@indigoai-us/hq-cli 5.339.0 → 5.340.1-beta.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/CHANGELOG.md +8 -0
- package/README.md +5 -0
- package/assets/scaffold/core/scripts/resolve-company.sh +46 -2
- package/dist/commands/cloud.js +1 -0
- package/dist/commands/core-dm-bind-native.d.ts +2 -0
- package/dist/commands/core-dm-bind-native.js +13 -5
- package/docs/anywhere-runtime.md +60 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.340.1-beta.0] — 2026-10-03
|
|
6
|
+
- Let `hq sync now` skip unchanged server-owned cloud placeholders while keeping their warnings visible, so the sync can complete.
|
|
7
|
+
|
|
8
|
+
## [5.340.0] — 2026-10-03
|
|
9
|
+
- Preserve resolver output when child processes exit before Windows pipe data has drained.
|
|
10
|
+
- Native `hq core dm-bind` on Windows now finds an `hq.exe` on PATH, and no longer accepts an `hq.cmd` shim it cannot launch.
|
|
11
|
+
- Document the flag-gated HQ Anywhere global install and hqd daemon. The runtime flag remains off by default.
|
|
12
|
+
|
|
5
13
|
## [5.339.0] — 2026-10-03
|
|
6
14
|
- Reduce cold-start imports for the `checkpoint-stop-gate` and `session-journal` native fast routes.
|
|
7
15
|
|
package/README.md
CHANGED
|
@@ -7,6 +7,11 @@ npm install -g @indigoai-us/hq-cli
|
|
|
7
7
|
hq --help
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
+
The global HQ runtime installs hooks for supported agent runtimes. When the
|
|
11
|
+
`hq-anywhere-runtime` flag is enabled, the hooks use hqd and a per-user folder
|
|
12
|
+
registry. The flag is off by default. See [HQ Anywhere runtime](docs/anywhere-runtime.md)
|
|
13
|
+
for install and link commands.
|
|
14
|
+
|
|
10
15
|
## Deploy comments
|
|
11
16
|
|
|
12
17
|
List comments left on an app in your current hq-deploy organization. Use the
|
|
@@ -142,16 +142,60 @@ const command = process.argv[1];
|
|
|
142
142
|
if (!command) process.exit(127);
|
|
143
143
|
const child = spawn(command, process.argv.slice(2), { detached: true, stdio: ["ignore", "pipe", "ignore"] });
|
|
144
144
|
let finished = false;
|
|
145
|
+
let exited = false;
|
|
146
|
+
let exitStatus = 1;
|
|
147
|
+
let flushedAfterExit = false;
|
|
148
|
+
let pendingWrites = 0;
|
|
149
|
+
let stdoutEnded = false;
|
|
150
|
+
let drainTimer;
|
|
151
|
+
const finishWhenReady = () => {
|
|
152
|
+
if (finished || !exited || pendingWrites !== 0) return;
|
|
153
|
+
if (!stdoutEnded && !flushedAfterExit) return;
|
|
154
|
+
finished = true;
|
|
155
|
+
clearTimeout(timer);
|
|
156
|
+
clearTimeout(drainTimer);
|
|
157
|
+
try { process.kill(-child.pid, "SIGTERM"); } catch (_) {}
|
|
158
|
+
process.exit(exitStatus);
|
|
159
|
+
};
|
|
160
|
+
const forward = (chunk) => {
|
|
161
|
+
pendingWrites++;
|
|
162
|
+
process.stdout.write(chunk, () => {
|
|
163
|
+
pendingWrites--;
|
|
164
|
+
finishWhenReady();
|
|
165
|
+
});
|
|
166
|
+
};
|
|
145
167
|
const finish = (status) => {
|
|
146
168
|
if (finished) return;
|
|
147
169
|
finished = true;
|
|
148
170
|
clearTimeout(timer);
|
|
171
|
+
clearTimeout(drainTimer);
|
|
149
172
|
try { process.kill(-child.pid, "SIGTERM"); } catch (_) {}
|
|
150
173
|
process.exit(status);
|
|
151
174
|
};
|
|
152
|
-
child.stdout.on("data",
|
|
175
|
+
child.stdout.on("data", forward);
|
|
176
|
+
child.stdout.once("end", () => {
|
|
177
|
+
stdoutEnded = true;
|
|
178
|
+
finishWhenReady();
|
|
179
|
+
});
|
|
153
180
|
child.once("error", () => finish(127));
|
|
154
|
-
child.once("exit", (code) =>
|
|
181
|
+
child.once("exit", (code) => {
|
|
182
|
+
exited = true;
|
|
183
|
+
exitStatus = typeof code === "number" ? code : 1;
|
|
184
|
+
try { process.kill(-child.pid, "SIGTERM"); } catch (_) {}
|
|
185
|
+
// Normally EOF follows child exit once the pipe has drained. A detached
|
|
186
|
+
// grandchild can keep the pipe open, so bound that wait and flush buffered
|
|
187
|
+
// bytes after a short drain window.
|
|
188
|
+
drainTimer = setTimeout(() => {
|
|
189
|
+
child.stdout.pause();
|
|
190
|
+
let chunk;
|
|
191
|
+
while ((chunk = child.stdout.read()) !== null) forward(chunk);
|
|
192
|
+
process.stdout.write("", () => {
|
|
193
|
+
flushedAfterExit = true;
|
|
194
|
+
finishWhenReady();
|
|
195
|
+
});
|
|
196
|
+
}, 250);
|
|
197
|
+
finishWhenReady();
|
|
198
|
+
});
|
|
155
199
|
const timer = setTimeout(() => finish(124), 2000);
|
|
156
200
|
' "$@"
|
|
157
201
|
}
|
package/dist/commands/cloud.js
CHANGED
|
@@ -1751,6 +1751,7 @@ async function runNowSingle(hqRoot, company, personal, message, onConflict, mode
|
|
|
1751
1751
|
hqRoot,
|
|
1752
1752
|
progressRecorder: trackingProgressRecorder(planLimitTracker, pushProgressCompany),
|
|
1753
1753
|
skipUnchanged: true,
|
|
1754
|
+
serverOwnedPathPolicy: "skip",
|
|
1754
1755
|
propagateDeletes: true,
|
|
1755
1756
|
propagateDeletePolicy: resolveDeletePolicy(),
|
|
1756
1757
|
...(onConflict ? { onConflict } : {}),
|
|
@@ -11,6 +11,8 @@ export type DmBindDeps = {
|
|
|
11
11
|
home: string;
|
|
12
12
|
now: () => Date;
|
|
13
13
|
fs: typeof fs;
|
|
14
|
+
/** Defaults to process.platform; tests pass it to exercise the Windows lookup. */
|
|
15
|
+
platform?: NodeJS.Platform;
|
|
14
16
|
runHq: (args: string[], env: NodeJS.ProcessEnv) => {
|
|
15
17
|
code: number;
|
|
16
18
|
stdout: string;
|
|
@@ -91,12 +91,20 @@ function hasHqOnPath(d) {
|
|
|
91
91
|
for (const directory of (d.env.PATH ?? "").split(path.delimiter)) {
|
|
92
92
|
if (!directory)
|
|
93
93
|
continue;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
// runHq spawns "hq" without a shell. On Windows that resolves only .exe and
|
|
95
|
+
// .com files, and Windows file modes carry no execute bits, so accept exactly
|
|
96
|
+
// what the spawn can launch. npm's hq.cmd shim needs a shell and is not
|
|
97
|
+
// accepted here.
|
|
98
|
+
const windows = (d.platform ?? process.platform) === "win32";
|
|
99
|
+
const names = windows ? ["hq.exe", "hq.com"] : ["hq"];
|
|
100
|
+
for (const name of names) {
|
|
101
|
+
try {
|
|
102
|
+
const stat = d.fs.statSync(path.join(directory, name));
|
|
103
|
+
if (stat.isFile() && (windows || (stat.mode & 0o111) !== 0))
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
catch { /* PATH entry is absent */ }
|
|
98
107
|
}
|
|
99
|
-
catch { /* PATH entry is absent */ }
|
|
100
108
|
}
|
|
101
109
|
return false;
|
|
102
110
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# HQ Anywhere runtime
|
|
2
|
+
|
|
3
|
+
HQ Anywhere installs global hooks for supported agent runtimes and uses the
|
|
4
|
+
local hqd daemon on macOS and Linux. Windows does not currently start hqd, so
|
|
5
|
+
the daemon-backed routing described here is unavailable there. A per-user
|
|
6
|
+
registry links repositories to HQ companies. The `hq-anywhere-runtime` flag
|
|
7
|
+
controls these features and is off by default.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Install and start hqd before registering global hooks. The global installer
|
|
12
|
+
checks for the daemon service when choosing the hook target.
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
hq daemon install
|
|
16
|
+
hq daemon status
|
|
17
|
+
hq install --global --runtime claude
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`hq install --global` defaults to Claude. Select other supported runtimes
|
|
21
|
+
explicitly with `--runtime codex`, `--runtime chatgpt`, or `--runtime grok`.
|
|
22
|
+
Claude and Codex receive local hook configuration. ChatGPT and Grok print
|
|
23
|
+
connector setup instructions and require the runtime flag to be enabled.
|
|
24
|
+
|
|
25
|
+
The CLI stores the HQ root at `~/.hq/root` and keeps the folder registry in
|
|
26
|
+
`~/.hq/registry.json`. These files belong to the current host. They are not
|
|
27
|
+
stored in a repository or synced HQ folder.
|
|
28
|
+
|
|
29
|
+
On Windows, `hq daemon install` reports that hqd cannot start because its
|
|
30
|
+
named-pipe ACL is not supported. Global hook installation may still configure
|
|
31
|
+
local runtime hooks, but it does not provide the hqd routing described below.
|
|
32
|
+
|
|
33
|
+
When the flag is enabled, the global hook uses hqd for events outside the HQ
|
|
34
|
+
root. Inside the root, the project hook routes through hqd when it is running
|
|
35
|
+
and uses the direct master hook when it is stopped.
|
|
36
|
+
|
|
37
|
+
## Link a repository
|
|
38
|
+
|
|
39
|
+
Run `hq link <company>` from a repository to associate it with a company. The
|
|
40
|
+
registry uses the normalized Git remote when one is available. Otherwise, it
|
|
41
|
+
uses the repository's canonical absolute path.
|
|
42
|
+
|
|
43
|
+
`HQ_REGISTRY_DIR` changes the registry directory, and `HQ_HQD_SOCKET` changes
|
|
44
|
+
the daemon socket path. The managed service does not inherit overrides from
|
|
45
|
+
the shell that ran `hq daemon install`; it persists `PATH` and
|
|
46
|
+
`HQ_DAEMON_DIR`. Keep the defaults for a managed install unless you configure
|
|
47
|
+
both the daemon service and the agent runtime with the same overrides. For a
|
|
48
|
+
systemd user service, add `Environment=HQ_REGISTRY_DIR=...` and
|
|
49
|
+
`Environment=HQ_HQD_SOCKET=...` in `systemctl --user edit hq-daemon.service`,
|
|
50
|
+
then run `systemctl --user daemon-reload` and
|
|
51
|
+
`systemctl --user restart hq-daemon.service`. For launchd, set both keys in the
|
|
52
|
+
`EnvironmentVariables` dictionary in
|
|
53
|
+
`~/Library/LaunchAgents/ai.getindigo.hq-daemon.plist`, then restart the job
|
|
54
|
+
with `launchctl kickstart -k gui/$(id -u)/ai.getindigo.hq-daemon`. Also set
|
|
55
|
+
both variables in the agent runtime environment so hooks and `hq link` use
|
|
56
|
+
the same paths.
|
|
57
|
+
|
|
58
|
+
The registry does not infer a company when a repository has no matching entry.
|
|
59
|
+
That session uses personal context. The socket protocol and registry format are
|
|
60
|
+
documented in the HQ Anywhere runtime knowledge entry in hq-core.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indigoai-us/hq-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.340.1-beta.0",
|
|
4
4
|
"description": "HQ by Indigo management CLI — modules and cloud sync",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"assets/lanes-reconcile",
|
|
17
17
|
"assets/lanes-hooks",
|
|
18
18
|
"templates",
|
|
19
|
+
"docs/anywhere-runtime.md",
|
|
19
20
|
"CHANGELOG.md",
|
|
20
21
|
"README.md",
|
|
21
22
|
"contracts",
|