@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
package/src/types.ts DELETED
@@ -1,146 +0,0 @@
1
- /**
2
- * HQ Module Manifest Types (US-001)
3
- *
4
- * `modules.yaml` hosts two kinds of entries, discriminated by `strategy`:
5
- * - link | merge | copy → git-repo-based module sync (existing flow)
6
- * - package → hq-pack content pack installed via `hq install`
7
- * (new in hq-core v12.0.0; see
8
- * knowledge/public/hq-core/package-yaml-spec.md)
9
- */
10
-
11
- import type { ContributionKey } from './utils/contribution-table.js';
12
-
13
- export type LegacyStrategy = 'link' | 'merge' | 'copy';
14
- export type SyncStrategy = LegacyStrategy | 'package';
15
- export type AccessLevel = 'public' | 'team' | `role:${string}`;
16
-
17
- export interface PathMapping {
18
- src: string; // Path within module repo
19
- dest: string; // Path in HQ tree (relative to HQ root)
20
- }
21
-
22
- export interface LegacyModuleDefinition {
23
- name: string;
24
- repo: string; // Git URL (https or git@)
25
- branch?: string; // Default: main
26
- strategy: LegacyStrategy;
27
- paths: PathMapping[]; // What to sync and where
28
- access?: AccessLevel;
29
- }
30
-
31
- export interface PackModuleDefinition {
32
- name: string; // e.g. 'hq-pack-gstack'
33
- strategy: 'package';
34
- source: string; // '@scope/name@ver' | git URL#sha | local path
35
- version?: string; // semver from the pack's package.yaml
36
- installed_at?: string; // e.g. 'packages/hq-pack-gstack'
37
- installed_at_iso?: string; // ISO timestamp
38
- resolved_sha?: string; // git transport only
39
- access?: AccessLevel;
40
- }
41
-
42
- export type ModuleDefinition = LegacyModuleDefinition | PackModuleDefinition;
43
-
44
- export interface ModulesManifest {
45
- version: '1';
46
- modules: ModuleDefinition[];
47
- }
48
-
49
- export interface ModuleLock {
50
- version: '1';
51
- locked: Record<string, string>; // module name -> commit SHA
52
- }
53
-
54
- export interface SyncState {
55
- version: '1';
56
- files: Record<string, {
57
- hash: string; // SHA256 of file content at sync time
58
- syncedAt: string; // ISO timestamp
59
- fromModule: string; // Module that provided this file
60
- }>;
61
- }
62
-
63
- export interface SyncResult {
64
- module: string;
65
- success: boolean;
66
- action: 'cloned' | 'fetched' | 'synced' | 'skipped';
67
- message?: string;
68
- filesChanged?: number;
69
- }
70
-
71
- // ---------------------------------------------------------------------------
72
- // hq-pack content-pack manifest (packages/{name}/package.yaml).
73
- //
74
- // Distinct from packages/hq-cli/src/schemas/hq-package.schema.json, which
75
- // covers the entitlement-gated registry flow (`hq packages install <slug>`).
76
- // ---------------------------------------------------------------------------
77
-
78
- /**
79
- * The `contributes.*` keys a pack may declare. DERIVED (US-003) from the single
80
- * declarative contribution registry in `utils/contribution-table.ts` -- adding
81
- * a contribution type is one row there, and this union updates automatically.
82
- * Do NOT restate the keys here.
83
- */
84
- export type PackContributeKey = ContributionKey;
85
-
86
- /**
87
- * Pack authorship attribution (US-001). OPTIONAL and backwards-compatible —
88
- * packs published before this field still validate. When present, install can
89
- * attribute the pack to a creator: `uid` is the HQ person UID, `handle` the
90
- * creator's marketplace handle, `displayName` the human-readable name.
91
- */
92
- export interface PackAuthor {
93
- uid: string;
94
- handle: string;
95
- displayName: string;
96
- }
97
-
98
- /**
99
- * A pack-to-pack dependency (M0). OPTIONAL and backwards-compatible — packs
100
- * published before this field omit `requires.packs` and install unchanged. When
101
- * present, each entry names another content pack that MUST already be installed
102
- * before this one (enforced at install time by `assertPackDependencies`, which
103
- * tracks installed packs by FILESYSTEM PRESENCE — not `modules.yaml`). `version`
104
- * is an optional semver RANGE the installed dependency must satisfy.
105
- */
106
- export interface PackDependency {
107
- name: string; // ^hq-pack-[a-z0-9][a-z0-9-]*$
108
- version?: string; // optional semver range
109
- }
110
-
111
- export interface PackManifest {
112
- name: string; // ^hq-pack-[a-z0-9][a-z0-9-]*$
113
- version: string; // semver
114
- publisher: string; // @scope
115
- access: 'public' | 'private';
116
- /**
117
- * Host + pack prerequisites. `hqCore` is a required semver RANGE the host HQ
118
- * must satisfy. `packs` (M0) is an OPTIONAL list of other content packs that
119
- * must be installed first — see PackDependency.
120
- */
121
- requires: { hqCore: string; packs?: PackDependency[] };
122
- contributes: Partial<Record<PackContributeKey, string[]>>;
123
- description?: string;
124
- license?: string;
125
- repository?: string;
126
- keywords?: string[];
127
- conditional?: string; // bash predicate; skip install if exits non-zero
128
- /**
129
- * Pack authorship attribution (US-001). Optional — absent on legacy packs.
130
- */
131
- author?: PackAuthor;
132
- /**
133
- * Declared capabilities the pack touches (US-001), e.g. hooks/scripts/
134
- * network/fs/secrets. Optional, free-form string entries — surfaced to the
135
- * user at install time for an at-a-glance trust signal. Reserved here; not
136
- * yet enforced.
137
- */
138
- capabilities?: string[];
139
- /**
140
- * Post-install initialization (US-004/US-005). Optional — absent on legacy
141
- * packs. `entrypoint` names a declared `contributes.skills`/`commands` entry
142
- * (slash-normalized); `prompt` is optional free-text prose (PHASE 1 does NOT
143
- * render the prose — only an auto-generated get-started line from entrypoint).
144
- */
145
- initialization?: { entrypoint: string; prompt?: string };
146
- }
@@ -1,23 +0,0 @@
1
- # >>> BEGIN GENERATED contribution table (US-003) — do not edit by hand
2
- # Generated from hq-cli/src/utils/contribution-table.ts by
3
- # hq-cli/scripts/generate-scan-packages-table.mjs. Regenerate with:
4
- # node scripts/generate-scan-packages-table.mjs --write core/scripts/scan-packages.sh
5
- # Each row is "payload|host|wire" (payload uses {item} for the name).
6
- # bash 3.2-compatible (macOS default bash has no associative arrays):
7
- # a plain indexed key list + a generated case-lookup function.
8
- CONTRIB_KEYS=(workers knowledge skills commands hooks policies scripts mcp)
9
- # contrib_row <key> -> echoes "payload|host|wire", empty if unknown.
10
- contrib_row() {
11
- case "$1" in
12
- workers) printf '%s' 'workers/{item}|core/workers/public|symlink' ;;
13
- knowledge) printf '%s' 'knowledge/{item}|core/knowledge/public|symlink' ;;
14
- skills) printf '%s' 'skills/{item}|.claude/skills|symlink' ;;
15
- commands) printf '%s' 'commands/{item}.md|.claude/commands|symlink' ;;
16
- hooks) printf '%s' 'hooks/{item}.sh|.claude/hooks|symlink' ;;
17
- policies) printf '%s' 'policies/{item}.md|core/policies|symlink' ;;
18
- scripts) printf '%s' 'scripts/{item}|core/scripts|symlink' ;;
19
- mcp) printf '%s' 'mcp/{item}.json|merge:claude+codex|merge' ;;
20
- *) return 0 ;;
21
- esac
22
- }
23
- # <<< END GENERATED contribution table
@@ -1,40 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { AuthError, isAuthError } from "./auth-error.js";
3
-
4
- describe("isAuthError", () => {
5
- // HQ-CLI-8: an expired HQ session surfaced as a vault 401 during company
6
- // slug resolution. The user fixes it with `hq login`; it should skip Sentry.
7
- it("classifies an AuthError as an expected auth state (skip Sentry)", () => {
8
- expect(isAuthError(new AuthError())).toBe(true);
9
- });
10
-
11
- it("uses an actionable default message", () => {
12
- expect(new AuthError().message).toMatch(/hq login/);
13
- });
14
-
15
- it("preserves a custom user-facing message verbatim", () => {
16
- const msg = "Sign in again before continuing.";
17
- expect(new AuthError(msg).message).toBe(msg);
18
- });
19
-
20
- it("keeps instanceof across the transpile target", () => {
21
- const err = new AuthError();
22
- expect(err).toBeInstanceOf(AuthError);
23
- expect(err).toBeInstanceOf(Error);
24
- expect(err.name).toBe("AuthError");
25
- });
26
-
27
- // A genuine defect must still reach Sentry — only the typed auth class is
28
- // diverted, so real bugs are never silently swallowed.
29
- it("does NOT match a plain Error (so real faults still report)", () => {
30
- expect(isAuthError(new Error("Unauthorized"))).toBe(false);
31
- expect(isAuthError(new Error("Your HQ session has expired. Run `hq login`."))).toBe(false);
32
- });
33
-
34
- it("does NOT match non-error values", () => {
35
- expect(isAuthError(null)).toBe(false);
36
- expect(isAuthError(undefined)).toBe(false);
37
- expect(isAuthError("Unauthorized")).toBe(false);
38
- expect(isAuthError({ message: "Unauthorized" })).toBe(false);
39
- });
40
- });
@@ -1,42 +0,0 @@
1
- // src/utils/auth-error.ts
2
- //
3
- // Classify expired or missing HQ session conditions surfaced by the vault API
4
- // (HQ-CLI-8). These are expected, user-actionable auth states — NOT hq-cli
5
- // defects — so the top-level catch prints the message and exits non-zero but
6
- // SKIPS Sentry capture, mirroring the company-selection (HQ-CLI-7),
7
- // expected-user-error (HQ-CLI-6), and environmental-FS (HQ-CLI-2) carve-outs.
8
- //
9
- // HQ-CLI-8: a user ran `hq integrations list --company liverecover --json`
10
- // with an expired HQ session. Company-slug resolution tried the caller-scoped
11
- // `/entity/check-slug/me` lookup and the global `/entity/by-slug/company/...`
12
- // fallback; both returned 401 Unauthorized. The plain Error that bubbled up
13
- // looked like a company-resolution defect and was shipped to Sentry as a fatal.
14
- // A 401 from vault resolution means the caller needs to run `hq login`; the
15
- // code cannot repair an expired token, so this is normal auth state, not a
16
- // crash to triage.
17
-
18
- /**
19
- * Thrown when the vault API reports the caller's HQ session is expired or
20
- * missing. The `message` is user-facing and actionable; the top-level handler
21
- * prints it verbatim and skips Sentry capture.
22
- */
23
- export class AuthError extends Error {
24
- constructor(
25
- message = "Your HQ session has expired or you're not signed in. Run `hq login` and try again.",
26
- ) {
27
- super(message);
28
- this.name = "AuthError";
29
- // Preserve `instanceof` across the TS→ES5/ES2015 transpile target.
30
- Object.setPrototypeOf(this, AuthError.prototype);
31
- }
32
- }
33
-
34
- /**
35
- * True when `err` is an expected auth-state failure the user must resolve with
36
- * `hq login`. Callers should print `err.message` and SKIP Sentry capture while
37
- * preserving a non-zero exit. Genuine faults are plain `Error`s and return
38
- * `false`, so real bugs still report.
39
- */
40
- export function isAuthError(err: unknown): boolean {
41
- return err instanceof AuthError;
42
- }
@@ -1,95 +0,0 @@
1
- /**
2
- * Unit tests for the billing-gate helpers (pure parsers + price formatting).
3
- * The command-level flows are covered in commands/{agents,outposts,billing}.test.ts;
4
- * this pins the trust-boundary parsing and the cost string.
5
- */
6
-
7
- import { describe, expect, it } from "vitest";
8
- import {
9
- AGENT_PRICE_CENTS,
10
- OUTPOST_PRICE_CENTS,
11
- formatUsd,
12
- isBillingSetupAction,
13
- parseBillingPayload,
14
- } from "./billing-gate.js";
15
-
16
- describe("prices", () => {
17
- it("match the console's authoritative constants", () => {
18
- expect(AGENT_PRICE_CENTS).toBe(10_000);
19
- expect(OUTPOST_PRICE_CENTS).toBe(8_000);
20
- });
21
- });
22
-
23
- describe("formatUsd", () => {
24
- it("renders cents as $X.YZ", () => {
25
- expect(formatUsd(10_000)).toBe("$100.00");
26
- expect(formatUsd(8_000)).toBe("$80.00");
27
- expect(formatUsd(0)).toBe("$0.00");
28
- });
29
- it("clamps negatives to zero", () => {
30
- expect(formatUsd(-500)).toBe("$0.00");
31
- });
32
- });
33
-
34
- describe("isBillingSetupAction", () => {
35
- it("accepts a valid org setup", () => {
36
- expect(
37
- isBillingSetupAction({
38
- payerType: "company",
39
- path: "/v1/billing/checkout/org",
40
- method: "POST",
41
- body: { companyUid: "cmp_x" },
42
- }),
43
- ).toBe(true);
44
- });
45
- it("accepts a valid person setup with no body", () => {
46
- expect(
47
- isBillingSetupAction({
48
- payerType: "person",
49
- path: "/v1/billing/checkout/person",
50
- method: "POST",
51
- }),
52
- ).toBe(true);
53
- });
54
- it("rejects unknown paths / shapes", () => {
55
- expect(
56
- isBillingSetupAction({
57
- payerType: "company",
58
- path: "/v1/billing/checkout/evil",
59
- method: "POST",
60
- }),
61
- ).toBe(false);
62
- expect(isBillingSetupAction(null)).toBe(false);
63
- expect(isBillingSetupAction({ payerType: "company" })).toBe(false);
64
- });
65
- });
66
-
67
- describe("parseBillingPayload", () => {
68
- it("extracts status + setup from a 402 body", () => {
69
- const parsed = parseBillingPayload({
70
- error: "payment required",
71
- billing: {
72
- status: "billing_required",
73
- setup: {
74
- payerType: "company",
75
- path: "/v1/billing/checkout/org",
76
- method: "POST",
77
- body: { companyUid: "cmp_x" },
78
- },
79
- },
80
- });
81
- expect(parsed?.status).toBe("billing_required");
82
- expect(parsed?.setup?.path).toBe("/v1/billing/checkout/org");
83
- });
84
- it("returns status with no setup when the setup is malformed", () => {
85
- const parsed = parseBillingPayload({
86
- billing: { status: "billing_required", setup: { bogus: true } },
87
- });
88
- expect(parsed?.status).toBe("billing_required");
89
- expect(parsed?.setup).toBeUndefined();
90
- });
91
- it("returns undefined for a non-billing error body", () => {
92
- expect(parseBillingPayload({ error: "forbidden" })).toBeUndefined();
93
- expect(parseBillingPayload(null)).toBeUndefined();
94
- });
95
- });
@@ -1,228 +0,0 @@
1
- /**
2
- * Billing gate for paid provisioning (agents & Outposts).
3
- *
4
- * hq-pro enforces billing server-side: a provision call for a resource whose
5
- * payer has no card on file returns `402` with a `billing` payload carrying a
6
- * `setup` action that names EXACTLY which checkout endpoint to hit. That
7
- * endpoint returns `{ url }` — a Stripe-hosted card-capture link.
8
- *
9
- * This module wires the client-side experience around that contract:
10
- * 1. `confirmChargeOrExit` — print the monthly cost and require `--yes`
11
- * BEFORE any paid provisioning call is made.
12
- * 2. `surfaceBillingRequired` — when the backend answers `402 billing_required`,
13
- * mint the card-capture link and print a plain, shareable message instead
14
- * of an opaque failure.
15
- * 3. `hq billing checkout` (see commands/billing.ts) reuses `mintPaymentLink`
16
- * to hand out the same link proactively.
17
- *
18
- * Prices mirror the console's authoritative constants
19
- * (hq-console `src/lib/billing-pricing.ts`): amounts are in the smallest
20
- * currency unit (US cents) to match Stripe's wire shape.
21
- */
22
-
23
- import chalk from "chalk";
24
- import { vaultApiFetch } from "./vault-api.js";
25
-
26
- /** Per-Agent monthly list price, in cents ($100.00 / agent / month). */
27
- export const AGENT_PRICE_CENTS = 10_000;
28
- /** Per-Outpost monthly list price, in cents ($80.00 / Outpost / month). */
29
- export const OUTPOST_PRICE_CENTS = 8_000;
30
-
31
- /** Render a cents amount as a `$X.YZ` USD string. */
32
- export function formatUsd(cents: number): string {
33
- return `$${(Math.max(0, Math.round(cents)) / 100).toFixed(2)}`;
34
- }
35
-
36
- /**
37
- * The server-supplied "how to add a card" action on a `402 billing_required`.
38
- * Mirrors hq-pro `src/billing/activation-billing.ts` `BillingSetupAction` and
39
- * the console's `src/lib/billing-setup.ts`.
40
- */
41
- export interface BillingSetupAction {
42
- payerType: "company" | "person";
43
- path: "/v1/billing/checkout/org" | "/v1/billing/checkout/person";
44
- method: "POST";
45
- body?: { companyUid?: string };
46
- }
47
-
48
- /** The `billing` envelope hq-pro attaches to a billing-blocked provision. */
49
- export interface BillingErrorPayload {
50
- status: string;
51
- setup?: BillingSetupAction;
52
- }
53
-
54
- /** Narrow an unknown value to a usable `BillingSetupAction`. */
55
- export function isBillingSetupAction(value: unknown): value is BillingSetupAction {
56
- if (!value || typeof value !== "object") return false;
57
- const setup = value as Partial<BillingSetupAction>;
58
- const body = setup.body;
59
- return (
60
- (setup.payerType === "company" || setup.payerType === "person") &&
61
- (setup.path === "/v1/billing/checkout/org" ||
62
- setup.path === "/v1/billing/checkout/person") &&
63
- setup.method === "POST" &&
64
- (body === undefined || (typeof body === "object" && body !== null))
65
- );
66
- }
67
-
68
- /** Pull a `BillingErrorPayload` out of a decoded hq-pro error body, if present. */
69
- export function parseBillingPayload(body: unknown): BillingErrorPayload | undefined {
70
- if (!body || typeof body !== "object") return undefined;
71
- const raw = (body as { billing?: unknown }).billing;
72
- if (!raw || typeof raw !== "object") return undefined;
73
- const status = (raw as { status?: unknown }).status;
74
- if (typeof status !== "string") return undefined;
75
- const setup = (raw as { setup?: unknown }).setup;
76
- return {
77
- status,
78
- ...(isBillingSetupAction(setup) ? { setup } : {}),
79
- };
80
- }
81
-
82
- export type PaidResource = "agent" | "Outpost";
83
-
84
- /**
85
- * Gate a paid provisioning call behind an explicit, informed `--yes`. Prints the
86
- * monthly charge in full prose (this is a paid, outward action — Auto-Clarity)
87
- * and exits non-zero when the caller has not passed `--yes`. Returns normally
88
- * once approved so the caller proceeds to provision.
89
- */
90
- export function confirmChargeOrExit(opts: {
91
- resource: PaidResource;
92
- unitCents: number;
93
- quantity?: number;
94
- yes?: boolean;
95
- }): void {
96
- const quantity = opts.quantity ?? 1;
97
- const total = opts.unitCents * quantity;
98
- const each =
99
- quantity > 1 ? ` (${formatUsd(opts.unitCents)} each × ${quantity})` : "";
100
- const noun = quantity > 1 ? `${opts.resource}s` : opts.resource;
101
- const article = /^[aeiou]/i.test(opts.resource) ? "an" : "a";
102
- const subject = quantity > 1 ? `${quantity} ${noun}` : `${article} ${noun}`;
103
- if (!opts.yes) {
104
- console.error(
105
- chalk.yellow(
106
- `Provisioning ${subject} adds a recurring charge of ` +
107
- `${formatUsd(total)}/month${each} to the payer on file. This is a ` +
108
- `paid resource.\n` +
109
- `Re-run with --yes to confirm you want to incur this charge.`,
110
- ),
111
- );
112
- process.exit(1);
113
- }
114
- console.log(
115
- chalk.dim(
116
- `Confirmed: ${formatUsd(total)}/month for ${quantity} ${noun}. Provisioning…`,
117
- ),
118
- );
119
- }
120
-
121
- /**
122
- * Mint a Stripe-hosted card-capture link for a `BillingSetupAction`. Returns the
123
- * hosted URL the payer opens to add a card. Throws on a non-2xx (the caller
124
- * decides how to surface it) — never swallows.
125
- */
126
- export async function mintPaymentLink(
127
- token: string,
128
- setup: BillingSetupAction,
129
- ): Promise<string> {
130
- const res = await vaultApiFetch({
131
- token,
132
- path: setup.path,
133
- method: "POST",
134
- body: setup.body?.companyUid ? { companyUid: setup.body.companyUid } : {},
135
- });
136
- if (!res.ok) {
137
- const body = (await res.json().catch(() => ({}))) as {
138
- error?: string;
139
- message?: string;
140
- };
141
- throw new Error(
142
- `Failed to mint a payment link: ${body.error ?? body.message ?? res.statusText}`,
143
- );
144
- }
145
- const data = (await res.json()) as { url?: string };
146
- if (!data.url) {
147
- throw new Error("Payment link response did not include a checkout URL.");
148
- }
149
- return data.url;
150
- }
151
-
152
- /**
153
- * The provision was blocked because the payer has no card on file. Mint the
154
- * card-capture link the backend pointed us at and print a plain, shareable
155
- * message so the user can add a card (or hand the link to whoever owns billing)
156
- * and re-run. Returns the URL, or `null` when the server gave no `setup` action
157
- * to act on. Never prints tokens or secrets.
158
- */
159
- export async function surfaceBillingRequired(
160
- token: string,
161
- billing: BillingErrorPayload,
162
- ): Promise<string | null> {
163
- if (!billing.setup) {
164
- console.error(
165
- chalk.yellow(
166
- "Provisioning is blocked on billing, but the server didn't return a " +
167
- "payment link. Add a card in the console billing page, then re-run.",
168
- ),
169
- );
170
- return null;
171
- }
172
- const url = await mintPaymentLink(token, billing.setup);
173
- console.log(
174
- chalk.yellow("No card on file — provisioning is blocked until one is added."),
175
- );
176
- console.log(
177
- "Add a card here (safe to share with whoever owns billing):\n " +
178
- chalk.cyan(url),
179
- );
180
- console.log(chalk.dim("Once a card is added, re-run the same command."));
181
- return url;
182
- }
183
-
184
- /**
185
- * Status-aware surface for a 402 billing block. hq-pro's envelope carries two
186
- * distinct remediations that must never be conflated (mirroring the server's
187
- * own P1-C classification):
188
- * - `payment_failed` — a card EXISTS and the charge was DECLINED. The
189
- * server's `message` already carries the friendly decline copy ("Your
190
- * card was declined…", "insufficient funds", …). Telling this user
191
- * "No card on file" sends them down the wrong remediation path entirely
192
- * (observed live 2026-07-20: a declined $80 Outpost proration surfaced
193
- * as "no card", triggering a hunt for a missing card that existed).
194
- * The capture link still surfaces — as the way to UPDATE the card.
195
- * - anything else (`billing_required`) — genuinely no usable card on
196
- * file; the existing add-a-card copy is correct.
197
- */
198
- export async function surfaceBillingBlocked(
199
- token: string,
200
- billing: BillingErrorPayload,
201
- serverMessage?: string,
202
- ): Promise<string | null> {
203
- if (billing.status !== "payment_failed") {
204
- return surfaceBillingRequired(token, billing);
205
- }
206
- console.error(
207
- chalk.yellow(
208
- serverMessage?.trim() ||
209
- "Your payment failed. Try a different card or contact your bank.",
210
- ),
211
- );
212
- if (!billing.setup) return null;
213
- try {
214
- const url = await mintPaymentLink(token, billing.setup);
215
- console.log(
216
- "Update or replace the card here (safe to share with whoever owns billing):\n " +
217
- chalk.cyan(url),
218
- );
219
- console.log(
220
- chalk.dim("Once the payment method is sorted, re-run the same command."),
221
- );
222
- return url;
223
- } catch {
224
- // Link minting is best-effort on the decline path — the decline reason
225
- // above is the essential part; the console billing page also works.
226
- return null;
227
- }
228
- }
@@ -1,18 +0,0 @@
1
- import type { Breadcrumb } from "@sentry/node";
2
-
3
- const BUFFER_SIZE = 20;
4
- const _buffer: Breadcrumb[] = [];
5
-
6
- // Sentry beforeBreadcrumb hook: records every breadcrumb in a ring buffer
7
- // and returns it unchanged so Sentry still processes it normally.
8
- export function beforeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null {
9
- _buffer.push(breadcrumb);
10
- if (_buffer.length > BUFFER_SIZE) {
11
- _buffer.shift();
12
- }
13
- return breadcrumb;
14
- }
15
-
16
- export function getRecentBreadcrumbs(): Breadcrumb[] {
17
- return [..._buffer];
18
- }