@hwip/cli 0.0.1 → 0.1.1
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/LICENSE +190 -0
- package/NOTICE +11 -0
- package/README.md +1983 -0
- package/dist/agent-list.d.ts +76 -0
- package/dist/agent-list.js +102 -0
- package/dist/agent-read.d.ts +105 -0
- package/dist/agent-read.js +309 -0
- package/dist/agent-rules-fetch.d.ts +51 -0
- package/dist/agent-rules-fetch.js +275 -0
- package/dist/agent-rules.default.d.ts +30 -0
- package/dist/agent-rules.default.js +305 -0
- package/dist/agent-session.d.ts +23 -0
- package/dist/agent-session.js +44 -0
- package/dist/agent-state.d.ts +84 -0
- package/dist/agent-state.js +188 -0
- package/dist/agent-target.d.ts +60 -0
- package/dist/agent-target.js +81 -0
- package/dist/agents.d.ts +31 -0
- package/dist/agents.js +75 -0
- package/dist/api.d.ts +28 -0
- package/dist/api.js +76 -0
- package/dist/args.d.ts +74 -0
- package/dist/args.js +254 -0
- package/dist/ask-context-attach.d.ts +73 -0
- package/dist/ask-context-attach.js +151 -0
- package/dist/ask-context-screen.d.ts +21 -0
- package/dist/ask-context-screen.js +49 -0
- package/dist/ask-context-switch.d.ts +31 -0
- package/dist/ask-context-switch.js +74 -0
- package/dist/ask-context.d.ts +84 -0
- package/dist/ask-context.js +172 -0
- package/dist/ask-pending.d.ts +47 -0
- package/dist/ask-pending.js +221 -0
- package/dist/ask-seal.d.ts +120 -0
- package/dist/ask-seal.js +179 -0
- package/dist/ask.d.ts +107 -0
- package/dist/ask.js +551 -0
- package/dist/blocked-prompt-seal.d.ts +39 -0
- package/dist/blocked-prompt-seal.js +92 -0
- package/dist/blocked-prompt.d.ts +62 -0
- package/dist/blocked-prompt.js +518 -0
- package/dist/channel.d.ts +67 -0
- package/dist/channel.js +136 -0
- package/dist/check-update.d.ts +28 -0
- package/dist/check-update.js +153 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +813 -0
- package/dist/codex-config.d.ts +24 -0
- package/dist/codex-config.js +169 -0
- package/dist/codex-transcript.d.ts +59 -0
- package/dist/codex-transcript.js +373 -0
- package/dist/command-refusal.d.ts +56 -0
- package/dist/command-refusal.js +127 -0
- package/dist/command-scan.d.ts +46 -0
- package/dist/command-scan.js +154 -0
- package/dist/command-seal.d.ts +57 -0
- package/dist/command-seal.js +88 -0
- package/dist/command-seq.d.ts +30 -0
- package/dist/command-seq.js +150 -0
- package/dist/config.d.ts +156 -0
- package/dist/config.js +392 -0
- package/dist/core-sections.d.ts +18 -0
- package/dist/core-sections.js +28 -0
- package/dist/crypto.d.ts +278 -0
- package/dist/crypto.js +698 -0
- package/dist/desktop-notify.d.ts +33 -0
- package/dist/desktop-notify.js +49 -0
- package/dist/device-directory.d.ts +36 -0
- package/dist/device-directory.js +97 -0
- package/dist/device-presence.d.ts +17 -0
- package/dist/device-presence.js +62 -0
- package/dist/downloads.d.ts +29 -0
- package/dist/downloads.js +106 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +28 -0
- package/dist/file-crypto.d.ts +94 -0
- package/dist/file-crypto.js +278 -0
- package/dist/file-view-budget.d.ts +15 -0
- package/dist/file-view-budget.js +34 -0
- package/dist/file-view-switch.d.ts +28 -0
- package/dist/file-view-switch.js +122 -0
- package/dist/file-view.d.ts +108 -0
- package/dist/file-view.js +327 -0
- package/dist/gate.d.ts +141 -0
- package/dist/gate.js +336 -0
- package/dist/gemini-transcript.d.ts +32 -0
- package/dist/gemini-transcript.js +189 -0
- package/dist/http-failure.d.ts +98 -0
- package/dist/http-failure.js +349 -0
- package/dist/hwip-core.generated.d.ts +7 -0
- package/dist/hwip-core.generated.js +14 -0
- package/dist/hwip-hook.d.ts +77 -0
- package/dist/hwip-hook.js +340 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +14 -0
- package/dist/input-sequencer.d.ts +65 -0
- package/dist/input-sequencer.js +142 -0
- package/dist/insecure-url.d.ts +16 -0
- package/dist/insecure-url.js +76 -0
- package/dist/installer.d.ts +96 -0
- package/dist/installer.js +850 -0
- package/dist/inventory-offload.d.ts +49 -0
- package/dist/inventory-offload.js +209 -0
- package/dist/inventory-worker.d.ts +2 -0
- package/dist/inventory-worker.js +27 -0
- package/dist/jsonc-doc.d.ts +106 -0
- package/dist/jsonc-doc.js +354 -0
- package/dist/keep-awake.d.ts +32 -0
- package/dist/keep-awake.js +46 -0
- package/dist/key-changes.d.ts +48 -0
- package/dist/key-changes.js +140 -0
- package/dist/lan-auth.d.ts +140 -0
- package/dist/lan-auth.js +217 -0
- package/dist/lan-endpoint.d.ts +41 -0
- package/dist/lan-endpoint.js +115 -0
- package/dist/lan-receiver.d.ts +122 -0
- package/dist/lan-receiver.js +510 -0
- package/dist/lan-sender.d.ts +76 -0
- package/dist/lan-sender.js +184 -0
- package/dist/lan-transfer.d.ts +36 -0
- package/dist/lan-transfer.js +54 -0
- package/dist/listener-device-id.d.ts +20 -0
- package/dist/listener-device-id.js +133 -0
- package/dist/listener-log.d.ts +4 -0
- package/dist/listener-log.js +23 -0
- package/dist/listener-process.d.ts +200 -0
- package/dist/listener-process.js +470 -0
- package/dist/listener-service.d.ts +225 -0
- package/dist/listener-service.js +682 -0
- package/dist/listener-worktree-cleanup.d.ts +27 -0
- package/dist/listener-worktree-cleanup.js +62 -0
- package/dist/listener.d.ts +1325 -0
- package/dist/listener.js +5681 -0
- package/dist/login-address.d.ts +25 -0
- package/dist/login-address.js +97 -0
- package/dist/login-page.d.ts +29 -0
- package/dist/login-page.js +93 -0
- package/dist/login.d.ts +98 -0
- package/dist/login.js +388 -0
- package/dist/mcp-command.d.ts +45 -0
- package/dist/mcp-command.js +50 -0
- package/dist/mcp.d.ts +19 -0
- package/dist/mcp.js +29 -0
- package/dist/node-support.d.ts +19 -0
- package/dist/node-support.js +38 -0
- package/dist/notify-failure.d.ts +57 -0
- package/dist/notify-failure.js +150 -0
- package/dist/opencode-transcript.d.ts +139 -0
- package/dist/opencode-transcript.js +390 -0
- package/dist/optional-features.d.ts +6 -0
- package/dist/optional-features.js +19 -0
- package/dist/pane-fit.d.ts +40 -0
- package/dist/pane-fit.js +119 -0
- package/dist/peer-key.d.ts +33 -0
- package/dist/peer-key.js +34 -0
- package/dist/pi-transcript.d.ts +26 -0
- package/dist/pi-transcript.js +255 -0
- package/dist/presence.d.ts +14 -0
- package/dist/presence.js +124 -0
- package/dist/private-files.d.ts +51 -0
- package/dist/private-files.js +218 -0
- package/dist/project-switch.d.ts +19 -0
- package/dist/project-switch.js +60 -0
- package/dist/redact.d.ts +10 -0
- package/dist/redact.js +21 -0
- package/dist/remote-agents.d.ts +410 -0
- package/dist/remote-agents.js +1218 -0
- package/dist/remote-hook.d.ts +12 -0
- package/dist/remote-hook.js +196 -0
- package/dist/replace-file.d.ts +50 -0
- package/dist/replace-file.js +328 -0
- package/dist/schedule-command.d.ts +35 -0
- package/dist/schedule-command.js +260 -0
- package/dist/schedule-launch.d.ts +15 -0
- package/dist/schedule-launch.js +24 -0
- package/dist/schedule-ready.d.ts +44 -0
- package/dist/schedule-ready.js +71 -0
- package/dist/schedule-remote.d.ts +77 -0
- package/dist/schedule-remote.js +167 -0
- package/dist/schedule-runner.d.ts +89 -0
- package/dist/schedule-runner.js +452 -0
- package/dist/schedule.d.ts +149 -0
- package/dist/schedule.js +428 -0
- package/dist/secret-mask.d.ts +29 -0
- package/dist/secret-mask.js +245 -0
- package/dist/self-register.d.ts +45 -0
- package/dist/self-register.js +67 -0
- package/dist/send.d.ts +56 -0
- package/dist/send.js +104 -0
- package/dist/session-diff.d.ts +161 -0
- package/dist/session-diff.js +445 -0
- package/dist/session-registry.d.ts +143 -0
- package/dist/session-registry.js +216 -0
- package/dist/sessions-report.d.ts +59 -0
- package/dist/sessions-report.js +99 -0
- package/dist/shell-audit.d.ts +34 -0
- package/dist/shell-audit.js +47 -0
- package/dist/subagent-transcripts.d.ts +167 -0
- package/dist/subagent-transcripts.js +437 -0
- package/dist/subscriber-trust.d.ts +128 -0
- package/dist/subscriber-trust.js +397 -0
- package/dist/templates.d.ts +105 -0
- package/dist/templates.js +871 -0
- package/dist/tmux-install.d.ts +44 -0
- package/dist/tmux-install.js +65 -0
- package/dist/tmux-liveness.d.ts +45 -0
- package/dist/tmux-liveness.js +71 -0
- package/dist/tmux-pane.d.ts +55 -0
- package/dist/tmux-pane.js +126 -0
- package/dist/tmux-socket.d.ts +20 -0
- package/dist/tmux-socket.js +292 -0
- package/dist/todo-fold.d.ts +31 -0
- package/dist/todo-fold.js +102 -0
- package/dist/transcript-tail.d.ts +312 -0
- package/dist/transcript-tail.js +718 -0
- package/dist/trust-command.d.ts +49 -0
- package/dist/trust-command.js +200 -0
- package/dist/trust-lock.d.ts +26 -0
- package/dist/trust-lock.js +94 -0
- package/dist/trust-pins.d.ts +37 -0
- package/dist/trust-pins.js +82 -0
- package/dist/turn-recorder-wire.d.ts +70 -0
- package/dist/turn-recorder-wire.js +165 -0
- package/dist/turn-recorder.d.ts +190 -0
- package/dist/turn-recorder.js +695 -0
- package/dist/turn-ring.d.ts +93 -0
- package/dist/turn-ring.js +418 -0
- package/dist/turn-watch.d.ts +177 -0
- package/dist/turn-watch.js +630 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.js +2 -0
- package/dist/uninstall.d.ts +55 -0
- package/dist/uninstall.js +507 -0
- package/dist/usage.d.ts +17 -0
- package/dist/usage.js +421 -0
- package/dist/verify.d.ts +47 -0
- package/dist/verify.js +396 -0
- package/dist/worktree.d.ts +144 -0
- package/dist/worktree.js +310 -0
- package/dist/wrapper.d.ts +254 -0
- package/dist/wrapper.js +704 -0
- package/dist/ws-url.d.ts +109 -0
- package/dist/ws-url.js +202 -0
- package/package.json +78 -10
- package/bin/hwip.js +0 -3
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nextCommandNumber = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const node_os_1 = require("node:os");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const private_files_js_1 = require("./private-files.js");
|
|
9
|
+
const FILE = 'command-seq';
|
|
10
|
+
const LOCK = 'command-seq.lock';
|
|
11
|
+
/** 40 tries 50 ms apart: two seconds, then the send is refused. */
|
|
12
|
+
const LOCK_TRIES = 40;
|
|
13
|
+
const LOCK_RETRY_MS = 50;
|
|
14
|
+
/** A lock older than this was left by a process that died holding it. */
|
|
15
|
+
const LOCK_STALE_MS = 5000;
|
|
16
|
+
const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
17
|
+
/**
|
|
18
|
+
* One try at the lock: its release when taken, 'held' when someone else has it, 'failed' when it cannot be made at all.
|
|
19
|
+
* The lock holds a token only its taker knows, and the release removes the file only while it still holds that token:
|
|
20
|
+
* a holder that was stopped for longer than `LOCK_STALE_MS` (a laptop asleep) finds its lock cleared and perhaps taken
|
|
21
|
+
* again, and must not remove the new holder's.
|
|
22
|
+
*/
|
|
23
|
+
const tryLock = (path) => {
|
|
24
|
+
const token = (0, node_crypto_1.randomBytes)(8).toString('hex');
|
|
25
|
+
let fd;
|
|
26
|
+
try {
|
|
27
|
+
fd = (0, node_fs_1.openSync)(path, 'wx', 0o600);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
// err.code is how node names a failed open. Nothing was created, so nothing here is ours to remove.
|
|
31
|
+
return err.code === 'EEXIST' ? 'held' : 'failed';
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
(0, node_fs_1.writeSync)(fd, token);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
try {
|
|
38
|
+
(0, node_fs_1.unlinkSync)(path); // created but not written (disk full): no later sender should wait on an empty lock
|
|
39
|
+
}
|
|
40
|
+
catch { /* gone already */ }
|
|
41
|
+
return 'failed';
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
(0, node_fs_1.closeSync)(fd);
|
|
45
|
+
}
|
|
46
|
+
(0, private_files_js_1.handBackToSudoUser)(path);
|
|
47
|
+
return () => {
|
|
48
|
+
try {
|
|
49
|
+
if ((0, node_fs_1.readFileSync)(path, 'utf-8') === token)
|
|
50
|
+
(0, node_fs_1.unlinkSync)(path);
|
|
51
|
+
}
|
|
52
|
+
catch { /* gone already: nothing is held */ }
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* The lock file's own age says whether anyone is still behind it. A stale one is moved aside under a name of its own
|
|
57
|
+
* and only then checked and removed: a plain unlink by path could remove a lock another waiter had just made. If what
|
|
58
|
+
* was moved is not the file that was seen, it was a live lock; it goes back unless yet another has been made since.
|
|
59
|
+
*/
|
|
60
|
+
const removeIfStale = (path) => {
|
|
61
|
+
try {
|
|
62
|
+
const seen = (0, node_fs_1.statSync)(path);
|
|
63
|
+
if (Date.now() - seen.mtimeMs <= LOCK_STALE_MS)
|
|
64
|
+
return;
|
|
65
|
+
const aside = `${path}.${process.pid}.${(0, node_crypto_1.randomBytes)(6).toString('hex')}.stale`;
|
|
66
|
+
(0, node_fs_1.renameSync)(path, aside);
|
|
67
|
+
try {
|
|
68
|
+
const moved = (0, node_fs_1.statSync)(aside);
|
|
69
|
+
if (moved.ino !== seen.ino || moved.mtimeMs !== seen.mtimeMs) {
|
|
70
|
+
try {
|
|
71
|
+
(0, node_fs_1.linkSync)(aside, path);
|
|
72
|
+
}
|
|
73
|
+
catch { /* someone made a lock since: theirs stands */ }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
(0, node_fs_1.unlinkSync)(aside);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch { /* taken, or removed, by someone else in between */ }
|
|
81
|
+
};
|
|
82
|
+
/** The last number handed out: 0 when there is no file or it holds no number, null when it cannot be read or is out of range. */
|
|
83
|
+
const readLast = (path) => {
|
|
84
|
+
let text;
|
|
85
|
+
try {
|
|
86
|
+
text = (0, node_fs_1.readFileSync)(path, 'utf-8');
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
return err.code === 'ENOENT' ? 0 : null; // err.code is how node names a missing file
|
|
90
|
+
}
|
|
91
|
+
const line = text.trim();
|
|
92
|
+
if (!/^\d+$/.test(line))
|
|
93
|
+
return 0;
|
|
94
|
+
const last = Number(line);
|
|
95
|
+
return Number.isSafeInteger(last) ? last : null;
|
|
96
|
+
};
|
|
97
|
+
/** Read, add, write: runs with the lock held, and without a pause, so callers in one process never overlap. */
|
|
98
|
+
const draw = (dir, now) => {
|
|
99
|
+
const path = (0, node_path_1.join)(dir, FILE);
|
|
100
|
+
const last = readLast(path);
|
|
101
|
+
if (last === null)
|
|
102
|
+
return { refused: 'io' };
|
|
103
|
+
const n = Math.max(last + 1, Math.floor(now()));
|
|
104
|
+
if (!Number.isSafeInteger(n))
|
|
105
|
+
return { refused: 'io' };
|
|
106
|
+
// Random name, exclusive create, then rename: a reader never sees half a line.
|
|
107
|
+
const temp = `${path}.${process.pid}.${(0, node_crypto_1.randomBytes)(6).toString('hex')}.tmp`;
|
|
108
|
+
try {
|
|
109
|
+
(0, node_fs_1.writeFileSync)(temp, `${n}\n`, { mode: 0o600, flag: 'wx' });
|
|
110
|
+
(0, private_files_js_1.handBackToSudoUser)(temp);
|
|
111
|
+
(0, node_fs_1.renameSync)(temp, path);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
try {
|
|
115
|
+
(0, node_fs_1.unlinkSync)(temp);
|
|
116
|
+
}
|
|
117
|
+
catch { /* never made */ }
|
|
118
|
+
return { refused: 'io' };
|
|
119
|
+
}
|
|
120
|
+
return n;
|
|
121
|
+
};
|
|
122
|
+
const nextCommandNumber = async (deps = {}) => {
|
|
123
|
+
const dir = deps.dir ?? (0, node_path_1.join)((0, node_os_1.homedir)(), '.hwip');
|
|
124
|
+
const now = deps.now ?? Date.now;
|
|
125
|
+
const sleep = deps.sleep ?? defaultSleep;
|
|
126
|
+
try {
|
|
127
|
+
(0, private_files_js_1.mkdirHandedBack)(dir, 0o700);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return { refused: 'io' };
|
|
131
|
+
}
|
|
132
|
+
const lock = (0, node_path_1.join)(dir, LOCK);
|
|
133
|
+
for (let attempt = 0; attempt < LOCK_TRIES; attempt += 1) {
|
|
134
|
+
const taken = tryLock(lock);
|
|
135
|
+
if (taken === 'failed')
|
|
136
|
+
return { refused: 'io' };
|
|
137
|
+
if (typeof taken === 'function') {
|
|
138
|
+
try {
|
|
139
|
+
return draw(dir, now);
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
taken();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
removeIfStale(lock);
|
|
146
|
+
await sleep(LOCK_RETRY_MS);
|
|
147
|
+
}
|
|
148
|
+
return { refused: 'lock' };
|
|
149
|
+
};
|
|
150
|
+
exports.nextCommandNumber = nextCommandNumber;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
export declare const CONFIG_DIR: string;
|
|
2
|
+
export declare const CONFIG_FILE: string;
|
|
3
|
+
/** The listener's subscriber trust store (subscriber-trust.ts), shared with `hwip trust`. */
|
|
4
|
+
export declare const TRUST_FILE: string;
|
|
5
|
+
export interface HwipConfig {
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
hookId?: string;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
wsUrl?: string;
|
|
10
|
+
/** `false` stops the listener holding the Mac awake on AC (`caffeinate -s`). README § Listener Options. */
|
|
11
|
+
keepAwake?: boolean;
|
|
12
|
+
/** `false` stops the listener uploading sealed session conversations for the app's history (`turn-recorder.ts`). README § Session history. */
|
|
13
|
+
turnHistory?: boolean;
|
|
14
|
+
/** Proxy settings for a process that does not get the shell's `HTTPS_PROXY` (a launchd service); the environment wins. README § Environment Variables. */
|
|
15
|
+
httpProxy?: string;
|
|
16
|
+
httpsProxy?: string;
|
|
17
|
+
noProxy?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* What a boolean option is when `config.json` is there and cannot be used (it does
|
|
21
|
+
* not parse, or is ignored for its mode). The options are opt-outs: read as "not set"
|
|
22
|
+
* they come back ON, and a user who wrote `"turnHistory": false` found sealed
|
|
23
|
+
* conversations uploading. Unreadable means off, for every boolean option HwipConfig has
|
|
24
|
+
* (the compiler holds the keys to the interface, and config-unreadable.test.ts reads it too).
|
|
25
|
+
*/
|
|
26
|
+
export type BooleanConfigKey = {
|
|
27
|
+
[K in keyof HwipConfig]-?: NonNullable<HwipConfig[K]> extends boolean ? K : never;
|
|
28
|
+
}[keyof HwipConfig];
|
|
29
|
+
export declare const unreadableConfigDefaults: Record<BooleanConfigKey, false>;
|
|
30
|
+
export declare const resolvedEnv: (key: string, env?: NodeJS.ProcessEnv) => string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* The two-way hook id: `HWIP_HOOK_ID` when it carries a real value, else
|
|
33
|
+
* `hookId` from ~/.hwip/config.json — what `hwip setup` writes. The plugin's
|
|
34
|
+
* gate.sh `hwip_hook_id` and the MCP server resolve it in the same order.
|
|
35
|
+
*/
|
|
36
|
+
export declare const resolveHookId: (env?: NodeJS.ProcessEnv) => string | undefined;
|
|
37
|
+
/** tmux session options the listener reads before falling back to parsing the name (listener `parseSessionName`). */
|
|
38
|
+
export declare const SESSION_PROJECT_OPTION = "@hwip_project";
|
|
39
|
+
export declare const SESSION_LABEL_OPTION = "@hwip_session_label";
|
|
40
|
+
/**
|
|
41
|
+
* The herdr pane a session is attached from, as `<herdr env var> → <session
|
|
42
|
+
* option>`. herdr finds agents by a pane's foreground process, which for a
|
|
43
|
+
* wrapped pane is the tmux client, so the plugin's `hwip-herdr.sh` hook and
|
|
44
|
+
* the pi extension (templates `PI_EXTENSION`) report the agent's state
|
|
45
|
+
* themselves, to the pane these options name. They are session options rather
|
|
46
|
+
* than the agent's own env because a `hwip` reattach from another herdr pane
|
|
47
|
+
* (or from outside herdr) must retarget a running agent.
|
|
48
|
+
*/
|
|
49
|
+
export declare const HERDR_SESSION_OPTIONS: {
|
|
50
|
+
readonly HERDR_PANE_ID: "@hwip_herdr_pane";
|
|
51
|
+
readonly HERDR_SOCKET_PATH: "@hwip_herdr_socket";
|
|
52
|
+
readonly HERDR_BIN_PATH: "@hwip_herdr_bin";
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Set by `hwip sh` on the session it opens, to that session's own name. The
|
|
56
|
+
* one exception to the listener's shell-pane refusal. Only a process on this
|
|
57
|
+
* machine can set a tmux option, so it says the user opened the shell — but it
|
|
58
|
+
* is not a boundary: the phone can set it through `!` in a Claude Code session,
|
|
59
|
+
* or from a shell that is already marked (README § Defense).
|
|
60
|
+
*/
|
|
61
|
+
export declare const SESSION_SHELL_OPTION = "@hwip_shell";
|
|
62
|
+
/** `name` as tmux holds it: tmux turns `.`/`:` into `_`, and `;` would end a tmux command (wrapper `tmuxSessionName`). */
|
|
63
|
+
export declare const tmuxName: (name: string) => string;
|
|
64
|
+
/**
|
|
65
|
+
* The repo a directory belongs to: `key` names the main checkout, `linked` says the directory is in a linked worktree,
|
|
66
|
+
* `root` is the main checkout's path — null where there is no main checkout to point at (the layouts `key` falls back on).
|
|
67
|
+
*/
|
|
68
|
+
export interface Checkout {
|
|
69
|
+
key: string;
|
|
70
|
+
linked: boolean;
|
|
71
|
+
root: string | null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Which checkout `dir` is in, from one `git rev-parse`; null outside git.
|
|
75
|
+
*
|
|
76
|
+
* Inside a linked worktree `--show-toplevel` is the worktree itself, so its
|
|
77
|
+
* name is not the repo's. The common dir is `<main checkout>/.git` from every
|
|
78
|
+
* worktree, and differs from the git dir only in a linked one. A common dir not
|
|
79
|
+
* named `.git` (bare-repo layout, submodule, `--separate-git-dir`) has no
|
|
80
|
+
* checkout to be named for, so the toplevel's own name stands and nothing is
|
|
81
|
+
* called linked — those worktrees keep reading as their own projects.
|
|
82
|
+
*
|
|
83
|
+
* Anything but three absolute paths is "outside git": a git too old for
|
|
84
|
+
* `--path-format` echoes it back as an unknown flag and exits 0, which would
|
|
85
|
+
* otherwise shift every answer by one and name the repo `--path-format=absolute`.
|
|
86
|
+
*
|
|
87
|
+
* The timeout is for the listener's sweep worker, which calls this for every
|
|
88
|
+
* new pane cwd: a repo on a hung network mount must cost one sweep a moment,
|
|
89
|
+
* not stop inventory. A timeout reads as "outside git" — nothing is regrouped.
|
|
90
|
+
*/
|
|
91
|
+
export declare const checkoutOf: (dir: string, run?: (dir: string) => string) => Checkout | null;
|
|
92
|
+
/**
|
|
93
|
+
* The project and label a `hwip-<tail>` session groups under, when its name
|
|
94
|
+
* does not say so — null when it does (the whole tail is the project).
|
|
95
|
+
*
|
|
96
|
+
* The one rule behind both the wrapper's session options and the listener's
|
|
97
|
+
* correction of sessions started without them, so the two never disagree.
|
|
98
|
+
* A tail starting `<repo>-` splits there, unless the rest is the wrapper's
|
|
99
|
+
* `-2`/`-3` family counter. Any session in a linked worktree belongs to its
|
|
100
|
+
* repo, whatever the worktree is called.
|
|
101
|
+
*/
|
|
102
|
+
export declare const groupOf: (tail: string, checkout: Checkout | null) => {
|
|
103
|
+
project: string;
|
|
104
|
+
label: string;
|
|
105
|
+
} | null;
|
|
106
|
+
export declare const PROJECT_DIR_ENV_VARS: readonly ["CLAUDE_PROJECT_DIR", "CURSOR_PROJECT_DIR", "WINDSURF_PROJECT_DIR"];
|
|
107
|
+
/** First set project-dir env (unresolved `${VAR}` placeholders ignored), else cwd. */
|
|
108
|
+
export declare const detectProjectDir: () => string;
|
|
109
|
+
/**
|
|
110
|
+
* Why this machine should not trust `~/.hwip/config.json` as it stands, or null.
|
|
111
|
+
* The file holds the API key AND says where the key is sent (`baseUrl`, `wsUrl`),
|
|
112
|
+
* so one that another user owns, or that anyone can write, is a way to redirect
|
|
113
|
+
* the key. `refuse`: ignore the file (and never write over it); otherwise only
|
|
114
|
+
* warn and restrict it. Group access to a file the user owns is not refused: a
|
|
115
|
+
* user-private group (umask 002, a dotfiles checkout) makes every file 664, and
|
|
116
|
+
* ignoring those would stop every command. Root may read what a user owns (sudo).
|
|
117
|
+
*/
|
|
118
|
+
export declare const configModeProblem: (st: {
|
|
119
|
+
uid: number;
|
|
120
|
+
mode: number;
|
|
121
|
+
}, myUid: number, file?: string) => {
|
|
122
|
+
refuse: boolean;
|
|
123
|
+
why: string;
|
|
124
|
+
} | null;
|
|
125
|
+
export declare const loadConfig: () => HwipConfig;
|
|
126
|
+
/** Why `config.json` is being ignored right now (it does not parse, or its mode refuses it), or null. For a log line or `hwip verify`. */
|
|
127
|
+
export declare const configIgnoredBecause: () => string | null;
|
|
128
|
+
/** The key about to be used is the config file's: none came by flag (`flagKey`) or `HWIP_API_KEY`. */
|
|
129
|
+
export declare const keyIsFromFile: (flagKey: string | boolean | undefined, config: HwipConfig) => boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Why the config file's key must not go to `envBase`, an address from `HWIP_BASE_URL`, or null. The key belongs to
|
|
132
|
+
* the file's `baseUrl`, else the default API; only the same origin may carry it (C129).
|
|
133
|
+
*/
|
|
134
|
+
export declare const fileKeyBaseRefusal: (envBase: string, config: HwipConfig) => string | null;
|
|
135
|
+
/**
|
|
136
|
+
* `url` as a base URL from `from`, before it is saved or sent anywhere: the same checks
|
|
137
|
+
* `resolveBaseUrl` applies (no user name or password in it, and an address at all).
|
|
138
|
+
*/
|
|
139
|
+
export declare const checkBaseUrl: (url: string, from: string) => string;
|
|
140
|
+
/**
|
|
141
|
+
* Where the key goes: the flag, `HWIP_BASE_URL`, the file, else the default API. A file that
|
|
142
|
+
* cannot be read may hold a base URL the key belongs to (staging, self-hosted); falling to the
|
|
143
|
+
* default would send the key to another server, so that stops here instead. A file ignored for
|
|
144
|
+
* its mode is not trusted for a base URL on purpose, and the default stands.
|
|
145
|
+
*
|
|
146
|
+
* `keyFromFile` (see `keyIsFromFile`): the config file's key belongs to the addresses the file says (its
|
|
147
|
+
* `baseUrl`, else the default API), so an address from `HWIP_BASE_URL` on another origin stops here instead of
|
|
148
|
+
* receiving it (C129). A flag is the user's own word on this command and is followed; so is the environment's
|
|
149
|
+
* address when the key came by flag or `HWIP_API_KEY` too.
|
|
150
|
+
*/
|
|
151
|
+
export declare const resolveBaseUrl: (flagValue: string | boolean | undefined, config: HwipConfig, keyFromFile?: boolean) => string;
|
|
152
|
+
/** `writeBlock` for the file as it is now. `install` and `login` ask first, so nothing is signed in to or verified for a save that cannot happen. */
|
|
153
|
+
export declare const configWriteProblem: () => string | null;
|
|
154
|
+
export declare const saveConfig: (config: HwipConfig) => void;
|
|
155
|
+
export declare const VERSION: string;
|
|
156
|
+
//# sourceMappingURL=config.d.ts.map
|