@nyte-ai/plugin 0.0.24 → 0.0.25-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,22 +4,33 @@ import {
4
4
 
5
5
  // src/canvas/schema.ts
6
6
  import { definePart } from "@nyte-ai/core";
7
- import { standard } from "@nyte-ai/schema";
7
+ import { idSchema, standard } from "@nyte-ai/schema";
8
8
  import { Type } from "typebox";
9
- var state = standard(Type.Object({
9
+ var CANVAS_RENDER_TOOL2 = "canvas_render";
10
+ var CANVAS_REVISIONS_KEPT2 = 50;
11
+ var drawn = {
10
12
  runtime: Type.Integer({ minimum: 1 }),
11
13
  title: Type.String({ minLength: 1, maxLength: 120 }),
14
+ height: Type.Union([Type.Number(), Type.Null()])
15
+ };
16
+ var revision = Type.Object({
17
+ number: Type.Integer({ minimum: 1 }),
18
+ blob: idSchema(),
19
+ ...drawn,
20
+ at: Type.Number()
21
+ });
22
+ var state = standard(Type.Object({
23
+ ...drawn,
12
24
  code: Type.String({ maxLength: CANVAS_CODE_LIMIT2 }),
13
- height: Type.Union([Type.Number(), Type.Null()]),
14
- error: Type.Union([Type.String(), Type.Null()])
25
+ error: Type.Union([Type.String(), Type.Null()]),
26
+ revisions: Type.Optional(Type.Array(revision, { maxItems: CANVAS_REVISIONS_KEPT2 }))
15
27
  }));
16
28
  var actions = {
17
29
  replace: {
18
30
  input: standard(Type.Object({
19
- runtime: Type.Integer({ minimum: 1 }),
20
- title: Type.String({ minLength: 1, maxLength: 120 }),
31
+ ...drawn,
21
32
  code: Type.String({ maxLength: CANVAS_CODE_LIMIT2 }),
22
- height: Type.Union([Type.Number(), Type.Null()])
33
+ blob: idSchema()
23
34
  }))
24
35
  },
25
36
  report: {
@@ -33,4 +44,4 @@ var canvas2 = definePart({
33
44
  fallback: (current, { id }) => `Canvas ${id}: ${current.title}.${current.error === null ? "" : ` It failed to render: ${current.error}. Fix it by calling canvas_render with canvas "${id}".`}`
34
45
  });
35
46
 
36
- export { canvas2 };
47
+ export { CANVAS_RENDER_TOOL2, CANVAS_REVISIONS_KEPT2, canvas2 };
@@ -15,7 +15,7 @@ import { processEnvironment } from "@nyte-ai/core";
15
15
  // package.json
16
16
  var package_default = {
17
17
  name: "@nyte-ai/plugin",
18
- version: "0.0.24",
18
+ version: "0.0.25-beta.1",
19
19
  private: false,
20
20
  license: "MIT",
21
21
  repository: {
@@ -190,7 +190,7 @@ var package_default = {
190
190
  scripts: {
191
191
  clean: "rm -rf node_modules .turbo",
192
192
  test: "vitest --run",
193
- typecheck: "tsrs --noEmit",
193
+ typecheck: "tsc --noEmit",
194
194
  "build:package": "bun ../../scripts/sdk-packages.mjs build plugin"
195
195
  },
196
196
  dependencies: {
@@ -215,7 +215,6 @@ var package_default = {
215
215
  "@types/node": "^26.6.5",
216
216
  "@types/react": "^19.3.0",
217
217
  react: "^19.3.1",
218
- typescript: "6.0.3",
219
218
  vitest: "^5.0.5"
220
219
  },
221
220
  peerDependencies: {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AcpProcess2
3
- } from "../../chunks/bash-description-necnb2k7.js";
3
+ } from "../../chunks/bash-description-eqp7ap2w.js";
4
4
  import"../../chunks/bash-description-svrhh5a5.js";
5
5
  import"../../chunks/bash-description-9nn3yp18.js";
6
6
  export {
@@ -25,11 +25,11 @@ export declare function acpAgents(options?: {
25
25
  id: string;
26
26
  contribute: {
27
27
  tools: ToolDefinition<{
28
+ thread: string;
28
29
  id: string;
29
- kind: string;
30
30
  title: string;
31
+ kind: string;
31
32
  input: Record<string, unknown>;
32
- thread: string;
33
33
  paths: string[];
34
34
  }, unknown>[];
35
35
  };
@@ -39,7 +39,7 @@ export declare function acpAgents(options?: {
39
39
  readonly contribute: import("@nyte-ai/core").Registries<"core">;
40
40
  readonly storage: import("@nyte-ai/core").PluginStorage;
41
41
  readonly signal: AbortSignal;
42
- hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
42
+ hook<N extends import("@nyte-ai/core").HookName<"core">>(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
43
43
  report(issue: import("@nyte-ai/schema").ValidationIssue): void;
44
44
  reload(): void;
45
45
  } & {
@@ -8,7 +8,7 @@ import {
8
8
  import"../../chunks/bash-description-svrhh5a5.js";
9
9
  import {
10
10
  AcpProcess2
11
- } from "../../chunks/bash-description-necnb2k7.js";
11
+ } from "../../chunks/bash-description-eqp7ap2w.js";
12
12
  import"../../chunks/bash-description-4vz9pxyx.js";
13
13
  import {
14
14
  registryEntries2,
@@ -32,6 +32,7 @@ export declare function approvalReason(policy: ApprovalPolicy, tool: ApprovalToo
32
32
  * @since 0.1.0
33
33
  */
34
34
  export declare const approval: import("@nyte-ai/core").PartDefinition<{
35
+ tool: string;
35
36
  class: {
36
37
  kind: "read";
37
38
  path: string;
@@ -42,21 +43,20 @@ export declare const approval: import("@nyte-ai/core").PartDefinition<{
42
43
  kind: "edit";
43
44
  path: string;
44
45
  } | {
45
- description?: string | undefined;
46
46
  kind: "shell";
47
47
  command: string;
48
+ description?: string | undefined;
48
49
  } | {
49
50
  kind: "delegate";
50
- title: string | null;
51
- role: "read" | "task" | "create" | "send" | "await" | "stop";
52
51
  child: import("@nyte-ai/schema").Id<"session"> | null;
52
+ role: "await" | "create" | "read" | "send" | "stop" | "task";
53
+ title: string | null;
53
54
  } | {
54
55
  kind: "custom";
55
56
  label: string;
56
57
  };
57
- reason: "edit" | "shell" | "tool" | "outside";
58
- tool: string;
59
- decision: "session" | "once" | "deny" | null;
58
+ reason: "edit" | "outside" | "shell" | "tool";
59
+ decision: "deny" | "once" | "session" | null;
60
60
  }, {
61
61
  once: {
62
62
  input: import("@nyte-ai/schema").Schema<object>;
@@ -89,6 +89,7 @@ declare const _default: {
89
89
  id: string;
90
90
  contribute: {
91
91
  parts: import("@nyte-ai/core").PartDefinition<{
92
+ tool: string;
92
93
  class: {
93
94
  kind: "read";
94
95
  path: string;
@@ -99,21 +100,20 @@ declare const _default: {
99
100
  kind: "edit";
100
101
  path: string;
101
102
  } | {
102
- description?: string | undefined;
103
103
  kind: "shell";
104
104
  command: string;
105
+ description?: string | undefined;
105
106
  } | {
106
107
  kind: "delegate";
107
- title: string | null;
108
- role: "read" | "task" | "create" | "send" | "await" | "stop";
109
108
  child: import("@nyte-ai/schema").Id<"session"> | null;
109
+ role: "await" | "create" | "read" | "send" | "stop" | "task";
110
+ title: string | null;
110
111
  } | {
111
112
  kind: "custom";
112
113
  label: string;
113
114
  };
114
- reason: "edit" | "shell" | "tool" | "outside";
115
- tool: string;
116
- decision: "session" | "once" | "deny" | null;
115
+ reason: "edit" | "outside" | "shell" | "tool";
116
+ decision: "deny" | "once" | "session" | null;
117
117
  }, {
118
118
  once: {
119
119
  input: import("@nyte-ai/schema").Schema<object>;
@@ -143,14 +143,14 @@ declare const _default: {
143
143
  readonly kind: "edit";
144
144
  readonly path: string;
145
145
  } | {
146
- readonly description?: string | undefined;
147
146
  readonly kind: "shell";
148
147
  readonly command: string;
148
+ readonly description?: string | undefined;
149
149
  } | {
150
150
  readonly kind: "delegate";
151
- readonly title: string | null;
152
- readonly role: "read" | "task" | "create" | "send" | "await" | "stop";
153
151
  readonly child: import("@nyte-ai/schema").Id<"session"> | null;
152
+ readonly role: "await" | "create" | "read" | "send" | "stop" | "task";
153
+ readonly title: string | null;
154
154
  } | {
155
155
  readonly kind: "custom";
156
156
  readonly label: string;
@@ -162,7 +162,7 @@ declare const _default: {
162
162
  readonly contribute: import("@nyte-ai/core").Registries<"core">;
163
163
  readonly storage: import("@nyte-ai/core").PluginStorage;
164
164
  readonly signal: AbortSignal;
165
- hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
165
+ hook<N extends import("@nyte-ai/core").HookName<"core">>(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
166
166
  report(issue: import("@nyte-ai/schema").ValidationIssue): void;
167
167
  reload(): void;
168
168
  } & {
@@ -25,6 +25,7 @@ export declare const APPROVAL_POLICIES: readonly [{
25
25
  readonly description: "Runs every tool without asking";
26
26
  }];
27
27
  declare const state: import("@nyte-ai/schema").Schema<{
28
+ tool: string;
28
29
  class: {
29
30
  kind: "read";
30
31
  path: string;
@@ -35,21 +36,20 @@ declare const state: import("@nyte-ai/schema").Schema<{
35
36
  kind: "edit";
36
37
  path: string;
37
38
  } | {
38
- description?: string | undefined;
39
39
  kind: "shell";
40
40
  command: string;
41
+ description?: string | undefined;
41
42
  } | {
42
43
  kind: "delegate";
43
- title: string | null;
44
- role: "read" | "task" | "create" | "send" | "await" | "stop";
45
44
  child: import("@nyte-ai/schema").Id<"session"> | null;
45
+ role: "await" | "create" | "read" | "send" | "stop" | "task";
46
+ title: string | null;
46
47
  } | {
47
48
  kind: "custom";
48
49
  label: string;
49
50
  };
50
- reason: "edit" | "shell" | "tool" | "outside";
51
- tool: string;
52
- decision: "session" | "once" | "deny" | null;
51
+ reason: "edit" | "outside" | "shell" | "tool";
52
+ decision: "deny" | "once" | "session" | null;
53
53
  }>;
54
54
  /**
55
55
  * One gated tool call: its tool, its class, why it asks (`shell`, `edit` in
@@ -87,6 +87,7 @@ export declare function approvalPrompt(current: Pick<ApprovalState, "tool" | "cl
87
87
  export declare const approval: {
88
88
  kind: string;
89
89
  state: import("@nyte-ai/schema").Schema<{
90
+ tool: string;
90
91
  class: {
91
92
  kind: "read";
92
93
  path: string;
@@ -97,21 +98,20 @@ export declare const approval: {
97
98
  kind: "edit";
98
99
  path: string;
99
100
  } | {
100
- description?: string | undefined;
101
101
  kind: "shell";
102
102
  command: string;
103
+ description?: string | undefined;
103
104
  } | {
104
105
  kind: "delegate";
105
- title: string | null;
106
- role: "read" | "task" | "create" | "send" | "await" | "stop";
107
106
  child: import("@nyte-ai/schema").Id<"session"> | null;
107
+ role: "await" | "create" | "read" | "send" | "stop" | "task";
108
+ title: string | null;
108
109
  } | {
109
110
  kind: "custom";
110
111
  label: string;
111
112
  };
112
- reason: "edit" | "shell" | "tool" | "outside";
113
- tool: string;
114
- decision: "session" | "once" | "deny" | null;
113
+ reason: "edit" | "outside" | "shell" | "tool";
114
+ decision: "deny" | "once" | "session" | null;
115
115
  }>;
116
116
  actions: {
117
117
  once: {
@@ -125,6 +125,7 @@ export declare const approval: {
125
125
  };
126
126
  };
127
127
  fallback: (current: {
128
+ tool: string;
128
129
  class: {
129
130
  kind: "read";
130
131
  path: string;
@@ -135,21 +136,20 @@ export declare const approval: {
135
136
  kind: "edit";
136
137
  path: string;
137
138
  } | {
138
- description?: string | undefined;
139
139
  kind: "shell";
140
140
  command: string;
141
+ description?: string | undefined;
141
142
  } | {
142
143
  kind: "delegate";
143
- title: string | null;
144
- role: "read" | "task" | "create" | "send" | "await" | "stop";
145
144
  child: import("@nyte-ai/schema").Id<"session"> | null;
145
+ role: "await" | "create" | "read" | "send" | "stop" | "task";
146
+ title: string | null;
146
147
  } | {
147
148
  kind: "custom";
148
149
  label: string;
149
150
  };
150
- reason: "edit" | "shell" | "tool" | "outside";
151
- tool: string;
152
- decision: "session" | "once" | "deny" | null;
151
+ reason: "edit" | "outside" | "shell" | "tool";
152
+ decision: "deny" | "once" | "session" | null;
153
153
  }, { id }: {
154
154
  readonly id: PartId;
155
155
  }) => string;
@@ -15,7 +15,7 @@ declare const _default: {
15
15
  readonly contribute: import("@nyte-ai/core").Registries<"core">;
16
16
  readonly storage: import("@nyte-ai/core").PluginStorage;
17
17
  readonly signal: AbortSignal;
18
- hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
18
+ hook<N extends import("@nyte-ai/core").HookName<"core">>(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
19
19
  report(issue: import("@nyte-ai/schema").ValidationIssue): void;
20
20
  reload(): void;
21
21
  } & {
@@ -1,14 +1,12 @@
1
1
  // src/bash-description.ts
2
+ import { bashProperties } from "@nyte-ai/core";
2
3
  import { standard } from "@nyte-ai/schema";
3
4
  import { Type } from "typebox";
4
5
  var parameters = standard(Type.Object({
5
- command: Type.String({ description: "The shell command to run." }),
6
+ ...bashProperties,
6
7
  description: Type.String({
7
8
  description: "Clear, concise description of what this command does in 5-10 words, in active voice."
8
- }),
9
- background: Type.Optional(Type.Boolean({
10
- description: "Start the command and return a job id with its first output instead of waiting for it to exit. Use for servers, watchers, and other long-lived commands, without a trailing &. The command keeps running across turns, and you are told when it exits; read its output or stop it with the job tool. Do not use it to speed up ordinary commands."
11
- }))
9
+ })
12
10
  }));
13
11
  var bash_description_default = {
14
12
  id: "bash-description",
@@ -48,24 +48,24 @@ export declare const TINTS: readonly ["blue", "pink", "orange", "teal", "red", "
48
48
  * answers any other import of `nyte/canvas` with a positioned error.
49
49
  */
50
50
  export declare const KIT: {
51
- readonly Stack: "{ direction?: \"row\" | \"column\" = \"column\", gap?: 0 | 1 | 2 | 3 | 4 | 6 = 2 (×4 px), align?: \"start\" | \"center\" | \"end\" | \"stretch\", justify?: \"start\" | \"center\" | \"end\" | \"between\", wrap?: boolean, children }: flex layout";
52
- readonly Grid: "{ columns?: number | \"auto\" = \"auto\", minWidth?: number = 160 (px, with \"auto\"), gap?: 0 | 1 | 2 | 3 | 4 | 6 = 2, children }: equal columns";
51
+ readonly Stack: '{ direction?: "row" | "column" = "column", gap?: 0 | 1 | 2 | 3 | 4 | 6 = 2 (×4 px), align?: "start" | "center" | "end" | "stretch", justify?: "start" | "center" | "end" | "between", wrap?: boolean, children }: flex layout';
52
+ readonly Grid: '{ columns?: number | "auto" = "auto", minWidth?: number = 160 (px, with "auto"), gap?: 0 | 1 | 2 | 3 | 4 | 6 = 2, children }: equal columns';
53
53
  readonly Divider: "{}: a hairline";
54
54
  readonly Heading: "{ level?: 1 | 2 | 3 = 2, children }";
55
- readonly Text: "{ size?: \"xs\" | \"sm\" | \"base\" | \"lg\", tone?: \"primary\" | \"secondary\" | \"tertiary\", weight?: \"normal\" | \"medium\" | \"semibold\", mono?: boolean, truncate?: boolean, align?: \"start\" | \"center\" | \"end\", children }";
55
+ readonly Text: '{ size?: "xs" | "sm" | "base" | "lg", tone?: "primary" | "secondary" | "tertiary", weight?: "normal" | "medium" | "semibold", mono?: boolean, truncate?: boolean, align?: "start" | "center" | "end", children }';
56
56
  readonly Code: "{ block?: boolean, children: string }: monospace, inline or a block";
57
- readonly Stat: "{ label: string, value: ReactNode, detail?: ReactNode, tone?: \"neutral\" | \"success\" | \"warning\" | \"danger\" }: a labelled number";
58
- readonly Badge: "{ tone?: \"neutral\" | \"info\" | \"success\" | \"warning\" | \"danger\", children }";
59
- readonly Meter: "{ value: number, max?: number = 100, label?: string, tone?: \"primary\" | \"success\" | \"warning\" | \"danger\" = \"primary\" }: a thin filled bar with the value beside the label";
60
- readonly Table: "{ columns: { key: string, label: ReactNode, align?: \"start\" | \"end\", width?: number | string }[], rows: Record<string, ReactNode>[], caption?: string }: rows are keyed by column key; a cell can hold a Sparkline or a Badge";
61
- readonly Callout: "{ tone?: \"info\" | \"success\" | \"warning\" | \"danger\", title?: string, children }";
57
+ readonly Stat: '{ label: string, value: ReactNode, detail?: ReactNode, tone?: "neutral" | "success" | "warning" | "danger" }: a labelled number';
58
+ readonly Badge: '{ tone?: "neutral" | "info" | "success" | "warning" | "danger", children }';
59
+ readonly Meter: '{ value: number, max?: number = 100, label?: string, tone?: "primary" | "success" | "warning" | "danger" = "primary" }: a thin filled bar with the value beside the label';
60
+ readonly Table: '{ columns: { key: string, label: ReactNode, align?: "start" | "end", width?: number | string }[], rows: Record<string, ReactNode>[], caption?: string }: rows are keyed by column key; a cell can hold a Sparkline or a Badge';
61
+ readonly Callout: '{ tone?: "info" | "success" | "warning" | "danger", title?: string, children }';
62
62
  readonly Card: "{ title?: ReactNode, actions?: ReactNode, padding?: 0 | 2 | 3 | 4 = 4, children }: an elevated bordered surface";
63
63
  readonly StackedBars: "{ label: string, series: { key: string, label: string, tint: Tint }[], buckets: { key: string, label: string, values: number[] }[], format: (value: number) => string, height?: number = 88, ticks?: number = 5 }: compact stacked bars without axes, a readout on pointer or arrow keys; the numbers live in the copy around it. Preferred beside a Stat or a heading figure";
64
64
  readonly Sparkline: "{ values: number[], tint?: Tint, label?: string, width?: number = 72, height?: number = 20 }: a row's trend scaled to its own peak, for a Table cell beside the row's number";
65
- readonly LineChart: "{ series: { id: string, data: { x: number | string, y: number }[], tint?: Tint }[], height?: number = 240, xFormat?: (x) => string, yFormat?: (y) => string, curve?: \"linear\" | \"monotone\" | \"step\", area?: boolean, legend?: boolean }: a full chart with axes and a readout";
66
- readonly BarChart: "{ data: Record<string, number | string>[], keys: (string | { key: string, label?: string, tint?: Tint })[], indexBy: string, height?: number = 240, layout?: \"vertical\" | \"horizontal\", mode?: \"grouped\" | \"stacked\" = \"stacked\", valueFormat?: (value: number) => string, legend?: boolean }: a full chart with axes and a readout with the total";
65
+ readonly LineChart: '{ series: { id: string, data: { x: number | string, y: number }[], tint?: Tint }[], height?: number = 240, xFormat?: (x) => string, yFormat?: (y) => string, curve?: "linear" | "monotone" | "step", area?: boolean, legend?: boolean }: a full chart with axes and a readout';
66
+ readonly BarChart: '{ data: Record<string, number | string>[], keys: (string | { key: string, label?: string, tint?: Tint })[], indexBy: string, height?: number = 240, layout?: "vertical" | "horizontal", mode?: "grouped" | "stacked" = "stacked", valueFormat?: (value: number) => string, legend?: boolean }: a full chart with axes and a readout with the total';
67
67
  readonly PieChart: "{ data: { id: string, value: number, label?: string, tint?: Tint }[], height?: number = 240, donut?: boolean, valueFormat?: (value: number) => string, legend?: boolean }";
68
- readonly Button: "{ variant?: \"solid\" | \"outline\" | \"ghost\", pill?: boolean, size?: \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", tone?: \"neutral\" | \"primary\" | \"success\" | \"warning\" | \"danger\", loading?: boolean, disabled?: boolean, onClick, children }";
68
+ readonly Button: '{ variant?: "solid" | "outline" | "ghost", pill?: boolean, size?: "2xs" | "xs" | "sm" | "md" | "lg" | "xl", tone?: "neutral" | "primary" | "success" | "warning" | "danger", loading?: boolean, disabled?: boolean, onClick, children }';
69
69
  readonly Tabs: "Tabs.Root { value?, defaultValue?, onValueChange? } > Tabs.List { children: Tabs.Tab { value, children }[] } + Tabs.Panel { value, children }";
70
70
  readonly Select: "Select { value?, defaultValue?, onValueChange? } > SelectTrigger { children: <SelectValue /> } + SelectContent { children: SelectItem[] }";
71
71
  readonly SelectTrigger: "see Select";
@@ -83,7 +83,7 @@ export declare const KIT: {
83
83
  readonly Collapsible: "Collapsible.Root { open?, defaultOpen?, onOpenChange? } > Collapsible.Trigger { children } + Collapsible.Panel { children }";
84
84
  readonly Kbd: "{ keys: string[] }";
85
85
  readonly Spinner: "{}";
86
- readonly useColorScheme: "(): \"light\" | \"dark\"";
86
+ readonly useColorScheme: '(): "light" | "dark"';
87
87
  };
88
88
  /** Every name `nyte/canvas` exports, in `KIT` order. */
89
89
  export declare const KIT_EXPORTS: readonly string[];
@@ -1,18 +1,27 @@
1
1
  import type { CanvasPreviewer } from "./canvas-preview.ts";
2
2
  import type { Plugin } from "@nyte-ai/plugin/core";
3
3
  export declare const canvas: import("@nyte-ai/core").PartDefinition<{
4
- code: string;
5
4
  runtime: number;
6
5
  title: string;
7
- error: string | null;
8
6
  height: number | null;
7
+ code: string;
8
+ error: string | null;
9
+ revisions?: {
10
+ runtime: number;
11
+ title: string;
12
+ height: number | null;
13
+ number: number;
14
+ blob: import("@nyte-ai/schema").Id<"blob">;
15
+ at: number;
16
+ }[] | undefined;
9
17
  }, {
10
18
  replace: {
11
19
  input: import("@nyte-ai/schema").Schema<{
12
- code: string;
13
20
  runtime: number;
14
21
  title: string;
15
22
  height: number | null;
23
+ code: string;
24
+ blob: import("@nyte-ai/schema").Id<"blob">;
16
25
  }>;
17
26
  };
18
27
  report: {
@@ -18,8 +18,10 @@ import {
18
18
  describeCanvasPreview2
19
19
  } from "../../chunks/bash-description-yyd9jznf.js";
20
20
  import {
21
+ CANVAS_RENDER_TOOL2,
22
+ CANVAS_REVISIONS_KEPT2,
21
23
  canvas2
22
- } from "../../chunks/bash-description-qnwggxq3.js";
24
+ } from "../../chunks/bash-description-1neewp76.js";
23
25
 
24
26
  // src/canvas/canvas.ts
25
27
  import { definePart, followedTrace, traced } from "@nyte-ai/core";
@@ -27,7 +29,24 @@ import { asId, standard } from "@nyte-ai/schema";
27
29
  import { Type } from "typebox";
28
30
  var handlers = {
29
31
  async replace(input, context) {
30
- const outcome = await context.part.update(() => ({ ...input, error: null }));
32
+ const outcome = await context.part.update((current) => ({
33
+ runtime: input.runtime,
34
+ title: input.title,
35
+ code: input.code,
36
+ height: input.height,
37
+ error: null,
38
+ revisions: [
39
+ ...current.revisions ?? [],
40
+ {
41
+ number: (current.revisions?.at(-1)?.number ?? 1) + 1,
42
+ blob: input.blob,
43
+ runtime: input.runtime,
44
+ title: input.title,
45
+ height: input.height,
46
+ at: Date.now()
47
+ }
48
+ ].slice(-CANVAS_REVISIONS_KEPT2)
49
+ }));
31
50
  if (outcome.kind !== "updated")
32
51
  throw new Error(`The canvas could not be replaced: ${outcome.kind}.`);
33
52
  },
@@ -99,7 +118,7 @@ ${describeErrors(compiled.errors)}`);
99
118
  var PREVIEW_FIRST = "Before rendering, call `canvas_preview` with the same `source` and `files`: it shows you the canvas and its errors, console and height without the user seeing it. Fix what it shows, then render once.";
100
119
  function renderTool(previewing) {
101
120
  return {
102
- name: "canvas_render",
121
+ name: CANVAS_RENDER_TOOL2,
103
122
  description: previewing ? `${PREVIEW_FIRST}
104
123
 
105
124
  ${CANVAS_DESCRIPTION}` : CANVAS_DESCRIPTION,
@@ -113,15 +132,18 @@ ${CANVAS_DESCRIPTION}` : CANVAS_DESCRIPTION,
113
132
  replay: "safe",
114
133
  async execute(args, invocation) {
115
134
  const compiled = await compile(args, invocation);
116
- const next = {
117
- runtime: compiled.runtime,
118
- title: args.title,
119
- code: compiled.code,
120
- height: args.height ?? null
121
- };
135
+ const drawn = { runtime: compiled.runtime, title: args.title, height: args.height ?? null };
136
+ const blob = await invocation.env.files.upload(async function* () {
137
+ yield encoder.encode(compiled.code);
138
+ }());
122
139
  if (args.canvas === undefined) {
123
140
  const part = await invocation.session.parts.create(canvas, {
124
- state: { ...next, error: null },
141
+ state: {
142
+ ...drawn,
143
+ code: compiled.code,
144
+ error: null,
145
+ revisions: [{ number: 1, blob, ...drawn, at: Date.now() }]
146
+ },
125
147
  placement: { kind: "transcript", role: "answer" }
126
148
  });
127
149
  return {
@@ -129,7 +151,7 @@ ${CANVAS_DESCRIPTION}` : CANVAS_DESCRIPTION,
129
151
  parts: [part.id]
130
152
  };
131
153
  }
132
- const outcome = await invocation.session.part(asId(args.canvas)).act("replace", next);
154
+ const outcome = await invocation.session.part(asId(args.canvas)).act("replace", { ...drawn, code: compiled.code, blob });
133
155
  if (outcome.kind !== "ok")
134
156
  throw new Error(`Canvas ${args.canvas} was not replaced: ${outcome.kind}.`);
135
157
  return {
@@ -1,41 +1,81 @@
1
1
  import type { Infer } from "@nyte-ai/schema";
2
+ /**
3
+ * The tool that renders a canvas and replaces one in place.
4
+ *
5
+ * @category plugins
6
+ * @since 0.1.0
7
+ */
8
+ export declare const CANVAS_RENDER_TOOL = "canvas_render";
9
+ /**
10
+ * How many revisions a canvas lists; a replace past it drops the oldest.
11
+ *
12
+ * @category plugins
13
+ * @since 0.1.0
14
+ */
15
+ export declare const CANVAS_REVISIONS_KEPT = 50;
2
16
  declare const state: import("@nyte-ai/schema").Schema<{
3
- code: string;
4
17
  runtime: number;
5
18
  title: string;
6
- error: string | null;
7
19
  height: number | null;
20
+ code: string;
21
+ error: string | null;
22
+ revisions?: {
23
+ runtime: number;
24
+ title: string;
25
+ height: number | null;
26
+ number: number;
27
+ blob: import("@nyte-ai/schema").Id<"blob">;
28
+ at: number;
29
+ }[] | undefined;
8
30
  }>;
9
31
  /**
10
32
  * Returns a canvas part's state: the compiled module, the runtime it needs,
11
- * its title, the agent's height hint and the last error a client reported.
33
+ * its title, the agent's height hint, the last error a client reported, and
34
+ * its revisions, oldest first, the last one being the module itself.
12
35
  *
13
36
  * @category plugins
14
37
  * @since 0.1.0
15
38
  */
16
39
  export type CanvasState = Infer<typeof state>;
40
+ /**
41
+ * One revision of a canvas: its compiled module stored as a blob, with what
42
+ * drawing it needs besides the code.
43
+ *
44
+ * @category plugins
45
+ * @since 0.1.0
46
+ */
47
+ export type CanvasRevision = NonNullable<CanvasState["revisions"]>[number];
17
48
  /**
18
49
  * A canvas part: a React module the agent wrote, compiled on the host and
19
50
  * drawn by a client inside the sandboxed runtime shell. `replace` swaps the
20
- * module in place; `report` records a load or render error a client saw,
21
- * which the model reads in the fallback.
51
+ * module in place and lists it as the next revision; `report` records a load
52
+ * or render error a client saw, which the model reads in the fallback.
22
53
  *
23
54
  * @category plugins
24
55
  * @since 0.1.0
25
56
  */
26
57
  export declare const canvas: import("@nyte-ai/core").PartDefinition<{
27
- code: string;
28
58
  runtime: number;
29
59
  title: string;
30
- error: string | null;
31
60
  height: number | null;
61
+ code: string;
62
+ error: string | null;
63
+ revisions?: {
64
+ runtime: number;
65
+ title: string;
66
+ height: number | null;
67
+ number: number;
68
+ blob: import("@nyte-ai/schema").Id<"blob">;
69
+ at: number;
70
+ }[] | undefined;
32
71
  }, {
33
72
  replace: {
34
73
  input: import("@nyte-ai/schema").Schema<{
35
- code: string;
36
74
  runtime: number;
37
75
  title: string;
38
76
  height: number | null;
77
+ code: string;
78
+ blob: import("@nyte-ai/schema").Id<"blob">;
39
79
  }>;
40
80
  };
41
81
  report: {
@@ -1,8 +1,12 @@
1
1
  import {
2
+ CANVAS_RENDER_TOOL2,
3
+ CANVAS_REVISIONS_KEPT2,
2
4
  canvas2
3
- } from "../../chunks/bash-description-qnwggxq3.js";
5
+ } from "../../chunks/bash-description-1neewp76.js";
4
6
  import"../../chunks/bash-description-dnvgk30y.js";
5
7
  import"../../chunks/bash-description-zfpm2rt0.js";
6
8
  export {
9
+ CANVAS_RENDER_TOOL2 as CANVAS_RENDER_TOOL,
10
+ CANVAS_REVISIONS_KEPT2 as CANVAS_REVISIONS_KEPT,
7
11
  canvas2 as canvas
8
12
  };
@@ -20,7 +20,7 @@ export declare function claudeCodeSdk(start?: StartQuery): {
20
20
  readonly contribute: import("@nyte-ai/core").Registries<"core">;
21
21
  readonly storage: import("@nyte-ai/core").PluginStorage;
22
22
  readonly signal: AbortSignal;
23
- hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
23
+ hook<N extends import("@nyte-ai/core").HookName<"core">>(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
24
24
  report(issue: import("@nyte-ai/schema").ValidationIssue): void;
25
25
  reload(): void;
26
26
  } & {
@@ -22,7 +22,7 @@ declare const _default: {
22
22
  readonly contribute: import("@nyte-ai/core").Registries<"client">;
23
23
  readonly storage: import("@nyte-ai/core").PluginStorage;
24
24
  readonly signal: AbortSignal;
25
- hook<N extends "run_ended_anywhere" | "app_ready" | "session_opened" | "before_submit" | "session_closed" | "app_closing">(name: N, entry: import("@nyte-ai/core").HookEntry<"client", N>): import("@nyte-ai/schema").Disposer;
25
+ hook<N extends import("@nyte-ai/core").HookName<"client">>(name: N, entry: import("@nyte-ai/core").HookEntry<"client", N>): import("@nyte-ai/schema").Disposer;
26
26
  report(issue: import("@nyte-ai/schema").ValidationIssue): void;
27
27
  reload(): void;
28
28
  } & import("@nyte-ai/plugin/client").ClientApi;
@@ -1,6 +1,6 @@
1
1
  import { text, thinking } from "@nyte-ai/core";
2
2
  import type { PartState } from "@nyte-ai/core";
3
- import type { Execution, Failure, HeadInfo, Message, MessageSource, SessionInfo, ToolClass, ToolPartState, UserContent, UserStatus } from "@nyte-ai/schema";
3
+ import type { Execution, Failure, HeadInfo, Message, MessageSource, SessionInfo, ToolClass, ToolPartState, UserContent } from "@nyte-ai/schema";
4
4
  /**
5
5
  * A message the user sent, or one a child, job or action delivered for them.
6
6
  *
@@ -92,32 +92,6 @@ export declare function readRawPart(message: PartMessage): RawPart;
92
92
  * @category presentation
93
93
  */
94
94
  export declare function showsReport(message: UserMessage): message is ReportMessage;
95
- type PendingStatus = Extract<UserStatus, {
96
- readonly kind: "pending";
97
- }>;
98
- /**
99
- * A message that waits in the queue: unsent, or pending for a later turn. A pending steer sent
100
- * while idle or joining the live run is never one.
101
- *
102
- * @category presentation
103
- */
104
- export type QueuedMessage = UserMessage & {
105
- readonly status: Extract<UserStatus, {
106
- readonly kind: "unsent";
107
- }> | (PendingStatus & {
108
- readonly schedule: Exclude<PendingStatus["schedule"], {
109
- readonly kind: "joined";
110
- }>;
111
- });
112
- };
113
- /**
114
- * Whether a message waits in the queue rather than showing in the transcript. A retrying send
115
- * always waits. Reports, joined steers and steers sent while idle stay in the transcript.
116
- * Other messages wait only while a run is active.
117
- *
118
- * @category presentation
119
- */
120
- export declare function waitsInQueue(message: UserMessage, running: boolean): message is QueuedMessage;
121
95
  /**
122
96
  * What a user message shows: an action's label in place of the prompt it sent.
123
97
  *
@@ -21,23 +21,6 @@ function readRawPart(message) {
21
21
  function showsReport(message) {
22
22
  return message.source.kind === "child" || message.source.kind === "job";
23
23
  }
24
- function waitsInQueue(message, running) {
25
- const { status } = message;
26
- if (showsReport(message))
27
- return false;
28
- switch (status.kind) {
29
- case "landed":
30
- return false;
31
- case "unsent":
32
- return status.retrying !== null || running && message.delivery !== "steer";
33
- case "pending":
34
- return running && status.schedule.kind !== "joined" && !(message.delivery === "steer" && status.schedule.kind === "next-turn" && status.schedule.reason === "idle");
35
- default: {
36
- const _exhaustive = status;
37
- return _exhaustive;
38
- }
39
- }
40
- }
41
24
  function shownContent(message) {
42
25
  return message.source.kind === "action" ? message.source.label : message.content;
43
26
  }
@@ -386,6 +369,5 @@ export {
386
369
  toolStatus,
387
370
  toolSubject,
388
371
  toolTitle,
389
- toolVerbs,
390
- waitsInQueue
372
+ toolVerbs
391
373
  };
@@ -1,15 +1,15 @@
1
1
  import type { ToolDefinition } from "@nyte-ai/core";
2
2
  export declare const question: import("@nyte-ai/core").PartDefinition<{
3
- answers: string[][] | null;
4
3
  questions: {
5
- multiple?: boolean | undefined;
4
+ question: string;
5
+ header: string;
6
6
  options: {
7
- description: string;
8
7
  label: string;
8
+ description: string;
9
9
  }[];
10
- question: string;
11
- header: string;
10
+ multiple?: boolean | undefined;
12
11
  }[];
12
+ answers: string[][] | null;
13
13
  }, {
14
14
  answer: {
15
15
  input: import("@nyte-ai/schema").Schema<{
@@ -28,16 +28,16 @@ declare const _default: {
28
28
  id: string;
29
29
  contribute: {
30
30
  parts: import("@nyte-ai/core").PartDefinition<{
31
- answers: string[][] | null;
32
31
  questions: {
33
- multiple?: boolean | undefined;
32
+ question: string;
33
+ header: string;
34
34
  options: {
35
- description: string;
36
35
  label: string;
36
+ description: string;
37
37
  }[];
38
- question: string;
39
- header: string;
38
+ multiple?: boolean | undefined;
40
39
  }[];
40
+ answers: string[][] | null;
41
41
  }, {
42
42
  answer: {
43
43
  input: import("@nyte-ai/schema").Schema<{
@@ -47,13 +47,13 @@ declare const _default: {
47
47
  }>[];
48
48
  tools: ToolDefinition<{
49
49
  questions: {
50
- multiple?: boolean | undefined;
50
+ question: string;
51
+ header: string;
51
52
  options: {
52
- description: string;
53
53
  label: string;
54
+ description: string;
54
55
  }[];
55
- question: string;
56
- header: string;
56
+ multiple?: boolean | undefined;
57
57
  }[];
58
58
  }, {
59
59
  answers: string[][] | null;
@@ -1,12 +1,12 @@
1
1
  import type { Infer, PartId, SessionView } from "@nyte-ai/schema";
2
2
  declare const info: import("@nyte-ai/schema").Schema<{
3
- multiple?: boolean | undefined;
3
+ question: string;
4
+ header: string;
4
5
  options: {
5
- description: string;
6
6
  label: string;
7
+ description: string;
7
8
  }[];
8
- question: string;
9
- header: string;
9
+ multiple?: boolean | undefined;
10
10
  }>;
11
11
  export declare const answerInput: import("@nyte-ai/schema").Schema<{
12
12
  answers: string[][];
@@ -15,26 +15,26 @@ export declare const questionOutput: import("@nyte-ai/schema").Schema<{
15
15
  answers: string[][] | null;
16
16
  }>;
17
17
  declare const state: import("@nyte-ai/schema").Schema<{
18
- answers: string[][] | null;
19
18
  questions: {
20
- multiple?: boolean | undefined;
19
+ question: string;
20
+ header: string;
21
21
  options: {
22
- description: string;
23
22
  label: string;
23
+ description: string;
24
24
  }[];
25
- question: string;
26
- header: string;
25
+ multiple?: boolean | undefined;
27
26
  }[];
27
+ answers: string[][] | null;
28
28
  }>;
29
29
  export declare const questionParameters: import("@nyte-ai/schema").Schema<{
30
30
  questions: {
31
- multiple?: boolean | undefined;
31
+ question: string;
32
+ header: string;
32
33
  options: {
33
- description: string;
34
34
  label: string;
35
+ description: string;
35
36
  }[];
36
- question: string;
37
- header: string;
37
+ multiple?: boolean | undefined;
38
38
  }[];
39
39
  }>;
40
40
  /** A question, its described choices, and whether the user may select several. */
@@ -53,16 +53,16 @@ export type QuestionState = Infer<typeof state>;
53
53
  export declare const question: {
54
54
  kind: string;
55
55
  state: import("@nyte-ai/schema").Schema<{
56
- answers: string[][] | null;
57
56
  questions: {
58
- multiple?: boolean | undefined;
57
+ question: string;
58
+ header: string;
59
59
  options: {
60
- description: string;
61
60
  label: string;
61
+ description: string;
62
62
  }[];
63
- question: string;
64
- header: string;
63
+ multiple?: boolean | undefined;
65
64
  }[];
65
+ answers: string[][] | null;
66
66
  }>;
67
67
  actions: {
68
68
  answer: {
@@ -72,16 +72,16 @@ export declare const question: {
72
72
  };
73
73
  };
74
74
  fallback: (current: {
75
- answers: string[][] | null;
76
75
  questions: {
77
- multiple?: boolean | undefined;
76
+ question: string;
77
+ header: string;
78
78
  options: {
79
- description: string;
80
79
  label: string;
80
+ description: string;
81
81
  }[];
82
- question: string;
83
- header: string;
82
+ multiple?: boolean | undefined;
84
83
  }[];
84
+ answers: string[][] | null;
85
85
  }, { id }: {
86
86
  readonly id: PartId;
87
87
  }) => string;
@@ -27,26 +27,26 @@ declare const _default: {
27
27
  };
28
28
  hooks: {
29
29
  run_started: (run: Readonly<{
30
+ readonly id: import("@nyte-ai/schema").Id<"run">;
31
+ readonly head: import("@nyte-ai/schema").Id<"head">;
32
+ readonly startedAt: number;
33
+ readonly attempt: number;
30
34
  readonly configuration: {
35
+ readonly kind: "exact";
31
36
  readonly model: {
32
- readonly id: string;
33
37
  readonly provider: string;
38
+ readonly id: string;
34
39
  };
35
- readonly thinking: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
36
- readonly kind: "exact";
40
+ readonly thinking: "high" | "low" | "max" | "medium" | "minimal" | "off" | "xhigh";
41
+ readonly agent: string | null;
37
42
  readonly settings: {
38
43
  readonly [x: string]: import("@nyte-ai/schema").Json;
39
44
  };
40
- readonly agent: string | null;
41
45
  readonly settingsVersion: string;
42
46
  };
43
- readonly id: import("@nyte-ai/schema").Id<"run">;
44
- readonly head: import("@nyte-ai/schema").Id<"head">;
45
- readonly startedAt: number;
46
- readonly attempt: number;
47
47
  readonly origin: {
48
- readonly message: import("@nyte-ai/schema").Id<"message">;
49
48
  readonly kind: "input";
49
+ readonly message: import("@nyte-ai/schema").Id<"message">;
50
50
  } | {
51
51
  readonly kind: "continuation";
52
52
  readonly from: "child" | "job" | "wake";
@@ -58,7 +58,7 @@ declare const _default: {
58
58
  readonly contribute: import("@nyte-ai/core").Registries<"core">;
59
59
  readonly storage: import("@nyte-ai/core").PluginStorage;
60
60
  readonly signal: AbortSignal;
61
- hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
61
+ hook<N extends import("@nyte-ai/core").HookName<"core">>(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
62
62
  report(issue: import("@nyte-ai/schema").ValidationIssue): void;
63
63
  reload(): void;
64
64
  } & {
@@ -21,7 +21,7 @@ declare const _default: {
21
21
  readonly contribute: import("@nyte-ai/core").Registries<"core">;
22
22
  readonly storage: import("@nyte-ai/core").PluginStorage;
23
23
  readonly signal: AbortSignal;
24
- hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
24
+ hook<N extends import("@nyte-ai/core").HookName<"core">>(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
25
25
  report(issue: import("@nyte-ai/schema").ValidationIssue): void;
26
26
  reload(): void;
27
27
  } & {
@@ -54,7 +54,7 @@ export declare const adapters: {
54
54
  declare const _default: {
55
55
  id: string;
56
56
  contribute: {
57
- settings: SettingDefinition<"exa" | "tavily" | "firecrawl" | "parallel">[];
57
+ settings: SettingDefinition<"exa" | "firecrawl" | "parallel" | "tavily">[];
58
58
  commands: Command<keyof import("@nyte-ai/core").SideTable>[];
59
59
  };
60
60
  activate(api: {
@@ -63,7 +63,7 @@ declare const _default: {
63
63
  readonly contribute: import("@nyte-ai/core").Registries<"core">;
64
64
  readonly storage: import("@nyte-ai/core").PluginStorage;
65
65
  readonly signal: AbortSignal;
66
- hook<N extends "session_activated" | "before_send" | "run_started" | "transform_transcript" | "before_compaction" | "before_request" | "before_tool" | "after_tool" | "after_request" | "run_ended">(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
66
+ hook<N extends import("@nyte-ai/core").HookName<"core">>(name: N, entry: import("@nyte-ai/core").HookEntry<"core", N>): import("@nyte-ai/schema").Disposer;
67
67
  report(issue: import("@nyte-ai/schema").ValidationIssue): void;
68
68
  reload(): void;
69
69
  } & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nyte-ai/plugin",
3
- "version": "0.0.24",
3
+ "version": "0.0.25-beta.1",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -144,9 +144,9 @@
144
144
  "@agentclientprotocol/sdk": "^2.0.0",
145
145
  "@anthropic-ai/claude-agent-sdk": "^0.3.306",
146
146
  "@earendil-works/pi-codemode": "^1.3.0",
147
- "@nyte-ai/ai": "0.0.24",
148
- "@nyte-ai/core": "0.0.24",
149
- "@nyte-ai/schema": "0.0.24",
147
+ "@nyte-ai/ai": "0.0.25-beta.1",
148
+ "@nyte-ai/core": "0.0.25-beta.1",
149
+ "@nyte-ai/schema": "0.0.25-beta.1",
150
150
  "@opentelemetry/api": "^1.10.0",
151
151
  "@opentelemetry/exporter-trace-otlp-http": "^0.300.0",
152
152
  "@opentelemetry/resources": "^3.0.0",
@@ -162,7 +162,6 @@
162
162
  "@types/node": "^26.6.5",
163
163
  "@types/react": "^19.3.0",
164
164
  "react": "^19.3.1",
165
- "typescript": "6.0.3",
166
165
  "vitest": "^5.0.5"
167
166
  },
168
167
  "peerDependencies": {
@@ -183,7 +182,7 @@
183
182
  "scripts": {
184
183
  "clean": "rm -rf node_modules .turbo",
185
184
  "test": "vitest --run",
186
- "typecheck": "tsrs --noEmit",
185
+ "typecheck": "tsc --noEmit",
187
186
  "build:package": "bun ../../scripts/sdk-packages.mjs build plugin"
188
187
  }
189
188
  }