@intentic/sandbox-contract 1.213.0 → 1.214.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/contracts/agent.contract.d.ts +2 -0
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.d.ts +150 -0
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +5 -1
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/system.contract.d.ts +2 -0
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/events.d.ts +5 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +1 -0
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +154 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/schemas.d.ts +31 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +10 -0
- package/dist/schemas.js.map +1 -1
- package/dist/workspace-state.d.ts +6 -5
- package/dist/workspace-state.d.ts.map +1 -1
- package/dist/workspace-state.js +5 -5
- package/dist/workspace-state.js.map +1 -1
- package/package.json +4 -4
- package/src/contracts/agents.contract.ts +12 -0
- package/src/events.ts +11 -3
- package/src/schemas.ts +50 -4
- package/src/workspace-state.test.ts +10 -0
- package/src/workspace-state.ts +76 -17
|
@@ -10,7 +10,8 @@ export interface WorkspaceStateFile extends StateFile {
|
|
|
10
10
|
declare const STATE_FILES: readonly [{
|
|
11
11
|
readonly path: ".intentic/capabilities.json";
|
|
12
12
|
readonly invalidates: readonly ["capabilities", "environment", "panels", "manifests"];
|
|
13
|
-
readonly portability: "
|
|
13
|
+
readonly portability: "carry";
|
|
14
|
+
readonly versioned: true;
|
|
14
15
|
}, {
|
|
15
16
|
readonly path: ".intentic/capability-dismissals.json";
|
|
16
17
|
readonly invalidates: readonly ["capabilities"];
|
|
@@ -122,8 +123,8 @@ declare const STATE_FILES: readonly [{
|
|
|
122
123
|
readonly path: ".intentic/extension-settings.json";
|
|
123
124
|
readonly invalidates: readonly [];
|
|
124
125
|
readonly why: "Held in a module-level shallowRef store per extension (web's extensionSettingsStore) with no query observer, and deliberately so: api.settings.get must answer SYNCHRONOUSLY from an extension's first activate() line, and the store outlives every component scope. A module-level QueryObserver is the one shape that would make invalidation refetch, and this app already ruled it out — it detaches on the queryClient.clear() at logout (see useSandbox's sandbox-list mirror). So a remote member's setting edit reaches this browser on its next load, not live.";
|
|
125
|
-
readonly portability: "
|
|
126
|
-
readonly
|
|
126
|
+
readonly portability: "carry";
|
|
127
|
+
readonly versioned: true;
|
|
127
128
|
}, {
|
|
128
129
|
readonly path: ".intentic/extension-enablement.json";
|
|
129
130
|
readonly invalidates: readonly ["extensions"];
|
|
@@ -158,9 +159,9 @@ declare const STATE_FILES: readonly [{
|
|
|
158
159
|
}, {
|
|
159
160
|
readonly path: ".intentic/auth/";
|
|
160
161
|
readonly invalidates: readonly [];
|
|
161
|
-
readonly why: "AI-provider credentials and runtime homes; each account is rendered through owner-gated provider routes.";
|
|
162
|
+
readonly why: "AI-provider credentials and runtime homes, plus the capability and extension-settings secret vaults; each account is rendered through owner-gated provider routes.";
|
|
162
163
|
readonly portability: "secret";
|
|
163
|
-
readonly note: "Sign the agent's AI accounts in again on the Agent tab.";
|
|
164
|
+
readonly note: "Sign the agent's AI accounts in again on the Agent tab, then re-enter each connection's credential on Capabilities and each extension's secret settings on Extensions — both arrived listed but unauthenticated.";
|
|
164
165
|
}, {
|
|
165
166
|
readonly path: ".intentic/sessions/claude/";
|
|
166
167
|
readonly invalidates: readonly [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-state.d.ts","sourceRoot":"","sources":["../src/workspace-state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AA0CxD,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IAKjD,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAExC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAgCtB,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAY1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAKzB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACnC;AAOD,QAAA,MAAM,WAAW;
|
|
1
|
+
{"version":3,"file":"workspace-state.d.ts","sourceRoot":"","sources":["../src/workspace-state.ts"],"names":[],"mappings":"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"}
|
package/dist/workspace-state.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { STATE_DIR } from "@intentic/constants";
|
|
2
2
|
const STATE_FILES = [
|
|
3
|
-
{ path: ".intentic/capabilities.json", invalidates: ["capabilities", "environment", "panels", "manifests"], portability: "
|
|
3
|
+
{ path: ".intentic/capabilities.json", invalidates: ["capabilities", "environment", "panels", "manifests"], portability: "carry", versioned: true },
|
|
4
4
|
{ path: ".intentic/capability-dismissals.json", invalidates: ["capabilities"], portability: "carry", versioned: true },
|
|
5
5
|
{ path: ".intentic/secret-uses.json", invalidates: ["secrets"], portability: "carry" },
|
|
6
6
|
{ path: ".intentic/personas.json", invalidates: ["personas", "capabilities", "manifests"], portability: "carry", versioned: true },
|
|
@@ -79,8 +79,8 @@ const STATE_FILES = [
|
|
|
79
79
|
path: ".intentic/extension-settings.json",
|
|
80
80
|
invalidates: [],
|
|
81
81
|
why: "Held in a module-level shallowRef store per extension (web's extensionSettingsStore) with no query observer, and deliberately so: api.settings.get must answer SYNCHRONOUSLY from an extension's first activate() line, and the store outlives every component scope. A module-level QueryObserver is the one shape that would make invalidation refetch, and this app already ruled it out — it detaches on the queryClient.clear() at logout (see useSandbox's sandbox-list mirror). So a remote member's setting edit reaches this browser on its next load, not live.",
|
|
82
|
-
portability: "
|
|
83
|
-
|
|
82
|
+
portability: "carry",
|
|
83
|
+
versioned: true,
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
path: ".intentic/extension-enablement.json",
|
|
@@ -107,9 +107,9 @@ const STATE_FILES = [
|
|
|
107
107
|
{
|
|
108
108
|
path: ".intentic/auth/",
|
|
109
109
|
invalidates: [],
|
|
110
|
-
why: "AI-provider credentials and runtime homes; each account is rendered through owner-gated provider routes.",
|
|
110
|
+
why: "AI-provider credentials and runtime homes, plus the capability and extension-settings secret vaults; each account is rendered through owner-gated provider routes.",
|
|
111
111
|
portability: "secret",
|
|
112
|
-
note: "Sign the agent's AI accounts in again on the Agent tab.",
|
|
112
|
+
note: "Sign the agent's AI accounts in again on the Agent tab, then re-enter each connection's credential on Capabilities and each extension's secret settings on Extensions — both arrived listed but unauthenticated.",
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
path: ".intentic/sessions/claude/",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-state.js","sourceRoot":"","sources":["../src/workspace-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AA4GhD,MAAM,WAAW,GAAG;
|
|
1
|
+
{"version":3,"file":"workspace-state.js","sourceRoot":"","sources":["../src/workspace-state.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentic/sandbox-contract",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.214.0",
|
|
4
4
|
"description": "oRPC wire contract for the intentic sandbox daemon — shared by the daemon and its browser client",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -89,9 +89,9 @@
|
|
|
89
89
|
"@orpc/contract": "1.14.13",
|
|
90
90
|
"tslib": "2.8.1",
|
|
91
91
|
"zod": "4.4.3",
|
|
92
|
-
"@intentic/constants": "1.
|
|
93
|
-
"@intentic/
|
|
94
|
-
"@intentic/
|
|
92
|
+
"@intentic/constants": "1.214.0",
|
|
93
|
+
"@intentic/registry": "1.214.0",
|
|
94
|
+
"@intentic/extension-manifest": "1.214.0"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@types/node": "24.13.2",
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
AgentLandSchema,
|
|
11
11
|
AgentPlaceSchema,
|
|
12
12
|
AgentRenameSchema,
|
|
13
|
+
AgentResumeAfterOutageSchema,
|
|
13
14
|
AgentSearchQuerySchema,
|
|
14
15
|
AgentSearchResultSchema,
|
|
15
16
|
AgentsListSchema,
|
|
@@ -67,6 +68,17 @@ export const agentsContract = {
|
|
|
67
68
|
// clears it back to "inherit". Legal mid-turn on purpose: the setting is read at turn COMPLETION, so
|
|
68
69
|
// flipping it while the agent works is exactly "hold THIS turn's work for review", the press that matters.
|
|
69
70
|
autoLand: oc.route({ method: "POST", path: "/agents/{id}/auto-land" }).input(AgentAutoLandSchema).output(AgentSummarySchema),
|
|
71
|
+
/* THIS conversation's answer to a provider outage — an override of the sandbox-wide `resumeAfterOutage`
|
|
72
|
+
* setting; null clears it back to "inherit". The chat's offer at the moment a turn dies writes this and
|
|
73
|
+
* never the global: the press happens inside one conversation and means "finish this piece of work", so
|
|
74
|
+
* its honest blast radius is that conversation. Sandbox ▸ Agent owns the default for everything else.
|
|
75
|
+
*
|
|
76
|
+
* Legal mid-turn, and unlike autoLand it is legal for a WORKSPACE conversation too — an outage kills a
|
|
77
|
+
* main-tree chat exactly as readily as an isolated one, and there is no branch involved either way. */
|
|
78
|
+
resumeAfterOutage: oc
|
|
79
|
+
.route({ method: "POST", path: "/agents/{id}/resume-after-outage" })
|
|
80
|
+
.input(AgentResumeAfterOutageSchema)
|
|
81
|
+
.output(AgentSummarySchema),
|
|
70
82
|
seen: oc.route({ method: "POST", path: "/agents/{id}/seen" }).input(AgentIdSchema).output(AgentSummarySchema),
|
|
71
83
|
seenAll: oc.route({ method: "POST", path: "/agents/seen" }).output(AgentsListSchema),
|
|
72
84
|
diff: oc.route({ method: "GET", path: "/agents/{id}/diff" }).input(AgentIdSchema).output(AgentChangesSchema),
|
package/src/events.ts
CHANGED
|
@@ -66,6 +66,11 @@ export const ServiceOfferSchema = z.object({
|
|
|
66
66
|
publisher: z.string(),
|
|
67
67
|
description: z.string(),
|
|
68
68
|
creditsPerRun: z.number(),
|
|
69
|
+
/* Whether the platform still has this listing on probation — a new provider that passed admission's
|
|
70
|
+
* mechanical gates but has not yet served enough runs cleanly to graduate. It rides the card because
|
|
71
|
+
* probation is the honest form of "listed automatically, not vouched for": the member approving the
|
|
72
|
+
* spend is the person who should know that, and the platform is the only party that can say it. */
|
|
73
|
+
probation: z.boolean().optional(),
|
|
69
74
|
// The owner's meter as the platform stated it with the catalog — what "N left today" renders from. Absent
|
|
70
75
|
// when the platform sent none (it answers a meter only to a member, and membership was already checked
|
|
71
76
|
// before this card went up, so in practice it is present; the field stays honest about the wire).
|
|
@@ -694,9 +699,12 @@ export const AgentEventSchema = z.discriminatedUnion("kind", [
|
|
|
694
699
|
resetsAt: z.number().optional(),
|
|
695
700
|
// Where the daemon's resume of THIS turn stands, for the two codes that have one (provider-outage,
|
|
696
701
|
// claude-token-refused). "scheduled" = the resume is armed and this turn comes back by itself;
|
|
697
|
-
// "available" = the daemon remembered the failed turn and
|
|
698
|
-
// resume, which is what the chat's offer
|
|
699
|
-
//
|
|
702
|
+
// "available" = the daemon remembered the failed turn and arming THIS conversation
|
|
703
|
+
// (AgentSummarySchema.resumeAfterOutage) picks up that same resume, which is what the chat's offer
|
|
704
|
+
// banner hangs off — outage only, since a renewal is never gated on a posture at all. The two words
|
|
705
|
+
// are read against the effective posture (the conversation's override, else the sandbox default), so a
|
|
706
|
+
// chat armed on its own says "scheduled" while the unarmed board around it says "available".
|
|
707
|
+
// Absent means there is nothing automatic to resume: a spent usage limit never has one,
|
|
700
708
|
// and a refused credential has none once re-minting it has already been tried and failed.
|
|
701
709
|
autoResume: z.enum(["scheduled", "available"]).optional(),
|
|
702
710
|
/* provider-outage only: the shape of the wait. `retryAt` (epoch seconds) is when the next attempt is
|
package/src/schemas.ts
CHANGED
|
@@ -832,6 +832,19 @@ export const AgentSummarySchema = z.object({
|
|
|
832
832
|
// the global toggle meaningful: an agent that never expressed an opinion follows the sandbox wherever it
|
|
833
833
|
// is pointed next. Written by `agents.autoLand`; the UI shows the EFFECTIVE value (this ?? the setting).
|
|
834
834
|
autoLand: z.boolean().optional(),
|
|
835
|
+
/* This agent's own answer to "re-run my turn when the model provider was what failed?" — the same
|
|
836
|
+
* two-level shape as `autoLand` above, and here for a sharper reason than symmetry.
|
|
837
|
+
*
|
|
838
|
+
* The press that writes this is offered INSIDE one conversation, at the moment that conversation's turn
|
|
839
|
+
* died, and what a person means by it is "finish THIS piece of work". It used to write the sandbox-wide
|
|
840
|
+
* setting, so one impatient click at 2 a.m. quietly armed every agent on the board — a blast radius
|
|
841
|
+
* nothing on screen had asked about. So the chat's offer writes this, the settings toggle writes the
|
|
842
|
+
* default, and the two stay honestly different things.
|
|
843
|
+
*
|
|
844
|
+
* ABSENT ⇒ inherit the sandbox setting, which is what keeps that default meaningful: a conversation that
|
|
845
|
+
* never expressed an opinion follows the sandbox wherever it is pointed next. Written by
|
|
846
|
+
* `agents.resumeAfterOutage`; every surface shows the EFFECTIVE value (this ?? the setting). */
|
|
847
|
+
resumeAfterOutage: z.boolean().optional(),
|
|
835
848
|
// A collaborator asked for this agent's work to be landed (agents.requestLand) — collaborators may drive
|
|
836
849
|
// agents but not merge into the main tree, so the ask rides the summary where every maintainer's board
|
|
837
850
|
// sees it. Cleared by the land or discard that answers it. Absent ⇒ nobody is waiting.
|
|
@@ -1048,6 +1061,11 @@ export const AgentPlaceSchema = z.object({ id: z.string().min(1), text: z.string
|
|
|
1048
1061
|
// the sandbox setting" — the browser sends it whenever the user toggles back to what the global already says,
|
|
1049
1062
|
// so agents don't accumulate frozen overrides that quietly stop following the global toggle.
|
|
1050
1063
|
export const AgentAutoLandSchema = z.object({ id: z.string().min(1), autoLand: z.boolean().nullable() });
|
|
1064
|
+
// resumeAfterOutage's input: this ONE conversation's answer to a provider outage. `null` clears the override
|
|
1065
|
+
// back to "inherit the sandbox setting" — sent whenever the user toggles back to what the global already says,
|
|
1066
|
+
// on the same reasoning as autoLand's null: an agent holding a frozen copy of a default has quietly stopped
|
|
1067
|
+
// following it, and nothing on screen would say so.
|
|
1068
|
+
export const AgentResumeAfterOutageSchema = z.object({ id: z.string().min(1), resumeAfterOutage: z.boolean().nullable() });
|
|
1051
1069
|
export const AgentFileDiffQuerySchema = z.object({ id: z.string().min(1), repo: z.string().min(1), path: z.string().min(1) });
|
|
1052
1070
|
/* WHY a path would not land. The distinction is the whole difference between an actionable report and a dead
|
|
1053
1071
|
* end, because the three have nothing in common but their symptom:
|
|
@@ -1852,15 +1870,23 @@ export const SandboxSettingsSchema = z.object({
|
|
|
1852
1870
|
// terminal state: without a sweep the Finished lane grows for the life of the sandbox, and each card it
|
|
1853
1871
|
// holds is a live worktree checkout, not just a row.
|
|
1854
1872
|
agentRetentionDays: z.number().min(0).max(365).default(3),
|
|
1855
|
-
/*
|
|
1856
|
-
* socket), re-run it on an escalating backoff until it goes through or the
|
|
1873
|
+
/* THE SANDBOX-WIDE DEFAULT for "when a turn dies because the MODEL PROVIDER was failing (500/502/503, a
|
|
1874
|
+
* 529 at capacity, a dropped socket), re-run it on an escalating backoff until it goes through or the
|
|
1875
|
+
* attempts are spent".
|
|
1876
|
+
*
|
|
1877
|
+
* A DEFAULT, not the whole answer: any one conversation may override it (AgentSummarySchema
|
|
1878
|
+
* .resumeAfterOutage), and the chat's own offer at the moment of failure writes THAT rather than this.
|
|
1879
|
+
* This toggle is the standing policy for every agent that has not said otherwise, which is why it lives in
|
|
1880
|
+
* settings and is not reachable by a single press from inside one chat — flipping how the whole board
|
|
1881
|
+
* behaves should be a thing somebody went to do.
|
|
1857
1882
|
*
|
|
1858
1883
|
* OFF by default, on the same reasoning that keeps a spent usage limit out of this pair entirely: a resume
|
|
1859
1884
|
* re-runs a turn the user sent once, on their own allowance, and only they can say whether the turn was
|
|
1860
1885
|
* worth paying for twice. Starting off costs nothing, because the failed turn is remembered whatever the
|
|
1861
1886
|
* toggle says (recordOutageFailure) — the failure frame reports an "available" resume and the chat's offer
|
|
1862
|
-
* arms that very turn the moment it is
|
|
1863
|
-
* nobody in the room (automation wakes, Discord, webhooks), which is the case no browser
|
|
1887
|
+
* arms that very turn the moment it is armed for that conversation. Worth turning ON for a sandbox whose
|
|
1888
|
+
* turns mostly have nobody in the room (automation wakes, Discord, webhooks), which is the case no browser
|
|
1889
|
+
* could rescue and the case a per-conversation press cannot reach. */
|
|
1864
1890
|
resumeAfterOutage: z.boolean().default(false),
|
|
1865
1891
|
/* When the daemon dies under a running turn, re-run that turn once it is back (agent/turn-journal.ts records
|
|
1866
1892
|
* every in-flight turn; the boot pass in agent/turn-resume.ts re-runs what survived). OFF by default, like
|
|
@@ -6049,6 +6075,26 @@ export const MigrationPlanSchema = z.object({
|
|
|
6049
6075
|
});
|
|
6050
6076
|
export type MigrationPlan = z.infer<typeof MigrationPlanSchema>;
|
|
6051
6077
|
|
|
6078
|
+
/* One of the owner's own computers, as an import SOURCE — the answer to "where is my setup" that needs no
|
|
6079
|
+
* packing at all. Read on the card's first render for every enrolled machine, so the offer appears before the
|
|
6080
|
+
* owner has read a single instruction.
|
|
6081
|
+
*
|
|
6082
|
+
* `found` absent means "connected, and nothing to import here" — which is a real answer worth rendering
|
|
6083
|
+
* quietly, not an error: the machine may simply be a different one from the machine the assistant runs on. */
|
|
6084
|
+
export const MigrationHostSchema = z.object({
|
|
6085
|
+
id: z.string(),
|
|
6086
|
+
online: z.boolean(),
|
|
6087
|
+
found: MigrationSourceSchema.optional(),
|
|
6088
|
+
// Why this machine cannot be read right now, when it cannot — offline, or its own refusal, in its words.
|
|
6089
|
+
detail: z.string().optional(),
|
|
6090
|
+
});
|
|
6091
|
+
export const MigrationHostsSchema = z.object({ hosts: z.array(MigrationHostSchema) });
|
|
6092
|
+
export type MigrationHost = z.infer<typeof MigrationHostSchema>;
|
|
6093
|
+
|
|
6094
|
+
// Read the setup off a connected computer instead of an upload. Answers with a plan, exactly as the upload
|
|
6095
|
+
// route does — everything after this point is identical whichever door the setup came through.
|
|
6096
|
+
export const MigrationScanSchema = z.object({ host: z.string().min(1) });
|
|
6097
|
+
|
|
6052
6098
|
export const MigrationApplySchema = z.object({
|
|
6053
6099
|
token: z.string(),
|
|
6054
6100
|
// The ticked item ids. Ids the re-derived plan does not contain are ignored rather than erroring — the
|
|
@@ -268,6 +268,12 @@ describe(`VERSIONED_STATE_PATHS`, () => {
|
|
|
268
268
|
it(`tracks exactly the configuration slice plus the agent's own authored output`, () => {
|
|
269
269
|
expect(VERSIONED_STATE_PATHS.toSorted()).toEqual([
|
|
270
270
|
`.intentic/automations.json`,
|
|
271
|
+
/* The connections themselves, and the entry that took the longest to earn its place — it was classed
|
|
272
|
+
* `secret` on the strength of holding each capability's credential, which stopped being true when the
|
|
273
|
+
* vault took the values out and left the shape behind. Connecting a deployment orchestrator, or
|
|
274
|
+
* granting a connected computer shell and screen control, is the largest change made to what this
|
|
275
|
+
* sandbox can DO, and it used to leave no diff. */
|
|
276
|
+
`.intentic/capabilities.json`,
|
|
271
277
|
`.intentic/capability-dismissals.json`,
|
|
272
278
|
/* The two entries the AGENT authors on its own initiative, and the reason `versioned` is not read as
|
|
273
279
|
* config-only. Both are the sandbox acting outward — a draft publishes words under the owner's name,
|
|
@@ -279,6 +285,10 @@ describe(`VERSIONED_STATE_PATHS`, () => {
|
|
|
279
285
|
`.intentic/environment.custom.Dockerfile`,
|
|
280
286
|
`.intentic/environment.d/`,
|
|
281
287
|
`.intentic/extension-enablement.json`,
|
|
288
|
+
/* Its twin, and the pair is the argument: the SWITCH was already tracked while the configuration
|
|
289
|
+
* behind it was not, so a commit could record turning an extension on and say nothing about what it
|
|
290
|
+
* was told to do. Tracked once its declared-secret values moved to the vault. */
|
|
291
|
+
`.intentic/extension-settings.json`,
|
|
282
292
|
// The owner's per-extension update posture (notify / agent / auto) — a standing decision about
|
|
283
293
|
// what may run unattended, which is exactly the kind of edit worth a line in `git log`.
|
|
284
294
|
`.intentic/extension-update-policy.json`,
|
package/src/workspace-state.ts
CHANGED
|
@@ -109,12 +109,31 @@ export interface WorkspaceStateFile extends StateFile {
|
|
|
109
109
|
const STATE_FILES = [
|
|
110
110
|
/* A capability add/remove recomposes the environment overlay and can add or drop a repo's panel.
|
|
111
111
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
|
|
112
|
+
* SPLIT ALREADY — and this entry's classification had not caught up, which is the whole of what changed here.
|
|
113
|
+
* It read `secret` on a claim that had stopped being true: that each entry's `config` carries that
|
|
114
|
+
* capability's credential, so the manifest is a secret in full. It does not. capabilities-store.ts's
|
|
115
|
+
* withSecretVault keeps credential VALUES off /work entirely — the manifest holds `__intentic_vaulted__`
|
|
116
|
+
* where one used to be, reads rehydrate so no caller noticed, and main.ts sweeps a hand-written value out at
|
|
117
|
+
* boot. What is left is the SHAPE of a connection: a kind, a URL, a username, a purpose, which permissions a
|
|
118
|
+
* connected computer was granted.
|
|
119
|
+
*
|
|
120
|
+
* WHICH KEYS THOSE ARE IS DERIVED, not listed a second time: `echo` already answers "what of this config may
|
|
121
|
+
* a browser see", and the credential keys are exactly its complement (capabilities/secret-fields.ts). A kind
|
|
122
|
+
* that starts withholding a new field starts vaulting it on the same commit. That is what makes this
|
|
123
|
+
* classification a property of the code rather than a promise to re-audit it — the reason the entry can be
|
|
124
|
+
* reclassified at all, and the reason a hand-kept "these fields are safe" list could not have earned it.
|
|
125
|
+
*
|
|
126
|
+
* `carry`, and this is the entry where that earns the most. composeEnvironment reads its Dockerfile fragments
|
|
127
|
+
* from here, so a bundle that dropped it arrived on a stock overlay with an import report listing every
|
|
128
|
+
* connection to re-add by hand. It now arrives listing them itself, each visibly unconnected and waiting for
|
|
129
|
+
* one credential apiece — the shape personas.json has had all along, for the same reason.
|
|
130
|
+
*
|
|
131
|
+
* `versioned`, which is the point. Connecting this sandbox to a deployment orchestrator, or granting a
|
|
132
|
+
* connected computer shell and screen control, is the largest change anyone makes to what it can DO, and it
|
|
133
|
+
* left a diff nowhere. One consequence worth stating rather than discovering: an identifier that pairs with a
|
|
134
|
+
* credential — Komodo's api key beside its api secret, which its own connector card calls "like a database
|
|
135
|
+
* user" — is echoed, and therefore lands in the diff exactly as a database username would. */
|
|
136
|
+
{ path: ".intentic/capabilities.json", invalidates: ["capabilities", "environment", "panels", "manifests"], portability: "carry", versioned: true },
|
|
118
137
|
|
|
119
138
|
/* Which workspace-derived recommendations the owner has said "not needed" to, and the evidence each was
|
|
120
139
|
* declined against. It rides the `capabilities` key because the catalog is what changes when one lands, and
|
|
@@ -290,16 +309,33 @@ const STATE_FILES = [
|
|
|
290
309
|
why: "Thread bookkeeping (an inbound thread — a Doorbell visitor, a Discord or Slack channel — → sandbox conversation + provider session), written on EVERY inbound message. Nothing in the browser reads it: what a thread produces is a conversation, and the fleet board already learns about that from the agent registry's own push. Naming a key here would bill every connected browser a refetch per inbound message — the request storm this table's own note warns about — to refresh nothing it can see.",
|
|
291
310
|
portability: "carry",
|
|
292
311
|
},
|
|
293
|
-
/*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
312
|
+
/* SPLIT, so that "what an extension is configured to do" and "the token it does it with" stop being one file.
|
|
313
|
+
*
|
|
314
|
+
* This entry used to be `secret` and untracked, classed by what a value COULD hold: values are a primitive
|
|
315
|
+
* union an extension chooses the meaning of, and "an API key for the service I talk to" is squarely within
|
|
316
|
+
* it. That classification was honest about the risk and wrong about the file — it meant an extension's whole
|
|
317
|
+
* configuration was unreviewable because one of its keys might be a credential, AND the credential was in
|
|
318
|
+
* there anyway, in a file the workspace API does not lock. A turn could simply read it.
|
|
319
|
+
*
|
|
320
|
+
* A descriptor already says which keys those are (`contributes.settings[].secret`), so the values it names
|
|
321
|
+
* now live in the vault off /work and this file keeps the rest — the capability manifest's split, applied to
|
|
322
|
+
* the same problem one table over (extensions/extension-settings.ts holds it, and the reasoning). Reads
|
|
323
|
+
* rehydrate, so no caller changed.
|
|
324
|
+
*
|
|
325
|
+
* What the split earns: `carry`, because what is left is an extension's configuration and a bundle should
|
|
326
|
+
* arrive with it; and `versioned`, because turning an extension's behaviour on is a decision, and the file
|
|
327
|
+
* that records it can now be read without reading anybody's token. The boot sweep is what keeps that true of
|
|
328
|
+
* a file the agent can also edit — see vaultExtensionSettingSecrets.
|
|
329
|
+
*
|
|
330
|
+
* NO `note`, and the split is why: a note is printed by the import report beside a SKIPPED entry, so an entry
|
|
331
|
+
* that carries can never show one. "Re-enter the credentials" is now the vault's instruction to give, and the
|
|
332
|
+
* vault is under `.intentic/auth/` — which is skipped, and says so there. */
|
|
297
333
|
{
|
|
298
334
|
path: ".intentic/extension-settings.json",
|
|
299
335
|
invalidates: [],
|
|
300
336
|
why: "Held in a module-level shallowRef store per extension (web's extensionSettingsStore) with no query observer, and deliberately so: api.settings.get must answer SYNCHRONOUSLY from an extension's first activate() line, and the store outlives every component scope. A module-level QueryObserver is the one shape that would make invalidation refetch, and this app already ruled it out — it detaches on the queryClient.clear() at logout (see useSandbox's sandbox-list mirror). So a remote member's setting edit reaches this browser on its next load, not live.",
|
|
301
|
-
portability: "
|
|
302
|
-
|
|
337
|
+
portability: "carry",
|
|
338
|
+
versioned: true,
|
|
303
339
|
},
|
|
304
340
|
/* Unlike the settings file above it, the on/off switch IS observed by a query — the Extensions tab's list,
|
|
305
341
|
* which carries each row's switch position — so a flip made elsewhere (another member, the agent writing the
|
|
@@ -346,6 +382,17 @@ const STATE_FILES = [
|
|
|
346
382
|
why: "Which of the routes each extension DECLARED it has actually called — the evidence behind the permissions list on its row. The one entry here whose empty set is a RATE decision rather than an architectural one: every browser with the app open reports its batch on a timer, so wiring this to the `extensions` query would refetch the whole list every few seconds for a figure nobody is watching change. The tab reads it when it loads, which is when anyone is reading it.",
|
|
347
383
|
portability: "carry",
|
|
348
384
|
},
|
|
385
|
+
/* THE ONE ENTRY WHERE "HOLDS NO CREDENTIAL" IS TRUE AND `versioned` IS STILL WRONG, which is worth stating
|
|
386
|
+
* because it looks like the two above it: an email and a role per row, nothing to vault, and "who may drive
|
|
387
|
+
* this sandbox" is as consequential a fact as any this table tracks.
|
|
388
|
+
*
|
|
389
|
+
* It stays out for two reasons that are not about secrecy. It is a MIRROR — the platform's invite records are
|
|
390
|
+
* the grant, this is the copy the enforcer keeps so a grant it never received is never honoured, and a change
|
|
391
|
+
* here is the two disagreeing rather than anyone deciding something. Review of the decision already exists,
|
|
392
|
+
* on the Access tab, against the record that is authoritative. And tracking it would mean reclassifying it
|
|
393
|
+
* `carry` to satisfy the guard, which is the one thing it must never be: an access list that travelled would
|
|
394
|
+
* let a source sandbox hand itself the target's ownership. Widening the guard for this single entry is the
|
|
395
|
+
* worse trade — it protects every `identity` entry, and most of those ARE credentials. */
|
|
349
396
|
{
|
|
350
397
|
path: ".intentic/members.json",
|
|
351
398
|
invalidates: [],
|
|
@@ -358,13 +405,20 @@ const STATE_FILES = [
|
|
|
358
405
|
/* Keep credentials and conversation state in disjoint top-level trees. Provider homes are intentionally
|
|
359
406
|
* classified as a single secret unit: several CLIs mix OAuth, config, and provider-native thread metadata,
|
|
360
407
|
* and no generic export can safely distinguish those files. The broad root also makes a newly-added provider
|
|
361
|
-
* secret by construction instead of relying on another hand-maintained provider-name list.
|
|
408
|
+
* secret by construction instead of relying on another hand-maintained provider-name list.
|
|
409
|
+
*
|
|
410
|
+
* IT IS NO LONGER ONLY THE AI LOGINS. Both credential splits put their vault here — `capability-secrets.json`
|
|
411
|
+
* and `extension-secrets.json`, sited beside the provider homes precisely because this tree is already
|
|
412
|
+
* outside the file routes, the workspace walk and the search index (composition.ts sites them, and the two
|
|
413
|
+
* stores argue why). So this is now the ONE entry a secret-less bundle leaves behind, and its note is
|
|
414
|
+
* therefore the only place the owner is told what to re-enter: the manifests that name those connections
|
|
415
|
+
* travel, and would otherwise arrive looking complete. */
|
|
362
416
|
{
|
|
363
417
|
path: ".intentic/auth/",
|
|
364
418
|
invalidates: [],
|
|
365
|
-
why: "AI-provider credentials and runtime homes; each account is rendered through owner-gated provider routes.",
|
|
419
|
+
why: "AI-provider credentials and runtime homes, plus the capability and extension-settings secret vaults; each account is rendered through owner-gated provider routes.",
|
|
366
420
|
portability: "secret",
|
|
367
|
-
note: "Sign the agent's AI accounts in again on the Agent tab.",
|
|
421
|
+
note: "Sign the agent's AI accounts in again on the Agent tab, then re-enter each connection's credential on Capabilities and each extension's secret settings on Extensions — both arrived listed but unauthenticated.",
|
|
368
422
|
},
|
|
369
423
|
/* Agent session transcripts, rewritten on every streamed token.
|
|
370
424
|
*
|
|
@@ -538,8 +592,13 @@ export const VERSIONED_STATE_PATHS: readonly string[] = WORKSPACE_STATE_FILES.fi
|
|
|
538
592
|
* ledger is forgotten from, and the forgetting is silent — it ranked loop iteration history and cloned
|
|
539
593
|
* third-party extension source against the user's own code for months before this derivation existed.
|
|
540
594
|
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
595
|
+
* WHAT THE CREDENTIAL SPLITS MOVED ACROSS THIS LINE, since the note that used to sit here said the opposite and
|
|
596
|
+
* was worth replacing rather than deleting. `capabilities.json` was `secret` and unversioned, and the sentence
|
|
597
|
+
* celebrated that the index therefore stopped copying capability tokens into search text. It is `versioned` now
|
|
598
|
+
* and searchable — and the guarantee is unchanged, because the tokens are not in the file any more. The floor
|
|
599
|
+
* moved from "keep the index away from the file that holds credentials" to "the file holds none", which is the
|
|
600
|
+
* stronger of the two: it also holds for the shell, which never consulted this list at all. `auth/` — where those
|
|
601
|
+
* values went, both vaults included — is still denied, and is the entry that was doing the real work all along. */
|
|
543
602
|
export const SEARCHABLE_STATE_PATHS: readonly string[] = WORKSPACE_STATE_FILES.filter((file) => file.versioned || file.authored).map(
|
|
544
603
|
(file) => file.path,
|
|
545
604
|
);
|