@intentic/extension-api 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.
- package/dist/api.d.ts +1 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -2
- package/src/api.ts +91 -81
- package/src/background.ts +13 -13
- package/src/diff.ts +11 -11
- package/src/engines.ts +1 -1
- package/src/facts.ts +7 -7
- package/src/host.ts +1 -1
- package/src/protocol.ts +4 -4
- package/src/route.ts +3 -3
- package/src/scope.ts +12 -12
- package/src/server.ts +15 -15
- package/src/stream.ts +3 -3
- package/src/surface.json +66 -0
- package/src/version.ts +19 -13
package/dist/api.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ export interface IntenticApi {
|
|
|
139
139
|
}): Promise<PickedModel | undefined>;
|
|
140
140
|
};
|
|
141
141
|
readonly navigate: (path: string) => void;
|
|
142
|
+
readonly href: (path: string) => string;
|
|
142
143
|
readonly route: {
|
|
143
144
|
query(): Readonly<Record<string, string>>;
|
|
144
145
|
setQuery(patch: Readonly<Record<string, string | undefined>>, options?: {
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const extensionApiVersion = "2.
|
|
1
|
+
export declare const extensionApiVersion = "2.9.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AA6DA,eAAO,MAAM,mBAAmB,UAAU,CAAC"}
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const extensionApiVersion = "2.
|
|
1
|
+
export const extensionApiVersion = "2.9.0";
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AA6DA,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAO,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentic/extension-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.224.0",
|
|
4
4
|
"description": "The versioned public API intentic extensions compile against — manifest schema, detection facts and the host API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@orpc/contract": "1.14.13",
|
|
46
46
|
"tslib": "2.8.1",
|
|
47
|
-
"@intentic/sandbox-contract": "1.
|
|
47
|
+
"@intentic/sandbox-contract": "1.224.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"vue": "3"
|
package/src/api.ts
CHANGED
|
@@ -13,15 +13,15 @@ export interface Disposable {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
// One sidebar element a view contributes: routed at /ext/<viewId>/<key> (the key segment is dropped when it
|
|
16
|
-
// equals the view id
|
|
16
|
+
// equals the view id, a singleton view links to /ext/<viewId>), rendered by the view's component with
|
|
17
17
|
// `repo` (+ props) bound.
|
|
18
18
|
export interface Activation {
|
|
19
|
-
// Stable per-view key (usually the repo name)
|
|
19
|
+
// Stable per-view key (usually the repo name), the route segment, so deep links survive reloads.
|
|
20
20
|
readonly key: string;
|
|
21
21
|
readonly title: string;
|
|
22
22
|
// An icon name from the host's icon set; absent ⇒ the rail renders the title's initials.
|
|
23
23
|
readonly icon?: string | undefined;
|
|
24
|
-
// The repo this element is rooted at
|
|
24
|
+
// The repo this element is rooted at, the fallback-dedup subject and the component's `repo` prop. Absent
|
|
25
25
|
// for capability-driven elements, which aren't rooted at any repo.
|
|
26
26
|
readonly repo?: string | undefined;
|
|
27
27
|
readonly props?: Record<string, unknown> | undefined;
|
|
@@ -34,39 +34,39 @@ export interface Activation {
|
|
|
34
34
|
// themselves to: it must mean "something happened here that you don't already know about", never "here is a
|
|
35
35
|
// statistic". A count that is lit most of the day teaches the user to stop seeing the rail.
|
|
36
36
|
export interface ViewBadge {
|
|
37
|
-
// How many, for work whose SIZE is what the user acts on
|
|
37
|
+
// How many, for work whose SIZE is what the user acts on, two files to review and two hundred are
|
|
38
38
|
// different afternoons. Omitted or 0 ⇒ no number. The host renders anything above 99 as "99+".
|
|
39
39
|
readonly count?: number | undefined;
|
|
40
40
|
// A glyph from the host's icon set, rendered INSTEAD of a number, for a pending action whose size changes
|
|
41
41
|
// nothing about what the user does with it: one click either way. "There is committed work here waiting to
|
|
42
|
-
// be sent" is the whole message, and a number beside it would be read in the unit `count` established
|
|
42
|
+
// be sent" is the whole message, and a number beside it would be read in the unit `count` established,
|
|
43
43
|
// so the amount goes in the tooltip and the glyph carries the kind. A badge with neither renders nothing.
|
|
44
44
|
readonly mark?: string | undefined;
|
|
45
45
|
// THE FIRST QUESTION A BADGE ANSWERS IS "DO I OWE THIS ANYTHING?", and until `neutral` existed there was no
|
|
46
46
|
// way to say no. A count that means "three things are alive in here" (open browsers, running services) was
|
|
47
|
-
// drawn exactly like one that means "three things are waiting on you"
|
|
47
|
+
// drawn exactly like one that means "three things are waiting on you", same pill, same tint, same digit,
|
|
48
48
|
// so a reader who chased one and found an inventory learned that badges do not repay being chased. That is
|
|
49
49
|
// the failure this vocabulary exists to prevent, arriving through the door it left open.
|
|
50
50
|
//
|
|
51
51
|
// `neutral` is an INVENTORY: true most of the day, nothing owed, quiet ink. `info` is the resting tone for
|
|
52
52
|
// work the user can act on (unread agents, uncommitted changes); `warning` marks a risk they are carrying
|
|
53
|
-
// (an exposed port); `danger` means something is BROKEN
|
|
53
|
+
// (an exposed port); `danger` means something is BROKEN, reach for it sparingly, its whole value is that it
|
|
54
54
|
// is rare enough to still mean something. Absent still means `info`, so a badge that says nothing about its
|
|
55
55
|
// tone is still assumed to be asking for something.
|
|
56
56
|
readonly tone?: "neutral" | "info" | "warning" | "danger" | undefined;
|
|
57
57
|
// Say what happened and how much, not just the number the user can already see. The host renders it
|
|
58
|
-
// AFTER the view's own name
|
|
58
|
+
// AFTER the view's own name, "Agents · 3 need you" on the rail, the chip's text in the mobile menu, so
|
|
59
59
|
// phrase it as the continuation of a label, not as a standalone sentence that repeats the view.
|
|
60
60
|
readonly tooltip?: string | undefined;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
/* ONE CACHED READ, described rather than performed
|
|
63
|
+
/* ONE CACHED READ, described rather than performed, the currency both `ViewRegistration.warm` and
|
|
64
64
|
* `api.sandbox.fetch` deal in.
|
|
65
65
|
*
|
|
66
66
|
* It is deliberately the shape a vue-query `useQuery` already takes, because that is the point: the entry a
|
|
67
67
|
* view warms, the entry its badge fills from a timer and the entry the view's own `useQuery` observes are ONE
|
|
68
68
|
* entry, and they are one entry because all three name it the same way. Two of the three used to be separate
|
|
69
|
-
* reads of the same route in this app's own extensions
|
|
69
|
+
* reads of the same route in this app's own extensions, the tile fetched the report every ten minutes and kept
|
|
70
70
|
* it privately, and the view it badged for started from nothing every time it was opened.
|
|
71
71
|
*
|
|
72
72
|
* The caching terms are optional and yours: `staleTime` is how long an answer stays believable without a
|
|
@@ -80,43 +80,43 @@ export interface HostQuery<T = unknown> {
|
|
|
80
80
|
readonly gcTime?: number | undefined;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
// A view's runtime registration
|
|
83
|
+
// A view's runtime registration, for third-party extensions, `id`, `label` and `surface` must match a
|
|
84
84
|
// `contributes.views` entry in the approved manifest or the host refuses the registration.
|
|
85
85
|
export interface ViewRegistration {
|
|
86
86
|
readonly id: string;
|
|
87
|
-
// The view family's human name (distinct from an Activation's per-repo `title`)
|
|
87
|
+
// The view family's human name (distinct from an Activation's per-repo `title`), labels the directory
|
|
88
88
|
// panel's surface switch when a repo activates several.
|
|
89
89
|
readonly label: string;
|
|
90
|
-
// Where the view's activations mount. `rail` is the always-visible left column
|
|
90
|
+
// Where the view's activations mount. `rail` is the always-visible left column, a place the user ACTS
|
|
91
91
|
// from, so a tile there must earn a permanently occupied slot. `directory` is a per-repo panel opened from
|
|
92
92
|
// the Workspace tree. `sandbox` is a tab on the Sandbox hub, where the subject is the box itself (its
|
|
93
|
-
// logs, its status, its consumption)
|
|
93
|
+
// logs, its status, its consumption), inspected occasionally rather than worked in, so it costs a tab in
|
|
94
94
|
// a scrolling word-labelled strip instead of an icon in the rail's fixed budget.
|
|
95
95
|
readonly surface: "rail" | "directory" | "sandbox";
|
|
96
|
-
/* Evidence-based detection over the public facts
|
|
96
|
+
/* Evidence-based detection over the public facts, one activation per sidebar element. Called on every
|
|
97
97
|
* facts poll; a throwing detect contributes nothing that round.
|
|
98
98
|
*
|
|
99
99
|
* MUST NOT WRITE REACTIVE STATE. This runs inside the host's render computed, so a `sandboxRef` (or any
|
|
100
100
|
* other `Ref`) written here is a computed mutating its own dependency: Vue re-runs it, it writes again,
|
|
101
|
-
* and the rail recurses until the frame is abandoned
|
|
101
|
+
* and the rail recurses until the frame is abandoned, taking every unrelated update queued behind it, so
|
|
102
102
|
* the symptom is a window that stops responding rather than one misbehaving tile.
|
|
103
103
|
*
|
|
104
|
-
* It IS the right place to notice things, though
|
|
104
|
+
* It IS the right place to notice things, though, it is the only callback that sees the live facts, so
|
|
105
105
|
* for the bookkeeping that notice produces (which connections a poller should ask about next round) use
|
|
106
106
|
* `sandboxValue`, which has the same lifetime and no observers. Same rule for `badge` below. */
|
|
107
107
|
readonly detect: (repos: readonly RepoFacts[], capabilities: readonly CapabilityFacts[]) => Activation[];
|
|
108
108
|
// What this activation's tile should say without being opened. Read inside the host's own computed, so
|
|
109
|
-
// reading a ref here re-renders the tile when it changes
|
|
109
|
+
// reading a ref here re-renders the tile when it changes, no push channel needed. Called on every render
|
|
110
110
|
// of every surface that draws tiles, so it must be cheap and pure: derive from state the extension already
|
|
111
|
-
// keeps, never fetch, and never write a ref (see detect above
|
|
111
|
+
// keeps, never fetch, and never write a ref (see detect above, same computed, same recursion). A throwing
|
|
112
112
|
// badge simply yields none.
|
|
113
113
|
//
|
|
114
|
-
// Requires `badge: true` on the manifest's matching contributes.views entry
|
|
114
|
+
// Requires `badge: true` on the manifest's matching contributes.views entry, the host drops the function
|
|
115
115
|
// otherwise, because a tile that can interrupt the user is a contribution the owner must have approved.
|
|
116
116
|
// The source has to stay alive while the view is UNMOUNTED (a badge you only see once you have already
|
|
117
117
|
// navigated to the view is pointless), so it belongs in module state owned by activate(), not in the view.
|
|
118
118
|
readonly badge?: ((activation: Activation) => ViewBadge | undefined) | undefined;
|
|
119
|
-
/* WHAT THIS VIEW WOULD LIKE IN HAND BEFORE ANYONE OPENS IT
|
|
119
|
+
/* WHAT THIS VIEW WOULD LIKE IN HAND BEFORE ANYONE OPENS IT, read ahead by the host's background loader in
|
|
120
120
|
* the gaps between what the user is already doing, so the tile opens with content instead of a skeleton.
|
|
121
121
|
*
|
|
122
122
|
* A rail tile is at the far end of the loader's priority order (the user is not there, they might GO
|
|
@@ -124,7 +124,7 @@ export interface ViewRegistration {
|
|
|
124
124
|
* of it is read and the view costs exactly what it cost before. Nothing here is user-visible, nothing
|
|
125
125
|
* retries, and a failed warm is simply a warm that did not happen.
|
|
126
126
|
*
|
|
127
|
-
* DECLARE THE QUERY, not a function that fetches it
|
|
127
|
+
* DECLARE THE QUERY, not a function that fetches it, that is the whole reason this takes a HostQuery. The
|
|
128
128
|
* host's own wishes used to carry a cache key and a separate "how to read it" callback, and for most of
|
|
129
129
|
* them the callback fetched the data and returned it to its caller without ever filing it under that key.
|
|
130
130
|
* The wish could then never be satisfied, and since the loader always takes the first unsatisfied wish, one
|
|
@@ -132,12 +132,12 @@ export interface ViewRegistration {
|
|
|
132
132
|
* object. Use the SAME key your view's `useQuery` reads (api.sandbox.key(...)), or you are warming an entry
|
|
133
133
|
* nothing will look in.
|
|
134
134
|
*
|
|
135
|
-
* Called on every beat of the loader, so it must be cheap and pure
|
|
135
|
+
* Called on every beat of the loader, so it must be cheap and pure, derive from state you already keep,
|
|
136
136
|
* never fetch. A throwing warm contributes nothing that beat. */
|
|
137
137
|
readonly warm?: (() => readonly HostQuery[]) | undefined;
|
|
138
138
|
// A fallback view's activations are dropped for repos already claimed by a non-fallback one.
|
|
139
139
|
readonly fallback?: true | undefined;
|
|
140
|
-
// An AUXILIARY view adds a surface BESIDE whatever else serves the repo instead of replacing it
|
|
140
|
+
// An AUXILIARY view adds a surface BESIDE whatever else serves the repo instead of replacing it, a test
|
|
141
141
|
// runner, a docs browser. Its activations render and mark the directory manageable exactly like any other,
|
|
142
142
|
// but they do not claim the repo, so the fallback view (the raw dev-server preview) survives alongside.
|
|
143
143
|
// Claiming is for a view that subsumes the fallback: `apps` renders the preview URLs itself, so dropping
|
|
@@ -147,9 +147,9 @@ export interface ViewRegistration {
|
|
|
147
147
|
readonly view: () => Promise<Component>;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
// A custom file viewer's runtime registration
|
|
150
|
+
// A custom file viewer's runtime registration, `id` must match a `contributes.viewers` entry in the approved
|
|
151
151
|
// manifest (the host reads the file extensions + fetch kind from there). The host resolves an open file to this
|
|
152
|
-
// viewer, gets its content, and renders `component` with `{ path, text?, blob?, src? }` bound
|
|
152
|
+
// viewer, gets its content, and renders `component` with `{ path, text?, blob?, src? }` bound, which of the
|
|
153
153
|
// three content props is filled is decided by the manifest's `fetch` (see ViewerContributionSchema).
|
|
154
154
|
export interface ViewerRegistration {
|
|
155
155
|
readonly id: string;
|
|
@@ -157,7 +157,7 @@ export interface ViewerRegistration {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
// What a directory row offers when a provider has a document for it: the icon the Workspace tree draws on that
|
|
160
|
-
// row, and what the tab it opens is called. `icon` is an open string like Activation.icon
|
|
160
|
+
// row, and what the tab it opens is called. `icon` is an open string like Activation.icon, a name outside the
|
|
161
161
|
// host's set renders nothing rather than failing the registration.
|
|
162
162
|
export interface DocumentOffer {
|
|
163
163
|
readonly icon: string;
|
|
@@ -166,22 +166,22 @@ export interface DocumentOffer {
|
|
|
166
166
|
// The tab's label. Short: the strip already shows the directory's own name beside it.
|
|
167
167
|
readonly title: string;
|
|
168
168
|
/* Whether the row keeps this icon when the pointer is elsewhere. A tree row's icons are revealed on hover,
|
|
169
|
-
* because a permanent column of them is what stops the eye reading names
|
|
169
|
+
* because a permanent column of them is what stops the eye reading names, but that rule assumes an icon is
|
|
170
170
|
* an ACTION you already know you want. An offer that is EVIDENCE is the opposite case: "there is a page about
|
|
171
171
|
* this package" is a fact nobody can act on until they see it, and finding it by sweeping fifty-five rows with
|
|
172
172
|
* the mouse is not finding it. Such an offer sets this, and the row carries it dimmed until hover.
|
|
173
173
|
*
|
|
174
|
-
* Left off (the default) by an offer every directory of its kind gets
|
|
174
|
+
* Left off (the default) by an offer every directory of its kind gets, a repo's git history is always there,
|
|
175
175
|
* so a permanent glyph states nothing and costs the same attention. */
|
|
176
176
|
readonly evidence?: boolean;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
/* A DOCUMENT PROVIDER
|
|
179
|
+
/* A DOCUMENT PROVIDER, an extension's answer to "there is something to READ about this directory".
|
|
180
180
|
*
|
|
181
181
|
* PATH-KEYED, which is the whole reason it is not a `view`. `detect()` on a ViewRegistration answers per REPO
|
|
182
182
|
* off the daemon's facts, and that is the wrong grain for a document: a monorepo is one repo with fifty-five
|
|
183
|
-
* documented packages. So this asks per directory instead, and the Workspace tree
|
|
184
|
-
* area
|
|
183
|
+
* documented packages. So this asks per directory instead, and the Workspace tree, not the rail, not a routed
|
|
184
|
+
* area, is where the answer lands.
|
|
185
185
|
*
|
|
186
186
|
* The host owns the tab. A provider says "yes, and here is what to call it"; opening it mounts `view` with the
|
|
187
187
|
* path bound, in the editor area beside the files it describes. That placement is the point: documentation about
|
|
@@ -191,7 +191,7 @@ export interface DocumentProviderRegistration {
|
|
|
191
191
|
readonly id: string;
|
|
192
192
|
/* Whether this provider has a document for a workspace path (root-relative; "" is the workspace root), and
|
|
193
193
|
* what the row should offer if so. Called for every visible directory row on every render of the tree, so it
|
|
194
|
-
* must be a LOOKUP and never a fetch
|
|
194
|
+
* must be a LOOKUP and never a fetch, derive it from state the extension already keeps. Reading a ref in
|
|
195
195
|
* here is what repaints the tree when documents land, the same contract (and the same reason) as
|
|
196
196
|
* ViewRegistration.badge; and like badge, that state has to outlive the view being unmounted, so it belongs
|
|
197
197
|
* in module state owned by activate(). A throwing detect simply offers nothing for that row. */
|
|
@@ -201,7 +201,7 @@ export interface DocumentProviderRegistration {
|
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
/* EVERYTHING THAT DECIDES WHO SERVES A TURN, as one value. The label is here because a view that shows a chosen
|
|
204
|
-
* model without showing the list would otherwise have to keep a catalog of its own
|
|
204
|
+
* model without showing the list would otherwise have to keep a catalog of its own, which is exactly the
|
|
205
205
|
* duplication `api.models` exists to end.
|
|
206
206
|
*
|
|
207
207
|
* The last two are optional because they are pins, and the unpinned state is the one most callers want: absent
|
|
@@ -209,17 +209,17 @@ export interface DocumentProviderRegistration {
|
|
|
209
209
|
* disconnected or a harness gains a provider. A caller that only cares which model runs can ignore both and
|
|
210
210
|
* lose nothing. */
|
|
211
211
|
export interface PickedModel {
|
|
212
|
-
// An `AgentProvider
|
|
212
|
+
// An `AgentProvider`, `claude`, `codex`, a configured model endpoint's id, an installed ACP agent's id.
|
|
213
213
|
// Open on purpose: the set grows with what the sandbox has connected, and an extension only carries it.
|
|
214
214
|
readonly provider: string;
|
|
215
215
|
readonly model: string;
|
|
216
216
|
readonly label: string;
|
|
217
|
-
/* WHICH CONNECTED ACCOUNT of that provider runs the turn, by its daemon-minted id
|
|
217
|
+
/* WHICH CONNECTED ACCOUNT of that provider runs the turn, by its daemon-minted id, absent ⇒ whichever comes
|
|
218
218
|
* first. It is on the pick rather than left to the daemon because the surfaces that start UNATTENDED runs are
|
|
219
219
|
* the ones that need it: nobody is watching at 6am, so a first account that has run out of headroom (or whose
|
|
220
220
|
* organization switched the plan off) is a run that errors every time until someone reads the row. */
|
|
221
221
|
readonly account?: string | undefined;
|
|
222
|
-
/* What the shell calls that account
|
|
222
|
+
/* What the shell calls that account, the sign-in identity, which is the only part of it the owner
|
|
223
223
|
* recognises ("Claude" is what three unrenamed accounts are all called).
|
|
224
224
|
*
|
|
225
225
|
* Absent means the shell cannot name it, which covers BOTH a pin whose credential has been disconnected and
|
|
@@ -227,7 +227,7 @@ export interface PickedModel {
|
|
|
227
227
|
* the same absence, and a view that reads it as "this automation is broken" says so about every row while the
|
|
228
228
|
* daemon is merely still starting. Show the name when there is one, and nothing when there isn't. */
|
|
229
229
|
readonly accountLabel?: string | undefined;
|
|
230
|
-
// `native` or `claude-code
|
|
230
|
+
// `native` or `claude-code`, the agentic loop, an axis of its own since codex/grok run the same subscription
|
|
231
231
|
// model ids under either. Absent ⇒ native, which for every other provider is the only answer there is.
|
|
232
232
|
readonly harness?: string | undefined;
|
|
233
233
|
}
|
|
@@ -242,17 +242,17 @@ export interface ProcessStatus {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
export interface IntenticApi {
|
|
245
|
-
// The host's @intentic/extension-api version
|
|
245
|
+
// The host's @intentic/extension-api version, what `engines.intentic` was checked against.
|
|
246
246
|
readonly apiVersion: string;
|
|
247
247
|
readonly views: {
|
|
248
248
|
register(view: ViewRegistration): Disposable;
|
|
249
249
|
};
|
|
250
|
-
// Custom file viewers (contributes.viewers)
|
|
250
|
+
// Custom file viewers (contributes.viewers), the host owns the fetch + open-file lifecycle and renders the
|
|
251
251
|
// registered component with the file's content; the extension only renders. See ViewerRegistration.
|
|
252
252
|
readonly viewers: {
|
|
253
253
|
register(viewer: ViewerRegistration): Disposable;
|
|
254
254
|
};
|
|
255
|
-
// Per-directory documents (contributes.documents)
|
|
255
|
+
// Per-directory documents (contributes.documents), the extension says which directories it can explain and
|
|
256
256
|
// renders one; the host draws the tree's affordance and owns the tab. See DocumentProviderRegistration.
|
|
257
257
|
readonly documents: {
|
|
258
258
|
register(provider: DocumentProviderRegistration): Disposable;
|
|
@@ -260,7 +260,7 @@ export interface IntenticApi {
|
|
|
260
260
|
*
|
|
261
261
|
* The row is the ordinary way in, so this is for the directories that have no row: the workspace root,
|
|
262
262
|
* which the tree renders the contents of rather than a line for. Without it a command contributed
|
|
263
|
-
* alongside a document provider
|
|
263
|
+
* alongside a document provider, "Show Git History" in the palette, has nothing it can actually open.
|
|
264
264
|
*
|
|
265
265
|
* `id` must be one of this extension's registered providers, and the provider must have an offer for
|
|
266
266
|
* `path` (the same `detect()` the tree asks); a provider that has nothing to say about the directory
|
|
@@ -279,17 +279,17 @@ export interface IntenticApi {
|
|
|
279
279
|
set(key: string, value: SettingValue): Promise<void>;
|
|
280
280
|
onDidChange(listener: (key: string) => void): Disposable;
|
|
281
281
|
};
|
|
282
|
-
// The authenticated transport to the sandbox daemon's routes
|
|
282
|
+
// The authenticated transport to the sandbox daemon's routes, auth is injected host-side; an extension
|
|
283
283
|
// never sees tokens. Reach is scoped: every door here is gated by the manifest's `permissions.sandbox`
|
|
284
284
|
// allowlist, so a call to an undeclared method+path throws rather than reaching the whole daemon.
|
|
285
285
|
readonly sandbox: {
|
|
286
|
-
/* THE DAEMON, TYPED
|
|
286
|
+
/* THE DAEMON, TYPED, the same contract the daemon implements, so a call names a procedure instead of
|
|
287
287
|
* building a URL. `rpc.git.stashApply({ repo, ref, pop })` carries the declared input shape and answers
|
|
288
288
|
* the declared output shape, both checked at build time.
|
|
289
289
|
*
|
|
290
290
|
* This is the door to reach for. `request`/`json` below take a path string, which means every caller
|
|
291
291
|
* re-derives what this already knows: the method, the escaping, the query encoding, and the shape of the
|
|
292
|
-
* answer
|
|
292
|
+
* answer, the last of those as an unchecked assertion that keeps compiling long after the daemon's reply
|
|
293
293
|
* has changed underneath it. Thirteen extensions between them hand-wrote a hundred such calls and
|
|
294
294
|
* re-validated half the responses against the very schemas the contract had already declared.
|
|
295
295
|
*
|
|
@@ -299,7 +299,7 @@ export interface IntenticApi {
|
|
|
299
299
|
readonly rpc: ContractRouterClient<typeof sandboxContract>;
|
|
300
300
|
request(path: string, init?: RequestInit): Promise<Response>;
|
|
301
301
|
json<T>(path: string, init?: RequestInit): Promise<T>;
|
|
302
|
-
/* READ THROUGH THE HOST'S CACHE, from outside a component
|
|
302
|
+
/* READ THROUGH THE HOST'S CACHE, from outside a component, the door for the module-level timers that
|
|
303
303
|
* badge a rail tile, which is where `useQuery` cannot reach.
|
|
304
304
|
*
|
|
305
305
|
* Concurrent callers of one key share a single request, and a caller inside `staleTime` is answered
|
|
@@ -307,27 +307,27 @@ export interface IntenticApi {
|
|
|
307
307
|
* polls a route on its own timer and hands the answer only to itself makes the view it badges for pay
|
|
308
308
|
* for the same read again on open. Through here, the badge's poll IS the view's first paint.
|
|
309
309
|
*
|
|
310
|
-
* The route is gated exactly as `json` is
|
|
310
|
+
* The route is gated exactly as `json` is, `queryFn` is your function, and whatever it calls carries
|
|
311
311
|
* its own manifest check. */
|
|
312
312
|
fetch<T>(query: HostQuery<T>): Promise<T>;
|
|
313
|
-
// Whether the active sandbox is currently reachable
|
|
313
|
+
// Whether the active sandbox is currently reachable, reactive when read inside a computed, so it
|
|
314
314
|
// drives host-provided vue-query `enabled` options.
|
|
315
315
|
reachable(): boolean;
|
|
316
|
-
// A cache key scoped to the ACTIVE sandbox
|
|
316
|
+
// A cache key scoped to the ACTIVE sandbox, the required prefix for every host-provided vue-query
|
|
317
317
|
// key, so caches never bleed across a sandbox switch.
|
|
318
318
|
key(...parts: readonly string[]): readonly unknown[];
|
|
319
319
|
// The daemon's base URL (its public tunnel origin), for building externally-shareable URLs like webhook
|
|
320
320
|
// endpoints. Undefined until the sandbox has registered its address. Not needed for `request`/`json`
|
|
321
|
-
// (those take a path and inject auth)
|
|
321
|
+
// (those take a path and inject auth), only when the raw origin must be shown to the user.
|
|
322
322
|
origin(): string | undefined;
|
|
323
|
-
/* THE SIGNED-IN USER'S TRUST TIER on the active sandbox
|
|
324
|
-
* `viewer
|
|
323
|
+
/* THE SIGNED-IN USER'S TRUST TIER on the active sandbox, `owner`, `maintainer`, `collaborator` or
|
|
324
|
+
* `viewer`, reactive when read inside a computed, like `reachable`. For AFFORDANCES ONLY: every route
|
|
325
325
|
* is independently floored by the daemon, so what this gates is whether an Approve button renders, never
|
|
326
326
|
* whether the call would succeed. A view that shows a viewer buttons the daemon will refuse teaches them
|
|
327
327
|
* that buttons lie; this is how a view says less instead.
|
|
328
328
|
*
|
|
329
329
|
* The first consumer is the drafts queue (approve/reject are maintainer-and-up), and it existed as a
|
|
330
|
-
* private composable before it was public API
|
|
330
|
+
* private composable before it was public API, which is the pattern this package's history warns about:
|
|
331
331
|
* a surface only its own app needs is a surface nobody else can build the same feature on. */
|
|
332
332
|
role(): "owner" | "maintainer" | "collaborator" | "viewer";
|
|
333
333
|
};
|
|
@@ -335,7 +335,7 @@ export interface IntenticApi {
|
|
|
335
335
|
repos(): readonly RepoFacts[];
|
|
336
336
|
capabilities(): readonly CapabilityFacts[];
|
|
337
337
|
onDidChange(listener: () => void): Disposable;
|
|
338
|
-
/* A REF MOVED IN ONE OF THESE REPOS
|
|
338
|
+
/* A REF MOVED IN ONE OF THESE REPOS, a commit, a branch, a checkout, a rebase, an aborted merge.
|
|
339
339
|
*
|
|
340
340
|
* Separate from `contributes.files` because no file contribution could ever carry it: the daemon's
|
|
341
341
|
* watcher descent-ignores `.git`, so a changed ref produces no `workspaceChanged` path to match a prefix
|
|
@@ -347,27 +347,27 @@ export interface IntenticApi {
|
|
|
347
347
|
* as the last thing the user clicked. `repos` are root-relative ids ("root" is the workspace repo itself).
|
|
348
348
|
*/
|
|
349
349
|
onDidChangeRefs(listener: (repos: readonly string[]) => void): Disposable;
|
|
350
|
-
/* OPEN A DIFF IN THE EDITOR AREA
|
|
350
|
+
/* OPEN A DIFF IN THE EDITOR AREA, the host's tab strip, beside the files the diff is about.
|
|
351
351
|
*
|
|
352
352
|
* The shell owns the strip, the viewer, the close orchestration and the edit-buffer bookkeeping; the
|
|
353
353
|
* extension owns only the question of what changed. Re-opening the same `key`+`scope`+`path` focuses the
|
|
354
|
-
* tab that is already open rather than stacking a second copy
|
|
354
|
+
* tab that is already open rather than stacking a second copy, see DiffPayload for how that identity is
|
|
355
355
|
* built. On mobile, where there is no strip, the host navigates to the diff instead.
|
|
356
356
|
*/
|
|
357
357
|
openDiff(payload: DiffPayload): void;
|
|
358
|
-
/* FILL A DIFF OPENED WITH `pending
|
|
358
|
+
/* FILL A DIFF OPENED WITH `pending`, the second half of opening a tab before its content exists.
|
|
359
359
|
*
|
|
360
360
|
* Refreshes, never opens: a tab the user has since closed or replaced takes nothing, and the content is
|
|
361
|
-
* simply dropped. That is what makes the pending open safe to use for a slow source
|
|
361
|
+
* simply dropped. That is what makes the pending open safe to use for a slow source, a reader who has
|
|
362
362
|
* moved on to another file is never yanked back to this one, and never has it appear under them.
|
|
363
363
|
*/
|
|
364
364
|
fillDiff(payload: DiffPayload): void;
|
|
365
|
-
/* READING AND WRITING WORKSPACE FILES
|
|
365
|
+
/* READING AND WRITING WORKSPACE FILES, the daemon's file routes, without the encoding.
|
|
366
366
|
*
|
|
367
367
|
* Extensions keep their durable state in the workspace rather than in settings: an acceptance run's
|
|
368
368
|
* reports, a documentation set's staging tree, the "what has the rail badge already shown" file each of
|
|
369
|
-
* them keeps. That is the right home
|
|
370
|
-
* and the agent writing into it out-of-band is the whole point
|
|
369
|
+
* them keeps. That is the right home, it survives a reload, it is shared across the owner's browsers,
|
|
370
|
+
* and the agent writing into it out-of-band is the whole point, but it left every extension spelling
|
|
371
371
|
* `sandbox.json(\`/workspace/file?path=${encodeURIComponent(path)}\`)` and then parsing the envelope out
|
|
372
372
|
* of the answer. Three extensions had five byte-identical copies of that one function.
|
|
373
373
|
*
|
|
@@ -375,7 +375,7 @@ export interface IntenticApi {
|
|
|
375
375
|
* an extension still declares `GET /workspace/file` and `POST /workspace/upload` in its manifest and one
|
|
376
376
|
* that doesn't is still refused. This removes the encoding, not the grant. */
|
|
377
377
|
// The file's text, or undefined when it is not there. Absent is the ordinary FIRST state for most of what
|
|
378
|
-
// extensions keep
|
|
378
|
+
// extensions keep, nothing has been acknowledged because nothing has been seen, so it is a value here,
|
|
379
379
|
// not a throw every caller would have to wrap. The daemon reports it the same way (a 200 that says the
|
|
380
380
|
// path holds nothing), so a poll over files that do not exist yet is silent rather than a page of failed
|
|
381
381
|
// requests in the owner's console.
|
|
@@ -385,19 +385,19 @@ export interface IntenticApi {
|
|
|
385
385
|
* One tolerant reader rather than one per caller. These files are written by agents and editable by
|
|
386
386
|
* hand, so a half-written or hand-mangled one is a case that WILL happen, and "skip it" is the right
|
|
387
387
|
* answer everywhere: one bad file must never blank the surface that reads it. Arrays answer undefined
|
|
388
|
-
* too
|
|
388
|
+
* too, every caller of this wants a record. */
|
|
389
389
|
readJson<T>(path: string): Promise<T | undefined>;
|
|
390
390
|
// Create or replace a workspace file. Throws on failure, unlike the reads: a write that silently did
|
|
391
391
|
// nothing would lose the thing the caller was told was saved.
|
|
392
392
|
write(path: string, body: string): Promise<void>;
|
|
393
393
|
};
|
|
394
|
-
// The extension's OWN declared background processes
|
|
394
|
+
// The extension's OWN declared background processes, names outside the manifest are refused.
|
|
395
395
|
readonly processes: {
|
|
396
396
|
status(name: string): Promise<ProcessStatus>;
|
|
397
397
|
start(name: string): Promise<void>;
|
|
398
398
|
stop(name: string): Promise<void>;
|
|
399
399
|
};
|
|
400
|
-
// The shell's ONE global terminal panel
|
|
400
|
+
// The shell's ONE global terminal panel, extensions aim it at a tmux session (a capability job, a dev
|
|
401
401
|
// server, an agent terminal); the host owns the panel itself.
|
|
402
402
|
readonly terminal: {
|
|
403
403
|
// Open the panel focused on a tmux session (starting/attaching it).
|
|
@@ -406,14 +406,14 @@ export interface IntenticApi {
|
|
|
406
406
|
setOpen(open: boolean): void;
|
|
407
407
|
};
|
|
408
408
|
// The shell's chat, the way `terminal` is the shell's one terminal panel: the extension names a transcript,
|
|
409
|
-
// the host owns the tab. What this is for is a record that points at agent work
|
|
410
|
-
// history, an audit row
|
|
409
|
+
// the host owns the tab. What this is for is a record that points at agent work, an automation's run
|
|
410
|
+
// history, an audit row, where "why did it do that" is only answerable by reading the transcript.
|
|
411
411
|
readonly chat: {
|
|
412
|
-
// Open (or focus) the tab for a stored runtime session id
|
|
412
|
+
// Open (or focus) the tab for a stored runtime session id, the same path the History menu and the fleet
|
|
413
413
|
// board take. A session the daemon no longer holds opens an empty tab rather than failing.
|
|
414
414
|
openSession(sessionId: string): void;
|
|
415
415
|
/* AIM A NEW CHAT AT A WORKFLOW: the host opens a session exactly as "New agent" does, with the
|
|
416
|
-
* composer's workflow badge set to this design
|
|
416
|
+
* composer's workflow badge set to this design, so the next message the user types becomes that run's
|
|
417
417
|
* request instead of a turn on the chat.
|
|
418
418
|
*
|
|
419
419
|
* It hands over the START of the work rather than performing it, and that is the point. An extension
|
|
@@ -426,26 +426,26 @@ export interface IntenticApi {
|
|
|
426
426
|
* nothing here can name a `Workflow` type.
|
|
427
427
|
*/
|
|
428
428
|
composeWorkflow(workflowId: string): void;
|
|
429
|
-
/* AIM A NEW CHAT AT A SAVED LOOP
|
|
429
|
+
/* AIM A NEW CHAT AT A SAVED LOOP, the same handover as `composeWorkflow` above, for the other kind of
|
|
430
430
|
* design: the host opens a session with the composer's loop badge set, so the next message the user
|
|
431
431
|
* types becomes the loop's GOAL and Send starts it running.
|
|
432
432
|
*
|
|
433
433
|
* It is a separate call rather than a flag on that one because the two badges are separate picks that
|
|
434
434
|
* cannot both be armed, and a single "compose with this id" would have had to guess which kind an id
|
|
435
|
-
* was. A loop id, not a running loop's
|
|
435
|
+
* was. A loop id, not a running loop's, nothing has started, and nothing is spent until the send.
|
|
436
436
|
*/
|
|
437
437
|
composeLoop(loopId: string): void;
|
|
438
438
|
};
|
|
439
439
|
/* WHICH MODEL A RUN THIS EXTENSION STARTS WILL SPEND, the way `terminal` is the shell's one terminal panel:
|
|
440
440
|
* the extension names the choice it is holding, the host owns the picker.
|
|
441
441
|
*
|
|
442
|
-
* It is an API rather than a kit component because the picker is not a widget
|
|
442
|
+
* It is an API rather than a kit component because the picker is not a widget, it is a live read of every
|
|
443
443
|
* connected provider's catalog, which credentials the sandbox actually holds, and what each model can do.
|
|
444
444
|
* An extension that rendered its own control could only ever offer a worse list: the acceptance view's did,
|
|
445
445
|
* fetching one provider's models behind a second dropdown for the provider itself, and so it happily
|
|
446
|
-
* offered models the sandbox had no credential for
|
|
446
|
+
* offered models the sandbox had no credential for, a run that fails on a credential error minutes later.
|
|
447
447
|
*
|
|
448
|
-
* IT COVERS THE WHOLE CHOICE
|
|
448
|
+
* IT COVERS THE WHOLE CHOICE, provider, account, harness, model, because covering three quarters of it is
|
|
449
449
|
* what produced the copy this API exists to prevent. The automations form asked all four questions, found an
|
|
450
450
|
* API that answered three, and hand-rolled ROWS OF CHIPS for every one of them to keep its own fields
|
|
451
451
|
* consistent with each other: a static provider list that offered providers the sandbox had no credential for
|
|
@@ -455,13 +455,13 @@ export interface IntenticApi {
|
|
|
455
455
|
// What a run opens on when nobody has chosen: the sandbox's Agent-runs model (Sandbox ▸ Agent ▸ Models),
|
|
456
456
|
// falling back to whatever the owner's own chat is set to. Reactive when read inside a computed.
|
|
457
457
|
agentRun(): PickedModel;
|
|
458
|
-
/* NAME A SELECTION THE EXTENSION ALREADY HOLDS
|
|
458
|
+
/* NAME A SELECTION THE EXTENSION ALREADY HOLDS, a pin read back from disk, which arrives as bare ids and
|
|
459
459
|
* has to be rendered before anyone opens the picker. This is what keeps `label` honest for the surfaces
|
|
460
460
|
* that SAVE a choice rather than spend it immediately: without it every one of them would keep a catalog
|
|
461
461
|
* to pretty-print its own stored ids, which is the duplication this API exists to end, and it would go
|
|
462
462
|
* stale the day a provider renames a model or the owner disconnects an account.
|
|
463
463
|
*
|
|
464
|
-
* Reactive when read inside a computed
|
|
464
|
+
* Reactive when read inside a computed, a model that lands in the catalog, or an account that stops being
|
|
465
465
|
* connected, changes what a stored pin should say about itself. */
|
|
466
466
|
describe(selection: {
|
|
467
467
|
readonly provider: string;
|
|
@@ -469,14 +469,14 @@ export interface IntenticApi {
|
|
|
469
469
|
readonly account?: string | undefined;
|
|
470
470
|
readonly harness?: string | undefined;
|
|
471
471
|
}): PickedModel;
|
|
472
|
-
/* Open the picker over `anchor
|
|
472
|
+
/* Open the picker over `anchor`, a popover on desktop, a sheet on mobile, starting on the selection the
|
|
473
473
|
* caller is holding. Resolves with the pick, or undefined if it was dismissed. A second call supersedes
|
|
474
474
|
* the first, resolving it as a dismissal.
|
|
475
475
|
*
|
|
476
476
|
* EVERY ROW SETTLES IT, including an account and a harness row: each click is one complete answer, so a
|
|
477
477
|
* caller never has to reconcile a half-changed selection, and the picker never has to hold state that
|
|
478
478
|
* disagrees with what the caller is showing. Picking a model under a DIFFERENT provider clears the
|
|
479
|
-
* account with it
|
|
479
|
+
* account with it, an account id is one provider's store key, so carrying it across would pin the run to
|
|
480
480
|
* an account that provider does not have. */
|
|
481
481
|
pick(options: {
|
|
482
482
|
readonly anchor: HTMLElement;
|
|
@@ -488,18 +488,28 @@ export interface IntenticApi {
|
|
|
488
488
|
};
|
|
489
489
|
// Navigate the shell to an app path (e.g. "/capabilities", "/ext/<view>/<key>").
|
|
490
490
|
readonly navigate: (path: string) => void;
|
|
491
|
+
/* THE SAME PATH AS A BROWSER ADDRESS — what a view puts in an `<a href>` so the thing it draws is a real
|
|
492
|
+
* link and not a <button> that happens to move the shell.
|
|
493
|
+
*
|
|
494
|
+
* Every row and card in this app that goes somewhere has a URL behind it, and a view that only calls
|
|
495
|
+
* `navigate` throws all of it away: nothing under the pointer in the status bar, nothing in the browser's
|
|
496
|
+
* own right-click menu, nothing to copy, and Ctrl/⌘-click navigating the tab the user is reading instead
|
|
497
|
+
* of opening a second one. So a navigational row renders as `<a :href="api.href(path)">` and calls
|
|
498
|
+
* `navigate` from its click handler — guarded with `browserOwnsClick` (@intentic/extension-ui) so a
|
|
499
|
+
* modified click is left to the browser. */
|
|
500
|
+
readonly href: (path: string) => string;
|
|
491
501
|
/* THE URL AS A VIEW'S STATE, so what a reader is looking at can be linked to.
|
|
492
502
|
*
|
|
493
503
|
* A view's own route space is the QUERY, not extra path segments: `/ext/:ext/:key?` is the whole route, and
|
|
494
|
-
* the `:key` segment already means "which activation" (one per repo). A view with internal navigation
|
|
495
|
-
* document browser, a selected run, an open file
|
|
504
|
+
* the `:key` segment already means "which activation" (one per repo). A view with internal navigation, a
|
|
505
|
+
* document browser, a selected run, an open file, therefore has nowhere in the path to put it, and without
|
|
496
506
|
* this it could only hold that state in memory, where a reload loses it and a link cannot carry it.
|
|
497
507
|
*
|
|
498
508
|
* Reading is reactive: read inside a computed and the view re-renders when the URL moves, which lets a view
|
|
499
509
|
* DERIVE its state from the query rather than mirror it in a ref (mirroring needs two watchers that can fight
|
|
500
510
|
* each other). Back and forward then work for free, because the URL is the state. */
|
|
501
511
|
readonly route: {
|
|
502
|
-
// The current query, flattened
|
|
512
|
+
// The current query, flattened, a repeated key takes its first value, since a view's state is scalar.
|
|
503
513
|
query(): Readonly<Record<string, string>>;
|
|
504
514
|
/* Merge a patch in; a key set to `undefined` is removed. Replaces the history entry by default and pushes
|
|
505
515
|
* a new one when asked: a filter or a display toggle should not fill the back stack, while moving to
|