agentsys 5.6.4 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.claude-plugin/marketplace.json +30 -19
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.kiro/agents/exploration-agent.json +1 -1
  4. package/.kiro/agents/implementation-agent.json +1 -1
  5. package/.kiro/agents/map-validator.json +2 -2
  6. package/.kiro/agents/perf-orchestrator.json +1 -1
  7. package/.kiro/agents/planning-agent.json +1 -1
  8. package/.kiro/skills/perf-code-paths/SKILL.md +1 -1
  9. package/.kiro/skills/perf-theory-gatherer/SKILL.md +1 -1
  10. package/.kiro/skills/repo-intel/SKILL.md +63 -0
  11. package/AGENTS.md +10 -8
  12. package/CHANGELOG.md +37 -0
  13. package/README.md +152 -98
  14. package/lib/binary/version.js +1 -1
  15. package/lib/repo-map/converter.js +130 -0
  16. package/lib/repo-map/index.js +117 -74
  17. package/lib/repo-map/installer.js +38 -172
  18. package/lib/repo-map/updater.js +16 -474
  19. package/meta/skills/maintain-cross-platform/SKILL.md +7 -6
  20. package/package.json +3 -3
  21. package/scripts/fix-graduated-repos.js +2 -2
  22. package/scripts/generate-docs.js +22 -16
  23. package/scripts/graduate-plugin.js +1 -1
  24. package/scripts/plugins.txt +7 -1
  25. package/scripts/preflight.js +4 -4
  26. package/scripts/validate-cross-platform-docs.js +2 -2
  27. package/site/content.json +40 -23
  28. package/site/index.html +44 -12
  29. package/site/ux-spec.md +6 -6
  30. package/.kiro/skills/repo-mapping/SKILL.md +0 -83
  31. package/lib/repo-map/concurrency.js +0 -29
  32. package/lib/repo-map/queries/go.js +0 -27
  33. package/lib/repo-map/queries/index.js +0 -100
  34. package/lib/repo-map/queries/java.js +0 -38
  35. package/lib/repo-map/queries/javascript.js +0 -55
  36. package/lib/repo-map/queries/python.js +0 -24
  37. package/lib/repo-map/queries/rust.js +0 -73
  38. package/lib/repo-map/queries/typescript.js +0 -38
  39. package/lib/repo-map/runner.js +0 -1364
  40. package/lib/repo-map/usage-analyzer.js +0 -407
@@ -1,347 +1,23 @@
1
+ 'use strict';
2
+
1
3
  /**
2
- * Repo map incremental updater
4
+ * Repo map staleness checker.
5
+ *
6
+ * Determines whether a cached repo-map is stale relative to the current git HEAD.
7
+ * The incremental update path is handled by agent-analyzer (repo-intel update).
3
8
  *
4
9
  * @module lib/repo-map/updater
5
10
  */
6
11
 
7
- 'use strict';
8
-
9
- const fsPromises = require('fs').promises;
10
- const path = require('path');
11
12
  const { execFileSync } = require('child_process');
12
13
 
13
- const runner = require('./runner');
14
14
  const cache = require('./cache');
15
- const installer = require('./installer');
16
- const { runWithConcurrency } = require('./concurrency');
17
-
18
- const SCAN_CONCURRENCY = 8;
19
- const SCANNABLE_EXTENSIONS = new Set(Object.values(runner.LANGUAGE_EXTENSIONS).flat());
20
-
21
- function isScannableFile(filePath) {
22
- const ext = path.extname(filePath).toLowerCase();
23
- return SCANNABLE_EXTENSIONS.has(ext);
24
- }
25
-
26
- /**
27
- * Perform incremental update based on git diff
28
- * @param {string} basePath - Repository root
29
- * @param {Object} map - Existing repo map
30
- * @returns {Promise<{success: boolean, map?: Object, changes?: Object, error?: string, needsFullRebuild?: boolean}>}
31
- */
32
- async function incrementalUpdate(basePath, map) {
33
- // Validate ast-grep
34
- const installed = installer.checkInstalledSync();
35
- if (!installed.found) {
36
- return {
37
- success: false,
38
- error: 'ast-grep not found',
39
- installSuggestion: installer.getInstallInstructions()
40
- };
41
- }
42
-
43
- if (!installer.meetsMinimumVersion(installed.version)) {
44
- return {
45
- success: false,
46
- error: `ast-grep version ${installed.version || 'unknown'} is too old. Minimum required: ${installer.getMinimumVersion()}`,
47
- installSuggestion: installer.getInstallInstructions()
48
- };
49
- }
50
-
51
- if (!map || !map.files) {
52
- return {
53
- success: false,
54
- error: 'Invalid repo map',
55
- needsFullRebuild: true
56
- };
57
- }
58
- map.stats = map.stats || {};
59
- if (!Array.isArray(map.stats.errors)) {
60
- map.stats.errors = [];
61
- }
62
- if (map.docs) {
63
- delete map.docs;
64
- }
65
-
66
- // Try git-based update first
67
- const gitInfo = runner.getGitInfo(basePath);
68
- if (!gitInfo || !map.git?.commit) {
69
- return updateWithoutGit(basePath, map, installed.command);
70
- }
71
-
72
- // Check if base commit exists
73
- if (!commitExists(basePath, map.git.commit)) {
74
- return {
75
- success: false,
76
- error: 'Base commit not found (history rewritten). Full rebuild required.',
77
- needsFullRebuild: true
78
- };
79
- }
80
-
81
- const diff = getGitDiff(basePath, map.git.commit);
82
- if (diff === null) {
83
- return updateWithoutGit(basePath, map, installed.command);
84
- }
85
-
86
- const changes = parseDiff(diff);
87
-
88
- // No changes - just update metadata
89
- if (changes.total === 0) {
90
- map.git = gitInfo;
91
- map.updated = new Date().toISOString();
92
- return {
93
- success: true,
94
- map,
95
- changes: { total: 0, updated: 0, added: 0, deleted: 0, renamed: 0 }
96
- };
97
- }
98
-
99
- // Apply deletions
100
- for (const file of changes.deleted) {
101
- delete map.files[file];
102
- delete map.dependencies[file];
103
- }
104
-
105
- // Apply renames
106
- for (const { from, to } of changes.renamed) {
107
- if (map.files[from]) {
108
- map.files[to] = map.files[from];
109
- delete map.files[from];
110
- }
111
- if (map.dependencies[from]) {
112
- map.dependencies[to] = map.dependencies[from];
113
- delete map.dependencies[from];
114
- }
115
- }
116
-
117
- // Apply added/modified - batch file existence checks
118
- const updatedFiles = [...changes.added, ...changes.modified];
119
- const fullPaths = updatedFiles.map(file => ({ file, fullPath: path.join(basePath, file) }));
120
-
121
- // Batch check file existence
122
- const existenceChecks = await Promise.all(
123
- fullPaths.map(async ({ file, fullPath }) => {
124
- try {
125
- await fsPromises.access(fullPath);
126
- return { file, fullPath, exists: true };
127
- } catch {
128
- return { file, fullPath, exists: false };
129
- }
130
- })
131
- );
132
-
133
- // Process files that exist with bounded concurrency
134
- const scanTargets = existenceChecks.filter(({ file, exists }) => exists && isScannableFile(file));
135
- const scanResults = await runWithConcurrency(scanTargets, SCAN_CONCURRENCY, async ({ file, fullPath }) => {
136
- const astErrors = [];
137
- const fileData = await runner.scanSingleFileAsync(installed.command, fullPath, basePath, {
138
- onError: (error) => astErrors.push(error)
139
- });
140
- return { file, fileData, astErrors };
141
- });
142
-
143
- const scanFailures = [];
144
- for (const result of scanResults) {
145
- if (!result) continue;
146
-
147
- if (result.astErrors.length > 0) {
148
- map.stats.errors.push(...result.astErrors);
149
- }
150
-
151
- if (!result.fileData) {
152
- if (result.astErrors.length > 0) {
153
- scanFailures.push(result.file);
154
- }
155
- continue;
156
- }
157
-
158
- map.files[result.file] = result.fileData;
159
- if (result.fileData.imports && result.fileData.imports.length > 0) {
160
- map.dependencies[result.file] = Array.from(new Set(result.fileData.imports.map(imp => imp.source)));
161
- } else {
162
- delete map.dependencies[result.file];
163
- }
164
- }
165
-
166
- if (scanFailures.length > 0) {
167
- return {
168
- success: false,
169
- error: `Failed to rescan ${scanFailures.length} file(s) during incremental update`,
170
- needsFullRebuild: true,
171
- failedFiles: scanFailures
172
- };
173
- }
174
-
175
- // Recalculate stats
176
- recalculateStats(map);
177
-
178
- // Update git metadata
179
- map.git = gitInfo;
180
- map.updated = new Date().toISOString();
181
-
182
- return {
183
- success: true,
184
- map,
185
- changes: {
186
- total: changes.total,
187
- updated: updatedFiles.length,
188
- added: changes.added.length,
189
- deleted: changes.deleted.length,
190
- renamed: changes.renamed.length
191
- }
192
- };
193
- }
194
15
 
195
16
  /**
196
- * Update without git (hash comparison)
197
- * @param {string} basePath - Repository root
198
- * @param {Object} map - Existing repo map
199
- * @param {string} cmd - ast-grep command
200
- * @returns {Promise<{success: boolean, map?: Object, changes?: Object}>}
201
- */
202
- async function updateWithoutGit(basePath, map, cmd) {
203
- const currentFiles = new Set();
204
- const languages = map.project?.languages || [];
205
- map.stats = map.stats || {};
206
- if (!Array.isArray(map.stats.errors)) {
207
- map.stats.errors = [];
208
- }
209
- if (map.docs) {
210
- delete map.docs;
211
- }
212
-
213
- for (const lang of languages) {
214
- const files = runner.findFilesForLanguage(basePath, lang);
215
- for (const file of files) {
216
- currentFiles.add(path.relative(basePath, file).replace(/\\/g, '/'));
217
- }
218
- }
219
-
220
- const changes = {
221
- added: [],
222
- modified: [],
223
- deleted: [],
224
- renamed: [],
225
- total: 0
226
- };
227
-
228
- // Collect existing files to check
229
- const existingFiles = Object.keys(map.files);
230
- const filesToCheck = [];
231
- const filesToDelete = [];
232
-
233
- for (const file of existingFiles) {
234
- if (!currentFiles.has(file)) {
235
- filesToDelete.push(file);
236
- } else {
237
- filesToCheck.push(file);
238
- currentFiles.delete(file);
239
- }
240
- }
241
-
242
- // Process deletions
243
- for (const file of filesToDelete) {
244
- changes.deleted.push(file);
245
- delete map.files[file];
246
- delete map.dependencies[file];
247
- }
248
-
249
- // Process existing files for modifications (async file reads)
250
- const checkResults = await runWithConcurrency(filesToCheck, SCAN_CONCURRENCY, async (file) => {
251
- const fullPath = path.join(basePath, file);
252
- const astErrors = [];
253
- const fileData = await runner.scanSingleFileAsync(cmd, fullPath, basePath, {
254
- onError: (error) => astErrors.push(error)
255
- });
256
- return { file, fileData, astErrors };
257
- });
258
-
259
- const scanFailures = [];
260
- for (const result of checkResults) {
261
- if (!result) continue;
262
-
263
- if (result.astErrors.length > 0) {
264
- map.stats.errors.push(...result.astErrors);
265
- }
266
-
267
- if (!result.fileData) {
268
- scanFailures.push(result.file);
269
- continue;
270
- }
271
-
272
- if (result.fileData.hash !== map.files[result.file].hash) {
273
- map.files[result.file] = result.fileData;
274
- if (result.fileData.imports && result.fileData.imports.length > 0) {
275
- map.dependencies[result.file] = Array.from(new Set(result.fileData.imports.map(imp => imp.source)));
276
- } else {
277
- delete map.dependencies[result.file];
278
- }
279
- changes.modified.push(result.file);
280
- }
281
- }
282
-
283
- // Process new files (async file reads)
284
- const addedFiles = Array.from(currentFiles);
285
- const addResults = await runWithConcurrency(addedFiles, SCAN_CONCURRENCY, async (file) => {
286
- const fullPath = path.join(basePath, file);
287
- const astErrors = [];
288
- const fileData = await runner.scanSingleFileAsync(cmd, fullPath, basePath, {
289
- onError: (error) => astErrors.push(error)
290
- });
291
- return { file, fileData, astErrors };
292
- });
293
-
294
- for (const result of addResults) {
295
- if (!result) continue;
296
-
297
- if (result.astErrors.length > 0) {
298
- map.stats.errors.push(...result.astErrors);
299
- }
300
-
301
- if (!result.fileData) {
302
- scanFailures.push(result.file);
303
- continue;
304
- }
305
-
306
- map.files[result.file] = result.fileData;
307
- if (result.fileData.imports && result.fileData.imports.length > 0) {
308
- map.dependencies[result.file] = Array.from(new Set(result.fileData.imports.map(imp => imp.source)));
309
- }
310
- changes.added.push(result.file);
311
- }
312
-
313
- if (scanFailures.length > 0) {
314
- return {
315
- success: false,
316
- error: `Failed to rescan ${scanFailures.length} file(s) during non-git update`,
317
- needsFullRebuild: true,
318
- failedFiles: scanFailures
319
- };
320
- }
321
-
322
- changes.total = changes.added.length + changes.modified.length + changes.deleted.length;
323
-
324
- recalculateStats(map);
325
- map.updated = new Date().toISOString();
326
-
327
- return {
328
- success: true,
329
- map,
330
- changes: {
331
- total: changes.total,
332
- updated: changes.modified.length,
333
- added: changes.added.length,
334
- deleted: changes.deleted.length,
335
- renamed: changes.renamed.length
336
- }
337
- };
338
- }
339
-
340
- /**
341
- * Check if repo-map is stale
342
- * @param {string} basePath - Repository root
343
- * @param {Object} map - Repo map
344
- * @returns {Object} Staleness info
17
+ * Check whether the cached map is stale
18
+ * @param {string} basePath - Repository root path
19
+ * @param {Object} map - Cached repo map
20
+ * @returns {{isStale: boolean, reason: string|null, commitsBehind: number, suggestFullRebuild: boolean}}
345
21
  */
346
22
  function checkStaleness(basePath, map) {
347
23
  const result = {
@@ -389,140 +65,35 @@ function checkStaleness(basePath, map) {
389
65
  return result;
390
66
  }
391
67
 
392
- /**
393
- * Parse git diff output
394
- * @param {string} diff - Git diff output
395
- * @returns {Object}
396
- */
397
- function parseDiff(diff) {
398
- const changes = {
399
- added: [],
400
- modified: [],
401
- deleted: [],
402
- renamed: [],
403
- total: 0
404
- };
405
-
406
- const lines = diff.split('\n').filter(Boolean);
407
- for (const line of lines) {
408
- const parts = line.split('\t');
409
- const status = parts[0];
410
-
411
- if (status.startsWith('R')) {
412
- const from = normalizePath(parts[1]);
413
- const to = normalizePath(parts[2]);
414
- changes.renamed.push({ from, to });
415
- const renameScore = Number(status.slice(1));
416
- if (!Number.isNaN(renameScore) && renameScore < 100 && to) {
417
- changes.modified.push(to);
418
- }
419
- continue;
420
- }
421
-
422
- const file = normalizePath(parts[1]);
423
- if (!file) continue;
424
-
425
- if (status === 'A') changes.added.push(file);
426
- else if (status === 'M') changes.modified.push(file);
427
- else if (status === 'D') changes.deleted.push(file);
428
-
429
- }
430
-
431
- changes.total = changes.added.length + changes.modified.length + changes.deleted.length + changes.renamed.length;
432
- return changes;
433
- }
434
-
435
- /**
436
- * Validate git commit hash format
437
- * @param {string} commit - Commit hash to validate
438
- * @returns {boolean} True if valid hex commit hash
439
- */
440
68
  function isValidCommitHash(commit) {
441
- // Git commit hashes are 4-40 hex characters (short to full SHA)
442
69
  return typeof commit === 'string' && /^[0-9a-fA-F]{4,40}$/.test(commit);
443
70
  }
444
71
 
445
- /**
446
- * Get git diff name-status
447
- * @param {string} basePath - Repository root
448
- * @param {string} sinceCommit - Base commit
449
- * @returns {string|null}
450
- */
451
- function getGitDiff(basePath, sinceCommit) {
452
- // Validate commit hash to prevent command injection
453
- if (!isValidCommitHash(sinceCommit)) {
454
- return null;
455
- }
456
- try {
457
- // Use execFileSync with arg array to prevent command injection
458
- return execFileSync('git', ['diff', '--name-status', '-M', sinceCommit, 'HEAD'], {
459
- cwd: basePath,
460
- encoding: 'utf8',
461
- stdio: ['pipe', 'pipe', 'pipe']
462
- }).trim();
463
- } catch {
464
- return null;
465
- }
466
- }
467
-
468
- /**
469
- * Check if commit exists
470
- * @param {string} basePath - Repository root
471
- * @param {string} commit - Commit hash
472
- * @returns {boolean}
473
- */
474
72
  function commitExists(basePath, commit) {
475
- // Validate commit hash to prevent command injection
476
- if (!isValidCommitHash(commit)) {
477
- return false;
478
- }
73
+ if (!isValidCommitHash(commit)) return false;
479
74
  try {
480
- // Use execFileSync with arg array to prevent command injection
481
- execFileSync('git', ['cat-file', '-e', commit], {
482
- cwd: basePath,
483
- stdio: ['pipe', 'pipe', 'pipe']
484
- });
75
+ execFileSync('git', ['cat-file', '-e', commit], { cwd: basePath, stdio: ['pipe', 'pipe', 'pipe'] });
485
76
  return true;
486
77
  } catch {
487
78
  return false;
488
79
  }
489
80
  }
490
81
 
491
- /**
492
- * Get current branch name
493
- * @param {string} basePath - Repository root
494
- * @returns {string|null}
495
- */
496
82
  function getCurrentBranch(basePath) {
497
83
  try {
498
- // Use execFileSync with arg array for consistency
499
84
  return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
500
- cwd: basePath,
501
- encoding: 'utf8',
502
- stdio: ['pipe', 'pipe', 'pipe']
85
+ cwd: basePath, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe']
503
86
  }).trim();
504
87
  } catch {
505
88
  return null;
506
89
  }
507
90
  }
508
91
 
509
- /**
510
- * Get number of commits behind HEAD
511
- * @param {string} basePath - Repository root
512
- * @param {string} commit - Base commit
513
- * @returns {number}
514
- */
515
92
  function getCommitsBehind(basePath, commit) {
516
- // Validate commit hash to prevent command injection
517
- if (!isValidCommitHash(commit)) {
518
- return 0;
519
- }
93
+ if (!isValidCommitHash(commit)) return 0;
520
94
  try {
521
- // Use execFileSync with arg array to prevent command injection
522
95
  const out = execFileSync('git', ['rev-list', `${commit}..HEAD`, '--count'], {
523
- cwd: basePath,
524
- encoding: 'utf8',
525
- stdio: ['pipe', 'pipe', 'pipe']
96
+ cwd: basePath, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe']
526
97
  }).trim();
527
98
  return Number(out) || 0;
528
99
  } catch {
@@ -530,33 +101,4 @@ function getCommitsBehind(basePath, commit) {
530
101
  }
531
102
  }
532
103
 
533
- /**
534
- * Normalize file path to forward slashes
535
- * @param {string} filePath - Path to normalize
536
- * @returns {string}
537
- */
538
- function normalizePath(filePath) {
539
- return filePath ? filePath.replace(/\\/g, '/') : filePath;
540
- }
541
-
542
- /**
543
- * Recalculate map stats
544
- * @param {Object} map - Repo map
545
- */
546
- function recalculateStats(map) {
547
- const files = Object.values(map.files || {});
548
- map.stats.totalFiles = files.length;
549
- map.stats.totalSymbols = files.reduce((sum, file) => {
550
- return sum +
551
- (file.symbols?.functions?.length || 0) +
552
- (file.symbols?.classes?.length || 0) +
553
- (file.symbols?.types?.length || 0) +
554
- (file.symbols?.constants?.length || 0);
555
- }, 0);
556
- }
557
-
558
- module.exports = {
559
- incrementalUpdate,
560
- updateWithoutGit,
561
- checkStaleness
562
- };
104
+ module.exports = { checkStaleness };
@@ -493,7 +493,7 @@ If pushing version tag (v*):
493
493
  **installForClaude()** - Line 116
494
494
  - Adds marketplace: `claude plugin marketplace add agent-sh/agentsys`
495
495
  - Installs 9 plugins: `claude plugin install {plugin}@agentsys`
496
- - Commands: /next-task, /ship, /deslop, /audit-project, /drift-detect, /enhance, /perf, /sync-docs, /repo-map
496
+ - Commands: /next-task, /ship, /deslop, /audit-project, /drift-detect, /enhance, /perf, /sync-docs, /repo-intel
497
497
 
498
498
  **installForOpenCode(installDir, options)** - Line 165
499
499
  - Creates dirs: `~/.config/opencode/commands/`, `~/.config/opencode/plugins/agentsys.ts`
@@ -520,7 +520,7 @@ const commandMappings = [
520
520
  ['sync-docs.md', 'sync-docs', 'sync-docs.md'],
521
521
  ['audit-project.md', 'audit-project', 'audit-project.md'],
522
522
  ['drift-detect.md', 'drift-detect', 'drift-detect.md'],
523
- ['repo-map.md', 'repo-map', 'repo-map.md'],
523
+ ['repo-intel.md', 'repo-intel', 'repo-intel.md'],
524
524
  ['perf.md', 'perf', 'perf.md'],
525
525
  ['ship.md', 'ship', 'ship.md']
526
526
  ];
@@ -933,7 +933,7 @@ If you find any of these while working:
933
933
  5. audit-project
934
934
  6. deslop
935
935
  7. drift-detect
936
- 8. repo-map
936
+ 8. repo-intel
937
937
  9. sync-docs
938
938
 
939
939
  **Agents:** 39 total = 29 file-based + 10 role-based
@@ -943,7 +943,7 @@ If you find any of these while working:
943
943
  - enhance: 9
944
944
  - perf: 6
945
945
  - drift-detect: 1
946
- - repo-map: 1
946
+ - repo-intel: 1
947
947
 
948
948
  **Role-based (10):** Defined inline in audit-project command
949
949
  - code-quality-reviewer, security-expert, performance-engineer, test-quality-guardian
@@ -951,11 +951,12 @@ If you find any of these while working:
951
951
  - frontend-specialist, backend-specialist, devops-reviewer
952
952
 
953
953
  **Skills:** 23 - Count SKILL.md in `plugins/*/skills/*/SKILL.md`
954
- - next-task: 4 (orchestrate-review, discover-tasks, validate-delivery, update-docs)
954
+ - next-task: 1 (discover-tasks)
955
+ - prepare-delivery: 4 (prepare-delivery, check-test-coverage, orchestrate-review, validate-delivery)
955
956
  - enhance: 10 (orchestrator, reporter, agent-prompts, claude-memory, docs, plugins, prompts, hooks, skills)
956
957
  - perf: 8 (analyzer, baseline, benchmark, code-paths, investigation-logger, profile, theory, theory-tester)
957
958
  - drift-detect: 1 (drift-analysis)
958
- - repo-map: 1 (repo-mapping)
959
+ - repo-intel: 1 (repo-intel)
959
960
 
960
961
  **Version Fields:** 11 files
961
962
  - 1x package.json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentsys",
3
- "version": "5.6.4",
3
+ "version": "5.8.0",
4
4
  "description": "A modular runtime and orchestration system for AI agents - works with Claude Code, OpenCode, and Codex CLI",
5
5
  "main": "lib/platform/detect-platform.js",
6
6
  "type": "commonjs",
@@ -64,8 +64,8 @@
64
64
  "cli",
65
65
  "pr-automation",
66
66
  "productivity",
67
- "repo-map",
68
- "ast-grep",
67
+ "repo-intel",
68
+ "static-analysis",
69
69
  "drift-detect"
70
70
  ],
71
71
  "author": {
@@ -26,14 +26,14 @@ const WORK_DIR = '/tmp/fix-repos';
26
26
  // 12 graduated plugins (agnix excluded — it stays in monorepo)
27
27
  const PLUGINS = [
28
28
  'next-task', 'ship', 'enhance', 'deslop', 'learn', 'consult',
29
- 'debate', 'drift-detect', 'repo-map', 'sync-docs', 'audit-project',
29
+ 'debate', 'drift-detect', 'repo-intel', 'sync-docs', 'audit-project',
30
30
  'perf'
31
31
  ];
32
32
 
33
33
  // All 13 plugin dir names that may exist in the repos
34
34
  const ALL_PLUGIN_DIRS = [
35
35
  'next-task', 'ship', 'enhance', 'deslop', 'learn', 'consult',
36
- 'debate', 'drift-detect', 'repo-map', 'sync-docs', 'audit-project',
36
+ 'debate', 'drift-detect', 'repo-intel', 'sync-docs', 'audit-project',
37
37
  'perf', 'agnix'
38
38
  ];
39
39