@indigoai-us/hq-cli 5.77.13 → 5.78.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.
Files changed (307) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/assets/scaffold/core/scripts/archive-old-threads.sh +86 -0
  3. package/assets/scaffold/core/scripts/backfill-company-skill-mirrors.sh +73 -0
  4. package/assets/scaffold/core/scripts/backfill-workspace-mirror.sh +51 -0
  5. package/assets/scaffold/core/scripts/codex-skill-bridge.sh +550 -0
  6. package/assets/scaffold/core/scripts/detect-stale-core-policy-mirror.sh +185 -0
  7. package/assets/scaffold/core/scripts/hq-status-summary.sh +187 -0
  8. package/assets/scaffold/core/scripts/ontology-readme-drift.sh +264 -0
  9. package/assets/scaffold/core/scripts/qmd-reindex-after-sync.sh +93 -0
  10. package/assets/scaffold/core/scripts/rebuild-all-indexes.sh +69 -0
  11. package/assets/scaffold/core/scripts/rebuild-companies-index.sh +206 -0
  12. package/assets/scaffold/core/scripts/rebuild-company-knowledge-index.sh +127 -0
  13. package/assets/scaffold/core/scripts/rebuild-orchestrator-index.sh +86 -0
  14. package/assets/scaffold/core/scripts/rebuild-projects-index.sh +105 -0
  15. package/assets/scaffold/core/scripts/rebuild-public-knowledge-index.sh +83 -0
  16. package/assets/scaffold/core/scripts/rebuild-reports-index.sh +114 -0
  17. package/assets/scaffold/core/scripts/rebuild-social-drafts-index.sh +135 -0
  18. package/assets/scaffold/core/scripts/rebuild-threads-index.sh +82 -0
  19. package/assets/scaffold/core/scripts/rebuild-workers-index.sh +97 -0
  20. package/assets/scaffold/core/scripts/resize-screenshot.sh +47 -0
  21. package/assets/scaffold/core/scripts/token-usage-report.sh +254 -0
  22. package/assets/scaffold/core/scripts/worktree.sh +136 -0
  23. package/dist/commands/agents.js +28 -12
  24. package/dist/commands/api-keys.js +100 -20
  25. package/dist/commands/core.d.ts +90 -0
  26. package/dist/commands/core.js +279 -0
  27. package/dist/commands/files-browse.d.ts +21 -0
  28. package/dist/commands/files-browse.js +145 -24
  29. package/dist/commands/files.js +33 -7
  30. package/dist/commands/members.js +16 -5
  31. package/dist/commands/pack-install.d.ts +14 -0
  32. package/dist/commands/pack-install.js +51 -2
  33. package/dist/commands/pkg-install.js +43 -0
  34. package/dist/commands/run.js +8 -0
  35. package/dist/commands/secrets.js +125 -65
  36. package/dist/main.js +6 -0
  37. package/dist/utils/api-key-command-gate.d.ts +45 -0
  38. package/dist/utils/api-key-command-gate.js +51 -0
  39. package/dist/utils/hq-roots.d.ts +91 -0
  40. package/dist/utils/hq-roots.js +212 -0
  41. package/dist/utils/resolve-vault-credential.d.ts +63 -3
  42. package/dist/utils/resolve-vault-credential.js +152 -6
  43. package/dist/utils/run-bundled-script.d.ts +66 -0
  44. package/dist/utils/run-bundled-script.js +80 -0
  45. package/dist/utils/vault-api.d.ts +21 -0
  46. package/dist/utils/vault-api.js +74 -3
  47. package/package.json +7 -1
  48. package/.claude/policies/hq-cli-interactive-reads-use-sts-vend.md +0 -49
  49. package/.github/workflows/ci.yml +0 -46
  50. package/.github/workflows/publish.yml +0 -36
  51. package/.github/workflows/scripts/smoke-test-pkg.sh +0 -97
  52. package/e2e/cli.test.ts +0 -128
  53. package/eslint.config.js +0 -37
  54. package/pnpm-workspace.yaml +0 -4
  55. package/scripts/chmod-bins.mjs +0 -49
  56. package/scripts/generate-dsn.mjs +0 -26
  57. package/scripts/generate-scan-packages-table.mjs +0 -113
  58. package/scripts/smoke-sources-signals.sh +0 -103
  59. package/src/bin/hq-auth-refresh.ts +0 -43
  60. package/src/cli-version.ts +0 -13
  61. package/src/commands/__fixtures__/make-tar.ts +0 -126
  62. package/src/commands/_patterns.ts +0 -10
  63. package/src/commands/add.ts +0 -75
  64. package/src/commands/agents.test.ts +0 -527
  65. package/src/commands/agents.ts +0 -923
  66. package/src/commands/api-keys.test.ts +0 -291
  67. package/src/commands/api-keys.ts +0 -382
  68. package/src/commands/artifact-verify.test.ts +0 -177
  69. package/src/commands/auth.test.ts +0 -82
  70. package/src/commands/auth.ts +0 -213
  71. package/src/commands/billing.test.ts +0 -158
  72. package/src/commands/billing.ts +0 -146
  73. package/src/commands/channels.test.ts +0 -74
  74. package/src/commands/channels.ts +0 -91
  75. package/src/commands/cloud-demote.test.ts +0 -401
  76. package/src/commands/cloud-demote.ts +0 -278
  77. package/src/commands/cloud-provision.test.ts +0 -1117
  78. package/src/commands/cloud-provision.ts +0 -942
  79. package/src/commands/cloud.pull-all.test.ts +0 -711
  80. package/src/commands/cloud.pull-per-company.test.ts +0 -188
  81. package/src/commands/cloud.push-all.test.ts +0 -485
  82. package/src/commands/cloud.scope-excluded-warning.test.ts +0 -22
  83. package/src/commands/cloud.selectors.test.ts +0 -208
  84. package/src/commands/cloud.status.test.ts +0 -160
  85. package/src/commands/cloud.test.ts +0 -41
  86. package/src/commands/cloud.ts +0 -2130
  87. package/src/commands/company.test.ts +0 -202
  88. package/src/commands/company.ts +0 -148
  89. package/src/commands/creators.test.ts +0 -60
  90. package/src/commands/creators.ts +0 -117
  91. package/src/commands/crm.test.ts +0 -179
  92. package/src/commands/crm.ts +0 -236
  93. package/src/commands/db-migrate.ts +0 -55
  94. package/src/commands/db-provision.ts +0 -114
  95. package/src/commands/db-sql.ts +0 -124
  96. package/src/commands/db-status.ts +0 -108
  97. package/src/commands/db.ts +0 -26
  98. package/src/commands/dm.test.ts +0 -748
  99. package/src/commands/dm.ts +0 -1226
  100. package/src/commands/feedback.test.ts +0 -413
  101. package/src/commands/feedback.ts +0 -169
  102. package/src/commands/files-browse.test.ts +0 -1249
  103. package/src/commands/files-browse.ts +0 -1506
  104. package/src/commands/files-delete.test.ts +0 -484
  105. package/src/commands/files-recovery.test.ts +0 -370
  106. package/src/commands/files.test.ts +0 -722
  107. package/src/commands/files.ts +0 -1446
  108. package/src/commands/group-grants.test.ts +0 -330
  109. package/src/commands/group-grants.ts +0 -455
  110. package/src/commands/groups.test.ts +0 -44
  111. package/src/commands/groups.ts +0 -368
  112. package/src/commands/integrations.test.ts +0 -633
  113. package/src/commands/integrations.ts +0 -507
  114. package/src/commands/list.ts +0 -85
  115. package/src/commands/login.ts +0 -52
  116. package/src/commands/logout.ts +0 -30
  117. package/src/commands/marketplace-install.test.ts +0 -543
  118. package/src/commands/marketplace-security.test.ts +0 -646
  119. package/src/commands/mcp-registration.test.ts +0 -2787
  120. package/src/commands/mcp-registration.ts +0 -2612
  121. package/src/commands/mcp-status.test.ts +0 -483
  122. package/src/commands/mcp-status.ts +0 -575
  123. package/src/commands/mcp-status.us011.test.ts +0 -243
  124. package/src/commands/meetings.test.ts +0 -522
  125. package/src/commands/meetings.ts +0 -789
  126. package/src/commands/members.test.ts +0 -1474
  127. package/src/commands/members.ts +0 -1181
  128. package/src/commands/onboard-identity-guard.test.ts +0 -99
  129. package/src/commands/onboard-identity-guard.ts +0 -103
  130. package/src/commands/onboard-join.test.ts +0 -96
  131. package/src/commands/onboard-join.ts +0 -101
  132. package/src/commands/onboard-warning.test.ts +0 -26
  133. package/src/commands/onboard-warning.ts +0 -12
  134. package/src/commands/onboard.ts +0 -267
  135. package/src/commands/outposts-heartbeat.test.ts +0 -299
  136. package/src/commands/outposts-heartbeat.ts +0 -310
  137. package/src/commands/outposts-replica-sync.test.ts +0 -272
  138. package/src/commands/outposts-self-deploy.test.ts +0 -243
  139. package/src/commands/outposts.test.ts +0 -1039
  140. package/src/commands/outposts.ts +0 -1935
  141. package/src/commands/pack-install-secret-authorization.test.ts +0 -115
  142. package/src/commands/pack-install.test.ts +0 -1469
  143. package/src/commands/pack-install.ts +0 -2247
  144. package/src/commands/pack-update-cache.test.ts +0 -149
  145. package/src/commands/packs.test.ts +0 -88
  146. package/src/commands/packs.ts +0 -622
  147. package/src/commands/people.test.ts +0 -807
  148. package/src/commands/people.ts +0 -422
  149. package/src/commands/pkg-install.dispatch.test.ts +0 -71
  150. package/src/commands/pkg-install.ts +0 -215
  151. package/src/commands/pkg-list.test.ts +0 -79
  152. package/src/commands/pkg-list.ts +0 -13
  153. package/src/commands/pkg-remove.ts +0 -71
  154. package/src/commands/pkg-update.ts +0 -189
  155. package/src/commands/publish.test.ts +0 -650
  156. package/src/commands/publish.ts +0 -580
  157. package/src/commands/reindex.test.ts +0 -259
  158. package/src/commands/reindex.ts +0 -274
  159. package/src/commands/rescue.test.ts +0 -39
  160. package/src/commands/rescue.ts +0 -210
  161. package/src/commands/run.env-local.test.ts +0 -88
  162. package/src/commands/run.test.ts +0 -45
  163. package/src/commands/run.ts +0 -184
  164. package/src/commands/safe-extract.test.ts +0 -459
  165. package/src/commands/safe-extract.ts +0 -444
  166. package/src/commands/secrets-scope.test.ts +0 -56
  167. package/src/commands/secrets-scope.ts +0 -32
  168. package/src/commands/secrets.parse-destination.test.ts +0 -38
  169. package/src/commands/secrets.test.ts +0 -2037
  170. package/src/commands/secrets.ts +0 -2240
  171. package/src/commands/signals.ts +0 -351
  172. package/src/commands/skill.test.ts +0 -770
  173. package/src/commands/skill.ts +0 -796
  174. package/src/commands/sources.ts +0 -362
  175. package/src/commands/sync-mode.test.ts +0 -366
  176. package/src/commands/sync-mode.ts +0 -387
  177. package/src/commands/sync-narrow.test.ts +0 -633
  178. package/src/commands/sync-narrow.ts +0 -555
  179. package/src/commands/sync.ts +0 -165
  180. package/src/commands/team-sync.ts +0 -628
  181. package/src/commands/update.ts +0 -71
  182. package/src/commands/whoami.ts +0 -83
  183. package/src/commands/workers.test.ts +0 -158
  184. package/src/commands/workers.ts +0 -301
  185. package/src/index.test.ts +0 -32
  186. package/src/index.ts +0 -20
  187. package/src/lib/db/control-plane.test.ts +0 -59
  188. package/src/lib/db/control-plane.ts +0 -113
  189. package/src/lib/db/local.test.ts +0 -81
  190. package/src/lib/db/local.ts +0 -148
  191. package/src/lib/db/migrate.test.ts +0 -133
  192. package/src/lib/db/migrate.ts +0 -137
  193. package/src/lib/db/paths.test.ts +0 -112
  194. package/src/lib/db/paths.ts +0 -128
  195. package/src/lib/db/remote-engine.test.ts +0 -44
  196. package/src/lib/db/remote-engine.ts +0 -148
  197. package/src/lib/db/remote-sql.test.ts +0 -32
  198. package/src/lib/db/remote-sql.ts +0 -62
  199. package/src/lib/db/sql.test.ts +0 -106
  200. package/src/lib/db/sql.ts +0 -192
  201. package/src/lib/hq-cloud-dep.smoke.test.ts +0 -75
  202. package/src/lib/local-tree-diff.test.ts +0 -301
  203. package/src/lib/local-tree-diff.ts +0 -362
  204. package/src/lib/narrow-hint-banner.test.ts +0 -235
  205. package/src/lib/narrow-hint-banner.ts +0 -212
  206. package/src/lib/plan-limit-nag.test.ts +0 -317
  207. package/src/lib/plan-limit-nag.ts +0 -264
  208. package/src/main.ts +0 -371
  209. package/src/node-preflight.test.ts +0 -60
  210. package/src/node-preflight.ts +0 -67
  211. package/src/outpost/session-heartbeat-bounds.test.ts +0 -195
  212. package/src/outpost/session-heartbeat-guard.test.ts +0 -105
  213. package/src/outpost/session-heartbeat-publisher.test.ts +0 -178
  214. package/src/outpost/session-heartbeat-publisher.ts +0 -186
  215. package/src/outpost/session-heartbeat-retain-guard.test.ts +0 -126
  216. package/src/outpost/session-heartbeat.test.ts +0 -459
  217. package/src/outpost/session-heartbeat.ts +0 -877
  218. package/src/packaging.test.ts +0 -109
  219. package/src/run/__fixtures__/discover-schemas/example.env.schema +0 -4
  220. package/src/run/discover-schemas.test.ts +0 -153
  221. package/src/run/discover-schemas.ts +0 -79
  222. package/src/run/hq-plugin.test.ts +0 -371
  223. package/src/run/hq-plugin.ts +0 -277
  224. package/src/run/varlock-shape.test.ts +0 -57
  225. package/src/schemas/hq-package.schema.json +0 -155
  226. package/src/sentry-before-send.test.ts +0 -359
  227. package/src/sentry-before-send.ts +0 -221
  228. package/src/sentry-epipe.test.ts +0 -37
  229. package/src/sentry-release.test.ts +0 -54
  230. package/src/sentry.test.ts +0 -24
  231. package/src/sentry.ts +0 -54
  232. package/src/strategies/link.ts +0 -62
  233. package/src/strategies/merge.ts +0 -142
  234. package/src/types.ts +0 -146
  235. package/src/utils/__fixtures__/scan-packages.generated-block.sh +0 -23
  236. package/src/utils/auth-error.test.ts +0 -40
  237. package/src/utils/auth-error.ts +0 -42
  238. package/src/utils/billing-gate.test.ts +0 -95
  239. package/src/utils/billing-gate.ts +0 -228
  240. package/src/utils/breadcrumb-buffer.ts +0 -18
  241. package/src/utils/cli-telemetry.test.ts +0 -153
  242. package/src/utils/cli-telemetry.ts +0 -61
  243. package/src/utils/cognito-session.machine.test.ts +0 -109
  244. package/src/utils/cognito-session.refresh.test.ts +0 -84
  245. package/src/utils/cognito-session.test.ts +0 -328
  246. package/src/utils/cognito-session.ts +0 -448
  247. package/src/utils/company-selection-error.test.ts +0 -42
  248. package/src/utils/company-selection-error.ts +0 -45
  249. package/src/utils/contribution-table.ts +0 -83
  250. package/src/utils/environmental-error.test.ts +0 -45
  251. package/src/utils/environmental-error.ts +0 -39
  252. package/src/utils/epipe.test.ts +0 -28
  253. package/src/utils/epipe.ts +0 -29
  254. package/src/utils/expected-cli-error.test.ts +0 -28
  255. package/src/utils/expected-cli-error.ts +0 -39
  256. package/src/utils/feedback-diagnostics.test.ts +0 -183
  257. package/src/utils/feedback-diagnostics.ts +0 -123
  258. package/src/utils/feedback-screenshots.test.ts +0 -134
  259. package/src/utils/feedback-screenshots.ts +0 -124
  260. package/src/utils/feedback-versions.test.ts +0 -98
  261. package/src/utils/feedback-versions.ts +0 -68
  262. package/src/utils/git.ts +0 -74
  263. package/src/utils/integrity.ts +0 -59
  264. package/src/utils/intercepted-process-exit.test.ts +0 -37
  265. package/src/utils/intercepted-process-exit.ts +0 -36
  266. package/src/utils/login-provider.test.ts +0 -42
  267. package/src/utils/login-provider.ts +0 -30
  268. package/src/utils/manifest.test.ts +0 -167
  269. package/src/utils/manifest.ts +0 -131
  270. package/src/utils/pack-contributions.test.ts +0 -603
  271. package/src/utils/pack-contributions.ts +0 -450
  272. package/src/utils/people.ts +0 -215
  273. package/src/utils/registry-client.ts +0 -204
  274. package/src/utils/registry.ts +0 -90
  275. package/src/utils/resolve-vault-credential.test.ts +0 -69
  276. package/src/utils/resolve-vault-credential.ts +0 -60
  277. package/src/utils/sandbox-runner-client.test.ts +0 -279
  278. package/src/utils/sandbox-runner-client.ts +0 -260
  279. package/src/utils/secrets-cache.ts +0 -183
  280. package/src/utils/sentry-identity.ts +0 -45
  281. package/src/utils/settle-with-timeout.test.ts +0 -21
  282. package/src/utils/settle-with-timeout.ts +0 -22
  283. package/src/utils/user-yaml-error.test.ts +0 -24
  284. package/src/utils/user-yaml-error.ts +0 -30
  285. package/src/utils/vault-api.test.ts +0 -536
  286. package/src/utils/vault-api.ts +0 -382
  287. package/src/utils/version-check.test.ts +0 -176
  288. package/src/utils/version-check.ts +0 -155
  289. package/src/utils/version-gate.test.ts +0 -1024
  290. package/src/utils/version-gate.ts +0 -702
  291. package/test/commands/db-tenant-isolation.test.ts +0 -94
  292. package/test/commands/db.test.ts +0 -85
  293. package/test/commands/signals.test.ts +0 -207
  294. package/test/commands/sources.test.ts +0 -231
  295. package/test/e2e/smoke-install-mcp.sh +0 -113
  296. package/test/fixtures/hq-pack-smoke-mcp/mcp/smoke-http.json +0 -1
  297. package/test/fixtures/hq-pack-smoke-mcp/package.yaml +0 -11
  298. package/test/fixtures/signals/action_item/sample.md +0 -16
  299. package/test/fixtures/signals/summary/sample.md +0 -12
  300. package/test/fixtures/sources/meetings/sample.md +0 -25
  301. package/test/helpers/cli-runner.ts +0 -150
  302. package/test/helpers/s3-list-mock.ts +0 -79
  303. package/test/helpers/vault-service-mock.ts +0 -295
  304. package/test/sources-signals/smoke.test.ts +0 -228
  305. package/tsconfig.json +0 -20
  306. package/vitest.config.ts +0 -11
  307. package/vitest.e2e.config.ts +0 -7
@@ -1,14 +1,57 @@
1
1
  import chalk from "chalk";
2
2
  import { ensureCognitoToken } from "../utils/cognito-session.js";
3
- import { assertCognitoOnlyCommand } from "../utils/resolve-vault-credential.js";
3
+ import { API_KEY_CAPABILITIES, CLI_API_KEY_CAPABILITIES, DEPLOY_APP_ALL, isApiKeyCapability, requireApiKeyCapability, unusableApiKeyCapabilities, } from "../utils/resolve-vault-credential.js";
4
4
  import { getCompanyUid, vaultApiFetch } from "./secrets.js";
5
+ /**
6
+ * Key administration is Cognito-only: no capability in the catalog grants
7
+ * minting, listing, or revoking keys, so a key can never widen itself.
8
+ */
5
9
  async function requireCognitoForApiKeys(label) {
6
- assertCognitoOnlyCommand(label);
10
+ requireApiKeyCapability(null, label);
7
11
  return ensureCognitoToken();
8
12
  }
9
13
  function collectRepeatedOption(value, previous) {
10
14
  return [...previous, value];
11
15
  }
16
+ /**
17
+ * Parse repeated `--capability` values. Comma-separated values are accepted in
18
+ * one flag too, so `--capability files:read,search:query` and two flags agree.
19
+ * Unknown names are rejected locally with the catalog (the server rejects them
20
+ * too — this just saves a round trip and names the valid set).
21
+ */
22
+ function parseCapabilities(values) {
23
+ const parsed = [];
24
+ for (const raw of values) {
25
+ for (const entry of raw.split(",")) {
26
+ const cap = entry.trim();
27
+ if (!cap)
28
+ continue;
29
+ if (!isApiKeyCapability(cap)) {
30
+ throw new Error(`Unknown capability '${cap}'. Supported: ${API_KEY_CAPABILITIES.join(", ")}`);
31
+ }
32
+ parsed.push(cap);
33
+ }
34
+ }
35
+ return [...new Set(parsed)];
36
+ }
37
+ function hasDeployCapability(capabilities) {
38
+ return capabilities.some((cap) => cap === "deploy:write" || cap === "deploy:read");
39
+ }
40
+ /**
41
+ * Deploy apps for the mint body. A deploy-capable key with no `--deploy-app`
42
+ * narrowing defaults to `["*"]` — every app its owner can reach at use time —
43
+ * matching hq-pro's `parseDeployScope`. `--deploy-app` still narrows to ids.
44
+ */
45
+ function resolveDeployApps(deployApp) {
46
+ const apps = [...new Set(deployApp.map((app) => app.trim()).filter(Boolean))];
47
+ if (apps.length === 0 || apps.includes(DEPLOY_APP_ALL)) {
48
+ return [DEPLOY_APP_ALL];
49
+ }
50
+ return apps;
51
+ }
52
+ function formatCapabilities(capabilities) {
53
+ return capabilities && capabilities.length > 0 ? capabilities.join(", ") : "-";
54
+ }
12
55
  function formatMaybe(value) {
13
56
  return value ?? "-";
14
57
  }
@@ -60,6 +103,7 @@ function renderApiKeysTable(apiKeys) {
60
103
  keyId: apiKey.keyId,
61
104
  name: apiKey.name,
62
105
  permission: apiKey.scope.permission,
106
+ capabilities: formatCapabilities(apiKey.scope.capabilities),
63
107
  prefixes: formatPrefixes(apiKey.scope.allowedPrefixes),
64
108
  deployApps: formatDeployApps(apiKey.scope.deploy),
65
109
  status: apiKey.status,
@@ -69,6 +113,7 @@ function renderApiKeysTable(apiKeys) {
69
113
  const keyIdWidth = Math.max(6, ...rows.map((row) => row.keyId.length));
70
114
  const nameWidth = Math.max(4, ...rows.map((row) => row.name.length));
71
115
  const permissionWidth = Math.max(10, ...rows.map((row) => row.permission.length));
116
+ const capabilitiesWidth = Math.max(12, ...rows.map((row) => row.capabilities.length));
72
117
  const prefixesWidth = Math.max(8, ...rows.map((row) => row.prefixes.length));
73
118
  const deployWidth = Math.max(6, ...rows.map((row) => row.deployApps.length));
74
119
  const statusWidth = Math.max(6, ...rows.map((row) => row.status.length));
@@ -78,6 +123,7 @@ function renderApiKeysTable(apiKeys) {
78
123
  "KEY ID".padEnd(keyIdWidth),
79
124
  "NAME".padEnd(nameWidth),
80
125
  "PERMISSION".padEnd(permissionWidth),
126
+ "CAPABILITIES".padEnd(capabilitiesWidth),
81
127
  "PREFIXES".padEnd(prefixesWidth),
82
128
  "DEPLOY".padEnd(deployWidth),
83
129
  "STATUS".padEnd(statusWidth),
@@ -90,6 +136,7 @@ function renderApiKeysTable(apiKeys) {
90
136
  row.keyId.padEnd(keyIdWidth),
91
137
  row.name.padEnd(nameWidth),
92
138
  row.permission.padEnd(permissionWidth),
139
+ row.capabilities.padEnd(capabilitiesWidth),
93
140
  row.prefixes.padEnd(prefixesWidth),
94
141
  row.deployApps.padEnd(deployWidth),
95
142
  row.status.padEnd(statusWidth),
@@ -107,17 +154,40 @@ export function registerApiKeysCommand(program) {
107
154
  .command("create")
108
155
  .description("Create a new API key (vault secrets and/or scoped deploy via --deploy-app)")
109
156
  .requiredOption("--name <label>", "Human-readable label for the API key")
110
- .option("--scope <prefix>", "Allowed secret prefix (repeatable)", collectRepeatedOption, [])
111
- .option("--deploy-app <id>", "Deploy app id/slug allowed for publish (repeatable)", collectRepeatedOption, [])
112
- .option("--permission <level>", "Secret permission level: read | write | admin (required when --scope is set)", "read")
157
+ .option("--scope <prefix>", "Secret scope (repeatable): exact name or slash descendants (FOO or FOO/...), not underscore siblings (FOO_BAR)", collectRepeatedOption, [])
158
+ .option("--capability <cap>", `Capability to grant (repeatable, comma-separated ok): ${API_KEY_CAPABILITIES.join(" | ")}`, collectRepeatedOption, [])
159
+ .option("--deploy", `Grant deploy:write over all apps the owner can reach (apps ${DEPLOY_APP_ALL}); narrow with --deploy-app`)
160
+ .option("--deploy-app <id>", "Deploy app id/slug allowed for publish (repeatable); narrows the deploy grant", collectRepeatedOption, [])
161
+ .option("--permission <level>", "Secret permission level: read | write | admin (applies to secret scopes; defaults to read)")
113
162
  .option("--expires <ISO8601>", "Optional ISO-8601 expiry timestamp")
114
163
  .action(async (opts) => {
115
164
  try {
116
- if (opts.scope.length === 0 && opts.deployApp.length === 0) {
117
- console.error(chalk.red("Error: provide at least one --scope <prefix> and/or --deploy-app <id>."));
165
+ const capabilities = parseCapabilities(opts.capability);
166
+ const wantsDeploy = hasDeployCapability(capabilities) ||
167
+ opts.deploy === true ||
168
+ opts.deployApp.length > 0;
169
+ const wantsSecrets = opts.scope.length > 0 ||
170
+ capabilities.some((cap) => cap.startsWith("secrets:"));
171
+ if (capabilities.length === 0 && opts.scope.length === 0 && !wantsDeploy) {
172
+ console.error(chalk.red("Error: provide at least one --capability <cap>, --scope <prefix>, --deploy, and/or --deploy-app <id>."));
173
+ process.exit(1);
174
+ }
175
+ const explicitPermission = opts.permission !== undefined
176
+ ? parsePermission(opts.permission)
177
+ : undefined;
178
+ if (explicitPermission !== undefined && !wantsSecrets) {
179
+ console.error(chalk.red("Error: --permission applies to secrets only — pass --scope <prefix> or a secrets:* --capability."));
118
180
  process.exit(1);
119
181
  }
120
- const permission = parsePermission(opts.permission);
182
+ // Secret scopes keep their historical default of read. With only
183
+ // secrets:* capabilities and no explicit level, hq-pro derives it
184
+ // (write for secrets:write/secrets:share, else read).
185
+ const permission = explicitPermission ??
186
+ (opts.scope.length > 0 ? parsePermission("read") : undefined);
187
+ // Deploy capabilities travel in BOTH `capabilities` (catalog) and
188
+ // `deploy.capabilities` (app-scoped block) — hq-pro reads the latter
189
+ // for app authorization and defaults to deploy:write.
190
+ const deployCapabilities = capabilities.filter((cap) => cap === "deploy:write" || cap === "deploy:read");
121
191
  const expiresAt = parseExpires(opts.expires);
122
192
  const token = await requireCognitoForApiKeys("api-keys create");
123
193
  const companyUid = await getCompanyUid(token, apiKeys.opts().company);
@@ -128,20 +198,19 @@ export function registerApiKeysCommand(program) {
128
198
  body: {
129
199
  companyUid,
130
200
  name: opts.name,
131
- ...(opts.scope.length > 0
132
- ? { allowedPrefixes: opts.scope, permission }
133
- : {}),
134
- ...(opts.deployApp.length > 0
201
+ ...(capabilities.length > 0 ? { capabilities } : {}),
202
+ ...(opts.scope.length > 0 ? { allowedPrefixes: opts.scope } : {}),
203
+ ...(permission !== undefined ? { permission } : {}),
204
+ ...(wantsDeploy
135
205
  ? {
136
206
  deploy: {
137
- apps: opts.deployApp,
138
- capabilities: ["deploy:write"],
207
+ apps: resolveDeployApps(opts.deployApp),
208
+ capabilities: deployCapabilities.length > 0
209
+ ? deployCapabilities
210
+ : ["deploy:write"],
139
211
  },
140
212
  }
141
213
  : {}),
142
- ...(opts.scope.length === 0 && opts.deployApp.length > 0
143
- ? { permission }
144
- : {}),
145
214
  ...(expiresAt ? { expiresAt } : {}),
146
215
  },
147
216
  });
@@ -157,6 +226,7 @@ export function registerApiKeysCommand(program) {
157
226
  console.log(` Name: ${data.apiKey.name}`);
158
227
  console.log(` Company: ${data.apiKey.companyUid}`);
159
228
  console.log(` Permission: ${data.apiKey.scope.permission}`);
229
+ console.log(` Capabilities: ${formatCapabilities(data.apiKey.scope.capabilities ?? capabilities)}`);
160
230
  console.log(` Prefixes: ${formatPrefixes(data.apiKey.scope.allowedPrefixes)}`);
161
231
  console.log(` Deploy apps: ${formatDeployApps(data.apiKey.scope.deploy)}`);
162
232
  console.log(` Status: ${data.apiKey.status}`);
@@ -166,18 +236,28 @@ export function registerApiKeysCommand(program) {
166
236
  console.log("");
167
237
  console.log(chalk.bold("Usage"));
168
238
  console.log(" This key acts as you (Cognito identity), limited to the scopes above.");
239
+ if (data.apiKey.scope.allowedPrefixes.length > 0) {
240
+ console.log(chalk.dim(" Secret scopes allow the exact name and slash descendants only (FOO and FOO/...), not FOO_BAR."));
241
+ }
169
242
  console.log(" Export it for automation (never falls back to a session):");
170
243
  console.log(`\n export HQ_API_KEY='${data.key.value}'\n`);
171
244
  console.log(" Vault secrets:");
172
245
  console.log(" hq secrets get <NAME> --reveal");
173
246
  console.log(" hq secrets exec --only <NAME> -- <command>");
247
+ console.log(" hq secrets list --company <cmp_uid> (secrets:read)");
248
+ console.log(" hq secrets set <NAME> --from-stdin --company <cmp_uid> (secrets:write)");
174
249
  console.log(" Or HTTP: POST /v1/keys/secrets/fetch with Authorization: Bearer <key>");
250
+ console.log(chalk.dim(" Company-scoped commands need --company <cmp_uid> (or HQ_COMPANY_UID) — slug lookup needs a session."));
175
251
  if (data.apiKey.scope.deploy?.apps?.length) {
176
- console.log(" Deploy (scoped apps only):");
177
- console.log(" Authorization: Bearer <key> against the hq-deploy API");
252
+ const deployApps = data.apiKey.scope.deploy.apps;
253
+ console.log(deployApps.includes(DEPLOY_APP_ALL)
254
+ ? " Deploy (every app the key owner can access):"
255
+ : " Deploy (scoped apps only):");
256
+ console.log(" Authorization: Bearer <key> against https://api.indigo-hq.com");
178
257
  console.log(chalk.dim(" Cannot change access-mode, password, or mint hqd_ keys."));
179
258
  }
180
- console.log(chalk.dim(" Unsupported under HQ_API_KEY: secrets list/set/share/acl (use a Cognito session)."));
259
+ console.log(chalk.dim(` Usable in hq-cli with HQ_API_KEY: ${CLI_API_KEY_CAPABILITIES.join(", ")}.`));
260
+ console.log(chalk.dim(` Cognito session still required for: ${unusableApiKeyCapabilities().join(", ")} (deploy:* is consumed by hq-deploy).`));
181
261
  }
182
262
  catch (err) {
183
263
  console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
@@ -0,0 +1,90 @@
1
+ /**
2
+ * `hq core <name>` — hidden host for HQ scaffold scripts that ship inside this
3
+ * package rather than inside the user's HQ tree.
4
+ *
5
+ * ## Why hidden
6
+ *
7
+ * These are not a public CLI surface. Every one of them is invoked by an HQ
8
+ * skill, hook, or another script — never typed by a person — and several are
9
+ * maintainer tools that would be actively harmful if a user ran them against
10
+ * their own install by mistake. Hiding them keeps `hq --help` describing the
11
+ * product rather than its plumbing. Hidden is discoverability control, not
12
+ * authorization: `hq core <name>` still dispatches normally, and
13
+ * `hq core --help` still lists the group's own contents.
14
+ *
15
+ * ## Why a manifest
16
+ *
17
+ * The direct commands and indexed rebuild targets each come from data tables,
18
+ * rather than one hand-written action per asset. The target table keeps all ten
19
+ * rebuilders behind one command while retaining the one-to-one asset mapping.
20
+ * It also gives the packaging test something to iterate: every entry must
21
+ * resolve to a real bundled asset.
22
+ *
23
+ * ## Root binding is per-entry and load-bearing
24
+ *
25
+ * Each entry declares how its ORIGINAL script found its root, and the wrapper
26
+ * reproduces exactly that. `"live"` scripts had a self-location fallback, so the
27
+ * CLI resolves and injects a root; `"cwd"` scripts had none — they read the
28
+ * caller's cwd — so the CLI injects nothing and leaves them in it. See
29
+ * `ScaffoldRoot`.
30
+ */
31
+ import { Command } from "commander";
32
+ /**
33
+ * Which tree a scaffold script operates on, mirroring how the ORIGINAL script
34
+ * found its root before it moved. Getting this wrong is not cosmetic: injecting a
35
+ * root into a script that derived one from cwd silently retargets it.
36
+ *
37
+ * "live" The original fell back to its own location inside the HQ tree
38
+ * (`${HQ_ROOT:-$(dirname $0)/../..}`). The CLI resolves the live root
39
+ * and exports it, reproducing that fallback.
40
+ *
41
+ * "cwd" The original derived its root from the CALLER's cwd
42
+ * (`git rev-parse --show-toplevel || pwd`, a cwd walk, or an argument).
43
+ * The CLI injects NOTHING and runs it in the caller's cwd, so it keeps
44
+ * resolving exactly as it always did. Any root the caller already has in
45
+ * the environment still wins, because the environment passes through
46
+ * untouched.
47
+ *
48
+ * There is deliberately no "source" mode: release-source tooling — the linters,
49
+ * generators, and validators that rewrite checked-in artifacts — stays
50
+ * scaffold-owned. hq-core's own CI executes those directly, so hosting them here
51
+ * would mean a linter fix could not be validated until a CLI release was
52
+ * published. See the scaffold-vs-cli-code-ownership policy.
53
+ */
54
+ export type ScaffoldRoot = "live" | "cwd";
55
+ type ScaffoldAsset = {
56
+ /** Path under `assets/scaffold/`. */
57
+ asset: string;
58
+ /** Which tree this script reads and writes. */
59
+ root: ScaffoldRoot;
60
+ /** One-line summary, shown in `hq core --help`. */
61
+ summary: string;
62
+ };
63
+ export type ScaffoldCommand = ScaffoldAsset & {
64
+ /** Direct subcommand name — `hq core <name>`. */
65
+ name: string;
66
+ };
67
+ export type RebuildIndexTarget = ScaffoldAsset & {
68
+ /** Rebuild target — `hq core rebuild-index <target>`. */
69
+ target: string;
70
+ };
71
+ /**
72
+ * The ten index rebuild targets. The command registration below intentionally
73
+ * loops over this table for lookup, so adding a target never requires another
74
+ * action handler and every target retains its own bundled asset.
75
+ */
76
+ export declare const REBUILD_INDEX_TARGETS: RebuildIndexTarget[];
77
+ /**
78
+ * The relocated scaffold scripts with direct `hq core <name>` commands.
79
+ *
80
+ * Ordering is by group, then alphabetical, so a reader can see the shape of
81
+ * what moved. Names match the original script basenames minus the extension,
82
+ * because every existing caller already refers to them that way and a rename
83
+ * would make the forwarders harder to audit against this table.
84
+ */
85
+ export declare const SCAFFOLD_COMMANDS: ScaffoldCommand[];
86
+ /** Every bundled asset, used by packaging and interpreter tests. */
87
+ export declare const SCAFFOLD_ASSETS: ScaffoldAsset[];
88
+ export declare function registerCoreCommands(program: Command): Command;
89
+ export {};
90
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1,279 @@
1
+ /**
2
+ * `hq core <name>` — hidden host for HQ scaffold scripts that ship inside this
3
+ * package rather than inside the user's HQ tree.
4
+ *
5
+ * ## Why hidden
6
+ *
7
+ * These are not a public CLI surface. Every one of them is invoked by an HQ
8
+ * skill, hook, or another script — never typed by a person — and several are
9
+ * maintainer tools that would be actively harmful if a user ran them against
10
+ * their own install by mistake. Hiding them keeps `hq --help` describing the
11
+ * product rather than its plumbing. Hidden is discoverability control, not
12
+ * authorization: `hq core <name>` still dispatches normally, and
13
+ * `hq core --help` still lists the group's own contents.
14
+ *
15
+ * ## Why a manifest
16
+ *
17
+ * The direct commands and indexed rebuild targets each come from data tables,
18
+ * rather than one hand-written action per asset. The target table keeps all ten
19
+ * rebuilders behind one command while retaining the one-to-one asset mapping.
20
+ * It also gives the packaging test something to iterate: every entry must
21
+ * resolve to a real bundled asset.
22
+ *
23
+ * ## Root binding is per-entry and load-bearing
24
+ *
25
+ * Each entry declares how its ORIGINAL script found its root, and the wrapper
26
+ * reproduces exactly that. `"live"` scripts had a self-location fallback, so the
27
+ * CLI resolves and injects a root; `"cwd"` scripts had none — they read the
28
+ * caller's cwd — so the CLI injects nothing and leaves them in it. See
29
+ * `ScaffoldRoot`.
30
+ */
31
+ import { Option } from "commander";
32
+ import { resolveLiveRoot } from "../utils/hq-roots.js";
33
+ import { runBundledScript } from "../utils/run-bundled-script.js";
34
+ /**
35
+ * The ten index rebuild targets. The command registration below intentionally
36
+ * loops over this table for lookup, so adding a target never requires another
37
+ * action handler and every target retains its own bundled asset.
38
+ */
39
+ export const REBUILD_INDEX_TARGETS = [
40
+ {
41
+ target: "all",
42
+ asset: "core/scripts/rebuild-all-indexes.sh",
43
+ root: "live",
44
+ summary: "Regenerate every INDEX.md across the HQ tree",
45
+ },
46
+ {
47
+ target: "companies",
48
+ asset: "core/scripts/rebuild-companies-index.sh",
49
+ root: "live",
50
+ summary: "Regenerate companies/INDEX.md",
51
+ },
52
+ {
53
+ target: "company-knowledge",
54
+ asset: "core/scripts/rebuild-company-knowledge-index.sh",
55
+ root: "live",
56
+ summary: "Regenerate a company's knowledge INDEX.md",
57
+ },
58
+ {
59
+ target: "orchestrator",
60
+ asset: "core/scripts/rebuild-orchestrator-index.sh",
61
+ root: "live",
62
+ summary: "Regenerate the orchestrator workspace INDEX.md",
63
+ },
64
+ {
65
+ target: "projects",
66
+ asset: "core/scripts/rebuild-projects-index.sh",
67
+ root: "live",
68
+ summary: "Regenerate the projects INDEX.md",
69
+ },
70
+ {
71
+ target: "public-knowledge",
72
+ asset: "core/scripts/rebuild-public-knowledge-index.sh",
73
+ root: "live",
74
+ summary: "Regenerate core/knowledge/public/INDEX.md",
75
+ },
76
+ {
77
+ target: "reports",
78
+ asset: "core/scripts/rebuild-reports-index.sh",
79
+ root: "live",
80
+ summary: "Regenerate the reports INDEX.md",
81
+ },
82
+ {
83
+ target: "social-drafts",
84
+ asset: "core/scripts/rebuild-social-drafts-index.sh",
85
+ root: "live",
86
+ summary: "Regenerate workspace/social-drafts/INDEX.md",
87
+ },
88
+ {
89
+ target: "threads",
90
+ asset: "core/scripts/rebuild-threads-index.sh",
91
+ root: "live",
92
+ summary: "Regenerate the session-threads INDEX.md",
93
+ },
94
+ {
95
+ target: "workers",
96
+ asset: "core/scripts/rebuild-workers-index.sh",
97
+ root: "live",
98
+ summary: "Regenerate the workers INDEX.md",
99
+ },
100
+ ];
101
+ /**
102
+ * The relocated scaffold scripts with direct `hq core <name>` commands.
103
+ *
104
+ * Ordering is by group, then alphabetical, so a reader can see the shape of
105
+ * what moved. Names match the original script basenames minus the extension,
106
+ * because every existing caller already refers to them that way and a rename
107
+ * would make the forwarders harder to audit against this table.
108
+ */
109
+ export const SCAFFOLD_COMMANDS = [
110
+ // ---- One-shot migrations and maintenance (live tree) ----
111
+ {
112
+ name: "archive-old-threads",
113
+ asset: "core/scripts/archive-old-threads.sh",
114
+ root: "live",
115
+ summary: "Archive aged session-thread files",
116
+ },
117
+ {
118
+ name: "backfill-company-skill-mirrors",
119
+ asset: "core/scripts/backfill-company-skill-mirrors.sh",
120
+ root: "cwd",
121
+ summary: "One-shot: mirror company skills into place",
122
+ },
123
+ {
124
+ name: "backfill-workspace-mirror",
125
+ asset: "core/scripts/backfill-workspace-mirror.sh",
126
+ root: "cwd",
127
+ summary: "One-shot: mirror threads into company workspaces",
128
+ },
129
+ {
130
+ name: "detect-stale-core-policy-mirror",
131
+ asset: "core/scripts/detect-stale-core-policy-mirror.sh",
132
+ root: "live",
133
+ summary: "Find (and prune) stale personal-policy mirrors in core",
134
+ },
135
+ {
136
+ name: "qmd-reindex-after-sync",
137
+ asset: "core/scripts/qmd-reindex-after-sync.sh",
138
+ root: "cwd",
139
+ summary: "Refresh qmd collections after a sync",
140
+ },
141
+ // ---- Reporting and utilities (live tree) ----
142
+ {
143
+ name: "codex-skill-bridge",
144
+ asset: "core/scripts/codex-skill-bridge.sh",
145
+ root: "live",
146
+ summary: "Install/inspect the Codex skill bridge",
147
+ },
148
+ {
149
+ name: "hq-status-summary",
150
+ asset: "core/scripts/hq-status-summary.sh",
151
+ root: "cwd",
152
+ summary: "Summarize working-tree status across the HQ tree",
153
+ },
154
+ {
155
+ name: "ontology-readme-drift",
156
+ asset: "core/scripts/ontology-readme-drift.sh",
157
+ root: "live",
158
+ summary: "Check a company's ontology README for drift",
159
+ },
160
+ {
161
+ name: "resize-screenshot",
162
+ asset: "core/scripts/resize-screenshot.sh",
163
+ root: "cwd",
164
+ summary: "Downscale a screenshot for context efficiency",
165
+ },
166
+ {
167
+ name: "token-usage-report",
168
+ asset: "core/scripts/token-usage-report.sh",
169
+ root: "cwd",
170
+ summary: "Report session token usage",
171
+ },
172
+ {
173
+ name: "worktree",
174
+ asset: "core/scripts/worktree.sh",
175
+ root: "live",
176
+ summary: "Create a git worktree under workspace/worktrees/",
177
+ },
178
+ ];
179
+ /** Every bundled asset, used by packaging and interpreter tests. */
180
+ export const SCAFFOLD_ASSETS = [
181
+ ...REBUILD_INDEX_TARGETS,
182
+ ...SCAFFOLD_COMMANDS,
183
+ ];
184
+ /**
185
+ * Resolve the tree an entry runs against, and the cwd to run it in.
186
+ *
187
+ * For "live" entries cwd is set to the resolved root, reproducing the
188
+ * self-location fallback the original script had when it lived in the tree.
189
+ *
190
+ * For "cwd" entries nothing is resolved and nothing is injected. Those scripts
191
+ * derived their root from the caller's cwd — `git rev-parse --show-toplevel ||
192
+ * pwd`, a cwd walk, or a positional argument — and injecting a root would
193
+ * retarget them at the tree the CLI happens to be near instead of the tree the
194
+ * caller is standing in. That regression is not hypothetical: it made four
195
+ * release linters silently lint the real checkout instead of the fixture holding
196
+ * the violation they were asked to catch, so they reported clean and their tests
197
+ * failed with "should fail the lint, but it passed".
198
+ */
199
+ function resolveEntryRoot(entry, scope) {
200
+ if (entry.root === "cwd") {
201
+ if (scope.hqRoot) {
202
+ // An explicit override is still honored — it is the caller asking for it.
203
+ const hqRoot = resolveLiveRoot({ hqRoot: scope.hqRoot });
204
+ return { cwd: hqRoot, hqRoot };
205
+ }
206
+ return { cwd: process.cwd() };
207
+ }
208
+ const hqRoot = resolveLiveRoot({ hqRoot: scope.hqRoot });
209
+ return { cwd: hqRoot, hqRoot };
210
+ }
211
+ function runEntry(entry, scope, args) {
212
+ const { cwd, hqRoot } = resolveEntryRoot(entry, scope);
213
+ const { code } = runBundledScript({
214
+ asset: entry.asset,
215
+ args,
216
+ cwd,
217
+ hqRoot,
218
+ });
219
+ // Propagate verbatim. Several of these scripts use their exit code as their
220
+ // interface (drift detected, lint failed), so remapping it would break the
221
+ // caller's contract.
222
+ if (code !== 0)
223
+ process.exit(code);
224
+ }
225
+ function expectedUserError(message) {
226
+ return Object.assign(new Error(message), { expected: true });
227
+ }
228
+ export function registerCoreCommands(program) {
229
+ const core = program
230
+ .command("core", { hidden: true })
231
+ .description("HQ scaffold scripts hosted by the CLI (core; not a stable surface)")
232
+ // The root override lives on the GROUP, not the subcommands, so it can never
233
+ // collide with a wrapped script's own flags — everything after the
234
+ // subcommand name is passed through untouched.
235
+ .addOption(new Option("--hq-root <path>", "HQ installation to operate on (live-root commands)").hideHelp());
236
+ const runCommand = (entry, args = [], cmd, target) => {
237
+ const scope = core.opts();
238
+ // `cmd.args` is the authoritative operand list: with
239
+ // allowUnknownOption() it retains unknown flags in their original order,
240
+ // which the declared variadic argument alone does not guarantee.
241
+ const operands = cmd.args.length > 0 ? cmd.args : args;
242
+ const passthrough = target === undefined ? operands : operands.slice(1);
243
+ runEntry(entry, scope, passthrough);
244
+ };
245
+ const validTargets = REBUILD_INDEX_TARGETS.map((entry) => entry.target);
246
+ core
247
+ .command("rebuild-index <target> [args...]")
248
+ .description(`Regenerate one index (target: ${validTargets.join(", ")})`)
249
+ // Pure passthrough: the wrapped script owns its own argument grammar, so
250
+ // Commander must not interpret, validate, or reorder anything after the
251
+ // target name.
252
+ .allowUnknownOption()
253
+ .allowExcessArguments()
254
+ .helpOption(false)
255
+ .action((target, args = [], _opts, cmd) => {
256
+ const entry = REBUILD_INDEX_TARGETS.find((candidate) => candidate.target === target);
257
+ if (!entry) {
258
+ throw expectedUserError(`Unknown rebuild-index target "${target}". Valid targets: ${validTargets.join(", ")}.`);
259
+ }
260
+ runCommand(entry, args, cmd, target);
261
+ });
262
+ for (const entry of SCAFFOLD_COMMANDS) {
263
+ core
264
+ .command(entry.name)
265
+ .description(entry.summary)
266
+ // Pure passthrough: the wrapped script owns its own argument grammar, so
267
+ // Commander must not interpret, validate, or reorder anything after the
268
+ // subcommand name.
269
+ .allowUnknownOption()
270
+ .allowExcessArguments()
271
+ .helpOption(false)
272
+ .argument("[args...]", "arguments passed through to the script")
273
+ .action((args = [], _opts, cmd) => {
274
+ runCommand(entry, args, cmd);
275
+ });
276
+ }
277
+ return core;
278
+ }
279
+ //# sourceMappingURL=core.js.map
@@ -412,6 +412,27 @@ export declare function createCompanyPresignClient(input: {
412
412
  token: string;
413
413
  companyUid: string;
414
414
  }): FilesBrowseS3Client;
415
+ /**
416
+ * `FilesBrowseVaultClient` for a Bearer `hqk_` key.
417
+ *
418
+ * `VaultClient` talks to the Cognito-JWT routes directly — it never passes
419
+ * through `vaultApiFetch`, so it cannot be handed an `hqk_` token: the key
420
+ * would arrive at a JWT-only route and come back as a 401 that reads like the
421
+ * caller is logged out. Company browse/cat/get/search need only three things
422
+ * from the client, and each has a keyed answer:
423
+ *
424
+ * - the company uid — supplied explicitly (`--company cmp_…` or
425
+ * HQ_COMPANY_UID). A key is company-bound and entity slug resolution has no
426
+ * keyed route, so a slug is refused rather than guessed.
427
+ * - the bucket name — unused on this path (see the constant above).
428
+ * - the caller's explicit grants — `GET /v1/keys/files/grants` (files:read),
429
+ * so the `shared-with-you` vs `role-bypass` column stays accurate.
430
+ *
431
+ * The identity surfaces a key cannot reach (`sts.vend`/`vendSelf` for the
432
+ * personal vault, `entity.get`, `listMyMemberships` for the cross-company
433
+ * roll-up) throw a fail-closed error naming the Cognito requirement.
434
+ */
435
+ export declare function createApiKeyBrowseVaultClient(token: string): FilesBrowseVaultClient & FilesSharedWithMeVaultClient;
415
436
  /**
416
437
  * Wire `hq files browse` + `hq files cat` onto an existing `files`
417
438
  * Commander group. `registerFilesCommand` in files.ts builds the group