devworkspace 0.3.0 → 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.
- package/CHANGELOG.md +42 -1
- package/README.md +8 -5
- package/dist/agents/claude/adapter.d.ts +3 -14
- package/dist/agents/claude/adapter.js +46 -49
- package/dist/agents/claude/adapter.js.map +1 -1
- package/dist/agents/codex/adapter.d.ts +2 -0
- package/dist/agents/codex/adapter.js +61 -0
- package/dist/agents/codex/adapter.js.map +1 -0
- package/dist/agents/copilot/adapter.d.ts +2 -0
- package/dist/agents/copilot/adapter.js +62 -0
- package/dist/agents/copilot/adapter.js.map +1 -0
- package/dist/agents/cursor/adapter.d.ts +2 -0
- package/dist/agents/cursor/adapter.js +127 -0
- package/dist/agents/cursor/adapter.js.map +1 -0
- package/dist/agents/index.d.ts +15 -0
- package/dist/agents/index.js +54 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/shared.d.ts +20 -0
- package/dist/agents/shared.js +76 -0
- package/dist/agents/shared.js.map +1 -0
- package/dist/agents/types.d.ts +16 -1
- package/dist/agents/types.js.map +1 -1
- package/dist/cli/args.d.ts +42 -0
- package/dist/cli/args.js +12 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/help.js +64 -10
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/render.d.ts +12 -1
- package/dist/cli/render.js +188 -0
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/run.js +100 -9
- package/dist/cli/run.js.map +1 -1
- package/dist/config/schemas.d.ts +6 -0
- package/dist/config/schemas.js +6 -0
- package/dist/config/schemas.js.map +1 -1
- package/dist/core/version.d.ts +7 -0
- package/dist/core/version.js +13 -0
- package/dist/core/version.js.map +1 -1
- package/dist/core/workspace.d.ts +1 -0
- package/dist/core/workspace.js +1 -0
- package/dist/core/workspace.js.map +1 -1
- package/dist/discovery/commands.d.ts +1 -0
- package/dist/discovery/commands.js +3 -1
- package/dist/discovery/commands.js.map +1 -1
- package/dist/features/schema.d.ts +3 -0
- package/dist/features/schema.js +79 -0
- package/dist/features/schema.js.map +1 -0
- package/dist/features/types.d.ts +77 -0
- package/dist/features/types.js +2 -0
- package/dist/features/types.js.map +1 -0
- package/dist/features/validate.d.ts +14 -0
- package/dist/features/validate.js +124 -0
- package/dist/features/validate.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/claudePlugin.d.ts +12 -0
- package/dist/integrations/adapters/claudePlugin.js +37 -8
- package/dist/integrations/adapters/claudePlugin.js.map +1 -1
- package/dist/integrations/adapters/pluginSkill.js +5 -0
- package/dist/integrations/adapters/pluginSkill.js.map +1 -1
- package/dist/security/files.js +10 -2
- package/dist/security/files.js.map +1 -1
- package/dist/security/redact.js +1 -1
- package/dist/security/redact.js.map +1 -1
- package/dist/services/agent.d.ts +12 -2
- package/dist/services/agent.js +96 -14
- package/dist/services/agent.js.map +1 -1
- package/dist/services/analysis.js +3 -3
- package/dist/services/analysis.js.map +1 -1
- package/dist/services/doctor.js +65 -14
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/drift.d.ts +21 -0
- package/dist/services/drift.js +89 -0
- package/dist/services/drift.js.map +1 -0
- package/dist/services/features.d.ts +22 -0
- package/dist/services/features.js +105 -0
- package/dist/services/features.js.map +1 -0
- package/dist/services/graph.d.ts +97 -0
- package/dist/services/graph.js +342 -0
- package/dist/services/graph.js.map +1 -0
- package/dist/services/refresh.js +15 -0
- package/dist/services/refresh.js.map +1 -1
- package/dist/services/reset.js +45 -5
- package/dist/services/reset.js.map +1 -1
- package/dist/services/setup.d.ts +56 -0
- package/dist/services/setup.js +116 -0
- package/dist/services/setup.js.map +1 -0
- package/dist/services/status.d.ts +8 -0
- package/dist/services/status.js +78 -10
- package/dist/services/status.js.map +1 -1
- package/dist/services/tasks.js +6 -1
- package/dist/services/tasks.js.map +1 -1
- package/dist/services/verify.d.ts +11 -0
- package/dist/services/verify.js +64 -2
- package/dist/services/verify.js.map +1 -1
- package/dist/tasks/routing.js +14 -10
- package/dist/tasks/routing.js.map +1 -1
- package/dist/tasks/task.js +6 -2
- package/dist/tasks/task.js.map +1 -1
- package/dist/verification/scope.js +1 -1
- package/dist/verification/scope.js.map +1 -1
- package/docs/agents.md +60 -0
- package/docs/architecture-report/01-executive-summary.md +168 -0
- package/docs/architecture-report/02-system-architecture.md +356 -0
- package/docs/architecture-report/03-tools-and-technologies.md +112 -0
- package/docs/architecture-report/04-execution-flows.md +257 -0
- package/docs/architecture-report/05-codebase-map.md +150 -0
- package/docs/architecture-report/06-command-reference.md +446 -0
- package/docs/architecture-report/07-data-flow-and-integrations.md +268 -0
- package/docs/architecture-report/08-build-test-deployment.md +185 -0
- package/docs/architecture-report/09-security-and-reliability.md +165 -0
- package/docs/architecture-report/10-feature-status.md +110 -0
- package/docs/architecture-report/11-glossary.md +97 -0
- package/docs/architecture-report/README.md +103 -0
- package/docs/architecture-report/diagrams.md +446 -0
- package/docs/architecture.md +2 -2
- package/docs/getting-started.md +38 -1
- package/package.json +1 -1
package/dist/tasks/task.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/tasks/task.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { DevWorkspaceError } from '../errors/index.js';\nimport { Check } from '../config/validate.js';\nimport { SCHEMA_VERSION, type CommandEntry } from '../config/schemas.js';\nimport { atomicWriteJson, ensureDir, pathExists, randomId } from '../utils/fs.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { backupIfVersionChanges, type Ws } from '../core/workspace.js';\nimport { containsSecret } from '../security/redact.js';\n\nexport const TASK_TYPES = [\n 'QUESTION',\n 'BUG',\n 'FEATURE',\n 'REFACTOR',\n 'DOCUMENTATION',\n 'TESTING',\n 'PERFORMANCE',\n 'SECURITY',\n 'ARCHITECTURE',\n 'RELEASE',\n 'MAINTENANCE',\n] as const;\nexport type TaskType = (typeof TASK_TYPES)[number];\n\nexport const TASK_STATUSES = ['IDEA', 'SPECIFIED', 'PLANNED', 'IN_PROGRESS', 'TESTING', 'REVIEW', 'BLOCKED', 'FAILED', 'COMPLETED'] as const;\nexport type TaskStatus = (typeof TASK_STATUSES)[number];\n\nexport const VERIFY_STATUSES = ['PENDING', 'PASS', 'FAIL', 'SKIPPED', 'COULD_NOT_RUN'] as const;\nexport type VerifyStatus = (typeof VERIFY_STATUSES)[number];\n\n/**\n * One recorded result for one package. `executed` means DevWorkspace ran the contract command itself and saw the exit\n * code; `claimed` is somebody's report (agent or person) that DevWorkspace could not observe.\n */\nexport interface Evidence {\n kind: 'executed' | 'claimed';\n at: string;\n /** Package directory relative to the project root; \".\" for the root. */\n package: string;\n command?: string;\n exitCode?: number | null;\n durationMs?: number;\n /** Fingerprint of the task's changes inside this package when the result was recorded. */\n scope?: string;\n /** A claim the user explicitly vouched for (--reason user-override). */\n userOverride?: boolean;\n /** One-line, scrubbed explanation (failure tail or refusal reason). Never a connection string or credential. */\n note?: string;\n}\n\nexport interface VerificationItem {\n check: string;\n required: boolean;\n status: VerifyStatus;\n reason?: string;\n detail?: string;\n updatedAt?: string;\n /** Latest result per package. Absent on tasks recorded by older versions. */\n evidence?: Evidence[];\n}\n\n/** Files that were already modified when the task was created, so they are not blamed on the task. */\nexport interface TaskScope {\n capturedAt: string;\n /** Git HEAD when the task was created; null outside a repository. */\n head: string | null;\n /** Project-relative path -> content hash of files already modified at creation (\"deleted\" for removed files). */\n baseline: Record<string, string>;\n}\n\nexport interface TestCounts {\n passed: number;\n failed: number;\n}\n\nexport interface Attestations {\n userWorkIntact: boolean;\n knowledgeReviewed: boolean;\n finalStateInspected: boolean;\n}\n\nexport interface Task {\n schemaVersion: number;\n id: string;\n title: string;\n type: TaskType;\n status: TaskStatus;\n createdAt: string;\n updatedAt: string;\n description: string;\n acceptanceCriteria: string[];\n plan: string[];\n affectedAreas: string[];\n verification: VerificationItem[];\n tests: { baseline?: TestCounts; after?: TestCounts };\n attestations: Attestations;\n /** Present on tasks created by 0.2.2+: enables package-aware, evidence-based completion. */\n scope?: TaskScope;\n decisions: string[];\n blockers: string[];\n constraints: string[];\n completionSummary?: string;\n history: { at: string; from: TaskStatus | null; to: TaskStatus; note?: string }[];\n}\n\nconst TRANSITIONS: Record<TaskStatus, TaskStatus[]> = {\n IDEA: ['SPECIFIED', 'PLANNED', 'IN_PROGRESS', 'BLOCKED', 'FAILED'],\n SPECIFIED: ['PLANNED', 'IN_PROGRESS', 'BLOCKED', 'IDEA'],\n PLANNED: ['IN_PROGRESS', 'SPECIFIED', 'BLOCKED', 'IDEA'],\n IN_PROGRESS: ['TESTING', 'REVIEW', 'COMPLETED', 'BLOCKED', 'FAILED', 'PLANNED'],\n TESTING: ['IN_PROGRESS', 'REVIEW', 'COMPLETED', 'BLOCKED', 'FAILED'],\n REVIEW: ['IN_PROGRESS', 'TESTING', 'COMPLETED', 'BLOCKED', 'FAILED'],\n BLOCKED: ['IN_PROGRESS', 'PLANNED', 'SPECIFIED', 'IDEA', 'FAILED'],\n FAILED: ['IN_PROGRESS', 'IDEA'],\n COMPLETED: ['IN_PROGRESS'],\n};\n\nexport function allowedTransitions(from: TaskStatus): TaskStatus[] {\n return TRANSITIONS[from];\n}\n\nconst CODE_CHANGING: TaskType[] = ['BUG', 'FEATURE', 'REFACTOR', 'PERFORMANCE', 'SECURITY', 'ARCHITECTURE', 'MAINTENANCE', 'TESTING', 'RELEASE'];\n\nconst CHECKS_BY_TYPE: Record<TaskType, string[]> = {\n QUESTION: [],\n DOCUMENTATION: [],\n BUG: ['unit', 'typecheck', 'lint', 'build'],\n FEATURE: ['unit', 'typecheck', 'lint', 'build', 'review'],\n REFACTOR: ['unit', 'typecheck', 'lint', 'build', 'review'],\n TESTING: ['unit', 'typecheck', 'lint'],\n PERFORMANCE: ['unit', 'build', 'review'],\n SECURITY: ['unit', 'typecheck', 'lint', 'build', 'review'],\n ARCHITECTURE: ['unit', 'typecheck', 'lint', 'build', 'review'],\n RELEASE: ['unit', 'typecheck', 'lint', 'build', 'integration', 'e2e'],\n MAINTENANCE: ['lint', 'build'],\n};\n\nexport function isCodeChanging(type: TaskType): boolean {\n return CODE_CHANGING.includes(type);\n}\n\n/** Verification a task of this type needs, given what the project actually offers. Unavailable checks are never demanded. */\nexport function requiredChecksFor(type: TaskType, contract: CommandEntry[], reviewLevel: 'off' | 'light' | 'strict' = 'light'): VerificationItem[] {\n const available = new Set(contract.filter((c) => c.available).map((c) => c.id as string));\n const items: VerificationItem[] = [];\n for (const check of CHECKS_BY_TYPE[type]) {\n if (check === 'review') {\n if (reviewLevel === 'off') continue;\n } else if (!available.has(check)) continue;\n items.push({ check, required: true, status: 'PENDING' });\n }\n return items;\n}\n\nexport function newTaskId(now: Date = new Date()): string {\n const d = now.toISOString().slice(0, 10).replace(/-/g, '');\n return `T-${d}-${randomId(2)}`;\n}\n\nexport interface NewTaskInput {\n title: string;\n type: TaskType;\n description?: string;\n verification: VerificationItem[];\n constraints?: string[];\n}\n\nexport function createTaskObject(input: NewTaskInput, now: string, id = newTaskId()): Task {\n const title = input.title.trim().slice(0, 200);\n if (!title) throw new DevWorkspaceError('USAGE', 'Task title must not be empty.');\n const task: Task = {\n schemaVersion: SCHEMA_VERSION,\n id,\n title,\n type: input.type,\n status: 'IDEA',\n createdAt: now,\n updatedAt: now,\n description: (input.description ?? '').trim().slice(0, 4000),\n acceptanceCriteria: [],\n plan: [],\n affectedAreas: [],\n verification: input.verification,\n tests: {},\n attestations: { userWorkIntact: false, knowledgeReviewed: false, finalStateInspected: false },\n decisions: [],\n blockers: [],\n constraints: input.constraints ?? [],\n history: [{ at: now, from: null, to: 'IDEA' }],\n };\n assertNoSecrets(task);\n return task;\n}\n\nexport function assertNoSecrets(task: Task): void {\n if (containsSecret(JSON.stringify(task))) {\n throw new DevWorkspaceError('SECURITY', 'Task content looks like it contains a secret; refusing to store it.', {\n hint: 'Remove credential values from titles, plans and notes.',\n });\n }\n}\n\nexport function validateTask(v: unknown, file = 'task'): Task {\n const c = new Check(file);\n const o = c.obj(v);\n c.at_('schemaVersion').int(o.schemaVersion, 1);\n c.at_('id').str(o.id, { min: 3, max: 64 });\n c.at_('title').str(o.title, { min: 1, max: 300 });\n c.at_('type').oneOf(o.type, TASK_TYPES);\n c.at_('status').oneOf(o.status, TASK_STATUSES);\n c.at_('createdAt').iso(o.createdAt);\n c.at_('updatedAt').iso(o.updatedAt);\n for (const k of ['acceptanceCriteria', 'plan', 'affectedAreas', 'decisions', 'blockers', 'constraints'] as const) c.at_(k).strArr(o[k]);\n c.at_('verification')\n .arr(o.verification, 100)\n .forEach((item, i) => {\n const ic = c.at_(`verification.${i}`);\n const io = ic.obj(item);\n ic.at_('check').str(io.check, { max: 50 });\n ic.at_('required').bool(io.required);\n ic.at_('status').oneOf(io.status, VERIFY_STATUSES);\n if (io.evidence !== undefined) {\n ic.at_('evidence')\n .arr(io.evidence, 100)\n .forEach((e, j) => {\n const ec = c.at_(`verification.${i}.evidence.${j}`);\n const eo = ec.obj(e);\n ec.at_('kind').oneOf(eo.kind, ['executed', 'claimed'] as const);\n ec.at_('package').str(eo.package, { max: 240 });\n });\n }\n });\n if (o.scope !== undefined) {\n const sc = c.at_('scope').obj(o.scope);\n c.at_('scope.capturedAt').iso(sc.capturedAt);\n c.at_('scope.baseline').obj(sc.baseline);\n }\n const a = c.at_('attestations').obj(o.attestations);\n c.at_('attestations.userWorkIntact').bool(a.userWorkIntact);\n c.at_('attestations.knowledgeReviewed').bool(a.knowledgeReviewed);\n c.at_('attestations.finalStateInspected').bool(a.finalStateInspected);\n c.at_('tests').obj(o.tests);\n c.at_('history').arr(o.history, 500);\n return o as unknown as Task;\n}\n\nexport interface GateResult {\n ok: boolean;\n failures: string[];\n warnings: string[];\n}\n\n/** What the gate needs to know beyond the task itself: the contract and what the task changed, per package. */\nexport interface GateContext {\n contract: CommandEntry[];\n /**\n * Fingerprint of the task's changes inside each package (\".\" = everything). `null` means the changes could not be\n * determined (not a Git repository, or nothing changed since the task started), so every package counts as affected.\n */\n scope: Record<string, string> | null;\n}\n\nconst UNKNOWN_SCOPE = 'unknown';\n\n/** Per-package requirements of one check. Returns false when the contract has no applicable package entry. */\nfunction packageGate(v: VerificationItem, ctx: GateContext, failures: string[], warnings: string[]): boolean {\n const entries = ctx.contract.filter((c) => c.id === v.check && c.available && !c.mutates);\n if (entries.length === 0) return false;\n const known = ctx.scope !== null;\n const unknown = !known;\n let applicable = 0;\n for (const entry of entries) {\n const pkg = entry.cwd ?? '.';\n const fp = known ? ctx.scope![pkg] : UNKNOWN_SCOPE;\n if (fp === undefined) continue; // this package was not changed, so this check does not apply to it\n applicable++;\n const label = `${v.check} [${pkg}]`;\n const ev = v.evidence?.find((e) => e.package === pkg);\n if (!ev) failures.push(`${label}: not run for the current changes`);\n else if (ev.kind === 'claimed' && !ev.userOverride) failures.push(`${label}: only claimed, not executed (run: devworkspace task run <id> ${v.check} --package ${pkg})`);\n else if (ev.kind === 'claimed') warnings.push(`${label}: accepted on the user's word; DevWorkspace did not observe it run`);\n else if (ev.exitCode !== 0) failures.push(`${label}: FAIL (exit ${ev.exitCode ?? 'none'})`);\n else if (!unknown && ev.scope !== fp) failures.push(`${label}: passed, but files changed afterwards; run it again`);\n }\n if (known && applicable === 0) warnings.push(`${v.check}: no package with this check was changed`);\n return true;\n}\n\n/**\n * The completion gate. A task is only COMPLETED when every applicable requirement holds.\n * Tasks that carry a `scope` (created by 0.2.2+) are checked per changed package against executed evidence; older\n * tasks keep the original rules.\n */\nexport function evaluateGate(task: Task, ctx?: GateContext): GateResult {\n const failures: string[] = [];\n const warnings: string[] = [];\n const scoped = !!ctx && !!task.scope;\n for (const v of task.verification) {\n if (!v.required) continue;\n if (v.status === 'FAIL') failures.push(`${v.check}: FAIL`);\n else if (v.status === 'COULD_NOT_RUN') failures.push(`${v.check}: could not run${v.detail ? ` (${v.detail})` : ''}`);\n else if (v.status === 'SKIPPED') {\n if (v.reason === 'user-override') warnings.push(`${v.check}: skipped at the user's request; completion is less certain`);\n else failures.push(`${v.check}: skipped without a user override`);\n } else if (scoped && packageGate(v, ctx!, failures, warnings)) {\n // handled per package\n } else if (v.status === 'PENDING') failures.push(`${v.check}: not run yet`);\n }\n const { baseline, after } = task.tests;\n if (baseline && !after) failures.push('baseline test results recorded, but no results after the change');\n if (baseline && after) {\n if (after.failed > baseline.failed) failures.push(`regression: failures rose from ${baseline.failed} to ${after.failed}`);\n if (after.passed < baseline.passed) failures.push(`regression: passing tests fell from ${baseline.passed} to ${after.passed}`);\n }\n if (isCodeChanging(task.type)) {\n if (!task.attestations.userWorkIntact) failures.push('not confirmed: no user work was overwritten');\n if (!task.attestations.knowledgeReviewed) failures.push('not confirmed: project knowledge was reviewed for updates');\n if (!task.attestations.finalStateInspected) failures.push('not confirmed: final repository state was inspected');\n }\n if ((isCodeChanging(task.type) || task.type === 'DOCUMENTATION') && !(task.completionSummary ?? '').trim()) {\n failures.push('completion summary is missing');\n }\n return { ok: failures.length === 0, failures, warnings };\n}\n\nexport function transitionTask(task: Task, to: TaskStatus, now: string, note?: string, ctx?: GateContext): GateResult | null {\n if (task.status === to) return null;\n if (!TRANSITIONS[task.status].includes(to)) {\n throw new DevWorkspaceError('GATE', `Cannot move a task from ${task.status} to ${to}.`, {\n hint: `Allowed from ${task.status}: ${TRANSITIONS[task.status].join(', ')}.`,\n });\n }\n let gate: GateResult | null = null;\n if (to === 'COMPLETED') {\n gate = evaluateGate(task, ctx);\n if (!gate.ok) {\n throw new DevWorkspaceError('GATE', `Task ${task.id} cannot be completed:\\n - ${gate.failures.join('\\n - ')}`, {\n hint: 'Resolve the items above (or mark the task BLOCKED/FAILED). A task is never complete while verification is failing.',\n });\n }\n }\n task.history.push({ at: now, from: task.status, to, ...(note ? { note: note.slice(0, 300) } : {}) });\n task.status = to;\n task.updatedAt = now;\n return gate;\n}\n\nexport function nextRequiredStep(task: Task, ctx?: GateContext): string {\n switch (task.status) {\n case 'COMPLETED':\n return 'None. The task is complete.';\n case 'FAILED':\n return 'Review the failure, then move the task back to IN_PROGRESS or close the idea.';\n case 'BLOCKED':\n return task.blockers.length > 0 ? `Resolve blocker: ${task.blockers[task.blockers.length - 1]}` : 'Identify and record what blocks this task.';\n case 'IDEA':\n return 'Clarify acceptance criteria, then plan.';\n case 'SPECIFIED':\n return 'Write a plan.';\n case 'PLANNED':\n return 'Start implementation (baseline verification first for meaningful changes).';\n default: {\n const pending = task.verification.filter((v) => v.required && (v.status === 'PENDING' || v.status === 'FAIL' || v.status === 'COULD_NOT_RUN'));\n if (pending.length > 0) return `Run/fix verification: ${pending.map((p) => `${p.check} (${p.status.toLowerCase().replace(/_/g, ' ')})`).join(', ')}.`;\n const g = evaluateGate(task, ctx);\n return g.ok ? 'All gates pass. Mark the task COMPLETED.' : `Satisfy the completion gate: ${g.failures[0]}`;\n }\n }\n}\n\n// ---------- storage ----------\n\nfunction taskFile(ws: Ws, task: Pick<Task, 'id' | 'status'>): string {\n return path.join(task.status === 'COMPLETED' ? ws.tasksCompleted : ws.tasksActive, `${task.id}.json`);\n}\n\nexport async function saveTask(ws: Ws, task: Task): Promise<void> {\n validateTask(task);\n assertNoSecrets(task);\n const dest = taskFile(ws, task);\n await backupIfVersionChanges(ws, dest, task.schemaVersion);\n await ensureDir(path.dirname(dest));\n await atomicWriteJson(dest, task);\n const other = path.join(task.status === 'COMPLETED' ? ws.tasksActive : ws.tasksCompleted, `${task.id}.json`);\n await fs.rm(other, { force: true });\n}\n\nexport async function loadTask(ws: Ws, idOrPrefix: string): Promise<Task> {\n for (const dir of [ws.tasksActive, ws.tasksCompleted]) {\n if (!(await pathExists(dir))) continue;\n const names = (await fs.readdir(dir)).filter((n) => n.endsWith('.json'));\n const hits = names.filter((n) => n === `${idOrPrefix}.json` || n.startsWith(idOrPrefix));\n if (hits.length > 1) {\n const exact = hits.find((n) => n === `${idOrPrefix}.json`);\n if (!exact) throw new DevWorkspaceError('USAGE', `Task id \"${idOrPrefix}\" is ambiguous.`, { hint: 'Use more characters of the id.' });\n hits.splice(0, hits.length, exact);\n }\n if (hits.length === 1) {\n const file = path.join(dir, hits[0]!);\n return (await readVersioned(file, 'task', SCHEMA_VERSION, validateTask)).data;\n }\n }\n throw new DevWorkspaceError('NOT_FOUND', `No task matching \"${idOrPrefix}\".`, { hint: 'List tasks with \"devworkspace task list --all\".' });\n}\n\nexport interface TaskListing {\n tasks: Task[];\n corrupt: { file: string; error: string }[];\n}\n\nexport async function listTasks(ws: Ws, opts: { includeCompleted?: boolean } = {}): Promise<TaskListing> {\n const tasks: Task[] = [];\n const corrupt: { file: string; error: string }[] = [];\n const dirs = opts.includeCompleted ? [ws.tasksActive, ws.tasksCompleted] : [ws.tasksActive];\n for (const dir of dirs) {\n if (!(await pathExists(dir))) continue;\n for (const name of (await fs.readdir(dir)).filter((n) => n.endsWith('.json')).sort()) {\n try {\n tasks.push((await readVersioned(path.join(dir, name), 'task', SCHEMA_VERSION, validateTask)).data);\n } catch (e) {\n corrupt.push({ file: `${path.basename(dir)}/${name}`, error: (e as Error).message });\n }\n }\n }\n tasks.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n return { tasks, corrupt };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/tasks/task.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { DevWorkspaceError } from '../errors/index.js';\nimport { Check } from '../config/validate.js';\nimport { SCHEMA_VERSION, type CommandEntry } from '../config/schemas.js';\nimport { atomicWriteJson, ensureDir, pathExists, randomId } from '../utils/fs.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { backupIfVersionChanges, type Ws } from '../core/workspace.js';\nimport { containsSecret } from '../security/redact.js';\n\nexport const TASK_TYPES = [\n 'QUESTION',\n 'BUG',\n 'FEATURE',\n 'REFACTOR',\n 'DOCUMENTATION',\n 'TESTING',\n 'PERFORMANCE',\n 'SECURITY',\n 'ARCHITECTURE',\n 'RELEASE',\n 'MAINTENANCE',\n] as const;\nexport type TaskType = (typeof TASK_TYPES)[number];\n\nexport const TASK_STATUSES = ['IDEA', 'SPECIFIED', 'PLANNED', 'IN_PROGRESS', 'TESTING', 'REVIEW', 'BLOCKED', 'FAILED', 'COMPLETED'] as const;\nexport type TaskStatus = (typeof TASK_STATUSES)[number];\n\nexport const VERIFY_STATUSES = ['PENDING', 'PASS', 'FAIL', 'SKIPPED', 'COULD_NOT_RUN'] as const;\nexport type VerifyStatus = (typeof VERIFY_STATUSES)[number];\n\n/**\n * One recorded result for one package. `executed` means DevWorkspace ran the contract command itself and saw the exit\n * code; `claimed` is somebody's report (agent or person) that DevWorkspace could not observe.\n */\nexport interface Evidence {\n kind: 'executed' | 'claimed';\n at: string;\n /** Package directory relative to the project root; \".\" for the root. */\n package: string;\n command?: string;\n exitCode?: number | null;\n durationMs?: number;\n /** Fingerprint of the task's changes inside this package when the result was recorded. */\n scope?: string;\n /** A claim the user explicitly vouched for (--reason user-override). */\n userOverride?: boolean;\n /** One-line, scrubbed explanation (failure tail or refusal reason). Never a connection string or credential. */\n note?: string;\n}\n\nexport interface VerificationItem {\n check: string;\n required: boolean;\n status: VerifyStatus;\n reason?: string;\n detail?: string;\n updatedAt?: string;\n /** Latest result per package. Absent on tasks recorded by older versions. */\n evidence?: Evidence[];\n}\n\n/** Files that were already modified when the task was created, so they are not blamed on the task. */\nexport interface TaskScope {\n capturedAt: string;\n /** Git HEAD when the task was created; null outside a repository. */\n head: string | null;\n /** Project-relative path -> content hash of files already modified at creation (\"deleted\" for removed files). */\n baseline: Record<string, string>;\n}\n\nexport interface TestCounts {\n passed: number;\n failed: number;\n}\n\nexport interface Attestations {\n userWorkIntact: boolean;\n knowledgeReviewed: boolean;\n finalStateInspected: boolean;\n}\n\nexport interface Task {\n schemaVersion: number;\n id: string;\n title: string;\n type: TaskType;\n status: TaskStatus;\n createdAt: string;\n updatedAt: string;\n description: string;\n acceptanceCriteria: string[];\n plan: string[];\n affectedAreas: string[];\n verification: VerificationItem[];\n tests: { baseline?: TestCounts; after?: TestCounts };\n attestations: Attestations;\n /** Present on tasks created by 0.2.2+: enables package-aware, evidence-based completion. */\n scope?: TaskScope;\n decisions: string[];\n blockers: string[];\n constraints: string[];\n completionSummary?: string;\n history: { at: string; from: TaskStatus | null; to: TaskStatus; note?: string }[];\n}\n\nconst TRANSITIONS: Record<TaskStatus, TaskStatus[]> = {\n IDEA: ['SPECIFIED', 'PLANNED', 'IN_PROGRESS', 'BLOCKED', 'FAILED'],\n SPECIFIED: ['PLANNED', 'IN_PROGRESS', 'BLOCKED', 'IDEA'],\n PLANNED: ['IN_PROGRESS', 'SPECIFIED', 'BLOCKED', 'IDEA'],\n IN_PROGRESS: ['TESTING', 'REVIEW', 'COMPLETED', 'BLOCKED', 'FAILED', 'PLANNED'],\n TESTING: ['IN_PROGRESS', 'REVIEW', 'COMPLETED', 'BLOCKED', 'FAILED'],\n REVIEW: ['IN_PROGRESS', 'TESTING', 'COMPLETED', 'BLOCKED', 'FAILED'],\n BLOCKED: ['IN_PROGRESS', 'PLANNED', 'SPECIFIED', 'IDEA', 'FAILED'],\n FAILED: ['IN_PROGRESS', 'IDEA'],\n COMPLETED: ['IN_PROGRESS'],\n};\n\nexport function allowedTransitions(from: TaskStatus): TaskStatus[] {\n return TRANSITIONS[from];\n}\n\nconst CODE_CHANGING: TaskType[] = ['BUG', 'FEATURE', 'REFACTOR', 'PERFORMANCE', 'SECURITY', 'ARCHITECTURE', 'MAINTENANCE', 'TESTING', 'RELEASE'];\n\nconst CHECKS_BY_TYPE: Record<TaskType, string[]> = {\n QUESTION: [],\n DOCUMENTATION: [],\n BUG: ['unit', 'typecheck', 'lint', 'build'],\n FEATURE: ['unit', 'typecheck', 'lint', 'build', 'review'],\n REFACTOR: ['unit', 'typecheck', 'lint', 'build', 'review'],\n TESTING: ['unit', 'typecheck', 'lint'],\n PERFORMANCE: ['unit', 'build', 'review'],\n SECURITY: ['unit', 'typecheck', 'lint', 'build', 'review'],\n ARCHITECTURE: ['unit', 'typecheck', 'lint', 'build', 'review'],\n RELEASE: ['unit', 'typecheck', 'lint', 'build', 'integration', 'e2e'],\n MAINTENANCE: ['lint', 'build'],\n};\n\nexport function isCodeChanging(type: TaskType): boolean {\n return CODE_CHANGING.includes(type);\n}\n\n/** Verification a task of this type needs, given what the project actually offers. Unavailable checks are never demanded. */\nexport function requiredChecksFor(type: TaskType, contract: CommandEntry[], reviewLevel: 'off' | 'light' | 'strict' = 'light'): VerificationItem[] {\n const available = new Set(contract.filter((c) => c.available).map((c) => c.id as string));\n const items: VerificationItem[] = [];\n for (const check of CHECKS_BY_TYPE[type]) {\n if (check === 'review') {\n if (reviewLevel === 'off') continue;\n } else if (!available.has(check)) continue;\n items.push({ check, required: true, status: 'PENDING' });\n }\n return items;\n}\n\nexport function newTaskId(now: Date = new Date()): string {\n const d = now.toISOString().slice(0, 10).replace(/-/g, '');\n return `T-${d}-${randomId(2)}`;\n}\n\nexport interface NewTaskInput {\n title: string;\n type: TaskType;\n description?: string;\n verification: VerificationItem[];\n constraints?: string[];\n}\n\nexport function createTaskObject(input: NewTaskInput, now: string, id = newTaskId()): Task {\n const title = input.title.trim().slice(0, 200);\n if (!title) throw new DevWorkspaceError('USAGE', 'Task title must not be empty.');\n const task: Task = {\n schemaVersion: SCHEMA_VERSION,\n id,\n title,\n type: input.type,\n status: 'IDEA',\n createdAt: now,\n updatedAt: now,\n description: (input.description ?? '').trim().slice(0, 4000),\n acceptanceCriteria: [],\n plan: [],\n affectedAreas: [],\n verification: input.verification,\n tests: {},\n attestations: { userWorkIntact: false, knowledgeReviewed: false, finalStateInspected: false },\n decisions: [],\n blockers: [],\n constraints: input.constraints ?? [],\n history: [{ at: now, from: null, to: 'IDEA' }],\n };\n assertNoSecrets(task);\n return task;\n}\n\nexport function assertNoSecrets(task: Task): void {\n if (containsSecret(JSON.stringify(task))) {\n throw new DevWorkspaceError('SECURITY', 'Task content looks like it contains a secret; refusing to store it.', {\n hint: 'Remove credential values from titles, plans and notes.',\n });\n }\n}\n\nexport function validateTask(v: unknown, file = 'task'): Task {\n const c = new Check(file);\n const o = c.obj(v);\n c.at_('schemaVersion').int(o.schemaVersion, 1);\n c.at_('id').str(o.id, { min: 3, max: 64 });\n c.at_('title').str(o.title, { min: 1, max: 300 });\n c.at_('type').oneOf(o.type, TASK_TYPES);\n c.at_('status').oneOf(o.status, TASK_STATUSES);\n c.at_('createdAt').iso(o.createdAt);\n c.at_('updatedAt').iso(o.updatedAt);\n for (const k of ['acceptanceCriteria', 'plan', 'affectedAreas', 'decisions', 'blockers', 'constraints'] as const) c.at_(k).strArr(o[k]);\n c.at_('verification')\n .arr(o.verification, 100)\n .forEach((item, i) => {\n const ic = c.at_(`verification.${i}`);\n const io = ic.obj(item);\n ic.at_('check').str(io.check, { max: 50 });\n ic.at_('required').bool(io.required);\n ic.at_('status').oneOf(io.status, VERIFY_STATUSES);\n if (io.evidence !== undefined) {\n ic.at_('evidence')\n .arr(io.evidence, 100)\n .forEach((e, j) => {\n const ec = c.at_(`verification.${i}.evidence.${j}`);\n const eo = ec.obj(e);\n ec.at_('kind').oneOf(eo.kind, ['executed', 'claimed'] as const);\n ec.at_('package').str(eo.package, { max: 240 });\n });\n }\n });\n if (o.scope !== undefined) {\n const sc = c.at_('scope').obj(o.scope);\n c.at_('scope.capturedAt').iso(sc.capturedAt);\n c.at_('scope.baseline').obj(sc.baseline);\n }\n const a = c.at_('attestations').obj(o.attestations);\n c.at_('attestations.userWorkIntact').bool(a.userWorkIntact);\n c.at_('attestations.knowledgeReviewed').bool(a.knowledgeReviewed);\n c.at_('attestations.finalStateInspected').bool(a.finalStateInspected);\n c.at_('tests').obj(o.tests);\n c.at_('history').arr(o.history, 500);\n return o as unknown as Task;\n}\n\nexport interface GateResult {\n ok: boolean;\n failures: string[];\n warnings: string[];\n}\n\n/** What the gate needs to know beyond the task itself: the contract and what the task changed, per package. */\nexport interface GateContext {\n contract: CommandEntry[];\n /**\n * Fingerprint of the task's changes inside each package (\".\" = everything). `null` means the changes could not be\n * determined (not a Git repository, or nothing changed since the task started), so every package counts as affected.\n */\n scope: Record<string, string> | null;\n}\n\nconst UNKNOWN_SCOPE = 'unknown';\n\n/** Per-package requirements of one check. Returns false when the contract has no applicable package entry. */\nfunction packageGate(v: VerificationItem, ctx: GateContext, failures: string[], warnings: string[]): boolean {\n const entries = ctx.contract.filter((c) => c.id === v.check && c.available && !c.mutates);\n if (entries.length === 0) return false;\n const known = ctx.scope !== null;\n const unknown = !known;\n let applicable = 0;\n for (const entry of entries) {\n const pkg = entry.cwd ?? '.';\n const fp = known ? ctx.scope![pkg] : UNKNOWN_SCOPE;\n if (fp === undefined) continue; // this package was not changed, so this check does not apply to it\n applicable++;\n const label = `${v.check} [${pkg}]`;\n const ev = v.evidence?.find((e) => e.package === pkg);\n if (!ev) failures.push(`${label}: not run for the current changes`);\n else if (ev.kind === 'claimed' && !ev.userOverride) failures.push(`${label}: only claimed, not executed (run: devworkspace task run <id> ${v.check} --package ${pkg})`);\n else if (ev.kind === 'claimed') warnings.push(`${label}: accepted on the user's word; DevWorkspace did not observe it run`);\n else if (ev.exitCode !== 0) failures.push(`${label}: FAIL (exit ${ev.exitCode ?? 'none'})`);\n else if (!unknown && ev.scope !== fp) failures.push(`${label}: passed, but files changed afterwards; run it again`);\n }\n if (known && applicable === 0) warnings.push(`${v.check}: no package with this check was changed`);\n return true;\n}\n\n/**\n * The completion gate. A task is only COMPLETED when every applicable requirement holds.\n * Tasks that carry a `scope` (created by 0.2.2+) are checked per changed package against executed evidence; older\n * tasks keep the original rules.\n */\nexport function evaluateGate(task: Task, ctx?: GateContext): GateResult {\n const failures: string[] = [];\n const warnings: string[] = [];\n const scoped = !!ctx && !!task.scope;\n for (const v of task.verification) {\n if (!v.required) continue;\n if (v.status === 'FAIL') failures.push(`${v.check}: FAIL`);\n else if (v.status === 'COULD_NOT_RUN') failures.push(`${v.check}: could not run${v.detail ? ` (${v.detail})` : ''}`);\n else if (v.status === 'SKIPPED') {\n if (v.reason === 'user-override') warnings.push(`${v.check}: skipped at the user's request; completion is less certain`);\n else failures.push(`${v.check}: skipped without a user override`);\n } else if (scoped && packageGate(v, ctx!, failures, warnings)) {\n // handled per package\n } else if (v.status === 'PENDING') failures.push(`${v.check}: not run yet`);\n }\n const { baseline, after } = task.tests;\n if (baseline && !after) failures.push('baseline test results recorded, but no results after the change');\n if (baseline && after) {\n if (after.failed > baseline.failed) failures.push(`regression: failures rose from ${baseline.failed} to ${after.failed}`);\n if (after.passed < baseline.passed) failures.push(`regression: passing tests fell from ${baseline.passed} to ${after.passed}`);\n }\n const isReadOnly = task.constraints?.some((c) => c === 'no-modify' || c === 'no-fix' || c === 'plan-only');\n if (isReadOnly && ctx?.scope && Object.keys(ctx.scope).length > 0) {\n failures.push('files were modified despite read-only constraint (no-modify, no-fix, or plan-only)');\n }\n if (isCodeChanging(task.type) && !isReadOnly) {\n if (!task.attestations.userWorkIntact) failures.push('not confirmed: no user work was overwritten');\n if (!task.attestations.knowledgeReviewed) failures.push('not confirmed: project knowledge was reviewed for updates');\n if (!task.attestations.finalStateInspected) failures.push('not confirmed: final repository state was inspected');\n }\n if ((isCodeChanging(task.type) || task.type === 'DOCUMENTATION' || isReadOnly) && !(task.completionSummary ?? '').trim()) {\n failures.push('completion summary is missing');\n }\n return { ok: failures.length === 0, failures, warnings };\n}\n\nexport function transitionTask(task: Task, to: TaskStatus, now: string, note?: string, ctx?: GateContext): GateResult | null {\n if (task.status === to) return null;\n if (!TRANSITIONS[task.status].includes(to)) {\n throw new DevWorkspaceError('GATE', `Cannot move a task from ${task.status} to ${to}.`, {\n hint: `Allowed from ${task.status}: ${TRANSITIONS[task.status].join(', ')}.`,\n });\n }\n let gate: GateResult | null = null;\n if (to === 'COMPLETED') {\n gate = evaluateGate(task, ctx);\n if (!gate.ok) {\n throw new DevWorkspaceError('GATE', `Task ${task.id} cannot be completed:\\n - ${gate.failures.join('\\n - ')}`, {\n hint: 'Resolve the items above (or mark the task BLOCKED/FAILED). A task is never complete while verification is failing.',\n });\n }\n }\n task.history.push({ at: now, from: task.status, to, ...(note ? { note: note.slice(0, 300) } : {}) });\n task.status = to;\n task.updatedAt = now;\n return gate;\n}\n\nexport function nextRequiredStep(task: Task, ctx?: GateContext): string {\n switch (task.status) {\n case 'COMPLETED':\n return 'None. The task is complete.';\n case 'FAILED':\n return 'Review the failure, then move the task back to IN_PROGRESS or close the idea.';\n case 'BLOCKED':\n return task.blockers.length > 0 ? `Resolve blocker: ${task.blockers[task.blockers.length - 1]}` : 'Identify and record what blocks this task.';\n case 'IDEA':\n return 'Clarify acceptance criteria, then plan.';\n case 'SPECIFIED':\n return 'Write a plan.';\n case 'PLANNED':\n return 'Start implementation (baseline verification first for meaningful changes).';\n default: {\n const pending = task.verification.filter((v) => v.required && (v.status === 'PENDING' || v.status === 'FAIL' || v.status === 'COULD_NOT_RUN'));\n if (pending.length > 0) return `Run/fix verification: ${pending.map((p) => `${p.check} (${p.status.toLowerCase().replace(/_/g, ' ')})`).join(', ')}.`;\n const g = evaluateGate(task, ctx);\n return g.ok ? 'All gates pass. Mark the task COMPLETED.' : `Satisfy the completion gate: ${g.failures[0]}`;\n }\n }\n}\n\n// ---------- storage ----------\n\nfunction taskFile(ws: Ws, task: Pick<Task, 'id' | 'status'>): string {\n return path.join(task.status === 'COMPLETED' ? ws.tasksCompleted : ws.tasksActive, `${task.id}.json`);\n}\n\nexport async function saveTask(ws: Ws, task: Task): Promise<void> {\n validateTask(task);\n assertNoSecrets(task);\n const dest = taskFile(ws, task);\n await backupIfVersionChanges(ws, dest, task.schemaVersion);\n await ensureDir(path.dirname(dest));\n await atomicWriteJson(dest, task);\n const other = path.join(task.status === 'COMPLETED' ? ws.tasksActive : ws.tasksCompleted, `${task.id}.json`);\n await fs.rm(other, { force: true });\n}\n\nexport async function loadTask(ws: Ws, idOrPrefix: string): Promise<Task> {\n for (const dir of [ws.tasksActive, ws.tasksCompleted]) {\n if (!(await pathExists(dir))) continue;\n const names = (await fs.readdir(dir)).filter((n) => n.endsWith('.json'));\n const hits = names.filter((n) => n === `${idOrPrefix}.json` || n.startsWith(idOrPrefix));\n if (hits.length > 1) {\n const exact = hits.find((n) => n === `${idOrPrefix}.json`);\n if (!exact) throw new DevWorkspaceError('USAGE', `Task id \"${idOrPrefix}\" is ambiguous.`, { hint: 'Use more characters of the id.' });\n hits.splice(0, hits.length, exact);\n }\n if (hits.length === 1) {\n const file = path.join(dir, hits[0]!);\n return (await readVersioned(file, 'task', SCHEMA_VERSION, validateTask)).data;\n }\n }\n throw new DevWorkspaceError('NOT_FOUND', `No task matching \"${idOrPrefix}\".`, { hint: 'List tasks with \"devworkspace task list --all\".' });\n}\n\nexport interface TaskListing {\n tasks: Task[];\n corrupt: { file: string; error: string }[];\n}\n\nexport async function listTasks(ws: Ws, opts: { includeCompleted?: boolean } = {}): Promise<TaskListing> {\n const tasks: Task[] = [];\n const corrupt: { file: string; error: string }[] = [];\n const dirs = opts.includeCompleted ? [ws.tasksActive, ws.tasksCompleted] : [ws.tasksActive];\n for (const dir of dirs) {\n if (!(await pathExists(dir))) continue;\n for (const name of (await fs.readdir(dir)).filter((n) => n.endsWith('.json')).sort()) {\n try {\n tasks.push((await readVersioned(path.join(dir, name), 'task', SCHEMA_VERSION, validateTask)).data);\n } catch (e) {\n corrupt.push({ file: `${path.basename(dir)}/${name}`, error: (e as Error).message });\n }\n }\n }\n tasks.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n return { tasks, corrupt };\n}\n"]}
|
|
@@ -7,7 +7,7 @@ import { run } from '../utils/proc.js';
|
|
|
7
7
|
const MAX_TRACKED_FILES = 2000;
|
|
8
8
|
const MAX_HASH_BYTES = 8 * 1024 * 1024;
|
|
9
9
|
/** Documentation and tool-managed folders never decide which package's checks apply. */
|
|
10
|
-
const NOT_CODE = /^(?:\.devworkspace|\.claude|graphify-out)\/|\.(?:md|mdx|rst|txt)$/i;
|
|
10
|
+
const NOT_CODE = /^(?:\.devworkspace|\.claude|\.cursor|\.github|graphify-out)\/|\.(?:md|mdx|mdc|rst|txt)$/i;
|
|
11
11
|
async function git(root, args) {
|
|
12
12
|
const r = await run('git', args, { cwd: root, timeoutMs: 30_000 });
|
|
13
13
|
return r.ok ? r.stdout : null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/verification/scope.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { CommandEntry } from '../config/schemas.js';\nimport { gitAvailable, parsePorcelainZ } from '../git/git.js';\nimport { isSensitiveFile } from '../security/files.js';\nimport type { TaskScope } from '../tasks/task.js';\nimport { sha256File, sha256Text } from '../utils/fs.js';\nimport { run } from '../utils/proc.js';\n\nconst MAX_TRACKED_FILES = 2000;\nconst MAX_HASH_BYTES = 8 * 1024 * 1024;\n/** Documentation and tool-managed folders never decide which package's checks apply. */\nconst NOT_CODE = /^(?:\\.devworkspace|\\.claude|graphify-out)\\/|\\.(?:md|mdx|rst|txt)$/i;\n\nexport type ChangeMap = Record<string, string>;\n\nasync function git(root: string, args: string[]): Promise<string | null> {\n const r = await run('git', args, { cwd: root, timeoutMs: 30_000 });\n return r.ok ? r.stdout : null;\n}\n\nasync function fileFingerprint(root: string, rel: string): Promise<string> {\n const full = path.join(root, ...rel.split('/'));\n try {\n const st = await fs.lstat(full);\n if (!st.isFile()) return 'not-a-file';\n if (st.size > MAX_HASH_BYTES) return `large:${st.size}:${Math.floor(st.mtimeMs)}`;\n return await sha256File(full);\n } catch {\n return 'deleted';\n }\n}\n\n/** Files that differ from HEAD right now (modified, staged or untracked), project-relative, with a content hash. */\nexport async function dirtyFiles(root: string): Promise<{ head: string | null; files: ChangeMap } | null> {\n if (!(await gitAvailable())) return null;\n if ((await git(root, ['rev-parse', '--is-inside-work-tree']))?.trim() !== 'true') return null;\n const prefix = ((await git(root, ['rev-parse', '--show-prefix'])) ?? '').trim();\n const head = ((await git(root, ['rev-parse', 'HEAD'])) ?? '').trim() || null;\n const status = await git(root, ['status', '--porcelain=v1', '-z', '--untracked-files=all']);\n if (status === null) return null;\n const files: ChangeMap = {};\n for (const e of parsePorcelainZ(status)) {\n if (e.xy === '!!' || !e.path.startsWith(prefix)) continue;\n const rel = e.path.slice(prefix.length);\n if (NOT_CODE.test(rel) || isSensitiveFile(rel)) continue;\n if (Object.keys(files).length >= MAX_TRACKED_FILES) break;\n files[rel] = await fileFingerprint(root, rel);\n }\n return { head, files };\n}\n\n/** Snapshot taken when a task is created: what is already modified is not the task's doing. */\nexport async function captureScope(root: string, now: string): Promise<TaskScope> {\n const d = await dirtyFiles(root);\n return { capturedAt: now, head: d?.head ?? null, baseline: d?.files ?? {} };\n}\n\n/** Project-relative files committed since `head` (so committing during a task does not hide its changes). */\nasync function committedSince(root: string, head: string): Promise<string[] | null> {\n const prefix = ((await git(root, ['rev-parse', '--show-prefix'])) ?? '').trim();\n const out = await git(root, ['diff', '--name-only', '-z', head, 'HEAD']);\n if (out === null) return null;\n return out.split('\\0').filter((f) => f && f.startsWith(prefix)).map((f) => f.slice(prefix.length));\n}\n\n/** Files that changed since the task started, with their current hashes. Null when that cannot be determined. */\nexport async function changedSince(root: string, scope: TaskScope): Promise<ChangeMap | null> {\n const now = await dirtyFiles(root);\n if (!now) return null;\n const changed: ChangeMap = {};\n for (const [rel, hash] of Object.entries(now.files)) if (scope.baseline[rel] !== hash) changed[rel] = hash;\n // A file that was modified at the start and has since been cleaned up (committed or reverted) also changed.\n for (const rel of Object.keys(scope.baseline)) if (!(rel in now.files)) changed[rel] = await fileFingerprint(root, rel);\n if (scope.head && now.head && scope.head !== now.head) {\n const committed = await committedSince(root, scope.head);\n if (committed === null) return null;\n for (const rel of committed) if (!NOT_CODE.test(rel) && !isSensitiveFile(rel) && !(rel in changed)) changed[rel] = await fileFingerprint(root, rel);\n }\n return changed;\n}\n\n/** Directories (relative to the project root) that have their own checks in the contract, longest first. */\nexport function packageDirs(contract: CommandEntry[]): string[] {\n const dirs = new Set<string>();\n for (const c of contract) if (c.available && c.cwd && c.cwd !== '.') dirs.add(c.cwd);\n return [...dirs].sort((a, b) => b.length - a.length || a.localeCompare(b));\n}\n\n/**\n * Fingerprint of the changes inside each package. A change under a package belongs to it; a change outside every package\n * (root config, shared tooling) belongs to all of them. \".\" covers everything. Returns null when nothing is known.\n */\nexport function scopeByPackage(changes: ChangeMap | null, contract: CommandEntry[]): Record<string, string> | null {\n if (!changes) return null;\n const files = Object.keys(changes).filter((f) => !NOT_CODE.test(f)).sort();\n if (files.length === 0) return null;\n const dirs = packageDirs(contract);\n const owner = (f: string): string | null => dirs.find((d) => f === d || f.startsWith(`${d}/`)) ?? null;\n const shared = files.filter((f) => owner(f) === null);\n const line = (f: string): string => `${f}:${changes[f]}`;\n const out: Record<string, string> = { '.': sha256Text(files.map(line).join('\\n')) };\n for (const d of dirs) {\n const mine = files.filter((f) => owner(f) === d);\n if (mine.length > 0 || shared.length > 0) out[d] = sha256Text([...mine, ...shared].sort().map(line).join('\\n'));\n }\n return out;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/verification/scope.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { CommandEntry } from '../config/schemas.js';\nimport { gitAvailable, parsePorcelainZ } from '../git/git.js';\nimport { isSensitiveFile } from '../security/files.js';\nimport type { TaskScope } from '../tasks/task.js';\nimport { sha256File, sha256Text } from '../utils/fs.js';\nimport { run } from '../utils/proc.js';\n\nconst MAX_TRACKED_FILES = 2000;\nconst MAX_HASH_BYTES = 8 * 1024 * 1024;\n/** Documentation and tool-managed folders never decide which package's checks apply. */\nconst NOT_CODE = /^(?:\\.devworkspace|\\.claude|\\.cursor|\\.github|graphify-out)\\/|\\.(?:md|mdx|mdc|rst|txt)$/i;\n\nexport type ChangeMap = Record<string, string>;\n\nasync function git(root: string, args: string[]): Promise<string | null> {\n const r = await run('git', args, { cwd: root, timeoutMs: 30_000 });\n return r.ok ? r.stdout : null;\n}\n\nasync function fileFingerprint(root: string, rel: string): Promise<string> {\n const full = path.join(root, ...rel.split('/'));\n try {\n const st = await fs.lstat(full);\n if (!st.isFile()) return 'not-a-file';\n if (st.size > MAX_HASH_BYTES) return `large:${st.size}:${Math.floor(st.mtimeMs)}`;\n return await sha256File(full);\n } catch {\n return 'deleted';\n }\n}\n\n/** Files that differ from HEAD right now (modified, staged or untracked), project-relative, with a content hash. */\nexport async function dirtyFiles(root: string): Promise<{ head: string | null; files: ChangeMap } | null> {\n if (!(await gitAvailable())) return null;\n if ((await git(root, ['rev-parse', '--is-inside-work-tree']))?.trim() !== 'true') return null;\n const prefix = ((await git(root, ['rev-parse', '--show-prefix'])) ?? '').trim();\n const head = ((await git(root, ['rev-parse', 'HEAD'])) ?? '').trim() || null;\n const status = await git(root, ['status', '--porcelain=v1', '-z', '--untracked-files=all']);\n if (status === null) return null;\n const files: ChangeMap = {};\n for (const e of parsePorcelainZ(status)) {\n if (e.xy === '!!' || !e.path.startsWith(prefix)) continue;\n const rel = e.path.slice(prefix.length);\n if (NOT_CODE.test(rel) || isSensitiveFile(rel)) continue;\n if (Object.keys(files).length >= MAX_TRACKED_FILES) break;\n files[rel] = await fileFingerprint(root, rel);\n }\n return { head, files };\n}\n\n/** Snapshot taken when a task is created: what is already modified is not the task's doing. */\nexport async function captureScope(root: string, now: string): Promise<TaskScope> {\n const d = await dirtyFiles(root);\n return { capturedAt: now, head: d?.head ?? null, baseline: d?.files ?? {} };\n}\n\n/** Project-relative files committed since `head` (so committing during a task does not hide its changes). */\nasync function committedSince(root: string, head: string): Promise<string[] | null> {\n const prefix = ((await git(root, ['rev-parse', '--show-prefix'])) ?? '').trim();\n const out = await git(root, ['diff', '--name-only', '-z', head, 'HEAD']);\n if (out === null) return null;\n return out.split('\\0').filter((f) => f && f.startsWith(prefix)).map((f) => f.slice(prefix.length));\n}\n\n/** Files that changed since the task started, with their current hashes. Null when that cannot be determined. */\nexport async function changedSince(root: string, scope: TaskScope): Promise<ChangeMap | null> {\n const now = await dirtyFiles(root);\n if (!now) return null;\n const changed: ChangeMap = {};\n for (const [rel, hash] of Object.entries(now.files)) if (scope.baseline[rel] !== hash) changed[rel] = hash;\n // A file that was modified at the start and has since been cleaned up (committed or reverted) also changed.\n for (const rel of Object.keys(scope.baseline)) if (!(rel in now.files)) changed[rel] = await fileFingerprint(root, rel);\n if (scope.head && now.head && scope.head !== now.head) {\n const committed = await committedSince(root, scope.head);\n if (committed === null) return null;\n for (const rel of committed) if (!NOT_CODE.test(rel) && !isSensitiveFile(rel) && !(rel in changed)) changed[rel] = await fileFingerprint(root, rel);\n }\n return changed;\n}\n\n/** Directories (relative to the project root) that have their own checks in the contract, longest first. */\nexport function packageDirs(contract: CommandEntry[]): string[] {\n const dirs = new Set<string>();\n for (const c of contract) if (c.available && c.cwd && c.cwd !== '.') dirs.add(c.cwd);\n return [...dirs].sort((a, b) => b.length - a.length || a.localeCompare(b));\n}\n\n/**\n * Fingerprint of the changes inside each package. A change under a package belongs to it; a change outside every package\n * (root config, shared tooling) belongs to all of them. \".\" covers everything. Returns null when nothing is known.\n */\nexport function scopeByPackage(changes: ChangeMap | null, contract: CommandEntry[]): Record<string, string> | null {\n if (!changes) return null;\n const files = Object.keys(changes).filter((f) => !NOT_CODE.test(f)).sort();\n if (files.length === 0) return null;\n const dirs = packageDirs(contract);\n const owner = (f: string): string | null => dirs.find((d) => f === d || f.startsWith(`${d}/`)) ?? null;\n const shared = files.filter((f) => owner(f) === null);\n const line = (f: string): string => `${f}:${changes[f]}`;\n const out: Record<string, string> = { '.': sha256Text(files.map(line).join('\\n')) };\n for (const d of dirs) {\n const mine = files.filter((f) => owner(f) === d);\n if (mine.length > 0 || shared.length > 0) out[d] = sha256Text([...mine, ...shared].sort().map(line).join('\\n'));\n }\n return out;\n}\n"]}
|
package/docs/agents.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Coding Agent Integrations
|
|
2
|
+
|
|
3
|
+
DevWorkspace is agent-agnostic. While it originated with Claude Code support, it provides typed adapters for multiple AI coding agents and tools across the ecosystem:
|
|
4
|
+
|
|
5
|
+
| Agent | Adapter ID | Primary Instruction Target | Capabilities |
|
|
6
|
+
| --- | --- | --- | --- |
|
|
7
|
+
| **Claude Code** | `claude` | `CLAUDE.md` or `.claude/CLAUDE.md`, `.claude/skills/devworkspace/SKILL.md` | Instructions, Skills, Plugins, CLI |
|
|
8
|
+
| **OpenAI Codex** | `codex` (alias `agents`) | `AGENTS.md` | Instructions |
|
|
9
|
+
| **Cursor** | `cursor` | `.cursor/rules/devworkspace.mdc` (or legacy `.cursorrules`) | Instructions |
|
|
10
|
+
| **GitHub Copilot** | `copilot` | `.github/copilot-instructions.md` | Instructions |
|
|
11
|
+
|
|
12
|
+
## Installing Agent Instructions
|
|
13
|
+
|
|
14
|
+
Use the `devworkspace agent` CLI command to manage agent integrations:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Preview what files would change
|
|
18
|
+
devworkspace agent install --agent cursor --dry-run
|
|
19
|
+
|
|
20
|
+
# Install for a specific agent
|
|
21
|
+
devworkspace agent install --agent cursor
|
|
22
|
+
devworkspace agent install --agent copilot
|
|
23
|
+
devworkspace agent install --agent codex
|
|
24
|
+
devworkspace agent install --agent claude
|
|
25
|
+
|
|
26
|
+
# Install for all supported agents in one command
|
|
27
|
+
devworkspace agent install --agent all
|
|
28
|
+
|
|
29
|
+
# List supported and detected agent integrations
|
|
30
|
+
devworkspace agent list
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## How Adapters Work
|
|
34
|
+
|
|
35
|
+
Every adapter implements the `AgentAdapter` contract defined in `src/agents/types.ts`:
|
|
36
|
+
|
|
37
|
+
- **Shared Section Engine (`src/agents/shared.ts`)**:
|
|
38
|
+
Instructions are injected within standardized HTML comment markers:
|
|
39
|
+
```markdown
|
|
40
|
+
<!-- devworkspace:start (managed by DevWorkspace - edit outside this block; run "devworkspace agent install" to refresh) -->
|
|
41
|
+
## DevWorkspace
|
|
42
|
+
...
|
|
43
|
+
<!-- devworkspace:end -->
|
|
44
|
+
```
|
|
45
|
+
User-authored content above or below the markers is strictly preserved byte-for-byte, including CRLF line endings on Windows.
|
|
46
|
+
|
|
47
|
+
- **Non-Destructive Reset (`devworkspace reset --include-agent-files`)**:
|
|
48
|
+
When resetting a workspace with `--include-agent-files`, DevWorkspace removes only its own managed blocks. If an instruction file contains user content outside the block, the user's content is preserved; only files that contained *strictly* the DevWorkspace block are unlinked.
|
|
49
|
+
|
|
50
|
+
- **Doctor & Readiness (`devworkspace doctor`)**:
|
|
51
|
+
`doctor` checks for the presence and freshness of installed instructions for whichever agents are configured in the project. Projects using Cursor, Copilot, or Codex achieve `Core workspace: READY` without requiring `CLAUDE.md`.
|
|
52
|
+
|
|
53
|
+
## Adding a New Agent Adapter
|
|
54
|
+
|
|
55
|
+
To add support for a new coding agent:
|
|
56
|
+
1. Create a directory under `src/agents/<agent-name>/` implementing `AgentAdapter`.
|
|
57
|
+
2. Implement `detectExisting(root)`, `detectAvailable?(root)`, `plan(ctx)`, and `unplan?(root)`.
|
|
58
|
+
3. Register the adapter in `src/agents/index.ts` under `AGENT_ADAPTERS` and `AGENTS`.
|
|
59
|
+
4. Add unit and integration tests under `tests/unit/agent-adapters.test.ts`.
|
|
60
|
+
|
|
@@ -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
|
+
|