iterate-plugin 2.9.2 → 2.9.3
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/dist/config-loader.js +27 -6
- package/dist/tools/checkpoint.js +5 -5
- package/dist/tools/config.js +3 -3
- package/dist/tools/context.js +3 -3
- package/dist/tools/decision-log.js +3 -3
- package/dist/tools/fix.js +7 -7
- package/dist/tools/history.js +3 -3
- package/dist/tools/prune.js +3 -3
- package/dist/tools/review.js +3 -3
- package/dist/tools/triage.js +3 -3
- package/dist/tools/validate.js +3 -3
- package/package.json +1 -1
- package/src/config-loader.ts +30 -6
- package/src/tools/checkpoint.ts +5 -5
- package/src/tools/config.ts +3 -3
- package/src/tools/context.ts +3 -3
- package/src/tools/decision-log.ts +3 -3
- package/src/tools/fix.ts +7 -7
- package/src/tools/history.ts +3 -3
- package/src/tools/prune.ts +3 -3
- package/src/tools/review.ts +3 -3
- package/src/tools/triage.ts +3 -3
- package/src/tools/validate.ts +3 -3
package/dist/config-loader.js
CHANGED
|
@@ -167,25 +167,46 @@ export function validateConfig(config) {
|
|
|
167
167
|
* path is unsafe; callers must short-circuit on the failure and return a
|
|
168
168
|
* structured error instead of proceeding.
|
|
169
169
|
*/
|
|
170
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Resolve a caller-supplied project root to a safe absolute path.
|
|
172
|
+
*
|
|
173
|
+
* Resolution order for the default (no explicit `path`) case:
|
|
174
|
+
* 1. `sessionCwd` — the absolute working directory the calling DSH session
|
|
175
|
+
* was created in (`exec.agent.session.header.cwd`). This is the
|
|
176
|
+
* authoritative workspace for the current conversation and is immune to
|
|
177
|
+
* where the web-service process happened to start.
|
|
178
|
+
* 2. the process cwd, when it is a usable directory (not `/` or the home
|
|
179
|
+
* dir — launchd/daemon-managed servers start with cwd=`/`);
|
|
180
|
+
* 3. the session workspace decoded from `DSH_SESSION_JSONL` (present when
|
|
181
|
+
* the DSH runtime injects per-session env into tool sub-processes).
|
|
182
|
+
*/
|
|
183
|
+
export function resolveProjectRoot(input, sessionCwd) {
|
|
171
184
|
const raw = (input ?? '').trim();
|
|
172
|
-
const root = raw ? resolve(raw) : resolve(effectiveCwd());
|
|
185
|
+
const root = raw ? resolve(raw) : resolve(effectiveCwd(sessionCwd));
|
|
173
186
|
if (!root || root === sep) {
|
|
174
187
|
return { ok: false, reason: 'Refusing filesystem root as project root.' };
|
|
175
188
|
}
|
|
176
189
|
return { ok: true, root };
|
|
177
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Thin adapter for tool `execute(args, exec)` bodies: pull the session cwd
|
|
193
|
+
* from the DSH run context and hand it to {@link resolveProjectRoot}.
|
|
194
|
+
*/
|
|
195
|
+
export function resolveProjectRootForExec(exec, input) {
|
|
196
|
+
return resolveProjectRoot(input, exec?.agent?.session?.header?.cwd);
|
|
197
|
+
}
|
|
178
198
|
/**
|
|
179
199
|
* Resolve the default working directory for tools invoked without an explicit
|
|
180
|
-
* `path`. Prefers the
|
|
181
|
-
*
|
|
182
|
-
* case fall back to the session workspace encoded in `DSH_SESSION_JSONL`
|
|
200
|
+
* `path`. Prefers the caller-provided session cwd, then the process cwd, then
|
|
201
|
+
* the session workspace encoded in `DSH_SESSION_JSONL`
|
|
183
202
|
* (`…/sessions/<encoded-workspace>/<session-id>/session.jsonl.zstd`), where
|
|
184
203
|
* the workspace directory is `--`-wrapped with `/` → `-` and percent-encoded
|
|
185
204
|
* bytes spelled as `~<hex>` (e.g. `/Volumes/Eng-Dev/iterate-skill` →
|
|
186
205
|
* `--Volumes-Eng-Dev-iterate-skill--`).
|
|
187
206
|
*/
|
|
188
|
-
function effectiveCwd() {
|
|
207
|
+
function effectiveCwd(sessionCwd) {
|
|
208
|
+
if (sessionCwd && sessionCwd !== sep && sessionCwd !== homedir())
|
|
209
|
+
return sessionCwd;
|
|
189
210
|
let cwd = '';
|
|
190
211
|
try {
|
|
191
212
|
cwd = process.cwd();
|
package/dist/tools/checkpoint.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
12
12
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
13
|
-
import {
|
|
13
|
+
import { resolveProjectRootForExec } from "../config-loader.js";
|
|
14
14
|
import { checkpointPath, iterateDir } from "../paths.js";
|
|
15
15
|
import { readRegistry } from "./fix.js";
|
|
16
16
|
import { readDecisionEntries } from "./decision-log.js";
|
|
@@ -142,8 +142,8 @@ export function registerCheckpointTool(ctx) {
|
|
|
142
142
|
{ type: 'text', text: JSON.stringify(value, null, 2) },
|
|
143
143
|
],
|
|
144
144
|
},
|
|
145
|
-
async execute(args) {
|
|
146
|
-
const resolved =
|
|
145
|
+
async execute(args, exec) {
|
|
146
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
147
147
|
if (!resolved.ok)
|
|
148
148
|
return { operation: args.operation, ok: false, error: resolved.reason };
|
|
149
149
|
const projectRoot = resolved.root;
|
|
@@ -246,8 +246,8 @@ export function registerStatusTool(ctx) {
|
|
|
246
246
|
return [{ type: 'text', text: lines.filter(Boolean).join('\n') }];
|
|
247
247
|
},
|
|
248
248
|
},
|
|
249
|
-
async execute(args) {
|
|
250
|
-
const resolved =
|
|
249
|
+
async execute(args, exec) {
|
|
250
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
251
251
|
if (!resolved.ok)
|
|
252
252
|
return { ok: false, error: resolved.reason };
|
|
253
253
|
const projectRoot = resolved.root;
|
package/dist/tools/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
3
|
-
import { loadEffectiveConfig, validateConfig,
|
|
3
|
+
import { loadEffectiveConfig, validateConfig, resolveProjectRootForExec } from "../config-loader.js";
|
|
4
4
|
import { applyConfigUpdates, readRawConfig, validateConfigUpdates, writeConfigFile, } from "../config-write.js";
|
|
5
5
|
/**
|
|
6
6
|
* Register the `iterate_config` tool.
|
|
@@ -62,8 +62,8 @@ export function registerConfigTool(ctx) {
|
|
|
62
62
|
{ type: 'text', text: JSON.stringify(value, null, 2) },
|
|
63
63
|
],
|
|
64
64
|
},
|
|
65
|
-
async execute(args) {
|
|
66
|
-
const resolved =
|
|
65
|
+
async execute(args, exec) {
|
|
66
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
67
67
|
if (!resolved.ok) {
|
|
68
68
|
return { found: false, error: resolved.reason };
|
|
69
69
|
}
|
package/dist/tools/context.js
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync, existsSync } from 'node:fs';
|
|
|
2
2
|
import { join, dirname, resolve } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
5
|
-
import {
|
|
5
|
+
import { resolveProjectRootForExec } from "../config-loader.js";
|
|
6
6
|
/** How many ancestor directories we walk up looking for a SKILL.md. */
|
|
7
7
|
const MAX_SKILL_DIR_LOOKUP_DEPTH = 12;
|
|
8
8
|
/** Maximum number of image attachments relayed into the context in one call. */
|
|
@@ -235,8 +235,8 @@ export function registerContextTool(ctx) {
|
|
|
235
235
|
return [{ type: 'text', text: parts.join('\n\n') }];
|
|
236
236
|
},
|
|
237
237
|
},
|
|
238
|
-
async execute(args) {
|
|
239
|
-
const resolved =
|
|
238
|
+
async execute(args, exec) {
|
|
239
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
240
240
|
if (!resolved.ok) {
|
|
241
241
|
return { found: false, error: resolved.reason, searched: [] };
|
|
242
242
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { appendFileSync, readFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
4
|
-
import {
|
|
4
|
+
import { resolveProjectRootForExec } from "../config-loader.js";
|
|
5
5
|
const LOG_DIR = '.iterate';
|
|
6
6
|
const LOG_FILE = 'decision-log.jsonl';
|
|
7
7
|
/** All valid DecisionLogEntry `type` values (must stay in sync with Types). */
|
|
@@ -147,8 +147,8 @@ export function registerDecisionLogTool(ctx) {
|
|
|
147
147
|
{ type: 'text', text: JSON.stringify(value, null, 2) },
|
|
148
148
|
],
|
|
149
149
|
},
|
|
150
|
-
async execute(args) {
|
|
151
|
-
const resolved =
|
|
150
|
+
async execute(args, exec) {
|
|
151
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
152
152
|
if (!resolved.ok) {
|
|
153
153
|
return { operation: args.operation, error: resolved.reason };
|
|
154
154
|
}
|
package/dist/tools/fix.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
22
|
-
import { loadEffectiveConfig,
|
|
22
|
+
import { loadEffectiveConfig, resolveProjectRootForExec } from "../config-loader.js";
|
|
23
23
|
import { countTouchedMethods } from "../method-scope.js";
|
|
24
24
|
import { fixBackupPath, fixRegistryPath, fixesDir } from "../paths.js";
|
|
25
25
|
import { appendDecisionEntry } from "./decision-log.js";
|
|
@@ -272,8 +272,8 @@ export function registerFixTool(ctx) {
|
|
|
272
272
|
{ type: 'text', text: value.ok ? `${value.diffSummary ?? 'fixed'} @ ${value.file} (id: ${value.id})` : `fix failed: ${value.error}` },
|
|
273
273
|
],
|
|
274
274
|
},
|
|
275
|
-
async execute(args) {
|
|
276
|
-
const resolved =
|
|
275
|
+
async execute(args, exec) {
|
|
276
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
277
277
|
if (!resolved.ok)
|
|
278
278
|
return { ok: false, error: resolved.reason };
|
|
279
279
|
const projectRoot = resolved.root;
|
|
@@ -433,8 +433,8 @@ export function registerDiffTool(ctx) {
|
|
|
433
433
|
return [{ type: 'text', text }];
|
|
434
434
|
},
|
|
435
435
|
},
|
|
436
|
-
async execute(args) {
|
|
437
|
-
const resolved =
|
|
436
|
+
async execute(args, exec) {
|
|
437
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
438
438
|
if (!resolved.ok)
|
|
439
439
|
return { ok: false, error: resolved.reason };
|
|
440
440
|
const projectRoot = resolved.root;
|
|
@@ -520,8 +520,8 @@ export function registerRollbackTool(ctx) {
|
|
|
520
520
|
{ type: 'text', text: value.ok ? `reverted fix ${value.id} in ${value.file}` : `rollback failed: ${value.error}` },
|
|
521
521
|
],
|
|
522
522
|
},
|
|
523
|
-
async execute(args) {
|
|
524
|
-
const resolved =
|
|
523
|
+
async execute(args, exec) {
|
|
524
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
525
525
|
if (!resolved.ok)
|
|
526
526
|
return { ok: false, error: resolved.reason };
|
|
527
527
|
const projectRoot = resolved.root;
|
package/dist/tools/history.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Complements `iterate_status` (compact summary) with the actual detail.
|
|
9
9
|
*/
|
|
10
10
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
11
|
-
import {
|
|
11
|
+
import { resolveProjectRootForExec } from "../config-loader.js";
|
|
12
12
|
import { readDecisionEntries } from "./decision-log.js";
|
|
13
13
|
import { readRegistry } from "./fix.js";
|
|
14
14
|
const DEFAULT_LIMIT = 50;
|
|
@@ -117,8 +117,8 @@ export function registerHistoryTool(ctx) {
|
|
|
117
117
|
return [{ type: 'text', text: lines.join('\n') }];
|
|
118
118
|
},
|
|
119
119
|
},
|
|
120
|
-
async execute(args) {
|
|
121
|
-
const resolved =
|
|
120
|
+
async execute(args, exec) {
|
|
121
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
122
122
|
if (!resolved.ok)
|
|
123
123
|
return { ok: false, kind: 'history', error: resolved.reason };
|
|
124
124
|
const projectRoot = resolved.root;
|
package/dist/tools/prune.js
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import { existsSync, readdirSync, rmSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
21
21
|
import { join } from 'node:path';
|
|
22
22
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
23
|
-
import {
|
|
23
|
+
import { resolveProjectRootForExec } from "../config-loader.js";
|
|
24
24
|
import { readDecisionEntries, appendDecisionEntry } from "./decision-log.js";
|
|
25
25
|
import { readRegistry, removeRecord, recomputeRoundCounts } from "./fix.js";
|
|
26
26
|
import { iterateDir, fixesDir, checkpointPath, fixRegistryPath } from "../paths.js";
|
|
@@ -225,8 +225,8 @@ export function registerPruneTool(ctx) {
|
|
|
225
225
|
return [{ type: 'text', text: lines.join('\n') }];
|
|
226
226
|
},
|
|
227
227
|
},
|
|
228
|
-
async execute(args) {
|
|
229
|
-
const resolved =
|
|
228
|
+
async execute(args, exec) {
|
|
229
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
230
230
|
if (!resolved.ok)
|
|
231
231
|
return { ok: false, dryRun: true, error: resolved.reason };
|
|
232
232
|
const projectRoot = resolved.root;
|
package/dist/tools/review.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
2
|
-
import { loadEffectiveConfig,
|
|
2
|
+
import { loadEffectiveConfig, resolveProjectRootForExec } from "../config-loader.js";
|
|
3
3
|
import { buildReviewPlan, buildReviewReport, sanitizeRounds, validateRoundsSchema, } from "../review.js";
|
|
4
4
|
import { buildFinalReviewReport, metaReviewReport } from "../meta-review.js";
|
|
5
5
|
import { evidenceToPlain, verifyFindings } from "../evidence.js";
|
|
@@ -106,8 +106,8 @@ export function registerReviewTool(ctx) {
|
|
|
106
106
|
{ type: 'text', text: JSON.stringify(value, null, 2) },
|
|
107
107
|
],
|
|
108
108
|
},
|
|
109
|
-
async execute(args) {
|
|
110
|
-
const resolved =
|
|
109
|
+
async execute(args, exec) {
|
|
110
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
111
111
|
if (!resolved.ok) {
|
|
112
112
|
return { operation: args.operation, error: resolved.reason };
|
|
113
113
|
}
|
package/dist/tools/triage.js
CHANGED
|
@@ -2,7 +2,7 @@ import { copyFileSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
4
4
|
import yaml from 'js-yaml';
|
|
5
|
-
import {
|
|
5
|
+
import { resolveProjectRootForExec } from "../config-loader.js";
|
|
6
6
|
const CONFIG_FILE = 'iterate.config.yaml';
|
|
7
7
|
/** Personalization key that holds the known-intentional list. */
|
|
8
8
|
const PERSONALIZATION_KEY = 'personalization';
|
|
@@ -272,8 +272,8 @@ export function registerTriageTool(ctx) {
|
|
|
272
272
|
{ type: 'text', text: JSON.stringify(value, null, 2) },
|
|
273
273
|
],
|
|
274
274
|
},
|
|
275
|
-
async execute(args) {
|
|
276
|
-
const resolved =
|
|
275
|
+
async execute(args, exec) {
|
|
276
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
277
277
|
if (!resolved.ok) {
|
|
278
278
|
return { operation: args.operation, error: resolved.reason };
|
|
279
279
|
}
|
package/dist/tools/validate.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { exec } from 'node:child_process';
|
|
2
2
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
3
|
-
import { loadEffectiveConfig, isCommandAllowed, flattenCommands,
|
|
3
|
+
import { loadEffectiveConfig, isCommandAllowed, flattenCommands, resolveProjectRootForExec, } from "../config-loader.js";
|
|
4
4
|
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
5
5
|
/** Hard ceiling on a single validation command's runtime, so a model cannot
|
|
6
6
|
* pin the tool open indefinitely via an unbounded `timeout` argument. */
|
|
@@ -103,8 +103,8 @@ export function registerValidateTool(ctx) {
|
|
|
103
103
|
},
|
|
104
104
|
],
|
|
105
105
|
},
|
|
106
|
-
async execute(args) {
|
|
107
|
-
const resolved =
|
|
106
|
+
async execute(args, exec) {
|
|
107
|
+
const resolved = resolveProjectRootForExec(exec, args.path);
|
|
108
108
|
if (!resolved.ok) {
|
|
109
109
|
return {
|
|
110
110
|
allowed: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iterate-plugin",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.3",
|
|
4
4
|
"description": "dsh plugin that turns the iterate skill into an autonomous closed-loop harness: plan -> parallel review xN -> atomic fixes -> validate -> loop -> auto-stop, plus a dry-run pure-review mode with multi-round convergence and a meta-review that audits the report and emits a final review report.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/config-loader.ts
CHANGED
|
@@ -184,26 +184,50 @@ export type ProjectRootResult = { ok: true; root: string } | { ok: false; reason
|
|
|
184
184
|
* path is unsafe; callers must short-circuit on the failure and return a
|
|
185
185
|
* structured error instead of proceeding.
|
|
186
186
|
*/
|
|
187
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Resolve a caller-supplied project root to a safe absolute path.
|
|
189
|
+
*
|
|
190
|
+
* Resolution order for the default (no explicit `path`) case:
|
|
191
|
+
* 1. `sessionCwd` — the absolute working directory the calling DSH session
|
|
192
|
+
* was created in (`exec.agent.session.header.cwd`). This is the
|
|
193
|
+
* authoritative workspace for the current conversation and is immune to
|
|
194
|
+
* where the web-service process happened to start.
|
|
195
|
+
* 2. the process cwd, when it is a usable directory (not `/` or the home
|
|
196
|
+
* dir — launchd/daemon-managed servers start with cwd=`/`);
|
|
197
|
+
* 3. the session workspace decoded from `DSH_SESSION_JSONL` (present when
|
|
198
|
+
* the DSH runtime injects per-session env into tool sub-processes).
|
|
199
|
+
*/
|
|
200
|
+
export function resolveProjectRoot(input?: string, sessionCwd?: string): ProjectRootResult {
|
|
188
201
|
const raw = (input ?? '').trim()
|
|
189
|
-
const root = raw ? resolve(raw) : resolve(effectiveCwd())
|
|
202
|
+
const root = raw ? resolve(raw) : resolve(effectiveCwd(sessionCwd))
|
|
190
203
|
if (!root || root === sep) {
|
|
191
204
|
return { ok: false, reason: 'Refusing filesystem root as project root.' }
|
|
192
205
|
}
|
|
193
206
|
return { ok: true, root }
|
|
194
207
|
}
|
|
195
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Thin adapter for tool `execute(args, exec)` bodies: pull the session cwd
|
|
211
|
+
* from the DSH run context and hand it to {@link resolveProjectRoot}.
|
|
212
|
+
*/
|
|
213
|
+
export function resolveProjectRootForExec(
|
|
214
|
+
exec: { agent?: { session?: { header?: { cwd?: string } } } } | undefined,
|
|
215
|
+
input?: string,
|
|
216
|
+
): ProjectRootResult {
|
|
217
|
+
return resolveProjectRoot(input, exec?.agent?.session?.header?.cwd)
|
|
218
|
+
}
|
|
219
|
+
|
|
196
220
|
/**
|
|
197
221
|
* Resolve the default working directory for tools invoked without an explicit
|
|
198
|
-
* `path`. Prefers the
|
|
199
|
-
*
|
|
200
|
-
* case fall back to the session workspace encoded in `DSH_SESSION_JSONL`
|
|
222
|
+
* `path`. Prefers the caller-provided session cwd, then the process cwd, then
|
|
223
|
+
* the session workspace encoded in `DSH_SESSION_JSONL`
|
|
201
224
|
* (`…/sessions/<encoded-workspace>/<session-id>/session.jsonl.zstd`), where
|
|
202
225
|
* the workspace directory is `--`-wrapped with `/` → `-` and percent-encoded
|
|
203
226
|
* bytes spelled as `~<hex>` (e.g. `/Volumes/Eng-Dev/iterate-skill` →
|
|
204
227
|
* `--Volumes-Eng-Dev-iterate-skill--`).
|
|
205
228
|
*/
|
|
206
|
-
function effectiveCwd(): string {
|
|
229
|
+
function effectiveCwd(sessionCwd?: string): string {
|
|
230
|
+
if (sessionCwd && sessionCwd !== sep && sessionCwd !== homedir()) return sessionCwd
|
|
207
231
|
let cwd = ''
|
|
208
232
|
try {
|
|
209
233
|
cwd = process.cwd()
|
package/src/tools/checkpoint.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
13
13
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
14
14
|
import type { JsonValue } from '@deepseek-ai/dsh-session'
|
|
15
|
-
import {
|
|
15
|
+
import { resolveProjectRootForExec } from '../config-loader.ts'
|
|
16
16
|
import { checkpointPath, iterateDir } from '../paths.ts'
|
|
17
17
|
import { readRegistry } from './fix.ts'
|
|
18
18
|
import { readDecisionEntries } from './decision-log.ts'
|
|
@@ -166,8 +166,8 @@ export function registerCheckpointTool(ctx: { tools: { register: (def: ReturnTyp
|
|
|
166
166
|
],
|
|
167
167
|
},
|
|
168
168
|
|
|
169
|
-
async execute(args) {
|
|
170
|
-
const resolved =
|
|
169
|
+
async execute(args, exec) {
|
|
170
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
171
171
|
if (!resolved.ok) return { operation: args.operation, ok: false, error: resolved.reason }
|
|
172
172
|
const projectRoot = resolved.root
|
|
173
173
|
|
|
@@ -274,8 +274,8 @@ export function registerStatusTool(ctx: { tools: { register: (def: ReturnType<ty
|
|
|
274
274
|
},
|
|
275
275
|
},
|
|
276
276
|
|
|
277
|
-
async execute(args) {
|
|
278
|
-
const resolved =
|
|
277
|
+
async execute(args, exec) {
|
|
278
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
279
279
|
if (!resolved.ok) return { ok: false, error: resolved.reason }
|
|
280
280
|
const projectRoot = resolved.root
|
|
281
281
|
const status = computeStatus({
|
package/src/tools/config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path'
|
|
2
2
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
3
3
|
import type { JsonValue } from '@deepseek-ai/dsh-session'
|
|
4
|
-
import { loadEffectiveConfig, validateConfig,
|
|
4
|
+
import { loadEffectiveConfig, validateConfig, resolveProjectRootForExec } from '../config-loader.ts'
|
|
5
5
|
import {
|
|
6
6
|
applyConfigUpdates,
|
|
7
7
|
readRawConfig,
|
|
@@ -76,8 +76,8 @@ export function registerConfigTool(ctx: { tools: { register: (def: ReturnType<ty
|
|
|
76
76
|
],
|
|
77
77
|
},
|
|
78
78
|
|
|
79
|
-
async execute(args) {
|
|
80
|
-
const resolved =
|
|
79
|
+
async execute(args, exec) {
|
|
80
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
81
81
|
if (!resolved.ok) {
|
|
82
82
|
return { found: false, error: resolved.reason }
|
|
83
83
|
}
|
package/src/tools/context.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync, existsSync } from 'node:fs'
|
|
|
2
2
|
import { join, dirname, resolve } from 'node:path'
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
4
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
5
|
-
import {
|
|
5
|
+
import { resolveProjectRootForExec } from '../config-loader.ts'
|
|
6
6
|
|
|
7
7
|
/** How many ancestor directories we walk up looking for a SKILL.md. */
|
|
8
8
|
const MAX_SKILL_DIR_LOOKUP_DEPTH = 12
|
|
@@ -257,8 +257,8 @@ export function registerContextTool(ctx: { tools: { register: (def: ReturnType<t
|
|
|
257
257
|
},
|
|
258
258
|
},
|
|
259
259
|
|
|
260
|
-
async execute(args) {
|
|
261
|
-
const resolved =
|
|
260
|
+
async execute(args, exec) {
|
|
261
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
262
262
|
if (!resolved.ok) {
|
|
263
263
|
return { found: false, error: resolved.reason, searched: [] }
|
|
264
264
|
}
|
|
@@ -2,7 +2,7 @@ import { appendFileSync, readFileSync, mkdirSync, existsSync } from 'node:fs'
|
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
4
4
|
import type { JsonValue } from '@deepseek-ai/dsh-session'
|
|
5
|
-
import {
|
|
5
|
+
import { resolveProjectRootForExec } from '../config-loader.ts'
|
|
6
6
|
import type { DecisionLogEntry } from '../types.ts'
|
|
7
7
|
|
|
8
8
|
const LOG_DIR = '.iterate'
|
|
@@ -159,8 +159,8 @@ export function registerDecisionLogTool(ctx: { tools: { register: (def: ReturnTy
|
|
|
159
159
|
],
|
|
160
160
|
},
|
|
161
161
|
|
|
162
|
-
async execute(args) {
|
|
163
|
-
const resolved =
|
|
162
|
+
async execute(args, exec) {
|
|
163
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
164
164
|
if (!resolved.ok) {
|
|
165
165
|
return { operation: args.operation, error: resolved.reason }
|
|
166
166
|
}
|
package/src/tools/fix.ts
CHANGED
|
@@ -21,7 +21,7 @@ import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from
|
|
|
21
21
|
import { join } from 'node:path'
|
|
22
22
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
23
23
|
import type { JsonValue } from '@deepseek-ai/dsh-session'
|
|
24
|
-
import { loadEffectiveConfig,
|
|
24
|
+
import { loadEffectiveConfig, resolveProjectRootForExec } from '../config-loader.ts'
|
|
25
25
|
import { countTouchedMethods } from '../method-scope.ts'
|
|
26
26
|
import { fixBackupPath, fixRegistryPath, fixesDir } from '../paths.ts'
|
|
27
27
|
import { appendDecisionEntry } from './decision-log.ts'
|
|
@@ -284,8 +284,8 @@ export function registerFixTool(ctx: { tools: { register: (def: ReturnType<typeo
|
|
|
284
284
|
],
|
|
285
285
|
},
|
|
286
286
|
|
|
287
|
-
async execute(args) {
|
|
288
|
-
const resolved =
|
|
287
|
+
async execute(args, exec) {
|
|
288
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
289
289
|
if (!resolved.ok) return { ok: false, error: resolved.reason }
|
|
290
290
|
const projectRoot = resolved.root
|
|
291
291
|
const { config } = loadEffectiveConfig(projectRoot)
|
|
@@ -454,8 +454,8 @@ export function registerDiffTool(ctx: { tools: { register: (def: ReturnType<type
|
|
|
454
454
|
},
|
|
455
455
|
},
|
|
456
456
|
|
|
457
|
-
async execute(args) {
|
|
458
|
-
const resolved =
|
|
457
|
+
async execute(args, exec) {
|
|
458
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
459
459
|
if (!resolved.ok) return { ok: false, error: resolved.reason }
|
|
460
460
|
const projectRoot = resolved.root
|
|
461
461
|
const registry = readRegistry(projectRoot)
|
|
@@ -544,8 +544,8 @@ export function registerRollbackTool(ctx: { tools: { register: (def: ReturnType<
|
|
|
544
544
|
],
|
|
545
545
|
},
|
|
546
546
|
|
|
547
|
-
async execute(args) {
|
|
548
|
-
const resolved =
|
|
547
|
+
async execute(args, exec) {
|
|
548
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
549
549
|
if (!resolved.ok) return { ok: false, error: resolved.reason }
|
|
550
550
|
const projectRoot = resolved.root
|
|
551
551
|
const id = typeof args.id === 'string' ? args.id : ''
|
package/src/tools/history.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
12
12
|
import type { JsonValue } from '@deepseek-ai/dsh-session'
|
|
13
|
-
import {
|
|
13
|
+
import { resolveProjectRootForExec } from '../config-loader.ts'
|
|
14
14
|
import { readDecisionEntries } from './decision-log.ts'
|
|
15
15
|
import { readRegistry } from './fix.ts'
|
|
16
16
|
import type { DecisionLogEntry, FixRegistry } from '../types.ts'
|
|
@@ -136,8 +136,8 @@ export function registerHistoryTool(ctx: { tools: { register: (def: ReturnType<t
|
|
|
136
136
|
},
|
|
137
137
|
},
|
|
138
138
|
|
|
139
|
-
async execute(args) {
|
|
140
|
-
const resolved =
|
|
139
|
+
async execute(args, exec) {
|
|
140
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
141
141
|
if (!resolved.ok) return { ok: false, kind: 'history', error: resolved.reason }
|
|
142
142
|
const projectRoot = resolved.root
|
|
143
143
|
|
package/src/tools/prune.ts
CHANGED
|
@@ -22,7 +22,7 @@ import { existsSync, readdirSync, rmSync, unlinkSync, writeFileSync } from 'node
|
|
|
22
22
|
import { join } from 'node:path'
|
|
23
23
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
24
24
|
import type { JsonValue } from '@deepseek-ai/dsh-session'
|
|
25
|
-
import {
|
|
25
|
+
import { resolveProjectRootForExec } from '../config-loader.ts'
|
|
26
26
|
import { readDecisionEntries, appendDecisionEntry } from './decision-log.ts'
|
|
27
27
|
import { readRegistry, removeRecord, recomputeRoundCounts } from './fix.ts'
|
|
28
28
|
import { iterateDir, fixesDir, checkpointPath, fixRegistryPath } from '../paths.ts'
|
|
@@ -265,8 +265,8 @@ export function registerPruneTool(ctx: { tools: { register: (def: ReturnType<typ
|
|
|
265
265
|
},
|
|
266
266
|
},
|
|
267
267
|
|
|
268
|
-
async execute(args) {
|
|
269
|
-
const resolved =
|
|
268
|
+
async execute(args, exec) {
|
|
269
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
270
270
|
if (!resolved.ok) return { ok: false, dryRun: true, error: resolved.reason }
|
|
271
271
|
const projectRoot = resolved.root
|
|
272
272
|
const retainDays = clampRetainDays(args.retainDays as number | undefined)
|
package/src/tools/review.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
2
|
import type { JsonValue } from '@deepseek-ai/dsh-session'
|
|
3
|
-
import { loadEffectiveConfig,
|
|
3
|
+
import { loadEffectiveConfig, resolveProjectRootForExec } from '../config-loader.ts'
|
|
4
4
|
import {
|
|
5
5
|
buildReviewPlan,
|
|
6
6
|
buildReviewReport,
|
|
@@ -131,8 +131,8 @@ export function registerReviewTool(ctx: { tools: { register: (def: ReturnType<ty
|
|
|
131
131
|
],
|
|
132
132
|
},
|
|
133
133
|
|
|
134
|
-
async execute(args) {
|
|
135
|
-
const resolved =
|
|
134
|
+
async execute(args, exec) {
|
|
135
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
136
136
|
if (!resolved.ok) {
|
|
137
137
|
return { operation: args.operation, error: resolved.reason }
|
|
138
138
|
}
|
package/src/tools/triage.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { join } from 'node:path'
|
|
|
3
3
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
4
4
|
import type { JsonValue } from '@deepseek-ai/dsh-session'
|
|
5
5
|
import yaml from 'js-yaml'
|
|
6
|
-
import {
|
|
6
|
+
import { resolveProjectRootForExec } from '../config-loader.ts'
|
|
7
7
|
import type { KnownIntentional } from '../types.ts'
|
|
8
8
|
|
|
9
9
|
const CONFIG_FILE = 'iterate.config.yaml'
|
|
@@ -313,8 +313,8 @@ export function registerTriageTool(ctx: { tools: { register: (def: ReturnType<ty
|
|
|
313
313
|
],
|
|
314
314
|
},
|
|
315
315
|
|
|
316
|
-
async execute(args) {
|
|
317
|
-
const resolved =
|
|
316
|
+
async execute(args, exec) {
|
|
317
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
318
318
|
if (!resolved.ok) {
|
|
319
319
|
return { operation: args.operation, error: resolved.reason }
|
|
320
320
|
}
|
package/src/tools/validate.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
loadEffectiveConfig,
|
|
5
5
|
isCommandAllowed,
|
|
6
6
|
flattenCommands,
|
|
7
|
-
|
|
7
|
+
resolveProjectRootForExec,
|
|
8
8
|
} from '../config-loader.ts'
|
|
9
9
|
import type { ValidationResult } from '../types.ts'
|
|
10
10
|
|
|
@@ -126,8 +126,8 @@ export function registerValidateTool(ctx: { tools: { register: (def: ReturnType<
|
|
|
126
126
|
],
|
|
127
127
|
},
|
|
128
128
|
|
|
129
|
-
async execute(args) {
|
|
130
|
-
const resolved =
|
|
129
|
+
async execute(args, exec) {
|
|
130
|
+
const resolved = resolveProjectRootForExec(exec, args.path)
|
|
131
131
|
if (!resolved.ok) {
|
|
132
132
|
return {
|
|
133
133
|
allowed: false,
|