clawup 1.0.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/README.md +245 -0
- package/dist/adapters/api-adapter.d.ts +76 -0
- package/dist/adapters/api-adapter.js +250 -0
- package/dist/adapters/api-adapter.js.map +1 -0
- package/dist/adapters/cli-adapter.d.ts +15 -0
- package/dist/adapters/cli-adapter.js +208 -0
- package/dist/adapters/cli-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +22 -0
- package/dist/adapters/index.js +32 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/types.d.ts +135 -0
- package/dist/adapters/types.js +14 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/bin.d.ts +8 -0
- package/dist/bin.js +221 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/config.d.ts +21 -0
- package/dist/commands/config.js +323 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/deploy.d.ts +7 -0
- package/dist/commands/deploy.js +13 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/destroy.d.ts +7 -0
- package/dist/commands/destroy.js +13 -0
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.js +698 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +8 -0
- package/dist/commands/list.js +42 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/push.d.ts +7 -0
- package/dist/commands/push.js +19 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/redeploy.d.ts +7 -0
- package/dist/commands/redeploy.js +13 -0
- package/dist/commands/redeploy.js.map +1 -0
- package/dist/commands/secrets.d.ts +16 -0
- package/dist/commands/secrets.js +169 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/ssh.d.ts +9 -0
- package/dist/commands/ssh.js +108 -0
- package/dist/commands/ssh.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.js +13 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.js +126 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.js +13 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/webhooks.d.ts +7 -0
- package/dist/commands/webhooks.js +13 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/lib/__tests__/identity.test.d.ts +1 -0
- package/dist/lib/__tests__/identity.test.js +186 -0
- package/dist/lib/__tests__/identity.test.js.map +1 -0
- package/dist/lib/__tests__/validate-agent.test.d.ts +1 -0
- package/dist/lib/__tests__/validate-agent.test.js +38 -0
- package/dist/lib/__tests__/validate-agent.test.js.map +1 -0
- package/dist/lib/config.d.ts +69 -0
- package/dist/lib/config.js +218 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +5 -0
- package/dist/lib/constants.js +29 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/exec.d.ts +24 -0
- package/dist/lib/exec.js +63 -0
- package/dist/lib/exec.js.map +1 -0
- package/dist/lib/prerequisites.d.ts +8 -0
- package/dist/lib/prerequisites.js +146 -0
- package/dist/lib/prerequisites.js.map +1 -0
- package/dist/lib/process.d.ts +18 -0
- package/dist/lib/process.js +37 -0
- package/dist/lib/process.js.map +1 -0
- package/dist/lib/pulumi.d.ts +37 -0
- package/dist/lib/pulumi.js +87 -0
- package/dist/lib/pulumi.js.map +1 -0
- package/dist/lib/tailscale.d.ts +75 -0
- package/dist/lib/tailscale.js +251 -0
- package/dist/lib/tailscale.js.map +1 -0
- package/dist/lib/tool-helpers.d.ts +15 -0
- package/dist/lib/tool-helpers.js +35 -0
- package/dist/lib/tool-helpers.js.map +1 -0
- package/dist/lib/ui.d.ts +26 -0
- package/dist/lib/ui.js +86 -0
- package/dist/lib/ui.js.map +1 -0
- package/dist/lib/update-check.d.ts +8 -0
- package/dist/lib/update-check.js +151 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/vendor.d.ts +34 -0
- package/dist/lib/vendor.js +128 -0
- package/dist/lib/vendor.js.map +1 -0
- package/dist/lib/workspace.d.ts +21 -0
- package/dist/lib/workspace.js +170 -0
- package/dist/lib/workspace.js.map +1 -0
- package/dist/tools/deploy.d.ts +16 -0
- package/dist/tools/deploy.js +181 -0
- package/dist/tools/deploy.js.map +1 -0
- package/dist/tools/destroy.d.ts +16 -0
- package/dist/tools/destroy.js +119 -0
- package/dist/tools/destroy.js.map +1 -0
- package/dist/tools/index.d.ts +20 -0
- package/dist/tools/index.js +34 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/push.d.ts +29 -0
- package/dist/tools/push.js +341 -0
- package/dist/tools/push.js.map +1 -0
- package/dist/tools/redeploy.d.ts +17 -0
- package/dist/tools/redeploy.js +181 -0
- package/dist/tools/redeploy.js.map +1 -0
- package/dist/tools/status.d.ts +16 -0
- package/dist/tools/status.js +205 -0
- package/dist/tools/status.js.map +1 -0
- package/dist/tools/validate.d.ts +16 -0
- package/dist/tools/validate.js +219 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/tools/webhooks.d.ts +17 -0
- package/dist/tools/webhooks.js +181 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/infra/Pulumi.yaml +6 -0
- package/infra/dist/components/cloud-init.js +412 -0
- package/infra/dist/components/config-generator.js +254 -0
- package/infra/dist/components/hetzner-agent.js +162 -0
- package/infra/dist/components/index.js +18 -0
- package/infra/dist/components/openclaw-agent.js +287 -0
- package/infra/dist/components/shared.js +132 -0
- package/infra/dist/components/types.js +6 -0
- package/infra/dist/index.js +387 -0
- package/infra/dist/shared-vpc.js +167 -0
- package/infra/node_modules/@clawup/core/dist/__tests__/schemas.test.d.ts +2 -0
- package/infra/node_modules/@clawup/core/dist/__tests__/schemas.test.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/__tests__/schemas.test.js +124 -0
- package/infra/node_modules/@clawup/core/dist/__tests__/schemas.test.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/coding-agent-registry.d.ts +32 -0
- package/infra/node_modules/@clawup/core/dist/coding-agent-registry.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/coding-agent-registry.js +56 -0
- package/infra/node_modules/@clawup/core/dist/coding-agent-registry.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/constants.d.ts +137 -0
- package/infra/node_modules/@clawup/core/dist/constants.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/constants.js +314 -0
- package/infra/node_modules/@clawup/core/dist/constants.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/dep-registry.d.ts +25 -0
- package/infra/node_modules/@clawup/core/dist/dep-registry.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/dep-registry.js +46 -0
- package/infra/node_modules/@clawup/core/dist/dep-registry.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/deps.d.ts +18 -0
- package/infra/node_modules/@clawup/core/dist/deps.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/deps.js +39 -0
- package/infra/node_modules/@clawup/core/dist/deps.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/identity.d.ts +20 -0
- package/infra/node_modules/@clawup/core/dist/identity.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/identity.js +217 -0
- package/infra/node_modules/@clawup/core/dist/identity.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/index.d.ts +18 -0
- package/infra/node_modules/@clawup/core/dist/index.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/index.js +52 -0
- package/infra/node_modules/@clawup/core/dist/index.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/plugin-registry.d.ts +13 -0
- package/infra/node_modules/@clawup/core/dist/plugin-registry.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/plugin-registry.js +24 -0
- package/infra/node_modules/@clawup/core/dist/plugin-registry.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/identity.d.ts +74 -0
- package/infra/node_modules/@clawup/core/dist/schemas/identity.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/identity.js +45 -0
- package/infra/node_modules/@clawup/core/dist/schemas/identity.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/index.d.ts +6 -0
- package/infra/node_modules/@clawup/core/dist/schemas/index.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/index.js +13 -0
- package/infra/node_modules/@clawup/core/dist/schemas/index.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/manifest.d.ts +159 -0
- package/infra/node_modules/@clawup/core/dist/schemas/manifest.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/manifest.js +54 -0
- package/infra/node_modules/@clawup/core/dist/schemas/manifest.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/skills.d.ts +30 -0
- package/infra/node_modules/@clawup/core/dist/skills.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/skills.js +52 -0
- package/infra/node_modules/@clawup/core/dist/skills.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/types.d.ts +59 -0
- package/infra/node_modules/@clawup/core/dist/types.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/types.js +30 -0
- package/infra/node_modules/@clawup/core/dist/types.js.map +1 -0
- package/infra/node_modules/@clawup/core/package.json +46 -0
- package/infra/package.json +12 -0
- package/package.json +43 -0
- package/scripts/postinstall.mjs +395 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pulumi CLI wrappers
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.currentStack = currentStack;
|
|
7
|
+
exports.selectOrCreateStack = selectOrCreateStack;
|
|
8
|
+
exports.setConfig = setConfig;
|
|
9
|
+
exports.getConfig = getConfig;
|
|
10
|
+
exports.getStackOutputs = getStackOutputs;
|
|
11
|
+
exports.pulumiUp = pulumiUp;
|
|
12
|
+
exports.pulumiDestroy = pulumiDestroy;
|
|
13
|
+
exports.pulumiPreview = pulumiPreview;
|
|
14
|
+
const exec_1 = require("./exec");
|
|
15
|
+
/**
|
|
16
|
+
* Get the current Pulumi stack name
|
|
17
|
+
*/
|
|
18
|
+
function currentStack(cwd) {
|
|
19
|
+
const result = (0, exec_1.capture)("pulumi", ["stack", "--show-name"], cwd);
|
|
20
|
+
return result.exitCode === 0 ? result.stdout.trim() : null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Select a Pulumi stack (create if it doesn't exist).
|
|
24
|
+
* Returns { ok, error } so callers can display the error message.
|
|
25
|
+
*/
|
|
26
|
+
function selectOrCreateStack(stackName, cwd) {
|
|
27
|
+
const select = (0, exec_1.capture)("pulumi", ["stack", "select", stackName], cwd);
|
|
28
|
+
if (select.exitCode === 0)
|
|
29
|
+
return { ok: true };
|
|
30
|
+
const init = (0, exec_1.capture)("pulumi", ["stack", "init", stackName], cwd);
|
|
31
|
+
if (init.exitCode === 0)
|
|
32
|
+
return { ok: true };
|
|
33
|
+
return { ok: false, error: init.stderr || select.stderr };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Set a Pulumi config value
|
|
37
|
+
*/
|
|
38
|
+
function setConfig(key, value, secret = false, cwd) {
|
|
39
|
+
const args = ["config", "set", key, value];
|
|
40
|
+
if (secret)
|
|
41
|
+
args.push("--secret");
|
|
42
|
+
const result = (0, exec_1.capture)("pulumi", args, cwd);
|
|
43
|
+
return result.exitCode === 0;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a Pulumi config value
|
|
47
|
+
*/
|
|
48
|
+
function getConfig(key, cwd) {
|
|
49
|
+
const result = (0, exec_1.capture)("pulumi", ["config", "get", key], cwd);
|
|
50
|
+
return result.exitCode === 0 ? result.stdout.trim() : null;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get stack outputs as JSON
|
|
54
|
+
*/
|
|
55
|
+
function getStackOutputs(showSecrets = false, cwd) {
|
|
56
|
+
const args = ["stack", "output", "--json"];
|
|
57
|
+
if (showSecrets)
|
|
58
|
+
args.push("--show-secrets");
|
|
59
|
+
const result = (0, exec_1.capture)("pulumi", args, cwd);
|
|
60
|
+
if (result.exitCode !== 0)
|
|
61
|
+
return null;
|
|
62
|
+
try {
|
|
63
|
+
return JSON.parse(result.stdout);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Run pulumi up with streaming output
|
|
71
|
+
*/
|
|
72
|
+
function pulumiUp(cwd) {
|
|
73
|
+
return (0, exec_1.stream)("pulumi", ["up", "--yes"], cwd);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Run pulumi destroy with streaming output
|
|
77
|
+
*/
|
|
78
|
+
function pulumiDestroy(cwd) {
|
|
79
|
+
return (0, exec_1.stream)("pulumi", ["destroy", "--yes"], cwd);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Run pulumi preview with streaming output
|
|
83
|
+
*/
|
|
84
|
+
function pulumiPreview(cwd) {
|
|
85
|
+
return (0, exec_1.stream)("pulumi", ["preview"], cwd);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=pulumi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pulumi.js","sourceRoot":"","sources":["../../lib/pulumi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailscale local daemon detection + API helpers for device management.
|
|
3
|
+
*
|
|
4
|
+
* Detection functions (isTailscaleInstalled, isTailscaleRunning, requireTailscale)
|
|
5
|
+
* check the local Tailscale daemon status for CLI commands that need it.
|
|
6
|
+
*
|
|
7
|
+
* API helpers (listTailscaleDevices, deleteTailscaleDevice) call the Tailscale
|
|
8
|
+
* control-plane API. All API calls retry up to 3 times with exponential backoff
|
|
9
|
+
* and log warnings on failure instead of silently returning null.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Check if the Tailscale CLI is installed.
|
|
13
|
+
* Checks system PATH first, then the macOS App Store location.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isTailscaleInstalled(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Check if the Tailscale daemon is running and connected.
|
|
18
|
+
* Returns true if BackendState is "Running".
|
|
19
|
+
*/
|
|
20
|
+
export declare function isTailscaleRunning(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Require Tailscale to be installed and running.
|
|
23
|
+
* Exits with a clear error message if not.
|
|
24
|
+
*/
|
|
25
|
+
export declare function requireTailscale(): void;
|
|
26
|
+
interface TailscaleDevice {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
hostname: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* List all devices on a tailnet via the Tailscale API.
|
|
33
|
+
* Retries up to 3 times with exponential backoff.
|
|
34
|
+
* Returns null on failure.
|
|
35
|
+
*/
|
|
36
|
+
export declare function listTailscaleDevices(apiKey: string, tailnet: string): TailscaleDevice[] | null;
|
|
37
|
+
/**
|
|
38
|
+
* Remove stale Tailscale devices for a set of agents.
|
|
39
|
+
* Used before deploy/redeploy to prevent duplicate device entries
|
|
40
|
+
* when Pulumi replaces servers (create-before-delete).
|
|
41
|
+
*
|
|
42
|
+
* Returns counts of cleaned, failed, and not-found devices.
|
|
43
|
+
*/
|
|
44
|
+
export declare function cleanupTailscaleDevices(apiKey: string, tailnet: string, stackName: string, agents: {
|
|
45
|
+
name: string;
|
|
46
|
+
}[]): {
|
|
47
|
+
cleaned: string[];
|
|
48
|
+
failed: string[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Delete a single Tailscale device by ID.
|
|
52
|
+
* Retries up to 3 times with exponential backoff.
|
|
53
|
+
* Returns true on success.
|
|
54
|
+
*/
|
|
55
|
+
export declare function deleteTailscaleDevice(apiKey: string, deviceId: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Ensure MagicDNS is enabled on the tailnet.
|
|
58
|
+
* MagicDNS requires at least one nameserver — adds Cloudflare + Google DNS if none set.
|
|
59
|
+
* Returns true if MagicDNS was newly enabled.
|
|
60
|
+
* Warns on failure instead of throwing.
|
|
61
|
+
*/
|
|
62
|
+
export declare function ensureMagicDns(apiKey: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Ensure Tailscale Funnel prerequisites are configured for the tailnet.
|
|
65
|
+
* 1. Enables MagicDNS (required for HTTPS certs)
|
|
66
|
+
* 2. Adds funnel capability to ACL nodeAttrs for all members
|
|
67
|
+
*
|
|
68
|
+
* Returns { magicDns: boolean; funnelAcl: boolean } indicating what was changed.
|
|
69
|
+
* Warns on failure instead of throwing.
|
|
70
|
+
*/
|
|
71
|
+
export declare function ensureTailscaleFunnel(apiKey: string): {
|
|
72
|
+
magicDns: boolean;
|
|
73
|
+
funnelAcl: boolean;
|
|
74
|
+
};
|
|
75
|
+
export {};
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tailscale local daemon detection + API helpers for device management.
|
|
4
|
+
*
|
|
5
|
+
* Detection functions (isTailscaleInstalled, isTailscaleRunning, requireTailscale)
|
|
6
|
+
* check the local Tailscale daemon status for CLI commands that need it.
|
|
7
|
+
*
|
|
8
|
+
* API helpers (listTailscaleDevices, deleteTailscaleDevice) call the Tailscale
|
|
9
|
+
* control-plane API. All API calls retry up to 3 times with exponential backoff
|
|
10
|
+
* and log warnings on failure instead of silently returning null.
|
|
11
|
+
*/
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.isTailscaleInstalled = isTailscaleInstalled;
|
|
17
|
+
exports.isTailscaleRunning = isTailscaleRunning;
|
|
18
|
+
exports.requireTailscale = requireTailscale;
|
|
19
|
+
exports.listTailscaleDevices = listTailscaleDevices;
|
|
20
|
+
exports.cleanupTailscaleDevices = cleanupTailscaleDevices;
|
|
21
|
+
exports.deleteTailscaleDevice = deleteTailscaleDevice;
|
|
22
|
+
exports.ensureMagicDns = ensureMagicDns;
|
|
23
|
+
exports.ensureTailscaleFunnel = ensureTailscaleFunnel;
|
|
24
|
+
const child_process_1 = require("child_process");
|
|
25
|
+
const child_process_2 = require("child_process");
|
|
26
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
27
|
+
/**
|
|
28
|
+
* Check if the Tailscale CLI is installed.
|
|
29
|
+
* Checks system PATH first, then the macOS App Store location.
|
|
30
|
+
*/
|
|
31
|
+
function isTailscaleInstalled() {
|
|
32
|
+
const bin = process.platform === "win32" ? "where" : "which";
|
|
33
|
+
const result = (0, child_process_2.spawnSync)(bin, ["tailscale"], { shell: false, stdio: "ignore" });
|
|
34
|
+
if (result.status === 0)
|
|
35
|
+
return true;
|
|
36
|
+
// macOS App Store installs Tailscale here
|
|
37
|
+
if (process.platform === "darwin") {
|
|
38
|
+
try {
|
|
39
|
+
const fs = require("fs");
|
|
40
|
+
return fs.existsSync("/Applications/Tailscale.app/Contents/MacOS/Tailscale");
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if the Tailscale daemon is running and connected.
|
|
50
|
+
* Returns true if BackendState is "Running".
|
|
51
|
+
*/
|
|
52
|
+
function isTailscaleRunning() {
|
|
53
|
+
try {
|
|
54
|
+
const output = (0, child_process_1.execSync)("tailscale status --json", {
|
|
55
|
+
encoding: "utf-8",
|
|
56
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
57
|
+
timeout: 5000,
|
|
58
|
+
});
|
|
59
|
+
const status = JSON.parse(output);
|
|
60
|
+
return status.BackendState === "Running";
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Require Tailscale to be installed and running.
|
|
68
|
+
* Exits with a clear error message if not.
|
|
69
|
+
*/
|
|
70
|
+
function requireTailscale() {
|
|
71
|
+
if (!isTailscaleInstalled()) {
|
|
72
|
+
const installHint = process.platform === "darwin"
|
|
73
|
+
? "Install from the Mac App Store or https://tailscale.com/download"
|
|
74
|
+
: "Install from https://tailscale.com/download";
|
|
75
|
+
console.error(`\n${picocolors_1.default.red(picocolors_1.default.bold("Error:"))} Tailscale is not installed.\n\n` +
|
|
76
|
+
`This command connects to agents over Tailscale.\n` +
|
|
77
|
+
` ${installHint}\n`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
if (!isTailscaleRunning()) {
|
|
81
|
+
console.error(`\n${picocolors_1.default.red(picocolors_1.default.bold("Error:"))} Tailscale is not connected.\n\n` +
|
|
82
|
+
`This command connects to agents over Tailscale.\n` +
|
|
83
|
+
` Tailscale is not running. Open the Tailscale app or run: ${picocolors_1.default.cyan("tailscale up")}\n`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const MAX_RETRIES = 3;
|
|
88
|
+
const BASE_DELAY_MS = 1000;
|
|
89
|
+
/**
|
|
90
|
+
* Synchronous sleep using Atomics.wait (safe for CLI context).
|
|
91
|
+
*/
|
|
92
|
+
function sleepSync(ms) {
|
|
93
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* List all devices on a tailnet via the Tailscale API.
|
|
97
|
+
* Retries up to 3 times with exponential backoff.
|
|
98
|
+
* Returns null on failure.
|
|
99
|
+
*/
|
|
100
|
+
function listTailscaleDevices(apiKey, tailnet) {
|
|
101
|
+
let lastError;
|
|
102
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
103
|
+
try {
|
|
104
|
+
const result = (0, child_process_1.execSync)(`curl -sf -H "Authorization: Bearer ${apiKey}" "https://api.tailscale.com/api/v2/tailnet/${tailnet}/devices?fields=default"`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 15000 });
|
|
105
|
+
const data = JSON.parse(result);
|
|
106
|
+
if (!data.devices || !Array.isArray(data.devices))
|
|
107
|
+
return null;
|
|
108
|
+
return data.devices.map((d) => ({
|
|
109
|
+
id: d.id,
|
|
110
|
+
name: d.name ?? "",
|
|
111
|
+
hostname: d.hostname ?? "",
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
lastError = err;
|
|
116
|
+
if (attempt < MAX_RETRIES) {
|
|
117
|
+
sleepSync(BASE_DELAY_MS * Math.pow(2, attempt));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
console.warn(`[tailscale] Failed to list devices after ${MAX_RETRIES + 1} attempts: ${lastError instanceof Error ? lastError.message : String(lastError)}`);
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Remove stale Tailscale devices for a set of agents.
|
|
126
|
+
* Used before deploy/redeploy to prevent duplicate device entries
|
|
127
|
+
* when Pulumi replaces servers (create-before-delete).
|
|
128
|
+
*
|
|
129
|
+
* Returns counts of cleaned, failed, and not-found devices.
|
|
130
|
+
*/
|
|
131
|
+
function cleanupTailscaleDevices(apiKey, tailnet, stackName, agents) {
|
|
132
|
+
const cleaned = [];
|
|
133
|
+
const failed = [];
|
|
134
|
+
const devices = listTailscaleDevices(apiKey, tailnet);
|
|
135
|
+
if (!devices)
|
|
136
|
+
return { cleaned, failed };
|
|
137
|
+
for (const agent of agents) {
|
|
138
|
+
const tsHost = `${stackName}-${agent.name}`;
|
|
139
|
+
const matching = devices.filter((d) => d.hostname === tsHost || d.name.startsWith(`${tsHost}.`));
|
|
140
|
+
for (const device of matching) {
|
|
141
|
+
const deleted = deleteTailscaleDevice(apiKey, device.id);
|
|
142
|
+
if (deleted) {
|
|
143
|
+
cleaned.push(`${agent.name} (${device.hostname})`);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
failed.push(agent.name);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return { cleaned, failed };
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Delete a single Tailscale device by ID.
|
|
154
|
+
* Retries up to 3 times with exponential backoff.
|
|
155
|
+
* Returns true on success.
|
|
156
|
+
*/
|
|
157
|
+
function deleteTailscaleDevice(apiKey, deviceId) {
|
|
158
|
+
let lastError;
|
|
159
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
160
|
+
try {
|
|
161
|
+
(0, child_process_1.execSync)(`curl -sf -X DELETE -H "Authorization: Bearer ${apiKey}" "https://api.tailscale.com/api/v2/device/${deviceId}"`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 15000 });
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
lastError = err;
|
|
166
|
+
if (attempt < MAX_RETRIES) {
|
|
167
|
+
sleepSync(BASE_DELAY_MS * Math.pow(2, attempt));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
console.warn(`[tailscale] Failed to delete device ${deviceId} after ${MAX_RETRIES + 1} attempts: ${lastError instanceof Error ? lastError.message : String(lastError)}`);
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Ensure MagicDNS is enabled on the tailnet.
|
|
176
|
+
* MagicDNS requires at least one nameserver — adds Cloudflare + Google DNS if none set.
|
|
177
|
+
* Returns true if MagicDNS was newly enabled.
|
|
178
|
+
* Warns on failure instead of throwing.
|
|
179
|
+
*/
|
|
180
|
+
function ensureMagicDns(apiKey) {
|
|
181
|
+
try {
|
|
182
|
+
const dnsResp = tsApiGet(apiKey, "/tailnet/-/dns/preferences");
|
|
183
|
+
const dns = JSON.parse(dnsResp);
|
|
184
|
+
if (dns.magicDNS)
|
|
185
|
+
return false; // already enabled
|
|
186
|
+
// MagicDNS requires at least one nameserver
|
|
187
|
+
const nsResp = tsApiGet(apiKey, "/tailnet/-/dns/nameservers");
|
|
188
|
+
const ns = JSON.parse(nsResp);
|
|
189
|
+
if (!ns.dns || ns.dns.length === 0) {
|
|
190
|
+
tsApiPost(apiKey, "/tailnet/-/dns/nameservers", { dns: ["1.1.1.1", "8.8.8.8"] });
|
|
191
|
+
}
|
|
192
|
+
tsApiPost(apiKey, "/tailnet/-/dns/preferences", { magicDNS: true });
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
console.warn(`[tailscale] Could not check/enable MagicDNS: ${err instanceof Error ? err.message : String(err)}`);
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Ensure Tailscale Funnel prerequisites are configured for the tailnet.
|
|
202
|
+
* 1. Enables MagicDNS (required for HTTPS certs)
|
|
203
|
+
* 2. Adds funnel capability to ACL nodeAttrs for all members
|
|
204
|
+
*
|
|
205
|
+
* Returns { magicDns: boolean; funnelAcl: boolean } indicating what was changed.
|
|
206
|
+
* Warns on failure instead of throwing.
|
|
207
|
+
*/
|
|
208
|
+
function ensureTailscaleFunnel(apiKey) {
|
|
209
|
+
const result = { magicDns: false, funnelAcl: false };
|
|
210
|
+
// 1. Ensure MagicDNS is enabled
|
|
211
|
+
result.magicDns = ensureMagicDns(apiKey);
|
|
212
|
+
// 2. Ensure Funnel is allowed in ACL
|
|
213
|
+
try {
|
|
214
|
+
const aclResp = tsApiGet(apiKey, "/tailnet/-/acl");
|
|
215
|
+
const acl = JSON.parse(aclResp);
|
|
216
|
+
const nodeAttrs = acl.nodeAttrs ?? [];
|
|
217
|
+
const hasFunnel = nodeAttrs.some((a) => Array.isArray(a.attr) && a.attr.includes("funnel"));
|
|
218
|
+
if (!hasFunnel) {
|
|
219
|
+
nodeAttrs.push({ target: ["autogroup:member"], attr: ["funnel"] });
|
|
220
|
+
acl.nodeAttrs = nodeAttrs;
|
|
221
|
+
tsApiPost(apiKey, "/tailnet/-/acl", acl);
|
|
222
|
+
result.funnelAcl = true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
console.warn(`[tailscale] Could not check/enable Funnel ACL: ${err instanceof Error ? err.message : String(err)}`);
|
|
227
|
+
}
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
/** GET a Tailscale API endpoint. Returns response body as string. */
|
|
231
|
+
function tsApiGet(apiKey, path) {
|
|
232
|
+
return (0, child_process_1.execSync)(`curl -sf -H "Authorization: Bearer ${apiKey}" -H "Accept: application/json" "https://api.tailscale.com/api/v2${path}"`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 15000 });
|
|
233
|
+
}
|
|
234
|
+
/** POST JSON to a Tailscale API endpoint. Uses a temp file for the payload. */
|
|
235
|
+
function tsApiPost(apiKey, path, body) {
|
|
236
|
+
const fs = require("fs");
|
|
237
|
+
const os = require("os");
|
|
238
|
+
const nodePath = require("path");
|
|
239
|
+
const tmpFile = nodePath.join(os.tmpdir(), `ts-api-${Date.now()}.json`);
|
|
240
|
+
try {
|
|
241
|
+
fs.writeFileSync(tmpFile, JSON.stringify(body));
|
|
242
|
+
return (0, child_process_1.execSync)(`curl -sf -X POST -H "Authorization: Bearer ${apiKey}" -H "Content-Type: application/json" -d @${tmpFile} "https://api.tailscale.com/api/v2${path}"`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 15000 });
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
try {
|
|
246
|
+
fs.unlinkSync(tmpFile);
|
|
247
|
+
}
|
|
248
|
+
catch { /* ignore */ }
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=tailscale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tailscale.js","sourceRoot":"","sources":["../../lib/tailscale.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for tool implementations (adapter-aware).
|
|
3
|
+
*
|
|
4
|
+
* These mirror the functions in pulumi.ts but accept an ExecAdapter
|
|
5
|
+
* instead of using the global capture() directly.
|
|
6
|
+
*/
|
|
7
|
+
import type { ExecAdapter } from "../adapters";
|
|
8
|
+
/**
|
|
9
|
+
* Get a Pulumi config value via ExecAdapter.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getConfig(exec: ExecAdapter, key: string, cwd?: string): string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Get stack outputs as JSON via ExecAdapter.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getStackOutputs(exec: ExecAdapter, showSecrets?: boolean, cwd?: string): Record<string, unknown> | null;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared helpers for tool implementations (adapter-aware).
|
|
4
|
+
*
|
|
5
|
+
* These mirror the functions in pulumi.ts but accept an ExecAdapter
|
|
6
|
+
* instead of using the global capture() directly.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.getConfig = getConfig;
|
|
10
|
+
exports.getStackOutputs = getStackOutputs;
|
|
11
|
+
/**
|
|
12
|
+
* Get a Pulumi config value via ExecAdapter.
|
|
13
|
+
*/
|
|
14
|
+
function getConfig(exec, key, cwd) {
|
|
15
|
+
const result = exec.capture("pulumi", ["config", "get", key], cwd);
|
|
16
|
+
return result.exitCode === 0 ? result.stdout.trim() : null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get stack outputs as JSON via ExecAdapter.
|
|
20
|
+
*/
|
|
21
|
+
function getStackOutputs(exec, showSecrets = false, cwd) {
|
|
22
|
+
const args = ["stack", "output", "--json"];
|
|
23
|
+
if (showSecrets)
|
|
24
|
+
args.push("--show-secrets");
|
|
25
|
+
const result = exec.capture("pulumi", args, cwd);
|
|
26
|
+
if (result.exitCode !== 0)
|
|
27
|
+
return null;
|
|
28
|
+
try {
|
|
29
|
+
return JSON.parse(result.stdout);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=tool-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-helpers.js","sourceRoot":"","sources":["../../lib/tool-helpers.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAOH,8BAGC;AAKD,0CAUC;AArBD;;GAEG;AACH,SAAgB,SAAS,CAAC,IAAiB,EAAE,GAAW,EAAE,GAAY;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,IAAiB,EAAE,cAAuB,KAAK,EAAE,GAAY;IAC3F,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3C,IAAI,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/lib/ui.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared UI helpers using @clack/prompts
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Display the Agent Army banner
|
|
6
|
+
*/
|
|
7
|
+
export declare function showBanner(): void;
|
|
8
|
+
/**
|
|
9
|
+
* Handle user cancellation (Ctrl+C)
|
|
10
|
+
*/
|
|
11
|
+
export declare function handleCancel(value: unknown): void;
|
|
12
|
+
/**
|
|
13
|
+
* Show an error and exit
|
|
14
|
+
*/
|
|
15
|
+
export declare function exitWithError(message: string): never;
|
|
16
|
+
/**
|
|
17
|
+
* Format a cost estimate string
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatCost(monthlyCost: number): string;
|
|
20
|
+
/**
|
|
21
|
+
* Format agent list for display
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatAgentList(agents: {
|
|
24
|
+
displayName: string;
|
|
25
|
+
role: string;
|
|
26
|
+
}[]): string;
|
package/dist/lib/ui.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared UI helpers using @clack/prompts
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.showBanner = showBanner;
|
|
43
|
+
exports.handleCancel = handleCancel;
|
|
44
|
+
exports.exitWithError = exitWithError;
|
|
45
|
+
exports.formatCost = formatCost;
|
|
46
|
+
exports.formatAgentList = formatAgentList;
|
|
47
|
+
const p = __importStar(require("@clack/prompts"));
|
|
48
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
49
|
+
/**
|
|
50
|
+
* Display the Agent Army banner
|
|
51
|
+
*/
|
|
52
|
+
function showBanner() {
|
|
53
|
+
console.log();
|
|
54
|
+
p.intro(picocolors_1.default.bgCyan(picocolors_1.default.black(" Agent Army ")));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Handle user cancellation (Ctrl+C)
|
|
58
|
+
*/
|
|
59
|
+
function handleCancel(value) {
|
|
60
|
+
if (p.isCancel(value)) {
|
|
61
|
+
p.cancel("Operation cancelled.");
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Show an error and exit
|
|
67
|
+
*/
|
|
68
|
+
function exitWithError(message) {
|
|
69
|
+
p.log.error(message);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Format a cost estimate string
|
|
74
|
+
*/
|
|
75
|
+
function formatCost(monthlyCost) {
|
|
76
|
+
return `~$${monthlyCost}/mo`;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Format agent list for display
|
|
80
|
+
*/
|
|
81
|
+
function formatAgentList(agents) {
|
|
82
|
+
return agents
|
|
83
|
+
.map((a) => ` ${picocolors_1.default.bold(a.displayName)} (${a.role})`)
|
|
84
|
+
.join("\n");
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../lib/ui.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQH,gCAGC;AAKD,oCAKC;AAKD,sCAGC;AAKD,gCAEC;AAKD,0CAIC;AA3CD,kDAAoC;AACpC,4DAA4B;AAE5B;;GAEG;AACH,SAAgB,UAAU;IACxB,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,CAAC,CAAC,KAAK,CAAC,oBAAE,CAAC,MAAM,CAAC,oBAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,OAAe;IAC3C,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,WAAmB;IAC5C,OAAO,KAAK,WAAW,KAAK,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,MAA+C;IAC7E,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,oBAAE,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;SACrD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background update notifier — checks npm for newer versions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check for updates and print a notice if a newer version is available.
|
|
6
|
+
* Non-blocking — errors are silently ignored.
|
|
7
|
+
*/
|
|
8
|
+
export declare function checkForUpdates(currentVersion: string): Promise<void>;
|