@cmodjs/core 3.1.0 → 4.0.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.
- package/docs/commands.md +38 -21
- package/docs/dependencies.md +27 -20
- package/docs/index.md +21 -17
- package/docs/install-steps.md +37 -29
- package/docs/jobs.md +25 -52
- package/docs/mod.md +93 -65
- package/docs/options.md +2 -2
- package/docs/permissions.md +4 -4
- package/docs/session.md +14 -12
- package/docs/testing.md +55 -32
- package/docs/ui.md +255 -263
- package/hotkeys.d.ts +22 -0
- package/hotkeys.d.ts.map +1 -0
- package/hotkeys.js +26 -0
- package/installer.d.ts +1 -1
- package/installer.d.ts.map +1 -1
- package/installer.js +11 -6
- package/jobs/check.d.ts +2 -1
- package/jobs/check.d.ts.map +1 -1
- package/jobs/check.js +2 -2
- package/jobs/context.d.ts +2 -1
- package/jobs/context.d.ts.map +1 -1
- package/jobs/context.js +1 -1
- package/jobs/permissions.d.ts +2 -1
- package/jobs/permissions.d.ts.map +1 -1
- package/jobs/permissions.js +2 -2
- package/jobs/program.js +1 -1
- package/jobs/prompt.d.ts +2 -1
- package/jobs/prompt.d.ts.map +1 -1
- package/jobs/prompt.js +20 -13
- package/jobs/schedule.d.ts +2 -1
- package/jobs/schedule.d.ts.map +1 -1
- package/jobs/schedule.js +15 -1
- package/jobs/slash-command.d.ts +6 -2
- package/jobs/slash-command.d.ts.map +1 -1
- package/jobs/slash-command.js +6 -5
- package/jobs/tool.d.ts +6 -4
- package/jobs/tool.d.ts.map +1 -1
- package/jobs/tool.js +3 -3
- package/mod.d.ts +63 -42
- package/mod.d.ts.map +1 -1
- package/mod.js +11 -1
- package/package.json +1 -1
- package/records.d.ts +13 -8
- package/records.d.ts.map +1 -1
- package/records.js +41 -31
- package/register.d.ts.map +1 -1
- package/register.js +1 -2
- package/runtime/announce.d.ts +1 -1
- package/runtime/announce.d.ts.map +1 -1
- package/runtime/announce.js +6 -7
- package/runtime/before.d.ts +2 -2
- package/runtime/before.d.ts.map +1 -1
- package/runtime/before.js +1 -1
- package/runtime/claude.d.ts +0 -1
- package/runtime/claude.d.ts.map +1 -1
- package/runtime/conversations.d.ts +4 -1
- package/runtime/conversations.d.ts.map +1 -1
- package/runtime/conversations.js +42 -14
- package/runtime/dependencies.d.ts.map +1 -1
- package/runtime/dependencies.js +2 -1
- package/runtime/engine.d.ts +5 -0
- package/runtime/engine.d.ts.map +1 -1
- package/runtime/grants.js +2 -2
- package/runtime/hooks.d.ts +1 -1
- package/runtime/hooks.d.ts.map +1 -1
- package/runtime/hotkeys.d.ts +15 -0
- package/runtime/hotkeys.d.ts.map +1 -0
- package/runtime/hotkeys.js +58 -0
- package/runtime/installer.d.ts +5 -2
- package/runtime/installer.d.ts.map +1 -1
- package/runtime/installer.js +23 -12
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +190 -141
- package/runtime/options.js +2 -2
- package/runtime/pages.d.ts +28 -0
- package/runtime/pages.d.ts.map +1 -0
- package/runtime/pages.js +98 -0
- package/runtime/parts.d.ts +14 -0
- package/runtime/parts.d.ts.map +1 -0
- package/runtime/parts.js +63 -0
- package/runtime/permission-check.d.ts +2 -2
- package/runtime/permission-check.d.ts.map +1 -1
- package/runtime/programs.js +1 -1
- package/runtime/router.d.ts +2 -2
- package/runtime/router.d.ts.map +1 -1
- package/runtime/router.js +1 -1
- package/runtime/sessions.d.ts +10 -9
- package/runtime/sessions.d.ts.map +1 -1
- package/runtime/sessions.js +14 -5
- package/runtime/state.d.ts +2 -1
- package/runtime/state.d.ts.map +1 -1
- package/runtime/state.js +1 -0
- package/runtime/toaster.d.ts +1 -1
- package/runtime/toaster.d.ts.map +1 -1
- package/runtime/toaster.js +10 -4
- package/runtime/ui.d.ts +87 -5
- package/runtime/ui.d.ts.map +1 -1
- package/runtime/ui.js +372 -109
- package/runtime/watches.d.ts +9 -0
- package/runtime/watches.d.ts.map +1 -0
- package/runtime/watches.js +73 -0
- package/runtime/widgets.d.ts +48 -0
- package/runtime/widgets.d.ts.map +1 -0
- package/runtime/widgets.js +219 -0
- package/session/context/turn/message/message.d.ts.map +1 -1
- package/session/context/turn/message/message.js +7 -2
- package/session/session.d.ts +11 -5
- package/session/session.d.ts.map +1 -1
- package/src/hotkeys.ts +51 -0
- package/src/installer.ts +8 -4
- package/src/jobs/check.ts +4 -3
- package/src/jobs/context.ts +3 -2
- package/src/jobs/permissions.ts +4 -3
- package/src/jobs/program.ts +1 -1
- package/src/jobs/prompt.ts +23 -14
- package/src/jobs/schedule.ts +16 -2
- package/src/jobs/slash-command.ts +10 -7
- package/src/jobs/tool.ts +7 -5
- package/src/mod.ts +59 -47
- package/src/records.ts +46 -31
- package/src/register.ts +2 -3
- package/src/runtime/announce.ts +6 -7
- package/src/runtime/before.ts +4 -4
- package/src/runtime/claude.ts +0 -1
- package/src/runtime/conversations.ts +66 -20
- package/src/runtime/dependencies.ts +2 -1
- package/src/runtime/engine.ts +5 -0
- package/src/runtime/grants.ts +2 -2
- package/src/runtime/hooks.ts +1 -0
- package/src/runtime/hotkeys.ts +80 -0
- package/src/runtime/installer.ts +24 -12
- package/src/runtime/lifecycle.ts +189 -136
- package/src/runtime/options.ts +2 -2
- package/src/runtime/pages.ts +127 -0
- package/src/runtime/parts.ts +72 -0
- package/src/runtime/permission-check.ts +2 -2
- package/src/runtime/programs.ts +1 -1
- package/src/runtime/router.ts +3 -3
- package/src/runtime/sessions.ts +24 -15
- package/src/runtime/state.ts +3 -1
- package/src/runtime/toaster.ts +10 -4
- package/src/runtime/ui.ts +405 -115
- package/src/runtime/watches.ts +75 -0
- package/src/runtime/widgets.ts +287 -0
- package/src/session/context/turn/message/message.ts +7 -2
- package/src/session/session.ts +10 -6
- package/src/testing/fake-claude.ts +9 -6
- package/src/testing/fake-elements.ts +7 -4
- package/src/testing/fake-sessions.ts +6 -4
- package/src/testing.ts +203 -46
- package/src/ui/areas.ts +27 -0
- package/src/ui/elements.ts +35 -0
- package/src/ui/markdown.ts +18 -18
- package/src/ui/panes.ts +73 -0
- package/src/ui/styles.ts +53 -0
- package/src/utils/subscription.ts +1 -0
- package/testing/fake-claude.d.ts +0 -1
- package/testing/fake-claude.d.ts.map +1 -1
- package/testing/fake-claude.js +9 -5
- package/testing/fake-elements.js +7 -4
- package/testing/fake-sessions.d.ts +2 -1
- package/testing/fake-sessions.d.ts.map +1 -1
- package/testing/fake-sessions.js +1 -0
- package/testing.d.ts +21 -6
- package/testing.d.ts.map +1 -1
- package/testing.js +206 -45
- package/ui/areas.d.ts +29 -0
- package/ui/areas.d.ts.map +1 -0
- package/ui/areas.js +6 -0
- package/ui/elements.d.ts +3 -0
- package/ui/elements.d.ts.map +1 -1
- package/ui/elements.js +36 -0
- package/ui/markdown.d.ts +14 -14
- package/ui/markdown.d.ts.map +1 -1
- package/ui/markdown.js +11 -11
- package/ui/panes.d.ts +71 -0
- package/ui/panes.d.ts.map +1 -0
- package/ui/panes.js +16 -0
- package/ui/styles.d.ts +44 -0
- package/ui/styles.d.ts.map +1 -0
- package/ui/styles.js +24 -0
- package/utils/subscription.d.ts +4 -0
- package/utils/subscription.d.ts.map +1 -0
- package/jobs/status-line.d.ts +0 -6
- package/jobs/status-line.d.ts.map +0 -1
- package/jobs/status-line.js +0 -39
- package/src/jobs/status-line.ts +0 -44
- package/src/ui/define-pane.ts +0 -27
- package/src/ui/places.ts +0 -49
- package/src/utils/disposable.ts +0 -3
- package/ui/define-pane.d.ts +0 -15
- package/ui/define-pane.d.ts.map +0 -1
- package/ui/define-pane.js +0 -12
- package/ui/places.d.ts +0 -43
- package/ui/places.d.ts.map +0 -1
- package/ui/places.js +0 -31
- package/utils/disposable.d.ts +0 -4
- package/utils/disposable.d.ts.map +0 -1
- /package/utils/{disposable.js → subscription.js} +0 -0
package/runtime/before.js
CHANGED
|
@@ -215,7 +215,7 @@ export function installBefore({ claude, router, hooks }) {
|
|
|
215
215
|
return answer.refuse === undefined ? next(e) : { skip: answer.refuse };
|
|
216
216
|
}),
|
|
217
217
|
];
|
|
218
|
-
return {
|
|
218
|
+
return { remove: () => added.forEach((each) => each.remove()) };
|
|
219
219
|
}
|
|
220
220
|
export function closingContext(where, task, closedAt) {
|
|
221
221
|
return task === undefined ? { number: where.context, openedAt: where.contextOpenedAt, closedAt } : { number: task.context, openedAt: task.contextOpenedAt ?? task.openedAt, closedAt, task: task.id };
|
package/runtime/claude.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ export type Claude = {
|
|
|
5
5
|
readonly root: string;
|
|
6
6
|
};
|
|
7
7
|
readonly ui: {
|
|
8
|
-
status(text: string | undefined): void;
|
|
9
8
|
log(text: string, options?: UiLogOptions): void;
|
|
10
9
|
notice(toolUseId: string, text: string | undefined): void;
|
|
11
10
|
invalidate(event: InvalidatableEventName): void;
|
package/runtime/claude.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/runtime/claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,IAAI,EACJ,eAAe,EACf,UAAU,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,OAAO,EACP,MAAM,EACN,aAAa,EACb,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,KAAK,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,cAAc,EACf,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACjE,QAAQ,CAAC,EAAE,EAAE;QACX,
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/runtime/claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,IAAI,EACJ,eAAe,EACf,UAAU,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,OAAO,EACP,MAAM,EACN,aAAa,EACb,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,KAAK,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,cAAc,EACf,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACjE,QAAQ,CAAC,EAAE,EAAE;QACX,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;QAC/C,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;QACzD,UAAU,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAA;QAC/C,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QAChF,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;QAC/C,KAAK,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QACzC,KAAK,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAA;QACnC,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;QACnD,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;QAC7C,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;QAChD,OAAO,CAAC,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,aAAa,CAAC,CAAA;KACtD,CAAA;IACD,QAAQ,CAAC,OAAO,EAAE;QAChB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;QAC9E,KAAK,CAAC,OAAO,EAAE,mBAAmB,GAAG,UAAU,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAA;KACvF,CAAA;IACD,QAAQ,CAAC,EAAE,EAAE;QACX,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QACnC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QAChD,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;QACvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;QACtC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;KAC7D,CAAA;IACD,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;KAAE,CAAA;IAC7E,QAAQ,CAAC,QAAQ,EAAE;QAAE,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAA;IACvE,QAAQ,CAAC,MAAM,EAAE;QAAE,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;KAAE,CAAA;IACjD,QAAQ,CAAC,KAAK,EAAE;QACd,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;QAClC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QAC/C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QAClC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;KAC1B,CAAA;IACD,QAAQ,CAAC,KAAK,EAAE;QACd,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;QACtB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,KAAK,CAAA;QACxC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,KAAK,CAAA;KACzC,CAAA;IACD,QAAQ,CAAC,OAAO,EAAE;QAChB,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;QACrB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;QACvB,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;QACtB,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;QACxB,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC,CAAA;QAC9B,QAAQ,IAAI,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAAA;QAC7C,QAAQ,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAA;QAChD,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAA;QAC5C,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;KACzC,CAAA;IACD,QAAQ,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAA;IAChE,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IAC1D,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAA;KAAE,CAAA;IAClE,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,IAAI,IAAI,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC;QAAC,GAAG,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;KAAE,CAAA;IACjL,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;KAAE,CAAA;IAC7G,QAAQ,CAAC,KAAK,EAAE;QACd,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;QAC5B,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;KACvD,CAAA;IACD,QAAQ,CAAC,GAAG,EAAE;QACZ,IAAI,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;QACnC,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;QACvC,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;KAC1C,CAAA;IACD,QAAQ,CAAC,IAAI,EAAE;QAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;CACpE,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Args, EventResult, Frozen } from 'claude-code';
|
|
2
|
+
import { type TurnData } from '../session/conversation.js';
|
|
2
3
|
import type { Claude } from './claude.js';
|
|
3
4
|
import type { Router } from './router.js';
|
|
4
5
|
export type Conversations = {
|
|
@@ -6,12 +7,14 @@ export type Conversations = {
|
|
|
6
7
|
readonly caller?: string;
|
|
7
8
|
}): Promise<EventResult<'cmod.call'> | undefined>;
|
|
8
9
|
moved(): void;
|
|
10
|
+
turnClosedBy(rowId: string): TurnData | undefined;
|
|
9
11
|
};
|
|
10
|
-
export declare function serveConversations({ claude, router, store, project, report }: {
|
|
12
|
+
export declare function serveConversations({ claude, router, store, project, report, clear, }: {
|
|
11
13
|
readonly claude: Claude;
|
|
12
14
|
readonly router: Router;
|
|
13
15
|
readonly store: string;
|
|
14
16
|
readonly project: () => string;
|
|
15
17
|
readonly report: (id: string, message: string, error: unknown) => void;
|
|
18
|
+
readonly clear: (id: string) => void;
|
|
16
19
|
}): Conversations;
|
|
17
20
|
//# sourceMappingURL=conversations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../src/runtime/conversations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../src/runtime/conversations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAK5D,OAAO,EAA2J,KAAK,QAAQ,EAAmB,MAAM,4BAA4B,CAAA;AAQpO,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,aAAa,CAAA;AAkCrD,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,CAAA;IAClH,KAAK,IAAI,IAAI,CAAA;IACb,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAA;CAClD,CAAA;AAMD,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,MAAM,EACN,KAAK,EACL,OAAO,EACP,MAAM,EACN,KAAK,GACN,EAAE;IACD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAA;IAC9B,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACtE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CACrC,GAAG,aAAa,CA2lBhB"}
|
package/runtime/conversations.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { consentPath, dataFolder, isObject, parseConsent } from '../records.js';
|
|
1
|
+
import { consentPath, coreVersion, dataFolder, grantFix, isObject, parseConsent } from '../records.js';
|
|
2
2
|
import { Message, rowOfAppend } from '../session/context/turn/message/message.js';
|
|
3
3
|
import { modNote, Note } from '../session/context/turn/message/note.js';
|
|
4
4
|
import { Person } from '../session/context/turn/message/sender.js';
|
|
5
5
|
import { createConversation, emptyConversation } from '../session/conversation.js';
|
|
6
6
|
import { Session, UsageChange } from '../session/session.js';
|
|
7
7
|
import { GoalChange } from '../session/goal/goal.js';
|
|
8
|
+
import { TurnEnd, TurnStart } from '../session/context/turn/turn.js';
|
|
8
9
|
import { receivedMatcher } from '../utils/matcher.js';
|
|
9
10
|
import { ifMissing } from '../utils/paths.js';
|
|
10
11
|
import { formatExit, messageOf } from '../utils/text.js';
|
|
@@ -13,11 +14,15 @@ import { cmodPluginName } from './dependencies.js';
|
|
|
13
14
|
import { readLines, runCmod } from './programs.js';
|
|
14
15
|
import { PassedTimeout } from './deadline.js';
|
|
15
16
|
import { actPermission, conversationMethods, everySession, isAct, isHeardBy, isInScope, resultOf, spawnTask, usageOf } from './sessions.js';
|
|
17
|
+
const relayKinds = new Set(['act', 'before', 'answer', 'watch', 'goal']);
|
|
18
|
+
const isRelay = (value) => isObject(value) && relayKinds.has(value['kind']);
|
|
16
19
|
const bufferedTaskRows = 200;
|
|
17
20
|
const beforeDeadlineMs = 5000;
|
|
18
21
|
const awayFoldMs = 8000;
|
|
19
22
|
const livenessMs = 5000;
|
|
20
|
-
|
|
23
|
+
const keptClosings = 200;
|
|
24
|
+
const keptMessages = 200;
|
|
25
|
+
export function serveConversations({ claude, router, store, project, report, clear, }) {
|
|
21
26
|
const folder = dataFolder(store, cmodPluginName);
|
|
22
27
|
const goals = `${folder}/goals`;
|
|
23
28
|
const watches = `${folder}/before`;
|
|
@@ -64,17 +69,23 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
64
69
|
};
|
|
65
70
|
const ended = (id) => new Error(`session ${id} has ended`);
|
|
66
71
|
const isRunning = async (id) => (await json(['history', 'sessions', '--running', '--all'])).some((each) => each.id === id);
|
|
72
|
+
let lastTurn;
|
|
73
|
+
const closings = new Map();
|
|
67
74
|
const dispatch = (to, changes, isInProject = true) => {
|
|
68
75
|
for (const change of changes) {
|
|
76
|
+
if (to === session && (change.type === TurnStart || change.type === TurnEnd) && change.turn.prompt.task === undefined)
|
|
77
|
+
lastTurn = change.turn;
|
|
69
78
|
if (change.type === Message && !liveIds.has(change.message.id) && to === session) {
|
|
70
79
|
live.push(change.message);
|
|
71
80
|
liveIds.add(change.message.id);
|
|
81
|
+
if (live.length > keptMessages)
|
|
82
|
+
liveIds.delete(live.shift()?.id ?? '');
|
|
72
83
|
}
|
|
73
84
|
for (const [mod, sessions] of heard) {
|
|
74
85
|
const subscriptions = [...(sessions.get(to) ?? []), ...(isInProject ? (sessions.get(everySession) ?? []) : [])];
|
|
75
86
|
if (!subscriptions.some(({ event, matcher }) => isHeardBy(event, matcher, change)))
|
|
76
87
|
continue;
|
|
77
|
-
void claude.cmod.call({ to: mod, method: conversationMethods.changed, input: { session: to, change, isInProject } }).
|
|
88
|
+
void claude.cmod.call({ to: mod, method: conversationMethods.changed, input: { session: to, change, isInProject } }).then(() => clear(`changed:${mod}`), (error) => report(`changed:${mod}`, `Could not tell ${mod} about session ${to}`, error));
|
|
78
89
|
}
|
|
79
90
|
}
|
|
80
91
|
};
|
|
@@ -209,7 +220,7 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
209
220
|
};
|
|
210
221
|
const askHere = async (mod, event, change, from = session, isInProject = true) => {
|
|
211
222
|
if (from !== session && !(await isGranted(mod, 'conversation')))
|
|
212
|
-
throw new Error(`${mod} needs the conversation permission to change what happens in another session.
|
|
223
|
+
throw new Error(`${mod} needs the conversation permission to change what happens in another session. ${grantFix}`);
|
|
213
224
|
return claude.cmod.call({ to: mod, method: conversationMethods.before, input: { session: from, event, change, isInProject } });
|
|
214
225
|
};
|
|
215
226
|
const isUnderHere = (task, ancestor) => {
|
|
@@ -298,6 +309,11 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
298
309
|
return;
|
|
299
310
|
}
|
|
300
311
|
dispatch(session, conversation.add(row, task));
|
|
312
|
+
if (task !== undefined || row.type !== 'system' || row.name !== 'turn_duration' || lastTurn === undefined)
|
|
313
|
+
return;
|
|
314
|
+
closings.set(row.id, lastTurn);
|
|
315
|
+
if (closings.size > keptClosings)
|
|
316
|
+
closings.delete(closings.keys().next().value);
|
|
301
317
|
};
|
|
302
318
|
router.add('classic.SessionStart', async (e, next) => {
|
|
303
319
|
start(e.session_id, e.source);
|
|
@@ -353,9 +369,15 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
353
369
|
if (sent === undefined)
|
|
354
370
|
return next(e);
|
|
355
371
|
const relay = JSON.parse(sent);
|
|
356
|
-
claude.clock.after(0, () => void received(relay).catch((error) => report('relay', 'Could not answer another session', error)));
|
|
372
|
+
claude.clock.after(0, () => void (isRelay(relay) ? received(relay) : refuse(relay)).catch((error) => report('relay', 'Could not answer another session', error)));
|
|
357
373
|
return { consumed: 'cmod relay' };
|
|
358
374
|
});
|
|
375
|
+
const unknownTo = async (what) => new Error(`Session ${await claude.session.id()} runs cmod ${coreVersion}, which has no ${what}.`);
|
|
376
|
+
const refuse = async (relay) => {
|
|
377
|
+
if (!isObject(relay) || typeof relay['id'] !== 'string' || typeof relay['from'] !== 'string')
|
|
378
|
+
return;
|
|
379
|
+
await post(relay['from'], { kind: 'answer', id: relay['id'], deny: (await unknownTo(`"${String(relay['kind'])}" relay`)).message });
|
|
380
|
+
};
|
|
359
381
|
const received = async (relay) => {
|
|
360
382
|
if (relay.kind === 'answer') {
|
|
361
383
|
const waiting = asked.get(relay.id);
|
|
@@ -381,13 +403,13 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
381
403
|
}
|
|
382
404
|
};
|
|
383
405
|
if (relay.kind === 'act')
|
|
384
|
-
return answered(() => perform(relay.caller, relay.action, relay.input, relay.task));
|
|
406
|
+
return answered(async () => (isAct(relay.action) ? perform(relay.caller, relay.action, relay.input, relay.task) : Promise.reject(await unknownTo(`"${String(relay.action)}" action`))));
|
|
385
407
|
return answered(() => askHere(relay.mod, relay.event, relay.change, relay.from, relay.project === project()));
|
|
386
408
|
};
|
|
387
409
|
const checkAct = async (caller, action, input) => {
|
|
388
410
|
const needed = actPermission(action, input);
|
|
389
411
|
if (needed !== undefined && !(await isGranted(caller, needed)))
|
|
390
|
-
throw new Error(`${caller} needs the ${needed} permission for ${action}.
|
|
412
|
+
throw new Error(`${caller} needs the ${needed} permission for ${action}. ${grantFix}`);
|
|
391
413
|
};
|
|
392
414
|
const perform = async (caller, action, input, task) => {
|
|
393
415
|
await checkAct(caller, action, input);
|
|
@@ -487,6 +509,7 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
487
509
|
return context === 0 ? [] : [{ number: context, openedAt: contextOpenedAt }];
|
|
488
510
|
};
|
|
489
511
|
const lastOf = (items, last) => (typeof last === 'number' ? items.slice(-last) : [...items]);
|
|
512
|
+
const isHeld = (kept, last) => typeof last === 'number' && kept.length >= last;
|
|
490
513
|
const methods = {
|
|
491
514
|
async [conversationMethods.sessions](request) {
|
|
492
515
|
const found = await json(['history', 'sessions', ...scopeArgs(request), ...(request['running'] === true ? ['--running'] : [])]);
|
|
@@ -500,23 +523,27 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
500
523
|
async [conversationMethods.messages](request) {
|
|
501
524
|
const id = String(request['session']);
|
|
502
525
|
const filters = [...textArg('--turn', request['turn']), ...textArg('--task', request['task']), ...textArg('--after', request['after'])];
|
|
503
|
-
const saved =
|
|
526
|
+
const saved = () => json(['history', 'messages', id, ...filters, ...countArg('--last', request['last'])]);
|
|
504
527
|
if (id !== session)
|
|
505
|
-
return saved;
|
|
528
|
+
return saved();
|
|
506
529
|
await starting;
|
|
507
530
|
const fits = (message) => (request['turn'] === undefined || message.turn === request['turn']) && message.task === request['task'];
|
|
508
531
|
const after = typeof request['after'] === 'string' ? live.findIndex((message) => message.id === request['after']) : -1;
|
|
509
532
|
const kept = live.slice(after + 1).filter(fits);
|
|
510
|
-
|
|
533
|
+
if (after >= 0 || isHeld(kept, request['last']))
|
|
534
|
+
return lastOf(kept, request['last']);
|
|
535
|
+
return lastOf(merged(await saved(), kept, (message) => message.id), request['last']);
|
|
511
536
|
},
|
|
512
537
|
async [conversationMethods.turns](request) {
|
|
513
538
|
const id = String(request['session']);
|
|
514
|
-
const saved =
|
|
539
|
+
const saved = () => json(['history', 'turns', id, ...textArg('--task', request['task']), ...countArg('--context', request['context']), ...countArg('--last', request['last'])]);
|
|
515
540
|
if (id !== session)
|
|
516
|
-
return saved;
|
|
541
|
+
return saved();
|
|
517
542
|
await starting;
|
|
518
543
|
const kept = liveTurns(request['task']).filter((turn) => request['context'] === undefined || turn.context === request['context']);
|
|
519
|
-
|
|
544
|
+
if (isHeld(kept, request['last']))
|
|
545
|
+
return lastOf(kept, request['last']);
|
|
546
|
+
return lastOf(merged(await saved(), kept, (turn) => turn.prompt.id), request['last']);
|
|
520
547
|
},
|
|
521
548
|
async [conversationMethods.contexts](request) {
|
|
522
549
|
const id = String(request['session']);
|
|
@@ -599,6 +626,7 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
599
626
|
},
|
|
600
627
|
};
|
|
601
628
|
return {
|
|
629
|
+
turnClosedBy: (rowId) => closings.get(rowId),
|
|
602
630
|
moved() {
|
|
603
631
|
for (const [key, watch] of ownWatches)
|
|
604
632
|
ownWatches.set(key, { ...watch, project: project() });
|
|
@@ -613,7 +641,7 @@ export function serveConversations({ claude, router, store, project, report }) {
|
|
|
613
641
|
const input = isObject(e.input) ? e.input : {};
|
|
614
642
|
const isDropping = (e.method === conversationMethods.subscribe || e.method === conversationMethods.watchBefore) && Array.isArray(input['subscriptions']) && input['subscriptions'].length === 0;
|
|
615
643
|
if (e.method !== conversationMethods.act && !isDropping && input['session'] !== (await claude.session.id()) && !(await isGranted(e.caller, 'conversation')))
|
|
616
|
-
return { deny: `${e.caller ?? 'A mod'} reads your conversations without your grant.
|
|
644
|
+
return { deny: `${e.caller ?? 'A mod'} reads your conversations without your grant. ${grantFix}` };
|
|
617
645
|
try {
|
|
618
646
|
return { value: await method(input, e.caller) };
|
|
619
647
|
}
|
|
@@ -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;
|
|
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;AAG9E,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"}
|
package/runtime/dependencies.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { installFix } from '../records.js';
|
|
1
2
|
import { messageOf } from '../utils/text.js';
|
|
2
3
|
export const cmodPluginName = 'cmod';
|
|
3
4
|
export async function answerCall(name, api, e) {
|
|
@@ -36,5 +37,5 @@ export function answeringOwnCalls(claude, router) {
|
|
|
36
37
|
return { ...claude, cmod: { call } };
|
|
37
38
|
}
|
|
38
39
|
export function notInstalled(name) {
|
|
39
|
-
return `${name} is not installed.
|
|
40
|
+
return `${name} is not installed. ${installFix}`;
|
|
40
41
|
}
|
package/runtime/engine.d.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import type { Claude } from './claude.js';
|
|
2
|
+
import type { Pages } from './pages.js';
|
|
2
3
|
import type { Router } from './router.js';
|
|
3
4
|
import type { Failure } from './toaster.js';
|
|
4
5
|
import type { ToolCalls } from './tool-calls.js';
|
|
6
|
+
import type { Widgets } from './widgets.js';
|
|
5
7
|
export type Engine = {
|
|
6
8
|
readonly claude: Claude;
|
|
7
9
|
readonly router: Router;
|
|
8
10
|
readonly toolCalls: ToolCalls;
|
|
9
11
|
readonly report: (failure: Failure) => void;
|
|
10
12
|
readonly hasPermissionCheck: () => boolean;
|
|
13
|
+
readonly answerInput: <Answer>(run: () => Promise<Answer>, passOn: () => Promise<unknown>) => Promise<Answer>;
|
|
14
|
+
readonly widgets?: Widgets;
|
|
15
|
+
readonly pages?: Pages;
|
|
11
16
|
};
|
|
12
17
|
export declare function keepEngine(mod: object, engine: Engine): void;
|
|
13
18
|
export declare function engineOf(mod: object): Engine;
|
package/runtime/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/runtime/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/runtime/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,OAAO,CAAA;IAC1C,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7G,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CACvB,CAAA;AAID,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI5C"}
|
package/runtime/grants.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isObject, isSettingCovered, permissionWords, settingPaths } from '../records.js';
|
|
1
|
+
import { grantFix, isObject, isSettingCovered, permissionWords, settingPaths } from '../records.js';
|
|
2
2
|
import { relativePath } from '../utils/paths.js';
|
|
3
3
|
import { cmodPluginName } from './dependencies.js';
|
|
4
4
|
import { actPermission, conversationMethods, isAct, toolPermission } from './sessions.js';
|
|
@@ -182,7 +182,7 @@ function writeItem(grants, path) {
|
|
|
182
182
|
export function refusal(grants, call, item) {
|
|
183
183
|
const { name } = grants;
|
|
184
184
|
if (isCovered(new Set(grants.declared), item, grants.home))
|
|
185
|
-
return `${name} calls ${call} without your grant to "${permissionWords(item)}".
|
|
185
|
+
return `${name} calls ${call} without your grant to "${permissionWords(item)}". ${grantFix}`;
|
|
186
186
|
return `${name} calls ${call}, which needs ${declaration(item, grants.home)} in package.json "cmod".`;
|
|
187
187
|
}
|
|
188
188
|
function declaration(item, home) {
|
package/runtime/hooks.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { type CallBase } from '../utils/call-effects.js';
|
|
|
6
6
|
export type Hook = Exclude<ClassicHookEvent, 'PreToolUse'>;
|
|
7
7
|
export type HookFields = Readonly<Record<string, unknown>>;
|
|
8
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';
|
|
9
|
+
export type RoutedEvent = `classic.${Hook}` | 'tool.check' | 'tool.call' | 'prompt.submit' | 'prompt.context' | 'prompt.attachment' | 'command.run' | 'command.describe' | 'session.measure' | 'skill.prompt' | 'ui.render' | 'ui.press' | 'ui.scroll' | 'ui.close' | 'cmod.call' | 'session.append' | 'session.compact' | 'session.receive' | 'agent.spawn' | 'turn.start';
|
|
10
10
|
type CallFiles = {
|
|
11
11
|
readonly read: string[];
|
|
12
12
|
readonly changed: string[];
|
package/runtime/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC5D,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,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;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,CAM1L;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"}
|
|
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,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC5D,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,kBAAkB,GAClB,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,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;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,CAM1L;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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Hotkey, Hotkeys } from '../hotkeys.js';
|
|
2
|
+
import type { Claude } from './claude.js';
|
|
3
|
+
import type { Router } from './router.js';
|
|
4
|
+
import type { Failure } from './toaster.js';
|
|
5
|
+
export declare function readCombos(claude: Claude, configRoot: string | undefined): Promise<Map<string, string>>;
|
|
6
|
+
export declare function createHotkeys({ name, declared, configRoot, claude, router, answerInput, report, }: {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly declared: Hotkeys;
|
|
9
|
+
readonly configRoot: string | undefined;
|
|
10
|
+
readonly claude: Claude;
|
|
11
|
+
readonly router: Router;
|
|
12
|
+
readonly answerInput: <Answer>(run: () => Promise<Answer>, passOn: () => Promise<unknown>) => Promise<Answer>;
|
|
13
|
+
readonly report: (failure: Failure) => void;
|
|
14
|
+
}): Promise<Readonly<Record<string, Hotkey>>>;
|
|
15
|
+
//# sourceMappingURL=hotkeys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hotkeys.d.ts","sourceRoot":"","sources":["../src/runtime/hotkeys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAIpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAS7G;AAED,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,MAAM,EACN,MAAM,EACN,WAAW,EACX,MAAM,GACP,EAAE;IACD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7G,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAC5C,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CA4C5C"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { boundCombos, hotkeyCommand } from '../records.js';
|
|
2
|
+
import { ifMissing } from '../utils/paths.js';
|
|
3
|
+
import { messageOf } from '../utils/text.js';
|
|
4
|
+
export async function readCombos(claude, configRoot) {
|
|
5
|
+
if (configRoot === undefined)
|
|
6
|
+
return new Map();
|
|
7
|
+
const text = await claude.fs.read(`${configRoot}/keybindings.json`).catch(ifMissing('{}'));
|
|
8
|
+
try {
|
|
9
|
+
return boundCombos(JSON.parse(text));
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
claude.ui.log(`${configRoot}/keybindings.json is not JSON, so cmod reads no combos from it: ${messageOf(error)}`, { to: 'debug' });
|
|
13
|
+
return new Map();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export async function createHotkeys({ name, declared, configRoot, claude, router, answerInput, report, }) {
|
|
17
|
+
const entries = Object.entries(declared);
|
|
18
|
+
if (entries.length === 0)
|
|
19
|
+
return {};
|
|
20
|
+
const combos = await readCombos(claude, configRoot);
|
|
21
|
+
const listeners = new Map();
|
|
22
|
+
const commands = new Map();
|
|
23
|
+
for (const [hotkey, { title }] of entries) {
|
|
24
|
+
listeners.set(hotkey, new Set());
|
|
25
|
+
claude.command.register({ name: hotkeyCommand(name, hotkey), description: title, immediate: true }).then(({ command }) => void commands.set(command, hotkey), (error) => report({ id: `hotkey:${hotkey}`, message: `The ${title} hotkey is not added`, error }));
|
|
26
|
+
}
|
|
27
|
+
router.add('command.describe', async (e, next) => {
|
|
28
|
+
const described = await next(e);
|
|
29
|
+
return commands.has(e.command) ? { ...described, isHidden: true } : described;
|
|
30
|
+
});
|
|
31
|
+
router.add('command.run', async (e, next) => {
|
|
32
|
+
const hotkey = commands.get(e.command);
|
|
33
|
+
if (hotkey === undefined)
|
|
34
|
+
return next(e);
|
|
35
|
+
return answerInput(async () => {
|
|
36
|
+
for (const listener of listeners.get(hotkey) ?? []) {
|
|
37
|
+
try {
|
|
38
|
+
await listener();
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
report({ id: `hotkey:${hotkey}`, message: `The ${declared[hotkey]?.title ?? hotkey} hotkey failed`, error });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {};
|
|
45
|
+
}, () => next(e));
|
|
46
|
+
});
|
|
47
|
+
return Object.fromEntries(entries.map(([hotkey, { title }]) => [
|
|
48
|
+
hotkey,
|
|
49
|
+
{
|
|
50
|
+
title,
|
|
51
|
+
combo: combos.get(hotkeyCommand(name, hotkey)),
|
|
52
|
+
onPress(listener) {
|
|
53
|
+
listeners.get(hotkey)?.add(listener);
|
|
54
|
+
return { remove: () => void listeners.get(hotkey)?.delete(listener) };
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
]));
|
|
58
|
+
}
|
package/runtime/installer.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare const installerPaneOf: (name: string) => string;
|
|
|
7
7
|
export type Consent = {
|
|
8
8
|
readonly install: string;
|
|
9
9
|
readonly uninstall: string;
|
|
10
|
-
readonly
|
|
10
|
+
readonly hotkeys: string;
|
|
11
11
|
readonly permissions: readonly string[];
|
|
12
12
|
readonly updates?: string | undefined;
|
|
13
13
|
};
|
|
@@ -20,5 +20,8 @@ export type Installer = {
|
|
|
20
20
|
step<State extends object>(mod: Mod<State>, step: Step<State>, index: number, total: number): Promise<boolean>;
|
|
21
21
|
close(): Promise<void>;
|
|
22
22
|
};
|
|
23
|
-
export declare function createInstaller(name: string, claude: () => Claude
|
|
23
|
+
export declare function createInstaller(name: string, claude: () => Claude, waiting: {
|
|
24
|
+
show(open: () => Promise<void>): void;
|
|
25
|
+
hide(): void;
|
|
26
|
+
}): Installer;
|
|
24
27
|
//# sourceMappingURL=installer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/runtime/installer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAA;AAC7E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAI3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,eAAO,MAAM,eAAe,SAAU,MAAM,KAAG,MAA0E,CAAA;AAEzH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/runtime/installer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAA;AAC7E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAI3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,eAAO,MAAM,eAAe,SAAU,MAAM,KAAG,MAA0E,CAAA;AAEzH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC,CAAA;AAOD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAA;IAC5C,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,aAAa,CAAA;IACjD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7I,IAAI,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9G,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB,CAAA;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,OAAO,EAAE;IAAE,IAAI,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAAC,IAAI,IAAI,IAAI,CAAA;CAAE,GAAG,SAAS,CAoJ/I"}
|
package/runtime/installer.js
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
|
-
import { permissionWords } from '../records.js';
|
|
1
|
+
import { permissionWords, secretFix } from '../records.js';
|
|
2
2
|
import { Box, Button, drawWith, Input, Text } from '../ui/elements.js';
|
|
3
3
|
import { messageOf } from '../utils/text.js';
|
|
4
4
|
export const installerPaneOf = (name) => `installer-${name.replace(/[^A-Za-z0-9_-]/g, '_')}`.slice(0, 64);
|
|
5
|
-
export function createInstaller(name, claude) {
|
|
5
|
+
export function createInstaller(name, claude, waiting) {
|
|
6
6
|
const paneId = installerPaneOf(name);
|
|
7
7
|
let page;
|
|
8
8
|
let isOpen = false;
|
|
9
|
+
const open = async () => {
|
|
10
|
+
isOpen = true;
|
|
11
|
+
await claude().ui.open({ id: paneId, title: `Install ${name}`, focus: true, holdToasts: true, closeOnEscape: true });
|
|
12
|
+
};
|
|
9
13
|
const show = async (build, cancelled) => {
|
|
10
14
|
page?.cancel();
|
|
11
15
|
const answer = new Promise((resolve) => {
|
|
12
16
|
const done = (value) => {
|
|
13
17
|
if (page === shown)
|
|
14
18
|
page = undefined;
|
|
19
|
+
waiting.hide();
|
|
15
20
|
resolve(value);
|
|
16
21
|
};
|
|
17
22
|
const shown = { ...build(done), cancel: () => done(cancelled) };
|
|
18
23
|
page = shown;
|
|
19
24
|
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
await
|
|
23
|
-
|
|
25
|
+
waiting.show(open);
|
|
26
|
+
if (!isOpen)
|
|
27
|
+
await open().catch((error) => {
|
|
28
|
+
waiting.hide();
|
|
29
|
+
throw error;
|
|
30
|
+
});
|
|
24
31
|
claude().ui.invalidate('ui.render');
|
|
25
32
|
return answer;
|
|
26
33
|
};
|
|
@@ -37,18 +44,18 @@ export function createInstaller(name, claude) {
|
|
|
37
44
|
isOpen = false;
|
|
38
45
|
page?.cancel();
|
|
39
46
|
},
|
|
40
|
-
consent({ install, uninstall,
|
|
47
|
+
consent({ install, uninstall, hotkeys, permissions, updates }) {
|
|
41
48
|
const changes = [
|
|
42
49
|
...(install === '' ? [] : [`Run ${install} now${uninstall === '' ? '' : `, and ${uninstall} when you remove it`}`]),
|
|
43
50
|
...(install === '' && uninstall !== '' ? [`Run ${uninstall} when you remove it`] : []),
|
|
44
|
-
...(
|
|
51
|
+
...(hotkeys === '' ? [] : [`Bind ${hotkeys}`]),
|
|
45
52
|
...(updates === undefined ? [] : [`Update ${name} automatically from the ${updates} marketplace`]),
|
|
46
53
|
];
|
|
47
54
|
return show((answer) => ({
|
|
48
55
|
draw: () => frame(`${name} wants to:`, [
|
|
49
56
|
...(permissions.length === 0 ? [] : [Box({ flexDirection: 'column', children: permissions.map((item) => bullet(permissionWords(item))) })]),
|
|
50
57
|
...(changes.length === 0 ? [] : [Text({ children: permissions.length === 0 ? 'Change your computer:' : 'and change your computer:' }), Box({ flexDirection: 'column', children: changes.map(bullet) })]),
|
|
51
|
-
Text({ dimColor: true, children: 'You can turn each permission off later in
|
|
58
|
+
Text({ dimColor: true, children: 'You can turn each permission off later in Settings.' }),
|
|
52
59
|
], [Button({ key: 'not-now', hotkey: 'n', label: 'Not now', onPress: () => answer(false) }), Button({ key: 'accept', hotkey: 'a', label: 'Accept', onPress: () => answer(true) })]),
|
|
53
60
|
}), false);
|
|
54
61
|
},
|
|
@@ -58,12 +65,16 @@ export function createInstaller(name, claude) {
|
|
|
58
65
|
return show((answer) => ({
|
|
59
66
|
draw: () => frame(`${name} needs ${missing.length === 1 ? 'one setting' : `${missing.length} settings`}:`, missing.map(([key, option]) => {
|
|
60
67
|
const label = Text({ children: [Text({ bold: true, children: option.title }), option.description === '' ? '' : Text({ dimColor: true, children: ` ${option.description}` })] });
|
|
61
|
-
if (option.type === 'secret')
|
|
62
|
-
return Box({
|
|
68
|
+
if (option.type === 'secret') {
|
|
69
|
+
return Box({
|
|
70
|
+
flexDirection: 'column',
|
|
71
|
+
children: [label, Text({ dimColor: true, children: `${secretFix} Then press Next.` }), Button({ key: `secret:${key}`, label: 'Open /config', onPress: () => void claude().command.run({ command: 'config' }) })],
|
|
72
|
+
});
|
|
73
|
+
}
|
|
63
74
|
const failure = failures.get(key);
|
|
64
75
|
const field = Input({
|
|
65
76
|
key: `option:${key}`,
|
|
66
|
-
label: '
|
|
77
|
+
label: 'Value',
|
|
67
78
|
placeholder: option.type === 'choice' ? (option.choices ?? []).join(', ') : option.type === 'toggle' ? 'true or false' : option.type === 'list' ? 'comma-separated' : '',
|
|
68
79
|
value: saved.get(key) ?? '',
|
|
69
80
|
submitLabel: 'save',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/runtime/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAqB,WAAW,EAAE,MAAM,EAAc,WAAW,EAAE,aAAa,EAAwB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/runtime/lifecycle.ts"],"names":[],"mappings":"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"}
|