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.
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:
deploy is a publish pipeline, not a reconciler. There is no drift detection and no prune.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.
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:
| String | Where it lives | What it is for |
|---|---|---|
id | flow.json | the flow itself. Never edit it |
name | flow.json | the display name, shown in the app. Free-form: spaces, capitals, punctuation |
| directory | flows/<dir>/, listed in konnecthub.json | what 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.
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.
.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:
credentials.json — the token for this project's workspace, at mode 0600. This is why
.konnecthub/ must stay gitignored: committing it would publish a real access token.
base/ — the exact bytes of every file as of the last sync. This is the merge base, which
is why it caches content rather than hashes: a hash can detect a conflict, only the content can
merge one.
deno.json — a generated resolver mapping konnecthub/flow, konnecthub/<lib> and
lib:<name> onto cached declarations, reproducing what a real build resolves.
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.
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.