iterate-plugin 3.5.7 → 3.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 +97 -22
- package/README.zh-CN.md +79 -19
- package/dist/approval-gate.js +143 -23
- package/dist/atomic-fs.js +148 -17
- package/dist/config-loader.js +516 -35
- package/dist/config-write.js +83 -22
- package/dist/evidence.js +141 -87
- package/dist/file-lock.js +193 -0
- package/dist/index.js +61 -28
- package/dist/jobs.js +56 -11
- package/dist/live.js +54 -14
- package/dist/meta-review.js +132 -28
- package/dist/method-scope.js +31 -8
- package/dist/review-scope.js +32 -9
- package/dist/review.js +96 -17
- package/dist/session-hooks.js +61 -14
- package/dist/skill-prompt.js +396 -66
- package/dist/tools/checkpoint.js +85 -19
- package/dist/tools/config.js +44 -2
- package/dist/tools/context.js +22 -5
- package/dist/tools/decision-log.js +106 -28
- package/dist/tools/defense-events.js +90 -31
- package/dist/tools/defense-store.js +28 -3
- package/dist/tools/experience-bank.js +108 -43
- package/dist/tools/experience-store.js +54 -4
- package/dist/tools/fix.js +347 -119
- package/dist/tools/history.js +68 -14
- package/dist/tools/present.js +80 -0
- package/dist/tools/prune.js +150 -53
- package/dist/tools/quality-gate.js +52 -2
- package/dist/tools/quality-store.js +17 -1
- package/dist/tools/review.js +158 -7
- package/dist/tools/transcript.js +173 -36
- package/dist/tools/triage.js +67 -12
- package/dist/tools/validate.js +115 -24
- package/dist/transcript.js +267 -4
- package/dist/working-directory.js +114 -0
- package/lib/client.js +1912 -512
- package/lib/parse.js +1001 -103
- package/package.json +16 -9
- package/src/approval-gate.ts +160 -23
- package/src/atomic-fs.ts +152 -17
- package/src/client/i18n.ts +517 -0
- package/src/client/index.ts +1031 -369
- package/src/client/session-cache.ts +54 -0
- package/src/config-loader.ts +549 -36
- package/src/config-write.ts +108 -26
- package/src/evidence.ts +194 -92
- package/src/file-lock.ts +211 -0
- package/src/index.ts +60 -29
- package/src/jobs.ts +63 -12
- package/src/live.ts +50 -12
- package/src/meta-review.ts +151 -34
- package/src/method-scope.ts +31 -8
- package/src/review-scope.ts +33 -10
- package/src/review.ts +96 -17
- package/src/session-hooks.ts +60 -13
- package/src/skill-prompt.ts +396 -66
- package/src/tools/checkpoint.ts +81 -19
- package/src/tools/config.ts +44 -2
- package/src/tools/context.ts +25 -5
- package/src/tools/decision-log.ts +114 -23
- package/src/tools/defense-events.ts +87 -31
- package/src/tools/defense-store.ts +30 -3
- package/src/tools/experience-bank.ts +112 -44
- package/src/tools/experience-store.ts +54 -5
- package/src/tools/fix.ts +258 -20
- package/src/tools/history.ts +74 -15
- package/src/tools/present.ts +89 -0
- package/src/tools/prune.ts +154 -51
- package/src/tools/quality-gate.ts +57 -2
- package/src/tools/quality-store.ts +18 -1
- package/src/tools/review.ts +155 -6
- package/src/tools/transcript.ts +178 -36
- package/src/tools/triage.ts +70 -13
- package/src/tools/validate.ts +138 -32
- package/src/transcript.ts +279 -4
- package/src/types.ts +29 -1
- package/src/working-directory.ts +126 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/working-directory.ts — follow dsh's mutable session working directory.
|
|
3
|
+
*
|
|
4
|
+
* Upstream history:
|
|
5
|
+
* - through dsh 0.2.1-alpha.1 the session's working directory WAS the
|
|
6
|
+
* immutable `Session.header.cwd`, so reading `exec.agent.session.header.cwd`
|
|
7
|
+
* was authoritative;
|
|
8
|
+
* - dsh 0.2.1-alpha.2 added the `working_directory` tool and the
|
|
9
|
+
* `WorkingDirectoryService` (`@deepseek-ai/dsh-working-directory`), whose
|
|
10
|
+
* contract explicitly states "the immutable Session header retains the
|
|
11
|
+
* ORIGINAL project" while `working-directory/change` events record the
|
|
12
|
+
* current one. After a model/user switches directories mid-session,
|
|
13
|
+
* `header.cwd` is therefore stale BY DESIGN.
|
|
14
|
+
*
|
|
15
|
+
* The iterate plugin resolves the project root (where `.iterate/` lives, where
|
|
16
|
+
* fixes are written, and — critically — which workspace the F8 approval policy
|
|
17
|
+
* is read from) from the session cwd. Sticking to `header.cwd` on a host that
|
|
18
|
+
* supports directory switches would silently operate on the wrong project:
|
|
19
|
+
* reviews would anchor to the original checkout while the model edits files
|
|
20
|
+
* elsewhere, and a `deny` policy in the active workspace would be read from
|
|
21
|
+
* the original one.
|
|
22
|
+
*
|
|
23
|
+
* So the effective directory is resolved through the host's service when it
|
|
24
|
+
* exists, and degrades to `header.cwd` otherwise:
|
|
25
|
+
* - feature-detected (`ctx.get('workingDirectory')`) — hosts older than
|
|
26
|
+
* 0.2.1-alpha.2 simply have no such service and keep the old behavior;
|
|
27
|
+
* - `service.get(session)` is the service's synchronous, I/O-free read of
|
|
28
|
+
* the committed directory, so this stays safe on the approval path;
|
|
29
|
+
* - every failure mode (no service, service throws, hostile getters, a
|
|
30
|
+
* non-string result) falls back to `header.cwd`, never to `undefined`
|
|
31
|
+
* where a header cwd exists.
|
|
32
|
+
*
|
|
33
|
+
* The service object is fetched lazily on every call, not once at plugin
|
|
34
|
+
* apply: dsh may register the service after this plugin loads, and a disposed
|
|
35
|
+
* context must degrade rather than cache a dead handle.
|
|
36
|
+
*/
|
|
37
|
+
/** The plugin context, installed once by `apply()`; null on hosts without it. */
|
|
38
|
+
let installedContext = null;
|
|
39
|
+
/** True when `value` looks like a cordis context carrying `ctx.get`. */
|
|
40
|
+
function isContextLike(value) {
|
|
41
|
+
return (typeof value === 'object' &&
|
|
42
|
+
value !== null &&
|
|
43
|
+
typeof value.get === 'function');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Install the plugin context used to look up the `workingDirectory` service.
|
|
47
|
+
* Passing anything without a callable `get` clears the installation (tests and
|
|
48
|
+
* hosts that load the plugin into a degraded context).
|
|
49
|
+
*/
|
|
50
|
+
export function installWorkingDirectoryContext(ctx) {
|
|
51
|
+
installedContext = isContextLike(ctx) ? ctx : null;
|
|
52
|
+
}
|
|
53
|
+
/** Forget the installed context (test isolation / unload). */
|
|
54
|
+
export function resetWorkingDirectoryContext() {
|
|
55
|
+
installedContext = null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Read the host's committed working directory for `session`, if the host
|
|
59
|
+
* provides the service and it answers with a usable absolute path.
|
|
60
|
+
*
|
|
61
|
+
* Returns `undefined` for every degradation path so callers keep their
|
|
62
|
+
* previous `header.cwd` behavior.
|
|
63
|
+
*/
|
|
64
|
+
function serviceWorkingDirectory(session) {
|
|
65
|
+
if (session === undefined || session === null)
|
|
66
|
+
return undefined;
|
|
67
|
+
const ctx = installedContext;
|
|
68
|
+
if (!ctx)
|
|
69
|
+
return undefined;
|
|
70
|
+
try {
|
|
71
|
+
const service = ctx.get?.('workingDirectory');
|
|
72
|
+
if (!service || typeof service.get !== 'function')
|
|
73
|
+
return undefined;
|
|
74
|
+
const dir = service.get(session);
|
|
75
|
+
// A relative or empty directory would move the project root somewhere
|
|
76
|
+
// unspecified — refuse it and keep the header value instead.
|
|
77
|
+
if (typeof dir !== 'string' || dir.length === 0)
|
|
78
|
+
return undefined;
|
|
79
|
+
return dir;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Missing/disposed service, unpublished session, or a throwing getter —
|
|
83
|
+
// degrade to the historical source rather than failing the tool call.
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The effective working directory of a session: the host's committed
|
|
89
|
+
* directory when available, else the immutable session header cwd.
|
|
90
|
+
*
|
|
91
|
+
* Returns `undefined` only when neither source yields a usable path.
|
|
92
|
+
*/
|
|
93
|
+
export function effectiveSessionCwd(session, headerCwd) {
|
|
94
|
+
const fromService = serviceWorkingDirectory(session);
|
|
95
|
+
if (fromService !== undefined)
|
|
96
|
+
return fromService;
|
|
97
|
+
return typeof headerCwd === 'string' && headerCwd.length > 0 ? headerCwd : undefined;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Extract the effective cwd from a tool execution (`exec.agent.session`),
|
|
101
|
+
* reading every property defensively: a hostile/proxied exec must degrade to
|
|
102
|
+
* the fallback path, never throw out of an approval or capture hook.
|
|
103
|
+
*/
|
|
104
|
+
export function sessionCwdOf(exec) {
|
|
105
|
+
try {
|
|
106
|
+
const agent = exec?.agent;
|
|
107
|
+
const session = agent?.session;
|
|
108
|
+
const headerCwd = typeof agent?.session?.header?.cwd === 'string' ? agent.session.header.cwd : undefined;
|
|
109
|
+
return effectiveSessionCwd(session, headerCwd);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|