@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
|
@@ -0,0 +1,219 @@
|
|
|
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]="d9f4f042-d671-5ca3-8b43-d26395fc0189")}catch(e){}}();
|
|
3
|
+
const SENSITIVE_FIELD_NAMES = new Set([
|
|
4
|
+
"password", "secret", "apikey", "api_key", "token",
|
|
5
|
+
// Cognito token-response fields captured as error context.
|
|
6
|
+
"idtoken", "accesstoken", "refreshtoken",
|
|
7
|
+
]);
|
|
8
|
+
// Stored lowercased; membership tested against `name.toLowerCase()`.
|
|
9
|
+
// MUST cover BOTH Auth.js v5 (current in hq-console, pinned to
|
|
10
|
+
// next-auth@5.0.0-beta.25 which resolves @auth/core@0.37.2) AND legacy
|
|
11
|
+
// NextAuth v4 name spaces — covering both is cheap and survives accidental
|
|
12
|
+
// downgrades or mixed-version repos. Grounded against @auth/core@0.37.2's
|
|
13
|
+
// src/lib/utils/cookie.ts (re-ground via `grep -nE
|
|
14
|
+
// '(sessionToken|callbackUrl|csrfToken|pkceCodeVerifier|state|nonce|webauthnChallenge): \{'
|
|
15
|
+
// node_modules/.pnpm/@auth+core@0.37.2/node_modules/@auth/core/src/lib/utils/cookie.ts`
|
|
16
|
+
// — seven matches, one per cookie family): two distinct prefixing patterns
|
|
17
|
+
// coexist there, and the entries below mirror BOTH exactly:
|
|
18
|
+
// • session-token / callback-url / pkce.code_verifier / state / nonce /
|
|
19
|
+
// challenge each pair the bare form (HTTP dev, cookiePrefix="") with
|
|
20
|
+
// the __Secure- form (HTTPS prod, cookiePrefix="__Secure-").
|
|
21
|
+
// • csrf-token is special: the source explicitly uses __Host- (NOT
|
|
22
|
+
// __Secure-) under HTTPS for stricter cookie scoping (the csrfToken
|
|
23
|
+
// entry in @auth/core's cookie.ts is the only one whose name template
|
|
24
|
+
// uses `__Host-` instead of `${cookiePrefix}`; the comment above it
|
|
25
|
+
// reads "Default to __Host- for CSRF token for additional protection
|
|
26
|
+
// if using useSecureCookies"). The set therefore pairs the bare form
|
|
27
|
+
// with __Host-, and does NOT include __Secure-authjs.csrf-token
|
|
28
|
+
// because @auth/core never emits that name. The legacy v4 entry mirrors
|
|
29
|
+
// the same pattern (bare next-auth.csrf-token + __Host-next-auth.csrf-token,
|
|
30
|
+
// no __Secure- variant).
|
|
31
|
+
// Missing any of the four OAuth-state families (pkce.code_verifier, state,
|
|
32
|
+
// nonce, challenge) ships a cookie-leak in the same class as the v4-only
|
|
33
|
+
// defect Round-4 called out. This set is the single authoritative spec;
|
|
34
|
+
// all of Steps 3/8/9a/12/13 reproduce it identically.
|
|
35
|
+
//
|
|
36
|
+
// MAINTAINER NOTE: Do NOT extend this set by mechanically pairing every
|
|
37
|
+
// cookie with bare + __Secure- + __Host-. The pairing follows the source:
|
|
38
|
+
// session-style cookies use __Secure-; csrf-style cookies use __Host-.
|
|
39
|
+
// New entries added in the future must be grounded against the actual
|
|
40
|
+
// emitter (Auth.js source for v5/v4, vendor docs for Clerk, etc.) rather
|
|
41
|
+
// than copied from the existing pattern.
|
|
42
|
+
const SENSITIVE_COOKIE_NAMES = new Set([
|
|
43
|
+
// ==== Auth.js v5 (next-auth@5 / @auth/core) ====
|
|
44
|
+
// Session JWT — bare + __Secure-
|
|
45
|
+
"authjs.session-token",
|
|
46
|
+
"__secure-authjs.session-token",
|
|
47
|
+
// CSRF double-submit token — bare + __Host- ONLY (@auth/core's cookie.ts
|
|
48
|
+
// csrfToken entry uses __Host-, never __Secure-)
|
|
49
|
+
"authjs.csrf-token",
|
|
50
|
+
"__host-authjs.csrf-token",
|
|
51
|
+
// Post-auth redirect URL — bare + __Secure-
|
|
52
|
+
"authjs.callback-url",
|
|
53
|
+
"__secure-authjs.callback-url",
|
|
54
|
+
// OAuth PKCE verifier — leaking this enables interception of an in-flight
|
|
55
|
+
// OAuth code exchange.
|
|
56
|
+
"authjs.pkce.code_verifier",
|
|
57
|
+
"__secure-authjs.pkce.code_verifier",
|
|
58
|
+
// OAuth CSRF/replay protection
|
|
59
|
+
"authjs.state",
|
|
60
|
+
"__secure-authjs.state",
|
|
61
|
+
// OpenID Connect nonce — replay protection
|
|
62
|
+
"authjs.nonce",
|
|
63
|
+
"__secure-authjs.nonce",
|
|
64
|
+
// OAuth WebAuthn challenge
|
|
65
|
+
"authjs.challenge",
|
|
66
|
+
"__secure-authjs.challenge",
|
|
67
|
+
// ==== NextAuth v4 legacy names (kept so accidental downgrades /
|
|
68
|
+
// mixed-version monorepos don't silently leak). Same prefix
|
|
69
|
+
// discipline as v5: csrf-token uses __Host-, others use __Secure-. ====
|
|
70
|
+
"next-auth.session-token",
|
|
71
|
+
"__secure-next-auth.session-token",
|
|
72
|
+
"next-auth.csrf-token",
|
|
73
|
+
"__host-next-auth.csrf-token",
|
|
74
|
+
"next-auth.callback-url",
|
|
75
|
+
"__secure-next-auth.callback-url",
|
|
76
|
+
"next-auth.pkce.code_verifier",
|
|
77
|
+
"__secure-next-auth.pkce.code_verifier",
|
|
78
|
+
"next-auth.state",
|
|
79
|
+
"__secure-next-auth.state",
|
|
80
|
+
// ==== Clerk (documented for future; no-op today) ====
|
|
81
|
+
"__clerk_db_jwt", "__session",
|
|
82
|
+
]);
|
|
83
|
+
const REDACTED = "[Filtered]";
|
|
84
|
+
const SENSITIVE_HEADER_NAMES = new Set([
|
|
85
|
+
"authorization", "proxy-authorization",
|
|
86
|
+
"cookie", "set-cookie",
|
|
87
|
+
"x-api-key", "x-auth-token", "x-access-token", "x-session-token",
|
|
88
|
+
]);
|
|
89
|
+
function scrubHeaders(h) {
|
|
90
|
+
if (!h)
|
|
91
|
+
return h;
|
|
92
|
+
const out = {};
|
|
93
|
+
for (const [k, v] of Object.entries(h)) {
|
|
94
|
+
out[k] = SENSITIVE_HEADER_NAMES.has(k.toLowerCase()) ? REDACTED : v;
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
function scrubCookies(c) {
|
|
99
|
+
if (!c)
|
|
100
|
+
return c;
|
|
101
|
+
if (typeof c === "string")
|
|
102
|
+
return REDACTED; // raw Cookie header — wholesale redact
|
|
103
|
+
const out = {};
|
|
104
|
+
for (const [k, v] of Object.entries(c)) {
|
|
105
|
+
out[k] = SENSITIVE_COOKIE_NAMES.has(k.toLowerCase()) ? REDACTED : v;
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
const SENSITIVE_STRING_PATTERNS = [
|
|
110
|
+
// kv pairs; `(?:id|access|refresh)[_-]?token` catches Cognito-style free-text
|
|
111
|
+
// `accessToken=...`, `refreshToken: ...`, `id_token=...` which bare `\btoken` misses.
|
|
112
|
+
/\b(password|secret|api[_-]?key|(?:id|access|refresh)[_-]?token|token)\s*[:=]\s*[^\s&"'<>]+/gi,
|
|
113
|
+
/\b(Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+/gi,
|
|
114
|
+
/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,
|
|
115
|
+
];
|
|
116
|
+
function scrubString(s) {
|
|
117
|
+
let out = s;
|
|
118
|
+
for (const re of SENSITIVE_STRING_PATTERNS) {
|
|
119
|
+
out = out.replace(re, (m) => {
|
|
120
|
+
const sep = m.search(/[:=\s]/);
|
|
121
|
+
return sep > 0 ? `${m.slice(0, sep + 1)}${REDACTED}` : REDACTED;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
function scrubQueryString(qs) {
|
|
127
|
+
try {
|
|
128
|
+
const params = new URLSearchParams(qs.startsWith("?") ? qs.slice(1) : qs);
|
|
129
|
+
const out = [];
|
|
130
|
+
for (const [k, v] of params) {
|
|
131
|
+
out.push(`${k}=${SENSITIVE_FIELD_NAMES.has(k.toLowerCase()) ? REDACTED : v}`);
|
|
132
|
+
}
|
|
133
|
+
const joined = out.join("&");
|
|
134
|
+
return qs.startsWith("?") ? `?${joined}` : joined;
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return scrubString(qs);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function scrubFields(value, memo = new Map()) {
|
|
141
|
+
if (value === null || typeof value !== "object")
|
|
142
|
+
return value;
|
|
143
|
+
const obj = value;
|
|
144
|
+
// On cycle revisit, return the SAME scrubbed copy built on first visit —
|
|
145
|
+
// NOT the original. Returning the original would leak fields reachable
|
|
146
|
+
// only through the cycle (e.g., a.self.token).
|
|
147
|
+
if (memo.has(obj))
|
|
148
|
+
return memo.get(obj);
|
|
149
|
+
if (Array.isArray(value)) {
|
|
150
|
+
const arr = [];
|
|
151
|
+
memo.set(obj, arr);
|
|
152
|
+
for (const v of value)
|
|
153
|
+
arr.push(scrubFields(v, memo));
|
|
154
|
+
return arr;
|
|
155
|
+
}
|
|
156
|
+
const out = {};
|
|
157
|
+
memo.set(obj, out);
|
|
158
|
+
for (const [k, v] of Object.entries(value)) {
|
|
159
|
+
if (SENSITIVE_FIELD_NAMES.has(k.toLowerCase())) {
|
|
160
|
+
out[k] = REDACTED;
|
|
161
|
+
}
|
|
162
|
+
else if (v !== null && typeof v === "object") {
|
|
163
|
+
out[k] = scrubFields(v, memo);
|
|
164
|
+
}
|
|
165
|
+
else if (typeof v === "string") {
|
|
166
|
+
// SCALAR-STRING DEFENSE-IN-DEPTH. A stringified log line stashed via
|
|
167
|
+
// setExtra / setContext / setUser can embed `password=...` or a Bearer
|
|
168
|
+
// token even when the outer key (`note`, `bio`, `log_line`, …) isn't
|
|
169
|
+
// in SENSITIVE_FIELD_NAMES. Route scalar strings through scrubString so
|
|
170
|
+
// these don't bypass the scrubber on their way into Sentry.
|
|
171
|
+
out[k] = scrubString(v);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
out[k] = v;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
export function beforeSend(event, _hint) {
|
|
180
|
+
if (event.request) {
|
|
181
|
+
const req = event.request;
|
|
182
|
+
event.request = {
|
|
183
|
+
...event.request,
|
|
184
|
+
headers: scrubHeaders(req.headers),
|
|
185
|
+
cookies: scrubCookies(req.cookies),
|
|
186
|
+
data: scrubFields(req.data),
|
|
187
|
+
query_string: typeof req.query_string === "string"
|
|
188
|
+
? scrubQueryString(req.query_string)
|
|
189
|
+
: req.query_string,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (typeof event.message === "string")
|
|
193
|
+
event.message = scrubString(event.message);
|
|
194
|
+
if (event.exception?.values) {
|
|
195
|
+
event.exception = {
|
|
196
|
+
...event.exception,
|
|
197
|
+
values: event.exception.values.map((v) => ({
|
|
198
|
+
...v,
|
|
199
|
+
value: typeof v.value === "string" ? scrubString(v.value) : v.value,
|
|
200
|
+
})),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
if (event.user)
|
|
204
|
+
event.user = scrubFields(event.user);
|
|
205
|
+
if (event.breadcrumbs) {
|
|
206
|
+
event.breadcrumbs = event.breadcrumbs.map((b) => ({
|
|
207
|
+
...b,
|
|
208
|
+
message: typeof b.message === "string" ? scrubString(b.message) : b.message,
|
|
209
|
+
data: b.data ? scrubFields(b.data) : b.data,
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
if (event.extra)
|
|
213
|
+
event.extra = scrubFields(event.extra);
|
|
214
|
+
if (event.contexts)
|
|
215
|
+
event.contexts = scrubFields(event.contexts);
|
|
216
|
+
return event;
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=sentry-before-send.js.map
|
|
219
|
+
//# debugId=d9f4f042-d671-5ca3-8b43-d26395fc0189
|
|
@@ -0,0 +1,5 @@
|
|
|
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]="55f2362e-5cf7-5dac-b6a3-ef0f9ccde645")}catch(e){}}();
|
|
3
|
+
export const BUNDLED_DSN = "https://ed8c1f7624b67945b43d485bbf98d0f7@o4507292345892864.ingest.us.sentry.io/4511263744786432";
|
|
4
|
+
//# sourceMappingURL=sentry-dsn.generated.js.map
|
|
5
|
+
//# debugId=55f2362e-5cf7-5dac-b6a3-ef0f9ccde645
|
package/dist/sentry.d.ts
ADDED
package/dist/sentry.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
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]="9a31fb53-8cc1-5394-ac16-e96b82fa6caa")}catch(e){}}();
|
|
3
|
+
import * as Sentry from "@sentry/node";
|
|
4
|
+
import { BUNDLED_DSN } from "./sentry-dsn.generated.js";
|
|
5
|
+
import { beforeSend } from "./sentry-before-send.js";
|
|
6
|
+
export function initSentry() {
|
|
7
|
+
const dsn = BUNDLED_DSN || process.env.SENTRY_DSN;
|
|
8
|
+
if (!dsn)
|
|
9
|
+
return;
|
|
10
|
+
Sentry.init({
|
|
11
|
+
dsn,
|
|
12
|
+
release: `hq-cli@${process.env.npm_package_version ?? "0.0.0"}`,
|
|
13
|
+
environment: process.env.HQ_CLI_ENV ?? "production",
|
|
14
|
+
initialScope: {
|
|
15
|
+
tags: { repo: "hq-cli" },
|
|
16
|
+
},
|
|
17
|
+
beforeSend,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export { Sentry };
|
|
21
|
+
//# sourceMappingURL=sentry.js.map
|
|
22
|
+
//# debugId=9a31fb53-8cc1-5394-ac16-e96b82fa6caa
|
package/dist/strategies/link.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Link Sync Strategy (US-006)
|
|
3
3
|
* Symlinks module paths into HQ tree
|
|
4
4
|
*/
|
|
5
|
+
|
|
6
|
+
!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]="602c865a-033c-5b7c-8839-11a66b9a6bc5")}catch(e){}}();
|
|
5
7
|
import * as fs from 'fs';
|
|
6
8
|
import * as path from 'path';
|
|
7
9
|
export async function linkSync(module, moduleDir, hqRoot) {
|
|
@@ -48,4 +50,5 @@ export async function linkSync(module, moduleDir, hqRoot) {
|
|
|
48
50
|
filesChanged,
|
|
49
51
|
};
|
|
50
52
|
}
|
|
51
|
-
//# sourceMappingURL=link.js.map
|
|
53
|
+
//# sourceMappingURL=link.js.map
|
|
54
|
+
//# debugId=602c865a-033c-5b7c-8839-11a66b9a6bc5
|
package/dist/strategies/merge.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Merge Sync Strategy (US-007)
|
|
3
3
|
* Copies files from module into HQ, tracks state for conflict detection
|
|
4
4
|
*/
|
|
5
|
+
|
|
6
|
+
!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]="7a161796-4e72-58d8-89f3-a1010add7d0f")}catch(e){}}();
|
|
5
7
|
import * as fs from 'fs';
|
|
6
8
|
import * as path from 'path';
|
|
7
9
|
import * as crypto from 'crypto';
|
|
@@ -107,4 +109,5 @@ export async function mergeSync(module, moduleDir, hqRoot) {
|
|
|
107
109
|
filesChanged: filesChanged.count,
|
|
108
110
|
};
|
|
109
111
|
}
|
|
110
|
-
//# sourceMappingURL=merge.js.map
|
|
112
|
+
//# sourceMappingURL=merge.js.map
|
|
113
|
+
//# debugId=7a161796-4e72-58d8-89f3-a1010add7d0f
|
package/dist/types.js
CHANGED
|
@@ -7,5 +7,8 @@
|
|
|
7
7
|
* (new in hq-core v12.0.0; see
|
|
8
8
|
* knowledge/public/hq-core/package-yaml-spec.md)
|
|
9
9
|
*/
|
|
10
|
+
|
|
11
|
+
!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]="42a2c1bd-8924-5fcf-8f50-72086dab7a97")}catch(e){}}();
|
|
10
12
|
export {};
|
|
11
|
-
//# sourceMappingURL=types.js.map
|
|
13
|
+
//# sourceMappingURL=types.js.map
|
|
14
|
+
//# debugId=42a2c1bd-8924-5fcf-8f50-72086dab7a97
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* HQ_COGNITO_CALLBACK_PORT — Loopback OAuth callback port
|
|
17
17
|
* HQ_VAULT_API_URL — vault-service API Gateway URL
|
|
18
18
|
*/
|
|
19
|
+
|
|
20
|
+
!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]="95513873-e956-5318-8115-e2088c581155")}catch(e){}}();
|
|
19
21
|
import * as os from "os";
|
|
20
22
|
import * as path from "path";
|
|
21
23
|
import chalk from "chalk";
|
|
@@ -96,4 +98,5 @@ export async function refreshCachedSession() {
|
|
|
96
98
|
};
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
|
-
//# sourceMappingURL=cognito-session.js.map
|
|
101
|
+
//# sourceMappingURL=cognito-session.js.map
|
|
102
|
+
//# debugId=95513873-e956-5318-8115-e2088c581155
|
package/dist/utils/git.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
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]="6ee15d43-ad5e-5f40-b27b-8bd389e0dad7")}catch(e){}}();
|
|
1
3
|
import * as fs from 'fs';
|
|
2
4
|
import * as path from 'path';
|
|
3
5
|
import simpleGit from 'simple-git';
|
|
@@ -67,4 +69,5 @@ export function ensureGitignore(hqRoot, entry) {
|
|
|
67
69
|
fs.writeFileSync(gitignorePath, content);
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
|
-
//# sourceMappingURL=git.js.map
|
|
72
|
+
//# sourceMappingURL=git.js.map
|
|
73
|
+
//# debugId=6ee15d43-ad5e-5f40-b27b-8bd389e0dad7
|
package/dist/utils/hq-root.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HQ root detection — walks up from cwd looking for HQ markers (US-004)
|
|
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]="aebb967b-5f70-5107-9d81-bb495be1c405")}catch(e){}}();
|
|
4
6
|
import * as fs from 'fs';
|
|
5
7
|
import * as path from 'path';
|
|
6
8
|
/**
|
|
@@ -19,4 +21,5 @@ export function findHqRoot() {
|
|
|
19
21
|
}
|
|
20
22
|
throw new Error('Could not find HQ root. Run this command from within your HQ directory.');
|
|
21
23
|
}
|
|
22
|
-
//# sourceMappingURL=hq-root.js.map
|
|
24
|
+
//# sourceMappingURL=hq-root.js.map
|
|
25
|
+
//# debugId=aebb967b-5f70-5107-9d81-bb495be1c405
|
package/dist/utils/integrity.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Integrity verification — SHA256 hash and RSA signature checks (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]="19765c32-6c3d-5477-bf80-0f7d08197d29")}catch(e){}}();
|
|
4
6
|
import * as crypto from 'crypto';
|
|
5
7
|
import * as fs from 'fs';
|
|
6
8
|
import * as path from 'path';
|
|
@@ -37,4 +39,5 @@ export function verifyRsaSignature(sha256Hash, signature, publicKeyPath) {
|
|
|
37
39
|
verifier.end();
|
|
38
40
|
return verifier.verify(publicKey, Buffer.from(signature, 'base64'));
|
|
39
41
|
}
|
|
40
|
-
//# sourceMappingURL=integrity.js.map
|
|
42
|
+
//# sourceMappingURL=integrity.js.map
|
|
43
|
+
//# debugId=19765c32-6c3d-5477-bf80-0f7d08197d29
|
package/dist/utils/manifest.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
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]="ea38913d-4086-56ca-872a-9a85ccf9c453")}catch(e){}}();
|
|
1
3
|
import * as fs from 'fs';
|
|
2
4
|
import * as path from 'path';
|
|
3
5
|
import * as yaml from 'js-yaml';
|
|
@@ -112,4 +114,5 @@ export function parseRepoName(repoUrl) {
|
|
|
112
114
|
export function isValidRepoUrl(url) {
|
|
113
115
|
return url.startsWith('https://') || url.startsWith('git@');
|
|
114
116
|
}
|
|
115
|
-
//# sourceMappingURL=manifest.js.map
|
|
117
|
+
//# sourceMappingURL=manifest.js.map
|
|
118
|
+
//# debugId=ea38913d-4086-56ca-872a-9a85ccf9c453
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Auth tokens are NEVER written to stdout or logs.
|
|
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]="ffe2dc58-fb20-5566-a56c-1b1c26999bba")}catch(e){}}();
|
|
7
9
|
import * as fs from 'fs';
|
|
8
10
|
import * as path from 'path';
|
|
9
11
|
import * as yaml from 'js-yaml';
|
|
@@ -99,4 +101,5 @@ export class RegistryClient {
|
|
|
99
101
|
return this.request('GET', `/packages/${encodeURIComponent(slug)}/download${qs ? `?${qs}` : ''}`, { auth: true });
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
|
-
//# sourceMappingURL=registry-client.js.map
|
|
104
|
+
//# sourceMappingURL=registry-client.js.map
|
|
105
|
+
//# debugId=ffe2dc58-fb20-5566-a56c-1b1c26999bba
|
package/dist/utils/registry.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Registry YAML helpers — read/write packages/registry.yaml (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]="3fb6a06d-7cbe-5764-be4f-6c8189de649c")}catch(e){}}();
|
|
4
6
|
import * as fs from 'fs';
|
|
5
7
|
import * as path from 'path';
|
|
6
8
|
import * as yaml from 'js-yaml';
|
|
@@ -55,4 +57,5 @@ export function removeFromRegistry(hqRoot, slug) {
|
|
|
55
57
|
const entries = readRegistry(hqRoot).filter((e) => e.slug !== slug);
|
|
56
58
|
writeRegistry(hqRoot, entries);
|
|
57
59
|
}
|
|
58
|
-
//# sourceMappingURL=registry.js.map
|
|
60
|
+
//# sourceMappingURL=registry.js.map
|
|
61
|
+
//# debugId=3fb6a06d-7cbe-5764-be4f-6c8189de649c
|
|
@@ -1,3 +1,5 @@
|
|
|
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]="263d7b10-622e-56c3-8c82-ebb294510b1b")}catch(e){}}();
|
|
1
3
|
import * as crypto from "node:crypto";
|
|
2
4
|
import * as fs from "node:fs";
|
|
3
5
|
import * as path from "node:path";
|
|
@@ -15,7 +17,7 @@ function ensureCacheDir(companyUid) {
|
|
|
15
17
|
function validateInputs(companyUid, name) {
|
|
16
18
|
if (!companyUid || companyUid.includes("/") || companyUid.includes(".."))
|
|
17
19
|
return false;
|
|
18
|
-
if (!/^[A-Z][A-Z0-9_]*$/.test(name))
|
|
20
|
+
if (!/^[A-Z][A-Z0-9_]*(?:\/[A-Z][A-Z0-9_]+)*$/.test(name))
|
|
19
21
|
return false;
|
|
20
22
|
return true;
|
|
21
23
|
}
|
|
@@ -101,6 +103,7 @@ export function writeCache(companyUid, name, value) {
|
|
|
101
103
|
timestamp.writeBigInt64BE(BigInt(Date.now()));
|
|
102
104
|
const out = Buffer.concat([timestamp, iv, authTag, encrypted]);
|
|
103
105
|
const filePath = path.join(CACHE_DIR, companyUid, name);
|
|
106
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
104
107
|
const tmpPath = `${filePath}.tmp.${process.pid}`;
|
|
105
108
|
fs.writeFileSync(tmpPath, out, { mode: 0o600 });
|
|
106
109
|
fs.renameSync(tmpPath, filePath);
|
|
@@ -131,4 +134,5 @@ export function clearAllCache() {
|
|
|
131
134
|
}
|
|
132
135
|
return { removed };
|
|
133
136
|
}
|
|
134
|
-
//# sourceMappingURL=secrets-cache.js.map
|
|
137
|
+
//# sourceMappingURL=secrets-cache.js.map
|
|
138
|
+
//# debugId=263d7b10-622e-56c3-8c82-ebb294510b1b
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indigoai-us/hq-cli",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.3",
|
|
4
4
|
"description": "HQ by Indigo management CLI — modules and cloud sync",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,14 +8,15 @@
|
|
|
8
8
|
"hq-auth-refresh": "dist/bin/hq-auth-refresh.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
11
|
+
"build": "node scripts/generate-dsn.mjs && tsc",
|
|
12
12
|
"typecheck": "tsc --noEmit",
|
|
13
13
|
"test": "vitest run",
|
|
14
14
|
"clean": "rm -rf dist"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
+
"@sentry/node": "^10.49.0",
|
|
17
18
|
"@indigoai-us/hq-cloud": "^5.1.0",
|
|
18
|
-
"@indigoai-us/hq-onboarding": "^0.1.
|
|
19
|
+
"@indigoai-us/hq-onboarding": "^0.1.0",
|
|
19
20
|
"chalk": "^5.3.0",
|
|
20
21
|
"commander": "^12.1.0",
|
|
21
22
|
"js-yaml": "^4.1.0",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { writeFileSync } from "fs";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
const isGitHubActions = process.env.GITHUB_ACTIONS === "true";
|
|
8
|
+
const isPublishJob = process.env.GITHUB_JOB === "publish";
|
|
9
|
+
const dsn = process.env.HQ_CLI_PUBLISH_SENTRY_DSN ?? "";
|
|
10
|
+
|
|
11
|
+
if (isGitHubActions && isPublishJob && !dsn) {
|
|
12
|
+
process.stderr.write(
|
|
13
|
+
"[generate-dsn] FATAL: GITHUB_ACTIONS=true, GITHUB_JOB=publish, " +
|
|
14
|
+
"but HQ_CLI_PUBLISH_SENTRY_DSN is not set. " +
|
|
15
|
+
"Add the repo secret HQ_CLI_PUBLISH_SENTRY_DSN before publishing.\n",
|
|
16
|
+
);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const outPath = join(__dirname, "../src/sentry-dsn.generated.ts");
|
|
21
|
+
const content = `export const BUNDLED_DSN = "${dsn}";\n`;
|
|
22
|
+
|
|
23
|
+
writeFileSync(outPath, content, "utf8");
|
|
24
|
+
process.stdout.write(
|
|
25
|
+
`[generate-dsn] Wrote BUNDLED_DSN="${dsn ? "[DSN set]" : ""}" to ${outPath}\n`,
|
|
26
|
+
);
|
|
@@ -11,22 +11,29 @@
|
|
|
11
11
|
* Writes the refreshed tokens to ~/.hq/cognito-tokens.json.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { initSentry, Sentry } from "../sentry.js";
|
|
14
15
|
import { refreshCachedSession } from "../utils/cognito-session.js";
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
const result = await refreshCachedSession();
|
|
18
|
-
if (result.refreshed) {
|
|
19
|
-
process.exit(0);
|
|
20
|
-
}
|
|
21
|
-
if (result.reason) {
|
|
22
|
-
process.stderr.write(`hq-auth-refresh: ${result.reason}\n`);
|
|
23
|
-
}
|
|
24
|
-
process.exit(1);
|
|
25
|
-
}
|
|
17
|
+
initSentry();
|
|
26
18
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
(async () => {
|
|
20
|
+
let exitCode = 1;
|
|
21
|
+
try {
|
|
22
|
+
const result = await refreshCachedSession();
|
|
23
|
+
if (result.refreshed) {
|
|
24
|
+
exitCode = 0;
|
|
25
|
+
} else {
|
|
26
|
+
if (result.reason) {
|
|
27
|
+
process.stderr.write(`hq-auth-refresh: ${result.reason}\n`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} catch (err) {
|
|
31
|
+
Sentry.captureException(err);
|
|
32
|
+
process.stderr.write(
|
|
33
|
+
`hq-auth-refresh: ${err instanceof Error ? err.message : String(err)}\n`,
|
|
34
|
+
);
|
|
35
|
+
} finally {
|
|
36
|
+
await Sentry.flush(2000);
|
|
37
|
+
process.exit(exitCode);
|
|
38
|
+
}
|
|
39
|
+
})();
|