@intentic/extension-api 1.176.3 → 1.209.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.
Files changed (49) hide show
  1. package/README.md +63 -13
  2. package/dist/api.d.ts +48 -1
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/diff.d.ts +20 -0
  5. package/dist/diff.d.ts.map +1 -0
  6. package/dist/diff.js +2 -0
  7. package/dist/diff.js.map +1 -0
  8. package/dist/engines.d.ts +2 -0
  9. package/dist/engines.d.ts.map +1 -0
  10. package/dist/engines.js +26 -0
  11. package/dist/engines.js.map +1 -0
  12. package/dist/facts.d.ts +1 -0
  13. package/dist/facts.d.ts.map +1 -1
  14. package/dist/host.d.ts +6 -0
  15. package/dist/host.d.ts.map +1 -0
  16. package/dist/host.js +15 -0
  17. package/dist/host.js.map +1 -0
  18. package/dist/index.d.ts +4 -2
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +4 -2
  21. package/dist/index.js.map +1 -1
  22. package/dist/server.d.ts +21 -0
  23. package/dist/server.d.ts.map +1 -0
  24. package/dist/server.js +2 -0
  25. package/dist/server.js.map +1 -0
  26. package/dist/version.d.ts +1 -1
  27. package/dist/version.d.ts.map +1 -1
  28. package/dist/version.js +1 -1
  29. package/dist/version.js.map +1 -1
  30. package/package.json +5 -4
  31. package/src/api.ts +270 -5
  32. package/src/diff.ts +59 -0
  33. package/src/engines.ts +31 -0
  34. package/src/facts.ts +6 -0
  35. package/src/host.ts +29 -0
  36. package/src/index.ts +4 -2
  37. package/src/server.ts +65 -0
  38. package/src/surface.json +280 -0
  39. package/src/version.ts +33 -1
  40. package/dist/manifest.d.ts +0 -260
  41. package/dist/manifest.d.ts.map +0 -1
  42. package/dist/manifest.js +0 -136
  43. package/dist/manifest.js.map +0 -1
  44. package/dist/permissions.d.ts +0 -2
  45. package/dist/permissions.d.ts.map +0 -1
  46. package/dist/permissions.js +0 -21
  47. package/dist/permissions.js.map +0 -1
  48. package/src/manifest.ts +0 -275
  49. package/src/permissions.ts +0 -36
package/dist/manifest.js DELETED
@@ -1,136 +0,0 @@
1
- import { z } from "zod";
2
- export const ViewContributionSchema = z.object({
3
- id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
4
- label: z.string().min(1),
5
- surface: z.enum(["rail", "directory", "sandbox"]),
6
- badge: z.boolean().optional(),
7
- });
8
- export const FileContributionSchema = z.object({
9
- path: z
10
- .string()
11
- .min(1)
12
- .refine((value) => !value.startsWith("/") && !value.split("/").includes(".."), {
13
- message: "path must be workspace-root-relative and stay inside the workspace",
14
- }),
15
- invalidates: z.array(z.string().min(1)).min(1),
16
- });
17
- export const ViewerContributionSchema = z.object({
18
- id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
19
- extensions: z.array(z.string().regex(/^[a-z0-9]+$/)).min(1),
20
- fetch: z.enum(["text", "blob", "url"]),
21
- });
22
- export const DocumentContributionSchema = z.object({
23
- id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
24
- label: z.string().min(1),
25
- });
26
- export const CommandContributionSchema = z.object({
27
- command: z.string().regex(/^[a-z0-9][a-z0-9-]*(\.[a-z0-9][a-z0-9-]*)+$/),
28
- title: z.string().min(1),
29
- icon: z.string().optional(),
30
- keybinding: z.string().regex(/^\S+$/).optional(),
31
- });
32
- export const SettingContributionSchema = z.object({
33
- key: z.string().regex(/^[a-z0-9][a-zA-Z0-9-]*$/),
34
- type: z.enum(["boolean", "string", "number", "enum"]),
35
- title: z.string().min(1),
36
- description: z.string().optional(),
37
- default: z.union([z.string(), z.number(), z.boolean()]).optional(),
38
- enum: z.array(z.string()).optional(),
39
- secret: z.boolean().optional(),
40
- env: z
41
- .string()
42
- .regex(/^[A-Z][A-Z0-9_]*$/)
43
- .optional(),
44
- });
45
- export const ProcessContributionSchema = z.object({
46
- name: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
47
- command: z.string().min(1),
48
- cwd: z.string().optional(),
49
- port: z.literal("auto").optional(),
50
- preview: z.boolean().optional(),
51
- autoStart: z.boolean().optional(),
52
- });
53
- export const AgentContributionSchema = z.object({
54
- path: z.string().optional(),
55
- });
56
- export const ListenerContributionSchema = z.object({
57
- provider: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
58
- eventTypes: z.array(z.string().regex(/^[a-z0-9][a-z0-9_]*$/)).min(1),
59
- });
60
- export const EnvironmentContributionSchema = z.object({
61
- fragment: z
62
- .string()
63
- .min(1)
64
- .refine((value) => !value.split("/").includes(".."), { message: "fragment must stay inside the checkout" }),
65
- });
66
- export const ConnectorFieldSchema = z.object({
67
- key: z.string().regex(/^[a-zA-Z][a-zA-Z0-9]*$/),
68
- label: z.string().min(1),
69
- placeholder: z.string().optional(),
70
- secret: z.boolean().optional(),
71
- optional: z.boolean().optional(),
72
- multiline: z.boolean().optional(),
73
- default: z.string().optional(),
74
- options: z.array(z.object({ value: z.string(), label: z.string() })).optional(),
75
- when: z.object({ key: z.string(), value: z.string() }).optional(),
76
- });
77
- export const ConnectorContributionSchema = z.object({
78
- provider: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
79
- kind: z.literal("cli"),
80
- catalog: z.object({
81
- name: z.string().min(1),
82
- logo: z.string().optional(),
83
- icon: z.string().optional(),
84
- description: z.string().min(1),
85
- category: z.string().min(1),
86
- hint: z.string().optional(),
87
- guide: z
88
- .object({
89
- url: z.string().optional(),
90
- urlFromField: z.string().optional(),
91
- path: z.string().optional(),
92
- linkLabel: z.string().optional(),
93
- scopes: z.string().optional(),
94
- steps: z.array(z.string()).optional(),
95
- })
96
- .optional(),
97
- }),
98
- fields: z.array(ConnectorFieldSchema).min(1),
99
- env: z.record(z.string().regex(/^[A-Z][A-Z0-9_]*$/), z.string()),
100
- skill: z.string().min(1),
101
- fragment: z.string().min(1).optional(),
102
- });
103
- export const ExtensionManifestSchema = z.object({
104
- publisher: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
105
- name: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
106
- version: z.string().min(1),
107
- engines: z.object({ intentic: z.string().min(1) }),
108
- entry: z
109
- .string()
110
- .min(1)
111
- .refine((value) => !value.split("/").includes(".."), { message: "entry must stay inside the checkout" })
112
- .optional(),
113
- permissions: z.object({ sandbox: z.array(z.string()) }).optional(),
114
- contributes: z
115
- .object({
116
- views: z.array(ViewContributionSchema).optional(),
117
- files: z.array(FileContributionSchema).optional(),
118
- viewers: z.array(ViewerContributionSchema).optional(),
119
- documents: z.array(DocumentContributionSchema).optional(),
120
- commands: z.array(CommandContributionSchema).optional(),
121
- settings: z.array(SettingContributionSchema).optional(),
122
- processes: z.array(ProcessContributionSchema).optional(),
123
- agent: AgentContributionSchema.optional(),
124
- environment: EnvironmentContributionSchema.optional(),
125
- connectors: z.array(ConnectorContributionSchema).optional(),
126
- listener: ListenerContributionSchema.optional(),
127
- bin: z
128
- .string()
129
- .min(1)
130
- .refine((value) => !value.split("/").includes(".."), { message: "bin must stay inside the checkout" })
131
- .optional(),
132
- })
133
- .optional(),
134
- });
135
- export const extensionIdOf = (manifest) => `${manifest.publisher}.${manifest.name}`;
136
- //# sourceMappingURL=manifest.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export declare const sandboxRouteAllowed: (permissions: readonly string[], method: string, path: string) => boolean;
2
- //# sourceMappingURL=permissions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,mBAAmB,gBAAiB,SAAS,MAAM,EAAE,UAAU,MAAM,QAAQ,MAAM,KAAG,OAOlG,CAAC"}
@@ -1,21 +0,0 @@
1
- const escapeRegExp = (literal) => literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2
- const compile = (entry) => {
3
- const spaceIndex = entry.indexOf(" ");
4
- if (spaceIndex < 0) {
5
- throw new Error(`invalid sandbox permission "${entry}" — expected "<METHOD> <path-glob>", e.g. "GET /panels"`);
6
- }
7
- const method = entry.slice(0, spaceIndex).trim().toUpperCase();
8
- const glob = entry.slice(spaceIndex + 1).trim();
9
- const source = `^${glob.split("*").map(escapeRegExp).join("[^/]+")}$`;
10
- const regex = new RegExp(source);
11
- return { method, test: (path) => regex.test(path) };
12
- };
13
- export const sandboxRouteAllowed = (permissions, method, path) => {
14
- const route = path.split("?")[0] ?? path;
15
- const wanted = method.toUpperCase();
16
- return permissions.some((entry) => {
17
- const compiled = compile(entry);
18
- return compiled.method === wanted && compiled.test(route);
19
- });
20
- };
21
- //# sourceMappingURL=permissions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAKA,MAAM,YAAY,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AASjG,MAAM,OAAO,GAAG,CAAC,KAAa,EAAiB,EAAE;IAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,yDAAyD,CAAC,CAAC;IACnH,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACxD,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,WAA8B,EAAE,MAAc,EAAE,IAAY,EAAW,EAAE;IACzG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,OAAO,QAAQ,CAAC,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACP,CAAC,CAAC"}
package/src/manifest.ts DELETED
@@ -1,275 +0,0 @@
1
- import { z } from "zod";
2
-
3
- /* The extension manifest: `intentic-extension.json` at the extension repo root (deliberately NOT inside
4
- * .claude-plugin/ — that directory is Claude Code's namespace with its own semantics). The manifest is the
5
- * approval surface: the install dialog shows exactly these declared contributions before the owner confirms,
6
- * and the host refuses runtime registrations (views, commands) whose ids the approved manifest never declared. */
7
-
8
- // A sidebar element family the extension may register at runtime (api.views.register): `rail` = a global
9
- // left-rail tile routed at /ext/:ext/:key?; `directory` = a per-repo panel opened from the Workspace tree;
10
- // `sandbox` = a tab on the Sandbox hub, for a view whose subject is the BOX rather than the work (see
11
- // ViewRegistration.surface).
12
- export const ViewContributionSchema = z.object({
13
- id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
14
- label: z.string().min(1),
15
- surface: z.enum(["rail", "directory", "sandbox"]),
16
- // Whether this view may badge its tile (ViewRegistration.badge). Declared here, like a command's
17
- // keybinding, because it is consequential: a badge interrupts the user from every other screen in the app.
18
- // Absent ⇒ the host drops any badge the extension registers.
19
- badge: z.boolean().optional(),
20
- });
21
- export type ViewContribution = z.infer<typeof ViewContributionSchema>;
22
-
23
- /* WHICH WORKSPACE FILE MAKES THIS EXTENSION'S VIEW STALE — the extension's half of the core's
24
- * WORKSPACE_STATE_FILES table (@intentic/sandbox-contract), in the same two fields so the browser can union them
25
- * without translating.
26
- *
27
- * An intentic workspace is file-first: the agent edits /work with its own file tools, out of band from every
28
- * HTTP route, and the daemon's filesystem watcher is the ONLY thing that can tell a browser its view went stale.
29
- * Before this contribution point existed an extension had no way into that push, so every one of them polled —
30
- * and the core's table had to hardcode `automations`/`automation-approvals`, query keys owned by an extension,
31
- * because the extension itself couldn't declare them. Declaring is now the extension's job and unioning is the
32
- * host's.
33
- *
34
- * It rides the manifest rather than a runtime api.workspace.onDidChangeFiles for two reasons: the owner sees at
35
- * install which of their files an extension reads, and there is nothing imperative left to get wrong — no
36
- * subscribe, no unsubscribe, no listener that quietly stops firing. */
37
- export const FileContributionSchema = z.object({
38
- /* Workspace-root-relative, forward-slash — the space the watcher's changed paths arrive in. Matched by
39
- * PREFIX, so one entry covers an exact file (`.intentic/automations.json`), a directory (`.intentic/drafts/`
40
- * — keep the trailing slash so it cannot match a sibling file) or a name family (`.intentic/environment.`).
41
- * Deliberately not a glob: prefix is the whole matching rule on both sides of this union. */
42
- path: z
43
- .string()
44
- .min(1)
45
- .refine((value) => !value.startsWith("/") && !value.split("/").includes(".."), {
46
- message: "path must be workspace-root-relative and stay inside the workspace",
47
- }),
48
- /* The browser query keys those contents feed — the first element of the extension's own
49
- * `api.sandbox.key(...)` keys, which is what makes them match (the sandbox id is a SUFFIX). Empty is not
50
- * allowed: a path that makes nothing stale is a declaration with no effect, and saying so at install beats
51
- * discovering it as a view that never refreshes.
52
- *
53
- * Keep the paths as narrow as the view actually needs. A broad prefix costs every connected browser a
54
- * refetch per matching write, and a write-heavy path (an index, a transcript, a log) turns that into a
55
- * request storm — the reason the core table leaves the daemon's own machine state off the push entirely. */
56
- invalidates: z.array(z.string().min(1)).min(1),
57
- });
58
- export type FileContribution = z.infer<typeof FileContributionSchema>;
59
-
60
- /* A custom file viewer the extension may register at runtime (api.viewers.register): the host resolves an open
61
- * file to this viewer by extension, gets its content, and renders the registered component with it — the host
62
- * keeps the fetch + open-file lifecycle and the daemon credentials; the extension only renders. `extensions`
63
- * are bare file extensions (no dot), e.g. ["docx"]. This is the non-sidebar contribution point.
64
- *
65
- * `fetch` is how much of the file the host puts in the extension's hands, and it is a real choice:
66
- * text — decoded utf8 (`text` prop). For a format that IS text: svg, a subtitle track, a notebook.
67
- * blob — the whole file in memory (`blob` prop). For a format that must be parsed end to end before any of
68
- * it can be shown: a .docx, a spreadsheet. Bounded by the daemon's raw-read cap.
69
- * url — a streaming URL the component points an element at (`src` prop), never the bytes. For anything
70
- * RANGE-READ rather than parsed: audio and video, where the file may be gigabytes and the player
71
- * wants the header, the index and the seconds around the playhead — not the file. The host mints
72
- * the credential on that URL and keeps it out of the extension.
73
- */
74
- export const ViewerContributionSchema = z.object({
75
- id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
76
- extensions: z.array(z.string().regex(/^[a-z0-9]+$/)).min(1),
77
- fetch: z.enum(["text", "blob", "url"]),
78
- });
79
- export type ViewerContribution = z.infer<typeof ViewerContributionSchema>;
80
-
81
- /* A per-directory document family the extension may register at runtime (api.documents.register): the provider
82
- * marks the directory rows it can explain in the Workspace tree, and the host opens its component as a tab —
83
- * see DocumentProviderRegistration.
84
- *
85
- * Only the id is declared, deliberately. The consequential part of a viewer is which FILES it takes over, and of
86
- * a command its global shortcut — both are decided here because the owner must see them. A document provider
87
- * takes nothing over: it adds an icon to rows it has something for, and every one of those rows is evidence the
88
- * owner can see for themselves. So the manifest gates WHETHER the extension may mark up the tree at all, and the
89
- * per-row wording stays with the provider, which is the only thing that knows what it found. */
90
- export const DocumentContributionSchema = z.object({
91
- id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
92
- // The family's human name, shown in the install dialog beside the extension's other contributions.
93
- label: z.string().min(1),
94
- });
95
- export type DocumentContribution = z.infer<typeof DocumentContributionSchema>;
96
-
97
- // A command the extension may register a handler for (api.commands.register); surfaced in the command palette.
98
- export const CommandContributionSchema = z.object({
99
- command: z.string().regex(/^[a-z0-9][a-z0-9-]*(\.[a-z0-9][a-z0-9-]*)+$/),
100
- title: z.string().min(1),
101
- icon: z.string().optional(),
102
- // An optional global keyboard shortcut, in the host's chord notation (`Mod`/`Ctrl`/`Shift`/`Alt` + key, e.g.
103
- // "Mod+Shift+K"; `Mod` = ⌘ on Apple, Ctrl elsewhere). It is DECLARED here so it rides the install dialog's
104
- // approval surface — a global shortcut is consequential, so like title/icon the manifest value is authoritative
105
- // and the host binds only what was approved. Whitespace-free; an unparseable chord simply never fires.
106
- keybinding: z.string().regex(/^\S+$/).optional(),
107
- });
108
- export type CommandContribution = z.infer<typeof CommandContributionSchema>;
109
-
110
- // A typed setting descriptor the host renders schema-driven into the Settings page and persists daemon-side —
111
- // `enum` lists the choices for type "enum" and is meaningless otherwise. `secret: true` masks the value in the
112
- // UI and strips it from reads (a set secret round-trips as "still set", never its value). `env` injects the
113
- // stored value into the agent's shell environment under that name every turn — the way a connector's
114
- // credential reaches the agent's CLI tools, but declared by the extension.
115
- export const SettingContributionSchema = z.object({
116
- key: z.string().regex(/^[a-z0-9][a-zA-Z0-9-]*$/),
117
- type: z.enum(["boolean", "string", "number", "enum"]),
118
- title: z.string().min(1),
119
- description: z.string().optional(),
120
- default: z.union([z.string(), z.number(), z.boolean()]).optional(),
121
- enum: z.array(z.string()).optional(),
122
- secret: z.boolean().optional(),
123
- env: z
124
- .string()
125
- .regex(/^[A-Z][A-Z0-9_]*$/)
126
- .optional(),
127
- });
128
- export type SettingContribution = z.infer<typeof SettingContributionSchema>;
129
-
130
- // A long-lived background process the daemon runs for the extension (tmux-managed, like panel dev servers).
131
- // `port: "auto"` assigns a free port injected as PORT; `preview` exposes it on a tunneled preview hostname;
132
- // `autoStart` launches it on install and daemon boot. `cwd` is relative to the extension checkout.
133
- export const ProcessContributionSchema = z.object({
134
- name: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
135
- command: z.string().min(1),
136
- cwd: z.string().optional(),
137
- port: z.literal("auto").optional(),
138
- preview: z.boolean().optional(),
139
- autoStart: z.boolean().optional(),
140
- });
141
- export type ProcessContribution = z.infer<typeof ProcessContributionSchema>;
142
-
143
- // "This checkout is ALSO a Claude Code plugin": the daemon hands the directory (`path` relative to the
144
- // checkout; absent ⇒ the checkout root) to the Agent SDK's plugin loader, which reads skills/agents/hooks/
145
- // commands/.mcp.json each turn — the daemon never parses plugin internals.
146
- export const AgentContributionSchema = z.object({
147
- path: z.string().optional(),
148
- });
149
- export type AgentContribution = z.infer<typeof AgentContributionSchema>;
150
-
151
- // A realtime listener the extension's gateway process (contributes.processes) implements: `provider` is the
152
- // slug its automation triggers fire on (Trigger.provider) and `eventTypes` the kinds those triggers may narrow
153
- // to (Trigger.eventType). The daemon validates listener automations against these, and serves the gateway a
154
- // provider-scoped control surface — GET /listeners/<provider>/state to reconcile, POST …/dispatch to wake an
155
- // automation (optionally holding a turn-stream), …/failure + …/status to report. The daemon holds no provider
156
- // connection itself; the extension's process does.
157
- export const ListenerContributionSchema = z.object({
158
- provider: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
159
- eventTypes: z.array(z.string().regex(/^[a-z0-9][a-z0-9_]*$/)).min(1),
160
- });
161
- export type ListenerContribution = z.infer<typeof ListenerContributionSchema>;
162
-
163
- // A Dockerfile fragment baked into the sandbox image overlay so the extension's tools are present at runtime
164
- // (a whisper binary, a psql client, …). `fragment` is a checkout-relative path to a file holding ONLY RUN/ENV
165
- // instructions — the daemon rejects FROM and privileged `# intentic:runtime` directives from extension
166
- // fragments (those stay daemon-owned), and the owner approves the composed overlay + rebuilds out-of-band.
167
- export const EnvironmentContributionSchema = z.object({
168
- fragment: z
169
- .string()
170
- .min(1)
171
- .refine((value) => !value.split("/").includes(".."), { message: "fragment must stay inside the checkout" }),
172
- });
173
- export type EnvironmentContribution = z.infer<typeof EnvironmentContributionSchema>;
174
-
175
- // A field the "+" install dialog renders for a connector's config form (a slug key, a label, secret/optional
176
- // flags, an optional select, a `when` gate). Mirrors the platform catalog's field shape so the web can render
177
- // connector cards from installed extensions exactly like core capability cards.
178
- export const ConnectorFieldSchema = z.object({
179
- key: z.string().regex(/^[a-zA-Z][a-zA-Z0-9]*$/),
180
- label: z.string().min(1),
181
- placeholder: z.string().optional(),
182
- secret: z.boolean().optional(),
183
- optional: z.boolean().optional(),
184
- multiline: z.boolean().optional(),
185
- default: z.string().optional(),
186
- options: z.array(z.object({ value: z.string(), label: z.string() })).optional(),
187
- when: z.object({ key: z.string(), value: z.string() }).optional(),
188
- });
189
- export type ConnectorField = z.infer<typeof ConnectorFieldSchema>;
190
-
191
- // A CLI-tool connector as DATA: the "+" card, the config fields, the env vars the agent's shell gets (value
192
- // templates over the fields — `${field}` substitutes, `${field:uri}` percent-encodes), the SKILL.md cheatsheet
193
- // path, and an optional image fragment path (a psql/whisper client). The daemon's cli handler resolves a
194
- // provider to its spec through the connector registry instead of a hardcoded table, so a connector is one
195
- // manifest entry + two files, no daemon change.
196
- export const ConnectorContributionSchema = z.object({
197
- provider: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
198
- kind: z.literal("cli"),
199
- catalog: z.object({
200
- name: z.string().min(1),
201
- logo: z.string().optional(),
202
- // An @intentic-app/ui IconName fallback glyph, rendered when no simple-icons `logo` fits the brand.
203
- icon: z.string().optional(),
204
- description: z.string().min(1),
205
- category: z.string().min(1),
206
- hint: z.string().optional(),
207
- // The credential-creation walkthrough the install dialog renders (the platform catalog's guide shape).
208
- guide: z
209
- .object({
210
- url: z.string().optional(),
211
- urlFromField: z.string().optional(),
212
- path: z.string().optional(),
213
- linkLabel: z.string().optional(),
214
- scopes: z.string().optional(),
215
- steps: z.array(z.string()).optional(),
216
- })
217
- .optional(),
218
- }),
219
- fields: z.array(ConnectorFieldSchema).min(1),
220
- env: z.record(z.string().regex(/^[A-Z][A-Z0-9_]*$/), z.string()),
221
- skill: z.string().min(1),
222
- fragment: z.string().min(1).optional(),
223
- });
224
- export type ConnectorContribution = z.infer<typeof ConnectorContributionSchema>;
225
-
226
- export const ExtensionManifestSchema = z.object({
227
- publisher: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
228
- name: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
229
- // The extension's own semver — display/identity only; the installed code identity is the pinned commit sha.
230
- version: z.string().min(1),
231
- // Semver range over the host's extension API version (extensionApiVersion) — checked before activation.
232
- engines: z.object({ intentic: z.string().min(1) }),
233
- // Repo-relative path of the prebuilt single-file ESM bundle (built with `vue` and `@intentic/extension-api`
234
- // as externals); absent ⇒ an agent-only extension with no UI entry.
235
- entry: z
236
- .string()
237
- .min(1)
238
- .refine((value) => !value.split("/").includes(".."), { message: "entry must stay inside the checkout" })
239
- .optional(),
240
- // The daemon routes this extension may call through api.sandbox.request/json — each "<METHOD> <path-glob>"
241
- // where `*` matches one path segment (e.g. "GET /panels", "POST /panels/*/start"). The host refuses any
242
- // api.sandbox call whose method+path isn't declared here, so an extension's backend reach is explicit and
243
- // reviewable instead of an ambient client to the whole daemon. Absent ⇒ the extension makes no api.sandbox calls.
244
- permissions: z.object({ sandbox: z.array(z.string()) }).optional(),
245
- contributes: z
246
- .object({
247
- views: z.array(ViewContributionSchema).optional(),
248
- // Which workspace files back those views — the extension's entry into the daemon's file-change push,
249
- // in place of a poll. See FileContributionSchema.
250
- files: z.array(FileContributionSchema).optional(),
251
- viewers: z.array(ViewerContributionSchema).optional(),
252
- documents: z.array(DocumentContributionSchema).optional(),
253
- commands: z.array(CommandContributionSchema).optional(),
254
- settings: z.array(SettingContributionSchema).optional(),
255
- processes: z.array(ProcessContributionSchema).optional(),
256
- agent: AgentContributionSchema.optional(),
257
- environment: EnvironmentContributionSchema.optional(),
258
- connectors: z.array(ConnectorContributionSchema).optional(),
259
- listener: ListenerContributionSchema.optional(),
260
- // A checkout-relative directory of executables the daemon prepends to the AGENT's PATH each turn —
261
- // how an extension ships a command-line tool for the agent (the CLI-tools path). The files ARE the
262
- // approved code (they ride the sha-pinned checkout); the daemon only adds the dir to PATH.
263
- bin: z
264
- .string()
265
- .min(1)
266
- .refine((value) => !value.split("/").includes(".."), { message: "bin must stay inside the checkout" })
267
- .optional(),
268
- })
269
- .optional(),
270
- });
271
- export type ExtensionManifest = z.infer<typeof ExtensionManifestSchema>;
272
-
273
- // The extension's identity everywhere (capability entries, /ext routes, settings namespaces) — derived, never
274
- // declared, so it can't contradict the publisher/name the install dialog showed.
275
- export const extensionIdOf = (manifest: Pick<ExtensionManifest, "publisher" | "name">): string => `${manifest.publisher}.${manifest.name}`;
@@ -1,36 +0,0 @@
1
- /* The sandbox-route permission model. An extension declares in its manifest exactly which daemon routes it may
2
- * reach through `api.sandbox.request/json`, as "<METHOD> <path-glob>" strings where `*` matches exactly one path
3
- * segment. The host matches every call against these and refuses an undeclared route — so an extension's backend
4
- * reach is explicit, diffable, and reviewable rather than an ambient client to the whole daemon. */
5
-
6
- const escapeRegExp = (literal: string): string => literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7
-
8
- interface CompiledRoute {
9
- readonly method: string;
10
- readonly test: (path: string) => boolean;
11
- }
12
-
13
- // "<METHOD> <path-glob>" → a method + an anchored path matcher. Each `*` in the glob matches one path segment
14
- // ([^/]+); everything else is literal. Throws on a malformed entry so a bad manifest fails loudly at load.
15
- const compile = (entry: string): CompiledRoute => {
16
- const spaceIndex = entry.indexOf(" ");
17
- if (spaceIndex < 0) {
18
- throw new Error(`invalid sandbox permission "${entry}" — expected "<METHOD> <path-glob>", e.g. "GET /panels"`);
19
- }
20
- const method = entry.slice(0, spaceIndex).trim().toUpperCase();
21
- const glob = entry.slice(spaceIndex + 1).trim();
22
- const source = `^${glob.split("*").map(escapeRegExp).join("[^/]+")}$`;
23
- const regex = new RegExp(source);
24
- return { method, test: (path) => regex.test(path) };
25
- };
26
-
27
- // Whether `method path` is covered by any of the declared permissions. The query string is ignored (routes are
28
- // matched on path only), and the method is compared case-insensitively.
29
- export const sandboxRouteAllowed = (permissions: readonly string[], method: string, path: string): boolean => {
30
- const route = path.split("?")[0] ?? path;
31
- const wanted = method.toUpperCase();
32
- return permissions.some((entry) => {
33
- const compiled = compile(entry);
34
- return compiled.method === wanted && compiled.test(route);
35
- });
36
- };