@geraldmaron/construct 1.0.14 → 1.0.16

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/README.md +21 -2
  2. package/bin/construct +146 -83
  3. package/commands/build/feature.md +0 -6
  4. package/commands/build/fix.md +0 -6
  5. package/commands/design/access.md +0 -6
  6. package/commands/design/flow.md +0 -6
  7. package/commands/design/ui.md +0 -6
  8. package/commands/measure/experiment.md +0 -6
  9. package/commands/measure/metrics.md +0 -6
  10. package/commands/measure/results.md +0 -6
  11. package/commands/plan/api.md +0 -6
  12. package/commands/plan/challenge.md +0 -6
  13. package/commands/plan/decide.md +0 -6
  14. package/commands/plan/feature.md +0 -7
  15. package/commands/plan/requirements.md +0 -6
  16. package/commands/remember/context.md +0 -6
  17. package/commands/remember/handoff.md +0 -6
  18. package/commands/remember/runbook.md +0 -6
  19. package/commands/review/code.md +0 -6
  20. package/commands/review/quality.md +0 -6
  21. package/commands/review/security.md +0 -6
  22. package/commands/ship/ready.md +0 -6
  23. package/commands/ship/release.md +0 -6
  24. package/commands/ship/status.md +0 -6
  25. package/commands/understand/docs.md +0 -6
  26. package/commands/understand/research.md +0 -6
  27. package/commands/understand/this.md +0 -6
  28. package/commands/understand/why.md +0 -6
  29. package/commands/work/clean.md +0 -6
  30. package/commands/work/drive.md +0 -6
  31. package/commands/work/optimize-prompts.md +0 -6
  32. package/commands/work/parallel-review.md +0 -6
  33. package/db/schema/010_cx_scores.sql +51 -0
  34. package/lib/beads-client.mjs +19 -1
  35. package/lib/cli-commands.mjs +280 -146
  36. package/lib/comment-lint.mjs +5 -1
  37. package/lib/context-state.mjs +15 -3
  38. package/lib/contracts/validate.mjs +72 -18
  39. package/lib/contracts/violation-log.mjs +169 -0
  40. package/lib/document-extract/docling-client.mjs +114 -0
  41. package/lib/document-extract/docling-sidecar.py +122 -0
  42. package/lib/document-extract/whisper-client.mjs +79 -0
  43. package/lib/document-extract.mjs +73 -8
  44. package/lib/document-ingest.mjs +26 -4
  45. package/lib/embed/daemon.mjs +6 -1
  46. package/lib/flavors/loader.mjs +1 -1
  47. package/lib/handoffs/contract.mjs +2 -2
  48. package/lib/hooks/session-start.mjs +1 -1
  49. package/lib/hooks/stop-notify.mjs +7 -0
  50. package/lib/ingest/chunker.mjs +94 -0
  51. package/lib/ingest/pipeline.mjs +53 -0
  52. package/lib/ingest/store.mjs +82 -0
  53. package/lib/install/first-invocation.mjs +5 -1
  54. package/lib/intake/prepare.mjs +22 -4
  55. package/lib/integrations/intake-integrations.mjs +28 -2
  56. package/lib/knowledge/search.mjs +12 -0
  57. package/lib/mcp/server.mjs +142 -1
  58. package/lib/mcp/tools/skills.mjs +6 -3
  59. package/lib/mcp/tools/telemetry.mjs +30 -0
  60. package/lib/mcp/tools/workflow.mjs +6 -2
  61. package/lib/observation-store.mjs +14 -5
  62. package/lib/ollama-manager.mjs +32 -28
  63. package/lib/orchestration-policy.mjs +15 -0
  64. package/lib/prompt-composer.js +11 -1
  65. package/lib/roles/gateway.mjs +30 -1
  66. package/lib/runtime/uv-bootstrap.mjs +129 -0
  67. package/lib/runtime/whisper-bootstrap.mjs +102 -0
  68. package/lib/scheduler/index.mjs +24 -4
  69. package/lib/server/index.mjs +22 -1
  70. package/lib/server/insights.mjs +12 -0
  71. package/lib/server/static/index.html +1 -1
  72. package/lib/setup.mjs +54 -9
  73. package/lib/specialists/postconditions.mjs +1 -1
  74. package/lib/sync/skill-frontmatter.mjs +113 -21
  75. package/lib/tracking-surfaces.mjs +2 -0
  76. package/lib/update.mjs +31 -3
  77. package/lib/upgrade.mjs +31 -4
  78. package/lib/validators/skills.mjs +86 -54
  79. package/package.json +5 -5
  80. package/personas/construct.md +6 -7
  81. package/platforms/claude/CLAUDE.md +43 -15
  82. package/platforms/claude/settings.template.json +1 -1
  83. package/rules/common/beads-hygiene.md +3 -9
  84. package/rules/common/code-review.md +3 -6
  85. package/rules/common/coding-style.md +3 -6
  86. package/rules/common/comments.md +3 -7
  87. package/rules/common/commit-approval.md +3 -6
  88. package/rules/common/cx-agent-routing.md +3 -7
  89. package/rules/common/cx-skill-routing.md +3 -3
  90. package/rules/common/doc-ownership.md +3 -8
  91. package/rules/common/efficiency.md +3 -8
  92. package/rules/common/framing.md +3 -8
  93. package/rules/common/git-workflow.md +3 -5
  94. package/rules/common/no-fabrication.md +4 -12
  95. package/rules/common/patterns.md +3 -5
  96. package/rules/common/release-gates.md +3 -8
  97. package/rules/common/research.md +3 -8
  98. package/rules/common/review-before-change.md +3 -9
  99. package/rules/common/security.md +3 -6
  100. package/rules/common/skill-composition.md +3 -7
  101. package/rules/common/testing.md +3 -6
  102. package/rules/golang/coding-style.md +1 -5
  103. package/rules/golang/hooks.md +1 -5
  104. package/rules/golang/patterns.md +1 -5
  105. package/rules/golang/security.md +1 -5
  106. package/rules/golang/testing.md +1 -5
  107. package/rules/python/coding-style.md +1 -5
  108. package/rules/python/hooks.md +1 -5
  109. package/rules/python/patterns.md +1 -5
  110. package/rules/python/security.md +1 -5
  111. package/rules/python/testing.md +1 -5
  112. package/rules/swift/coding-style.md +1 -5
  113. package/rules/swift/hooks.md +1 -5
  114. package/rules/swift/patterns.md +1 -5
  115. package/rules/swift/security.md +1 -5
  116. package/rules/swift/testing.md +1 -5
  117. package/rules/typescript/coding-style.md +1 -5
  118. package/rules/typescript/hooks.md +1 -5
  119. package/rules/typescript/patterns.md +1 -5
  120. package/rules/typescript/security.md +1 -5
  121. package/rules/typescript/testing.md +1 -5
  122. package/rules/web/coding-style.md +3 -5
  123. package/rules/web/design-quality.md +3 -5
  124. package/rules/web/hooks.md +3 -5
  125. package/rules/web/patterns.md +3 -5
  126. package/rules/web/performance.md +3 -5
  127. package/rules/web/security.md +3 -5
  128. package/rules/web/testing.md +3 -5
  129. package/scripts/sync-specialists.mjs +20 -2
  130. package/skills/ai/agent-dev.md +4 -5
  131. package/skills/ai/llm-security.md +4 -5
  132. package/skills/ai/ml-ops.md +4 -5
  133. package/skills/ai/orchestration-workflow.md +4 -5
  134. package/skills/ai/prompt-and-eval.md +4 -5
  135. package/skills/ai/prompt-optimizer.md +4 -6
  136. package/skills/ai/rag-system.md +4 -5
  137. package/skills/architecture/api-design.md +4 -5
  138. package/skills/architecture/caching.md +4 -5
  139. package/skills/architecture/cloud-native.md +4 -5
  140. package/skills/architecture/message-queue.md +4 -5
  141. package/skills/architecture/security-arch.md +4 -5
  142. package/skills/compliance/ai-disclosure.md +4 -5
  143. package/skills/compliance/data-privacy.md +4 -5
  144. package/skills/compliance/license-audit.md +4 -5
  145. package/skills/compliance/regulatory-review.md +4 -5
  146. package/skills/development/cpp.md +4 -5
  147. package/skills/development/go.md +4 -5
  148. package/skills/development/java.md +4 -5
  149. package/skills/development/kotlin.md +4 -5
  150. package/skills/development/mobile-crossplatform.md +4 -5
  151. package/skills/development/python.md +4 -5
  152. package/skills/development/rust.md +4 -5
  153. package/skills/development/shell.md +4 -5
  154. package/skills/development/swift.md +4 -5
  155. package/skills/development/typescript.md +4 -5
  156. package/skills/devops/ci-cd.md +4 -5
  157. package/skills/devops/containerization.md +4 -5
  158. package/skills/devops/cost-optimization.md +4 -5
  159. package/skills/devops/data-engineering.md +4 -5
  160. package/skills/devops/database.md +4 -5
  161. package/skills/devops/dependency-management.md +4 -5
  162. package/skills/devops/devsecops.md +4 -5
  163. package/skills/devops/git-workflow.md +4 -5
  164. package/skills/devops/incident-response.md +4 -5
  165. package/skills/devops/monorepo.md +4 -5
  166. package/skills/devops/observability.md +4 -5
  167. package/skills/devops/performance.md +4 -5
  168. package/skills/devops/testing.md +4 -5
  169. package/skills/docs/adr-workflow.md +4 -7
  170. package/skills/docs/backlog-proposal-workflow.md +4 -3
  171. package/skills/docs/customer-profile-workflow.md +4 -3
  172. package/skills/docs/document-ingest-workflow.md +4 -3
  173. package/skills/docs/evidence-ingest-workflow.md +4 -3
  174. package/skills/docs/init-docs.md +4 -5
  175. package/skills/docs/init-project.md +4 -5
  176. package/skills/docs/prd-workflow.md +4 -7
  177. package/skills/docs/prfaq-workflow.md +4 -3
  178. package/skills/docs/product-intelligence-review.md +4 -3
  179. package/skills/docs/product-intelligence-workflow.md +4 -6
  180. package/skills/docs/product-signal-workflow.md +4 -5
  181. package/skills/docs/research-workflow.md +4 -5
  182. package/skills/docs/runbook-workflow.md +4 -5
  183. package/skills/docs/strategy-workflow.md +4 -5
  184. package/skills/exploration/dependency-graph-reading.md +4 -7
  185. package/skills/exploration/repo-map.md +4 -5
  186. package/skills/exploration/tracer-bullet-method.md +4 -7
  187. package/skills/exploration/unknown-codebase-onboarding.md +4 -7
  188. package/skills/frameworks/django.md +4 -5
  189. package/skills/frameworks/nextjs.md +4 -5
  190. package/skills/frameworks/react.md +4 -5
  191. package/skills/frameworks/spring-boot.md +4 -5
  192. package/skills/frontend-design/accessibility.md +4 -5
  193. package/skills/frontend-design/component-patterns.md +4 -5
  194. package/skills/frontend-design/engineering.md +4 -5
  195. package/skills/frontend-design/state-management.md +4 -5
  196. package/skills/frontend-design/ui-aesthetics.md +4 -5
  197. package/skills/frontend-design/ux-principles.md +4 -5
  198. package/skills/operating/change-management.md +4 -8
  199. package/skills/operating/incident-response.md +4 -8
  200. package/skills/operating/oncall-rotation.md +4 -7
  201. package/skills/operating/orchestration-reference.md +4 -10
  202. package/skills/quality-gates/review-work.md +4 -5
  203. package/skills/quality-gates/verify-change.md +4 -5
  204. package/skills/quality-gates/verify-module.md +4 -5
  205. package/skills/quality-gates/verify-quality.md +4 -5
  206. package/skills/quality-gates/verify-security.md +4 -5
  207. package/skills/roles/architect.ai-systems.md +6 -9
  208. package/skills/roles/architect.data.md +6 -9
  209. package/skills/roles/architect.enterprise.md +6 -9
  210. package/skills/roles/architect.integration.md +6 -9
  211. package/skills/roles/architect.md +7 -14
  212. package/skills/roles/architect.platform.md +6 -9
  213. package/skills/roles/data-analyst.experiment.md +6 -9
  214. package/skills/roles/data-analyst.md +6 -9
  215. package/skills/roles/data-analyst.product-intelligence.md +7 -9
  216. package/skills/roles/data-analyst.product.md +6 -9
  217. package/skills/roles/data-analyst.telemetry.md +7 -9
  218. package/skills/roles/data-engineer.pipeline.md +6 -9
  219. package/skills/roles/data-engineer.vector-retrieval.md +7 -9
  220. package/skills/roles/data-engineer.warehouse.md +6 -9
  221. package/skills/roles/debugger.md +6 -9
  222. package/skills/roles/designer.accessibility.md +6 -9
  223. package/skills/roles/designer.md +7 -9
  224. package/skills/roles/engineer.ai.md +6 -9
  225. package/skills/roles/engineer.data.md +6 -9
  226. package/skills/roles/engineer.md +9 -9
  227. package/skills/roles/engineer.platform.md +6 -9
  228. package/skills/roles/operator.docs.md +6 -9
  229. package/skills/roles/operator.md +9 -9
  230. package/skills/roles/operator.release.md +6 -9
  231. package/skills/roles/operator.sre.md +6 -9
  232. package/skills/roles/orchestrator.md +6 -9
  233. package/skills/roles/product-manager.ai-product.md +6 -9
  234. package/skills/roles/product-manager.business-strategy.md +6 -9
  235. package/skills/roles/product-manager.enterprise.md +6 -9
  236. package/skills/roles/product-manager.growth.md +7 -9
  237. package/skills/roles/product-manager.md +7 -9
  238. package/skills/roles/product-manager.platform.md +6 -9
  239. package/skills/roles/product-manager.product.md +6 -9
  240. package/skills/roles/qa.ai-eval.md +8 -9
  241. package/skills/roles/qa.api-contract.md +7 -9
  242. package/skills/roles/qa.data-pipeline.md +7 -9
  243. package/skills/roles/qa.md +7 -9
  244. package/skills/roles/qa.test-automation.md +6 -9
  245. package/skills/roles/qa.web-ui.md +7 -9
  246. package/skills/roles/researcher.explorer.md +6 -9
  247. package/skills/roles/researcher.md +8 -9
  248. package/skills/roles/researcher.ux.md +6 -9
  249. package/skills/roles/reviewer.devil-advocate.md +6 -9
  250. package/skills/roles/reviewer.evaluator.md +6 -9
  251. package/skills/roles/reviewer.md +9 -9
  252. package/skills/roles/reviewer.trace.md +6 -9
  253. package/skills/roles/security.ai.md +7 -9
  254. package/skills/roles/security.appsec.md +6 -9
  255. package/skills/roles/security.cloud.md +6 -9
  256. package/skills/roles/security.legal-compliance.md +6 -9
  257. package/skills/roles/security.md +7 -9
  258. package/skills/roles/security.privacy.md +7 -9
  259. package/skills/roles/security.supply-chain.md +7 -9
  260. package/skills/security/blue-team.md +4 -5
  261. package/skills/security/code-audit.md +4 -5
  262. package/skills/security/pentest.md +4 -5
  263. package/skills/security/red-team.md +4 -5
  264. package/skills/security/threat-intel.md +4 -5
  265. package/skills/security/vuln-research.md +4 -5
  266. package/skills/strategy/competitive-landscape.md +4 -8
  267. package/skills/strategy/market-research-methods.md +4 -8
  268. package/skills/strategy/narrative-arc.md +4 -8
  269. package/skills/strategy/pricing-positioning.md +4 -8
  270. package/skills/utility/clean-code.md +4 -5
  271. package/specialists/policy-inventory.json +14 -0
  272. package/lib/specialist-contracts-enforce.mjs +0 -172
  273. package/rules/common/agents.md +0 -28
  274. package/rules/common/development-workflow.md +0 -32
  275. package/rules/common/performance.md +0 -55
@@ -9,6 +9,7 @@
9
9
  * Command Visibility:
10
10
  * - core: true → shown in default --help (90% of users)
11
11
  * - core: false → hidden unless --all flag (advanced/internal commands)
12
+ * - internal: true → hidden from --help and --all; callable but not advertised
12
13
  */
13
14
 
14
15
  export const CLI_COMMANDS = [
@@ -45,10 +46,11 @@ export const CLI_COMMANDS = [
45
46
  emoji: '🛠️',
46
47
  category: 'Core',
47
48
  core: true,
48
- description: 'Machine setup: install Docker, cm, and bootstrap config',
49
- usage: 'construct install [--yes]',
49
+ description: 'Machine setup (once per machine): Docker, cm/cass, config, embeddings',
50
+ usage: 'construct install [--yes] [--no-docker]',
50
51
  options: [
51
- { flag: '--yes', desc: 'Apply defaults without prompts' },
52
+ { flag: '--yes', desc: 'Apply defaults without prompts' },
53
+ { flag: '--no-docker', desc: 'Skip Docker-based service setup (local Postgres)' },
52
54
  ],
53
55
  },
54
56
  {
@@ -56,7 +58,7 @@ export const CLI_COMMANDS = [
56
58
  emoji: '🏗️',
57
59
  category: 'Core',
58
60
  core: true,
59
- description: 'Initialize project and start services',
61
+ description: 'Project setup (once per repo): scaffold .cx/, AGENTS.md, plan.md, adapters',
60
62
  usage: 'construct init [path] [options]',
61
63
  options: [
62
64
  { flag: '--yes', desc: 'Accept all defaults (non-interactive)' },
@@ -205,17 +207,18 @@ export const CLI_COMMANDS = [
205
207
  category: 'Core',
206
208
  core: true,
207
209
  description: 'Check installation health',
208
- usage: 'construct doctor',
210
+ usage: 'construct doctor [--fix-legacy-agents]',
211
+ options: [
212
+ { flag: '--fix-legacy-agents', desc: 'Sweep legacy cx-*.md agents at user scope and re-sync' },
213
+ ],
209
214
  },
210
-
211
- // ── Work (project workflows) ──────────────────────────────────────────
212
215
  {
213
216
  name: 'distill',
214
217
  emoji: '🔬',
215
218
  category: 'Work',
216
219
  core: false,
217
220
  description: 'Distill documents with query-focused chunking',
218
- usage: 'construct distill <dir> [--format=summary|decisions|full]',
221
+ usage: 'construct distill <file>',
219
222
  },
220
223
  {
221
224
  name: 'ingest',
@@ -223,7 +226,7 @@ export const CLI_COMMANDS = [
223
226
  category: 'Work',
224
227
  core: false,
225
228
  description: 'Convert documents to indexed markdown',
226
- usage: 'construct ingest <file> [--sync]',
229
+ usage: 'construct ingest <file> [--strict] [--legacy-extractor]',
227
230
  },
228
231
  {
229
232
  name: 'infer',
@@ -231,7 +234,7 @@ export const CLI_COMMANDS = [
231
234
  category: 'Work',
232
235
  core: false,
233
236
  description: 'Infer schema from documents',
234
- usage: 'construct infer <file> [--unified]',
237
+ usage: 'construct infer <file>',
235
238
  },
236
239
  {
237
240
  name: 'search',
@@ -247,7 +250,7 @@ export const CLI_COMMANDS = [
247
250
  category: 'Work',
248
251
  core: false,
249
252
  description: 'Manage storage backend',
250
- usage: 'construct storage sync|status|reset',
253
+ usage: 'construct storage <status|reset>',
251
254
  },
252
255
  {
253
256
  name: 'headhunt',
@@ -255,7 +258,7 @@ export const CLI_COMMANDS = [
255
258
  category: 'Work',
256
259
  core: false,
257
260
  description: 'Create domain expertise overlays',
258
- usage: 'construct headhunt <domain>',
261
+ usage: 'construct headhunt <create|list>',
259
262
  },
260
263
  {
261
264
  name: 'graph',
@@ -263,229 +266,180 @@ export const CLI_COMMANDS = [
263
266
  category: 'Work',
264
267
  core: false,
265
268
  description: 'Task graph management',
266
- usage: 'construct graph list|show|from-intake',
269
+ usage: 'construct graph <show|update>',
267
270
  },
268
-
269
- // ── Models & Integrations ─────────────────────────────────────────────
270
271
  {
271
272
  name: 'models',
272
273
  emoji: '🧠',
273
274
  category: 'Models & Integrations',
275
+ core: false,
274
276
  description: 'Show or update model tier assignments',
275
- usage: 'construct models [--poll|--apply|--reset|--tier=TIER|--set=MODEL|--prefer-free|--prefer-free-same-family]',
276
- options: [
277
- { flag: '--poll', desc: 'Query OpenRouter for currently free models' },
278
- { flag: '--apply', desc: 'Auto-apply best free models and sync' },
279
- { flag: '--reset', desc: 'Remove model overrides, restore defaults' },
280
- { flag: '--tier=TIER', desc: 'Target tier: reasoning | standard | fast' },
281
- { flag: '--set=MODEL_ID',desc: 'Set specific model for the tier' },
282
- { flag: '--prefer-free', desc: 'When inferring sibling tiers, prefer free models where possible' },
283
- { flag: '--prefer-free-same-family', desc: 'Prefer free siblings only when they stay in the same provider family' },
277
+ usage: 'construct models <list|set|free|reset|usage|cost>',
278
+ subcommands: [
279
+ { name: 'list', desc: 'Show current tier assignments' },
280
+ { name: 'set --tier=<reasoning|standard|fast> --model=<model>', desc: 'Set a model for a tier' },
281
+ { name: 'free', desc: 'List available free models' },
282
+ { name: 'reset', desc: 'Reset all tier assignments' },
283
+ { name: 'usage', desc: 'Show token usage per tier' },
284
+ { name: 'cost', desc: 'Show cost breakdown' },
284
285
  ],
285
286
  },
286
287
  {
287
288
  name: 'mcp',
288
289
  emoji: '🔌',
289
290
  category: 'Models & Integrations',
291
+ core: false,
290
292
  description: 'Manage MCP integrations',
291
- usage: 'construct mcp <list|add|remove|info> [name]',
293
+ usage: 'construct mcp <list|add|remove|info>',
292
294
  subcommands: [
293
- { name: 'list', desc: 'Show all MCP integrations and status' },
294
- { name: 'add', desc: 'Add an MCP integration interactively' },
295
- { name: 'remove', desc: 'Remove an MCP integration' },
296
- { name: 'info', desc: 'Show setup details for an integration' },
295
+ { name: 'list', desc: 'List configured MCP integrations' },
296
+ { name: 'add <id>', desc: 'Add an MCP integration by id' },
297
+ { name: 'remove <id>', desc: 'Remove an MCP integration' },
298
+ { name: 'info <id>', desc: 'Show details for one MCP integration' },
297
299
  ],
298
300
  },
299
301
  {
300
302
  name: 'plugin',
301
303
  emoji: '🧩',
302
304
  category: 'Models & Integrations',
305
+ core: false,
303
306
  description: 'Manage external Construct plugin manifests',
304
- usage: 'construct plugin <list|info|validate|init> [name]',
305
- subcommands: [
306
- { name: 'list', desc: 'Show loaded plugins and manifest sources' },
307
- { name: 'info', desc: 'Show details for a plugin' },
308
- { name: 'validate', desc: 'Validate all discovered plugin manifests' },
309
- { name: 'init', desc: 'Create a starter plugin manifest in .cx/plugins/' },
310
- ],
307
+ usage: 'construct plugin <list|info|init>',
311
308
  },
312
309
  {
313
310
  name: 'hosts',
314
311
  emoji: '🖥️',
315
312
  category: 'Models & Integrations',
313
+ core: false,
316
314
  description: 'Show host support for Construct orchestration',
317
- usage: 'construct hosts',
315
+ usage: 'construct hosts [--json]',
318
316
  },
319
317
  {
320
318
  name: 'claude:allow',
321
319
  emoji: '🔓',
322
320
  category: 'Models & Integrations',
321
+ core: false,
323
322
  description: 'Manage Claude Code `permissions.allow` from the outside (auto-classifier blocks the agent from editing it)',
324
- usage: 'construct claude:allow <list|add|remove|check> [pattern...] [--apply]',
325
- subcommands: [
326
- { name: 'list', desc: 'Print every allowlist entry' },
327
- { name: 'add', desc: 'Add one or more patterns (idempotent)' },
328
- { name: 'remove', desc: 'Remove patterns' },
329
- { name: 'check', desc: 'Detect branch-prefix gaps; `--apply` writes the suggestions' },
330
- ],
323
+ usage: 'construct claude:allow <check|apply|add|remove>',
331
324
  },
332
-
333
- // ── Observability ─────────────────────────────────────────────────────
334
325
  {
335
326
  name: 'review',
336
327
  emoji: '📈',
337
328
  category: 'Observability',
329
+ core: false,
338
330
  description: 'Generate agent performance review from Langfuse trace backend',
339
- usage: 'construct review [--days=N] [--agent=NAME] [--schedule]',
340
- options: [
341
- { flag: '--days=N', desc: 'Review window in days (default: 30)' },
342
- { flag: '--agent=NAME', desc: 'Filter to a specific agent' },
343
- { flag: '--out=PATH', desc: 'Output directory' },
344
- { flag: '--json-only', desc: 'Write raw JSON only, skip markdown report' },
345
- { flag: '--schedule', desc: 'Schedule automatic weekly reviews' },
346
- { flag: '--cadence=CRON',desc: 'Cron expression for --schedule (default: Monday 9am)' },
347
- ],
331
+ usage: 'construct review [--agent=<id>] [--days=N]',
348
332
  },
349
333
  {
350
334
  name: 'optimize',
351
335
  emoji: '⚙️',
352
336
  category: 'Observability',
337
+ core: false,
353
338
  description: 'Prompt optimization using Langfuse trace quality scores',
354
- usage: 'construct optimize <agent> [--dry-run] [--list]',
355
- options: [
356
- { flag: '--dry-run', desc: 'Preview changes without applying' },
357
- { flag: '--list', desc: 'Show all agents with quality scores' },
358
- { flag: '--threshold=N', desc: 'Quality threshold to trigger optimization (default: 0.7)' },
359
- { flag: '--days=N', desc: 'Trace window in days (default: 7)' },
360
- { flag: '--min-traces=N', desc: 'Minimum traces required (default: 20)' },
361
- ],
339
+ usage: 'construct optimize <agent>',
362
340
  },
363
341
  {
364
342
  name: 'telemetry-backfill',
365
343
  emoji: '🩹',
366
344
  category: 'Observability',
345
+ core: false,
367
346
  description: 'Backfill sparse traces with observations (trace backend)',
368
- usage: 'construct telemetry-backfill [--limit=N]',
369
- options: [
370
- { flag: '--limit=N', desc: 'Maximum sparse traces to backfill (default: 10)' },
371
- { flag: '--best-effort', desc: 'Skip failures instead of exiting non-zero' },
372
- ],
347
+ usage: 'construct telemetry-backfill',
373
348
  },
374
349
  {
375
350
  name: 'eval-datasets',
376
351
  emoji: '📊',
377
352
  category: 'Observability',
353
+ core: false,
378
354
  description: 'Sync scored Langfuse traces into eval datasets for prompt regression testing',
379
- usage: 'construct eval-datasets [--limit=N]',
380
- options: [
381
- { flag: '--limit=N', desc: 'Maximum scored traces to sync (default: 100)' },
382
- ],
355
+ usage: 'construct eval-datasets',
383
356
  },
384
357
  {
385
358
  name: 'llm-judge',
386
359
  emoji: '⚖️',
387
360
  category: 'Observability',
361
+ core: false,
388
362
  description: 'Run LLM-as-a-judge evaluations on unscored traces for continuous quality feedback',
389
- usage: 'construct llm-judge [--limit=N] [--model=NAME]',
390
- options: [
391
- { flag: '--limit=N', desc: 'Maximum traces to evaluate (default: 10)' },
392
- { flag: '--model=NAME', desc: 'LLM model to use for evaluation (default: claude-3-5-sonnet-20241022)' },
393
- ],
363
+ usage: 'construct llm-judge',
394
364
  },
395
365
  {
396
366
  name: 'efficiency',
397
367
  emoji: '🧮',
398
368
  category: 'Observability',
369
+ core: false,
399
370
  description: 'Show read efficiency, repeated files, and context-budget guidance',
400
371
  usage: 'construct efficiency [--json]',
401
- options: [
402
- { flag: '--json', desc: 'Output raw JSON' },
403
- ],
404
372
  },
405
373
  {
406
374
  name: 'evals',
407
375
  emoji: '🧪',
408
376
  category: 'Observability',
377
+ core: false,
409
378
  description: 'Show evaluator catalog for prompt and agent experiments',
410
- usage: 'construct evals [--json]',
411
- options: [
412
- { flag: '--json', desc: 'Output raw JSON' },
413
- ],
379
+ usage: 'construct evals <list|run>',
414
380
  },
415
381
  {
416
382
  name: 'cleanup',
417
383
  emoji: '🧹',
418
384
  category: 'Diagnostics',
385
+ core: false,
419
386
  description: 'Release dev-agent memory pressure by cleaning stale helper and bridge processes',
420
- usage: 'construct cleanup [--pressure-release] [--quiet]',
387
+ usage: 'construct cleanup [--dry-run] [--quiet] [--pressure-release] [--pressure-only] [--disk-only]',
421
388
  options: [
422
- { flag: '--pressure-release', desc: 'Also terminate stale cass index processes when swap is above threshold' },
423
- { flag: '--quiet', desc: 'Suppress per-process output and only act on the current policy' },
389
+ { flag: '--dry-run', desc: 'Show what would be cleaned without changing anything' },
390
+ { flag: '--quiet', desc: 'Minimal output' },
391
+ { flag: '--pressure-release', desc: 'Also kill stale dev-agent processes' },
392
+ { flag: '--pressure-only', desc: 'Pressure release only — skip disk cleanup' },
393
+ { flag: '--disk-only', desc: 'Disk cleanup only — skip pressure release' },
424
394
  ],
425
395
  },
426
-
427
- // ── Teams & Audit ────────────────────────────────────────────────────
428
396
  {
429
397
  name: 'team',
430
398
  emoji: '👥',
431
399
  category: 'Work',
400
+ core: false,
432
401
  description: 'Team review and template listing',
433
- usage: 'construct team <review|templates>',
434
- subcommands: [
435
- { name: 'review', desc: 'Run telemetry-backed team performance review' },
436
- { name: 'templates', desc: 'List available team templates from specialists/teams.json' },
437
- ],
402
+ usage: 'construct team <list|review>',
438
403
  },
439
404
  {
440
405
  name: 'audit',
441
406
  emoji: '🔍',
442
407
  category: 'Diagnostics',
408
+ core: false,
443
409
  description: 'Audit Construct internals and review the mutation trail',
444
- usage: 'construct audit <skills|trail>',
445
- subcommands: [
446
- { name: 'skills', desc: 'Audit skill files for stub headers, broken references, and missing content' },
447
- { name: 'trail', desc: 'Show the append-only audit trail of every mutation (agent, task, file, hash). Supports --verify, --agent, --tool, --since, --json.' },
448
- ],
410
+ usage: 'construct audit <events|trail>',
449
411
  },
450
412
  {
451
413
  name: 'doc',
452
414
  emoji: '🔏',
453
415
  category: 'Diagnostics',
416
+ core: false,
454
417
  description: 'Verify or inspect auditability stamps on Construct-generated markdown files',
455
- usage: 'construct doc <verify|install-hooks> [path] [--json]',
456
- subcommands: [
457
- { name: 'verify', desc: 'Check body_hash stamps on one file or all .md files under a path. Exits non-zero if any fail.' },
458
- { name: 'install-hooks', desc: 'Install the prepare-commit-msg git hook into .git/hooks/ for AI provenance trailers.' },
459
- ],
418
+ usage: 'construct doc <verify|inspect>',
419
+ },
420
+ {
421
+ name: 'bootstrap',
422
+ emoji: '🌱',
423
+ category: 'Work',
424
+ core: false,
425
+ description: 'Import seed observation corpus into local memory store for cold-start acceleration',
426
+ usage: 'construct bootstrap',
427
+ },
428
+ {
429
+ name: 'reflect',
430
+ emoji: '🪞',
431
+ category: 'Work',
432
+ core: false,
433
+ description: 'Capture improvement feedback from chat session and update Construct core',
434
+ usage: 'construct reflect',
460
435
  },
461
- {
462
- name: 'bootstrap',
463
- emoji: '🌱',
464
- category: 'Work',
465
- description: 'Import seed observation corpus into local memory store for cold-start acceleration',
466
- usage: 'construct bootstrap [--verbose]',
467
- options: [
468
- { flag: '--verbose', desc: 'Print each observation imported or skipped' },
469
- ],
470
- },
471
- {
472
- name: 'reflect',
473
- emoji: '🪞',
474
- category: 'Work',
475
- description: 'Capture improvement feedback from chat session and update Construct core',
476
- usage: 'construct reflect [--target=<internal|how-tos|decisions>] [--summary=<text>]',
477
- options: [
478
- { flag: '--target=<internal|how-tos|decisions>', desc: 'Knowledge subdir to store feedback (default: internal)' },
479
- { flag: '--summary=<text>', desc: 'Brief summary of the improvement feedback' },
480
- ],
481
- },
482
436
  {
483
437
  name: 'memory',
484
438
  emoji: '💡',
485
439
  category: 'Work',
486
440
  core: false,
487
441
  description: 'Inspect memory layer',
488
- usage: 'construct memory stats|consolidate',
442
+ usage: 'construct memory <status|search>',
489
443
  },
490
444
  {
491
445
  name: 'drop',
@@ -493,7 +447,7 @@ export const CLI_COMMANDS = [
493
447
  category: 'Work',
494
448
  core: false,
495
449
  description: 'Ingest file from Downloads/Desktop',
496
- usage: 'construct drop [--list]',
450
+ usage: 'construct drop <file>',
497
451
  },
498
452
  {
499
453
  name: 'wireframe',
@@ -501,7 +455,7 @@ export const CLI_COMMANDS = [
501
455
  category: 'Work',
502
456
  core: false,
503
457
  description: 'Generate wireframes from description',
504
- usage: 'construct wireframe "<description>"',
458
+ usage: 'construct wireframe <description>',
505
459
  },
506
460
  {
507
461
  name: 'ollama',
@@ -509,17 +463,15 @@ export const CLI_COMMANDS = [
509
463
  category: 'Integrations',
510
464
  core: false,
511
465
  description: 'Manage local Ollama models',
512
- usage: 'construct ollama status|pull|test',
466
+ usage: 'construct ollama <list|pull|run>',
513
467
  },
514
-
515
- // ── Advanced (hidden by default) ──────────────────────────────────────
516
468
  {
517
469
  name: 'beads',
518
470
  emoji: '📿',
519
471
  category: 'Advanced',
520
472
  core: false,
521
473
  description: 'Task queue management',
522
- usage: 'construct beads status|cleanup',
474
+ usage: 'construct beads <list|show|create|update|close|drift|stats>',
523
475
  },
524
476
  {
525
477
  name: 'config',
@@ -527,7 +479,7 @@ export const CLI_COMMANDS = [
527
479
  category: 'Advanced',
528
480
  core: false,
529
481
  description: 'Deployment mode configuration',
530
- usage: 'construct config mode',
482
+ usage: 'construct config <get|set>',
531
483
  },
532
484
  {
533
485
  name: 'uninstall',
@@ -535,7 +487,11 @@ export const CLI_COMMANDS = [
535
487
  category: 'Advanced',
536
488
  core: false,
537
489
  description: 'Remove Construct state',
538
- usage: 'construct uninstall',
490
+ usage: 'construct uninstall [--yes] [--all]',
491
+ options: [
492
+ { flag: '--yes', desc: 'Remove auto-risk categories without prompting' },
493
+ { flag: '--all', desc: 'Combined with --yes: also remove ask-risk categories (project data, machine config)' },
494
+ ],
539
495
  },
540
496
  {
541
497
  name: 'update',
@@ -559,7 +515,7 @@ export const CLI_COMMANDS = [
559
515
  category: 'Advanced',
560
516
  core: false,
561
517
  description: 'Shell completion scripts',
562
- usage: 'construct completions',
518
+ usage: 'construct completions <bash|zsh|install>',
563
519
  },
564
520
  {
565
521
  name: 'list',
@@ -575,7 +531,7 @@ export const CLI_COMMANDS = [
575
531
  category: 'Advanced',
576
532
  core: false,
577
533
  description: 'Role framework management',
578
- usage: 'construct role list|status',
534
+ usage: 'construct role <list|set|latest>',
579
535
  },
580
536
  {
581
537
  name: 'embed',
@@ -729,18 +685,143 @@ export const CLI_COMMANDS = [
729
685
  description: 'Query telemetry traces and latency data',
730
686
  usage: 'construct telemetry query <latency|top-slow|errors|trace>',
731
687
  },
688
+ {
689
+ name: 'ask',
690
+ emoji: '❓',
691
+ category: 'Work',
692
+ core: false,
693
+ description: 'One-shot ask against the active knowledge index',
694
+ usage: 'construct ask <query>',
695
+ },
696
+ {
697
+ name: 'handoffs',
698
+ emoji: '📦',
699
+ category: 'Work',
700
+ core: false,
701
+ description: 'List and inspect session handoff files in .cx/handoffs/',
702
+ usage: 'construct handoffs <list|show>',
703
+ },
704
+ {
705
+ name: 'feedback:record',
706
+ emoji: '📝',
707
+ category: 'Observability',
708
+ core: false,
709
+ description: 'Record an outcome rating for a recent specialist invocation',
710
+ usage: 'construct feedback:record <id> --score=<0-1> [--note="..."]',
711
+ },
712
+ {
713
+ name: 'feedback:history',
714
+ emoji: '📜',
715
+ category: 'Observability',
716
+ core: false,
717
+ description: 'Show recorded outcome ratings',
718
+ usage: 'construct feedback:history [--days=N]',
719
+ },
720
+ {
721
+ name: 'roles:list',
722
+ emoji: '🎭',
723
+ category: 'Advanced',
724
+ core: false,
725
+ description: 'List installed role contracts',
726
+ usage: 'construct roles:list',
727
+ },
728
+ {
729
+ name: 'roles:set',
730
+ emoji: '🎭',
731
+ category: 'Advanced',
732
+ core: false,
733
+ description: 'Activate a role contract',
734
+ usage: 'construct roles:set <role>',
735
+ },
736
+ {
737
+ name: 'docs:check',
738
+ emoji: '📄',
739
+ category: 'Diagnostics',
740
+ core: false,
741
+ description: 'Check for missing how-to guides (alias for `docs check`)',
742
+ usage: 'construct docs:check',
743
+ },
744
+ {
745
+ name: 'docs:verify',
746
+ emoji: '📄',
747
+ category: 'Diagnostics',
748
+ core: false,
749
+ description: 'Validate documentation quality (alias for `docs verify`)',
750
+ usage: 'construct docs:verify',
751
+ },
752
+ {
753
+ name: 'docs:update',
754
+ emoji: '📄',
755
+ category: 'Diagnostics',
756
+ core: false,
757
+ description: 'Regenerate AUTO-managed doc regions (alias for `docs update`)',
758
+ usage: 'construct docs:update',
759
+ },
760
+ {
761
+ name: 'docs:reconcile',
762
+ emoji: '📄',
763
+ category: 'Diagnostics',
764
+ core: false,
765
+ description: 'Reconcile docs against the registry',
766
+ usage: 'construct docs:reconcile',
767
+ },
768
+ {
769
+ name: 'docs:site',
770
+ emoji: '📄',
771
+ category: 'Diagnostics',
772
+ core: false,
773
+ description: 'Manage the docs static site build',
774
+ usage: 'construct docs:site <build|serve>',
775
+ },
776
+ {
777
+ name: 'beads:stats',
778
+ emoji: '📿',
779
+ category: 'Advanced',
780
+ core: false,
781
+ description: 'Show beads counters and drift summary',
782
+ usage: 'construct beads:stats',
783
+ },
784
+ {
785
+ name: 'telemetry-setup',
786
+ emoji: '🩹',
787
+ category: 'Observability',
788
+ core: false,
789
+ description: 'Configure Langfuse credentials and trace export',
790
+ usage: 'construct telemetry-setup',
791
+ },
792
+ // ── Internal — callable but not advertised in help or completions ────
793
+ { name: 'hook', category: 'Internal', core: false, internal: true, description: 'Hook dispatch — invoked by the harness, not by users', usage: 'construct hook <event>' },
794
+ { name: 'seed-traces', category: 'Internal', core: false, internal: true, description: 'Dev fixture: seed traces for testing', usage: 'construct seed-traces' },
795
+ { name: 'migrate', category: 'Internal', core: false, internal: true, description: 'Internal: run pending storage migrations', usage: 'construct migrate' },
796
+ { name: 'dashboard:sync', category: 'Internal', core: false, internal: true, description: 'Internal: refresh dashboard state from the registry', usage: 'construct dashboard:sync' },
797
+ { name: 'init:update', category: 'Internal', core: false, internal: true, description: 'Internal: re-run init scaffolding for an existing project', usage: 'construct init:update' },
798
+ { name: 'lint:agents', category: 'Internal', core: false, internal: true, description: 'Internal lint: agent definitions', usage: 'construct lint:agents' },
799
+ { name: 'lint:comments', category: 'Internal', core: false, internal: true, description: 'Internal lint: source comments', usage: 'construct lint:comments' },
800
+ { name: 'lint:contracts', category: 'Internal', core: false, internal: true, description: 'Internal lint: specialist contracts', usage: 'construct lint:contracts' },
801
+ { name: 'lint:research', category: 'Internal', core: false, internal: true, description: 'Internal lint: research artifacts', usage: 'construct lint:research' },
802
+ { name: 'lint:templates', category: 'Internal', core: false, internal: true, description: 'Internal lint: shipped templates', usage: 'construct lint:templates' },
803
+ { name: 'evaluator:rubrics', category: 'Internal', core: false, internal: true, description: 'Internal: list registered evaluator rubrics', usage: 'construct evaluator:rubrics' },
804
+ { name: 'activation:status', category: 'Internal', core: false, internal: true, description: 'Internal: agent activation telemetry', usage: 'construct activation:status' },
805
+ { name: 'prune', category: 'Internal', core: false, internal: true, description: 'Internal: prune ephemeral storage entries', usage: 'construct prune' },
806
+ { name: 'overrides', category: 'Internal', core: false, internal: true, description: 'Internal: list project overrides over the catalog', usage: 'construct overrides' },
807
+ { name: 'resources', category: 'Internal', core: false, internal: true, description: 'Internal: resource probe', usage: 'construct resources' },
732
808
  ];
733
809
 
734
810
  /** Flat list of all top-level command names (for completions). */
735
- export const COMMAND_NAMES = CLI_COMMANDS.map(c => c.name);
811
+ export const COMMAND_NAMES = CLI_COMMANDS.filter((c) => !c.internal).map((c) => c.name);
812
+
813
+ /** Every handler key (including internal) — used for catalog-parity tests. */
814
+ export const ALL_COMMAND_NAMES = CLI_COMMANDS.map((c) => c.name);
736
815
 
737
816
  /** Commands grouped by category, sorted alphabetically by name within each group. */
738
- export const CLI_COMMANDS_BY_CATEGORY = CLI_COMMANDS.reduce((acc, cmd) => {
739
- const cat = cmd.category ?? 'Other';
740
- if (!acc[cat]) acc[cat] = [];
741
- acc[cat].push(cmd);
742
- return acc;
743
- }, {});
817
+ export const CLI_COMMANDS_BY_CATEGORY = CLI_COMMANDS
818
+ .filter((c) => !c.internal)
819
+ .reduce((acc, cmd) => {
820
+ const cat = cmd.category ?? 'Other';
821
+ if (!acc[cat]) acc[cat] = [];
822
+ acc[cat].push(cmd);
823
+ return acc;
824
+ }, {});
744
825
  for (const cat of Object.keys(CLI_COMMANDS_BY_CATEGORY)) {
745
826
  CLI_COMMANDS_BY_CATEGORY[cat].sort((a, b) => a.name.localeCompare(b.name));
746
827
  }
@@ -758,13 +839,66 @@ export const CATEGORY_ORDER = [
758
839
 
759
840
  /** Check if a command should be shown by default (core: true) or hidden (core: false). */
760
841
  export function isCoreCommand(commandName) {
761
- const cmd = CLI_COMMANDS.find(c => c.name === commandName);
842
+ const cmd = CLI_COMMANDS.find((c) => c.name === commandName);
762
843
  return cmd?.core ?? false;
763
844
  }
764
845
 
846
+ /** Check if a command is internal (hidden from --help and --all). */
847
+ export function isInternalCommand(commandName) {
848
+ const cmd = CLI_COMMANDS.find((c) => c.name === commandName);
849
+ return cmd?.internal === true;
850
+ }
851
+
765
852
  /** Get commands filtered by visibility. */
766
853
  export function getCommands(options = {}) {
767
854
  const { showAll = false } = options;
768
- if (showAll) return CLI_COMMANDS;
769
- return CLI_COMMANDS.filter(cmd => cmd.core);
855
+ const visible = CLI_COMMANDS.filter((c) => !c.internal);
856
+ if (showAll) return visible;
857
+ return visible.filter((cmd) => cmd.core);
858
+ }
859
+
860
+ /** Look up a single command entry by name. */
861
+ export function getCommandSpec(name) {
862
+ return CLI_COMMANDS.find((c) => c.name === name) || null;
863
+ }
864
+
865
+ const ESC = String.fromCharCode(27);
866
+
867
+ // Render a per-command help block. Pulls usage, description, subcommands,
868
+ // and options from the CLI_COMMANDS entry so help stays consistent across
869
+ // every command. Internal commands fall back to a minimal block.
870
+
871
+ export function formatCommandHelp(name, { colors = false } = {}) {
872
+ const useColor = colors && process.stdout.isTTY && !process.env.NO_COLOR && process.env.TERM !== 'dumb';
873
+ const c = useColor
874
+ ? { bold: `${ESC}[1m`, dim: `${ESC}[2m`, reset: `${ESC}[0m` }
875
+ : { bold: '', dim: '', reset: '' };
876
+ const spec = getCommandSpec(name);
877
+ if (!spec) {
878
+ return `Unknown command: ${name}\n\nRun 'construct --help' for available commands.\n`;
879
+ }
880
+ const lines = [];
881
+ lines.push(`${c.bold}construct ${spec.name}${c.reset} — ${spec.description}`);
882
+ lines.push('');
883
+ if (spec.usage) {
884
+ lines.push(`${c.dim}Usage:${c.reset} ${spec.usage}`);
885
+ lines.push('');
886
+ }
887
+ if (spec.subcommands && spec.subcommands.length > 0) {
888
+ lines.push(`${c.bold}Subcommands${c.reset}`);
889
+ const width = Math.max(...spec.subcommands.map((s) => s.name.length));
890
+ for (const sub of spec.subcommands) {
891
+ lines.push(` ${sub.name.padEnd(width)} ${sub.desc}`);
892
+ }
893
+ lines.push('');
894
+ }
895
+ if (spec.options && spec.options.length > 0) {
896
+ lines.push(`${c.bold}Options${c.reset}`);
897
+ const width = Math.max(...spec.options.map((o) => o.flag.length));
898
+ for (const opt of spec.options) {
899
+ lines.push(` ${opt.flag.padEnd(width)} ${opt.desc}`);
900
+ }
901
+ lines.push('');
902
+ }
903
+ return lines.join('\n');
770
904
  }