@hasna/machines 0.0.30 → 0.0.32
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/cli/index.js +1069 -1055
- package/dist/commands/apps.d.ts +4 -3
- package/dist/commands/apps.d.ts.map +1 -1
- package/dist/commands/install-claude.d.ts +4 -3
- package/dist/commands/install-claude.d.ts.map +1 -1
- package/dist/commands/install-tailscale.d.ts +2 -1
- package/dist/commands/install-tailscale.d.ts.map +1 -1
- package/dist/commands/setup.d.ts +2 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/sync.d.ts +3 -2
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/consumer.js +11 -0
- package/dist/index.js +88 -70
- package/dist/mcp/index.js +88 -70
- package/dist/remote.d.ts +3 -0
- package/dist/remote.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/commands/apps.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { type MachineCommandRunner } from "../remote.js";
|
|
1
2
|
import type { AppsDiffResult, AppsStatusResult, ManifestAppSpec, SetupResult } from "../types.js";
|
|
2
3
|
export declare function listApps(machineId?: string): {
|
|
3
4
|
machineId: string;
|
|
4
5
|
apps: ManifestAppSpec[];
|
|
5
6
|
};
|
|
6
7
|
export declare function buildAppsPlan(machineId?: string): SetupResult;
|
|
7
|
-
export declare function getAppsStatus(machineId?: string): AppsStatusResult;
|
|
8
|
-
export declare function diffApps(machineId?: string): AppsDiffResult;
|
|
8
|
+
export declare function getAppsStatus(machineId?: string, runner?: MachineCommandRunner): AppsStatusResult;
|
|
9
|
+
export declare function diffApps(machineId?: string, runner?: MachineCommandRunner): AppsDiffResult;
|
|
9
10
|
export declare function runAppsInstall(machineId?: string, options?: {
|
|
10
11
|
apply?: boolean;
|
|
11
12
|
yes?: boolean;
|
|
12
|
-
}): SetupResult;
|
|
13
|
+
}, runner?: MachineCommandRunner): SetupResult;
|
|
13
14
|
//# sourceMappingURL=apps.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"AACA,OAAO,EAAmD,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC1G,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAGhB,eAAe,EACf,WAAW,EAEZ,MAAM,aAAa,CAAC;AAqGrB,wBAAgB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,EAAE,CAAA;CAAE,CAM3F;AAED,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAQ7D;AAED,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,GAAE,oBAAwC,GAAG,gBAAgB,CAYpH;AAED,wBAAgB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,GAAE,oBAAwC,GAAG,cAAc,CAO7G;AAED,wBAAgB,cAAc,CAC5B,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,EAChD,MAAM,GAAE,oBAAwC,GAC/C,WAAW,CAmBb"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type MachineCommandRunner } from "../remote.js";
|
|
1
2
|
import type { ClaudeCliDiffResult, ClaudeCliStatusResult, SetupResult } from "../types.js";
|
|
2
3
|
declare const AI_CLI_PACKAGES: {
|
|
3
4
|
readonly claude: "@anthropic-ai/claude-code";
|
|
@@ -6,11 +7,11 @@ declare const AI_CLI_PACKAGES: {
|
|
|
6
7
|
};
|
|
7
8
|
export type AiCliTool = keyof typeof AI_CLI_PACKAGES;
|
|
8
9
|
export declare function buildClaudeInstallPlan(machineId?: string, tools?: string[]): SetupResult;
|
|
9
|
-
export declare function getClaudeCliStatus(machineId?: string, tools?: string[]): ClaudeCliStatusResult;
|
|
10
|
-
export declare function diffClaudeCli(machineId?: string, tools?: string[]): ClaudeCliDiffResult;
|
|
10
|
+
export declare function getClaudeCliStatus(machineId?: string, tools?: string[], runner?: MachineCommandRunner): ClaudeCliStatusResult;
|
|
11
|
+
export declare function diffClaudeCli(machineId?: string, tools?: string[], runner?: MachineCommandRunner): ClaudeCliDiffResult;
|
|
11
12
|
export declare function runClaudeInstall(machineId?: string, tools?: string[], options?: {
|
|
12
13
|
apply?: boolean;
|
|
13
14
|
yes?: boolean;
|
|
14
|
-
}): SetupResult;
|
|
15
|
+
}, runner?: MachineCommandRunner): SetupResult;
|
|
15
16
|
export {};
|
|
16
17
|
//# sourceMappingURL=install-claude.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-claude.d.ts","sourceRoot":"","sources":["../../src/commands/install-claude.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install-claude.d.ts","sourceRoot":"","sources":["../../src/commands/install-claude.ts"],"names":[],"mappings":"AACA,OAAO,EAAmD,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC1G,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,EAAkC,WAAW,EAAa,MAAM,aAAa,CAAC;AAEtI,QAAA,MAAM,eAAe;;;;CAIX,CAAC;AAQX,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,eAAe,CAAC;AAkDrD,wBAAgB,sBAAsB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,WAAW,CAQxF;AAED,wBAAgB,kBAAkB,CAChC,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,MAAM,GAAE,oBAAwC,GAC/C,qBAAqB,CAYvB;AAED,wBAAgB,aAAa,CAC3B,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,MAAM,GAAE,oBAAwC,GAC/C,mBAAmB,CAOrB;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,EAChD,MAAM,GAAE,oBAAwC,GAC/C,WAAW,CAmBb"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { type MachineCommandRunner } from "../remote.js";
|
|
1
2
|
import type { SetupResult } from "../types.js";
|
|
2
3
|
export declare function buildTailscaleInstallPlan(machineId?: string): SetupResult;
|
|
3
4
|
export declare function runTailscaleInstall(machineId?: string, options?: {
|
|
4
5
|
apply?: boolean;
|
|
5
6
|
yes?: boolean;
|
|
6
|
-
}): SetupResult;
|
|
7
|
+
}, runner?: MachineCommandRunner): SetupResult;
|
|
7
8
|
//# sourceMappingURL=install-tailscale.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-tailscale.d.ts","sourceRoot":"","sources":["../../src/commands/install-tailscale.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,WAAW,EAAa,MAAM,aAAa,CAAC;AAoC3E,wBAAgB,yBAAyB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"install-tailscale.d.ts","sourceRoot":"","sources":["../../src/commands/install-tailscale.ts"],"names":[],"mappings":"AACA,OAAO,EAAmD,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC1G,OAAO,KAAK,EAAmB,WAAW,EAAa,MAAM,aAAa,CAAC;AAoC3E,wBAAgB,yBAAyB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAWzE;AAED,wBAAgB,mBAAmB,CACjC,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,EAChD,MAAM,GAAE,oBAAwC,GAC/C,WAAW,CAmBb"}
|
package/dist/commands/setup.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { type MachineCommandRunner } from "../remote.js";
|
|
1
2
|
import type { SetupResult } from "../types.js";
|
|
2
3
|
export declare function buildSetupPlan(machineId?: string): SetupResult;
|
|
3
4
|
export declare function runSetup(machineId?: string, options?: {
|
|
4
5
|
apply?: boolean;
|
|
5
6
|
yes?: boolean;
|
|
6
|
-
}): SetupResult;
|
|
7
|
+
}, runner?: MachineCommandRunner): SetupResult;
|
|
7
8
|
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,WAAW,EAAa,MAAM,aAAa,CAAC;AAsE3E,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoD,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC3G,OAAO,KAAK,EAAmB,WAAW,EAAa,MAAM,aAAa,CAAC;AAsE3E,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAyB9D;AAED,wBAAgB,QAAQ,CACtB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,EAChD,MAAM,GAAE,oBAAwC,GAC/C,WAAW,CAmCb"}
|
package/dist/commands/sync.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { type MachineCommandRunner } from "../remote.js";
|
|
1
2
|
import type { SyncResult } from "../types.js";
|
|
2
|
-
export declare function buildSyncPlan(machineId?: string): SyncResult;
|
|
3
|
+
export declare function buildSyncPlan(machineId?: string, runner?: MachineCommandRunner): SyncResult;
|
|
3
4
|
export declare function runSync(machineId?: string, options?: {
|
|
4
5
|
apply?: boolean;
|
|
5
6
|
yes?: boolean;
|
|
6
|
-
}): SyncResult;
|
|
7
|
+
}, runner?: MachineCommandRunner): SyncResult;
|
|
7
8
|
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAA+B,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAMA,OAAO,EAA2E,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAClI,OAAO,KAAK,EAA+B,UAAU,EAAE,MAAM,aAAa,CAAC;AAqF3E,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,GAAE,oBAAwC,GAAG,UAAU,CA4B9G;AAwBD,wBAAgB,OAAO,CACrB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,EAChD,MAAM,GAAE,oBAAwC,GAC/C,UAAU,CAwCZ"}
|
package/dist/consumer.js
CHANGED
|
@@ -5633,6 +5633,17 @@ function runMachineCommand(machineId, command) {
|
|
|
5633
5633
|
exitCode: result.status ?? 1
|
|
5634
5634
|
};
|
|
5635
5635
|
}
|
|
5636
|
+
function describeMachineCommandFailure(operation, result) {
|
|
5637
|
+
const detail = (result.stderr || result.stdout || "").trim();
|
|
5638
|
+
const suffix = detail ? `: ${detail}` : "";
|
|
5639
|
+
return `${operation} failed on ${result.machineId} via ${result.source} (exit ${result.exitCode})${suffix}`;
|
|
5640
|
+
}
|
|
5641
|
+
function requireMachineCommandSuccess(operation, result) {
|
|
5642
|
+
if (result.exitCode !== 0) {
|
|
5643
|
+
throw new Error(describeMachineCommandFailure(operation, result));
|
|
5644
|
+
}
|
|
5645
|
+
return result;
|
|
5646
|
+
}
|
|
5636
5647
|
|
|
5637
5648
|
// src/compatibility.ts
|
|
5638
5649
|
var DEFAULT_COMMANDS = [
|
package/dist/index.js
CHANGED
|
@@ -12202,6 +12202,17 @@ function runMachineCommand(machineId, command) {
|
|
|
12202
12202
|
exitCode: result.status ?? 1
|
|
12203
12203
|
};
|
|
12204
12204
|
}
|
|
12205
|
+
function describeMachineCommandFailure(operation, result) {
|
|
12206
|
+
const detail = (result.stderr || result.stdout || "").trim();
|
|
12207
|
+
const suffix = detail ? `: ${detail}` : "";
|
|
12208
|
+
return `${operation} failed on ${result.machineId} via ${result.source} (exit ${result.exitCode})${suffix}`;
|
|
12209
|
+
}
|
|
12210
|
+
function requireMachineCommandSuccess(operation, result) {
|
|
12211
|
+
if (result.exitCode !== 0) {
|
|
12212
|
+
throw new Error(describeMachineCommandFailure(operation, result));
|
|
12213
|
+
}
|
|
12214
|
+
return result;
|
|
12215
|
+
}
|
|
12205
12216
|
|
|
12206
12217
|
// src/compatibility.ts
|
|
12207
12218
|
var DEFAULT_COMMANDS = [
|
|
@@ -12634,7 +12645,14 @@ function buildAppSteps(machine) {
|
|
|
12634
12645
|
}));
|
|
12635
12646
|
}
|
|
12636
12647
|
function resolveMachine(machineId) {
|
|
12637
|
-
|
|
12648
|
+
if (!machineId)
|
|
12649
|
+
return detectCurrentMachineManifest();
|
|
12650
|
+
return getManifestMachine(machineId) || {
|
|
12651
|
+
id: machineId,
|
|
12652
|
+
platform: "linux",
|
|
12653
|
+
workspacePath: "",
|
|
12654
|
+
apps: []
|
|
12655
|
+
};
|
|
12638
12656
|
}
|
|
12639
12657
|
function parseProbeOutput(app, machine, stdout) {
|
|
12640
12658
|
const lines = stdout.trim().split(`
|
|
@@ -12665,27 +12683,28 @@ function buildAppsPlan(machineId) {
|
|
|
12665
12683
|
executed: 0
|
|
12666
12684
|
};
|
|
12667
12685
|
}
|
|
12668
|
-
function getAppsStatus(machineId) {
|
|
12686
|
+
function getAppsStatus(machineId, runner = runMachineCommand) {
|
|
12669
12687
|
const machine = resolveMachine(machineId);
|
|
12688
|
+
const readiness = requireMachineCommandSuccess("Apps status readiness check", runner(machine.id, "true"));
|
|
12670
12689
|
const apps = (machine.apps || []).map((app) => {
|
|
12671
|
-
const probe =
|
|
12690
|
+
const probe = requireMachineCommandSuccess(`App probe ${app.name}`, runner(machine.id, buildAppProbeCommand(machine, app)));
|
|
12672
12691
|
return parseProbeOutput(app, machine, probe.stdout);
|
|
12673
12692
|
});
|
|
12674
12693
|
return {
|
|
12675
12694
|
machineId: machine.id,
|
|
12676
|
-
source:
|
|
12695
|
+
source: readiness.source,
|
|
12677
12696
|
apps
|
|
12678
12697
|
};
|
|
12679
12698
|
}
|
|
12680
|
-
function diffApps(machineId) {
|
|
12681
|
-
const status = getAppsStatus(machineId);
|
|
12699
|
+
function diffApps(machineId, runner = runMachineCommand) {
|
|
12700
|
+
const status = getAppsStatus(machineId, runner);
|
|
12682
12701
|
return {
|
|
12683
12702
|
...status,
|
|
12684
12703
|
missing: status.apps.filter((app) => !app.installed).map((app) => app.name),
|
|
12685
12704
|
installed: status.apps.filter((app) => app.installed).map((app) => app.name)
|
|
12686
12705
|
};
|
|
12687
12706
|
}
|
|
12688
|
-
function runAppsInstall(machineId, options = {}) {
|
|
12707
|
+
function runAppsInstall(machineId, options = {}, runner = runMachineCommand) {
|
|
12689
12708
|
const plan = buildAppsPlan(machineId);
|
|
12690
12709
|
if (!options.apply)
|
|
12691
12710
|
return plan;
|
|
@@ -12694,14 +12713,7 @@ function runAppsInstall(machineId, options = {}) {
|
|
|
12694
12713
|
}
|
|
12695
12714
|
let executed = 0;
|
|
12696
12715
|
for (const step of plan.steps) {
|
|
12697
|
-
|
|
12698
|
-
stdout: "pipe",
|
|
12699
|
-
stderr: "pipe",
|
|
12700
|
-
env: process.env
|
|
12701
|
-
});
|
|
12702
|
-
if (result.exitCode !== 0) {
|
|
12703
|
-
throw new Error(`App install failed (${step.id}): ${result.stderr.toString().trim()}`);
|
|
12704
|
-
}
|
|
12716
|
+
requireMachineCommandSuccess(`App install ${step.id}`, runner(plan.machineId, step.command));
|
|
12705
12717
|
executed += 1;
|
|
12706
12718
|
}
|
|
12707
12719
|
return {
|
|
@@ -12990,7 +13002,13 @@ function buildInstallSteps(machine, tools) {
|
|
|
12990
13002
|
}));
|
|
12991
13003
|
}
|
|
12992
13004
|
function resolveMachine2(machineId) {
|
|
12993
|
-
|
|
13005
|
+
if (!machineId)
|
|
13006
|
+
return detectCurrentMachineManifest();
|
|
13007
|
+
return getManifestMachine(machineId) || {
|
|
13008
|
+
id: machineId,
|
|
13009
|
+
platform: "linux",
|
|
13010
|
+
workspacePath: ""
|
|
13011
|
+
};
|
|
12994
13012
|
}
|
|
12995
13013
|
function buildProbeCommand(tool) {
|
|
12996
13014
|
const binary = getToolBinary(tool);
|
|
@@ -13017,25 +13035,28 @@ function buildClaudeInstallPlan(machineId, tools) {
|
|
|
13017
13035
|
executed: 0
|
|
13018
13036
|
};
|
|
13019
13037
|
}
|
|
13020
|
-
function getClaudeCliStatus(machineId, tools) {
|
|
13038
|
+
function getClaudeCliStatus(machineId, tools, runner = runMachineCommand) {
|
|
13021
13039
|
const machine = resolveMachine2(machineId);
|
|
13022
13040
|
const normalizedTools = normalizeTools(tools);
|
|
13023
|
-
const route =
|
|
13041
|
+
const route = requireMachineCommandSuccess("AI CLI status readiness check", runner(machine.id, "true")).source;
|
|
13024
13042
|
return {
|
|
13025
13043
|
machineId: machine.id,
|
|
13026
13044
|
source: route,
|
|
13027
|
-
tools: normalizedTools.map((tool) =>
|
|
13045
|
+
tools: normalizedTools.map((tool) => {
|
|
13046
|
+
const result = requireMachineCommandSuccess(`AI CLI probe ${tool}`, runner(machine.id, buildProbeCommand(tool)));
|
|
13047
|
+
return parseProbe(tool, result.stdout);
|
|
13048
|
+
})
|
|
13028
13049
|
};
|
|
13029
13050
|
}
|
|
13030
|
-
function diffClaudeCli(machineId, tools) {
|
|
13031
|
-
const status = getClaudeCliStatus(machineId, tools);
|
|
13051
|
+
function diffClaudeCli(machineId, tools, runner = runMachineCommand) {
|
|
13052
|
+
const status = getClaudeCliStatus(machineId, tools, runner);
|
|
13032
13053
|
return {
|
|
13033
13054
|
...status,
|
|
13034
13055
|
missing: status.tools.filter((tool) => !tool.installed).map((tool) => tool.tool),
|
|
13035
13056
|
installed: status.tools.filter((tool) => tool.installed).map((tool) => tool.tool)
|
|
13036
13057
|
};
|
|
13037
13058
|
}
|
|
13038
|
-
function runClaudeInstall(machineId, tools, options = {}) {
|
|
13059
|
+
function runClaudeInstall(machineId, tools, options = {}, runner = runMachineCommand) {
|
|
13039
13060
|
const plan = buildClaudeInstallPlan(machineId, tools);
|
|
13040
13061
|
if (!options.apply)
|
|
13041
13062
|
return plan;
|
|
@@ -13044,14 +13065,7 @@ function runClaudeInstall(machineId, tools, options = {}) {
|
|
|
13044
13065
|
}
|
|
13045
13066
|
let executed = 0;
|
|
13046
13067
|
for (const step of plan.steps) {
|
|
13047
|
-
|
|
13048
|
-
stdout: "pipe",
|
|
13049
|
-
stderr: "pipe",
|
|
13050
|
-
env: process.env
|
|
13051
|
-
});
|
|
13052
|
-
if (result.exitCode !== 0) {
|
|
13053
|
-
throw new Error(`AI CLI install failed (${step.id}): ${result.stderr.toString().trim()}`);
|
|
13054
|
-
}
|
|
13068
|
+
requireMachineCommandSuccess(`AI CLI install ${step.id}`, runner(plan.machineId, step.command));
|
|
13055
13069
|
executed += 1;
|
|
13056
13070
|
}
|
|
13057
13071
|
return {
|
|
@@ -13094,7 +13108,10 @@ function buildInstallSteps2(machine) {
|
|
|
13094
13108
|
];
|
|
13095
13109
|
}
|
|
13096
13110
|
function buildTailscaleInstallPlan(machineId) {
|
|
13097
|
-
const machine =
|
|
13111
|
+
const machine = machineId ? getManifestMachine(machineId) : detectCurrentMachineManifest();
|
|
13112
|
+
if (!machine) {
|
|
13113
|
+
throw new Error(`Machine not found in manifest: ${machineId}`);
|
|
13114
|
+
}
|
|
13098
13115
|
return {
|
|
13099
13116
|
machineId: machine.id,
|
|
13100
13117
|
mode: "plan",
|
|
@@ -13102,7 +13119,7 @@ function buildTailscaleInstallPlan(machineId) {
|
|
|
13102
13119
|
executed: 0
|
|
13103
13120
|
};
|
|
13104
13121
|
}
|
|
13105
|
-
function runTailscaleInstall(machineId, options = {}) {
|
|
13122
|
+
function runTailscaleInstall(machineId, options = {}, runner = runMachineCommand) {
|
|
13106
13123
|
const plan = buildTailscaleInstallPlan(machineId);
|
|
13107
13124
|
if (!options.apply)
|
|
13108
13125
|
return plan;
|
|
@@ -13111,14 +13128,7 @@ function runTailscaleInstall(machineId, options = {}) {
|
|
|
13111
13128
|
}
|
|
13112
13129
|
let executed = 0;
|
|
13113
13130
|
for (const step of plan.steps) {
|
|
13114
|
-
|
|
13115
|
-
stdout: "pipe",
|
|
13116
|
-
stderr: "pipe",
|
|
13117
|
-
env: process.env
|
|
13118
|
-
});
|
|
13119
|
-
if (result.exitCode !== 0) {
|
|
13120
|
-
throw new Error(`Tailscale install failed (${step.id}): ${result.stderr.toString().trim()}`);
|
|
13121
|
-
}
|
|
13131
|
+
requireMachineCommandSuccess(`Tailscale install ${step.id}`, runner(plan.machineId, step.command));
|
|
13122
13132
|
executed += 1;
|
|
13123
13133
|
}
|
|
13124
13134
|
return {
|
|
@@ -14482,6 +14492,9 @@ function buildSetupPlan(machineId) {
|
|
|
14482
14492
|
const manifest = readManifest();
|
|
14483
14493
|
const currentMachineId = getLocalMachineId();
|
|
14484
14494
|
const selected = machineId ? manifest.machines.find((machine) => machine.id === machineId) : manifest.machines.find((machine) => machine.id === currentMachineId);
|
|
14495
|
+
if (machineId && !selected) {
|
|
14496
|
+
throw new Error(`Machine not found in manifest: ${machineId}`);
|
|
14497
|
+
}
|
|
14485
14498
|
const target = selected || {
|
|
14486
14499
|
id: currentMachineId,
|
|
14487
14500
|
platform: "linux",
|
|
@@ -14495,7 +14508,7 @@ function buildSetupPlan(machineId) {
|
|
|
14495
14508
|
executed: 0
|
|
14496
14509
|
};
|
|
14497
14510
|
}
|
|
14498
|
-
function runSetup(machineId, options = {}) {
|
|
14511
|
+
function runSetup(machineId, options = {}, runner = runMachineCommand) {
|
|
14499
14512
|
const plan = buildSetupPlan(machineId);
|
|
14500
14513
|
if (!options.apply) {
|
|
14501
14514
|
return plan;
|
|
@@ -14505,18 +14518,17 @@ function runSetup(machineId, options = {}) {
|
|
|
14505
14518
|
}
|
|
14506
14519
|
let executed = 0;
|
|
14507
14520
|
for (const step of plan.steps) {
|
|
14508
|
-
const result =
|
|
14509
|
-
stdout: "pipe",
|
|
14510
|
-
stderr: "pipe",
|
|
14511
|
-
env: process.env
|
|
14512
|
-
});
|
|
14521
|
+
const result = runner(plan.machineId, step.command);
|
|
14513
14522
|
if (result.exitCode !== 0) {
|
|
14514
14523
|
recordSetupRun(plan.machineId, "failed", {
|
|
14515
14524
|
executed,
|
|
14516
14525
|
failedStep: step,
|
|
14517
|
-
stderr: result.stderr
|
|
14526
|
+
stderr: result.stderr,
|
|
14527
|
+
stdout: result.stdout,
|
|
14528
|
+
exitCode: result.exitCode,
|
|
14529
|
+
source: result.source
|
|
14518
14530
|
});
|
|
14519
|
-
throw new Error(`Setup step
|
|
14531
|
+
throw new Error(describeMachineCommandFailure(`Setup step ${step.id}`, result));
|
|
14520
14532
|
}
|
|
14521
14533
|
executed += 1;
|
|
14522
14534
|
}
|
|
@@ -14657,16 +14669,17 @@ function quote4(value) {
|
|
|
14657
14669
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
14658
14670
|
}
|
|
14659
14671
|
function packageCheckCommand(machine, packageName, manager = machine.platform === "macos" ? "brew" : "apt") {
|
|
14672
|
+
const quotedPackageName = quote4(packageName);
|
|
14660
14673
|
if (manager === "bun") {
|
|
14661
|
-
return `bun pm ls -g --all | grep -F ${
|
|
14674
|
+
return `if bun pm ls -g --all 2>/dev/null | grep -F ${quotedPackageName} >/dev/null 2>&1; then printf 'installed=1\\n'; else printf 'installed=0\\n'; fi`;
|
|
14662
14675
|
}
|
|
14663
14676
|
if (manager === "brew") {
|
|
14664
|
-
return `brew list --versions ${
|
|
14677
|
+
return `if brew list --versions ${quotedPackageName} >/dev/null 2>&1; then printf 'installed=1\\n'; else printf 'installed=0\\n'; fi`;
|
|
14665
14678
|
}
|
|
14666
14679
|
if (manager === "apt") {
|
|
14667
|
-
return `dpkg -s ${
|
|
14680
|
+
return `if dpkg -s ${quotedPackageName} >/dev/null 2>&1; then printf 'installed=1\\n'; else printf 'installed=0\\n'; fi`;
|
|
14668
14681
|
}
|
|
14669
|
-
return `command -v ${
|
|
14682
|
+
return `if command -v ${quotedPackageName} >/dev/null 2>&1; then printf 'installed=1\\n'; else printf 'installed=0\\n'; fi`;
|
|
14670
14683
|
}
|
|
14671
14684
|
function packageInstallCommand(machine, packageName, manager = machine.platform === "macos" ? "brew" : "apt") {
|
|
14672
14685
|
if (manager === "bun") {
|
|
@@ -14680,15 +14693,15 @@ function packageInstallCommand(machine, packageName, manager = machine.platform
|
|
|
14680
14693
|
}
|
|
14681
14694
|
return packageName;
|
|
14682
14695
|
}
|
|
14683
|
-
function detectPackageActions(machine) {
|
|
14696
|
+
function detectPackageActions(machine, runner) {
|
|
14684
14697
|
return (machine.packages || []).map((pkg, index) => {
|
|
14685
14698
|
const manager = pkg.manager || (machine.platform === "macos" ? "brew" : "apt");
|
|
14686
|
-
const check2 =
|
|
14687
|
-
|
|
14688
|
-
|
|
14689
|
-
|
|
14690
|
-
|
|
14691
|
-
|
|
14699
|
+
const check2 = runner(machine.id, packageCheckCommand(machine, pkg.name, manager));
|
|
14700
|
+
if (check2.exitCode !== 0) {
|
|
14701
|
+
throw new Error(describeMachineCommandFailure(`Sync package probe ${pkg.name}`, check2));
|
|
14702
|
+
}
|
|
14703
|
+
const installed = check2.stdout.split(`
|
|
14704
|
+
`).some((line) => line.trim() === "installed=1");
|
|
14692
14705
|
return {
|
|
14693
14706
|
id: `package-${index + 1}`,
|
|
14694
14707
|
title: `${installed ? "Package present" : "Install package"} ${pkg.name}`,
|
|
@@ -14699,6 +14712,9 @@ function detectPackageActions(machine) {
|
|
|
14699
14712
|
});
|
|
14700
14713
|
}
|
|
14701
14714
|
function detectFileActions(machine) {
|
|
14715
|
+
if ((machine.files || []).length > 0 && resolveMachineCommand(machine.id, "true").source !== "local") {
|
|
14716
|
+
throw new Error(`Remote file sync planning is not supported for ${machine.id}; refusing to inspect or apply local paths as remote state.`);
|
|
14717
|
+
}
|
|
14702
14718
|
return (machine.files || []).map((file, index) => {
|
|
14703
14719
|
const sourceExists = existsSync8(file.source);
|
|
14704
14720
|
const targetExists = existsSync8(file.target);
|
|
@@ -14722,17 +14738,20 @@ function detectFileActions(machine) {
|
|
|
14722
14738
|
};
|
|
14723
14739
|
});
|
|
14724
14740
|
}
|
|
14725
|
-
function buildSyncPlan(machineId) {
|
|
14741
|
+
function buildSyncPlan(machineId, runner = runMachineCommand) {
|
|
14726
14742
|
const manifest = readManifest();
|
|
14727
14743
|
const currentMachineId = getLocalMachineId();
|
|
14728
14744
|
const selected = machineId ? manifest.machines.find((machine) => machine.id === machineId) : manifest.machines.find((machine) => machine.id === currentMachineId);
|
|
14745
|
+
if (machineId && !selected) {
|
|
14746
|
+
throw new Error(`Machine not found in manifest: ${machineId}`);
|
|
14747
|
+
}
|
|
14729
14748
|
const target = selected || {
|
|
14730
14749
|
id: currentMachineId,
|
|
14731
14750
|
platform: "linux",
|
|
14732
14751
|
workspacePath: `${homedir6()}/workspace`
|
|
14733
14752
|
};
|
|
14734
14753
|
const actions = [
|
|
14735
|
-
...detectPackageActions(target),
|
|
14754
|
+
...detectPackageActions(target, runner),
|
|
14736
14755
|
...detectFileActions(target)
|
|
14737
14756
|
];
|
|
14738
14757
|
return {
|
|
@@ -14762,8 +14781,8 @@ function applyFileAction(command) {
|
|
|
14762
14781
|
symlinkSync(sourcePath, targetPath);
|
|
14763
14782
|
}
|
|
14764
14783
|
}
|
|
14765
|
-
function runSync(machineId, options = {}) {
|
|
14766
|
-
const plan = buildSyncPlan(machineId);
|
|
14784
|
+
function runSync(machineId, options = {}, runner = runMachineCommand) {
|
|
14785
|
+
const plan = buildSyncPlan(machineId, runner);
|
|
14767
14786
|
if (!options.apply) {
|
|
14768
14787
|
return plan;
|
|
14769
14788
|
}
|
|
@@ -14777,18 +14796,17 @@ function runSync(machineId, options = {}) {
|
|
|
14777
14796
|
if (action.kind === "file") {
|
|
14778
14797
|
applyFileAction(action.command);
|
|
14779
14798
|
} else {
|
|
14780
|
-
const result =
|
|
14781
|
-
stdout: "pipe",
|
|
14782
|
-
stderr: "pipe",
|
|
14783
|
-
env: process.env
|
|
14784
|
-
});
|
|
14799
|
+
const result = runner(plan.machineId, action.command);
|
|
14785
14800
|
if (result.exitCode !== 0) {
|
|
14786
14801
|
recordSyncRun(plan.machineId, "failed", {
|
|
14787
14802
|
executed,
|
|
14788
14803
|
failedAction: action,
|
|
14789
|
-
stderr: result.stderr
|
|
14804
|
+
stderr: result.stderr,
|
|
14805
|
+
stdout: result.stdout,
|
|
14806
|
+
exitCode: result.exitCode,
|
|
14807
|
+
source: result.source
|
|
14790
14808
|
});
|
|
14791
|
-
throw new Error(`Sync action
|
|
14809
|
+
throw new Error(describeMachineCommandFailure(`Sync action ${action.id}`, result));
|
|
14792
14810
|
}
|
|
14793
14811
|
}
|
|
14794
14812
|
executed += 1;
|