@oxygen-agent/cli 1.987.20 → 1.1003.12

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.
Files changed (106) hide show
  1. package/README.md +1 -1
  2. package/dist/admin-primary-providers-render.d.ts +0 -2
  3. package/dist/admin-primary-providers-render.js +1 -1
  4. package/dist/browser-login.js +1 -4
  5. package/dist/command-manifest.d.ts +3 -2
  6. package/dist/command-manifest.js +10 -0
  7. package/dist/credentials.d.ts +1 -1
  8. package/dist/functions-commands.js +6 -2
  9. package/dist/help.d.ts +8 -0
  10. package/dist/help.js +46 -0
  11. package/dist/index.js +1569 -123
  12. package/dist/knowledge-mirror.d.ts +2 -2
  13. package/dist/runtime.d.ts +0 -15
  14. package/dist/runtime.js +1 -1
  15. package/dist/session.d.ts +4 -3
  16. package/dist/skills.d.ts +8 -7
  17. package/dist/skills.js +24 -10
  18. package/dist/transcript.d.ts +2 -1
  19. package/dist/util.d.ts +1 -1
  20. package/dist/util.js +1 -3
  21. package/node_modules/@oxygen/formula/dist/coerce.d.ts +10 -0
  22. package/node_modules/@oxygen/formula/dist/coerce.js +10 -0
  23. package/node_modules/@oxygen/formula/dist/formula-functions.js +65 -0
  24. package/node_modules/@oxygen/formula/dist/hash.d.ts +19 -0
  25. package/node_modules/@oxygen/formula/dist/hash.js +199 -0
  26. package/node_modules/@oxygen/formula/dist/value-cleaners.d.ts +6 -1
  27. package/node_modules/@oxygen/formula/dist/value-cleaners.js +10 -26
  28. package/node_modules/@oxygen/shared/dist/array-utils.d.ts +5 -0
  29. package/node_modules/@oxygen/shared/dist/array-utils.js +11 -0
  30. package/node_modules/@oxygen/shared/dist/billing.d.ts +78 -22
  31. package/node_modules/@oxygen/shared/dist/billing.js +150 -40
  32. package/node_modules/@oxygen/shared/dist/capability-discovery.d.ts +17 -0
  33. package/node_modules/@oxygen/shared/dist/capability-discovery.js +89 -16
  34. package/node_modules/@oxygen/shared/dist/column-autofill.d.ts +52 -0
  35. package/node_modules/@oxygen/shared/dist/column-autofill.js +80 -0
  36. package/node_modules/@oxygen/shared/dist/column-output-fields.js +2 -6
  37. package/node_modules/@oxygen/shared/dist/company-enrichment-fields.d.ts +108 -0
  38. package/node_modules/@oxygen/shared/dist/company-enrichment-fields.js +545 -0
  39. package/node_modules/@oxygen/shared/dist/copilot-skills.generated.d.ts +2 -2
  40. package/node_modules/@oxygen/shared/dist/copilot-skills.generated.js +2 -2
  41. package/node_modules/@oxygen/shared/dist/deploy-env.d.ts +74 -0
  42. package/node_modules/@oxygen/shared/dist/deploy-env.js +82 -0
  43. package/node_modules/@oxygen/shared/dist/dnc-rules.d.ts +130 -0
  44. package/node_modules/@oxygen/shared/dist/dnc-rules.js +221 -0
  45. package/node_modules/@oxygen/shared/dist/enrichment-intents.d.ts +103 -0
  46. package/node_modules/@oxygen/shared/dist/enrichment-intents.js +819 -0
  47. package/node_modules/@oxygen/shared/dist/error-message.d.ts +1 -0
  48. package/node_modules/@oxygen/shared/dist/error-message.js +3 -0
  49. package/node_modules/@oxygen/shared/dist/error-redaction.js +1 -3
  50. package/node_modules/@oxygen/shared/dist/external-write-policy.d.ts +33 -0
  51. package/node_modules/@oxygen/shared/dist/external-write-policy.js +68 -0
  52. package/node_modules/@oxygen/shared/dist/format-percent.d.ts +8 -0
  53. package/node_modules/@oxygen/shared/dist/format-percent.js +13 -0
  54. package/node_modules/@oxygen/shared/dist/freemail-domains.d.ts +81 -0
  55. package/node_modules/@oxygen/shared/dist/freemail-domains.js +157 -0
  56. package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.d.ts +1 -0
  57. package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.js +1 -1
  58. package/node_modules/@oxygen/shared/dist/index.d.ts +13 -0
  59. package/node_modules/@oxygen/shared/dist/index.js +13 -0
  60. package/node_modules/@oxygen/shared/dist/json-path.js +1 -3
  61. package/node_modules/@oxygen/shared/dist/knowledge-bases.js +1 -3
  62. package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.d.ts +2 -2
  63. package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.js +2 -2
  64. package/node_modules/@oxygen/shared/dist/langfuse.js +9 -0
  65. package/node_modules/@oxygen/shared/dist/linkedin-countries.d.ts +32 -0
  66. package/node_modules/@oxygen/shared/dist/linkedin-countries.js +359 -0
  67. package/node_modules/@oxygen/shared/dist/log-sink-selector.d.ts +39 -0
  68. package/node_modules/@oxygen/shared/dist/log-sink-selector.js +56 -0
  69. package/node_modules/@oxygen/shared/dist/log.d.ts +1 -0
  70. package/node_modules/@oxygen/shared/dist/log.js +6 -1
  71. package/node_modules/@oxygen/shared/dist/object-storage.d.ts +17 -0
  72. package/node_modules/@oxygen/shared/dist/object-storage.js +21 -0
  73. package/node_modules/@oxygen/shared/dist/otlp-log-sink.d.ts +54 -0
  74. package/node_modules/@oxygen/shared/dist/otlp-log-sink.js +213 -0
  75. package/node_modules/@oxygen/shared/dist/plan-capabilities.js +1 -0
  76. package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +23 -22
  77. package/node_modules/@oxygen/shared/dist/plan-limits.js +45 -18
  78. package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +48 -41
  79. package/node_modules/@oxygen/shared/dist/pricing-sheet.js +36 -25
  80. package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.d.ts +22 -22
  81. package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.js +40 -34
  82. package/node_modules/@oxygen/shared/dist/product-analytics-environment.js +9 -0
  83. package/node_modules/@oxygen/shared/dist/product-analytics-events.d.ts +15 -0
  84. package/node_modules/@oxygen/shared/dist/product-analytics-events.js +15 -0
  85. package/node_modules/@oxygen/shared/dist/rate-window.d.ts +5 -0
  86. package/node_modules/@oxygen/shared/dist/rate-window.js +8 -0
  87. package/node_modules/@oxygen/shared/dist/research-output-contract.js +1 -3
  88. package/node_modules/@oxygen/shared/dist/search-vocab.js +4 -5
  89. package/node_modules/@oxygen/shared/dist/select-options.js +6 -1
  90. package/node_modules/@oxygen/shared/dist/sequence-failures.js +1 -5
  91. package/node_modules/@oxygen/shared/dist/sequences.d.ts +23 -0
  92. package/node_modules/@oxygen/shared/dist/sequences.js +110 -4
  93. package/node_modules/@oxygen/shared/dist/spend-safety.d.ts +22 -10
  94. package/node_modules/@oxygen/shared/dist/spend-safety.js +15 -21
  95. package/node_modules/@oxygen/shared/dist/sql-rows.d.ts +1 -0
  96. package/node_modules/@oxygen/shared/dist/sql-rows.js +3 -0
  97. package/node_modules/@oxygen/shared/dist/telemetry.js +9 -1
  98. package/node_modules/@oxygen/shared/dist/type-guards.d.ts +22 -0
  99. package/node_modules/@oxygen/shared/dist/type-guards.js +35 -0
  100. package/node_modules/@oxygen/shared/dist/value-readers.d.ts +21 -0
  101. package/node_modules/@oxygen/shared/dist/value-readers.js +59 -0
  102. package/node_modules/@oxygen/shared/dist/version.js +1 -1
  103. package/node_modules/@oxygen/shared/package.json +50 -0
  104. package/node_modules/@oxygen/workflows/dist/graph/expression.js +2 -5
  105. package/node_modules/@oxygen/workflows/dist/graph/params.js +1 -1
  106. package/package.json +2 -2
@@ -20,19 +20,19 @@ export declare const AUTONOMOUS_WORKFLOW_TRIGGER_TYPES: ReadonlySet<string>;
20
20
  * Per-run managed-credit ceiling for a LIVE workflow run fired by an autonomous
21
21
  * trigger when neither run metadata nor the manifest declares `max_credits`.
22
22
  */
23
- export declare const DEFAULT_TRIGGER_RUN_CREDIT_CEILING: Record<PlanTier, number | null>;
23
+ export declare const DEFAULT_TRIGGER_RUN_CREDIT_CEILING: Record<SpendSafetyPlanTier, number | null>;
24
24
  /**
25
25
  * Per-delivery credit ceiling stamped onto a standing/webhook table auto-run
26
26
  * batch when the armed configuration carries no explicit `max_credits`.
27
27
  */
28
- export declare const DEFAULT_AUTO_RUN_BATCH_CREDIT_CEILING: Record<PlanTier, number | null>;
28
+ export declare const DEFAULT_AUTO_RUN_BATCH_CREDIT_CEILING: Record<SpendSafetyPlanTier, number | null>;
29
29
  /**
30
30
  * Row ceiling for a BYOK AI-column run whose caller gave no explicit row bound
31
31
  * (no limit, no row_ids, selection "all"). BYOK bills the customer's own
32
32
  * provider account, so a credit ceiling is meaningless — row count is the
33
33
  * enforceable unit. An explicit limit (up to the 500k platform row cap) wins.
34
34
  */
35
- export declare const DEFAULT_BYOK_COLUMN_RUN_MAX_ROWS: Record<PlanTier, number | null>;
35
+ export declare const DEFAULT_BYOK_COLUMN_RUN_MAX_ROWS: Record<SpendSafetyPlanTier, number | null>;
36
36
  /**
37
37
  * Default per-provider DAILY call cap for BYOK provider traffic (the customer's
38
38
  * own key). Short-window pacing defaults already exist in provider-fetch; this
@@ -40,7 +40,7 @@ export declare const DEFAULT_BYOK_COLUMN_RUN_MAX_ROWS: Record<PlanTier, number |
40
40
  * with the self-serve override surface live. A workspace
41
41
  * provider_rate_limit_policies row with windowSeconds=86400 overrides it.
42
42
  */
43
- export declare const DEFAULT_BYOK_PROVIDER_DAILY_CALL_CAP: Record<PlanTier, number | null>;
43
+ export declare const DEFAULT_BYOK_PROVIDER_DAILY_CALL_CAP: Record<SpendSafetyPlanTier, number | null>;
44
44
  export declare const BYOK_PROVIDER_DAILY_WINDOW_SECONDS: number;
45
45
  export declare const BYOK_PROVIDER_DAILY_CAP_ENFORCEMENT_ENV = "OXYGEN_BYOK_DAILY_CAPS";
46
46
  export type ByokProviderDailyCapEnforcementMode = "observe_only" | "enforced";
@@ -105,10 +105,14 @@ export type OrgDailySpendGuard = {
105
105
  * decision is made, so enforcement and the read surfaces cannot drift apart.
106
106
  */
107
107
  export declare function resolveOrgDailySpendGuard(monthlyCredits: number | null | undefined): OrgDailySpendGuard | null;
108
- export declare function resolveDefaultTriggerRunCreditCeiling(tier: PlanTier): number | null;
109
- export declare function resolveDefaultAutoRunBatchCreditCeiling(tier: PlanTier): number | null;
110
- export declare function resolveDefaultByokColumnRunMaxRows(tier: PlanTier): number | null;
111
- export declare function resolveDefaultByokProviderDailyCallCap(tier: PlanTier): number | null;
108
+ /** Credits carry 3 decimals everywhere (control-DB numeric(18,3)). */
109
+ export declare function roundCredits(value: number): number;
110
+ /** Credit estimates that present to 2 decimals (cent-grained customer copy). */
111
+ export declare function roundCreditsToCents(value: number): number;
112
+ export declare function resolveDefaultTriggerRunCreditCeiling(tier: SpendSafetyPlanTier): number | null;
113
+ export declare function resolveDefaultAutoRunBatchCreditCeiling(tier: SpendSafetyPlanTier): number | null;
114
+ export declare function resolveDefaultByokColumnRunMaxRows(tier: SpendSafetyPlanTier): number | null;
115
+ export declare function resolveDefaultByokProviderDailyCallCap(tier: SpendSafetyPlanTier): number | null;
112
116
  /**
113
117
  * The plan tiers the spend-safety default tables above are keyed by. `limitsTier`
114
118
  * collapses "enterprise" onto the "scale" enforcement rung, but these tables carry
@@ -119,5 +123,13 @@ export declare function resolveDefaultByokProviderDailyCallCap(tier: PlanTier):
119
123
  * `oxygen limits` report, the org-facing provider-limits API, and the BYOK
120
124
  * daily-cap enforcement resolver — they must agree on which column an org reads.
121
125
  */
122
- export declare const SPEND_SAFETY_PLAN_TIERS: readonly PlanTier[];
123
- export declare function resolveSpendSafetyPlanTier(planTier: string | null, limitsTier: LimitsTier): PlanTier;
126
+ /**
127
+ * The tiers these tables are keyed by. `oxygen` is deliberately ABSENT: its six
128
+ * rungs span four enforcement rungs, so an Oxygen plan must fall through to its
129
+ * limitsTier (the price band) rather than read one shared column. Adding an
130
+ * "oxygen" column here would silently give a $1,999 workspace the same ceiling
131
+ * as a $49 one.
132
+ */
133
+ export type SpendSafetyPlanTier = Exclude<PlanTier, "oxygen">;
134
+ export declare const SPEND_SAFETY_PLAN_TIERS: readonly SpendSafetyPlanTier[];
135
+ export declare function resolveSpendSafetyPlanTier(planTier: string | null, limitsTier: LimitsTier): SpendSafetyPlanTier;
@@ -9,11 +9,11 @@ export const AUTONOMOUS_WORKFLOW_TRIGGER_TYPES = new Set([
9
9
  * trigger when neither run metadata nor the manifest declares `max_credits`.
10
10
  */
11
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,
12
+ free: 50,
13
+ starter: 500,
14
+ pro: 1_000,
15
+ team: 2_500,
16
+ scale: 25_000,
17
17
  enterprise: null,
18
18
  };
19
19
  /**
@@ -21,11 +21,11 @@ export const DEFAULT_TRIGGER_RUN_CREDIT_CEILING = {
21
21
  * batch when the armed configuration carries no explicit `max_credits`.
22
22
  */
23
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,
24
+ free: 50,
25
+ starter: 500,
26
+ pro: 1_000,
27
+ team: 2_500,
28
+ scale: 25_000,
29
29
  enterprise: null,
30
30
  };
31
31
  /**
@@ -129,9 +129,13 @@ export function resolveOrgDailySpendGuard(monthlyCredits) {
129
129
  };
130
130
  }
131
131
  /** Credits carry 3 decimals everywhere (control-DB numeric(18,3)). */
132
- function roundCredits(value) {
132
+ export function roundCredits(value) {
133
133
  return Math.round(value * 1000) / 1000;
134
134
  }
135
+ /** Credit estimates that present to 2 decimals (cent-grained customer copy). */
136
+ export function roundCreditsToCents(value) {
137
+ return Math.round((value + Number.EPSILON) * 100) / 100;
138
+ }
135
139
  export function resolveDefaultTriggerRunCreditCeiling(tier) {
136
140
  return DEFAULT_TRIGGER_RUN_CREDIT_CEILING[tier];
137
141
  }
@@ -144,16 +148,6 @@ export function resolveDefaultByokColumnRunMaxRows(tier) {
144
148
  export function resolveDefaultByokProviderDailyCallCap(tier) {
145
149
  return DEFAULT_BYOK_PROVIDER_DAILY_CALL_CAP[tier];
146
150
  }
147
- /**
148
- * The plan tiers the spend-safety default tables above are keyed by. `limitsTier`
149
- * collapses "enterprise" onto the "scale" enforcement rung, but these tables carry
150
- * a distinct "enterprise" column (null = runs on custom limits) — so prefer the
151
- * raw plan_tier whenever it is itself a table key, and fall back to the limits rung
152
- * (always a valid PlanTier key) when plan_tier is absent or an unknown/legacy
153
- * string (e.g. a Stripe price nickname). Single source of truth for the
154
- * `oxygen limits` report, the org-facing provider-limits API, and the BYOK
155
- * daily-cap enforcement resolver — they must agree on which column an org reads.
156
- */
157
151
  export const SPEND_SAFETY_PLAN_TIERS = [
158
152
  "free",
159
153
  "starter",
@@ -0,0 +1 @@
1
+ export declare function executeRows<T>(value: unknown): T[];
@@ -0,0 +1,3 @@
1
+ export function executeRows(value) {
2
+ return (value.rows ?? value);
3
+ }
@@ -1,4 +1,5 @@
1
1
  import { SpanStatusCode, metrics, trace, } from "@opentelemetry/api";
2
+ import { deployEnvTelemetryEnvironment, deployPlatformAttribute } from "./deploy-env.js";
2
3
  import { errorId } from "./log.js";
3
4
  import { normalizeTelemetryAttributes } from "./redaction.js";
4
5
  import { redactSqlParameters, sqlErrorTelemetryAttributes } from "./sql-error.js";
@@ -73,7 +74,14 @@ export function commonTelemetryAttributes(attributes) {
73
74
  const pick = (workerKeys, webKeys) => pickEnvBySurface(workerProcess, workerKeys, webKeys);
74
75
  return {
75
76
  "oxygen.version": OXYGEN_VERSION,
76
- "deployment.environment": pick(["FLY_ENVIRONMENT", "NODE_ENV"], ["VERCEL_ENV", "NODE_ENV"]),
77
+ // Which infrastructure this process runs on, so a self-hosted span is
78
+ // never mistaken for a managed one while both targets are live.
79
+ "oxygen.platform": deployPlatformAttribute(),
80
+ // OXYGEN_DEPLOY_ENV is consulted first and is the only signal a self-hosted
81
+ // box has: it carries neither FLY_ENVIRONMENT nor VERCEL_ENV, so without
82
+ // this the whole fleet would report its NODE_ENV and collapse prod, shadow
83
+ // and dev into one bucket. Unset leaves the managed chain untouched.
84
+ "deployment.environment": deployEnvTelemetryEnvironment() ?? pick(["FLY_ENVIRONMENT", "NODE_ENV"], ["VERCEL_ENV", "NODE_ENV"]),
77
85
  // deployment.sha stays the deploy artifact id: the Fly registry image ref on
78
86
  // the worker (release cross-reference), VERCEL_GIT_COMMIT_SHA on the web. The
79
87
  // worker's image ref is NOT a git commit, so deployment.git_sha carries the
@@ -13,3 +13,25 @@
13
13
  * `Record<string, unknown>`. Rejects `null`, arrays, and every primitive.
14
14
  */
15
15
  export declare function isRecord(value: unknown): value is Record<string, unknown>;
16
+ /**
17
+ * `value` as a `Record<string, unknown>` when it is a non-null, non-array
18
+ * object, else null.
19
+ */
20
+ export declare function asRecordOrNull(value: unknown): Record<string, unknown> | null;
21
+ /** Alias of {@link asRecordOrNull} for call sites that spell it `asRecord`. */
22
+ export declare const asRecord: typeof asRecordOrNull;
23
+ /**
24
+ * `value` as a `Record<string, unknown>`, falling back to an empty object.
25
+ * Deliberately masks "absent" and "present but wrong shape" the same way its
26
+ * call sites always have — use {@link asRecordOrNull} when that matters.
27
+ */
28
+ export declare function asRecordOrEmpty(value: unknown): Record<string, unknown>;
29
+ /** Finite number, else null. Does not parse numeric strings. */
30
+ export declare function readFiniteNumber(value: unknown): number | null;
31
+ /** Trimmed non-empty string, else null. */
32
+ export declare function readTrimmedString(value: unknown): string | null;
33
+ /**
34
+ * Trimmed non-empty string, else null — additionally coercing a number to its
35
+ * string form. Distinct from {@link readTrimmedString}, which rejects numbers.
36
+ */
37
+ export declare function readCoercedString(value: unknown): string | null;
@@ -15,3 +15,38 @@
15
15
  export function isRecord(value) {
16
16
  return typeof value === "object" && value !== null && !Array.isArray(value);
17
17
  }
18
+ /**
19
+ * `value` as a `Record<string, unknown>` when it is a non-null, non-array
20
+ * object, else null.
21
+ */
22
+ export function asRecordOrNull(value) {
23
+ return isRecord(value) ? value : null;
24
+ }
25
+ /** Alias of {@link asRecordOrNull} for call sites that spell it `asRecord`. */
26
+ export const asRecord = asRecordOrNull;
27
+ /**
28
+ * `value` as a `Record<string, unknown>`, falling back to an empty object.
29
+ * Deliberately masks "absent" and "present but wrong shape" the same way its
30
+ * call sites always have — use {@link asRecordOrNull} when that matters.
31
+ */
32
+ export function asRecordOrEmpty(value) {
33
+ return isRecord(value) ? value : {};
34
+ }
35
+ /** Finite number, else null. Does not parse numeric strings. */
36
+ export function readFiniteNumber(value) {
37
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
38
+ }
39
+ /** Trimmed non-empty string, else null. */
40
+ export function readTrimmedString(value) {
41
+ return typeof value === "string" && value.trim() ? value.trim() : null;
42
+ }
43
+ /**
44
+ * Trimmed non-empty string, else null — additionally coercing a number to its
45
+ * string form. Distinct from {@link readTrimmedString}, which rejects numbers.
46
+ */
47
+ export function readCoercedString(value) {
48
+ if (typeof value !== "string" && typeof value !== "number")
49
+ return null;
50
+ const trimmed = String(value).trim();
51
+ return trimmed ? trimmed : null;
52
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Canonical readers that coerce an `unknown` value (or a field of an untyped
3
+ * record) into a string/number, used across every OXYGEN package.
4
+ */
5
+ /** Trimmed non-empty string, else null. */
6
+ export declare function readString(value: unknown): string | null;
7
+ /** The first key in `keys` whose value is a non-empty string, trimmed. */
8
+ export declare function readFirstString(source: Record<string, unknown>, keys: string[]): string | null;
9
+ /** The first key in `keys` on `record` holding a non-empty string, trimmed. */
10
+ export declare function readStringField(record: Record<string, unknown>, keys: string[]): string | null;
11
+ /** Walk a dot-separated path through nested records; undefined when it breaks. */
12
+ export declare function readByPath(value: unknown, path: string): unknown;
13
+ /** Trimmed non-empty string, else null. */
14
+ export declare function readStringValue(value: unknown): string | null;
15
+ /**
16
+ * Non-empty string returned VERBATIM: emptiness is tested on the trimmed form
17
+ * but the original value is returned, so stored values keep their whitespace.
18
+ */
19
+ export declare function readStringValueUntrimmed(value: unknown): string | null;
20
+ /** Finite number, else null. Does not parse numeric strings. */
21
+ export declare function readNumberValue(value: unknown): number | null;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Canonical readers that coerce an `unknown` value (or a field of an untyped
3
+ * record) into a string/number, used across every OXYGEN package.
4
+ */
5
+ import { isRecord } from "./type-guards.js";
6
+ /** Trimmed non-empty string, else null. */
7
+ export function readString(value) {
8
+ return typeof value === "string" && value.trim() ? value.trim() : null;
9
+ }
10
+ /** The first key in `keys` whose value is a non-empty string, trimmed. */
11
+ export function readFirstString(source, keys) {
12
+ for (const key of keys) {
13
+ const value = source[key];
14
+ if (typeof value !== "string")
15
+ continue;
16
+ const trimmed = value.trim();
17
+ if (trimmed)
18
+ return trimmed;
19
+ }
20
+ return null;
21
+ }
22
+ /** The first key in `keys` on `record` holding a non-empty string, trimmed. */
23
+ export function readStringField(record, keys) {
24
+ for (const key of keys) {
25
+ const value = record[key];
26
+ if (typeof value === "string" && value.trim())
27
+ return value.trim();
28
+ }
29
+ return null;
30
+ }
31
+ /** Walk a dot-separated path through nested records; undefined when it breaks. */
32
+ export function readByPath(value, path) {
33
+ if (!path)
34
+ return value;
35
+ let current = value;
36
+ for (const segment of path.split(".")) {
37
+ if (!segment)
38
+ continue;
39
+ if (!isRecord(current))
40
+ return undefined;
41
+ current = current[segment];
42
+ }
43
+ return current;
44
+ }
45
+ /** Trimmed non-empty string, else null. */
46
+ export function readStringValue(value) {
47
+ return typeof value === "string" && value.trim() ? value.trim() : null;
48
+ }
49
+ /**
50
+ * Non-empty string returned VERBATIM: emptiness is tested on the trimmed form
51
+ * but the original value is returned, so stored values keep their whitespace.
52
+ */
53
+ export function readStringValueUntrimmed(value) {
54
+ return typeof value === "string" && value.trim() ? value : null;
55
+ }
56
+ /** Finite number, else null. Does not parse numeric strings. */
57
+ export function readNumberValue(value) {
58
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
59
+ }
@@ -1,6 +1,6 @@
1
1
  // Release metadata is a string API: a new version must not change the exported
2
2
  // declaration type and invalidate every dependent package's compiler state.
3
- export const OXYGEN_VERSION = "1.987.20";
3
+ export const OXYGEN_VERSION = "1.1003.12";
4
4
  // The GLOBAL CLI compatibility floor: the oldest CLI allowed to call any
5
5
  // operational route. Raising it hard-rejects every older CLI from the entire
6
6
  // product, so it obeys one law, enforced by scripts/ci/cli-min-version-gate.mjs:
@@ -96,6 +96,16 @@
96
96
  "import": "./dist/person-name.js",
97
97
  "default": "./dist/person-name.js"
98
98
  },
99
+ "./linkedin-countries": {
100
+ "types": "./dist/linkedin-countries.d.ts",
101
+ "import": "./dist/linkedin-countries.js",
102
+ "default": "./dist/linkedin-countries.js"
103
+ },
104
+ "./freemail-domains": {
105
+ "types": "./dist/freemail-domains.d.ts",
106
+ "import": "./dist/freemail-domains.js",
107
+ "default": "./dist/freemail-domains.js"
108
+ },
99
109
  "./select-options": {
100
110
  "types": "./dist/select-options.d.ts",
101
111
  "import": "./dist/select-options.js",
@@ -121,6 +131,21 @@
121
131
  "import": "./dist/cli-result.js",
122
132
  "default": "./dist/cli-result.js"
123
133
  },
134
+ "./type-guards": {
135
+ "types": "./dist/type-guards.d.ts",
136
+ "import": "./dist/type-guards.js",
137
+ "default": "./dist/type-guards.js"
138
+ },
139
+ "./value-readers": {
140
+ "types": "./dist/value-readers.d.ts",
141
+ "import": "./dist/value-readers.js",
142
+ "default": "./dist/value-readers.js"
143
+ },
144
+ "./timing": {
145
+ "types": "./dist/timing.d.ts",
146
+ "import": "./dist/timing.js",
147
+ "default": "./dist/timing.js"
148
+ },
124
149
  "./custom-http-safety": {
125
150
  "types": "./dist/custom-http-safety.d.ts",
126
151
  "import": "./dist/custom-http-safety.js",
@@ -225,6 +250,31 @@
225
250
  "types": "./dist/workspace-file-storage.d.ts",
226
251
  "import": "./dist/workspace-file-storage.js",
227
252
  "default": "./dist/workspace-file-storage.js"
253
+ },
254
+ "./company-enrichment-fields": {
255
+ "types": "./dist/company-enrichment-fields.d.ts",
256
+ "import": "./dist/company-enrichment-fields.js",
257
+ "default": "./dist/company-enrichment-fields.js"
258
+ },
259
+ "./*": {
260
+ "types": "./dist/*.d.ts",
261
+ "import": "./dist/*.js",
262
+ "default": "./dist/*.js"
263
+ },
264
+ "./enrichment-intents": {
265
+ "types": "./dist/enrichment-intents.d.ts",
266
+ "import": "./dist/enrichment-intents.js",
267
+ "default": "./dist/enrichment-intents.js"
268
+ },
269
+ "./log": {
270
+ "types": "./dist/log.d.ts",
271
+ "import": "./dist/log.js",
272
+ "default": "./dist/log.js"
273
+ },
274
+ "./linkedin-sequences": {
275
+ "types": "./dist/linkedin-sequences.d.ts",
276
+ "import": "./dist/linkedin-sequences.js",
277
+ "default": "./dist/linkedin-sequences.js"
228
278
  }
229
279
  },
230
280
  "dependencies": {}
@@ -13,7 +13,7 @@
13
13
  // - Reading is prototype-safe. Path segments are matched against own properties
14
14
  // only, and the segments that reach JavaScript object internals
15
15
  // (__proto__ / constructor / prototype) are rejected outright.
16
- import { analyzeFormulaDependencies, evaluateFormulaInScope, formulaExpressionError, } from "@oxygen/formula";
16
+ import { analyzeFormulaDependencies, evaluateFormulaInScope, formulaExpressionError, isRecord, } from "@oxygen/formula";
17
17
  /** A deterministic authoring/data error; retrying the same revision cannot repair it. */
18
18
  export class WorkflowValueCoercionError extends Error {
19
19
  coercion;
@@ -587,7 +587,7 @@ function lookupFormulaIdentifier(scope, identifier) {
587
587
  if (BLOCKED_PATH_SEGMENTS.has(identifier))
588
588
  return { found: false };
589
589
  const input = scope.trigger?.input;
590
- if (isPlainObject(input) && Object.prototype.hasOwnProperty.call(input, identifier)) {
590
+ if (isRecord(input) && Object.prototype.hasOwnProperty.call(input, identifier)) {
591
591
  return { found: true, value: input[identifier] };
592
592
  }
593
593
  const node = readSegment(scope.steps, identifier);
@@ -627,9 +627,6 @@ function isCoalescibleWorkflowFormulaPath(scope, identifier) {
627
627
  }
628
628
  return false;
629
629
  }
630
- function isPlainObject(value) {
631
- return typeof value === "object" && value !== null && !Array.isArray(value);
632
- }
633
630
  // ---------------------------------------------------------------------------
634
631
  // Conditions
635
632
  // ---------------------------------------------------------------------------
@@ -28,7 +28,7 @@ export const ANY_OF_REQUIREMENTS = {
28
28
  * Empty means ready.
29
29
  */
30
30
  export function missingToolParams(input) {
31
- const { toolId, fields, params, closed } = input;
31
+ const { toolId, fields, params } = input;
32
32
  const label = (name) => fields.find((field) => field.name === name)?.title ?? name;
33
33
  // An unknown key suppresses the missing-required report, because a misspelled
34
34
  // name is simultaneously an unknown key AND the reason a required field looks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxygen-agent/cli",
3
- "version": "1.987.20",
3
+ "version": "1.1003.12",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  "README.md"
33
33
  ],
34
34
  "dependencies": {
35
- "@aws-sdk/client-s3": "3.1050.0",
35
+ "@aws-sdk/client-s3": "3.1136.0",
36
36
  "@aws-sdk/s3-request-presigner": "3.1050.0",
37
37
  "@langfuse/core": "^5.11.0",
38
38
  "@langfuse/otel": "^5.11.0",