@agimon-ai/doompi-git 0.0.1-alpha.19 → 0.0.1-alpha.20
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/extensions/pi.cjs +2 -2
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.mts.map +1 -1
- package/dist/extensions/pi.mjs +2 -2
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/extensions/server.cjs +2 -2
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +2 -2
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +2 -2
- package/dist/extensions/web.mjs.map +1 -1
- package/package.json +6 -6
package/dist/extensions/pi.cjs
CHANGED
|
@@ -80,10 +80,10 @@ var runWorktree_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineCli
|
|
|
80
80
|
//#endregion
|
|
81
81
|
//#region generated/pi.ts
|
|
82
82
|
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
83
|
-
const via = (identity, value) =>
|
|
83
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
84
84
|
...identity,
|
|
85
85
|
...value
|
|
86
|
-
}
|
|
86
|
+
};
|
|
87
87
|
const extension = (0, _agimon_ai_doompi_core_piExtension.definePiExtension)("@agimon-ai/doompi-git", async (context) => {
|
|
88
88
|
const scopeSession = await root_cli_default(context);
|
|
89
89
|
const contextSession = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.cjs","names":["defineRoot","createGitDependencies","defineRoot","contribution","defineCliCommand","contribution","defineResource","defineCliTool","definePiTool","RUN_WORKTREE_TOOL_NAME","RUN_WORKTREE_DESCRIPTION","RunWorktreeToolSchema","validateParams","executeRunWorktreeTool","defineCliTool","contribution","definePiExtension","rootSession","composeRootHooks","commandGit","resourceDoompiUseGit","piToolContributions","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/constants/git.ts","../../src/extensions/workspaces/sessions/(backend)/command/_lib/git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompi-use-git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/_lib/runWorktree.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli.ts","../../generated/pi.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createGitDependencies } from '../../../../../services/gitDependencies';\nimport type { GitExtensionDependencies } from '../../../../../types/extension';\n\nconst root = defineRoot((context: PiPluginContext<Partial<GitExtensionDependencies>>) => ({\n value: createGitDependencies(context.options),\n}));\n\nexport type GitPiScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.cli';\n\nexport default defineRoot(contribution);\n","export const COMMAND_NAME = 'doom-git';\nexport const COMMAND_DESCRIPTION = 'Show git worktrees owned by this session';\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n// @scaffold-generated\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../../../../../constants/git';\nimport type { GitExtensionDependencies, GitExtensionService } from '../../../../../../types/extension';\nimport type { GitPiScope } from '../../_lib/root.cli';\n\nexport function createGitCommand(\n service: GitExtensionService,\n): readonly [string, Parameters<ExtensionAPI['registerCommand']>[1]] {\n return [\n COMMAND_NAME,\n {\n description: COMMAND_DESCRIPTION,\n handler: async (_args, ctx) => {\n const result = await service.execute();\n if (ctx.hasUI) ctx.ui.notify(result.message, result.level);\n },\n },\n ];\n}\n\nexport default (context: WithRoot<PiPluginContext<Partial<GitExtensionDependencies>>, GitPiScope>) =>\n createGitCommand(context.root.service);\n","import { defineCliCommand } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git.cli';\n\nexport default defineCliCommand(contribution);\n","export function createDoompiUseGitResource(moduleUrl: string) {\n return {\n source: '@agimon-ai/doompi-git',\n moduleUrl,\n skills: [\n {\n name: 'doompi-use-git',\n description:\n 'Use @agimon-ai/doompi-git: Git worktree sessions for DoomPi: spawn an isolated worktree with its own session and manage it from the parent',\n },\n ],\n };\n}\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createDoompiUseGitResource } from './_lib/doompi-use-git.cli';\n\nexport default defineResource(createDoompiUseGitResource(import.meta.url));\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport { definePiTool, type PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../../schemas/runWorktreeTool';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n type RunWorktreeToolDetails,\n} from '../../../../../../services/runWorktree';\nimport type { WorktreeOperations } from '../../../../../../services/worktreeOperations';\nimport type { GitExtensionDependencies } from '../../../../../../types/extension';\nimport type { GitPiScope } from '../../_lib/root.cli';\n\nexport default defineCliTool((context: WithRoot<PiPluginContext<Partial<GitExtensionDependencies>>, GitPiScope>) =>\n definePiTool(createRunWorktreeTool(context.root.operations)),\n);\n\nexport { RUN_WORKTREE_TOOL_NAME, validateParams };\nexport type { RunWorktreeToolDetails };\n\n/** Creates the typed Pi worktree tool declaration. */\nexport function createRunWorktreeTool(\n operations: WorktreeOperations,\n): ToolDefinition<typeof RunWorktreeToolSchema, RunWorktreeToolDetails> {\n const tool: ToolDefinition<typeof RunWorktreeToolSchema, RunWorktreeToolDetails> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n prepareArguments: validateParams,\n // The signal and the progress callback are the host's two answers to a\n // call that takes minutes. Dropping them is what let an interrupted spawn\n // run on with nobody waiting for it, and left the caller staring at\n // nothing while it did.\n execute: async (_id, rawParams, signal, onUpdate, ctx) => {\n const params = validateParams(rawParams) as RunWorktreeToolParams;\n return (await executeRunWorktreeTool(\n params,\n operations,\n {\n cwd: ctx.cwd,\n sessionId: ctx.sessionManager.getSessionId(),\n },\n {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) =>\n onUpdate?.({ content: [{ type: 'text', text: label }], details: { action: params.action } }),\n },\n )) as AgentToolResult<RunWorktreeToolDetails>;\n },\n };\n return tool;\n}\n","import { defineCliTool } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/runWorktree.cli';\n\nexport default defineCliTool(contribution);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandGit from '../src/extensions/workspaces/sessions/(backend)/command/git.cli';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandGit> | OptionsOf<typeof resourceDoompiUseGit> | OptionsOf<typeof toolRunWorktree>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T => ({ ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-git', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandGit, contextSession)]; },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseGit, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-git', [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":";;;;;;;;;AAMA,MAAM,QAAA,GAAOA,qCAAAA,WAAAA,EAAY,aAAiE,EACxF,OAAOC,wBAAAA,sBAAsB,QAAQ,OAAO,EAC9C,EAAE;;;ACJF,IAAA,oBAAA,GAAeC,qCAAAA,WAAAA,CAAWC,IAAY;;;ACJtC,MAAa,eAAe;AAC5B,MAAa,sBAAsB;;;ACQnC,SAAgB,iBACd,SACmE;CACnE,OAAO,CACL,cACA;EACE,aAAa;EACb,SAAS,OAAO,OAAO,QAAQ;GAC7B,MAAM,SAAS,MAAM,QAAQ,QAAQ;GACrC,IAAI,IAAI,OAAO,IAAI,GAAG,OAAO,OAAO,SAAS,OAAO,KAAK;EAC3D;CACF,CACF;AACF;AAEA,IAAA,qBAAgB,YACd,iBAAiB,QAAQ,KAAK,OAAO;;;ACrBvC,IAAA,mBAAA,GAAeC,qCAAAA,iBAAAA,CAAiBC,iBAAY;;;ACJ5C,SAAgB,2BAA2B,WAAmB;CAC5D,OAAO;EACL,QAAQ;EACR;EACA,QAAQ,CACN;GACE,MAAM;GACN,aACE;EACJ,CACF;CACF;AACF;;;ACRA,IAAA,8BAAA,GAAeC,qCAAAA,eAAAA,CAAe,2BAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,IAA0C,CAAC;;;ACazE,IAAA,6BAAA,GAAeC,qCAAAA,cAAAA,EAAe,aAAA,GAC5BC,mCAAAA,aAAAA,CAAa,sBAAsB,QAAQ,KAAK,UAAU,CAAC,CAC7D;;AAMA,SAAgB,sBACd,YACsE;CA4BtE,OAAO;EA1BL,MAAMC,oBAAAA;EACN,OAAO;EACP,aAAaC,oBAAAA;EACb,YAAYC,oBAAAA;EACZ,kBAAkBC,oBAAAA;EAKlB,SAAS,OAAO,KAAK,WAAW,QAAQ,UAAU,QAAQ;GACxD,MAAM,SAASA,oBAAAA,eAAe,SAAS;GACvC,OAAQ,MAAMC,oBAAAA,uBACZ,QACA,YACA;IACE,KAAK,IAAI;IACT,WAAW,IAAI,eAAe,aAAa;GAC7C,GACA;IACE,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;IACzC,aAAa,UACX,WAAW;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;KAAM,CAAC;KAAG,SAAS,EAAE,QAAQ,OAAO,OAAO;IAAE,CAAC;GAC/F,CACF;EACF;CAEQ;AACZ;;;ACpDA,IAAA,2BAAA,GAAeC,qCAAAA,cAAAA,CAAcC,yBAAY;;;ACYzC,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AACpE,MAAM,OAAU,UAAmC,WAAuB;CAAE,GAAG;CAAU,GAAI;AAAiB;AAE9G,MAAa,aAAA,GAAYC,mCAAAA,kBAAAA,CAAoC,yBAAyB,OAAO,YAAY;CACvG,MAAM,eAAe,MAAMC,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,IAAA,GAAGC,qCAAAA,iBAAAA,CAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,iBAAY,cAAc,CAAC;EAAG;EAC7F,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAGC,4BAAsB,cAAc,CAAC;EAAG;EACzG,IAAA,GAAGC,mCAAAA,oBAAAA,CAAoB,yBAAyB,CAAC,IAAI,EAAE,MAAM,eAAe,GAAG,GAAGC,yBAAiB,cAAc,CAAC,CAAC,CAAC;EACpH,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"pi.cjs","names":["defineRoot","createGitDependencies","defineRoot","contribution","defineCliCommand","contribution","defineResource","defineCliTool","definePiTool","RUN_WORKTREE_TOOL_NAME","RUN_WORKTREE_DESCRIPTION","RunWorktreeToolSchema","validateParams","executeRunWorktreeTool","defineCliTool","contribution","definePiExtension","rootSession","composeRootHooks","commandGit","resourceDoompiUseGit","piToolContributions","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/constants/git.ts","../../src/extensions/workspaces/sessions/(backend)/command/_lib/git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompi-use-git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/_lib/runWorktree.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli.ts","../../generated/pi.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createGitDependencies } from '../../../../../services/gitDependencies';\nimport type { GitExtensionDependencies } from '../../../../../types/extension';\n\nconst root = defineRoot((context: PiPluginContext<Partial<GitExtensionDependencies>>) => ({\n value: createGitDependencies(context.options),\n}));\n\nexport type GitPiScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.cli';\n\nexport default defineRoot(contribution);\n","export const COMMAND_NAME = 'doom-git';\nexport const COMMAND_DESCRIPTION = 'Show git worktrees owned by this session';\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n// @scaffold-generated\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../../../../../constants/git';\nimport type { GitExtensionDependencies, GitExtensionService } from '../../../../../../types/extension';\nimport type { GitPiScope } from '../../_lib/root.cli';\n\nexport function createGitCommand(\n service: GitExtensionService,\n): readonly [string, Parameters<ExtensionAPI['registerCommand']>[1]] {\n return [\n COMMAND_NAME,\n {\n description: COMMAND_DESCRIPTION,\n handler: async (_args, ctx) => {\n const result = await service.execute();\n if (ctx.hasUI) ctx.ui.notify(result.message, result.level);\n },\n },\n ];\n}\n\nexport default (context: WithRoot<PiPluginContext<Partial<GitExtensionDependencies>>, GitPiScope>) =>\n createGitCommand(context.root.service);\n","import { defineCliCommand } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git.cli';\n\nexport default defineCliCommand(contribution);\n","export function createDoompiUseGitResource(moduleUrl: string) {\n return {\n source: '@agimon-ai/doompi-git',\n moduleUrl,\n skills: [\n {\n name: 'doompi-use-git',\n description:\n 'Use @agimon-ai/doompi-git: Git worktree sessions for DoomPi: spawn an isolated worktree with its own session and manage it from the parent',\n },\n ],\n };\n}\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createDoompiUseGitResource } from './_lib/doompi-use-git.cli';\n\nexport default defineResource(createDoompiUseGitResource(import.meta.url));\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport { definePiTool, type PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../../schemas/runWorktreeTool';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n type RunWorktreeToolDetails,\n} from '../../../../../../services/runWorktree';\nimport type { WorktreeOperations } from '../../../../../../services/worktreeOperations';\nimport type { GitExtensionDependencies } from '../../../../../../types/extension';\nimport type { GitPiScope } from '../../_lib/root.cli';\n\nexport default defineCliTool((context: WithRoot<PiPluginContext<Partial<GitExtensionDependencies>>, GitPiScope>) =>\n definePiTool(createRunWorktreeTool(context.root.operations)),\n);\n\nexport { RUN_WORKTREE_TOOL_NAME, validateParams };\nexport type { RunWorktreeToolDetails };\n\n/** Creates the typed Pi worktree tool declaration. */\nexport function createRunWorktreeTool(\n operations: WorktreeOperations,\n): ToolDefinition<typeof RunWorktreeToolSchema, RunWorktreeToolDetails> {\n const tool: ToolDefinition<typeof RunWorktreeToolSchema, RunWorktreeToolDetails> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n prepareArguments: validateParams,\n // The signal and the progress callback are the host's two answers to a\n // call that takes minutes. Dropping them is what let an interrupted spawn\n // run on with nobody waiting for it, and left the caller staring at\n // nothing while it did.\n execute: async (_id, rawParams, signal, onUpdate, ctx) => {\n const params = validateParams(rawParams) as RunWorktreeToolParams;\n return (await executeRunWorktreeTool(\n params,\n operations,\n {\n cwd: ctx.cwd,\n sessionId: ctx.sessionManager.getSessionId(),\n },\n {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) =>\n onUpdate?.({ content: [{ type: 'text', text: label }], details: { action: params.action } }),\n },\n )) as AgentToolResult<RunWorktreeToolDetails>;\n },\n };\n return tool;\n}\n","import { defineCliTool } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/runWorktree.cli';\n\nexport default defineCliTool(contribution);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandGit from '../src/extensions/workspaces/sessions/(backend)/command/git.cli';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandGit> | OptionsOf<typeof resourceDoompiUseGit> | OptionsOf<typeof toolRunWorktree>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-git', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandGit, contextSession)]; },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseGit, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-git', [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":";;;;;;;;;AAMA,MAAM,QAAA,GAAOA,qCAAAA,WAAAA,EAAY,aAAiE,EACxF,OAAOC,wBAAAA,sBAAsB,QAAQ,OAAO,EAC9C,EAAE;;;ACJF,IAAA,oBAAA,GAAeC,qCAAAA,WAAAA,CAAWC,IAAY;;;ACJtC,MAAa,eAAe;AAC5B,MAAa,sBAAsB;;;ACQnC,SAAgB,iBACd,SACmE;CACnE,OAAO,CACL,cACA;EACE,aAAa;EACb,SAAS,OAAO,OAAO,QAAQ;GAC7B,MAAM,SAAS,MAAM,QAAQ,QAAQ;GACrC,IAAI,IAAI,OAAO,IAAI,GAAG,OAAO,OAAO,SAAS,OAAO,KAAK;EAC3D;CACF,CACF;AACF;AAEA,IAAA,qBAAgB,YACd,iBAAiB,QAAQ,KAAK,OAAO;;;ACrBvC,IAAA,mBAAA,GAAeC,qCAAAA,iBAAAA,CAAiBC,iBAAY;;;ACJ5C,SAAgB,2BAA2B,WAAmB;CAC5D,OAAO;EACL,QAAQ;EACR;EACA,QAAQ,CACN;GACE,MAAM;GACN,aACE;EACJ,CACF;CACF;AACF;;;ACRA,IAAA,8BAAA,GAAeC,qCAAAA,eAAAA,CAAe,2BAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,IAA0C,CAAC;;;ACazE,IAAA,6BAAA,GAAeC,qCAAAA,cAAAA,EAAe,aAAA,GAC5BC,mCAAAA,aAAAA,CAAa,sBAAsB,QAAQ,KAAK,UAAU,CAAC,CAC7D;;AAMA,SAAgB,sBACd,YACsE;CA4BtE,OAAO;EA1BL,MAAMC,oBAAAA;EACN,OAAO;EACP,aAAaC,oBAAAA;EACb,YAAYC,oBAAAA;EACZ,kBAAkBC,oBAAAA;EAKlB,SAAS,OAAO,KAAK,WAAW,QAAQ,UAAU,QAAQ;GACxD,MAAM,SAASA,oBAAAA,eAAe,SAAS;GACvC,OAAQ,MAAMC,oBAAAA,uBACZ,QACA,YACA;IACE,KAAK,IAAI;IACT,WAAW,IAAI,eAAe,aAAa;GAC7C,GACA;IACE,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;IACzC,aAAa,UACX,WAAW;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;KAAM,CAAC;KAAG,SAAS,EAAE,QAAQ,OAAO,OAAO;IAAE,CAAC;GAC/F,CACF;EACF;CAEQ;AACZ;;;ACpDA,IAAA,2BAAA,GAAeC,qCAAAA,cAAAA,CAAcC,yBAAY;;;ACYzC,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AACpE,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,aAAA,GAAYC,mCAAAA,kBAAAA,CAAoC,yBAAyB,OAAO,YAAY;CACvG,MAAM,eAAe,MAAMC,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,IAAA,GAAGC,qCAAAA,iBAAAA,CAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,iBAAY,cAAc,CAAC;EAAG;EAC7F,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAGC,4BAAsB,cAAc,CAAC;EAAG;EACzG,IAAA,GAAGC,mCAAAA,oBAAAA,CAAoB,yBAAyB,CAAC,IAAI,EAAE,MAAM,eAAe,GAAG,GAAGC,yBAAiB,cAAc,CAAC,CAAC,CAAC;EACpH,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.d.mts","names":[],"sources":["../../generated/pi.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"pi.d.mts","names":[],"sources":["../../generated/pi.ts"],"mappings":";;qBAqBa,+DAAS,mBAAA,QAAT"}
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -76,10 +76,10 @@ var runWorktree_cli_default = defineCliTool(runWorktree_cli_default$1);
|
|
|
76
76
|
//#endregion
|
|
77
77
|
//#region generated/pi.ts
|
|
78
78
|
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
79
|
-
const via = (identity, value) =>
|
|
79
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
80
80
|
...identity,
|
|
81
81
|
...value
|
|
82
|
-
}
|
|
82
|
+
};
|
|
83
83
|
const extension = definePiExtension("@agimon-ai/doompi-git", async (context) => {
|
|
84
84
|
const scopeSession = await root_cli_default(context);
|
|
85
85
|
const contextSession = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.mjs","names":["contribution","contribution","contribution","rootSession","commandGit","resourceDoompiUseGit","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/constants/git.ts","../../src/extensions/workspaces/sessions/(backend)/command/_lib/git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompi-use-git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/_lib/runWorktree.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli.ts","../../generated/pi.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createGitDependencies } from '../../../../../services/gitDependencies';\nimport type { GitExtensionDependencies } from '../../../../../types/extension';\n\nconst root = defineRoot((context: PiPluginContext<Partial<GitExtensionDependencies>>) => ({\n value: createGitDependencies(context.options),\n}));\n\nexport type GitPiScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.cli';\n\nexport default defineRoot(contribution);\n","export const COMMAND_NAME = 'doom-git';\nexport const COMMAND_DESCRIPTION = 'Show git worktrees owned by this session';\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n// @scaffold-generated\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../../../../../constants/git';\nimport type { GitExtensionDependencies, GitExtensionService } from '../../../../../../types/extension';\nimport type { GitPiScope } from '../../_lib/root.cli';\n\nexport function createGitCommand(\n service: GitExtensionService,\n): readonly [string, Parameters<ExtensionAPI['registerCommand']>[1]] {\n return [\n COMMAND_NAME,\n {\n description: COMMAND_DESCRIPTION,\n handler: async (_args, ctx) => {\n const result = await service.execute();\n if (ctx.hasUI) ctx.ui.notify(result.message, result.level);\n },\n },\n ];\n}\n\nexport default (context: WithRoot<PiPluginContext<Partial<GitExtensionDependencies>>, GitPiScope>) =>\n createGitCommand(context.root.service);\n","import { defineCliCommand } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git.cli';\n\nexport default defineCliCommand(contribution);\n","export function createDoompiUseGitResource(moduleUrl: string) {\n return {\n source: '@agimon-ai/doompi-git',\n moduleUrl,\n skills: [\n {\n name: 'doompi-use-git',\n description:\n 'Use @agimon-ai/doompi-git: Git worktree sessions for DoomPi: spawn an isolated worktree with its own session and manage it from the parent',\n },\n ],\n };\n}\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createDoompiUseGitResource } from './_lib/doompi-use-git.cli';\n\nexport default defineResource(createDoompiUseGitResource(import.meta.url));\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport { definePiTool, type PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../../schemas/runWorktreeTool';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n type RunWorktreeToolDetails,\n} from '../../../../../../services/runWorktree';\nimport type { WorktreeOperations } from '../../../../../../services/worktreeOperations';\nimport type { GitExtensionDependencies } from '../../../../../../types/extension';\nimport type { GitPiScope } from '../../_lib/root.cli';\n\nexport default defineCliTool((context: WithRoot<PiPluginContext<Partial<GitExtensionDependencies>>, GitPiScope>) =>\n definePiTool(createRunWorktreeTool(context.root.operations)),\n);\n\nexport { RUN_WORKTREE_TOOL_NAME, validateParams };\nexport type { RunWorktreeToolDetails };\n\n/** Creates the typed Pi worktree tool declaration. */\nexport function createRunWorktreeTool(\n operations: WorktreeOperations,\n): ToolDefinition<typeof RunWorktreeToolSchema, RunWorktreeToolDetails> {\n const tool: ToolDefinition<typeof RunWorktreeToolSchema, RunWorktreeToolDetails> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n prepareArguments: validateParams,\n // The signal and the progress callback are the host's two answers to a\n // call that takes minutes. Dropping them is what let an interrupted spawn\n // run on with nobody waiting for it, and left the caller staring at\n // nothing while it did.\n execute: async (_id, rawParams, signal, onUpdate, ctx) => {\n const params = validateParams(rawParams) as RunWorktreeToolParams;\n return (await executeRunWorktreeTool(\n params,\n operations,\n {\n cwd: ctx.cwd,\n sessionId: ctx.sessionManager.getSessionId(),\n },\n {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) =>\n onUpdate?.({ content: [{ type: 'text', text: label }], details: { action: params.action } }),\n },\n )) as AgentToolResult<RunWorktreeToolDetails>;\n },\n };\n return tool;\n}\n","import { defineCliTool } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/runWorktree.cli';\n\nexport default defineCliTool(contribution);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandGit from '../src/extensions/workspaces/sessions/(backend)/command/git.cli';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandGit> | OptionsOf<typeof resourceDoompiUseGit> | OptionsOf<typeof toolRunWorktree>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T => ({ ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-git', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandGit, contextSession)]; },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseGit, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-git', [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":";;;;;AAMA,MAAM,OAAO,YAAY,aAAiE,EACxF,OAAO,sBAAsB,QAAQ,OAAO,EAC9C,EAAE;;;ACJF,IAAA,mBAAe,WAAWA,IAAY;;;ACJtC,MAAa,eAAe;AAC5B,MAAa,sBAAsB;;;ACQnC,SAAgB,iBACd,SACmE;CACnE,OAAO,CACL,cACA;EACE,aAAa;EACb,SAAS,OAAO,OAAO,QAAQ;GAC7B,MAAM,SAAS,MAAM,QAAQ,QAAQ;GACrC,IAAI,IAAI,OAAO,IAAI,GAAG,OAAO,OAAO,SAAS,OAAO,KAAK;EAC3D;CACF,CACF;AACF;AAEA,IAAA,qBAAgB,YACd,iBAAiB,QAAQ,KAAK,OAAO;;;ACrBvC,IAAA,kBAAe,iBAAiBC,iBAAY;;;ACJ5C,SAAgB,2BAA2B,WAAmB;CAC5D,OAAO;EACL,QAAQ;EACR;EACA,QAAQ,CACN;GACE,MAAM;GACN,aACE;EACJ,CACF;CACF;AACF;;;ACRA,IAAA,6BAAe,eAAe,2BAA2B,YAAY,GAAG,CAAC;;;ACazE,IAAA,4BAAe,eAAe,YAC5B,aAAa,sBAAsB,QAAQ,KAAK,UAAU,CAAC,CAC7D;;AAMA,SAAgB,sBACd,YACsE;CA4BtE,OAAO;EA1BL,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY;EACZ,kBAAkB;EAKlB,SAAS,OAAO,KAAK,WAAW,QAAQ,UAAU,QAAQ;GACxD,MAAM,SAAS,eAAe,SAAS;GACvC,OAAQ,MAAM,uBACZ,QACA,YACA;IACE,KAAK,IAAI;IACT,WAAW,IAAI,eAAe,aAAa;GAC7C,GACA;IACE,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;IACzC,aAAa,UACX,WAAW;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;KAAM,CAAC;KAAG,SAAS,EAAE,QAAQ,OAAO,OAAO;IAAE,CAAC;GAC/F,CACF;EACF;CAEQ;AACZ;;;ACpDA,IAAA,0BAAe,cAAcC,yBAAY;;;ACYzC,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AACpE,MAAM,OAAU,UAAmC,WAAuB;CAAE,GAAG;CAAU,GAAI;AAAiB;AAE9G,MAAa,YAAY,kBAAoC,yBAAyB,OAAO,YAAY;CACvG,MAAM,eAAe,MAAMC,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,GAAG,iBAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,iBAAY,cAAc,CAAC;EAAG;EAC7F,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAGC,4BAAsB,cAAc,CAAC;EAAG;EACzG,GAAG,oBAAoB,yBAAyB,CAAC,IAAI,EAAE,MAAM,eAAe,GAAG,GAAGC,yBAAiB,cAAc,CAAC,CAAC,CAAC;EACpH,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"pi.mjs","names":["contribution","contribution","contribution","rootSession","commandGit","resourceDoompiUseGit","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/constants/git.ts","../../src/extensions/workspaces/sessions/(backend)/command/_lib/git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompi-use-git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/_lib/runWorktree.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli.ts","../../generated/pi.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createGitDependencies } from '../../../../../services/gitDependencies';\nimport type { GitExtensionDependencies } from '../../../../../types/extension';\n\nconst root = defineRoot((context: PiPluginContext<Partial<GitExtensionDependencies>>) => ({\n value: createGitDependencies(context.options),\n}));\n\nexport type GitPiScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.cli';\n\nexport default defineRoot(contribution);\n","export const COMMAND_NAME = 'doom-git';\nexport const COMMAND_DESCRIPTION = 'Show git worktrees owned by this session';\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n// @scaffold-generated\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { COMMAND_NAME, COMMAND_DESCRIPTION } from '../../../../../../constants/git';\nimport type { GitExtensionDependencies, GitExtensionService } from '../../../../../../types/extension';\nimport type { GitPiScope } from '../../_lib/root.cli';\n\nexport function createGitCommand(\n service: GitExtensionService,\n): readonly [string, Parameters<ExtensionAPI['registerCommand']>[1]] {\n return [\n COMMAND_NAME,\n {\n description: COMMAND_DESCRIPTION,\n handler: async (_args, ctx) => {\n const result = await service.execute();\n if (ctx.hasUI) ctx.ui.notify(result.message, result.level);\n },\n },\n ];\n}\n\nexport default (context: WithRoot<PiPluginContext<Partial<GitExtensionDependencies>>, GitPiScope>) =>\n createGitCommand(context.root.service);\n","import { defineCliCommand } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git.cli';\n\nexport default defineCliCommand(contribution);\n","export function createDoompiUseGitResource(moduleUrl: string) {\n return {\n source: '@agimon-ai/doompi-git',\n moduleUrl,\n skills: [\n {\n name: 'doompi-use-git',\n description:\n 'Use @agimon-ai/doompi-git: Git worktree sessions for DoomPi: spawn an isolated worktree with its own session and manage it from the parent',\n },\n ],\n };\n}\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createDoompiUseGitResource } from './_lib/doompi-use-git.cli';\n\nexport default defineResource(createDoompiUseGitResource(import.meta.url));\n","import { defineCliTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport { definePiTool, type PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\nimport type { AgentToolResult } from '@earendil-works/pi-agent-core';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../../schemas/runWorktreeTool';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n type RunWorktreeToolDetails,\n} from '../../../../../../services/runWorktree';\nimport type { WorktreeOperations } from '../../../../../../services/worktreeOperations';\nimport type { GitExtensionDependencies } from '../../../../../../types/extension';\nimport type { GitPiScope } from '../../_lib/root.cli';\n\nexport default defineCliTool((context: WithRoot<PiPluginContext<Partial<GitExtensionDependencies>>, GitPiScope>) =>\n definePiTool(createRunWorktreeTool(context.root.operations)),\n);\n\nexport { RUN_WORKTREE_TOOL_NAME, validateParams };\nexport type { RunWorktreeToolDetails };\n\n/** Creates the typed Pi worktree tool declaration. */\nexport function createRunWorktreeTool(\n operations: WorktreeOperations,\n): ToolDefinition<typeof RunWorktreeToolSchema, RunWorktreeToolDetails> {\n const tool: ToolDefinition<typeof RunWorktreeToolSchema, RunWorktreeToolDetails> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n prepareArguments: validateParams,\n // The signal and the progress callback are the host's two answers to a\n // call that takes minutes. Dropping them is what let an interrupted spawn\n // run on with nobody waiting for it, and left the caller staring at\n // nothing while it did.\n execute: async (_id, rawParams, signal, onUpdate, ctx) => {\n const params = validateParams(rawParams) as RunWorktreeToolParams;\n return (await executeRunWorktreeTool(\n params,\n operations,\n {\n cwd: ctx.cwd,\n sessionId: ctx.sessionManager.getSessionId(),\n },\n {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) =>\n onUpdate?.({ content: [{ type: 'text', text: label }], details: { action: params.action } }),\n },\n )) as AgentToolResult<RunWorktreeToolDetails>;\n },\n };\n return tool;\n}\n","import { defineCliTool } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/runWorktree.cli';\n\nexport default defineCliTool(contribution);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandGit from '../src/extensions/workspaces/sessions/(backend)/command/git.cli';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandGit> | OptionsOf<typeof resourceDoompiUseGit> | OptionsOf<typeof toolRunWorktree>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-git', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandGit, contextSession)]; },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseGit, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-git', [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":";;;;;AAMA,MAAM,OAAO,YAAY,aAAiE,EACxF,OAAO,sBAAsB,QAAQ,OAAO,EAC9C,EAAE;;;ACJF,IAAA,mBAAe,WAAWA,IAAY;;;ACJtC,MAAa,eAAe;AAC5B,MAAa,sBAAsB;;;ACQnC,SAAgB,iBACd,SACmE;CACnE,OAAO,CACL,cACA;EACE,aAAa;EACb,SAAS,OAAO,OAAO,QAAQ;GAC7B,MAAM,SAAS,MAAM,QAAQ,QAAQ;GACrC,IAAI,IAAI,OAAO,IAAI,GAAG,OAAO,OAAO,SAAS,OAAO,KAAK;EAC3D;CACF,CACF;AACF;AAEA,IAAA,qBAAgB,YACd,iBAAiB,QAAQ,KAAK,OAAO;;;ACrBvC,IAAA,kBAAe,iBAAiBC,iBAAY;;;ACJ5C,SAAgB,2BAA2B,WAAmB;CAC5D,OAAO;EACL,QAAQ;EACR;EACA,QAAQ,CACN;GACE,MAAM;GACN,aACE;EACJ,CACF;CACF;AACF;;;ACRA,IAAA,6BAAe,eAAe,2BAA2B,YAAY,GAAG,CAAC;;;ACazE,IAAA,4BAAe,eAAe,YAC5B,aAAa,sBAAsB,QAAQ,KAAK,UAAU,CAAC,CAC7D;;AAMA,SAAgB,sBACd,YACsE;CA4BtE,OAAO;EA1BL,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY;EACZ,kBAAkB;EAKlB,SAAS,OAAO,KAAK,WAAW,QAAQ,UAAU,QAAQ;GACxD,MAAM,SAAS,eAAe,SAAS;GACvC,OAAQ,MAAM,uBACZ,QACA,YACA;IACE,KAAK,IAAI;IACT,WAAW,IAAI,eAAe,aAAa;GAC7C,GACA;IACE,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;IACzC,aAAa,UACX,WAAW;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;KAAM,CAAC;KAAG,SAAS,EAAE,QAAQ,OAAO,OAAO;IAAE,CAAC;GAC/F,CACF;EACF;CAEQ;AACZ;;;ACpDA,IAAA,0BAAe,cAAcC,yBAAY;;;ACYzC,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AACpE,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,YAAY,kBAAoC,yBAAyB,OAAO,YAAY;CACvG,MAAM,eAAe,MAAMC,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,GAAG,iBAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,iBAAY,cAAc,CAAC;EAAG;EAC7F,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAGC,4BAAsB,cAAc,CAAC;EAAG;EACzG,GAAG,oBAAoB,yBAAyB,CAAC,IAAI,EAAE,MAAM,eAAe,GAAG,GAAGC,yBAAiB,cAAc,CAAC,CAAC,CAAC;EACpH,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}
|
|
@@ -433,10 +433,10 @@ var runWorktree_server_default = (0, _agimon_ai_doompi_core_extensionFile.define
|
|
|
433
433
|
//#endregion
|
|
434
434
|
//#region generated/server.ts
|
|
435
435
|
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
436
|
-
const via = (identity, value) =>
|
|
436
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
437
437
|
...identity,
|
|
438
438
|
...value
|
|
439
|
-
}
|
|
439
|
+
};
|
|
440
440
|
const facet = (0, _agimon_ai_doompi_core_serverFacet.defineServerPlugin)({
|
|
441
441
|
name: "@agimon-ai/doompi-git",
|
|
442
442
|
global: (context) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.cjs","names":["createWorktreeMessageInbox","createWorktreeOperations","createWorktreeGit","readDoomSessionDelivery","readPackageResource","RUN_WORKTREE_TOOL_NAME","RUN_WORKTREE_DESCRIPTION","RunWorktreeToolSchema","validateParams","executeRunWorktreeTool","defineRoot","defineRoot","contribution","DoomGitExpectedError","GIT_WORKTREE_LIFECYCLE_EVENT","createWorktreeOperations","createWorktreeGit","defineRoute","contribution","createWorktreeRegistry","registryFile","DoomGitExpectedError","HubUnavailableError","createWorktreeOperations","createWorktreeGit","GIT_WORKTREE_LIFECYCLE_EVENT","isWorktreeLifecycleEvent","defineChannel","contribution","defineResource","contribution","defineResource","contribution","defineResource","contribution","defineServerTool","defineServerPlugin","apiRoute","channelGitWorktrees","rootSession","composeRootHooks","resourceDoompiGit","resourceDoompiGitReadme","resourceDoompiUseGit","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/(backend)/api/_lib/route.server.ts","../../src/extensions/(backend)/api/route.server.ts","../../src/types/webWorktrees.ts","../../src/extensions/(backend)/channel/_lib/git-worktrees.server.ts","../../src/extensions/(backend)/channel/git-worktrees.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.ts","../../generated/server.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport {\n type DoomHeadlessResource,\n type DoomHeadlessTool,\n type DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\nimport { readPackageResource, type DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport { readDoomSessionDelivery } from '@agimon-ai/doompi-session';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../schemas/runWorktreeTool';\nimport { createWorktreeGit } from '../../../../../services/gitCli';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n} from '../../../../../services/runWorktree';\nimport { createWorktreeMessageInbox } from '../../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../../services/worktreeOperations';\n\nfunction progressResult(action: RunWorktreeToolParams['action'], label: string): DoomHeadlessToolResult {\n return { content: [{ type: 'text', text: label }], details: { action } };\n}\n\nexport function createGitSession({ context, host: serverHost }: DoomServerPluginContext) {\n if (serverHost.context.directEvents === undefined)\n throw new Error('Git headless facet requires the session direct event bus.');\n if (serverHost.context.sessionId === undefined) throw new Error('Git headless facet requires a session identity.');\n const sessionId = serverHost.context.sessionId;\n const directEvents = serverHost.context.directEvents;\n const messageInbox = createWorktreeMessageInbox(directEvents, sessionId);\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: serverHost.context.sessionService,\n messageInbox,\n sessionDelivery: () => readDoomSessionDelivery(context),\n });\n const resources: DoomHeadlessResource[] = [\n {\n // The package index is Help-catalog material, not standing instruction, so it\n // only enters the prompt while Help mode is active. Matches the Pi facet,\n // which has always routed this through the Help service.\n when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor', mode: 'help' } },\n name: 'doompi-git',\n kind: 'context',\n read: () => readPackageResource(import.meta.url, 'llms.txt'),\n },\n {\n name: 'doompi-use-git',\n kind: 'skill',\n read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-use-git/SKILL.md'),\n },\n ];\n\n const tool: DoomHeadlessTool<typeof RunWorktreeToolSchema> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n promptSnippet: 'Create and manage Git worktree sessions',\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal, onUpdate, execution) {\n const params = validateParams(parameters) as RunWorktreeToolParams;\n return executeRunWorktreeTool(params, operations, execution, {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) => onUpdate?.(progressResult(params.action, label)),\n });\n },\n };\n return { value: { resources, tool }, onDispose: () => messageInbox.close() };\n}\n\nconst root = defineRoot(createGitSession);\nexport type GitServerScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.server';\n\nexport default defineRoot(contribution);\n","import type { DoomApi, DoomApiContext, DoomApiHandler } from '@agimon-ai/doompi-core/packageApi';\n\nimport { DoomGitExpectedError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../services/worktreeOperations';\n\n/**\n * The worktree surface the cockpit panel calls.\n *\n * Hub-scoped because worktrees are a property of a repository, not of one\n * session: the panel lists and creates them whether or not the session that\n * made them is focused, and a session-scoped API would disappear with it.\n *\n * The panel names a repository by the hub's opaque id and never by path.\n * `resolveRepository` turns that into an admitted root, so a browser cannot\n * point this at a directory the cockpit was never given.\n */\nfunction badRequest(message: string): Response {\n return Response.json({ error: message }, { status: 400 });\n}\n\nfunction failed(error: unknown): Response {\n if (error instanceof DoomGitExpectedError) {\n return Response.json({ error: error.message, code: error.code }, { status: error.retryable ? 503 : 409 });\n }\n // Never the raw message: a git failure can carry a remote URL with a token.\n return Response.json({ error: 'The worktree operation failed.' }, { status: 500 });\n}\n\nexport const api: DoomApi = {\n basePath: 'git',\n start(context: DoomApiContext): DoomApiHandler {\n if (context.directEvents === undefined) throw new Error('Git hub API requires the direct event bus.');\n const directEvents = context.directEvents;\n const publishLifecycle = (sessionId: string, repositoryRoot: string): void => {\n directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, sessionId, { version: 1 as const, repositoryRoot });\n };\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: context.sessionService,\n });\n\n /** The admitted root for a request, or a response explaining why not. */\n const rootOf = (url: URL): string | Response => {\n const repositoryId = url.searchParams.get('repositoryId');\n if (repositoryId === null || repositoryId === '') return badRequest('A repositoryId is required.');\n const root = context.resolveRepository?.(repositoryId);\n if (root === undefined) return badRequest('That repository is not admitted to this cockpit.');\n return root;\n };\n\n return {\n async fetch(request) {\n const url = new URL(request.url);\n const root = rootOf(url);\n if (root instanceof Response) return root;\n // The operations layer works from a cwd, and an admitted repository\n // root is one.\n const callerContext = { cwd: root, sessionId: url.searchParams.get('sessionId') ?? '' };\n const isMutation =\n (request.method === 'POST' && url.pathname === '/worktrees') ||\n (request.method === 'DELETE' && /^\\/worktrees\\/[^/]+$/u.test(url.pathname));\n if (isMutation && callerContext.sessionId === '')\n return badRequest('A sessionId is required for worktree mutations.');\n\n try {\n if (request.method === 'GET' && url.pathname === '/worktrees') {\n return Response.json({ worktrees: await operations.list(callerContext) });\n }\n if (request.method === 'POST' && url.pathname === '/worktrees') {\n const body = (await request.json()) as { branch?: string; baseRef?: string; name?: string };\n if (typeof body.branch !== 'string' || body.branch.trim() === '') {\n return badRequest('A branch is required.');\n }\n const record = await operations.spawn(callerContext, {\n branch: body.branch,\n ...(body.baseRef === undefined ? {} : { baseRef: body.baseRef }),\n ...(body.name === undefined ? {} : { name: body.name }),\n });\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record }, { status: 201 });\n }\n const closing = /^\\/worktrees\\/([^/]+)$/u.exec(url.pathname);\n if (request.method === 'DELETE' && closing) {\n const record = await operations.close(\n callerContext,\n decodeURIComponent(String(closing[1])),\n url.searchParams.get('force') === 'true',\n );\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record });\n }\n return Response.json({ error: 'No such worktree route.' }, { status: 404 });\n } catch (error) {\n context.onNotice(`worktree request failed: ${(error as Error).name}`);\n return failed(error);\n }\n },\n close() {},\n };\n },\n};\n\nexport default api;\n","import { defineRoute } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/route.server';\n\nexport default defineRoute(contribution);\n","/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The worktrees data channel, and the commands the dock sends back through it.\n *\n * The registry is durable state only. Live lifecycle changes arrive through the\n * hub-owned direct event bus, so this channel never polls or claims files.\n */\nimport type {\n DoomHubChannel,\n DoomHubChannelSource,\n DoomHubSessionScope,\n DoomHubSessionService,\n} from '@agimon-ai/doompi-core/hubChannel';\n\nimport { DoomGitExpectedError, HubUnavailableError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { registryFile } from '../../../../services/paths';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT, isWorktreeLifecycleEvent } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations, type WorktreeOperations } from '../../../../services/worktreeOperations';\nimport { createWorktreeRegistry } from '../../../../services/worktreeRegistry';\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../types/webWorktrees';\n\ninterface SessionState {\n worktrees: WorktreeView[];\n pending: string | undefined;\n error: string | undefined;\n errorTarget: WorktreeErrorTarget | undefined;\n}\n\nfunction payloadOf(state: SessionState): Record<string, unknown> {\n return {\n worktrees: state.worktrees,\n ...(state.pending === undefined ? {} : { pending: state.pending }),\n ...(state.error === undefined ? {} : { error: state.error }),\n ...(state.errorTarget === undefined ? {} : { errorTarget: state.errorTarget }),\n };\n}\n\n/** What the channel needs from its surroundings, injected so tests stay off this machine. */\nexport interface WorktreesChannelOptions {\n operations?: WorktreeOperations;\n homeDir?: string;\n}\n\ninterface ViewDeps {\n homeDir: string | undefined;\n sessionService: DoomHubSessionService;\n}\n\n/** Worktrees visible to this session, using the hub's live session table for ownership. */\nfunction viewsFor(scope: DoomHubSessionScope, deps: ViewDeps): WorktreeView[] {\n try {\n return createWorktreeRegistry(registryFile(scope.cwd, deps.homeDir))\n .list()\n .flatMap((record) => {\n const owned = record.parentSessionId === scope.sessionId;\n const unowned = !owned && !deps.sessionService.isLive(record.parentSessionId);\n if (!owned && !unowned) return [];\n return [\n {\n id: record.id,\n branch: record.branch,\n path: record.path,\n sessionId: record.status === 'orphaned' ? null : record.sessionId,\n orphaned: record.status === 'orphaned',\n unowned,\n },\n ];\n });\n } catch {\n return [];\n }\n}\n\nfunction sameList(left: readonly WorktreeView[], right: readonly WorktreeView[]): boolean {\n if (left.length !== right.length) return false;\n return left.every((entry, index) => {\n const other = right[index];\n return (\n other !== undefined &&\n entry.id === other.id &&\n entry.branch === other.branch &&\n entry.sessionId === other.sessionId &&\n entry.orphaned === other.orphaned &&\n entry.unowned === other.unowned\n );\n });\n}\n\nfunction errorTargetFor(command: GitWorktreesCommand): WorktreeErrorTarget {\n return command.action === 'create' ? { action: 'create' } : { action: 'close', id: command.id };\n}\n\n/** A command the page sent, or undefined when the frame was not one. */\nfunction parseCommand(payload: unknown): GitWorktreesCommand | undefined {\n if (typeof payload !== 'object' || payload === null) return undefined;\n const value = payload as Record<string, unknown>;\n if (value.action === 'create') {\n if (typeof value.branch !== 'string' || value.branch.trim() === '') return undefined;\n if (\n value.reservationId !== undefined &&\n (typeof value.reservationId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(value.reservationId))\n )\n return undefined;\n return {\n action: 'create',\n branch: value.branch.trim(),\n ...(typeof value.baseRef === 'string' && value.baseRef.trim() !== '' ? { baseRef: value.baseRef.trim() } : {}),\n ...(typeof value.reservationId === 'string' ? { reservationId: value.reservationId } : {}),\n };\n }\n if (value.action === 'close') {\n if (typeof value.id !== 'string' || value.id === '') return undefined;\n return { action: 'close', id: value.id, ...(value.force === true ? { force: true } : {}) };\n }\n return undefined;\n}\n\n/**\n * What the reader is told when a command fails.\n *\n * An expected failure explains itself. Anything else is summarised, never\n * echoed: a git error can carry a remote URL with a token in it.\n */\nfunction failureText(error: unknown): string {\n return error instanceof DoomGitExpectedError ? error.message : 'The worktree operation failed.';\n}\n\n/** Starts one direct-event subscription per managed session. */\nexport function createWorktreesChannel(options: WorktreesChannelOptions = {}): DoomHubChannel {\n // Assigned by start, because receive is reachable only while the channel is\n // running and the command needs the state the direct event subscriptions keep.\n let receiveCommand: ((scope: DoomHubSessionScope, payload: unknown) => void) | undefined;\n\n return {\n frameType: GIT_WORKTREES_TYPE,\n start(host) {\n const sessionService = host.sessionService;\n if (sessionService === undefined) {\n throw new HubUnavailableError('The cockpit session service is unavailable. Start the cockpit and try again.');\n }\n const worktrees =\n options.operations ??\n createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService,\n });\n const unregisterWorktreeProvisioner = sessionService.registerReservedWorktreeProvisioner?.(\n async ({ reservationId, parentSessionId, signal }) => {\n const parent = host.sessions().find((scope) => scope.sessionId === parentSessionId);\n if (parent === undefined) throw new Error('The conversation parent session is unavailable.');\n const branch = `doompi/conversation-${reservationId.slice(0, 12)}`;\n await worktrees.spawn(\n { cwd: parent.cwd, sessionId: parent.sessionId },\n { branch, name: `conversation ${reservationId.slice(0, 8)}`, reservationId },\n { signal },\n );\n const reservations = sessionService.reservations;\n if (reservations === undefined) throw new Error('Conversation reservations are unavailable.');\n return reservations.complete(reservationId, parentSessionId);\n },\n );\n const views: ViewDeps = { homeDir: options.homeDir, sessionService };\n const latest = new Map<string, SessionState>();\n const subscriptions = new Map<string, () => void>();\n const busy = new Set<string>();\n const generations = new Map<string, symbol>();\n const newGeneration = (sessionId: string): symbol => {\n const generation = Symbol(sessionId);\n generations.set(sessionId, generation);\n return generation;\n };\n\n /** Republishes a session, skipping a frame that would say nothing new. */\n const publish = (scope: DoomHubSessionScope, force: boolean): void => {\n const previous = latest.get(scope.sessionId);\n const next: SessionState = {\n worktrees: viewsFor(scope, views),\n pending: previous?.pending,\n error: previous?.error,\n errorTarget: previous?.errorTarget,\n };\n if (\n !force &&\n previous !== undefined &&\n sameList(previous.worktrees, next.worktrees) &&\n previous.pending === next.pending &&\n previous.error === next.error &&\n previous.errorTarget === next.errorTarget\n ) {\n return;\n }\n latest.set(scope.sessionId, next);\n host.publish(scope.sessionId, payloadOf(next));\n };\n\n const mark = (\n scope: DoomHubSessionScope,\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n const previous = latest.get(scope.sessionId);\n latest.set(scope.sessionId, {\n worktrees: previous?.worktrees ?? viewsFor(scope, views),\n pending,\n error,\n errorTarget,\n });\n publish(scope, true);\n };\n\n /** Announces a successful mutation to this session's lifecycle subscribers. */\n const publishLifecycle = (scope: DoomHubSessionScope, repositoryRoot: string): void => {\n host.directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, {\n version: 1,\n repositoryRoot,\n });\n };\n\n const run = async (\n scope: DoomHubSessionScope,\n command: GitWorktreesCommand,\n generation: symbol,\n ): Promise<void> => {\n const context = { cwd: scope.cwd, sessionId: scope.sessionId };\n const markCurrent = (\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, pending, error, errorTarget);\n };\n if (command.action === 'create') {\n markCurrent(`creating ${command.branch}…`, undefined, undefined);\n const record = await worktrees.spawn(\n context,\n {\n branch: command.branch,\n ...(command.baseRef === undefined ? {} : { baseRef: command.baseRef }),\n ...(command.reservationId === undefined ? {} : { reservationId: command.reservationId }),\n },\n // Each phase replaces the label, so the panel says what is\n // happening instead of holding one line for the whole wait.\n { onProgress: (label) => markCurrent(label, undefined, undefined) },\n );\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n return;\n }\n markCurrent(`closing ${command.id}…`, undefined, undefined);\n const record = await worktrees.close(context, command.id, command.force ?? false);\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n };\n\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n const state = latest.get(scope.sessionId);\n return state === undefined ? undefined : payloadOf(state);\n },\n sessionAdded(scope) {\n newGeneration(scope.sessionId);\n publish(scope, false);\n const unsubscribe = host.directEvents.subscribe(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, (payload) => {\n if (!isWorktreeLifecycleEvent(payload)) return;\n let sameRepository = false;\n try {\n sameRepository =\n registryFile(scope.cwd, options.homeDir) === registryFile(payload.repositoryRoot, options.homeDir);\n } catch {\n sameRepository = false;\n }\n if (sameRepository) publish(scope, false);\n });\n subscriptions.set(scope.sessionId, unsubscribe);\n },\n sessionRemoved(sessionId) {\n newGeneration(sessionId);\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n latest.delete(sessionId);\n busy.delete(sessionId);\n },\n close() {\n unregisterWorktreeProvisioner?.();\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n latest.clear();\n busy.clear();\n generations.clear();\n },\n };\n receiveCommand = (scope, payload) => {\n const command = parseCommand(payload);\n if (command === undefined) return;\n // One operation per session. A create runs for minutes, and a second\n // click must not start a second worktree behind the first.\n if (busy.has(scope.sessionId)) return;\n const generation = generations.get(scope.sessionId);\n if (generation === undefined) return;\n busy.add(scope.sessionId);\n void run(scope, command, generation)\n .then(() => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, undefined, undefined, undefined);\n })\n .catch((error: unknown) => {\n if (generations.get(scope.sessionId) !== generation) return;\n host.onNotice(`worktree command failed for ${scope.sessionId} (${failureText(error)})`);\n mark(scope, undefined, failureText(error), errorTargetFor(command));\n })\n .finally(() => {\n if (generations.get(scope.sessionId) === generation) busy.delete(scope.sessionId);\n });\n };\n\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport default createWorktreesChannel;\n","import { defineChannel } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git-worktrees.server';\n\nexport default defineChannel(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[0]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGit.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[2]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGitReadme.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[1]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiUseGit.server';\n\nexport default defineResource(contribution);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../_lib/root.server';\n\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.tool);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/route.server';\nimport channelGitWorktrees from '../src/extensions/(backend)/channel/git-worktrees.server';\nimport resourceDoompiGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server';\nimport resourceDoompiGitReadme from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T => ({ ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/doompi-git',\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiGit, contextSession), at(resourceDoompiGitReadme, contextSession), at(resourceDoompiUseGit, contextSession)]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["createWorktreeMessageInbox","createWorktreeOperations","createWorktreeGit","readDoomSessionDelivery","readPackageResource","RUN_WORKTREE_TOOL_NAME","RUN_WORKTREE_DESCRIPTION","RunWorktreeToolSchema","validateParams","executeRunWorktreeTool","defineRoot","defineRoot","contribution","DoomGitExpectedError","GIT_WORKTREE_LIFECYCLE_EVENT","createWorktreeOperations","createWorktreeGit","defineRoute","contribution","createWorktreeRegistry","registryFile","DoomGitExpectedError","HubUnavailableError","createWorktreeOperations","createWorktreeGit","GIT_WORKTREE_LIFECYCLE_EVENT","isWorktreeLifecycleEvent","defineChannel","contribution","defineResource","contribution","defineResource","contribution","defineResource","contribution","defineServerTool","defineServerPlugin","apiRoute","channelGitWorktrees","rootSession","composeRootHooks","resourceDoompiGit","resourceDoompiGitReadme","resourceDoompiUseGit","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/(backend)/api/_lib/route.server.ts","../../src/extensions/(backend)/api/route.server.ts","../../src/types/webWorktrees.ts","../../src/extensions/(backend)/channel/_lib/git-worktrees.server.ts","../../src/extensions/(backend)/channel/git-worktrees.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.ts","../../generated/server.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport {\n type DoomHeadlessResource,\n type DoomHeadlessTool,\n type DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\nimport { readPackageResource, type DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport { readDoomSessionDelivery } from '@agimon-ai/doompi-session';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../schemas/runWorktreeTool';\nimport { createWorktreeGit } from '../../../../../services/gitCli';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n} from '../../../../../services/runWorktree';\nimport { createWorktreeMessageInbox } from '../../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../../services/worktreeOperations';\n\nfunction progressResult(action: RunWorktreeToolParams['action'], label: string): DoomHeadlessToolResult {\n return { content: [{ type: 'text', text: label }], details: { action } };\n}\n\nexport function createGitSession({ context, host: serverHost }: DoomServerPluginContext) {\n if (serverHost.context.directEvents === undefined)\n throw new Error('Git headless facet requires the session direct event bus.');\n if (serverHost.context.sessionId === undefined) throw new Error('Git headless facet requires a session identity.');\n const sessionId = serverHost.context.sessionId;\n const directEvents = serverHost.context.directEvents;\n const messageInbox = createWorktreeMessageInbox(directEvents, sessionId);\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: serverHost.context.sessionService,\n messageInbox,\n sessionDelivery: () => readDoomSessionDelivery(context),\n });\n const resources: DoomHeadlessResource[] = [\n {\n // The package index is Help-catalog material, not standing instruction, so it\n // only enters the prompt while Help mode is active. Matches the Pi facet,\n // which has always routed this through the Help service.\n when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor', mode: 'help' } },\n name: 'doompi-git',\n kind: 'context',\n read: () => readPackageResource(import.meta.url, 'llms.txt'),\n },\n {\n name: 'doompi-use-git',\n kind: 'skill',\n read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-use-git/SKILL.md'),\n },\n ];\n\n const tool: DoomHeadlessTool<typeof RunWorktreeToolSchema> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n promptSnippet: 'Create and manage Git worktree sessions',\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal, onUpdate, execution) {\n const params = validateParams(parameters) as RunWorktreeToolParams;\n return executeRunWorktreeTool(params, operations, execution, {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) => onUpdate?.(progressResult(params.action, label)),\n });\n },\n };\n return { value: { resources, tool }, onDispose: () => messageInbox.close() };\n}\n\nconst root = defineRoot(createGitSession);\nexport type GitServerScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.server';\n\nexport default defineRoot(contribution);\n","import type { DoomApi, DoomApiContext, DoomApiHandler } from '@agimon-ai/doompi-core/packageApi';\n\nimport { DoomGitExpectedError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../services/worktreeOperations';\n\n/**\n * The worktree surface the cockpit panel calls.\n *\n * Hub-scoped because worktrees are a property of a repository, not of one\n * session: the panel lists and creates them whether or not the session that\n * made them is focused, and a session-scoped API would disappear with it.\n *\n * The panel names a repository by the hub's opaque id and never by path.\n * `resolveRepository` turns that into an admitted root, so a browser cannot\n * point this at a directory the cockpit was never given.\n */\nfunction badRequest(message: string): Response {\n return Response.json({ error: message }, { status: 400 });\n}\n\nfunction failed(error: unknown): Response {\n if (error instanceof DoomGitExpectedError) {\n return Response.json({ error: error.message, code: error.code }, { status: error.retryable ? 503 : 409 });\n }\n // Never the raw message: a git failure can carry a remote URL with a token.\n return Response.json({ error: 'The worktree operation failed.' }, { status: 500 });\n}\n\nexport const api: DoomApi = {\n basePath: 'git',\n start(context: DoomApiContext): DoomApiHandler {\n if (context.directEvents === undefined) throw new Error('Git hub API requires the direct event bus.');\n const directEvents = context.directEvents;\n const publishLifecycle = (sessionId: string, repositoryRoot: string): void => {\n directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, sessionId, { version: 1 as const, repositoryRoot });\n };\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: context.sessionService,\n });\n\n /** The admitted root for a request, or a response explaining why not. */\n const rootOf = (url: URL): string | Response => {\n const repositoryId = url.searchParams.get('repositoryId');\n if (repositoryId === null || repositoryId === '') return badRequest('A repositoryId is required.');\n const root = context.resolveRepository?.(repositoryId);\n if (root === undefined) return badRequest('That repository is not admitted to this cockpit.');\n return root;\n };\n\n return {\n async fetch(request) {\n const url = new URL(request.url);\n const root = rootOf(url);\n if (root instanceof Response) return root;\n // The operations layer works from a cwd, and an admitted repository\n // root is one.\n const callerContext = { cwd: root, sessionId: url.searchParams.get('sessionId') ?? '' };\n const isMutation =\n (request.method === 'POST' && url.pathname === '/worktrees') ||\n (request.method === 'DELETE' && /^\\/worktrees\\/[^/]+$/u.test(url.pathname));\n if (isMutation && callerContext.sessionId === '')\n return badRequest('A sessionId is required for worktree mutations.');\n\n try {\n if (request.method === 'GET' && url.pathname === '/worktrees') {\n return Response.json({ worktrees: await operations.list(callerContext) });\n }\n if (request.method === 'POST' && url.pathname === '/worktrees') {\n const body = (await request.json()) as { branch?: string; baseRef?: string; name?: string };\n if (typeof body.branch !== 'string' || body.branch.trim() === '') {\n return badRequest('A branch is required.');\n }\n const record = await operations.spawn(callerContext, {\n branch: body.branch,\n ...(body.baseRef === undefined ? {} : { baseRef: body.baseRef }),\n ...(body.name === undefined ? {} : { name: body.name }),\n });\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record }, { status: 201 });\n }\n const closing = /^\\/worktrees\\/([^/]+)$/u.exec(url.pathname);\n if (request.method === 'DELETE' && closing) {\n const record = await operations.close(\n callerContext,\n decodeURIComponent(String(closing[1])),\n url.searchParams.get('force') === 'true',\n );\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record });\n }\n return Response.json({ error: 'No such worktree route.' }, { status: 404 });\n } catch (error) {\n context.onNotice(`worktree request failed: ${(error as Error).name}`);\n return failed(error);\n }\n },\n close() {},\n };\n },\n};\n\nexport default api;\n","import { defineRoute } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/route.server';\n\nexport default defineRoute(contribution);\n","/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The worktrees data channel, and the commands the dock sends back through it.\n *\n * The registry is durable state only. Live lifecycle changes arrive through the\n * hub-owned direct event bus, so this channel never polls or claims files.\n */\nimport type {\n DoomHubChannel,\n DoomHubChannelSource,\n DoomHubSessionScope,\n DoomHubSessionService,\n} from '@agimon-ai/doompi-core/hubChannel';\n\nimport { DoomGitExpectedError, HubUnavailableError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { registryFile } from '../../../../services/paths';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT, isWorktreeLifecycleEvent } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations, type WorktreeOperations } from '../../../../services/worktreeOperations';\nimport { createWorktreeRegistry } from '../../../../services/worktreeRegistry';\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../types/webWorktrees';\n\ninterface SessionState {\n worktrees: WorktreeView[];\n pending: string | undefined;\n error: string | undefined;\n errorTarget: WorktreeErrorTarget | undefined;\n}\n\nfunction payloadOf(state: SessionState): Record<string, unknown> {\n return {\n worktrees: state.worktrees,\n ...(state.pending === undefined ? {} : { pending: state.pending }),\n ...(state.error === undefined ? {} : { error: state.error }),\n ...(state.errorTarget === undefined ? {} : { errorTarget: state.errorTarget }),\n };\n}\n\n/** What the channel needs from its surroundings, injected so tests stay off this machine. */\nexport interface WorktreesChannelOptions {\n operations?: WorktreeOperations;\n homeDir?: string;\n}\n\ninterface ViewDeps {\n homeDir: string | undefined;\n sessionService: DoomHubSessionService;\n}\n\n/** Worktrees visible to this session, using the hub's live session table for ownership. */\nfunction viewsFor(scope: DoomHubSessionScope, deps: ViewDeps): WorktreeView[] {\n try {\n return createWorktreeRegistry(registryFile(scope.cwd, deps.homeDir))\n .list()\n .flatMap((record) => {\n const owned = record.parentSessionId === scope.sessionId;\n const unowned = !owned && !deps.sessionService.isLive(record.parentSessionId);\n if (!owned && !unowned) return [];\n return [\n {\n id: record.id,\n branch: record.branch,\n path: record.path,\n sessionId: record.status === 'orphaned' ? null : record.sessionId,\n orphaned: record.status === 'orphaned',\n unowned,\n },\n ];\n });\n } catch {\n return [];\n }\n}\n\nfunction sameList(left: readonly WorktreeView[], right: readonly WorktreeView[]): boolean {\n if (left.length !== right.length) return false;\n return left.every((entry, index) => {\n const other = right[index];\n return (\n other !== undefined &&\n entry.id === other.id &&\n entry.branch === other.branch &&\n entry.sessionId === other.sessionId &&\n entry.orphaned === other.orphaned &&\n entry.unowned === other.unowned\n );\n });\n}\n\nfunction errorTargetFor(command: GitWorktreesCommand): WorktreeErrorTarget {\n return command.action === 'create' ? { action: 'create' } : { action: 'close', id: command.id };\n}\n\n/** A command the page sent, or undefined when the frame was not one. */\nfunction parseCommand(payload: unknown): GitWorktreesCommand | undefined {\n if (typeof payload !== 'object' || payload === null) return undefined;\n const value = payload as Record<string, unknown>;\n if (value.action === 'create') {\n if (typeof value.branch !== 'string' || value.branch.trim() === '') return undefined;\n if (\n value.reservationId !== undefined &&\n (typeof value.reservationId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(value.reservationId))\n )\n return undefined;\n return {\n action: 'create',\n branch: value.branch.trim(),\n ...(typeof value.baseRef === 'string' && value.baseRef.trim() !== '' ? { baseRef: value.baseRef.trim() } : {}),\n ...(typeof value.reservationId === 'string' ? { reservationId: value.reservationId } : {}),\n };\n }\n if (value.action === 'close') {\n if (typeof value.id !== 'string' || value.id === '') return undefined;\n return { action: 'close', id: value.id, ...(value.force === true ? { force: true } : {}) };\n }\n return undefined;\n}\n\n/**\n * What the reader is told when a command fails.\n *\n * An expected failure explains itself. Anything else is summarised, never\n * echoed: a git error can carry a remote URL with a token in it.\n */\nfunction failureText(error: unknown): string {\n return error instanceof DoomGitExpectedError ? error.message : 'The worktree operation failed.';\n}\n\n/** Starts one direct-event subscription per managed session. */\nexport function createWorktreesChannel(options: WorktreesChannelOptions = {}): DoomHubChannel {\n // Assigned by start, because receive is reachable only while the channel is\n // running and the command needs the state the direct event subscriptions keep.\n let receiveCommand: ((scope: DoomHubSessionScope, payload: unknown) => void) | undefined;\n\n return {\n frameType: GIT_WORKTREES_TYPE,\n start(host) {\n const sessionService = host.sessionService;\n if (sessionService === undefined) {\n throw new HubUnavailableError('The cockpit session service is unavailable. Start the cockpit and try again.');\n }\n const worktrees =\n options.operations ??\n createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService,\n });\n const unregisterWorktreeProvisioner = sessionService.registerReservedWorktreeProvisioner?.(\n async ({ reservationId, parentSessionId, signal }) => {\n const parent = host.sessions().find((scope) => scope.sessionId === parentSessionId);\n if (parent === undefined) throw new Error('The conversation parent session is unavailable.');\n const branch = `doompi/conversation-${reservationId.slice(0, 12)}`;\n await worktrees.spawn(\n { cwd: parent.cwd, sessionId: parent.sessionId },\n { branch, name: `conversation ${reservationId.slice(0, 8)}`, reservationId },\n { signal },\n );\n const reservations = sessionService.reservations;\n if (reservations === undefined) throw new Error('Conversation reservations are unavailable.');\n return reservations.complete(reservationId, parentSessionId);\n },\n );\n const views: ViewDeps = { homeDir: options.homeDir, sessionService };\n const latest = new Map<string, SessionState>();\n const subscriptions = new Map<string, () => void>();\n const busy = new Set<string>();\n const generations = new Map<string, symbol>();\n const newGeneration = (sessionId: string): symbol => {\n const generation = Symbol(sessionId);\n generations.set(sessionId, generation);\n return generation;\n };\n\n /** Republishes a session, skipping a frame that would say nothing new. */\n const publish = (scope: DoomHubSessionScope, force: boolean): void => {\n const previous = latest.get(scope.sessionId);\n const next: SessionState = {\n worktrees: viewsFor(scope, views),\n pending: previous?.pending,\n error: previous?.error,\n errorTarget: previous?.errorTarget,\n };\n if (\n !force &&\n previous !== undefined &&\n sameList(previous.worktrees, next.worktrees) &&\n previous.pending === next.pending &&\n previous.error === next.error &&\n previous.errorTarget === next.errorTarget\n ) {\n return;\n }\n latest.set(scope.sessionId, next);\n host.publish(scope.sessionId, payloadOf(next));\n };\n\n const mark = (\n scope: DoomHubSessionScope,\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n const previous = latest.get(scope.sessionId);\n latest.set(scope.sessionId, {\n worktrees: previous?.worktrees ?? viewsFor(scope, views),\n pending,\n error,\n errorTarget,\n });\n publish(scope, true);\n };\n\n /** Announces a successful mutation to this session's lifecycle subscribers. */\n const publishLifecycle = (scope: DoomHubSessionScope, repositoryRoot: string): void => {\n host.directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, {\n version: 1,\n repositoryRoot,\n });\n };\n\n const run = async (\n scope: DoomHubSessionScope,\n command: GitWorktreesCommand,\n generation: symbol,\n ): Promise<void> => {\n const context = { cwd: scope.cwd, sessionId: scope.sessionId };\n const markCurrent = (\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, pending, error, errorTarget);\n };\n if (command.action === 'create') {\n markCurrent(`creating ${command.branch}…`, undefined, undefined);\n const record = await worktrees.spawn(\n context,\n {\n branch: command.branch,\n ...(command.baseRef === undefined ? {} : { baseRef: command.baseRef }),\n ...(command.reservationId === undefined ? {} : { reservationId: command.reservationId }),\n },\n // Each phase replaces the label, so the panel says what is\n // happening instead of holding one line for the whole wait.\n { onProgress: (label) => markCurrent(label, undefined, undefined) },\n );\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n return;\n }\n markCurrent(`closing ${command.id}…`, undefined, undefined);\n const record = await worktrees.close(context, command.id, command.force ?? false);\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n };\n\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n const state = latest.get(scope.sessionId);\n return state === undefined ? undefined : payloadOf(state);\n },\n sessionAdded(scope) {\n newGeneration(scope.sessionId);\n publish(scope, false);\n const unsubscribe = host.directEvents.subscribe(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, (payload) => {\n if (!isWorktreeLifecycleEvent(payload)) return;\n let sameRepository = false;\n try {\n sameRepository =\n registryFile(scope.cwd, options.homeDir) === registryFile(payload.repositoryRoot, options.homeDir);\n } catch {\n sameRepository = false;\n }\n if (sameRepository) publish(scope, false);\n });\n subscriptions.set(scope.sessionId, unsubscribe);\n },\n sessionRemoved(sessionId) {\n newGeneration(sessionId);\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n latest.delete(sessionId);\n busy.delete(sessionId);\n },\n close() {\n unregisterWorktreeProvisioner?.();\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n latest.clear();\n busy.clear();\n generations.clear();\n },\n };\n receiveCommand = (scope, payload) => {\n const command = parseCommand(payload);\n if (command === undefined) return;\n // One operation per session. A create runs for minutes, and a second\n // click must not start a second worktree behind the first.\n if (busy.has(scope.sessionId)) return;\n const generation = generations.get(scope.sessionId);\n if (generation === undefined) return;\n busy.add(scope.sessionId);\n void run(scope, command, generation)\n .then(() => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, undefined, undefined, undefined);\n })\n .catch((error: unknown) => {\n if (generations.get(scope.sessionId) !== generation) return;\n host.onNotice(`worktree command failed for ${scope.sessionId} (${failureText(error)})`);\n mark(scope, undefined, failureText(error), errorTargetFor(command));\n })\n .finally(() => {\n if (generations.get(scope.sessionId) === generation) busy.delete(scope.sessionId);\n });\n };\n\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport default createWorktreesChannel;\n","import { defineChannel } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git-worktrees.server';\n\nexport default defineChannel(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[0]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGit.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[2]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGitReadme.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[1]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiUseGit.server';\n\nexport default defineResource(contribution);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../_lib/root.server';\n\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.tool);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/route.server';\nimport channelGitWorktrees from '../src/extensions/(backend)/channel/git-worktrees.server';\nimport resourceDoompiGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server';\nimport resourceDoompiGitReadme from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/doompi-git',\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiGit, contextSession), at(resourceDoompiGitReadme, contextSession), at(resourceDoompiUseGit, contextSession)]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.mts","names":[],"sources":["../../generated/server.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../generated/server.ts"],"mappings":";qBAkBa,oDAAK"}
|
|
@@ -429,10 +429,10 @@ var runWorktree_server_default = defineServerTool((context) => context.root.tool
|
|
|
429
429
|
//#endregion
|
|
430
430
|
//#region generated/server.ts
|
|
431
431
|
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
432
|
-
const via = (identity, value) =>
|
|
432
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
433
433
|
...identity,
|
|
434
434
|
...value
|
|
435
|
-
}
|
|
435
|
+
};
|
|
436
436
|
const facet = defineServerPlugin({
|
|
437
437
|
name: "@agimon-ai/doompi-git",
|
|
438
438
|
global: (context) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":["contribution","contribution","contribution","contribution","contribution","contribution","apiRoute","channelGitWorktrees","rootSession","resourceDoompiGit","resourceDoompiGitReadme","resourceDoompiUseGit","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/(backend)/api/_lib/route.server.ts","../../src/extensions/(backend)/api/route.server.ts","../../src/types/webWorktrees.ts","../../src/extensions/(backend)/channel/_lib/git-worktrees.server.ts","../../src/extensions/(backend)/channel/git-worktrees.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.ts","../../generated/server.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport {\n type DoomHeadlessResource,\n type DoomHeadlessTool,\n type DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\nimport { readPackageResource, type DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport { readDoomSessionDelivery } from '@agimon-ai/doompi-session';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../schemas/runWorktreeTool';\nimport { createWorktreeGit } from '../../../../../services/gitCli';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n} from '../../../../../services/runWorktree';\nimport { createWorktreeMessageInbox } from '../../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../../services/worktreeOperations';\n\nfunction progressResult(action: RunWorktreeToolParams['action'], label: string): DoomHeadlessToolResult {\n return { content: [{ type: 'text', text: label }], details: { action } };\n}\n\nexport function createGitSession({ context, host: serverHost }: DoomServerPluginContext) {\n if (serverHost.context.directEvents === undefined)\n throw new Error('Git headless facet requires the session direct event bus.');\n if (serverHost.context.sessionId === undefined) throw new Error('Git headless facet requires a session identity.');\n const sessionId = serverHost.context.sessionId;\n const directEvents = serverHost.context.directEvents;\n const messageInbox = createWorktreeMessageInbox(directEvents, sessionId);\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: serverHost.context.sessionService,\n messageInbox,\n sessionDelivery: () => readDoomSessionDelivery(context),\n });\n const resources: DoomHeadlessResource[] = [\n {\n // The package index is Help-catalog material, not standing instruction, so it\n // only enters the prompt while Help mode is active. Matches the Pi facet,\n // which has always routed this through the Help service.\n when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor', mode: 'help' } },\n name: 'doompi-git',\n kind: 'context',\n read: () => readPackageResource(import.meta.url, 'llms.txt'),\n },\n {\n name: 'doompi-use-git',\n kind: 'skill',\n read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-use-git/SKILL.md'),\n },\n ];\n\n const tool: DoomHeadlessTool<typeof RunWorktreeToolSchema> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n promptSnippet: 'Create and manage Git worktree sessions',\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal, onUpdate, execution) {\n const params = validateParams(parameters) as RunWorktreeToolParams;\n return executeRunWorktreeTool(params, operations, execution, {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) => onUpdate?.(progressResult(params.action, label)),\n });\n },\n };\n return { value: { resources, tool }, onDispose: () => messageInbox.close() };\n}\n\nconst root = defineRoot(createGitSession);\nexport type GitServerScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.server';\n\nexport default defineRoot(contribution);\n","import type { DoomApi, DoomApiContext, DoomApiHandler } from '@agimon-ai/doompi-core/packageApi';\n\nimport { DoomGitExpectedError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../services/worktreeOperations';\n\n/**\n * The worktree surface the cockpit panel calls.\n *\n * Hub-scoped because worktrees are a property of a repository, not of one\n * session: the panel lists and creates them whether or not the session that\n * made them is focused, and a session-scoped API would disappear with it.\n *\n * The panel names a repository by the hub's opaque id and never by path.\n * `resolveRepository` turns that into an admitted root, so a browser cannot\n * point this at a directory the cockpit was never given.\n */\nfunction badRequest(message: string): Response {\n return Response.json({ error: message }, { status: 400 });\n}\n\nfunction failed(error: unknown): Response {\n if (error instanceof DoomGitExpectedError) {\n return Response.json({ error: error.message, code: error.code }, { status: error.retryable ? 503 : 409 });\n }\n // Never the raw message: a git failure can carry a remote URL with a token.\n return Response.json({ error: 'The worktree operation failed.' }, { status: 500 });\n}\n\nexport const api: DoomApi = {\n basePath: 'git',\n start(context: DoomApiContext): DoomApiHandler {\n if (context.directEvents === undefined) throw new Error('Git hub API requires the direct event bus.');\n const directEvents = context.directEvents;\n const publishLifecycle = (sessionId: string, repositoryRoot: string): void => {\n directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, sessionId, { version: 1 as const, repositoryRoot });\n };\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: context.sessionService,\n });\n\n /** The admitted root for a request, or a response explaining why not. */\n const rootOf = (url: URL): string | Response => {\n const repositoryId = url.searchParams.get('repositoryId');\n if (repositoryId === null || repositoryId === '') return badRequest('A repositoryId is required.');\n const root = context.resolveRepository?.(repositoryId);\n if (root === undefined) return badRequest('That repository is not admitted to this cockpit.');\n return root;\n };\n\n return {\n async fetch(request) {\n const url = new URL(request.url);\n const root = rootOf(url);\n if (root instanceof Response) return root;\n // The operations layer works from a cwd, and an admitted repository\n // root is one.\n const callerContext = { cwd: root, sessionId: url.searchParams.get('sessionId') ?? '' };\n const isMutation =\n (request.method === 'POST' && url.pathname === '/worktrees') ||\n (request.method === 'DELETE' && /^\\/worktrees\\/[^/]+$/u.test(url.pathname));\n if (isMutation && callerContext.sessionId === '')\n return badRequest('A sessionId is required for worktree mutations.');\n\n try {\n if (request.method === 'GET' && url.pathname === '/worktrees') {\n return Response.json({ worktrees: await operations.list(callerContext) });\n }\n if (request.method === 'POST' && url.pathname === '/worktrees') {\n const body = (await request.json()) as { branch?: string; baseRef?: string; name?: string };\n if (typeof body.branch !== 'string' || body.branch.trim() === '') {\n return badRequest('A branch is required.');\n }\n const record = await operations.spawn(callerContext, {\n branch: body.branch,\n ...(body.baseRef === undefined ? {} : { baseRef: body.baseRef }),\n ...(body.name === undefined ? {} : { name: body.name }),\n });\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record }, { status: 201 });\n }\n const closing = /^\\/worktrees\\/([^/]+)$/u.exec(url.pathname);\n if (request.method === 'DELETE' && closing) {\n const record = await operations.close(\n callerContext,\n decodeURIComponent(String(closing[1])),\n url.searchParams.get('force') === 'true',\n );\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record });\n }\n return Response.json({ error: 'No such worktree route.' }, { status: 404 });\n } catch (error) {\n context.onNotice(`worktree request failed: ${(error as Error).name}`);\n return failed(error);\n }\n },\n close() {},\n };\n },\n};\n\nexport default api;\n","import { defineRoute } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/route.server';\n\nexport default defineRoute(contribution);\n","/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The worktrees data channel, and the commands the dock sends back through it.\n *\n * The registry is durable state only. Live lifecycle changes arrive through the\n * hub-owned direct event bus, so this channel never polls or claims files.\n */\nimport type {\n DoomHubChannel,\n DoomHubChannelSource,\n DoomHubSessionScope,\n DoomHubSessionService,\n} from '@agimon-ai/doompi-core/hubChannel';\n\nimport { DoomGitExpectedError, HubUnavailableError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { registryFile } from '../../../../services/paths';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT, isWorktreeLifecycleEvent } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations, type WorktreeOperations } from '../../../../services/worktreeOperations';\nimport { createWorktreeRegistry } from '../../../../services/worktreeRegistry';\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../types/webWorktrees';\n\ninterface SessionState {\n worktrees: WorktreeView[];\n pending: string | undefined;\n error: string | undefined;\n errorTarget: WorktreeErrorTarget | undefined;\n}\n\nfunction payloadOf(state: SessionState): Record<string, unknown> {\n return {\n worktrees: state.worktrees,\n ...(state.pending === undefined ? {} : { pending: state.pending }),\n ...(state.error === undefined ? {} : { error: state.error }),\n ...(state.errorTarget === undefined ? {} : { errorTarget: state.errorTarget }),\n };\n}\n\n/** What the channel needs from its surroundings, injected so tests stay off this machine. */\nexport interface WorktreesChannelOptions {\n operations?: WorktreeOperations;\n homeDir?: string;\n}\n\ninterface ViewDeps {\n homeDir: string | undefined;\n sessionService: DoomHubSessionService;\n}\n\n/** Worktrees visible to this session, using the hub's live session table for ownership. */\nfunction viewsFor(scope: DoomHubSessionScope, deps: ViewDeps): WorktreeView[] {\n try {\n return createWorktreeRegistry(registryFile(scope.cwd, deps.homeDir))\n .list()\n .flatMap((record) => {\n const owned = record.parentSessionId === scope.sessionId;\n const unowned = !owned && !deps.sessionService.isLive(record.parentSessionId);\n if (!owned && !unowned) return [];\n return [\n {\n id: record.id,\n branch: record.branch,\n path: record.path,\n sessionId: record.status === 'orphaned' ? null : record.sessionId,\n orphaned: record.status === 'orphaned',\n unowned,\n },\n ];\n });\n } catch {\n return [];\n }\n}\n\nfunction sameList(left: readonly WorktreeView[], right: readonly WorktreeView[]): boolean {\n if (left.length !== right.length) return false;\n return left.every((entry, index) => {\n const other = right[index];\n return (\n other !== undefined &&\n entry.id === other.id &&\n entry.branch === other.branch &&\n entry.sessionId === other.sessionId &&\n entry.orphaned === other.orphaned &&\n entry.unowned === other.unowned\n );\n });\n}\n\nfunction errorTargetFor(command: GitWorktreesCommand): WorktreeErrorTarget {\n return command.action === 'create' ? { action: 'create' } : { action: 'close', id: command.id };\n}\n\n/** A command the page sent, or undefined when the frame was not one. */\nfunction parseCommand(payload: unknown): GitWorktreesCommand | undefined {\n if (typeof payload !== 'object' || payload === null) return undefined;\n const value = payload as Record<string, unknown>;\n if (value.action === 'create') {\n if (typeof value.branch !== 'string' || value.branch.trim() === '') return undefined;\n if (\n value.reservationId !== undefined &&\n (typeof value.reservationId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(value.reservationId))\n )\n return undefined;\n return {\n action: 'create',\n branch: value.branch.trim(),\n ...(typeof value.baseRef === 'string' && value.baseRef.trim() !== '' ? { baseRef: value.baseRef.trim() } : {}),\n ...(typeof value.reservationId === 'string' ? { reservationId: value.reservationId } : {}),\n };\n }\n if (value.action === 'close') {\n if (typeof value.id !== 'string' || value.id === '') return undefined;\n return { action: 'close', id: value.id, ...(value.force === true ? { force: true } : {}) };\n }\n return undefined;\n}\n\n/**\n * What the reader is told when a command fails.\n *\n * An expected failure explains itself. Anything else is summarised, never\n * echoed: a git error can carry a remote URL with a token in it.\n */\nfunction failureText(error: unknown): string {\n return error instanceof DoomGitExpectedError ? error.message : 'The worktree operation failed.';\n}\n\n/** Starts one direct-event subscription per managed session. */\nexport function createWorktreesChannel(options: WorktreesChannelOptions = {}): DoomHubChannel {\n // Assigned by start, because receive is reachable only while the channel is\n // running and the command needs the state the direct event subscriptions keep.\n let receiveCommand: ((scope: DoomHubSessionScope, payload: unknown) => void) | undefined;\n\n return {\n frameType: GIT_WORKTREES_TYPE,\n start(host) {\n const sessionService = host.sessionService;\n if (sessionService === undefined) {\n throw new HubUnavailableError('The cockpit session service is unavailable. Start the cockpit and try again.');\n }\n const worktrees =\n options.operations ??\n createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService,\n });\n const unregisterWorktreeProvisioner = sessionService.registerReservedWorktreeProvisioner?.(\n async ({ reservationId, parentSessionId, signal }) => {\n const parent = host.sessions().find((scope) => scope.sessionId === parentSessionId);\n if (parent === undefined) throw new Error('The conversation parent session is unavailable.');\n const branch = `doompi/conversation-${reservationId.slice(0, 12)}`;\n await worktrees.spawn(\n { cwd: parent.cwd, sessionId: parent.sessionId },\n { branch, name: `conversation ${reservationId.slice(0, 8)}`, reservationId },\n { signal },\n );\n const reservations = sessionService.reservations;\n if (reservations === undefined) throw new Error('Conversation reservations are unavailable.');\n return reservations.complete(reservationId, parentSessionId);\n },\n );\n const views: ViewDeps = { homeDir: options.homeDir, sessionService };\n const latest = new Map<string, SessionState>();\n const subscriptions = new Map<string, () => void>();\n const busy = new Set<string>();\n const generations = new Map<string, symbol>();\n const newGeneration = (sessionId: string): symbol => {\n const generation = Symbol(sessionId);\n generations.set(sessionId, generation);\n return generation;\n };\n\n /** Republishes a session, skipping a frame that would say nothing new. */\n const publish = (scope: DoomHubSessionScope, force: boolean): void => {\n const previous = latest.get(scope.sessionId);\n const next: SessionState = {\n worktrees: viewsFor(scope, views),\n pending: previous?.pending,\n error: previous?.error,\n errorTarget: previous?.errorTarget,\n };\n if (\n !force &&\n previous !== undefined &&\n sameList(previous.worktrees, next.worktrees) &&\n previous.pending === next.pending &&\n previous.error === next.error &&\n previous.errorTarget === next.errorTarget\n ) {\n return;\n }\n latest.set(scope.sessionId, next);\n host.publish(scope.sessionId, payloadOf(next));\n };\n\n const mark = (\n scope: DoomHubSessionScope,\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n const previous = latest.get(scope.sessionId);\n latest.set(scope.sessionId, {\n worktrees: previous?.worktrees ?? viewsFor(scope, views),\n pending,\n error,\n errorTarget,\n });\n publish(scope, true);\n };\n\n /** Announces a successful mutation to this session's lifecycle subscribers. */\n const publishLifecycle = (scope: DoomHubSessionScope, repositoryRoot: string): void => {\n host.directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, {\n version: 1,\n repositoryRoot,\n });\n };\n\n const run = async (\n scope: DoomHubSessionScope,\n command: GitWorktreesCommand,\n generation: symbol,\n ): Promise<void> => {\n const context = { cwd: scope.cwd, sessionId: scope.sessionId };\n const markCurrent = (\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, pending, error, errorTarget);\n };\n if (command.action === 'create') {\n markCurrent(`creating ${command.branch}…`, undefined, undefined);\n const record = await worktrees.spawn(\n context,\n {\n branch: command.branch,\n ...(command.baseRef === undefined ? {} : { baseRef: command.baseRef }),\n ...(command.reservationId === undefined ? {} : { reservationId: command.reservationId }),\n },\n // Each phase replaces the label, so the panel says what is\n // happening instead of holding one line for the whole wait.\n { onProgress: (label) => markCurrent(label, undefined, undefined) },\n );\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n return;\n }\n markCurrent(`closing ${command.id}…`, undefined, undefined);\n const record = await worktrees.close(context, command.id, command.force ?? false);\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n };\n\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n const state = latest.get(scope.sessionId);\n return state === undefined ? undefined : payloadOf(state);\n },\n sessionAdded(scope) {\n newGeneration(scope.sessionId);\n publish(scope, false);\n const unsubscribe = host.directEvents.subscribe(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, (payload) => {\n if (!isWorktreeLifecycleEvent(payload)) return;\n let sameRepository = false;\n try {\n sameRepository =\n registryFile(scope.cwd, options.homeDir) === registryFile(payload.repositoryRoot, options.homeDir);\n } catch {\n sameRepository = false;\n }\n if (sameRepository) publish(scope, false);\n });\n subscriptions.set(scope.sessionId, unsubscribe);\n },\n sessionRemoved(sessionId) {\n newGeneration(sessionId);\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n latest.delete(sessionId);\n busy.delete(sessionId);\n },\n close() {\n unregisterWorktreeProvisioner?.();\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n latest.clear();\n busy.clear();\n generations.clear();\n },\n };\n receiveCommand = (scope, payload) => {\n const command = parseCommand(payload);\n if (command === undefined) return;\n // One operation per session. A create runs for minutes, and a second\n // click must not start a second worktree behind the first.\n if (busy.has(scope.sessionId)) return;\n const generation = generations.get(scope.sessionId);\n if (generation === undefined) return;\n busy.add(scope.sessionId);\n void run(scope, command, generation)\n .then(() => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, undefined, undefined, undefined);\n })\n .catch((error: unknown) => {\n if (generations.get(scope.sessionId) !== generation) return;\n host.onNotice(`worktree command failed for ${scope.sessionId} (${failureText(error)})`);\n mark(scope, undefined, failureText(error), errorTargetFor(command));\n })\n .finally(() => {\n if (generations.get(scope.sessionId) === generation) busy.delete(scope.sessionId);\n });\n };\n\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport default createWorktreesChannel;\n","import { defineChannel } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git-worktrees.server';\n\nexport default defineChannel(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[0]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGit.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[2]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGitReadme.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[1]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiUseGit.server';\n\nexport default defineResource(contribution);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../_lib/root.server';\n\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.tool);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/route.server';\nimport channelGitWorktrees from '../src/extensions/(backend)/channel/git-worktrees.server';\nimport resourceDoompiGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server';\nimport resourceDoompiGitReadme from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T => ({ ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/doompi-git',\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiGit, contextSession), at(resourceDoompiGitReadme, contextSession), at(resourceDoompiUseGit, contextSession)]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["contribution","contribution","contribution","contribution","contribution","contribution","apiRoute","channelGitWorktrees","rootSession","resourceDoompiGit","resourceDoompiGitReadme","resourceDoompiUseGit","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/(backend)/api/_lib/route.server.ts","../../src/extensions/(backend)/api/route.server.ts","../../src/types/webWorktrees.ts","../../src/extensions/(backend)/channel/_lib/git-worktrees.server.ts","../../src/extensions/(backend)/channel/git-worktrees.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.ts","../../generated/server.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport {\n type DoomHeadlessResource,\n type DoomHeadlessTool,\n type DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\nimport { readPackageResource, type DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport { readDoomSessionDelivery } from '@agimon-ai/doompi-session';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../schemas/runWorktreeTool';\nimport { createWorktreeGit } from '../../../../../services/gitCli';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n} from '../../../../../services/runWorktree';\nimport { createWorktreeMessageInbox } from '../../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../../services/worktreeOperations';\n\nfunction progressResult(action: RunWorktreeToolParams['action'], label: string): DoomHeadlessToolResult {\n return { content: [{ type: 'text', text: label }], details: { action } };\n}\n\nexport function createGitSession({ context, host: serverHost }: DoomServerPluginContext) {\n if (serverHost.context.directEvents === undefined)\n throw new Error('Git headless facet requires the session direct event bus.');\n if (serverHost.context.sessionId === undefined) throw new Error('Git headless facet requires a session identity.');\n const sessionId = serverHost.context.sessionId;\n const directEvents = serverHost.context.directEvents;\n const messageInbox = createWorktreeMessageInbox(directEvents, sessionId);\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: serverHost.context.sessionService,\n messageInbox,\n sessionDelivery: () => readDoomSessionDelivery(context),\n });\n const resources: DoomHeadlessResource[] = [\n {\n // The package index is Help-catalog material, not standing instruction, so it\n // only enters the prompt while Help mode is active. Matches the Pi facet,\n // which has always routed this through the Help service.\n when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor', mode: 'help' } },\n name: 'doompi-git',\n kind: 'context',\n read: () => readPackageResource(import.meta.url, 'llms.txt'),\n },\n {\n name: 'doompi-use-git',\n kind: 'skill',\n read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-use-git/SKILL.md'),\n },\n ];\n\n const tool: DoomHeadlessTool<typeof RunWorktreeToolSchema> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n promptSnippet: 'Create and manage Git worktree sessions',\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal, onUpdate, execution) {\n const params = validateParams(parameters) as RunWorktreeToolParams;\n return executeRunWorktreeTool(params, operations, execution, {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) => onUpdate?.(progressResult(params.action, label)),\n });\n },\n };\n return { value: { resources, tool }, onDispose: () => messageInbox.close() };\n}\n\nconst root = defineRoot(createGitSession);\nexport type GitServerScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.server';\n\nexport default defineRoot(contribution);\n","import type { DoomApi, DoomApiContext, DoomApiHandler } from '@agimon-ai/doompi-core/packageApi';\n\nimport { DoomGitExpectedError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../services/worktreeOperations';\n\n/**\n * The worktree surface the cockpit panel calls.\n *\n * Hub-scoped because worktrees are a property of a repository, not of one\n * session: the panel lists and creates them whether or not the session that\n * made them is focused, and a session-scoped API would disappear with it.\n *\n * The panel names a repository by the hub's opaque id and never by path.\n * `resolveRepository` turns that into an admitted root, so a browser cannot\n * point this at a directory the cockpit was never given.\n */\nfunction badRequest(message: string): Response {\n return Response.json({ error: message }, { status: 400 });\n}\n\nfunction failed(error: unknown): Response {\n if (error instanceof DoomGitExpectedError) {\n return Response.json({ error: error.message, code: error.code }, { status: error.retryable ? 503 : 409 });\n }\n // Never the raw message: a git failure can carry a remote URL with a token.\n return Response.json({ error: 'The worktree operation failed.' }, { status: 500 });\n}\n\nexport const api: DoomApi = {\n basePath: 'git',\n start(context: DoomApiContext): DoomApiHandler {\n if (context.directEvents === undefined) throw new Error('Git hub API requires the direct event bus.');\n const directEvents = context.directEvents;\n const publishLifecycle = (sessionId: string, repositoryRoot: string): void => {\n directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, sessionId, { version: 1 as const, repositoryRoot });\n };\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: context.sessionService,\n });\n\n /** The admitted root for a request, or a response explaining why not. */\n const rootOf = (url: URL): string | Response => {\n const repositoryId = url.searchParams.get('repositoryId');\n if (repositoryId === null || repositoryId === '') return badRequest('A repositoryId is required.');\n const root = context.resolveRepository?.(repositoryId);\n if (root === undefined) return badRequest('That repository is not admitted to this cockpit.');\n return root;\n };\n\n return {\n async fetch(request) {\n const url = new URL(request.url);\n const root = rootOf(url);\n if (root instanceof Response) return root;\n // The operations layer works from a cwd, and an admitted repository\n // root is one.\n const callerContext = { cwd: root, sessionId: url.searchParams.get('sessionId') ?? '' };\n const isMutation =\n (request.method === 'POST' && url.pathname === '/worktrees') ||\n (request.method === 'DELETE' && /^\\/worktrees\\/[^/]+$/u.test(url.pathname));\n if (isMutation && callerContext.sessionId === '')\n return badRequest('A sessionId is required for worktree mutations.');\n\n try {\n if (request.method === 'GET' && url.pathname === '/worktrees') {\n return Response.json({ worktrees: await operations.list(callerContext) });\n }\n if (request.method === 'POST' && url.pathname === '/worktrees') {\n const body = (await request.json()) as { branch?: string; baseRef?: string; name?: string };\n if (typeof body.branch !== 'string' || body.branch.trim() === '') {\n return badRequest('A branch is required.');\n }\n const record = await operations.spawn(callerContext, {\n branch: body.branch,\n ...(body.baseRef === undefined ? {} : { baseRef: body.baseRef }),\n ...(body.name === undefined ? {} : { name: body.name }),\n });\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record }, { status: 201 });\n }\n const closing = /^\\/worktrees\\/([^/]+)$/u.exec(url.pathname);\n if (request.method === 'DELETE' && closing) {\n const record = await operations.close(\n callerContext,\n decodeURIComponent(String(closing[1])),\n url.searchParams.get('force') === 'true',\n );\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record });\n }\n return Response.json({ error: 'No such worktree route.' }, { status: 404 });\n } catch (error) {\n context.onNotice(`worktree request failed: ${(error as Error).name}`);\n return failed(error);\n }\n },\n close() {},\n };\n },\n};\n\nexport default api;\n","import { defineRoute } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/route.server';\n\nexport default defineRoute(contribution);\n","/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The worktrees data channel, and the commands the dock sends back through it.\n *\n * The registry is durable state only. Live lifecycle changes arrive through the\n * hub-owned direct event bus, so this channel never polls or claims files.\n */\nimport type {\n DoomHubChannel,\n DoomHubChannelSource,\n DoomHubSessionScope,\n DoomHubSessionService,\n} from '@agimon-ai/doompi-core/hubChannel';\n\nimport { DoomGitExpectedError, HubUnavailableError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { registryFile } from '../../../../services/paths';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT, isWorktreeLifecycleEvent } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations, type WorktreeOperations } from '../../../../services/worktreeOperations';\nimport { createWorktreeRegistry } from '../../../../services/worktreeRegistry';\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../types/webWorktrees';\n\ninterface SessionState {\n worktrees: WorktreeView[];\n pending: string | undefined;\n error: string | undefined;\n errorTarget: WorktreeErrorTarget | undefined;\n}\n\nfunction payloadOf(state: SessionState): Record<string, unknown> {\n return {\n worktrees: state.worktrees,\n ...(state.pending === undefined ? {} : { pending: state.pending }),\n ...(state.error === undefined ? {} : { error: state.error }),\n ...(state.errorTarget === undefined ? {} : { errorTarget: state.errorTarget }),\n };\n}\n\n/** What the channel needs from its surroundings, injected so tests stay off this machine. */\nexport interface WorktreesChannelOptions {\n operations?: WorktreeOperations;\n homeDir?: string;\n}\n\ninterface ViewDeps {\n homeDir: string | undefined;\n sessionService: DoomHubSessionService;\n}\n\n/** Worktrees visible to this session, using the hub's live session table for ownership. */\nfunction viewsFor(scope: DoomHubSessionScope, deps: ViewDeps): WorktreeView[] {\n try {\n return createWorktreeRegistry(registryFile(scope.cwd, deps.homeDir))\n .list()\n .flatMap((record) => {\n const owned = record.parentSessionId === scope.sessionId;\n const unowned = !owned && !deps.sessionService.isLive(record.parentSessionId);\n if (!owned && !unowned) return [];\n return [\n {\n id: record.id,\n branch: record.branch,\n path: record.path,\n sessionId: record.status === 'orphaned' ? null : record.sessionId,\n orphaned: record.status === 'orphaned',\n unowned,\n },\n ];\n });\n } catch {\n return [];\n }\n}\n\nfunction sameList(left: readonly WorktreeView[], right: readonly WorktreeView[]): boolean {\n if (left.length !== right.length) return false;\n return left.every((entry, index) => {\n const other = right[index];\n return (\n other !== undefined &&\n entry.id === other.id &&\n entry.branch === other.branch &&\n entry.sessionId === other.sessionId &&\n entry.orphaned === other.orphaned &&\n entry.unowned === other.unowned\n );\n });\n}\n\nfunction errorTargetFor(command: GitWorktreesCommand): WorktreeErrorTarget {\n return command.action === 'create' ? { action: 'create' } : { action: 'close', id: command.id };\n}\n\n/** A command the page sent, or undefined when the frame was not one. */\nfunction parseCommand(payload: unknown): GitWorktreesCommand | undefined {\n if (typeof payload !== 'object' || payload === null) return undefined;\n const value = payload as Record<string, unknown>;\n if (value.action === 'create') {\n if (typeof value.branch !== 'string' || value.branch.trim() === '') return undefined;\n if (\n value.reservationId !== undefined &&\n (typeof value.reservationId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(value.reservationId))\n )\n return undefined;\n return {\n action: 'create',\n branch: value.branch.trim(),\n ...(typeof value.baseRef === 'string' && value.baseRef.trim() !== '' ? { baseRef: value.baseRef.trim() } : {}),\n ...(typeof value.reservationId === 'string' ? { reservationId: value.reservationId } : {}),\n };\n }\n if (value.action === 'close') {\n if (typeof value.id !== 'string' || value.id === '') return undefined;\n return { action: 'close', id: value.id, ...(value.force === true ? { force: true } : {}) };\n }\n return undefined;\n}\n\n/**\n * What the reader is told when a command fails.\n *\n * An expected failure explains itself. Anything else is summarised, never\n * echoed: a git error can carry a remote URL with a token in it.\n */\nfunction failureText(error: unknown): string {\n return error instanceof DoomGitExpectedError ? error.message : 'The worktree operation failed.';\n}\n\n/** Starts one direct-event subscription per managed session. */\nexport function createWorktreesChannel(options: WorktreesChannelOptions = {}): DoomHubChannel {\n // Assigned by start, because receive is reachable only while the channel is\n // running and the command needs the state the direct event subscriptions keep.\n let receiveCommand: ((scope: DoomHubSessionScope, payload: unknown) => void) | undefined;\n\n return {\n frameType: GIT_WORKTREES_TYPE,\n start(host) {\n const sessionService = host.sessionService;\n if (sessionService === undefined) {\n throw new HubUnavailableError('The cockpit session service is unavailable. Start the cockpit and try again.');\n }\n const worktrees =\n options.operations ??\n createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService,\n });\n const unregisterWorktreeProvisioner = sessionService.registerReservedWorktreeProvisioner?.(\n async ({ reservationId, parentSessionId, signal }) => {\n const parent = host.sessions().find((scope) => scope.sessionId === parentSessionId);\n if (parent === undefined) throw new Error('The conversation parent session is unavailable.');\n const branch = `doompi/conversation-${reservationId.slice(0, 12)}`;\n await worktrees.spawn(\n { cwd: parent.cwd, sessionId: parent.sessionId },\n { branch, name: `conversation ${reservationId.slice(0, 8)}`, reservationId },\n { signal },\n );\n const reservations = sessionService.reservations;\n if (reservations === undefined) throw new Error('Conversation reservations are unavailable.');\n return reservations.complete(reservationId, parentSessionId);\n },\n );\n const views: ViewDeps = { homeDir: options.homeDir, sessionService };\n const latest = new Map<string, SessionState>();\n const subscriptions = new Map<string, () => void>();\n const busy = new Set<string>();\n const generations = new Map<string, symbol>();\n const newGeneration = (sessionId: string): symbol => {\n const generation = Symbol(sessionId);\n generations.set(sessionId, generation);\n return generation;\n };\n\n /** Republishes a session, skipping a frame that would say nothing new. */\n const publish = (scope: DoomHubSessionScope, force: boolean): void => {\n const previous = latest.get(scope.sessionId);\n const next: SessionState = {\n worktrees: viewsFor(scope, views),\n pending: previous?.pending,\n error: previous?.error,\n errorTarget: previous?.errorTarget,\n };\n if (\n !force &&\n previous !== undefined &&\n sameList(previous.worktrees, next.worktrees) &&\n previous.pending === next.pending &&\n previous.error === next.error &&\n previous.errorTarget === next.errorTarget\n ) {\n return;\n }\n latest.set(scope.sessionId, next);\n host.publish(scope.sessionId, payloadOf(next));\n };\n\n const mark = (\n scope: DoomHubSessionScope,\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n const previous = latest.get(scope.sessionId);\n latest.set(scope.sessionId, {\n worktrees: previous?.worktrees ?? viewsFor(scope, views),\n pending,\n error,\n errorTarget,\n });\n publish(scope, true);\n };\n\n /** Announces a successful mutation to this session's lifecycle subscribers. */\n const publishLifecycle = (scope: DoomHubSessionScope, repositoryRoot: string): void => {\n host.directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, {\n version: 1,\n repositoryRoot,\n });\n };\n\n const run = async (\n scope: DoomHubSessionScope,\n command: GitWorktreesCommand,\n generation: symbol,\n ): Promise<void> => {\n const context = { cwd: scope.cwd, sessionId: scope.sessionId };\n const markCurrent = (\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, pending, error, errorTarget);\n };\n if (command.action === 'create') {\n markCurrent(`creating ${command.branch}…`, undefined, undefined);\n const record = await worktrees.spawn(\n context,\n {\n branch: command.branch,\n ...(command.baseRef === undefined ? {} : { baseRef: command.baseRef }),\n ...(command.reservationId === undefined ? {} : { reservationId: command.reservationId }),\n },\n // Each phase replaces the label, so the panel says what is\n // happening instead of holding one line for the whole wait.\n { onProgress: (label) => markCurrent(label, undefined, undefined) },\n );\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n return;\n }\n markCurrent(`closing ${command.id}…`, undefined, undefined);\n const record = await worktrees.close(context, command.id, command.force ?? false);\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n };\n\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n const state = latest.get(scope.sessionId);\n return state === undefined ? undefined : payloadOf(state);\n },\n sessionAdded(scope) {\n newGeneration(scope.sessionId);\n publish(scope, false);\n const unsubscribe = host.directEvents.subscribe(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, (payload) => {\n if (!isWorktreeLifecycleEvent(payload)) return;\n let sameRepository = false;\n try {\n sameRepository =\n registryFile(scope.cwd, options.homeDir) === registryFile(payload.repositoryRoot, options.homeDir);\n } catch {\n sameRepository = false;\n }\n if (sameRepository) publish(scope, false);\n });\n subscriptions.set(scope.sessionId, unsubscribe);\n },\n sessionRemoved(sessionId) {\n newGeneration(sessionId);\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n latest.delete(sessionId);\n busy.delete(sessionId);\n },\n close() {\n unregisterWorktreeProvisioner?.();\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n latest.clear();\n busy.clear();\n generations.clear();\n },\n };\n receiveCommand = (scope, payload) => {\n const command = parseCommand(payload);\n if (command === undefined) return;\n // One operation per session. A create runs for minutes, and a second\n // click must not start a second worktree behind the first.\n if (busy.has(scope.sessionId)) return;\n const generation = generations.get(scope.sessionId);\n if (generation === undefined) return;\n busy.add(scope.sessionId);\n void run(scope, command, generation)\n .then(() => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, undefined, undefined, undefined);\n })\n .catch((error: unknown) => {\n if (generations.get(scope.sessionId) !== generation) return;\n host.onNotice(`worktree command failed for ${scope.sessionId} (${failureText(error)})`);\n mark(scope, undefined, failureText(error), errorTargetFor(command));\n })\n .finally(() => {\n if (generations.get(scope.sessionId) === generation) busy.delete(scope.sessionId);\n });\n };\n\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport default createWorktreesChannel;\n","import { defineChannel } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git-worktrees.server';\n\nexport default defineChannel(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[0]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGit.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[2]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGitReadme.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[1]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiUseGit.server';\n\nexport default defineResource(contribution);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../_lib/root.server';\n\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.tool);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/route.server';\nimport channelGitWorktrees from '../src/extensions/(backend)/channel/git-worktrees.server';\nimport resourceDoompiGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server';\nimport resourceDoompiGitReadme from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/doompi-git',\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiGit, contextSession), at(resourceDoompiGitReadme, contextSession), at(resourceDoompiUseGit, contextSession)]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}
|
package/dist/extensions/web.mjs
CHANGED
|
@@ -537,10 +537,10 @@ function RunWorktreeToolMessage({ args, output, running, isError }) {
|
|
|
537
537
|
var runWorktree_web_default = defineToolRenderer({ message: RunWorktreeToolMessage });
|
|
538
538
|
//#endregion
|
|
539
539
|
//#region generated/web.ts
|
|
540
|
-
const via = (identity, value) =>
|
|
540
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
541
541
|
...identity,
|
|
542
542
|
...value
|
|
543
|
-
}
|
|
543
|
+
};
|
|
544
544
|
const webPlugin = defineWebPlugin({
|
|
545
545
|
id: "git",
|
|
546
546
|
session: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.mjs","names":["contribution","activityGroupGit","channelGitWorktrees","fillWorktree","fillWorktreeCreate","fillWorktrees","lifecycleStart","toolRunWorktree"],"sources":["../../src/types/webWorktrees.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/worktreesActivityStore.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/WorktreesPanel.tsx","../../src/extensions/workspaces/sessions/(frontend)/activity-group/git.web.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/gitWorktrees.web.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreeCreateDialog.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktree.session-menu.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/WorktreeCreate.overlay.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreesActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/_lib/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/RunWorktreeToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/runWorktree.web.tsx","../../generated/web.ts"],"sourcesContent":["/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The dock's view of this session's worktrees, and the commands it sends.\n *\n * DESIGN PATTERNS:\n * - Session-scoped store fed by one hub channel. The hub is authoritative; the\n * page never reads a registry and never guesses.\n * - Actions are channel frames, not prompts. The hub half owns the tool's\n * operations, so the panel names the work and the hub performs it; a\n * worktree made from the dock is the same object the tool makes, without\n * spending a turn of the conversation to ask for it.\n * - The sender lives in a store rather than a module variable, because a web\n * plugin keeps no mutable module state and the page may reconnect.\n *\n * AVOID:\n * - Calling the hub package API from here. A dock slot gets no sealed request\n * transport, and raw fetch breaks the remote cockpit.\n * - `sendSessionFrame` for a command. It envelopes the frame as a session\n * command bound for the agent, which never reaches a channel's `receive`.\n */\nimport { defineGlobalStore, defineSessionStore, type WebPluginRuntime } from '@agimon-ai/doompi-core/web';\n\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../../types/webWorktrees';\n\nexport interface WorktreesSession {\n /** The worktrees the hub last reported for this session's repository. */\n worktrees: WorktreeView[];\n /** Label of the operation the hub is running for this session. */\n pending: string | undefined;\n /** The last failure the hub reported, shown until the next command. */\n error: string | undefined;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n\nexport const worktreeActivity = defineSessionStore<WorktreesSession>({\n worktrees: [],\n pending: undefined,\n error: undefined,\n errorTarget: undefined,\n});\n\n/** Captures the clicked card, so a focus change cannot retarget an open dialog. */\nexport const worktreeCreateDialog = defineGlobalStore<{ sessionId: string; reservationId?: string } | null>(null);\n/**\n * The page's hub socket sender, held for as long as the plugin runs.\n *\n * Undefined before `startWorktreeRuntime` and after it disposes; a command\n * sent in that window is dropped rather than queued, because a queue would\n * replay a worktree create against a socket that has since changed sessions.\n */\nconst worktreeSender = defineGlobalStore<WebPluginRuntime['sendHubFrame'] | undefined>(undefined);\n\n/** Binds the page's hub socket. The plugin host calls this once per page. */\nexport function startWorktreeRuntime(runtime: WebPluginRuntime): () => void {\n // Wrapped rather than referenced: an unbound method would lose the runtime\n // it belongs to the moment the store hands it back.\n const send = (frame: Record<string, unknown>): void => {\n runtime.sendHubFrame(frame);\n };\n worktreeSender.update(() => send);\n return () => {\n worktreeSender.update((current) => (current === send ? undefined : current));\n worktreeCreateDialog.update(() => null);\n };\n}\n\n/**\n * Whether this session has worktree work in flight.\n *\n * A standing worktree is state, not work: it sits there until someone closes\n * it, so counting it would leave the session reading as busy forever, with a\n * \"background work is still running\" notice under a conversation where\n * nothing is running. Only a create or close actually in progress counts.\n *\n * The group stays visible either way. Declaring an active source at all is\n * what keeps it in the dock; this answers how it is drawn, not whether it is\n * there.\n */\nexport const worktreeActivitySource = {\n subscribe(listener: () => void) {\n const subscription = worktreeActivity.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId: string | null) {\n return worktreeActivity.select(worktreeActivity.store.state, sessionId).pending !== undefined;\n },\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction optionalText(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction optionalErrorTarget(value: unknown): WorktreeErrorTarget | undefined {\n if (!isRecord(value)) return undefined;\n if (value.action === 'create') return { action: 'create' };\n if (value.action === 'close' && typeof value.id === 'string' && value.id !== '') {\n return { action: 'close', id: value.id };\n }\n return undefined;\n}\n\n/** The plugin's session data channel: 'git_worktrees' payloads into the store. */\nexport const worktreesChannel = worktreeActivity.channel<WorktreesSession>({\n channel: GIT_WORKTREES_TYPE,\n parse(input) {\n if (!isRecord(input) || !Array.isArray(input.worktrees)) return null;\n return {\n worktrees: input.worktrees.filter(isRecord) as unknown as WorktreeView[],\n pending: optionalText(input.pending),\n error: optionalText(input.error),\n errorTarget: optionalErrorTarget(input.errorTarget),\n };\n },\n reduce(_current, next) {\n return next;\n },\n});\n\n/** Sends one command to the session's worktrees channel. */\nfunction command(sessionId: string, payload: GitWorktreesCommand): void {\n worktreeSender.store.state?.({ type: GIT_WORKTREES_TYPE, sessionId, payload });\n}\n\n/** Asks the hub for a worktree. The hub answers on the same channel. */\nexport function requestWorktreeCreate(\n sessionId: string,\n branch: string,\n baseRef: string,\n reservationId?: string,\n): void {\n const trimmedBase = baseRef.trim();\n command(sessionId, {\n action: 'create',\n branch: branch.trim(),\n ...(trimmedBase === '' ? {} : { baseRef: trimmedBase }),\n ...(reservationId === undefined ? {} : { reservationId }),\n });\n}\n\n/** Asks the hub to close one worktree. Refusal on a dirty tree stays the hub's call. */\nexport function requestWorktreeClose(sessionId: string, id: string): void {\n command(sessionId, { action: 'close', id });\n}\n","import type { TransientTab, WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\n/**\n * The '# git' group's tab: this session's worktrees, and the form that makes one.\n *\n * DESIGN PATTERNS:\n * - Lives in the activity dock, opened by the group's name. A worktree is work\n * in progress belonging to the session that started it, so it sits beside\n * agents, runners and workflows rather than in a settings screen.\n * - Header, form, then cards, the same rhythm the runners and workflows panels\n * use. A worktree row is a card because it carries three facts and two\n * actions, which a single line cannot hold without becoming a puzzle.\n * - Local form state is never reset by a data refresh. Direct lifecycle events\n * update the list without discarding a half-typed branch name.\n * - Acts through the plugin's own hub channel, so a worktree made here and one\n * made by the tool take exactly the same path.\n * - Creating waits on the cockpit starting a session, so the hub reports each\n * phase on that channel and the header shows it turning. A button that looks\n * idle for two minutes reads as broken.\n *\n * AVOID:\n * - Deriving form state from refreshed store data instead of the user's input.\n * - Colour classes outside the token set. `doom-error`, `doom-line` and\n * `doom-bright` are not tokens: they compile to nothing and the row silently\n * loses its border.\n */\nimport { Button, Dot, EmptyState, Input, Spinner, StatusBadge } from '@agimon-ai/doompi-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useState } from 'react';\n\nimport type { WorktreeView } from '../../../../../types/webWorktrees';\nimport { requestWorktreeClose, requestWorktreeCreate, worktreeActivity } from '../_lib/worktreesActivityStore';\n\nconst WORKTREES_TAB_ID = 'git-worktrees';\n\nexport function worktreesTab(): TransientTab {\n return { id: WORKTREES_TAB_ID, label: 'worktrees', panel: WorktreesPanel };\n}\n\nexport function WorktreesPanel({ sessionId, sessionReservationId }: WebPluginSlotProps) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, sessionId));\n const [branch, setBranch] = useState('');\n const [baseRef, setBaseRef] = useState('');\n\n const busy = session.pending !== undefined;\n const canCreate = sessionId !== null && branch.trim() !== '' && !busy;\n const createError = session.errorTarget?.action === 'create' ? session.error : undefined;\n const closeErrorId = session.errorTarget?.action === 'close' ? session.errorTarget.id : undefined;\n const panelError =\n session.error !== undefined &&\n (session.errorTarget === undefined ||\n (closeErrorId !== undefined && !session.worktrees.some((worktree) => worktree.id === closeErrorId)));\n\n const create = (): void => {\n if (sessionId === null || !canCreate) return;\n requestWorktreeCreate(sessionId, branch, baseRef, sessionReservationId);\n // A reserved setup must be retried with the same branch after a partial failure.\n if (sessionReservationId === undefined) {\n setBranch('');\n setBaseRef('');\n }\n };\n\n return (\n <div data-testid=\"git-worktrees-panel\" className=\"flex min-h-0 flex-1 flex-col overflow-auto\">\n <div className=\"flex min-h-11 shrink-0 items-center gap-2.5 border-b border-doom-border-soft px-3 sm:px-[26px]\">\n <span className=\"text-sm font-bold text-doom-hi\">worktrees</span>\n <span data-testid=\"git-worktrees-count\" className=\"text-xs text-doom-faint\">\n {session.worktrees.length === 0 ? 'none yet' : `${String(session.worktrees.length)} open`}\n </span>\n <span className=\"min-w-0 flex-1\" />\n {session.pending === undefined ? null : (\n <span data-testid=\"git-worktree-pending\" className=\"flex min-w-0 items-center gap-1.5\">\n <Spinner className=\"h-3 w-3 shrink-0 text-doom-faint\" label={session.pending} />\n <span className=\"min-w-0 truncate text-xs text-doom-dim\">{session.pending}</span>\n </span>\n )}\n </div>\n\n <div className=\"flex shrink-0 flex-col gap-1.5 border-b border-doom-border-soft px-3 py-2.5 sm:px-[26px]\">\n <div className=\"flex items-center gap-2\">\n <Input\n data-testid=\"git-worktree-branch\"\n aria-label=\"Branch\"\n size=\"sm\"\n className=\"min-w-0 flex-1\"\n placeholder=\"wt/fix-auth\"\n value={branch}\n onChange={(event) => setBranch(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') create();\n }}\n />\n <Input\n data-testid=\"git-worktree-base\"\n aria-label=\"Base ref\"\n size=\"sm\"\n placeholder=\"base (current)\"\n value={baseRef}\n onChange={(event) => setBaseRef(event.target.value)}\n className=\"w-32 shrink-0\"\n />\n <Button data-testid=\"git-worktree-create\" size=\"sm\" disabled={!canCreate} onClick={create}>\n Create\n </Button>\n </div>\n {createError === undefined ? (\n <p className=\"text-2xs text-doom-faint\">\n Creates the worktree outside the repository and starts a session nested under this one.\n </p>\n ) : (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"text-2xs text-doom-red\">\n {createError}\n </p>\n )}\n </div>\n\n {panelError ? (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"px-3 pt-2 text-2xs text-doom-red sm:px-[26px]\">\n {session.error}\n </p>\n ) : null}\n\n {session.worktrees.length === 0 ? (\n <EmptyState\n data-testid=\"git-worktrees-empty\"\n className=\"px-4 py-8\"\n title=\"no worktrees yet\"\n description=\"a worktree is its own checkout on its own branch, with its own session nested under this one.\"\n />\n ) : (\n <ul data-testid=\"git-worktrees-list\" className=\"flex flex-col gap-2.5 px-3 py-3 sm:px-[26px]\">\n {session.worktrees.map((worktree: WorktreeView) => (\n <WorktreeCard\n key={worktree.id}\n worktree={worktree}\n sessionId={sessionId}\n busy={busy}\n error={closeErrorId === worktree.id ? session.error : undefined}\n />\n ))}\n </ul>\n )}\n </div>\n );\n}\n\n/** One worktree: what it is, where it is, and the one thing you can do to it. */\nfunction WorktreeCard({\n worktree,\n sessionId,\n busy,\n error,\n}: {\n worktree: WorktreeView;\n busy: boolean;\n error?: string;\n} & Pick<WebPluginSlotProps, 'sessionId'>) {\n return (\n <li\n data-testid={`git-worktree-${worktree.id}`}\n className=\"flex min-w-0 flex-col gap-1.5 rounded-md border border-doom-border-soft bg-doom-panel p-2.5\"\n >\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <Dot tone={worktree.orphaned ? 'red' : worktree.sessionId === null ? 'muted' : 'blue'} />\n <span className=\"min-w-0 flex-1 truncate text-sm font-bold text-doom-hi\">{worktree.branch}</span>\n {worktree.orphaned ? (\n <StatusBadge tone=\"error\" size=\"xs\">\n orphaned\n </StatusBadge>\n ) : null}\n {worktree.unowned ? (\n <StatusBadge tone=\"info\" size=\"xs\">\n unowned\n </StatusBadge>\n ) : null}\n </div>\n\n <span className=\"min-w-0 truncate text-2xs text-doom-faint\">{worktree.path}</span>\n\n <div className=\"flex items-center gap-1.5 pt-0.5\">\n <span className=\"min-w-0 flex-1\" />\n {sessionId === null ? null : (\n <Button\n variant=\"danger-outline\"\n size=\"xs\"\n disabled={busy}\n data-testid={`git-worktree-close-${worktree.id}`}\n className=\"px-2 text-2xs font-bold\"\n onClick={() => requestWorktreeClose(sessionId, worktree.id)}\n >\n close\n </Button>\n )}\n </div>\n {error === undefined ? null : (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"text-2xs text-doom-red\">\n {error}\n </p>\n )}\n </li>\n );\n}\n","import { defineActivityGroup } from '@agimon-ai/doompi-core/web';\n\nimport { worktreesTab } from '../_components/WorktreesPanel';\nimport { worktreeActivitySource } from '../_lib/worktreesActivityStore';\n\nexport default defineActivityGroup({\n keys: 'g w',\n activeSource: worktreeActivitySource,\n marksBackgroundWork: false,\n transientTab: worktreesTab,\n order: 30,\n});\n","import { defineChannelFile } from '@agimon-ai/doompi-core/web';\n\nimport { worktreesChannel } from '../_lib/worktreesActivityStore';\n\nexport default defineChannelFile(worktreesChannel);\n","import type { WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\nimport {\n Dialog,\n DialogBody,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DropdownMenuItem,\n} from '@agimon-ai/doompi-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useEffect } from 'react';\n\nimport { WorktreesPanel } from '../../_components/WorktreesPanel';\nimport { worktreeCreateDialog, worktreesChannel } from '../../_lib/worktreesActivityStore';\n\nexport function WorktreeSessionMenu({ sessionId, sessionReservationId }: WebPluginSlotProps) {\n return (\n <DropdownMenuItem\n disabled={sessionId === null}\n data-testid={`session-worktree-${sessionReservationId ?? sessionId}`}\n onSelect={() => {\n if (sessionId !== null)\n worktreeCreateDialog.update(() => ({\n sessionId,\n ...(sessionReservationId === undefined ? {} : { reservationId: sessionReservationId }),\n }));\n }}\n >\n create worktree session…\n </DropdownMenuItem>\n );\n}\n\nexport function WorktreeCreateOverlay(props: WebPluginSlotProps) {\n const target = useStore(worktreeCreateDialog.store);\n const { holdSessionChannels } = props;\n useEffect(() => {\n if (target === null) return;\n return holdSessionChannels?.(target.sessionId, (frame) => {\n if (frame.type !== worktreesChannel.channel) return;\n const payload = worktreesChannel.parse(frame.payload);\n if (payload !== null) worktreesChannel.apply(target.sessionId, payload);\n });\n }, [target, holdSessionChannels]);\n if (target === null) return null;\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open) worktreeCreateDialog.update(() => null);\n }}\n >\n <DialogContent width=\"lg\" data-testid=\"session-worktree-dialog\">\n <DialogHeader>\n <DialogTitle>create worktree session</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <DialogDescription>\n Creates a separate checkout and a new session. Existing sessions stay in their current directories.\n </DialogDescription>\n <WorktreesPanel\n {...props}\n key={`${target.sessionId}:${target.reservationId ?? ''}`}\n sessionId={target.sessionId}\n sessionReservationId={target.reservationId}\n />\n </DialogBody>\n </DialogContent>\n </Dialog>\n );\n}\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { WorktreeSessionMenu } from './_components/WorktreeCreateDialog';\n\nexport default defineFill({ component: WorktreeSessionMenu });\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { WorktreeCreateOverlay } from './_components/WorktreeCreateDialog';\n\nexport default defineFill({ component: WorktreeCreateOverlay });\n","import type { WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\n/**\n * The '# git' group's body in the activity dock.\n *\n * DESIGN PATTERNS:\n * - One line per worktree, the same rule the runners rail follows: enough to\n * notice it, not enough to work with it. The group's own name opens the tab\n * that has room.\n * - Idle still shows the launcher. A repository with no worktrees is the state\n * where someone most wants to make one.\n *\n * AVOID:\n * - Doing work here. This section reports and launches; the panel and the tool\n * own everything else.\n */\nimport { Button, Dot, Spinner, StatusBadge } from '@agimon-ai/doompi-web-components';\nimport { useStore } from '@tanstack/react-store';\n\nimport type { WorktreeView } from '../../../../../../types/webWorktrees';\nimport { worktreesTab } from '../../_components/WorktreesPanel';\nimport { worktreeActivity } from '../../_lib/worktreesActivityStore';\n\nexport function WorktreesActivitySection({ sessionId, openTransientTab }: WebPluginSlotProps) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, sessionId));\n\n if (session.worktrees.length === 0 && session.pending === undefined) {\n return (\n <div className=\"flex items-center gap-2 px-1\">\n <p data-testid=\"activity-summary-git\" className=\"px-1 text-xs text-doom-faint\">\n idle\n </p>\n {sessionId === null ? null : (\n <Button\n variant=\"link\"\n size=\"xs\"\n data-testid=\"activity-git-create\"\n className=\"px-0\"\n onClick={() => openTransientTab(worktreesTab())}\n >\n create a worktree\n </Button>\n )}\n </div>\n );\n }\n\n return (\n <div data-testid=\"activity-git-worktrees\" className=\"flex flex-col gap-0.5\">\n {session.pending === undefined ? null : (\n <span className=\"flex min-w-0 items-center gap-1.5 px-1\">\n <Spinner className=\"h-3 w-3 shrink-0 text-doom-faint\" label={session.pending} />\n <span className=\"min-w-0 truncate text-xs text-doom-dim\">{session.pending}</span>\n </span>\n )}\n {session.worktrees.map((worktree: WorktreeView) => (\n <Button\n key={worktree.id}\n variant=\"ghost\"\n size=\"card\"\n data-testid={`activity-git-worktree-${worktree.id}`}\n className=\"min-w-0 gap-1.5 px-1\"\n onClick={() => openTransientTab(worktreesTab())}\n >\n <span className=\"flex w-full min-w-0 items-center gap-1.5\">\n <Dot tone={worktree.orphaned ? 'red' : worktree.sessionId === null ? 'muted' : 'blue'} />\n <span className=\"min-w-0 flex-1 truncate text-left text-xs font-bold text-doom-hi\">{worktree.branch}</span>\n {worktree.orphaned ? (\n <StatusBadge tone=\"error\" size=\"xs\">\n orphaned\n </StatusBadge>\n ) : null}\n {worktree.unowned ? (\n <StatusBadge tone=\"info\" size=\"xs\">\n unowned\n </StatusBadge>\n ) : null}\n </span>\n </Button>\n ))}\n </div>\n );\n}\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { WorktreesActivitySection } from './_components/WorktreesActivitySection';\n\nexport default defineFill({ component: WorktreesActivitySection });\n","import { startWorktreeRuntime } from '../../_lib/worktreesActivityStore';\n\nexport default startWorktreeRuntime;\n","import { defineWebLifecycle } from '@agimon-ai/doompi-core/web';\n\nimport contribution from './_lib/start.web';\n\nexport default defineWebLifecycle(contribution);\n","import type { ToolMessageRenderProps } from '@agimon-ai/doompi-core/web';\nimport { MessageItem, MessageItemBody, MessageItemHeader, toolTone } from '@agimon-ai/doompi-web-components';\n\nconst ACTION_LABEL: Readonly<Record<string, string>> = {\n spawn_worktree: 'Create worktree',\n close_worktree: 'Close worktree',\n list: 'List worktrees',\n status: 'Worktree status',\n merge: 'Merge worktree',\n prune: 'Prune worktrees',\n send: 'Message worktree',\n messages: 'Read worktree messages',\n};\n\n/**\n * The timeline item for `run_worktree`.\n *\n * DESIGN PATTERNS:\n * - Built on MessageItem, like every other tool renderer in the cockpit. That\n * is what gives it the shared collapse toggle and the RUNNING/OK/ERROR badge\n * rather than a hand-rolled ellipsis that never resolves.\n * - The action and its subject go in the heading because that is what a reader\n * scanning a transcript needs: \"close_worktree a1b2c3d4\" answers the question\n * the raw JSON arguments make them decode.\n * - A create takes as long as the cockpit needs to start a session, and the\n * tool streams each phase into `output`, so the body is where the wait is\n * visible.\n */\nexport function RunWorktreeToolMessage({ args, output, running, isError }: ToolMessageRenderProps) {\n const action = typeof args.action === 'string' ? args.action : '';\n const subject = typeof args.branch === 'string' ? args.branch : typeof args.id === 'string' ? args.id : '';\n\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable={output !== ''}>\n <MessageItemHeader title={ACTION_LABEL[action] ?? 'Worktree'}>\n {subject === '' ? null : <span className=\"min-w-0 truncate text-doom-dim\">{subject}</span>}\n </MessageItemHeader>\n {output === '' ? null : (\n <MessageItemBody>\n <pre className={`whitespace-pre-wrap text-xs ${isError ? 'text-doom-red' : 'text-doom-dim'}`}>{output}</pre>\n </MessageItemBody>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/doompi-core/web';\n\nimport { RunWorktreeToolMessage } from './_components/RunWorktreeToolMessage';\n\nexport default defineToolRenderer({ message: RunWorktreeToolMessage });\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/doompi-core/web';\n\nimport activityGroupGit from '../src/extensions/workspaces/sessions/(frontend)/activity-group/git.web';\nimport channelGitWorktrees from '../src/extensions/workspaces/sessions/(frontend)/channel/gitWorktrees.web';\nimport fillWorktree from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktree.session-menu.web';\nimport fillWorktreeCreate from '../src/extensions/workspaces/sessions/(frontend)/fill/WorktreeCreate.overlay.web';\nimport fillWorktrees from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.web';\nimport lifecycleStart from '../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.web';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(frontend)/tool/runWorktree.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T => ({ ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'git',\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'git' }, activityGroupGit)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'git_worktrees' }, channelGitWorktrees)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'session-menu', id: 'worktree' }, fillWorktree), via({ slot: 'overlay', id: 'worktree-create' }, fillWorktreeCreate), via({ slot: 'activity.git', id: 'worktrees' }, fillWorktrees)]; },\n get start(): WebPluginContributions['start'] { return lifecycleStart; },\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['run_worktree'] }, toolRunWorktree)]; },\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"web.mjs","names":["contribution","activityGroupGit","channelGitWorktrees","fillWorktree","fillWorktreeCreate","fillWorktrees","lifecycleStart","toolRunWorktree"],"sources":["../../src/types/webWorktrees.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/worktreesActivityStore.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/WorktreesPanel.tsx","../../src/extensions/workspaces/sessions/(frontend)/activity-group/git.web.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/gitWorktrees.web.ts","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreeCreateDialog.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktree.session-menu.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/WorktreeCreate.overlay.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorktreesActivitySection.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/_lib/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.web.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/RunWorktreeToolMessage.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/runWorktree.web.tsx","../../generated/web.ts"],"sourcesContent":["/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The dock's view of this session's worktrees, and the commands it sends.\n *\n * DESIGN PATTERNS:\n * - Session-scoped store fed by one hub channel. The hub is authoritative; the\n * page never reads a registry and never guesses.\n * - Actions are channel frames, not prompts. The hub half owns the tool's\n * operations, so the panel names the work and the hub performs it; a\n * worktree made from the dock is the same object the tool makes, without\n * spending a turn of the conversation to ask for it.\n * - The sender lives in a store rather than a module variable, because a web\n * plugin keeps no mutable module state and the page may reconnect.\n *\n * AVOID:\n * - Calling the hub package API from here. A dock slot gets no sealed request\n * transport, and raw fetch breaks the remote cockpit.\n * - `sendSessionFrame` for a command. It envelopes the frame as a session\n * command bound for the agent, which never reaches a channel's `receive`.\n */\nimport { defineGlobalStore, defineSessionStore, type WebPluginRuntime } from '@agimon-ai/doompi-core/web';\n\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../../types/webWorktrees';\n\nexport interface WorktreesSession {\n /** The worktrees the hub last reported for this session's repository. */\n worktrees: WorktreeView[];\n /** Label of the operation the hub is running for this session. */\n pending: string | undefined;\n /** The last failure the hub reported, shown until the next command. */\n error: string | undefined;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n\nexport const worktreeActivity = defineSessionStore<WorktreesSession>({\n worktrees: [],\n pending: undefined,\n error: undefined,\n errorTarget: undefined,\n});\n\n/** Captures the clicked card, so a focus change cannot retarget an open dialog. */\nexport const worktreeCreateDialog = defineGlobalStore<{ sessionId: string; reservationId?: string } | null>(null);\n/**\n * The page's hub socket sender, held for as long as the plugin runs.\n *\n * Undefined before `startWorktreeRuntime` and after it disposes; a command\n * sent in that window is dropped rather than queued, because a queue would\n * replay a worktree create against a socket that has since changed sessions.\n */\nconst worktreeSender = defineGlobalStore<WebPluginRuntime['sendHubFrame'] | undefined>(undefined);\n\n/** Binds the page's hub socket. The plugin host calls this once per page. */\nexport function startWorktreeRuntime(runtime: WebPluginRuntime): () => void {\n // Wrapped rather than referenced: an unbound method would lose the runtime\n // it belongs to the moment the store hands it back.\n const send = (frame: Record<string, unknown>): void => {\n runtime.sendHubFrame(frame);\n };\n worktreeSender.update(() => send);\n return () => {\n worktreeSender.update((current) => (current === send ? undefined : current));\n worktreeCreateDialog.update(() => null);\n };\n}\n\n/**\n * Whether this session has worktree work in flight.\n *\n * A standing worktree is state, not work: it sits there until someone closes\n * it, so counting it would leave the session reading as busy forever, with a\n * \"background work is still running\" notice under a conversation where\n * nothing is running. Only a create or close actually in progress counts.\n *\n * The group stays visible either way. Declaring an active source at all is\n * what keeps it in the dock; this answers how it is drawn, not whether it is\n * there.\n */\nexport const worktreeActivitySource = {\n subscribe(listener: () => void) {\n const subscription = worktreeActivity.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId: string | null) {\n return worktreeActivity.select(worktreeActivity.store.state, sessionId).pending !== undefined;\n },\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction optionalText(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction optionalErrorTarget(value: unknown): WorktreeErrorTarget | undefined {\n if (!isRecord(value)) return undefined;\n if (value.action === 'create') return { action: 'create' };\n if (value.action === 'close' && typeof value.id === 'string' && value.id !== '') {\n return { action: 'close', id: value.id };\n }\n return undefined;\n}\n\n/** The plugin's session data channel: 'git_worktrees' payloads into the store. */\nexport const worktreesChannel = worktreeActivity.channel<WorktreesSession>({\n channel: GIT_WORKTREES_TYPE,\n parse(input) {\n if (!isRecord(input) || !Array.isArray(input.worktrees)) return null;\n return {\n worktrees: input.worktrees.filter(isRecord) as unknown as WorktreeView[],\n pending: optionalText(input.pending),\n error: optionalText(input.error),\n errorTarget: optionalErrorTarget(input.errorTarget),\n };\n },\n reduce(_current, next) {\n return next;\n },\n});\n\n/** Sends one command to the session's worktrees channel. */\nfunction command(sessionId: string, payload: GitWorktreesCommand): void {\n worktreeSender.store.state?.({ type: GIT_WORKTREES_TYPE, sessionId, payload });\n}\n\n/** Asks the hub for a worktree. The hub answers on the same channel. */\nexport function requestWorktreeCreate(\n sessionId: string,\n branch: string,\n baseRef: string,\n reservationId?: string,\n): void {\n const trimmedBase = baseRef.trim();\n command(sessionId, {\n action: 'create',\n branch: branch.trim(),\n ...(trimmedBase === '' ? {} : { baseRef: trimmedBase }),\n ...(reservationId === undefined ? {} : { reservationId }),\n });\n}\n\n/** Asks the hub to close one worktree. Refusal on a dirty tree stays the hub's call. */\nexport function requestWorktreeClose(sessionId: string, id: string): void {\n command(sessionId, { action: 'close', id });\n}\n","import type { TransientTab, WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\n/**\n * The '# git' group's tab: this session's worktrees, and the form that makes one.\n *\n * DESIGN PATTERNS:\n * - Lives in the activity dock, opened by the group's name. A worktree is work\n * in progress belonging to the session that started it, so it sits beside\n * agents, runners and workflows rather than in a settings screen.\n * - Header, form, then cards, the same rhythm the runners and workflows panels\n * use. A worktree row is a card because it carries three facts and two\n * actions, which a single line cannot hold without becoming a puzzle.\n * - Local form state is never reset by a data refresh. Direct lifecycle events\n * update the list without discarding a half-typed branch name.\n * - Acts through the plugin's own hub channel, so a worktree made here and one\n * made by the tool take exactly the same path.\n * - Creating waits on the cockpit starting a session, so the hub reports each\n * phase on that channel and the header shows it turning. A button that looks\n * idle for two minutes reads as broken.\n *\n * AVOID:\n * - Deriving form state from refreshed store data instead of the user's input.\n * - Colour classes outside the token set. `doom-error`, `doom-line` and\n * `doom-bright` are not tokens: they compile to nothing and the row silently\n * loses its border.\n */\nimport { Button, Dot, EmptyState, Input, Spinner, StatusBadge } from '@agimon-ai/doompi-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useState } from 'react';\n\nimport type { WorktreeView } from '../../../../../types/webWorktrees';\nimport { requestWorktreeClose, requestWorktreeCreate, worktreeActivity } from '../_lib/worktreesActivityStore';\n\nconst WORKTREES_TAB_ID = 'git-worktrees';\n\nexport function worktreesTab(): TransientTab {\n return { id: WORKTREES_TAB_ID, label: 'worktrees', panel: WorktreesPanel };\n}\n\nexport function WorktreesPanel({ sessionId, sessionReservationId }: WebPluginSlotProps) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, sessionId));\n const [branch, setBranch] = useState('');\n const [baseRef, setBaseRef] = useState('');\n\n const busy = session.pending !== undefined;\n const canCreate = sessionId !== null && branch.trim() !== '' && !busy;\n const createError = session.errorTarget?.action === 'create' ? session.error : undefined;\n const closeErrorId = session.errorTarget?.action === 'close' ? session.errorTarget.id : undefined;\n const panelError =\n session.error !== undefined &&\n (session.errorTarget === undefined ||\n (closeErrorId !== undefined && !session.worktrees.some((worktree) => worktree.id === closeErrorId)));\n\n const create = (): void => {\n if (sessionId === null || !canCreate) return;\n requestWorktreeCreate(sessionId, branch, baseRef, sessionReservationId);\n // A reserved setup must be retried with the same branch after a partial failure.\n if (sessionReservationId === undefined) {\n setBranch('');\n setBaseRef('');\n }\n };\n\n return (\n <div data-testid=\"git-worktrees-panel\" className=\"flex min-h-0 flex-1 flex-col overflow-auto\">\n <div className=\"flex min-h-11 shrink-0 items-center gap-2.5 border-b border-doom-border-soft px-3 sm:px-[26px]\">\n <span className=\"text-sm font-bold text-doom-hi\">worktrees</span>\n <span data-testid=\"git-worktrees-count\" className=\"text-xs text-doom-faint\">\n {session.worktrees.length === 0 ? 'none yet' : `${String(session.worktrees.length)} open`}\n </span>\n <span className=\"min-w-0 flex-1\" />\n {session.pending === undefined ? null : (\n <span data-testid=\"git-worktree-pending\" className=\"flex min-w-0 items-center gap-1.5\">\n <Spinner className=\"h-3 w-3 shrink-0 text-doom-faint\" label={session.pending} />\n <span className=\"min-w-0 truncate text-xs text-doom-dim\">{session.pending}</span>\n </span>\n )}\n </div>\n\n <div className=\"flex shrink-0 flex-col gap-1.5 border-b border-doom-border-soft px-3 py-2.5 sm:px-[26px]\">\n <div className=\"flex items-center gap-2\">\n <Input\n data-testid=\"git-worktree-branch\"\n aria-label=\"Branch\"\n size=\"sm\"\n className=\"min-w-0 flex-1\"\n placeholder=\"wt/fix-auth\"\n value={branch}\n onChange={(event) => setBranch(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') create();\n }}\n />\n <Input\n data-testid=\"git-worktree-base\"\n aria-label=\"Base ref\"\n size=\"sm\"\n placeholder=\"base (current)\"\n value={baseRef}\n onChange={(event) => setBaseRef(event.target.value)}\n className=\"w-32 shrink-0\"\n />\n <Button data-testid=\"git-worktree-create\" size=\"sm\" disabled={!canCreate} onClick={create}>\n Create\n </Button>\n </div>\n {createError === undefined ? (\n <p className=\"text-2xs text-doom-faint\">\n Creates the worktree outside the repository and starts a session nested under this one.\n </p>\n ) : (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"text-2xs text-doom-red\">\n {createError}\n </p>\n )}\n </div>\n\n {panelError ? (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"px-3 pt-2 text-2xs text-doom-red sm:px-[26px]\">\n {session.error}\n </p>\n ) : null}\n\n {session.worktrees.length === 0 ? (\n <EmptyState\n data-testid=\"git-worktrees-empty\"\n className=\"px-4 py-8\"\n title=\"no worktrees yet\"\n description=\"a worktree is its own checkout on its own branch, with its own session nested under this one.\"\n />\n ) : (\n <ul data-testid=\"git-worktrees-list\" className=\"flex flex-col gap-2.5 px-3 py-3 sm:px-[26px]\">\n {session.worktrees.map((worktree: WorktreeView) => (\n <WorktreeCard\n key={worktree.id}\n worktree={worktree}\n sessionId={sessionId}\n busy={busy}\n error={closeErrorId === worktree.id ? session.error : undefined}\n />\n ))}\n </ul>\n )}\n </div>\n );\n}\n\n/** One worktree: what it is, where it is, and the one thing you can do to it. */\nfunction WorktreeCard({\n worktree,\n sessionId,\n busy,\n error,\n}: {\n worktree: WorktreeView;\n busy: boolean;\n error?: string;\n} & Pick<WebPluginSlotProps, 'sessionId'>) {\n return (\n <li\n data-testid={`git-worktree-${worktree.id}`}\n className=\"flex min-w-0 flex-col gap-1.5 rounded-md border border-doom-border-soft bg-doom-panel p-2.5\"\n >\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <Dot tone={worktree.orphaned ? 'red' : worktree.sessionId === null ? 'muted' : 'blue'} />\n <span className=\"min-w-0 flex-1 truncate text-sm font-bold text-doom-hi\">{worktree.branch}</span>\n {worktree.orphaned ? (\n <StatusBadge tone=\"error\" size=\"xs\">\n orphaned\n </StatusBadge>\n ) : null}\n {worktree.unowned ? (\n <StatusBadge tone=\"info\" size=\"xs\">\n unowned\n </StatusBadge>\n ) : null}\n </div>\n\n <span className=\"min-w-0 truncate text-2xs text-doom-faint\">{worktree.path}</span>\n\n <div className=\"flex items-center gap-1.5 pt-0.5\">\n <span className=\"min-w-0 flex-1\" />\n {sessionId === null ? null : (\n <Button\n variant=\"danger-outline\"\n size=\"xs\"\n disabled={busy}\n data-testid={`git-worktree-close-${worktree.id}`}\n className=\"px-2 text-2xs font-bold\"\n onClick={() => requestWorktreeClose(sessionId, worktree.id)}\n >\n close\n </Button>\n )}\n </div>\n {error === undefined ? null : (\n <p role=\"alert\" data-testid=\"git-worktree-error\" className=\"text-2xs text-doom-red\">\n {error}\n </p>\n )}\n </li>\n );\n}\n","import { defineActivityGroup } from '@agimon-ai/doompi-core/web';\n\nimport { worktreesTab } from '../_components/WorktreesPanel';\nimport { worktreeActivitySource } from '../_lib/worktreesActivityStore';\n\nexport default defineActivityGroup({\n keys: 'g w',\n activeSource: worktreeActivitySource,\n marksBackgroundWork: false,\n transientTab: worktreesTab,\n order: 30,\n});\n","import { defineChannelFile } from '@agimon-ai/doompi-core/web';\n\nimport { worktreesChannel } from '../_lib/worktreesActivityStore';\n\nexport default defineChannelFile(worktreesChannel);\n","import type { WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\nimport {\n Dialog,\n DialogBody,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DropdownMenuItem,\n} from '@agimon-ai/doompi-web-components';\nimport { useStore } from '@tanstack/react-store';\nimport { useEffect } from 'react';\n\nimport { WorktreesPanel } from '../../_components/WorktreesPanel';\nimport { worktreeCreateDialog, worktreesChannel } from '../../_lib/worktreesActivityStore';\n\nexport function WorktreeSessionMenu({ sessionId, sessionReservationId }: WebPluginSlotProps) {\n return (\n <DropdownMenuItem\n disabled={sessionId === null}\n data-testid={`session-worktree-${sessionReservationId ?? sessionId}`}\n onSelect={() => {\n if (sessionId !== null)\n worktreeCreateDialog.update(() => ({\n sessionId,\n ...(sessionReservationId === undefined ? {} : { reservationId: sessionReservationId }),\n }));\n }}\n >\n create worktree session…\n </DropdownMenuItem>\n );\n}\n\nexport function WorktreeCreateOverlay(props: WebPluginSlotProps) {\n const target = useStore(worktreeCreateDialog.store);\n const { holdSessionChannels } = props;\n useEffect(() => {\n if (target === null) return;\n return holdSessionChannels?.(target.sessionId, (frame) => {\n if (frame.type !== worktreesChannel.channel) return;\n const payload = worktreesChannel.parse(frame.payload);\n if (payload !== null) worktreesChannel.apply(target.sessionId, payload);\n });\n }, [target, holdSessionChannels]);\n if (target === null) return null;\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open) worktreeCreateDialog.update(() => null);\n }}\n >\n <DialogContent width=\"lg\" data-testid=\"session-worktree-dialog\">\n <DialogHeader>\n <DialogTitle>create worktree session</DialogTitle>\n </DialogHeader>\n <DialogBody>\n <DialogDescription>\n Creates a separate checkout and a new session. Existing sessions stay in their current directories.\n </DialogDescription>\n <WorktreesPanel\n {...props}\n key={`${target.sessionId}:${target.reservationId ?? ''}`}\n sessionId={target.sessionId}\n sessionReservationId={target.reservationId}\n />\n </DialogBody>\n </DialogContent>\n </Dialog>\n );\n}\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { WorktreeSessionMenu } from './_components/WorktreeCreateDialog';\n\nexport default defineFill({ component: WorktreeSessionMenu });\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { WorktreeCreateOverlay } from './_components/WorktreeCreateDialog';\n\nexport default defineFill({ component: WorktreeCreateOverlay });\n","import type { WebPluginSlotProps } from '@agimon-ai/doompi-core/web';\n/**\n * The '# git' group's body in the activity dock.\n *\n * DESIGN PATTERNS:\n * - One line per worktree, the same rule the runners rail follows: enough to\n * notice it, not enough to work with it. The group's own name opens the tab\n * that has room.\n * - Idle still shows the launcher. A repository with no worktrees is the state\n * where someone most wants to make one.\n *\n * AVOID:\n * - Doing work here. This section reports and launches; the panel and the tool\n * own everything else.\n */\nimport { Button, Dot, Spinner, StatusBadge } from '@agimon-ai/doompi-web-components';\nimport { useStore } from '@tanstack/react-store';\n\nimport type { WorktreeView } from '../../../../../../types/webWorktrees';\nimport { worktreesTab } from '../../_components/WorktreesPanel';\nimport { worktreeActivity } from '../../_lib/worktreesActivityStore';\n\nexport function WorktreesActivitySection({ sessionId, openTransientTab }: WebPluginSlotProps) {\n const session = useStore(worktreeActivity.store, (state) => worktreeActivity.select(state, sessionId));\n\n if (session.worktrees.length === 0 && session.pending === undefined) {\n return (\n <div className=\"flex items-center gap-2 px-1\">\n <p data-testid=\"activity-summary-git\" className=\"px-1 text-xs text-doom-faint\">\n idle\n </p>\n {sessionId === null ? null : (\n <Button\n variant=\"link\"\n size=\"xs\"\n data-testid=\"activity-git-create\"\n className=\"px-0\"\n onClick={() => openTransientTab(worktreesTab())}\n >\n create a worktree\n </Button>\n )}\n </div>\n );\n }\n\n return (\n <div data-testid=\"activity-git-worktrees\" className=\"flex flex-col gap-0.5\">\n {session.pending === undefined ? null : (\n <span className=\"flex min-w-0 items-center gap-1.5 px-1\">\n <Spinner className=\"h-3 w-3 shrink-0 text-doom-faint\" label={session.pending} />\n <span className=\"min-w-0 truncate text-xs text-doom-dim\">{session.pending}</span>\n </span>\n )}\n {session.worktrees.map((worktree: WorktreeView) => (\n <Button\n key={worktree.id}\n variant=\"ghost\"\n size=\"card\"\n data-testid={`activity-git-worktree-${worktree.id}`}\n className=\"min-w-0 gap-1.5 px-1\"\n onClick={() => openTransientTab(worktreesTab())}\n >\n <span className=\"flex w-full min-w-0 items-center gap-1.5\">\n <Dot tone={worktree.orphaned ? 'red' : worktree.sessionId === null ? 'muted' : 'blue'} />\n <span className=\"min-w-0 flex-1 truncate text-left text-xs font-bold text-doom-hi\">{worktree.branch}</span>\n {worktree.orphaned ? (\n <StatusBadge tone=\"error\" size=\"xs\">\n orphaned\n </StatusBadge>\n ) : null}\n {worktree.unowned ? (\n <StatusBadge tone=\"info\" size=\"xs\">\n unowned\n </StatusBadge>\n ) : null}\n </span>\n </Button>\n ))}\n </div>\n );\n}\n","import { defineFill } from '@agimon-ai/doompi-core/web';\n\nimport { WorktreesActivitySection } from './_components/WorktreesActivitySection';\n\nexport default defineFill({ component: WorktreesActivitySection });\n","import { startWorktreeRuntime } from '../../_lib/worktreesActivityStore';\n\nexport default startWorktreeRuntime;\n","import { defineWebLifecycle } from '@agimon-ai/doompi-core/web';\n\nimport contribution from './_lib/start.web';\n\nexport default defineWebLifecycle(contribution);\n","import type { ToolMessageRenderProps } from '@agimon-ai/doompi-core/web';\nimport { MessageItem, MessageItemBody, MessageItemHeader, toolTone } from '@agimon-ai/doompi-web-components';\n\nconst ACTION_LABEL: Readonly<Record<string, string>> = {\n spawn_worktree: 'Create worktree',\n close_worktree: 'Close worktree',\n list: 'List worktrees',\n status: 'Worktree status',\n merge: 'Merge worktree',\n prune: 'Prune worktrees',\n send: 'Message worktree',\n messages: 'Read worktree messages',\n};\n\n/**\n * The timeline item for `run_worktree`.\n *\n * DESIGN PATTERNS:\n * - Built on MessageItem, like every other tool renderer in the cockpit. That\n * is what gives it the shared collapse toggle and the RUNNING/OK/ERROR badge\n * rather than a hand-rolled ellipsis that never resolves.\n * - The action and its subject go in the heading because that is what a reader\n * scanning a transcript needs: \"close_worktree a1b2c3d4\" answers the question\n * the raw JSON arguments make them decode.\n * - A create takes as long as the cockpit needs to start a session, and the\n * tool streams each phase into `output`, so the body is where the wait is\n * visible.\n */\nexport function RunWorktreeToolMessage({ args, output, running, isError }: ToolMessageRenderProps) {\n const action = typeof args.action === 'string' ? args.action : '';\n const subject = typeof args.branch === 'string' ? args.branch : typeof args.id === 'string' ? args.id : '';\n\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable={output !== ''}>\n <MessageItemHeader title={ACTION_LABEL[action] ?? 'Worktree'}>\n {subject === '' ? null : <span className=\"min-w-0 truncate text-doom-dim\">{subject}</span>}\n </MessageItemHeader>\n {output === '' ? null : (\n <MessageItemBody>\n <pre className={`whitespace-pre-wrap text-xs ${isError ? 'text-doom-red' : 'text-doom-dim'}`}>{output}</pre>\n </MessageItemBody>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/doompi-core/web';\n\nimport { RunWorktreeToolMessage } from './_components/RunWorktreeToolMessage';\n\nexport default defineToolRenderer({ message: RunWorktreeToolMessage });\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/doompi-core/web';\n\nimport activityGroupGit from '../src/extensions/workspaces/sessions/(frontend)/activity-group/git.web';\nimport channelGitWorktrees from '../src/extensions/workspaces/sessions/(frontend)/channel/gitWorktrees.web';\nimport fillWorktree from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktree.session-menu.web';\nimport fillWorktreeCreate from '../src/extensions/workspaces/sessions/(frontend)/fill/WorktreeCreate.overlay.web';\nimport fillWorktrees from '../src/extensions/workspaces/sessions/(frontend)/fill/Worktrees.activity.git.web';\nimport lifecycleStart from '../src/extensions/workspaces/sessions/(frontend)/lifecycle/start.web';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(frontend)/tool/runWorktree.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'git',\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'git' }, activityGroupGit)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'git_worktrees' }, channelGitWorktrees)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'session-menu', id: 'worktree' }, fillWorktree), via({ slot: 'overlay', id: 'worktree-create' }, fillWorktreeCreate), via({ slot: 'activity.git', id: 'worktrees' }, fillWorktrees)]; },\n get start(): WebPluginContributions['start'] { return lifecycleStart; },\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['run_worktree'] }, toolRunWorktree)]; },\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAeA,MAAa,qBAAqB;;;;;;;;;;;;;;;;;;;;;;ACwBlC,MAAa,mBAAmB,mBAAqC;CACnE,WAAW,CAAC;CACZ,SAAS,KAAA;CACT,OAAO,KAAA;CACP,aAAa,KAAA;AACf,CAAC;;AAGD,MAAa,uBAAuB,kBAAwE,IAAI;;;;;;;;AAQhH,MAAM,iBAAiB,kBAAgE,KAAA,CAAS;;AAGhG,SAAgB,qBAAqB,SAAuC;CAG1E,MAAM,QAAQ,UAAyC;EACrD,QAAQ,aAAa,KAAK;CAC5B;CACA,eAAe,aAAa,IAAI;CAChC,aAAa;EACX,eAAe,QAAQ,YAAa,YAAY,OAAO,KAAA,IAAY,OAAQ;EAC3E,qBAAqB,aAAa,IAAI;CACxC;AACF;;;;;;;;;;;;;AAcA,MAAa,yBAAyB;CACpC,UAAU,UAAsB;EAC9B,MAAM,eAAe,iBAAiB,MAAM,UAAU,QAAQ;EAC9D,aAAa,aAAa,YAAY;CACxC;CACA,SAAS,WAA0B;EACjC,OAAO,iBAAiB,OAAO,iBAAiB,MAAM,OAAO,SAAS,CAAC,CAAC,YAAY,KAAA;CACtF;AACF;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,aAAa,OAAoC;CACxD,OAAO,OAAO,UAAU,YAAY,UAAU,KAAK,QAAQ,KAAA;AAC7D;AAEA,SAAS,oBAAoB,OAAiD;CAC5E,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO,KAAA;CAC7B,IAAI,MAAM,WAAW,UAAU,OAAO,EAAE,QAAQ,SAAS;CACzD,IAAI,MAAM,WAAW,WAAW,OAAO,MAAM,OAAO,YAAY,MAAM,OAAO,IAC3E,OAAO;EAAE,QAAQ;EAAS,IAAI,MAAM;CAAG;AAG3C;;AAGA,MAAa,mBAAmB,iBAAiB,QAA0B;CACzE,SAAS;CACT,MAAM,OAAO;EACX,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,MAAM,QAAQ,MAAM,SAAS,GAAG,OAAO;EAChE,OAAO;GACL,WAAW,MAAM,UAAU,OAAO,QAAQ;GAC1C,SAAS,aAAa,MAAM,OAAO;GACnC,OAAO,aAAa,MAAM,KAAK;GAC/B,aAAa,oBAAoB,MAAM,WAAW;EACpD;CACF;CACA,OAAO,UAAU,MAAM;EACrB,OAAO;CACT;AACF,CAAC;;AAGD,SAAS,QAAQ,WAAmB,SAAoC;CACtE,eAAe,MAAM,QAAQ;EAAE,MAAM;EAAoB;EAAW;CAAQ,CAAC;AAC/E;;AAGA,SAAgB,sBACd,WACA,QACA,SACA,eACM;CACN,MAAM,cAAc,QAAQ,KAAK;CACjC,QAAQ,WAAW;EACjB,QAAQ;EACR,QAAQ,OAAO,KAAK;EACpB,GAAI,gBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,YAAY;EACrD,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc;CACzD,CAAC;AACH;;AAGA,SAAgB,qBAAqB,WAAmB,IAAkB;CACxE,QAAQ,WAAW;EAAE,QAAQ;EAAS;CAAG,CAAC;AAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvHA,MAAM,mBAAmB;AAEzB,SAAgB,eAA6B;CAC3C,OAAO;EAAE,IAAI;EAAkB,OAAO;EAAa,OAAO;CAAe;AAC3E;AAEA,SAAgB,eAAe,EAAE,WAAW,wBAA4C;CACtF,MAAM,UAAU,SAAS,iBAAiB,QAAQ,UAAU,iBAAiB,OAAO,OAAO,SAAS,CAAC;CACrG,MAAM,CAAC,QAAQ,aAAa,SAAS,EAAE;CACvC,MAAM,CAAC,SAAS,cAAc,SAAS,EAAE;CAEzC,MAAM,OAAO,QAAQ,YAAY,KAAA;CACjC,MAAM,YAAY,cAAc,QAAQ,OAAO,KAAK,MAAM,MAAM,CAAC;CACjE,MAAM,cAAc,QAAQ,aAAa,WAAW,WAAW,QAAQ,QAAQ,KAAA;CAC/E,MAAM,eAAe,QAAQ,aAAa,WAAW,UAAU,QAAQ,YAAY,KAAK,KAAA;CACxF,MAAM,aACJ,QAAQ,UAAU,KAAA,MACjB,QAAQ,gBAAgB,KAAA,KACtB,iBAAiB,KAAA,KAAa,CAAC,QAAQ,UAAU,MAAM,aAAa,SAAS,OAAO,YAAY;CAErG,MAAM,eAAqB;EACzB,IAAI,cAAc,QAAQ,CAAC,WAAW;EACtC,sBAAsB,WAAW,QAAQ,SAAS,oBAAoB;EAEtE,IAAI,yBAAyB,KAAA,GAAW;GACtC,UAAU,EAAE;GACZ,WAAW,EAAE;EACf;CACF;CAEA,OACE,qBAAC,OAAD;EAAK,eAAY;EAAsB,WAAU;EAAjD,UAAA;GACE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,QAAD;MAAM,WAAU;MAAiC,UAAA;KAAe,CAAA;KAChE,oBAAC,QAAD;MAAM,eAAY;MAAsB,WAAU;MAC/C,UAAA,QAAQ,UAAU,WAAW,IAAI,aAAa,GAAG,OAAO,QAAQ,UAAU,MAAM,EAAE;KAC/E,CAAA;KACN,oBAAC,QAAD,EAAM,WAAU,iBAAkB,CAAA;KACjC,QAAQ,YAAY,KAAA,IAAY,OAC/B,qBAAC,QAAD;MAAM,eAAY;MAAuB,WAAU;MAAnD,UAAA,CACE,oBAAC,SAAD;OAAS,WAAU;OAAmC,OAAO,QAAQ;MAAU,CAAA,GAC/E,oBAAC,QAAD;OAAM,WAAU;OAA0C,UAAA,QAAQ;MAAc,CAAA,CAC5E;;IAEL;;GAEL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,oBAAC,OAAD;OACE,eAAY;OACZ,cAAW;OACX,MAAK;OACL,WAAU;OACV,aAAY;OACZ,OAAO;OACP,WAAW,UAAU,UAAU,MAAM,OAAO,KAAK;OACjD,YAAY,UAAU;QACpB,IAAI,MAAM,QAAQ,SAAS,OAAO;OACpC;MACD,CAAA;MACD,oBAAC,OAAD;OACE,eAAY;OACZ,cAAW;OACX,MAAK;OACL,aAAY;OACZ,OAAO;OACP,WAAW,UAAU,WAAW,MAAM,OAAO,KAAK;OAClD,WAAU;MACX,CAAA;MACD,oBAAC,QAAD;OAAQ,eAAY;OAAsB,MAAK;OAAK,UAAU,CAAC;OAAW,SAAS;OAAQ,UAAA;MAEnF,CAAA;KACL;IACJ,CAAA,GAAA,gBAAgB,KAAA,IACf,oBAAC,KAAD;KAAG,WAAU;KAA2B,UAAA;IAErC,CAAA,IAEH,oBAAC,KAAD;KAAG,MAAK;KAAQ,eAAY;KAAqB,WAAU;KACxD,UAAA;IACA,CAAA,CAEF;;GAEJ,aACC,oBAAC,KAAD;IAAG,MAAK;IAAQ,eAAY;IAAqB,WAAU;IACxD,UAAA,QAAQ;GACR,CAAA,IACD;GAEH,QAAQ,UAAU,WAAW,IAC5B,oBAAC,YAAD;IACE,eAAY;IACZ,WAAU;IACV,OAAM;IACN,aAAY;GACb,CAAA,IAED,oBAAC,MAAD;IAAI,eAAY;IAAqB,WAAU;IAC5C,UAAA,QAAQ,UAAU,KAAK,aACtB,oBAAC,cAAD;KAEY;KACC;KACL;KACN,OAAO,iBAAiB,SAAS,KAAK,QAAQ,QAAQ,KAAA;IACvD,GALM,SAAS,EAKf,CACF;GACC,CAAA;EAEH;;AAET;;AAGA,SAAS,aAAa,EACpB,UACA,WACA,MACA,SAKyC;CACzC,OACE,qBAAC,MAAD;EACE,eAAa,gBAAgB,SAAS;EACtC,WAAU;EAFZ,UAAA;GAIE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,KAAD,EAAK,MAAM,SAAS,WAAW,QAAQ,SAAS,cAAc,OAAO,UAAU,OAAS,CAAA;KACxF,oBAAC,QAAD;MAAM,WAAU;MAA0D,UAAA,SAAS;KAAa,CAAA;KAC/F,SAAS,WACR,oBAAC,aAAD;MAAa,MAAK;MAAQ,MAAK;MAAK,UAAA;KAEvB,CAAA,IACX;KACH,SAAS,UACR,oBAAC,aAAD;MAAa,MAAK;MAAO,MAAK;MAAK,UAAA;KAEtB,CAAA,IACX;IACD;;GAEL,oBAAC,QAAD;IAAM,WAAU;IAA6C,UAAA,SAAS;GAAW,CAAA;GAEjF,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,QAAD,EAAM,WAAU,iBAAkB,CAAA,GACjC,cAAc,OAAO,OACpB,oBAAC,QAAD;KACE,SAAQ;KACR,MAAK;KACL,UAAU;KACV,eAAa,sBAAsB,SAAS;KAC5C,WAAU;KACV,eAAe,qBAAqB,WAAW,SAAS,EAAE;KAC3D,UAAA;IAEO,CAAA,CAEP;;GACJ,UAAU,KAAA,IAAY,OACrB,oBAAC,KAAD;IAAG,MAAK;IAAQ,eAAY;IAAqB,WAAU;IACxD,UAAA;GACA,CAAA;EAEH;;AAER;;;ACpMA,IAAA,kBAAe,oBAAoB;CACjC,MAAM;CACN,cAAc;CACd,qBAAqB;CACrB,cAAc;CACd,OAAO;AACT,CAAC;;;ACPD,IAAA,2BAAe,kBAAkB,gBAAgB;;;ACYjD,SAAgB,oBAAoB,EAAE,WAAW,wBAA4C;CAC3F,OACE,oBAAC,kBAAD;EACE,UAAU,cAAc;EACxB,eAAa,oBAAoB,wBAAwB;EACzD,gBAAgB;GACd,IAAI,cAAc,MAChB,qBAAqB,cAAc;IACjC;IACA,GAAI,yBAAyB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,qBAAqB;GACtF,EAAE;EACN;EACD,UAAA;CAEiB,CAAA;AAEtB;AAEA,SAAgB,sBAAsB,OAA2B;CAC/D,MAAM,SAAS,SAAS,qBAAqB,KAAK;CAClD,MAAM,EAAE,wBAAwB;CAChC,gBAAgB;EACd,IAAI,WAAW,MAAM;EACrB,OAAO,sBAAsB,OAAO,YAAY,UAAU;GACxD,IAAI,MAAM,SAAS,iBAAiB,SAAS;GAC7C,MAAM,UAAU,iBAAiB,MAAM,MAAM,OAAO;GACpD,IAAI,YAAY,MAAM,iBAAiB,MAAM,OAAO,WAAW,OAAO;EACxE,CAAC;CACH,GAAG,CAAC,QAAQ,mBAAmB,CAAC;CAChC,IAAI,WAAW,MAAM,OAAO;CAC5B,OACE,oBAAC,QAAD;EACE,MAAA;EACA,eAAe,SAAS;GACtB,IAAI,CAAC,MAAM,qBAAqB,aAAa,IAAI;EACnD;EAEA,UAAA,qBAAC,eAAD;GAAe,OAAM;GAAK,eAAY;GAAtC,UAAA,CACE,oBAAC,cAAD,EAAA,UACE,oBAAC,aAAD,EAAA,UAAa,0BAAoC,CAAA,EACrC,CAAA,GACd,qBAAC,YAAD,EAAA,UAAA,CACE,oBAAC,mBAAD,EAAA,UAAmB,sGAEA,CAAA,GACnB,8BAAC,gBAAD;IACE,GAAI;IACJ,KAAK,GAAG,OAAO,UAAU,GAAG,OAAO,iBAAiB;IACpD,WAAW,OAAO;IAClB,sBAAsB,OAAO;GAC9B,CAAA,CACS,EAAA,CAAA,CACC;;CACT,CAAA;AAEZ;;;ACnEA,IAAA,oCAAe,WAAW,EAAE,WAAW,oBAAoB,CAAC;;;ACA5D,IAAA,qCAAe,WAAW,EAAE,WAAW,sBAAsB,CAAC;;;;;;;;;;;;;;;;;ACkB9D,SAAgB,yBAAyB,EAAE,WAAW,oBAAwC;CAC5F,MAAM,UAAU,SAAS,iBAAiB,QAAQ,UAAU,iBAAiB,OAAO,OAAO,SAAS,CAAC;CAErG,IAAI,QAAQ,UAAU,WAAW,KAAK,QAAQ,YAAY,KAAA,GACxD,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,KAAD;GAAG,eAAY;GAAuB,WAAU;GAA+B,UAAA;EAE5E,CAAA,GACF,cAAc,OAAO,OACpB,oBAAC,QAAD;GACE,SAAQ;GACR,MAAK;GACL,eAAY;GACZ,WAAU;GACV,eAAe,iBAAiB,aAAa,CAAC;GAC/C,UAAA;EAEO,CAAA,CAEP;;CAIT,OACE,qBAAC,OAAD;EAAK,eAAY;EAAyB,WAAU;EAApD,UAAA,CACG,QAAQ,YAAY,KAAA,IAAY,OAC/B,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACE,oBAAC,SAAD;IAAS,WAAU;IAAmC,OAAO,QAAQ;GAAU,CAAA,GAC/E,oBAAC,QAAD;IAAM,WAAU;IAA0C,UAAA,QAAQ;GAAc,CAAA,CAC5E;EAEP,CAAA,GAAA,QAAQ,UAAU,KAAK,aACtB,oBAAC,QAAD;GAEE,SAAQ;GACR,MAAK;GACL,eAAa,yBAAyB,SAAS;GAC/C,WAAU;GACV,eAAe,iBAAiB,aAAa,CAAC;GAE9C,UAAA,qBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA;KACE,oBAAC,KAAD,EAAK,MAAM,SAAS,WAAW,QAAQ,SAAS,cAAc,OAAO,UAAU,OAAS,CAAA;KACxF,oBAAC,QAAD;MAAM,WAAU;MAAoE,UAAA,SAAS;KAAa,CAAA;KACzG,SAAS,WACR,oBAAC,aAAD;MAAa,MAAK;MAAQ,MAAK;MAAK,UAAA;KAEvB,CAAA,IACX;KACH,SAAS,UACR,oBAAC,aAAD;MAAa,MAAK;MAAO,MAAK;MAAK,UAAA;KAEtB,CAAA,IACX;IACA;;EACA,GArBD,SAAS,EAqBR,CACT,CACE;;AAET;;;AC7EA,IAAA,qCAAe,WAAW,EAAE,WAAW,yBAAyB,CAAC;;;AEAjE,IAAA,oBAAe,mBAAmBA,oBAAY;;;ACD9C,MAAM,eAAiD;CACrD,gBAAgB;CAChB,gBAAgB;CAChB,MAAM;CACN,QAAQ;CACR,OAAO;CACP,OAAO;CACP,MAAM;CACN,UAAU;AACZ;;;;;;;;;;;;;;;AAgBA,SAAgB,uBAAuB,EAAE,MAAM,QAAQ,SAAS,WAAmC;CACjG,MAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;CAC/D,MAAM,UAAU,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;CAExG,OACE,qBAAC,aAAD;EAAa,MAAM,SAAS;GAAE;GAAS;EAAQ,CAAC;EAAG,YAAY,WAAW;EAA1E,UAAA,CACE,oBAAC,mBAAD;GAAmB,OAAO,aAAa,WAAW;GAC/C,UAAA,YAAY,KAAK,OAAO,oBAAC,QAAD;IAAM,WAAU;IAAkC,UAAA;GAAc,CAAA;EACxE,CAAA,GAClB,WAAW,KAAK,OACf,oBAAC,iBAAD,EAAA,UACE,oBAAC,OAAD;GAAK,WAAW,+BAA+B,UAAU,kBAAkB;GAAoB,UAAA;EAAY,CAAA,EAC5F,CAAA,CAER;;AAEjB;;;ACxCA,IAAA,0BAAe,mBAAmB,EAAE,SAAS,uBAAuB,CAAC;;;ACOrE,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,YAAY,gBAAgB;CACvC,IAAI;CACJ,SAAS;EACP,IAAI,iBAA2D;GAAE,OAAO,CAAC,IAAI,EAAE,MAAM,MAAM,GAAGC,eAAgB,CAAC;EAAG;EAClH,IAAI,WAA+C;GAAE,OAAO,CAAC,IAAI,EAAE,SAAS,gBAAgB,GAAGC,wBAAmB,CAAC;EAAG;EACtH,IAAI,QAAyC;GAAE,OAAO;IAAC,IAAI;KAAE,MAAM;KAAgB,IAAI;IAAW,GAAGC,iCAAY;IAAG,IAAI;KAAE,MAAM;KAAW,IAAI;IAAkB,GAAGC,kCAAkB;IAAG,IAAI;KAAE,MAAM;KAAgB,IAAI;IAAY,GAAGC,kCAAa;GAAC;EAAG;EACzP,IAAI,QAAyC;GAAE,OAAOC;EAAgB;EACtE,IAAI,gBAAyD;GAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE,GAAGC,uBAAe,CAAC;EAAG;CAC7H;AACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-git",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.20",
|
|
4
4
|
"description": "Git worktree sessions for DoomPi: spawn an isolated worktree with its own session and manage it from the parent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -67,17 +67,17 @@
|
|
|
67
67
|
"access": "public"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.
|
|
71
|
-
"@agimon-ai/doompi-session": "0.0.1-alpha.
|
|
72
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.
|
|
70
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.84",
|
|
71
|
+
"@agimon-ai/doompi-session": "0.0.1-alpha.8",
|
|
72
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.42",
|
|
73
73
|
"@deepseek-ai/cordis": "4.0.2",
|
|
74
74
|
"@tanstack/react-store": "0.11.1",
|
|
75
75
|
"@tanstack/store": "0.11.1",
|
|
76
76
|
"typebox": "1.3.34"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@agimon-ai/doompi-build": "0.0.1-alpha.
|
|
80
|
-
"@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.1-alpha.
|
|
79
|
+
"@agimon-ai/doompi-build": "0.0.1-alpha.12",
|
|
80
|
+
"@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.1-alpha.78",
|
|
81
81
|
"@earendil-works/pi-agent-core": "0.87.1",
|
|
82
82
|
"@earendil-works/pi-coding-agent": "0.87.1",
|
|
83
83
|
"@types/node": "26.6.1",
|