@intentic/sandbox-contract 1.211.0 → 1.213.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/agent-catalog.d.ts +1 -1
- package/dist/agent-catalog.d.ts.map +1 -1
- package/dist/agent-catalog.js +12 -6
- package/dist/agent-catalog.js.map +1 -1
- package/dist/chores/fix-deps.d.ts.map +1 -1
- package/dist/chores/fix-deps.js.map +1 -1
- package/dist/contracts/agent.contract.d.ts +2 -2
- package/dist/contracts/endpoints.contract.d.ts +22 -0
- package/dist/contracts/endpoints.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.js +3 -0
- package/dist/contracts/endpoints.contract.js.map +1 -1
- package/dist/events.d.ts +6 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +3 -0
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +10 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +93 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +29 -0
- package/dist/schemas.js.map +1 -1
- package/dist/workspace-state.d.ts +2 -6
- package/dist/workspace-state.d.ts.map +1 -1
- package/dist/workspace-state.js +2 -9
- package/dist/workspace-state.js.map +1 -1
- package/package.json +4 -4
- package/src/agent-catalog.test.ts +5 -1
- package/src/agent-catalog.ts +26 -12
- package/src/chores/fix-deps.ts +5 -9
- package/src/contracts/endpoints.contract.ts +7 -0
- package/src/events.ts +7 -0
- package/src/index.ts +1 -1
- package/src/schemas.ts +76 -0
- package/src/workspace-state.test.ts +32 -2
- package/src/workspace-state.ts +52 -19
|
@@ -59,6 +59,7 @@ declare const STATE_FILES: readonly [{
|
|
|
59
59
|
readonly path: ".intentic/drafts/";
|
|
60
60
|
readonly invalidates: readonly ["drafts"];
|
|
61
61
|
readonly portability: "carry";
|
|
62
|
+
readonly versioned: true;
|
|
62
63
|
readonly authored: true;
|
|
63
64
|
}, {
|
|
64
65
|
readonly path: ".intentic/automations.json";
|
|
@@ -76,12 +77,6 @@ declare const STATE_FILES: readonly [{
|
|
|
76
77
|
readonly invalidates: readonly [];
|
|
77
78
|
readonly why: "Declared by the intentic.automations extension's contributes.files — `automation-approvals` is its query key, not core's.";
|
|
78
79
|
readonly portability: "carry";
|
|
79
|
-
}, {
|
|
80
|
-
readonly path: ".intentic/automations.seeded.json";
|
|
81
|
-
readonly invalidates: readonly [];
|
|
82
|
-
readonly why: "Which default automations this workspace has been offered (default-automations.ts); nothing renders it — it exists so deleting a seeded automation is final.";
|
|
83
|
-
readonly portability: "carry";
|
|
84
|
-
readonly versioned: true;
|
|
85
80
|
}, {
|
|
86
81
|
readonly path: ".intentic/chores/";
|
|
87
82
|
readonly invalidates: readonly [];
|
|
@@ -138,6 +133,7 @@ declare const STATE_FILES: readonly [{
|
|
|
138
133
|
readonly path: ".intentic/workspace-extensions/";
|
|
139
134
|
readonly invalidates: readonly ["extensions"];
|
|
140
135
|
readonly portability: "carry";
|
|
136
|
+
readonly versioned: true;
|
|
141
137
|
readonly authored: true;
|
|
142
138
|
}, {
|
|
143
139
|
readonly path: ".intentic/extension-updates.json";
|
|
@@ -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;
|
|
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
|
@@ -20,7 +20,7 @@ const STATE_FILES = [
|
|
|
20
20
|
portability: "derived",
|
|
21
21
|
note: "Stamps of when each rule last did something; the new sandbox starts its own record.",
|
|
22
22
|
},
|
|
23
|
-
{ path: ".intentic/drafts/", invalidates: ["drafts"], portability: "carry", authored: true },
|
|
23
|
+
{ path: ".intentic/drafts/", invalidates: ["drafts"], portability: "carry", versioned: true, authored: true },
|
|
24
24
|
{
|
|
25
25
|
path: ".intentic/automations.json",
|
|
26
26
|
invalidates: [],
|
|
@@ -40,13 +40,6 @@ const STATE_FILES = [
|
|
|
40
40
|
why: "Declared by the intentic.automations extension's contributes.files — `automation-approvals` is its query key, not core's.",
|
|
41
41
|
portability: "carry",
|
|
42
42
|
},
|
|
43
|
-
{
|
|
44
|
-
path: ".intentic/automations.seeded.json",
|
|
45
|
-
invalidates: [],
|
|
46
|
-
why: "Which default automations this workspace has been offered (default-automations.ts); nothing renders it — it exists so deleting a seeded automation is final.",
|
|
47
|
-
portability: "carry",
|
|
48
|
-
versioned: true,
|
|
49
|
-
},
|
|
50
43
|
{
|
|
51
44
|
path: ".intentic/chores/",
|
|
52
45
|
invalidates: [],
|
|
@@ -95,7 +88,7 @@ const STATE_FILES = [
|
|
|
95
88
|
portability: "carry",
|
|
96
89
|
versioned: true,
|
|
97
90
|
},
|
|
98
|
-
{ path: ".intentic/workspace-extensions/", invalidates: ["extensions"], portability: "carry", authored: true },
|
|
91
|
+
{ path: ".intentic/workspace-extensions/", invalidates: ["extensions"], portability: "carry", versioned: true, authored: true },
|
|
99
92
|
{ path: ".intentic/extension-updates.json", invalidates: ["extensions"], portability: "carry" },
|
|
100
93
|
{ path: ".intentic/extension-update-policy.json", invalidates: ["extensions"], portability: "carry", versioned: true },
|
|
101
94
|
{
|
|
@@ -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;
|
|
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.213.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/extension-manifest": "1.
|
|
94
|
-
"@intentic/registry": "1.
|
|
92
|
+
"@intentic/constants": "1.213.0",
|
|
93
|
+
"@intentic/extension-manifest": "1.213.0",
|
|
94
|
+
"@intentic/registry": "1.213.0"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@types/node": "24.13.2",
|
|
@@ -41,7 +41,7 @@ describe("every provider/harness pair declares what it can do", () => {
|
|
|
41
41
|
// is the drift this record exists to end.
|
|
42
42
|
expect(["claude-code", "codex", "opencode", "opencode-gemini", "acp", "pi"]).toContain(capabilities.runtime);
|
|
43
43
|
expect(["modes", "plan"]).toContain(capabilities.permissions);
|
|
44
|
-
expect(["full", "http", "none"]).toContain(capabilities.mcp);
|
|
44
|
+
expect(["full", "browser", "http", "none"]).toContain(capabilities.mcp);
|
|
45
45
|
// Every runtime executes SOMETHING — a record listing no backend would hide the shell every loop has.
|
|
46
46
|
expect(capabilities.execution).toContain("shell");
|
|
47
47
|
for (const backend of capabilities.execution) {
|
|
@@ -155,6 +155,10 @@ test("the ceiling has nothing to disclose; a floor names what it lacks", () => {
|
|
|
155
155
|
expect(acp).toContain("MCP tools only — no plugins or browser");
|
|
156
156
|
expect(acp).not.toContain("no slash commands");
|
|
157
157
|
expect(acp).not.toContain("no terminal panel");
|
|
158
|
+
|
|
159
|
+
const codex = limitationsOf(capabilitiesOf("codex", "native"));
|
|
160
|
+
expect(codex).toContain("browser tools only — no plugins or other MCP tools");
|
|
161
|
+
expect(codex).not.toContain("no MCP tools or plugins");
|
|
158
162
|
});
|
|
159
163
|
|
|
160
164
|
test("every axis a record can lack has words for it", () => {
|
package/src/agent-catalog.ts
CHANGED
|
@@ -211,9 +211,11 @@ export interface AgentCapabilities {
|
|
|
211
211
|
// Can stop mid-turn and ask the user a multiple-choice question (`question` frames).
|
|
212
212
|
readonly questions: boolean;
|
|
213
213
|
// Which of the turn's tools reach the agent. "full" = http MCP tools + in-process SDK servers + plugin
|
|
214
|
-
// checkouts + the browser servers; "
|
|
215
|
-
// MCP support; "none" = the runtime has no seam for
|
|
216
|
-
|
|
214
|
+
// checkouts + the browser servers; "browser" = the process-backed browser servers alone; "http" = the http
|
|
215
|
+
// MCP tools alone, and only if the agent advertises http MCP support; "none" = the runtime has no seam for
|
|
216
|
+
// them at all. Keeping the partial answers distinct matters: a runtime that can drive a connected account
|
|
217
|
+
// must not be described as tool-less, and one that cannot host daemon-side SDK servers must not claim full.
|
|
218
|
+
readonly mcp: "full" | "browser" | "http" | "none";
|
|
217
219
|
/* WHICH EXECUTION BACKENDS THE RUNTIME HOSTS — the ways a turn RUNS things, as opposed to the tools it is
|
|
218
220
|
* handed. "shell" is the runtime's own command tool (Bash on the Claude Code loop, each foreign loop's
|
|
219
221
|
* equivalent); "js" is the sandbox's JavaScript backend (execution/ in the daemon): the model writes a
|
|
@@ -291,20 +293,26 @@ const CLAUDE_CODE: AgentCapabilities = {
|
|
|
291
293
|
instructions: "replace",
|
|
292
294
|
};
|
|
293
295
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
/* Codex app-server: item-level events, process-backed MCP servers, and the four interactive seams its protocol
|
|
297
|
+
* actually publishes — `turn/steer` for mid-turn injection, the experimental `item/tool/requestUserInput` server
|
|
298
|
+
* request behind a question card, `skills/list` for the `/` popover (a picked command rides back as a structured
|
|
299
|
+
* skill input), and the same mount namespace the Claude Code loop gets, because app-server is a child process
|
|
300
|
+
* the adapter spawns and nsenter can put it in the turn's namespace like any other.
|
|
301
|
+
*
|
|
302
|
+
* Browser servers ride the per-thread config; daemon-side SDK servers, plugins and server-initiated APPROVALS
|
|
303
|
+
* stay unwired — the container is the isolation boundary, so approvals are declined by design rather than
|
|
304
|
+
* missing (codex-app-server.ts refuses every server request but the question one). */
|
|
297
305
|
const CODEX: AgentCapabilities = {
|
|
298
306
|
runtime: "codex",
|
|
299
|
-
steering:
|
|
307
|
+
steering: true,
|
|
300
308
|
permissions: "plan",
|
|
301
|
-
questions:
|
|
302
|
-
mcp: "
|
|
309
|
+
questions: true,
|
|
310
|
+
mcp: "browser",
|
|
303
311
|
execution: ["shell"],
|
|
304
312
|
effort: true,
|
|
305
313
|
fastMode: false,
|
|
306
|
-
isolation: "
|
|
307
|
-
commands:
|
|
314
|
+
isolation: "namespace",
|
|
315
|
+
commands: true,
|
|
308
316
|
terminals: false,
|
|
309
317
|
recovery: false,
|
|
310
318
|
/* Both halves, through the per-thread `config` block the adapter already sends: `model_instructions_file`
|
|
@@ -459,7 +467,13 @@ export const limitationsOf = (capabilities: AgentCapabilities): string[] => [
|
|
|
459
467
|
...(capabilities.permissions === "plan" ? ["no per-tool approvals"] : []),
|
|
460
468
|
...(capabilities.questions ? [] : ["no clarifying questions"]),
|
|
461
469
|
...(capabilities.steering ? [] : ["no mid-turn steering"]),
|
|
462
|
-
...(capabilities.mcp === "none"
|
|
470
|
+
...(capabilities.mcp === "none"
|
|
471
|
+
? ["no MCP tools or plugins"]
|
|
472
|
+
: capabilities.mcp === "http"
|
|
473
|
+
? ["MCP tools only — no plugins or browser"]
|
|
474
|
+
: capabilities.mcp === "browser"
|
|
475
|
+
? ["browser tools only — no plugins or other MCP tools"]
|
|
476
|
+
: []),
|
|
463
477
|
...(capabilities.execution.includes("js") ? [] : ["no code runs — its shell is the one way to execute"]),
|
|
464
478
|
...(capabilities.effort ? [] : ["no effort control"]),
|
|
465
479
|
...(capabilities.commands ? [] : ["no slash commands"]),
|
package/src/chores/fix-deps.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
/* THE FIX CHORE —
|
|
1
|
+
/* THE FIX CHORE — the template for opting into dependency-breakage repair.
|
|
2
2
|
*
|
|
3
|
-
* The
|
|
4
|
-
* automations extension offers it as a recipe for anyone who deleted it and wants it back. Written once here
|
|
5
|
-
* for the chore book's own reason: two copies of a prompt drift, and only one of them gets fixed when we
|
|
6
|
-
* learn how to phrase it.
|
|
3
|
+
* The automations catalogue offers it as a recipe; nothing creates it until the owner picks that template.
|
|
7
4
|
*
|
|
8
5
|
* It wakes on `deps.broken` — the dependency verifier's edge event: a landed change drifted the installed
|
|
9
6
|
* dependencies, the daemon reinstalled them, ran the tree's own checks, and they came back red. The payload
|
|
@@ -16,10 +13,9 @@
|
|
|
16
13
|
* Attempt 1 is the breakage, attempt 2 is one landed fix that still failed; past that the loop stops and the
|
|
17
14
|
* standing red is the owner's to read (the activity feed has been narrating every step).
|
|
18
15
|
*
|
|
19
|
-
* THE HOLD IS THE
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* before it starts, cancellable the whole way, and it never starts while another agent is mid-turn. */
|
|
16
|
+
* THE HOLD IS THE SECOND CHANCE. After the owner creates the automation from its template, each fire is held,
|
|
17
|
+
* visibly, for this many seconds on the Automations page before it starts, cancellable the whole way, and it
|
|
18
|
+
* never starts while another agent is mid-turn. */
|
|
23
19
|
export const FIX_DEPS_AUTOMATION = {
|
|
24
20
|
id: "fix-dependency-breakage",
|
|
25
21
|
title: "Fix what a dependency change broke",
|
|
@@ -15,13 +15,20 @@ import { CapabilityIdParamSchema, ModelsSchema } from "../schemas.js";
|
|
|
15
15
|
* `available` false is the ordinary answer, not an error: most sandboxes run against a platform that serves no
|
|
16
16
|
* trial, and the picker simply has no trial row to badge.
|
|
17
17
|
*/
|
|
18
|
+
const TrialHealthSchema = z.enum(["unknown", "healthy", "degraded", "unavailable"]);
|
|
19
|
+
export type TrialHealth = z.infer<typeof TrialHealthSchema>;
|
|
20
|
+
|
|
18
21
|
export const TrialStatusSchema = z.object({
|
|
19
22
|
available: z.boolean(),
|
|
20
23
|
allowance: z.number().int().nonnegative(),
|
|
21
24
|
used: z.number().int().nonnegative(),
|
|
22
25
|
remaining: z.number().int().nonnegative(),
|
|
26
|
+
// The shared trial pool's last real chat outcome. `unknown` means no recent turn has measured it.
|
|
27
|
+
health: TrialHealthSchema,
|
|
23
28
|
// ISO stamp of the next reset, absent until the platform has answered once.
|
|
24
29
|
resetsAt: z.string().optional(),
|
|
30
|
+
// Earliest known time a quarantined upstream key can be tried again.
|
|
31
|
+
retryAt: z.string().optional(),
|
|
25
32
|
});
|
|
26
33
|
export type TrialStatusResponse = z.infer<typeof TrialStatusSchema>;
|
|
27
34
|
|
package/src/events.ts
CHANGED
|
@@ -671,6 +671,13 @@ export const AgentEventSchema = z.discriminatedUnion("kind", [
|
|
|
671
671
|
// backoff (provider-health.ts): the frame is a notice about a turn that is coming back, and
|
|
672
672
|
// reaches the client as a plain failure only once the attempts are spent.
|
|
673
673
|
"provider-outage",
|
|
674
|
+
// The platform-owned free-trial pool failed after its bounded key walk. Unlike provider-outage,
|
|
675
|
+
// this is never auto-resumed: failed calls are refunded and the user's message is held to retry.
|
|
676
|
+
"trial-unavailable",
|
|
677
|
+
// The trial answered, but the selected upstream model/request cannot run through this sandbox.
|
|
678
|
+
"trial-model-unavailable",
|
|
679
|
+
// This account's platform-owned daily trial allowance is spent until its UTC reset.
|
|
680
|
+
"trial-exhausted",
|
|
674
681
|
// The harness read the message as a slash command it doesn't have, and discarded everything
|
|
675
682
|
// after the name — the model never saw the message. Nothing was processed, so the client holds
|
|
676
683
|
// the text back instead of leaving the user to retype it (same treatment as claude-reauth).
|
package/src/index.ts
CHANGED
|
@@ -46,7 +46,7 @@ export { choresContract } from "./contracts/chores.contract.js";
|
|
|
46
46
|
export { ciContract } from "./contracts/ci.contract.js";
|
|
47
47
|
export { claudeContract } from "./contracts/claude.contract.js";
|
|
48
48
|
export { draftsContract } from "./contracts/drafts.contract.js";
|
|
49
|
-
export { endpointsContract, TrialStatusSchema, type TrialStatusResponse } from "./contracts/endpoints.contract.js";
|
|
49
|
+
export { endpointsContract, type TrialHealth, TrialStatusSchema, type TrialStatusResponse } from "./contracts/endpoints.contract.js";
|
|
50
50
|
export { extensionsContract } from "./contracts/extensions.contract.js";
|
|
51
51
|
export { personasContract } from "./contracts/personas.contract.js";
|
|
52
52
|
export { gitContract } from "./contracts/git.contract.js";
|
package/src/schemas.ts
CHANGED
|
@@ -5995,6 +5995,82 @@ export const ImportReportSchema = z.object({
|
|
|
5995
5995
|
});
|
|
5996
5996
|
export type ImportReport = z.infer<typeof ImportReportSchema>;
|
|
5997
5997
|
|
|
5998
|
+
/* ---- migrations: importing a FOREIGN assistant's setup (Hermes, OpenClaw) ----
|
|
5999
|
+
*
|
|
6000
|
+
* A different crossing than a bundle restore, and deliberately a different surface: a bundle is our own format,
|
|
6001
|
+
* re-derived entry by entry against the state manifests, while a migration reads a directory some OTHER
|
|
6002
|
+
* program laid out (`~/.hermes`) and TRANSLATES it into native things — skills, automations, capabilities,
|
|
6003
|
+
* merged memory. Nothing foreign is executed or copied verbatim into daemon state; every item lands through the
|
|
6004
|
+
* same write paths the settings/skills/automations/capabilities surfaces use, which is what keeps an imported
|
|
6005
|
+
* setup editable and deletable in the ordinary UI the day after (docs/assistant-import-design.md).
|
|
6006
|
+
*
|
|
6007
|
+
* The flow is PREVIEW-FIRST, mirroring what these tools' own `migrate` commands taught their users to expect:
|
|
6008
|
+
* `plan` parses the uploaded archive into an itemized checklist and holds the upload in memory under a token;
|
|
6009
|
+
* `apply` names the ticked item ids and the token. The plan is RE-DERIVED from the held archive at apply — the
|
|
6010
|
+
* wire plan is a rendering for the owner, never the input the write trusts (restore.ts's rule, kept). */
|
|
6011
|
+
export const MigrationSourceSchema = z.enum(["hermes", "openclaw"]);
|
|
6012
|
+
export type MigrationSource = z.infer<typeof MigrationSourceSchema>;
|
|
6013
|
+
|
|
6014
|
+
// What an item becomes here, not what it was there — the apply loop dispatches on this, and the checklist
|
|
6015
|
+
// groups by it so the owner reads "3 skills, 2 automations" rather than a foreign directory listing.
|
|
6016
|
+
export const MigrationTargetSchema = z.enum(["memory", "skill", "automation", "capability", "secret", "file"]);
|
|
6017
|
+
export type MigrationTarget = z.infer<typeof MigrationTargetSchema>;
|
|
6018
|
+
|
|
6019
|
+
export const MigrationItemSchema = z.object({
|
|
6020
|
+
// Deterministic (derived from the source artifact, e.g. `skill:weather`), so the ids the owner ticked name
|
|
6021
|
+
// the same items when the plan is re-derived at apply.
|
|
6022
|
+
id: z.string(),
|
|
6023
|
+
target: MigrationTargetSchema,
|
|
6024
|
+
// The checklist line, plain words: "Skill — weather", "Nightly digest (9:00 every day)".
|
|
6025
|
+
label: z.string(),
|
|
6026
|
+
detail: z.string().optional(),
|
|
6027
|
+
/* The default tick. False marks the items the owner should read before taking — a server URL that points at
|
|
6028
|
+
* localhost on the OLD machine, an .env key that looks like tuning rather than a credential. They still
|
|
6029
|
+
* import fine when ticked; the flag is the adapter's judgment, not a gate. */
|
|
6030
|
+
recommended: z.boolean(),
|
|
6031
|
+
// Names of the secrets this item would store (never values — values stay in the held archive until apply,
|
|
6032
|
+
// and only move when the apply says includeSecrets). Empty for items that carry none.
|
|
6033
|
+
secrets: z.array(z.string()),
|
|
6034
|
+
});
|
|
6035
|
+
export type MigrationItem = z.infer<typeof MigrationItemSchema>;
|
|
6036
|
+
|
|
6037
|
+
export const MigrationNeedsActionSchema = z.object({ subject: z.string(), detail: z.string() });
|
|
6038
|
+
|
|
6039
|
+
export const MigrationPlanSchema = z.object({
|
|
6040
|
+
source: MigrationSourceSchema,
|
|
6041
|
+
// Names the held upload for the apply call. Minted per plan; a new upload replaces the held one.
|
|
6042
|
+
token: z.string(),
|
|
6043
|
+
items: z.array(MigrationItemSchema),
|
|
6044
|
+
// What the adapter saw and will not move — sessions, logs, pairing state — listed rather than silent.
|
|
6045
|
+
refused: z.array(z.string()),
|
|
6046
|
+
// What is already known not to move mechanically (channels to reconnect, a model to pick) — the same
|
|
6047
|
+
// honesty ImportReportSchema carries, surfaced at PREVIEW time so the owner ticks with open eyes.
|
|
6048
|
+
needsAction: z.array(MigrationNeedsActionSchema),
|
|
6049
|
+
});
|
|
6050
|
+
export type MigrationPlan = z.infer<typeof MigrationPlanSchema>;
|
|
6051
|
+
|
|
6052
|
+
export const MigrationApplySchema = z.object({
|
|
6053
|
+
token: z.string(),
|
|
6054
|
+
// The ticked item ids. Ids the re-derived plan does not contain are ignored rather than erroring — the
|
|
6055
|
+
// archive is the truth, and a stale checklist must not block the items that still exist.
|
|
6056
|
+
items: z.array(z.string()),
|
|
6057
|
+
// The owner's explicit consent to move credential VALUES (mirrors the bundle export's `?secrets=`, and the
|
|
6058
|
+
// `--include-secrets` these tools' own migrate commands require). Off: secret items are skipped and
|
|
6059
|
+
// capability configs land without their keys.
|
|
6060
|
+
includeSecrets: z.boolean(),
|
|
6061
|
+
});
|
|
6062
|
+
export type MigrationApply = z.infer<typeof MigrationApplySchema>;
|
|
6063
|
+
|
|
6064
|
+
export const MigrationReportSchema = z.object({
|
|
6065
|
+
applied: z.array(z.object({ id: z.string(), target: MigrationTargetSchema, label: z.string() })),
|
|
6066
|
+
// Items that were ticked and did not land, each with the reason — a full disk, an env store that needs
|
|
6067
|
+
// DevOps active. Distinct from `refused`, which is the class of things never attempted.
|
|
6068
|
+
failed: z.array(z.object({ id: z.string(), label: z.string(), error: z.string() })),
|
|
6069
|
+
refused: z.array(z.string()),
|
|
6070
|
+
needsAction: z.array(MigrationNeedsActionSchema),
|
|
6071
|
+
});
|
|
6072
|
+
export type MigrationReport = z.infer<typeof MigrationReportSchema>;
|
|
6073
|
+
|
|
5998
6074
|
/* One export sitting in the daemon's export directory — the ARTIFACT a bundle is, rather than the request that
|
|
5999
6075
|
* produced it. Packing takes minutes over a real workspace, so tying it to a response made it a property of one
|
|
6000
6076
|
* browser tab: a refresh abandoned the work and left nothing to come back to. It is a file now, and every field
|
|
@@ -265,11 +265,16 @@ describe(`VERSIONED_STATE_PATHS`, () => {
|
|
|
265
265
|
|
|
266
266
|
/* Spelled out rather than derived, so ADDING a tracked entry is a visible edit to this list and not a silent
|
|
267
267
|
* consequence of editing the table above — the review the flag itself exists to force. */
|
|
268
|
-
it(`tracks exactly the configuration slice`, () => {
|
|
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
|
-
`.intentic/automations.seeded.json`,
|
|
272
271
|
`.intentic/capability-dismissals.json`,
|
|
272
|
+
/* The two entries the AGENT authors on its own initiative, and the reason `versioned` is not read as
|
|
273
|
+
* config-only. Both are the sandbox acting outward — a draft publishes words under the owner's name,
|
|
274
|
+
* a workspace extension is code that runs in the app and can serve HTTP with the workspace under
|
|
275
|
+
* node:fs — and both used to reach that far with no diff anywhere. Kept rather than consumed, one
|
|
276
|
+
* small file at a time, so tracking them yields a record instead of churn. */
|
|
277
|
+
`.intentic/drafts/`,
|
|
273
278
|
`.intentic/environment.Dockerfile`,
|
|
274
279
|
`.intentic/environment.custom.Dockerfile`,
|
|
275
280
|
`.intentic/environment.d/`,
|
|
@@ -288,9 +293,34 @@ describe(`VERSIONED_STATE_PATHS`, () => {
|
|
|
288
293
|
`.intentic/skills/`,
|
|
289
294
|
`.intentic/templates.json`,
|
|
290
295
|
`.intentic/workflows.json`,
|
|
296
|
+
`.intentic/workspace-extensions/`,
|
|
291
297
|
]);
|
|
292
298
|
});
|
|
293
299
|
|
|
300
|
+
/* THE ASYMMETRY THIS CLOSED, kept as its own assertion because it is the failure rather than a detail of it:
|
|
301
|
+
* the switch was tracked and the thing it switched was not, so a commit could record turning on an extension
|
|
302
|
+
* whose code nobody else could read — and a workspace extension has no install moment to review at instead. */
|
|
303
|
+
it(`tracks a workspace extension's code, not just the switch that enables it`, () => {
|
|
304
|
+
expect(VERSIONED_STATE_PATHS).toContain(`.intentic/extension-enablement.json`);
|
|
305
|
+
expect(VERSIONED_STATE_PATHS).toContain(`.intentic/workspace-extensions/`);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
/* A QUEUE IS A LEDGER, which is the distinction the two entries above turn on. A draft is kept after it
|
|
309
|
+
* settles (`posted`, with postedAt/postedUrl stamped on it), so tracking it leaves a durable record of what
|
|
310
|
+
* went out; a held wake is REMOVED once answered, so tracking it would leave an add and a delete describing
|
|
311
|
+
* a decision whose outcome lives elsewhere. Same for the staged docs: publishing copies them into the repo,
|
|
312
|
+
* where they are tracked as ordinary content, so tracking the staging tree too would double every page. */
|
|
313
|
+
it(`leaves the consumed queues and the staging trees out even though they are authored`, () => {
|
|
314
|
+
for (const path of [`.intentic/approvals/`, `.intentic/docs/`]) {
|
|
315
|
+
expect([path, VERSIONED_STATE_PATHS.includes(path)]).toEqual([path, false]);
|
|
316
|
+
}
|
|
317
|
+
// Both still reach workspace search — searchability is a property of the content, not of tracking.
|
|
318
|
+
for (const path of [`.intentic/approvals/`, `.intentic/docs/`]) {
|
|
319
|
+
const entry = WORKSPACE_STATE_FILES.find((file) => file.path === path);
|
|
320
|
+
expect([path, entry?.versioned === true || entry?.authored === true]).toEqual([path, path === `.intentic/docs/`]);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
294
324
|
/* The composed overlay is `derived` — recomposed on every boot from the custom file that IS tracked, against
|
|
295
325
|
* whatever base image this container happens to be on. Tracking it would put a rewritten-at-startup file in
|
|
296
326
|
* front of the owner as a change they made. */
|
package/src/workspace-state.ts
CHANGED
|
@@ -60,11 +60,23 @@ export interface WorkspaceStateFile extends StateFile {
|
|
|
60
60
|
* the same reason. An ignore-pattern list would invert it: a credential store added next month would be
|
|
61
61
|
* committed on its first write, and nothing would have had to change for that to happen.
|
|
62
62
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* -
|
|
66
|
-
*
|
|
67
|
-
*
|
|
63
|
+
* WHAT EARNS IT is one question, asked of the entry rather than of its shape: does a change here change what
|
|
64
|
+
* this sandbox DOES? Two families answer yes.
|
|
65
|
+
* - CONFIGURATION — the small, slow-moving files that decide how the sandbox behaves: settings, personas,
|
|
66
|
+
* skills, automations, workflow designs, the environment overlay, which extensions are on.
|
|
67
|
+
* - AUTHORED CONTENT WHOSE CONSEQUENCES LEAVE THE SANDBOX — a workspace extension is code that runs in the
|
|
68
|
+
* app with a declared permission surface and a backend of its own; a post draft is words that go out
|
|
69
|
+
* under the owner's name. Neither is configuration, and reading `versioned` as config-only is what kept
|
|
70
|
+
* both of them out: an agent could write, and then run, a whole extension with a diff nowhere, and
|
|
71
|
+
* propose a public post that left no trace once declined. The rule was never "is this a setting", it was
|
|
72
|
+
* "can this be read, reverted and attributed" — and for the two things the AGENT authors on its own,
|
|
73
|
+
* that matters more than it does for a file a person edited on purpose.
|
|
74
|
+
*
|
|
75
|
+
* Two kinds of entry stay out on purpose even though they are `carry` and hold no secret:
|
|
76
|
+
* - LEDGERS (workflow runs, loop iterations, thread bookkeeping, permission-usage batches, held-wake
|
|
77
|
+
* queues), which are rewritten on a timer or several times per step. Tracking them buries the owner's
|
|
78
|
+
* code review under machine noise — one of them is written every few seconds while a browser has the app
|
|
79
|
+
* open. A queue is a ledger too: it records that something was ASKED, and is emptied when it is answered.
|
|
68
80
|
* - BULK (session transcripts, artifacts), which are hundreds of megabytes of constantly-rewritten
|
|
69
81
|
* content. They travel in a bundle; they do not belong in a diff.
|
|
70
82
|
* `versioned` is therefore NARROWER than `carry`, and the two answer different questions: carry is "does it
|
|
@@ -74,7 +86,10 @@ export interface WorkspaceStateFile extends StateFile {
|
|
|
74
86
|
* human- or agent-written TEXT that a workspace search should surface? Every `versioned` entry already is
|
|
75
87
|
* (a setting, a persona, a skill — things the agent is asked to find and edit), so this flag exists only
|
|
76
88
|
* for the entries that are authored content without being config: a draft awaiting approval, a staged
|
|
77
|
-
* README, an extension the agent wrote in place.
|
|
89
|
+
* README, an extension the agent wrote in place. Two of those three are now `versioned` as well, which makes
|
|
90
|
+
* the flag redundant to `SEARCHABLE_STATE_PATHS` on them and is why it stays anyway: searchability is a
|
|
91
|
+
* property of the content, and hanging it on `versioned` would mean a future decision to stop TRACKING a
|
|
92
|
+
* draft silently also stopped anyone FINDING one. Everything else under `.intentic` is machine state, and
|
|
78
93
|
* `SEARCHABLE_STATE_PATHS` below is what lets the search engine deny the rest BY DEFAULT instead of
|
|
79
94
|
* hand-keeping a deny list that goes stale the day a store is added (which is how a 98 kB loop ledger and
|
|
80
95
|
* whole third-party extension checkouts ended up ranking in code search). */
|
|
@@ -159,10 +174,22 @@ const STATE_FILES = [
|
|
|
159
174
|
portability: "derived",
|
|
160
175
|
note: "Stamps of when each rule last did something; the new sandbox starts its own record.",
|
|
161
176
|
},
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
177
|
+
/* Written by the AGENT's file tools (the drafts skill), read by the owner's approval inbox — the one entry
|
|
178
|
+
* here whose whole point is that a change arrives from outside the browser that renders it. `authored`:
|
|
179
|
+
* a draft is text somebody wrote, and "find the reddit draft about X" is an ordinary search.
|
|
180
|
+
*
|
|
181
|
+
* `versioned` because a draft is the furthest-reaching thing the agent writes: these words go out under the
|
|
182
|
+
* owner's name, to an audience, and cannot be recalled. The approval inbox already gates that — but a gate is
|
|
183
|
+
* not a record. Declining one used to erase it, so the question "what has this agent tried to post" had no
|
|
184
|
+
* answer at all, and an approved post's own history (what was proposed, what the owner changed, when it
|
|
185
|
+
* actually went) lived only in a file nobody could diff.
|
|
186
|
+
*
|
|
187
|
+
* It costs almost nothing to track, which is why the ledger objection does not reach it: a draft is one small
|
|
188
|
+
* file per post, it is written a handful of times across its whole life (proposed → approved → posted, with
|
|
189
|
+
* `postedAt`/`postedUrl` stamped at the end), and it is KEPT afterwards rather than consumed — so tracking
|
|
190
|
+
* yields a durable record instead of the add/delete churn a queue would produce. Nothing in a draft is a
|
|
191
|
+
* credential: it is a platform, a target URL and the body itself, all of it bound for publication anyway. */
|
|
192
|
+
{ path: ".intentic/drafts/", invalidates: ["drafts"], portability: "carry", versioned: true, authored: true },
|
|
166
193
|
// ---- declared by the extension that renders them (contributes.files), not here ----
|
|
167
194
|
// The path is the DAEMON's (automations-store writes both), the query keys are the intentic.automations
|
|
168
195
|
// extension's. It declares them in its own manifest and the browser unions the two lists, so uninstalling
|
|
@@ -199,13 +226,6 @@ const STATE_FILES = [
|
|
|
199
226
|
why: "Declared by the intentic.automations extension's contributes.files — `automation-approvals` is its query key, not core's.",
|
|
200
227
|
portability: "carry",
|
|
201
228
|
},
|
|
202
|
-
{
|
|
203
|
-
path: ".intentic/automations.seeded.json",
|
|
204
|
-
invalidates: [],
|
|
205
|
-
why: "Which default automations this workspace has been offered (default-automations.ts); nothing renders it — it exists so deleting a seeded automation is final.",
|
|
206
|
-
portability: "carry",
|
|
207
|
-
versioned: true,
|
|
208
|
-
},
|
|
209
229
|
/* The maintenance ledger and probe evidence, written by the daemon's chores-store and rendered by the
|
|
210
230
|
* intentic.maintenance extension — the automations shape exactly: the path is the daemon's, the query keys
|
|
211
231
|
* (`maintenance-report`, `maintenance-runs`) are the extension's own contributes.files. Point-in-time
|
|
@@ -296,8 +316,21 @@ const STATE_FILES = [
|
|
|
296
316
|
* an extension and it is live for the daemon and every session at once, since .intentic is shared), so this
|
|
297
317
|
* push is what makes one appearing or changing show up on the Extensions tab while the owner watches.
|
|
298
318
|
* `authored` for the same reason as drafts: this is source the agent wrote and will be asked to find —
|
|
299
|
-
* unlike `.intentic/extensions/` below, which is CLONES of source that lives elsewhere.
|
|
300
|
-
|
|
319
|
+
* unlike `.intentic/extensions/` below, which is CLONES of source that lives elsewhere.
|
|
320
|
+
*
|
|
321
|
+
* `versioned` FOR THAT SAME REASON, which is the whole argument. Every other load path an extension can take
|
|
322
|
+
* is already reviewable by construction: a git-installed one is a sha in `capabilities.json` that an owner
|
|
323
|
+
* approved, a baked one shipped in the image. This one is neither — it is code that appears because an agent
|
|
324
|
+
* wrote a file, runs in the app on the owner's session, may register a rail tile, and may serve HTTP from a
|
|
325
|
+
* node process with the workspace under `node:fs` and whatever `permissions.daemon` names. Untracked, the
|
|
326
|
+
* switch that turns it on was in `git log` (extension-enablement.json, below) while the thing being switched
|
|
327
|
+
* on was not: a commit could record enabling something nobody else could read. It is also the one extension
|
|
328
|
+
* kind with no install moment to review at, so the diff is the only review there is.
|
|
329
|
+
*
|
|
330
|
+
* Not a ledger and not bulk: a handful of small authored files per extension, written when someone edits them.
|
|
331
|
+
* The daemon restarts the backend host on a change here, so an edit is already a consequential event — this
|
|
332
|
+
* makes it a legible one. */
|
|
333
|
+
{ path: ".intentic/workspace-extensions/", invalidates: ["extensions"], portability: "carry", versioned: true, authored: true },
|
|
301
334
|
/* What the registry comparison found per installed extension (update available / advisory / post-update
|
|
302
335
|
* health), written by the periodic check and by the update/revert transactions — pushed to the tab because
|
|
303
336
|
* an advisory that auto-disabled something must not wait for a reload to be seen. */
|