@cmodjs/core 1.6.0 → 2.0.1

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 (136) hide show
  1. package/docs/commands.md +7 -7
  2. package/docs/dependencies.md +1 -1
  3. package/docs/index.md +12 -11
  4. package/docs/jobs.md +12 -16
  5. package/docs/mod.md +111 -36
  6. package/docs/permissions.md +14 -18
  7. package/docs/session.md +171 -82
  8. package/docs/state.md +5 -5
  9. package/docs/testing.md +57 -41
  10. package/docs/ui.md +9 -9
  11. package/jobs/permissions/decide-permission.d.ts.map +1 -1
  12. package/jobs/permissions/decide-permission.js +1 -1
  13. package/jobs/prompt.d.ts +1 -3
  14. package/jobs/prompt.d.ts.map +1 -1
  15. package/jobs/prompt.js +2 -21
  16. package/jobs/slash-command.d.ts +1 -1
  17. package/jobs/slash-command.d.ts.map +1 -1
  18. package/jobs/slash-command.js +1 -1
  19. package/jobs/status-line.d.ts +0 -1
  20. package/jobs/status-line.d.ts.map +1 -1
  21. package/jobs/status-line.js +3 -4
  22. package/mod.d.ts +53 -105
  23. package/mod.d.ts.map +1 -1
  24. package/mod.js +18 -80
  25. package/package.json +1 -1
  26. package/records.d.ts +1 -1
  27. package/records.js +1 -1
  28. package/register.d.ts.map +1 -1
  29. package/register.js +8 -5
  30. package/runtime/before.d.ts +11 -4
  31. package/runtime/before.d.ts.map +1 -1
  32. package/runtime/before.js +131 -67
  33. package/runtime/claude.d.ts +6 -1
  34. package/runtime/claude.d.ts.map +1 -1
  35. package/runtime/conversations.d.ts.map +1 -1
  36. package/runtime/conversations.js +82 -38
  37. package/runtime/deadline.d.ts +17 -0
  38. package/runtime/deadline.d.ts.map +1 -1
  39. package/runtime/deadline.js +34 -0
  40. package/runtime/dependencies.d.ts +2 -0
  41. package/runtime/dependencies.d.ts.map +1 -1
  42. package/runtime/dependencies.js +12 -0
  43. package/runtime/grants.d.ts.map +1 -1
  44. package/runtime/grants.js +13 -8
  45. package/runtime/hooks.d.ts +15 -11
  46. package/runtime/hooks.d.ts.map +1 -1
  47. package/runtime/hooks.js +8 -165
  48. package/runtime/lifecycle.d.ts +4 -2
  49. package/runtime/lifecycle.d.ts.map +1 -1
  50. package/runtime/lifecycle.js +96 -62
  51. package/runtime/permission-check.d.ts +15 -0
  52. package/runtime/permission-check.d.ts.map +1 -0
  53. package/runtime/permission-check.js +37 -0
  54. package/runtime/sessions.d.ts +35 -5
  55. package/runtime/sessions.d.ts.map +1 -1
  56. package/runtime/sessions.js +304 -82
  57. package/runtime/state.d.ts.map +1 -1
  58. package/runtime/state.js +14 -11
  59. package/runtime/tool-calls.d.ts +0 -1
  60. package/runtime/tool-calls.d.ts.map +1 -1
  61. package/runtime/tool-calls.js +0 -19
  62. package/session/context/turn/message/instruction-file.d.ts +9 -0
  63. package/session/context/turn/message/instruction-file.d.ts.map +1 -0
  64. package/session/context/turn/message/instruction-file.js +4 -0
  65. package/session/context/turn/message/message.d.ts +6 -4
  66. package/session/context/turn/message/message.d.ts.map +1 -1
  67. package/session/context/turn/message/message.js +12 -8
  68. package/session/context/turn/message/sender.d.ts +2 -1
  69. package/session/context/turn/message/sender.d.ts.map +1 -1
  70. package/session/context/turn/message/sender.js +4 -1
  71. package/session/context/turn/message/tool-call.d.ts +5 -0
  72. package/session/context/turn/message/tool-call.d.ts.map +1 -1
  73. package/session/context/turn/message/tool-result.d.ts +6 -1
  74. package/session/context/turn/message/tool-result.d.ts.map +1 -1
  75. package/session/context/turn/turn.d.ts +7 -0
  76. package/session/context/turn/turn.d.ts.map +1 -1
  77. package/session/conversation.d.ts +10 -3
  78. package/session/conversation.d.ts.map +1 -1
  79. package/session/conversation.js +14 -5
  80. package/session/goal/goal.d.ts +1 -1
  81. package/session/goal/goal.d.ts.map +1 -1
  82. package/session/goal/task.d.ts +2 -2
  83. package/session/goal/task.d.ts.map +1 -1
  84. package/session/session.d.ts +361 -26
  85. package/session/session.d.ts.map +1 -1
  86. package/session/session.js +40 -0
  87. package/src/jobs/permissions/decide-permission.ts +2 -1
  88. package/src/jobs/prompt.ts +3 -20
  89. package/src/jobs/slash-command.ts +2 -2
  90. package/src/jobs/status-line.ts +4 -7
  91. package/src/mod.ts +52 -147
  92. package/src/records.ts +1 -1
  93. package/src/register.ts +8 -5
  94. package/src/runtime/before.ts +140 -66
  95. package/src/runtime/claude.ts +5 -1
  96. package/src/runtime/conversations.ts +75 -37
  97. package/src/runtime/deadline.ts +38 -0
  98. package/src/runtime/dependencies.ts +12 -0
  99. package/src/runtime/grants.ts +11 -7
  100. package/src/runtime/hooks.ts +24 -163
  101. package/src/runtime/lifecycle.ts +110 -77
  102. package/src/runtime/permission-check.ts +47 -0
  103. package/src/runtime/sessions.ts +334 -91
  104. package/src/runtime/state.ts +15 -8
  105. package/src/runtime/tool-calls.ts +0 -19
  106. package/src/session/context/turn/message/instruction-file.ts +13 -0
  107. package/src/session/context/turn/message/message.ts +17 -11
  108. package/src/session/context/turn/message/sender.ts +5 -2
  109. package/src/session/context/turn/message/tool-call.ts +3 -0
  110. package/src/session/context/turn/message/tool-result.ts +6 -1
  111. package/src/session/context/turn/turn.ts +4 -0
  112. package/src/session/conversation.ts +21 -8
  113. package/src/session/goal/goal.ts +1 -1
  114. package/src/session/goal/task.ts +2 -2
  115. package/src/session/session.ts +227 -24
  116. package/src/testing/claude-code.ts +23 -0
  117. package/src/testing/fake-claude.ts +5 -1
  118. package/src/testing/fake-sessions.ts +38 -24
  119. package/src/testing.ts +88 -19
  120. package/testing/claude-code.d.ts +12 -0
  121. package/testing/claude-code.d.ts.map +1 -0
  122. package/testing/claude-code.js +10 -0
  123. package/testing/fake-claude.d.ts +4 -0
  124. package/testing/fake-claude.d.ts.map +1 -1
  125. package/testing/fake-claude.js +4 -1
  126. package/testing/fake-sessions.d.ts +8 -6
  127. package/testing/fake-sessions.d.ts.map +1 -1
  128. package/testing/fake-sessions.js +35 -20
  129. package/testing.d.ts +38 -9
  130. package/testing.d.ts.map +1 -1
  131. package/testing.js +58 -8
  132. package/docs/hooks.md +0 -259
  133. package/session/context/turn/message/document.d.ts +0 -7
  134. package/session/context/turn/message/document.d.ts.map +0 -1
  135. package/session/context/turn/message/document.js +0 -1
  136. package/src/session/context/turn/message/document.ts +0 -8
@@ -1,5 +1,39 @@
1
1
  export const longestMs = 600_000;
2
2
  export const toolDeadline = { ms: 30000, job: 'tool' };
3
+ export const listenerMs = 10_000;
4
+ export class PassedTimeout extends Error {
5
+ }
6
+ const timers = globalThis;
7
+ export function listenerOf(name, method, args) {
8
+ const hasMatcher = typeof args[1] === 'function';
9
+ const listener = (hasMatcher ? args[1] : args[0]);
10
+ const options = ((hasMatcher ? args[2] : args[1]) ?? {});
11
+ if (typeof listener !== 'function')
12
+ throw new Error(`${name}: ${method} takes a listener, or a matcher and then a listener.`);
13
+ const { timeoutMs, onFailure } = options;
14
+ if (timeoutMs !== undefined && (typeof timeoutMs !== 'number' || !Number.isInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > longestMs))
15
+ throw new Error(`${name}: ${method}'s timeoutMs is ${String(timeoutMs)}. Give a whole number of milliseconds above 0 and at most ${longestMs}.`);
16
+ if (onFailure !== undefined && onFailure !== 'pass' && onFailure !== 'refuse')
17
+ throw new Error(`${name}: ${method}'s onFailure is ${String(onFailure)}. Give 'pass' or 'refuse'.`);
18
+ return { matcher: hasMatcher ? args[0] : undefined, listener, options };
19
+ }
20
+ export async function withinTime(clock, method, { timeoutMs = listenerMs }, run) {
21
+ const controller = new AbortController();
22
+ const deadline = (await clock.now()) + timeoutMs;
23
+ let timer;
24
+ const passed = new Promise((_resolve, reject) => {
25
+ timer = timers.setTimeout(() => {
26
+ controller.abort();
27
+ reject(new PassedTimeout(`${method} passed its ${timeoutMs / 1000} s timeout`));
28
+ }, timeoutMs);
29
+ });
30
+ try {
31
+ return await Promise.race([Promise.resolve().then(() => run({ deadline, signal: controller.signal })), passed]);
32
+ }
33
+ finally {
34
+ timers.clearTimeout(timer);
35
+ }
36
+ }
3
37
  export function beforeDeadline(claude, { ms, job }, call, task) {
4
38
  return new Promise((resolve, reject) => {
5
39
  const passed = job === undefined ? `its ${ms / 1000} s deadline` : `the ${ms / 1000} s deadline of ${job}`;
@@ -1,10 +1,12 @@
1
1
  import type { Args, CmodDependencies, EventResult, Frozen } from 'claude-code';
2
2
  import type { Claude } from './claude.js';
3
+ import type { Router } from './router.js';
3
4
  export declare const cmodPluginName = "cmod";
4
5
  export declare function answerCall(name: string, api: {
5
6
  readonly [method: string]: (input: never) => unknown;
6
7
  }, e: Frozen<Args<'cmod.call'>>): Promise<EventResult<'cmod.call'>>;
7
8
  export declare function dependencyCalls(claude: Claude, within: (call: string, task: Promise<unknown>) => Promise<unknown>): CmodDependencies;
8
9
  export declare function withBareRefusals(claude: Claude): Claude;
10
+ export declare function answeringOwnCalls(claude: Claude, router: Router): Claude;
9
11
  export declare function notInstalled(name: string): string;
10
12
  //# sourceMappingURL=dependencies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../src/runtime/dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,eAAO,MAAM,cAAc,SAAS,CAAA;AAEpC,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;IAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;CAAE,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAQ7K;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAOpI;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD"}
1
+ {"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../src/runtime/dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,eAAO,MAAM,cAAc,SAAS,CAAA;AAEpC,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;IAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;CAAE,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAQ7K;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAOpI;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CASxE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD"}
@@ -23,6 +23,18 @@ export function withBareRefusals(claude) {
23
23
  });
24
24
  return { ...claude, cmod: { call } };
25
25
  }
26
+ export function answeringOwnCalls(claude, router) {
27
+ const name = claude.plugin.name;
28
+ const call = async (input) => {
29
+ if (input.to !== name)
30
+ return claude.cmod.call(input);
31
+ const answer = await router.dispatch('cmod.call', { ...input, caller: name }, async () => ({ deny: `${name} has no method ${input.method}.` }));
32
+ if (answer.deny !== undefined)
33
+ throw new Error(answer.deny);
34
+ return answer.value;
35
+ };
36
+ return { ...claude, cmod: { call } };
37
+ }
26
38
  export function notInstalled(name) {
27
39
  return `${name} is not installed. Add it with /plugin.`;
28
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../src/runtime/grants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG7C,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,CAAA;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,SAAS,MAAM,EAAE,CAAA;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,CAAA;CAClD,CAAA;AAED,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAI/C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAIzD;AAkBD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAItG;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1F;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAElJ;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAkFrE;AAmBD,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAWvG;AAiBD,wBAAgB,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9G;AA4BD,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1C,CAAA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAEzD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAa9G;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CA+BxJ"}
1
+ {"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../src/runtime/grants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG7C,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,CAAA;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,SAAS,MAAM,EAAE,CAAA;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,CAAA;CAClD,CAAA;AAED,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAI/C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAIzD;AAkBD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAItG;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1F;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAElJ;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAwFrE;AAmBD,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAWvG;AAiBD,wBAAgB,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9G;AA0BD,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1C,CAAA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAEzD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAa9G;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CA+BxJ"}
package/runtime/grants.js CHANGED
@@ -72,10 +72,6 @@ export function checkingGrants(claude, grants) {
72
72
  },
73
73
  session: {
74
74
  ...claude.session,
75
- messages: (async (...args) => {
76
- await gate('session.messages', 'conversation');
77
- return claude.session.messages(...args);
78
- }),
79
75
  append: async (args) => {
80
76
  await gate('send', 'prompt');
81
77
  return claude.session.append(args);
@@ -91,13 +87,24 @@ export function checkingGrants(claude, grants) {
91
87
  return claude.prompt.submit(args);
92
88
  },
93
89
  },
90
+ command: {
91
+ ...claude.command,
92
+ run: async (args) => {
93
+ await gate(`commands.run(${args.command})`, 'prompt');
94
+ return claude.command.run(args);
95
+ },
96
+ },
94
97
  cmod: {
95
98
  async call(args) {
96
99
  const named = args.to === cmodPluginName ? conversationCalls[args.method] : undefined;
97
100
  const given = args.method === conversationMethods.act && isObject(args.input) ? String(args.input['action']) : undefined;
98
101
  const action = given !== undefined && isAct(given) ? given : undefined;
99
- if (named !== undefined)
100
- await gate(action ?? named, action === undefined ? 'conversation' : actPermission(action, isObject(args.input) ? args.input['input'] : undefined));
102
+ const isThisSession = isObject(args.input) && args.input['session'] === (await claude.session.id());
103
+ const isDropping = (args.method === conversationMethods.subscribe || args.method === conversationMethods.watchBefore) && isObject(args.input) && Array.isArray(args.input['subscriptions']) && args.input['subscriptions'].length === 0;
104
+ if (named !== undefined && action !== undefined)
105
+ await gate(action, actPermission(action, isObject(args.input) ? args.input['input'] : undefined));
106
+ else if (named !== undefined && !isThisSession && !isDropping)
107
+ await gate(named, 'conversation');
101
108
  return claude.cmod.call(args);
102
109
  },
103
110
  },
@@ -191,10 +198,8 @@ function declaration(item, home) {
191
198
  const classicParts = {
192
199
  additionalContext: 'prompt',
193
200
  initialUserMessage: 'prompt',
194
- suppressOriginalPrompt: 'prompt',
195
201
  updatedToolOutput: 'prompt',
196
202
  updatedMCPToolOutput: 'prompt',
197
- updatedInput: 'tools',
198
203
  retry: 'approve',
199
204
  };
200
205
  const blocksKeepWorking = ['classic.Stop', 'classic.PostToolUse'];
@@ -1,19 +1,23 @@
1
- import type { Hook, HookListener } from '../mod.js';
1
+ import type { ClassicHookEvent, ClassicHookInputs } from 'claude-code';
2
2
  import type { Claude } from './claude.js';
3
3
  import type { RoutedHook } from './router.js';
4
4
  import type { Failure } from './toaster.js';
5
- import { type ToolCalls } from './tool-calls.js';
6
- export type RoutedEvent = `classic.${Exclude<Hook, 'PreToolUse'>}` | 'tool.check' | 'tool.call' | 'prompt.submit' | 'prompt.context' | 'prompt.attachment' | 'command.run' | 'session.measure' | 'skill.prompt' | 'ui.render' | 'ui.press' | 'ui.scroll' | 'ui.close' | 'cmod.call' | 'session.append' | 'session.compact' | 'session.receive' | 'agent.spawn';
5
+ import { type CallBase } from '../utils/call-effects.js';
6
+ export type Hook = Exclude<ClassicHookEvent, 'PreToolUse'>;
7
+ export type HookFields = Readonly<Record<string, unknown>>;
8
+ export type HookListener<H extends Hook> = (input: ClassicHookInputs[H]) => HookFields | undefined | Promise<HookFields | undefined>;
9
+ export type RoutedEvent = `classic.${Hook}` | 'tool.check' | 'tool.call' | 'prompt.submit' | 'prompt.context' | 'prompt.attachment' | 'command.run' | 'session.measure' | 'skill.prompt' | 'ui.render' | 'ui.press' | 'ui.scroll' | 'ui.close' | 'cmod.call' | 'session.append' | 'session.compact' | 'session.receive' | 'agent.spawn' | 'turn.start';
7
10
  export declare const permissionEvents: readonly RoutedEvent[];
8
- export declare function classicHook<E extends Exclude<Hook, 'PreToolUse'>>(name: string, event: E, hook: HookListener<E>, claude: Claude, calls: ToolCalls, report: (failure: Failure) => void): RoutedHook<RoutedEvent>;
9
- type HeldDecision = {
10
- readonly decision: 'allow' | 'ask';
11
- readonly reason?: string;
11
+ type CallFiles = {
12
+ readonly read: string[];
13
+ readonly changed: string[];
12
14
  };
13
- export type HeldDecisions = Map<string, HeldDecision>;
14
- export declare function preToolUseHook(name: string, hook: HookListener<'PreToolUse'>, claude: Claude, calls: ToolCalls, held: HeldDecisions | undefined): RoutedHook<'tool.call'>;
15
- export declare function heldDecisionHook(held: HeldDecisions): RoutedHook<'tool.check'>;
15
+ export declare function classicHook<H extends Hook>(event: H, hook: HookListener<H>, report: (failure: Failure) => void): RoutedHook<RoutedEvent>;
16
16
  export declare function userSkillHook(claude: Claude): RoutedHook<'skill.prompt'>;
17
- export declare const strictness: readonly ['allow', 'ask', 'deny'];
17
+ export type HomeFolders = {
18
+ readonly home: string | undefined;
19
+ readonly configRoot: string | undefined;
20
+ };
21
+ export declare function callFiles(name: string, claude: Claude, folders: Promise<HomeFolders>, use: CallBase, cwd: string): Promise<CallFiles>;
18
22
  export {};
19
23
  //# sourceMappingURL=hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/runtime/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAyB,YAAY,EAAE,MAAM,WAAW,CAAA;AAE1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAM3E,MAAM,MAAM,WAAW,GACnB,WAAW,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,GACxC,YAAY,GACZ,WAAW,GACX,eAAe,GACf,gBAAgB,GAChB,mBAAmB,GACnB,aAAa,GACb,iBAAiB,GACjB,cAAc,GACd,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,GACX,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,aAAa,CAAA;AAEjB,eAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,EAAgD,CAAA;AA4CnG,wBAAgB,WAAW,CAAC,CAAC,SAAS,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAuB/M;AAED,KAAK,YAAY,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpF,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;AAErD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,CA6BzK;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAAC,YAAY,CAAC,CAM9E;AAYD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,cAAc,CAAC,CAexE;AAgED,eAAO,MAAM,UAAU,YAAI,OAAO,EAAE,KAAK,EAAE,MAAM,CAAU,CAAA"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/runtime/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAe,KAAK,QAAQ,EAAmB,MAAM,0BAA0B,CAAA;AAKtF,MAAM,MAAM,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAA;AAE1D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAE1D,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAA;AAEpI,MAAM,MAAM,WAAW,GACnB,WAAW,IAAI,EAAE,GACjB,YAAY,GACZ,WAAW,GACX,eAAe,GACf,gBAAgB,GAChB,mBAAmB,GACnB,aAAa,GACb,iBAAiB,GACjB,cAAc,GACd,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,GACX,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,aAAa,GACb,YAAY,CAAA;AAEhB,eAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,EAAgD,CAAA;AAEnG,KAAK,SAAS,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAExE,wBAAgB,WAAW,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAYxI;AAMD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,cAAc,CAAC,CAexE;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAExG,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAgB3I"}
package/runtime/hooks.js CHANGED
@@ -1,67 +1,15 @@
1
1
  import { configFolders } from '../records.js';
2
- import { reservedKeys, toolInputOf } from './tool-calls.js';
3
- import { callEffects, inputOf } from '../utils/call-effects.js';
2
+ import { callEffects } from '../utils/call-effects.js';
4
3
  import { dynamicPattern } from '../utils/parse-shell.js';
5
4
  import { isMissing } from '../utils/paths.js';
6
5
  import { messageOf } from '../utils/text.js';
7
6
  export const permissionEvents = ['tool.check', 'classic.PermissionRequest'];
8
- const flags = ['suppressOriginalPrompt', 'reloadSkills', 'retry'];
9
- const readFields = {
10
- Setup: ['additionalContext'],
11
- SessionStart: ['additionalContext', 'initialUserMessage', 'sessionTitle', 'watchPaths', 'reloadSkills'],
12
- SessionEnd: [],
13
- UserPromptSubmit: ['additionalContext', 'sessionTitle', 'suppressOriginalPrompt'],
14
- UserPromptExpansion: ['additionalContext', 'suppressOriginalPrompt'],
15
- InstructionsLoaded: [],
16
- ConfigChange: [],
17
- DirectoryAdded: [],
18
- PreModelSwitch: ['permissionDecision', 'permissionDecisionReason'],
19
- PostModelSwitch: ['additionalContext'],
20
- PreToolUse: ['additionalContext', 'permissionDecision', 'permissionDecisionReason', 'updatedInput'],
21
- PermissionRequest: ['decision'],
22
- PermissionDenied: ['retry'],
23
- PostToolUse: ['additionalContext', 'updatedToolOutput', 'updatedMCPToolOutput'],
24
- PostToolUseFailure: ['additionalContext'],
25
- PostToolBatch: ['additionalContext'],
26
- MessageDisplay: ['displayContent'],
27
- SubagentStart: ['additionalContext'],
28
- SubagentStop: ['additionalContext'],
29
- TaskCreated: [],
30
- TaskCompleted: [],
31
- TeammateIdle: [],
32
- Elicitation: [],
33
- ElicitationResult: [],
34
- Notification: [],
35
- PreCompact: [],
36
- PostCompact: [],
37
- Stop: ['additionalContext'],
38
- StopFailure: [],
39
- CwdChanged: [],
40
- FileChanged: [],
41
- WorktreeCreate: ['worktreePath'],
42
- WorktreeRemove: [],
43
- };
44
- export function classicHook(name, event, hook, claude, calls, report) {
45
- const hookInputOf = async (e) => {
46
- if (event !== 'PostToolUse' && event !== 'PostToolUseFailure')
47
- return e;
48
- const input = e;
49
- const cwd = calls.cwdOf(input.tool_use_id) ?? input.cwd;
50
- return { ...input, files: await callFiles(name, claude, { tool: input.tool_name, input: inputOf(input.tool_input) }, cwd) };
51
- };
52
- const resultOf = async (e) => {
53
- const answer = await hook((await hookInputOf(e)));
54
- if (answer === undefined)
55
- return undefined;
56
- if (answer.systemMessage !== undefined)
57
- claude.ui.log(answer.systemMessage);
58
- return classicResult(event, answer);
59
- };
7
+ export function classicHook(event, hook, report) {
60
8
  const routed = async (e, next) => {
61
- const ours = await resultOf(e).catch((error) => {
62
- if (event === 'PermissionRequest')
63
- return { decision: { behavior: 'deny', message: `${name}: the ${event} hook failed: ${messageOf(error)}` } };
64
- report({ id: `hook:${event}`, message: `The ${event} hook failed`, error });
9
+ const ours = await Promise.resolve()
10
+ .then(() => hook(e))
11
+ .catch((error) => {
12
+ report({ id: `hook:${event}`, message: `The ${event} listener failed`, error });
65
13
  return undefined;
66
14
  });
67
15
  if (ours === undefined)
@@ -70,57 +18,6 @@ export function classicHook(name, event, hook, claude, calls, report) {
70
18
  };
71
19
  return routed;
72
20
  }
73
- export function preToolUseHook(name, hook, claude, calls, held) {
74
- return async (e, next) => {
75
- let ours;
76
- try {
77
- const answer = await hook(await preToolUseInput(name, e, claude, calls.agentOf));
78
- if (answer?.systemMessage !== undefined)
79
- claude.ui.log(answer.systemMessage);
80
- ours = answer === undefined ? {} : classicResult('PreToolUse', answer);
81
- }
82
- catch (error) {
83
- return { deny: `${name}: the PreToolUse hook failed: ${messageOf(error)}` };
84
- }
85
- if (typeof ours['deny'] === 'string')
86
- return { deny: ours['deny'] };
87
- const decided = heldDecisionOf(ours);
88
- if (decided !== undefined && held === undefined) {
89
- return { deny: `${name}: the PreToolUse hook answered permissionDecision "${decided.decision}", so hooks/register.ts must call registerPermissionCheck(addHook) after registerMod.` };
90
- }
91
- const updated = ours['updatedInput'];
92
- const reserved = Object.fromEntries(Object.entries(e).filter(([key]) => reservedKeys.includes(key)));
93
- const earlier = held?.get(e.tool_use_id);
94
- if (decided !== undefined)
95
- held?.set(e.tool_use_id, earlier !== undefined && strictness.indexOf(earlier.decision) >= strictness.indexOf(decided.decision) ? earlier : decided);
96
- let result;
97
- try {
98
- result = await next(updated === undefined ? e : { ...reserved, ...updated });
99
- }
100
- finally {
101
- if (decided !== undefined)
102
- held?.delete(e.tool_use_id);
103
- }
104
- const context = ours['additionalContext'];
105
- if (context === undefined || result.deny !== undefined)
106
- return result;
107
- return { ...result, context: [...(result.context ?? []), ...context] };
108
- };
109
- }
110
- export function heldDecisionHook(held) {
111
- return async (e, next) => {
112
- const below = await next(e);
113
- const ours = e.tool_use_id === undefined ? undefined : held.get(e.tool_use_id);
114
- return ours === undefined || below.decision === 'deny' ? below : ours;
115
- };
116
- }
117
- function heldDecisionOf(ours) {
118
- if (ours['allow'] !== undefined)
119
- return { decision: 'allow' };
120
- if (typeof ours['ask'] !== 'string')
121
- return undefined;
122
- return ours['ask'] === '' ? { decision: 'ask' } : { decision: 'ask', reason: ours['ask'] };
123
- }
124
21
  const frontmatter = /^---\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/;
125
22
  const baseDirectoryLine = /^Base directory for this skill: [^\n]*\n\n/;
126
23
  export function userSkillHook(claude) {
@@ -143,25 +40,9 @@ export function userSkillHook(claude) {
143
40
  return next(e);
144
41
  };
145
42
  }
146
- async function preToolUseInput(name, envelope, claude, agentOf) {
147
- const { tool, tool_use_id } = envelope;
148
- const [session_id, cwd, { agentId, agentType }] = await Promise.all([claude.session.id(), claude.session.cwd(), agentOf(tool_use_id)]);
149
- const tool_input = toolInputOf(envelope);
150
- return {
151
- session_id,
152
- cwd,
153
- hook_event_name: 'PreToolUse',
154
- tool_name: tool,
155
- tool_input,
156
- tool_use_id,
157
- ...(agentId === undefined ? {} : { agent_id: agentId }),
158
- ...(agentType === undefined ? {} : { agent_type: agentType }),
159
- files: await callFiles(name, claude, { tool, input: tool_input }, cwd),
160
- };
161
- }
162
- async function callFiles(name, claude, use, cwd) {
43
+ export async function callFiles(name, claude, folders, use, cwd) {
163
44
  try {
164
- const [home, configRoot] = await Promise.all([claude.env.home(), claude.env.configHome()]);
45
+ const { home, configRoot } = await folders;
165
46
  if (home === undefined)
166
47
  throw new Error('HOME is not set, so ~ in a path has no meaning.');
167
48
  const { shell, reads, writes } = callEffects(use, { cwd, home, ...(configRoot === undefined ? {} : { configRoot }), fs: claude.fs });
@@ -179,44 +60,6 @@ async function callFiles(name, claude, use, cwd) {
179
60
  return { read: [], changed: [] };
180
61
  }
181
62
  }
182
- function classicResult(event, answer) {
183
- const result = {};
184
- const unread = (field) => new Error(`it answered ${field}, which ${event} does not read. Remove it from the answer.`);
185
- if (event === 'PreToolUse') {
186
- if (answer.continue === false || answer.stopReason !== undefined)
187
- throw unread('continue or stopReason');
188
- if (answer.decision === 'block')
189
- result['deny'] = answer.reason ?? '';
190
- }
191
- else {
192
- if (answer.continue === false)
193
- result['preventContinuation'] = true;
194
- if (answer.stopReason !== undefined)
195
- result['stopReason'] = answer.stopReason;
196
- if (answer.decision === 'block')
197
- result['block'] = answer.reason ?? '';
198
- }
199
- const specific = answer.hookSpecificOutput ?? {};
200
- if (specific.hookEventName !== undefined && specific.hookEventName !== event) {
201
- throw new Error(`it answered hookSpecificOutput.hookEventName "${specific.hookEventName}". Set it to "${event}" or leave it out.`);
202
- }
203
- for (const [field, value] of Object.entries(specific)) {
204
- if (field === 'hookEventName' || value === undefined || (value === false && flags.includes(field)))
205
- continue;
206
- if (!readFields[event].includes(field))
207
- throw unread(`hookSpecificOutput.${field}`);
208
- if (field === 'additionalContext')
209
- result['additionalContext'] = [value];
210
- else if (field === 'permissionDecision' && event === 'PreToolUse') {
211
- const reason = specific.permissionDecisionReason ?? '';
212
- result[value] = value === 'allow' ? true : reason;
213
- }
214
- else if (field !== 'permissionDecisionReason' || event !== 'PreToolUse')
215
- result[field] = value;
216
- }
217
- return result;
218
- }
219
- export const strictness = ['allow', 'ask', 'deny'];
220
63
  function mergeClassic(below, ours) {
221
64
  const merged = { ...below, ...ours };
222
65
  const context = [...(below['additionalContext'] ?? []), ...(ours['additionalContext'] ?? [])];
@@ -1,9 +1,10 @@
1
1
  import type { Args, EventResult, Frozen, PluginOptions } from 'claude-code';
2
- import { type Mod, type ModDefinition } from '../mod.js';
2
+ import type { Mod, ModDefinition } from '../mod.js';
3
3
  import type { Options } from '../options.js';
4
4
  import { type Steps } from '../records.js';
5
5
  import type { Claude } from './claude.js';
6
6
  import { type RoutedEvent } from './hooks.js';
7
+ import type { PermissionRoutes } from './permission-check.js';
7
8
  import { type RouterNext } from './router.js';
8
9
  import { type ShownToast } from './toaster.js';
9
10
  export type Plugin = {
@@ -24,7 +25,8 @@ export type Lifecycle<State extends object> = {
24
25
  readonly toasts: readonly ShownToast[];
25
26
  start(claude: Claude, read: (claude: Claude) => Promise<Plugin>): Promise<void>;
26
27
  route<N extends RoutedEvent>(event: N, e: Frozen<Args<N>>, next: RouterNext<N>): Promise<EventResult<N>>;
28
+ raise(method: string, payload: Readonly<Record<string, unknown>>): Promise<unknown>;
27
29
  };
28
30
  export declare function readPlugin(claude: Claude): Promise<Plugin>;
29
- export declare function createLifecycle<State extends object, Declared extends Options = Options>(definition: ModDefinition<State, string, Declared>, checksPermissions?: () => boolean, options?: PluginOptions, asksPerson?: boolean): Lifecycle<State>;
31
+ export declare function createLifecycle<State extends object, Declared extends Options = Options>(definition: ModDefinition<State, string, Declared>, permissionRoutes?: () => PermissionRoutes | undefined, options?: PluginOptions, asksPerson?: boolean): Lifecycle<State>;
30
32
  //# sourceMappingURL=lifecycle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/runtime/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAc,aAAa,EAAwB,MAAM,aAAa,CAAA;AAE7G,OAAO,EAAkI,KAAK,GAAG,EAAE,KAAK,aAAa,EAAkD,MAAM,WAAW,CAAA;AACxO,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,eAAe,CAAA;AAC1D,OAAO,EAA2T,KAAK,KAAK,EAAE,MAAM,eAAe,CAAA;AAGnW,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAOzC,OAAO,EAAsG,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAOjJ,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAMxE,OAAO,EAA+B,KAAK,UAAU,EAAgB,MAAM,cAAc,CAAA;AAMzF,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEtG,MAAM,MAAM,SAAS,CAAC,KAAK,SAAS,MAAM,IAAI;IAC5C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAA;IACtC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/E,KAAK,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;CACzG,CAAA;AAwCD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBhE;AAkCD,wBAAgB,eAAe,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,OAAO,GAAG,OAAO,EACtF,UAAU,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAClD,iBAAiB,GAAE,MAAM,OAAoB,EAC7C,OAAO,GAAE,aAAkB,EAC3B,UAAU,UAAO,GAChB,SAAS,CAAC,KAAK,CAAC,CAkclB"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/runtime/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAc,aAAa,EAAwB,MAAM,aAAa,CAAA;AAE7G,OAAO,KAAK,EAA4C,GAAG,EAAE,aAAa,EAAmF,MAAM,WAAW,CAAA;AAC9K,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,eAAe,CAAA;AAC1D,OAAO,EAA2T,KAAK,KAAK,EAAE,MAAM,eAAe,CAAA;AAGnW,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAOzC,OAAO,EAA8E,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACzH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO7D,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAMxE,OAAO,EAA+B,KAAK,UAAU,EAAgB,MAAM,cAAc,CAAA;AAMzF,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEtG,MAAM,MAAM,SAAS,CAAC,KAAK,SAAS,MAAM,IAAI;IAC5C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAA;IACtC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/E,KAAK,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;IACxG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACpF,CAAA;AA2CD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBhE;AAkCD,wBAAgB,eAAe,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,OAAO,GAAG,OAAO,EACtF,UAAU,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAClD,gBAAgB,GAAE,MAAM,gBAAgB,GAAG,SAA2B,EACtE,OAAO,GAAE,aAAkB,EAC3B,UAAU,UAAO,GAChB,SAAS,CAAC,KAAK,CAAC,CAsdlB"}