@indigoai-us/hq-cli 5.345.148 → 5.345.149

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 (65) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +2 -0
  3. package/dist/command-catalog.generated.d.ts +44 -8
  4. package/dist/command-catalog.generated.js +53 -8
  5. package/dist/command-help.js +2 -1
  6. package/dist/commands/access.d.ts +45 -2
  7. package/dist/commands/access.js +537 -223
  8. package/dist/commands/billing-usage.d.ts +33 -2
  9. package/dist/commands/billing-usage.js +75 -4
  10. package/dist/commands/bot.js +2 -2
  11. package/dist/commands/channels.d.ts +27 -0
  12. package/dist/commands/channels.js +108 -4
  13. package/dist/commands/core-refresh-vault-access-native.d.ts +16 -0
  14. package/dist/commands/core-refresh-vault-access-native.js +142 -9
  15. package/dist/commands/core.js +4 -1
  16. package/dist/commands/dm.js +9 -1
  17. package/dist/commands/install-global.d.ts +1 -8
  18. package/dist/commands/install-global.js +11 -27
  19. package/dist/commands/library-add.d.ts +31 -1
  20. package/dist/commands/library-add.js +69 -2
  21. package/dist/commands/library.js +37 -3
  22. package/dist/commands/reindex.js +19 -0
  23. package/dist/hook-engine-path.js +10 -3
  24. package/dist/index.d.ts +10 -0
  25. package/dist/index.js +70 -5
  26. package/dist/lazy-commands.js +2 -0
  27. package/dist/lib/billing/usage-cost.d.ts +31 -1
  28. package/dist/lib/billing/usage-cost.js +46 -0
  29. package/dist/lib/db/local.d.ts +2 -2
  30. package/dist/lib/db/local.js +2 -2
  31. package/dist/lib/db/sql.js +2 -2
  32. package/dist/lib/db/sqlite-binding.d.ts +22 -0
  33. package/dist/lib/db/sqlite-binding.js +168 -0
  34. package/dist/lib/doctor/checks/anywhere.d.ts +12 -0
  35. package/dist/lib/doctor/checks/anywhere.js +63 -12
  36. package/dist/lib/doctor/checks/cli-path.d.ts +2 -1
  37. package/dist/lib/doctor/checks/cli-path.js +2 -1
  38. package/dist/lib/doctor/checks/hook-engine.js +2 -1
  39. package/dist/lib/hook-engine/reconcile.d.ts +9 -0
  40. package/dist/lib/hook-engine/reconcile.js +134 -0
  41. package/dist/lib/hook-engine/registration.d.ts +17 -0
  42. package/dist/lib/hook-engine/registration.js +50 -0
  43. package/dist/lib/install/claude-targets.d.ts +2 -1
  44. package/dist/lib/install/claude-targets.js +8 -3
  45. package/dist/lib/install/codex-targets.d.ts +3 -0
  46. package/dist/lib/install/codex-targets.js +15 -4
  47. package/dist/lib/install/hook-target.d.ts +9 -0
  48. package/dist/lib/install/hook-target.js +39 -0
  49. package/dist/lib/windows/console-encoding.d.ts +24 -0
  50. package/dist/lib/windows/console-encoding.js +83 -0
  51. package/dist/lib/windows/install-followup.d.ts +35 -0
  52. package/dist/lib/windows/install-followup.js +142 -0
  53. package/dist/lib/windows/user-path.d.ts +80 -3
  54. package/dist/lib/windows/user-path.js +187 -26
  55. package/dist/main.js +2 -1
  56. package/dist/unknown-command.d.ts +18 -0
  57. package/dist/unknown-command.js +88 -0
  58. package/dist/utils/cognito-session.d.ts +8 -0
  59. package/dist/utils/cognito-session.js +14 -2
  60. package/dist/utils/hook-trust.d.ts +9 -0
  61. package/dist/utils/hook-trust.js +30 -2
  62. package/dist/utils/qmd-native-binding-error.js +3 -1
  63. package/dist/utils/resolve-executable.d.ts +2 -0
  64. package/dist/utils/resolve-executable.js +6 -2
  65. package/package.json +8 -8
package/CHANGELOG.md CHANGED
@@ -2,6 +2,41 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.345.149] — 2026-10-19
6
+ - `hq access` answers faster. It checks the exact path first and, on a miss,
7
+ looks only in the nearest folder instead of listing the whole vault. It
8
+ loads the member list only when it is about to send an access request.
9
+ Results and denial reasons are the same as before.
10
+ - `hq access` takes several paths at once (`hq access a.md b.md`) or reads
11
+ them from `--stdin`, one per line. Each path gets its own result, `--json`
12
+ prints an array, and the exit code is the highest one across the paths.
13
+ - A folder path now resolves to the folder, and the three spellings `docs`,
14
+ `docs/` and `docs/*` all check the same folder. Before, a bare folder name
15
+ was matched against every file in the vault and usually came back
16
+ ambiguous.
17
+ - Two `hq bot create` error messages now call HQ's built-in bot "your assistant" instead of "setup bot", matching the desktop app. Using `--kind company` with the setup worker now says "HQ's assistant is always a personal bot; drop --kind company.", and using the reserved name `setup` with another worker now says the name is reserved for HQ's assistant. The reserved name and the worker are still `setup`, so commands are unchanged.
18
+ - `hq channels list` takes `--json`, `--active-since <time|duration>` and
19
+ `--sort activity`. `--active-since 2h` (or an ISO time) lists only the
20
+ channels and group DMs with activity since then, newest first, so a sweep
21
+ no longer has to read all of your channels to find the busy ones. `--json`
22
+ includes each channel's last-activity time and unread count.
23
+ - New `hq channels changes [--cursor <token>]` prints the channels that changed
24
+ since the last call's cursor, as JSON. With no cursor it prints a full
25
+ snapshot and a cursor to use next time.
26
+ - `hq dm channel <channel id> --json` no longer downloads your whole channel
27
+ list first, so reading one channel by id takes about a second.
28
+ - `hq billing usage` no longer prices meters for a company or personal account
29
+ on a flat plan (for example a Workforce company that subscribed before usage
30
+ pricing). It shows the readings and one line saying usage meters are not
31
+ billed, with no per-meter cost and no projected bill. `--json` carries
32
+ `onUsagePricing` and leaves out the cost fields. The plan comes from the
33
+ server; when an older server does not send it, the command uses the billing
34
+ summary, and it shows no cost when neither says.
35
+ - `hq library add` now reaches the company vault for members in `shared` or `custom` sync mode. When the library folder is outside the membership's sync scope, the command pins it the same way `hq files get` does, so the next sync uploads the new placeholders and teammates and cloud search can find them. `all` mode and folders already covered by a grant or pin are left alone. If the sync scope cannot be read or the pin cannot be written, the command prints a warning with the exact `hq files get <folder>/ --company <co>` command to run. `--json` output reports this as `syncScope`.
36
+ - `hq library add --to <folder>` no longer pins the whole target folder for `shared` or `custom` sync. Outside the default `library/` folder it pins only the placeholders it wrote, so the rest of that folder stays out of sync. When the pin cannot be written or the sync scope cannot be read, the warning lists the exact paths to add to `.hq/pins.json` (the `hq files get library/` command is still printed for the default folder).
37
+ - Windows cold-install polish. The first `hq` command adds the npm folder that holds `hq.cmd` to the user PATH (HKCU only), idempotently, and broadcasts the environment change. It never edits the machine PATH. `hq doctor` still prints the exact PowerShell command when that folder is missing. npm install no longer needs a package postinstall for the mesh daemon: `hq mesh daemon install --if-stale` runs once on the first real command for that CLI version (the postinstall now only pins the native hook engine), and better-sqlite3 loads from its prebuilt binary or fails with `npm install -g @indigoai-us/hq-cli --allow-scripts=better-sqlite3`. On a Windows console that is not UTF-8, hq prints ASCII instead of a garbled em dash. `hq invite --help` and other unknown commands print `unknown command` plus a nested did-you-mean and exit non-zero, instead of the main help. When the hqd named pipe cannot be used, `hq doctor` says whether hqd is down, access was denied, the pipe is missing, or hqd did not answer. On Windows, `hq reindex` now finds the npm `codex.cmd` shim on PATH and runs it through cmd.exe, so Codex hook trust no longer fails with `spawn codex ENOENT`. When Codex is missing, reindex names it and says how to fix it. Any hook-trust failure now says that runtime will not run HQ hooks until trust succeeds and to rerun `hq reindex`. The SessionStart vault-access refresh (`hq core refresh-vault-access`) exits right away when nobody is signed in to HQ. Each child `hq` call it makes has a 30-second timeout (`HQ_VAULT_ACCESS_TIMEOUT_MS` changes it) and runs with `HQ_NO_BROWSER_LOGIN=1`, so a signed-out child fails fast instead of waiting on a browser login.
38
+ - Register the pinned native hook launcher behind the default-off hook-engine-launcher flag, with Claude exec form, Codex commandWindows, and reindex rollback to bash. Project hook files are converted in place and restored exactly, and a registration file that cannot be read no longer stops the others or their Codex trust. Codex hooks are only trusted after their file was written and verified.
39
+
5
40
  ## [5.345.148] — 2026-10-19
6
41
 
7
42
  - The `hq lanes` free-memory gate (`throttle.min_available_mem_mb`) now reads the same values as macOS `memory_pressure`: the system-wide free percentage and the pressure level. A Mac that `memory_pressure` reports as normal with enough free memory no longer holds new lanes. While the gate is set, new lanes wait at the warn or critical level. The old `vm_stat` reading, which leaves out purgeable and compressible memory, is used only when those values cannot be read. A memory hold is recorded as `memory_hold` in the throttle state and in `hq lanes admit` output, with the signal, the reading, the level and the threshold.
package/README.md CHANGED
@@ -7,6 +7,8 @@ npm install -g @indigoai-us/hq-cli
7
7
  hq --help
8
8
  ```
9
9
 
10
+ On Windows, the first `hq` command adds the folder that holds `hq.cmd` to your user PATH (HKCU only, not the machine PATH). You do not need to approve npm install scripts for hq itself. If the local database cannot load better-sqlite3 because npm skipped its install script, HQ tries to download the prebuilt binary. If that fails, the error names `npm install -g @indigoai-us/hq-cli --allow-scripts=better-sqlite3`.
11
+
10
12
  ## Marketplace package verification
11
13
 
12
14
  Marketplace packages must include an Ed25519 signature made with a platform
@@ -3125,20 +3125,20 @@ export declare const COMMAND_CATALOG: readonly [{
3125
3125
  }];
3126
3126
  }, {
3127
3127
  readonly name: "access";
3128
- readonly description: "Tell whether a vault file exists and whether you can read it. Never a bare not-found. Exit codes: 0 local/not-synced, 2 never-existed, 3 no-access, 4 ambiguous.";
3128
+ readonly description: "Tell whether a vault file exists and whether you can read it. Never a bare not-found. Takes one or more paths or queries. Exit codes: 0 local/not-synced, 2 never-existed, 3 no-access, 4 ambiguous.";
3129
3129
  readonly aliases: readonly [];
3130
3130
  readonly hidden: false;
3131
3131
  readonly helpOption: true;
3132
3132
  readonly helpCommand: false;
3133
- readonly usage: "[options] <path-or-query>";
3133
+ readonly usage: "[options] [vault-path...]";
3134
3134
  readonly helpText: readonly [{
3135
3135
  readonly position: "after";
3136
- readonly text: "\nExit codes:\n 0 local or not-synced (file exists and you can read it)\n 2 never-existed (the path was never created)\n 3 no-access (the file exists but you cannot read it)\n 4 ambiguous (several keys matched; pick one)\n";
3136
+ readonly text: "\nExit codes:\n 0 local or not-synced (file exists and you can read it)\n 2 never-existed (the path was never created)\n 3 no-access (the file exists but you cannot read it)\n 4 ambiguous (several keys matched; pick one)\n\nWith several paths, each gets its own result block and the exit code is the\nhighest one across the paths.\n";
3137
3137
  }];
3138
3138
  readonly arguments: readonly [{
3139
- readonly name: "path-or-query";
3140
- readonly required: true;
3141
- readonly variadic: false;
3139
+ readonly name: "vault-path";
3140
+ readonly required: false;
3141
+ readonly variadic: true;
3142
3142
  readonly description: "";
3143
3143
  }];
3144
3144
  readonly options: readonly [{
@@ -3151,7 +3151,11 @@ export declare const COMMAND_CATALOG: readonly [{
3151
3151
  readonly hidden: false;
3152
3152
  }, {
3153
3153
  readonly flags: "--json";
3154
- readonly description: "Print a single JSON object";
3154
+ readonly description: "Print a single JSON object (an array for several paths)";
3155
+ readonly hidden: false;
3156
+ }, {
3157
+ readonly flags: "--stdin";
3158
+ readonly description: "Read more paths from stdin, one per line";
3155
3159
  readonly hidden: false;
3156
3160
  }, {
3157
3161
  readonly flags: "--no-fix";
@@ -4026,7 +4030,35 @@ export declare const COMMAND_CATALOG: readonly [{
4026
4030
  readonly usage: "[options]";
4027
4031
  readonly helpText: readonly [];
4028
4032
  readonly arguments: readonly [];
4029
- readonly options: readonly [];
4033
+ readonly options: readonly [{
4034
+ readonly flags: "--json";
4035
+ readonly description: "Output the channel array as JSON, including activity fields.";
4036
+ readonly hidden: false;
4037
+ }, {
4038
+ readonly flags: "--active-since <when>";
4039
+ readonly description: "Only channels with activity at or after an ISO time or a duration back from now (30m, 2h, 1d); newest first.";
4040
+ readonly hidden: false;
4041
+ }, {
4042
+ readonly flags: "--sort <order>";
4043
+ readonly description: "'activity' lists the most recently active channels first.";
4044
+ readonly hidden: false;
4045
+ }];
4046
+ readonly subcommands: readonly [];
4047
+ }, {
4048
+ readonly name: "changes";
4049
+ readonly description: "Print the channels that changed since a feed cursor, as JSON (no cursor → full snapshot).";
4050
+ readonly aliases: readonly [];
4051
+ readonly hidden: false;
4052
+ readonly helpOption: true;
4053
+ readonly helpCommand: false;
4054
+ readonly usage: "[options]";
4055
+ readonly helpText: readonly [];
4056
+ readonly arguments: readonly [];
4057
+ readonly options: readonly [{
4058
+ readonly flags: "--cursor <token>";
4059
+ readonly description: "Cursor from the previous `hq channels changes` response.";
4060
+ readonly hidden: false;
4061
+ }];
4030
4062
  readonly subcommands: readonly [];
4031
4063
  }, {
4032
4064
  readonly name: "members";
@@ -8404,6 +8436,10 @@ export declare const COMMAND_CATALOG: readonly [{
8404
8436
  readonly flags: "--repair";
8405
8437
  readonly description: "Repair the pinned copy after closing running hook processes";
8406
8438
  readonly hidden: false;
8439
+ }, {
8440
+ readonly flags: "--for-registration";
8441
+ readonly description: "Print a path only when the offline launcher flag is enabled";
8442
+ readonly hidden: false;
8407
8443
  }];
8408
8444
  readonly subcommands: readonly [];
8409
8445
  }, {
@@ -3766,23 +3766,23 @@ export const COMMAND_CATALOG = [
3766
3766
  },
3767
3767
  {
3768
3768
  "name": "access",
3769
- "description": "Tell whether a vault file exists and whether you can read it. Never a bare not-found. Exit codes: 0 local/not-synced, 2 never-existed, 3 no-access, 4 ambiguous.",
3769
+ "description": "Tell whether a vault file exists and whether you can read it. Never a bare not-found. Takes one or more paths or queries. Exit codes: 0 local/not-synced, 2 never-existed, 3 no-access, 4 ambiguous.",
3770
3770
  "aliases": [],
3771
3771
  "hidden": false,
3772
3772
  "helpOption": true,
3773
3773
  "helpCommand": false,
3774
- "usage": "[options] <path-or-query>",
3774
+ "usage": "[options] [vault-path...]",
3775
3775
  "helpText": [
3776
3776
  {
3777
3777
  "position": "after",
3778
- "text": "\nExit codes:\n 0 local or not-synced (file exists and you can read it)\n 2 never-existed (the path was never created)\n 3 no-access (the file exists but you cannot read it)\n 4 ambiguous (several keys matched; pick one)\n"
3778
+ "text": "\nExit codes:\n 0 local or not-synced (file exists and you can read it)\n 2 never-existed (the path was never created)\n 3 no-access (the file exists but you cannot read it)\n 4 ambiguous (several keys matched; pick one)\n\nWith several paths, each gets its own result block and the exit code is the\nhighest one across the paths.\n"
3779
3779
  }
3780
3780
  ],
3781
3781
  "arguments": [
3782
3782
  {
3783
- "name": "path-or-query",
3784
- "required": true,
3785
- "variadic": false,
3783
+ "name": "vault-path",
3784
+ "required": false,
3785
+ "variadic": true,
3786
3786
  "description": ""
3787
3787
  }
3788
3788
  ],
@@ -3799,7 +3799,12 @@ export const COMMAND_CATALOG = [
3799
3799
  },
3800
3800
  {
3801
3801
  "flags": "--json",
3802
- "description": "Print a single JSON object",
3802
+ "description": "Print a single JSON object (an array for several paths)",
3803
+ "hidden": false
3804
+ },
3805
+ {
3806
+ "flags": "--stdin",
3807
+ "description": "Read more paths from stdin, one per line",
3803
3808
  "hidden": false
3804
3809
  },
3805
3810
  {
@@ -4872,7 +4877,42 @@ export const COMMAND_CATALOG = [
4872
4877
  "usage": "[options]",
4873
4878
  "helpText": [],
4874
4879
  "arguments": [],
4875
- "options": [],
4880
+ "options": [
4881
+ {
4882
+ "flags": "--json",
4883
+ "description": "Output the channel array as JSON, including activity fields.",
4884
+ "hidden": false
4885
+ },
4886
+ {
4887
+ "flags": "--active-since <when>",
4888
+ "description": "Only channels with activity at or after an ISO time or a duration back from now (30m, 2h, 1d); newest first.",
4889
+ "hidden": false
4890
+ },
4891
+ {
4892
+ "flags": "--sort <order>",
4893
+ "description": "'activity' lists the most recently active channels first.",
4894
+ "hidden": false
4895
+ }
4896
+ ],
4897
+ "subcommands": []
4898
+ },
4899
+ {
4900
+ "name": "changes",
4901
+ "description": "Print the channels that changed since a feed cursor, as JSON (no cursor → full snapshot).",
4902
+ "aliases": [],
4903
+ "hidden": false,
4904
+ "helpOption": true,
4905
+ "helpCommand": false,
4906
+ "usage": "[options]",
4907
+ "helpText": [],
4908
+ "arguments": [],
4909
+ "options": [
4910
+ {
4911
+ "flags": "--cursor <token>",
4912
+ "description": "Cursor from the previous `hq channels changes` response.",
4913
+ "hidden": false
4914
+ }
4915
+ ],
4876
4916
  "subcommands": []
4877
4917
  },
4878
4918
  {
@@ -10241,6 +10281,11 @@ export const COMMAND_CATALOG = [
10241
10281
  "flags": "--repair",
10242
10282
  "description": "Repair the pinned copy after closing running hook processes",
10243
10283
  "hidden": false
10284
+ },
10285
+ {
10286
+ "flags": "--for-registration",
10287
+ "description": "Print a path only when the offline launcher flag is enabled",
10288
+ "hidden": false
10244
10289
  }
10245
10290
  ],
10246
10291
  "subcommands": []
@@ -1,6 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import { CLI_VERSION } from "./cli-version.js";
3
3
  import { registerCommandCatalog } from "./lazy-commands.js";
4
+ import { argvWithoutHelpOnUnknownCommand } from "./unknown-command.js";
4
5
  export async function runCommandHelp(argv) {
5
6
  const program = new Command()
6
7
  .name("hq")
@@ -10,6 +11,6 @@ export async function runCommandHelp(argv) {
10
11
  registerCommandCatalog(program);
11
12
  const { hideStorageInCatalog } = await import("./lib/storage-feature-flag.js");
12
13
  hideStorageInCatalog(program);
13
- await program.parseAsync([...argv]);
14
+ await program.parseAsync(argvWithoutHelpOnUnknownCommand([...argv]));
14
15
  }
15
16
  //# sourceMappingURL=command-help.js.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `hq access <path-or-query>` — existence + ACL probe with a self-healing
2
+ * `hq access <path-or-query...>` — existence + ACL probe with a self-healing
3
3
  * ladder: resolve, list, probe ACL, then (with --fix) download / pin / repair
4
4
  * sync or request access from the grantor.
5
5
  *
@@ -74,10 +74,19 @@ export interface AccessDeps {
74
74
  fetchAclTree: (prefix: string) => Promise<AccessAclTree | null>;
75
75
  /** Active members (owner/admin/member/guest) — used for grantor resolution. */
76
76
  listMembers: () => Promise<AccessMember[]>;
77
+ /** The caller, or a loader for it. A loader runs only when a request is sent. */
77
78
  requester: {
78
79
  email: string;
79
80
  name?: string;
80
- };
81
+ } | (() => Promise<{
82
+ email: string;
83
+ name?: string;
84
+ }>);
85
+ /**
86
+ * Batch POST acl/resolve: permission per company-relative target (null when
87
+ * the resolver grants nothing). Used by batch mode only.
88
+ */
89
+ resolveAcl?: (targets: string[]) => Promise<Map<string, string | null>>;
81
90
  dm?: {
82
91
  send(msg: {
83
92
  recipient: string;
@@ -150,7 +159,34 @@ export declare function outcomeExitCode(outcome: AccessOutcome): 0 | 2 | 3 | 4;
150
159
  export declare function formatAccessOutcome(result: RunAccessResult): string;
151
160
  export declare function resolveGrantor(tree: AccessAclTree | null, members: AccessMember[]): AccessGrantor | null;
152
161
  export declare function runAccess(input: RunAccessInput): Promise<RunAccessResult>;
162
+ export interface RunAccessBatchInput {
163
+ targets: string[];
164
+ fix: boolean;
165
+ json: boolean;
166
+ yes?: boolean;
167
+ deps: AccessDeps;
168
+ /** Parallel existence checks. Default 4. */
169
+ concurrency?: number;
170
+ }
171
+ export interface RunAccessBatchResult {
172
+ results: Array<{
173
+ target: string;
174
+ result: RunAccessResult;
175
+ }>;
176
+ /** Highest exit code across the targets. */
177
+ exitCode: 0 | 2 | 3 | 4;
178
+ }
179
+ /**
180
+ * Several targets in one company: one vend, one bucket lookup, and one
181
+ * acl/resolve call for all of them, then bounded-concurrency existence
182
+ * checks. Requests (DM rung) run one at a time in input order so prompts and
183
+ * grantor lines never interleave. Several fuzzy hits are reported as
184
+ * ambiguous; the interactive picker is single-path only.
185
+ */
186
+ export declare function runAccessBatch(input: RunAccessBatchInput): Promise<RunAccessBatchResult>;
153
187
  export declare function registerAccessCommand(program: Command): void;
188
+ /** One target per non-blank line; surrounding whitespace is ignored. */
189
+ export declare function parseTargetLines(text: string): string[];
154
190
  /**
155
191
  * Resolve the company `hq access` runs against: explicit `company` (the
156
192
  * ladder forwards the slug stamped on a 403), else the slug anchored in the
@@ -173,4 +209,11 @@ export declare function runAccessForPath(path: string, opts?: {
173
209
  yes?: boolean;
174
210
  fix?: boolean;
175
211
  }): Promise<RunAccessResult>;
212
+ export declare function runAccessForPaths(paths: string[], opts?: {
213
+ company?: string;
214
+ hqRoot?: string;
215
+ json?: boolean;
216
+ yes?: boolean;
217
+ fix?: boolean;
218
+ }): Promise<RunAccessBatchResult>;
176
219
  //# sourceMappingURL=access.d.ts.map