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,546 @@
1
+ "use strict";
2
+
3
+ const crypto = require("crypto");
4
+ const path = require("path");
5
+ const { nowIso, safeWriteJson } = require("../fsx");
6
+ const { detectProject, detectEnvironment } = require("./detect-environment");
7
+ const { detectAiSurfaces, detectModelRouting } = require("./ai-surface-detector");
8
+ const { runRepairEngine } = require("./repair-engine");
9
+ const {
10
+ checkReadiness,
11
+ planRepairs,
12
+ runSelfHealingPass,
13
+ } = require("./activation-self-healing");
14
+ const { appendProductLearningEvent } = require("../product-learning-events");
15
+
16
+ const ACTIVATION_CONTRACT = "avorelo.activation.v1";
17
+ const ACTIVATION_SCHEMA_VERSION = 1;
18
+ const MAX_REPAIR_ATTEMPTS = 3;
19
+
20
+ function createActivationId() {
21
+ return `act-${Date.now()}-${crypto.randomBytes(3).toString("hex")}`;
22
+ }
23
+
24
+ function defaultResult(cwd) {
25
+ return {
26
+ schemaVersion: ACTIVATION_SCHEMA_VERSION,
27
+ contract: ACTIVATION_CONTRACT,
28
+ activationId: createActivationId(),
29
+ startedAt: nowIso(),
30
+ completedAt: null,
31
+ cwd: cwd || process.cwd(),
32
+ workspaceRoot: null,
33
+ status: "not_started",
34
+ ready: false,
35
+ attempts: 0,
36
+ maxAttempts: MAX_REPAIR_ATTEMPTS,
37
+ detectedEnvironment: {},
38
+ detectedAiSurfaces: [],
39
+ detectedModelRouting: { status: "unknown" },
40
+ safeFixesPlanned: [],
41
+ safeFixesApplied: [],
42
+ unsafeBlockers: [],
43
+ hardBlockers: [],
44
+ verificationChecks: {},
45
+ readiness: {},
46
+ generatedReceipts: [],
47
+ dashboardPath: null,
48
+ valueTrackingReady: false,
49
+ valueClaimsShown: false,
50
+ nextAction: null,
51
+ agentRepairInstructions: null,
52
+ firstValueReadiness: null,
53
+ forceRefresh: false,
54
+ refreshedSurfaces: [],
55
+ refreshSkipped: [],
56
+ refreshErrors: [],
57
+ errors: [],
58
+ redacted: true,
59
+ };
60
+ }
61
+
62
+ function buildReadinessLabels(checks) {
63
+ const labels = [];
64
+ if (checks.workspace_detected) labels.push("Workspace connected");
65
+ if (checks.model_routing) labels.push("Routing detected");
66
+ if (checks.workspace_registry) labels.push("Registry ready");
67
+ if (checks.session_context) labels.push("Session context ready");
68
+ if (checks.security_baseline) labels.push("Security checks ready");
69
+ if (checks.dashboard_preview || checks.operating_value) labels.push("Dashboard ready");
70
+ return labels;
71
+ }
72
+
73
+ function buildNextAction(target, readinessChecks) {
74
+ const t = target || "claude";
75
+ const handoffCommand = `node bin/avorelo session-context --handoff --target ${t}`;
76
+ const dashboardCommand = "node bin/avorelo dashboard --value";
77
+
78
+ if (t === "codex") {
79
+ return {
80
+ handoff: "node bin/avorelo session-context --handoff --target codex",
81
+ dashboard: dashboardCommand,
82
+ note: "Paste handoff output into your Codex prompt for session continuity.",
83
+ };
84
+ }
85
+ if (t === "local-model") {
86
+ return {
87
+ handoff: "node bin/avorelo session-context --handoff --target local-model",
88
+ dashboard: dashboardCommand,
89
+ note: "Local model target prepared with compact session context.",
90
+ };
91
+ }
92
+ return {
93
+ handoff: handoffCommand,
94
+ dashboard: dashboardCommand,
95
+ note: "Paste handoff output at the start of your next Claude Code session.",
96
+ };
97
+ }
98
+
99
+ function buildFirstValueReadiness(checks, nextAction) {
100
+ const missing = [];
101
+ if (!checks.session_context) missing.push("session_context");
102
+ if (!checks.workspace_registry) missing.push("workspace_registry");
103
+ if (!checks.brain_pack) missing.push("brain_pack");
104
+ if (!checks.operating_value) missing.push("operating_value");
105
+ if (!checks.dashboard_preview) missing.push("dashboard_preview");
106
+ if (!checks.proof_summary) missing.push("proof_summary");
107
+ if (!checks.security_baseline) missing.push("security_baseline");
108
+
109
+ const ready = missing.filter((k) => ["session_context", "workspace_registry", "brain_pack", "operating_value"].includes(k)).length === 0;
110
+
111
+ return {
112
+ ready,
113
+ sessionContextReady: Boolean(checks.session_context),
114
+ targetHandoffReady: Boolean(checks.session_context),
115
+ dashboardValueReady: Boolean(checks.dashboard_preview || checks.operating_value),
116
+ operatingValueReady: Boolean(checks.operating_value),
117
+ workspaceRegistryReady: Boolean(checks.workspace_registry),
118
+ brainPackReady: Boolean(checks.brain_pack),
119
+ proofReady: Boolean(checks.proof_summary),
120
+ capabilityRecommendationReady: Boolean(checks.workspace_registry && checks.brain_pack),
121
+ securityBaselineReady: Boolean(checks.security_baseline),
122
+ nextAction: nextAction && nextAction.handoff ? nextAction.handoff : "node bin/avorelo session-context --handoff --target claude",
123
+ missing,
124
+ };
125
+ }
126
+
127
+ function emitActivationEvent(cwd, eventName, payload, dryRun) {
128
+ if (dryRun) return;
129
+ try {
130
+ appendProductLearningEvent(cwd, {
131
+ eventName,
132
+ category: "activation",
133
+ surface: "local",
134
+ status: "observed",
135
+ payload: payload || {},
136
+ });
137
+ } catch {
138
+ // event emission is best-effort; never fail activation
139
+ }
140
+ }
141
+
142
+ function buildAgentRepairInstructions(result) {
143
+ // Use only required-check failures so optional checks don't pollute the repair plan
144
+ const remainingFailing = result.readiness && Array.isArray(result.readiness.failing)
145
+ ? result.readiness.failing
146
+ : Object.entries(result.verificationChecks || {}).filter(([, v]) => !v).map(([k]) => k);
147
+
148
+ return {
149
+ schemaVersion: 1,
150
+ contract: "avorelo.activation.agent-repair.v1",
151
+ activationId: result.activationId,
152
+ status: result.status,
153
+ ready: result.ready,
154
+ attemptsUsed: result.attempts,
155
+ maxAttempts: result.maxAttempts,
156
+ failingChecks: remainingFailing,
157
+ hardBlockers: result.hardBlockers,
158
+ safeFixesApplied: result.safeFixesApplied,
159
+ unsafeBlockers: result.unsafeBlockers,
160
+ nextRepairCommand: "node bin/avorelo activate --repair",
161
+ instructions: [
162
+ "Run `node bin/avorelo activate --repair` to retry the self-healing pass.",
163
+ "If a hard blocker is listed, address it and rerun activation.",
164
+ "If failingChecks remain after repair, inspect each path manually.",
165
+ "All safe/domain-owned fixes have already been attempted automatically.",
166
+ "Only proceed with changes listed in this repair plan.",
167
+ "Do not delete user source files, modify business logic, or change CI behavior.",
168
+ ],
169
+ };
170
+ }
171
+
172
+ function runActivationV1(cwd, options = {}) {
173
+ const result = defaultResult(cwd);
174
+ result.workspaceRoot = cwd;
175
+ result.forceRefresh = Boolean(options.forceRefresh);
176
+
177
+ // Status: scanning
178
+ result.status = "scanning";
179
+
180
+ // Emit activation_started
181
+ emitActivationEvent(cwd, "activation_started", {
182
+ forceRefresh: result.forceRefresh,
183
+ dryRun: Boolean(options.dryRun),
184
+ target: options.target || "claude",
185
+ }, options.dryRun);
186
+
187
+ try {
188
+ // Phase: environment detection
189
+ result.detectedEnvironment = detectEnvironment(cwd, { env: options.env });
190
+ result.detectedAiSurfaces = detectAiSurfaces(cwd, { env: options.env });
191
+ result.detectedModelRouting = detectModelRouting(cwd, { env: options.env });
192
+
193
+ // Emit scan completed
194
+ emitActivationEvent(cwd, "activation_scan_completed", {
195
+ aiSurfaceCount: result.detectedAiSurfaces.length,
196
+ routingStatus: result.detectedModelRouting.status,
197
+ nodeDetected: result.detectedEnvironment.nodeDetected,
198
+ }, options.dryRun);
199
+
200
+ if (result.detectedModelRouting.status && result.detectedModelRouting.status !== "unknown") {
201
+ emitActivationEvent(cwd, "activation_model_routing_detected", {
202
+ routingStatus: result.detectedModelRouting.status,
203
+ envProviderCount: (result.detectedModelRouting.envProviders || []).length,
204
+ }, options.dryRun);
205
+ }
206
+
207
+ // Hard blocker: Node missing
208
+ if (!result.detectedEnvironment.nodeDetected) {
209
+ result.hardBlockers.push({
210
+ id: "node_missing",
211
+ message: "Node.js is required but not detected. Install Node.js and rerun activation.",
212
+ requiresUser: true,
213
+ });
214
+ }
215
+
216
+ // Early exit if hard blockers at scan phase
217
+ if (result.hardBlockers.length > 0) {
218
+ result.status = "blocked_hard";
219
+ result.ready = false;
220
+ result.completedAt = nowIso();
221
+ result.agentRepairInstructions = buildAgentRepairInstructions(result);
222
+ emitActivationEvent(cwd, "activation_hard_blocker_detected", {
223
+ blockerCount: result.hardBlockers.length,
224
+ firstBlockerId: result.hardBlockers[0] && result.hardBlockers[0].id,
225
+ }, options.dryRun);
226
+ return result;
227
+ }
228
+
229
+ // Phase: repair + verify loop
230
+ for (let attempt = 0; attempt < MAX_REPAIR_ATTEMPTS; attempt++) {
231
+ result.attempts = attempt + 1;
232
+ result.status = "repairing";
233
+
234
+ // Run existing repair engine (dirs, config, context-pack, host configuration)
235
+ const repairEngineResult = runRepairEngine(cwd, {
236
+ environment: result.detectedEnvironment,
237
+ project: detectProject(cwd, { env: options.env }),
238
+ detectedHosts: [],
239
+ existingState: null,
240
+ doctor: null,
241
+ }, { repair: !options.dryRun });
242
+
243
+ const engineRepairs = repairEngineResult.repairsAttempted || [];
244
+
245
+ // Run self-healing pass (gitignore, registry, brain-pack, session-context, operating-value)
246
+ const healingContext = {
247
+ target: options.target,
248
+ detectedModelRouting: result.detectedModelRouting,
249
+ hardBlockers: repairEngineResult.manualFixesRequired
250
+ .filter((f) => f.blocking)
251
+ .map((f) => ({ id: f.id, message: f.reason, requiresUser: true })),
252
+ };
253
+
254
+ const selfHealResult = runSelfHealingPass(cwd, healingContext, {
255
+ dryRun: options.dryRun,
256
+ target: options.target,
257
+ forceRefresh: options.forceRefresh,
258
+ });
259
+
260
+ // Propagate force-refresh results
261
+ if (selfHealResult.refreshedSurfaces && selfHealResult.refreshedSurfaces.length > 0) {
262
+ result.refreshedSurfaces = selfHealResult.refreshedSurfaces;
263
+ }
264
+ if (selfHealResult.refreshSkipped && selfHealResult.refreshSkipped.length > 0) {
265
+ result.refreshSkipped = selfHealResult.refreshSkipped;
266
+ }
267
+ if (selfHealResult.refreshErrors && selfHealResult.refreshErrors.length > 0) {
268
+ result.refreshErrors = selfHealResult.refreshErrors;
269
+ }
270
+
271
+ // Collect all hard blockers
272
+ const allHardBlockers = [
273
+ ...healingContext.hardBlockers,
274
+ ...selfHealResult.hardBlockers,
275
+ ];
276
+
277
+ const allRepairs = [
278
+ ...engineRepairs.map((r) => ({ ...r, source: "repair-engine" })),
279
+ ...selfHealResult.repairs.map((r) => ({ ...r, source: "self-healing" })),
280
+ ];
281
+
282
+ // Split into planned vs applied
283
+ const planned = allRepairs.filter((r) => r.status === "planned");
284
+ const applied = allRepairs.filter((r) => r.status === "applied");
285
+
286
+ result.safeFixesPlanned = planned.map((r) => r.label || r.id);
287
+ result.safeFixesApplied = applied.map((r) => r.label || r.id);
288
+
289
+ // Emit per-repair events (aggregate, not per-item)
290
+ if (applied.length > 0) {
291
+ emitActivationEvent(cwd, "activation_safe_fix_applied", {
292
+ fixCount: applied.length,
293
+ attempt: result.attempts,
294
+ }, options.dryRun);
295
+ }
296
+
297
+ if (allHardBlockers.length > 0) {
298
+ result.hardBlockers = allHardBlockers;
299
+ result.status = "blocked_hard";
300
+ emitActivationEvent(cwd, "activation_hard_blocker_detected", {
301
+ blockerCount: allHardBlockers.length,
302
+ firstBlockerId: allHardBlockers[0] && allHardBlockers[0].id,
303
+ }, options.dryRun);
304
+ break;
305
+ }
306
+
307
+ // Phase: verify
308
+ result.status = "verifying";
309
+ const readinessResult = checkReadiness(cwd, healingContext);
310
+ result.verificationChecks = readinessResult.checks;
311
+ result.readiness = {
312
+ labels: buildReadinessLabels(readinessResult.checks),
313
+ failing: readinessResult.failingRequired,
314
+ ready: readinessResult.ready,
315
+ };
316
+
317
+ emitActivationEvent(cwd, "activation_verification_completed", {
318
+ attempt: result.attempts,
319
+ failingRequiredCount: readinessResult.failingRequired.length,
320
+ readinessReady: readinessResult.ready,
321
+ }, options.dryRun);
322
+
323
+ // Extract dashboard path from repairs
324
+ const dashboardRepair = selfHealResult.repairs.find((r) => r.dashboardPath);
325
+ if (dashboardRepair) {
326
+ result.dashboardPath = dashboardRepair.dashboardPath;
327
+ emitActivationEvent(cwd, "activation_dashboard_ready", {
328
+ hasDashboardPath: true,
329
+ }, options.dryRun);
330
+ }
331
+
332
+ // Value tracking ready (without savings claims)
333
+ result.valueTrackingReady = readinessResult.checks.operating_value === true;
334
+ result.valueClaimsShown = false;
335
+
336
+ if (readinessResult.ready) {
337
+ result.status = "ready";
338
+ result.ready = true;
339
+ break;
340
+ }
341
+
342
+ // If still failing required checks and last attempt, mark blocked
343
+ if (attempt === MAX_REPAIR_ATTEMPTS - 1) {
344
+ result.status = "blocked_hard";
345
+ result.hardBlockers.push({
346
+ id: "max_attempts_exceeded",
347
+ message: `Activation could not complete after ${MAX_REPAIR_ATTEMPTS} repair attempts. Failing required checks: ${readinessResult.failingRequired.join(", ")}`,
348
+ requiresUser: false,
349
+ failingChecks: readinessResult.failingRequired,
350
+ });
351
+ }
352
+ }
353
+
354
+ } catch (err) {
355
+ result.status = "failed_internal";
356
+ result.errors.push({ message: err.message });
357
+ result.hardBlockers.push({
358
+ id: "internal_error",
359
+ message: `Activation failed internally: ${err.message}`,
360
+ requiresUser: false,
361
+ });
362
+ }
363
+
364
+ // Build next action
365
+ result.nextAction = buildNextAction(options.target, result.verificationChecks);
366
+
367
+ // Build first value readiness
368
+ result.firstValueReadiness = buildFirstValueReadiness(result.verificationChecks || {}, result.nextAction);
369
+
370
+ // Build agent repair instructions
371
+ result.agentRepairInstructions = buildAgentRepairInstructions(result);
372
+
373
+ // Emit final ready/blocked event
374
+ if (result.ready) {
375
+ emitActivationEvent(cwd, "activation_ready", {
376
+ attemptsUsed: result.attempts,
377
+ surfacesRefreshed: result.refreshedSurfaces.length,
378
+ firstValueReady: result.firstValueReadiness && result.firstValueReadiness.ready,
379
+ }, options.dryRun);
380
+ }
381
+ emitActivationEvent(cwd, "activation_agent_repair_plan_generated", {
382
+ ready: result.ready,
383
+ failingChecksCount: (result.agentRepairInstructions && result.agentRepairInstructions.failingChecks && result.agentRepairInstructions.failingChecks.length) || 0,
384
+ }, options.dryRun);
385
+
386
+ result.completedAt = nowIso();
387
+
388
+ // Write backward-compat activation.json so cco-status / cco-dashboard still work
389
+ if (!options.dryRun) {
390
+ try {
391
+ const { buildActivationState, writeActivationState } = require("./activation-state");
392
+ const compatStatus = result.ready ? "first_value_ready" : (result.status === "blocked_hard" ? "blocked" : result.status);
393
+ writeActivationState(cwd, buildActivationState({
394
+ status: compatStatus,
395
+ project: detectProject(cwd, { env: options.env }),
396
+ environment: result.detectedEnvironment,
397
+ account: { connected: false, plan: "free", features: {} },
398
+ detectedHosts: result.detectedAiSurfaces.map((s) => ({
399
+ id: s.id,
400
+ label: s.label,
401
+ detected: true,
402
+ installState: "detected",
403
+ depth: "shallow",
404
+ limitations: [],
405
+ })),
406
+ enabledIntegrations: result.detectedAiSurfaces.map((s) => s.id),
407
+ repairsAttempted: result.safeFixesApplied.map((label) => ({ id: label, status: "applied", reason: label })),
408
+ manualFixesRequired: result.hardBlockers.map((b) => ({ id: b.id, label: b.message, blocking: true, command: null, reason: b.message })),
409
+ nextAction: result.nextAction
410
+ ? { label: "Start working", command: result.nextAction.handoff || null, reason: "Avorelo is ready.", blocking: false }
411
+ : { label: "Check setup", command: "node bin/avorelo activate", reason: "Activation incomplete.", blocking: false },
412
+ firstValue: { available: result.ready, summary: null },
413
+ }));
414
+ } catch {
415
+ // backward-compat write is best-effort; do not fail activation
416
+ }
417
+ }
418
+ return result;
419
+ }
420
+
421
+ function parseActivationArgs(argv) {
422
+ const args = {
423
+ json: false,
424
+ dryRun: false,
425
+ repair: true,
426
+ target: "claude",
427
+ open: false,
428
+ agentRepair: false,
429
+ forceRefresh: false,
430
+ help: false,
431
+ };
432
+
433
+ for (let i = 0; i < argv.length; i += 1) {
434
+ const token = argv[i];
435
+ if (token === "--json") args.json = true;
436
+ if (token === "--dry-run") args.dryRun = true;
437
+ if (token === "--repair") args.repair = true;
438
+ if (token === "--open") args.open = true;
439
+ if (token === "--agent-repair") args.agentRepair = true;
440
+ if (token === "--force-refresh") args.forceRefresh = true;
441
+ if (token === "--help" || token === "-h") args.help = true;
442
+ if (token === "--target" && argv[i + 1]) {
443
+ args.target = argv[i + 1];
444
+ i += 1;
445
+ }
446
+ if (token.startsWith("--target=")) {
447
+ args.target = token.split("=")[1] || "claude";
448
+ }
449
+ }
450
+
451
+ return args;
452
+ }
453
+
454
+ function formatActivationSuccess(result) {
455
+ const lines = [];
456
+ lines.push("Avorelo is ready.");
457
+ lines.push("");
458
+ lines.push("Ready:");
459
+
460
+ const readyLabels = result.readiness && Array.isArray(result.readiness.labels)
461
+ ? result.readiness.labels
462
+ : ["Workspace connected", "Routing detected", "Registry ready", "Session context ready", "Security checks ready", "Dashboard ready"];
463
+
464
+ for (const label of readyLabels) {
465
+ lines.push(`- ${label}`);
466
+ }
467
+
468
+ lines.push("");
469
+ lines.push("Next:");
470
+ if (result.nextAction && result.nextAction.handoff) {
471
+ lines.push(result.nextAction.handoff);
472
+ }
473
+
474
+ lines.push("");
475
+ lines.push("Dashboard:");
476
+ if (result.nextAction && result.nextAction.dashboard) {
477
+ lines.push(result.nextAction.dashboard);
478
+ }
479
+
480
+ return lines.join("\n");
481
+ }
482
+
483
+ function formatActivationBlocked(result) {
484
+ const lines = [];
485
+ lines.push("Avorelo could not finish activation automatically.");
486
+ lines.push("");
487
+
488
+ if (result.safeFixesApplied.length > 0) {
489
+ lines.push("Fixed:");
490
+ for (const fix of result.safeFixesApplied) {
491
+ lines.push(`- ${fix}`);
492
+ }
493
+ lines.push("");
494
+ }
495
+
496
+ lines.push("Blocked:");
497
+ const blockers = result.hardBlockers.length > 0
498
+ ? result.hardBlockers
499
+ : [{ message: "Unknown hard blocker — rerun activation for details." }];
500
+ for (const b of blockers) {
501
+ lines.push(`- ${b.message || b.id}`);
502
+ }
503
+
504
+ if (result.safeFixesApplied.length > 0) {
505
+ lines.push("");
506
+ lines.push("I already tried:");
507
+ for (const fix of result.safeFixesApplied) {
508
+ lines.push(`- ${fix}`);
509
+ }
510
+ }
511
+
512
+ lines.push("");
513
+ lines.push("Next:");
514
+ if (result.hardBlockers.length > 0 && result.hardBlockers[0].requiresUser) {
515
+ lines.push(result.hardBlockers[0].message || "Address the blocker above and rerun activation.");
516
+ } else {
517
+ lines.push("node bin/avorelo activate --repair");
518
+ }
519
+
520
+ lines.push("");
521
+ lines.push("Agent repair:");
522
+ lines.push("node bin/avorelo activate --agent-repair");
523
+
524
+ return lines.join("\n");
525
+ }
526
+
527
+ function formatActivationText(result) {
528
+ if (result.ready) return formatActivationSuccess(result);
529
+ return formatActivationBlocked(result);
530
+ }
531
+
532
+ function formatActivationJson(result) {
533
+ return JSON.stringify(result, null, 2);
534
+ }
535
+
536
+ module.exports = {
537
+ ACTIVATION_CONTRACT,
538
+ ACTIVATION_SCHEMA_VERSION,
539
+ MAX_REPAIR_ATTEMPTS,
540
+ runActivationV1,
541
+ parseActivationArgs,
542
+ formatActivationSuccess,
543
+ formatActivationBlocked,
544
+ formatActivationText,
545
+ formatActivationJson,
546
+ };