@ours.network/fleet 1.2.0-nightly.43 → 1.2.0-nightly.45

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.
@@ -0,0 +1,253 @@
1
+ import { type FleetConfig, type ManagedCliWorkflowId, type ResolvedRole } from './config.js';
2
+ import type { SessionPrep } from './harness/types.js';
3
+ /** Capability-gated by the installer; see src/capabilities.ts. */
4
+ export declare const MANAGED_CONFIGURATION_FLAG = "--managed-configuration";
5
+ /** What the last launch of a role actually prepared. Lives in the role's state dir. */
6
+ export declare const MANAGED_CLI_RECORD = ".managed-cli.json";
7
+ /** Quoted path tokens were refused by Codex 0.159.0 (#231) and granted by 0.160.0. */
8
+ export declare const CODEX_QUOTED_PATH_MINIMUM = "0.160.0";
9
+ export interface ManagedCliForm {
10
+ /** Argv tokens after the pin, matched exactly. */
11
+ tokens: readonly string[];
12
+ /** `lifecycle` forms create, change or retire tasks, rooms and agents. */
13
+ effect: 'help' | 'read' | 'lifecycle';
14
+ /** Whether the command itself takes -c/--configuration, where the pin is injected. */
15
+ configuration: boolean;
16
+ }
17
+ export interface ManagedCliWorkflow {
18
+ description: string;
19
+ forms: readonly ManagedCliForm[];
20
+ /** Named so nobody reads their absence as an oversight. */
21
+ excluded: readonly string[];
22
+ }
23
+ export declare const MANAGED_CLI_WORKFLOWS: Readonly<Record<ManagedCliWorkflowId, ManagedCliWorkflow>>;
24
+ export type ManagedEntry = {
25
+ kind: 'none';
26
+ } | {
27
+ kind: 'error';
28
+ message: string;
29
+ } | {
30
+ kind: 'pinned';
31
+ configuration: string;
32
+ form: ManagedCliForm;
33
+ argv: string[];
34
+ };
35
+ /**
36
+ * Recognise the pinned entry form in `argv` (process.argv.slice(2)) and return
37
+ * the ordinary argv Commander should parse.
38
+ *
39
+ * The pin must be the first argument: that is the only position a native prefix
40
+ * rule can fix. For a command that takes `--configuration`, the pinned file is
41
+ * injected directly after the command tokens; a later, different value is
42
+ * refused by `assertPinnedConfiguration` on the PARSED option, so `-c`,
43
+ * `-cFILE`, `--configuration=FILE` and repeats need no token heuristics here.
44
+ */
45
+ export declare function parseManagedEntry(argv: readonly string[]): ManagedEntry;
46
+ /** Refuse a parsed `--configuration` that is not the pinned file. Throws a plain Error. */
47
+ export declare function assertPinnedConfiguration(pinned: string, parsed: unknown): void;
48
+ export interface ManagedCliPaths {
49
+ node: string;
50
+ cli: string;
51
+ configuration: string;
52
+ }
53
+ /** The exact tokens a rule fixes: this process's node, this installation's CLI, this configuration. */
54
+ export declare function managedCliPaths(configPath?: string, overrides?: Partial<ManagedCliPaths>): ManagedCliPaths;
55
+ /** The canonical shell spelling of one path token, or undefined when none is qualified. */
56
+ export declare function shellSpelling(token: string): string | undefined;
57
+ export declare const needsQuoting: (paths: ManagedCliPaths) => boolean;
58
+ /** The argv prefix every prepared invocation starts with. */
59
+ export declare function managedCliPrefix(paths: ManagedCliPaths): string[];
60
+ /** The same prefix as the agent must type it. Undefined when a path cannot be spelled. */
61
+ export declare function managedCliCommandPrefix(paths: ManagedCliPaths): string | undefined;
62
+ /** Codex execution rules: one `prefix_rule` per form. JSON strings are valid Starlark strings. */
63
+ export declare function renderCodexRules(paths: ManagedCliPaths, workflows: readonly ManagedCliWorkflowId[]): string;
64
+ export interface ClaudeManagedCliSettings {
65
+ permissions: {
66
+ allow: string[];
67
+ };
68
+ sandbox: {
69
+ excludedCommands: string[];
70
+ };
71
+ }
72
+ /**
73
+ * Claude needs BOTH halves: `permissions.allow` authorizes the Bash call and
74
+ * `sandbox.excludedCommands` places it outside the OS sandbox when one is
75
+ * enabled. Each form is listed bare and with ` *` because the wildcard form
76
+ * alone is not relied on to match an invocation without arguments.
77
+ */
78
+ export declare function claudeManagedCliSettings(paths: ManagedCliPaths, workflows: readonly ManagedCliWorkflowId[]): ClaudeManagedCliSettings | undefined;
79
+ /**
80
+ * Merge the fragment into Fleet's own per-role settings overlay. Entries from a
81
+ * previous launch are dropped first, so a moved node, CLI or configuration
82
+ * leaves nothing stale behind. `sandbox.enabled` is never written: whether
83
+ * Claude's OS sandbox is on stays the operator's setting.
84
+ */
85
+ export declare function mergeClaudeOverlay(base: Record<string, unknown>, fragment: ClaudeManagedCliSettings | undefined): Record<string, unknown>;
86
+ export type ManagedCliMechanism = 'codex-workspace-rules' | 'claude-session-settings';
87
+ export interface ManagedCliAnalysis {
88
+ role: string;
89
+ harness: string;
90
+ session: string;
91
+ workflows: ManagedCliWorkflowId[];
92
+ state: 'not-declared' | 'not-required' | 'unsupported' | 'supported';
93
+ mechanism?: ManagedCliMechanism;
94
+ /** Why the state is not-required or unsupported. Actionable, one per line. */
95
+ reasons: string[];
96
+ /** What the prepared policy actually grants, for disclosure. */
97
+ scope: string[];
98
+ workspace: string;
99
+ paths: ManagedCliPaths;
100
+ /** The prefix the agent types; absent unless supported. */
101
+ commandPrefix?: string;
102
+ }
103
+ export interface ManagedCliDeps {
104
+ platform?: NodeJS.Platform;
105
+ paths?: Partial<ManagedCliPaths>;
106
+ /** Codex version for the quoted-path qualification; read from the role's Codex when omitted. */
107
+ codexVersion?: string;
108
+ }
109
+ export declare function roleWorkspace(role: ResolvedRole, temp?: boolean): string;
110
+ /** Decide, without touching the filesystem, what Fleet prepares for one role. */
111
+ export declare function analyzeManagedCli(role: ResolvedRole, configPath: string | undefined, options?: ManagedCliDeps & {
112
+ temp?: boolean;
113
+ workspace?: string;
114
+ }): ManagedCliAnalysis;
115
+ export declare function codexRulesPath(workspace: string, configuration: string): string;
116
+ export type RulesAction = 'created' | 'updated' | 'unchanged' | 'removed' | 'conflict';
117
+ export interface RulesResult {
118
+ path: string;
119
+ action: RulesAction;
120
+ detail?: string;
121
+ }
122
+ /** Write this workspace's rules file and record `holder` as needing it. */
123
+ export declare function acquireCodexRules(workspace: string, paths: ManagedCliPaths, workflows: readonly ManagedCliWorkflowId[], holder: string): RulesResult;
124
+ /**
125
+ * Drop `holder` from every rules file except `keep`. A file left without a
126
+ * holder is removed when Fleet still owns it; a file other agents hold is left
127
+ * exactly as it is. This is what a launch does when the role stopped declaring
128
+ * the workflow, lost support, or moved to another workspace or configuration.
129
+ */
130
+ export declare function releaseCodexRules(holder: string, keep?: string): RulesResult[];
131
+ /**
132
+ * Bring every registered rules file of `configuration` in line with `expected`
133
+ * (path → persistent holders). Temporary holders stay while their state dir
134
+ * exists. A file nobody holds is removed if — and only if — Fleet still owns
135
+ * it; a file whose configuration no longer exists is obsolete and goes too.
136
+ */
137
+ export declare function reconcileCodexRules(configuration: string, expected: ReadonlyMap<string, readonly string[]>, write: boolean): RulesResult[];
138
+ /** Static comparison of the rules file with what this installation would generate. */
139
+ export declare function inspectCodexRules(workspace: string, paths: ManagedCliPaths, workflows: readonly ManagedCliWorkflowId[]): {
140
+ path: string;
141
+ state: 'prepared' | 'missing' | 'stale' | 'conflict';
142
+ detail: string;
143
+ };
144
+ /** Whether Codex treats the workspace as trusted, which is what loads project rules. */
145
+ export declare function codexWorkspaceTrust(workspace: string, env?: NodeJS.ProcessEnv): {
146
+ state: 'trusted' | 'untrusted' | 'unknown';
147
+ source: string;
148
+ };
149
+ export interface ClaudeSettingsInspection {
150
+ /** `unknown` when no readable source states it; Claude's default is then off. */
151
+ sandbox: 'enabled' | 'disabled' | 'unknown';
152
+ sources: string[];
153
+ /** Bash deny rules, which take precedence over Fleet's allow entries. */
154
+ bashDeny: string[];
155
+ unreadable: string[];
156
+ }
157
+ export declare function inspectClaudeSettings(workspace: string, env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): ClaudeSettingsInspection;
158
+ export interface ManagedCliRecord {
159
+ version: 1;
160
+ state: ManagedCliAnalysis['state'] | 'conflict';
161
+ mechanism?: ManagedCliMechanism;
162
+ workflows: ManagedCliWorkflowId[];
163
+ paths: ManagedCliPaths;
164
+ workspace: string;
165
+ /** Hash of everything that decides the generated policy; equal digests mean the same policy. */
166
+ digest: string;
167
+ /** When a policy with this digest was first loaded into a launch. */
168
+ preparedAt: string;
169
+ artifact?: string;
170
+ reasons: string[];
171
+ }
172
+ export declare function managedCliDigest(analysis: ManagedCliAnalysis): string;
173
+ export declare function readManagedCliRecord(stateDir: string): ManagedCliRecord | undefined;
174
+ /**
175
+ * Prepare the native policy for one launch and return the session prep to use.
176
+ * Never throws: a role whose policy cannot be prepared still launches, exactly
177
+ * as sandboxed as it was, and the reason is logged and recorded.
178
+ */
179
+ export declare function prepareManagedCliLaunch(role: ResolvedRole, options: {
180
+ stateDir: string;
181
+ runCwd: string;
182
+ configPath?: string;
183
+ temp?: boolean;
184
+ prep: SessionPrep;
185
+ log(line: string): void;
186
+ deps?: ManagedCliDeps;
187
+ now?(): Date;
188
+ }): SessionPrep;
189
+ export interface ManagedCliObservation {
190
+ /** Per form, the best completed pinned invocation recorded after the current policy was loaded. */
191
+ current: {
192
+ form: string;
193
+ effect: ManagedCliForm['effect'];
194
+ at: string;
195
+ class: string;
196
+ }[];
197
+ /** Pinned invocations that predate the current policy: history, not verification. */
198
+ historical: number;
199
+ /** Rows pinned to a configuration other than the one this policy was prepared for. */
200
+ foreign: number;
201
+ summary: string;
202
+ }
203
+ /** Read the role's audit ledger without mutating or recovering it. */
204
+ export declare function observeManagedCli(stateDir: string, record: ManagedCliRecord | undefined): ManagedCliObservation;
205
+ export interface ManagedCliRoleReport {
206
+ role: string;
207
+ harness: string;
208
+ session: string;
209
+ workflows: ManagedCliWorkflowId[];
210
+ /** Generated configuration compared with this installation. Static. */
211
+ setup: {
212
+ state: 'not-declared' | 'not-required' | 'unsupported' | 'prepared' | 'missing' | 'stale' | 'conflict' | 'generated-at-launch';
213
+ mechanism?: ManagedCliMechanism;
214
+ artifact?: string;
215
+ action?: RulesAction;
216
+ detail: string;
217
+ };
218
+ /** Whether the session that is (or was last) running loaded the current policy. */
219
+ session_policy: 'not-applicable' | 'never-launched' | 'current' | 'restart-required';
220
+ /** From the audit ledger. Never inferred from `setup`. */
221
+ observed: ManagedCliObservation;
222
+ commandPrefix?: string;
223
+ scope: string[];
224
+ warnings: string[];
225
+ }
226
+ export interface ManagedCliReport {
227
+ version: 1;
228
+ configuration: string;
229
+ node: string;
230
+ cli: string;
231
+ platform: {
232
+ os: NodeJS.Platform;
233
+ declared: boolean;
234
+ };
235
+ wrote: boolean;
236
+ roles: ManagedCliRoleReport[];
237
+ removed: RulesResult[];
238
+ disclosure: string[];
239
+ }
240
+ export declare function managedCliReport(cfg: Pick<FleetConfig, 'roles'>, configPath: string | undefined, options: ManagedCliDeps & {
241
+ write: boolean;
242
+ env?: NodeJS.ProcessEnv;
243
+ }): ManagedCliReport;
244
+ /**
245
+ * Add a workflow to an existing Agent file, and nothing else. Comments, key
246
+ * order and every other setting — permissions included — are preserved.
247
+ */
248
+ export declare function enableManagedCli(configPath: string | undefined, agent: string, workflow: ManagedCliWorkflowId): {
249
+ file: string;
250
+ changed: boolean;
251
+ };
252
+ /** The briefing section for a role, or nothing when it declares no workflow. */
253
+ export declare function managedCliBriefing(role: ResolvedRole, configPath: string | undefined, temp?: boolean): string[];