@indigoai-us/hq-cli 5.308.0 → 5.309.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.
Files changed (95) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/command-catalog.generated.d.ts +4 -1
  3. package/dist/command-catalog.generated.js +5 -1
  4. package/dist/commands/agents.js +6 -0
  5. package/dist/commands/core-checkpoint-gate-setting.d.ts +0 -10
  6. package/dist/commands/core-checkpoint-gate-setting.js +3 -3
  7. package/dist/commands/core-ontology.d.ts +1 -9
  8. package/dist/commands/core-ontology.js +4 -4
  9. package/dist/commands/core-policy.d.ts +0 -3
  10. package/dist/commands/core-policy.js +3 -3
  11. package/dist/commands/files.js +1 -1
  12. package/dist/commands/index-cmd.js +1 -1
  13. package/dist/commands/integrations-api.d.ts +9 -4
  14. package/dist/commands/integrations-api.js +9 -6
  15. package/dist/commands/integrations-manage.js +11 -3
  16. package/dist/commands/integrations.d.ts +8 -0
  17. package/dist/commands/integrations.js +83 -0
  18. package/dist/commands/lanes-checks.d.ts +6 -2
  19. package/dist/commands/lanes-checks.js +69 -19
  20. package/dist/commands/lanes-report.js +5 -2
  21. package/dist/commands/lanes.d.ts +0 -11
  22. package/dist/commands/lanes.js +6 -6
  23. package/dist/commands/mcp-registration.d.ts +5 -11
  24. package/dist/commands/mcp-registration.js +2 -6
  25. package/dist/lib/core-utils/sentry-report.d.ts +5 -11
  26. package/dist/lib/core-utils/sentry-report.js +2 -2
  27. package/dist/lib/db/local.d.ts +0 -5
  28. package/dist/lib/db/local.js +1 -1
  29. package/dist/lib/db/migrate.d.ts +0 -12
  30. package/dist/lib/db/migrate.js +5 -5
  31. package/dist/lib/db/sql.d.ts +0 -10
  32. package/dist/lib/db/sql.js +4 -8
  33. package/dist/lib/doctor/checks/codex-wiring.d.ts +0 -4
  34. package/dist/lib/doctor/checks/codex-wiring.js +3 -35
  35. package/dist/lib/doctor/checks/grok-wiring.js +1 -34
  36. package/dist/lib/doctor/checks/runtime-health.d.ts +0 -17
  37. package/dist/lib/doctor/checks/runtime-health.js +4 -4
  38. package/dist/lib/doctor/checks/scaffold-cli-floor.d.ts +0 -1
  39. package/dist/lib/doctor/checks/scaffold-cli-floor.js +1 -1
  40. package/dist/lib/doctor/compat.d.ts +0 -16
  41. package/dist/lib/doctor/compat.js +3 -3
  42. package/dist/lib/doctor/deep/effects.js +1 -3
  43. package/dist/lib/doctor/deep/sandbox.js +1 -3
  44. package/dist/lib/doctor/fixtures/schema.js +1 -3
  45. package/dist/lib/doctor/platform.d.ts +0 -26
  46. package/dist/lib/doctor/platform.js +5 -5
  47. package/dist/lib/doctor/shared.d.ts +8 -0
  48. package/dist/lib/doctor/shared.js +38 -0
  49. package/dist/lib/lanes/autopilot.js +125 -103
  50. package/dist/lib/monitor.d.ts +2 -6
  51. package/dist/lib/monitor.js +5 -5
  52. package/dist/lib/onboarding/errors.d.ts +2 -1
  53. package/dist/lib/onboarding/errors.js +1 -1
  54. package/dist/lib/onboarding/index.d.ts +2 -6
  55. package/dist/lib/onboarding/index.js +2 -5
  56. package/dist/lib/report-publish.d.ts +1 -10
  57. package/dist/lib/report-publish.js +3 -9
  58. package/dist/lib/search-index/embed-lock.d.ts +0 -7
  59. package/dist/lib/search-index/embed-lock.js +1 -1
  60. package/dist/lib/search-index/index.d.ts +7 -0
  61. package/dist/lib/search-index/index.js +21 -2
  62. package/dist/lib/search-index/load-gate.d.ts +0 -8
  63. package/dist/lib/search-index/load-gate.js +3 -3
  64. package/dist/lib/search-index/max-doc-bytes.d.ts +2 -3
  65. package/dist/lib/search-index/max-doc-bytes.js +1 -1
  66. package/dist/lib/search-index/qmd-exit-diagnostics.d.ts +5 -0
  67. package/dist/lib/search-index/qmd-exit-diagnostics.js +40 -0
  68. package/dist/lib/service-manager/launchd.d.ts +0 -7
  69. package/dist/lib/service-manager/launchd.js +2 -2
  70. package/dist/main.js +7 -2
  71. package/dist/startup-registration.js +9 -1
  72. package/dist/utils/client-health.d.ts +0 -4
  73. package/dist/utils/client-health.js +2 -2
  74. package/dist/utils/feedback-diagnostics.d.ts +2 -1
  75. package/dist/utils/feedback-log-bundle.d.ts +0 -25
  76. package/dist/utils/feedback-log-bundle.js +5 -5
  77. package/dist/utils/feedback-logs.d.ts +4 -38
  78. package/dist/utils/feedback-logs.js +7 -7
  79. package/dist/utils/feedback-screenshots.d.ts +0 -1
  80. package/dist/utils/feedback-screenshots.js +1 -1
  81. package/dist/utils/install-tree-torn.d.ts +19 -13
  82. package/dist/utils/install-tree-torn.js +77 -2
  83. package/dist/utils/local-files-overview.d.ts +0 -6
  84. package/dist/utils/local-files-overview.js +1 -1
  85. package/dist/utils/qmd-model-download-error.d.ts +0 -8
  86. package/dist/utils/qmd-model-download-error.js +1 -1
  87. package/dist/utils/qmd-query-document-error.d.ts +0 -6
  88. package/dist/utils/qmd-query-document-error.js +1 -1
  89. package/dist/utils/scaffold-fast-import-guard.d.ts +0 -1
  90. package/dist/utils/scaffold-fast-import-guard.js +1 -1
  91. package/dist/utils/scaffold-sibling-references.d.ts +3 -2
  92. package/dist/utils/sentry-fingerprint.js +17 -0
  93. package/dist/utils/version-gate.d.ts +4 -0
  94. package/dist/utils/version-gate.js +13 -0
  95. package/package.json +1 -1
@@ -42,11 +42,12 @@
42
42
  import * as fs from "node:fs";
43
43
  import * as path from "node:path";
44
44
  import { parse as parseToml } from "smol-toml";
45
+ import { collectCommands, fileState } from "../shared.js";
45
46
  import { ALLOWED_DIVERGENCE_RELPATH, loadAllowedDivergence, } from "../allowed-divergence.js";
46
47
  /** Basename of the single-adapter script the current architecture routes to. */
47
- export const CODEX_ADAPTER_BASENAME = "hq-codex-hook-adapter.sh";
48
+ const CODEX_ADAPTER_BASENAME = "hq-codex-hook-adapter.sh";
48
49
  /** Library the adapter sources to dispatch `.claude/settings.json` live. */
49
- export const CODEX_DISPATCH_LIB_RELPATH = path.join("core", "scripts", "lib", "hook-adapter-core.sh");
50
+ const CODEX_DISPATCH_LIB_RELPATH = path.join("core", "scripts", "lib", "hook-adapter-core.sh");
50
51
  /**
51
52
  * Lifecycle events the shipped `.codex/config.toml` routes through the adapter.
52
53
  * A missing event means the Claude hooks for that event never run under Codex.
@@ -549,44 +550,11 @@ function extractBraceBlock(source, from) {
549
550
  return source.slice(open + 1);
550
551
  }
551
552
  // --- shared low-level helpers --------------------------------------------------
552
- /** Collect every `command` string from a `{hooks:{Event:[{hooks:[…]}]}}` doc. */
553
- function collectCommands(parsed) {
554
- const commands = [];
555
- if (!parsed || typeof parsed !== "object")
556
- return commands;
557
- const hooks = parsed.hooks;
558
- if (!hooks || typeof hooks !== "object")
559
- return commands;
560
- for (const entries of Object.values(hooks)) {
561
- if (!Array.isArray(entries))
562
- continue;
563
- for (const entry of entries) {
564
- const inner = entry?.hooks;
565
- if (!Array.isArray(inner))
566
- continue;
567
- for (const hook of inner) {
568
- const command = hook?.command;
569
- if (typeof command === "string")
570
- commands.push(command);
571
- }
572
- }
573
- }
574
- return commands;
575
- }
576
553
  function resolvePath(hqRoot, target) {
577
554
  if (!target)
578
555
  return null;
579
556
  return path.isAbsolute(target) ? target : path.resolve(hqRoot, target);
580
557
  }
581
- function fileState(target) {
582
- try {
583
- const stat = fs.statSync(target);
584
- return { present: stat.isFile(), executable: (stat.mode & 0o111) !== 0 };
585
- }
586
- catch {
587
- return { present: false, executable: false };
588
- }
589
- }
590
558
  function filesEqual(a, b) {
591
559
  try {
592
560
  return fs.readFileSync(a).equals(fs.readFileSync(b));
@@ -22,6 +22,7 @@
22
22
  import * as fs from "node:fs";
23
23
  import * as os from "node:os";
24
24
  import * as path from "node:path";
25
+ import { collectCommands, fileState } from "../shared.js";
25
26
  /** The command a user runs to install the user-global Grok bridge. */
26
27
  export const GROK_TRUST_REMEDIATION = "bash core/scripts/grok-trust.sh";
27
28
  /** Files that grok-trust.sh installs into `~/.grok/hooks/` for the bridge. */
@@ -149,38 +150,4 @@ function bridgeInstalled(bridgeDir) {
149
150
  }
150
151
  return false;
151
152
  }
152
- // --- shared low-level helpers --------------------------------------------------
153
- /** Collect every `command` string from a `{hooks:{Event:[{hooks:[…]}]}}` doc. */
154
- function collectCommands(parsed) {
155
- const commands = [];
156
- if (!parsed || typeof parsed !== "object")
157
- return commands;
158
- const hooks = parsed.hooks;
159
- if (!hooks || typeof hooks !== "object")
160
- return commands;
161
- for (const entries of Object.values(hooks)) {
162
- if (!Array.isArray(entries))
163
- continue;
164
- for (const entry of entries) {
165
- const inner = entry?.hooks;
166
- if (!Array.isArray(inner))
167
- continue;
168
- for (const hook of inner) {
169
- const command = hook?.command;
170
- if (typeof command === "string")
171
- commands.push(command);
172
- }
173
- }
174
- }
175
- return commands;
176
- }
177
- function fileState(target) {
178
- try {
179
- const stat = fs.statSync(target);
180
- return { present: stat.isFile(), executable: (stat.mode & 0o111) !== 0 };
181
- }
182
- catch {
183
- return { present: false, executable: false };
184
- }
185
- }
186
153
  //# sourceMappingURL=grok-wiring.js.map
@@ -28,16 +28,6 @@
28
28
  import type { CheckContext, CheckFamily, CheckResult } from "../types.js";
29
29
  /** The id of the AI-runtime-health family. */
30
30
  export declare const RUNTIMES_FAMILY_ID = "runtimes";
31
- /** Common id prefix for every result this family emits. */
32
- export declare const RUNTIMES_PREFIX = "runtimes";
33
- /**
34
- * The deterministic one-line probe prompt. Health is proven by a round-trip
35
- * (exit 0 plus non-empty output), not by exact-matching the reply, so a model
36
- * that answers with anything at all still passes.
37
- */
38
- export declare const PROBE_PROMPT = "Reply with exactly: OK";
39
- /** How long each live probe may run before it is killed and marked UNKNOWN. */
40
- export declare const DEFAULT_PROBE_TIMEOUT_MS = 120000;
41
31
  /** One AI runtime the doctor knows how to find and probe. */
42
32
  export interface RuntimeSpec {
43
33
  /** Stable key used in check ids, e.g. `runtimes.codex.binary`. */
@@ -94,11 +84,4 @@ export interface RuntimeHealthDeps {
94
84
  export declare function checkRuntimeHealth(context: CheckContext, deps?: RuntimeHealthDeps): Promise<CheckResult[]>;
95
85
  /** The registered family object. */
96
86
  export declare const runtimeHealthFamily: CheckFamily;
97
- /**
98
- * Resolve an executable name against PATH with a pure filesystem scan — no
99
- * process is spawned, keeping the doctor's default run a function of on-disk
100
- * shape. First PATH entry containing an executable regular file wins, which is
101
- * exactly the copy a shell would run.
102
- */
103
- export declare function resolveOnPath(binary: string): string | null;
104
87
  //# sourceMappingURL=runtime-health.d.ts.map
@@ -33,15 +33,15 @@ import { planCommandSpawn } from "../../../utils/windows-spawn.js";
33
33
  /** The id of the AI-runtime-health family. */
34
34
  export const RUNTIMES_FAMILY_ID = "runtimes";
35
35
  /** Common id prefix for every result this family emits. */
36
- export const RUNTIMES_PREFIX = "runtimes";
36
+ const RUNTIMES_PREFIX = "runtimes";
37
37
  /**
38
38
  * The deterministic one-line probe prompt. Health is proven by a round-trip
39
39
  * (exit 0 plus non-empty output), not by exact-matching the reply, so a model
40
40
  * that answers with anything at all still passes.
41
41
  */
42
- export const PROBE_PROMPT = "Reply with exactly: OK";
42
+ const PROBE_PROMPT = "Reply with exactly: OK";
43
43
  /** How long each live probe may run before it is killed and marked UNKNOWN. */
44
- export const DEFAULT_PROBE_TIMEOUT_MS = 120_000;
44
+ const DEFAULT_PROBE_TIMEOUT_MS = 120_000;
45
45
  /**
46
46
  * The three runtimes HQ wires hooks for. Codex runs its probe under its own
47
47
  * read-only sandbox and outside-a-repo mode so the probe can never write; the
@@ -243,7 +243,7 @@ export const runtimeHealthFamily = {
243
243
  * shape. First PATH entry containing an executable regular file wins, which is
244
244
  * exactly the copy a shell would run.
245
245
  */
246
- export function resolveOnPath(binary) {
246
+ function resolveOnPath(binary) {
247
247
  const pathVar = process.env.PATH ?? "";
248
248
  for (const dir of pathVar.split(path.delimiter)) {
249
249
  if (!dir)
@@ -1,6 +1,5 @@
1
1
  import type { CheckContext, CheckFamily, CheckResult } from "../types.js";
2
2
  export declare const SCAFFOLD_CLI_FLOOR_FAMILY_ID = "scaffold-cli-floor";
3
- export declare const SCAFFOLD_CLI_FLOOR_FAMILY_TITLE = "Scaffold CLI compatibility";
4
3
  export declare const SCAFFOLD_CLI_FLOOR_CHECK_ID = "scaffold-cli-floor.requires-hq-cli";
5
4
  export declare const scaffoldCliFloorFamily: CheckFamily;
6
5
  export declare function checkScaffoldCliFloor(context: CheckContext): CheckResult[];
@@ -4,7 +4,7 @@ import * as yaml from "js-yaml";
4
4
  import { CLI_VERSION } from "../../../cli-version.js";
5
5
  import { compareScaffoldCliFloor } from "../../scaffold-cli-floor.js";
6
6
  export const SCAFFOLD_CLI_FLOOR_FAMILY_ID = "scaffold-cli-floor";
7
- export const SCAFFOLD_CLI_FLOOR_FAMILY_TITLE = "Scaffold CLI compatibility";
7
+ const SCAFFOLD_CLI_FLOOR_FAMILY_TITLE = "Scaffold CLI compatibility";
8
8
  export const SCAFFOLD_CLI_FLOOR_CHECK_ID = "scaffold-cli-floor.requires-hq-cli";
9
9
  export const scaffoldCliFloorFamily = {
10
10
  id: SCAFFOLD_CLI_FLOOR_FAMILY_ID,
@@ -31,22 +31,6 @@ import type { DoctorJsonDocument } from "./json-output.js";
31
31
  export declare const CHECK_HQ_HOOKS_PASS_EXIT = 0;
32
32
  /** Exit code check-hq-hooks.sh returns on a health failure. Preserved. */
33
33
  export declare const CHECK_HQ_HOOKS_FAIL_EXIT = 2;
34
- /** Exit code check-hq-hooks.sh returns on a usage error. Preserved. */
35
- export declare const CHECK_HQ_HOOKS_USAGE_EXIT = 64;
36
- /** The runtime-probe result id: whether hooks actually fired (the ledger). */
37
- export declare const RUNTIME_ENFORCEMENT_CHECK_ID = "hooks.runtime.enforcement";
38
- /**
39
- * The `hq doctor` check ids that correspond to check-hq-hooks.sh's *settings
40
- * load* scope — the subset of the hooks family the wrapper is allowed to fail
41
- * on. Deliberately narrow: it covers a missing/invalid settings file, an
42
- * unquoted `$CLAUDE_PROJECT_DIR` that word-splits on a spaced root, and a hook
43
- * command that runs a script which is not on disk — and nothing else. The many
44
- * richer doctor findings (executable bits, orphaned scripts, three-profile
45
- * membership, Codex/Grok parity, fixture coverage) are intentionally OUT of
46
- * scope, so the wrapper stays byte-for-byte compatible with callers that only
47
- * ever cared whether the hook configuration could load.
48
- */
49
- export declare const CHECK_HQ_HOOKS_SETTINGS_SCOPE: readonly string[];
50
34
  /**
51
35
  * Whether hook dispatch was observed this session. Mirrors the wrapper's
52
36
  * `HQ runtime enforcement: …` line. `NOT CHECKED` is the default when
@@ -31,9 +31,9 @@ export const CHECK_HQ_HOOKS_PASS_EXIT = 0;
31
31
  /** Exit code check-hq-hooks.sh returns on a health failure. Preserved. */
32
32
  export const CHECK_HQ_HOOKS_FAIL_EXIT = 2;
33
33
  /** Exit code check-hq-hooks.sh returns on a usage error. Preserved. */
34
- export const CHECK_HQ_HOOKS_USAGE_EXIT = 64;
34
+ const CHECK_HQ_HOOKS_USAGE_EXIT = 64;
35
35
  /** The runtime-probe result id: whether hooks actually fired (the ledger). */
36
- export const RUNTIME_ENFORCEMENT_CHECK_ID = "hooks.runtime.enforcement";
36
+ const RUNTIME_ENFORCEMENT_CHECK_ID = "hooks.runtime.enforcement";
37
37
  /**
38
38
  * The `hq doctor` check ids that correspond to check-hq-hooks.sh's *settings
39
39
  * load* scope — the subset of the hooks family the wrapper is allowed to fail
@@ -45,7 +45,7 @@ export const RUNTIME_ENFORCEMENT_CHECK_ID = "hooks.runtime.enforcement";
45
45
  * scope, so the wrapper stays byte-for-byte compatible with callers that only
46
46
  * ever cared whether the hook configuration could load.
47
47
  */
48
- export const CHECK_HQ_HOOKS_SETTINGS_SCOPE = [
48
+ const CHECK_HQ_HOOKS_SETTINGS_SCOPE = [
49
49
  "hooks.settings-present",
50
50
  "hooks.settings-required-command-hooks",
51
51
  "hooks.settings-valid-json",
@@ -36,6 +36,7 @@ import { spawnSync } from "node:child_process";
36
36
  import { createHash } from "node:crypto";
37
37
  import * as fs from "node:fs";
38
38
  import * as path from "node:path";
39
+ import { isRecord } from "../shared.js";
39
40
  /**
40
41
  * Parse a fixture case's `effects:` field into a list of {@link
41
42
  * EffectExpectation}. Returns the list, or an error string naming what was
@@ -223,7 +224,4 @@ function hashFile(abs) {
223
224
  return null;
224
225
  }
225
226
  }
226
- function isRecord(value) {
227
- return typeof value === "object" && value !== null && !Array.isArray(value);
228
- }
229
227
  //# sourceMappingURL=effects.js.map
@@ -39,6 +39,7 @@ import * as fs from "node:fs";
39
39
  import * as os from "node:os";
40
40
  import * as path from "node:path";
41
41
  import * as yaml from "js-yaml";
42
+ import { isRecord } from "../shared.js";
42
43
  import { classifyCaseStatus, looksLikeFixture, } from "../fixtures/schema.js";
43
44
  import { HOOK_TESTS_RELDIR, registeredHookIds } from "../fixtures/discover.js";
44
45
  import { isSideEffectingHookId } from "./classify.js";
@@ -566,7 +567,4 @@ function oneLine(text) {
566
567
  const collapsed = text.replace(/\s+/g, " ").trim();
567
568
  return collapsed.length > 200 ? `${collapsed.slice(0, 197)}…` : collapsed;
568
569
  }
569
- function isRecord(value) {
570
- return typeof value === "object" && value !== null && !Array.isArray(value);
571
- }
572
570
  //# sourceMappingURL=sandbox.js.map
@@ -27,6 +27,7 @@
27
27
  * module owns only the classification semantics, so both the doctor and its
28
28
  * tests agree on what a case outcome means.
29
29
  */
30
+ import { isRecord } from "../shared.js";
30
31
  /**
31
32
  * Every fixture schema version this build of the CLI can interpret. A fixture
32
33
  * declaring a version outside this set is reported UNKNOWN, never PASS — see
@@ -242,7 +243,4 @@ export function classifyCaseStatus(met, expectedFailure) {
242
243
  return met ? "WARN" : "KNOWN-DEFECT";
243
244
  return met ? "PASS" : "FAIL";
244
245
  }
245
- function isRecord(value) {
246
- return typeof value === "object" && value !== null && !Array.isArray(value);
247
- }
248
246
  //# sourceMappingURL=schema.js.map
@@ -126,24 +126,8 @@ export declare function claudeCodeFlagEvidence(env: NodeJS.ProcessEnv): Platform
126
126
  * `com.googlecode.iterm2`), so this fires only under a real desktop host.
127
127
  */
128
128
  export declare function bundleIdEvidence(env: NodeJS.ProcessEnv): PlatformEvidence | null;
129
- /**
130
- * Codex runtime environment variables, kept in parity with the canonical shell
131
- * detector `core/scripts/lib/detect-codex.sh`. Presence of any is a strong Codex
132
- * signal. One evidence entry is produced per variable found so a single Codex
133
- * signal can be tested in isolation.
134
- */
135
- export declare const CODEX_ENV_VARS: readonly ["CODEX_SANDBOX", "CODEX_SESSION_ID", "CODEX_EXECUTION_ID", "CODEX_AGENT_ID", "CODEX_THREAD_ID", "CODEX_SHELL", "CODEX_CI", "CODEX_INTERNAL_ORIGINATOR_OVERRIDE", "OPENAI_CODEX"];
136
129
  /** Every Codex environment signal present in `env`, one entry per variable. */
137
130
  export declare function codexEnvEvidence(env: NodeJS.ProcessEnv): PlatformEvidence[];
138
- /**
139
- * Grok runtime environment variables. Restricted to variables the Grok host
140
- * exports into the session (a session id, its workspace root) — HQ's own Grok
141
- * *launcher* variables (`GROK_BIN`, `GROK_CONFIG`, `XAI_API_KEY`, …) are
142
- * excluded on purpose: those can be set inside a Claude or Codex session that is
143
- * merely preparing to launch Grok, and treating them as "we are running under
144
- * Grok" would be a false positive.
145
- */
146
- export declare const GROK_ENV_VARS: readonly ["GROK_SESSION_ID", "GROK_WORKSPACE_ROOT"];
147
131
  /** Every Grok environment signal present in `env`, one entry per variable. */
148
132
  export declare function grokEnvEvidence(env: NodeJS.ProcessEnv): PlatformEvidence[];
149
133
  /**
@@ -157,10 +141,6 @@ export declare function grokEnvEvidence(env: NodeJS.ProcessEnv): PlatformEvidenc
157
141
  * on its environment signals instead, and this function does not guess it.
158
142
  */
159
143
  export declare function ancestryEvidence(ancestors: AncestorProcess[]): PlatformEvidence[];
160
- /** The one command this module ever launches to read process ancestry. */
161
- export declare const PS_COMMAND = "ps";
162
- /** `ps` arguments: every process as `pid ppid comm`, header-suppressed. */
163
- export declare const PS_ARGS: readonly ["-Ao", "pid=,ppid=,comm="];
164
144
  /**
165
145
  * Low-level process-table provider: runs a command and returns its stdout, or
166
146
  * `null` on failure. This is the single seam through which any process is
@@ -186,12 +166,6 @@ export interface ReadAncestryOptions {
186
166
  * environment signals rather than throwing.
187
167
  */
188
168
  export declare function readProcessAncestry(options?: ReadAncestryOptions): AncestorProcess[];
189
- /**
190
- * Collect the environment signals, in a stable order: entrypoint, the Claude
191
- * flag, bundle id, Codex vars, then Grok vars. Process ancestry is collected
192
- * separately (and lazily) by {@link detectPlatform}.
193
- */
194
- export declare function collectEnvEvidence(env: NodeJS.ProcessEnv): PlatformEvidence[];
195
169
  /**
196
170
  * Collect every signal from an environment and an explicit ancestor chain, in a
197
171
  * stable order: environment signals first, then process ancestry. Exposed for
@@ -150,7 +150,7 @@ function looksLikeClaudeDesktopBundle(id) {
150
150
  * signal. One evidence entry is produced per variable found so a single Codex
151
151
  * signal can be tested in isolation.
152
152
  */
153
- export const CODEX_ENV_VARS = [
153
+ const CODEX_ENV_VARS = [
154
154
  "CODEX_SANDBOX",
155
155
  "CODEX_SESSION_ID",
156
156
  "CODEX_EXECUTION_ID",
@@ -185,7 +185,7 @@ export function codexEnvEvidence(env) {
185
185
  * merely preparing to launch Grok, and treating them as "we are running under
186
186
  * Grok" would be a false positive.
187
187
  */
188
- export const GROK_ENV_VARS = ["GROK_SESSION_ID", "GROK_WORKSPACE_ROOT"];
188
+ const GROK_ENV_VARS = ["GROK_SESSION_ID", "GROK_WORKSPACE_ROOT"];
189
189
  /** Every Grok environment signal present in `env`, one entry per variable. */
190
190
  export function grokEnvEvidence(env) {
191
191
  const found = [];
@@ -249,9 +249,9 @@ const DEFAULT_MAX_HOPS = 20;
249
249
  /** Wall-clock bound for the single `ps` snapshot, keeping startup fast. */
250
250
  const PS_TIMEOUT_MS = 250;
251
251
  /** The one command this module ever launches to read process ancestry. */
252
- export const PS_COMMAND = "ps";
252
+ const PS_COMMAND = "ps";
253
253
  /** `ps` arguments: every process as `pid ppid comm`, header-suppressed. */
254
- export const PS_ARGS = ["-Ao", "pid=,ppid=,comm="];
254
+ const PS_ARGS = ["-Ao", "pid=,ppid=,comm="];
255
255
  /**
256
256
  * Read this process's ancestor chain (nearest parent first) by taking one `ps`
257
257
  * snapshot of the process table and walking parent pointers upward. A single
@@ -330,7 +330,7 @@ function defaultPsSpawner(command, args) {
330
330
  * flag, bundle id, Codex vars, then Grok vars. Process ancestry is collected
331
331
  * separately (and lazily) by {@link detectPlatform}.
332
332
  */
333
- export function collectEnvEvidence(env) {
333
+ function collectEnvEvidence(env) {
334
334
  const evidence = [];
335
335
  const entrypoint = entrypointEvidence(env);
336
336
  if (entrypoint)
@@ -0,0 +1,8 @@
1
+ /** Collect every `command` string from a `{hooks:{Event:[{hooks:[…]}]}}` doc. */
2
+ export declare function collectCommands(parsed: unknown): string[];
3
+ export declare function fileState(target: string): {
4
+ present: boolean;
5
+ executable: boolean;
6
+ };
7
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
8
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1,38 @@
1
+ import * as fs from "node:fs";
2
+ /** Collect every `command` string from a `{hooks:{Event:[{hooks:[…]}]}}` doc. */
3
+ export function collectCommands(parsed) {
4
+ const commands = [];
5
+ if (!parsed || typeof parsed !== "object")
6
+ return commands;
7
+ const hooks = parsed.hooks;
8
+ if (!hooks || typeof hooks !== "object")
9
+ return commands;
10
+ for (const entries of Object.values(hooks)) {
11
+ if (!Array.isArray(entries))
12
+ continue;
13
+ for (const entry of entries) {
14
+ const inner = entry?.hooks;
15
+ if (!Array.isArray(inner))
16
+ continue;
17
+ for (const hook of inner) {
18
+ const command = hook?.command;
19
+ if (typeof command === "string")
20
+ commands.push(command);
21
+ }
22
+ }
23
+ }
24
+ return commands;
25
+ }
26
+ export function fileState(target) {
27
+ try {
28
+ const stat = fs.statSync(target);
29
+ return { present: stat.isFile(), executable: (stat.mode & 0o111) !== 0 };
30
+ }
31
+ catch {
32
+ return { present: false, executable: false };
33
+ }
34
+ }
35
+ export function isRecord(value) {
36
+ return typeof value === "object" && value !== null && !Array.isArray(value);
37
+ }
38
+ //# sourceMappingURL=shared.js.map