@cmodjs/core 3.0.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 +39 -22
- 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 +94 -66
- package/docs/options.md +2 -2
- package/docs/permissions.md +7 -5
- 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 +14 -8
- package/records.d.ts.map +1 -1
- package/records.js +44 -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/permission-check.js +12 -4
- 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 +50 -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 +13 -5
- 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/ui/elements.js
CHANGED
|
@@ -29,6 +29,41 @@ function built(current, value) {
|
|
|
29
29
|
const { name, props } = value[unbuilt];
|
|
30
30
|
return build(current, name, props);
|
|
31
31
|
}
|
|
32
|
+
const elementKey = '$cmodElement';
|
|
33
|
+
const handlerKey = '$cmodHandler';
|
|
34
|
+
export function elementData(value, handlers) {
|
|
35
|
+
if (typeof value === 'function')
|
|
36
|
+
return { [handlerKey]: handlers.push(value) - 1 };
|
|
37
|
+
if (Array.isArray(value))
|
|
38
|
+
return value.map((each) => elementData(each, handlers));
|
|
39
|
+
if (typeof value !== 'object' || value === null)
|
|
40
|
+
return value;
|
|
41
|
+
if (unbuilt in value) {
|
|
42
|
+
const { name, props } = value[unbuilt];
|
|
43
|
+
return { [elementKey]: name, props: elementData(props, handlers) };
|
|
44
|
+
}
|
|
45
|
+
if (Object.getPrototypeOf(value) !== Object.prototype)
|
|
46
|
+
throw new Error('a widget draws only the elements of ui/elements.js and ui/components.js, text, numbers, and plain objects.');
|
|
47
|
+
return Object.fromEntries(Object.entries(value).map(([key, each]) => [key, elementData(each, handlers)]));
|
|
48
|
+
}
|
|
49
|
+
export function elementOf(data, keyPrefix, press) {
|
|
50
|
+
if (Array.isArray(data))
|
|
51
|
+
return data.map((each) => elementOf(each, keyPrefix, press));
|
|
52
|
+
if (typeof data !== 'object' || data === null)
|
|
53
|
+
return data;
|
|
54
|
+
const fields = data;
|
|
55
|
+
if (typeof fields[handlerKey] === 'number') {
|
|
56
|
+
const handler = fields[handlerKey];
|
|
57
|
+
return (...args) => press(handler, JSON.parse(JSON.stringify(args)));
|
|
58
|
+
}
|
|
59
|
+
const name = fields[elementKey];
|
|
60
|
+
if (name === undefined)
|
|
61
|
+
return Object.fromEntries(Object.entries(fields).map(([key, each]) => [key, elementOf(each, keyPrefix, press)]));
|
|
62
|
+
if (typeof name !== 'string' || !Object.hasOwn(constructors, name))
|
|
63
|
+
throw new Error(`a widget drew ${String(name)}, which is not an element of ui/elements.js.`);
|
|
64
|
+
const props = elementOf(fields['props'], keyPrefix, press);
|
|
65
|
+
return constructors[name]((typeof props['key'] === 'string' ? { ...props, key: `${keyPrefix}${props['key']}` } : props));
|
|
66
|
+
}
|
|
32
67
|
export const Box = element('Box');
|
|
33
68
|
export const Text = element('Text');
|
|
34
69
|
export const Button = element('Button');
|
|
@@ -38,3 +73,4 @@ export const Markdown = element('Markdown');
|
|
|
38
73
|
export const Input = element('Input');
|
|
39
74
|
export const Select = element('Select');
|
|
40
75
|
export const Image = element('Image');
|
|
76
|
+
const constructors = { Box, Text, Button, Link, Code, Markdown, Input, Select, Image };
|
package/ui/markdown.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
type
|
|
1
|
+
import type { StyleProps } from './styles.js';
|
|
2
|
+
type BlockText = {
|
|
3
3
|
readonly text: string;
|
|
4
4
|
readonly source: string;
|
|
5
5
|
};
|
|
@@ -24,28 +24,28 @@ type BlockFields = {
|
|
|
24
24
|
readonly value: string;
|
|
25
25
|
};
|
|
26
26
|
};
|
|
27
|
-
export type BlockProps<Type extends string> = Type extends keyof BlockFields ?
|
|
27
|
+
export type BlockProps<Type extends string> = Type extends keyof BlockFields ? BlockText & BlockFields[Type] : BlockText;
|
|
28
28
|
export type MarkdownPiece<Render> = {
|
|
29
29
|
readonly text: string;
|
|
30
30
|
} | {
|
|
31
31
|
readonly render: Render;
|
|
32
|
-
readonly props:
|
|
32
|
+
readonly props: BlockText;
|
|
33
33
|
};
|
|
34
34
|
export type MarkdownReader = <Render>(text: string, renderOf: (type: string) => Render | undefined, replyId?: string) => readonly MarkdownPiece<Render>[];
|
|
35
|
-
export type
|
|
35
|
+
export type Block<Type extends string = string> = {
|
|
36
36
|
readonly name: string;
|
|
37
37
|
readonly markdown: Type;
|
|
38
38
|
createReader(): MarkdownReader;
|
|
39
39
|
};
|
|
40
|
-
export declare const Heading:
|
|
41
|
-
export declare const Paragraph:
|
|
42
|
-
export declare const CodeBlock:
|
|
43
|
-
export declare const BlockQuote:
|
|
44
|
-
export declare const List:
|
|
45
|
-
export declare const Table:
|
|
46
|
-
export declare const ThematicBreak:
|
|
47
|
-
export declare const HtmlBlock:
|
|
40
|
+
export declare const Heading: Block<"heading">;
|
|
41
|
+
export declare const Paragraph: Block<"paragraph">;
|
|
42
|
+
export declare const CodeBlock: Block<"code">;
|
|
43
|
+
export declare const BlockQuote: Block<"blockquote">;
|
|
44
|
+
export declare const List: Block<"list">;
|
|
45
|
+
export declare const Table: Block<"table">;
|
|
46
|
+
export declare const ThematicBreak: Block<"thematicBreak">;
|
|
47
|
+
export declare const HtmlBlock: Block<"html">;
|
|
48
48
|
export declare function createReader(): MarkdownReader;
|
|
49
|
-
export declare function markdownBlocks<
|
|
49
|
+
export declare function markdownBlocks<K extends Block>(text: string, kind: K): Omit<StyleProps<K>, 'Default'>[];
|
|
50
50
|
export {};
|
|
51
51
|
//# sourceMappingURL=markdown.d.ts.map
|
package/ui/markdown.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/ui/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,KAAK,
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/ui/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,KAAK,SAAS,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnE,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;KAAE,CAAA;IAClD,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACtG,IAAI,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAA;IACjG,KAAK,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAA;KAAE,CAAA;IAC1E,IAAI,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,IAAI,SAAS,MAAM,IAAI,IAAI,SAAS,MAAM,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,CAAA;AAExH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAA;AAEtH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,SAAS,aAAa,CAAC,MAAM,CAAC,EAAE,CAAA;AAEzJ,MAAM,MAAM,KAAK,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;IACvB,YAAY,IAAI,cAAc,CAAA;CAC/B,CAAA;AAMD,eAAO,MAAM,OAAO,kBAAkC,CAAA;AACtD,eAAO,MAAM,SAAS,oBAAsC,CAAA;AAC5D,eAAO,MAAM,SAAS,eAAiC,CAAA;AACvD,eAAO,MAAM,UAAU,qBAAwC,CAAA;AAC/D,eAAO,MAAM,IAAI,eAA4B,CAAA;AAC7C,eAAO,MAAM,KAAK,gBAA8B,CAAA;AAChD,eAAO,MAAM,aAAa,wBAA8C,CAAA;AACxE,eAAO,MAAM,SAAS,eAAiC,CAAA;AA4BvD,wBAAgB,YAAY,IAAI,cAAc,CA0C7C;AA0DD,wBAAgB,cAAc,CAAC,CAAC,SAAS,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAGvG"}
|
package/ui/markdown.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { fromMarkdown, gfm, gfmFromMarkdown, toString } from '../vendor-markdown.js';
|
|
2
|
-
function
|
|
2
|
+
function blockKind(name, markdown) {
|
|
3
3
|
return { name, markdown, createReader };
|
|
4
4
|
}
|
|
5
|
-
export const Heading =
|
|
6
|
-
export const Paragraph =
|
|
7
|
-
export const CodeBlock =
|
|
8
|
-
export const BlockQuote =
|
|
9
|
-
export const List =
|
|
10
|
-
export const Table =
|
|
11
|
-
export const ThematicBreak =
|
|
12
|
-
export const HtmlBlock =
|
|
5
|
+
export const Heading = blockKind('Heading', 'heading');
|
|
6
|
+
export const Paragraph = blockKind('Paragraph', 'paragraph');
|
|
7
|
+
export const CodeBlock = blockKind('CodeBlock', 'code');
|
|
8
|
+
export const BlockQuote = blockKind('BlockQuote', 'blockquote');
|
|
9
|
+
export const List = blockKind('List', 'list');
|
|
10
|
+
export const Table = blockKind('Table', 'table');
|
|
11
|
+
export const ThematicBreak = blockKind('ThematicBreak', 'thematicBreak');
|
|
12
|
+
export const HtmlBlock = blockKind('HtmlBlock', 'html');
|
|
13
13
|
const keptReplies = 64;
|
|
14
14
|
const extensions = [gfm()];
|
|
15
15
|
const mdastExtensions = [gfmFromMarkdown()];
|
|
@@ -120,7 +120,7 @@ function plainText(node) {
|
|
|
120
120
|
return toString(node);
|
|
121
121
|
return node.children.map(plainText).join(node.type === 'tableRow' ? '\t' : '\n');
|
|
122
122
|
}
|
|
123
|
-
export function markdownBlocks(text,
|
|
124
|
-
const blocks = parsed(text, 0).filter((block) => block.type ===
|
|
123
|
+
export function markdownBlocks(text, kind) {
|
|
124
|
+
const blocks = parsed(text, 0).filter((block) => block.type === kind.markdown);
|
|
125
125
|
return blocks.map((block) => block.props);
|
|
126
126
|
}
|
package/ui/panes.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Frozen, PaneCloseInput, RenderElement, RenderPropsOf, UiScrollInput } from 'claude-code';
|
|
2
|
+
import type { Mod } from '../mod.js';
|
|
3
|
+
export type ScrollTarget = 'start' | 'end' | {
|
|
4
|
+
readonly key: string;
|
|
5
|
+
};
|
|
6
|
+
export type ScrollOptions = {
|
|
7
|
+
readonly block?: 'start' | 'center' | 'end' | 'nearest';
|
|
8
|
+
};
|
|
9
|
+
export type OpenOptions<Params> = {
|
|
10
|
+
readonly focus?: true;
|
|
11
|
+
} & (undefined extends Params ? {
|
|
12
|
+
readonly params?: Params;
|
|
13
|
+
} : {
|
|
14
|
+
readonly params: Params;
|
|
15
|
+
});
|
|
16
|
+
export type PaneProps<Params> = Frozen<RenderPropsOf['Pane']> & {
|
|
17
|
+
readonly params: Params;
|
|
18
|
+
};
|
|
19
|
+
export type PaneInit<State extends object = Record<never, never>, Params = undefined> = {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly title: string;
|
|
22
|
+
readonly columns?: number | ((state: State) => number | undefined);
|
|
23
|
+
readonly rows?: number | ((state: State) => number | undefined);
|
|
24
|
+
readonly closeOnEscape?: true;
|
|
25
|
+
readonly holdToasts?: true;
|
|
26
|
+
render(mod: Mod<State>, props: PaneProps<Params>): RenderElement;
|
|
27
|
+
onScroll?(mod: Mod<State>, e: Frozen<UiScrollInput>): void | Promise<void>;
|
|
28
|
+
onClose?(mod: Mod<State>, e: Frozen<PaneCloseInput>): void | Promise<void>;
|
|
29
|
+
};
|
|
30
|
+
export type Pane<Params = undefined> = {
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly isOpen: boolean;
|
|
33
|
+
readonly isShown: boolean;
|
|
34
|
+
readonly isFocused: boolean;
|
|
35
|
+
readonly params: Params | undefined;
|
|
36
|
+
open(...options: undefined extends Params ? [options?: OpenOptions<Params>] : [options: OpenOptions<Params>]): Promise<void>;
|
|
37
|
+
toggle(options?: {
|
|
38
|
+
readonly focus?: true;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
close(): Promise<void>;
|
|
41
|
+
scrollTo(target: ScrollTarget, options?: ScrollOptions): Promise<void>;
|
|
42
|
+
remove(): void;
|
|
43
|
+
};
|
|
44
|
+
export type PageProps<Params> = {
|
|
45
|
+
readonly params: Params;
|
|
46
|
+
readonly isFocused: boolean;
|
|
47
|
+
readonly columns: number;
|
|
48
|
+
};
|
|
49
|
+
export type PageInit<State extends object = Record<never, never>, Params = undefined> = {
|
|
50
|
+
readonly id: string;
|
|
51
|
+
readonly title: string;
|
|
52
|
+
render(mod: Mod<State>, props: PageProps<Params>): RenderElement;
|
|
53
|
+
};
|
|
54
|
+
export type Page<Params = undefined> = {
|
|
55
|
+
readonly id: string;
|
|
56
|
+
readonly isOpen: boolean;
|
|
57
|
+
readonly isShown: boolean;
|
|
58
|
+
readonly isFocused: boolean;
|
|
59
|
+
readonly params: Params | undefined;
|
|
60
|
+
open(...options: undefined extends Params ? [options?: OpenOptions<Params>] : [options: OpenOptions<Params>]): Promise<void>;
|
|
61
|
+
toggle(options?: {
|
|
62
|
+
readonly focus?: true;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
close(): Promise<void>;
|
|
65
|
+
scrollTo(target: ScrollTarget, options?: ScrollOptions): Promise<void>;
|
|
66
|
+
remove(): void;
|
|
67
|
+
};
|
|
68
|
+
export declare const sizeKeys: readonly ['columns', 'rows'];
|
|
69
|
+
export declare function checkPart(name: string, kind: string, id: string, title: string): void;
|
|
70
|
+
export declare function checkPane<State extends object, Params>(name: string, pane: PaneInit<State, Params>): void;
|
|
71
|
+
//# sourceMappingURL=panes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panes.d.ts","sourceRoot":"","sources":["../src/ui/panes.ts"],"names":[],"mappings":"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"}
|
package/ui/panes.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const partId = /^[A-Za-z0-9_-]{1,64}$/;
|
|
2
|
+
export const sizeKeys = ['columns', 'rows'];
|
|
3
|
+
export function checkPart(name, kind, id, title) {
|
|
4
|
+
if (!partId.test(id))
|
|
5
|
+
throw new Error(`${name}: "${id}" is not a ${kind} id. Use 1 to 64 letters, digits, "_", or "-".`);
|
|
6
|
+
if (title.trim() === '')
|
|
7
|
+
throw new Error(`${name}: the ${kind} "${id}" needs a title, the label its tab shows.`);
|
|
8
|
+
}
|
|
9
|
+
export function checkPane(name, pane) {
|
|
10
|
+
checkPart(name, 'pane', pane.id, pane.title);
|
|
11
|
+
for (const key of sizeKeys) {
|
|
12
|
+
const size = pane[key];
|
|
13
|
+
if (typeof size !== 'function' && size !== undefined && (!Number.isInteger(size) || size <= 0))
|
|
14
|
+
throw new Error(`${name}: the pane "${pane.id}" has ${key} ${size}. Use a whole number above 0, or leave it out.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
package/ui/styles.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Frozen, RenderComponent, RenderElement, RenderPropsOf } from 'claude-code';
|
|
2
|
+
import type { Mod } from '../mod.js';
|
|
3
|
+
import type { Block, BlockProps } from './markdown.js';
|
|
4
|
+
export declare const ToolGroup = "toolGroup";
|
|
5
|
+
export declare const ToolProgress = "toolProgress";
|
|
6
|
+
export declare const CommandOutput = "commandOutput";
|
|
7
|
+
export declare const AskUserQuestion = "askUserQuestion";
|
|
8
|
+
declare const components: {
|
|
9
|
+
readonly prompt: 'UserMessage';
|
|
10
|
+
readonly reply: 'AssistantMessage';
|
|
11
|
+
readonly toolCall: 'ToolUse';
|
|
12
|
+
readonly toolResult: 'ToolResult';
|
|
13
|
+
readonly notice: 'InfoNotice';
|
|
14
|
+
readonly toolGroup: 'ToolGroup';
|
|
15
|
+
readonly toolProgress: 'ToolProgress';
|
|
16
|
+
readonly commandOutput: 'CommandOutput';
|
|
17
|
+
readonly askUserQuestion: 'AskUserQuestion';
|
|
18
|
+
readonly working: 'Spinner';
|
|
19
|
+
readonly turnEnd: 'TurnDuration';
|
|
20
|
+
};
|
|
21
|
+
export type Row = keyof typeof components;
|
|
22
|
+
export type Kind = Row | Block;
|
|
23
|
+
type RowProps = {
|
|
24
|
+
readonly [R in Row]: RenderPropsOf[(typeof components)[R]];
|
|
25
|
+
};
|
|
26
|
+
type PropsOf<K extends Kind> = K extends Row ? RowProps[K] : K extends Block<infer Type> ? BlockProps<Type> : never;
|
|
27
|
+
type DefaultOf<K extends Kind> = K extends Row ? Partial<Omit<RowProps[K], 'onScreen'>> : {
|
|
28
|
+
readonly source?: string;
|
|
29
|
+
};
|
|
30
|
+
export type StyleProps<K extends Kind> = Frozen<PropsOf<K>> & {
|
|
31
|
+
readonly Default: (props: Frozen<DefaultOf<K>>) => RenderElement;
|
|
32
|
+
};
|
|
33
|
+
export type StyleInit<K extends Kind, State extends object = Record<never, never>> = {
|
|
34
|
+
readonly kind: K;
|
|
35
|
+
render(mod: Mod<State>, props: StyleProps<K>): RenderElement;
|
|
36
|
+
};
|
|
37
|
+
export type Style = {
|
|
38
|
+
readonly kind: Kind;
|
|
39
|
+
remove(): void;
|
|
40
|
+
};
|
|
41
|
+
export declare function componentOf(kind: Kind): Exclude<RenderComponent, 'Pane'> | undefined;
|
|
42
|
+
export declare function nameOf(kind: Kind): string;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/ui/styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAEtD,eAAO,MAAM,SAAS,cAAc,CAAA;AACpC,eAAO,MAAM,YAAY,iBAAiB,CAAA;AAC1C,eAAO,MAAM,aAAa,kBAAkB,CAAA;AAC5C,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAEhD,QAAA,MAAM,UAAU;qBACN,aAAa;oBACd,kBAAkB;uBACf,SAAS;yBACP,YAAY;qBAChB,YAAY;wBACP,WAAW;2BACR,cAAc;4BACb,eAAe;8BACb,iBAAiB;sBACzB,SAAS;sBACT,cAAc;CACoD,CAAA;AAE/E,MAAM,MAAM,GAAG,GAAG,MAAM,OAAO,UAAU,CAAA;AAEzC,MAAM,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAA;AAE9B,KAAK,QAAQ,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,GAAG,GAAG,aAAa,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAE9E,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;AAEnH,KAAK,SAAS,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAA;CAAE,CAAA;AAElI,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;IACnF,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,aAAa,CAAA;CAC7D,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,MAAM,IAAI,IAAI,CAAA;CACf,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,SAAS,CAEpF;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEzC"}
|
package/ui/styles.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TurnEnd, Working } from './areas.js';
|
|
2
|
+
export const ToolGroup = 'toolGroup';
|
|
3
|
+
export const ToolProgress = 'toolProgress';
|
|
4
|
+
export const CommandOutput = 'commandOutput';
|
|
5
|
+
export const AskUserQuestion = 'askUserQuestion';
|
|
6
|
+
const components = {
|
|
7
|
+
prompt: 'UserMessage',
|
|
8
|
+
reply: 'AssistantMessage',
|
|
9
|
+
toolCall: 'ToolUse',
|
|
10
|
+
toolResult: 'ToolResult',
|
|
11
|
+
notice: 'InfoNotice',
|
|
12
|
+
[ToolGroup]: 'ToolGroup',
|
|
13
|
+
[ToolProgress]: 'ToolProgress',
|
|
14
|
+
[CommandOutput]: 'CommandOutput',
|
|
15
|
+
[AskUserQuestion]: 'AskUserQuestion',
|
|
16
|
+
[Working]: 'Spinner',
|
|
17
|
+
[TurnEnd]: 'TurnDuration',
|
|
18
|
+
};
|
|
19
|
+
export function componentOf(kind) {
|
|
20
|
+
return typeof kind === 'string' && Object.hasOwn(components, kind) ? components[kind] : undefined;
|
|
21
|
+
}
|
|
22
|
+
export function nameOf(kind) {
|
|
23
|
+
return typeof kind === 'string' ? `${kind.charAt(0).toUpperCase()}${kind.slice(1)}` : kind.name;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../src/utils/subscription.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,IAAI,IAAI,CAAA;CAAE,CAAA"}
|
package/jobs/status-line.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { Job, Mod } from '../mod.js';
|
|
2
|
-
import type { Usage } from '../session/session.js';
|
|
3
|
-
export declare function statusLine<State extends object = Record<never, never>>(options: {
|
|
4
|
-
readonly text: (usage: Usage, mod: Mod<State>) => string | undefined | Promise<string | undefined>;
|
|
5
|
-
}): Job<void, State>;
|
|
6
|
-
//# sourceMappingURL=status-line.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"status-line.d.ts","sourceRoot":"","sources":["../src/jobs/status-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAKzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAMlD,wBAAgB,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CAAE,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAgCzM"}
|
package/jobs/status-line.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { engineOf } from '../runtime/engine.js';
|
|
2
|
-
import { usageOf } from '../runtime/sessions.js';
|
|
3
|
-
import { onStateChange } from '../runtime/state.js';
|
|
4
|
-
import { messageOf } from '../utils/text.js';
|
|
5
|
-
import { withinDeadline } from './context.js';
|
|
6
|
-
const deadline = { ms: 2000, job: 'statusLine' };
|
|
7
|
-
export function statusLine(options) {
|
|
8
|
-
const { text } = options;
|
|
9
|
-
return (job) => {
|
|
10
|
-
const { mod, announce, reserveName } = job;
|
|
11
|
-
const { claude, router } = engineOf(mod);
|
|
12
|
-
reserveName('statusLine', '', `${mod.name}: a status line is already added. A mod has one status line: join the texts in one statusLine.`);
|
|
13
|
-
let shown;
|
|
14
|
-
let queue = Promise.resolve();
|
|
15
|
-
const update = async () => {
|
|
16
|
-
try {
|
|
17
|
-
const usage = await usageOf(claude);
|
|
18
|
-
const next = await withinDeadline(mod, deadline, 'the status line', () => text(usage, mod));
|
|
19
|
-
if (next === shown)
|
|
20
|
-
return;
|
|
21
|
-
shown = next;
|
|
22
|
-
claude.ui.status(next);
|
|
23
|
-
}
|
|
24
|
-
catch (error) {
|
|
25
|
-
mod.log(`the status line kept its last text: ${messageOf(error)}`);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
const refresh = () => {
|
|
29
|
-
queue = queue.then(update);
|
|
30
|
-
};
|
|
31
|
-
announce('a status line');
|
|
32
|
-
router.add('session.measure', (e, next) => {
|
|
33
|
-
refresh();
|
|
34
|
-
return next(e);
|
|
35
|
-
});
|
|
36
|
-
onStateChange(mod.state, refresh);
|
|
37
|
-
refresh();
|
|
38
|
-
};
|
|
39
|
-
}
|
package/src/jobs/status-line.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { Job, Mod } from '../mod.js'
|
|
2
|
-
import type { Deadline } from '../runtime/deadline.js'
|
|
3
|
-
import { engineOf } from '../runtime/engine.js'
|
|
4
|
-
import { usageOf } from '../runtime/sessions.js'
|
|
5
|
-
import { onStateChange } from '../runtime/state.js'
|
|
6
|
-
import type { Usage } from '../session/session.js'
|
|
7
|
-
import { messageOf } from '../utils/text.js'
|
|
8
|
-
import { withinDeadline } from './context.js'
|
|
9
|
-
|
|
10
|
-
const deadline: Deadline = { ms: 2000, job: 'statusLine' }
|
|
11
|
-
|
|
12
|
-
export function statusLine<State extends object = Record<never, never>>(options: { readonly text: (usage: Usage, mod: Mod<State>) => string | undefined | Promise<string | undefined> }): Job<void, State> {
|
|
13
|
-
const { text } = options
|
|
14
|
-
return (job) => {
|
|
15
|
-
const { mod, announce, reserveName } = job
|
|
16
|
-
const { claude, router } = engineOf(mod)
|
|
17
|
-
reserveName('statusLine', '', `${mod.name}: a status line is already added. A mod has one status line: join the texts in one statusLine.`)
|
|
18
|
-
|
|
19
|
-
let shown: string | undefined
|
|
20
|
-
let queue = Promise.resolve()
|
|
21
|
-
const update = async () => {
|
|
22
|
-
try {
|
|
23
|
-
const usage = await usageOf(claude)
|
|
24
|
-
const next = await withinDeadline(mod, deadline, 'the status line', () => text(usage, mod))
|
|
25
|
-
if (next === shown) return
|
|
26
|
-
shown = next
|
|
27
|
-
claude.ui.status(next)
|
|
28
|
-
} catch (error) {
|
|
29
|
-
mod.log(`the status line kept its last text: ${messageOf(error)}`)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const refresh = () => {
|
|
33
|
-
queue = queue.then(update)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
announce('a status line')
|
|
37
|
-
router.add('session.measure', (e, next) => {
|
|
38
|
-
refresh()
|
|
39
|
-
return next(e)
|
|
40
|
-
})
|
|
41
|
-
onStateChange(mod.state, refresh)
|
|
42
|
-
refresh()
|
|
43
|
-
}
|
|
44
|
-
}
|
package/src/ui/define-pane.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { Frozen, PaneCloseInput, RenderElement, RenderPropsOf, UiScrollInput } from 'claude-code'
|
|
2
|
-
import type { Mod } from '../mod.js'
|
|
3
|
-
|
|
4
|
-
export type Pane<State extends object = Record<never, never>> = {
|
|
5
|
-
readonly id: string
|
|
6
|
-
readonly title: string
|
|
7
|
-
readonly columns?: number | ((state: State) => number | undefined)
|
|
8
|
-
readonly rows?: number | ((state: State) => number | undefined)
|
|
9
|
-
readonly closeOnEscape?: true
|
|
10
|
-
readonly holdToasts?: true
|
|
11
|
-
render(mod: Mod<State>, props: Frozen<RenderPropsOf['Pane']>): RenderElement
|
|
12
|
-
onScroll?(mod: Mod<State>, e: Frozen<UiScrollInput>): void | Promise<void>
|
|
13
|
-
onClose?(mod: Mod<State>, e: Frozen<PaneCloseInput>): void | Promise<void>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const paneId = /^[A-Za-z0-9_-]{1,64}$/
|
|
17
|
-
|
|
18
|
-
const sizeKeys = ['columns', 'rows'] as const
|
|
19
|
-
|
|
20
|
-
export function definePane<State extends object = Record<never, never>>(pane: Pane<State>): Pane<State> {
|
|
21
|
-
if (!paneId.test(pane.id)) throw new Error(`definePane: "${pane.id}" is not a pane id. Use 1 to 64 letters, digits, "_", or "-".`)
|
|
22
|
-
for (const key of sizeKeys) {
|
|
23
|
-
const size = pane[key]
|
|
24
|
-
if (typeof size !== 'function' && size !== undefined && (!Number.isInteger(size) || size <= 0)) throw new Error(`definePane: the pane "${pane.id}" has ${key} ${size}. Use a whole number above 0, or leave it out.`)
|
|
25
|
-
}
|
|
26
|
-
return pane
|
|
27
|
-
}
|
package/src/ui/places.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { Frozen, RenderComponent, RenderElement, RenderPropsOf } from 'claude-code'
|
|
2
|
-
import type { BlockProps, MarkdownPlace } from './markdown.js'
|
|
3
|
-
|
|
4
|
-
export const ToolGroup = 'toolGroup'
|
|
5
|
-
export const ToolProgress = 'toolProgress'
|
|
6
|
-
export const CommandOutput = 'commandOutput'
|
|
7
|
-
export const AskUserQuestion = 'askUserQuestion'
|
|
8
|
-
export const Spinner = 'spinner'
|
|
9
|
-
export const TurnDuration = 'turnDuration'
|
|
10
|
-
export const SessionMode = 'sessionMode'
|
|
11
|
-
export const PromptHint = 'promptHint'
|
|
12
|
-
export const AbovePrompt = 'abovePrompt'
|
|
13
|
-
|
|
14
|
-
const components = {
|
|
15
|
-
prompt: 'UserMessage',
|
|
16
|
-
reply: 'AssistantMessage',
|
|
17
|
-
toolCall: 'ToolUse',
|
|
18
|
-
toolResult: 'ToolResult',
|
|
19
|
-
notice: 'InfoNotice',
|
|
20
|
-
[ToolGroup]: 'ToolGroup',
|
|
21
|
-
[ToolProgress]: 'ToolProgress',
|
|
22
|
-
[CommandOutput]: 'CommandOutput',
|
|
23
|
-
[AskUserQuestion]: 'AskUserQuestion',
|
|
24
|
-
[Spinner]: 'Spinner',
|
|
25
|
-
[TurnDuration]: 'TurnDuration',
|
|
26
|
-
[SessionMode]: 'SessionMode',
|
|
27
|
-
[PromptHint]: 'PromptHint',
|
|
28
|
-
[AbovePrompt]: 'AbovePrompt',
|
|
29
|
-
} as const satisfies Readonly<Record<string, Exclude<RenderComponent, 'Pane'>>>
|
|
30
|
-
|
|
31
|
-
export type ComponentPlace = keyof typeof components
|
|
32
|
-
|
|
33
|
-
export type Place = ComponentPlace | MarkdownPlace
|
|
34
|
-
|
|
35
|
-
type ComponentProps = { readonly [P in ComponentPlace]: RenderPropsOf[(typeof components)[P]] }
|
|
36
|
-
|
|
37
|
-
type PropsOf<P extends Place> = P extends ComponentPlace ? ComponentProps[P] : P extends MarkdownPlace<infer Type> ? BlockProps<Type> : never
|
|
38
|
-
|
|
39
|
-
type DefaultOf<P extends Place> = P extends ComponentPlace ? Partial<Omit<ComponentProps[P], 'onScreen'>> : { readonly source?: string }
|
|
40
|
-
|
|
41
|
-
export type PlaceProps<P extends Place> = Frozen<PropsOf<P>> & { readonly Default: (props: Frozen<DefaultOf<P>>) => RenderElement }
|
|
42
|
-
|
|
43
|
-
export function componentOf(place: Place): Exclude<RenderComponent, 'Pane'> | undefined {
|
|
44
|
-
return typeof place === 'string' && Object.hasOwn(components, place) ? components[place] : undefined
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function nameOf(place: Place): string {
|
|
48
|
-
return typeof place === 'string' ? `${place.charAt(0).toUpperCase()}${place.slice(1)}` : place.name
|
|
49
|
-
}
|
package/src/utils/disposable.ts
DELETED
package/ui/define-pane.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Frozen, PaneCloseInput, RenderElement, RenderPropsOf, UiScrollInput } from 'claude-code';
|
|
2
|
-
import type { Mod } from '../mod.js';
|
|
3
|
-
export type Pane<State extends object = Record<never, never>> = {
|
|
4
|
-
readonly id: string;
|
|
5
|
-
readonly title: string;
|
|
6
|
-
readonly columns?: number | ((state: State) => number | undefined);
|
|
7
|
-
readonly rows?: number | ((state: State) => number | undefined);
|
|
8
|
-
readonly closeOnEscape?: true;
|
|
9
|
-
readonly holdToasts?: true;
|
|
10
|
-
render(mod: Mod<State>, props: Frozen<RenderPropsOf['Pane']>): RenderElement;
|
|
11
|
-
onScroll?(mod: Mod<State>, e: Frozen<UiScrollInput>): void | Promise<void>;
|
|
12
|
-
onClose?(mod: Mod<State>, e: Frozen<PaneCloseInput>): void | Promise<void>;
|
|
13
|
-
};
|
|
14
|
-
export declare function definePane<State extends object = Record<never, never>>(pane: Pane<State>): Pane<State>;
|
|
15
|
-
//# sourceMappingURL=define-pane.d.ts.map
|
package/ui/define-pane.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"define-pane.d.ts","sourceRoot":"","sources":["../src/ui/define-pane.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACtG,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAEpC,MAAM,MAAM,IAAI,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;IAC9D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,GAAG,SAAS,CAAC,CAAA;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,GAAG,SAAS,CAAC,CAAA;IAC/D,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAA;IAC1B,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,aAAa,CAAA;IAC5E,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1E,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3E,CAAA;AAMD,wBAAgB,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAOtG"}
|
package/ui/define-pane.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const paneId = /^[A-Za-z0-9_-]{1,64}$/;
|
|
2
|
-
const sizeKeys = ['columns', 'rows'];
|
|
3
|
-
export function definePane(pane) {
|
|
4
|
-
if (!paneId.test(pane.id))
|
|
5
|
-
throw new Error(`definePane: "${pane.id}" is not a pane id. Use 1 to 64 letters, digits, "_", or "-".`);
|
|
6
|
-
for (const key of sizeKeys) {
|
|
7
|
-
const size = pane[key];
|
|
8
|
-
if (typeof size !== 'function' && size !== undefined && (!Number.isInteger(size) || size <= 0))
|
|
9
|
-
throw new Error(`definePane: the pane "${pane.id}" has ${key} ${size}. Use a whole number above 0, or leave it out.`);
|
|
10
|
-
}
|
|
11
|
-
return pane;
|
|
12
|
-
}
|
package/ui/places.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { Frozen, RenderComponent, RenderElement, RenderPropsOf } from 'claude-code';
|
|
2
|
-
import type { BlockProps, MarkdownPlace } from './markdown.js';
|
|
3
|
-
export declare const ToolGroup = "toolGroup";
|
|
4
|
-
export declare const ToolProgress = "toolProgress";
|
|
5
|
-
export declare const CommandOutput = "commandOutput";
|
|
6
|
-
export declare const AskUserQuestion = "askUserQuestion";
|
|
7
|
-
export declare const Spinner = "spinner";
|
|
8
|
-
export declare const TurnDuration = "turnDuration";
|
|
9
|
-
export declare const SessionMode = "sessionMode";
|
|
10
|
-
export declare const PromptHint = "promptHint";
|
|
11
|
-
export declare const AbovePrompt = "abovePrompt";
|
|
12
|
-
declare const components: {
|
|
13
|
-
readonly prompt: 'UserMessage';
|
|
14
|
-
readonly reply: 'AssistantMessage';
|
|
15
|
-
readonly toolCall: 'ToolUse';
|
|
16
|
-
readonly toolResult: 'ToolResult';
|
|
17
|
-
readonly notice: 'InfoNotice';
|
|
18
|
-
readonly toolGroup: 'ToolGroup';
|
|
19
|
-
readonly toolProgress: 'ToolProgress';
|
|
20
|
-
readonly commandOutput: 'CommandOutput';
|
|
21
|
-
readonly askUserQuestion: 'AskUserQuestion';
|
|
22
|
-
readonly spinner: 'Spinner';
|
|
23
|
-
readonly turnDuration: 'TurnDuration';
|
|
24
|
-
readonly sessionMode: 'SessionMode';
|
|
25
|
-
readonly promptHint: 'PromptHint';
|
|
26
|
-
readonly abovePrompt: 'AbovePrompt';
|
|
27
|
-
};
|
|
28
|
-
export type ComponentPlace = keyof typeof components;
|
|
29
|
-
export type Place = ComponentPlace | MarkdownPlace;
|
|
30
|
-
type ComponentProps = {
|
|
31
|
-
readonly [P in ComponentPlace]: RenderPropsOf[(typeof components)[P]];
|
|
32
|
-
};
|
|
33
|
-
type PropsOf<P extends Place> = P extends ComponentPlace ? ComponentProps[P] : P extends MarkdownPlace<infer Type> ? BlockProps<Type> : never;
|
|
34
|
-
type DefaultOf<P extends Place> = P extends ComponentPlace ? Partial<Omit<ComponentProps[P], 'onScreen'>> : {
|
|
35
|
-
readonly source?: string;
|
|
36
|
-
};
|
|
37
|
-
export type PlaceProps<P extends Place> = Frozen<PropsOf<P>> & {
|
|
38
|
-
readonly Default: (props: Frozen<DefaultOf<P>>) => RenderElement;
|
|
39
|
-
};
|
|
40
|
-
export declare function componentOf(place: Place): Exclude<RenderComponent, 'Pane'> | undefined;
|
|
41
|
-
export declare function nameOf(place: Place): string;
|
|
42
|
-
export {};
|
|
43
|
-
//# sourceMappingURL=places.d.ts.map
|
package/ui/places.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"places.d.ts","sourceRoot":"","sources":["../src/ui/places.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE9D,eAAO,MAAM,SAAS,cAAc,CAAA;AACpC,eAAO,MAAM,YAAY,iBAAiB,CAAA;AAC1C,eAAO,MAAM,aAAa,kBAAkB,CAAA;AAC5C,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAChD,eAAO,MAAM,OAAO,YAAY,CAAA;AAChC,eAAO,MAAM,YAAY,iBAAiB,CAAA;AAC1C,eAAO,MAAM,WAAW,gBAAgB,CAAA;AACxC,eAAO,MAAM,UAAU,eAAe,CAAA;AACtC,eAAO,MAAM,WAAW,gBAAgB,CAAA;AAExC,QAAA,MAAM,UAAU;qBACN,aAAa;oBACd,kBAAkB;uBACf,SAAS;yBACP,YAAY;qBAChB,YAAY;wBACP,WAAW;2BACR,cAAc;4BACb,eAAe;8BACb,iBAAiB;sBACzB,SAAS;2BACJ,cAAc;0BACf,aAAa;yBACd,YAAY;0BACX,aAAa;CACiD,CAAA;AAE/E,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,UAAU,CAAA;AAEpD,MAAM,MAAM,KAAK,GAAG,cAAc,GAAG,aAAa,CAAA;AAElD,KAAK,cAAc,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,cAAc,GAAG,aAAa,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAE/F,KAAK,OAAO,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,aAAa,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;AAE7I,KAAK,SAAS,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAExI,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAA;CAAE,CAAA;AAEnI,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,SAAS,CAEtF;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAE3C"}
|
package/ui/places.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export const ToolGroup = 'toolGroup';
|
|
2
|
-
export const ToolProgress = 'toolProgress';
|
|
3
|
-
export const CommandOutput = 'commandOutput';
|
|
4
|
-
export const AskUserQuestion = 'askUserQuestion';
|
|
5
|
-
export const Spinner = 'spinner';
|
|
6
|
-
export const TurnDuration = 'turnDuration';
|
|
7
|
-
export const SessionMode = 'sessionMode';
|
|
8
|
-
export const PromptHint = 'promptHint';
|
|
9
|
-
export const AbovePrompt = 'abovePrompt';
|
|
10
|
-
const components = {
|
|
11
|
-
prompt: 'UserMessage',
|
|
12
|
-
reply: 'AssistantMessage',
|
|
13
|
-
toolCall: 'ToolUse',
|
|
14
|
-
toolResult: 'ToolResult',
|
|
15
|
-
notice: 'InfoNotice',
|
|
16
|
-
[ToolGroup]: 'ToolGroup',
|
|
17
|
-
[ToolProgress]: 'ToolProgress',
|
|
18
|
-
[CommandOutput]: 'CommandOutput',
|
|
19
|
-
[AskUserQuestion]: 'AskUserQuestion',
|
|
20
|
-
[Spinner]: 'Spinner',
|
|
21
|
-
[TurnDuration]: 'TurnDuration',
|
|
22
|
-
[SessionMode]: 'SessionMode',
|
|
23
|
-
[PromptHint]: 'PromptHint',
|
|
24
|
-
[AbovePrompt]: 'AbovePrompt',
|
|
25
|
-
};
|
|
26
|
-
export function componentOf(place) {
|
|
27
|
-
return typeof place === 'string' && Object.hasOwn(components, place) ? components[place] : undefined;
|
|
28
|
-
}
|
|
29
|
-
export function nameOf(place) {
|
|
30
|
-
return typeof place === 'string' ? `${place.charAt(0).toUpperCase()}${place.slice(1)}` : place.name;
|
|
31
|
-
}
|
package/utils/disposable.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"disposable.d.ts","sourceRoot":"","sources":["../src/utils/disposable.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,IAAI,IAAI,CAAA;CAChB,CAAA"}
|