@indigoai-us/hq-cli 5.5.2 → 5.5.3
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/dist/bin/hq-auth-refresh.js +26 -13
- package/dist/commands/_patterns.d.ts +3 -0
- package/dist/commands/_patterns.js +6 -0
- package/dist/commands/add.js +4 -1
- package/dist/commands/auth.js +4 -1
- package/dist/commands/cloud.js +4 -1
- package/dist/commands/groups.d.ts +3 -0
- package/dist/commands/groups.js +344 -0
- package/dist/commands/list.js +4 -1
- package/dist/commands/login.js +4 -1
- package/dist/commands/logout.js +4 -1
- package/dist/commands/onboard.js +4 -1
- package/dist/commands/pack-install.js +4 -1
- package/dist/commands/pkg-install.js +4 -1
- package/dist/commands/pkg-list.js +4 -1
- package/dist/commands/pkg-remove.js +4 -1
- package/dist/commands/pkg-update.js +4 -1
- package/dist/commands/secrets.d.ts +9 -0
- package/dist/commands/secrets.js +263 -25
- package/dist/commands/sync.js +4 -1
- package/dist/commands/team-sync.js +4 -1
- package/dist/commands/update.js +4 -1
- package/dist/commands/whoami.js +4 -1
- package/dist/index.js +21 -2
- package/dist/sentry-before-send.d.ts +3 -0
- package/dist/sentry-before-send.js +219 -0
- package/dist/sentry-dsn.generated.d.ts +2 -0
- package/dist/sentry-dsn.generated.js +5 -0
- package/dist/sentry.d.ts +4 -0
- package/dist/sentry.js +22 -0
- package/dist/strategies/link.js +4 -1
- package/dist/strategies/merge.js +4 -1
- package/dist/types.js +4 -1
- package/dist/utils/cognito-session.js +4 -1
- package/dist/utils/git.js +4 -1
- package/dist/utils/hq-root.js +4 -1
- package/dist/utils/integrity.js +4 -1
- package/dist/utils/manifest.js +4 -1
- package/dist/utils/registry-client.js +4 -1
- package/dist/utils/registry.js +4 -1
- package/dist/utils/secrets-cache.js +6 -2
- package/package.json +4 -3
- package/scripts/generate-dsn.mjs +26 -0
- package/src/bin/hq-auth-refresh.ts +23 -16
- package/src/commands/_patterns.ts +2 -0
- package/src/commands/groups.ts +357 -0
- package/src/commands/secrets.ts +306 -26
- package/src/index.ts +17 -1
- package/src/sentry-before-send.test.ts +359 -0
- package/src/sentry-before-send.ts +221 -0
- package/src/sentry.test.ts +24 -0
- package/src/sentry.ts +19 -0
- package/src/utils/secrets-cache.ts +2 -1
- package/dist/bin/hq-auth-refresh.d.ts.map +0 -1
- package/dist/bin/hq-auth-refresh.js.map +0 -1
- package/dist/commands/add.d.ts.map +0 -1
- package/dist/commands/add.js.map +0 -1
- package/dist/commands/auth.d.ts.map +0 -1
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/cloud.d.ts.map +0 -1
- package/dist/commands/cloud.js.map +0 -1
- package/dist/commands/list.d.ts.map +0 -1
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js.map +0 -1
- package/dist/commands/onboard.d.ts.map +0 -1
- package/dist/commands/onboard.js.map +0 -1
- package/dist/commands/pack-install.d.ts.map +0 -1
- package/dist/commands/pack-install.js.map +0 -1
- package/dist/commands/pkg-install.d.ts.map +0 -1
- package/dist/commands/pkg-install.js.map +0 -1
- package/dist/commands/pkg-list.d.ts.map +0 -1
- package/dist/commands/pkg-list.js.map +0 -1
- package/dist/commands/pkg-remove.d.ts.map +0 -1
- package/dist/commands/pkg-remove.js.map +0 -1
- package/dist/commands/pkg-update.d.ts.map +0 -1
- package/dist/commands/pkg-update.js.map +0 -1
- package/dist/commands/secrets.d.ts.map +0 -1
- package/dist/commands/secrets.js.map +0 -1
- package/dist/commands/sync.d.ts.map +0 -1
- package/dist/commands/sync.js.map +0 -1
- package/dist/commands/team-sync.d.ts.map +0 -1
- package/dist/commands/team-sync.js.map +0 -1
- package/dist/commands/update.d.ts.map +0 -1
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/whoami.d.ts.map +0 -1
- package/dist/commands/whoami.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/strategies/link.d.ts.map +0 -1
- package/dist/strategies/link.js.map +0 -1
- package/dist/strategies/merge.d.ts.map +0 -1
- package/dist/strategies/merge.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/auth.d.ts +0 -27
- package/dist/utils/auth.d.ts.map +0 -1
- package/dist/utils/auth.js +0 -155
- package/dist/utils/auth.js.map +0 -1
- package/dist/utils/cognito-session.d.ts.map +0 -1
- package/dist/utils/cognito-session.js.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/hq-root.d.ts.map +0 -1
- package/dist/utils/hq-root.js.map +0 -1
- package/dist/utils/integrity.d.ts.map +0 -1
- package/dist/utils/integrity.js.map +0 -1
- package/dist/utils/manifest.d.ts.map +0 -1
- package/dist/utils/manifest.js.map +0 -1
- package/dist/utils/registry-client.d.ts.map +0 -1
- package/dist/utils/registry-client.js.map +0 -1
- package/dist/utils/registry.d.ts.map +0 -1
- package/dist/utils/registry.js.map +0 -1
- package/dist/utils/secrets-cache.d.ts.map +0 -1
- package/dist/utils/secrets-cache.js.map +0 -1
- package/dist/utils/token-store.d.ts +0 -28
- package/dist/utils/token-store.d.ts.map +0 -1
- package/dist/utils/token-store.js +0 -68
- package/dist/utils/token-store.js.map +0 -1
|
@@ -9,19 +9,32 @@
|
|
|
9
9
|
* Exit 0 on refresh, exit 1 if no cached session or refresh failed.
|
|
10
10
|
* Writes the refreshed tokens to ~/.hq/cognito-tokens.json.
|
|
11
11
|
*/
|
|
12
|
+
|
|
13
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="28774b80-becb-5fb9-b676-dee74c26d73d")}catch(e){}}();
|
|
14
|
+
import { initSentry, Sentry } from "../sentry.js";
|
|
12
15
|
import { refreshCachedSession } from "../utils/cognito-session.js";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
initSentry();
|
|
17
|
+
(async () => {
|
|
18
|
+
let exitCode = 1;
|
|
19
|
+
try {
|
|
20
|
+
const result = await refreshCachedSession();
|
|
21
|
+
if (result.refreshed) {
|
|
22
|
+
exitCode = 0;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
if (result.reason) {
|
|
26
|
+
process.stderr.write(`hq-auth-refresh: ${result.reason}\n`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
17
29
|
}
|
|
18
|
-
|
|
19
|
-
|
|
30
|
+
catch (err) {
|
|
31
|
+
Sentry.captureException(err);
|
|
32
|
+
process.stderr.write(`hq-auth-refresh: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
20
33
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
//#
|
|
34
|
+
finally {
|
|
35
|
+
await Sentry.flush(2000);
|
|
36
|
+
process.exit(exitCode);
|
|
37
|
+
}
|
|
38
|
+
})();
|
|
39
|
+
//# sourceMappingURL=hq-auth-refresh.js.map
|
|
40
|
+
//# debugId=28774b80-becb-5fb9-b676-dee74c26d73d
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="61b178c5-2bd1-5503-bbee-ecb98a9d72f5")}catch(e){}}();
|
|
3
|
+
export const SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*(?:\/[A-Z][A-Z0-9_]+)*$/;
|
|
4
|
+
export const GROUP_ID_PATTERN = /^grp_[A-Za-z0-9_-]+$/;
|
|
5
|
+
//# sourceMappingURL=_patterns.js.map
|
|
6
|
+
//# debugId=61b178c5-2bd1-5503-bbee-ecb98a9d72f5
|
package/dist/commands/add.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* hq modules add command (US-003)
|
|
3
3
|
*/
|
|
4
|
+
|
|
5
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4b8dd2fb-2564-590a-b294-7deeff926e4b")}catch(e){}}();
|
|
4
6
|
import { findHqRoot, addModule, parseRepoName, isValidRepoUrl } from '../utils/manifest.js';
|
|
5
7
|
export function registerAddCommand(program) {
|
|
6
8
|
program
|
|
@@ -58,4 +60,5 @@ export function registerAddCommand(program) {
|
|
|
58
60
|
}
|
|
59
61
|
});
|
|
60
62
|
}
|
|
61
|
-
//# sourceMappingURL=add.js.map
|
|
63
|
+
//# sourceMappingURL=add.js.map
|
|
64
|
+
//# debugId=4b8dd2fb-2564-590a-b294-7deeff926e4b
|
package/dist/commands/auth.js
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* session is kept fresh by `hq auth refresh` / `hq-auth-refresh` and consumed
|
|
14
14
|
* by the deploy + sync skills.
|
|
15
15
|
*/
|
|
16
|
+
|
|
17
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a4a30b14-55b3-5206-9148-48aff1a8cdd4")}catch(e){}}();
|
|
16
18
|
import chalk from "chalk";
|
|
17
19
|
import { browserLogin, clearCachedTokens, loadCachedTokens, isExpiring, CognitoAuthError, } from "@indigoai-us/hq-cloud";
|
|
18
20
|
import { DEFAULT_COGNITO, refreshCachedSession, } from "../utils/cognito-session.js";
|
|
@@ -107,4 +109,5 @@ export function registerAuthCommands(program) {
|
|
|
107
109
|
: chalk.green(`${label}HQ session valid (expiresAt=${cached.expiresAt})`));
|
|
108
110
|
});
|
|
109
111
|
}
|
|
110
|
-
//# sourceMappingURL=auth.js.map
|
|
112
|
+
//# sourceMappingURL=auth.js.map
|
|
113
|
+
//# debugId=a4a30b14-55b3-5206-9148-48aff1a8cdd4
|
package/dist/commands/cloud.js
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* hq sync pull — pull all permitted files from the vault
|
|
13
13
|
* hq sync status — show local journal summary
|
|
14
14
|
*/
|
|
15
|
+
|
|
16
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a3524c87-f874-56f4-92b3-9c33467b4f95")}catch(e){}}();
|
|
15
17
|
import chalk from "chalk";
|
|
16
18
|
import * as fs from "fs";
|
|
17
19
|
import * as path from "path";
|
|
@@ -135,4 +137,5 @@ function formatBytes(bytes) {
|
|
|
135
137
|
const value = bytes / Math.pow(1024, exponent);
|
|
136
138
|
return `${value.toFixed(value >= 100 || exponent === 0 ? 0 : 1)} ${units[exponent]}`;
|
|
137
139
|
}
|
|
138
|
-
//# sourceMappingURL=cloud.js.map
|
|
140
|
+
//# sourceMappingURL=cloud.js.map
|
|
141
|
+
//# debugId=a3524c87-f874-56f4-92b3-9c33467b4f95
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e84b2c37-90d0-559c-ace0-2b08fb69eec5")}catch(e){}}();
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { ensureCognitoToken } from "../utils/cognito-session.js";
|
|
5
|
+
import { vaultApiFetch, getCompanyUid } from "./secrets.js";
|
|
6
|
+
import { GROUP_ID_PATTERN } from "./_patterns.js";
|
|
7
|
+
const EMAIL_PATTERN = /^[^\s]+@[^\s]+$/;
|
|
8
|
+
const PERSON_UID_PATTERN = /^prs_[A-Za-z0-9_-]+$/;
|
|
9
|
+
function detectPrincipalType(principal) {
|
|
10
|
+
if (EMAIL_PATTERN.test(principal)) {
|
|
11
|
+
// Server normalizes email again; we normalize here so local validation /
|
|
12
|
+
// cache keys agree with the server-side canonicalization.
|
|
13
|
+
return { granteeType: "email", granteeId: principal.trim().toLowerCase() };
|
|
14
|
+
}
|
|
15
|
+
if (PERSON_UID_PATTERN.test(principal)) {
|
|
16
|
+
return { granteeType: "person", granteeId: principal };
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function shortDate(iso) {
|
|
21
|
+
return iso.slice(0, 10);
|
|
22
|
+
}
|
|
23
|
+
export function registerGroupsCommand(program) {
|
|
24
|
+
const groups = program
|
|
25
|
+
.command("groups")
|
|
26
|
+
.description("Manage groups in HQ vault")
|
|
27
|
+
.option("--company <slug>", "Company slug (resolves to companyUid)");
|
|
28
|
+
groups
|
|
29
|
+
.command("create <groupId>")
|
|
30
|
+
.description("Create a new group")
|
|
31
|
+
.requiredOption("--name <name>", "Human-readable group name")
|
|
32
|
+
.option("--description <desc>", "Optional description")
|
|
33
|
+
.action(async (groupId, opts) => {
|
|
34
|
+
try {
|
|
35
|
+
if (!GROUP_ID_PATTERN.test(groupId)) {
|
|
36
|
+
console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
const token = await ensureCognitoToken();
|
|
40
|
+
const companySlug = groups.opts().company;
|
|
41
|
+
const companyUid = await getCompanyUid(token, companySlug);
|
|
42
|
+
const body = { groupId, name: opts.name };
|
|
43
|
+
if (opts.description)
|
|
44
|
+
body.description = opts.description;
|
|
45
|
+
const res = await vaultApiFetch({
|
|
46
|
+
token,
|
|
47
|
+
path: `/secrets/${encodeURIComponent(companyUid)}/groups`,
|
|
48
|
+
method: "POST",
|
|
49
|
+
body,
|
|
50
|
+
});
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
const err = await res.json().catch(() => ({}));
|
|
53
|
+
if (res.status === 401) {
|
|
54
|
+
console.error(chalk.red("Not authenticated — please run `hq login`"));
|
|
55
|
+
}
|
|
56
|
+
else if (res.status === 403) {
|
|
57
|
+
console.error(chalk.red("Not authorized — owner or admin role required"));
|
|
58
|
+
}
|
|
59
|
+
else if (res.status === 409) {
|
|
60
|
+
console.error(chalk.red(`Group already exists: ${groupId}`));
|
|
61
|
+
}
|
|
62
|
+
else if (res.status >= 500) {
|
|
63
|
+
console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
|
|
67
|
+
}
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
console.log(chalk.green(`Group '${groupId}' (${opts.name}) created`));
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
groups
|
|
78
|
+
.command("delete <groupId>")
|
|
79
|
+
.description("Delete a group")
|
|
80
|
+
.action(async (groupId) => {
|
|
81
|
+
try {
|
|
82
|
+
if (!GROUP_ID_PATTERN.test(groupId)) {
|
|
83
|
+
console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
const token = await ensureCognitoToken();
|
|
87
|
+
const companySlug = groups.opts().company;
|
|
88
|
+
const companyUid = await getCompanyUid(token, companySlug);
|
|
89
|
+
const res = await vaultApiFetch({
|
|
90
|
+
token,
|
|
91
|
+
path: `/secrets/${encodeURIComponent(companyUid)}/groups`,
|
|
92
|
+
method: "DELETE",
|
|
93
|
+
query: { groupId },
|
|
94
|
+
});
|
|
95
|
+
if (!res.ok) {
|
|
96
|
+
const err = await res.json().catch(() => ({}));
|
|
97
|
+
if (res.status === 401) {
|
|
98
|
+
console.error(chalk.red("Not authenticated — please run `hq login`"));
|
|
99
|
+
}
|
|
100
|
+
else if (res.status === 403) {
|
|
101
|
+
console.error(chalk.red("Not authorized — owner or admin role required"));
|
|
102
|
+
}
|
|
103
|
+
else if (res.status === 404) {
|
|
104
|
+
console.error(chalk.red(`Group not found: ${groupId}`));
|
|
105
|
+
}
|
|
106
|
+
else if (res.status >= 500) {
|
|
107
|
+
console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
|
|
111
|
+
}
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
console.log(chalk.green(`Group '${groupId}' deleted`));
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
groups
|
|
122
|
+
.command("add <groupId> <principal>")
|
|
123
|
+
.description("Add a person to a group (principal: email or personUid)")
|
|
124
|
+
.action(async (groupId, principal) => {
|
|
125
|
+
try {
|
|
126
|
+
if (!GROUP_ID_PATTERN.test(groupId)) {
|
|
127
|
+
console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
const detected = detectPrincipalType(principal);
|
|
131
|
+
if (!detected) {
|
|
132
|
+
console.error(chalk.red(`Invalid principal '${principal}': must be an email address or a personUid matching prs_<alphanumeric>`));
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
const token = await ensureCognitoToken();
|
|
136
|
+
const companySlug = groups.opts().company;
|
|
137
|
+
const companyUid = await getCompanyUid(token, companySlug);
|
|
138
|
+
const res = await vaultApiFetch({
|
|
139
|
+
token,
|
|
140
|
+
path: `/secrets/${encodeURIComponent(companyUid)}/groups/members`,
|
|
141
|
+
method: "POST",
|
|
142
|
+
body: { groupId, granteeType: detected.granteeType, granteeId: detected.granteeId },
|
|
143
|
+
});
|
|
144
|
+
if (!res.ok) {
|
|
145
|
+
const err = await res.json().catch(() => ({}));
|
|
146
|
+
if (res.status === 401) {
|
|
147
|
+
console.error(chalk.red("Not authenticated — please run `hq login`"));
|
|
148
|
+
}
|
|
149
|
+
else if (res.status === 403) {
|
|
150
|
+
console.error(chalk.red("Not authorized — owner/admin role or group creator required"));
|
|
151
|
+
}
|
|
152
|
+
else if (res.status === 404) {
|
|
153
|
+
// Server provides a helpful message (email not found vs group not found)
|
|
154
|
+
console.error(chalk.red(err.error ?? `Not found`));
|
|
155
|
+
}
|
|
156
|
+
else if (res.status >= 500) {
|
|
157
|
+
console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
|
|
161
|
+
}
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
console.log(chalk.green(`Added ${principal} to group '${groupId}'`));
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
groups
|
|
172
|
+
.command("remove <groupId> <principal>")
|
|
173
|
+
.description("Remove a person from a group (principal: email or personUid)")
|
|
174
|
+
.action(async (groupId, principal) => {
|
|
175
|
+
try {
|
|
176
|
+
if (!GROUP_ID_PATTERN.test(groupId)) {
|
|
177
|
+
console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
const detected = detectPrincipalType(principal);
|
|
181
|
+
if (!detected) {
|
|
182
|
+
console.error(chalk.red(`Invalid principal '${principal}': must be an email address or a personUid matching prs_<alphanumeric>`));
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
const token = await ensureCognitoToken();
|
|
186
|
+
const companySlug = groups.opts().company;
|
|
187
|
+
const companyUid = await getCompanyUid(token, companySlug);
|
|
188
|
+
const res = await vaultApiFetch({
|
|
189
|
+
token,
|
|
190
|
+
path: `/secrets/${encodeURIComponent(companyUid)}/groups/members`,
|
|
191
|
+
method: "DELETE",
|
|
192
|
+
query: {
|
|
193
|
+
groupId,
|
|
194
|
+
granteeType: detected.granteeType,
|
|
195
|
+
granteeId: detected.granteeId,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
if (!res.ok) {
|
|
199
|
+
const err = await res.json().catch(() => ({}));
|
|
200
|
+
if (res.status === 401) {
|
|
201
|
+
console.error(chalk.red("Not authenticated — please run `hq login`"));
|
|
202
|
+
}
|
|
203
|
+
else if (res.status === 403) {
|
|
204
|
+
console.error(chalk.red("Not authorized — owner/admin role or group creator required"));
|
|
205
|
+
}
|
|
206
|
+
else if (res.status === 404) {
|
|
207
|
+
console.error(chalk.red(err.error ?? `Not found`));
|
|
208
|
+
}
|
|
209
|
+
else if (res.status >= 500) {
|
|
210
|
+
console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
|
|
214
|
+
}
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
console.log(chalk.green(`Removed ${principal} from group '${groupId}'`));
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
groups
|
|
225
|
+
.command("list")
|
|
226
|
+
.description("List all groups in the company")
|
|
227
|
+
.action(async () => {
|
|
228
|
+
try {
|
|
229
|
+
const token = await ensureCognitoToken();
|
|
230
|
+
const companySlug = groups.opts().company;
|
|
231
|
+
const companyUid = await getCompanyUid(token, companySlug);
|
|
232
|
+
const res = await vaultApiFetch({
|
|
233
|
+
token,
|
|
234
|
+
path: `/secrets/${encodeURIComponent(companyUid)}/groups`,
|
|
235
|
+
});
|
|
236
|
+
if (!res.ok) {
|
|
237
|
+
const err = await res.json().catch(() => ({}));
|
|
238
|
+
if (res.status === 401) {
|
|
239
|
+
console.error(chalk.red("Not authenticated — please run `hq login`"));
|
|
240
|
+
}
|
|
241
|
+
else if (res.status === 403) {
|
|
242
|
+
console.error(chalk.red("Not authorized to list groups"));
|
|
243
|
+
}
|
|
244
|
+
else if (res.status >= 500) {
|
|
245
|
+
console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
|
|
249
|
+
}
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
const data = await res.json();
|
|
253
|
+
if (data.groups.length === 0) {
|
|
254
|
+
console.log(chalk.gray("No groups in this company yet."));
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const idW = Math.max(8, ...data.groups.map((g) => g.groupId.length));
|
|
258
|
+
const nameW = Math.max(4, ...data.groups.map((g) => g.name.length));
|
|
259
|
+
const descW = Math.max(11, ...data.groups.map((g) => (g.description ?? "").length));
|
|
260
|
+
console.log(chalk.bold([
|
|
261
|
+
"GROUP_ID".padEnd(idW),
|
|
262
|
+
"NAME".padEnd(nameW),
|
|
263
|
+
"DESCRIPTION".padEnd(descW),
|
|
264
|
+
"CREATED_AT",
|
|
265
|
+
].join(" ")));
|
|
266
|
+
for (const g of data.groups) {
|
|
267
|
+
console.log([
|
|
268
|
+
g.groupId.padEnd(idW),
|
|
269
|
+
g.name.padEnd(nameW),
|
|
270
|
+
(g.description ?? "").padEnd(descW),
|
|
271
|
+
shortDate(g.createdAt),
|
|
272
|
+
].join(" "));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
277
|
+
process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
groups
|
|
281
|
+
.command("members <groupId>")
|
|
282
|
+
.description("List members of a group")
|
|
283
|
+
.action(async (groupId) => {
|
|
284
|
+
try {
|
|
285
|
+
if (!GROUP_ID_PATTERN.test(groupId)) {
|
|
286
|
+
console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
|
|
287
|
+
process.exit(1);
|
|
288
|
+
}
|
|
289
|
+
const token = await ensureCognitoToken();
|
|
290
|
+
const companySlug = groups.opts().company;
|
|
291
|
+
const companyUid = await getCompanyUid(token, companySlug);
|
|
292
|
+
const res = await vaultApiFetch({
|
|
293
|
+
token,
|
|
294
|
+
path: `/secrets/${encodeURIComponent(companyUid)}/groups/members`,
|
|
295
|
+
query: { groupId },
|
|
296
|
+
});
|
|
297
|
+
if (!res.ok) {
|
|
298
|
+
const err = await res.json().catch(() => ({}));
|
|
299
|
+
if (res.status === 401) {
|
|
300
|
+
console.error(chalk.red("Not authenticated — please run `hq login`"));
|
|
301
|
+
}
|
|
302
|
+
else if (res.status === 403) {
|
|
303
|
+
console.error(chalk.red("Not authorized to view group members"));
|
|
304
|
+
}
|
|
305
|
+
else if (res.status === 404) {
|
|
306
|
+
console.error(chalk.red(`Group not found: ${groupId}`));
|
|
307
|
+
}
|
|
308
|
+
else if (res.status >= 500) {
|
|
309
|
+
console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
|
|
313
|
+
}
|
|
314
|
+
process.exit(1);
|
|
315
|
+
}
|
|
316
|
+
const data = await res.json();
|
|
317
|
+
console.log(`Members of '${groupId}':`);
|
|
318
|
+
if (data.members.length === 0) {
|
|
319
|
+
console.log(chalk.gray("No members yet — use 'hq groups add' to add."));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const uidW = Math.max(10, ...data.members.map((m) => m.personUid.length));
|
|
323
|
+
const byW = Math.max(8, ...data.members.map((m) => m.addedBy.length));
|
|
324
|
+
console.log(chalk.bold([
|
|
325
|
+
"PERSON_UID".padEnd(uidW),
|
|
326
|
+
"ADDED_BY".padEnd(byW),
|
|
327
|
+
"ADDED_AT",
|
|
328
|
+
].join(" ")));
|
|
329
|
+
for (const m of data.members) {
|
|
330
|
+
console.log([
|
|
331
|
+
m.personUid.padEnd(uidW),
|
|
332
|
+
m.addedBy.padEnd(byW),
|
|
333
|
+
shortDate(m.addedAt),
|
|
334
|
+
].join(" "));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
catch (err) {
|
|
338
|
+
console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
|
|
339
|
+
process.exit(1);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=groups.js.map
|
|
344
|
+
//# debugId=e84b2c37-90d0-559c-ace0-2b08fb69eec5
|
package/dist/commands/list.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* hq modules list command (US-005)
|
|
3
3
|
*/
|
|
4
|
+
|
|
5
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0ed2bacf-8934-5b52-a841-1eaa2bbcd8b8")}catch(e){}}();
|
|
4
6
|
import * as path from 'path';
|
|
5
7
|
import { findHqRoot, readManifest, readLock, getModulesDir } from '../utils/manifest.js';
|
|
6
8
|
import { isRepo, getCurrentCommit, isBehindRemote } from '../utils/git.js';
|
|
@@ -69,4 +71,5 @@ export function registerListCommand(program) {
|
|
|
69
71
|
}
|
|
70
72
|
});
|
|
71
73
|
}
|
|
72
|
-
//# sourceMappingURL=list.js.map
|
|
74
|
+
//# sourceMappingURL=list.js.map
|
|
75
|
+
//# debugId=0ed2bacf-8934-5b52-a841-1eaa2bbcd8b8
|
package/dist/commands/login.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* hq login — opens browser for Cognito auth via Google OAuth
|
|
3
3
|
*/
|
|
4
|
+
|
|
5
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="31735154-208b-5544-85a4-22f8f0fbe415")}catch(e){}}();
|
|
4
6
|
import chalk from 'chalk';
|
|
5
7
|
import { browserLogin, loadCachedTokens, isExpiring } from '@indigoai-us/hq-cloud';
|
|
6
8
|
import { DEFAULT_COGNITO } from '../utils/cognito-session.js';
|
|
@@ -41,4 +43,5 @@ export function registerLoginCommand(program) {
|
|
|
41
43
|
}
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
|
-
//# sourceMappingURL=login.js.map
|
|
46
|
+
//# sourceMappingURL=login.js.map
|
|
47
|
+
//# debugId=31735154-208b-5544-85a4-22f8f0fbe415
|
package/dist/commands/logout.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* hq logout — clears cached Cognito session
|
|
3
3
|
*/
|
|
4
|
+
|
|
5
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="120038e8-9b88-59c3-821a-da21ccb1c365")}catch(e){}}();
|
|
4
6
|
import chalk from 'chalk';
|
|
5
7
|
import { clearCachedTokens, loadCachedTokens } from '@indigoai-us/hq-cloud';
|
|
6
8
|
export function registerLogoutCommand(program) {
|
|
@@ -23,4 +25,5 @@ export function registerLogoutCommand(program) {
|
|
|
23
25
|
}
|
|
24
26
|
});
|
|
25
27
|
}
|
|
26
|
-
//# sourceMappingURL=logout.js.map
|
|
28
|
+
//# sourceMappingURL=logout.js.map
|
|
29
|
+
//# debugId=120038e8-9b88-59c3-821a-da21ccb1c365
|
package/dist/commands/onboard.js
CHANGED
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
* If the cached token is missing or expired beyond the refresh window, the
|
|
19
19
|
* browser-OAuth flow opens automatically.
|
|
20
20
|
*/
|
|
21
|
+
|
|
22
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="38856701-42d8-587b-9969-8da51ede7cd4")}catch(e){}}();
|
|
21
23
|
import chalk from "chalk";
|
|
22
24
|
import { runOnboardCli } from "@indigoai-us/hq-onboarding";
|
|
23
25
|
import { DEFAULT_HQ_ROOT, ensureCognitoToken, buildVaultConfig, } from "../utils/cognito-session.js";
|
|
@@ -139,4 +141,5 @@ export function registerOnboardCommand(program) {
|
|
|
139
141
|
}
|
|
140
142
|
});
|
|
141
143
|
}
|
|
142
|
-
//# sourceMappingURL=onboard.js.map
|
|
144
|
+
//# sourceMappingURL=onboard.js.map
|
|
145
|
+
//# debugId=38856701-42d8-587b-9969-8da51ede7cd4
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
* 7. Append entry to modules.yaml with strategy: package
|
|
31
31
|
* 8. Run scan-packages.sh to wire contributions into host paths
|
|
32
32
|
*/
|
|
33
|
+
|
|
34
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9c0fc9f1-9a26-5a3f-a795-7254534316d5")}catch(e){}}();
|
|
33
35
|
import * as fs from 'fs';
|
|
34
36
|
import * as os from 'os';
|
|
35
37
|
import * as path from 'path';
|
|
@@ -510,4 +512,5 @@ export async function installPack(source, opts = {}) {
|
|
|
510
512
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
511
513
|
}
|
|
512
514
|
}
|
|
513
|
-
//# sourceMappingURL=pack-install.js.map
|
|
515
|
+
//# sourceMappingURL=pack-install.js.map
|
|
516
|
+
//# debugId=9c0fc9f1-9a26-5a3f-a795-7254534316d5
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* 8. Update packages/registry.yaml
|
|
13
13
|
* 9. Print next-step message
|
|
14
14
|
*/
|
|
15
|
+
|
|
16
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="874fe8a4-2348-5f03-8600-c545cac13fc9")}catch(e){}}();
|
|
15
17
|
import * as fs from 'fs';
|
|
16
18
|
import * as os from 'os';
|
|
17
19
|
import * as path from 'path';
|
|
@@ -153,4 +155,5 @@ async function installPackage(slug, company) {
|
|
|
153
155
|
}
|
|
154
156
|
}
|
|
155
157
|
}
|
|
156
|
-
//# sourceMappingURL=pkg-install.js.map
|
|
158
|
+
//# sourceMappingURL=pkg-install.js.map
|
|
159
|
+
//# debugId=874fe8a4-2348-5f03-8600-c545cac13fc9
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Graceful offline: if registry is unreachable, show cached data with a note.
|
|
5
5
|
*/
|
|
6
|
+
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ce4886ce-109a-5ace-b8d9-4e5bed61978a")}catch(e){}}();
|
|
6
8
|
import chalk from 'chalk';
|
|
7
9
|
import { findHqRoot } from '../utils/hq-root.js';
|
|
8
10
|
import { readRegistry } from '../utils/registry.js';
|
|
@@ -67,4 +69,5 @@ async function listPackages() {
|
|
|
67
69
|
console.log(chalk.yellow('Note: Could not reach registry — showing cached data only.'));
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
|
-
//# sourceMappingURL=pkg-list.js.map
|
|
72
|
+
//# sourceMappingURL=pkg-list.js.map
|
|
73
|
+
//# debugId=ce4886ce-109a-5ace-b8d9-4e5bed61978a
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* 2. Remove entry from packages/registry.yaml
|
|
6
6
|
* 3. Print next-step message
|
|
7
7
|
*/
|
|
8
|
+
|
|
9
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b54529d6-de12-595e-b1c7-ab50b9f22eb5")}catch(e){}}();
|
|
8
10
|
import * as fs from 'fs';
|
|
9
11
|
import * as path from 'path';
|
|
10
12
|
import chalk from 'chalk';
|
|
@@ -50,4 +52,5 @@ async function removePackage(slug) {
|
|
|
50
52
|
console.log(chalk.green(`\nRemoved ${slug}.`));
|
|
51
53
|
console.log(chalk.cyan('Run /package-remove ' + slug + ' in Claude to clean up merged content.'));
|
|
52
54
|
}
|
|
53
|
-
//# sourceMappingURL=pkg-remove.js.map
|
|
55
|
+
//# sourceMappingURL=pkg-remove.js.map
|
|
56
|
+
//# debugId=b54529d6-de12-595e-b1c7-ab50b9f22eb5
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* If no slug: check all installed packages for updates.
|
|
5
5
|
* If slug given: update only that package.
|
|
6
6
|
*/
|
|
7
|
+
|
|
8
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3ef2968d-eb65-594b-a506-4314b70dd3dc")}catch(e){}}();
|
|
7
9
|
import * as fs from 'fs';
|
|
8
10
|
import * as os from 'os';
|
|
9
11
|
import * as path from 'path';
|
|
@@ -121,4 +123,5 @@ async function updatePackages(slug) {
|
|
|
121
123
|
}
|
|
122
124
|
console.log(`\n${updatedCount} package(s) updated${updatedCount > 0 ? '.' : ' — everything is current.'}`);
|
|
123
125
|
}
|
|
124
|
-
//# sourceMappingURL=pkg-update.js.map
|
|
126
|
+
//# sourceMappingURL=pkg-update.js.map
|
|
127
|
+
//# debugId=3ef2968d-eb65-594b-a506-4314b70dd3dc
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
export interface VaultApiOptions {
|
|
3
|
+
token: string;
|
|
4
|
+
path: string;
|
|
5
|
+
method?: string;
|
|
6
|
+
body?: Record<string, unknown>;
|
|
7
|
+
query?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
export declare function vaultApiFetch(opts: VaultApiOptions): Promise<Response>;
|
|
10
|
+
export declare function getCompanyUid(token: string, companySlug: string | undefined): Promise<string>;
|
|
2
11
|
export declare function registerSecretsCommand(program: Command): void;
|
|
3
12
|
//# sourceMappingURL=secrets.d.ts.map
|