@intentic/extension-manifest 1.222.0 → 1.224.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.
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/points/capabilities.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;iBA+EhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAepE,eAAO,MAAM,YAAY,UAAW,eAAe,UAAU,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAG,OACtB,CAAC;AA2D5E,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAmFnC,CAAC;AACP,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,sBAAsB,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAcnF,eAAO,MAAM,yBAAyB,SAAU,MAAM,KAAG,MAAM,GAAG,SAA8D,CAAC;AAEjI,eAAO,MAAM,iBAAiB;mBACpB,cAAc;0BAEhB,4UAA4U;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAE9S,CAAC"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/points/capabilities.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;iBA+EhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAepE,eAAO,MAAM,YAAY,UAAW,eAAe,UAAU,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAG,OACtB,CAAC;AA+D5E,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAwFnC,CAAC;AACP,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,sBAAsB,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAcnF,eAAO,MAAM,yBAAyB,SAAU,MAAM,KAAG,MAAM,GAAG,SAA8D,CAAC;AAEjI,eAAO,MAAM,iBAAiB;mBACpB,cAAc;0BAEhB,4UAA4U;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAE9S,CAAC"}
@@ -99,7 +99,10 @@ export const CapabilityContributionSchema = z
99
99
  .url()
100
100
  .optional()
101
101
  .describe("Where that same profile opens once it HAS a session — the owner's own hands on the connected browser. Separate from loginUrl because for some platforms the login lives on another site entirely (YouTube signs in at accounts.google.com)."),
102
- skill: z.string().min(1).describe("Checkout-relative SKILL.md teaching the agent this site's actions."),
102
+ skill: z
103
+ .string()
104
+ .min(1)
105
+ .describe("Checkout-relative SKILL.md teaching the agent this site's actions — rendered once per site, all its connected accounts on one roster (`${accounts}`), the core tool note at `${tools}`."),
103
106
  }),
104
107
  z.object({
105
108
  ...contributionBase,
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/points/capabilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/points/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKzC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,wBAAwB,CAAC;IAC/C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAC3E,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAChC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAOjC,OAAO,EAAE,CAAC;SACL,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACL,2SAA2S,CAC9S;IAIL,IAAI,EAAE,CAAC;SACF,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACL,+MAA+M,CAClN;IAQL,OAAO,EAAE,CAAC;SACL,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACL,yQAAyQ,CAC5Q;IACL,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,OAAO,EAAE,CAAC;SACL,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;SACzD,QAAQ,EAAE;SACV,QAAQ,CAAC,gCAAgC,CAAC;IAQ/C,IAAI,EAAE,CAAC;SACF,MAAM,EAAE;SACR,MAAM,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;SACrE,QAAQ,EAAE;SACV,QAAQ,CACL,kMAAkM,CACrM;IAGL,KAAK,EAAE,CAAC;SACH,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACL,2JAA2J,CAC9J;IAML,IAAI,EAAE,CAAC;SACF,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACL,8RAA8R,CACjS;CACR,CAAC,CAAC;AAgBH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAsB,EAAE,MAAyC,EAAW,EAAE,CACvG,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;AAI5E,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,GAAG,WAAW;IAMd,WAAW,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACL,iMAAiM,CACpM;IACL,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAG3B,IAAI,EAAE,CAAC;SACF,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACL,qNAAqN,CACxN;IAEL,KAAK,EAAE,CAAC;SACH,MAAM,CAAC;QACJ,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC1B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;KACxC,CAAC;SACD,QAAQ,EAAE;SACV,QAAQ,CAAC,2FAA2F,CAAC;CAC7G,CAAC,CAAC;AAIH,MAAM,gBAAgB,GAAG;IACrB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,sBAAsB,CAAC;IAC5C,OAAO,EAAE,aAAa;IACtB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;CACzC,CAAC;AAgBF,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC;KACxC,kBAAkB,CAAC,MAAM,EAAE;IAIxB,CAAC,CAAC,MAAM,CAAC;QACL,GAAG,gBAAgB;QACnB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QACtB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,GAAG,EAAE,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;aACzD,QAAQ,CACL,0KAA0K,CAC7K;QACL,KAAK,EAAE,CAAC;aACH,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CAAC,0HAA0H,CAAC;QACzI,QAAQ,EAAE,CAAC;aACN,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;aACV,QAAQ,CAAC,yFAAyF,CAAC;KAC3G,CAAC;IAgBF,CAAC,CAAC,MAAM,CAAC;QACL,GAAG,gBAAgB;QACnB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;QAC1B,QAAQ,EAAE,CAAC;aACN,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,CACL,wQAAwQ,CAC3Q;QACL,OAAO,EAAE,CAAC;aACL,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,CACL,6OAA6O,CAChP;QACL,KAAK,EAAE,CAAC;aACH,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CACL,yLAAyL,CAC5L;KACR,CAAC;IAGF,CAAC,CAAC,MAAM,CAAC;QACL,GAAG,gBAAgB;QACnB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qEAAqE,CAAC;KAC3G,CAAC;IAIF,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;CAC9D,CAAC;KACD,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IAIvB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACtB,OAAO;IACX,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC7E,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;YACjI,GAAG,CAAC,QAAQ,CAAC;gBACT,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,0CAA0C,KAAK,CAAC,GAAG,4CAA4C;aAC3G,CAAC,CAAC;QACP,CAAC;IACL,CAAC;AACL,CAAC,CAAC,CAAC;AAaP,MAAM,aAAa,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAG/F,CAAC;AACF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,IAAY,EAAsB,EAAE,CAAC,aAAa,CAAC,IAAkC,CAAC,CAAC;AAEjI,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC7B,IAAI,EAAE,cAAc;IACpB,WAAW,EACP,4UAA4U;IAChV,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC;CACX,CAAC"}
@@ -749,7 +749,7 @@
749
749
  "skill": {
750
750
  "type": "string",
751
751
  "minLength": 1,
752
- "description": "Checkout-relative SKILL.md teaching the agent this site's actions."
752
+ "description": "Checkout-relative SKILL.md teaching the agent this site's actions — rendered once per site, all its connected accounts on one roster (`${accounts}`), the core tool note at `${tools}`."
753
753
  }
754
754
  },
755
755
  "required": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentic/extension-manifest",
3
- "version": "1.222.0",
3
+ "version": "1.224.0",
4
4
  "description": "What an intentic extension DECLARES — the intentic-extension.json schema and the sandbox-route allowlist rule",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,7 +34,7 @@
34
34
  "dependencies": {
35
35
  "tslib": "2.8.1",
36
36
  "zod": "4.4.3",
37
- "@intentic/base": "1.222.0"
37
+ "@intentic/base": "1.224.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "24.13.2",
package/src/bundle.ts CHANGED
@@ -1,8 +1,8 @@
1
- /* WHAT A PUBLISHED BUNDLE MAY IMPORT — the loader's side of the manifest contract, stated where both sides can
1
+ /* WHAT A PUBLISHED BUNDLE MAY IMPORT, the loader's side of the manifest contract, stated where both sides can
2
2
  * read it. The host fetches an extension's entry bytes and imports them from a blob: URL, which has two hard
3
3
  * consequences: a relative import resolves against a blob: URL that was never created (a 404 for a file that
4
4
  * exists on disk), and a bare specifier resolves only if the shell's import map publishes it. Both failures are
5
- * invisible to the author — their own workspace loads the directory live — and fatal for every installer.
5
+ * invisible to the author, their own workspace loads the directory live, and fatal for every installer.
6
6
  *
7
7
  * It lives HERE, beside the manifest schema, because two independent judges have to agree on it: the daemon's
8
8
  * readiness check (before an author publishes) and the registry scanner (re-deriving the same answer cold, at
@@ -14,7 +14,7 @@
14
14
  export const HOST_PUBLISHED_SPECIFIERS = ["vue", "@intentic/extension-api", "@intentic/extension-ui", "@tanstack/vue-query"] as const;
15
15
 
16
16
  // Every specifier a single-file ESM bundle names: static imports, re-exports, bare side-effect imports, and
17
- // dynamic import(). A bundle is one file by contract, so a regex over its text is the right instrument — there
17
+ // dynamic import(). A bundle is one file by contract, so a regex over its text is the right instrument, there
18
18
  // is no module graph to walk.
19
19
  export const bundleSpecifiers = (source: string): string[] => [
20
20
  ...new Set([
@@ -1,17 +1,17 @@
1
1
  import type { z } from "zod";
2
2
 
3
- /* A CONTRIBUTION POINT, DEFINED ONCE — its key, its shape, and the sentence that explains it to the person
3
+ /* A CONTRIBUTION POINT, DEFINED ONCE, its key, its shape, and the sentence that explains it to the person
4
4
  * writing the manifest, in one object.
5
5
  *
6
6
  * The three used to live apart, and only two of them lived anywhere at all. The key and the shape sat in one
7
7
  * file that every feature had to edit to add anything, in two places (the schema, then the key on `contributes`);
8
- * the explanation sat in a `//` comment above it, where the extension author — the only reader it was written
9
- * for — could never see it. So the manifest was a thing you wrote by copying another extension's and guessing,
8
+ * the explanation sat in a `//` comment above it, where the extension author, the only reader it was written
9
+ * for, could never see it. So the manifest was a thing you wrote by copying another extension's and guessing,
10
10
  * with a misspelt contribution point dropped in silence rather than named.
11
11
  *
12
12
  * Binding the description to the schema is what changes that: it rides `z.describe`, so it reaches the generated
13
13
  * authoring schema (json-schema.ts) and comes back as hover text in the author's editor. The prose that is for
14
- * MAINTAINERS — why a point exists, what it replaced, what it deliberately does not do — stays a comment in the
14
+ * MAINTAINERS, why a point exists, what it replaced, what it deliberately does not do, stays a comment in the
15
15
  * point's own file, because it is not what someone filling in a field needs to read. */
16
16
  export interface ContributionPoint<Name extends string = string, Schema extends z.ZodType = z.ZodType> {
17
17
  // The key under `contributes` in intentic-extension.json.
@@ -20,7 +20,7 @@ export interface ContributionPoint<Name extends string = string, Schema extends
20
20
  * them, and what the host does with it. It lands verbatim in editor hover text, so a paragraph of rationale
21
21
  * here is a paragraph in a tooltip. */
22
22
  readonly description: string;
23
- // The value shape under that key — an array for a point that takes many entries, the entry itself for a
23
+ // The value shape under that key, an array for a point that takes many entries, the entry itself for a
24
24
  // point that takes one. `contributes` makes every one of them optional; a point is never required.
25
25
  readonly schema: Schema;
26
26
  }
@@ -1,12 +1,12 @@
1
1
  import { z } from "zod";
2
2
  import { ExtensionManifestSchema } from "./manifest.js";
3
3
 
4
- /* THE AUTHORING SCHEMA — what an editor reads to help someone write `intentic-extension.json`.
4
+ /* THE AUTHORING SCHEMA, what an editor reads to help someone write `intentic-extension.json`.
5
5
  *
6
6
  * A manifest was previously written by copying another extension's and guessing. Nothing told the author what a
7
7
  * field meant, because every explanation lived in a `//` comment in this package; and nothing told them when
8
8
  * they got one wrong, because zod STRIPS unknown keys at every level rather than refusing them. A misspelt
9
- * `viewers` was not an error — it was a viewer that never appeared, discovered at install, with the manifest
9
+ * `viewers` was not an error, it was a viewer that never appeared, discovered at install, with the manifest
10
10
  * parsing perfectly.
11
11
  *
12
12
  * So: the same points, emitted as JSON Schema, with the descriptions that ride each one (contribution-point.ts)
@@ -15,7 +15,7 @@ import { ExtensionManifestSchema } from "./manifest.js";
15
15
  *
16
16
  * STRICT HERE, LENIENT AT RUNTIME, and the asymmetry is the point. Authoring is where an unknown key is a typo
17
17
  * and should be shouted about. Runtime is where an unknown key is a manifest written for a NEWER host, which an
18
- * older daemon must go on installing with the point it doesn't understand ignored — refusing it outright would
18
+ * older daemon must go on installing with the point it doesn't understand ignored, refusing it outright would
19
19
  * make every addition to this list a breaking change. */
20
20
 
21
21
  // Where the published copy answers, so `$schema` in a manifest resolves for an author who has installed nothing.
@@ -23,7 +23,7 @@ export const MANIFEST_SCHEMA_URL = "https://intentic.dev/intentic-extension.sche
23
23
 
24
24
  /* `additionalProperties: false` on every object node, so a key nothing declares is flagged where it is typed.
25
25
  *
26
- * Skips a node that already carries `additionalProperties` — that is a `z.record`, whose whole shape is "any key,
26
+ * Skips a node that already carries `additionalProperties`, that is a `z.record`, whose whole shape is "any key,
27
27
  * this value" (a cli capability's `env`), and pinning it closed would reject every entry it exists to accept. */
28
28
  const closeToUnknownKeys = (node: unknown): void => {
29
29
  if (Array.isArray(node)) {
@@ -44,7 +44,7 @@ const closeToUnknownKeys = (node: unknown): void => {
44
44
  }
45
45
  };
46
46
 
47
- /* The manifest schema as JSON Schema. `io: "input"` because this describes what an author WRITES — the shape
47
+ /* The manifest schema as JSON Schema. `io: "input"` because this describes what an author WRITES, the shape
48
48
  * going in, before any refinement or default has been applied to it. */
49
49
  export const manifestJsonSchema = (): Record<string, unknown> => {
50
50
  const schema = z.toJSONSchema(ExtensionManifestSchema, { unrepresentable: "any", io: "input" }) as Record<string, unknown>;
@@ -58,5 +58,5 @@ export const manifestJsonSchema = (): Record<string, unknown> => {
58
58
  };
59
59
 
60
60
  // The committed file's exact bytes, so the generator and the check that guards it cannot disagree about
61
- // formatting — four spaces and a trailing newline, the repo's shape for a committed generated document.
61
+ // formatting, four spaces and a trailing newline, the repo's shape for a committed generated document.
62
62
  export const serializeManifestJsonSchema = (schema: Record<string, unknown>): string => `${JSON.stringify(schema, undefined, 4)}\n`;
package/src/manifest.ts CHANGED
@@ -3,25 +3,25 @@ import { MARK_FIELDS } from "./mark.js";
3
3
  import { contributesSchema } from "./points/index.js";
4
4
 
5
5
  /* The extension manifest: `intentic-extension.json` at the extension repo root (deliberately NOT inside
6
- * .claude-plugin/ — that directory is Claude Code's namespace with its own semantics). The manifest is the
6
+ * .claude-plugin/, that directory is Claude Code's namespace with its own semantics). The manifest is the
7
7
  * approval surface: the install dialog shows exactly these declared contributions before the owner confirms,
8
8
  * and the host refuses runtime registrations (views, commands) whose ids the approved manifest never declared.
9
9
  *
10
- * This file is the ENVELOPE only — who the extension is, which host it needs, what code it ships, how far it
10
+ * This file is the ENVELOPE only, who the extension is, which host it needs, what code it ships, how far it
11
11
  * may reach. What it may CONTRIBUTE is one file per contribution point under points/, assembled here; see
12
12
  * contribution-point.ts for why the description travels with the schema instead of sitting in a comment. */
13
13
 
14
14
  export const ExtensionManifestSchema = z.object({
15
- /* The authoring schema this manifest is written against — editors read it and give the author completion,
15
+ /* The authoring schema this manifest is written against, editors read it and give the author completion,
16
16
  * hover text and a red squiggle on a misspelt key. Declared so it survives the parse rather than being
17
17
  * silently stripped, which is what would otherwise happen to the one field an author is most likely to add
18
18
  * by hand. Nothing at runtime reads it. */
19
19
  $schema: z.string().optional().describe("The authoring schema, for editor completion and validation. Nothing at runtime reads it."),
20
20
  publisher: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
21
21
  name: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
22
- // The extension's own semver — display/identity only; the installed code identity is the pinned commit sha.
22
+ // The extension's own semver, display/identity only; the installed code identity is the pinned commit sha.
23
23
  version: z.string().min(1).describe("Your own semver — display and identity only. The installed code's identity is the pinned commit sha."),
24
- /* The section this extension sits under in the Sandbox hub's Extensions tab — a grouping by what it is FOR,
24
+ /* The section this extension sits under in the Sandbox hub's Extensions tab, a grouping by what it is FOR,
25
25
  * declared because it cannot be derived. Nine of the first-party extensions contribute a rail tile, so a
26
26
  * grouping read off `contributes` puts more than half the list in one section and says nothing about any of
27
27
  * them. Deliberately a loose string, exactly like a connector's `catalog.category`: the vocabulary belongs
@@ -34,13 +34,13 @@ export const ExtensionManifestSchema = z.object({
34
34
  .describe(
35
35
  "Which section of the Extensions tab this sits under — a grouping by what it is FOR, which cannot be derived from what it contributes. A section this app has never heard of lands in “Other” rather than failing to install.",
36
36
  ),
37
- /* What the extension is drawn as wherever it is LISTED rather than used — the Extensions tab, a registry
37
+ /* What the extension is drawn as wherever it is LISTED rather than used, the Extensions tab, a registry
38
38
  * being browsed, the gallery. Deliberately here and not on a view: `Activation.icon` is the glyph of one
39
39
  * rail tile, it only exists once the extension's code has activated in this browser, and nine of the
40
40
  * first-party extensions register no view at all. An extension that is switched off, daemon-only, or not
41
41
  * yet installed still has to look like something. See MARK_FIELDS. */
42
42
  ...MARK_FIELDS,
43
- // Semver range over the host's extension API version (extensionApiVersion) — checked before activation.
43
+ // Semver range over the host's extension API version (extensionApiVersion), checked before activation.
44
44
  engines: z
45
45
  .object({ intentic: z.string().min(1) })
46
46
  .describe("A semver range over the host's extension API version, checked before your code is activated."),
@@ -54,7 +54,7 @@ export const ExtensionManifestSchema = z.object({
54
54
  .describe(
55
55
  "Repo-relative path of your prebuilt single-file ESM bundle, built with `vue` and `@intentic/extension-api` as externals. Absent ⇒ an extension with no UI.",
56
56
  ),
57
- /* Repo-relative path of the prebuilt single-file node ESM SERVER bundle — the extension's BACKEND half,
57
+ /* Repo-relative path of the prebuilt single-file node ESM SERVER bundle, the extension's BACKEND half,
58
58
  * exporting `activateServer(api, context)`. Loaded by the daemon's backend host (a separate supervised
59
59
  * process, so a toggle or a live edit is a host restart rather than a daemon death) and served under the
60
60
  * extension's own route namespace `/x/<id>/…`, which the daemon proxies. Self-contained by construction:
@@ -68,12 +68,12 @@ export const ExtensionManifestSchema = z.object({
68
68
  .describe(
69
69
  "Repo-relative path of your prebuilt single-file node ESM server bundle, exporting `activateServer`. Served under your own route namespace, which the daemon proxies. Nothing is provided at runtime but node builtins, so bundle everything else in. Absent ⇒ no backend.",
70
70
  ),
71
- // Declared reach, both halves in one grammar — "<METHOD> <path-glob>" where `*` matches one path segment
72
- // (e.g. "GET /panels", "POST /panels/*/start") — so the install dialog, the gate and the usage ledger read
71
+ // Declared reach, both halves in one grammar, "<METHOD> <path-glob>" where `*` matches one path segment
72
+ // (e.g. "GET /panels", "POST /panels/*/start"), so the install dialog, the gate and the usage ledger read
73
73
  // one vocabulary.
74
- // sandbox — the daemon routes the UI half may call through api.sandbox (the host refuses undeclared
74
+ // sandbox, the daemon routes the UI half may call through api.sandbox (the host refuses undeclared
75
75
  // ones). An extension's OWN namespace `/x/<its id>/…` needs no entry: its backend is its own.
76
- // daemon — the daemon routes the SERVER half may call through api.daemon, enforced by the daemon's
76
+ // daemon , the daemon routes the SERVER half may call through api.daemon, enforced by the daemon's
77
77
  // extension-token grant. Separate from `sandbox` because the halves run as different
78
78
  // principals: the UI acts with the owner's session, the backend with a minted per-extension
79
79
  // token, and a grant to one must never quietly widen the other.
@@ -99,6 +99,6 @@ export const ExtensionManifestSchema = z.object({
99
99
  });
100
100
  export type ExtensionManifest = z.infer<typeof ExtensionManifestSchema>;
101
101
 
102
- // The extension's identity everywhere (capability entries, /ext routes, settings namespaces) — derived, never
102
+ // The extension's identity everywhere (capability entries, /ext routes, settings namespaces), derived, never
103
103
  // declared, so it can't contradict the publisher/name the install dialog showed.
104
104
  export const extensionIdOf = (manifest: Pick<ExtensionManifest, "publisher" | "name">): string => `${manifest.publisher}.${manifest.name}`;
package/src/mark.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
 
3
- /* HOW SOMETHING LOOKS BEFORE ANY OF ITS CODE RUNS — the mark a capability card and an extension are drawn
3
+ /* HOW SOMETHING LOOKS BEFORE ANY OF ITS CODE RUNS, the mark a capability card and an extension are drawn
4
4
  * with, in ONE shape because one component draws both (<BrandMark>) and a second copy of these two fields is a
5
5
  * second answer to what happens when a slug 404s.
6
6
  *
@@ -8,7 +8,7 @@ import { z } from "zod";
8
8
  * author controls completely, and the only one that can make a grid of unfamiliar names look like a shelf of
9
9
  * distinct products rather than a column of identical glyphs. `logo` is a simple-icons slug fetched from a
10
10
  * CDN: exactly right for a card standing in for somebody else's product (GitHub, Postgres, Slack), useless
11
- * for the many things that have no brand in that set, and unreachable in an offline sandbox — so it can never
11
+ * for the many things that have no brand in that set, and unreachable in an offline sandbox, so it can never
12
12
  * be the only tier. `icon` is a name from the host's own bundled vocabulary, which ships in the image, follows
13
13
  * the theme and costs no request; it is what carries a first-party extension that has not been drawn yet. What
14
14
  * declares none of them is drawn as its initials, so no row is ever blank and no author is obliged to have a
@@ -16,15 +16,15 @@ import { z } from "zod";
16
16
  *
17
17
  * ART BEATS A BRAND SLUG because they answer different questions. A slug says "this is Slack"; art says "this
18
18
  * is mine". An extension that stands in for somebody else's product should declare the slug and no art, and
19
- * one that is its own thing should declare art — but where both arrive, the author's own drawing is the more
19
+ * one that is its own thing should declare art, but where both arrive, the author's own drawing is the more
20
20
  * specific claim and wins.
21
21
  *
22
22
  * Artwork that will not parse, a slug that fails to load and an icon name this build has never heard of all
23
- * fall to the tier BELOW rather than to a hole — the rule the rail already applies to Activation.icon, here for
23
+ * fall to the tier BELOW rather than to a hole, the rule the rail already applies to Activation.icon, here for
24
24
  * the surfaces that must draw an extension whose code is not running: one that is switched off, one that is
25
25
  * daemon-only, one being read about in a registry before it is installed at all. */
26
26
 
27
- /* Big enough for a drawn mark, far too small for a traced photograph — which is the line being drawn. This
27
+ /* Big enough for a drawn mark, far too small for a traced photograph, which is the line being drawn. This
28
28
  * string rides every registry row and every manifest read, so it is a budget as much as a limit: at 4 KB the
29
29
  * whole official registry's artwork costs less than one screenshot, and an author who needs more than that is
30
30
  * shipping a raster they should be shipping as a brand slug or not at all. */
@@ -33,18 +33,18 @@ const ART_MAX_BYTES = 4096;
33
33
  export const MARK_FIELDS = {
34
34
  /* THE SVG DOCUMENT ITSELF, not a URL and not base64.
35
35
  *
36
- * A URL would put a stranger's server in the render path of a page listing extensions — a fetch that
36
+ * A URL would put a stranger's server in the render path of a page listing extensions, a fetch that
37
37
  * tracks who is browsing what, breaks in an offline sandbox, and 404s long after the row was approved:
38
38
  * the three failures the `logo` tier already documents, with none of its excuse. Inline costs one string
39
39
  * and always draws.
40
40
  *
41
41
  * Kept as READABLE TEXT rather than a data URI because of who reads it. The registry's curated file is
42
42
  * reviewed by a human before anything is published, and `<rect fill="#5B4FE9"/><circle .../>` can be read
43
- * in a diff, while base64 is a wall nobody checks — an opaque blob in the one file whose entire purpose is
43
+ * in a diff, while base64 is a wall nobody checks, an opaque blob in the one file whose entire purpose is
44
44
  * to be checked. The renderer does its own encoding at the point of use.
45
45
  *
46
46
  * It is drawn INERT (an <img>, never inline in the document), so a hostile registry row cannot script the
47
- * page it is listed on — see <BrandMark>, which owns that guarantee and the sniff test that enforces it. */
47
+ * page it is listed on, see <BrandMark>, which owns that guarantee and the sniff test that enforces it. */
48
48
  art: z
49
49
  .string()
50
50
  .max(ART_MAX_BYTES)
@@ -1,6 +1,6 @@
1
1
  /* The sandbox-route permission model. An extension declares in its manifest exactly which daemon routes it may
2
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
3
+ * segment. The host matches every call against these and refuses an undeclared route, so an extension's backend
4
4
  * reach is explicit, diffable, and reviewable rather than an ambient client to the whole daemon. */
5
5
 
6
6
  const escapeRegExp = (literal: string): string => literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import type { ContributionPoint } from "../contribution-point.js";
3
3
 
4
4
  // "This checkout is ALSO a Claude Code plugin": the daemon hands the directory to the Agent SDK's plugin
5
- // loader, which reads skills/agents/hooks/commands/.mcp.json each turn — the daemon never parses plugin
5
+ // loader, which reads skills/agents/hooks/commands/.mcp.json each turn, the daemon never parses plugin
6
6
  // internals.
7
7
  export const AgentContributionSchema = z.object({
8
8
  path: z.string().optional().describe("Relative to the extension checkout. Absent ⇒ the checkout root."),
@@ -1,12 +1,12 @@
1
1
  import { z } from "zod";
2
2
  import type { ContributionPoint } from "../contribution-point.js";
3
3
 
4
- /* A STARTING POINT in the automation composer — a trigger, a prompt written for that trigger's payload, and
4
+ /* A STARTING POINT in the automation composer, a trigger, a prompt written for that trigger's payload, and
5
5
  * whatever guard or hold makes it safe to leave on. Pure prefill: creating one makes an ordinary automation and
6
6
  * the daemon knows nothing about templates afterwards.
7
7
  *
8
8
  * IT LIVES WITH THE AREA THAT KNOWS THE SERVICE, which is the point of it being a contribution at all. The
9
- * automation surface used to carry every one of these — Komodo's, Sentry's, Stripe's, CI's, the chore book's —
9
+ * automation surface used to carry every one of these. Komodo's, Sentry's, Stripe's, CI's, the chore book's,
10
10
  * so a pack that gained something worth reacting to could not say so without an edit to a surface it has
11
11
  * nothing to do with. A template declared here appears when the pack is installed and its capability connected,
12
12
  * and disappears with it.
@@ -14,7 +14,7 @@ import type { ContributionPoint } from "../contribution-point.js";
14
14
  * The daemon validates each one against the real trigger schema when it builds the catalogue and drops what
15
15
  * does not parse, so a template can never offer a trigger that `upsert` would refuse. */
16
16
  export const AutomationTemplateContributionSchema = z.object({
17
- // Prefills the automation name, and is what "does one of these exist already" is asked by — so it must be
17
+ // Prefills the automation name, and is what "does one of these exist already" is asked by, so it must be
18
18
  // spelled as an automation id, not as prose.
19
19
  id: z
20
20
  .string()
@@ -23,7 +23,7 @@ export const AutomationTemplateContributionSchema = z.object({
23
23
  title: z.string().min(1),
24
24
  logo: z.string().min(1).optional().describe("A simple-icons slug for the card."),
25
25
  icon: z.string().min(1).optional().describe("A name from the host's icon set, drawn when no simple-icons slug fits."),
26
- // Capability providers that make this template WORK — any one connected is enough (fixing CI rides github
26
+ // Capability providers that make this template WORK, any one connected is enough (fixing CI rides github
27
27
  // or gitlab). Omitted ⇒ nothing to connect, always offered.
28
28
  requires: z
29
29
  .array(z.string().min(1))
package/src/points/bin.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import type { ContributionPoint } from "../contribution-point.js";
3
3
 
4
- // A checkout-relative directory of executables the daemon prepends to the AGENT's PATH each turn — how an
4
+ // A checkout-relative directory of executables the daemon prepends to the AGENT's PATH each turn, how an
5
5
  // extension ships a command-line tool for the agent (the CLI-tools path). The files ARE the approved code (they
6
6
  // ride the sha-pinned checkout); the daemon only adds the dir to PATH.
7
7
  export const binPoint = {
@@ -13,7 +13,7 @@ export const CapabilityFieldSchema = z.object({
13
13
  secret: z.boolean().optional().describe("Mask it, and never echo it back."),
14
14
  optional: z.boolean().optional(),
15
15
  multiline: z.boolean().optional(),
16
- // An OPT-IN EXTRA rather than a decision — rendered as a switch, carried as the "on"/"off" the config
16
+ // An OPT-IN EXTRA rather than a decision, rendered as a switch, carried as the "on"/"off" the config
17
17
  // schemas already speak (the vpn's pfs/aggressive precedent). A two-option Segmented can express the same
18
18
  // value, and reads wrong for this: it presents a choice the user must make to proceed, sized like the
19
19
  // required fields around it. Something the capability works fine without wants the control that is quiet
@@ -34,7 +34,7 @@ export const CapabilityFieldSchema = z.object({
34
34
  .describe(
35
35
  "A line under this control, for what the label alone cannot say — a host requirement, when a value takes effect. The card's own `hint` speaks for the whole card; this one is bound to the field it qualifies.",
36
36
  ),
37
- /* This field's value only takes effect after the sandbox is REBUILT — it rides the environment overlay
37
+ /* This field's value only takes effect after the sandbox is REBUILT, it rides the environment overlay
38
38
  * rather than something the daemon can act on now. Rendered as a chip beside the label.
39
39
  *
40
40
  * The one fact a user needs before touching a control, and the one the form cannot infer: two switches
@@ -52,12 +52,12 @@ export const CapabilityFieldSchema = z.object({
52
52
  .array(z.object({ value: z.string(), label: z.string() }))
53
53
  .optional()
54
54
  .describe("Turns the field into a select."),
55
- /* Gates this field on the answers already given — the SSH credential that only applies to the auth mode
55
+ /* Gates this field on the answers already given, the SSH credential that only applies to the auth mode
56
56
  * chosen, the gateway fields that belong to one VPN provider. A `when` condition (@intentic/base/when)
57
57
  * evaluated against the form's live values, so it re-reads as the user toggles.
58
58
  *
59
59
  * Refused at parse when it does not parse. A card is data an extension ships, and a condition nobody can
60
- * evaluate is not a field that is always shown or always hidden — it is a card whose author believes it
60
+ * evaluate is not a field that is always shown or always hidden, it is a card whose author believes it
61
61
  * asks something it never asks. Failing the manifest names the card; failing at render names nothing. */
62
62
  when: z
63
63
  .string()
@@ -66,7 +66,7 @@ export const CapabilityFieldSchema = z.object({
66
66
  .describe(
67
67
  "Only show this field while a condition over the answers already given holds — `auth == 'key'`, `provider in ['ipsec', 'fortinet']`, `!advanced`. Supports `&&`, `||`, `!`, comparisons and `in`.",
68
68
  ),
69
- // A fixed value baked into the config rather than asked for — how a card pins a discriminator
69
+ // A fixed value baked into the config rather than asked for, how a card pins a discriminator
70
70
  // (platform="reddit", provider="stripe"). Rendered as nothing; sent as itself.
71
71
  value: z
72
72
  .string()
@@ -74,9 +74,9 @@ export const CapabilityFieldSchema = z.object({
74
74
  .describe(
75
75
  'A fixed value baked into the config rather than asked for — how a card pins its discriminator (platform="reddit", provider="stripe"). Renders as nothing.',
76
76
  ),
77
- /* This field holds a TOTP seed — the base32 key (or otpauth:// URI) a service shows when enrolling an
77
+ /* This field holds a TOTP seed, the base32 key (or otpauth:// URI) a service shows when enrolling an
78
78
  * authenticator app. Declare it WITH `secret: true`: the seed is a durable second factor, so it is never
79
- * echoed and, unlike an ordinary secret, never enters the agent's environment either — the daemon mints the
79
+ * echoed and, unlike an ordinary secret, never enters the agent's environment either, the daemon mints the
80
80
  * six-digit codes on demand (`otp <name>` / GET /capabilities/<id>/otp) and only those cross, each dead
81
81
  * within its period. A cli entry whose env references a totp field therefore fails to parse (see below). */
82
82
  totp: z
@@ -88,7 +88,7 @@ export const CapabilityFieldSchema = z.object({
88
88
  });
89
89
  export type CapabilityField = z.infer<typeof CapabilityFieldSchema>;
90
90
 
91
- /* WHETHER A FIELD IS IN PLAY, given what has been answered so far — and the only place that decides it.
91
+ /* WHETHER A FIELD IS IN PLAY, given what has been answered so far, and the only place that decides it.
92
92
  *
93
93
  * Two tiers ask this question about the same card. The web's form asks it to decide what to draw and what to
94
94
  * validate; the daemon asks it at install to decide which fields it may demand. They used to answer it with
@@ -98,7 +98,7 @@ export type CapabilityField = z.infer<typeof CapabilityFieldSchema>;
98
98
  * report about one card rather than as a broken rule.
99
99
  *
100
100
  * It lives beside the schema for the reason the description does: this is a fact about the shape, and the two
101
- * consumers are in different packages. Parsed per call rather than cached — a card has a handful of fields,
101
+ * consumers are in different packages. Parsed per call rather than cached, a card has a handful of fields,
102
102
  * this runs on a keystroke at worst, and a cache keyed by manifest strings is a map that outlives every
103
103
  * extension that ever declared one. */
104
104
  export const fieldApplies = (field: CapabilityField, values: Readonly<Record<string, unknown>>): boolean =>
@@ -109,7 +109,7 @@ export const fieldApplies = (field: CapabilityField, values: Readonly<Record<str
109
109
  const CatalogSchema = z.object({
110
110
  name: z.string().min(1),
111
111
  ...MARK_FIELDS,
112
- // ONE LINE — aim for 60 characters or fewer. The grid clamps this at two lines and a card sits beside two
112
+ // ONE LINE, aim for 60 characters or fewer. The grid clamps this at two lines and a card sits beside two
113
113
  // others in a pane the index column has already taken 16rem out of, so a paragraph here is a paragraph the
114
114
  // reader gets truncated. Everything longer belongs in `hint`, which the config form prints in full and the
115
115
  // catalog's search reads. Not capped in the schema: an extension published before this rule should still
@@ -121,7 +121,7 @@ const CatalogSchema = z.object({
121
121
  "ONE LINE — aim for 60 characters or fewer. The grid clamps it at two lines in a narrow pane, so a paragraph here is a paragraph the reader gets truncated. Everything longer belongs in `hint`.",
122
122
  ),
123
123
  category: z.string().min(1),
124
- // The paragraph. Shown under the add-form, and searched from the catalog — so the words that identify this
124
+ // The paragraph. Shown under the add-form, and searched from the catalog, so the words that identify this
125
125
  // card to someone hunting for it ("webauthn", "socket mode") belong here even when the tile can't show them.
126
126
  hint: z
127
127
  .string()
@@ -151,20 +151,24 @@ const contributionBase = {
151
151
  fields: z.array(CapabilityFieldSchema),
152
152
  };
153
153
 
154
- /* A CAPABILITY CARD AS DATA. The catalog is the extensible layer; the HANDLERS are core — so an entry names one
154
+ /* A CAPABILITY CARD AS DATA. The catalog is the extensible layer; the HANDLERS are core, so an entry names one
155
155
  * of the kinds whose daemon-side machinery is fully generic over its data, and the machinery stays put. The
156
156
  * kinds NOT listed here are the ones whose card is one-to-one with a handler that owns real privilege (`docker`
157
157
  * bakes --privileged, `vpn` bakes NET_ADMIN, `extension` installs extensions, `devops` scaffolds repos): their
158
158
  * cards live in the platform catalog because separating card from handler would split one concept in two, and
159
159
  * because a manifest that could name them would be a manifest that grants itself privilege. That restriction is
160
- * this discriminated union, not a comment — a manifest naming any other kind fails to parse.
160
+ * this discriminated union, not a comment, a manifest naming any other kind fails to parse.
161
161
  *
162
- * `${id}` in a skill file is substituted with the instance name at apply time (so a host pack's tool names read
163
- * `mcp__my-laptop__run_command`), and, for `cli`, each `$ENVVAR` becomes its per-instance suffixed name. */
162
+ * `${id}` in a cli/host skill file is substituted with the instance name at apply time (so a host pack's tool
163
+ * names read `mcp__my-laptop__run_command`), and, for `cli`, each `$ENVVAR` becomes its per-instance suffixed
164
+ * name. A BROWSER pack's skill renders once per SITE rather than per instance, its seams are `${accounts}`
165
+ * (the roster of connected accounts), `${tools}` (the core driving/connecting note) and `${site}` (the host,
166
+ * for the generic card whose text can name no site of its own); `${id}` and per-field substitution do not
167
+ * apply there (capabilities/account-skills.ts in the sandbox daemon). */
164
168
  export const CapabilityContributionSchema = z
165
169
  .discriminatedUnion("kind", [
166
170
  // A CLI tool the AGENT gets, authenticated: the env vars its shell receives (value templates over the
167
- // fields — `${field}` substitutes, `${field:uri}` percent-encodes), a SKILL.md cheatsheet, and an optional
171
+ // fields, `${field}` substitutes, `${field:uri}` percent-encodes), a SKILL.md cheatsheet, and an optional
168
172
  // image fragment holding the client binary (psql, mysql, whisper).
169
173
  z.object({
170
174
  ...contributionBase,
@@ -187,18 +191,18 @@ export const CapabilityContributionSchema = z
187
191
  }),
188
192
  /* A site the agent acts on AS THE OWNER, through the shared logged-in Chromium. `loginUrl` is what the
189
193
  * sign-in window opens; the profile it persists is the credential. `homeUrl` is where that same profile
190
- * opens once it HAS one — the owner's own hands on the connected browser, which a login page is the wrong
194
+ * opens once it HAS one, the owner's own hands on the connected browser, which a login page is the wrong
191
195
  * place to start (signed in, it only redirects). Two fields because for some platforms the login lives on
192
196
  * another site entirely (YouTube signs in at accounts.google.com), so one cannot be derived from the other.
193
197
  * No `env` and no `fragment`: the browser itself is core (one Chromium install serves every platform),
194
- * only the identity is per-entry. A card never declares the account's username/password either — those are
198
+ * only the identity is per-entry. A card never declares the account's username/password either, those are
195
199
  * CORE form fields on every browser card (the catalog appends them; the daemon's add validation accepts
196
200
  * them), because which box a login form wants filled is the same fact on every site.
197
201
  *
198
202
  * BOTH URLs ARE OPTIONAL, so that one card can be the GENERIC one: a site card pins them (Reddit knows
199
203
  * where Reddit signs in), and the generic "browser session" card asks for them on its form instead, which
200
- * is what lets a user connect a site nobody shipped a card for. A card must do one or the other — pin a
201
- * URL or declare a field that supplies it — and the daemon's apply says so on the form when neither does,
204
+ * is what lets a user connect a site nobody shipped a card for. A card must do one or the other, pin a
205
+ * URL or declare a field that supplies it, and the daemon's apply says so on the form when neither does,
202
206
  * because the alternative is a sign-in window that opens on nothing. */
203
207
  z.object({
204
208
  ...contributionBase,
@@ -215,9 +219,14 @@ export const CapabilityContributionSchema = z
215
219
  .describe(
216
220
  "Where that same profile opens once it HAS a session — the owner's own hands on the connected browser. Separate from loginUrl because for some platforms the login lives on another site entirely (YouTube signs in at accounts.google.com).",
217
221
  ),
218
- skill: z.string().min(1).describe("Checkout-relative SKILL.md teaching the agent this site's actions."),
222
+ skill: z
223
+ .string()
224
+ .min(1)
225
+ .describe(
226
+ "Checkout-relative SKILL.md teaching the agent this site's actions — rendered once per site, all its connected accounts on one roster (`${accounts}`), the core tool note at `${tools}`.",
227
+ ),
219
228
  }),
220
- // An operating system a connected computer can run — the skill pack that teaches the agent THAT machine's
229
+ // An operating system a connected computer can run, the skill pack that teaches the agent THAT machine's
221
230
  // shell. The enrollment, the socket and the scope enforcement are core; only the pack varies.
222
231
  z.object({
223
232
  ...contributionBase,
@@ -225,13 +234,13 @@ export const CapabilityContributionSchema = z
225
234
  skill: z.string().min(1).describe("Checkout-relative SKILL.md teaching the agent that machine's shell."),
226
235
  }),
227
236
  /* A PRESET over a core kind: no payload at all, just a named card whose `fields` carry the defaults. What an
228
- * ACP agent needs is a command, so "OpenCode" is entirely a name, a logo and a filled-in form — which is
237
+ * ACP agent needs is a command, so "OpenCode" is entirely a name, a logo and a filled-in form, which is
229
238
  * exactly what a catalog row is. */
230
239
  z.object({ ...contributionBase, kind: z.literal("agent") }),
231
240
  ])
232
241
  .superRefine((spec, ctx) => {
233
242
  // The totp flag's one invariant, enforced where the manifest is parsed rather than trusted to authors: a
234
- // seed the daemon mints codes from must never ride the env into the agent's shell — that would hand the
243
+ // seed the daemon mints codes from must never ride the env into the agent's shell, that would hand the
235
244
  // agent the second factor itself instead of one expiring code at a time.
236
245
  if (spec.kind !== "cli") {
237
246
  return;
@@ -246,15 +255,15 @@ export const CapabilityContributionSchema = z
246
255
  }
247
256
  });
248
257
  export type CapabilityContribution = z.infer<typeof CapabilityContributionSchema>;
249
- // The arms carrying a per-instance SKILL.md — the daemon templates and installs these identically.
258
+ // The arms carrying a per-instance SKILL.md, the daemon templates and installs these identically.
250
259
  export type SkillContribution = Extract<CapabilityContribution, { skill: string }>;
251
260
 
252
261
  /* The config key a kind's cards PIN to their own id, so a stored capability can be traced back to the card that
253
- * made it — the daemon resolves the entry's handler data through it, and the web tells one card's instances from
262
+ * made it, the daemon resolves the entry's handler data through it, and the web tells one card's instances from
254
263
  * another's. `agent` has none on purpose: its cards are presets over one config shape, differing only in their
255
264
  * defaults, so every agent instance belongs to every agent card equally.
256
265
  *
257
- * Here, beside the schema, because it is a fact about the contribution shape — the daemon, the catalog and the
266
+ * Here, beside the schema, because it is a fact about the contribution shape, the daemon, the catalog and the
258
267
  * web all need it, and three copies of it is three chances for a card's instances to go missing. `satisfies`
259
268
  * rather than a lookup table so a new arm above is a compile error until this answers for it. */
260
269
  const DISCRIMINATOR = { cli: "provider", browser: "platform", host: "platform", agent: undefined } satisfies Record<
@@ -9,7 +9,7 @@ export const CommandContributionSchema = z.object({
9
9
  icon: z.string().optional().describe("A name from the host's icon set, drawn beside the title."),
10
10
  // An optional global keyboard shortcut, in the host's chord notation (`Mod`/`Ctrl`/`Shift`/`Alt` + key, e.g.
11
11
  // "Mod+Shift+K"; `Mod` = ⌘ on Apple, Ctrl elsewhere). It is DECLARED here so it rides the install dialog's
12
- // approval surface — a global shortcut is consequential, so like title/icon the manifest value is authoritative
12
+ // approval surface, a global shortcut is consequential, so like title/icon the manifest value is authoritative
13
13
  // and the host binds only what was approved. Whitespace-free; an unparseable chord simply never fires.
14
14
  keybinding: z
15
15
  .string()
@@ -18,12 +18,12 @@ export const CommandContributionSchema = z.object({
18
18
  .describe(
19
19
  'A global keyboard shortcut, e.g. "Mod+Shift+K" — `Mod` is ⌘ on Apple and Ctrl elsewhere. Declared here because a global shortcut is consequential: the owner approves it at install, and the host binds only what was approved.',
20
20
  ),
21
- /* When the KEYBINDING applies — a condition over the shell's context keys (`tabSurface == 'chat'`,
21
+ /* When the KEYBINDING applies, a condition over the shell's context keys (`tabSurface == 'chat'`,
22
22
  * `!editableTarget`; see @intentic/base/when). The palette ignores it: a command is always runnable by
23
23
  * name, and what a condition decides is whether the chord is claimed from whatever else would have had it.
24
24
  *
25
25
  * Declared here because it could not be declared anywhere. The shell's own commands used to gate on a
26
- * JavaScript predicate, which an extension has no way to ship — so every extension command took its chord
26
+ * JavaScript predicate, which an extension has no way to ship, so every extension command took its chord
27
27
  * globally, from every surface, including terminals where a bare key belongs to the program on the other
28
28
  * end. A condition an extension can write is what makes a contributed shortcut safe to grant. */
29
29
  when: z
@@ -2,11 +2,11 @@ import { z } from "zod";
2
2
  import type { ContributionPoint } from "../contribution-point.js";
3
3
 
4
4
  /* A per-directory document family the extension may register at runtime (api.documents.register): the provider
5
- * marks the directory rows it can explain in the Workspace tree, and the host opens its component as a tab —
5
+ * marks the directory rows it can explain in the Workspace tree, and the host opens its component as a tab,
6
6
  * see DocumentProviderRegistration.
7
7
  *
8
8
  * Only the id and the label are declared, deliberately. The consequential part of a viewer is which FILES it
9
- * takes over, and of a command its global shortcut — both are decided in the manifest because the owner must see
9
+ * takes over, and of a command its global shortcut, both are decided in the manifest because the owner must see
10
10
  * them. A document provider takes nothing over: it adds an icon to rows it has something for, and every one of
11
11
  * those rows is evidence the owner can see for themselves. So the manifest gates WHETHER the extension may mark
12
12
  * up the tree at all, and the per-row wording stays with the provider, which is the only thing that knows what
@@ -1,24 +1,24 @@
1
1
  import { z } from "zod";
2
2
  import type { ContributionPoint } from "../contribution-point.js";
3
3
 
4
- /* WHICH WORKSPACE FILE MAKES THIS EXTENSION'S VIEW STALE — the extension's half of the core's
4
+ /* WHICH WORKSPACE FILE MAKES THIS EXTENSION'S VIEW STALE, the extension's half of the core's
5
5
  * WORKSPACE_STATE_FILES table (@intentic/sandbox-contract), in the same two fields so the browser can union them
6
6
  * without translating.
7
7
  *
8
8
  * An intentic workspace is file-first: the agent edits /work with its own file tools, out of band from every
9
9
  * HTTP route, and the daemon's filesystem watcher is the ONLY thing that can tell a browser its view went stale.
10
- * Before this contribution point existed an extension had no way into that push, so every one of them polled —
10
+ * Before this contribution point existed an extension had no way into that push, so every one of them polled,
11
11
  * and the core's table had to hardcode `automations`/`automation-approvals`, query keys owned by an extension,
12
12
  * because the extension itself couldn't declare them. Declaring is now the extension's job and unioning is the
13
13
  * host's.
14
14
  *
15
15
  * It rides the manifest rather than a runtime api.workspace.onDidChangeFiles for two reasons: the owner sees at
16
- * install which of their files an extension reads, and there is nothing imperative left to get wrong — no
16
+ * install which of their files an extension reads, and there is nothing imperative left to get wrong, no
17
17
  * subscribe, no unsubscribe, no listener that quietly stops firing. */
18
18
  export const FileContributionSchema = z.object({
19
- /* Workspace-root-relative, forward-slash — the space the watcher's changed paths arrive in. Matched by
19
+ /* Workspace-root-relative, forward-slash, the space the watcher's changed paths arrive in. Matched by
20
20
  * PREFIX, so one entry covers an exact file (`.intentic/config/automations.json`), a directory (`.intentic/config/drafts/`
21
- * — keep the trailing slash so it cannot match a sibling file) or a name family (`.intentic/environment.`).
21
+ *, keep the trailing slash so it cannot match a sibling file) or a name family (`.intentic/environment.`).
22
22
  * Deliberately not a glob: prefix is the whole matching rule on both sides of this union. */
23
23
  path: z
24
24
  .string()
@@ -29,14 +29,14 @@ export const FileContributionSchema = z.object({
29
29
  .describe(
30
30
  "Workspace-root-relative, forward-slash, matched by prefix — so one entry covers an exact file (`.intentic/config/automations.json`), a directory (`.intentic/config/drafts/`, with the trailing slash so it cannot match a sibling file) or a name family (`.intentic/environment.`). Not a glob.",
31
31
  ),
32
- /* The browser query keys those contents feed — the first element of the extension's own
32
+ /* The browser query keys those contents feed, the first element of the extension's own
33
33
  * `api.sandbox.key(...)` keys, which is what makes them match (the sandbox id is a SUFFIX). Empty is not
34
34
  * allowed: a path that makes nothing stale is a declaration with no effect, and saying so at install beats
35
35
  * discovering it as a view that never refreshes.
36
36
  *
37
37
  * Keep the paths as narrow as the view actually needs. A broad prefix costs every connected browser a
38
38
  * refetch per matching write, and a write-heavy path (an index, a transcript, a log) turns that into a
39
- * request storm — the reason the core table leaves the daemon's own machine state off the push entirely. */
39
+ * request storm, the reason the core table leaves the daemon's own machine state off the push entirely. */
40
40
  invalidates: z
41
41
  .array(z.string().min(1))
42
42
  .min(1)
@@ -30,14 +30,14 @@ export * from "./views.js";
30
30
 
31
31
  /* EVERYTHING A MANIFEST MAY DECLARE. `contributes` is assembled from this list (manifest.ts), the authoring
32
32
  * JSON Schema is generated from it (json-schema.ts), and the SDK's surface guard reads the point names back out
33
- * of it — so the three cannot disagree about what this build supports.
33
+ * of it, so the three cannot disagree about what this build supports.
34
34
  *
35
35
  * Collected explicitly rather than by a module-load side effect, because two readers need the answer to be the
36
36
  * same every time it is asked: the wire contract's lock file, which is a committed document a diff has to be
37
37
  * able to guard, and the generated schema, which is committed too. A registry that filled itself as modules
38
38
  * happened to load would make both of those depend on import order.
39
39
  *
40
- * Adding a point is a file in this directory and a line here — points.test.ts fails when a file appears without
40
+ * Adding a point is a file in this directory and a line here, points.test.ts fails when a file appears without
41
41
  * the line, so the pair cannot come apart. */
42
42
  export const CONTRIBUTION_POINTS = [
43
43
  viewsPoint,
@@ -56,13 +56,13 @@ export const CONTRIBUTION_POINTS = [
56
56
  ] as const satisfies readonly ContributionPoint[];
57
57
 
58
58
  // The `contributes` shape those points assemble to: each point's key, its schema, optional. A mapped type
59
- // rather than a widened record so `manifest.contributes.views` keeps its exact type at every call site — the
59
+ // rather than a widened record so `manifest.contributes.views` keeps its exact type at every call site, the
60
60
  // whole point of the schema being typed at all.
61
61
  type ContributesShape = {
62
62
  [Point in (typeof CONTRIBUTION_POINTS)[number] as Point["name"]]: z.ZodOptional<Point["schema"]>;
63
63
  };
64
64
 
65
- /* The `contributes` object, assembled rather than hand-written — which is what makes adding a point a file plus
65
+ /* The `contributes` object, assembled rather than hand-written, which is what makes adding a point a file plus
66
66
  * a line above, instead of an edit to a schema thirteen unrelated features share.
67
67
  *
68
68
  * Each point's description rides `z.describe` onto its own key, so it survives into the generated authoring
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import type { ContributionPoint } from "../contribution-point.js";
3
3
 
4
- // One narrowing field the generic automation editor draws for a source — a channel, a branch. `hint` is the
4
+ // One narrowing field the generic automation editor draws for a source, a channel, a branch. `hint` is the
5
5
  // sentence under the input, for a filter whose empty case is easy to get wrong.
6
6
  const TriggerFieldContributionSchema = z.object({
7
7
  label: z.string().min(1),
@@ -15,12 +15,12 @@ const TriggerFieldContributionSchema = z.object({
15
15
  * the provider extension is what lets a newly installed listener become configurable without a matching app
16
16
  * release.
17
17
  *
18
- * The daemon serves a provider-scoped control surface — GET /listeners/<provider>/state to reconcile, POST
18
+ * The daemon serves a provider-scoped control surface. GET /listeners/<provider>/state to reconcile, POST
19
19
  * …/dispatch to wake an automation (optionally holding a turn-stream), …/failure + …/status to report. The
20
20
  * daemon holds no provider connection itself.
21
21
  *
22
22
  * WHAT DISPATCHES IT IS OPEN. A gateway process (contributes.processes) is the usual answer and the one the
23
- * reconcile feed is shaped for — it holds a live connection the daemon must not. But an extension BACKEND can
23
+ * reconcile feed is shaped for, it holds a live connection the daemon must not. But an extension BACKEND can
24
24
  * dispatch through the same route by declaring the dispatch path in `permissions.daemon`, which is
25
25
  * how an area that learns things on its own schedule (an estate poller noticing a container died) contributes
26
26
  * a trigger without running a gateway at all. Declaring this with neither is legal and inert: the source is
@@ -55,7 +55,7 @@ export const ListenerContributionSchema = z.object({
55
55
  "Only for a source whose message events distinguish being addressed. Absent ⇒ the editor offers no mention-only filter, rather than inventing semantics you did not promise.",
56
56
  ),
57
57
  channel: TriggerFieldContributionSchema.describe("The primary narrowing filter — a channel, a room, a repo."),
58
- // A SECOND narrowing axis, for a source whose events carry one — a pipeline's git ref, so a trigger can
58
+ // A SECOND narrowing axis, for a source whose events carry one, a pipeline's git ref, so a trigger can
59
59
  // say "the branch that ships" rather than "every agent's every failure". Absent ⇒ the editor offers
60
60
  // only the channel filter.
61
61
  branchField: TriggerFieldContributionSchema.optional().describe(
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import type { ContributionPoint } from "../contribution-point.js";
3
3
 
4
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
5
+ * file to this viewer by extension, gets its content, and renders the registered component with it, the host
6
6
  * keeps the fetch + open-file lifecycle and the daemon credentials; the extension only renders. This is the
7
7
  * non-sidebar contribution point. */
8
8
  export const ViewerContributionSchema = z.object({
@@ -12,12 +12,12 @@ export const ViewerContributionSchema = z.object({
12
12
  .min(1)
13
13
  .describe('Bare file extensions, no dot — e.g. ["docx", "xlsx"].'),
14
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
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
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
18
+ * url , a streaming URL the component points an element at (`src` prop), never the bytes. For anything
19
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
20
+ * wants the header, the index and the seconds around the playhead, not the file. The host mints
21
21
  * the credential on that URL and keeps it out of the extension.
22
22
  */
23
23
  fetch: z
@@ -2,18 +2,18 @@ import type { ExtensionManifest } from "./manifest.js";
2
2
 
3
3
  /* WHAT AN UPDATE ASKS FOR, MECHANICALLY. The install dialog renders a manifest's contributions once; an update
4
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
5
+ * skip on the fifth update. So each manifest is folded to a set of POWERS, the consequential facts an owner
6
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
7
+ * PATH, what may interrupt from another screen, each under a stable key (the identity compared) with a plain
8
8
  * sentence (what the reader sees). The diff is set arithmetic over the keys.
9
9
  *
10
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
11
+ * version. A power's INTERNALS moving (a process's command line, a fragment's contents) keeps its key, the
12
12
  * code changed, which is what the sha pin and the agent diff-read answer for; this diff answers only "did the
13
13
  * set of things I approved grow". An empty `added` is what makes an update one click. */
14
14
 
15
15
  export interface PowersDiff {
16
- // Powers the new manifest declares that the installed one didn't — the reason an update re-asks.
16
+ // Powers the new manifest declares that the installed one didn't, the reason an update re-asks.
17
17
  readonly added: string[];
18
18
  readonly removed: string[];
19
19
  readonly unchanged: string[];
@@ -81,7 +81,7 @@ const powersOf = (manifest: ExtensionManifest): Map<string, string> => {
81
81
  };
82
82
 
83
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.
84
+ // the install dialog already renders, one vocabulary for both moments.
85
85
  export const diffPowers = (before: ExtensionManifest | undefined, after: ExtensionManifest): PowersDiff => {
86
86
  const from = before === undefined ? new Map<string, string>() : powersOf(before);
87
87
  const to = powersOf(after);