@shardflux/cli 0.19.1 → 0.20.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 +65 -1
- package/README.md +14 -2
- package/dist/account-pool.d.ts +1 -0
- package/dist/account-pool.js +4 -1
- package/dist/agent-config-files.d.ts +19 -0
- package/dist/agent-config-files.js +70 -1
- package/dist/agent-config-return.d.ts +150 -0
- package/dist/agent-config-return.js +618 -0
- package/dist/agent-config-sync.d.ts +10 -2
- package/dist/agent-config-sync.js +45 -51
- package/dist/agent-setup.js +2 -2
- package/dist/args.d.ts +1 -1
- package/dist/args.js +11 -2
- package/dist/conversation-terminal.js +4 -2
- package/dist/conversations.d.ts +4 -0
- package/dist/device-helper.js +29 -2
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +11 -0
- package/dist/filesystem-commands.d.ts +12 -0
- package/dist/filesystem-commands.js +68 -6
- package/dist/handlers.js +2 -1
- package/dist/machine-setup.d.ts +180 -0
- package/dist/machine-setup.js +802 -0
- package/dist/main.js +14 -2
- package/dist/seed-phases.d.ts +5 -2
- package/dist/seed-phases.js +4 -1
- package/dist/terminal-onboarding.d.ts +2 -0
- package/dist/terminal-onboarding.js +5 -0
- package/package.json +5 -5
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { AgentFilesystem, Workspace } from '@shardflux/sdk';
|
|
2
|
+
import type { Ctx, Handler } from './commands.js';
|
|
3
|
+
import { AgentStateStore } from './agent-state.js';
|
|
4
|
+
import { type Values } from './args.js';
|
|
5
|
+
export type Runner = 'claude' | 'codex' | 'cloud';
|
|
6
|
+
type Env = Record<string, string | undefined>;
|
|
7
|
+
/** Set for the local agent's processes: the `shard` it runs only reaches this machine VM (see `setupGuard`). */
|
|
8
|
+
export declare const SETUP_VM_ENV = "SHARDFLUX_MACHINE_SETUP_VM";
|
|
9
|
+
export declare const DEFAULT_AGENT_TIMEOUT_MS: number;
|
|
10
|
+
export interface ChildResult {
|
|
11
|
+
code: number | null;
|
|
12
|
+
signal: NodeJS.Signals | null;
|
|
13
|
+
stdout: string;
|
|
14
|
+
stderr: string;
|
|
15
|
+
timedOut: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ChildOptions {
|
|
18
|
+
cwd?: string;
|
|
19
|
+
env?: Env;
|
|
20
|
+
input?: string;
|
|
21
|
+
timeoutMs: number;
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
onLine?: (line: string) => void;
|
|
24
|
+
maxBytes?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Runs argv without a shell in its own process group; past the time box (or on abort) the whole group gets SIGTERM, then
|
|
28
|
+
* SIGKILL 5 s later. Keeps the last `maxBytes` of each stream. Never throws for a non-zero exit or a missing program.
|
|
29
|
+
*/
|
|
30
|
+
export declare function runChild(argv: string[], o: ChildOptions): Promise<ChildResult>;
|
|
31
|
+
/** The first executable `name` on PATH or in the usual install folders (a menu bar app's PATH is short). */
|
|
32
|
+
export declare function findExecutable(name: string, env: Env): string | undefined;
|
|
33
|
+
export interface LocalAgent {
|
|
34
|
+
app: 'claude' | 'codex';
|
|
35
|
+
bin: string;
|
|
36
|
+
version: string;
|
|
37
|
+
help: string;
|
|
38
|
+
signedIn: boolean;
|
|
39
|
+
usable: boolean;
|
|
40
|
+
reason?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Flags a restricted `claude -p` run needs (checked against `claude --help` of the installed version). */
|
|
43
|
+
export declare const CLAUDE_REQUIRED_FLAGS: readonly ["--print", "--tools", "--allowedTools", "--disallowedTools", "--permission-mode", "dontAsk", "--strict-mcp-config", "--setting-sources", "--output-format", "stream-json"];
|
|
44
|
+
/** Flags `codex exec` needs for a sandboxed run (checked against `codex exec --help`). */
|
|
45
|
+
export declare const CODEX_REQUIRED_FLAGS: readonly ["--sandbox", "workspace-write", "--skip-git-repo-check", "--json", "--cd"];
|
|
46
|
+
export declare function inspectClaude(env: Env): Promise<LocalAgent | undefined>;
|
|
47
|
+
export declare function inspectCodex(env: Env): Promise<LocalAgent | undefined>;
|
|
48
|
+
export interface Candidate {
|
|
49
|
+
runner: Runner;
|
|
50
|
+
agent?: LocalAgent;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The agents to try, in order: this computer's Claude Code, then its Codex, then the account's cloud Claude in the
|
|
54
|
+
* machine VM. When one stops for a reason the next would not hit (a usage limit, a sign-in that expired, a sandbox that
|
|
55
|
+
* keeps shard from the VM, a crash, its time box), the next one runs. `--agent` names exactly one.
|
|
56
|
+
*/
|
|
57
|
+
export declare function runnerChain(claude: LocalAgent | undefined, codex: LocalAgent | undefined, forced?: Runner): {
|
|
58
|
+
chain: Candidate[];
|
|
59
|
+
skipped: string[];
|
|
60
|
+
};
|
|
61
|
+
/** Every agent gets its own time box, and all of them together at most twice it: the apps wait 30 minutes. */
|
|
62
|
+
export declare const AGENT_BUDGET_FACTOR = 2;
|
|
63
|
+
export declare function attemptTimeout(perAgentMs: number, spentMs: number): number | undefined;
|
|
64
|
+
/** Read-only commands a local Claude may run on this computer (each a prefix rule). No cat: file reads go through Read, where the secret paths are denied. */
|
|
65
|
+
export declare const READ_ONLY_COMMANDS: readonly ["brew list", "brew leaves", "brew info", "brew --prefix", "brew --version", "ls", "which", "command -v", "uname", "sw_vers", "git config --global --get", "git config --global --list", "git config --get", "git config --list", "npm ls -g", "npm list -g", "pnpm ls -g", "pipx list", "uv tool list", "gem list", "cargo install --list", "gh extension list", "asdf current", "asdf list", "mise ls", "mise current", "pyenv versions", "rbenv versions", "fnm list", "volta list"];
|
|
66
|
+
/** Tools whose `--version` (or `version`) a local Claude may print. */
|
|
67
|
+
export declare const VERSION_TOOLS: readonly ["node", "npm", "pnpm", "yarn", "bun", "deno", "python3", "python", "pip3", "uv", "go", "rustc", "cargo", "ruby", "java", "php", "dotnet", "git", "gh", "docker", "kubectl", "terraform", "aws", "gcloud", "zsh", "bash", "fish", "tmux", "nvim", "vim", "starship", "mise", "asdf"];
|
|
68
|
+
/** Never read on this computer, whatever the agent decides: keys, tokens, cloud and package-registry credentials, keychains, browser and app data. */
|
|
69
|
+
export declare const SECRET_PATHS: readonly ["~/.ssh/**", "~/.aws/**", "~/.azure/**", "~/.config/gcloud/**", "~/.kube/**", "~/.docker/**", "~/.gnupg/**", "~/.password-store/**", "~/Library/**", "~/.local/share/keyrings/**", "~/.config/op/**", "~/.config/gh/**", "~/.config/hub", "~/.config/shardflux/**", "~/.netrc", "~/.git-credentials", "~/.npmrc", "~/.yarnrc.yml", "~/.pypirc", "~/.gem/credentials", "~/.cargo/credentials", "~/.cargo/credentials.toml", "~/.vault-token", "~/.terraform.d/**", "~/.claude.json", "~/.claude/.credentials.json", "~/.codex/auth.json", "~/.mozilla/**", "~/.config/google-chrome/**", "//**/.env", "//**/.env.*", "//**/*.pem", "//**/*.key", "//**/*.p12", "//**/*.pfx", "//**/id_rsa*", "//**/id_ed25519*", "//**/id_ecdsa*", "//**/*credentials*", "//**/*secret*", "//**/*token*"];
|
|
70
|
+
/** `claude` argv for the restricted run (the task goes on standard input). `help` is the installed version's `--help`. */
|
|
71
|
+
export declare function claudeArgs(key: string, help: string): string[];
|
|
72
|
+
/** `codex exec` argv: writes only in `workDir` (and temp folders), network on for `shard`, the task on standard input. */
|
|
73
|
+
export declare function codexArgs(workDir: string, help: string): string[];
|
|
74
|
+
/**
|
|
75
|
+
* While `SHARDFLUX_MACHINE_SETUP_VM` is set (the setup agent's own commands), shard only runs commands on that VM: exec,
|
|
76
|
+
* file writes from standard input, reads and listings. Returns the refusal, or undefined when the command may run.
|
|
77
|
+
*/
|
|
78
|
+
export declare function setupGuard(env: Env, command: string, values: Values, positionals: string[]): string | undefined;
|
|
79
|
+
export interface Inventory {
|
|
80
|
+
os: string;
|
|
81
|
+
shell: string | null;
|
|
82
|
+
homebrew: string[] | null;
|
|
83
|
+
runtimes: Record<string, string>;
|
|
84
|
+
version_files: Record<string, string>;
|
|
85
|
+
version_managers: string[];
|
|
86
|
+
clis: string[];
|
|
87
|
+
npm_globals: string[];
|
|
88
|
+
git: {
|
|
89
|
+
name?: string;
|
|
90
|
+
email?: string;
|
|
91
|
+
};
|
|
92
|
+
dotfiles: string[];
|
|
93
|
+
}
|
|
94
|
+
/** What is on this computer, without contents that could hold a secret: names, versions, the git identity. */
|
|
95
|
+
export declare function collectInventory(env: Env): Promise<Inventory>;
|
|
96
|
+
/** Skills this computer's config copy brings to the machine: ~/.claude/skills and ~/.codex/skills (not Codex's bundled .system). */
|
|
97
|
+
export declare function countSkills(home: string): number;
|
|
98
|
+
/**
|
|
99
|
+
* The fixed task: agent-setup.ts's "Build the machine" step, extended to recreate this computer. `where` is 'local' for
|
|
100
|
+
* an agent on this computer (it reaches the VM through shard) or 'vm' for the cloud Claude inside the machine VM.
|
|
101
|
+
*/
|
|
102
|
+
export declare function setupTask(where: 'local' | 'vm', key: string, inventory: Inventory): string;
|
|
103
|
+
export interface SetupSummary {
|
|
104
|
+
tools: string[];
|
|
105
|
+
runtimes: string[];
|
|
106
|
+
shell: string | null;
|
|
107
|
+
dotfiles: string[];
|
|
108
|
+
skipped: Array<{
|
|
109
|
+
item: string;
|
|
110
|
+
reason: string;
|
|
111
|
+
}>;
|
|
112
|
+
}
|
|
113
|
+
/** The last JSON object in the agent's final message (a fenced block or bare), normalised. */
|
|
114
|
+
export declare function parseSummary(text: string): SetupSummary | undefined;
|
|
115
|
+
/** "Cloud machine ready: gh, Node 24, Python 3.13, 12 skills": what a person recognises, at most 80 characters. */
|
|
116
|
+
export declare function readyLine(summary: SetupSummary | undefined, skills: number): string;
|
|
117
|
+
export declare function workingLine(runner: Runner): string;
|
|
118
|
+
export declare function failedLine(message: string): string;
|
|
119
|
+
export interface SetupRecord {
|
|
120
|
+
state: 'running' | 'ready' | 'failed';
|
|
121
|
+
runner: Runner | null;
|
|
122
|
+
pid: number | null;
|
|
123
|
+
started_at: string;
|
|
124
|
+
finished_at: string | null;
|
|
125
|
+
machine_version: number | null;
|
|
126
|
+
line: string;
|
|
127
|
+
summary: (SetupSummary & {
|
|
128
|
+
skills: number;
|
|
129
|
+
runner: Runner;
|
|
130
|
+
}) | null;
|
|
131
|
+
/** Each agent tried, in order (0.20.0+): the one that set the machine up last, with ok. */
|
|
132
|
+
attempts?: Attempt[];
|
|
133
|
+
error: string | null;
|
|
134
|
+
duration_ms: number | null;
|
|
135
|
+
}
|
|
136
|
+
export interface Attempt {
|
|
137
|
+
runner: Runner;
|
|
138
|
+
ok: boolean;
|
|
139
|
+
error: string | null;
|
|
140
|
+
duration_ms: number;
|
|
141
|
+
}
|
|
142
|
+
export declare function readRecord(store: AgentStateStore, apiUrl: string, org: string): SetupRecord | undefined;
|
|
143
|
+
/**
|
|
144
|
+
* Claims the run under agents.json's lock: a live run is never doubled; with `ifNeeded` a machine already set up from
|
|
145
|
+
* this computer is left alone.
|
|
146
|
+
*/
|
|
147
|
+
export declare function claimRun(store: AgentStateStore, apiUrl: string, org: string, ifNeeded: boolean, start: SetupRecord): {
|
|
148
|
+
claimed: true;
|
|
149
|
+
} | {
|
|
150
|
+
claimed: false;
|
|
151
|
+
record: SetupRecord;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Whether the agent reached the machine VM at all: every shard command it ran failed (a sandbox without network, a
|
|
155
|
+
* permission it was never given) means nothing was set up, whatever its reply says, and the next agent should try.
|
|
156
|
+
*/
|
|
157
|
+
export declare class ShardReach {
|
|
158
|
+
private calls;
|
|
159
|
+
private ok;
|
|
160
|
+
private firstError;
|
|
161
|
+
record(succeeded: boolean, output?: string): void;
|
|
162
|
+
check(app: string): void;
|
|
163
|
+
}
|
|
164
|
+
export interface SetupDeps {
|
|
165
|
+
inspectClaude?: typeof inspectClaude;
|
|
166
|
+
inspectCodex?: typeof inspectCodex;
|
|
167
|
+
inventory?: typeof collectInventory;
|
|
168
|
+
open?: (ctx: Ctx, state: AgentFilesystem) => Promise<{
|
|
169
|
+
state: AgentFilesystem;
|
|
170
|
+
ws: Workspace;
|
|
171
|
+
}>;
|
|
172
|
+
}
|
|
173
|
+
export declare function machineSetup(ctx: Ctx, values: Values, deps?: SetupDeps): Promise<number>;
|
|
174
|
+
/**
|
|
175
|
+
* Starts `shard machine setup --from-this-computer --if-needed --json` detached (the terminal onboarding, right after
|
|
176
|
+
* its Agents step): its output goes to machine-setup.out in the config directory. Returns false without a runtime.
|
|
177
|
+
*/
|
|
178
|
+
export declare function startMachineSetupInBackground(ctx: Ctx): boolean;
|
|
179
|
+
export declare const MACHINE_SETUP_HANDLERS: Record<string, Handler>;
|
|
180
|
+
export {};
|