@indigoai-us/hq-cli 5.119.5 → 5.119.6
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 +8 -0
- package/dist/commands/agents.js +39 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.119.6] — 2026-09-17
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Slack token paste links now use the company's canonical Console slug. Links
|
|
10
|
+
built with an internal company ID redirected to the company home and lost the
|
|
11
|
+
agent setup form.
|
|
12
|
+
|
|
5
13
|
## [5.119.5] — 2026-09-17
|
|
6
14
|
|
|
7
15
|
### Fixed
|
package/dist/commands/agents.js
CHANGED
|
@@ -443,7 +443,7 @@ function currentDeviceSignInAction(status) {
|
|
|
443
443
|
code,
|
|
444
444
|
};
|
|
445
445
|
}
|
|
446
|
-
function pendingSlackAction(status) {
|
|
446
|
+
function pendingSlackAction(status, companySlug) {
|
|
447
447
|
const agent = recordValue(status.agent);
|
|
448
448
|
const configuredSlack = recordValue(recordValue(agent?.channels)?.slack);
|
|
449
449
|
const appId = nonEmptyString(configuredSlack?.appId);
|
|
@@ -455,6 +455,9 @@ function pendingSlackAction(status) {
|
|
|
455
455
|
new URL(tokenPage).hostname === "api.slack.com" &&
|
|
456
456
|
agentUid && AGENT_UID_PATTERN.test(agentUid) &&
|
|
457
457
|
companyUid && /^cmp_[A-Za-z0-9_-]+$/.test(companyUid)) {
|
|
458
|
+
const companyUrlKey = companySlug && /^[a-z0-9][a-z0-9-]*$/.test(companySlug)
|
|
459
|
+
? companySlug
|
|
460
|
+
: companyUid;
|
|
458
461
|
return {
|
|
459
462
|
type: "slack-app-token",
|
|
460
463
|
title: `Finish ${nonEmptyString(agent?.name) ?? "the agent"}'s Slack connection`,
|
|
@@ -462,7 +465,7 @@ function pendingSlackAction(status) {
|
|
|
462
465
|
instruction: "Create an app-level token with the connections:write scope, then paste it into HQ. HQ verifies the token and resumes setup; if Slack asks you to install the app, follow the install link shown there.",
|
|
463
466
|
url: `https://api.slack.com/apps/${appId}/general`,
|
|
464
467
|
urlLabel: "Get token",
|
|
465
|
-
pasteUrl: `https://hq.computer/companies/${encodeURIComponent(
|
|
468
|
+
pasteUrl: `https://hq.computer/companies/${encodeURIComponent(companyUrlKey)}/agents?setup=${encodeURIComponent(agentUid)}`,
|
|
466
469
|
};
|
|
467
470
|
}
|
|
468
471
|
const diagnostics = recordValue(agent?.channelDiagnostics);
|
|
@@ -496,12 +499,40 @@ function pendingSlackAction(status) {
|
|
|
496
499
|
* status fields into a list so another operator action can be added without
|
|
497
500
|
* changing the renderers or command control flow.
|
|
498
501
|
*/
|
|
499
|
-
function pendingOperatorActions(status) {
|
|
502
|
+
function pendingOperatorActions(status, companySlug) {
|
|
500
503
|
return [
|
|
501
504
|
currentDeviceSignInAction(status),
|
|
502
|
-
pendingSlackAction(status),
|
|
505
|
+
pendingSlackAction(status, companySlug),
|
|
503
506
|
].filter((action) => action !== null);
|
|
504
507
|
}
|
|
508
|
+
async function consoleCompanySlug(token, status, companyRef) {
|
|
509
|
+
if (companyRef && /^[a-z0-9][a-z0-9-]*$/.test(companyRef))
|
|
510
|
+
return companyRef;
|
|
511
|
+
const agent = recordValue(status.agent);
|
|
512
|
+
const slack = recordValue(recordValue(agent?.channels)?.slack);
|
|
513
|
+
if (!slack?.appTokenPendingUrl)
|
|
514
|
+
return undefined;
|
|
515
|
+
const companyUid = nonEmptyString(agent?.companyUid);
|
|
516
|
+
if (!companyUid)
|
|
517
|
+
return undefined;
|
|
518
|
+
try {
|
|
519
|
+
const response = await vaultApiFetch({
|
|
520
|
+
token,
|
|
521
|
+
path: "/membership/me",
|
|
522
|
+
signal: AbortSignal.timeout(10_000),
|
|
523
|
+
});
|
|
524
|
+
if (!response.ok)
|
|
525
|
+
return undefined;
|
|
526
|
+
const body = recordValue(await response.json());
|
|
527
|
+
const memberships = Array.isArray(body?.memberships) ? body.memberships : [];
|
|
528
|
+
const membership = memberships.map(recordValue).find((item) => item?.companyUid === companyUid && item?.status === "active");
|
|
529
|
+
const slug = nonEmptyString(membership?.companySlug);
|
|
530
|
+
return slug && /^[a-z0-9][a-z0-9-]*$/.test(slug) ? slug : undefined;
|
|
531
|
+
}
|
|
532
|
+
catch {
|
|
533
|
+
return undefined;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
505
536
|
function pendingActionsJson(actions) {
|
|
506
537
|
return actions.map(({ type, title, instruction, url, pasteUrl, code }) => ({
|
|
507
538
|
type,
|
|
@@ -1190,7 +1221,9 @@ export function registerAgentsCommand(program) {
|
|
|
1190
1221
|
const status = identity
|
|
1191
1222
|
? await getAgentStatus(token, identity.uid)
|
|
1192
1223
|
: null;
|
|
1193
|
-
const actions = status
|
|
1224
|
+
const actions = status
|
|
1225
|
+
? pendingOperatorActions(status, await consoleCompanySlug(token, status, companyOf(this)))
|
|
1226
|
+
: [];
|
|
1194
1227
|
const slackInstall = actions.find((action) => action.type === "slack-install");
|
|
1195
1228
|
if (opts.json) {
|
|
1196
1229
|
console.log(JSON.stringify({
|
|
@@ -1311,7 +1344,7 @@ export function registerAgentsCommand(program) {
|
|
|
1311
1344
|
const token = (await resolveVaultCredential()).token;
|
|
1312
1345
|
const agentUid = await resolveAgentUid(token, agent, companyOf(this));
|
|
1313
1346
|
const status = await getAgentStatus(token, agentUid);
|
|
1314
|
-
const actions = pendingOperatorActions(status);
|
|
1347
|
+
const actions = pendingOperatorActions(status, await consoleCompanySlug(token, status, companyOf(this)));
|
|
1315
1348
|
if (opts.json) {
|
|
1316
1349
|
process.stdout.write(JSON.stringify({
|
|
1317
1350
|
...status,
|