@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
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
- }