devworkspace 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +15 -2
  3. package/dist/agents/claude/content.js +3 -3
  4. package/dist/agents/claude/content.js.map +1 -1
  5. package/dist/cli/args.d.ts +19 -0
  6. package/dist/cli/args.js +6 -0
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/cli/help.js +40 -5
  9. package/dist/cli/help.js.map +1 -1
  10. package/dist/cli/render.d.ts +7 -0
  11. package/dist/cli/render.js +104 -17
  12. package/dist/cli/render.js.map +1 -1
  13. package/dist/cli/run.d.ts +6 -0
  14. package/dist/cli/run.js +65 -3
  15. package/dist/cli/run.js.map +1 -1
  16. package/dist/config/schemas.d.ts +7 -1
  17. package/dist/config/schemas.js +10 -0
  18. package/dist/config/schemas.js.map +1 -1
  19. package/dist/core/workspace.js +2 -1
  20. package/dist/core/workspace.js.map +1 -1
  21. package/dist/discovery/commands.d.ts +34 -3
  22. package/dist/discovery/commands.js +95 -33
  23. package/dist/discovery/commands.js.map +1 -1
  24. package/dist/discovery/detect.d.ts +17 -0
  25. package/dist/discovery/detect.js +101 -42
  26. package/dist/discovery/detect.js.map +1 -1
  27. package/dist/index.d.ts +3 -1
  28. package/dist/index.js +2 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/integrations/adapters/agent-skills.d.ts +8 -0
  31. package/dist/integrations/adapters/agent-skills.js +25 -0
  32. package/dist/integrations/adapters/agent-skills.js.map +1 -0
  33. package/dist/integrations/adapters/claudePlugin.d.ts +41 -0
  34. package/dist/integrations/adapters/claudePlugin.js +129 -0
  35. package/dist/integrations/adapters/claudePlugin.js.map +1 -0
  36. package/dist/integrations/adapters/graphify.d.ts +2 -0
  37. package/dist/integrations/adapters/graphify.js +277 -0
  38. package/dist/integrations/adapters/graphify.js.map +1 -0
  39. package/dist/integrations/adapters/omniroute.d.ts +6 -0
  40. package/dist/integrations/adapters/omniroute.js +32 -0
  41. package/dist/integrations/adapters/omniroute.js.map +1 -0
  42. package/dist/integrations/adapters/pluginSkill.d.ts +28 -0
  43. package/dist/integrations/adapters/pluginSkill.js +195 -0
  44. package/dist/integrations/adapters/pluginSkill.js.map +1 -0
  45. package/dist/integrations/adapters/ponytail.d.ts +8 -0
  46. package/dist/integrations/adapters/ponytail.js +33 -0
  47. package/dist/integrations/adapters/ponytail.js.map +1 -0
  48. package/dist/integrations/exec.d.ts +26 -0
  49. package/dist/integrations/exec.js +167 -0
  50. package/dist/integrations/exec.js.map +1 -0
  51. package/dist/integrations/index.d.ts +5 -6
  52. package/dist/integrations/index.js +3 -29
  53. package/dist/integrations/index.js.map +1 -1
  54. package/dist/integrations/manager.d.ts +62 -0
  55. package/dist/integrations/manager.js +261 -0
  56. package/dist/integrations/manager.js.map +1 -0
  57. package/dist/integrations/notices.d.ts +13 -0
  58. package/dist/integrations/notices.js +68 -0
  59. package/dist/integrations/notices.js.map +1 -0
  60. package/dist/integrations/persistentPath.d.ts +20 -0
  61. package/dist/integrations/persistentPath.js +47 -0
  62. package/dist/integrations/persistentPath.js.map +1 -0
  63. package/dist/integrations/protect.d.ts +20 -0
  64. package/dist/integrations/protect.js +131 -0
  65. package/dist/integrations/protect.js.map +1 -0
  66. package/dist/integrations/state.d.ts +10 -0
  67. package/dist/integrations/state.js +81 -0
  68. package/dist/integrations/state.js.map +1 -0
  69. package/dist/integrations/types.d.ts +139 -16
  70. package/dist/integrations/types.js +13 -1
  71. package/dist/integrations/types.js.map +1 -1
  72. package/dist/prompts/onboarding.d.ts +3 -3
  73. package/dist/prompts/onboarding.js +9 -8
  74. package/dist/prompts/onboarding.js.map +1 -1
  75. package/dist/services/analysis.d.ts +15 -3
  76. package/dist/services/analysis.js +21 -23
  77. package/dist/services/analysis.js.map +1 -1
  78. package/dist/services/common.d.ts +8 -5
  79. package/dist/services/common.js +2 -5
  80. package/dist/services/common.js.map +1 -1
  81. package/dist/services/doctor.d.ts +10 -0
  82. package/dist/services/doctor.js +87 -19
  83. package/dist/services/doctor.js.map +1 -1
  84. package/dist/services/init.d.ts +9 -2
  85. package/dist/services/init.js +10 -7
  86. package/dist/services/init.js.map +1 -1
  87. package/dist/services/integrations.d.ts +26 -0
  88. package/dist/services/integrations.js +35 -0
  89. package/dist/services/integrations.js.map +1 -0
  90. package/dist/services/refresh.js +1 -1
  91. package/dist/services/refresh.js.map +1 -1
  92. package/dist/services/status.d.ts +4 -2
  93. package/dist/services/status.js +4 -4
  94. package/dist/services/status.js.map +1 -1
  95. package/dist/utils/lock.d.ts +2 -0
  96. package/dist/utils/lock.js +2 -2
  97. package/dist/utils/lock.js.map +1 -1
  98. package/dist/utils/proc.d.ts +8 -1
  99. package/dist/utils/proc.js +31 -8
  100. package/dist/utils/proc.js.map +1 -1
  101. package/docs/architecture.md +1 -1
  102. package/docs/claude.md +4 -0
  103. package/docs/getting-started.md +2 -2
  104. package/docs/integrations.md +98 -33
  105. package/docs/security.md +5 -1
  106. package/docs/testing.md +6 -0
  107. package/docs/troubleshooting.md +11 -1
  108. package/package.json +1 -1
  109. package/dist/integrations/agent-skills.d.ts +0 -10
  110. package/dist/integrations/agent-skills.js +0 -45
  111. package/dist/integrations/agent-skills.js.map +0 -1
  112. package/dist/integrations/graphify.d.ts +0 -7
  113. package/dist/integrations/graphify.js +0 -54
  114. package/dist/integrations/graphify.js.map +0 -1
  115. package/dist/integrations/omniroute.d.ts +0 -7
  116. package/dist/integrations/omniroute.js +0 -24
  117. package/dist/integrations/omniroute.js.map +0 -1
  118. package/dist/integrations/ponytail.d.ts +0 -10
  119. package/dist/integrations/ponytail.js +0 -58
  120. package/dist/integrations/ponytail.js.map +0 -1
  121. package/dist/integrations/probe.d.ts +0 -6
  122. package/dist/integrations/probe.js +0 -41
  123. package/dist/integrations/probe.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/services/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { SCHEMA_VERSION, validateAnalysisState, validateCommands } from '../config/schemas.js';\nimport { findWorkspaceRoot, LOCAL_GITIGNORE, loadProject, wsPaths, type Ws } from '../core/workspace.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { getGitState, gitAvailable, gitTrackedFiles } from '../git/git.js';\nimport { detectIntegrations } from '../integrations/index.js';\nimport { loadFacts } from '../knowledge/facts.js';\nimport { ONBOARDING_REQUIREMENTS, validatePrompt } from '../prompts/requirements.js';\nimport { isSensitiveFile } from '../security/files.js';\nimport { findSecrets } from '../security/redact.js';\nimport { listDecisions } from '../decisions/decision.js';\nimport { listTasks } from '../tasks/task.js';\nimport { ensureDir, listFilesRecursive, pathExists, readTextBounded, atomicWriteFile } from '../utils/fs.js';\nimport { findAbsolutePaths } from '../utils/paths.js';\nimport { instructionsInstalled, knowledgeWritten } from './status.js';\nimport { integrationCtx, type ServiceOptions } from './common.js';\nimport { withLock } from '../utils/lock.js';\n\nexport type CheckStatus = 'pass' | 'warn' | 'fail' | 'info';\n\nexport interface DoctorCheck {\n id: string;\n status: CheckStatus;\n message: string;\n remediation?: string;\n}\n\nexport interface DoctorResult {\n root: string | null;\n checks: DoctorCheck[];\n counts: { pass: number; warn: number; fail: number; info: number };\n healthy: boolean;\n ready: boolean;\n fixed: string[];\n}\n\nexport interface DoctorOptions extends ServiceOptions {\n fix?: boolean;\n minNodeMajor?: number;\n}\n\nexport const MIN_NODE_MAJOR = 20;\n\nexport async function runDoctor(o: DoctorOptions): Promise<DoctorResult> {\n const checks: DoctorCheck[] = [];\n const fixed: string[] = [];\n const add = (id: string, status: CheckStatus, message: string, remediation?: string): void => {\n checks.push({ id, status, message, ...(remediation ? { remediation } : {}) });\n };\n\n const major = Number(process.versions.node.split('.')[0]);\n const minNode = o.minNodeMajor ?? MIN_NODE_MAJOR;\n if (major >= minNode) add('node', 'pass', `Node.js ${process.versions.node}`);\n else add('node', 'fail', `Node.js ${process.versions.node} is older than the required ${minNode}`, `Install Node.js ${minNode} or newer (https://nodejs.org).`);\n\n const hasGit = await gitAvailable();\n if (hasGit) add('git', 'pass', 'Git is available');\n else add('git', 'warn', 'Git was not found on PATH', 'Install Git; DevWorkspace works without it but cannot protect uncommitted changes.');\n\n const root = await findWorkspaceRoot(o.cwd);\n if (!root) {\n if (await pathExists(path.join(o.cwd, '.devworkspace'))) {\n add('workspace', 'fail', 'Partial initialization: .devworkspace/ exists but project.json is missing', 'Restore project.json from Git, or run \"devworkspace init\" to complete the setup (existing files are kept).');\n } else {\n add('workspace', 'fail', 'No DevWorkspace found in this directory or any parent', 'Run: devworkspace init');\n }\n return finish(null, checks, fixed);\n }\n const ws = wsPaths(root);\n add('workspace', 'pass', 'Workspace found');\n\n // Project config and schema compatibility.\n let projectOk = false;\n try {\n const p = await loadProject(ws);\n projectOk = true;\n add('project', 'pass', `project.json valid (schema v${p.schemaVersion}, id ${p.projectId.slice(0, 8)})`);\n } catch (e) {\n const code = (e as { code?: string }).code;\n add('project', 'fail', (e as Error).message.split('\\n')[0]!, code === 'SCHEMA_TOO_NEW' ? 'Upgrade DevWorkspace: npm install -g devworkspace@latest' : 'Restore .devworkspace/project.json from Git, or re-run \"devworkspace init\" after moving the broken file away.');\n }\n\n // Layout.\n const dirs = [ws.contextDir, ws.decisionsDir, ws.tasksActive, ws.tasksCompleted, ws.sessionsDir, ws.analysisDir, ws.stateDir];\n const missingDirs: string[] = [];\n for (const d of dirs) if (!(await pathExists(d))) missingDirs.push(d);\n if (missingDirs.length === 0) add('layout', 'pass', 'Workspace folders present');\n else if (o.fix && projectOk) {\n await withLock(ws.dir, async () => {\n for (const d of missingDirs) await ensureDir(d);\n });\n fixed.push(`created ${missingDirs.length} missing folder(s)`);\n add('layout', 'pass', `Recreated ${missingDirs.length} missing folder(s)`);\n } else {\n add('layout', 'warn', `Missing folders: ${missingDirs.map((d) => path.basename(d)).join(', ')}`, 'Run: devworkspace doctor --fix');\n }\n\n // Ignore rules.\n const giOk = await fs.readFile(ws.gitignore, 'utf8').then(\n (gi) => gi.split(/\\r?\\n/).some((l) => l.trim() === 'local/'),\n () => false,\n );\n if (giOk) add('ignore-local', 'pass', 'Machine-local state is git-ignored');\n else if (o.fix && projectOk) {\n await atomicWriteFile(ws.gitignore, LOCAL_GITIGNORE);\n fixed.push('wrote .devworkspace/.gitignore');\n add('ignore-local', 'pass', 'Wrote .devworkspace/.gitignore');\n } else add('ignore-local', 'fail', '.devworkspace/.gitignore does not ignore local/', 'Run: devworkspace doctor --fix');\n\n try {\n const rootGi = await fs.readFile(path.join(root, '.gitignore'), 'utf8');\n if (rootGi.split(/\\r?\\n/).some((l) => /^\\/?\\.devworkspace\\/?\\*?$/.test(l.trim()))) {\n add('ignore-root', 'warn', 'The root .gitignore ignores all of .devworkspace/, so project knowledge will not be shared', 'Remove that rule; .devworkspace/.gitignore already excludes machine-local files.');\n }\n } catch {\n /* no root .gitignore */\n }\n\n // Knowledge and contract.\n try {\n const facts = await loadFacts(ws);\n const stale = facts.facts.filter((f) => f.status === 'STALE');\n add('facts', 'pass', `${facts.facts.length} fact(s) stored`);\n if (stale.length > 0) add('staleness', 'warn', `${stale.length} stale fact(s): ${stale.slice(0, 5).map((f) => f.key).join(', ')}`, 'Run: devworkspace refresh');\n else if (facts.facts.length > 0) add('staleness', 'pass', 'No stale facts recorded');\n } catch (e) {\n add('facts', 'fail', (e as Error).message.split('\\n')[0]!, 'Restore .devworkspace/context/facts.json from Git or a backup under .devworkspace/local/backups.');\n }\n\n if (await pathExists(ws.commands)) {\n try {\n const c = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data;\n add('contract', 'pass', 'Testing contract present');\n const unit = c.checks.find((x) => x.id === 'unit');\n if (!unit?.available) add('tests-available', 'warn', 'No unit-test command detected', 'Add a test script or edit .devworkspace/context/commands.json; tasks will not be able to demand tests.');\n if (!c.checks.some((x) => x.id === 'build' && x.available)) add('build-available', 'info', 'No build command detected');\n } catch (e) {\n add('contract', 'fail', (e as Error).message.split('\\n')[0]!, 'Fix commands.json or re-run: devworkspace analyze');\n }\n } else add('contract', 'warn', 'Testing contract not generated yet', 'Run: devworkspace analyze');\n\n if (await pathExists(ws.analysisState)) {\n try {\n const a = (await readVersioned(ws.analysisState, 'analysis', SCHEMA_VERSION, validateAnalysisState)).data;\n add('analysis', 'pass', `Last analysis ${a.analyzedAt}${a.truncated ? ' (partial: size limits hit)' : ''}`);\n } catch (e) {\n add('analysis', 'fail', (e as Error).message.split('\\n')[0]!, 'Re-run: devworkspace analyze');\n }\n } else add('analysis', 'warn', 'Repository has not been analyzed', 'Run: devworkspace analyze');\n\n // Prompt quality (when present).\n if (await pathExists(ws.onboardingPrompt)) {\n const text = (await readTextBounded(ws.onboardingPrompt, 1024 * 1024)) ?? '';\n const missing = validatePrompt(text, ONBOARDING_REQUIREMENTS);\n if (missing.length === 0) add('onboarding-prompt', 'pass', 'Onboarding prompt satisfies all behavioural requirements');\n else add('onboarding-prompt', 'fail', `Onboarding prompt is missing: ${missing.join(', ')}`, 'Re-run: devworkspace analyze');\n }\n\n // Agent wiring.\n if (await instructionsInstalled(ws)) add('agent-instructions', 'pass', 'Claude instructions and skill installed');\n else add('agent-instructions', 'warn', 'Claude instructions are not installed (or the managed section is missing)', 'Run: devworkspace agent install');\n if (await knowledgeWritten(ws)) add('onboarding', 'pass', 'Architecture knowledge written');\n else add('onboarding', 'warn', 'Onboarding is not complete: .devworkspace/context/architecture.md is missing or empty', 'Paste .devworkspace/analysis/onboarding-prompt.md into Claude Code.');\n\n // Integrations.\n for (const i of await detectIntegrations(integrationCtx(o, root))) {\n if (i.state === 'READY') add(`integration-${i.id}`, 'pass', `${i.name}: ready`);\n else if (i.optional) add(`integration-${i.id}`, 'info', `${i.name}: ${i.state.toLowerCase().replace('_', ' ')} (optional)`);\n else add(`integration-${i.id}`, 'warn', `${i.name}: ${i.state.toLowerCase().replace('_', ' ')}${i.details[0] ? ` - ${i.details[0]}` : ''}`, i.remediation[0]);\n }\n\n // Security and portability.\n const wsFiles = (await listFilesRecursive(ws.dir, 3000)).filter((f) => !f.startsWith(ws.localDir) && !/\\.tmp$/.test(f));\n const secretHits: string[] = [];\n const absHits: string[] = [];\n for (const f of wsFiles) {\n if (!/\\.(json|md)$/.test(f)) continue;\n const rel = path.relative(ws.dir, f).replace(/\\\\/g, '/');\n const text = await readTextBounded(f, 1024 * 1024);\n if (!text) continue;\n if (findSecrets(text).length > 0) secretHits.push(rel);\n if (rel !== 'analysis/onboarding-prompt.md' && rel !== 'analysis/refresh-prompt.md' && findAbsolutePaths(text).length > 0) absHits.push(rel);\n }\n if (secretHits.length === 0) add('secrets', 'pass', 'No secret-like values in .devworkspace');\n else add('secrets', 'fail', `Secret-like values found in: ${secretHits.join(', ')}`, 'Remove the values, rotate the credential if it was real, and re-run doctor.');\n if (absHits.length === 0) add('portability', 'pass', 'No machine-specific absolute paths in portable knowledge');\n else add('portability', 'warn', `Absolute paths found in: ${absHits.join(', ')}`, 'Replace them with project-relative paths so the workspace works after the project moves.');\n\n const git = await getGitState(root);\n if (git.isRepo) {\n const tracked = await gitTrackedFiles(root);\n const bad = (tracked ?? []).filter((f) => isSensitiveFile(f));\n if (bad.length > 0) add('tracked-secrets', 'warn', `Credential-like files are tracked by Git: ${bad.slice(0, 5).join(', ')}`, 'Remove them from Git history if they hold real secrets (git rm --cached, then rotate).');\n else add('tracked-secrets', 'pass', 'No credential-like files tracked by Git');\n }\n\n const leftovers = wsFiles.filter((f) => f.endsWith('.tmp'));\n const allTmp = (await listFilesRecursive(ws.dir, 3000)).filter((f) => f.endsWith('.tmp'));\n if (allTmp.length > 0 || leftovers.length > 0) add('tmp-files', 'warn', `${allTmp.length} leftover temporary file(s) from an interrupted write`, 'They are safe to delete: ' + allTmp.slice(0, 3).map((f) => path.relative(root, f).replace(/\\\\/g, '/')).join(', '));\n\n // Tasks and decisions.\n const { tasks, corrupt } = await listTasks(ws, { includeCompleted: true });\n if (corrupt.length > 0) add('tasks', 'fail', `${corrupt.length} unreadable task file(s): ${corrupt.map((c) => c.file).join(', ')}`, 'Restore them from Git or delete the broken file.');\n else add('tasks', 'pass', `${tasks.length} task(s) readable`);\n const dec = await listDecisions(ws);\n if (dec.unreadable.length > 0) add('decisions', 'warn', `Unreadable decision file(s): ${dec.unreadable.join(', ')}`, 'Check their front matter.');\n\n return finish(root, checks, fixed, ws);\n}\n\nasync function finish(root: string | null, checks: DoctorCheck[], fixed: string[], ws?: Ws): Promise<DoctorResult> {\n const counts = { pass: 0, warn: 0, fail: 0, info: 0 };\n for (const c of checks) counts[c.status]++;\n let ready = false;\n if (ws) ready = counts.fail === 0 && (await instructionsInstalled(ws)) && (await knowledgeWritten(ws));\n return { root, checks, counts, healthy: counts.fail === 0, ready, fixed };\n}\n"]}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/services/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { SCHEMA_VERSION, validateAnalysisState, validateCommands } from '../config/schemas.js';\nimport { findWorkspaceRoot, LOCAL_GITIGNORE, loadProject, wsPaths, type Ws } from '../core/workspace.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { getGitState, gitAvailable, gitTrackedFiles } from '../git/git.js';\nimport { inspectAll, summarize, type IntegrationReport } from '../integrations/index.js';\nimport { loadFacts } from '../knowledge/facts.js';\nimport { ONBOARDING_REQUIREMENTS, validatePrompt } from '../prompts/requirements.js';\nimport { isSensitiveFile } from '../security/files.js';\nimport { findSecrets } from '../security/redact.js';\nimport { listDecisions } from '../decisions/decision.js';\nimport { listTasks } from '../tasks/task.js';\nimport { ensureDir, listFilesRecursive, pathExists, readJsonFile, readTextBounded, atomicWriteFile } from '../utils/fs.js';\nimport { ALWAYS_SKIP_DIRS } from '../discovery/scan.js';\nimport { isAuxPath } from '../discovery/detect.js';\nimport { findAbsolutePaths } from '../utils/paths.js';\nimport { instructionsInstalled, knowledgeWritten } from './status.js';\nimport { managerEnv, type ServiceOptions } from './common.js';\nimport { withLock } from '../utils/lock.js';\n\nexport type CheckStatus = 'pass' | 'warn' | 'fail' | 'info';\n\nexport interface DoctorCheck {\n id: string;\n status: CheckStatus;\n message: string;\n remediation?: string;\n}\n\nexport interface DoctorResult {\n root: string | null;\n checks: DoctorCheck[];\n counts: { pass: number; warn: number; fail: number; info: number };\n /** Core workspace has no failing checks. */\n healthy: boolean;\n /** Core workspace is onboarded: instructions installed and architecture knowledge written. */\n ready: boolean;\n fixed: string[];\n /** Observed integration state, kept separate from core readiness. */\n integrations: IntegrationReport[];\n integrationSummary: { complete: boolean; required: number; verified: number };\n}\n\nexport interface DoctorOptions extends ServiceOptions {\n fix?: boolean;\n minNodeMajor?: number;\n}\n\nexport const MIN_NODE_MAJOR = 20;\n\nexport async function runDoctor(o: DoctorOptions): Promise<DoctorResult> {\n const checks: DoctorCheck[] = [];\n const fixed: string[] = [];\n const add = (id: string, status: CheckStatus, message: string, remediation?: string): void => {\n checks.push({ id, status, message, ...(remediation ? { remediation } : {}) });\n };\n\n const major = Number(process.versions.node.split('.')[0]);\n const minNode = o.minNodeMajor ?? MIN_NODE_MAJOR;\n if (major >= minNode) add('node', 'pass', `Node.js ${process.versions.node}`);\n else add('node', 'fail', `Node.js ${process.versions.node} is older than the required ${minNode}`, `Install Node.js ${minNode} or newer (https://nodejs.org).`);\n\n const hasGit = await gitAvailable();\n if (hasGit) add('git', 'pass', 'Git is available');\n else add('git', 'warn', 'Git was not found on PATH', 'Install Git; DevWorkspace works without it but cannot protect uncommitted changes.');\n\n const root = await findWorkspaceRoot(o.cwd);\n if (!root) {\n if (await pathExists(path.join(o.cwd, '.devworkspace'))) {\n add('workspace', 'fail', 'Partial initialization: .devworkspace/ exists but project.json is missing', 'Restore project.json from Git, or run \"devworkspace init\" to complete the setup (existing files are kept).');\n } else {\n add('workspace', 'fail', 'No DevWorkspace found in this directory or any parent', 'Run: devworkspace init');\n }\n return finish(null, checks, fixed, undefined, o);\n }\n const ws = wsPaths(root);\n add('workspace', 'pass', 'Workspace found');\n\n // Project config and schema compatibility.\n let projectOk = false;\n let acknowledgedNoVerification = false;\n try {\n const p = await loadProject(ws);\n projectOk = true;\n acknowledgedNoVerification = p.settings.acknowledgeNoVerification === true;\n add('project', 'pass', `project.json valid (schema v${p.schemaVersion}, id ${p.projectId.slice(0, 8)})`);\n } catch (e) {\n const code = (e as { code?: string }).code;\n add('project', 'fail', (e as Error).message.split('\\n')[0]!, code === 'SCHEMA_TOO_NEW' ? 'Upgrade DevWorkspace: npm install -g devworkspace@latest' : 'Restore .devworkspace/project.json from Git, or re-run \"devworkspace init\" after moving the broken file away.');\n }\n\n // Layout.\n const dirs = [ws.contextDir, ws.decisionsDir, ws.tasksActive, ws.tasksCompleted, ws.sessionsDir, ws.analysisDir, ws.stateDir];\n const missingDirs: string[] = [];\n for (const d of dirs) if (!(await pathExists(d))) missingDirs.push(d);\n if (missingDirs.length === 0) add('layout', 'pass', 'Workspace folders present');\n else if (o.fix && projectOk) {\n await withLock(ws.dir, async () => {\n for (const d of missingDirs) await ensureDir(d);\n });\n fixed.push(`created ${missingDirs.length} missing folder(s)`);\n add('layout', 'pass', `Recreated ${missingDirs.length} missing folder(s)`);\n } else {\n add('layout', 'warn', `Missing folders: ${missingDirs.map((d) => path.basename(d)).join(', ')}`, 'Run: devworkspace doctor --fix');\n }\n\n // Ignore rules.\n const giOk = await fs.readFile(ws.gitignore, 'utf8').then(\n (gi) => gi.split(/\\r?\\n/).some((l) => l.trim() === 'local/'),\n () => false,\n );\n if (giOk) add('ignore-local', 'pass', 'Machine-local state is git-ignored');\n else if (o.fix && projectOk) {\n await atomicWriteFile(ws.gitignore, LOCAL_GITIGNORE);\n fixed.push('wrote .devworkspace/.gitignore');\n add('ignore-local', 'pass', 'Wrote .devworkspace/.gitignore');\n } else add('ignore-local', 'fail', '.devworkspace/.gitignore does not ignore local/', 'Run: devworkspace doctor --fix');\n\n try {\n const rootGi = await fs.readFile(path.join(root, '.gitignore'), 'utf8');\n if (rootGi.split(/\\r?\\n/).some((l) => /^\\/?\\.devworkspace\\/?\\*?$/.test(l.trim()))) {\n add('ignore-root', 'warn', 'The root .gitignore ignores all of .devworkspace/, so project knowledge will not be shared', 'Remove that rule; .devworkspace/.gitignore already excludes machine-local files.');\n }\n } catch {\n /* no root .gitignore */\n }\n\n // Knowledge and contract.\n try {\n const facts = await loadFacts(ws);\n const stale = facts.facts.filter((f) => f.status === 'STALE');\n add('facts', 'pass', `${facts.facts.length} fact(s) stored`);\n if (stale.length > 0) add('staleness', 'warn', `${stale.length} stale fact(s): ${stale.slice(0, 5).map((f) => f.key).join(', ')}`, 'Run: devworkspace refresh');\n else if (facts.facts.length > 0) add('staleness', 'pass', 'No stale facts recorded');\n } catch (e) {\n add('facts', 'fail', (e as Error).message.split('\\n')[0]!, 'Restore .devworkspace/context/facts.json from Git or a backup under .devworkspace/local/backups.');\n }\n\n if (await pathExists(ws.commands)) {\n try {\n const c = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data;\n add('contract', 'pass', 'Testing contract present');\n if (!c.checks.some((x) => x.id === 'unit' && x.available)) add('tests-available', 'warn', 'No unit-test command detected', 'Add a test script or edit .devworkspace/context/commands.json; tasks will not be able to demand tests.');\n if (!c.checks.some((x) => x.id === 'build' && x.available)) add('build-available', 'info', 'No build command detected');\n const configured = c.checks.filter((x) => x.available);\n if (configured.length > 0) {\n const ids = [...new Set(configured.map((x) => x.id))];\n const dirs = [...new Set(configured.map((x) => x.cwd).filter((d): d is string => !!d))];\n add('verification-commands', 'pass', `${ids.length} verification check(s) configured: ${ids.join(', ')}${dirs.length ? ` (in ${dirs.join(', ')})` : ''}`);\n } else if (acknowledgedNoVerification) {\n add('verification-commands', 'info', 'No verification commands; acknowledged in project.json (settings.acknowledgeNoVerification)');\n } else {\n add(\n 'verification-commands',\n 'warn',\n 'No verification commands (tests, lint, typecheck, build) are configured, so tasks cannot require any verification',\n 'Run: devworkspace analyze. If the project intentionally has none, set \"acknowledgeNoVerification\": true under settings in .devworkspace/project.json.',\n );\n }\n } catch (e) {\n add('contract', 'fail', (e as Error).message.split('\\n')[0]!, 'Fix commands.json or re-run: devworkspace analyze');\n }\n } else add('contract', 'warn', 'Testing contract not generated yet', 'Run: devworkspace analyze');\n\n await checkDiscovery(ws, add);\n\n if (await pathExists(ws.analysisState)) {\n try {\n const a = (await readVersioned(ws.analysisState, 'analysis', SCHEMA_VERSION, validateAnalysisState)).data;\n add('analysis', 'pass', `Last analysis ${a.analyzedAt}${a.truncated ? ' (partial: size limits hit)' : ''}`);\n } catch (e) {\n add('analysis', 'fail', (e as Error).message.split('\\n')[0]!, 'Re-run: devworkspace analyze');\n }\n } else add('analysis', 'warn', 'Repository has not been analyzed', 'Run: devworkspace analyze');\n\n // Prompt quality (when present).\n if (await pathExists(ws.onboardingPrompt)) {\n const text = (await readTextBounded(ws.onboardingPrompt, 1024 * 1024)) ?? '';\n const missing = validatePrompt(text, ONBOARDING_REQUIREMENTS);\n if (missing.length === 0) add('onboarding-prompt', 'pass', 'Onboarding prompt satisfies all behavioural requirements');\n else add('onboarding-prompt', 'fail', `Onboarding prompt is missing: ${missing.join(', ')}`, 'Re-run: devworkspace analyze');\n }\n\n // Agent wiring.\n if (await instructionsInstalled(ws)) add('agent-instructions', 'pass', 'Claude instructions and skill installed');\n else add('agent-instructions', 'warn', 'Claude instructions are not installed (or the managed section is missing)', 'Run: devworkspace agent install');\n if (await knowledgeWritten(ws)) add('onboarding', 'pass', 'Architecture knowledge written');\n else add('onboarding', 'warn', 'Onboarding is not complete: .devworkspace/context/architecture.md is missing or empty', 'Paste .devworkspace/analysis/onboarding-prompt.md into Claude Code.');\n\n // Security and portability.\n const wsFiles = (await listFilesRecursive(ws.dir, 3000)).filter((f) => !f.startsWith(ws.localDir) && !/\\.tmp$/.test(f));\n const secretHits: string[] = [];\n const absHits: string[] = [];\n for (const f of wsFiles) {\n if (!/\\.(json|md)$/.test(f)) continue;\n const rel = path.relative(ws.dir, f).replace(/\\\\/g, '/');\n const text = await readTextBounded(f, 1024 * 1024);\n if (!text) continue;\n if (findSecrets(text).length > 0) secretHits.push(rel);\n if (rel !== 'analysis/onboarding-prompt.md' && rel !== 'analysis/refresh-prompt.md' && findAbsolutePaths(text).length > 0) absHits.push(rel);\n }\n if (secretHits.length === 0) add('secrets', 'pass', 'No secret-like values in .devworkspace');\n else add('secrets', 'fail', `Secret-like values found in: ${secretHits.join(', ')}`, 'Remove the values, rotate the credential if it was real, and re-run doctor.');\n if (absHits.length === 0) add('portability', 'pass', 'No machine-specific absolute paths in portable knowledge');\n else add('portability', 'warn', `Absolute paths found in: ${absHits.join(', ')}`, 'Replace them with project-relative paths so the workspace works after the project moves.');\n\n const git = await getGitState(root);\n if (git.isRepo) {\n const tracked = await gitTrackedFiles(root);\n const bad = (tracked ?? []).filter((f) => isSensitiveFile(f));\n if (bad.length > 0) add('tracked-secrets', 'warn', `Credential-like files are tracked by Git: ${bad.slice(0, 5).join(', ')}`, 'Remove them from Git history if they hold real secrets (git rm --cached, then rotate).');\n else add('tracked-secrets', 'pass', 'No credential-like files tracked by Git');\n }\n\n const leftovers = wsFiles.filter((f) => f.endsWith('.tmp'));\n const allTmp = (await listFilesRecursive(ws.dir, 3000)).filter((f) => f.endsWith('.tmp'));\n if (allTmp.length > 0 || leftovers.length > 0) add('tmp-files', 'warn', `${allTmp.length} leftover temporary file(s) from an interrupted write`, 'They are safe to delete: ' + allTmp.slice(0, 3).map((f) => path.relative(root, f).replace(/\\\\/g, '/')).join(', '));\n\n // Tasks and decisions.\n const { tasks, corrupt } = await listTasks(ws, { includeCompleted: true });\n if (corrupt.length > 0) add('tasks', 'fail', `${corrupt.length} unreadable task file(s): ${corrupt.map((c) => c.file).join(', ')}`, 'Restore them from Git or delete the broken file.');\n else add('tasks', 'pass', `${tasks.length} task(s) readable`);\n const dec = await listDecisions(ws);\n if (dec.unreadable.length > 0) add('decisions', 'warn', `Unreadable decision file(s): ${dec.unreadable.join(', ')}`, 'Check their front matter.');\n\n return finish(root, checks, fixed, ws, o);\n}\n\nasync function finish(root: string | null, checks: DoctorCheck[], fixed: string[], ws: Ws | undefined, o: DoctorOptions): Promise<DoctorResult> {\n const counts = { pass: 0, warn: 0, fail: 0, info: 0 };\n for (const c of checks) counts[c.status]++;\n let ready = false;\n const discoveryOk = !checks.some((c) => DISCOVERY_CHECKS.has(c.id) && c.status === 'warn');\n if (ws) ready = counts.fail === 0 && discoveryOk && (await instructionsInstalled(ws)) && (await knowledgeWritten(ws));\n // Integrations are observed (tools are run), and reported separately: a missing optional tool never makes the core workspace unhealthy.\n const integrations = root && ws ? await inspectAll(ws, managerEnv(o, root), { deep: true }) : [];\n const s = summarize(integrations);\n return { root, checks, counts, healthy: counts.fail === 0, ready, fixed, integrations, integrationSummary: { complete: integrations.length > 0 && s.complete, required: s.required, verified: s.verified } };\n}\n\n/** Doctor checks that say whether the repository was actually understood, as opposed to the folder merely existing. */\nconst DISCOVERY_CHECKS = new Set(['discovery-incomplete', 'discovery-ecosystem', 'verification-commands']);\n\n/** package.json files near the top of the tree (two levels), found without a full scan. */\nasync function findNearbyManifests(root: string): Promise<string[]> {\n const found: string[] = [];\n const skip = (name: string, rel: string): boolean => name.startsWith('.') || ALWAYS_SKIP_DIRS.has(name) || isAuxPath(`${rel}/x`);\n async function dirs(rel: string): Promise<string[]> {\n try {\n return (await fs.readdir(path.join(root, rel), { withFileTypes: true })).filter((e) => e.isDirectory() && !skip(e.name, rel ? `${rel}/${e.name}` : e.name)).map((e) => (rel ? `${rel}/${e.name}` : e.name));\n } catch {\n return [];\n }\n }\n for (const d1 of await dirs('')) {\n if (await pathExists(path.join(root, d1, 'package.json'))) found.push(`${d1}/package.json`);\n for (const d2 of (await dirs(d1)).slice(0, 100)) if (await pathExists(path.join(root, d2, 'package.json'))) found.push(`${d2}/package.json`);\n }\n return found.sort();\n}\n\nasync function checkDiscovery(ws: Ws, add: (id: string, status: CheckStatus, message: string, remediation?: string) => void): Promise<void> {\n if (!(await pathExists(ws.discovery))) return; // \"not analyzed yet\" is reported by the analysis check\n let d: { ecosystems?: string[]; languages?: { name: string; files: number }[]; manifests?: string[]; monorepo?: { packages?: { path: string }[] }; scan?: { fileCount?: number } };\n try {\n d = (await readJsonFile(ws.discovery)) as typeof d;\n } catch (e) {\n add('discovery-ecosystem', 'fail', (e as Error).message.split('\\n')[0]!, 'Re-run: devworkspace analyze');\n return;\n }\n const eco = d.ecosystems ?? [];\n const languages = (d.languages ?? []).map((l) => l.name);\n // Manifests the analysis recorded. Older reports lack the list, so reconstruct it from the packages they did record.\n const known = new Set<string>(d.manifests ?? []);\n for (const p of d.monorepo?.packages ?? []) known.add(`${p.path}/package.json`);\n if (eco.includes('node')) known.add('package.json');\n const missed = (await findNearbyManifests(ws.root)).filter((m) => !known.has(m));\n if (missed.length > 0) {\n add(\n 'discovery-incomplete',\n 'warn',\n `The repository has package manifest(s) the last analysis did not record: ${missed.slice(0, 4).join(', ')}${missed.length > 4 ? ', ...' : ''}`,\n 'Run: devworkspace analyze (current versions detect nested packages). Commands you confirmed earlier are kept.',\n );\n } else if (eco.length === 0 && languages.length > 0) {\n add(\n 'discovery-ecosystem',\n 'warn',\n `No ecosystem was detected although ${d.scan?.fileCount ?? 'several'} files were scanned (${languages.slice(0, 3).join(', ')}), so build and test tooling is unknown`,\n 'Run: devworkspace analyze. If the project has no package manifest, record its commands by hand in .devworkspace/context/commands.json.',\n );\n } else if (eco.length > 0) {\n const n = d.monorepo?.packages?.length ?? 0;\n add('discovery-ecosystem', 'pass', `Detected ${eco.join(', ')}${n > 0 ? ` (${n} package${n === 1 ? '' : 's'})` : ''}`);\n } else {\n add('discovery-ecosystem', 'info', 'No source files or manifests detected');\n }\n}\n"]}
@@ -1,8 +1,13 @@
1
- import { detectIntegrations } from '../integrations/index.js';
1
+ import { type IntegrationReport, type SetupResult } from '../integrations/index.js';
2
2
  import { type ServiceOptions } from './common.js';
3
3
  export interface InitOptions extends ServiceOptions {
4
4
  /** Explicit project root; defaults to the Git top-level or the current directory. */
5
5
  root?: string;
6
+ /** Also run the integration manager (same code path as `devworkspace setup --integrations`). */
7
+ withIntegrations?: {
8
+ yes: boolean;
9
+ scope: 'project' | 'user';
10
+ };
6
11
  }
7
12
  export interface InitResult {
8
13
  root: string;
@@ -12,7 +17,9 @@ export interface InitResult {
12
17
  unchanged: string[];
13
18
  gitignoreUpdated: boolean;
14
19
  notes: string[];
15
- integrations: Awaited<ReturnType<typeof detectIntegrations>>;
20
+ integrations: IntegrationReport[];
21
+ /** Present when withIntegrations was requested. */
22
+ setup?: SetupResult;
16
23
  nextSteps: string[];
17
24
  }
18
25
  export declare function initWorkspace(o: InitOptions): Promise<InitResult>;
@@ -3,14 +3,14 @@ import path from 'node:path';
3
3
  import { SCHEMA_VERSION, validateProject } from '../config/schemas.js';
4
4
  import { DevWorkspaceError } from '../errors/index.js';
5
5
  import { gitTopLevel } from '../git/git.js';
6
- import { detectIntegrations } from '../integrations/index.js';
6
+ import { inspectAll, runSetup } from '../integrations/index.js';
7
7
  import { atomicWriteFile, atomicWriteJson, ensureDir, pathExists } from '../utils/fs.js';
8
8
  import { findWorkspaceRoot, LOCAL_GITIGNORE, loadProject, wsPaths, WORKSPACE_DIR } from '../core/workspace.js';
9
9
  import { packageVersion } from '../core/version.js';
10
10
  import { withLock } from '../utils/lock.js';
11
11
  import { readPackageJson } from '../discovery/detect.js';
12
12
  import { newProjectId } from './analysis.js';
13
- import { integrationCtx, isoNow } from './common.js';
13
+ import { isoNow, managerEnv } from './common.js';
14
14
  async function resolveRoot(o, notes) {
15
15
  if (o.root)
16
16
  return path.resolve(o.cwd, o.root);
@@ -58,7 +58,6 @@ export async function initWorkspace(o) {
58
58
  const pkg = (await pathExists(path.join(root, 'package.json'))) ? await readPackageJson(root, 'package.json').catch(() => null) : null;
59
59
  const name = pkg?.name ?? path.basename(root);
60
60
  const now = isoNow(o);
61
- const integrations = await detectIntegrations(integrationCtx(o, root));
62
61
  const result = (extra) => ({
63
62
  root,
64
63
  dryRun: !!o.dryRun,
@@ -67,10 +66,11 @@ export async function initWorkspace(o) {
67
66
  unchanged,
68
67
  gitignoreUpdated: false,
69
68
  notes,
70
- integrations,
69
+ integrations: [],
71
70
  nextSteps: ['Run: devworkspace analyze', 'Then paste .devworkspace/analysis/onboarding-prompt.md into Claude Code'],
72
71
  ...extra,
73
72
  });
73
+ const shallow = async () => inspectAll(ws, managerEnv(o, root), { deep: false });
74
74
  if (o.dryRun) {
75
75
  for (const d of dirs)
76
76
  if (!(await pathExists(d)))
@@ -79,7 +79,7 @@ export async function initWorkspace(o) {
79
79
  created.push(rel(ws.projectJson));
80
80
  if (!(await pathExists(ws.gitignore)))
81
81
  created.push(rel(ws.gitignore));
82
- return result({});
82
+ return result({ integrations: await shallow() });
83
83
  }
84
84
  await ensureDir(ws.dir);
85
85
  return withLock(ws.dir, async () => {
@@ -128,8 +128,11 @@ export async function initWorkspace(o) {
128
128
  notes.push('Added missing ignore rules to .devworkspace/.gitignore.');
129
129
  else
130
130
  unchanged.push(rel(ws.gitignore));
131
- await atomicWriteJson(ws.integrationsState, { schemaVersion: SCHEMA_VERSION, detectedAt: now, integrations });
132
- return result({ gitignoreUpdated: gi === 'updated' });
131
+ let setup;
132
+ if (o.withIntegrations) {
133
+ setup = await runSetup(ws, managerEnv(o, root), { scope: o.withIntegrations.scope, yes: o.withIntegrations.yes, dryRun: false, repair: false });
134
+ }
135
+ return result({ gitignoreUpdated: gi === 'updated', integrations: setup ? setup.outcomes.map((x) => x.report) : await shallow(), ...(setup ? { setup } : {}) });
133
136
  });
134
137
  }
135
138
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/services/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { SCHEMA_VERSION, validateProject, type ProjectConfig } from '../config/schemas.js';\nimport { DevWorkspaceError } from '../errors/index.js';\nimport { gitTopLevel } from '../git/git.js';\nimport { detectIntegrations } from '../integrations/index.js';\nimport { atomicWriteFile, atomicWriteJson, ensureDir, pathExists } from '../utils/fs.js';\nimport { findWorkspaceRoot, LOCAL_GITIGNORE, loadProject, wsPaths, WORKSPACE_DIR, type Ws } from '../core/workspace.js';\nimport { packageVersion } from '../core/version.js';\nimport { withLock } from '../utils/lock.js';\nimport { readPackageJson } from '../discovery/detect.js';\nimport { newProjectId } from './analysis.js';\nimport { integrationCtx, isoNow, type ServiceOptions } from './common.js';\n\nexport interface InitOptions extends ServiceOptions {\n /** Explicit project root; defaults to the Git top-level or the current directory. */\n root?: string;\n}\n\nexport interface InitResult {\n root: string;\n dryRun: boolean;\n alreadyInitialized: boolean;\n created: string[];\n unchanged: string[];\n gitignoreUpdated: boolean;\n notes: string[];\n integrations: Awaited<ReturnType<typeof detectIntegrations>>;\n nextSteps: string[];\n}\n\nasync function resolveRoot(o: InitOptions, notes: string[]): Promise<string> {\n if (o.root) return path.resolve(o.cwd, o.root);\n const existing = await findWorkspaceRoot(o.cwd);\n if (existing) {\n if (path.resolve(existing) !== path.resolve(o.cwd)) notes.push(`Using the existing workspace root (${path.relative(o.cwd, existing) || '.'}).`);\n return existing;\n }\n const top = await gitTopLevel(o.cwd);\n if (top && path.resolve(top).toLowerCase() !== path.resolve(o.cwd).toLowerCase()) {\n notes.push('Current directory is inside a Git repository; using the repository root. Pass --root to choose a different directory.');\n return path.resolve(top);\n }\n return path.resolve(o.cwd);\n}\n\n/** Make sure each required line is present in .devworkspace/.gitignore without removing anything the user added. */\nasync function ensureGitignore(ws: Ws): Promise<'created' | 'updated' | 'unchanged'> {\n if (!(await pathExists(ws.gitignore))) {\n await atomicWriteFile(ws.gitignore, LOCAL_GITIGNORE);\n return 'created';\n }\n const text = await fs.readFile(ws.gitignore, 'utf8');\n const have = new Set(text.split(/\\r?\\n/).map((l) => l.trim()));\n const missing = LOCAL_GITIGNORE.split('\\n').filter((l) => l && !l.startsWith('#') && !have.has(l));\n if (missing.length === 0) return 'unchanged';\n const eol = text.includes('\\r\\n') ? '\\r\\n' : '\\n';\n await atomicWriteFile(ws.gitignore, text + (text.endsWith('\\n') ? '' : eol) + missing.join(eol) + eol);\n return 'updated';\n}\n\nexport async function initWorkspace(o: InitOptions): Promise<InitResult> {\n const notes: string[] = [];\n const root = await resolveRoot(o, notes);\n const st = await fs.stat(root).catch(() => null);\n if (!st?.isDirectory()) {\n throw new DevWorkspaceError('NOT_FOUND', `Project root does not exist: ${root}`, { hint: 'Run the command inside your project, or pass --root <dir>.' });\n }\n const ws = wsPaths(root);\n const created: string[] = [];\n const unchanged: string[] = [];\n const rel = (p: string): string => path.relative(root, p).replace(/\\\\/g, '/');\n const alreadyInitialized = await pathExists(ws.projectJson);\n\n const dirs = [ws.contextDir, ws.decisionsDir, ws.tasksActive, ws.tasksCompleted, ws.sessionsDir, ws.analysisDir, ws.stateDir];\n const pkg = (await pathExists(path.join(root, 'package.json'))) ? await readPackageJson(root, 'package.json').catch(() => null) : null;\n const name = pkg?.name ?? path.basename(root);\n const now = isoNow(o);\n\n const integrations = await detectIntegrations(integrationCtx(o, root));\n\n const result = (extra: Partial<InitResult>): InitResult => ({\n root,\n dryRun: !!o.dryRun,\n alreadyInitialized,\n created,\n unchanged,\n gitignoreUpdated: false,\n notes,\n integrations,\n nextSteps: ['Run: devworkspace analyze', 'Then paste .devworkspace/analysis/onboarding-prompt.md into Claude Code'],\n ...extra,\n });\n\n if (o.dryRun) {\n for (const d of dirs) if (!(await pathExists(d))) created.push(rel(d) + '/');\n if (!alreadyInitialized) created.push(rel(ws.projectJson));\n if (!(await pathExists(ws.gitignore))) created.push(rel(ws.gitignore));\n return result({});\n }\n\n await ensureDir(ws.dir);\n return withLock(ws.dir, async () => {\n for (const d of dirs) {\n if (await pathExists(d)) unchanged.push(rel(d) + '/');\n else {\n await ensureDir(d);\n created.push(rel(d) + '/');\n }\n }\n // Empty directories do not survive Git, so keep portable folders alive.\n for (const d of [ws.decisionsDir, ws.tasksActive, ws.tasksCompleted, ws.sessionsDir]) {\n const keep = path.join(d, '.gitkeep');\n if (!(await pathExists(keep))) await fs.writeFile(keep, '');\n }\n\n let project: ProjectConfig;\n if (alreadyInitialized) {\n project = await loadProject(ws);\n unchanged.push(rel(ws.projectJson));\n if (project.devworkspaceVersion !== packageVersion()) {\n project = { ...project, devworkspaceVersion: packageVersion(), updatedAt: now };\n await atomicWriteJson(ws.projectJson, validateProject(project));\n notes.push(`Recorded DevWorkspace ${packageVersion()} in project.json.`);\n }\n } else {\n project = {\n schemaVersion: SCHEMA_VERSION,\n projectId: newProjectId(),\n name,\n createdAt: now,\n updatedAt: now,\n devworkspaceVersion: packageVersion(),\n settings: { review: 'light', maxFiles: 50_000 },\n managedFiles: [{ path: `${WORKSPACE_DIR}/.gitignore`, mode: 'owned' }],\n };\n await atomicWriteJson(ws.projectJson, validateProject(project));\n created.push(rel(ws.projectJson));\n }\n\n const gi = await ensureGitignore(ws);\n if (gi === 'created') created.push(rel(ws.gitignore));\n else if (gi === 'updated') notes.push('Added missing ignore rules to .devworkspace/.gitignore.');\n else unchanged.push(rel(ws.gitignore));\n\n await atomicWriteJson(ws.integrationsState, { schemaVersion: SCHEMA_VERSION, detectedAt: now, integrations });\n return result({ gitignoreUpdated: gi === 'updated' });\n });\n}\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/services/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { SCHEMA_VERSION, validateProject, type ProjectConfig } from '../config/schemas.js';\nimport { DevWorkspaceError } from '../errors/index.js';\nimport { gitTopLevel } from '../git/git.js';\nimport { inspectAll, runSetup, type IntegrationReport, type SetupResult } from '../integrations/index.js';\nimport { atomicWriteFile, atomicWriteJson, ensureDir, pathExists } from '../utils/fs.js';\nimport { findWorkspaceRoot, LOCAL_GITIGNORE, loadProject, wsPaths, WORKSPACE_DIR, type Ws } from '../core/workspace.js';\nimport { packageVersion } from '../core/version.js';\nimport { withLock } from '../utils/lock.js';\nimport { readPackageJson } from '../discovery/detect.js';\nimport { newProjectId } from './analysis.js';\nimport { isoNow, managerEnv, type ServiceOptions } from './common.js';\n\nexport interface InitOptions extends ServiceOptions {\n /** Explicit project root; defaults to the Git top-level or the current directory. */\n root?: string;\n /** Also run the integration manager (same code path as `devworkspace setup --integrations`). */\n withIntegrations?: { yes: boolean; scope: 'project' | 'user' };\n}\n\nexport interface InitResult {\n root: string;\n dryRun: boolean;\n alreadyInitialized: boolean;\n created: string[];\n unchanged: string[];\n gitignoreUpdated: boolean;\n notes: string[];\n integrations: IntegrationReport[];\n /** Present when withIntegrations was requested. */\n setup?: SetupResult;\n nextSteps: string[];\n}\n\nasync function resolveRoot(o: InitOptions, notes: string[]): Promise<string> {\n if (o.root) return path.resolve(o.cwd, o.root);\n const existing = await findWorkspaceRoot(o.cwd);\n if (existing) {\n if (path.resolve(existing) !== path.resolve(o.cwd)) notes.push(`Using the existing workspace root (${path.relative(o.cwd, existing) || '.'}).`);\n return existing;\n }\n const top = await gitTopLevel(o.cwd);\n if (top && path.resolve(top).toLowerCase() !== path.resolve(o.cwd).toLowerCase()) {\n notes.push('Current directory is inside a Git repository; using the repository root. Pass --root to choose a different directory.');\n return path.resolve(top);\n }\n return path.resolve(o.cwd);\n}\n\n/** Make sure each required line is present in .devworkspace/.gitignore without removing anything the user added. */\nasync function ensureGitignore(ws: Ws): Promise<'created' | 'updated' | 'unchanged'> {\n if (!(await pathExists(ws.gitignore))) {\n await atomicWriteFile(ws.gitignore, LOCAL_GITIGNORE);\n return 'created';\n }\n const text = await fs.readFile(ws.gitignore, 'utf8');\n const have = new Set(text.split(/\\r?\\n/).map((l) => l.trim()));\n const missing = LOCAL_GITIGNORE.split('\\n').filter((l) => l && !l.startsWith('#') && !have.has(l));\n if (missing.length === 0) return 'unchanged';\n const eol = text.includes('\\r\\n') ? '\\r\\n' : '\\n';\n await atomicWriteFile(ws.gitignore, text + (text.endsWith('\\n') ? '' : eol) + missing.join(eol) + eol);\n return 'updated';\n}\n\nexport async function initWorkspace(o: InitOptions): Promise<InitResult> {\n const notes: string[] = [];\n const root = await resolveRoot(o, notes);\n const st = await fs.stat(root).catch(() => null);\n if (!st?.isDirectory()) {\n throw new DevWorkspaceError('NOT_FOUND', `Project root does not exist: ${root}`, { hint: 'Run the command inside your project, or pass --root <dir>.' });\n }\n const ws = wsPaths(root);\n const created: string[] = [];\n const unchanged: string[] = [];\n const rel = (p: string): string => path.relative(root, p).replace(/\\\\/g, '/');\n const alreadyInitialized = await pathExists(ws.projectJson);\n\n const dirs = [ws.contextDir, ws.decisionsDir, ws.tasksActive, ws.tasksCompleted, ws.sessionsDir, ws.analysisDir, ws.stateDir];\n const pkg = (await pathExists(path.join(root, 'package.json'))) ? await readPackageJson(root, 'package.json').catch(() => null) : null;\n const name = pkg?.name ?? path.basename(root);\n const now = isoNow(o);\n\n\n const result = (extra: Partial<InitResult>): InitResult => ({\n root,\n dryRun: !!o.dryRun,\n alreadyInitialized,\n created,\n unchanged,\n gitignoreUpdated: false,\n notes,\n integrations: [],\n nextSteps: ['Run: devworkspace analyze', 'Then paste .devworkspace/analysis/onboarding-prompt.md into Claude Code'],\n ...extra,\n });\n const shallow = async (): Promise<IntegrationReport[]> => inspectAll(ws, managerEnv(o, root), { deep: false });\n\n if (o.dryRun) {\n for (const d of dirs) if (!(await pathExists(d))) created.push(rel(d) + '/');\n if (!alreadyInitialized) created.push(rel(ws.projectJson));\n if (!(await pathExists(ws.gitignore))) created.push(rel(ws.gitignore));\n return result({ integrations: await shallow() });\n }\n\n await ensureDir(ws.dir);\n return withLock(ws.dir, async () => {\n for (const d of dirs) {\n if (await pathExists(d)) unchanged.push(rel(d) + '/');\n else {\n await ensureDir(d);\n created.push(rel(d) + '/');\n }\n }\n // Empty directories do not survive Git, so keep portable folders alive.\n for (const d of [ws.decisionsDir, ws.tasksActive, ws.tasksCompleted, ws.sessionsDir]) {\n const keep = path.join(d, '.gitkeep');\n if (!(await pathExists(keep))) await fs.writeFile(keep, '');\n }\n\n let project: ProjectConfig;\n if (alreadyInitialized) {\n project = await loadProject(ws);\n unchanged.push(rel(ws.projectJson));\n if (project.devworkspaceVersion !== packageVersion()) {\n project = { ...project, devworkspaceVersion: packageVersion(), updatedAt: now };\n await atomicWriteJson(ws.projectJson, validateProject(project));\n notes.push(`Recorded DevWorkspace ${packageVersion()} in project.json.`);\n }\n } else {\n project = {\n schemaVersion: SCHEMA_VERSION,\n projectId: newProjectId(),\n name,\n createdAt: now,\n updatedAt: now,\n devworkspaceVersion: packageVersion(),\n settings: { review: 'light', maxFiles: 50_000 },\n managedFiles: [{ path: `${WORKSPACE_DIR}/.gitignore`, mode: 'owned' }],\n };\n await atomicWriteJson(ws.projectJson, validateProject(project));\n created.push(rel(ws.projectJson));\n }\n\n const gi = await ensureGitignore(ws);\n if (gi === 'created') created.push(rel(ws.gitignore));\n else if (gi === 'updated') notes.push('Added missing ignore rules to .devworkspace/.gitignore.');\n else unchanged.push(rel(ws.gitignore));\n\n let setup: SetupResult | undefined;\n if (o.withIntegrations) {\n setup = await runSetup(ws, managerEnv(o, root), { scope: o.withIntegrations.scope, yes: o.withIntegrations.yes, dryRun: false, repair: false });\n }\n return result({ gitignoreUpdated: gi === 'updated', integrations: setup ? setup.outcomes.map((x) => x.report) : await shallow(), ...(setup ? { setup } : {}) });\n });\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import { type IntegrationId, type IntegrationReport, type InstallScope, type ProgressEvent, type SetupResult } from '../integrations/index.js';
2
+ import { type ServiceOptions } from './common.js';
3
+ export interface SetupRequest {
4
+ yes?: boolean;
5
+ scope?: InstallScope;
6
+ only?: string[];
7
+ repair?: boolean;
8
+ }
9
+ export declare function parseOnly(only: string[] | undefined): IntegrationId[] | undefined;
10
+ /** Install and verify the integrations. Without `yes`, only project-local, non-executing steps may run. */
11
+ export declare function setupIntegrations(o: ServiceOptions, req?: SetupRequest, onEvent?: (e: ProgressEvent) => void): Promise<SetupResult>;
12
+ export interface IntegrationsStatus {
13
+ deep: boolean;
14
+ reports: IntegrationReport[];
15
+ summary: {
16
+ complete: boolean;
17
+ required: number;
18
+ verified: number;
19
+ };
20
+ acknowledged?: string[];
21
+ }
22
+ /** Observed state (never the saved file alone). `deep` runs the tools; shallow only looks at files and PATH. */
23
+ export declare function integrationsStatus(o: ServiceOptions, opts?: {
24
+ deep?: boolean;
25
+ restarted?: boolean;
26
+ }): Promise<IntegrationsStatus>;
@@ -0,0 +1,35 @@
1
+ import { DevWorkspaceError } from '../errors/index.js';
2
+ import { requireWorkspace } from '../core/workspace.js';
3
+ import { INTEGRATION_IDS, acknowledgeRestart, inspectAll, runSetup, summarize, } from '../integrations/index.js';
4
+ import { isoNow, managerEnv } from './common.js';
5
+ export function parseOnly(only) {
6
+ if (!only || only.length === 0)
7
+ return undefined;
8
+ const ids = only.flatMap((s) => s.split(',')).map((s) => s.trim()).filter(Boolean);
9
+ for (const id of ids) {
10
+ if (!INTEGRATION_IDS.includes(id)) {
11
+ throw new DevWorkspaceError('USAGE', `Unknown integration "${id}".`, { hint: `Use: ${INTEGRATION_IDS.join(', ')}.` });
12
+ }
13
+ }
14
+ return ids;
15
+ }
16
+ /** Install and verify the integrations. Without `yes`, only project-local, non-executing steps may run. */
17
+ export async function setupIntegrations(o, req = {}, onEvent) {
18
+ const ws = await requireWorkspace(o.cwd);
19
+ return runSetup(ws, managerEnv(o, ws.root), { scope: req.scope ?? 'project', yes: !!req.yes, dryRun: !!o.dryRun, repair: !!req.repair, only: parseOnly(req.only) }, onEvent);
20
+ }
21
+ /** Observed state (never the saved file alone). `deep` runs the tools; shallow only looks at files and PATH. */
22
+ export async function integrationsStatus(o, opts = {}) {
23
+ const ws = await requireWorkspace(o.cwd);
24
+ const env = managerEnv(o, ws.root);
25
+ let acknowledged;
26
+ if (opts.restarted) {
27
+ const before = await inspectAll(ws, env, { deep: false });
28
+ acknowledged = before.filter((r) => r.status === 'RESTART_REQUIRED').map((r) => r.id);
29
+ await acknowledgeRestart(ws, acknowledged, isoNow(o));
30
+ }
31
+ const reports = await inspectAll(ws, env, { deep: opts.deep ?? true });
32
+ const s = summarize(reports);
33
+ return { deep: opts.deep ?? true, reports, summary: { complete: s.complete, required: s.required, verified: s.verified }, ...(acknowledged ? { acknowledged } : {}) };
34
+ }
35
+ //# sourceMappingURL=integrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrations.js","sourceRoot":"","sources":["../../src/services/integrations.ts"],"names":[],"mappings":"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","sourcesContent":["import { DevWorkspaceError } from '../errors/index.js';\nimport { requireWorkspace } from '../core/workspace.js';\nimport {\n INTEGRATION_IDS,\n acknowledgeRestart,\n inspectAll,\n runSetup,\n summarize,\n type IntegrationId,\n type IntegrationReport,\n type InstallScope,\n type ProgressEvent,\n type SetupResult,\n} from '../integrations/index.js';\nimport { isoNow, managerEnv, type ServiceOptions } from './common.js';\n\nexport interface SetupRequest {\n yes?: boolean;\n scope?: InstallScope;\n only?: string[];\n repair?: boolean;\n}\n\nexport function parseOnly(only: string[] | undefined): IntegrationId[] | undefined {\n if (!only || only.length === 0) return undefined;\n const ids = only.flatMap((s) => s.split(',')).map((s) => s.trim()).filter(Boolean);\n for (const id of ids) {\n if (!(INTEGRATION_IDS as readonly string[]).includes(id)) {\n throw new DevWorkspaceError('USAGE', `Unknown integration \"${id}\".`, { hint: `Use: ${INTEGRATION_IDS.join(', ')}.` });\n }\n }\n return ids as IntegrationId[];\n}\n\n/** Install and verify the integrations. Without `yes`, only project-local, non-executing steps may run. */\nexport async function setupIntegrations(o: ServiceOptions, req: SetupRequest = {}, onEvent?: (e: ProgressEvent) => void): Promise<SetupResult> {\n const ws = await requireWorkspace(o.cwd);\n return runSetup(\n ws,\n managerEnv(o, ws.root),\n { scope: req.scope ?? 'project', yes: !!req.yes, dryRun: !!o.dryRun, repair: !!req.repair, only: parseOnly(req.only) },\n onEvent,\n );\n}\n\nexport interface IntegrationsStatus {\n deep: boolean;\n reports: IntegrationReport[];\n summary: { complete: boolean; required: number; verified: number };\n acknowledged?: string[];\n}\n\n/** Observed state (never the saved file alone). `deep` runs the tools; shallow only looks at files and PATH. */\nexport async function integrationsStatus(o: ServiceOptions, opts: { deep?: boolean; restarted?: boolean } = {}): Promise<IntegrationsStatus> {\n const ws = await requireWorkspace(o.cwd);\n const env = managerEnv(o, ws.root);\n let acknowledged: string[] | undefined;\n if (opts.restarted) {\n const before = await inspectAll(ws, env, { deep: false });\n acknowledged = before.filter((r) => r.status === 'RESTART_REQUIRED').map((r) => r.id);\n await acknowledgeRestart(ws, acknowledged as IntegrationId[], isoNow(o));\n }\n const reports = await inspectAll(ws, env, { deep: opts.deep ?? true });\n const s = summarize(reports);\n return { deep: opts.deep ?? true, reports, summary: { complete: s.complete, required: s.required, verified: s.verified }, ...(acknowledged ? { acknowledged } : {}) };\n}\n"]}
@@ -37,7 +37,7 @@ export async function refreshWorkspace(o) {
37
37
  };
38
38
  }
39
39
  await writeJsonIfChanged(ws.discovery, run.discovery);
40
- await writeCommands(ws, run.discovery.commands);
40
+ await writeCommands(ws, run.discovery.commands, { truncated: run.discovery.scan.truncated });
41
41
  const det = await applyDetectorFacts(ws, run.discovery, now);
42
42
  const facts = await loadFacts(ws);
43
43
  const rep = await applyStaleness(ws.root, facts, now);
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/services/refresh.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { SCHEMA_VERSION, validateAnalysisState, type AnalysisState } from '../config/schemas.js';\nimport { loadProject } from '../core/workspace.js';\nimport { readVersioned, writeVersioned } from '../core/versioned.js';\nimport { packageVersion } from '../core/version.js';\nimport { applyStaleness, loadFacts, saveFacts } from '../knowledge/facts.js';\nimport { buildRefreshPrompt } from '../prompts/refresh.js';\nimport { pathExists, sha256Text, writeJsonIfChanged, writeTextIfChanged } from '../utils/fs.js';\nimport { applyDetectorFacts, runDiscovery, writeCommands } from './analysis.js';\nimport { isoNow, mutate, type ServiceOptions } from './common.js';\n\nexport interface RefreshResult {\n dryRun: boolean;\n headChanged: boolean;\n autoRefreshed: string[];\n retired: string[];\n stale: { key: string; value: string; reason: string }[];\n needsReview: { key: string; reason: string }[];\n prompt: string | null;\n}\n\n/**\n * Incremental refresh. Deterministic facts are re-derived on the spot; everything else is re-hashed against its cited\n * sources and only the facts whose evidence changed become STALE and enter the (optional) agent refresh prompt.\n */\nexport async function refreshWorkspace(o: ServiceOptions): Promise<RefreshResult> {\n return mutate(o, async (ws) => {\n const project = await loadProject(ws);\n const now = isoNow(o);\n const run = await runDiscovery(ws, project.name, project.settings.maxFiles);\n let previous: AnalysisState | null = null;\n if (await pathExists(ws.analysisState)) {\n previous = (await readVersioned(ws.analysisState, 'analysis', SCHEMA_VERSION, validateAnalysisState)).data;\n }\n const headChanged = !!previous && previous.gitHead !== run.gitHead;\n\n if (o.dryRun) {\n const facts = await loadFacts(ws);\n const probe = structuredClone(facts);\n const rep = await applyStaleness(ws.root, probe, now);\n return {\n dryRun: true,\n headChanged,\n autoRefreshed: [],\n retired: [],\n stale: rep.newlyStale.map((s) => ({ ...s, value: probe.facts.find((f) => f.key === s.key)?.value ?? '' })),\n needsReview: rep.needsReview,\n prompt: null,\n };\n }\n\n await writeJsonIfChanged(ws.discovery, run.discovery);\n await writeCommands(ws, run.discovery.commands);\n const det = await applyDetectorFacts(ws, run.discovery, now);\n\n const facts = await loadFacts(ws);\n const rep = await applyStaleness(ws.root, facts, now);\n await saveFacts(ws, facts);\n\n const stale = facts.facts.filter((f) => f.status === 'STALE' && f.sourceType !== 'detector').map((f) => ({ key: f.key, value: f.value, reason: f.staleReason ?? 'evidence changed' }));\n let prompt: string | null = null;\n if (stale.length > 0 || rep.needsReview.length > 0) {\n await writeTextIfChanged(\n ws.refreshPrompt,\n buildRefreshPrompt({ projectName: project.name, stale, needsReview: rep.needsReview, autoRefreshed: det.written, cliVersion: packageVersion() }),\n );\n prompt = path.relative(ws.root, ws.refreshPrompt).replace(/\\\\/g, '/');\n }\n\n const state: AnalysisState = {\n schemaVersion: SCHEMA_VERSION,\n analyzedAt: previous?.analyzedAt ?? now,\n refreshedAt: now,\n gitHead: run.gitHead,\n fileCount: run.discovery.scan.fileCount,\n truncated: run.discovery.scan.truncated,\n discoveryHash: sha256Text(JSON.stringify(run.discovery)),\n };\n await writeVersioned(ws, ws.analysisState, state);\n return { dryRun: false, headChanged, autoRefreshed: det.written, retired: det.retired, stale, needsReview: rep.needsReview, prompt };\n });\n}\n"]}
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/services/refresh.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { SCHEMA_VERSION, validateAnalysisState, type AnalysisState } from '../config/schemas.js';\nimport { loadProject } from '../core/workspace.js';\nimport { readVersioned, writeVersioned } from '../core/versioned.js';\nimport { packageVersion } from '../core/version.js';\nimport { applyStaleness, loadFacts, saveFacts } from '../knowledge/facts.js';\nimport { buildRefreshPrompt } from '../prompts/refresh.js';\nimport { pathExists, sha256Text, writeJsonIfChanged, writeTextIfChanged } from '../utils/fs.js';\nimport { applyDetectorFacts, runDiscovery, writeCommands } from './analysis.js';\nimport { isoNow, mutate, type ServiceOptions } from './common.js';\n\nexport interface RefreshResult {\n dryRun: boolean;\n headChanged: boolean;\n autoRefreshed: string[];\n retired: string[];\n stale: { key: string; value: string; reason: string }[];\n needsReview: { key: string; reason: string }[];\n prompt: string | null;\n}\n\n/**\n * Incremental refresh. Deterministic facts are re-derived on the spot; everything else is re-hashed against its cited\n * sources and only the facts whose evidence changed become STALE and enter the (optional) agent refresh prompt.\n */\nexport async function refreshWorkspace(o: ServiceOptions): Promise<RefreshResult> {\n return mutate(o, async (ws) => {\n const project = await loadProject(ws);\n const now = isoNow(o);\n const run = await runDiscovery(ws, project.name, project.settings.maxFiles);\n let previous: AnalysisState | null = null;\n if (await pathExists(ws.analysisState)) {\n previous = (await readVersioned(ws.analysisState, 'analysis', SCHEMA_VERSION, validateAnalysisState)).data;\n }\n const headChanged = !!previous && previous.gitHead !== run.gitHead;\n\n if (o.dryRun) {\n const facts = await loadFacts(ws);\n const probe = structuredClone(facts);\n const rep = await applyStaleness(ws.root, probe, now);\n return {\n dryRun: true,\n headChanged,\n autoRefreshed: [],\n retired: [],\n stale: rep.newlyStale.map((s) => ({ ...s, value: probe.facts.find((f) => f.key === s.key)?.value ?? '' })),\n needsReview: rep.needsReview,\n prompt: null,\n };\n }\n\n await writeJsonIfChanged(ws.discovery, run.discovery);\n await writeCommands(ws, run.discovery.commands, { truncated: run.discovery.scan.truncated });\n const det = await applyDetectorFacts(ws, run.discovery, now);\n\n const facts = await loadFacts(ws);\n const rep = await applyStaleness(ws.root, facts, now);\n await saveFacts(ws, facts);\n\n const stale = facts.facts.filter((f) => f.status === 'STALE' && f.sourceType !== 'detector').map((f) => ({ key: f.key, value: f.value, reason: f.staleReason ?? 'evidence changed' }));\n let prompt: string | null = null;\n if (stale.length > 0 || rep.needsReview.length > 0) {\n await writeTextIfChanged(\n ws.refreshPrompt,\n buildRefreshPrompt({ projectName: project.name, stale, needsReview: rep.needsReview, autoRefreshed: det.written, cliVersion: packageVersion() }),\n );\n prompt = path.relative(ws.root, ws.refreshPrompt).replace(/\\\\/g, '/');\n }\n\n const state: AnalysisState = {\n schemaVersion: SCHEMA_VERSION,\n analyzedAt: previous?.analyzedAt ?? now,\n refreshedAt: now,\n gitHead: run.gitHead,\n fileCount: run.discovery.scan.fileCount,\n truncated: run.discovery.scan.truncated,\n discoveryHash: sha256Text(JSON.stringify(run.discovery)),\n };\n await writeVersioned(ws, ws.analysisState, state);\n return { dryRun: false, headChanged, autoRefreshed: det.written, retired: det.retired, stale, needsReview: rep.needsReview, prompt };\n });\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { type Ws } from '../core/workspace.js';
2
- import { type IntegrationStatus } from '../integrations/index.js';
2
+ import { type IntegrationReport } from '../integrations/index.js';
3
3
  import { type ServiceOptions } from './common.js';
4
4
  export interface TaskBrief {
5
5
  id: string;
@@ -36,13 +36,15 @@ export interface StatusResult {
36
36
  knowledgeWritten: boolean;
37
37
  ready: boolean;
38
38
  };
39
- integrations: IntegrationStatus[];
39
+ /** Shallow observation (files and PATH only; never VERIFIED). Run doctor or `integrations status` to verify. */
40
+ integrations: IntegrationReport[];
40
41
  activeTasks: TaskBrief[];
41
42
  verification: {
42
43
  id: string;
43
44
  available: boolean;
44
45
  command: string | null;
45
46
  required: string;
47
+ cwd?: string;
46
48
  }[];
47
49
  lastSession: {
48
50
  id: string;
@@ -4,14 +4,14 @@ import { SCHEMA_VERSION, validateAnalysisState, validateCommands } from '../conf
4
4
  import { findWorkspaceRoot, loadProject, wsPaths } from '../core/workspace.js';
5
5
  import { readVersioned } from '../core/versioned.js';
6
6
  import { getGitState } from '../git/git.js';
7
- import { detectIntegrations } from '../integrations/index.js';
7
+ import { inspectAll } from '../integrations/index.js';
8
8
  import { loadFacts } from '../knowledge/facts.js';
9
9
  import { listSessions } from '../sessions/session.js';
10
10
  import { listTasks, nextRequiredStep } from '../tasks/task.js';
11
11
  import { pathExists } from '../utils/fs.js';
12
12
  import { SECTION_END } from '../agents/claude/content.js';
13
13
  import { SKILL_PATH } from '../agents/claude/content.js';
14
- import { integrationCtx } from './common.js';
14
+ import { managerEnv } from './common.js';
15
15
  const brief = (t) => ({ id: t.id, title: t.title, type: t.type, status: t.status, updatedAt: t.updatedAt, next: nextRequiredStep(t) });
16
16
  export async function instructionsInstalled(ws) {
17
17
  for (const rel of ['CLAUDE.md', '.claude/CLAUDE.md']) {
@@ -87,7 +87,7 @@ export async function getStatus(o) {
87
87
  if (await pathExists(ws.commands)) {
88
88
  try {
89
89
  const commands = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data;
90
- base.verification = commands.checks.map((c) => ({ id: c.id, available: c.available, command: c.command, required: c.required }));
90
+ base.verification = commands.checks.map((c) => ({ id: c.id, available: c.available, command: c.command, required: c.required, ...(c.cwd ? { cwd: c.cwd } : {}) }));
91
91
  }
92
92
  catch (e) {
93
93
  base.workspace = 'Needs attention';
@@ -102,7 +102,7 @@ export async function getStatus(o) {
102
102
  const sessions = await listSessions(ws, 1);
103
103
  if (sessions[0])
104
104
  base.lastSession = { id: sessions[0].id, goal: sessions[0].goal, next: sessions[0].next };
105
- base.integrations = await detectIntegrations(integrationCtx(o, root));
105
+ base.integrations = await inspectAll(ws, managerEnv(o, root), { deep: false });
106
106
  base.onboarding.instructionsInstalled = await instructionsInstalled(ws);
107
107
  base.onboarding.knowledgeWritten = await knowledgeWritten(ws);
108
108
  base.onboarding.ready = base.onboarding.instructionsInstalled && base.onboarding.knowledgeWritten && base.knowledge.state !== 'Empty';
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/services/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAqB,MAAM,sBAAsB,CAAC;AAClH,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,EAAW,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAA0B,MAAM,0BAA0B,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAa,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AA2BlE,MAAM,KAAK,GAAG,CAAC,CAAO,EAAa,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAExJ,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAAM;IAChD,KAAK,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YAC9E,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC9J,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAM;IAC3C,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,2GAA2G;AAC3G,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,CAAiB;IAC/C,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAwB;QACpC,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;QACxE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM;KAC5B,CAAC;IACF,MAAM,IAAI,GAAiB;QACzB,WAAW,EAAE,KAAK;QAClB,IAAI;QACJ,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,iBAAiB;QAC5B,GAAG,EAAE,QAAQ;QACb,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE;QACrE,UAAU,EAAE,EAAE,qBAAqB,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;QACnF,YAAY,EAAE,EAAE;QAChB,WAAW,EAAE,EAAE;QACf,YAAY,EAAE,EAAE;QAChB,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE,CAAC;KAChB,CAAC;IACF,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;QAC7D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;IACtF,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;QACrE,IAAI,UAAU,GAAkB,IAAI,CAAC;QACrC,IAAI,MAAM,UAAU,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC;YACvC,UAAU,GAAG,CAAC,MAAM,aAAa,CAAC,EAAE,CAAC,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QAC1H,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACjJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAC;QACnC,IAAI,CAAC,gBAAgB,GAAI,CAAW,CAAC,OAAO,CAAC;IAC/C,CAAC;IAED,IAAI,MAAM,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,CAAC,MAAM,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;YACvG,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAe,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACjJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAC;YACnC,IAAI,CAAC,gBAAgB,KAAM,CAAW,CAAC,OAAO,CAAC;QACjD,CAAC;IACH,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IACnC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAC;IAC3D,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3C,IAAI,QAAQ,CAAC,CAAC,CAAC;QAAE,IAAI,CAAC,WAAW,GAAG,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE3G,IAAI,CAAC,YAAY,GAAG,MAAM,kBAAkB,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACtE,IAAI,CAAC,UAAU,CAAC,qBAAqB,GAAG,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACxE,IAAI,CAAC,UAAU,CAAC,gBAAgB,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,qBAAqB,IAAI,IAAI,CAAC,UAAU,CAAC,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,KAAK,OAAO,CAAC;IACtI,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { SCHEMA_VERSION, validateAnalysisState, validateCommands, type CommandEntry } from '../config/schemas.js';\nimport { findWorkspaceRoot, loadProject, wsPaths, type Ws } from '../core/workspace.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { getGitState } from '../git/git.js';\nimport { detectIntegrations, type IntegrationStatus } from '../integrations/index.js';\nimport { loadFacts } from '../knowledge/facts.js';\nimport { listSessions } from '../sessions/session.js';\nimport { listTasks, nextRequiredStep, type Task } from '../tasks/task.js';\nimport { pathExists } from '../utils/fs.js';\nimport { SECTION_END } from '../agents/claude/content.js';\nimport { SKILL_PATH } from '../agents/claude/content.js';\nimport { integrationCtx, type ServiceOptions } from './common.js';\n\nexport interface TaskBrief {\n id: string;\n title: string;\n type: string;\n status: string;\n updatedAt: string;\n next: string;\n}\n\nexport interface StatusResult {\n initialized: boolean;\n root: string | null;\n project: { name: string; id: string } | null;\n workspace: 'Healthy' | 'Needs attention' | 'Not initialized' | 'Unreadable';\n workspaceProblem?: string;\n git: { available: boolean; isRepo: boolean; branch: string | null; workingTree: 'Clean' | 'Modified' | 'Unknown'; changes: number };\n knowledge: { state: 'Current' | 'Stale' | 'Empty' | 'Unknown'; facts: number; stale: number; analyzedAt: string | null };\n onboarding: { instructionsInstalled: boolean; knowledgeWritten: boolean; ready: boolean };\n integrations: IntegrationStatus[];\n activeTasks: TaskBrief[];\n verification: { id: string; available: boolean; command: string | null; required: string }[];\n lastSession: { id: string; goal: string; next: string } | null;\n corruptTasks: number;\n}\n\nconst brief = (t: Task): TaskBrief => ({ id: t.id, title: t.title, type: t.type, status: t.status, updatedAt: t.updatedAt, next: nextRequiredStep(t) });\n\nexport async function instructionsInstalled(ws: Ws): Promise<boolean> {\n for (const rel of ['CLAUDE.md', '.claude/CLAUDE.md']) {\n try {\n const text = await fs.readFile(path.join(ws.root, ...rel.split('/')), 'utf8');\n if (text.includes('<!-- devworkspace:start') && text.includes(SECTION_END) && (await pathExists(path.join(ws.root, ...SKILL_PATH.split('/'))))) return true;\n } catch {\n /* try next */\n }\n }\n return false;\n}\n\nexport async function knowledgeWritten(ws: Ws): Promise<boolean> {\n try {\n return (await fs.stat(path.join(ws.contextDir, 'architecture.md'))).size >= 200;\n } catch {\n return false;\n }\n}\n\n/** Cheap overview: reads small workspace files and Git status only. Never hashes or scans source files. */\nexport async function getStatus(o: ServiceOptions): Promise<StatusResult> {\n const root = await findWorkspaceRoot(o.cwd);\n const git = await getGitState(root ?? o.cwd);\n const gitBrief: StatusResult['git'] = {\n available: git.available,\n isRepo: git.isRepo,\n branch: git.branch,\n workingTree: git.isRepo ? (git.dirty ? 'Modified' : 'Clean') : 'Unknown',\n changes: git.entries.length,\n };\n const base: StatusResult = {\n initialized: false,\n root,\n project: null,\n workspace: 'Not initialized',\n git: gitBrief,\n knowledge: { state: 'Unknown', facts: 0, stale: 0, analyzedAt: null },\n onboarding: { instructionsInstalled: false, knowledgeWritten: false, ready: false },\n integrations: [],\n activeTasks: [],\n verification: [],\n lastSession: null,\n corruptTasks: 0,\n };\n if (!root) return base;\n\n const ws = wsPaths(root);\n base.initialized = true;\n try {\n const project = await loadProject(ws);\n base.project = { name: project.name, id: project.projectId };\n base.workspace = 'Healthy';\n } catch (e) {\n return { ...base, workspace: 'Unreadable', workspaceProblem: (e as Error).message };\n }\n\n try {\n const facts = await loadFacts(ws);\n const stale = facts.facts.filter((f) => f.status === 'STALE').length;\n let analyzedAt: string | null = null;\n if (await pathExists(ws.analysisState)) {\n analyzedAt = (await readVersioned(ws.analysisState, 'analysis', SCHEMA_VERSION, validateAnalysisState)).data.analyzedAt;\n }\n base.knowledge = { facts: facts.facts.length, stale, analyzedAt, state: facts.facts.length === 0 ? 'Empty' : stale > 0 ? 'Stale' : 'Current' };\n } catch (e) {\n base.workspace = 'Needs attention';\n base.workspaceProblem = (e as Error).message;\n }\n\n if (await pathExists(ws.commands)) {\n try {\n const commands = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data;\n base.verification = commands.checks.map((c: CommandEntry) => ({ id: c.id, available: c.available, command: c.command, required: c.required }));\n } catch (e) {\n base.workspace = 'Needs attention';\n base.workspaceProblem ??= (e as Error).message;\n }\n }\n\n const { tasks, corrupt } = await listTasks(ws);\n base.activeTasks = tasks.map(brief);\n base.corruptTasks = corrupt.length;\n if (corrupt.length > 0) base.workspace = 'Needs attention';\n const sessions = await listSessions(ws, 1);\n if (sessions[0]) base.lastSession = { id: sessions[0].id, goal: sessions[0].goal, next: sessions[0].next };\n\n base.integrations = await detectIntegrations(integrationCtx(o, root));\n base.onboarding.instructionsInstalled = await instructionsInstalled(ws);\n base.onboarding.knowledgeWritten = await knowledgeWritten(ws);\n base.onboarding.ready = base.onboarding.instructionsInstalled && base.onboarding.knowledgeWritten && base.knowledge.state !== 'Empty';\n return base;\n}\n"]}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/services/status.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { SCHEMA_VERSION, validateAnalysisState, validateCommands, type CommandEntry } from '../config/schemas.js';\nimport { findWorkspaceRoot, loadProject, wsPaths, type Ws } from '../core/workspace.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { getGitState } from '../git/git.js';\nimport { inspectAll, type IntegrationReport } from '../integrations/index.js';\nimport { loadFacts } from '../knowledge/facts.js';\nimport { listSessions } from '../sessions/session.js';\nimport { listTasks, nextRequiredStep, type Task } from '../tasks/task.js';\nimport { pathExists } from '../utils/fs.js';\nimport { SECTION_END } from '../agents/claude/content.js';\nimport { SKILL_PATH } from '../agents/claude/content.js';\nimport { managerEnv, type ServiceOptions } from './common.js';\n\nexport interface TaskBrief {\n id: string;\n title: string;\n type: string;\n status: string;\n updatedAt: string;\n next: string;\n}\n\nexport interface StatusResult {\n initialized: boolean;\n root: string | null;\n project: { name: string; id: string } | null;\n workspace: 'Healthy' | 'Needs attention' | 'Not initialized' | 'Unreadable';\n workspaceProblem?: string;\n git: { available: boolean; isRepo: boolean; branch: string | null; workingTree: 'Clean' | 'Modified' | 'Unknown'; changes: number };\n knowledge: { state: 'Current' | 'Stale' | 'Empty' | 'Unknown'; facts: number; stale: number; analyzedAt: string | null };\n onboarding: { instructionsInstalled: boolean; knowledgeWritten: boolean; ready: boolean };\n /** Shallow observation (files and PATH only; never VERIFIED). Run doctor or `integrations status` to verify. */\n integrations: IntegrationReport[];\n activeTasks: TaskBrief[];\n verification: { id: string; available: boolean; command: string | null; required: string; cwd?: string }[];\n lastSession: { id: string; goal: string; next: string } | null;\n corruptTasks: number;\n}\n\nconst brief = (t: Task): TaskBrief => ({ id: t.id, title: t.title, type: t.type, status: t.status, updatedAt: t.updatedAt, next: nextRequiredStep(t) });\n\nexport async function instructionsInstalled(ws: Ws): Promise<boolean> {\n for (const rel of ['CLAUDE.md', '.claude/CLAUDE.md']) {\n try {\n const text = await fs.readFile(path.join(ws.root, ...rel.split('/')), 'utf8');\n if (text.includes('<!-- devworkspace:start') && text.includes(SECTION_END) && (await pathExists(path.join(ws.root, ...SKILL_PATH.split('/'))))) return true;\n } catch {\n /* try next */\n }\n }\n return false;\n}\n\nexport async function knowledgeWritten(ws: Ws): Promise<boolean> {\n try {\n return (await fs.stat(path.join(ws.contextDir, 'architecture.md'))).size >= 200;\n } catch {\n return false;\n }\n}\n\n/** Cheap overview: reads small workspace files and Git status only. Never hashes or scans source files. */\nexport async function getStatus(o: ServiceOptions): Promise<StatusResult> {\n const root = await findWorkspaceRoot(o.cwd);\n const git = await getGitState(root ?? o.cwd);\n const gitBrief: StatusResult['git'] = {\n available: git.available,\n isRepo: git.isRepo,\n branch: git.branch,\n workingTree: git.isRepo ? (git.dirty ? 'Modified' : 'Clean') : 'Unknown',\n changes: git.entries.length,\n };\n const base: StatusResult = {\n initialized: false,\n root,\n project: null,\n workspace: 'Not initialized',\n git: gitBrief,\n knowledge: { state: 'Unknown', facts: 0, stale: 0, analyzedAt: null },\n onboarding: { instructionsInstalled: false, knowledgeWritten: false, ready: false },\n integrations: [],\n activeTasks: [],\n verification: [],\n lastSession: null,\n corruptTasks: 0,\n };\n if (!root) return base;\n\n const ws = wsPaths(root);\n base.initialized = true;\n try {\n const project = await loadProject(ws);\n base.project = { name: project.name, id: project.projectId };\n base.workspace = 'Healthy';\n } catch (e) {\n return { ...base, workspace: 'Unreadable', workspaceProblem: (e as Error).message };\n }\n\n try {\n const facts = await loadFacts(ws);\n const stale = facts.facts.filter((f) => f.status === 'STALE').length;\n let analyzedAt: string | null = null;\n if (await pathExists(ws.analysisState)) {\n analyzedAt = (await readVersioned(ws.analysisState, 'analysis', SCHEMA_VERSION, validateAnalysisState)).data.analyzedAt;\n }\n base.knowledge = { facts: facts.facts.length, stale, analyzedAt, state: facts.facts.length === 0 ? 'Empty' : stale > 0 ? 'Stale' : 'Current' };\n } catch (e) {\n base.workspace = 'Needs attention';\n base.workspaceProblem = (e as Error).message;\n }\n\n if (await pathExists(ws.commands)) {\n try {\n const commands = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data;\n base.verification = commands.checks.map((c: CommandEntry) => ({ id: c.id, available: c.available, command: c.command, required: c.required, ...(c.cwd ? { cwd: c.cwd } : {}) }));\n } catch (e) {\n base.workspace = 'Needs attention';\n base.workspaceProblem ??= (e as Error).message;\n }\n }\n\n const { tasks, corrupt } = await listTasks(ws);\n base.activeTasks = tasks.map(brief);\n base.corruptTasks = corrupt.length;\n if (corrupt.length > 0) base.workspace = 'Needs attention';\n const sessions = await listSessions(ws, 1);\n if (sessions[0]) base.lastSession = { id: sessions[0].id, goal: sessions[0].goal, next: sessions[0].next };\n\n base.integrations = await inspectAll(ws, managerEnv(o, root), { deep: false });\n base.onboarding.instructionsInstalled = await instructionsInstalled(ws);\n base.onboarding.knowledgeWritten = await knowledgeWritten(ws);\n base.onboarding.ready = base.onboarding.instructionsInstalled && base.onboarding.knowledgeWritten && base.knowledge.state !== 'Empty';\n return base;\n}\n"]}
@@ -1,6 +1,8 @@
1
1
  export interface LockOptions {
2
2
  timeoutMs?: number;
3
3
  staleMs?: number;
4
+ /** Lock file name under .devworkspace/local/. Long-running operations use their own lock. */
5
+ name?: string;
4
6
  }
5
7
  /** Exclusive advisory lock stored under .devworkspace/local/. Stale locks (dead pid or too old) are broken. */
6
8
  export declare function withLock<T>(workspaceDir: string, fn: () => Promise<T>, opts?: LockOptions): Promise<T>;
@@ -17,7 +17,7 @@ export async function withLock(workspaceDir, fn, opts = {}) {
17
17
  const timeoutMs = opts.timeoutMs ?? 5000;
18
18
  const staleMs = opts.staleMs ?? 60_000;
19
19
  const dir = path.join(workspaceDir, 'local');
20
- const lockPath = path.join(dir, 'workspace.lock');
20
+ const lockPath = path.join(dir, opts.name ?? 'workspace.lock');
21
21
  await ensureDir(dir);
22
22
  const started = Date.now();
23
23
  for (;;) {
@@ -52,7 +52,7 @@ export async function withLock(workspaceDir, fn, opts = {}) {
52
52
  }
53
53
  if (Date.now() - started > timeoutMs) {
54
54
  throw new DevWorkspaceError('LOCKED', 'Another DevWorkspace process is modifying this workspace.', {
55
- hint: `Wait for it to finish, or delete ${path.join('.devworkspace', 'local', 'workspace.lock')} if no process is running.`,
55
+ hint: `Wait for it to finish, or delete ${path.join('.devworkspace', 'local', opts.name ?? 'workspace.lock')} if no process is running.`,
56
56
  });
57
57
  }
58
58
  await new Promise((r) => setTimeout(r, 50));