@coryrylan/cradle 0.0.0 → 1.3.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/CHANGELOG.md +38 -0
- package/README.md +63 -37
- package/dist/agent/aliases.d.ts +2 -2
- package/dist/agent/extensions/agent-browser-nono-fallback.d.ts +3 -0
- package/dist/agent/extensions/providers.d.ts +12 -1
- package/dist/agent/folder.d.ts +31 -5
- package/dist/agent/launch.d.ts +35 -21
- package/dist/agent/package-filters.d.ts +13 -0
- package/dist/agent/packages.d.ts +24 -10
- package/dist/commands/doctor.d.ts +5 -6
- package/dist/commands/{start.d.ts → run.d.ts} +50 -16
- package/dist/index.js +45 -28
- package/dist/nono/profiles.d.ts +1 -1
- package/dist/sbx/compose.d.ts +115 -0
- package/dist/util/proc.d.ts +11 -0
- package/package.json +10 -7
package/dist/nono/profiles.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export interface ProfileSpec {
|
|
|
45
45
|
* `extends default`, pulls the `node_runtime` group, and grants mise/pi/say
|
|
46
46
|
* paths) merged with this run's grants — the target cwd, the agent folder, the
|
|
47
47
|
* state dir, the linked git dir when cwd is a worktree/submodule checkout, and
|
|
48
|
-
* the agent's own `sandbox/nono.json
|
|
48
|
+
* the agent's own path and direct-child Unix socket grants from `sandbox/nono.json`. Regenerated every run into the
|
|
49
49
|
* state dir, so there is no shared global profile: each agent's permissions
|
|
50
50
|
* are fully described by its own directory.
|
|
51
51
|
*
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { AgentNetwork, AgentSandboxGrants } from '../agent/folder.js';
|
|
2
|
+
/**
|
|
3
|
+
* Guest `localhost` resolves to the microVM itself, not the host — host
|
|
4
|
+
* loopback is reachable at this gateway, which sbx routes through the policy
|
|
5
|
+
* proxy. Used both to rewrite `allowDomain` localhost entries (see
|
|
6
|
+
* `composeSbxPolicyArgvs`) and caller-supplied base URLs (see
|
|
7
|
+
* `rewriteLocalhostBaseUrl`).
|
|
8
|
+
*/
|
|
9
|
+
export declare const SBX_HOST_GATEWAY = "host.docker.internal";
|
|
10
|
+
/** A single sbx mount: a host path (preserved verbatim in the guest) and its access mode. */
|
|
11
|
+
export interface SbxMount {
|
|
12
|
+
readonly path: string;
|
|
13
|
+
readonly readonly: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Everything `composeSbxCreateArgv`, `composeSbxPolicyArgvs`,
|
|
17
|
+
* `composeSbxProvisionArgv`, and `composeSbxExecArgv` need — the sbx analog of
|
|
18
|
+
* nono's `ProfileSpec`.
|
|
19
|
+
*/
|
|
20
|
+
export interface SbxSpec {
|
|
21
|
+
/** Resolved path, or bare `sbx` for dry-run previews. */
|
|
22
|
+
readonly sbxBin: string;
|
|
23
|
+
/** Sandbox name from `sbxSandboxName()`. */
|
|
24
|
+
readonly name: string;
|
|
25
|
+
/** The target project — always the first (rw) workspace mount. */
|
|
26
|
+
readonly cwd: string;
|
|
27
|
+
/** Host home dir — for the exec `HOME` override and the `~/.pi/agent` mount. */
|
|
28
|
+
readonly home: string;
|
|
29
|
+
/** From `composeSbxMounts()`; cwd first. Fixed at sandbox creation time. */
|
|
30
|
+
readonly mounts: readonly SbxMount[];
|
|
31
|
+
/** Precedence-resolved network posture — the same shape nono consumes. */
|
|
32
|
+
readonly network?: AgentNetwork;
|
|
33
|
+
/** Host pi version to pin in-guest; `null` = install only if missing. */
|
|
34
|
+
readonly piVersion: string | null;
|
|
35
|
+
/** Pass `-t` on exec — set when a TTY is present. */
|
|
36
|
+
readonly tty: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** Inputs to `composeSbxMounts` — everything that can contribute a guest mount. */
|
|
39
|
+
export interface SbxMountContext {
|
|
40
|
+
readonly cwd: string;
|
|
41
|
+
readonly agentDir: string;
|
|
42
|
+
readonly stateDir: string;
|
|
43
|
+
readonly home: string;
|
|
44
|
+
readonly grants: AgentSandboxGrants;
|
|
45
|
+
/**
|
|
46
|
+
* The real git dir when `cwd` is a linked worktree or submodule checkout
|
|
47
|
+
* (see `agent/linked-git-dir.ts`) — mirrors nono's `ProfileSpec.linkedGitDir`.
|
|
48
|
+
* Absent for regular repos, where `.git` already sits inside the cwd mount.
|
|
49
|
+
*/
|
|
50
|
+
readonly linkedGitDir?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build this run's guest mount list: cwd (rw), the agent folder (ro), the
|
|
54
|
+
* state dir (rw), `~/.pi/agent` (rw — pi's auth/settings store; the exec
|
|
55
|
+
* `HOME` override in `composeSbxExecArgv` makes pi find it there), the linked
|
|
56
|
+
* git dir when present (rw), then the agent's own `sandbox/nono.json` grants
|
|
57
|
+
* (`read` ro, `write`/`allow` rw), each expanded against `home`. Duplicate
|
|
58
|
+
* paths collapse to one entry — rw wins over ro, first-occurrence order
|
|
59
|
+
* otherwise — since sbx takes a flat mount list, not layered grants.
|
|
60
|
+
*/
|
|
61
|
+
export declare function composeSbxMounts(ctx: SbxMountContext): SbxMount[];
|
|
62
|
+
/**
|
|
63
|
+
* `cradle-<stateDirBasename>-<hash8>` — hash8 is the first 8 hex chars of a
|
|
64
|
+
* sha256 over the order-insensitive sorted `path:ro|rw` strings, mirroring
|
|
65
|
+
* `agentId` (`agent/state.ts`). Mounts are fixed at sbx creation time, so this
|
|
66
|
+
* name keys the mount set: a changed mount set yields a new sandbox name
|
|
67
|
+
* instead of silently attaching to (and running with) a stale mount list.
|
|
68
|
+
*/
|
|
69
|
+
export declare function sbxSandboxName(stateDirBasename: string, mounts: readonly SbxMount[]): string;
|
|
70
|
+
/** `sbx create shell <path>[:ro]... --name <name> -q`. `spec.mounts` already carries cwd first. */
|
|
71
|
+
export declare function composeSbxCreateArgv(spec: SbxSpec): string[];
|
|
72
|
+
/**
|
|
73
|
+
* Per-sandbox network policy argvs (idempotent re-adds — safe to run every
|
|
74
|
+
* launch). `[]` when `spec.network` is absent. A `block: true` posture emits a
|
|
75
|
+
* single deny-all — `allowDomain` is ignored under block, matching nono's
|
|
76
|
+
* block-wins precedence, since a same-scope deny always beats an allow.
|
|
77
|
+
* Otherwise, a non-empty `allowDomain` emits a single allow argv with every
|
|
78
|
+
* expanded resource comma-joined (see `composeAllowResources`); an empty or
|
|
79
|
+
* absent `allowDomain` under a non-blocking posture emits nothing.
|
|
80
|
+
* `openPort`/`listenPort`/`networkProfile` have no sbx policy equivalent —
|
|
81
|
+
* see `sbxNetworkWarnings` for their disclosures.
|
|
82
|
+
*/
|
|
83
|
+
export declare function composeSbxPolicyArgvs(spec: SbxSpec): string[][];
|
|
84
|
+
/**
|
|
85
|
+
* Warn-and-drop disclosures for `AgentNetwork` fields sbx cannot enforce the
|
|
86
|
+
* way nono does. Returns `[]` when nothing applies (including when `network`
|
|
87
|
+
* is absent) — this module never throws, it only reports what it dropped.
|
|
88
|
+
*/
|
|
89
|
+
export declare function sbxNetworkWarnings(network: AgentNetwork | undefined): string[];
|
|
90
|
+
/** Warn-and-drop disclosure for the one `AgentSandboxGrants` field sbx cannot honor: Unix sockets cannot cross the VM boundary. */
|
|
91
|
+
export declare function sbxGrantWarnings(grants: AgentSandboxGrants): string[];
|
|
92
|
+
/**
|
|
93
|
+
* `sbx exec <name> bash -lc <script>` running an idempotent pi install: with
|
|
94
|
+
* `spec.piVersion` pinned, reinstalls only on a version mismatch (`pi
|
|
95
|
+
* --version` compared against the pin); with `null`, installs only if `pi` is
|
|
96
|
+
* missing from PATH entirely, otherwise leaving whatever version is already
|
|
97
|
+
* there.
|
|
98
|
+
*/
|
|
99
|
+
export declare function composeSbxProvisionArgv(spec: SbxSpec): string[];
|
|
100
|
+
/**
|
|
101
|
+
* `sbx exec -i [-t] -e HOME=<home> -w <cwd> <name> <piArgv...>` — docker-exec
|
|
102
|
+
* semantics. `-t` rides only when `spec.tty` is set (a TTY is present);
|
|
103
|
+
* forcing it without one breaks non-interactive callers.
|
|
104
|
+
*/
|
|
105
|
+
export declare function composeSbxExecArgv(spec: SbxSpec, piArgv: readonly string[]): string[];
|
|
106
|
+
/** True when `stderr` reports the sandbox name is already taken — callers treat that as attach, not failure. */
|
|
107
|
+
export declare function isSbxAlreadyExistsError(stderr: string): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Rewrite a `localhost`/`127.0.0.1` base URL to `SBX_HOST_GATEWAY`, preserving
|
|
110
|
+
* scheme, port, and path — a host service bound to loopback is unreachable
|
|
111
|
+
* from inside the sbx guest microVM under its own name, but the gateway
|
|
112
|
+
* routes through the policy proxy back to the host. Any other host, and a
|
|
113
|
+
* parse failure, pass through unchanged.
|
|
114
|
+
*/
|
|
115
|
+
export declare function rewriteLocalhostBaseUrl(baseUrl: string): string;
|
package/dist/util/proc.d.ts
CHANGED
|
@@ -16,6 +16,17 @@ export declare function killOn(proc: Killable, signal: ForwardableSignal): () =>
|
|
|
16
16
|
* sandboxed-run `MISE_CACHE_DIR`, see `agent/launch.ts`'s `composeEnv`).
|
|
17
17
|
*/
|
|
18
18
|
export declare function runForeground(argv: readonly string[], env?: Record<string, string>): Promise<number>;
|
|
19
|
+
/**
|
|
20
|
+
* Run a setup command silently, capturing stderr for the caller's error
|
|
21
|
+
* message — the sbx create/policy/provision sequence, see
|
|
22
|
+
* `commands/run.ts`'s `MaterializeDeps.run`. Never throws on a non-zero
|
|
23
|
+
* exit: the caller decides which failures matter (an sbx create name
|
|
24
|
+
* collision means attach, not failure).
|
|
25
|
+
*/
|
|
26
|
+
export declare function runCapture(argv: readonly string[]): Promise<{
|
|
27
|
+
exitCode: number;
|
|
28
|
+
stderr: string;
|
|
29
|
+
}>;
|
|
19
30
|
/** Run a package install (e.g. `npm install`) in `cwd`, inheriting output; throws on non-zero exit. */
|
|
20
31
|
export declare function runInstall(command: readonly string[], cwd: string): Promise<void>;
|
|
21
32
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coryrylan/cradle",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A runtime for portable agents defined as folders — launches the pi coding agent configured from an agent folder, sandboxed with nono",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -220,14 +220,17 @@
|
|
|
220
220
|
}
|
|
221
221
|
},
|
|
222
222
|
"dependencies": {
|
|
223
|
-
"yargs": "18.0.0"
|
|
223
|
+
"yargs": "^18.0.0"
|
|
224
224
|
},
|
|
225
225
|
"devDependencies": {
|
|
226
|
-
"@
|
|
227
|
-
"@
|
|
226
|
+
"@coryrylan/tools": "1.1.0",
|
|
227
|
+
"@eslint/js": "10.0.1",
|
|
228
|
+
"@eslint/json": "1.2.0",
|
|
229
|
+
"@types/bun": "1.3.14",
|
|
228
230
|
"@types/yargs": "17.0.35",
|
|
229
|
-
"eslint": "
|
|
230
|
-
"
|
|
231
|
-
"typescript
|
|
231
|
+
"eslint": "10.6.0",
|
|
232
|
+
"eslint-plugin-jsdoc": "63.2.0",
|
|
233
|
+
"typescript": "6.0.3",
|
|
234
|
+
"typescript-eslint": "8.62.1"
|
|
232
235
|
}
|
|
233
236
|
}
|