@oxgeneral/orch 0.3.2 → 0.3.4
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/App-RKAPZNZO.js +6682 -0
- package/dist/agent-KBTLGGCT.js +183 -0
- package/dist/agent-shop-YN2BSLHM.js +2 -0
- package/dist/chunk-2C2TFQ7K.js +136 -0
- package/dist/chunk-45K2XID7.js +29 -0
- package/dist/{shell-IH2MMTVP.js → chunk-52BFUGDD.js} +8 -6
- package/dist/chunk-7X2GI5OV.js +181 -0
- package/dist/{chunk-HSBYJ5C5.js → chunk-A36WAF2S.js} +89 -2
- package/dist/chunk-CHIP7O6V.js +83 -0
- package/dist/{claude-RIB3RQS5.js → chunk-D6RFF3KN.js} +12 -9
- package/dist/{chunk-BCPUTULS.js → chunk-DAVHOWGD.js} +188 -16
- package/dist/chunk-FRTKB575.js +87 -0
- package/dist/chunk-HXYAZGLP.js +15 -0
- package/dist/chunk-I3SMISEF.js +29 -0
- package/dist/chunk-K6DMQERQ.js +89 -0
- package/dist/chunk-LV6GDBBI.js +297 -0
- package/dist/chunk-NLQAJ7TW.js +147 -0
- package/dist/chunk-NLQAJ7TW.js.map +1 -0
- package/dist/chunk-P6ATSXGL.js +107 -0
- package/dist/chunk-PNE6LQRF.js +5 -0
- package/dist/{chunk-MGFMVPRD.js → chunk-S3QYSBW4.js} +11 -4
- package/dist/chunk-S3QYSBW4.js.map +1 -0
- package/dist/chunk-U2VDNUZL.js +52 -0
- package/dist/{chunk-QEEM67OA.js → chunk-UIJYU3J7.js} +3 -3
- package/dist/{chunk-QEEM67OA.js.map → chunk-UIJYU3J7.js.map} +1 -1
- package/dist/{chunk-2UC4SVJB.js → chunk-VMDQVRBR.js} +22 -8
- package/dist/chunk-VMDQVRBR.js.map +1 -0
- package/dist/chunk-W6RSVMXR.js +66 -0
- package/dist/claude-INM52PTH.js +88 -0
- package/dist/claude-INM52PTH.js.map +1 -0
- package/dist/claude-NHUNA5RZ.js +5 -0
- package/dist/cli.js +199 -1
- package/dist/clipboard-service-RTDUUQQU.js +200 -0
- package/dist/{codex-VBUSA2GJ.js → codex-DIXT44JR.js} +17 -11
- package/dist/codex-QGH2GRV6.js +125 -0
- package/dist/codex-QGH2GRV6.js.map +1 -0
- package/dist/config-OTAVSMOD.js +75 -0
- package/dist/container-LJU4QNDH.js +1594 -0
- package/dist/context-OL4BVUV5.js +83 -0
- package/dist/{cursor-4QIOTDBW.js → cursor-C3TR2IJC.js} +11 -8
- package/dist/cursor-KQJTQ73D.js +99 -0
- package/dist/cursor-KQJTQ73D.js.map +1 -0
- package/dist/doctor-V2FPS236.js +67 -0
- package/dist/doctor-service-TPOMFAIG.js +2 -0
- package/dist/goal-FMYYN2FR.js +138 -0
- package/dist/index.d.ts +64 -41
- package/dist/index.js +23 -14
- package/dist/index.js.map +1 -1
- package/dist/init-U7MCIOB2.js +165 -0
- package/dist/logs-PHPYWQ6I.js +207 -0
- package/dist/msg-FUWWLEKM.js +95 -0
- package/dist/orchestrator-ADO66XZ3.js +5 -0
- package/dist/{orchestrator-FGGXK3N3.js.map → orchestrator-ADO66XZ3.js.map} +1 -1
- package/dist/orchestrator-E3FQ4SOE.js +1424 -0
- package/dist/process-manager-HUVNAPQV.js +2 -0
- package/dist/registry-PQWRVNF2.js +2 -0
- package/dist/run-N72G5V2H.js +95 -0
- package/dist/shell-3S4VLYEG.js +4 -0
- package/dist/shell-JXOPKDXH.js +221 -0
- package/dist/shell-JXOPKDXH.js.map +1 -0
- package/dist/shop-picker-2HY67UWP.js +79 -0
- package/dist/status-RZWN2C6C.js +56 -0
- package/dist/task-2TJW6Z7O.js +221 -0
- package/dist/team-PFLP4PPL.js +97 -0
- package/dist/template-engine-4IZKRRHG.js +3 -0
- package/dist/tui-IM3YUUVD.js +245 -0
- package/dist/update-YLP7FPNY.js +64 -0
- package/dist/update-check-4YKLGBFB.js +2 -0
- package/dist/{workspace-manager-T6AXG7XL.js → workspace-manager-EVD67GCG.js} +4 -4
- package/dist/{workspace-manager-T6AXG7XL.js.map → workspace-manager-EVD67GCG.js.map} +1 -1
- package/dist/workspace-manager-JM6U7JOH.js +215 -0
- package/package.json +1 -1
- package/readme.md +9 -2
- package/scripts/postinstall.js +44 -2
- package/dist/App-YJM5QGP7.js +0 -19
- package/dist/agent-S4DKSX63.js +0 -9
- package/dist/agent-shop-D2RS4BZK.js +0 -2
- package/dist/chunk-2UC4SVJB.js.map +0 -1
- package/dist/chunk-5AJ4LYO5.js +0 -8
- package/dist/chunk-6MJ7V6VY.js +0 -2
- package/dist/chunk-CDFA4IIQ.js +0 -2
- package/dist/chunk-CHRW4CLD.js +0 -2
- package/dist/chunk-GZ2Q56YZ.js +0 -2
- package/dist/chunk-HMMPM7MF.js +0 -3
- package/dist/chunk-HXOMNULD.js +0 -2
- package/dist/chunk-IQXRQBUK.js +0 -83
- package/dist/chunk-IQXRQBUK.js.map +0 -1
- package/dist/chunk-L26TK7Y5.js +0 -2
- package/dist/chunk-L3FYR45M.js +0 -2
- package/dist/chunk-LXNRCJ22.js +0 -2
- package/dist/chunk-MGFMVPRD.js.map +0 -1
- package/dist/chunk-MNXU3KCD.js +0 -2
- package/dist/chunk-PJ5DKXGR.js +0 -2
- package/dist/chunk-UMZEA3JT.js +0 -5
- package/dist/chunk-UW6GUUE6.js +0 -3
- package/dist/chunk-ZA5Z33GO.js +0 -11
- package/dist/claude-E36EGXUV.js +0 -2
- package/dist/claude-RIB3RQS5.js.map +0 -1
- package/dist/clipboard-service-PDTSZIR5.js +0 -25
- package/dist/codex-OTZKVESD.js +0 -2
- package/dist/codex-VBUSA2GJ.js.map +0 -1
- package/dist/config-CCSS2P7R.js +0 -2
- package/dist/container-OIXLFSX2.js +0 -6
- package/dist/context-GSMQHQES.js +0 -7
- package/dist/cursor-3DJA6LWS.js +0 -2
- package/dist/cursor-4QIOTDBW.js.map +0 -1
- package/dist/doctor-KBK5JZBZ.js +0 -2
- package/dist/doctor-service-PB7YBH3F.js +0 -2
- package/dist/goal-RFKFPR7M.js +0 -8
- package/dist/init-WRDFAFS2.js +0 -53
- package/dist/logs-5QHJWMEG.js +0 -12
- package/dist/msg-4SCLBO4K.js +0 -9
- package/dist/orchestrator-FGGXK3N3.js +0 -5
- package/dist/orchestrator-R7IWZUT6.js +0 -13
- package/dist/process-manager-33H27MQF.js +0 -2
- package/dist/registry-BO2PPRNG.js +0 -2
- package/dist/run-HSHRELOP.js +0 -3
- package/dist/shell-EOJBDWTH.js +0 -2
- package/dist/shell-IH2MMTVP.js.map +0 -1
- package/dist/shop-picker-LE3SKFOX.js +0 -5
- package/dist/status-DLBNWSWM.js +0 -2
- package/dist/task-J6ZN7ALI.js +0 -20
- package/dist/team-MSIBKOQC.js +0 -4
- package/dist/template-engine-ONIDVD4F.js +0 -2
- package/dist/tui-LW7WIDE3.js +0 -2
- package/dist/update-PC2ENCKU.js +0 -2
- package/dist/update-check-HGMBDYHL.js +0 -2
- package/dist/workspace-manager-KOOYTO7E.js +0 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/infrastructure/workspace/merge-strategy.ts","../src/infrastructure/workspace/workspace-manager.ts"],"names":[],"mappings":"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","file":"workspace-manager-T6AXG7XL.js","sourcesContent":["/**\n * Git merge strategy for worktree branches.\n *\n * Encapsulates `git merge --no-ff` execution and conflict handling.\n */\n\nimport type { IProcessManager } from '../process/process-manager.js';\n\nexport type MergeResult =\n | { success: true }\n | { success: false; conflictInfo: string };\n\nexport class MergeStrategy {\n constructor(\n private readonly projectRoot: string,\n private readonly processManager: IProcessManager,\n ) {}\n\n /**\n * Merge a branch into the current branch with --no-ff.\n * On conflict, aborts the merge and returns conflict info.\n */\n async mergeBack(branch: string): Promise<MergeResult> {\n return new Promise((resolve) => {\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['merge', '--no-ff', branch, '-m', `Merge ${branch}`],\n { cwd: this.projectRoot },\n );\n\n let output = '';\n const maxOutputLen = 2000;\n const appendOutput = (chunk: Buffer) => {\n if (output.length < maxOutputLen) output += chunk.toString();\n };\n proc.stdout?.on('data', appendOutput);\n proc.stderr?.on('data', appendOutput);\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve({ success: true });\n return;\n }\n\n const trimmedOutput = output.slice(0, 1000);\n const isConflict = trimmedOutput.includes('CONFLICT') || trimmedOutput.includes('Merge conflict');\n\n if (!isConflict) {\n // Non-conflict failure (branch not found, hook failure, etc.) — no merge to abort\n resolve({ success: false, conflictInfo: trimmedOutput });\n return;\n }\n\n // Abort the failed merge to restore clean state\n try {\n const { process: abortProc } = this.processManager.spawn(\n 'git',\n ['merge', '--abort'],\n { cwd: this.projectRoot },\n );\n abortProc.on('close', () => {\n resolve({ success: false, conflictInfo: trimmedOutput });\n });\n abortProc.on('error', () => {\n resolve({ success: false, conflictInfo: trimmedOutput });\n });\n } catch {\n resolve({ success: false, conflictInfo: trimmedOutput });\n }\n });\n\n proc.on('error', (err) => {\n resolve({ success: false, conflictInfo: err.message });\n });\n });\n }\n}\n","/**\n * Workspace manager implementation.\n *\n * Resolves workspace path based on mode priority chain:\n * task.workspace_mode → agent.config.workspace_mode → defaults.agent.workspace_mode → 'worktree'\n */\n\nimport path from 'node:path';\nimport fs from 'node:fs/promises';\nimport type { Agent } from '../../domain/agent.js';\nimport type { OrchestratorConfig } from '../../domain/config.js';\nimport type { Task, WorkspaceMode } from '../../domain/task.js';\nimport type { IProcessManager } from '../process/process-manager.js';\nimport { validateWorkspacePath, sanitizeId } from '../storage/paths.js';\nimport { ensureDir } from '../storage/fs-utils.js';\nimport type { IWorkspaceManager, PrepareResult } from './interface.js';\nimport { MergeStrategy, type MergeResult } from './merge-strategy.js';\nimport { WorkspaceError } from '../../domain/errors.js';\n\nexport class WorkspaceManager implements IWorkspaceManager {\n private readonly mergeStrategy: MergeStrategy;\n private gitRepoChecked = false;\n private isGitRepo = false;\n\n constructor(\n private readonly projectRoot: string,\n private readonly orchestryDir: string,\n private readonly processManager: IProcessManager,\n ) {\n this.mergeStrategy = new MergeStrategy(projectRoot, processManager);\n }\n\n async prepare(task: Task, agent: Agent, config: OrchestratorConfig): Promise<PrepareResult> {\n const mode = this.resolveMode(task, agent, config);\n\n if (mode !== 'shared') {\n await this.requireGitRepo(mode);\n }\n\n switch (mode) {\n case 'shared':\n return { path: this.projectRoot };\n\n case 'worktree':\n return this.prepareWorktree(task);\n\n case 'isolated':\n return { path: await this.prepareIsolated(task) };\n\n default:\n return { path: this.projectRoot };\n }\n }\n\n private async requireGitRepo(mode: WorkspaceMode): Promise<void> {\n if (!this.gitRepoChecked) {\n try {\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['rev-parse', '--is-inside-work-tree'],\n { cwd: this.projectRoot },\n );\n const code = await new Promise<number | null>((resolve) => {\n proc.on('close', resolve);\n proc.on('error', () => resolve(1));\n });\n this.isGitRepo = code === 0;\n } catch {\n this.isGitRepo = false;\n }\n // Only cache positive result — negative may change if user runs git init\n if (this.isGitRepo) this.gitRepoChecked = true;\n }\n\n if (!this.isGitRepo) {\n throw new WorkspaceError(\n `workspace_mode \"${mode}\" requires a git repository`,\n 'Run: git init && git add -A && git commit -m \"Initial commit\"\\n Or set workspace_mode: shared in .orchestry/config.yml',\n );\n }\n }\n\n async mergeBack(branch: string): Promise<MergeResult> {\n return this.mergeStrategy.mergeBack(branch);\n }\n\n async cleanup(taskId: string): Promise<void> {\n const workspacePath = path.join(this.orchestryDir, 'workspaces', sanitizeId(taskId));\n\n // Try git worktree remove first (cleans up .git/worktrees/ metadata)\n try {\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['worktree', 'remove', '--force', workspacePath],\n { cwd: this.projectRoot },\n );\n await new Promise<void>((resolve) => {\n proc.on('close', () => resolve());\n proc.on('error', () => resolve());\n });\n } catch {\n // Not a worktree or git not available — fall through to rm\n }\n\n // Remove directory regardless (handles isolated mode and worktree cleanup failures)\n try {\n await fs.rm(workspacePath, { recursive: true, force: true });\n } catch {\n // Workspace may not exist\n }\n }\n\n validate(workspacePath: string, projectRoot: string): void {\n validateWorkspacePath(workspacePath, projectRoot);\n }\n\n private resolveMode(task: Task, agent: Agent, config: OrchestratorConfig): WorkspaceMode {\n return (\n task.workspace_mode ??\n agent.config.workspace_mode ??\n config.defaults.agent.workspace_mode ??\n 'worktree'\n );\n }\n\n private async prepareWorktree(task: Task): Promise<PrepareResult> {\n const workspacePath = path.join(\n this.orchestryDir,\n 'workspaces',\n sanitizeId(task.id),\n );\n await ensureDir(path.dirname(workspacePath));\n\n const titleSlug = sanitizeTitle(task.title) || sanitizeId(task.id);\n const branchName = `orchestry/${sanitizeId(task.id)}/${titleSlug}`;\n\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['worktree', 'add', workspacePath, '-b', branchName],\n { cwd: this.projectRoot },\n );\n\n await new Promise<void>((resolve, reject) => {\n proc.on('close', (code) => {\n if (code === 0) resolve();\n else reject(new Error(`git worktree add failed with code ${code}`));\n });\n proc.on('error', reject);\n });\n\n // Remove .orchestry/ from worktree to prevent recursive state/workspaces\n const worktreeOrchestry = path.join(workspacePath, '.orchestry');\n await fs.rm(worktreeOrchestry, { recursive: true, force: true }).catch(() => {});\n\n return { path: workspacePath, branch: branchName };\n }\n\n private async prepareIsolated(task: Task): Promise<string> {\n const workspacePath = path.join(\n this.orchestryDir,\n 'workspaces',\n sanitizeId(task.id),\n );\n await ensureDir(path.dirname(workspacePath));\n\n // Try git clone first, fall back to rsync\n try {\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['clone', '--local', '--no-hardlinks', '.', workspacePath],\n { cwd: this.projectRoot },\n );\n\n await new Promise<void>((resolve, reject) => {\n proc.on('close', (code) => {\n if (code === 0) resolve();\n else reject(new Error('git clone failed'));\n });\n proc.on('error', reject);\n });\n } catch {\n // Fallback: rsync\n const excludeFile = path.join(this.orchestryDir, 'workspace-exclude');\n const args = ['-a', `--exclude-from=${excludeFile}`, './', `${workspacePath}/`];\n\n const { process: proc } = this.processManager.spawn('rsync', args, {\n cwd: this.projectRoot,\n });\n\n await new Promise<void>((resolve, reject) => {\n proc.on('close', (code) => {\n if (code === 0) resolve();\n else reject(new Error(`rsync failed with code ${code}`));\n });\n proc.on('error', reject);\n });\n }\n\n // Remove .orchestry/ to prevent recursive workspaces (covers both clone and rsync)\n const clonedOrchestry = path.join(workspacePath, '.orchestry');\n await fs.rm(clonedOrchestry, { recursive: true, force: true }).catch(() => {});\n\n return workspacePath;\n }\n}\n\nfunction sanitizeTitle(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 40);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/infrastructure/workspace/merge-strategy.ts","../src/infrastructure/workspace/workspace-manager.ts"],"names":[],"mappings":"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","file":"workspace-manager-EVD67GCG.js","sourcesContent":["/**\n * Git merge strategy for worktree branches.\n *\n * Encapsulates `git merge --no-ff` execution and conflict handling.\n */\n\nimport type { IProcessManager } from '../process/process-manager.js';\n\nexport type MergeResult =\n | { success: true }\n | { success: false; conflictInfo: string };\n\nexport class MergeStrategy {\n constructor(\n private readonly projectRoot: string,\n private readonly processManager: IProcessManager,\n ) {}\n\n /**\n * Merge a branch into the current branch with --no-ff.\n * On conflict, aborts the merge and returns conflict info.\n */\n async mergeBack(branch: string): Promise<MergeResult> {\n return new Promise((resolve) => {\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['merge', '--no-ff', branch, '-m', `Merge ${branch}`],\n { cwd: this.projectRoot },\n );\n\n let output = '';\n const maxOutputLen = 2000;\n const appendOutput = (chunk: Buffer) => {\n if (output.length < maxOutputLen) output += chunk.toString();\n };\n proc.stdout?.on('data', appendOutput);\n proc.stderr?.on('data', appendOutput);\n\n proc.on('close', (code) => {\n if (code === 0) {\n resolve({ success: true });\n return;\n }\n\n const trimmedOutput = output.slice(0, 1000);\n const isConflict = trimmedOutput.includes('CONFLICT') || trimmedOutput.includes('Merge conflict');\n\n if (!isConflict) {\n // Non-conflict failure (branch not found, hook failure, etc.) — no merge to abort\n resolve({ success: false, conflictInfo: trimmedOutput });\n return;\n }\n\n // Abort the failed merge to restore clean state\n try {\n const { process: abortProc } = this.processManager.spawn(\n 'git',\n ['merge', '--abort'],\n { cwd: this.projectRoot },\n );\n abortProc.on('close', () => {\n resolve({ success: false, conflictInfo: trimmedOutput });\n });\n abortProc.on('error', () => {\n resolve({ success: false, conflictInfo: trimmedOutput });\n });\n } catch {\n resolve({ success: false, conflictInfo: trimmedOutput });\n }\n });\n\n proc.on('error', (err) => {\n resolve({ success: false, conflictInfo: err.message });\n });\n });\n }\n}\n","/**\n * Workspace manager implementation.\n *\n * Resolves workspace path based on mode priority chain:\n * task.workspace_mode → agent.config.workspace_mode → defaults.agent.workspace_mode → 'worktree'\n */\n\nimport path from 'node:path';\nimport fs from 'node:fs/promises';\nimport type { Agent } from '../../domain/agent.js';\nimport type { OrchestratorConfig } from '../../domain/config.js';\nimport type { Task, WorkspaceMode } from '../../domain/task.js';\nimport type { IProcessManager } from '../process/process-manager.js';\nimport { validateWorkspacePath, sanitizeId } from '../storage/paths.js';\nimport { ensureDir } from '../storage/fs-utils.js';\nimport type { IWorkspaceManager, PrepareResult } from './interface.js';\nimport { MergeStrategy, type MergeResult } from './merge-strategy.js';\nimport { WorkspaceError } from '../../domain/errors.js';\n\nexport class WorkspaceManager implements IWorkspaceManager {\n private readonly mergeStrategy: MergeStrategy;\n private gitRepoChecked = false;\n private isGitRepo = false;\n\n constructor(\n private readonly projectRoot: string,\n private readonly orchestryDir: string,\n private readonly processManager: IProcessManager,\n ) {\n this.mergeStrategy = new MergeStrategy(projectRoot, processManager);\n }\n\n async prepare(task: Task, agent: Agent, config: OrchestratorConfig): Promise<PrepareResult> {\n const mode = this.resolveMode(task, agent, config);\n\n if (mode !== 'shared') {\n await this.requireGitRepo(mode);\n }\n\n switch (mode) {\n case 'shared':\n return { path: this.projectRoot };\n\n case 'worktree':\n return this.prepareWorktree(task);\n\n case 'isolated':\n return { path: await this.prepareIsolated(task) };\n\n default:\n return { path: this.projectRoot };\n }\n }\n\n private async requireGitRepo(mode: WorkspaceMode): Promise<void> {\n if (!this.gitRepoChecked) {\n try {\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['rev-parse', '--is-inside-work-tree'],\n { cwd: this.projectRoot },\n );\n const code = await new Promise<number | null>((resolve) => {\n proc.on('close', resolve);\n proc.on('error', () => resolve(1));\n });\n this.isGitRepo = code === 0;\n } catch {\n this.isGitRepo = false;\n }\n // Only cache positive result — negative may change if user runs git init\n if (this.isGitRepo) this.gitRepoChecked = true;\n }\n\n if (!this.isGitRepo) {\n throw new WorkspaceError(\n `workspace_mode \"${mode}\" requires a git repository`,\n 'Run: git init && git add -A && git commit -m \"Initial commit\"\\n Or set workspace_mode: shared in .orchestry/config.yml',\n );\n }\n }\n\n async mergeBack(branch: string): Promise<MergeResult> {\n return this.mergeStrategy.mergeBack(branch);\n }\n\n async cleanup(taskId: string): Promise<void> {\n const workspacePath = path.join(this.orchestryDir, 'workspaces', sanitizeId(taskId));\n\n // Try git worktree remove first (cleans up .git/worktrees/ metadata)\n try {\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['worktree', 'remove', '--force', workspacePath],\n { cwd: this.projectRoot },\n );\n await new Promise<void>((resolve) => {\n proc.on('close', () => resolve());\n proc.on('error', () => resolve());\n });\n } catch {\n // Not a worktree or git not available — fall through to rm\n }\n\n // Remove directory regardless (handles isolated mode and worktree cleanup failures)\n try {\n await fs.rm(workspacePath, { recursive: true, force: true });\n } catch {\n // Workspace may not exist\n }\n }\n\n validate(workspacePath: string, projectRoot: string): void {\n validateWorkspacePath(workspacePath, projectRoot);\n }\n\n private resolveMode(task: Task, agent: Agent, config: OrchestratorConfig): WorkspaceMode {\n return (\n task.workspace_mode ??\n agent.config.workspace_mode ??\n config.defaults.agent.workspace_mode ??\n 'worktree'\n );\n }\n\n private async prepareWorktree(task: Task): Promise<PrepareResult> {\n const workspacePath = path.join(\n this.orchestryDir,\n 'workspaces',\n sanitizeId(task.id),\n );\n await ensureDir(path.dirname(workspacePath));\n\n const titleSlug = sanitizeTitle(task.title) || sanitizeId(task.id);\n const branchName = `orchestry/${sanitizeId(task.id)}/${titleSlug}`;\n\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['worktree', 'add', workspacePath, '-b', branchName],\n { cwd: this.projectRoot },\n );\n\n await new Promise<void>((resolve, reject) => {\n proc.on('close', (code) => {\n if (code === 0) resolve();\n else reject(new Error(`git worktree add failed with code ${code}`));\n });\n proc.on('error', reject);\n });\n\n // Remove .orchestry/ from worktree to prevent recursive state/workspaces\n const worktreeOrchestry = path.join(workspacePath, '.orchestry');\n await fs.rm(worktreeOrchestry, { recursive: true, force: true }).catch(() => {});\n\n return { path: workspacePath, branch: branchName };\n }\n\n private async prepareIsolated(task: Task): Promise<string> {\n const workspacePath = path.join(\n this.orchestryDir,\n 'workspaces',\n sanitizeId(task.id),\n );\n await ensureDir(path.dirname(workspacePath));\n\n // Try git clone first, fall back to rsync\n try {\n const { process: proc } = this.processManager.spawn(\n 'git',\n ['clone', '--local', '--no-hardlinks', '.', workspacePath],\n { cwd: this.projectRoot },\n );\n\n await new Promise<void>((resolve, reject) => {\n proc.on('close', (code) => {\n if (code === 0) resolve();\n else reject(new Error('git clone failed'));\n });\n proc.on('error', reject);\n });\n } catch {\n // Fallback: rsync\n const excludeFile = path.join(this.orchestryDir, 'workspace-exclude');\n const args = ['-a', `--exclude-from=${excludeFile}`, './', `${workspacePath}/`];\n\n const { process: proc } = this.processManager.spawn('rsync', args, {\n cwd: this.projectRoot,\n });\n\n await new Promise<void>((resolve, reject) => {\n proc.on('close', (code) => {\n if (code === 0) resolve();\n else reject(new Error(`rsync failed with code ${code}`));\n });\n proc.on('error', reject);\n });\n }\n\n // Remove .orchestry/ to prevent recursive workspaces (covers both clone and rsync)\n const clonedOrchestry = path.join(workspacePath, '.orchestry');\n await fs.rm(clonedOrchestry, { recursive: true, force: true }).catch(() => {});\n\n return workspacePath;\n }\n}\n\nfunction sanitizeTitle(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n .slice(0, 40);\n}\n"]}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { sanitizeId, validateWorkspacePath, ensureDir } from './chunk-LV6GDBBI.js';
|
|
3
|
+
import { WorkspaceError } from './chunk-2C2TFQ7K.js';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs/promises';
|
|
6
|
+
|
|
7
|
+
// src/infrastructure/workspace/merge-strategy.ts
|
|
8
|
+
var MergeStrategy = class {
|
|
9
|
+
constructor(projectRoot, processManager) {
|
|
10
|
+
this.projectRoot = projectRoot;
|
|
11
|
+
this.processManager = processManager;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Merge a branch into the current branch with --no-ff.
|
|
15
|
+
* On conflict, aborts the merge and returns conflict info.
|
|
16
|
+
*/
|
|
17
|
+
async mergeBack(branch) {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
const { process: proc } = this.processManager.spawn(
|
|
20
|
+
"git",
|
|
21
|
+
["merge", "--no-ff", branch, "-m", `Merge ${branch}`],
|
|
22
|
+
{ cwd: this.projectRoot }
|
|
23
|
+
);
|
|
24
|
+
let output = "";
|
|
25
|
+
const maxOutputLen = 2e3;
|
|
26
|
+
const appendOutput = (chunk) => {
|
|
27
|
+
if (output.length < maxOutputLen) output += chunk.toString();
|
|
28
|
+
};
|
|
29
|
+
proc.stdout?.on("data", appendOutput);
|
|
30
|
+
proc.stderr?.on("data", appendOutput);
|
|
31
|
+
proc.on("close", (code) => {
|
|
32
|
+
if (code === 0) {
|
|
33
|
+
resolve({ success: true });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const trimmedOutput = output.slice(0, 1e3);
|
|
37
|
+
const isConflict = trimmedOutput.includes("CONFLICT") || trimmedOutput.includes("Merge conflict");
|
|
38
|
+
if (!isConflict) {
|
|
39
|
+
resolve({ success: false, conflictInfo: trimmedOutput });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const { process: abortProc } = this.processManager.spawn(
|
|
44
|
+
"git",
|
|
45
|
+
["merge", "--abort"],
|
|
46
|
+
{ cwd: this.projectRoot }
|
|
47
|
+
);
|
|
48
|
+
abortProc.on("close", () => {
|
|
49
|
+
resolve({ success: false, conflictInfo: trimmedOutput });
|
|
50
|
+
});
|
|
51
|
+
abortProc.on("error", () => {
|
|
52
|
+
resolve({ success: false, conflictInfo: trimmedOutput });
|
|
53
|
+
});
|
|
54
|
+
} catch {
|
|
55
|
+
resolve({ success: false, conflictInfo: trimmedOutput });
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
proc.on("error", (err) => {
|
|
59
|
+
resolve({ success: false, conflictInfo: err.message });
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/infrastructure/workspace/workspace-manager.ts
|
|
66
|
+
var WorkspaceManager = class {
|
|
67
|
+
constructor(projectRoot, orchestryDir, processManager) {
|
|
68
|
+
this.projectRoot = projectRoot;
|
|
69
|
+
this.orchestryDir = orchestryDir;
|
|
70
|
+
this.processManager = processManager;
|
|
71
|
+
this.mergeStrategy = new MergeStrategy(projectRoot, processManager);
|
|
72
|
+
}
|
|
73
|
+
mergeStrategy;
|
|
74
|
+
gitRepoChecked = false;
|
|
75
|
+
isGitRepo = false;
|
|
76
|
+
async prepare(task, agent, config) {
|
|
77
|
+
const mode = this.resolveMode(task, agent, config);
|
|
78
|
+
if (mode !== "shared") {
|
|
79
|
+
await this.requireGitRepo(mode);
|
|
80
|
+
}
|
|
81
|
+
switch (mode) {
|
|
82
|
+
case "shared":
|
|
83
|
+
return { path: this.projectRoot };
|
|
84
|
+
case "worktree":
|
|
85
|
+
return this.prepareWorktree(task);
|
|
86
|
+
case "isolated":
|
|
87
|
+
return { path: await this.prepareIsolated(task) };
|
|
88
|
+
default:
|
|
89
|
+
return { path: this.projectRoot };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async requireGitRepo(mode) {
|
|
93
|
+
if (!this.gitRepoChecked) {
|
|
94
|
+
try {
|
|
95
|
+
const { process: proc } = this.processManager.spawn(
|
|
96
|
+
"git",
|
|
97
|
+
["rev-parse", "--is-inside-work-tree"],
|
|
98
|
+
{ cwd: this.projectRoot }
|
|
99
|
+
);
|
|
100
|
+
const code = await new Promise((resolve) => {
|
|
101
|
+
proc.on("close", resolve);
|
|
102
|
+
proc.on("error", () => resolve(1));
|
|
103
|
+
});
|
|
104
|
+
this.isGitRepo = code === 0;
|
|
105
|
+
} catch {
|
|
106
|
+
this.isGitRepo = false;
|
|
107
|
+
}
|
|
108
|
+
if (this.isGitRepo) this.gitRepoChecked = true;
|
|
109
|
+
}
|
|
110
|
+
if (!this.isGitRepo) {
|
|
111
|
+
throw new WorkspaceError(
|
|
112
|
+
`workspace_mode "${mode}" requires a git repository`,
|
|
113
|
+
'Run: git init && git add -A && git commit -m "Initial commit"\n Or set workspace_mode: shared in .orchestry/config.yml'
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async mergeBack(branch) {
|
|
118
|
+
return this.mergeStrategy.mergeBack(branch);
|
|
119
|
+
}
|
|
120
|
+
async cleanup(taskId) {
|
|
121
|
+
const workspacePath = path.join(this.orchestryDir, "workspaces", sanitizeId(taskId));
|
|
122
|
+
try {
|
|
123
|
+
const { process: proc } = this.processManager.spawn(
|
|
124
|
+
"git",
|
|
125
|
+
["worktree", "remove", "--force", workspacePath],
|
|
126
|
+
{ cwd: this.projectRoot }
|
|
127
|
+
);
|
|
128
|
+
await new Promise((resolve) => {
|
|
129
|
+
proc.on("close", () => resolve());
|
|
130
|
+
proc.on("error", () => resolve());
|
|
131
|
+
});
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
await fs.rm(workspacePath, { recursive: true, force: true });
|
|
136
|
+
} catch {
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
validate(workspacePath, projectRoot) {
|
|
140
|
+
validateWorkspacePath(workspacePath, projectRoot);
|
|
141
|
+
}
|
|
142
|
+
resolveMode(task, agent, config) {
|
|
143
|
+
return task.workspace_mode ?? agent.config.workspace_mode ?? config.defaults.agent.workspace_mode ?? "worktree";
|
|
144
|
+
}
|
|
145
|
+
async prepareWorktree(task) {
|
|
146
|
+
const workspacePath = path.join(
|
|
147
|
+
this.orchestryDir,
|
|
148
|
+
"workspaces",
|
|
149
|
+
sanitizeId(task.id)
|
|
150
|
+
);
|
|
151
|
+
await ensureDir(path.dirname(workspacePath));
|
|
152
|
+
const titleSlug = sanitizeTitle(task.title) || sanitizeId(task.id);
|
|
153
|
+
const branchName = `orchestry/${sanitizeId(task.id)}/${titleSlug}`;
|
|
154
|
+
const { process: proc } = this.processManager.spawn(
|
|
155
|
+
"git",
|
|
156
|
+
["worktree", "add", workspacePath, "-b", branchName],
|
|
157
|
+
{ cwd: this.projectRoot }
|
|
158
|
+
);
|
|
159
|
+
await new Promise((resolve, reject) => {
|
|
160
|
+
proc.on("close", (code) => {
|
|
161
|
+
if (code === 0) resolve();
|
|
162
|
+
else reject(new Error(`git worktree add failed with code ${code}`));
|
|
163
|
+
});
|
|
164
|
+
proc.on("error", reject);
|
|
165
|
+
});
|
|
166
|
+
const worktreeOrchestry = path.join(workspacePath, ".orchestry");
|
|
167
|
+
await fs.rm(worktreeOrchestry, { recursive: true, force: true }).catch(() => {
|
|
168
|
+
});
|
|
169
|
+
return { path: workspacePath, branch: branchName };
|
|
170
|
+
}
|
|
171
|
+
async prepareIsolated(task) {
|
|
172
|
+
const workspacePath = path.join(
|
|
173
|
+
this.orchestryDir,
|
|
174
|
+
"workspaces",
|
|
175
|
+
sanitizeId(task.id)
|
|
176
|
+
);
|
|
177
|
+
await ensureDir(path.dirname(workspacePath));
|
|
178
|
+
try {
|
|
179
|
+
const { process: proc } = this.processManager.spawn(
|
|
180
|
+
"git",
|
|
181
|
+
["clone", "--local", "--no-hardlinks", ".", workspacePath],
|
|
182
|
+
{ cwd: this.projectRoot }
|
|
183
|
+
);
|
|
184
|
+
await new Promise((resolve, reject) => {
|
|
185
|
+
proc.on("close", (code) => {
|
|
186
|
+
if (code === 0) resolve();
|
|
187
|
+
else reject(new Error("git clone failed"));
|
|
188
|
+
});
|
|
189
|
+
proc.on("error", reject);
|
|
190
|
+
});
|
|
191
|
+
} catch {
|
|
192
|
+
const excludeFile = path.join(this.orchestryDir, "workspace-exclude");
|
|
193
|
+
const args = ["-a", `--exclude-from=${excludeFile}`, "./", `${workspacePath}/`];
|
|
194
|
+
const { process: proc } = this.processManager.spawn("rsync", args, {
|
|
195
|
+
cwd: this.projectRoot
|
|
196
|
+
});
|
|
197
|
+
await new Promise((resolve, reject) => {
|
|
198
|
+
proc.on("close", (code) => {
|
|
199
|
+
if (code === 0) resolve();
|
|
200
|
+
else reject(new Error(`rsync failed with code ${code}`));
|
|
201
|
+
});
|
|
202
|
+
proc.on("error", reject);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
const clonedOrchestry = path.join(workspacePath, ".orchestry");
|
|
206
|
+
await fs.rm(clonedOrchestry, { recursive: true, force: true }).catch(() => {
|
|
207
|
+
});
|
|
208
|
+
return workspacePath;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
function sanitizeTitle(title) {
|
|
212
|
+
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export { WorkspaceManager };
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://www.npmjs.com/package/@oxgeneral/orch"><img src="https://img.shields.io/npm/v/@oxgeneral/orch?color=cb0000" alt="npm" /></a>
|
|
11
11
|
<a href="#get-started-in-30-seconds"><img src="https://img.shields.io/badge/setup-one%20command-brightgreen" alt="One command setup" /></a>
|
|
12
12
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License" /></a>
|
|
13
|
-
<a href="#development"><img src="https://img.shields.io/badge/tests-
|
|
13
|
+
<a href="#development"><img src="https://img.shields.io/badge/tests-1386%20passing-brightgreen" alt="Tests" /></a>
|
|
14
14
|
<a href="#architecture"><img src="https://img.shields.io/badge/TypeScript-strict-blue" alt="TypeScript strict" /></a>
|
|
15
15
|
</p>
|
|
16
16
|
</p>
|
|
@@ -94,6 +94,13 @@ Full-screen Ink/React dashboard with:
|
|
|
94
94
|
- Activity feed with token counts
|
|
95
95
|
- Keyboard-driven: create tasks, assign agents, approve reviews — without leaving the terminal
|
|
96
96
|
- Command bar with `/task add`, `/agent add`, tab completion
|
|
97
|
+
- **Help overlay** (`?` or `F1`) — discover all keyboard shortcuts at any time
|
|
98
|
+
- **Toast notifications** — done/failed/review completions with optional bell sound
|
|
99
|
+
- **Error hint panel** — when an agent fails, see the exact cause and fix hint inline
|
|
100
|
+
- **Detail panel resize** (`+`/`-`/`M`) — expand agent/task detail to full screen
|
|
101
|
+
- **Goal-task linking** — badge tasks with their goal, group by goal with `G`, see per-goal progress bars
|
|
102
|
+
- **Inline validation** — wizard forms validate as you type (duplicate names, invalid priority)
|
|
103
|
+
- **Tab badge flash** — header tabs blink on task completion events outside the active tab
|
|
97
104
|
|
|
98
105
|
### Goals — strategic direction for your agents
|
|
99
106
|
Define high-level goals and let ORCH autonomously generate tasks to achieve them. Goals have statuses (`active`, `paused`, `achieved`, `abandoned`), can be assigned to specific agents, and appear in a dedicated TUI tab for tracking.
|
|
@@ -231,7 +238,7 @@ src/
|
|
|
231
238
|
```bash
|
|
232
239
|
npm run dev # Run via tsx
|
|
233
240
|
npm run build # Build ESM + DTS
|
|
234
|
-
npm test #
|
|
241
|
+
npm test # 1386 tests via Vitest
|
|
235
242
|
npm run typecheck # Strict TypeScript
|
|
236
243
|
```
|
|
237
244
|
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,11 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Post-install
|
|
4
|
+
* Post-install: patch Ink caches + show banner.
|
|
5
5
|
* Pure Node.js, no dependencies.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
//
|
|
8
|
+
// Patch Ink's unbounded caches before anything else
|
|
9
|
+
try {
|
|
10
|
+
const { readFileSync, writeFileSync, existsSync } = require('node:fs');
|
|
11
|
+
const { join } = require('node:path');
|
|
12
|
+
const inkBuild = join(__dirname, '..', 'node_modules', 'ink', 'build');
|
|
13
|
+
const MAX = 2000;
|
|
14
|
+
|
|
15
|
+
const wrapPath = join(inkBuild, 'wrap-text.js');
|
|
16
|
+
if (existsSync(wrapPath)) {
|
|
17
|
+
let s = readFileSync(wrapPath, 'utf8');
|
|
18
|
+
if (!s.includes('_lruKeys')) {
|
|
19
|
+
s = s.replace('const cache = {};', `const cache = {};\nconst _lruKeys = [];\nconst _MAX = ${MAX};`);
|
|
20
|
+
s = s.replace('cache[cacheKey] = wrappedText;', `cache[cacheKey] = wrappedText;\n _lruKeys.push(cacheKey);\n if (_lruKeys.length > _MAX) { delete cache[_lruKeys.shift()]; }`);
|
|
21
|
+
writeFileSync(wrapPath, s);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const measurePath = join(inkBuild, 'measure-text.js');
|
|
26
|
+
if (existsSync(measurePath)) {
|
|
27
|
+
let s = readFileSync(measurePath, 'utf8');
|
|
28
|
+
if (!s.includes('_MAX_MT')) {
|
|
29
|
+
s = s.replace('const cache = new Map();', `const cache = new Map();\nconst _MAX_MT = ${MAX};`);
|
|
30
|
+
s = s.replace('cache.set(text, dimensions);', `cache.set(text, dimensions);\n if (cache.size > _MAX_MT) { const first = cache.keys().next().value; cache.delete(first); }`);
|
|
31
|
+
writeFileSync(measurePath, s);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Patch output.js: add LRU eviction to OutputCaches maps
|
|
35
|
+
const outputPath = join(inkBuild, 'output.js');
|
|
36
|
+
if (existsSync(outputPath)) {
|
|
37
|
+
let s = readFileSync(outputPath, 'utf8');
|
|
38
|
+
if (!s.includes('_OC_MAX')) {
|
|
39
|
+
// Add LRU bound to all three Maps in OutputCaches
|
|
40
|
+
const lru = (prop) => `\n if (this.${prop}.size > _OC_MAX) { const k = this.${prop}.keys().next().value; this.${prop}.delete(k); }`;
|
|
41
|
+
s = s.replace('class OutputCaches {', `const _OC_MAX = ${MAX};\nclass OutputCaches {`);
|
|
42
|
+
s = s.replace('this.styledChars.set(line, cached);', `this.styledChars.set(line, cached);${lru('styledChars')}`);
|
|
43
|
+
s = s.replace('this.widths.set(text, cached);', `this.widths.set(text, cached);${lru('widths')}`);
|
|
44
|
+
s = s.replace('this.blockWidths.set(text, cached);', `this.blockWidths.set(text, cached);${lru('blockWidths')}`);
|
|
45
|
+
writeFileSync(outputPath, s);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} catch { /* non-fatal: caches will just be unbounded */ }
|
|
49
|
+
|
|
50
|
+
// Skip banner in CI or non-interactive environments
|
|
9
51
|
if (process.env.CI || !process.stderr.isTTY) process.exit(0);
|
|
10
52
|
|
|
11
53
|
// Color values synced with src/cli/output.ts colors map
|