@oxygen-agent/cli 1.1014.136 → 1.1014.618
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/admin-primary-providers-render.js +27 -19
- package/dist/cli-output.d.ts +12 -0
- package/dist/cli-output.js +395 -0
- package/dist/cli-paths.d.ts +1 -0
- package/dist/cli-paths.js +3 -0
- package/dist/cli-profile-context.d.ts +3 -0
- package/dist/cli-profile-context.js +13 -0
- package/dist/command-manifest.d.ts +15 -0
- package/dist/command-manifest.js +23 -1
- package/dist/command-support.d.ts +438 -0
- package/dist/command-support.js +1610 -0
- package/dist/commands/action-column.d.ts +3 -0
- package/dist/commands/action-column.js +43 -0
- package/dist/commands/activation.d.ts +3 -0
- package/dist/commands/activation.js +24 -0
- package/dist/commands/admin.d.ts +3 -0
- package/dist/commands/admin.js +347 -0
- package/dist/commands/ads.d.ts +3 -0
- package/dist/commands/ads.js +62 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.js +274 -0
- package/dist/commands/api-keys.d.ts +3 -0
- package/dist/commands/api-keys.js +77 -0
- package/dist/commands/approvals.d.ts +3 -0
- package/dist/commands/approvals.js +518 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.js +230 -0
- package/dist/commands/billing.d.ts +3 -0
- package/dist/commands/billing.js +357 -0
- package/dist/commands/blueprints.d.ts +3 -0
- package/dist/commands/blueprints.js +312 -0
- package/dist/commands/budget.d.ts +3 -0
- package/dist/commands/budget.js +55 -0
- package/dist/commands/callables.d.ts +3 -0
- package/dist/commands/callables.js +111 -0
- package/dist/commands/capabilities.d.ts +3 -0
- package/dist/commands/capabilities.js +44 -0
- package/dist/commands/cells.d.ts +3 -0
- package/dist/commands/cells.js +94 -0
- package/dist/commands/columns.d.ts +3 -0
- package/dist/commands/columns.js +1628 -0
- package/dist/commands/commands.d.ts +3 -0
- package/dist/commands/commands.js +45 -0
- package/dist/commands/comments.d.ts +3 -0
- package/dist/commands/comments.js +188 -0
- package/dist/commands/companies.d.ts +3 -0
- package/dist/commands/companies.js +312 -0
- package/dist/commands/connections.d.ts +3 -0
- package/dist/commands/connections.js +39 -0
- package/dist/commands/context.d.ts +3 -0
- package/dist/commands/context.js +170 -0
- package/dist/commands/copilot.d.ts +3 -0
- package/dist/commands/copilot.js +565 -0
- package/dist/commands/crm.d.ts +3 -0
- package/dist/commands/crm.js +1669 -0
- package/dist/commands/custom-integrations.d.ts +3 -0
- package/dist/commands/custom-integrations.js +140 -0
- package/dist/commands/dashboards.d.ts +3 -0
- package/dist/commands/dashboards.js +240 -0
- package/dist/commands/db.d.ts +3 -0
- package/dist/commands/db.js +190 -0
- package/dist/commands/deliverability.d.ts +3 -0
- package/dist/commands/deliverability.js +90 -0
- package/dist/commands/directory.d.ts +3 -0
- package/dist/commands/directory.js +101 -0
- package/dist/commands/domains.d.ts +3 -0
- package/dist/commands/domains.js +604 -0
- package/dist/commands/egress.d.ts +3 -0
- package/dist/commands/egress.js +130 -0
- package/dist/commands/email.d.ts +3 -0
- package/dist/commands/email.js +49 -0
- package/dist/commands/engagement.d.ts +3 -0
- package/dist/commands/engagement.js +189 -0
- package/dist/commands/enrich-column.d.ts +3 -0
- package/dist/commands/enrich-column.js +149 -0
- package/dist/commands/enrichment.d.ts +3 -0
- package/dist/commands/enrichment.js +49 -0
- package/dist/commands/feedback.d.ts +3 -0
- package/dist/commands/feedback.js +96 -0
- package/dist/commands/feeds.d.ts +3 -0
- package/dist/commands/feeds.js +486 -0
- package/dist/commands/find.d.ts +3 -0
- package/dist/commands/find.js +159 -0
- package/dist/commands/followers.d.ts +3 -0
- package/dist/commands/followers.js +39 -0
- package/dist/commands/formulas.d.ts +3 -0
- package/dist/commands/formulas.js +43 -0
- package/dist/commands/home.d.ts +3 -0
- package/dist/commands/home.js +22 -0
- package/dist/commands/inbox.d.ts +3 -0
- package/dist/commands/inbox.js +779 -0
- package/dist/commands/integrations.d.ts +3 -0
- package/dist/commands/integrations.js +290 -0
- package/dist/commands/knowledge.d.ts +3 -0
- package/dist/commands/knowledge.js +874 -0
- package/dist/commands/lead-sourcing.d.ts +3 -0
- package/dist/commands/lead-sourcing.js +52 -0
- package/dist/commands/limits.d.ts +3 -0
- package/dist/commands/limits.js +54 -0
- package/dist/commands/linkedin.d.ts +3 -0
- package/dist/commands/linkedin.js +275 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.js +347 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.js +12 -0
- package/dist/commands/mailboxes.d.ts +3 -0
- package/dist/commands/mailboxes.js +1290 -0
- package/dist/commands/managed-inboxes.d.ts +3 -0
- package/dist/commands/managed-inboxes.js +361 -0
- package/dist/commands/messages.d.ts +3 -0
- package/dist/commands/messages.js +78 -0
- package/dist/commands/notetaker.d.ts +3 -0
- package/dist/commands/notetaker.js +79 -0
- package/dist/commands/observability.d.ts +3 -0
- package/dist/commands/observability.js +125 -0
- package/dist/commands/orgs.d.ts +3 -0
- package/dist/commands/orgs.js +237 -0
- package/dist/commands/people.d.ts +3 -0
- package/dist/commands/people.js +353 -0
- package/dist/commands/posts.d.ts +3 -0
- package/dist/commands/posts.js +139 -0
- package/dist/commands/profiles.d.ts +3 -0
- package/dist/commands/profiles.js +250 -0
- package/dist/commands/projects.d.ts +3 -0
- package/dist/commands/projects.js +94 -0
- package/dist/commands/prompts.d.ts +3 -0
- package/dist/commands/prompts.js +84 -0
- package/dist/commands/publishing.d.ts +3 -0
- package/dist/commands/publishing.js +1419 -0
- package/dist/commands/recipes.d.ts +3 -0
- package/dist/commands/recipes.js +120 -0
- package/dist/commands/reviews.d.ts +3 -0
- package/dist/commands/reviews.js +75 -0
- package/dist/commands/rows.d.ts +3 -0
- package/dist/commands/rows.js +27 -0
- package/dist/commands/runs.d.ts +3 -0
- package/dist/commands/runs.js +37 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.js +182 -0
- package/dist/commands/senders.d.ts +3 -0
- package/dist/commands/senders.js +393 -0
- package/dist/commands/sequences.d.ts +3 -0
- package/dist/commands/sequences.js +2322 -0
- package/dist/commands/session.d.ts +3 -0
- package/dist/commands/session.js +109 -0
- package/dist/commands/signals.d.ts +3 -0
- package/dist/commands/signals.js +289 -0
- package/dist/commands/signup-leads.d.ts +3 -0
- package/dist/commands/signup-leads.js +46 -0
- package/dist/commands/skills.d.ts +3 -0
- package/dist/commands/skills.js +50 -0
- package/dist/commands/sourcing.d.ts +3 -0
- package/dist/commands/sourcing.js +27 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.js +51 -0
- package/dist/commands/supabase.d.ts +3 -0
- package/dist/commands/supabase.js +128 -0
- package/dist/commands/support.d.ts +3 -0
- package/dist/commands/support.js +651 -0
- package/dist/commands/suppressions.d.ts +3 -0
- package/dist/commands/suppressions.js +577 -0
- package/dist/commands/table-ingestions.d.ts +3 -0
- package/dist/commands/table-ingestions.js +145 -0
- package/dist/commands/table-runs.d.ts +3 -0
- package/dist/commands/table-runs.js +277 -0
- package/dist/commands/tables.d.ts +3 -0
- package/dist/commands/tables.js +3492 -0
- package/dist/commands/tags.d.ts +3 -0
- package/dist/commands/tags.js +147 -0
- package/dist/commands/tools.d.ts +3 -0
- package/dist/commands/tools.js +246 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.js +106 -0
- package/dist/commands/verify.d.ts +3 -0
- package/dist/commands/verify.js +27 -0
- package/dist/commands/viewers.d.ts +3 -0
- package/dist/commands/viewers.js +72 -0
- package/dist/commands/voice.d.ts +3 -0
- package/dist/commands/voice.js +351 -0
- package/dist/commands/whatsapp.d.ts +3 -0
- package/dist/commands/whatsapp.js +226 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.js +110 -0
- package/dist/commands/worker.d.ts +3 -0
- package/dist/commands/worker.js +60 -0
- package/dist/commands/workflows.d.ts +3 -0
- package/dist/commands/workflows.js +1752 -0
- package/dist/commands/workspace.d.ts +3 -0
- package/dist/commands/workspace.js +94 -0
- package/dist/compact-list-flags.d.ts +7 -0
- package/dist/compact-list-flags.js +12 -0
- package/dist/crm-support-flags.js +14 -5
- package/dist/customer-operation-commands.js +8 -6
- package/dist/diagnostic-uploader.d.ts +3 -1
- package/dist/diagnostic-uploader.js +29 -8
- package/dist/help.d.ts +5 -0
- package/dist/help.js +22 -0
- package/dist/index.d.ts +98 -1
- package/dist/index.js +331 -30719
- package/dist/local-module-loader.d.ts +4 -0
- package/dist/local-module-loader.js +156 -0
- package/dist/visual-commands.js +9 -5
- package/node_modules/@oxygen/cli-ugc/dist/commands.js +2 -2
- package/node_modules/@oxygen/shared/dist/agent-session-schedule.d.ts +36 -0
- package/node_modules/@oxygen/shared/dist/agent-session-schedule.js +69 -0
- package/node_modules/@oxygen/shared/dist/agent-sessions.d.ts +14 -5
- package/node_modules/@oxygen/shared/dist/agent-sessions.js +14 -3
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +175 -14
- package/node_modules/@oxygen/shared/dist/compact-list-result.d.ts +6 -0
- package/node_modules/@oxygen/shared/dist/compact-list-result.js +27 -0
- package/node_modules/@oxygen/shared/dist/contracts/agent-sessions.d.ts +12 -1
- package/node_modules/@oxygen/shared/dist/contracts/agent-sessions.js +5 -2
- package/node_modules/@oxygen/shared/dist/contracts/browser-operations.js +4 -2
- package/node_modules/@oxygen/shared/dist/contracts/compact-list-reads.d.ts +57 -0
- package/node_modules/@oxygen/shared/dist/contracts/compact-list-reads.js +23 -0
- package/node_modules/@oxygen/shared/dist/contracts/crm-support.d.ts +52 -0
- package/node_modules/@oxygen/shared/dist/contracts/crm-support.js +43 -2
- package/node_modules/@oxygen/shared/dist/contracts/customer-operations.js +17 -14
- package/node_modules/@oxygen/shared/dist/contracts/knowledge-content-reads.js +1 -1
- package/node_modules/@oxygen/shared/dist/contracts/knowledge-proposal-reads.d.ts +49 -0
- package/node_modules/@oxygen/shared/dist/contracts/knowledge-proposal-reads.js +14 -0
- package/node_modules/@oxygen/shared/dist/contracts/knowledge-sync.js +1 -1
- package/node_modules/@oxygen/shared/dist/contracts/limits-read.js +60 -7
- package/node_modules/@oxygen/shared/dist/contracts/operations.d.ts +9 -1
- package/node_modules/@oxygen/shared/dist/contracts/operations.js +13 -5
- package/node_modules/@oxygen/shared/dist/contracts/publishing-reads.js +1 -1
- package/node_modules/@oxygen/shared/dist/contracts/teammates.d.ts +16 -0
- package/node_modules/@oxygen/shared/dist/contracts/teammates.js +115 -0
- package/node_modules/@oxygen/shared/dist/cost-estimate-view.js +21 -3
- package/node_modules/@oxygen/shared/dist/cost-estimate.d.ts +31 -1
- package/node_modules/@oxygen/shared/dist/cost-estimate.js +56 -15
- package/node_modules/@oxygen/shared/dist/diagnostic-credentials.d.ts +2 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-credentials.js +2 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-lock.js +71 -44
- package/node_modules/@oxygen/shared/dist/diagnostic-spool.d.ts +18 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-spool.js +348 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-storage-failure.d.ts +10 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-storage-failure.js +42 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-storage.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/diagnostic-storage.js +59 -213
- package/node_modules/@oxygen/shared/dist/diagnostics.js +3 -2
- package/node_modules/@oxygen/shared/dist/email-dsn.d.ts +16 -5
- package/node_modules/@oxygen/shared/dist/email-dsn.js +97 -1
- package/node_modules/@oxygen/shared/dist/emailguard-placement-probe.js +5 -0
- package/node_modules/@oxygen/shared/dist/enrichment-intents.js +4 -5
- package/node_modules/@oxygen/shared/dist/file-import.js +5 -2
- package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +30 -0
- package/node_modules/@oxygen/shared/dist/hosted-ai.js +20 -0
- package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.d.ts +6 -2
- package/node_modules/@oxygen/shared/dist/knowledge-seed-content.d.ts +17 -7
- package/node_modules/@oxygen/shared/dist/knowledge-seed-content.js +81 -17
- package/node_modules/@oxygen/shared/dist/langfuse.js +8 -4
- package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/mailbox-import.d.ts +6 -3
- package/node_modules/@oxygen/shared/dist/mailbox-import.js +9 -9
- package/node_modules/@oxygen/shared/dist/mcp-server-info.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/mcp-server-info.js +10 -0
- package/node_modules/@oxygen/shared/dist/object-storage.d.ts +10 -0
- package/node_modules/@oxygen/shared/dist/object-storage.js +14 -0
- package/node_modules/@oxygen/shared/dist/plan-limits-view.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/plan-limits-view.js +17 -1
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +1 -1
- package/node_modules/@oxygen/shared/dist/provider-selection.d.ts +15 -0
- package/node_modules/@oxygen/shared/dist/provider-selection.js +3 -0
- package/node_modules/@oxygen/shared/dist/repricing.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/repricing.js +2 -2
- package/node_modules/@oxygen/shared/dist/schedule-label.d.ts +6 -0
- package/node_modules/@oxygen/shared/dist/schedule-label.js +12 -0
- package/node_modules/@oxygen/shared/dist/sequence-failures.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/sequence-failures.js +20 -6
- package/node_modules/@oxygen/shared/dist/teammate-groups.d.ts +55 -0
- package/node_modules/@oxygen/shared/dist/teammate-groups.js +74 -0
- package/node_modules/@oxygen/shared/dist/teammate-messages.d.ts +52 -0
- package/node_modules/@oxygen/shared/dist/teammate-messages.js +88 -0
- package/node_modules/@oxygen/shared/dist/teammate-notes.d.ts +58 -0
- package/node_modules/@oxygen/shared/dist/teammate-notes.js +73 -0
- package/node_modules/@oxygen/shared/dist/teammate-routines.d.ts +95 -0
- package/node_modules/@oxygen/shared/dist/teammate-routines.js +266 -0
- package/node_modules/@oxygen/shared/dist/teammate-tasks.d.ts +56 -0
- package/node_modules/@oxygen/shared/dist/teammate-tasks.js +114 -0
- package/node_modules/@oxygen/shared/dist/teammates.d.ts +78 -0
- package/node_modules/@oxygen/shared/dist/teammates.js +140 -0
- package/node_modules/@oxygen/shared/dist/user-capability-routing.js +120 -0
- package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.generated.js +1 -1
- package/node_modules/@oxygen/shared/dist/visual-render.d.ts +9 -1
- package/node_modules/@oxygen/shared/dist/visual-render.js +12 -5
- package/node_modules/@oxygen/shared/dist/warmup-metrics.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/warmup-metrics.js +44 -0
- 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
|
+
}
|
package/dist/visual-commands.js
CHANGED
|
@@ -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
|
|
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("
|
|
41
|
-
.requiredOption("--scope-hash <hash>", "Exact preview scope hash.")
|
|
42
|
-
|
|
43
|
-
.
|
|
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
|
|
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
|
|
113
|
-
if (
|
|
114
|
-
fail(
|
|
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))
|