devworkspace 0.3.1 → 0.3.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 (73) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/README.md +3 -1
  3. package/dist/cli/args.d.ts +42 -0
  4. package/dist/cli/args.js +12 -0
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli/help.js +52 -5
  7. package/dist/cli/help.js.map +1 -1
  8. package/dist/cli/render.d.ts +10 -0
  9. package/dist/cli/render.js +167 -0
  10. package/dist/cli/render.js.map +1 -1
  11. package/dist/cli/run.js +84 -4
  12. package/dist/cli/run.js.map +1 -1
  13. package/dist/config/schemas.d.ts +6 -0
  14. package/dist/config/schemas.js +6 -0
  15. package/dist/config/schemas.js.map +1 -1
  16. package/dist/core/version.d.ts +7 -0
  17. package/dist/core/version.js +13 -0
  18. package/dist/core/version.js.map +1 -1
  19. package/dist/core/workspace.d.ts +1 -0
  20. package/dist/core/workspace.js +1 -0
  21. package/dist/core/workspace.js.map +1 -1
  22. package/dist/discovery/commands.d.ts +1 -0
  23. package/dist/discovery/commands.js +3 -1
  24. package/dist/discovery/commands.js.map +1 -1
  25. package/dist/features/schema.d.ts +3 -0
  26. package/dist/features/schema.js +79 -0
  27. package/dist/features/schema.js.map +1 -0
  28. package/dist/features/types.d.ts +77 -0
  29. package/dist/features/types.js +2 -0
  30. package/dist/features/types.js.map +1 -0
  31. package/dist/features/validate.d.ts +14 -0
  32. package/dist/features/validate.js +124 -0
  33. package/dist/features/validate.js.map +1 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.js +3 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/services/doctor.js +34 -0
  38. package/dist/services/doctor.js.map +1 -1
  39. package/dist/services/drift.d.ts +21 -0
  40. package/dist/services/drift.js +89 -0
  41. package/dist/services/drift.js.map +1 -0
  42. package/dist/services/features.d.ts +22 -0
  43. package/dist/services/features.js +105 -0
  44. package/dist/services/features.js.map +1 -0
  45. package/dist/services/graph.d.ts +97 -0
  46. package/dist/services/graph.js +342 -0
  47. package/dist/services/graph.js.map +1 -0
  48. package/dist/services/refresh.js +15 -0
  49. package/dist/services/refresh.js.map +1 -1
  50. package/dist/services/setup.d.ts +56 -0
  51. package/dist/services/setup.js +116 -0
  52. package/dist/services/setup.js.map +1 -0
  53. package/dist/services/status.d.ts +6 -0
  54. package/dist/services/status.js +16 -0
  55. package/dist/services/status.js.map +1 -1
  56. package/dist/services/verify.d.ts +11 -0
  57. package/dist/services/verify.js +64 -2
  58. package/dist/services/verify.js.map +1 -1
  59. package/docs/architecture-report/01-executive-summary.md +168 -0
  60. package/docs/architecture-report/02-system-architecture.md +356 -0
  61. package/docs/architecture-report/03-tools-and-technologies.md +112 -0
  62. package/docs/architecture-report/04-execution-flows.md +257 -0
  63. package/docs/architecture-report/05-codebase-map.md +150 -0
  64. package/docs/architecture-report/06-command-reference.md +446 -0
  65. package/docs/architecture-report/07-data-flow-and-integrations.md +268 -0
  66. package/docs/architecture-report/08-build-test-deployment.md +185 -0
  67. package/docs/architecture-report/09-security-and-reliability.md +165 -0
  68. package/docs/architecture-report/10-feature-status.md +110 -0
  69. package/docs/architecture-report/11-glossary.md +97 -0
  70. package/docs/architecture-report/README.md +103 -0
  71. package/docs/architecture-report/diagrams.md +446 -0
  72. package/docs/getting-started.md +38 -1
  73. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/services/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,UAAU,EAAuB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAW7D,MAAM,UAAU,mBAAmB;IACjC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACzC,IAAI,IAAI,GAAqB,mBAAmB,CAAC;IACjD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACzD,IAAI,GAAG,WAAW,CAAC;IACrB,CAAC;SAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC3H,IAAI,GAAG,iBAAiB,CAAC;IAC3B,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC5D,CAAC;AAuCD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,CAAiB;IAClD,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7D,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,YAAY,IAAI,QAAQ,CAAC;IACtC,MAAM,UAAU,GAAG,CAAC,YAAY,CAAC;IACjC,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;IAElC,4CAA4C;IAC5C,MAAM,aAAa,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/C,qFAAqF;IACrF,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAEjE,wEAAwE;IACxE,MAAM,WAAW,GAAG,MAAM,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpF,MAAM,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAE/E,qCAAqC;IACrC,IAAI,eAAe,GAAmC,IAAI,CAAC;IAC3D,IAAI,MAAM,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,YAAY,CAAC,EAAE,CAAC,CAAC;YACjC,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC1D,eAAe,GAAG;gBAChB,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,eAAe,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACzE,CAAC;IACH,CAAC;IAED,2FAA2F;IAC3F,MAAM,mBAAmB,GAAG,MAAM,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvF,MAAM,YAAY,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;KACrB,CAAC,CAAC,CAAC;IAEJ,4BAA4B;IAC5B,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1D,wBAAwB;IACxB,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;QACzB,SAAS,CAAC,IAAI,CAAC,6GAA6G,CAAC,CAAC;IAChI,CAAC;IACD,MAAM,eAAe,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC;IACtG,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,SAAS,CAAC,IAAI,CAAC,mFAAmF,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtJ,CAAC;IACD,SAAS,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;IAC7E,SAAS,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IAE5F,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;IAEtC,OAAO;QACL,IAAI;QACJ,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC,QAAQ,GAAG;QACxD,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;QAClC,GAAG;QACH,WAAW,EAAE,IAAI;QACjB,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,IAAI;QACzB,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzD,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,cAAc,EAAE,CAAC,CAAC,cAAc;SACjC,CAAC,CAAC;QACH,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,YAAY,EAAE;YACZ,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM;YACzC,SAAS,EAAE,eAAe,CAAC,MAAM;YACjC,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,KAAK,EAAE,WAAW,CAAC,MAAM;SAC1B;QACD,QAAQ,EAAE,eAAe;QACzB,YAAY;QACZ,MAAM,EAAE;YACN,OAAO,EAAE,YAAY,CAAC,OAAO;YAC7B,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI;YAChC,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI;YAClC,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI;SACnC;QACD,SAAS;KACV,CAAC;AACJ,CAAC","sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { packageVersion } from '../core/version.js';\nimport { findWorkspaceRoot, loadProject, wsPaths } from '../core/workspace.js';\nimport { detectContractDrift } from '../discovery/commands.js';\nimport { inspectAll } from '../integrations/index.js';\nimport { pathExists } from '../utils/fs.js';\nimport { analyzeWorkspace } from './analysis.js';\nimport { managerEnv, type ServiceOptions } from './common.js';\nimport { runDoctor } from './doctor.js';\nimport { loadFeatures } from './features.js';\nimport { initWorkspace } from './init.js';\nimport { validateFeatureMap } from '../features/validate.js';\nimport type { ContractDriftItem } from '../discovery/commands.js';\n\nexport type CliExecutionMode = 'source-checkout' | 'installed-package' | 'npx-cache';\n\nexport interface CliProvenance {\n version: string;\n path: string;\n mode: CliExecutionMode;\n}\n\nexport function detectCliProvenance(): CliProvenance {\n const cliPath = process.argv[1] ? path.resolve(process.argv[1]) : 'unknown';\n const norm = cliPath.replace(/\\\\/g, '/');\n let mode: CliExecutionMode = 'installed-package';\n if (norm.includes('/_npx/') || norm.includes('\\\\_npx\\\\')) {\n mode = 'npx-cache';\n } else if (norm.includes('/devworkspace/dist/') || norm.endsWith('/dist/cli/main.js') || norm.endsWith('/src/cli/main.ts')) {\n mode = 'source-checkout';\n }\n return { version: packageVersion(), path: cliPath, mode };\n}\n\nexport interface ProjectSetupResult {\n root: string;\n os: string;\n nodeVersion: string;\n cli: CliProvenance;\n initialized: boolean;\n isFirstRun: boolean;\n projectName: string;\n packages: { path: string; ecosystem: string; packageManager?: string }[];\n frameworks: string[];\n verification: {\n total: number;\n available: number;\n checks: string[];\n drift: ContractDriftItem[];\n };\n features: {\n present: boolean;\n total: number;\n verified: number;\n unknown: number;\n } | null;\n integrations: {\n id: string;\n name: string;\n status: string;\n required: boolean;\n }[];\n doctor: {\n healthy: boolean;\n passed: number;\n warnings: number;\n failures: number;\n };\n nextSteps: string[];\n}\n\n/**\n * Single-command setup workflow.\n * Idempotently inspects repository, initializes or safely updates .devworkspace/,\n * discovers packages & commands, checks for drift, validates feature map if present,\n * observes optional integrations, and runs safe diagnostics.\n */\nexport async function setupProject(o: ServiceOptions): Promise<ProjectSetupResult> {\n const startDir = o.cwd ? path.resolve(o.cwd) : process.cwd();\n const existingRoot = await findWorkspaceRoot(startDir);\n const root = existingRoot ?? startDir;\n const isFirstRun = !existingRoot;\n const cli = detectCliProvenance();\n\n // 1. Initialize workspace non-destructively\n await initWorkspace({ ...o, cwd: root, root });\n\n // 2. Discover packages, commands, frameworks, entrypoints, and derive detector facts\n const ws = wsPaths(root);\n const analysis = await analyzeWorkspace(ws, { ...o, cwd: root });\n\n // 3. Inspect configured verification commands and detect contract drift\n const driftReport = await detectContractDrift(ws.root, analysis.discovery.commands);\n const availableChecks = analysis.discovery.commands.filter((c) => c.available);\n\n // 4. Validate feature map if present\n let featuresSummary: ProjectSetupResult['features'] = null;\n if (await pathExists(ws.features)) {\n try {\n const f = await loadFeatures(ws);\n const rep = await validateFeatureMap(ws.root, f.features);\n featuresSummary = {\n present: true,\n total: rep.total,\n verified: rep.verified,\n unknown: rep.unknown,\n };\n } catch {\n featuresSummary = { present: true, total: 0, verified: 0, unknown: 0 };\n }\n }\n\n // 5. Shallowly observe optional integrations (Graphify, Agent Skills, Ponytail, OmniRoute)\n const integrationsReports = await inspectAll(ws, managerEnv(o, root), { deep: false });\n const integrations = integrationsReports.map((r) => ({\n id: r.id,\n name: r.name,\n status: r.status,\n required: r.required,\n }));\n\n // 6. Run doctor diagnostics\n const doctorResult = await runDoctor({ ...o, cwd: root });\n\n // 7. Compile next steps\n const nextSteps: string[] = [];\n if (driftReport.hasDrift) {\n nextSteps.push('Review verification contract drift: run \"devworkspace refresh\" or edit .devworkspace/context/commands.json.');\n }\n const missingRequired = integrationsReports.filter((r) => r.required && r.status === 'NOT_INSTALLED');\n if (missingRequired.length > 0) {\n nextSteps.push(`Optional integrations: run \"devworkspace setup --integrations --yes\" to install ${missingRequired.map((m) => m.name).join(', ')}.`);\n }\n nextSteps.push('Check overall workspace health: run \"devworkspace status\".');\n nextSteps.push('Start your first engineering task: run \"devworkspace task new <request>\".');\n\n const project = await loadProject(ws);\n\n return {\n root,\n os: `${os.type()} ${os.release()} (${process.platform})`,\n nodeVersion: process.versions.node,\n cli,\n initialized: true,\n isFirstRun,\n projectName: project.name,\n packages: analysis.discovery.monorepo.packages.map((p) => ({\n path: p.path,\n ecosystem: p.ecosystem,\n packageManager: p.packageManager,\n })),\n frameworks: analysis.discovery.frameworks.map((f) => f.name),\n verification: {\n total: analysis.discovery.commands.length,\n available: availableChecks.length,\n checks: [...new Set(availableChecks.map((c) => c.id))],\n drift: driftReport.issues,\n },\n features: featuresSummary,\n integrations,\n doctor: {\n healthy: doctorResult.healthy,\n passed: doctorResult.counts.pass,\n warnings: doctorResult.counts.warn,\n failures: doctorResult.counts.fail,\n },\n nextSteps,\n };\n}\n"]}
@@ -54,6 +54,12 @@ export interface StatusResult {
54
54
  cwd?: string;
55
55
  mutates?: boolean;
56
56
  }[];
57
+ features?: {
58
+ total: number;
59
+ verified: number;
60
+ inferred: number;
61
+ unknown: number;
62
+ } | null;
57
63
  lastSession: {
58
64
  id: string;
59
65
  goal: string;
@@ -12,6 +12,7 @@ import { pathExists } from '../utils/fs.js';
12
12
  import { SECTION_START, SECTION_END } from '../agents/shared.js';
13
13
  import { SKILL_PATH } from '../agents/claude/content.js';
14
14
  import { listAgentAdapters } from '../agents/index.js';
15
+ import { loadFeatures } from './features.js';
15
16
  import { isoNow, managerEnv } from './common.js';
16
17
  const brief = (t) => ({ id: t.id, title: t.title, type: t.type, status: t.status, updatedAt: t.updatedAt, next: nextRequiredStep(t) });
17
18
  export async function detectInstalledAgents(ws) {
@@ -156,6 +157,21 @@ export async function getStatus(o, opts = {}) {
156
157
  const sessions = await listSessions(ws, 1);
157
158
  if (sessions[0])
158
159
  base.lastSession = { id: sessions[0].id, goal: sessions[0].goal, next: sessions[0].next };
160
+ if (await pathExists(ws.features)) {
161
+ try {
162
+ const f = await loadFeatures(ws);
163
+ const v = f.features.filter((x) => x.status === 'verified').length;
164
+ const inf = f.features.filter((x) => x.status === 'inferred').length;
165
+ const unk = f.features.filter((x) => x.status === 'unknown').length;
166
+ base.features = { total: f.features.length, verified: v, inferred: inf, unknown: unk };
167
+ }
168
+ catch {
169
+ base.features = null;
170
+ }
171
+ }
172
+ else {
173
+ base.features = null;
174
+ }
159
175
  base.integrations = await inspectAll(ws, managerEnv(o, root), { deep: !!opts.deep });
160
176
  base.onboarding.instructionsInstalled = await instructionsInstalled(ws);
161
177
  base.onboarding.knowledgeWritten = await knowledgeWritten(ws);
@@ -1 +1 @@
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 { evaluateStaleness, 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_START, SECTION_END } from '../agents/shared.js';\nimport { SKILL_PATH } from '../agents/claude/content.js';\nimport { listAgentAdapters } from '../agents/index.js';\nimport type { AgentAdapter } from '../agents/types.js';\nimport { isoNow, 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; staleItems: { key: string; reason: string; recorded: boolean }[]; needsReview: number };\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; mutates?: boolean }[];\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 detectInstalledAgents(ws: Ws): Promise<AgentAdapter[]> {\n const installed: AgentAdapter[] = [];\n for (const adapter of listAgentAdapters()) {\n if (adapter.id === 'claude') {\n let claudeFound = false;\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(SECTION_START) && text.includes(SECTION_END) && (await pathExists(path.join(ws.root, ...SKILL_PATH.split('/'))))) {\n claudeFound = true;\n break;\n }\n } catch {\n /* try next */\n }\n }\n if (claudeFound) installed.push(adapter);\n } else if (adapter.id === 'codex') {\n try {\n const text = await fs.readFile(path.join(ws.root, 'AGENTS.md'), 'utf8');\n if (text.includes(SECTION_START) && text.includes(SECTION_END)) installed.push(adapter);\n } catch {\n /* not found */\n }\n } else if (adapter.id === 'cursor') {\n let cursorFound = false;\n for (const rel of ['.cursor/rules/devworkspace.mdc', '.cursorrules']) {\n try {\n const text = await fs.readFile(path.join(ws.root, ...rel.split('/')), 'utf8');\n if (text.includes(SECTION_START) && text.includes(SECTION_END)) {\n cursorFound = true;\n break;\n }\n } catch {\n /* try next */\n }\n }\n if (cursorFound) installed.push(adapter);\n } else if (adapter.id === 'copilot') {\n try {\n const text = await fs.readFile(path.join(ws.root, '.github', 'copilot-instructions.md'), 'utf8');\n if (text.includes(SECTION_START) && text.includes(SECTION_END)) installed.push(adapter);\n } catch {\n /* not found */\n }\n }\n }\n return installed;\n}\n\nexport async function instructionsInstalled(ws: Ws): Promise<boolean> {\n const installed = await detectInstalledAgents(ws);\n return installed.length > 0;\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: small workspace files, Git status and a fingerprint check of the few files facts cite. Never scans the repository. */\nexport async function getStatus(o: ServiceOptions, opts: { deep?: boolean } = {}): 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, staleItems: [], needsReview: 0 },\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 view = await evaluateStaleness(ws.root, facts, isoNow(o));\n const items = [...view.recorded.map((x) => ({ ...x, recorded: true })), ...view.detected.map((x) => ({ ...x, recorded: false }))];\n const stale = items.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, staleItems: items, needsReview: view.needsReview.length, 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 } : {}), ...(c.mutates !== undefined ? { mutates: c.mutates } : {}) }));\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: !!opts.deep });\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 { evaluateStaleness, 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_START, SECTION_END } from '../agents/shared.js';\nimport { SKILL_PATH } from '../agents/claude/content.js';\nimport { listAgentAdapters } from '../agents/index.js';\nimport type { AgentAdapter } from '../agents/types.js';\nimport { loadFeatures } from './features.js';\nimport { isoNow, 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; staleItems: { key: string; reason: string; recorded: boolean }[]; needsReview: number };\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; mutates?: boolean }[];\n features?: { total: number; verified: number; inferred: number; unknown: number } | null;\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 detectInstalledAgents(ws: Ws): Promise<AgentAdapter[]> {\n const installed: AgentAdapter[] = [];\n for (const adapter of listAgentAdapters()) {\n if (adapter.id === 'claude') {\n let claudeFound = false;\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(SECTION_START) && text.includes(SECTION_END) && (await pathExists(path.join(ws.root, ...SKILL_PATH.split('/'))))) {\n claudeFound = true;\n break;\n }\n } catch {\n /* try next */\n }\n }\n if (claudeFound) installed.push(adapter);\n } else if (adapter.id === 'codex') {\n try {\n const text = await fs.readFile(path.join(ws.root, 'AGENTS.md'), 'utf8');\n if (text.includes(SECTION_START) && text.includes(SECTION_END)) installed.push(adapter);\n } catch {\n /* not found */\n }\n } else if (adapter.id === 'cursor') {\n let cursorFound = false;\n for (const rel of ['.cursor/rules/devworkspace.mdc', '.cursorrules']) {\n try {\n const text = await fs.readFile(path.join(ws.root, ...rel.split('/')), 'utf8');\n if (text.includes(SECTION_START) && text.includes(SECTION_END)) {\n cursorFound = true;\n break;\n }\n } catch {\n /* try next */\n }\n }\n if (cursorFound) installed.push(adapter);\n } else if (adapter.id === 'copilot') {\n try {\n const text = await fs.readFile(path.join(ws.root, '.github', 'copilot-instructions.md'), 'utf8');\n if (text.includes(SECTION_START) && text.includes(SECTION_END)) installed.push(adapter);\n } catch {\n /* not found */\n }\n }\n }\n return installed;\n}\n\nexport async function instructionsInstalled(ws: Ws): Promise<boolean> {\n const installed = await detectInstalledAgents(ws);\n return installed.length > 0;\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: small workspace files, Git status and a fingerprint check of the few files facts cite. Never scans the repository. */\nexport async function getStatus(o: ServiceOptions, opts: { deep?: boolean } = {}): 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, staleItems: [], needsReview: 0 },\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 view = await evaluateStaleness(ws.root, facts, isoNow(o));\n const items = [...view.recorded.map((x) => ({ ...x, recorded: true })), ...view.detected.map((x) => ({ ...x, recorded: false }))];\n const stale = items.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, staleItems: items, needsReview: view.needsReview.length, 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 } : {}), ...(c.mutates !== undefined ? { mutates: c.mutates } : {}) }));\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 if (await pathExists(ws.features)) {\n try {\n const f = await loadFeatures(ws);\n const v = f.features.filter((x) => x.status === 'verified').length;\n const inf = f.features.filter((x) => x.status === 'inferred').length;\n const unk = f.features.filter((x) => x.status === 'unknown').length;\n base.features = { total: f.features.length, verified: v, inferred: inf, unknown: unk };\n } catch {\n base.features = null;\n }\n } else {\n base.features = null;\n }\n\n base.integrations = await inspectAll(ws, managerEnv(o, root), { deep: !!opts.deep });\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"]}
@@ -22,6 +22,17 @@ export interface RunCheckResult {
22
22
  check: string;
23
23
  runs: PackageRun[];
24
24
  }
25
+ /** Check if a contract check represents an automated test suite. */
26
+ export declare function isTestCommand(id: string, command: string): boolean;
27
+ export interface ZeroTestResult {
28
+ isZeroTests: boolean;
29
+ reason?: string;
30
+ }
31
+ /**
32
+ * Detects known zero-test execution signatures from test runners (Vitest, Jest, Pytest, Mocha, Go, Cargo).
33
+ * Prevents commands that exit with code 0 because no tests were found (e.g. --passWithNoTests) from falsely passing.
34
+ */
35
+ export declare function detectZeroTests(command: string, stdout: string, stderr: string): ZeroTestResult;
25
36
  export declare function splitCommand(command: string): string[] | null;
26
37
  /**
27
38
  * PATH lookup on Windows finds the extensionless Unix shell script (`npm`) before `npm.cmd`, and that cannot be
@@ -21,6 +21,60 @@ export async function gateContext(ws, task, contract) {
21
21
  const scope = task.scope ? scopeByPackage(await changedSince(ws.root, task.scope), checks) : null;
22
22
  return { contract: checks, scope };
23
23
  }
24
+ /** Check if a contract check represents an automated test suite. */
25
+ export function isTestCommand(id, command) {
26
+ if (id === 'unit' || id === 'integration' || id === 'e2e' || id === 'security')
27
+ return true;
28
+ return /\b(test|vitest|jest|pytest|playwright|cypress|mocha|ava|tap)\b/i.test(command);
29
+ }
30
+ /**
31
+ * Detects known zero-test execution signatures from test runners (Vitest, Jest, Pytest, Mocha, Go, Cargo).
32
+ * Prevents commands that exit with code 0 because no tests were found (e.g. --passWithNoTests) from falsely passing.
33
+ */
34
+ export function detectZeroTests(command, stdout, stderr) {
35
+ const combined = `${stdout}\n${stderr}`;
36
+ const hasPassWithNoTests = /--passWithNoTests\b|--pass-with-no-tests\b/i.test(command);
37
+ // 1. Vitest zero-test patterns
38
+ if (/No test files found/i.test(combined)) {
39
+ return { isZeroTests: true, reason: 'Vitest reported no test files found' };
40
+ }
41
+ if (/Test Files\s+0\s+passed\s*\(0\)/i.test(combined) || /Test Files\s+0\s+failed\s*\(0\)/i.test(combined)) {
42
+ return { isZeroTests: true, reason: 'Vitest ran 0 test files' };
43
+ }
44
+ if (/Tests\s+0\s+passed\s*\(0\)/i.test(combined) && !/Tests\s+[1-9]\d*\s+passed/i.test(combined)) {
45
+ return { isZeroTests: true, reason: 'Vitest ran 0 tests' };
46
+ }
47
+ // 2. Jest zero-test patterns
48
+ if (/Ran all test suites matching.*No tests found/i.test(combined)) {
49
+ return { isZeroTests: true, reason: 'Jest found no test suites matching path' };
50
+ }
51
+ if (/Test Suites:\s*0\s*(?:passed,\s*)?0\s*total/i.test(combined) || /Test Suites:\s*0\s*total/i.test(combined)) {
52
+ return { isZeroTests: true, reason: 'Jest ran 0 test suites' };
53
+ }
54
+ if (/Tests:\s*0\s*(?:passed,\s*)?0\s*total/i.test(combined) || /Tests:\s*0\s*total/i.test(combined)) {
55
+ return { isZeroTests: true, reason: 'Jest ran 0 tests' };
56
+ }
57
+ // 3. Pytest zero-test patterns
58
+ if (/collected 0 items/i.test(combined) || /no tests ran in/i.test(combined)) {
59
+ return { isZeroTests: true, reason: 'Pytest collected and ran 0 items' };
60
+ }
61
+ // 4. Mocha / Node test runner zero-test patterns
62
+ if (/\b0 passing\b/i.test(combined) && !/[1-9]\d*\s+passing\b/i.test(combined)) {
63
+ return { isZeroTests: true, reason: 'Mocha reported 0 passing tests' };
64
+ }
65
+ // 5. Go / Cargo / other zero-test patterns
66
+ if (/\[no test files\]/i.test(combined)) {
67
+ return { isZeroTests: true, reason: 'Go test reported [no test files]' };
68
+ }
69
+ if (/running 0 tests/i.test(combined) && !/running [1-9]\d* tests/i.test(combined)) {
70
+ return { isZeroTests: true, reason: 'Cargo test ran 0 tests' };
71
+ }
72
+ // 6. Explicit passWithNoTests with no tests indicated
73
+ if (hasPassWithNoTests && (/no tests\b/i.test(combined) || /0 tests\b/i.test(combined) || /0 total\b/i.test(combined))) {
74
+ return { isZeroTests: true, reason: 'Command used --passWithNoTests and executed 0 tests' };
75
+ }
76
+ return { isZeroTests: false };
77
+ }
24
78
  /** Anything a shell would interpret. Contract commands are run as an argument vector, never through a shell. */
25
79
  const SHELL_SYNTAX = /[&|;<>$`(){}"'\\*?!%^\r\n]/;
26
80
  export function splitCommand(command) {
@@ -102,8 +156,16 @@ export async function runTaskCheck(o, id, check, opts = {}) {
102
156
  runs.push({ ...base, outcome: 'refused', safety: cls.safety, reason: `could not start: ${scrub(r.error)}` });
103
157
  continue;
104
158
  }
105
- const passed = r.ok && r.code === 0;
106
- const tail = passed ? undefined : scrub((r.error ?? '') || (r.timedOut ? 'timed out' : '') || r.stderr.slice(-300) || r.stdout.slice(-300) || `exit ${r.code}`);
159
+ const zeroTestResult = isTestCommand(entry.id, entry.command ?? '')
160
+ ? detectZeroTests(entry.command ?? '', r.stdout, r.stderr)
161
+ : { isZeroTests: false };
162
+ const isVacuous = r.ok && r.code === 0 && zeroTestResult.isZeroTests;
163
+ const passed = r.ok && r.code === 0 && !isVacuous;
164
+ const tail = !passed
165
+ ? isVacuous
166
+ ? `vacuous test pass: command exited with code 0 but executed 0 tests (${zeroTestResult.reason})`
167
+ : scrub((r.error ?? '') || (r.timedOut ? 'timed out' : '') || r.stderr.slice(-300) || r.stdout.slice(-300) || `exit ${r.code}`)
168
+ : undefined;
107
169
  runs.push({ ...base, outcome: passed ? 'passed' : 'failed', safety: cls.safety, exitCode: r.code, durationMs, ...(tail ? { reason: tail } : {}) });
108
170
  evidence.push({ kind: 'executed', at: isoNow(o), package: pkg, command: entry.command ?? undefined, exitCode: r.code, durationMs, scope: fingerprint ?? 'unknown', ...(tail ? { note: tail } : {}) });
109
171
  }
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/services/verify.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { SCHEMA_VERSION, validateCommands, type CommandEntry } from '../config/schemas.js';\nimport { requireWorkspace, type Ws } from '../core/workspace.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { DevWorkspaceError } from '../errors/index.js';\nimport { createRunner } from '../integrations/exec.js';\nimport { scrub } from '../integrations/manager.js';\nimport { loadTask, saveTask, type Evidence, type GateContext, type Task, type VerificationItem, type VerifyStatus, assertNoSecrets } from '../tasks/task.js';\nimport { pathExists } from '../utils/fs.js';\nimport { classifyCommand, isDeclared, loadTestEnv, readManifestEvidence, assertSafeTarget, removeDeclaration, saveDeclaration, type CommandSafety, type TestEnvDeclaration } from '../verification/safety.js';\nimport { changedSince, scopeByPackage } from '../verification/scope.js';\nimport { isoNow, mutate, type ServiceOptions } from './common.js';\n\nexport async function loadContract(ws: Ws): Promise<CommandEntry[]> {\n if (!(await pathExists(ws.commands))) return [];\n return (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data.checks;\n}\n\n/** Contract plus what the task has changed per package: everything the completion gate needs to judge it. */\nexport async function gateContext(ws: Ws, task: Task, contract?: CommandEntry[]): Promise<GateContext> {\n const checks = contract ?? (await loadContract(ws));\n const scope = task.scope ? scopeByPackage(await changedSince(ws.root, task.scope), checks) : null;\n return { contract: checks, scope };\n}\n\nexport type RunOutcome = 'passed' | 'failed' | 'refused' | 'not-affected';\n\nexport interface PackageRun {\n package: string;\n command: string | null;\n outcome: RunOutcome;\n exitCode?: number | null;\n durationMs?: number;\n /** Why DevWorkspace did not run it, or the scrubbed tail of a failure. */\n reason?: string;\n safety: CommandSafety['safety'];\n}\n\nexport interface RunCheckResult {\n task: Task;\n check: string;\n runs: PackageRun[];\n}\n\n/** Anything a shell would interpret. Contract commands are run as an argument vector, never through a shell. */\nconst SHELL_SYNTAX = /[&|;<>$`(){}\"'\\\\*?!%^\\r\\n]/;\n\nexport function splitCommand(command: string): string[] | null {\n if (SHELL_SYNTAX.test(command)) return null;\n const parts = command.trim().split(/\\s+/);\n return parts[0] ? parts : null;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10 * 60_000;\n\n/**\n * PATH lookup on Windows finds the extensionless Unix shell script (`npm`) before `npm.cmd`, and that cannot be\n * spawned. Prefer the Windows launcher next to it. Elsewhere the lookup result is used as is.\n */\nexport async function resolveExecutable(found: string | null, name: string, platform: NodeJS.Platform, exists: (p: string) => Promise<boolean>): Promise<string> {\n if (!found) return name;\n if (platform !== 'win32' || /\\.(?:exe|cmd|bat|com)$/i.test(found)) return found;\n for (const ext of ['.cmd', '.exe', '.bat']) if (await exists(found + ext)) return found + ext;\n return found;\n}\n\n/**\n * Run one contract check for the packages the task changed, and record what really happened. DevWorkspace only runs\n * read-only, non-destructive commands; anything that may touch a database runs only after the user declared a test\n * environment for that package and check. Refusals are recorded as \"could not run\", never as a pass.\n */\nexport async function runTaskCheck(o: ServiceOptions, id: string, check: string, opts: { package?: string; timeoutMs?: number } = {}): Promise<RunCheckResult> {\n const ws = await requireWorkspace(o.cwd);\n const task = await loadTask(ws, id);\n const contract = await loadContract(ws);\n const wanted = opts.package ? (opts.package === '.' || opts.package === '' ? '.' : opts.package.replace(/\\/+$/, '')) : undefined;\n const entries = contract.filter((c) => c.id === check && c.available && (wanted === undefined || (c.cwd ?? '.') === wanted));\n if (entries.length === 0) {\n throw new DevWorkspaceError('NOT_FOUND', `The testing contract has no \"${check}\" command${wanted ? ` for package \"${wanted}\"` : ''}.`, {\n hint: 'See the contract with \"devworkspace context\", or add the command to .devworkspace/context/commands.json.',\n });\n }\n const scope = (await gateContext(ws, task, contract)).scope;\n const decls = await loadTestEnv(ws);\n const runner = o.runner ?? createRunner(o.env ?? process.env, o.platform);\n const runs: PackageRun[] = [];\n const evidence: Evidence[] = [];\n\n for (const entry of entries) {\n const pkg = entry.cwd ?? '.';\n const base = { package: pkg, command: entry.command };\n const fingerprint = scope === null ? 'unknown' : scope[pkg];\n if (wanted === undefined && fingerprint === undefined) {\n runs.push({ ...base, outcome: 'not-affected', safety: 'safe', reason: 'the task changed nothing in this package' });\n continue;\n }\n const manifest = await readManifestEvidence(ws.root, entry);\n const cls = classifyCommand(entry, manifest);\n if (cls.safety === 'blocked') {\n runs.push({ ...base, outcome: 'refused', safety: cls.safety, reason: `refused: ${cls.reasons.join('; ')}` });\n continue;\n }\n if (cls.safety === 'needs-test-environment' && !isDeclared(decls, pkg, check)) {\n runs.push({\n ...base,\n outcome: 'refused',\n safety: cls.safety,\n reason: `refused: ${cls.reasons.join('; ')}. Run it yourself against a test environment you control, then declare it with: devworkspace testenv declare --package ${pkg} --check ${check} --target \"<description>\" --yes`,\n });\n continue;\n }\n const argv = splitCommand(entry.command ?? '');\n if (!argv) {\n runs.push({ ...base, outcome: 'refused', safety: cls.safety, reason: 'refused: the command uses shell syntax, and DevWorkspace never runs a shell' });\n continue;\n }\n const exe = await resolveExecutable(await runner.which(argv[0]!), argv[0]!, o.platform ?? process.platform, pathExists);\n const started = Date.now();\n const r = await runner.run({ command: exe, args: argv.slice(1), cwd: pkg === '.' ? ws.root : path.join(ws.root, ...pkg.split('/')), timeoutMs: opts.timeoutMs ?? DEFAULT_TIMEOUT_MS });\n const durationMs = Date.now() - started;\n if (r.code === null && !r.timedOut && r.error) {\n // The command never started (missing executable, bad cwd): that is \"could not run\", not a test failure.\n runs.push({ ...base, outcome: 'refused', safety: cls.safety, reason: `could not start: ${scrub(r.error)}` });\n continue;\n }\n const passed = r.ok && r.code === 0;\n const tail = passed ? undefined : scrub((r.error ?? '') || (r.timedOut ? 'timed out' : '') || r.stderr.slice(-300) || r.stdout.slice(-300) || `exit ${r.code}`);\n runs.push({ ...base, outcome: passed ? 'passed' : 'failed', safety: cls.safety, exitCode: r.code, durationMs, ...(tail ? { reason: tail } : {}) });\n evidence.push({ kind: 'executed', at: isoNow(o), package: pkg, command: entry.command ?? undefined, exitCode: r.code, durationMs, scope: fingerprint ?? 'unknown', ...(tail ? { note: tail } : {}) });\n }\n\n const updated = await mutate(o, async (w) => {\n const t = await loadTask(w, id);\n let item = t.verification.find((v) => v.check === check);\n if (!item) {\n item = { check, required: false, status: 'PENDING' };\n t.verification.push(item);\n }\n for (const e of evidence) item.evidence = [...(item.evidence ?? []).filter((x) => x.package !== e.package), e];\n item.status = summarize(item, runs);\n const refused = runs.filter((r) => r.outcome === 'refused');\n if (item.status === 'COULD_NOT_RUN') item.detail = refused.map((r) => `${r.package}: ${r.reason}`).join(' | ').slice(0, 500);\n else delete item.detail;\n delete item.reason;\n item.updatedAt = isoNow(o);\n t.updatedAt = item.updatedAt;\n assertNoSecrets(t);\n await saveTask(w, t);\n return t;\n });\n return { task: updated, check, runs };\n}\n\nfunction summarize(item: VerificationItem, runs: PackageRun[]): VerifyStatus {\n if (runs.some((r) => r.outcome === 'failed')) return 'FAIL';\n if (runs.some((r) => r.outcome === 'refused')) return 'COULD_NOT_RUN';\n if (runs.some((r) => r.outcome === 'passed')) return 'PASS';\n return item.status;\n}\n\n// ---------- declared test environments ----------\n\nexport async function declareTestEnv(o: ServiceOptions, input: { package: string; checks: string[]; target: string; yes: boolean }): Promise<TestEnvDeclaration> {\n if (!input.yes) {\n throw new DevWorkspaceError('USAGE', 'Declaring a test environment is a statement that running these checks there is safe; confirm with --yes.', {\n hint: 'DevWorkspace cannot verify a database target (it never reads connection settings). This records your assertion, locally, and nothing else.',\n });\n }\n assertSafeTarget(input.target);\n const ws = await requireWorkspace(o.cwd);\n const pkg = input.package === '' ? '.' : input.package.replace(/\\/+$/, '');\n const contract = await loadContract(ws);\n if (!contract.some((c) => c.available && (c.cwd ?? '.') === pkg)) {\n throw new DevWorkspaceError('NOT_FOUND', `The testing contract has no commands for package \"${pkg}\".`, { hint: 'Use a package directory shown by \"devworkspace context\".' });\n }\n const allowed = new Set(['unit', 'integration', 'e2e', 'security']);\n const bad = input.checks.filter((c) => !allowed.has(c));\n if (input.checks.length === 0 || bad.length > 0) {\n throw new DevWorkspaceError('USAGE', `--check must be one or more of: ${[...allowed].join(', ')}.`, { hint: 'Migrations, seeds and resets are never run by DevWorkspace.' });\n }\n const decl: TestEnvDeclaration = { package: pkg, checks: [...new Set(input.checks)].sort(), target: input.target.trim(), declaredAt: isoNow(o) };\n await mutate(o, async (w) => saveDeclaration(w, decl));\n return decl;\n}\n\nexport async function listTestEnv(o: ServiceOptions): Promise<TestEnvDeclaration[]> {\n return loadTestEnv(await requireWorkspace(o.cwd));\n}\n\nexport async function revokeTestEnv(o: ServiceOptions, pkg: string): Promise<boolean> {\n return mutate(o, async (w) => removeDeclaration(w, pkg === '' ? '.' : pkg.replace(/\\/+$/, '')));\n}\n"]}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/services/verify.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAqB,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAW,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAwF,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC7J,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAA+C,MAAM,2BAA2B,CAAC;AAC9M,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAuB,MAAM,aAAa,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EAAM;IACvC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,OAAO,CAAC,MAAM,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;AACtG,CAAC;AAED,6GAA6G;AAC7G,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAM,EAAE,IAAU,EAAE,QAAyB;IAC7E,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,MAAM,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClG,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC;AAqBD,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAC,EAAU,EAAE,OAAe;IACvD,IAAI,EAAE,KAAK,MAAM,IAAI,EAAE,KAAK,aAAa,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAC5F,OAAO,iEAAiE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACzF,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,MAAc,EAAE,MAAc;IAC7E,MAAM,QAAQ,GAAG,GAAG,MAAM,KAAK,MAAM,EAAE,CAAC;IACxC,MAAM,kBAAkB,GAAG,6CAA6C,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEvF,+BAA+B;IAC/B,IAAI,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1C,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;IAC9E,CAAC;IACD,IAAI,kCAAkC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,kCAAkC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3G,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IAClE,CAAC;IACD,IAAI,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjG,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC7D,CAAC;IAED,6BAA6B;IAC7B,IAAI,+CAA+C,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,yCAAyC,EAAE,CAAC;IAClF,CAAC;IACD,IAAI,8CAA8C,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,2BAA2B,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChH,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,wCAAwC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpG,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC3D,CAAC;IAED,+BAA+B;IAC/B,IAAI,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7E,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAC;IAC3E,CAAC;IAED,iDAAiD;IACjD,IAAI,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/E,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC;IACzE,CAAC;IAED,2CAA2C;IAC3C,IAAI,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAC;IAC3E,CAAC;IACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnF,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACjE,CAAC;IAED,sDAAsD;IACtD,IAAI,kBAAkB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QACvH,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,qDAAqD,EAAE,CAAC;IAC9F,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAChC,CAAC;AAED,gHAAgH;AAChH,MAAM,YAAY,GAAG,4BAA4B,CAAC;AAElD,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,kBAAkB,GAAG,EAAE,GAAG,MAAM,CAAC;AAEvC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAoB,EAAE,IAAY,EAAE,QAAyB,EAAE,MAAuC;IAC5I,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,QAAQ,KAAK,OAAO,IAAI,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAChF,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAAE,IAAI,MAAM,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC;YAAE,OAAO,KAAK,GAAG,GAAG,CAAC;IAC9F,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,CAAiB,EAAE,EAAU,EAAE,KAAa,EAAE,OAAiD,EAAE;IAClI,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjI,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;IAC7H,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,iBAAiB,CAAC,WAAW,EAAE,gCAAgC,KAAK,YAAY,MAAM,CAAC,CAAC,CAAC,iBAAiB,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE;YACrI,IAAI,EAAE,0GAA0G;SACjH,CAAC,CAAC;IACL,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,MAAM,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAiB,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAe,EAAE,CAAC;IAEhC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC;QAC7B,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QACtD,MAAM,WAAW,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5D,IAAI,MAAM,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,0CAA0C,EAAE,CAAC,CAAC;YACpH,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7G,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,wBAAwB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;YAC9E,IAAI,CAAC,IAAI,CAAC;gBACR,GAAG,IAAI;gBACP,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM,EAAE,YAAY,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,0HAA0H,GAAG,YAAY,KAAK,iCAAiC;aAC1N,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,6EAA6E,EAAE,CAAC,CAAC;YACtJ,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACxH,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,kBAAkB,EAAE,CAAC,CAAC;QACvL,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QACxC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YAC9C,wGAAwG;YACxG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7G,SAAS;QACX,CAAC;QACD,MAAM,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;YACjE,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;YAC1D,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,cAAc,CAAC,WAAW,CAAC;QACrE,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;QAClD,MAAM,IAAI,GAAG,CAAC,MAAM;YAClB,CAAC,CAAC,SAAS;gBACT,CAAC,CAAC,uEAAuE,cAAc,CAAC,MAAM,GAAG;gBACjG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACjI,CAAC,CAAC,SAAS,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACnJ,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,IAAI,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxM,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1C,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChC,IAAI,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YACrD,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/G,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,eAAe;YAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;;YACxH,OAAO,IAAI,CAAC,MAAM,CAAC;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,eAAe,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACxC,CAAC;AAED,SAAS,SAAS,CAAC,IAAsB,EAAE,IAAkB;IAC3D,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC;QAAE,OAAO,MAAM,CAAC;IAC5D,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC;QAAE,OAAO,eAAe,CAAC;IACtE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC;QAAE,OAAO,MAAM,CAAC;IAC5D,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,mDAAmD;AAEnD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,CAAiB,EAAE,KAA0E;IAChI,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACf,MAAM,IAAI,iBAAiB,CAAC,OAAO,EAAE,0GAA0G,EAAE;YAC/I,IAAI,EAAE,4IAA4I;SACnJ,CAAC,CAAC;IACL,CAAC;IACD,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,CAAC,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,iBAAiB,CAAC,WAAW,EAAE,qDAAqD,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,0DAA0D,EAAE,CAAC,CAAC;IAC/K,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,iBAAiB,CAAC,OAAO,EAAE,mCAAmC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,6DAA6D,EAAE,CAAC,CAAC;IAC/K,CAAC;IACD,MAAM,IAAI,GAAuB,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACjJ,MAAM,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,CAAiB;IACjD,OAAO,WAAW,CAAC,MAAM,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,CAAiB,EAAE,GAAW;IAChE,OAAO,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAClG,CAAC","sourcesContent":["import path from 'node:path';\nimport { SCHEMA_VERSION, validateCommands, type CommandEntry } from '../config/schemas.js';\nimport { requireWorkspace, type Ws } from '../core/workspace.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { DevWorkspaceError } from '../errors/index.js';\nimport { createRunner } from '../integrations/exec.js';\nimport { scrub } from '../integrations/manager.js';\nimport { loadTask, saveTask, type Evidence, type GateContext, type Task, type VerificationItem, type VerifyStatus, assertNoSecrets } from '../tasks/task.js';\nimport { pathExists } from '../utils/fs.js';\nimport { classifyCommand, isDeclared, loadTestEnv, readManifestEvidence, assertSafeTarget, removeDeclaration, saveDeclaration, type CommandSafety, type TestEnvDeclaration } from '../verification/safety.js';\nimport { changedSince, scopeByPackage } from '../verification/scope.js';\nimport { isoNow, mutate, type ServiceOptions } from './common.js';\n\nexport async function loadContract(ws: Ws): Promise<CommandEntry[]> {\n if (!(await pathExists(ws.commands))) return [];\n return (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data.checks;\n}\n\n/** Contract plus what the task has changed per package: everything the completion gate needs to judge it. */\nexport async function gateContext(ws: Ws, task: Task, contract?: CommandEntry[]): Promise<GateContext> {\n const checks = contract ?? (await loadContract(ws));\n const scope = task.scope ? scopeByPackage(await changedSince(ws.root, task.scope), checks) : null;\n return { contract: checks, scope };\n}\n\nexport type RunOutcome = 'passed' | 'failed' | 'refused' | 'not-affected';\n\nexport interface PackageRun {\n package: string;\n command: string | null;\n outcome: RunOutcome;\n exitCode?: number | null;\n durationMs?: number;\n /** Why DevWorkspace did not run it, or the scrubbed tail of a failure. */\n reason?: string;\n safety: CommandSafety['safety'];\n}\n\nexport interface RunCheckResult {\n task: Task;\n check: string;\n runs: PackageRun[];\n}\n\n/** Check if a contract check represents an automated test suite. */\nexport function isTestCommand(id: string, command: string): boolean {\n if (id === 'unit' || id === 'integration' || id === 'e2e' || id === 'security') return true;\n return /\\b(test|vitest|jest|pytest|playwright|cypress|mocha|ava|tap)\\b/i.test(command);\n}\n\nexport interface ZeroTestResult {\n isZeroTests: boolean;\n reason?: string;\n}\n\n/**\n * Detects known zero-test execution signatures from test runners (Vitest, Jest, Pytest, Mocha, Go, Cargo).\n * Prevents commands that exit with code 0 because no tests were found (e.g. --passWithNoTests) from falsely passing.\n */\nexport function detectZeroTests(command: string, stdout: string, stderr: string): ZeroTestResult {\n const combined = `${stdout}\\n${stderr}`;\n const hasPassWithNoTests = /--passWithNoTests\\b|--pass-with-no-tests\\b/i.test(command);\n\n // 1. Vitest zero-test patterns\n if (/No test files found/i.test(combined)) {\n return { isZeroTests: true, reason: 'Vitest reported no test files found' };\n }\n if (/Test Files\\s+0\\s+passed\\s*\\(0\\)/i.test(combined) || /Test Files\\s+0\\s+failed\\s*\\(0\\)/i.test(combined)) {\n return { isZeroTests: true, reason: 'Vitest ran 0 test files' };\n }\n if (/Tests\\s+0\\s+passed\\s*\\(0\\)/i.test(combined) && !/Tests\\s+[1-9]\\d*\\s+passed/i.test(combined)) {\n return { isZeroTests: true, reason: 'Vitest ran 0 tests' };\n }\n\n // 2. Jest zero-test patterns\n if (/Ran all test suites matching.*No tests found/i.test(combined)) {\n return { isZeroTests: true, reason: 'Jest found no test suites matching path' };\n }\n if (/Test Suites:\\s*0\\s*(?:passed,\\s*)?0\\s*total/i.test(combined) || /Test Suites:\\s*0\\s*total/i.test(combined)) {\n return { isZeroTests: true, reason: 'Jest ran 0 test suites' };\n }\n if (/Tests:\\s*0\\s*(?:passed,\\s*)?0\\s*total/i.test(combined) || /Tests:\\s*0\\s*total/i.test(combined)) {\n return { isZeroTests: true, reason: 'Jest ran 0 tests' };\n }\n\n // 3. Pytest zero-test patterns\n if (/collected 0 items/i.test(combined) || /no tests ran in/i.test(combined)) {\n return { isZeroTests: true, reason: 'Pytest collected and ran 0 items' };\n }\n\n // 4. Mocha / Node test runner zero-test patterns\n if (/\\b0 passing\\b/i.test(combined) && !/[1-9]\\d*\\s+passing\\b/i.test(combined)) {\n return { isZeroTests: true, reason: 'Mocha reported 0 passing tests' };\n }\n\n // 5. Go / Cargo / other zero-test patterns\n if (/\\[no test files\\]/i.test(combined)) {\n return { isZeroTests: true, reason: 'Go test reported [no test files]' };\n }\n if (/running 0 tests/i.test(combined) && !/running [1-9]\\d* tests/i.test(combined)) {\n return { isZeroTests: true, reason: 'Cargo test ran 0 tests' };\n }\n\n // 6. Explicit passWithNoTests with no tests indicated\n if (hasPassWithNoTests && (/no tests\\b/i.test(combined) || /0 tests\\b/i.test(combined) || /0 total\\b/i.test(combined))) {\n return { isZeroTests: true, reason: 'Command used --passWithNoTests and executed 0 tests' };\n }\n\n return { isZeroTests: false };\n}\n\n/** Anything a shell would interpret. Contract commands are run as an argument vector, never through a shell. */\nconst SHELL_SYNTAX = /[&|;<>$`(){}\"'\\\\*?!%^\\r\\n]/;\n\nexport function splitCommand(command: string): string[] | null {\n if (SHELL_SYNTAX.test(command)) return null;\n const parts = command.trim().split(/\\s+/);\n return parts[0] ? parts : null;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10 * 60_000;\n\n/**\n * PATH lookup on Windows finds the extensionless Unix shell script (`npm`) before `npm.cmd`, and that cannot be\n * spawned. Prefer the Windows launcher next to it. Elsewhere the lookup result is used as is.\n */\nexport async function resolveExecutable(found: string | null, name: string, platform: NodeJS.Platform, exists: (p: string) => Promise<boolean>): Promise<string> {\n if (!found) return name;\n if (platform !== 'win32' || /\\.(?:exe|cmd|bat|com)$/i.test(found)) return found;\n for (const ext of ['.cmd', '.exe', '.bat']) if (await exists(found + ext)) return found + ext;\n return found;\n}\n\n/**\n * Run one contract check for the packages the task changed, and record what really happened. DevWorkspace only runs\n * read-only, non-destructive commands; anything that may touch a database runs only after the user declared a test\n * environment for that package and check. Refusals are recorded as \"could not run\", never as a pass.\n */\nexport async function runTaskCheck(o: ServiceOptions, id: string, check: string, opts: { package?: string; timeoutMs?: number } = {}): Promise<RunCheckResult> {\n const ws = await requireWorkspace(o.cwd);\n const task = await loadTask(ws, id);\n const contract = await loadContract(ws);\n const wanted = opts.package ? (opts.package === '.' || opts.package === '' ? '.' : opts.package.replace(/\\/+$/, '')) : undefined;\n const entries = contract.filter((c) => c.id === check && c.available && (wanted === undefined || (c.cwd ?? '.') === wanted));\n if (entries.length === 0) {\n throw new DevWorkspaceError('NOT_FOUND', `The testing contract has no \"${check}\" command${wanted ? ` for package \"${wanted}\"` : ''}.`, {\n hint: 'See the contract with \"devworkspace context\", or add the command to .devworkspace/context/commands.json.',\n });\n }\n const scope = (await gateContext(ws, task, contract)).scope;\n const decls = await loadTestEnv(ws);\n const runner = o.runner ?? createRunner(o.env ?? process.env, o.platform);\n const runs: PackageRun[] = [];\n const evidence: Evidence[] = [];\n\n for (const entry of entries) {\n const pkg = entry.cwd ?? '.';\n const base = { package: pkg, command: entry.command };\n const fingerprint = scope === null ? 'unknown' : scope[pkg];\n if (wanted === undefined && fingerprint === undefined) {\n runs.push({ ...base, outcome: 'not-affected', safety: 'safe', reason: 'the task changed nothing in this package' });\n continue;\n }\n const manifest = await readManifestEvidence(ws.root, entry);\n const cls = classifyCommand(entry, manifest);\n if (cls.safety === 'blocked') {\n runs.push({ ...base, outcome: 'refused', safety: cls.safety, reason: `refused: ${cls.reasons.join('; ')}` });\n continue;\n }\n if (cls.safety === 'needs-test-environment' && !isDeclared(decls, pkg, check)) {\n runs.push({\n ...base,\n outcome: 'refused',\n safety: cls.safety,\n reason: `refused: ${cls.reasons.join('; ')}. Run it yourself against a test environment you control, then declare it with: devworkspace testenv declare --package ${pkg} --check ${check} --target \"<description>\" --yes`,\n });\n continue;\n }\n const argv = splitCommand(entry.command ?? '');\n if (!argv) {\n runs.push({ ...base, outcome: 'refused', safety: cls.safety, reason: 'refused: the command uses shell syntax, and DevWorkspace never runs a shell' });\n continue;\n }\n const exe = await resolveExecutable(await runner.which(argv[0]!), argv[0]!, o.platform ?? process.platform, pathExists);\n const started = Date.now();\n const r = await runner.run({ command: exe, args: argv.slice(1), cwd: pkg === '.' ? ws.root : path.join(ws.root, ...pkg.split('/')), timeoutMs: opts.timeoutMs ?? DEFAULT_TIMEOUT_MS });\n const durationMs = Date.now() - started;\n if (r.code === null && !r.timedOut && r.error) {\n // The command never started (missing executable, bad cwd): that is \"could not run\", not a test failure.\n runs.push({ ...base, outcome: 'refused', safety: cls.safety, reason: `could not start: ${scrub(r.error)}` });\n continue;\n }\n const zeroTestResult = isTestCommand(entry.id, entry.command ?? '')\n ? detectZeroTests(entry.command ?? '', r.stdout, r.stderr)\n : { isZeroTests: false };\n const isVacuous = r.ok && r.code === 0 && zeroTestResult.isZeroTests;\n const passed = r.ok && r.code === 0 && !isVacuous;\n const tail = !passed\n ? isVacuous\n ? `vacuous test pass: command exited with code 0 but executed 0 tests (${zeroTestResult.reason})`\n : scrub((r.error ?? '') || (r.timedOut ? 'timed out' : '') || r.stderr.slice(-300) || r.stdout.slice(-300) || `exit ${r.code}`)\n : undefined;\n runs.push({ ...base, outcome: passed ? 'passed' : 'failed', safety: cls.safety, exitCode: r.code, durationMs, ...(tail ? { reason: tail } : {}) });\n evidence.push({ kind: 'executed', at: isoNow(o), package: pkg, command: entry.command ?? undefined, exitCode: r.code, durationMs, scope: fingerprint ?? 'unknown', ...(tail ? { note: tail } : {}) });\n }\n\n const updated = await mutate(o, async (w) => {\n const t = await loadTask(w, id);\n let item = t.verification.find((v) => v.check === check);\n if (!item) {\n item = { check, required: false, status: 'PENDING' };\n t.verification.push(item);\n }\n for (const e of evidence) item.evidence = [...(item.evidence ?? []).filter((x) => x.package !== e.package), e];\n item.status = summarize(item, runs);\n const refused = runs.filter((r) => r.outcome === 'refused');\n if (item.status === 'COULD_NOT_RUN') item.detail = refused.map((r) => `${r.package}: ${r.reason}`).join(' | ').slice(0, 500);\n else delete item.detail;\n delete item.reason;\n item.updatedAt = isoNow(o);\n t.updatedAt = item.updatedAt;\n assertNoSecrets(t);\n await saveTask(w, t);\n return t;\n });\n return { task: updated, check, runs };\n}\n\nfunction summarize(item: VerificationItem, runs: PackageRun[]): VerifyStatus {\n if (runs.some((r) => r.outcome === 'failed')) return 'FAIL';\n if (runs.some((r) => r.outcome === 'refused')) return 'COULD_NOT_RUN';\n if (runs.some((r) => r.outcome === 'passed')) return 'PASS';\n return item.status;\n}\n\n// ---------- declared test environments ----------\n\nexport async function declareTestEnv(o: ServiceOptions, input: { package: string; checks: string[]; target: string; yes: boolean }): Promise<TestEnvDeclaration> {\n if (!input.yes) {\n throw new DevWorkspaceError('USAGE', 'Declaring a test environment is a statement that running these checks there is safe; confirm with --yes.', {\n hint: 'DevWorkspace cannot verify a database target (it never reads connection settings). This records your assertion, locally, and nothing else.',\n });\n }\n assertSafeTarget(input.target);\n const ws = await requireWorkspace(o.cwd);\n const pkg = input.package === '' ? '.' : input.package.replace(/\\/+$/, '');\n const contract = await loadContract(ws);\n if (!contract.some((c) => c.available && (c.cwd ?? '.') === pkg)) {\n throw new DevWorkspaceError('NOT_FOUND', `The testing contract has no commands for package \"${pkg}\".`, { hint: 'Use a package directory shown by \"devworkspace context\".' });\n }\n const allowed = new Set(['unit', 'integration', 'e2e', 'security']);\n const bad = input.checks.filter((c) => !allowed.has(c));\n if (input.checks.length === 0 || bad.length > 0) {\n throw new DevWorkspaceError('USAGE', `--check must be one or more of: ${[...allowed].join(', ')}.`, { hint: 'Migrations, seeds and resets are never run by DevWorkspace.' });\n }\n const decl: TestEnvDeclaration = { package: pkg, checks: [...new Set(input.checks)].sort(), target: input.target.trim(), declaredAt: isoNow(o) };\n await mutate(o, async (w) => saveDeclaration(w, decl));\n return decl;\n}\n\nexport async function listTestEnv(o: ServiceOptions): Promise<TestEnvDeclaration[]> {\n return loadTestEnv(await requireWorkspace(o.cwd));\n}\n\nexport async function revokeTestEnv(o: ServiceOptions, pkg: string): Promise<boolean> {\n return mutate(o, async (w) => removeDeclaration(w, pkg === '' ? '.' : pkg.replace(/\\/+$/, '')));\n}\n"]}
@@ -0,0 +1,168 @@
1
+ # Chapter 1: Executive Summary
2
+
3
+ > **A beginner-friendly overview of what DevWorkspace is, why it was created, and how it transforms AI-assisted software engineering.**
4
+
5
+ ---
6
+
7
+ ## 1. The Core Problem DevWorkspace Solves
8
+
9
+ Modern AI coding agents (such as Claude Code, Cursor, OpenAI Codex, GitHub Copilot, and Google Antigravity) are remarkably capable at writing code. However, when dropped into a new or complex repository, they suffer from predictable, recurring failure modes:
10
+
11
+ 1. **Context Window Exhaustion**: Agents attempt to read hundreds of files or entire directories, filling up their context window with irrelevant code and forgetting instructions.
12
+ 2. **Hallucinated Project Commands**: In multi-package or monorepo setups (such as a repository with `backend/` and `frontend/` but no root `package.json`), agents attempt to run `npm test` or `npm run build` at the root, failing immediately.
13
+ 3. **Accidental Destruction of User Work**: Agents often run `git reset --hard` or overwrite uncommitted changes when debugging or attempting to reproduce an issue.
14
+ 4. **Credential Leaks**: Agents accidentally read `.env`, `.env.local`, or private key files, exposing secrets in prompts, logs, or commit messages.
15
+ 5. **Hallucinated Completion**: An agent writes code, encounters a failing build or test, ignores the failure, and prematurely declares: *"All tasks are complete and verified!"*
16
+
17
+ **DevWorkspace was built to eliminate these exact failure modes.**
18
+
19
+ ---
20
+
21
+ ## 2. What is DevWorkspace?
22
+
23
+ **DevWorkspace** is a project-local CLI tool that acts as a deterministic, persistent operating environment for AI coding agents.
24
+
25
+ ```
26
+ +---------------------------------------------------------------------------------------+
27
+ | DEVWORKSPACE |
28
+ | |
29
+ | 1. Discovers the repo deterministically (No AI involved in scanning) |
30
+ | 2. Writes portable facts and testing contracts into .devworkspace/ |
31
+ | 3. Installs instruction files (AGENTS.md, CLAUDE.md, etc.) non-destructively |
32
+ | 4. Enforces strict verification gates before any task can be marked COMPLETED |
33
+ | 5. Requires zero external npm runtime dependencies (100% Node.js built-ins) |
34
+ +---------------------------------------------------------------------------------------+
35
+ ```
36
+
37
+ When you initialize DevWorkspace in a repository, it creates a lightweight `.devworkspace/` directory. Inside, it stores facts about the project's tech stack, package structure, entry points, architectural decisions (ADRs), and tasks. It then injects non-destructive instructions into whatever AI agent tools the developer uses.
38
+
39
+ ---
40
+
41
+ ## 3. The Real-World Analogy: An Airport Control Tower
42
+
43
+ Think of an AI coding agent as a **visiting pilot flying an aircraft**.
44
+ - The pilot is skilled and capable of flying the plane.
45
+ - However, the pilot does not know the specific runway layout, local weather conditions, mountain obstacles, or taxiway rules of this particular airport.
46
+ - If left alone without ground guidance, the pilot might try to land on an active construction zone or taxi across an occupied runway.
47
+
48
+ **DevWorkspace is the Airport Control Tower and Navigational Chart:**
49
+ - **Navigational Chart (`.devworkspace/context/`)**: Tells the pilot exactly where the runways are (`backend`, `frontend`), which radio frequencies to use (exact `npm run ...` commands and their working directories), and where the hazardous zones are (`.env` files, production migrations).
50
+ - **Control Tower Logs (`.devworkspace/tasks/`)**: Keeps a continuous log of every flight maneuver. The pilot cannot claim they have landed safely (`COMPLETED`) until the tower confirms the wheels have touched down and the runway sensors register `PASS`.
51
+ - **Flight Operating Rules (`AGENTS.md` / `CLAUDE.md`)**: A clear checklist in the cockpit explaining the mandatory safety protocol: never dump fuel over cities (never wipe uncommitted user work), check wind conditions before descent (run `git status` first).
52
+
53
+ ---
54
+
55
+ ## 4. The Five Architectural Pillars
56
+
57
+ DevWorkspace is built around five core principles enforced across its codebase:
58
+
59
+ ```mermaid
60
+ flowchart LR
61
+ P1["1. Deterministic Discovery\n(No LLM hallucination in repo scanning)"]
62
+ P2["2. Progressive Context Loading\n(Level 1 to Level 6 shallow-first)"]
63
+ P3["3. Multi-Agent Adapters\n(Claude, Codex, Cursor, Copilot)"]
64
+ P4["4. Completion Verification Gates\n(Evidence over claims, regression tracking)"]
65
+ P5["5. Zero-Secret Invariants\n(Never read .env, symlink & path defense)"]
66
+
67
+ P1 --- P2 --- P3 --- P4 --- P5
68
+ ```
69
+
70
+ ### Pillar 1: Deterministic Discovery
71
+ DevWorkspace never uses an AI model to discover a repository. Its analysis engine (`src/discovery/`) uses fast, deterministic filesystem scanning, manifest parsing (`package.json`, `Cargo.toml`, `pyproject.toml`), and extension counting. It is 100% reproducible, runs in under a second even on repositories with thousands of files, and costs zero API tokens.
72
+
73
+ ### Pillar 2: Progressive Context Loading
74
+ To keep agent token consumption minimal, DevWorkspace structures project knowledge into shallow tiers. An agent reads high-level operating rules first (Level 1), queries specific facts if needed (Level 2), inspects relevant architecture decisions (Level 3), and only reads source code and tests (Level 5–6) for the files directly touched by the task.
75
+
76
+ ### Pillar 3: Multi-Agent Compatibility
77
+ DevWorkspace is not locked into a single AI tool. It features a pluggable adapter system (`src/agents/`) that non-destructively generates and updates native instruction files:
78
+ - **OpenAI Codex & Antigravity**: `AGENTS.md`
79
+ - **Claude Code**: `CLAUDE.md` and `.claude/skills/devworkspace/SKILL.md`
80
+ - **Cursor IDE**: `.cursor/rules/devworkspace.mdc`
81
+ - **GitHub Copilot**: `.github/copilot-instructions.md`
82
+
83
+ All adapters preserve existing human-written instructions by enclosing DevWorkspace rules within dedicated comment blocks: `<!-- devworkspace:start --> ... <!-- devworkspace:end -->`.
84
+
85
+ ### Pillar 4: Evidence-Based Completion Gates
86
+ In DevWorkspace, a task status is a state machine: `IDEA` -> `SPECIFIED` -> `PLANNED` -> `IN_PROGRESS` -> `TESTING` -> `REVIEW` -> `COMPLETED`. An agent **cannot** transition a task to `COMPLETED` by simply asserting that it is finished. The completion gate (`evaluateGate` in `src/tasks/task.ts`) inspects real execution evidence:
87
+ - Did required typechecks, linting, tests, and builds pass?
88
+ - Did passing test counts drop, or did failures increase compared to baseline?
89
+ - Did the agent respect read-only constraints?
90
+ - Has the agent confirmed the three mandatory human attestations (user work intact, knowledge reviewed, final state inspected)?
91
+
92
+ If any check fails, the transition is rejected with a `GATE` error.
93
+
94
+ ### Pillar 5: Zero-Secret & Path Security Invariants
95
+ DevWorkspace treats the repository as **untrusted data**:
96
+ - **Never reads credential files**: `.env`, `.env.local`, `.pem`, `.key`, and service account tokens are detected by name only; their bytes are never read into memory.
97
+ - **Symlink traversal defense**: Analysis code (`safeReadText`) uses realpath canonicalization and checks every path component to prevent directory traversal and symlink escape attacks.
98
+ - **Database safety**: Commands containing destructive terms (`drop`, `truncate`, `flushall`, `migrate`, `seed`) or requiring live databases are blocked from running automatically unless a developer explicitly declares a local test environment (`devworkspace testenv declare`).
99
+
100
+ ---
101
+
102
+ ## 5. A Beginner-Friendly Walkthrough of One Representative Run
103
+
104
+ Here is what happens in practice when a developer or agent uses DevWorkspace in a project:
105
+
106
+ ```bash
107
+ # Step 1: Initialize DevWorkspace in the repository
108
+ $ npx devworkspace init
109
+ ✓ DevWorkspace initialized.
110
+ Created: .devworkspace/ (project.json, context/, tasks/, decisions/, analysis/)
111
+
112
+ # Step 2: Run deterministic repository discovery
113
+ $ npx devworkspace analyze
114
+ ✓ Analysis complete (deterministic discovery; no AI involved).
115
+ Files scanned: 893
116
+ Ecosystems: node; package manager: npm
117
+ Monorepo: multi-package (backend, frontend)
118
+ Verification commands found: typecheck, unit, integration, lint, build
119
+ Wrote: .devworkspace/context/commands.json
120
+ Wrote: .devworkspace/analysis/onboarding-prompt.md
121
+
122
+ # Step 3: Install instructions for your coding agent
123
+ $ npx devworkspace agent install --agent all
124
+ ✓ codex instructions processed: CREATE AGENTS.md
125
+ ✓ cursor instructions processed: CREATE .cursor/rules/devworkspace.mdc
126
+ ✓ copilot instructions processed: CREATE .github/copilot-instructions.md
127
+
128
+ # Step 4: The agent starts working on a new feature
129
+ $ npx devworkspace task new "Add invoice PDF generation endpoint"
130
+ ✓ Created T-20261102-4a1b
131
+ type: FEATURE (classified)
132
+ required verification: unit, typecheck, lint, build, review
133
+ workflow: Check git status. Read relevant facts and decisions.
134
+
135
+ # Step 5: After coding, the agent runs contract checks
136
+ $ npx devworkspace task run T-20261102-4a1b unit
137
+ ok [backend] npm run test:unit (exit code 0, 1.4s)
138
+ ok [frontend] npm test (exit code 0, 2.1s)
139
+
140
+ # Step 6: The agent attests that user work was untouched and finishes
141
+ $ npx devworkspace task attest T-20261102-4a1b --user-work-intact --knowledge-reviewed --final-state-inspected
142
+ ✓ Attestations recorded.
143
+
144
+ $ npx devworkspace task status T-20261102-4a1b COMPLETED --note "Implemented with PDFKit; 14 tests passing"
145
+ ✓ T-20261102-4a1b is now COMPLETED
146
+ ```
147
+
148
+ ---
149
+
150
+ ## 6. Zero Runtime Dependencies
151
+
152
+ One of the most remarkable technical decisions in DevWorkspace is that `package.json` contains:
153
+
154
+ ```json
155
+ "dependencies": {}
156
+ ```
157
+
158
+ DevWorkspace has **zero third-party production dependencies**. Everything—JSON validation, child process execution, argument parsing, file hashing, symlink canonicalization, lockfiles, and terminal formatting—is implemented entirely using standard **Node.js 20+ built-in modules** (`node:fs/promises`, `node:path`, `node:child_process`, `node:crypto`, `node:util`, `node:os`).
159
+
160
+ This guarantees:
161
+ - **Instant execution**: No `node_modules` installation delay when running via `npx devworkspace`.
162
+ - **Zero supply-chain vulnerability risk**: No deeply nested third-party packages that could be hijacked.
163
+ - **Maximum portability**: Runs identically across Linux, macOS, and Windows.
164
+
165
+ ---
166
+
167
+ *Continue to [Chapter 2: System Architecture](./02-system-architecture.md) for the detailed layer breakdown and component interaction model.*
168
+