@indigoai-us/hq-cli 5.301.0 → 5.303.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 +26 -0
- package/assets/scaffold/core/scripts/rebuild-projects-index.sh +99 -12
- package/assets/scaffold/core/scripts/token-usage-report.sh +72 -20
- package/dist/command-catalog.generated.d.ts +4 -1
- package/dist/command-catalog.generated.js +5 -1
- package/dist/commands/bot.js +1 -0
- package/dist/commands/core-checkpoint.js +1 -0
- package/dist/commands/core-handoff-fast.js +1 -0
- package/dist/commands/core-handoff.js +2 -0
- package/dist/commands/deploy-comments.js +5 -2
- package/dist/commands/integrations-connect.d.ts +3 -0
- package/dist/commands/integrations-connect.js +21 -2
- package/dist/commands/lanes-message.js +33 -3
- package/dist/commands/lanes-questions.d.ts +4 -2
- package/dist/commands/lanes-questions.js +123 -2
- package/dist/commands/lanes-resume.js +25 -4
- package/dist/commands/lanes-shared.d.ts +13 -1
- package/dist/commands/lanes-watch.js +5 -1
- package/dist/commands/lanes.js +91 -9
- package/dist/commands/monitor.js +17 -2
- package/dist/commands/report.js +5 -2
- package/dist/commands/rescue.d.ts +4 -0
- package/dist/commands/rescue.js +27 -17
- package/dist/lib/agent-kit/fallback.d.ts +1 -0
- package/dist/lib/agent-kit/fallback.js +1 -0
- package/dist/lib/bot/cli-update.d.ts +0 -8
- package/dist/lib/bot/cli-update.js +5 -5
- package/dist/lib/bot/daemon.d.ts +5 -1
- package/dist/lib/bot/daemon.js +4 -4
- package/dist/lib/bot/local-jobs.d.ts +1 -21
- package/dist/lib/bot/local-jobs.js +12 -12
- package/dist/lib/core-utils/soft-timeout.js +1 -1
- package/dist/lib/daemon/config.d.ts +0 -1
- package/dist/lib/daemon/config.js +1 -1
- package/dist/lib/deploy-apps.d.ts +13 -0
- package/dist/lib/deploy-apps.js +24 -0
- package/dist/lib/index-render/projects.js +82 -5
- package/dist/lib/lanes/delivery.d.ts +7 -3
- package/dist/lib/lanes/delivery.js +18 -8
- package/dist/lib/lanes/index.d.ts +1 -1
- package/dist/lib/lanes/keep-alive.d.ts +13 -3
- package/dist/lib/lanes/keep-alive.js +29 -5
- package/dist/lib/lanes/outpost-dispatch.d.ts +5 -0
- package/dist/lib/lanes/outpost-dispatch.js +12 -0
- package/dist/lib/lanes/reconcile.d.ts +1 -0
- package/dist/lib/lanes/reconcile.js +358 -38
- package/dist/lib/lanes/spawn.d.ts +1 -0
- package/dist/lib/lanes/spawn.js +20 -10
- package/dist/lib/lanes/store.js +24 -0
- package/dist/lib/lanes/story-ledger.d.ts +2 -0
- package/dist/lib/lanes/story-ledger.js +8 -0
- package/dist/lib/lanes/types.d.ts +26 -4
- package/dist/lib/lanes/types.js +33 -1
- package/dist/lib/lanes/watch.d.ts +1 -0
- package/dist/lib/lanes/watch.js +19 -6
- package/dist/lib/lanes/watcher.js +139 -9
- package/dist/lib/mesh/live/daemon/run.js +36 -2
- package/dist/lib/report-snapshot.d.ts +0 -2
- package/dist/lib/report-snapshot.js +2 -2
- package/dist/lib/search-index/background.d.ts +1 -0
- package/dist/lib/search-index/background.js +1 -0
- package/dist/utils/run-bundled-script.js +103 -1
- package/dist/utils/update-command-supervisor.cjs +1 -0
- package/dist/utils/version-gate.js +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/** File name of the snapshot inside the published report. */
|
|
2
2
|
export declare const REPORT_PREVIEW_FILE = "hq-preview.png";
|
|
3
|
-
export declare const REPORT_PREVIEW_WIDTH = 1280;
|
|
4
|
-
export declare const REPORT_PREVIEW_HEIGHT = 720;
|
|
5
3
|
/** First installed browser that can take a snapshot, or null. */
|
|
6
4
|
export declare function findSnapshotBrowser(env?: NodeJS.ProcessEnv, platform?: string, exists?: (file: string) => boolean): string | null;
|
|
7
5
|
export declare function snapshotArgs(indexFile: string, outFile: string, profileDir: string): string[];
|
|
@@ -13,8 +13,8 @@ import * as path from "node:path";
|
|
|
13
13
|
import { pathToFileURL } from "node:url";
|
|
14
14
|
/** File name of the snapshot inside the published report. */
|
|
15
15
|
export const REPORT_PREVIEW_FILE = "hq-preview.png";
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const REPORT_PREVIEW_WIDTH = 1280;
|
|
17
|
+
const REPORT_PREVIEW_HEIGHT = 720;
|
|
18
18
|
const SNAPSHOT_TIMEOUT_MS = 30_000;
|
|
19
19
|
const PNG_MAGIC = Buffer.from([0x89, 0x50, 0x4e, 0x47]);
|
|
20
20
|
const BROWSER_PATHS = {
|
|
@@ -92,6 +92,7 @@ export function defaultSpawnWorker({ logPath, fallbackLogPath }, io = defaultSpa
|
|
|
92
92
|
: ['ignore', opened.fd, opened.fd];
|
|
93
93
|
const child = io.spawn(process.execPath, [entry, 'index', 'background', '--worker', ...logArgs], {
|
|
94
94
|
detached: true,
|
|
95
|
+
windowsHide: true,
|
|
95
96
|
stdio,
|
|
96
97
|
});
|
|
97
98
|
if (opened.fd !== null)
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* script needs to see termination, not a success code.
|
|
30
30
|
*/
|
|
31
31
|
import { spawnSync } from "child_process";
|
|
32
|
+
import * as fs from "node:fs";
|
|
32
33
|
import * as path from "path";
|
|
33
34
|
import { resolveBundledAsset } from "./hq-roots.js";
|
|
34
35
|
/**
|
|
@@ -41,6 +42,93 @@ export function interpreterFor(asset) {
|
|
|
41
42
|
const ext = path.extname(asset).toLowerCase();
|
|
42
43
|
return ext === ".mjs" || ext === ".js" || ext === ".cjs" ? "node" : "bash";
|
|
43
44
|
}
|
|
45
|
+
function envValue(env, name) {
|
|
46
|
+
const key = Object.keys(env).find((candidate) => candidate.toLowerCase() === name.toLowerCase());
|
|
47
|
+
return key ? env[key] : undefined;
|
|
48
|
+
}
|
|
49
|
+
function isFile(file, lookupErrors) {
|
|
50
|
+
try {
|
|
51
|
+
return fs.statSync(file).isFile();
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
// Missing PATH candidates are expected during lookup; retain the cause so
|
|
55
|
+
// the final actionable error can expose why no interpreter was resolved.
|
|
56
|
+
lookupErrors.push(error);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function isWithinWindowsDirectory(file, directory) {
|
|
61
|
+
const normalizedFile = path.win32.resolve(file).toLowerCase();
|
|
62
|
+
const normalizedDirectory = path.win32.resolve(directory).toLowerCase();
|
|
63
|
+
return (normalizedFile === normalizedDirectory ||
|
|
64
|
+
normalizedFile.startsWith(`${normalizedDirectory}${path.win32.sep}`));
|
|
65
|
+
}
|
|
66
|
+
function isExcludedWindowsBash(file, env) {
|
|
67
|
+
if (path.win32.basename(file).toLowerCase() !== "bash.exe")
|
|
68
|
+
return false;
|
|
69
|
+
const windowsDir = envValue(env, "SystemRoot") ?? envValue(env, "WINDIR") ?? "C:\\Windows";
|
|
70
|
+
const systemBash = path.win32.resolve(windowsDir, "System32", "bash.exe");
|
|
71
|
+
if (path.win32.resolve(file).toLowerCase() === systemBash.toLowerCase())
|
|
72
|
+
return true;
|
|
73
|
+
const localAppData = envValue(env, "LOCALAPPDATA");
|
|
74
|
+
return Boolean(localAppData &&
|
|
75
|
+
isWithinWindowsDirectory(file, path.win32.resolve(localAppData, "Microsoft", "WindowsApps")));
|
|
76
|
+
}
|
|
77
|
+
function findOnWindowsPath(executable, env, lookupErrors) {
|
|
78
|
+
const pathValue = envValue(env, "PATH") ?? "";
|
|
79
|
+
const extensions = executable.includes(".")
|
|
80
|
+
? [""]
|
|
81
|
+
: (envValue(env, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD")
|
|
82
|
+
.split(";")
|
|
83
|
+
.filter(Boolean)
|
|
84
|
+
.map((ext) => ext.toLowerCase());
|
|
85
|
+
for (const entry of pathValue.split(";").filter(Boolean)) {
|
|
86
|
+
const directory = entry.trim().replace(/^"|"$/g, "");
|
|
87
|
+
for (const extension of extensions) {
|
|
88
|
+
const candidate = path.win32.join(directory, `${executable}${extension}`);
|
|
89
|
+
if (!isExcludedWindowsBash(candidate, env) && isFile(candidate, lookupErrors))
|
|
90
|
+
return candidate;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
function resolveWindowsBash(env) {
|
|
96
|
+
const lookupErrors = [];
|
|
97
|
+
const configured = envValue(env, "CLAUDE_CODE_GIT_BASH_PATH");
|
|
98
|
+
if (configured && !isExcludedWindowsBash(configured, env) && isFile(configured, lookupErrors)) {
|
|
99
|
+
return { executable: configured, cause: lookupErrors.at(-1) };
|
|
100
|
+
}
|
|
101
|
+
const pathBash = findOnWindowsPath("bash", env, lookupErrors);
|
|
102
|
+
if (pathBash)
|
|
103
|
+
return { executable: pathBash, cause: lookupErrors.at(-1) };
|
|
104
|
+
const gitExe = findOnWindowsPath("git.exe", env, lookupErrors);
|
|
105
|
+
if (gitExe) {
|
|
106
|
+
const derived = path.win32.resolve(path.win32.dirname(gitExe), "..", "bin", "bash.exe");
|
|
107
|
+
if (!isExcludedWindowsBash(derived, env) && isFile(derived, lookupErrors)) {
|
|
108
|
+
return { executable: derived, cause: lookupErrors.at(-1) };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const programFiles = envValue(env, "ProgramFiles") ?? "C:\\Program Files";
|
|
112
|
+
const localAppData = envValue(env, "LOCALAPPDATA");
|
|
113
|
+
const standardPaths = [
|
|
114
|
+
path.win32.join(programFiles, "Git", "bin", "bash.exe"),
|
|
115
|
+
...(localAppData ? [path.win32.join(localAppData, "Programs", "Git", "bin", "bash.exe")] : []),
|
|
116
|
+
];
|
|
117
|
+
const executable = standardPaths.find((candidate) => !isExcludedWindowsBash(candidate, env) && isFile(candidate, lookupErrors));
|
|
118
|
+
return {
|
|
119
|
+
executable,
|
|
120
|
+
cause: lookupErrors.at(-1) ??
|
|
121
|
+
Object.assign(new Error("Bash was not found (ENOENT)"), { code: "ENOENT" }),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function bashNotFoundError(asset, cause) {
|
|
125
|
+
const isHandoff = asset.replaceAll("\\", "/").endsWith("core/scripts/handoff-finalize.sh");
|
|
126
|
+
const recovery = isHandoff
|
|
127
|
+
? "The handoff was not saved; rerun the command."
|
|
128
|
+
: "The script did not run; rerun this command.";
|
|
129
|
+
return new Error(`Bash was not found to run bundled script ${asset}. Install Git for Windows or ` +
|
|
130
|
+
`set CLAUDE_CODE_GIT_BASH_PATH. ${recovery}`, { cause });
|
|
131
|
+
}
|
|
44
132
|
/**
|
|
45
133
|
* Execute a bundled scaffold script and return its exit code.
|
|
46
134
|
*
|
|
@@ -56,12 +144,26 @@ export function runBundledScript(opts) {
|
|
|
56
144
|
env.CLAUDE_PROJECT_DIR = opts.hqRoot;
|
|
57
145
|
}
|
|
58
146
|
Object.assign(env, opts.env ?? {});
|
|
59
|
-
const
|
|
147
|
+
const interpreter = interpreterFor(opts.asset);
|
|
148
|
+
const windowsBash = process.platform === "win32" && interpreter === "bash"
|
|
149
|
+
? resolveWindowsBash(env)
|
|
150
|
+
: undefined;
|
|
151
|
+
const executable = windowsBash?.executable ?? interpreter;
|
|
152
|
+
if (windowsBash && !windowsBash.executable) {
|
|
153
|
+
throw bashNotFoundError(opts.asset, windowsBash.cause);
|
|
154
|
+
}
|
|
155
|
+
const result = spawnSync(executable, [script, ...(opts.args ?? [])], {
|
|
60
156
|
cwd: opts.cwd,
|
|
61
157
|
env,
|
|
62
158
|
stdio: "inherit",
|
|
63
159
|
});
|
|
64
160
|
if (result.error) {
|
|
161
|
+
const spawnError = result.error;
|
|
162
|
+
if (process.platform === "win32" &&
|
|
163
|
+
interpreter === "bash" &&
|
|
164
|
+
spawnError.code === "ENOENT") {
|
|
165
|
+
throw bashNotFoundError(opts.asset, spawnError);
|
|
166
|
+
}
|
|
65
167
|
throw new Error(`Failed to run bundled script ${opts.asset}: ${result.error.message}`);
|
|
66
168
|
}
|
|
67
169
|
if (result.signal) {
|
|
@@ -186,6 +186,7 @@ function runUpdateSupervisor(config, dependencies = {}) {
|
|
|
186
186
|
try {
|
|
187
187
|
child = spawn(config.cmd, config.args, {
|
|
188
188
|
detached: true,
|
|
189
|
+
windowsHide: true,
|
|
189
190
|
stdio: ["ignore", "inherit", config.diagnosticMarker ? "pipe" : "inherit"],
|
|
190
191
|
shell: config.shell,
|
|
191
192
|
});
|
|
@@ -637,7 +637,7 @@ export { buildSpawnPlan, quoteForWindowsShell };
|
|
|
637
637
|
* protection silently disappearing.
|
|
638
638
|
*/
|
|
639
639
|
export function inOwnProcessGroup(options) {
|
|
640
|
-
return { ...options, detached: true };
|
|
640
|
+
return { ...options, detached: true, windowsHide: true };
|
|
641
641
|
}
|
|
642
642
|
/** Tail of captured installer stderr kept to explain a failure. */
|
|
643
643
|
const INSTALL_DETAIL_MAX_CHARS = 400;
|