@posthog/agent 1.25.0 → 1.26.0

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 (41) hide show
  1. package/dist/_virtual/_tslib.js +74 -0
  2. package/dist/_virtual/_tslib.js.map +1 -0
  3. package/dist/_virtual/index.js +2 -2
  4. package/dist/_virtual/index2.js +2 -2
  5. package/dist/_virtual/index8.js +2 -2
  6. package/dist/_virtual/index9.js +2 -2
  7. package/dist/node_modules/@agentclientprotocol/sdk/dist/acp.js +284 -3
  8. package/dist/node_modules/@agentclientprotocol/sdk/dist/acp.js.map +1 -1
  9. package/dist/node_modules/@agentclientprotocol/sdk/dist/schema.js +2 -1
  10. package/dist/node_modules/@agentclientprotocol/sdk/dist/schema.js.map +1 -1
  11. package/dist/node_modules/ajv/dist/ajv.js +1 -1
  12. package/dist/node_modules/ajv/dist/compile/codegen/index.js +1 -1
  13. package/dist/node_modules/ajv/dist/compile/validate/index.js +1 -1
  14. package/dist/node_modules/ajv/dist/vocabularies/discriminator/index.js +1 -1
  15. package/dist/node_modules/ajv-formats/dist/index.js +1 -1
  16. package/dist/package.json.js +1 -1
  17. package/dist/src/adapters/claude/claude.d.ts.map +1 -1
  18. package/dist/src/adapters/claude/claude.js +21 -5
  19. package/dist/src/adapters/claude/claude.js.map +1 -1
  20. package/dist/src/adapters/claude/mcp-server.js +105 -92
  21. package/dist/src/adapters/claude/mcp-server.js.map +1 -1
  22. package/dist/src/adapters/claude/tools.d.ts.map +1 -1
  23. package/dist/src/adapters/claude/tools.js +8 -1
  24. package/dist/src/adapters/claude/tools.js.map +1 -1
  25. package/dist/src/agent.d.ts +7 -1
  26. package/dist/src/agent.d.ts.map +1 -1
  27. package/dist/src/agent.js +151 -0
  28. package/dist/src/agent.js.map +1 -1
  29. package/dist/src/session-store.d.ts +7 -2
  30. package/dist/src/session-store.d.ts.map +1 -1
  31. package/dist/src/session-store.js +11 -0
  32. package/dist/src/session-store.js.map +1 -1
  33. package/dist/src/worktree-manager.d.ts.map +1 -1
  34. package/dist/src/worktree-manager.js +3 -5
  35. package/dist/src/worktree-manager.js.map +1 -1
  36. package/package.json +1 -1
  37. package/src/adapters/claude/claude.ts +21 -5
  38. package/src/adapters/claude/tools.ts +8 -1
  39. package/src/agent.ts +213 -1
  40. package/src/session-store.ts +18 -3
  41. package/src/worktree-manager.ts +4 -7
@@ -1 +1 @@
1
- {"version":3,"file":"worktree-manager.js","sources":["../../src/worktree-manager.ts"],"sourcesContent":["import { exec, execFile } from \"node:child_process\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport type { WorktreeInfo } from \"./types.js\";\nimport { Logger } from \"./utils/logger.js\";\n\nconst execAsync = promisify(exec);\nconst execFileAsync = promisify(execFile);\n\nexport interface WorktreeConfig {\n mainRepoPath: string;\n worktreeBasePath?: string;\n logger?: Logger;\n}\n\nconst ADJECTIVES = [\n \"swift\",\n \"bright\",\n \"calm\",\n \"bold\",\n \"gentle\",\n \"quick\",\n \"soft\",\n \"warm\",\n \"cool\",\n \"wise\",\n \"keen\",\n \"brave\",\n \"clear\",\n \"crisp\",\n \"deep\",\n \"fair\",\n \"fine\",\n \"free\",\n \"glad\",\n \"good\",\n \"grand\",\n \"great\",\n \"happy\",\n \"kind\",\n \"light\",\n \"lively\",\n \"neat\",\n \"nice\",\n \"plain\",\n \"proud\",\n \"pure\",\n \"rare\",\n \"rich\",\n \"safe\",\n \"sharp\",\n \"shy\",\n \"simple\",\n \"slim\",\n \"smart\",\n \"smooth\",\n \"solid\",\n \"sound\",\n \"spare\",\n \"stable\",\n \"steady\",\n \"still\",\n \"strong\",\n \"sure\",\n \"sweet\",\n \"tall\",\n \"agile\",\n \"ancient\",\n \"autumn\",\n \"azure\",\n \"cosmic\",\n \"daring\",\n \"dawn\",\n \"dusty\",\n \"eager\",\n \"early\",\n \"endless\",\n \"fading\",\n \"fallen\",\n \"famous\",\n \"feral\",\n \"fierce\",\n \"fleet\",\n \"foggy\",\n \"forest\",\n \"frozen\",\n \"gleeful\",\n \"golden\",\n \"hazy\",\n \"hidden\",\n \"hollow\",\n \"humble\",\n \"hushed\",\n \"icy\",\n \"inner\",\n \"late\",\n \"lazy\",\n \"little\",\n \"lone\",\n \"long\",\n \"lost\",\n \"lucky\",\n \"lunar\",\n \"magic\",\n \"mellow\",\n \"mighty\",\n \"misty\",\n \"modest\",\n \"mossy\",\n \"mystic\",\n \"nimble\",\n \"noble\",\n \"ocean\",\n \"outer\",\n \"pale\",\n \"paper\",\n \"patient\",\n \"peaceful\",\n \"phantom\",\n \"polite\",\n \"primal\",\n \"quiet\",\n \"rapid\",\n \"restless\",\n \"rising\",\n \"roaming\",\n \"rocky\",\n \"rustic\",\n \"sacred\",\n \"sandy\",\n \"secret\",\n \"serene\",\n \"shadow\",\n \"shining\",\n \"silent\",\n \"silky\",\n \"silver\",\n \"sleek\",\n \"snowy\",\n \"solar\",\n \"solemn\",\n \"spring\",\n \"starry\",\n \"stormy\",\n \"summer\",\n \"sunny\",\n \"tender\",\n \"thorny\",\n \"tiny\",\n \"tranquil\",\n \"twilight\",\n \"upward\",\n \"velvet\",\n \"vivid\",\n \"wandering\",\n \"wary\",\n \"wild\",\n \"windy\",\n \"winter\",\n \"wispy\",\n \"young\",\n];\n\nconst COLORS = [\n \"blue\",\n \"red\",\n \"green\",\n \"amber\",\n \"coral\",\n \"jade\",\n \"pearl\",\n \"ruby\",\n \"sage\",\n \"teal\",\n \"gold\",\n \"silver\",\n \"bronze\",\n \"copper\",\n \"ivory\",\n \"onyx\",\n \"opal\",\n \"rose\",\n \"slate\",\n \"violet\",\n \"aqua\",\n \"azure\",\n \"beige\",\n \"black\",\n \"brass\",\n \"brick\",\n \"brown\",\n \"cedar\",\n \"charcoal\",\n \"cherry\",\n \"chestnut\",\n \"chrome\",\n \"cider\",\n \"cinnamon\",\n \"citrus\",\n \"clay\",\n \"cloud\",\n \"cobalt\",\n \"cocoa\",\n \"cream\",\n \"crimson\",\n \"crystal\",\n \"cyan\",\n \"denim\",\n \"dusk\",\n \"ebony\",\n \"ember\",\n \"emerald\",\n \"fern\",\n \"flame\",\n \"flint\",\n \"forest\",\n \"frost\",\n \"garnet\",\n \"ginger\",\n \"glacier\",\n \"granite\",\n \"grape\",\n \"gray\",\n \"hazel\",\n \"honey\",\n \"indigo\",\n \"iron\",\n \"lapis\",\n \"lava\",\n \"lavender\",\n \"lemon\",\n \"lilac\",\n \"lime\",\n \"magenta\",\n \"mahogany\",\n \"maple\",\n \"marble\",\n \"maroon\",\n \"mauve\",\n \"midnight\",\n \"mint\",\n \"mocha\",\n \"moss\",\n \"mustard\",\n \"navy\",\n \"nickel\",\n \"obsidian\",\n \"ochre\",\n \"olive\",\n \"orange\",\n \"orchid\",\n \"peach\",\n \"pine\",\n \"pink\",\n \"plum\",\n \"porcelain\",\n \"purple\",\n \"quartz\",\n \"rust\",\n \"saffron\",\n \"salmon\",\n \"sand\",\n \"sapphire\",\n \"scarlet\",\n \"sepia\",\n \"shadow\",\n \"sienna\",\n \"smoke\",\n \"snow\",\n \"steel\",\n \"stone\",\n \"storm\",\n \"sunset\",\n \"tan\",\n \"tangerine\",\n \"taupe\",\n \"terra\",\n \"timber\",\n \"topaz\",\n \"turquoise\",\n \"umber\",\n \"vanilla\",\n \"walnut\",\n \"wheat\",\n \"white\",\n \"wine\",\n \"yellow\",\n];\n\nconst ANIMALS = [\n \"fox\",\n \"owl\",\n \"bear\",\n \"wolf\",\n \"hawk\",\n \"deer\",\n \"lynx\",\n \"otter\",\n \"raven\",\n \"falcon\",\n \"badger\",\n \"beaver\",\n \"bison\",\n \"bobcat\",\n \"crane\",\n \"eagle\",\n \"ferret\",\n \"finch\",\n \"gopher\",\n \"heron\",\n \"jaguar\",\n \"koala\",\n \"lemur\",\n \"marten\",\n \"mink\",\n \"moose\",\n \"newt\",\n \"ocelot\",\n \"osprey\",\n \"panda\",\n \"parrot\",\n \"pelican\",\n \"puma\",\n \"quail\",\n \"rabbit\",\n \"raccoon\",\n \"salmon\",\n \"seal\",\n \"shark\",\n \"shrew\",\n \"sloth\",\n \"snake\",\n \"spider\",\n \"squid\",\n \"stork\",\n \"swan\",\n \"tiger\",\n \"toucan\",\n \"turtle\",\n \"whale\",\n \"albatross\",\n \"ant\",\n \"antelope\",\n \"armadillo\",\n \"baboon\",\n \"bat\",\n \"bee\",\n \"beetle\",\n \"buffalo\",\n \"butterfly\",\n \"camel\",\n \"cardinal\",\n \"caribou\",\n \"catfish\",\n \"cheetah\",\n \"chipmunk\",\n \"cicada\",\n \"clam\",\n \"cobra\",\n \"condor\",\n \"corgi\",\n \"cougar\",\n \"coyote\",\n \"crab\",\n \"cricket\",\n \"crow\",\n \"dolphin\",\n \"donkey\",\n \"dove\",\n \"dragonfly\",\n \"duck\",\n \"eel\",\n \"egret\",\n \"elephant\",\n \"elk\",\n \"emu\",\n \"firefly\",\n \"flamingo\",\n \"frog\",\n \"gazelle\",\n \"gecko\",\n \"gibbon\",\n \"giraffe\",\n \"goat\",\n \"goose\",\n \"gorilla\",\n \"grasshopper\",\n \"grouse\",\n \"gull\",\n \"hamster\",\n \"hare\",\n \"hedgehog\",\n \"hippo\",\n \"hornet\",\n \"horse\",\n \"hound\",\n \"hummingbird\",\n \"hyena\",\n \"ibis\",\n \"iguana\",\n \"impala\",\n \"jackal\",\n \"jay\",\n \"jellyfish\",\n \"kangaroo\",\n \"kestrel\",\n \"kingfisher\",\n \"kite\",\n \"kiwi\",\n \"lark\",\n \"leopard\",\n \"lion\",\n \"lizard\",\n \"llama\",\n \"lobster\",\n \"loon\",\n \"macaw\",\n \"magpie\",\n \"mallard\",\n \"mammoth\",\n \"manatee\",\n \"mantis\",\n \"marlin\",\n \"marmot\",\n \"meerkat\",\n \"mockingbird\",\n \"mole\",\n \"mongoose\",\n \"monkey\",\n \"moth\",\n \"mouse\",\n \"mule\",\n \"narwhal\",\n \"nightingale\",\n \"octopus\",\n \"opossum\",\n \"orangutan\",\n \"oriole\",\n \"ostrich\",\n \"oyster\",\n \"panther\",\n \"peacock\",\n \"penguin\",\n \"pheasant\",\n \"pig\",\n \"pigeon\",\n \"pike\",\n \"piranha\",\n \"platypus\",\n \"pony\",\n \"porcupine\",\n \"porpoise\",\n \"python\",\n \"raven\",\n \"ray\",\n \"reindeer\",\n \"rhino\",\n \"robin\",\n \"rooster\",\n \"salamander\",\n \"sandpiper\",\n \"sardine\",\n \"scorpion\",\n \"seagull\",\n \"seahorse\",\n \"skunk\",\n \"snail\",\n \"sparrow\",\n \"squirrel\",\n \"starfish\",\n \"starling\",\n \"stingray\",\n \"swallow\",\n \"tapir\",\n \"termite\",\n \"tern\",\n \"toad\",\n \"trout\",\n \"tuna\",\n \"viper\",\n \"vulture\",\n \"walrus\",\n \"wasp\",\n \"weasel\",\n \"wombat\",\n \"woodpecker\",\n \"wren\",\n \"yak\",\n \"zebra\",\n];\n\nconst WORKTREE_FOLDER_NAME = \".array\";\n\nexport class WorktreeManager {\n private mainRepoPath: string;\n private worktreeBasePath: string | null;\n private repoName: string;\n private logger: Logger;\n\n constructor(config: WorktreeConfig) {\n this.mainRepoPath = config.mainRepoPath;\n this.worktreeBasePath = config.worktreeBasePath || null;\n this.repoName = path.basename(config.mainRepoPath);\n this.logger =\n config.logger ||\n new Logger({ debug: false, prefix: \"[WorktreeManager]\" });\n }\n\n private usesExternalPath(): boolean {\n return this.worktreeBasePath !== null;\n }\n\n private async runGitCommand(command: string): Promise<string> {\n try {\n const { stdout } = await execAsync(`git ${command}`, {\n cwd: this.mainRepoPath,\n });\n return stdout.trim();\n } catch (error) {\n throw new Error(`Git command failed: ${command}\\n${error}`);\n }\n }\n\n private randomElement<T>(array: T[]): T {\n return array[crypto.randomInt(array.length)];\n }\n\n generateWorktreeName(): string {\n const adjective = this.randomElement(ADJECTIVES);\n const color = this.randomElement(COLORS);\n const animal = this.randomElement(ANIMALS);\n return `${adjective}-${color}-${animal}`;\n }\n\n private getWorktreeFolderPath(): string {\n if (this.worktreeBasePath) {\n return path.join(this.worktreeBasePath, this.repoName);\n }\n return path.join(this.mainRepoPath, WORKTREE_FOLDER_NAME);\n }\n\n private getWorktreePath(name: string): string {\n return path.join(this.getWorktreeFolderPath(), name);\n }\n\n async worktreeExists(name: string): Promise<boolean> {\n const worktreePath = this.getWorktreePath(name);\n try {\n await fs.access(worktreePath);\n return true;\n } catch {\n return false;\n }\n }\n\n async ensureArrayDirIgnored(): Promise<void> {\n // Use .git/info/exclude instead of .gitignore to avoid modifying tracked files\n const excludePath = path.join(this.mainRepoPath, \".git\", \"info\", \"exclude\");\n const ignorePattern = `/${WORKTREE_FOLDER_NAME}/`;\n\n let content = \"\";\n try {\n content = await fs.readFile(excludePath, \"utf-8\");\n } catch {\n // File doesn't exist or .git/info doesn't exist\n }\n\n // Check if pattern is already present\n if (\n content.includes(`/${WORKTREE_FOLDER_NAME}/`) ||\n content.includes(`/${WORKTREE_FOLDER_NAME}`)\n ) {\n this.logger.debug(\"Exclude file already contains .array folder pattern\");\n return;\n }\n\n // Ensure .git/info directory exists\n const infoDir = path.join(this.mainRepoPath, \".git\", \"info\");\n await fs.mkdir(infoDir, { recursive: true });\n\n // Append the pattern\n const newContent = `${content.trimEnd()}\\n\\n# Array worktrees\\n${ignorePattern}\\n`;\n await fs.writeFile(excludePath, newContent);\n this.logger.info(\"Added .array folder to .git/info/exclude\");\n }\n\n private async generateUniqueWorktreeName(): Promise<string> {\n let name = this.generateWorktreeName();\n let attempts = 0;\n const maxAttempts = 100;\n\n while ((await this.worktreeExists(name)) && attempts < maxAttempts) {\n name = this.generateWorktreeName();\n attempts++;\n }\n\n if (attempts >= maxAttempts) {\n // Fallback: append timestamp\n name = `${this.generateWorktreeName()}-${Date.now()}`;\n }\n\n return name;\n }\n\n private async getDefaultBranch(): Promise<string> {\n try {\n const remoteBranch = await this.runGitCommand(\n \"symbolic-ref refs/remotes/origin/HEAD\",\n );\n return remoteBranch.replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Fallback: check if main exists, otherwise use master\n try {\n await this.runGitCommand(\"rev-parse --verify main\");\n return \"main\";\n } catch {\n try {\n await this.runGitCommand(\"rev-parse --verify master\");\n return \"master\";\n } catch {\n throw new Error(\n \"Cannot determine default branch. No main or master branch found.\",\n );\n }\n }\n }\n }\n\n async createWorktree(): Promise<WorktreeInfo> {\n // Only modify .git/info/exclude when using in-repo storage\n if (!this.usesExternalPath()) {\n await this.ensureArrayDirIgnored();\n }\n\n // Ensure the worktree folder exists when using external path\n if (this.usesExternalPath()) {\n const folderPath = this.getWorktreeFolderPath();\n await fs.mkdir(folderPath, { recursive: true });\n }\n\n // Generate unique worktree name\n const worktreeName = await this.generateUniqueWorktreeName();\n const worktreePath = this.getWorktreePath(worktreeName);\n const branchName = `posthog/${worktreeName}`;\n const baseBranch = await this.getDefaultBranch();\n\n this.logger.info(\"Creating worktree\", {\n worktreeName,\n worktreePath,\n branchName,\n baseBranch,\n external: this.usesExternalPath(),\n });\n\n // Create the worktree with a new branch\n if (this.usesExternalPath()) {\n // Use absolute path for external worktrees\n await this.runGitCommand(\n `worktree add -b \"${branchName}\" \"${worktreePath}\" \"${baseBranch}\"`,\n );\n } else {\n // Use relative path from repo root for in-repo worktrees\n const relativePath = `${WORKTREE_FOLDER_NAME}/${worktreeName}`;\n await this.runGitCommand(\n `worktree add -b \"${branchName}\" \"./${relativePath}\" \"${baseBranch}\"`,\n );\n }\n\n const createdAt = new Date().toISOString();\n\n this.logger.info(\"Worktree created successfully\", {\n worktreeName,\n worktreePath,\n branchName,\n });\n\n return {\n worktreePath,\n worktreeName,\n branchName,\n baseBranch,\n createdAt,\n };\n }\n\n async deleteWorktree(worktreePath: string): Promise<void> {\n this.logger.info(\"Deleting worktree\", { worktreePath });\n\n try {\n // First, try to remove the worktree via git using execFileAsync for safety\n await execFileAsync(\n \"git\",\n [\"worktree\", \"remove\", worktreePath, \"--force\"],\n {\n cwd: this.mainRepoPath,\n },\n );\n this.logger.info(\"Worktree deleted successfully\", { worktreePath });\n } catch (error) {\n this.logger.warn(\n \"Git worktree remove failed, attempting manual cleanup\",\n {\n worktreePath,\n error,\n },\n );\n\n // Manual cleanup if git command fails\n try {\n await fs.rm(worktreePath, { recursive: true, force: true });\n // Also prune the worktree list\n await this.runGitCommand(\"worktree prune\");\n this.logger.info(\"Worktree cleaned up manually\", { worktreePath });\n } catch (cleanupError) {\n this.logger.error(\"Failed to cleanup worktree\", {\n worktreePath,\n cleanupError,\n });\n throw cleanupError;\n }\n }\n }\n\n async getWorktreeInfo(worktreePath: string): Promise<WorktreeInfo | null> {\n try {\n // Parse the worktree list to find info about this worktree\n const output = await this.runGitCommand(\"worktree list --porcelain\");\n const worktrees = this.parseWorktreeList(output);\n\n const worktree = worktrees.find((w) => w.worktreePath === worktreePath);\n return worktree || null;\n } catch (error) {\n this.logger.debug(\"Failed to get worktree info\", { worktreePath, error });\n return null;\n }\n }\n\n async listWorktrees(): Promise<WorktreeInfo[]> {\n try {\n const output = await this.runGitCommand(\"worktree list --porcelain\");\n return this.parseWorktreeList(output);\n } catch (error) {\n this.logger.debug(\"Failed to list worktrees\", { error });\n return [];\n }\n }\n\n private parseWorktreeList(output: string): WorktreeInfo[] {\n const worktrees: WorktreeInfo[] = [];\n const entries = output.split(\"\\n\\n\").filter((e) => e.trim());\n const worktreeFolderPath = this.getWorktreeFolderPath();\n\n for (const entry of entries) {\n const lines = entry.split(\"\\n\");\n let worktreePath = \"\";\n let branchName = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"worktree \")) {\n worktreePath = line.replace(\"worktree \", \"\");\n } else if (line.startsWith(\"branch refs/heads/\")) {\n branchName = line.replace(\"branch refs/heads/\", \"\");\n }\n }\n\n // Include worktrees that:\n // 1. Are in our worktree folder (external or in-repo)\n // 2. Have a posthog/ branch prefix (our naming convention)\n const isInWorktreeFolder = worktreePath?.startsWith(worktreeFolderPath);\n const isPosthogBranch = branchName?.startsWith(\"posthog/\");\n\n if (\n worktreePath &&\n branchName &&\n (isInWorktreeFolder || isPosthogBranch)\n ) {\n const worktreeName = path.basename(worktreePath);\n worktrees.push({\n worktreePath,\n worktreeName,\n branchName,\n baseBranch: \"\",\n createdAt: \"\",\n });\n }\n }\n\n return worktrees;\n }\n\n async isWorktree(repoPath: string): Promise<boolean> {\n try {\n const { stdout } = await execAsync(\n \"git rev-parse --is-inside-work-tree\",\n { cwd: repoPath },\n );\n if (stdout.trim() !== \"true\") {\n return false;\n }\n\n // Check if there's a .git file (worktrees have a .git file, not a .git directory)\n const gitPath = path.join(repoPath, \".git\");\n const stat = await fs.stat(gitPath);\n return stat.isFile(); // Worktrees have .git as a file, main repos have .git as a directory\n } catch {\n return false;\n }\n }\n\n async getMainRepoPathFromWorktree(\n worktreePath: string,\n ): Promise<string | null> {\n try {\n const gitFilePath = path.join(worktreePath, \".git\");\n const content = await fs.readFile(gitFilePath, \"utf-8\");\n\n // The .git file in a worktree contains: gitdir: /path/to/main/.git/worktrees/name\n const match = content.match(/gitdir:\\s*(.+)/);\n if (match) {\n const gitDir = match[1].trim();\n // Go up from .git/worktrees/name to get the main repo path\n // The gitdir points to something like: /main/repo/.git/worktrees/worktree-name\n const mainGitDir = path.resolve(gitDir, \"..\", \"..\", \"..\");\n return mainGitDir;\n }\n return null;\n } catch {\n return null;\n }\n }\n\n async cleanupOrphanedWorktrees(associatedWorktreePaths: string[]): Promise<{\n deleted: string[];\n errors: Array<{ path: string; error: string }>;\n }> {\n this.logger.info(\"Starting cleanup of orphaned worktrees\");\n\n const allWorktrees = await this.listWorktrees();\n const deleted: string[] = [];\n const errors: Array<{ path: string; error: string }> = [];\n\n const associatedPathsSet = new Set(\n associatedWorktreePaths.map((p) => path.resolve(p)),\n );\n\n for (const worktree of allWorktrees) {\n const resolvedPath = path.resolve(worktree.worktreePath);\n\n if (!associatedPathsSet.has(resolvedPath)) {\n this.logger.info(\"Found orphaned worktree\", {\n path: worktree.worktreePath,\n });\n\n try {\n await this.deleteWorktree(worktree.worktreePath);\n deleted.push(worktree.worktreePath);\n this.logger.info(\"Deleted orphaned worktree\", {\n path: worktree.worktreePath,\n });\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n errors.push({\n path: worktree.worktreePath,\n error: errorMessage,\n });\n this.logger.error(\"Failed to delete orphaned worktree\", {\n path: worktree.worktreePath,\n error: errorMessage,\n });\n }\n }\n }\n\n this.logger.info(\"Cleanup completed\", {\n deleted: deleted.length,\n errors: errors.length,\n });\n\n return { deleted, errors };\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worktree-manager.js","sources":["../../src/worktree-manager.ts"],"sourcesContent":["import { exec, execFile } from \"node:child_process\";\nimport * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport type { WorktreeInfo } from \"./types.js\";\nimport { Logger } from \"./utils/logger.js\";\n\nconst execAsync = promisify(exec);\nconst execFileAsync = promisify(execFile);\n\nexport interface WorktreeConfig {\n mainRepoPath: string;\n worktreeBasePath?: string;\n logger?: Logger;\n}\n\nconst ADJECTIVES = [\n \"swift\",\n \"bright\",\n \"calm\",\n \"bold\",\n \"gentle\",\n \"quick\",\n \"soft\",\n \"warm\",\n \"cool\",\n \"wise\",\n \"keen\",\n \"brave\",\n \"clear\",\n \"crisp\",\n \"deep\",\n \"fair\",\n \"fine\",\n \"free\",\n \"glad\",\n \"good\",\n \"grand\",\n \"great\",\n \"happy\",\n \"kind\",\n \"light\",\n \"lively\",\n \"neat\",\n \"nice\",\n \"plain\",\n \"proud\",\n \"pure\",\n \"rare\",\n \"rich\",\n \"safe\",\n \"sharp\",\n \"shy\",\n \"simple\",\n \"slim\",\n \"smart\",\n \"smooth\",\n \"solid\",\n \"sound\",\n \"spare\",\n \"stable\",\n \"steady\",\n \"still\",\n \"strong\",\n \"sure\",\n \"sweet\",\n \"tall\",\n \"agile\",\n \"ancient\",\n \"autumn\",\n \"azure\",\n \"cosmic\",\n \"daring\",\n \"dawn\",\n \"dusty\",\n \"eager\",\n \"early\",\n \"endless\",\n \"fading\",\n \"fallen\",\n \"famous\",\n \"feral\",\n \"fierce\",\n \"fleet\",\n \"foggy\",\n \"forest\",\n \"frozen\",\n \"gleeful\",\n \"golden\",\n \"hazy\",\n \"hidden\",\n \"hollow\",\n \"humble\",\n \"hushed\",\n \"icy\",\n \"inner\",\n \"late\",\n \"lazy\",\n \"little\",\n \"lone\",\n \"long\",\n \"lost\",\n \"lucky\",\n \"lunar\",\n \"magic\",\n \"mellow\",\n \"mighty\",\n \"misty\",\n \"modest\",\n \"mossy\",\n \"mystic\",\n \"nimble\",\n \"noble\",\n \"ocean\",\n \"outer\",\n \"pale\",\n \"paper\",\n \"patient\",\n \"peaceful\",\n \"phantom\",\n \"polite\",\n \"primal\",\n \"quiet\",\n \"rapid\",\n \"restless\",\n \"rising\",\n \"roaming\",\n \"rocky\",\n \"rustic\",\n \"sacred\",\n \"sandy\",\n \"secret\",\n \"serene\",\n \"shadow\",\n \"shining\",\n \"silent\",\n \"silky\",\n \"silver\",\n \"sleek\",\n \"snowy\",\n \"solar\",\n \"solemn\",\n \"spring\",\n \"starry\",\n \"stormy\",\n \"summer\",\n \"sunny\",\n \"tender\",\n \"thorny\",\n \"tiny\",\n \"tranquil\",\n \"twilight\",\n \"upward\",\n \"velvet\",\n \"vivid\",\n \"wandering\",\n \"wary\",\n \"wild\",\n \"windy\",\n \"winter\",\n \"wispy\",\n \"young\",\n];\n\nconst COLORS = [\n \"blue\",\n \"red\",\n \"green\",\n \"amber\",\n \"coral\",\n \"jade\",\n \"pearl\",\n \"ruby\",\n \"sage\",\n \"teal\",\n \"gold\",\n \"silver\",\n \"bronze\",\n \"copper\",\n \"ivory\",\n \"onyx\",\n \"opal\",\n \"rose\",\n \"slate\",\n \"violet\",\n \"aqua\",\n \"azure\",\n \"beige\",\n \"black\",\n \"brass\",\n \"brick\",\n \"brown\",\n \"cedar\",\n \"charcoal\",\n \"cherry\",\n \"chestnut\",\n \"chrome\",\n \"cider\",\n \"cinnamon\",\n \"citrus\",\n \"clay\",\n \"cloud\",\n \"cobalt\",\n \"cocoa\",\n \"cream\",\n \"crimson\",\n \"crystal\",\n \"cyan\",\n \"denim\",\n \"dusk\",\n \"ebony\",\n \"ember\",\n \"emerald\",\n \"fern\",\n \"flame\",\n \"flint\",\n \"forest\",\n \"frost\",\n \"garnet\",\n \"ginger\",\n \"glacier\",\n \"granite\",\n \"grape\",\n \"gray\",\n \"hazel\",\n \"honey\",\n \"indigo\",\n \"iron\",\n \"lapis\",\n \"lava\",\n \"lavender\",\n \"lemon\",\n \"lilac\",\n \"lime\",\n \"magenta\",\n \"mahogany\",\n \"maple\",\n \"marble\",\n \"maroon\",\n \"mauve\",\n \"midnight\",\n \"mint\",\n \"mocha\",\n \"moss\",\n \"mustard\",\n \"navy\",\n \"nickel\",\n \"obsidian\",\n \"ochre\",\n \"olive\",\n \"orange\",\n \"orchid\",\n \"peach\",\n \"pine\",\n \"pink\",\n \"plum\",\n \"porcelain\",\n \"purple\",\n \"quartz\",\n \"rust\",\n \"saffron\",\n \"salmon\",\n \"sand\",\n \"sapphire\",\n \"scarlet\",\n \"sepia\",\n \"shadow\",\n \"sienna\",\n \"smoke\",\n \"snow\",\n \"steel\",\n \"stone\",\n \"storm\",\n \"sunset\",\n \"tan\",\n \"tangerine\",\n \"taupe\",\n \"terra\",\n \"timber\",\n \"topaz\",\n \"turquoise\",\n \"umber\",\n \"vanilla\",\n \"walnut\",\n \"wheat\",\n \"white\",\n \"wine\",\n \"yellow\",\n];\n\nconst ANIMALS = [\n \"fox\",\n \"owl\",\n \"bear\",\n \"wolf\",\n \"hawk\",\n \"deer\",\n \"lynx\",\n \"otter\",\n \"raven\",\n \"falcon\",\n \"badger\",\n \"beaver\",\n \"bison\",\n \"bobcat\",\n \"crane\",\n \"eagle\",\n \"ferret\",\n \"finch\",\n \"gopher\",\n \"heron\",\n \"jaguar\",\n \"koala\",\n \"lemur\",\n \"marten\",\n \"mink\",\n \"moose\",\n \"newt\",\n \"ocelot\",\n \"osprey\",\n \"panda\",\n \"parrot\",\n \"pelican\",\n \"puma\",\n \"quail\",\n \"rabbit\",\n \"raccoon\",\n \"salmon\",\n \"seal\",\n \"shark\",\n \"shrew\",\n \"sloth\",\n \"snake\",\n \"spider\",\n \"squid\",\n \"stork\",\n \"swan\",\n \"tiger\",\n \"toucan\",\n \"turtle\",\n \"whale\",\n \"albatross\",\n \"ant\",\n \"antelope\",\n \"armadillo\",\n \"baboon\",\n \"bat\",\n \"bee\",\n \"beetle\",\n \"buffalo\",\n \"butterfly\",\n \"camel\",\n \"cardinal\",\n \"caribou\",\n \"catfish\",\n \"cheetah\",\n \"chipmunk\",\n \"cicada\",\n \"clam\",\n \"cobra\",\n \"condor\",\n \"corgi\",\n \"cougar\",\n \"coyote\",\n \"crab\",\n \"cricket\",\n \"crow\",\n \"dolphin\",\n \"donkey\",\n \"dove\",\n \"dragonfly\",\n \"duck\",\n \"eel\",\n \"egret\",\n \"elephant\",\n \"elk\",\n \"emu\",\n \"firefly\",\n \"flamingo\",\n \"frog\",\n \"gazelle\",\n \"gecko\",\n \"gibbon\",\n \"giraffe\",\n \"goat\",\n \"goose\",\n \"gorilla\",\n \"grasshopper\",\n \"grouse\",\n \"gull\",\n \"hamster\",\n \"hare\",\n \"hedgehog\",\n \"hippo\",\n \"hornet\",\n \"horse\",\n \"hound\",\n \"hummingbird\",\n \"hyena\",\n \"ibis\",\n \"iguana\",\n \"impala\",\n \"jackal\",\n \"jay\",\n \"jellyfish\",\n \"kangaroo\",\n \"kestrel\",\n \"kingfisher\",\n \"kite\",\n \"kiwi\",\n \"lark\",\n \"leopard\",\n \"lion\",\n \"lizard\",\n \"llama\",\n \"lobster\",\n \"loon\",\n \"macaw\",\n \"magpie\",\n \"mallard\",\n \"mammoth\",\n \"manatee\",\n \"mantis\",\n \"marlin\",\n \"marmot\",\n \"meerkat\",\n \"mockingbird\",\n \"mole\",\n \"mongoose\",\n \"monkey\",\n \"moth\",\n \"mouse\",\n \"mule\",\n \"narwhal\",\n \"nightingale\",\n \"octopus\",\n \"opossum\",\n \"orangutan\",\n \"oriole\",\n \"ostrich\",\n \"oyster\",\n \"panther\",\n \"peacock\",\n \"penguin\",\n \"pheasant\",\n \"pig\",\n \"pigeon\",\n \"pike\",\n \"piranha\",\n \"platypus\",\n \"pony\",\n \"porcupine\",\n \"porpoise\",\n \"python\",\n \"raven\",\n \"ray\",\n \"reindeer\",\n \"rhino\",\n \"robin\",\n \"rooster\",\n \"salamander\",\n \"sandpiper\",\n \"sardine\",\n \"scorpion\",\n \"seagull\",\n \"seahorse\",\n \"skunk\",\n \"snail\",\n \"sparrow\",\n \"squirrel\",\n \"starfish\",\n \"starling\",\n \"stingray\",\n \"swallow\",\n \"tapir\",\n \"termite\",\n \"tern\",\n \"toad\",\n \"trout\",\n \"tuna\",\n \"viper\",\n \"vulture\",\n \"walrus\",\n \"wasp\",\n \"weasel\",\n \"wombat\",\n \"woodpecker\",\n \"wren\",\n \"yak\",\n \"zebra\",\n];\n\nconst WORKTREE_FOLDER_NAME = \".array\";\n\nexport class WorktreeManager {\n private mainRepoPath: string;\n private worktreeBasePath: string | null;\n private repoName: string;\n private logger: Logger;\n\n constructor(config: WorktreeConfig) {\n this.mainRepoPath = config.mainRepoPath;\n this.worktreeBasePath = config.worktreeBasePath || null;\n this.repoName = path.basename(config.mainRepoPath);\n this.logger =\n config.logger ||\n new Logger({ debug: false, prefix: \"[WorktreeManager]\" });\n }\n\n private usesExternalPath(): boolean {\n return this.worktreeBasePath !== null;\n }\n\n private async runGitCommand(command: string): Promise<string> {\n try {\n const { stdout } = await execAsync(`git ${command}`, {\n cwd: this.mainRepoPath,\n });\n return stdout.trim();\n } catch (error) {\n throw new Error(`Git command failed: ${command}\\n${error}`);\n }\n }\n\n private randomElement<T>(array: T[]): T {\n return array[crypto.randomInt(array.length)];\n }\n\n generateWorktreeName(): string {\n const adjective = this.randomElement(ADJECTIVES);\n const color = this.randomElement(COLORS);\n const animal = this.randomElement(ANIMALS);\n return `${adjective}-${color}-${animal}`;\n }\n\n private getWorktreeFolderPath(): string {\n if (this.worktreeBasePath) {\n return path.join(this.worktreeBasePath, this.repoName);\n }\n return path.join(this.mainRepoPath, WORKTREE_FOLDER_NAME);\n }\n\n private getWorktreePath(name: string): string {\n return path.join(this.getWorktreeFolderPath(), name);\n }\n\n async worktreeExists(name: string): Promise<boolean> {\n const worktreePath = this.getWorktreePath(name);\n try {\n await fs.access(worktreePath);\n return true;\n } catch {\n return false;\n }\n }\n\n async ensureArrayDirIgnored(): Promise<void> {\n // Use .git/info/exclude instead of .gitignore to avoid modifying tracked files\n const excludePath = path.join(this.mainRepoPath, \".git\", \"info\", \"exclude\");\n const ignorePattern = `/${WORKTREE_FOLDER_NAME}/`;\n\n let content = \"\";\n try {\n content = await fs.readFile(excludePath, \"utf-8\");\n } catch {\n // File doesn't exist or .git/info doesn't exist\n }\n\n // Check if pattern is already present\n if (\n content.includes(`/${WORKTREE_FOLDER_NAME}/`) ||\n content.includes(`/${WORKTREE_FOLDER_NAME}`)\n ) {\n this.logger.debug(\"Exclude file already contains .array folder pattern\");\n return;\n }\n\n // Ensure .git/info directory exists\n const infoDir = path.join(this.mainRepoPath, \".git\", \"info\");\n await fs.mkdir(infoDir, { recursive: true });\n\n // Append the pattern\n const newContent = `${content.trimEnd()}\\n\\n# Array worktrees\\n${ignorePattern}\\n`;\n await fs.writeFile(excludePath, newContent);\n this.logger.info(\"Added .array folder to .git/info/exclude\");\n }\n\n private async generateUniqueWorktreeName(): Promise<string> {\n let name = this.generateWorktreeName();\n let attempts = 0;\n const maxAttempts = 100;\n\n while ((await this.worktreeExists(name)) && attempts < maxAttempts) {\n name = this.generateWorktreeName();\n attempts++;\n }\n\n if (attempts >= maxAttempts) {\n // Fallback: append timestamp\n name = `${this.generateWorktreeName()}-${Date.now()}`;\n }\n\n return name;\n }\n\n private async getDefaultBranch(): Promise<string> {\n try {\n const remoteBranch = await this.runGitCommand(\n \"symbolic-ref refs/remotes/origin/HEAD\",\n );\n return remoteBranch.replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Fallback: check if main exists, otherwise use master\n try {\n await this.runGitCommand(\"rev-parse --verify main\");\n return \"main\";\n } catch {\n try {\n await this.runGitCommand(\"rev-parse --verify master\");\n return \"master\";\n } catch {\n throw new Error(\n \"Cannot determine default branch. No main or master branch found.\",\n );\n }\n }\n }\n }\n\n async createWorktree(): Promise<WorktreeInfo> {\n // Only modify .git/info/exclude when using in-repo storage\n if (!this.usesExternalPath()) {\n await this.ensureArrayDirIgnored();\n }\n\n // Ensure the worktree folder exists when using external path\n if (this.usesExternalPath()) {\n const folderPath = this.getWorktreeFolderPath();\n await fs.mkdir(folderPath, { recursive: true });\n }\n\n // Generate unique worktree name\n const worktreeName = await this.generateUniqueWorktreeName();\n const worktreePath = this.getWorktreePath(worktreeName);\n const branchName = `array/${worktreeName}`;\n const baseBranch = await this.getDefaultBranch();\n\n this.logger.info(\"Creating worktree\", {\n worktreeName,\n worktreePath,\n branchName,\n baseBranch,\n external: this.usesExternalPath(),\n });\n\n // Create the worktree with a new branch\n if (this.usesExternalPath()) {\n // Use absolute path for external worktrees\n await this.runGitCommand(\n `worktree add -b \"${branchName}\" \"${worktreePath}\" \"${baseBranch}\"`,\n );\n } else {\n // Use relative path from repo root for in-repo worktrees\n const relativePath = `${WORKTREE_FOLDER_NAME}/${worktreeName}`;\n await this.runGitCommand(\n `worktree add -b \"${branchName}\" \"./${relativePath}\" \"${baseBranch}\"`,\n );\n }\n\n const createdAt = new Date().toISOString();\n\n this.logger.info(\"Worktree created successfully\", {\n worktreeName,\n worktreePath,\n branchName,\n });\n\n return {\n worktreePath,\n worktreeName,\n branchName,\n baseBranch,\n createdAt,\n };\n }\n\n async deleteWorktree(worktreePath: string): Promise<void> {\n this.logger.info(\"Deleting worktree\", { worktreePath });\n\n try {\n // First, try to remove the worktree via git using execFileAsync for safety\n await execFileAsync(\n \"git\",\n [\"worktree\", \"remove\", worktreePath, \"--force\"],\n {\n cwd: this.mainRepoPath,\n },\n );\n this.logger.info(\"Worktree deleted successfully\", { worktreePath });\n } catch (error) {\n this.logger.warn(\n \"Git worktree remove failed, attempting manual cleanup\",\n {\n worktreePath,\n error,\n },\n );\n\n // Manual cleanup if git command fails\n try {\n await fs.rm(worktreePath, { recursive: true, force: true });\n // Also prune the worktree list\n await this.runGitCommand(\"worktree prune\");\n this.logger.info(\"Worktree cleaned up manually\", { worktreePath });\n } catch (cleanupError) {\n this.logger.error(\"Failed to cleanup worktree\", {\n worktreePath,\n cleanupError,\n });\n throw cleanupError;\n }\n }\n }\n\n async getWorktreeInfo(worktreePath: string): Promise<WorktreeInfo | null> {\n try {\n // Parse the worktree list to find info about this worktree\n const output = await this.runGitCommand(\"worktree list --porcelain\");\n const worktrees = this.parseWorktreeList(output);\n\n const worktree = worktrees.find((w) => w.worktreePath === worktreePath);\n return worktree || null;\n } catch (error) {\n this.logger.debug(\"Failed to get worktree info\", { worktreePath, error });\n return null;\n }\n }\n\n async listWorktrees(): Promise<WorktreeInfo[]> {\n try {\n const output = await this.runGitCommand(\"worktree list --porcelain\");\n return this.parseWorktreeList(output);\n } catch (error) {\n this.logger.debug(\"Failed to list worktrees\", { error });\n return [];\n }\n }\n\n private parseWorktreeList(output: string): WorktreeInfo[] {\n const worktrees: WorktreeInfo[] = [];\n const entries = output.split(\"\\n\\n\").filter((e) => e.trim());\n const worktreeFolderPath = this.getWorktreeFolderPath();\n\n for (const entry of entries) {\n const lines = entry.split(\"\\n\");\n let worktreePath = \"\";\n let branchName = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"worktree \")) {\n worktreePath = line.replace(\"worktree \", \"\");\n } else if (line.startsWith(\"branch refs/heads/\")) {\n branchName = line.replace(\"branch refs/heads/\", \"\");\n }\n }\n\n // Include worktrees that:\n // 1. Are in our worktree folder (external or in-repo)\n // 2. Have a posthog/ branch prefix (our naming convention)\n const isInWorktreeFolder = worktreePath?.startsWith(worktreeFolderPath);\n const isArrayBranch =\n branchName?.startsWith(\"array/\") || branchName?.startsWith(\"posthog/\");\n\n if (worktreePath && branchName && (isInWorktreeFolder || isArrayBranch)) {\n const worktreeName = path.basename(worktreePath);\n worktrees.push({\n worktreePath,\n worktreeName,\n branchName,\n baseBranch: \"\",\n createdAt: \"\",\n });\n }\n }\n\n return worktrees;\n }\n\n async isWorktree(repoPath: string): Promise<boolean> {\n try {\n const { stdout } = await execAsync(\n \"git rev-parse --is-inside-work-tree\",\n { cwd: repoPath },\n );\n if (stdout.trim() !== \"true\") {\n return false;\n }\n\n // Check if there's a .git file (worktrees have a .git file, not a .git directory)\n const gitPath = path.join(repoPath, \".git\");\n const stat = await fs.stat(gitPath);\n return stat.isFile(); // Worktrees have .git as a file, main repos have .git as a directory\n } catch {\n return false;\n }\n }\n\n async getMainRepoPathFromWorktree(\n worktreePath: string,\n ): Promise<string | null> {\n try {\n const gitFilePath = path.join(worktreePath, \".git\");\n const content = await fs.readFile(gitFilePath, \"utf-8\");\n\n // The .git file in a worktree contains: gitdir: /path/to/main/.git/worktrees/name\n const match = content.match(/gitdir:\\s*(.+)/);\n if (match) {\n const gitDir = match[1].trim();\n // Go up from .git/worktrees/name to get the main repo path\n // The gitdir points to something like: /main/repo/.git/worktrees/worktree-name\n const mainGitDir = path.resolve(gitDir, \"..\", \"..\", \"..\");\n return mainGitDir;\n }\n return null;\n } catch {\n return null;\n }\n }\n\n async cleanupOrphanedWorktrees(associatedWorktreePaths: string[]): Promise<{\n deleted: string[];\n errors: Array<{ path: string; error: string }>;\n }> {\n this.logger.info(\"Starting cleanup of orphaned worktrees\");\n\n const allWorktrees = await this.listWorktrees();\n const deleted: string[] = [];\n const errors: Array<{ path: string; error: string }> = [];\n\n const associatedPathsSet = new Set(\n associatedWorktreePaths.map((p) => path.resolve(p)),\n );\n\n for (const worktree of allWorktrees) {\n const resolvedPath = path.resolve(worktree.worktreePath);\n\n if (!associatedPathsSet.has(resolvedPath)) {\n this.logger.info(\"Found orphaned worktree\", {\n path: worktree.worktreePath,\n });\n\n try {\n await this.deleteWorktree(worktree.worktreePath);\n deleted.push(worktree.worktreePath);\n this.logger.info(\"Deleted orphaned worktree\", {\n path: worktree.worktreePath,\n });\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n errors.push({\n path: worktree.worktreePath,\n error: errorMessage,\n });\n this.logger.error(\"Failed to delete orphaned worktree\", {\n path: worktree.worktreePath,\n error: errorMessage,\n });\n }\n }\n }\n\n this.logger.info(\"Cleanup completed\", {\n deleted: deleted.length,\n errors: errors.length,\n });\n\n return { deleted, errors };\n }\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/agent",
3
- "version": "1.25.0",
3
+ "version": "1.26.0",
4
4
  "repository": "https://github.com/PostHog/array",
5
5
  "description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
6
6
  "main": "./dist/index.js",
@@ -171,7 +171,7 @@ export class ClaudeAcpAgent implements Agent {
171
171
  fileContentCache: { [key: string]: string };
172
172
  backgroundTerminals: { [key: string]: BackgroundTerminal } = {};
173
173
  clientCapabilities?: ClientCapabilities;
174
- logger: Logger = new Logger({ debug: false, prefix: "[ClaudeAcpAgent]" });
174
+ logger: Logger = new Logger({ debug: true, prefix: "[ClaudeAcpAgent]" });
175
175
  sessionStore?: SessionStore;
176
176
 
177
177
  constructor(client: AgentSideConnection, sessionStore?: SessionStore) {
@@ -341,9 +341,13 @@ export class ClaudeAcpAgent implements Agent {
341
341
  allowDangerouslySkipPermissions: !IS_ROOT,
342
342
  permissionMode,
343
343
  canUseTool: this.canUseTool(sessionId),
344
- // note: although not documented by the types, passing an absolute path
345
- // here works to find zed's managed node version.
346
- executable: process.execPath as any,
344
+ // Use "node" to resolve via PATH where a symlink to Electron exists.
345
+ // This avoids launching the Electron binary directly from the app bundle,
346
+ // which can cause dock icons to appear on macOS even with ELECTRON_RUN_AS_NODE.
347
+ executable: "node",
348
+ // Prevent spawned Electron processes from showing in dock/tray.
349
+ // Must merge with process.env since SDK replaces rather than merges.
350
+ env: { ...process.env, ELECTRON_RUN_AS_NODE: "1" },
347
351
  ...(process.env.CLAUDE_CODE_EXECUTABLE && {
348
352
  pathToClaudeCodeExecutable: process.env.CLAUDE_CODE_EXECUTABLE,
349
353
  }),
@@ -930,6 +934,7 @@ export class ClaudeAcpAgent implements Agent {
930
934
  async resumeSession(
931
935
  params: LoadSessionRequest,
932
936
  ): Promise<LoadSessionResponse> {
937
+ this.logger.info("[RESUME] Resuming session", { params });
933
938
  const { sessionId } = params;
934
939
 
935
940
  // Extract persistence config and SDK session ID from _meta
@@ -976,6 +981,11 @@ export class ClaudeAcpAgent implements Agent {
976
981
 
977
982
  const permissionMode = "default";
978
983
 
984
+ this.logger.info("Resuming session", {
985
+ cwd: params.cwd,
986
+ sdkSessionId,
987
+ persistence,
988
+ });
979
989
  const options: Options = {
980
990
  cwd: params.cwd,
981
991
  includePartialMessages: true,
@@ -986,7 +996,13 @@ export class ClaudeAcpAgent implements Agent {
986
996
  permissionMode,
987
997
  canUseTool: this.canUseTool(sessionId),
988
998
  stderr: (err) => this.logger.error(err),
989
- executable: process.execPath as any,
999
+ // Use "node" to resolve via PATH where a symlink to Electron exists.
1000
+ // This avoids launching the Electron binary directly from the app bundle,
1001
+ // which can cause dock icons to appear on macOS even with ELECTRON_RUN_AS_NODE.
1002
+ executable: "node",
1003
+ // Prevent spawned Electron processes from showing in dock/tray.
1004
+ // Must merge with process.env since SDK replaces rather than merges.
1005
+ env: { ...process.env, ELECTRON_RUN_AS_NODE: "1" },
990
1006
  ...(process.env.CLAUDE_CODE_EXECUTABLE && {
991
1007
  pathToClaudeCodeExecutable: process.env.CLAUDE_CODE_EXECUTABLE,
992
1008
  }),
@@ -153,7 +153,14 @@ export function toolInfoFromToolUse(
153
153
  title: "Read File",
154
154
  kind: "read",
155
155
  content: [],
156
- locations: [{ path: input.file_path, line: input.offset ?? 0 }],
156
+ locations: input.file_path
157
+ ? [
158
+ {
159
+ path: input.file_path,
160
+ line: input.offset ?? 0,
161
+ },
162
+ ]
163
+ : [],
157
164
  };
158
165
 
159
166
  case "LS":
package/src/agent.ts CHANGED
@@ -1,3 +1,13 @@
1
+ import {
2
+ type Client,
3
+ ClientSideConnection,
4
+ type ContentBlock,
5
+ ndJsonStream,
6
+ PROTOCOL_VERSION,
7
+ type RequestPermissionRequest,
8
+ type RequestPermissionResponse,
9
+ type SessionNotification,
10
+ } from "@agentclientprotocol/sdk";
1
11
  import { POSTHOG_NOTIFICATIONS } from "./acp-extensions.js";
2
12
  import {
3
13
  createAcpConnection,
@@ -10,7 +20,13 @@ import { PromptBuilder } from "./prompt-builder.js";
10
20
  import { SessionStore } from "./session-store.js";
11
21
  import { TaskManager } from "./task-manager.js";
12
22
  import { TemplateManager } from "./template-manager.js";
13
- import type { AgentConfig, CanUseTool, Task } from "./types.js";
23
+ import type {
24
+ AgentConfig,
25
+ CanUseTool,
26
+ StoredNotification,
27
+ Task,
28
+ TaskExecutionOptions,
29
+ } from "./types.js";
14
30
  import { Logger } from "./utils/logger.js";
15
31
  import { TASK_WORKFLOW } from "./workflow/config.js";
16
32
  import type { SendNotification, WorkflowRuntime } from "./workflow/types.js";
@@ -312,6 +328,29 @@ export class Agent {
312
328
  return this.posthogAPI;
313
329
  }
314
330
 
331
+ /**
332
+ * Send a notification to a cloud task run's S3 log.
333
+ * The cloud runner will pick up new notifications via interrupt polling.
334
+ */
335
+ async sendNotification(
336
+ taskId: string,
337
+ runId: string,
338
+ notification: StoredNotification,
339
+ ): Promise<void> {
340
+ if (!this.posthogAPI) {
341
+ throw new Error(
342
+ "PostHog API not configured. Cannot send notification to cloud task.",
343
+ );
344
+ }
345
+
346
+ await this.posthogAPI.appendTaskRunLog(taskId, runId, [notification]);
347
+ this.logger.debug("Notification sent to cloud task", {
348
+ taskId,
349
+ runId,
350
+ method: notification.notification.method,
351
+ });
352
+ }
353
+
315
354
  async getTaskFiles(taskId: string): Promise<any[]> {
316
355
  this.logger.debug("Getting task files", { taskId });
317
356
  const files = await this.fileManager.getTaskFiles(taskId);
@@ -493,6 +532,179 @@ Generated by PostHog Agent`;
493
532
  }
494
533
  }
495
534
 
535
+ async runTaskCloud(
536
+ taskId: string,
537
+ taskRunId: string,
538
+ options: TaskExecutionOptions = {},
539
+ ): Promise<void> {
540
+ await this._configureLlmGateway();
541
+
542
+ const task = await this.fetchTask(taskId);
543
+ const cwd = options.repositoryPath || this.workingDirectory;
544
+ const taskSlug = (task as any).slug || task.id;
545
+
546
+ this.currentRunId = taskRunId;
547
+
548
+ this.logger.info("Starting cloud task execution", {
549
+ taskId: task.id,
550
+ taskSlug,
551
+ taskRunId,
552
+ cwd,
553
+ });
554
+
555
+ if (!this.sessionStore) {
556
+ throw new Error(
557
+ "SessionStore required for cloud mode. Ensure PostHog API credentials are configured.",
558
+ );
559
+ }
560
+
561
+ // Start session in SessionStore (updates task run status to in_progress)
562
+ const taskRun = await this.sessionStore.start(taskRunId, taskId, taskRunId);
563
+ this.logger.debug("Session started", {
564
+ taskRunId,
565
+ logUrl: taskRun?.log_url,
566
+ });
567
+
568
+ // Create internal ACP connection with S3 persistence
569
+ const acpConnection = createAcpConnection({
570
+ sessionStore: this.sessionStore,
571
+ sessionId: taskRunId,
572
+ taskId: task.id,
573
+ });
574
+
575
+ // Create client connection using the client-side streams
576
+ const clientStream = ndJsonStream(
577
+ acpConnection.clientStreams.writable as WritableStream<Uint8Array>,
578
+ acpConnection.clientStreams.readable as ReadableStream<Uint8Array>,
579
+ );
580
+
581
+ // Create auto-approving client for headless cloud mode
582
+ const cloudClient: Client = {
583
+ async requestPermission(params) {
584
+ const allowOption = params.options.find(
585
+ (o) => o.kind === "allow_once" || o.kind === "allow_always",
586
+ );
587
+ return {
588
+ outcome: {
589
+ outcome: "selected",
590
+ optionId: allowOption?.optionId ?? params.options[0].optionId,
591
+ },
592
+ };
593
+ },
594
+ async sessionUpdate(_params) {
595
+ // Notifications are already being persisted to S3 via tapped streams
596
+ },
597
+ };
598
+
599
+ const clientConnection = new ClientSideConnection(
600
+ (_agent) => cloudClient,
601
+ clientStream,
602
+ );
603
+
604
+ try {
605
+ // Initialize the connection
606
+ await clientConnection.initialize({
607
+ protocolVersion: PROTOCOL_VERSION,
608
+ clientCapabilities: {},
609
+ });
610
+
611
+ // Create new session
612
+ await clientConnection.newSession({
613
+ cwd,
614
+ mcpServers: [],
615
+ _meta: { sessionId: taskRunId },
616
+ });
617
+
618
+ // Prepare git branch if not skipped
619
+ if (!options.skipGitBranch) {
620
+ const sendNotification: SendNotification = async (method, params) => {
621
+ this.logger.debug(`Notification: ${method}`, params);
622
+ await acpConnection.agentConnection.extNotification?.(method, params);
623
+ };
624
+ await this.prepareTaskBranch(taskSlug, true, sendNotification);
625
+ }
626
+
627
+ // Build initial prompt from task description
628
+ const initialPrompt: ContentBlock[] = [
629
+ {
630
+ type: "text",
631
+ text: `# Task: ${task.title}\n\n${task.description}`,
632
+ },
633
+ ];
634
+
635
+ // Track the last known log entry count for interrupt polling
636
+ let lastKnownEntryCount = 0;
637
+ let isPolling = true;
638
+
639
+ // Start interrupt polling in background
640
+ const pollForInterrupts = async () => {
641
+ while (isPolling) {
642
+ await new Promise((resolve) => setTimeout(resolve, 2000)); // Poll every 2 seconds
643
+ if (!isPolling) break;
644
+
645
+ try {
646
+ const newEntries = await this.sessionStore!.pollForNewEntries(
647
+ taskRunId,
648
+ lastKnownEntryCount,
649
+ );
650
+
651
+ for (const entry of newEntries) {
652
+ lastKnownEntryCount++;
653
+ // Look for user_message notifications
654
+ if (
655
+ entry.notification?.method === "sessionUpdate" &&
656
+ (entry.notification?.params as any)?.sessionUpdate ===
657
+ "user_message"
658
+ ) {
659
+ const content = (entry.notification?.params as any)?.content;
660
+ if (content) {
661
+ this.logger.info("Processing user interrupt", { content });
662
+ // Send as new prompt - will be processed after current prompt completes
663
+ await clientConnection.prompt({
664
+ sessionId: taskRunId,
665
+ prompt: Array.isArray(content) ? content : [content],
666
+ });
667
+ }
668
+ }
669
+ }
670
+ } catch (err) {
671
+ this.logger.warn("Interrupt polling error", { error: err });
672
+ }
673
+ }
674
+ };
675
+
676
+ // Start polling in background (don't await)
677
+ const pollingPromise = pollForInterrupts();
678
+
679
+ // Send initial prompt and wait for completion
680
+ this.logger.info("Sending initial prompt to agent");
681
+ const result = await clientConnection.prompt({
682
+ sessionId: taskRunId,
683
+ prompt: initialPrompt,
684
+ });
685
+
686
+ // Stop interrupt polling
687
+ isPolling = false;
688
+ await pollingPromise;
689
+
690
+ this.logger.info("Task execution complete", {
691
+ taskId: task.id,
692
+ stopReason: result.stopReason,
693
+ });
694
+
695
+ await this.sessionStore.complete(taskRunId);
696
+ } catch (error) {
697
+ const errorMessage =
698
+ error instanceof Error ? error.message : String(error);
699
+ this.logger.error("Cloud task execution failed", {
700
+ taskId: task.id,
701
+ error: errorMessage,
702
+ });
703
+ await this.sessionStore.fail(taskRunId, errorMessage);
704
+ throw error;
705
+ }
706
+ }
707
+
496
708
  private async ensurePullRequest(
497
709
  task: Task,
498
710
  stepResults: Record<string, any>,
@@ -90,7 +90,7 @@ export class SessionStore {
90
90
  }
91
91
 
92
92
  /** Load raw JSON-RPC messages from S3 */
93
- async load(logUrl: string): Promise<unknown[]> {
93
+ async load(logUrl: string): Promise<StoredNotification[]> {
94
94
  const response = await fetch(logUrl);
95
95
 
96
96
  if (!response.ok) {
@@ -105,12 +105,27 @@ export class SessionStore {
105
105
  .split("\n")
106
106
  .map((line) => {
107
107
  try {
108
- return JSON.parse(line);
108
+ return JSON.parse(line) as StoredNotification;
109
109
  } catch {
110
110
  return null;
111
111
  }
112
112
  })
113
- .filter((entry): entry is unknown => entry !== null);
113
+ .filter((entry): entry is StoredNotification => entry !== null);
114
+ }
115
+
116
+ /**
117
+ * Poll S3 for new entries since last check.
118
+ * Used for interrupt handling in cloud mode.
119
+ */
120
+ async pollForNewEntries(
121
+ sessionId: string,
122
+ lastKnownCount: number,
123
+ ): Promise<StoredNotification[]> {
124
+ const config = this.configs.get(sessionId);
125
+ if (!config?.logUrl) return [];
126
+
127
+ const entries = await this.load(config.logUrl);
128
+ return entries.slice(lastKnownCount);
114
129
  }
115
130
 
116
131
  /** Force flush pending entries */
@@ -643,7 +643,7 @@ export class WorktreeManager {
643
643
  // Generate unique worktree name
644
644
  const worktreeName = await this.generateUniqueWorktreeName();
645
645
  const worktreePath = this.getWorktreePath(worktreeName);
646
- const branchName = `posthog/${worktreeName}`;
646
+ const branchName = `array/${worktreeName}`;
647
647
  const baseBranch = await this.getDefaultBranch();
648
648
 
649
649
  this.logger.info("Creating worktree", {
@@ -769,13 +769,10 @@ export class WorktreeManager {
769
769
  // 1. Are in our worktree folder (external or in-repo)
770
770
  // 2. Have a posthog/ branch prefix (our naming convention)
771
771
  const isInWorktreeFolder = worktreePath?.startsWith(worktreeFolderPath);
772
- const isPosthogBranch = branchName?.startsWith("posthog/");
772
+ const isArrayBranch =
773
+ branchName?.startsWith("array/") || branchName?.startsWith("posthog/");
773
774
 
774
- if (
775
- worktreePath &&
776
- branchName &&
777
- (isInWorktreeFolder || isPosthogBranch)
778
- ) {
775
+ if (worktreePath && branchName && (isInWorktreeFolder || isArrayBranch)) {
779
776
  const worktreeName = path.basename(worktreePath);
780
777
  worktrees.push({
781
778
  worktreePath,