devworkspace 0.2.0 → 0.2.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 (78) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +4 -3
  3. package/dist/agents/claude/content.js +3 -2
  4. package/dist/agents/claude/content.js.map +1 -1
  5. package/dist/cli/args.d.ts +16 -0
  6. package/dist/cli/args.js +5 -0
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/cli/help.js +30 -7
  9. package/dist/cli/help.js.map +1 -1
  10. package/dist/cli/render.d.ts +7 -1
  11. package/dist/cli/render.js +70 -13
  12. package/dist/cli/render.js.map +1 -1
  13. package/dist/cli/run.js +47 -8
  14. package/dist/cli/run.js.map +1 -1
  15. package/dist/config/schemas.d.ts +12 -1
  16. package/dist/config/schemas.js +12 -0
  17. package/dist/config/schemas.js.map +1 -1
  18. package/dist/discovery/commands.d.ts +34 -3
  19. package/dist/discovery/commands.js +109 -33
  20. package/dist/discovery/commands.js.map +1 -1
  21. package/dist/discovery/detect.d.ts +23 -0
  22. package/dist/discovery/detect.js +113 -48
  23. package/dist/discovery/detect.js.map +1 -1
  24. package/dist/discovery/docs.d.ts +10 -0
  25. package/dist/discovery/docs.js +52 -0
  26. package/dist/discovery/docs.js.map +1 -0
  27. package/dist/discovery/entrypoints.d.ts +20 -0
  28. package/dist/discovery/entrypoints.js +67 -0
  29. package/dist/discovery/entrypoints.js.map +1 -0
  30. package/dist/integrations/adapters/graphify.js +46 -8
  31. package/dist/integrations/adapters/graphify.js.map +1 -1
  32. package/dist/integrations/manager.js +14 -1
  33. package/dist/integrations/manager.js.map +1 -1
  34. package/dist/integrations/persistentPath.d.ts +20 -0
  35. package/dist/integrations/persistentPath.js +47 -0
  36. package/dist/integrations/persistentPath.js.map +1 -0
  37. package/dist/integrations/types.d.ts +6 -0
  38. package/dist/integrations/types.js.map +1 -1
  39. package/dist/knowledge/facts.d.ts +59 -2
  40. package/dist/knowledge/facts.js +115 -17
  41. package/dist/knowledge/facts.js.map +1 -1
  42. package/dist/prompts/onboarding.js +9 -6
  43. package/dist/prompts/onboarding.js.map +1 -1
  44. package/dist/services/analysis.d.ts +13 -1
  45. package/dist/services/analysis.js +23 -18
  46. package/dist/services/analysis.js.map +1 -1
  47. package/dist/services/doctor.js +92 -7
  48. package/dist/services/doctor.js.map +1 -1
  49. package/dist/services/knowledge.d.ts +17 -0
  50. package/dist/services/knowledge.js +28 -2
  51. package/dist/services/knowledge.js.map +1 -1
  52. package/dist/services/refresh.js +6 -6
  53. package/dist/services/refresh.js.map +1 -1
  54. package/dist/services/status.d.ts +12 -2
  55. package/dist/services/status.js +11 -9
  56. package/dist/services/status.js.map +1 -1
  57. package/dist/services/tasks.d.ts +2 -0
  58. package/dist/services/tasks.js +20 -12
  59. package/dist/services/tasks.js.map +1 -1
  60. package/dist/services/verify.d.ts +47 -0
  61. package/dist/services/verify.js +172 -0
  62. package/dist/services/verify.js.map +1 -0
  63. package/dist/tasks/routing.js +8 -3
  64. package/dist/tasks/routing.js.map +1 -1
  65. package/dist/tasks/task.d.ts +49 -5
  66. package/dist/tasks/task.js +68 -11
  67. package/dist/tasks/task.js.map +1 -1
  68. package/dist/verification/safety.d.ts +38 -0
  69. package/dist/verification/safety.js +120 -0
  70. package/dist/verification/safety.js.map +1 -0
  71. package/dist/verification/scope.d.ts +19 -0
  72. package/dist/verification/scope.js +119 -0
  73. package/dist/verification/scope.js.map +1 -0
  74. package/docs/integrations.md +1 -1
  75. package/docs/knowledge.md +2 -0
  76. package/docs/testing.md +29 -2
  77. package/docs/troubleshooting.md +4 -1
  78. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoints.js","sourceRoot":"","sources":["../../src/discovery/entrypoints.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport type { PackageInfo } from './detect.js';\n\nexport type EntryKind = 'server' | 'worker' | 'main' | 'cli';\n\nexport interface EntryPoint {\n /** Path relative to the package directory (POSIX). */\n path: string;\n /** The package directory relative to the project root; \".\" for the root package. */\n cwd: string;\n kind: EntryKind;\n /** Where the evidence came from, e.g. `backend/package.json#scripts.dev`. */\n evidence: string;\n}\n\n/** Script names that start a long-running process. Everything else (build, test, db:migrate, ...) is not an entry point. */\nconst RUN_SCRIPT = /^(?:dev|start|serve|server|watch|worker|workers|queue|consumer)(?::.+)?$/;\nconst WORKER_HINT = /worker|queue|consumer/i;\nconst FILE_TOKEN = /(?:^|[\\s\"'=;&|])((?:\\.{1,2}\\/)?[\\w@./-]+\\.(?:[cm]?[jt]s|[jt]sx))(?=$|[\\s\"';&|])/g;\nconst NOT_AN_ENTRY = /\\.(?:config|test|spec|d)\\.[cm]?[jt]s$|(^|\\/)(?:node_modules|dist|build)\\//;\nconst OUTPUT_DIR = /^(?:\\.\\/)?(?:dist|build|out|lib)\\//;\nconst SOURCE_EXT = ['.ts', '.tsx', '.mts', '.cts', '.js', '.mjs', '.cjs', '.jsx'];\n\nfunction resolveIn(files: Set<string>, dir: string, token: string): string | null {\n const rel = (p: string): string => path.posix.normalize(dir ? `${dir}/${p}` : p);\n const direct = rel(token.replace(/^\\.\\//, ''));\n if (!OUTPUT_DIR.test(token) && files.has(direct)) return direct;\n if (OUTPUT_DIR.test(token)) {\n // `node dist/app/server.js` runs the compiled form of src/app/server.ts\n const stem = token.replace(OUTPUT_DIR, '').replace(/\\.[cm]?js$/, '');\n for (const ext of SOURCE_EXT) {\n const candidate = rel(`src/${stem}${ext}`);\n if (files.has(candidate)) return candidate;\n }\n }\n return null;\n}\n\n/**\n * Entry points that a package itself declares: files named by its start-like scripts, its `main` and its `bin`.\n * A file is never an entry point just because it is called server.ts, worker.ts or index.ts.\n */\nexport function discoverEntryPoints(packages: { dir: string; pkg: PackageInfo; manifest: string }[], files: Set<string>): EntryPoint[] {\n const found = new Map<string, EntryPoint>();\n const add = (dir: string, projectRel: string, kind: EntryKind, evidence: string): void => {\n const rel = dir ? projectRel.slice(dir.length + 1) : projectRel;\n const key = `${dir}\\u0000${rel}`;\n const prev = found.get(key);\n // A worker script wins over a generic server label for the same file.\n if (!prev || (kind === 'worker' && prev.kind !== 'worker')) found.set(key, { path: rel, cwd: dir || '.', kind, evidence });\n };\n\n for (const { dir, pkg, manifest } of packages) {\n for (const [name, body] of Object.entries(pkg.scripts)) {\n if (!RUN_SCRIPT.test(name)) continue;\n for (const m of body.matchAll(FILE_TOKEN)) {\n const token = m[1]!;\n if (token.startsWith('-') || NOT_AN_ENTRY.test(token.replace(OUTPUT_DIR, 'x/'))) continue;\n const hit = resolveIn(files, dir, token);\n if (!hit) continue;\n add(dir, hit, WORKER_HINT.test(name) || WORKER_HINT.test(path.posix.basename(hit)) ? 'worker' : 'server', `${manifest}#scripts.${name}`);\n }\n }\n if (pkg.main) {\n const hit = resolveIn(files, dir, pkg.main);\n if (hit && !NOT_AN_ENTRY.test(hit)) add(dir, hit, 'main', `${manifest}#main`);\n }\n for (const bin of pkg.bin ?? []) {\n const hit = resolveIn(files, dir, bin);\n if (hit && !NOT_AN_ENTRY.test(hit)) add(dir, hit, 'cli', `${manifest}#bin`);\n }\n }\n const order: Record<EntryKind, number> = { server: 0, worker: 1, main: 2, cli: 3 };\n return [...found.values()].sort((a, b) => a.cwd.localeCompare(b.cwd) || order[a.kind] - order[b.kind] || a.path.localeCompare(b.path)).slice(0, 60);\n}\n"]}
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { compareVersions, findPython, findTool } from '../exec.js';
4
4
  import { GRAPHIFY_NOTICE, writeThirdPartyNotice } from '../notices.js';
5
5
  import { pathExists } from '../../utils/fs.js';
6
+ import { persistentPathHas } from '../persistentPath.js';
6
7
  /**
7
8
  * Graphify. Verified against the published package (graphifyy 0.9.82) and its CLI help on 2026-10-09:
8
9
  * - PyPI package `graphifyy`, executable `graphify`; README documents pip and pipx (pipx recommended on Windows)
@@ -12,7 +13,6 @@ import { pathExists } from '../../utils/fs.js';
12
13
  * It merges and is idempotent, but it does change files the user owns, so every run is snapshotted and verified.
13
14
  * uv is not mentioned in the README; `uv tool install` is used because it is the equivalent of pipx for console tools.
14
15
  */
15
- const EXE = process.platform === 'win32' ? 'graphify.exe' : 'graphify';
16
16
  const MIN_PYTHON = '3.10.0';
17
17
  async function exists(p) {
18
18
  return pathExists(p);
@@ -25,7 +25,7 @@ async function locate(ctx, deep) {
25
25
  if (deep)
26
26
  dirs.push(...(await toolBinDirs(ctx)));
27
27
  for (const d of dirs) {
28
- const candidate = path.join(d, ctx.platform === 'win32' ? 'graphify.exe' : EXE);
28
+ const candidate = path.join(d, ctx.platform === 'win32' ? 'graphify.exe' : 'graphify');
29
29
  if (await exists(candidate))
30
30
  return { path: candidate, onPath: false };
31
31
  }
@@ -69,6 +69,35 @@ function pathAdvice(ctx, dir) {
69
69
  ? [`${where} (Settings > System > About > Advanced system settings > Environment Variables), or run \`pipx ensurepath\` / \`uv tool update-shell\`, then open a new terminal.`]
70
70
  : [`${where}, or run \`pipx ensurepath\` / \`uv tool update-shell\`, then open a new terminal.`];
71
71
  }
72
+ /**
73
+ * Why is graphify not on this process's PATH? On Windows the registry tells us whether the folder is already on the
74
+ * persistent PATH (then a restart is the fix and adding it again would be wrong advice) or genuinely missing from it.
75
+ * Elsewhere, or when the registry cannot be read, the persistent PATH is unknown and the general advice is kept.
76
+ * Only called for deep inspections; quick checks never spawn a process.
77
+ */
78
+ async function diagnoseMissingPath(ctx, dir) {
79
+ const persistent = await ctx.persistentPath();
80
+ const where = persistent ? persistentPathHas(persistent, dir) : null;
81
+ if (persistent && where) {
82
+ return {
83
+ staleSession: true,
84
+ explanation: `graphify is on your ${where} PATH (${dir}), but this terminal or editor started before that was set, so processes launched from it (including Claude Code hooks) still cannot find it.`,
85
+ nextSteps: ['Close and reopen your terminal, or restart VS Code (and Claude Code), so it inherits the updated PATH. No change to PATH is needed. Then run: devworkspace doctor'],
86
+ };
87
+ }
88
+ if (persistent) {
89
+ return {
90
+ staleSession: false,
91
+ explanation: `graphify is not on your PATH: ${dir} is missing from this terminal's PATH and from your persistent user and machine PATH.`,
92
+ nextSteps: pathAdvice(ctx, dir),
93
+ };
94
+ }
95
+ return {
96
+ staleSession: false,
97
+ explanation: 'graphify is not on this terminal\'s PATH.',
98
+ nextSteps: [...pathAdvice(ctx, dir), 'If you already added it, restart the terminal or editor so it picks up the change.'],
99
+ };
100
+ }
72
101
  export const graphify = {
73
102
  id: 'graphify',
74
103
  name: 'Graphify',
@@ -131,13 +160,22 @@ export const graphify = {
131
160
  nextSteps.push('devworkspace integrations repair --yes');
132
161
  return { ...base, status: 'DEGRADED', variant: 'cli + stale project skill', scope, version, warnings, nextSteps };
133
162
  }
134
- if (hooks && !loc.onPath) {
135
- warnings.push('Claude Code hooks call `graphify` by name, but it is not on PATH in this terminal, so the hooks would fail.');
136
- nextSteps.push(...pathAdvice(ctx, loc.path ? path.dirname(loc.path) : null));
137
- return { ...base, status: 'DEGRADED', variant: 'cli + project skill (PATH missing)', scope, version, warnings, nextSteps };
163
+ if (!loc.onPath) {
164
+ const dir = path.dirname(loc.path);
165
+ // Only a deep inspection may ask the registry; a quick check keeps the general advice.
166
+ const diag = deep
167
+ ? await diagnoseMissingPath(ctx, dir)
168
+ : { staleSession: false, explanation: 'graphify is not on this terminal\'s PATH.', nextSteps: pathAdvice(ctx, dir) };
169
+ if (hooks) {
170
+ warnings.push(`Claude Code hooks call \`graphify\` by name, so they fail until it is found. ${diag.explanation}`);
171
+ nextSteps.push(...diag.nextSteps);
172
+ return diag.staleSession
173
+ ? { ...base, status: 'RESTART_REQUIRED', variant: 'cli + project skill (restart terminal)', scope, version, warnings, nextSteps }
174
+ : { ...base, status: 'DEGRADED', variant: 'cli + project skill (PATH missing)', scope, version, warnings, nextSteps };
175
+ }
176
+ warnings.push(diag.explanation);
177
+ nextSteps.push(...diag.nextSteps);
138
178
  }
139
- if (!loc.onPath)
140
- warnings.push(`graphify is installed but not on PATH. ${pathAdvice(ctx, path.dirname(loc.path))[0]}`);
141
179
  return { ...base, status: deep ? 'VERIFIED' : 'INSTALLED', variant: 'cli + project skill', scope, version, warnings, nextSteps };
142
180
  },
143
181
  async plan(ctx, report) {
@@ -1 +1 @@
1
- {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../../src/integrations/adapters/graphify.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { compareVersions, findPython, findTool } from '../exec.js';\nimport { GRAPHIFY_NOTICE, writeThirdPartyNotice } from '../notices.js';\nimport type { AdapterContext, Check, IntegrationAdapter, IntegrationReport, PlanResult, PlanStep, StepOutcome } from '../types.js';\nimport { pathExists } from '../../utils/fs.js';\n\n/**\n * Graphify. Verified against the published package (graphifyy 0.9.82) and its CLI help on 2026-10-09:\n * - PyPI package `graphifyy`, executable `graphify`; README documents pip and pipx (pipx recommended on Windows)\n * - `graphify --version` prints \"graphify <version>\"\n * - `graphify install --project` writes .claude/skills/graphify/, appends a graphify section to CLAUDE.md,\n * creates .claude/CLAUDE.md and registers PreToolUse hooks (`graphify hook-guard ...`) in .claude/settings.json.\n * It merges and is idempotent, but it does change files the user owns, so every run is snapshotted and verified.\n * uv is not mentioned in the README; `uv tool install` is used because it is the equivalent of pipx for console tools.\n */\n\nconst EXE = process.platform === 'win32' ? 'graphify.exe' : 'graphify';\nconst MIN_PYTHON = '3.10.0';\n\ninterface Located {\n path: string | null;\n onPath: boolean;\n}\n\nasync function exists(p: string): Promise<boolean> {\n return pathExists(p);\n}\n\nasync function locate(ctx: AdapterContext, deep: boolean): Promise<Located> {\n const onPath = await ctx.runner.which('graphify');\n if (onPath) return { path: onPath, onPath: true };\n const dirs = [path.join(ctx.home, '.local', 'bin')];\n if (deep) dirs.push(...(await toolBinDirs(ctx)));\n for (const d of dirs) {\n const candidate = path.join(d, ctx.platform === 'win32' ? 'graphify.exe' : EXE);\n if (await exists(candidate)) return { path: candidate, onPath: false };\n }\n return { path: null, onPath: false };\n}\n\n/** Where uv, pipx and `pip --user` put console scripts, asked from the tools themselves (they differ by OS and version). */\nasync function toolBinDirs(ctx: AdapterContext): Promise<string[]> {\n const out: string[] = [];\n const uv = await findTool(ctx.runner, 'uv', ctx.signal);\n if (uv) {\n const r = await ctx.runner.run({ command: uv.command, args: ['tool', 'dir', '--bin'], timeoutMs: 10_000, signal: ctx.signal });\n if (r.ok && r.stdout.trim()) out.push(r.stdout.trim().split(/\\r?\\n/)[0]!);\n }\n const pipx = await findTool(ctx.runner, 'pipx', ctx.signal);\n if (pipx) {\n const r = await ctx.runner.run({ command: pipx.command, args: ['environment', '--value', 'PIPX_BIN_DIR'], timeoutMs: 10_000, signal: ctx.signal });\n if (r.ok && r.stdout.trim()) out.push(r.stdout.trim().split(/\\r?\\n/)[0]!);\n }\n const py = await findPython(ctx.runner, ctx.platform, ctx.signal);\n if (py) {\n const code = \"import sysconfig,os;print(sysconfig.get_path('scripts', os.name + '_user'))\";\n const r = await ctx.runner.run({ command: py.command, args: [...py.args, '-c', code], timeoutMs: 10_000, signal: ctx.signal });\n if (r.ok && r.stdout.trim()) out.push(r.stdout.trim().split(/\\r?\\n/)[0]!);\n }\n return out;\n}\n\nasync function readText(p: string): Promise<string | null> {\n try {\n return await fs.readFile(p, 'utf8');\n } catch {\n return null;\n }\n}\n\nfunction pathAdvice(ctx: AdapterContext, dir: string | null): string[] {\n const where = dir ? `Add ${dir} to your PATH` : 'Add the folder containing graphify to your PATH';\n return ctx.platform === 'win32'\n ? [`${where} (Settings > System > About > Advanced system settings > Environment Variables), or run \\`pipx ensurepath\\` / \\`uv tool update-shell\\`, then open a new terminal.`]\n : [`${where}, or run \\`pipx ensurepath\\` / \\`uv tool update-shell\\`, then open a new terminal.`];\n}\n\nexport const graphify: IntegrationAdapter = {\n id: 'graphify',\n name: 'Graphify',\n required: true,\n docsUrl: 'https://github.com/Graphify-Labs/graphify',\n usage:\n 'For \"where is X / what depends on Y\" questions, query the Graphify graph first (graphify query \"<question>\", graphify path \"<A>\" \"<B>\", graphify explain \"<concept>\") ' +\n 'or use the /graphify skill. The graph is a navigation aid, not a source of truth: confirm in the actual files before relying on it. After editing code, `graphify update .` refreshes it (no LLM cost).',\n\n async inspect(ctx, deep): Promise<IntegrationReport> {\n const loc = await locate(ctx, deep);\n const projectSkill = await exists(path.join(ctx.root, '.claude', 'skills', 'graphify', 'SKILL.md'));\n const userSkill = !projectSkill && (await exists(path.join(ctx.home, '.claude', 'skills', 'graphify', 'SKILL.md')));\n const settings = (await readText(path.join(ctx.root, '.claude', 'settings.json'))) ?? '';\n const hooks = /graphify\\s+hook-guard/.test(settings);\n const graph = await exists(path.join(ctx.root, 'graphify-out', 'graph.json'));\n const skillVersion = ((await readText(path.join(ctx.root, '.claude', 'skills', 'graphify', '.graphify_version'))) ?? '').trim() || null;\n\n let version: string | null = null;\n let runnable: boolean | null = null;\n if (deep && loc.path) {\n const r = await ctx.runner.run({ command: loc.path, args: ['--version'], timeoutMs: 15_000, signal: ctx.signal });\n const m = /graphify\\s+(\\S+)/i.exec(r.stdout);\n runnable = r.ok && !!m;\n version = m?.[1] ?? null;\n }\n\n const checks: Check[] = [\n { name: 'graphify executable', ok: !!loc.path, detail: loc.path ? (loc.onPath ? 'on PATH' : 'found, but not on PATH') : 'not found' },\n ];\n if (deep && loc.path) checks.push({ name: 'graphify --version', ok: !!runnable, detail: version ? `graphify ${version}` : 'did not run' });\n checks.push({ name: 'Claude skill', ok: projectSkill || userSkill, detail: projectSkill ? 'project (.claude/skills/graphify)' : userSkill ? 'user (~/.claude/skills/graphify)' : 'missing' });\n if (projectSkill && version && skillVersion) checks.push({ name: 'skill matches CLI version', ok: skillVersion === version, detail: `skill ${skillVersion}, CLI ${version}` });\n const capabilities = { cli: !!loc.path, skill: projectSkill || userSkill, hooks, graphBuilt: graph };\n const warnings: string[] = [];\n const nextSteps: string[] = [];\n if (!graph) warnings.push('No graph built yet. In Claude Code run `/graphify .` (graph building uses the model, so DevWorkspace does not do it).');\n\n const base = { id: 'graphify', name: 'Graphify', required: true, deep, capabilities, checks } as const;\n const scope = projectSkill ? 'project' : userSkill ? 'user' : null;\n\n if (!loc.path && !projectSkill && !userSkill) {\n nextSteps.push('devworkspace setup --integrations --yes');\n return { ...base, status: 'NOT_INSTALLED', variant: null, scope: null, version: null, warnings, nextSteps };\n }\n if (!loc.path) {\n warnings.push('The Claude skill/hooks exist but the graphify command is missing, so they cannot work.');\n nextSteps.push('devworkspace integrations repair --yes');\n return { ...base, status: 'DEGRADED', variant: 'project skill without CLI', scope, version: null, warnings, nextSteps };\n }\n if (deep && runnable === false) {\n warnings.push('The graphify executable was found but `graphify --version` failed.');\n nextSteps.push('devworkspace integrations repair --yes');\n return { ...base, status: 'DEGRADED', variant: 'cli (not runnable)', scope, version, warnings, nextSteps };\n }\n if (!projectSkill && !userSkill) {\n warnings.push('The graphify CLI is installed but its Claude skill is not set up for this project.');\n nextSteps.push('devworkspace setup --integrations --yes (runs `graphify install --project`)');\n return { ...base, status: 'DEGRADED', variant: 'cli without project skill', scope: null, version, warnings, nextSteps };\n }\n if (version && skillVersion && compareVersions(version.replace(/[^0-9.]/g, '') || '0.0.0', skillVersion.replace(/[^0-9.]/g, '') || '0.0.0') !== 0) {\n warnings.push(`The project skill is from graphify ${skillVersion} but the CLI is ${version}.`);\n nextSteps.push('devworkspace integrations repair --yes');\n return { ...base, status: 'DEGRADED', variant: 'cli + stale project skill', scope, version, warnings, nextSteps };\n }\n if (hooks && !loc.onPath) {\n warnings.push('Claude Code hooks call `graphify` by name, but it is not on PATH in this terminal, so the hooks would fail.');\n nextSteps.push(...pathAdvice(ctx, loc.path ? path.dirname(loc.path) : null));\n return { ...base, status: 'DEGRADED', variant: 'cli + project skill (PATH missing)', scope, version, warnings, nextSteps };\n }\n if (!loc.onPath) warnings.push(`graphify is installed but not on PATH. ${pathAdvice(ctx, path.dirname(loc.path))[0]}`);\n return { ...base, status: deep ? 'VERIFIED' : 'INSTALLED', variant: 'cli + project skill', scope, version, warnings, nextSteps };\n },\n\n async plan(ctx, report): Promise<PlanResult> {\n const protectPaths = ['CLAUDE.md', '.claude/CLAUDE.md', '.claude/settings.json', '.claude/settings.local.json', 'AGENTS.md'];\n const blockers: string[] = [];\n const notes: string[] = [];\n const steps: PlanStep[] = [];\n if (report.status === 'VERIFIED' && !ctx.setup.repair) return { steps, blockers, protectPaths, notes: ['already verified'] };\n\n const loc = await locate(ctx, true);\n const exeRef: { path: string | null } = { path: loc.path };\n const scope = ctx.setup.scope;\n\n if (!loc.path) {\n const uv = await findTool(ctx.runner, 'uv', ctx.signal);\n const pipx = await findTool(ctx.runner, 'pipx', ctx.signal);\n const py = await findPython(ctx.runner, ctx.platform, ctx.signal);\n const pyOk = !!py && compareVersions(py.version, MIN_PYTHON) >= 0;\n const choice: { command: string[]; how: string } | null = uv\n ? { command: [uv.command, 'tool', 'install', 'graphifyy'], how: 'uv tool install' }\n : pipx\n ? { command: [pipx.command, 'install', 'graphifyy'], how: 'pipx install' }\n : pyOk && py\n ? { command: [py.command, ...py.args, '-m', 'pip', 'install', '--user', 'graphifyy'], how: 'pip install --user' }\n : null;\n if (choice && !uv && !pipx) notes.push('uv and pipx were not found; falling back to the documented `pip install --user` (no administrator rights needed).');\n if (!choice) {\n if (py && !pyOk) blockers.push(`Python ${py.version} is too old; graphify needs Python 3.10 or newer.`);\n blockers.push(\n 'No installer found. Graphify is a Python tool: install ONE of these, then re-run setup (nothing else is required):',\n ctx.platform === 'win32'\n ? ' - uv: winget install --id astral-sh.uv (or https://docs.astral.sh/uv/getting-started/installation/)'\n : ' - uv: https://docs.astral.sh/uv/getting-started/installation/',\n ' - Python 3.10+ from https://www.python.org/downloads/ (the Microsoft Store \"python\" shortcut on Windows is not a real install)',\n ' - pipx: https://pipx.pypa.io/stable/installation/',\n );\n return { steps, blockers, protectPaths, notes };\n }\n const { command, how } = choice;\n const [cmd, ...args] = command;\n steps.push({\n id: 'graphify:tool',\n description: `Install the graphifyy package for your user account (${how}; no administrator rights, nothing system-wide)`,\n command: command.map((c, i) => (i === 0 ? path.basename(c, path.extname(c)) : c)).join(' '),\n level: 'machine',\n async run(): Promise<StepOutcome> {\n const r = await ctx.runner.run({ command: cmd!, args, cwd: ctx.root, timeoutMs: 600_000, signal: ctx.signal });\n if (r.aborted) return { ok: false, detail: 'cancelled' };\n if (r.timedOut) return { ok: false, detail: 'timed out after 10 minutes (network?)' };\n if (!r.ok) {\n const text = `${r.stderr}\\n${r.stdout}`;\n if (/externally[- ]managed/i.test(text)) return { ok: false, detail: 'pip refuses to install into this Python (externally-managed environment). Install pipx or uv instead, then re-run.' };\n if (/permission denied|access is denied|EACCES|WinError 5/i.test(text)) return { ok: false, detail: 'permission denied while installing. Run the command yourself from a terminal with the right permissions.' };\n const tail = text.split(/\\r?\\n/).map((l) => l.trim()).filter(Boolean).slice(-3).join(' ');\n return { ok: false, detail: (tail || r.error || `exit ${r.code}`).slice(0, 400) };\n }\n const found = await locate(ctx, true);\n if (!found.path) return { ok: false, detail: 'graphifyy was installed but the graphify executable could not be located. Check the Scripts/bin folder of your Python tool.' };\n exeRef.path = found.path;\n return { ok: true, detail: found.onPath ? 'installed' : 'installed (not on PATH in this terminal)' };\n },\n });\n }\n\n steps.push({\n id: 'graphify:project-skill',\n description:\n scope === 'user'\n ? 'Install the Graphify skill for your user account (graphify install)'\n : 'Install the Graphify project skill (graphify install --project): adds .claude/skills/graphify/, appends a graphify section to CLAUDE.md and registers Claude Code hooks in .claude/settings.json (existing content is preserved and verified)',\n command: scope === 'user' ? 'graphify install' : 'graphify install --project',\n level: scope === 'user' ? 'user-config' : 'project',\n async run(): Promise<StepOutcome> {\n if (!exeRef.path) return { ok: false, detail: 'the graphify executable is not available' };\n const r = await ctx.runner.run({ command: exeRef.path, args: scope === 'user' ? ['install'] : ['install', '--project'], cwd: ctx.root, timeoutMs: 120_000, signal: ctx.signal });\n if (r.aborted) return { ok: false, detail: 'cancelled' };\n if (r.timedOut) return { ok: false, detail: 'timed out after 120 s' };\n if (!r.ok) {\n const tail = `${r.stderr}\\n${r.stdout}`.split(/\\r?\\n/).map((l) => l.trim()).filter(Boolean).slice(-3).join(' ');\n return { ok: false, detail: (tail || r.error || `exit ${r.code}`).slice(0, 400) };\n }\n return { ok: true, detail: 'project skill installed', restartRequired: true, managedPaths: scope === 'user' ? [] : ['.claude/skills/graphify'] };\n },\n });\n steps.push({\n id: 'graphify:notice',\n description: 'Record attribution in .devworkspace/THIRD_PARTY_NOTICES.md',\n level: 'project',\n async run(): Promise<StepOutcome> {\n await writeThirdPartyNotice(ctx.root, GRAPHIFY_NOTICE);\n return { ok: true };\n },\n });\n return { steps, blockers, protectPaths, notes };\n },\n};\n"]}
1
+ {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../../src/integrations/adapters/graphify.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { compareVersions, findPython, findTool } from '../exec.js';\nimport { GRAPHIFY_NOTICE, writeThirdPartyNotice } from '../notices.js';\nimport type { AdapterContext, Check, IntegrationAdapter, IntegrationReport, PlanResult, PlanStep, StepOutcome } from '../types.js';\nimport { pathExists } from '../../utils/fs.js';\nimport { persistentPathHas } from '../persistentPath.js';\n\n/**\n * Graphify. Verified against the published package (graphifyy 0.9.82) and its CLI help on 2026-10-09:\n * - PyPI package `graphifyy`, executable `graphify`; README documents pip and pipx (pipx recommended on Windows)\n * - `graphify --version` prints \"graphify <version>\"\n * - `graphify install --project` writes .claude/skills/graphify/, appends a graphify section to CLAUDE.md,\n * creates .claude/CLAUDE.md and registers PreToolUse hooks (`graphify hook-guard ...`) in .claude/settings.json.\n * It merges and is idempotent, but it does change files the user owns, so every run is snapshotted and verified.\n * uv is not mentioned in the README; `uv tool install` is used because it is the equivalent of pipx for console tools.\n */\n\nconst MIN_PYTHON = '3.10.0';\n\ninterface Located {\n path: string | null;\n onPath: boolean;\n}\n\nasync function exists(p: string): Promise<boolean> {\n return pathExists(p);\n}\n\nasync function locate(ctx: AdapterContext, deep: boolean): Promise<Located> {\n const onPath = await ctx.runner.which('graphify');\n if (onPath) return { path: onPath, onPath: true };\n const dirs = [path.join(ctx.home, '.local', 'bin')];\n if (deep) dirs.push(...(await toolBinDirs(ctx)));\n for (const d of dirs) {\n const candidate = path.join(d, ctx.platform === 'win32' ? 'graphify.exe' : 'graphify');\n if (await exists(candidate)) return { path: candidate, onPath: false };\n }\n return { path: null, onPath: false };\n}\n\n/** Where uv, pipx and `pip --user` put console scripts, asked from the tools themselves (they differ by OS and version). */\nasync function toolBinDirs(ctx: AdapterContext): Promise<string[]> {\n const out: string[] = [];\n const uv = await findTool(ctx.runner, 'uv', ctx.signal);\n if (uv) {\n const r = await ctx.runner.run({ command: uv.command, args: ['tool', 'dir', '--bin'], timeoutMs: 10_000, signal: ctx.signal });\n if (r.ok && r.stdout.trim()) out.push(r.stdout.trim().split(/\\r?\\n/)[0]!);\n }\n const pipx = await findTool(ctx.runner, 'pipx', ctx.signal);\n if (pipx) {\n const r = await ctx.runner.run({ command: pipx.command, args: ['environment', '--value', 'PIPX_BIN_DIR'], timeoutMs: 10_000, signal: ctx.signal });\n if (r.ok && r.stdout.trim()) out.push(r.stdout.trim().split(/\\r?\\n/)[0]!);\n }\n const py = await findPython(ctx.runner, ctx.platform, ctx.signal);\n if (py) {\n const code = \"import sysconfig,os;print(sysconfig.get_path('scripts', os.name + '_user'))\";\n const r = await ctx.runner.run({ command: py.command, args: [...py.args, '-c', code], timeoutMs: 10_000, signal: ctx.signal });\n if (r.ok && r.stdout.trim()) out.push(r.stdout.trim().split(/\\r?\\n/)[0]!);\n }\n return out;\n}\n\nasync function readText(p: string): Promise<string | null> {\n try {\n return await fs.readFile(p, 'utf8');\n } catch {\n return null;\n }\n}\n\nfunction pathAdvice(ctx: AdapterContext, dir: string | null): string[] {\n const where = dir ? `Add ${dir} to your PATH` : 'Add the folder containing graphify to your PATH';\n return ctx.platform === 'win32'\n ? [`${where} (Settings > System > About > Advanced system settings > Environment Variables), or run \\`pipx ensurepath\\` / \\`uv tool update-shell\\`, then open a new terminal.`]\n : [`${where}, or run \\`pipx ensurepath\\` / \\`uv tool update-shell\\`, then open a new terminal.`];\n}\n\ninterface PathDiagnosis {\n /** The folder is on the PATH new processes get, but this process started before that was set. */\n staleSession: boolean;\n /** Short, accurate description of the situation for the user. */\n explanation: string;\n nextSteps: string[];\n}\n\n/**\n * Why is graphify not on this process's PATH? On Windows the registry tells us whether the folder is already on the\n * persistent PATH (then a restart is the fix and adding it again would be wrong advice) or genuinely missing from it.\n * Elsewhere, or when the registry cannot be read, the persistent PATH is unknown and the general advice is kept.\n * Only called for deep inspections; quick checks never spawn a process.\n */\nasync function diagnoseMissingPath(ctx: AdapterContext, dir: string): Promise<PathDiagnosis> {\n const persistent = await ctx.persistentPath();\n const where = persistent ? persistentPathHas(persistent, dir) : null;\n if (persistent && where) {\n return {\n staleSession: true,\n explanation: `graphify is on your ${where} PATH (${dir}), but this terminal or editor started before that was set, so processes launched from it (including Claude Code hooks) still cannot find it.`,\n nextSteps: ['Close and reopen your terminal, or restart VS Code (and Claude Code), so it inherits the updated PATH. No change to PATH is needed. Then run: devworkspace doctor'],\n };\n }\n if (persistent) {\n return {\n staleSession: false,\n explanation: `graphify is not on your PATH: ${dir} is missing from this terminal's PATH and from your persistent user and machine PATH.`,\n nextSteps: pathAdvice(ctx, dir),\n };\n }\n return {\n staleSession: false,\n explanation: 'graphify is not on this terminal\\'s PATH.',\n nextSteps: [...pathAdvice(ctx, dir), 'If you already added it, restart the terminal or editor so it picks up the change.'],\n };\n}\n\nexport const graphify: IntegrationAdapter = {\n id: 'graphify',\n name: 'Graphify',\n required: true,\n docsUrl: 'https://github.com/Graphify-Labs/graphify',\n usage:\n 'For \"where is X / what depends on Y\" questions, query the Graphify graph first (graphify query \"<question>\", graphify path \"<A>\" \"<B>\", graphify explain \"<concept>\") ' +\n 'or use the /graphify skill. The graph is a navigation aid, not a source of truth: confirm in the actual files before relying on it. After editing code, `graphify update .` refreshes it (no LLM cost).',\n\n async inspect(ctx, deep): Promise<IntegrationReport> {\n const loc = await locate(ctx, deep);\n const projectSkill = await exists(path.join(ctx.root, '.claude', 'skills', 'graphify', 'SKILL.md'));\n const userSkill = !projectSkill && (await exists(path.join(ctx.home, '.claude', 'skills', 'graphify', 'SKILL.md')));\n const settings = (await readText(path.join(ctx.root, '.claude', 'settings.json'))) ?? '';\n const hooks = /graphify\\s+hook-guard/.test(settings);\n const graph = await exists(path.join(ctx.root, 'graphify-out', 'graph.json'));\n const skillVersion = ((await readText(path.join(ctx.root, '.claude', 'skills', 'graphify', '.graphify_version'))) ?? '').trim() || null;\n\n let version: string | null = null;\n let runnable: boolean | null = null;\n if (deep && loc.path) {\n const r = await ctx.runner.run({ command: loc.path, args: ['--version'], timeoutMs: 15_000, signal: ctx.signal });\n const m = /graphify\\s+(\\S+)/i.exec(r.stdout);\n runnable = r.ok && !!m;\n version = m?.[1] ?? null;\n }\n\n const checks: Check[] = [\n { name: 'graphify executable', ok: !!loc.path, detail: loc.path ? (loc.onPath ? 'on PATH' : 'found, but not on PATH') : 'not found' },\n ];\n if (deep && loc.path) checks.push({ name: 'graphify --version', ok: !!runnable, detail: version ? `graphify ${version}` : 'did not run' });\n checks.push({ name: 'Claude skill', ok: projectSkill || userSkill, detail: projectSkill ? 'project (.claude/skills/graphify)' : userSkill ? 'user (~/.claude/skills/graphify)' : 'missing' });\n if (projectSkill && version && skillVersion) checks.push({ name: 'skill matches CLI version', ok: skillVersion === version, detail: `skill ${skillVersion}, CLI ${version}` });\n const capabilities = { cli: !!loc.path, skill: projectSkill || userSkill, hooks, graphBuilt: graph };\n const warnings: string[] = [];\n const nextSteps: string[] = [];\n if (!graph) warnings.push('No graph built yet. In Claude Code run `/graphify .` (graph building uses the model, so DevWorkspace does not do it).');\n\n const base = { id: 'graphify', name: 'Graphify', required: true, deep, capabilities, checks } as const;\n const scope = projectSkill ? 'project' : userSkill ? 'user' : null;\n\n if (!loc.path && !projectSkill && !userSkill) {\n nextSteps.push('devworkspace setup --integrations --yes');\n return { ...base, status: 'NOT_INSTALLED', variant: null, scope: null, version: null, warnings, nextSteps };\n }\n if (!loc.path) {\n warnings.push('The Claude skill/hooks exist but the graphify command is missing, so they cannot work.');\n nextSteps.push('devworkspace integrations repair --yes');\n return { ...base, status: 'DEGRADED', variant: 'project skill without CLI', scope, version: null, warnings, nextSteps };\n }\n if (deep && runnable === false) {\n warnings.push('The graphify executable was found but `graphify --version` failed.');\n nextSteps.push('devworkspace integrations repair --yes');\n return { ...base, status: 'DEGRADED', variant: 'cli (not runnable)', scope, version, warnings, nextSteps };\n }\n if (!projectSkill && !userSkill) {\n warnings.push('The graphify CLI is installed but its Claude skill is not set up for this project.');\n nextSteps.push('devworkspace setup --integrations --yes (runs `graphify install --project`)');\n return { ...base, status: 'DEGRADED', variant: 'cli without project skill', scope: null, version, warnings, nextSteps };\n }\n if (version && skillVersion && compareVersions(version.replace(/[^0-9.]/g, '') || '0.0.0', skillVersion.replace(/[^0-9.]/g, '') || '0.0.0') !== 0) {\n warnings.push(`The project skill is from graphify ${skillVersion} but the CLI is ${version}.`);\n nextSteps.push('devworkspace integrations repair --yes');\n return { ...base, status: 'DEGRADED', variant: 'cli + stale project skill', scope, version, warnings, nextSteps };\n }\n if (!loc.onPath) {\n const dir = path.dirname(loc.path);\n // Only a deep inspection may ask the registry; a quick check keeps the general advice.\n const diag: PathDiagnosis = deep\n ? await diagnoseMissingPath(ctx, dir)\n : { staleSession: false, explanation: 'graphify is not on this terminal\\'s PATH.', nextSteps: pathAdvice(ctx, dir) };\n if (hooks) {\n warnings.push(`Claude Code hooks call \\`graphify\\` by name, so they fail until it is found. ${diag.explanation}`);\n nextSteps.push(...diag.nextSteps);\n return diag.staleSession\n ? { ...base, status: 'RESTART_REQUIRED', variant: 'cli + project skill (restart terminal)', scope, version, warnings, nextSteps }\n : { ...base, status: 'DEGRADED', variant: 'cli + project skill (PATH missing)', scope, version, warnings, nextSteps };\n }\n warnings.push(diag.explanation);\n nextSteps.push(...diag.nextSteps);\n }\n return { ...base, status: deep ? 'VERIFIED' : 'INSTALLED', variant: 'cli + project skill', scope, version, warnings, nextSteps };\n },\n\n async plan(ctx, report): Promise<PlanResult> {\n const protectPaths = ['CLAUDE.md', '.claude/CLAUDE.md', '.claude/settings.json', '.claude/settings.local.json', 'AGENTS.md'];\n const blockers: string[] = [];\n const notes: string[] = [];\n const steps: PlanStep[] = [];\n if (report.status === 'VERIFIED' && !ctx.setup.repair) return { steps, blockers, protectPaths, notes: ['already verified'] };\n\n const loc = await locate(ctx, true);\n const exeRef: { path: string | null } = { path: loc.path };\n const scope = ctx.setup.scope;\n\n if (!loc.path) {\n const uv = await findTool(ctx.runner, 'uv', ctx.signal);\n const pipx = await findTool(ctx.runner, 'pipx', ctx.signal);\n const py = await findPython(ctx.runner, ctx.platform, ctx.signal);\n const pyOk = !!py && compareVersions(py.version, MIN_PYTHON) >= 0;\n const choice: { command: string[]; how: string } | null = uv\n ? { command: [uv.command, 'tool', 'install', 'graphifyy'], how: 'uv tool install' }\n : pipx\n ? { command: [pipx.command, 'install', 'graphifyy'], how: 'pipx install' }\n : pyOk && py\n ? { command: [py.command, ...py.args, '-m', 'pip', 'install', '--user', 'graphifyy'], how: 'pip install --user' }\n : null;\n if (choice && !uv && !pipx) notes.push('uv and pipx were not found; falling back to the documented `pip install --user` (no administrator rights needed).');\n if (!choice) {\n if (py && !pyOk) blockers.push(`Python ${py.version} is too old; graphify needs Python 3.10 or newer.`);\n blockers.push(\n 'No installer found. Graphify is a Python tool: install ONE of these, then re-run setup (nothing else is required):',\n ctx.platform === 'win32'\n ? ' - uv: winget install --id astral-sh.uv (or https://docs.astral.sh/uv/getting-started/installation/)'\n : ' - uv: https://docs.astral.sh/uv/getting-started/installation/',\n ' - Python 3.10+ from https://www.python.org/downloads/ (the Microsoft Store \"python\" shortcut on Windows is not a real install)',\n ' - pipx: https://pipx.pypa.io/stable/installation/',\n );\n return { steps, blockers, protectPaths, notes };\n }\n const { command, how } = choice;\n const [cmd, ...args] = command;\n steps.push({\n id: 'graphify:tool',\n description: `Install the graphifyy package for your user account (${how}; no administrator rights, nothing system-wide)`,\n command: command.map((c, i) => (i === 0 ? path.basename(c, path.extname(c)) : c)).join(' '),\n level: 'machine',\n async run(): Promise<StepOutcome> {\n const r = await ctx.runner.run({ command: cmd!, args, cwd: ctx.root, timeoutMs: 600_000, signal: ctx.signal });\n if (r.aborted) return { ok: false, detail: 'cancelled' };\n if (r.timedOut) return { ok: false, detail: 'timed out after 10 minutes (network?)' };\n if (!r.ok) {\n const text = `${r.stderr}\\n${r.stdout}`;\n if (/externally[- ]managed/i.test(text)) return { ok: false, detail: 'pip refuses to install into this Python (externally-managed environment). Install pipx or uv instead, then re-run.' };\n if (/permission denied|access is denied|EACCES|WinError 5/i.test(text)) return { ok: false, detail: 'permission denied while installing. Run the command yourself from a terminal with the right permissions.' };\n const tail = text.split(/\\r?\\n/).map((l) => l.trim()).filter(Boolean).slice(-3).join(' ');\n return { ok: false, detail: (tail || r.error || `exit ${r.code}`).slice(0, 400) };\n }\n const found = await locate(ctx, true);\n if (!found.path) return { ok: false, detail: 'graphifyy was installed but the graphify executable could not be located. Check the Scripts/bin folder of your Python tool.' };\n exeRef.path = found.path;\n return { ok: true, detail: found.onPath ? 'installed' : 'installed (not on PATH in this terminal)' };\n },\n });\n }\n\n steps.push({\n id: 'graphify:project-skill',\n description:\n scope === 'user'\n ? 'Install the Graphify skill for your user account (graphify install)'\n : 'Install the Graphify project skill (graphify install --project): adds .claude/skills/graphify/, appends a graphify section to CLAUDE.md and registers Claude Code hooks in .claude/settings.json (existing content is preserved and verified)',\n command: scope === 'user' ? 'graphify install' : 'graphify install --project',\n level: scope === 'user' ? 'user-config' : 'project',\n async run(): Promise<StepOutcome> {\n if (!exeRef.path) return { ok: false, detail: 'the graphify executable is not available' };\n const r = await ctx.runner.run({ command: exeRef.path, args: scope === 'user' ? ['install'] : ['install', '--project'], cwd: ctx.root, timeoutMs: 120_000, signal: ctx.signal });\n if (r.aborted) return { ok: false, detail: 'cancelled' };\n if (r.timedOut) return { ok: false, detail: 'timed out after 120 s' };\n if (!r.ok) {\n const tail = `${r.stderr}\\n${r.stdout}`.split(/\\r?\\n/).map((l) => l.trim()).filter(Boolean).slice(-3).join(' ');\n return { ok: false, detail: (tail || r.error || `exit ${r.code}`).slice(0, 400) };\n }\n return { ok: true, detail: 'project skill installed', restartRequired: true, managedPaths: scope === 'user' ? [] : ['.claude/skills/graphify'] };\n },\n });\n steps.push({\n id: 'graphify:notice',\n description: 'Record attribution in .devworkspace/THIRD_PARTY_NOTICES.md',\n level: 'project',\n async run(): Promise<StepOutcome> {\n await writeThirdPartyNotice(ctx.root, GRAPHIFY_NOTICE);\n return { ok: true };\n },\n });\n return { steps, blockers, protectPaths, notes };\n },\n};\n"]}
@@ -8,6 +8,7 @@ import { graphify } from './adapters/graphify.js';
8
8
  import { omniroute } from './adapters/omniroute.js';
9
9
  import { ponytail } from './adapters/ponytail.js';
10
10
  import { createRunner } from './exec.js';
11
+ import { readPersistentPath } from './persistentPath.js';
11
12
  import { restoreSnapshot, takeSnapshot, verifySnapshot } from './protect.js';
12
13
  import { blankEntry, loadIntegrationsState, saveIntegrationEntry, wasInterrupted } from './state.js';
13
14
  import { REQUIRED_INTEGRATIONS, } from './types.js';
@@ -33,7 +34,19 @@ function resolveEnv(m) {
33
34
  };
34
35
  }
35
36
  function ctxFor(m, setup, prior, report, signal) {
36
- return { root: m.root, home: m.home, env: m.env, platform: m.platform, runner: m.runner, setup, prior, report, signal };
37
+ let persistent;
38
+ return {
39
+ root: m.root,
40
+ home: m.home,
41
+ env: m.env,
42
+ platform: m.platform,
43
+ runner: m.runner,
44
+ setup,
45
+ signal,
46
+ prior,
47
+ report,
48
+ persistentPath: () => (persistent ??= readPersistentPath(m.runner, m.platform, m.env, signal)),
49
+ };
37
50
  }
38
51
  const DEFAULT_SETUP = { scope: 'project', yes: false, dryRun: false, repair: false };
39
52
  /** Combine what was observed with what earlier runs recorded. Records can only add warnings or RESTART_REQUIRED, never VERIFIED. */
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/integrations/manager.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'node:os';\nimport type { Ws } from '../core/workspace.js';\nimport { onCleanup } from '../utils/cleanup.js';\nimport { withLock } from '../utils/lock.js';\nimport { redact } from '../security/redact.js';\nimport { findAbsolutePaths } from '../utils/paths.js';\nimport { agentSkills } from './adapters/agent-skills.js';\nimport { graphify } from './adapters/graphify.js';\nimport { omniroute } from './adapters/omniroute.js';\nimport { ponytail } from './adapters/ponytail.js';\nimport { createRunner } from './exec.js';\nimport { restoreSnapshot, takeSnapshot, verifySnapshot } from './protect.js';\nimport { blankEntry, loadIntegrationsState, saveIntegrationEntry, wasInterrupted } from './state.js';\nimport {\n REQUIRED_INTEGRATIONS,\n type AdapterContext,\n type IntegrationAdapter,\n type IntegrationId,\n type IntegrationReport,\n type PersistedIntegration,\n type PlanStep,\n type ProgressEvent,\n type Runner,\n type SetupOptions,\n type StatusCode,\n type StepLevel,\n} from './types.js';\n\n/** Tool output goes into reports and the state file: strip secrets and machine-specific paths, flatten to one line. */\nexport function scrub(text: string): string {\n let out = redact(text);\n for (const p of findAbsolutePaths(out)) out = out.split(p).join('<path>');\n return out.replace(/\\s+/g, ' ').trim().slice(0, 400);\n}\n\nexport const ADAPTERS: IntegrationAdapter[] = [graphify, agentSkills, ponytail, omniroute];\n\nexport interface ManagerEnv {\n root: string;\n home?: string;\n env?: NodeJS.ProcessEnv;\n platform?: NodeJS.Platform;\n runner?: Runner;\n now?: () => Date;\n adapters?: IntegrationAdapter[];\n}\n\nexport interface StepResult {\n id: string;\n description: string;\n command?: string;\n level: StepLevel;\n state: 'ok' | 'failed' | 'not-run';\n detail?: string;\n requiresApproval?: boolean;\n}\n\nexport type OutcomeAction =\n | 'already-verified'\n | 'awaiting-restart'\n | 'nothing-to-do'\n | 'blocked'\n | 'dry-run'\n | 'approval-required'\n | 'installed'\n | 'failed'\n | 'not-selected';\n\nexport interface IntegrationOutcome {\n id: IntegrationId;\n name: string;\n action: OutcomeAction;\n before: StatusCode;\n report: IntegrationReport;\n plan: { description: string; command?: string; level: StepLevel }[];\n steps: StepResult[];\n notes: string[];\n}\n\nexport interface SetupResult {\n dryRun: boolean;\n scope: SetupOptions['scope'];\n outcomes: IntegrationOutcome[];\n events: ProgressEvent[];\n /** Every requested required integration is VERIFIED. */\n complete: boolean;\n approvalRequired: boolean;\n}\n\nfunction resolveEnv(m: ManagerEnv): Required<Pick<ManagerEnv, 'root' | 'home' | 'env' | 'platform' | 'runner' | 'now' | 'adapters'>> {\n const env = m.env ?? process.env;\n const platform = m.platform ?? process.platform;\n return {\n root: m.root,\n home: m.home ?? os.homedir(),\n env,\n platform,\n runner: m.runner ?? createRunner(env, platform),\n now: m.now ?? (() => new Date()),\n adapters: m.adapters ?? ADAPTERS,\n };\n}\n\nfunction ctxFor(m: ReturnType<typeof resolveEnv>, setup: SetupOptions, prior: PersistedIntegration | undefined, report: (e: ProgressEvent) => void, signal?: AbortSignal): AdapterContext {\n return { root: m.root, home: m.home, env: m.env, platform: m.platform, runner: m.runner, setup, prior, report, signal };\n}\n\nconst DEFAULT_SETUP: SetupOptions = { scope: 'project', yes: false, dryRun: false, repair: false };\n\n/** Combine what was observed with what earlier runs recorded. Records can only add warnings or RESTART_REQUIRED, never VERIFIED. */\nexport function applyPersisted(report: IntegrationReport, entry: PersistedIntegration | undefined): IntegrationReport {\n if (!entry) return report;\n const out: IntegrationReport = { ...report, warnings: [...report.warnings], nextSteps: [...report.nextSteps] };\n if (wasInterrupted(entry)) {\n out.warnings.push('A previous setup run was interrupted before it finished.');\n if (!out.nextSteps.includes('devworkspace integrations repair --yes')) out.nextSteps.push('devworkspace integrations repair --yes');\n }\n if ((out.status === 'NOT_INSTALLED' || out.status === 'DEGRADED') && entry.lastError) {\n out.status = 'FAILED';\n out.warnings.push(`The last setup attempt failed: ${entry.lastError}`);\n }\n if (entry.restartRequiredAt && (out.status === 'VERIFIED' || out.status === 'INSTALLED')) {\n out.status = 'RESTART_REQUIRED';\n out.nextSteps.push('Restart Claude Code (or run /reload-plugins) so it loads the new skills/plugins/hooks, then run: devworkspace integrations status --restarted');\n }\n return out;\n}\n\nexport async function inspectAll(ws: Ws, mEnv: ManagerEnv, opts: { deep: boolean; onlyRequired?: boolean } = { deep: false }): Promise<IntegrationReport[]> {\n const m = resolveEnv(mEnv);\n const state = await loadIntegrationsState(ws, m.now().toISOString());\n const list = m.adapters.filter((a) => !opts.onlyRequired || a.required);\n return Promise.all(\n list.map(async (a) => {\n const ctx = ctxFor(m, DEFAULT_SETUP, state.integrations[a.id], () => undefined);\n try {\n return applyPersisted(await a.inspect(ctx, opts.deep), state.integrations[a.id]);\n } catch (e) {\n return {\n id: a.id,\n name: a.name,\n required: a.required,\n status: 'FAILED' as const,\n variant: null,\n scope: null,\n version: null,\n checks: [],\n capabilities: {},\n warnings: [`Inspection failed: ${scrub((e as Error).message)}`],\n nextSteps: ['devworkspace doctor --debug'],\n deep: opts.deep,\n };\n }\n }),\n );\n}\n\n/** Summary used by doctor/status: required integrations only; OmniRoute never counts. */\nexport function summarize(reports: IntegrationReport[]): { complete: boolean; required: number; verified: number; pending: IntegrationReport[] } {\n const required = reports.filter((r) => r.required);\n const pending = required.filter((r) => r.status !== 'VERIFIED');\n return { complete: pending.length === 0, required: required.length, verified: required.length - pending.length, pending };\n}\n\nexport async function acknowledgeRestart(ws: Ws, ids: IntegrationId[], now: string): Promise<void> {\n for (const id of ids) await saveIntegrationEntry(ws, id, { restartRequiredAt: null }, now);\n}\n\nconst describeStep = (s: PlanStep): { description: string; command?: string; level: StepLevel } => ({ description: s.description, command: s.command, level: s.level });\n\nexport async function runSetup(ws: Ws, mEnv: ManagerEnv, setup: SetupOptions, onEvent: (e: ProgressEvent) => void = () => undefined): Promise<SetupResult> {\n const m = resolveEnv(mEnv);\n const events: ProgressEvent[] = [];\n const emit = (e: ProgressEvent): void => {\n events.push(e);\n onEvent(e);\n };\n const ac = new AbortController();\n const disposeCancel = onCleanup(() => ac.abort());\n const wanted = m.adapters.filter((a) => (setup.only ? setup.only.includes(a.id) : REQUIRED_INTEGRATIONS.includes(a.id)));\n const outcomes: IntegrationOutcome[] = [];\n let approvalRequired = false;\n\n try {\n for (const adapter of wanted) {\n const nowIso = (): string => m.now().toISOString();\n const state = await loadIntegrationsState(ws, nowIso());\n const prior = state.integrations[adapter.id];\n const ctx = ctxFor(m, setup, prior, emit, ac.signal);\n emit({ id: adapter.id, step: 'inspect', state: 'start', detail: `checking ${adapter.name}` });\n const before = applyPersisted(await adapter.inspect(ctx, true), prior);\n const outcome = (action: OutcomeAction, report: IntegrationReport, extra: Partial<IntegrationOutcome> = {}): IntegrationOutcome => ({\n id: adapter.id,\n name: adapter.name,\n action,\n before: before.status,\n report,\n plan: [],\n steps: [],\n notes: [],\n ...extra,\n });\n\n if (before.status === 'VERIFIED' && !setup.repair) {\n emit({ id: adapter.id, step: 'inspect', state: 'skip', detail: 'already verified' });\n outcomes.push(outcome('already-verified', before));\n continue;\n }\n if (before.status === 'RESTART_REQUIRED' && !setup.repair) {\n emit({ id: adapter.id, step: 'inspect', state: 'skip', detail: 'installed; waiting for a Claude Code restart' });\n outcomes.push(outcome('awaiting-restart', before));\n continue;\n }\n\n const plan = await adapter.plan(ctx, before);\n if (plan.steps.length === 0) {\n if (plan.blockers.length > 0) {\n emit({ id: adapter.id, step: 'prerequisites', state: 'fail', detail: plan.blockers[0] });\n outcomes.push(outcome('blocked', { ...before, status: 'PREREQUISITES_MISSING', nextSteps: plan.blockers }, { notes: plan.notes }));\n } else {\n outcomes.push(outcome('nothing-to-do', before, { notes: plan.notes }));\n }\n continue;\n }\n const planInfo = plan.steps.map(describeStep);\n if (setup.dryRun) {\n outcomes.push(outcome('dry-run', before, { plan: planInfo, notes: plan.notes }));\n continue;\n }\n const needsConsent = plan.steps.some((s) => s.level !== 'project');\n if (needsConsent && !setup.yes) {\n approvalRequired = true;\n const levels = [...new Set(plan.steps.filter((s) => s.level !== 'project').map((s) => s.level))];\n outcomes.push(\n outcome('approval-required', { ...before, nextSteps: [`Re-run with --yes to approve: ${levels.join(', ')} step(s). Review them first with --dry-run.`, ...before.nextSteps] }, { plan: planInfo, notes: plan.notes }),\n );\n continue;\n }\n\n // ---- execute ----\n const results: StepResult[] = plan.steps.map((s) => ({ id: s.id, description: s.description, command: s.command, level: s.level, state: 'not-run' as const }));\n const managedPrior = prior?.managedPaths ?? [];\n const isManaged = (rel: string): boolean => managedPrior.some((p) => rel === p || rel.startsWith(`${p}/`));\n const managedNew = new Set<string>(managedPrior);\n let restartRequired = false;\n let failure: string | null = null;\n const hints: string[] = [];\n\n await withLock(\n ws.dir,\n async () => {\n await saveIntegrationEntry(ws, adapter.id, { installing: { pid: process.pid, startedAt: nowIso(), step: plan.steps[0]!.id }, lastAttemptAt: nowIso() }, nowIso());\n const snap = await takeSnapshot(m.root, plan.protectPaths, ['.claude/skills'], isManaged);\n for (let i = 0; i < plan.steps.length && !failure; i++) {\n const step = plan.steps[i]!;\n if (ac.signal.aborted) {\n failure = 'cancelled';\n break;\n }\n emit({ id: adapter.id, step: step.id, state: 'start', detail: step.description });\n let out;\n try {\n out = await step.run();\n } catch (e) {\n out = { ok: false, detail: (e as Error).message };\n }\n const violations = await verifySnapshot(snap);\n if (violations.length > 0) {\n await restoreSnapshot(snap, violations);\n out = { ok: false, detail: `Refused: this step would have overwritten your files (${violations.map((v) => `${v.path}: ${v.reason}`).join('; ')}). They were restored.` };\n }\n const res = results[i]!;\n res.state = out.ok ? 'ok' : 'failed';\n res.detail = out.detail ? scrub(out.detail) : undefined;\n if (!out.ok && out.hint) hints.push(out.hint);\n res.requiresApproval = out.requiresApproval;\n emit({ id: adapter.id, step: step.id, state: out.ok ? 'ok' : 'fail', detail: res.detail ?? step.description });\n if (out.ok) {\n if (out.restartRequired) restartRequired = true;\n for (const p of out.managedPaths ?? []) managedNew.add(p);\n } else failure = res.detail ?? 'step failed';\n }\n },\n { name: 'integrations.lock', staleMs: 30 * 60_000, timeoutMs: 10_000 },\n );\n\n const after = await adapterInspectAfter(ws, adapter, m, setup, emit, nowIso());\n await saveIntegrationEntry(\n ws,\n adapter.id,\n {\n installing: null,\n lastError: failure,\n managedPaths: [...managedNew].sort(),\n ...(restartRequired && !failure ? { restartRequiredAt: nowIso() } : {}),\n },\n nowIso(),\n );\n const finalState = (await loadIntegrationsState(ws, nowIso())).integrations[adapter.id] ?? blankEntry();\n let finalReport = applyPersisted(after, finalState);\n if (failure && finalReport.status !== 'VERIFIED') finalReport = { ...finalReport, status: 'FAILED', warnings: [...finalReport.warnings, `Setup stopped: ${failure}`] };\n if (hints.length > 0) finalReport = { ...finalReport, nextSteps: [...hints, ...finalReport.nextSteps] };\n const approvalStep = results.find((r) => r.requiresApproval);\n if (approvalStep?.command) finalReport = { ...finalReport, nextSteps: [`Run this yourself in a terminal (Claude Code needs your approval): ${approvalStep.command}`, ...finalReport.nextSteps] };\n await saveIntegrationEntry(\n ws,\n adapter.id,\n { status: finalReport.status, variant: finalReport.variant, scope: finalReport.scope, version: finalReport.version, lastVerifiedAt: finalReport.status === 'VERIFIED' ? nowIso() : null },\n nowIso(),\n );\n outcomes.push(outcome(failure ? 'failed' : 'installed', finalReport, { plan: planInfo, steps: results, notes: plan.notes }));\n }\n } finally {\n disposeCancel();\n }\n\n const required = outcomes.filter((o) => o.report.required);\n return {\n dryRun: setup.dryRun,\n scope: setup.scope,\n outcomes,\n events,\n complete: required.length > 0 && required.every((o) => o.report.status === 'VERIFIED'),\n approvalRequired,\n };\n}\n\nasync function adapterInspectAfter(ws: Ws, adapter: IntegrationAdapter, m: ReturnType<typeof resolveEnv>, setup: SetupOptions, emit: (e: ProgressEvent) => void, now: string): Promise<IntegrationReport> {\n const state = await loadIntegrationsState(ws, now);\n emit({ id: adapter.id, step: 'verify', state: 'start', detail: 'verifying the installation' });\n const report = await adapter.inspect(ctxFor(m, setup, state.integrations[adapter.id], emit), true);\n emit({ id: adapter.id, step: 'verify', state: report.status === 'VERIFIED' ? 'ok' : 'info', detail: report.status });\n return report;\n}\n"]}
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/integrations/manager.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'node:os';\nimport type { Ws } from '../core/workspace.js';\nimport { onCleanup } from '../utils/cleanup.js';\nimport { withLock } from '../utils/lock.js';\nimport { redact } from '../security/redact.js';\nimport { findAbsolutePaths } from '../utils/paths.js';\nimport { agentSkills } from './adapters/agent-skills.js';\nimport { graphify } from './adapters/graphify.js';\nimport { omniroute } from './adapters/omniroute.js';\nimport { ponytail } from './adapters/ponytail.js';\nimport { createRunner } from './exec.js';\nimport { readPersistentPath, type PersistentPath } from './persistentPath.js';\nimport { restoreSnapshot, takeSnapshot, verifySnapshot } from './protect.js';\nimport { blankEntry, loadIntegrationsState, saveIntegrationEntry, wasInterrupted } from './state.js';\nimport {\n REQUIRED_INTEGRATIONS,\n type AdapterContext,\n type IntegrationAdapter,\n type IntegrationId,\n type IntegrationReport,\n type PersistedIntegration,\n type PlanStep,\n type ProgressEvent,\n type Runner,\n type SetupOptions,\n type StatusCode,\n type StepLevel,\n} from './types.js';\n\n/** Tool output goes into reports and the state file: strip secrets and machine-specific paths, flatten to one line. */\nexport function scrub(text: string): string {\n let out = redact(text);\n for (const p of findAbsolutePaths(out)) out = out.split(p).join('<path>');\n return out.replace(/\\s+/g, ' ').trim().slice(0, 400);\n}\n\nexport const ADAPTERS: IntegrationAdapter[] = [graphify, agentSkills, ponytail, omniroute];\n\nexport interface ManagerEnv {\n root: string;\n home?: string;\n env?: NodeJS.ProcessEnv;\n platform?: NodeJS.Platform;\n runner?: Runner;\n now?: () => Date;\n adapters?: IntegrationAdapter[];\n}\n\nexport interface StepResult {\n id: string;\n description: string;\n command?: string;\n level: StepLevel;\n state: 'ok' | 'failed' | 'not-run';\n detail?: string;\n requiresApproval?: boolean;\n}\n\nexport type OutcomeAction =\n | 'already-verified'\n | 'awaiting-restart'\n | 'nothing-to-do'\n | 'blocked'\n | 'dry-run'\n | 'approval-required'\n | 'installed'\n | 'failed'\n | 'not-selected';\n\nexport interface IntegrationOutcome {\n id: IntegrationId;\n name: string;\n action: OutcomeAction;\n before: StatusCode;\n report: IntegrationReport;\n plan: { description: string; command?: string; level: StepLevel }[];\n steps: StepResult[];\n notes: string[];\n}\n\nexport interface SetupResult {\n dryRun: boolean;\n scope: SetupOptions['scope'];\n outcomes: IntegrationOutcome[];\n events: ProgressEvent[];\n /** Every requested required integration is VERIFIED. */\n complete: boolean;\n approvalRequired: boolean;\n}\n\nfunction resolveEnv(m: ManagerEnv): Required<Pick<ManagerEnv, 'root' | 'home' | 'env' | 'platform' | 'runner' | 'now' | 'adapters'>> {\n const env = m.env ?? process.env;\n const platform = m.platform ?? process.platform;\n return {\n root: m.root,\n home: m.home ?? os.homedir(),\n env,\n platform,\n runner: m.runner ?? createRunner(env, platform),\n now: m.now ?? (() => new Date()),\n adapters: m.adapters ?? ADAPTERS,\n };\n}\n\nfunction ctxFor(m: ReturnType<typeof resolveEnv>, setup: SetupOptions, prior: PersistedIntegration | undefined, report: (e: ProgressEvent) => void, signal?: AbortSignal): AdapterContext {\n let persistent: Promise<PersistentPath | null> | undefined;\n return {\n root: m.root,\n home: m.home,\n env: m.env,\n platform: m.platform,\n runner: m.runner,\n setup,\n signal,\n prior,\n report,\n persistentPath: () => (persistent ??= readPersistentPath(m.runner, m.platform, m.env, signal)),\n };\n}\n\nconst DEFAULT_SETUP: SetupOptions = { scope: 'project', yes: false, dryRun: false, repair: false };\n\n/** Combine what was observed with what earlier runs recorded. Records can only add warnings or RESTART_REQUIRED, never VERIFIED. */\nexport function applyPersisted(report: IntegrationReport, entry: PersistedIntegration | undefined): IntegrationReport {\n if (!entry) return report;\n const out: IntegrationReport = { ...report, warnings: [...report.warnings], nextSteps: [...report.nextSteps] };\n if (wasInterrupted(entry)) {\n out.warnings.push('A previous setup run was interrupted before it finished.');\n if (!out.nextSteps.includes('devworkspace integrations repair --yes')) out.nextSteps.push('devworkspace integrations repair --yes');\n }\n if ((out.status === 'NOT_INSTALLED' || out.status === 'DEGRADED') && entry.lastError) {\n out.status = 'FAILED';\n out.warnings.push(`The last setup attempt failed: ${entry.lastError}`);\n }\n if (entry.restartRequiredAt && (out.status === 'VERIFIED' || out.status === 'INSTALLED')) {\n out.status = 'RESTART_REQUIRED';\n out.nextSteps.push('Restart Claude Code (or run /reload-plugins) so it loads the new skills/plugins/hooks, then run: devworkspace integrations status --restarted');\n }\n return out;\n}\n\nexport async function inspectAll(ws: Ws, mEnv: ManagerEnv, opts: { deep: boolean; onlyRequired?: boolean } = { deep: false }): Promise<IntegrationReport[]> {\n const m = resolveEnv(mEnv);\n const state = await loadIntegrationsState(ws, m.now().toISOString());\n const list = m.adapters.filter((a) => !opts.onlyRequired || a.required);\n return Promise.all(\n list.map(async (a) => {\n const ctx = ctxFor(m, DEFAULT_SETUP, state.integrations[a.id], () => undefined);\n try {\n return applyPersisted(await a.inspect(ctx, opts.deep), state.integrations[a.id]);\n } catch (e) {\n return {\n id: a.id,\n name: a.name,\n required: a.required,\n status: 'FAILED' as const,\n variant: null,\n scope: null,\n version: null,\n checks: [],\n capabilities: {},\n warnings: [`Inspection failed: ${scrub((e as Error).message)}`],\n nextSteps: ['devworkspace doctor --debug'],\n deep: opts.deep,\n };\n }\n }),\n );\n}\n\n/** Summary used by doctor/status: required integrations only; OmniRoute never counts. */\nexport function summarize(reports: IntegrationReport[]): { complete: boolean; required: number; verified: number; pending: IntegrationReport[] } {\n const required = reports.filter((r) => r.required);\n const pending = required.filter((r) => r.status !== 'VERIFIED');\n return { complete: pending.length === 0, required: required.length, verified: required.length - pending.length, pending };\n}\n\nexport async function acknowledgeRestart(ws: Ws, ids: IntegrationId[], now: string): Promise<void> {\n for (const id of ids) await saveIntegrationEntry(ws, id, { restartRequiredAt: null }, now);\n}\n\nconst describeStep = (s: PlanStep): { description: string; command?: string; level: StepLevel } => ({ description: s.description, command: s.command, level: s.level });\n\nexport async function runSetup(ws: Ws, mEnv: ManagerEnv, setup: SetupOptions, onEvent: (e: ProgressEvent) => void = () => undefined): Promise<SetupResult> {\n const m = resolveEnv(mEnv);\n const events: ProgressEvent[] = [];\n const emit = (e: ProgressEvent): void => {\n events.push(e);\n onEvent(e);\n };\n const ac = new AbortController();\n const disposeCancel = onCleanup(() => ac.abort());\n const wanted = m.adapters.filter((a) => (setup.only ? setup.only.includes(a.id) : REQUIRED_INTEGRATIONS.includes(a.id)));\n const outcomes: IntegrationOutcome[] = [];\n let approvalRequired = false;\n\n try {\n for (const adapter of wanted) {\n const nowIso = (): string => m.now().toISOString();\n const state = await loadIntegrationsState(ws, nowIso());\n const prior = state.integrations[adapter.id];\n const ctx = ctxFor(m, setup, prior, emit, ac.signal);\n emit({ id: adapter.id, step: 'inspect', state: 'start', detail: `checking ${adapter.name}` });\n const before = applyPersisted(await adapter.inspect(ctx, true), prior);\n const outcome = (action: OutcomeAction, report: IntegrationReport, extra: Partial<IntegrationOutcome> = {}): IntegrationOutcome => ({\n id: adapter.id,\n name: adapter.name,\n action,\n before: before.status,\n report,\n plan: [],\n steps: [],\n notes: [],\n ...extra,\n });\n\n if (before.status === 'VERIFIED' && !setup.repair) {\n emit({ id: adapter.id, step: 'inspect', state: 'skip', detail: 'already verified' });\n outcomes.push(outcome('already-verified', before));\n continue;\n }\n if (before.status === 'RESTART_REQUIRED' && !setup.repair) {\n emit({ id: adapter.id, step: 'inspect', state: 'skip', detail: 'installed; waiting for a Claude Code restart' });\n outcomes.push(outcome('awaiting-restart', before));\n continue;\n }\n\n const plan = await adapter.plan(ctx, before);\n if (plan.steps.length === 0) {\n if (plan.blockers.length > 0) {\n emit({ id: adapter.id, step: 'prerequisites', state: 'fail', detail: plan.blockers[0] });\n outcomes.push(outcome('blocked', { ...before, status: 'PREREQUISITES_MISSING', nextSteps: plan.blockers }, { notes: plan.notes }));\n } else {\n outcomes.push(outcome('nothing-to-do', before, { notes: plan.notes }));\n }\n continue;\n }\n const planInfo = plan.steps.map(describeStep);\n if (setup.dryRun) {\n outcomes.push(outcome('dry-run', before, { plan: planInfo, notes: plan.notes }));\n continue;\n }\n const needsConsent = plan.steps.some((s) => s.level !== 'project');\n if (needsConsent && !setup.yes) {\n approvalRequired = true;\n const levels = [...new Set(plan.steps.filter((s) => s.level !== 'project').map((s) => s.level))];\n outcomes.push(\n outcome('approval-required', { ...before, nextSteps: [`Re-run with --yes to approve: ${levels.join(', ')} step(s). Review them first with --dry-run.`, ...before.nextSteps] }, { plan: planInfo, notes: plan.notes }),\n );\n continue;\n }\n\n // ---- execute ----\n const results: StepResult[] = plan.steps.map((s) => ({ id: s.id, description: s.description, command: s.command, level: s.level, state: 'not-run' as const }));\n const managedPrior = prior?.managedPaths ?? [];\n const isManaged = (rel: string): boolean => managedPrior.some((p) => rel === p || rel.startsWith(`${p}/`));\n const managedNew = new Set<string>(managedPrior);\n let restartRequired = false;\n let failure: string | null = null;\n const hints: string[] = [];\n\n await withLock(\n ws.dir,\n async () => {\n await saveIntegrationEntry(ws, adapter.id, { installing: { pid: process.pid, startedAt: nowIso(), step: plan.steps[0]!.id }, lastAttemptAt: nowIso() }, nowIso());\n const snap = await takeSnapshot(m.root, plan.protectPaths, ['.claude/skills'], isManaged);\n for (let i = 0; i < plan.steps.length && !failure; i++) {\n const step = plan.steps[i]!;\n if (ac.signal.aborted) {\n failure = 'cancelled';\n break;\n }\n emit({ id: adapter.id, step: step.id, state: 'start', detail: step.description });\n let out;\n try {\n out = await step.run();\n } catch (e) {\n out = { ok: false, detail: (e as Error).message };\n }\n const violations = await verifySnapshot(snap);\n if (violations.length > 0) {\n await restoreSnapshot(snap, violations);\n out = { ok: false, detail: `Refused: this step would have overwritten your files (${violations.map((v) => `${v.path}: ${v.reason}`).join('; ')}). They were restored.` };\n }\n const res = results[i]!;\n res.state = out.ok ? 'ok' : 'failed';\n res.detail = out.detail ? scrub(out.detail) : undefined;\n if (!out.ok && out.hint) hints.push(out.hint);\n res.requiresApproval = out.requiresApproval;\n emit({ id: adapter.id, step: step.id, state: out.ok ? 'ok' : 'fail', detail: res.detail ?? step.description });\n if (out.ok) {\n if (out.restartRequired) restartRequired = true;\n for (const p of out.managedPaths ?? []) managedNew.add(p);\n } else failure = res.detail ?? 'step failed';\n }\n },\n { name: 'integrations.lock', staleMs: 30 * 60_000, timeoutMs: 10_000 },\n );\n\n const after = await adapterInspectAfter(ws, adapter, m, setup, emit, nowIso());\n await saveIntegrationEntry(\n ws,\n adapter.id,\n {\n installing: null,\n lastError: failure,\n managedPaths: [...managedNew].sort(),\n ...(restartRequired && !failure ? { restartRequiredAt: nowIso() } : {}),\n },\n nowIso(),\n );\n const finalState = (await loadIntegrationsState(ws, nowIso())).integrations[adapter.id] ?? blankEntry();\n let finalReport = applyPersisted(after, finalState);\n if (failure && finalReport.status !== 'VERIFIED') finalReport = { ...finalReport, status: 'FAILED', warnings: [...finalReport.warnings, `Setup stopped: ${failure}`] };\n if (hints.length > 0) finalReport = { ...finalReport, nextSteps: [...hints, ...finalReport.nextSteps] };\n const approvalStep = results.find((r) => r.requiresApproval);\n if (approvalStep?.command) finalReport = { ...finalReport, nextSteps: [`Run this yourself in a terminal (Claude Code needs your approval): ${approvalStep.command}`, ...finalReport.nextSteps] };\n await saveIntegrationEntry(\n ws,\n adapter.id,\n { status: finalReport.status, variant: finalReport.variant, scope: finalReport.scope, version: finalReport.version, lastVerifiedAt: finalReport.status === 'VERIFIED' ? nowIso() : null },\n nowIso(),\n );\n outcomes.push(outcome(failure ? 'failed' : 'installed', finalReport, { plan: planInfo, steps: results, notes: plan.notes }));\n }\n } finally {\n disposeCancel();\n }\n\n const required = outcomes.filter((o) => o.report.required);\n return {\n dryRun: setup.dryRun,\n scope: setup.scope,\n outcomes,\n events,\n complete: required.length > 0 && required.every((o) => o.report.status === 'VERIFIED'),\n approvalRequired,\n };\n}\n\nasync function adapterInspectAfter(ws: Ws, adapter: IntegrationAdapter, m: ReturnType<typeof resolveEnv>, setup: SetupOptions, emit: (e: ProgressEvent) => void, now: string): Promise<IntegrationReport> {\n const state = await loadIntegrationsState(ws, now);\n emit({ id: adapter.id, step: 'verify', state: 'start', detail: 'verifying the installation' });\n const report = await adapter.inspect(ctxFor(m, setup, state.integrations[adapter.id], emit), true);\n emit({ id: adapter.id, step: 'verify', state: report.status === 'VERIFIED' ? 'ok' : 'info', detail: report.status });\n return report;\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import type { Runner } from './types.js';
2
+ /**
3
+ * The PATH Windows will give to NEW processes, as stored in the registry. A running terminal or editor keeps the PATH
4
+ * it started with, so it can differ from this. Read-only: nothing here ever writes to the registry or the environment.
5
+ */
6
+ export interface PersistentPath {
7
+ user: string[];
8
+ machine: string[];
9
+ }
10
+ /** Extract the value of `Path` from `reg query <key> /v Path` output. */
11
+ export declare function parseRegPath(output: string): string | null;
12
+ /** Expand %NAME% references the way Windows does (case-insensitive); unknown names are left untouched. */
13
+ export declare function expandWindowsVars(value: string, env: NodeJS.ProcessEnv): string;
14
+ export declare function splitPathList(value: string): string[];
15
+ /** Windows paths are case-insensitive and tolerate trailing separators and `.`/`..` segments. */
16
+ export declare function normalizeWindowsDir(dir: string): string;
17
+ /** Windows only. Returns null on every other platform, or when the user PATH cannot be read (unknown, not "absent"). */
18
+ export declare function readPersistentPath(runner: Runner, platform: NodeJS.Platform, env: NodeJS.ProcessEnv, signal?: AbortSignal): Promise<PersistentPath | null>;
19
+ /** Which persistent PATH (if any) lists this directory. */
20
+ export declare function persistentPathHas(pp: PersistentPath, dir: string): 'user' | 'machine' | null;
@@ -0,0 +1,47 @@
1
+ import path from 'node:path';
2
+ const USER_KEY = 'HKCU\\Environment';
3
+ const MACHINE_KEY = 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment';
4
+ /** Extract the value of `Path` from `reg query <key> /v Path` output. */
5
+ export function parseRegPath(output) {
6
+ const m = /^\s*Path\s+REG_(?:EXPAND_)?SZ\s+(.*?)\s*$/im.exec(output);
7
+ return m && m[1] !== undefined ? m[1] : null;
8
+ }
9
+ /** Expand %NAME% references the way Windows does (case-insensitive); unknown names are left untouched. */
10
+ export function expandWindowsVars(value, env) {
11
+ const lower = new Map(Object.entries(env).map(([k, v]) => [k.toLowerCase(), v ?? '']));
12
+ return value.replace(/%([^%]+)%/g, (whole, name) => lower.get(name.toLowerCase()) ?? whole);
13
+ }
14
+ export function splitPathList(value) {
15
+ return value.split(';').map((s) => s.trim().replace(/^"(.*)"$/, '$1')).filter(Boolean);
16
+ }
17
+ /** Windows paths are case-insensitive and tolerate trailing separators and `.`/`..` segments. */
18
+ export function normalizeWindowsDir(dir) {
19
+ return path.win32.normalize(dir).replace(/[\\/]+$/, '').toLowerCase();
20
+ }
21
+ async function readKey(runner, key, env, signal) {
22
+ const r = await runner.run({ command: 'reg', args: ['query', key, '/v', 'Path'], timeoutMs: 10_000, signal });
23
+ if (!r.ok)
24
+ return null;
25
+ const raw = parseRegPath(r.stdout);
26
+ return raw === null ? [] : splitPathList(expandWindowsVars(raw, env));
27
+ }
28
+ /** Windows only. Returns null on every other platform, or when the user PATH cannot be read (unknown, not "absent"). */
29
+ export async function readPersistentPath(runner, platform, env, signal) {
30
+ if (platform !== 'win32')
31
+ return null;
32
+ const user = await readKey(runner, USER_KEY, env, signal);
33
+ if (user === null)
34
+ return null;
35
+ const machine = (await readKey(runner, MACHINE_KEY, env, signal)) ?? [];
36
+ return { user, machine };
37
+ }
38
+ /** Which persistent PATH (if any) lists this directory. */
39
+ export function persistentPathHas(pp, dir) {
40
+ const want = normalizeWindowsDir(dir);
41
+ if (pp.user.some((p) => normalizeWindowsDir(p) === want))
42
+ return 'user';
43
+ if (pp.machine.some((p) => normalizeWindowsDir(p) === want))
44
+ return 'machine';
45
+ return null;
46
+ }
47
+ //# sourceMappingURL=persistentPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistentPath.js","sourceRoot":"","sources":["../../src/integrations/persistentPath.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport type { Runner } from './types.js';\n\n/**\n * The PATH Windows will give to NEW processes, as stored in the registry. A running terminal or editor keeps the PATH\n * it started with, so it can differ from this. Read-only: nothing here ever writes to the registry or the environment.\n */\nexport interface PersistentPath {\n user: string[];\n machine: string[];\n}\n\nconst USER_KEY = 'HKCU\\\\Environment';\nconst MACHINE_KEY = 'HKLM\\\\SYSTEM\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment';\n\n/** Extract the value of `Path` from `reg query <key> /v Path` output. */\nexport function parseRegPath(output: string): string | null {\n const m = /^\\s*Path\\s+REG_(?:EXPAND_)?SZ\\s+(.*?)\\s*$/im.exec(output);\n return m && m[1] !== undefined ? m[1] : null;\n}\n\n/** Expand %NAME% references the way Windows does (case-insensitive); unknown names are left untouched. */\nexport function expandWindowsVars(value: string, env: NodeJS.ProcessEnv): string {\n const lower = new Map(Object.entries(env).map(([k, v]) => [k.toLowerCase(), v ?? '']));\n return value.replace(/%([^%]+)%/g, (whole, name: string) => lower.get(name.toLowerCase()) ?? whole);\n}\n\nexport function splitPathList(value: string): string[] {\n return value.split(';').map((s) => s.trim().replace(/^\"(.*)\"$/, '$1')).filter(Boolean);\n}\n\n/** Windows paths are case-insensitive and tolerate trailing separators and `.`/`..` segments. */\nexport function normalizeWindowsDir(dir: string): string {\n return path.win32.normalize(dir).replace(/[\\\\/]+$/, '').toLowerCase();\n}\n\nasync function readKey(runner: Runner, key: string, env: NodeJS.ProcessEnv, signal?: AbortSignal): Promise<string[] | null> {\n const r = await runner.run({ command: 'reg', args: ['query', key, '/v', 'Path'], timeoutMs: 10_000, signal });\n if (!r.ok) return null;\n const raw = parseRegPath(r.stdout);\n return raw === null ? [] : splitPathList(expandWindowsVars(raw, env));\n}\n\n/** Windows only. Returns null on every other platform, or when the user PATH cannot be read (unknown, not \"absent\"). */\nexport async function readPersistentPath(runner: Runner, platform: NodeJS.Platform, env: NodeJS.ProcessEnv, signal?: AbortSignal): Promise<PersistentPath | null> {\n if (platform !== 'win32') return null;\n const user = await readKey(runner, USER_KEY, env, signal);\n if (user === null) return null;\n const machine = (await readKey(runner, MACHINE_KEY, env, signal)) ?? [];\n return { user, machine };\n}\n\n/** Which persistent PATH (if any) lists this directory. */\nexport function persistentPathHas(pp: PersistentPath, dir: string): 'user' | 'machine' | null {\n const want = normalizeWindowsDir(dir);\n if (pp.user.some((p) => normalizeWindowsDir(p) === want)) return 'user';\n if (pp.machine.some((p) => normalizeWindowsDir(p) === want)) return 'machine';\n return null;\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import type { RunResult } from '../utils/proc.js';
2
+ import type { PersistentPath } from './persistentPath.js';
2
3
  export declare const INTEGRATION_IDS: readonly ["graphify", "agent-skills", "ponytail", "omniroute"];
3
4
  export type IntegrationId = (typeof INTEGRATION_IDS)[number];
4
5
  /** Integrations that "full integration readiness" requires. OmniRoute is optional and never counted. */
@@ -102,6 +103,11 @@ export interface AdapterContext {
102
103
  runner: Runner;
103
104
  setup: SetupOptions;
104
105
  signal?: AbortSignal;
106
+ /**
107
+ * The PATH new processes will start with (Windows registry; read-only). Null where that concept does not apply
108
+ * (macOS, Linux) or cannot be read. Adapters must treat null as "unknown", never as "absent".
109
+ */
110
+ persistentPath(): Promise<PersistentPath | null>;
105
111
  /** Persisted facts from earlier runs (only trusted as hints). */
106
112
  prior: PersistedIntegration | undefined;
107
113
  report(e: ProgressEvent): void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/integrations/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AAG9F,wGAAwG;AACxG,MAAM,CAAC,MAAM,qBAAqB,GAAoB,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;AAE/F,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,eAAe;IACf,uBAAuB;IACvB,YAAY;IACZ,WAAW;IACX,UAAU;IACV,UAAU;IACV,QAAQ;IACR,kBAAkB;CACV,CAAC","sourcesContent":["import type { RunResult } from '../utils/proc.js';\n\nexport const INTEGRATION_IDS = ['graphify', 'agent-skills', 'ponytail', 'omniroute'] as const;\nexport type IntegrationId = (typeof INTEGRATION_IDS)[number];\n\n/** Integrations that \"full integration readiness\" requires. OmniRoute is optional and never counted. */\nexport const REQUIRED_INTEGRATIONS: IntegrationId[] = ['graphify', 'agent-skills', 'ponytail'];\n\nexport const STATUS_CODES = [\n 'NOT_INSTALLED',\n 'PREREQUISITES_MISSING',\n 'INSTALLING',\n 'INSTALLED',\n 'VERIFIED',\n 'DEGRADED',\n 'FAILED',\n 'RESTART_REQUIRED',\n] as const;\nexport type StatusCode = (typeof STATUS_CODES)[number];\n\nexport type InstallScope = 'project' | 'user';\n\nexport interface Check {\n name: string;\n ok: boolean;\n detail?: string;\n}\n\n/**\n * What was actually observed about an integration. `deep` reports come from running the tool and are the only\n * ones that can be VERIFIED; shallow reports only look at files and PATH and top out at INSTALLED.\n */\nexport interface IntegrationReport {\n id: IntegrationId;\n name: string;\n required: boolean;\n status: StatusCode;\n /** e.g. \"cli + project skill\", \"native plugin\", \"portable skills\" */\n variant: string | null;\n scope: InstallScope | null;\n version: string | null;\n checks: Check[];\n capabilities: Record<string, boolean>;\n warnings: string[];\n /** Exact commands or instructions that would move this integration forward. */\n nextSteps: string[];\n deep: boolean;\n}\n\n// ---------- process runner (mockable) ----------\n\nexport interface RunSpec {\n command: string;\n args: string[];\n cwd?: string;\n env?: Record<string, string | undefined>;\n timeoutMs?: number;\n signal?: AbortSignal;\n}\n\nexport interface Runner {\n run(spec: RunSpec): Promise<RunResult>;\n /** Run `npx <args>` without a shell (resolves npm's npx-cli.js next to the running Node). */\n runNpx(args: string[], spec?: Omit<RunSpec, 'command' | 'args'>): Promise<RunResult>;\n which(name: string): Promise<string | null>;\n}\n\n// ---------- setup ----------\n\nexport interface SetupOptions {\n scope: InstallScope;\n /** Consent for machine-level, user-config and third-party-code steps. Never implied. */\n yes: boolean;\n dryRun: boolean;\n /** Allow re-running install steps for DEGRADED/FAILED integrations. */\n repair: boolean;\n only?: IntegrationId[];\n}\n\n/**\n * project changes files inside the project only\n * machine installs a tool for the current user (uv/pipx/pip --user)\n * user-config changes the user's Claude Code configuration (user scope)\n * third-party-code runs a package from a registry (npx skills)\n */\nexport type StepLevel = 'project' | 'machine' | 'user-config' | 'third-party-code';\n\nexport interface StepOutcome {\n ok: boolean;\n detail?: string;\n /** The tool needs interactive approval we will not simulate. */\n requiresApproval?: boolean;\n restartRequired?: boolean;\n /** An actionable next step for the user when this step failed. */\n hint?: string;\n /** Project-relative paths this step created; recorded so repair can refresh them without touching user files. */\n managedPaths?: string[];\n}\n\nexport interface PlanStep {\n id: string;\n description: string;\n /** Human-readable command line (never executed from this string). */\n command?: string;\n level: StepLevel;\n run(): Promise<StepOutcome>;\n}\n\nexport interface PlanResult {\n steps: PlanStep[];\n /** Missing prerequisites with exact remediation; when non-empty and no steps exist, nothing can be done automatically. */\n blockers: string[];\n /** Files the steps may legitimately touch but must only extend, never overwrite. */\n protectPaths: string[];\n notes: string[];\n}\n\nexport interface ProgressEvent {\n id: IntegrationId | 'setup';\n step: string;\n state: 'start' | 'ok' | 'skip' | 'fail' | 'info';\n detail?: string;\n}\n\nexport interface AdapterContext {\n root: string;\n home: string;\n env: NodeJS.ProcessEnv;\n platform: NodeJS.Platform;\n runner: Runner;\n setup: SetupOptions;\n signal?: AbortSignal;\n /** Persisted facts from earlier runs (only trusted as hints). */\n prior: PersistedIntegration | undefined;\n report(e: ProgressEvent): void;\n}\n\nexport interface IntegrationAdapter {\n id: IntegrationId;\n name: string;\n required: boolean;\n /** Text embedded in the generated agent skill. */\n usage: string;\n docsUrl: string;\n inspect(ctx: AdapterContext, deep: boolean): Promise<IntegrationReport>;\n plan(ctx: AdapterContext, report: IntegrationReport): Promise<PlanResult>;\n}\n\n// ---------- persisted state (.devworkspace/state/integrations.json) ----------\n\nexport interface PersistedIntegration {\n status: StatusCode;\n variant: string | null;\n scope: InstallScope | null;\n version: string | null;\n lastAttemptAt: string | null;\n lastVerifiedAt: string | null;\n lastError: string | null;\n /** Set when a step finished that needs a Claude Code restart/reload; cleared by acknowledging the restart. */\n restartRequiredAt: string | null;\n /** Project-relative paths this tool created, so repair may refresh them without touching user files. */\n managedPaths: string[];\n /** Set while a setup run is in progress. A leftover value means the run was interrupted. */\n installing: { pid: number; startedAt: string; step: string } | null;\n}\n\nexport interface IntegrationsStateFile {\n schemaVersion: number;\n updatedAt: string;\n integrations: Partial<Record<IntegrationId, PersistedIntegration>>;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/integrations/types.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,CAAU,CAAC;AAG9F,wGAAwG;AACxG,MAAM,CAAC,MAAM,qBAAqB,GAAoB,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;AAE/F,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,eAAe;IACf,uBAAuB;IACvB,YAAY;IACZ,WAAW;IACX,UAAU;IACV,UAAU;IACV,QAAQ;IACR,kBAAkB;CACV,CAAC","sourcesContent":["import type { RunResult } from '../utils/proc.js';\nimport type { PersistentPath } from './persistentPath.js';\n\nexport const INTEGRATION_IDS = ['graphify', 'agent-skills', 'ponytail', 'omniroute'] as const;\nexport type IntegrationId = (typeof INTEGRATION_IDS)[number];\n\n/** Integrations that \"full integration readiness\" requires. OmniRoute is optional and never counted. */\nexport const REQUIRED_INTEGRATIONS: IntegrationId[] = ['graphify', 'agent-skills', 'ponytail'];\n\nexport const STATUS_CODES = [\n 'NOT_INSTALLED',\n 'PREREQUISITES_MISSING',\n 'INSTALLING',\n 'INSTALLED',\n 'VERIFIED',\n 'DEGRADED',\n 'FAILED',\n 'RESTART_REQUIRED',\n] as const;\nexport type StatusCode = (typeof STATUS_CODES)[number];\n\nexport type InstallScope = 'project' | 'user';\n\nexport interface Check {\n name: string;\n ok: boolean;\n detail?: string;\n}\n\n/**\n * What was actually observed about an integration. `deep` reports come from running the tool and are the only\n * ones that can be VERIFIED; shallow reports only look at files and PATH and top out at INSTALLED.\n */\nexport interface IntegrationReport {\n id: IntegrationId;\n name: string;\n required: boolean;\n status: StatusCode;\n /** e.g. \"cli + project skill\", \"native plugin\", \"portable skills\" */\n variant: string | null;\n scope: InstallScope | null;\n version: string | null;\n checks: Check[];\n capabilities: Record<string, boolean>;\n warnings: string[];\n /** Exact commands or instructions that would move this integration forward. */\n nextSteps: string[];\n deep: boolean;\n}\n\n// ---------- process runner (mockable) ----------\n\nexport interface RunSpec {\n command: string;\n args: string[];\n cwd?: string;\n env?: Record<string, string | undefined>;\n timeoutMs?: number;\n signal?: AbortSignal;\n}\n\nexport interface Runner {\n run(spec: RunSpec): Promise<RunResult>;\n /** Run `npx <args>` without a shell (resolves npm's npx-cli.js next to the running Node). */\n runNpx(args: string[], spec?: Omit<RunSpec, 'command' | 'args'>): Promise<RunResult>;\n which(name: string): Promise<string | null>;\n}\n\n// ---------- setup ----------\n\nexport interface SetupOptions {\n scope: InstallScope;\n /** Consent for machine-level, user-config and third-party-code steps. Never implied. */\n yes: boolean;\n dryRun: boolean;\n /** Allow re-running install steps for DEGRADED/FAILED integrations. */\n repair: boolean;\n only?: IntegrationId[];\n}\n\n/**\n * project changes files inside the project only\n * machine installs a tool for the current user (uv/pipx/pip --user)\n * user-config changes the user's Claude Code configuration (user scope)\n * third-party-code runs a package from a registry (npx skills)\n */\nexport type StepLevel = 'project' | 'machine' | 'user-config' | 'third-party-code';\n\nexport interface StepOutcome {\n ok: boolean;\n detail?: string;\n /** The tool needs interactive approval we will not simulate. */\n requiresApproval?: boolean;\n restartRequired?: boolean;\n /** An actionable next step for the user when this step failed. */\n hint?: string;\n /** Project-relative paths this step created; recorded so repair can refresh them without touching user files. */\n managedPaths?: string[];\n}\n\nexport interface PlanStep {\n id: string;\n description: string;\n /** Human-readable command line (never executed from this string). */\n command?: string;\n level: StepLevel;\n run(): Promise<StepOutcome>;\n}\n\nexport interface PlanResult {\n steps: PlanStep[];\n /** Missing prerequisites with exact remediation; when non-empty and no steps exist, nothing can be done automatically. */\n blockers: string[];\n /** Files the steps may legitimately touch but must only extend, never overwrite. */\n protectPaths: string[];\n notes: string[];\n}\n\nexport interface ProgressEvent {\n id: IntegrationId | 'setup';\n step: string;\n state: 'start' | 'ok' | 'skip' | 'fail' | 'info';\n detail?: string;\n}\n\nexport interface AdapterContext {\n root: string;\n home: string;\n env: NodeJS.ProcessEnv;\n platform: NodeJS.Platform;\n runner: Runner;\n setup: SetupOptions;\n signal?: AbortSignal;\n /**\n * The PATH new processes will start with (Windows registry; read-only). Null where that concept does not apply\n * (macOS, Linux) or cannot be read. Adapters must treat null as \"unknown\", never as \"absent\".\n */\n persistentPath(): Promise<PersistentPath | null>;\n /** Persisted facts from earlier runs (only trusted as hints). */\n prior: PersistedIntegration | undefined;\n report(e: ProgressEvent): void;\n}\n\nexport interface IntegrationAdapter {\n id: IntegrationId;\n name: string;\n required: boolean;\n /** Text embedded in the generated agent skill. */\n usage: string;\n docsUrl: string;\n inspect(ctx: AdapterContext, deep: boolean): Promise<IntegrationReport>;\n plan(ctx: AdapterContext, report: IntegrationReport): Promise<PlanResult>;\n}\n\n// ---------- persisted state (.devworkspace/state/integrations.json) ----------\n\nexport interface PersistedIntegration {\n status: StatusCode;\n variant: string | null;\n scope: InstallScope | null;\n version: string | null;\n lastAttemptAt: string | null;\n lastVerifiedAt: string | null;\n lastError: string | null;\n /** Set when a step finished that needs a Claude Code restart/reload; cleared by acknowledging the restart. */\n restartRequiredAt: string | null;\n /** Project-relative paths this tool created, so repair may refresh them without touching user files. */\n managedPaths: string[];\n /** Set while a setup run is in progress. A leftover value means the run was interrupted. */\n installing: { pid: number; startedAt: string; step: string } | null;\n}\n\nexport interface IntegrationsStateFile {\n schemaVersion: number;\n updatedAt: string;\n integrations: Partial<Record<IntegrationId, PersistedIntegration>>;\n}\n"]}