@oxygen-agent/cli 1.1003.12 → 1.1010.644

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 (102) hide show
  1. package/README.md +1 -1
  2. package/dist/column-decision-options.d.ts +20 -0
  3. package/dist/column-decision-options.js +54 -0
  4. package/dist/command-manifest.js +15 -2
  5. package/dist/functions-commands.js +11 -11
  6. package/dist/index.js +1222 -159
  7. package/dist/search-ai-filter-notice.d.ts +17 -0
  8. package/dist/search-ai-filter-notice.js +38 -0
  9. package/dist/skills.js +34 -10
  10. package/dist/util.d.ts +9 -0
  11. package/dist/util.js +14 -0
  12. package/node_modules/@oxygen/cli-ugc/dist/commands.js +296 -140
  13. package/node_modules/@oxygen/cli-ugc/dist/field-parser.d.ts +9 -0
  14. package/node_modules/@oxygen/cli-ugc/dist/field-parser.js +34 -0
  15. package/node_modules/@oxygen/recipe-sdk/dist/index.d.ts +13 -0
  16. package/node_modules/@oxygen/shared/dist/billing.d.ts +21 -0
  17. package/node_modules/@oxygen/shared/dist/billing.js +45 -0
  18. package/node_modules/@oxygen/shared/dist/byok-connect.js +5 -0
  19. package/node_modules/@oxygen/shared/dist/capability-discovery.d.ts +10 -0
  20. package/node_modules/@oxygen/shared/dist/capability-discovery.js +223 -13
  21. package/node_modules/@oxygen/shared/dist/cli-http-error.d.ts +8 -0
  22. package/node_modules/@oxygen/shared/dist/cli-http-error.js +8 -0
  23. package/node_modules/@oxygen/shared/dist/cli-result.js +1 -0
  24. package/node_modules/@oxygen/shared/dist/column-autofill.js +5 -23
  25. package/node_modules/@oxygen/shared/dist/column-decision.d.ts +50 -0
  26. package/node_modules/@oxygen/shared/dist/column-decision.js +228 -0
  27. package/node_modules/@oxygen/shared/dist/company-enrichment-fields.d.ts +9 -4
  28. package/node_modules/@oxygen/shared/dist/company-enrichment-fields.js +11 -8
  29. package/node_modules/@oxygen/shared/dist/copilot-skills.generated.d.ts +4 -4
  30. package/node_modules/@oxygen/shared/dist/copilot-skills.generated.js +4 -4
  31. package/node_modules/@oxygen/shared/dist/cutover-freeze.d.ts +26 -0
  32. package/node_modules/@oxygen/shared/dist/cutover-freeze.js +52 -0
  33. package/node_modules/@oxygen/shared/dist/data-suppliers.d.ts +57 -0
  34. package/node_modules/@oxygen/shared/dist/data-suppliers.js +59 -0
  35. package/node_modules/@oxygen/shared/dist/enrichment-intents.d.ts +6 -2
  36. package/node_modules/@oxygen/shared/dist/enrichment-intents.js +13 -23
  37. package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +60 -4
  38. package/node_modules/@oxygen/shared/dist/hosted-ai.js +125 -10
  39. package/node_modules/@oxygen/shared/dist/index.d.ts +2 -0
  40. package/node_modules/@oxygen/shared/dist/index.js +2 -0
  41. package/node_modules/@oxygen/shared/dist/langfuse.d.ts +44 -1
  42. package/node_modules/@oxygen/shared/dist/langfuse.js +407 -14
  43. package/node_modules/@oxygen/shared/dist/linkedin-countries.d.ts +1 -0
  44. package/node_modules/@oxygen/shared/dist/linkedin-countries.js +2 -0
  45. package/node_modules/@oxygen/shared/dist/linkedin-country-timezones.d.ts +24 -0
  46. package/node_modules/@oxygen/shared/dist/linkedin-country-timezones.js +276 -0
  47. package/node_modules/@oxygen/shared/dist/linkedin-message-deletion.d.ts +2 -0
  48. package/node_modules/@oxygen/shared/dist/linkedin-message-deletion.js +5 -0
  49. package/node_modules/@oxygen/shared/dist/linkedin-post-keywords.d.ts +44 -0
  50. package/node_modules/@oxygen/shared/dist/linkedin-post-keywords.js +116 -0
  51. package/node_modules/@oxygen/shared/dist/linkedin-sequences.d.ts +96 -0
  52. package/node_modules/@oxygen/shared/dist/linkedin-sequences.js +123 -0
  53. package/node_modules/@oxygen/shared/dist/llm-durable-capture.d.ts +24 -0
  54. package/node_modules/@oxygen/shared/dist/llm-durable-capture.js +89 -0
  55. package/node_modules/@oxygen/shared/dist/llm-prompts.d.ts +75 -0
  56. package/node_modules/@oxygen/shared/dist/llm-prompts.js +161 -0
  57. package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.d.ts +90 -0
  58. package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.js +130 -0
  59. package/node_modules/@oxygen/shared/dist/operational-telemetry.d.ts +24 -0
  60. package/node_modules/@oxygen/shared/dist/operational-telemetry.js +73 -0
  61. package/node_modules/@oxygen/shared/dist/otlp-log-sink.d.ts +29 -4
  62. package/node_modules/@oxygen/shared/dist/otlp-log-sink.js +189 -36
  63. package/node_modules/@oxygen/shared/dist/product-analytics-events.d.ts +21 -2
  64. package/node_modules/@oxygen/shared/dist/product-analytics-events.js +21 -1
  65. package/node_modules/@oxygen/shared/dist/redaction.js +4 -1
  66. package/node_modules/@oxygen/shared/dist/scraper-lane-credential.d.ts +18 -0
  67. package/node_modules/@oxygen/shared/dist/scraper-lane-credential.js +23 -0
  68. package/node_modules/@oxygen/shared/dist/sequences.js +5 -1
  69. package/node_modules/@oxygen/shared/dist/signup-lead-payload.d.ts +80 -0
  70. package/node_modules/@oxygen/shared/dist/signup-lead-payload.js +198 -0
  71. package/node_modules/@oxygen/shared/dist/social-capabilities.d.ts +6 -0
  72. package/node_modules/@oxygen/shared/dist/social-capabilities.js +25 -16
  73. package/node_modules/@oxygen/shared/dist/social-post-metrics-core.d.ts +32 -0
  74. package/node_modules/@oxygen/shared/dist/social-post-metrics-core.js +32 -0
  75. package/node_modules/@oxygen/shared/dist/social-post-metrics-linkedin.d.ts +31 -0
  76. package/node_modules/@oxygen/shared/dist/social-post-metrics-linkedin.js +103 -0
  77. package/node_modules/@oxygen/shared/dist/social-post-metrics-series.d.ts +96 -0
  78. package/node_modules/@oxygen/shared/dist/social-post-metrics-series.js +213 -0
  79. package/node_modules/@oxygen/shared/dist/social-post-metrics-x.d.ts +13 -0
  80. package/node_modules/@oxygen/shared/dist/social-post-metrics-x.js +78 -0
  81. package/node_modules/@oxygen/shared/dist/social-post-metrics.d.ts +36 -0
  82. package/node_modules/@oxygen/shared/dist/social-post-metrics.js +51 -0
  83. package/node_modules/@oxygen/shared/dist/stripe-price-catalog.d.ts +36 -0
  84. package/node_modules/@oxygen/shared/dist/stripe-price-catalog.js +184 -0
  85. package/node_modules/@oxygen/shared/dist/stripe-subscription-kind.d.ts +41 -0
  86. package/node_modules/@oxygen/shared/dist/stripe-subscription-kind.js +44 -0
  87. package/node_modules/@oxygen/shared/dist/table-limits.d.ts +3 -0
  88. package/node_modules/@oxygen/shared/dist/table-limits.js +3 -0
  89. package/node_modules/@oxygen/shared/dist/telemetry-export-observer.d.ts +94 -0
  90. package/node_modules/@oxygen/shared/dist/telemetry-export-observer.js +298 -0
  91. package/node_modules/@oxygen/shared/dist/telemetry.d.ts +11 -0
  92. package/node_modules/@oxygen/shared/dist/telemetry.js +19 -1
  93. package/node_modules/@oxygen/shared/dist/ugc.d.ts +22 -11
  94. package/node_modules/@oxygen/shared/dist/ugc.js +10 -0
  95. package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -0
  96. package/node_modules/@oxygen/shared/dist/version.generated.js +2 -0
  97. package/node_modules/@oxygen/shared/dist/version.js +8 -1
  98. package/node_modules/@oxygen/shared/dist/workspace-event-catalog.js +0 -23
  99. package/node_modules/@oxygen/shared/dist/workspace-file-storage.d.ts +29 -0
  100. package/node_modules/@oxygen/shared/dist/workspace-file-storage.js +31 -0
  101. package/node_modules/@oxygen/shared/package.json +9 -0
  102. package/package.json +2 -1
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A charged search AI filter's run totals as one terminal line (ADR 0027,
3
+ * amendment 2026-09-25). `table-ingestions get` carries them under
4
+ * `ai_filter`; `table-ingestions wait` nests that response under
5
+ * `ingestionRun`. The blind baseline could not see what a filter kept and
6
+ * what it dropped, so the terminal says it next to the JSON.
7
+ *
8
+ * Matches and items the filter could not judge are both written to the table,
9
+ * so the line never sums them into one "kept": the blind acceptance
10
+ * (2026-09-25) read "kept 200, dropped 0" as 200 matches when 27 of them were
11
+ * never judged.
12
+ *
13
+ * Returns null unless the envelope carries run totals. The plan's and the dry
14
+ * run's `ai_filter` blocks are quotes without a `fetched` count, so they print
15
+ * nothing.
16
+ */
17
+ export declare function formatSearchAiFilterTotalsNotice(data: unknown): string | null;
@@ -0,0 +1,38 @@
1
+ import { isRecord } from "./util.js";
2
+ /**
3
+ * A charged search AI filter's run totals as one terminal line (ADR 0027,
4
+ * amendment 2026-09-25). `table-ingestions get` carries them under
5
+ * `ai_filter`; `table-ingestions wait` nests that response under
6
+ * `ingestionRun`. The blind baseline could not see what a filter kept and
7
+ * what it dropped, so the terminal says it next to the JSON.
8
+ *
9
+ * Matches and items the filter could not judge are both written to the table,
10
+ * so the line never sums them into one "kept": the blind acceptance
11
+ * (2026-09-25) read "kept 200, dropped 0" as 200 matches when 27 of them were
12
+ * never judged.
13
+ *
14
+ * Returns null unless the envelope carries run totals. The plan's and the dry
15
+ * run's `ai_filter` blocks are quotes without a `fetched` count, so they print
16
+ * nothing.
17
+ */
18
+ export function formatSearchAiFilterTotalsNotice(data) {
19
+ if (!isRecord(data))
20
+ return null;
21
+ const run = isRecord(data.ingestionRun) ? data.ingestionRun : data;
22
+ const totals = isRecord(run.ai_filter) ? run.ai_filter : null;
23
+ if (!totals || typeof totals.fetched !== "number")
24
+ return null;
25
+ const count = (value) => (typeof value === "number" && Number.isFinite(value) ? value : 0);
26
+ const matched = count(totals.kept_matched ?? totals.matched);
27
+ const unjudged = count(totals.kept_unjudged ?? totals.unclassified);
28
+ const credits = count(totals.credits_charged);
29
+ const parts = [
30
+ `${matched} matched`,
31
+ `${unjudged} could not be judged (kept, marked unclassified)`,
32
+ `${count(totals.dropped)} dropped`,
33
+ ];
34
+ const unavailable = typeof totals.unavailable_reason === "string" && totals.unavailable_reason
35
+ ? `. The filter did not run on some pages: ${totals.unavailable_reason}`
36
+ : "";
37
+ return `AI filter: fetched ${count(totals.fetched)}: ${parts.join(", ")}${credits > 0 ? `; ${credits} credits` : ""}${unavailable}`;
38
+ }
package/dist/skills.js CHANGED
@@ -793,27 +793,51 @@ function scoreSkill(skill, tokens, recommendedSkills) {
793
793
  score += 400 - (routeIndex * 20);
794
794
  return score;
795
795
  }
796
+ /**
797
+ * Rank a skill's documents against the query tokens.
798
+ *
799
+ * An EXACT hit on a provider name, a path segment, or a tag outranks an
800
+ * incidental substring. Flat `includes` scoring made a query that literally
801
+ * names a provider lose to an unrelated document that merely contains the
802
+ * letters: measured 2026-09-21, `skills search "hubspot import segment
803
+ * do-not-contact suppression"` returned `provider-runbooks/bettercontact.md`
804
+ * and not `provider-runbooks/hubspot.md`, because "contact" is a substring of
805
+ * "bettercontact" and the alphabetical tie-break did the rest. A blind
806
+ * acceptance run lost its whole HubSpot fallback to that.
807
+ */
796
808
  function matchingSkillDocuments(skill, tokens) {
797
809
  if (tokens.length === 0)
798
810
  return [];
799
811
  return skill.documents
800
812
  .map((document) => ({
801
813
  document,
802
- score: tokens.reduce((total, token) => {
803
- const text = [
804
- document.path,
805
- document.title ?? "",
806
- document.kind ?? "",
807
- ...document.tags,
808
- ...document.providers,
809
- ].join(" ").toLowerCase();
810
- return total + (text.includes(token) ? 1 : 0);
811
- }, 0),
814
+ score: scoreSkillDocument(document, tokens),
812
815
  }))
813
816
  .filter((entry) => entry.score > 0)
814
817
  .sort((a, b) => b.score - a.score || a.document.path.localeCompare(b.document.path))
815
818
  .map((entry) => entry.document);
816
819
  }
820
+ function scoreSkillDocument(document, tokens) {
821
+ const exact = new Set([
822
+ ...document.providers.map((value) => value.toLowerCase()),
823
+ ...document.tags.map((value) => value.toLowerCase()),
824
+ // Path segments without the extension: "provider-runbooks/hubspot.md" ->
825
+ // "provider", "runbooks", "hubspot".
826
+ ...document.path.toLowerCase().replace(/\.[a-z0-9]+$/, "").split(/[^a-z0-9]+/),
827
+ ].filter(Boolean));
828
+ const substring = [
829
+ document.path,
830
+ document.title ?? "",
831
+ document.kind ?? "",
832
+ ...document.tags,
833
+ ...document.providers,
834
+ ].join(" ").toLowerCase();
835
+ return tokens.reduce((total, token) => {
836
+ if (exact.has(token))
837
+ return total + 5;
838
+ return total + (substring.includes(token) ? 1 : 0);
839
+ }, 0);
840
+ }
817
841
  function inspectSkillsInstaller() {
818
842
  const invocation = resolveCmdShimInvocation("npx", ["--version"], process.platform, process.env);
819
843
  const result = spawnSync(invocation.executable, invocation.args, {
package/dist/util.d.ts CHANGED
@@ -1,3 +1,12 @@
1
1
  export { isRecord } from "@oxygen/shared";
2
2
  export declare function readOption(value: string | undefined): string | null;
3
+ /**
4
+ * A flag whose ABSENCE and whose EMPTY value mean different things: absent
5
+ * leaves the field alone, `""` clears it. `readOption` folds both into `null`,
6
+ * which is how `crm tasks update --title x` used to send `priority: null,
7
+ * due_at: null, body: null, assignee_actor_id: null` and wipe a task's deadline
8
+ * and priority on every rename (dev, 2026-09-22) — and `crm notes update --pin`
9
+ * cleared the title the same way.
10
+ */
11
+ export declare function readClearableOption(value: string | undefined): string | null | undefined;
3
12
  export declare function readErrorMessage(error: unknown): string;
package/dist/util.js CHANGED
@@ -2,6 +2,20 @@ export { isRecord } from "@oxygen/shared";
2
2
  export function readOption(value) {
3
3
  return typeof value === "string" && value.trim() ? value.trim() : null;
4
4
  }
5
+ /**
6
+ * A flag whose ABSENCE and whose EMPTY value mean different things: absent
7
+ * leaves the field alone, `""` clears it. `readOption` folds both into `null`,
8
+ * which is how `crm tasks update --title x` used to send `priority: null,
9
+ * due_at: null, body: null, assignee_actor_id: null` and wipe a task's deadline
10
+ * and priority on every rename (dev, 2026-09-22) — and `crm notes update --pin`
11
+ * cleared the title the same way.
12
+ */
13
+ export function readClearableOption(value) {
14
+ if (value === undefined)
15
+ return undefined;
16
+ const trimmed = value.trim();
17
+ return trimmed ? trimmed : null;
18
+ }
5
19
  export function readErrorMessage(error) {
6
20
  return error instanceof Error ? error.message : "unknown error";
7
21
  }