codehere 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +36 -192
  2. package/dist/application/use-cases/check-claimed-tests.js +81 -0
  3. package/dist/application/use-cases/detect-test-weakening.js +237 -0
  4. package/dist/application/use-cases/rerun-tests.js +110 -7
  5. package/dist/index.js +38 -1212
  6. package/dist/infrastructure/orchestration/artifacts-extractor.js +2 -323
  7. package/dist/presentation/cli/commands/check-command.js +178 -23
  8. package/dist/presentation/cli/commands/help-command.js +21 -285
  9. package/dist/ui.js +5 -236
  10. package/dist/utils/version.js +0 -6
  11. package/package.json +9 -38
  12. package/dist/application/services/verdict-service.js +0 -154
  13. package/dist/application/use-cases/assess-cross-vendor.js +0 -126
  14. package/dist/application/use-cases/build-cross-vendor-verdict.js +0 -118
  15. package/dist/application/use-cases/domain-trust.js +0 -110
  16. package/dist/application/use-cases/export-aat.js +0 -107
  17. package/dist/application/use-cases/generate-acceptance-criteria.js +0 -223
  18. package/dist/application/use-cases/generate-final-report.js +0 -259
  19. package/dist/application/use-cases/generate-narration.js +0 -130
  20. package/dist/application/use-cases/generate-thread-title.js +0 -181
  21. package/dist/application/use-cases/narrator-prompt-template.js +0 -158
  22. package/dist/application/use-cases/plan-auto-review.js +0 -57
  23. package/dist/application/use-cases/reconcile-audit.js +0 -100
  24. package/dist/application/use-cases/search-sessions.js +0 -70
  25. package/dist/application/use-cases/should-auto-review.js +0 -71
  26. package/dist/application/use-cases/thread-export.js +0 -245
  27. package/dist/application/use-cases/verify-claim.js +0 -456
  28. package/dist/application/use-cases/write-pass.js +0 -277
  29. package/dist/domain/audit.js +0 -11
  30. package/dist/domain/services/codebase-detector.js +0 -85
  31. package/dist/domain/task.js +0 -91
  32. package/dist/error-handler.js +0 -139
  33. package/dist/infrastructure/completion/bash-completion.js +0 -29
  34. package/dist/infrastructure/completion/fish-completion.js +0 -17
  35. package/dist/infrastructure/completion/zsh-completion.js +0 -25
  36. package/dist/infrastructure/config/config-manager.js +0 -174
  37. package/dist/infrastructure/config/product-context.js +0 -49
  38. package/dist/infrastructure/context/adapters/drawio-source.js +0 -157
  39. package/dist/infrastructure/context/adapters/figma-source.js +0 -198
  40. package/dist/infrastructure/context/adapters/github-issue-source.js +0 -160
  41. package/dist/infrastructure/context/adapters/linear-source.js +0 -190
  42. package/dist/infrastructure/context/context-resolver.js +0 -144
  43. package/dist/infrastructure/context/context-source.js +0 -114
  44. package/dist/infrastructure/context/github-api.js +0 -110
  45. package/dist/infrastructure/context/github-device-flow.js +0 -65
  46. package/dist/infrastructure/context/oauth-flow.js +0 -207
  47. package/dist/infrastructure/context/oauth-store.js +0 -122
  48. package/dist/infrastructure/context/registry-bootstrap.js +0 -95
  49. package/dist/infrastructure/context/write-pass-resolver.js +0 -106
  50. package/dist/infrastructure/cost/budget-config.js +0 -114
  51. package/dist/infrastructure/cost/cost-router.js +0 -97
  52. package/dist/infrastructure/cost/spend-aggregator.js +0 -222
  53. package/dist/infrastructure/cost/team-ledger.js +0 -355
  54. package/dist/infrastructure/discovery/discovery-log.js +0 -85
  55. package/dist/infrastructure/hooks/audit-tip-signature.js +0 -336
  56. package/dist/infrastructure/hooks/claude-sdk-hook.js +0 -1018
  57. package/dist/infrastructure/hooks/hook-mode.js +0 -87
  58. package/dist/infrastructure/hooks/mirror-tool-call-to-audit.js +0 -49
  59. package/dist/infrastructure/hooks/pre-prompt-scan.js +0 -122
  60. package/dist/infrastructure/hooks/session-analyzer.js +0 -177
  61. package/dist/infrastructure/observability/execution-tracer.js +0 -227
  62. package/dist/infrastructure/orchestration/agent-adapter.js +0 -13
  63. package/dist/infrastructure/orchestration/agent-installer.js +0 -101
  64. package/dist/infrastructure/orchestration/agents-config-seed.js +0 -68
  65. package/dist/infrastructure/orchestration/aider-adapter.js +0 -611
  66. package/dist/infrastructure/orchestration/cassette-recorder.js +0 -120
  67. package/dist/infrastructure/orchestration/claude-code-adapter.js +0 -592
  68. package/dist/infrastructure/orchestration/codex-adapter.js +0 -574
  69. package/dist/infrastructure/orchestration/conductor-adapter.js +0 -416
  70. package/dist/infrastructure/orchestration/context-handoff.js +0 -162
  71. package/dist/infrastructure/orchestration/control/codex-control-surface.js +0 -99
  72. package/dist/infrastructure/orchestration/control/control-surface.js +0 -15
  73. package/dist/infrastructure/orchestration/detect-ollama.js +0 -75
  74. package/dist/infrastructure/orchestration/failover-classifier.js +0 -151
  75. package/dist/infrastructure/orchestration/failover-config.js +0 -67
  76. package/dist/infrastructure/orchestration/failover-policy.js +0 -106
  77. package/dist/infrastructure/orchestration/gemini-adapter.js +0 -663
  78. package/dist/infrastructure/orchestration/generic-cli-adapter.js +0 -689
  79. package/dist/infrastructure/orchestration/graphify-context.js +0 -209
  80. package/dist/infrastructure/orchestration/memory-injector.js +0 -380
  81. package/dist/infrastructure/orchestration/mocks/mock-agent-repl.js +0 -388
  82. package/dist/infrastructure/orchestration/mocks/mock-codex-app-server.js +0 -73
  83. package/dist/infrastructure/orchestration/mocks/mock-synthesis.js +0 -83
  84. package/dist/infrastructure/orchestration/mocks/resolve-agent-spawn.js +0 -37
  85. package/dist/infrastructure/orchestration/opencode-adapter.js +0 -580
  86. package/dist/infrastructure/orchestration/progress-aggregator.js +0 -906
  87. package/dist/infrastructure/orchestration/readiness.js +0 -103
  88. package/dist/infrastructure/orchestration/session-manager.js +0 -1590
  89. package/dist/infrastructure/orchestration/session-persistence.js +0 -394
  90. package/dist/infrastructure/orchestration/thread-key-store.js +0 -127
  91. package/dist/infrastructure/orchestration/write-pass-store.js +0 -38
  92. package/dist/infrastructure/protocols/cloud-sync.js +0 -207
  93. package/dist/infrastructure/protocols/mcp-helpers.js +0 -25
  94. package/dist/infrastructure/protocols/mcp-server-impl.js +0 -3935
  95. package/dist/infrastructure/protocols/mcp-tools.js +0 -401
  96. package/dist/infrastructure/protocols/probe-port.js +0 -36
  97. package/dist/infrastructure/protocols/thread-phase.js +0 -105
  98. package/dist/infrastructure/protocols/ui/app-script-artifacts.js +0 -121
  99. package/dist/infrastructure/protocols/ui/app-script-audit-footer.js +0 -44
  100. package/dist/infrastructure/protocols/ui/app-script-audit-verify.js +0 -56
  101. package/dist/infrastructure/protocols/ui/app-script-composer-cost.js +0 -588
  102. package/dist/infrastructure/protocols/ui/app-script-context-sources.js +0 -168
  103. package/dist/infrastructure/protocols/ui/app-script-conversation.js +0 -67
  104. package/dist/infrastructure/protocols/ui/app-script-drawer.js +0 -115
  105. package/dist/infrastructure/protocols/ui/app-script-failover.js +0 -133
  106. package/dist/infrastructure/protocols/ui/app-script-github.js +0 -113
  107. package/dist/infrastructure/protocols/ui/app-script-observer.js +0 -104
  108. package/dist/infrastructure/protocols/ui/app-script-onboarding.js +0 -80
  109. package/dist/infrastructure/protocols/ui/app-script-overlay.js +0 -203
  110. package/dist/infrastructure/protocols/ui/app-script-recovery.js +0 -136
  111. package/dist/infrastructure/protocols/ui/app-script-render.js +0 -166
  112. package/dist/infrastructure/protocols/ui/app-script-share.js +0 -78
  113. package/dist/infrastructure/protocols/ui/app-script-sidebar.js +0 -194
  114. package/dist/infrastructure/protocols/ui/app-script-tour.js +0 -78
  115. package/dist/infrastructure/protocols/ui/app-script-wpass.js +0 -312
  116. package/dist/infrastructure/protocols/ui/app-script.js +0 -2998
  117. package/dist/infrastructure/protocols/ui/font-faces.js +0 -7
  118. package/dist/infrastructure/protocols/ui/styles.js +0 -2147
  119. package/dist/infrastructure/protocols/ui/tokens.js +0 -96
  120. package/dist/infrastructure/protocols/ui-page-v2.js +0 -320
  121. package/dist/infrastructure/protocols/verify-page.js +0 -1677
  122. package/dist/infrastructure/security/file-collection.js +0 -118
  123. package/dist/infrastructure/security/fix-code.js +0 -144
  124. package/dist/infrastructure/security/fix-secret.js +0 -89
  125. package/dist/infrastructure/security/permissions-config.js +0 -235
  126. package/dist/infrastructure/security/scan-types.js +0 -10
  127. package/dist/infrastructure/security/ship-scan.js +0 -195
  128. package/dist/infrastructure/security/trust-scorer.js +0 -724
  129. package/dist/infrastructure/security/vibe-checks.js +0 -99
  130. package/dist/infrastructure/storage/atomic-write.js +0 -86
  131. package/dist/infrastructure/storage/cross-tool-agents.js +0 -268
  132. package/dist/infrastructure/storage/project-thread-migration.js +0 -237
  133. package/dist/infrastructure/storage/project-thread-mirror.js +0 -671
  134. package/dist/infrastructure/storage/project-thread-reader.js +0 -409
  135. package/dist/infrastructure/storage/project-thread-title-backfill.js +0 -214
  136. package/dist/monitoring.js +0 -212
  137. package/dist/presentation/cli/commands/audit-command.js +0 -201
  138. package/dist/presentation/cli/commands/budget-command.js +0 -79
  139. package/dist/presentation/cli/commands/config-command.js +0 -125
  140. package/dist/presentation/cli/commands/context-source-command.js +0 -217
  141. package/dist/presentation/cli/commands/hook-command.js +0 -265
  142. package/dist/presentation/cli/commands/init-command.js +0 -590
  143. package/dist/presentation/cli/commands/memory-command.js +0 -1031
  144. package/dist/presentation/cli/commands/narrator-command.js +0 -101
  145. package/dist/presentation/cli/commands/permission-command.js +0 -105
  146. package/dist/presentation/cli/commands/protocols-builder.js +0 -254
  147. package/dist/presentation/cli/commands/protocols-command.js +0 -84
  148. package/dist/presentation/cli/commands/repo-map-builder.js +0 -247
  149. package/dist/presentation/cli/commands/report-command.js +0 -403
  150. package/dist/presentation/cli/commands/scan-command.js +0 -52
  151. package/dist/presentation/cli/commands/scan-tool-command.js +0 -110
  152. package/dist/presentation/cli/commands/search-command.js +0 -51
  153. package/dist/presentation/cli/commands/setup-command.js +0 -330
  154. package/dist/presentation/cli/commands/status-command.js +0 -614
  155. package/dist/presentation/cli/commands/team-command.js +0 -256
  156. package/dist/presentation/cli/commands/thread-command.js +0 -370
  157. package/dist/presentation/cli/commands/trust-command.js +0 -328
  158. package/dist/presentation/cli/commands/verify-command.js +0 -298
  159. package/dist/presentation/cli/error-display.js +0 -328
  160. package/dist/presentation/cli/repl.js +0 -805
  161. package/dist/presentation/cli/task-deliverable.js +0 -153
  162. package/dist/testing/cassette.js +0 -125
  163. package/dist/testing/replay-adapter.js +0 -147
@@ -1,277 +0,0 @@
1
- /**
2
- * Write-Pass (W-PASS) primitive · v0.9 S6 · the WRITE counterpart to S1's
3
- * context-source READ primitive.
4
- *
5
- * Demo v12 lines 2030-2050. Every time an agent wants to make a stateful
6
- * call to a third-party tool (Linear status update, GitHub PR comment,
7
- * Notion page edit, etc.) it emits a `WritePassIntent`. Codehere mediates:
8
- *
9
- * 1. Intent · agent → codehere · {target, method, payload, reason}
10
- * 2. Approval · user → codehere · approve / edit / cancel
11
- * 3. Mediated send · codehere → third-party · captures response
12
- * 4. Audit · chained entry for each step
13
- *
14
- * Why this primitive exists: AI 2027 forecasts agentic AI doing autonomous
15
- * multi-tool writes by mid-2027. Without W-PASS we either (a) hand the
16
- * agent raw API keys + tokens — every write is invisible to the human,
17
- * audit-impossible — or (b) ban writes entirely and lose half the value.
18
- * W-PASS is the middle path: writes happen, but every payload is human-
19
- * mediated and chain-recorded.
20
- *
21
- * This file is PURE LOGIC · no fs, no fetch. CLI + HTTP + UI wrap it.
22
- */
23
- import { randomUUID, createHash } from 'crypto';
24
- /** Errors raised by W-PASS primitive functions. */
25
- export class WritePassError extends Error {
26
- code;
27
- constructor(code, message) {
28
- super(`[w-pass] ${code}: ${message}`);
29
- this.code = code;
30
- }
31
- }
32
- /* ──────────────────────────────────────────────────────────────────────── */
33
- /* Pure helpers */
34
- /* ──────────────────────────────────────────────────────────────────────── */
35
- /** Generate a fresh W-PASS id · stable across the intent → decision → send cycle. */
36
- export function newPassId() {
37
- return randomUUID();
38
- }
39
- /** Allowed URL schemes for W-PASS targets · matches context-source's namespace
40
- * (we want symmetry: read via context-source, write via write-pass, same identifiers). */
41
- const ALLOWED_SCHEMES = new Set(['linear', 'github', 'figma', 'drawio', 'notion']);
42
- /**
43
- * Validate that an intent is well-formed before showing it to the user.
44
- * Refuse anything we can't audit (unknown scheme, unsupported method, empty
45
- * reason, etc.). Throws WritePassError with a precise code.
46
- */
47
- export function validateIntent(intent) {
48
- if (typeof intent !== 'object' || intent === null) {
49
- throw new WritePassError('invalid_intent', 'intent must be an object');
50
- }
51
- const it = intent;
52
- if (typeof it.id !== 'string' || it.id.length === 0) {
53
- throw new WritePassError('invalid_intent', 'id required');
54
- }
55
- if (typeof it.sessionId !== 'string' || it.sessionId.length === 0) {
56
- throw new WritePassError('invalid_intent', 'sessionId required');
57
- }
58
- if (typeof it.target !== 'string' || it.target.length === 0) {
59
- throw new WritePassError('invalid_intent', 'target required');
60
- }
61
- const schemeMatch = it.target.match(/^([a-z][a-z0-9+.-]*):\/\//);
62
- if (!schemeMatch) {
63
- throw new WritePassError('invalid_intent', `target must be a URL with a scheme · got "${it.target}"`);
64
- }
65
- if (!ALLOWED_SCHEMES.has(schemeMatch[1])) {
66
- throw new WritePassError('unsupported_target', `scheme "${schemeMatch[1]}" not allowed · supported: ${[...ALLOWED_SCHEMES].sort().join(', ')}`);
67
- }
68
- if (typeof it.method !== 'string') {
69
- throw new WritePassError('invalid_intent', 'method required');
70
- }
71
- const m = it.method.toUpperCase();
72
- if (m !== 'POST' && m !== 'PUT' && m !== 'PATCH' && m !== 'DELETE') {
73
- throw new WritePassError('unsupported_method', `method "${it.method}" not allowed for W-PASS (use context-source for GET)`);
74
- }
75
- if (typeof it.reason !== 'string' || it.reason.trim().length === 0) {
76
- throw new WritePassError('invalid_intent', 'reason required · must be a non-empty one-line "why"');
77
- }
78
- if (typeof it.emittedAt !== 'number' || !Number.isFinite(it.emittedAt)) {
79
- throw new WritePassError('invalid_intent', 'emittedAt required (epoch ms)');
80
- }
81
- // payload may be any JSON value · we don't constrain shape here · the user
82
- // sees it verbatim and decides.
83
- return {
84
- id: it.id,
85
- sessionId: it.sessionId,
86
- target: it.target,
87
- method: m,
88
- payload: it.payload,
89
- reason: it.reason,
90
- emittedAt: it.emittedAt,
91
- emittedBy: typeof it.emittedBy === 'string' ? it.emittedBy : undefined,
92
- };
93
- }
94
- /** Validate a decision belongs to its intent and carries the fields required for its kind. */
95
- export function validateDecision(decision, intent) {
96
- if (typeof decision !== 'object' || decision === null) {
97
- throw new WritePassError('invalid_decision', 'decision must be an object');
98
- }
99
- const d = decision;
100
- if (d.passId !== intent.id) {
101
- throw new WritePassError('invalid_decision', `decision.passId "${d.passId}" doesn't match intent.id "${intent.id}"`);
102
- }
103
- const kind = d.kind;
104
- if (kind !== 'approve' && kind !== 'edit' && kind !== 'cancel') {
105
- throw new WritePassError('invalid_decision', `kind must be approve | edit | cancel · got "${d.kind}"`);
106
- }
107
- if (kind === 'edit' && d.editedPayload === undefined) {
108
- throw new WritePassError('invalid_decision', 'edit requires editedPayload');
109
- }
110
- if (typeof d.decidedAt !== 'number' || !Number.isFinite(d.decidedAt)) {
111
- throw new WritePassError('invalid_decision', 'decidedAt required (epoch ms)');
112
- }
113
- return {
114
- passId: intent.id,
115
- kind,
116
- editedPayload: kind === 'edit' ? d.editedPayload : undefined,
117
- note: typeof d.note === 'string' ? d.note : undefined,
118
- decidedAt: d.decidedAt,
119
- };
120
- }
121
- /**
122
- * Apply a decision to an intent and produce the next status.
123
- * Pure · no I/O. The caller (daemon route) does the network call and produces
124
- * a `WritePassResponse` which then transitions 'approved'/'edited' → 'sent'.
125
- */
126
- export function applyDecision(intent, decision) {
127
- if (decision.kind === 'cancel') {
128
- return { kind: 'cancelled', intent, decision };
129
- }
130
- if (decision.kind === 'edit') {
131
- return { kind: 'edited', intent, decision, effectivePayload: decision.editedPayload };
132
- }
133
- return { kind: 'approved', intent, decision };
134
- }
135
- /**
136
- * After codehere does the mediated send, record the response and transition
137
- * to 'sent' (2xx/3xx) or 'failed' (everything else).
138
- */
139
- export function applyResponse(status, response) {
140
- const effectivePayload = status.kind === 'edited' ? status.effectivePayload : status.intent.payload;
141
- const ok = response.status >= 200 && response.status < 400;
142
- return ok
143
- ? { kind: 'sent', intent: status.intent, decision: status.decision, effectivePayload, response }
144
- : { kind: 'failed', intent: status.intent, decision: status.decision, effectivePayload, response };
145
- }
146
- /* ──────────────────────────────────────────────────────────────────────── */
147
- /* Audit-line shaping */
148
- /* ──────────────────────────────────────────────────────────────────────── */
149
- /**
150
- * Deterministic JSON for hashing into the audit chain. Same canonical-form
151
- * rules as thread-export's canonicalize · keys sorted, undefined dropped,
152
- * non-finite numbers refused. We want two machines that re-serialize the
153
- * same intent to compute the same hash.
154
- */
155
- export function canonicalizeForAudit(value) {
156
- if (value === null)
157
- return 'null';
158
- if (typeof value === 'number') {
159
- if (!Number.isFinite(value))
160
- throw new Error(`cannot canonicalize non-finite number: ${value}`);
161
- return JSON.stringify(value);
162
- }
163
- if (typeof value === 'string' || typeof value === 'boolean')
164
- return JSON.stringify(value);
165
- if (Array.isArray(value)) {
166
- return '[' + value.map(canonicalizeForAudit).join(',') + ']';
167
- }
168
- if (typeof value === 'object') {
169
- const obj = value;
170
- const keys = Object.keys(obj).sort();
171
- const parts = keys
172
- .filter((k) => obj[k] !== undefined)
173
- .map((k) => JSON.stringify(k) + ':' + canonicalizeForAudit(obj[k]));
174
- return '{' + parts.join(',') + '}';
175
- }
176
- if (value === undefined)
177
- return 'null';
178
- throw new Error(`cannot canonicalize type: ${typeof value}`);
179
- }
180
- /** SHA-256 hash of canonicalize(value) · 16-char hex prefix for inline display. */
181
- export function shortContentHash(value) {
182
- return createHash('sha256').update(canonicalizeForAudit(value)).digest('hex').slice(0, 16);
183
- }
184
- /** Render a status transition as an audit-chain entry. Caller appends it. */
185
- export function statusToAuditLine(s) {
186
- const sessionId = s.intent.sessionId;
187
- const timestamp = new Date('response' in s ? s.response.receivedAt : 'decision' in s ? s.decision.decidedAt : s.intent.emittedAt).toISOString();
188
- const baseSummary = {
189
- passId: s.intent.id,
190
- target: s.intent.target,
191
- method: s.intent.method,
192
- reason: s.intent.reason,
193
- payloadHash: shortContentHash(s.intent.payload),
194
- };
195
- switch (s.kind) {
196
- case 'pending':
197
- return {
198
- toolName: 'WritePass.intent',
199
- toolInput: canonicalizeForAudit(baseSummary),
200
- riskScore: 0,
201
- blocked: false,
202
- findings: 0,
203
- criticalFindings: 0,
204
- sessionId,
205
- timestamp,
206
- };
207
- case 'approved':
208
- return {
209
- toolName: 'WritePass.approved',
210
- toolInput: canonicalizeForAudit({ ...baseSummary, note: s.decision.note }),
211
- riskScore: 0,
212
- blocked: false,
213
- findings: 0,
214
- criticalFindings: 0,
215
- sessionId,
216
- timestamp,
217
- };
218
- case 'edited':
219
- return {
220
- toolName: 'WritePass.edited',
221
- toolInput: canonicalizeForAudit({
222
- ...baseSummary,
223
- editedPayloadHash: shortContentHash(s.effectivePayload),
224
- note: s.decision.note,
225
- }),
226
- riskScore: 0,
227
- blocked: false,
228
- findings: 0,
229
- criticalFindings: 0,
230
- sessionId,
231
- timestamp,
232
- };
233
- case 'cancelled':
234
- return {
235
- toolName: 'WritePass.cancelled',
236
- toolInput: canonicalizeForAudit({ ...baseSummary, note: s.decision.note }),
237
- riskScore: 0,
238
- blocked: true,
239
- findings: 0,
240
- criticalFindings: 0,
241
- sessionId,
242
- timestamp,
243
- };
244
- case 'sent':
245
- return {
246
- toolName: 'WritePass.sent',
247
- toolInput: canonicalizeForAudit({
248
- ...baseSummary,
249
- effectivePayloadHash: shortContentHash(s.effectivePayload),
250
- responseStatus: s.response.status,
251
- }),
252
- riskScore: 0,
253
- blocked: false,
254
- findings: 0,
255
- criticalFindings: 0,
256
- sessionId,
257
- timestamp,
258
- };
259
- case 'failed':
260
- return {
261
- toolName: 'WritePass.failed',
262
- toolInput: canonicalizeForAudit({
263
- ...baseSummary,
264
- effectivePayloadHash: shortContentHash(s.effectivePayload),
265
- responseStatus: s.response.status,
266
- error: s.response.error,
267
- }),
268
- riskScore: 0,
269
- blocked: false,
270
- findings: 1,
271
- criticalFindings: 0,
272
- sessionId,
273
- timestamp,
274
- };
275
- }
276
- }
277
- //# sourceMappingURL=write-pass.js.map
@@ -1,11 +0,0 @@
1
- /**
2
- * Domain types for the tamper-evident-aspiring audit chain.
3
- *
4
- * These are pure data shapes — no I/O, no clock, no dependencies. They live in
5
- * `domain/` (not `infrastructure/hooks/`) so the dependency rule points inward:
6
- * the hook, the daemon, and the use-cases all import these DOWN from domain,
7
- * rather than reaching up into a hook file for the core vocabulary.
8
- * Moved here 2026-06-09 (spec R14 / ARCHITECTURE.md M1).
9
- */
10
- export {};
11
- //# sourceMappingURL=audit.js.map
@@ -1,85 +0,0 @@
1
- /**
2
- * Domain Service: CodebaseDetector
3
- * Detects and identifies codebase root directory
4
- */
5
- import { existsSync } from 'fs';
6
- import { join, dirname, resolve } from 'path';
7
- /**
8
- * Find codebase root (git root, package.json parent, or current directory)
9
- */
10
- export function findCodebaseRoot(startPath = process.cwd()) {
11
- const resolvedStart = resolve(startPath);
12
- const currentDir = resolvedStart;
13
- // Try to find git root first
14
- const gitRoot = findGitRoot(currentDir);
15
- if (gitRoot) {
16
- return {
17
- rootPath: gitRoot,
18
- codebaseId: generateCodebaseId(gitRoot),
19
- type: 'git',
20
- };
21
- }
22
- // Try to find package.json
23
- const packageRoot = findPackageRoot(currentDir);
24
- if (packageRoot) {
25
- return {
26
- rootPath: packageRoot,
27
- codebaseId: generateCodebaseId(packageRoot),
28
- type: 'package',
29
- };
30
- }
31
- // Fallback to current directory
32
- return {
33
- rootPath: currentDir,
34
- codebaseId: generateCodebaseId(currentDir),
35
- type: 'directory',
36
- };
37
- }
38
- /**
39
- * Generate stable codebase ID from path
40
- * Uses absolute path normalized for cross-platform compatibility
41
- */
42
- function generateCodebaseId(path) {
43
- // Normalize path (handle Windows/Unix differences)
44
- const normalized = resolve(path).replace(/\\/g, '/');
45
- // Use path as ID (stable identifier)
46
- // For production, could hash this for shorter IDs
47
- return normalized;
48
- }
49
- /**
50
- * Find git root directory
51
- */
52
- function findGitRoot(startPath) {
53
- let currentDir = startPath;
54
- const root = currentDir.split(/[/\\]/)[0];
55
- while (currentDir !== root) {
56
- if (existsSync(join(currentDir, '.git'))) {
57
- return currentDir;
58
- }
59
- const parentDir = dirname(currentDir);
60
- if (parentDir === currentDir) {
61
- break;
62
- }
63
- currentDir = parentDir;
64
- }
65
- return null;
66
- }
67
- /**
68
- * Find package.json root directory
69
- */
70
- function findPackageRoot(startPath) {
71
- let currentDir = startPath;
72
- const root = currentDir.split(/[/\\]/)[0];
73
- while (currentDir !== root) {
74
- if (existsSync(join(currentDir, 'package.json'))) {
75
- return currentDir;
76
- }
77
- const parentDir = dirname(currentDir);
78
- if (parentDir === currentDir) {
79
- break;
80
- }
81
- currentDir = parentDir;
82
- }
83
- return null;
84
- }
85
- //# sourceMappingURL=codebase-detector.js.map
@@ -1,91 +0,0 @@
1
- /**
2
- * Domain types for a task's observable shape — status, progress steps, and the
3
- * end-of-task artifacts. Pure data: no I/O, no behavior, no dependencies. These
4
- * live in `domain/` so application + infrastructure import them DOWN, rather than
5
- * reaching up into an adapter file for the core vocabulary.
6
- * Moved here 2026-06-09 (spec R14 / ARCHITECTURE.md M1) from
7
- * infrastructure/orchestration/agent-adapter.ts. The `TaskSession` runtime handle
8
- * (which has behavior: subscribe/kill/appendMessage) and the `AgentAdapter` port
9
- * stay with the adapters; only the pure data shapes move here.
10
- */
11
- /**
12
- * R13/M3 — THE one owned transition for `artifacts.tests`. Before this, the
13
- * exit-path re-run mutated the artifact inline in the session manager: the
14
- * exit-code-authoritative merge, the claim-preservation rule, and the
15
- * silent-blank-when-unobservable gap all lived in untyped infra code. This is
16
- * now the only writer of the post-exit tests artifact.
17
- *
18
- * Mutates `artifacts` IN PLACE by design: the live TaskSession exposes
19
- * `artifacts` as a readonly getter over one shared object that the API layer
20
- * re-reads each poll — replacing the reference would detach the live verdict.
21
- *
22
- * Rules (verbatim from the prior inline code, now pinned by unit tests):
23
- * - exit code is authoritative: a non-zero exit with no parseable count still
24
- * forces failed >= 1, so a "tests pass" claim that didn't pass gets caught;
25
- * - the agent's ORIGINAL scrape is preserved as `claimed` so the verifier can
26
- * still catch a prose-vs-own-stdout self-contradiction;
27
- * - couldn't run → the explicit reason lands in `testsUnobserved` instead of
28
- * leaving the artifact silently blank (the R5 leftover).
29
- */
30
- export function applyTestObservation(artifacts, observation) {
31
- if (!observation.ran) {
32
- artifacts.testsUnobserved = observation.skippedReason ?? 'could not re-run the tests';
33
- return 'unobserved';
34
- }
35
- const claimed = artifacts.tests;
36
- let failed = observation.failed ?? 0;
37
- if (observation.exitCode !== 0 && failed === 0)
38
- failed = 1;
39
- // LOW #28 (atomic audit) · exit 0 with no parseable count reuses the
40
- // AGENT'S claimed number. The exit code is ground truth (the suite ran and
41
- // passed) but the COUNT is not — say which is which (countSource) so the
42
- // surface can label "re-run ✓ · count as reported" instead of implying the
43
- // number itself was observed.
44
- const countParsed = observation.passed !== undefined;
45
- const passed = observation.passed ?? (observation.exitCode === 0 ? (claimed?.passed ?? 0) : 0);
46
- artifacts.tests = {
47
- passed,
48
- failed,
49
- observed: true,
50
- ...(countParsed ? {} : { countSource: 'claimed' }),
51
- ...(claimed ? { claimed: { passed: claimed.passed, failed: claimed.failed } } : {}),
52
- ...(observation.command ? { command: observation.command } : {}),
53
- ...(observation.exitCode !== undefined ? { exitCode: observation.exitCode } : {}),
54
- ...(observation.durationMs !== undefined ? { durationMs: observation.durationMs } : {}),
55
- };
56
- delete artifacts.testsUnobserved; // an observed result supersedes any earlier couldn't-observe
57
- return 'observed';
58
- }
59
- /** Derive the typed completeness view from a session's recorded parts. */
60
- export function describeCompleted(input) {
61
- const a = input.artifacts;
62
- return {
63
- sessionId: input.sessionId,
64
- agent: input.agent,
65
- status: input.status,
66
- completedAt: input.completedAt,
67
- durationMs: input.durationMs,
68
- steps: input.steps ?? [],
69
- files: a?.files
70
- ? { present: a.files }
71
- : {
72
- absent: a?.noGitTracking
73
- ? "ran in a non-git folder — codehere can't see what changed"
74
- : 'no file changes recorded',
75
- },
76
- tests: a?.tests
77
- ? { present: a.tests }
78
- : { absent: a?.testsUnobserved ?? 'not test-relevant — no claim made, no test files touched' },
79
- report: input.finalReport?.summary
80
- ? { present: { summary: input.finalReport.summary } }
81
- : { absent: input.failedReport ? 'report generation failed' : 'no written report' },
82
- audit: input.auditRecon
83
- ? { present: input.auditRecon }
84
- : {
85
- // Precise: reconciliation RUNS in the daemon at completion but is
86
- // held in memory, not persisted — so a later reader can't see it.
87
- absent: 'reconciliation not visible here — it runs in the daemon that observed the exit and is not persisted',
88
- },
89
- };
90
- }
91
- //# sourceMappingURL=task.js.map
@@ -1,139 +0,0 @@
1
- /**
2
- * Error classification + circuit breaker for API calls.
3
- */
4
- export var ErrorType;
5
- (function (ErrorType) {
6
- ErrorType["RETRYABLE"] = "RETRYABLE";
7
- ErrorType["FATAL"] = "FATAL";
8
- ErrorType["RATE_LIMIT"] = "RATE_LIMIT";
9
- ErrorType["NETWORK"] = "NETWORK";
10
- ErrorType["API_ERROR"] = "API_ERROR";
11
- ErrorType["VALIDATION"] = "VALIDATION";
12
- ErrorType["POLICY"] = "POLICY";
13
- })(ErrorType || (ErrorType = {}));
14
- export class EnterpriseError extends Error {
15
- errorType;
16
- context;
17
- retryable;
18
- constructor(message, errorType, context, retryable = false) {
19
- super(message);
20
- this.errorType = errorType;
21
- this.context = context;
22
- this.retryable = retryable;
23
- this.name = 'EnterpriseError';
24
- }
25
- }
26
- /**
27
- * Classify error type for appropriate handling
28
- */
29
- export function classifyError(error) {
30
- if (error instanceof EnterpriseError) {
31
- return error.errorType;
32
- }
33
- // Check for 429 status code directly (Cohere SDK errors)
34
- if (error && typeof error === 'object') {
35
- const err = error;
36
- if (err.statusCode === 429 || err.status === 429) {
37
- return ErrorType.RATE_LIMIT;
38
- }
39
- // Check error name/class
40
- const errorName = err.constructor?.name || err.name || '';
41
- if (errorName.includes('TooManyRequests') || errorName === 'TooManyRequestsError') {
42
- return ErrorType.RATE_LIMIT;
43
- }
44
- // Check body/message for trial key quota messages
45
- const body = err.body || err.message || '';
46
- if (typeof body === 'string' && body.includes('Trial key') && body.includes('1000 API calls')) {
47
- return ErrorType.RATE_LIMIT;
48
- }
49
- }
50
- const errorMessage = error instanceof Error ? error.message : String(error);
51
- const lowerMessage = errorMessage.toLowerCase();
52
- // Rate limiting - check message content
53
- if (lowerMessage.includes('rate limit') ||
54
- lowerMessage.includes('429') ||
55
- lowerMessage.includes('too many requests') ||
56
- lowerMessage.includes('toomanyrequests') ||
57
- (lowerMessage.includes('trial key') && lowerMessage.includes('1000'))) {
58
- return ErrorType.RATE_LIMIT;
59
- }
60
- // Network errors
61
- if (lowerMessage.includes('network') || lowerMessage.includes('timeout') || lowerMessage.includes('econnrefused')) {
62
- return ErrorType.NETWORK;
63
- }
64
- // API errors
65
- if (lowerMessage.includes('api') || lowerMessage.includes('cohere')) {
66
- return ErrorType.API_ERROR;
67
- }
68
- // Validation errors
69
- if (lowerMessage.includes('validation') || lowerMessage.includes('invalid')) {
70
- return ErrorType.VALIDATION;
71
- }
72
- // Default to retryable
73
- return ErrorType.RETRYABLE;
74
- }
75
- /**
76
- * Circuit breaker pattern for API calls
77
- */
78
- export class CircuitBreaker {
79
- threshold;
80
- resetTimeout;
81
- failures = 0;
82
- lastFailureTime = 0;
83
- state = 'CLOSED';
84
- constructor(threshold = 5, resetTimeout = 30000) {
85
- this.threshold = threshold;
86
- this.resetTimeout = resetTimeout;
87
- }
88
- async execute(operation) {
89
- // Check if circuit should be reset
90
- if (this.state === 'OPEN') {
91
- const timeSinceLastFailure = Date.now() - this.lastFailureTime;
92
- if (timeSinceLastFailure > this.resetTimeout) {
93
- this.state = 'HALF_OPEN';
94
- }
95
- else {
96
- throw new EnterpriseError('Circuit breaker is OPEN. Service unavailable.', ErrorType.API_ERROR, {
97
- operation: 'circuit_breaker',
98
- timestamp: new Date().toISOString(),
99
- errorType: ErrorType.API_ERROR,
100
- originalError: new Error('Circuit breaker open'),
101
- }, false);
102
- }
103
- }
104
- try {
105
- const result = await operation();
106
- // Success - reset failures if in HALF_OPEN
107
- if (this.state === 'HALF_OPEN') {
108
- this.state = 'CLOSED';
109
- this.failures = 0;
110
- }
111
- else if (this.failures > 0) {
112
- this.failures = 0;
113
- }
114
- return result;
115
- }
116
- catch (error) {
117
- this.failures++;
118
- this.lastFailureTime = Date.now();
119
- // Open circuit if threshold exceeded
120
- if (this.failures >= this.threshold) {
121
- this.state = 'OPEN';
122
- }
123
- throw error;
124
- }
125
- }
126
- getState() {
127
- return this.state;
128
- }
129
- reset() {
130
- this.failures = 0;
131
- this.state = 'CLOSED';
132
- this.lastFailureTime = 0;
133
- }
134
- }
135
- /**
136
- * Global circuit breaker for Cohere API
137
- */
138
- export const cohereCircuitBreaker = new CircuitBreaker(5, 30000);
139
- //# sourceMappingURL=error-handler.js.map
@@ -1,29 +0,0 @@
1
- /**
2
- * Bash Completion Script Generator
3
- *
4
- * Completions are generated from the REAL registered command list passed by
5
- * the caller — the alpha-era hardcoded set (`ask plan orchestrate …`) shipped
6
- * completions for commands that never existed (caught by the 2026-06-07
7
- * v1-readiness audit, Lane C).
8
- */
9
- export function generateBashCompletion(commands) {
10
- const opts = commands.map((c) => c.name).join(' ');
11
- return `# Codehere bash completion
12
- _complete_codehere() {
13
- local cur prev opts
14
- COMPREPLY=()
15
- cur="\${COMP_WORDS[COMP_CWORD]}"
16
- prev="\${COMP_WORDS[COMP_CWORD-1]}"
17
- opts="${opts}"
18
-
19
- if [[ \${cur} == -* ]]; then
20
- COMPREPLY=($(compgen -W "--help --version" -- \${cur}))
21
- else
22
- COMPREPLY=($(compgen -W "\${opts}" -- \${cur}))
23
- fi
24
- }
25
-
26
- complete -F _complete_codehere codehere
27
- `;
28
- }
29
- //# sourceMappingURL=bash-completion.js.map
@@ -1,17 +0,0 @@
1
- /**
2
- * Fish Completion Script Generator
3
- *
4
- * Completions are generated from the REAL registered command list passed by
5
- * the caller (see bash-completion.ts header for the audit history).
6
- */
7
- export function generateFishCompletion(commands) {
8
- const lines = commands
9
- .map((c) => `complete -c codehere -n __fish_use_subcommand -a ${c.name} -d "${c.description.replace(/"/g, '')}"`)
10
- .join('\n');
11
- return `# Codehere fish completion
12
- complete -c codehere -f
13
-
14
- ${lines}
15
- `;
16
- }
17
- //# sourceMappingURL=fish-completion.js.map
@@ -1,25 +0,0 @@
1
- /**
2
- * Zsh Completion Script Generator
3
- *
4
- * Completions are generated from the REAL registered command list passed by
5
- * the caller (see bash-completion.ts header for the audit history).
6
- */
7
- export function generateZshCompletion(commands) {
8
- // zsh _describe entries are 'name:description' — strip colons/quotes from
9
- // descriptions so they can't break the entry syntax.
10
- const entries = commands.map((c) => ` '${c.name}:${c.description.replace(/['":]/g, '')}'`).join('\n');
11
- return `#compdef codehere
12
-
13
- _codehere() {
14
- local -a commands
15
- commands=(
16
- ${entries}
17
- )
18
-
19
- _describe 'codehere' commands
20
- }
21
-
22
- _codehere "$@"
23
- `;
24
- }
25
- //# sourceMappingURL=zsh-completion.js.map