@intentic/extension-manifest 1.176.3

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 (114) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +74 -0
  3. package/dist/bundle.d.ts +4 -0
  4. package/dist/bundle.d.ts.map +1 -0
  5. package/dist/bundle.js +22 -0
  6. package/dist/bundle.js.map +1 -0
  7. package/dist/contribution-point.d.ts +7 -0
  8. package/dist/contribution-point.d.ts.map +1 -0
  9. package/dist/contribution-point.js +2 -0
  10. package/dist/contribution-point.js.map +1 -0
  11. package/dist/index.d.ts +8 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +8 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/json-schema.d.ts +4 -0
  16. package/dist/json-schema.d.ts.map +1 -0
  17. package/dist/json-schema.js +33 -0
  18. package/dist/json-schema.js.map +1 -0
  19. package/dist/manifest.d.ts +300 -0
  20. package/dist/manifest.d.ts.map +1 -0
  21. package/dist/manifest.js +46 -0
  22. package/dist/manifest.js.map +1 -0
  23. package/dist/mark.d.ts +6 -0
  24. package/dist/mark.d.ts.map +1 -0
  25. package/dist/mark.js +12 -0
  26. package/dist/mark.js.map +1 -0
  27. package/dist/permissions.d.ts +2 -0
  28. package/dist/permissions.d.ts.map +1 -0
  29. package/dist/permissions.js +21 -0
  30. package/dist/permissions.js.map +1 -0
  31. package/dist/points/agent.d.ts +13 -0
  32. package/dist/points/agent.d.ts.map +1 -0
  33. package/dist/points/agent.js +10 -0
  34. package/dist/points/agent.js.map +1 -0
  35. package/dist/points/automation-templates.d.ts +67 -0
  36. package/dist/points/automation-templates.d.ts.map +1 -0
  37. package/dist/points/automation-templates.js +47 -0
  38. package/dist/points/automation-templates.js.map +1 -0
  39. package/dist/points/bin.d.ts +7 -0
  40. package/dist/points/bin.d.ts.map +1 -0
  41. package/dist/points/bin.js +10 -0
  42. package/dist/points/bin.js.map +1 -0
  43. package/dist/points/capabilities.d.ts +352 -0
  44. package/dist/points/capabilities.d.ts.map +1 -0
  45. package/dist/points/capabilities.js +131 -0
  46. package/dist/points/capabilities.js.map +1 -0
  47. package/dist/points/commands.d.ts +21 -0
  48. package/dist/points/commands.d.ts.map +1 -0
  49. package/dist/points/commands.js +23 -0
  50. package/dist/points/commands.js.map +1 -0
  51. package/dist/points/documents.d.ts +15 -0
  52. package/dist/points/documents.d.ts.map +1 -0
  53. package/dist/points/documents.js +14 -0
  54. package/dist/points/documents.js.map +1 -0
  55. package/dist/points/environment.d.ts +13 -0
  56. package/dist/points/environment.d.ts.map +1 -0
  57. package/dist/points/environment.js +14 -0
  58. package/dist/points/environment.js.map +1 -0
  59. package/dist/points/files.d.ts +15 -0
  60. package/dist/points/files.d.ts.map +1 -0
  61. package/dist/points/files.js +20 -0
  62. package/dist/points/files.js.map +1 -0
  63. package/dist/points/index.d.ts +609 -0
  64. package/dist/points/index.d.ts.map +1 -0
  65. package/dist/points/index.js +44 -0
  66. package/dist/points/index.js.map +1 -0
  67. package/dist/points/listener.d.ts +51 -0
  68. package/dist/points/listener.d.ts.map +1 -0
  69. package/dist/points/listener.js +44 -0
  70. package/dist/points/listener.js.map +1 -0
  71. package/dist/points/processes.d.ts +23 -0
  72. package/dist/points/processes.d.ts.map +1 -0
  73. package/dist/points/processes.js +15 -0
  74. package/dist/points/processes.js.map +1 -0
  75. package/dist/points/settings.d.ts +37 -0
  76. package/dist/points/settings.d.ts.map +1 -0
  77. package/dist/points/settings.js +24 -0
  78. package/dist/points/settings.js.map +1 -0
  79. package/dist/points/viewers.d.ts +25 -0
  80. package/dist/points/viewers.d.ts.map +1 -0
  81. package/dist/points/viewers.js +17 -0
  82. package/dist/points/viewers.js.map +1 -0
  83. package/dist/points/views.d.ts +27 -0
  84. package/dist/points/views.d.ts.map +1 -0
  85. package/dist/points/views.js +18 -0
  86. package/dist/points/views.js.map +1 -0
  87. package/dist/powers-diff.d.ts +8 -0
  88. package/dist/powers-diff.d.ts.map +1 -0
  89. package/dist/powers-diff.js +77 -0
  90. package/dist/powers-diff.js.map +1 -0
  91. package/intentic-extension.schema.json +1341 -0
  92. package/package.json +49 -0
  93. package/src/bundle.ts +41 -0
  94. package/src/contribution-point.ts +26 -0
  95. package/src/index.ts +7 -0
  96. package/src/json-schema.ts +62 -0
  97. package/src/manifest.ts +104 -0
  98. package/src/mark.ts +34 -0
  99. package/src/permissions.ts +36 -0
  100. package/src/points/agent.ts +17 -0
  101. package/src/points/automation-templates.ts +84 -0
  102. package/src/points/bin.ts +15 -0
  103. package/src/points/capabilities.ts +271 -0
  104. package/src/points/commands.ts +44 -0
  105. package/src/points/documents.ts +31 -0
  106. package/src/points/environment.ts +24 -0
  107. package/src/points/files.ts +54 -0
  108. package/src/points/index.ts +73 -0
  109. package/src/points/listener.ts +81 -0
  110. package/src/points/processes.ts +20 -0
  111. package/src/points/settings.ts +31 -0
  112. package/src/points/viewers.ts +36 -0
  113. package/src/points/views.ts +33 -0
  114. package/src/powers-diff.ts +100 -0
@@ -0,0 +1,36 @@
1
+ import { z } from "zod";
2
+ import type { ContributionPoint } from "../contribution-point.js";
3
+
4
+ /* A custom file viewer the extension may register at runtime (api.viewers.register): the host resolves an open
5
+ * file to this viewer by extension, gets its content, and renders the registered component with it — the host
6
+ * keeps the fetch + open-file lifecycle and the daemon credentials; the extension only renders. This is the
7
+ * non-sidebar contribution point. */
8
+ export const ViewerContributionSchema = z.object({
9
+ id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
10
+ extensions: z
11
+ .array(z.string().regex(/^[a-z0-9]+$/))
12
+ .min(1)
13
+ .describe('Bare file extensions, no dot — e.g. ["docx", "xlsx"].'),
14
+ /* `fetch` is how much of the file the host puts in the extension's hands, and it is a real choice:
15
+ * text — decoded utf8 (`text` prop). For a format that IS text: svg, a subtitle track, a notebook.
16
+ * blob — the whole file in memory (`blob` prop). For a format that must be parsed end to end before any of
17
+ * it can be shown: a .docx, a spreadsheet. Bounded by the daemon's raw-read cap.
18
+ * url — a streaming URL the component points an element at (`src` prop), never the bytes. For anything
19
+ * RANGE-READ rather than parsed: audio and video, where the file may be gigabytes and the player
20
+ * wants the header, the index and the seconds around the playhead — not the file. The host mints
21
+ * the credential on that URL and keeps it out of the extension.
22
+ */
23
+ fetch: z
24
+ .enum(["text", "blob", "url"])
25
+ .describe(
26
+ "How much of the file the host hands you. `text` for a format that is text (svg, a subtitle track). `blob` for one that must be parsed end to end before any of it shows (a .docx, a spreadsheet) — bounded by the daemon's raw-read cap. `url` for anything range-read rather than parsed (audio, video): your component gets a streaming URL to point an element at, never the bytes.",
27
+ ),
28
+ });
29
+ export type ViewerContribution = z.infer<typeof ViewerContributionSchema>;
30
+
31
+ export const viewersPoint = {
32
+ name: "viewers",
33
+ description:
34
+ "File formats this extension can render. The host resolves an opened file to your viewer by its extension, fetches the content, and renders your component with it — you keep none of the fetch lifecycle and none of the daemon credentials.",
35
+ schema: z.array(ViewerContributionSchema),
36
+ } as const satisfies ContributionPoint;
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ import type { ContributionPoint } from "../contribution-point.js";
3
+
4
+ // A sidebar element family the extension may register at runtime (api.views.register): `rail` = a global
5
+ // left-rail tile routed at /ext/:ext/:key?; `directory` = a per-repo panel opened from the Workspace tree;
6
+ // `sandbox` = a tab on the Sandbox hub, for a view whose subject is the BOX rather than the work (see
7
+ // ViewRegistration.surface).
8
+ export const ViewContributionSchema = z.object({
9
+ id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
10
+ label: z.string().min(1).describe("The name shown on the tile or tab. The manifest's value wins over the one passed at registration."),
11
+ surface: z
12
+ .enum(["rail", "directory", "sandbox"])
13
+ .describe(
14
+ "Where it appears. `rail` is a tile in the global left rail; `directory` is a panel opened from a repo in the Workspace tree; `sandbox` is a tab on the Sandbox hub, for a view whose subject is the box rather than the work.",
15
+ ),
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
20
+ .boolean()
21
+ .optional()
22
+ .describe(
23
+ "Allow this view to put a count on its tile. Declared because a badge interrupts from every other screen in the app; leave it out and any badge the extension registers is dropped.",
24
+ ),
25
+ });
26
+ export type ViewContribution = z.infer<typeof ViewContributionSchema>;
27
+
28
+ export const viewsPoint = {
29
+ name: "views",
30
+ description:
31
+ "Sidebar elements this extension may register at runtime. Each entry reserves an id and a surface; the extension supplies the component with api.views.register, and the host refuses any registration this list does not cover.",
32
+ schema: z.array(ViewContributionSchema),
33
+ } as const satisfies ContributionPoint;
@@ -0,0 +1,100 @@
1
+ import type { ExtensionManifest } from "./manifest.js";
2
+
3
+ /* WHAT AN UPDATE ASKS FOR, MECHANICALLY. The install dialog renders a manifest's contributions once; an update
4
+ * is judged on what sits BETWEEN two manifests, and "read both and compare" is exactly the job a person will
5
+ * skip on the fifth update. So each manifest is folded to a set of POWERS — the consequential facts an owner
6
+ * approved: which daemon routes it may call, which processes the daemon runs for it, what lands on the agent's
7
+ * PATH, what may interrupt from another screen — each under a stable key (the identity compared) with a plain
8
+ * sentence (what the reader sees). The diff is set arithmetic over the keys.
9
+ *
10
+ * Deliberately NOT here: plain settings (a new knob is config surface, not reach), display marks, category,
11
+ * version. A power's INTERNALS moving (a process's command line, a fragment's contents) keeps its key — the
12
+ * code changed, which is what the sha pin and the agent diff-read answer for; this diff answers only "did the
13
+ * set of things I approved grow". An empty `added` is what makes an update one click. */
14
+
15
+ export interface PowersDiff {
16
+ // Powers the new manifest declares that the installed one didn't — the reason an update re-asks.
17
+ readonly added: string[];
18
+ readonly removed: string[];
19
+ readonly unchanged: string[];
20
+ }
21
+
22
+ const powersOf = (manifest: ExtensionManifest): Map<string, string> => {
23
+ const powers = new Map<string, string>();
24
+ if (manifest.entry !== undefined) {
25
+ powers.set("entry", "runs a UI bundle in your browser");
26
+ }
27
+ if (manifest.server !== undefined) {
28
+ powers.set("server", "runs a backend bundle inside the daemon's extension host");
29
+ }
30
+ for (const route of manifest.permissions?.sandbox ?? []) {
31
+ powers.set(`sandbox:${route}`, `its UI calls the sandbox route ${route}`);
32
+ }
33
+ for (const route of manifest.permissions?.daemon ?? []) {
34
+ powers.set(`daemon:${route}`, `its backend calls the daemon route ${route}`);
35
+ }
36
+ for (const view of manifest.contributes?.views ?? []) {
37
+ powers.set(`view:${view.id}`, `a ${view.surface} view "${view.label}"`);
38
+ if (view.badge === true) {
39
+ powers.set(`view-badge:${view.id}`, `may badge the "${view.label}" tile from any screen`);
40
+ }
41
+ }
42
+ for (const viewer of manifest.contributes?.viewers ?? []) {
43
+ powers.set(`viewer:${viewer.id}`, `opens .${viewer.extensions.join(", .")} files (${viewer.fetch})`);
44
+ }
45
+ for (const document of manifest.contributes?.documents ?? []) {
46
+ powers.set(`document:${document.id}`, `marks workspace directories ("${document.label}")`);
47
+ }
48
+ for (const command of manifest.contributes?.commands ?? []) {
49
+ powers.set(`command:${command.command}`, `a palette command "${command.title}"`);
50
+ if (command.keybinding !== undefined) {
51
+ powers.set(`keybinding:${command.command}`, `the global shortcut ${command.keybinding} ("${command.title}")`);
52
+ }
53
+ }
54
+ for (const setting of manifest.contributes?.settings ?? []) {
55
+ if (setting.env !== undefined) {
56
+ powers.set(`setting-env:${setting.key}`, `puts the "${setting.key}" setting into the agent's environment as ${setting.env}`);
57
+ }
58
+ }
59
+ for (const process of manifest.contributes?.processes ?? []) {
60
+ powers.set(`process:${process.name}`, `a background process "${process.name}"${process.autoStart === true ? " (starts on boot)" : ""}`);
61
+ }
62
+ for (const file of manifest.contributes?.files ?? []) {
63
+ powers.set(`files:${file.path}`, `is told when ${file.path} changes`);
64
+ }
65
+ if (manifest.contributes?.agent !== undefined) {
66
+ powers.set("agent", "contributes skills, agents and hooks to the agent's turns");
67
+ }
68
+ if (manifest.contributes?.environment !== undefined) {
69
+ powers.set("environment", "bakes an environment fragment into the sandbox image");
70
+ }
71
+ for (const capability of manifest.contributes?.capabilities ?? []) {
72
+ powers.set(`capability:${capability.id}`, `a ${capability.kind} capability card "${capability.catalog.name}"`);
73
+ }
74
+ if (manifest.contributes?.listener !== undefined) {
75
+ powers.set(`listener:${manifest.contributes.listener.provider}`, `a realtime listener provider "${manifest.contributes.listener.provider}"`);
76
+ }
77
+ if (manifest.contributes?.bin !== undefined) {
78
+ powers.set("bin", "puts its shipped tools on the agent's PATH");
79
+ }
80
+ return powers;
81
+ };
82
+
83
+ // `before` absent covers a first install: everything the manifest declares is `added`, which is exactly what
84
+ // the install dialog already renders — one vocabulary for both moments.
85
+ export const diffPowers = (before: ExtensionManifest | undefined, after: ExtensionManifest): PowersDiff => {
86
+ const from = before === undefined ? new Map<string, string>() : powersOf(before);
87
+ const to = powersOf(after);
88
+ const added: string[] = [];
89
+ const removed: string[] = [];
90
+ const unchanged: string[] = [];
91
+ for (const [key, label] of to) {
92
+ (from.has(key) ? unchanged : added).push(label);
93
+ }
94
+ for (const [key, label] of from) {
95
+ if (!to.has(key)) {
96
+ removed.push(label);
97
+ }
98
+ }
99
+ return { added, removed, unchanged };
100
+ };