harnery 0.41.0 → 0.43.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/dist/commander.d.ts +16 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +21 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +63 -5
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +113 -12
- package/dist/commands/browse.d.ts +164 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +263 -51
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +52 -0
- package/dist/commands/disk.d.ts +6 -0
- package/dist/commands/disk.d.ts.map +1 -0
- package/dist/commands/disk.js +80 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +48 -1
- package/dist/commands/files.d.ts +16 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -2
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +43 -9
- package/dist/commands/rm.d.ts +4 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +87 -0
- package/dist/commands/servers.d.ts +7 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/commands/servers.js +394 -0
- package/dist/commands/tunnel.d.ts +65 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +372 -103
- package/dist/commands/web-fetch.d.ts +3 -2
- package/dist/commands/web-fetch.d.ts.map +1 -1
- package/dist/commands/web-fetch.js +25 -19
- package/dist/commands/web.d.ts +7 -1
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +9 -3
- package/dist/core/adapters/profiles.d.ts +9 -0
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +22 -1
- package/dist/core/adapters/types.d.ts +9 -0
- package/dist/core/adapters/types.d.ts.map +1 -1
- package/dist/core/agents/cli.js +13 -6
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +11 -5
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +59 -13
- package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +60 -0
- package/dist/core/agents/state/names.d.ts +43 -3
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +87 -3
- package/dist/core/artifacts/delivery-card.js +9 -2
- package/dist/core/artifacts/index.d.ts +140 -4
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +522 -49
- package/dist/core/config.d.ts +68 -11
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +128 -3
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +2 -2
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +16 -0
- package/dist/core/events/v3/projection.js +9 -1
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-reader.js +42 -16
- package/dist/core/hooks/adapter/events.d.ts +17 -0
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +5 -0
- package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
- package/dist/core/hooks/adapter/wiring.d.ts +37 -7
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +62 -4
- package/dist/core/hooks/cli.js +131 -23
- package/dist/core/hooks/fork-lineage.d.ts +40 -0
- package/dist/core/hooks/fork-lineage.d.ts.map +1 -0
- package/dist/core/hooks/fork-lineage.js +62 -0
- package/dist/core/hooks/resolve/transcript.d.ts +16 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +84 -0
- package/dist/core/hooks/run-markers.d.ts +37 -0
- package/dist/core/hooks/run-markers.d.ts.map +1 -0
- package/dist/core/hooks/run-markers.js +109 -0
- package/dist/core/hooks/shell-rm.d.ts +2 -0
- package/dist/core/hooks/shell-rm.d.ts.map +1 -0
- package/dist/core/hooks/shell-rm.js +105 -0
- package/dist/core/hooks/shell-tokens.d.ts +12 -0
- package/dist/core/hooks/shell-tokens.d.ts.map +1 -0
- package/dist/core/hooks/shell-tokens.js +97 -0
- package/dist/core/hooks/shell-waiter.d.ts.map +1 -1
- package/dist/core/hooks/shell-waiter.js +3 -93
- package/dist/core/semantic/contract.d.ts +5 -5
- package/dist/core/servers/index.d.ts +211 -0
- package/dist/core/servers/index.d.ts.map +1 -0
- package/dist/core/servers/index.js +560 -0
- package/dist/core/servers/net.d.ts +58 -0
- package/dist/core/servers/net.d.ts.map +1 -0
- package/dist/core/servers/net.js +270 -0
- package/dist/core/servers/tunnels.d.ts +14 -0
- package/dist/core/servers/tunnels.d.ts.map +1 -0
- package/dist/core/servers/tunnels.js +33 -0
- package/dist/core/storage/builtins.js +1 -0
- package/dist/core/storage/process-log.d.ts +12 -0
- package/dist/core/storage/process-log.d.ts.map +1 -1
- package/dist/core/storage/process-log.js +10 -2
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +30 -1
- package/dist/core/workflow/sandbox-projection.d.ts +13 -2
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +23 -0
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +6 -1
- package/dist/core/workflow/spawn-codex.d.ts +2 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +20 -1
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +6 -1
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -1
- package/dist/core/workflow/spawn-opencode.js +4 -1
- package/dist/core/workflow/types.d.ts +47 -2
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/worker-access.d.ts +92 -0
- package/dist/core/workflow/worker-access.d.ts.map +1 -0
- package/dist/core/workflow/worker-access.js +450 -0
- package/dist/lib/browser/batch-steps.d.ts +18 -0
- package/dist/lib/browser/batch-steps.d.ts.map +1 -0
- package/dist/lib/browser/batch-steps.js +82 -0
- package/dist/lib/browser/collect/collector.d.ts +99 -0
- package/dist/lib/browser/collect/collector.d.ts.map +1 -0
- package/dist/lib/browser/collect/collector.js +202 -0
- package/dist/lib/browser/collect/fields.d.ts +31 -0
- package/dist/lib/browser/collect/fields.d.ts.map +1 -0
- package/dist/lib/browser/collect/fields.js +75 -0
- package/dist/lib/browser/collect/index.d.ts +6 -0
- package/dist/lib/browser/collect/index.d.ts.map +1 -0
- package/dist/lib/browser/collect/index.js +5 -0
- package/dist/lib/browser/collect/page-driver.d.ts +14 -0
- package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
- package/dist/lib/browser/collect/page-driver.js +306 -0
- package/dist/lib/browser/collect/presets.d.ts +52 -0
- package/dist/lib/browser/collect/presets.d.ts.map +1 -0
- package/dist/lib/browser/collect/presets.js +176 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
- package/dist/lib/browser/collect/scroll-plan.js +118 -0
- package/dist/lib/browser/index.d.ts +1 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.d.ts +2 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +13 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +1 -0
- package/dist/lib/browser/windows-chrome.d.ts +59 -0
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
- package/dist/lib/browser/windows-chrome.js +179 -0
- package/dist/lib/claude-desktop-share.d.ts +136 -0
- package/dist/lib/claude-desktop-share.d.ts.map +1 -0
- package/dist/lib/claude-desktop-share.js +394 -0
- package/dist/lib/disk-usage.d.ts +50 -0
- package/dist/lib/disk-usage.d.ts.map +1 -0
- package/dist/lib/disk-usage.js +303 -0
- package/dist/lib/docs-lint.d.ts +6 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +8 -3
- package/dist/lib/guarded-remove.d.ts +34 -0
- package/dist/lib/guarded-remove.d.ts.map +1 -0
- package/dist/lib/guarded-remove.js +310 -0
- package/dist/lib/instructions/templates.js +8 -8
- package/dist/lib/tunnel/allowlist.d.ts +44 -0
- package/dist/lib/tunnel/allowlist.d.ts.map +1 -0
- package/dist/lib/tunnel/allowlist.js +204 -0
- package/dist/lib/tunnel/current-address.d.ts +41 -0
- package/dist/lib/tunnel/current-address.d.ts.map +1 -0
- package/dist/lib/tunnel/current-address.js +123 -0
- package/dist/lib/tunnel/error-page.d.ts +1 -1
- package/dist/lib/tunnel/error-page.d.ts.map +1 -1
- package/dist/lib/tunnel/error-page.js +19 -8
- package/dist/lib/tunnel/gate.js +33 -7
- package/dist/lib/tunnel/path-scope.d.ts +22 -0
- package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
- package/dist/lib/tunnel/path-scope.js +62 -0
- package/dist/lib/tunnel/processes.d.ts +39 -0
- package/dist/lib/tunnel/processes.d.ts.map +1 -0
- package/dist/lib/tunnel/processes.js +121 -0
- package/dist/lib/tunnel/state.d.ts +33 -3
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +115 -30
- package/package.json +7 -1
- package/schemas/config.schema.json +91 -0
- package/src/commander.ts +51 -0
- package/src/commands/agents.ts +111 -11
- package/src/commands/artifacts.ts +171 -19
- package/src/commands/browse.ts +400 -57
- package/src/commands/claude-desktop.ts +61 -0
- package/src/commands/disk.ts +114 -0
- package/src/commands/doctor.ts +52 -1
- package/src/commands/files.ts +93 -2
- package/src/commands/init.ts +55 -5
- package/src/commands/rm.ts +115 -0
- package/src/commands/servers.ts +506 -0
- package/src/commands/tunnel.ts +494 -116
- package/src/commands/web-fetch.ts +30 -19
- package/src/commands/web.ts +9 -3
- package/src/core/adapters/profiles.ts +22 -1
- package/src/core/adapters/types.ts +10 -0
- package/src/core/agents/cli.ts +14 -6
- package/src/core/agents/render/prompt-context.ts +25 -8
- package/src/core/agents/render/session-context.ts +84 -16
- package/src/core/agents/state/live-coordination-view.ts +73 -0
- package/src/core/agents/state/names.ts +117 -6
- package/src/core/artifacts/delivery-card.ts +10 -2
- package/src/core/artifacts/index.ts +697 -44
- package/src/core/config.ts +183 -4
- package/src/core/diagnostics/bundle.ts +2 -1
- package/src/core/events/v3/producers/recorder.ts +16 -0
- package/src/core/events/v3/projection.ts +11 -1
- package/src/core/events/v3/support-storage/pack-reader.ts +45 -19
- package/src/core/hooks/adapter/events.ts +19 -0
- package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
- package/src/core/hooks/adapter/wiring.ts +116 -8
- package/src/core/hooks/cli.ts +152 -22
- package/src/core/hooks/fork-lineage.ts +82 -0
- package/src/core/hooks/resolve/transcript.ts +88 -0
- package/src/core/hooks/run-markers.ts +132 -0
- package/src/core/hooks/shell-rm.ts +103 -0
- package/src/core/hooks/shell-tokens.ts +96 -0
- package/src/core/hooks/shell-waiter.ts +4 -91
- package/src/core/servers/index.ts +712 -0
- package/src/core/servers/net.ts +283 -0
- package/src/core/servers/tunnels.ts +39 -0
- package/src/core/storage/builtins.ts +1 -0
- package/src/core/storage/process-log.ts +17 -2
- package/src/core/workflow/engine.ts +38 -1
- package/src/core/workflow/sandbox-projection.ts +38 -2
- package/src/core/workflow/spawn-claude.ts +5 -1
- package/src/core/workflow/spawn-codex.ts +18 -1
- package/src/core/workflow/spawn-cursor.ts +5 -1
- package/src/core/workflow/spawn-opencode.ts +4 -1
- package/src/core/workflow/types.ts +62 -2
- package/src/core/workflow/worker-access.ts +525 -0
- package/src/lib/browser/batch-steps.ts +79 -0
- package/src/lib/browser/collect/collector.ts +306 -0
- package/src/lib/browser/collect/fields.ts +87 -0
- package/src/lib/browser/collect/index.ts +47 -0
- package/src/lib/browser/collect/page-driver.ts +327 -0
- package/src/lib/browser/collect/presets.ts +237 -0
- package/src/lib/browser/collect/scroll-plan.ts +179 -0
- package/src/lib/browser/index.ts +1 -0
- package/src/lib/browser/page-review-judge.ts +16 -0
- package/src/lib/browser/qa-run-contracts.ts +11 -0
- package/src/lib/browser/qa-run.ts +1 -0
- package/src/lib/browser/windows-chrome.ts +227 -0
- package/src/lib/claude-desktop-share.ts +511 -0
- package/src/lib/disk-usage.ts +347 -0
- package/src/lib/docs-lint.ts +8 -3
- package/src/lib/guarded-remove.ts +376 -0
- package/src/lib/instructions/templates.ts +8 -8
- package/src/lib/tunnel/allowlist.ts +208 -0
- package/src/lib/tunnel/current-address.ts +158 -0
- package/src/lib/tunnel/error-page.ts +25 -9
- package/src/lib/tunnel/gate.ts +38 -9
- package/src/lib/tunnel/path-scope.ts +73 -0
- package/src/lib/tunnel/processes.ts +149 -0
- package/src/lib/tunnel/state.ts +143 -30
package/src/lib/tunnel/state.ts
CHANGED
|
@@ -1,21 +1,43 @@
|
|
|
1
1
|
// Tunnel config + state persistence + provider helpers. Commands default to
|
|
2
2
|
// <cwd>/.cache/tunnel/; gitignored, so the allowlist is per-machine.
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
5
|
import {
|
|
6
|
+
accessSync,
|
|
7
|
+
chmodSync,
|
|
8
|
+
constants,
|
|
6
9
|
existsSync,
|
|
7
10
|
mkdirSync,
|
|
8
11
|
readdirSync,
|
|
9
12
|
readFileSync,
|
|
13
|
+
statSync,
|
|
10
14
|
unlinkSync,
|
|
11
15
|
writeFileSync,
|
|
12
16
|
} from "node:fs";
|
|
13
|
-
import {
|
|
17
|
+
import { homedir } from "node:os";
|
|
18
|
+
import { delimiter, join, resolve } from "node:path";
|
|
19
|
+
import { isPathAllowed } from "./path-scope.ts";
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
/** Overrides the directory that holds tunnel state and config (a host keeps it out of `.cache/`). */
|
|
22
|
+
export const TUNNEL_DIR_ENV = "HARNERY_TUNNEL_DIR";
|
|
23
|
+
/** Explicit cloudflared binary, for a host that ships a managed copy. */
|
|
24
|
+
export const CLOUDFLARED_ENV = "HARNERY_CLOUDFLARED";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Where tunnel state lives: `$HARNERY_TUNNEL_DIR` when set, else
|
|
28
|
+
* `<root>/.cache/tunnel/`. Root defaults to cwd for the command surface and can
|
|
29
|
+
* be supplied by callers that already resolved a repo.
|
|
30
|
+
*/
|
|
31
|
+
export function tunnelDir(
|
|
32
|
+
root: string = process.cwd(),
|
|
33
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
34
|
+
): string {
|
|
35
|
+
const override = env[TUNNEL_DIR_ENV]?.trim();
|
|
36
|
+
return override ? resolve(override) : resolve(root, ".cache", "tunnel");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function cachePath(filename: string, root: string = process.cwd()): string {
|
|
40
|
+
const dir = tunnelDir(root);
|
|
19
41
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
20
42
|
return resolve(dir, filename);
|
|
21
43
|
}
|
|
@@ -62,7 +84,16 @@ const DEFAULT_CONFIG: TunnelConfig = {
|
|
|
62
84
|
};
|
|
63
85
|
|
|
64
86
|
export interface TunnelConfig {
|
|
87
|
+
/** Exact addresses and CIDR ranges the gate admits (Cloudflare provider). */
|
|
65
88
|
allowed_ips: string[];
|
|
89
|
+
/**
|
|
90
|
+
* Entries `allow add --current` added for this machine's own public
|
|
91
|
+
* addresses. They are a subset of `allowed_ips`; the next refresh replaces
|
|
92
|
+
* exactly these and never touches an entry added by hand.
|
|
93
|
+
*/
|
|
94
|
+
auto_allowed?: string[];
|
|
95
|
+
/** Explicit cloudflared binary; `$HARNERY_CLOUDFLARED` wins over this. */
|
|
96
|
+
cloudflared_path?: string;
|
|
66
97
|
}
|
|
67
98
|
|
|
68
99
|
export type TunnelProvider = "cloudflare" | "tailscale";
|
|
@@ -81,38 +112,53 @@ export interface TunnelState {
|
|
|
81
112
|
target: string;
|
|
82
113
|
vhost: string;
|
|
83
114
|
gate_port: number;
|
|
115
|
+
/** URL path prefixes the gate forwards; every other path is refused. */
|
|
116
|
+
allow_paths: string[];
|
|
84
117
|
tailscale_mode?: TailscaleMode;
|
|
85
118
|
tailscale_path?: string;
|
|
86
119
|
tailscale_https_port?: number;
|
|
87
120
|
}
|
|
88
121
|
|
|
89
|
-
/**
|
|
122
|
+
/**
|
|
123
|
+
* Normalize a parsed state blob; supply `name` for pre-multi-instance files.
|
|
124
|
+
* A state written before path scopes existed reads as an empty scope, which
|
|
125
|
+
* the gate treats as "refuse every path".
|
|
126
|
+
*/
|
|
90
127
|
function normalizeState(raw: TunnelState, fallbackName: string): TunnelState {
|
|
91
|
-
return {
|
|
128
|
+
return {
|
|
129
|
+
...raw,
|
|
130
|
+
name: raw.name ?? fallbackName,
|
|
131
|
+
provider: raw.provider ?? "cloudflare",
|
|
132
|
+
allow_paths: Array.isArray(raw.allow_paths) ? raw.allow_paths : [],
|
|
133
|
+
};
|
|
92
134
|
}
|
|
93
135
|
|
|
94
136
|
export function readConfig(): TunnelConfig {
|
|
95
|
-
const p = cachePath(
|
|
137
|
+
const p = cachePath(CONFIG_FILE);
|
|
96
138
|
if (!existsSync(p)) {
|
|
97
139
|
writeConfig(DEFAULT_CONFIG);
|
|
98
140
|
return { ...DEFAULT_CONFIG, allowed_ips: [...DEFAULT_CONFIG.allowed_ips] };
|
|
99
141
|
}
|
|
100
142
|
try {
|
|
101
|
-
|
|
143
|
+
const parsed = JSON.parse(readFileSync(p, "utf-8")) as Partial<TunnelConfig>;
|
|
144
|
+
return {
|
|
145
|
+
...parsed,
|
|
146
|
+
allowed_ips: Array.isArray(parsed.allowed_ips) ? parsed.allowed_ips : [],
|
|
147
|
+
};
|
|
102
148
|
} catch {
|
|
103
149
|
return { ...DEFAULT_CONFIG, allowed_ips: [...DEFAULT_CONFIG.allowed_ips] };
|
|
104
150
|
}
|
|
105
151
|
}
|
|
106
152
|
|
|
107
153
|
export function writeConfig(cfg: TunnelConfig): void {
|
|
108
|
-
writeFileSync(cachePath(
|
|
154
|
+
writeFileSync(cachePath(CONFIG_FILE), JSON.stringify(cfg, null, 2));
|
|
109
155
|
}
|
|
110
156
|
|
|
111
157
|
export function readState(
|
|
112
158
|
name: string = DEFAULT_INSTANCE,
|
|
113
159
|
root: string = process.cwd(),
|
|
114
160
|
): TunnelState | null {
|
|
115
|
-
const p = cachePath(
|
|
161
|
+
const p = cachePath(stateFile(name), root);
|
|
116
162
|
if (!existsSync(p)) return null;
|
|
117
163
|
try {
|
|
118
164
|
return normalizeState(JSON.parse(readFileSync(p, "utf-8")) as TunnelState, name);
|
|
@@ -122,11 +168,11 @@ export function readState(
|
|
|
122
168
|
}
|
|
123
169
|
|
|
124
170
|
export function writeState(state: TunnelState, root: string = process.cwd()): void {
|
|
125
|
-
writeFileSync(cachePath(
|
|
171
|
+
writeFileSync(cachePath(stateFile(state.name), root), JSON.stringify(state, null, 2));
|
|
126
172
|
}
|
|
127
173
|
|
|
128
174
|
export function clearState(name: string = DEFAULT_INSTANCE, root: string = process.cwd()): void {
|
|
129
|
-
const p = cachePath(
|
|
175
|
+
const p = cachePath(stateFile(name), root);
|
|
130
176
|
if (existsSync(p)) unlinkSync(p);
|
|
131
177
|
}
|
|
132
178
|
|
|
@@ -135,7 +181,7 @@ export function clearState(name: string = DEFAULT_INSTANCE, root: string = proce
|
|
|
135
181
|
* `state*.json` under `.cache/tunnel/`; tolerates missing/corrupt files.
|
|
136
182
|
*/
|
|
137
183
|
export function listStates(root: string = process.cwd()): TunnelState[] {
|
|
138
|
-
const dir =
|
|
184
|
+
const dir = tunnelDir(root);
|
|
139
185
|
if (!existsSync(dir)) return [];
|
|
140
186
|
const out: TunnelState[] = [];
|
|
141
187
|
for (const file of readdirSync(dir)) {
|
|
@@ -169,7 +215,7 @@ export function isTunnelStateLive(
|
|
|
169
215
|
return typeof providerPid === "number" && processAlive(providerPid);
|
|
170
216
|
}
|
|
171
217
|
|
|
172
|
-
function tunnelTargetPort(state: TunnelState): number | null {
|
|
218
|
+
export function tunnelTargetPort(state: TunnelState): number | null {
|
|
173
219
|
const value = /^[a-z][a-z\d+.-]*:\/\//i.test(state.target)
|
|
174
220
|
? state.target
|
|
175
221
|
: `http://${state.target}`;
|
|
@@ -209,31 +255,98 @@ export function findLiveTunnelForOrigin(
|
|
|
209
255
|
);
|
|
210
256
|
}
|
|
211
257
|
|
|
212
|
-
/**
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
258
|
+
/** True when the tunnel's path scope forwards every one of `paths`. */
|
|
259
|
+
export function tunnelServesPaths(state: TunnelState, paths: readonly string[]): boolean {
|
|
260
|
+
return paths.every((path) => isPathAllowed(path, state.allow_paths));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function isRunnableFile(path: string): boolean {
|
|
217
264
|
try {
|
|
218
|
-
|
|
219
|
-
|
|
265
|
+
if (!statSync(path).isFile()) return false;
|
|
266
|
+
if (process.platform === "win32") return true;
|
|
267
|
+
accessSync(path, constants.X_OK);
|
|
268
|
+
return true;
|
|
220
269
|
} catch {
|
|
221
|
-
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** First `name` on PATH (honoring `.exe` on Windows), or null. Needs no shell. */
|
|
275
|
+
function findOnPath(name: string, env: NodeJS.ProcessEnv = process.env): string | null {
|
|
276
|
+
const names = process.platform === "win32" ? [`${name}.exe`, name] : [name];
|
|
277
|
+
for (const dir of (env.PATH ?? env.Path ?? "").split(delimiter)) {
|
|
278
|
+
if (!dir) continue;
|
|
279
|
+
for (const candidate of names) {
|
|
280
|
+
const full = join(dir, candidate);
|
|
281
|
+
if (isRunnableFile(full)) return full;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Resolve the cloudflared binary:
|
|
289
|
+
* 1. `$HARNERY_CLOUDFLARED`, then `cloudflared_path` in the tunnel config: an
|
|
290
|
+
* explicit choice, so a missing or non-runnable file is an error, never a
|
|
291
|
+
* silent fall-through to some other copy.
|
|
292
|
+
* 2. `cloudflared` on PATH.
|
|
293
|
+
* 3. `~/.local/bin/cloudflared`.
|
|
294
|
+
* 4. Linux x86-64 and arm64: download the latest release to (3).
|
|
295
|
+
* Elsewhere it throws with install guidance.
|
|
296
|
+
*/
|
|
297
|
+
export function ensureCloudflared(
|
|
298
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
299
|
+
configuredPath: string | undefined = readConfig().cloudflared_path,
|
|
300
|
+
): string {
|
|
301
|
+
const explicit = env[CLOUDFLARED_ENV]?.trim();
|
|
302
|
+
const fromConfig = configuredPath?.trim();
|
|
303
|
+
for (const [source, path] of [
|
|
304
|
+
[CLOUDFLARED_ENV, explicit],
|
|
305
|
+
["cloudflared_path in the tunnel config", fromConfig],
|
|
306
|
+
] as const) {
|
|
307
|
+
if (!path) continue;
|
|
308
|
+
if (isRunnableFile(path)) return path;
|
|
309
|
+
throw new Error(
|
|
310
|
+
`cloudflared is set by ${source} to ${path}, but that file is missing or not runnable.`,
|
|
311
|
+
);
|
|
222
312
|
}
|
|
223
|
-
const local = `${process.env.HOME}/.local/bin/cloudflared`;
|
|
224
|
-
if (existsSync(local)) return local;
|
|
225
313
|
|
|
226
|
-
|
|
314
|
+
const onPath = findOnPath("cloudflared", env);
|
|
315
|
+
if (onPath) return onPath;
|
|
316
|
+
const exe = process.platform === "win32" ? "cloudflared.exe" : "cloudflared";
|
|
317
|
+
const local = join(homedir(), ".local", "bin", exe);
|
|
318
|
+
if (isRunnableFile(local)) return local;
|
|
319
|
+
|
|
320
|
+
const asset =
|
|
321
|
+
process.platform === "linux"
|
|
322
|
+
? (
|
|
323
|
+
{ x64: "cloudflared-linux-amd64", arm64: "cloudflared-linux-arm64" } as Record<
|
|
324
|
+
string,
|
|
325
|
+
string
|
|
326
|
+
>
|
|
327
|
+
)[process.arch]
|
|
328
|
+
: undefined;
|
|
329
|
+
if (!asset) {
|
|
227
330
|
throw new Error(
|
|
228
|
-
"cloudflared not installed.
|
|
331
|
+
"cloudflared not installed. Install it (macOS: `brew install cloudflared`; Windows: " +
|
|
332
|
+
"`winget install Cloudflare.cloudflared`), or point `$HARNERY_CLOUDFLARED` at a binary. " +
|
|
229
333
|
"On Linux it auto-installs to ~/.local/bin/cloudflared.",
|
|
230
334
|
);
|
|
231
335
|
}
|
|
232
336
|
|
|
233
337
|
process.stderr.write("Installing cloudflared to ~/.local/bin/...\n"); // lint-ok-emission: sync setup phase before structured output; pairs with the inherited stdio of the curl below
|
|
234
|
-
|
|
235
|
-
|
|
338
|
+
mkdirSync(join(homedir(), ".local", "bin"), { recursive: true });
|
|
339
|
+
const download = spawnSync(
|
|
340
|
+
"curl",
|
|
341
|
+
[
|
|
342
|
+
"-fsSL",
|
|
343
|
+
`https://github.com/cloudflare/cloudflared/releases/latest/download/${asset}`,
|
|
344
|
+
"-o",
|
|
345
|
+
local,
|
|
346
|
+
],
|
|
236
347
|
{ stdio: "inherit" },
|
|
237
348
|
);
|
|
349
|
+
if (download.status !== 0) throw new Error("Downloading cloudflared failed; install it by hand.");
|
|
350
|
+
chmodSync(local, 0o755);
|
|
238
351
|
return local;
|
|
239
352
|
}
|