@indigoai-us/hq-cli 5.266.0 → 5.267.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 +10 -0
- package/dist/lib/billing/plan-limit-upgrade-url.d.ts +3 -2
- package/dist/lib/billing/plan-limit-upgrade-url.js +50 -11
- package/dist/lib/bot/inbox-poll-backoff-flag.d.ts +1 -1
- package/dist/lib/bot/inbox-poll-backoff-flag.js +4 -1
- package/dist/utils/plan-gate-error.js +9 -6
- package/dist/utils/team-upgrade.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.267.0] — 2026-09-28
|
|
6
|
+
|
|
7
|
+
- Company billing links opened by CLI plan-limit flows now carry cli_limit attribution into checkout telemetry.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Local bots now read the idle inbox backoff flag with a 2 s budget. The
|
|
12
|
+
150 ms budget timed out from home networks, so bots kept polling every 2 s
|
|
13
|
+
even when the flag was on for them.
|
|
14
|
+
|
|
5
15
|
## [5.266.0] — 2026-09-28
|
|
6
16
|
|
|
7
17
|
### Added
|
|
@@ -6,8 +6,9 @@ export interface PlanLimitUpgradeUrlChoices {
|
|
|
6
6
|
legacyUrl: string;
|
|
7
7
|
}
|
|
8
8
|
export declare function isPlanLimitUpgradeFallbackEnabled(): boolean;
|
|
9
|
-
/** Resolve
|
|
9
|
+
/** Resolve and attribute the final selected company billing destination. */
|
|
10
10
|
export declare function selectPlanLimitUpgradeUrl(companySlug: string | undefined, choices: PlanLimitUpgradeUrlChoices): string;
|
|
11
|
-
|
|
11
|
+
export declare function withCliLimitEntrySurface(value: string): string;
|
|
12
|
+
/** Keep the existing destination and flag behavior while labeling company limit links. */
|
|
12
13
|
export declare function planLimitUpgradeFallbackUrl(companySlug: string | undefined, previousFallbackUrl: string): string;
|
|
13
14
|
//# sourceMappingURL=plan-limit-upgrade-url.d.ts.map
|
|
@@ -13,23 +13,62 @@ function companyBillingUrl(companySlug) {
|
|
|
13
13
|
return null;
|
|
14
14
|
const slug = companySlug?.trim();
|
|
15
15
|
const route = slug
|
|
16
|
-
? `/companies/${encodeURIComponent(slug)}/billing?upgrade=1`
|
|
16
|
+
? `/companies/${encodeURIComponent(slug)}/billing?upgrade=1&entrySurface=cli_limit`
|
|
17
17
|
: "/billing";
|
|
18
18
|
return `${origin}${route}`;
|
|
19
19
|
}
|
|
20
|
-
/** Resolve
|
|
20
|
+
/** Resolve and attribute the final selected company billing destination. */
|
|
21
21
|
export function selectPlanLimitUpgradeUrl(companySlug, choices) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const nestedUrl = choices.nestedUrl?.trim() || undefined;
|
|
26
|
-
const generatedUrl = companyBillingUrl(companySlug);
|
|
27
|
-
if (companySlug?.trim()) {
|
|
28
|
-
return generatedUrl ?? topLevelUrl ?? nestedUrl ?? choices.legacyUrl;
|
|
22
|
+
let selected;
|
|
23
|
+
if (!isPlanLimitUpgradeFallbackEnabled()) {
|
|
24
|
+
selected = choices.legacyUrl;
|
|
29
25
|
}
|
|
30
|
-
|
|
26
|
+
else {
|
|
27
|
+
const topLevelUrl = choices.topLevelUrl?.trim() || undefined;
|
|
28
|
+
const nestedUrl = choices.nestedUrl?.trim() || undefined;
|
|
29
|
+
const generatedUrl = companyBillingUrl(companySlug);
|
|
30
|
+
if (companySlug?.trim()) {
|
|
31
|
+
selected = generatedUrl ?? topLevelUrl ?? nestedUrl ?? choices.legacyUrl;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
selected = topLevelUrl ?? nestedUrl ?? generatedUrl ?? choices.legacyUrl;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return withCliLimitEntrySurface(selected);
|
|
38
|
+
}
|
|
39
|
+
export function withCliLimitEntrySurface(value) {
|
|
40
|
+
try {
|
|
41
|
+
const url = new URL(value);
|
|
42
|
+
if (url.protocol !== "https:" || url.username || url.password)
|
|
43
|
+
return value;
|
|
44
|
+
const callbackUrl = url.searchParams.get("callbackUrl");
|
|
45
|
+
if (callbackUrl) {
|
|
46
|
+
const callback = new URL(callbackUrl, url.origin);
|
|
47
|
+
const parts = callback.pathname.split("/").filter(Boolean);
|
|
48
|
+
if (parts.length === 5 && parts[0] === "api" && parts[1] === "companies" &&
|
|
49
|
+
/^cmp_[A-Za-z0-9_-]+$/.test(parts[2]) && parts[3] === "billing" && parts[4] === "upgrade") {
|
|
50
|
+
callback.searchParams.set("entrySurface", "cli_limit");
|
|
51
|
+
const serializedCallback = /^[a-z][a-z0-9+.-]*:/i.test(callbackUrl)
|
|
52
|
+
? callback.toString()
|
|
53
|
+
: callbackUrl.startsWith("//")
|
|
54
|
+
? `//${callback.host}${callback.pathname}${callback.search}${callback.hash}`
|
|
55
|
+
: `${callback.pathname}${callback.search}${callback.hash}`;
|
|
56
|
+
url.searchParams.set("callbackUrl", serializedCallback);
|
|
57
|
+
return url.toString();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
61
|
+
if (parts.length === 3 && parts[0] === "companies" && parts[2] === "billing") {
|
|
62
|
+
url.searchParams.set("entrySurface", "cli_limit");
|
|
63
|
+
return url.toString();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
31
70
|
}
|
|
32
|
-
/** Keep
|
|
71
|
+
/** Keep the existing destination and flag behavior while labeling company limit links. */
|
|
33
72
|
export function planLimitUpgradeFallbackUrl(companySlug, previousFallbackUrl) {
|
|
34
73
|
return selectPlanLimitUpgradeUrl(companySlug, {
|
|
35
74
|
legacyUrl: previousFallbackUrl,
|
|
@@ -2,7 +2,7 @@ import { type FlagClient, type FlagClientOptions } from "@indigoai-us/hq-flags-c
|
|
|
2
2
|
import { type BotConfig } from "./config.js";
|
|
3
3
|
export declare const INBOX_POLL_BACKOFF_FLAG = "agents.inbox-poll-backoff-local-cli";
|
|
4
4
|
export declare const INBOX_POLL_BACKOFF_FLAG_FALLBACK = false;
|
|
5
|
-
export declare const INBOX_POLL_BACKOFF_FLAG_TIMEOUT_MS =
|
|
5
|
+
export declare const INBOX_POLL_BACKOFF_FLAG_TIMEOUT_MS = 2000;
|
|
6
6
|
export declare const INBOX_POLL_BACKOFF_FLAG_CACHE_MS: number;
|
|
7
7
|
type InboxPollBackoffFlagClient = Pick<FlagClient, "ready" | "isEnabled" | "close">;
|
|
8
8
|
export interface InboxPollBackoffFlagReaderDependencies {
|
|
@@ -5,7 +5,10 @@ import { resolveFlagRegistryEndpoint } from "../flag-registry-endpoint.js";
|
|
|
5
5
|
import { effectiveBotCompanies, effectiveBotKind } from "./config.js";
|
|
6
6
|
export const INBOX_POLL_BACKOFF_FLAG = "agents.inbox-poll-backoff-local-cli";
|
|
7
7
|
export const INBOX_POLL_BACKOFF_FLAG_FALLBACK = false;
|
|
8
|
-
|
|
8
|
+
// One read every three minutes on a fresh connection. From a home network the
|
|
9
|
+
// TCP and TLS handshakes plus the resolve call take about 250-400 ms, so a
|
|
10
|
+
// 150 ms budget timed out on every read and kept the gate off.
|
|
11
|
+
export const INBOX_POLL_BACKOFF_FLAG_TIMEOUT_MS = 2_000;
|
|
9
12
|
export const INBOX_POLL_BACKOFF_FLAG_CACHE_MS = 3 * 60_000;
|
|
10
13
|
const COMPANY_UID_RE = /^cmp_[A-Za-z0-9]{3,128}$/;
|
|
11
14
|
export function safeErrorClass(error) {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* message instead of every command parsing and printing a server response.
|
|
5
5
|
*/
|
|
6
6
|
import { renderPersonalPlanFeatureNotice } from "../lib/plan-limit-nag.js";
|
|
7
|
+
import { withCliLimitEntrySurface } from "../lib/billing/plan-limit-upgrade-url.js";
|
|
7
8
|
function planGateReason(code, details) {
|
|
8
9
|
if (details.reason?.trim())
|
|
9
10
|
return details.reason.trim();
|
|
@@ -27,11 +28,12 @@ function planGateReason(code, details) {
|
|
|
27
28
|
/** One renderer for server-selected upgrade links across CLI plan refusals. */
|
|
28
29
|
export function formatUpgradeRefusal(reason, upgradeUrl, options = {}) {
|
|
29
30
|
const safeUrl = safeUpgradeUrl(upgradeUrl);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const cliLimitUrl = safeUrl ? withCliLimitEntrySurface(safeUrl) : undefined;
|
|
32
|
+
if (options.urlOnly && cliLimitUrl)
|
|
33
|
+
return cliLimitUrl;
|
|
34
|
+
if (!cliLimitUrl)
|
|
33
35
|
return reason;
|
|
34
|
-
return `${reason}\nUpgrade: ${
|
|
36
|
+
return `${reason}\nUpgrade: ${cliLimitUrl}`;
|
|
35
37
|
}
|
|
36
38
|
function safeUpgradeUrl(value) {
|
|
37
39
|
if (typeof value !== "string" ||
|
|
@@ -94,6 +96,7 @@ export async function offerUpgradeLink(url, deps = {}) {
|
|
|
94
96
|
const safeUrl = safeUpgradeUrl(url);
|
|
95
97
|
if (!safeUrl)
|
|
96
98
|
return false;
|
|
99
|
+
const cliLimitUrl = withCliLimitEntrySurface(safeUrl);
|
|
97
100
|
if (!(deps.interactive ?? canOfferTeamUpgrade(deps.argv)))
|
|
98
101
|
return false;
|
|
99
102
|
let answer;
|
|
@@ -113,11 +116,11 @@ export async function offerUpgradeLink(url, deps = {}) {
|
|
|
113
116
|
if (!/^y(?:es)?$/i.test(answer.trim()))
|
|
114
117
|
return false;
|
|
115
118
|
if (deps.openUrl) {
|
|
116
|
-
await deps.openUrl(
|
|
119
|
+
await deps.openUrl(cliLimitUrl);
|
|
117
120
|
}
|
|
118
121
|
else {
|
|
119
122
|
const { default: open } = await import("open");
|
|
120
|
-
await open(
|
|
123
|
+
await open(cliLimitUrl);
|
|
121
124
|
}
|
|
122
125
|
return true;
|
|
123
126
|
}
|