@orion-agents/orion-code 0.3.22 → 0.3.24

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 (41) hide show
  1. package/CHANGELOG.md +50 -3
  2. package/README.md +6 -5
  3. package/README.zh-CN.md +5 -4
  4. package/dist/harness/failure-attribution.d.ts +23 -0
  5. package/dist/harness/failure-attribution.js +103 -0
  6. package/dist/harness/verified-repair.d.ts +71 -0
  7. package/dist/harness/verified-repair.js +212 -0
  8. package/dist/product/paths.d.ts +20 -1
  9. package/dist/product/paths.js +293 -10
  10. package/dist/runtime/release-receipts.d.ts +3 -3
  11. package/dist/runtime/release-receipts.js +29 -0
  12. package/dist/services/config-dir.d.ts +3 -2
  13. package/dist/services/config-dir.js +6 -29
  14. package/dist/services/repo-intelligence/index.d.ts +11 -0
  15. package/dist/services/repo-intelligence/index.js +20 -0
  16. package/dist/services/repo-intelligence/recall.d.ts +44 -0
  17. package/dist/services/repo-intelligence/recall.js +115 -0
  18. package/dist/services/repo-intelligence/symbol-index.d.ts +52 -0
  19. package/dist/services/repo-intelligence/symbol-index.js +258 -0
  20. package/dist/services/session-storage.d.ts +18 -2
  21. package/dist/services/session-storage.js +196 -60
  22. package/dist/web/protocol.d.ts +8 -0
  23. package/dist/web/workbench-controller.js +46 -2
  24. package/dist/web-client/assets/{FilesPanel-CKeXPofZ.js → FilesPanel-BjEDjE7l.js} +1 -1
  25. package/dist/web-client/assets/{GitPanel-DollPxv0.js → GitPanel-DvgAZDRA.js} +1 -1
  26. package/dist/web-client/assets/{ReviewPanel-CNADacIn.js → ReviewPanel-BMPaYKDY.js} +1 -1
  27. package/dist/web-client/assets/{TerminalPanel-Cyns4uJt.js → TerminalPanel-Da1ZEhGF.js} +1 -1
  28. package/dist/web-client/assets/index-DZOlUgt6.js +20 -0
  29. package/dist/web-client/assets/{useAutoNotice-BLADeFFj.js → useAutoNotice-Ylj5bfSH.js} +1 -1
  30. package/dist/web-client/index.html +1 -1
  31. package/npm-shrinkwrap.json +2 -2
  32. package/package.json +1 -1
  33. package/dist/services/auto-fix/autoFixConfig.d.ts +0 -30
  34. package/dist/services/auto-fix/autoFixConfig.js +0 -78
  35. package/dist/services/auto-fix/autoFixHook.d.ts +0 -27
  36. package/dist/services/auto-fix/autoFixHook.js +0 -99
  37. package/dist/services/auto-fix/autoFixRunner.d.ts +0 -60
  38. package/dist/services/auto-fix/autoFixRunner.js +0 -207
  39. package/dist/services/auto-fix/index.d.ts +0 -7
  40. package/dist/services/auto-fix/index.js +0 -17
  41. package/dist/web-client/assets/index-BhGhORAX.js +0 -20
@@ -7,7 +7,7 @@
7
7
  * of concatenating ".orion-code" directly.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.PROJECT_CONFIG_CANDIDATES = void 0;
10
+ exports.PROJECT_CONFIG_CANDIDATES = exports.ProjectStorageIdentityUnavailableError = void 0;
11
11
  exports.getConfigHome = getConfigHome;
12
12
  exports.getConfigDir = getConfigDir;
13
13
  exports.getGlobalConfigPath = getGlobalConfigPath;
@@ -20,7 +20,10 @@ exports.getMcpConfigPath = getMcpConfigPath;
20
20
  exports.getProjectsDir = getProjectsDir;
21
21
  exports.getGlobalEnvPath = getGlobalEnvPath;
22
22
  exports.encodeProjectPath = encodeProjectPath;
23
+ exports.resolveProjectStorageIdentityAsync = resolveProjectStorageIdentityAsync;
24
+ exports.assertProjectStorageIdentity = assertProjectStorageIdentity;
23
25
  exports.resolveProjectStoragePath = resolveProjectStoragePath;
26
+ exports.resolveProjectStoragePathAsync = resolveProjectStoragePathAsync;
24
27
  exports.getCanonicalProjectKey = getCanonicalProjectKey;
25
28
  exports.getProjectDir = getProjectDir;
26
29
  exports.getProjectMetadataPath = getProjectMetadataPath;
@@ -46,6 +49,7 @@ exports.getMemoryPath = getMemoryPath;
46
49
  exports.getExistingMemoryPaths = getExistingMemoryPaths;
47
50
  exports.ensureConfigDir = ensureConfigDir;
48
51
  exports.ensureProjectDir = ensureProjectDir;
52
+ exports.ensureResolvedProjectDir = ensureResolvedProjectDir;
49
53
  exports.getProjectInstructionsPath = getProjectInstructionsPath;
50
54
  exports.getProjectSkillsDir = getProjectSkillsDir;
51
55
  const os_1 = require("os");
@@ -108,30 +112,296 @@ function encodeProjectPath(projectPath) {
108
112
  const suffix = (0, crypto_1.createHash)('sha256').update(normalized).digest('hex').slice(0, 8);
109
113
  return `${encoded || 'root'}-${suffix}`;
110
114
  }
111
- /** Resolve a project path for storage identity. */
115
+ const projectStorageIdentities = new Map();
116
+ const MAX_PROJECT_STORAGE_IDENTITIES = 256;
117
+ const pendingProjectStorageIdentities = new Map();
118
+ /** Interactive Hosts must not persist an unverified Git project identity. */
119
+ class ProjectStorageIdentityUnavailableError extends Error {
120
+ constructor(message = 'Git 项目身份暂时无法确认,请检查本地 Git 后重试;未创建会话。') {
121
+ super(message);
122
+ this.code = 'project_storage_identity_unavailable';
123
+ this.name = 'ProjectStorageIdentityUnavailableError';
124
+ }
125
+ }
126
+ exports.ProjectStorageIdentityUnavailableError = ProjectStorageIdentityUnavailableError;
127
+ function gitIdentityFileFingerprint(path) {
128
+ try {
129
+ const file = (0, fs_1.statSync)(path);
130
+ return [file.dev, file.ino, file.mode, file.size, file.mtimeMs, file.ctimeMs].join(':');
131
+ }
132
+ catch {
133
+ return 'missing';
134
+ }
135
+ }
136
+ /** Git's small pointer files, not repository contents, identify external gitdirs. */
137
+ function readGitIdentityPointer(path) {
138
+ try {
139
+ const file = (0, fs_1.statSync)(path);
140
+ if (!file.isFile() || file.size > 4096)
141
+ return undefined;
142
+ return (0, fs_1.readFileSync)(path, 'utf-8').trim();
143
+ }
144
+ catch {
145
+ return undefined;
146
+ }
147
+ }
148
+ /**
149
+ * Track the nearest Git boundary without spawning Git. New nested repos,
150
+ * removed/replaced .git markers, root-affecting Git configuration and symlink
151
+ * retargeting invalidate identities; ordinary Git object/ref writes do not.
152
+ */
153
+ function projectStorageFingerprint(canonicalPath) {
154
+ let directory = canonicalPath;
155
+ while (true) {
156
+ try {
157
+ const markerPath = (0, path_1.join)(directory, '.git');
158
+ const marker = (0, fs_1.statSync)(markerPath);
159
+ const markerIdentity = marker.isDirectory()
160
+ ? [marker.dev, marker.ino, marker.mode]
161
+ : [marker.dev, marker.ino, marker.mode, marker.size, marker.mtimeMs, marker.ctimeMs];
162
+ const pointer = marker.isDirectory() ? undefined : readGitIdentityPointer(markerPath);
163
+ const gitDirectory = marker.isDirectory()
164
+ ? markerPath
165
+ : pointer?.startsWith('gitdir: ')
166
+ ? (0, path_1.resolve)(directory, pointer.slice('gitdir: '.length))
167
+ : undefined;
168
+ const configIdentity = [];
169
+ if (gitDirectory) {
170
+ configIdentity.push(gitDirectory, gitIdentityFileFingerprint((0, path_1.join)(gitDirectory, 'config')), gitIdentityFileFingerprint((0, path_1.join)(gitDirectory, 'config.worktree')));
171
+ // Linked worktrees keep shared configuration outside their own gitdir.
172
+ // Track both the pointer and shared config, including enabling/disabling
173
+ // extensions.worktreeConfig, without running another Git subprocess.
174
+ const commonPointerPath = (0, path_1.join)(gitDirectory, 'commondir');
175
+ const commonPointer = readGitIdentityPointer(commonPointerPath);
176
+ configIdentity.push(gitIdentityFileFingerprint(commonPointerPath));
177
+ if (commonPointer) {
178
+ const commonDirectory = (0, path_1.resolve)(gitDirectory, commonPointer);
179
+ configIdentity.push(commonDirectory, gitIdentityFileFingerprint((0, path_1.join)(commonDirectory, 'config')));
180
+ }
181
+ }
182
+ return {
183
+ fingerprint: `${directory}:${markerIdentity.join(':')}|${configIdentity.join('|')}`,
184
+ hasGitBoundary: true,
185
+ };
186
+ }
187
+ catch {
188
+ // No readable Git marker at this level; check its parent.
189
+ }
190
+ const parent = (0, path_1.dirname)(directory);
191
+ if (parent === directory)
192
+ return { fingerprint: 'folder', hasGitBoundary: false };
193
+ directory = parent;
194
+ }
195
+ }
196
+ function storageOperationFingerprintUnchecked(projectPath) {
197
+ const absolute = (0, path_1.resolve)(projectPath);
198
+ const exists = (0, fs_1.existsSync)(absolute);
199
+ const canonical = exists ? (0, fs_1.realpathSync)(absolute) : absolute;
200
+ const directory = exists ? (0, fs_1.statSync)(canonical) : undefined;
201
+ const gitEnvironment = Object.entries(process.env)
202
+ .filter(([key]) => key.startsWith('GIT_'))
203
+ .sort(([left], [right]) => left.localeCompare(right));
204
+ const external = ['GIT_DIR', 'GIT_COMMON_DIR', 'GIT_WORK_TREE'].map(key => {
205
+ const value = process.env[key];
206
+ if (!value)
207
+ return '';
208
+ const path = (0, path_1.resolve)(canonical, value);
209
+ const target = (0, fs_1.existsSync)(path) ? (0, fs_1.realpathSync)(path) : path;
210
+ const common = readGitIdentityPointer((0, path_1.join)(target, 'commondir'));
211
+ return [
212
+ target,
213
+ gitIdentityFileFingerprint((0, path_1.join)(target, 'config')),
214
+ gitIdentityFileFingerprint((0, path_1.join)(target, 'config.worktree')),
215
+ gitIdentityFileFingerprint((0, path_1.join)(target, 'commondir')),
216
+ common ? gitIdentityFileFingerprint((0, path_1.join)((0, path_1.resolve)(target, common), 'config')) : '',
217
+ ].join('|');
218
+ });
219
+ return JSON.stringify([
220
+ canonical,
221
+ directory ? [directory.dev, directory.ino, directory.mode] : 'missing',
222
+ projectStorageFingerprint(canonical).fingerprint,
223
+ gitEnvironment,
224
+ external,
225
+ ]);
226
+ }
227
+ function storageOperationFingerprint(projectPath) {
228
+ try {
229
+ return storageOperationFingerprintUnchecked(projectPath);
230
+ }
231
+ catch {
232
+ throw new ProjectStorageIdentityUnavailableError('Project storage path changed or became unavailable. Retry.');
233
+ }
234
+ }
235
+ async function resolveProjectStorageIdentityAsync(projectPath) {
236
+ const requestedPath = (0, path_1.resolve)(projectPath);
237
+ const before = storageOperationFingerprint(requestedPath);
238
+ const canonicalPath = await resolveProjectStoragePathAsync(requestedPath);
239
+ if (storageOperationFingerprint(requestedPath) !== before) {
240
+ throw new ProjectStorageIdentityUnavailableError('Project storage identity changed. Retry.');
241
+ }
242
+ return Object.freeze({
243
+ requestedPath,
244
+ canonicalPath,
245
+ projectKey: encodeProjectPath(canonicalPath),
246
+ fingerprint: JSON.stringify([before, storageOperationFingerprint(canonicalPath)]),
247
+ });
248
+ }
249
+ /** Cheap lock-admission validation: filesystem/environment only, no Git spawn. */
250
+ function assertProjectStorageIdentity(identity) {
251
+ if (JSON.stringify([
252
+ storageOperationFingerprint(identity.requestedPath),
253
+ storageOperationFingerprint(identity.canonicalPath),
254
+ ]) !== identity.fingerprint) {
255
+ throw new ProjectStorageIdentityUnavailableError('Project storage identity changed while waiting. Retry.');
256
+ }
257
+ }
258
+ /** Resolve a project path for storage identity with bounded, invalidatable reuse. */
112
259
  function resolveProjectStoragePath(projectPath) {
113
260
  const absolute = (0, path_1.resolve)(projectPath);
114
261
  if ((0, fs_1.existsSync)(absolute)) {
262
+ let canonical = absolute;
263
+ try {
264
+ canonical = (0, fs_1.realpathSync)(absolute);
265
+ }
266
+ catch {
267
+ return absolute;
268
+ }
269
+ // Explicit external Git configuration can change identity independently of
270
+ // the local .git boundary. Preserve its live Git semantics rather than cache it.
271
+ const cacheable = !process.env.GIT_DIR && !process.env.GIT_WORK_TREE && !process.env.GIT_COMMON_DIR;
272
+ const boundary = projectStorageFingerprint(canonical);
273
+ const fingerprint = [
274
+ boundary.fingerprint,
275
+ process.env.GIT_CEILING_DIRECTORIES ?? '',
276
+ process.env.GIT_DISCOVERY_ACROSS_FILESYSTEM ?? '',
277
+ ].join('|');
278
+ const cached = cacheable ? projectStorageIdentities.get(canonical) : undefined;
279
+ if (cached?.fingerprint === fingerprint && (0, fs_1.existsSync)(cached.path)) {
280
+ projectStorageIdentities.delete(canonical);
281
+ projectStorageIdentities.set(canonical, cached);
282
+ return cached.path;
283
+ }
284
+ let resolvedPath = canonical;
285
+ let gitResolved = false;
115
286
  try {
116
287
  const root = (0, child_process_1.execFileSync)('git', ['-C', absolute, 'rev-parse', '--show-toplevel'], {
117
288
  encoding: 'utf-8',
118
289
  stdio: ['ignore', 'pipe', 'ignore'],
290
+ timeout: 250,
291
+ killSignal: 'SIGKILL',
292
+ maxBuffer: 4096,
293
+ env: process.env,
119
294
  }).trim();
120
- if (root)
121
- return (0, fs_1.realpathSync)(root);
295
+ if (root) {
296
+ resolvedPath = (0, fs_1.realpathSync)(root);
297
+ gitResolved = true;
298
+ }
122
299
  }
123
300
  catch {
124
- // Not a git worktree.
301
+ // Unavailable Git falls back to the existing canonical-folder identity.
125
302
  }
126
- try {
127
- return (0, fs_1.realpathSync)(absolute);
128
- }
129
- catch {
130
- return absolute;
303
+ // A failure under a real Git boundary may be transient. Do not pin its
304
+ // fallback folder identity; a later successful probe must recover the root.
305
+ if (cacheable && (gitResolved || !boundary.hasGitBoundary)) {
306
+ projectStorageIdentities.set(canonical, { fingerprint, path: resolvedPath });
307
+ if (projectStorageIdentities.size > MAX_PROJECT_STORAGE_IDENTITIES) {
308
+ const oldest = projectStorageIdentities.keys().next().value;
309
+ if (oldest)
310
+ projectStorageIdentities.delete(oldest);
311
+ }
131
312
  }
313
+ return resolvedPath;
132
314
  }
133
315
  return absolute;
134
316
  }
317
+ /** Pre-resolve interactive Host identities without blocking its event loop. */
318
+ async function resolveProjectStoragePathAsync(projectPath) {
319
+ const absolute = (0, path_1.resolve)(projectPath);
320
+ if (!(0, fs_1.existsSync)(absolute))
321
+ return absolute;
322
+ let canonical;
323
+ try {
324
+ canonical = (0, fs_1.realpathSync)(absolute);
325
+ }
326
+ catch {
327
+ throw new ProjectStorageIdentityUnavailableError('Project storage path became unavailable. Retry.');
328
+ }
329
+ const cacheable = !process.env.GIT_DIR && !process.env.GIT_WORK_TREE && !process.env.GIT_COMMON_DIR;
330
+ const boundary = projectStorageFingerprint(canonical);
331
+ const operationFingerprint = storageOperationFingerprint(absolute);
332
+ const fingerprint = [
333
+ boundary.fingerprint,
334
+ process.env.GIT_CEILING_DIRECTORIES ?? '',
335
+ process.env.GIT_DISCOVERY_ACROSS_FILESYSTEM ?? '',
336
+ ].join('|');
337
+ const cached = cacheable ? projectStorageIdentities.get(canonical) : undefined;
338
+ if (cached?.fingerprint === fingerprint && (0, fs_1.existsSync)(cached.path))
339
+ return cached.path;
340
+ const pendingKey = `${canonical}|${fingerprint}`;
341
+ const pending = cacheable ? pendingProjectStorageIdentities.get(pendingKey) : undefined;
342
+ if (pending)
343
+ return pending;
344
+ const probe = new Promise((resolveIdentity, rejectIdentity) => {
345
+ (0, child_process_1.execFile)('git', ['-C', absolute, 'rev-parse', '--show-toplevel'], {
346
+ encoding: 'utf-8',
347
+ timeout: 250,
348
+ killSignal: 'SIGKILL',
349
+ maxBuffer: 4096,
350
+ env: process.env,
351
+ }, (error, stdout) => {
352
+ let currentFingerprint;
353
+ try {
354
+ currentFingerprint = storageOperationFingerprint(absolute);
355
+ }
356
+ catch (failure) {
357
+ rejectIdentity(failure);
358
+ return;
359
+ }
360
+ if (currentFingerprint !== operationFingerprint) {
361
+ rejectIdentity(new ProjectStorageIdentityUnavailableError('Project storage identity changed during Git discovery. Retry.'));
362
+ return;
363
+ }
364
+ if (boundary.hasGitBoundary && (error || !stdout.trim())) {
365
+ rejectIdentity(new ProjectStorageIdentityUnavailableError());
366
+ return;
367
+ }
368
+ let result = canonical;
369
+ let gitResolved = false;
370
+ if (!error && stdout.trim()) {
371
+ try {
372
+ result = (0, fs_1.realpathSync)(stdout.trim());
373
+ gitResolved = true;
374
+ }
375
+ catch {
376
+ if (boundary.hasGitBoundary) {
377
+ rejectIdentity(new ProjectStorageIdentityUnavailableError());
378
+ return;
379
+ }
380
+ }
381
+ }
382
+ // Never seed a completed probe under a boundary changed while it ran.
383
+ if (cacheable && (gitResolved || !boundary.hasGitBoundary)) {
384
+ projectStorageIdentities.set(canonical, { fingerprint, path: result });
385
+ if (projectStorageIdentities.size > MAX_PROJECT_STORAGE_IDENTITIES) {
386
+ const oldest = projectStorageIdentities.keys().next().value;
387
+ if (oldest)
388
+ projectStorageIdentities.delete(oldest);
389
+ }
390
+ }
391
+ resolveIdentity(result);
392
+ });
393
+ });
394
+ if (cacheable)
395
+ pendingProjectStorageIdentities.set(pendingKey, probe);
396
+ try {
397
+ return await probe;
398
+ }
399
+ finally {
400
+ if (pendingProjectStorageIdentities.get(pendingKey) === probe) {
401
+ pendingProjectStorageIdentities.delete(pendingKey);
402
+ }
403
+ }
404
+ }
135
405
  function getCanonicalProjectKey(projectPath) {
136
406
  return encodeProjectPath(resolveProjectStoragePath(projectPath));
137
407
  }
@@ -246,6 +516,19 @@ function ensureProjectDir(projectPath) {
246
516
  const { updateProjectMetadata } = require('../services/config-dir');
247
517
  updateProjectMetadata(projectPath);
248
518
  }
519
+ /** Use the already-verified identity; do not re-probe Git under explicit env. */
520
+ function ensureResolvedProjectDir(identity) {
521
+ assertProjectStorageIdentity(identity);
522
+ ensureConfigDir();
523
+ const projectDir = (0, path_1.join)(getProjectsDir(), identity.projectKey);
524
+ const sessionsDir = (0, path_1.join)(projectDir, 'sessions');
525
+ (0, fs_1.mkdirSync)(sessionsDir, { recursive: true, mode: 0o700 });
526
+ sweepStorageDirectory(projectDir);
527
+ sweepStorageDirectory(sessionsDir);
528
+ const { updateProjectMetadata } = require('../services/config-dir');
529
+ updateProjectMetadata(identity.canonicalPath, new Date(), identity);
530
+ return sessionsDir;
531
+ }
249
532
  // ── Project filesystem scanning ─────────────────────────────────────────────
250
533
  /** Ordered project config candidate files (relative to project root). */
251
534
  exports.PROJECT_CONFIG_CANDIDATES = [
@@ -7,7 +7,7 @@ export declare const WEB_E2E_LEGACY_SCENARIOS_V1: readonly ["E2E-P0-01", "E2E-P0
7
7
  export declare const WEB_E2E_WEB31_SCENARIOS_V1: readonly ["WEB31-P0-01", "WEB31-P0-02", "WEB31-P0-03", "WEB31-P0-04", "WEB31-P0-05", "WEB31-P0-06", "WEB31-P0-07", "WEB31-P0-08", "WEB31-P0-09", "WEB31-P0-10", "WEB31-P0-11", "WEB31-P0-12"];
8
8
  export declare const WEB_E2E_WEB32_SCENARIOS_V1: readonly ["WEB32-P0-01", "WEB32-P0-02", "WEB32-P0-03", "WEB32-P0-04", "WEB32-P0-05", "WEB32-P0-06", "WEB32-P0-07", "WEB32-P0-08", "WEB32-P0-09", "WEB32-P0-10", "WEB32-P0-11", "WEB32-P0-12"];
9
9
  export declare const WEB_E2E_WEB33_THEME_SCENARIOS_V1: readonly ["WEB33-P0-01", "WEB33-P0-02", "WEB33-P0-03", "WEB33-P0-04", "WEB33-P0-05", "WEB33-P0-06", "WEB33-P0-07", "WEB33-P0-08", "WEB33-P0-09", "WEB33-P0-10", "WEB33-P0-11", "WEB33-P0-12"];
10
- export declare const WEB_E2E_WEB33_SESSION_SCENARIOS_V1: readonly ["WEB33-P0-16", "WEB33-P0-17", "WEB33-P0-18", "WEB33-P0-19", "WEB33-P0-20", "WEB33-P0-21", "WEB33-P0-22", "WEB33-P0-23", "WEB33-P0-24"];
10
+ export declare const WEB_E2E_WEB33_SESSION_SCENARIOS_V1: readonly ["WEB33-P0-16", "WEB33-P0-17", "WEB33-P0-18", "WEB33-P0-19", "WEB33-P0-20", "WEB33-P0-21", "WEB33-P0-22", "WEB33-P0-23", "WEB33-P0-24", "WEB33-P0-44", "WEB33-P0-45", "WEB33-P0-46", "WEB33-P0-47", "WEB33-P0-48", "WEB33-P0-49", "WEB33-P0-50", "WEB33-P0-51", "WEB33-P0-52", "WEB33-P0-53", "WEB33-P0-54", "WEB33-P0-55", "WEB33-P0-56", "WEB33-P0-57"];
11
11
  /**
12
12
  * v0.3.20 — the WEB33 scenarios whose specs shipped between v0.3.13 and
13
13
  * v0.3.15 (rail, transcript navigator, brand, files editor, resource layout)
@@ -37,7 +37,7 @@ export declare const WEB_E2E_WEB38_SCENARIOS_V1: readonly ["WEB38-P0-01", "WEB38
37
37
  * actually verify; the per-stage unit suites are registered separately.
38
38
  */
39
39
  export declare const WEB_E2E_WEB317_SCENARIOS_V1: readonly string[];
40
- export declare const WEB_E2E_WEB33_SCENARIOS_V1: readonly ("WEB33-P0-01" | "WEB33-P0-02" | "WEB33-P0-03" | "WEB33-P0-04" | "WEB33-P0-05" | "WEB33-P0-06" | "WEB33-P0-07" | "WEB33-P0-08" | "WEB33-P0-09" | "WEB33-P0-10" | "WEB33-P0-11" | "WEB33-P0-12" | "WEB33-P0-16" | "WEB33-P0-17" | "WEB33-P0-18" | "WEB33-P0-19" | "WEB33-P0-20" | "WEB33-P0-21" | "WEB33-P0-22" | "WEB33-P0-23" | "WEB33-P0-24" | "WEB33-P0-13" | "WEB33-P0-14" | "WEB33-P0-15" | "WEB33-P0-25" | "WEB33-P0-26" | "WEB33-P0-27" | "WEB33-P0-28" | "WEB33-P0-29" | "WEB33-P0-30" | "WEB33-P0-31" | "WEB33-P0-32" | "WEB33-P0-34" | "WEB33-P0-41" | "WEB33-P0-42" | "WEB33-P0-43")[];
40
+ export declare const WEB_E2E_WEB33_SCENARIOS_V1: readonly ("WEB33-P0-01" | "WEB33-P0-02" | "WEB33-P0-03" | "WEB33-P0-04" | "WEB33-P0-05" | "WEB33-P0-06" | "WEB33-P0-07" | "WEB33-P0-08" | "WEB33-P0-09" | "WEB33-P0-10" | "WEB33-P0-11" | "WEB33-P0-12" | "WEB33-P0-16" | "WEB33-P0-17" | "WEB33-P0-18" | "WEB33-P0-19" | "WEB33-P0-20" | "WEB33-P0-21" | "WEB33-P0-22" | "WEB33-P0-23" | "WEB33-P0-24" | "WEB33-P0-44" | "WEB33-P0-45" | "WEB33-P0-46" | "WEB33-P0-47" | "WEB33-P0-48" | "WEB33-P0-49" | "WEB33-P0-50" | "WEB33-P0-51" | "WEB33-P0-52" | "WEB33-P0-53" | "WEB33-P0-54" | "WEB33-P0-55" | "WEB33-P0-56" | "WEB33-P0-57" | "WEB33-P0-13" | "WEB33-P0-14" | "WEB33-P0-15" | "WEB33-P0-25" | "WEB33-P0-26" | "WEB33-P0-27" | "WEB33-P0-28" | "WEB33-P0-29" | "WEB33-P0-30" | "WEB33-P0-31" | "WEB33-P0-32" | "WEB33-P0-34" | "WEB33-P0-41" | "WEB33-P0-42" | "WEB33-P0-43")[];
41
41
  /**
42
42
  * v0.3.19 — closing the v0.3.17 G317 assertion backlog.
43
43
  *
@@ -51,7 +51,7 @@ export declare const WEB_E2E_FULL_SCENARIOS_V1: readonly string[];
51
51
  export declare const WEB_E2E_SETTINGS_SCENARIOS_V1: readonly string[];
52
52
  export declare const WEB_E2E_WEB31_CRITICAL_SCENARIOS_V1: readonly ["WEB31-P0-01", "WEB31-P0-02", "WEB31-P0-08", "WEB31-P0-09", "WEB31-P0-10", "WEB31-P0-12"];
53
53
  export declare const WEB_E2E_WEB32_CRITICAL_SCENARIOS_V1: readonly ["WEB32-P0-01", "WEB32-P0-04", "WEB32-P0-05", "WEB32-P0-06", "WEB32-P0-09", "WEB32-P0-11", "WEB32-P0-12"];
54
- export declare const WEB_E2E_WEB33_CRITICAL_SCENARIOS_V1: readonly ["WEB33-P0-01", "WEB33-P0-03", "WEB33-P0-08", "WEB33-P0-10", "WEB33-P0-12", "WEB33-P0-16", "WEB33-P0-17", "WEB33-P0-18", "WEB33-P0-20", "WEB33-P0-21", "WEB33-P0-23", "WEB33-P0-24"];
54
+ export declare const WEB_E2E_WEB33_CRITICAL_SCENARIOS_V1: readonly ["WEB33-P0-01", "WEB33-P0-03", "WEB33-P0-08", "WEB33-P0-10", "WEB33-P0-12", "WEB33-P0-16", "WEB33-P0-17", "WEB33-P0-18", "WEB33-P0-20", "WEB33-P0-21", "WEB33-P0-23", "WEB33-P0-24", "WEB33-P0-44", "WEB33-P0-45", "WEB33-P0-46", "WEB33-P0-47", "WEB33-P0-48", "WEB33-P0-49", "WEB33-P0-50", "WEB33-P0-51", "WEB33-P0-52", "WEB33-P0-53", "WEB33-P0-54", "WEB33-P0-55", "WEB33-P0-56", "WEB33-P0-57"];
55
55
  export declare const WEB_E2E_CRITICAL_SCENARIOS_V1: readonly string[];
56
56
  export type ReleaseGateDecisionV1 = 'GO' | 'NO_GO';
57
57
  export interface TarballArtifactReceiptV1 {
@@ -96,6 +96,21 @@ exports.WEB_E2E_WEB33_SESSION_SCENARIOS_V1 = Object.freeze([
96
96
  'WEB33-P0-22',
97
97
  'WEB33-P0-23',
98
98
  'WEB33-P0-24',
99
+ // v0.3.24 — admission-window, creation and warm-switch regressions.
100
+ 'WEB33-P0-44',
101
+ 'WEB33-P0-45',
102
+ 'WEB33-P0-46',
103
+ 'WEB33-P0-47',
104
+ 'WEB33-P0-48',
105
+ 'WEB33-P0-49',
106
+ 'WEB33-P0-50',
107
+ 'WEB33-P0-51',
108
+ 'WEB33-P0-52',
109
+ 'WEB33-P0-53',
110
+ 'WEB33-P0-54',
111
+ 'WEB33-P0-55',
112
+ 'WEB33-P0-56',
113
+ 'WEB33-P0-57',
99
114
  ]);
100
115
  /**
101
116
  * v0.3.20 — the WEB33 scenarios whose specs shipped between v0.3.13 and
@@ -226,6 +241,20 @@ exports.WEB_E2E_WEB33_CRITICAL_SCENARIOS_V1 = Object.freeze([
226
241
  'WEB33-P0-21',
227
242
  'WEB33-P0-23',
228
243
  'WEB33-P0-24',
244
+ 'WEB33-P0-44',
245
+ 'WEB33-P0-45',
246
+ 'WEB33-P0-46',
247
+ 'WEB33-P0-47',
248
+ 'WEB33-P0-48',
249
+ 'WEB33-P0-49',
250
+ 'WEB33-P0-50',
251
+ 'WEB33-P0-51',
252
+ 'WEB33-P0-52',
253
+ 'WEB33-P0-53',
254
+ 'WEB33-P0-54',
255
+ 'WEB33-P0-55',
256
+ 'WEB33-P0-56',
257
+ 'WEB33-P0-57',
229
258
  ]);
230
259
  exports.WEB_E2E_CRITICAL_SCENARIOS_V1 = Object.freeze([
231
260
  ...exports.WEB_E2E_LEGACY_SCENARIOS_V1.slice(0, 4),
@@ -4,7 +4,7 @@
4
4
  * Re-exports from src/product/paths.ts for backward compatibility.
5
5
  * All new code should import directly from src/product/paths.ts.
6
6
  */
7
- export { getConfigHome, getConfigDir, getGlobalConfigPath, getSettingsPath, getUsageStatePath, getUsageLedgerPath, getUserMemoryPath, getHistoryPath, getMcpConfigPath, getProjectsDir, getGlobalEnvPath, encodeProjectPath, resolveProjectStoragePath, getCanonicalProjectKey, getProjectDir, getProjectMetadataPath, getProjectSessionsDir, getProjectSessionMetaPath, getProjectSessionMessagesPath, getProjectSessionHarnessPath, getProjectSessionCompactPath, getProjectSessionTracePath, getProjectSessionGoalPath, getProjectMemoryDir, getLegacyProjectMemoryDir, getProjectArtifactsDir, getProjectCheckpointsDir, getProjectIndexesDir, getCostDir, getDailyCostPath, getCacheDir, getMemoryPath, getExistingMemoryPaths, ensureConfigDir, ensureProjectDir, PROJECT_CONFIG_CANDIDATES, getProjectInstructionsPath, getProjectSkillsDir, type MemoryType, } from '../product/paths';
7
+ export { getConfigHome, getConfigDir, getGlobalConfigPath, getSettingsPath, getUsageStatePath, getUsageLedgerPath, getUserMemoryPath, getHistoryPath, getMcpConfigPath, getProjectsDir, getGlobalEnvPath, encodeProjectPath, resolveProjectStoragePath, resolveProjectStoragePathAsync, getCanonicalProjectKey, getProjectDir, getProjectMetadataPath, getProjectSessionsDir, getProjectSessionMetaPath, getProjectSessionMessagesPath, getProjectSessionHarnessPath, getProjectSessionCompactPath, getProjectSessionTracePath, getProjectSessionGoalPath, getProjectMemoryDir, getLegacyProjectMemoryDir, getProjectArtifactsDir, getProjectCheckpointsDir, getProjectIndexesDir, getCostDir, getDailyCostPath, getCacheDir, getMemoryPath, getExistingMemoryPaths, ensureConfigDir, ensureProjectDir, PROJECT_CONFIG_CANDIDATES, getProjectInstructionsPath, getProjectSkillsDir, type MemoryType, } from '../product/paths';
8
8
  export declare const PROJECT_METADATA_SCHEMA_VERSION = 1;
9
9
  export interface ProjectMetadata {
10
10
  schemaVersion: number;
@@ -13,6 +13,7 @@ export interface ProjectMetadata {
13
13
  createdAt: string;
14
14
  lastSeenAt: string;
15
15
  }
16
+ import { type ProjectStorageIdentity } from '../product/paths';
16
17
  export declare function readProjectMetadata(projectPath: string): ProjectMetadata | null;
17
- export declare function updateProjectMetadata(projectPath: string, now?: Date): ProjectMetadata;
18
+ export declare function updateProjectMetadata(projectPath: string, now?: Date, identity?: ProjectStorageIdentity): ProjectMetadata;
18
19
  //# sourceMappingURL=config-dir.d.ts.map
@@ -6,11 +6,10 @@
6
6
  * All new code should import directly from src/product/paths.ts.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.PROJECT_METADATA_SCHEMA_VERSION = exports.getProjectSkillsDir = exports.getProjectInstructionsPath = exports.PROJECT_CONFIG_CANDIDATES = exports.ensureProjectDir = exports.ensureConfigDir = exports.getExistingMemoryPaths = exports.getMemoryPath = exports.getCacheDir = exports.getDailyCostPath = exports.getCostDir = exports.getProjectIndexesDir = exports.getProjectCheckpointsDir = exports.getProjectArtifactsDir = exports.getLegacyProjectMemoryDir = exports.getProjectMemoryDir = exports.getProjectSessionGoalPath = exports.getProjectSessionTracePath = exports.getProjectSessionCompactPath = exports.getProjectSessionHarnessPath = exports.getProjectSessionMessagesPath = exports.getProjectSessionMetaPath = exports.getProjectSessionsDir = exports.getProjectMetadataPath = exports.getProjectDir = exports.getCanonicalProjectKey = exports.resolveProjectStoragePath = exports.encodeProjectPath = exports.getGlobalEnvPath = exports.getProjectsDir = exports.getMcpConfigPath = exports.getHistoryPath = exports.getUserMemoryPath = exports.getUsageLedgerPath = exports.getUsageStatePath = exports.getSettingsPath = exports.getGlobalConfigPath = exports.getConfigDir = exports.getConfigHome = void 0;
9
+ exports.PROJECT_METADATA_SCHEMA_VERSION = exports.getProjectSkillsDir = exports.getProjectInstructionsPath = exports.PROJECT_CONFIG_CANDIDATES = exports.ensureProjectDir = exports.ensureConfigDir = exports.getExistingMemoryPaths = exports.getMemoryPath = exports.getCacheDir = exports.getDailyCostPath = exports.getCostDir = exports.getProjectIndexesDir = exports.getProjectCheckpointsDir = exports.getProjectArtifactsDir = exports.getLegacyProjectMemoryDir = exports.getProjectMemoryDir = exports.getProjectSessionGoalPath = exports.getProjectSessionTracePath = exports.getProjectSessionCompactPath = exports.getProjectSessionHarnessPath = exports.getProjectSessionMessagesPath = exports.getProjectSessionMetaPath = exports.getProjectSessionsDir = exports.getProjectMetadataPath = exports.getProjectDir = exports.getCanonicalProjectKey = exports.resolveProjectStoragePathAsync = exports.resolveProjectStoragePath = exports.encodeProjectPath = exports.getGlobalEnvPath = exports.getProjectsDir = exports.getMcpConfigPath = exports.getHistoryPath = exports.getUserMemoryPath = exports.getUsageLedgerPath = exports.getUsageStatePath = exports.getSettingsPath = exports.getGlobalConfigPath = exports.getConfigDir = exports.getConfigHome = void 0;
10
10
  exports.readProjectMetadata = readProjectMetadata;
11
11
  exports.updateProjectMetadata = updateProjectMetadata;
12
12
  const fs_1 = require("fs");
13
- const child_process_1 = require("child_process");
14
13
  const path_1 = require("path");
15
14
  const atomic_write_1 = require("./atomic-write");
16
15
  const debug_log_1 = require("../utils/debug-log");
@@ -28,6 +27,7 @@ Object.defineProperty(exports, "getProjectsDir", { enumerable: true, get: functi
28
27
  Object.defineProperty(exports, "getGlobalEnvPath", { enumerable: true, get: function () { return paths_1.getGlobalEnvPath; } });
29
28
  Object.defineProperty(exports, "encodeProjectPath", { enumerable: true, get: function () { return paths_1.encodeProjectPath; } });
30
29
  Object.defineProperty(exports, "resolveProjectStoragePath", { enumerable: true, get: function () { return paths_1.resolveProjectStoragePath; } });
30
+ Object.defineProperty(exports, "resolveProjectStoragePathAsync", { enumerable: true, get: function () { return paths_1.resolveProjectStoragePathAsync; } });
31
31
  Object.defineProperty(exports, "getCanonicalProjectKey", { enumerable: true, get: function () { return paths_1.getCanonicalProjectKey; } });
32
32
  Object.defineProperty(exports, "getProjectDir", { enumerable: true, get: function () { return paths_1.getProjectDir; } });
33
33
  Object.defineProperty(exports, "getProjectMetadataPath", { enumerable: true, get: function () { return paths_1.getProjectMetadataPath; } });
@@ -75,33 +75,10 @@ function readProjectMetadata(projectPath) {
75
75
  return null;
76
76
  }
77
77
  }
78
- function updateProjectMetadata(projectPath, now = new Date()) {
79
- const resolvedPath = (() => {
80
- const absolute = (0, path_1.resolve)(projectPath);
81
- if ((0, fs_1.existsSync)(absolute)) {
82
- try {
83
- const root = (0, child_process_1.execFileSync)('git', ['-C', absolute, 'rev-parse', '--show-toplevel'], {
84
- encoding: 'utf-8',
85
- stdio: ['ignore', 'pipe', 'ignore'],
86
- }).trim();
87
- if (root)
88
- return (0, fs_1.realpathSync)(root);
89
- }
90
- catch (error) {
91
- // Not a git worktree, or git is unavailable: fall back to the path.
92
- (0, debug_log_1.debugError)('config-dir.resolveGitRoot', error, absolute);
93
- }
94
- try {
95
- return (0, fs_1.realpathSync)(absolute);
96
- }
97
- catch (error) {
98
- // Broken symlink or a race with a deletion; the literal path is
99
- // still a usable project key.
100
- (0, debug_log_1.debugError)('config-dir.realpath', error, absolute);
101
- }
102
- }
103
- return absolute;
104
- })();
78
+ function updateProjectMetadata(projectPath, now = new Date(), identity) {
79
+ if (identity)
80
+ (0, paths_2.assertProjectStorageIdentity)(identity);
81
+ const resolvedPath = identity?.canonicalPath ?? (0, paths_2.resolveProjectStoragePath)(projectPath);
105
82
  const projectKey = (0, paths_2.encodeProjectPath)(resolvedPath);
106
83
  const projectDir = (0, path_1.join)((0, paths_2.getProjectsDir)(), projectKey);
107
84
  if (!(0, fs_1.existsSync)(projectDir)) {
@@ -0,0 +1,11 @@
1
+ /**
2
+ * v0.3.23 T23-B — Repo Intelligence facade: symbol index, incremental
3
+ * maintenance, task-relevant recall with sourced reasons, and budget-aware
4
+ * selection. Feature-flagged at the integration seam (ORION_CODE_REPO_INTELLIGENCE)
5
+ * so the prompt assembly can adopt it incrementally.
6
+ */
7
+ export { RepoSymbolIndexV1, type RepoSymbolEntryV1, type RepoFileRecordV1, type RepoIndexStatsV1, type RepoSymbolIndexOptionsV1, } from './symbol-index';
8
+ export { recallFiles, selectWithinBudget, type RecallCandidateV1, type RecallOptionsV1, } from './recall';
9
+ /** The runtime integration flag: 'on' enables harness wiring; default off. */
10
+ export declare function isRepoIntelligenceEnabled(env?: Readonly<Record<string, string | undefined>>): boolean;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.selectWithinBudget = exports.recallFiles = exports.RepoSymbolIndexV1 = void 0;
4
+ exports.isRepoIntelligenceEnabled = isRepoIntelligenceEnabled;
5
+ /**
6
+ * v0.3.23 T23-B — Repo Intelligence facade: symbol index, incremental
7
+ * maintenance, task-relevant recall with sourced reasons, and budget-aware
8
+ * selection. Feature-flagged at the integration seam (ORION_CODE_REPO_INTELLIGENCE)
9
+ * so the prompt assembly can adopt it incrementally.
10
+ */
11
+ var symbol_index_1 = require("./symbol-index");
12
+ Object.defineProperty(exports, "RepoSymbolIndexV1", { enumerable: true, get: function () { return symbol_index_1.RepoSymbolIndexV1; } });
13
+ var recall_1 = require("./recall");
14
+ Object.defineProperty(exports, "recallFiles", { enumerable: true, get: function () { return recall_1.recallFiles; } });
15
+ Object.defineProperty(exports, "selectWithinBudget", { enumerable: true, get: function () { return recall_1.selectWithinBudget; } });
16
+ /** The runtime integration flag: 'on' enables harness wiring; default off. */
17
+ function isRepoIntelligenceEnabled(env = process.env) {
18
+ return env.ORION_CODE_REPO_INTELLIGENCE === 'on';
19
+ }
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,44 @@
1
+ /**
2
+ * v0.3.23 T23-B3 — task-relevant context recall over the symbol index.
3
+ *
4
+ * Given the user intent, the currently active files, and (optionally) recently
5
+ * changed files, produce a bounded, ranked candidate list. Every candidate
6
+ * carries explicit `reasons[]` — the recall result is evidence, not a black
7
+ * box — and the caller can log it into the Harness ledger.
8
+ *
9
+ * Scoring (heuristic, evaluated by the Recall@K suite — not claimed as
10
+ * semantic understanding):
11
+ * +50 direct mention: the intent names the path or its basename
12
+ * +30 symbol match: a quoted/known symbol from the intent is defined here
13
+ * +20 import adjacency: an active file imports this file (or vice versa)
14
+ * +15 test pairing: tests/<x>.test.* <-> src/<x>.*
15
+ * +10 recent change: the file appears in the changed set
16
+ */
17
+ import type { RepoSymbolIndexV1 } from './symbol-index';
18
+ export interface RecallCandidateV1 {
19
+ readonly path: string;
20
+ readonly score: number;
21
+ readonly reasons: readonly string[];
22
+ }
23
+ export interface RecallOptionsV1 {
24
+ /** Free-text user intent (task description). */
25
+ readonly intent: string;
26
+ /** Files the user or the current turn is already working with. */
27
+ readonly activeFiles: readonly string[];
28
+ /** Files changed in the current change-set (git diff), if available. */
29
+ readonly changedFiles?: readonly string[];
30
+ /** Maximum number of candidates returned. */
31
+ readonly limit?: number;
32
+ }
33
+ export declare function recallFiles(index: RepoSymbolIndexV1, options: RecallOptionsV1): readonly RecallCandidateV1[];
34
+ /**
35
+ * Budget-aware selection: rank candidates, deduplicate by directory concentration
36
+ * (at most `maxPerDirectory` per immediate directory), and always keep explicitly
37
+ * active files (the user touched them — they are never dropped for budget).
38
+ */
39
+ export declare function selectWithinBudget(candidates: readonly RecallCandidateV1[], options: {
40
+ readonly activeFiles: readonly string[];
41
+ readonly maxFiles?: number;
42
+ readonly maxPerDirectory?: number;
43
+ }): readonly RecallCandidateV1[];
44
+ //# sourceMappingURL=recall.d.ts.map