@agimon-ai/doompi-hook 0.0.1-alpha.9 → 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.
Files changed (144) hide show
  1. package/README.md +113 -48
  2. package/dist/apiContracts.cjs +17 -0
  3. package/dist/apiContracts.cjs.map +1 -0
  4. package/dist/apiContracts.d.mts +53 -0
  5. package/dist/apiContracts.d.mts.map +1 -0
  6. package/dist/apiContracts.mjs +13 -0
  7. package/dist/apiContracts.mjs.map +1 -0
  8. package/dist/authoring.cjs +10 -0
  9. package/dist/authoring.cjs.map +1 -0
  10. package/dist/authoring.d.mts +7 -0
  11. package/dist/authoring.d.mts.map +1 -0
  12. package/dist/authoring.mjs +9 -0
  13. package/dist/authoring.mjs.map +1 -0
  14. package/dist/extensions/mcp.cjs +26 -0
  15. package/dist/extensions/mcp.cjs.map +1 -0
  16. package/dist/extensions/mcp.d.mts +5 -0
  17. package/dist/extensions/mcp.d.mts.map +1 -0
  18. package/dist/extensions/mcp.mjs +21 -0
  19. package/dist/extensions/mcp.mjs.map +1 -0
  20. package/dist/extensions/pi.cjs +268 -1
  21. package/dist/extensions/pi.cjs.map +1 -0
  22. package/dist/extensions/pi.d.mts +6 -2
  23. package/dist/extensions/pi.d.mts.map +1 -0
  24. package/dist/extensions/pi.mjs +263 -1
  25. package/dist/extensions/pi.mjs.map +1 -0
  26. package/dist/extensions/server.cjs +211 -0
  27. package/dist/extensions/server.cjs.map +1 -0
  28. package/dist/extensions/server.d.mts +5 -0
  29. package/dist/extensions/server.d.mts.map +1 -0
  30. package/dist/extensions/server.mjs +206 -0
  31. package/dist/extensions/server.mjs.map +1 -0
  32. package/dist/hookModule-c2GtLnm1.d.mts +54 -0
  33. package/dist/hookModule-c2GtLnm1.d.mts.map +1 -0
  34. package/dist/hookModules-CjBUOlER.mjs +749 -0
  35. package/dist/hookModules-CjBUOlER.mjs.map +1 -0
  36. package/dist/hookModules-DShU8Nls.cjs +899 -0
  37. package/dist/hookModules-DShU8Nls.cjs.map +1 -0
  38. package/dist/hookRuntime-BDfSkRP-.cjs +459 -0
  39. package/dist/hookRuntime-BDfSkRP-.cjs.map +1 -0
  40. package/dist/hookRuntime-BouwbVig.mjs +370 -0
  41. package/dist/hookRuntime-BouwbVig.mjs.map +1 -0
  42. package/dist/index-C3Xt9wLJ.d.mts +369 -0
  43. package/dist/index-C3Xt9wLJ.d.mts.map +1 -0
  44. package/dist/index.cjs +23 -1
  45. package/dist/index.d.mts +3 -12
  46. package/dist/index.mjs +2 -1
  47. package/llms.txt +2 -2
  48. package/package.json +58 -14
  49. package/src/prompts/doompi-author-hook/SKILL.md +97 -20
  50. package/dist/_virtual/_rolldown/runtime.cjs +0 -1
  51. package/dist/adapters/hookDocuments.cjs +0 -2
  52. package/dist/adapters/hookDocuments.cjs.map +0 -1
  53. package/dist/adapters/hookDocuments.d.cts +0 -23
  54. package/dist/adapters/hookDocuments.d.cts.map +0 -1
  55. package/dist/adapters/hookDocuments.d.mts +0 -23
  56. package/dist/adapters/hookDocuments.d.mts.map +0 -1
  57. package/dist/adapters/hookDocuments.mjs +0 -2
  58. package/dist/adapters/hookDocuments.mjs.map +0 -1
  59. package/dist/adapters/hookRunner.cjs +0 -2
  60. package/dist/adapters/hookRunner.cjs.map +0 -1
  61. package/dist/adapters/hookRunner.d.cts +0 -22
  62. package/dist/adapters/hookRunner.d.cts.map +0 -1
  63. package/dist/adapters/hookRunner.d.mts +0 -22
  64. package/dist/adapters/hookRunner.d.mts.map +0 -1
  65. package/dist/adapters/hookRunner.mjs +0 -2
  66. package/dist/adapters/hookRunner.mjs.map +0 -1
  67. package/dist/adapters/pi/extension.cjs +0 -2
  68. package/dist/adapters/pi/extension.cjs.map +0 -1
  69. package/dist/adapters/pi/extension.d.cts +0 -14
  70. package/dist/adapters/pi/extension.d.cts.map +0 -1
  71. package/dist/adapters/pi/extension.d.mts +0 -14
  72. package/dist/adapters/pi/extension.d.mts.map +0 -1
  73. package/dist/adapters/pi/extension.mjs +0 -2
  74. package/dist/adapters/pi/extension.mjs.map +0 -1
  75. package/dist/adapters/pi/hookHandlers.cjs +0 -8
  76. package/dist/adapters/pi/hookHandlers.cjs.map +0 -1
  77. package/dist/adapters/pi/hookHandlers.mjs +0 -8
  78. package/dist/adapters/pi/hookHandlers.mjs.map +0 -1
  79. package/dist/adapters/telemetry/logSinkTelemetry.cjs +0 -2
  80. package/dist/adapters/telemetry/logSinkTelemetry.cjs.map +0 -1
  81. package/dist/adapters/telemetry/logSinkTelemetry.d.cts +0 -14
  82. package/dist/adapters/telemetry/logSinkTelemetry.d.cts.map +0 -1
  83. package/dist/adapters/telemetry/logSinkTelemetry.d.mts +0 -14
  84. package/dist/adapters/telemetry/logSinkTelemetry.d.mts.map +0 -1
  85. package/dist/adapters/telemetry/logSinkTelemetry.mjs +0 -2
  86. package/dist/adapters/telemetry/logSinkTelemetry.mjs.map +0 -1
  87. package/dist/extensions/pi.d.cts +0 -2
  88. package/dist/index.d.cts +0 -12
  89. package/dist/services/hookDecisions.cjs +0 -3
  90. package/dist/services/hookDecisions.cjs.map +0 -1
  91. package/dist/services/hookDecisions.d.cts +0 -19
  92. package/dist/services/hookDecisions.d.cts.map +0 -1
  93. package/dist/services/hookDecisions.d.mts +0 -19
  94. package/dist/services/hookDecisions.d.mts.map +0 -1
  95. package/dist/services/hookDecisions.mjs +0 -3
  96. package/dist/services/hookDecisions.mjs.map +0 -1
  97. package/dist/services/hookPayload.cjs +0 -2
  98. package/dist/services/hookPayload.cjs.map +0 -1
  99. package/dist/services/hookPayload.d.cts +0 -9
  100. package/dist/services/hookPayload.d.cts.map +0 -1
  101. package/dist/services/hookPayload.d.mts +0 -9
  102. package/dist/services/hookPayload.d.mts.map +0 -1
  103. package/dist/services/hookPayload.mjs +0 -2
  104. package/dist/services/hookPayload.mjs.map +0 -1
  105. package/dist/services/hookRegistry.cjs +0 -2
  106. package/dist/services/hookRegistry.cjs.map +0 -1
  107. package/dist/services/hookRegistry.d.cts +0 -37
  108. package/dist/services/hookRegistry.d.cts.map +0 -1
  109. package/dist/services/hookRegistry.d.mts +0 -37
  110. package/dist/services/hookRegistry.d.mts.map +0 -1
  111. package/dist/services/hookRegistry.mjs +0 -2
  112. package/dist/services/hookRegistry.mjs.map +0 -1
  113. package/dist/services/pluginHooks.cjs +0 -2
  114. package/dist/services/pluginHooks.cjs.map +0 -1
  115. package/dist/services/pluginHooks.d.cts +0 -13
  116. package/dist/services/pluginHooks.d.cts.map +0 -1
  117. package/dist/services/pluginHooks.d.mts +0 -13
  118. package/dist/services/pluginHooks.d.mts.map +0 -1
  119. package/dist/services/pluginHooks.mjs +0 -2
  120. package/dist/services/pluginHooks.mjs.map +0 -1
  121. package/dist/services/toolNames.cjs +0 -2
  122. package/dist/services/toolNames.cjs.map +0 -1
  123. package/dist/services/toolNames.d.cts +0 -8
  124. package/dist/services/toolNames.d.cts.map +0 -1
  125. package/dist/services/toolNames.d.mts +0 -8
  126. package/dist/services/toolNames.d.mts.map +0 -1
  127. package/dist/services/toolNames.mjs +0 -2
  128. package/dist/services/toolNames.mjs.map +0 -1
  129. package/dist/types/hooks.cjs +0 -2
  130. package/dist/types/hooks.cjs.map +0 -1
  131. package/dist/types/hooks.d.cts +0 -145
  132. package/dist/types/hooks.d.cts.map +0 -1
  133. package/dist/types/hooks.d.mts +0 -145
  134. package/dist/types/hooks.d.mts.map +0 -1
  135. package/dist/types/hooks.mjs +0 -2
  136. package/dist/types/hooks.mjs.map +0 -1
  137. package/dist/types/telemetry.cjs +0 -2
  138. package/dist/types/telemetry.cjs.map +0 -1
  139. package/dist/types/telemetry.d.cts +0 -20
  140. package/dist/types/telemetry.d.cts.map +0 -1
  141. package/dist/types/telemetry.d.mts +0 -20
  142. package/dist/types/telemetry.d.mts.map +0 -1
  143. package/dist/types/telemetry.mjs +0 -2
  144. package/dist/types/telemetry.mjs.map +0 -1
@@ -1 +1,268 @@
1
- Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../adapters/pi/extension.cjs");exports.default=e.default,exports.hookExtension=e.default;
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ const require_hookModules = require("../hookModules-DShU8Nls.cjs");
6
+ const require_hookRuntime = require("../hookRuntime-BDfSkRP-.cjs");
7
+ let _agimon_ai_doompi_core_piExtension = require("@agimon-ai/doompi-core/piExtension");
8
+ let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
9
+ let _agimon_ai_doompi_core_cordisHost = require("@agimon-ai/doompi-core/cordisHost");
10
+ //#region src/services/hookHandlers/index.ts
11
+ function scopeFor(pi, session, ctx) {
12
+ if (session.parentContext) return {
13
+ ...session.parentContext,
14
+ signal: session.signal,
15
+ operationSignal: ctx.signal
16
+ };
17
+ return {
18
+ sessionId: ctx.sessionManager.getSessionId(),
19
+ isSubagent: Boolean(process.env[require_hookRuntime.SUBAGENT_ENVIRONMENT_FLAG]),
20
+ cwd: ctx.cwd,
21
+ repoRoot: session.config().harness.root ?? ctx.cwd,
22
+ ...ctx.model ? { model: {
23
+ provider: ctx.model.provider,
24
+ id: ctx.model.id
25
+ } } : {},
26
+ signal: session.signal,
27
+ operationSignal: ctx.signal,
28
+ async sendMessage(text, delivery) {
29
+ pi.sendMessage({
30
+ customType: require_hookRuntime.CONTEXT_MESSAGE_TYPE,
31
+ content: text,
32
+ display: true
33
+ }, { deliverAs: delivery });
34
+ },
35
+ async appendCustomEntry(type, data) {
36
+ pi.appendEntry(type, data);
37
+ }
38
+ };
39
+ }
40
+ async function runPiDispatch(pi, session, ctx, request, statusKey, statusLabel, signal) {
41
+ try {
42
+ const scope = scopeFor(pi, session, ctx);
43
+ return await require_hookRuntime.dispatchHooks(session, {
44
+ ...scope,
45
+ operationSignal: signal ?? scope.operationSignal
46
+ }, {
47
+ ...request,
48
+ progress: (index, total) => {
49
+ if (ctx.hasUI) ctx.ui.setStatus(statusKey, `${statusLabel} (${index + 1}/${total})...`);
50
+ }
51
+ });
52
+ } finally {
53
+ if (ctx.hasUI) ctx.ui.setStatus(statusKey, void 0);
54
+ }
55
+ }
56
+ async function steerHookFailures(pi, session, failures) {
57
+ if (failures.length === 0) return;
58
+ if (session.parentContext) await session.parentContext.sendMessage(require_hookModules.hookFailureMessage(failures), "steer");
59
+ else pi.sendMessage({
60
+ customType: require_hookRuntime.FAILURE_MESSAGE_TYPE,
61
+ content: require_hookModules.hookFailureMessage(failures),
62
+ display: true
63
+ }, require_hookRuntime.STEER);
64
+ }
65
+ function createSessionStart(pi, resolveRuntime) {
66
+ return (event, ctx) => {
67
+ const runtime = resolveRuntime();
68
+ if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return void 0;
69
+ const { session, readiness } = runtime;
70
+ const run = async (signal, isReady = () => true) => {
71
+ await session.prepare();
72
+ const result = await runPiDispatch(pi, session, ctx, {
73
+ eventName: require_hookModules.HOOK_EVENT.sessionStart,
74
+ event
75
+ }, `${require_hookRuntime.STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:start`, "Running session-start hooks", signal);
76
+ signal?.throwIfAborted();
77
+ if (!runtime.isCurrent() || !isReady()) return;
78
+ await steerHookFailures(pi, session, result.failures);
79
+ const context = require_hookModules.additionalContextsFrom(result.decisions).join("\n\n");
80
+ if (context) await scopeFor(pi, session, ctx).sendMessage(context, "steer");
81
+ };
82
+ return readiness ? readiness.start(ctx, run) : run();
83
+ };
84
+ }
85
+ function createBeforeAgentStart(resolveRuntime) {
86
+ return async (_event, ctx) => {
87
+ const runtime = resolveRuntime();
88
+ if (!runtime?.isCurrent()) return;
89
+ await runtime.session.prepare(runtime.session.parentContext?.isSubagent ?? Boolean(process.env["PI_SUBAGENT_CHILD"]));
90
+ await runtime.readiness?.wait(ctx);
91
+ };
92
+ }
93
+ function createToolCall(pi, resolveRuntime) {
94
+ return async (event, ctx) => {
95
+ const runtime = resolveRuntime();
96
+ if (!runtime?.isCurrent()) return void 0;
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
+ }
114
+ if (!runtime.isCurrent()) return void 0;
115
+ const result = await runPiDispatch(pi, runtime.session, ctx, {
116
+ eventName: require_hookModules.HOOK_EVENT.preToolUse,
117
+ event
118
+ }, `${require_hookRuntime.STATUS_PREFIX}:${event.toolCallId}:pre`, `Running pre-tool hooks for ${event.toolName}`);
119
+ if (!runtime.isCurrent()) return void 0;
120
+ await steerHookFailures(pi, runtime.session, result.failures);
121
+ return result.toolCall;
122
+ };
123
+ }
124
+ function createToolResult(pi, resolveRuntime) {
125
+ return async (event, ctx) => {
126
+ const runtime = resolveRuntime();
127
+ if (!runtime?.isCurrent()) return void 0;
128
+ await runtime.readiness?.wait(ctx);
129
+ if (!runtime.isCurrent()) return void 0;
130
+ const result = await runPiDispatch(pi, runtime.session, ctx, {
131
+ eventName: require_hookModules.HOOK_EVENT.postToolUse,
132
+ event
133
+ }, `${require_hookRuntime.STATUS_PREFIX}:${event.toolCallId}:post`, `Running post-tool hooks for ${event.toolName}`);
134
+ if (!runtime.isCurrent()) return void 0;
135
+ return result.toolResult;
136
+ };
137
+ }
138
+ function createAgentSettled(pi, resolveRuntime) {
139
+ let refusals = 0;
140
+ return async (event, ctx) => {
141
+ const runtime = resolveRuntime();
142
+ if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return;
143
+ await runtime.readiness?.wait(ctx);
144
+ if (!runtime.isCurrent()) return;
145
+ const result = await runPiDispatch(pi, runtime.session, ctx, {
146
+ eventName: require_hookModules.HOOK_EVENT.stop,
147
+ event,
148
+ extraPayload: { [require_hookRuntime.STOP_HOOK_ACTIVE_FIELD]: refusals > 0 }
149
+ }, `${require_hookRuntime.STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:stop`, "Running stop hooks");
150
+ if (!runtime.isCurrent()) return;
151
+ if (result.failures.length > 0) pi.sendMessage({
152
+ customType: require_hookRuntime.FAILURE_MESSAGE_TYPE,
153
+ content: require_hookModules.hookFailureMessage(result.failures),
154
+ display: true
155
+ }, require_hookRuntime.NO_TURN);
156
+ const reason = require_hookModules.decisionReason(result.decisions.find(require_hookModules.isDenied));
157
+ if (!reason) {
158
+ refusals = 0;
159
+ return;
160
+ }
161
+ if (refusals >= 5) {
162
+ refusals = 0;
163
+ pi.sendMessage({
164
+ customType: require_hookRuntime.FAILURE_MESSAGE_TYPE,
165
+ content: `A Stop hook refused ${String(5)} stops in a row, so the agent stops here. Its last reason: ${reason}`,
166
+ display: true
167
+ }, require_hookRuntime.NO_TURN);
168
+ return;
169
+ }
170
+ refusals += 1;
171
+ pi.sendMessage({
172
+ customType: require_hookRuntime.STOP_BLOCK_MESSAGE_TYPE,
173
+ content: reason,
174
+ display: true
175
+ }, require_hookRuntime.FOLLOW_UP_TURN);
176
+ };
177
+ }
178
+ function createHookHandlers(pi, resolveRuntime) {
179
+ let shutdown;
180
+ return {
181
+ session_start: createSessionStart(pi, resolveRuntime),
182
+ before_agent_start: createBeforeAgentStart(resolveRuntime),
183
+ tool_call: createToolCall(pi, resolveRuntime),
184
+ tool_result: createToolResult(pi, resolveRuntime),
185
+ agent_settled: createAgentSettled(pi, resolveRuntime),
186
+ session_shutdown: (_event, ctx) => {
187
+ const current = resolveRuntime();
188
+ if (!current?.isCurrent() || scopeFor(pi, current.session, ctx).isSubagent) return void 0;
189
+ shutdown ??= runSessionEndHooks(pi, current.session, ctx);
190
+ return shutdown;
191
+ }
192
+ };
193
+ }
194
+ /** SessionEnd remains plugin-only and once-only while the session is still usable. */
195
+ async function runSessionEndHooks(pi, session, ctx) {
196
+ await runPiDispatch(pi, session, ctx, { eventName: require_hookModules.HOOK_EVENT.sessionEnd }, `${require_hookRuntime.STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:end`, "Running session-end hooks");
197
+ }
198
+ //#endregion
199
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts
200
+ const createHookPiRoot = ({ pi, options, context }) => {
201
+ const binding = require_hookRuntime.createHookBinding(options ?? {});
202
+ const runtime = () => {
203
+ const server = context.get(_agimon_ai_doompi_core_cordisHost.DOOM_CORDIS_SERVER_SERVICES);
204
+ return server ? server.get(require_hookRuntime.DOOM_HOOK_SESSION_SERVICE) : binding.runtime();
205
+ };
206
+ return {
207
+ value: createHookHandlers(pi, runtime),
208
+ services: [binding.plugin]
209
+ };
210
+ };
211
+ //#endregion
212
+ //#region src/extensions/workspaces/sessions/(backend)/root.cli.ts
213
+ var root_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoot)(createHookPiRoot);
214
+ //#endregion
215
+ //#region src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.ts
216
+ var agent_settled_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineCliHook)((context) => context.root.agent_settled);
217
+ //#endregion
218
+ //#region src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts
219
+ var before_agent_start_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineCliHook)((context) => context.root.before_agent_start);
220
+ //#endregion
221
+ //#region src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli.ts
222
+ var session_shutdown_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineCliHook)((context) => context.root.session_shutdown);
223
+ //#endregion
224
+ //#region src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts
225
+ var session_start_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineCliHook)((context) => context.root.session_start);
226
+ //#endregion
227
+ //#region src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli.ts
228
+ var tool_call_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineCliHook)((context) => context.root.tool_call);
229
+ //#endregion
230
+ //#region src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli.ts
231
+ var tool_result_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineCliHook)((context) => context.root.tool_result);
232
+ //#endregion
233
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli.ts
234
+ var doompi_use_hook_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineResource)({
235
+ source: require_hookRuntime.PACKAGE_SOURCE,
236
+ moduleUrl: require("url").pathToFileURL(__filename).href,
237
+ skills: [require_hookRuntime.HOOK_HELP_SKILL]
238
+ });
239
+ //#endregion
240
+ //#region generated/pi.ts
241
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
242
+ const extension = (0, _agimon_ai_doompi_core_piExtension.definePiExtension)("@agimon-ai/doompi-hook", async (context) => {
243
+ const scopeSession = await root_cli_default(context);
244
+ const contextSession = {
245
+ ...context,
246
+ root: scopeSession.value
247
+ };
248
+ return {
249
+ ...(0, _agimon_ai_doompi_core_extensionFile.composeRootHooks)(scopeSession),
250
+ events: {
251
+ agent_settled: at(agent_settled_cli_default, contextSession),
252
+ before_agent_start: at(before_agent_start_cli_default, contextSession),
253
+ session_shutdown: at(session_shutdown_cli_default, contextSession),
254
+ session_start: at(session_start_cli_default, contextSession),
255
+ tool_call: at(tool_call_cli_default, contextSession),
256
+ tool_result: at(tool_result_cli_default, contextSession)
257
+ },
258
+ get resources() {
259
+ return [at(doompi_use_hook_cli_default, contextSession)];
260
+ },
261
+ services: [...scopeSession.services ?? []]
262
+ };
263
+ });
264
+ //#endregion
265
+ exports.default = extension;
266
+ exports.extension = extension;
267
+
268
+ //# sourceMappingURL=pi.cjs.map
@@ -0,0 +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 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,2 +1,6 @@
1
- import hookExtension, { HookExtensionOptions } from "../adapters/pi/extension.mjs";
2
- export { type HookExtensionOptions, hookExtension as default, hookExtension };
1
+ import { s as HookExtensionOptions } from "../index-C3Xt9wLJ.mjs";
2
+ //#region generated/pi.d.ts
3
+ export declare const extension: import("@agimon-ai/doompi-core/runtimePiExtension").DefinedPiExtension<HookExtensionOptions>;
4
+ //#endregion
5
+ export { extension as default };
6
+ //# sourceMappingURL=pi.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi.d.mts","names":["_$___src_exports0.HookExtensionOptions"],"sources":["../../generated/pi.ts"],"mappings":";;qBAuBa,+DAAS,mBAATA"}
@@ -1 +1,263 @@
1
- import e from"../adapters/pi/extension.mjs";export{e as default,e as hookExtension};
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
+ import { definePiExtension } from "@agimon-ai/doompi-core/piExtension";
4
+ import { composeRootHooks, defineCliHook, defineResource, defineRoot } from "@agimon-ai/doompi-core/extensionFile";
5
+ import { DOOM_CORDIS_SERVER_SERVICES } from "@agimon-ai/doompi-core/cordisHost";
6
+ //#region src/services/hookHandlers/index.ts
7
+ function scopeFor(pi, session, ctx) {
8
+ if (session.parentContext) return {
9
+ ...session.parentContext,
10
+ signal: session.signal,
11
+ operationSignal: ctx.signal
12
+ };
13
+ return {
14
+ sessionId: ctx.sessionManager.getSessionId(),
15
+ isSubagent: Boolean(process.env[SUBAGENT_ENVIRONMENT_FLAG]),
16
+ cwd: ctx.cwd,
17
+ repoRoot: session.config().harness.root ?? ctx.cwd,
18
+ ...ctx.model ? { model: {
19
+ provider: ctx.model.provider,
20
+ id: ctx.model.id
21
+ } } : {},
22
+ signal: session.signal,
23
+ operationSignal: ctx.signal,
24
+ async sendMessage(text, delivery) {
25
+ pi.sendMessage({
26
+ customType: CONTEXT_MESSAGE_TYPE,
27
+ content: text,
28
+ display: true
29
+ }, { deliverAs: delivery });
30
+ },
31
+ async appendCustomEntry(type, data) {
32
+ pi.appendEntry(type, data);
33
+ }
34
+ };
35
+ }
36
+ async function runPiDispatch(pi, session, ctx, request, statusKey, statusLabel, signal) {
37
+ try {
38
+ const scope = scopeFor(pi, session, ctx);
39
+ return await dispatchHooks(session, {
40
+ ...scope,
41
+ operationSignal: signal ?? scope.operationSignal
42
+ }, {
43
+ ...request,
44
+ progress: (index, total) => {
45
+ if (ctx.hasUI) ctx.ui.setStatus(statusKey, `${statusLabel} (${index + 1}/${total})...`);
46
+ }
47
+ });
48
+ } finally {
49
+ if (ctx.hasUI) ctx.ui.setStatus(statusKey, void 0);
50
+ }
51
+ }
52
+ async function steerHookFailures(pi, session, failures) {
53
+ if (failures.length === 0) return;
54
+ if (session.parentContext) await session.parentContext.sendMessage(hookFailureMessage(failures), "steer");
55
+ else pi.sendMessage({
56
+ customType: FAILURE_MESSAGE_TYPE,
57
+ content: hookFailureMessage(failures),
58
+ display: true
59
+ }, STEER);
60
+ }
61
+ function createSessionStart(pi, resolveRuntime) {
62
+ return (event, ctx) => {
63
+ const runtime = resolveRuntime();
64
+ if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return void 0;
65
+ const { session, readiness } = runtime;
66
+ const run = async (signal, isReady = () => true) => {
67
+ await session.prepare();
68
+ const result = await runPiDispatch(pi, session, ctx, {
69
+ eventName: HOOK_EVENT.sessionStart,
70
+ event
71
+ }, `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:start`, "Running session-start hooks", signal);
72
+ signal?.throwIfAborted();
73
+ if (!runtime.isCurrent() || !isReady()) return;
74
+ await steerHookFailures(pi, session, result.failures);
75
+ const context = additionalContextsFrom(result.decisions).join("\n\n");
76
+ if (context) await scopeFor(pi, session, ctx).sendMessage(context, "steer");
77
+ };
78
+ return readiness ? readiness.start(ctx, run) : run();
79
+ };
80
+ }
81
+ function createBeforeAgentStart(resolveRuntime) {
82
+ return async (_event, ctx) => {
83
+ const runtime = resolveRuntime();
84
+ if (!runtime?.isCurrent()) return;
85
+ await runtime.session.prepare(runtime.session.parentContext?.isSubagent ?? Boolean(process.env["PI_SUBAGENT_CHILD"]));
86
+ await runtime.readiness?.wait(ctx);
87
+ };
88
+ }
89
+ function createToolCall(pi, resolveRuntime) {
90
+ return async (event, ctx) => {
91
+ const runtime = resolveRuntime();
92
+ if (!runtime?.isCurrent()) return void 0;
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
+ }
110
+ if (!runtime.isCurrent()) return void 0;
111
+ const result = await runPiDispatch(pi, runtime.session, ctx, {
112
+ eventName: HOOK_EVENT.preToolUse,
113
+ event
114
+ }, `${STATUS_PREFIX}:${event.toolCallId}:pre`, `Running pre-tool hooks for ${event.toolName}`);
115
+ if (!runtime.isCurrent()) return void 0;
116
+ await steerHookFailures(pi, runtime.session, result.failures);
117
+ return result.toolCall;
118
+ };
119
+ }
120
+ function createToolResult(pi, resolveRuntime) {
121
+ return async (event, ctx) => {
122
+ const runtime = resolveRuntime();
123
+ if (!runtime?.isCurrent()) return void 0;
124
+ await runtime.readiness?.wait(ctx);
125
+ if (!runtime.isCurrent()) return void 0;
126
+ const result = await runPiDispatch(pi, runtime.session, ctx, {
127
+ eventName: HOOK_EVENT.postToolUse,
128
+ event
129
+ }, `${STATUS_PREFIX}:${event.toolCallId}:post`, `Running post-tool hooks for ${event.toolName}`);
130
+ if (!runtime.isCurrent()) return void 0;
131
+ return result.toolResult;
132
+ };
133
+ }
134
+ function createAgentSettled(pi, resolveRuntime) {
135
+ let refusals = 0;
136
+ return async (event, ctx) => {
137
+ const runtime = resolveRuntime();
138
+ if (!runtime?.isCurrent() || scopeFor(pi, runtime.session, ctx).isSubagent) return;
139
+ await runtime.readiness?.wait(ctx);
140
+ if (!runtime.isCurrent()) return;
141
+ const result = await runPiDispatch(pi, runtime.session, ctx, {
142
+ eventName: HOOK_EVENT.stop,
143
+ event,
144
+ extraPayload: { [STOP_HOOK_ACTIVE_FIELD]: refusals > 0 }
145
+ }, `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:stop`, "Running stop hooks");
146
+ if (!runtime.isCurrent()) return;
147
+ if (result.failures.length > 0) pi.sendMessage({
148
+ customType: FAILURE_MESSAGE_TYPE,
149
+ content: hookFailureMessage(result.failures),
150
+ display: true
151
+ }, NO_TURN);
152
+ const reason = decisionReason(result.decisions.find(isDenied));
153
+ if (!reason) {
154
+ refusals = 0;
155
+ return;
156
+ }
157
+ if (refusals >= 5) {
158
+ refusals = 0;
159
+ pi.sendMessage({
160
+ customType: FAILURE_MESSAGE_TYPE,
161
+ content: `A Stop hook refused ${String(5)} stops in a row, so the agent stops here. Its last reason: ${reason}`,
162
+ display: true
163
+ }, NO_TURN);
164
+ return;
165
+ }
166
+ refusals += 1;
167
+ pi.sendMessage({
168
+ customType: STOP_BLOCK_MESSAGE_TYPE,
169
+ content: reason,
170
+ display: true
171
+ }, FOLLOW_UP_TURN);
172
+ };
173
+ }
174
+ function createHookHandlers(pi, resolveRuntime) {
175
+ let shutdown;
176
+ return {
177
+ session_start: createSessionStart(pi, resolveRuntime),
178
+ before_agent_start: createBeforeAgentStart(resolveRuntime),
179
+ tool_call: createToolCall(pi, resolveRuntime),
180
+ tool_result: createToolResult(pi, resolveRuntime),
181
+ agent_settled: createAgentSettled(pi, resolveRuntime),
182
+ session_shutdown: (_event, ctx) => {
183
+ const current = resolveRuntime();
184
+ if (!current?.isCurrent() || scopeFor(pi, current.session, ctx).isSubagent) return void 0;
185
+ shutdown ??= runSessionEndHooks(pi, current.session, ctx);
186
+ return shutdown;
187
+ }
188
+ };
189
+ }
190
+ /** SessionEnd remains plugin-only and once-only while the session is still usable. */
191
+ async function runSessionEndHooks(pi, session, ctx) {
192
+ await runPiDispatch(pi, session, ctx, { eventName: HOOK_EVENT.sessionEnd }, `${STATUS_PREFIX}:${ctx.sessionManager.getSessionId()}:end`, "Running session-end hooks");
193
+ }
194
+ //#endregion
195
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts
196
+ const createHookPiRoot = ({ pi, options, context }) => {
197
+ const binding = createHookBinding(options ?? {});
198
+ const runtime = () => {
199
+ const server = context.get(DOOM_CORDIS_SERVER_SERVICES);
200
+ return server ? server.get(DOOM_HOOK_SESSION_SERVICE) : binding.runtime();
201
+ };
202
+ return {
203
+ value: createHookHandlers(pi, runtime),
204
+ services: [binding.plugin]
205
+ };
206
+ };
207
+ //#endregion
208
+ //#region src/extensions/workspaces/sessions/(backend)/root.cli.ts
209
+ var root_cli_default = defineRoot(createHookPiRoot);
210
+ //#endregion
211
+ //#region src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.ts
212
+ var agent_settled_cli_default = defineCliHook((context) => context.root.agent_settled);
213
+ //#endregion
214
+ //#region src/extensions/workspaces/sessions/(backend)/hook/before-agent-start.cli.ts
215
+ var before_agent_start_cli_default = defineCliHook((context) => context.root.before_agent_start);
216
+ //#endregion
217
+ //#region src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.cli.ts
218
+ var session_shutdown_cli_default = defineCliHook((context) => context.root.session_shutdown);
219
+ //#endregion
220
+ //#region src/extensions/workspaces/sessions/(backend)/hook/session-start.cli.ts
221
+ var session_start_cli_default = defineCliHook((context) => context.root.session_start);
222
+ //#endregion
223
+ //#region src/extensions/workspaces/sessions/(backend)/hook/tool-call.cli.ts
224
+ var tool_call_cli_default = defineCliHook((context) => context.root.tool_call);
225
+ //#endregion
226
+ //#region src/extensions/workspaces/sessions/(backend)/hook/tool-result.cli.ts
227
+ var tool_result_cli_default = defineCliHook((context) => context.root.tool_result);
228
+ //#endregion
229
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompi-use-hook.cli.ts
230
+ var doompi_use_hook_cli_default = defineResource({
231
+ source: PACKAGE_SOURCE,
232
+ moduleUrl: import.meta.url,
233
+ skills: [HOOK_HELP_SKILL]
234
+ });
235
+ //#endregion
236
+ //#region generated/pi.ts
237
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
238
+ const extension = definePiExtension("@agimon-ai/doompi-hook", async (context) => {
239
+ const scopeSession = await root_cli_default(context);
240
+ const contextSession = {
241
+ ...context,
242
+ root: scopeSession.value
243
+ };
244
+ return {
245
+ ...composeRootHooks(scopeSession),
246
+ events: {
247
+ agent_settled: at(agent_settled_cli_default, contextSession),
248
+ before_agent_start: at(before_agent_start_cli_default, contextSession),
249
+ session_shutdown: at(session_shutdown_cli_default, contextSession),
250
+ session_start: at(session_start_cli_default, contextSession),
251
+ tool_call: at(tool_call_cli_default, contextSession),
252
+ tool_result: at(tool_result_cli_default, contextSession)
253
+ },
254
+ get resources() {
255
+ return [at(doompi_use_hook_cli_default, contextSession)];
256
+ },
257
+ services: [...scopeSession.services ?? []]
258
+ };
259
+ });
260
+ //#endregion
261
+ export { extension as default, extension };
262
+
263
+ //# sourceMappingURL=pi.mjs.map