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,417 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
5
+
6
+ const CONTRACT = "avorelo.adapterReadiness.v1";
7
+ const SCHEMA_VERSION = 1;
8
+
9
+ const READINESS_DIR_REL = ".claude/cco/orchestration/adapter-readiness";
10
+ const LATEST_READINESS_REL = `${READINESS_DIR_REL}/latest-readiness.json`;
11
+
12
+ // Host detection config — expanded to all 7 hosts (PR #163)
13
+ const HOST_CONFIGS = Object.freeze([
14
+ {
15
+ host: "cli",
16
+ label: "CLI (local)",
17
+ configPaths: [],
18
+ hookConfigPath: null,
19
+ markers: [],
20
+ fallback: true,
21
+ alwaysAvailable: true,
22
+ },
23
+ {
24
+ host: "claude_code",
25
+ label: "Claude Code",
26
+ configPaths: [".claude/settings.json", ".claude/settings.local.json"],
27
+ hookConfigPath: ".claude/settings.json",
28
+ markers: [".claude"],
29
+ },
30
+ {
31
+ host: "codex",
32
+ label: "Codex CLI",
33
+ configPaths: ["codex.yaml", ".codex/config.yaml"],
34
+ hookConfigPath: null,
35
+ markers: ["codex.yaml", ".codex"],
36
+ partialOnly: true,
37
+ },
38
+ {
39
+ host: "vscode",
40
+ label: "VS Code",
41
+ configPaths: [".vscode/settings.json"],
42
+ hookConfigPath: null,
43
+ markers: [".vscode"],
44
+ partialOnly: true,
45
+ },
46
+ {
47
+ host: "cursor",
48
+ label: "Cursor",
49
+ configPaths: [".cursor/settings.json"],
50
+ hookConfigPath: null,
51
+ markers: [".cursor"],
52
+ partialOnly: true,
53
+ },
54
+ {
55
+ host: "openhands",
56
+ label: "OpenHands",
57
+ configPaths: [".openhands/config.yaml", ".openhands/hooks.json"],
58
+ hookConfigPath: ".openhands/hooks.json",
59
+ markers: [".openhands"],
60
+ unsupportedUnlessDetected: true,
61
+ },
62
+ {
63
+ host: "unknown",
64
+ label: "Unknown/Generic",
65
+ configPaths: [],
66
+ hookConfigPath: null,
67
+ markers: [],
68
+ fallback: true,
69
+ },
70
+ ]);
71
+
72
+ function ensureDir(dir) {
73
+ fs.mkdirSync(dir, { recursive: true });
74
+ }
75
+
76
+ function nowIso() {
77
+ return new Date().toISOString();
78
+ }
79
+
80
+ function safeWriteJson(filePath, data) {
81
+ ensureDir(path.dirname(filePath));
82
+ fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
83
+ }
84
+
85
+ function safeExists(p) {
86
+ try {
87
+ return fs.existsSync(p);
88
+ } catch {
89
+ return false;
90
+ }
91
+ }
92
+
93
+ function safeReadJson(filePath) {
94
+ try {
95
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
96
+ } catch {
97
+ return null;
98
+ }
99
+ }
100
+
101
+ function detectHost(cwd, hostConfig) {
102
+ if (hostConfig.fallback) {
103
+ return {
104
+ host: hostConfig.host,
105
+ label: hostConfig.label,
106
+ detected: false, // generic_cli is a fallback, not detected via markers
107
+ fallback: true,
108
+ };
109
+ }
110
+
111
+ for (const marker of hostConfig.markers) {
112
+ if (safeExists(path.join(cwd, marker))) {
113
+ return {
114
+ host: hostConfig.host,
115
+ label: hostConfig.label,
116
+ detected: true,
117
+ fallback: false,
118
+ };
119
+ }
120
+ }
121
+
122
+ return {
123
+ host: hostConfig.host,
124
+ label: hostConfig.label,
125
+ detected: false,
126
+ fallback: false,
127
+ };
128
+ }
129
+
130
+ function inspectHostConfig(cwd, hostConfig) {
131
+ const detection = detectHost(cwd, hostConfig);
132
+ const result = {
133
+ host: hostConfig.host,
134
+ label: hostConfig.label,
135
+ detected: detection.detected,
136
+ fallback: detection.fallback || false,
137
+ configPath: hostConfig.hookConfigPath,
138
+ existingConfig: null,
139
+ configValid: null,
140
+ safeToAutoModify: false, // Always false — never auto-modify
141
+ previewAvailable: false,
142
+ reasonCodes: [],
143
+ };
144
+
145
+ if (!detection.detected && !detection.fallback) {
146
+ result.reasonCodes.push("HOST_NOT_DETECTED");
147
+ return result;
148
+ }
149
+
150
+ // Check for existing hook config
151
+ if (hostConfig.hookConfigPath) {
152
+ const configAbs = path.join(cwd, hostConfig.hookConfigPath);
153
+ if (safeExists(configAbs)) {
154
+ const parsed = safeReadJson(configAbs);
155
+ if (parsed !== null) {
156
+ result.existingConfig = { present: true, valid: true, redacted: true };
157
+ result.configValid = true;
158
+ result.reasonCodes.push("CONFIG_FOUND", "CONFIG_VALID");
159
+ } else {
160
+ result.existingConfig = { present: true, valid: false, redacted: true };
161
+ result.configValid = false;
162
+ result.reasonCodes.push("CONFIG_FOUND", "CONFIG_INVALID_JSON");
163
+ }
164
+ } else {
165
+ result.existingConfig = { present: false };
166
+ result.configValid = null;
167
+ result.reasonCodes.push("NO_EXISTING_CONFIG");
168
+ }
169
+ // Preview is available for any detected host with a known config path
170
+ result.previewAvailable = true;
171
+ }
172
+
173
+ if (detection.fallback) {
174
+ result.previewAvailable = true;
175
+ result.reasonCodes.push("GENERIC_CLI_FALLBACK");
176
+ }
177
+
178
+ return result;
179
+ }
180
+
181
+ function detectAdapterReadiness(cwd, options = {}) {
182
+ const hosts = HOST_CONFIGS.map((hc) => inspectHostConfig(cwd, hc));
183
+
184
+ const detectedHosts = hosts.filter((h) => h.detected && !h.fallback);
185
+ const hasDetected = detectedHosts.length > 0;
186
+
187
+ let status;
188
+ if (hasDetected) {
189
+ const allValid = detectedHosts.every((h) => h.configValid !== false);
190
+ const anyInvalid = detectedHosts.some((h) => h.configValid === false);
191
+ if (anyInvalid) {
192
+ status = "needs_review";
193
+ } else {
194
+ status = "partial"; // detected but hooks not installed yet
195
+ }
196
+ } else {
197
+ status = "partial"; // generic_cli fallback available
198
+ }
199
+
200
+ return { hosts, status, hasDetected };
201
+ }
202
+
203
+ // ── Adapter Signal Collection (PR #163) ──────────────────────────────────────
204
+
205
+ function collectAdapterSignals(cwd, options) {
206
+ options = options || {};
207
+ function safeArtifact(rel) {
208
+ try {
209
+ const p = path.join(cwd, rel);
210
+ if (!fs.existsSync(p)) return null;
211
+ return JSON.parse(fs.readFileSync(p, "utf8").replace(/^/, ""));
212
+ } catch { return null; }
213
+ }
214
+ return {
215
+ hostCapabilityMatrix: safeArtifact(".claude/cco/orchestration/adapter-readiness/latest-host-capability-matrix.json"),
216
+ crossHostInstall: safeArtifact(".claude/cco/orchestration/adapter-readiness/latest-cross-host-install.json"),
217
+ crossHostInstallPlan: safeArtifact(".claude/cco/orchestration/adapter-readiness/latest-install-plan.json"),
218
+ crossHostValueFlow: safeArtifact(".claude/cco/orchestration/adapter-readiness/latest-cross-host-value-flow.json"),
219
+ adapterSafetyBoundaries: safeArtifact(".claude/cco/orchestration/adapter-readiness/latest-adapter-safety-boundaries.json"),
220
+ hostSupportContext: safeArtifact(".claude/cco/orchestration/adapter-readiness/latest-host-support-context.json"),
221
+ browserProofPreflight: safeArtifact(".claude/cco/orchestration/adapter-readiness/latest-browser-proof-preflight.json"),
222
+ technicalGate: safeArtifact(".claude/cco/orchestration/adapter-readiness/latest-technical-gate.json"),
223
+ supportBundle: safeArtifact(".claude/cco/support/latest-support-bundle.json"),
224
+ };
225
+ }
226
+
227
+ function scoreAdapterReadiness(signals, options) {
228
+ options = options || {};
229
+ // If technical gate is available, use its score
230
+ if (signals && signals.technicalGate && typeof signals.technicalGate.score === "number") {
231
+ return {
232
+ score: signals.technicalGate.score,
233
+ verdict: signals.technicalGate.verdict || (signals.technicalGate.score >= 90 ? "adapter_ready" : signals.technicalGate.score >= 60 ? "adapter_partial" : "adapter_not_ready"),
234
+ basis: "technical_gate",
235
+ };
236
+ }
237
+ // Compute from sub-signal statuses
238
+ const weights = { adapterSafetyBoundaries: 25, crossHostValueFlow: 20, hostCapabilityMatrix: 15, crossHostInstall: 15, hostSupportContext: 15, browserProofPreflight: 10 };
239
+ const statusScore = { pass: 1.0, warn: 0.5, blocked: 0.0, info: 1.0 };
240
+ let earned = 0;
241
+ const total = Object.values(weights).reduce(function(a, b) { return a + b; }, 0);
242
+ Object.keys(weights).forEach(function(key) {
243
+ const sig = signals && signals[key];
244
+ const s = (sig && sig.status) || "warn";
245
+ earned += weights[key] * (statusScore[s] != null ? statusScore[s] : 0.5);
246
+ });
247
+ const score = Math.round((earned / total) * 100);
248
+ return {
249
+ score,
250
+ verdict: score >= 90 ? "adapter_ready" : score >= 60 ? "adapter_partial" : "adapter_not_ready",
251
+ basis: "signal_aggregation",
252
+ };
253
+ }
254
+
255
+ function detectHostCapabilities(cwd, options) {
256
+ // Returns per-host detection + capabilities from host-capability-matrix if available
257
+ try {
258
+ const { HOST_DEFS, inspectHostCapabilities } = require("./host-capability-matrix");
259
+ return HOST_DEFS.map(function(def) { return inspectHostCapabilities(cwd, def); });
260
+ } catch (e) {
261
+ // Fallback: use local HOST_CONFIGS
262
+ return HOST_CONFIGS.map(function(hc) { return inspectHostConfig(cwd, hc); });
263
+ }
264
+ }
265
+
266
+ function classifyHostStatus(hostConfig, inspected) {
267
+ // cli/unknown/generic_cli fallback: always ready
268
+ if (hostConfig.alwaysAvailable || hostConfig.host === "cli" || hostConfig.host === "unknown") return "ready";
269
+ if (inspected.detected) {
270
+ // Never claim fully "ready" without verified evidence — use "partial"
271
+ return "partial";
272
+ }
273
+ // Not detected
274
+ if (hostConfig.unsupportedUnlessDetected) return "unsupported";
275
+ if (hostConfig.partialOnly) return "unknown";
276
+ return "unknown";
277
+ }
278
+
279
+ function buildAdapterReadiness(cwd, options = {}) {
280
+ const { hosts, status: detectedStatus, hasDetected } = detectAdapterReadiness(cwd, options);
281
+ const signals = collectAdapterSignals(cwd, options);
282
+ const { score, verdict, basis } = scoreAdapterReadiness(signals, options);
283
+
284
+ // Build hostStatuses from detection
285
+ const hostStatuses = {};
286
+ HOST_CONFIGS.forEach(function(hc) {
287
+ const inspected = hosts.find(function(h) { return h.host === hc.host; }) || { detected: false };
288
+ hostStatuses[hc.host] = classifyHostStatus(hc, inspected);
289
+ });
290
+
291
+ const readyHosts = Object.keys(hostStatuses).filter(function(k) { return hostStatuses[k] === "ready"; });
292
+ const partialHosts = Object.keys(hostStatuses).filter(function(k) { return hostStatuses[k] === "partial"; });
293
+ const unsupportedHosts = Object.keys(hostStatuses).filter(function(k) { return hostStatuses[k] === "unsupported"; });
294
+
295
+ const blockers = [];
296
+ const warnings = [];
297
+
298
+ // CLI must always be ready
299
+ if (!readyHosts.includes("cli")) {
300
+ blockers.push({ id: "cli_not_ready", message: "CLI host is not available — local path broken." });
301
+ }
302
+ if (unsupportedHosts.length > 0) {
303
+ warnings.push({ id: "unsupported_hosts", message: "Unsupported hosts caveated: " + unsupportedHosts.join(", ") });
304
+ }
305
+ if (score < 60 && !blockers.length) {
306
+ warnings.push({ id: "low_score", message: "Adapter readiness score " + score + "/100 — run sub-module commands to improve." });
307
+ }
308
+
309
+ const status = blockers.length > 0 ? "blocked" : (score >= 90 && !warnings.length) ? "pass" : "warn";
310
+
311
+ let recommendedNextPr;
312
+ if (blockers.length > 0) recommendedNextPr = "Repair: CLI adapter path broken";
313
+ else if (score >= 90) recommendedNextPr = "Alpha Launch Candidate Prep";
314
+ else if (score >= 60) recommendedNextPr = "Run cross-host sub-module commands to improve score";
315
+ else recommendedNextPr = "Run: node bin/avorelo adapter-readiness-technical --json";
316
+
317
+ const recommendedMode = "preview_only";
318
+ let nextAction;
319
+ if (detectedStatus === "needs_review") {
320
+ nextAction = "Review invalid config file(s) before applying hook preview.";
321
+ } else if (hasDetected) {
322
+ nextAction = "Review the generated hook config preview. Apply requires explicit user approval.";
323
+ } else {
324
+ nextAction = "No host adapter detected. CLI fallback available.";
325
+ }
326
+
327
+ return {
328
+ contract: CONTRACT,
329
+ schemaVersion: SCHEMA_VERSION,
330
+ createdAt: nowIso(),
331
+ status,
332
+ score,
333
+ verdict,
334
+ scoreBasis: basis,
335
+ hosts,
336
+ hostStatuses,
337
+ readyHosts,
338
+ partialHosts,
339
+ unsupportedHosts,
340
+ blockers,
341
+ warnings,
342
+ recommendedNextPr,
343
+ recommendedMode,
344
+ nextAction,
345
+ approvalRequiredBeforeApply: true,
346
+ noWorksEverywhereClaim: true,
347
+ noPublicLaunchClaim: true,
348
+ redacted: true,
349
+ };
350
+ }
351
+
352
+ function writeAdapterReadiness(cwd, readiness) {
353
+ const absPath = path.join(cwd, LATEST_READINESS_REL);
354
+ ensureDir(path.dirname(absPath));
355
+ safeWriteJson(absPath, readiness);
356
+ return { path: LATEST_READINESS_REL, written: true };
357
+ }
358
+
359
+ function buildAdapterReadinessSurface(cwd, options = {}) {
360
+ const readiness = buildAdapterReadiness(cwd, options);
361
+ const writeResult = writeAdapterReadiness(cwd, readiness);
362
+ return { readiness, writeResult };
363
+ }
364
+
365
+ function formatAdapterReadinessText(readiness, options = {}) {
366
+ const debug = options.debug || false;
367
+ const lines = [`Avorelo adapter readiness: ${readiness.status}.`, ""];
368
+
369
+ const detected = (readiness.hosts || []).filter((h) => h.detected && !h.fallback);
370
+ const fallback = (readiness.hosts || []).filter((h) => h.fallback);
371
+
372
+ if (detected.length > 0) {
373
+ lines.push("Detected hosts:");
374
+ for (const h of detected) {
375
+ const configNote = h.existingConfig && h.existingConfig.present && h.existingConfig.valid
376
+ ? "existing config valid"
377
+ : h.existingConfig && h.existingConfig.present && h.existingConfig.valid === false
378
+ ? "existing config invalid — needs review"
379
+ : "no existing config";
380
+ lines.push(` - ${h.label}: ${configNote}`);
381
+ }
382
+ } else {
383
+ lines.push("No host adapter detected. Generic CLI fallback available.");
384
+ }
385
+
386
+ lines.push("", `Recommended mode: ${readiness.recommendedMode}`);
387
+ lines.push("Safe to auto-modify: false (approval required before any config change)");
388
+ lines.push(`Next: ${readiness.nextAction}`);
389
+
390
+ if (debug) {
391
+ lines.push("", "All hosts:");
392
+ for (const h of readiness.hosts || []) {
393
+ lines.push(` [${h.host}] detected=${h.detected} previewAvailable=${h.previewAvailable} configPath=${h.configPath || "none"}`);
394
+ if (h.reasonCodes && h.reasonCodes.length > 0) {
395
+ lines.push(` Reason codes: ${h.reasonCodes.join(", ")}`);
396
+ }
397
+ }
398
+ }
399
+
400
+ return lines.join("\n");
401
+ }
402
+
403
+ module.exports = {
404
+ CONTRACT,
405
+ SCHEMA_VERSION,
406
+ LATEST_READINESS_REL,
407
+ HOST_CONFIGS,
408
+ detectAdapterReadiness,
409
+ buildAdapterReadiness,
410
+ writeAdapterReadiness,
411
+ collectAdapterSignals,
412
+ scoreAdapterReadiness,
413
+ detectHostCapabilities,
414
+ classifyHostStatus,
415
+ buildAdapterReadinessSurface,
416
+ formatAdapterReadinessText,
417
+ };