cap-pro 1.0.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 (275) hide show
  1. package/.claude-plugin/README.md +26 -0
  2. package/.claude-plugin/marketplace.json +24 -0
  3. package/.claude-plugin/plugin.json +24 -0
  4. package/LICENSE +21 -0
  5. package/README.ja-JP.md +834 -0
  6. package/README.ko-KR.md +823 -0
  7. package/README.md +806 -0
  8. package/README.pt-BR.md +452 -0
  9. package/README.zh-CN.md +800 -0
  10. package/agents/cap-architect.md +269 -0
  11. package/agents/cap-brainstormer.md +207 -0
  12. package/agents/cap-curator.md +276 -0
  13. package/agents/cap-debugger.md +365 -0
  14. package/agents/cap-designer.md +246 -0
  15. package/agents/cap-historian.md +464 -0
  16. package/agents/cap-migrator.md +291 -0
  17. package/agents/cap-prototyper.md +197 -0
  18. package/agents/cap-validator.md +308 -0
  19. package/bin/install.js +5433 -0
  20. package/cap/bin/cap-tools.cjs +853 -0
  21. package/cap/bin/lib/arc-scanner.cjs +344 -0
  22. package/cap/bin/lib/cap-affinity-engine.cjs +862 -0
  23. package/cap/bin/lib/cap-anchor.cjs +228 -0
  24. package/cap/bin/lib/cap-annotation-writer.cjs +340 -0
  25. package/cap/bin/lib/cap-checkpoint.cjs +434 -0
  26. package/cap/bin/lib/cap-cluster-detect.cjs +945 -0
  27. package/cap/bin/lib/cap-cluster-display.cjs +52 -0
  28. package/cap/bin/lib/cap-cluster-format.cjs +245 -0
  29. package/cap/bin/lib/cap-cluster-helpers.cjs +295 -0
  30. package/cap/bin/lib/cap-cluster-io.cjs +212 -0
  31. package/cap/bin/lib/cap-completeness.cjs +540 -0
  32. package/cap/bin/lib/cap-deps.cjs +583 -0
  33. package/cap/bin/lib/cap-design-families.cjs +332 -0
  34. package/cap/bin/lib/cap-design.cjs +966 -0
  35. package/cap/bin/lib/cap-divergence-detector.cjs +400 -0
  36. package/cap/bin/lib/cap-doctor.cjs +752 -0
  37. package/cap/bin/lib/cap-feature-map-internals.cjs +19 -0
  38. package/cap/bin/lib/cap-feature-map-migrate.cjs +335 -0
  39. package/cap/bin/lib/cap-feature-map-monorepo.cjs +885 -0
  40. package/cap/bin/lib/cap-feature-map-shard.cjs +315 -0
  41. package/cap/bin/lib/cap-feature-map.cjs +1943 -0
  42. package/cap/bin/lib/cap-fitness-score.cjs +1075 -0
  43. package/cap/bin/lib/cap-impact-analysis.cjs +652 -0
  44. package/cap/bin/lib/cap-learn-review.cjs +1072 -0
  45. package/cap/bin/lib/cap-learning-signals.cjs +627 -0
  46. package/cap/bin/lib/cap-loader.cjs +227 -0
  47. package/cap/bin/lib/cap-logger.cjs +57 -0
  48. package/cap/bin/lib/cap-memory-bridge.cjs +764 -0
  49. package/cap/bin/lib/cap-memory-confidence.cjs +452 -0
  50. package/cap/bin/lib/cap-memory-dir.cjs +987 -0
  51. package/cap/bin/lib/cap-memory-engine.cjs +698 -0
  52. package/cap/bin/lib/cap-memory-extends.cjs +398 -0
  53. package/cap/bin/lib/cap-memory-graph.cjs +790 -0
  54. package/cap/bin/lib/cap-memory-migrate.cjs +2015 -0
  55. package/cap/bin/lib/cap-memory-pin.cjs +183 -0
  56. package/cap/bin/lib/cap-memory-platform.cjs +490 -0
  57. package/cap/bin/lib/cap-memory-prune.cjs +707 -0
  58. package/cap/bin/lib/cap-memory-schema.cjs +812 -0
  59. package/cap/bin/lib/cap-migrate-tags.cjs +309 -0
  60. package/cap/bin/lib/cap-migrate.cjs +540 -0
  61. package/cap/bin/lib/cap-pattern-apply.cjs +1203 -0
  62. package/cap/bin/lib/cap-pattern-pipeline.cjs +1034 -0
  63. package/cap/bin/lib/cap-plugin-manifest.cjs +80 -0
  64. package/cap/bin/lib/cap-realtime-affinity.cjs +399 -0
  65. package/cap/bin/lib/cap-reconcile.cjs +570 -0
  66. package/cap/bin/lib/cap-research-gate.cjs +218 -0
  67. package/cap/bin/lib/cap-scope-filter.cjs +402 -0
  68. package/cap/bin/lib/cap-semantic-pipeline.cjs +1038 -0
  69. package/cap/bin/lib/cap-session-extract.cjs +987 -0
  70. package/cap/bin/lib/cap-session.cjs +445 -0
  71. package/cap/bin/lib/cap-snapshot-linkage.cjs +963 -0
  72. package/cap/bin/lib/cap-stack-docs.cjs +646 -0
  73. package/cap/bin/lib/cap-tag-observer.cjs +371 -0
  74. package/cap/bin/lib/cap-tag-scanner.cjs +1766 -0
  75. package/cap/bin/lib/cap-telemetry.cjs +466 -0
  76. package/cap/bin/lib/cap-test-audit.cjs +1438 -0
  77. package/cap/bin/lib/cap-thread-migrator.cjs +307 -0
  78. package/cap/bin/lib/cap-thread-synthesis.cjs +545 -0
  79. package/cap/bin/lib/cap-thread-tracker.cjs +519 -0
  80. package/cap/bin/lib/cap-trace.cjs +399 -0
  81. package/cap/bin/lib/cap-trust-mode.cjs +336 -0
  82. package/cap/bin/lib/cap-ui-design-editor.cjs +642 -0
  83. package/cap/bin/lib/cap-ui-mind-map.cjs +712 -0
  84. package/cap/bin/lib/cap-ui-thread-nav.cjs +693 -0
  85. package/cap/bin/lib/cap-ui.cjs +1245 -0
  86. package/cap/bin/lib/cap-upgrade.cjs +1028 -0
  87. package/cap/bin/lib/cli/arg-helpers.cjs +49 -0
  88. package/cap/bin/lib/cli/frontmatter-router.cjs +31 -0
  89. package/cap/bin/lib/cli/init-router.cjs +68 -0
  90. package/cap/bin/lib/cli/phase-router.cjs +102 -0
  91. package/cap/bin/lib/cli/state-router.cjs +61 -0
  92. package/cap/bin/lib/cli/template-router.cjs +37 -0
  93. package/cap/bin/lib/cli/uat-router.cjs +29 -0
  94. package/cap/bin/lib/cli/validation-router.cjs +26 -0
  95. package/cap/bin/lib/cli/verification-router.cjs +31 -0
  96. package/cap/bin/lib/cli/workstream-router.cjs +39 -0
  97. package/cap/bin/lib/commands.cjs +961 -0
  98. package/cap/bin/lib/config.cjs +467 -0
  99. package/cap/bin/lib/convention-reader.cjs +258 -0
  100. package/cap/bin/lib/core.cjs +1241 -0
  101. package/cap/bin/lib/feature-aggregator.cjs +423 -0
  102. package/cap/bin/lib/frontmatter.cjs +337 -0
  103. package/cap/bin/lib/init.cjs +1443 -0
  104. package/cap/bin/lib/manifest-generator.cjs +383 -0
  105. package/cap/bin/lib/milestone.cjs +253 -0
  106. package/cap/bin/lib/model-profiles.cjs +69 -0
  107. package/cap/bin/lib/monorepo-context.cjs +226 -0
  108. package/cap/bin/lib/monorepo-migrator.cjs +509 -0
  109. package/cap/bin/lib/phase.cjs +889 -0
  110. package/cap/bin/lib/profile-output.cjs +989 -0
  111. package/cap/bin/lib/profile-pipeline.cjs +540 -0
  112. package/cap/bin/lib/roadmap.cjs +330 -0
  113. package/cap/bin/lib/security.cjs +394 -0
  114. package/cap/bin/lib/session-manager.cjs +292 -0
  115. package/cap/bin/lib/skeleton-generator.cjs +179 -0
  116. package/cap/bin/lib/state.cjs +1032 -0
  117. package/cap/bin/lib/template.cjs +231 -0
  118. package/cap/bin/lib/test-detector.cjs +62 -0
  119. package/cap/bin/lib/uat.cjs +283 -0
  120. package/cap/bin/lib/verify.cjs +889 -0
  121. package/cap/bin/lib/workspace-detector.cjs +371 -0
  122. package/cap/bin/lib/workstream.cjs +492 -0
  123. package/cap/commands/gsd/workstreams.md +63 -0
  124. package/cap/references/arc-standard.md +315 -0
  125. package/cap/references/cap-agent-architecture.md +101 -0
  126. package/cap/references/cap-gitignore-template +9 -0
  127. package/cap/references/cap-zero-deps.md +158 -0
  128. package/cap/references/checkpoints.md +778 -0
  129. package/cap/references/continuation-format.md +249 -0
  130. package/cap/references/contract-test-templates.md +312 -0
  131. package/cap/references/feature-map-template.md +25 -0
  132. package/cap/references/git-integration.md +295 -0
  133. package/cap/references/git-planning-commit.md +38 -0
  134. package/cap/references/model-profiles.md +174 -0
  135. package/cap/references/phase-numbering.md +126 -0
  136. package/cap/references/planning-config.md +202 -0
  137. package/cap/references/property-test-templates.md +316 -0
  138. package/cap/references/security-test-templates.md +347 -0
  139. package/cap/references/session-template.json +8 -0
  140. package/cap/references/tdd.md +263 -0
  141. package/cap/references/user-profiling.md +681 -0
  142. package/cap/references/verification-patterns.md +612 -0
  143. package/cap/templates/UAT.md +265 -0
  144. package/cap/templates/claude-md.md +175 -0
  145. package/cap/templates/codebase/architecture.md +255 -0
  146. package/cap/templates/codebase/concerns.md +310 -0
  147. package/cap/templates/codebase/conventions.md +307 -0
  148. package/cap/templates/codebase/integrations.md +280 -0
  149. package/cap/templates/codebase/stack.md +186 -0
  150. package/cap/templates/codebase/structure.md +285 -0
  151. package/cap/templates/codebase/testing.md +480 -0
  152. package/cap/templates/config.json +44 -0
  153. package/cap/templates/context.md +352 -0
  154. package/cap/templates/continue-here.md +78 -0
  155. package/cap/templates/copilot-instructions.md +7 -0
  156. package/cap/templates/debug-subagent-prompt.md +91 -0
  157. package/cap/templates/discussion-log.md +63 -0
  158. package/cap/templates/milestone-archive.md +123 -0
  159. package/cap/templates/milestone.md +115 -0
  160. package/cap/templates/phase-prompt.md +610 -0
  161. package/cap/templates/planner-subagent-prompt.md +117 -0
  162. package/cap/templates/project.md +186 -0
  163. package/cap/templates/requirements.md +231 -0
  164. package/cap/templates/research-project/ARCHITECTURE.md +204 -0
  165. package/cap/templates/research-project/FEATURES.md +147 -0
  166. package/cap/templates/research-project/PITFALLS.md +200 -0
  167. package/cap/templates/research-project/STACK.md +120 -0
  168. package/cap/templates/research-project/SUMMARY.md +170 -0
  169. package/cap/templates/research.md +552 -0
  170. package/cap/templates/roadmap.md +202 -0
  171. package/cap/templates/state.md +176 -0
  172. package/cap/templates/summary.md +364 -0
  173. package/cap/templates/user-preferences.md +498 -0
  174. package/cap/templates/verification-report.md +322 -0
  175. package/cap/workflows/add-phase.md +112 -0
  176. package/cap/workflows/add-tests.md +351 -0
  177. package/cap/workflows/add-todo.md +158 -0
  178. package/cap/workflows/audit-milestone.md +340 -0
  179. package/cap/workflows/audit-uat.md +109 -0
  180. package/cap/workflows/autonomous.md +891 -0
  181. package/cap/workflows/check-todos.md +177 -0
  182. package/cap/workflows/cleanup.md +152 -0
  183. package/cap/workflows/complete-milestone.md +767 -0
  184. package/cap/workflows/diagnose-issues.md +231 -0
  185. package/cap/workflows/discovery-phase.md +289 -0
  186. package/cap/workflows/discuss-phase-assumptions.md +653 -0
  187. package/cap/workflows/discuss-phase.md +1049 -0
  188. package/cap/workflows/do.md +104 -0
  189. package/cap/workflows/execute-phase.md +846 -0
  190. package/cap/workflows/execute-plan.md +514 -0
  191. package/cap/workflows/fast.md +105 -0
  192. package/cap/workflows/forensics.md +265 -0
  193. package/cap/workflows/health.md +181 -0
  194. package/cap/workflows/help.md +660 -0
  195. package/cap/workflows/insert-phase.md +130 -0
  196. package/cap/workflows/list-phase-assumptions.md +178 -0
  197. package/cap/workflows/list-workspaces.md +56 -0
  198. package/cap/workflows/manager.md +362 -0
  199. package/cap/workflows/map-codebase.md +377 -0
  200. package/cap/workflows/milestone-summary.md +223 -0
  201. package/cap/workflows/new-milestone.md +486 -0
  202. package/cap/workflows/new-project.md +1250 -0
  203. package/cap/workflows/new-workspace.md +237 -0
  204. package/cap/workflows/next.md +97 -0
  205. package/cap/workflows/node-repair.md +92 -0
  206. package/cap/workflows/note.md +156 -0
  207. package/cap/workflows/pause-work.md +176 -0
  208. package/cap/workflows/plan-milestone-gaps.md +273 -0
  209. package/cap/workflows/plan-phase.md +857 -0
  210. package/cap/workflows/plant-seed.md +169 -0
  211. package/cap/workflows/pr-branch.md +129 -0
  212. package/cap/workflows/profile-user.md +449 -0
  213. package/cap/workflows/progress.md +507 -0
  214. package/cap/workflows/quick.md +757 -0
  215. package/cap/workflows/remove-phase.md +155 -0
  216. package/cap/workflows/remove-workspace.md +90 -0
  217. package/cap/workflows/research-phase.md +82 -0
  218. package/cap/workflows/resume-project.md +326 -0
  219. package/cap/workflows/review.md +228 -0
  220. package/cap/workflows/session-report.md +146 -0
  221. package/cap/workflows/settings.md +283 -0
  222. package/cap/workflows/ship.md +228 -0
  223. package/cap/workflows/stats.md +60 -0
  224. package/cap/workflows/transition.md +671 -0
  225. package/cap/workflows/ui-phase.md +298 -0
  226. package/cap/workflows/ui-review.md +161 -0
  227. package/cap/workflows/update.md +323 -0
  228. package/cap/workflows/validate-phase.md +170 -0
  229. package/cap/workflows/verify-phase.md +254 -0
  230. package/cap/workflows/verify-work.md +637 -0
  231. package/commands/cap/annotate.md +165 -0
  232. package/commands/cap/brainstorm.md +393 -0
  233. package/commands/cap/checkpoint.md +106 -0
  234. package/commands/cap/completeness.md +94 -0
  235. package/commands/cap/continue.md +72 -0
  236. package/commands/cap/debug.md +588 -0
  237. package/commands/cap/deps.md +169 -0
  238. package/commands/cap/design.md +479 -0
  239. package/commands/cap/init.md +354 -0
  240. package/commands/cap/iterate.md +249 -0
  241. package/commands/cap/learn.md +459 -0
  242. package/commands/cap/memory.md +275 -0
  243. package/commands/cap/migrate-feature-map.md +91 -0
  244. package/commands/cap/migrate-memory.md +108 -0
  245. package/commands/cap/migrate-tags.md +91 -0
  246. package/commands/cap/migrate.md +131 -0
  247. package/commands/cap/prototype.md +510 -0
  248. package/commands/cap/reconcile.md +121 -0
  249. package/commands/cap/review.md +360 -0
  250. package/commands/cap/save.md +72 -0
  251. package/commands/cap/scan.md +404 -0
  252. package/commands/cap/start.md +356 -0
  253. package/commands/cap/status.md +118 -0
  254. package/commands/cap/test-audit.md +262 -0
  255. package/commands/cap/test.md +394 -0
  256. package/commands/cap/trace.md +133 -0
  257. package/commands/cap/ui.md +167 -0
  258. package/hooks/dist/cap-check-update.js +115 -0
  259. package/hooks/dist/cap-context-monitor.js +185 -0
  260. package/hooks/dist/cap-learn-review-hook.js +114 -0
  261. package/hooks/dist/cap-learning-hook.js +192 -0
  262. package/hooks/dist/cap-memory.js +299 -0
  263. package/hooks/dist/cap-prompt-guard.js +97 -0
  264. package/hooks/dist/cap-statusline.js +157 -0
  265. package/hooks/dist/cap-tag-observer.js +115 -0
  266. package/hooks/dist/cap-version-check.js +112 -0
  267. package/hooks/dist/cap-workflow-guard.js +175 -0
  268. package/hooks/hooks.json +55 -0
  269. package/package.json +58 -0
  270. package/scripts/base64-scan.sh +262 -0
  271. package/scripts/build-hooks.js +93 -0
  272. package/scripts/cap-removal-checklist.md +202 -0
  273. package/scripts/prompt-injection-scan.sh +199 -0
  274. package/scripts/run-tests.cjs +181 -0
  275. package/scripts/secret-scan.sh +227 -0
@@ -0,0 +1,404 @@
1
+ ---
2
+ name: cap:scan
3
+ description: "Scan codebase for @cap-feature and @cap-todo tags with monorepo support. Traverses all workspace packages, updates Feature Map, reports coverage gaps."
4
+ argument-hint: "[--features NAME] [--json] [--monorepo] [--strict] [--include=<glob>] [--exclude=<glob>]"
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ - Glob
10
+ - Grep
11
+ ---
12
+
13
+ <!-- @cap-context CAP v2.0 scan command (final pass) -- adds monorepo workspace traversal and cross-package file references to the base scan flow. -->
14
+ <!-- @cap-decision Monorepo detection is automatic -- checks package.json workspaces field and lerna.json. No --monorepo flag required (AC-80). -->
15
+ <!-- @cap-decision Cross-package file references use full relative paths from project root (e.g., packages/core/src/auth.ts) to avoid ambiguity (AC-79). -->
16
+ <!-- @cap-constraint Works seamlessly with normal single-repo projects -- monorepo features are additive, not blocking (AC-80). -->
17
+ <!-- @cap-feature(feature:F-085) Scope filter — gitignore-aware, plugin-mirror-aware, with --include/--exclude glob overrides. Shared with cap-migrate-tags via cap-scope-filter.cjs. -->
18
+
19
+ <!-- @cap-todo(ref:AC-78) /cap:scan shall traverse all packages in a monorepo -->
20
+ <!-- @cap-todo(ref:AC-79) Feature Map entries shall support cross-package file references -->
21
+ <!-- @cap-todo(ref:AC-80) CAP shall work seamlessly with normal single-repo projects with no monorepo-specific configuration required -->
22
+ <!-- @cap-feature(feature:F-046) Polylingual tag context detection: --strict flag fails the scan if any @cap-* token is found outside a recognized comment context. -->
23
+ <!-- @cap-todo(ac:F-046/AC-4) /cap:scan --strict invokes scanner.scanDirectoryWithContext with strict:true for CI enforcement. -->
24
+
25
+ <objective>
26
+ Scans the codebase for @cap-feature and @cap-todo tags. In monorepo projects, automatically detects and traverses all workspace packages. Cross-references against FEATURE-MAP.md, flags orphan tags, and auto-enriches Feature Map with discovered file references.
27
+
28
+ **Monorepo support:**
29
+ - Automatically detects npm/yarn/pnpm workspaces from package.json `workspaces` field
30
+ - Detects Lerna monorepos from lerna.json
31
+ - Traverses all workspace packages independently
32
+ - File references use full paths from project root (e.g., `packages/core/src/auth.ts`)
33
+
34
+ **Polylingual context detection (F-046):**
35
+ - The scanner now classifies each `@cap-*` match against the file's comment syntax (per extension).
36
+ - Tokens found outside any recognized comment (e.g. inside a string literal) are NOT parsed as tags but are reported as warnings.
37
+ - Supported comment styles: `//`, `/* */` (JS/TS/Go/Rust/C/Java/CSS/SCSS), `#` (Python/Ruby/Shell/YAML/TOML), `"""`/`'''` (Python triple-quote), `=begin`/`=end` (Ruby), `///` (Rust doc), `<!-- -->` (HTML/Markdown), `--` (SQL).
38
+
39
+ **Scope filter (F-085):** the scan respects the project's top-level `.gitignore` and an opinionated default-exclude list. By default it skips:
40
+
41
+ - everything matched by `.gitignore` (typically `.claude/`, `node_modules/`, `dist/`, `coverage/`, build caches);
42
+ - agent worktrees under `.claude/worktrees/`;
43
+ - the plugin-self-mirror at `.claude/cap/` (detected when both `bin/` and `commands/` are present);
44
+ - test fixtures under `tests/fixtures/` and `**/fixtures/polyglot/` — fixtures are intentionally raw-tagged.
45
+
46
+ The same scope filter is shared with `cap:migrate-tags` so the two tools never disagree about which files are in scope.
47
+
48
+ **Arguments:**
49
+ - `--features NAME` -- scope scan to specific Feature Map entries (comma-separated)
50
+ - `--json` -- output raw scan results as JSON instead of formatted report
51
+ - `--strict` -- (F-046/AC-4) fail the scan with a non-zero exit code if ANY `@cap-*` token is found outside a recognized comment. Intended for CI enforcement.
52
+ - `--include=<glob>` -- restrict the scan to paths matching the pattern (additive, repeatable).
53
+ - `--exclude=<glob>` -- additionally skip paths matching the pattern (additive, repeatable).
54
+ </objective>
55
+
56
+ <context>
57
+ $ARGUMENTS
58
+
59
+ @FEATURE-MAP.md
60
+ </context>
61
+
62
+ <process>
63
+
64
+ ## Step 0: Parse flags
65
+
66
+ Check `$ARGUMENTS` for:
67
+ - `--features NAME` -- if present, store as `feature_filter`
68
+ - `--json` -- if present, set `json_output = true`
69
+ - `--strict` -- if present, set `strict_mode = true` (F-046/AC-4)
70
+
71
+ ## Step 0b: Check active app scoping
72
+
73
+ ```bash
74
+ node -e "
75
+ const session = require('./cap/bin/lib/cap-session.cjs');
76
+ const s = session.loadSession(process.cwd());
77
+ console.log(JSON.stringify({ activeApp: s.activeApp }));
78
+ "
79
+ ```
80
+
81
+ Store as `app_scope`. If `app_scope.activeApp` is set, this scan will be scoped to the active app directory and its shared packages. The results will be written to the app's FEATURE-MAP.md (not root).
82
+
83
+ ## Step 1: Detect monorepo configuration
84
+
85
+ <!-- @cap-decision Monorepo detection reads package.json workspaces and lerna.json. Supports npm, yarn, pnpm workspace patterns. Glob expansion uses Bash for simplicity. -->
86
+
87
+ ```bash
88
+ node -e "
89
+ const fs = require('node:fs');
90
+ const path = require('node:path');
91
+ const pkgPath = path.join(process.cwd(), 'package.json');
92
+ const lernaPath = path.join(process.cwd(), 'lerna.json');
93
+ const result = { isMonorepo: false, workspaces: [], packages: [] };
94
+
95
+ // Check package.json workspaces
96
+ if (fs.existsSync(pkgPath)) {
97
+ try {
98
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
99
+ if (pkg.workspaces) {
100
+ result.isMonorepo = true;
101
+ result.workspaces = Array.isArray(pkg.workspaces)
102
+ ? pkg.workspaces
103
+ : (pkg.workspaces.packages || []);
104
+ }
105
+ } catch (_e) {}
106
+ }
107
+
108
+ // Check pnpm-workspace.yaml
109
+ const pnpmPath = path.join(process.cwd(), 'pnpm-workspace.yaml');
110
+ if (!result.isMonorepo && fs.existsSync(pnpmPath)) {
111
+ try {
112
+ const content = fs.readFileSync(pnpmPath, 'utf8');
113
+ const packagesMatch = content.match(/packages:\\s*\\n((?:\\s+-\\s*.+\\n?)*)/);
114
+ if (packagesMatch) {
115
+ result.isMonorepo = true;
116
+ result.workspaces = packagesMatch[1]
117
+ .split('\\n')
118
+ .map(line => line.replace(/^\\s*-\\s*['\"]?/, '').replace(/['\"]?\\s*$/, ''))
119
+ .filter(Boolean);
120
+ }
121
+ } catch (_e) {}
122
+ }
123
+
124
+ // Check nx.json
125
+ const nxPath = path.join(process.cwd(), 'nx.json');
126
+ if (!result.isMonorepo && fs.existsSync(nxPath)) {
127
+ try {
128
+ const nx = JSON.parse(fs.readFileSync(nxPath, 'utf8'));
129
+ result.isMonorepo = true;
130
+ const layout = nx.workspaceLayout || {};
131
+ const patterns = [];
132
+ if (layout.appsDir) patterns.push(layout.appsDir + '/*');
133
+ if (layout.libsDir) patterns.push(layout.libsDir + '/*');
134
+ if (patterns.length === 0) {
135
+ for (const dir of ['apps', 'packages', 'libs']) {
136
+ if (fs.existsSync(path.join(process.cwd(), dir))) {
137
+ patterns.push(dir + '/*');
138
+ }
139
+ }
140
+ }
141
+ result.workspaces = patterns;
142
+ } catch (_e) {}
143
+ }
144
+
145
+ // Check lerna.json
146
+ if (!result.isMonorepo && fs.existsSync(lernaPath)) {
147
+ try {
148
+ const lerna = JSON.parse(fs.readFileSync(lernaPath, 'utf8'));
149
+ result.isMonorepo = true;
150
+ result.workspaces = lerna.packages || ['packages/*'];
151
+ } catch (_e) {}
152
+ }
153
+
154
+ // Resolve workspace globs to actual package directories
155
+ if (result.isMonorepo) {
156
+ for (const ws of result.workspaces) {
157
+ const wsBase = ws.replace('/*', '').replace('/**', '');
158
+ const wsDir = path.join(process.cwd(), wsBase);
159
+ if (fs.existsSync(wsDir) && fs.statSync(wsDir).isDirectory()) {
160
+ const entries = fs.readdirSync(wsDir, { withFileTypes: true });
161
+ for (const entry of entries) {
162
+ if (entry.isDirectory()) {
163
+ const pkgJsonPath = path.join(wsDir, entry.name, 'package.json');
164
+ if (fs.existsSync(pkgJsonPath)) {
165
+ result.packages.push(path.join(wsBase, entry.name));
166
+ }
167
+ }
168
+ }
169
+ }
170
+ }
171
+ }
172
+
173
+ console.log(JSON.stringify(result, null, 2));
174
+ "
175
+ ```
176
+
177
+ Store as `monorepo_info`. Log project type:
178
+ - Monorepo: "Detected monorepo with {N} workspace packages: {list}"
179
+ - Single repo: "Single repository project detected."
180
+
181
+ ## Step 2: Run tag scanner (with monorepo and app-scoping awareness)
182
+
183
+ **If `app_scope.activeApp` is set (app-scoped scan):**
184
+
185
+ Scan only the active app directory and its referenced shared packages:
186
+
187
+ ```bash
188
+ node -e "
189
+ const scanner = require('./cap/bin/lib/cap-tag-scanner.cjs');
190
+ const projectRoot = process.cwd();
191
+ const appPath = process.argv[1];
192
+ const result = scanner.scanApp(projectRoot, appPath);
193
+ console.log(JSON.stringify({ tags: result.tags, scannedDirs: result.scannedDirs }, null, 2));
194
+ " '<ACTIVE_APP_PATH>'
195
+ ```
196
+
197
+ Log: "App-scoped scan: {activeApp} (+ {N} shared packages)"
198
+
199
+ **Else if monorepo detected (full monorepo scan):**
200
+
201
+ Scan each workspace package independently AND the root:
202
+
203
+ ```bash
204
+ node -e "
205
+ const scanner = require('./cap/bin/lib/cap-tag-scanner.cjs');
206
+ const fs = require('node:fs');
207
+ const path = require('node:path');
208
+
209
+ const monorepoInfo = JSON.parse(process.argv[1]);
210
+ const projectRoot = process.cwd();
211
+
212
+ if (monorepoInfo.isMonorepo) {
213
+ // Scan root first
214
+ const rootTags = scanner.scanDirectory(projectRoot, { projectRoot });
215
+ const allTags = [...rootTags];
216
+
217
+ // Scan each workspace package
218
+ for (const pkg of monorepoInfo.packages) {
219
+ const pkgDir = path.join(projectRoot, pkg);
220
+ if (fs.existsSync(pkgDir)) {
221
+ const pkgTags = scanner.scanDirectory(pkgDir, { projectRoot });
222
+ allTags.push(...pkgTags);
223
+ }
224
+ }
225
+
226
+ // Deduplicate by file+line
227
+ const seen = new Set();
228
+ const deduped = allTags.filter(t => {
229
+ const key = t.file + ':' + t.line;
230
+ if (seen.has(key)) return false;
231
+ seen.add(key);
232
+ return true;
233
+ });
234
+
235
+ console.log(JSON.stringify(deduped, null, 2));
236
+ } else {
237
+ const tags = scanner.scanDirectory(projectRoot);
238
+ console.log(JSON.stringify(tags, null, 2));
239
+ }
240
+ " '<MONOREPO_INFO_JSON>'
241
+ ```
242
+
243
+ **Else (single repo):**
244
+
245
+ Standard scan as before.
246
+
247
+ Store as `all_tags`.
248
+
249
+ ## Step 2b: Polylingual context check (only when `--strict` is set)
250
+
251
+ <!-- @cap-decision When --strict is set, run the polylingual scanner in strict mode. It throws on any @cap-* token outside a recognized comment (string literal, code reference). Intended for CI enforcement (F-046/AC-4). -->
252
+
253
+ If `strict_mode === true`:
254
+
255
+ ```bash
256
+ node -e "
257
+ const scanner = require('./cap/bin/lib/cap-tag-scanner.cjs');
258
+ try {
259
+ const result = scanner.scanDirectoryWithContext(process.cwd(), { strict: true });
260
+ console.log(JSON.stringify({ ok: true, tags: result.tags.length, warnings: result.warnings.length }));
261
+ } catch (e) {
262
+ if (e.code === 'CAP_STRICT_TAG_VIOLATION') {
263
+ console.error(e.message);
264
+ process.exit(1);
265
+ }
266
+ throw e;
267
+ }
268
+ "
269
+ ```
270
+
271
+ If the command exits non-zero, surface the violation list to the user and abort the scan (do NOT proceed to enrichment). Otherwise continue to Step 3.
272
+
273
+ When `strict_mode === false` (default), the polylingual scan still runs but warnings are silently collected (available in `--json` output) and do not block the scan.
274
+
275
+ ## Step 3: Group tags by feature and by package
276
+
277
+ ```bash
278
+ node -e "
279
+ const tags = JSON.parse(process.argv[1]);
280
+ const groups = {};
281
+ const packageGroups = {};
282
+
283
+ for (const tag of tags) {
284
+ // Group by feature
285
+ const fid = (tag.metadata && tag.metadata.feature) || '(unassigned)';
286
+ if (!groups[fid]) groups[fid] = [];
287
+ groups[fid].push(tag);
288
+
289
+ // Group by package (first path segment if monorepo)
290
+ const parts = tag.file.split('/');
291
+ const pkg = parts.length > 2 && parts[0] === 'packages' ? parts[0] + '/' + parts[1] : '(root)';
292
+ if (!packageGroups[pkg]) packageGroups[pkg] = [];
293
+ packageGroups[pkg].push(tag);
294
+ }
295
+
296
+ console.log(JSON.stringify({ byFeature: groups, byPackage: packageGroups }, null, 2));
297
+ " '<ALL_TAGS_JSON>'
298
+ ```
299
+
300
+ ## Step 4: Cross-reference and detect orphans
301
+
302
+ Same as base scan -- run orphan detection against FEATURE-MAP.md.
303
+
304
+ ## Step 5: Auto-enrich Feature Map with cross-package file references
305
+
306
+ <!-- @cap-decision Cross-package file refs are stored as full relative paths from project root. This means packages/core/src/auth.ts, not just src/auth.ts. Feature Map readers can identify the package from the path prefix. -->
307
+
308
+ **If app-scoped (activeApp set):** Enrich the app's FEATURE-MAP.md, not root.
309
+
310
+ ```bash
311
+ node -e "
312
+ const fm = require('./cap/bin/lib/cap-feature-map.cjs');
313
+ const activeApp = process.argv[1] === 'null' ? null : process.argv[1];
314
+ const tags = JSON.parse(process.argv[2]);
315
+ const updated = fm.enrichFromTags(process.cwd(), tags, activeApp);
316
+ console.log(JSON.stringify({
317
+ features_enriched: updated.features.filter(f => f.files.length > 0).length,
318
+ total_file_refs: updated.features.reduce((sum, f) => sum + f.files.length, 0),
319
+ cross_package_refs: updated.features.reduce((sum, f) =>
320
+ sum + f.files.filter(fp => fp.startsWith('packages/')).length, 0)
321
+ }));
322
+ " '<ACTIVE_APP_OR_NULL>' '<ALL_TAGS_JSON>'
323
+ ```
324
+
325
+ **If not app-scoped (full scan):**
326
+
327
+ ```bash
328
+ node -e "
329
+ const scanner = require('./cap/bin/lib/cap-tag-scanner.cjs');
330
+ const fm = require('./cap/bin/lib/cap-feature-map.cjs');
331
+ const tags = scanner.scanDirectory(process.cwd());
332
+ const updated = fm.enrichFromTags(process.cwd(), tags);
333
+ console.log(JSON.stringify({
334
+ features_enriched: updated.features.filter(f => f.files.length > 0).length,
335
+ total_file_refs: updated.features.reduce((sum, f) => sum + f.files.length, 0),
336
+ cross_package_refs: updated.features.reduce((sum, f) =>
337
+ sum + f.files.filter(fp => fp.startsWith('packages/')).length, 0)
338
+ }));
339
+ "
340
+ ```
341
+
342
+ ## Step 5b: Record regret signals from @cap-decision regret:true tags (F-070/AC-3)
343
+
344
+ <!-- @cap-todo(ac:F-070/AC-3) Decision-Regret collector runs from /cap:scan, not from a hook (regret detection is retrospective and would blow F-070/AC-5's hook-overhead budget if scanned per Stop). -->
345
+ <!-- @cap-decision(F-070/D4) Trigger split — hooks fire override / memory-ref; tag-scanner enrichment fires regret. -->
346
+
347
+ ```bash
348
+ node -e "
349
+ const scanner = require('./cap/bin/lib/cap-tag-scanner.cjs');
350
+ const learning = require('./cap/bin/lib/cap-learning-signals.cjs');
351
+ const session = require('./cap/bin/lib/cap-session.cjs');
352
+ const tags = scanner.scanDirectory(process.cwd(), { projectRoot: process.cwd() });
353
+ let sessionId = null;
354
+ try { const s = session.loadSession(process.cwd()); sessionId = s && s.sessionId || null; } catch(_e){}
355
+ const result = learning.recordRegretsFromScan(process.cwd(), tags, { sessionId });
356
+ console.log(JSON.stringify(result));
357
+ "
358
+ ```
359
+
360
+ ## Step 6: Output results
361
+
362
+ **Formatted report (default):**
363
+
364
+ ```
365
+ cap:scan complete.
366
+
367
+ {If monorepo:}
368
+ Monorepo: {workspace_count} packages scanned
369
+ {For each package:}
370
+ - {package_name}: {tag_count} tags
371
+
372
+ Tags found: {total_tags}
373
+ @cap-feature: {count}
374
+ @cap-todo: {count}
375
+ @cap-risk: {count}
376
+ @cap-decision:{count}
377
+
378
+ Coverage: {files_with_tags} of {total_source_files} source files ({percentage}%)
379
+
380
+ Feature Map enrichment:
381
+ Features with file refs: {N}
382
+ Total file references: {N}
383
+ {If monorepo:} Cross-package refs: {N}
384
+
385
+ {Orphan section same as base scan}
386
+
387
+ Feature breakdown:
388
+ {For each feature group:}
389
+ {feature_id}: {count} tags ({type breakdown})
390
+ ```
391
+
392
+ ## Step 7: Update session
393
+
394
+ ```bash
395
+ node -e "
396
+ const session = require('./cap/bin/lib/cap-session.cjs');
397
+ session.updateSession(process.cwd(), {
398
+ lastCommand: '/cap:scan',
399
+ lastCommandTimestamp: new Date().toISOString()
400
+ });
401
+ "
402
+ ```
403
+
404
+ </process>