@oxygen-agent/cli 1.377.3 → 1.575.19
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/README.md +1 -1
- package/dist/column-run-notices.d.ts +11 -0
- package/dist/column-run-notices.js +37 -0
- package/dist/command-manifest.js +13 -8
- package/dist/help.js +78 -16
- package/dist/index.js +3450 -447
- package/dist/skills.js +106 -1
- package/node_modules/@oxygen/formula/dist/coerce.d.ts +8 -0
- package/node_modules/@oxygen/formula/dist/coerce.js +10 -0
- package/node_modules/@oxygen/formula/dist/evaluate.d.ts +31 -0
- package/node_modules/@oxygen/formula/dist/evaluate.js +248 -0
- package/node_modules/@oxygen/formula/dist/expression.d.ts +64 -0
- package/node_modules/@oxygen/formula/dist/expression.js +428 -0
- package/node_modules/@oxygen/formula/dist/formula-functions.d.ts +71 -0
- package/node_modules/@oxygen/formula/dist/formula-functions.js +1100 -0
- package/node_modules/@oxygen/formula/dist/index.d.ts +17 -0
- package/node_modules/@oxygen/formula/dist/index.js +17 -0
- package/node_modules/@oxygen/formula/dist/value-normalizers.d.ts +30 -0
- package/node_modules/@oxygen/formula/dist/value-normalizers.js +80 -0
- package/node_modules/@oxygen/formula/package.json +26 -0
- package/node_modules/@oxygen/recipe-sdk/dist/index.d.ts +30 -0
- package/node_modules/@oxygen/recipe-sdk/dist/index.js +2 -2
- package/node_modules/@oxygen/shared/dist/billing-anchors.d.ts +60 -0
- package/node_modules/@oxygen/shared/dist/billing-anchors.js +135 -0
- package/node_modules/@oxygen/shared/dist/billing.d.ts +99 -5
- package/node_modules/@oxygen/shared/dist/billing.js +185 -8
- package/node_modules/@oxygen/shared/dist/call-outcomes.d.ts +59 -0
- package/node_modules/@oxygen/shared/dist/call-outcomes.js +73 -0
- package/node_modules/@oxygen/shared/dist/cli-result.js +1 -0
- package/node_modules/@oxygen/shared/dist/credit-guidance.js +3 -1
- package/node_modules/@oxygen/shared/dist/crm-reply-events.d.ts +35 -0
- package/node_modules/@oxygen/shared/dist/crm-reply-events.js +31 -0
- package/node_modules/@oxygen/shared/dist/dial-guardrail-overrides.d.ts +50 -0
- package/node_modules/@oxygen/shared/dist/dial-guardrail-overrides.js +65 -0
- package/node_modules/@oxygen/shared/dist/directory.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/directory.js +1 -0
- package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +15 -0
- package/node_modules/@oxygen/shared/dist/hosted-ai.js +19 -0
- package/node_modules/@oxygen/shared/dist/index.d.ts +9 -0
- package/node_modules/@oxygen/shared/dist/index.js +9 -0
- package/node_modules/@oxygen/shared/dist/linkedin-quota-denial.d.ts +31 -0
- package/node_modules/@oxygen/shared/dist/linkedin-quota-denial.js +56 -0
- package/node_modules/@oxygen/shared/dist/linkedin-sequences.d.ts +5 -4
- package/node_modules/@oxygen/shared/dist/linkedin-sequences.js +5 -4
- package/node_modules/@oxygen/shared/dist/linkedin-url.d.ts +22 -0
- package/node_modules/@oxygen/shared/dist/linkedin-url.js +7 -4
- package/node_modules/@oxygen/shared/dist/log.js +41 -2
- package/node_modules/@oxygen/shared/dist/microsoft-consent-url.d.ts +7 -0
- package/node_modules/@oxygen/shared/dist/microsoft-consent-url.js +29 -0
- package/node_modules/@oxygen/shared/dist/object-storage.d.ts +31 -0
- package/node_modules/@oxygen/shared/dist/object-storage.js +61 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +636 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.js +199 -0
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +89 -23
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +88 -24
- package/node_modules/@oxygen/shared/dist/sequence-crm-events.d.ts +291 -0
- package/node_modules/@oxygen/shared/dist/sequence-crm-events.js +224 -0
- package/node_modules/@oxygen/shared/dist/sequence-template.d.ts +42 -1
- package/node_modules/@oxygen/shared/dist/sequence-template.js +0 -0
- package/node_modules/@oxygen/shared/dist/sequences.d.ts +287 -24
- package/node_modules/@oxygen/shared/dist/sequences.js +940 -60
- package/node_modules/@oxygen/shared/dist/spend-safety.d.ts +70 -0
- package/node_modules/@oxygen/shared/dist/spend-safety.js +106 -0
- package/node_modules/@oxygen/shared/dist/tags.d.ts +90 -1
- package/node_modules/@oxygen/shared/dist/tags.js +122 -6
- package/node_modules/@oxygen/shared/dist/version.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.js +1 -1
- package/node_modules/@oxygen/shared/dist/workflow-trigger-metadata.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/workflow-trigger-metadata.js +4 -0
- package/node_modules/@oxygen/shared/package.json +95 -0
- package/node_modules/@oxygen/workflows/dist/event-dispatch.d.ts +126 -0
- package/node_modules/@oxygen/workflows/dist/event-dispatch.js +173 -0
- package/node_modules/@oxygen/workflows/dist/graph/expression.d.ts +78 -0
- package/node_modules/@oxygen/workflows/dist/graph/expression.js +700 -0
- package/node_modules/@oxygen/workflows/dist/graph/index.d.ts +20 -0
- package/node_modules/@oxygen/workflows/dist/graph/index.js +20 -0
- package/node_modules/@oxygen/workflows/dist/graph/lint.d.ts +4 -0
- package/node_modules/@oxygen/workflows/dist/graph/lint.js +812 -0
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.d.ts +501 -0
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.js +200 -0
- package/node_modules/@oxygen/workflows/dist/graph/params.d.ts +86 -0
- package/node_modules/@oxygen/workflows/dist/graph/params.js +173 -0
- package/node_modules/@oxygen/workflows/dist/graph/remap.d.ts +48 -0
- package/node_modules/@oxygen/workflows/dist/graph/remap.js +213 -0
- package/node_modules/@oxygen/workflows/dist/graph/topology.d.ts +46 -0
- package/node_modules/@oxygen/workflows/dist/graph/topology.js +280 -0
- package/node_modules/@oxygen/workflows/dist/graph/types.d.ts +270 -0
- package/node_modules/@oxygen/workflows/dist/graph/types.js +93 -0
- package/node_modules/@oxygen/workflows/dist/index.d.ts +113 -1
- package/node_modules/@oxygen/workflows/dist/index.js +179 -13
- package/node_modules/@oxygen/workflows/dist/tool-effects.d.ts +1 -0
- package/node_modules/@oxygen/workflows/dist/tool-effects.js +19 -0
- package/node_modules/@oxygen/workflows/dist/usage-estimate.js +135 -4
- package/node_modules/@oxygen/workflows/package.json +4 -0
- package/package.json +7 -5
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { PlanTier } from "./billing.js";
|
|
2
|
+
import type { LimitsTier } from "./plan-limits.js";
|
|
3
|
+
/**
|
|
4
|
+
* Spend-safety defaults: plan-scaled ceilings applied when an autonomous
|
|
5
|
+
* spend path was armed WITHOUT an explicit cap. They restore the ADR-0011
|
|
6
|
+
* doctrine that every cron/webhook/event trigger persists a per-delivery
|
|
7
|
+
* ceiling — absence of a cap is no longer unbounded. Explicit user caps always
|
|
8
|
+
* win and are never clamped down; `null` means no default applies (enterprise
|
|
9
|
+
* runs on custom limits; free has no BYOK).
|
|
10
|
+
*
|
|
11
|
+
* Values anchor to ≥ one day-equivalent of the plan's monthly credits
|
|
12
|
+
* (monthlyCredits / 30), orders of magnitude above typical per-delivery spend,
|
|
13
|
+
* so the ceiling binds on runaway loops, not legitimate heavy runs.
|
|
14
|
+
*/
|
|
15
|
+
/** Where an effective cap came from: caller-declared or a plan-tier default. */
|
|
16
|
+
export type EffectiveCapSource = "explicit" | "trigger_default";
|
|
17
|
+
/** Workflow run trigger types that fire without a human in the loop. */
|
|
18
|
+
export declare const AUTONOMOUS_WORKFLOW_TRIGGER_TYPES: ReadonlySet<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Per-run managed-credit ceiling for a LIVE workflow run fired by an autonomous
|
|
21
|
+
* trigger when neither run metadata nor the manifest declares `max_credits`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const DEFAULT_TRIGGER_RUN_CREDIT_CEILING: Record<PlanTier, number | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Per-delivery credit ceiling stamped onto a standing/webhook table auto-run
|
|
26
|
+
* batch when the armed configuration carries no explicit `max_credits`.
|
|
27
|
+
*/
|
|
28
|
+
export declare const DEFAULT_AUTO_RUN_BATCH_CREDIT_CEILING: Record<PlanTier, number | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Row ceiling for a BYOK AI-column run whose caller gave no explicit row bound
|
|
31
|
+
* (no limit, no row_ids, selection "all"). BYOK bills the customer's own
|
|
32
|
+
* provider account, so a credit ceiling is meaningless — row count is the
|
|
33
|
+
* enforceable unit. An explicit limit (up to the 500k platform row cap) wins.
|
|
34
|
+
*/
|
|
35
|
+
export declare const DEFAULT_BYOK_COLUMN_RUN_MAX_ROWS: Record<PlanTier, number | null>;
|
|
36
|
+
/**
|
|
37
|
+
* Default per-provider DAILY call cap for BYOK provider traffic (the customer's
|
|
38
|
+
* own key). Short-window pacing defaults already exist in provider-fetch; this
|
|
39
|
+
* bounds daily volume. Warn-first: enforcement flips only after telemetry and
|
|
40
|
+
* with the self-serve override surface live. A workspace
|
|
41
|
+
* provider_rate_limit_policies row with windowSeconds=86400 overrides it.
|
|
42
|
+
*/
|
|
43
|
+
export declare const DEFAULT_BYOK_PROVIDER_DAILY_CALL_CAP: Record<PlanTier, number | null>;
|
|
44
|
+
export declare const BYOK_PROVIDER_DAILY_WINDOW_SECONDS: number;
|
|
45
|
+
/**
|
|
46
|
+
* Implicit org-level DAILY budget guard, evaluated only when the org has no
|
|
47
|
+
* explicit org-scope daily budget policy and the plan has finite positive
|
|
48
|
+
* monthly credits. Warn when one rolling day spends past WARN_PCT of the
|
|
49
|
+
* monthly grant; hard-block at BLOCK_PCT (a loop burning a whole month in a
|
|
50
|
+
* day is near-certainly runaway — this also protects large top-up balances).
|
|
51
|
+
* Setting any explicit org-daily policy fully suppresses the implicit pair.
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_ORG_DAILY_SPEND_WARN_PCT = 0.25;
|
|
54
|
+
export declare const DEFAULT_ORG_DAILY_SPEND_BLOCK_PCT = 1;
|
|
55
|
+
export declare function resolveDefaultTriggerRunCreditCeiling(tier: PlanTier): number | null;
|
|
56
|
+
export declare function resolveDefaultAutoRunBatchCreditCeiling(tier: PlanTier): number | null;
|
|
57
|
+
export declare function resolveDefaultByokColumnRunMaxRows(tier: PlanTier): number | null;
|
|
58
|
+
export declare function resolveDefaultByokProviderDailyCallCap(tier: PlanTier): number | null;
|
|
59
|
+
/**
|
|
60
|
+
* The plan tiers the spend-safety default tables above are keyed by. `limitsTier`
|
|
61
|
+
* collapses "enterprise" onto the "scale" enforcement rung, but these tables carry
|
|
62
|
+
* a distinct "enterprise" column (null = runs on custom limits) — so prefer the
|
|
63
|
+
* raw plan_tier whenever it is itself a table key, and fall back to the limits rung
|
|
64
|
+
* (always a valid PlanTier key) when plan_tier is absent or an unknown/legacy
|
|
65
|
+
* string (e.g. a Stripe price nickname). Single source of truth for the
|
|
66
|
+
* `oxygen limits` report, the org-facing provider-limits API, and the BYOK
|
|
67
|
+
* daily-cap enforcement resolver — they must agree on which column an org reads.
|
|
68
|
+
*/
|
|
69
|
+
export declare const SPEND_SAFETY_PLAN_TIERS: readonly PlanTier[];
|
|
70
|
+
export declare function resolveSpendSafetyPlanTier(planTier: string | null, limitsTier: LimitsTier): PlanTier;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** Workflow run trigger types that fire without a human in the loop. */
|
|
2
|
+
export const AUTONOMOUS_WORKFLOW_TRIGGER_TYPES = new Set([
|
|
3
|
+
"cron",
|
|
4
|
+
"webhook",
|
|
5
|
+
"event",
|
|
6
|
+
]);
|
|
7
|
+
/**
|
|
8
|
+
* Per-run managed-credit ceiling for a LIVE workflow run fired by an autonomous
|
|
9
|
+
* trigger when neither run metadata nor the manifest declares `max_credits`.
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_TRIGGER_RUN_CREDIT_CEILING = {
|
|
12
|
+
free: 500,
|
|
13
|
+
starter: 5_000,
|
|
14
|
+
pro: 10_000,
|
|
15
|
+
team: 25_000,
|
|
16
|
+
scale: 250_000,
|
|
17
|
+
enterprise: null,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Per-delivery credit ceiling stamped onto a standing/webhook table auto-run
|
|
21
|
+
* batch when the armed configuration carries no explicit `max_credits`.
|
|
22
|
+
*/
|
|
23
|
+
export const DEFAULT_AUTO_RUN_BATCH_CREDIT_CEILING = {
|
|
24
|
+
free: 500,
|
|
25
|
+
starter: 5_000,
|
|
26
|
+
pro: 10_000,
|
|
27
|
+
team: 25_000,
|
|
28
|
+
scale: 250_000,
|
|
29
|
+
enterprise: null,
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Row ceiling for a BYOK AI-column run whose caller gave no explicit row bound
|
|
33
|
+
* (no limit, no row_ids, selection "all"). BYOK bills the customer's own
|
|
34
|
+
* provider account, so a credit ceiling is meaningless — row count is the
|
|
35
|
+
* enforceable unit. An explicit limit (up to the 500k platform row cap) wins.
|
|
36
|
+
*/
|
|
37
|
+
export const DEFAULT_BYOK_COLUMN_RUN_MAX_ROWS = {
|
|
38
|
+
free: null,
|
|
39
|
+
starter: 25_000,
|
|
40
|
+
pro: 50_000,
|
|
41
|
+
team: 100_000,
|
|
42
|
+
scale: 250_000,
|
|
43
|
+
enterprise: null,
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Default per-provider DAILY call cap for BYOK provider traffic (the customer's
|
|
47
|
+
* own key). Short-window pacing defaults already exist in provider-fetch; this
|
|
48
|
+
* bounds daily volume. Warn-first: enforcement flips only after telemetry and
|
|
49
|
+
* with the self-serve override surface live. A workspace
|
|
50
|
+
* provider_rate_limit_policies row with windowSeconds=86400 overrides it.
|
|
51
|
+
*/
|
|
52
|
+
export const DEFAULT_BYOK_PROVIDER_DAILY_CALL_CAP = {
|
|
53
|
+
free: null,
|
|
54
|
+
starter: 10_000,
|
|
55
|
+
pro: 25_000,
|
|
56
|
+
team: 50_000,
|
|
57
|
+
scale: 200_000,
|
|
58
|
+
enterprise: null,
|
|
59
|
+
};
|
|
60
|
+
export const BYOK_PROVIDER_DAILY_WINDOW_SECONDS = 24 * 60 * 60;
|
|
61
|
+
/**
|
|
62
|
+
* Implicit org-level DAILY budget guard, evaluated only when the org has no
|
|
63
|
+
* explicit org-scope daily budget policy and the plan has finite positive
|
|
64
|
+
* monthly credits. Warn when one rolling day spends past WARN_PCT of the
|
|
65
|
+
* monthly grant; hard-block at BLOCK_PCT (a loop burning a whole month in a
|
|
66
|
+
* day is near-certainly runaway — this also protects large top-up balances).
|
|
67
|
+
* Setting any explicit org-daily policy fully suppresses the implicit pair.
|
|
68
|
+
*/
|
|
69
|
+
export const DEFAULT_ORG_DAILY_SPEND_WARN_PCT = 0.25;
|
|
70
|
+
export const DEFAULT_ORG_DAILY_SPEND_BLOCK_PCT = 1;
|
|
71
|
+
export function resolveDefaultTriggerRunCreditCeiling(tier) {
|
|
72
|
+
return DEFAULT_TRIGGER_RUN_CREDIT_CEILING[tier];
|
|
73
|
+
}
|
|
74
|
+
export function resolveDefaultAutoRunBatchCreditCeiling(tier) {
|
|
75
|
+
return DEFAULT_AUTO_RUN_BATCH_CREDIT_CEILING[tier];
|
|
76
|
+
}
|
|
77
|
+
export function resolveDefaultByokColumnRunMaxRows(tier) {
|
|
78
|
+
return DEFAULT_BYOK_COLUMN_RUN_MAX_ROWS[tier];
|
|
79
|
+
}
|
|
80
|
+
export function resolveDefaultByokProviderDailyCallCap(tier) {
|
|
81
|
+
return DEFAULT_BYOK_PROVIDER_DAILY_CALL_CAP[tier];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The plan tiers the spend-safety default tables above are keyed by. `limitsTier`
|
|
85
|
+
* collapses "enterprise" onto the "scale" enforcement rung, but these tables carry
|
|
86
|
+
* a distinct "enterprise" column (null = runs on custom limits) — so prefer the
|
|
87
|
+
* raw plan_tier whenever it is itself a table key, and fall back to the limits rung
|
|
88
|
+
* (always a valid PlanTier key) when plan_tier is absent or an unknown/legacy
|
|
89
|
+
* string (e.g. a Stripe price nickname). Single source of truth for the
|
|
90
|
+
* `oxygen limits` report, the org-facing provider-limits API, and the BYOK
|
|
91
|
+
* daily-cap enforcement resolver — they must agree on which column an org reads.
|
|
92
|
+
*/
|
|
93
|
+
export const SPEND_SAFETY_PLAN_TIERS = [
|
|
94
|
+
"free",
|
|
95
|
+
"starter",
|
|
96
|
+
"pro",
|
|
97
|
+
"team",
|
|
98
|
+
"scale",
|
|
99
|
+
"enterprise",
|
|
100
|
+
];
|
|
101
|
+
export function resolveSpendSafetyPlanTier(planTier, limitsTier) {
|
|
102
|
+
if (planTier && SPEND_SAFETY_PLAN_TIERS.includes(planTier)) {
|
|
103
|
+
return planTier;
|
|
104
|
+
}
|
|
105
|
+
return limitsTier;
|
|
106
|
+
}
|
|
@@ -1,7 +1,45 @@
|
|
|
1
|
+
import type { TagColor } from "./select-options.js";
|
|
1
2
|
/** Primitive kinds that participate in the workspace tag union today. */
|
|
2
|
-
export declare const TAG_KINDS: readonly ["knowledge_page", "publishing_post", "sequence", "table", "workflow", "recipe", "conversation", "mailbox", "sender", "record"];
|
|
3
|
+
export declare const TAG_KINDS: readonly ["knowledge_page", "publishing_post", "sequence", "table", "workflow", "recipe", "conversation", "mailbox", "sender", "record", "domain", "project", "engagement_watch"];
|
|
3
4
|
export type TagKind = (typeof TAG_KINDS)[number];
|
|
5
|
+
/**
|
|
6
|
+
* The taggable kinds in prose, for CLI `--help` and MCP tool descriptions.
|
|
7
|
+
*
|
|
8
|
+
* Lives next to {@link TAG_KINDS} because those descriptions are the *discovery*
|
|
9
|
+
* surface: a blind-user eval (2026-07-21) found the tags help still advertising
|
|
10
|
+
* the original seven kinds, so a user reading `tags --help` had no way to learn
|
|
11
|
+
* that domains, projects, or engagement watches were taggable at all — they had
|
|
12
|
+
* to stumble on each owning group's own help. One string, one import, and
|
|
13
|
+
* `TAG_KIND_PROSE_MARKERS` fails the build/test if a new kind skips it.
|
|
14
|
+
*/
|
|
15
|
+
export declare const TAG_KINDS_PROSE: string;
|
|
16
|
+
/**
|
|
17
|
+
* The phrase each kind must contribute to {@link TAG_KINDS_PROSE}. Typed as a
|
|
18
|
+
* total map over TagKind, so adding a kind is a compile error until it is named
|
|
19
|
+
* here, and the paired test asserts the phrase actually appears in the prose.
|
|
20
|
+
*/
|
|
21
|
+
export declare const TAG_KIND_PROSE_MARKERS: Record<TagKind, string>;
|
|
4
22
|
export declare function isTagKind(value: unknown): value is TagKind;
|
|
23
|
+
/**
|
|
24
|
+
* How each kind is named when a tag's footprint is listed. Total over TagKind,
|
|
25
|
+
* so adding a kind is a compile error until it is labelled — the same guarantee
|
|
26
|
+
* {@link TAG_KIND_PROSE_MARKERS} gives the help text.
|
|
27
|
+
*
|
|
28
|
+
* `many` is sentence-form with proper nouns preserved ("CRM records"), which is
|
|
29
|
+
* what an inline count wants ("3 CRM records"). Headings run it through
|
|
30
|
+
* {@link tagKindHeading}, which only uppercases a leading lowercase letter, so
|
|
31
|
+
* "CRM records" survives intact where a naive capitalize would yield "Crm".
|
|
32
|
+
* Three hand-maintained copies of this map used to drift (the /tags page said
|
|
33
|
+
* "knowledge", the detail page and the MCP widget said "Knowledge pages").
|
|
34
|
+
*/
|
|
35
|
+
export declare const TAG_KIND_LABELS: Record<TagKind, {
|
|
36
|
+
one: string;
|
|
37
|
+
many: string;
|
|
38
|
+
}>;
|
|
39
|
+
/** Inline label for a count: `tagKindLabel("sequence", 1)` → "sequence". */
|
|
40
|
+
export declare function tagKindLabel(kind: string, count: number): string;
|
|
41
|
+
/** Section heading for a kind: "Knowledge pages", "CRM records". */
|
|
42
|
+
export declare function tagKindHeading(kind: string): string;
|
|
5
43
|
/** Hard cap per tagged item — matches the wiki's long-standing limit. */
|
|
6
44
|
export declare const MAX_TAGS_PER_ITEM = 50;
|
|
7
45
|
/**
|
|
@@ -12,3 +50,54 @@ export declare const MAX_TAGS_PER_ITEM = 50;
|
|
|
12
50
|
export declare function normalizeTagList(values: readonly unknown[]): string[];
|
|
13
51
|
/** Lenient variant: `undefined`/`null`/non-arrays normalize to `[]`. */
|
|
14
52
|
export declare function normalizeTags(value: unknown): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Registry-only caps (ADR 0017). Deliberately NOT enforced by
|
|
55
|
+
* {@link normalizeTagList}: that runs on every writer's hot path, so adding a
|
|
56
|
+
* length filter there would silently drop an existing long tag the next time
|
|
57
|
+
* any row carrying it was rewritten. A longer tag stays legal to carry — it
|
|
58
|
+
* just cannot be declared.
|
|
59
|
+
*/
|
|
60
|
+
export declare const MAX_TAG_LABEL_LENGTH = 200;
|
|
61
|
+
export declare const MAX_TAG_DESCRIPTION_LENGTH = 500;
|
|
62
|
+
/**
|
|
63
|
+
* Normalize ONE label the way {@link normalizeTagList} normalizes each element,
|
|
64
|
+
* and reject what the registry cannot store: non-strings, blanks, and anything
|
|
65
|
+
* over {@link MAX_TAG_LABEL_LENGTH}. Returns `null` so callers can raise their
|
|
66
|
+
* own typed error.
|
|
67
|
+
*
|
|
68
|
+
* Note this lowercases and trims but does NOT slugify — "Q3 Outbound" becomes
|
|
69
|
+
* "q3 outbound", space intact. Any character is legal in a tag.
|
|
70
|
+
*/
|
|
71
|
+
export declare function normalizeTagLabel(value: unknown): string | null;
|
|
72
|
+
/**
|
|
73
|
+
* One tag as every read surface sees it: carrier counts unioned across stores,
|
|
74
|
+
* plus the registry annotation when the tag is declared.
|
|
75
|
+
*
|
|
76
|
+
* Canonical here rather than in the web app because two consumers used to
|
|
77
|
+
* declare it independently (`WorkspaceTagIndexEntry` server-side and
|
|
78
|
+
* `WorkspaceTagVocabularyEntry` in the TagPicker). Extra properties are
|
|
79
|
+
* structurally compatible in TypeScript, so widening one and not the other
|
|
80
|
+
* compiled silently and the picker simply never saw the new fields.
|
|
81
|
+
*
|
|
82
|
+
* `color` is the explicit OVERRIDE or null — never the derived color. Resolving
|
|
83
|
+
* `tagColorForLabel` here would force every chip render to consult the index
|
|
84
|
+
* instead of computing locally, which is the property that lets undeclared tags
|
|
85
|
+
* stay color-stable with nothing stored.
|
|
86
|
+
*/
|
|
87
|
+
export type WorkspaceTagEntry = {
|
|
88
|
+
tag: string;
|
|
89
|
+
/** Carriers only. 0 for a declared tag nothing carries yet. */
|
|
90
|
+
total: number;
|
|
91
|
+
counts: Partial<Record<TagKind, number>>;
|
|
92
|
+
/** Has a registry row. */
|
|
93
|
+
declared: boolean;
|
|
94
|
+
description: string | null;
|
|
95
|
+
color: TagColor | null;
|
|
96
|
+
pinned: boolean;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Index ordering, shared by the web page, the CLI/MCP payload, and the picker.
|
|
100
|
+
* Pinned first matters beyond the tags page: the picker truncates its suggestion
|
|
101
|
+
* list, and a curated tag with few carriers would otherwise fall off that cliff.
|
|
102
|
+
*/
|
|
103
|
+
export declare function compareWorkspaceTagEntries(a: Pick<WorkspaceTagEntry, "tag" | "total" | "pinned">, b: Pick<WorkspaceTagEntry, "tag" | "total" | "pinned">): number;
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
// Workspace tags (Tags primitive, ADR 0010): free-form
|
|
2
|
-
// across primitives so campaign knowledge links across
|
|
3
|
-
// campaign-learnings wiki page, the source table, and
|
|
4
|
-
// can all carry `q3-outbound`.
|
|
5
|
-
// the 0009/0025 pattern); this module is the one
|
|
6
|
-
// participate, and how a tag
|
|
1
|
+
// Workspace tags (Tags primitive, ADR 0010; registry per ADR 0017): free-form
|
|
2
|
+
// lowercase labels shared across primitives so campaign knowledge links across
|
|
3
|
+
// stores — a sequence, its campaign-learnings wiki page, the source table, and
|
|
4
|
+
// the workflow that feeds it can all carry `q3-outbound`. Carrier storage stays
|
|
5
|
+
// per-store (`tags text[]` + GIN, the 0009/0025 pattern); this module is the one
|
|
6
|
+
// vocabulary: which kinds participate, and how a tag is normalized before it is
|
|
7
|
+
// written anywhere.
|
|
8
|
+
//
|
|
9
|
+
// Since ADR 0017 a tag exists iff it is DECLARED (a row in the tenant registry,
|
|
10
|
+
// `ox_context.workspace_tags`) OR CARRIED (some store's tags array holds it).
|
|
11
|
+
// The registry is an ANNOTATION table — description, color override, pinned —
|
|
12
|
+
// and never records which items carry a tag. Drift is legal in both directions.
|
|
7
13
|
/** Primitive kinds that participate in the workspace tag union today. */
|
|
8
14
|
export const TAG_KINDS = [
|
|
9
15
|
"knowledge_page",
|
|
@@ -16,10 +22,86 @@ export const TAG_KINDS = [
|
|
|
16
22
|
"mailbox",
|
|
17
23
|
"sender",
|
|
18
24
|
"record",
|
|
25
|
+
"domain",
|
|
26
|
+
"project",
|
|
27
|
+
"engagement_watch",
|
|
19
28
|
];
|
|
29
|
+
/**
|
|
30
|
+
* The taggable kinds in prose, for CLI `--help` and MCP tool descriptions.
|
|
31
|
+
*
|
|
32
|
+
* Lives next to {@link TAG_KINDS} because those descriptions are the *discovery*
|
|
33
|
+
* surface: a blind-user eval (2026-07-21) found the tags help still advertising
|
|
34
|
+
* the original seven kinds, so a user reading `tags --help` had no way to learn
|
|
35
|
+
* that domains, projects, or engagement watches were taggable at all — they had
|
|
36
|
+
* to stumble on each owning group's own help. One string, one import, and
|
|
37
|
+
* `TAG_KIND_PROSE_MARKERS` fails the build/test if a new kind skips it.
|
|
38
|
+
*/
|
|
39
|
+
export const TAG_KINDS_PROSE = "publishing posts, knowledge pages, sequences, tables, workflows, recipes, " +
|
|
40
|
+
"inbox conversations, CRM records, mailboxes, sender accounts, sending domains, " +
|
|
41
|
+
"projects, and engagement watches";
|
|
42
|
+
/**
|
|
43
|
+
* The phrase each kind must contribute to {@link TAG_KINDS_PROSE}. Typed as a
|
|
44
|
+
* total map over TagKind, so adding a kind is a compile error until it is named
|
|
45
|
+
* here, and the paired test asserts the phrase actually appears in the prose.
|
|
46
|
+
*/
|
|
47
|
+
export const TAG_KIND_PROSE_MARKERS = {
|
|
48
|
+
knowledge_page: "knowledge page",
|
|
49
|
+
publishing_post: "publishing post",
|
|
50
|
+
sequence: "sequence",
|
|
51
|
+
table: "table",
|
|
52
|
+
workflow: "workflow",
|
|
53
|
+
recipe: "recipe",
|
|
54
|
+
conversation: "inbox conversation",
|
|
55
|
+
mailbox: "mailbox",
|
|
56
|
+
sender: "sender account",
|
|
57
|
+
record: "CRM record",
|
|
58
|
+
domain: "sending domain",
|
|
59
|
+
project: "project",
|
|
60
|
+
engagement_watch: "engagement watch",
|
|
61
|
+
};
|
|
20
62
|
export function isTagKind(value) {
|
|
21
63
|
return typeof value === "string" && TAG_KINDS.includes(value);
|
|
22
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* How each kind is named when a tag's footprint is listed. Total over TagKind,
|
|
67
|
+
* so adding a kind is a compile error until it is labelled — the same guarantee
|
|
68
|
+
* {@link TAG_KIND_PROSE_MARKERS} gives the help text.
|
|
69
|
+
*
|
|
70
|
+
* `many` is sentence-form with proper nouns preserved ("CRM records"), which is
|
|
71
|
+
* what an inline count wants ("3 CRM records"). Headings run it through
|
|
72
|
+
* {@link tagKindHeading}, which only uppercases a leading lowercase letter, so
|
|
73
|
+
* "CRM records" survives intact where a naive capitalize would yield "Crm".
|
|
74
|
+
* Three hand-maintained copies of this map used to drift (the /tags page said
|
|
75
|
+
* "knowledge", the detail page and the MCP widget said "Knowledge pages").
|
|
76
|
+
*/
|
|
77
|
+
export const TAG_KIND_LABELS = {
|
|
78
|
+
knowledge_page: { one: "knowledge page", many: "knowledge pages" },
|
|
79
|
+
publishing_post: { one: "publishing post", many: "publishing posts" },
|
|
80
|
+
sequence: { one: "sequence", many: "sequences" },
|
|
81
|
+
table: { one: "table", many: "tables" },
|
|
82
|
+
workflow: { one: "workflow", many: "workflows" },
|
|
83
|
+
recipe: { one: "recipe", many: "recipes" },
|
|
84
|
+
conversation: { one: "conversation", many: "conversations" },
|
|
85
|
+
mailbox: { one: "mailbox", many: "mailboxes" },
|
|
86
|
+
sender: { one: "sender account", many: "sender accounts" },
|
|
87
|
+
record: { one: "CRM record", many: "CRM records" },
|
|
88
|
+
domain: { one: "domain", many: "domains" },
|
|
89
|
+
project: { one: "project", many: "projects" },
|
|
90
|
+
engagement_watch: { one: "engagement watch", many: "engagement watches" },
|
|
91
|
+
};
|
|
92
|
+
/** Inline label for a count: `tagKindLabel("sequence", 1)` → "sequence". */
|
|
93
|
+
export function tagKindLabel(kind, count) {
|
|
94
|
+
const entry = isTagKind(kind) ? TAG_KIND_LABELS[kind] : null;
|
|
95
|
+
if (!entry)
|
|
96
|
+
return kind;
|
|
97
|
+
return count === 1 ? entry.one : entry.many;
|
|
98
|
+
}
|
|
99
|
+
/** Section heading for a kind: "Knowledge pages", "CRM records". */
|
|
100
|
+
export function tagKindHeading(kind) {
|
|
101
|
+
const entry = isTagKind(kind) ? TAG_KIND_LABELS[kind] : null;
|
|
102
|
+
const label = entry ? entry.many : kind;
|
|
103
|
+
return label.charAt(0).toUpperCase() + label.slice(1);
|
|
104
|
+
}
|
|
23
105
|
/** Hard cap per tagged item — matches the wiki's long-standing limit. */
|
|
24
106
|
export const MAX_TAGS_PER_ITEM = 50;
|
|
25
107
|
/**
|
|
@@ -36,3 +118,37 @@ export function normalizeTags(value) {
|
|
|
36
118
|
return [];
|
|
37
119
|
return normalizeTagList(value);
|
|
38
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Registry-only caps (ADR 0017). Deliberately NOT enforced by
|
|
123
|
+
* {@link normalizeTagList}: that runs on every writer's hot path, so adding a
|
|
124
|
+
* length filter there would silently drop an existing long tag the next time
|
|
125
|
+
* any row carrying it was rewritten. A longer tag stays legal to carry — it
|
|
126
|
+
* just cannot be declared.
|
|
127
|
+
*/
|
|
128
|
+
export const MAX_TAG_LABEL_LENGTH = 200;
|
|
129
|
+
export const MAX_TAG_DESCRIPTION_LENGTH = 500;
|
|
130
|
+
/**
|
|
131
|
+
* Normalize ONE label the way {@link normalizeTagList} normalizes each element,
|
|
132
|
+
* and reject what the registry cannot store: non-strings, blanks, and anything
|
|
133
|
+
* over {@link MAX_TAG_LABEL_LENGTH}. Returns `null` so callers can raise their
|
|
134
|
+
* own typed error.
|
|
135
|
+
*
|
|
136
|
+
* Note this lowercases and trims but does NOT slugify — "Q3 Outbound" becomes
|
|
137
|
+
* "q3 outbound", space intact. Any character is legal in a tag.
|
|
138
|
+
*/
|
|
139
|
+
export function normalizeTagLabel(value) {
|
|
140
|
+
if (typeof value !== "string")
|
|
141
|
+
return null;
|
|
142
|
+
const normalized = value.trim().toLowerCase();
|
|
143
|
+
if (!normalized || normalized.length > MAX_TAG_LABEL_LENGTH)
|
|
144
|
+
return null;
|
|
145
|
+
return normalized;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Index ordering, shared by the web page, the CLI/MCP payload, and the picker.
|
|
149
|
+
* Pinned first matters beyond the tags page: the picker truncates its suggestion
|
|
150
|
+
* list, and a curated tag with few carriers would otherwise fall off that cliff.
|
|
151
|
+
*/
|
|
152
|
+
export function compareWorkspaceTagEntries(a, b) {
|
|
153
|
+
return Number(b.pinned) - Number(a.pinned) || b.total - a.total || a.tag.localeCompare(b.tag);
|
|
154
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const OXYGEN_VERSION = "1.
|
|
1
|
+
export const OXYGEN_VERSION = "1.575.19";
|
|
2
2
|
// The GLOBAL CLI compatibility floor: the oldest CLI allowed to call any
|
|
3
3
|
// operational route. Raising it hard-rejects every older CLI from the entire
|
|
4
4
|
// product, so it obeys one law, enforced by scripts/ci/cli-min-version-gate.mjs:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const WORKFLOW_TRIGGER_AUTO_PAUSE_METADATA_KEYS: readonly ["consecutive_failure_count", "last_failure_code", "last_failure_at", "auto_paused_at", "auto_pause_reason"];
|
|
1
|
+
export declare const WORKFLOW_TRIGGER_AUTO_PAUSE_METADATA_KEYS: readonly ["consecutive_failure_count", "consecutive_capacity_failure_count", "last_failure_code", "last_failure_at", "auto_paused_at", "auto_pause_reason"];
|
|
2
2
|
export declare function clearWorkflowTriggerAutoPauseMetadata(metadata: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export const WORKFLOW_TRIGGER_AUTO_PAUSE_METADATA_KEYS = [
|
|
2
2
|
"consecutive_failure_count",
|
|
3
|
+
// The provider-capacity streak, counted independently of the deterministic one
|
|
4
|
+
// so the two classes cannot borrow each other's budget. Listed here so a
|
|
5
|
+
// success — or a re-enable — clears it through the same single path.
|
|
6
|
+
"consecutive_capacity_failure_count",
|
|
3
7
|
"last_failure_code",
|
|
4
8
|
"last_failure_at",
|
|
5
9
|
"auto_paused_at",
|
|
@@ -11,15 +11,110 @@
|
|
|
11
11
|
"import": "./dist/index.js",
|
|
12
12
|
"default": "./dist/index.js"
|
|
13
13
|
},
|
|
14
|
+
"./directory": {
|
|
15
|
+
"types": "./dist/directory.d.ts",
|
|
16
|
+
"import": "./dist/directory.js",
|
|
17
|
+
"default": "./dist/directory.js"
|
|
18
|
+
},
|
|
14
19
|
"./file-import": {
|
|
15
20
|
"types": "./dist/file-import.d.ts",
|
|
16
21
|
"import": "./dist/file-import.js",
|
|
17
22
|
"default": "./dist/file-import.js"
|
|
18
23
|
},
|
|
24
|
+
"./linkedin-url": {
|
|
25
|
+
"types": "./dist/linkedin-url.d.ts",
|
|
26
|
+
"import": "./dist/linkedin-url.js",
|
|
27
|
+
"default": "./dist/linkedin-url.js"
|
|
28
|
+
},
|
|
29
|
+
"./cell-format": {
|
|
30
|
+
"types": "./dist/cell-format.d.ts",
|
|
31
|
+
"import": "./dist/cell-format.js",
|
|
32
|
+
"default": "./dist/cell-format.js"
|
|
33
|
+
},
|
|
34
|
+
"./column-types": {
|
|
35
|
+
"types": "./dist/column-types.d.ts",
|
|
36
|
+
"import": "./dist/column-types.js",
|
|
37
|
+
"default": "./dist/column-types.js"
|
|
38
|
+
},
|
|
39
|
+
"./object-storage": {
|
|
40
|
+
"types": "./dist/object-storage.d.ts",
|
|
41
|
+
"import": "./dist/object-storage.js",
|
|
42
|
+
"default": "./dist/object-storage.js"
|
|
43
|
+
},
|
|
44
|
+
"./select-options": {
|
|
45
|
+
"types": "./dist/select-options.d.ts",
|
|
46
|
+
"import": "./dist/select-options.js",
|
|
47
|
+
"default": "./dist/select-options.js"
|
|
48
|
+
},
|
|
49
|
+
"./suppression-entries": {
|
|
50
|
+
"types": "./dist/suppression-entries.d.ts",
|
|
51
|
+
"import": "./dist/suppression-entries.js",
|
|
52
|
+
"default": "./dist/suppression-entries.js"
|
|
53
|
+
},
|
|
54
|
+
"./cli-result": {
|
|
55
|
+
"types": "./dist/cli-result.d.ts",
|
|
56
|
+
"import": "./dist/cli-result.js",
|
|
57
|
+
"default": "./dist/cli-result.js"
|
|
58
|
+
},
|
|
19
59
|
"./custom-http-safety": {
|
|
20
60
|
"types": "./dist/custom-http-safety.d.ts",
|
|
21
61
|
"import": "./dist/custom-http-safety.js",
|
|
22
62
|
"default": "./dist/custom-http-safety.js"
|
|
63
|
+
},
|
|
64
|
+
"./search-vocab": {
|
|
65
|
+
"types": "./dist/search-vocab.d.ts",
|
|
66
|
+
"import": "./dist/search-vocab.js",
|
|
67
|
+
"default": "./dist/search-vocab.js"
|
|
68
|
+
},
|
|
69
|
+
"./signup-lead-webhook": {
|
|
70
|
+
"types": "./dist/signup-lead-webhook.d.ts",
|
|
71
|
+
"import": "./dist/signup-lead-webhook.js",
|
|
72
|
+
"default": "./dist/signup-lead-webhook.js"
|
|
73
|
+
},
|
|
74
|
+
"./knowledge-constants": {
|
|
75
|
+
"types": "./dist/knowledge-constants.d.ts",
|
|
76
|
+
"import": "./dist/knowledge-constants.js",
|
|
77
|
+
"default": "./dist/knowledge-constants.js"
|
|
78
|
+
},
|
|
79
|
+
"./workflow-status-change": {
|
|
80
|
+
"types": "./dist/workflow-status-change.d.ts",
|
|
81
|
+
"import": "./dist/workflow-status-change.js",
|
|
82
|
+
"default": "./dist/workflow-status-change.js"
|
|
83
|
+
},
|
|
84
|
+
"./billing": {
|
|
85
|
+
"types": "./dist/billing.d.ts",
|
|
86
|
+
"import": "./dist/billing.js",
|
|
87
|
+
"default": "./dist/billing.js"
|
|
88
|
+
},
|
|
89
|
+
"./pricing-sheet": {
|
|
90
|
+
"types": "./dist/pricing-sheet.d.ts",
|
|
91
|
+
"import": "./dist/pricing-sheet.js",
|
|
92
|
+
"default": "./dist/pricing-sheet.js"
|
|
93
|
+
},
|
|
94
|
+
"./copilot-journeys": {
|
|
95
|
+
"types": "./dist/copilot-journeys.d.ts",
|
|
96
|
+
"import": "./dist/copilot-journeys.js",
|
|
97
|
+
"default": "./dist/copilot-journeys.js"
|
|
98
|
+
},
|
|
99
|
+
"./hosted-ai": {
|
|
100
|
+
"types": "./dist/hosted-ai.d.ts",
|
|
101
|
+
"import": "./dist/hosted-ai.js",
|
|
102
|
+
"default": "./dist/hosted-ai.js"
|
|
103
|
+
},
|
|
104
|
+
"./sequences": {
|
|
105
|
+
"types": "./dist/sequences.d.ts",
|
|
106
|
+
"import": "./dist/sequences.js",
|
|
107
|
+
"default": "./dist/sequences.js"
|
|
108
|
+
},
|
|
109
|
+
"./tags": {
|
|
110
|
+
"types": "./dist/tags.d.ts",
|
|
111
|
+
"import": "./dist/tags.js",
|
|
112
|
+
"default": "./dist/tags.js"
|
|
113
|
+
},
|
|
114
|
+
"./schedule-label": {
|
|
115
|
+
"types": "./dist/schedule-label.d.ts",
|
|
116
|
+
"import": "./dist/schedule-label.js",
|
|
117
|
+
"default": "./dist/schedule-label.js"
|
|
23
118
|
}
|
|
24
119
|
},
|
|
25
120
|
"dependencies": {}
|