@te-river/opencode-team-mode 1.6.1 → 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/note.d.ts.map +1 -1
- package/dist/host/note.js +8 -5
- package/dist/host/note.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 +43 -0
- package/dist/host/v2-capabilities.d.ts.map +1 -1
- package/dist/host/v2-capabilities.js +77 -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 +62 -7
- package/dist/host/v2-session-client.d.ts.map +1 -1
- package/dist/host/v2-session-client.js +485 -26
- 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 +648 -74
- 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 +44 -27
- 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 +74 -57
- 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 +154 -22
- package/dist/tm/dispatch.d.ts.map +1 -1
- package/dist/tm/dispatch.js +559 -80
- 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 +31 -27
- package/dist/tm/stats.d.ts.map +1 -1
- package/dist/tm/stats.js +170 -58
- 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 +124 -39
- package/docs/installation.md +9 -0
- package/docs/research/browser-pane.md +5 -0
- package/docs/v2-port-notes.md +500 -315
- package/package.json +1 -1
- package/scripts/gen-v2-config.mjs +246 -94
- package/scripts/lib/fake-ctx.mjs +244 -146
package/dist/capabilities.d.ts
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Host-capability
|
|
2
|
+
* Host-capability matrix — the "fail loud, not silent" seam (2026-09-19).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* dialog out of the build, and the only symptom is the agent working around
|
|
12
|
-
* something the user never agreed to lose.
|
|
4
|
+
* This file holds the SHARED row contract and the markdown renderer. The v1
|
|
5
|
+
* probe that used to live here (a static SEAMS list classified by watching
|
|
6
|
+
* hooks fire and events arrive) was removed in 1.7.0 with the rest of v1
|
|
7
|
+
* support; the v2 rows are built from what THIS session observed in
|
|
8
|
+
* `src/host/v2-capabilities.ts`, because a 2.x host is moving under us and a
|
|
9
|
+
* row that says "declared" because a type file mentions a name is worth
|
|
10
|
+
* nothing when the host never calls it.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
12
|
+
* Row states (the vocabulary both sides share):
|
|
15
13
|
* - `missing` — the surface is gone; the named feature is off.
|
|
16
14
|
* - `declared` — the surface exists but nothing has exercised it yet.
|
|
17
15
|
* - `ok` — observed working in this process (a hook fired, an event
|
|
@@ -22,9 +20,8 @@
|
|
|
22
20
|
* (the `attachments` screenshot — the host either paints it
|
|
23
21
|
* or ignores it, and we cannot observe which).
|
|
24
22
|
*
|
|
25
|
-
* `tm_stats` renders the live matrix;
|
|
26
|
-
*
|
|
27
|
-
* mid-task. Nothing here ever throws and nothing probes the network.
|
|
23
|
+
* `tm_stats` renders the live matrix; nothing here ever throws and nothing
|
|
24
|
+
* probes the network.
|
|
28
25
|
*/
|
|
29
26
|
/** How each row was decided — kept as data so a test can pin the reasoning. */
|
|
30
27
|
export type CapState = "ok" | "declared" | "missing" | "not-seen" | "unverified";
|
|
@@ -38,29 +35,6 @@ export interface CapabilityRow {
|
|
|
38
35
|
evidence: CapEvidence;
|
|
39
36
|
note?: string;
|
|
40
37
|
}
|
|
41
|
-
export interface CapabilityProbe {
|
|
42
|
-
observeAskBridge(present: boolean): void;
|
|
43
|
-
observeEvent(type: string): void;
|
|
44
|
-
observeHook(name: string): void;
|
|
45
|
-
/** Live matrix for tm_stats. */
|
|
46
|
-
snapshot(): CapabilityRow[];
|
|
47
|
-
/** Rows the plugin considers load-bearing and did NOT find. */
|
|
48
|
-
missingRequired(): CapabilityRow[];
|
|
49
|
-
/** One trajectory line + (when something required is gone) one toast. */
|
|
50
|
-
report(): {
|
|
51
|
-
rows: CapabilityRow[];
|
|
52
|
-
missing: string[];
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
export declare function createCapabilityProbe(deps: {
|
|
56
|
-
client: unknown;
|
|
57
|
-
/** `input.$` — the host shell bridge, handed outside the client object. */
|
|
58
|
-
hasShellBridge?: boolean;
|
|
59
|
-
/** Already-resolved R6 reply capability (index.ts owns that decision). */
|
|
60
|
-
hasPermissionReply?: boolean;
|
|
61
|
-
trajectory?: (event: Record<string, unknown>) => void;
|
|
62
|
-
notify?: (message: string) => void;
|
|
63
|
-
}): CapabilityProbe;
|
|
64
38
|
/** Markdown table for tm_stats — the shape the host renders fastest. */
|
|
65
39
|
export declare function renderCapabilityMatrix(rows: readonly CapabilityRow[]): string;
|
|
66
40
|
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,CAAA;AAEhF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAA;AAE3E,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAA;IACZ,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,QAAQ,CAAA;IACf,QAAQ,EAAE,WAAW,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wEAAwE;AACxE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAQ7E"}
|
package/dist/capabilities.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Host-capability
|
|
2
|
+
* Host-capability matrix — the "fail loud, not silent" seam (2026-09-19).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* dialog out of the build, and the only symptom is the agent working around
|
|
12
|
-
* something the user never agreed to lose.
|
|
4
|
+
* This file holds the SHARED row contract and the markdown renderer. The v1
|
|
5
|
+
* probe that used to live here (a static SEAMS list classified by watching
|
|
6
|
+
* hooks fire and events arrive) was removed in 1.7.0 with the rest of v1
|
|
7
|
+
* support; the v2 rows are built from what THIS session observed in
|
|
8
|
+
* `src/host/v2-capabilities.ts`, because a 2.x host is moving under us and a
|
|
9
|
+
* row that says "declared" because a type file mentions a name is worth
|
|
10
|
+
* nothing when the host never calls it.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
12
|
+
* Row states (the vocabulary both sides share):
|
|
15
13
|
* - `missing` — the surface is gone; the named feature is off.
|
|
16
14
|
* - `declared` — the surface exists but nothing has exercised it yet.
|
|
17
15
|
* - `ok` — observed working in this process (a hook fired, an event
|
|
@@ -22,137 +20,9 @@
|
|
|
22
20
|
* (the `attachments` screenshot — the host either paints it
|
|
23
21
|
* or ignores it, and we cannot observe which).
|
|
24
22
|
*
|
|
25
|
-
* `tm_stats` renders the live matrix;
|
|
26
|
-
*
|
|
27
|
-
* mid-task. Nothing here ever throws and nothing probes the network.
|
|
23
|
+
* `tm_stats` renders the live matrix; nothing here ever throws and nothing
|
|
24
|
+
* probes the network.
|
|
28
25
|
*/
|
|
29
|
-
const SEAMS = [
|
|
30
|
-
{
|
|
31
|
-
seam: "ToolContext.ask",
|
|
32
|
-
feature: "out-of-allowlist web fetch/search/browser + every tm_pty start",
|
|
33
|
-
evidence: "runtime",
|
|
34
|
-
observed: ["ask-bridge"],
|
|
35
|
-
required: true,
|
|
36
|
-
note: "first observed by whichever tm_* tool runs",
|
|
37
|
-
},
|
|
38
|
-
{ seam: "client.session.messages", feature: "tm_join (collecting a sub-agent reply)", evidence: "static", path: "session.messages", required: true },
|
|
39
|
-
{ seam: "client.session.children", feature: "tm_join recovery after a restart", evidence: "static", path: "session.children" },
|
|
40
|
-
{ seam: "client.session.status", feature: "tm_join bounded wait", evidence: "static", path: "session.status" },
|
|
41
|
-
{ seam: "client.session.abort", feature: "tm_join cancel:true", evidence: "static", path: "session.abort" },
|
|
42
|
-
{ seam: "client.pty.create", feature: "tm_pty (non-blocking commands)", evidence: "static", path: "pty.create", required: true },
|
|
43
|
-
{ seam: "client.permission.reply", feature: "the approval gate's auto-reject timer", evidence: "static", path: "permission.reply", required: true },
|
|
44
|
-
{ seam: "tui.showToast", feature: "a toast when a dialog is waiting", evidence: "static", path: "tui.showToast" },
|
|
45
|
-
{ seam: "input.$ (shell bridge)", feature: "tm_bash via the host shell (else spawn fallback)", evidence: "static", path: "$" },
|
|
46
|
-
{
|
|
47
|
-
seam: "event permission.asked",
|
|
48
|
-
feature: "R6/R2 dialog observation + the unanswered-ask timer",
|
|
49
|
-
evidence: "event",
|
|
50
|
-
observed: ["permission.asked"],
|
|
51
|
-
note: "only arrives once something asks — absence so far is not a break",
|
|
52
|
-
},
|
|
53
|
-
{ seam: "hook tool.execute.before", feature: "bash timeout clamp + R6 deferral", evidence: "hook", observed: ["hook:tool.execute.before"], required: true },
|
|
54
|
-
{ seam: "hook tool.definition", feature: "TM_TOOL_HINTS on built-in bash/task", evidence: "hook", observed: ["hook:tool.definition"] },
|
|
55
|
-
{ seam: "hook chat.params", feature: "TM_AGENT_TEMPERATURE", evidence: "hook", observed: ["hook:chat.params"] },
|
|
56
|
-
{ seam: "hook shell.env", feature: "NO_COLOR / TM_SHELL_ENV passthrough", evidence: "hook", observed: ["hook:shell.env"] },
|
|
57
|
-
{ seam: "hook experimental.session.compacting", feature: "the must-survive compaction context", evidence: "hook", observed: ["hook:session.compacting"] },
|
|
58
|
-
{
|
|
59
|
-
seam: "ToolResult.attachments",
|
|
60
|
-
feature: "tm_browser take_screenshot { image:true }",
|
|
61
|
-
evidence: "human",
|
|
62
|
-
state: "unverified",
|
|
63
|
-
note: "we emit the official shape; whether the desktop paints it is only visible to you",
|
|
64
|
-
},
|
|
65
|
-
];
|
|
66
|
-
/** Read a dot path off the live client without assuming any of it exists. */
|
|
67
|
-
function pathPresent(client, dotted) {
|
|
68
|
-
if (dotted === "$")
|
|
69
|
-
return false; // resolved by the caller — not a client path
|
|
70
|
-
let cur = client;
|
|
71
|
-
for (const seg of dotted.split(".")) {
|
|
72
|
-
if (!cur || typeof cur !== "object")
|
|
73
|
-
return false;
|
|
74
|
-
cur = cur[seg];
|
|
75
|
-
}
|
|
76
|
-
return typeof cur === "function";
|
|
77
|
-
}
|
|
78
|
-
export function createCapabilityProbe(deps) {
|
|
79
|
-
const ok = new Set();
|
|
80
|
-
if (deps.hasShellBridge)
|
|
81
|
-
ok.add("$");
|
|
82
|
-
if (deps.hasPermissionReply)
|
|
83
|
-
ok.add("permission.reply");
|
|
84
|
-
const presentOf = (spec) => {
|
|
85
|
-
if (!spec.path)
|
|
86
|
-
return null;
|
|
87
|
-
if (spec.path === "$")
|
|
88
|
-
return !!deps.hasShellBridge;
|
|
89
|
-
if (spec.path === "permission.reply")
|
|
90
|
-
return !!deps.hasPermissionReply;
|
|
91
|
-
return pathPresent(deps.client, spec.path);
|
|
92
|
-
};
|
|
93
|
-
const rowFor = (spec) => {
|
|
94
|
-
const observed = (spec.observed ?? []).some((name) => ok.has(name));
|
|
95
|
-
const present = presentOf(spec);
|
|
96
|
-
const row = { seam: spec.seam, feature: spec.feature, evidence: spec.evidence, state: "not-seen" };
|
|
97
|
-
if (spec.state === "unverified")
|
|
98
|
-
row.state = "unverified";
|
|
99
|
-
else if (observed)
|
|
100
|
-
row.state = "ok";
|
|
101
|
-
else if (present === false)
|
|
102
|
-
row.state = "missing";
|
|
103
|
-
else if (spec.evidence === "static")
|
|
104
|
-
row.state = "declared";
|
|
105
|
-
else
|
|
106
|
-
row.state = "not-seen";
|
|
107
|
-
if (spec.note)
|
|
108
|
-
row.note = spec.note;
|
|
109
|
-
return row;
|
|
110
|
-
};
|
|
111
|
-
let reported = false;
|
|
112
|
-
const report = () => {
|
|
113
|
-
const rows = SEAMS.map(rowFor);
|
|
114
|
-
const missing = rows.filter((r) => r.state === "missing").map((r) => r.seam);
|
|
115
|
-
if (reported)
|
|
116
|
-
return { rows, missing };
|
|
117
|
-
reported = true;
|
|
118
|
-
try {
|
|
119
|
-
deps.trajectory?.({ tool: "capabilities", step_id: "boot", event: "probe", rows: rows.map((r) => `${r.seam}=${r.state}`) });
|
|
120
|
-
}
|
|
121
|
-
catch {
|
|
122
|
-
/* observability only */
|
|
123
|
-
}
|
|
124
|
-
const required = SEAMS.filter((s, i) => s.required && rows[i].state === "missing").map((s) => s.feature);
|
|
125
|
-
if (required.length) {
|
|
126
|
-
try {
|
|
127
|
-
deps.notify?.(`检测到宿主接口缺失,本进程已降级:${required.join(";")}。` +
|
|
128
|
-
`(OpenCode 升级后常见。用 tm_stats 看完整能力矩阵。)`);
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
/* notification is best-effort */
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return { rows, missing };
|
|
135
|
-
};
|
|
136
|
-
return {
|
|
137
|
-
observeAskBridge(present) {
|
|
138
|
-
if (present)
|
|
139
|
-
ok.add("ask-bridge");
|
|
140
|
-
},
|
|
141
|
-
observeEvent(type) {
|
|
142
|
-
const t = String(type ?? "");
|
|
143
|
-
if (t === "permission.asked" || t === "permission.updated")
|
|
144
|
-
ok.add("permission.asked");
|
|
145
|
-
},
|
|
146
|
-
observeHook(name) {
|
|
147
|
-
const n = String(name ?? "");
|
|
148
|
-
if (n)
|
|
149
|
-
ok.add(`hook:${n}`);
|
|
150
|
-
},
|
|
151
|
-
snapshot: () => SEAMS.map(rowFor),
|
|
152
|
-
missingRequired: () => SEAMS.map(rowFor).filter((r, i) => SEAMS[i].required && r.state === "missing"),
|
|
153
|
-
report,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
26
|
/** Markdown table for tm_stats — the shape the host renders fastest. */
|
|
157
27
|
export function renderCapabilityMatrix(rows) {
|
|
158
28
|
const badge = (s) => s === "ok" ? "✓ 已验证" : s === "declared" ? "◦ 存在未用" : s === "missing" ? "✗ 缺失" : s === "not-seen" ? "… 待观察" : "? 需人眼";
|
package/dist/capabilities.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAiBH,wEAAwE;AACxE,MAAM,UAAU,sBAAsB,CAAC,IAA8B;IACnE,MAAM,KAAK,GAAG,CAAC,CAAW,EAAU,EAAE,CACpC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAA;IACtH,MAAM,KAAK,GAAG,CAAC,uBAAuB,EAAE,eAAe,CAAC,CAAA;IACxD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,OAAO,MAAM,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IACnG,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
package/dist/commands.js
CHANGED
|
@@ -104,7 +104,7 @@ Cite your sources with file:line paths. Do not fabricate APIs or citations.`,
|
|
|
104
104
|
/* ------------------------------------------------------------------ */
|
|
105
105
|
const teamRun = {
|
|
106
106
|
description: "Full team workflow — deterministic routing, approval gate on >=2 dispatches, structured handoffs.",
|
|
107
|
-
agent: "
|
|
107
|
+
agent: "Team",
|
|
108
108
|
template: `Execute the full team workflow for the following task.
|
|
109
109
|
|
|
110
110
|
## Task
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* R6 —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* R6 — file-tool path classification and tool-call level routing
|
|
3
|
+
* (tm_* aliasing = anti-backdoor). Split out of the former monolithic
|
|
4
|
+
* envprotect.ts; behavior unchanged.
|
|
5
|
+
*
|
|
6
|
+
* The `tool.execute.before` HOOK FACTORY that used to live here
|
|
7
|
+
* (`createEnvProtectHook`, with its `auditInterception` and its deferral to the
|
|
8
|
+
* approval gate) was deleted with the v1 personality: v2 has no plugin-raised
|
|
9
|
+
* dialog to defer to, and the enforcement that remains on v2 is the per-command
|
|
10
|
+
* classifier at `src/host/v2-guard.ts` (`shellGuard`) riding
|
|
11
|
+
* `permission.hook("evaluate")`. What stays in this file is the CLASSIFIER
|
|
12
|
+
* SURFACE both personalities' tests pin — the matchers are the product, the
|
|
13
|
+
* v1 hook was only one way to call them.
|
|
6
14
|
*/
|
|
7
15
|
import { type EnvProtectMode } from "./patterns.js";
|
|
8
16
|
/**
|
|
@@ -15,31 +23,4 @@ export declare function classifyPathFields(args: Record<string, unknown> | undef
|
|
|
15
23
|
* `off` always passes (the hook stays installed but is a no-op).
|
|
16
24
|
*/
|
|
17
25
|
export declare function inspectToolCall(tool: string, args: Record<string, unknown> | undefined, mode: EnvProtectMode, extra?: RegExp[]): string | null;
|
|
18
|
-
/**
|
|
19
|
-
* Build the `tool.execute.before` hook. The hook is installed in every
|
|
20
|
-
* mode; with mode "off" it returns immediately and everything passes.
|
|
21
|
-
* When a block triggers, the audit entry is written first, then the fixed
|
|
22
|
-
* structured error is thrown so opencode surfaces it to the model as the
|
|
23
|
-
* failed tool result.
|
|
24
|
-
*
|
|
25
|
-
* `options.deferToApproval` (the unified approval gate) — called with the
|
|
26
|
-
* tool call's `input.sessionID`; when it reports `true`, a built-in-bash
|
|
27
|
-
* environment read in an EXACT ask-glob form is passed through WITHOUT
|
|
28
|
-
* throwing, because the official confirmation dialog is the live gate for
|
|
29
|
-
* it (approve → runs, reject or timeout → the host blocks it). The signal
|
|
30
|
-
* is SESSION-SCOPED on purpose: the gate registers only sessions carrying
|
|
31
|
-
* our injected bash ask set (exec-role chat.message, or an R6-env-classified
|
|
32
|
-
* `permission.asked`), so a stock build/plan session — where no dialog would
|
|
33
|
-
* ever open for `printenv` — keeps the hard throw instead of slipping the
|
|
34
|
-
* read through a global arm flag. Reaching the deferral point at all
|
|
35
|
-
* additionally requires the command to match the config globs byte-exactly,
|
|
36
|
-
* so the dialog is GUARANTEED to fire wherever deferral happens. A failed
|
|
37
|
-
* auto-reject flips the gate back to `false` everywhere, restoring the hard
|
|
38
|
-
* throw (fail-closed). tm_* channels are never deferred (no dialog opens
|
|
39
|
-
* for them).
|
|
40
|
-
*/
|
|
41
|
-
export declare function createEnvProtectHook(client: unknown, mode: EnvProtectMode, extra?: RegExp[], options?: {
|
|
42
|
-
deferToApproval?: (sessionID?: string) => boolean;
|
|
43
|
-
envApproved?: (sessionID?: string) => boolean;
|
|
44
|
-
}): (input: unknown, output: unknown) => Promise<void>;
|
|
45
26
|
//# sourceMappingURL=hook.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/envprotect/hook.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/envprotect/hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAA+C,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAchG;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,IAAI,EAAE,cAAc,EACpB,KAAK,GAAE,MAAM,EAAO,GACnB,MAAM,GAAG,IAAI,CAWf;AAoBD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,IAAI,EAAE,cAAc,EACpB,KAAK,GAAE,MAAM,EAAO,GACnB,MAAM,GAAG,IAAI,CAYf"}
|
package/dist/envprotect/hook.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* R6 —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* R6 — file-tool path classification and tool-call level routing
|
|
3
|
+
* (tm_* aliasing = anti-backdoor). Split out of the former monolithic
|
|
4
|
+
* envprotect.ts; behavior unchanged.
|
|
5
|
+
*
|
|
6
|
+
* The `tool.execute.before` HOOK FACTORY that used to live here
|
|
7
|
+
* (`createEnvProtectHook`, with its `auditInterception` and its deferral to the
|
|
8
|
+
* approval gate) was deleted with the v1 personality: v2 has no plugin-raised
|
|
9
|
+
* dialog to defer to, and the enforcement that remains on v2 is the per-command
|
|
10
|
+
* classifier at `src/host/v2-guard.ts` (`shellGuard`) riding
|
|
11
|
+
* `permission.hook("evaluate")`. What stays in this file is the CLASSIFIER
|
|
12
|
+
* SURFACE both personalities' tests pin — the matchers are the product, the
|
|
13
|
+
* v1 hook was only one way to call them.
|
|
6
14
|
*/
|
|
7
|
-
import { CATEGORY_ENV_FILE_PATH, CATEGORY_EXTRA_DENY
|
|
15
|
+
import { CATEGORY_ENV_FILE_PATH, CATEGORY_EXTRA_DENY } from "./patterns.js";
|
|
8
16
|
import { classifyBashCommand } from "./bash-classify.js";
|
|
9
17
|
import { isEnvFilePath } from "./path-classify.js";
|
|
10
|
-
import { isAskGatedEnvCommand } from "./gate-predicates.js";
|
|
11
18
|
// ---------- file-tool path classification ----------
|
|
12
19
|
/**
|
|
13
20
|
* Path-class argument keys scanned defensively across read / grep / glob /
|
|
@@ -70,89 +77,4 @@ export function inspectToolCall(tool, args, mode, extra = []) {
|
|
|
70
77
|
}
|
|
71
78
|
return null;
|
|
72
79
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Best-effort audit of one interception. Records ONLY the tool name and
|
|
75
|
-
* the pattern category (privacy red line: never command text, paths,
|
|
76
|
-
* variable names or values); the message embeds the service id itself so
|
|
77
|
-
* file-backed log sinks that drop the `service` field stay greppable. A
|
|
78
|
-
* failing audit endpoint must never turn a block into a pass-through, so
|
|
79
|
-
* every failure is swallowed after the call attempt.
|
|
80
|
-
*/
|
|
81
|
-
async function auditInterception(client, tool, category) {
|
|
82
|
-
try {
|
|
83
|
-
// Call the method THROUGH the app object. Destructuring `app.log`
|
|
84
|
-
// first would drop the SDK's `this` binding, so every real call died
|
|
85
|
-
// inside the SDK and was silently swallowed here — zero audit entries.
|
|
86
|
-
const app = client?.app;
|
|
87
|
-
if (!app || typeof app.log !== "function")
|
|
88
|
-
return;
|
|
89
|
-
await app.log({
|
|
90
|
-
body: {
|
|
91
|
-
level: "warn",
|
|
92
|
-
service: ENV_PROTECT_SERVICE,
|
|
93
|
-
message: `${ENV_PROTECT_SERVICE} :: ${tool} :: ${category}`,
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
/* audit is best-effort; the block below still takes effect */
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Build the `tool.execute.before` hook. The hook is installed in every
|
|
103
|
-
* mode; with mode "off" it returns immediately and everything passes.
|
|
104
|
-
* When a block triggers, the audit entry is written first, then the fixed
|
|
105
|
-
* structured error is thrown so opencode surfaces it to the model as the
|
|
106
|
-
* failed tool result.
|
|
107
|
-
*
|
|
108
|
-
* `options.deferToApproval` (the unified approval gate) — called with the
|
|
109
|
-
* tool call's `input.sessionID`; when it reports `true`, a built-in-bash
|
|
110
|
-
* environment read in an EXACT ask-glob form is passed through WITHOUT
|
|
111
|
-
* throwing, because the official confirmation dialog is the live gate for
|
|
112
|
-
* it (approve → runs, reject or timeout → the host blocks it). The signal
|
|
113
|
-
* is SESSION-SCOPED on purpose: the gate registers only sessions carrying
|
|
114
|
-
* our injected bash ask set (exec-role chat.message, or an R6-env-classified
|
|
115
|
-
* `permission.asked`), so a stock build/plan session — where no dialog would
|
|
116
|
-
* ever open for `printenv` — keeps the hard throw instead of slipping the
|
|
117
|
-
* read through a global arm flag. Reaching the deferral point at all
|
|
118
|
-
* additionally requires the command to match the config globs byte-exactly,
|
|
119
|
-
* so the dialog is GUARANTEED to fire wherever deferral happens. A failed
|
|
120
|
-
* auto-reject flips the gate back to `false` everywhere, restoring the hard
|
|
121
|
-
* throw (fail-closed). tm_* channels are never deferred (no dialog opens
|
|
122
|
-
* for them).
|
|
123
|
-
*/
|
|
124
|
-
export function createEnvProtectHook(client, mode, extra = [], options = {}) {
|
|
125
|
-
return async (input, output) => {
|
|
126
|
-
if (mode === "off")
|
|
127
|
-
return;
|
|
128
|
-
const tool = String(input?.tool ?? "");
|
|
129
|
-
const rawSid = input?.sessionID;
|
|
130
|
-
const sessionID = typeof rawSid === "string" && rawSid.trim() !== "" ? rawSid.trim() : undefined;
|
|
131
|
-
const args = output?.args;
|
|
132
|
-
const category = inspectToolCall(tool, args, mode, extra);
|
|
133
|
-
if (!category)
|
|
134
|
-
return;
|
|
135
|
-
// Session-wide env approval ("always" on first env ask) — pass silently;
|
|
136
|
-
// the "always" event itself was already audited by the approval gate.
|
|
137
|
-
// The blanket NEVER covers env-FILE reads (CATEGORY_ENV_FILE_PATH):
|
|
138
|
-
// files on disk (.env, shell rc family) never open a dialog of their
|
|
139
|
-
// own (they are not in the ask-pattern set), so no "always" verdict can
|
|
140
|
-
// have consented to them — they keep hard-throwing even in an
|
|
141
|
-
// env-approved session.
|
|
142
|
-
if (sessionID &&
|
|
143
|
-
options.envApproved?.(sessionID) &&
|
|
144
|
-
category !== CATEGORY_ENV_FILE_PATH) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
// Defer ONLY the built-in bash tool (never its tm_bash alias), ONLY in a
|
|
148
|
-
// registered session, for the exact forms the config escalates to `ask`.
|
|
149
|
-
if (tool.trim().toLowerCase() === "bash" && sessionID && options.deferToApproval?.(sessionID)) {
|
|
150
|
-
const command = args?.command;
|
|
151
|
-
if (isAskGatedEnvCommand(String(command ?? ""), mode, extra))
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
await auditInterception(client, tool, category);
|
|
155
|
-
throw envProtectError(category);
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
80
|
//# sourceMappingURL=hook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/envprotect/hook.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/envprotect/hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAuB,MAAM,eAAe,CAAA;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,sDAAsD;AAEtD;;;;;GAKG;AACH,MAAM,cAAc,GAAG,uDAAuD,CAAA;AAE9E;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAyC,EACzC,IAAoB,EACpB,QAAkB,EAAE;IAEpB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAClD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK;YAAE,SAAQ;QACjD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,SAAQ;QACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,mBAAmB,CAAA;QAClD,CAAC;QACD,IAAI,aAAa,CAAC,KAAK,CAAC;YAAE,OAAO,sBAAsB,CAAA;IACzD,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,gDAAgD;AAEhD,uEAAuE;AACvE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAEjE;;;;;;GAMG;AACH,MAAM,eAAe,GAA2B;IAC9C,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;CAChB,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,IAAyC,EACzC,IAAoB,EACpB,QAAkB,EAAE;IAEpB,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,CAAA;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACvD,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,OAAO,CAAA;IAChD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,MAAM,OAAO,GAAI,IAA0C,EAAE,OAAO,CAAA;QACpE,OAAO,mBAAmB,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;IAChE,CAAC;IACD,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* Split out of the former monolithic envprotect.ts; behavior unchanged.
|
|
5
5
|
*
|
|
6
6
|
* These are the shapes a wildcard CAN express (head-anchored globs). The
|
|
7
|
-
* plugin NEVER self-allows; an unanswered dialog is
|
|
8
|
-
*
|
|
7
|
+
* plugin NEVER self-allows; an unanswered dialog is the host's own to resolve
|
|
8
|
+
* (v2 gives a plugin no dialog to raise, so the guard fails closed — see
|
|
9
|
+
* src/host/v2-guard.ts).
|
|
9
10
|
*/
|
|
10
11
|
/** Audit log service identifier (also the query key for "what was blocked"). */
|
|
11
12
|
export declare const ENV_PROTECT_SERVICE = "team-mode-env-protect";
|
|
@@ -24,8 +25,9 @@ export declare const CATEGORY_EXTRA_DENY = "extra-deny";
|
|
|
24
25
|
* declaring them `ask` in each agent's bash permission object. The host
|
|
25
26
|
* pops a dialog for any command matching one of these patterns and SUSPENDS
|
|
26
27
|
* it: a human reply ("once"/"always") runs the command, a "reject" or NO
|
|
27
|
-
* REPLY is
|
|
28
|
-
*
|
|
28
|
+
* REPLY is the host's own to resolve — v2 gives a plugin no dialog to raise,
|
|
29
|
+
* so the guard fails closed (see src/host/v2-guard.ts). The plugin NEVER
|
|
30
|
+
* self-allows.
|
|
29
31
|
*
|
|
30
32
|
* These are the shapes a wildcard CAN express (head-anchored globs, matching
|
|
31
33
|
* the probe-verified grammar: `printenv*`, `rm *`, `Get-ChildItem env:*`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/envprotect/patterns.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/envprotect/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,0BAA0B,CAAA;AAE1D;;;GAGG;AACH,eAAO,MAAM,mBAAmB,sKAC4B,CAAA;AAE5D,0EAA0E;AAC1E,eAAO,MAAM,yBAAyB,qBAAqB,CAAA;AAC3D,eAAO,MAAM,2BAA2B,uBAAuB,CAAA;AAC/D,eAAO,MAAM,sBAAsB,kBAAkB,CAAA;AACrD,eAAO,MAAM,mBAAmB,eAAe,CAAA;AAK/C;;;;;;;;;;;;;;;;;GAiBG;AAEH,yEAAyE;AACzE,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAyB1D,CAAA;AAEF;;;6EAG6E;AAC7E,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CA6C7D,CAAA;AAEF,6EAA6E;AAC7E,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAErD,CAAA;AACD,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAExD,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,UAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO5F;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,CAAA;AAE1D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAIlE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAarD;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAEvD"}
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* Split out of the former monolithic envprotect.ts; behavior unchanged.
|
|
5
5
|
*
|
|
6
6
|
* These are the shapes a wildcard CAN express (head-anchored globs). The
|
|
7
|
-
* plugin NEVER self-allows; an unanswered dialog is
|
|
8
|
-
*
|
|
7
|
+
* plugin NEVER self-allows; an unanswered dialog is the host's own to resolve
|
|
8
|
+
* (v2 gives a plugin no dialog to raise, so the guard fails closed — see
|
|
9
|
+
* src/host/v2-guard.ts).
|
|
9
10
|
*/
|
|
10
11
|
/** Audit log service identifier (also the query key for "what was blocked"). */
|
|
11
12
|
export const ENV_PROTECT_SERVICE = "team-mode-env-protect";
|
|
@@ -27,8 +28,9 @@ export const CATEGORY_EXTRA_DENY = "extra-deny";
|
|
|
27
28
|
* declaring them `ask` in each agent's bash permission object. The host
|
|
28
29
|
* pops a dialog for any command matching one of these patterns and SUSPENDS
|
|
29
30
|
* it: a human reply ("once"/"always") runs the command, a "reject" or NO
|
|
30
|
-
* REPLY is
|
|
31
|
-
*
|
|
31
|
+
* REPLY is the host's own to resolve — v2 gives a plugin no dialog to raise,
|
|
32
|
+
* so the guard fails closed (see src/host/v2-guard.ts). The plugin NEVER
|
|
33
|
+
* self-allows.
|
|
32
34
|
*
|
|
33
35
|
* These are the shapes a wildcard CAN express (head-anchored globs, matching
|
|
34
36
|
* the probe-verified grammar: `printenv*`, `rm *`, `Get-ChildItem env:*`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/envprotect/patterns.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/envprotect/patterns.ts"],"names":[],"mappings":"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"}
|
package/dist/envprotect.d.ts
CHANGED
|
@@ -32,5 +32,5 @@ export type { EnvProtectMode } from "./envprotect/patterns.js";
|
|
|
32
32
|
export { isEnvFilePath } from "./envprotect/path-classify.js";
|
|
33
33
|
export { classifyBashCommand } from "./envprotect/bash-classify.js";
|
|
34
34
|
export { categorizePermission, commandMatchesAnyAskPattern, isAskGatedEnvCommand, } from "./envprotect/gate-predicates.js";
|
|
35
|
-
export { classifyPathFields,
|
|
35
|
+
export { classifyPathFields, inspectToolCall } from "./envprotect/hook.js";
|
|
36
36
|
//# sourceMappingURL=envprotect.d.ts.map
|
package/dist/envprotect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envprotect.d.ts","sourceRoot":"","sources":["../src/envprotect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,eAAe,EACf,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,qBAAqB,GACtB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"envprotect.d.ts","sourceRoot":"","sources":["../src/envprotect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,eAAe,EACf,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,qBAAqB,GACtB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA"}
|
package/dist/envprotect.js
CHANGED
|
@@ -31,5 +31,5 @@ export { CATEGORY_BASH_ENV_COMMAND, CATEGORY_BASH_ENV_EXPANSION, CATEGORY_ENV_FI
|
|
|
31
31
|
export { isEnvFilePath } from "./envprotect/path-classify.js";
|
|
32
32
|
export { classifyBashCommand } from "./envprotect/bash-classify.js";
|
|
33
33
|
export { categorizePermission, commandMatchesAnyAskPattern, isAskGatedEnvCommand, } from "./envprotect/gate-predicates.js";
|
|
34
|
-
export { classifyPathFields,
|
|
34
|
+
export { classifyPathFields, inspectToolCall } from "./envprotect/hook.js";
|
|
35
35
|
//# sourceMappingURL=envprotect.js.map
|
package/dist/envprotect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envprotect.js","sourceRoot":"","sources":["../src/envprotect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,eAAe,EACf,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,qBAAqB,GACtB,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"envprotect.js","sourceRoot":"","sources":["../src/envprotect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,eAAe,EACf,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,qBAAqB,GACtB,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA"}
|
package/dist/host/note.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../../src/host/note.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../../src/host/note.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAwBpE"}
|
package/dist/host/note.js
CHANGED
|
@@ -13,14 +13,17 @@ export function blackboardNote(root, ttlDays) {
|
|
|
13
13
|
` skeleton) are the PRIMARY transport — normal work needs no files at all.`,
|
|
14
14
|
`- Board files exist ONLY for oversized deliverables (>~50 lines), and they`,
|
|
15
15
|
` go through \`tm_board_write { task, topic, content, session? }\` — the board's`,
|
|
16
|
-
` write side, carried by every role including the ones with no file
|
|
17
|
-
`
|
|
18
|
-
`
|
|
16
|
+
` write side, carried by every role including the ones with no write-capable file`,
|
|
17
|
+
` tool. Where your tool list does not name it, the Code Mode catalog holds it:`,
|
|
18
|
+
` \`execute\` → \`tools.tm_board_write({ task, topic, content })\`. Never hand-write`,
|
|
19
|
+
` the file — the writer is what places`,
|
|
20
|
+
` \`<root>/<session-key>/<task-slug>/NN-<role>-<topic>[-rN].md\`, never overwrites,`,
|
|
21
|
+
` and answers with the PATH (never the content).`,
|
|
19
22
|
` On the FIRST board write of this conversation pass a session folder made from`,
|
|
20
23
|
` a compact clock timestamp (PowerShell: \`Get-Date -Format yyyyMMdd-HHmmss\`;`,
|
|
21
24
|
` POSIX: \`date +%Y%m%d-%H%M%S\`) and reuse it for every later task; omit it and`,
|
|
22
|
-
` the tool stamps one — that is how a role with no
|
|
23
|
-
` all. Never write into another conversation's session folder.`,
|
|
25
|
+
` the tool stamps one — that is how a role with no command shell reaches the`,
|
|
26
|
+
` board at all. Never write into another conversation's session folder.`,
|
|
24
27
|
`- Auto-cleanup: the plugin sweeps task directories idle for more than ${ttlDays} days (at startup and hourly).`,
|
|
25
28
|
` This is the ONLY cleanup path — never delete task or session directories yourself.`,
|
|
26
29
|
].join("\n");
|
package/dist/host/note.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"note.js","sourceRoot":"","sources":["../../src/host/note.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,OAAe;IAC1D,OAAO;QACL,EAAE;QACF,EAAE;QACF,kDAAkD;QAClD,qBAAqB,IAAI,IAAI;QAC7B,oFAAoF;QACpF,4EAA4E;QAC5E,4EAA4E;QAC5E,kFAAkF;QAClF
|
|
1
|
+
{"version":3,"file":"note.js","sourceRoot":"","sources":["../../src/host/note.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,OAAe;IAC1D,OAAO;QACL,EAAE;QACF,EAAE;QACF,kDAAkD;QAClD,qBAAqB,IAAI,IAAI;QAC7B,oFAAoF;QACpF,4EAA4E;QAC5E,4EAA4E;QAC5E,kFAAkF;QAClF,mFAAmF;QACnF,iFAAiF;QACjF,uFAAuF;QACvF,wCAAwC;QACxC,qFAAqF;QACrF,kDAAkD;QAClD,iFAAiF;QACjF,gFAAgF;QAChF,kFAAkF;QAClF,8EAA8E;QAC9E,0EAA0E;QAC1E,yEAAyE,OAAO,gCAAgC;QAChH,sFAAsF;KACvF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
|