@te-river/opencode-team-mode 1.6.2 → 1.7.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/README.md +117 -118
- package/README.zh-CN.md +98 -100
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +89 -79
- package/dist/agents.js.map +1 -1
- package/dist/approval-gate.d.ts +8 -9
- package/dist/approval-gate.d.ts.map +1 -1
- package/dist/approval-gate.js +13 -14
- package/dist/approval-gate.js.map +1 -1
- package/dist/capabilities.d.ts +11 -37
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +11 -141
- package/dist/capabilities.js.map +1 -1
- package/dist/commands.js +1 -1
- package/dist/envprotect/hook.d.ts +12 -31
- package/dist/envprotect/hook.d.ts.map +1 -1
- package/dist/envprotect/hook.js +13 -91
- package/dist/envprotect/hook.js.map +1 -1
- package/dist/envprotect/patterns.d.ts +6 -4
- package/dist/envprotect/patterns.d.ts.map +1 -1
- package/dist/envprotect/patterns.js +6 -4
- package/dist/envprotect/patterns.js.map +1 -1
- package/dist/envprotect.d.ts +1 -1
- package/dist/envprotect.d.ts.map +1 -1
- package/dist/envprotect.js +1 -1
- package/dist/envprotect.js.map +1 -1
- package/dist/host/v2-browser-gate.d.ts +19 -1
- package/dist/host/v2-browser-gate.d.ts.map +1 -1
- package/dist/host/v2-browser-gate.js +47 -6
- package/dist/host/v2-browser-gate.js.map +1 -1
- package/dist/host/v2-capabilities.d.ts +33 -0
- package/dist/host/v2-capabilities.d.ts.map +1 -1
- package/dist/host/v2-capabilities.js +50 -1
- package/dist/host/v2-capabilities.js.map +1 -1
- package/dist/host/v2-compaction.d.ts +129 -0
- package/dist/host/v2-compaction.d.ts.map +1 -0
- package/dist/host/v2-compaction.js +346 -0
- package/dist/host/v2-compaction.js.map +1 -0
- package/dist/host/v2-default-agent.d.ts +37 -0
- package/dist/host/v2-default-agent.d.ts.map +1 -0
- package/dist/host/v2-default-agent.js +128 -0
- package/dist/host/v2-default-agent.js.map +1 -0
- package/dist/host/v2-events.d.ts +2 -0
- package/dist/host/v2-events.d.ts.map +1 -1
- package/dist/host/v2-events.js +27 -0
- package/dist/host/v2-events.js.map +1 -1
- package/dist/host/v2-guard.d.ts +178 -0
- package/dist/host/v2-guard.d.ts.map +1 -1
- package/dist/host/v2-guard.js +324 -8
- package/dist/host/v2-guard.js.map +1 -1
- package/dist/host/v2-offload.d.ts +1 -1
- package/dist/host/v2-offload.js +2 -2
- package/dist/host/v2-permissions.d.ts +45 -44
- package/dist/host/v2-permissions.d.ts.map +1 -1
- package/dist/host/v2-permissions.js +48 -49
- package/dist/host/v2-permissions.js.map +1 -1
- package/dist/host/v2-probe-chain.d.ts +93 -0
- package/dist/host/v2-probe-chain.d.ts.map +1 -0
- package/dist/host/v2-probe-chain.js +146 -0
- package/dist/host/v2-probe-chain.js.map +1 -0
- package/dist/host/v2-prune.d.ts +157 -0
- package/dist/host/v2-prune.d.ts.map +1 -0
- package/dist/host/v2-prune.js +507 -0
- package/dist/host/v2-prune.js.map +1 -0
- package/dist/host/v2-retry.d.ts +143 -0
- package/dist/host/v2-retry.d.ts.map +1 -0
- package/dist/host/v2-retry.js +315 -0
- package/dist/host/v2-retry.js.map +1 -0
- package/dist/host/v2-scope.d.ts.map +1 -1
- package/dist/host/v2-scope.js +14 -7
- package/dist/host/v2-scope.js.map +1 -1
- package/dist/host/v2-session-client.d.ts +24 -0
- package/dist/host/v2-session-client.d.ts.map +1 -1
- package/dist/host/v2-session-client.js +243 -3
- package/dist/host/v2-session-client.js.map +1 -1
- package/dist/host/v2-session.d.ts +72 -1
- package/dist/host/v2-session.d.ts.map +1 -1
- package/dist/host/v2-session.js +154 -10
- package/dist/host/v2-session.js.map +1 -1
- package/dist/host/v2-tool.d.ts +2 -3
- package/dist/host/v2-tool.d.ts.map +1 -1
- package/dist/host/v2-tool.js +2 -3
- package/dist/host/v2-tool.js.map +1 -1
- package/dist/host/v2-types.d.ts +25 -0
- package/dist/host/v2-types.d.ts.map +1 -1
- package/dist/host/v2.d.ts +14 -12
- package/dist/host/v2.d.ts.map +1 -1
- package/dist/host/v2.js +500 -73
- package/dist/host/v2.js.map +1 -1
- package/dist/identity.d.ts +27 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +34 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +9 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -27
- package/dist/index.js.map +1 -1
- package/dist/prompts/lead.d.ts +1 -1
- package/dist/prompts/lead.d.ts.map +1 -1
- package/dist/prompts/lead.js +38 -25
- package/dist/prompts/lead.js.map +1 -1
- package/dist/prompts/shared.d.ts +2 -2
- package/dist/prompts/shared.d.ts.map +1 -1
- package/dist/prompts/shared.js +66 -56
- package/dist/prompts/shared.js.map +1 -1
- package/dist/prompts/specialists.d.ts +2 -2
- package/dist/prompts/specialists.d.ts.map +1 -1
- package/dist/prompts/specialists.js +53 -83
- package/dist/prompts/specialists.js.map +1 -1
- package/dist/tm/args-schema.d.ts +7 -32
- package/dist/tm/args-schema.d.ts.map +1 -1
- package/dist/tm/args-schema.js +12 -153
- package/dist/tm/args-schema.js.map +1 -1
- package/dist/tm/board.d.ts +10 -9
- package/dist/tm/board.d.ts.map +1 -1
- package/dist/tm/board.js +11 -10
- package/dist/tm/board.js.map +1 -1
- package/dist/tm/config-files.d.ts +81 -0
- package/dist/tm/config-files.d.ts.map +1 -0
- package/dist/tm/config-files.js +209 -0
- package/dist/tm/config-files.js.map +1 -0
- package/dist/tm/config-layers.d.ts +117 -0
- package/dist/tm/config-layers.d.ts.map +1 -0
- package/dist/tm/config-layers.js +320 -0
- package/dist/tm/config-layers.js.map +1 -0
- package/dist/tm/config.d.ts +10 -101
- package/dist/tm/config.d.ts.map +1 -1
- package/dist/tm/config.js +17 -71
- package/dist/tm/config.js.map +1 -1
- package/dist/tm/dispatch.d.ts +115 -21
- package/dist/tm/dispatch.d.ts.map +1 -1
- package/dist/tm/dispatch.js +424 -67
- package/dist/tm/dispatch.js.map +1 -1
- package/dist/tm/egress.d.ts +19 -7
- package/dist/tm/egress.d.ts.map +1 -1
- package/dist/tm/egress.js +21 -9
- package/dist/tm/egress.js.map +1 -1
- package/dist/tm/index.d.ts +23 -20
- package/dist/tm/index.d.ts.map +1 -1
- package/dist/tm/index.js +117 -116
- package/dist/tm/index.js.map +1 -1
- package/dist/tm/ledger.d.ts +9 -2
- package/dist/tm/ledger.d.ts.map +1 -1
- package/dist/tm/ledger.js +4 -1
- package/dist/tm/ledger.js.map +1 -1
- package/dist/tm/perm-ask.d.ts +3 -3
- package/dist/tm/perm-ask.d.ts.map +1 -1
- package/dist/tm/perm-ask.js +3 -3
- package/dist/tm/perm-ask.js.map +1 -1
- package/dist/tm/pipelines.d.ts +12 -11
- package/dist/tm/pipelines.d.ts.map +1 -1
- package/dist/tm/pipelines.js +40 -207
- package/dist/tm/pipelines.js.map +1 -1
- package/dist/tm/preview.d.ts +1 -1
- package/dist/tm/preview.js +3 -3
- package/dist/tm/preview.js.map +1 -1
- package/dist/tm/refs.d.ts +31 -4
- package/dist/tm/refs.d.ts.map +1 -1
- package/dist/tm/refs.js +48 -4
- package/dist/tm/refs.js.map +1 -1
- package/dist/tm/result.d.ts +1 -1
- package/dist/tm/result.d.ts.map +1 -1
- package/dist/tm/result.js +4 -3
- package/dist/tm/result.js.map +1 -1
- package/dist/tm/search.d.ts +2 -2
- package/dist/tm/search.js +7 -7
- package/dist/tm/search.js.map +1 -1
- package/dist/tm/serp-loop.d.ts +19 -7
- package/dist/tm/serp-loop.d.ts.map +1 -1
- package/dist/tm/serp-loop.js +24 -9
- package/dist/tm/serp-loop.js.map +1 -1
- package/dist/tm/stats.d.ts +12 -27
- package/dist/tm/stats.d.ts.map +1 -1
- package/dist/tm/stats.js +43 -45
- package/dist/tm/stats.js.map +1 -1
- package/dist/tm/store.d.ts +18 -5
- package/dist/tm/store.d.ts.map +1 -1
- package/dist/tm/store.js +39 -9
- package/dist/tm/store.js.map +1 -1
- package/dist/tm/tools.d.ts +7 -5
- package/dist/tm/tools.d.ts.map +1 -1
- package/dist/tm/tools.js +10 -41
- package/dist/tm/tools.js.map +1 -1
- package/dist/tm/webfetch.d.ts +1 -1
- package/dist/tm/webfetch.d.ts.map +1 -1
- package/dist/tm/webfetch.js +38 -23
- package/dist/tm/webfetch.js.map +1 -1
- package/dist/types.d.ts +40 -123
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -21
- package/dist/types.js.map +1 -1
- package/docs/installation-v2.md +109 -33
- package/docs/installation.md +9 -0
- package/docs/research/browser-pane.md +5 -0
- package/docs/v2-port-notes.md +87 -0
- package/package.json +1 -1
- package/scripts/gen-v2-config.mjs +246 -94
- package/scripts/lib/fake-ctx.mjs +75 -0
|
@@ -130,44 +130,37 @@ requests against UI pages as UI proof, no hand-written DOM stubs. If the
|
|
|
130
130
|
project ALREADY ships a browser-test setup (e.g. a Playwright config in
|
|
131
131
|
the repo), you may use that tooling as designed.
|
|
132
132
|
|
|
133
|
-
## UI verification (
|
|
134
|
-
For user-visible frontend changes, verify through the
|
|
135
|
-
— snapshot-first, never screenshot-guessing
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
blocked script domain means \`allow_host { host }\` then re-navigate;
|
|
150
|
-
a human-verification wall means a human has to pass it, so report UI NOT
|
|
133
|
+
## UI verification (the host's native browser tools — you carry them)
|
|
134
|
+
For user-visible frontend changes, verify through the host's own \`browser_*\`
|
|
135
|
+
tools — snapshot-first, never screenshot-guessing. The exact verb names and
|
|
136
|
+
argument shapes are the HOST's; check the official tool docs before the first
|
|
137
|
+
call rather than guessing one:
|
|
138
|
+
1. \`browser_navigate { url }\` once, then \`browser_snapshot\` FIRST and act
|
|
139
|
+
ONLY on the addressing tokens it returned — guessed selectors or guessed
|
|
140
|
+
text are BANNED. The snapshot's addressing notation is the host's (its
|
|
141
|
+
ariaSnapshot writes \`@e8 [link] "…"\`); read the one-time note the gate
|
|
142
|
+
attaches the first time you use it, because a guessed \`snap.text\` or an
|
|
143
|
+
\`fn\` argument that is really \`script\` each costs a round.
|
|
144
|
+
2. One action, one observation: after \`browser_click\` / \`browser_fill\` /
|
|
145
|
+
\`browser_press_key\`, take a fresh \`browser_snapshot\` BEFORE concluding;
|
|
146
|
+
never stack blind actions. A thin/empty snapshot is a claim about the page
|
|
147
|
+
or about our own gate — never about the site being empty. A
|
|
148
|
+
human-verification wall means a human has to pass it, so report UI NOT
|
|
151
149
|
VERIFIED instead of retrying it into the ground.
|
|
152
|
-
3. Popups, dialogs and new tabs fold into the SAME observation round —
|
|
153
|
-
|
|
154
|
-
4. Waits:
|
|
155
|
-
|
|
156
|
-
5.
|
|
150
|
+
3. Popups, dialogs and new tabs fold into the SAME observation round — one
|
|
151
|
+
\`browser_snapshot\` after handling them, not one round each.
|
|
152
|
+
4. Waits: use the host's own wait verb inside a bounded budget; never
|
|
153
|
+
sleep-then-pray.
|
|
154
|
+
5. \`browser_screenshot\` ONLY for what a snapshot cannot show (layout, color,
|
|
157
155
|
canvas); the aria snapshot / page text is your primary observation.
|
|
158
|
-
6.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
servers, deployed preview routes) — open web browsing stays with the
|
|
164
|
-
lead and the researcher.
|
|
165
|
-
If tm_browser is unavailable on this host, the action you need is not
|
|
166
|
-
offered by the degraded engine, or the route needs credentials you were
|
|
167
|
-
not given, end your report with:
|
|
156
|
+
6. Your use is UI verification of THIS project (local dev servers, deployed
|
|
157
|
+
preview routes) — open web browsing stays with the lead and the researcher.
|
|
158
|
+
If the host offers no \`browser_*\` tools (a CLI/standalone host has none), the
|
|
159
|
+
verb you need is not available, or the route needs credentials you were not
|
|
160
|
+
given, end your report with:
|
|
168
161
|
\`UI NOT VERIFIED: <what still needs manual checking>\`
|
|
169
162
|
so the lead can relay it honestly to the user. Pretending otherwise is
|
|
170
|
-
worse than admitting the gap.
|
|
163
|
+
worse than admitting the gap — never simulate a browser you do not have.
|
|
171
164
|
|
|
172
165
|
## Failure classification (required for every failing case)
|
|
173
166
|
- **PRODUCT_BUG** — the code is wrong. Include minimal repro + expected
|
|
@@ -236,51 +229,24 @@ You are one of the two network roles (the other is the team lead).
|
|
|
236
229
|
- tm_webfetch (known URL): one governed GET of an allowlisted page;
|
|
237
230
|
search-engine result pages it fetches are auto-extracted to hit
|
|
238
231
|
lists. A hit tagged (域名不在白名单,需批准)needs the approval
|
|
239
|
-
dialog before it can be read — prefer a hit you can fetch, or
|
|
240
|
-
|
|
241
|
-
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
to pass. Absence of a confirmation dialog is NOT evidence the host
|
|
256
|
-
is on the allowlist: the reply now says which path let a page through
|
|
257
|
-
(静态白名单 / 你刚批准的窗 / 宿主按已记住的"始终允许"秒回). A saved
|
|
258
|
-
"always" is project-wide, so it can let YOUR session through without
|
|
259
|
-
ever asking you — quote the tool's own line instead of concluding
|
|
260
|
-
"该 URL 在白名单内". When a snapshot ends with "N 个子资源请求被拦截" the
|
|
261
|
-
governance gate trimmed the page: that is NOT "the site has no
|
|
262
|
-
images" — report the blocked hosts in FINDINGS instead. And when the
|
|
263
|
-
page comes back with 0 个可寻址节点 WHILE a script host was blocked,
|
|
264
|
-
the blankness is our gate, not an empty site (a site's own bundle can
|
|
265
|
-
live on a brand-unrelated CDN — Baidu's bdimg.com is the standing
|
|
266
|
-
example): call \`allow_host { host }\` for that one domain (one
|
|
267
|
-
official dialog, your browser only, nothing written to config), then
|
|
268
|
-
re-navigate — or name the host in HANDOFF so the user can add it to
|
|
269
|
-
TM_WEBFETCH_ALLOWED_DOMAINS and restart. A reply that calls the page
|
|
270
|
-
a human-verification wall is a different fact again: a human has to pass it, so
|
|
271
|
-
change source (another engine, another site) and never report either case
|
|
272
|
-
as the site having no content. When your
|
|
273
|
-
UI work is done, action:"close" and quote the tool's own verdict —
|
|
274
|
-
已确认关闭 (a pid was checked and is gone) / 进程未核验 (no pid was
|
|
275
|
-
available, so nothing was verified) / 警告:关闭未完全成功 (the
|
|
276
|
-
leftovers are named). Only the first may be reported as the browser being
|
|
277
|
-
closed; the other two report an unverified close and ask the user to check
|
|
278
|
-
the window. Never tell
|
|
279
|
-
the user a window is gone because you asked for it to close.
|
|
280
|
-
Isolated temp profile;
|
|
281
|
-
navigation is domain-allowlisted at the network layer.
|
|
232
|
+
dialog before it can be read — prefer a hit you can fetch, or open it
|
|
233
|
+
in the host's native browser.
|
|
234
|
+
- the host's native browser tools (interactive): for a JS-rendered page
|
|
235
|
+
tm_webfetch cannot read, use the host's own \`browser_*\` catalog —
|
|
236
|
+
\`browser_navigate\` then \`browser_snapshot\`, acting ONLY on the
|
|
237
|
+
addressing tokens the snapshot returned (never guess a selector). The
|
|
238
|
+
verb names and argument shapes are the HOST's; check the official tool
|
|
239
|
+
docs before the first call rather than guessing one. Read the one-time
|
|
240
|
+
note the gate attaches: the snapshot's addressing notation is the host's
|
|
241
|
+
(\`@e8 [link] "…"\`), and a guessed \`snap.text\` or an \`fn\` argument that
|
|
242
|
+
is really \`script\` each costs a round. A thin/empty snapshot is a claim
|
|
243
|
+
about the page or about our own gate — never about the site being empty;
|
|
244
|
+
a human-verification wall means a human has to pass it, so change source
|
|
245
|
+
(another engine, another site) instead of retrying it into the ground.
|
|
246
|
+
If the host offers no \`browser_*\` tools (a CLI/standalone host has none),
|
|
247
|
+
report the gap — never simulate a browser you do not have.
|
|
282
248
|
2. FALLBACK — user-configured MCP/plugin tools (browser automation, web
|
|
283
|
-
search, page fetchers) for what tm_search /
|
|
249
|
+
search, page fetchers) for what tm_search / tm_webfetch
|
|
284
250
|
cannot do.
|
|
285
251
|
Seeded allowlist hosts and shapes (extend via
|
|
286
252
|
TM_WEBFETCH_ALLOWED_DOMAINS):
|
|
@@ -306,14 +272,18 @@ Oversized pages come back as a handle — page with tm_fetch (try
|
|
|
306
272
|
mode:"structure" first). Never fabricate page content — an unfetchable
|
|
307
273
|
claim stays unfetched and is reported as a gap.
|
|
308
274
|
|
|
309
|
-
## Recon batching (
|
|
310
|
-
Local-repo recon
|
|
311
|
-
|
|
312
|
-
|
|
275
|
+
## Recon batching (parallel calls first)
|
|
276
|
+
Local-repo recon batches in the shape the host actually allows: independent
|
|
277
|
+
reads / greps / globs toward one goal go in ONE message as PARALLEL tool
|
|
278
|
+
calls — one round, several results. \`execute\` (Code Mode) does NOT run those
|
|
279
|
+
native tools — its catalog lists the governed tm_* calls only, and
|
|
280
|
+
\`tools["read"]\` inside it answers \`Unknown tool\` (\`typeof tools.read\` saying
|
|
281
|
+
\`"function"\` is a measured false positive) — so use \`execute\` to fold many
|
|
282
|
+
governed tm_* calls into one program (ALWAYS \`return\` the
|
|
313
283
|
aggregated findings). Firing single lookups one at a time for one
|
|
314
284
|
question wastes the team's time and tokens. The same rule covers
|
|
315
285
|
independent web calls: two unrelated tm_search queries belong in one
|
|
316
|
-
round (or one
|
|
286
|
+
round (or one \`execute\` program), never in two.
|
|
317
287
|
|
|
318
288
|
## Behavioral constraints
|
|
319
289
|
- When analyzing dependencies, output call-graph diagrams in mermaid format.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specialists.js","sourceRoot":"","sources":["../../src/prompts/specialists.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B/B,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBjC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2C9B,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG
|
|
1
|
+
{"version":3,"file":"specialists.js","sourceRoot":"","sources":["../../src/prompts/specialists.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B/B,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBjC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2C9B,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8E5B,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgHhC,CAAA"}
|
package/dist/tm/args-schema.d.ts
CHANGED
|
@@ -8,15 +8,10 @@
|
|
|
8
8
|
* ...}}` garbage args in real sessions (the model wrapped its args 3/3
|
|
9
9
|
* times), even though flat args reached execute fine.
|
|
10
10
|
*/
|
|
11
|
+
import { type ConfigFileRoots } from "./config-files.js";
|
|
12
|
+
import type { EnvLike } from "./config-layers.js";
|
|
11
13
|
declare function buildArgsSchemas(): Promise<Record<string, Record<string, unknown>>>;
|
|
12
14
|
export { buildArgsSchemas };
|
|
13
|
-
/**
|
|
14
|
-
* tm_ptc_run args — same ZodRawShape treatment (BUG#3 class): a raw shape
|
|
15
|
-
* when zod is available, descriptors otherwise. Kept separate from
|
|
16
|
-
* buildArgsSchemas because buildPtcRunTool is sync; tm/index awaits this
|
|
17
|
-
* once and passes the result in as `deps.args`.
|
|
18
|
-
*/
|
|
19
|
-
export declare function buildPtcArgsSchema(): Promise<Record<string, unknown>>;
|
|
20
15
|
/**
|
|
21
16
|
* tm_webfetch args — same ZodRawShape treatment (BUG#3 class); descriptor
|
|
22
17
|
* fallback when zod is absent. tm/index awaits this and passes the result
|
|
@@ -40,37 +35,17 @@ export declare function buildWebfetchArgsSchema(): Promise<Record<string, unknow
|
|
|
40
35
|
* The §6m-s anti-drift test asserts the descriptor names every
|
|
41
36
|
* SEARCH_ENGINE_NAMES entry and none of the removed engines.
|
|
42
37
|
*/
|
|
43
|
-
export declare function buildSearchArgsSchema(defaultEngine?: string
|
|
38
|
+
export declare function buildSearchArgsSchema(defaultEngine?: string, layeredInput?: {
|
|
39
|
+
env?: EnvLike;
|
|
40
|
+
roots?: ConfigFileRoots;
|
|
41
|
+
}): Promise<Record<string, unknown>>;
|
|
44
42
|
/**
|
|
45
43
|
* tm_memory args — same ZodRawShape treatment (BUG#3 class); descriptor
|
|
46
44
|
* fallback when zod is absent.
|
|
47
45
|
*/
|
|
48
46
|
export declare function buildMemoryArgsSchema(): Promise<Record<string, unknown>>;
|
|
49
|
-
/**
|
|
50
|
-
* tm_browser args — same ZodRawShape treatment (BUG#3 class); descriptor
|
|
51
|
-
* fallback when zod is absent.
|
|
52
|
-
*
|
|
53
|
-
* STRIP BEHAVIOR / WHY EVERY FIELD IS DECLARED: this is a RAW shape, never
|
|
54
|
-
* wrapped in z.object() (BUG#3), so no zod-level .strip()/.passthrough()
|
|
55
|
-
* applies and execute() reads rawArgs verbatim. But the host serializes
|
|
56
|
-
* exactly these keys into the LLM parameter spec — an undeclared field is
|
|
57
|
-
* invisible to the model and never reaches browser.ts, i.e. the shape is a
|
|
58
|
-
* CLOSED param surface in effect. T5's 16 playwright verbs
|
|
59
|
-
* (BROWSER_PLAYWRIGHT_ACTIONS, browser.ts:505) + the 5 compat verbs consume
|
|
60
|
-
* 19 fields across execute/act (args.uid/selector/targetUid/targetSelector/
|
|
61
|
-
* text/key/function/expression/filePath/files/index/timeoutMs/dialogAction/
|
|
62
|
-
* promptText/clear/fullPage/image, browser.ts act() + execute()) — every one
|
|
63
|
-
* is declared below, or the corresponding verb silently loses its input.
|
|
64
|
-
*
|
|
65
|
-
* `headless` is DELIBERATELY not declared (2026-09-18): it used to be a model
|
|
66
|
-
* arg, `Boolean("false")` read as true, and one such call pinned the whole
|
|
67
|
-
* host process to a headless browser that every anti-bot gate then rejected.
|
|
68
|
-
* Mode is an operator setting (TM_BROWSER_HEADLESS) — a closed surface here
|
|
69
|
-
* is the fix, not a validation layer.
|
|
70
|
-
*/
|
|
71
|
-
export declare function buildBrowserArgsSchema(): Promise<Record<string, unknown>>;
|
|
72
47
|
/** tm_board_write — four strings, and the shape of the PATH is the tool's
|
|
73
48
|
* business, not the model's (that is what makes it safe to hand a writer to a
|
|
74
|
-
* role that owns no file tool). */
|
|
49
|
+
* role that owns no write-capable file tool). */
|
|
75
50
|
export declare function buildBoardArgsSchema(): Promise<Record<string, unknown>>;
|
|
76
51
|
//# sourceMappingURL=args-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args-schema.d.ts","sourceRoot":"","sources":["../../src/tm/args-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"args-schema.d.ts","sourceRoot":"","sources":["../../src/tm/args-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAChF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAkCjD,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CA4DlF;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAE3B;;;;GAIG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA0ChF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAA;CAAE,GACxD,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAmClC;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA+C9E;AAED;;kDAEkD;AAClD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAoB7E"}
|
package/dist/tm/args-schema.js
CHANGED
|
@@ -9,9 +9,7 @@
|
|
|
9
9
|
* times), even though flat args reached execute fine.
|
|
10
10
|
*/
|
|
11
11
|
import { resolveTmConfig } from "./config.js";
|
|
12
|
-
|
|
13
|
-
// copy here is how a shipped verb went missing from the tool schema.
|
|
14
|
-
import { BROWSER_ACTION_MENU, BROWSER_PLAYWRIGHT_ACTIONS } from "./browser.js";
|
|
12
|
+
import { resolveLayeredTmConfig } from "./config-files.js";
|
|
15
13
|
/**
|
|
16
14
|
* Load zod when the host environment provides it (opencode ships it as a
|
|
17
15
|
* peer); fall back to plain arg descriptors so the plugin never hard-depends
|
|
@@ -42,35 +40,12 @@ async function buildArgsSchemas() {
|
|
|
42
40
|
const z = await loadZod();
|
|
43
41
|
if (!z) {
|
|
44
42
|
return {
|
|
45
|
-
tm_read: describe(null, null, "path: string (required)"),
|
|
46
|
-
tm_grep: describe(null, null, "pattern: string (required), path: string (optional)"),
|
|
47
|
-
tm_bash: describe(null, null, "command: string (required, read-only allowlisted)"),
|
|
48
43
|
tm_fetch: describe(null, null, "ref: string (required), access_token: string, offset: int, limit: int, mode: lines|structure, fields: dot-path (json handle projection)"),
|
|
49
44
|
};
|
|
50
45
|
}
|
|
51
46
|
const zz = z;
|
|
52
47
|
// RAW SHAPES — no zz.object() wrapper (BUG#3).
|
|
53
48
|
return {
|
|
54
|
-
tm_read: {
|
|
55
|
-
path: zz
|
|
56
|
-
.string()
|
|
57
|
-
.describe("File path, relative to the project root (or absolute within it). Env files (.env, *.env, .bashrc family) are rejected — same R6 source as the built-in read."),
|
|
58
|
-
},
|
|
59
|
-
tm_grep: {
|
|
60
|
-
pattern: zz.string().describe("Regex to search (ripgrep syntax)."),
|
|
61
|
-
// describe-LAST on every optional chain — zod v4 drops a description
|
|
62
|
-
// applied before .optional() when the shape is serialized (see
|
|
63
|
-
// buildMemoryArgsSchema); a required field's describe stays first.
|
|
64
|
-
path: zz
|
|
65
|
-
.string()
|
|
66
|
-
.optional()
|
|
67
|
-
.describe("Optional directory scope, relative to the project root."),
|
|
68
|
-
},
|
|
69
|
-
tm_bash: {
|
|
70
|
-
command: zz
|
|
71
|
-
.string()
|
|
72
|
-
.describe("Read-only shell command (allowlisted heads only). bash on POSIX, PowerShell-like on Windows."),
|
|
73
|
-
},
|
|
74
49
|
tm_fetch: {
|
|
75
50
|
ref: zz
|
|
76
51
|
.string()
|
|
@@ -103,47 +78,6 @@ async function buildArgsSchemas() {
|
|
|
103
78
|
};
|
|
104
79
|
}
|
|
105
80
|
export { buildArgsSchemas };
|
|
106
|
-
/**
|
|
107
|
-
* tm_ptc_run args — same ZodRawShape treatment (BUG#3 class): a raw shape
|
|
108
|
-
* when zod is available, descriptors otherwise. Kept separate from
|
|
109
|
-
* buildArgsSchemas because buildPtcRunTool is sync; tm/index awaits this
|
|
110
|
-
* once and passes the result in as `deps.args`.
|
|
111
|
-
*/
|
|
112
|
-
export async function buildPtcArgsSchema() {
|
|
113
|
-
const z = await loadZod();
|
|
114
|
-
if (!z) {
|
|
115
|
-
return {
|
|
116
|
-
program: { descriptor: "program: string (required, async fn body, ≤TM_PTC_MAX_PROGRAM_CHARS)" },
|
|
117
|
-
label: { descriptor: "label: string (optional, ≤80 chars)" },
|
|
118
|
-
budgets: { descriptor: "budgets: { max_calls?, max_errors?, timeout_ms? } (optional, tighten-only; any other key is rejected)" },
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
const zz = z;
|
|
122
|
-
return {
|
|
123
|
-
program: zz
|
|
124
|
-
.string()
|
|
125
|
-
.describe("Async function body. Available: tm.read(args), tm.grep(args), tm.bash(args), tm.fetch(args) — each returns {ok:true, data} or {ok:false, error:{tool,phase,line?,message}}. `return` a value for the aggregation summary."),
|
|
126
|
-
// Wave B Minor③: zod v4 DROPS a description set before .optional() when
|
|
127
|
-
// the shape is serialized, so every optional chain here is describe-LAST
|
|
128
|
-
// (matches buildMemoryArgsSchema / buildBrowserArgsSchema).
|
|
129
|
-
label: zz.string().optional().describe("Optional run label (≤80 chars)."),
|
|
130
|
-
// Fix batch T1: an EXPLICIT zod object — z.any() let host-side arg
|
|
131
|
-
// handling mangle the budgets value so parsePtcArgs never saw it and
|
|
132
|
-
// the caller's budgets silently fell back to the defaults.
|
|
133
|
-
// Wave B Minor②: .strict() rejects unknown budget keys (a typo like
|
|
134
|
-
// max_call silently read as an omitted default before — now it fails
|
|
135
|
-
// loudly). parsePtcArgs enforces the same at the runtime layer.
|
|
136
|
-
budgets: zz
|
|
137
|
-
.object({
|
|
138
|
-
max_calls: zz.number().int().min(1).optional().describe("Max bridged tm_* calls (tighten-only)."),
|
|
139
|
-
max_errors: zz.number().int().min(1).optional().describe("Max failed bridged calls (tighten-only)."),
|
|
140
|
-
timeout_ms: zz.number().int().min(1).optional().describe("Wall-clock budget in ms (floor 5000, tighten-only)."),
|
|
141
|
-
})
|
|
142
|
-
.strict()
|
|
143
|
-
.optional()
|
|
144
|
-
.describe("Optional budgets object { max_calls?, max_errors?, timeout_ms? } — tighten-only, clamped to the TM_PTC_* ceilings. Unknown keys are rejected."),
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
81
|
/**
|
|
148
82
|
* tm_webfetch args — same ZodRawShape treatment (BUG#3 class); descriptor
|
|
149
83
|
* fallback when zod is absent. tm/index awaits this and passes the result
|
|
@@ -195,9 +129,17 @@ export async function buildWebfetchArgsSchema() {
|
|
|
195
129
|
* The §6m-s anti-drift test asserts the descriptor names every
|
|
196
130
|
* SEARCH_ENGINE_NAMES entry and none of the removed engines.
|
|
197
131
|
*/
|
|
198
|
-
export async function buildSearchArgsSchema(defaultEngine) {
|
|
132
|
+
export async function buildSearchArgsSchema(defaultEngine, layeredInput) {
|
|
199
133
|
const { AUTO_ENGINE_KEY, SEARCH_ENGINE_NAMES } = await import("./search.js");
|
|
200
|
-
|
|
134
|
+
// The descriptor's default MUST match the runtime's. When the caller hands
|
|
135
|
+
// us the layered view's inputs we resolve through the SAME file-aware path;
|
|
136
|
+
// otherwise we fall back to env-only — a bare call (a test) must never read
|
|
137
|
+
// the user's real ~/.config/opencode.
|
|
138
|
+
const defEngine = (defaultEngine && defaultEngine.trim()) ||
|
|
139
|
+
(layeredInput
|
|
140
|
+
? resolveLayeredTmConfig(layeredInput.env ?? process.env, layeredInput.roots).cfg.searchDefaultEngine
|
|
141
|
+
: resolveTmConfig().searchDefaultEngine) ||
|
|
142
|
+
AUTO_ENGINE_KEY;
|
|
201
143
|
const engineList = `${AUTO_ENGINE_KEY}|${SEARCH_ENGINE_NAMES.join("|")}`;
|
|
202
144
|
const engineDesc = `engine: ${engineList} (optional, default ${defEngine}). ` +
|
|
203
145
|
`"${AUTO_ENGINE_KEY}" classifies the query and fans the matching engines out in parallel ` +
|
|
@@ -262,92 +204,9 @@ export async function buildMemoryArgsSchema() {
|
|
|
262
204
|
.describe("compact only: absent = dry-run (report planned merges), true = perform them (originals backed up under memories/.compact-backup/)."),
|
|
263
205
|
};
|
|
264
206
|
}
|
|
265
|
-
/**
|
|
266
|
-
* tm_browser args — same ZodRawShape treatment (BUG#3 class); descriptor
|
|
267
|
-
* fallback when zod is absent.
|
|
268
|
-
*
|
|
269
|
-
* STRIP BEHAVIOR / WHY EVERY FIELD IS DECLARED: this is a RAW shape, never
|
|
270
|
-
* wrapped in z.object() (BUG#3), so no zod-level .strip()/.passthrough()
|
|
271
|
-
* applies and execute() reads rawArgs verbatim. But the host serializes
|
|
272
|
-
* exactly these keys into the LLM parameter spec — an undeclared field is
|
|
273
|
-
* invisible to the model and never reaches browser.ts, i.e. the shape is a
|
|
274
|
-
* CLOSED param surface in effect. T5's 16 playwright verbs
|
|
275
|
-
* (BROWSER_PLAYWRIGHT_ACTIONS, browser.ts:505) + the 5 compat verbs consume
|
|
276
|
-
* 19 fields across execute/act (args.uid/selector/targetUid/targetSelector/
|
|
277
|
-
* text/key/function/expression/filePath/files/index/timeoutMs/dialogAction/
|
|
278
|
-
* promptText/clear/fullPage/image, browser.ts act() + execute()) — every one
|
|
279
|
-
* is declared below, or the corresponding verb silently loses its input.
|
|
280
|
-
*
|
|
281
|
-
* `headless` is DELIBERATELY not declared (2026-09-18): it used to be a model
|
|
282
|
-
* arg, `Boolean("false")` read as true, and one such call pinned the whole
|
|
283
|
-
* host process to a headless browser that every anti-bot gate then rejected.
|
|
284
|
-
* Mode is an operator setting (TM_BROWSER_HEADLESS) — a closed surface here
|
|
285
|
-
* is the fix, not a validation layer.
|
|
286
|
-
*/
|
|
287
|
-
export async function buildBrowserArgsSchema() {
|
|
288
|
-
const z = await loadZod();
|
|
289
|
-
// Derived from the action table itself (browser.ts) — the hand-written verb
|
|
290
|
-
// list here is how `new_page` and `close_page` went missing from the schema
|
|
291
|
-
// while the gate accepted them.
|
|
292
|
-
const ACTION_LIST = `${BROWSER_ACTION_MENU} (required) — the ${BROWSER_PLAYWRIGHT_ACTIONS.length} chrome-devtools-mcp verbs, ` +
|
|
293
|
-
`plus open|navigate|read|screenshot|close (compat) and allow_host (ask the user to un-block ONE script domain).`;
|
|
294
|
-
if (!z) {
|
|
295
|
-
return {
|
|
296
|
-
action: { descriptor: `action: ${ACTION_LIST}` },
|
|
297
|
-
id: { descriptor: 'id: which browser ("b1" from open) — one per agent; required once more than one is live, another agent\'s id is refused' },
|
|
298
|
-
url: { descriptor: "url: string (open/navigate/navigate_page/new_page, allowlisted https)" },
|
|
299
|
-
host: { descriptor: "host: one bare domain for allow_host (no wildcards, no URL, no port)" },
|
|
300
|
-
image: { descriptor: "image: true with take_screenshot — inline the PNG pixels in this result" },
|
|
301
|
-
uid: { descriptor: "uid: snapshot [uid=eN] token (click/fill/hover/drag/upload_file/wait_for)" },
|
|
302
|
-
selector: { descriptor: "selector: CSS/text locator escape hatch (only when a snapshot cannot express the node)" },
|
|
303
|
-
targetUid: { descriptor: "targetUid: drag destination uid" },
|
|
304
|
-
targetSelector: { descriptor: "targetSelector: drag destination selector" },
|
|
305
|
-
text: { descriptor: "text: fill value / wait_for visible text" },
|
|
306
|
-
key: { descriptor: "key: press_key chord, e.g. Enter|Control+A" },
|
|
307
|
-
function: { descriptor: "function: JS function source for evaluate_script" },
|
|
308
|
-
expression: { descriptor: "expression: alias of function (evaluate_script)" },
|
|
309
|
-
filePath: { descriptor: "filePath: local file path for upload_file" },
|
|
310
|
-
files: { descriptor: "files: alias of filePath — single path or array of paths" },
|
|
311
|
-
index: { descriptor: "index: select_page target tab index from list_pages" },
|
|
312
|
-
timeoutMs: { descriptor: "timeoutMs: wait_for budget in ms (default 3000, clamped 100..30000)" },
|
|
313
|
-
dialogAction: { descriptor: "dialogAction: accept|dismiss for handle_dialog (default accept)" },
|
|
314
|
-
promptText: { descriptor: "promptText: prompt-dialog reply text for handle_dialog accept" },
|
|
315
|
-
clear: { descriptor: "clear: drain the console buffer after list_console_messages" },
|
|
316
|
-
fullPage: { descriptor: "fullPage: take_screenshot captures the full page (default viewport only)" },
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
// describe-LAST on every optional chain — zod v4 drops a description set
|
|
320
|
-
// before .optional() when the shape is serialized (see buildMemoryArgsSchema).
|
|
321
|
-
const zz = z;
|
|
322
|
-
const str = (d) => zz.string().optional().describe(d);
|
|
323
|
-
const bool = (d) => zz.boolean().optional().describe(d);
|
|
324
|
-
return {
|
|
325
|
-
action: zz.string().describe(ACTION_LIST),
|
|
326
|
-
id: str('Which browser to drive — the id `open` returned ("b1"). Each agent gets its OWN browser: the id is required as soon as more than one is live, another agent\'s id is refused with the owner named, and close {id:"all"} closes all of yours.'),
|
|
327
|
-
url: str("Absolute https URL on an allowlisted host (open/navigate/navigate_page). URL-encode the query (CJK terms too)."),
|
|
328
|
-
host: str("allow_host only: ONE bare domain whose script the subresource gate blocked (e.g. bkssl.bdimg.com). Wildcards/URLs/ports are refused — the user approves exactly this string."),
|
|
329
|
-
image: bool("take_screenshot only: inline the PNG pixels into this tool result (default false = path only; pixels cost context, so ask only when the screenshot IS the evidence)."),
|
|
330
|
-
uid: str("Snapshot [uid=eN] token from the LATEST take_snapshot (click/fill/hover/drag source/upload_file/wait_for)."),
|
|
331
|
-
selector: str("CSS/text locator escape hatch — only for a node the snapshot cannot express; never guess locators."),
|
|
332
|
-
targetUid: str("drag destination uid from the latest take_snapshot."),
|
|
333
|
-
targetSelector: str("drag destination selector escape hatch."),
|
|
334
|
-
text: str("fill value, or the visible text to wait for with wait_for (uid or text — one of them)."),
|
|
335
|
-
key: str('press_key chord, e.g. "Enter" or "Control+A".'),
|
|
336
|
-
function: str("JS function/expression source for evaluate_script (returns the JSON-serialized value)."),
|
|
337
|
-
expression: str("Alias of function for evaluate_script."),
|
|
338
|
-
filePath: str("Local file path for upload_file (must exist on disk)."),
|
|
339
|
-
files: zz.any().optional().describe("Alias of filePath for upload_file — a single path or an array of paths."),
|
|
340
|
-
index: zz.number().int().min(0).optional().describe("select_page target tab index (0-based, from list_pages)."),
|
|
341
|
-
timeoutMs: zz.number().int().min(100).optional().describe("wait_for visibility budget in ms (engine default 3000, clamped to 30000)."),
|
|
342
|
-
dialogAction: str("handle_dialog verdict: accept (default) | dismiss."),
|
|
343
|
-
promptText: str("Reply text when handle_dialog accepts a prompt()-type dialog."),
|
|
344
|
-
clear: bool("Drain the buffered console messages after list_console_messages."),
|
|
345
|
-
fullPage: bool("take_screenshot captures the full page (default: viewport only)."),
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
207
|
/** tm_board_write — four strings, and the shape of the PATH is the tool's
|
|
349
208
|
* business, not the model's (that is what makes it safe to hand a writer to a
|
|
350
|
-
* role that owns no file tool). */
|
|
209
|
+
* role that owns no write-capable file tool). */
|
|
351
210
|
export async function buildBoardArgsSchema() {
|
|
352
211
|
const z = await loadZod();
|
|
353
212
|
if (!z) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args-schema.js","sourceRoot":"","sources":["../../src/tm/args-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,
|
|
1
|
+
{"version":3,"file":"args-schema.js","sourceRoot":"","sources":["../../src/tm/args-schema.ts"],"names":[],"mappings":"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"}
|
package/dist/tm/board.d.ts
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
* tm_board_write — the write side of the blackboard (2026-09-23).
|
|
3
3
|
*
|
|
4
4
|
* Why it exists: the board is the one place an oversized deliverable is
|
|
5
|
-
* supposed to go, but reaching it needs a file tool
|
|
6
|
-
* roles carry none
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
5
|
+
* supposed to go, but reaching it needs a write-capable file tool, and three of
|
|
6
|
+
* the six roles carry none: `architect` and `researcher` get no write/edit/bash
|
|
7
|
+
* from `whitelist()` and `reviewer` has only the read-only bash whose redirects
|
|
8
|
+
* P3 refuses — all three keep the read-capable tm_* set, so they are not
|
|
9
|
+
* tool-less. Every "write the design doc to the board" dispatch therefore ended
|
|
10
|
+
* as `BLACKBOARD WRITE FAILED` with the document pasted inline anyway — the
|
|
11
|
+
* reply shape this team exists to enforce (skeleton + path, never a wall of
|
|
12
|
+
* text) was un-followable for exactly the two roles that produce the longest
|
|
13
|
+
* artifacts. Even the documented session folder is out of reach: creating it
|
|
14
|
+
* means running `Get-Date`, which those roles cannot run either.
|
|
14
15
|
*
|
|
15
16
|
* What this is NOT: a general file writer. It places a NEW markdown file
|
|
16
17
|
* inside `<board-root>/<session-key>/<task-slug>/` and nothing else — no
|
package/dist/tm/board.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../../src/tm/board.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../../src/tm/board.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD;yDACyD;AACzD,eAAO,MAAM,uBAAuB,SAAU,CAAA;AAC9C;oEACoE;AACpE,eAAO,MAAM,2BAA2B,MAAM,CAAA;AAC9C,eAAO,MAAM,2BAA2B,KAAK,CAAA;AAE7C;;4EAE4E;AAC5E,wBAAgB,eAAe,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM,CAM9D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,SAAK,GAAG,MAAM,CAU3D;AAED;yDACyD;AACzD,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAO5D;AAED;;iCAEiC;AACjC,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED;;;;gEAIgE;AAChE,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAaxC;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;CAChC,GAAG,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAkClC;AAED;;yBAEyB;AACzB,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiB5F;AAED;;;oDAGoD;AACpD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAa7D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,SAAS,EAAE,WAAW,CAAA;IACtB;;gEAE4D;IAC5D,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,MAAM,CAAA;CACrB,GAAG;IACF,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;CACjF,CA4FA"}
|
package/dist/tm/board.js
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
* tm_board_write — the write side of the blackboard (2026-09-23).
|
|
3
3
|
*
|
|
4
4
|
* Why it exists: the board is the one place an oversized deliverable is
|
|
5
|
-
* supposed to go, but reaching it needs a file tool
|
|
6
|
-
* roles carry none
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
5
|
+
* supposed to go, but reaching it needs a write-capable file tool, and three of
|
|
6
|
+
* the six roles carry none: `architect` and `researcher` get no write/edit/bash
|
|
7
|
+
* from `whitelist()` and `reviewer` has only the read-only bash whose redirects
|
|
8
|
+
* P3 refuses — all three keep the read-capable tm_* set, so they are not
|
|
9
|
+
* tool-less. Every "write the design doc to the board" dispatch therefore ended
|
|
10
|
+
* as `BLACKBOARD WRITE FAILED` with the document pasted inline anyway — the
|
|
11
|
+
* reply shape this team exists to enforce (skeleton + path, never a wall of
|
|
12
|
+
* text) was un-followable for exactly the two roles that produce the longest
|
|
13
|
+
* artifacts. Even the documented session folder is out of reach: creating it
|
|
14
|
+
* means running `Get-Date`, which those roles cannot run either.
|
|
14
15
|
*
|
|
15
16
|
* What this is NOT: a general file writer. It places a NEW markdown file
|
|
16
17
|
* inside `<board-root>/<session-key>/<task-slug>/` and nothing else — no
|
|
@@ -265,7 +266,7 @@ export function buildBoardWriteTool(deps) {
|
|
|
265
266
|
execute,
|
|
266
267
|
};
|
|
267
268
|
}
|
|
268
|
-
const DESCRIPTION = `Blackboard file writer — the deliverable channel for roles that own no file
|
|
269
|
+
const DESCRIPTION = `Blackboard file writer — the deliverable channel for roles that own no write-capable file tool (architect and researcher carry no write/edit/bash, so a board write through the host's file tools is impossible for them by construction). Writes ONE new markdown file at <board-root>/<session-key>/<task-slug>/NN-<role>-<topic>[-rN].md, where NN and -rN are chosen by this tool (never overwritten: a revision is a new round file, so the board keeps its audit trail). Args: task (slug), topic (slug), content, and optionally session — pass the folder the lead already created so every role in this conversation writes into the SAME folder; omit it and the tool stamps yyyyMMdd-HHmmss for you. The role in the filename comes from the host's ctx, not from what you claim. Scope is enforced, not polite: segments are sanitized, the target's realpath must stay under the board root (a symlinked task dir pointing outside is refused), the name always ends in .md so no .env/rc file can be produced, and content is capped by TM_BOARD_MAX_CHARS with a per-session file cap. The reply is the absolute path plus the byte count and NEVER the content — pasting the deliverable back is the exact thing this channel exists to prevent, so after a successful write the report carries skeleton + path, not the document.`;
|
|
269
270
|
const FALLBACK_ARGS = {
|
|
270
271
|
task: { descriptor: "task: task-slug folder (the one the dispatch named)" },
|
|
271
272
|
topic: { descriptor: "topic: file topic, becomes the name after NN-<role>-" },
|