@indigoai-us/hq-cli 5.77.14 → 5.79.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 (309) hide show
  1. package/CHANGELOG.md +31 -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/meetings.js +16 -9
  31. package/dist/commands/members.js +16 -5
  32. package/dist/commands/pack-install.d.ts +14 -0
  33. package/dist/commands/pack-install.js +42 -2
  34. package/dist/commands/pkg-install.js +39 -2
  35. package/dist/commands/run.js +6 -2
  36. package/dist/commands/secrets.js +120 -65
  37. package/dist/main.js +6 -0
  38. package/dist/utils/api-key-command-gate.d.ts +45 -0
  39. package/dist/utils/api-key-command-gate.js +51 -0
  40. package/dist/utils/hq-roots.d.ts +91 -0
  41. package/dist/utils/hq-roots.js +212 -0
  42. package/dist/utils/resolve-vault-credential.d.ts +63 -3
  43. package/dist/utils/resolve-vault-credential.js +152 -6
  44. package/dist/utils/run-bundled-script.d.ts +66 -0
  45. package/dist/utils/run-bundled-script.js +80 -0
  46. package/dist/utils/vault-api.d.ts +21 -0
  47. package/dist/utils/vault-api.js +74 -3
  48. package/package.json +7 -1
  49. package/.claude/policies/hq-cli-interactive-reads-use-sts-vend.md +0 -49
  50. package/.github/workflows/ci.yml +0 -46
  51. package/.github/workflows/publish.yml +0 -36
  52. package/.github/workflows/scripts/smoke-test-pkg.sh +0 -97
  53. package/e2e/cli.test.ts +0 -128
  54. package/eslint.config.js +0 -37
  55. package/pnpm-workspace.yaml +0 -4
  56. package/scripts/chmod-bins.mjs +0 -49
  57. package/scripts/generate-dsn.mjs +0 -26
  58. package/scripts/generate-scan-packages-table.mjs +0 -113
  59. package/scripts/smoke-sources-signals.sh +0 -103
  60. package/src/bin/hq-auth-refresh.ts +0 -43
  61. package/src/cli-version.ts +0 -13
  62. package/src/commands/__fixtures__/make-tar.ts +0 -126
  63. package/src/commands/_patterns.ts +0 -10
  64. package/src/commands/add.ts +0 -75
  65. package/src/commands/agents.test.ts +0 -527
  66. package/src/commands/agents.ts +0 -923
  67. package/src/commands/api-keys.test.ts +0 -291
  68. package/src/commands/api-keys.ts +0 -382
  69. package/src/commands/artifact-verify.test.ts +0 -177
  70. package/src/commands/auth.test.ts +0 -82
  71. package/src/commands/auth.ts +0 -213
  72. package/src/commands/billing.test.ts +0 -158
  73. package/src/commands/billing.ts +0 -146
  74. package/src/commands/channels.test.ts +0 -74
  75. package/src/commands/channels.ts +0 -91
  76. package/src/commands/cloud-demote.test.ts +0 -401
  77. package/src/commands/cloud-demote.ts +0 -278
  78. package/src/commands/cloud-provision.test.ts +0 -1117
  79. package/src/commands/cloud-provision.ts +0 -942
  80. package/src/commands/cloud.pull-all.test.ts +0 -711
  81. package/src/commands/cloud.pull-per-company.test.ts +0 -188
  82. package/src/commands/cloud.push-all.test.ts +0 -485
  83. package/src/commands/cloud.scope-excluded-warning.test.ts +0 -22
  84. package/src/commands/cloud.selectors.test.ts +0 -208
  85. package/src/commands/cloud.status.test.ts +0 -160
  86. package/src/commands/cloud.test.ts +0 -41
  87. package/src/commands/cloud.ts +0 -2130
  88. package/src/commands/company.test.ts +0 -202
  89. package/src/commands/company.ts +0 -148
  90. package/src/commands/creators.test.ts +0 -60
  91. package/src/commands/creators.ts +0 -117
  92. package/src/commands/crm.test.ts +0 -179
  93. package/src/commands/crm.ts +0 -236
  94. package/src/commands/db-migrate.ts +0 -55
  95. package/src/commands/db-provision.ts +0 -114
  96. package/src/commands/db-sql.ts +0 -124
  97. package/src/commands/db-status.ts +0 -108
  98. package/src/commands/db.ts +0 -26
  99. package/src/commands/dm.test.ts +0 -748
  100. package/src/commands/dm.ts +0 -1226
  101. package/src/commands/feedback.test.ts +0 -413
  102. package/src/commands/feedback.ts +0 -169
  103. package/src/commands/files-browse.test.ts +0 -1249
  104. package/src/commands/files-browse.ts +0 -1506
  105. package/src/commands/files-delete.test.ts +0 -484
  106. package/src/commands/files-recovery.test.ts +0 -370
  107. package/src/commands/files.test.ts +0 -722
  108. package/src/commands/files.ts +0 -1446
  109. package/src/commands/group-grants.test.ts +0 -330
  110. package/src/commands/group-grants.ts +0 -455
  111. package/src/commands/groups.test.ts +0 -44
  112. package/src/commands/groups.ts +0 -368
  113. package/src/commands/integrations.test.ts +0 -633
  114. package/src/commands/integrations.ts +0 -507
  115. package/src/commands/list.ts +0 -85
  116. package/src/commands/login.ts +0 -52
  117. package/src/commands/logout.ts +0 -30
  118. package/src/commands/marketplace-install.test.ts +0 -543
  119. package/src/commands/marketplace-security.test.ts +0 -646
  120. package/src/commands/mcp-registration.test.ts +0 -2787
  121. package/src/commands/mcp-registration.ts +0 -2612
  122. package/src/commands/mcp-status.test.ts +0 -483
  123. package/src/commands/mcp-status.ts +0 -575
  124. package/src/commands/mcp-status.us011.test.ts +0 -243
  125. package/src/commands/meetings.test.ts +0 -522
  126. package/src/commands/meetings.ts +0 -789
  127. package/src/commands/members.test.ts +0 -1474
  128. package/src/commands/members.ts +0 -1181
  129. package/src/commands/onboard-identity-guard.test.ts +0 -99
  130. package/src/commands/onboard-identity-guard.ts +0 -103
  131. package/src/commands/onboard-join.test.ts +0 -96
  132. package/src/commands/onboard-join.ts +0 -101
  133. package/src/commands/onboard-warning.test.ts +0 -26
  134. package/src/commands/onboard-warning.ts +0 -12
  135. package/src/commands/onboard.ts +0 -267
  136. package/src/commands/outposts-heartbeat.test.ts +0 -299
  137. package/src/commands/outposts-heartbeat.ts +0 -310
  138. package/src/commands/outposts-replica-sync.test.ts +0 -272
  139. package/src/commands/outposts-self-deploy.test.ts +0 -243
  140. package/src/commands/outposts.test.ts +0 -1039
  141. package/src/commands/outposts.ts +0 -1935
  142. package/src/commands/pack-install-secret-authorization.test.ts +0 -115
  143. package/src/commands/pack-install.test.ts +0 -1469
  144. package/src/commands/pack-install.ts +0 -2256
  145. package/src/commands/pack-update-cache.test.ts +0 -149
  146. package/src/commands/packs-update-api-key.test.ts +0 -105
  147. package/src/commands/packs.test.ts +0 -88
  148. package/src/commands/packs.ts +0 -622
  149. package/src/commands/people.test.ts +0 -807
  150. package/src/commands/people.ts +0 -422
  151. package/src/commands/pkg-install.dispatch.test.ts +0 -103
  152. package/src/commands/pkg-install.ts +0 -221
  153. package/src/commands/pkg-list.test.ts +0 -79
  154. package/src/commands/pkg-list.ts +0 -13
  155. package/src/commands/pkg-remove.ts +0 -71
  156. package/src/commands/pkg-update.ts +0 -189
  157. package/src/commands/publish.test.ts +0 -650
  158. package/src/commands/publish.ts +0 -580
  159. package/src/commands/reindex.test.ts +0 -259
  160. package/src/commands/reindex.ts +0 -274
  161. package/src/commands/rescue.test.ts +0 -39
  162. package/src/commands/rescue.ts +0 -210
  163. package/src/commands/run.env-local.test.ts +0 -88
  164. package/src/commands/run.test.ts +0 -45
  165. package/src/commands/run.ts +0 -190
  166. package/src/commands/safe-extract.test.ts +0 -459
  167. package/src/commands/safe-extract.ts +0 -444
  168. package/src/commands/secrets-scope.test.ts +0 -56
  169. package/src/commands/secrets-scope.ts +0 -32
  170. package/src/commands/secrets.parse-destination.test.ts +0 -38
  171. package/src/commands/secrets.test.ts +0 -2050
  172. package/src/commands/secrets.ts +0 -2249
  173. package/src/commands/signals.ts +0 -351
  174. package/src/commands/skill.test.ts +0 -770
  175. package/src/commands/skill.ts +0 -796
  176. package/src/commands/sources.ts +0 -362
  177. package/src/commands/sync-mode.test.ts +0 -366
  178. package/src/commands/sync-mode.ts +0 -387
  179. package/src/commands/sync-narrow.test.ts +0 -633
  180. package/src/commands/sync-narrow.ts +0 -555
  181. package/src/commands/sync.ts +0 -165
  182. package/src/commands/team-sync.ts +0 -628
  183. package/src/commands/update.ts +0 -71
  184. package/src/commands/whoami.ts +0 -83
  185. package/src/commands/workers.test.ts +0 -158
  186. package/src/commands/workers.ts +0 -301
  187. package/src/index.test.ts +0 -32
  188. package/src/index.ts +0 -20
  189. package/src/lib/db/control-plane.test.ts +0 -59
  190. package/src/lib/db/control-plane.ts +0 -113
  191. package/src/lib/db/local.test.ts +0 -81
  192. package/src/lib/db/local.ts +0 -148
  193. package/src/lib/db/migrate.test.ts +0 -133
  194. package/src/lib/db/migrate.ts +0 -137
  195. package/src/lib/db/paths.test.ts +0 -112
  196. package/src/lib/db/paths.ts +0 -128
  197. package/src/lib/db/remote-engine.test.ts +0 -44
  198. package/src/lib/db/remote-engine.ts +0 -148
  199. package/src/lib/db/remote-sql.test.ts +0 -32
  200. package/src/lib/db/remote-sql.ts +0 -62
  201. package/src/lib/db/sql.test.ts +0 -106
  202. package/src/lib/db/sql.ts +0 -192
  203. package/src/lib/hq-cloud-dep.smoke.test.ts +0 -75
  204. package/src/lib/local-tree-diff.test.ts +0 -301
  205. package/src/lib/local-tree-diff.ts +0 -362
  206. package/src/lib/narrow-hint-banner.test.ts +0 -235
  207. package/src/lib/narrow-hint-banner.ts +0 -212
  208. package/src/lib/plan-limit-nag.test.ts +0 -317
  209. package/src/lib/plan-limit-nag.ts +0 -264
  210. package/src/main.ts +0 -371
  211. package/src/node-preflight.test.ts +0 -60
  212. package/src/node-preflight.ts +0 -67
  213. package/src/outpost/session-heartbeat-bounds.test.ts +0 -195
  214. package/src/outpost/session-heartbeat-guard.test.ts +0 -105
  215. package/src/outpost/session-heartbeat-publisher.test.ts +0 -178
  216. package/src/outpost/session-heartbeat-publisher.ts +0 -186
  217. package/src/outpost/session-heartbeat-retain-guard.test.ts +0 -126
  218. package/src/outpost/session-heartbeat.test.ts +0 -459
  219. package/src/outpost/session-heartbeat.ts +0 -877
  220. package/src/packaging.test.ts +0 -109
  221. package/src/run/__fixtures__/discover-schemas/example.env.schema +0 -4
  222. package/src/run/discover-schemas.test.ts +0 -153
  223. package/src/run/discover-schemas.ts +0 -79
  224. package/src/run/hq-plugin.test.ts +0 -371
  225. package/src/run/hq-plugin.ts +0 -277
  226. package/src/run/varlock-shape.test.ts +0 -57
  227. package/src/schemas/hq-package.schema.json +0 -155
  228. package/src/sentry-before-send.test.ts +0 -359
  229. package/src/sentry-before-send.ts +0 -221
  230. package/src/sentry-epipe.test.ts +0 -37
  231. package/src/sentry-release.test.ts +0 -54
  232. package/src/sentry.test.ts +0 -24
  233. package/src/sentry.ts +0 -54
  234. package/src/strategies/link.ts +0 -62
  235. package/src/strategies/merge.ts +0 -142
  236. package/src/types.ts +0 -146
  237. package/src/utils/__fixtures__/scan-packages.generated-block.sh +0 -23
  238. package/src/utils/auth-error.test.ts +0 -40
  239. package/src/utils/auth-error.ts +0 -42
  240. package/src/utils/billing-gate.test.ts +0 -95
  241. package/src/utils/billing-gate.ts +0 -228
  242. package/src/utils/breadcrumb-buffer.ts +0 -18
  243. package/src/utils/cli-telemetry.test.ts +0 -153
  244. package/src/utils/cli-telemetry.ts +0 -61
  245. package/src/utils/cognito-session.machine.test.ts +0 -109
  246. package/src/utils/cognito-session.refresh.test.ts +0 -84
  247. package/src/utils/cognito-session.test.ts +0 -328
  248. package/src/utils/cognito-session.ts +0 -448
  249. package/src/utils/company-selection-error.test.ts +0 -42
  250. package/src/utils/company-selection-error.ts +0 -45
  251. package/src/utils/contribution-table.ts +0 -83
  252. package/src/utils/environmental-error.test.ts +0 -45
  253. package/src/utils/environmental-error.ts +0 -39
  254. package/src/utils/epipe.test.ts +0 -28
  255. package/src/utils/epipe.ts +0 -29
  256. package/src/utils/expected-cli-error.test.ts +0 -28
  257. package/src/utils/expected-cli-error.ts +0 -39
  258. package/src/utils/feedback-diagnostics.test.ts +0 -183
  259. package/src/utils/feedback-diagnostics.ts +0 -123
  260. package/src/utils/feedback-screenshots.test.ts +0 -134
  261. package/src/utils/feedback-screenshots.ts +0 -124
  262. package/src/utils/feedback-versions.test.ts +0 -98
  263. package/src/utils/feedback-versions.ts +0 -68
  264. package/src/utils/git.ts +0 -74
  265. package/src/utils/integrity.ts +0 -59
  266. package/src/utils/intercepted-process-exit.test.ts +0 -37
  267. package/src/utils/intercepted-process-exit.ts +0 -36
  268. package/src/utils/login-provider.test.ts +0 -42
  269. package/src/utils/login-provider.ts +0 -30
  270. package/src/utils/manifest.test.ts +0 -167
  271. package/src/utils/manifest.ts +0 -131
  272. package/src/utils/pack-contributions.test.ts +0 -603
  273. package/src/utils/pack-contributions.ts +0 -450
  274. package/src/utils/people.ts +0 -215
  275. package/src/utils/registry-client.ts +0 -204
  276. package/src/utils/registry.ts +0 -90
  277. package/src/utils/resolve-vault-credential.test.ts +0 -69
  278. package/src/utils/resolve-vault-credential.ts +0 -60
  279. package/src/utils/sandbox-runner-client.test.ts +0 -279
  280. package/src/utils/sandbox-runner-client.ts +0 -260
  281. package/src/utils/secrets-cache.ts +0 -183
  282. package/src/utils/sentry-identity.ts +0 -45
  283. package/src/utils/settle-with-timeout.test.ts +0 -21
  284. package/src/utils/settle-with-timeout.ts +0 -22
  285. package/src/utils/user-yaml-error.test.ts +0 -24
  286. package/src/utils/user-yaml-error.ts +0 -30
  287. package/src/utils/vault-api.test.ts +0 -536
  288. package/src/utils/vault-api.ts +0 -382
  289. package/src/utils/version-check.test.ts +0 -176
  290. package/src/utils/version-check.ts +0 -155
  291. package/src/utils/version-gate.test.ts +0 -1024
  292. package/src/utils/version-gate.ts +0 -702
  293. package/test/commands/db-tenant-isolation.test.ts +0 -94
  294. package/test/commands/db.test.ts +0 -85
  295. package/test/commands/signals.test.ts +0 -207
  296. package/test/commands/sources.test.ts +0 -231
  297. package/test/e2e/smoke-install-mcp.sh +0 -113
  298. package/test/fixtures/hq-pack-smoke-mcp/mcp/smoke-http.json +0 -1
  299. package/test/fixtures/hq-pack-smoke-mcp/package.yaml +0 -11
  300. package/test/fixtures/signals/action_item/sample.md +0 -16
  301. package/test/fixtures/signals/summary/sample.md +0 -12
  302. package/test/fixtures/sources/meetings/sample.md +0 -25
  303. package/test/helpers/cli-runner.ts +0 -150
  304. package/test/helpers/s3-list-mock.ts +0 -79
  305. package/test/helpers/vault-service-mock.ts +0 -295
  306. package/test/sources-signals/smoke.test.ts +0 -228
  307. package/tsconfig.json +0 -20
  308. package/vitest.config.ts +0 -11
  309. package/vitest.e2e.config.ts +0 -7
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Root resolution for CLI-hosted HQ scaffold code.
3
+ *
4
+ * When shell that used to live inside the HQ scaffold moves into this npm
5
+ * package, it loses the one thing it relied on: `BASH_SOURCE`/`$0` pointed at
6
+ * the user's live HQ tree, so "where am I" and "where is HQ" were the same
7
+ * answer. Inside a globally installed package they are three different answers,
8
+ * and conflating any two of them silently corrupts the wrong tree.
9
+ *
10
+ * liveRoot The user's HQ installation — companies/, workspace/, personal/,
11
+ * the installed .claude/ and core/. This is runtime state. Hidden
12
+ * runtime commands operate here.
13
+ *
14
+ * packageRoot This npm package's own directory, where bundled scaffold assets
15
+ * ship. Read-only in practice: a global install may sit in a
16
+ * root-owned prefix. NEVER usable as liveRoot.
17
+ *
18
+ * There is deliberately no third "source root". Release-source tooling — the
19
+ * linters, generators, and validators that rewrite checked-in artifacts — stays
20
+ * scaffold-owned, so nothing here ever needs to resolve an hq-core checkout. See
21
+ * the scaffold-vs-cli-code-ownership policy for why.
22
+ *
23
+ * The invariant that matters most: `resolveLiveRoot` never consults
24
+ * `import.meta.url`. A relocated script asking "where is HQ" must get the live
25
+ * tree, not the package it happens to be bundled in.
26
+ */
27
+ import * as fs from "fs";
28
+ import * as path from "path";
29
+ import { fileURLToPath } from "url";
30
+ /** This package's name, used to identify its root when walking upward. */
31
+ const CLI_PACKAGE_NAME = "@indigoai-us/hq-cli";
32
+ /**
33
+ * A root that cannot be resolved is the caller's state — a wrong `--hq-root`, or a
34
+ * command run from outside any HQ tree. Marking
35
+ * these `expected` makes the top-level handler print the message and skip Sentry;
36
+ * an unmarked error there prints NOTHING and only ships a crash report, which is
37
+ * the worst possible outcome for a misconfiguration the user can fix.
38
+ *
39
+ * Deliberately not used for packaging faults — a missing bundled asset IS a
40
+ * defect and should reach Sentry.
41
+ */
42
+ function rootError(message) {
43
+ const err = new Error(message);
44
+ err.expected = true;
45
+ return err;
46
+ }
47
+ /** Where bundled scaffold assets live, relative to the package root. */
48
+ export const BUNDLED_ASSET_DIR = path.join("assets", "scaffold");
49
+ /**
50
+ * Does this directory look like an HQ tree root?
51
+ *
52
+ * `companies/` is the load-bearing marker — it is the source of truth for
53
+ * tenants and exists in every real install. The second clause tolerates the
54
+ * three shapes a tree can legitimately be in: a full install, a scaffold
55
+ * checkout without a personal overlay, and a personal-only overlay.
56
+ */
57
+ export function isHqRoot(dir) {
58
+ return (fs.existsSync(path.join(dir, "companies")) &&
59
+ (fs.existsSync(path.join(dir, ".claude")) ||
60
+ fs.existsSync(path.join(dir, "core")) ||
61
+ fs.existsSync(path.join(dir, "personal"))));
62
+ }
63
+ function realpathOrResolve(p) {
64
+ try {
65
+ return fs.realpathSync(p);
66
+ }
67
+ catch {
68
+ return path.resolve(p);
69
+ }
70
+ }
71
+ let cachedPackageRoot;
72
+ /**
73
+ * This package's installed root — the directory holding its `package.json`.
74
+ *
75
+ * Walks up from the compiled module (`dist/utils/hq-roots.js`) until it finds a
76
+ * `package.json` whose name matches, rather than hard-coding `..` hops, so the
77
+ * answer survives a change in output layout.
78
+ */
79
+ export function packageRoot() {
80
+ if (cachedPackageRoot === null) {
81
+ throw new Error(`Could not locate the ${CLI_PACKAGE_NAME} package root from ${import.meta.url}.`);
82
+ }
83
+ if (cachedPackageRoot !== undefined)
84
+ return cachedPackageRoot;
85
+ let dir = path.dirname(fileURLToPath(import.meta.url));
86
+ for (;;) {
87
+ const manifest = path.join(dir, "package.json");
88
+ if (fs.existsSync(manifest)) {
89
+ try {
90
+ const parsed = JSON.parse(fs.readFileSync(manifest, "utf8"));
91
+ if (parsed.name === CLI_PACKAGE_NAME) {
92
+ cachedPackageRoot = realpathOrResolve(dir);
93
+ return cachedPackageRoot;
94
+ }
95
+ }
96
+ catch {
97
+ // A malformed package.json on the way up is not our package; keep going.
98
+ }
99
+ }
100
+ const parent = path.dirname(dir);
101
+ if (parent === dir)
102
+ break;
103
+ dir = parent;
104
+ }
105
+ cachedPackageRoot = null;
106
+ throw new Error(`Could not locate the ${CLI_PACKAGE_NAME} package root from ${import.meta.url}.`);
107
+ }
108
+ /** Reset the memoized package root. Tests only. */
109
+ export function __resetPackageRootCache() {
110
+ cachedPackageRoot = undefined;
111
+ }
112
+ /**
113
+ * Resolve the user's live HQ installation.
114
+ *
115
+ * Precedence: `--hq-root` → `HQ_ROOT` → `CLAUDE_PROJECT_DIR` → walk up from cwd.
116
+ *
117
+ * ## An explicit root is trusted; a discovered one must be recognized
118
+ *
119
+ * The FIRST explicit candidate present wins outright — there is no fall-through
120
+ * past it, because silently operating on a different tree than the caller named
121
+ * is the worst available outcome.
122
+ *
123
+ * That explicit candidate is checked only for the two things that are always
124
+ * wrong: it must be a directory, and it must not be inside {@link packageRoot}
125
+ * (that is this package, not anyone's HQ). It is deliberately NOT required to
126
+ * satisfy {@link isHqRoot}.
127
+ *
128
+ * Requiring markers here was tried and was wrong: the scripts these roots feed
129
+ * accepted any `HQ_ROOT` before they moved, and several callers legitimately pass
130
+ * a minimal tree — e.g. `rebuild-threads-index` against a fixture holding nothing
131
+ * but `workspace/threads/`. Enforcing markers on an explicit value turned a
132
+ * relocation into a silent contract change and broke those callers.
133
+ *
134
+ * The cwd walk is the opposite case: there the marker check is the only thing
135
+ * that can identify a root at all, so it stays mandatory.
136
+ */
137
+ export function resolveLiveRoot(opts = {}) {
138
+ const env = opts.env ?? process.env;
139
+ const candidates = [];
140
+ if (opts.hqRoot) {
141
+ candidates.push({ value: opts.hqRoot, source: "--hq-root" });
142
+ }
143
+ if (env.HQ_ROOT) {
144
+ candidates.push({ value: env.HQ_ROOT, source: "$HQ_ROOT" });
145
+ }
146
+ if (env.CLAUDE_PROJECT_DIR) {
147
+ candidates.push({
148
+ value: env.CLAUDE_PROJECT_DIR,
149
+ source: "$CLAUDE_PROJECT_DIR",
150
+ });
151
+ }
152
+ const explicit = candidates[0];
153
+ if (explicit) {
154
+ const resolved = realpathOrResolve(explicit.value);
155
+ if (isWithinPackage(resolved)) {
156
+ throw rootError(`${explicit.source} points inside the ${CLI_PACKAGE_NAME} package ` +
157
+ `(${resolved}). That is the CLI's own install directory, not an HQ tree.`);
158
+ }
159
+ if (!fs.existsSync(resolved) || !fs.statSync(resolved).isDirectory()) {
160
+ throw rootError(`${explicit.source} is not a directory: ${resolved}`);
161
+ }
162
+ return resolved;
163
+ }
164
+ // Walk up from cwd. Unlike the explicit tiers this is a guess, so failing to
165
+ // find a root here is reported as "run this from inside HQ" rather than as a
166
+ // bad value.
167
+ let dir = realpathOrResolve(opts.cwd ?? process.cwd());
168
+ for (;;) {
169
+ if (isHqRoot(dir) && !isWithinPackage(dir))
170
+ return dir;
171
+ const parent = path.dirname(dir);
172
+ if (parent === dir)
173
+ break;
174
+ dir = parent;
175
+ }
176
+ throw rootError("Could not find your HQ installation. Run this from inside your HQ " +
177
+ "directory, or pass --hq-root <path> / set $HQ_ROOT.");
178
+ }
179
+ function isWithinPackage(candidate) {
180
+ let root;
181
+ try {
182
+ root = packageRoot();
183
+ }
184
+ catch {
185
+ // If we cannot locate our own package we cannot be inside it either.
186
+ return false;
187
+ }
188
+ const rel = path.relative(root, candidate);
189
+ return rel === "" || (!rel.startsWith("..") && !path.isAbsolute(rel));
190
+ }
191
+ /**
192
+ * Absolute path to a scaffold asset bundled in this package.
193
+ *
194
+ * Refuses to resolve outside the asset directory so a manifest entry can never
195
+ * be coaxed into executing an arbitrary path, and fails loudly when the asset
196
+ * is missing — an absent asset means the packlist dropped it, which is a
197
+ * packaging bug worth surfacing rather than a runtime fallback.
198
+ */
199
+ export function resolveBundledAsset(relativePath) {
200
+ const assetDir = path.join(packageRoot(), BUNDLED_ASSET_DIR);
201
+ const resolved = path.resolve(assetDir, relativePath);
202
+ const rel = path.relative(assetDir, resolved);
203
+ if (rel.startsWith("..") || path.isAbsolute(rel)) {
204
+ throw new Error(`Bundled asset path escapes ${BUNDLED_ASSET_DIR}: ${relativePath}`);
205
+ }
206
+ if (!fs.existsSync(resolved)) {
207
+ throw new Error(`Bundled asset is missing from the installed package: ${BUNDLED_ASSET_DIR}/${relativePath}\n` +
208
+ "This is a packaging fault — the file exists in source but was not published.");
209
+ }
210
+ return resolved;
211
+ }
212
+ //# sourceMappingURL=hq-roots.js.map
@@ -1,5 +1,27 @@
1
1
  /** Vault API keys issued by `hq api-keys create` (hq-pro). */
2
2
  export declare const HQ_API_KEY_PREFIX = "hqk_";
3
+ /**
4
+ * Capability catalog for identity-bound vault API keys. MUST match hq-pro's
5
+ * `src/api-keys/capabilities.ts` — the server is authoritative for what a key
6
+ * may do; this copy exists so the CLI can name capabilities in `api-keys
7
+ * create` and in its own fail-closed messages.
8
+ */
9
+ export declare const API_KEY_CAPABILITIES: readonly ["secrets:read", "secrets:write", "secrets:share", "deploy:write", "deploy:read", "files:read", "files:write", "search:query", "agents:use", "mcp:call", "packs:install", "members:read", "members:write"];
10
+ export type ApiKeyCapability = (typeof API_KEY_CAPABILITIES)[number];
11
+ /** Deploy apps wildcard: every app the key owner can reach at use time. */
12
+ export declare const DEPLOY_APP_ALL = "*";
13
+ export declare function isApiKeyCapability(value: string): value is ApiKeyCapability;
14
+ /**
15
+ * Capabilities hq-cli can exercise with an `HQ_API_KEY`. Vault surfaces use
16
+ * parallel Bearer `hqk_` routes under `/v1/keys/…` (rewritten in
17
+ * {@link vaultApiFetch}); `deploy:*` is consumed by hq-deploy via SigV4
18
+ * introspect. Surfaces without a keyed route still fail closed.
19
+ */
20
+ export declare const CLI_API_KEY_CAPABILITIES: readonly ApiKeyCapability[];
21
+ /** True when hq-cli has a Bearer `hqk_` route for this capability. */
22
+ export declare function apiKeyCapabilityIsUsable(capability: ApiKeyCapability): boolean;
23
+ /** Catalog capabilities hq-cli cannot use with an API key yet. */
24
+ export declare function unusableApiKeyCapabilities(): ApiKeyCapability[];
3
25
  export type VaultCredential = {
4
26
  kind: "api-key";
5
27
  token: string;
@@ -23,8 +45,46 @@ export declare function resolveVaultCredential(options?: {
23
45
  interactive?: boolean;
24
46
  }): Promise<VaultCredential>;
25
47
  /**
26
- * Throw when HQ_API_KEY is set but the command only supports Cognito sessions
27
- * (list, set, ACL, api-keys admin, etc.).
48
+ * Fail-closed message for a surface an `HQ_API_KEY` cannot drive. Always names
49
+ * what an API key CAN do (granted) next to what it cannot (missing), so the
50
+ * caller can decide between minting a broader key and unsetting HQ_API_KEY.
51
+ */
52
+ export declare function apiKeyCapabilityGateMessage(capability: ApiKeyCapability | null, commandLabel: string, options?: {
53
+ routeAvailable?: boolean;
54
+ }): string;
55
+ /**
56
+ * Capability gate for a command about to run under `HQ_API_KEY`.
57
+ *
58
+ * No-op when HQ_API_KEY is unset (the Cognito path is unchanged) and when the
59
+ * capability has a CLI-reachable Bearer `hqk_` route. Otherwise throws a
60
+ * fail-closed error listing granted vs missing capabilities.
61
+ *
62
+ * - `capability: null` — the surface has no capability at all (key
63
+ * administration, interactive session flows).
64
+ * - `routeAvailable: false` — the capability exists in the catalog but this
65
+ * specific surface has no `/v1/keys` route (e.g. the secrets HEAD probe).
66
+ *
67
+ * The server re-checks the key's real grants on every call; this gate only
68
+ * stops the CLI from quietly using a Cognito session instead of the key.
69
+ */
70
+ export declare function requireApiKeyCapability(capability: ApiKeyCapability | null, commandLabel: string, options?: {
71
+ routeAvailable?: boolean;
72
+ }): void;
73
+ /**
74
+ * {@link resolveVaultCredential} behind {@link requireApiKeyCapability}: the
75
+ * gate runs BEFORE any credential work so a key that cannot drive the surface
76
+ * never reaches the network and never triggers an interactive login.
77
+ */
78
+ export declare function resolveVaultCredentialForCapability(capability: ApiKeyCapability | null, commandLabel: string, options?: {
79
+ interactive?: boolean;
80
+ routeAvailable?: boolean;
81
+ }): Promise<VaultCredential>;
82
+ /**
83
+ * Render hq-pro's capability-denial body (`_api-key-auth.ts` returns
84
+ * `{ error, granted: string[], missing: string }` on a 403) as a message that
85
+ * names the key's REAL granted set next to what the call needed. This is the
86
+ * authoritative granted-vs-missing report; the client-side gate above can only
87
+ * describe what hq-cli supports.
28
88
  */
29
- export declare function assertCognitoOnlyCommand(commandLabel: string): void;
89
+ export declare function formatApiKeyCapabilityDenial(body: unknown, fallback: string): string;
30
90
  //# sourceMappingURL=resolve-vault-credential.d.ts.map
@@ -1,6 +1,63 @@
1
1
  import { ensureCognitoToken } from "./cognito-session.js";
2
2
  /** Vault API keys issued by `hq api-keys create` (hq-pro). */
3
3
  export const HQ_API_KEY_PREFIX = "hqk_";
4
+ /**
5
+ * Capability catalog for identity-bound vault API keys. MUST match hq-pro's
6
+ * `src/api-keys/capabilities.ts` — the server is authoritative for what a key
7
+ * may do; this copy exists so the CLI can name capabilities in `api-keys
8
+ * create` and in its own fail-closed messages.
9
+ */
10
+ export const API_KEY_CAPABILITIES = [
11
+ "secrets:read",
12
+ "secrets:write",
13
+ "secrets:share",
14
+ "deploy:write",
15
+ "deploy:read",
16
+ "files:read",
17
+ "files:write",
18
+ "search:query",
19
+ "agents:use",
20
+ "mcp:call",
21
+ "packs:install",
22
+ "members:read",
23
+ "members:write",
24
+ ];
25
+ /** Deploy apps wildcard: every app the key owner can reach at use time. */
26
+ export const DEPLOY_APP_ALL = "*";
27
+ const CAPABILITY_SET = new Set(API_KEY_CAPABILITIES);
28
+ export function isApiKeyCapability(value) {
29
+ return CAPABILITY_SET.has(value);
30
+ }
31
+ /**
32
+ * Capabilities hq-cli can exercise with an `HQ_API_KEY`. Vault surfaces use
33
+ * parallel Bearer `hqk_` routes under `/v1/keys/…` (rewritten in
34
+ * {@link vaultApiFetch}); `deploy:*` is consumed by hq-deploy via SigV4
35
+ * introspect. Surfaces without a keyed route still fail closed.
36
+ */
37
+ export const CLI_API_KEY_CAPABILITIES = [
38
+ "secrets:read",
39
+ "secrets:write",
40
+ "secrets:share",
41
+ "deploy:write",
42
+ "deploy:read",
43
+ "files:read",
44
+ "files:write",
45
+ "search:query",
46
+ "agents:use",
47
+ "mcp:call",
48
+ "packs:install",
49
+ "members:read",
50
+ "members:write",
51
+ ];
52
+ const CLI_CAPABILITY_SET = new Set(CLI_API_KEY_CAPABILITIES);
53
+ /** True when hq-cli has a Bearer `hqk_` route for this capability. */
54
+ export function apiKeyCapabilityIsUsable(capability) {
55
+ return CLI_CAPABILITY_SET.has(capability);
56
+ }
57
+ /** Catalog capabilities hq-cli cannot use with an API key yet. */
58
+ export function unusableApiKeyCapabilities() {
59
+ return API_KEY_CAPABILITIES.filter((cap) => !CLI_CAPABILITY_SET.has(cap));
60
+ }
4
61
  /**
5
62
  * Raw HQ_API_KEY from the environment, trimmed. Undefined when unset/empty.
6
63
  * Does not validate prefix — use {@link resolveVaultCredential} for that.
@@ -34,15 +91,104 @@ export async function resolveVaultCredential(options) {
34
91
  });
35
92
  return { kind: "cognito", token };
36
93
  }
94
+ function expectedError(message) {
95
+ // Marked expected so main.ts prints the message and skips Sentry: a key
96
+ // presented at a surface it cannot serve is the caller's configuration,
97
+ // not an hq-cli defect.
98
+ return Object.assign(new Error(message), { expected: true });
99
+ }
100
+ function formatCapabilityList(capabilities) {
101
+ return capabilities.length > 0 ? capabilities.join(", ") : "(none)";
102
+ }
37
103
  /**
38
- * Throw when HQ_API_KEY is set but the command only supports Cognito sessions
39
- * (list, set, ACL, api-keys admin, etc.).
104
+ * Fail-closed message for a surface an `HQ_API_KEY` cannot drive. Always names
105
+ * what an API key CAN do (granted) next to what it cannot (missing), so the
106
+ * caller can decide between minting a broader key and unsetting HQ_API_KEY.
40
107
  */
41
- export function assertCognitoOnlyCommand(commandLabel) {
108
+ export function apiKeyCapabilityGateMessage(capability, commandLabel, options) {
109
+ const head = capability === null
110
+ ? `HQ_API_KEY is set; '${commandLabel}' is not supported for API keys — ` +
111
+ `no capability grants it (it needs your Cognito session).`
112
+ : options?.routeAvailable === false
113
+ ? `HQ_API_KEY is set; '${commandLabel}' is not supported for API keys — ` +
114
+ `capability '${capability}' would apply but hq-pro serves no vault ` +
115
+ `API-key route for it yet.`
116
+ : `HQ_API_KEY is set; '${commandLabel}' is not supported for API keys — ` +
117
+ `it needs capability '${capability}'.`;
118
+ return [
119
+ head,
120
+ ` Granted to hq-cli with an API key: ${formatCapabilityList(CLI_API_KEY_CAPABILITIES)}`,
121
+ ` Missing (Cognito session required): ${formatCapabilityList(unusableApiKeyCapabilities())}`,
122
+ ` Unset HQ_API_KEY to use your Cognito session.`,
123
+ ].join("\n");
124
+ }
125
+ /**
126
+ * Capability gate for a command about to run under `HQ_API_KEY`.
127
+ *
128
+ * No-op when HQ_API_KEY is unset (the Cognito path is unchanged) and when the
129
+ * capability has a CLI-reachable Bearer `hqk_` route. Otherwise throws a
130
+ * fail-closed error listing granted vs missing capabilities.
131
+ *
132
+ * - `capability: null` — the surface has no capability at all (key
133
+ * administration, interactive session flows).
134
+ * - `routeAvailable: false` — the capability exists in the catalog but this
135
+ * specific surface has no `/v1/keys` route (e.g. the secrets HEAD probe).
136
+ *
137
+ * The server re-checks the key's real grants on every call; this gate only
138
+ * stops the CLI from quietly using a Cognito session instead of the key.
139
+ */
140
+ export function requireApiKeyCapability(capability, commandLabel, options) {
42
141
  if (peekHqApiKey() === undefined)
43
142
  return;
44
- throw new Error(`HQ_API_KEY is set; '${commandLabel}' is not supported for API keys. ` +
45
- `API keys support scoped secret reads via \`hq secrets get\`, \`hq secrets exec\`, ` +
46
- `and \`hq secrets env\`. Unset HQ_API_KEY to use your Cognito session.`);
143
+ if (capability !== null &&
144
+ options?.routeAvailable !== false &&
145
+ apiKeyCapabilityIsUsable(capability)) {
146
+ return;
147
+ }
148
+ throw expectedError(apiKeyCapabilityGateMessage(capability, commandLabel, options));
149
+ }
150
+ /**
151
+ * {@link resolveVaultCredential} behind {@link requireApiKeyCapability}: the
152
+ * gate runs BEFORE any credential work so a key that cannot drive the surface
153
+ * never reaches the network and never triggers an interactive login.
154
+ */
155
+ export async function resolveVaultCredentialForCapability(capability, commandLabel, options) {
156
+ requireApiKeyCapability(capability, commandLabel, {
157
+ routeAvailable: options?.routeAvailable,
158
+ });
159
+ return resolveVaultCredential({ interactive: options?.interactive });
160
+ }
161
+ /**
162
+ * Render hq-pro's capability-denial body (`_api-key-auth.ts` returns
163
+ * `{ error, granted: string[], missing: string }` on a 403) as a message that
164
+ * names the key's REAL granted set next to what the call needed. This is the
165
+ * authoritative granted-vs-missing report; the client-side gate above can only
166
+ * describe what hq-cli supports.
167
+ */
168
+ export function formatApiKeyCapabilityDenial(body, fallback) {
169
+ const record = body !== null && typeof body === "object"
170
+ ? body
171
+ : {};
172
+ const head = typeof record.error === "string"
173
+ ? record.error
174
+ : typeof record.message === "string"
175
+ ? record.message
176
+ : fallback;
177
+ const granted = Array.isArray(record.granted)
178
+ ? record.granted.filter((cap) => typeof cap === "string")
179
+ : [];
180
+ const missing = Array.isArray(record.missing)
181
+ ? record.missing.filter((cap) => typeof cap === "string")
182
+ : typeof record.missing === "string"
183
+ ? [record.missing]
184
+ : [];
185
+ if (granted.length === 0 && missing.length === 0) {
186
+ return head;
187
+ }
188
+ return [
189
+ head,
190
+ ` Granted: ${formatCapabilityList(granted)}`,
191
+ ` Missing: ${formatCapabilityList(missing)}`,
192
+ ].join("\n");
47
193
  }
48
194
  //# sourceMappingURL=resolve-vault-credential.js.map
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Runner for scaffold shell bundled inside this package.
3
+ *
4
+ * The scripts this executes used to be invoked directly by skills, hooks, and
5
+ * other scripts. Their callers observe argv, stdin, stdout, stderr, and the exit
6
+ * code — so this runner's job is to be transparent on all five, and to hand the
7
+ * script the same environment it used to get from living inside the HQ tree.
8
+ *
9
+ * Deliberate choices:
10
+ *
11
+ * - `stdio: "inherit"`. Not piped. Piping would buffer output that callers
12
+ * stream, reorder stdout against stderr, and require re-emitting bytes we
13
+ * have no reason to touch. Inheriting also means a script that reads stdin
14
+ * (the hook payload pattern) gets the real fd, unbuffered and unconsumed.
15
+ *
16
+ * - an explicit interpreter (`bash` or `node`) rather than executing the file
17
+ * directly. The executable bit does survive `npm publish` for files that
18
+ * carry it, but relying on it makes correctness depend on a mode that a
19
+ * repack, a filesystem, or a zip round-trip can quietly drop. Naming the
20
+ * interpreter removes that dependency without changing script semantics.
21
+ * The interpreter is chosen by extension — two of the relocated assets are
22
+ * Node programs, and running those through bash fails with a shell syntax
23
+ * error on the first `const`.
24
+ *
25
+ * - the exit code is returned, never mapped. A script that exits 2 to block a
26
+ * tool call must still exit 2 through this path.
27
+ *
28
+ * - signals are surfaced as the conventional 128+n. A caller that kills a
29
+ * script needs to see termination, not a success code.
30
+ */
31
+ /**
32
+ * Which interpreter runs a bundled asset, chosen by extension.
33
+ *
34
+ * Exported so the manifest test can assert every declared asset maps to one,
35
+ * rather than discovering a mismatch at runtime on a user's machine.
36
+ */
37
+ export declare function interpreterFor(asset: string): "node" | "bash";
38
+ export type RunBundledScriptOptions = {
39
+ /** Path of the script under `assets/scaffold/`, e.g. `core/scripts/foo.sh`. */
40
+ asset: string;
41
+ /** Arguments passed through to the script, unchanged. */
42
+ args?: string[];
43
+ /** Working directory for the child. Defaults to the resolved live root. */
44
+ cwd: string;
45
+ /**
46
+ * The live HQ root. Exported as both `HQ_ROOT` and `CLAUDE_PROJECT_DIR`
47
+ * because relocated scripts read one, the other, or both — and inside the CLI
48
+ * neither is guaranteed to already be set by the caller.
49
+ */
50
+ hqRoot?: string;
51
+ /** Extra environment for the child, applied last. */
52
+ env?: Record<string, string | undefined>;
53
+ };
54
+ export type RunBundledScriptResult = {
55
+ /** The child's exit code, or 128+signal if it was terminated by one. */
56
+ code: number;
57
+ };
58
+ /**
59
+ * Execute a bundled scaffold script and return its exit code.
60
+ *
61
+ * Does not throw on a non-zero exit — a non-zero code is data here, not an
62
+ * error, because several relocated scripts use exit codes as their interface.
63
+ * Throws only when the script could not be started at all.
64
+ */
65
+ export declare function runBundledScript(opts: RunBundledScriptOptions): RunBundledScriptResult;
66
+ //# sourceMappingURL=run-bundled-script.d.ts.map
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Runner for scaffold shell bundled inside this package.
3
+ *
4
+ * The scripts this executes used to be invoked directly by skills, hooks, and
5
+ * other scripts. Their callers observe argv, stdin, stdout, stderr, and the exit
6
+ * code — so this runner's job is to be transparent on all five, and to hand the
7
+ * script the same environment it used to get from living inside the HQ tree.
8
+ *
9
+ * Deliberate choices:
10
+ *
11
+ * - `stdio: "inherit"`. Not piped. Piping would buffer output that callers
12
+ * stream, reorder stdout against stderr, and require re-emitting bytes we
13
+ * have no reason to touch. Inheriting also means a script that reads stdin
14
+ * (the hook payload pattern) gets the real fd, unbuffered and unconsumed.
15
+ *
16
+ * - an explicit interpreter (`bash` or `node`) rather than executing the file
17
+ * directly. The executable bit does survive `npm publish` for files that
18
+ * carry it, but relying on it makes correctness depend on a mode that a
19
+ * repack, a filesystem, or a zip round-trip can quietly drop. Naming the
20
+ * interpreter removes that dependency without changing script semantics.
21
+ * The interpreter is chosen by extension — two of the relocated assets are
22
+ * Node programs, and running those through bash fails with a shell syntax
23
+ * error on the first `const`.
24
+ *
25
+ * - the exit code is returned, never mapped. A script that exits 2 to block a
26
+ * tool call must still exit 2 through this path.
27
+ *
28
+ * - signals are surfaced as the conventional 128+n. A caller that kills a
29
+ * script needs to see termination, not a success code.
30
+ */
31
+ import { spawnSync } from "child_process";
32
+ import * as path from "path";
33
+ import { resolveBundledAsset } from "./hq-roots.js";
34
+ /**
35
+ * Which interpreter runs a bundled asset, chosen by extension.
36
+ *
37
+ * Exported so the manifest test can assert every declared asset maps to one,
38
+ * rather than discovering a mismatch at runtime on a user's machine.
39
+ */
40
+ export function interpreterFor(asset) {
41
+ const ext = path.extname(asset).toLowerCase();
42
+ return ext === ".mjs" || ext === ".js" || ext === ".cjs" ? "node" : "bash";
43
+ }
44
+ /**
45
+ * Execute a bundled scaffold script and return its exit code.
46
+ *
47
+ * Does not throw on a non-zero exit — a non-zero code is data here, not an
48
+ * error, because several relocated scripts use exit codes as their interface.
49
+ * Throws only when the script could not be started at all.
50
+ */
51
+ export function runBundledScript(opts) {
52
+ const script = resolveBundledAsset(opts.asset);
53
+ const env = { ...process.env };
54
+ if (opts.hqRoot) {
55
+ env.HQ_ROOT = opts.hqRoot;
56
+ env.CLAUDE_PROJECT_DIR = opts.hqRoot;
57
+ }
58
+ Object.assign(env, opts.env ?? {});
59
+ const result = spawnSync(interpreterFor(opts.asset), [script, ...(opts.args ?? [])], {
60
+ cwd: opts.cwd,
61
+ env,
62
+ stdio: "inherit",
63
+ });
64
+ if (result.error) {
65
+ throw new Error(`Failed to run bundled script ${opts.asset}: ${result.error.message}`);
66
+ }
67
+ if (result.signal) {
68
+ // Conventional shell encoding, so a caller checking for termination sees it.
69
+ const signals = {
70
+ SIGHUP: 1,
71
+ SIGINT: 2,
72
+ SIGQUIT: 3,
73
+ SIGKILL: 9,
74
+ SIGTERM: 15,
75
+ };
76
+ return { code: 128 + (signals[result.signal] ?? 0) };
77
+ }
78
+ return { code: result.status ?? 0 };
79
+ }
80
+ //# sourceMappingURL=run-bundled-script.js.map
@@ -13,6 +13,27 @@ export interface VaultApiOptions {
13
13
  query?: Record<string, string>;
14
14
  signal?: AbortSignal;
15
15
  }
16
+ /**
17
+ * Map Cognito JWT paths onto parallel Bearer `hqk_` routes under `/v1/keys/…`.
18
+ * Returns null when no keyed route exists (caller must fail closed).
19
+ *
20
+ * The table mirrors hq-pro's gateway routes, NOT its path shapes: a rewrite is
21
+ * listed only where an `hqk_`-authorized route actually exists. Two surfaces
22
+ * are therefore unmapped ON PURPOSE, and adding a rewrite for them would turn
23
+ * an explicit fail-closed error into a 404/401 that reads like a login problem:
24
+ *
25
+ * - the unversioned file ACL + share surfaces (`/files/{companyUid}/acl…`,
26
+ * `/files/{companyUid}/share-session`) — hq-pro serves these under JWT
27
+ * only. `/v1/keys/files/…` exists but covers the VERSIONED family
28
+ * (`list`, `versions`, `versions-list`, `grants`, `tombstones`, `presign`,
29
+ * `delete`, `restore`), which is a different set of handlers.
30
+ * - the notify surface (`/v1/notify/dm`, `/v1/notify/thread`) behind
31
+ * `hq agents message|thread` — there is no `/v1/keys/notify…` route.
32
+ *
33
+ * Both are additionally gated at the command layer so they fail before any
34
+ * network call; this stays the backstop for a new call site that forgets to.
35
+ */
36
+ export declare function rewritePathForApiKey(path: string): string | null;
16
37
  export declare function vaultApiFetch(opts: VaultApiOptions): Promise<Response>;
17
38
  /**
18
39
  * Public (NONE-auth) GET against the vault API — no bearer token. The