avorelo 0.1.0 → 0.2.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 (260) hide show
  1. package/LICENSE +23 -16
  2. package/README.md +91 -51
  3. package/bin/avorelo.mjs +7 -0
  4. package/dist/avorelo.mjs +14337 -0
  5. package/package.json +106 -120
  6. package/bin/avorelo +0 -9
  7. package/scripts/README.md +0 -40
  8. package/scripts/cco-dashboard.js +0 -252
  9. package/scripts/cco-status.js +0 -430
  10. package/scripts/lib/activation/account-state.js +0 -37
  11. package/scripts/lib/activation/activation-runner.js +0 -546
  12. package/scripts/lib/activation/activation-self-healing.js +0 -480
  13. package/scripts/lib/activation/activation-state.js +0 -83
  14. package/scripts/lib/activation/activation-summary.js +0 -191
  15. package/scripts/lib/activation/adapters/claude-code.js +0 -77
  16. package/scripts/lib/activation/adapters/codex-cli.js +0 -52
  17. package/scripts/lib/activation/adapters/cursor.js +0 -37
  18. package/scripts/lib/activation/adapters/github-agent.js +0 -39
  19. package/scripts/lib/activation/adapters/terminal.js +0 -42
  20. package/scripts/lib/activation/adapters/vscode.js +0 -39
  21. package/scripts/lib/activation/adapters/windsurf.js +0 -37
  22. package/scripts/lib/activation/ai-surface-detector.js +0 -151
  23. package/scripts/lib/activation/connect-account.js +0 -145
  24. package/scripts/lib/activation/detect-environment.js +0 -75
  25. package/scripts/lib/activation/detect-hosts.js +0 -62
  26. package/scripts/lib/activation/format-activation-output.js +0 -109
  27. package/scripts/lib/activation/next-action.js +0 -43
  28. package/scripts/lib/activation/repair-engine.js +0 -219
  29. package/scripts/lib/activation-distribution-readiness.js +0 -507
  30. package/scripts/lib/adapter-conformance.js +0 -176
  31. package/scripts/lib/adapter-readiness.js +0 -417
  32. package/scripts/lib/adapter-safety-boundaries.js +0 -335
  33. package/scripts/lib/adapter-technical-readiness-gate.js +0 -205
  34. package/scripts/lib/agent-access-governance.js +0 -455
  35. package/scripts/lib/agent-enforcement.js +0 -765
  36. package/scripts/lib/agent-policy-profile.js +0 -210
  37. package/scripts/lib/agent-security/action-evaluator.js +0 -507
  38. package/scripts/lib/agent-security/adapter-registry.js +0 -98
  39. package/scripts/lib/agent-security/auto-policy.js +0 -139
  40. package/scripts/lib/agent-security/bounded-scan.js +0 -93
  41. package/scripts/lib/agent-security/enforcement-adapter.js +0 -174
  42. package/scripts/lib/agent-security/enforcement-engine.js +0 -1129
  43. package/scripts/lib/agent-security/file-write-adapter.js +0 -183
  44. package/scripts/lib/agent-security/file-write-rules.js +0 -178
  45. package/scripts/lib/agent-security/index.js +0 -3342
  46. package/scripts/lib/agent-security/instruction-risk.js +0 -181
  47. package/scripts/lib/agent-security/mcp-action-adapter.js +0 -185
  48. package/scripts/lib/agent-security/mcp-action-rules.js +0 -184
  49. package/scripts/lib/agent-security/package-action-adapter.js +0 -175
  50. package/scripts/lib/agent-security/package-action-rules.js +0 -233
  51. package/scripts/lib/agent-security/performance.js +0 -148
  52. package/scripts/lib/agent-security/permission-minimizer.js +0 -403
  53. package/scripts/lib/agent-security/scan-cache.js +0 -74
  54. package/scripts/lib/agent-security/source-trust.js +0 -146
  55. package/scripts/lib/ai-install-prompt.js +0 -288
  56. package/scripts/lib/ai-workspace-hygiene.js +0 -1499
  57. package/scripts/lib/alpha-activation.js +0 -520
  58. package/scripts/lib/alpha-feedback.js +0 -263
  59. package/scripts/lib/alpha-readiness-gate.js +0 -332
  60. package/scripts/lib/anti-gaming.js +0 -169
  61. package/scripts/lib/artifact-health.js +0 -431
  62. package/scripts/lib/attribution.js +0 -180
  63. package/scripts/lib/audit.js +0 -289
  64. package/scripts/lib/avorelo-skill-registry.js +0 -810
  65. package/scripts/lib/batch-jobs.js +0 -71
  66. package/scripts/lib/brain-pack.js +0 -578
  67. package/scripts/lib/brand-boundary.js +0 -424
  68. package/scripts/lib/brand.js +0 -74
  69. package/scripts/lib/browser-capability.js +0 -1048
  70. package/scripts/lib/browser-proof-preflight.js +0 -321
  71. package/scripts/lib/cache-readiness.js +0 -187
  72. package/scripts/lib/canonical-reentry.js +0 -162
  73. package/scripts/lib/capability-packs.js +0 -314
  74. package/scripts/lib/capability-recommender.js +0 -512
  75. package/scripts/lib/capability-registry.js +0 -1059
  76. package/scripts/lib/carry-forward-surfacing.js +0 -194
  77. package/scripts/lib/ccusage-adapter.js +0 -188
  78. package/scripts/lib/company-loop.js +0 -1149
  79. package/scripts/lib/config.js +0 -637
  80. package/scripts/lib/context-acquisition-plan.js +0 -287
  81. package/scripts/lib/context-budget-guard.js +0 -170
  82. package/scripts/lib/context-budget-scanner.js +0 -257
  83. package/scripts/lib/context-optimizer.js +0 -715
  84. package/scripts/lib/context-reduction-plan.js +0 -178
  85. package/scripts/lib/context-safety.js +0 -88
  86. package/scripts/lib/context-savings-engine.js +0 -158
  87. package/scripts/lib/cost-evidence.js +0 -254
  88. package/scripts/lib/cross-host-install-plan.js +0 -308
  89. package/scripts/lib/cross-host-install-readiness.js +0 -237
  90. package/scripts/lib/cross-host-value-flow.js +0 -268
  91. package/scripts/lib/dashboard.js +0 -900
  92. package/scripts/lib/design-partner-feedback.js +0 -346
  93. package/scripts/lib/entitlements.js +0 -100
  94. package/scripts/lib/execution-packet.js +0 -559
  95. package/scripts/lib/experimentation-events.js +0 -547
  96. package/scripts/lib/external-capability-compliance.js +0 -107
  97. package/scripts/lib/external-user-simulation.js +0 -166
  98. package/scripts/lib/failure-recovery-readiness.js +0 -81
  99. package/scripts/lib/failure-recovery.js +0 -419
  100. package/scripts/lib/feedback-intelligence.js +0 -537
  101. package/scripts/lib/feedback-signals.js +0 -205
  102. package/scripts/lib/file-integrity.js +0 -68
  103. package/scripts/lib/fsx.js +0 -127
  104. package/scripts/lib/full-readiness-gate.js +0 -451
  105. package/scripts/lib/guidance-builder.js +0 -174
  106. package/scripts/lib/hook-apply.js +0 -1019
  107. package/scripts/lib/hook-baseline.js +0 -310
  108. package/scripts/lib/hook-config-preview.js +0 -275
  109. package/scripts/lib/hook-contracts.js +0 -290
  110. package/scripts/lib/hook-safety-boundary-readiness.js +0 -80
  111. package/scripts/lib/host-capability-matrix.js +0 -351
  112. package/scripts/lib/host-support-context.js +0 -254
  113. package/scripts/lib/http-hook-action.js +0 -538
  114. package/scripts/lib/install-ai-readiness.js +0 -84
  115. package/scripts/lib/install-intake-risk.js +0 -1037
  116. package/scripts/lib/install-journey-intelligence.js +0 -329
  117. package/scripts/lib/intervention-guidance.js +0 -57
  118. package/scripts/lib/known-limitations.js +0 -115
  119. package/scripts/lib/l8-path-truth.js +0 -146
  120. package/scripts/lib/launch-hardening-gate.js +0 -436
  121. package/scripts/lib/launch-readiness.js +0 -628
  122. package/scripts/lib/learning-memory.js +0 -686
  123. package/scripts/lib/lifecycle-hooks.js +0 -802
  124. package/scripts/lib/local-package-smoke.js +0 -423
  125. package/scripts/lib/local-pricing.js +0 -299
  126. package/scripts/lib/mcp-enforcement.js +0 -311
  127. package/scripts/lib/mcp-least-privilege-policy.js +0 -303
  128. package/scripts/lib/mcp-tool-inventory.js +0 -388
  129. package/scripts/lib/mcp-tool-risk.js +0 -0
  130. package/scripts/lib/memory.js +0 -335
  131. package/scripts/lib/metrics.js +0 -699
  132. package/scripts/lib/micro-proof.js +0 -133
  133. package/scripts/lib/next-run-context.js +0 -436
  134. package/scripts/lib/operating-value.js +0 -1648
  135. package/scripts/lib/optimization-v3.js +0 -122
  136. package/scripts/lib/orchestration/adapters/_shared.js +0 -49
  137. package/scripts/lib/orchestration/adapters/aider.js +0 -18
  138. package/scripts/lib/orchestration/adapters/claude-code.js +0 -35
  139. package/scripts/lib/orchestration/adapters/codex.js +0 -35
  140. package/scripts/lib/orchestration/adapters/gemini-cli.js +0 -18
  141. package/scripts/lib/orchestration/adapters/git.js +0 -25
  142. package/scripts/lib/orchestration/adapters/index.js +0 -31
  143. package/scripts/lib/orchestration/adapters/lm-studio.js +0 -18
  144. package/scripts/lib/orchestration/adapters/ollama.js +0 -18
  145. package/scripts/lib/orchestration/adapters/opencode.js +0 -18
  146. package/scripts/lib/orchestration/adapters/openrouter.js +0 -18
  147. package/scripts/lib/orchestration/adapters/test-runner.js +0 -25
  148. package/scripts/lib/orchestration/cli.js +0 -438
  149. package/scripts/lib/orchestration/execution-manager.js +0 -279
  150. package/scripts/lib/orchestration/handoff.js +0 -314
  151. package/scripts/lib/orchestration/index.js +0 -456
  152. package/scripts/lib/orchestration/inventory.js +0 -47
  153. package/scripts/lib/orchestration/model-discovery.js +0 -498
  154. package/scripts/lib/orchestration/model-profiler.js +0 -170
  155. package/scripts/lib/orchestration/model-profiles.js +0 -252
  156. package/scripts/lib/orchestration/model-refresh-policy.js +0 -72
  157. package/scripts/lib/orchestration/proof-writer.js +0 -349
  158. package/scripts/lib/orchestration/provider-discovery/aider.js +0 -49
  159. package/scripts/lib/orchestration/provider-discovery/claude-code.js +0 -56
  160. package/scripts/lib/orchestration/provider-discovery/codex.js +0 -49
  161. package/scripts/lib/orchestration/provider-discovery/common.js +0 -186
  162. package/scripts/lib/orchestration/provider-discovery/gemini.js +0 -106
  163. package/scripts/lib/orchestration/provider-discovery/lm-studio.js +0 -118
  164. package/scripts/lib/orchestration/provider-discovery/models-dev.js +0 -12
  165. package/scripts/lib/orchestration/provider-discovery/ollama.js +0 -100
  166. package/scripts/lib/orchestration/provider-discovery/opencode.js +0 -47
  167. package/scripts/lib/orchestration/provider-discovery/openrouter.js +0 -44
  168. package/scripts/lib/orchestration/risk-classifier.js +0 -130
  169. package/scripts/lib/orchestration/routing-policy.js +0 -486
  170. package/scripts/lib/orchestration/settings.js +0 -112
  171. package/scripts/lib/orchestration/state.js +0 -165
  172. package/scripts/lib/orchestration/verification-manager.js +0 -138
  173. package/scripts/lib/output-profiles.js +0 -146
  174. package/scripts/lib/package-content-audit.js +0 -368
  175. package/scripts/lib/package-runtime.js +0 -278
  176. package/scripts/lib/plan-surface.js +0 -53
  177. package/scripts/lib/plans.js +0 -2318
  178. package/scripts/lib/policy-provider.js +0 -27
  179. package/scripts/lib/prelaunch-activation-readiness.js +0 -409
  180. package/scripts/lib/prelaunch-evidence-store.js +0 -816
  181. package/scripts/lib/prelaunch-intelligence.js +0 -869
  182. package/scripts/lib/pricing-experiment.js +0 -118
  183. package/scripts/lib/pro-moment-events.js +0 -77
  184. package/scripts/lib/pro-moment-state.js +0 -227
  185. package/scripts/lib/pro-moments.js +0 -1216
  186. package/scripts/lib/product-learning-events.js +0 -629
  187. package/scripts/lib/project-profile.js +0 -555
  188. package/scripts/lib/prompt-compiler.js +0 -280
  189. package/scripts/lib/prompt-lint.js +0 -32
  190. package/scripts/lib/prompt-suggestions.js +0 -52
  191. package/scripts/lib/proof-canonical.js +0 -398
  192. package/scripts/lib/proof-drilldown.js +0 -383
  193. package/scripts/lib/proof-events.js +0 -342
  194. package/scripts/lib/proof-history.js +0 -243
  195. package/scripts/lib/proof-metrics.js +0 -296
  196. package/scripts/lib/proof-outcome-evidence.js +0 -134
  197. package/scripts/lib/proof-receipt.js +0 -335
  198. package/scripts/lib/proof-record.js +0 -461
  199. package/scripts/lib/public-activation-distribution-gate.js +0 -258
  200. package/scripts/lib/public-cli.js +0 -3891
  201. package/scripts/lib/public-distribution-truth.js +0 -211
  202. package/scripts/lib/public-install-claim-checker.js +0 -294
  203. package/scripts/lib/publish-provenance-readiness.js +0 -283
  204. package/scripts/lib/readiness-delta.js +0 -218
  205. package/scripts/lib/readiness-evidence-closure.js +0 -196
  206. package/scripts/lib/reentry-memory-capture.js +0 -241
  207. package/scripts/lib/reentry-memory-retrieval.js +0 -302
  208. package/scripts/lib/reentry-memory-status.js +0 -146
  209. package/scripts/lib/reentry-memory-store.js +0 -178
  210. package/scripts/lib/reentry-state.js +0 -66
  211. package/scripts/lib/release-candidate-bundle.js +0 -166
  212. package/scripts/lib/remediation.js +0 -81
  213. package/scripts/lib/repo-map.js +0 -391
  214. package/scripts/lib/run-improvements-lifecycle.js +0 -330
  215. package/scripts/lib/run-improvements.js +0 -789
  216. package/scripts/lib/runtime-decision-policy.js +0 -387
  217. package/scripts/lib/safe-path-engine.js +0 -705
  218. package/scripts/lib/safe-run-controller.js +0 -887
  219. package/scripts/lib/score.js +0 -262
  220. package/scripts/lib/seamless-enforcement.js +0 -329
  221. package/scripts/lib/seamless-outcome.js +0 -689
  222. package/scripts/lib/seamless-reality-gate.js +0 -5043
  223. package/scripts/lib/security-risk-classifier.js +0 -511
  224. package/scripts/lib/security-scan.js +0 -384
  225. package/scripts/lib/session-context-optimizer.js +0 -1211
  226. package/scripts/lib/session-timing.js +0 -315
  227. package/scripts/lib/skill-hygiene.js +0 -805
  228. package/scripts/lib/skill-packs.js +0 -161
  229. package/scripts/lib/skills-operating-layer.js +0 -580
  230. package/scripts/lib/smart-work-routing.js +0 -768
  231. package/scripts/lib/source-catalog.js +0 -700
  232. package/scripts/lib/status-value-summary.js +0 -32
  233. package/scripts/lib/support-bundle.js +0 -578
  234. package/scripts/lib/task-continuation.js +0 -440
  235. package/scripts/lib/test-helpers.js +0 -15
  236. package/scripts/lib/tier.js +0 -38
  237. package/scripts/lib/token-context-quality-gate.js +0 -370
  238. package/scripts/lib/token-cost-capture.js +0 -187
  239. package/scripts/lib/token-cost-intelligence.js +0 -358
  240. package/scripts/lib/token-efficiency-evidence.js +0 -213
  241. package/scripts/lib/token-evidence.js +0 -699
  242. package/scripts/lib/tokenish.js +0 -17
  243. package/scripts/lib/tool-output-sandbox.js +0 -304
  244. package/scripts/lib/trust-audit.js +0 -136
  245. package/scripts/lib/unified-events.js +0 -396
  246. package/scripts/lib/upgrade-interruption-recovery.js +0 -407
  247. package/scripts/lib/usage-ledger.js +0 -201
  248. package/scripts/lib/value-ledger.js +0 -130
  249. package/scripts/lib/value-proof-calibration.js +0 -531
  250. package/scripts/lib/visual-qa.js +0 -231
  251. package/scripts/lib/voice-alpha.js +0 -29
  252. package/scripts/lib/work-aware-orchestration.js +0 -976
  253. package/scripts/lib/work-control-receipts.js +0 -577
  254. package/scripts/lib/work-ledger.js +0 -1123
  255. package/scripts/lib/work-panel-preview.js +0 -352
  256. package/scripts/lib/workflow-discipline.js +0 -280
  257. package/scripts/lib/workflow-signals.js +0 -419
  258. package/scripts/lib/workspace-map.js +0 -281
  259. package/scripts/lib/workspace-registry.js +0 -1367
  260. package/scripts/lib/workspace-resolver.js +0 -480
@@ -1,507 +0,0 @@
1
- "use strict";
2
-
3
- // ── Activation Distribution Readiness ────────────────────────────────────────
4
- // Contract: avorelo.activationDistributionReadiness.v1
5
- // Answers: "Can a first external user install, activate, see first value,
6
- // understand limitations, and recover safely without founder hand-holding?"
7
- // Does NOT claim public launch readiness. Honest about missing evidence.
8
-
9
- const fs = require("fs");
10
- const path = require("path");
11
- const { nowIso } = require("./fsx");
12
- const { appendProductLearningEvent } = require("./product-learning-events");
13
-
14
- const CONTRACT = "avorelo.activationDistributionReadiness.v1";
15
- const SCHEMA_VERSION = 1;
16
- const ARTIFACT_DIR_REL = ".claude/cco/orchestration/activation-distribution";
17
- const ARTIFACT_REL = ARTIFACT_DIR_REL + "/latest-activation-distribution-readiness.json";
18
-
19
- const SCORE_READY = 85;
20
- const SCORE_WARN = 70;
21
-
22
- const CHECK_WEIGHTS = {
23
- install_command_available: 8,
24
- install_docs_current: 5,
25
- activation_entrypoint_available: 8,
26
- doctor_available: 5,
27
- first_value_surface_available: 8,
28
- clear_next_action_available: 6,
29
- recovery_path_available: 7,
30
- support_bundle_available: 6,
31
- known_limitations_visible: 5,
32
- release_candidate_bundle_safe: 6,
33
- evidence_closure_complete: 6,
34
- external_user_simulation_covered: 6,
35
- token_cost_honest: 7,
36
- feedback_intelligence_honest: 7,
37
- no_public_launch_claim: 8,
38
- safe_next_action_exists: 6,
39
- };
40
-
41
- const TOTAL_WEIGHT = Object.values(CHECK_WEIGHTS).reduce(function(a, b) { return a + b; }, 0);
42
-
43
- function safeReadJson(absPath) {
44
- try {
45
- if (!fs.existsSync(absPath)) return null;
46
- return JSON.parse(fs.readFileSync(absPath, "utf8").replace(/^/, ""));
47
- } catch { return null; }
48
- }
49
-
50
- function pass(id, label, evidence, detail) {
51
- return { id: id, label: label, status: "pass", evidence: evidence || null, detail: detail || null, safeNextAction: null };
52
- }
53
- function warn(id, label, safeNextAction, evidence, detail) {
54
- return { id: id, label: label, status: "warn", evidence: evidence || null, detail: detail || null, safeNextAction: safeNextAction || "Run readiness closure to identify missing evidence." };
55
- }
56
- function blocked(id, label, safeNextAction, evidence, detail) {
57
- return { id: id, label: label, status: "blocked", evidence: evidence || null, detail: detail || null, safeNextAction: safeNextAction || "Fix blocker before proceeding." };
58
- }
59
- function info(id, label, detail) {
60
- return { id: id, label: label, status: "info", evidence: null, detail: detail || null, safeNextAction: null };
61
- }
62
-
63
- function checkInstallCommandAvailable(cwd) {
64
- const binPath = path.join(cwd, "bin", "avorelo");
65
- const hasBin = fs.existsSync(binPath);
66
- const pkgPath = path.join(cwd, "package.json");
67
- const pkg = safeReadJson(pkgPath);
68
- const hasBinField = pkg && pkg.bin && (typeof pkg.bin === "string" || Object.keys(pkg.bin).length > 0);
69
- if (!hasBin && !hasBinField) {
70
- return blocked("install_command_available", "Install command available",
71
- "Create bin/avorelo entry point. Add bin field to package.json.",
72
- null, "No bin/avorelo and no bin field in package.json.");
73
- }
74
- return pass("install_command_available", "Install command available",
75
- { binExists: hasBin, pkgBinField: !!hasBinField }, null);
76
- }
77
-
78
- function checkInstallDocsCurrent(cwd) {
79
- const docsDir = path.join(cwd, "docs");
80
- if (!fs.existsSync(docsDir)) {
81
- return warn("install_docs_current", "Install docs current",
82
- "Create docs/ directory with install instructions.",
83
- null, "No docs directory found.");
84
- }
85
- const docFiles = fs.readdirSync(docsDir).filter(function(f) {
86
- return f.toLowerCase().includes("install") || f.toLowerCase().includes("activation") || f.toLowerCase().includes("readiness");
87
- });
88
- if (docFiles.length === 0) {
89
- return warn("install_docs_current", "Install docs current",
90
- "Add install/activation documentation to docs/ directory.",
91
- null, "No install or activation docs found in docs/.");
92
- }
93
- return pass("install_docs_current", "Install docs current",
94
- { docCount: docFiles.length, examples: docFiles.slice(0, 3) }, null);
95
- }
96
-
97
- function checkActivationEntrypointAvailable(cwd) {
98
- const cliPath = path.join(cwd, "scripts", "lib", "public-cli.js");
99
- if (!fs.existsSync(cliPath)) {
100
- return blocked("activation_entrypoint_available", "Activation entrypoint available",
101
- "Create scripts/lib/public-cli.js with activate command.",
102
- null, "public-cli.js not found.");
103
- }
104
- const content = fs.readFileSync(cliPath, "utf8");
105
- const hasActivate = content.includes('"activate"') || content.includes("'activate'");
106
- const hasInstallAi = content.includes('"install-ai"') || content.includes("'install-ai'");
107
- if (!hasActivate && !hasInstallAi) {
108
- return warn("activation_entrypoint_available", "Activation entrypoint available",
109
- "Add activate or install-ai command to public-cli.js.",
110
- null, "No activate or install-ai command found in public-cli.js.");
111
- }
112
- return pass("activation_entrypoint_available", "Activation entrypoint available",
113
- { hasActivate: hasActivate, hasInstallAi: hasInstallAi }, null);
114
- }
115
-
116
- function checkDoctorAvailable(cwd) {
117
- const cliPath = path.join(cwd, "scripts", "lib", "public-cli.js");
118
- if (!fs.existsSync(cliPath)) {
119
- return warn("doctor_available", "Doctor/readiness check available",
120
- "Add doctor command to public-cli.js.",
121
- null, "public-cli.js not found.");
122
- }
123
- const content = fs.readFileSync(cliPath, "utf8");
124
- const hasDoctor = content.includes('"doctor"') || content.includes("'doctor'");
125
- const hasReadiness = content.includes('"readiness"') || content.includes("'readiness'");
126
- const hasPrelaunhReadiness = content.includes('"prelaunch-readiness"') || content.includes("'prelaunch-readiness'");
127
- if (!hasDoctor && !hasReadiness && !hasPrelaunhReadiness) {
128
- return warn("doctor_available", "Doctor/readiness check available",
129
- "Add a doctor or readiness command so users can self-diagnose setup issues.",
130
- null, "No doctor or readiness command found.");
131
- }
132
- return pass("doctor_available", "Doctor/readiness check available",
133
- { hasDoctor: hasDoctor, hasReadiness: hasReadiness }, null);
134
- }
135
-
136
- function checkFirstValueSurfaceAvailable(cwd) {
137
- const firstValueArtifact = safeReadJson(path.join(cwd, ".claude/cco/orchestration/prelaunch-readiness/latest-activation-readiness.json"));
138
- const valueSummary = safeReadJson(path.join(cwd, ".claude/cco/orchestration/seamless-outcome/latest-value-summary.json"));
139
- const cliPath = path.join(cwd, "scripts", "lib", "public-cli.js");
140
- const hasFirstValueCmd = fs.existsSync(cliPath) &&
141
- (fs.readFileSync(cliPath, "utf8").includes("first-value") || fs.readFileSync(cliPath, "utf8").includes("first_value"));
142
- if (!firstValueArtifact && !valueSummary && !hasFirstValueCmd) {
143
- return warn("first_value_surface_available", "First value surface available",
144
- "Run: node bin/avorelo first-value-check --json to generate first value surface.",
145
- null, "No first-value artifact or command found.");
146
- }
147
- return pass("first_value_surface_available", "First value surface available",
148
- { hasActivationArtifact: !!firstValueArtifact, hasValueSummary: !!valueSummary, hasCliCommand: hasFirstValueCmd }, null);
149
- }
150
-
151
- function checkClearNextActionAvailable(cwd) {
152
- const gate = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-gate.json"));
153
- if (!gate) {
154
- return warn("clear_next_action_available", "Clear next action available",
155
- "Run: node bin/avorelo full-readiness --json to generate gate with safeNextAction.",
156
- null, "Full readiness gate artifact not found.");
157
- }
158
- if (!gate.safeNextAction || gate.safeNextAction.length < 10) {
159
- return warn("clear_next_action_available", "Clear next action available",
160
- "Re-run full-readiness gate. safeNextAction should be specific and actionable.",
161
- gate, "Gate has no safeNextAction or it is too vague.");
162
- }
163
- return pass("clear_next_action_available", "Clear next action available",
164
- { safeNextAction: gate.safeNextAction.slice(0, 80) }, null);
165
- }
166
-
167
- function checkRecoveryPathAvailable(cwd) {
168
- const hardening = safeReadJson(path.join(cwd, ".claude/cco/orchestration/launch-hardening/latest-gate.json"));
169
- const failureRecovery = safeReadJson(path.join(cwd, ".claude/cco/orchestration/launch-hardening/latest-failure-recovery.json"));
170
- const cliPath = path.join(cwd, "scripts", "lib", "public-cli.js");
171
- const hasRecoveryCmd = fs.existsSync(cliPath) &&
172
- (fs.readFileSync(cliPath, "utf8").includes("recovery") || fs.readFileSync(cliPath, "utf8").includes("resume"));
173
- if (!hardening && !failureRecovery && !hasRecoveryCmd) {
174
- return warn("recovery_path_available", "Failure/recovery path available",
175
- "Run: node bin/avorelo launch-hardening --json to verify recovery gates.",
176
- null, "No hardening or failure recovery artifact found.");
177
- }
178
- return pass("recovery_path_available", "Failure/recovery path available",
179
- { hasHardening: !!hardening, hasFailureRecovery: !!failureRecovery, hasCli: hasRecoveryCmd }, null);
180
- }
181
-
182
- function checkSupportBundleAvailable(cwd) {
183
- const bundle = safeReadJson(path.join(cwd, ".claude/cco/support/latest-support-bundle.json"));
184
- if (!bundle) {
185
- return warn("support_bundle_available", "Support bundle available",
186
- "Run: node bin/avorelo support-bundle --json to generate a redacted support bundle.",
187
- null, "Support bundle artifact not found.");
188
- }
189
- if (bundle.redacted !== true) {
190
- return blocked("support_bundle_available", "Support bundle available",
191
- "Regenerate support bundle with redacted: true.",
192
- null, "Support bundle exists but redacted is not true — safety violation.");
193
- }
194
- return pass("support_bundle_available", "Support bundle available",
195
- { redacted: bundle.redacted }, null);
196
- }
197
-
198
- function checkKnownLimitationsVisible(cwd) {
199
- const kl = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-known-limitations.json"));
200
- if (!kl) {
201
- return warn("known_limitations_visible", "Known limitations visible",
202
- "Run: node bin/avorelo known-limitations --json to generate limitations register.",
203
- null, "Known limitations artifact not found.");
204
- }
205
- if (!kl.limitations || kl.limitations.length === 0) {
206
- return warn("known_limitations_visible", "Known limitations visible",
207
- "Known limitations register is empty — must document real limitations.",
208
- null, "Empty limitations register.");
209
- }
210
- const blockers = kl.limitations.filter(function(l) { return l.severity === "blocker" && l.status === "needs_fix"; });
211
- if (blockers.length > 0) {
212
- return blocked("known_limitations_visible", "Known limitations visible",
213
- "Resolve blocker limitations before proceeding with distribution.",
214
- { blockerIds: blockers.map(function(b) { return b.id; }) },
215
- blockers.length + " blocker limitation(s) unresolved.");
216
- }
217
- return pass("known_limitations_visible", "Known limitations visible",
218
- { totalLimitations: kl.limitations.length, blockers: 0 }, null);
219
- }
220
-
221
- function checkReleaseCandidateBundleSafe(cwd) {
222
- const rcb = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-release-candidate-bundle.json"));
223
- if (!rcb) {
224
- return warn("release_candidate_bundle_safe", "Release candidate bundle safe",
225
- "Run: node bin/avorelo release-candidate-bundle --json",
226
- null, "Release candidate bundle not found.");
227
- }
228
- if (rcb.rawContentExcluded !== true) {
229
- return blocked("release_candidate_bundle_safe", "Release candidate bundle safe",
230
- "Regenerate release candidate bundle. rawContentExcluded must be true.",
231
- null, "rawContentExcluded is not true — raw content may be exposed.");
232
- }
233
- return pass("release_candidate_bundle_safe", "Release candidate bundle safe",
234
- { rawContentExcluded: rcb.rawContentExcluded, redacted: rcb.redacted }, null);
235
- }
236
-
237
- function checkEvidenceClosureComplete(cwd) {
238
- const ec = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-evidence-closure.json"));
239
- if (!ec) {
240
- return warn("evidence_closure_complete", "Evidence closure complete",
241
- "Run: node bin/avorelo readiness-closure --json",
242
- null, "Evidence closure artifact not found.");
243
- }
244
- if (ec.status === "complete") {
245
- return pass("evidence_closure_complete", "Evidence closure complete",
246
- { evidencePresentCount: ec.evidencePresentCount, totalChecked: ec.totalChecked }, null);
247
- }
248
- if (ec.evidenceMissingCount > 0) {
249
- return warn("evidence_closure_complete", "Evidence closure complete",
250
- ec.nextAction || "Follow recoverCommand for each missing artifact.",
251
- { presentCount: ec.evidencePresentCount, missingCount: ec.evidenceMissingCount },
252
- ec.evidenceMissingCount + " artifact(s) still missing.");
253
- }
254
- return pass("evidence_closure_complete", "Evidence closure complete",
255
- { status: ec.status }, null);
256
- }
257
-
258
- function checkExternalUserSimulationCovered(cwd) {
259
- const sim = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-external-user-simulation.json"));
260
- if (!sim) {
261
- return warn("external_user_simulation_covered", "External user simulation covered",
262
- "Run: node bin/avorelo external-user-sim --json",
263
- null, "External user simulation not run.");
264
- }
265
- if (sim.blocked > 0) {
266
- return blocked("external_user_simulation_covered", "External user simulation covered",
267
- "Fix blocked scenarios. Run: node bin/avorelo external-user-sim --json",
268
- { blockedCount: sim.blocked },
269
- sim.blocked + " scenario(s) blocked in external user simulation.");
270
- }
271
- return pass("external_user_simulation_covered", "External user simulation covered",
272
- { passed: sim.passed, warned: sim.warned, total: sim.totalScenarios }, null);
273
- }
274
-
275
- function checkTokenCostHonest(cwd) {
276
- const tc = safeReadJson(path.join(cwd, ".claude/cco/orchestration/prelaunch-intelligence/latest-token-cost-intelligence.json"));
277
- if (!tc) {
278
- return warn("token_cost_honest", "Token cost evidence honest",
279
- "Run: node bin/avorelo token-cost --json. Status not_available is acceptable.",
280
- null, "Token cost intelligence artifact not found.");
281
- }
282
- if (tc.noExactSavingsClaim !== true) {
283
- return blocked("token_cost_honest", "Token cost evidence honest",
284
- "Ensure noExactSavingsClaim=true in token cost intelligence.",
285
- null, "noExactSavingsClaim is not true — exact savings claim may be made.");
286
- }
287
- return pass("token_cost_honest", "Token cost evidence honest",
288
- { status: tc.status, evidenceLevel: tc.evidenceLevel, noExactSavingsClaim: tc.noExactSavingsClaim }, null);
289
- }
290
-
291
- function checkFeedbackIntelligenceHonest(cwd) {
292
- const fi = safeReadJson(path.join(cwd, ".claude/cco/orchestration/prelaunch-intelligence/latest-feedback-intelligence.json"));
293
- if (!fi) {
294
- return warn("feedback_intelligence_honest", "Feedback intelligence honest",
295
- "Run: node bin/avorelo feedback insights --json. Insufficient is acceptable; missing is not.",
296
- null, "Feedback intelligence artifact not found.");
297
- }
298
- // As long as the artifact exists and represents the truth, it passes — even if insufficient
299
- return pass("feedback_intelligence_honest", "Feedback intelligence honest",
300
- { status: fi.status, sessionsAnalyzed: fi.sessionsAnalyzed, redacted: fi.redacted }, null);
301
- }
302
-
303
- function checkNoPublicLaunchClaim(cwd) {
304
- const gate = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-gate.json"));
305
- const rcb = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-release-candidate-bundle.json"));
306
- var violations = [];
307
- if (gate && gate.noPublicLaunchClaim !== true) violations.push("full-readiness gate");
308
- if (rcb && rcb.noPublicLaunchClaim !== true) violations.push("release-candidate-bundle");
309
- if (violations.length > 0) {
310
- return blocked("no_public_launch_claim", "No public launch claim on outputs",
311
- "Set noPublicLaunchClaim: true on all output artifacts.",
312
- null, "Violations: " + violations.join(", "));
313
- }
314
- return pass("no_public_launch_claim", "No public launch claim on outputs",
315
- { verified: ["full-readiness gate", "release-candidate-bundle"] }, null);
316
- }
317
-
318
- function checkSafeNextActionExists(cwd) {
319
- const gate = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-gate.json"));
320
- if (!gate) {
321
- return warn("safe_next_action_exists", "Safe next action for every blocker/warning",
322
- "Run: node bin/avorelo full-readiness --json to generate gate.",
323
- null, "Gate artifact not found.");
324
- }
325
- const blockers = gate.blockers || [];
326
- const missingSnA = blockers.filter(function(b) { return !b.safeNextAction || b.safeNextAction.length < 5; });
327
- if (missingSnA.length > 0) {
328
- return blocked("safe_next_action_exists", "Safe next action for every blocker/warning",
329
- "Add safeNextAction to all blockers in full-readiness-gate.js.",
330
- { missingIds: missingSnA.map(function(b) { return b.id; }) },
331
- "Blockers without safeNextAction: " + missingSnA.map(function(b) { return b.id; }).join(", "));
332
- }
333
- if (!gate.safeNextAction) {
334
- return warn("safe_next_action_exists", "Safe next action for every blocker/warning",
335
- "Add top-level safeNextAction to full-readiness gate.",
336
- null, "Gate has no top-level safeNextAction.");
337
- }
338
- return pass("safe_next_action_exists", "Safe next action for every blocker/warning",
339
- { blockerCount: blockers.length, allHaveSafeNextAction: true }, null);
340
- }
341
-
342
- function collectActivationDistributionSignals(cwd) {
343
- function read(rel) { return safeReadJson(path.join(cwd, rel)); }
344
- return {
345
- gate: read(".claude/cco/orchestration/full-readiness/latest-gate.json"),
346
- evidenceClosure: read(".claude/cco/orchestration/full-readiness/latest-evidence-closure.json"),
347
- knownLimitations: read(".claude/cco/orchestration/full-readiness/latest-known-limitations.json"),
348
- externalUserSim: read(".claude/cco/orchestration/full-readiness/latest-external-user-simulation.json"),
349
- releaseCandidateBundle: read(".claude/cco/orchestration/full-readiness/latest-release-candidate-bundle.json"),
350
- supportBundle: read(".claude/cco/support/latest-support-bundle.json"),
351
- tokenCost: read(".claude/cco/orchestration/prelaunch-intelligence/latest-token-cost-intelligence.json"),
352
- feedbackIntelligence: read(".claude/cco/orchestration/prelaunch-intelligence/latest-feedback-intelligence.json"),
353
- prelaunchReadiness: read(".claude/cco/orchestration/prelaunch-readiness/latest-activation-readiness.json"),
354
- valueSummary: read(".claude/cco/orchestration/seamless-outcome/latest-value-summary.json"),
355
- hardening: read(".claude/cco/orchestration/launch-hardening/latest-gate.json"),
356
- };
357
- }
358
-
359
- function scoreActivationDistributionReadiness(checks) {
360
- var totalEarned = 0;
361
- checks.forEach(function(c) {
362
- var weight = CHECK_WEIGHTS[c.id] || 0;
363
- if (c.status === "pass" || c.status === "info") totalEarned += weight;
364
- else if (c.status === "warn") totalEarned += Math.floor(weight * 0.5);
365
- });
366
- return Math.round((totalEarned / TOTAL_WEIGHT) * 100);
367
- }
368
-
369
- function runActivationDistributionReadiness(cwd, options) {
370
- options = options || {};
371
- var checks = [
372
- checkInstallCommandAvailable(cwd),
373
- checkInstallDocsCurrent(cwd),
374
- checkActivationEntrypointAvailable(cwd),
375
- checkDoctorAvailable(cwd),
376
- checkFirstValueSurfaceAvailable(cwd),
377
- checkClearNextActionAvailable(cwd),
378
- checkRecoveryPathAvailable(cwd),
379
- checkSupportBundleAvailable(cwd),
380
- checkKnownLimitationsVisible(cwd),
381
- checkReleaseCandidateBundleSafe(cwd),
382
- checkEvidenceClosureComplete(cwd),
383
- checkExternalUserSimulationCovered(cwd),
384
- checkTokenCostHonest(cwd),
385
- checkFeedbackIntelligenceHonest(cwd),
386
- checkNoPublicLaunchClaim(cwd),
387
- checkSafeNextActionExists(cwd),
388
- ];
389
-
390
- var blockers = checks.filter(function(c) { return c.status === "blocked"; });
391
- var warnings = checks.filter(function(c) { return c.status === "warn"; });
392
- var passes = checks.filter(function(c) { return c.status === "pass"; });
393
- var score = scoreActivationDistributionReadiness(checks);
394
-
395
- var status;
396
- if (blockers.length > 0) status = "blocked";
397
- else if (score >= SCORE_READY) status = "ready";
398
- else if (score >= SCORE_WARN) status = "warn";
399
- else status = "insufficient_data";
400
-
401
- var safeNextActions = [];
402
- blockers.forEach(function(b) { if (b.safeNextAction) safeNextActions.push(b.safeNextAction); });
403
- warnings.slice(0, 3).forEach(function(w) { if (w.safeNextAction) safeNextActions.push(w.safeNextAction); });
404
- if (safeNextActions.length === 0) safeNextActions.push("Run: node bin/avorelo readiness-closure --json to identify missing evidence.");
405
-
406
- var releaseCandidateStatus = (status === "ready") ? "candidate_ready" : (status === "warn") ? "candidate_warn" : "candidate_blocked";
407
-
408
- var result = {
409
- contract: CONTRACT,
410
- schemaVersion: SCHEMA_VERSION,
411
- createdAt: nowIso(),
412
- status: status,
413
- releaseCandidateStatus: releaseCandidateStatus,
414
- score: score,
415
- checks: checks,
416
- blockers: blockers,
417
- warnings: warnings,
418
- passes: passes,
419
- safeNextActions: safeNextActions,
420
- noPublicLaunchClaim: true,
421
- noReleaseReadyClaimUnlessPassed: true,
422
- redacted: true,
423
- };
424
-
425
- try { appendProductLearningEvent(cwd, { eventName: "activation_distribution_readiness_run", category: "activation_distribution", status: status, score: score, blockerCount: blockers.length, warnCount: warnings.length }); } catch (e) {}
426
- return result;
427
- }
428
-
429
- function writeActivationDistributionReadiness(cwd, result) {
430
- var dir = path.join(cwd, ARTIFACT_DIR_REL);
431
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
432
- fs.writeFileSync(path.join(cwd, ARTIFACT_REL), JSON.stringify(result, null, 2));
433
- return result;
434
- }
435
-
436
- function buildActivationDistributionSurface(cwd, options) {
437
- options = options || {};
438
- var artifact = safeReadJson(path.join(cwd, ARTIFACT_REL));
439
- if (!artifact) return { status: "not_available", contract: CONTRACT };
440
- return {
441
- contract: artifact.contract,
442
- status: artifact.status,
443
- releaseCandidateStatus: artifact.releaseCandidateStatus,
444
- score: artifact.score,
445
- blockerCount: (artifact.blockers || []).length,
446
- warningCount: (artifact.warnings || []).length,
447
- safeNextActions: (artifact.safeNextActions || []).slice(0, 3),
448
- noPublicLaunchClaim: artifact.noPublicLaunchClaim,
449
- redacted: artifact.redacted,
450
- };
451
- }
452
-
453
- function formatActivationDistributionText(result, options) {
454
- options = options || {};
455
- var lines = [];
456
- lines.push("Activation distribution readiness: " + result.status + " (score: " + result.score + "/100)");
457
- if (result.blockers && result.blockers.length > 0) {
458
- lines.push("Blockers: " + result.blockers.length);
459
- result.blockers.forEach(function(b) { lines.push(" [blocked] " + b.label + " — " + (b.safeNextAction || "")); });
460
- }
461
- if (result.warnings && result.warnings.length > 0) {
462
- lines.push("Warnings: " + result.warnings.length);
463
- if (options.debug) result.warnings.forEach(function(w) { lines.push(" [warn] " + w.label + " — " + (w.safeNextAction || "")); });
464
- }
465
- if (result.safeNextActions && result.safeNextActions.length > 0) {
466
- lines.push("Next: " + result.safeNextActions[0]);
467
- }
468
- lines.push("No public launch claim. Redacted.");
469
- if (options.debug) {
470
- lines.push("");
471
- lines.push("Checks:");
472
- (result.checks || []).forEach(function(c) { lines.push(" [" + c.status + "] " + c.id + (c.detail ? " — " + c.detail : "")); });
473
- }
474
- return lines.join("\n");
475
- }
476
-
477
- module.exports = {
478
- CONTRACT,
479
- SCHEMA_VERSION,
480
- ARTIFACT_REL,
481
- SCORE_READY,
482
- SCORE_WARN,
483
- CHECK_WEIGHTS,
484
- collectActivationDistributionSignals,
485
- scoreActivationDistributionReadiness,
486
- runActivationDistributionReadiness,
487
- writeActivationDistributionReadiness,
488
- buildActivationDistributionSurface,
489
- formatActivationDistributionText,
490
- // Individual checks exported for testing
491
- checkInstallCommandAvailable,
492
- checkInstallDocsCurrent,
493
- checkActivationEntrypointAvailable,
494
- checkDoctorAvailable,
495
- checkFirstValueSurfaceAvailable,
496
- checkClearNextActionAvailable,
497
- checkRecoveryPathAvailable,
498
- checkSupportBundleAvailable,
499
- checkKnownLimitationsVisible,
500
- checkReleaseCandidateBundleSafe,
501
- checkEvidenceClosureComplete,
502
- checkExternalUserSimulationCovered,
503
- checkTokenCostHonest,
504
- checkFeedbackIntelligenceHonest,
505
- checkNoPublicLaunchClaim,
506
- checkSafeNextActionExists,
507
- };
@@ -1,176 +0,0 @@
1
- "use strict";
2
-
3
- const { HOOK_EVENT_NAMES } = require("./hook-contracts");
4
-
5
- const CAPABILITY_MAP = {
6
- claude: {
7
- platform: "claude",
8
- supportsHooks: [...HOOK_EVENT_NAMES],
9
- supportsToolOutputReplacement: true,
10
- supportsPermissionDecision: true,
11
- supportsPanelLaunch: true,
12
- supportsRules: false,
13
- supportsMCPConfig: true,
14
- supportsExtensionBridge: false,
15
- supportsPermissionControl: true,
16
- partialSupportNotes: [],
17
- },
18
- cursor: {
19
- platform: "cursor",
20
- supportsHooks: ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop", "SessionEnd"],
21
- supportsToolOutputReplacement: false,
22
- supportsPermissionDecision: false,
23
- supportsPanelLaunch: true,
24
- supportsRules: true,
25
- supportsMCPConfig: true,
26
- supportsExtensionBridge: true,
27
- supportsPermissionControl: false,
28
- partialSupportNotes: [
29
- "Cursor does not provide Claude-equivalent hook lifecycle for all 18 events.",
30
- "Permission decisions are advisory via rules/extension workflow.",
31
- "Tool output replacement is not directly supported; recommendations are post-action.",
32
- ],
33
- },
34
- windsurf: {
35
- platform: "windsurf",
36
- supportsHooks: [
37
- "SessionStart",
38
- "UserPromptSubmit",
39
- "PreToolUse",
40
- "PostToolUse",
41
- "PostToolUseFailure",
42
- "Notification",
43
- "Stop",
44
- "TaskCompleted",
45
- "SubagentStart",
46
- "SubagentStop",
47
- "ConfigChange",
48
- "SessionEnd",
49
- ],
50
- supportsToolOutputReplacement: false,
51
- supportsPermissionDecision: true,
52
- supportsPanelLaunch: true,
53
- supportsRules: false,
54
- supportsMCPConfig: true,
55
- supportsExtensionBridge: false,
56
- supportsPermissionControl: true,
57
- partialSupportNotes: [
58
- "Tool output replacement is host-limited; optimizer uses post-action recommendations instead.",
59
- "Hook names differ by host; mapped through adapter contract.",
60
- ],
61
- },
62
- "copilot-coding-agent": {
63
- platform: "copilot-coding-agent",
64
- supportsHooks: ["SessionStart", "PreToolUse", "PostToolUse", "Stop", "TaskCompleted", "SessionEnd"],
65
- supportsToolOutputReplacement: false,
66
- supportsPermissionDecision: false,
67
- supportsPanelLaunch: true,
68
- supportsRules: true,
69
- supportsMCPConfig: false,
70
- supportsExtensionBridge: false,
71
- supportsPermissionControl: false,
72
- partialSupportNotes: [
73
- "No first-class permission decision hook parity; guardrails run in advisory mode.",
74
- "Notification and teammate events are synthesized from available telemetry.",
75
- ],
76
- },
77
- continue: {
78
- platform: "continue",
79
- supportsHooks: ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop", "SessionEnd"],
80
- supportsToolOutputReplacement: false,
81
- supportsPermissionDecision: false,
82
- supportsPanelLaunch: true,
83
- supportsRules: true,
84
- supportsMCPConfig: true,
85
- supportsExtensionBridge: false,
86
- supportsPermissionControl: false,
87
- partialSupportNotes: [
88
- "Permission decisions are advisory due to host capabilities.",
89
- "Subagent and worktree lifecycle events are approximated when unavailable.",
90
- ],
91
- },
92
- codex: {
93
- platform: "codex",
94
- supportsHooks: ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop", "SessionEnd"],
95
- supportsToolOutputReplacement: false,
96
- supportsPermissionDecision: true,
97
- supportsPanelLaunch: true,
98
- supportsRules: false,
99
- supportsMCPConfig: true,
100
- supportsExtensionBridge: false,
101
- supportsPermissionControl: true,
102
- partialSupportNotes: ["Hook/event mapping relies on adapter routing and may not expose all Claude-native lifecycle events."],
103
- },
104
- };
105
-
106
- function normalizePlatform(platform) {
107
- const p = String(platform || "claude").toLowerCase();
108
- if (p === "copilot" || p === "github-copilot" || p === "github-copilot-coding-agent") return "copilot-coding-agent";
109
- return CAPABILITY_MAP[p] ? p : "claude";
110
- }
111
-
112
- function getAdapterCapabilityMap(platform) {
113
- const key = normalizePlatform(platform);
114
- return CAPABILITY_MAP[key];
115
- }
116
-
117
- function normalizeDashboardForPlatform(platform, dashboard) {
118
- const capabilityMap = getAdapterCapabilityMap(platform);
119
- const unsupportedHooks = HOOK_EVENT_NAMES.filter((evt) => !capabilityMap.supportsHooks.includes(evt));
120
-
121
- return {
122
- platform: capabilityMap.platform,
123
- capabilityMap,
124
- partialSupport: unsupportedHooks.length > 0,
125
- partialSupportNotes: [...capabilityMap.partialSupportNotes],
126
- unsupportedHooks,
127
- statusDashboardVersion: dashboard.statusDashboardVersion,
128
- tier: dashboard.tier,
129
- dashboardFraming: dashboard.dashboardFraming,
130
- benefitSummary: dashboard.benefitSummary,
131
- memorySummary: dashboard.memorySummary,
132
- contextBudgetPlan: dashboard.contextBudgetPlan,
133
- recommendationTraces: dashboard.recommendationTraces || [],
134
- recommendationDecision: dashboard.recommendationDecision || null,
135
- nextBestAction: dashboard.nextBestAction,
136
- nextBestPrompt: dashboard.nextBestPrompt,
137
- simplifyModeStatus: dashboard.simplifyModeStatus,
138
- teamUnifiedView: dashboard.teamUnifiedView,
139
- pricingMeter: dashboard.pricingMeter,
140
- cloudSync: dashboard.cloudSync,
141
- };
142
- }
143
-
144
- function hasNormalizedDashboardShape(payload) {
145
- return Boolean(
146
- payload &&
147
- typeof payload === "object" &&
148
- typeof payload.platform === "string" &&
149
- payload.capabilityMap &&
150
- Array.isArray(payload.capabilityMap.supportsHooks) &&
151
- typeof payload.capabilityMap.supportsToolOutputReplacement === "boolean" &&
152
- typeof payload.capabilityMap.supportsPermissionDecision === "boolean" &&
153
- typeof payload.capabilityMap.supportsPanelLaunch === "boolean" &&
154
- typeof payload.capabilityMap.supportsRules === "boolean" &&
155
- typeof payload.capabilityMap.supportsMCPConfig === "boolean" &&
156
- typeof payload.capabilityMap.supportsExtensionBridge === "boolean" &&
157
- Array.isArray(payload.partialSupportNotes) &&
158
- payload.benefitSummary &&
159
- payload.memorySummary &&
160
- payload.contextBudgetPlan &&
161
- typeof payload.nextBestAction === "string" &&
162
- typeof payload.nextBestPrompt === "string" &&
163
- payload.simplifyModeStatus &&
164
- payload.pricingMeter &&
165
- payload.teamUnifiedView &&
166
- payload.cloudSync
167
- );
168
- }
169
-
170
- module.exports = {
171
- CAPABILITY_MAP,
172
- normalizePlatform,
173
- getAdapterCapabilityMap,
174
- normalizeDashboardForPlatform,
175
- hasNormalizedDashboardShape,
176
- };