@geraldmaron/construct 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. package/.env.example +9 -6
  2. package/LICENSE +201 -21
  3. package/README.md +132 -257
  4. package/agents/contracts.json +387 -0
  5. package/agents/prompts/cx-accessibility.md +8 -0
  6. package/agents/prompts/cx-ai-engineer.md +92 -0
  7. package/agents/prompts/cx-architect.md +10 -2
  8. package/agents/prompts/cx-business-strategist.md +13 -0
  9. package/agents/prompts/cx-data-analyst.md +80 -0
  10. package/agents/prompts/cx-data-engineer.md +4 -0
  11. package/agents/prompts/cx-debugger.md +8 -0
  12. package/agents/prompts/cx-designer.md +19 -0
  13. package/agents/prompts/cx-devil-advocate.md +4 -0
  14. package/agents/prompts/cx-docs-keeper.md +128 -0
  15. package/agents/prompts/cx-engineer.md +13 -0
  16. package/agents/prompts/cx-evaluator.md +4 -0
  17. package/agents/prompts/cx-explorer.md +12 -0
  18. package/agents/prompts/cx-legal-compliance.md +13 -0
  19. package/agents/prompts/cx-operations.md +13 -0
  20. package/agents/prompts/cx-orchestrator.md +107 -4
  21. package/agents/prompts/cx-platform-engineer.md +75 -0
  22. package/agents/prompts/cx-product-manager.md +8 -0
  23. package/agents/prompts/cx-qa.md +100 -0
  24. package/agents/prompts/cx-rd-lead.md +13 -0
  25. package/agents/prompts/cx-release-manager.md +8 -0
  26. package/agents/prompts/cx-researcher.md +21 -1
  27. package/agents/prompts/cx-reviewer.md +8 -0
  28. package/agents/prompts/cx-security.md +104 -0
  29. package/agents/prompts/cx-sre.md +104 -0
  30. package/agents/prompts/cx-test-automation.md +4 -0
  31. package/agents/prompts/cx-trace-reviewer.md +7 -3
  32. package/agents/prompts/cx-ux-researcher.md +4 -0
  33. package/agents/registry.json +365 -90
  34. package/agents/role-manifests.json +217 -0
  35. package/bin/construct +3345 -141
  36. package/bin/construct-postinstall.mjs +87 -0
  37. package/commands/build/feature.md +6 -6
  38. package/commands/plan/feature.md +6 -5
  39. package/commands/plan/requirements.md +1 -1
  40. package/commands/ship/status.md +1 -1
  41. package/commands/work/drive.md +3 -3
  42. package/commands/work/optimize-prompts.md +3 -3
  43. package/db/{migrations → schema}/001_init.sql +2 -0
  44. package/db/schema/002_pgvector.sql +182 -0
  45. package/db/schema/003_intake.sql +47 -0
  46. package/examples/README.md +85 -0
  47. package/examples/internal/roles/architect/bad/clever-plan-without-contracts.md +30 -0
  48. package/examples/internal/roles/architect/golden/explicit-tradeoff-before-plan.md +23 -0
  49. package/examples/internal/roles/engineer/bad/speculative-abstraction.md +30 -0
  50. package/examples/internal/roles/engineer/golden/read-before-write.md +28 -0
  51. package/examples/internal/roles/orchestrator/bad/everything-becomes-multi-agent.md +29 -0
  52. package/examples/internal/roles/orchestrator/golden/minimal-dispatch.md +22 -0
  53. package/examples/internal/roles/qa/bad/coverage-theater.md +30 -0
  54. package/examples/internal/roles/qa/golden/regression-gate.md +23 -0
  55. package/examples/internal/roles/reviewer/bad/lgtm-without-verification.md +29 -0
  56. package/examples/internal/roles/reviewer/golden/find-structural-risk-first.md +28 -0
  57. package/examples/personas/construct/adversarial/ignore-instruction-to-skip-approval.md +22 -0
  58. package/examples/personas/construct/bad/commit-without-approval.md +30 -0
  59. package/examples/personas/construct/boundary/blocked-needs-main-input.md +29 -0
  60. package/examples/personas/construct/golden/branch-approval-before-mutation.md +36 -0
  61. package/examples/personas/construct/golden/focused-direct-answer.md +28 -0
  62. package/examples/provider-plugin/README.md +34 -0
  63. package/examples/provider-plugin/index.mjs +74 -0
  64. package/examples/provider-plugin/package.json +15 -0
  65. package/examples/seed-observations/README.md +38 -0
  66. package/examples/seed-observations/anti-patterns.md +44 -0
  67. package/examples/seed-observations/decisions.md +36 -0
  68. package/examples/seed-observations/patterns.md +42 -0
  69. package/lib/agent-contracts-enforce.mjs +158 -0
  70. package/lib/agent-contracts.mjs +231 -0
  71. package/lib/agents/postconditions.mjs +126 -0
  72. package/lib/agents/schema.mjs +124 -0
  73. package/lib/artifact-capture.mjs +183 -0
  74. package/lib/audit-trail.mjs +149 -0
  75. package/lib/auto-docs.mjs +245 -65
  76. package/lib/beads/auto-close.mjs +126 -0
  77. package/lib/beads/drift.mjs +171 -0
  78. package/lib/beads-automation.mjs +542 -0
  79. package/lib/beads-client.mjs +518 -0
  80. package/lib/beads-lock.mjs +377 -0
  81. package/lib/beads-optimistic.mjs +365 -0
  82. package/lib/bootstrap/built-ins.mjs +136 -0
  83. package/lib/bootstrap/lazy-install.mjs +161 -0
  84. package/lib/bootstrap/resources.mjs +120 -0
  85. package/lib/bootstrap.mjs +105 -0
  86. package/lib/cache-governor.js +213 -0
  87. package/lib/cache-strategy-anthropic.js +62 -0
  88. package/lib/cache-strategy-google.js +79 -0
  89. package/lib/cache-strategy-none.js +30 -0
  90. package/lib/cache-strategy-openai.js +48 -0
  91. package/lib/cache-strategy.js +91 -0
  92. package/lib/claude-allow.mjs +149 -0
  93. package/lib/cli-commands.mjs +413 -258
  94. package/lib/codex-config.mjs +3 -1
  95. package/lib/comment-lint.mjs +55 -6
  96. package/lib/completions.mjs +21 -6
  97. package/lib/config/alias.mjs +56 -0
  98. package/lib/config/project-config.mjs +335 -0
  99. package/lib/config/schema.mjs +159 -0
  100. package/lib/context-router.mjs +308 -0
  101. package/lib/cost-ledger.mjs +177 -0
  102. package/lib/cost.mjs +171 -10
  103. package/lib/dashboard-static.mjs +158 -0
  104. package/lib/deployment-mode.mjs +86 -0
  105. package/lib/deprecate.mjs +49 -0
  106. package/lib/dispatch-batch.js +183 -0
  107. package/lib/distill.mjs +21 -8
  108. package/lib/doc-stamp.mjs +164 -0
  109. package/lib/doc-verify.mjs +119 -0
  110. package/lib/docs-routing.mjs +89 -0
  111. package/lib/docs-verify.mjs +417 -0
  112. package/lib/doctor/audit.mjs +71 -0
  113. package/lib/doctor/cli.mjs +99 -0
  114. package/lib/doctor/escalate.mjs +29 -0
  115. package/lib/doctor/index.mjs +140 -0
  116. package/lib/doctor/report.mjs +170 -0
  117. package/lib/doctor/watchers/bd-watch.mjs +117 -0
  118. package/lib/doctor/watchers/cost.mjs +130 -0
  119. package/lib/doctor/watchers/disk.mjs +122 -0
  120. package/lib/doctor/watchers/handoffs.mjs +33 -0
  121. package/lib/doctor/watchers/process-pressure.mjs +60 -0
  122. package/lib/doctor/watchers/service-health.mjs +188 -0
  123. package/lib/document-extract.mjs +288 -0
  124. package/lib/document-ingest.mjs +230 -0
  125. package/lib/drop.mjs +282 -0
  126. package/lib/embed/approval-queue.mjs +176 -0
  127. package/lib/embed/artifact.mjs +349 -0
  128. package/lib/embed/authority-guard.mjs +155 -0
  129. package/lib/embed/cli.mjs +408 -0
  130. package/lib/embed/config.mjs +355 -0
  131. package/lib/embed/conflict-detection.mjs +264 -0
  132. package/lib/embed/customer-profiles.mjs +480 -0
  133. package/lib/embed/daemon.mjs +1309 -0
  134. package/lib/embed/demand-fetch.mjs +449 -0
  135. package/lib/embed/docs-lifecycle.mjs +349 -0
  136. package/lib/embed/inbox-live-watcher.mjs +119 -0
  137. package/lib/embed/inbox.mjs +343 -0
  138. package/lib/embed/intake-metrics.mjs +190 -0
  139. package/lib/embed/jobs/vector-sync.mjs +198 -0
  140. package/lib/embed/notifications.mjs +75 -0
  141. package/lib/embed/output.mjs +79 -0
  142. package/lib/embed/providers/github.mjs +295 -0
  143. package/lib/embed/providers/jira.mjs +192 -0
  144. package/lib/embed/providers/linear.mjs +186 -0
  145. package/lib/embed/providers/registry.mjs +115 -0
  146. package/lib/embed/providers/slack.mjs +203 -0
  147. package/lib/embed/recommendation-store.mjs +378 -0
  148. package/lib/embed/roadmap.mjs +374 -0
  149. package/lib/embed/role-framing.mjs +110 -0
  150. package/lib/embed/scheduler.mjs +99 -0
  151. package/lib/embed/semantic.mjs +325 -0
  152. package/lib/embed/snapshot.mjs +191 -0
  153. package/lib/embed/supervision.mjs +235 -0
  154. package/lib/embed/target-resolver.mjs +186 -0
  155. package/lib/embed/worker.mjs +62 -0
  156. package/lib/embed/workspaces.mjs +297 -0
  157. package/lib/engine/chunker-headings.mjs +110 -0
  158. package/lib/engine/compressor-heuristic.mjs +100 -0
  159. package/lib/engine/consolidate.mjs +287 -0
  160. package/lib/engine/contracts.mjs +126 -0
  161. package/lib/engine/defaults.mjs +129 -0
  162. package/lib/engine/eval-retrieval.mjs +148 -0
  163. package/lib/engine/fuser-rrf.mjs +62 -0
  164. package/lib/engine/index.mjs +37 -0
  165. package/lib/engine/registry.mjs +146 -0
  166. package/lib/engine/reranker-mmr.mjs +90 -0
  167. package/lib/engine/tokens.mjs +77 -0
  168. package/lib/entity-store.mjs +280 -0
  169. package/lib/env-config.mjs +69 -4
  170. package/lib/evals/retrieval-bench.mjs +159 -0
  171. package/lib/evaluator-optimizer.mjs +317 -0
  172. package/lib/features.mjs +159 -29
  173. package/lib/gates-audit.mjs +236 -0
  174. package/lib/git-hooks/prepare-commit-msg +58 -0
  175. package/lib/handoffs/cleanup.mjs +159 -0
  176. package/lib/handoffs/contract.mjs +162 -0
  177. package/lib/handoffs/inventory.mjs +120 -0
  178. package/lib/headhunt.mjs +28 -47
  179. package/lib/health-check.mjs +399 -0
  180. package/lib/hook-health.mjs +442 -0
  181. package/lib/hooks/_lib/log.mjs +82 -0
  182. package/lib/hooks/adaptive-lint.mjs +26 -2
  183. package/lib/hooks/agent-tracker.mjs +171 -14
  184. package/lib/hooks/audit-reads.mjs +109 -0
  185. package/lib/hooks/audit-trail.mjs +153 -0
  186. package/lib/hooks/bash-output-logger.mjs +71 -0
  187. package/lib/hooks/block-no-verify.mjs +41 -0
  188. package/lib/hooks/ci-status-check.mjs +82 -0
  189. package/lib/hooks/comment-lint.mjs +29 -7
  190. package/lib/hooks/config-protection.mjs +39 -18
  191. package/lib/hooks/context-watch.mjs +137 -0
  192. package/lib/hooks/context-window-recovery.mjs +4 -20
  193. package/lib/hooks/dep-audit.mjs +16 -0
  194. package/lib/hooks/doc-coupling-check.mjs +80 -0
  195. package/lib/hooks/edit-accumulator.mjs +3 -0
  196. package/lib/hooks/edit-error-recovery.mjs +3 -0
  197. package/lib/hooks/edit-guard.mjs +45 -4
  198. package/lib/hooks/env-check.mjs +3 -0
  199. package/lib/hooks/guard-bash.mjs +58 -1
  200. package/lib/hooks/mcp-audit.mjs +18 -20
  201. package/lib/hooks/mcp-health-check.mjs +36 -0
  202. package/lib/hooks/model-fallback.mjs +42 -56
  203. package/lib/hooks/policy-engine.mjs +209 -0
  204. package/lib/hooks/post-merge-docs-check.mjs +63 -0
  205. package/lib/hooks/pre-compact.mjs +4 -24
  206. package/lib/hooks/pre-push-gate.mjs +200 -37
  207. package/lib/hooks/proactive-activation.mjs +284 -0
  208. package/lib/hooks/read-tracker.mjs +27 -4
  209. package/lib/hooks/readme-age-check.mjs +77 -0
  210. package/lib/hooks/registry-sync.mjs +12 -5
  211. package/lib/hooks/scan-secrets.mjs +50 -7
  212. package/lib/hooks/session-optimize.mjs +311 -0
  213. package/lib/hooks/session-start.mjs +287 -28
  214. package/lib/hooks/stop-notify.mjs +236 -96
  215. package/lib/hooks/stop-typecheck.mjs +13 -1
  216. package/lib/hooks/test-watch.mjs +68 -0
  217. package/lib/host-capabilities.mjs +31 -10
  218. package/lib/init-docs.mjs +731 -291
  219. package/lib/init-unified.mjs +1000 -0
  220. package/lib/init-update.mjs +168 -0
  221. package/lib/init.mjs +107 -0
  222. package/lib/install/first-invocation.mjs +119 -0
  223. package/lib/install/stage-project.mjs +69 -0
  224. package/lib/intake/classify.mjs +278 -0
  225. package/lib/intake/feedback.mjs +273 -0
  226. package/lib/intake/filesystem-queue.mjs +158 -0
  227. package/lib/intake/intake-config.mjs +132 -0
  228. package/lib/intake/postgres-queue.mjs +198 -0
  229. package/lib/intake/prepare.mjs +139 -0
  230. package/lib/intake/queue.mjs +83 -0
  231. package/lib/intake/session-prelude.mjs +50 -0
  232. package/lib/integrations/intake-integrations.mjs +740 -0
  233. package/lib/intent-classifier.mjs +253 -0
  234. package/lib/knowledge/layout.mjs +72 -0
  235. package/lib/knowledge/rag.mjs +331 -0
  236. package/lib/knowledge/search.mjs +315 -0
  237. package/lib/knowledge/trends.mjs +261 -0
  238. package/lib/logger.mjs +85 -0
  239. package/lib/mcp/broker.mjs +124 -0
  240. package/lib/mcp/server.mjs +554 -854
  241. package/lib/mcp/tools/document.mjs +132 -0
  242. package/lib/mcp/tools/memory.mjs +209 -0
  243. package/lib/mcp/tools/project.mjs +349 -0
  244. package/lib/mcp/tools/skills.mjs +409 -0
  245. package/lib/mcp/tools/storage.mjs +60 -0
  246. package/lib/mcp/tools/telemetry.mjs +315 -0
  247. package/lib/mcp/tools/workflow.mjs +112 -0
  248. package/lib/mcp-catalog.json +54 -3
  249. package/lib/mcp-manager.mjs +96 -48
  250. package/lib/mcp-platform-config.mjs +22 -22
  251. package/lib/memory-stats.mjs +121 -0
  252. package/lib/mode-commands.mjs +124 -0
  253. package/lib/model-free-selector.mjs +184 -0
  254. package/lib/model-pricing.mjs +152 -0
  255. package/lib/model-registry.mjs +226 -0
  256. package/lib/model-router.mjs +362 -386
  257. package/lib/observation-store.mjs +391 -0
  258. package/lib/ollama-manager.mjs +428 -0
  259. package/lib/opencode-config.mjs +13 -3
  260. package/lib/opencode-runtime-plugin.mjs +70 -38
  261. package/lib/opencode-telemetry.mjs +64 -6
  262. package/lib/orchestration-policy.mjs +509 -6
  263. package/lib/overrides/resolver.mjs +207 -0
  264. package/lib/parity.mjs +147 -0
  265. package/lib/paths.mjs +33 -0
  266. package/lib/performance/generate.mjs +212 -0
  267. package/lib/plugin-registry.mjs +268 -0
  268. package/lib/policy/engine.mjs +130 -0
  269. package/lib/policy/unified-gates.mjs +96 -0
  270. package/lib/project-detection.mjs +129 -0
  271. package/lib/project-init-shared.mjs +272 -0
  272. package/lib/project-profile.mjs +447 -0
  273. package/lib/prompt-composer.js +434 -0
  274. package/lib/prompt-metadata.mjs +1 -1
  275. package/lib/provider-capabilities-anthropic.js +44 -0
  276. package/lib/provider-capabilities-deepseek.js +37 -0
  277. package/lib/provider-capabilities-generic.js +26 -0
  278. package/lib/provider-capabilities-google.js +47 -0
  279. package/lib/provider-capabilities-openai.js +45 -0
  280. package/lib/provider-capabilities.js +142 -0
  281. package/lib/providers/atlassian-confluence/index.mjs +103 -0
  282. package/lib/providers/atlassian-jira/index.mjs +100 -0
  283. package/lib/providers/auth-manager.mjs +126 -0
  284. package/lib/providers/circuit-breaker.mjs +124 -0
  285. package/lib/providers/contract.mjs +93 -0
  286. package/lib/providers/github/index.mjs +126 -0
  287. package/lib/providers/registry.mjs +184 -0
  288. package/lib/providers/salesforce/index.mjs +100 -0
  289. package/lib/providers/slack/index.mjs +80 -0
  290. package/lib/reflect.mjs +137 -0
  291. package/lib/research-lint.mjs +164 -0
  292. package/lib/resources/budget.mjs +259 -0
  293. package/lib/role-preload.mjs +21 -6
  294. package/lib/roles/approval-surface.mjs +54 -0
  295. package/lib/roles/cli.mjs +118 -0
  296. package/lib/roles/event-bus.mjs +79 -0
  297. package/lib/roles/fence.mjs +84 -0
  298. package/lib/roles/gateway.mjs +260 -0
  299. package/lib/roles/hook-emit.mjs +37 -0
  300. package/lib/roles/manifest.mjs +48 -0
  301. package/lib/roles/router.mjs +27 -0
  302. package/lib/runtime-pressure.mjs +360 -0
  303. package/lib/schema-artifact.mjs +134 -0
  304. package/lib/schema-infer.mjs +551 -0
  305. package/lib/server/auth.mjs +168 -0
  306. package/lib/server/chat.mjs +336 -0
  307. package/lib/server/cors.mjs +77 -0
  308. package/lib/server/csrf.mjs +91 -0
  309. package/lib/server/index.mjs +1927 -78
  310. package/lib/server/insights.mjs +765 -0
  311. package/lib/server/rate-limit.mjs +91 -0
  312. package/lib/server/static/assets/index-ab25c707.js +70 -0
  313. package/lib/server/static/assets/index-f0c80a2b.css +1 -0
  314. package/lib/server/static/index.html +12 -817
  315. package/lib/server/telemetry-login.mjs +108 -0
  316. package/lib/server/webhook.mjs +510 -0
  317. package/lib/service-manager.mjs +522 -58
  318. package/lib/services/pattern-promotion-service.mjs +167 -0
  319. package/lib/services/telemetry-backend.mjs +178 -0
  320. package/lib/session-store.mjs +374 -0
  321. package/lib/setup-prompts.mjs +96 -0
  322. package/lib/setup.mjs +523 -36
  323. package/lib/skills-apply.mjs +280 -0
  324. package/lib/skills-scope.mjs +118 -0
  325. package/lib/status.mjs +261 -70
  326. package/lib/storage/admin.mjs +355 -0
  327. package/lib/storage/backend.mjs +2 -1
  328. package/lib/storage/backup.mjs +347 -0
  329. package/lib/storage/embeddings-engine.mjs +133 -0
  330. package/lib/storage/embeddings-legacy.mjs +85 -0
  331. package/lib/storage/embeddings-local.mjs +108 -0
  332. package/lib/storage/embeddings-ollama.mjs +78 -0
  333. package/lib/storage/embeddings-openai.mjs +85 -0
  334. package/lib/storage/embeddings.mjs +92 -33
  335. package/lib/storage/file-lock.mjs +130 -0
  336. package/lib/storage/fusion.mjs +95 -0
  337. package/lib/storage/hybrid-query.mjs +34 -27
  338. package/lib/storage/migrations.mjs +187 -0
  339. package/lib/storage/postgres-backup.mjs +124 -0
  340. package/lib/storage/sql-store.mjs +5 -15
  341. package/lib/storage/state-source.mjs +12 -13
  342. package/lib/storage/store-version.mjs +115 -0
  343. package/lib/storage/sync.mjs +144 -35
  344. package/lib/storage/unified-storage.mjs +550 -0
  345. package/lib/storage/vector-client.mjs +286 -0
  346. package/lib/storage/vector-store.mjs +71 -30
  347. package/lib/task-graph/generate.mjs +135 -0
  348. package/lib/task-graph/schema.mjs +81 -0
  349. package/lib/task-graph/store.mjs +71 -0
  350. package/lib/telemetry/backends/local.mjs +62 -0
  351. package/lib/telemetry/backends/{langfuse.mjs → remote.mjs} +27 -14
  352. package/lib/telemetry/backfill.mjs +180 -0
  353. package/lib/telemetry/eval-datasets.mjs +203 -0
  354. package/lib/telemetry/{langfuse-ingest.mjs → ingest.mjs} +26 -20
  355. package/lib/telemetry/intent-verifications.mjs +86 -0
  356. package/lib/telemetry/llm-judge.mjs +350 -0
  357. package/lib/telemetry/model-pricing-catalog.mjs +557 -0
  358. package/lib/telemetry/setup.mjs +151 -0
  359. package/lib/telemetry/skill-calls.mjs +78 -0
  360. package/lib/telemetry/team-rollup.mjs +4 -4
  361. package/lib/token-engine.js +117 -0
  362. package/lib/token-estimator-anthropic.js +15 -0
  363. package/lib/token-estimator-deepseek.js +13 -0
  364. package/lib/token-estimator-default.js +13 -0
  365. package/lib/token-estimator-google.js +13 -0
  366. package/lib/token-estimator-openai.js +13 -0
  367. package/lib/toolkit-env.mjs +1 -1
  368. package/lib/tty-prompts.mjs +211 -0
  369. package/lib/uninstall/uninstall.mjs +423 -0
  370. package/lib/update.mjs +115 -0
  371. package/lib/upgrade.mjs +141 -0
  372. package/lib/validator.mjs +51 -2
  373. package/lib/validators/skills.mjs +142 -0
  374. package/lib/wireframe.mjs +422 -0
  375. package/lib/worker/entrypoint.mjs +241 -0
  376. package/lib/worker/evidence.mjs +107 -0
  377. package/lib/worker/run.mjs +154 -0
  378. package/lib/worker/trace.mjs +182 -0
  379. package/lib/workflow-state.mjs +14 -18
  380. package/package.json +21 -8
  381. package/personas/construct.md +53 -51
  382. package/platforms/claude/CLAUDE.md +1 -1
  383. package/platforms/claude/settings.template.json +115 -68
  384. package/platforms/opencode/config.template.json +3 -7
  385. package/rules/common/agents.md +11 -38
  386. package/rules/common/beads-hygiene.md +75 -0
  387. package/rules/common/code-review.md +11 -100
  388. package/rules/common/coding-style.md +5 -3
  389. package/rules/common/comments.md +30 -111
  390. package/rules/common/commit-approval.md +53 -0
  391. package/rules/common/cx-agent-routing.md +1 -0
  392. package/rules/common/development-workflow.md +23 -41
  393. package/rules/common/doc-ownership.md +54 -0
  394. package/rules/common/efficiency.md +57 -0
  395. package/rules/common/framing.md +76 -0
  396. package/rules/common/git-workflow.md +2 -4
  397. package/rules/common/patterns.md +3 -7
  398. package/rules/common/performance.md +15 -31
  399. package/rules/common/release-gates.md +69 -0
  400. package/rules/common/research.md +107 -0
  401. package/rules/common/security.md +6 -6
  402. package/rules/common/skill-composition.md +67 -0
  403. package/rules/common/testing.md +15 -27
  404. package/rules/golang/hooks.md +0 -4
  405. package/rules/policy/bootstrap.yaml +11 -0
  406. package/rules/policy/drive.yaml +8 -0
  407. package/rules/policy/task.yaml +9 -0
  408. package/rules/policy/workflow.yaml +9 -0
  409. package/rules/python/hooks.md +0 -4
  410. package/rules/swift/hooks.md +0 -4
  411. package/rules/typescript/hooks.md +0 -4
  412. package/rules/web/hooks.md +0 -2
  413. package/{sync-agents.mjs → scripts/sync-agents.mjs} +306 -61
  414. package/skills/ai/prompt-optimizer.md +7 -7
  415. package/skills/compliance/ai-disclosure.md +58 -0
  416. package/skills/compliance/data-privacy.md +46 -0
  417. package/skills/compliance/license-audit.md +40 -0
  418. package/skills/compliance/regulatory-review.md +61 -0
  419. package/skills/docs/document-ingest-workflow.md +52 -0
  420. package/skills/docs/evidence-ingest-workflow.md +9 -0
  421. package/skills/docs/init-docs.md +51 -18
  422. package/skills/docs/product-intelligence-workflow.md +12 -0
  423. package/skills/docs/product-signal-workflow.md +4 -0
  424. package/skills/docs/research-workflow.md +23 -8
  425. package/skills/docs/runbook-workflow.md +1 -1
  426. package/skills/operating/orchestration-reference.md +151 -0
  427. package/skills/roles/architect.md +5 -0
  428. package/skills/roles/engineer.md +32 -0
  429. package/skills/roles/operator.md +12 -0
  430. package/skills/roles/reviewer.md +23 -0
  431. package/skills/routing.md +1 -1
  432. package/templates/devcontainer/Dockerfile.devcontainer +38 -0
  433. package/templates/devcontainer/devcontainer.json +31 -0
  434. package/templates/distribution/bootstrap.ps1 +142 -0
  435. package/templates/distribution/bootstrap.sh +196 -0
  436. package/templates/distribution/run.mjs +187 -0
  437. package/templates/docs/adr.md +44 -8
  438. package/templates/docs/changelog-entry.md +43 -0
  439. package/templates/docs/construct_guide.md +149 -0
  440. package/templates/docs/evidence-brief.md +2 -2
  441. package/templates/docs/meta-prd.md +140 -19
  442. package/templates/docs/onboarding.md +57 -0
  443. package/templates/docs/prd.md +159 -15
  444. package/templates/docs/research-brief.md +4 -4
  445. package/templates/homebrew/construct.rb +67 -0
  446. package/langfuse/docker-compose.yml +0 -82
  447. package/lib/eval-harness.mjs +0 -59
  448. package/lib/hooks/bootstrap-guard.mjs +0 -90
  449. package/lib/hooks/console-warn.mjs +0 -43
  450. package/lib/hooks/continuation-enforcer.mjs +0 -72
  451. package/lib/hooks/drive-guard.mjs +0 -89
  452. package/lib/hooks/mcp-task-scope.mjs +0 -47
  453. package/lib/hooks/task-completed-guard.mjs +0 -43
  454. package/lib/hooks/teammate-idle-guard.mjs +0 -54
  455. package/lib/hooks/workflow-guard.mjs +0 -62
  456. package/lib/prompt-composer.mjs +0 -196
  457. package/lib/review.mjs +0 -429
  458. package/lib/server/static/app.js +0 -841
  459. package/lib/telemetry/langfuse-model-sync.mjs +0 -270
  460. package/rules/common/hooks.md +0 -35
  461. package/rules/zh/README.md +0 -113
  462. package/rules/zh/agents.md +0 -55
  463. package/rules/zh/code-review.md +0 -129
  464. package/rules/zh/coding-style.md +0 -53
  465. package/rules/zh/development-workflow.md +0 -49
  466. package/rules/zh/git-workflow.md +0 -29
  467. package/rules/zh/hooks.md +0 -35
  468. package/rules/zh/patterns.md +0 -36
  469. package/rules/zh/performance.md +0 -60
  470. package/rules/zh/security.md +0 -34
  471. package/rules/zh/testing.md +0 -34
@@ -0,0 +1,235 @@
1
+ /**
2
+ * lib/embed/supervision.mjs — platform supervisor integration for the embed daemon.
3
+ *
4
+ * Writes a platform service file so the embed daemon is automatically
5
+ * restarted with exponential backoff if it crashes, and started on login/boot.
6
+ *
7
+ * Platform support:
8
+ * macOS — launchd plist at ~/Library/LaunchAgents/com.construct.embed.plist
9
+ * Linux — systemd user unit at ~/.config/systemd/user/construct-embed.service
10
+ * Windows — Task Scheduler (schtasks) entry named "Construct.Embed"
11
+ *
12
+ * Usage:
13
+ * import { installSupervision, uninstallSupervision, supervisionStatus } from './supervision.mjs';
14
+ * await installSupervision();
15
+ * await uninstallSupervision();
16
+ * const info = await supervisionStatus();
17
+ */
18
+
19
+ import fs from 'node:fs';
20
+ import os from 'node:os';
21
+ import path from 'node:path';
22
+ import { spawnSync } from 'node:child_process';
23
+
24
+ const HOME = os.homedir();
25
+ const PLATFORM = process.platform;
26
+ const NODE_BIN = process.execPath;
27
+
28
+ // Path to the construct bin — we use absolute path so launchd/systemd can find it.
29
+ function constructBin() {
30
+ const local = path.join(HOME, '.construct', 'bin', 'construct');
31
+ if (fs.existsSync(local)) return local;
32
+ const result = spawnSync('which', ['construct'], { encoding: 'utf8' });
33
+ return result.status === 0 ? result.stdout.trim() : 'construct';
34
+ }
35
+
36
+ // ── macOS launchd ───────────────────────────────────────────────────────────
37
+
38
+ const LAUNCHD_LABEL = 'com.construct.embed';
39
+ const LAUNCHD_PLIST = path.join(HOME, 'Library', 'LaunchAgents', `${LAUNCHD_LABEL}.plist`);
40
+
41
+ function launchdPlist(bin, logPath) {
42
+ return `<?xml version="1.0" encoding="UTF-8"?>
43
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
44
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
45
+ <plist version="1.0">
46
+ <dict>
47
+ <key>Label</key>
48
+ <string>${LAUNCHD_LABEL}</string>
49
+ <key>ProgramArguments</key>
50
+ <array>
51
+ <string>${NODE_BIN}</string>
52
+ <string>${bin}</string>
53
+ <string>embed</string>
54
+ <string>start</string>
55
+ <string>--foreground</string>
56
+ </array>
57
+ <key>RunAtLoad</key>
58
+ <true/>
59
+ <key>KeepAlive</key>
60
+ <dict>
61
+ <key>Crashed</key>
62
+ <true/>
63
+ </dict>
64
+ <key>ThrottleInterval</key>
65
+ <integer>10</integer>
66
+ <key>StandardOutPath</key>
67
+ <string>${logPath}</string>
68
+ <key>StandardErrorPath</key>
69
+ <string>${logPath}</string>
70
+ <key>EnvironmentVariables</key>
71
+ <dict>
72
+ <key>HOME</key>
73
+ <string>${HOME}</string>
74
+ </dict>
75
+ </dict>
76
+ </plist>
77
+ `;
78
+ }
79
+
80
+ async function installLaunchd(bin, logPath) {
81
+ fs.mkdirSync(path.dirname(LAUNCHD_PLIST), { recursive: true });
82
+ fs.writeFileSync(LAUNCHD_PLIST, launchdPlist(bin, logPath));
83
+ const load = spawnSync('launchctl', ['load', '-w', LAUNCHD_PLIST], { encoding: 'utf8' });
84
+ if (load.status !== 0) {
85
+ throw new Error(`launchctl load failed: ${load.stderr}`);
86
+ }
87
+ return { method: 'launchd', file: LAUNCHD_PLIST };
88
+ }
89
+
90
+ async function uninstallLaunchd() {
91
+ if (!fs.existsSync(LAUNCHD_PLIST)) return { method: 'launchd', wasInstalled: false };
92
+ spawnSync('launchctl', ['unload', '-w', LAUNCHD_PLIST], { encoding: 'utf8' });
93
+ fs.rmSync(LAUNCHD_PLIST, { force: true });
94
+ return { method: 'launchd', wasInstalled: true };
95
+ }
96
+
97
+ function launchdStatus() {
98
+ if (!fs.existsSync(LAUNCHD_PLIST)) return { installed: false };
99
+ const result = spawnSync('launchctl', ['list', LAUNCHD_LABEL], { encoding: 'utf8' });
100
+ return {
101
+ installed: true,
102
+ active: result.status === 0,
103
+ file: LAUNCHD_PLIST,
104
+ };
105
+ }
106
+
107
+ // ── Linux systemd ───────────────────────────────────────────────────────────
108
+
109
+ const SYSTEMD_UNIT_NAME = 'construct-embed.service';
110
+ const SYSTEMD_UNIT_DIR = path.join(HOME, '.config', 'systemd', 'user');
111
+ const SYSTEMD_UNIT_FILE = path.join(SYSTEMD_UNIT_DIR, SYSTEMD_UNIT_NAME);
112
+
113
+ function systemdUnit(bin, logPath) {
114
+ return `[Unit]
115
+ Description=Construct embed daemon
116
+ After=network.target
117
+
118
+ [Service]
119
+ Type=simple
120
+ ExecStart=${NODE_BIN} ${bin} embed start --foreground
121
+ Restart=on-failure
122
+ RestartSec=10
123
+ RestartMaxDelay=300
124
+ StandardOutput=append:${logPath}
125
+ StandardError=append:${logPath}
126
+ Environment=HOME=${HOME}
127
+
128
+ [Install]
129
+ WantedBy=default.target
130
+ `;
131
+ }
132
+
133
+ async function installSystemd(bin, logPath) {
134
+ fs.mkdirSync(SYSTEMD_UNIT_DIR, { recursive: true });
135
+ fs.writeFileSync(SYSTEMD_UNIT_FILE, systemdUnit(bin, logPath));
136
+
137
+ const reload = spawnSync('systemctl', ['--user', 'daemon-reload'], { encoding: 'utf8' });
138
+ if (reload.status !== 0) throw new Error(`daemon-reload failed: ${reload.stderr}`);
139
+
140
+ const enable = spawnSync('systemctl', ['--user', 'enable', '--now', SYSTEMD_UNIT_NAME], { encoding: 'utf8' });
141
+ if (enable.status !== 0) throw new Error(`systemctl enable failed: ${enable.stderr}`);
142
+
143
+ return { method: 'systemd', file: SYSTEMD_UNIT_FILE };
144
+ }
145
+
146
+ async function uninstallSystemd() {
147
+ if (!fs.existsSync(SYSTEMD_UNIT_FILE)) return { method: 'systemd', wasInstalled: false };
148
+ spawnSync('systemctl', ['--user', 'disable', '--now', SYSTEMD_UNIT_NAME], { encoding: 'utf8' });
149
+ fs.rmSync(SYSTEMD_UNIT_FILE, { force: true });
150
+ spawnSync('systemctl', ['--user', 'daemon-reload'], { encoding: 'utf8' });
151
+ return { method: 'systemd', wasInstalled: true };
152
+ }
153
+
154
+ function systemdStatus() {
155
+ if (!fs.existsSync(SYSTEMD_UNIT_FILE)) return { installed: false };
156
+ const result = spawnSync('systemctl', ['--user', 'is-active', SYSTEMD_UNIT_NAME], { encoding: 'utf8' });
157
+ return {
158
+ installed: true,
159
+ active: result.stdout.trim() === 'active',
160
+ file: SYSTEMD_UNIT_FILE,
161
+ };
162
+ }
163
+
164
+ // ── Windows Task Scheduler ──────────────────────────────────────────────────
165
+
166
+ const WIN_TASK_NAME = 'Construct.Embed';
167
+
168
+ async function installWindows(bin, logPath) {
169
+ const cmd = [
170
+ 'schtasks', '/Create', '/F',
171
+ '/TN', WIN_TASK_NAME,
172
+ '/TR', `"${NODE_BIN}" "${bin}" embed start --foreground >> "${logPath}" 2>&1`,
173
+ '/SC', 'ONLOGON',
174
+ '/RL', 'HIGHEST',
175
+ ].join(' ');
176
+ const result = spawnSync('cmd', ['/c', cmd], { encoding: 'utf8' });
177
+ if (result.status !== 0) throw new Error(`schtasks failed: ${result.stderr}`);
178
+ return { method: 'task-scheduler', taskName: WIN_TASK_NAME };
179
+ }
180
+
181
+ async function uninstallWindows() {
182
+ const result = spawnSync('schtasks', ['/Query', '/TN', WIN_TASK_NAME], { encoding: 'utf8' });
183
+ if (result.status !== 0) return { method: 'task-scheduler', wasInstalled: false };
184
+ spawnSync('schtasks', ['/Delete', '/TN', WIN_TASK_NAME, '/F'], { encoding: 'utf8' });
185
+ return { method: 'task-scheduler', wasInstalled: true };
186
+ }
187
+
188
+ function windowsStatus() {
189
+ const result = spawnSync('schtasks', ['/Query', '/TN', WIN_TASK_NAME, '/FO', 'CSV'], { encoding: 'utf8' });
190
+ if (result.status !== 0) return { installed: false };
191
+ const running = result.stdout.includes('Running');
192
+ return { installed: true, active: running, taskName: WIN_TASK_NAME };
193
+ }
194
+
195
+ // ── Public API ──────────────────────────────────────────────────────────────
196
+
197
+ function logPath() {
198
+ return path.join(HOME, '.cx', 'runtime', 'embed-daemon.log');
199
+ }
200
+
201
+ /**
202
+ * Install the platform supervisor so the embed daemon auto-restarts on crash.
203
+ */
204
+ export async function installSupervision() {
205
+ const bin = constructBin();
206
+ const log = logPath();
207
+ fs.mkdirSync(path.dirname(log), { recursive: true });
208
+
209
+ if (PLATFORM === 'darwin') return installLaunchd(bin, log);
210
+ if (PLATFORM === 'linux') return installSystemd(bin, log);
211
+ if (PLATFORM === 'win32') return installWindows(bin, log);
212
+ throw new Error(`supervision not supported on platform: ${PLATFORM}`);
213
+ }
214
+
215
+ /**
216
+ * Remove the platform supervisor entry. Does not stop a currently-running daemon.
217
+ */
218
+ export async function uninstallSupervision() {
219
+ if (PLATFORM === 'darwin') return uninstallLaunchd();
220
+ if (PLATFORM === 'linux') return uninstallSystemd();
221
+ if (PLATFORM === 'win32') return uninstallWindows();
222
+ throw new Error(`supervision not supported on platform: ${PLATFORM}`);
223
+ }
224
+
225
+ /**
226
+ * Check whether the supervisor is installed and active.
227
+ *
228
+ * @returns {{ installed: boolean, active?: boolean, method?: string, file?: string }}
229
+ */
230
+ export function supervisionStatus() {
231
+ if (PLATFORM === 'darwin') return { method: 'launchd', ...launchdStatus() };
232
+ if (PLATFORM === 'linux') return { method: 'systemd', ...systemdStatus() };
233
+ if (PLATFORM === 'win32') return { method: 'task-scheduler', ...windowsStatus() };
234
+ return { installed: false, method: 'unsupported' };
235
+ }
@@ -0,0 +1,186 @@
1
+ /**
2
+ * lib/embed/target-resolver.mjs — target discovery and routing for embed mode.
3
+ *
4
+ * Resolution order:
5
+ * 1. Explicit targets from config (targets[])
6
+ * 2. Provider-linked discovery (e.g., Jira issue references a GitHub repo)
7
+ * 3. Broadened search if nothing actionable matched
8
+ * 4. Workspace fallback (~/.construct/workspace) — always present
9
+ *
10
+ * Each resolved target is a normalized object:
11
+ * { type, ref?, path?, access, provider?, docs? }
12
+ *
13
+ * access:
14
+ * - 'local' → filesystem path exists, read/write via fs
15
+ * - 'remote' → interact via provider API only
16
+ * - 'hybrid' → local clone exists AND remote provider available
17
+ */
18
+
19
+ import fs from 'node:fs';
20
+ import path from 'node:path';
21
+ import { DEFAULT_WORKSPACE_PATH, WORKSPACE_DOCS_LANES } from './config.mjs';
22
+
23
+ /**
24
+ * Resolve all actionable targets for this embed cycle.
25
+ *
26
+ * @param {object} config - Parsed embed config (from loadEmbedConfig/normalize)
27
+ * @param {object} providerRegistry - ProviderRegistry instance for remote lookups
28
+ * @param {object} [opts]
29
+ * @param {object[]} [opts.signals] - Signals from sources (issues, PRs, etc.) that may reference repos
30
+ * @returns {Promise<ResolvedTarget[]>}
31
+ */
32
+ export async function resolveTargets(config, providerRegistry, opts = {}) {
33
+ const resolved = [];
34
+ const seen = new Set();
35
+
36
+ // Phase 1: Explicit targets from config
37
+ for (const t of config.targets ?? []) {
38
+ const rt = resolveExplicit(t);
39
+ const key = targetKey(rt);
40
+ if (!seen.has(key)) {
41
+ seen.add(key);
42
+ resolved.push(rt);
43
+ }
44
+ }
45
+
46
+ // Phase 2: Provider-linked discovery from source signals
47
+ if (opts.signals?.length) {
48
+ const discovered = discoverFromSignals(opts.signals, providerRegistry);
49
+ for (const rt of discovered) {
50
+ const key = targetKey(rt);
51
+ if (!seen.has(key)) {
52
+ seen.add(key);
53
+ resolved.push(rt);
54
+ }
55
+ }
56
+ }
57
+
58
+ // Phase 3: Ensure workspace fallback
59
+ const hasWorkspace = resolved.some((t) => t.type === 'workspace');
60
+ if (!hasWorkspace) {
61
+ resolved.push({
62
+ type: 'workspace',
63
+ path: DEFAULT_WORKSPACE_PATH,
64
+ access: 'local',
65
+ docs: WORKSPACE_DOCS_LANES,
66
+ });
67
+ }
68
+
69
+ return resolved;
70
+ }
71
+
72
+ /**
73
+ * Resolve a single explicit target config entry into a normalized target.
74
+ */
75
+ function resolveExplicit(target) {
76
+ if (target.type === 'workspace') {
77
+ return {
78
+ type: 'workspace',
79
+ path: target.path ?? DEFAULT_WORKSPACE_PATH,
80
+ access: 'local',
81
+ docs: WORKSPACE_DOCS_LANES,
82
+ };
83
+ }
84
+
85
+ // type: repo
86
+ const hasLocal = target.path && fs.existsSync(target.path);
87
+ const hasRemote = !!target.ref;
88
+
89
+ let access = 'remote';
90
+ if (hasLocal && hasRemote) access = 'hybrid';
91
+ else if (hasLocal) access = 'local';
92
+
93
+ return {
94
+ type: target.type,
95
+ ref: target.ref ?? null,
96
+ path: hasLocal ? target.path : null,
97
+ access,
98
+ provider: target.provider ?? inferProvider(target.ref),
99
+ docs: target.docs ?? null,
100
+ };
101
+ }
102
+
103
+ /**
104
+ * Extract repo references from source signals (issues, PRs, commits that mention repos).
105
+ */
106
+ function discoverFromSignals(signals, _providerRegistry) {
107
+ const discovered = [];
108
+ const repoPattern = /(?:github\.com|gitlab\.com)[/:]([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)/g;
109
+
110
+ for (const signal of signals) {
111
+ const text = signal.body ?? signal.description ?? signal.title ?? '';
112
+ let match;
113
+ while ((match = repoPattern.exec(text)) !== null) {
114
+ const ref = match[0].replace(/^(github\.com|gitlab\.com)[/:]/, '$1/');
115
+ discovered.push({
116
+ type: 'repo',
117
+ ref,
118
+ path: null,
119
+ access: 'remote',
120
+ provider: ref.startsWith('github') ? 'github' : 'gitlab',
121
+ docs: null,
122
+ discoveredFrom: signal.id ?? signal.url ?? 'signal',
123
+ });
124
+ }
125
+ }
126
+
127
+ return discovered;
128
+ }
129
+
130
+ /**
131
+ * Infer provider from a ref string.
132
+ */
133
+ function inferProvider(ref) {
134
+ if (!ref) return null;
135
+ if (ref.includes('github.com') || ref.includes('github:')) return 'github';
136
+ if (ref.includes('gitlab.com') || ref.includes('gitlab:')) return 'gitlab';
137
+ if (ref.includes('bitbucket')) return 'bitbucket';
138
+ return null;
139
+ }
140
+
141
+ /**
142
+ * Deduplication key for a target.
143
+ */
144
+ function targetKey(t) {
145
+ if (t.type === 'workspace') return 'workspace:' + (t.path ?? 'default');
146
+ return `${t.type}:${t.ref ?? ''}:${t.path ?? ''}`;
147
+ }
148
+
149
+ /**
150
+ * Given resolved targets and an artifact type, determine where to route output.
151
+ *
152
+ * Routing logic:
153
+ * - If a target has a matching docs lane, route there
154
+ * - If no specific target matches, route to workspace
155
+ *
156
+ * @param {ResolvedTarget[]} targets
157
+ * @param {string} artifactType - e.g. 'adrs', 'prds', 'memos', 'notes', 'intake'
158
+ * @returns {ResolvedTarget}
159
+ */
160
+ export function routeArtifact(targets, artifactType) {
161
+ // Prefer non-workspace target with matching docs lane
162
+ for (const t of targets) {
163
+ if (t.type === 'workspace') continue;
164
+ if (t.access === 'local' || t.access === 'hybrid') {
165
+ // Local targets can receive docs directly
166
+ return t;
167
+ }
168
+ }
169
+
170
+ // Fall back to workspace
171
+ const workspace = targets.find((t) => t.type === 'workspace');
172
+ return workspace ?? { type: 'workspace', path: DEFAULT_WORKSPACE_PATH, access: 'local', docs: WORKSPACE_DOCS_LANES };
173
+ }
174
+
175
+ /**
176
+ * Resolve the filesystem path for writing an artifact to a target.
177
+ *
178
+ * @param {ResolvedTarget} target
179
+ * @param {string} artifactType - docs lane (adrs, prds, memos, notes, intake)
180
+ * @param {string} filename
181
+ * @returns {string} Absolute file path
182
+ */
183
+ export function resolveArtifactPath(target, artifactType, filename) {
184
+ const base = target.path ?? DEFAULT_WORKSPACE_PATH;
185
+ return path.join(base, 'docs', artifactType, filename);
186
+ }
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * lib/embed/worker.mjs — Long-running embed daemon worker.
4
+ *
5
+ * Spawned detached by `construct embed start`. Runs until SIGTERM.
6
+ * Reads --config <path> from argv, or auto-discovers sources from config.env.
7
+ */
8
+
9
+ import os from 'node:os';
10
+ import path from 'node:path';
11
+ import { loadConstructEnv } from '../env-config.mjs';
12
+ import { EmbedDaemon } from './daemon.mjs';
13
+
14
+ function parseArgv(argv) {
15
+ for (let i = 0; i < argv.length; i++) {
16
+ if (argv[i] === '--config' && argv[i + 1]) return argv[i + 1];
17
+ }
18
+ return null;
19
+ }
20
+
21
+ const configPath = parseArgv(process.argv.slice(2));
22
+ const env = loadConstructEnv();
23
+
24
+ // If no config file, build an auto-discovered config inline and inject it
25
+ let daemonOpts = { env };
26
+ if (configPath) {
27
+ daemonOpts.configPath = configPath;
28
+ } else {
29
+ const { ProviderRegistry } = await import('./providers/registry.mjs');
30
+ const { EMPTY_CONFIG } = await import('./config.mjs');
31
+ const registry = await ProviderRegistry.fromEnv(env);
32
+ const sources = registry.autoSources(env);
33
+ daemonOpts.registry = registry;
34
+ daemonOpts.config = {
35
+ ...EMPTY_CONFIG,
36
+ sources,
37
+ // Default snapshot sink so operators always have a current markdown copy on disk.
38
+ outputs: [{ type: 'markdown', path: '.cx/snapshot.md' }],
39
+ };
40
+ }
41
+
42
+ const daemon = new EmbedDaemon(daemonOpts);
43
+
44
+ process.on('SIGTERM', () => {
45
+ daemon.stop();
46
+ process.exit(0);
47
+ });
48
+
49
+ process.on('SIGINT', () => {
50
+ daemon.stop();
51
+ process.exit(0);
52
+ });
53
+
54
+ process.on('uncaughtException', (err) => {
55
+ process.stderr.write(`[embed/worker] uncaughtException: ${err.message}\n${err.stack}\n`);
56
+ });
57
+
58
+ process.on('unhandledRejection', (reason) => {
59
+ process.stderr.write(`[embed/worker] unhandledRejection: ${reason}\n`);
60
+ });
61
+
62
+ await daemon.start();