devworkspace 0.3.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,14 +16,119 @@ export const CONTEXT_ROLES = ['explorer', 'tester', 'reviewer'];
16
16
  export function isContextRole(v) {
17
17
  return typeof v === 'string' && CONTEXT_ROLES.includes(v);
18
18
  }
19
- const STOP = new Set(['the', 'and', 'for', 'with', 'that', 'this', 'from', 'into', 'does', 'how', 'what', 'where', 'why', 'when', 'which', 'fix', 'add', 'bug', 'make', 'new', 'can', 'are', 'not', 'our', 'all', 'use', 'get', 'set']);
19
+ const STOP = new Set([
20
+ 'the', 'and', 'for', 'with', 'that', 'this', 'from', 'into', 'does', 'how',
21
+ 'what', 'where', 'why', 'when', 'which', 'fix', 'add', 'bug', 'make', 'new',
22
+ 'can', 'are', 'not', 'our', 'all', 'use', 'get', 'set', 'let', 'may'
23
+ ]);
24
+ const WEAK_TERMS = new Set(['error', 'errors', 'check', 'checks', 'data', 'improve', 'update', 'run', 'test', 'handle', 'handling', 'code']);
25
+ const PATH_STRUCTURAL_TERMS = new Set([
26
+ 'backend', 'frontend', 'service', 'services', 'controller', 'controllers',
27
+ 'worker', 'workers', 'dto', 'dtos', 'src', 'modules', 'app', 'tests',
28
+ 'unit', 'integration', 'test', 'spec', 'ts', 'tsx', 'js', 'jsx', 'json', 'md'
29
+ ]);
20
30
  const CLIP = 400;
21
31
  const SECURITY_WORDS = /auth|tenant|permission|rbac|security|isolation|role|session|ownership/i;
22
32
  const ISSUE_KEY = /^(?:issue|limit|known|bug|risk)/i;
23
33
  /** Facts that describe the stack and layout; implementation-style tasks need them, a lookup question does not. */
24
34
  const STACK_KEY = /^(?:stack\.|repo\.packages|repo\.monorepo|repo\.entry-points|convention|style|arch|pattern|testing)/i;
25
35
  const BROAD_TYPES = ['FEATURE', 'REFACTOR', 'ARCHITECTURE', 'TESTING', 'PERFORMANCE', 'MAINTENANCE', 'RELEASE'];
26
- const words = (text) => [...new Set((text.toLowerCase().match(/[a-z0-9_][a-z0-9_.-]{2,}/g) ?? []).filter((w) => !STOP.has(w)))].sort();
36
+ /** Normalizes words by stripping standard English inflectional suffixes deterministically. */
37
+ function normalizeStem(w) {
38
+ const s = w.toLowerCase().trim();
39
+ if (s.endsWith('ies') && s.length > 4)
40
+ return s.slice(0, -3) + 'y';
41
+ if (s.endsWith('es') && s.length > 4 && /[sxz]|ch|sh$/.test(s.slice(0, -2)))
42
+ return s.slice(0, -2);
43
+ if (s.endsWith('s') && s.length > 3 && !s.endsWith('ss'))
44
+ return s.slice(0, -1);
45
+ if (s.endsWith('ing') && s.length > 5)
46
+ return s.slice(0, -3);
47
+ if (s.endsWith('tion') && s.length > 6)
48
+ return s.slice(0, -4);
49
+ if (s.endsWith('ed') && s.length > 4)
50
+ return s.slice(0, -2);
51
+ return s;
52
+ }
53
+ /** Explicit domain synonym dictionary grounded in engineering tasks and repository knowledge. */
54
+ const DOMAIN_SYNONYMS = {
55
+ // Database, migrations, schema and persistence
56
+ table: ['database', 'schema', 'orm', 'migration', 'sql'],
57
+ column: ['database', 'schema', 'migration', 'sql'],
58
+ schema: ['database', 'orm', 'migration', 'sql', 'drizzle', 'postgres'],
59
+ migration: ['database', 'schema', 'migrate', 'sql', 'drizzle'],
60
+ migrate: ['database', 'schema', 'migration', 'sql'],
61
+ sql: ['database', 'postgres', 'drizzle', 'query'],
62
+ db: ['database', 'postgres', 'drizzle', 'orm'],
63
+ database: ['db', 'schema', 'orm', 'postgres', 'drizzle'],
64
+ drizzle: ['database', 'orm', 'schema'],
65
+ postgres: ['database', 'sql'],
66
+ // Authentication, tenancy, and authorization
67
+ auth: ['jwt', 'session', 'security', 'tenant', 'permission'],
68
+ jwt: ['auth', 'session', 'token', 'security'],
69
+ password: ['hash', 'argon2', 'auth', 'security'],
70
+ hash: ['password', 'argon2', 'security'],
71
+ tenant: ['tenancy', 'isolation', 'security', 'auth'],
72
+ tenancy: ['tenant', 'isolation', 'security'],
73
+ isolation: ['tenant', 'tenancy', 'security'],
74
+ // Billing and financial
75
+ invoice: ['billing', 'cents', 'precision'],
76
+ billing: ['invoice', 'cents', 'precision'],
77
+ cents: ['billing', 'invoice', 'precision'],
78
+ payment: ['stripe', 'gateway'],
79
+ // API, HTTP, and Backend Services
80
+ endpoint: ['api', 'controller', 'service', 'dto'],
81
+ api: ['endpoint', 'controller', 'service', 'dto'],
82
+ supplier: ['supplier', 'dto', 'service'],
83
+ controller: ['service', 'dto', 'api', 'endpoint'],
84
+ dto: ['validation', 'typebox', 'schema', 'controller'],
85
+ // Frontend and UI
86
+ component: ['ui', 'frontend', 'page', 'react'],
87
+ pagination: ['ui', 'component', 'frontend', 'table'],
88
+ frontend: ['ui', 'component', 'react'],
89
+ ui: ['component', 'frontend', 'react'],
90
+ react: ['ui', 'component', 'frontend'],
91
+ // Inventory and Stock
92
+ stock: ['inventory', 'product', 'service'],
93
+ inventory: ['stock', 'product', 'service'],
94
+ product: ['inventory', 'stock', 'service'],
95
+ sku: ['product', 'inventory', 'barcode'],
96
+ barcode: ['sku', 'product', 'inventory']
97
+ };
98
+ /** Extracts words from text without punctuation. */
99
+ const words = (text) => [...new Set((text.toLowerCase().match(/[a-z0-9_][a-z0-9_.-]{1,}/g) ?? []).filter((w) => !STOP.has(w)))].sort();
100
+ /** Expands terms using word stemming and explicit domain synonym clusters. */
101
+ function expandQueryTerms(rawWords) {
102
+ const expanded = new Set(rawWords);
103
+ for (const w of rawWords) {
104
+ const stem = normalizeStem(w);
105
+ if (stem.length >= 2)
106
+ expanded.add(stem);
107
+ const syns = DOMAIN_SYNONYMS[w] ?? DOMAIN_SYNONYMS[stem];
108
+ if (syns) {
109
+ for (const s of syns)
110
+ expanded.add(s);
111
+ }
112
+ }
113
+ return [...expanded].sort();
114
+ }
115
+ /** Matches terms against text with token/boundary precision. */
116
+ function matchesQuery(text, terms) {
117
+ const lower = text.toLowerCase();
118
+ const matched = [];
119
+ for (const term of terms) {
120
+ if (term.includes('.') || term.includes('/')) {
121
+ if (lower.includes(term))
122
+ matched.push(term);
123
+ }
124
+ else {
125
+ const re = new RegExp(`(?:^|[\\s._/:-])${term}(?:$|[\\s._/:-])`, 'i');
126
+ if (re.test(lower))
127
+ matched.push(term);
128
+ }
129
+ }
130
+ return matched;
131
+ }
27
132
  const norm = (s) => s.toLowerCase().replace(/\s+/g, ' ').trim();
28
133
  /** Which context documents are worth pointing at for a task type. */
29
134
  const DOCS_BY_TYPE = {
@@ -47,27 +152,100 @@ async function buildBaseTaskContext(o, request) {
47
152
  const cls = classifyRequest(request);
48
153
  const type = cls.type;
49
154
  const kw = words(request);
155
+ const expandedTerms = expandQueryTerms(kw);
50
156
  const included = [];
51
- const hit = (text) => kw.filter((w) => text.includes(w));
157
+ const hit = (text) => matchesQuery(text, expandedTerms);
158
+ // Packages and the testing contract
159
+ let allChecks = [];
160
+ if (await pathExists(ws.commands))
161
+ allChecks = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data.checks;
162
+ const pkgReason = new Map();
163
+ for (const d of packageDirs(allChecks)) {
164
+ const m = matchesQuery(request, [d]);
165
+ if (m.length > 0)
166
+ pkgReason.set(d, `request names "${m[0]}"`);
167
+ }
168
+ // Enhanced package discovery from domain context when not explicitly named
169
+ if (pkgReason.size === 0 && packageDirs(allChecks).length > 1) {
170
+ const hasBackend = matchesQuery(request, ['api', 'endpoint', 'endpoints', 'controller', 'controllers', 'dto', 'dtos', 'database', 'migration', 'migrations', 'migrate', 'sql', 'postgres', 'drizzle', 'orm', 'fastify', 'server', 'jwt', 'argon2', 'service', 'services', 'invoice']).length > 0;
171
+ const hasFrontend = matchesQuery(request, ['ui', 'component', 'components', 'frontend', 'page', 'pages', 'pagination', 'react', 'vite', 'view', 'views', 'button', 'modal']).length > 0;
172
+ const available = packageDirs(allChecks);
173
+ if (hasBackend && !hasFrontend && available.includes('backend')) {
174
+ pkgReason.set('backend', 'inferred from backend domain terminology');
175
+ }
176
+ else if (hasFrontend && !hasBackend && available.includes('frontend')) {
177
+ pkgReason.set('frontend', 'inferred from frontend UI terminology');
178
+ }
179
+ else if (hasBackend && hasFrontend) {
180
+ if (available.includes('backend'))
181
+ pkgReason.set('backend', 'request spans backend');
182
+ if (available.includes('frontend'))
183
+ pkgReason.set('frontend', 'request spans frontend');
184
+ }
185
+ }
186
+ // dirtyFiles already leaves out documentation and tool-managed files, so a docs-only change selects no package.
187
+ // Only worth the Git calls when the request did not already pick a package and there is more than one to choose from.
188
+ const dirty = type !== 'QUESTION' && type !== 'DOCUMENTATION' && pkgReason.size === 0 && packageDirs(allChecks).length > 1 ? await dirtyFiles(ws.root) : null;
189
+ for (const f of Object.keys(dirty?.files ?? {})) {
190
+ const d = packageDirs(allChecks).find((x) => f === x || f.startsWith(`${x}/`));
191
+ if (d && !pkgReason.has(d))
192
+ pkgReason.set(d, 'has uncommitted code changes');
193
+ }
52
194
  // Facts
53
195
  const all = (await loadFacts(ws)).facts;
54
196
  const picked = new Map();
197
+ const isSinglePackage = pkgReason.size === 1;
198
+ const targetPkg = isSinglePackage ? [...pkgReason.keys()][0] : null;
55
199
  for (const f of all) {
56
- const m = hit(`${f.key} ${f.value} ${f.source}`.toLowerCase());
57
- if (m.length > 0)
58
- picked.set(f.key, `matches "${m.slice(0, 3).join('", "')}"`);
200
+ // If request confidently targets a single package, avoid pulling in unrelated package facts
201
+ if (targetPkg === 'backend') {
202
+ if (f.source.startsWith('frontend/') || f.key === 'stack.ui' || f.key.startsWith('convention.frontend')) {
203
+ continue;
204
+ }
205
+ }
206
+ else if (targetPkg === 'frontend') {
207
+ if (f.source.startsWith('backend/') || f.key === 'stack.database' || f.key === 'stack.orm' || f.key.startsWith('testing.db')) {
208
+ continue;
209
+ }
210
+ }
211
+ // Match terms against fact key and value; only match source path against specific non-structural request words
212
+ const mText = hit(`${f.key} ${f.value}`);
213
+ const mSource = matchesQuery(f.source, kw.filter((w) => !PATH_STRUCTURAL_TERMS.has(w)));
214
+ const m = [...new Set([...mText, ...mSource])];
215
+ const nonWeak = m.filter(w => !WEAK_TERMS.has(w));
216
+ if (nonWeak.length > 0)
217
+ picked.set(f.key, `matches "${nonWeak.slice(0, 3).join('", "')}"`);
59
218
  }
60
219
  const group = (re, why, also) => {
61
- for (const f of all)
62
- if (!picked.has(f.key) && (re.test(f.key) || also?.(f)))
220
+ for (const f of all) {
221
+ if (picked.has(f.key))
222
+ continue;
223
+ if (targetPkg === 'backend' && (f.source.startsWith('frontend/') || f.key === 'stack.ui' || f.key.startsWith('convention.frontend')))
224
+ continue;
225
+ if (targetPkg === 'frontend' && (f.source.startsWith('backend/') || f.key === 'stack.database' || f.key === 'stack.orm' || f.key.startsWith('testing.db')))
226
+ continue;
227
+ if (re.test(f.key) || also?.(f))
63
228
  picked.set(f.key, why);
229
+ }
64
230
  };
65
- if (type !== 'QUESTION' && type !== 'DOCUMENTATION')
66
- group(/^repo\.(?:packages|entry-points)$/, `package layout (${type})`);
231
+ // Package layout facts: include in multi-package/cross-package/uncertain contexts, omit global entry points in single-package tasks
232
+ if (type !== 'QUESTION' && type !== 'DOCUMENTATION') {
233
+ if (!isSinglePackage || type === 'ARCHITECTURE') {
234
+ group(/^repo\.(?:packages|entry-points|monorepo)$/, `package layout (${type})`);
235
+ }
236
+ }
67
237
  if (type === 'BUG' || type === 'SECURITY')
68
238
  group(ISSUE_KEY, 'known issue / limitation', (f) => f.status === 'STALE' && f.sourceType !== 'detector');
69
- if (BROAD_TYPES.includes(type))
70
- group(STACK_KEY, `stack and conventions (${type})`);
239
+ if (BROAD_TYPES.includes(type)) {
240
+ group(/^stack\.ecosystem$/, `stack and conventions (${type})`);
241
+ if (targetPkg === 'backend' || !isSinglePackage) {
242
+ group(/^(?:arch\.modules|convention\.service-layer)$/, `architecture conventions (${type})`);
243
+ group(/^(?:stack\.framework|stack\.database|stack\.orm)$/, `backend stack (${type})`);
244
+ }
245
+ if (targetPkg === 'frontend' || !isSinglePackage) {
246
+ group(/^(?:convention\.frontend-components|stack\.ui)$/, `frontend stack (${type})`);
247
+ }
248
+ }
71
249
  if (type === 'SECURITY')
72
250
  group(/^$/, 'security / authorization rule', (f) => SECURITY_WORDS.test(`${f.key} ${f.value}`));
73
251
  if (type === 'DOCUMENTATION')
@@ -91,24 +269,6 @@ async function buildBaseTaskContext(o, request) {
91
269
  facts.push(clip ? { ...f, value: f.value.slice(0, CLIP), clipped: f.value.length - CLIP } : f);
92
270
  included.push({ kind: 'fact', id: f.key, reason: picked.get(f.key) });
93
271
  }
94
- // Packages and the testing contract
95
- let allChecks = [];
96
- if (await pathExists(ws.commands))
97
- allChecks = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data.checks;
98
- const pkgReason = new Map();
99
- for (const d of packageDirs(allChecks)) {
100
- const m = hit(d.toLowerCase());
101
- if (m.length > 0)
102
- pkgReason.set(d, `request names "${m[0]}"`);
103
- }
104
- // dirtyFiles already leaves out documentation and tool-managed files, so a docs-only change selects no package.
105
- // Only worth the Git calls when the request did not already pick a package and there is more than one to choose from.
106
- const dirty = type !== 'QUESTION' && type !== 'DOCUMENTATION' && pkgReason.size === 0 && packageDirs(allChecks).length > 1 ? await dirtyFiles(ws.root) : null;
107
- for (const f of Object.keys(dirty?.files ?? {})) {
108
- const d = packageDirs(allChecks).find((x) => f === x || f.startsWith(`${x}/`));
109
- if (d && !pkgReason.has(d))
110
- pkgReason.set(d, 'has uncommitted code changes');
111
- }
112
272
  const usable = allChecks.filter((c) => c.available);
113
273
  const scoped = pkgReason.size > 0 ? usable.filter((c) => !c.cwd || c.cwd === '.' || pkgReason.has(c.cwd)) : usable;
114
274
  const checks = type === 'QUESTION' || type === 'DOCUMENTATION' ? [] : scoped;
@@ -122,17 +282,19 @@ async function buildBaseTaskContext(o, request) {
122
282
  safety.push({ package: c.cwd ?? '.', check: c.id, command: c.command, safety: s.safety, reasons: s.reasons });
123
283
  }
124
284
  SAFETY_RULES.forEach((_, i) => included.push({ kind: 'rule', id: `safety-${i + 1}`, reason: 'safety rule, included in every context' }));
125
- // Decisions: titles and file references only
285
+ // Decisions: titles, context, decision, consequences, and file references
126
286
  const decs = (await listDecisions(ws)).decisions;
127
287
  const wantAll = type === 'ARCHITECTURE' || type === 'SECURITY';
128
288
  const decisions = [];
129
289
  for (const d of decs) {
130
- const m = hit(`${d.title} ${d.decision} ${d.context}`.toLowerCase());
131
- if (d.status === 'superseded' && m.length === 0)
290
+ const fullText = `${d.title} ${d.decision} ${d.context} ${d.consequences} ${d.file}`;
291
+ const m = matchesQuery(fullText, expandedTerms);
292
+ const nonWeak = m.filter(w => !WEAK_TERMS.has(w));
293
+ if (d.status === 'superseded' && nonWeak.length === 0)
132
294
  continue;
133
- if (m.length > 0 || wantAll) {
295
+ if (nonWeak.length > 0 || wantAll) {
134
296
  decisions.push({ number: d.number, title: d.title, status: d.status, file: d.file });
135
- included.push({ kind: 'decision', id: String(d.number).padStart(4, '0'), reason: m.length > 0 ? `matches "${m[0]}"` : `${type} tasks review all decisions` });
297
+ included.push({ kind: 'decision', id: String(d.number).padStart(4, '0'), reason: nonWeak.length > 0 ? `matches "${nonWeak[0]}"` : `${type} tasks review all decisions` });
136
298
  }
137
299
  }
138
300
  // Documents: referenced, never embedded
@@ -142,7 +304,7 @@ async function buildBaseTaskContext(o, request) {
142
304
  for (const name of (await fs.readdir(ws.contextDir)).filter((n) => n.endsWith('.md')).sort()) {
143
305
  docCount++;
144
306
  const byType = (DOCS_BY_TYPE[type] ?? []).includes(name);
145
- const m = hit(name.toLowerCase());
307
+ const m = matchesQuery(name, expandedTerms);
146
308
  if (byType || m.length > 0) {
147
309
  documents.push({ name, bytes: (await fs.stat(path.join(ws.contextDir, name))).size });
148
310
  included.push({ kind: 'document', id: name, reason: byType ? `reference for ${type}` : `request names "${m[0]}"` });
@@ -178,7 +340,8 @@ export async function getAgentContextSlice(o, opts) {
178
340
  const base = opts.base ?? (await buildBaseTaskContext(o, opts.request));
179
341
  const role = opts.role;
180
342
  const kw = words(opts.request);
181
- const hit = (text) => kw.filter((w) => text.includes(w));
343
+ const expandedTerms = expandQueryTerms(kw);
344
+ const hit = (text) => matchesQuery(text, expandedTerms);
182
345
  let slicedFacts = [...base.facts];
183
346
  let slicedChecks = [...base.checks];
184
347
  let slicedDecisions = [...base.decisions];
@@ -194,10 +357,10 @@ export async function getAgentContextSlice(o, opts) {
194
357
  return true;
195
358
  if (STACK_KEY.test(f.key) && !/^convention\.test/i.test(f.key))
196
359
  return true;
197
- const m = hit(`${f.key} ${f.value}`.toLowerCase());
360
+ const m = hit(`${f.key} ${f.value}`);
198
361
  return m.length > 0 && !/^convention\.test/i.test(f.key);
199
362
  });
200
- slicedDecisions = base.decisions.filter((d) => hit(`${d.title} ${d.file}`.toLowerCase()).length > 0).slice(0, 3);
363
+ slicedDecisions = base.decisions.slice(0, 3);
201
364
  slicedDocuments = base.documents.filter((d) => ['architecture.md', 'integrations.md'].includes(d.name));
202
365
  // Entry points from facts or packages
203
366
  const epFact = base.facts.find((f) => f.key === 'repo.entry-points');
@@ -217,7 +380,7 @@ export async function getAgentContextSlice(o, opts) {
217
380
  try {
218
381
  const featFile = await loadFeatures(ws);
219
382
  const matchedFeats = featFile.features.filter((f) => {
220
- const text = `${f.id} ${f.name} ${f.description ?? ''} ${(f.tags ?? []).join(' ')}`.toLowerCase();
383
+ const text = `${f.id} ${f.name} ${f.description ?? ''} ${(f.tags ?? []).join(' ')}`;
221
384
  return hit(text).length > 0;
222
385
  });
223
386
  if (matchedFeats.length > 0) {
@@ -236,7 +399,7 @@ export async function getAgentContextSlice(o, opts) {
236
399
  const graph = await loadGraphData(ws.root);
237
400
  if (graph.exists && graph.data && graph.data.nodes) {
238
401
  const matchedNodes = [];
239
- for (const w of kw) {
402
+ for (const w of expandedTerms) {
240
403
  const n = findMatchingStartNode(graph.data.nodes, w);
241
404
  if (n && !matchedNodes.some((x) => x.id === n.id)) {
242
405
  matchedNodes.push({
@@ -1 +1 @@
1
- {"version":3,"file":"taskContext.js","sourceRoot":"","sources":["../../src/services/taskContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { SCHEMA_VERSION, validateCommands, type CommandEntry, type Fact } from '../config/schemas.js';\nimport { loadProject, requireWorkspace } from '../core/workspace.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { listDecisions } from '../decisions/decision.js';\nimport { loadFacts } from '../knowledge/facts.js';\nimport { classifyRequest } from '../tasks/routing.js';\nimport type { TaskType } from '../tasks/task.js';\nimport { pathExists } from '../utils/fs.js';\nimport { classifyCommand, readManifestEvidence } from '../verification/safety.js';\nimport { dirtyFiles, packageDirs } from '../verification/scope.js';\nimport { SAFETY_RULES, type ContextResult } from './knowledge.js';\nimport type { ServiceOptions } from './common.js';\nimport { loadFeatures } from './features.js';\nimport { loadGraphData, findMatchingStartNode } from './graph.js';\n\nexport const CONTEXT_ROLES = ['explorer', 'tester', 'reviewer'] as const;\nexport type ContextRole = (typeof CONTEXT_ROLES)[number];\n\nexport function isContextRole(v: unknown): v is ContextRole {\n return typeof v === 'string' && (CONTEXT_ROLES as readonly string[]).includes(v);\n}\n\nexport interface ContextItem {\n kind: 'fact' | 'check' | 'decision' | 'document' | 'rule';\n id: string;\n /** Why this item is in the context; every item carries one. */\n reason: string;\n}\n\nexport interface TaskContextResult {\n project: { name: string; id: string };\n request: string;\n type: TaskType;\n confidence: 'high' | 'low';\n readOnly: boolean;\n /** `clipped` = characters left out of a long detector-derived value; the full value is in facts.json. */\n facts: (Fact & { clipped?: number })[];\n /** Detector facts folded into another fact with the identical value; nothing is deleted from facts.json. */\n aliases: { key: string; sameAs: string }[];\n checks: CommandEntry[];\n safety: ContextResult['safety'];\n rules: string[];\n decisions: { number: number; title: string; status: string; file: string }[];\n /** Detailed documents are referenced by name, never embedded. */\n documents: { name: string; bytes: number }[];\n packages: string[];\n included: ContextItem[];\n counts: { facts: [number, number]; checks: [number, number]; decisions: [number, number]; documents: [number, number] };\n role?: ContextRole;\n roleGuidance?: string[];\n roleFindings?: {\n entryPoints?: string[];\n graphNodes?: { id: string; status: string; path: string | null; symbol: string | null }[];\n features?: { id: string; name: string; status?: string }[];\n testFrameworks?: string[];\n zeroTestSafeguards?: string[];\n diffNotice?: string;\n };\n}\n\nconst STOP = new Set(['the', 'and', 'for', 'with', 'that', 'this', 'from', 'into', 'does', 'how', 'what', 'where', 'why', 'when', 'which', 'fix', 'add', 'bug', 'make', 'new', 'can', 'are', 'not', 'our', 'all', 'use', 'get', 'set']);\nconst CLIP = 400;\nconst SECURITY_WORDS = /auth|tenant|permission|rbac|security|isolation|role|session|ownership/i;\nconst ISSUE_KEY = /^(?:issue|limit|known|bug|risk)/i;\n/** Facts that describe the stack and layout; implementation-style tasks need them, a lookup question does not. */\nconst STACK_KEY = /^(?:stack\\.|repo\\.packages|repo\\.monorepo|repo\\.entry-points|convention|style|arch|pattern|testing)/i;\nconst BROAD_TYPES: TaskType[] = ['FEATURE', 'REFACTOR', 'ARCHITECTURE', 'TESTING', 'PERFORMANCE', 'MAINTENANCE', 'RELEASE'];\n\nconst words = (text: string): string[] => [...new Set((text.toLowerCase().match(/[a-z0-9_][a-z0-9_.-]{2,}/g) ?? []).filter((w) => !STOP.has(w)))].sort();\nconst norm = (s: string): string => s.toLowerCase().replace(/\\s+/g, ' ').trim();\n\n/** Which context documents are worth pointing at for a task type. */\nconst DOCS_BY_TYPE: Partial<Record<TaskType, string[]>> = {\n ARCHITECTURE: ['architecture.md', 'integrations.md'],\n REFACTOR: ['architecture.md', 'conventions.md'],\n FEATURE: ['architecture.md', 'conventions.md'],\n BUG: ['testing.md'],\n TESTING: ['testing.md'],\n SECURITY: ['testing.md', 'architecture.md'],\n PERFORMANCE: ['architecture.md'],\n RELEASE: ['testing.md'],\n};\n\n/**\n * Task-aware context. Selection is deterministic (sorted inputs, no clocks, no randomness) and rule-based: the request is\n * classified, its keywords select facts/decisions/packages, and the type decides which broader groups come along.\n * Safety rules are included for every type; the per-package \"not run automatically\" list whenever checks are included.\n */\nasync function buildBaseTaskContext(o: ServiceOptions, request: string): Promise<TaskContextResult> {\n const ws = await requireWorkspace(o.cwd);\n const project = await loadProject(ws);\n const cls = classifyRequest(request);\n const type = cls.type;\n const kw = words(request);\n const included: ContextItem[] = [];\n const hit = (text: string): string[] => kw.filter((w) => text.includes(w));\n\n // Facts\n const all = (await loadFacts(ws)).facts;\n const picked = new Map<string, string>();\n for (const f of all) {\n const m = hit(`${f.key} ${f.value} ${f.source}`.toLowerCase());\n if (m.length > 0) picked.set(f.key, `matches \"${m.slice(0, 3).join('\", \"')}\"`);\n }\n const group = (re: RegExp, why: string, also?: (f: Fact) => boolean): void => {\n for (const f of all) if (!picked.has(f.key) && (re.test(f.key) || also?.(f))) picked.set(f.key, why);\n };\n if (type !== 'QUESTION' && type !== 'DOCUMENTATION') group(/^repo\\.(?:packages|entry-points)$/, `package layout (${type})`);\n if (type === 'BUG' || type === 'SECURITY') group(ISSUE_KEY, 'known issue / limitation', (f) => f.status === 'STALE' && f.sourceType !== 'detector');\n if (BROAD_TYPES.includes(type)) group(STACK_KEY, `stack and conventions (${type})`);\n if (type === 'SECURITY') group(/^$/, 'security / authorization rule', (f) => SECURITY_WORDS.test(`${f.key} ${f.value}`));\n if (type === 'DOCUMENTATION') group(/^repo\\.docs$/, 'documentation index');\n const selected = all.filter((f) => picked.has(f.key));\n\n // Compaction: a detector fact whose value equals another selected fact's is folded into it. Human-authored facts are never folded or clipped.\n const aliases: TaskContextResult['aliases'] = [];\n const owners = new Map<string, string>();\n for (const f of [...selected].sort((a, b) => Number(a.sourceType === 'detector') - Number(b.sourceType === 'detector') || a.key.localeCompare(b.key))) {\n if (!owners.has(norm(f.value))) owners.set(norm(f.value), f.key);\n }\n const facts: TaskContextResult['facts'] = [];\n for (const f of [...selected].sort((a, b) => a.key.localeCompare(b.key))) {\n const owner = owners.get(norm(f.value))!;\n if (owner !== f.key && f.sourceType === 'detector') {\n aliases.push({ key: f.key, sameAs: owner });\n continue;\n }\n const clip = f.sourceType === 'detector' && f.value.length > CLIP;\n facts.push(clip ? { ...f, value: f.value.slice(0, CLIP), clipped: f.value.length - CLIP } : f);\n included.push({ kind: 'fact', id: f.key, reason: picked.get(f.key)! });\n }\n\n // Packages and the testing contract\n let allChecks: CommandEntry[] = [];\n if (await pathExists(ws.commands)) allChecks = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data.checks;\n const pkgReason = new Map<string, string>();\n for (const d of packageDirs(allChecks)) {\n const m = hit(d.toLowerCase());\n if (m.length > 0) pkgReason.set(d, `request names \"${m[0]}\"`);\n }\n // dirtyFiles already leaves out documentation and tool-managed files, so a docs-only change selects no package.\n // Only worth the Git calls when the request did not already pick a package and there is more than one to choose from.\n const dirty = type !== 'QUESTION' && type !== 'DOCUMENTATION' && pkgReason.size === 0 && packageDirs(allChecks).length > 1 ? await dirtyFiles(ws.root) : null;\n for (const f of Object.keys(dirty?.files ?? {})) {\n const d = packageDirs(allChecks).find((x) => f === x || f.startsWith(`${x}/`));\n if (d && !pkgReason.has(d)) pkgReason.set(d, 'has uncommitted code changes');\n }\n const usable = allChecks.filter((c) => c.available);\n const scoped = pkgReason.size > 0 ? usable.filter((c) => !c.cwd || c.cwd === '.' || pkgReason.has(c.cwd)) : usable;\n const checks = type === 'QUESTION' || type === 'DOCUMENTATION' ? [] : scoped;\n for (const c of checks) included.push({ kind: 'check', id: `${c.cwd ?? '.'}:${c.id}`, reason: c.cwd && pkgReason.has(c.cwd) ? `package: ${pkgReason.get(c.cwd)}` : `testing contract (${type})` });\n\n // Commands that must not run unguarded stay visible whenever their package's checks are in play.\n const safety: ContextResult['safety'] = [];\n for (const c of checks) {\n const s = classifyCommand(c, await readManifestEvidence(ws.root, c));\n if (s.safety !== 'safe') safety.push({ package: c.cwd ?? '.', check: c.id, command: c.command, safety: s.safety, reasons: s.reasons });\n }\n SAFETY_RULES.forEach((_, i) => included.push({ kind: 'rule', id: `safety-${i + 1}`, reason: 'safety rule, included in every context' }));\n\n // Decisions: titles and file references only\n const decs = (await listDecisions(ws)).decisions;\n const wantAll = type === 'ARCHITECTURE' || type === 'SECURITY';\n const decisions: TaskContextResult['decisions'] = [];\n for (const d of decs) {\n const m = hit(`${d.title} ${d.decision} ${d.context}`.toLowerCase());\n if (d.status === 'superseded' && m.length === 0) continue;\n if (m.length > 0 || wantAll) {\n decisions.push({ number: d.number, title: d.title, status: d.status, file: d.file });\n included.push({ kind: 'decision', id: String(d.number).padStart(4, '0'), reason: m.length > 0 ? `matches \"${m[0]}\"` : `${type} tasks review all decisions` });\n }\n }\n\n // Documents: referenced, never embedded\n const documents: TaskContextResult['documents'] = [];\n let docCount = 0;\n if (await pathExists(ws.contextDir)) {\n for (const name of (await fs.readdir(ws.contextDir)).filter((n) => n.endsWith('.md')).sort()) {\n docCount++;\n const byType = (DOCS_BY_TYPE[type] ?? []).includes(name);\n const m = hit(name.toLowerCase());\n if (byType || m.length > 0) {\n documents.push({ name, bytes: (await fs.stat(path.join(ws.contextDir, name))).size });\n included.push({ kind: 'document', id: name, reason: byType ? `reference for ${type}` : `request names \"${m[0]}\"` });\n }\n }\n }\n\n return {\n project: { name: project.name, id: project.projectId },\n request,\n type,\n confidence: cls.confidence,\n readOnly: cls.readOnly,\n facts,\n aliases,\n checks,\n safety,\n rules: SAFETY_RULES,\n decisions,\n documents,\n packages: [...pkgReason.keys()].sort(),\n included,\n counts: { facts: [facts.length, all.length], checks: [checks.length, usable.length], decisions: [decisions.length, decs.length], documents: [documents.length, docCount] },\n };\n}\n\nexport async function getTaskContext(\n o: ServiceOptions,\n opts: { request: string; role?: ContextRole },\n): Promise<TaskContextResult> {\n const base = await buildBaseTaskContext(o, opts.request);\n if (!opts.role) return base;\n return getAgentContextSlice(o, { request: opts.request, role: opts.role, base });\n}\n\nexport async function getAgentContextSlice(\n o: ServiceOptions,\n opts: { request: string; role: ContextRole; base?: TaskContextResult },\n): Promise<TaskContextResult> {\n const ws = await requireWorkspace(o.cwd);\n const base = opts.base ?? (await buildBaseTaskContext(o, opts.request));\n const role = opts.role;\n const kw = words(opts.request);\n const hit = (text: string): string[] => kw.filter((w) => text.includes(w));\n\n let slicedFacts = [...base.facts];\n let slicedChecks = [...base.checks];\n let slicedDecisions = [...base.decisions];\n let slicedDocuments = [...base.documents];\n let roleGuidance: string[] = [];\n const roleFindings: NonNullable<TaskContextResult['roleFindings']> = {};\n\n if (role === 'explorer') {\n // Explorer: Prioritize entry points, symbols, features, graph connections.\n // Avoid unrelated test commands, entire file contents, complete repo dumps.\n slicedChecks = [];\n slicedFacts = base.facts.filter((f) => {\n if (/^repo\\.(?:entry-points|packages|monorepo)$/.test(f.key)) return true;\n if (STACK_KEY.test(f.key) && !/^convention\\.test/i.test(f.key)) return true;\n const m = hit(`${f.key} ${f.value}`.toLowerCase());\n return m.length > 0 && !/^convention\\.test/i.test(f.key);\n });\n\n slicedDecisions = base.decisions.filter((d) => hit(`${d.title} ${d.file}`.toLowerCase()).length > 0).slice(0, 3);\n slicedDocuments = base.documents.filter((d) => ['architecture.md', 'integrations.md'].includes(d.name));\n\n // Entry points from facts or packages\n const epFact = base.facts.find((f) => f.key === 'repo.entry-points');\n const entryPoints: string[] = [];\n if (epFact && epFact.value) {\n for (const p of epFact.value.split(',').map((x) => x.trim()).filter(Boolean)) {\n if (!entryPoints.includes(p)) entryPoints.push(p);\n }\n }\n if (entryPoints.length === 0 && base.packages.length > 0) {\n entryPoints.push(...base.packages);\n }\n if (entryPoints.length > 0) roleFindings.entryPoints = entryPoints.slice(0, 10);\n\n // Feature knowledge map references\n try {\n const featFile = await loadFeatures(ws);\n const matchedFeats = featFile.features.filter((f) => {\n const text = `${f.id} ${f.name} ${f.description ?? ''} ${(f.tags ?? []).join(' ')}`.toLowerCase();\n return hit(text).length > 0;\n });\n if (matchedFeats.length > 0) {\n roleFindings.features = matchedFeats.slice(0, 8).map((f) => ({\n id: f.id,\n name: f.name,\n status: f.status,\n }));\n }\n } catch {\n // Graceful fallback if features file unreadable\n }\n\n // Graphify graph lookup\n try {\n const graph = await loadGraphData(ws.root);\n if (graph.exists && graph.data && graph.data.nodes) {\n const matchedNodes: NonNullable<TaskContextResult['roleFindings']>['graphNodes'] = [];\n for (const w of kw) {\n const n = findMatchingStartNode(graph.data.nodes, w);\n if (n && !matchedNodes.some((x) => x.id === n.id)) {\n matchedNodes.push({\n id: n.id,\n status: typeof n.status === 'string' ? n.status : 'symbol',\n path: n.path || n.file || null,\n symbol: typeof n.name === 'string' ? n.name : null,\n });\n }\n if (matchedNodes.length >= 6) break;\n }\n if (matchedNodes.length > 0) roleFindings.graphNodes = matchedNodes;\n }\n } catch {\n // Graceful fallback if graph lookup fails\n }\n\n roleGuidance = [\n 'Investigate referenced entry points and feature components before reading full files.',\n 'Trace deep call dependencies with \"devworkspace graph trace <symbol>\".',\n 'Conclude exploration with a concise handoff: identified files, uncertainty, and next step.',\n ];\n } else if (role === 'tester') {\n // Tester: Prioritize test files, test framework conventions, verification contracts, zero-test safeguards.\n slicedFacts = base.facts.filter((f) => {\n if (/^convention\\.test/i.test(f.key) || ISSUE_KEY.test(f.key)) return true;\n if (STACK_KEY.test(f.key) && /test/i.test(f.key + f.value)) return true;\n const m = hit(`${f.key} ${f.value}`.toLowerCase());\n return m.length > 0;\n });\n\n slicedChecks = base.checks;\n slicedDocuments = base.documents.filter((d) => d.name === 'testing.md');\n slicedDecisions = base.decisions.filter((d) => /test|verify|quality/i.test(d.title));\n\n roleFindings.zeroTestSafeguards = [\n 'Zero-test pass detection active across Vitest, Jest, Pytest, Mocha, Go, and Cargo.',\n 'Commands exiting code 0 with 0 tests executed are classified as unverified false passes.',\n 'Record baseline before modifications: devworkspace task tests <id> --phase baseline --passed <n> --failed <n>.',\n \"Execute verification via 'devworkspace task run <id> <check>'.\",\n ];\n\n roleGuidance = [\n 'Verify required contract commands for affected packages before claiming completion.',\n 'Write focused regression tests covering defect reproduction or feature acceptance criteria.',\n 'Never run destructive commands or test suites touching unmanaged databases without \"testenv declare\".',\n ];\n } else if (role === 'reviewer') {\n // Reviewer: Prioritize git diff/changed files, permanent safety rules, ADRs, potential regressions.\n slicedFacts = base.facts.filter((f) => {\n if (SECURITY_WORDS.test(`${f.key} ${f.value}`)) return true;\n if (/^convention\\./i.test(f.key)) return true;\n const m = hit(`${f.key} ${f.value}`.toLowerCase());\n return m.length > 0;\n });\n\n // Keep review-relevant checks (lint, typecheck, review, and test suites)\n if (base.checks.length > 0) {\n slicedChecks = base.checks.filter((c) => /lint|typecheck|review|test/i.test(c.id));\n } else {\n try {\n if (await pathExists(ws.commands)) {\n const contract = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data.checks;\n const usable = contract.filter((c) => c.available && /lint|typecheck|review|test/i.test(c.id));\n slicedChecks = base.packages.length > 0\n ? usable.filter((c) => !c.cwd || c.cwd === '.' || base.packages.includes(c.cwd))\n : usable;\n }\n } catch {\n slicedChecks = [];\n }\n }\n slicedDecisions = base.decisions;\n slicedDocuments = base.documents.filter((d) => ['conventions.md', 'architecture.md'].includes(d.name));\n\n try {\n const dirty = await dirtyFiles(ws.root);\n const dirtyList = dirty ? Object.keys(dirty.files) : [];\n if (dirtyList.length > 0) {\n const preview = dirtyList.slice(0, 5).join(', ') + (dirtyList.length > 5 ? ` (+${dirtyList.length - 5} more)` : '');\n roleFindings.diffNotice = `${dirtyList.length} uncommitted file(s) detected: ${preview}. Inspect exact diff with \"git diff\".`;\n } else {\n roleFindings.diffNotice = 'No uncommitted changes detected in working tree. When reviewing a branch or PR, the caller must supply the target diff or commit range.';\n }\n } catch {\n roleFindings.diffNotice = 'Could not inspect git working tree status. The caller must supply the diff or commit range.';\n }\n\n roleGuidance = [\n 'Audit diff against permanent SAFETY_RULES (no secrets in code/logs, no path traversals, untrusted commands).',\n 'Verify changes strictly comply with recorded decisions (ADRs) and feature contracts.',\n 'Ensure required verification checks have executed results before approving the completion gate.',\n ];\n }\n\n const factKeys = new Set(slicedFacts.map((f) => f.key));\n const checkIds = new Set(slicedChecks.map((c) => `${c.cwd ?? '.'}:${c.id}`));\n const decIds = new Set(slicedDecisions.map((d) => String(d.number).padStart(4, '0')));\n const docNames = new Set(slicedDocuments.map((d) => d.name));\n\n const included: ContextItem[] = base.included.filter((item) => {\n if (item.kind === 'rule') return true;\n if (item.kind === 'fact') return factKeys.has(item.id);\n if (item.kind === 'check') return checkIds.has(item.id);\n if (item.kind === 'decision') return decIds.has(item.id);\n if (item.kind === 'document') return docNames.has(item.id);\n return false;\n });\n\n included.push({\n kind: 'rule',\n id: `role:${role}`,\n reason: `context tailored for ${role} role (Phase 1 role-based context slicing)`,\n });\n\n return {\n ...base,\n role,\n facts: slicedFacts,\n checks: slicedChecks,\n decisions: slicedDecisions,\n documents: slicedDocuments,\n rules: SAFETY_RULES,\n included,\n counts: {\n facts: [slicedFacts.length, base.counts.facts[1]],\n checks: [slicedChecks.length, base.counts.checks[1]],\n decisions: [slicedDecisions.length, base.counts.decisions[1]],\n documents: [slicedDocuments.length, base.counts.documents[1]],\n },\n roleGuidance,\n roleFindings,\n };\n}\n"]}
1
+ {"version":3,"file":"taskContext.js","sourceRoot":"","sources":["../../src/services/taskContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { SCHEMA_VERSION, validateCommands, type CommandEntry, type Fact } from '../config/schemas.js';\nimport { loadProject, requireWorkspace } from '../core/workspace.js';\nimport { readVersioned } from '../core/versioned.js';\nimport { listDecisions } from '../decisions/decision.js';\nimport { loadFacts } from '../knowledge/facts.js';\nimport { classifyRequest } from '../tasks/routing.js';\nimport type { TaskType } from '../tasks/task.js';\nimport { pathExists } from '../utils/fs.js';\nimport { classifyCommand, readManifestEvidence } from '../verification/safety.js';\nimport { dirtyFiles, packageDirs } from '../verification/scope.js';\nimport { SAFETY_RULES, type ContextResult } from './knowledge.js';\nimport type { ServiceOptions } from './common.js';\nimport { loadFeatures } from './features.js';\nimport { loadGraphData, findMatchingStartNode } from './graph.js';\n\nexport const CONTEXT_ROLES = ['explorer', 'tester', 'reviewer'] as const;\nexport type ContextRole = (typeof CONTEXT_ROLES)[number];\n\nexport function isContextRole(v: unknown): v is ContextRole {\n return typeof v === 'string' && (CONTEXT_ROLES as readonly string[]).includes(v);\n}\n\nexport interface ContextItem {\n kind: 'fact' | 'check' | 'decision' | 'document' | 'rule';\n id: string;\n /** Why this item is in the context; every item carries one. */\n reason: string;\n}\n\nexport interface TaskContextResult {\n project: { name: string; id: string };\n request: string;\n type: TaskType;\n confidence: 'high' | 'low';\n readOnly: boolean;\n /** `clipped` = characters left out of a long detector-derived value; the full value is in facts.json. */\n facts: (Fact & { clipped?: number })[];\n /** Detector facts folded into another fact with the identical value; nothing is deleted from facts.json. */\n aliases: { key: string; sameAs: string }[];\n checks: CommandEntry[];\n safety: ContextResult['safety'];\n rules: string[];\n decisions: { number: number; title: string; status: string; file: string }[];\n /** Detailed documents are referenced by name, never embedded. */\n documents: { name: string; bytes: number }[];\n packages: string[];\n included: ContextItem[];\n counts: { facts: [number, number]; checks: [number, number]; decisions: [number, number]; documents: [number, number] };\n role?: ContextRole;\n roleGuidance?: string[];\n roleFindings?: {\n entryPoints?: string[];\n graphNodes?: { id: string; status: string; path: string | null; symbol: string | null }[];\n features?: { id: string; name: string; status?: string }[];\n testFrameworks?: string[];\n zeroTestSafeguards?: string[];\n diffNotice?: string;\n };\n}\n\nconst STOP = new Set([\n 'the', 'and', 'for', 'with', 'that', 'this', 'from', 'into', 'does', 'how',\n 'what', 'where', 'why', 'when', 'which', 'fix', 'add', 'bug', 'make', 'new',\n 'can', 'are', 'not', 'our', 'all', 'use', 'get', 'set', 'let', 'may'\n]);\nconst WEAK_TERMS = new Set(['error', 'errors', 'check', 'checks', 'data', 'improve', 'update', 'run', 'test', 'handle', 'handling', 'code']);\nconst PATH_STRUCTURAL_TERMS = new Set([\n 'backend', 'frontend', 'service', 'services', 'controller', 'controllers',\n 'worker', 'workers', 'dto', 'dtos', 'src', 'modules', 'app', 'tests',\n 'unit', 'integration', 'test', 'spec', 'ts', 'tsx', 'js', 'jsx', 'json', 'md'\n]);\nconst CLIP = 400;\nconst SECURITY_WORDS = /auth|tenant|permission|rbac|security|isolation|role|session|ownership/i;\nconst ISSUE_KEY = /^(?:issue|limit|known|bug|risk)/i;\n/** Facts that describe the stack and layout; implementation-style tasks need them, a lookup question does not. */\nconst STACK_KEY = /^(?:stack\\.|repo\\.packages|repo\\.monorepo|repo\\.entry-points|convention|style|arch|pattern|testing)/i;\nconst BROAD_TYPES: TaskType[] = ['FEATURE', 'REFACTOR', 'ARCHITECTURE', 'TESTING', 'PERFORMANCE', 'MAINTENANCE', 'RELEASE'];\n\n/** Normalizes words by stripping standard English inflectional suffixes deterministically. */\nfunction normalizeStem(w: string): string {\n const s = w.toLowerCase().trim();\n if (s.endsWith('ies') && s.length > 4) return s.slice(0, -3) + 'y';\n if (s.endsWith('es') && s.length > 4 && /[sxz]|ch|sh$/.test(s.slice(0, -2))) return s.slice(0, -2);\n if (s.endsWith('s') && s.length > 3 && !s.endsWith('ss')) return s.slice(0, -1);\n if (s.endsWith('ing') && s.length > 5) return s.slice(0, -3);\n if (s.endsWith('tion') && s.length > 6) return s.slice(0, -4);\n if (s.endsWith('ed') && s.length > 4) return s.slice(0, -2);\n return s;\n}\n\n/** Explicit domain synonym dictionary grounded in engineering tasks and repository knowledge. */\nconst DOMAIN_SYNONYMS: Record<string, string[]> = {\n // Database, migrations, schema and persistence\n table: ['database', 'schema', 'orm', 'migration', 'sql'],\n column: ['database', 'schema', 'migration', 'sql'],\n schema: ['database', 'orm', 'migration', 'sql', 'drizzle', 'postgres'],\n migration: ['database', 'schema', 'migrate', 'sql', 'drizzle'],\n migrate: ['database', 'schema', 'migration', 'sql'],\n sql: ['database', 'postgres', 'drizzle', 'query'],\n db: ['database', 'postgres', 'drizzle', 'orm'],\n database: ['db', 'schema', 'orm', 'postgres', 'drizzle'],\n drizzle: ['database', 'orm', 'schema'],\n postgres: ['database', 'sql'],\n\n // Authentication, tenancy, and authorization\n auth: ['jwt', 'session', 'security', 'tenant', 'permission'],\n jwt: ['auth', 'session', 'token', 'security'],\n password: ['hash', 'argon2', 'auth', 'security'],\n hash: ['password', 'argon2', 'security'],\n tenant: ['tenancy', 'isolation', 'security', 'auth'],\n tenancy: ['tenant', 'isolation', 'security'],\n isolation: ['tenant', 'tenancy', 'security'],\n\n // Billing and financial\n invoice: ['billing', 'cents', 'precision'],\n billing: ['invoice', 'cents', 'precision'],\n cents: ['billing', 'invoice', 'precision'],\n payment: ['stripe', 'gateway'],\n\n // API, HTTP, and Backend Services\n endpoint: ['api', 'controller', 'service', 'dto'],\n api: ['endpoint', 'controller', 'service', 'dto'],\n supplier: ['supplier', 'dto', 'service'],\n controller: ['service', 'dto', 'api', 'endpoint'],\n dto: ['validation', 'typebox', 'schema', 'controller'],\n\n // Frontend and UI\n component: ['ui', 'frontend', 'page', 'react'],\n pagination: ['ui', 'component', 'frontend', 'table'],\n frontend: ['ui', 'component', 'react'],\n ui: ['component', 'frontend', 'react'],\n react: ['ui', 'component', 'frontend'],\n\n // Inventory and Stock\n stock: ['inventory', 'product', 'service'],\n inventory: ['stock', 'product', 'service'],\n product: ['inventory', 'stock', 'service'],\n sku: ['product', 'inventory', 'barcode'],\n barcode: ['sku', 'product', 'inventory']\n};\n\n/** Extracts words from text without punctuation. */\nconst words = (text: string): string[] =>\n [...new Set((text.toLowerCase().match(/[a-z0-9_][a-z0-9_.-]{1,}/g) ?? []).filter((w) => !STOP.has(w)))].sort();\n\n/** Expands terms using word stemming and explicit domain synonym clusters. */\nfunction expandQueryTerms(rawWords: string[]): string[] {\n const expanded = new Set<string>(rawWords);\n for (const w of rawWords) {\n const stem = normalizeStem(w);\n if (stem.length >= 2) expanded.add(stem);\n const syns = DOMAIN_SYNONYMS[w] ?? DOMAIN_SYNONYMS[stem];\n if (syns) {\n for (const s of syns) expanded.add(s);\n }\n }\n return [...expanded].sort();\n}\n\n/** Matches terms against text with token/boundary precision. */\nfunction matchesQuery(text: string, terms: string[]): string[] {\n const lower = text.toLowerCase();\n const matched: string[] = [];\n for (const term of terms) {\n if (term.includes('.') || term.includes('/')) {\n if (lower.includes(term)) matched.push(term);\n } else {\n const re = new RegExp(`(?:^|[\\\\s._/:-])${term}(?:$|[\\\\s._/:-])`, 'i');\n if (re.test(lower)) matched.push(term);\n }\n }\n return matched;\n}\n\nconst norm = (s: string): string => s.toLowerCase().replace(/\\s+/g, ' ').trim();\n\n/** Which context documents are worth pointing at for a task type. */\nconst DOCS_BY_TYPE: Partial<Record<TaskType, string[]>> = {\n ARCHITECTURE: ['architecture.md', 'integrations.md'],\n REFACTOR: ['architecture.md', 'conventions.md'],\n FEATURE: ['architecture.md', 'conventions.md'],\n BUG: ['testing.md'],\n TESTING: ['testing.md'],\n SECURITY: ['testing.md', 'architecture.md'],\n PERFORMANCE: ['architecture.md'],\n RELEASE: ['testing.md'],\n};\n\n/**\n * Task-aware context. Selection is deterministic (sorted inputs, no clocks, no randomness) and rule-based: the request is\n * classified, its keywords select facts/decisions/packages, and the type decides which broader groups come along.\n * Safety rules are included for every type; the per-package \"not run automatically\" list whenever checks are included.\n */\nasync function buildBaseTaskContext(o: ServiceOptions, request: string): Promise<TaskContextResult> {\n const ws = await requireWorkspace(o.cwd);\n const project = await loadProject(ws);\n const cls = classifyRequest(request);\n const type = cls.type;\n const kw = words(request);\n const expandedTerms = expandQueryTerms(kw);\n const included: ContextItem[] = [];\n const hit = (text: string): string[] => matchesQuery(text, expandedTerms);\n\n // Packages and the testing contract\n let allChecks: CommandEntry[] = [];\n if (await pathExists(ws.commands)) allChecks = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data.checks;\n const pkgReason = new Map<string, string>();\n for (const d of packageDirs(allChecks)) {\n const m = matchesQuery(request, [d]);\n if (m.length > 0) pkgReason.set(d, `request names \"${m[0]}\"`);\n }\n\n // Enhanced package discovery from domain context when not explicitly named\n if (pkgReason.size === 0 && packageDirs(allChecks).length > 1) {\n const hasBackend = matchesQuery(request, ['api', 'endpoint', 'endpoints', 'controller', 'controllers', 'dto', 'dtos', 'database', 'migration', 'migrations', 'migrate', 'sql', 'postgres', 'drizzle', 'orm', 'fastify', 'server', 'jwt', 'argon2', 'service', 'services', 'invoice']).length > 0;\n const hasFrontend = matchesQuery(request, ['ui', 'component', 'components', 'frontend', 'page', 'pages', 'pagination', 'react', 'vite', 'view', 'views', 'button', 'modal']).length > 0;\n const available = packageDirs(allChecks);\n if (hasBackend && !hasFrontend && available.includes('backend')) {\n pkgReason.set('backend', 'inferred from backend domain terminology');\n } else if (hasFrontend && !hasBackend && available.includes('frontend')) {\n pkgReason.set('frontend', 'inferred from frontend UI terminology');\n } else if (hasBackend && hasFrontend) {\n if (available.includes('backend')) pkgReason.set('backend', 'request spans backend');\n if (available.includes('frontend')) pkgReason.set('frontend', 'request spans frontend');\n }\n }\n\n // dirtyFiles already leaves out documentation and tool-managed files, so a docs-only change selects no package.\n // Only worth the Git calls when the request did not already pick a package and there is more than one to choose from.\n const dirty = type !== 'QUESTION' && type !== 'DOCUMENTATION' && pkgReason.size === 0 && packageDirs(allChecks).length > 1 ? await dirtyFiles(ws.root) : null;\n for (const f of Object.keys(dirty?.files ?? {})) {\n const d = packageDirs(allChecks).find((x) => f === x || f.startsWith(`${x}/`));\n if (d && !pkgReason.has(d)) pkgReason.set(d, 'has uncommitted code changes');\n }\n\n // Facts\n const all = (await loadFacts(ws)).facts;\n const picked = new Map<string, string>();\n const isSinglePackage = pkgReason.size === 1;\n const targetPkg = isSinglePackage ? [...pkgReason.keys()][0] : null;\n\n for (const f of all) {\n // If request confidently targets a single package, avoid pulling in unrelated package facts\n if (targetPkg === 'backend') {\n if (f.source.startsWith('frontend/') || f.key === 'stack.ui' || f.key.startsWith('convention.frontend')) {\n continue;\n }\n } else if (targetPkg === 'frontend') {\n if (f.source.startsWith('backend/') || f.key === 'stack.database' || f.key === 'stack.orm' || f.key.startsWith('testing.db')) {\n continue;\n }\n }\n\n // Match terms against fact key and value; only match source path against specific non-structural request words\n const mText = hit(`${f.key} ${f.value}`);\n const mSource = matchesQuery(f.source, kw.filter((w) => !PATH_STRUCTURAL_TERMS.has(w)));\n const m = [...new Set([...mText, ...mSource])];\n const nonWeak = m.filter(w => !WEAK_TERMS.has(w));\n if (nonWeak.length > 0) picked.set(f.key, `matches \"${nonWeak.slice(0, 3).join('\", \"')}\"`);\n }\n\n const group = (re: RegExp, why: string, also?: (f: Fact) => boolean): void => {\n for (const f of all) {\n if (picked.has(f.key)) continue;\n if (targetPkg === 'backend' && (f.source.startsWith('frontend/') || f.key === 'stack.ui' || f.key.startsWith('convention.frontend'))) continue;\n if (targetPkg === 'frontend' && (f.source.startsWith('backend/') || f.key === 'stack.database' || f.key === 'stack.orm' || f.key.startsWith('testing.db'))) continue;\n if (re.test(f.key) || also?.(f)) picked.set(f.key, why);\n }\n };\n\n // Package layout facts: include in multi-package/cross-package/uncertain contexts, omit global entry points in single-package tasks\n if (type !== 'QUESTION' && type !== 'DOCUMENTATION') {\n if (!isSinglePackage || type === 'ARCHITECTURE') {\n group(/^repo\\.(?:packages|entry-points|monorepo)$/, `package layout (${type})`);\n }\n }\n\n if (type === 'BUG' || type === 'SECURITY') group(ISSUE_KEY, 'known issue / limitation', (f) => f.status === 'STALE' && f.sourceType !== 'detector');\n\n if (BROAD_TYPES.includes(type)) {\n group(/^stack\\.ecosystem$/, `stack and conventions (${type})`);\n if (targetPkg === 'backend' || !isSinglePackage) {\n group(/^(?:arch\\.modules|convention\\.service-layer)$/, `architecture conventions (${type})`);\n group(/^(?:stack\\.framework|stack\\.database|stack\\.orm)$/, `backend stack (${type})`);\n }\n if (targetPkg === 'frontend' || !isSinglePackage) {\n group(/^(?:convention\\.frontend-components|stack\\.ui)$/, `frontend stack (${type})`);\n }\n }\n\n if (type === 'SECURITY') group(/^$/, 'security / authorization rule', (f) => SECURITY_WORDS.test(`${f.key} ${f.value}`));\n if (type === 'DOCUMENTATION') group(/^repo\\.docs$/, 'documentation index');\n const selected = all.filter((f) => picked.has(f.key));\n\n // Compaction: a detector fact whose value equals another selected fact's is folded into it. Human-authored facts are never folded or clipped.\n const aliases: TaskContextResult['aliases'] = [];\n const owners = new Map<string, string>();\n for (const f of [...selected].sort((a, b) => Number(a.sourceType === 'detector') - Number(b.sourceType === 'detector') || a.key.localeCompare(b.key))) {\n if (!owners.has(norm(f.value))) owners.set(norm(f.value), f.key);\n }\n const facts: TaskContextResult['facts'] = [];\n for (const f of [...selected].sort((a, b) => a.key.localeCompare(b.key))) {\n const owner = owners.get(norm(f.value))!;\n if (owner !== f.key && f.sourceType === 'detector') {\n aliases.push({ key: f.key, sameAs: owner });\n continue;\n }\n const clip = f.sourceType === 'detector' && f.value.length > CLIP;\n facts.push(clip ? { ...f, value: f.value.slice(0, CLIP), clipped: f.value.length - CLIP } : f);\n included.push({ kind: 'fact', id: f.key, reason: picked.get(f.key)! });\n }\n\n const usable = allChecks.filter((c) => c.available);\n const scoped = pkgReason.size > 0 ? usable.filter((c) => !c.cwd || c.cwd === '.' || pkgReason.has(c.cwd)) : usable;\n const checks = type === 'QUESTION' || type === 'DOCUMENTATION' ? [] : scoped;\n for (const c of checks) included.push({ kind: 'check', id: `${c.cwd ?? '.'}:${c.id}`, reason: c.cwd && pkgReason.has(c.cwd) ? `package: ${pkgReason.get(c.cwd)}` : `testing contract (${type})` });\n\n // Commands that must not run unguarded stay visible whenever their package's checks are in play.\n const safety: ContextResult['safety'] = [];\n for (const c of checks) {\n const s = classifyCommand(c, await readManifestEvidence(ws.root, c));\n if (s.safety !== 'safe') safety.push({ package: c.cwd ?? '.', check: c.id, command: c.command, safety: s.safety, reasons: s.reasons });\n }\n SAFETY_RULES.forEach((_, i) => included.push({ kind: 'rule', id: `safety-${i + 1}`, reason: 'safety rule, included in every context' }));\n\n // Decisions: titles, context, decision, consequences, and file references\n const decs = (await listDecisions(ws)).decisions;\n const wantAll = type === 'ARCHITECTURE' || type === 'SECURITY';\n const decisions: TaskContextResult['decisions'] = [];\n for (const d of decs) {\n const fullText = `${d.title} ${d.decision} ${d.context} ${d.consequences} ${d.file}`;\n const m = matchesQuery(fullText, expandedTerms);\n const nonWeak = m.filter(w => !WEAK_TERMS.has(w));\n if (d.status === 'superseded' && nonWeak.length === 0) continue;\n if (nonWeak.length > 0 || wantAll) {\n decisions.push({ number: d.number, title: d.title, status: d.status, file: d.file });\n included.push({ kind: 'decision', id: String(d.number).padStart(4, '0'), reason: nonWeak.length > 0 ? `matches \"${nonWeak[0]}\"` : `${type} tasks review all decisions` });\n }\n }\n\n // Documents: referenced, never embedded\n const documents: TaskContextResult['documents'] = [];\n let docCount = 0;\n if (await pathExists(ws.contextDir)) {\n for (const name of (await fs.readdir(ws.contextDir)).filter((n) => n.endsWith('.md')).sort()) {\n docCount++;\n const byType = (DOCS_BY_TYPE[type] ?? []).includes(name);\n const m = matchesQuery(name, expandedTerms);\n if (byType || m.length > 0) {\n documents.push({ name, bytes: (await fs.stat(path.join(ws.contextDir, name))).size });\n included.push({ kind: 'document', id: name, reason: byType ? `reference for ${type}` : `request names \"${m[0]}\"` });\n }\n }\n }\n\n return {\n project: { name: project.name, id: project.projectId },\n request,\n type,\n confidence: cls.confidence,\n readOnly: cls.readOnly,\n facts,\n aliases,\n checks,\n safety,\n rules: SAFETY_RULES,\n decisions,\n documents,\n packages: [...pkgReason.keys()].sort(),\n included,\n counts: { facts: [facts.length, all.length], checks: [checks.length, usable.length], decisions: [decisions.length, decs.length], documents: [documents.length, docCount] },\n };\n}\n\nexport async function getTaskContext(\n o: ServiceOptions,\n opts: { request: string; role?: ContextRole },\n): Promise<TaskContextResult> {\n const base = await buildBaseTaskContext(o, opts.request);\n if (!opts.role) return base;\n return getAgentContextSlice(o, { request: opts.request, role: opts.role, base });\n}\n\nexport async function getAgentContextSlice(\n o: ServiceOptions,\n opts: { request: string; role: ContextRole; base?: TaskContextResult },\n): Promise<TaskContextResult> {\n const ws = await requireWorkspace(o.cwd);\n const base = opts.base ?? (await buildBaseTaskContext(o, opts.request));\n const role = opts.role;\n const kw = words(opts.request);\n const expandedTerms = expandQueryTerms(kw);\n const hit = (text: string): string[] => matchesQuery(text, expandedTerms);\n\n let slicedFacts = [...base.facts];\n let slicedChecks = [...base.checks];\n let slicedDecisions = [...base.decisions];\n let slicedDocuments = [...base.documents];\n let roleGuidance: string[] = [];\n const roleFindings: NonNullable<TaskContextResult['roleFindings']> = {};\n\n if (role === 'explorer') {\n // Explorer: Prioritize entry points, symbols, features, graph connections.\n // Avoid unrelated test commands, entire file contents, complete repo dumps.\n slicedChecks = [];\n slicedFacts = base.facts.filter((f) => {\n if (/^repo\\.(?:entry-points|packages|monorepo)$/.test(f.key)) return true;\n if (STACK_KEY.test(f.key) && !/^convention\\.test/i.test(f.key)) return true;\n const m = hit(`${f.key} ${f.value}`);\n return m.length > 0 && !/^convention\\.test/i.test(f.key);\n });\n\n slicedDecisions = base.decisions.slice(0, 3);\n slicedDocuments = base.documents.filter((d) => ['architecture.md', 'integrations.md'].includes(d.name));\n\n // Entry points from facts or packages\n const epFact = base.facts.find((f) => f.key === 'repo.entry-points');\n const entryPoints: string[] = [];\n if (epFact && epFact.value) {\n for (const p of epFact.value.split(',').map((x) => x.trim()).filter(Boolean)) {\n if (!entryPoints.includes(p)) entryPoints.push(p);\n }\n }\n if (entryPoints.length === 0 && base.packages.length > 0) {\n entryPoints.push(...base.packages);\n }\n if (entryPoints.length > 0) roleFindings.entryPoints = entryPoints.slice(0, 10);\n\n // Feature knowledge map references\n try {\n const featFile = await loadFeatures(ws);\n const matchedFeats = featFile.features.filter((f) => {\n const text = `${f.id} ${f.name} ${f.description ?? ''} ${(f.tags ?? []).join(' ')}`;\n return hit(text).length > 0;\n });\n if (matchedFeats.length > 0) {\n roleFindings.features = matchedFeats.slice(0, 8).map((f) => ({\n id: f.id,\n name: f.name,\n status: f.status,\n }));\n }\n } catch {\n // Graceful fallback if features file unreadable\n }\n\n // Graphify graph lookup\n try {\n const graph = await loadGraphData(ws.root);\n if (graph.exists && graph.data && graph.data.nodes) {\n const matchedNodes: NonNullable<TaskContextResult['roleFindings']>['graphNodes'] = [];\n for (const w of expandedTerms) {\n const n = findMatchingStartNode(graph.data.nodes, w);\n if (n && !matchedNodes.some((x) => x.id === n.id)) {\n matchedNodes.push({\n id: n.id,\n status: typeof n.status === 'string' ? n.status : 'symbol',\n path: n.path || n.file || null,\n symbol: typeof n.name === 'string' ? n.name : null,\n });\n }\n if (matchedNodes.length >= 6) break;\n }\n if (matchedNodes.length > 0) roleFindings.graphNodes = matchedNodes;\n }\n } catch {\n // Graceful fallback if graph lookup fails\n }\n\n roleGuidance = [\n 'Investigate referenced entry points and feature components before reading full files.',\n 'Trace deep call dependencies with \"devworkspace graph trace <symbol>\".',\n 'Conclude exploration with a concise handoff: identified files, uncertainty, and next step.',\n ];\n } else if (role === 'tester') {\n // Tester: Prioritize test files, test framework conventions, verification contracts, zero-test safeguards.\n slicedFacts = base.facts.filter((f) => {\n if (/^convention\\.test/i.test(f.key) || ISSUE_KEY.test(f.key)) return true;\n if (STACK_KEY.test(f.key) && /test/i.test(f.key + f.value)) return true;\n const m = hit(`${f.key} ${f.value}`.toLowerCase());\n return m.length > 0;\n });\n\n slicedChecks = base.checks;\n slicedDocuments = base.documents.filter((d) => d.name === 'testing.md');\n slicedDecisions = base.decisions.filter((d) => /test|verify|quality/i.test(d.title));\n\n roleFindings.zeroTestSafeguards = [\n 'Zero-test pass detection active across Vitest, Jest, Pytest, Mocha, Go, and Cargo.',\n 'Commands exiting code 0 with 0 tests executed are classified as unverified false passes.',\n 'Record baseline before modifications: devworkspace task tests <id> --phase baseline --passed <n> --failed <n>.',\n \"Execute verification via 'devworkspace task run <id> <check>'.\",\n ];\n\n roleGuidance = [\n 'Verify required contract commands for affected packages before claiming completion.',\n 'Write focused regression tests covering defect reproduction or feature acceptance criteria.',\n 'Never run destructive commands or test suites touching unmanaged databases without \"testenv declare\".',\n ];\n } else if (role === 'reviewer') {\n // Reviewer: Prioritize git diff/changed files, permanent safety rules, ADRs, potential regressions.\n slicedFacts = base.facts.filter((f) => {\n if (SECURITY_WORDS.test(`${f.key} ${f.value}`)) return true;\n if (/^convention\\./i.test(f.key)) return true;\n const m = hit(`${f.key} ${f.value}`.toLowerCase());\n return m.length > 0;\n });\n\n // Keep review-relevant checks (lint, typecheck, review, and test suites)\n if (base.checks.length > 0) {\n slicedChecks = base.checks.filter((c) => /lint|typecheck|review|test/i.test(c.id));\n } else {\n try {\n if (await pathExists(ws.commands)) {\n const contract = (await readVersioned(ws.commands, 'commands', SCHEMA_VERSION, validateCommands)).data.checks;\n const usable = contract.filter((c) => c.available && /lint|typecheck|review|test/i.test(c.id));\n slicedChecks = base.packages.length > 0\n ? usable.filter((c) => !c.cwd || c.cwd === '.' || base.packages.includes(c.cwd))\n : usable;\n }\n } catch {\n slicedChecks = [];\n }\n }\n slicedDecisions = base.decisions;\n slicedDocuments = base.documents.filter((d) => ['conventions.md', 'architecture.md'].includes(d.name));\n\n try {\n const dirty = await dirtyFiles(ws.root);\n const dirtyList = dirty ? Object.keys(dirty.files) : [];\n if (dirtyList.length > 0) {\n const preview = dirtyList.slice(0, 5).join(', ') + (dirtyList.length > 5 ? ` (+${dirtyList.length - 5} more)` : '');\n roleFindings.diffNotice = `${dirtyList.length} uncommitted file(s) detected: ${preview}. Inspect exact diff with \"git diff\".`;\n } else {\n roleFindings.diffNotice = 'No uncommitted changes detected in working tree. When reviewing a branch or PR, the caller must supply the target diff or commit range.';\n }\n } catch {\n roleFindings.diffNotice = 'Could not inspect git working tree status. The caller must supply the diff or commit range.';\n }\n\n roleGuidance = [\n 'Audit diff against permanent SAFETY_RULES (no secrets in code/logs, no path traversals, untrusted commands).',\n 'Verify changes strictly comply with recorded decisions (ADRs) and feature contracts.',\n 'Ensure required verification checks have executed results before approving the completion gate.',\n ];\n }\n\n const factKeys = new Set(slicedFacts.map((f) => f.key));\n const checkIds = new Set(slicedChecks.map((c) => `${c.cwd ?? '.'}:${c.id}`));\n const decIds = new Set(slicedDecisions.map((d) => String(d.number).padStart(4, '0')));\n const docNames = new Set(slicedDocuments.map((d) => d.name));\n\n const included: ContextItem[] = base.included.filter((item) => {\n if (item.kind === 'rule') return true;\n if (item.kind === 'fact') return factKeys.has(item.id);\n if (item.kind === 'check') return checkIds.has(item.id);\n if (item.kind === 'decision') return decIds.has(item.id);\n if (item.kind === 'document') return docNames.has(item.id);\n return false;\n });\n\n included.push({\n kind: 'rule',\n id: `role:${role}`,\n reason: `context tailored for ${role} role (Phase 1 role-based context slicing)`,\n });\n\n return {\n ...base,\n role,\n facts: slicedFacts,\n checks: slicedChecks,\n decisions: slicedDecisions,\n documents: slicedDocuments,\n rules: SAFETY_RULES,\n included,\n counts: {\n facts: [slicedFacts.length, base.counts.facts[1]],\n checks: [slicedChecks.length, base.counts.checks[1]],\n decisions: [slicedDecisions.length, base.counts.decisions[1]],\n documents: [slicedDocuments.length, base.counts.documents[1]],\n },\n roleGuidance,\n roleFindings,\n };\n}\n"]}
package/docs/agents.md CHANGED
@@ -50,6 +50,38 @@ Every adapter implements the `AgentAdapter` contract defined in `src/agents/type
50
50
  - **Doctor & Readiness (`devworkspace doctor`)**:
51
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
52
 
53
+ ## Model Context Protocol (MCP) Integration
54
+
55
+ For agents that support the Model Context Protocol (such as Claude Code, OpenAI Codex, and Google Antigravity), DevWorkspace can be configured as a local stdio MCP server:
56
+
57
+ ```bash
58
+ # Configure Claude Code (.mcp.json)
59
+ devworkspace setup --agent claude-code
60
+
61
+ # Configure OpenAI Codex (mcp.json)
62
+ devworkspace setup --agent codex
63
+
64
+ # Configure Google Antigravity (.antigravity/mcp.json)
65
+ devworkspace setup --agent antigravity
66
+
67
+ # Preview planned configuration changes without modifying files:
68
+ devworkspace setup --agent claude-code --check
69
+ ```
70
+
71
+ See [docs/mcp.md](mcp.md) for full protocol details, security boundaries, and debugging instructions.
72
+
73
+ ### Instruction Markers Coexistence
74
+
75
+ DevWorkspace strictly segregates standard CLI instructions from MCP instructions using dedicated HTML comment markers:
76
+ - Standard Agent Instructions: `<!-- devworkspace:start -->` ... `<!-- devworkspace:end -->`
77
+ - MCP Agent Instructions: `<!-- devworkspace-mcp:start -->` ... `<!-- devworkspace-mcp:end -->`
78
+
79
+ Both sets of instructions can coexist in the same project files (e.g. `CLAUDE.md`, `AGENTS.md`, or `.antigravity/rules`). Running `devworkspace agent install` or `devworkspace setup --agent <name>` will never overwrite or clobber the other block, and all custom user notes outside the blocks are preserved byte-for-byte.
80
+
81
+ ### MCP PATH Requirements
82
+
83
+ The generated agent configurations register `"command": "devworkspace"`. Ensure that `devworkspace` is available in your system `PATH` (such as via `npm install -g devworkspace`). If you prefer running without global binaries, modify the command in `.mcp.json` / `mcp.json` / `.antigravity/mcp.json` to `"npx"` with arguments `["-y", "devworkspace", "mcp", "serve"]`.
84
+
53
85
  ## Adding a New Agent Adapter
54
86
 
55
87
  To add support for a new coding agent: