@amistio/cli 0.1.14 → 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";
@@ -4385,6 +4389,8 @@ var appEvaluationStart = "AMISTIO_APP_EVALUATION_START";
4385
4389
  var appEvaluationEnd = "AMISTIO_APP_EVALUATION_END";
4386
4390
  var projectContextRefreshStart = "AMISTIO_PROJECT_CONTEXT_REFRESH_START";
4387
4391
  var projectContextRefreshEnd = "AMISTIO_PROJECT_CONTEXT_REFRESH_END";
4392
+ var validProjectContextEntityTypes = /* @__PURE__ */ new Set(["project", "system", "component", "domain", "tool", "decision", "feature", "risk", "team", "workflow", "unknown"]);
4393
+ var validProjectContextRelationTypes = /* @__PURE__ */ new Set(["uses", "depends_on", "decides", "supersedes", "touches", "blocks", "implements", "mentions"]);
4388
4394
  function createWorkExecutionPrompt(workItem, context) {
4389
4395
  if (workItem.workKind === "brainGeneration") {
4390
4396
  return createBrainGenerationPrompt(workItem);
@@ -4491,6 +4497,7 @@ function createProjectContextRefreshPrompt(workItem, context) {
4491
4497
  "- Prefer summaries, repository-relative paths, short citations, tags, and freshness status over raw source excerpts.",
4492
4498
  "- Mark stale or missing areas explicitly instead of guessing.",
4493
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.",
4494
4501
  "",
4495
4502
  "## Data Safety",
4496
4503
  "",
@@ -4947,7 +4954,7 @@ function parseAppEvaluationScanResult(output) {
4947
4954
  const parsed = JSON.parse(stripJsonFence(payload));
4948
4955
  return appEvaluationScanResultSchema.parse(parsed);
4949
4956
  }
4950
- function parseProjectContextRefreshResult(output) {
4957
+ function parseProjectContextRefreshResult(output, options = {}) {
4951
4958
  const start = output.indexOf(projectContextRefreshStart);
4952
4959
  const end = output.indexOf(projectContextRefreshEnd, start + projectContextRefreshStart.length);
4953
4960
  if (start === -1 || end === -1 || end <= start) {
@@ -4955,7 +4962,8 @@ function parseProjectContextRefreshResult(output) {
4955
4962
  }
4956
4963
  const payload = output.slice(start + projectContextRefreshStart.length, end).trim();
4957
4964
  const parsed = JSON.parse(stripJsonFence(payload));
4958
- return projectContextRefreshResultSchema.parse(parsed);
4965
+ const normalized = normalizeProjectContextRefreshPaths(normalizeProjectContextRefreshEnums(parsed), options);
4966
+ return projectContextRefreshResultSchema.parse(normalized);
4959
4967
  }
4960
4968
  function projectContextRefreshSubmissionFailureSummary(result) {
4961
4969
  if (result.refresh.status !== "failed" && result.workItem.status !== "failed") {
@@ -5019,6 +5027,122 @@ function createBrainGenerationPrompt(workItem) {
5019
5027
  "Do not put Markdown fences around the markers. Do not claim implementation is complete."
5020
5028
  ].join("\n");
5021
5029
  }
5030
+ function normalizeProjectContextRefreshEnums(value) {
5031
+ if (!isObjectRecord(value)) {
5032
+ return value;
5033
+ }
5034
+ const normalized = { ...value };
5035
+ if (Array.isArray(normalized.entities)) {
5036
+ normalized.entities = normalized.entities.map((entity) => {
5037
+ if (!isObjectRecord(entity)) {
5038
+ return entity;
5039
+ }
5040
+ const normalizedEntity = { ...entity };
5041
+ normalizedEntity.entityType = normalizeProjectContextEntityType(entity.entityType);
5042
+ return normalizedEntity;
5043
+ });
5044
+ }
5045
+ if (Array.isArray(normalized.relations)) {
5046
+ normalized.relations = normalized.relations.map((relation) => {
5047
+ if (!isObjectRecord(relation)) {
5048
+ return relation;
5049
+ }
5050
+ const normalizedRelation = { ...relation };
5051
+ normalizedRelation.relationType = normalizeProjectContextRelationType(relation.relationType);
5052
+ return normalizedRelation;
5053
+ });
5054
+ }
5055
+ return normalized;
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
+ }
5129
+ function normalizeProjectContextEntityType(value) {
5130
+ if (typeof value !== "string") {
5131
+ return "unknown";
5132
+ }
5133
+ const normalized = value.trim().toLowerCase();
5134
+ return validProjectContextEntityTypes.has(normalized) ? normalized : "unknown";
5135
+ }
5136
+ function normalizeProjectContextRelationType(value) {
5137
+ if (typeof value !== "string") {
5138
+ return "mentions";
5139
+ }
5140
+ const normalized = value.trim().toLowerCase();
5141
+ return validProjectContextRelationTypes.has(normalized) ? normalized : "mentions";
5142
+ }
5143
+ function isObjectRecord(value) {
5144
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5145
+ }
5022
5146
  function artifactFormatPreferenceInstructions(preference) {
5023
5147
  if (preference === "html") {
5024
5148
  return "The user chose HTML. Generate .html artifacts under docs/html/<folder>/ and set contentFormat to html.";
@@ -5194,7 +5318,7 @@ function roundNumber(value, digits) {
5194
5318
  import { execFile as execFile4 } from "node:child_process";
5195
5319
  import { createHash as createHash6 } from "node:crypto";
5196
5320
  import { readdir as readdir4, readFile as readFile8, stat as stat4 } from "node:fs/promises";
5197
- import path10 from "node:path";
5321
+ import path11 from "node:path";
5198
5322
  import { promisify as promisify4 } from "node:util";
5199
5323
  var execFileAsync4 = promisify4(execFile4);
5200
5324
  var defaultMaxFileKb = 256;
@@ -5213,12 +5337,12 @@ var documentFolderByType = {
5213
5337
  workflow: "docs/workflows"
5214
5338
  };
5215
5339
  async function inspectLocalRepository(rootDir, defaultBranch) {
5216
- const requestedRoot = path10.resolve(rootDir);
5340
+ const requestedRoot = path11.resolve(rootDir);
5217
5341
  const root = await runGit2(["-C", requestedRoot, "rev-parse", "--show-toplevel"]).catch(() => requestedRoot);
5218
5342
  const detectedBranch = await runGit2(["-C", root, "symbolic-ref", "--quiet", "--short", "HEAD"]).catch(() => defaultBranch);
5219
5343
  const originUrl = await runGit2(["-C", root, "remote", "get-url", "origin"]).catch(() => void 0);
5220
5344
  const parsedCloneUrl = originUrl ? parseOptionalOriginCloneUrl(originUrl) : void 0;
5221
- const repoName = (parsedCloneUrl?.repoName ?? path10.basename(root)) || "repository";
5345
+ const repoName = (parsedCloneUrl?.repoName ?? path11.basename(root)) || "repository";
5222
5346
  const fingerprintSeed = parsedCloneUrl ? `origin:${parsedCloneUrl.normalizedKey}` : `repo:${repoName}:${detectedBranch || defaultBranch}`;
5223
5347
  return {
5224
5348
  rootDir: root,
@@ -5230,7 +5354,7 @@ async function inspectLocalRepository(rootDir, defaultBranch) {
5230
5354
  };
5231
5355
  }
5232
5356
  async function scanLegacyDocuments(options) {
5233
- const rootDir = path10.resolve(options.rootDir);
5357
+ const rootDir = path11.resolve(options.rootDir);
5234
5358
  const maxBytes = (options.maxFileKb ?? defaultMaxFileKb) * 1024;
5235
5359
  const skipped = [];
5236
5360
  const candidates = [];
@@ -5250,7 +5374,7 @@ async function scanLegacyDocuments(options) {
5250
5374
  skipped.push({ repoPath, reason: "excluded" });
5251
5375
  continue;
5252
5376
  }
5253
- const fullPath = path10.join(rootDir, ...repoPath.split("/"));
5377
+ const fullPath = path11.join(rootDir, ...repoPath.split("/"));
5254
5378
  const fileStat = await stat4(fullPath).catch(() => void 0);
5255
5379
  if (!fileStat?.isFile()) {
5256
5380
  skipped.push({ repoPath, reason: "unreadable" });
@@ -5352,8 +5476,8 @@ async function listRepositoryPaths(rootDir) {
5352
5476
  async function walkRepository(rootDir, directory, files) {
5353
5477
  const entries = await readdir4(directory, { withFileTypes: true }).catch(() => []);
5354
5478
  for (const entry of entries) {
5355
- const fullPath = path10.join(directory, entry.name);
5356
- const repoPath = normalizeRepoPath4(path10.relative(rootDir, fullPath));
5479
+ const fullPath = path11.join(directory, entry.name);
5480
+ const repoPath = normalizeRepoPath4(path11.relative(rootDir, fullPath));
5357
5481
  if (entry.isDirectory()) {
5358
5482
  if (!excludedDirectoryNames.has(entry.name)) {
5359
5483
  await walkRepository(rootDir, fullPath, files);
@@ -5419,9 +5543,9 @@ function uniqueDestinationPath(basePath, sourcePath, usedPaths) {
5419
5543
  usedPaths.add(basePath);
5420
5544
  return basePath;
5421
5545
  }
5422
- const extension = path10.posix.extname(basePath) || ".md";
5423
- const directory = path10.posix.dirname(basePath);
5424
- 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);
5425
5549
  const uniquePath = `${directory}/${basename}-${hashText(sourcePath, 8)}${extension}`;
5426
5550
  usedPaths.add(uniquePath);
5427
5551
  return uniquePath;
@@ -5440,7 +5564,7 @@ function inferTitle2(content, repoPath) {
5440
5564
  if (heading) return heading;
5441
5565
  const htmlHeading = body.match(/<h1\b[^>]*>([\s\S]*?)<\/h1>/i)?.[1]?.replace(/<[^>]+>/g, "").trim();
5442
5566
  if (htmlHeading) return htmlHeading;
5443
- 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();
5444
5568
  return titleCase(basename || "Imported Document");
5445
5569
  }
5446
5570
  function stripFrontmatter(content) {
@@ -5474,7 +5598,7 @@ async function runGit2(args) {
5474
5598
 
5475
5599
  // src/runner-actions.ts
5476
5600
  import { spawn as spawn4 } from "node:child_process";
5477
- import path11 from "node:path";
5601
+ import path12 from "node:path";
5478
5602
  function buildBackgroundRunnerArgs(options) {
5479
5603
  const args = [
5480
5604
  "run",
@@ -5484,7 +5608,7 @@ function buildBackgroundRunnerArgs(options) {
5484
5608
  "--runner-id",
5485
5609
  options.runnerId,
5486
5610
  "--root",
5487
- path11.resolve(options.root),
5611
+ path12.resolve(options.root),
5488
5612
  "--session",
5489
5613
  options.session,
5490
5614
  "--interval-seconds",
@@ -5602,7 +5726,7 @@ function truncateProcessOutput(value) {
5602
5726
  // src/git-worktree.ts
5603
5727
  import { execFile as execFile5 } from "node:child_process";
5604
5728
  import { mkdir as mkdir9, stat as stat5 } from "node:fs/promises";
5605
- import path12 from "node:path";
5729
+ import path13 from "node:path";
5606
5730
  import { promisify as promisify5 } from "node:util";
5607
5731
  var execFileAsync5 = promisify5(execFile5);
5608
5732
  function needsGitWorktreeIsolation(workItem) {
@@ -5631,7 +5755,7 @@ async function prepareGitWorktreeIsolation(rootDir, workItem) {
5631
5755
  await assertExistingWorktree(worktreePath, identity.branch);
5632
5756
  return { ...identity, baseRevision, worktreePath };
5633
5757
  }
5634
- await mkdir9(path12.dirname(worktreePath), { recursive: true });
5758
+ await mkdir9(path13.dirname(worktreePath), { recursive: true });
5635
5759
  const branchExists = await gitCommandSucceeds(repoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${identity.branch}`]);
5636
5760
  const worktreeArgs = branchExists ? ["worktree", "add", worktreePath, identity.branch] : ["worktree", "add", "-b", identity.branch, worktreePath, baseRevision];
5637
5761
  await gitOutput(repoRoot, worktreeArgs).catch((error) => {
@@ -5640,9 +5764,9 @@ async function prepareGitWorktreeIsolation(rootDir, workItem) {
5640
5764
  return { ...identity, baseRevision, worktreePath };
5641
5765
  }
5642
5766
  function localWorktreePath(repoRoot, worktreeKey) {
5643
- const repoName = path12.basename(repoRoot);
5767
+ const repoName = path13.basename(repoRoot);
5644
5768
  const worktreeSlug = worktreeKey.split("/").filter(Boolean).pop() ?? "work";
5645
- return path12.join(path12.dirname(repoRoot), `${repoName}.worktrees`, worktreeSlug);
5769
+ return path13.join(path13.dirname(repoRoot), `${repoName}.worktrees`, worktreeSlug);
5646
5770
  }
5647
5771
  async function assertExistingWorktree(worktreePath, branch) {
5648
5772
  await gitOutput(worktreePath, ["rev-parse", "--is-inside-work-tree"]);
@@ -5689,7 +5813,7 @@ function errorMessage2(error) {
5689
5813
 
5690
5814
  // src/implementation-handoff.ts
5691
5815
  import { execFile as execFile6 } from "node:child_process";
5692
- import path13 from "node:path";
5816
+ import path14 from "node:path";
5693
5817
  import { promisify as promisify6 } from "node:util";
5694
5818
  var execFileAsync6 = promisify6(execFile6);
5695
5819
  async function completeImplementationHandoff(input) {
@@ -5775,7 +5899,7 @@ async function cleanupWorktree(run, input) {
5775
5899
  return { status: "failed", message: "Cleanup skipped because the worktree is not clean after PR handoff." };
5776
5900
  }
5777
5901
  try {
5778
- 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]);
5779
5903
  return { status: "completed" };
5780
5904
  } catch (error) {
5781
5905
  return { status: "failed", message: `Cleanup failed: ${safeErrorMessage(error)}` };
@@ -6264,7 +6388,7 @@ program.command("run").description("Claim and run approved Amistio work locally"
6264
6388
  projectId: context.metadata.amistioProjectId,
6265
6389
  repositoryLinkId: context.metadata.repositoryLinkId,
6266
6390
  runnerId,
6267
- rootDir: path14.resolve(options.root),
6391
+ rootDir: path15.resolve(options.root),
6268
6392
  apiUrl: options.apiUrl,
6269
6393
  args: buildBackgroundRunnerArgs(resolvedOptions)
6270
6394
  });
@@ -6436,7 +6560,7 @@ runnerService.command("install").description("Install a user-level startup servi
6436
6560
  projectId: context.metadata.amistioProjectId,
6437
6561
  repositoryLinkId: context.metadata.repositoryLinkId,
6438
6562
  runnerId,
6439
- rootDir: path14.resolve(options.root),
6563
+ rootDir: path15.resolve(options.root),
6440
6564
  apiUrl: options.apiUrl,
6441
6565
  args,
6442
6566
  platform
@@ -6908,6 +7032,7 @@ async function runNextWorkItem({
6908
7032
  return await finalizeProjectContextRefreshWork({
6909
7033
  apiClient,
6910
7034
  durationMs: Date.now() - startedAt,
7035
+ executionRoot,
6911
7036
  projectId,
6912
7037
  repositoryLinkId,
6913
7038
  runnerId,
@@ -7762,6 +7887,7 @@ ${toolResult.stderr}`);
7762
7887
  async function finalizeProjectContextRefreshWork({
7763
7888
  apiClient,
7764
7889
  durationMs,
7890
+ executionRoot,
7765
7891
  projectId,
7766
7892
  repositoryLinkId,
7767
7893
  runnerId,
@@ -7776,7 +7902,7 @@ async function finalizeProjectContextRefreshWork({
7776
7902
  if (toolResult.exitCode === 0) {
7777
7903
  try {
7778
7904
  refreshResult = parseProjectContextRefreshResult(`${toolResult.stdout}
7779
- ${toolResult.stderr}`);
7905
+ ${toolResult.stderr}`, { repositoryRoot: executionRoot });
7780
7906
  } catch (error) {
7781
7907
  refreshError = errorMessage3(error);
7782
7908
  }
@@ -8153,7 +8279,7 @@ function parseReasoningEffort(value) {
8153
8279
  throw new Error(`Expected reasoning effort auto, low, medium, high, or xhigh; received ${value}.`);
8154
8280
  }
8155
8281
  function inferRepoName(root) {
8156
- return path14.basename(path14.resolve(root)) || "repository";
8282
+ return path15.basename(path15.resolve(root)) || "repository";
8157
8283
  }
8158
8284
  function createRepoFingerprint(accountId, projectId, repositoryLinkId) {
8159
8285
  return createHash7("sha256").update(`${accountId}:${projectId}:${repositoryLinkId}`).digest("hex");