@cmodjs/core 0.3.0 → 1.5.0

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 (280) hide show
  1. package/docs/commands.md +61 -10
  2. package/docs/dependencies.md +16 -14
  3. package/docs/hooks.md +64 -29
  4. package/docs/index.md +29 -25
  5. package/docs/install-steps.md +13 -9
  6. package/docs/jobs.md +59 -111
  7. package/docs/mod.md +227 -175
  8. package/docs/options.md +2 -2
  9. package/docs/permissions.md +27 -16
  10. package/docs/session.md +311 -0
  11. package/docs/state.md +11 -7
  12. package/docs/testing.md +68 -23
  13. package/docs/ui.md +116 -76
  14. package/jobs/check.d.ts.map +1 -1
  15. package/jobs/check.js +5 -2
  16. package/jobs/context.d.ts +7 -8
  17. package/jobs/context.d.ts.map +1 -1
  18. package/jobs/context.js +23 -73
  19. package/jobs/permissions/decide-permission.d.ts +5 -3
  20. package/jobs/permissions/decide-permission.d.ts.map +1 -1
  21. package/jobs/permissions/decide-permission.js +6 -4
  22. package/jobs/permissions/find-project-scope.d.ts +1 -1
  23. package/jobs/permissions/find-project-scope.d.ts.map +1 -1
  24. package/jobs/permissions/find-project-scope.js +8 -11
  25. package/jobs/permissions/match-target.d.ts +2 -2
  26. package/jobs/permissions/match-target.d.ts.map +1 -1
  27. package/jobs/permissions.d.ts +1 -1
  28. package/jobs/permissions.d.ts.map +1 -1
  29. package/jobs/permissions.js +6 -4
  30. package/jobs/program.d.ts.map +1 -1
  31. package/jobs/program.js +14 -4
  32. package/jobs/prompt.d.ts +4 -2
  33. package/jobs/prompt.d.ts.map +1 -1
  34. package/jobs/prompt.js +16 -15
  35. package/jobs/schedule.d.ts +2 -2
  36. package/jobs/schedule.d.ts.map +1 -1
  37. package/jobs/schedule.js +9 -9
  38. package/jobs/slash-command.d.ts +4 -4
  39. package/jobs/slash-command.d.ts.map +1 -1
  40. package/jobs/slash-command.js +14 -9
  41. package/jobs/status-line.d.ts +1 -11
  42. package/jobs/status-line.d.ts.map +1 -1
  43. package/jobs/status-line.js +8 -12
  44. package/jobs/tool.d.ts +2 -2
  45. package/jobs/tool.d.ts.map +1 -1
  46. package/jobs/tool.js +15 -9
  47. package/mod.d.ts +178 -75
  48. package/mod.d.ts.map +1 -1
  49. package/mod.js +127 -3
  50. package/options.d.ts +2 -2
  51. package/options.js +19 -19
  52. package/package.json +3 -3
  53. package/records.d.ts +13 -8
  54. package/records.d.ts.map +1 -1
  55. package/records.js +33 -17
  56. package/register.d.ts.map +1 -1
  57. package/register.js +34 -5
  58. package/runtime/announce.d.ts +18 -0
  59. package/runtime/announce.d.ts.map +1 -0
  60. package/runtime/announce.js +68 -0
  61. package/runtime/before.d.ts +32 -0
  62. package/runtime/before.d.ts.map +1 -0
  63. package/runtime/before.js +214 -0
  64. package/runtime/bound.d.ts +4 -0
  65. package/runtime/bound.d.ts.map +1 -0
  66. package/runtime/bound.js +9 -0
  67. package/runtime/claude.d.ts +4 -2
  68. package/runtime/claude.d.ts.map +1 -1
  69. package/runtime/conversations.d.ts +17 -0
  70. package/runtime/conversations.d.ts.map +1 -0
  71. package/runtime/conversations.js +563 -0
  72. package/runtime/deadline.d.ts +0 -1
  73. package/runtime/deadline.d.ts.map +1 -1
  74. package/runtime/deadline.js +1 -1
  75. package/runtime/dependencies.d.ts +2 -0
  76. package/runtime/dependencies.d.ts.map +1 -1
  77. package/runtime/dependencies.js +10 -1
  78. package/runtime/engine.d.ts +13 -0
  79. package/runtime/engine.d.ts.map +1 -0
  80. package/runtime/engine.js +10 -0
  81. package/runtime/grants.d.ts +4 -0
  82. package/runtime/grants.d.ts.map +1 -1
  83. package/runtime/grants.js +68 -31
  84. package/runtime/hooks.d.ts +5 -4
  85. package/runtime/hooks.d.ts.map +1 -1
  86. package/runtime/hooks.js +29 -9
  87. package/runtime/installer.d.ts +1 -1
  88. package/runtime/installer.d.ts.map +1 -1
  89. package/runtime/installer.js +17 -14
  90. package/runtime/lifecycle.d.ts +3 -1
  91. package/runtime/lifecycle.d.ts.map +1 -1
  92. package/runtime/lifecycle.js +414 -212
  93. package/runtime/metadata.d.ts +3 -1
  94. package/runtime/metadata.d.ts.map +1 -1
  95. package/runtime/metadata.js +25 -14
  96. package/runtime/options.d.ts +3 -1
  97. package/runtime/options.d.ts.map +1 -1
  98. package/runtime/options.js +4 -4
  99. package/runtime/programs.d.ts +8 -0
  100. package/runtime/programs.d.ts.map +1 -1
  101. package/runtime/programs.js +39 -1
  102. package/runtime/router.d.ts +2 -1
  103. package/runtime/router.d.ts.map +1 -1
  104. package/runtime/router.js +11 -3
  105. package/runtime/sessions.d.ts +58 -0
  106. package/runtime/sessions.d.ts.map +1 -0
  107. package/runtime/sessions.js +433 -0
  108. package/runtime/state.d.ts +6 -2
  109. package/runtime/state.d.ts.map +1 -1
  110. package/runtime/state.js +46 -13
  111. package/runtime/toaster.d.ts +24 -0
  112. package/runtime/toaster.d.ts.map +1 -0
  113. package/runtime/toaster.js +286 -0
  114. package/runtime/ui.d.ts +6 -17
  115. package/runtime/ui.d.ts.map +1 -1
  116. package/runtime/ui.js +62 -118
  117. package/session/context/context.d.ts +12 -0
  118. package/session/context/context.d.ts.map +1 -0
  119. package/session/context/context.js +2 -0
  120. package/session/context/turn/message/document.d.ts +7 -0
  121. package/session/context/turn/message/document.d.ts.map +1 -0
  122. package/session/context/turn/message/document.js +1 -0
  123. package/session/context/turn/message/message.d.ts +55 -0
  124. package/session/context/turn/message/message.d.ts.map +1 -0
  125. package/session/context/turn/message/message.js +178 -0
  126. package/session/context/turn/message/note.d.ts +8 -0
  127. package/session/context/turn/message/note.d.ts.map +1 -0
  128. package/session/context/turn/message/note.js +1 -0
  129. package/session/context/turn/message/notice.d.ts +6 -0
  130. package/session/context/turn/message/notice.d.ts.map +1 -0
  131. package/session/context/turn/message/notice.js +1 -0
  132. package/session/context/turn/message/prompt.d.ts +8 -0
  133. package/session/context/turn/message/prompt.d.ts.map +1 -0
  134. package/session/context/turn/message/prompt.js +1 -0
  135. package/session/context/turn/message/reply.d.ts +6 -0
  136. package/session/context/turn/message/reply.d.ts.map +1 -0
  137. package/session/context/turn/message/reply.js +1 -0
  138. package/session/context/turn/message/sender.d.ts +14 -0
  139. package/session/context/turn/message/sender.d.ts.map +1 -0
  140. package/session/context/turn/message/sender.js +30 -0
  141. package/session/context/turn/message/skill.d.ts +7 -0
  142. package/session/context/turn/message/skill.d.ts.map +1 -0
  143. package/session/context/turn/message/skill.js +1 -0
  144. package/session/context/turn/message/tool-call.d.ts +9 -0
  145. package/session/context/turn/message/tool-call.d.ts.map +1 -0
  146. package/session/context/turn/message/tool-call.js +1 -0
  147. package/session/context/turn/message/tool-result.d.ts +8 -0
  148. package/session/context/turn/message/tool-result.d.ts.map +1 -0
  149. package/session/context/turn/message/tool-result.js +1 -0
  150. package/session/context/turn/turn.d.ts +13 -0
  151. package/session/context/turn/turn.d.ts.map +1 -0
  152. package/session/context/turn/turn.js +2 -0
  153. package/session/conversation.d.ts +73 -0
  154. package/session/conversation.d.ts.map +1 -0
  155. package/session/conversation.js +146 -0
  156. package/session/goal/goal.d.ts +11 -0
  157. package/session/goal/goal.d.ts.map +1 -0
  158. package/session/goal/goal.js +1 -0
  159. package/session/goal/task.d.ts +16 -0
  160. package/session/goal/task.d.ts.map +1 -0
  161. package/session/goal/task.js +3 -0
  162. package/session/session.d.ts +158 -0
  163. package/session/session.d.ts.map +1 -0
  164. package/session/session.js +2 -0
  165. package/src/jobs/check.ts +7 -4
  166. package/src/jobs/context.ts +24 -82
  167. package/src/jobs/permissions/decide-permission.ts +10 -8
  168. package/src/jobs/permissions/find-project-scope.ts +8 -14
  169. package/src/jobs/permissions/match-target.ts +3 -3
  170. package/src/jobs/permissions.ts +8 -6
  171. package/src/jobs/program.ts +13 -4
  172. package/src/jobs/prompt.ts +21 -24
  173. package/src/jobs/schedule.ts +14 -14
  174. package/src/jobs/slash-command.ts +20 -14
  175. package/src/jobs/status-line.ts +9 -21
  176. package/src/jobs/tool.ts +17 -11
  177. package/src/mod.ts +252 -97
  178. package/src/options.ts +22 -22
  179. package/src/records.ts +40 -23
  180. package/src/register.ts +34 -5
  181. package/src/runtime/announce.ts +76 -0
  182. package/src/runtime/before.ts +200 -0
  183. package/src/runtime/bound.ts +12 -0
  184. package/src/runtime/claude.ts +7 -2
  185. package/src/runtime/conversations.ts +579 -0
  186. package/src/runtime/deadline.ts +2 -2
  187. package/src/runtime/dependencies.ts +13 -1
  188. package/src/runtime/engine.ts +23 -0
  189. package/src/runtime/grants.ts +69 -29
  190. package/src/runtime/hooks.ts +39 -14
  191. package/src/runtime/installer.ts +16 -14
  192. package/src/runtime/lifecycle.ts +413 -201
  193. package/src/runtime/metadata.ts +37 -14
  194. package/src/runtime/options.ts +19 -4
  195. package/src/runtime/programs.ts +40 -1
  196. package/src/runtime/router.ts +11 -4
  197. package/src/runtime/sessions.ts +447 -0
  198. package/src/runtime/state.ts +50 -14
  199. package/src/runtime/toaster.ts +334 -0
  200. package/src/runtime/ui.ts +65 -143
  201. package/src/session/context/context.ts +14 -0
  202. package/src/session/context/turn/message/document.ts +8 -0
  203. package/src/session/context/turn/message/message.ts +203 -0
  204. package/src/session/context/turn/message/note.ts +9 -0
  205. package/src/session/context/turn/message/notice.ts +7 -0
  206. package/src/session/context/turn/message/prompt.ts +9 -0
  207. package/src/session/context/turn/message/reply.ts +7 -0
  208. package/src/session/context/turn/message/sender.ts +38 -0
  209. package/src/session/context/turn/message/skill.ts +8 -0
  210. package/src/session/context/turn/message/tool-call.ts +10 -0
  211. package/src/session/context/turn/message/tool-result.ts +9 -0
  212. package/src/session/context/turn/turn.ts +15 -0
  213. package/src/session/conversation.ts +194 -0
  214. package/src/session/goal/goal.ts +10 -0
  215. package/src/session/goal/task.ts +19 -0
  216. package/src/session/session.ts +141 -0
  217. package/src/testing/fake-claude.ts +25 -17
  218. package/src/testing/fake-elements.ts +3 -2
  219. package/src/testing/fake-files.ts +1 -1
  220. package/src/testing/fake-sessions.ts +277 -0
  221. package/src/testing.ts +138 -35
  222. package/src/ui/components.ts +3 -3
  223. package/src/ui/elements.ts +22 -8
  224. package/src/ui/markdown.ts +22 -26
  225. package/src/ui/places.ts +49 -0
  226. package/src/utils/call-effects.ts +5 -5
  227. package/src/utils/changelog.ts +32 -0
  228. package/src/utils/disposable.ts +3 -0
  229. package/src/utils/matcher.ts +37 -0
  230. package/src/utils/metadata.ts +17 -15
  231. package/src/utils/parse-shell.ts +9 -8
  232. package/src/utils/paths.ts +21 -4
  233. package/src/utils/text.ts +4 -0
  234. package/testing/fake-claude.d.ts +5 -1
  235. package/testing/fake-claude.d.ts.map +1 -1
  236. package/testing/fake-claude.js +21 -12
  237. package/testing/fake-elements.js +4 -2
  238. package/testing/fake-files.js +1 -1
  239. package/testing/fake-sessions.d.ts +81 -0
  240. package/testing/fake-sessions.d.ts.map +1 -0
  241. package/testing/fake-sessions.js +249 -0
  242. package/testing.d.ts +34 -13
  243. package/testing.d.ts.map +1 -1
  244. package/testing.js +115 -23
  245. package/ui/components.d.ts +2 -3
  246. package/ui/components.d.ts.map +1 -1
  247. package/ui/components.js +3 -3
  248. package/ui/elements.d.ts.map +1 -1
  249. package/ui/elements.js +19 -9
  250. package/ui/markdown.d.ts +35 -33
  251. package/ui/markdown.d.ts.map +1 -1
  252. package/ui/markdown.js +14 -16
  253. package/ui/places.d.ts +43 -0
  254. package/ui/places.d.ts.map +1 -0
  255. package/ui/places.js +31 -0
  256. package/utils/call-effects.d.ts +2 -1
  257. package/utils/call-effects.d.ts.map +1 -1
  258. package/utils/call-effects.js +3 -3
  259. package/utils/changelog.d.ts +9 -0
  260. package/utils/changelog.d.ts.map +1 -0
  261. package/utils/changelog.js +29 -0
  262. package/utils/disposable.d.ts +4 -0
  263. package/utils/disposable.d.ts.map +1 -0
  264. package/utils/disposable.js +1 -0
  265. package/utils/matcher.d.ts +13 -0
  266. package/utils/matcher.d.ts.map +1 -0
  267. package/utils/matcher.js +32 -0
  268. package/utils/metadata.d.ts +3 -3
  269. package/utils/metadata.js +18 -14
  270. package/utils/parse-shell.js +9 -7
  271. package/utils/paths.d.ts +4 -1
  272. package/utils/paths.d.ts.map +1 -1
  273. package/utils/paths.js +19 -4
  274. package/utils/text.d.ts +1 -0
  275. package/utils/text.d.ts.map +1 -1
  276. package/utils/text.js +3 -0
  277. package/src/ui/slots.ts +0 -36
  278. package/ui/slots.d.ts +0 -208
  279. package/ui/slots.d.ts.map +0 -1
  280. package/ui/slots.js +0 -19
package/mod.js CHANGED
@@ -1,7 +1,112 @@
1
1
  import { checkOptions } from './options.js';
2
- export { longestMs } from './runtime/deadline.js';
3
- export { notInstalled } from './runtime/dependencies.js';
4
- export { messageOf } from './utils/text.js';
2
+ import { bound } from './runtime/bound.js';
3
+ import { Mod as modSender } from './session/context/turn/message/sender.js';
4
+ export const SessionStart = 'SessionStart';
5
+ export const SessionEnd = 'SessionEnd';
6
+ export const UserPromptSubmit = 'UserPromptSubmit';
7
+ export const InstructionsLoaded = 'InstructionsLoaded';
8
+ export const PreToolUse = 'PreToolUse';
9
+ export const PermissionRequest = 'PermissionRequest';
10
+ export const PermissionDenied = 'PermissionDenied';
11
+ export const PostToolUse = 'PostToolUse';
12
+ export const PostToolUseFailure = 'PostToolUseFailure';
13
+ export const PostToolBatch = 'PostToolBatch';
14
+ export const SubagentStart = 'SubagentStart';
15
+ export const SubagentStop = 'SubagentStop';
16
+ export const Notification = 'Notification';
17
+ export const PreCompact = 'PreCompact';
18
+ export const Stop = 'Stop';
19
+ export const StopFailure = 'StopFailure';
20
+ export const CwdChanged = 'CwdChanged';
21
+ export const FileChanged = 'FileChanged';
22
+ export const UserPromptExpansion = 'UserPromptExpansion';
23
+ export const Setup = 'Setup';
24
+ export const ConfigChange = 'ConfigChange';
25
+ export const DirectoryAdded = 'DirectoryAdded';
26
+ export const PreModelSwitch = 'PreModelSwitch';
27
+ export const PostModelSwitch = 'PostModelSwitch';
28
+ export const PostCompact = 'PostCompact';
29
+ export const MessageDisplay = 'MessageDisplay';
30
+ export const TodoCreated = 'TaskCreated';
31
+ export const TodoCompleted = 'TaskCompleted';
32
+ export const TeammateIdle = 'TeammateIdle';
33
+ export const Elicitation = 'Elicitation';
34
+ export const ElicitationResult = 'ElicitationResult';
35
+ export const WorktreeCreate = 'WorktreeCreate';
36
+ export const WorktreeRemove = 'WorktreeRemove';
37
+ export const hooks = [
38
+ Setup,
39
+ SessionStart,
40
+ SessionEnd,
41
+ UserPromptSubmit,
42
+ UserPromptExpansion,
43
+ InstructionsLoaded,
44
+ ConfigChange,
45
+ DirectoryAdded,
46
+ PreModelSwitch,
47
+ PostModelSwitch,
48
+ PreToolUse,
49
+ PermissionRequest,
50
+ PermissionDenied,
51
+ PostToolUse,
52
+ PostToolUseFailure,
53
+ PostToolBatch,
54
+ MessageDisplay,
55
+ SubagentStart,
56
+ SubagentStop,
57
+ TodoCreated,
58
+ TodoCompleted,
59
+ TeammateIdle,
60
+ Elicitation,
61
+ ElicitationResult,
62
+ Notification,
63
+ PreCompact,
64
+ PostCompact,
65
+ Stop,
66
+ StopFailure,
67
+ CwdChanged,
68
+ FileChanged,
69
+ WorktreeCreate,
70
+ WorktreeRemove,
71
+ ];
72
+ export const sessions = {
73
+ get current() {
74
+ return bound().sessions.current;
75
+ },
76
+ list: (options) => bound().sessions.list(options),
77
+ search: (text, options) => bound().sessions.search(text, options),
78
+ on: ((...args) => bound().sessions.on(...args)),
79
+ before: ((...args) => bound().sessions.before(...args)),
80
+ };
81
+ export const settings = {
82
+ list: () => bound().settings.list(),
83
+ user: { read: () => bound().settings.user.read(), update: (values) => bound().settings.user.update(values) },
84
+ project: { read: () => bound().settings.project.read(), update: (values) => bound().settings.project.update(values) },
85
+ local: { read: () => bound().settings.local.read(), update: (values) => bound().settings.local.update(values) },
86
+ };
87
+ export const model = {
88
+ complete: (request, options) => bound().model.complete(request, options),
89
+ };
90
+ export const fs = {
91
+ read: (path) => bound().fs.read(path),
92
+ write: (path, text) => bound().fs.write(path, text),
93
+ exists: (path) => bound().fs.exists(path),
94
+ find: (glob) => bound().fs.find(glob),
95
+ list: (path) => bound().fs.list(path),
96
+ stat: (path, options) => bound().fs.stat(path, options),
97
+ };
98
+ export const metadata = {
99
+ read: (path) => bound().metadata.read(path),
100
+ update: (path, change) => bound().metadata.update(path, change),
101
+ };
102
+ export const process = {
103
+ run: (argv, init) => bound().process.run(argv, init),
104
+ spawn: (argv, init) => bound().process.spawn(argv, init),
105
+ };
106
+ export const http = {
107
+ fetch: (url, init) => bound().http.fetch(url, init),
108
+ };
109
+ export const Mod = modSender;
5
110
  export function defineMod(definition) {
6
111
  if (definition.name.trim() === '')
7
112
  throw new Error('defineMod: the mod needs a name, such as the name in .claude-plugin/plugin.json.');
@@ -9,3 +114,22 @@ export function defineMod(definition) {
9
114
  checkOptions(definition.name, definition.options);
10
115
  return definition;
11
116
  }
117
+ export { AbovePrompt, AskUserQuestion, CommandOutput, PromptHint, SessionMode, Spinner, ToolGroup, ToolProgress, TurnDuration } from './ui/places.js';
118
+ export { Session, UsageChange } from './session/session.js';
119
+ export { ContextEnd, ContextStart } from './session/context/context.js';
120
+ export { TurnEnd, TurnStart } from './session/context/turn/turn.js';
121
+ export { Message } from './session/context/turn/message/message.js';
122
+ export { Prompt } from './session/context/turn/message/prompt.js';
123
+ export { Note } from './session/context/turn/message/note.js';
124
+ export { Reply } from './session/context/turn/message/reply.js';
125
+ export { ToolCall } from './session/context/turn/message/tool-call.js';
126
+ export { ToolResult } from './session/context/turn/message/tool-result.js';
127
+ export { Skill } from './session/context/turn/message/skill.js';
128
+ export { Document } from './session/context/turn/message/document.js';
129
+ export { Notice } from './session/context/turn/message/notice.js';
130
+ export { Channel, Person, Schedule, Sdk } from './session/context/turn/message/sender.js';
131
+ export { GoalChange } from './session/goal/goal.js';
132
+ export { Task, TaskEnd, TaskStart } from './session/goal/task.js';
133
+ export { longestMs } from './runtime/deadline.js';
134
+ export { notInstalled } from './runtime/dependencies.js';
135
+ export { messageOf } from './utils/text.js';
package/options.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- export type OptionKind = 'text' | 'secret' | 'number' | 'toggle' | 'choice' | 'folder' | 'file' | 'list';
1
+ export type OptionType = 'text' | 'secret' | 'number' | 'toggle' | 'choice' | 'folder' | 'file' | 'list';
2
2
  export type OptionValue = string | number | boolean | readonly string[];
3
3
  type Described = {
4
4
  readonly title: string;
5
5
  readonly description: string;
6
6
  };
7
7
  export type Option<Value extends OptionValue = OptionValue> = Described & {
8
- readonly kind: OptionKind;
8
+ readonly type: OptionType;
9
9
  readonly default?: Value;
10
10
  readonly min?: number;
11
11
  readonly max?: number;
package/options.js CHANGED
@@ -1,12 +1,12 @@
1
1
  export const option = {
2
- text: (field) => ({ ...field, kind: 'text' }),
3
- secret: (field) => ({ ...field, kind: 'secret' }),
4
- number: (field) => ({ ...field, kind: 'number' }),
5
- toggle: (field) => ({ ...field, kind: 'toggle', default: field.default ?? false }),
6
- choice: (choices, field) => ({ ...field, kind: 'choice', choices }),
7
- folder: (field) => ({ ...field, kind: 'folder' }),
8
- file: (field) => ({ ...field, kind: 'file' }),
9
- list: (field) => ({ ...field, kind: 'list' }),
2
+ text: (field) => ({ ...field, type: 'text' }),
3
+ secret: (field) => ({ ...field, type: 'secret' }),
4
+ number: (field) => ({ ...field, type: 'number' }),
5
+ toggle: (field) => ({ ...field, type: 'toggle', default: field.default ?? false }),
6
+ choice: (choices, field) => ({ ...field, type: 'choice', choices }),
7
+ folder: (field) => ({ ...field, type: 'folder' }),
8
+ file: (field) => ({ ...field, type: 'file' }),
9
+ list: (field) => ({ ...field, type: 'list' }),
10
10
  };
11
11
  const types = { text: 'string', secret: 'string', number: 'number', toggle: 'boolean', choice: 'string', folder: 'directory', file: 'file', list: 'string' };
12
12
  const optionKey = /^[A-Za-z_]\w*$/;
@@ -17,9 +17,9 @@ export function checkOptions(name, options) {
17
17
  throw new Error(`${at} is not an option name. Use letters, digits, and _, starting with a letter, as Claude Code passes each option on as CLAUDE_PLUGIN_OPTION_${key.toUpperCase()}.`);
18
18
  if (declared.title.trim() === '')
19
19
  throw new Error(`${at} needs a title, the label /config shows.`);
20
- if (declared.kind === 'choice' && (declared.choices ?? []).length === 0)
20
+ if (declared.type === 'choice' && (declared.choices ?? []).length === 0)
21
21
  throw new Error(`${at} is a choice with no choices. Give option.choice(['a', 'b'], { ... }).`);
22
- if (declared.kind === 'choice' && declared.default !== undefined && !(declared.choices ?? []).includes(declared.default))
22
+ if (declared.type === 'choice' && declared.default !== undefined && !(declared.choices ?? []).includes(declared.default))
23
23
  throw new Error(`${at} defaults to ${String(declared.default)}, which is not one of its choices: ${(declared.choices ?? []).join(', ')}.`);
24
24
  }
25
25
  return options;
@@ -28,12 +28,12 @@ export function userConfigOf(options) {
28
28
  return Object.fromEntries(Object.entries(options).map(([key, declared]) => [
29
29
  key,
30
30
  {
31
- type: types[declared.kind],
31
+ type: types[declared.type],
32
32
  title: declared.title,
33
33
  description: declared.description,
34
- ...(declared.kind === 'secret' ? { sensitive: true } : {}),
35
- ...(declared.kind === 'list' ? { multiple: true } : {}),
36
- ...(declared.kind === 'choice' ? { options: declared.choices } : {}),
34
+ ...(declared.type === 'secret' ? { sensitive: true } : {}),
35
+ ...(declared.type === 'list' ? { multiple: true } : {}),
36
+ ...(declared.type === 'choice' ? { options: declared.choices } : {}),
37
37
  ...(declared.default === undefined ? {} : { default: declared.default }),
38
38
  ...(declared.min === undefined ? {} : { min: declared.min }),
39
39
  ...(declared.max === undefined ? {} : { max: declared.max }),
@@ -44,10 +44,10 @@ export function isUnset(value) {
44
44
  return value === undefined || value === '' || (Array.isArray(value) && value.length === 0);
45
45
  }
46
46
  export function fitsOption(declared, value) {
47
- const kind = declared.kind;
48
- if (kind === 'toggle')
47
+ const type = declared.type;
48
+ if (type === 'toggle')
49
49
  return typeof value === 'boolean' ? undefined : 'takes true or false';
50
- if (kind === 'number') {
50
+ if (type === 'number') {
51
51
  if (typeof value !== 'number' || !Number.isFinite(value))
52
52
  return 'takes a number';
53
53
  if (declared.min !== undefined && value < declared.min)
@@ -56,11 +56,11 @@ export function fitsOption(declared, value) {
56
56
  return `takes ${declared.max} or less`;
57
57
  return undefined;
58
58
  }
59
- if (kind === 'list')
59
+ if (type === 'list')
60
60
  return Array.isArray(value) && value.every((item) => typeof item === 'string') ? undefined : 'takes a list of text';
61
61
  if (typeof value !== 'string')
62
62
  return 'takes text';
63
- if (kind === 'choice' && !(declared.choices ?? []).includes(value))
63
+ if (type === 'choice' && !(declared.choices ?? []).includes(value))
64
64
  return `takes one of: ${(declared.choices ?? []).join(', ')}`;
65
65
  return undefined;
66
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmodjs/core",
3
- "version": "0.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "Build Claude Code mods: hooks, panes, permissions, checks, and an install that just works.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,6 +18,7 @@
18
18
  "*.d.ts.map",
19
19
  "jobs/",
20
20
  "runtime/",
21
+ "session/",
21
22
  "testing/",
22
23
  "ui/",
23
24
  "utils/",
@@ -26,7 +27,7 @@
26
27
  ],
27
28
  "scripts": {
28
29
  "build": "tsc -p tsconfig.build.json && bun build src/vendor.ts --outfile vendor.js --format esm --target browser --define process=undefined && NODE_ENV=production bun build src/vendor-markdown.ts --outfile vendor-markdown.js --format esm --target browser --conditions worker",
29
- "check": "tsc -p tsconfig.json --noEmit && oxlint --deny-warnings",
30
+ "check": "tsc -p tsconfig.json --noEmit && OXLINT_TSGOLINT_PATH=../lint/node_modules/.bin/tsgolint ../lint/node_modules/.bin/oxlint --type-aware --deny-warnings",
30
31
  "test": "bun test"
31
32
  },
32
33
  "dependencies": {
@@ -42,7 +43,6 @@
42
43
  "mdast-util-gfm": "^3.1.0",
43
44
  "mdast-util-to-string": "^4.0.0",
44
45
  "micromark-extension-gfm": "^3.0.0",
45
- "oxlint": "1.86.0",
46
46
  "pathe": "^2.0.3",
47
47
  "picomatch": "^4.0.7",
48
48
  "shell-quote": "^1.12.0",
package/records.d.ts CHANGED
@@ -15,35 +15,38 @@ export type Steps = {
15
15
  keys?: Readonly<Record<string, string>>;
16
16
  permissions?: readonly string[];
17
17
  };
18
- export declare const listPermissions: readonly ['network', 'run', 'files'];
19
- export declare const flagPermissions: readonly ['conversation', 'prompt', 'model', 'agents', 'tools', 'config', 'approve'];
18
+ export declare const listPermissions: readonly ['network', 'run', 'files', 'config'];
19
+ export declare const flagPermissions: readonly ['conversation', 'prompt', 'model', 'tasks', 'tools', 'approve'];
20
20
  export type ListPermission = (typeof listPermissions)[number];
21
21
  export type FlagPermission = (typeof flagPermissions)[number];
22
22
  export type ReadFile = (path: string) => Promise<string | undefined>;
23
23
  export type RunnerEvent = {
24
- kind: 'progress';
24
+ type: 'progress';
25
25
  done: number;
26
26
  total: number;
27
27
  label: string;
28
28
  } | {
29
- kind: 'log';
29
+ type: 'log';
30
30
  text: string;
31
31
  } | {
32
- kind: 'needs-consent';
32
+ type: 'needs-consent';
33
33
  sha256: string;
34
34
  install: string;
35
35
  uninstall: string;
36
36
  keys: string;
37
37
  permissions: readonly string[];
38
38
  } | {
39
- kind: 'done';
39
+ type: 'done';
40
40
  name: string;
41
41
  version?: string;
42
42
  } | {
43
- kind: 'missing';
43
+ type: 'missing';
44
44
  name: string;
45
45
  } | {
46
- kind: 'failed';
46
+ type: 'retries';
47
+ when: 'changed' | 'later';
48
+ } | {
49
+ type: 'failed';
47
50
  code: number;
48
51
  message: string;
49
52
  };
@@ -61,6 +64,7 @@ export declare function writeRecord(write: (path: string, text: string) => Promi
61
64
  export declare function readSteps(pkg: unknown): Steps | undefined;
62
65
  export declare function permissionWords(item: string): string;
63
66
  export declare const settingsPagesMethod = "cmod:settingsPages";
67
+ export declare const changelogPage = "changelog";
64
68
  export declare const openPageMethod = "cmod:openPage";
65
69
  export declare const pendingStepsMethod = "cmod:pendingSteps";
66
70
  export declare const finishStepsMethod = "cmod:finishSteps";
@@ -68,6 +72,7 @@ export declare function marketplaceOf(root: string, name: string): string | unde
68
72
  export declare function updatesToTurnOn(marketplace: string | undefined, settings: unknown, known: unknown): string | undefined;
69
73
  export declare function consentPath(store: string): string;
70
74
  export declare function parseConsent(value: unknown, path: string): Record<string, string[]>;
75
+ export declare const coreVersion = "1.5.0";
71
76
  export declare function oldestCmodFor(steps: Steps): string;
72
77
  export declare function keyWords(keys: Readonly<Record<string, string>> | undefined): string;
73
78
  export declare function scriptPaths(command: string): string[];
package/records.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"records.d.ts","sourceRoot":"","sources":["src/records.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"records.d.ts","sourceRoot":"","sources":["src/records.ts"],"names":[],"mappings":"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"}
package/records.js CHANGED
@@ -1,9 +1,16 @@
1
1
  import { listed, messageOf } from './utils/text.js';
2
- export const listPermissions = ['network', 'run', 'files'];
3
- export const flagPermissions = ['conversation', 'prompt', 'model', 'agents', 'tools', 'config', 'approve'];
2
+ export const listPermissions = ['network', 'run', 'files', 'config'];
3
+ export const flagPermissions = ['conversation', 'prompt', 'model', 'tasks', 'tools', 'approve'];
4
4
  const permissionNames = [...listPermissions, ...flagPermissions];
5
5
  const hostName = /^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)*$/;
6
6
  const programName = /^[A-Za-z0-9][A-Za-z0-9._+-]*$/;
7
+ const settingName = /^[A-Za-z][A-Za-z0-9]*$/;
8
+ const listItemHint = {
9
+ network: 'a host alone, such as "api.github.com", or a socket path, such as "/var/run/docker.sock"',
10
+ run: 'a program\'s command, such as "gh"',
11
+ files: 'a path that starts with ~/ or /, such as "~/.zshrc"',
12
+ config: 'a Claude Code setting\'s name, such as "cleanupPeriodDays"',
13
+ };
7
14
  export const pluginName = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
8
15
  export function storeFolder(env) {
9
16
  const dataHome = env['XDG_DATA_HOME'];
@@ -129,14 +136,14 @@ function readPermissions(steps) {
129
136
  items.push('run:*');
130
137
  continue;
131
138
  }
132
- const example = name === 'network' ? '["api.github.com"]' : name === 'run' ? '["gh"], or "*" for any program' : '["~/.zshrc"]';
139
+ const example = { network: '["api.github.com"]', run: '["gh"], or "*" for any program', files: '["~/.zshrc"]', config: '["cleanupPeriodDays"]' }[name];
133
140
  if (!Array.isArray(value) || value.length === 0 || !value.every((each) => typeof each === 'string'))
134
141
  throw new Error(`${at} sets "${name}" to ${JSON.stringify(value)}. Write a list, such as "${name}": ${example}.`);
135
142
  for (const each of value) {
136
143
  const isPath = /^(~\/|\/)/.test(each) && !each.split('/').includes('..');
137
- const isValid = name === 'network' ? hostName.test(each) || isPath : name === 'run' ? programName.test(each) : isPath;
138
- if (!isValid)
139
- throw new Error(`${at} lists "${each}" under "${name}". Write ${name === 'network' ? 'a host alone, such as "api.github.com", or a socket path, such as "/var/run/docker.sock"' : name === 'run' ? 'a program\'s command, such as "gh"' : 'a path that starts with ~/ or /, such as "~/.zshrc"'}.`);
144
+ const isValid = { network: hostName.test(each) || isPath, run: programName.test(each), files: isPath, config: settingName.test(each) }[name];
145
+ if (isValid !== true)
146
+ throw new Error(`${at} lists "${each}" under "${name}". Write ${listItemHint[name]}.`);
140
147
  items.push(`${name}:${each}`);
141
148
  }
142
149
  }
@@ -153,17 +160,17 @@ export function permissionWords(item) {
153
160
  case 'files':
154
161
  return `Change ${target}`;
155
162
  case 'conversation':
156
- return 'Read this conversation';
163
+ return 'Read your Claude Code conversations';
157
164
  case 'prompt':
158
165
  return 'Add text Claude reads and start turns';
159
166
  case 'model':
160
167
  return 'Ask a model, which uses your plan';
161
- case 'agents':
162
- return 'Start agents';
168
+ case 'tasks':
169
+ return 'Start tasks that work beside Claude';
163
170
  case 'tools':
164
171
  return "Use and change Claude's tool calls";
165
172
  case 'config':
166
- return 'Change your Claude Code settings';
173
+ return `Change ${target} in your Claude Code settings`;
167
174
  case 'approve':
168
175
  return "Approve Claude's tool calls for you";
169
176
  default:
@@ -171,6 +178,7 @@ export function permissionWords(item) {
171
178
  }
172
179
  }
173
180
  export const settingsPagesMethod = 'cmod:settingsPages';
181
+ export const changelogPage = 'changelog';
174
182
  export const openPageMethod = 'cmod:openPage';
175
183
  export const pendingStepsMethod = 'cmod:pendingSteps';
176
184
  export const finishStepsMethod = 'cmod:finishSteps';
@@ -212,7 +220,10 @@ function readKeys(keys) {
212
220
  }
213
221
  return { keys: commands };
214
222
  }
223
+ export const coreVersion = '1.5.0';
215
224
  export function oldestCmodFor(steps) {
225
+ if (steps.permissions?.some((item) => item === 'tasks' || item.startsWith('config:')) === true)
226
+ return '1.0.0';
216
227
  if (steps.permissions !== undefined)
217
228
  return '0.2.0';
218
229
  return Object.keys(steps.keys ?? {}).length > 0 ? '0.1.12' : '0.0.0';
@@ -279,7 +290,7 @@ export async function scriptsSha256(steps, files) {
279
290
  return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, '0')).join('');
280
291
  }
281
292
  export function formatEvent(event) {
282
- switch (event.kind) {
293
+ switch (event.type) {
283
294
  case 'progress':
284
295
  return `progress ${event.done} ${event.total}${event.label === '' ? '' : ` ${event.label}`}`;
285
296
  case 'log':
@@ -292,27 +303,32 @@ export function formatEvent(event) {
292
303
  return `missing ${event.name}`;
293
304
  case 'failed':
294
305
  return `failed ${event.code}\t${event.message.replace(/\s*\n\s*/g, ' ')}`;
306
+ case 'retries':
307
+ return `retries ${event.when}`;
295
308
  }
296
309
  }
297
310
  export function parseEvent(line) {
298
311
  const progress = /^progress (\d+) (\d+)(?: (.*))?$/.exec(line);
299
312
  if (progress !== null)
300
- return { kind: 'progress', done: Number(progress[1]), total: Number(progress[2]), label: progress[3] ?? '' };
313
+ return { type: 'progress', done: Number(progress[1]), total: Number(progress[2]), label: progress[3] ?? '' };
301
314
  const consent = /^needs-consent (\S+)\t([^\t]*)\t([^\t]*)(?:\t(.*))?$/.exec(line);
302
315
  if (consent !== null) {
303
316
  const [keys = '', ...permissions] = (consent[4] ?? '').split('\t');
304
- return { kind: 'needs-consent', sha256: consent[1], install: consent[2], uninstall: consent[3], keys, permissions: permissions.filter((item) => item !== '') };
317
+ return { type: 'needs-consent', sha256: consent[1], install: consent[2], uninstall: consent[3], keys, permissions: permissions.filter((item) => item !== '') };
305
318
  }
306
319
  const done = /^done (\S+)(?: (\S+))?$/.exec(line);
307
320
  if (done !== null)
308
- return { kind: 'done', name: done[1], ...(done[2] === undefined ? {} : { version: done[2] }) };
321
+ return { type: 'done', name: done[1], ...(done[2] === undefined ? {} : { version: done[2] }) };
309
322
  const missing = /^missing (\S+)$/.exec(line);
310
323
  if (missing !== null)
311
- return { kind: 'missing', name: missing[1] };
324
+ return { type: 'missing', name: missing[1] };
312
325
  const failed = /^failed (-?\d+)(?:\t(.*))?$/.exec(line);
313
326
  if (failed !== null)
314
- return { kind: 'failed', code: Number(failed[1]), message: failed[2] ?? '' };
315
- return { kind: 'log', text: line.replace(/^log /, '') };
327
+ return { type: 'failed', code: Number(failed[1]), message: failed[2] ?? '' };
328
+ const retries = /^retries (changed|later)$/.exec(line);
329
+ if (retries !== null)
330
+ return { type: 'retries', when: retries[1] };
331
+ return { type: 'log', text: line.replace(/^log /, '') };
316
332
  }
317
333
  export function isAtLeast(version, minimum) {
318
334
  const parts = version.split('.').map(Number);
package/register.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoD,EAAE,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAA;AACpH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAW3C,wBAAgB,aAAa,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAEjE;AA4ED,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CA+BzK;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,CAIzD"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoD,EAAE,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAA;AACpH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAY3C,wBAAgB,aAAa,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAEjE;AAmFD,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAoDzK;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,CAIzD"}
package/register.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { cmodPluginName } from './runtime/dependencies.js';
1
2
  import { createLifecycle, readPlugin } from './runtime/lifecycle.js';
2
3
  let lifecycle;
3
4
  let checksPermissions = false;
@@ -9,7 +10,6 @@ async function startMod($, eventInput, passOn) {
9
10
  const claude = {
10
11
  plugin: { name: $.plugin.name, root: $.plugin.root },
11
12
  ui: {
12
- toast: (text, options) => $.ui.toast(text, options),
13
13
  status: (text) => $.ui.status(text),
14
14
  log: (text, options) => $.ui.log(text, options),
15
15
  notice: (toolUseId, text) => $.ui.notice(toolUseId, text),
@@ -19,6 +19,8 @@ async function startMod($, eventInput, passOn) {
19
19
  close: (pane) => $.ui.close(pane),
20
20
  panes: () => $.ui.panes(),
21
21
  scroll: (args) => $.ui.scroll(args),
22
+ copy: (args) => $.ui.copy(args),
23
+ focus: (args) => $.ui.focus(args),
22
24
  resolve: (render) => $.ui.resolve(render),
23
25
  },
24
26
  process: {
@@ -55,11 +57,12 @@ async function startMod($, eventInput, passOn) {
55
57
  surfaces: () => $.session.surfaces(),
56
58
  messages: ((args) => (args === undefined ? $.session.messages() : $.session.messages(args))),
57
59
  append: (args) => $.session.append(args),
60
+ send: (args) => $.session.send(args),
58
61
  },
59
62
  prompt: { submit: (args) => $.prompt.submit(args) },
60
63
  model: { complete: (request, options) => $.model.complete(request, options) },
61
64
  command: { register: (command) => $.command.register(command) },
62
- tool: { register: (tool) => $.tool.register(tool), call: ((input) => $.tool.call(input)) },
65
+ tool: { register: (tool) => $.tool.register(tool), call: (input) => $.tool.call(input) },
63
66
  agent: {
64
67
  list: () => $.agent.list(),
65
68
  spawn: (args) => $.agent.spawn(args),
@@ -71,32 +74,51 @@ async function startMod($, eventInput, passOn) {
71
74
  },
72
75
  cmod: { call: (input) => $.cmod.call(input) },
73
76
  };
74
- await lifecycle.start(claude, readPlugin);
75
- return passOn(eventInput);
77
+ const [, answer] = await Promise.all([lifecycle.start(claude, readPlugin), passOn(eventInput)]);
78
+ return answer;
76
79
  }
77
80
  function routeToMod(_$, eventInput, passOn) {
78
81
  return lifecycle.route(passOn.event, eventInput, (passed) => passOn(passed));
79
82
  }
83
+ function routeCallToMod(_$, eventInput, passOn) {
84
+ const called = { ...eventInput, caller: passOn.origin.plugin };
85
+ return lifecycle.route('cmod.call', called, (passed) => passOn(Object.fromEntries(Object.entries(passed).filter(([key]) => key !== 'caller'))));
86
+ }
80
87
  export function registerMod(addHook, definition, options) {
81
88
  checksPermissions = false;
82
89
  registered = definition;
83
90
  lifecycle = createLifecycle(definition, () => checksPermissions, options);
84
91
  addHook('session.start', startMod);
92
+ addHook('classic.Setup', routeToMod);
85
93
  addHook('classic.SessionStart', routeToMod);
86
94
  addHook('classic.SessionEnd', routeToMod);
87
95
  addHook('classic.UserPromptSubmit', routeToMod);
96
+ addHook('classic.UserPromptExpansion', routeToMod);
88
97
  addHook('classic.InstructionsLoaded', routeToMod);
98
+ addHook('classic.ConfigChange', routeToMod);
99
+ addHook('classic.DirectoryAdded', routeToMod);
100
+ addHook('classic.PreModelSwitch', routeToMod);
101
+ addHook('classic.PostModelSwitch', routeToMod);
89
102
  addHook('classic.PermissionDenied', routeToMod);
90
103
  addHook('classic.PostToolUse', routeToMod);
91
104
  addHook('classic.PostToolUseFailure', routeToMod);
92
105
  addHook('classic.PostToolBatch', routeToMod);
106
+ addHook('classic.MessageDisplay', routeToMod);
93
107
  addHook('classic.SubagentStart', routeToMod);
94
108
  addHook('classic.SubagentStop', routeToMod);
109
+ addHook('classic.TaskCreated', routeToMod);
110
+ addHook('classic.TaskCompleted', routeToMod);
111
+ addHook('classic.TeammateIdle', routeToMod);
112
+ addHook('classic.Elicitation', routeToMod);
113
+ addHook('classic.ElicitationResult', routeToMod);
95
114
  addHook('classic.Notification', routeToMod);
96
115
  addHook('classic.PreCompact', routeToMod);
116
+ addHook('classic.PostCompact', routeToMod);
97
117
  addHook('classic.Stop', routeToMod);
98
118
  addHook('classic.StopFailure', routeToMod);
99
119
  addHook('classic.FileChanged', routeToMod);
120
+ addHook('classic.WorktreeCreate', routeToMod);
121
+ addHook('classic.WorktreeRemove', routeToMod);
100
122
  addHook('tool.call', routeToMod);
101
123
  addHook('prompt.submit', routeToMod);
102
124
  addHook('prompt.context', routeToMod);
@@ -107,7 +129,14 @@ export function registerMod(addHook, definition, options) {
107
129
  addHook('ui.press', routeToMod);
108
130
  addHook('ui.scroll', routeToMod);
109
131
  addHook('ui.close', routeToMod);
110
- addHook('cmod.call', routeToMod);
132
+ addHook('cmod.call', routeCallToMod);
133
+ if (definition.name !== cmodPluginName)
134
+ return;
135
+ addHook('session.append', routeToMod);
136
+ addHook('session.compact', routeToMod);
137
+ addHook('session.receive', routeToMod);
138
+ addHook('agent.spawn', routeToMod);
139
+ addHook('prompt.attachment', routeToMod);
111
140
  }
112
141
  export function registerPermissionCheck(addHook) {
113
142
  checksPermissions = true;
@@ -0,0 +1,18 @@
1
+ import type { Claude } from './claude.js';
2
+ import type { Plugin } from './lifecycle.js';
3
+ export type Announced = {
4
+ readonly version: string;
5
+ readonly added: readonly string[];
6
+ };
7
+ export type Announcement = {
8
+ readonly message: string;
9
+ readonly description?: string;
10
+ readonly action?: {
11
+ readonly label: string;
12
+ readonly onClick: () => unknown;
13
+ };
14
+ };
15
+ export declare const announcementMs = 10000;
16
+ export declare function announcedOf(saved: unknown): Announced | undefined;
17
+ export declare function announcementOf(claude: Claude, plugin: Plugin, granted: ReadonlySet<string>, added: readonly string[], previous: Announced | undefined): Promise<Announcement>;
18
+ //# sourceMappingURL=announce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"announce.d.ts","sourceRoot":"","sources":["../src/runtime/announce.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAE5C,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAA;AAEvF,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAA;KAAE,CAAA;CAAE,CAAA;AAErK,eAAO,MAAM,cAAc,QAAS,CAAA;AAIpC,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAIjE;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAuCnL"}