avorelo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/bin/avorelo +9 -0
  4. package/package.json +135 -0
  5. package/scripts/README.md +40 -0
  6. package/scripts/cco-dashboard.js +252 -0
  7. package/scripts/cco-status.js +430 -0
  8. package/scripts/lib/activation/account-state.js +37 -0
  9. package/scripts/lib/activation/activation-runner.js +546 -0
  10. package/scripts/lib/activation/activation-self-healing.js +480 -0
  11. package/scripts/lib/activation/activation-state.js +83 -0
  12. package/scripts/lib/activation/activation-summary.js +191 -0
  13. package/scripts/lib/activation/adapters/claude-code.js +77 -0
  14. package/scripts/lib/activation/adapters/codex-cli.js +52 -0
  15. package/scripts/lib/activation/adapters/cursor.js +37 -0
  16. package/scripts/lib/activation/adapters/github-agent.js +39 -0
  17. package/scripts/lib/activation/adapters/terminal.js +42 -0
  18. package/scripts/lib/activation/adapters/vscode.js +39 -0
  19. package/scripts/lib/activation/adapters/windsurf.js +37 -0
  20. package/scripts/lib/activation/ai-surface-detector.js +151 -0
  21. package/scripts/lib/activation/connect-account.js +145 -0
  22. package/scripts/lib/activation/detect-environment.js +75 -0
  23. package/scripts/lib/activation/detect-hosts.js +62 -0
  24. package/scripts/lib/activation/format-activation-output.js +109 -0
  25. package/scripts/lib/activation/next-action.js +43 -0
  26. package/scripts/lib/activation/repair-engine.js +219 -0
  27. package/scripts/lib/activation-distribution-readiness.js +507 -0
  28. package/scripts/lib/adapter-conformance.js +176 -0
  29. package/scripts/lib/adapter-readiness.js +417 -0
  30. package/scripts/lib/adapter-safety-boundaries.js +335 -0
  31. package/scripts/lib/adapter-technical-readiness-gate.js +205 -0
  32. package/scripts/lib/agent-access-governance.js +455 -0
  33. package/scripts/lib/agent-enforcement.js +765 -0
  34. package/scripts/lib/agent-policy-profile.js +210 -0
  35. package/scripts/lib/agent-security/action-evaluator.js +507 -0
  36. package/scripts/lib/agent-security/adapter-registry.js +98 -0
  37. package/scripts/lib/agent-security/auto-policy.js +139 -0
  38. package/scripts/lib/agent-security/bounded-scan.js +93 -0
  39. package/scripts/lib/agent-security/enforcement-adapter.js +174 -0
  40. package/scripts/lib/agent-security/enforcement-engine.js +1129 -0
  41. package/scripts/lib/agent-security/file-write-adapter.js +183 -0
  42. package/scripts/lib/agent-security/file-write-rules.js +178 -0
  43. package/scripts/lib/agent-security/index.js +3342 -0
  44. package/scripts/lib/agent-security/instruction-risk.js +181 -0
  45. package/scripts/lib/agent-security/mcp-action-adapter.js +185 -0
  46. package/scripts/lib/agent-security/mcp-action-rules.js +184 -0
  47. package/scripts/lib/agent-security/package-action-adapter.js +175 -0
  48. package/scripts/lib/agent-security/package-action-rules.js +233 -0
  49. package/scripts/lib/agent-security/performance.js +148 -0
  50. package/scripts/lib/agent-security/permission-minimizer.js +403 -0
  51. package/scripts/lib/agent-security/scan-cache.js +74 -0
  52. package/scripts/lib/agent-security/source-trust.js +146 -0
  53. package/scripts/lib/ai-install-prompt.js +288 -0
  54. package/scripts/lib/ai-workspace-hygiene.js +1499 -0
  55. package/scripts/lib/alpha-activation.js +520 -0
  56. package/scripts/lib/alpha-feedback.js +263 -0
  57. package/scripts/lib/alpha-readiness-gate.js +332 -0
  58. package/scripts/lib/anti-gaming.js +169 -0
  59. package/scripts/lib/artifact-health.js +431 -0
  60. package/scripts/lib/attribution.js +180 -0
  61. package/scripts/lib/audit.js +289 -0
  62. package/scripts/lib/avorelo-skill-registry.js +810 -0
  63. package/scripts/lib/batch-jobs.js +71 -0
  64. package/scripts/lib/brain-pack.js +578 -0
  65. package/scripts/lib/brand-boundary.js +424 -0
  66. package/scripts/lib/brand.js +74 -0
  67. package/scripts/lib/browser-capability.js +1048 -0
  68. package/scripts/lib/browser-proof-preflight.js +321 -0
  69. package/scripts/lib/cache-readiness.js +187 -0
  70. package/scripts/lib/canonical-reentry.js +162 -0
  71. package/scripts/lib/capability-packs.js +314 -0
  72. package/scripts/lib/capability-recommender.js +512 -0
  73. package/scripts/lib/capability-registry.js +1059 -0
  74. package/scripts/lib/carry-forward-surfacing.js +194 -0
  75. package/scripts/lib/ccusage-adapter.js +188 -0
  76. package/scripts/lib/company-loop.js +1149 -0
  77. package/scripts/lib/config.js +637 -0
  78. package/scripts/lib/context-acquisition-plan.js +287 -0
  79. package/scripts/lib/context-budget-guard.js +170 -0
  80. package/scripts/lib/context-budget-scanner.js +257 -0
  81. package/scripts/lib/context-optimizer.js +715 -0
  82. package/scripts/lib/context-reduction-plan.js +178 -0
  83. package/scripts/lib/context-safety.js +88 -0
  84. package/scripts/lib/context-savings-engine.js +158 -0
  85. package/scripts/lib/cost-evidence.js +254 -0
  86. package/scripts/lib/cross-host-install-plan.js +308 -0
  87. package/scripts/lib/cross-host-install-readiness.js +237 -0
  88. package/scripts/lib/cross-host-value-flow.js +268 -0
  89. package/scripts/lib/dashboard.js +900 -0
  90. package/scripts/lib/design-partner-feedback.js +346 -0
  91. package/scripts/lib/entitlements.js +100 -0
  92. package/scripts/lib/execution-packet.js +559 -0
  93. package/scripts/lib/experimentation-events.js +547 -0
  94. package/scripts/lib/external-capability-compliance.js +107 -0
  95. package/scripts/lib/external-user-simulation.js +166 -0
  96. package/scripts/lib/failure-recovery-readiness.js +81 -0
  97. package/scripts/lib/failure-recovery.js +419 -0
  98. package/scripts/lib/feedback-intelligence.js +537 -0
  99. package/scripts/lib/feedback-signals.js +205 -0
  100. package/scripts/lib/file-integrity.js +68 -0
  101. package/scripts/lib/fsx.js +127 -0
  102. package/scripts/lib/full-readiness-gate.js +451 -0
  103. package/scripts/lib/guidance-builder.js +174 -0
  104. package/scripts/lib/hook-apply.js +1019 -0
  105. package/scripts/lib/hook-baseline.js +310 -0
  106. package/scripts/lib/hook-config-preview.js +275 -0
  107. package/scripts/lib/hook-contracts.js +290 -0
  108. package/scripts/lib/hook-safety-boundary-readiness.js +80 -0
  109. package/scripts/lib/host-capability-matrix.js +351 -0
  110. package/scripts/lib/host-support-context.js +254 -0
  111. package/scripts/lib/http-hook-action.js +538 -0
  112. package/scripts/lib/install-ai-readiness.js +84 -0
  113. package/scripts/lib/install-intake-risk.js +1037 -0
  114. package/scripts/lib/install-journey-intelligence.js +329 -0
  115. package/scripts/lib/intervention-guidance.js +57 -0
  116. package/scripts/lib/known-limitations.js +115 -0
  117. package/scripts/lib/l8-path-truth.js +146 -0
  118. package/scripts/lib/launch-hardening-gate.js +436 -0
  119. package/scripts/lib/launch-readiness.js +628 -0
  120. package/scripts/lib/learning-memory.js +686 -0
  121. package/scripts/lib/lifecycle-hooks.js +802 -0
  122. package/scripts/lib/local-package-smoke.js +423 -0
  123. package/scripts/lib/local-pricing.js +299 -0
  124. package/scripts/lib/mcp-enforcement.js +311 -0
  125. package/scripts/lib/mcp-least-privilege-policy.js +303 -0
  126. package/scripts/lib/mcp-tool-inventory.js +388 -0
  127. package/scripts/lib/mcp-tool-risk.js +0 -0
  128. package/scripts/lib/memory.js +335 -0
  129. package/scripts/lib/metrics.js +699 -0
  130. package/scripts/lib/micro-proof.js +133 -0
  131. package/scripts/lib/next-run-context.js +436 -0
  132. package/scripts/lib/operating-value.js +1648 -0
  133. package/scripts/lib/optimization-v3.js +122 -0
  134. package/scripts/lib/orchestration/adapters/_shared.js +49 -0
  135. package/scripts/lib/orchestration/adapters/aider.js +18 -0
  136. package/scripts/lib/orchestration/adapters/claude-code.js +35 -0
  137. package/scripts/lib/orchestration/adapters/codex.js +35 -0
  138. package/scripts/lib/orchestration/adapters/gemini-cli.js +18 -0
  139. package/scripts/lib/orchestration/adapters/git.js +25 -0
  140. package/scripts/lib/orchestration/adapters/index.js +31 -0
  141. package/scripts/lib/orchestration/adapters/lm-studio.js +18 -0
  142. package/scripts/lib/orchestration/adapters/ollama.js +18 -0
  143. package/scripts/lib/orchestration/adapters/opencode.js +18 -0
  144. package/scripts/lib/orchestration/adapters/openrouter.js +18 -0
  145. package/scripts/lib/orchestration/adapters/test-runner.js +25 -0
  146. package/scripts/lib/orchestration/cli.js +438 -0
  147. package/scripts/lib/orchestration/execution-manager.js +279 -0
  148. package/scripts/lib/orchestration/handoff.js +314 -0
  149. package/scripts/lib/orchestration/index.js +456 -0
  150. package/scripts/lib/orchestration/inventory.js +47 -0
  151. package/scripts/lib/orchestration/model-discovery.js +498 -0
  152. package/scripts/lib/orchestration/model-profiler.js +170 -0
  153. package/scripts/lib/orchestration/model-profiles.js +252 -0
  154. package/scripts/lib/orchestration/model-refresh-policy.js +72 -0
  155. package/scripts/lib/orchestration/proof-writer.js +349 -0
  156. package/scripts/lib/orchestration/provider-discovery/aider.js +49 -0
  157. package/scripts/lib/orchestration/provider-discovery/claude-code.js +56 -0
  158. package/scripts/lib/orchestration/provider-discovery/codex.js +49 -0
  159. package/scripts/lib/orchestration/provider-discovery/common.js +186 -0
  160. package/scripts/lib/orchestration/provider-discovery/gemini.js +106 -0
  161. package/scripts/lib/orchestration/provider-discovery/lm-studio.js +118 -0
  162. package/scripts/lib/orchestration/provider-discovery/models-dev.js +12 -0
  163. package/scripts/lib/orchestration/provider-discovery/ollama.js +100 -0
  164. package/scripts/lib/orchestration/provider-discovery/opencode.js +47 -0
  165. package/scripts/lib/orchestration/provider-discovery/openrouter.js +44 -0
  166. package/scripts/lib/orchestration/risk-classifier.js +130 -0
  167. package/scripts/lib/orchestration/routing-policy.js +486 -0
  168. package/scripts/lib/orchestration/settings.js +112 -0
  169. package/scripts/lib/orchestration/state.js +165 -0
  170. package/scripts/lib/orchestration/verification-manager.js +138 -0
  171. package/scripts/lib/output-profiles.js +146 -0
  172. package/scripts/lib/package-content-audit.js +368 -0
  173. package/scripts/lib/package-runtime.js +278 -0
  174. package/scripts/lib/plan-surface.js +53 -0
  175. package/scripts/lib/plans.js +2318 -0
  176. package/scripts/lib/policy-provider.js +27 -0
  177. package/scripts/lib/prelaunch-activation-readiness.js +409 -0
  178. package/scripts/lib/prelaunch-evidence-store.js +816 -0
  179. package/scripts/lib/prelaunch-intelligence.js +869 -0
  180. package/scripts/lib/pricing-experiment.js +118 -0
  181. package/scripts/lib/pro-moment-events.js +77 -0
  182. package/scripts/lib/pro-moment-state.js +227 -0
  183. package/scripts/lib/pro-moments.js +1216 -0
  184. package/scripts/lib/product-learning-events.js +629 -0
  185. package/scripts/lib/project-profile.js +555 -0
  186. package/scripts/lib/prompt-compiler.js +280 -0
  187. package/scripts/lib/prompt-lint.js +32 -0
  188. package/scripts/lib/prompt-suggestions.js +52 -0
  189. package/scripts/lib/proof-canonical.js +398 -0
  190. package/scripts/lib/proof-drilldown.js +383 -0
  191. package/scripts/lib/proof-events.js +342 -0
  192. package/scripts/lib/proof-history.js +243 -0
  193. package/scripts/lib/proof-metrics.js +296 -0
  194. package/scripts/lib/proof-outcome-evidence.js +134 -0
  195. package/scripts/lib/proof-receipt.js +335 -0
  196. package/scripts/lib/proof-record.js +461 -0
  197. package/scripts/lib/public-activation-distribution-gate.js +258 -0
  198. package/scripts/lib/public-cli.js +3891 -0
  199. package/scripts/lib/public-distribution-truth.js +211 -0
  200. package/scripts/lib/public-install-claim-checker.js +294 -0
  201. package/scripts/lib/publish-provenance-readiness.js +283 -0
  202. package/scripts/lib/readiness-delta.js +218 -0
  203. package/scripts/lib/readiness-evidence-closure.js +196 -0
  204. package/scripts/lib/reentry-memory-capture.js +241 -0
  205. package/scripts/lib/reentry-memory-retrieval.js +302 -0
  206. package/scripts/lib/reentry-memory-status.js +146 -0
  207. package/scripts/lib/reentry-memory-store.js +178 -0
  208. package/scripts/lib/reentry-state.js +66 -0
  209. package/scripts/lib/release-candidate-bundle.js +166 -0
  210. package/scripts/lib/remediation.js +81 -0
  211. package/scripts/lib/repo-map.js +391 -0
  212. package/scripts/lib/run-improvements-lifecycle.js +330 -0
  213. package/scripts/lib/run-improvements.js +789 -0
  214. package/scripts/lib/runtime-decision-policy.js +387 -0
  215. package/scripts/lib/safe-path-engine.js +705 -0
  216. package/scripts/lib/safe-run-controller.js +887 -0
  217. package/scripts/lib/score.js +262 -0
  218. package/scripts/lib/seamless-enforcement.js +329 -0
  219. package/scripts/lib/seamless-outcome.js +689 -0
  220. package/scripts/lib/seamless-reality-gate.js +5043 -0
  221. package/scripts/lib/security-risk-classifier.js +511 -0
  222. package/scripts/lib/security-scan.js +384 -0
  223. package/scripts/lib/session-context-optimizer.js +1211 -0
  224. package/scripts/lib/session-timing.js +315 -0
  225. package/scripts/lib/skill-hygiene.js +805 -0
  226. package/scripts/lib/skill-packs.js +161 -0
  227. package/scripts/lib/skills-operating-layer.js +580 -0
  228. package/scripts/lib/smart-work-routing.js +768 -0
  229. package/scripts/lib/source-catalog.js +700 -0
  230. package/scripts/lib/status-value-summary.js +32 -0
  231. package/scripts/lib/support-bundle.js +578 -0
  232. package/scripts/lib/task-continuation.js +440 -0
  233. package/scripts/lib/test-helpers.js +15 -0
  234. package/scripts/lib/tier.js +38 -0
  235. package/scripts/lib/token-context-quality-gate.js +370 -0
  236. package/scripts/lib/token-cost-capture.js +187 -0
  237. package/scripts/lib/token-cost-intelligence.js +358 -0
  238. package/scripts/lib/token-efficiency-evidence.js +213 -0
  239. package/scripts/lib/token-evidence.js +699 -0
  240. package/scripts/lib/tokenish.js +17 -0
  241. package/scripts/lib/tool-output-sandbox.js +304 -0
  242. package/scripts/lib/trust-audit.js +136 -0
  243. package/scripts/lib/unified-events.js +396 -0
  244. package/scripts/lib/upgrade-interruption-recovery.js +407 -0
  245. package/scripts/lib/usage-ledger.js +201 -0
  246. package/scripts/lib/value-ledger.js +130 -0
  247. package/scripts/lib/value-proof-calibration.js +531 -0
  248. package/scripts/lib/visual-qa.js +231 -0
  249. package/scripts/lib/voice-alpha.js +29 -0
  250. package/scripts/lib/work-aware-orchestration.js +976 -0
  251. package/scripts/lib/work-control-receipts.js +577 -0
  252. package/scripts/lib/work-ledger.js +1123 -0
  253. package/scripts/lib/work-panel-preview.js +352 -0
  254. package/scripts/lib/workflow-discipline.js +280 -0
  255. package/scripts/lib/workflow-signals.js +419 -0
  256. package/scripts/lib/workspace-map.js +281 -0
  257. package/scripts/lib/workspace-registry.js +1367 -0
  258. package/scripts/lib/workspace-resolver.js +480 -0
@@ -0,0 +1,480 @@
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const { ensureCcoDirs, nowIso } = require("../fsx");
6
+
7
+ // Avorelo runtime artifact patterns to keep out of git
8
+ const GITIGNORE_PATTERNS = Object.freeze([
9
+ ".claude/cco/orchestration/",
10
+ ".claude/cco/security/",
11
+ ".claude/cco/events/",
12
+ ".claude/cco/memory/",
13
+ ".claude/cco/metrics/",
14
+ ".claude/cco/reports/",
15
+ ".claude/cco/context/",
16
+ ".claude/cco/state/activation.json",
17
+ ".claude/cco/state/onboarding.json",
18
+ ".claude/cco/state/context-pack.json",
19
+ ".claude/cco/state/reentry-carry-forward.json",
20
+ ]);
21
+
22
+ const GITIGNORE_BLOCK_HEADER = "# Avorelo runtime artifacts";
23
+ const GITIGNORE_BLOCK_FOOTER = "# end Avorelo runtime artifacts";
24
+
25
+ // Readiness keys and their descriptions
26
+ const READINESS_CHECKS = Object.freeze([
27
+ { id: "workspace_detected", label: "Workspace connected", required: true },
28
+ { id: "runtime_dirs", label: "Runtime directories", required: true },
29
+ { id: "local_config", label: "Local config", required: true },
30
+ { id: "gitignore_ready", label: "Runtime artifacts ignored", required: false },
31
+ { id: "workspace_registry", label: "Workspace registry", required: true },
32
+ { id: "brain_pack", label: "Brain pack", required: true },
33
+ { id: "session_context", label: "Session context ready", required: true },
34
+ { id: "operating_value", label: "Value tracking baseline", required: true },
35
+ { id: "dashboard_preview", label: "Dashboard ready", required: false },
36
+ { id: "proof_summary", label: "Proof summary", required: false },
37
+ { id: "security_baseline", label: "Security checks ready", required: false },
38
+ { id: "model_routing", label: "Routing detected", required: false },
39
+ ]);
40
+
41
+ function safeExists(cwd, relPath) {
42
+ try {
43
+ return fs.existsSync(path.join(cwd, relPath));
44
+ } catch {
45
+ return false;
46
+ }
47
+ }
48
+
49
+ // --- .gitignore management ---
50
+
51
+ function readGitignore(cwd) {
52
+ const abs = path.join(cwd, ".gitignore");
53
+ try {
54
+ return fs.existsSync(abs) ? fs.readFileSync(abs, "utf8") : "";
55
+ } catch {
56
+ return "";
57
+ }
58
+ }
59
+
60
+ function hasGitignoreBlock(content) {
61
+ return content.includes(GITIGNORE_BLOCK_HEADER);
62
+ }
63
+
64
+ function buildGitignoreBlock() {
65
+ return [
66
+ GITIGNORE_BLOCK_HEADER,
67
+ ...GITIGNORE_PATTERNS,
68
+ GITIGNORE_BLOCK_FOOTER,
69
+ "",
70
+ ].join("\n");
71
+ }
72
+
73
+ function ensureGitignorePatterns(cwd, options = {}) {
74
+ if (options.dryRun) {
75
+ const current = readGitignore(cwd);
76
+ if (!hasGitignoreBlock(current)) {
77
+ return { applied: true, dryRun: true, action: "would_append_block" };
78
+ }
79
+ return { applied: false, dryRun: true, action: "already_present" };
80
+ }
81
+
82
+ const abs = path.join(cwd, ".gitignore");
83
+ let current = readGitignore(cwd);
84
+
85
+ if (hasGitignoreBlock(current)) {
86
+ return { applied: false, action: "already_present" };
87
+ }
88
+
89
+ const block = buildGitignoreBlock();
90
+ const separator = current && !current.endsWith("\n") ? "\n" : "";
91
+ const updated = current + separator + "\n" + block;
92
+
93
+ try {
94
+ fs.writeFileSync(abs, updated, "utf8");
95
+ return { applied: true, action: "appended_block" };
96
+ } catch (err) {
97
+ return { applied: false, action: "write_failed", error: err.message };
98
+ }
99
+ }
100
+
101
+ // --- Corrupted state detection and repair ---
102
+
103
+ function detectCorruptedJson(cwd, relPath) {
104
+ const abs = path.join(cwd, relPath);
105
+ if (!fs.existsSync(abs)) return { exists: false, corrupted: false };
106
+ try {
107
+ const raw = fs.readFileSync(abs, "utf8");
108
+ JSON.parse(raw);
109
+ return { exists: true, corrupted: false };
110
+ } catch {
111
+ return { exists: true, corrupted: true };
112
+ }
113
+ }
114
+
115
+ function moveCorruptedAside(cwd, relPath) {
116
+ const abs = path.join(cwd, relPath);
117
+ const backupAbs = abs + ".corrupted-" + Date.now();
118
+ try {
119
+ fs.renameSync(abs, backupAbs);
120
+ return { moved: true, backup: backupAbs };
121
+ } catch (err) {
122
+ try {
123
+ fs.unlinkSync(abs);
124
+ return { moved: true, deleted: true };
125
+ } catch {
126
+ return { moved: false, error: err.message };
127
+ }
128
+ }
129
+ }
130
+
131
+ // --- Readiness surface generation ---
132
+
133
+ function generateWorkspaceRegistry(cwd, options = {}) {
134
+ if (options.dryRun) return { planned: true };
135
+ try {
136
+ const { buildWorkspaceRegistry, writeWorkspaceRegistry } = require("../workspace-registry");
137
+ const registry = buildWorkspaceRegistry(cwd);
138
+ writeWorkspaceRegistry(cwd, registry);
139
+ return { generated: true, id: registry.registryId || "unknown" };
140
+ } catch (err) {
141
+ return { generated: false, error: err.message };
142
+ }
143
+ }
144
+
145
+ function generateBrainPack(cwd, options = {}) {
146
+ if (options.dryRun) return { planned: true };
147
+ try {
148
+ const { buildBrainPack, writeBrainPack } = require("../brain-pack");
149
+ const bp = buildBrainPack(cwd);
150
+ writeBrainPack(cwd, bp);
151
+ return { generated: true };
152
+ } catch (err) {
153
+ return { generated: false, error: err.message };
154
+ }
155
+ }
156
+
157
+ function generateSessionContext(cwd, options = {}) {
158
+ if (options.dryRun) return { planned: true };
159
+ try {
160
+ const { buildSessionContext, writeSessionContext } = require("../session-context-optimizer");
161
+ const ctx = buildSessionContext(cwd, { target: options.target || "claude" });
162
+ writeSessionContext(cwd, ctx);
163
+ return { generated: true };
164
+ } catch (err) {
165
+ return { generated: false, error: err.message };
166
+ }
167
+ }
168
+
169
+ function generateOperatingValueBaseline(cwd, options = {}) {
170
+ if (options.dryRun) return { planned: true };
171
+ try {
172
+ const { buildOperatingValue, writeOperatingValue } = require("../operating-value");
173
+ const value = buildOperatingValue(cwd);
174
+ writeOperatingValue(cwd, value);
175
+ // Explicitly: do NOT surface any time/token savings in activation
176
+ return {
177
+ generated: true,
178
+ dashboardPath: value.dashboardReady && value.dashboardReady.localDashboardPath
179
+ ? value.dashboardReady.localDashboardPath
180
+ : null,
181
+ valueClaimsShown: false,
182
+ };
183
+ } catch (err) {
184
+ return { generated: false, error: err.message, valueClaimsShown: false };
185
+ }
186
+ }
187
+
188
+ // --- Readiness verification ---
189
+
190
+ function checkReadiness(cwd, context) {
191
+ const checks = {};
192
+
193
+ // workspace_detected
194
+ checks.workspace_detected = Boolean(cwd && cwd.length > 0 && fs.existsSync(cwd));
195
+
196
+ // runtime_dirs
197
+ checks.runtime_dirs = (
198
+ safeExists(cwd, ".claude/cco/state") &&
199
+ safeExists(cwd, ".claude/cco/orchestration") &&
200
+ safeExists(cwd, ".claude/cco/config.json")
201
+ );
202
+
203
+ // local_config
204
+ checks.local_config = safeExists(cwd, ".claude/cco/config.json");
205
+
206
+ // gitignore_ready
207
+ const gitignoreContent = readGitignore(cwd);
208
+ checks.gitignore_ready = hasGitignoreBlock(gitignoreContent);
209
+
210
+ // workspace_registry
211
+ checks.workspace_registry = safeExists(cwd, ".claude/cco/orchestration/workspace-registry/latest-registry.json");
212
+
213
+ // brain_pack
214
+ checks.brain_pack = safeExists(cwd, ".claude/cco/context/brain-pack/latest.json");
215
+
216
+ // session_context
217
+ checks.session_context = safeExists(cwd, ".claude/cco/orchestration/session-context/latest-context.json");
218
+
219
+ // operating_value
220
+ checks.operating_value = safeExists(cwd, ".claude/cco/orchestration/operating-value/latest-value.json");
221
+
222
+ // dashboard_preview (non-required, nice-to-have)
223
+ checks.dashboard_preview = safeExists(cwd, ".claude/cco/orchestration/operating-value/dashboard-preview.md");
224
+
225
+ // proof_summary
226
+ checks.proof_summary = (
227
+ safeExists(cwd, ".claude/cco/orchestration/current-proof.md") ||
228
+ safeExists(cwd, ".claude/cco/orchestration/current-proof.json")
229
+ );
230
+
231
+ // security_baseline (non-blocking — intake may not have run yet)
232
+ checks.security_baseline = safeExists(cwd, ".claude/cco/security");
233
+
234
+ // model_routing (from context, non-blocking)
235
+ checks.model_routing = Boolean(context && context.detectedModelRouting && context.detectedModelRouting.status);
236
+
237
+ // Required checks
238
+ const requiredChecks = READINESS_CHECKS.filter((c) => c.required).map((c) => c.id);
239
+ const failingRequired = requiredChecks.filter((id) => !checks[id]);
240
+ const ready = failingRequired.length === 0;
241
+
242
+ const hardBlockers = context && Array.isArray(context.hardBlockers) ? context.hardBlockers : [];
243
+
244
+ return {
245
+ checks,
246
+ ready: ready && hardBlockers.length === 0,
247
+ failingRequired,
248
+ hardBlockers,
249
+ };
250
+ }
251
+
252
+ // --- Planned repairs (dry-run) ---
253
+
254
+ function planRepairs(cwd, readinessResult) {
255
+ const plans = [];
256
+
257
+ if (!readinessResult.checks.runtime_dirs || !readinessResult.checks.local_config) {
258
+ plans.push({
259
+ id: "ensure_runtime_dirs",
260
+ label: "Create Avorelo runtime directories",
261
+ safeToAutoFix: true,
262
+ domainOwned: true,
263
+ });
264
+ }
265
+
266
+ if (!readinessResult.checks.gitignore_ready) {
267
+ plans.push({
268
+ id: "ensure_gitignore",
269
+ label: "Add Avorelo patterns to .gitignore",
270
+ safeToAutoFix: true,
271
+ domainOwned: true,
272
+ });
273
+ }
274
+
275
+ if (!readinessResult.checks.workspace_registry) {
276
+ plans.push({
277
+ id: "generate_workspace_registry",
278
+ label: "Generate workspace registry",
279
+ safeToAutoFix: true,
280
+ domainOwned: true,
281
+ });
282
+ }
283
+
284
+ if (!readinessResult.checks.brain_pack) {
285
+ plans.push({
286
+ id: "generate_brain_pack",
287
+ label: "Initialize brain pack",
288
+ safeToAutoFix: true,
289
+ domainOwned: true,
290
+ });
291
+ }
292
+
293
+ if (!readinessResult.checks.session_context) {
294
+ plans.push({
295
+ id: "generate_session_context",
296
+ label: "Generate session context baseline",
297
+ safeToAutoFix: true,
298
+ domainOwned: true,
299
+ });
300
+ }
301
+
302
+ if (!readinessResult.checks.operating_value) {
303
+ plans.push({
304
+ id: "generate_operating_value",
305
+ label: "Generate value tracking baseline",
306
+ safeToAutoFix: true,
307
+ domainOwned: true,
308
+ });
309
+ }
310
+
311
+ return plans;
312
+ }
313
+
314
+ // --- Full self-healing repair pass ---
315
+
316
+ function runSelfHealingPass(cwd, context, options = {}) {
317
+ const repairs = [];
318
+ const hardBlockers = [];
319
+ const refreshedSurfaces = [];
320
+ const refreshSkipped = [];
321
+ const refreshErrors = [];
322
+ const forceRefresh = Boolean(options.forceRefresh);
323
+
324
+ // 1. Ensure runtime dirs
325
+ if (!safeExists(cwd, ".claude/cco/state") || !safeExists(cwd, ".claude/cco/config.json")) {
326
+ if (options.dryRun) {
327
+ repairs.push({ id: "ensure_runtime_dirs", status: "planned", label: "Create Avorelo runtime directories" });
328
+ } else {
329
+ try {
330
+ ensureCcoDirs(cwd);
331
+ const { ensureProjectConfig } = require("../fsx");
332
+ ensureProjectConfig(cwd);
333
+ repairs.push({ id: "ensure_runtime_dirs", status: "applied", label: "Created Avorelo runtime directories" });
334
+ } catch (err) {
335
+ hardBlockers.push({
336
+ id: "runtime_dirs_failed",
337
+ message: `Cannot create local runtime directories: ${err.message}`,
338
+ requiresUser: true,
339
+ });
340
+ }
341
+ }
342
+ }
343
+
344
+ if (hardBlockers.length > 0) return { repairs, hardBlockers, refreshedSurfaces, refreshSkipped, refreshErrors };
345
+
346
+ // 2. Gitignore
347
+ const gitignoreResult = ensureGitignorePatterns(cwd, options);
348
+ if (gitignoreResult.applied) {
349
+ repairs.push({ id: "ensure_gitignore", status: options.dryRun ? "planned" : "applied", label: "Added Avorelo patterns to .gitignore" });
350
+ }
351
+
352
+ // 3. Workspace registry
353
+ const registryRel = ".claude/cco/orchestration/workspace-registry/latest-registry.json";
354
+ const registryState = detectCorruptedJson(cwd, registryRel);
355
+ if (registryState.corrupted) {
356
+ if (!options.dryRun) {
357
+ const moved = moveCorruptedAside(cwd, registryRel);
358
+ repairs.push({ id: "repair_corrupted_registry", status: moved.moved ? "applied" : "failed", label: "Moved corrupted registry aside for regeneration" });
359
+ } else {
360
+ repairs.push({ id: "repair_corrupted_registry", status: "planned", label: "Would move corrupted registry aside" });
361
+ }
362
+ }
363
+
364
+ if (forceRefresh && safeExists(cwd, registryRel) && !options.dryRun) {
365
+ // Force-refresh: regenerate even if present
366
+ const result = generateWorkspaceRegistry(cwd, options);
367
+ if (result.generated) {
368
+ repairs.push({ id: "force_refresh_workspace_registry", status: "applied", label: "Force-refreshed workspace registry", detail: result });
369
+ refreshedSurfaces.push("workspace_registry");
370
+ } else {
371
+ refreshErrors.push({ surface: "workspace_registry", error: result.error || "unknown" });
372
+ }
373
+ } else if (!safeExists(cwd, registryRel)) {
374
+ const result = generateWorkspaceRegistry(cwd, options);
375
+ repairs.push({ id: "generate_workspace_registry", status: result.planned ? "planned" : (result.generated ? "applied" : "failed"), label: "Generated workspace registry", detail: result });
376
+ } else if (forceRefresh && options.dryRun) {
377
+ refreshSkipped.push({ surface: "workspace_registry", reason: "dry-run" });
378
+ }
379
+
380
+ // 4. Brain pack
381
+ const brainPackRel = ".claude/cco/context/brain-pack/latest.json";
382
+ const brainPackState = detectCorruptedJson(cwd, brainPackRel);
383
+ if (brainPackState.corrupted) {
384
+ if (!options.dryRun) moveCorruptedAside(cwd, brainPackRel);
385
+ repairs.push({ id: "repair_corrupted_brain_pack", status: options.dryRun ? "planned" : "applied", label: "Moved corrupted brain pack aside" });
386
+ }
387
+
388
+ if (forceRefresh && safeExists(cwd, brainPackRel) && !options.dryRun) {
389
+ const result = generateBrainPack(cwd, options);
390
+ if (result.generated) {
391
+ repairs.push({ id: "force_refresh_brain_pack", status: "applied", label: "Force-refreshed brain pack", detail: result });
392
+ refreshedSurfaces.push("brain_pack");
393
+ } else {
394
+ refreshErrors.push({ surface: "brain_pack", error: result.error || "unknown" });
395
+ }
396
+ } else if (!safeExists(cwd, brainPackRel)) {
397
+ const result = generateBrainPack(cwd, options);
398
+ repairs.push({ id: "generate_brain_pack", status: result.planned ? "planned" : (result.generated ? "applied" : "failed"), label: "Initialized brain pack", detail: result });
399
+ } else if (forceRefresh && options.dryRun) {
400
+ refreshSkipped.push({ surface: "brain_pack", reason: "dry-run" });
401
+ }
402
+
403
+ // 5. Session context
404
+ const sessionContextRel = ".claude/cco/orchestration/session-context/latest-context.json";
405
+ const scState = detectCorruptedJson(cwd, sessionContextRel);
406
+ if (scState.corrupted) {
407
+ if (!options.dryRun) moveCorruptedAside(cwd, sessionContextRel);
408
+ repairs.push({ id: "repair_corrupted_session_context", status: options.dryRun ? "planned" : "applied", label: "Moved corrupted session context aside" });
409
+ }
410
+
411
+ if (forceRefresh && safeExists(cwd, sessionContextRel) && !options.dryRun) {
412
+ const result = generateSessionContext(cwd, { ...options, target: context.target });
413
+ if (result.generated) {
414
+ repairs.push({ id: "force_refresh_session_context", status: "applied", label: "Force-refreshed session context", detail: result });
415
+ refreshedSurfaces.push("session_context");
416
+ } else {
417
+ refreshErrors.push({ surface: "session_context", error: result.error || "unknown" });
418
+ }
419
+ } else if (!safeExists(cwd, sessionContextRel)) {
420
+ const result = generateSessionContext(cwd, { ...options, target: context.target });
421
+ repairs.push({ id: "generate_session_context", status: result.planned ? "planned" : (result.generated ? "applied" : "failed"), label: "Generated session context baseline", detail: result });
422
+ } else if (forceRefresh && options.dryRun) {
423
+ refreshSkipped.push({ surface: "session_context", reason: "dry-run" });
424
+ }
425
+
426
+ // 6. Operating value baseline (readiness only, no savings claim)
427
+ const operatingValueRel = ".claude/cco/orchestration/operating-value/latest-value.json";
428
+ const ovState = detectCorruptedJson(cwd, operatingValueRel);
429
+ if (ovState.corrupted) {
430
+ if (!options.dryRun) moveCorruptedAside(cwd, operatingValueRel);
431
+ repairs.push({ id: "repair_corrupted_operating_value", status: options.dryRun ? "planned" : "applied", label: "Moved corrupted value baseline aside" });
432
+ }
433
+
434
+ if (forceRefresh && safeExists(cwd, operatingValueRel) && !options.dryRun) {
435
+ const result = generateOperatingValueBaseline(cwd, options);
436
+ if (result.generated) {
437
+ repairs.push({
438
+ id: "force_refresh_operating_value",
439
+ status: "applied",
440
+ label: "Force-refreshed value tracking baseline",
441
+ dashboardPath: result.dashboardPath || null,
442
+ valueClaimsShown: false,
443
+ });
444
+ refreshedSurfaces.push("operating_value");
445
+ } else {
446
+ refreshErrors.push({ surface: "operating_value", error: result.error || "unknown" });
447
+ }
448
+ } else if (!safeExists(cwd, operatingValueRel)) {
449
+ const result = generateOperatingValueBaseline(cwd, options);
450
+ repairs.push({
451
+ id: "generate_operating_value",
452
+ status: result.planned ? "planned" : (result.generated ? "applied" : "failed"),
453
+ label: "Generated value tracking baseline",
454
+ dashboardPath: result.dashboardPath || null,
455
+ valueClaimsShown: false,
456
+ });
457
+ } else if (forceRefresh && options.dryRun) {
458
+ refreshSkipped.push({ surface: "operating_value", reason: "dry-run" });
459
+ }
460
+
461
+ return { repairs, hardBlockers, refreshedSurfaces, refreshSkipped, refreshErrors };
462
+ }
463
+
464
+ module.exports = {
465
+ GITIGNORE_PATTERNS,
466
+ READINESS_CHECKS,
467
+ readGitignore,
468
+ hasGitignoreBlock,
469
+ buildGitignoreBlock,
470
+ ensureGitignorePatterns,
471
+ detectCorruptedJson,
472
+ moveCorruptedAside,
473
+ generateWorkspaceRegistry,
474
+ generateBrainPack,
475
+ generateSessionContext,
476
+ generateOperatingValueBaseline,
477
+ checkReadiness,
478
+ planRepairs,
479
+ runSelfHealingPass,
480
+ };
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+
3
+ const { safeReadJson, safeWriteJson, nowIso } = require("../fsx");
4
+
5
+ const ACTIVATION_STATE_REL = ".claude/cco/state/activation.json";
6
+
7
+ function defaultActivationState(cwd) {
8
+ return {
9
+ version: 1,
10
+ status: "not_started",
11
+ createdAt: nowIso(),
12
+ updatedAt: nowIso(),
13
+ project: {
14
+ cwd,
15
+ gitDetected: false,
16
+ repoRoot: null,
17
+ packageJsonDetected: false,
18
+ },
19
+ environment: {
20
+ platform: process.platform,
21
+ nodeDetected: Boolean(process.execPath),
22
+ npmDetected: false,
23
+ gitDetected: false,
24
+ internetLikelyAvailable: true,
25
+ },
26
+ account: {
27
+ connected: false,
28
+ plan: "free",
29
+ features: {},
30
+ },
31
+ detectedHosts: [],
32
+ enabledIntegrations: [],
33
+ repairsAttempted: [],
34
+ manualFixesRequired: [],
35
+ nextAction: {
36
+ label: "Check setup",
37
+ command: "npx avorelo@latest activate",
38
+ reason: "Activation has not run yet.",
39
+ blocking: false,
40
+ },
41
+ firstValue: {
42
+ available: false,
43
+ summary: null,
44
+ },
45
+ };
46
+ }
47
+
48
+ function readActivationState(cwd) {
49
+ return safeReadJson(cwd, ACTIVATION_STATE_REL, defaultActivationState(cwd));
50
+ }
51
+
52
+ function buildActivationState(input) {
53
+ const existing = input.existingState || defaultActivationState(input.project?.cwd || process.cwd());
54
+ const createdAt = existing.createdAt || nowIso();
55
+ return {
56
+ version: 1,
57
+ status: input.status || existing.status || "not_started",
58
+ createdAt,
59
+ updatedAt: nowIso(),
60
+ project: input.project || existing.project,
61
+ environment: input.environment || existing.environment,
62
+ account: input.account || existing.account,
63
+ detectedHosts: Array.isArray(input.detectedHosts) ? input.detectedHosts : existing.detectedHosts,
64
+ enabledIntegrations: Array.isArray(input.enabledIntegrations) ? input.enabledIntegrations : existing.enabledIntegrations,
65
+ repairsAttempted: Array.isArray(input.repairsAttempted) ? input.repairsAttempted : existing.repairsAttempted,
66
+ manualFixesRequired: Array.isArray(input.manualFixesRequired) ? input.manualFixesRequired : existing.manualFixesRequired,
67
+ nextAction: input.nextAction || existing.nextAction,
68
+ firstValue: input.firstValue || existing.firstValue,
69
+ };
70
+ }
71
+
72
+ function writeActivationState(cwd, state) {
73
+ safeWriteJson(cwd, ACTIVATION_STATE_REL, state);
74
+ return state;
75
+ }
76
+
77
+ module.exports = {
78
+ ACTIVATION_STATE_REL,
79
+ defaultActivationState,
80
+ readActivationState,
81
+ buildActivationState,
82
+ writeActivationState,
83
+ };