@oxygen-agent/cli 1.1014.136 → 1.1014.619

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 (293) hide show
  1. package/README.md +1 -1
  2. package/dist/admin-primary-providers-render.js +27 -19
  3. package/dist/cli-output.d.ts +12 -0
  4. package/dist/cli-output.js +395 -0
  5. package/dist/cli-paths.d.ts +1 -0
  6. package/dist/cli-paths.js +3 -0
  7. package/dist/cli-profile-context.d.ts +3 -0
  8. package/dist/cli-profile-context.js +13 -0
  9. package/dist/command-manifest.d.ts +15 -0
  10. package/dist/command-manifest.js +23 -1
  11. package/dist/command-support.d.ts +438 -0
  12. package/dist/command-support.js +1610 -0
  13. package/dist/commands/action-column.d.ts +3 -0
  14. package/dist/commands/action-column.js +43 -0
  15. package/dist/commands/activation.d.ts +3 -0
  16. package/dist/commands/activation.js +24 -0
  17. package/dist/commands/admin.d.ts +3 -0
  18. package/dist/commands/admin.js +347 -0
  19. package/dist/commands/ads.d.ts +3 -0
  20. package/dist/commands/ads.js +62 -0
  21. package/dist/commands/agent.d.ts +3 -0
  22. package/dist/commands/agent.js +274 -0
  23. package/dist/commands/api-keys.d.ts +3 -0
  24. package/dist/commands/api-keys.js +77 -0
  25. package/dist/commands/approvals.d.ts +3 -0
  26. package/dist/commands/approvals.js +518 -0
  27. package/dist/commands/auth.d.ts +3 -0
  28. package/dist/commands/auth.js +230 -0
  29. package/dist/commands/billing.d.ts +3 -0
  30. package/dist/commands/billing.js +357 -0
  31. package/dist/commands/blueprints.d.ts +3 -0
  32. package/dist/commands/blueprints.js +312 -0
  33. package/dist/commands/budget.d.ts +3 -0
  34. package/dist/commands/budget.js +55 -0
  35. package/dist/commands/callables.d.ts +3 -0
  36. package/dist/commands/callables.js +111 -0
  37. package/dist/commands/capabilities.d.ts +3 -0
  38. package/dist/commands/capabilities.js +44 -0
  39. package/dist/commands/cells.d.ts +3 -0
  40. package/dist/commands/cells.js +94 -0
  41. package/dist/commands/columns.d.ts +3 -0
  42. package/dist/commands/columns.js +1628 -0
  43. package/dist/commands/commands.d.ts +3 -0
  44. package/dist/commands/commands.js +45 -0
  45. package/dist/commands/comments.d.ts +3 -0
  46. package/dist/commands/comments.js +188 -0
  47. package/dist/commands/companies.d.ts +3 -0
  48. package/dist/commands/companies.js +312 -0
  49. package/dist/commands/connections.d.ts +3 -0
  50. package/dist/commands/connections.js +39 -0
  51. package/dist/commands/context.d.ts +3 -0
  52. package/dist/commands/context.js +170 -0
  53. package/dist/commands/copilot.d.ts +3 -0
  54. package/dist/commands/copilot.js +565 -0
  55. package/dist/commands/crm.d.ts +3 -0
  56. package/dist/commands/crm.js +1672 -0
  57. package/dist/commands/custom-integrations.d.ts +3 -0
  58. package/dist/commands/custom-integrations.js +140 -0
  59. package/dist/commands/dashboards.d.ts +3 -0
  60. package/dist/commands/dashboards.js +240 -0
  61. package/dist/commands/db.d.ts +3 -0
  62. package/dist/commands/db.js +190 -0
  63. package/dist/commands/deliverability.d.ts +3 -0
  64. package/dist/commands/deliverability.js +90 -0
  65. package/dist/commands/directory.d.ts +3 -0
  66. package/dist/commands/directory.js +101 -0
  67. package/dist/commands/domains.d.ts +3 -0
  68. package/dist/commands/domains.js +604 -0
  69. package/dist/commands/egress.d.ts +3 -0
  70. package/dist/commands/egress.js +130 -0
  71. package/dist/commands/email.d.ts +3 -0
  72. package/dist/commands/email.js +49 -0
  73. package/dist/commands/engagement.d.ts +3 -0
  74. package/dist/commands/engagement.js +189 -0
  75. package/dist/commands/enrich-column.d.ts +3 -0
  76. package/dist/commands/enrich-column.js +149 -0
  77. package/dist/commands/enrichment.d.ts +3 -0
  78. package/dist/commands/enrichment.js +49 -0
  79. package/dist/commands/feedback.d.ts +3 -0
  80. package/dist/commands/feedback.js +96 -0
  81. package/dist/commands/feeds.d.ts +3 -0
  82. package/dist/commands/feeds.js +486 -0
  83. package/dist/commands/find.d.ts +3 -0
  84. package/dist/commands/find.js +159 -0
  85. package/dist/commands/followers.d.ts +3 -0
  86. package/dist/commands/followers.js +39 -0
  87. package/dist/commands/formulas.d.ts +3 -0
  88. package/dist/commands/formulas.js +43 -0
  89. package/dist/commands/home.d.ts +3 -0
  90. package/dist/commands/home.js +22 -0
  91. package/dist/commands/inbox.d.ts +3 -0
  92. package/dist/commands/inbox.js +779 -0
  93. package/dist/commands/integrations.d.ts +3 -0
  94. package/dist/commands/integrations.js +290 -0
  95. package/dist/commands/knowledge.d.ts +3 -0
  96. package/dist/commands/knowledge.js +874 -0
  97. package/dist/commands/lead-sourcing.d.ts +3 -0
  98. package/dist/commands/lead-sourcing.js +52 -0
  99. package/dist/commands/limits.d.ts +3 -0
  100. package/dist/commands/limits.js +54 -0
  101. package/dist/commands/linkedin.d.ts +3 -0
  102. package/dist/commands/linkedin.js +275 -0
  103. package/dist/commands/login.d.ts +3 -0
  104. package/dist/commands/login.js +347 -0
  105. package/dist/commands/logout.d.ts +3 -0
  106. package/dist/commands/logout.js +12 -0
  107. package/dist/commands/mailboxes.d.ts +3 -0
  108. package/dist/commands/mailboxes.js +1290 -0
  109. package/dist/commands/managed-inboxes.d.ts +3 -0
  110. package/dist/commands/managed-inboxes.js +361 -0
  111. package/dist/commands/messages.d.ts +3 -0
  112. package/dist/commands/messages.js +78 -0
  113. package/dist/commands/notetaker.d.ts +3 -0
  114. package/dist/commands/notetaker.js +79 -0
  115. package/dist/commands/observability.d.ts +3 -0
  116. package/dist/commands/observability.js +125 -0
  117. package/dist/commands/orgs.d.ts +3 -0
  118. package/dist/commands/orgs.js +237 -0
  119. package/dist/commands/people.d.ts +3 -0
  120. package/dist/commands/people.js +353 -0
  121. package/dist/commands/posts.d.ts +3 -0
  122. package/dist/commands/posts.js +139 -0
  123. package/dist/commands/profiles.d.ts +3 -0
  124. package/dist/commands/profiles.js +250 -0
  125. package/dist/commands/projects.d.ts +3 -0
  126. package/dist/commands/projects.js +94 -0
  127. package/dist/commands/prompts.d.ts +3 -0
  128. package/dist/commands/prompts.js +84 -0
  129. package/dist/commands/publishing.d.ts +3 -0
  130. package/dist/commands/publishing.js +1419 -0
  131. package/dist/commands/recipes.d.ts +3 -0
  132. package/dist/commands/recipes.js +120 -0
  133. package/dist/commands/reviews.d.ts +3 -0
  134. package/dist/commands/reviews.js +75 -0
  135. package/dist/commands/rows.d.ts +3 -0
  136. package/dist/commands/rows.js +27 -0
  137. package/dist/commands/runs.d.ts +3 -0
  138. package/dist/commands/runs.js +37 -0
  139. package/dist/commands/search.d.ts +3 -0
  140. package/dist/commands/search.js +182 -0
  141. package/dist/commands/senders.d.ts +3 -0
  142. package/dist/commands/senders.js +393 -0
  143. package/dist/commands/sequences.d.ts +3 -0
  144. package/dist/commands/sequences.js +2322 -0
  145. package/dist/commands/session.d.ts +3 -0
  146. package/dist/commands/session.js +109 -0
  147. package/dist/commands/signals.d.ts +3 -0
  148. package/dist/commands/signals.js +289 -0
  149. package/dist/commands/signup-leads.d.ts +3 -0
  150. package/dist/commands/signup-leads.js +46 -0
  151. package/dist/commands/skills.d.ts +3 -0
  152. package/dist/commands/skills.js +50 -0
  153. package/dist/commands/sourcing.d.ts +3 -0
  154. package/dist/commands/sourcing.js +27 -0
  155. package/dist/commands/status.d.ts +3 -0
  156. package/dist/commands/status.js +51 -0
  157. package/dist/commands/supabase.d.ts +3 -0
  158. package/dist/commands/supabase.js +128 -0
  159. package/dist/commands/support.d.ts +3 -0
  160. package/dist/commands/support.js +651 -0
  161. package/dist/commands/suppressions.d.ts +3 -0
  162. package/dist/commands/suppressions.js +577 -0
  163. package/dist/commands/table-ingestions.d.ts +3 -0
  164. package/dist/commands/table-ingestions.js +145 -0
  165. package/dist/commands/table-runs.d.ts +3 -0
  166. package/dist/commands/table-runs.js +277 -0
  167. package/dist/commands/tables.d.ts +3 -0
  168. package/dist/commands/tables.js +3505 -0
  169. package/dist/commands/tags.d.ts +3 -0
  170. package/dist/commands/tags.js +147 -0
  171. package/dist/commands/tools.d.ts +3 -0
  172. package/dist/commands/tools.js +246 -0
  173. package/dist/commands/update.d.ts +3 -0
  174. package/dist/commands/update.js +106 -0
  175. package/dist/commands/verify.d.ts +3 -0
  176. package/dist/commands/verify.js +27 -0
  177. package/dist/commands/viewers.d.ts +3 -0
  178. package/dist/commands/viewers.js +72 -0
  179. package/dist/commands/voice.d.ts +3 -0
  180. package/dist/commands/voice.js +351 -0
  181. package/dist/commands/whatsapp.d.ts +3 -0
  182. package/dist/commands/whatsapp.js +226 -0
  183. package/dist/commands/whoami.d.ts +3 -0
  184. package/dist/commands/whoami.js +110 -0
  185. package/dist/commands/worker.d.ts +3 -0
  186. package/dist/commands/worker.js +60 -0
  187. package/dist/commands/workflows.d.ts +3 -0
  188. package/dist/commands/workflows.js +1752 -0
  189. package/dist/commands/workspace.d.ts +3 -0
  190. package/dist/commands/workspace.js +94 -0
  191. package/dist/compact-list-flags.d.ts +7 -0
  192. package/dist/compact-list-flags.js +12 -0
  193. package/dist/crm-support-flags.js +14 -5
  194. package/dist/customer-operation-commands.js +8 -6
  195. package/dist/diagnostic-uploader.d.ts +3 -1
  196. package/dist/diagnostic-uploader.js +29 -8
  197. package/dist/help.d.ts +5 -0
  198. package/dist/help.js +22 -0
  199. package/dist/index.d.ts +98 -1
  200. package/dist/index.js +331 -30719
  201. package/dist/local-module-loader.d.ts +4 -0
  202. package/dist/local-module-loader.js +156 -0
  203. package/dist/visual-commands.js +9 -5
  204. package/node_modules/@oxygen/cli-ugc/dist/commands.js +2 -2
  205. package/node_modules/@oxygen/shared/dist/agent-session-schedule.d.ts +36 -0
  206. package/node_modules/@oxygen/shared/dist/agent-session-schedule.js +69 -0
  207. package/node_modules/@oxygen/shared/dist/agent-sessions.d.ts +14 -5
  208. package/node_modules/@oxygen/shared/dist/agent-sessions.js +14 -3
  209. package/node_modules/@oxygen/shared/dist/capability-discovery.js +175 -14
  210. package/node_modules/@oxygen/shared/dist/compact-list-result.d.ts +6 -0
  211. package/node_modules/@oxygen/shared/dist/compact-list-result.js +27 -0
  212. package/node_modules/@oxygen/shared/dist/contracts/agent-sessions.d.ts +12 -1
  213. package/node_modules/@oxygen/shared/dist/contracts/agent-sessions.js +5 -2
  214. package/node_modules/@oxygen/shared/dist/contracts/browser-operations.js +4 -2
  215. package/node_modules/@oxygen/shared/dist/contracts/compact-list-reads.d.ts +57 -0
  216. package/node_modules/@oxygen/shared/dist/contracts/compact-list-reads.js +23 -0
  217. package/node_modules/@oxygen/shared/dist/contracts/crm-support.d.ts +52 -0
  218. package/node_modules/@oxygen/shared/dist/contracts/crm-support.js +43 -2
  219. package/node_modules/@oxygen/shared/dist/contracts/customer-operations.js +20 -16
  220. package/node_modules/@oxygen/shared/dist/contracts/knowledge-content-reads.js +1 -1
  221. package/node_modules/@oxygen/shared/dist/contracts/knowledge-proposal-reads.d.ts +49 -0
  222. package/node_modules/@oxygen/shared/dist/contracts/knowledge-proposal-reads.js +14 -0
  223. package/node_modules/@oxygen/shared/dist/contracts/knowledge-sync.js +1 -1
  224. package/node_modules/@oxygen/shared/dist/contracts/limits-read.js +60 -7
  225. package/node_modules/@oxygen/shared/dist/contracts/operations.d.ts +9 -1
  226. package/node_modules/@oxygen/shared/dist/contracts/operations.js +13 -5
  227. package/node_modules/@oxygen/shared/dist/contracts/publishing-reads.js +1 -1
  228. package/node_modules/@oxygen/shared/dist/contracts/teammates.d.ts +16 -0
  229. package/node_modules/@oxygen/shared/dist/contracts/teammates.js +115 -0
  230. package/node_modules/@oxygen/shared/dist/cost-estimate-view.js +21 -3
  231. package/node_modules/@oxygen/shared/dist/cost-estimate.d.ts +31 -1
  232. package/node_modules/@oxygen/shared/dist/cost-estimate.js +56 -15
  233. package/node_modules/@oxygen/shared/dist/diagnostic-credentials.d.ts +2 -0
  234. package/node_modules/@oxygen/shared/dist/diagnostic-credentials.js +2 -0
  235. package/node_modules/@oxygen/shared/dist/diagnostic-lock.js +71 -44
  236. package/node_modules/@oxygen/shared/dist/diagnostic-spool.d.ts +18 -0
  237. package/node_modules/@oxygen/shared/dist/diagnostic-spool.js +348 -0
  238. package/node_modules/@oxygen/shared/dist/diagnostic-storage-failure.d.ts +10 -0
  239. package/node_modules/@oxygen/shared/dist/diagnostic-storage-failure.js +42 -0
  240. package/node_modules/@oxygen/shared/dist/diagnostic-storage.d.ts +1 -1
  241. package/node_modules/@oxygen/shared/dist/diagnostic-storage.js +59 -213
  242. package/node_modules/@oxygen/shared/dist/diagnostics.js +3 -2
  243. package/node_modules/@oxygen/shared/dist/email-dsn.d.ts +16 -5
  244. package/node_modules/@oxygen/shared/dist/email-dsn.js +97 -1
  245. package/node_modules/@oxygen/shared/dist/emailguard-placement-probe.js +5 -0
  246. package/node_modules/@oxygen/shared/dist/enrichment-intents.js +4 -5
  247. package/node_modules/@oxygen/shared/dist/file-import.d.ts +8 -0
  248. package/node_modules/@oxygen/shared/dist/file-import.js +21 -2
  249. package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +30 -0
  250. package/node_modules/@oxygen/shared/dist/hosted-ai.js +20 -0
  251. package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.d.ts +6 -2
  252. package/node_modules/@oxygen/shared/dist/knowledge-seed-content.d.ts +17 -7
  253. package/node_modules/@oxygen/shared/dist/knowledge-seed-content.js +81 -17
  254. package/node_modules/@oxygen/shared/dist/langfuse.js +8 -4
  255. package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.d.ts +1 -1
  256. package/node_modules/@oxygen/shared/dist/mailbox-import.d.ts +6 -3
  257. package/node_modules/@oxygen/shared/dist/mailbox-import.js +9 -9
  258. package/node_modules/@oxygen/shared/dist/mcp-server-info.d.ts +8 -0
  259. package/node_modules/@oxygen/shared/dist/mcp-server-info.js +10 -0
  260. package/node_modules/@oxygen/shared/dist/object-storage.d.ts +10 -0
  261. package/node_modules/@oxygen/shared/dist/object-storage.js +14 -0
  262. package/node_modules/@oxygen/shared/dist/plan-limits-view.d.ts +5 -0
  263. package/node_modules/@oxygen/shared/dist/plan-limits-view.js +17 -1
  264. package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +1 -1
  265. package/node_modules/@oxygen/shared/dist/pricing-sheet.js +1 -1
  266. package/node_modules/@oxygen/shared/dist/provider-selection.d.ts +15 -0
  267. package/node_modules/@oxygen/shared/dist/provider-selection.js +3 -0
  268. package/node_modules/@oxygen/shared/dist/repricing.d.ts +1 -1
  269. package/node_modules/@oxygen/shared/dist/repricing.js +2 -2
  270. package/node_modules/@oxygen/shared/dist/schedule-label.d.ts +6 -0
  271. package/node_modules/@oxygen/shared/dist/schedule-label.js +12 -0
  272. package/node_modules/@oxygen/shared/dist/sequence-failures.d.ts +1 -0
  273. package/node_modules/@oxygen/shared/dist/sequence-failures.js +20 -6
  274. package/node_modules/@oxygen/shared/dist/teammate-groups.d.ts +55 -0
  275. package/node_modules/@oxygen/shared/dist/teammate-groups.js +74 -0
  276. package/node_modules/@oxygen/shared/dist/teammate-messages.d.ts +52 -0
  277. package/node_modules/@oxygen/shared/dist/teammate-messages.js +88 -0
  278. package/node_modules/@oxygen/shared/dist/teammate-notes.d.ts +58 -0
  279. package/node_modules/@oxygen/shared/dist/teammate-notes.js +73 -0
  280. package/node_modules/@oxygen/shared/dist/teammate-routines.d.ts +95 -0
  281. package/node_modules/@oxygen/shared/dist/teammate-routines.js +266 -0
  282. package/node_modules/@oxygen/shared/dist/teammate-tasks.d.ts +56 -0
  283. package/node_modules/@oxygen/shared/dist/teammate-tasks.js +114 -0
  284. package/node_modules/@oxygen/shared/dist/teammates.d.ts +78 -0
  285. package/node_modules/@oxygen/shared/dist/teammates.js +140 -0
  286. package/node_modules/@oxygen/shared/dist/user-capability-routing.js +120 -0
  287. package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -1
  288. package/node_modules/@oxygen/shared/dist/version.generated.js +1 -1
  289. package/node_modules/@oxygen/shared/dist/visual-render.d.ts +9 -1
  290. package/node_modules/@oxygen/shared/dist/visual-render.js +12 -5
  291. package/node_modules/@oxygen/shared/dist/warmup-metrics.d.ts +5 -0
  292. package/node_modules/@oxygen/shared/dist/warmup-metrics.js +44 -0
  293. package/package.json +1 -1
@@ -0,0 +1,4 @@
1
+ import { type RecipeDefinition } from "@oxygen/recipe-sdk";
2
+ export declare function loadRecipeFromBundle(bundle: string, filePath: string): Promise<RecipeDefinition>;
3
+ export declare function importJavaScriptWorkflowModule(absolutePath: string, source: string): Promise<Record<string, unknown>>;
4
+ export declare function importTranspiledWorkflowModule(absolutePath: string, source: string): Promise<Record<string, unknown>>;
@@ -0,0 +1,156 @@
1
+ import { isRecipeDefinition } from "@oxygen/recipe-sdk";
2
+ import { OxygenError } from "@oxygen/shared/cli-result";
3
+ import { createHash } from "node:crypto";
4
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
5
+ import { tmpdir } from "node:os";
6
+ import { pathToFileURL } from "node:url";
7
+ // Escape Next static analysis (the CLI is bundled by tsc, but mirror the
8
+ // worker's escape so both load identically).
9
+ // skipcq: JS-R1003 — intentional dynamic-import escape mirrored from the worker; not arbitrary code execution
10
+ const dynamicRecipeImport = new Function("specifier", "return import(specifier);");
11
+ async function importRecipeModule(specifier) {
12
+ try {
13
+ return await dynamicRecipeImport(specifier);
14
+ }
15
+ catch (error) {
16
+ if (error instanceof TypeError && error.message.includes("dynamic import callback")) {
17
+ return await import(specifier);
18
+ }
19
+ throw error;
20
+ }
21
+ }
22
+ export async function loadRecipeFromBundle(bundle, filePath) {
23
+ const dir = mkdtempSync(`${tmpdir()}/oxygen-recipe-`);
24
+ const compiledPath = `${dir}/recipe.mjs`;
25
+ writeFileSync(compiledPath, bundle, "utf8");
26
+ try {
27
+ const url = pathToFileURL(compiledPath);
28
+ url.searchParams.set("v", createHash("sha256").update(bundle).digest("hex").slice(0, 16));
29
+ const mod = await importRecipeModule(url.href);
30
+ const candidate = mod.default ?? mod.recipe ?? mod.workflow;
31
+ if (!isRecipeDefinition(candidate)) {
32
+ throw new OxygenError("invalid_workflow_file", "Recipe module must export a defineRecipe() result as default.", {
33
+ details: { file: filePath },
34
+ exitCode: 1,
35
+ });
36
+ }
37
+ return candidate;
38
+ }
39
+ finally {
40
+ rmSync(dir, { recursive: true, force: true });
41
+ }
42
+ }
43
+ export async function importJavaScriptWorkflowModule(absolutePath, source) {
44
+ const url = pathToFileURL(absolutePath);
45
+ url.searchParams.set("v", createHash("sha256").update(source).digest("hex").slice(0, 16));
46
+ return await import(url.href);
47
+ }
48
+ export async function importTranspiledWorkflowModule(absolutePath, source) {
49
+ if (/\bfrom\s+["']\.\.?\//.test(source) || /\bimport\s*\(\s*["']\.\.?\//.test(source)) {
50
+ throw new OxygenError("unsupported_workflow_file", "TypeScript workflow files cannot use relative imports in workflow modules.", {
51
+ details: { file: absolutePath },
52
+ exitCode: 1,
53
+ });
54
+ }
55
+ const ts = await import("typescript");
56
+ const transpiled = ts.transpileModule(source, {
57
+ fileName: absolutePath,
58
+ compilerOptions: {
59
+ module: ts.ModuleKind.ESNext,
60
+ target: ts.ScriptTarget.ES2022,
61
+ moduleResolution: ts.ModuleResolutionKind.NodeNext,
62
+ esModuleInterop: true,
63
+ },
64
+ }).outputText;
65
+ const dir = mkdtempSync(`${tmpdir()}/oxygen-workflow-`);
66
+ const workflowsUrl = await resolveWorkflowRuntimeModuleUrl(dir);
67
+ const rewritten = transpiled
68
+ .replaceAll("from \"@oxygen/workflows\"", `from "${workflowsUrl}"`)
69
+ .replaceAll("from '@oxygen/workflows'", `from "${workflowsUrl}"`);
70
+ const compiledPath = `${dir}/workflow.mjs`;
71
+ writeFileSync(compiledPath, rewritten, "utf8");
72
+ try {
73
+ return await importJavaScriptWorkflowModule(compiledPath, rewritten);
74
+ }
75
+ finally {
76
+ rmSync(dir, { recursive: true, force: true });
77
+ }
78
+ }
79
+ async function resolveWorkflowRuntimeModuleUrl(tempDir) {
80
+ try {
81
+ return await import.meta.resolve("@oxygen/workflows");
82
+ }
83
+ catch {
84
+ const shimPath = `${tempDir}/oxygen-workflows-shim.mjs`;
85
+ writeFileSync(shimPath, workflowRuntimeShimSource(), "utf8");
86
+ return pathToFileURL(shimPath).href;
87
+ }
88
+ }
89
+ function workflowRuntimeShimSource() {
90
+ return `
91
+ export function defineWorkflow(input) {
92
+ return {
93
+ __oxygen_workflow_definition: true,
94
+ id: input.id,
95
+ name: input.name,
96
+ ...(input.status ? { status: input.status } : {}),
97
+ ...(input.specification ? { specification: input.specification } : {}),
98
+ ...(input.trigger ? { trigger: input.trigger } : {}),
99
+ ...(input.inputSchema ? { inputSchema: input.inputSchema } : {}),
100
+ steps: input.steps,
101
+ };
102
+ }
103
+ export function apiTrigger(input = {}) {
104
+ return { type: "api", ...(input.status ? { status: input.status } : {}) };
105
+ }
106
+ export function webhookTrigger(input) {
107
+ return {
108
+ type: "webhook",
109
+ trigger_id: input.id,
110
+ ...(input.name !== undefined ? { trigger_name: input.name } : {}),
111
+ secret_required: input.secret ?? true,
112
+ ...(input.idempotencyKeyPath !== undefined ? { idempotency_key_path: input.idempotencyKeyPath } : {}),
113
+ ...(input.status ? { status: input.status } : {}),
114
+ };
115
+ }
116
+ export function cronTrigger(input) {
117
+ return {
118
+ type: "cron",
119
+ cron: input.cron,
120
+ ...(input.timezone !== undefined ? { timezone: input.timezone } : {}),
121
+ ...(input.status ? { status: input.status } : {}),
122
+ };
123
+ }
124
+ export function eventTrigger(input) {
125
+ return {
126
+ type: "event",
127
+ source: input.source,
128
+ event: input.event,
129
+ ...(input.filters ? { filters: input.filters } : {}),
130
+ ...(input.idempotencyKeyPath !== undefined ? { idempotency_key_path: input.idempotencyKeyPath } : {}),
131
+ ...(input.status ? { status: input.status } : {}),
132
+ };
133
+ }
134
+ export function transformStep(input) {
135
+ return {
136
+ __oxygen_workflow_step: true,
137
+ kind: "transform",
138
+ id: input.id,
139
+ ...(input.description ? { description: input.description } : {}),
140
+ run: input.run,
141
+ };
142
+ }
143
+ export function toolStep(input) {
144
+ return {
145
+ __oxygen_workflow_step: true,
146
+ kind: "tool",
147
+ id: input.id,
148
+ ...(input.description ? { description: input.description } : {}),
149
+ tool: input.tool,
150
+ ...(input.effect ? { effect: input.effect } : {}),
151
+ ...(input.mode ? { mode: input.mode } : {}),
152
+ payload: input.payload,
153
+ };
154
+ }
155
+ `;
156
+ }
@@ -1,3 +1,4 @@
1
+ import { Option } from "commander";
1
2
  import { createHash } from "node:crypto";
2
3
  import { readFileSync, statSync, writeFileSync } from "node:fs";
3
4
  import { resolve } from "node:path";
@@ -31,16 +32,19 @@ export function registerVisualCommands(program, handle) {
31
32
  writeFileSync(options.out, bytes, { flag: "wx", mode: 0o600 });
32
33
  return { path: resolve(options.out), ...data.file };
33
34
  }));
34
- visuals.command("render-preview").description("Preview rendering without starting paid compute.")
35
+ visuals.command("render-preview").description("Preview rendering without starting compute; rendering is free.")
35
36
  .requiredOption("--source-file-ids <ids>", "Comma-separated HTML file UUIDs in page order.")
36
37
  .option("--width <pixels>", "CSS pixel width.", "1080").option("--height <pixels>", "CSS pixel height.", "1350")
37
38
  .option("--scale <1|2>", "PNG scale.", "1").option("--formats <png,pdf>", "Output formats.", "png")
38
39
  .option("--json", "Print a JSON envelope.")
39
40
  .action((options) => handle("visuals render preview", options, () => requestOxygen("/api/cli/visuals/renders", { method: "POST", body: { source_file_ids: options.sourceFileIds.split(",").map((s) => s.trim()), width: Number(options.width), height: Number(options.height), scale: Number(options.scale), formats: options.formats.split(",") } })));
40
- visuals.command("render-start <render-id>").description("Approve an exact preview and enqueue one idempotent render job.")
41
- .requiredOption("--scope-hash <hash>", "Exact preview scope hash.").requiredOption("--max-credits <credits>", "Approved ceiling from preview.")
42
- .requiredOption("--approved", "Authorize this exact render.").option("--json", "Print a JSON envelope.")
43
- .action((id, options) => handle("visuals render start", options, () => requestOxygen(`/api/cli/visuals/renders/${encodeURIComponent(id)}`, { method: "POST", body: { scope_hash: options.scopeHash, max_credits: Number(options.maxCredits), approved: options.approved } })));
41
+ visuals.command("render-start <render-id>").description("Start an exact preview as one idempotent render job; rendering is free.")
42
+ .requiredOption("--scope-hash <hash>", "Exact preview scope hash.")
43
+ // Rendering became free on 2026-10-14; the approval flags it needed are retired.
44
+ .addOption(new Option("--max-credits <credits>", "Deprecated: rendering is free. Still accepted so older scripts keep running.").hideHelp())
45
+ .addOption(new Option("--approved", "Deprecated: rendering is free. Still accepted so older scripts keep running.").hideHelp())
46
+ .option("--json", "Print a JSON envelope.")
47
+ .action((id, options) => handle("visuals render start", options, () => requestOxygen(`/api/cli/visuals/renders/${encodeURIComponent(id)}`, { method: "POST", body: { scope_hash: options.scopeHash } })));
44
48
  visuals.command("render-get <render-id>").description("Read render state and output downloads; optionally wait for a terminal state.")
45
49
  .option("--wait", "Poll every 2 seconds until completed, failed, cancelled or effect_unknown; starts no render.")
46
50
  .option("--timeout-seconds <n>", "Maximum wait with --wait, from 1 to 600 seconds. Defaults to 180.")
@@ -141,7 +141,7 @@ export function registerUgcCommands(program, { request: requestOxygen, handle })
141
141
  }));
142
142
  group("analytics")
143
143
  .command("get")
144
- .description("Read UGC analytics in the active workspace. Read-only. The brand workspace sees every creator; a creator workspace only ever gets its own row, with or without --participation-id.")
144
+ .description("Read UGC analytics in the active workspace. Read-only. Find available program IDs with `ugc programs list --json`. The brand workspace sees every creator; a creator workspace only ever gets its own row, with or without --participation-id.")
145
145
  .requiredOption("--program-id <id>", "Program ID.")
146
146
  .option("--participation-id <id>", "Creator participation ID.")
147
147
  .option("--post-cursor <cursor>", "Next post_performance page from next_post_cursor; totals still cover all enrolled posts.")
@@ -1035,7 +1035,7 @@ export function registerUgcCommands(program, { request: requestOxygen, handle })
1035
1035
  {
1036
1036
  action: "sponsorship_preview",
1037
1037
  command: "sponsorship preview",
1038
- description: "Preview sponsoring creators who already joined, as a signed-in master admin: funding is card (seat plus 10,000-credit grant) or credits (one LinkedIn reservation per creator). Org API keys cannot quote. To sponsor creators who have not joined yet, invite them with creators invite --sponsor.",
1038
+ description: "Preview card or credit sponsorship costs as a signed-in master admin; may apply due plan grants or expiry. Card funds a seat plus 10,000 credits; credits reserve one LinkedIn account per joined creator. Org API keys cannot quote. Before creators join, use creators invite --sponsor.",
1039
1039
  fields: [
1040
1040
  {
1041
1041
  name: "program_id",
@@ -0,0 +1,36 @@
1
+ /** The original kind, and the default when `kind` is absent. */
2
+ export type AgentSessionIntervalSchedule = {
3
+ kind?: "interval";
4
+ interval_minutes: number;
5
+ min_interval_minutes: number;
6
+ max_interval_minutes: number;
7
+ };
8
+ /** Wakes at each cron time in `timezone`; the session cannot move its own next wake. */
9
+ export type AgentSessionCronSchedule = {
10
+ kind: "cron";
11
+ cron: string;
12
+ timezone: string;
13
+ };
14
+ export type AgentSessionSchedule = AgentSessionIntervalSchedule | AgentSessionCronSchedule;
15
+ /** The fastest any session may wake, whichever kind of schedule it has. */
16
+ export declare const AGENT_SESSION_MIN_INTERVAL_MINUTES = 5;
17
+ export declare function agentSessionScheduleKind(schedule: AgentSessionSchedule): "interval" | "cron";
18
+ /**
19
+ * What is wrong with a schedule, or null. A cron expression is checked for
20
+ * syntax and its zone for existence here; whether it fires, and no more often
21
+ * than every five minutes, needs the scheduler and is checked by the host.
22
+ */
23
+ export declare function agentSessionScheduleProblem(schedule: unknown): string | null;
24
+ /** The schedule in words, a cron one with its zone: "Weekdays at 09:00 (Europe/Berlin)". */
25
+ export declare function describeAgentSessionSchedule(schedule: AgentSessionSchedule): string;
26
+ export type NextCronRunAfter = (input: {
27
+ cron: string;
28
+ timezone: string;
29
+ after: Date;
30
+ }) => Date;
31
+ /**
32
+ * When a cron session next wakes after `after`, from the host's scheduler; null
33
+ * for an interval session, whose next wake the store counts on the database
34
+ * clock. Missed cron times are skipped, never replayed.
35
+ */
36
+ export declare function nextAgentSessionCronWake(schedule: AgentSessionSchedule, after: Date, nextCronRunAfter: NextCronRunAfter): Date | null;
@@ -0,0 +1,69 @@
1
+ // When an ongoing Agent session wakes (ADR 0011 sessions; ADR 0032 routines):
2
+ // every N minutes, or at the times of a cron expression in an IANA time zone.
3
+ //
4
+ // One owner for the shape, its validation and its words, because the session
5
+ // store, the web, the worker and a teammate's routine card all read it. Where
6
+ // the next cron time falls is the Workflows scheduler's answer
7
+ // (`nextCronRunAfter`), which this layer cannot import: hosts pass it in.
8
+ import { humanizeCronSchedule, isCronSyntax } from "./schedule-label.js";
9
+ import { isValidTimeZone } from "./zoned-time.js";
10
+ /** The fastest any session may wake, whichever kind of schedule it has. */
11
+ export const AGENT_SESSION_MIN_INTERVAL_MINUTES = 5;
12
+ const MAX_INTERVAL_MINUTES = 525_600;
13
+ const INTERVAL_FIELDS = ["interval_minutes", "min_interval_minutes", "max_interval_minutes"];
14
+ export function agentSessionScheduleKind(schedule) {
15
+ return schedule.kind === "cron" ? "cron" : "interval";
16
+ }
17
+ /**
18
+ * What is wrong with a schedule, or null. A cron expression is checked for
19
+ * syntax and its zone for existence here; whether it fires, and no more often
20
+ * than every five minutes, needs the scheduler and is checked by the host.
21
+ */
22
+ export function agentSessionScheduleProblem(schedule) {
23
+ if (!schedule || typeof schedule !== "object" || Array.isArray(schedule))
24
+ return "Set a schedule.";
25
+ const value = schedule;
26
+ if (value.kind === "cron") {
27
+ if (INTERVAL_FIELDS.some((key) => value[key] !== undefined)) {
28
+ return "A cron schedule wakes at its cron times; leave out the interval fields.";
29
+ }
30
+ if (typeof value.cron !== "string" || !isCronSyntax(value.cron))
31
+ return "Use a five-field cron expression, e.g. \"0 9 * * 1-5\".";
32
+ if (typeof value.timezone !== "string" || !isValidTimeZone(value.timezone))
33
+ return "Use an IANA time zone for the cron schedule, e.g. Europe/Berlin.";
34
+ return null;
35
+ }
36
+ if (value.kind !== undefined && value.kind !== "interval")
37
+ return "Choose an interval or a cron schedule.";
38
+ if (value.cron !== undefined || value.timezone !== undefined)
39
+ return "Set kind to cron to wake at cron times in a time zone.";
40
+ const [interval, min, max] = INTERVAL_FIELDS.map((key) => value[key]);
41
+ const numbers = [interval, min, max].every((field) => typeof field === "number" && Number.isFinite(field));
42
+ if (!numbers || min < AGENT_SESSION_MIN_INTERVAL_MINUTES || max < min
43
+ || interval < min || interval > max || max > MAX_INTERVAL_MINUTES) {
44
+ return "The check interval must fit approved bounds (at least five minutes).";
45
+ }
46
+ return null;
47
+ }
48
+ function everyMinutes(minutes) {
49
+ if (minutes % 1_440 === 0)
50
+ return minutes === 1_440 ? "Every day" : `Every ${minutes / 1_440} days`;
51
+ if (minutes % 60 === 0)
52
+ return minutes === 60 ? "Every hour" : `Every ${minutes / 60} hours`;
53
+ return `Every ${minutes} minutes`;
54
+ }
55
+ /** The schedule in words, a cron one with its zone: "Weekdays at 09:00 (Europe/Berlin)". */
56
+ export function describeAgentSessionSchedule(schedule) {
57
+ if (schedule.kind === "cron") {
58
+ return `${humanizeCronSchedule(schedule.cron) ?? `Cron ${schedule.cron.trim()}`} (${schedule.timezone})`;
59
+ }
60
+ return everyMinutes(schedule.interval_minutes);
61
+ }
62
+ /**
63
+ * When a cron session next wakes after `after`, from the host's scheduler; null
64
+ * for an interval session, whose next wake the store counts on the database
65
+ * clock. Missed cron times are skipped, never replayed.
66
+ */
67
+ export function nextAgentSessionCronWake(schedule, after, nextCronRunAfter) {
68
+ return schedule.kind === "cron" ? nextCronRunAfter({ cron: schedule.cron, timezone: schedule.timezone, after }) : null;
69
+ }
@@ -1,3 +1,4 @@
1
+ import { type AgentSessionSchedule } from "./agent-session-schedule.js";
1
2
  export type AgentSessionStatus = "draft" | "active" | "paused" | "budget_wait" | "completed" | "archived";
2
3
  export type AgentSessionResources = {
3
4
  sequences: string[];
@@ -15,11 +16,7 @@ export type AgentSessionConfig = {
15
16
  template: string;
16
17
  resources: AgentSessionResources;
17
18
  actions: string[];
18
- schedule: {
19
- interval_minutes: number;
20
- min_interval_minutes: number;
21
- max_interval_minutes: number;
22
- };
19
+ schedule: AgentSessionSchedule;
23
20
  budget: {
24
21
  per_run_credits: number;
25
22
  daily_credits: number;
@@ -27,7 +24,19 @@ export type AgentSessionConfig = {
27
24
  };
28
25
  ends_at?: string | undefined;
29
26
  events: string[];
27
+ /**
28
+ * A teammate routine (ADR 0032): set up from its creator's private chat with
29
+ * the teammate, which its reports post into. Only the creator may start,
30
+ * change or message it; anyone may pause it.
31
+ */
32
+ teammate_routine?: AgentSessionTeammateRoutine | undefined;
33
+ };
34
+ export type AgentSessionTeammateRoutine = {
35
+ chat_id: string;
36
+ proposal_id?: string | undefined;
30
37
  };
38
+ /** The routine marker of a session's settings, or null for a general session. */
39
+ export declare function agentSessionTeammateRoutine(config: Pick<AgentSessionConfig, "teammate_routine">): AgentSessionTeammateRoutine | null;
31
40
  export declare function agentSessionsEnabled(env?: Record<string, string | undefined>): boolean;
32
41
  export declare function agentSessionsAvailableTo(env: Record<string, string | undefined>, viewer: {
33
42
  email: string | null | undefined;
@@ -1,6 +1,12 @@
1
1
  import { isStaffEmail } from "./staff.js";
2
2
  import { OxygenError } from "./cli-result.js";
3
3
  import { WORKSPACE_EVENT_CATALOG } from "./workspace-event-catalog.js";
4
+ import { agentSessionScheduleProblem } from "./agent-session-schedule.js";
5
+ /** The routine marker of a session's settings, or null for a general session. */
6
+ export function agentSessionTeammateRoutine(config) {
7
+ const marker = config.teammate_routine;
8
+ return marker && typeof marker.chat_id === "string" ? marker : null;
9
+ }
4
10
  export function agentSessionsEnabled(env = process.env) {
5
11
  return env.OXYGEN_DEPLOY_ENV === "selfhost-dev" && env.OXYGEN_AGENT_SESSIONS_ENABLED === "staff" && env.OXYGEN_AGENTS_ENABLED?.trim().toLowerCase() === "true";
6
12
  }
@@ -109,9 +115,14 @@ export function validateAgentSessionConfig(config, requireResources = true) {
109
115
  fail("Set positive per-run and rolling daily caps; daily must cover one run and per-run cannot exceed 25,000 credits.");
110
116
  if (lifetime !== undefined && (!Number.isFinite(lifetime) || lifetime < perRun))
111
117
  fail("The lifetime cap must cover one run.");
112
- const { interval_minutes: interval, min_interval_minutes: min, max_interval_minutes: max } = config.schedule;
113
- if (![interval, min, max].every(Number.isFinite) || min < 5 || max < min || interval < min || interval > max || max > 525600)
114
- fail("The check interval must fit approved bounds (at least five minutes).");
118
+ const scheduleProblem = agentSessionScheduleProblem(config.schedule);
119
+ if (scheduleProblem)
120
+ fail(scheduleProblem);
121
+ const routine = config.teammate_routine;
122
+ if (routine !== undefined && (!routine || typeof routine.chat_id !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(routine.chat_id)
123
+ || (routine.proposal_id !== undefined && (typeof routine.proposal_id !== "string" || !routine.proposal_id.trim() || routine.proposal_id.length > 64)))) {
124
+ fail("An Oxygent routine names the chat it reports into by its session ID.");
125
+ }
115
126
  if (config.ends_at && !Number.isFinite(Date.parse(config.ends_at)))
116
127
  fail("Use an ISO date for the end time.");
117
128
  if (config.actions.some(name => !AGENT_SESSION_ADAPTERS[name] || AGENT_SESSION_ADAPTERS[name].read))