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