@agimon-ai/doompi-hook 0.0.1-alpha.90 → 0.0.1-alpha.91

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.
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_hookModules = require("../hookModules-hfDQUKiA.cjs");
6
- const require_hookRuntime = require("../hookRuntime-BLFf_6_E.cjs");
5
+ const require_hookModules = require("../hookModules-DShU8Nls.cjs");
6
+ const require_hookRuntime = require("../hookRuntime-BDfSkRP-.cjs");
7
7
  let _agimon_ai_doompi_core_piExtension = require("@agimon-ai/doompi-core/piExtension");
8
8
  let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
9
9
  let _agimon_ai_doompi_core_cordisHost = require("@agimon-ai/doompi-core/cordisHost");
@@ -68,6 +68,7 @@ function createSessionStart(pi, resolveRuntime) {
68
68
  if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return void 0;
69
69
  const { session, readiness } = runtime;
70
70
  const run = async (signal, isReady = () => true) => {
71
+ await session.prepare();
71
72
  const result = await runPiDispatch(pi, session, ctx, {
72
73
  eventName: require_hookModules.HOOK_EVENT.sessionStart,
73
74
  event
@@ -85,6 +86,7 @@ function createBeforeAgentStart(resolveRuntime) {
85
86
  return async (_event, ctx) => {
86
87
  const runtime = resolveRuntime();
87
88
  if (!runtime?.isCurrent()) return;
89
+ await runtime.session.prepare(runtime.session.parentContext?.isSubagent ?? Boolean(process.env["PI_SUBAGENT_CHILD"]));
88
90
  await runtime.readiness?.wait(ctx);
89
91
  };
90
92
  }
@@ -92,7 +94,23 @@ function createToolCall(pi, resolveRuntime) {
92
94
  return async (event, ctx) => {
93
95
  const runtime = resolveRuntime();
94
96
  if (!runtime?.isCurrent()) return void 0;
95
- await runtime.readiness?.wait(ctx);
97
+ try {
98
+ await runtime.session.prepare(scopeFor(pi, runtime.session, ctx).isSubagent);
99
+ await runtime.readiness?.wait(ctx);
100
+ } catch (error) {
101
+ const reason = error instanceof Error ? error.message : String(error);
102
+ try {
103
+ pi.sendMessage({
104
+ customType: require_hookRuntime.FAILURE_MESSAGE_TYPE,
105
+ content: reason,
106
+ display: true
107
+ }, require_hookRuntime.STEER);
108
+ } catch {}
109
+ return {
110
+ block: true,
111
+ reason
112
+ };
113
+ }
96
114
  if (!runtime.isCurrent()) return void 0;
97
115
  const result = await runPiDispatch(pi, runtime.session, ctx, {
98
116
  eventName: require_hookModules.HOOK_EVENT.preToolUse,
@@ -1 +1 @@
1
- {"version":3,"file":"pi.cjs","names":["SUBAGENT_ENVIRONMENT_FLAG","CONTEXT_MESSAGE_TYPE","dispatchHooks","hookFailureMessage","FAILURE_MESSAGE_TYPE","STEER","HOOK_EVENT","STATUS_PREFIX","additionalContextsFrom","STOP_HOOK_ACTIVE_FIELD","NO_TURN","decisionReason","isDenied","STOP_BLOCK_MESSAGE_TYPE","FOLLOW_UP_TURN","createHookBinding","DOOM_CORDIS_SERVER_SERVICES","DOOM_HOOK_SESSION_SERVICE","defineRoot","defineCliHook","defineCliHook","defineCliHook","defineCliHook","defineCliHook","defineCliHook","defineResource","PACKAGE_SOURCE","HOOK_HELP_SKILL","definePiExtension","rootSession","composeRootHooks","hookAgentSettled","hookBeforeAgentStart","hookSessionShutdown","hookSessionStart","hookToolCall","hookToolResult","resourceDoompiUseHook"],"sources":["../../src/services/hookHandlers/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli.ts","../../generated/pi.ts"],"sourcesContent":["import type { PiEventHandlers } from '@agimon-ai/doompi-core/piExtension';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n STATUS_PREFIX,\n FAILURE_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n STOP_BLOCK_MESSAGE_TYPE,\n FOLLOW_UP_TURN,\n MAX_STOP_REFUSALS,\n NO_TURN,\n STEER,\n STOP_HOOK_ACTIVE_FIELD,\n SUBAGENT_ENVIRONMENT_FLAG,\n CONTEXT_SEPARATOR,\n} from '../../constants/hookHandlers';\nimport { HOOK_EVENT } from '../../constants/hooks';\nimport type { HookFailure } from '../../types/hooks';\nimport { additionalContextsFrom, decisionReason, hookFailureMessage, isDenied } from '../hookDecisions';\nimport { dispatchHooks } from '../hookDispatch';\nimport type { HookDispatchRequest, HookDispatchResult, HookDispatchScope } from '../hookDispatch/type';\nimport type { HookRuntimeResolver, HookSession } from '../hookRuntime/type';\n\nfunction scopeFor(pi: ExtensionAPI, session: HookSession, ctx: ExtensionContext): HookDispatchScope {\n if (session.parentContext) return { ...session.parentContext, signal: session.signal, operationSignal: ctx.signal };\n return {\n sessionId: ctx.sessionManager.getSessionId(),\n isSubagent: Boolean(process.env[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: ctx.cwd,\n repoRoot: session.config().harness.root ?? ctx.cwd,\n ...(ctx.model ? { model: { provider: ctx.model.provider, id: ctx.model.id } } : {}),\n signal: session.signal,\n operationSignal: ctx.signal,\n async sendMessage(text, delivery) {\n pi.sendMessage({ customType: CONTEXT_MESSAGE_TYPE, content: text, display: true }, { deliverAs: delivery });\n },\n async appendCustomEntry(type, data) {\n pi.appendEntry(type, data);\n },\n };\n}\n\nasync function runPiDispatch(\n pi: ExtensionAPI,\n session: HookSession,\n ctx: ExtensionContext,\n request: HookDispatchRequest,\n statusKey: string,\n statusLabel: string,\n signal?: AbortSignal,\n): Promise<HookDispatchResult> {\n try {\n const scope = scopeFor(pi, session, ctx);\n return await dispatchHooks(\n session,\n { ...scope, operationSignal: signal ?? scope.operationSignal },\n {\n ...request,\n progress: (index, total) => {\n if (ctx.hasUI) ctx.ui.setStatus(statusKey, `${statusLabel} (${index + 1}/${total})...`);\n },\n },\n );\n } finally {\n if (ctx.hasUI) ctx.ui.setStatus(statusKey, undefined);\n }\n}\n\nasync function steerHookFailures(\n pi: ExtensionAPI,\n session: HookSession,\n failures: ReadonlyArray<HookFailure>,\n): Promise<void> {\n if (failures.length === 0) return;\n if (session.parentContext) await session.parentContext.sendMessage(hookFailureMessage(failures), 'steer');\n else\n pi.sendMessage({ customType: FAILURE_MESSAGE_TYPE, content: hookFailureMessage(failures), display: true }, STEER);\n}\n\nfunction createSessionStart(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['session_start'] {\n return (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return undefined;\n const { session, readiness } = runtime;\n const run = async (signal?: AbortSignal, isReady: () => boolean = () => true): Promise<void> => {\n const result = await runPiDispatch(\n pi,\n session,\n ctx,\n { eventName: HOOK_EVENT.sessionStart, event },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:start`,\n 'Running session-start hooks',\n signal,\n );\n signal?.throwIfAborted();\n if (!runtime.isCurrent() || !isReady()) return;\n await steerHookFailures(pi, session, result.failures);\n const context = additionalContextsFrom(result.decisions).join(CONTEXT_SEPARATOR);\n if (context) await scopeFor(pi, session, ctx).sendMessage(context, 'steer');\n };\n return readiness ? readiness.start(ctx, run) : run();\n };\n}\n\nfunction createBeforeAgentStart(resolveRuntime: HookRuntimeResolver): PiEventHandlers['before_agent_start'] {\n return async (_event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n await runtime.readiness?.wait(ctx);\n };\n}\n\nfunction createToolCall(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['tool_call'] {\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return undefined;\n // Readiness is a host gate, not an advisory hook error.\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return undefined;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n { eventName: HOOK_EVENT.preToolUse, event },\n `${STATUS_PREFIX}:${event.toolCallId}:pre`,\n `Running pre-tool hooks for ${event.toolName}`,\n );\n if (!runtime.isCurrent()) return undefined;\n await steerHookFailures(pi, runtime.session, result.failures);\n return result.toolCall;\n };\n}\n\nfunction createToolResult(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['tool_result'] {\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return undefined;\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return undefined;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n { eventName: HOOK_EVENT.postToolUse, event },\n `${STATUS_PREFIX}:${event.toolCallId}:post`,\n `Running post-tool hooks for ${event.toolName}`,\n );\n if (!runtime.isCurrent()) return undefined;\n return result.toolResult;\n };\n}\n\nfunction createAgentSettled(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['agent_settled'] {\n let refusals = 0;\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return;\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n {\n eventName: HOOK_EVENT.stop,\n event,\n extraPayload: { [STOP_HOOK_ACTIVE_FIELD]: refusals > 0 },\n },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:stop`,\n 'Running stop hooks',\n );\n if (!runtime.isCurrent()) return;\n if (result.failures.length > 0)\n pi.sendMessage(\n {\n customType: FAILURE_MESSAGE_TYPE,\n content: hookFailureMessage(result.failures),\n display: true,\n },\n NO_TURN,\n );\n const reason = decisionReason(result.decisions.find(isDenied));\n if (!reason) {\n refusals = 0;\n return;\n }\n if (refusals >= MAX_STOP_REFUSALS) {\n refusals = 0;\n pi.sendMessage(\n {\n customType: FAILURE_MESSAGE_TYPE,\n content: `A Stop hook refused ${String(MAX_STOP_REFUSALS)} stops in a row, so the agent stops here. Its last reason: ${reason}`,\n display: true,\n },\n NO_TURN,\n );\n return;\n }\n refusals += 1;\n pi.sendMessage({ customType: STOP_BLOCK_MESSAGE_TYPE, content: reason, display: true }, FOLLOW_UP_TURN);\n };\n}\n\nexport function createHookHandlers(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers {\n let shutdown: Promise<void> | undefined;\n return {\n session_start: createSessionStart(pi, resolveRuntime),\n before_agent_start: createBeforeAgentStart(resolveRuntime),\n tool_call: createToolCall(pi, resolveRuntime),\n tool_result: createToolResult(pi, resolveRuntime),\n agent_settled: createAgentSettled(pi, resolveRuntime),\n session_shutdown: (_event, ctx) => {\n const current = resolveRuntime();\n if (!current?.isCurrent() || scopeFor(pi, current.session, ctx).isSubagent) return undefined;\n shutdown ??= runSessionEndHooks(pi, current.session, ctx);\n return shutdown;\n },\n };\n}\n\n/** SessionEnd remains plugin-only and once-only while the session is still usable. */\nexport async function runSessionEndHooks(pi: ExtensionAPI, session: HookSession, ctx: ExtensionContext): Promise<void> {\n await runPiDispatch(\n pi,\n session,\n ctx,\n { eventName: HOOK_EVENT.sessionEnd },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:end`,\n 'Running session-end hooks',\n );\n}\n","import { DOOM_CORDIS_SERVER_SERVICES, type DoomCordisServerServices } from '@agimon-ai/doompi-core/cordisHost';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createHookHandlers } from '../../../../../services/hookHandlers';\nimport { createHookBinding } from '../../../../../services/hookRuntime';\nimport {\n DOOM_HOOK_SESSION_SERVICE,\n type HookExtensionOptions,\n type HookRuntime,\n} from '../../../../../services/hookRuntime/type';\n\nexport const createHookPiRoot = ({ pi, options, context }: PiPluginContext<HookExtensionOptions>) => {\n const binding = createHookBinding(options ?? {});\n const runtime = (): HookRuntime | undefined => {\n // The bridge publishes this accessor just before session_start. Never build\n // a second session instance for headless lifecycle handlers.\n const server = context.get(DOOM_CORDIS_SERVER_SERVICES) as DoomCordisServerServices | undefined;\n return server ? server.get<HookRuntime>(DOOM_HOOK_SESSION_SERVICE) : binding.runtime();\n };\n return { value: createHookHandlers(pi, runtime), services: [binding.plugin] };\n};\nexport type HookPiScope = Awaited<ReturnType<typeof createHookPiRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createHookPiRoot } from './_lib/piRoot';\n\nexport default defineRoot(createHookPiRoot);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['agent_settled'] =>\n context.root.agent_settled,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['before_agent_start'] =>\n context.root.before_agent_start,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['session_shutdown'] =>\n context.root.session_shutdown,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['session_start'] =>\n context.root.session_start,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['tool_call'] => context.root.tool_call,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['tool_result'] =>\n context.root.tool_result,\n);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { HOOK_HELP_SKILL, PACKAGE_SOURCE } from '../../../../../constants/hook';\nexport default defineResource({ source: PACKAGE_SOURCE, moduleUrl: import.meta.url, skills: [HOOK_HELP_SKILL] });\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, 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 hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli';\nimport hookToolCall from '../src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli';\nimport hookToolResult from '../src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli';\nimport resourceDoompiUseHook from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof hookAgentSettled> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookSessionShutdown> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof hookToolCall> | OptionsOf<typeof hookToolResult> | OptionsOf<typeof resourceDoompiUseHook>, 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;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-hook', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n events: {\n agent_settled: at(hookAgentSettled, contextSession) as NonNullable<PiPluginContributions['events']>['agent_settled'],\n before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n session_shutdown: at(hookSessionShutdown, contextSession) as NonNullable<PiPluginContributions['events']>['session_shutdown'],\n session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n tool_call: at(hookToolCall, contextSession) as NonNullable<PiPluginContributions['events']>['tool_call'],\n tool_result: at(hookToolResult, contextSession) as NonNullable<PiPluginContributions['events']>['tool_result'],\n },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseHook, contextSession)]; },\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":"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"}
1
+ {"version":3,"file":"pi.cjs","names":["SUBAGENT_ENVIRONMENT_FLAG","CONTEXT_MESSAGE_TYPE","dispatchHooks","hookFailureMessage","FAILURE_MESSAGE_TYPE","STEER","HOOK_EVENT","STATUS_PREFIX","additionalContextsFrom","STOP_HOOK_ACTIVE_FIELD","NO_TURN","decisionReason","isDenied","STOP_BLOCK_MESSAGE_TYPE","FOLLOW_UP_TURN","createHookBinding","DOOM_CORDIS_SERVER_SERVICES","DOOM_HOOK_SESSION_SERVICE","defineRoot","defineCliHook","defineCliHook","defineCliHook","defineCliHook","defineCliHook","defineCliHook","defineResource","PACKAGE_SOURCE","HOOK_HELP_SKILL","definePiExtension","rootSession","composeRootHooks","hookAgentSettled","hookBeforeAgentStart","hookSessionShutdown","hookSessionStart","hookToolCall","hookToolResult","resourceDoompiUseHook"],"sources":["../../src/services/hookHandlers/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli.ts","../../generated/pi.ts"],"sourcesContent":["import type { PiEventHandlers } from '@agimon-ai/doompi-core/piExtension';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n STATUS_PREFIX,\n FAILURE_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n STOP_BLOCK_MESSAGE_TYPE,\n FOLLOW_UP_TURN,\n MAX_STOP_REFUSALS,\n NO_TURN,\n STEER,\n STOP_HOOK_ACTIVE_FIELD,\n SUBAGENT_ENVIRONMENT_FLAG,\n CONTEXT_SEPARATOR,\n} from '../../constants/hookHandlers';\nimport { HOOK_EVENT } from '../../constants/hooks';\nimport type { HookFailure } from '../../types/hooks';\nimport { additionalContextsFrom, decisionReason, hookFailureMessage, isDenied } from '../hookDecisions';\nimport { dispatchHooks } from '../hookDispatch';\nimport type { HookDispatchRequest, HookDispatchResult, HookDispatchScope } from '../hookDispatch/type';\nimport type { HookRuntimeResolver, HookSession } from '../hookRuntime/type';\n\nfunction scopeFor(pi: ExtensionAPI, session: HookSession, ctx: ExtensionContext): HookDispatchScope {\n if (session.parentContext) return { ...session.parentContext, signal: session.signal, operationSignal: ctx.signal };\n return {\n sessionId: ctx.sessionManager.getSessionId(),\n isSubagent: Boolean(process.env[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: ctx.cwd,\n repoRoot: session.config().harness.root ?? ctx.cwd,\n ...(ctx.model ? { model: { provider: ctx.model.provider, id: ctx.model.id } } : {}),\n signal: session.signal,\n operationSignal: ctx.signal,\n async sendMessage(text, delivery) {\n pi.sendMessage({ customType: CONTEXT_MESSAGE_TYPE, content: text, display: true }, { deliverAs: delivery });\n },\n async appendCustomEntry(type, data) {\n pi.appendEntry(type, data);\n },\n };\n}\n\nasync function runPiDispatch(\n pi: ExtensionAPI,\n session: HookSession,\n ctx: ExtensionContext,\n request: HookDispatchRequest,\n statusKey: string,\n statusLabel: string,\n signal?: AbortSignal,\n): Promise<HookDispatchResult> {\n try {\n const scope = scopeFor(pi, session, ctx);\n return await dispatchHooks(\n session,\n { ...scope, operationSignal: signal ?? scope.operationSignal },\n {\n ...request,\n progress: (index, total) => {\n if (ctx.hasUI) ctx.ui.setStatus(statusKey, `${statusLabel} (${index + 1}/${total})...`);\n },\n },\n );\n } finally {\n if (ctx.hasUI) ctx.ui.setStatus(statusKey, undefined);\n }\n}\n\nasync function steerHookFailures(\n pi: ExtensionAPI,\n session: HookSession,\n failures: ReadonlyArray<HookFailure>,\n): Promise<void> {\n if (failures.length === 0) return;\n if (session.parentContext) await session.parentContext.sendMessage(hookFailureMessage(failures), 'steer');\n else\n pi.sendMessage({ customType: FAILURE_MESSAGE_TYPE, content: hookFailureMessage(failures), display: true }, STEER);\n}\n\nfunction createSessionStart(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['session_start'] {\n return (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return undefined;\n const { session, readiness } = runtime;\n const run = async (signal?: AbortSignal, isReady: () => boolean = () => true): Promise<void> => {\n await session.prepare();\n const result = await runPiDispatch(\n pi,\n session,\n ctx,\n { eventName: HOOK_EVENT.sessionStart, event },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:start`,\n 'Running session-start hooks',\n signal,\n );\n signal?.throwIfAborted();\n if (!runtime.isCurrent() || !isReady()) return;\n await steerHookFailures(pi, session, result.failures);\n const context = additionalContextsFrom(result.decisions).join(CONTEXT_SEPARATOR);\n if (context) await scopeFor(pi, session, ctx).sendMessage(context, 'steer');\n };\n return readiness ? readiness.start(ctx, run) : run();\n };\n}\n\nfunction createBeforeAgentStart(resolveRuntime: HookRuntimeResolver): PiEventHandlers['before_agent_start'] {\n return async (_event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n await runtime.session.prepare(\n runtime.session.parentContext?.isSubagent ?? Boolean(process.env[SUBAGENT_ENVIRONMENT_FLAG]),\n );\n await runtime.readiness?.wait(ctx);\n };\n}\n\nfunction createToolCall(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['tool_call'] {\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return undefined;\n // Readiness is a host gate, not an advisory hook error.\n try {\n await runtime.session.prepare(scopeFor(pi, runtime.session, ctx).isSubagent);\n await runtime.readiness?.wait(ctx);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n try {\n pi.sendMessage({ customType: FAILURE_MESSAGE_TYPE, content: reason, display: true }, STEER);\n } catch {\n // The tool block still carries recovery when prompt admission is unavailable.\n }\n return { block: true, reason };\n }\n if (!runtime.isCurrent()) return undefined;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n { eventName: HOOK_EVENT.preToolUse, event },\n `${STATUS_PREFIX}:${event.toolCallId}:pre`,\n `Running pre-tool hooks for ${event.toolName}`,\n );\n if (!runtime.isCurrent()) return undefined;\n await steerHookFailures(pi, runtime.session, result.failures);\n return result.toolCall;\n };\n}\n\nfunction createToolResult(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['tool_result'] {\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return undefined;\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return undefined;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n { eventName: HOOK_EVENT.postToolUse, event },\n `${STATUS_PREFIX}:${event.toolCallId}:post`,\n `Running post-tool hooks for ${event.toolName}`,\n );\n if (!runtime.isCurrent()) return undefined;\n return result.toolResult;\n };\n}\n\nfunction createAgentSettled(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['agent_settled'] {\n let refusals = 0;\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return;\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n {\n eventName: HOOK_EVENT.stop,\n event,\n extraPayload: { [STOP_HOOK_ACTIVE_FIELD]: refusals > 0 },\n },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:stop`,\n 'Running stop hooks',\n );\n if (!runtime.isCurrent()) return;\n if (result.failures.length > 0)\n pi.sendMessage(\n {\n customType: FAILURE_MESSAGE_TYPE,\n content: hookFailureMessage(result.failures),\n display: true,\n },\n NO_TURN,\n );\n const reason = decisionReason(result.decisions.find(isDenied));\n if (!reason) {\n refusals = 0;\n return;\n }\n if (refusals >= MAX_STOP_REFUSALS) {\n refusals = 0;\n pi.sendMessage(\n {\n customType: FAILURE_MESSAGE_TYPE,\n content: `A Stop hook refused ${String(MAX_STOP_REFUSALS)} stops in a row, so the agent stops here. Its last reason: ${reason}`,\n display: true,\n },\n NO_TURN,\n );\n return;\n }\n refusals += 1;\n pi.sendMessage({ customType: STOP_BLOCK_MESSAGE_TYPE, content: reason, display: true }, FOLLOW_UP_TURN);\n };\n}\n\nexport function createHookHandlers(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers {\n let shutdown: Promise<void> | undefined;\n return {\n session_start: createSessionStart(pi, resolveRuntime),\n before_agent_start: createBeforeAgentStart(resolveRuntime),\n tool_call: createToolCall(pi, resolveRuntime),\n tool_result: createToolResult(pi, resolveRuntime),\n agent_settled: createAgentSettled(pi, resolveRuntime),\n session_shutdown: (_event, ctx) => {\n const current = resolveRuntime();\n if (!current?.isCurrent() || scopeFor(pi, current.session, ctx).isSubagent) return undefined;\n shutdown ??= runSessionEndHooks(pi, current.session, ctx);\n return shutdown;\n },\n };\n}\n\n/** SessionEnd remains plugin-only and once-only while the session is still usable. */\nexport async function runSessionEndHooks(pi: ExtensionAPI, session: HookSession, ctx: ExtensionContext): Promise<void> {\n await runPiDispatch(\n pi,\n session,\n ctx,\n { eventName: HOOK_EVENT.sessionEnd },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:end`,\n 'Running session-end hooks',\n );\n}\n","import { DOOM_CORDIS_SERVER_SERVICES, type DoomCordisServerServices } from '@agimon-ai/doompi-core/cordisHost';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createHookHandlers } from '../../../../../services/hookHandlers';\nimport { createHookBinding } from '../../../../../services/hookRuntime';\nimport {\n DOOM_HOOK_SESSION_SERVICE,\n type HookExtensionOptions,\n type HookRuntime,\n} from '../../../../../services/hookRuntime/type';\n\nexport const createHookPiRoot = ({ pi, options, context }: PiPluginContext<HookExtensionOptions>) => {\n const binding = createHookBinding(options ?? {});\n const runtime = (): HookRuntime | undefined => {\n // The bridge publishes this accessor just before session_start. Never build\n // a second session instance for headless lifecycle handlers.\n const server = context.get(DOOM_CORDIS_SERVER_SERVICES) as DoomCordisServerServices | undefined;\n return server ? server.get<HookRuntime>(DOOM_HOOK_SESSION_SERVICE) : binding.runtime();\n };\n return { value: createHookHandlers(pi, runtime), services: [binding.plugin] };\n};\nexport type HookPiScope = Awaited<ReturnType<typeof createHookPiRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createHookPiRoot } from './_lib/piRoot';\n\nexport default defineRoot(createHookPiRoot);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['agent_settled'] =>\n context.root.agent_settled,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['before_agent_start'] =>\n context.root.before_agent_start,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['session_shutdown'] =>\n context.root.session_shutdown,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['session_start'] =>\n context.root.session_start,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['tool_call'] => context.root.tool_call,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['tool_result'] =>\n context.root.tool_result,\n);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { HOOK_HELP_SKILL, PACKAGE_SOURCE } from '../../../../../constants/hook';\nexport default defineResource({ source: PACKAGE_SOURCE, moduleUrl: import.meta.url, skills: [HOOK_HELP_SKILL] });\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, 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 hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli';\nimport hookToolCall from '../src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli';\nimport hookToolResult from '../src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli';\nimport resourceDoompiUseHook from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof hookAgentSettled> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookSessionShutdown> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof hookToolCall> | OptionsOf<typeof hookToolResult> | OptionsOf<typeof resourceDoompiUseHook>, 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;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-hook', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n events: {\n agent_settled: at(hookAgentSettled, contextSession) as NonNullable<PiPluginContributions['events']>['agent_settled'],\n before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n session_shutdown: at(hookSessionShutdown, contextSession) as NonNullable<PiPluginContributions['events']>['session_shutdown'],\n session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n tool_call: at(hookToolCall, contextSession) as NonNullable<PiPluginContributions['events']>['tool_call'],\n tool_result: at(hookToolResult, contextSession) as NonNullable<PiPluginContributions['events']>['tool_result'],\n },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseHook, contextSession)]; },\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { s as HookExtensionOptions } from "../index-Dhd9UC9g.mjs";
1
+ import { s as HookExtensionOptions } from "../index-C3Xt9wLJ.mjs";
2
2
  //#region generated/pi.d.ts
3
3
  export declare const extension: import("@agimon-ai/doompi-core/runtimePiExtension").DefinedPiExtension<HookExtensionOptions>;
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
- import { b as isDenied, g as decisionReason, h as additionalContextsFrom, n as HOOK_EVENT, y as hookFailureMessage } from "../hookModules-DAFDGPUC.mjs";
2
- import { a as dispatchHooks, c as FAILURE_MESSAGE_TYPE, d as STATUS_PREFIX, f as STEER, h as SUBAGENT_ENVIRONMENT_FLAG, i as PACKAGE_SOURCE, l as FOLLOW_UP_TURN, m as STOP_HOOK_ACTIVE_FIELD, n as DOOM_HOOK_SESSION_SERVICE, p as STOP_BLOCK_MESSAGE_TYPE, r as HOOK_HELP_SKILL, s as CONTEXT_MESSAGE_TYPE, t as createHookBinding, u as NO_TURN } from "../hookRuntime-D27m9ndl.mjs";
1
+ import { b as isDenied, g as decisionReason, h as additionalContextsFrom, n as HOOK_EVENT, y as hookFailureMessage } from "../hookModules-CjBUOlER.mjs";
2
+ import { a as dispatchHooks, c as FAILURE_MESSAGE_TYPE, d as STATUS_PREFIX, f as STEER, h as SUBAGENT_ENVIRONMENT_FLAG, i as PACKAGE_SOURCE, l as FOLLOW_UP_TURN, m as STOP_HOOK_ACTIVE_FIELD, n as DOOM_HOOK_SESSION_SERVICE, p as STOP_BLOCK_MESSAGE_TYPE, r as HOOK_HELP_SKILL, s as CONTEXT_MESSAGE_TYPE, t as createHookBinding, u as NO_TURN } from "../hookRuntime-BouwbVig.mjs";
3
3
  import { definePiExtension } from "@agimon-ai/doompi-core/piExtension";
4
4
  import { composeRootHooks, defineCliHook, defineResource, defineRoot } from "@agimon-ai/doompi-core/extensionFile";
5
5
  import { DOOM_CORDIS_SERVER_SERVICES } from "@agimon-ai/doompi-core/cordisHost";
@@ -64,6 +64,7 @@ function createSessionStart(pi, resolveRuntime) {
64
64
  if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return void 0;
65
65
  const { session, readiness } = runtime;
66
66
  const run = async (signal, isReady = () => true) => {
67
+ await session.prepare();
67
68
  const result = await runPiDispatch(pi, session, ctx, {
68
69
  eventName: HOOK_EVENT.sessionStart,
69
70
  event
@@ -81,6 +82,7 @@ function createBeforeAgentStart(resolveRuntime) {
81
82
  return async (_event, ctx) => {
82
83
  const runtime = resolveRuntime();
83
84
  if (!runtime?.isCurrent()) return;
85
+ await runtime.session.prepare(runtime.session.parentContext?.isSubagent ?? Boolean(process.env["PI_SUBAGENT_CHILD"]));
84
86
  await runtime.readiness?.wait(ctx);
85
87
  };
86
88
  }
@@ -88,7 +90,23 @@ function createToolCall(pi, resolveRuntime) {
88
90
  return async (event, ctx) => {
89
91
  const runtime = resolveRuntime();
90
92
  if (!runtime?.isCurrent()) return void 0;
91
- await runtime.readiness?.wait(ctx);
93
+ try {
94
+ await runtime.session.prepare(scopeFor(pi, runtime.session, ctx).isSubagent);
95
+ await runtime.readiness?.wait(ctx);
96
+ } catch (error) {
97
+ const reason = error instanceof Error ? error.message : String(error);
98
+ try {
99
+ pi.sendMessage({
100
+ customType: FAILURE_MESSAGE_TYPE,
101
+ content: reason,
102
+ display: true
103
+ }, STEER);
104
+ } catch {}
105
+ return {
106
+ block: true,
107
+ reason
108
+ };
109
+ }
92
110
  if (!runtime.isCurrent()) return void 0;
93
111
  const result = await runPiDispatch(pi, runtime.session, ctx, {
94
112
  eventName: HOOK_EVENT.preToolUse,
@@ -1 +1 @@
1
- {"version":3,"file":"pi.mjs","names":["rootSession","hookAgentSettled","hookBeforeAgentStart","hookSessionShutdown","hookSessionStart","hookToolCall","hookToolResult","resourceDoompiUseHook"],"sources":["../../src/services/hookHandlers/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli.ts","../../generated/pi.ts"],"sourcesContent":["import type { PiEventHandlers } from '@agimon-ai/doompi-core/piExtension';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n STATUS_PREFIX,\n FAILURE_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n STOP_BLOCK_MESSAGE_TYPE,\n FOLLOW_UP_TURN,\n MAX_STOP_REFUSALS,\n NO_TURN,\n STEER,\n STOP_HOOK_ACTIVE_FIELD,\n SUBAGENT_ENVIRONMENT_FLAG,\n CONTEXT_SEPARATOR,\n} from '../../constants/hookHandlers';\nimport { HOOK_EVENT } from '../../constants/hooks';\nimport type { HookFailure } from '../../types/hooks';\nimport { additionalContextsFrom, decisionReason, hookFailureMessage, isDenied } from '../hookDecisions';\nimport { dispatchHooks } from '../hookDispatch';\nimport type { HookDispatchRequest, HookDispatchResult, HookDispatchScope } from '../hookDispatch/type';\nimport type { HookRuntimeResolver, HookSession } from '../hookRuntime/type';\n\nfunction scopeFor(pi: ExtensionAPI, session: HookSession, ctx: ExtensionContext): HookDispatchScope {\n if (session.parentContext) return { ...session.parentContext, signal: session.signal, operationSignal: ctx.signal };\n return {\n sessionId: ctx.sessionManager.getSessionId(),\n isSubagent: Boolean(process.env[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: ctx.cwd,\n repoRoot: session.config().harness.root ?? ctx.cwd,\n ...(ctx.model ? { model: { provider: ctx.model.provider, id: ctx.model.id } } : {}),\n signal: session.signal,\n operationSignal: ctx.signal,\n async sendMessage(text, delivery) {\n pi.sendMessage({ customType: CONTEXT_MESSAGE_TYPE, content: text, display: true }, { deliverAs: delivery });\n },\n async appendCustomEntry(type, data) {\n pi.appendEntry(type, data);\n },\n };\n}\n\nasync function runPiDispatch(\n pi: ExtensionAPI,\n session: HookSession,\n ctx: ExtensionContext,\n request: HookDispatchRequest,\n statusKey: string,\n statusLabel: string,\n signal?: AbortSignal,\n): Promise<HookDispatchResult> {\n try {\n const scope = scopeFor(pi, session, ctx);\n return await dispatchHooks(\n session,\n { ...scope, operationSignal: signal ?? scope.operationSignal },\n {\n ...request,\n progress: (index, total) => {\n if (ctx.hasUI) ctx.ui.setStatus(statusKey, `${statusLabel} (${index + 1}/${total})...`);\n },\n },\n );\n } finally {\n if (ctx.hasUI) ctx.ui.setStatus(statusKey, undefined);\n }\n}\n\nasync function steerHookFailures(\n pi: ExtensionAPI,\n session: HookSession,\n failures: ReadonlyArray<HookFailure>,\n): Promise<void> {\n if (failures.length === 0) return;\n if (session.parentContext) await session.parentContext.sendMessage(hookFailureMessage(failures), 'steer');\n else\n pi.sendMessage({ customType: FAILURE_MESSAGE_TYPE, content: hookFailureMessage(failures), display: true }, STEER);\n}\n\nfunction createSessionStart(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['session_start'] {\n return (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return undefined;\n const { session, readiness } = runtime;\n const run = async (signal?: AbortSignal, isReady: () => boolean = () => true): Promise<void> => {\n const result = await runPiDispatch(\n pi,\n session,\n ctx,\n { eventName: HOOK_EVENT.sessionStart, event },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:start`,\n 'Running session-start hooks',\n signal,\n );\n signal?.throwIfAborted();\n if (!runtime.isCurrent() || !isReady()) return;\n await steerHookFailures(pi, session, result.failures);\n const context = additionalContextsFrom(result.decisions).join(CONTEXT_SEPARATOR);\n if (context) await scopeFor(pi, session, ctx).sendMessage(context, 'steer');\n };\n return readiness ? readiness.start(ctx, run) : run();\n };\n}\n\nfunction createBeforeAgentStart(resolveRuntime: HookRuntimeResolver): PiEventHandlers['before_agent_start'] {\n return async (_event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n await runtime.readiness?.wait(ctx);\n };\n}\n\nfunction createToolCall(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['tool_call'] {\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return undefined;\n // Readiness is a host gate, not an advisory hook error.\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return undefined;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n { eventName: HOOK_EVENT.preToolUse, event },\n `${STATUS_PREFIX}:${event.toolCallId}:pre`,\n `Running pre-tool hooks for ${event.toolName}`,\n );\n if (!runtime.isCurrent()) return undefined;\n await steerHookFailures(pi, runtime.session, result.failures);\n return result.toolCall;\n };\n}\n\nfunction createToolResult(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['tool_result'] {\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return undefined;\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return undefined;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n { eventName: HOOK_EVENT.postToolUse, event },\n `${STATUS_PREFIX}:${event.toolCallId}:post`,\n `Running post-tool hooks for ${event.toolName}`,\n );\n if (!runtime.isCurrent()) return undefined;\n return result.toolResult;\n };\n}\n\nfunction createAgentSettled(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['agent_settled'] {\n let refusals = 0;\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return;\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n {\n eventName: HOOK_EVENT.stop,\n event,\n extraPayload: { [STOP_HOOK_ACTIVE_FIELD]: refusals > 0 },\n },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:stop`,\n 'Running stop hooks',\n );\n if (!runtime.isCurrent()) return;\n if (result.failures.length > 0)\n pi.sendMessage(\n {\n customType: FAILURE_MESSAGE_TYPE,\n content: hookFailureMessage(result.failures),\n display: true,\n },\n NO_TURN,\n );\n const reason = decisionReason(result.decisions.find(isDenied));\n if (!reason) {\n refusals = 0;\n return;\n }\n if (refusals >= MAX_STOP_REFUSALS) {\n refusals = 0;\n pi.sendMessage(\n {\n customType: FAILURE_MESSAGE_TYPE,\n content: `A Stop hook refused ${String(MAX_STOP_REFUSALS)} stops in a row, so the agent stops here. Its last reason: ${reason}`,\n display: true,\n },\n NO_TURN,\n );\n return;\n }\n refusals += 1;\n pi.sendMessage({ customType: STOP_BLOCK_MESSAGE_TYPE, content: reason, display: true }, FOLLOW_UP_TURN);\n };\n}\n\nexport function createHookHandlers(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers {\n let shutdown: Promise<void> | undefined;\n return {\n session_start: createSessionStart(pi, resolveRuntime),\n before_agent_start: createBeforeAgentStart(resolveRuntime),\n tool_call: createToolCall(pi, resolveRuntime),\n tool_result: createToolResult(pi, resolveRuntime),\n agent_settled: createAgentSettled(pi, resolveRuntime),\n session_shutdown: (_event, ctx) => {\n const current = resolveRuntime();\n if (!current?.isCurrent() || scopeFor(pi, current.session, ctx).isSubagent) return undefined;\n shutdown ??= runSessionEndHooks(pi, current.session, ctx);\n return shutdown;\n },\n };\n}\n\n/** SessionEnd remains plugin-only and once-only while the session is still usable. */\nexport async function runSessionEndHooks(pi: ExtensionAPI, session: HookSession, ctx: ExtensionContext): Promise<void> {\n await runPiDispatch(\n pi,\n session,\n ctx,\n { eventName: HOOK_EVENT.sessionEnd },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:end`,\n 'Running session-end hooks',\n );\n}\n","import { DOOM_CORDIS_SERVER_SERVICES, type DoomCordisServerServices } from '@agimon-ai/doompi-core/cordisHost';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createHookHandlers } from '../../../../../services/hookHandlers';\nimport { createHookBinding } from '../../../../../services/hookRuntime';\nimport {\n DOOM_HOOK_SESSION_SERVICE,\n type HookExtensionOptions,\n type HookRuntime,\n} from '../../../../../services/hookRuntime/type';\n\nexport const createHookPiRoot = ({ pi, options, context }: PiPluginContext<HookExtensionOptions>) => {\n const binding = createHookBinding(options ?? {});\n const runtime = (): HookRuntime | undefined => {\n // The bridge publishes this accessor just before session_start. Never build\n // a second session instance for headless lifecycle handlers.\n const server = context.get(DOOM_CORDIS_SERVER_SERVICES) as DoomCordisServerServices | undefined;\n return server ? server.get<HookRuntime>(DOOM_HOOK_SESSION_SERVICE) : binding.runtime();\n };\n return { value: createHookHandlers(pi, runtime), services: [binding.plugin] };\n};\nexport type HookPiScope = Awaited<ReturnType<typeof createHookPiRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createHookPiRoot } from './_lib/piRoot';\n\nexport default defineRoot(createHookPiRoot);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['agent_settled'] =>\n context.root.agent_settled,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['before_agent_start'] =>\n context.root.before_agent_start,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['session_shutdown'] =>\n context.root.session_shutdown,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['session_start'] =>\n context.root.session_start,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['tool_call'] => context.root.tool_call,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['tool_result'] =>\n context.root.tool_result,\n);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { HOOK_HELP_SKILL, PACKAGE_SOURCE } from '../../../../../constants/hook';\nexport default defineResource({ source: PACKAGE_SOURCE, moduleUrl: import.meta.url, skills: [HOOK_HELP_SKILL] });\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, 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 hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli';\nimport hookToolCall from '../src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli';\nimport hookToolResult from '../src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli';\nimport resourceDoompiUseHook from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof hookAgentSettled> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookSessionShutdown> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof hookToolCall> | OptionsOf<typeof hookToolResult> | OptionsOf<typeof resourceDoompiUseHook>, 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;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-hook', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n events: {\n agent_settled: at(hookAgentSettled, contextSession) as NonNullable<PiPluginContributions['events']>['agent_settled'],\n before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n session_shutdown: at(hookSessionShutdown, contextSession) as NonNullable<PiPluginContributions['events']>['session_shutdown'],\n session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n tool_call: at(hookToolCall, contextSession) as NonNullable<PiPluginContributions['events']>['tool_call'],\n tool_result: at(hookToolResult, contextSession) as NonNullable<PiPluginContributions['events']>['tool_result'],\n },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseHook, contextSession)]; },\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":"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"}
1
+ {"version":3,"file":"pi.mjs","names":["rootSession","hookAgentSettled","hookBeforeAgentStart","hookSessionShutdown","hookSessionStart","hookToolCall","hookToolResult","resourceDoompiUseHook"],"sources":["../../src/services/hookHandlers/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli.ts","../../generated/pi.ts"],"sourcesContent":["import type { PiEventHandlers } from '@agimon-ai/doompi-core/piExtension';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n STATUS_PREFIX,\n FAILURE_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n STOP_BLOCK_MESSAGE_TYPE,\n FOLLOW_UP_TURN,\n MAX_STOP_REFUSALS,\n NO_TURN,\n STEER,\n STOP_HOOK_ACTIVE_FIELD,\n SUBAGENT_ENVIRONMENT_FLAG,\n CONTEXT_SEPARATOR,\n} from '../../constants/hookHandlers';\nimport { HOOK_EVENT } from '../../constants/hooks';\nimport type { HookFailure } from '../../types/hooks';\nimport { additionalContextsFrom, decisionReason, hookFailureMessage, isDenied } from '../hookDecisions';\nimport { dispatchHooks } from '../hookDispatch';\nimport type { HookDispatchRequest, HookDispatchResult, HookDispatchScope } from '../hookDispatch/type';\nimport type { HookRuntimeResolver, HookSession } from '../hookRuntime/type';\n\nfunction scopeFor(pi: ExtensionAPI, session: HookSession, ctx: ExtensionContext): HookDispatchScope {\n if (session.parentContext) return { ...session.parentContext, signal: session.signal, operationSignal: ctx.signal };\n return {\n sessionId: ctx.sessionManager.getSessionId(),\n isSubagent: Boolean(process.env[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: ctx.cwd,\n repoRoot: session.config().harness.root ?? ctx.cwd,\n ...(ctx.model ? { model: { provider: ctx.model.provider, id: ctx.model.id } } : {}),\n signal: session.signal,\n operationSignal: ctx.signal,\n async sendMessage(text, delivery) {\n pi.sendMessage({ customType: CONTEXT_MESSAGE_TYPE, content: text, display: true }, { deliverAs: delivery });\n },\n async appendCustomEntry(type, data) {\n pi.appendEntry(type, data);\n },\n };\n}\n\nasync function runPiDispatch(\n pi: ExtensionAPI,\n session: HookSession,\n ctx: ExtensionContext,\n request: HookDispatchRequest,\n statusKey: string,\n statusLabel: string,\n signal?: AbortSignal,\n): Promise<HookDispatchResult> {\n try {\n const scope = scopeFor(pi, session, ctx);\n return await dispatchHooks(\n session,\n { ...scope, operationSignal: signal ?? scope.operationSignal },\n {\n ...request,\n progress: (index, total) => {\n if (ctx.hasUI) ctx.ui.setStatus(statusKey, `${statusLabel} (${index + 1}/${total})...`);\n },\n },\n );\n } finally {\n if (ctx.hasUI) ctx.ui.setStatus(statusKey, undefined);\n }\n}\n\nasync function steerHookFailures(\n pi: ExtensionAPI,\n session: HookSession,\n failures: ReadonlyArray<HookFailure>,\n): Promise<void> {\n if (failures.length === 0) return;\n if (session.parentContext) await session.parentContext.sendMessage(hookFailureMessage(failures), 'steer');\n else\n pi.sendMessage({ customType: FAILURE_MESSAGE_TYPE, content: hookFailureMessage(failures), display: true }, STEER);\n}\n\nfunction createSessionStart(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['session_start'] {\n return (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return undefined;\n const { session, readiness } = runtime;\n const run = async (signal?: AbortSignal, isReady: () => boolean = () => true): Promise<void> => {\n await session.prepare();\n const result = await runPiDispatch(\n pi,\n session,\n ctx,\n { eventName: HOOK_EVENT.sessionStart, event },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:start`,\n 'Running session-start hooks',\n signal,\n );\n signal?.throwIfAborted();\n if (!runtime.isCurrent() || !isReady()) return;\n await steerHookFailures(pi, session, result.failures);\n const context = additionalContextsFrom(result.decisions).join(CONTEXT_SEPARATOR);\n if (context) await scopeFor(pi, session, ctx).sendMessage(context, 'steer');\n };\n return readiness ? readiness.start(ctx, run) : run();\n };\n}\n\nfunction createBeforeAgentStart(resolveRuntime: HookRuntimeResolver): PiEventHandlers['before_agent_start'] {\n return async (_event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n await runtime.session.prepare(\n runtime.session.parentContext?.isSubagent ?? Boolean(process.env[SUBAGENT_ENVIRONMENT_FLAG]),\n );\n await runtime.readiness?.wait(ctx);\n };\n}\n\nfunction createToolCall(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['tool_call'] {\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return undefined;\n // Readiness is a host gate, not an advisory hook error.\n try {\n await runtime.session.prepare(scopeFor(pi, runtime.session, ctx).isSubagent);\n await runtime.readiness?.wait(ctx);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n try {\n pi.sendMessage({ customType: FAILURE_MESSAGE_TYPE, content: reason, display: true }, STEER);\n } catch {\n // The tool block still carries recovery when prompt admission is unavailable.\n }\n return { block: true, reason };\n }\n if (!runtime.isCurrent()) return undefined;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n { eventName: HOOK_EVENT.preToolUse, event },\n `${STATUS_PREFIX}:${event.toolCallId}:pre`,\n `Running pre-tool hooks for ${event.toolName}`,\n );\n if (!runtime.isCurrent()) return undefined;\n await steerHookFailures(pi, runtime.session, result.failures);\n return result.toolCall;\n };\n}\n\nfunction createToolResult(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['tool_result'] {\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return undefined;\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return undefined;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n { eventName: HOOK_EVENT.postToolUse, event },\n `${STATUS_PREFIX}:${event.toolCallId}:post`,\n `Running post-tool hooks for ${event.toolName}`,\n );\n if (!runtime.isCurrent()) return undefined;\n return result.toolResult;\n };\n}\n\nfunction createAgentSettled(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers['agent_settled'] {\n let refusals = 0;\n return async (event, ctx) => {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return;\n await runtime.readiness?.wait(ctx);\n if (!runtime.isCurrent()) return;\n const result = await runPiDispatch(\n pi,\n runtime.session,\n ctx,\n {\n eventName: HOOK_EVENT.stop,\n event,\n extraPayload: { [STOP_HOOK_ACTIVE_FIELD]: refusals > 0 },\n },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:stop`,\n 'Running stop hooks',\n );\n if (!runtime.isCurrent()) return;\n if (result.failures.length > 0)\n pi.sendMessage(\n {\n customType: FAILURE_MESSAGE_TYPE,\n content: hookFailureMessage(result.failures),\n display: true,\n },\n NO_TURN,\n );\n const reason = decisionReason(result.decisions.find(isDenied));\n if (!reason) {\n refusals = 0;\n return;\n }\n if (refusals >= MAX_STOP_REFUSALS) {\n refusals = 0;\n pi.sendMessage(\n {\n customType: FAILURE_MESSAGE_TYPE,\n content: `A Stop hook refused ${String(MAX_STOP_REFUSALS)} stops in a row, so the agent stops here. Its last reason: ${reason}`,\n display: true,\n },\n NO_TURN,\n );\n return;\n }\n refusals += 1;\n pi.sendMessage({ customType: STOP_BLOCK_MESSAGE_TYPE, content: reason, display: true }, FOLLOW_UP_TURN);\n };\n}\n\nexport function createHookHandlers(pi: ExtensionAPI, resolveRuntime: HookRuntimeResolver): PiEventHandlers {\n let shutdown: Promise<void> | undefined;\n return {\n session_start: createSessionStart(pi, resolveRuntime),\n before_agent_start: createBeforeAgentStart(resolveRuntime),\n tool_call: createToolCall(pi, resolveRuntime),\n tool_result: createToolResult(pi, resolveRuntime),\n agent_settled: createAgentSettled(pi, resolveRuntime),\n session_shutdown: (_event, ctx) => {\n const current = resolveRuntime();\n if (!current?.isCurrent() || scopeFor(pi, current.session, ctx).isSubagent) return undefined;\n shutdown ??= runSessionEndHooks(pi, current.session, ctx);\n return shutdown;\n },\n };\n}\n\n/** SessionEnd remains plugin-only and once-only while the session is still usable. */\nexport async function runSessionEndHooks(pi: ExtensionAPI, session: HookSession, ctx: ExtensionContext): Promise<void> {\n await runPiDispatch(\n pi,\n session,\n ctx,\n { eventName: HOOK_EVENT.sessionEnd },\n `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:end`,\n 'Running session-end hooks',\n );\n}\n","import { DOOM_CORDIS_SERVER_SERVICES, type DoomCordisServerServices } from '@agimon-ai/doompi-core/cordisHost';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createHookHandlers } from '../../../../../services/hookHandlers';\nimport { createHookBinding } from '../../../../../services/hookRuntime';\nimport {\n DOOM_HOOK_SESSION_SERVICE,\n type HookExtensionOptions,\n type HookRuntime,\n} from '../../../../../services/hookRuntime/type';\n\nexport const createHookPiRoot = ({ pi, options, context }: PiPluginContext<HookExtensionOptions>) => {\n const binding = createHookBinding(options ?? {});\n const runtime = (): HookRuntime | undefined => {\n // The bridge publishes this accessor just before session_start. Never build\n // a second session instance for headless lifecycle handlers.\n const server = context.get(DOOM_CORDIS_SERVER_SERVICES) as DoomCordisServerServices | undefined;\n return server ? server.get<HookRuntime>(DOOM_HOOK_SESSION_SERVICE) : binding.runtime();\n };\n return { value: createHookHandlers(pi, runtime), services: [binding.plugin] };\n};\nexport type HookPiScope = Awaited<ReturnType<typeof createHookPiRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createHookPiRoot } from './_lib/piRoot';\n\nexport default defineRoot(createHookPiRoot);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['agent_settled'] =>\n context.root.agent_settled,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['before_agent_start'] =>\n context.root.before_agent_start,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['session_shutdown'] =>\n context.root.session_shutdown,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['session_start'] =>\n context.root.session_start,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['tool_call'] => context.root.tool_call,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiEventHandlers, PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { HookPiScope } from '../_lib/piRoot';\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<unknown>, HookPiScope>): PiEventHandlers['tool_result'] =>\n context.root.tool_result,\n);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { HOOK_HELP_SKILL, PACKAGE_SOURCE } from '../../../../../constants/hook';\nexport default defineResource({ source: PACKAGE_SOURCE, moduleUrl: import.meta.url, skills: [HOOK_HELP_SKILL] });\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, 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 hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.cli';\nimport hookToolCall from '../src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli';\nimport hookToolResult from '../src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli';\nimport resourceDoompiUseHook from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof hookAgentSettled> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookSessionShutdown> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof hookToolCall> | OptionsOf<typeof hookToolResult> | OptionsOf<typeof resourceDoompiUseHook>, 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;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-hook', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n events: {\n agent_settled: at(hookAgentSettled, contextSession) as NonNullable<PiPluginContributions['events']>['agent_settled'],\n before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n session_shutdown: at(hookSessionShutdown, contextSession) as NonNullable<PiPluginContributions['events']>['session_shutdown'],\n session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n tool_call: at(hookToolCall, contextSession) as NonNullable<PiPluginContributions['events']>['tool_call'],\n tool_result: at(hookToolResult, contextSession) as NonNullable<PiPluginContributions['events']>['tool_result'],\n },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseHook, contextSession)]; },\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":"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"}
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_hookModules = require("../hookModules-hfDQUKiA.cjs");
6
- const require_hookRuntime = require("../hookRuntime-BLFf_6_E.cjs");
5
+ const require_hookModules = require("../hookModules-DShU8Nls.cjs");
6
+ const require_hookRuntime = require("../hookRuntime-BDfSkRP-.cjs");
7
7
  let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
8
8
  let _agimon_ai_doompi_core_serverFacet = require("@agimon-ai/doompi-core/serverFacet");
9
9
  let _agimon_ai_doompi_core_headless = require("@agimon-ai/doompi-core/headless");
@@ -37,7 +37,11 @@ function createServerHooks(resolveRuntime) {
37
37
  return {
38
38
  beforeAgentStart: {
39
39
  event: "before_agent_start",
40
- handle: (event, execution) => execution.session.appendCustomEntry("doom-hook", hookEntry(event))
40
+ async handle(event, execution) {
41
+ const runtime = resolveRuntime();
42
+ if (runtime?.isCurrent()) await runtime.session.prepare(scopeFor(runtime, execution).isSubagent);
43
+ await execution.session.appendCustomEntry("doom-hook", hookEntry(event));
44
+ }
41
45
  },
42
46
  toolCall: {
43
47
  event: "tool_call",
@@ -45,6 +49,11 @@ function createServerHooks(resolveRuntime) {
45
49
  const runtime = resolveRuntime();
46
50
  if (!runtime?.isCurrent()) return;
47
51
  const scope = scopeFor(runtime, execution);
52
+ try {
53
+ await runtime.session.prepare(scope.isSubagent);
54
+ } catch (error) {
55
+ return { block: { reason: error instanceof Error ? error.message : String(error) } };
56
+ }
48
57
  const native = {
49
58
  type: "tool_call",
50
59
  toolCallId: event.toolCallId,
@@ -1 +1 @@
1
- {"version":3,"file":"server.cjs","names":["SUBAGENT_ENVIRONMENT_FLAG","DoomHeadlessPromptAdmissionError","STATUS_PREFIX","dispatchHooks","HOOK_EVENT","hookFailureMessage","createHookBinding","SUBAGENT_ENVIRONMENT_FLAG","DoomHeadlessPromptAdmissionError","defineRoot","defineHook","defineHook","defineHook","defineHook","defineHook","defineResource","HOOK_HELP_SKILL","DOOM_HELP_WHEN","packageResourcePath","readPackageResource","defineServerPlugin","rootSession","composeRootHooks","hookAgentSettled","hookBeforeAgentStart","hookSessionShutdown","hookToolCall","hookToolResult","resourceDoompiAuthorHook"],"sources":["../../src/services/serverHooks/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-call.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-result.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-hook.server.ts","../../generated/server.ts"],"sourcesContent":["import {\n DoomHeadlessPromptAdmissionError,\n type DoomHeadlessExecutionContext,\n type DoomHeadlessHook,\n} from '@agimon-ai/doompi-core/headless';\nimport type { ToolCallEvent, ToolResultEvent } from '@earendil-works/pi-coding-agent';\n\nimport { BLOCKED_BY_HOOK, STATUS_PREFIX, SUBAGENT_ENVIRONMENT_FLAG } from '../../constants/hookHandlers';\nimport { HOOK_EVENT } from '../../constants/hooks';\nimport { hookFailureMessage } from '../hookDecisions';\nimport { dispatchHooks } from '../hookDispatch';\nimport type { HookDispatchScope } from '../hookDispatch/type';\nimport type { HookRuntime, HookRuntimeResolver } from '../hookRuntime/type';\n\nfunction hookEntry(event: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return { version: 1, event: typeof event.type === 'string' ? event.type : 'headless-hook', data: event };\n}\n\nfunction scopeFor(runtime: HookRuntime, execution: DoomHeadlessExecutionContext): HookDispatchScope {\n return {\n sessionId: execution.sessionId,\n isSubagent: Boolean(execution.environment[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: execution.cwd,\n repoRoot: execution.repoRoot,\n model: execution.model,\n signal: runtime.session.signal,\n operationSignal: execution.signal,\n async sendMessage(text, delivery) {\n if (!execution.session.admitPrompt)\n throw new DoomHeadlessPromptAdmissionError('The session cannot admit a hook prompt.');\n await execution.session.admitPrompt(text, delivery);\n },\n appendCustomEntry: (type, data) => execution.session.appendCustomEntry(type, data),\n };\n}\n\n/** Server facets own tool dispatch. Lifecycle rows belong only to the Pi bridge. */\nexport function createServerHooks(resolveRuntime: HookRuntimeResolver) {\n const beforeAgentStart: DoomHeadlessHook<'before_agent_start'> = {\n event: 'before_agent_start',\n handle: (event, execution) => execution.session.appendCustomEntry('doom-hook', hookEntry(event)),\n };\n const toolCall: DoomHeadlessHook<'tool_call'> = {\n event: 'tool_call',\n async handle(event, execution) {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n const scope = scopeFor(runtime, execution);\n const native = {\n type: 'tool_call',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args,\n } as ToolCallEvent;\n const key = `${STATUS_PREFIX}:${native.toolCallId}:pre`;\n try {\n const result = await dispatchHooks(runtime.session, scope, {\n eventName: HOOK_EVENT.preToolUse,\n event: native,\n progress: (index, total) =>\n execution.client.setStatus(key, `Running pre-tool hooks for ${native.toolName} (${index + 1}/${total})...`),\n });\n if (result.failures.length > 0) await scope.sendMessage(hookFailureMessage(result.failures), 'steer');\n return result.toolCall?.block\n ? { block: { reason: result.toolCall.reason ?? BLOCKED_BY_HOOK } }\n : { args: native.input };\n } finally {\n execution.client.setStatus(key, undefined);\n }\n },\n };\n const toolResult: DoomHeadlessHook<'tool_result'> = {\n event: 'tool_result',\n async handle(event, execution) {\n await execution.session.appendCustomEntry('doom-hook', hookEntry(event));\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n const native = {\n type: 'tool_result',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args,\n content: event.content,\n details: event.details,\n isError: event.isError,\n } as ToolResultEvent;\n const key = `${STATUS_PREFIX}:${native.toolCallId}:post`;\n try {\n const result = await dispatchHooks(runtime.session, scopeFor(runtime, execution), {\n eventName: HOOK_EVENT.postToolUse,\n event: native,\n progress: (index, total) =>\n execution.client.setStatus(\n key,\n `Running post-tool hooks for ${native.toolName} (${index + 1}/${total})...`,\n ),\n });\n return result.toolResult;\n } finally {\n execution.client.setStatus(key, undefined);\n }\n },\n };\n const agentSettled: DoomHeadlessHook<'agent_settled'> = {\n event: 'agent_settled',\n handle: (event, execution) => execution.session.appendCustomEntry('doom-hook', hookEntry(event)),\n };\n const sessionShutdown: DoomHeadlessHook<'session_shutdown'> = {\n event: 'session_shutdown',\n handle(_event, execution) {\n execution.client.setStatus('doom-hook', undefined);\n },\n };\n return { beforeAgentStart, toolCall, toolResult, agentSettled, sessionShutdown };\n}\n","import { DoomHeadlessPromptAdmissionError } from '@agimon-ai/doompi-core/headless';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { SUBAGENT_ENVIRONMENT_FLAG } from '../../../../../constants/hookHandlers';\nimport { createHookBinding } from '../../../../../services/hookRuntime';\nimport { createServerHooks } from '../../../../../services/serverHooks';\n\nexport const createHookServerRoot = ({ agent, signal }: DoomServerPluginContext) => {\n if (!agent) throw new Error('Hook session requires the headless host.');\n const execution = agent.context;\n const binding = createHookBinding(\n {},\n {\n sessionId: execution.sessionId,\n isSubagent: Boolean(execution.environment[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: execution.cwd,\n repoRoot: execution.repoRoot,\n get model() {\n return execution.model;\n },\n async sendMessage(text, delivery) {\n if (!execution.session.admitPrompt)\n throw new DoomHeadlessPromptAdmissionError('The session cannot admit a hook prompt.');\n await execution.session.admitPrompt(text, delivery);\n },\n appendCustomEntry: (type, data) => execution.session.appendCustomEntry(type, data),\n },\n signal,\n );\n return { value: createServerHooks(binding.runtime), services: [binding.plugin] };\n};\n\nexport type HookServerScope = Awaited<ReturnType<typeof createHookServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createHookServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createHookServerRoot);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.agentSettled);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.beforeAgentStart);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.sessionShutdown);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.toolCall);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.toolResult);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\nimport { DOOM_HELP_WHEN } from '@agimon-ai/doompi-core/help';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { HOOK_HELP_SKILL } from '../../../../../constants/hook';\n\nexport default defineResource({\n ...HOOK_HELP_SKILL,\n when: DOOM_HELP_WHEN,\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/doompi-author-hook/SKILL.md'),\n read: async () => {\n const text = await readPackageResource(import.meta.url, 'src/prompts/doompi-author-hook/SKILL.md');\n if (!text.trim()) throw new Error('The installed hook-authoring skill is missing or unreadable.');\n return text;\n },\n});\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 hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server';\nimport hookToolCall from '../src/extensions/workspaces/sessions/(backend)/hook/tool-call.server';\nimport hookToolResult from '../src/extensions/workspaces/sessions/(backend)/hook/tool-result.server';\nimport resourceDoompiAuthorHook from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-hook.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-hook',\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get hooks(): DoomServerSessionPlugin['hooks'] { return [via({ event: 'agent_settled' }, at(hookAgentSettled, contextSession)), via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'session_shutdown' }, at(hookSessionShutdown, contextSession)), via({ event: 'tool_call' }, at(hookToolCall, contextSession)), via({ event: 'tool_result' }, at(hookToolResult, contextSession))]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiAuthorHook, 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":["SUBAGENT_ENVIRONMENT_FLAG","DoomHeadlessPromptAdmissionError","STATUS_PREFIX","dispatchHooks","HOOK_EVENT","hookFailureMessage","createHookBinding","SUBAGENT_ENVIRONMENT_FLAG","DoomHeadlessPromptAdmissionError","defineRoot","defineHook","defineHook","defineHook","defineHook","defineHook","defineResource","HOOK_HELP_SKILL","DOOM_HELP_WHEN","packageResourcePath","readPackageResource","defineServerPlugin","rootSession","composeRootHooks","hookAgentSettled","hookBeforeAgentStart","hookSessionShutdown","hookToolCall","hookToolResult","resourceDoompiAuthorHook"],"sources":["../../src/services/serverHooks/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-call.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-result.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-hook.server.ts","../../generated/server.ts"],"sourcesContent":["import {\n DoomHeadlessPromptAdmissionError,\n type DoomHeadlessExecutionContext,\n type DoomHeadlessHook,\n} from '@agimon-ai/doompi-core/headless';\nimport type { ToolCallEvent, ToolResultEvent } from '@earendil-works/pi-coding-agent';\n\nimport { BLOCKED_BY_HOOK, STATUS_PREFIX, SUBAGENT_ENVIRONMENT_FLAG } from '../../constants/hookHandlers';\nimport { HOOK_EVENT } from '../../constants/hooks';\nimport { hookFailureMessage } from '../hookDecisions';\nimport { dispatchHooks } from '../hookDispatch';\nimport type { HookDispatchScope } from '../hookDispatch/type';\nimport type { HookRuntime, HookRuntimeResolver } from '../hookRuntime/type';\n\nfunction hookEntry(event: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return { version: 1, event: typeof event.type === 'string' ? event.type : 'headless-hook', data: event };\n}\n\nfunction scopeFor(runtime: HookRuntime, execution: DoomHeadlessExecutionContext): HookDispatchScope {\n return {\n sessionId: execution.sessionId,\n isSubagent: Boolean(execution.environment[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: execution.cwd,\n repoRoot: execution.repoRoot,\n model: execution.model,\n signal: runtime.session.signal,\n operationSignal: execution.signal,\n async sendMessage(text, delivery) {\n if (!execution.session.admitPrompt)\n throw new DoomHeadlessPromptAdmissionError('The session cannot admit a hook prompt.');\n await execution.session.admitPrompt(text, delivery);\n },\n appendCustomEntry: (type, data) => execution.session.appendCustomEntry(type, data),\n };\n}\n\n/** Server facets own tool dispatch. Lifecycle rows belong only to the Pi bridge. */\nexport function createServerHooks(resolveRuntime: HookRuntimeResolver) {\n const beforeAgentStart: DoomHeadlessHook<'before_agent_start'> = {\n event: 'before_agent_start',\n async handle(event, execution) {\n const runtime = resolveRuntime();\n if (runtime?.isCurrent()) await runtime.session.prepare(scopeFor(runtime, execution).isSubagent);\n await execution.session.appendCustomEntry('doom-hook', hookEntry(event));\n },\n };\n const toolCall: DoomHeadlessHook<'tool_call'> = {\n event: 'tool_call',\n async handle(event, execution) {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n const scope = scopeFor(runtime, execution);\n try {\n await runtime.session.prepare(scope.isSubagent);\n } catch (error) {\n return { block: { reason: error instanceof Error ? error.message : String(error) } };\n }\n const native = {\n type: 'tool_call',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args,\n } as ToolCallEvent;\n const key = `${STATUS_PREFIX}:${native.toolCallId}:pre`;\n try {\n const result = await dispatchHooks(runtime.session, scope, {\n eventName: HOOK_EVENT.preToolUse,\n event: native,\n progress: (index, total) =>\n execution.client.setStatus(key, `Running pre-tool hooks for ${native.toolName} (${index + 1}/${total})...`),\n });\n if (result.failures.length > 0) await scope.sendMessage(hookFailureMessage(result.failures), 'steer');\n return result.toolCall?.block\n ? { block: { reason: result.toolCall.reason ?? BLOCKED_BY_HOOK } }\n : { args: native.input };\n } finally {\n execution.client.setStatus(key, undefined);\n }\n },\n };\n const toolResult: DoomHeadlessHook<'tool_result'> = {\n event: 'tool_result',\n async handle(event, execution) {\n await execution.session.appendCustomEntry('doom-hook', hookEntry(event));\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n const native = {\n type: 'tool_result',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args,\n content: event.content,\n details: event.details,\n isError: event.isError,\n } as ToolResultEvent;\n const key = `${STATUS_PREFIX}:${native.toolCallId}:post`;\n try {\n const result = await dispatchHooks(runtime.session, scopeFor(runtime, execution), {\n eventName: HOOK_EVENT.postToolUse,\n event: native,\n progress: (index, total) =>\n execution.client.setStatus(\n key,\n `Running post-tool hooks for ${native.toolName} (${index + 1}/${total})...`,\n ),\n });\n return result.toolResult;\n } finally {\n execution.client.setStatus(key, undefined);\n }\n },\n };\n const agentSettled: DoomHeadlessHook<'agent_settled'> = {\n event: 'agent_settled',\n handle: (event, execution) => execution.session.appendCustomEntry('doom-hook', hookEntry(event)),\n };\n const sessionShutdown: DoomHeadlessHook<'session_shutdown'> = {\n event: 'session_shutdown',\n handle(_event, execution) {\n execution.client.setStatus('doom-hook', undefined);\n },\n };\n return { beforeAgentStart, toolCall, toolResult, agentSettled, sessionShutdown };\n}\n","import { DoomHeadlessPromptAdmissionError } from '@agimon-ai/doompi-core/headless';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { SUBAGENT_ENVIRONMENT_FLAG } from '../../../../../constants/hookHandlers';\nimport { createHookBinding } from '../../../../../services/hookRuntime';\nimport { createServerHooks } from '../../../../../services/serverHooks';\n\nexport const createHookServerRoot = ({ agent, signal }: DoomServerPluginContext) => {\n if (!agent) throw new Error('Hook session requires the headless host.');\n const execution = agent.context;\n const binding = createHookBinding(\n {},\n {\n sessionId: execution.sessionId,\n isSubagent: Boolean(execution.environment[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: execution.cwd,\n repoRoot: execution.repoRoot,\n get model() {\n return execution.model;\n },\n async sendMessage(text, delivery) {\n if (!execution.session.admitPrompt)\n throw new DoomHeadlessPromptAdmissionError('The session cannot admit a hook prompt.');\n await execution.session.admitPrompt(text, delivery);\n },\n appendCustomEntry: (type, data) => execution.session.appendCustomEntry(type, data),\n },\n signal,\n );\n return { value: createServerHooks(binding.runtime), services: [binding.plugin] };\n};\n\nexport type HookServerScope = Awaited<ReturnType<typeof createHookServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createHookServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createHookServerRoot);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.agentSettled);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.beforeAgentStart);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.sessionShutdown);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.toolCall);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.toolResult);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\nimport { DOOM_HELP_WHEN } from '@agimon-ai/doompi-core/help';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { HOOK_HELP_SKILL } from '../../../../../constants/hook';\n\nexport default defineResource({\n ...HOOK_HELP_SKILL,\n when: DOOM_HELP_WHEN,\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/doompi-author-hook/SKILL.md'),\n read: async () => {\n const text = await readPackageResource(import.meta.url, 'src/prompts/doompi-author-hook/SKILL.md');\n if (!text.trim()) throw new Error('The installed hook-authoring skill is missing or unreadable.');\n return text;\n },\n});\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 hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server';\nimport hookToolCall from '../src/extensions/workspaces/sessions/(backend)/hook/tool-call.server';\nimport hookToolResult from '../src/extensions/workspaces/sessions/(backend)/hook/tool-result.server';\nimport resourceDoompiAuthorHook from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-hook.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-hook',\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get hooks(): DoomServerSessionPlugin['hooks'] { return [via({ event: 'agent_settled' }, at(hookAgentSettled, contextSession)), via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'session_shutdown' }, at(hookSessionShutdown, contextSession)), via({ event: 'tool_call' }, at(hookToolCall, contextSession)), via({ event: 'tool_result' }, at(hookToolResult, contextSession))]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiAuthorHook, 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,5 +1,5 @@
1
- import { n as HOOK_EVENT, y as hookFailureMessage } from "../hookModules-DAFDGPUC.mjs";
2
- import { a as dispatchHooks, d as STATUS_PREFIX, h as SUBAGENT_ENVIRONMENT_FLAG, r as HOOK_HELP_SKILL, t as createHookBinding } from "../hookRuntime-D27m9ndl.mjs";
1
+ import { n as HOOK_EVENT, y as hookFailureMessage } from "../hookModules-CjBUOlER.mjs";
2
+ import { a as dispatchHooks, d as STATUS_PREFIX, h as SUBAGENT_ENVIRONMENT_FLAG, r as HOOK_HELP_SKILL, t as createHookBinding } from "../hookRuntime-BouwbVig.mjs";
3
3
  import { composeRootHooks, defineHook, defineResource, defineRoot } from "@agimon-ai/doompi-core/extensionFile";
4
4
  import { defineServerPlugin, packageResourcePath, readPackageResource } from "@agimon-ai/doompi-core/serverFacet";
5
5
  import { DoomHeadlessPromptAdmissionError } from "@agimon-ai/doompi-core/headless";
@@ -33,7 +33,11 @@ function createServerHooks(resolveRuntime) {
33
33
  return {
34
34
  beforeAgentStart: {
35
35
  event: "before_agent_start",
36
- handle: (event, execution) => execution.session.appendCustomEntry("doom-hook", hookEntry(event))
36
+ async handle(event, execution) {
37
+ const runtime = resolveRuntime();
38
+ if (runtime?.isCurrent()) await runtime.session.prepare(scopeFor(runtime, execution).isSubagent);
39
+ await execution.session.appendCustomEntry("doom-hook", hookEntry(event));
40
+ }
37
41
  },
38
42
  toolCall: {
39
43
  event: "tool_call",
@@ -41,6 +45,11 @@ function createServerHooks(resolveRuntime) {
41
45
  const runtime = resolveRuntime();
42
46
  if (!runtime?.isCurrent()) return;
43
47
  const scope = scopeFor(runtime, execution);
48
+ try {
49
+ await runtime.session.prepare(scope.isSubagent);
50
+ } catch (error) {
51
+ return { block: { reason: error instanceof Error ? error.message : String(error) } };
52
+ }
44
53
  const native = {
45
54
  type: "tool_call",
46
55
  toolCallId: event.toolCallId,
@@ -1 +1 @@
1
- {"version":3,"file":"server.mjs","names":["rootSession","hookAgentSettled","hookBeforeAgentStart","hookSessionShutdown","hookToolCall","hookToolResult","resourceDoompiAuthorHook"],"sources":["../../src/services/serverHooks/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-call.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-result.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-hook.server.ts","../../generated/server.ts"],"sourcesContent":["import {\n DoomHeadlessPromptAdmissionError,\n type DoomHeadlessExecutionContext,\n type DoomHeadlessHook,\n} from '@agimon-ai/doompi-core/headless';\nimport type { ToolCallEvent, ToolResultEvent } from '@earendil-works/pi-coding-agent';\n\nimport { BLOCKED_BY_HOOK, STATUS_PREFIX, SUBAGENT_ENVIRONMENT_FLAG } from '../../constants/hookHandlers';\nimport { HOOK_EVENT } from '../../constants/hooks';\nimport { hookFailureMessage } from '../hookDecisions';\nimport { dispatchHooks } from '../hookDispatch';\nimport type { HookDispatchScope } from '../hookDispatch/type';\nimport type { HookRuntime, HookRuntimeResolver } from '../hookRuntime/type';\n\nfunction hookEntry(event: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return { version: 1, event: typeof event.type === 'string' ? event.type : 'headless-hook', data: event };\n}\n\nfunction scopeFor(runtime: HookRuntime, execution: DoomHeadlessExecutionContext): HookDispatchScope {\n return {\n sessionId: execution.sessionId,\n isSubagent: Boolean(execution.environment[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: execution.cwd,\n repoRoot: execution.repoRoot,\n model: execution.model,\n signal: runtime.session.signal,\n operationSignal: execution.signal,\n async sendMessage(text, delivery) {\n if (!execution.session.admitPrompt)\n throw new DoomHeadlessPromptAdmissionError('The session cannot admit a hook prompt.');\n await execution.session.admitPrompt(text, delivery);\n },\n appendCustomEntry: (type, data) => execution.session.appendCustomEntry(type, data),\n };\n}\n\n/** Server facets own tool dispatch. Lifecycle rows belong only to the Pi bridge. */\nexport function createServerHooks(resolveRuntime: HookRuntimeResolver) {\n const beforeAgentStart: DoomHeadlessHook<'before_agent_start'> = {\n event: 'before_agent_start',\n handle: (event, execution) => execution.session.appendCustomEntry('doom-hook', hookEntry(event)),\n };\n const toolCall: DoomHeadlessHook<'tool_call'> = {\n event: 'tool_call',\n async handle(event, execution) {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n const scope = scopeFor(runtime, execution);\n const native = {\n type: 'tool_call',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args,\n } as ToolCallEvent;\n const key = `${STATUS_PREFIX}:${native.toolCallId}:pre`;\n try {\n const result = await dispatchHooks(runtime.session, scope, {\n eventName: HOOK_EVENT.preToolUse,\n event: native,\n progress: (index, total) =>\n execution.client.setStatus(key, `Running pre-tool hooks for ${native.toolName} (${index + 1}/${total})...`),\n });\n if (result.failures.length > 0) await scope.sendMessage(hookFailureMessage(result.failures), 'steer');\n return result.toolCall?.block\n ? { block: { reason: result.toolCall.reason ?? BLOCKED_BY_HOOK } }\n : { args: native.input };\n } finally {\n execution.client.setStatus(key, undefined);\n }\n },\n };\n const toolResult: DoomHeadlessHook<'tool_result'> = {\n event: 'tool_result',\n async handle(event, execution) {\n await execution.session.appendCustomEntry('doom-hook', hookEntry(event));\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n const native = {\n type: 'tool_result',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args,\n content: event.content,\n details: event.details,\n isError: event.isError,\n } as ToolResultEvent;\n const key = `${STATUS_PREFIX}:${native.toolCallId}:post`;\n try {\n const result = await dispatchHooks(runtime.session, scopeFor(runtime, execution), {\n eventName: HOOK_EVENT.postToolUse,\n event: native,\n progress: (index, total) =>\n execution.client.setStatus(\n key,\n `Running post-tool hooks for ${native.toolName} (${index + 1}/${total})...`,\n ),\n });\n return result.toolResult;\n } finally {\n execution.client.setStatus(key, undefined);\n }\n },\n };\n const agentSettled: DoomHeadlessHook<'agent_settled'> = {\n event: 'agent_settled',\n handle: (event, execution) => execution.session.appendCustomEntry('doom-hook', hookEntry(event)),\n };\n const sessionShutdown: DoomHeadlessHook<'session_shutdown'> = {\n event: 'session_shutdown',\n handle(_event, execution) {\n execution.client.setStatus('doom-hook', undefined);\n },\n };\n return { beforeAgentStart, toolCall, toolResult, agentSettled, sessionShutdown };\n}\n","import { DoomHeadlessPromptAdmissionError } from '@agimon-ai/doompi-core/headless';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { SUBAGENT_ENVIRONMENT_FLAG } from '../../../../../constants/hookHandlers';\nimport { createHookBinding } from '../../../../../services/hookRuntime';\nimport { createServerHooks } from '../../../../../services/serverHooks';\n\nexport const createHookServerRoot = ({ agent, signal }: DoomServerPluginContext) => {\n if (!agent) throw new Error('Hook session requires the headless host.');\n const execution = agent.context;\n const binding = createHookBinding(\n {},\n {\n sessionId: execution.sessionId,\n isSubagent: Boolean(execution.environment[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: execution.cwd,\n repoRoot: execution.repoRoot,\n get model() {\n return execution.model;\n },\n async sendMessage(text, delivery) {\n if (!execution.session.admitPrompt)\n throw new DoomHeadlessPromptAdmissionError('The session cannot admit a hook prompt.');\n await execution.session.admitPrompt(text, delivery);\n },\n appendCustomEntry: (type, data) => execution.session.appendCustomEntry(type, data),\n },\n signal,\n );\n return { value: createServerHooks(binding.runtime), services: [binding.plugin] };\n};\n\nexport type HookServerScope = Awaited<ReturnType<typeof createHookServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createHookServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createHookServerRoot);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.agentSettled);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.beforeAgentStart);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.sessionShutdown);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.toolCall);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.toolResult);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\nimport { DOOM_HELP_WHEN } from '@agimon-ai/doompi-core/help';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { HOOK_HELP_SKILL } from '../../../../../constants/hook';\n\nexport default defineResource({\n ...HOOK_HELP_SKILL,\n when: DOOM_HELP_WHEN,\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/doompi-author-hook/SKILL.md'),\n read: async () => {\n const text = await readPackageResource(import.meta.url, 'src/prompts/doompi-author-hook/SKILL.md');\n if (!text.trim()) throw new Error('The installed hook-authoring skill is missing or unreadable.');\n return text;\n },\n});\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 hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server';\nimport hookToolCall from '../src/extensions/workspaces/sessions/(backend)/hook/tool-call.server';\nimport hookToolResult from '../src/extensions/workspaces/sessions/(backend)/hook/tool-result.server';\nimport resourceDoompiAuthorHook from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-hook.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-hook',\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get hooks(): DoomServerSessionPlugin['hooks'] { return [via({ event: 'agent_settled' }, at(hookAgentSettled, contextSession)), via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'session_shutdown' }, at(hookSessionShutdown, contextSession)), via({ event: 'tool_call' }, at(hookToolCall, contextSession)), via({ event: 'tool_result' }, at(hookToolResult, contextSession))]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiAuthorHook, 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":["rootSession","hookAgentSettled","hookBeforeAgentStart","hookSessionShutdown","hookToolCall","hookToolResult","resourceDoompiAuthorHook"],"sources":["../../src/services/serverHooks/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-call.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-result.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-hook.server.ts","../../generated/server.ts"],"sourcesContent":["import {\n DoomHeadlessPromptAdmissionError,\n type DoomHeadlessExecutionContext,\n type DoomHeadlessHook,\n} from '@agimon-ai/doompi-core/headless';\nimport type { ToolCallEvent, ToolResultEvent } from '@earendil-works/pi-coding-agent';\n\nimport { BLOCKED_BY_HOOK, STATUS_PREFIX, SUBAGENT_ENVIRONMENT_FLAG } from '../../constants/hookHandlers';\nimport { HOOK_EVENT } from '../../constants/hooks';\nimport { hookFailureMessage } from '../hookDecisions';\nimport { dispatchHooks } from '../hookDispatch';\nimport type { HookDispatchScope } from '../hookDispatch/type';\nimport type { HookRuntime, HookRuntimeResolver } from '../hookRuntime/type';\n\nfunction hookEntry(event: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return { version: 1, event: typeof event.type === 'string' ? event.type : 'headless-hook', data: event };\n}\n\nfunction scopeFor(runtime: HookRuntime, execution: DoomHeadlessExecutionContext): HookDispatchScope {\n return {\n sessionId: execution.sessionId,\n isSubagent: Boolean(execution.environment[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: execution.cwd,\n repoRoot: execution.repoRoot,\n model: execution.model,\n signal: runtime.session.signal,\n operationSignal: execution.signal,\n async sendMessage(text, delivery) {\n if (!execution.session.admitPrompt)\n throw new DoomHeadlessPromptAdmissionError('The session cannot admit a hook prompt.');\n await execution.session.admitPrompt(text, delivery);\n },\n appendCustomEntry: (type, data) => execution.session.appendCustomEntry(type, data),\n };\n}\n\n/** Server facets own tool dispatch. Lifecycle rows belong only to the Pi bridge. */\nexport function createServerHooks(resolveRuntime: HookRuntimeResolver) {\n const beforeAgentStart: DoomHeadlessHook<'before_agent_start'> = {\n event: 'before_agent_start',\n async handle(event, execution) {\n const runtime = resolveRuntime();\n if (runtime?.isCurrent()) await runtime.session.prepare(scopeFor(runtime, execution).isSubagent);\n await execution.session.appendCustomEntry('doom-hook', hookEntry(event));\n },\n };\n const toolCall: DoomHeadlessHook<'tool_call'> = {\n event: 'tool_call',\n async handle(event, execution) {\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n const scope = scopeFor(runtime, execution);\n try {\n await runtime.session.prepare(scope.isSubagent);\n } catch (error) {\n return { block: { reason: error instanceof Error ? error.message : String(error) } };\n }\n const native = {\n type: 'tool_call',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args,\n } as ToolCallEvent;\n const key = `${STATUS_PREFIX}:${native.toolCallId}:pre`;\n try {\n const result = await dispatchHooks(runtime.session, scope, {\n eventName: HOOK_EVENT.preToolUse,\n event: native,\n progress: (index, total) =>\n execution.client.setStatus(key, `Running pre-tool hooks for ${native.toolName} (${index + 1}/${total})...`),\n });\n if (result.failures.length > 0) await scope.sendMessage(hookFailureMessage(result.failures), 'steer');\n return result.toolCall?.block\n ? { block: { reason: result.toolCall.reason ?? BLOCKED_BY_HOOK } }\n : { args: native.input };\n } finally {\n execution.client.setStatus(key, undefined);\n }\n },\n };\n const toolResult: DoomHeadlessHook<'tool_result'> = {\n event: 'tool_result',\n async handle(event, execution) {\n await execution.session.appendCustomEntry('doom-hook', hookEntry(event));\n const runtime = resolveRuntime();\n if (!runtime?.isCurrent()) return;\n const native = {\n type: 'tool_result',\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n input: event.args,\n content: event.content,\n details: event.details,\n isError: event.isError,\n } as ToolResultEvent;\n const key = `${STATUS_PREFIX}:${native.toolCallId}:post`;\n try {\n const result = await dispatchHooks(runtime.session, scopeFor(runtime, execution), {\n eventName: HOOK_EVENT.postToolUse,\n event: native,\n progress: (index, total) =>\n execution.client.setStatus(\n key,\n `Running post-tool hooks for ${native.toolName} (${index + 1}/${total})...`,\n ),\n });\n return result.toolResult;\n } finally {\n execution.client.setStatus(key, undefined);\n }\n },\n };\n const agentSettled: DoomHeadlessHook<'agent_settled'> = {\n event: 'agent_settled',\n handle: (event, execution) => execution.session.appendCustomEntry('doom-hook', hookEntry(event)),\n };\n const sessionShutdown: DoomHeadlessHook<'session_shutdown'> = {\n event: 'session_shutdown',\n handle(_event, execution) {\n execution.client.setStatus('doom-hook', undefined);\n },\n };\n return { beforeAgentStart, toolCall, toolResult, agentSettled, sessionShutdown };\n}\n","import { DoomHeadlessPromptAdmissionError } from '@agimon-ai/doompi-core/headless';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { SUBAGENT_ENVIRONMENT_FLAG } from '../../../../../constants/hookHandlers';\nimport { createHookBinding } from '../../../../../services/hookRuntime';\nimport { createServerHooks } from '../../../../../services/serverHooks';\n\nexport const createHookServerRoot = ({ agent, signal }: DoomServerPluginContext) => {\n if (!agent) throw new Error('Hook session requires the headless host.');\n const execution = agent.context;\n const binding = createHookBinding(\n {},\n {\n sessionId: execution.sessionId,\n isSubagent: Boolean(execution.environment[SUBAGENT_ENVIRONMENT_FLAG]),\n cwd: execution.cwd,\n repoRoot: execution.repoRoot,\n get model() {\n return execution.model;\n },\n async sendMessage(text, delivery) {\n if (!execution.session.admitPrompt)\n throw new DoomHeadlessPromptAdmissionError('The session cannot admit a hook prompt.');\n await execution.session.admitPrompt(text, delivery);\n },\n appendCustomEntry: (type, data) => execution.session.appendCustomEntry(type, data),\n },\n signal,\n );\n return { value: createServerHooks(binding.runtime), services: [binding.plugin] };\n};\n\nexport type HookServerScope = Awaited<ReturnType<typeof createHookServerRoot>>['value'];\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createHookServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createHookServerRoot);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.agentSettled);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.beforeAgentStart);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.sessionShutdown);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.toolCall);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { HookServerScope } from '../_lib/serverRoot';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, HookServerScope>) => root.toolResult);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\nimport { DOOM_HELP_WHEN } from '@agimon-ai/doompi-core/help';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { HOOK_HELP_SKILL } from '../../../../../constants/hook';\n\nexport default defineResource({\n ...HOOK_HELP_SKILL,\n when: DOOM_HELP_WHEN,\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/doompi-author-hook/SKILL.md'),\n read: async () => {\n const text = await readPackageResource(import.meta.url, 'src/prompts/doompi-author-hook/SKILL.md');\n if (!text.trim()) throw new Error('The installed hook-authoring skill is missing or unreadable.');\n return text;\n },\n});\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 hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.server';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server';\nimport hookToolCall from '../src/extensions/workspaces/sessions/(backend)/hook/tool-call.server';\nimport hookToolResult from '../src/extensions/workspaces/sessions/(backend)/hook/tool-result.server';\nimport resourceDoompiAuthorHook from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-hook.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-hook',\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get hooks(): DoomServerSessionPlugin['hooks'] { return [via({ event: 'agent_settled' }, at(hookAgentSettled, contextSession)), via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'session_shutdown' }, at(hookSessionShutdown, contextSession)), via({ event: 'tool_call' }, at(hookToolCall, contextSession)), via({ event: 'tool_result' }, at(hookToolResult, contextSession))]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiAuthorHook, 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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"}