@rallycry/conveyor-agent 8.5.0 → 8.5.1
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/{chunk-63FTZOL5.js → chunk-6B545CHM.js} +126 -9
- package/dist/chunk-6B545CHM.js.map +1 -0
- package/dist/{chunk-3T4SJEH6.js → chunk-WZCO64YR.js} +167 -52
- package/dist/chunk-WZCO64YR.js.map +1 -0
- package/dist/cli.js +23 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +16 -3
- package/dist/index.js +2 -2
- package/dist/{tag-audit-handler-PKYLDJHH.js → tag-audit-handler-3IFB7YDV.js} +2 -2
- package/dist/{task-audit-handler-WINYLZMU.js → task-audit-handler-U5Q52YT2.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-3T4SJEH6.js.map +0 -1
- package/dist/chunk-63FTZOL5.js.map +0 -1
- /package/dist/{tag-audit-handler-PKYLDJHH.js.map → tag-audit-handler-3IFB7YDV.js.map} +0 -0
- /package/dist/{task-audit-handler-WINYLZMU.js.map → task-audit-handler-U5Q52YT2.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
loadForwardPorts,
|
|
10
10
|
runSetupCommand,
|
|
11
11
|
runStartCommand
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WZCO64YR.js";
|
|
13
13
|
import "./chunk-FDWECEDJ.js";
|
|
14
14
|
import {
|
|
15
15
|
createServiceLogger
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-6B545CHM.js";
|
|
17
17
|
|
|
18
18
|
// src/cli.ts
|
|
19
19
|
import { readFileSync } from "fs";
|
|
@@ -224,19 +224,28 @@ if (CONVEYOR_PROJECT_TOKEN && CONVEYOR_PROJECT_ID) {
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
);
|
|
227
|
+
const skipShutdownFlush = process.env.CONVEYOR_SKIP_SHUTDOWN_GIT_FLUSH === "true";
|
|
227
228
|
const shutdownAgent = (signal) => {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
229
|
+
if (skipShutdownFlush) {
|
|
230
|
+
logger.info(`Received ${signal}, stopping agent (git flush handled by project runner)`);
|
|
231
|
+
runner.stop();
|
|
232
|
+
} else {
|
|
233
|
+
logger.info(`Received ${signal}, flushing git and stopping agent`);
|
|
234
|
+
void (async () => {
|
|
235
|
+
try {
|
|
236
|
+
await runner.flushGitOnShutdown();
|
|
237
|
+
} finally {
|
|
238
|
+
runner.stop();
|
|
239
|
+
}
|
|
240
|
+
})();
|
|
241
|
+
}
|
|
242
|
+
setTimeout(
|
|
243
|
+
() => {
|
|
244
|
+
logger.warn(`Forcing exit after ${signal} timeout`);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
},
|
|
247
|
+
skipShutdownFlush ? 1e4 : 45e3
|
|
248
|
+
).unref();
|
|
240
249
|
};
|
|
241
250
|
process.on("SIGTERM", () => shutdownAgent("SIGTERM"));
|
|
242
251
|
process.on("SIGINT", () => shutdownAgent("SIGINT"));
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/utils/session-identity.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { SessionRunner } from \"./runner/session-runner.js\";\nimport { ProjectRunner } from \"./runner/project-runner.js\";\nimport type { AgentRunnerStatus, RunnerMode } from \"@project/shared\";\nimport { createServiceLogger } from \"./utils/logger.js\";\nimport {\n applyBootstrapToEnv,\n buildSessionPreviewPorts,\n fetchBootstrap,\n loadConveyorConfig,\n loadForwardPorts,\n runSetupCommand,\n runStartCommand,\n} from \"./setup/index.js\";\nimport { checkSessionTaskIdentity } from \"./utils/session-identity.js\";\n\n// Handle --version flag before any other initialization\nif (process.argv.includes(\"--version\")) {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkgPath = join(__dirname, \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n process.stdout.write(pkg.version + \"\\n\");\n process.exit(0);\n}\n\nconst logger = createServiceLogger(\"CLI\");\n\nasync function bootstrapFromCodespace(apiUrl: string, instanceName: string): Promise<void> {\n const bootstrapToken = process.env.CONVEYOR_BOOTSTRAP_TOKEN;\n const apiUrlFromEnv = Boolean(process.env.CONVEYOR_API_URL);\n logger.info(\"Bootstrapping from codespace\", {\n codespace: instanceName,\n apiUrl,\n apiUrlFromEnv,\n bootstrapTokenPresent: Boolean(bootstrapToken),\n });\n const result = await fetchBootstrap({\n apiUrl,\n instanceName,\n bootstrapToken,\n });\n if (!result.ok) {\n logger.error(\"Bootstrap failed after retries\", {\n reason: result.reason,\n attempts: result.attempts,\n status: result.status,\n detail: result.detail,\n apiUrl,\n apiUrlFromEnv,\n bootstrapTokenPresent: Boolean(bootstrapToken),\n hint: apiUrlFromEnv\n ? \"Verify the codespace was created by this Conveyor deployment and that the bootstrap token is current.\"\n : \"CONVEYOR_API_URL was not set as a codespace secret — agent fell back to the built-in default. Re-create the codespace, or push CONVEYOR_API_URL via project settings.\",\n });\n process.exit(1);\n }\n applyBootstrapToEnv(result.config);\n if (result.config.mode === \"project\") {\n logger.info(\"Bootstrap complete (project mode)\", {\n projectId: result.config.projectId,\n attempts: result.attempts,\n });\n } else {\n logger.info(\"Bootstrap complete\", {\n taskId: result.config.taskId,\n attempts: result.attempts,\n });\n }\n}\n\n// Helper to detect expected abort errors from SDK cleanup\nfunction isExpectedAbortError(error: Error | NodeJS.ErrnoException): boolean {\n const message = error.message || \"\";\n const hasAbortMessage = /operation aborted/i.test(message) || /abort/i.test(message);\n const hasAbortCode = !(\"code\" in error) || error.code === undefined || error.code === \"ABORT_ERR\";\n return hasAbortMessage && hasAbortCode;\n}\n\nprocess.on(\"uncaughtException\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EPIPE\") return;\n\n if (isExpectedAbortError(err)) {\n logger.info(\"Ignored expected abort after shutdown\", { error: err.message, code: err.code });\n return;\n }\n\n logger.error(\"Uncaught exception\", { error: err.message, code: err.code });\n process.exit(1);\n});\n\nprocess.on(\"unhandledRejection\", (reason: unknown) => {\n const err = reason instanceof Error ? reason : new Error(String(reason));\n\n if (isExpectedAbortError(err)) {\n logger.info(\"Ignored expected abort rejection after shutdown\", { error: err.message });\n return;\n }\n\n logger.error(\"Unhandled rejection\", { error: err.message });\n process.exit(1);\n});\n\nconst DEFAULT_CONVEYOR_API_URL = \"https://api.conveyor.rallycryapp.com\";\nlet conveyorApiUrl = process.env.CONVEYOR_API_URL || DEFAULT_CONVEYOR_API_URL;\n\n// Step 1: Codespace bootstrap\nconst INSTANCE_NAME = process.env.CODESPACE_NAME || process.env.CLAUDESPACE_NAME;\nif (INSTANCE_NAME && !process.env.CONVEYOR_TASK_TOKEN && !process.env.CONVEYOR_PROJECT_TOKEN) {\n if (!conveyorApiUrl) {\n logger.error(\"Could not resolve CONVEYOR_API_URL for codespace bootstrap\");\n process.exit(1);\n }\n await bootstrapFromCodespace(conveyorApiUrl, INSTANCE_NAME);\n conveyorApiUrl = process.env.CONVEYOR_API_URL ?? conveyorApiUrl;\n}\n\n// Step 2: Read env vars (bootstrap may have set them)\nconst CONVEYOR_PROJECT_TOKEN = process.env.CONVEYOR_PROJECT_TOKEN;\nconst CONVEYOR_PROJECT_ID = process.env.CONVEYOR_PROJECT_ID;\n\n// Step 3: Branch on mode\nif (CONVEYOR_PROJECT_TOKEN && CONVEYOR_PROJECT_ID) {\n const CONVEYOR_PROJECT_DIR = process.env.CONVEYOR_WORKSPACE ?? process.cwd();\n\n if (!conveyorApiUrl) {\n logger.error(\"Could not resolve CONVEYOR_API_URL for project runner mode\");\n process.exit(1);\n }\n\n logger.info(\"Starting project runner\", { projectId: CONVEYOR_PROJECT_ID });\n\n const runner = new ProjectRunner({\n conveyorApiUrl,\n projectToken: CONVEYOR_PROJECT_TOKEN,\n projectId: CONVEYOR_PROJECT_ID,\n projectDir: CONVEYOR_PROJECT_DIR,\n });\n\n process.on(\"SIGTERM\", () => {\n logger.info(\"Received SIGTERM, stopping project runner\");\n void runner.stop();\n setTimeout(() => {\n logger.warn(\"Forcing exit after SIGTERM timeout\");\n process.exit(1);\n }, 40_000).unref();\n });\n\n process.on(\"SIGINT\", () => {\n logger.info(\"Received SIGINT, stopping project runner\");\n void runner.stop();\n setTimeout(() => {\n logger.warn(\"Forcing exit after SIGINT timeout\");\n process.exit(1);\n }, 40_000).unref();\n });\n\n runner\n .start()\n .then(() => {\n // start() resolves once stop() resolves the lifecycle promise (UI disconnect,\n // shutdown signal, or SIGINT/SIGTERM). Exit so the terminal returns to the shell\n // instead of hanging on lingering socket.io/PTY handles.\n process.exit(0);\n })\n .catch((error: unknown) => {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(\"Project runner failed\", { error: msg });\n process.exit(1);\n });\n} else {\n const CONVEYOR_TASK_TOKEN = process.env.CONVEYOR_TASK_TOKEN;\n const CONVEYOR_TASK_ID = process.env.CONVEYOR_TASK_ID;\n const CONVEYOR_WORKSPACE = process.env.CONVEYOR_WORKSPACE ?? process.cwd();\n const CONVEYOR_MODE = (process.env.CONVEYOR_MODE ?? \"task\") as RunnerMode;\n const CONVEYOR_AGENT_MODE = process.env.CONVEYOR_AGENT_MODE || undefined;\n const CONVEYOR_IS_AUTO = CONVEYOR_AGENT_MODE\n ? CONVEYOR_AGENT_MODE === \"auto\"\n : process.env.CONVEYOR_IS_AUTO === \"true\";\n\n if (!CONVEYOR_TASK_TOKEN || !CONVEYOR_TASK_ID) {\n logger.error(\"Missing required environment variables\");\n logger.error(\" CONVEYOR_TASK_TOKEN - JWT token for task authentication\");\n logger.error(\" CONVEYOR_TASK_ID - ID of the task to execute\");\n logger.error(\"\");\n logger.error(\"CONVEYOR_API_URL is provided via codespace secret or bootstrap.\");\n logger.error(\"\");\n logger.error(\"Optional:\");\n logger.error(\" CONVEYOR_MODE - Runner mode: 'task' (default) or 'pm'\");\n logger.error(\" CONVEYOR_WORKSPACE - Working directory (defaults to cwd)\");\n process.exit(1);\n }\n\n if (CONVEYOR_MODE !== \"task\" && CONVEYOR_MODE !== \"pm\" && CONVEYOR_MODE !== \"code-review\") {\n logger.error(\"Invalid CONVEYOR_MODE\", {\n mode: CONVEYOR_MODE,\n expected: [\"task\", \"pm\", \"code-review\"],\n });\n process.exit(1);\n }\n\n logger.info(\"Starting agent\", { mode: CONVEYOR_MODE });\n\n // Claudespace pods: longer idle timeout to stay alive for incoming messages.\n // Non-claudespace environments (local, workspace, GitHub Codespaces) have\n // persistent state and don't need the periodic WIP commit safety net, so\n // disable the git flush timer for them.\n const lifecycleOverrides = process.env.CLAUDESPACE_NAME\n ? { idleTimeoutMs: 60 * 60 * 1000 }\n : { gitFlushIntervalMs: 0 };\n\n const runner = new SessionRunner(\n {\n connection: {\n apiUrl: conveyorApiUrl ?? \"\",\n taskToken: CONVEYOR_TASK_TOKEN,\n // CONVEYOR_SESSION_ID is the CodespaceSession ID for BaseService ACL.\n // Falls back to CONVEYOR_TASK_ID for backward compat (codespace bootstrap sets only task ID).\n sessionId: process.env.CONVEYOR_SESSION_ID ?? CONVEYOR_TASK_ID,\n runnerMode: CONVEYOR_MODE,\n },\n runnerMode: CONVEYOR_MODE,\n isAuto: CONVEYOR_IS_AUTO,\n workspaceDir: CONVEYOR_WORKSPACE,\n agentMode: CONVEYOR_AGENT_MODE as import(\"@project/shared\").AgentMode | undefined,\n lifecycle: lifecycleOverrides,\n },\n {\n onStatusChange: (status: AgentRunnerStatus) => {\n logger.info(\"Status changed\", { status });\n },\n onEvent: (event: Record<string, unknown>) => {\n const detail =\n (event.message as string) ?? (event.content as string) ?? (event.summary as string) ?? \"\";\n if (detail) {\n logger.info(detail, { eventType: event.type as string });\n }\n },\n },\n );\n\n const shutdownAgent = (signal: \"SIGTERM\" | \"SIGINT\") => {\n logger.info(`Received ${signal}, flushing git and stopping agent`);\n // Flush WIP commit + push BEFORE stop() tears down the connection, since\n // the token-refresh RPC needs a live socket. Then stop the runner.\n void (async () => {\n try {\n await runner.flushGitOnShutdown();\n } finally {\n runner.stop();\n }\n })();\n setTimeout(() => {\n logger.warn(`Forcing exit after ${signal} timeout`);\n process.exit(1);\n }, 45_000).unref();\n };\n\n process.on(\"SIGTERM\", () => shutdownAgent(\"SIGTERM\"));\n process.on(\"SIGINT\", () => shutdownAgent(\"SIGINT\"));\n\n // Connect first so setup/start output is forwarded to the API\n await runner.connect();\n\n // Defense-in-depth: warn loudly if CONVEYOR_SESSION_ID decodes to a different\n // task than CONVEYOR_TASK_ID. Authoritative checks are server-side\n // (requireTaskAuth + partial-unique index on active CodespaceSessions). This\n // is a visibility net in case those regress — see SEC-9 postmortem in\n // .claude/rules/agent-codespace.md.\n void checkSessionTaskIdentity({\n sessionId: process.env.CONVEYOR_SESSION_ID,\n taskId: CONVEYOR_TASK_ID,\n fetchSessionTaskId: async (sessionId) => {\n const ctx = await runner.connection.call(\"getTaskContext\", { sessionId });\n return ctx.id;\n },\n logger,\n });\n\n // Run setup + start commands in the background so the agent can start\n // fetching context and thinking immediately. The dev environment will be\n // ready by the time the agent needs to actually execute anything in it.\n // Start command still runs after setup (install must finish before `bun\n // run dev` works), but both are decoupled from runner.run().\n //\n // INVARIANT: failures inside this IIFE are NON-FATAL. Any throw or non-zero\n // exit from setup/start must surface as a chat event, never as process.exit.\n // The agent continues so the user can still interact with it and debug.\n const conveyorConfig = loadConveyorConfig();\n if (conveyorConfig) {\n void (async () => {\n const logOutput = (stream: \"stdout\" | \"stderr\", data: string) => {\n runner.connection.sendEvent({ type: \"setup_output\", stream, data });\n (stream === \"stderr\" ? process.stderr : process.stdout).write(data);\n };\n if (conveyorConfig.setupCommand) {\n logger.info(\"Running setup command (background)\", {\n command: conveyorConfig.setupCommand,\n });\n try {\n await runSetupCommand(conveyorConfig.setupCommand, CONVEYOR_WORKSPACE, logOutput);\n logger.info(\"Setup command completed\");\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Setup command failed\";\n logger.error(\"Setup command failed\", { error: msg });\n runner.connection.sendEvent({ type: \"setup_error\", message: msg });\n }\n }\n\n let startCommandRunning = false;\n if (conveyorConfig.startCommand) {\n logger.info(\"Running start command\", { command: conveyorConfig.startCommand });\n const child = runStartCommand(\n conveyorConfig.startCommand,\n CONVEYOR_WORKSPACE,\n (stream, data) => {\n runner.connection.sendEvent({ type: \"start_command_output\", stream, data });\n (stream === \"stderr\" ? process.stderr : process.stdout).write(data);\n },\n );\n startCommandRunning = true;\n child.on(\"exit\", (code, signal) => {\n logger.info(\"Start command exited\", { code, signal });\n runner.connection.sendEvent({\n type: \"start_command_exited\",\n code,\n signal,\n message: `start command exited${code === null ? \"\" : ` with code ${code}`}${signal ? ` (signal: ${signal})` : \"\"}`,\n });\n // Surface non-zero exits as a loud chat message too, so users know\n // their dev server crashed and the agent may hit tool-use failures.\n if (code !== null && code !== 0) {\n runner.connection.sendEvent({\n type: \"start_command_error\",\n message: `start command exited with code ${code}${signal ? ` (signal: ${signal})` : \"\"}`,\n });\n }\n });\n child.on(\"error\", (err) => {\n logger.error(\"Start command error\", { error: err.message });\n runner.connection.sendEvent({ type: \"start_command_error\", message: err.message });\n });\n }\n\n const forwardPorts = await loadForwardPorts(CONVEYOR_WORKSPACE);\n const previewPorts = buildSessionPreviewPorts(forwardPorts);\n runner.connection.sendEvent({\n type: \"setup_complete\",\n startCommandRunning,\n previewPort: conveyorConfig.previewPort,\n ...(previewPorts.length > 0 ? { previewPorts } : {}),\n });\n })();\n }\n\n // Start the main agent lifecycle immediately in parallel with setup\n // (context fetch, mode resolution, core loop).\n runner\n .run()\n .then(() => {\n // Exit with code 0 for clean shutdown (entrypoint won't restart),\n // code 1 for errors (entrypoint will restart).\n process.exit(runner.finalState === \"error\" ? 1 : 0);\n })\n .catch((error: unknown) => {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(\"Agent runner failed\", { error: msg });\n process.exit(1);\n });\n}\n","// Defense-in-depth startup check. The authoritative guarantee that a session is\n// bound to the right task lives server-side (requireTaskAuth + the Postgres\n// partial-unique index on active CodespaceSessions). This check exists so that\n// if those invariants ever regress, a human sees a loud WARN immediately\n// instead of the symptoms SEC-9 produced (multiple agents silently clobbering\n// the same branch).\nexport interface SessionIdentityLogger {\n warn(message: string, data?: Record<string, unknown>): void;\n info?(message: string, data?: Record<string, unknown>): void;\n}\n\nexport interface CheckSessionTaskIdentityParams {\n sessionId: string | undefined;\n taskId: string;\n fetchSessionTaskId: (sessionId: string) => Promise<string>;\n logger: SessionIdentityLogger;\n}\n\nexport async function checkSessionTaskIdentity(\n params: CheckSessionTaskIdentityParams,\n): Promise<\"match\" | \"mismatch\" | \"skipped\" | \"error\"> {\n const { sessionId, taskId, fetchSessionTaskId, logger } = params;\n if (!sessionId || sessionId === taskId) return \"skipped\";\n let sessionTaskId: string;\n try {\n sessionTaskId = await fetchSessionTaskId(sessionId);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n logger.warn(\"Could not verify session/task identity — continuing (defense-in-depth only)\", {\n sessionId,\n taskId,\n error: message,\n });\n return \"error\";\n }\n if (sessionTaskId !== taskId) {\n logger.warn(\n \"!!! CONVEYOR_SESSION_ID is bound to a different task than CONVEYOR_TASK_ID — server-side guards should still block mutations, but this indicates a misconfiguration or replayed token.\",\n { sessionId, envTaskId: taskId, sessionTaskId },\n );\n return \"mismatch\";\n }\n return \"match\";\n}\n"],"mappings":"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","names":["logger"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/utils/session-identity.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { SessionRunner } from \"./runner/session-runner.js\";\nimport { ProjectRunner } from \"./runner/project-runner.js\";\nimport type { AgentRunnerStatus, RunnerMode } from \"@project/shared\";\nimport { createServiceLogger } from \"./utils/logger.js\";\nimport {\n applyBootstrapToEnv,\n buildSessionPreviewPorts,\n fetchBootstrap,\n loadConveyorConfig,\n loadForwardPorts,\n runSetupCommand,\n runStartCommand,\n} from \"./setup/index.js\";\nimport { checkSessionTaskIdentity } from \"./utils/session-identity.js\";\n\n// Handle --version flag before any other initialization\nif (process.argv.includes(\"--version\")) {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkgPath = join(__dirname, \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n process.stdout.write(pkg.version + \"\\n\");\n process.exit(0);\n}\n\nconst logger = createServiceLogger(\"CLI\");\n\nasync function bootstrapFromCodespace(apiUrl: string, instanceName: string): Promise<void> {\n const bootstrapToken = process.env.CONVEYOR_BOOTSTRAP_TOKEN;\n const apiUrlFromEnv = Boolean(process.env.CONVEYOR_API_URL);\n logger.info(\"Bootstrapping from codespace\", {\n codespace: instanceName,\n apiUrl,\n apiUrlFromEnv,\n bootstrapTokenPresent: Boolean(bootstrapToken),\n });\n const result = await fetchBootstrap({\n apiUrl,\n instanceName,\n bootstrapToken,\n });\n if (!result.ok) {\n logger.error(\"Bootstrap failed after retries\", {\n reason: result.reason,\n attempts: result.attempts,\n status: result.status,\n detail: result.detail,\n apiUrl,\n apiUrlFromEnv,\n bootstrapTokenPresent: Boolean(bootstrapToken),\n hint: apiUrlFromEnv\n ? \"Verify the codespace was created by this Conveyor deployment and that the bootstrap token is current.\"\n : \"CONVEYOR_API_URL was not set as a codespace secret — agent fell back to the built-in default. Re-create the codespace, or push CONVEYOR_API_URL via project settings.\",\n });\n process.exit(1);\n }\n applyBootstrapToEnv(result.config);\n if (result.config.mode === \"project\") {\n logger.info(\"Bootstrap complete (project mode)\", {\n projectId: result.config.projectId,\n attempts: result.attempts,\n });\n } else {\n logger.info(\"Bootstrap complete\", {\n taskId: result.config.taskId,\n attempts: result.attempts,\n });\n }\n}\n\n// Helper to detect expected abort errors from SDK cleanup\nfunction isExpectedAbortError(error: Error | NodeJS.ErrnoException): boolean {\n const message = error.message || \"\";\n const hasAbortMessage = /operation aborted/i.test(message) || /abort/i.test(message);\n const hasAbortCode = !(\"code\" in error) || error.code === undefined || error.code === \"ABORT_ERR\";\n return hasAbortMessage && hasAbortCode;\n}\n\nprocess.on(\"uncaughtException\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EPIPE\") return;\n\n if (isExpectedAbortError(err)) {\n logger.info(\"Ignored expected abort after shutdown\", { error: err.message, code: err.code });\n return;\n }\n\n logger.error(\"Uncaught exception\", { error: err.message, code: err.code });\n process.exit(1);\n});\n\nprocess.on(\"unhandledRejection\", (reason: unknown) => {\n const err = reason instanceof Error ? reason : new Error(String(reason));\n\n if (isExpectedAbortError(err)) {\n logger.info(\"Ignored expected abort rejection after shutdown\", { error: err.message });\n return;\n }\n\n logger.error(\"Unhandled rejection\", { error: err.message });\n process.exit(1);\n});\n\nconst DEFAULT_CONVEYOR_API_URL = \"https://api.conveyor.rallycryapp.com\";\nlet conveyorApiUrl = process.env.CONVEYOR_API_URL || DEFAULT_CONVEYOR_API_URL;\n\n// Step 1: Codespace bootstrap\nconst INSTANCE_NAME = process.env.CODESPACE_NAME || process.env.CLAUDESPACE_NAME;\nif (INSTANCE_NAME && !process.env.CONVEYOR_TASK_TOKEN && !process.env.CONVEYOR_PROJECT_TOKEN) {\n if (!conveyorApiUrl) {\n logger.error(\"Could not resolve CONVEYOR_API_URL for codespace bootstrap\");\n process.exit(1);\n }\n await bootstrapFromCodespace(conveyorApiUrl, INSTANCE_NAME);\n conveyorApiUrl = process.env.CONVEYOR_API_URL ?? conveyorApiUrl;\n}\n\n// Step 2: Read env vars (bootstrap may have set them)\nconst CONVEYOR_PROJECT_TOKEN = process.env.CONVEYOR_PROJECT_TOKEN;\nconst CONVEYOR_PROJECT_ID = process.env.CONVEYOR_PROJECT_ID;\n\n// Step 3: Branch on mode\nif (CONVEYOR_PROJECT_TOKEN && CONVEYOR_PROJECT_ID) {\n const CONVEYOR_PROJECT_DIR = process.env.CONVEYOR_WORKSPACE ?? process.cwd();\n\n if (!conveyorApiUrl) {\n logger.error(\"Could not resolve CONVEYOR_API_URL for project runner mode\");\n process.exit(1);\n }\n\n logger.info(\"Starting project runner\", { projectId: CONVEYOR_PROJECT_ID });\n\n const runner = new ProjectRunner({\n conveyorApiUrl,\n projectToken: CONVEYOR_PROJECT_TOKEN,\n projectId: CONVEYOR_PROJECT_ID,\n projectDir: CONVEYOR_PROJECT_DIR,\n });\n\n process.on(\"SIGTERM\", () => {\n logger.info(\"Received SIGTERM, stopping project runner\");\n void runner.stop();\n setTimeout(() => {\n logger.warn(\"Forcing exit after SIGTERM timeout\");\n process.exit(1);\n }, 40_000).unref();\n });\n\n process.on(\"SIGINT\", () => {\n logger.info(\"Received SIGINT, stopping project runner\");\n void runner.stop();\n setTimeout(() => {\n logger.warn(\"Forcing exit after SIGINT timeout\");\n process.exit(1);\n }, 40_000).unref();\n });\n\n runner\n .start()\n .then(() => {\n // start() resolves once stop() resolves the lifecycle promise (UI disconnect,\n // shutdown signal, or SIGINT/SIGTERM). Exit so the terminal returns to the shell\n // instead of hanging on lingering socket.io/PTY handles.\n process.exit(0);\n })\n .catch((error: unknown) => {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(\"Project runner failed\", { error: msg });\n process.exit(1);\n });\n} else {\n const CONVEYOR_TASK_TOKEN = process.env.CONVEYOR_TASK_TOKEN;\n const CONVEYOR_TASK_ID = process.env.CONVEYOR_TASK_ID;\n const CONVEYOR_WORKSPACE = process.env.CONVEYOR_WORKSPACE ?? process.cwd();\n const CONVEYOR_MODE = (process.env.CONVEYOR_MODE ?? \"task\") as RunnerMode;\n const CONVEYOR_AGENT_MODE = process.env.CONVEYOR_AGENT_MODE || undefined;\n const CONVEYOR_IS_AUTO = CONVEYOR_AGENT_MODE\n ? CONVEYOR_AGENT_MODE === \"auto\"\n : process.env.CONVEYOR_IS_AUTO === \"true\";\n\n if (!CONVEYOR_TASK_TOKEN || !CONVEYOR_TASK_ID) {\n logger.error(\"Missing required environment variables\");\n logger.error(\" CONVEYOR_TASK_TOKEN - JWT token for task authentication\");\n logger.error(\" CONVEYOR_TASK_ID - ID of the task to execute\");\n logger.error(\"\");\n logger.error(\"CONVEYOR_API_URL is provided via codespace secret or bootstrap.\");\n logger.error(\"\");\n logger.error(\"Optional:\");\n logger.error(\" CONVEYOR_MODE - Runner mode: 'task' (default) or 'pm'\");\n logger.error(\" CONVEYOR_WORKSPACE - Working directory (defaults to cwd)\");\n process.exit(1);\n }\n\n if (CONVEYOR_MODE !== \"task\" && CONVEYOR_MODE !== \"pm\" && CONVEYOR_MODE !== \"code-review\") {\n logger.error(\"Invalid CONVEYOR_MODE\", {\n mode: CONVEYOR_MODE,\n expected: [\"task\", \"pm\", \"code-review\"],\n });\n process.exit(1);\n }\n\n logger.info(\"Starting agent\", { mode: CONVEYOR_MODE });\n\n // Claudespace pods: longer idle timeout to stay alive for incoming messages.\n // Non-claudespace environments (local, workspace, GitHub Codespaces) have\n // persistent state and don't need the periodic WIP commit safety net, so\n // disable the git flush timer for them.\n const lifecycleOverrides = process.env.CLAUDESPACE_NAME\n ? { idleTimeoutMs: 60 * 60 * 1000 }\n : { gitFlushIntervalMs: 0 };\n\n const runner = new SessionRunner(\n {\n connection: {\n apiUrl: conveyorApiUrl ?? \"\",\n taskToken: CONVEYOR_TASK_TOKEN,\n // CONVEYOR_SESSION_ID is the CodespaceSession ID for BaseService ACL.\n // Falls back to CONVEYOR_TASK_ID for backward compat (codespace bootstrap sets only task ID).\n sessionId: process.env.CONVEYOR_SESSION_ID ?? CONVEYOR_TASK_ID,\n runnerMode: CONVEYOR_MODE,\n },\n runnerMode: CONVEYOR_MODE,\n isAuto: CONVEYOR_IS_AUTO,\n workspaceDir: CONVEYOR_WORKSPACE,\n agentMode: CONVEYOR_AGENT_MODE as import(\"@project/shared\").AgentMode | undefined,\n lifecycle: lifecycleOverrides,\n },\n {\n onStatusChange: (status: AgentRunnerStatus) => {\n logger.info(\"Status changed\", { status });\n },\n onEvent: (event: Record<string, unknown>) => {\n const detail =\n (event.message as string) ?? (event.content as string) ?? (event.summary as string) ?? \"\";\n if (detail) {\n logger.info(detail, { eventType: event.type as string });\n }\n },\n },\n );\n\n // Children of a local project runner skip the shutdown git flush — the\n // parent flushes every child working tree after the kill, and the flush's\n // token RPC + pushes can outlast the parent's SIGTERM→SIGKILL window.\n const skipShutdownFlush = process.env.CONVEYOR_SKIP_SHUTDOWN_GIT_FLUSH === \"true\";\n\n const shutdownAgent = (signal: \"SIGTERM\" | \"SIGINT\") => {\n if (skipShutdownFlush) {\n logger.info(`Received ${signal}, stopping agent (git flush handled by project runner)`);\n runner.stop();\n } else {\n logger.info(`Received ${signal}, flushing git and stopping agent`);\n // Flush WIP commit + push BEFORE stop() tears down the connection, since\n // the token-refresh RPC needs a live socket. Then stop the runner.\n void (async () => {\n try {\n await runner.flushGitOnShutdown();\n } finally {\n runner.stop();\n }\n })();\n }\n setTimeout(\n () => {\n logger.warn(`Forcing exit after ${signal} timeout`);\n process.exit(1);\n },\n skipShutdownFlush ? 10_000 : 45_000,\n ).unref();\n };\n\n process.on(\"SIGTERM\", () => shutdownAgent(\"SIGTERM\"));\n process.on(\"SIGINT\", () => shutdownAgent(\"SIGINT\"));\n\n // Connect first so setup/start output is forwarded to the API\n await runner.connect();\n\n // Defense-in-depth: warn loudly if CONVEYOR_SESSION_ID decodes to a different\n // task than CONVEYOR_TASK_ID. Authoritative checks are server-side\n // (requireTaskAuth + partial-unique index on active CodespaceSessions). This\n // is a visibility net in case those regress — see SEC-9 postmortem in\n // .claude/rules/agent-codespace.md.\n void checkSessionTaskIdentity({\n sessionId: process.env.CONVEYOR_SESSION_ID,\n taskId: CONVEYOR_TASK_ID,\n fetchSessionTaskId: async (sessionId) => {\n const ctx = await runner.connection.call(\"getTaskContext\", { sessionId });\n return ctx.id;\n },\n logger,\n });\n\n // Run setup + start commands in the background so the agent can start\n // fetching context and thinking immediately. The dev environment will be\n // ready by the time the agent needs to actually execute anything in it.\n // Start command still runs after setup (install must finish before `bun\n // run dev` works), but both are decoupled from runner.run().\n //\n // INVARIANT: failures inside this IIFE are NON-FATAL. Any throw or non-zero\n // exit from setup/start must surface as a chat event, never as process.exit.\n // The agent continues so the user can still interact with it and debug.\n const conveyorConfig = loadConveyorConfig();\n if (conveyorConfig) {\n void (async () => {\n const logOutput = (stream: \"stdout\" | \"stderr\", data: string) => {\n runner.connection.sendEvent({ type: \"setup_output\", stream, data });\n (stream === \"stderr\" ? process.stderr : process.stdout).write(data);\n };\n if (conveyorConfig.setupCommand) {\n logger.info(\"Running setup command (background)\", {\n command: conveyorConfig.setupCommand,\n });\n try {\n await runSetupCommand(conveyorConfig.setupCommand, CONVEYOR_WORKSPACE, logOutput);\n logger.info(\"Setup command completed\");\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Setup command failed\";\n logger.error(\"Setup command failed\", { error: msg });\n runner.connection.sendEvent({ type: \"setup_error\", message: msg });\n }\n }\n\n let startCommandRunning = false;\n if (conveyorConfig.startCommand) {\n logger.info(\"Running start command\", { command: conveyorConfig.startCommand });\n const child = runStartCommand(\n conveyorConfig.startCommand,\n CONVEYOR_WORKSPACE,\n (stream, data) => {\n runner.connection.sendEvent({ type: \"start_command_output\", stream, data });\n (stream === \"stderr\" ? process.stderr : process.stdout).write(data);\n },\n );\n startCommandRunning = true;\n child.on(\"exit\", (code, signal) => {\n logger.info(\"Start command exited\", { code, signal });\n runner.connection.sendEvent({\n type: \"start_command_exited\",\n code,\n signal,\n message: `start command exited${code === null ? \"\" : ` with code ${code}`}${signal ? ` (signal: ${signal})` : \"\"}`,\n });\n // Surface non-zero exits as a loud chat message too, so users know\n // their dev server crashed and the agent may hit tool-use failures.\n if (code !== null && code !== 0) {\n runner.connection.sendEvent({\n type: \"start_command_error\",\n message: `start command exited with code ${code}${signal ? ` (signal: ${signal})` : \"\"}`,\n });\n }\n });\n child.on(\"error\", (err) => {\n logger.error(\"Start command error\", { error: err.message });\n runner.connection.sendEvent({ type: \"start_command_error\", message: err.message });\n });\n }\n\n const forwardPorts = await loadForwardPorts(CONVEYOR_WORKSPACE);\n const previewPorts = buildSessionPreviewPorts(forwardPorts);\n runner.connection.sendEvent({\n type: \"setup_complete\",\n startCommandRunning,\n previewPort: conveyorConfig.previewPort,\n ...(previewPorts.length > 0 ? { previewPorts } : {}),\n });\n })();\n }\n\n // Start the main agent lifecycle immediately in parallel with setup\n // (context fetch, mode resolution, core loop).\n runner\n .run()\n .then(() => {\n // Exit with code 0 for clean shutdown (entrypoint won't restart),\n // code 1 for errors (entrypoint will restart).\n process.exit(runner.finalState === \"error\" ? 1 : 0);\n })\n .catch((error: unknown) => {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(\"Agent runner failed\", { error: msg });\n process.exit(1);\n });\n}\n","// Defense-in-depth startup check. The authoritative guarantee that a session is\n// bound to the right task lives server-side (requireTaskAuth + the Postgres\n// partial-unique index on active CodespaceSessions). This check exists so that\n// if those invariants ever regress, a human sees a loud WARN immediately\n// instead of the symptoms SEC-9 produced (multiple agents silently clobbering\n// the same branch).\nexport interface SessionIdentityLogger {\n warn(message: string, data?: Record<string, unknown>): void;\n info?(message: string, data?: Record<string, unknown>): void;\n}\n\nexport interface CheckSessionTaskIdentityParams {\n sessionId: string | undefined;\n taskId: string;\n fetchSessionTaskId: (sessionId: string) => Promise<string>;\n logger: SessionIdentityLogger;\n}\n\nexport async function checkSessionTaskIdentity(\n params: CheckSessionTaskIdentityParams,\n): Promise<\"match\" | \"mismatch\" | \"skipped\" | \"error\"> {\n const { sessionId, taskId, fetchSessionTaskId, logger } = params;\n if (!sessionId || sessionId === taskId) return \"skipped\";\n let sessionTaskId: string;\n try {\n sessionTaskId = await fetchSessionTaskId(sessionId);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n logger.warn(\"Could not verify session/task identity — continuing (defense-in-depth only)\", {\n sessionId,\n taskId,\n error: message,\n });\n return \"error\";\n }\n if (sessionTaskId !== taskId) {\n logger.warn(\n \"!!! CONVEYOR_SESSION_ID is bound to a different task than CONVEYOR_TASK_ID — server-side guards should still block mutations, but this indicates a misconfiguration or replayed token.\",\n { sessionId, envTaskId: taskId, sessionTaskId },\n );\n return \"mismatch\";\n }\n return \"match\";\n}\n"],"mappings":"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","names":["logger"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ declare class AgentConnection {
|
|
|
46
46
|
private readonly config;
|
|
47
47
|
private eventBuffer;
|
|
48
48
|
private flushTimer;
|
|
49
|
+
private tokenRefreshTimer;
|
|
49
50
|
private lastEmittedStatus;
|
|
50
51
|
private lastReportedStatus;
|
|
51
52
|
private droppedEventCount;
|
|
@@ -79,6 +80,8 @@ declare class AgentConnection {
|
|
|
79
80
|
private isReconnecting;
|
|
80
81
|
private reconnectToSession;
|
|
81
82
|
private looksLikeAuthError;
|
|
83
|
+
private startProactiveTokenRefresh;
|
|
84
|
+
private stopProactiveTokenRefresh;
|
|
82
85
|
private drainPendingMessages;
|
|
83
86
|
onMessage(callback: (msg: IncomingMessage) => void): void;
|
|
84
87
|
onStop(callback: () => void): void;
|
|
@@ -491,7 +494,9 @@ declare class ProjectConnection {
|
|
|
491
494
|
constructor(config: ProjectConnectionConfig);
|
|
492
495
|
get projectId(): string;
|
|
493
496
|
get connected(): boolean;
|
|
494
|
-
call<M extends keyof AgentSessionServiceMethods>(method: M, payload: AgentSessionServiceMethods[M]["payload"]
|
|
497
|
+
call<M extends keyof AgentSessionServiceMethods>(method: M, payload: AgentSessionServiceMethods[M]["payload"], opts?: {
|
|
498
|
+
timeoutMs?: number;
|
|
499
|
+
}): Promise<AgentSessionServiceMethods[M]["response"]>;
|
|
495
500
|
connect(): Promise<void>;
|
|
496
501
|
disconnect(): void;
|
|
497
502
|
onReconnect(callback: () => void): void;
|
|
@@ -551,9 +556,17 @@ declare class ProjectRunner {
|
|
|
551
556
|
start(): Promise<void>;
|
|
552
557
|
/** Best-effort WIP commit + push of every tracked working tree on shutdown.
|
|
553
558
|
* Iterates the main project dir plus any active agent worktrees so nothing
|
|
554
|
-
* pending is lost when the pod is killed. Never throws.
|
|
555
|
-
|
|
559
|
+
* pending is lost when the pod is killed. Never throws.
|
|
560
|
+
*
|
|
561
|
+
* Callers that kill child agents first must snapshot the worktree dirs
|
|
562
|
+
* BEFORE the kill — the child exit handler removes entries from
|
|
563
|
+
* `activeAgents`, so reading it after the kill misses the worktrees. */
|
|
564
|
+
flushGitOnShutdown(dirs?: Set<string>): Promise<void>;
|
|
556
565
|
stop(): Promise<void>;
|
|
566
|
+
/** Idempotent final step: tear down the socket and resolve the lifecycle
|
|
567
|
+
* promise so start() returns. Called from stop()'s finally and from the
|
|
568
|
+
* shutdown watchdog. */
|
|
569
|
+
private finishShutdown;
|
|
557
570
|
private wireEventHandlers;
|
|
558
571
|
private handleReconnect;
|
|
559
572
|
private handleAuditTags;
|
package/dist/index.js
CHANGED
|
@@ -25,9 +25,9 @@ import {
|
|
|
25
25
|
stageAndCommit,
|
|
26
26
|
unshallowRepo,
|
|
27
27
|
updateRemoteToken
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-WZCO64YR.js";
|
|
29
29
|
import "./chunk-FDWECEDJ.js";
|
|
30
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-6B545CHM.js";
|
|
31
31
|
|
|
32
32
|
// src/runner/file-cache.ts
|
|
33
33
|
var DEFAULT_MAX_SIZE_BYTES = 50 * 1024 * 1024;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createHarness,
|
|
3
3
|
createServiceLogger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6B545CHM.js";
|
|
5
5
|
|
|
6
6
|
// src/runner/tag-audit-handler.ts
|
|
7
7
|
var logger = createServiceLogger("TagAudit");
|
|
@@ -219,4 +219,4 @@ export {
|
|
|
219
219
|
buildTagAuditPrompt,
|
|
220
220
|
handleTagAudit
|
|
221
221
|
};
|
|
222
|
-
//# sourceMappingURL=tag-audit-handler-
|
|
222
|
+
//# sourceMappingURL=tag-audit-handler-3IFB7YDV.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
createHarness,
|
|
6
6
|
createServiceLogger,
|
|
7
7
|
defineTool
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6B545CHM.js";
|
|
9
9
|
|
|
10
10
|
// src/runner/task-audit-handler.ts
|
|
11
11
|
import { z } from "zod";
|
|
@@ -798,4 +798,4 @@ async function handleTaskAudit(request, connection, projectDir) {
|
|
|
798
798
|
export {
|
|
799
799
|
handleTaskAudit
|
|
800
800
|
};
|
|
801
|
-
//# sourceMappingURL=task-audit-handler-
|
|
801
|
+
//# sourceMappingURL=task-audit-handler-U5Q52YT2.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rallycry/conveyor-agent",
|
|
3
|
-
"version": "8.5.
|
|
3
|
+
"version": "8.5.1",
|
|
4
4
|
"description": "Conveyor Agent Runner v8 - PTY harness for the task chat (SDK harness for audit/project-chat). Agent-as-User architecture with BaseService patterns. Works locally too.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|