@posthog/agent 2.3.556 → 2.3.619
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/agent.js +64 -30
- package/dist/agent.js.map +1 -1
- package/dist/handoff-checkpoint.js +142 -117
- package/dist/handoff-checkpoint.js.map +1 -1
- package/dist/posthog-api.js +1 -1
- package/dist/posthog-api.js.map +1 -1
- package/dist/server/agent-server.d.ts +2 -1
- package/dist/server/agent-server.js +125 -69
- package/dist/server/agent-server.js.map +1 -1
- package/dist/server/bin.cjs +136 -81
- package/dist/server/bin.cjs.map +1 -1
- package/package.json +3 -3
- package/src/adapters/claude/conversion/sdk-to-acp.ts +1 -26
- package/src/adapters/codex/codex-agent.test.ts +83 -0
- package/src/adapters/codex/codex-agent.ts +16 -0
- package/src/adapters/error-classification.ts +30 -0
- package/src/server/agent-server.test.ts +17 -0
- package/src/server/agent-server.ts +28 -9
- package/src/server/question-relay.test.ts +67 -5
package/dist/server/bin.cjs
CHANGED
|
@@ -3951,6 +3951,7 @@ var import_sdk5 = require("@agentclientprotocol/sdk");
|
|
|
3951
3951
|
var import_node_server = require("@hono/node-server");
|
|
3952
3952
|
|
|
3953
3953
|
// ../git/dist/queries.js
|
|
3954
|
+
var import_node_fs = require("fs");
|
|
3954
3955
|
var fs3 = __toESM(require("fs/promises"), 1);
|
|
3955
3956
|
var path2 = __toESM(require("path"), 1);
|
|
3956
3957
|
|
|
@@ -8502,13 +8503,20 @@ init_git_response_error();
|
|
|
8502
8503
|
var simpleGit = gitInstanceFactory;
|
|
8503
8504
|
|
|
8504
8505
|
// ../git/dist/client.js
|
|
8506
|
+
var PERFORMANCE_CONFIG = [
|
|
8507
|
+
"core.untrackedCache=true",
|
|
8508
|
+
"core.fsmonitor=true",
|
|
8509
|
+
"core.preloadIndex=true"
|
|
8510
|
+
];
|
|
8505
8511
|
function createGitClient(baseDir, options) {
|
|
8506
|
-
const { abortSignal: signal, ...rest } = options ?? {};
|
|
8512
|
+
const { abortSignal: signal, config: callerConfig, ...rest } = options ?? {};
|
|
8513
|
+
const config = callerConfig ? [...PERFORMANCE_CONFIG, ...callerConfig] : PERFORMANCE_CONFIG;
|
|
8507
8514
|
return simpleGit({
|
|
8508
8515
|
baseDir,
|
|
8509
8516
|
maxConcurrentProcesses: 6,
|
|
8510
8517
|
trimmed: true,
|
|
8511
8518
|
abort: signal,
|
|
8519
|
+
config,
|
|
8512
8520
|
...rest
|
|
8513
8521
|
});
|
|
8514
8522
|
}
|
|
@@ -8661,14 +8669,18 @@ var GitOperationManagerImpl = class _GitOperationManagerImpl {
|
|
|
8661
8669
|
}
|
|
8662
8670
|
async executeRead(repoPath, operation, options) {
|
|
8663
8671
|
const state = this.getRepoState(repoPath);
|
|
8672
|
+
const env = {
|
|
8673
|
+
...getCleanEnv(),
|
|
8674
|
+
GIT_OPTIONAL_LOCKS: "0",
|
|
8675
|
+
...options?.env
|
|
8676
|
+
};
|
|
8664
8677
|
if (options?.signal) {
|
|
8665
8678
|
const scopedGit = createGitClient(repoPath, {
|
|
8666
8679
|
abortSignal: options.signal
|
|
8667
8680
|
});
|
|
8668
|
-
return operation(scopedGit.env(
|
|
8681
|
+
return operation(scopedGit.env(env));
|
|
8669
8682
|
}
|
|
8670
|
-
|
|
8671
|
-
return operation(git);
|
|
8683
|
+
return operation(state.client.env(env));
|
|
8672
8684
|
}
|
|
8673
8685
|
async executeWrite(repoPath, operation, options) {
|
|
8674
8686
|
const state = this.getRepoState(repoPath);
|
|
@@ -8678,15 +8690,16 @@ var GitOperationManagerImpl = class _GitOperationManagerImpl {
|
|
|
8678
8690
|
throw new Error(`Git repository is locked: ${repoPath}`);
|
|
8679
8691
|
}
|
|
8680
8692
|
}
|
|
8693
|
+
const env = { ...getCleanEnv(), ...options?.env };
|
|
8681
8694
|
await state.lock.acquireWrite();
|
|
8682
8695
|
try {
|
|
8683
8696
|
if (options?.signal) {
|
|
8684
8697
|
const scopedGit = createGitClient(repoPath, {
|
|
8685
8698
|
abortSignal: options.signal
|
|
8686
8699
|
});
|
|
8687
|
-
return await operation(scopedGit.env(
|
|
8700
|
+
return await operation(scopedGit.env(env));
|
|
8688
8701
|
}
|
|
8689
|
-
return await operation(state.client.env(
|
|
8702
|
+
return await operation(state.client.env(env));
|
|
8690
8703
|
} catch (error) {
|
|
8691
8704
|
if (options?.signal?.aborted) {
|
|
8692
8705
|
await removeLock(repoPath).catch(() => {
|
|
@@ -8713,6 +8726,9 @@ function getGitOperationManager() {
|
|
|
8713
8726
|
return instance2;
|
|
8714
8727
|
}
|
|
8715
8728
|
|
|
8729
|
+
// ../git/dist/status-stream.js
|
|
8730
|
+
var import_node_child_process2 = require("child_process");
|
|
8731
|
+
|
|
8716
8732
|
// ../git/dist/queries.js
|
|
8717
8733
|
async function getCurrentBranch(baseDir, options) {
|
|
8718
8734
|
const manager = getGitOperationManager();
|
|
@@ -8747,6 +8763,44 @@ async function listWorktrees(baseDir, options) {
|
|
|
8747
8763
|
return worktrees;
|
|
8748
8764
|
}, { signal: options?.abortSignal });
|
|
8749
8765
|
}
|
|
8766
|
+
async function inspectGitBusyState(git) {
|
|
8767
|
+
const toplevel = (await git.raw(["rev-parse", "--show-toplevel"])).trim();
|
|
8768
|
+
const resolveGitPath = async (gitPath) => {
|
|
8769
|
+
const relative = (await git.raw(["rev-parse", "--git-path", gitPath])).trim();
|
|
8770
|
+
return path2.isAbsolute(relative) ? relative : path2.resolve(toplevel, relative);
|
|
8771
|
+
};
|
|
8772
|
+
const pathExists = async (gitPath) => {
|
|
8773
|
+
const resolved = await resolveGitPath(gitPath);
|
|
8774
|
+
try {
|
|
8775
|
+
await fs3.access(resolved);
|
|
8776
|
+
return true;
|
|
8777
|
+
} catch {
|
|
8778
|
+
return false;
|
|
8779
|
+
}
|
|
8780
|
+
};
|
|
8781
|
+
const dirExists = async (gitPath) => {
|
|
8782
|
+
const resolved = await resolveGitPath(gitPath);
|
|
8783
|
+
try {
|
|
8784
|
+
const stat4 = await fs3.stat(resolved);
|
|
8785
|
+
return stat4.isDirectory();
|
|
8786
|
+
} catch {
|
|
8787
|
+
return false;
|
|
8788
|
+
}
|
|
8789
|
+
};
|
|
8790
|
+
if (await dirExists("rebase-merge") || await dirExists("rebase-apply")) {
|
|
8791
|
+
return { busy: true, operation: "rebase" };
|
|
8792
|
+
}
|
|
8793
|
+
if (await pathExists("MERGE_HEAD")) {
|
|
8794
|
+
return { busy: true, operation: "merge" };
|
|
8795
|
+
}
|
|
8796
|
+
if (await pathExists("CHERRY_PICK_HEAD")) {
|
|
8797
|
+
return { busy: true, operation: "cherry-pick" };
|
|
8798
|
+
}
|
|
8799
|
+
if (await pathExists("REVERT_HEAD")) {
|
|
8800
|
+
return { busy: true, operation: "revert" };
|
|
8801
|
+
}
|
|
8802
|
+
return { busy: false };
|
|
8803
|
+
}
|
|
8750
8804
|
|
|
8751
8805
|
// src/server/agent-server.ts
|
|
8752
8806
|
var import_hono = require("hono");
|
|
@@ -8755,7 +8809,7 @@ var import_zod3 = require("zod");
|
|
|
8755
8809
|
// package.json
|
|
8756
8810
|
var package_default = {
|
|
8757
8811
|
name: "@posthog/agent",
|
|
8758
|
-
version: "2.3.
|
|
8812
|
+
version: "2.3.619",
|
|
8759
8813
|
repository: "https://github.com/PostHog/code",
|
|
8760
8814
|
description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
|
|
8761
8815
|
exports: {
|
|
@@ -11311,8 +11365,7 @@ var ParserManager = class {
|
|
|
11311
11365
|
}
|
|
11312
11366
|
this.queryCache.set(cacheKey, query2);
|
|
11313
11367
|
return query2;
|
|
11314
|
-
} catch
|
|
11315
|
-
warn("Query compilation failed", err2);
|
|
11368
|
+
} catch {
|
|
11316
11369
|
this.failedQueries.add(cacheKey);
|
|
11317
11370
|
return null;
|
|
11318
11371
|
}
|
|
@@ -13698,6 +13751,23 @@ function tryParsePartialJson(s) {
|
|
|
13698
13751
|
return null;
|
|
13699
13752
|
}
|
|
13700
13753
|
|
|
13754
|
+
// src/adapters/error-classification.ts
|
|
13755
|
+
var UPSTREAM_PROVIDER_ERROR_STATUS_PATTERN = /API Error:\s*(?:429|5\d\d)\b/i;
|
|
13756
|
+
function classifyAgentError(result) {
|
|
13757
|
+
if (!result) return "agent_error";
|
|
13758
|
+
const text2 = result.trim();
|
|
13759
|
+
if (/API Error:\s*terminated\b/i.test(text2)) {
|
|
13760
|
+
return "upstream_stream_terminated";
|
|
13761
|
+
}
|
|
13762
|
+
if (/API Error:\s*Connection error\b/i.test(text2)) {
|
|
13763
|
+
return "upstream_connection_error";
|
|
13764
|
+
}
|
|
13765
|
+
if (UPSTREAM_PROVIDER_ERROR_STATUS_PATTERN.test(text2)) {
|
|
13766
|
+
return "upstream_provider_failure";
|
|
13767
|
+
}
|
|
13768
|
+
return "agent_error";
|
|
13769
|
+
}
|
|
13770
|
+
|
|
13701
13771
|
// src/adapters/claude/permissions/posthog-exec-gate.ts
|
|
13702
13772
|
var POSTHOG_EXEC_TOOL_RE = /^mcp__posthog(?:_[^_]+)*__exec$/;
|
|
13703
13773
|
var POSTHOG_CALL_COMMAND_RE = /^\s*call\s+(?:--json\s+)?([a-zA-Z0-9_-]+)/;
|
|
@@ -13894,7 +13964,7 @@ var createPreToolUseHook = (settingsManager, logger) => async (input, _toolUseID
|
|
|
13894
13964
|
};
|
|
13895
13965
|
|
|
13896
13966
|
// src/adapters/claude/conversion/tool-use-to-acp.ts
|
|
13897
|
-
var
|
|
13967
|
+
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
13898
13968
|
var import_node_path3 = __toESM(require("path"), 1);
|
|
13899
13969
|
|
|
13900
13970
|
// src/adapters/claude/mcp/tool-metadata.ts
|
|
@@ -14128,7 +14198,7 @@ function toolInfoFromToolUse(toolUse, options) {
|
|
|
14128
14198
|
oldContent = options.cachedFileContent[writeFilePath];
|
|
14129
14199
|
} else {
|
|
14130
14200
|
try {
|
|
14131
|
-
oldContent =
|
|
14201
|
+
oldContent = import_node_fs2.default.readFileSync(writeFilePath, "utf-8");
|
|
14132
14202
|
} catch {
|
|
14133
14203
|
}
|
|
14134
14204
|
}
|
|
@@ -14542,7 +14612,7 @@ function resolveFileContent(filePath, oldText, cachedFileContent) {
|
|
|
14542
14612
|
}
|
|
14543
14613
|
}
|
|
14544
14614
|
try {
|
|
14545
|
-
const content =
|
|
14615
|
+
const content = import_node_fs2.default.readFileSync(filePath, "utf-8");
|
|
14546
14616
|
if (content.includes(oldText)) {
|
|
14547
14617
|
return content;
|
|
14548
14618
|
}
|
|
@@ -15014,17 +15084,6 @@ async function handleSystemMessage(message, context) {
|
|
|
15014
15084
|
break;
|
|
15015
15085
|
}
|
|
15016
15086
|
}
|
|
15017
|
-
function classifyAgentError(result) {
|
|
15018
|
-
if (!result) return "agent_error";
|
|
15019
|
-
const text2 = result.trim();
|
|
15020
|
-
if (/API Error:\s*terminated\b/i.test(text2)) {
|
|
15021
|
-
return "upstream_stream_terminated";
|
|
15022
|
-
}
|
|
15023
|
-
if (/API Error:\s*Connection error\b/i.test(text2)) {
|
|
15024
|
-
return "upstream_connection_error";
|
|
15025
|
-
}
|
|
15026
|
-
return "agent_error";
|
|
15027
|
-
}
|
|
15028
15087
|
function handleResultMessage(message) {
|
|
15029
15088
|
const usage = extractUsageFromResult(message);
|
|
15030
15089
|
switch (message.subtype) {
|
|
@@ -16086,7 +16145,7 @@ function parseMcpServers(params) {
|
|
|
16086
16145
|
}
|
|
16087
16146
|
|
|
16088
16147
|
// src/adapters/claude/session/options.ts
|
|
16089
|
-
var
|
|
16148
|
+
var import_node_child_process3 = require("child_process");
|
|
16090
16149
|
var fs7 = __toESM(require("fs"), 1);
|
|
16091
16150
|
var os3 = __toESM(require("os"), 1);
|
|
16092
16151
|
var path9 = __toESM(require("path"), 1);
|
|
@@ -16234,7 +16293,7 @@ function getAbortController(userProvidedController) {
|
|
|
16234
16293
|
}
|
|
16235
16294
|
function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited, logger) {
|
|
16236
16295
|
return (spawnOpts) => {
|
|
16237
|
-
const child = (0,
|
|
16296
|
+
const child = (0, import_node_child_process3.spawn)(spawnOpts.command, spawnOpts.args, {
|
|
16238
16297
|
cwd: spawnOpts.cwd,
|
|
16239
16298
|
env: spawnOpts.env,
|
|
16240
16299
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -17907,7 +17966,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
|
|
|
17907
17966
|
};
|
|
17908
17967
|
|
|
17909
17968
|
// src/adapters/codex/codex-agent.ts
|
|
17910
|
-
var
|
|
17969
|
+
var import_node_fs4 = require("fs");
|
|
17911
17970
|
var import_node_path5 = require("path");
|
|
17912
17971
|
var import_sdk3 = require("@agentclientprotocol/sdk");
|
|
17913
17972
|
|
|
@@ -18192,8 +18251,8 @@ function parseCodexToml(content, cwd) {
|
|
|
18192
18251
|
}
|
|
18193
18252
|
|
|
18194
18253
|
// src/adapters/codex/spawn.ts
|
|
18195
|
-
var
|
|
18196
|
-
var
|
|
18254
|
+
var import_node_child_process4 = require("child_process");
|
|
18255
|
+
var import_node_fs3 = require("fs");
|
|
18197
18256
|
var import_node_path4 = require("path");
|
|
18198
18257
|
function buildConfigArgs(options) {
|
|
18199
18258
|
const args2 = [];
|
|
@@ -18225,7 +18284,7 @@ function buildConfigArgs(options) {
|
|
|
18225
18284
|
}
|
|
18226
18285
|
function findCodexBinary(options) {
|
|
18227
18286
|
const configArgs = buildConfigArgs(options);
|
|
18228
|
-
if (options.binaryPath && (0,
|
|
18287
|
+
if (options.binaryPath && (0, import_node_fs3.existsSync)(options.binaryPath)) {
|
|
18229
18288
|
return { command: options.binaryPath, args: configArgs };
|
|
18230
18289
|
}
|
|
18231
18290
|
if (options.binaryPath) {
|
|
@@ -18244,7 +18303,7 @@ function spawnCodexProcess(options) {
|
|
|
18244
18303
|
env.POSTHOG_GATEWAY_API_KEY = options.apiKey;
|
|
18245
18304
|
}
|
|
18246
18305
|
const { command, args: args2 } = findCodexBinary(options);
|
|
18247
|
-
if (options.binaryPath && (0,
|
|
18306
|
+
if (options.binaryPath && (0, import_node_fs3.existsSync)(options.binaryPath)) {
|
|
18248
18307
|
const binDir = (0, import_node_path4.dirname)(options.binaryPath);
|
|
18249
18308
|
env.PATH = `${binDir}${import_node_path4.delimiter}${env.PATH ?? ""}`;
|
|
18250
18309
|
}
|
|
@@ -18256,7 +18315,7 @@ function spawnCodexProcess(options) {
|
|
|
18256
18315
|
hasApiKey: !!options.apiKey,
|
|
18257
18316
|
binaryPath: options.binaryPath
|
|
18258
18317
|
});
|
|
18259
|
-
const child = (0,
|
|
18318
|
+
const child = (0, import_node_child_process4.spawn)(command, args2, {
|
|
18260
18319
|
cwd: options.cwd,
|
|
18261
18320
|
env,
|
|
18262
18321
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -18315,6 +18374,17 @@ function prependPrContext(params) {
|
|
|
18315
18374
|
prompt: [{ type: "text", text: prContext }, ...params.prompt]
|
|
18316
18375
|
};
|
|
18317
18376
|
}
|
|
18377
|
+
function classifyPromptError(error) {
|
|
18378
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
18379
|
+
const classification = classifyAgentError(message);
|
|
18380
|
+
if (classification === "agent_error") {
|
|
18381
|
+
return error;
|
|
18382
|
+
}
|
|
18383
|
+
return import_sdk3.RequestError.internalError(
|
|
18384
|
+
{ classification, result: message },
|
|
18385
|
+
message
|
|
18386
|
+
);
|
|
18387
|
+
}
|
|
18318
18388
|
var CODEX_NATIVE_MODE = {
|
|
18319
18389
|
auto: "auto",
|
|
18320
18390
|
default: "auto",
|
|
@@ -18345,7 +18415,7 @@ function resolveStructuredOutputMcpScript() {
|
|
|
18345
18415
|
let dir = import_meta2.dirname ?? __dirname;
|
|
18346
18416
|
for (let i2 = 0; i2 < 5; i2++) {
|
|
18347
18417
|
const candidate = (0, import_node_path5.resolve)(dir, rel);
|
|
18348
|
-
if ((0,
|
|
18418
|
+
if ((0, import_node_fs4.existsSync)(candidate)) return candidate;
|
|
18349
18419
|
dir = (0, import_node_path5.resolve)(dir, "..");
|
|
18350
18420
|
}
|
|
18351
18421
|
throw new Error(
|
|
@@ -18644,6 +18714,8 @@ var CodexAcpAgent = class extends BaseAcpAgent {
|
|
|
18644
18714
|
let response;
|
|
18645
18715
|
try {
|
|
18646
18716
|
response = await this.codexConnection.prompt(prependPrContext(params));
|
|
18717
|
+
} catch (error) {
|
|
18718
|
+
throw classifyPromptError(error);
|
|
18647
18719
|
} finally {
|
|
18648
18720
|
this.session.promptRunning = false;
|
|
18649
18721
|
}
|
|
@@ -18979,7 +19051,7 @@ var import_node_os2 = require("os");
|
|
|
18979
19051
|
var import_node_path7 = require("path");
|
|
18980
19052
|
|
|
18981
19053
|
// ../git/dist/handoff.js
|
|
18982
|
-
var
|
|
19054
|
+
var import_node_child_process5 = require("child_process");
|
|
18983
19055
|
var import_promises2 = require("fs/promises");
|
|
18984
19056
|
var import_node_os = require("os");
|
|
18985
19057
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
@@ -19145,7 +19217,7 @@ var GitSaga = class extends Saga {
|
|
|
19145
19217
|
return manager.executeWrite(input.baseDir, async (git) => {
|
|
19146
19218
|
this._git = git;
|
|
19147
19219
|
return this.executeGitOperations(input);
|
|
19148
|
-
}, { signal: input.signal });
|
|
19220
|
+
}, { signal: input.signal, env: input.env });
|
|
19149
19221
|
}
|
|
19150
19222
|
};
|
|
19151
19223
|
|
|
@@ -19257,42 +19329,7 @@ async function hasUnmergedEntries(git) {
|
|
|
19257
19329
|
return output.trim().length > 0;
|
|
19258
19330
|
}
|
|
19259
19331
|
async function getGitBusyState(git) {
|
|
19260
|
-
|
|
19261
|
-
const resolveGitPath = async (gitPath) => {
|
|
19262
|
-
const relative = (await git.raw(["rev-parse", "--git-path", gitPath])).trim();
|
|
19263
|
-
return path13.isAbsolute(relative) ? relative : path13.resolve(toplevel, relative);
|
|
19264
|
-
};
|
|
19265
|
-
const pathExists = async (gitPath) => {
|
|
19266
|
-
const resolved = await resolveGitPath(gitPath);
|
|
19267
|
-
try {
|
|
19268
|
-
await fs11.access(resolved);
|
|
19269
|
-
return true;
|
|
19270
|
-
} catch {
|
|
19271
|
-
return false;
|
|
19272
|
-
}
|
|
19273
|
-
};
|
|
19274
|
-
const dirExists = async (gitPath) => {
|
|
19275
|
-
const resolved = await resolveGitPath(gitPath);
|
|
19276
|
-
try {
|
|
19277
|
-
const stat4 = await fs11.stat(resolved);
|
|
19278
|
-
return stat4.isDirectory();
|
|
19279
|
-
} catch {
|
|
19280
|
-
return false;
|
|
19281
|
-
}
|
|
19282
|
-
};
|
|
19283
|
-
if (await dirExists("rebase-merge") || await dirExists("rebase-apply")) {
|
|
19284
|
-
return { busy: true, operation: "rebase" };
|
|
19285
|
-
}
|
|
19286
|
-
if (await pathExists("MERGE_HEAD")) {
|
|
19287
|
-
return { busy: true, operation: "merge" };
|
|
19288
|
-
}
|
|
19289
|
-
if (await pathExists("CHERRY_PICK_HEAD")) {
|
|
19290
|
-
return { busy: true, operation: "cherry-pick" };
|
|
19291
|
-
}
|
|
19292
|
-
if (await pathExists("REVERT_HEAD")) {
|
|
19293
|
-
return { busy: true, operation: "revert" };
|
|
19294
|
-
}
|
|
19295
|
-
return { busy: false };
|
|
19332
|
+
return inspectGitBusyState(git);
|
|
19296
19333
|
}
|
|
19297
19334
|
var MAX_WORKTREE_FILE_BYTES = 1024 * 1024;
|
|
19298
19335
|
async function createWorktreeTree(git, baseDir, head) {
|
|
@@ -19794,7 +19831,7 @@ var GitHandoffTracker = class {
|
|
|
19794
19831
|
}
|
|
19795
19832
|
async runGitProcessAllowingFailure(args2) {
|
|
19796
19833
|
return new Promise((resolve7, reject) => {
|
|
19797
|
-
const child = (0,
|
|
19834
|
+
const child = (0, import_node_child_process5.spawn)("git", args2, {
|
|
19798
19835
|
cwd: this.repositoryPath,
|
|
19799
19836
|
stdio: ["ignore", "ignore", "pipe"]
|
|
19800
19837
|
});
|
|
@@ -19818,7 +19855,7 @@ var GitHandoffTracker = class {
|
|
|
19818
19855
|
}
|
|
19819
19856
|
async runGitWithEnv(env, args2) {
|
|
19820
19857
|
return new Promise((resolve7, reject) => {
|
|
19821
|
-
const child = (0,
|
|
19858
|
+
const child = (0, import_node_child_process5.spawn)("git", args2, {
|
|
19822
19859
|
cwd: this.repositoryPath,
|
|
19823
19860
|
stdio: ["ignore", "pipe", "pipe"],
|
|
19824
19861
|
env
|
|
@@ -19843,7 +19880,7 @@ var GitHandoffTracker = class {
|
|
|
19843
19880
|
}
|
|
19844
19881
|
runGitProcess(args2, input) {
|
|
19845
19882
|
return new Promise((resolve7, reject) => {
|
|
19846
|
-
const child = (0,
|
|
19883
|
+
const child = (0, import_node_child_process5.spawn)("git", args2, {
|
|
19847
19884
|
cwd: this.repositoryPath,
|
|
19848
19885
|
stdio: "pipe"
|
|
19849
19886
|
});
|
|
@@ -20695,7 +20732,7 @@ ${toolSummary}`);
|
|
|
20695
20732
|
}
|
|
20696
20733
|
|
|
20697
20734
|
// src/session-log-writer.ts
|
|
20698
|
-
var
|
|
20735
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
20699
20736
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
20700
20737
|
var import_node_path8 = __toESM(require("path"), 1);
|
|
20701
20738
|
var SessionLogWriter = class _SessionLogWriter {
|
|
@@ -20739,7 +20776,7 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20739
20776
|
context.runId
|
|
20740
20777
|
);
|
|
20741
20778
|
try {
|
|
20742
|
-
|
|
20779
|
+
import_node_fs5.default.mkdirSync(sessionDir, { recursive: true });
|
|
20743
20780
|
} catch (error) {
|
|
20744
20781
|
this.logger.warn("Failed to create local cache directory", {
|
|
20745
20782
|
sessionDir,
|
|
@@ -20998,7 +21035,7 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
20998
21035
|
"logs.ndjson"
|
|
20999
21036
|
);
|
|
21000
21037
|
try {
|
|
21001
|
-
|
|
21038
|
+
import_node_fs5.default.appendFileSync(logPath, `${JSON.stringify(entry)}
|
|
21002
21039
|
`);
|
|
21003
21040
|
} catch (error) {
|
|
21004
21041
|
this.logger.warn("Failed to write to local cache", {
|
|
@@ -21033,11 +21070,11 @@ var SessionLogWriter = class _SessionLogWriter {
|
|
|
21033
21070
|
};
|
|
21034
21071
|
|
|
21035
21072
|
// src/server/agentsh-runtime.ts
|
|
21036
|
-
var
|
|
21073
|
+
var import_node_child_process6 = require("child_process");
|
|
21037
21074
|
var import_promises5 = require("fs/promises");
|
|
21038
21075
|
var import_node_util2 = require("util");
|
|
21039
21076
|
var AGENTSH_SESSION_ID_FILE = "/tmp/agentsh-session-id";
|
|
21040
|
-
var execFileAsync2 = (0, import_node_util2.promisify)(
|
|
21077
|
+
var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process6.execFile);
|
|
21041
21078
|
function errorMessage(error) {
|
|
21042
21079
|
return error instanceof Error ? error.message : String(error);
|
|
21043
21080
|
}
|
|
@@ -21257,8 +21294,15 @@ function validateCommandParams(method, params) {
|
|
|
21257
21294
|
var agentErrorClassificationSchema = import_zod3.z.enum([
|
|
21258
21295
|
"upstream_stream_terminated",
|
|
21259
21296
|
"upstream_connection_error",
|
|
21297
|
+
"upstream_provider_failure",
|
|
21260
21298
|
"agent_error"
|
|
21261
21299
|
]);
|
|
21300
|
+
var UPSTREAM_PROVIDER_FAILURE_MESSAGE = "The upstream AI provider failed to process the request. Please retry the task in a few minutes.";
|
|
21301
|
+
var upstreamProviderFailureClassifications = /* @__PURE__ */ new Set([
|
|
21302
|
+
"upstream_stream_terminated",
|
|
21303
|
+
"upstream_connection_error",
|
|
21304
|
+
"upstream_provider_failure"
|
|
21305
|
+
]);
|
|
21262
21306
|
var errorWithClassificationSchema = import_zod3.z.object({
|
|
21263
21307
|
data: import_zod3.z.object({ classification: agentErrorClassificationSchema })
|
|
21264
21308
|
});
|
|
@@ -22002,7 +22046,9 @@ var AgentServer = class {
|
|
|
22002
22046
|
}
|
|
22003
22047
|
classifyAndSignalFailure(payload, phase, error) {
|
|
22004
22048
|
const { classification, message } = this.extractErrorClassification(error);
|
|
22005
|
-
const errorMessage2 =
|
|
22049
|
+
const errorMessage2 = upstreamProviderFailureClassifications.has(
|
|
22050
|
+
classification
|
|
22051
|
+
) ? UPSTREAM_PROVIDER_FAILURE_MESSAGE : message || "Agent error";
|
|
22006
22052
|
this.logger.error(`send_${phase}_task_message_failed`, {
|
|
22007
22053
|
classification,
|
|
22008
22054
|
message
|
|
@@ -22440,9 +22486,14 @@ After completing the requested changes:
|
|
|
22440
22486
|
1. Check out the existing PR branch with \`gh pr checkout ${prUrl}\`
|
|
22441
22487
|
2. Stage and commit all changes with a clear commit message
|
|
22442
22488
|
3. Push to the existing PR branch
|
|
22489
|
+
4. For every PR review comment or review thread you addressed, treat the thread as done only after BOTH of these:
|
|
22490
|
+
- Reply on the thread with a short note describing what changed (reference the commit SHA when useful) using \`gh api -X POST /repos/{owner}/{repo}/pulls/{n}/comments/{id}/replies -f body='...'\`.
|
|
22491
|
+
- Resolve the thread via the \`resolveReviewThread\` GraphQL mutation: \`gh api graphql -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' -f id="<thread-node-id>"\`.
|
|
22492
|
+
List unresolved threads first with \`gh api graphql -f query='{repository(owner:"<owner>",name:"<repo>"){pullRequest(number:<n>){reviewThreads(first:100){nodes{id isResolved comments(first:1){nodes{body}}}}}}}'\` so you can resolve each one you fixed.
|
|
22443
22493
|
|
|
22444
22494
|
Important:
|
|
22445
22495
|
- Do NOT create a new branch or a new pull request.
|
|
22496
|
+
- Do NOT push fixes for review comments without replying to and resolving each related thread.
|
|
22446
22497
|
${attributionInstructions}
|
|
22447
22498
|
`;
|
|
22448
22499
|
}
|
|
@@ -22454,7 +22505,7 @@ When the user asks for code changes:
|
|
|
22454
22505
|
When the user explicitly asks to clone or work in a GitHub repository:
|
|
22455
22506
|
- Clone the repository into /tmp/workspace/repos/<owner>/<repo> using \`gh repo clone <owner>/<repo> /tmp/workspace/repos/<owner>/<repo>\`
|
|
22456
22507
|
- Work from inside that cloned repository for follow-up code changes
|
|
22457
|
-
- If the user explicitly asks you to open or update a pull request, create a branch, commit the requested changes, push it, and open a draft pull request from inside the clone
|
|
22508
|
+
- If the user explicitly asks you to open or update a pull request, create a branch, commit the requested changes, push it, and open a draft pull request from inside the clone. Before opening the PR, check the cloned repo for a PR template at \`.github/pull_request_template.md\` (or variants; fall back to the org's \`.github\` repo via \`gh api\`) and use it as the body structure, and search for matching open issues with \`gh issue list --search\` to include \`Closes #<n>\` / \`Refs #<n>\` links.
|
|
22458
22509
|
- Do NOT create branches, commits, push changes, or open pull requests unless the user explicitly asks for that`;
|
|
22459
22510
|
return `
|
|
22460
22511
|
# Cloud Task Execution \u2014 No Repository Mode
|
|
@@ -22494,7 +22545,11 @@ After completing the requested changes:
|
|
|
22494
22545
|
1. Create a new branch prefixed with \`posthog-code/\` (e.g. \`posthog-code/fix-login-redirect\`) based on the work done
|
|
22495
22546
|
2. Stage and commit all changes with a clear commit message
|
|
22496
22547
|
3. Push the branch to origin
|
|
22497
|
-
4.
|
|
22548
|
+
4. Before opening the PR, prepare the body:
|
|
22549
|
+
- Check the repo for a PR template at \`.github/pull_request_template.md\` (also try \`.github/PULL_REQUEST_TEMPLATE.md\`, \`docs/pull_request_template.md\`, and root variants). If one exists, use its exact section headings as the PR body \u2014 do NOT fall back to a generic Summary/Test plan format.
|
|
22550
|
+
- If no repo-level template exists, check the org's \`.github\` repo via \`gh api /repos/<owner>/.github/contents/.github/pull_request_template.md\` (and other common paths) and use that as a fallback.
|
|
22551
|
+
- Search for matching open issues with \`gh issue list --state open --search '<keywords>'\` (derive keywords from the branch name, commits, and changed files; \`gh issue view <n>\` to confirm relevance). For every issue this PR would resolve, include a \`Closes #<n>\` line in the body so GitHub auto-links and auto-closes it on merge. For issues that are related but not fully resolved, use \`Refs #<n>\` instead.
|
|
22552
|
+
5. Create a draft pull request using \`gh pr create --draft${this.config.baseBranch ? ` --base ${this.config.baseBranch}` : ""}\` with a descriptive title and the body prepared above. Add the following footer at the end of the PR description:
|
|
22498
22553
|
\`\`\`
|
|
22499
22554
|
---
|
|
22500
22555
|
*Created with [PostHog Code](https://posthog.com/code?ref=pr)*
|