ftown 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attention-cli.d.ts +32 -0
- package/dist/attention-cli.js +310 -0
- package/dist/attention-cli.js.map +1 -0
- package/dist/attention-events.d.ts +2 -1
- package/dist/attention-events.js.map +1 -1
- package/dist/attention-store.d.ts +6 -3
- package/dist/attention-store.js +60 -2
- package/dist/attention-store.js.map +1 -1
- package/dist/brief-cli.d.ts +10 -0
- package/dist/brief-cli.js +163 -0
- package/dist/brief-cli.js.map +1 -0
- package/dist/command-rpc.d.ts +11 -0
- package/dist/command-rpc.js +83 -16
- package/dist/command-rpc.js.map +1 -1
- package/dist/coordination/attention-routing.d.ts +37 -0
- package/dist/coordination/attention-routing.js +154 -0
- package/dist/coordination/attention-routing.js.map +1 -0
- package/dist/coordination/board.js +82 -3
- package/dist/coordination/board.js.map +1 -1
- package/dist/coordination/contract-b.d.ts +206 -0
- package/dist/coordination/contract-b.js +58 -0
- package/dist/coordination/contract-b.js.map +1 -0
- package/dist/coordination/contract-c.d.ts +117 -0
- package/dist/coordination/contract-c.js +47 -0
- package/dist/coordination/contract-c.js.map +1 -0
- package/dist/coordination/contract.d.ts +8 -1
- package/dist/coordination/contract.js +1 -1
- package/dist/coordination/contract.js.map +1 -1
- package/dist/coordination/format.js +51 -12
- package/dist/coordination/format.js.map +1 -1
- package/dist/coordination/plan.d.ts +74 -0
- package/dist/coordination/plan.js +534 -0
- package/dist/coordination/plan.js.map +1 -0
- package/dist/coordination/routes-brief.d.ts +10 -0
- package/dist/coordination/routes-brief.js +149 -0
- package/dist/coordination/routes-brief.js.map +1 -0
- package/dist/coordination/routes-plan.d.ts +13 -0
- package/dist/coordination/routes-plan.js +182 -0
- package/dist/coordination/routes-plan.js.map +1 -0
- package/dist/coordination/routes-worktrees.d.ts +29 -0
- package/dist/coordination/routes-worktrees.js +138 -0
- package/dist/coordination/routes-worktrees.js.map +1 -0
- package/dist/coordination/wiring.d.ts +17 -2
- package/dist/coordination/wiring.js +81 -11
- package/dist/coordination/wiring.js.map +1 -1
- package/dist/coordination-cli.d.ts +6 -1
- package/dist/coordination-cli.js +23 -7
- package/dist/coordination-cli.js.map +1 -1
- package/dist/create-ftown-session.d.ts +26 -1
- package/dist/create-ftown-session.js +208 -104
- package/dist/create-ftown-session.js.map +1 -1
- package/dist/ftown-cli.js +14 -2
- package/dist/ftown-cli.js.map +1 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/local-api-server.d.ts +24 -0
- package/dist/local-api-server.js +473 -32
- package/dist/local-api-server.js.map +1 -1
- package/dist/mail-delivery.d.ts +18 -4
- package/dist/mail-delivery.js +50 -8
- package/dist/mail-delivery.js.map +1 -1
- package/dist/plan-cli.d.ts +52 -0
- package/dist/plan-cli.js +357 -0
- package/dist/plan-cli.js.map +1 -0
- package/dist/security/bridge/permissions.js +55 -5
- package/dist/security/bridge/permissions.js.map +1 -1
- package/dist/session-controller.d.ts +17 -1
- package/dist/session-controller.js +93 -2
- package/dist/session-controller.js.map +1 -1
- package/dist/sessions-commands.js +75 -5
- package/dist/sessions-commands.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/worktrees-cli.d.ts +39 -0
- package/dist/worktrees-cli.js +168 -0
- package/dist/worktrees-cli.js.map +1 -0
- package/dist/worktrees.d.ts +16 -0
- package/dist/worktrees.js +292 -0
- package/dist/worktrees.js.map +1 -0
- package/hooks/ftown-antigravity-hook.sh +12 -6
- package/package.json +2 -2
- package/skills/ftown/SKILL.md +88 -5
- package/skills/ftown/references/orchestrator.md +32 -29
- package/skills/ftown/references/sessions.md +155 -12
|
@@ -76,18 +76,111 @@ ftown board [--json] [--since <n>] [--ready] [--all] [--session-id <id>]
|
|
|
76
76
|
# Wait until a board condition holds
|
|
77
77
|
ftown board [--wait --until any-change|any-done|any-blocked|all-done|any-ready [--timeout <s≤300>]] [--session-id <id>]
|
|
78
78
|
|
|
79
|
-
# Tree events for my tree (status, attention, pr, preview, exit, idle, result, mail)
|
|
79
|
+
# Tree events for my tree (status, attention, pr, preview, exit, idle, result, mail, plan, removed)
|
|
80
80
|
ftown events [--json] [--since <n>] [--limit <n>] [--wait [--timeout <s≤300>]] [--session-id <id>]
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
`--ready` lists only children whose PR checks passed and who are not done;
|
|
84
|
-
`--all` includes archived
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
`--all` includes retired (archived) children after the live ones, newest
|
|
85
|
+
first, capped at 50 and suffixed `(retired)` in plain output; `--since <n>`
|
|
86
|
+
limits the board to children with events after that cursor (the board
|
|
87
|
+
prints its cursor). Pass the cursor back as `--since` to see only what
|
|
88
|
+
changed. Plain board output appends a `planned` section after the child
|
|
89
|
+
rows: up to 5 ready plan items as `→ <id> <title>`, then `+N more` when
|
|
90
|
+
more are ready.
|
|
91
|
+
|
|
92
|
+
Tree events also include `plan` (one per plan change, summary
|
|
93
|
+
`<id> <state>: <title>`, plus ` → ready: <id>, …` when items become ready)
|
|
94
|
+
and `removed` (summary `removed`, when a child is removed or archived
|
|
95
|
+
while not already exited).
|
|
87
96
|
|
|
88
97
|
Exit codes for `status`, `board` and `events`: 0 ok, 1 error, 2 usage,
|
|
89
98
|
3 wait timed out with the condition unmet.
|
|
90
99
|
|
|
100
|
+
## Plan list
|
|
101
|
+
|
|
102
|
+
The plan is the manager's plan, not a ticket system: a todo list with
|
|
103
|
+
precedence stored on the manager (parent) session. It defaults to
|
|
104
|
+
`FTOWN_SESSION_ID`; `--session-id <id>` targets another session's plan.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# List in plan order (--json passes the PlanView through)
|
|
108
|
+
ftown plan [--json] [--session-id <id>]
|
|
109
|
+
|
|
110
|
+
# Add (title is the remaining words; precedence via --after/--priority)
|
|
111
|
+
ftown plan add <title...> [--note <t>] [--after <id,id>] [--priority 1|2|3] [--session-id <id>]
|
|
112
|
+
|
|
113
|
+
# Link an existing child, or set state directly
|
|
114
|
+
ftown plan start <id> --session <child-id> [--session-id <id>]
|
|
115
|
+
ftown plan done <id> [--session-id <id>]
|
|
116
|
+
ftown plan drop <id> [--session-id <id>]
|
|
117
|
+
ftown plan todo <id> [--session-id <id>]
|
|
118
|
+
|
|
119
|
+
# Edit or remove (removing strips the id from other items' after lists)
|
|
120
|
+
ftown plan edit <id> [--title <t>] [--note <t>|--no-note] [--after <ids>|--no-after] [--priority n] [--session-id <id>]
|
|
121
|
+
ftown plan rm <id> [--session-id <id>]
|
|
122
|
+
|
|
123
|
+
# Create a child for a plan item (marks it started, linked to the child)
|
|
124
|
+
ftown sessions create --parent --plan-item <id> --prompt "<task>"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
List marks: `→` ready, `·` waiting, `▸` started, `✓` done, `✗` dropped,
|
|
128
|
+
printed as `<mark> <id> [P<priority>] <title>` plus `(after p1,p2)` or
|
|
129
|
+
`→ <child name>` when linked. Ordering is ready first, then waiting (both
|
|
130
|
+
by priority ascending, then creation time), then started, done and
|
|
131
|
+
dropped. An item is ready when it is `todo` and every item in its `after`
|
|
132
|
+
list is `done` or `dropped`; precedence is set only with `--after` and
|
|
133
|
+
`--priority` (1 is highest). Item ids are `p<n>` and are never reused.
|
|
134
|
+
Limits: 200 items, title 140 characters, note 500, at most 20 `after`
|
|
135
|
+
ids; `after` ids must exist, with no self-reference or cycles.
|
|
136
|
+
|
|
137
|
+
`--plan-item <id>` (on `ftown sessions create`, requires `--parent` or
|
|
138
|
+
`--parent-id`) fails with an error before any session is created when the
|
|
139
|
+
item is unknown or not `todo`; after creation the item becomes `started`
|
|
140
|
+
with the child linked, and a linking failure only warns (the session
|
|
141
|
+
stays). When a linked child's card becomes `done`, the item becomes
|
|
142
|
+
`done`; a `failed` card leaves it `started` for the manager to decide.
|
|
143
|
+
Setting an item back to `todo` clears its linked session. Exit codes for
|
|
144
|
+
`ftown plan`: 0 ok, 1 error, 2 usage.
|
|
145
|
+
|
|
146
|
+
## Manager brief
|
|
147
|
+
|
|
148
|
+
A coordinating session keeps a markdown brief plus timestamped notes; the
|
|
149
|
+
dashboard overview renders the brief, the last 10 notes and the session's
|
|
150
|
+
children automatically. The target defaults to `FTOWN_SESSION_ID`.
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
ftown brief show [--json] [--session-id <id>]
|
|
154
|
+
ftown brief set (--file <path.md> | --text <t> | --clear) [--session-id <id>]
|
|
155
|
+
ftown brief note <text...> [--session-id <id>]
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Text is markdown, at most 16384 characters; a note is a single line of
|
|
159
|
+
1–280 characters; at most 50 notes are kept (oldest dropped). Control
|
|
160
|
+
characters except newline and tab are stripped; text over the limit is an
|
|
161
|
+
error (exit 1), never truncated.
|
|
162
|
+
|
|
163
|
+
## Worktrees
|
|
164
|
+
|
|
165
|
+
Children that write code can get a bridge-created git worktree. The default
|
|
166
|
+
branch is `ftown/<slug(name)>` at `<repoRoot>/.claude/worktrees/<slug(name)>`;
|
|
167
|
+
the base defaults to the current branch of the working directory (a detached
|
|
168
|
+
HEAD needs `--base`). Only bridge-created worktrees are ever removed.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
ftown sessions create --parent --worktree [--branch <b>] [--base <ref>] [--workdir <dir>]
|
|
172
|
+
ftown sessions remove <id> [--keep-worktree | --force-worktree]
|
|
173
|
+
ftown worktrees list [--json]
|
|
174
|
+
ftown worktrees prune [--json]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
On remove, a clean worktree whose branch is merged or fully pushed is
|
|
178
|
+
retired (worktree removed; the branch is deleted only when merged);
|
|
179
|
+
otherwise it is retained and the command prints why (for example
|
|
180
|
+
`worktree retained: 2 unpushed commits`). `--keep-worktree` always retains,
|
|
181
|
+
`--force-worktree` forces removal. `prune` applies the same rule to archived
|
|
182
|
+
sessions only.
|
|
183
|
+
|
|
91
184
|
## Preview session files
|
|
92
185
|
|
|
93
186
|
```bash
|
|
@@ -183,7 +276,9 @@ Attention persists an `agent_needs_input` event, returns its exact ID and update
|
|
|
183
276
|
the existing dashboard attention flow. Logical duplicate unresolved requests
|
|
184
277
|
coalesce while recording occurrences; resolving it permits a new incident.
|
|
185
278
|
Only creation triggers notification, and hosted push remains opt-in with existing
|
|
186
|
-
session/harness eligibility.
|
|
279
|
+
session/harness eligibility. For a parent-routed item, creation notifies only
|
|
280
|
+
the parent; the dashboard notice and push fire if it is escalated to the human.
|
|
281
|
+
Do not automatically retry an uncertain mutation.
|
|
187
282
|
Acknowledging/resolving an event never answers or approves a CLI prompt.
|
|
188
283
|
|
|
189
284
|
### Questions and answers
|
|
@@ -223,6 +318,37 @@ FTown session follow the same path and are answered from the dashboard inbox.
|
|
|
223
318
|
The terminal picker appears only if the human chooses "Answer in terminal" or
|
|
224
319
|
after an hour.
|
|
225
320
|
|
|
321
|
+
### Parent-first routing
|
|
322
|
+
|
|
323
|
+
When the asking session has a running parent, the request goes to the parent
|
|
324
|
+
first: the parent receives one waking escalation mail (`[ftown question ...]`)
|
|
325
|
+
naming the commands below, and the human's inbox shows the item greyed as
|
|
326
|
+
"with parent" (the human may still answer it). There is no timer; only the
|
|
327
|
+
parent, or the parent stopping while the item is open, moves it to the human.
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
# Open parent-routed questions from my children (plain: `<child> <eventId> <title>` plus options)
|
|
331
|
+
ftown attention list [--json]
|
|
332
|
+
|
|
333
|
+
# Answer a child's question (as the parent)
|
|
334
|
+
ftown attention answer <child-id> <event-id> (--option <n|label>... | --text <t> | --answers-json <json>) [--json]
|
|
335
|
+
|
|
336
|
+
# Raise it to the human instead (note at most 500 characters)
|
|
337
|
+
ftown attention escalate <child-id> <event-id> [--note <t>] [--json]
|
|
338
|
+
|
|
339
|
+
# Bypass the parent: only the human can provide this
|
|
340
|
+
ftown sessions attention --to human --message "Please paste the API token" --title "Credential needed"
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Answer only from facts you hold — the plan, the agreed contract, earlier
|
|
344
|
+
human answers. Preferences and irreversible choices are escalated, not
|
|
345
|
+
answered. A parent answer is delivered exactly like a human answer (live
|
|
346
|
+
waiter, or mail whose sender is the parent session).
|
|
347
|
+
|
|
348
|
+
Exit codes for `ftown attention`: 0 ok, 1 error, 2 usage, 4 forbidden (the
|
|
349
|
+
caller is not the child's parent), 5 conflict (already resolved or already
|
|
350
|
+
escalated to the human).
|
|
351
|
+
|
|
226
352
|
PR links accept only HTTPS GitHub `/owner/repo/pull/<positive-number>` URLs.
|
|
227
353
|
Outer whitespace, query/fragment and a trailing slash are normalized; credentials,
|
|
228
354
|
nondefault ports and other paths/hosts are rejected. No GitHub request is made.
|
|
@@ -291,6 +417,10 @@ Fan-out targets are messaged sequentially, one JSON result line per target.
|
|
|
291
417
|
| `--command` | Full command override (skips `--shell` builder) |
|
|
292
418
|
| `--parent` | Set parent to `$FTOWN_SESSION_ID` |
|
|
293
419
|
| `--parent-id` | Explicit parent session UUID |
|
|
420
|
+
| `--plan-item <id>` | Do plan item `p<n>` of the parent (requires `--parent` or `--parent-id`; see Plan list) |
|
|
421
|
+
| `--worktree` | Create a bridge-owned git worktree for the session (see Worktrees) |
|
|
422
|
+
| `--branch <b>` | Worktree branch (requires `--worktree`; default `ftown/<slug(name)>`) |
|
|
423
|
+
| `--base <ref>` | Ref the worktree branch starts from (requires `--worktree`) |
|
|
294
424
|
| `--model` | Harness model name or provider/model pattern (when supported) |
|
|
295
425
|
|
|
296
426
|
Provider-flavored shells (`zai`, `kimi`, `deepseek`, `fireworks`) run Claude
|
|
@@ -313,9 +443,9 @@ ftown sessions grep <child-id> --pattern 'FAIL|Error'
|
|
|
313
443
|
|
|
314
444
|
### Completion handoff
|
|
315
445
|
|
|
316
|
-
|
|
317
|
-
FTown session before the completion notice.
|
|
318
|
-
task is complete, before the final handoff. Replace the sample URL and summary
|
|
446
|
+
A top-level session (no parent): when the task creates or updates a GitHub PR,
|
|
447
|
+
associate its actual URL with the FTown session before the completion notice.
|
|
448
|
+
Then request user attention once the task is complete, before the final handoff. Replace the sample URL and summary
|
|
319
449
|
below with truthful outcomes and checks (including checks not run):
|
|
320
450
|
|
|
321
451
|
```bash
|
|
@@ -329,8 +459,10 @@ For tasks without a PR, omit the PR command and PR summary. Use the verified
|
|
|
329
459
|
|
|
330
460
|
Send one completion request per completed task, not repeated per-turn notices.
|
|
331
461
|
Logical duplicate coalescing does not justify retries after an uncertain outcome;
|
|
332
|
-
inspect the existing request first, as described above. Child agents
|
|
333
|
-
|
|
462
|
+
inspect the existing request first, as described above. Child agents do not
|
|
463
|
+
raise "Work complete": they set their card to `done` and send their assigned
|
|
464
|
+
result to the parent, and the parent raises one completion notice for the
|
|
465
|
+
whole job.
|
|
334
466
|
|
|
335
467
|
## Environment
|
|
336
468
|
|
|
@@ -361,7 +493,18 @@ The CLI wraps the loopback API. Raw access if needed:
|
|
|
361
493
|
| GET | `/api/sessions` | List |
|
|
362
494
|
| POST | `/api/sessions` | Create |
|
|
363
495
|
| PATCH | `/api/sessions/:id` | Rename, move or associate a PR (`{ name?, parentSessionId?, pullRequestUrl? }`; `null` detaches/clears) |
|
|
364
|
-
| POST | `/api/sessions/:id/attention` | Request
|
|
496
|
+
| POST | `/api/sessions/:id/attention` | Request input (`{ message, title?, questions?, to?: 'human' }`) → `{ event }`; invalid `questions` → 400 `invalid_prompt` |
|
|
497
|
+
| POST | `/api/sessions/:id/attention/:eventId/answer` | Parent answers a child (`{ answers }`); 403 not the parent, 409 resolved |
|
|
498
|
+
| POST | `/api/sessions/:id/attention/:eventId/escalate` | Parent raises it to the human (`{ note? }`); 403 not the parent, 409 already human/resolved |
|
|
499
|
+
| GET | `/api/sessions/:id/attention/routed` | Open parent-routed items of my children → `{ items }` |
|
|
500
|
+
| GET/PUT/DELETE | `/api/sessions/:id/brief` | Read, set/clear (`{ text: string \| null }`) or delete the manager brief |
|
|
501
|
+
| POST | `/api/sessions/:id/brief/notes` | Append a brief note (`{ text }`) |
|
|
502
|
+
| GET | `/api/sessions/:id/plan` | Read the plan (`PlanView`: ordered items plus ready ids) |
|
|
503
|
+
| POST | `/api/sessions/:id/plan` | Add a plan item (`{ title, note?, after?, priority? }`) → `{ item }` |
|
|
504
|
+
| PATCH | `/api/sessions/:id/plan/:itemId` | Edit a plan item (`{ title?, note?: string\|null, after?, priority?, state?, sessionId?: string\|null }`) → `{ item }`; item id is `p<n>` |
|
|
505
|
+
| DELETE | `/api/sessions/:id/plan/:itemId` | Remove a plan item (strips it from other items' `after`) → `{ ok: true }` |
|
|
506
|
+
| GET | `/api/worktrees` | List bridge-owned worktrees with git status |
|
|
507
|
+
| POST | `/api/worktrees/prune` | Retire eligible archived worktrees → `{ removed, retained }` |
|
|
365
508
|
| GET | `/api/sessions/:id/attention/:eventId` | Read one item (`?waitSeconds=0..25` long-polls until resolved) → `{ event }`; 404 `attention_not_found` |
|
|
366
509
|
| POST | `/api/sessions/:id/attention/ask` | Harness hook: record an AskUserQuestion (`{ toolName, toolUseId, toolInput }`) → `{ event }` or `null` if not promptable |
|
|
367
510
|
| GET | `/api/sessions/:id/screen` | Terminal lines |
|
|
@@ -373,7 +516,7 @@ The CLI wraps the loopback API. Raw access if needed:
|
|
|
373
516
|
| POST | `/api/sessions/:id/message` | Inject a message line as keystrokes (`{ text, from? }`) |
|
|
374
517
|
| PUT | `/api/sessions/:id/preview` | Replace or add preview files, local CLI only (`{ paths: string[], mode: 'replace' \| 'add' }`) |
|
|
375
518
|
| DELETE | `/api/sessions/:id/preview` | Remove preview files by name or clear the preview, local CLI only (`{ names?: string[] }`; absent names clears all) |
|
|
376
|
-
| DELETE | `/api/sessions/:id` | Remove (tombstone-archived) |
|
|
519
|
+
| DELETE | `/api/sessions/:id` | Remove (tombstone-archived; `?worktree=keep\|force` overrides worktree retirement) |
|
|
377
520
|
| GET | `/api/archive` | List removed-session tombstones |
|
|
378
521
|
| POST | `/api/sessions/:id/revive` | Recreate a removed session (new id) |
|
|
379
522
|
|