@amistio/cli 0.1.15 → 0.1.16

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.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { createHash as createHash7, randomUUID } from "node:crypto";
5
5
  import { writeFile as writeFile9 } from "node:fs/promises";
6
6
  import os7 from "node:os";
7
- import path14 from "node:path";
7
+ import path15 from "node:path";
8
8
  import { Command } from "commander";
9
9
 
10
10
  // ../shared/src/schemas.ts
@@ -773,6 +773,9 @@ var projectContextRepoPathSchema = z.string().trim().min(1).max(300).refine((val
773
773
  }
774
774
  return !value.split(/[\\/]+/).includes("..");
775
775
  }, "Path must be repository-relative without traversal");
776
+ var projectContextCitationSchema = assistantCitationSchema.extend({
777
+ repoPath: projectContextRepoPathSchema.optional()
778
+ });
776
779
  var projectContextCoverageSchema = z.object({
777
780
  status: projectContextFreshnessSchema.default("missing"),
778
781
  sliceCount: z.number().int().nonnegative().default(0),
@@ -789,7 +792,7 @@ var projectContextSliceSchema = z.object({
789
792
  repoPaths: z.array(projectContextRepoPathSchema).max(80).default([]),
790
793
  ownerHints: z.array(z.string().trim().min(1).max(160)).max(20).default([]),
791
794
  tags: z.array(z.string().trim().min(1).max(80)).max(30).default([]),
792
- citations: z.array(assistantCitationSchema).default([]),
795
+ citations: z.array(projectContextCitationSchema).default([]),
793
796
  dependsOn: z.array(z.string().trim().min(1).max(160)).max(50).default([]),
794
797
  freshness: projectContextFreshnessSchema.default("fresh"),
795
798
  confidence: z.number().min(0).max(1).default(0.6),
@@ -803,7 +806,7 @@ var projectContextEntitySchema = z.object({
803
806
  summary: z.string().trim().min(1).max(1200).optional(),
804
807
  aliases: z.array(z.string().trim().min(1).max(200)).default([]),
805
808
  sliceIds: z.array(z.string().trim().min(1).max(160)).default([]),
806
- citations: z.array(assistantCitationSchema).default([]),
809
+ citations: z.array(projectContextCitationSchema).default([]),
807
810
  confidence: z.number().min(0).max(1).default(0.6)
808
811
  });
809
812
  var projectContextRelationSchema = z.object({
@@ -812,7 +815,7 @@ var projectContextRelationSchema = z.object({
812
815
  fromId: z.string().trim().min(1).max(200),
813
816
  toId: z.string().trim().min(1).max(200),
814
817
  summary: z.string().trim().min(1).max(1200),
815
- citations: z.array(assistantCitationSchema).default([]),
818
+ citations: z.array(projectContextCitationSchema).default([]),
816
819
  confidence: z.number().min(0).max(1).default(0.6)
817
820
  });
818
821
  var projectSystemDiagramStatusSchema = z.enum(["draft", "proposed", "approved", "stale", "archived"]);
@@ -829,7 +832,7 @@ var projectSystemDiagramNodeSchema = z.object({
829
832
  lane: z.string().trim().min(1).max(120).optional(),
830
833
  sliceIds: z.array(z.string().trim().min(1).max(160)).default([]),
831
834
  entityIds: z.array(z.string().trim().min(1).max(200)).default([]),
832
- citations: z.array(assistantCitationSchema).min(1),
835
+ citations: z.array(projectContextCitationSchema).min(1),
833
836
  confidence: z.number().min(0).max(1).default(0.6),
834
837
  freshness: projectContextFreshnessSchema.default("fresh")
835
838
  });
@@ -840,7 +843,7 @@ var projectSystemDiagramEdgeSchema = z.object({
840
843
  relationType: knowledgeRelationTypeSchema.default("mentions"),
841
844
  label: z.string().trim().min(1).max(120).optional(),
842
845
  summary: z.string().trim().min(1).max(1200),
843
- citations: z.array(assistantCitationSchema).min(1),
846
+ citations: z.array(projectContextCitationSchema).min(1),
844
847
  confidence: z.number().min(0).max(1).default(0.6),
845
848
  freshness: projectContextFreshnessSchema.default("fresh")
846
849
  });
@@ -849,7 +852,7 @@ var projectSystemDiagramGroupSchema = z.object({
849
852
  label: z.string().trim().min(1).max(120),
850
853
  kind: projectSystemDiagramGroupKindSchema.default("group"),
851
854
  summary: z.string().trim().min(1).max(1200).optional(),
852
- citations: z.array(assistantCitationSchema).default([])
855
+ citations: z.array(projectContextCitationSchema).default([])
853
856
  });
854
857
  var projectSystemDiagramViewSchema = z.object({
855
858
  viewId: z.string().trim().min(1).max(160),
@@ -871,7 +874,7 @@ var projectSystemDiagramGraphManifestSchema = z.object({
871
874
  edges: z.array(projectSystemDiagramEdgeSchema).default([]),
872
875
  groups: z.array(projectSystemDiagramGroupSchema).default([]),
873
876
  views: z.array(projectSystemDiagramViewSchema).min(1),
874
- citations: z.array(assistantCitationSchema).default([]),
877
+ citations: z.array(projectContextCitationSchema).default([]),
875
878
  unknowns: z.array(z.string().trim().min(1).max(300)).default([]),
876
879
  warnings: z.array(z.string().trim().min(1).max(600)).default([])
877
880
  });
@@ -957,7 +960,7 @@ var projectContextPackSchema = z.object({
957
960
  slices: z.array(projectContextSliceSchema).default([]),
958
961
  entities: z.array(projectContextEntitySchema).default([]),
959
962
  relations: z.array(projectContextRelationSchema).default([]),
960
- citations: z.array(assistantCitationSchema).default([]),
963
+ citations: z.array(projectContextCitationSchema).default([]),
961
964
  freshnessWarnings: z.array(z.string().trim().min(1).max(600)).default([]),
962
965
  tokenEstimate: z.number().int().nonnegative().default(0),
963
966
  generatedAt: isoDateTimeSchema
@@ -2382,8 +2385,8 @@ var toolSessionMutationSchema = z3.object({
2382
2385
  });
2383
2386
  function resolveApiUrl(apiUrl, urlPath) {
2384
2387
  const base = apiUrl.endsWith("/") ? apiUrl.slice(0, -1) : apiUrl;
2385
- const path15 = urlPath.startsWith("/") ? urlPath : `/${urlPath}`;
2386
- return new URL(`${base}${path15}`);
2388
+ const path16 = urlPath.startsWith("/") ? urlPath : `/${urlPath}`;
2389
+ return new URL(`${base}${path16}`);
2387
2390
  }
2388
2391
 
2389
2392
  // src/orchestrator.ts
@@ -4371,6 +4374,7 @@ function defaultSessionStorePath() {
4371
4374
  }
4372
4375
 
4373
4376
  // src/work-runner.ts
4377
+ import path10 from "node:path";
4374
4378
  var generationResultStart = "AMISTIO_BRAIN_GENERATION_RESULT_START";
4375
4379
  var generationResultEnd = "AMISTIO_BRAIN_GENERATION_RESULT_END";
4376
4380
  var assistantAnswerStart = "AMISTIO_ASSISTANT_ANSWER_START";
@@ -4493,6 +4497,7 @@ function createProjectContextRefreshPrompt(workItem, context) {
4493
4497
  "- Prefer summaries, repository-relative paths, short citations, tags, and freshness status over raw source excerpts.",
4494
4498
  "- Mark stale or missing areas explicitly instead of guessing.",
4495
4499
  "- Keep repoPaths repository-relative; never include /absolute paths or ../ traversal.",
4500
+ "- If local inspection prints a path inside this checkout, convert it to the repository-relative path before returning JSON.",
4496
4501
  "",
4497
4502
  "## Data Safety",
4498
4503
  "",
@@ -4949,7 +4954,7 @@ function parseAppEvaluationScanResult(output) {
4949
4954
  const parsed = JSON.parse(stripJsonFence(payload));
4950
4955
  return appEvaluationScanResultSchema.parse(parsed);
4951
4956
  }
4952
- function parseProjectContextRefreshResult(output) {
4957
+ function parseProjectContextRefreshResult(output, options = {}) {
4953
4958
  const start = output.indexOf(projectContextRefreshStart);
4954
4959
  const end = output.indexOf(projectContextRefreshEnd, start + projectContextRefreshStart.length);
4955
4960
  if (start === -1 || end === -1 || end <= start) {
@@ -4957,7 +4962,8 @@ function parseProjectContextRefreshResult(output) {
4957
4962
  }
4958
4963
  const payload = output.slice(start + projectContextRefreshStart.length, end).trim();
4959
4964
  const parsed = JSON.parse(stripJsonFence(payload));
4960
- return projectContextRefreshResultSchema.parse(normalizeProjectContextRefreshEnums(parsed));
4965
+ const normalized = normalizeProjectContextRefreshPaths(normalizeProjectContextRefreshEnums(parsed), options);
4966
+ return projectContextRefreshResultSchema.parse(normalized);
4961
4967
  }
4962
4968
  function projectContextRefreshSubmissionFailureSummary(result) {
4963
4969
  if (result.refresh.status !== "failed" && result.workItem.status !== "failed") {
@@ -5048,6 +5054,78 @@ function normalizeProjectContextRefreshEnums(value) {
5048
5054
  }
5049
5055
  return normalized;
5050
5056
  }
5057
+ function normalizeProjectContextRefreshPaths(value, options) {
5058
+ if (!isObjectRecord(value)) {
5059
+ return value;
5060
+ }
5061
+ const normalized = { ...value };
5062
+ if (Array.isArray(normalized.slices)) {
5063
+ normalized.slices = normalized.slices.map((slice) => normalizeProjectContextSlicePaths(slice, options));
5064
+ }
5065
+ if (Array.isArray(normalized.entities)) {
5066
+ normalized.entities = normalized.entities.map((entity) => normalizeProjectContextCitationPaths(entity, options));
5067
+ }
5068
+ if (Array.isArray(normalized.relations)) {
5069
+ normalized.relations = normalized.relations.map((relation) => normalizeProjectContextCitationPaths(relation, options));
5070
+ }
5071
+ return normalized;
5072
+ }
5073
+ function normalizeProjectContextSlicePaths(value, options) {
5074
+ if (!isObjectRecord(value)) {
5075
+ return value;
5076
+ }
5077
+ const normalized = normalizeProjectContextCitationPaths(value, options);
5078
+ if (Array.isArray(normalized.repoPaths)) {
5079
+ normalized.repoPaths = normalized.repoPaths.map((repoPath) => typeof repoPath === "string" ? normalizeProjectContextRepoPath(repoPath, options) : repoPath);
5080
+ }
5081
+ return normalized;
5082
+ }
5083
+ function normalizeProjectContextCitationPaths(value, options) {
5084
+ if (!isObjectRecord(value)) {
5085
+ return value;
5086
+ }
5087
+ const normalized = { ...value };
5088
+ if (Array.isArray(normalized.citations)) {
5089
+ normalized.citations = normalized.citations.map((citation) => {
5090
+ if (!isObjectRecord(citation)) {
5091
+ return citation;
5092
+ }
5093
+ const normalizedCitation = { ...citation };
5094
+ if (typeof normalizedCitation.repoPath === "string") {
5095
+ normalizedCitation.repoPath = normalizeProjectContextRepoPath(normalizedCitation.repoPath, options);
5096
+ }
5097
+ return normalizedCitation;
5098
+ });
5099
+ }
5100
+ return normalized;
5101
+ }
5102
+ function normalizeProjectContextRepoPath(value, options) {
5103
+ const trimmed = value.trim();
5104
+ if (!trimmed || /^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(trimmed) || /^file:/i.test(trimmed) || /^[A-Za-z]:($|[^\\/])/.test(trimmed)) {
5105
+ throwUnsafeProjectContextPath();
5106
+ }
5107
+ const absolute = trimmed.startsWith("/") || trimmed.startsWith("\\\\") || path10.isAbsolute(trimmed) || path10.win32.isAbsolute(trimmed);
5108
+ if (!absolute) {
5109
+ return normalizeRelativeProjectContextPath(trimmed);
5110
+ }
5111
+ if (!options.repositoryRoot) {
5112
+ throwUnsafeProjectContextPath();
5113
+ }
5114
+ const useWindowsPathRules = path10.win32.isAbsolute(trimmed) && !trimmed.startsWith("/");
5115
+ const relativePath = useWindowsPathRules ? path10.win32.relative(path10.win32.resolve(options.repositoryRoot), path10.win32.resolve(trimmed)) : path10.relative(path10.resolve(options.repositoryRoot), path10.resolve(trimmed));
5116
+ return normalizeRelativeProjectContextPath(relativePath);
5117
+ }
5118
+ function normalizeRelativeProjectContextPath(value) {
5119
+ const normalized = value.trim().replace(/\\/g, "/");
5120
+ const segments = normalized.split("/").filter((segment) => segment.length > 0 && segment !== ".");
5121
+ if (!segments.length || normalized.startsWith("/") || normalized === "~" || normalized.startsWith("~/") || /^[A-Za-z]:/.test(normalized) || segments.includes("..")) {
5122
+ throwUnsafeProjectContextPath();
5123
+ }
5124
+ return segments.join("/");
5125
+ }
5126
+ function throwUnsafeProjectContextPath() {
5127
+ throw new Error("Project context refresh contains an unsafe repository path.");
5128
+ }
5051
5129
  function normalizeProjectContextEntityType(value) {
5052
5130
  if (typeof value !== "string") {
5053
5131
  return "unknown";
@@ -5240,7 +5318,7 @@ function roundNumber(value, digits) {
5240
5318
  import { execFile as execFile4 } from "node:child_process";
5241
5319
  import { createHash as createHash6 } from "node:crypto";
5242
5320
  import { readdir as readdir4, readFile as readFile8, stat as stat4 } from "node:fs/promises";
5243
- import path10 from "node:path";
5321
+ import path11 from "node:path";
5244
5322
  import { promisify as promisify4 } from "node:util";
5245
5323
  var execFileAsync4 = promisify4(execFile4);
5246
5324
  var defaultMaxFileKb = 256;
@@ -5259,12 +5337,12 @@ var documentFolderByType = {
5259
5337
  workflow: "docs/workflows"
5260
5338
  };
5261
5339
  async function inspectLocalRepository(rootDir, defaultBranch) {
5262
- const requestedRoot = path10.resolve(rootDir);
5340
+ const requestedRoot = path11.resolve(rootDir);
5263
5341
  const root = await runGit2(["-C", requestedRoot, "rev-parse", "--show-toplevel"]).catch(() => requestedRoot);
5264
5342
  const detectedBranch = await runGit2(["-C", root, "symbolic-ref", "--quiet", "--short", "HEAD"]).catch(() => defaultBranch);
5265
5343
  const originUrl = await runGit2(["-C", root, "remote", "get-url", "origin"]).catch(() => void 0);
5266
5344
  const parsedCloneUrl = originUrl ? parseOptionalOriginCloneUrl(originUrl) : void 0;
5267
- const repoName = (parsedCloneUrl?.repoName ?? path10.basename(root)) || "repository";
5345
+ const repoName = (parsedCloneUrl?.repoName ?? path11.basename(root)) || "repository";
5268
5346
  const fingerprintSeed = parsedCloneUrl ? `origin:${parsedCloneUrl.normalizedKey}` : `repo:${repoName}:${detectedBranch || defaultBranch}`;
5269
5347
  return {
5270
5348
  rootDir: root,
@@ -5276,7 +5354,7 @@ async function inspectLocalRepository(rootDir, defaultBranch) {
5276
5354
  };
5277
5355
  }
5278
5356
  async function scanLegacyDocuments(options) {
5279
- const rootDir = path10.resolve(options.rootDir);
5357
+ const rootDir = path11.resolve(options.rootDir);
5280
5358
  const maxBytes = (options.maxFileKb ?? defaultMaxFileKb) * 1024;
5281
5359
  const skipped = [];
5282
5360
  const candidates = [];
@@ -5296,7 +5374,7 @@ async function scanLegacyDocuments(options) {
5296
5374
  skipped.push({ repoPath, reason: "excluded" });
5297
5375
  continue;
5298
5376
  }
5299
- const fullPath = path10.join(rootDir, ...repoPath.split("/"));
5377
+ const fullPath = path11.join(rootDir, ...repoPath.split("/"));
5300
5378
  const fileStat = await stat4(fullPath).catch(() => void 0);
5301
5379
  if (!fileStat?.isFile()) {
5302
5380
  skipped.push({ repoPath, reason: "unreadable" });
@@ -5398,8 +5476,8 @@ async function listRepositoryPaths(rootDir) {
5398
5476
  async function walkRepository(rootDir, directory, files) {
5399
5477
  const entries = await readdir4(directory, { withFileTypes: true }).catch(() => []);
5400
5478
  for (const entry of entries) {
5401
- const fullPath = path10.join(directory, entry.name);
5402
- const repoPath = normalizeRepoPath4(path10.relative(rootDir, fullPath));
5479
+ const fullPath = path11.join(directory, entry.name);
5480
+ const repoPath = normalizeRepoPath4(path11.relative(rootDir, fullPath));
5403
5481
  if (entry.isDirectory()) {
5404
5482
  if (!excludedDirectoryNames.has(entry.name)) {
5405
5483
  await walkRepository(rootDir, fullPath, files);
@@ -5465,9 +5543,9 @@ function uniqueDestinationPath(basePath, sourcePath, usedPaths) {
5465
5543
  usedPaths.add(basePath);
5466
5544
  return basePath;
5467
5545
  }
5468
- const extension = path10.posix.extname(basePath) || ".md";
5469
- const directory = path10.posix.dirname(basePath);
5470
- const basename = path10.posix.basename(basePath, extension);
5546
+ const extension = path11.posix.extname(basePath) || ".md";
5547
+ const directory = path11.posix.dirname(basePath);
5548
+ const basename = path11.posix.basename(basePath, extension);
5471
5549
  const uniquePath = `${directory}/${basename}-${hashText(sourcePath, 8)}${extension}`;
5472
5550
  usedPaths.add(uniquePath);
5473
5551
  return uniquePath;
@@ -5486,7 +5564,7 @@ function inferTitle2(content, repoPath) {
5486
5564
  if (heading) return heading;
5487
5565
  const htmlHeading = body.match(/<h1\b[^>]*>([\s\S]*?)<\/h1>/i)?.[1]?.replace(/<[^>]+>/g, "").trim();
5488
5566
  if (htmlHeading) return htmlHeading;
5489
- const basename = path10.posix.basename(repoPath, path10.posix.extname(repoPath)).replace(/[-_]+/g, " ").trim();
5567
+ const basename = path11.posix.basename(repoPath, path11.posix.extname(repoPath)).replace(/[-_]+/g, " ").trim();
5490
5568
  return titleCase(basename || "Imported Document");
5491
5569
  }
5492
5570
  function stripFrontmatter(content) {
@@ -5520,7 +5598,7 @@ async function runGit2(args) {
5520
5598
 
5521
5599
  // src/runner-actions.ts
5522
5600
  import { spawn as spawn4 } from "node:child_process";
5523
- import path11 from "node:path";
5601
+ import path12 from "node:path";
5524
5602
  function buildBackgroundRunnerArgs(options) {
5525
5603
  const args = [
5526
5604
  "run",
@@ -5530,7 +5608,7 @@ function buildBackgroundRunnerArgs(options) {
5530
5608
  "--runner-id",
5531
5609
  options.runnerId,
5532
5610
  "--root",
5533
- path11.resolve(options.root),
5611
+ path12.resolve(options.root),
5534
5612
  "--session",
5535
5613
  options.session,
5536
5614
  "--interval-seconds",
@@ -5648,7 +5726,7 @@ function truncateProcessOutput(value) {
5648
5726
  // src/git-worktree.ts
5649
5727
  import { execFile as execFile5 } from "node:child_process";
5650
5728
  import { mkdir as mkdir9, stat as stat5 } from "node:fs/promises";
5651
- import path12 from "node:path";
5729
+ import path13 from "node:path";
5652
5730
  import { promisify as promisify5 } from "node:util";
5653
5731
  var execFileAsync5 = promisify5(execFile5);
5654
5732
  function needsGitWorktreeIsolation(workItem) {
@@ -5677,7 +5755,7 @@ async function prepareGitWorktreeIsolation(rootDir, workItem) {
5677
5755
  await assertExistingWorktree(worktreePath, identity.branch);
5678
5756
  return { ...identity, baseRevision, worktreePath };
5679
5757
  }
5680
- await mkdir9(path12.dirname(worktreePath), { recursive: true });
5758
+ await mkdir9(path13.dirname(worktreePath), { recursive: true });
5681
5759
  const branchExists = await gitCommandSucceeds(repoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${identity.branch}`]);
5682
5760
  const worktreeArgs = branchExists ? ["worktree", "add", worktreePath, identity.branch] : ["worktree", "add", "-b", identity.branch, worktreePath, baseRevision];
5683
5761
  await gitOutput(repoRoot, worktreeArgs).catch((error) => {
@@ -5686,9 +5764,9 @@ async function prepareGitWorktreeIsolation(rootDir, workItem) {
5686
5764
  return { ...identity, baseRevision, worktreePath };
5687
5765
  }
5688
5766
  function localWorktreePath(repoRoot, worktreeKey) {
5689
- const repoName = path12.basename(repoRoot);
5767
+ const repoName = path13.basename(repoRoot);
5690
5768
  const worktreeSlug = worktreeKey.split("/").filter(Boolean).pop() ?? "work";
5691
- return path12.join(path12.dirname(repoRoot), `${repoName}.worktrees`, worktreeSlug);
5769
+ return path13.join(path13.dirname(repoRoot), `${repoName}.worktrees`, worktreeSlug);
5692
5770
  }
5693
5771
  async function assertExistingWorktree(worktreePath, branch) {
5694
5772
  await gitOutput(worktreePath, ["rev-parse", "--is-inside-work-tree"]);
@@ -5735,7 +5813,7 @@ function errorMessage2(error) {
5735
5813
 
5736
5814
  // src/implementation-handoff.ts
5737
5815
  import { execFile as execFile6 } from "node:child_process";
5738
- import path13 from "node:path";
5816
+ import path14 from "node:path";
5739
5817
  import { promisify as promisify6 } from "node:util";
5740
5818
  var execFileAsync6 = promisify6(execFile6);
5741
5819
  async function completeImplementationHandoff(input) {
@@ -5821,7 +5899,7 @@ async function cleanupWorktree(run, input) {
5821
5899
  return { status: "failed", message: "Cleanup skipped because the worktree is not clean after PR handoff." };
5822
5900
  }
5823
5901
  try {
5824
- await gitOutput2(run, input.primaryRepoRoot || path13.dirname(input.worktreePath), ["worktree", "remove", input.worktreePath]);
5902
+ await gitOutput2(run, input.primaryRepoRoot || path14.dirname(input.worktreePath), ["worktree", "remove", input.worktreePath]);
5825
5903
  return { status: "completed" };
5826
5904
  } catch (error) {
5827
5905
  return { status: "failed", message: `Cleanup failed: ${safeErrorMessage(error)}` };
@@ -6310,7 +6388,7 @@ program.command("run").description("Claim and run approved Amistio work locally"
6310
6388
  projectId: context.metadata.amistioProjectId,
6311
6389
  repositoryLinkId: context.metadata.repositoryLinkId,
6312
6390
  runnerId,
6313
- rootDir: path14.resolve(options.root),
6391
+ rootDir: path15.resolve(options.root),
6314
6392
  apiUrl: options.apiUrl,
6315
6393
  args: buildBackgroundRunnerArgs(resolvedOptions)
6316
6394
  });
@@ -6482,7 +6560,7 @@ runnerService.command("install").description("Install a user-level startup servi
6482
6560
  projectId: context.metadata.amistioProjectId,
6483
6561
  repositoryLinkId: context.metadata.repositoryLinkId,
6484
6562
  runnerId,
6485
- rootDir: path14.resolve(options.root),
6563
+ rootDir: path15.resolve(options.root),
6486
6564
  apiUrl: options.apiUrl,
6487
6565
  args,
6488
6566
  platform
@@ -6954,6 +7032,7 @@ async function runNextWorkItem({
6954
7032
  return await finalizeProjectContextRefreshWork({
6955
7033
  apiClient,
6956
7034
  durationMs: Date.now() - startedAt,
7035
+ executionRoot,
6957
7036
  projectId,
6958
7037
  repositoryLinkId,
6959
7038
  runnerId,
@@ -7808,6 +7887,7 @@ ${toolResult.stderr}`);
7808
7887
  async function finalizeProjectContextRefreshWork({
7809
7888
  apiClient,
7810
7889
  durationMs,
7890
+ executionRoot,
7811
7891
  projectId,
7812
7892
  repositoryLinkId,
7813
7893
  runnerId,
@@ -7822,7 +7902,7 @@ async function finalizeProjectContextRefreshWork({
7822
7902
  if (toolResult.exitCode === 0) {
7823
7903
  try {
7824
7904
  refreshResult = parseProjectContextRefreshResult(`${toolResult.stdout}
7825
- ${toolResult.stderr}`);
7905
+ ${toolResult.stderr}`, { repositoryRoot: executionRoot });
7826
7906
  } catch (error) {
7827
7907
  refreshError = errorMessage3(error);
7828
7908
  }
@@ -8199,7 +8279,7 @@ function parseReasoningEffort(value) {
8199
8279
  throw new Error(`Expected reasoning effort auto, low, medium, high, or xhigh; received ${value}.`);
8200
8280
  }
8201
8281
  function inferRepoName(root) {
8202
- return path14.basename(path14.resolve(root)) || "repository";
8282
+ return path15.basename(path15.resolve(root)) || "repository";
8203
8283
  }
8204
8284
  function createRepoFingerprint(accountId, projectId, repositoryLinkId) {
8205
8285
  return createHash7("sha256").update(`${accountId}:${projectId}:${repositoryLinkId}`).digest("hex");