openpond-sdk 0.0.5 → 0.0.7

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 CHANGED
@@ -96,6 +96,31 @@ console.log(result.command.output);
96
96
 
97
97
  The package also exports `createOpenPondSandboxClient`, all public sandbox input and response types, and the OpChat helpers used by the Work loop.
98
98
 
99
+ ## Workflows and scheduled Work
100
+
101
+ Use `openpond.workflows` for model-driven scheduled Work. Workflows use the same Saved Work definitions, conversations, runs, and scheduler as the hosted OpenPond Workflows UI:
102
+
103
+ ```ts
104
+ const workflow = await openpond.workflows.create({
105
+ name: "Morning market brief",
106
+ prompt: "Summarize the overnight market and write the brief to outputs.",
107
+ recurrence: {
108
+ version: 1,
109
+ kind: "weekdays",
110
+ timeZone: "America/New_York",
111
+ startDate: "2026-08-18",
112
+ localTime: "08:30",
113
+ end: { kind: "never" },
114
+ },
115
+ });
116
+
117
+ const catalog = await openpond.workflows.list();
118
+ await openpond.workflows.runNow(workflow.scheduleId);
119
+ await openpond.workflows.update(workflow.scheduleId, { enabled: false });
120
+ ```
121
+
122
+ `openpond.workflows` is distinct from `openpond.sandboxes.createSchedule()`. Workflows schedule model-driven Work and create normal Work conversations and run history. Raw sandbox schedules execute a declared sandbox command or action.
123
+
99
124
  ## Project Actions
100
125
 
101
126
  Project Actions expose typed business functions from a normal Git Project to local OpenPond Work. The website and action wrapper can import the same neutral domain module, so the harness does not duplicate application logic.
package/dist/index.js CHANGED
@@ -1188,7 +1188,8 @@ var OpenPondSandboxClient = class extends OpenPondSandboxInstanceClient {
1188
1188
  return this.requestApiRoot(`/projects?${query.toString()}`).then((payload) => payload.projects);
1189
1189
  }
1190
1190
  upsertProject(input) {
1191
- return this.requestApiRoot("/projects", {
1191
+ const query = new URLSearchParams({ teamId: input.teamId });
1192
+ return this.requestApiRoot(`/projects?${query.toString()}`, {
1192
1193
  method: "POST",
1193
1194
  body: JSON.stringify(input)
1194
1195
  }).then((payload) => payload.project);
@@ -1255,7 +1256,8 @@ var OpenPondSandboxClient = class extends OpenPondSandboxInstanceClient {
1255
1256
  return this.requestApiRoot(`/agents?${query.toString()}`).then((payload) => payload.agents);
1256
1257
  }
1257
1258
  upsertAgent(input) {
1258
- return this.requestApiRoot("/agents", {
1259
+ const query = new URLSearchParams({ teamId: input.teamId });
1260
+ return this.requestApiRoot(`/agents?${query.toString()}`, {
1259
1261
  method: "POST",
1260
1262
  body: JSON.stringify(input)
1261
1263
  }).then((payload) => payload.agent);
@@ -1277,7 +1279,8 @@ var OpenPondSandboxClient = class extends OpenPondSandboxInstanceClient {
1277
1279
  }).then((payload) => payload.agent);
1278
1280
  }
1279
1281
  runAgent(agentId, input) {
1280
- return this.requestApiRoot(`/agents/${encodeURIComponent(agentId)}/run`, {
1282
+ const query = new URLSearchParams({ teamId: input.teamId });
1283
+ return this.requestApiRoot(`/agents/${encodeURIComponent(agentId)}/run?${query.toString()}`, {
1281
1284
  method: "POST",
1282
1285
  headers: {
1283
1286
  Prefer: "respond-async"
@@ -1300,7 +1303,8 @@ var OpenPondSandboxClient = class extends OpenPondSandboxInstanceClient {
1300
1303
  const { teamId: _teamId, ...body } = input;
1301
1304
  return this.requestApiRoot(`/agents/${encodeURIComponent(agentId)}/source/checks?${query.toString()}`, {
1302
1305
  method: "POST",
1303
- body: JSON.stringify(body)
1306
+ body: JSON.stringify(body),
1307
+ timeoutMs: 15 * 60 * 1e3
1304
1308
  });
1305
1309
  }
1306
1310
  publishAgentSource(agentId, input) {
@@ -2476,6 +2480,151 @@ function sleep2(milliseconds, signal) {
2476
2480
  });
2477
2481
  }
2478
2482
 
2483
+ // src/project-actions.ts
2484
+ import { promises as fs } from "node:fs";
2485
+ var OpenPondProjectActionsClient = class {
2486
+ #apiKey;
2487
+ #apiBaseUrl;
2488
+ constructor(input) {
2489
+ this.#apiKey = input.apiKey;
2490
+ this.#apiBaseUrl = input.apiBaseUrl.replace(/\/+$/, "");
2491
+ }
2492
+ async list(input) {
2493
+ const response = await apiFetch(
2494
+ this.#apiBaseUrl,
2495
+ this.#apiKey,
2496
+ projectActionPath(input.projectId, "releases", input.teamId)
2497
+ );
2498
+ return (await readApiJson(response, "List Project Action releases")).releases;
2499
+ }
2500
+ async catalog(input) {
2501
+ const response = await apiFetch(
2502
+ this.#apiBaseUrl,
2503
+ this.#apiKey,
2504
+ projectActionPath(input.projectId, "catalog", input.teamId)
2505
+ );
2506
+ return (await readApiJson(response, "Get Project Action catalog")).catalog;
2507
+ }
2508
+ async publish(input) {
2509
+ const [bundle, runner] = await Promise.all([
2510
+ fs.readFile(input.build.bundlePath),
2511
+ fs.readFile(input.build.runnerPath)
2512
+ ]);
2513
+ const response = await apiFetch(
2514
+ this.#apiBaseUrl,
2515
+ this.#apiKey,
2516
+ projectActionPath(input.projectId, "releases", input.teamId),
2517
+ {
2518
+ method: "POST",
2519
+ body: JSON.stringify({
2520
+ sourceRef: input.sourceRef,
2521
+ sourceCommitSha: input.sourceCommitSha,
2522
+ bundleBase64: bundle.toString("base64"),
2523
+ runnerBase64: runner.toString("base64"),
2524
+ registry: input.build.registry,
2525
+ manifest: input.build.manifest,
2526
+ metadata: input.metadata
2527
+ })
2528
+ }
2529
+ );
2530
+ return (await readApiJson(response, "Publish Project Actions")).release;
2531
+ }
2532
+ async run(input) {
2533
+ const response = await apiFetch(
2534
+ this.#apiBaseUrl,
2535
+ this.#apiKey,
2536
+ projectActionPath(input.projectId, `actions/${encodeURIComponent(input.actionId)}`, input.teamId),
2537
+ {
2538
+ method: "POST",
2539
+ body: JSON.stringify({
2540
+ input: input.value ?? {},
2541
+ releaseId: input.releaseId,
2542
+ idempotencyKey: input.idempotencyKey,
2543
+ callerType: input.callerType ?? "sdk",
2544
+ callerId: input.callerId
2545
+ }),
2546
+ signal: input.signal,
2547
+ timeoutMs: 15 * 60 * 1e3
2548
+ }
2549
+ );
2550
+ return (await readApiJson(response, "Run Project Action")).invocation;
2551
+ }
2552
+ };
2553
+ function projectActionPath(projectId, suffix, teamId) {
2554
+ return `/v1/project-actions/${encodeURIComponent(projectId)}/${suffix}?teamId=${encodeURIComponent(teamId)}`;
2555
+ }
2556
+
2557
+ // src/workflows.ts
2558
+ import { randomUUID as randomUUID2 } from "node:crypto";
2559
+ var OpenPondWorkflowsClient = class {
2560
+ #apiKey;
2561
+ #apiBaseUrl;
2562
+ constructor(input) {
2563
+ this.#apiKey = input.apiKey;
2564
+ this.#apiBaseUrl = input.apiBaseUrl.replace(/\/+$/, "");
2565
+ }
2566
+ async list(options = {}) {
2567
+ return this.#request("", "List Workflows", {
2568
+ signal: options.signal
2569
+ });
2570
+ }
2571
+ async create(input, options = {}) {
2572
+ return this.#request("", "Create Workflow", {
2573
+ method: "POST",
2574
+ body: JSON.stringify({
2575
+ ...input,
2576
+ clientRequestId: input.clientRequestId?.trim() || randomUUID2()
2577
+ }),
2578
+ signal: options.signal
2579
+ });
2580
+ }
2581
+ async update(scheduleId, input, options = {}) {
2582
+ return this.#request(
2583
+ `/schedules/${encodeURIComponent(requiredId(scheduleId, "scheduleId"))}`,
2584
+ "Update Workflow",
2585
+ {
2586
+ method: "PATCH",
2587
+ body: JSON.stringify(input),
2588
+ signal: options.signal
2589
+ }
2590
+ );
2591
+ }
2592
+ async delete(scheduleId, options = {}) {
2593
+ return this.#request(
2594
+ `/schedules/${encodeURIComponent(requiredId(scheduleId, "scheduleId"))}`,
2595
+ "Delete Workflow",
2596
+ { method: "DELETE", signal: options.signal }
2597
+ );
2598
+ }
2599
+ async runNow(scheduleId, input = {}, options = {}) {
2600
+ return this.#request(
2601
+ `/schedules/${encodeURIComponent(requiredId(scheduleId, "scheduleId"))}/run`,
2602
+ "Run Workflow",
2603
+ {
2604
+ method: "POST",
2605
+ body: JSON.stringify({
2606
+ clientRequestId: input.clientRequestId?.trim() || randomUUID2()
2607
+ }),
2608
+ signal: options.signal
2609
+ }
2610
+ );
2611
+ }
2612
+ async #request(suffix, label, options = {}) {
2613
+ const response = await apiFetch(
2614
+ this.#apiBaseUrl,
2615
+ this.#apiKey,
2616
+ `/v1/saved-work${suffix}`,
2617
+ options
2618
+ );
2619
+ return readApiJson(response, label);
2620
+ }
2621
+ };
2622
+ function requiredId(value, label) {
2623
+ const normalized = value.trim();
2624
+ if (!normalized) throw new Error(`${label} is required`);
2625
+ return normalized;
2626
+ }
2627
+
2479
2628
  // ../cloud/dist/sandbox/types/runtime-profiles.js
2480
2629
  var SANDBOX_RUNTIME_PROFILE_IDS = [
2481
2630
  "openpond-generic-v1",
@@ -2488,6 +2637,8 @@ var SANDBOX_RUNTIME_PROFILE_IDS = [
2488
2637
  var OpenPondClient = class {
2489
2638
  sandboxes;
2490
2639
  work;
2640
+ workflows;
2641
+ actions;
2491
2642
  constructor(options) {
2492
2643
  const apiKey = options.apiKey.trim();
2493
2644
  if (!apiKey) throw new Error("OpenPond API key is required");
@@ -2503,6 +2654,8 @@ var OpenPondClient = class {
2503
2654
  chatApiBaseUrl: options.chatApiUrl?.trim() || resolveOpChatApiBaseUrl({ apiBaseUrl, env: {} }),
2504
2655
  sandboxes: this.sandboxes
2505
2656
  });
2657
+ this.workflows = new OpenPondWorkflowsClient({ apiKey, apiBaseUrl });
2658
+ this.actions = new OpenPondProjectActionsClient({ apiKey, apiBaseUrl });
2506
2659
  }
2507
2660
  };
2508
2661
  function createOpenPondClient(options) {
@@ -2511,8 +2664,10 @@ function createOpenPondClient(options) {
2511
2664
  export {
2512
2665
  OpenPondApiError,
2513
2666
  OpenPondClient,
2667
+ OpenPondProjectActionsClient,
2514
2668
  OpenPondSandboxClient,
2515
2669
  OpenPondWorkClient,
2670
+ OpenPondWorkflowsClient,
2516
2671
  SANDBOX_RUNTIME_PROFILE_IDS,
2517
2672
  createOpenPondClient,
2518
2673
  createOpenPondSandboxClient,