ftown 0.19.68 → 0.20.1

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.
Files changed (60) hide show
  1. package/dist/ask-question-hook.d.ts +46 -0
  2. package/dist/ask-question-hook.js +192 -0
  3. package/dist/ask-question-hook.js.map +1 -0
  4. package/dist/attention-events.d.ts +38 -2
  5. package/dist/attention-events.js +70 -0
  6. package/dist/attention-events.js.map +1 -1
  7. package/dist/attention-prompt-protocol.d.ts +92 -0
  8. package/dist/attention-prompt-protocol.js +28 -0
  9. package/dist/attention-prompt-protocol.js.map +1 -0
  10. package/dist/attention-prompt.d.ts +12 -0
  11. package/dist/attention-prompt.js +333 -0
  12. package/dist/attention-prompt.js.map +1 -0
  13. package/dist/attention-store.d.ts +29 -1
  14. package/dist/attention-store.js +218 -18
  15. package/dist/attention-store.js.map +1 -1
  16. package/dist/browser-access.js +7 -1
  17. package/dist/browser-access.js.map +1 -1
  18. package/dist/command-rpc.d.ts +10 -0
  19. package/dist/command-rpc.js +84 -19
  20. package/dist/command-rpc.js.map +1 -1
  21. package/dist/harness-commands.js +7 -0
  22. package/dist/harness-commands.js.map +1 -1
  23. package/dist/hook-installer.d.ts +2 -0
  24. package/dist/hook-installer.js +83 -9
  25. package/dist/hook-installer.js.map +1 -1
  26. package/dist/index.js +4 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/local-api-server.d.ts +3 -1
  29. package/dist/local-api-server.js +109 -11
  30. package/dist/local-api-server.js.map +1 -1
  31. package/dist/mcp/fleet.d.ts +1 -1
  32. package/dist/mcp/fleet.js +1 -1
  33. package/dist/mcp/fleet.js.map +1 -1
  34. package/dist/mcp/security-events.js +2 -2
  35. package/dist/mcp/security-events.js.map +1 -1
  36. package/dist/mcp/server.js +38 -9
  37. package/dist/mcp/server.js.map +1 -1
  38. package/dist/pull-request-review-protocol.d.ts +59 -0
  39. package/dist/pull-request-review-protocol.js +6 -0
  40. package/dist/pull-request-review-protocol.js.map +1 -0
  41. package/dist/pull-request-review.d.ts +19 -0
  42. package/dist/pull-request-review.js +234 -0
  43. package/dist/pull-request-review.js.map +1 -0
  44. package/dist/security/bridge/account-state.d.ts +4 -4
  45. package/dist/security/bridge/audit.js +1 -1
  46. package/dist/security/bridge/audit.js.map +1 -1
  47. package/dist/security/bridge/identity.d.ts +3 -3
  48. package/dist/security/bridge/metadata.d.ts +2 -2
  49. package/dist/security/bridge/permissions.js +9 -4
  50. package/dist/security/bridge/permissions.js.map +1 -1
  51. package/dist/session-wire.d.ts +1 -0
  52. package/dist/session-wire.js +6 -2
  53. package/dist/session-wire.js.map +1 -1
  54. package/dist/sessions-commands.d.ts +5 -0
  55. package/dist/sessions-commands.js +155 -5
  56. package/dist/sessions-commands.js.map +1 -1
  57. package/dist/types.d.ts +6 -2
  58. package/package.json +2 -2
  59. package/skills/ftown/SKILL.md +29 -6
  60. package/skills/ftown/references/sessions.md +65 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ftown",
3
- "version": "0.19.68",
3
+ "version": "0.20.1",
4
4
  "description": "CLI bridge for ftown — generic PTY-over-Centrifugo relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -80,5 +80,5 @@
80
80
  "overrides": {
81
81
  "qs": "6.16.1"
82
82
  },
83
- "gitHead": "05ab67b05ac1cac33b22f3d180ddf6d9a9579294"
83
+ "gitHead": "825bd2e5518e79eb94f0b7651e924cbed6530c13"
84
84
  }
@@ -41,6 +41,8 @@ ftown sessions list
41
41
  ftown sessions create --prompt "Review the auth module" --workdir "$PWD" --parent
42
42
  ftown sessions screen <session-id> --limit 200
43
43
  ftown sessions attention --message "Please review the migration plan" --title "Review requested"
44
+ ftown sessions attention --title "Pick a database" --message "Which database should I use?" --option Postgres --option SQLite --wait
45
+ ftown sessions attention-status <event-id> --wait
44
46
  ftown sessions pr https://github.com/owner/repo/pull/123
45
47
  ftown sessions pr --clear
46
48
  ftown sessions preview ./preview.html
@@ -89,10 +91,27 @@ task needs it. Inspect peers with `ftown sessions list` and
89
91
 
90
92
  Use `ftown sessions attention --message "..."` when you need human input. It
91
93
  creates a durable attention record and uses the dashboard's existing notice flow;
92
- it does not answer a prompt or guarantee a push notification. Push remains opt-in
93
- and requires a supported hosted session. Repeating an unresolved request updates
94
- its occurrence count; after an uncertain result, inspect the existing request
95
- before retrying.
94
+ a plain request does not answer a prompt or guarantee a push notification. Push
95
+ remains opt-in and requires a supported hosted session. Repeating an unresolved
96
+ request updates its occurrence count; after an uncertain result, inspect the
97
+ existing request before retrying.
98
+
99
+ ### Questions with answers
100
+
101
+ Add `--option <label>` (repeatable) to ask a question the human answers in the
102
+ dashboard inbox. `--multi` allows several choices; `--no-text` disallows a
103
+ free-text reply. Without options the question is free text. Add `--wait` to
104
+ block until the answer arrives (`--timeout <s>`, default 600). A timeout does
105
+ not cancel the question; check later with
106
+ `ftown sessions attention-status <event-id> --wait`. The command prints the
107
+ event ID.
108
+
109
+ Delivery: a live waiter receives the answer; otherwise it arrives as ftown mail
110
+ from "You" starting with `[ftown attention answer id=...]`.
111
+
112
+ Claude Code `AskUserQuestion` calls inside an FTown session are answered from
113
+ the same inbox, and the terminal picker appears only after "Answer in terminal"
114
+ or an hour. Exit codes and waiting details: `references/sessions.md`.
96
115
 
97
116
  Attach one GitHub pull request with `ftown sessions pr <URL>`; another URL
98
117
  replaces it and `--clear` removes it. This records a link without creating a PR.
@@ -111,8 +130,12 @@ Older bridges report `bridge_upgrade_required` before mutation.
111
130
  Remote MCP callers use `attention_request` with explicit `machine` and
112
131
  `sessionId`, or `sessions_update` with `pullRequestUrl` (string to set, null to
113
132
  clear). Mutation tools require control access; remote callers have no automatic
114
- local self identity. Keep the returned attention event ID for existing inbox,
115
- acknowledge and resolve operations, which do not answer the agent's question.
133
+ local self identity. To ask with options or free text, pass `questions` to
134
+ `attention_request`, then poll `attention_get` (`eventId`, optional
135
+ `waitSeconds` 0..25) until the event is resolved (`resolvedAt` set).
136
+ `event.answer` holds the answer; a resolution without an answer means it was
137
+ dismissed. Keep the returned attention event ID: the
138
+ inbox, acknowledge and resolve operations never answer the agent's question.
116
139
 
117
140
  For tasks performed in an FTown session, associate the task's GitHub PR when
118
141
  created or updated, before the completion notice: use `ftown sessions pr <URL>`
@@ -88,6 +88,20 @@ machine and session ID. A queued message does not mean an agent has read it.
88
88
  # Request human input for this session (JSON {event} by default)
89
89
  ftown sessions attention --message "Please review the migration plan" --title "Review requested"
90
90
 
91
+ # Ask a single-select question and block until the human answers (default timeout 600 s)
92
+ ftown sessions attention --title "Pick a database" --message "Which database should I use?" \
93
+ --option Postgres --option SQLite --wait
94
+
95
+ # Multi-select without free text
96
+ ftown sessions attention --message "Which checks should run?" --option Lint --option Test --option Typecheck --multi --no-text
97
+
98
+ # Several questions (array or {"questions": [...]})
99
+ ftown sessions attention --message "Setup" --questions-json '[{"question":"Runtime?","options":["Node","Bun"]},{"question":"Notes?"}]'
100
+
101
+ # Check a question later (one GET; --wait long-polls)
102
+ ftown sessions attention-status <event-id>
103
+ ftown sessions attention-status <event-id> --wait --timeout 300
104
+
91
105
  # Set or replace this session's single GitHub PR link (JSON {session})
92
106
  ftown sessions pr https://github.com/owner/repo/pull/123
93
107
 
@@ -113,6 +127,43 @@ Only creation triggers notification, and hosted push remains opt-in with existin
113
127
  session/harness eligibility. Do not automatically retry an uncertain mutation.
114
128
  Acknowledging/resolving an event never answers or approves a CLI prompt.
115
129
 
130
+ ### Questions and answers
131
+
132
+ `--option <label>` is repeatable and builds one question whose message is the
133
+ `--message` text, with those labels as choices. `--multi` allows several choices
134
+ and `--no-text` disallows free text; without options the question is free text.
135
+ `--questions-json` takes an array of questions or `{ "questions": [...] }`, where
136
+ each question has `question`, optional `header`, `options` (strings or
137
+ `{label, description?}`, at most 8), `multiSelect` and `allowText`. It cannot be
138
+ combined with `--option`, `--multi` or `--no-text`. `--multi` and `--no-text`
139
+ need `--option`; `--timeout` needs `--wait`; `--wait` needs questions. Questions
140
+ require a bridge reporting `capabilities.attention.prompt === true`; otherwise
141
+ the command fails before writing and asks you to update the bridge.
142
+
143
+ `--wait` and `attention-status --wait` print `Waiting for an answer (attention <id>)...`
144
+ to stderr and poll until the item is resolved or the deadline (`--timeout`
145
+ `--timeout <s>`, 1..86400, default 600). Exit codes:
146
+
147
+ | Exit | Meaning |
148
+ |------|---------|
149
+ | 0 | Answered; the formatted answer is printed to stdout |
150
+ | 2 | Resolved without an answer (dismissed or otherwise closed) |
151
+ | 3 | Still pending (`attention-status` without `--wait`) |
152
+ | 124 | Timed out; check later with `attention-status <id> --wait` |
153
+ | 1 | Error, including invalid flags or JSON and transient failures after retries |
154
+
155
+ Without `--wait`, `attention` prints the event ID when questions are present, so
156
+ the agent can check later with `attention-status`.
157
+
158
+ Delivery: the human answers in the dashboard inbox. A live waiter (`--wait`,
159
+ `attention-status --wait`, or MCP `attention_get` polling) receives the answer
160
+ directly. If nobody is waiting, the answer is sent as ftown mail from "You"
161
+ (`fromName` "You", thread `attention:<id>`) whose body starts with
162
+ `[ftown attention answer id=<id>]`. Claude Code `AskUserQuestion` calls inside an
163
+ FTown session follow the same path and are answered from the dashboard inbox.
164
+ The terminal picker appears only if the human chooses "Answer in terminal" or
165
+ after an hour.
166
+
116
167
  PR links accept only HTTPS GitHub `/owner/repo/pull/<positive-number>` URLs.
117
168
  Outer whitespace, query/fragment and a trailing slash are normalized; credentials,
118
169
  nondefault ports and other paths/hosts are rejected. No GitHub request is made.
@@ -122,10 +173,17 @@ its value. New sessions/children do not implicitly inherit a parent's PR.
122
173
  New commands probe the exact bridge capability before writing; update old bridges
123
174
  with the exact version setup command in their readiness hint. For remote MCP,
124
175
  `attention_request` requires explicit `{machine, sessionId, message, title?}` and
125
- returns `{machine, sessionId, event}`. `sessions_update` accepts `pullRequestUrl`
126
- (string or null), alongside existing name/parent fields. A mixed PR+name update
127
- rejects an old bridge before changing either field. Read-only MCP clients cannot
128
- see these mutation tools; control authorization and machine ownership still apply.
176
+ returns `{machine, sessionId, event}`; it also accepts optional `questions` (1 to
177
+ 4 entries, shaped as above) when the bridge reports `prompt`. `attention_get`
178
+ takes `{machine, sessionId, eventId, waitSeconds?}` (`waitSeconds` 0..25) and
179
+ returns `{machine, sessionId, event}`. Poll it until the event is resolved
180
+ (`resolvedAt` set): `event.answer` holds the answer, and a resolution without an
181
+ answer means the question was dismissed.
182
+
183
+ `sessions_update` accepts `pullRequestUrl` (string or null), alongside existing
184
+ name/parent fields. A mixed PR+name update rejects an old bridge before changing
185
+ either field. Read-only MCP clients cannot see these mutation tools; control
186
+ authorization and machine ownership still apply.
129
187
 
130
188
  ## Messaging (mail)
131
189
 
@@ -246,7 +304,9 @@ The CLI wraps the loopback API. Raw access if needed:
246
304
  | GET | `/api/sessions` | List |
247
305
  | POST | `/api/sessions` | Create |
248
306
  | PATCH | `/api/sessions/:id` | Rename, move or associate a PR (`{ name?, parentSessionId?, pullRequestUrl? }`; `null` detaches/clears) |
249
- | POST | `/api/sessions/:id/attention` | Request human input (`{ message, title? }`) → `{ event }` |
307
+ | POST | `/api/sessions/:id/attention` | Request human input (`{ message, title?, questions? }`) → `{ event }`; invalid `questions` → 400 `invalid_prompt` |
308
+ | GET | `/api/sessions/:id/attention/:eventId` | Read one item (`?waitSeconds=0..25` long-polls until resolved) → `{ event }`; 404 `attention_not_found` |
309
+ | POST | `/api/sessions/:id/attention/ask` | Harness hook: record an AskUserQuestion (`{ toolName, toolUseId, toolInput }`) → `{ event }` or `null` if not promptable |
250
310
  | GET | `/api/sessions/:id/screen` | Terminal lines |
251
311
  | POST | `/api/sessions/:id/grep` | Search |
252
312
  | POST | `/api/sessions/:id/keys` | Send keys |