@indigoai-us/hq-cli 5.341.2 → 5.341.3
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 +9 -0
- package/assets/hqd/windows-pipe-host.ps1 +282 -0
- package/dist/commands/billing-sponsor.js +20 -1
- package/dist/commands/core-derive-trigger-facts-native.d.ts +2 -0
- package/dist/commands/core-derive-trigger-facts-native.js +92 -25
- package/dist/commands/core-migrate-policy-triggers-native.d.ts +1 -0
- package/dist/commands/core-migrate-policy-triggers-native.js +26 -12
- package/dist/commands/doctor.js +2 -2
- package/dist/lib/aws-sdk-node-warning-output.js +2 -3
- package/dist/lib/billing/plan-lock.js +19 -2
- package/dist/lib/bot/owner-context.d.ts +2 -0
- package/dist/lib/bot/owner-context.js +19 -1
- package/dist/lib/daemon/flag-monitor.d.ts +5 -0
- package/dist/lib/daemon/flag-monitor.js +14 -1
- package/dist/lib/daemon/protocol.d.ts +26 -3
- package/dist/lib/daemon/protocol.js +9 -5
- package/dist/lib/daemon/run.js +14 -16
- package/dist/lib/daemon/server.d.ts +13 -0
- package/dist/lib/daemon/server.js +283 -28
- package/dist/lib/daemon/windows-pipe-host.d.ts +17 -0
- package/dist/lib/daemon/windows-pipe-host.js +218 -0
- package/dist/lib/diagnostics.d.ts +9 -0
- package/dist/lib/diagnostics.js +12 -0
- package/dist/lib/doctor/checks/anywhere.d.ts +6 -1
- package/dist/lib/doctor/checks/anywhere.js +131 -13
- package/dist/lib/doctor/json-output.d.ts +2 -0
- package/dist/lib/doctor/json-output.js +1 -0
- package/dist/lib/doctor/registry.js +1 -3
- package/dist/lib/doctor/types.d.ts +4 -0
- package/dist/utils/run-bundled-script.d.ts +2 -0
- package/dist/utils/run-bundled-script.js +10 -1
- package/docs/anywhere-runtime.md +32 -5
- package/package.json +2 -1
|
@@ -18,11 +18,12 @@ import { HQ_MCP_SERVER_NAME, SKILL_LINK_PREFIX, claudeTargets } from "../../inst
|
|
|
18
18
|
import { codexTargets } from "../../install/codex-targets.js";
|
|
19
19
|
import { CHATGPT_MODE } from "../../install/chatgpt-targets.js";
|
|
20
20
|
import { GROK_MODE } from "../../install/grok-targets.js";
|
|
21
|
-
import {
|
|
21
|
+
import { HqdClientError, hqdRequest } from "../../daemon/protocol.js";
|
|
22
22
|
import { daemonPresenceLabel, heartbeatFile, readHeartbeat } from "../../daemon/heartbeat.js";
|
|
23
23
|
import { DAEMON_LAUNCHD_LABEL, DAEMON_SYSTEMD_UNIT, DAEMON_WINDOWS_TASK } from "../../daemon/install.js";
|
|
24
24
|
import { hqdSocketPath } from "../../daemon/protocol.js";
|
|
25
25
|
import { readRegistry, registryDir, registryFile } from "../../registry/registry.js";
|
|
26
|
+
import { anywhereRuntimeEnabled } from "../../../commands/anywhere-runtime-flag.js";
|
|
26
27
|
export const ANYWHERE_FAMILY_ID = "anywhere";
|
|
27
28
|
export const REMEDIATION = {
|
|
28
29
|
installClaude: "hq install --global --runtime claude",
|
|
@@ -38,9 +39,69 @@ export const anywhereFamily = createAnywhereFamily();
|
|
|
38
39
|
function result(status, checkId, message, remediation, target) {
|
|
39
40
|
return { status, checkId: `anywhere.${checkId}`, message, ...(remediation ? { remediation } : {}), ...(target ? { target } : {}) };
|
|
40
41
|
}
|
|
41
|
-
export async function runAnywhereChecks(
|
|
42
|
+
export async function runAnywhereChecks(context, deps = {}) {
|
|
42
43
|
const home = deps.home ?? os.homedir();
|
|
43
44
|
const env = deps.env ?? process.env;
|
|
45
|
+
const socketPath = hqdSocketPath(home, env);
|
|
46
|
+
const cwd = context.cwd ?? process.cwd();
|
|
47
|
+
const runtimeEnabled = (deps.runtimeEnabled ?? anywhereRuntimeEnabled)();
|
|
48
|
+
let health;
|
|
49
|
+
let healthUnsupported = false;
|
|
50
|
+
try {
|
|
51
|
+
if (deps.health) {
|
|
52
|
+
health = await deps.health(cwd);
|
|
53
|
+
}
|
|
54
|
+
else if (deps.ping) {
|
|
55
|
+
const version = await deps.ping();
|
|
56
|
+
health = {
|
|
57
|
+
reachable: true,
|
|
58
|
+
version,
|
|
59
|
+
uptimeMs: null,
|
|
60
|
+
flag: { enabled: runtimeEnabled, lastSuccessfulReadAgeMs: null, heldThroughReadError: false },
|
|
61
|
+
resolution: { scope: "personal", company: null, fallbackReason: "no_match" },
|
|
62
|
+
socket: { path: socketPath, transport: process.platform === "win32" ? "windows_named_pipe" : "unix_socket", mode: null, ownerMatchesUser: null, userOnly: null },
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
health = await hqdRequest("health", { cwd }, { socketPath });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error instanceof HqdClientError && error.code === "unknown_op") {
|
|
71
|
+
try {
|
|
72
|
+
let version = null;
|
|
73
|
+
let uptimeMs = null;
|
|
74
|
+
if (deps.ping) {
|
|
75
|
+
version = await deps.ping();
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const ping = await hqdRequest("ping", {}, { socketPath });
|
|
79
|
+
if (typeof ping.version === "string")
|
|
80
|
+
version = ping.version;
|
|
81
|
+
if (typeof ping.uptimeMs === "number")
|
|
82
|
+
uptimeMs = ping.uptimeMs;
|
|
83
|
+
}
|
|
84
|
+
health = {
|
|
85
|
+
reachable: true,
|
|
86
|
+
version,
|
|
87
|
+
uptimeMs,
|
|
88
|
+
flag: { enabled: null, lastSuccessfulReadAgeMs: null, heldThroughReadError: false },
|
|
89
|
+
resolution: { scope: "unknown", company: null, fallbackReason: null },
|
|
90
|
+
socket: { path: socketPath, transport: process.platform === "win32" ? "windows_named_pipe" : "unix_socket", mode: null, ownerMatchesUser: null, userOnly: null },
|
|
91
|
+
};
|
|
92
|
+
healthUnsupported = true;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
health = unreachableHealth(socketPath);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
health = unreachableHealth(socketPath);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const healthCheck = runtimeHealthCheck(health, healthUnsupported);
|
|
103
|
+
if (!runtimeEnabled)
|
|
104
|
+
return [healthCheck];
|
|
44
105
|
const claude = claudeTargets(home);
|
|
45
106
|
const codex = codexTargets(home);
|
|
46
107
|
const installed = [claude.hqPointer, claude.stateFile, codex.stateFile].some((p) => fs.existsSync(p));
|
|
@@ -48,10 +109,10 @@ export async function runAnywhereChecks(_context, deps = {}) {
|
|
|
48
109
|
result("WARN", "chatgpt-mode", `ChatGPT integration mode: ${CHATGPT_MODE}; host connector setup is managed in ChatGPT`, "hq install --global --runtime chatgpt"),
|
|
49
110
|
result("WARN", "grok-mode", `Grok integration mode: ${GROK_MODE}; host connector setup is managed in Grok`, "hq install --global --runtime grok"),
|
|
50
111
|
];
|
|
112
|
+
const out = [healthCheck, ...remoteModes];
|
|
51
113
|
if (!installed) {
|
|
52
|
-
return [...
|
|
114
|
+
return [...out, result("NA", "installed", "HQ local anywhere runtime is not installed on this machine", REMEDIATION.installClaude)];
|
|
53
115
|
}
|
|
54
|
-
const out = [...remoteModes];
|
|
55
116
|
const pluginInstall = readClaudePluginInstall(claude.stateFile);
|
|
56
117
|
out.push(checkInstallMode(claude.stateFile));
|
|
57
118
|
out.push(checkPointer(claude.hqPointer));
|
|
@@ -63,16 +124,11 @@ export async function runAnywhereChecks(_context, deps = {}) {
|
|
|
63
124
|
out.push(result("FAIL", "daemon-installed", `daemon service is installed but not loaded (${service.detail})`, REMEDIATION.daemonRestart));
|
|
64
125
|
else
|
|
65
126
|
out.push(result("PASS", "daemon-installed", `daemon service is installed and loaded (${service.detail})`));
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
let running = null;
|
|
69
|
-
try {
|
|
70
|
-
running = await ping();
|
|
127
|
+
const running = health.reachable ? health.version : null;
|
|
128
|
+
if (health.reachable)
|
|
71
129
|
out.push(result("PASS", "socket", `hqd answered on ${socketPath}`, undefined, socketPath));
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
out.push(result("FAIL", "socket", `hqd is not reachable: ${err instanceof Error ? err.message : String(err)}`, REMEDIATION.daemonInstall, socketPath));
|
|
75
|
-
}
|
|
130
|
+
else
|
|
131
|
+
out.push(result("FAIL", "socket", `hqd is not reachable on ${socketPath}`, REMEDIATION.daemonInstall, socketPath));
|
|
76
132
|
const cliVersion = deps.cliVersion ?? CLI_VERSION;
|
|
77
133
|
if (running === null)
|
|
78
134
|
out.push(result("FAIL", "version", `cannot compare versions: hqd did not answer (hq-cli is ${cliVersion})`, REMEDIATION.daemonInstall));
|
|
@@ -96,6 +152,68 @@ export async function runAnywhereChecks(_context, deps = {}) {
|
|
|
96
152
|
out.push(checkSkillLinks("codex", codex.skillsDir, REMEDIATION.installCodex));
|
|
97
153
|
return out;
|
|
98
154
|
}
|
|
155
|
+
function unreachableHealth(socketPath) {
|
|
156
|
+
return {
|
|
157
|
+
reachable: false,
|
|
158
|
+
version: null,
|
|
159
|
+
uptimeMs: null,
|
|
160
|
+
flag: { enabled: null, lastSuccessfulReadAgeMs: null, heldThroughReadError: false },
|
|
161
|
+
resolution: { scope: "unknown", company: null, fallbackReason: null },
|
|
162
|
+
socket: { path: socketPath, transport: process.platform === "win32" ? "windows_named_pipe" : "unix_socket", mode: null, ownerMatchesUser: null, userOnly: null },
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function runtimeHealthCheck(health, healthUnsupported = false) {
|
|
166
|
+
const { flag, resolution, socket } = health;
|
|
167
|
+
const age = flag.lastSuccessfulReadAgeMs === null
|
|
168
|
+
? "unknown"
|
|
169
|
+
: `${new Intl.NumberFormat("en-US").format(flag.lastSuccessfulReadAgeMs)} ms`;
|
|
170
|
+
const flagLabel = flag.enabled === null ? "unknown" : flag.enabled ? "on" : "off";
|
|
171
|
+
const binding = resolution.scope === "company"
|
|
172
|
+
? `company ${resolution.company}`
|
|
173
|
+
: resolution.scope === "personal"
|
|
174
|
+
? `personal (fallback: ${resolution.fallbackReason ?? "unspecified"})`
|
|
175
|
+
: health.reachable && healthUnsupported
|
|
176
|
+
? "unknown (resident daemon lacks the health operation)"
|
|
177
|
+
: "unknown (daemon unavailable)";
|
|
178
|
+
const socketSecurity = socket.transport === "windows_named_pipe"
|
|
179
|
+
? "Windows named pipe (mode and owner are not reported)"
|
|
180
|
+
: `mode ${socket.mode ?? "unknown"}; owner matches current user: ${socket.ownerMatchesUser === null ? "unknown" : socket.ownerMatchesUser ? "yes" : "no"}; user-only: ${socket.userOnly === null ? "unknown" : socket.userOnly ? "yes" : "no"}`;
|
|
181
|
+
const unreachableMessage = socket.transport === "windows_named_pipe"
|
|
182
|
+
? `hqd is not reachable on ${socket.path}; Windows daemon startup is refused because named-pipe ACLs are unsupported`
|
|
183
|
+
: `hqd is not reachable on ${socket.path}; version, uptime, flag state, and cwd binding are unavailable`;
|
|
184
|
+
const socketNotUserOnly = health.reachable && socket.transport === "unix_socket" && (socket.userOnly !== true || socket.ownerMatchesUser !== true);
|
|
185
|
+
const warningNotes = [
|
|
186
|
+
healthUnsupported ? "resident hqd does not support detailed health; restart hqd for full diagnostics" : null,
|
|
187
|
+
socketNotUserOnly ? "socket is not confirmed user-only" : null,
|
|
188
|
+
].filter((note) => note !== null);
|
|
189
|
+
const message = health.reachable
|
|
190
|
+
? `hqd reachable; version ${health.version ?? "unknown"}; uptime ${health.uptimeMs === null ? "unknown" : `${new Intl.NumberFormat("en-US").format(health.uptimeMs)} ms`}; runtime flag ${flagLabel}; last successful flag read ${age} ago; held through read error: ${flag.heldThroughReadError ? "yes" : "no"}; cwd binding ${binding}; socket ${socket.path}; ${socketSecurity}${warningNotes.length ? `; ${warningNotes.join("; ")}` : ""}`
|
|
191
|
+
: unreachableMessage;
|
|
192
|
+
const remediation = healthUnsupported || socketNotUserOnly ? REMEDIATION.daemonRestart : undefined;
|
|
193
|
+
return {
|
|
194
|
+
status: health.reachable && warningNotes.length === 0 ? "PASS" : "WARN",
|
|
195
|
+
checkId: "anywhere.runtime-health",
|
|
196
|
+
target: socket.path,
|
|
197
|
+
message,
|
|
198
|
+
...(remediation ? { remediation } : {}),
|
|
199
|
+
details: {
|
|
200
|
+
reachable: health.reachable,
|
|
201
|
+
version: health.version,
|
|
202
|
+
uptimeMs: health.uptimeMs,
|
|
203
|
+
flagEnabled: flag.enabled,
|
|
204
|
+
lastSuccessfulFlagReadAgeMs: flag.lastSuccessfulReadAgeMs,
|
|
205
|
+
flagHeldThroughReadError: flag.heldThroughReadError,
|
|
206
|
+
resolvedScope: resolution.scope,
|
|
207
|
+
company: resolution.company,
|
|
208
|
+
fallbackReason: resolution.fallbackReason,
|
|
209
|
+
socketPath: socket.path,
|
|
210
|
+
socketTransport: socket.transport,
|
|
211
|
+
socketMode: socket.mode,
|
|
212
|
+
socketOwnerMatchesUser: socket.ownerMatchesUser,
|
|
213
|
+
socketUserOnly: socket.userOnly,
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
}
|
|
99
217
|
function checkInstallMode(file) {
|
|
100
218
|
try {
|
|
101
219
|
const state = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
@@ -58,6 +58,8 @@ export interface DoctorJsonResult {
|
|
|
58
58
|
target?: string;
|
|
59
59
|
/** Human-readable explanation. */
|
|
60
60
|
message: string;
|
|
61
|
+
/** Safe structured diagnostic fields, when a check provides them. */
|
|
62
|
+
details?: Record<string, unknown>;
|
|
61
63
|
/** Remediation hint. Present only when the result carries one. */
|
|
62
64
|
remediation?: string;
|
|
63
65
|
/** Structured remediation (US-011). Present on actionable findings only. */
|
|
@@ -60,6 +60,7 @@ function toJsonResult(familyId, result, clientHealthReasonCodesEnabledCheckIds)
|
|
|
60
60
|
: {}),
|
|
61
61
|
...(result.target !== undefined ? { target: result.target } : {}),
|
|
62
62
|
message: result.message,
|
|
63
|
+
...(result.details !== undefined ? { details: result.details } : {}),
|
|
63
64
|
...(result.remediation !== undefined
|
|
64
65
|
? { remediation: result.remediation }
|
|
65
66
|
: {}),
|
|
@@ -27,7 +27,6 @@ import { anywhereFamily } from "./checks/anywhere.js";
|
|
|
27
27
|
import { scaffoldCliFloorFamily } from "./checks/scaffold-cli-floor.js";
|
|
28
28
|
import { fixtureCoverageFamily } from "./fixtures/discover.js";
|
|
29
29
|
import { checkClaudeWiring } from "./checks/claude-wiring.js";
|
|
30
|
-
import { anywhereRuntimeEnabled } from "../../commands/anywhere-runtime-flag.js";
|
|
31
30
|
/**
|
|
32
31
|
* An ordered, id-keyed set of check families. Registration order is preserved
|
|
33
32
|
* (Map iteration order), and re-registering an id replaces the family in place
|
|
@@ -266,8 +265,7 @@ export function createDefaultRegistry() {
|
|
|
266
265
|
registry.register(botsFamily);
|
|
267
266
|
// HQ anywhere (US-012): pointer, registry, hqd service/socket/version,
|
|
268
267
|
// heartbeat, MCP registrations and skill links. NA when not installed.
|
|
269
|
-
|
|
270
|
-
registry.register(anywhereFamily);
|
|
268
|
+
registry.register(anywhereFamily);
|
|
271
269
|
return registry;
|
|
272
270
|
}
|
|
273
271
|
//# sourceMappingURL=registry.js.map
|
|
@@ -35,6 +35,8 @@ export interface CheckResult {
|
|
|
35
35
|
target?: string;
|
|
36
36
|
/** Human-readable one-line explanation of the result. */
|
|
37
37
|
message: string;
|
|
38
|
+
/** Safe structured fields for machine-readable results. */
|
|
39
|
+
details?: Record<string, unknown>;
|
|
38
40
|
/** Optional remediation hint (a command or instruction). */
|
|
39
41
|
remediation?: string;
|
|
40
42
|
}
|
|
@@ -47,6 +49,8 @@ export interface CheckResult {
|
|
|
47
49
|
export interface CheckContext {
|
|
48
50
|
/** Absolute, resolved HQ tree root every check reads from. */
|
|
49
51
|
hqRoot: string;
|
|
52
|
+
/** Original caller working directory, used only for company/personal binding diagnostics. */
|
|
53
|
+
cwd?: string;
|
|
50
54
|
/**
|
|
51
55
|
* The detected host platform (id, and optionally the evidence behind it).
|
|
52
56
|
* Host-specific live checks — the US-006 runtime probe — key their
|
|
@@ -51,6 +51,8 @@ export type RunBundledScriptOptions = {
|
|
|
51
51
|
hqRoot?: string;
|
|
52
52
|
/** Extra environment for the child, applied last. */
|
|
53
53
|
env?: Record<string, string | undefined>;
|
|
54
|
+
/** Convert the script path for Git Bash when the script resolves sibling assets from BASH_SOURCE. */
|
|
55
|
+
msysScriptPath?: boolean;
|
|
54
56
|
/** Capture stdout and stderr as bytes instead of inheriting those streams. */
|
|
55
57
|
captureOutput?: boolean;
|
|
56
58
|
/** Bytes supplied on stdin. With no value, stdin is inherited as before. */
|
|
@@ -44,6 +44,14 @@ export function interpreterFor(asset) {
|
|
|
44
44
|
const ext = path.extname(asset).toLowerCase();
|
|
45
45
|
return ext === ".mjs" || ext === ".js" || ext === ".cjs" ? "node" : "bash";
|
|
46
46
|
}
|
|
47
|
+
/** Git Bash expects drive paths in MSYS form when an interpreter arg is a script path. */
|
|
48
|
+
function scriptPathForBash(script) {
|
|
49
|
+
if (process.platform !== "win32")
|
|
50
|
+
return script;
|
|
51
|
+
const normalized = script.replaceAll("\\", "/");
|
|
52
|
+
const drivePath = normalized.match(/^([A-Za-z]):\/(.*)$/);
|
|
53
|
+
return drivePath ? `/${drivePath[1].toLowerCase()}/${drivePath[2]}` : normalized;
|
|
54
|
+
}
|
|
47
55
|
function envValue(env, name) {
|
|
48
56
|
const key = Object.keys(env).find((candidate) => candidate.toLowerCase() === name.toLowerCase());
|
|
49
57
|
return key ? env[key] : undefined;
|
|
@@ -176,7 +184,8 @@ export function runBundledScript(opts) {
|
|
|
176
184
|
: inputDescriptor !== undefined
|
|
177
185
|
? [stdinStdio, "inherit", "inherit"]
|
|
178
186
|
: "inherit";
|
|
179
|
-
|
|
187
|
+
const scriptArg = interpreter === "bash" && opts.msysScriptPath ? scriptPathForBash(script) : script;
|
|
188
|
+
result = spawnSync(executable, [scriptArg, ...(opts.args ?? [])], {
|
|
180
189
|
cwd: opts.cwd,
|
|
181
190
|
env,
|
|
182
191
|
stdio,
|
package/docs/anywhere-runtime.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# HQ Anywhere runtime
|
|
2
2
|
|
|
3
3
|
HQ Anywhere installs global hooks for supported agent runtimes and uses the
|
|
4
|
-
local hqd daemon on macOS and
|
|
5
|
-
|
|
4
|
+
local hqd daemon on macOS, Linux, and Windows. On Windows, hqd uses a bundled
|
|
5
|
+
PowerShell pipe host that applies and verifies a user-only named-pipe DACL
|
|
6
|
+
before becoming ready. A per-user
|
|
6
7
|
registry links repositories to HQ companies. The `hq-anywhere-runtime` flag
|
|
7
8
|
controls these features and is off by default.
|
|
8
9
|
|
|
@@ -26,9 +27,19 @@ The CLI stores the HQ root at `~/.hq/root` and keeps the folder registry in
|
|
|
26
27
|
`~/.hq/registry.json`. These files belong to the current host. They are not
|
|
27
28
|
stored in a repository or synced HQ folder.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
Windows requires Windows PowerShell 5.1 or PowerShell 7 for the bundled pipe
|
|
31
|
+
host. If it is unavailable, the pipe cannot be created with a verified
|
|
32
|
+
current-user-only DACL, or another process already owns the pipe name, hqd
|
|
33
|
+
refuses to start. The `hq-anywhere-runtime` flag remains off by default on all
|
|
34
|
+
platforms.
|
|
35
|
+
|
|
36
|
+
On macOS and Linux, hqd checks the socket directory and socket path with
|
|
37
|
+
`lstat` before serving. It refuses symlinked, shared, or foreign-owned paths.
|
|
38
|
+
The default socket is under `~/.hq/daemon/`, separate from the registry directory;
|
|
39
|
+
a directory created for the socket is set to `0700`. hqd replaces a stale
|
|
40
|
+
socket only when the current user owns it, then verifies the listening socket
|
|
41
|
+
is `0600`. If a check fails, hqd reports the path and stops without removing an
|
|
42
|
+
unexpected file.
|
|
32
43
|
|
|
33
44
|
When the flag is enabled, the global hook uses hqd for events outside the HQ
|
|
34
45
|
root. Inside the root, the project hook routes through hqd when it is running
|
|
@@ -51,6 +62,22 @@ An authentication still in progress when revocation arrives fails cleanly;
|
|
|
51
62
|
hosted MCP calls already forwarded are allowed to finish or return their normal
|
|
52
63
|
request error. The daemon process itself does not terminate.
|
|
53
64
|
|
|
65
|
+
## Diagnose the runtime
|
|
66
|
+
|
|
67
|
+
`hq doctor` reports hqd reachability, version and uptime, the last successful
|
|
68
|
+
runtime-flag read and its age, and whether hqd is holding that decision after a
|
|
69
|
+
read error. It also reports the company selected for the current directory or
|
|
70
|
+
the reason it fell back to personal context. On Unix, the socket line includes
|
|
71
|
+
its permission mode, owner check and whether it is user-only. Windows reports
|
|
72
|
+
the named-pipe transport without Unix mode or owner fields. Use `hq doctor
|
|
73
|
+
--json` for the same fields as structured details. The hqd health operation is
|
|
74
|
+
read-only and available while the runtime flag is off; it reports only the
|
|
75
|
+
current directory's binding and never returns authentication tokens. A Unix
|
|
76
|
+
socket that cannot be verified as user-only produces a warning. If an older
|
|
77
|
+
resident daemon does not support the health operation, doctor falls back to
|
|
78
|
+
`ping` for reachability, version and uptime, then warns that a restart is needed
|
|
79
|
+
for full diagnostics.
|
|
80
|
+
|
|
54
81
|
## Link a repository
|
|
55
82
|
|
|
56
83
|
Run `hq link <company>` from a repository to associate it with a company. The
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indigoai-us/hq-cli",
|
|
3
|
-
"version": "5.341.
|
|
3
|
+
"version": "5.341.3",
|
|
4
4
|
"description": "HQ by Indigo management CLI — modules and cloud sync",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"assets/scaffold",
|
|
14
14
|
"assets/bot-workers",
|
|
15
15
|
"assets/mesh-daemon",
|
|
16
|
+
"assets/hqd",
|
|
16
17
|
"assets/lanes-reconcile",
|
|
17
18
|
"assets/lanes-hooks",
|
|
18
19
|
"templates",
|