oxe-cc 1.2.1 → 1.3.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 (276) hide show
  1. package/.cursor/commands/oxe-ask.md +2 -2
  2. package/.cursor/commands/oxe-capabilities.md +2 -2
  3. package/.cursor/commands/oxe-checkpoint.md +2 -2
  4. package/.cursor/commands/oxe-compact.md +2 -2
  5. package/.cursor/commands/oxe-dashboard.md +2 -2
  6. package/.cursor/commands/oxe-debug.md +2 -2
  7. package/.cursor/commands/oxe-discuss.md +2 -2
  8. package/.cursor/commands/oxe-execute.md +5 -2
  9. package/.cursor/commands/oxe-forensics.md +2 -2
  10. package/.cursor/commands/oxe-help.md +2 -2
  11. package/.cursor/commands/oxe-loop.md +2 -2
  12. package/.cursor/commands/oxe-milestone.md +2 -2
  13. package/.cursor/commands/oxe-next.md +2 -2
  14. package/.cursor/commands/oxe-obs.md +2 -2
  15. package/.cursor/commands/oxe-plan-agent.md +2 -2
  16. package/.cursor/commands/oxe-plan.md +2 -2
  17. package/.cursor/commands/oxe-project.md +2 -2
  18. package/.cursor/commands/oxe-quick.md +2 -2
  19. package/.cursor/commands/oxe-research.md +2 -2
  20. package/.cursor/commands/oxe-retro.md +2 -2
  21. package/.cursor/commands/oxe-review-pr.md +2 -2
  22. package/.cursor/commands/oxe-route.md +2 -2
  23. package/.cursor/commands/oxe-scan.md +2 -2
  24. package/.cursor/commands/oxe-security.md +2 -2
  25. package/.cursor/commands/oxe-session.md +2 -2
  26. package/.cursor/commands/oxe-ship.md +2 -2
  27. package/.cursor/commands/oxe-skill.md +2 -2
  28. package/.cursor/commands/oxe-spec.md +2 -2
  29. package/.cursor/commands/oxe-ui-review.md +2 -2
  30. package/.cursor/commands/oxe-ui-spec.md +2 -2
  31. package/.cursor/commands/oxe-update.md +2 -2
  32. package/.cursor/commands/oxe-validate-gaps.md +2 -2
  33. package/.cursor/commands/oxe-verify.md +5 -2
  34. package/.cursor/commands/oxe-workstream.md +2 -2
  35. package/.cursor/commands/oxe.md +2 -2
  36. package/.github/copilot-instructions.md +13 -13
  37. package/.github/prompts/oxe-ask.prompt.md +2 -2
  38. package/.github/prompts/oxe-capabilities.prompt.md +2 -2
  39. package/.github/prompts/oxe-checkpoint.prompt.md +2 -2
  40. package/.github/prompts/oxe-compact.prompt.md +2 -2
  41. package/.github/prompts/oxe-dashboard.prompt.md +2 -2
  42. package/.github/prompts/oxe-debug.prompt.md +2 -2
  43. package/.github/prompts/oxe-discuss.prompt.md +2 -2
  44. package/.github/prompts/oxe-execute.prompt.md +5 -2
  45. package/.github/prompts/oxe-forensics.prompt.md +2 -2
  46. package/.github/prompts/oxe-help.prompt.md +2 -2
  47. package/.github/prompts/oxe-loop.prompt.md +2 -2
  48. package/.github/prompts/oxe-milestone.prompt.md +2 -2
  49. package/.github/prompts/oxe-next.prompt.md +2 -2
  50. package/.github/prompts/oxe-obs.prompt.md +2 -2
  51. package/.github/prompts/oxe-plan-agent.prompt.md +2 -2
  52. package/.github/prompts/oxe-plan.prompt.md +2 -2
  53. package/.github/prompts/oxe-project.prompt.md +2 -2
  54. package/.github/prompts/oxe-quick.prompt.md +2 -2
  55. package/.github/prompts/oxe-research.prompt.md +2 -2
  56. package/.github/prompts/oxe-retro.prompt.md +2 -2
  57. package/.github/prompts/oxe-review-pr.prompt.md +2 -2
  58. package/.github/prompts/oxe-route.prompt.md +2 -2
  59. package/.github/prompts/oxe-scan.prompt.md +2 -2
  60. package/.github/prompts/oxe-security.prompt.md +2 -2
  61. package/.github/prompts/oxe-session.prompt.md +2 -2
  62. package/.github/prompts/oxe-ship.prompt.md +2 -2
  63. package/.github/prompts/oxe-skill.prompt.md +2 -2
  64. package/.github/prompts/oxe-spec.prompt.md +2 -2
  65. package/.github/prompts/oxe-ui-review.prompt.md +2 -2
  66. package/.github/prompts/oxe-ui-spec.prompt.md +2 -2
  67. package/.github/prompts/oxe-update.prompt.md +2 -2
  68. package/.github/prompts/oxe-validate-gaps.prompt.md +2 -2
  69. package/.github/prompts/oxe-verify.prompt.md +5 -2
  70. package/.github/prompts/oxe-workstream.prompt.md +2 -2
  71. package/.github/prompts/oxe.prompt.md +2 -2
  72. package/CHANGELOG.md +52 -17
  73. package/README.md +610 -551
  74. package/bin/banner.txt +1 -1
  75. package/bin/lib/oxe-agent-install.cjs +69 -69
  76. package/bin/lib/oxe-azure.cjs +1445 -1445
  77. package/bin/lib/oxe-context-engine.cjs +867 -867
  78. package/bin/lib/oxe-dashboard.cjs +76 -28
  79. package/bin/lib/oxe-operational.cjs +2144 -1340
  80. package/bin/lib/oxe-project-health.cjs +483 -1
  81. package/bin/lib/oxe-runtime-semantics.cjs +12 -0
  82. package/bin/oxe-cc.js +554 -152
  83. package/commands/oxe/ask.md +2 -2
  84. package/commands/oxe/capabilities.md +2 -2
  85. package/commands/oxe/checkpoint.md +2 -2
  86. package/commands/oxe/compact.md +2 -2
  87. package/commands/oxe/dashboard.md +2 -2
  88. package/commands/oxe/debug.md +2 -2
  89. package/commands/oxe/discuss.md +2 -2
  90. package/commands/oxe/execute.md +5 -2
  91. package/commands/oxe/forensics.md +2 -2
  92. package/commands/oxe/help.md +2 -2
  93. package/commands/oxe/loop.md +2 -2
  94. package/commands/oxe/milestone.md +2 -2
  95. package/commands/oxe/next.md +2 -2
  96. package/commands/oxe/obs.md +2 -2
  97. package/commands/oxe/oxe.md +2 -2
  98. package/commands/oxe/plan-agent.md +2 -2
  99. package/commands/oxe/plan.md +2 -2
  100. package/commands/oxe/project.md +2 -2
  101. package/commands/oxe/quick.md +2 -2
  102. package/commands/oxe/research.md +2 -2
  103. package/commands/oxe/retro.md +2 -2
  104. package/commands/oxe/review-pr.md +2 -2
  105. package/commands/oxe/route.md +2 -2
  106. package/commands/oxe/scan.md +2 -2
  107. package/commands/oxe/security.md +2 -2
  108. package/commands/oxe/session.md +2 -2
  109. package/commands/oxe/ship.md +2 -2
  110. package/commands/oxe/skill.md +2 -2
  111. package/commands/oxe/spec.md +2 -2
  112. package/commands/oxe/ui-review.md +2 -2
  113. package/commands/oxe/ui-spec.md +2 -2
  114. package/commands/oxe/update.md +2 -2
  115. package/commands/oxe/validate-gaps.md +2 -2
  116. package/commands/oxe/verify.md +5 -2
  117. package/commands/oxe/workstream.md +2 -2
  118. package/lib/runtime/delivery/branch-manager.d.ts +1 -0
  119. package/lib/runtime/delivery/branch-manager.js +7 -0
  120. package/lib/runtime/delivery/ci-checks.js +34 -1
  121. package/lib/runtime/delivery/delivery-records.d.ts +34 -0
  122. package/lib/runtime/delivery/delivery-records.js +48 -0
  123. package/lib/runtime/delivery/index.d.ts +1 -0
  124. package/lib/runtime/delivery/index.js +1 -0
  125. package/lib/runtime/delivery/promotion-pipeline.d.ts +26 -2
  126. package/lib/runtime/delivery/promotion-pipeline.js +111 -14
  127. package/lib/runtime/gate/gate-manager.d.ts +41 -0
  128. package/lib/runtime/gate/gate-manager.js +108 -1
  129. package/lib/runtime/index.d.ts +2 -2
  130. package/lib/runtime/index.js +3 -1
  131. package/lib/runtime/models/gate-decision.d.ts +4 -1
  132. package/lib/runtime/models/workspace.d.ts +3 -0
  133. package/lib/runtime/plugins/capability-adapter.d.ts +12 -0
  134. package/lib/runtime/plugins/capability-adapter.js +204 -0
  135. package/lib/runtime/plugins/capability-matrix.d.ts +5 -0
  136. package/lib/runtime/plugins/capability-matrix.js +48 -17
  137. package/lib/runtime/plugins/index.d.ts +1 -0
  138. package/lib/runtime/plugins/index.js +1 -0
  139. package/lib/runtime/plugins/plugin-abi.d.ts +2 -0
  140. package/lib/runtime/plugins/plugin-manifest.d.ts +1 -1
  141. package/lib/runtime/plugins/plugin-manifest.js +6 -2
  142. package/lib/runtime/plugins/plugin-registry.d.ts +46 -0
  143. package/lib/runtime/plugins/plugin-registry.js +79 -2
  144. package/lib/runtime/policy/policy-engine.d.ts +19 -0
  145. package/lib/runtime/policy/policy-engine.js +76 -4
  146. package/lib/runtime/projection/projection-engine.d.ts +9 -1
  147. package/lib/runtime/projection/projection-engine.js +73 -3
  148. package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +43 -1
  149. package/lib/runtime/scheduler/multi-agent-coordinator.js +151 -39
  150. package/lib/runtime/scheduler/run-journal.d.ts +1 -1
  151. package/lib/runtime/scheduler/scheduler.d.ts +19 -1
  152. package/lib/runtime/scheduler/scheduler.js +258 -13
  153. package/lib/runtime/verification/verification-compiler.d.ts +43 -0
  154. package/lib/runtime/verification/verification-compiler.js +137 -0
  155. package/lib/runtime/verification/verification-manifest.d.ts +9 -0
  156. package/lib/runtime/verification/verification-manifest.js +56 -6
  157. package/lib/runtime/workspace/strategies/ephemeral-container.d.ts +1 -0
  158. package/lib/runtime/workspace/strategies/ephemeral-container.js +4 -0
  159. package/lib/runtime/workspace/strategies/git-worktree.d.ts +1 -0
  160. package/lib/runtime/workspace/strategies/git-worktree.js +2 -0
  161. package/lib/runtime/workspace/strategies/inplace.d.ts +1 -0
  162. package/lib/runtime/workspace/strategies/inplace.js +2 -0
  163. package/lib/runtime/workspace/workspace-manager.d.ts +2 -1
  164. package/lib/sdk/README.md +9 -9
  165. package/lib/sdk/index.cjs +33 -24
  166. package/lib/sdk/index.d.ts +149 -14
  167. package/oxe/templates/ACTIVE-RUN.template.json +32 -32
  168. package/oxe/templates/CAPABILITIES.template.md +7 -7
  169. package/oxe/templates/CAPABILITY.template.md +45 -45
  170. package/oxe/templates/CHECKPOINTS.template.md +7 -7
  171. package/oxe/templates/EXECUTION-RUNTIME.template.md +68 -68
  172. package/oxe/templates/HYPOTHESES.template.md +33 -33
  173. package/oxe/templates/LESSONS-METRICS.template.json +13 -13
  174. package/oxe/templates/NOTES.template.md +16 -16
  175. package/oxe/templates/PLAN-REVIEW.template.md +31 -31
  176. package/oxe/templates/SESSION.template.md +34 -34
  177. package/oxe/templates/SKILL.template.md +26 -26
  178. package/oxe/templates/STATE.md +55 -55
  179. package/oxe/templates/WORKFLOW_AUTHORING.md +18 -18
  180. package/oxe/workflows/ask.md +96 -96
  181. package/oxe/workflows/capabilities.md +25 -25
  182. package/oxe/workflows/dashboard.md +33 -33
  183. package/oxe/workflows/discuss.md +12 -12
  184. package/oxe/workflows/execute.md +14 -0
  185. package/oxe/workflows/help.md +352 -352
  186. package/oxe/workflows/next.md +22 -22
  187. package/oxe/workflows/oxe.md +6 -6
  188. package/oxe/workflows/plan-agent.md +9 -9
  189. package/oxe/workflows/quick.md +10 -10
  190. package/oxe/workflows/references/reasoning-discovery.md +28 -28
  191. package/oxe/workflows/references/reasoning-execution.md +29 -29
  192. package/oxe/workflows/references/reasoning-planning.md +32 -32
  193. package/oxe/workflows/references/reasoning-review.md +29 -29
  194. package/oxe/workflows/references/reasoning-status.md +24 -24
  195. package/oxe/workflows/references/robustness-elevation.md +295 -295
  196. package/oxe/workflows/references/workflow-runtime-contracts.json +952 -930
  197. package/oxe/workflows/route.md +16 -16
  198. package/oxe/workflows/session.md +213 -213
  199. package/oxe/workflows/ship.md +142 -142
  200. package/oxe/workflows/skill.md +44 -44
  201. package/oxe/workflows/ui-review.md +36 -36
  202. package/oxe/workflows/verify-audit.md +73 -73
  203. package/oxe/workflows/verify.md +10 -0
  204. package/package.json +92 -92
  205. package/packages/runtime/package.json +17 -17
  206. package/packages/runtime/src/audit/audit-trail.ts +243 -243
  207. package/packages/runtime/src/audit/index.ts +2 -2
  208. package/packages/runtime/src/audit/policy-pack.ts +62 -62
  209. package/packages/runtime/src/compiler/graph-compiler.ts +245 -245
  210. package/packages/runtime/src/compiler/index.ts +1 -1
  211. package/packages/runtime/src/context/context-pack-builder.ts +259 -259
  212. package/packages/runtime/src/context/context-pack-store.ts +197 -197
  213. package/packages/runtime/src/context/context-profiles.ts +60 -60
  214. package/packages/runtime/src/context/index.ts +3 -3
  215. package/packages/runtime/src/decision/decision-engine.ts +174 -174
  216. package/packages/runtime/src/decision/decision-memo.ts +211 -211
  217. package/packages/runtime/src/decision/index.ts +2 -2
  218. package/packages/runtime/src/delivery/branch-manager.ts +91 -84
  219. package/packages/runtime/src/delivery/ci-checks.ts +285 -252
  220. package/packages/runtime/src/delivery/delivery-records.ts +75 -0
  221. package/packages/runtime/src/delivery/index.ts +5 -4
  222. package/packages/runtime/src/delivery/pr-manager.ts +112 -112
  223. package/packages/runtime/src/delivery/promotion-pipeline.ts +334 -180
  224. package/packages/runtime/src/events/bus.ts +92 -92
  225. package/packages/runtime/src/events/catalog.ts +29 -29
  226. package/packages/runtime/src/events/envelope.ts +14 -14
  227. package/packages/runtime/src/events/index.ts +3 -3
  228. package/packages/runtime/src/evidence/evidence-store.ts +130 -130
  229. package/packages/runtime/src/evidence/index.ts +1 -1
  230. package/packages/runtime/src/gate/gate-manager.ts +289 -137
  231. package/packages/runtime/src/gate/index.ts +1 -1
  232. package/packages/runtime/src/index.ts +41 -37
  233. package/packages/runtime/src/models/attempt.ts +19 -19
  234. package/packages/runtime/src/models/evidence.ts +21 -21
  235. package/packages/runtime/src/models/gate-decision.ts +25 -21
  236. package/packages/runtime/src/models/index.ts +8 -8
  237. package/packages/runtime/src/models/run.ts +24 -24
  238. package/packages/runtime/src/models/session.ts +11 -11
  239. package/packages/runtime/src/models/verification-result.ts +10 -10
  240. package/packages/runtime/src/models/work-item.ts +25 -25
  241. package/packages/runtime/src/models/workspace.ts +31 -28
  242. package/packages/runtime/src/plugins/capability-adapter.ts +206 -0
  243. package/packages/runtime/src/plugins/capability-matrix.ts +126 -83
  244. package/packages/runtime/src/plugins/index.ts +5 -4
  245. package/packages/runtime/src/plugins/plugin-abi.ts +97 -95
  246. package/packages/runtime/src/plugins/plugin-manifest.ts +118 -113
  247. package/packages/runtime/src/plugins/plugin-registry.ts +232 -124
  248. package/packages/runtime/src/policy/index.ts +1 -1
  249. package/packages/runtime/src/policy/policy-engine.ts +330 -244
  250. package/packages/runtime/src/projection/index.ts +1 -1
  251. package/packages/runtime/src/projection/projection-engine.ts +328 -249
  252. package/packages/runtime/src/reducers/debug-reducer.ts +36 -36
  253. package/packages/runtime/src/reducers/index.ts +2 -2
  254. package/packages/runtime/src/reducers/run-state-reducer.ts +269 -269
  255. package/packages/runtime/src/scheduler/agent-registry.ts +132 -132
  256. package/packages/runtime/src/scheduler/agent-roles.ts +109 -109
  257. package/packages/runtime/src/scheduler/index.ts +4 -4
  258. package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +521 -333
  259. package/packages/runtime/src/scheduler/run-journal.ts +62 -62
  260. package/packages/runtime/src/scheduler/scheduler.ts +722 -441
  261. package/packages/runtime/src/verification/index.ts +2 -2
  262. package/packages/runtime/src/verification/verification-compiler.ts +436 -225
  263. package/packages/runtime/src/verification/verification-manifest.ts +252 -192
  264. package/packages/runtime/src/workspace/index.ts +5 -5
  265. package/packages/runtime/src/workspace/strategies/ephemeral-container.ts +126 -121
  266. package/packages/runtime/src/workspace/strategies/git-worktree.ts +79 -77
  267. package/packages/runtime/src/workspace/strategies/inplace.ts +38 -35
  268. package/packages/runtime/src/workspace/workspace-manager.ts +16 -15
  269. package/packages/runtime/tsconfig.json +17 -17
  270. package/vscode-extension/.vscodeignore +7 -7
  271. package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
  272. package/vscode-extension/package.json +185 -185
  273. package/vscode-extension/src/extension.js +310 -310
  274. package/vscode-extension/src/shared/contextLoader.js +137 -137
  275. package/vscode-extension/src/shared/contractBuilder.js +159 -159
  276. package/vscode-extension/src/shared/stateReader.js +101 -101
@@ -1,197 +1,197 @@
1
- import path from 'path';
2
- import fs from 'fs';
3
- import type { ContextPack, ContextArtifact, ContextQualityScore } from './context-pack-builder';
4
-
5
- export interface ContextPackMeta {
6
- pack_id: string;
7
- work_item_id: string;
8
- run_id: string;
9
- built_at: string;
10
- artifact_count: number;
11
- estimated_tokens: number;
12
- stale: boolean;
13
- stale_reason: string | null;
14
- }
15
-
16
- export interface ContextPackDiff {
17
- added: string[];
18
- removed: string[];
19
- score_changed: Array<{ id: string; before: number; after: number }>;
20
- }
21
-
22
- function packPath(projectRoot: string, runId: string, workItemId: string): string {
23
- return path.join(projectRoot, '.oxe', 'runs', runId, `context-pack-${workItemId}.json`);
24
- }
25
-
26
- function metaIndexPath(projectRoot: string, runId: string): string {
27
- return path.join(projectRoot, '.oxe', 'runs', runId, 'context-packs.index.json');
28
- }
29
-
30
- function estimateTokens(pack: ContextPack): number {
31
- return Math.ceil(pack.artifacts.reduce((sum, a) => sum + a.content.length, 0) / 4);
32
- }
33
-
34
- export function savePack(
35
- projectRoot: string,
36
- runId: string,
37
- pack: ContextPack
38
- ): ContextPackMeta {
39
- const p = packPath(projectRoot, runId, pack.work_item_id);
40
- fs.mkdirSync(path.dirname(p), { recursive: true });
41
- fs.writeFileSync(p, JSON.stringify(pack, null, 2), 'utf8');
42
-
43
- const meta: ContextPackMeta = {
44
- pack_id: `cp-${runId}-${pack.work_item_id}`,
45
- work_item_id: pack.work_item_id,
46
- run_id: runId,
47
- built_at: pack.built_at,
48
- artifact_count: pack.artifacts.length,
49
- estimated_tokens: estimateTokens(pack),
50
- stale: false,
51
- stale_reason: null,
52
- };
53
-
54
- updateMetaIndex(projectRoot, runId, meta);
55
- return meta;
56
- }
57
-
58
- export function loadPack(
59
- projectRoot: string,
60
- runId: string,
61
- workItemId: string
62
- ): ContextPack | null {
63
- const p = packPath(projectRoot, runId, workItemId);
64
- if (!fs.existsSync(p)) return null;
65
- try {
66
- return JSON.parse(fs.readFileSync(p, 'utf8')) as ContextPack;
67
- } catch {
68
- return null;
69
- }
70
- }
71
-
72
- export function markStale(
73
- projectRoot: string,
74
- runId: string,
75
- workItemId: string,
76
- reason: string
77
- ): void {
78
- const index = loadMetaIndex(projectRoot, runId);
79
- const meta = index.find((m) => m.work_item_id === workItemId);
80
- if (!meta) return;
81
- meta.stale = true;
82
- meta.stale_reason = reason;
83
- saveMetaIndex(projectRoot, runId, index);
84
- }
85
-
86
- export function isStale(
87
- projectRoot: string,
88
- runId: string,
89
- workItemId: string
90
- ): boolean {
91
- const index = loadMetaIndex(projectRoot, runId);
92
- return index.find((m) => m.work_item_id === workItemId)?.stale ?? false;
93
- }
94
-
95
- export function diffPacks(before: ContextPack, after: ContextPack): ContextPackDiff {
96
- const beforeIds = new Set(before.artifacts.map((a) => a.id));
97
- const afterIds = new Set(after.artifacts.map((a) => a.id));
98
- const beforeMap = new Map(before.artifacts.map((a) => [a.id, a]));
99
- const afterMap = new Map(after.artifacts.map((a) => [a.id, a]));
100
-
101
- const added = [...afterIds].filter((id) => !beforeIds.has(id));
102
- const removed = [...beforeIds].filter((id) => !afterIds.has(id));
103
-
104
- const score_changed: ContextPackDiff['score_changed'] = [];
105
- for (const id of afterIds) {
106
- if (!beforeIds.has(id)) continue;
107
- const bScore = beforeMap.get(id)!.relevanceScore;
108
- const aScore = afterMap.get(id)!.relevanceScore;
109
- if (Math.abs(bScore - aScore) > 0.05) {
110
- score_changed.push({ id, before: bScore, after: aScore });
111
- }
112
- }
113
-
114
- return { added, removed, score_changed };
115
- }
116
-
117
- export function listPackMeta(projectRoot: string, runId: string): ContextPackMeta[] {
118
- return loadMetaIndex(projectRoot, runId);
119
- }
120
-
121
- // ─── ContextPackRef — link pack to a specific execution attempt ───────────────
122
-
123
- export interface ContextPackRef {
124
- ref_id: string;
125
- pack_id: string;
126
- attempt_id: string;
127
- work_item_id: string;
128
- run_id: string;
129
- artifacts_used: string[];
130
- quality: ContextQualityScore;
131
- linked_at: string;
132
- }
133
-
134
- function packRefPath(projectRoot: string, runId: string, attemptId: string): string {
135
- return path.join(projectRoot, '.oxe', 'runs', runId, `context-ref-${attemptId}.json`);
136
- }
137
-
138
- export function linkPackToAttempt(
139
- projectRoot: string,
140
- runId: string,
141
- attemptId: string,
142
- pack: ContextPack,
143
- quality: ContextQualityScore
144
- ): ContextPackRef {
145
- const ref: ContextPackRef = {
146
- ref_id: `ref-${runId}-${attemptId}`,
147
- pack_id: `cp-${runId}-${pack.work_item_id}`,
148
- attempt_id: attemptId,
149
- work_item_id: pack.work_item_id,
150
- run_id: runId,
151
- artifacts_used: pack.artifacts.map((a) => a.id),
152
- quality,
153
- linked_at: new Date().toISOString(),
154
- };
155
- const p = packRefPath(projectRoot, runId, attemptId);
156
- fs.mkdirSync(path.dirname(p), { recursive: true });
157
- fs.writeFileSync(p, JSON.stringify(ref, null, 2), 'utf8');
158
- return ref;
159
- }
160
-
161
- export function getPackRefForAttempt(
162
- projectRoot: string,
163
- runId: string,
164
- attemptId: string
165
- ): ContextPackRef | null {
166
- const p = packRefPath(projectRoot, runId, attemptId);
167
- if (!fs.existsSync(p)) return null;
168
- try {
169
- return JSON.parse(fs.readFileSync(p, 'utf8')) as ContextPackRef;
170
- } catch {
171
- return null;
172
- }
173
- }
174
-
175
- function loadMetaIndex(projectRoot: string, runId: string): ContextPackMeta[] {
176
- const p = metaIndexPath(projectRoot, runId);
177
- if (!fs.existsSync(p)) return [];
178
- try {
179
- return JSON.parse(fs.readFileSync(p, 'utf8')) as ContextPackMeta[];
180
- } catch {
181
- return [];
182
- }
183
- }
184
-
185
- function saveMetaIndex(projectRoot: string, runId: string, index: ContextPackMeta[]): void {
186
- const p = metaIndexPath(projectRoot, runId);
187
- fs.mkdirSync(path.dirname(p), { recursive: true });
188
- fs.writeFileSync(p, JSON.stringify(index, null, 2), 'utf8');
189
- }
190
-
191
- function updateMetaIndex(projectRoot: string, runId: string, meta: ContextPackMeta): void {
192
- const index = loadMetaIndex(projectRoot, runId);
193
- const idx = index.findIndex((m) => m.work_item_id === meta.work_item_id);
194
- if (idx >= 0) index[idx] = meta;
195
- else index.push(meta);
196
- saveMetaIndex(projectRoot, runId, index);
197
- }
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import type { ContextPack, ContextArtifact, ContextQualityScore } from './context-pack-builder';
4
+
5
+ export interface ContextPackMeta {
6
+ pack_id: string;
7
+ work_item_id: string;
8
+ run_id: string;
9
+ built_at: string;
10
+ artifact_count: number;
11
+ estimated_tokens: number;
12
+ stale: boolean;
13
+ stale_reason: string | null;
14
+ }
15
+
16
+ export interface ContextPackDiff {
17
+ added: string[];
18
+ removed: string[];
19
+ score_changed: Array<{ id: string; before: number; after: number }>;
20
+ }
21
+
22
+ function packPath(projectRoot: string, runId: string, workItemId: string): string {
23
+ return path.join(projectRoot, '.oxe', 'runs', runId, `context-pack-${workItemId}.json`);
24
+ }
25
+
26
+ function metaIndexPath(projectRoot: string, runId: string): string {
27
+ return path.join(projectRoot, '.oxe', 'runs', runId, 'context-packs.index.json');
28
+ }
29
+
30
+ function estimateTokens(pack: ContextPack): number {
31
+ return Math.ceil(pack.artifacts.reduce((sum, a) => sum + a.content.length, 0) / 4);
32
+ }
33
+
34
+ export function savePack(
35
+ projectRoot: string,
36
+ runId: string,
37
+ pack: ContextPack
38
+ ): ContextPackMeta {
39
+ const p = packPath(projectRoot, runId, pack.work_item_id);
40
+ fs.mkdirSync(path.dirname(p), { recursive: true });
41
+ fs.writeFileSync(p, JSON.stringify(pack, null, 2), 'utf8');
42
+
43
+ const meta: ContextPackMeta = {
44
+ pack_id: `cp-${runId}-${pack.work_item_id}`,
45
+ work_item_id: pack.work_item_id,
46
+ run_id: runId,
47
+ built_at: pack.built_at,
48
+ artifact_count: pack.artifacts.length,
49
+ estimated_tokens: estimateTokens(pack),
50
+ stale: false,
51
+ stale_reason: null,
52
+ };
53
+
54
+ updateMetaIndex(projectRoot, runId, meta);
55
+ return meta;
56
+ }
57
+
58
+ export function loadPack(
59
+ projectRoot: string,
60
+ runId: string,
61
+ workItemId: string
62
+ ): ContextPack | null {
63
+ const p = packPath(projectRoot, runId, workItemId);
64
+ if (!fs.existsSync(p)) return null;
65
+ try {
66
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as ContextPack;
67
+ } catch {
68
+ return null;
69
+ }
70
+ }
71
+
72
+ export function markStale(
73
+ projectRoot: string,
74
+ runId: string,
75
+ workItemId: string,
76
+ reason: string
77
+ ): void {
78
+ const index = loadMetaIndex(projectRoot, runId);
79
+ const meta = index.find((m) => m.work_item_id === workItemId);
80
+ if (!meta) return;
81
+ meta.stale = true;
82
+ meta.stale_reason = reason;
83
+ saveMetaIndex(projectRoot, runId, index);
84
+ }
85
+
86
+ export function isStale(
87
+ projectRoot: string,
88
+ runId: string,
89
+ workItemId: string
90
+ ): boolean {
91
+ const index = loadMetaIndex(projectRoot, runId);
92
+ return index.find((m) => m.work_item_id === workItemId)?.stale ?? false;
93
+ }
94
+
95
+ export function diffPacks(before: ContextPack, after: ContextPack): ContextPackDiff {
96
+ const beforeIds = new Set(before.artifacts.map((a) => a.id));
97
+ const afterIds = new Set(after.artifacts.map((a) => a.id));
98
+ const beforeMap = new Map(before.artifacts.map((a) => [a.id, a]));
99
+ const afterMap = new Map(after.artifacts.map((a) => [a.id, a]));
100
+
101
+ const added = [...afterIds].filter((id) => !beforeIds.has(id));
102
+ const removed = [...beforeIds].filter((id) => !afterIds.has(id));
103
+
104
+ const score_changed: ContextPackDiff['score_changed'] = [];
105
+ for (const id of afterIds) {
106
+ if (!beforeIds.has(id)) continue;
107
+ const bScore = beforeMap.get(id)!.relevanceScore;
108
+ const aScore = afterMap.get(id)!.relevanceScore;
109
+ if (Math.abs(bScore - aScore) > 0.05) {
110
+ score_changed.push({ id, before: bScore, after: aScore });
111
+ }
112
+ }
113
+
114
+ return { added, removed, score_changed };
115
+ }
116
+
117
+ export function listPackMeta(projectRoot: string, runId: string): ContextPackMeta[] {
118
+ return loadMetaIndex(projectRoot, runId);
119
+ }
120
+
121
+ // ─── ContextPackRef — link pack to a specific execution attempt ───────────────
122
+
123
+ export interface ContextPackRef {
124
+ ref_id: string;
125
+ pack_id: string;
126
+ attempt_id: string;
127
+ work_item_id: string;
128
+ run_id: string;
129
+ artifacts_used: string[];
130
+ quality: ContextQualityScore;
131
+ linked_at: string;
132
+ }
133
+
134
+ function packRefPath(projectRoot: string, runId: string, attemptId: string): string {
135
+ return path.join(projectRoot, '.oxe', 'runs', runId, `context-ref-${attemptId}.json`);
136
+ }
137
+
138
+ export function linkPackToAttempt(
139
+ projectRoot: string,
140
+ runId: string,
141
+ attemptId: string,
142
+ pack: ContextPack,
143
+ quality: ContextQualityScore
144
+ ): ContextPackRef {
145
+ const ref: ContextPackRef = {
146
+ ref_id: `ref-${runId}-${attemptId}`,
147
+ pack_id: `cp-${runId}-${pack.work_item_id}`,
148
+ attempt_id: attemptId,
149
+ work_item_id: pack.work_item_id,
150
+ run_id: runId,
151
+ artifacts_used: pack.artifacts.map((a) => a.id),
152
+ quality,
153
+ linked_at: new Date().toISOString(),
154
+ };
155
+ const p = packRefPath(projectRoot, runId, attemptId);
156
+ fs.mkdirSync(path.dirname(p), { recursive: true });
157
+ fs.writeFileSync(p, JSON.stringify(ref, null, 2), 'utf8');
158
+ return ref;
159
+ }
160
+
161
+ export function getPackRefForAttempt(
162
+ projectRoot: string,
163
+ runId: string,
164
+ attemptId: string
165
+ ): ContextPackRef | null {
166
+ const p = packRefPath(projectRoot, runId, attemptId);
167
+ if (!fs.existsSync(p)) return null;
168
+ try {
169
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as ContextPackRef;
170
+ } catch {
171
+ return null;
172
+ }
173
+ }
174
+
175
+ function loadMetaIndex(projectRoot: string, runId: string): ContextPackMeta[] {
176
+ const p = metaIndexPath(projectRoot, runId);
177
+ if (!fs.existsSync(p)) return [];
178
+ try {
179
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as ContextPackMeta[];
180
+ } catch {
181
+ return [];
182
+ }
183
+ }
184
+
185
+ function saveMetaIndex(projectRoot: string, runId: string, index: ContextPackMeta[]): void {
186
+ const p = metaIndexPath(projectRoot, runId);
187
+ fs.mkdirSync(path.dirname(p), { recursive: true });
188
+ fs.writeFileSync(p, JSON.stringify(index, null, 2), 'utf8');
189
+ }
190
+
191
+ function updateMetaIndex(projectRoot: string, runId: string, meta: ContextPackMeta): void {
192
+ const index = loadMetaIndex(projectRoot, runId);
193
+ const idx = index.findIndex((m) => m.work_item_id === meta.work_item_id);
194
+ if (idx >= 0) index[idx] = meta;
195
+ else index.push(meta);
196
+ saveMetaIndex(projectRoot, runId, index);
197
+ }
@@ -1,60 +1,60 @@
1
- import type { ContextArtifact } from './context-pack-builder';
2
-
3
- export type ContextDecisionType = 'execute' | 'verify' | 'plan' | 'review' | 'debug' | 'migration';
4
-
5
- export interface ContextProfile {
6
- decision_type: ContextDecisionType;
7
- artifact_kind_weights: Record<ContextArtifact['kind'], number>;
8
- quality_threshold: number;
9
- max_artifacts: number;
10
- max_tokens: number;
11
- }
12
-
13
- export const DEFAULT_PROFILES: Record<ContextDecisionType, ContextProfile> = {
14
- execute: {
15
- decision_type: 'execute',
16
- artifact_kind_weights: { evidence: 0.8, lesson: 0.3, file: 0.6, summary: 0.4 },
17
- quality_threshold: 0.6,
18
- max_artifacts: 20,
19
- max_tokens: 8000,
20
- },
21
- verify: {
22
- decision_type: 'verify',
23
- artifact_kind_weights: { evidence: 0.9, lesson: 0.2, file: 0.5, summary: 0.5 },
24
- quality_threshold: 0.7,
25
- max_artifacts: 15,
26
- max_tokens: 6000,
27
- },
28
- plan: {
29
- decision_type: 'plan',
30
- artifact_kind_weights: { evidence: 0.4, lesson: 0.9, file: 0.7, summary: 0.6 },
31
- quality_threshold: 0.5,
32
- max_artifacts: 25,
33
- max_tokens: 10000,
34
- },
35
- review: {
36
- decision_type: 'review',
37
- artifact_kind_weights: { evidence: 0.6, lesson: 0.5, file: 0.8, summary: 0.5 },
38
- quality_threshold: 0.55,
39
- max_artifacts: 20,
40
- max_tokens: 8000,
41
- },
42
- debug: {
43
- decision_type: 'debug',
44
- artifact_kind_weights: { evidence: 0.9, lesson: 0.6, file: 0.7, summary: 0.4 },
45
- quality_threshold: 0.6,
46
- max_artifacts: 20,
47
- max_tokens: 8000,
48
- },
49
- migration: {
50
- decision_type: 'migration',
51
- artifact_kind_weights: { evidence: 0.7, lesson: 0.7, file: 0.9, summary: 0.5 },
52
- quality_threshold: 0.65,
53
- max_artifacts: 30,
54
- max_tokens: 12000,
55
- },
56
- };
57
-
58
- export function getProfile(decisionType: ContextDecisionType): ContextProfile {
59
- return DEFAULT_PROFILES[decisionType];
60
- }
1
+ import type { ContextArtifact } from './context-pack-builder';
2
+
3
+ export type ContextDecisionType = 'execute' | 'verify' | 'plan' | 'review' | 'debug' | 'migration';
4
+
5
+ export interface ContextProfile {
6
+ decision_type: ContextDecisionType;
7
+ artifact_kind_weights: Record<ContextArtifact['kind'], number>;
8
+ quality_threshold: number;
9
+ max_artifacts: number;
10
+ max_tokens: number;
11
+ }
12
+
13
+ export const DEFAULT_PROFILES: Record<ContextDecisionType, ContextProfile> = {
14
+ execute: {
15
+ decision_type: 'execute',
16
+ artifact_kind_weights: { evidence: 0.8, lesson: 0.3, file: 0.6, summary: 0.4 },
17
+ quality_threshold: 0.6,
18
+ max_artifacts: 20,
19
+ max_tokens: 8000,
20
+ },
21
+ verify: {
22
+ decision_type: 'verify',
23
+ artifact_kind_weights: { evidence: 0.9, lesson: 0.2, file: 0.5, summary: 0.5 },
24
+ quality_threshold: 0.7,
25
+ max_artifacts: 15,
26
+ max_tokens: 6000,
27
+ },
28
+ plan: {
29
+ decision_type: 'plan',
30
+ artifact_kind_weights: { evidence: 0.4, lesson: 0.9, file: 0.7, summary: 0.6 },
31
+ quality_threshold: 0.5,
32
+ max_artifacts: 25,
33
+ max_tokens: 10000,
34
+ },
35
+ review: {
36
+ decision_type: 'review',
37
+ artifact_kind_weights: { evidence: 0.6, lesson: 0.5, file: 0.8, summary: 0.5 },
38
+ quality_threshold: 0.55,
39
+ max_artifacts: 20,
40
+ max_tokens: 8000,
41
+ },
42
+ debug: {
43
+ decision_type: 'debug',
44
+ artifact_kind_weights: { evidence: 0.9, lesson: 0.6, file: 0.7, summary: 0.4 },
45
+ quality_threshold: 0.6,
46
+ max_artifacts: 20,
47
+ max_tokens: 8000,
48
+ },
49
+ migration: {
50
+ decision_type: 'migration',
51
+ artifact_kind_weights: { evidence: 0.7, lesson: 0.7, file: 0.9, summary: 0.5 },
52
+ quality_threshold: 0.65,
53
+ max_artifacts: 30,
54
+ max_tokens: 12000,
55
+ },
56
+ };
57
+
58
+ export function getProfile(decisionType: ContextDecisionType): ContextProfile {
59
+ return DEFAULT_PROFILES[decisionType];
60
+ }
@@ -1,3 +1,3 @@
1
- export * from './context-pack-builder';
2
- export * from './context-pack-store';
3
- export * from './context-profiles';
1
+ export * from './context-pack-builder';
2
+ export * from './context-pack-store';
3
+ export * from './context-profiles';