@cmodjs/core 1.0.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 (122) hide show
  1. package/docs/commands.md +22 -11
  2. package/docs/dependencies.md +6 -4
  3. package/docs/hooks.md +26 -3
  4. package/docs/index.md +1 -1
  5. package/docs/install-steps.md +5 -3
  6. package/docs/mod.md +29 -3
  7. package/docs/permissions.md +4 -4
  8. package/docs/session.md +126 -63
  9. package/docs/testing.md +7 -5
  10. package/docs/ui.md +9 -1
  11. package/jobs/program.d.ts.map +1 -1
  12. package/jobs/program.js +7 -2
  13. package/mod.d.ts +30 -6
  14. package/mod.d.ts.map +1 -1
  15. package/mod.js +34 -1
  16. package/package.json +1 -1
  17. package/records.d.ts +4 -1
  18. package/records.d.ts.map +1 -1
  19. package/records.js +6 -1
  20. package/register.d.ts.map +1 -1
  21. package/register.js +17 -0
  22. package/runtime/announce.d.ts.map +1 -1
  23. package/runtime/announce.js +2 -0
  24. package/runtime/before.d.ts +32 -0
  25. package/runtime/before.d.ts.map +1 -0
  26. package/runtime/before.js +214 -0
  27. package/runtime/claude.d.ts +2 -1
  28. package/runtime/claude.d.ts.map +1 -1
  29. package/runtime/conversations.d.ts +1 -0
  30. package/runtime/conversations.d.ts.map +1 -1
  31. package/runtime/conversations.js +333 -61
  32. package/runtime/dependencies.js +1 -1
  33. package/runtime/engine.d.ts +2 -6
  34. package/runtime/engine.d.ts.map +1 -1
  35. package/runtime/grants.d.ts.map +1 -1
  36. package/runtime/grants.js +8 -8
  37. package/runtime/hooks.d.ts +1 -1
  38. package/runtime/hooks.d.ts.map +1 -1
  39. package/runtime/hooks.js +19 -4
  40. package/runtime/installer.d.ts +1 -1
  41. package/runtime/installer.d.ts.map +1 -1
  42. package/runtime/installer.js +6 -5
  43. package/runtime/lifecycle.d.ts.map +1 -1
  44. package/runtime/lifecycle.js +129 -58
  45. package/runtime/metadata.d.ts.map +1 -1
  46. package/runtime/metadata.js +5 -4
  47. package/runtime/sessions.d.ts +26 -4
  48. package/runtime/sessions.d.ts.map +1 -1
  49. package/runtime/sessions.js +315 -117
  50. package/runtime/toaster.d.ts +5 -12
  51. package/runtime/toaster.d.ts.map +1 -1
  52. package/runtime/toaster.js +133 -23
  53. package/runtime/ui.d.ts.map +1 -1
  54. package/runtime/ui.js +26 -6
  55. package/session/context/context.d.ts +3 -1
  56. package/session/context/context.d.ts.map +1 -1
  57. package/session/context/turn/message/message.d.ts +1 -0
  58. package/session/context/turn/message/message.d.ts.map +1 -1
  59. package/session/context/turn/message/message.js +42 -1
  60. package/session/context/turn/turn.d.ts +2 -1
  61. package/session/context/turn/turn.d.ts.map +1 -1
  62. package/session/conversation.d.ts +20 -11
  63. package/session/conversation.d.ts.map +1 -1
  64. package/session/conversation.js +50 -27
  65. package/session/goal/goal.d.ts +3 -2
  66. package/session/goal/goal.d.ts.map +1 -1
  67. package/session/goal/task.d.ts +4 -4
  68. package/session/goal/task.d.ts.map +1 -1
  69. package/session/session.d.ts +80 -21
  70. package/session/session.d.ts.map +1 -1
  71. package/session/session.js +1 -0
  72. package/src/jobs/program.ts +7 -2
  73. package/src/mod.ts +48 -5
  74. package/src/records.ts +6 -1
  75. package/src/register.ts +17 -0
  76. package/src/runtime/announce.ts +2 -0
  77. package/src/runtime/before.ts +200 -0
  78. package/src/runtime/claude.ts +3 -0
  79. package/src/runtime/conversations.ts +337 -60
  80. package/src/runtime/dependencies.ts +1 -1
  81. package/src/runtime/engine.ts +2 -1
  82. package/src/runtime/grants.ts +8 -10
  83. package/src/runtime/hooks.ts +20 -4
  84. package/src/runtime/installer.ts +6 -5
  85. package/src/runtime/lifecycle.ts +135 -55
  86. package/src/runtime/metadata.ts +5 -4
  87. package/src/runtime/sessions.ts +316 -111
  88. package/src/runtime/toaster.ts +160 -44
  89. package/src/runtime/ui.ts +23 -4
  90. package/src/session/context/context.ts +3 -1
  91. package/src/session/context/turn/message/message.ts +39 -1
  92. package/src/session/context/turn/turn.ts +2 -1
  93. package/src/session/conversation.ts +56 -31
  94. package/src/session/goal/goal.ts +3 -2
  95. package/src/session/goal/task.ts +4 -4
  96. package/src/session/session.ts +62 -15
  97. package/src/testing/fake-claude.ts +4 -2
  98. package/src/testing/fake-sessions.ts +94 -20
  99. package/src/testing.ts +27 -3
  100. package/src/utils/call-effects.ts +2 -2
  101. package/src/utils/disposable.ts +3 -0
  102. package/src/utils/matcher.ts +1 -1
  103. package/src/utils/paths.ts +6 -3
  104. package/testing/fake-claude.d.ts +1 -0
  105. package/testing/fake-claude.d.ts.map +1 -1
  106. package/testing/fake-claude.js +3 -1
  107. package/testing/fake-sessions.d.ts +8 -1
  108. package/testing/fake-sessions.d.ts.map +1 -1
  109. package/testing/fake-sessions.js +97 -18
  110. package/testing.d.ts +1 -0
  111. package/testing.d.ts.map +1 -1
  112. package/testing.js +23 -2
  113. package/utils/call-effects.d.ts +1 -0
  114. package/utils/call-effects.d.ts.map +1 -1
  115. package/utils/call-effects.js +1 -1
  116. package/utils/disposable.d.ts +4 -0
  117. package/utils/disposable.d.ts.map +1 -0
  118. package/utils/disposable.js +1 -0
  119. package/utils/matcher.js +1 -1
  120. package/utils/paths.d.ts +2 -1
  121. package/utils/paths.d.ts.map +1 -1
  122. package/utils/paths.js +6 -3
@@ -11,19 +11,38 @@ export const searchLimit = 50;
11
11
  const agentTools = ['Agent', 'Task'];
12
12
  const asyncLaunch = 'Async agent launched';
13
13
  export function emptyConversation(session) {
14
- return { session, context: 0, contextOpenedAt: '', agentCalls: [], endedCalls: {}, tasks: {} };
14
+ return { session, context: 0, contextOpenedAt: '', agentCalls: [], endedCalls: {}, tasks: {}, taskTurns: {} };
15
15
  }
16
16
  export function createConversation(start) {
17
17
  let { context, contextOpenedAt, turn, goal } = start;
18
18
  const agentCalls = new Set(start.agentCalls);
19
19
  const endedCalls = new Map(Object.entries(start.endedCalls));
20
20
  const tasks = new Map(Object.entries(start.tasks));
21
+ const taskTurns = new Map(Object.entries(start.taskTurns));
22
+ const endTaskTurn = (task, at) => {
23
+ const open = taskTurns.get(task);
24
+ if (open === undefined)
25
+ return [];
26
+ taskTurns.delete(task);
27
+ return open.closedAt === undefined ? [{ type: TurnEnd, turn: { ...open, closedAt: at } }] : [];
28
+ };
21
29
  const startContext = (at) => {
22
30
  context += 1;
23
31
  contextOpenedAt = at;
24
32
  return [{ type: ContextStart, context: { number: context, openedAt: at } }];
25
33
  };
26
34
  const endContext = (at) => (context === 0 ? [] : [{ type: ContextEnd, context: { number: context, openedAt: contextOpenedAt, closedAt: at } }]);
35
+ const compactTask = (task, at) => {
36
+ const owner = tasks.get(task);
37
+ if (owner === undefined)
38
+ return [];
39
+ const next = { ...owner, context: owner.context + 1, contextOpenedAt: at };
40
+ tasks.set(task, next);
41
+ return [
42
+ { type: ContextEnd, context: { number: owner.context, openedAt: owner.contextOpenedAt ?? owner.openedAt, closedAt: at, task } },
43
+ { type: ContextStart, context: { number: next.context, openedAt: at, task } },
44
+ ];
45
+ };
27
46
  const endTurn = (at) => {
28
47
  if (turn === undefined)
29
48
  return [];
@@ -31,19 +50,22 @@ export function createConversation(start) {
31
50
  turn = undefined;
32
51
  return [{ type: TurnEnd, turn: ended }];
33
52
  };
34
- const endTask = (call, at) => {
35
- const task = [...tasks.values()].find((each) => each.openedBy === call);
36
- if (task === undefined) {
53
+ const endTask = (call, at, only) => {
54
+ const opened = [...tasks.values()].filter((each) => each.openedBy === call && (only === undefined || each.id === only));
55
+ if (opened.length === 0) {
37
56
  if (agentCalls.has(call))
38
57
  endedCalls.set(call, at);
39
58
  return [];
40
59
  }
41
- if (task.closedAt !== undefined)
42
- return [];
43
- const ended = { ...task, closedAt: at };
44
- tasks.set(task.id, ended);
45
- agentCalls.delete(call);
46
- return [{ type: TaskEnd, task: ended }];
60
+ if (only === undefined)
61
+ agentCalls.delete(call);
62
+ return opened.flatMap((task) => {
63
+ if (task.closedAt !== undefined)
64
+ return [];
65
+ const ended = { ...task, closedAt: at };
66
+ tasks.set(task.id, ended);
67
+ return [...endTaskTurn(task.id, at), { type: TaskEnd, task: ended }];
68
+ });
47
69
  };
48
70
  const changeGoal = (text) => {
49
71
  goal = text;
@@ -56,28 +78,31 @@ export function createConversation(start) {
56
78
  changes.push(...startContext(row.at));
57
79
  if (task === undefined && row.type === 'system' && row.name === 'turn_duration')
58
80
  return [...changes, ...endTurn(row.at)];
59
- if (task === undefined && row.type === 'system' && row.name === 'compact_boundary')
60
- return [...changes, ...endContext(row.at), ...startContext(row.at)];
81
+ if (row.type === 'system' && row.name === 'compact_boundary')
82
+ return [...changes, ...(task === undefined ? [...endContext(row.at), ...startContext(row.at)] : compactTask(task, row.at))];
61
83
  const owner = task === undefined ? undefined : tasks.get(task);
84
+ const placedIn = owner?.context ?? context;
62
85
  for (const unplaced of messagesOf(row, task !== undefined)) {
63
- if (task === undefined && unplaced.type === Prompt) {
64
- changes.push(...endTurn(row.at));
65
- const opened = { prompt: { ...unplaced, session: start.session, context, turn: unplaced.id }, context, openedAt: row.at };
66
- turn = opened;
86
+ if (unplaced.type === Prompt) {
87
+ changes.push(...(task === undefined ? endTurn(row.at) : endTaskTurn(task, row.at)));
88
+ const opened = { prompt: { ...unplaced, session: start.session, context: placedIn, turn: unplaced.id, ...(task === undefined ? {} : { task }) }, context: placedIn, openedAt: row.at, ...(owner?.closedAt === undefined ? {} : { closedAt: owner.closedAt }) };
89
+ if (task === undefined)
90
+ turn = opened;
91
+ else
92
+ taskTurns.set(task, opened);
67
93
  changes.push({ type: TurnStart, turn: opened });
68
- if (goal === undefined)
94
+ if (task === undefined && goal === undefined)
69
95
  changes.push(...changeGoal(unplaced.text));
70
96
  }
97
+ const open = task === undefined ? turn : taskTurns.get(task);
71
98
  const placed = {
72
99
  ...unplaced,
73
100
  session: start.session,
74
- context: owner?.context ?? context,
75
- ...(task === undefined && turn !== undefined ? { turn: turn.prompt.id } : {}),
101
+ context: placedIn,
102
+ ...(open === undefined ? {} : { turn: open.prompt.id }),
76
103
  ...(task === undefined ? {} : { task }),
77
104
  };
78
105
  changes.push({ type: Message, message: placed });
79
- if (task !== undefined)
80
- continue;
81
106
  if (placed.type === ToolCall && agentTools.includes(placed.name))
82
107
  agentCalls.add(placed.callId);
83
108
  if (placed.type === ToolResult && agentCalls.has(placed.callId) && !placed.text.startsWith(asyncLaunch))
@@ -85,7 +110,7 @@ export function createConversation(start) {
85
110
  if (placed.type === Note && placed.from.type === Task) {
86
111
  const call = tagOf(textOf(row.content), 'tool-use-id');
87
112
  if (call !== undefined && agentCalls.has(call))
88
- changes.push(...endTask(call, row.at));
113
+ changes.push(...endTask(call, row.at, tagOf(textOf(row.content), 'task-id')));
89
114
  }
90
115
  }
91
116
  return changes;
@@ -98,13 +123,10 @@ export function createConversation(start) {
98
123
  agentCalls.add(data.openedBy);
99
124
  const changes = [{ type: TaskStart, task: started }];
100
125
  const endedAt = endedCalls.get(data.openedBy);
101
- if (endedAt !== undefined) {
102
- endedCalls.delete(data.openedBy);
103
- changes.push(...endTask(data.openedBy, endedAt));
104
- }
126
+ if (endedAt !== undefined)
127
+ changes.push(...endTask(data.openedBy, endedAt, data.id));
105
128
  return changes;
106
129
  },
107
- endContext,
108
130
  startContext,
109
131
  changeGoal,
110
132
  get state() {
@@ -117,6 +139,7 @@ export function createConversation(start) {
117
139
  agentCalls: [...agentCalls],
118
140
  endedCalls: Object.fromEntries(endedCalls),
119
141
  tasks: Object.fromEntries(tasks),
142
+ taskTurns: Object.fromEntries(taskTurns),
120
143
  };
121
144
  },
122
145
  };
@@ -1,10 +1,11 @@
1
+ import type { RecordPart } from '../session.js';
1
2
  import type { Task } from './task.js';
2
3
  export declare const GoalChange = "goalChange";
3
- export type Goal = {
4
+ export type Goal = RecordPart & {
4
5
  readonly text: string;
6
+ tasks(): Promise<Task[]>;
5
7
  update(change: {
6
8
  readonly text: string;
7
9
  }): Promise<void>;
8
- tasks(): Promise<Task[]>;
9
10
  };
10
11
  //# sourceMappingURL=goal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"goal.d.ts","sourceRoot":"","sources":["../../src/session/goal/goal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAErC,eAAO,MAAM,UAAU,eAAe,CAAA;AAEtC,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxD,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;CACzB,CAAA"}
1
+ {"version":3,"file":"goal.d.ts","sourceRoot":"","sources":["../../src/session/goal/goal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAErC,eAAO,MAAM,UAAU,eAAe,CAAA;AAEtC,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACxB,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACzD,CAAA"}
@@ -1,16 +1,16 @@
1
1
  import type { Message } from '../context/turn/message/message.js';
2
+ import type { RecordPart, Session } from '../session.js';
2
3
  export declare const Task = "task";
3
4
  export declare const TaskStart = "taskStart";
4
5
  export declare const TaskEnd = "taskEnd";
5
- export type Task = {
6
+ export type Task = RecordPart & {
6
7
  readonly id: string;
7
8
  readonly title: string;
8
- readonly agentType: string;
9
- readonly model?: string;
9
+ readonly owner: Session;
10
10
  readonly openedBy: string;
11
11
  readonly openedAt: string;
12
12
  readonly closedAt?: string;
13
- messages(): Promise<Message[]>;
14
13
  tasks(): Promise<Task[]>;
14
+ messages(): Promise<Message[]>;
15
15
  };
16
16
  //# sourceMappingURL=task.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/session/goal/task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAA;AAEjE,eAAO,MAAM,IAAI,SAAS,CAAA;AAE1B,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAC9B,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;CACzB,CAAA"}
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/session/goal/task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAExD,eAAO,MAAM,IAAI,SAAS,CAAA;AAE1B,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACxB,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;CAC/B,CAAA"}
@@ -1,4 +1,4 @@
1
- import type { Disposable } from '../mod.js';
1
+ import type { Disposable } from '../utils/disposable.js';
2
2
  import type { Matcher } from '../utils/matcher.js';
3
3
  import type { Context, ContextEnd, ContextStart } from './context/context.js';
4
4
  import type { Document } from './context/turn/message/document.js';
@@ -15,7 +15,8 @@ import type { Turn, TurnEnd, TurnStart } from './context/turn/turn.js';
15
15
  import type { Goal, GoalChange } from './goal/goal.js';
16
16
  import type { Task, TaskEnd, TaskStart } from './goal/task.js';
17
17
  export declare const Session = "session";
18
- export type SessionEvent = typeof Message | MessageType | typeof ContextStart | typeof ContextEnd | typeof TurnStart | typeof TurnEnd | typeof TaskStart | typeof TaskEnd | typeof GoalChange;
18
+ export declare const UsageChange = "usageChange";
19
+ export type SessionEvent = typeof Message | MessageType | typeof ContextStart | typeof ContextEnd | typeof TurnStart | typeof TurnEnd | typeof TaskStart | typeof TaskEnd | typeof GoalChange | typeof UsageChange;
19
20
  export type SessionPayload = {
20
21
  readonly message: Message;
21
22
  readonly prompt: Prompt;
@@ -33,19 +34,73 @@ export type SessionPayload = {
33
34
  readonly taskStart: Task;
34
35
  readonly taskEnd: Task;
35
36
  readonly goalChange: Goal;
37
+ readonly usageChange: Usage;
36
38
  };
39
+ export type Refusal = {
40
+ readonly refuse: string;
41
+ };
42
+ export type BeforeAnswer = {
43
+ readonly prompt: {
44
+ readonly text: string;
45
+ } | Refusal;
46
+ readonly note: {
47
+ readonly text: string;
48
+ };
49
+ readonly skill: {
50
+ readonly text: string;
51
+ };
52
+ readonly document: {
53
+ readonly text: string;
54
+ } | Refusal;
55
+ readonly reply: {
56
+ readonly text: string;
57
+ };
58
+ readonly toolCall: {
59
+ readonly input: Readonly<Record<string, unknown>>;
60
+ } | {
61
+ readonly result: string;
62
+ } | Refusal;
63
+ readonly toolResult: {
64
+ readonly text: string;
65
+ };
66
+ readonly notice: {
67
+ readonly text: string;
68
+ };
69
+ readonly taskStart: {
70
+ readonly owner: {
71
+ readonly model: string;
72
+ };
73
+ } | Refusal;
74
+ readonly taskEnd: Refusal;
75
+ readonly turnEnd: Refusal;
76
+ readonly contextEnd: Refusal;
77
+ };
78
+ export type BeforeEvent = keyof BeforeAnswer;
37
79
  export type Usage = {
38
80
  readonly model: string;
39
81
  readonly context: {
40
82
  readonly tokens?: number;
41
- readonly window: number;
83
+ readonly window?: number;
42
84
  readonly percent?: number;
43
85
  };
44
86
  readonly cost?: {
45
87
  readonly usd: number;
46
88
  };
47
89
  };
90
+ export type Client = 'terminal' | 'desktop' | 'mobile' | 'vscode';
48
91
  export type Listener<Event extends SessionEvent> = (payload: SessionPayload[Event]) => unknown;
92
+ export type BeforeListener<Event extends BeforeEvent> = (payload: SessionPayload[Event]) => BeforeAnswer[Event] | void | Promise<BeforeAnswer[Event] | void>;
93
+ export type SearchOptions = {
94
+ readonly limit?: number;
95
+ readonly before?: Pick<Message, 'session' | 'id'>;
96
+ };
97
+ export type RecordPart = {
98
+ search(text: string, options?: SearchOptions): Promise<Message[]>;
99
+ on<Event extends SessionEvent>(event: Event, listener: Listener<Event>): Disposable;
100
+ on<Event extends SessionEvent>(event: Event, matcher: Matcher<SessionPayload[Event]>, listener: Listener<Event>): Disposable;
101
+ before<Event extends BeforeEvent>(event: Event, listener: BeforeListener<Event>): Disposable;
102
+ before<Event extends BeforeEvent>(event: Event, matcher: Matcher<SessionPayload[Event]>, listener: BeforeListener<Event>): Disposable;
103
+ };
49
104
  export type SessionSend = {
50
105
  readonly type: typeof Prompt | typeof Note;
51
106
  readonly text: string;
@@ -58,42 +113,46 @@ export type TaskStartArgs = {
58
113
  readonly name?: string;
59
114
  readonly cwd?: string;
60
115
  };
61
- export type Session = {
116
+ export type ToolCallArgs = {
117
+ readonly name: string;
118
+ readonly input: Readonly<Record<string, unknown>>;
119
+ };
120
+ export type Session = RecordPart & {
62
121
  readonly id: string;
63
122
  readonly title: string;
64
123
  readonly project: string;
65
- readonly cwd: string;
124
+ readonly agentType?: string;
66
125
  readonly model: string;
126
+ readonly cwd: string;
127
+ readonly isRunning: boolean;
67
128
  readonly startedAt: string;
68
129
  readonly lastAt: string;
69
130
  readonly forkedFrom?: string;
70
- readonly isRunning: boolean;
71
- usage(): Promise<Usage>;
72
- on<Event extends SessionEvent>(event: Event, listener: Listener<Event>): Disposable;
73
- on<Event extends SessionEvent>(event: Event, matcher: Matcher<SessionPayload[Event]>, listener: Listener<Event>): Disposable;
74
- send(message: SessionSend): Promise<void>;
75
- startTask(task: TaskStartArgs): Promise<Task>;
131
+ goal(): Promise<Goal>;
132
+ context(): Promise<Context>;
133
+ contexts(): Promise<Context[]>;
134
+ turn(): Promise<Turn | undefined>;
135
+ turns(options?: {
136
+ readonly last?: number;
137
+ }): Promise<Turn[]>;
76
138
  messages(options?: {
77
139
  readonly after?: string;
78
140
  readonly last?: number;
79
141
  }): Promise<Message[]>;
80
- turns(options?: {
81
- readonly last?: number;
82
- }): Promise<Turn[]>;
83
- contexts(): Promise<Context[]>;
84
- goal(): Promise<Goal>;
142
+ send(message: SessionSend): Promise<void>;
143
+ startTask(task: TaskStartArgs): Promise<Task>;
144
+ callTool(call: ToolCallArgs): Promise<ToolResult>;
145
+ usage(): Promise<Usage>;
146
+ clients(): Promise<Client[]>;
85
147
  };
86
148
  export type SessionScope = {
87
149
  readonly running?: boolean;
88
150
  readonly since?: string;
89
151
  readonly everyProject?: boolean;
90
152
  };
91
- export type Sessions = {
153
+ export type Sessions = Omit<RecordPart, 'search'> & {
92
154
  readonly current: Session;
93
155
  list(options?: SessionScope): Promise<Session[]>;
94
- search(text: string, options?: SessionScope & {
95
- readonly limit?: number;
96
- readonly before?: Pick<Message, 'session' | 'id'>;
97
- }): Promise<Message[]>;
156
+ search(text: string, options?: SessionScope & SearchOptions): Promise<Message[]>;
98
157
  };
99
158
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session/session.ts"],"names":[],"mappings":"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"}
@@ -1 +1,2 @@
1
1
  export const Session = 'session';
2
+ export const UsageChange = 'usageChange';
@@ -28,7 +28,12 @@ export function program(options: { readonly command: readonly string[]; readonly
28
28
  const stop = (reason: string) => {
29
29
  state = 'fatal'
30
30
  failure = new Error(`${mod.name}: the ${executable} program stopped: ${reason}`)
31
- report({ id: `program:${executable}`, message: `The ${executable} program stopped`, description: reason })
31
+ const retry = () => {
32
+ exits = 0
33
+ failure = undefined
34
+ void start()
35
+ }
36
+ report({ id: `program:${executable}`, message: `The ${executable} program stopped`, description: reason, retry })
32
37
  for (const waiter of waiting.splice(0)) waiter.reject(failure)
33
38
  }
34
39
 
@@ -66,7 +71,7 @@ export function program(options: { readonly command: readonly string[]; readonly
66
71
  exits += 1
67
72
  const wait = backoffSeconds[exits - 1]
68
73
  if (wait === undefined) {
69
- stop(`it did not start again after ${backoffSeconds.length} tries: ${lastError === '' ? 'no standard error' : lastError}. Fix it, then run /reload-plugins.`)
74
+ stop(`it did not start again after ${backoffSeconds.length} tries: ${lastError === '' ? 'no standard error' : lastError}.`)
70
75
  return
71
76
  }
72
77
  state = 'backoff'
package/src/mod.ts CHANGED
@@ -2,6 +2,7 @@ import type {
2
2
  AskOptions,
3
3
  ClassicHookInputs,
4
4
  CmodDependencies,
5
+ ConfigRow,
5
6
  FsStatOptions,
6
7
  HookStream,
7
8
  HttpInit,
@@ -28,11 +29,10 @@ import { Mod as modSender } from './session/context/turn/message/sender.js'
28
29
  import type { Sessions } from './session/session.js'
29
30
  import type { Pane } from './ui/define-pane.js'
30
31
  import type { Place, PlaceProps } from './ui/places.js'
32
+ import type { Disposable } from './utils/disposable.js'
31
33
  import type { Matcher } from './utils/matcher.js'
32
34
 
33
- export type Disposable = {
34
- dispose(): void
35
- }
35
+ export type { Disposable }
36
36
 
37
37
  export type ToastId = string | number
38
38
 
@@ -63,6 +63,8 @@ export type PaneHandle = {
63
63
  close(): Promise<void>
64
64
  toggle(options?: Readonly<Pick<PaneOpenArgs, 'focus'>>): Promise<void>
65
65
  readonly isOpen: boolean
66
+ readonly isShown: boolean
67
+ readonly isFocused: boolean
66
68
  }
67
69
 
68
70
  export const SessionStart = 'SessionStart'
@@ -83,26 +85,56 @@ export const Stop = 'Stop'
83
85
  export const StopFailure = 'StopFailure'
84
86
  export const CwdChanged = 'CwdChanged'
85
87
  export const FileChanged = 'FileChanged'
88
+ export const UserPromptExpansion = 'UserPromptExpansion'
89
+ export const Setup = 'Setup'
90
+ export const ConfigChange = 'ConfigChange'
91
+ export const DirectoryAdded = 'DirectoryAdded'
92
+ export const PreModelSwitch = 'PreModelSwitch'
93
+ export const PostModelSwitch = 'PostModelSwitch'
94
+ export const PostCompact = 'PostCompact'
95
+ export const MessageDisplay = 'MessageDisplay'
96
+ export const TodoCreated = 'TaskCreated'
97
+ export const TodoCompleted = 'TaskCompleted'
98
+ export const TeammateIdle = 'TeammateIdle'
99
+ export const Elicitation = 'Elicitation'
100
+ export const ElicitationResult = 'ElicitationResult'
101
+ export const WorktreeCreate = 'WorktreeCreate'
102
+ export const WorktreeRemove = 'WorktreeRemove'
86
103
 
87
104
  export const hooks = [
105
+ Setup,
88
106
  SessionStart,
89
107
  SessionEnd,
90
108
  UserPromptSubmit,
109
+ UserPromptExpansion,
91
110
  InstructionsLoaded,
111
+ ConfigChange,
112
+ DirectoryAdded,
113
+ PreModelSwitch,
114
+ PostModelSwitch,
92
115
  PreToolUse,
93
116
  PermissionRequest,
94
117
  PermissionDenied,
95
118
  PostToolUse,
96
119
  PostToolUseFailure,
97
120
  PostToolBatch,
121
+ MessageDisplay,
98
122
  SubagentStart,
99
123
  SubagentStop,
124
+ TodoCreated,
125
+ TodoCompleted,
126
+ TeammateIdle,
127
+ Elicitation,
128
+ ElicitationResult,
100
129
  Notification,
101
130
  PreCompact,
131
+ PostCompact,
102
132
  Stop,
103
133
  StopFailure,
104
134
  CwdChanged,
105
135
  FileChanged,
136
+ WorktreeCreate,
137
+ WorktreeRemove,
106
138
  ] as const
107
139
 
108
140
  export type Hook = (typeof hooks)[number]
@@ -129,6 +161,8 @@ export type HookAnswer = {
129
161
  updatedToolOutput?: unknown
130
162
  updatedMCPToolOutput?: unknown
131
163
  retry?: boolean
164
+ displayContent?: string
165
+ worktreePath?: string
132
166
  }
133
167
  }
134
168
 
@@ -203,9 +237,15 @@ export type SettingsFile = {
203
237
  update(values: Readonly<Record<string, unknown>>): Promise<void>
204
238
  }
205
239
 
240
+ export type Setting = Pick<ConfigRow, 'key' | 'label' | 'kind' | 'value' | 'isLocked'> & {
241
+ readonly description?: string
242
+ readonly options?: readonly string[]
243
+ readonly plugin?: string
244
+ }
245
+
206
246
  export type Imports = {
207
247
  readonly sessions: Sessions
208
- readonly settings: { readonly user: SettingsFile; readonly project: SettingsFile; readonly local: SettingsFile }
248
+ readonly settings: { list(): Promise<Setting[]>; readonly user: SettingsFile; readonly project: SettingsFile; readonly local: SettingsFile }
209
249
  readonly model: { complete(request: ModelCompleteRequest, options?: ModelCompleteOptions): Promise<ModelCompleteResult> }
210
250
  readonly fs: {
211
251
  read(path: string): Promise<string>
@@ -232,9 +272,12 @@ export const sessions: Imports['sessions'] = {
232
272
  },
233
273
  list: (options) => bound().sessions.list(options),
234
274
  search: (text, options) => bound().sessions.search(text, options),
275
+ on: ((...args: Parameters<Imports['sessions']['on']>) => bound().sessions.on(...args)) as Imports['sessions']['on'],
276
+ before: ((...args: Parameters<Imports['sessions']['before']>) => bound().sessions.before(...args)) as Imports['sessions']['before'],
235
277
  }
236
278
 
237
279
  export const settings: Imports['settings'] = {
280
+ list: () => bound().settings.list(),
238
281
  user: { read: () => bound().settings.user.read(), update: (values) => bound().settings.user.update(values) },
239
282
  project: { read: () => bound().settings.project.read(), update: (values) => bound().settings.project.update(values) },
240
283
  local: { read: () => bound().settings.local.read(), update: (values) => bound().settings.local.update(values) },
@@ -335,7 +378,7 @@ export function defineMod<State extends StateGroups = Record<never, never>, Name
335
378
  export type { Matcher } from './utils/matcher.js'
336
379
  export type { Place, PlaceProps } from './ui/places.js'
337
380
  export { AbovePrompt, AskUserQuestion, CommandOutput, PromptHint, SessionMode, Spinner, ToolGroup, ToolProgress, TurnDuration } from './ui/places.js'
338
- export { Session, type SessionEvent, type SessionPayload, type SessionScope, type SessionSend, type Sessions, type TaskStartArgs, type Usage } from './session/session.js'
381
+ export { Session, UsageChange, type BeforeAnswer, type BeforeEvent, type BeforeListener, type Client, type Listener, type RecordPart, type Refusal, type SearchOptions, type SessionEvent, type SessionPayload, type SessionScope, type SessionSend, type Sessions, type TaskStartArgs, type ToolCallArgs, type Usage } from './session/session.js'
339
382
  export { ContextEnd, ContextStart, type Context } from './session/context/context.js'
340
383
  export { TurnEnd, TurnStart, type Turn } from './session/context/turn/turn.js'
341
384
  export { Message, type MessageType } from './session/context/turn/message/message.js'
package/src/records.ts CHANGED
@@ -42,6 +42,7 @@ export type RunnerEvent =
42
42
  | { type: 'needs-consent'; sha256: string; install: string; uninstall: string; keys: string; permissions: readonly string[] }
43
43
  | { type: 'done'; name: string; version?: string }
44
44
  | { type: 'missing'; name: string }
45
+ | { type: 'retries'; when: 'changed' | 'later' }
45
46
  | { type: 'failed'; code: number; message: string }
46
47
 
47
48
  export const pluginName = /^[A-Za-z0-9][A-Za-z0-9._-]*$/
@@ -249,7 +250,7 @@ function readKeys(keys: unknown): Steps {
249
250
  return { keys: commands }
250
251
  }
251
252
 
252
- export const coreVersion = '1.0.0'
253
+ export const coreVersion = '1.5.0'
253
254
 
254
255
  export function oldestCmodFor(steps: Steps): string {
255
256
  if (steps.permissions?.some((item) => item === 'tasks' || item.startsWith('config:')) === true) return '1.0.0'
@@ -328,6 +329,8 @@ export function formatEvent(event: RunnerEvent): string {
328
329
  return `missing ${event.name}`
329
330
  case 'failed':
330
331
  return `failed ${event.code}\t${event.message.replace(/\s*\n\s*/g, ' ')}`
332
+ case 'retries':
333
+ return `retries ${event.when}`
331
334
  }
332
335
  }
333
336
 
@@ -345,6 +348,8 @@ export function parseEvent(line: string): RunnerEvent {
345
348
  if (missing !== null) return { type: 'missing', name: missing[1] as string }
346
349
  const failed = /^failed (-?\d+)(?:\t(.*))?$/.exec(line)
347
350
  if (failed !== null) return { type: 'failed', code: Number(failed[1]), message: failed[2] ?? '' }
351
+ const retries = /^retries (changed|later)$/.exec(line)
352
+ if (retries !== null) return { type: 'retries', when: retries[1] as 'changed' | 'later' }
348
353
  return { type: 'log', text: line.replace(/^log /, '') }
349
354
  }
350
355
 
package/src/register.ts CHANGED
@@ -30,6 +30,7 @@ async function startMod($: EngineInterface, eventInput: Frozen<Args<'session.sta
30
30
  panes: () => $.ui.panes(),
31
31
  scroll: (args) => $.ui.scroll(args),
32
32
  copy: (args) => $.ui.copy(args),
33
+ focus: (args) => $.ui.focus(args),
33
34
  resolve: (render) => $.ui.resolve(render),
34
35
  },
35
36
  process: {
@@ -101,21 +102,36 @@ export function registerMod<State extends object, Declared extends Options>(addH
101
102
  registered = definition as ModDefinition<object>
102
103
  lifecycle = createLifecycle(definition, () => checksPermissions, options)
103
104
  addHook('session.start', startMod)
105
+ addHook('classic.Setup', routeToMod)
104
106
  addHook('classic.SessionStart', routeToMod)
105
107
  addHook('classic.SessionEnd', routeToMod)
106
108
  addHook('classic.UserPromptSubmit', routeToMod)
109
+ addHook('classic.UserPromptExpansion', routeToMod)
107
110
  addHook('classic.InstructionsLoaded', routeToMod)
111
+ addHook('classic.ConfigChange', routeToMod)
112
+ addHook('classic.DirectoryAdded', routeToMod)
113
+ addHook('classic.PreModelSwitch', routeToMod)
114
+ addHook('classic.PostModelSwitch', routeToMod)
108
115
  addHook('classic.PermissionDenied', routeToMod)
109
116
  addHook('classic.PostToolUse', routeToMod)
110
117
  addHook('classic.PostToolUseFailure', routeToMod)
111
118
  addHook('classic.PostToolBatch', routeToMod)
119
+ addHook('classic.MessageDisplay', routeToMod)
112
120
  addHook('classic.SubagentStart', routeToMod)
113
121
  addHook('classic.SubagentStop', routeToMod)
122
+ addHook('classic.TaskCreated', routeToMod)
123
+ addHook('classic.TaskCompleted', routeToMod)
124
+ addHook('classic.TeammateIdle', routeToMod)
125
+ addHook('classic.Elicitation', routeToMod)
126
+ addHook('classic.ElicitationResult', routeToMod)
114
127
  addHook('classic.Notification', routeToMod)
115
128
  addHook('classic.PreCompact', routeToMod)
129
+ addHook('classic.PostCompact', routeToMod)
116
130
  addHook('classic.Stop', routeToMod)
117
131
  addHook('classic.StopFailure', routeToMod)
118
132
  addHook('classic.FileChanged', routeToMod)
133
+ addHook('classic.WorktreeCreate', routeToMod)
134
+ addHook('classic.WorktreeRemove', routeToMod)
119
135
  addHook('tool.call', routeToMod)
120
136
  addHook('prompt.submit', routeToMod)
121
137
  addHook('prompt.context', routeToMod)
@@ -132,6 +148,7 @@ export function registerMod<State extends object, Declared extends Options>(addH
132
148
  addHook('session.compact', routeToMod)
133
149
  addHook('session.receive', routeToMod)
134
150
  addHook('agent.spawn', routeToMod)
151
+ addHook('prompt.attachment', routeToMod)
135
152
  }
136
153
 
137
154
  export function registerPermissionCheck(addHook: On): void {
@@ -27,9 +27,11 @@ export async function announcementOf(claude: Claude, plugin: Plugin, granted: Re
27
27
  const open = (page?: string) => () => claude.cmod.call({ to: cmodPluginName, method: 'openSettings', input: { mod: plugin.name, ...(page === undefined ? {} : { page }) } })
28
28
  if (previous === undefined) {
29
29
  const { program, keys } = plugin.steps
30
+ const rules = (await claude.fs.list(`${plugin.root}/rules`).catch(ifMissing([]))).filter((entry) => entry.kind === 'file' && entry.name.endsWith('.md')).map((entry) => entry.name.slice(0, -'.md'.length)).toSorted()
30
31
  const lines = [
31
32
  field('description'),
32
33
  added.length > 0 ? `Adds ${listed(added)}.` : undefined,
34
+ rules.length > 0 ? `Adds ${rules.length} ${rules.length === 1 ? 'rule' : 'rules'}: ${listed(rules)}.` : undefined,
33
35
  program === undefined ? undefined : `Installed the ${program} program.`,
34
36
  ...Object.entries(keys ?? {}).map(([key, command]) => `Binds ${key} to /${command}.`),
35
37
  ...[...granted].map((item) => `${permissionWords(item)}.`),