@te-river/opencode-team-mode 1.4.9 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -38
- package/README.zh-CN.md +58 -38
- package/dist/envprotect.d.ts +123 -0
- package/dist/envprotect.d.ts.map +1 -0
- package/dist/envprotect.js +467 -0
- package/dist/envprotect.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/tm/config.d.ts +71 -0
- package/dist/tm/config.d.ts.map +1 -0
- package/dist/tm/config.js +97 -0
- package/dist/tm/config.js.map +1 -0
- package/dist/tm/guard.d.ts +56 -0
- package/dist/tm/guard.d.ts.map +1 -0
- package/dist/tm/guard.js +249 -0
- package/dist/tm/guard.js.map +1 -0
- package/dist/tm/index.d.ts +39 -0
- package/dist/tm/index.d.ts.map +1 -0
- package/dist/tm/index.js +63 -0
- package/dist/tm/index.js.map +1 -0
- package/dist/tm/preview.d.ts +46 -0
- package/dist/tm/preview.d.ts.map +1 -0
- package/dist/tm/preview.js +354 -0
- package/dist/tm/preview.js.map +1 -0
- package/dist/tm/refs.d.ts +37 -0
- package/dist/tm/refs.d.ts.map +1 -0
- package/dist/tm/refs.js +58 -0
- package/dist/tm/refs.js.map +1 -0
- package/dist/tm/store.d.ts +95 -0
- package/dist/tm/store.d.ts.map +1 -0
- package/dist/tm/store.js +222 -0
- package/dist/tm/store.js.map +1 -0
- package/dist/tm/tools.d.ts +68 -0
- package/dist/tm/tools.d.ts.map +1 -0
- package/dist/tm/tools.js +706 -0
- package/dist/tm/tools.js.map +1 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/tm/store.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JIT layer-2 tools — run-payload store + trajectory.
|
|
3
|
+
*
|
|
4
|
+
* Blackboard layout (under TM_BLACKBOARD_DIR, default `<project>/.blackboard/`):
|
|
5
|
+
* runs/{run_id}/steps/{step_id}/{seq:03d}-{tool}.md full offloaded result
|
|
6
|
+
* runs/{run_id}/index.jsonl one append per result
|
|
7
|
+
* entry = { ts, run_id, step_id, seq, tool, ref, file, tokens,
|
|
8
|
+
* content_type, expire_at, preview }
|
|
9
|
+
*
|
|
10
|
+
* Trajectory layout (under TM_TRAJECTORY_DIR, default `<project>/.trajectory/`):
|
|
11
|
+
* runs/{run_id}/steps.jsonl append-only, one line per event — NO code
|
|
12
|
+
* path may rewrite, truncate or delete lines;
|
|
13
|
+
* the TTL sweep of whole expired run dirs is
|
|
14
|
+
* the sanctioned reclamation path.
|
|
15
|
+
* runs/{run_id}/usage.jsonl RESERVED for T2.2 (constant below, unused).
|
|
16
|
+
*
|
|
17
|
+
* Reclamation philosophy mirrors blackboard.ts: a startup sweep removes run
|
|
18
|
+
* dirs idle past the TTL — idleness measured across the whole run-dir tree
|
|
19
|
+
* (file appends must count as activity; only this sweep is destructive).
|
|
20
|
+
*/
|
|
21
|
+
import * as fs from "node:fs";
|
|
22
|
+
import * as path from "node:path";
|
|
23
|
+
import { buildRef } from "./refs.js";
|
|
24
|
+
/** Reserved for T2.2 usage accounting — path constant only in this phase. */
|
|
25
|
+
export const USAGE_JSONL_RELPATH = "usage.jsonl";
|
|
26
|
+
/** Offloaded result files follow `{seq:03d}-{tool}.md` inside a step dir. */
|
|
27
|
+
const STEP_FILE = /^\d{3}-[\w.-]+\.md$/;
|
|
28
|
+
export class RunStore {
|
|
29
|
+
blackboardRoot;
|
|
30
|
+
trajectoryRoot;
|
|
31
|
+
_runId;
|
|
32
|
+
_ttlMs;
|
|
33
|
+
constructor(opts) {
|
|
34
|
+
this._runId = opts.runId;
|
|
35
|
+
this._ttlMs = opts.ttlDays * 24 * 60 * 60 * 1000;
|
|
36
|
+
this.blackboardRoot = path.isAbsolute(opts.blackboardDir)
|
|
37
|
+
? opts.blackboardDir
|
|
38
|
+
: path.join(opts.projectRoot, opts.blackboardDir);
|
|
39
|
+
this.trajectoryRoot = path.isAbsolute(opts.trajectoryDir)
|
|
40
|
+
? opts.trajectoryDir
|
|
41
|
+
: path.join(opts.projectRoot, opts.trajectoryDir);
|
|
42
|
+
}
|
|
43
|
+
get runId() {
|
|
44
|
+
return this._runId;
|
|
45
|
+
}
|
|
46
|
+
runDir() {
|
|
47
|
+
return path.join(this.blackboardRoot, "runs", this._runId);
|
|
48
|
+
}
|
|
49
|
+
stepsRoot() {
|
|
50
|
+
return path.join(this.runDir(), "steps");
|
|
51
|
+
}
|
|
52
|
+
trajectoryFile() {
|
|
53
|
+
return path.join(this.trajectoryRoot, "runs", this._runId, "steps.jsonl");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Write one offloaded result: step file (single write, never rewritten) +
|
|
57
|
+
* index.jsonl append. Throws on store failures — the caller degrades
|
|
58
|
+
* (governance failures must not fail the task).
|
|
59
|
+
*/
|
|
60
|
+
writeResult(stepId, meta) {
|
|
61
|
+
const stepDir = path.join(this.stepsRoot(), stepId);
|
|
62
|
+
fs.mkdirSync(stepDir, { recursive: true });
|
|
63
|
+
const seq = fs.readdirSync(stepDir).filter((f) => STEP_FILE.test(f)).length + 1;
|
|
64
|
+
const safeTool = meta.tool.replace(/[^\w-]/g, "_");
|
|
65
|
+
const name = `${String(seq).padStart(3, "0")}-${safeTool}.md`;
|
|
66
|
+
const file = path.join(stepDir, name);
|
|
67
|
+
fs.writeFileSync(file, meta.content, "utf8");
|
|
68
|
+
const ref = buildRef(this._runId, stepId);
|
|
69
|
+
const entry = {
|
|
70
|
+
ts: new Date().toISOString(),
|
|
71
|
+
run_id: this._runId,
|
|
72
|
+
step_id: stepId,
|
|
73
|
+
seq,
|
|
74
|
+
tool: meta.tool,
|
|
75
|
+
ref,
|
|
76
|
+
file: `${stepId}/${name}`,
|
|
77
|
+
tokens: meta.tokens,
|
|
78
|
+
content_type: meta.contentType,
|
|
79
|
+
expire_at: meta.expireAt,
|
|
80
|
+
preview: meta.preview,
|
|
81
|
+
};
|
|
82
|
+
fs.appendFileSync(path.join(this.runDir(), "index.jsonl"), JSON.stringify(entry) + "\n", "utf8");
|
|
83
|
+
return { stepId, seq, file, ref, expireAt: meta.expireAt };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Append one trajectory event. Append-only by contract; best-effort
|
|
87
|
+
* (trajectory failures are swallowed — the blackboard failure path is the
|
|
88
|
+
* one that degrades upstream).
|
|
89
|
+
*/
|
|
90
|
+
appendTrajectory(event) {
|
|
91
|
+
try {
|
|
92
|
+
const file = this.trajectoryFile();
|
|
93
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
94
|
+
const line = JSON.stringify({ ts: new Date().toISOString(), run_id: this._runId, ...event }) + "\n";
|
|
95
|
+
fs.appendFileSync(file, line, "utf8");
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
/* trajectory is best-effort */
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Latest index entry for a ref (last append wins), or null. */
|
|
102
|
+
findIndexEntry(ref) {
|
|
103
|
+
try {
|
|
104
|
+
const text = fs.readFileSync(path.join(this.runDir(), "index.jsonl"), "utf8");
|
|
105
|
+
let found = null;
|
|
106
|
+
for (const line of text.split(/\r?\n/)) {
|
|
107
|
+
if (!line.trim())
|
|
108
|
+
continue;
|
|
109
|
+
try {
|
|
110
|
+
const entry = JSON.parse(line);
|
|
111
|
+
if (entry && entry.ref === ref)
|
|
112
|
+
found = entry;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
/* skip torn/bad line — append-only logs can have them on crash */
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return found;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Read the offloaded payload file of a step; null when gone/unreadable.
|
|
125
|
+
* With multiple seq files in one step (defensive re-entry), the LATEST
|
|
126
|
+
* seq wins — consistent with findIndexEntry's last-append-wins. */
|
|
127
|
+
readStepFile(stepId) {
|
|
128
|
+
try {
|
|
129
|
+
const dir = path.join(this.stepsRoot(), stepId);
|
|
130
|
+
const files = fs.readdirSync(dir).filter((f) => STEP_FILE.test(f)).sort();
|
|
131
|
+
if (files.length === 0)
|
|
132
|
+
return null;
|
|
133
|
+
return { content: fs.readFileSync(path.join(dir, files[files.length - 1]), "utf8") };
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Startup-only reclamation: remove run dirs (both stores) whose last tree
|
|
141
|
+
* activity is older than the TTL. This is the ONLY destructive path in
|
|
142
|
+
* this module. Returns the number of run dirs removed. Never throws.
|
|
143
|
+
*/
|
|
144
|
+
sweepExpired(now = Date.now()) {
|
|
145
|
+
let removed = 0;
|
|
146
|
+
for (const root of [this.blackboardRoot, this.trajectoryRoot]) {
|
|
147
|
+
const runsDir = path.join(root, "runs");
|
|
148
|
+
let entries;
|
|
149
|
+
try {
|
|
150
|
+
entries = fs.readdirSync(runsDir);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
continue; // store not created yet — nothing to sweep
|
|
154
|
+
}
|
|
155
|
+
for (const entry of entries) {
|
|
156
|
+
const dir = path.join(runsDir, entry);
|
|
157
|
+
try {
|
|
158
|
+
if (!fs.statSync(dir).isDirectory())
|
|
159
|
+
continue;
|
|
160
|
+
// Activity = max mtime across the run-dir TREE (M2, mirrors
|
|
161
|
+
// blackboard.ts): appending to steps.jsonl / step files does NOT
|
|
162
|
+
// refresh the parent dir's mtime, so a dir-mtime check deleted
|
|
163
|
+
// live runs (review probe E1). lastActivityMs returning 0 (stat
|
|
164
|
+
// failure) keeps the dir — fail-closed.
|
|
165
|
+
const last = lastActivityMs(dir);
|
|
166
|
+
if (last !== 0 && now - last > this._ttlMs) {
|
|
167
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
168
|
+
removed++;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
/* raced entry — skip */
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return removed;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Latest mtime within `dir`, recursing the whole tree (M2 — mirrors
|
|
181
|
+
* blackboard.ts's lastActivity, which is regression-pinned there). A
|
|
182
|
+
* directory's own mtime only changes when direct children are created/
|
|
183
|
+
* removed/renamed — NOT when a file inside is appended or rewritten in
|
|
184
|
+
* place — so the sweep must look at file activity.
|
|
185
|
+
*
|
|
186
|
+
* The depth difference vs blackboard.ts's lastActivity (capped `levels`
|
|
187
|
+
* recursion) is DELIBERATE: blackboard trees can be user-managed and
|
|
188
|
+
* arbitrarily deep, so they cap defensively; the run-dir tree here is
|
|
189
|
+
* plugin-owned and bounded by what the plugin itself wrote. Even a
|
|
190
|
+
* pathological cycle terminates naturally — fs.statSync on a symlink loop
|
|
191
|
+
* fails with ELOOP and is swallowed by the catch below.
|
|
192
|
+
*/
|
|
193
|
+
function lastActivityMs(dir) {
|
|
194
|
+
let latest;
|
|
195
|
+
try {
|
|
196
|
+
latest = fs.statSync(dir).mtimeMs;
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return 0;
|
|
200
|
+
}
|
|
201
|
+
let entries;
|
|
202
|
+
try {
|
|
203
|
+
entries = fs.readdirSync(dir);
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return latest; // unreadable dir: its own mtime is all we know
|
|
207
|
+
}
|
|
208
|
+
for (const entry of entries) {
|
|
209
|
+
const child = path.join(dir, entry);
|
|
210
|
+
try {
|
|
211
|
+
const st = fs.statSync(child);
|
|
212
|
+
const seen = st.isDirectory() ? lastActivityMs(child) : st.mtimeMs;
|
|
213
|
+
if (seen > latest)
|
|
214
|
+
latest = seen;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
/* raced deletion — ignore */
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return latest;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/tm/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JIT layer-2 tools — the four governed pipelines (T1.2 + T1.3 + T1.4).
|
|
3
|
+
*
|
|
4
|
+
* tm_read — governed passthrough of client.file.read (T0.4-verified API)
|
|
5
|
+
* tm_grep — governed passthrough of client.find.text (T0.4-verified API)
|
|
6
|
+
* tm_bash — read-only allowlisted shell via the host `$` bridge
|
|
7
|
+
* tm_fetch — paged/structured retrieval of offloaded payloads (handles)
|
|
8
|
+
*
|
|
9
|
+
* Shared governance (every tool):
|
|
10
|
+
* - ToolResult contract (official tool.d.ts:39-46): execute() returns
|
|
11
|
+
* {output: string} — ALWAYS. Handles, structured errors, pages and
|
|
12
|
+
* degraded warnings are formatted INTO the output text; a bare object
|
|
13
|
+
* return crashes the host result pipeline (`c.split`) and the model
|
|
14
|
+
* would never see the handle it needs to drive tm_fetch.
|
|
15
|
+
* - R6 reuse: env-file paths / env commands are refused through the SAME
|
|
16
|
+
* envprotect matchers the global hook uses (anti-backdoor requirement);
|
|
17
|
+
* the hook layer additionally aliases tm_* onto read/grep/bash so even a
|
|
18
|
+
* future tool-code regression cannot bypass R6.
|
|
19
|
+
* - Threshold offload: estimateTokens(content) >= TM_OFFLOAD_THRESHOLD
|
|
20
|
+
* (default 2000; == threshold also offloads) -> full payload to the run
|
|
21
|
+
* store + trajectory, handle {offloaded, ref, access_token, expire_at,
|
|
22
|
+
* tokens, preview} back. Below -> content inline.
|
|
23
|
+
* - Structured errors (T1.4): pipelines still produce
|
|
24
|
+
* {error: {tool, phase, message, line?}} internally — never a bare
|
|
25
|
+
* throw — and execute() renders them readably into output; shell errors
|
|
26
|
+
* carry a line when one can be extracted and stdout noise is stripped.
|
|
27
|
+
* - Degradation: an offload (store) failure returns truncated content plus
|
|
28
|
+
* a warning — a governance fault must never fail the task.
|
|
29
|
+
*/
|
|
30
|
+
import type * as crypto from "node:crypto";
|
|
31
|
+
import { type EnvProtectMode } from "../envprotect.js";
|
|
32
|
+
import type { ToolDefinition } from "../types.js";
|
|
33
|
+
import { type TmConfig } from "./config.js";
|
|
34
|
+
import type { RunStore } from "./store.js";
|
|
35
|
+
export type TmPhase = "args" | "permission" | "client" | "execute" | "store" | "governance";
|
|
36
|
+
export interface TmErrorBody {
|
|
37
|
+
error: {
|
|
38
|
+
tool: string;
|
|
39
|
+
phase: TmPhase;
|
|
40
|
+
message: string;
|
|
41
|
+
line?: number;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export declare function tmError(tool: string, phase: TmPhase, message: string, line?: number): TmErrorBody;
|
|
45
|
+
/** Fixed invalid-handle message (spec-pinned wording for tm_fetch). */
|
|
46
|
+
export declare const HANDLE_INVALID_MESSAGE = "\u8F7D\u8377\u5DF2\u6E05\u7406\u6216 run \u4E0D\u5339\u914D\uFF0C\u5EFA\u8BAE\u91CD\u8DD1\u539F\u5DE5\u5177\u3002";
|
|
47
|
+
export interface TmDeps {
|
|
48
|
+
client: unknown;
|
|
49
|
+
$: unknown;
|
|
50
|
+
cfg: TmConfig;
|
|
51
|
+
store: RunStore;
|
|
52
|
+
runId: string;
|
|
53
|
+
/** Process-random HMAC key — used to VERIFY handle tokens in tm_fetch. */
|
|
54
|
+
hmacKey: crypto.BinaryLike;
|
|
55
|
+
accessToken: string;
|
|
56
|
+
expireAt: number;
|
|
57
|
+
mode: EnvProtectMode;
|
|
58
|
+
extra: RegExp[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build the four tool definitions. Async only because of the optional zod
|
|
62
|
+
* load; every pipeline itself is runtime-defensive against raw args. Every
|
|
63
|
+
* execute() funnels through toToolResult so the return value ALWAYS satisfies
|
|
64
|
+
* the host ToolResult contract ({output: string}) — handles, structured
|
|
65
|
+
* errors, pages and degraded warnings included.
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildTmTools(deps: TmDeps): Promise<Record<string, ToolDefinition>>;
|
|
68
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/tm/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,KAAK,MAAM,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAgE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACpH,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,aAAa,CAAA;AAC7D,OAAO,EAA0C,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAW1C,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,YAAY,CAAA;AAE3F,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACxE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAIjG;AAED,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,sHAA4B,CAAA;AAgQ/D,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,OAAO,CAAA;IACf,CAAC,EAAE,OAAO,CAAA;IACV,GAAG,EAAE,QAAQ,CAAA;IACb,KAAK,EAAE,QAAQ,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC,UAAU,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAqaD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAyBxF"}
|