@geraldmaron/construct 1.2.1 → 1.2.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 (198) hide show
  1. package/README.md +6 -6
  2. package/bin/construct +41 -67
  3. package/commands/plan/decide.md +1 -1
  4. package/commands/remember/runbook.md +1 -1
  5. package/examples/README.md +1 -1
  6. package/examples/distribution/README.md +1 -1
  7. package/examples/distribution/sources/adr.md +2 -2
  8. package/examples/distribution/sources/deck-one-pager.md +1 -1
  9. package/examples/distribution/sources/prd-platform.md +1 -1
  10. package/examples/distribution/sources/research-brief.md +2 -2
  11. package/examples/distribution/sources/rfc-platform.md +1 -1
  12. package/examples/distribution/sources/runbook.md +2 -2
  13. package/examples/distribution/sources/strategy.md +1 -1
  14. package/lib/agent-instructions/inject.mjs +1 -1
  15. package/lib/artifact-type-from-path.mjs +9 -5
  16. package/lib/audit-specialists.mjs +1 -1
  17. package/lib/audit-trail.mjs +3 -3
  18. package/lib/auto-docs.mjs +10 -10
  19. package/lib/bootstrap/built-ins.mjs +3 -3
  20. package/lib/boundary.mjs +3 -2
  21. package/lib/brand-prose.mjs +1 -1
  22. package/lib/cache-governor.js +4 -4
  23. package/lib/certification/document-io-fixtures.mjs +1 -1
  24. package/lib/chat/config.mjs +2 -2
  25. package/lib/chat/desktop-binary.mjs +5 -3
  26. package/lib/cli-commands.mjs +3 -3
  27. package/lib/cli-service-inventory.mjs +1 -1
  28. package/lib/comment-lint.mjs +9 -5
  29. package/lib/config/alias.mjs +3 -2
  30. package/lib/config/intake-policy.mjs +8 -78
  31. package/lib/config/project-config.mjs +95 -5
  32. package/lib/config/schema.mjs +9 -19
  33. package/lib/config/xdg.mjs +63 -0
  34. package/lib/contracts/violation-log.mjs +2 -2
  35. package/lib/cost-ledger.mjs +4 -3
  36. package/lib/cost.mjs +3 -2
  37. package/lib/decisions/registry.mjs +3 -3
  38. package/lib/distill.mjs +2 -2
  39. package/lib/docs-verify.mjs +2 -0
  40. package/lib/doctor/audit.mjs +4 -3
  41. package/lib/doctor/cli.mjs +0 -1
  42. package/lib/doctor/index.mjs +4 -4
  43. package/lib/doctor/report.mjs +3 -3
  44. package/lib/doctor/watchers/bd-watch.mjs +5 -5
  45. package/lib/doctor/watchers/cost.mjs +4 -4
  46. package/lib/doctor/watchers/disk.mjs +4 -3
  47. package/lib/doctor/watchers/service-health.mjs +5 -5
  48. package/lib/document-export.mjs +1 -1
  49. package/lib/document-extract.mjs +3 -3
  50. package/lib/document-ingest.mjs +13 -3
  51. package/lib/efficiency.mjs +2 -1
  52. package/lib/embed/approval-queue.mjs +3 -2
  53. package/lib/embed/cli.mjs +7 -5
  54. package/lib/embed/config.mjs +6 -5
  55. package/lib/embed/daemon.mjs +6 -5
  56. package/lib/embed/inbox-live-watcher.mjs +1 -1
  57. package/lib/embed/inbox.mjs +52 -37
  58. package/lib/embed/intake-metrics.mjs +3 -2
  59. package/lib/embed/reconcile.mjs +1 -1
  60. package/lib/embed/semantic.mjs +3 -2
  61. package/lib/embed/supervision.mjs +4 -2
  62. package/lib/engine/registry.mjs +3 -3
  63. package/lib/env-config.mjs +34 -12
  64. package/lib/features.mjs +4 -3
  65. package/lib/health-check.mjs +7 -6
  66. package/lib/hook-health.mjs +5 -4
  67. package/lib/hooks/_lib/log.mjs +4 -3
  68. package/lib/hooks/_lib/output-mode.mjs +2 -1
  69. package/lib/hooks/agent-tracker.mjs +3 -4
  70. package/lib/hooks/audit-reads.mjs +2 -2
  71. package/lib/hooks/audit-trail.mjs +2 -2
  72. package/lib/hooks/bash-output-logger.mjs +3 -3
  73. package/lib/hooks/brand-prose-lint.mjs +1 -1
  74. package/lib/hooks/ci-status-check.mjs +3 -2
  75. package/lib/hooks/context-watch.mjs +2 -2
  76. package/lib/hooks/context-window-recovery.mjs +5 -5
  77. package/lib/hooks/dep-audit.mjs +2 -2
  78. package/lib/hooks/doc-coupling-check.mjs +3 -2
  79. package/lib/hooks/edit-accumulator.mjs +3 -2
  80. package/lib/hooks/edit-guard.mjs +3 -3
  81. package/lib/hooks/guard-bash.mjs +2 -2
  82. package/lib/hooks/model-fallback.mjs +2 -1
  83. package/lib/hooks/policy-engine.mjs +4 -3
  84. package/lib/hooks/pre-compact.mjs +7 -7
  85. package/lib/hooks/readme-age-check.mjs +2 -2
  86. package/lib/hooks/session-optimize.mjs +4 -3
  87. package/lib/hooks/session-start.mjs +6 -5
  88. package/lib/hooks/stop-notify.mjs +9 -8
  89. package/lib/hooks/stop-typecheck.mjs +4 -3
  90. package/lib/hooks/test-watch.mjs +2 -2
  91. package/lib/host-disposition.mjs +1 -1
  92. package/lib/ingest/provider-extract.mjs +2 -1
  93. package/lib/init/detect-existing-structure.mjs +2 -2
  94. package/lib/init/doc-lanes.mjs +3 -10
  95. package/lib/init-docs.mjs +12 -54
  96. package/lib/init-unified.mjs +35 -81
  97. package/lib/init.mjs +7 -5
  98. package/lib/install/desktop-binary-download.mjs +5 -2
  99. package/lib/intake/daemon.mjs +31 -8
  100. package/lib/intake/intake-config.mjs +5 -32
  101. package/lib/integrations/intake-integrations.mjs +8 -7
  102. package/lib/knowledge/rag.mjs +2 -2
  103. package/lib/knowledge/search.mjs +15 -15
  104. package/lib/maintenance/cleanup.mjs +14 -10
  105. package/lib/mcp/server.mjs +1 -1
  106. package/lib/mcp/tools/project.mjs +2 -1
  107. package/lib/model-cheapest-provider.mjs +4 -3
  108. package/lib/model-pricing.mjs +3 -2
  109. package/lib/model-router.mjs +4 -3
  110. package/lib/models/catalog.mjs +2 -1
  111. package/lib/models/execution-capability-profile.mjs +2 -1
  112. package/lib/models/provider-poll.mjs +2 -1
  113. package/lib/ollama-manager.mjs +0 -1
  114. package/lib/op-log.mjs +2 -1
  115. package/lib/opencode-runtime-plugin.mjs +3 -2
  116. package/lib/oracle/artifact-gate.mjs +3 -0
  117. package/lib/oracle/cli.mjs +2 -1
  118. package/lib/oracle/execute.mjs +3 -2
  119. package/lib/oracle/index.mjs +2 -1
  120. package/lib/oracle/read-model.mjs +3 -2
  121. package/lib/performance/generate.mjs +4 -3
  122. package/lib/platforms/capabilities.mjs +1 -1
  123. package/lib/plugin-registry.mjs +2 -1
  124. package/lib/profiles/lifecycle.mjs +3 -3
  125. package/lib/project-profile.mjs +2 -1
  126. package/lib/project-root.mjs +9 -7
  127. package/lib/provider-capabilities.js +4 -3
  128. package/lib/providers/auth-manager.mjs +2 -1
  129. package/lib/providers/copilot-auth.mjs +3 -2
  130. package/lib/providers/creds.mjs +3 -2
  131. package/lib/providers/registry.mjs +3 -3
  132. package/lib/providers/secret-resolver.mjs +3 -2
  133. package/lib/read-tracker-store.mjs +2 -1
  134. package/lib/reconcile/mcp-entry-reconcile.mjs +2 -2
  135. package/lib/reflect.mjs +2 -1
  136. package/lib/registry/generate-docs.mjs +2 -2
  137. package/lib/roles/approval-surface.mjs +5 -4
  138. package/lib/roles/event-bus.mjs +0 -1
  139. package/lib/roles/gateway.mjs +6 -2
  140. package/lib/rules-delivery.mjs +1 -1
  141. package/lib/runtime-pressure.mjs +5 -3
  142. package/lib/sandbox.mjs +3 -2
  143. package/lib/scheduler/solo.mjs +6 -4
  144. package/lib/server/auth.mjs +4 -3
  145. package/lib/server/index.mjs +24 -26
  146. package/lib/server/insights.mjs +5 -4
  147. package/lib/server/webhook.mjs +2 -1
  148. package/lib/service-manager.mjs +5 -3
  149. package/lib/setup.mjs +9 -8
  150. package/lib/status.mjs +6 -5
  151. package/lib/storage/embeddings-local.mjs +3 -2
  152. package/lib/storage/sync.mjs +2 -2
  153. package/lib/telemetry/client.mjs +0 -1
  154. package/lib/telemetry/intent-verifications.mjs +6 -6
  155. package/lib/telemetry/model-pricing-catalog.mjs +4 -3
  156. package/lib/telemetry/rule-calls.mjs +3 -3
  157. package/lib/telemetry/skill-calls.mjs +3 -3
  158. package/lib/template-registry.mjs +1 -0
  159. package/lib/templates/visual-requirements.mjs +1 -1
  160. package/lib/test-corpus-inventory.mjs +1 -1
  161. package/lib/uninstall/uninstall.mjs +12 -10
  162. package/package.json +3 -3
  163. package/platforms/claude/settings.template.json +43 -43
  164. package/rules/common/no-fabrication.md +1 -1
  165. package/rules/common/release-gates.md +1 -1
  166. package/rules/common/research.md +1 -1
  167. package/rules/common/review-before-change.md +1 -1
  168. package/scripts/sync-specialists.mjs +11 -8
  169. package/skills/docs/adr-workflow.md +3 -3
  170. package/skills/docs/init-docs.md +9 -9
  171. package/skills/docs/prd-workflow.md +5 -5
  172. package/skills/docs/product-intelligence-review.md +1 -1
  173. package/skills/docs/product-intelligence-workflow.md +2 -2
  174. package/skills/docs/product-signal-workflow.md +1 -1
  175. package/skills/docs/runbook-workflow.md +4 -4
  176. package/skills/exploration/unknown-codebase-onboarding.md +1 -1
  177. package/skills/operating/orchestration-reference.md +1 -1
  178. package/skills/routing.md +3 -3
  179. package/specialists/prompts/cx-architect.md +1 -1
  180. package/specialists/prompts/cx-docs-keeper.md +1 -1
  181. package/specialists/prompts/cx-researcher.md +1 -1
  182. package/specialists/prompts/cx-sre.md +1 -1
  183. package/specialists/role-manifests.json +6 -6
  184. package/templates/docs/README.md +125 -0
  185. package/templates/docs/construct_guide.md +3 -4
  186. package/templates/docs/persona-artifact.md +1 -1
  187. package/templates/docs/prds/README.md +25 -0
  188. package/templates/docs/prds/templates/_template.md +206 -0
  189. package/templates/docs/prds/templates/meta-prd.template.md +177 -0
  190. package/templates/docs/prds/templates/prd-business.template.md +61 -0
  191. package/templates/docs/prds/templates/prd-platform.template.md +81 -0
  192. package/templates/docs/prds/templates/prfaq.template.md +38 -0
  193. package/templates/docs/rfcs/README.md +22 -0
  194. package/templates/docs/rfcs/templates/_template.md +58 -0
  195. package/templates/docs/rfcs/templates/rfc-platform.template.md +72 -0
  196. package/templates/homebrew/construct.rb +1 -1
  197. package/templates/workflows/new-feature.yml +8 -8
  198. package/lib/intake/legacy-paths.mjs +0 -5
@@ -5,7 +5,6 @@
5
5
  * CONSTRUCT_TRACE_BACKEND and never throws into callers.
6
6
  */
7
7
  import { existsSync, mkdirSync, appendFileSync } from 'node:fs';
8
- import { homedir } from 'node:os';
9
8
  import { join } from 'node:path';
10
9
  import { randomUUID } from 'node:crypto';
11
10
 
@@ -13,18 +13,18 @@
13
13
  */
14
14
 
15
15
  import fs from 'node:fs';
16
- import os from 'node:os';
17
16
  import path from 'node:path';
18
17
  import { appendBounded } from '../logging/rotate.mjs';
19
18
  import { resolveProjectScopedPath } from '../project-root.mjs';
19
+ import { doctorRoot } from '../config/xdg.mjs';
20
20
 
21
21
  // intent-verifications are PROJECT-SCOPED — a verification belongs to a
22
- // specific routing decision in a specific project. DEFAULT_LOG_PATH stays
23
- // at the legacy user-scope location for back-compat with readers that
24
- // imported the constant; the writer below resolves per-call so each
25
- // invocation lands in the project's .cx/ when one is detected.
22
+ // specific routing decision in a specific project. DEFAULT_LOG_PATH resolves
23
+ // to the global doctor root for back-compat with readers that imported the
24
+ // constant; the writer below resolves per-call so each invocation lands in
25
+ // the project's .cx/ when one is detected.
26
26
 
27
- export const DEFAULT_LOG_PATH = path.join(os.homedir(), '.cx', 'intent-verifications.jsonl');
27
+ export const DEFAULT_LOG_PATH = path.join(doctorRoot(), 'intent-verifications.jsonl');
28
28
 
29
29
  /**
30
30
  * Fire-and-forget append of one verification event.
@@ -15,13 +15,14 @@
15
15
  */
16
16
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
17
17
  import { join } from "path";
18
- import { homedir } from "os";
18
+
19
+ import { doctorRoot } from "../config/xdg.mjs";
19
20
 
20
21
  const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models";
21
22
  const LITELLM_PRICING_URL =
22
23
  "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
23
24
  const PRICING_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
24
- const PRICING_CACHE_PATH = join(homedir(), ".cx", "pricing-cache.json");
25
+ const PRICING_CACHE_PATH = join(doctorRoot(), "pricing-cache.json");
25
26
 
26
27
  export function describePricingCatalogFreshness() {
27
28
  try {
@@ -133,7 +134,7 @@ async function fetchLiteLLMPricing(fetchImpl = globalThis.fetch) {
133
134
  });
134
135
  }
135
136
  try {
136
- mkdirSync(join(homedir(), ".cx"), { recursive: true });
137
+ mkdirSync(doctorRoot(), { recursive: true });
137
138
  writeFileSync(PRICING_CACHE_PATH, JSON.stringify({ fetchedAt: Date.now(), models }));
138
139
  } catch { /* non-critical */ }
139
140
  return models;
@@ -1,16 +1,16 @@
1
1
  /**
2
2
  * lib/telemetry/rule-calls.mjs — record when a rule path is referenced at runtime.
3
3
  *
4
- * Mirrors hook-calls telemetry: append-only JSONL at ~/.cx/rule-calls.jsonl.
4
+ * Mirrors hook-calls telemetry: append-only JSONL at <doctorRoot>/rule-calls.jsonl.
5
5
  * Consumed by `construct rules usage` for consolidation decisions.
6
6
  */
7
7
 
8
8
  import fs from 'node:fs';
9
- import os from 'node:os';
10
9
  import path from 'node:path';
11
10
  import { appendBounded } from '../logging/rotate.mjs';
11
+ import { doctorRoot } from '../config/xdg.mjs';
12
12
 
13
- export const DEFAULT_LOG_PATH = path.join(os.homedir(), '.cx', 'rule-calls.jsonl');
13
+ export const DEFAULT_LOG_PATH = path.join(doctorRoot(), 'rule-calls.jsonl');
14
14
 
15
15
  /**
16
16
  * @param {object} event
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * lib/telemetry/skill-calls.mjs — measure which skill files actually get loaded.
3
3
  *
4
- * Appends one JSON line per skill load to ~/.cx/skill-calls.jsonl so
4
+ * Appends one JSON line per skill load to <doctorRoot>/skill-calls.jsonl so
5
5
  * `construct skills usage/orphans/hot/correlate-quality` can answer:
6
6
  * which skills have no load events in a 30-day window (pruning candidates),
7
7
  * which skills are loaded from many agents (hot paths), and which skills
@@ -15,17 +15,17 @@
15
15
  */
16
16
 
17
17
  import fs from 'node:fs';
18
- import os from 'node:os';
19
18
  import path from 'node:path';
20
19
  import { appendBounded } from '../logging/rotate.mjs';
21
20
  import { resolveProjectScope } from '../project-root.mjs';
21
+ import { doctorRoot } from '../config/xdg.mjs';
22
22
 
23
23
  // Skill calls are CROSS-PROJECT telemetry — a single log lets you see which
24
24
  // skills load hot across every project the user has run Construct in. Stays
25
25
  // at user scope; each entry is tagged with `projectId` so a reader can
26
26
  // attribute usage to a specific project without losing the global view.
27
27
 
28
- export const DEFAULT_LOG_PATH = path.join(os.homedir(), '.cx', 'skill-calls.jsonl');
28
+ export const DEFAULT_LOG_PATH = path.join(doctorRoot(), 'skill-calls.jsonl');
29
29
 
30
30
  /**
31
31
  * Fire-and-forget log of a skill load event.
@@ -70,4 +70,5 @@ export const TEMPLATE_OWNERSHIP_EXEMPTIONS = new Set([
70
70
  'rfc-platform',
71
71
  'prd-platform',
72
72
  'prd-business',
73
+ 'README',
73
74
  ]);
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Loads structure and visual requirements from specialists/artifact-manifest.json
5
5
  * (single source of truth) and merges legacy types not yet in the manifest.
6
- * Paired with docs/concepts/doc-visual-matrix.md; pinned by template tests.
6
+ * Paired with docs/guides/concepts/doc-visual-matrix.md; pinned by template tests.
7
7
  */
8
8
 
9
9
  import { validateArtifactPostconditions } from '../contracts/validate.mjs';
@@ -173,7 +173,7 @@ export function computeReleaseCriticalGaps(ledger) {
173
173
  for (const row of SHIPPED_MATRIX_CAPABILITIES) {
174
174
  if (ledgerCoversHint(allLedgerIds, row.ledgerHints)) continue;
175
175
  gaps.push({
176
- source: 'docs/audit/capability-matrix.md',
176
+ source: 'docs/operations/audit/capability-matrix.md',
177
177
  capability: row.id,
178
178
  status: 'shipped',
179
179
  reason: 'no ledger entry matches shipped capability hints',
@@ -24,7 +24,7 @@
24
24
  * --dry-run print the plan, change nothing
25
25
  * --yes non-interactive; remove auto-risk items, skip ask-risk items
26
26
  * --yes --all non-interactive; remove both auto- and ask-risk items
27
- * --keep-state only remove project-scope launcher + adapters; preserve .cx/, ~/.construct, Postgres
27
+ * --keep-state only remove project-scope launcher + adapters; preserve .cx/, the XDG user dirs, Postgres
28
28
  * --with-images also remove the shared pgvector Docker image (off by default; ADR-0027)
29
29
  * --scope=project|machine|all limit which categories are evaluated (default: all)
30
30
  */
@@ -37,6 +37,7 @@ import { fileURLToPath } from 'node:url';
37
37
 
38
38
  import { multiSelect } from '../tty-prompts.mjs';
39
39
  import { getUserConfigDir, getUserEnvPath } from '../env-config.mjs';
40
+ import { stateDir, cacheDir, doctorRoot } from '../config/xdg.mjs';
40
41
  import { removeTomlTables, tomlString } from '../codex-config.mjs';
41
42
  import { postgresContainerName, LEGACY_PG_CONTAINER } from '../home-namespace.mjs';
42
43
 
@@ -84,12 +85,13 @@ function buildCategories({ cwd, home, withImages = false }) {
84
85
  const projectPlanMd = path.join(cwd, 'plan.md');
85
86
  const userHome = home;
86
87
  const userConstructDir = getUserConfigDir(userHome);
88
+ const userStateDir = stateDir(userHome);
87
89
  const userConfigEnv = getUserEnvPath(userHome);
88
- const userEmbedCache = path.join(userConstructDir, 'cache', 'embeddings');
89
- const userVectorIndex = path.join(userConstructDir, 'vector');
90
- const userWorkspace = path.join(userConstructDir, 'workspace');
90
+ const userEmbedCache = path.join(cacheDir(userHome), 'embeddings');
91
+ const userVectorIndex = path.join(userStateDir, 'vector');
92
+ const userWorkspace = path.join(userStateDir, 'workspace');
91
93
  const userPgComposeDir = path.join(userConstructDir, 'services', 'postgres');
92
- const userCxDir = path.join(userHome, '.cx');
94
+ const userCxDir = doctorRoot(userHome);
93
95
  const launchAgentPlist = path.join(userHome, 'Library', 'LaunchAgents', `${PRESSURE_GUARD_LABEL}.plist`);
94
96
  const claudeSettings = path.join(userHome, '.claude', 'settings.json');
95
97
  const opencodeConfig = path.join(userHome, '.config', 'opencode', 'opencode.json');
@@ -172,7 +174,7 @@ function buildCategories({ cwd, home, withImages = false }) {
172
174
  id: 'machine-workspace',
173
175
  scope: 'machine',
174
176
  risk: 'auto',
175
- label: '~/.construct/workspace and ~/.construct/vector',
177
+ label: `${rel(userHome, userWorkspace)} and ${rel(userHome, userVectorIndex)}`,
176
178
  detect: () => existsAny(userWorkspace) || existsAny(userVectorIndex),
177
179
  describe: () => 'Removes the per-user working dir and fallback JSON vector index. Both are regenerated on next use.',
178
180
  execute: () => {
@@ -186,7 +188,7 @@ function buildCategories({ cwd, home, withImages = false }) {
186
188
  id: 'machine-cx',
187
189
  scope: 'machine',
188
190
  risk: 'auto',
189
- label: '~/.cx (daemon state, logs)',
191
+ label: `${rel(userHome, userCxDir)} (daemon state, logs)`,
190
192
  detect: () => existsAny(userCxDir),
191
193
  describe: () => `Removes ${rel(userHome, userCxDir)}. Daemon PIDs, telemetry, setup logs; all regenerated on next setup.`,
192
194
  execute: () => removePath(userCxDir),
@@ -195,7 +197,7 @@ function buildCategories({ cwd, home, withImages = false }) {
195
197
  id: 'machine-embedding-cache',
196
198
  scope: 'machine',
197
199
  risk: 'ask',
198
- label: '~/.construct/cache/embeddings (~22 MB ONNX model)',
200
+ label: `${rel(userHome, userEmbedCache)} (~22 MB ONNX model)`,
199
201
  detect: () => existsAny(userEmbedCache),
200
202
  describe: () => 'Removes the cached ONNX embedding model. Skip if you plan to reinstall soon — re-downloading takes a minute.',
201
203
  execute: () => removePath(userEmbedCache),
@@ -204,7 +206,7 @@ function buildCategories({ cwd, home, withImages = false }) {
204
206
  id: 'machine-config-env',
205
207
  scope: 'machine',
206
208
  risk: 'ask',
207
- label: '~/.construct/config.env (API keys + consent flags)',
209
+ label: `${rel(userHome, userConfigEnv)} (API keys + consent flags)`,
208
210
  detect: () => existsAny(userConfigEnv),
209
211
  describe: () => 'Removes saved API keys (Anthropic/OpenAI/telemetry/etc.) and bootstrap consent. Skip if you intend to reinstall and reuse the keys.',
210
212
  execute: () => removePath(userConfigEnv),
@@ -231,7 +233,7 @@ function buildCategories({ cwd, home, withImages = false }) {
231
233
  id: 'machine-postgres-compose',
232
234
  scope: 'machine',
233
235
  risk: 'auto',
234
- label: '~/.construct/services/postgres/ (compose file)',
236
+ label: `${rel(userHome, userPgComposeDir)} (compose file)`,
235
237
  detect: () => existsAny(userPgComposeDir),
236
238
  describe: () => 'Removes the local docker-compose.yml. Run after removing the container.',
237
239
  execute: () => removePath(userPgComposeDir),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geraldmaron/construct",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "type": "module",
5
5
  "packageManager": "npm@11.5.1",
6
6
  "description": "Construct — agent orchestration layer for OpenCode, Claude Code, and other coding surfaces",
@@ -52,7 +52,7 @@
52
52
  "scripts": {
53
53
  "mcp": "node lib/mcp/server.mjs",
54
54
  "test": "node scripts/run-tests.mjs",
55
- "test:functional": "node --test --test-timeout=120000 --test-concurrency=1 tests/functional/*.functional.test.mjs",
55
+ "test:functional": "XDG_CONFIG_HOME= XDG_STATE_HOME= XDG_CACHE_HOME= node --test --test-timeout=120000 --test-concurrency=1 tests/functional/*.functional.test.mjs",
56
56
  "test:unit": "node scripts/run-tests.mjs --exclude=tests/functional",
57
57
  "lint:js": "eslint bin/construct \"lib/**/*.mjs\" \"scripts/**/*.mjs\" \"tests/**/*.mjs\"",
58
58
  "coverage": "c8 --reporter=text-summary --reporter=lcov --src=lib --src=bin node scripts/run-tests.mjs --exclude=tests/functional",
@@ -80,7 +80,7 @@
80
80
  "release:check": "node ./bin/construct doctor && npm test && node ./bin/construct docs:update --check && node ./bin/construct docs:site --check && node ./bin/construct registry:generate-docs --check && node ./bin/construct docs:verify --strict && node scripts/alignment/census.mjs --ratchet && node ./bin/construct dashboard:sync --check && node ./bin/construct lint:comments && node ./bin/construct certify gate && node scripts/lint-commits-pr.mjs",
81
81
  "release:gate": "node --test tests/functional/release-gate.functional.test.mjs",
82
82
  "audit:published": "node scripts/audit-published-artifact.mjs",
83
- "version": "node scripts/sync-construct-version.mjs && git add .construct/version",
83
+ "version": "node scripts/sync-construct-version.mjs && git add -f .construct/version",
84
84
  "release:preflight": "node scripts/pre-release-check.mjs",
85
85
  "release:preflight:no-auth": "node scripts/pre-release-check.mjs --skip-auth",
86
86
  "npm:publish": "npm run release:check && npm publish --access public",
@@ -9,7 +9,7 @@
9
9
  "hooks": [
10
10
  {
11
11
  "type": "command",
12
- "command": "node \"$HOME/.construct/lib/hooks/session-start.mjs\"",
12
+ "command": "node \"$HOME/.config/construct/lib/hooks/session-start.mjs\"",
13
13
  "timeout": 10
14
14
  }
15
15
  ],
@@ -23,7 +23,7 @@
23
23
  "hooks": [
24
24
  {
25
25
  "type": "command",
26
- "command": "node \"$HOME/.construct/lib/hooks/policy-engine.mjs\" PreToolUse",
26
+ "command": "node \"$HOME/.config/construct/lib/hooks/policy-engine.mjs\" PreToolUse",
27
27
  "timeout": 10
28
28
  }
29
29
  ],
@@ -35,7 +35,7 @@
35
35
  "hooks": [
36
36
  {
37
37
  "type": "command",
38
- "command": "node \"$HOME/.construct/lib/hooks/orchestration-dispatch-guard.mjs\"",
38
+ "command": "node \"$HOME/.config/construct/lib/hooks/orchestration-dispatch-guard.mjs\"",
39
39
  "timeout": 5
40
40
  }
41
41
  ],
@@ -47,7 +47,7 @@
47
47
  "hooks": [
48
48
  {
49
49
  "type": "command",
50
- "command": "node \"$HOME/.construct/lib/hooks/block-no-verify.mjs\"",
50
+ "command": "node \"$HOME/.config/construct/lib/hooks/block-no-verify.mjs\"",
51
51
  "timeout": 5
52
52
  }
53
53
  ],
@@ -59,7 +59,7 @@
59
59
  "hooks": [
60
60
  {
61
61
  "type": "command",
62
- "command": "node \"$HOME/.construct/lib/hooks/pre-push-gate.mjs\"",
62
+ "command": "node \"$HOME/.config/construct/lib/hooks/pre-push-gate.mjs\"",
63
63
  "timeout": 180
64
64
  }
65
65
  ],
@@ -71,7 +71,7 @@
71
71
  "hooks": [
72
72
  {
73
73
  "type": "command",
74
- "command": "node \"$HOME/.construct/lib/hooks/guard-bash.mjs\"",
74
+ "command": "node \"$HOME/.config/construct/lib/hooks/guard-bash.mjs\"",
75
75
  "timeout": 5
76
76
  }
77
77
  ],
@@ -83,7 +83,7 @@
83
83
  "hooks": [
84
84
  {
85
85
  "type": "command",
86
- "command": "node \"$HOME/.construct/lib/hooks/config-protection.mjs\"",
86
+ "command": "node \"$HOME/.config/construct/lib/hooks/config-protection.mjs\"",
87
87
  "timeout": 5
88
88
  }
89
89
  ],
@@ -95,7 +95,7 @@
95
95
  "hooks": [
96
96
  {
97
97
  "type": "command",
98
- "command": "node \"$HOME/.construct/lib/hooks/mcp-health-check.mjs\"",
98
+ "command": "node \"$HOME/.config/construct/lib/hooks/mcp-health-check.mjs\"",
99
99
  "timeout": 3
100
100
  }
101
101
  ],
@@ -107,7 +107,7 @@
107
107
  "hooks": [
108
108
  {
109
109
  "type": "command",
110
- "command": "node \"$HOME/.construct/lib/hooks/edit-guard.mjs\"",
110
+ "command": "node \"$HOME/.config/construct/lib/hooks/edit-guard.mjs\"",
111
111
  "timeout": 5
112
112
  }
113
113
  ],
@@ -133,7 +133,7 @@
133
133
  "hooks": [
134
134
  {
135
135
  "type": "command",
136
- "command": "node \"$HOME/.construct/lib/hooks/scan-secrets.mjs\"",
136
+ "command": "node \"$HOME/.config/construct/lib/hooks/scan-secrets.mjs\"",
137
137
  "timeout": 10
138
138
  }
139
139
  ],
@@ -145,7 +145,7 @@
145
145
  "hooks": [
146
146
  {
147
147
  "type": "command",
148
- "command": "node \"$HOME/.construct/lib/hooks/adaptive-lint.mjs\"",
148
+ "command": "node \"$HOME/.config/construct/lib/hooks/adaptive-lint.mjs\"",
149
149
  "timeout": 30,
150
150
  "async": true
151
151
  }
@@ -158,7 +158,7 @@
158
158
  "hooks": [
159
159
  {
160
160
  "type": "command",
161
- "command": "node \"$HOME/.construct/lib/hooks/comment-lint.mjs\"",
161
+ "command": "node \"$HOME/.config/construct/lib/hooks/comment-lint.mjs\"",
162
162
  "timeout": 15
163
163
  }
164
164
  ],
@@ -170,7 +170,7 @@
170
170
  "hooks": [
171
171
  {
172
172
  "type": "command",
173
- "command": "node \"$HOME/.construct/lib/hooks/brand-prose-lint.mjs\"",
173
+ "command": "node \"$HOME/.config/construct/lib/hooks/brand-prose-lint.mjs\"",
174
174
  "timeout": 15
175
175
  }
176
176
  ],
@@ -182,7 +182,7 @@
182
182
  "hooks": [
183
183
  {
184
184
  "type": "command",
185
- "command": "node \"$HOME/.construct/lib/hooks/artifact-release-gate.mjs\"",
185
+ "command": "node \"$HOME/.config/construct/lib/hooks/artifact-release-gate.mjs\"",
186
186
  "timeout": 15
187
187
  }
188
188
  ],
@@ -194,7 +194,7 @@
194
194
  "hooks": [
195
195
  {
196
196
  "type": "command",
197
- "command": "node \"$HOME/.construct/lib/hooks/doc-coupling-check.mjs\"",
197
+ "command": "node \"$HOME/.config/construct/lib/hooks/doc-coupling-check.mjs\"",
198
198
  "timeout": 5
199
199
  }
200
200
  ],
@@ -206,7 +206,7 @@
206
206
  "hooks": [
207
207
  {
208
208
  "type": "command",
209
- "command": "node \"$HOME/.construct/lib/hooks/graph-impact-advisory.mjs\"",
209
+ "command": "node \"$HOME/.config/construct/lib/hooks/graph-impact-advisory.mjs\"",
210
210
  "timeout": 10
211
211
  }
212
212
  ],
@@ -218,7 +218,7 @@
218
218
  "hooks": [
219
219
  {
220
220
  "type": "command",
221
- "command": "node \"$HOME/.construct/lib/hooks/edit-accumulator.mjs\"",
221
+ "command": "node \"$HOME/.config/construct/lib/hooks/edit-accumulator.mjs\"",
222
222
  "timeout": 3
223
223
  }
224
224
  ],
@@ -230,7 +230,7 @@
230
230
  "hooks": [
231
231
  {
232
232
  "type": "command",
233
- "command": "node \"$HOME/.construct/lib/hooks/registry-sync.mjs\"",
233
+ "command": "node \"$HOME/.config/construct/lib/hooks/registry-sync.mjs\"",
234
234
  "timeout": 15,
235
235
  "async": true
236
236
  }
@@ -243,7 +243,7 @@
243
243
  "hooks": [
244
244
  {
245
245
  "type": "command",
246
- "command": "node \"$HOME/.construct/lib/hooks/dep-audit.mjs\"",
246
+ "command": "node \"$HOME/.config/construct/lib/hooks/dep-audit.mjs\"",
247
247
  "timeout": 35,
248
248
  "async": true
249
249
  }
@@ -256,7 +256,7 @@
256
256
  "hooks": [
257
257
  {
258
258
  "type": "command",
259
- "command": "node \"$HOME/.construct/lib/hooks/audit-reads.mjs\"",
259
+ "command": "node \"$HOME/.config/construct/lib/hooks/audit-reads.mjs\"",
260
260
  "timeout": 3,
261
261
  "async": true
262
262
  }
@@ -269,7 +269,7 @@
269
269
  "hooks": [
270
270
  {
271
271
  "type": "command",
272
- "command": "node \"$HOME/.construct/lib/hooks/mcp-audit.mjs\"",
272
+ "command": "node \"$HOME/.config/construct/lib/hooks/mcp-audit.mjs\"",
273
273
  "timeout": 3,
274
274
  "async": true
275
275
  }
@@ -282,7 +282,7 @@
282
282
  "hooks": [
283
283
  {
284
284
  "type": "command",
285
- "command": "node \"$HOME/.construct/lib/hooks/agent-tracker.mjs\"",
285
+ "command": "node \"$HOME/.config/construct/lib/hooks/agent-tracker.mjs\"",
286
286
  "timeout": 3,
287
287
  "async": true
288
288
  }
@@ -295,7 +295,7 @@
295
295
  "hooks": [
296
296
  {
297
297
  "type": "command",
298
- "command": "node \"$HOME/.construct/lib/hooks/bash-output-logger.mjs\"",
298
+ "command": "node \"$HOME/.config/construct/lib/hooks/bash-output-logger.mjs\"",
299
299
  "timeout": 5
300
300
  }
301
301
  ],
@@ -307,7 +307,7 @@
307
307
  "hooks": [
308
308
  {
309
309
  "type": "command",
310
- "command": "node \"$HOME/.construct/lib/hooks/test-watch.mjs\"",
310
+ "command": "node \"$HOME/.config/construct/lib/hooks/test-watch.mjs\"",
311
311
  "timeout": 5,
312
312
  "async": true
313
313
  }
@@ -320,7 +320,7 @@
320
320
  "hooks": [
321
321
  {
322
322
  "type": "command",
323
- "command": "node \"$HOME/.construct/lib/hooks/post-merge-docs-check.mjs\"",
323
+ "command": "node \"$HOME/.config/construct/lib/hooks/post-merge-docs-check.mjs\"",
324
324
  "timeout": 5,
325
325
  "async": true
326
326
  }
@@ -333,7 +333,7 @@
333
333
  "hooks": [
334
334
  {
335
335
  "type": "command",
336
- "command": "node \"$HOME/.construct/lib/hooks/post-merge-tracking.mjs\"",
336
+ "command": "node \"$HOME/.config/construct/lib/hooks/post-merge-tracking.mjs\"",
337
337
  "timeout": 5,
338
338
  "async": true
339
339
  }
@@ -346,7 +346,7 @@
346
346
  "hooks": [
347
347
  {
348
348
  "type": "command",
349
- "command": "node \"$HOME/.construct/lib/hooks/audit-trail.mjs\"",
349
+ "command": "node \"$HOME/.config/construct/lib/hooks/audit-trail.mjs\"",
350
350
  "timeout": 5
351
351
  }
352
352
  ],
@@ -358,7 +358,7 @@
358
358
  "hooks": [
359
359
  {
360
360
  "type": "command",
361
- "command": "node \"$HOME/.construct/lib/hooks/orchestration-dispatch-guard.mjs\"",
361
+ "command": "node \"$HOME/.config/construct/lib/hooks/orchestration-dispatch-guard.mjs\"",
362
362
  "timeout": 5
363
363
  }
364
364
  ],
@@ -372,7 +372,7 @@
372
372
  "hooks": [
373
373
  {
374
374
  "type": "command",
375
- "command": "node \"$HOME/.construct/lib/hooks/model-fallback.mjs\"",
375
+ "command": "node \"$HOME/.config/construct/lib/hooks/model-fallback.mjs\"",
376
376
  "timeout": 130,
377
377
  "async": true
378
378
  }
@@ -385,7 +385,7 @@
385
385
  "hooks": [
386
386
  {
387
387
  "type": "command",
388
- "command": "node \"$HOME/.construct/lib/hooks/mcp-health-check.mjs\" --mark-failure",
388
+ "command": "node \"$HOME/.config/construct/lib/hooks/mcp-health-check.mjs\" --mark-failure",
389
389
  "timeout": 3
390
390
  }
391
391
  ],
@@ -397,7 +397,7 @@
397
397
  "hooks": [
398
398
  {
399
399
  "type": "command",
400
- "command": "node \"$HOME/.construct/lib/hooks/context-window-recovery.mjs\"",
400
+ "command": "node \"$HOME/.config/construct/lib/hooks/context-window-recovery.mjs\"",
401
401
  "timeout": 60,
402
402
  "async": true
403
403
  }
@@ -410,7 +410,7 @@
410
410
  "hooks": [
411
411
  {
412
412
  "type": "command",
413
- "command": "node \"$HOME/.construct/lib/hooks/edit-error-recovery.mjs\"",
413
+ "command": "node \"$HOME/.config/construct/lib/hooks/edit-error-recovery.mjs\"",
414
414
  "timeout": 15,
415
415
  "async": true
416
416
  }
@@ -425,7 +425,7 @@
425
425
  "hooks": [
426
426
  {
427
427
  "type": "command",
428
- "command": "node \"$HOME/.construct/lib/hooks/pre-compact.mjs\"",
428
+ "command": "node \"$HOME/.config/construct/lib/hooks/pre-compact.mjs\"",
429
429
  "timeout": 15
430
430
  }
431
431
  ],
@@ -439,7 +439,7 @@
439
439
  "hooks": [
440
440
  {
441
441
  "type": "command",
442
- "command": "node \"$HOME/.construct/lib/hooks/policy-engine.mjs\" Stop",
442
+ "command": "node \"$HOME/.config/construct/lib/hooks/policy-engine.mjs\" Stop",
443
443
  "timeout": 15
444
444
  }
445
445
  ],
@@ -451,7 +451,7 @@
451
451
  "hooks": [
452
452
  {
453
453
  "type": "command",
454
- "command": "node \"$HOME/.construct/lib/hooks/stop-typecheck.mjs\"",
454
+ "command": "node \"$HOME/.config/construct/lib/hooks/stop-typecheck.mjs\"",
455
455
  "timeout": 120,
456
456
  "async": true
457
457
  }
@@ -464,7 +464,7 @@
464
464
  "hooks": [
465
465
  {
466
466
  "type": "command",
467
- "command": "node \"$HOME/.construct/lib/hooks/readme-age-check.mjs\"",
467
+ "command": "node \"$HOME/.config/construct/lib/hooks/readme-age-check.mjs\"",
468
468
  "timeout": 5,
469
469
  "async": true
470
470
  }
@@ -477,7 +477,7 @@
477
477
  "hooks": [
478
478
  {
479
479
  "type": "command",
480
- "command": "node \"$HOME/.construct/lib/hooks/stop-notify.mjs\"",
480
+ "command": "node \"$HOME/.config/construct/lib/hooks/stop-notify.mjs\"",
481
481
  "timeout": 10,
482
482
  "async": true
483
483
  }
@@ -490,7 +490,7 @@
490
490
  "hooks": [
491
491
  {
492
492
  "type": "command",
493
- "command": "node \"$HOME/.construct/lib/hooks/pre-compact.mjs\"",
493
+ "command": "node \"$HOME/.config/construct/lib/hooks/pre-compact.mjs\"",
494
494
  "timeout": 15,
495
495
  "async": true
496
496
  }
@@ -503,7 +503,7 @@
503
503
  "hooks": [
504
504
  {
505
505
  "type": "command",
506
- "command": "node \"$HOME/.construct/lib/hooks/session-optimize.mjs\"",
506
+ "command": "node \"$HOME/.config/construct/lib/hooks/session-optimize.mjs\"",
507
507
  "timeout": 600,
508
508
  "async": true
509
509
  }
@@ -516,7 +516,7 @@
516
516
  "hooks": [
517
517
  {
518
518
  "type": "command",
519
- "command": "node \"$HOME/.construct/lib/hooks/session-reflect.mjs\"",
519
+ "command": "node \"$HOME/.config/construct/lib/hooks/session-reflect.mjs\"",
520
520
  "timeout": 5,
521
521
  "async": true
522
522
  }
@@ -529,7 +529,7 @@
529
529
  "hooks": [
530
530
  {
531
531
  "type": "command",
532
- "command": "node \"$HOME/.construct/lib/hooks/session-tracking-refresh.mjs\"",
532
+ "command": "node \"$HOME/.config/construct/lib/hooks/session-tracking-refresh.mjs\"",
533
533
  "timeout": 5,
534
534
  "async": true
535
535
  }
@@ -544,7 +544,7 @@
544
544
  "hooks": [
545
545
  {
546
546
  "type": "command",
547
- "command": "node \"$HOME/.construct/lib/hooks/context-watch.mjs\"",
547
+ "command": "node \"$HOME/.config/construct/lib/hooks/context-watch.mjs\"",
548
548
  "timeout": 5
549
549
  }
550
550
  ],
@@ -556,7 +556,7 @@
556
556
  "hooks": [
557
557
  {
558
558
  "type": "command",
559
- "command": "node \"$HOME/.construct/lib/hooks/ci-status-check.mjs\"",
559
+ "command": "node \"$HOME/.config/construct/lib/hooks/ci-status-check.mjs\"",
560
560
  "timeout": 5
561
561
  }
562
562
  ],
@@ -55,7 +55,7 @@ Fabrication is the single largest threat to trust in an agent system. A persona
55
55
 
56
56
  ## Enforcement
57
57
 
58
- - `lib/comment-lint.mjs` enforces a subset of these patterns on artifact paths (`docs/prd/**`, `docs/adr/**`, `docs/rfc/**`, `docs/research/**`, `.cx/knowledge/**`, `.cx/handoffs/**`, `.cx/research/**`). PostToolUse warns; `npm run lint:comments`, `construct lint:comments`, and the release gate block.
58
+ - `lib/comment-lint.mjs` enforces a subset of these patterns on artifact paths (`docs/specs/prd/**`, `docs/decisions/adr/**`, `docs/decisions/rfc/**`, `docs/notes/research/**`, `.cx/knowledge/**`, `.cx/handoffs/**`, `.cx/research/**`). PostToolUse warns; `npm run lint:comments`, `construct lint:comments`, and the release gate block.
59
59
  - `specialists/contracts.json` postconditions check structural requirements (mandatory sections, intake traceability, citation density). `lib/contracts/validate.mjs#validateHandoff` blocks handoffs that fail validation; binary postconditions in `lib/specialists/postconditions.mjs` block rubber-stamp reviews, post-hoc threat models, symptom-only fixes, stale-doc PRs, and post-hoc accessibility. Enforcement is hard-default `block`.
60
60
  - `construct intake done <id> --output=<path>` stamps `intake_id`, `intake_confidence`, and `intake_rationale` into the artifact's frontmatter so every intake-derived artifact carries verifiable provenance.
61
61
 
@@ -42,7 +42,7 @@ For every non-trivial change:
42
42
 
43
43
  1. **A Beads issue exists.** `bd ready` to find or create one. `bd show <id>` to read context. `bd update <id> --claim` to claim before editing files.
44
44
  2. **`plan.md` reflects the work.** Even though `plan.md` is local-only and gitignored, it stays the human-readable working plan. Mark items `done` when they ship; add new rows for work that wasn't previously tracked.
45
- 3. **Doc updates land in the same change as code.** If runtime shape, contracts, boundaries, or major dependencies changed, update `docs/concepts/architecture.md` in the same commit. If the docs surface or maintenance contract changed, update `docs/README.md`. If active work, decisions, or assumptions changed, update `.cx/context.md` and `.cx/context.json`. Always add a `CHANGELOG.md` entry.
45
+ 3. **Doc updates land in the same change as code.** If runtime shape, contracts, boundaries, or major dependencies changed, update `docs/guides/concepts/architecture.md` in the same commit. If the docs surface or maintenance contract changed, update `docs/README.md`. If active work, decisions, or assumptions changed, update `.cx/context.md` and `.cx/context.json`. Always add a `CHANGELOG.md` entry.
46
46
  4. **Beads close on green.** `bd close <id>` happens after CI is green and the work is verified: not before.
47
47
 
48
48
  ## Hard rules
@@ -47,7 +47,7 @@ Start with the narrowest authoritative source that can answer the question:
47
47
  1. **Local project evidence first**
48
48
  - `.cx/research/`
49
49
  - `.cx/knowledge/`
50
- - `docs/prd/`, `docs/meta-prd/`, `docs/adr/`, `docs/runbooks/`
50
+ - `docs/specs/prd/`, `docs/meta-prd/`, `docs/decisions/adr/`, `docs/operations/runbooks/`
51
51
  - ingested markdown artifacts under `.cx/knowledge/`
52
52
  - repo code, tests, configs, and existing decisions
53
53
  2. **Primary external sources second**