docks-kit 0.17.1 → 0.17.3
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/AGENTS.md +41 -33
- package/cli/docs/omp-context.md +104 -0
- package/cli/docs/omp-models.md +106 -56
- package/cli/src/argv.ts +38 -469
- package/cli/src/argvSurface.ts +371 -0
- package/cli/src/argvValidate.ts +122 -0
- package/cli/src/commands/docs.ts +62 -42
- package/cli/src/commands/harnesses.ts +38 -45
- package/cli/src/commands/model.ts +48 -53
- package/cli/src/commands/models.ts +24 -26
- package/cli/src/commands/omp.ts +132 -112
- package/cli/src/commands/plugins.ts +20 -20
- package/cli/src/commands/skills.ts +22 -20
- package/cli/src/commands/status.ts +87 -80
- package/cli/src/commands/sync.ts +113 -87
- package/cli/src/commands/toolchain.ts +21 -21
- package/cli/src/commands/update.ts +139 -117
- package/cli/src/efforts.ts +35 -34
- package/cli/src/engine-native/DESIGN.md +30 -30
- package/cli/src/engine-native/bun.ts +77 -55
- package/cli/src/engine-native/claudeLsp.ts +154 -0
- package/cli/src/engine-native/claudeOptionalPlugins.ts +113 -0
- package/cli/src/engine-native/claudePluginPasses.ts +348 -0
- package/cli/src/engine-native/claudeRemovals.ts +195 -0
- package/cli/src/engine-native/claudeRetired.ts +4 -4
- package/cli/src/engine-native/claudeRuntime.ts +94 -68
- package/cli/src/engine-native/claudeSettings.ts +174 -0
- package/cli/src/engine-native/claudeSettingsModifiers.ts +50 -54
- package/cli/src/engine-native/claudeSync.ts +176 -456
- package/cli/src/engine-native/codexConfig.ts +158 -0
- package/cli/src/engine-native/codexHooks.ts +91 -0
- package/cli/src/engine-native/codexPlugins.ts +290 -0
- package/cli/src/engine-native/codexStatus.ts +24 -0
- package/cli/src/engine-native/codexSync.ts +110 -568
- package/cli/src/engine-native/codexToml.ts +140 -138
- package/cli/src/engine-native/deps.ts +144 -107
- package/cli/src/engine-native/engineCtx.ts +126 -0
- package/cli/src/engine-native/exec.ts +98 -87
- package/cli/src/engine-native/failures.ts +3 -3
- package/cli/src/engine-native/harnesses.ts +62 -72
- package/cli/src/engine-native/index.ts +34 -315
- package/cli/src/engine-native/jq.ts +25 -24
- package/cli/src/engine-native/logger.ts +98 -100
- package/cli/src/engine-native/models.ts +50 -45
- package/cli/src/engine-native/modes.ts +83 -80
- package/cli/src/engine-native/ompFileDeploy.ts +111 -0
- package/cli/src/engine-native/ompMarketplace.ts +136 -0
- package/cli/src/engine-native/ompOverlay.ts +67 -64
- package/cli/src/engine-native/ompPaths.ts +49 -38
- package/cli/src/engine-native/ompPlugins.ts +170 -0
- package/cli/src/engine-native/ompRemovals.ts +159 -0
- package/cli/src/engine-native/ompSync.ts +69 -409
- package/cli/src/engine-native/ompYaml.ts +43 -41
- package/cli/src/engine-native/os/darwin.ts +5 -5
- package/cli/src/engine-native/os/index.ts +15 -15
- package/cli/src/engine-native/os/linux.ts +5 -5
- package/cli/src/engine-native/os/posix.ts +28 -24
- package/cli/src/engine-native/os/targets.ts +17 -17
- package/cli/src/engine-native/os/types.ts +31 -31
- package/cli/src/engine-native/os/windows.ts +61 -61
- package/cli/src/engine-native/parseArgs.ts +122 -372
- package/cli/src/engine-native/parseHelp.ts +66 -0
- package/cli/src/engine-native/parseModifiers.ts +222 -0
- package/cli/src/engine-native/services.ts +34 -34
- package/cli/src/engine-native/settings.ts +15 -15
- package/cli/src/engine-native/sharedTypes.d.ts +46 -0
- package/cli/src/engine-native/skillsInstall.ts +105 -0
- package/cli/src/engine-native/skillsLinks.ts +203 -0
- package/cli/src/engine-native/skillsManifest.ts +16 -0
- package/cli/src/engine-native/skillsPrune.ts +108 -0
- package/cli/src/engine-native/skillsSync.ts +28 -362
- package/cli/src/engine-native/syncConcurrency.ts +55 -0
- package/cli/src/engine-native/syncDispatch.ts +141 -0
- package/cli/src/engine-native/toolchain.ts +65 -62
- package/cli/src/engine.ts +65 -57
- package/cli/src/generated/sotPayload.ts +7 -7
- package/cli/src/kitHome.ts +44 -40
- package/cli/src/main.ts +63 -56
- package/cli/src/manifests.ts +53 -54
- package/cli/src/md.d.ts +2 -2
- package/cli/src/payload.ts +9 -9
- package/cli/src/services.ts +21 -13
- package/cli/tsconfig.json +4 -1
- package/docks-kit +13 -2
- package/docks-kit.ps1 +21 -6
- package/package.json +10 -2
- package/cli/src/engine-native/claudePlugins.ts +0 -510
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* install; this registry owns WHICH external tools exist, whether they are
|
|
8
8
|
* required, and the one-line command that installs a missing one.
|
|
9
9
|
*/
|
|
10
|
-
import { homedir } from "node:os"
|
|
11
|
-
import { isAbsolute } from "node:path"
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { isAbsolute } from "node:path";
|
|
12
12
|
|
|
13
|
-
import { capture, commandExists, p, which } from "./exec"
|
|
14
|
-
import { isObject, parseJson } from "./jq"
|
|
15
|
-
import { hostOs, platformName, rawPlatform } from "./os"
|
|
13
|
+
import { capture, commandExists, p, which } from "./exec";
|
|
14
|
+
import { isObject, parseJson } from "./jq";
|
|
15
|
+
import { hostOs, platformName, rawPlatform } from "./os";
|
|
16
16
|
|
|
17
17
|
export type ToolId =
|
|
18
18
|
| "git"
|
|
@@ -35,71 +35,74 @@ export type ToolId =
|
|
|
35
35
|
| "apt-get"
|
|
36
36
|
| "dnf"
|
|
37
37
|
| "pacman"
|
|
38
|
-
| "zypper"
|
|
38
|
+
| "zypper";
|
|
39
39
|
|
|
40
40
|
/** required = the engine aborts when missing; optional = warn + degrade. */
|
|
41
|
-
export type Requirement = "required" | "optional"
|
|
41
|
+
export type Requirement = "required" | "optional";
|
|
42
42
|
|
|
43
43
|
export type ProbeResult =
|
|
44
44
|
| { readonly state: "present"; readonly path?: string }
|
|
45
|
-
| { readonly state: "missing" }
|
|
45
|
+
| { readonly state: "missing" };
|
|
46
46
|
|
|
47
47
|
export interface ProbeExecutor {
|
|
48
|
-
readonly commandExists: (name: string) => boolean
|
|
49
|
-
readonly capture: (cmd: string, args: ReadonlyArray<string>) => Promise<string
|
|
50
|
-
readonly which: (name: string) => string
|
|
48
|
+
readonly commandExists: (name: string) => boolean;
|
|
49
|
+
readonly capture: (cmd: string, args: ReadonlyArray<string>) => Promise<string>;
|
|
50
|
+
readonly which: (name: string) => string;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export interface DependencySpec {
|
|
54
|
-
readonly id: ToolId
|
|
55
|
-
readonly requirement: Requirement
|
|
56
|
-
readonly versionArgs: ReadonlyArray<string
|
|
54
|
+
readonly id: ToolId;
|
|
55
|
+
readonly requirement: Requirement;
|
|
56
|
+
readonly versionArgs: ReadonlyArray<string>;
|
|
57
57
|
/** Platform-correct one-line install command (param injectable for tests). */
|
|
58
|
-
readonly installHint: (platform?: NodeJS.Platform) => string
|
|
59
|
-
readonly resolve?: (exec: ProbeExecutor, platform: NodeJS.Platform) => ProbeResult
|
|
60
|
-
readonly version?: (exec: ProbeExecutor) => Promise<string
|
|
58
|
+
readonly installHint: (platform?: NodeJS.Platform) => string;
|
|
59
|
+
readonly resolve?: (exec: ProbeExecutor, platform: NodeJS.Platform) => ProbeResult;
|
|
60
|
+
readonly version?: (exec: ProbeExecutor) => Promise<string>;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
interface SpecOptions {
|
|
64
|
-
readonly versionArgs?: ReadonlyArray<string
|
|
65
|
-
readonly resolve?: (exec: ProbeExecutor, platform: NodeJS.Platform) => ProbeResult
|
|
66
|
-
readonly version?: (exec: ProbeExecutor) => Promise<string
|
|
64
|
+
readonly versionArgs?: ReadonlyArray<string>;
|
|
65
|
+
readonly resolve?: (exec: ProbeExecutor, platform: NodeJS.Platform) => ProbeResult;
|
|
66
|
+
readonly version?: (exec: ProbeExecutor) => Promise<string>;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const spec = (
|
|
70
70
|
id: ToolId,
|
|
71
71
|
requirement: Requirement,
|
|
72
72
|
installHint: (platform?: NodeJS.Platform) => string,
|
|
73
|
-
options: SpecOptions = {}
|
|
73
|
+
options: SpecOptions = {},
|
|
74
74
|
): DependencySpec => ({
|
|
75
75
|
id,
|
|
76
76
|
requirement,
|
|
77
77
|
versionArgs: options.versionArgs ?? ["--version"],
|
|
78
78
|
installHint,
|
|
79
79
|
resolve: options.resolve,
|
|
80
|
-
version: options.version
|
|
81
|
-
})
|
|
80
|
+
version: options.version,
|
|
81
|
+
});
|
|
82
82
|
|
|
83
83
|
// Presence is the injected executor's verdict; `which` only resolves WHERE the
|
|
84
84
|
// tool is, which on Windows is the `.cmd`/`.exe` candidate rather than the name.
|
|
85
|
-
const pathProbe =
|
|
85
|
+
const pathProbe =
|
|
86
|
+
(id: string): ((exec: ProbeExecutor) => ProbeResult) =>
|
|
86
87
|
(exec) => {
|
|
87
|
-
if (!exec.commandExists(id)) return { state: "missing" }
|
|
88
|
-
const path = exec.which(id)
|
|
89
|
-
return path === "" ? { state: "present" } : { state: "present", path }
|
|
90
|
-
}
|
|
88
|
+
if (!exec.commandExists(id)) return { state: "missing" };
|
|
89
|
+
const path = exec.which(id);
|
|
90
|
+
return path === "" ? { state: "present" } : { state: "present", path };
|
|
91
|
+
};
|
|
91
92
|
|
|
92
|
-
const versionProbe =
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
const versionProbe =
|
|
94
|
+
(
|
|
95
|
+
id: string,
|
|
96
|
+
versionArgs: ReadonlyArray<string> = ["--version"],
|
|
97
|
+
parse: (out: string) => string = (out) => out,
|
|
98
|
+
): ((exec: ProbeExecutor) => Promise<string>) =>
|
|
99
|
+
async (exec) =>
|
|
100
|
+
parse(await exec.capture(id, versionArgs));
|
|
98
101
|
|
|
99
102
|
const home = (): string => {
|
|
100
|
-
const envHome = process.env["HOME"]
|
|
101
|
-
return envHome !== undefined && envHome !== "" ? envHome : homedir()
|
|
102
|
-
}
|
|
103
|
+
const envHome = process.env["HOME"];
|
|
104
|
+
return envHome !== undefined && envHome !== "" ? envHome : homedir();
|
|
105
|
+
};
|
|
103
106
|
|
|
104
107
|
/**
|
|
105
108
|
* The resolved path gets persisted into global direct-exec hooks, so a
|
|
@@ -107,156 +110,190 @@ const home = (): string => {
|
|
|
107
110
|
* break outside the sync working directory.
|
|
108
111
|
*/
|
|
109
112
|
const findBun = (exec: ProbeExecutor): { command: string; path: string } | undefined => {
|
|
110
|
-
const onPath = exec.which("bun")
|
|
113
|
+
const onPath = exec.which("bun");
|
|
111
114
|
if (onPath !== "" && isAbsolute(onPath)) {
|
|
112
|
-
return { command: "bun", path: onPath }
|
|
115
|
+
return { command: "bun", path: onPath };
|
|
113
116
|
}
|
|
114
117
|
const root =
|
|
115
118
|
process.env["BUN_INSTALL"] !== undefined && process.env["BUN_INSTALL"] !== ""
|
|
116
119
|
? process.env["BUN_INSTALL"]!
|
|
117
|
-
: p(home(), ".bun")
|
|
120
|
+
: p(home(), ".bun");
|
|
118
121
|
for (const candidate of [p(root, "bin", "bun"), p(home(), ".bun", "bin", "bun")]) {
|
|
119
|
-
const found = exec.which(candidate)
|
|
120
|
-
if (found !== "" && isAbsolute(found)) return { command: found, path: found }
|
|
122
|
+
const found = exec.which(candidate);
|
|
123
|
+
if (found !== "" && isAbsolute(found)) return { command: found, path: found };
|
|
121
124
|
}
|
|
122
|
-
return undefined
|
|
123
|
-
}
|
|
125
|
+
return undefined;
|
|
126
|
+
};
|
|
124
127
|
|
|
125
128
|
const resolveBun = (exec: ProbeExecutor): ProbeResult => {
|
|
126
|
-
const bun = findBun(exec)
|
|
127
|
-
return bun === undefined
|
|
128
|
-
|
|
129
|
-
: { state: "present", path: bun.path }
|
|
130
|
-
}
|
|
129
|
+
const bun = findBun(exec);
|
|
130
|
+
return bun === undefined ? { state: "missing" } : { state: "present", path: bun.path };
|
|
131
|
+
};
|
|
131
132
|
|
|
132
|
-
const npmGlobalCache = new WeakMap<ProbeExecutor, Promise<{ [k: string]: string }>>()
|
|
133
|
+
const npmGlobalCache = new WeakMap<ProbeExecutor, Promise<{ [k: string]: string }>>();
|
|
133
134
|
|
|
134
135
|
const npmGlobalVersions = (exec: ProbeExecutor): Promise<{ [k: string]: string }> => {
|
|
135
|
-
const hit = npmGlobalCache.get(exec)
|
|
136
|
-
if (hit !== undefined) return hit
|
|
136
|
+
const hit = npmGlobalCache.get(exec);
|
|
137
|
+
if (hit !== undefined) return hit;
|
|
137
138
|
const pending = (async (): Promise<{ [k: string]: string }> => {
|
|
138
|
-
const out: { [k: string]: string } = {}
|
|
139
|
+
const out: { [k: string]: string } = {};
|
|
139
140
|
if (exec.commandExists("npm")) {
|
|
140
|
-
const doc = parseJson(await exec.capture("npm", ["ls", "-g", "--depth=0", "--json"]))
|
|
141
|
-
const deps =
|
|
141
|
+
const doc = parseJson(await exec.capture("npm", ["ls", "-g", "--depth=0", "--json"]));
|
|
142
|
+
const deps =
|
|
143
|
+
doc !== undefined && isObject(doc) && isObject(doc["dependencies"])
|
|
144
|
+
? doc["dependencies"]
|
|
145
|
+
: {};
|
|
142
146
|
for (const [name, value] of Object.entries(deps)) {
|
|
143
|
-
if (isObject(value) && typeof value["version"] === "string") out[name] = value["version"]
|
|
147
|
+
if (isObject(value) && typeof value["version"] === "string") out[name] = value["version"];
|
|
144
148
|
}
|
|
145
149
|
}
|
|
146
|
-
return out
|
|
147
|
-
})()
|
|
148
|
-
npmGlobalCache.set(exec, pending)
|
|
149
|
-
return pending
|
|
150
|
-
}
|
|
150
|
+
return out;
|
|
151
|
+
})();
|
|
152
|
+
npmGlobalCache.set(exec, pending);
|
|
153
|
+
return pending;
|
|
154
|
+
};
|
|
151
155
|
|
|
152
|
-
const versionNpmGlobal =
|
|
153
|
-
(
|
|
156
|
+
const versionNpmGlobal =
|
|
157
|
+
(pkg: string) =>
|
|
158
|
+
async (exec: ProbeExecutor): Promise<string> =>
|
|
159
|
+
(await npmGlobalVersions(exec))[pkg] ?? "";
|
|
154
160
|
|
|
155
|
-
export const defaultProbeExecutor: ProbeExecutor = { commandExists, capture, which }
|
|
161
|
+
export const defaultProbeExecutor: ProbeExecutor = { commandExists, capture, which };
|
|
156
162
|
|
|
157
163
|
export const DEPENDENCIES: Record<ToolId, DependencySpec> = {
|
|
158
164
|
git: spec(
|
|
159
165
|
"git",
|
|
160
166
|
"optional",
|
|
161
167
|
(pf = rawPlatform()) => hostOs(platformName(pf)).installHint("git"),
|
|
162
|
-
{ version: versionProbe("git") }
|
|
168
|
+
{ version: versionProbe("git") },
|
|
163
169
|
),
|
|
164
170
|
jq: spec("jq", "optional", (pf = rawPlatform()) => hostOs(platformName(pf)).installHint("jq"), {
|
|
165
|
-
version: versionProbe("jq")
|
|
166
|
-
}),
|
|
167
|
-
curl: spec("curl", "optional", (pf = rawPlatform()) => hostOs(platformName(pf)).installHint("curl"), {
|
|
168
|
-
version: versionProbe("curl")
|
|
169
|
-
}),
|
|
170
|
-
node: spec("node", "optional", () => "install Node.js via https://nodejs.org (or your package manager)", {
|
|
171
|
-
version: versionProbe("node")
|
|
171
|
+
version: versionProbe("jq"),
|
|
172
172
|
}),
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
curl: spec(
|
|
174
|
+
"curl",
|
|
175
|
+
"optional",
|
|
176
|
+
(pf = rawPlatform()) => hostOs(platformName(pf)).installHint("curl"),
|
|
177
|
+
{
|
|
178
|
+
version: versionProbe("curl"),
|
|
179
|
+
},
|
|
180
|
+
),
|
|
181
|
+
node: spec(
|
|
182
|
+
"node",
|
|
183
|
+
"optional",
|
|
184
|
+
() => "install Node.js via https://nodejs.org (or your package manager)",
|
|
185
|
+
{
|
|
186
|
+
version: versionProbe("node"),
|
|
187
|
+
},
|
|
188
|
+
),
|
|
189
|
+
npm: spec(
|
|
190
|
+
"npm",
|
|
191
|
+
"optional",
|
|
192
|
+
() => "ships with Node.js — install via https://nodejs.org (or your package manager)",
|
|
193
|
+
),
|
|
194
|
+
npx: spec(
|
|
195
|
+
"npx",
|
|
196
|
+
"optional",
|
|
197
|
+
() => "ships with Node.js — install via https://nodejs.org (or your package manager)",
|
|
198
|
+
),
|
|
175
199
|
claude: spec(
|
|
176
200
|
"claude",
|
|
177
201
|
"optional",
|
|
178
202
|
(pf = rawPlatform()) => hostOs(platformName(pf)).installHint("claude"),
|
|
179
|
-
{ version: versionProbe("claude") }
|
|
203
|
+
{ version: versionProbe("claude") },
|
|
180
204
|
),
|
|
181
205
|
codex: spec(
|
|
182
206
|
"codex",
|
|
183
207
|
"optional",
|
|
184
208
|
(pf = rawPlatform()) => hostOs(platformName(pf)).installHint("codex"),
|
|
185
|
-
{ version: versionProbe("codex") }
|
|
209
|
+
{ version: versionProbe("codex") },
|
|
186
210
|
),
|
|
187
211
|
omp: spec(
|
|
188
212
|
"omp",
|
|
189
213
|
"optional",
|
|
190
|
-
() =>
|
|
191
|
-
|
|
214
|
+
() =>
|
|
215
|
+
"install omp from https://github.com/can1357/oh-my-pi (an existing install self-updates with `omp update`)",
|
|
216
|
+
{ version: versionProbe("omp", ["--version"], (out) => out.trim().replace(/^omp[/v]/, "")) },
|
|
192
217
|
),
|
|
193
|
-
bun: spec(
|
|
194
|
-
|
|
218
|
+
bun: spec("bun", "optional", () => "curl -fsSL https://bun.sh/install | bash", {
|
|
219
|
+
resolve: resolveBun,
|
|
220
|
+
version: async (exec) => {
|
|
221
|
+
const bun = findBun(exec);
|
|
222
|
+
if (bun === undefined) return "";
|
|
223
|
+
return await exec.capture(bun.command, ["--version"]);
|
|
224
|
+
},
|
|
225
|
+
}),
|
|
226
|
+
bwrap: spec(
|
|
227
|
+
"bwrap",
|
|
195
228
|
"optional",
|
|
196
|
-
() => "
|
|
229
|
+
() => "sudo apt install -y bubblewrap (or dnf/pacman/zypper equivalent)",
|
|
197
230
|
{
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const bun = findBun(exec)
|
|
201
|
-
if (bun === undefined) return ""
|
|
202
|
-
return await exec.capture(bun.command, ["--version"])
|
|
203
|
-
}
|
|
204
|
-
}
|
|
231
|
+
version: versionProbe("bwrap"),
|
|
232
|
+
},
|
|
205
233
|
),
|
|
206
|
-
bwrap: spec("bwrap", "optional", () => "sudo apt install -y bubblewrap (or dnf/pacman/zypper equivalent)", {
|
|
207
|
-
version: versionProbe("bwrap")
|
|
208
|
-
}),
|
|
209
234
|
ffplay: spec(
|
|
210
235
|
"ffplay",
|
|
211
236
|
"optional",
|
|
212
237
|
(pf = rawPlatform()) => hostOs(platformName(pf)).installHint("ffplay"),
|
|
213
|
-
{
|
|
238
|
+
{
|
|
239
|
+
versionArgs: ["-version"],
|
|
240
|
+
version: versionProbe("ffplay", ["-version"]),
|
|
241
|
+
resolve: pathProbe("ffplay"),
|
|
242
|
+
},
|
|
214
243
|
),
|
|
215
244
|
intelephense: spec("intelephense", "optional", () => "npm install -g intelephense", {
|
|
216
245
|
resolve: pathProbe("intelephense"),
|
|
217
|
-
version: versionNpmGlobal("intelephense")
|
|
246
|
+
version: versionNpmGlobal("intelephense"),
|
|
218
247
|
}),
|
|
219
248
|
"typescript-language-server": spec(
|
|
220
249
|
"typescript-language-server",
|
|
221
250
|
"optional",
|
|
222
251
|
() => "npm install -g typescript-language-server typescript",
|
|
223
|
-
{
|
|
252
|
+
{
|
|
253
|
+
resolve: pathProbe("typescript-language-server"),
|
|
254
|
+
version: versionProbe("typescript-language-server"),
|
|
255
|
+
},
|
|
224
256
|
),
|
|
225
257
|
tsc: spec("tsc", "optional", () => "npm install -g typescript", {
|
|
226
258
|
resolve: pathProbe("tsc"),
|
|
227
|
-
version: versionProbe("tsc")
|
|
259
|
+
version: versionProbe("tsc"),
|
|
228
260
|
}),
|
|
229
261
|
"rust-analyzer": spec("rust-analyzer", "optional", () => "rustup component add rust-analyzer", {
|
|
230
262
|
resolve: pathProbe("rust-analyzer"),
|
|
231
|
-
version: versionProbe("rust-analyzer")
|
|
263
|
+
version: versionProbe("rust-analyzer"),
|
|
232
264
|
}),
|
|
233
265
|
rustup: spec("rustup", "optional", () => "install the Rust toolchain from https://rustup.rs", {
|
|
234
|
-
version: versionProbe("rustup")
|
|
266
|
+
version: versionProbe("rustup"),
|
|
235
267
|
}),
|
|
236
268
|
"apt-get": spec("apt-get", "optional", () => "install apt via your Linux distribution"),
|
|
237
269
|
dnf: spec("dnf", "optional", () => "install dnf via your Linux distribution"),
|
|
238
270
|
pacman: spec("pacman", "optional", () => "install pacman via your Linux distribution"),
|
|
239
|
-
zypper: spec("zypper", "optional", () => "install zypper via your Linux distribution")
|
|
240
|
-
}
|
|
271
|
+
zypper: spec("zypper", "optional", () => "install zypper via your Linux distribution"),
|
|
272
|
+
};
|
|
241
273
|
|
|
242
274
|
export function resolveDependency(
|
|
243
275
|
specification: DependencySpec,
|
|
244
276
|
exec: ProbeExecutor,
|
|
245
|
-
platform: NodeJS.Platform = rawPlatform()
|
|
277
|
+
platform: NodeJS.Platform = rawPlatform(),
|
|
246
278
|
): ProbeResult {
|
|
247
|
-
return (specification.resolve ?? pathProbe(specification.id))(exec, platform)
|
|
279
|
+
return (specification.resolve ?? pathProbe(specification.id))(exec, platform);
|
|
248
280
|
}
|
|
249
281
|
|
|
250
|
-
export async function resolveVersion(
|
|
251
|
-
|
|
252
|
-
|
|
282
|
+
export async function resolveVersion(
|
|
283
|
+
specification: DependencySpec,
|
|
284
|
+
exec: ProbeExecutor,
|
|
285
|
+
): Promise<string> {
|
|
286
|
+
if (resolveDependency(specification, exec).state !== "present") return "";
|
|
287
|
+
return await (specification.version ?? versionProbe(specification.id, specification.versionArgs))(
|
|
288
|
+
exec,
|
|
289
|
+
);
|
|
253
290
|
}
|
|
254
291
|
|
|
255
292
|
export async function resolvePath(
|
|
256
293
|
specification: DependencySpec,
|
|
257
294
|
exec: ProbeExecutor,
|
|
258
|
-
platform: NodeJS.Platform = rawPlatform()
|
|
295
|
+
platform: NodeJS.Platform = rawPlatform(),
|
|
259
296
|
): Promise<string> {
|
|
260
|
-
const result = resolveDependency(specification, exec, platform)
|
|
261
|
-
return result.state === "present" ? (result.path ?? exec.which(specification.id)) : ""
|
|
297
|
+
const result = resolveDependency(specification, exec, platform);
|
|
298
|
+
return result.state === "present" ? (result.path ?? exec.which(specification.id)) : "";
|
|
262
299
|
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EngineNative run context: the shared `Ctx` shape plus its construction from
|
|
3
|
+
* the environment. Split from index.ts, which re-exports the public surface
|
|
4
|
+
* so existing import paths keep working.
|
|
5
|
+
*/
|
|
6
|
+
import { p } from "./exec";
|
|
7
|
+
import { engineHome } from "./harnesses";
|
|
8
|
+
import type { TerminalLease } from "./logger";
|
|
9
|
+
import type { BunRuntimeState } from "./bun";
|
|
10
|
+
import { kitHome } from "../kitHome";
|
|
11
|
+
import { ExitError, parseClaudePlugin, parseCompactWindow } from "./parseArgs";
|
|
12
|
+
import type { EngineServices } from "./services";
|
|
13
|
+
import type { SyncConcurrency } from "./syncConcurrency";
|
|
14
|
+
|
|
15
|
+
export type ModifierFlag =
|
|
16
|
+
| "--claude-model"
|
|
17
|
+
| "--claude-effort"
|
|
18
|
+
| "--claude-advisor"
|
|
19
|
+
| "--claude-compact-window"
|
|
20
|
+
| "--claude-permissive"
|
|
21
|
+
| "--claude-plugin"
|
|
22
|
+
| "--codex-model"
|
|
23
|
+
| "--codex-effort";
|
|
24
|
+
|
|
25
|
+
export interface Ctx {
|
|
26
|
+
readonly repoDir: string;
|
|
27
|
+
readonly home: string;
|
|
28
|
+
readonly agentsDir: string;
|
|
29
|
+
readonly interactive: boolean;
|
|
30
|
+
dryRun: boolean;
|
|
31
|
+
verbose: boolean;
|
|
32
|
+
skipBubblewrap: boolean;
|
|
33
|
+
skipPluginRefresh?: boolean;
|
|
34
|
+
reconcile: boolean;
|
|
35
|
+
prune: boolean;
|
|
36
|
+
claudeCompactWindow: string;
|
|
37
|
+
claudePermissive: boolean;
|
|
38
|
+
claudePlugins: Array<string>;
|
|
39
|
+
claudeModel: string;
|
|
40
|
+
claudeEffort: string;
|
|
41
|
+
claudeAdvisor: string;
|
|
42
|
+
codexModel: string;
|
|
43
|
+
codexEffort: string;
|
|
44
|
+
/** Distinguishes an explicitly empty modifier from an option that was not supplied. */
|
|
45
|
+
modifierFlags?: Set<ModifierFlag>;
|
|
46
|
+
/** Injected capability seam (logger/deps/platform) — see services.ts. */
|
|
47
|
+
readonly services: EngineServices;
|
|
48
|
+
syncConcurrency: SyncConcurrency;
|
|
49
|
+
terminalLease?: TerminalLease;
|
|
50
|
+
bunRuntime?: Promise<BunRuntimeState>;
|
|
51
|
+
targetFilterSet: boolean;
|
|
52
|
+
syncClaude: boolean;
|
|
53
|
+
syncCodex: boolean;
|
|
54
|
+
syncAgents: boolean;
|
|
55
|
+
syncOmp: boolean;
|
|
56
|
+
/** Per-run next-step triggers (Output Policy): advice prints only when its trigger changed or --verbose. */
|
|
57
|
+
readonly nextStepTriggers: {
|
|
58
|
+
claudePlugins: boolean;
|
|
59
|
+
claudeRestart: boolean;
|
|
60
|
+
codexRestart: boolean;
|
|
61
|
+
skillsRestart: boolean;
|
|
62
|
+
ompRestart: boolean;
|
|
63
|
+
};
|
|
64
|
+
/** Harness-CLI operations that failed this run; a non-empty list fails the sync. */
|
|
65
|
+
readonly failures: Array<string>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Globals default from env using the historical ${VAR:-default} contract. */
|
|
69
|
+
export function makeCtx(services: EngineServices): Ctx {
|
|
70
|
+
const env = process.env;
|
|
71
|
+
const home = engineHome(env);
|
|
72
|
+
const compactWindowSource = env["CLAUDE_COMPACT_WINDOW"] ?? "";
|
|
73
|
+
const claudeCompactWindow =
|
|
74
|
+
compactWindowSource === "" ? "" : parseCompactWindow(compactWindowSource);
|
|
75
|
+
if (claudeCompactWindow === undefined) {
|
|
76
|
+
services.logger.err("CLAUDE_COMPACT_WINDOW expects a token count (e.g. 680000 or 680k)");
|
|
77
|
+
throw new ExitError(2);
|
|
78
|
+
}
|
|
79
|
+
const claudePlugins = (env["CLAUDE_PLUGINS"] ?? "")
|
|
80
|
+
.split(" ")
|
|
81
|
+
.filter((plugin) => plugin !== "")
|
|
82
|
+
.map((plugin) => parseClaudePlugin(plugin, services.logger.err));
|
|
83
|
+
return {
|
|
84
|
+
repoDir: kitHome(),
|
|
85
|
+
home,
|
|
86
|
+
agentsDir:
|
|
87
|
+
env["AGENTS_DIR"] !== undefined && env["AGENTS_DIR"] !== ""
|
|
88
|
+
? env["AGENTS_DIR"]
|
|
89
|
+
: p(home, ".agents"),
|
|
90
|
+
interactive:
|
|
91
|
+
env["DOCKS_KIT_INTERACTIVE"] === "1" ||
|
|
92
|
+
(env["DOCKS_KIT_INTERACTIVE"] !== "0" &&
|
|
93
|
+
process.stdout.isTTY === true &&
|
|
94
|
+
process.stdin.isTTY === true),
|
|
95
|
+
dryRun: env["DRY_RUN"] === "1",
|
|
96
|
+
verbose: env["DOCKS_KIT_VERBOSE"] === "1",
|
|
97
|
+
skipBubblewrap: env["SKIP_BUBBLEWRAP"] === "1",
|
|
98
|
+
skipPluginRefresh: false,
|
|
99
|
+
reconcile: env["RECONCILE"] === "1",
|
|
100
|
+
prune: env["PRUNE"] === "1",
|
|
101
|
+
claudeCompactWindow,
|
|
102
|
+
claudePermissive: env["CLAUDE_PERMISSIVE"] === "1",
|
|
103
|
+
claudePlugins,
|
|
104
|
+
claudeModel: env["CLAUDE_MODEL"] ?? "",
|
|
105
|
+
claudeEffort: "",
|
|
106
|
+
claudeAdvisor: "",
|
|
107
|
+
codexModel: env["CODEX_MODEL"] ?? "",
|
|
108
|
+
codexEffort: "",
|
|
109
|
+
modifierFlags: new Set(),
|
|
110
|
+
syncConcurrency: 3,
|
|
111
|
+
services,
|
|
112
|
+
targetFilterSet: false,
|
|
113
|
+
syncClaude: false,
|
|
114
|
+
syncCodex: false,
|
|
115
|
+
syncAgents: false,
|
|
116
|
+
syncOmp: false,
|
|
117
|
+
nextStepTriggers: {
|
|
118
|
+
claudePlugins: false,
|
|
119
|
+
claudeRestart: false,
|
|
120
|
+
codexRestart: false,
|
|
121
|
+
skillsRestart: false,
|
|
122
|
+
ompRestart: false,
|
|
123
|
+
},
|
|
124
|
+
failures: [],
|
|
125
|
+
};
|
|
126
|
+
}
|