@difflab/pi 0.7.1 → 0.7.2

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.
Files changed (56) hide show
  1. package/README.md +22 -40
  2. package/agents/diffpi-copilot.md +2 -2
  3. package/agents/diffpi-orchestrator.md +9 -14
  4. package/agents/diffpi-plan-reviewer.md +4 -12
  5. package/agents/diffpi-planner.md +6 -12
  6. package/agents/diffpi-reviewer.md +6 -10
  7. package/agents/diffpi-tutor.md +2 -2
  8. package/agents/diffpi-worker.md +3 -6
  9. package/dist/commands/dispatch.d.ts +4 -0
  10. package/dist/commands/dispatch.d.ts.map +1 -0
  11. package/dist/commands/index.d.ts +1 -3
  12. package/dist/commands/index.d.ts.map +1 -1
  13. package/dist/commands/plan.d.ts +1 -1
  14. package/dist/commands/plan.d.ts.map +1 -1
  15. package/dist/commands/review.d.ts +1 -1
  16. package/dist/commands/review.d.ts.map +1 -1
  17. package/dist/extensions/index.js +365 -881
  18. package/dist/index.d.ts +0 -2
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +40 -403
  21. package/dist/tools/index.d.ts +1 -3
  22. package/dist/tools/index.d.ts.map +1 -1
  23. package/dist/tools/index.js +95 -212
  24. package/package.json +2 -2
  25. package/skills/diffpi-setup/SKILL.md +1 -1
  26. package/skills/plan/SKILL.md +12 -22
  27. package/skills/plan/references/design-quality.md +3 -3
  28. package/skills/plan/references/workflows/annotate.md +9 -3
  29. package/skills/plan/references/workflows/finalize.md +10 -6
  30. package/skills/plan/references/workflows/go.md +25 -7
  31. package/skills/plan/references/workflows/help.md +20 -3
  32. package/skills/plan/references/workflows/init.md +23 -6
  33. package/skills/plan/references/workflows/inline-fallback.md +9 -0
  34. package/skills/plan/references/workflows/new.md +22 -7
  35. package/skills/plan/references/workflows/update.md +22 -6
  36. package/skills/plan/references/workflows/validate.md +31 -0
  37. package/skills/review/SKILL.md +14 -6
  38. package/skills/review/references/workflows/address.md +19 -6
  39. package/skills/review/references/workflows/auto.md +21 -5
  40. package/skills/review/references/workflows/complete.md +17 -4
  41. package/skills/review/references/workflows/edit.md +8 -2
  42. package/skills/review/references/workflows/foreground-fallback.md +7 -0
  43. package/skills/review/references/workflows/help.md +22 -13
  44. package/skills/review/references/workflows/merge.md +17 -2
  45. package/skills/review/references/workflows/new.md +17 -5
  46. package/skills/review/references/workflows/open.md +8 -2
  47. package/skills/review/references/workflows/publish.md +17 -4
  48. package/skills/review/references/workflows/status.md +7 -2
  49. package/templates/plan/PLAN.md +1 -1
  50. package/dist/commands/mode.d.ts +0 -5
  51. package/dist/commands/mode.d.ts.map +0 -1
  52. package/dist/modes.d.ts +0 -75
  53. package/dist/modes.d.ts.map +0 -1
  54. package/dist/tools/modes.d.ts +0 -4
  55. package/dist/tools/modes.d.ts.map +0 -1
  56. package/skills/mode/SKILL.md +0 -38
package/dist/index.d.ts CHANGED
@@ -6,7 +6,6 @@ export { checkConventionalSubject, CONVENTIONAL_COMMIT, runMiseGates } from './g
6
6
  export { assertReviewEventSupported, createLocalReviewBackend, createRemoteReviewBackend, githubReviewSubmissionEndpoint, hasGitlabDraftNotes, parseGitlabDiffRefs, } from './review';
7
7
  export { mcp } from './mcp';
8
8
  export { mise } from './extensions/misex';
9
- export { createModeController, discoverAgentModes, resolveAgentMode } from './modes';
10
9
  export { pi } from './pi';
11
10
  export { loadReviewPublicationState, reviewBodyFingerprint, reviewCommentFingerprint, reviewReplyFingerprint, saveReviewPublicationState, unpublishedReviewComments, } from './review';
12
11
  export { computeProjectSlug, ensureStore, plansDir, reviewsDir, sessionsDir, storeDir, storeGlobalRoot } from './store';
@@ -17,7 +16,6 @@ export { dedupeFindings, findingSchema, findingsSchema, yymmdd, localReviewAutho
17
16
  export { ensureMcpAdapters, ensureMise, ensureMiseDeps, ensureMiseHooks, ensurePiAgents, ensurePiPlugins, ensurePiSkills, setupPi, } from './setup';
18
17
  export { loadTemplate, renderTemplate, templateRelativePath } from './templates';
19
18
  export type { DiffpiAgentConfig, DiffpiConfig, DiffpiConfigPaths, LoadedDiffpiConfig } from './config';
20
- export type { AgentMode, ModeCatalog, ModeController, ModeListOptions, ModePromptStrategy, ModeSelectionResult, ModeThinkingLevel, } from './modes';
21
19
  export type { CommandResult } from './extensions/processx';
22
20
  export type { ForgeProvider, Ide, LaunchOptions, LaunchResult, Mux, VcsInfo } from './environment';
23
21
  export type { Forge, OpenPrOptions, PrRef, VcsBackend } from './vcs';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -15,15 +15,6 @@ var zx = {
15
15
 
16
16
  // src/fsx.ts
17
17
  import { readdir, readFile } from "node:fs/promises";
18
- async function readDirectoryIfExists(path) {
19
- try {
20
- return await readdir(path, { withFileTypes: true });
21
- } catch (error) {
22
- if (isMissingPath(error))
23
- return [];
24
- throw error;
25
- }
26
- }
27
18
  async function readTextIfExists(path) {
28
19
  try {
29
20
  return await readFile(path, "utf8");
@@ -2108,361 +2099,10 @@ async function getOptionalFile2(path) {
2108
2099
  function isRecord(value) {
2109
2100
  return value !== null && typeof value === "object" && !Array.isArray(value);
2110
2101
  }
2111
- // src/modes.ts
2112
- import {
2113
- getAgentDir,
2114
- parseFrontmatter as parseFrontmatter2
2115
- } from "@earendil-works/pi-coding-agent";
2116
- import { readFile as readFile9 } from "node:fs/promises";
2117
- import { homedir as homedir6 } from "node:os";
2118
- import { basename as basename4, extname, join as join11 } from "node:path";
2119
- async function discoverAgentModes(options) {
2120
- const agentDir = options.agentDir ?? getAgentDir();
2121
- const homeDir = options.homeDir ?? homedir6();
2122
- const modes = new Map;
2123
- const diagnostics = [];
2124
- await loadAgentModes(options.bundledAgentsDir ?? BUNDLED_AGENTS_DIR, "diffpi agent", modes, diagnostics);
2125
- await loadAgentModes(join11(agentDir, "agents"), "user agent", modes, diagnostics);
2126
- if (options.includeSkills) {
2127
- await loadSkillModes(join11(homeDir, ".agents", "skills"), "user skill", modes, diagnostics);
2128
- await loadSkillModes(join11(agentDir, "skills"), "pi user skill", modes, diagnostics);
2129
- }
2130
- if (options.projectTrusted === true) {
2131
- if (options.includeSkills) {
2132
- await loadSkillModes(join11(options.cwd, ".agents", "skills"), "project skill", modes, diagnostics);
2133
- await loadSkillModes(join11(options.cwd, ".pi", "skills"), "pi project skill", modes, diagnostics);
2134
- }
2135
- await loadAgentModes(join11(options.cwd, ".agents", "agents"), "project agent", modes, diagnostics);
2136
- await loadAgentModes(join11(options.cwd, ".pi", "agents"), "pi project agent", modes, diagnostics);
2137
- }
2138
- const userConfig = await loadDiffpiConfig({ homeDir });
2139
- const configuredModes = [...modes.values()].map((mode) => ({
2140
- ...mode,
2141
- modelPreferences: resolveAgentModelPreferences(mode.id, mode.modelPreferences, userConfig.config)
2142
- }));
2143
- return {
2144
- modes: configuredModes.sort((left, right) => left.id.localeCompare(right.id)),
2145
- diagnostics
2146
- };
2147
- }
2148
- function resolveAgentMode(modes, requested) {
2149
- const name = requested.trim();
2150
- if (!name)
2151
- return { ok: false, message: "Agent name is required." };
2152
- const exact = modes.find((mode) => mode.id === name);
2153
- if (exact)
2154
- return { ok: true, active: exact, message: `Active inline agent: ${exact.id}.` };
2155
- const lowerName = name.toLowerCase();
2156
- const matches = modes.filter((mode) => mode.id.toLowerCase() === lowerName);
2157
- if (matches.length === 1) {
2158
- const active = matches[0];
2159
- return { ok: true, active, message: `Active inline agent: ${active.id}.` };
2160
- }
2161
- if (matches.length > 1) {
2162
- return {
2163
- ok: false,
2164
- message: `Inline agent "${name}" is ambiguous. Use one of: ${matches.map((mode) => mode.id).join(", ")}.`
2165
- };
2166
- }
2167
- return { ok: false, message: `Unknown inline agent "${name}". Run /skill:mode or diffpi_modes_list.` };
2168
- }
2169
- function createModeController(pi, options = {}) {
2170
- let active;
2171
- let baseline;
2172
- const updateStatus = (ctx) => {
2173
- const model = ctx.model ? ` · ${ctx.model.provider}/${ctx.model.id}` : "";
2174
- const label = active?.label.toUpperCase() ?? "DEFAULT";
2175
- const badge = `AGENT ${label}${model}`;
2176
- ctx.ui.setStatus(MODE_STATUS_KEY, undefined);
2177
- ctx.ui.setWidget?.(MODE_WIDGET_KEY, [badge], { placement: "belowEditor" });
2178
- };
2179
- const list = (ctx, listOptions = {}) => discoverAgentModes({
2180
- cwd: ctx.cwd,
2181
- agentDir: options.agentDir,
2182
- bundledAgentsDir: options.bundledAgentsDir,
2183
- homeDir: options.homeDir,
2184
- projectTrusted: ctx.isProjectTrusted(),
2185
- includeSkills: listOptions.includeSkills
2186
- });
2187
- return {
2188
- list,
2189
- async set(agent, ctx) {
2190
- const catalog = await list(ctx, { includeSkills: agent.includes(":") });
2191
- const result = resolveAgentMode(catalog.modes, agent);
2192
- if (!result.ok || !result.active)
2193
- return result;
2194
- const previousActive = active;
2195
- const previousBaseline = baseline;
2196
- baseline ??= captureRuntime(pi, ctx);
2197
- if (active && baseline)
2198
- await restoreRuntime(pi, baseline, ctx);
2199
- active = result.active;
2200
- try {
2201
- const runtimeMessage = await applyModeRuntime(pi, active, ctx);
2202
- pi.appendEntry(MODE_STATE_ENTRY, { active, baseline });
2203
- updateStatus(ctx);
2204
- return { ...result, message: `${result.message} ${runtimeMessage}` };
2205
- } catch (error) {
2206
- await restoreRuntime(pi, baseline, ctx);
2207
- active = undefined;
2208
- baseline = undefined;
2209
- if (previousActive && previousBaseline) {
2210
- try {
2211
- active = previousActive;
2212
- baseline = previousBaseline;
2213
- await applyModeRuntime(pi, active, ctx);
2214
- } catch {
2215
- active = undefined;
2216
- baseline = undefined;
2217
- }
2218
- }
2219
- if (!active)
2220
- pi.appendEntry(MODE_STATE_ENTRY, { active: null });
2221
- updateStatus(ctx);
2222
- return { ok: false, message: error instanceof Error ? error.message : String(error) };
2223
- }
2224
- },
2225
- async unset(ctx) {
2226
- if (!active)
2227
- return { ok: true, message: "Inline agent is already clear." };
2228
- if (baseline)
2229
- await restoreRuntime(pi, baseline, ctx);
2230
- active = undefined;
2231
- pi.appendEntry(MODE_STATE_ENTRY, { active: null });
2232
- baseline = undefined;
2233
- updateStatus(ctx);
2234
- return { ok: true, message: "Inline agent cleared. The previous model, thinking, tools, and prompt resume." };
2235
- },
2236
- async restore(ctx) {
2237
- const previousActive = active;
2238
- const previousBaseline = baseline;
2239
- const entry = [...ctx.sessionManager.getBranch()].reverse().find((candidate) => candidate.type === "custom" && candidate.customType === MODE_STATE_ENTRY);
2240
- const restored = entry?.data?.active;
2241
- const restoredBaseline = entry?.data?.baseline;
2242
- if (isAgentModeSnapshot(restored)) {
2243
- const catalog = await list(ctx, { includeSkills: restored.id.includes(":") });
2244
- const current = catalog.modes.find((mode) => mode.id === restored.id);
2245
- active = current ?? normalizeAgentModeSnapshot(restored);
2246
- baseline = isModeBaseline(restoredBaseline) ? restoredBaseline : previousBaseline;
2247
- try {
2248
- await applyModeRuntime(pi, active, ctx);
2249
- } catch (error) {
2250
- const fallbackBaseline = previousBaseline ?? (isModeBaseline(restoredBaseline) ? restoredBaseline : undefined);
2251
- if (fallbackBaseline)
2252
- await restoreRuntime(pi, fallbackBaseline, ctx);
2253
- active = undefined;
2254
- baseline = undefined;
2255
- throw error;
2256
- }
2257
- } else {
2258
- if (previousActive && previousBaseline)
2259
- pi.setActiveTools(previousBaseline.tools);
2260
- active = undefined;
2261
- baseline = undefined;
2262
- }
2263
- updateStatus(ctx);
2264
- },
2265
- refresh(ctx) {
2266
- updateStatus(ctx);
2267
- },
2268
- apply(systemPrompt) {
2269
- if (!active)
2270
- return systemPrompt;
2271
- if (active.promptStrategy === "replace")
2272
- return active.systemPrompt;
2273
- return `${systemPrompt}
2274
-
2275
- ## Active inline agent: ${active.label}
2276
-
2277
- ${active.systemPrompt}`;
2278
- },
2279
- getActive() {
2280
- return active;
2281
- },
2282
- getStatus(ctx) {
2283
- return {
2284
- active: active?.id,
2285
- model: ctx.model ? { provider: ctx.model.provider, id: ctx.model.id } : undefined,
2286
- thinkingLevel: pi.getThinkingLevel(),
2287
- activeTools: pi.getActiveTools(),
2288
- capabilityError: active ? validateModeRuntime(pi, active, ctx) : undefined
2289
- };
2290
- }
2291
- };
2292
- }
2293
- var MODE_STATE_ENTRY = "diffpi-mode-state";
2294
- var MODE_STATUS_KEY = "diffpi-mode";
2295
- var MODE_WIDGET_KEY = "diffpi-mode-badge";
2296
- var MODE_CONTROL_TOOLS = [
2297
- "ask_user_question",
2298
- "diffpi_modes_list",
2299
- "diffpi_modes_set",
2300
- "diffpi_modes_unset",
2301
- "diffpi_modes_status"
2302
- ];
2303
- var BUNDLED_AGENTS_DIR = resolveBundledAgentsDir();
2304
- var THINKING_LEVELS = new Set(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
2305
- async function applyModeRuntime(pi, mode, ctx) {
2306
- let selectedModel;
2307
- if (mode.modelPreferences.length > 0) {
2308
- const scoped = ctx.scopedModels.length > 0 ? ctx.scopedModels.map((entry) => entry.model) : undefined;
2309
- const availableModels = scoped ?? ctx.modelRegistry.getAvailable();
2310
- for (const preference of mode.modelPreferences) {
2311
- const model = findPreferredModel(availableModels, preference);
2312
- if (model && await pi.setModel(model)) {
2313
- selectedModel = `${model.provider}/${model.id}`;
2314
- break;
2315
- }
2316
- }
2317
- }
2318
- if (mode.thinkingLevel)
2319
- pi.setThinkingLevel(mode.thinkingLevel);
2320
- if (mode.tools.length > 0) {
2321
- const availableTools = new Set(pi.getAllTools().map((tool) => tool.name));
2322
- const selectedTools = [...new Set([...mode.tools, ...MODE_CONTROL_TOOLS])].filter((tool) => availableTools.has(tool));
2323
- if (selectedTools.length > 0)
2324
- pi.setActiveTools(selectedTools);
2325
- }
2326
- const availableTools = new Set(pi.getAllTools().map((tool) => tool.name));
2327
- const unavailableTools = mode.requiredTools.filter((tool) => !availableTools.has(tool));
2328
- const activeTools = new Set(pi.getActiveTools());
2329
- const missingTools = mode.requiredTools.filter((tool) => !activeTools.has(tool));
2330
- const forbiddenTools = mode.forbiddenTools.filter((tool) => activeTools.has(tool));
2331
- if (unavailableTools.length > 0 || missingTools.length > 0 || forbiddenTools.length > 0)
2332
- throw new Error(`Profile preflight failed: missing required tools [${[...new Set([...unavailableTools, ...missingTools])].join(", ")}]${forbiddenTools.length > 0 ? `; forbidden tools active [${forbiddenTools.join(", ")}]` : ""}`);
2333
- if (mode.requireModel && !selectedModel)
2334
- throw new Error("Profile preflight failed: requested model was not selected.");
2335
- if (mode.requireThinking && (!mode.thinkingLevel || pi.getThinkingLevel() !== mode.thinkingLevel))
2336
- throw new Error(`Profile preflight failed: thinking level ${mode.thinkingLevel ?? "unset"} was not applied.`);
2337
- const parts = [];
2338
- if (mode.modelPreferences.length > 0) {
2339
- parts.push(selectedModel ? `Model: ${selectedModel}.` : "No preferred model was available; kept the current model.");
2340
- }
2341
- if (mode.thinkingLevel)
2342
- parts.push(`Thinking: ${mode.thinkingLevel}.`);
2343
- if (mode.tools.length > 0)
2344
- parts.push("Applied the profile tool set.");
2345
- return parts.join(" ") || "The profile changes the prompt only.";
2346
- }
2347
- function validateModeRuntime(pi, mode, ctx) {
2348
- const activeTools = new Set(pi.getActiveTools());
2349
- const missingTools = mode.requiredTools.filter((tool) => !activeTools.has(tool));
2350
- const forbiddenTools = mode.forbiddenTools.filter((tool) => activeTools.has(tool));
2351
- if (missingTools.length > 0 || forbiddenTools.length > 0)
2352
- return `Profile capability check failed: missing required tools [${missingTools.join(", ")}]${forbiddenTools.length > 0 ? `; forbidden tools active [${forbiddenTools.join(", ")}]` : ""}`;
2353
- if (mode.requireModel && mode.modelPreferences.length > 0) {
2354
- const actual = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : "unset";
2355
- const available = ctx.scopedModels.length > 0 ? ctx.scopedModels.map((entry) => entry.model) : ctx.modelRegistry.getAvailable();
2356
- const expected = mode.modelPreferences.map((preference) => findPreferredModel(available, preference)).find(Boolean);
2357
- if (!expected || `${expected.provider}/${expected.id}` !== actual)
2358
- return `Profile capability check failed: requested model was not active (actual ${actual}).`;
2359
- }
2360
- if (mode.requireThinking && (!mode.thinkingLevel || pi.getThinkingLevel() !== mode.thinkingLevel))
2361
- return `Profile capability check failed: thinking level ${mode.thinkingLevel ?? "unset"} was not applied.`;
2362
- return;
2363
- }
2364
- async function restoreRuntime(pi, state, ctx) {
2365
- if (state.model) {
2366
- const model = ctx.modelRegistry.find(state.model.provider, state.model.id);
2367
- if (model)
2368
- await pi.setModel(model);
2369
- }
2370
- pi.setThinkingLevel(state.thinkingLevel);
2371
- pi.setActiveTools(state.tools);
2372
- const restoredTools = pi.getActiveTools();
2373
- if (state.tools.some((tool) => !restoredTools.includes(tool)))
2374
- throw new Error("Failed to restore the previous active tool set.");
2375
- }
2376
- function captureRuntime(pi, ctx) {
2377
- return {
2378
- model: ctx.model ? { provider: ctx.model.provider, id: ctx.model.id } : undefined,
2379
- thinkingLevel: pi.getThinkingLevel(),
2380
- tools: pi.getActiveTools()
2381
- };
2382
- }
2383
- async function loadSkillModes(skillsDir, source, modes, diagnostics) {
2384
- const entries = await readDirectoryIfExists(skillsDir);
2385
- for (const entry of entries.filter((item) => item.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
2386
- await loadAgentModes(join11(skillsDir, entry.name, "agents"), `${source} ${entry.name}`, modes, diagnostics, entry.name);
2387
- }
2388
- }
2389
- async function loadAgentModes(directory, source, modes, diagnostics, skillName) {
2390
- const entries = await readDirectoryIfExists(directory);
2391
- for (const entry of entries.filter((item) => item.isFile() && item.name.endsWith(".md")).sort((a, b) => a.name.localeCompare(b.name))) {
2392
- const path = join11(directory, entry.name);
2393
- try {
2394
- const content = await readFile9(path, "utf8");
2395
- const { frontmatter, body } = parseFrontmatter2(content.startsWith("\uFEFF") ? content.slice(1) : content);
2396
- if (frontmatter.enabled === false || frontmatter.inline === false)
2397
- continue;
2398
- const name = getFrontmatterText(frontmatter.name) ?? basename4(path, extname(path));
2399
- const systemPrompt = body.trim();
2400
- if (!name || name.includes(":") || !systemPrompt) {
2401
- diagnostics.push(`Skipped ${path}: agent name must not contain ":" and prompt body is required.`);
2402
- continue;
2403
- }
2404
- const id = skillName ? `${skillName}:${name}` : name;
2405
- modes.set(id, {
2406
- id,
2407
- label: getFrontmatterText(frontmatter.display_name) ?? name,
2408
- description: getFrontmatterText(frontmatter.description) ?? `Inline agent from ${basename4(path)}`,
2409
- systemPrompt,
2410
- promptStrategy: frontmatter.prompt_mode === "append" ? "append" : "replace",
2411
- modelPreferences: [
2412
- ...getFrontmatterList(frontmatter.model),
2413
- ...getFrontmatterList(frontmatter.model_fallbacks)
2414
- ],
2415
- thinkingLevel: getThinkingLevel(frontmatter.thinking),
2416
- requiredTools: getFrontmatterList(frontmatter.required_tools),
2417
- forbiddenTools: getFrontmatterList(frontmatter.forbidden_tools),
2418
- requireModel: frontmatter.required_model === true,
2419
- requireThinking: frontmatter.required_thinking === true,
2420
- tools: getFrontmatterList(frontmatter.tools),
2421
- source,
2422
- sourcePath: path
2423
- });
2424
- } catch (error) {
2425
- diagnostics.push(`Skipped ${path}: ${error instanceof Error ? error.message : String(error)}`);
2426
- }
2427
- }
2428
- }
2429
- function getFrontmatterText(value) {
2430
- return typeof value === "string" && value.trim() ? value.trim() : undefined;
2431
- }
2432
- function getFrontmatterList(value) {
2433
- const values = Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : [];
2434
- return values.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
2435
- }
2436
- function getThinkingLevel(value) {
2437
- const level = getFrontmatterText(value);
2438
- return level && THINKING_LEVELS.has(level) ? level : undefined;
2439
- }
2440
- function normalizeAgentModeSnapshot(value) {
2441
- return {
2442
- ...value,
2443
- requiredTools: Array.isArray(value.requiredTools) ? value.requiredTools : [],
2444
- forbiddenTools: Array.isArray(value.forbiddenTools) ? value.forbiddenTools : [],
2445
- requireModel: value.requireModel === true,
2446
- requireThinking: value.requireThinking === true
2447
- };
2448
- }
2449
- function isAgentModeSnapshot(value) {
2450
- if (!value || typeof value !== "object")
2451
- return false;
2452
- const candidate = value;
2453
- return typeof candidate.id === "string" && typeof candidate.label === "string" && typeof candidate.description === "string" && typeof candidate.systemPrompt === "string" && (candidate.promptStrategy === "append" || candidate.promptStrategy === "replace") && Array.isArray(candidate.modelPreferences) && (candidate.thinkingLevel === undefined || THINKING_LEVELS.has(candidate.thinkingLevel)) && (candidate.requiredTools === undefined || Array.isArray(candidate.requiredTools)) && (candidate.forbiddenTools === undefined || Array.isArray(candidate.forbiddenTools)) && (candidate.requireModel === undefined || typeof candidate.requireModel === "boolean") && (candidate.requireThinking === undefined || typeof candidate.requireThinking === "boolean") && Array.isArray(candidate.tools) && typeof candidate.source === "string" && typeof candidate.sourcePath === "string";
2454
- }
2455
- function isModeBaseline(value) {
2456
- if (!value || typeof value !== "object")
2457
- return false;
2458
- const candidate = value;
2459
- const model = candidate.model;
2460
- return (model === undefined || typeof model.provider === "string" && typeof model.id === "string") && candidate.thinkingLevel !== undefined && THINKING_LEVELS.has(candidate.thinkingLevel) && Array.isArray(candidate.tools) && candidate.tools.every((tool) => typeof tool === "string");
2461
- }
2462
2102
  // src/pi.ts
2463
2103
  import { mkdir as mkdir5, writeFile as writeFile6 } from "node:fs/promises";
2464
- import { homedir as homedir7 } from "node:os";
2465
- import { dirname as dirname6, join as join12 } from "node:path";
2104
+ import { homedir as homedir6 } from "node:os";
2105
+ import { dirname as dirname6, join as join11 } from "node:path";
2466
2106
  var pi = {
2467
2107
  executableCheck: findPiExecutable,
2468
2108
  packageList: listPiPackages,
@@ -2475,7 +2115,7 @@ var pi = {
2475
2115
  configEnsure: ensurePiConfig
2476
2116
  };
2477
2117
  async function ensurePiAgent(filename, content, agentDir = resolvePiAgentDir(), dryRun = false) {
2478
- const path = join12(agentDir, "agents", filename);
2118
+ const path = join11(agentDir, "agents", filename);
2479
2119
  const currentText = await readTextIfExists(path);
2480
2120
  const changed = currentText !== content;
2481
2121
  if (changed && !dryRun) {
@@ -2484,10 +2124,10 @@ async function ensurePiAgent(filename, content, agentDir = resolvePiAgentDir(),
2484
2124
  }
2485
2125
  return { path, changed, existed: currentText !== undefined, planned: changed && dryRun };
2486
2126
  }
2487
- async function checkGlobalPiSkill(name, agentDir = resolvePiAgentDir(), sharedSkillsDir = join12(homedir7(), ".agents", "skills")) {
2488
- const roots = [join12(agentDir, "skills"), sharedSkillsDir];
2127
+ async function checkGlobalPiSkill(name, agentDir = resolvePiAgentDir(), sharedSkillsDir = join11(homedir6(), ".agents", "skills")) {
2128
+ const roots = [join11(agentDir, "skills"), sharedSkillsDir];
2489
2129
  for (const root of roots) {
2490
- if (await readTextIfExists(join12(root, name, "SKILL.md")) !== undefined)
2130
+ if (await readTextIfExists(join11(root, name, "SKILL.md")) !== undefined)
2491
2131
  return true;
2492
2132
  }
2493
2133
  return false;
@@ -2536,8 +2176,8 @@ function hasPiPackage(listOutput, source) {
2536
2176
  async function installPiPackage(executable, source) {
2537
2177
  await runChecked(executable, ["install", source]);
2538
2178
  }
2539
- function resolvePiAgentDir(homeDir = homedir7()) {
2540
- return process.env.PI_CODING_AGENT_DIR ?? (process.env.XDG_CONFIG_HOME ? join12(process.env.XDG_CONFIG_HOME, "pi") : join12(homeDir, ".pi", "agent"));
2179
+ function resolvePiAgentDir(homeDir = homedir6()) {
2180
+ return process.env.PI_CODING_AGENT_DIR ?? (process.env.XDG_CONFIG_HOME ? join11(process.env.XDG_CONFIG_HOME, "pi") : join11(homeDir, ".pi", "agent"));
2541
2181
  }
2542
2182
  function parseJsonObject(content, path) {
2543
2183
  if (!content?.trim())
@@ -2550,27 +2190,27 @@ function parseJsonObject(content, path) {
2550
2190
  throw new Error(`Expected valid JSON object in ${path}.`);
2551
2191
  }
2552
2192
  // src/plan/verify.ts
2553
- import { readFile as readFile10, readdir as readdir2, stat } from "node:fs/promises";
2554
- import { basename as basename5, dirname as dirname7, join as join13, resolve as resolve4 } from "node:path";
2193
+ import { readFile as readFile9, readdir as readdir2, stat } from "node:fs/promises";
2194
+ import { basename as basename4, dirname as dirname7, join as join12, resolve as resolve4 } from "node:path";
2555
2195
  async function verifyLivePlan(requested, cwd = process.cwd()) {
2556
2196
  const path = resolve4(cwd, requested);
2557
2197
  let planPath = path;
2558
2198
  try {
2559
2199
  if ((await stat(path)).isDirectory())
2560
- planPath = join13(path, "PLAN.md");
2200
+ planPath = join12(path, "PLAN.md");
2561
2201
  } catch {}
2562
2202
  const issues = [];
2563
2203
  const briefPaths = [];
2564
2204
  const planDir = dirname7(planPath);
2565
- if (basename5(planPath) !== "PLAN.md") {
2205
+ if (basename4(planPath) !== "PLAN.md") {
2566
2206
  addIssue(issues, planPath, 0, "path", "Select PLAN.md or its directory.");
2567
2207
  return { planPath, briefPaths, ok: false, issues };
2568
2208
  }
2569
- if (!/^\d{6}(?:-[a-z0-9]+)+$/.test(basename5(planDir)) || basename5(dirname7(planDir)) !== "plan" || basename5(dirname7(dirname7(planDir))) !== ".diffpi")
2209
+ if (!/^\d{6}(?:-[a-z0-9]+)+$/.test(basename4(planDir)) || basename4(dirname7(planDir)) !== "plan" || basename4(dirname7(dirname7(planDir))) !== ".diffpi")
2570
2210
  addIssue(issues, planPath, 0, "layout", "Place PLAN.md under .diffpi/plan/<YYMMDD[-ticket]-short-slug>/.");
2571
2211
  let source;
2572
2212
  try {
2573
- source = await readFile10(planPath, "utf8");
2213
+ source = await readFile9(planPath, "utf8");
2574
2214
  } catch {
2575
2215
  addIssue(issues, planPath, 0, "missing-plan", "PLAN.md is not readable.");
2576
2216
  return { planPath, briefPaths, ok: false, issues };
@@ -2584,7 +2224,7 @@ async function verifyLivePlan(requested, cwd = process.cwd()) {
2584
2224
  if (!planLines[line]?.startsWith(`### Phase ${index + 1}: `))
2585
2225
  addIssue(issues, planPath, line + 1, "phase-order", "Number phase headings from 1 without gaps.");
2586
2226
  }
2587
- const implementation = join13(planDir, "implementation");
2227
+ const implementation = join12(planDir, "implementation");
2588
2228
  let rootEntries = [];
2589
2229
  let briefEntries = [];
2590
2230
  try {
@@ -2593,18 +2233,18 @@ async function verifyLivePlan(requested, cwd = process.cwd()) {
2593
2233
  } catch {}
2594
2234
  for (const entry of rootEntries) {
2595
2235
  if (entry !== "PLAN.md" && entry !== "implementation")
2596
- addIssue(issues, join13(planDir, entry), 0, "layout", "Only PLAN.md and implementation/ belong in the plan directory.");
2236
+ addIssue(issues, join12(planDir, entry), 0, "layout", "Only PLAN.md and implementation/ belong in the plan directory.");
2597
2237
  }
2598
2238
  for (const entry of briefEntries) {
2599
2239
  const ordinal = /^phase-(\d+)\.md$/.exec(entry)?.[1];
2600
2240
  if (!ordinal || !Number(ordinal) || Number(ordinal) > phases.length || entry !== `phase-${Number(ordinal)}.md`)
2601
- addIssue(issues, join13(implementation, entry), 0, "extra-brief", "Only matching numbered phase briefs belong in implementation/.");
2241
+ addIssue(issues, join12(implementation, entry), 0, "extra-brief", "Only matching numbered phase briefs belong in implementation/.");
2602
2242
  }
2603
2243
  for (let index = 0;index < phases.length; index++) {
2604
- const brief = join13(implementation, `phase-${index + 1}.md`);
2244
+ const brief = join12(implementation, `phase-${index + 1}.md`);
2605
2245
  briefPaths.push(brief);
2606
2246
  try {
2607
- const lines = visibleLines(await readFile10(brief, "utf8"));
2247
+ const lines = visibleLines(await readFile9(brief, "utf8"));
2608
2248
  if (!/^# Phase \d+:\s*\S/.test(lines[0] ?? "") || !lines[0]?.startsWith(`# Phase ${index + 1}: `))
2609
2249
  addIssue(issues, brief, 1, "phase-title", `Start with # Phase ${index + 1}: <title>.`);
2610
2250
  checkHeadings(lines, brief, ["Objective", "Files Affected", "Tasks", "Implementation Constraints"], issues);
@@ -2636,10 +2276,10 @@ function checkHeadings(lines, file, names, issues) {
2636
2276
  addIssue(issues, file, found[0]?.line ?? 0, "headings", `Expected headings, in order: ${expected.join(", ")}.`);
2637
2277
  }
2638
2278
  // src/setup.ts
2639
- import { parseFrontmatter as parseFrontmatter3 } from "@earendil-works/pi-coding-agent";
2640
- import { readdir as readdir3, readFile as readFile11 } from "node:fs/promises";
2641
- import { homedir as homedir8 } from "node:os";
2642
- import { basename as basename6, join as join14 } from "node:path";
2279
+ import { parseFrontmatter as parseFrontmatter2 } from "@earendil-works/pi-coding-agent";
2280
+ import { readdir as readdir3, readFile as readFile10 } from "node:fs/promises";
2281
+ import { homedir as homedir7 } from "node:os";
2282
+ import { basename as basename5, join as join13 } from "node:path";
2643
2283
  var MISE_DEPENDENCIES = [
2644
2284
  { name: "node", tool: "node", spec: "node@22", minimumVersion: "22.19.0" },
2645
2285
  { name: "zellij", tool: "zellij", spec: "zellij@latest", minimumVersion: undefined },
@@ -2672,14 +2312,14 @@ var PI_SKILL_SOURCES = [
2672
2312
  { repository: "cloudvoyant/codevoyant", skills: ["git"] }
2673
2313
  ];
2674
2314
  var MCP_ADAPTER_PACKAGE = "npm:pi-mcp-adapter";
2675
- var BUNDLED_AGENTS_DIR2 = resolveBundledAgentsDir();
2315
+ var BUNDLED_AGENTS_DIR = resolveBundledAgentsDir();
2676
2316
  var FORGE_DEPENDENCIES = {
2677
2317
  github: { name: "gh", tool: "gh", spec: "gh@latest", minimumVersion: undefined },
2678
2318
  gitlab: { name: "glab", tool: "glab", spec: "glab@latest", minimumVersion: undefined }
2679
2319
  };
2680
2320
  async function ensureMise(options = {}) {
2681
- const homeDir = options.homeDir ?? homedir8();
2682
- const current = await mise.executableCheck() ?? await mise.executableCheck(join14(homeDir, ".local", "bin", "mise"));
2321
+ const homeDir = options.homeDir ?? homedir7();
2322
+ const current = await mise.executableCheck() ?? await mise.executableCheck(join13(homeDir, ".local", "bin", "mise"));
2683
2323
  if (current)
2684
2324
  return { executable: current, action: createSetupAction("mise", "ready", current) };
2685
2325
  reportProgress(options, "Installing mise");
@@ -2728,9 +2368,9 @@ async function ensureMiseDeps(miseExecutable, options = {}) {
2728
2368
  async function ensurePiPlugins(options = {}) {
2729
2369
  const actions = await ensurePiPackages(PI_PACKAGES, options);
2730
2370
  const agentDir = options.agentDir ?? pi.agentDir(options.homeDir);
2731
- const webSearch = await pi.configEnsure(join14(agentDir, "web-search.json"), (config) => ({ ...config, workflow: "auto-summary" }), options.dryRun);
2371
+ const webSearch = await pi.configEnsure(join13(agentDir, "web-search.json"), (config) => ({ ...config, workflow: "auto-summary" }), options.dryRun);
2732
2372
  actions.push(getConfigSetupAction("web search settings", webSearch));
2733
- const lsp = await pi.configEnsure(join14(agentDir, "pi-lsp.json"), (config) => ({
2373
+ const lsp = await pi.configEnsure(join13(agentDir, "pi-lsp.json"), (config) => ({
2734
2374
  ...config,
2735
2375
  progressive: { ...getRecord(config.progressive), enabled: true, inject: "none" }
2736
2376
  }), options.dryRun);
@@ -2739,13 +2379,13 @@ async function ensurePiPlugins(options = {}) {
2739
2379
  }
2740
2380
  async function ensurePiAgents(options = {}) {
2741
2381
  const agentDir = options.agentDir ?? pi.agentDir(options.homeDir);
2742
- const bundledAgentsDir = options.bundledAgentsDir ?? BUNDLED_AGENTS_DIR2;
2382
+ const bundledAgentsDir = options.bundledAgentsDir ?? BUNDLED_AGENTS_DIR;
2743
2383
  const userConfig = await loadDiffpiConfig({ homeDir: options.homeDir });
2744
2384
  const entries = (await readdir3(bundledAgentsDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.startsWith("diffpi-") && entry.name.endsWith(".md")).sort((left, right) => left.name.localeCompare(right.name));
2745
2385
  const actions = [];
2746
2386
  for (const entry of entries) {
2747
- const id = basename6(entry.name, ".md").replace(/^diffpi-/, "");
2748
- const source = await readFile11(join14(bundledAgentsDir, entry.name), "utf8");
2387
+ const id = basename5(entry.name, ".md").replace(/^diffpi-/, "");
2388
+ const source = await readFile10(join13(bundledAgentsDir, entry.name), "utf8");
2749
2389
  const content = materializeAgentModels(source, id, userConfig.config, options.availableModels);
2750
2390
  const result = await pi.agentEnsure(entry.name, content, agentDir, options.dryRun);
2751
2391
  actions.push(getConfigSetupAction(`pi agent ${id}`, result));
@@ -2754,7 +2394,7 @@ async function ensurePiAgents(options = {}) {
2754
2394
  }
2755
2395
  async function ensurePiSkills(miseExecutable, options = {}) {
2756
2396
  const agentDir = options.agentDir ?? pi.agentDir(options.homeDir);
2757
- const sharedSkillsDir = join14(options.homeDir ?? homedir8(), ".agents", "skills");
2397
+ const sharedSkillsDir = join13(options.homeDir ?? homedir7(), ".agents", "skills");
2758
2398
  const actions = [];
2759
2399
  for (const source of PI_SKILL_SOURCES) {
2760
2400
  const missing = [];
@@ -2870,7 +2510,7 @@ async function gitlabMcpHost(projectDir) {
2870
2510
  }
2871
2511
  }
2872
2512
  function materializeAgentModels(content, agentId, config, availableModels) {
2873
- const { frontmatter } = parseFrontmatter3(content.startsWith("\uFEFF") ? content.slice(1) : content);
2513
+ const { frontmatter } = parseFrontmatter2(content.startsWith("\uFEFF") ? content.slice(1) : content);
2874
2514
  const profilePreferences = [...getTextList(frontmatter.model), ...getTextList(frontmatter.model_fallbacks)];
2875
2515
  const preferences = resolveAgentModelPreferences(agentId, profilePreferences, config);
2876
2516
  let selectedIndex = availableModels === undefined && preferences.length > 0 ? 0 : -1;
@@ -2950,7 +2590,7 @@ function reportProgress(options, message) {
2950
2590
  options.onProgress?.(message);
2951
2591
  }
2952
2592
  async function packageVersion2() {
2953
- const source = await readFile11(join14(resolveBundledAgentsDir(), "..", "package.json"), "utf8");
2593
+ const source = await readFile10(join13(resolveBundledAgentsDir(), "..", "package.json"), "utf8");
2954
2594
  let value;
2955
2595
  try {
2956
2596
  value = JSON.parse(source);
@@ -2965,13 +2605,13 @@ function getRecord(value) {
2965
2605
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
2966
2606
  }
2967
2607
  // src/templates.ts
2968
- import { readFile as readFile12 } from "node:fs/promises";
2969
- import { homedir as homedir9 } from "node:os";
2970
- import { join as join15, normalize } from "node:path";
2608
+ import { readFile as readFile11 } from "node:fs/promises";
2609
+ import { homedir as homedir8 } from "node:os";
2610
+ import { join as join14, normalize } from "node:path";
2971
2611
  async function loadTemplate(name, options = {}) {
2972
2612
  const relative = templateRelativePath(name);
2973
- const userPath = join15(options.homeDir ?? homedir9(), ".difflab", "diffpi", "templates", relative);
2974
- const bundledPath = join15(options.bundledDir ?? resolveBundledTemplatesDir(), relative);
2613
+ const userPath = join14(options.homeDir ?? homedir8(), ".difflab", "diffpi", "templates", relative);
2614
+ const bundledPath = join14(options.bundledDir ?? resolveBundledTemplatesDir(), relative);
2975
2615
  const user = await readOptionalFile(userPath);
2976
2616
  if (user !== undefined)
2977
2617
  return { name, path: userPath, source: "user", content: user };
@@ -2992,7 +2632,7 @@ function templateRelativePath(name) {
2992
2632
  }
2993
2633
  async function readOptionalFile(path) {
2994
2634
  try {
2995
- return await readFile12(path, "utf8");
2635
+ return await readFile11(path, "utf8");
2996
2636
  } catch (error) {
2997
2637
  if (error.code === "ENOENT")
2998
2638
  return;
@@ -3015,7 +2655,6 @@ export {
3015
2655
  createForge,
3016
2656
  createForgeBackend,
3017
2657
  createLocalReviewBackend,
3018
- createModeController,
3019
2658
  createRemoteReviewBackend,
3020
2659
  createVcsBackend,
3021
2660
  dedupeFindings,
@@ -3025,7 +2664,6 @@ export {
3025
2664
  detectVcs,
3026
2665
  diffpiConfigPaths,
3027
2666
  diffpiLaunchName,
3028
- discoverAgentModes,
3029
2667
  ensureMcpAdapters,
3030
2668
  ensureMise,
3031
2669
  ensureMiseDeps,
@@ -3062,7 +2700,6 @@ export {
3062
2700
  renderReviewDoc,
3063
2701
  renderTemplate,
3064
2702
  renderThreadArtifact,
3065
- resolveAgentMode,
3066
2703
  resolveAgentModelPreferences,
3067
2704
  resolvePrSession,
3068
2705
  resolveReviewSession,
@@ -1,12 +1,10 @@
1
1
  import type { ExtensionAPI, ToolDefinition } from '@earendil-works/pi-coding-agent';
2
- import type { ModeController } from '../modes';
3
2
  export { watchCiTool } from './ci';
4
3
  export { diffpiLogTool } from './log';
5
4
  export { planVerifyTool } from './plan';
6
5
  export { createDiffpiReloadTool } from './reload';
7
- export { createModeTools } from './modes';
8
6
  export { createReviewTools } from './review';
9
7
  export { diffpiSetupTool, diffpiValidateTool } from './setup';
10
8
  export { diffpiTemplateTool } from './templates';
11
- export declare function createPiTools(pi: Pick<ExtensionAPI, 'events' | 'sendUserMessage'>, modes: ModeController): readonly ToolDefinition[];
9
+ export declare function createPiTools(pi: Pick<ExtensionAPI, 'events' | 'sendUserMessage'>): readonly ToolDefinition[];
12
10
  //# sourceMappingURL=index.d.ts.map