Projects

konnecthub init my-flows
cd my-flows

init scaffolds a project and links nothing. That is the decision, not an omission: the repo is a partial, opt-in view of a workspace, and a scaffold that adopted every flow it found would make the repo look authoritative over things it does not own.

What a project owns

Flow source, and nothing else.

Deployments, triggers, data stores, services and connections are configured in the app and are not represented here. Two consequences follow directly:

Getting flows into it

konnecthub new "Order Received"      # create a flow, remotely and locally
konnecthub new "Order Router" --graph   # the same, built as a graph (graph.json)
konnecthub new shared --library      # a library, entered at mod.ts
konnecthub new upper --node          # a custom node type, entered at node.ts
konnecthub link                      # adopt flows that already exist in the workspace

new creates the flow on the server and pulls the template it seeded, so the first push is an ordinary update rather than a conflict. link with no arguments lists what is adoptable and asks.

Three names, and which one is the flow

A flow is identified by the id recorded in its own flow.json — an opaque platform id, written for you by new and link. Everything else about a flow is a label:

StringWhere it livesWhat it is for
idflow.jsonthe flow itself. Never edit it
nameflow.jsonthe display name, shown in the app. Free-form: spaces, capitals, punctuation
directoryflows/<dir>/, listed in konnecthub.jsonwhat you type: konnecthub push order-received

So konnecthub new "Order Received" creates a flow called Order Received in a directory called order-received. Override the directory with --dir.

The exceptions are a library and a node type, whose name is how they are referenced: lib:shared resolves by name and a graph pins ws:upper@3, so their names have to stay a lowercase slug and are their directory.

Layout

konnecthub.json        origin, workspace, and the flow directories this repo has adopted
flows/<dir>/
  flow.json            CLI metadata: id, name, description, kind. Never pushed
  inputs.json          the flow's input schema — a real draft file
  main.ts              entrypoint — or graph.json for a graph flow
  tests/<case>.json    one test case each. Never pushed
libs/<name>/           workspace libraries, entered at mod.ts, imported as lib:<name>
nodes/<name>/          custom node types, entered at node.ts or graph.json
.claude/skills/        agent instructions, generated by the API
.konnecthub/           CLI state and this project's token — gitignored, never hand-edited

konnecthub.json and flow.json each carry a $schema pointing at your own installation, so an editor validates them as you type. init also maps inputs.json and a graph's graph.json to their schemas in .vscode/settings.json — those cannot carry a $schema key of their own, because they are synced files and the key would show up as a diff on every pull.

flow.json and tests/ are reserved on both sides: they are never pushed to the draft and never pulled over.

The state directory

.konnecthub/ is gitignored, and everything in it except your token is rebuildable — deleting it costs a re-pull and a login, never data.

It holds three things worth knowing about:

Point your editor's Deno configuration at that file and imports resolve there too. Refresh the declarations with konnecthub types, and workspace libraries with konnecthub libs.

Renaming

A display name is just a label — change name in flow.json, push, done. Or rename it in the app and pull. The flow's deployments, schedules and history are attached to its id, which neither direction touches.

A directory is a local handle. Rename it, update the entry in konnecthub.json, and rename .konnecthub/base/<dir> to match so the merge base follows it — otherwise the next push sees every file as new on both sides.

A file inside a flow needs nothing: identical bytes under a new path are detected and sent as a move, keeping the file's identity and its static flag.

Next