@cursor/july 0.1.68 → 0.1.73

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 (226) hide show
  1. package/AGENTS.md +4 -5
  2. package/README.md +23 -11
  3. package/dist/bin/agent-serve.js +3 -2
  4. package/dist/channels/github/api.d.ts +2 -0
  5. package/dist/channels/github/api.d.ts.map +1 -1
  6. package/dist/channels/github/api.js +2 -1
  7. package/dist/channels/github/binding.d.ts +7 -0
  8. package/dist/channels/github/binding.d.ts.map +1 -1
  9. package/dist/channels/github/binding.js +4 -0
  10. package/dist/channels/github/checks.d.ts +99 -0
  11. package/dist/channels/github/checks.d.ts.map +1 -0
  12. package/dist/channels/github/checks.js +108 -0
  13. package/dist/channels/github/cursor-account.d.ts +4 -4
  14. package/dist/channels/github/cursor-account.d.ts.map +1 -1
  15. package/dist/channels/github/cursor-account.js +7 -5
  16. package/dist/channels/github/index.d.ts +1 -0
  17. package/dist/channels/github/index.d.ts.map +1 -1
  18. package/dist/channels/github/index.js +1 -0
  19. package/dist/channels/github/types.d.ts +8 -0
  20. package/dist/channels/github/types.d.ts.map +1 -1
  21. package/dist/channels/slack/manifest.d.ts +2 -2
  22. package/dist/channels/slack/manifest.d.ts.map +1 -1
  23. package/dist/channels/slack/manifest.js +13 -11
  24. package/dist/channels/slack/types.d.ts +2 -2
  25. package/dist/channels/slack/types.d.ts.map +1 -1
  26. package/dist/connections.d.ts +17 -5
  27. package/dist/connections.d.ts.map +1 -1
  28. package/dist/connections.js +17 -5
  29. package/dist/docs/404.html +2 -2
  30. package/dist/docs/ab.html +3 -3
  31. package/dist/docs/assets/{app.C5XUTCw9.js → app.CdbcFD8T.js} +1 -1
  32. package/dist/docs/assets/chunks/@localSearchIndexroot.DQad--_z.js +1 -0
  33. package/dist/docs/assets/chunks/{VPLocalSearchBox.CGDTAYHY.js → VPLocalSearchBox.D_NKImM7.js} +1 -1
  34. package/dist/docs/assets/chunks/{theme.lPixh250.js → theme.CMvz7cu9.js} +2 -2
  35. package/dist/docs/assets/{concepts.md.CqOsxbMU.js → concepts.md.BXAm6G-C.js} +1 -1
  36. package/dist/docs/assets/{guides_mcp-oauth.md.C7G7IykG.js → guides_mcp-oauth.md.CzEB6RaG.js} +1 -1
  37. package/dist/docs/assets/{reference_agent-config.md.DHkkvcEZ.js → reference_agent-config.md.BZnEKfEc.js} +3 -4
  38. package/dist/docs/assets/{reference_agent-config.md.DHkkvcEZ.lean.js → reference_agent-config.md.BZnEKfEc.lean.js} +1 -1
  39. package/dist/docs/assets/{reference_connections.md.Bwswbm6H.js → reference_connections.md.Cu3N-S3Q.js} +18 -11
  40. package/dist/docs/assets/{reference_connections.md.Bwswbm6H.lean.js → reference_connections.md.Cu3N-S3Q.lean.js} +1 -1
  41. package/dist/docs/assets/{reference_sessions.md.DBVFi2Sx.js → reference_sessions.md.B0DdlM-K.js} +1 -1
  42. package/dist/docs/assets/{reference_tools.md.Wmvb7Lob.js → reference_tools.md.DTg_kEsx.js} +1 -1
  43. package/dist/docs/assets/troubleshooting.md.DQ-hYuZT.js +1 -0
  44. package/dist/docs/building-with-agents.html +3 -3
  45. package/dist/docs/concepts.html +5 -5
  46. package/dist/docs/deployment.html +3 -3
  47. package/dist/docs/evals.html +3 -3
  48. package/dist/docs/example-agents/approval-buddy.html +3 -3
  49. package/dist/docs/example-agents/benny.html +3 -3
  50. package/dist/docs/example-agents/bugbot.html +3 -3
  51. package/dist/docs/example-agents/codebase-wiki.html +3 -3
  52. package/dist/docs/example-agents/codeowners-review.html +3 -3
  53. package/dist/docs/example-agents/concierge.html +3 -3
  54. package/dist/docs/example-agents/fsd.html +3 -3
  55. package/dist/docs/example-agents/index.html +3 -3
  56. package/dist/docs/example-agents/knowledge-base.html +3 -3
  57. package/dist/docs/example-agents/oncall.html +3 -3
  58. package/dist/docs/example-agents/security-reviewer.html +3 -3
  59. package/dist/docs/example-agents/slack-agent.html +3 -3
  60. package/dist/docs/example-agents/weather-agent.html +3 -3
  61. package/dist/docs/guides/agent-to-agent.html +3 -3
  62. package/dist/docs/guides/cloud-runtime.html +3 -3
  63. package/dist/docs/guides/convert-automation.html +3 -3
  64. package/dist/docs/guides/github.html +3 -3
  65. package/dist/docs/guides/human-in-the-loop.html +3 -3
  66. package/dist/docs/guides/mcp-oauth.html +5 -5
  67. package/dist/docs/guides/opentelemetry.html +3 -3
  68. package/dist/docs/guides/slack.html +3 -3
  69. package/dist/docs/guides/webhooks.html +3 -3
  70. package/dist/docs/hashmap.json +1 -1
  71. package/dist/docs/hillclimbing.html +3 -3
  72. package/dist/docs/index.html +3 -3
  73. package/dist/docs/quickstart.html +3 -3
  74. package/dist/docs/reference/agent-config.html +5 -6
  75. package/dist/docs/reference/artifacts.html +3 -3
  76. package/dist/docs/reference/channels.html +3 -3
  77. package/dist/docs/reference/cli.html +3 -3
  78. package/dist/docs/reference/connections.html +20 -13
  79. package/dist/docs/reference/hooks.html +3 -3
  80. package/dist/docs/reference/http-api.html +3 -3
  81. package/dist/docs/reference/instructions.html +3 -3
  82. package/dist/docs/reference/playground.html +3 -3
  83. package/dist/docs/reference/project-layout.html +3 -3
  84. package/dist/docs/reference/prompt.html +3 -3
  85. package/dist/docs/reference/schedules.html +3 -3
  86. package/dist/docs/reference/sessions.html +5 -5
  87. package/dist/docs/reference/skills.html +3 -3
  88. package/dist/docs/reference/subagents.html +3 -3
  89. package/dist/docs/reference/tools.html +5 -5
  90. package/dist/docs/scaffolding-agents.html +3 -3
  91. package/dist/docs/storage.html +3 -3
  92. package/dist/docs/templates/agentic-owners.html +3 -3
  93. package/dist/docs/templates/demo.html +3 -3
  94. package/dist/docs/templates/pr-autofixer.html +3 -3
  95. package/dist/docs/templates/security-reviewer.html +3 -3
  96. package/dist/docs/templates/triage.html +3 -3
  97. package/dist/docs/troubleshooting.html +5 -5
  98. package/dist/internal/advertise-tools.d.ts +11 -6
  99. package/dist/internal/advertise-tools.d.ts.map +1 -1
  100. package/dist/internal/advertise-tools.js +63 -30
  101. package/dist/internal/cli-deploy.d.ts.map +1 -1
  102. package/dist/internal/cli-deploy.js +2 -4
  103. package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -1
  104. package/dist/internal/convert-automation/convert-workflow.js +2 -10
  105. package/dist/internal/cursor/account-mcp.d.ts +29 -3
  106. package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
  107. package/dist/internal/cursor/account-mcp.js +147 -67
  108. package/dist/internal/cursor/backend-client.d.ts +11 -6
  109. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  110. package/dist/internal/cursor/backend-client.js +32 -10
  111. package/dist/internal/cursor-account-mcp-auth.d.ts +11 -0
  112. package/dist/internal/cursor-account-mcp-auth.d.ts.map +1 -1
  113. package/dist/internal/cursor-account-mcp-auth.js +69 -0
  114. package/dist/internal/deploy-client.d.ts +0 -7
  115. package/dist/internal/deploy-client.d.ts.map +1 -1
  116. package/dist/internal/deploy-client.js +2 -4
  117. package/dist/internal/deploy-manifest.d.ts +15 -24
  118. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  119. package/dist/internal/deploy-manifest.js +38 -27
  120. package/dist/internal/deployment-scm-event-stream.d.ts +4 -1
  121. package/dist/internal/deployment-scm-event-stream.d.ts.map +1 -1
  122. package/dist/internal/deployment-scm-event-stream.js +15 -1
  123. package/dist/internal/discovery.d.ts.map +1 -1
  124. package/dist/internal/discovery.js +42 -10
  125. package/dist/internal/init-project.d.ts.map +1 -1
  126. package/dist/internal/init-project.js +7 -106
  127. package/dist/internal/init-scaffold.d.ts +8 -0
  128. package/dist/internal/init-scaffold.d.ts.map +1 -0
  129. package/dist/internal/init-scaffold.js +168 -0
  130. package/dist/internal/inline-stdio-mcp.d.ts +2 -0
  131. package/dist/internal/inline-stdio-mcp.d.ts.map +1 -1
  132. package/dist/internal/inline-stdio-mcp.js +10 -8
  133. package/dist/internal/json-schema.d.ts +7 -0
  134. package/dist/internal/json-schema.d.ts.map +1 -1
  135. package/dist/internal/json-schema.js +18 -3
  136. package/dist/internal/mcp-endpoint.js +7 -7
  137. package/dist/internal/mcp-host.js +4 -2
  138. package/dist/internal/mcp-oauth.d.ts +22 -0
  139. package/dist/internal/mcp-oauth.d.ts.map +1 -1
  140. package/dist/internal/mcp-oauth.js +40 -1
  141. package/dist/internal/package-inline-stdio.d.ts.map +1 -1
  142. package/dist/internal/package-inline-stdio.js +5 -5
  143. package/dist/internal/review-comments.d.ts +97 -0
  144. package/dist/internal/review-comments.d.ts.map +1 -1
  145. package/dist/internal/review-comments.js +151 -0
  146. package/dist/internal/sanitize-mcp-tool-name.d.ts +20 -0
  147. package/dist/internal/sanitize-mcp-tool-name.d.ts.map +1 -0
  148. package/dist/internal/sanitize-mcp-tool-name.js +30 -0
  149. package/dist/internal/session-engine.d.ts.map +1 -1
  150. package/dist/internal/session-engine.js +4 -6
  151. package/dist/internal/shallow-clone.d.ts +94 -39
  152. package/dist/internal/shallow-clone.d.ts.map +1 -1
  153. package/dist/internal/shallow-clone.js +188 -68
  154. package/dist/internal/terminal-style.d.ts +18 -0
  155. package/dist/internal/terminal-style.d.ts.map +1 -1
  156. package/dist/internal/terminal-style.js +46 -1
  157. package/dist/internal/workspace.d.ts +2 -0
  158. package/dist/internal/workspace.d.ts.map +1 -1
  159. package/dist/internal/workspace.js +5 -0
  160. package/dist/playground/assets/index-77uhu5Kr.css +1 -0
  161. package/dist/playground/assets/{index-yxs1heea.js → index-D4buox4m.js} +42 -42
  162. package/dist/playground/index.html +2 -2
  163. package/dist/tools.d.ts +7 -0
  164. package/dist/tools.d.ts.map +1 -1
  165. package/dist/types.d.ts +28 -3
  166. package/dist/types.d.ts.map +1 -1
  167. package/docs/concepts.md +4 -4
  168. package/docs/guides/mcp-oauth.md +3 -1
  169. package/docs/reference/agent-config.md +11 -12
  170. package/docs/reference/connections.md +44 -26
  171. package/docs/reference/sessions.md +2 -2
  172. package/docs/reference/tools.md +1 -1
  173. package/docs/troubleshooting.md +3 -2
  174. package/package.json +4 -1
  175. package/skills/create-agent/SKILL.md +12 -9
  176. package/skills/debug/SKILL.md +2 -1
  177. package/skills/framework-map/SKILL.md +6 -6
  178. package/skills/mcp-auth/SKILL.md +8 -6
  179. package/src/bin/agent-serve.ts +3 -2
  180. package/src/channels/github/api.ts +6 -1
  181. package/src/channels/github/binding.ts +21 -0
  182. package/src/channels/github/checks.ts +179 -0
  183. package/src/channels/github/cursor-account.ts +9 -6
  184. package/src/channels/github/index.ts +1 -0
  185. package/src/channels/github/types.ts +8 -0
  186. package/src/channels/slack/manifest.ts +8 -10
  187. package/src/channels/slack/types.ts +2 -2
  188. package/src/connections.ts +17 -5
  189. package/src/internal/advertise-tools.ts +72 -23
  190. package/src/internal/cli-deploy.ts +4 -15
  191. package/src/internal/convert-automation/convert-workflow.ts +2 -11
  192. package/src/internal/cursor/account-mcp.ts +208 -73
  193. package/src/internal/cursor/backend-client.ts +45 -11
  194. package/src/internal/cursor-account-mcp-auth.ts +83 -0
  195. package/src/internal/deploy-client.ts +0 -10
  196. package/src/internal/deploy-manifest.ts +33 -39
  197. package/src/internal/deployment-scm-event-stream.ts +17 -1
  198. package/src/internal/discovery.ts +47 -3
  199. package/src/internal/init-project.ts +7 -133
  200. package/src/internal/init-scaffold.ts +176 -0
  201. package/src/internal/inline-stdio-mcp.ts +13 -0
  202. package/src/internal/json-schema.ts +24 -3
  203. package/src/internal/mcp-endpoint.ts +6 -0
  204. package/src/internal/mcp-host.ts +4 -0
  205. package/src/internal/mcp-oauth.ts +55 -1
  206. package/src/internal/package-inline-stdio.ts +5 -1
  207. package/src/internal/review-comments.ts +245 -0
  208. package/src/internal/sanitize-mcp-tool-name.ts +33 -0
  209. package/src/internal/session-engine.ts +7 -0
  210. package/src/internal/shallow-clone.ts +293 -105
  211. package/src/internal/terminal-style.ts +67 -1
  212. package/src/internal/workspace.ts +6 -0
  213. package/src/tools.ts +7 -0
  214. package/src/types.ts +32 -4
  215. package/templates/agentic-owners/agent/agent.ts +3 -0
  216. package/templates/demo/agent/agent.ts +3 -0
  217. package/templates/security-reviewer/agent/agent.ts +3 -0
  218. package/templates/triage/agent/agent.ts +3 -0
  219. package/dist/docs/assets/chunks/@localSearchIndexroot.DvUR3lv9.js +0 -1
  220. package/dist/docs/assets/troubleshooting.md.CuVztCKs.js +0 -1
  221. package/dist/playground/assets/index-CoL7xCJl.css +0 -1
  222. /package/dist/docs/assets/{concepts.md.CqOsxbMU.lean.js → concepts.md.BXAm6G-C.lean.js} +0 -0
  223. /package/dist/docs/assets/{guides_mcp-oauth.md.C7G7IykG.lean.js → guides_mcp-oauth.md.CzEB6RaG.lean.js} +0 -0
  224. /package/dist/docs/assets/{reference_sessions.md.DBVFi2Sx.lean.js → reference_sessions.md.B0DdlM-K.lean.js} +0 -0
  225. /package/dist/docs/assets/{reference_tools.md.Wmvb7Lob.lean.js → reference_tools.md.DTg_kEsx.lean.js} +0 -0
  226. /package/dist/docs/assets/{troubleshooting.md.CuVztCKs.lean.js → troubleshooting.md.DQ-hYuZT.lean.js} +0 -0
@@ -12,7 +12,38 @@ import { mkdirSync, rmSync } from "node:fs";
12
12
  import { promisify } from "node:util";
13
13
  const execFileAsync = promisify(execFile);
14
14
  /**
15
- * Default clone credential: the serve host's Cursor-account GitHub lease.
15
+ * Resolve a PR URL to its clone target, or `undefined` when the SCM has no
16
+ * shallow-clone support (callers then review on their fallback checkout —
17
+ * e.g. Origin PRs, where the host checkout already is the reviewed repo).
18
+ */
19
+ export function resolveScmCloneTarget(prUrl) {
20
+ let url;
21
+ try {
22
+ url = new URL(prUrl);
23
+ }
24
+ catch (_a) {
25
+ return undefined;
26
+ }
27
+ const parts = url.pathname.split("/").filter(Boolean);
28
+ if (url.hostname === "github.com" &&
29
+ parts.length >= 4 &&
30
+ parts[2] === "pull" &&
31
+ Number.isInteger(Number(parts[3]))) {
32
+ const repo = `${parts[0]}/${parts[1]}`;
33
+ const prNumber = Number(parts[3]);
34
+ return {
35
+ provider: "github",
36
+ repo,
37
+ prNumber,
38
+ remoteUrl: `https://github.com/${repo}.git`,
39
+ credentialUsername: "x-access-token",
40
+ prHeadRef: `refs/pull/${prNumber}/head`,
41
+ };
42
+ }
43
+ return undefined;
44
+ }
45
+ /**
46
+ * Default GitHub clone credential: the serve host's Cursor-account lease.
16
47
  * `CursorGithubCredentialProvider` mints it repo-scoped from the backend and
17
48
  * keeps `GH_TOKEN` refreshed for child processes; `GITHUB_TOKEN` covers
18
49
  * local/CI runs that export the conventional variable instead.
@@ -22,6 +53,107 @@ export function serveHostGithubAuth(env = process.env) {
22
53
  const token = ((_b = (_a = env.GH_TOKEN) !== null && _a !== void 0 ? _a : env.GITHUB_TOKEN) !== null && _b !== void 0 ? _b : "").trim();
23
54
  return token === "" ? undefined : { token };
24
55
  }
56
+ /** Pair the provider's git-over-HTTPS username with the bearer token. */
57
+ function cloneCredential(target, auth) {
58
+ return auth === undefined
59
+ ? undefined
60
+ : { username: target.credentialUsername, token: auth.token };
61
+ }
62
+ /** Default clone credential source per provider. */
63
+ function defaultCloneAuth(target) {
64
+ switch (target.provider) {
65
+ case "github":
66
+ return serveHostGithubAuth();
67
+ }
68
+ }
69
+ /** Cap on diff text handed to a model; beyond this it is truncated. */
70
+ const DIFF_MAX_CHARS = 80000;
71
+ /**
72
+ * Diff two commits inside an existing shallow PR checkout, fetching either
73
+ * end on demand when the shallow history does not already contain it.
74
+ *
75
+ * Lives here because it needs the same authenticated git the clone uses —
76
+ * a `--depth=1` checkout usually lacks the older commit, so reading a range
77
+ * means another credentialed fetch. Never throws: every failure becomes an
78
+ * `unavailable` reason the caller can act on or surface.
79
+ */
80
+ export function tryDiffCommitRange(args) {
81
+ return __awaiter(this, void 0, void 0, function* () {
82
+ var _a;
83
+ if (!isFullCommitSha(args.from) || !isFullCommitSha(args.to)) {
84
+ return {
85
+ status: "unavailable",
86
+ reason: "Could not compute a reliable diff because a commit SHA was not a full 40-character SHA.",
87
+ };
88
+ }
89
+ const credential = cloneCredential(args.target, (_a = args.auth) !== null && _a !== void 0 ? _a : defaultCloneAuth(args.target));
90
+ for (const sha of [args.from, args.to]) {
91
+ if (!(yield ensureCommitFetched(args.checkoutDir, sha, args.target, credential))) {
92
+ return {
93
+ status: "unavailable",
94
+ reason: "Could not compute a reliable diff because a commit was unavailable in the checkout.",
95
+ };
96
+ }
97
+ }
98
+ try {
99
+ const diff = yield git(args.checkoutDir, [
100
+ "diff",
101
+ "--no-ext-diff",
102
+ "--unified=80",
103
+ `${args.from}..${args.to}`,
104
+ ...(args.file === undefined ? [] : ["--", args.file]),
105
+ ]);
106
+ return {
107
+ status: "ok",
108
+ diff: diff.length <= DIFF_MAX_CHARS
109
+ ? diff
110
+ : `${diff.slice(0, DIFF_MAX_CHARS)}\n\n[diff truncated at ${DIFF_MAX_CHARS} characters]`,
111
+ };
112
+ }
113
+ catch (_b) {
114
+ return {
115
+ status: "unavailable",
116
+ reason: "Could not compute a reliable diff because git diff failed.",
117
+ };
118
+ }
119
+ });
120
+ }
121
+ function isFullCommitSha(value) {
122
+ return /^[0-9a-f]{40}$/i.test(value);
123
+ }
124
+ /** Present already, or fetchable by SHA, or reachable from the PR head ref. */
125
+ function ensureCommitFetched(checkoutDir, sha, target, credential) {
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ if ((yield revParse(checkoutDir, sha)) !== undefined) {
128
+ return true;
129
+ }
130
+ const attempts = [
131
+ [...FETCH_ARGS, sha],
132
+ // Deeper history on the PR head ref: the older end of an inter-run range
133
+ // is usually an ancestor of the tip rather than the tip itself.
134
+ [
135
+ "fetch",
136
+ "--depth=200",
137
+ "--no-tags",
138
+ "--quiet",
139
+ "origin",
140
+ target.prHeadRef,
141
+ ],
142
+ ];
143
+ for (const attempt of attempts) {
144
+ try {
145
+ yield git(checkoutDir, attempt, credential);
146
+ if ((yield revParse(checkoutDir, sha)) !== undefined) {
147
+ return true;
148
+ }
149
+ }
150
+ catch (_a) {
151
+ // Try the next strategy; the caller fails closed if none work.
152
+ }
153
+ }
154
+ return false;
155
+ });
156
+ }
25
157
  function logShallowClone(message, fields = {}) {
26
158
  const suffix = Object.entries(fields)
27
159
  .filter(([, value]) => value !== undefined)
@@ -55,12 +187,12 @@ function gitError(args, error) {
55
187
  return new Error(`git ${args.join(" ")} failed — ${detail}`);
56
188
  }
57
189
  /**
58
- * The one credential helper git may use: serve the caller-provided token
59
- * from the child process env at request time. The shell reads
60
- * `$SHALLOW_CLONE_GIT_TOKEN` when git asks, keeping the token out of argv.
190
+ * The one credential helper git may use: serve the caller-provided
191
+ * credential from the child process env at request time. The shell reads
192
+ * the values when git asks, keeping the token out of argv.
61
193
  */
62
- const TOKEN_CREDENTIAL_HELPER = '!f() { test "$1" = get && printf "username=x-access-token\\npassword=$SHALLOW_CLONE_GIT_TOKEN\\n"; }; f';
63
- function git(cwd, args, auth) {
194
+ const CREDENTIAL_HELPER = '!f() { test "$1" = get && printf "username=$SHALLOW_CLONE_GIT_USERNAME\\npassword=$SHALLOW_CLONE_GIT_TOKEN\\n"; }; f';
195
+ function git(cwd, args, credential) {
64
196
  return __awaiter(this, void 0, void 0, function* () {
65
197
  // Async on purpose: fetches/checkouts of large repos take minutes, and the
66
198
  // serve host runs the clone in-process. A synchronous git call blocks the
@@ -68,9 +200,9 @@ function git(cwd, args, auth) {
68
200
  // long enough for the platform's probe budget to replace the engine.
69
201
  try {
70
202
  const { stdout } = yield execFileAsync("git", [
71
- ...(auth === undefined
203
+ ...(credential === undefined
72
204
  ? []
73
- : ["-c", `credential.helper=${TOKEN_CREDENTIAL_HELPER}`]),
205
+ : ["-c", `credential.helper=${CREDENTIAL_HELPER}`]),
74
206
  ...args,
75
207
  ], {
76
208
  cwd,
@@ -82,9 +214,12 @@ function git(cwd, args, auth) {
82
214
  // .com/.insteadOf` entries scoped to a *different* repo, as cloud
83
215
  // VMs bake in) cannot hijack auth away from the explicit token,
84
216
  // and no ambient credential helpers run against PR-author input.
85
- GIT_CONFIG_GLOBAL: "/dev/null", GIT_CONFIG_SYSTEM: "/dev/null", GIT_TERMINAL_PROMPT: "0" }), (auth === undefined
217
+ GIT_CONFIG_GLOBAL: "/dev/null", GIT_CONFIG_SYSTEM: "/dev/null", GIT_TERMINAL_PROMPT: "0" }), (credential === undefined
86
218
  ? {}
87
- : { SHALLOW_CLONE_GIT_TOKEN: auth.token })),
219
+ : {
220
+ SHALLOW_CLONE_GIT_USERNAME: credential.username,
221
+ SHALLOW_CLONE_GIT_TOKEN: credential.token,
222
+ })),
88
223
  });
89
224
  return stdout;
90
225
  }
@@ -105,14 +240,16 @@ function revParse(cwd, rev) {
105
240
  });
106
241
  }
107
242
  const FETCH_ARGS = ["fetch", "--depth=1", "--no-tags", "--quiet", "origin"];
243
+ /** Local tracking ref the PR head ref is fetched into. */
244
+ const LOCAL_PR_HEAD_REF = "refs/remotes/origin/shallow-clone-pr-head";
108
245
  /**
109
- * Create a fresh shallow checkout of a GitHub PR head at `checkoutDir`.
246
+ * Create a fresh shallow checkout of a PR head at `checkoutDir`.
110
247
  *
111
248
  * Fetch order (both single depth-1 round-trips):
112
249
  * 1. Fetch `headSha` (and `baseSha` when known) directly — GitHub advertises
113
250
  * `allow-reachable-sha1-in-want`, and this pins the exact reviewed commit
114
251
  * the way Bugbot's `shallow_fetch` does.
115
- * 2. Fall back to `refs/pull/<n>/head`, verifying it still resolves to
252
+ * 2. Fall back to the target's PR head ref, verifying it still resolves to
116
253
  * `headSha` so the working tree cannot silently drift from the pinned
117
254
  * patch in the review bundle.
118
255
  *
@@ -121,23 +258,19 @@ const FETCH_ARGS = ["fetch", "--depth=1", "--no-tags", "--quiet", "origin"];
121
258
  */
122
259
  export function createShallowPrCheckout(args) {
123
260
  return __awaiter(this, void 0, void 0, function* () {
124
- var _a;
125
- const { repo, prNumber, headSha, baseSha, checkoutDir, auth } = args;
261
+ const { target, headSha, baseSha, checkoutDir, auth } = args;
262
+ const { repo, prNumber } = target;
263
+ const credential = cloneCredential(target, auth);
126
264
  const startedAt = Date.now();
127
265
  logShallowClone("cloning PR head", { repo, prNumber, headSha, baseSha });
128
266
  rmSync(checkoutDir, { recursive: true, force: true });
129
267
  mkdirSync(checkoutDir, { recursive: true });
130
268
  yield git(checkoutDir, ["init", "--quiet"]);
131
- yield git(checkoutDir, [
132
- "remote",
133
- "add",
134
- "origin",
135
- (_a = args.remoteUrl) !== null && _a !== void 0 ? _a : `https://github.com/${repo}.git`,
136
- ]);
269
+ yield git(checkoutDir, ["remote", "add", "origin", target.remoteUrl]);
137
270
  const shaFetch = () => __awaiter(this, void 0, void 0, function* () {
138
271
  const extraBase = baseSha === undefined || baseSha === headSha ? [] : [baseSha];
139
272
  try {
140
- yield git(checkoutDir, [...FETCH_ARGS, headSha, ...extraBase], auth);
273
+ yield git(checkoutDir, [...FETCH_ARGS, headSha, ...extraBase], credential);
141
274
  }
142
275
  catch (error) {
143
276
  if (extraBase.length === 0) {
@@ -151,29 +284,24 @@ export function createShallowPrCheckout(args) {
151
284
  baseSha,
152
285
  error: errorSummary(error),
153
286
  });
154
- yield git(checkoutDir, [...FETCH_ARGS, headSha], auth);
287
+ yield git(checkoutDir, [...FETCH_ARGS, headSha], credential);
155
288
  }
156
289
  });
157
290
  let headSource;
158
- let shaFetchError;
159
291
  try {
160
292
  yield shaFetch();
161
293
  headSource = "sha_fetch";
162
294
  }
163
295
  catch (error) {
164
- shaFetchError = errorSummary(error);
165
- if (prNumber === undefined) {
166
- throw new Error(`Shallow SHA fetch failed for ${repo}@${headSha} and no PR number is available for a ref fallback: ${shaFetchError}`);
167
- }
296
+ const shaFetchError = errorSummary(error);
168
297
  logShallowClone("sha fetch failed; falling back to PR head ref", {
169
298
  repo,
170
299
  prNumber,
171
300
  headSha,
172
301
  error: shaFetchError,
173
302
  });
174
- const prRef = `refs/pull/${prNumber}/head`;
175
- yield git(checkoutDir, [...FETCH_ARGS, `+${prRef}:refs/remotes/origin/pr/${prNumber}/head`], auth);
176
- const fetchedSha = yield revParse(checkoutDir, `refs/remotes/origin/pr/${prNumber}/head`);
303
+ yield git(checkoutDir, [...FETCH_ARGS, `+${target.prHeadRef}:${LOCAL_PR_HEAD_REF}`], credential);
304
+ const fetchedSha = yield revParse(checkoutDir, LOCAL_PR_HEAD_REF);
177
305
  if (fetchedSha !== headSha) {
178
306
  throw new Error(`Shallow PR ref fetch for ${repo}#${prNumber} resolved to ${fetchedSha !== null && fetchedSha !== void 0 ? fetchedSha : "nothing"}, expected pinned head ${headSha} (sha fetch error: ${shaFetchError})`);
179
307
  }
@@ -194,7 +322,7 @@ export function createShallowPrCheckout(args) {
194
322
  // Best-effort: local diffs are nice-to-have, the pinned patch in the
195
323
  // prompt is the authoritative delta either way.
196
324
  try {
197
- yield git(checkoutDir, [...FETCH_ARGS, baseSha], auth);
325
+ yield git(checkoutDir, [...FETCH_ARGS, baseSha], credential);
198
326
  baseFetched = (yield revParse(checkoutDir, baseSha)) !== undefined;
199
327
  }
200
328
  catch (error) {
@@ -218,71 +346,63 @@ export function createShallowPrCheckout(args) {
218
346
  return { checkoutDir, headSha, baseFetched, headSource };
219
347
  });
220
348
  }
221
- /** True for `https://github.com/<owner>/<repo>/pull/<n>` URLs. */
222
- export function isGithubPrUrl(prUrl) {
223
- try {
224
- const url = new URL(prUrl);
225
- const parts = url.pathname.split("/").filter(Boolean);
226
- return (url.hostname === "github.com" &&
227
- parts.length >= 4 &&
228
- parts[2] === "pull" &&
229
- Number.isInteger(Number(parts[3])));
230
- }
231
- catch (_a) {
232
- return false;
233
- }
234
- }
235
349
  /**
236
350
  * Best-effort shallow PR checkout for hosts whose SDK agents should read the
237
351
  * reviewed repo instead of the host's own checkout.
238
352
  *
239
353
  * Returns no checkout — leaving the caller on its fallback working
240
- * directory — when the PR is not on GitHub (e.g. Origin PRs, where the host
241
- * checkout is the reviewed repo), when no head SHA is pinned, when no clone
242
- * credential is available, or when the clone fails; `fallbackReason` says
243
- * which. Failures are logged, never thrown: agents still have the pinned
244
- * patch in their prompts, so a missing checkout degrades quality rather
245
- * than the run.
354
+ * directory — when the PR's SCM has no clone support (e.g. Origin PRs,
355
+ * where the host checkout is the reviewed repo), when no head SHA is
356
+ * pinned, when no clone credential is available, or when the clone fails;
357
+ * `fallbackReason` says which. Failures are logged, never thrown: agents
358
+ * still have the pinned patch in their prompts, so a missing checkout
359
+ * degrades quality rather than the run.
246
360
  */
247
361
  export function tryCreateShallowPrCheckout(options) {
248
362
  return __awaiter(this, void 0, void 0, function* () {
249
- var _a;
250
- const { prUrl, repo, prNumber, headSha, baseSha, checkoutDir, remoteUrl } = options;
251
- if (remoteUrl === undefined && !isGithubPrUrl(prUrl)) {
252
- logShallowClone("skipped: not a GitHub PR URL", { prUrl });
253
- return { fallbackReason: "skipped: not a GitHub PR URL" };
363
+ var _a, _b;
364
+ const { prUrl, headSha, baseSha, checkoutDir } = options;
365
+ const target = (_a = options.target) !== null && _a !== void 0 ? _a : resolveScmCloneTarget(prUrl);
366
+ if (target === undefined) {
367
+ logShallowClone("skipped: unsupported SCM for shallow clone", { prUrl });
368
+ return { fallbackReason: "skipped: unsupported SCM for shallow clone" };
254
369
  }
255
370
  if (headSha === undefined) {
256
- logShallowClone("skipped: no pinned head SHA", { repo, prUrl });
371
+ logShallowClone("skipped: no pinned head SHA", {
372
+ repo: target.repo,
373
+ prUrl,
374
+ });
257
375
  return { fallbackReason: "skipped: no pinned head SHA" };
258
376
  }
259
- const auth = (_a = options.auth) !== null && _a !== void 0 ? _a : serveHostGithubAuth();
260
- if (remoteUrl === undefined && auth === undefined) {
261
- // Fail fast instead of letting an unauthenticated fetch 404/hang: real
262
- // GitHub clones need the serve host's lease (or an explicit token).
263
- logShallowClone("skipped: no GitHub clone credential", { repo, prUrl });
377
+ const auth = (_b = options.auth) !== null && _b !== void 0 ? _b : defaultCloneAuth(target);
378
+ if (auth === undefined && target.remoteUrl.startsWith("https://")) {
379
+ // Fail fast instead of letting an unauthenticated fetch 404/hang: HTTPS
380
+ // clones need the provider's credential (or an explicit token).
381
+ logShallowClone("skipped: no clone credential", {
382
+ repo: target.repo,
383
+ provider: target.provider,
384
+ prUrl,
385
+ });
264
386
  return {
265
- fallbackReason: "skipped: no GitHub clone credential (serve host GH_TOKEN lease not installed)",
387
+ fallbackReason: `skipped: no ${target.provider} clone credential (serve host token lease not installed)`,
266
388
  };
267
389
  }
268
390
  try {
269
391
  return {
270
392
  checkout: yield createShallowPrCheckout({
271
- repo,
272
- prNumber,
393
+ target,
273
394
  headSha,
274
395
  baseSha,
275
396
  checkoutDir,
276
397
  auth,
277
- remoteUrl,
278
398
  }),
279
399
  };
280
400
  }
281
401
  catch (error) {
282
402
  const reason = errorSummary(error);
283
403
  logShallowClone("failed; caller falls back to host checkout", {
284
- repo,
285
- prNumber,
404
+ repo: target.repo,
405
+ prNumber: target.prNumber,
286
406
  headSha,
287
407
  error: reason,
288
408
  });
@@ -17,6 +17,24 @@ export declare function makePalette(enabled: boolean): TerminalPalette;
17
17
  export declare function stdoutPalette(): TerminalPalette;
18
18
  /** Palette for human-facing stderr (login progress, warnings). */
19
19
  export declare function stderrPalette(): TerminalPalette;
20
+ /** Visible column count, ignoring CSI color/style and OSC 8 hyperlinks. */
21
+ export declare function visibleWidth(text: string): number;
22
+ /** True when `text` already carries CSI styling or OSC 8 (do not wrap again). */
23
+ export declare function hasAnsiStyling(text: string): boolean;
24
+ /**
25
+ * Clickable terminal hyperlink (OSC 8). The URI is the click target; `label`
26
+ * is what the user sees. `visibleWidth` ignores the OSC wrapper.
27
+ */
28
+ export declare function terminalHyperlink(url: string, label: string, enabled?: boolean): string;
29
+ /**
30
+ * Unicode box around `lines`. `color` wraps the whole box (borders + body)
31
+ * so a warning panel can be yellow without per-line prefixes.
32
+ */
33
+ export declare function formatTerminalBox(lines: readonly string[], options?: {
34
+ color?: (s: string) => string;
35
+ minWidth?: number;
36
+ padding?: number;
37
+ }): string;
20
38
  /** Wipe the terminal before a `dev` Enter-to-restart cycle. */
21
39
  export declare function clearTerminal(stream?: NodeJS.WriteStream): void;
22
40
  //# sourceMappingURL=terminal-style.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-style.d.ts","sourceRoot":"","sources":["../../src/internal/terminal-style.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7B,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/B;AAcD,wBAAgB,eAAe,CAC7B,MAAM,GAAE,MAAM,CAAC,WAA4B,GAC1C,OAAO,CAET;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAiB7D;AAED,oEAAoE;AACpE,wBAAgB,aAAa,IAAI,eAAe,CAE/C;AAED,kEAAkE;AAClE,wBAAgB,aAAa,IAAI,eAAe,CAE/C;AAED,+DAA+D;AAC/D,wBAAgB,aAAa,CAC3B,MAAM,GAAE,MAAM,CAAC,WAA4B,GAC1C,IAAI,CAMN"}
1
+ {"version":3,"file":"terminal-style.d.ts","sourceRoot":"","sources":["../../src/internal/terminal-style.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7B,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/B;AAsBD,wBAAgB,eAAe,CAC7B,MAAM,GAAE,MAAM,CAAC,WAA4B,GAC1C,OAAO,CAET;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAiB7D;AAED,oEAAoE;AACpE,wBAAgB,aAAa,IAAI,eAAe,CAE/C;AAED,kEAAkE;AAClE,wBAAgB,aAAa,IAAI,eAAe,CAE/C;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,OAA2B,GACnC,MAAM,CAKR;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,MAAM,CAoBR;AAED,+DAA+D;AAC/D,wBAAgB,aAAa,CAC3B,MAAM,GAAE,MAAM,CAAC,WAA4B,GAC1C,IAAI,CAMN"}
@@ -4,6 +4,11 @@
4
4
  */
5
5
  import { clearScreenDown, cursorTo } from "node:readline";
6
6
  const IDENTITY = (s) => s;
7
+ const ESC = "\u001b";
8
+ const BEL = "\u0007";
9
+ const ANSI_CSI = new RegExp(`${ESC}\\[[0-9;]*m`, "g");
10
+ /** OSC 8 hyperlinks: `ESC ] 8 ; params ; uri BEL` (or ST). */
11
+ const OSC_8 = new RegExp(`${ESC}\\]8;[^${BEL}${ESC}]*(?:${BEL}|${ESC}\\\\)`, "g");
7
12
  const PLAIN = {
8
13
  dim: IDENTITY,
9
14
  bold: IDENTITY,
@@ -22,7 +27,7 @@ export function makePalette(enabled) {
22
27
  }
23
28
  const wrap = (code) => (s) => `\u001b[${code}m${s}\u001b[0m`;
24
29
  return {
25
- dim: wrap("2"),
30
+ dim: (s) => (hasAnsiStyling(s) ? s : wrap("2")(s)),
26
31
  bold: wrap("1"),
27
32
  cyan: wrap("36"),
28
33
  green: wrap("32"),
@@ -39,6 +44,46 @@ export function stdoutPalette() {
39
44
  export function stderrPalette() {
40
45
  return makePalette(colorEnabledFor(process.stderr));
41
46
  }
47
+ /** Visible column count, ignoring CSI color/style and OSC 8 hyperlinks. */
48
+ export function visibleWidth(text) {
49
+ return text.replace(OSC_8, "").replace(ANSI_CSI, "").length;
50
+ }
51
+ /** True when `text` already carries CSI styling or OSC 8 (do not wrap again). */
52
+ export function hasAnsiStyling(text) {
53
+ return text.includes("\u001b[") || text.includes("\u001b]");
54
+ }
55
+ /**
56
+ * Clickable terminal hyperlink (OSC 8). The URI is the click target; `label`
57
+ * is what the user sees. `visibleWidth` ignores the OSC wrapper.
58
+ */
59
+ export function terminalHyperlink(url, label, enabled = colorEnabledFor()) {
60
+ if (!enabled) {
61
+ return label;
62
+ }
63
+ return `\u001b]8;;${url}\u0007\u001b[4m${label}\u001b[24m\u001b]8;;\u0007`;
64
+ }
65
+ /**
66
+ * Unicode box around `lines`. `color` wraps the whole box (borders + body)
67
+ * so a warning panel can be yellow without per-line prefixes.
68
+ */
69
+ export function formatTerminalBox(lines, options) {
70
+ var _a, _b, _c;
71
+ const color = (_a = options === null || options === void 0 ? void 0 : options.color) !== null && _a !== void 0 ? _a : IDENTITY;
72
+ const padding = (_b = options === null || options === void 0 ? void 0 : options.padding) !== null && _b !== void 0 ? _b : 1;
73
+ const contentWidth = Math.max((_c = options === null || options === void 0 ? void 0 : options.minWidth) !== null && _c !== void 0 ? _c : 0, ...lines.map((line) => visibleWidth(line)), 1);
74
+ const inner = contentWidth + padding * 2;
75
+ const padLine = (line) => {
76
+ const extra = contentWidth - visibleWidth(line);
77
+ return `│${" ".repeat(padding)}${line}${" ".repeat(padding + extra)}│`;
78
+ };
79
+ const paint = (line) => color(line);
80
+ const box = [
81
+ paint(`╭${"─".repeat(inner)}╮`),
82
+ ...lines.map((line) => paint(padLine(line))),
83
+ paint(`╰${"─".repeat(inner)}╯`),
84
+ ].join("\n");
85
+ return box;
86
+ }
42
87
  /** Wipe the terminal before a `dev` Enter-to-restart cycle. */
43
88
  export function clearTerminal(stream = process.stdout) {
44
89
  if (stream.isTTY !== true) {
@@ -99,6 +99,8 @@ export declare function buildAgentsMdContent(agent: ResolvedAgent, options: {
99
99
  * are skipped by nested rule discovery.
100
100
  */
101
101
  export declare function isNestedInGitRepo(dir: string): Promise<boolean>;
102
+ /** Default harness parent for a nested-git agent project. */
103
+ export declare function defaultLocalHarnessCwd(dirName: string): string;
102
104
  /**
103
105
  * Give a session workspace its own git root so the harness roots *there*
104
106
  * rather than at the enclosing repo (see {@link isNestedInGitRepo}). Without
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/internal/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkBH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOjE;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,mBAAmB,CAAC;AAE7D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,MAAM,GAAG,SAAS,CAapB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE;IAAE,cAAc,EAAE,OAAO,CAAA;CAA8B,GAC/D,MAAM,CA8CR;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GACjC,MAAM,CA6BR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,MAAM,CAeR;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcrE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpE;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAkCf;AAqGD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAO3D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,CACX,MAAM,EACN,MAAM,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CACjE,GACA,OAAO,CAAC,IAAI,CAAC,CAcf"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/internal/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOjE;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,mBAAmB,CAAC;AAE7D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,MAAM,GAAG,SAAS,CAapB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE;IAAE,cAAc,EAAE,OAAO,CAAA;CAA8B,GAC/D,MAAM,CA8CR;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GACjC,MAAM,CA6BR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,MAAM,CAeR;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcrE;AAED,6DAA6D;AAC7D,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpE;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAkCf;AAqGD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAO3D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,CACX,MAAM,EACN,MAAM,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CACjE,GACA,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -17,6 +17,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
17
17
  };
18
18
  import { execFile } from "node:child_process";
19
19
  import { chmod, copyFile, lstat, mkdir, readlink, rm, stat, symlink, writeFile, } from "node:fs/promises";
20
+ import { homedir } from "node:os";
20
21
  import { dirname, join, parse, relative, resolve, sep } from "node:path";
21
22
  import { promisify } from "node:util";
22
23
  import { agentStoreKeys, DEPLOYMENT_STORE_MOUNT_PATH } from "../files.js";
@@ -222,6 +223,10 @@ export function isNestedInGitRepo(dir) {
222
223
  return false;
223
224
  });
224
225
  }
226
+ /** Default harness parent for a nested-git agent project. */
227
+ export function defaultLocalHarnessCwd(dirName) {
228
+ return join(homedir(), ".cache", "agent-serve", dirName);
229
+ }
225
230
  /**
226
231
  * Give a session workspace its own git root so the harness roots *there*
227
232
  * rather than at the enclosing repo (see {@link isNestedInGitRepo}). Without