openpond-code 0.1.0 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # openpond-code
2
2
 
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 176a699: updated endpoints
8
+
9
+ ## 0.1.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 05f2e19: testing github push
14
+
3
15
  ## 0.1.0
4
16
 
5
17
  - Initial release of the API key CLI.
package/README.md CHANGED
@@ -102,7 +102,7 @@ await client.apps.agentCreate(
102
102
  You can override hosts with `baseUrl`, `apiUrl`, and `toolUrl` in `createClient`, or
103
103
  via `OPENPOND_BASE_URL`, `OPENPOND_API_URL`, and `OPENPOND_TOOL_URL`.
104
104
 
105
- Examples live in `openpond-code/examples`.
105
+ Examples live in `examples`.
106
106
 
107
107
  ## Local TUI
108
108
 
package/dist/api.d.ts CHANGED
@@ -125,6 +125,96 @@ export type AppListItem = {
125
125
  gitBranch: string | null;
126
126
  } | null;
127
127
  };
128
+ export type AppRuntimeSummary = {
129
+ app: {
130
+ appId: string;
131
+ name: string;
132
+ description: string | null;
133
+ teamId: string;
134
+ templateRepoUrl: string | null;
135
+ templateBranch: string | null;
136
+ initialPromptSnapshot: string | null;
137
+ };
138
+ runtime: {
139
+ latestDeployment: {
140
+ id: string;
141
+ status: string;
142
+ isProduction: boolean | null;
143
+ createdAt: string;
144
+ } | null;
145
+ schedules: {
146
+ total: number;
147
+ enabled: number;
148
+ disabled: number;
149
+ };
150
+ notifications: {
151
+ scheduleEmailsEnabled: boolean;
152
+ scheduleTweetsEnabled: boolean;
153
+ };
154
+ toolNotifyEmail: {
155
+ notifyEmailEnabledCount: number;
156
+ toolsConfiguredCount: number;
157
+ };
158
+ lastScheduleRun: {
159
+ id: string;
160
+ status: string;
161
+ executionTime: string;
162
+ scheduleName: string;
163
+ errorMessage: string | null;
164
+ } | null;
165
+ lastToolRun: {
166
+ id: string;
167
+ status: string;
168
+ endpoint: string;
169
+ toolName: string | null;
170
+ method: string | null;
171
+ createdAt: string;
172
+ executionTime: number | null;
173
+ error: string | null;
174
+ } | null;
175
+ };
176
+ wallet: {
177
+ personalWalletAddress: string | null;
178
+ operatingWalletAddress: string | null;
179
+ arbitrum: {
180
+ eth: {
181
+ raw: string;
182
+ formatted: string;
183
+ } | null;
184
+ usdc: {
185
+ raw: string;
186
+ formatted: string;
187
+ } | null;
188
+ };
189
+ hyperliquid: {
190
+ mainnet: {
191
+ accountValue: number | null;
192
+ withdrawable: number | null;
193
+ totalMarginUsed: number | null;
194
+ error?: string;
195
+ };
196
+ testnet: {
197
+ accountValue: number | null;
198
+ withdrawable: number | null;
199
+ totalMarginUsed: number | null;
200
+ error?: string;
201
+ };
202
+ };
203
+ };
204
+ asOf: string;
205
+ };
206
+ export type AssistantMode = "plan" | "performance";
207
+ export type AssistantRunRequest = {
208
+ appId: string;
209
+ mode: AssistantMode;
210
+ prompt: string;
211
+ };
212
+ export type AssistantRunResponse = {
213
+ ok: boolean;
214
+ mode: AssistantMode;
215
+ conversationId: string;
216
+ response: string;
217
+ };
128
218
  export declare function listApps(apiBase: string, token: string, options?: {
129
219
  handle?: string;
130
220
  }): Promise<AppListItem[]>;
@@ -161,6 +251,8 @@ export declare function createAgentFromPrompt(baseUrl: string, token: string, pa
161
251
  export declare function getUserPerformance(baseUrl: string, token: string, options?: {
162
252
  appId?: string;
163
253
  }): Promise<unknown>;
254
+ export declare function getAppRuntimeSummary(baseUrl: string, token: string, appId: string): Promise<AppRuntimeSummary>;
255
+ export declare function runAssistantMode(baseUrl: string, token: string, payload: AssistantRunRequest): Promise<AssistantRunResponse>;
164
256
  export declare function postAgentDigest(baseUrl: string, token: string, body: {
165
257
  content: string;
166
258
  runAt?: string;
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli-package.ts
4
- import {spawn} from "node:child_process";
5
- import {promises as fs3, existsSync} from "node:fs";
4
+ import { spawn } from "node:child_process";
5
+ import { promises as fs3, existsSync } from "node:fs";
6
6
  import path3 from "node:path";
7
- import {stdin as input, stdout as output} from "node:process";
8
- import {createInterface} from "node:readline/promises";
7
+ import { stdin as input, stdout as output } from "node:process";
8
+ import { createInterface } from "node:readline/promises";
9
9
 
10
10
  // src/api.ts
11
11
  async function apiFetch(baseUrl, token, path, init) {
@@ -143,6 +143,28 @@ async function getUserPerformance(baseUrl, token, options) {
143
143
  }
144
144
  return await response.json();
145
145
  }
146
+ async function getAppRuntimeSummary(baseUrl, token, appId) {
147
+ const params = new URLSearchParams({ appId });
148
+ const response = await apiFetch(baseUrl, token, `/apps/summary?${params.toString()}`, {
149
+ method: "GET"
150
+ });
151
+ if (!response.ok) {
152
+ const text = await response.text().catch(() => "");
153
+ throw new Error(`Summary lookup failed: ${response.status} ${text}`);
154
+ }
155
+ return await response.json();
156
+ }
157
+ async function runAssistantMode(baseUrl, token, payload) {
158
+ const response = await apiFetch(baseUrl, token, "/apps/assistant/run", {
159
+ method: "POST",
160
+ body: JSON.stringify(payload)
161
+ });
162
+ if (!response.ok) {
163
+ const text = await response.text().catch(() => "");
164
+ throw new Error(`Assistant run failed: ${response.status} ${text}`);
165
+ }
166
+ return await response.json();
167
+ }
146
168
  async function executeUserTool(baseUrl, token, body) {
147
169
  const response = await apiFetch(baseUrl, token, "/apps/tools/execute", {
148
170
  method: "POST",
@@ -257,10 +279,10 @@ async function getDeploymentDetail(apiBase, token, deploymentId) {
257
279
  const payload = await response.json().catch(() => ({}));
258
280
  return payload.deployment ?? null;
259
281
  }
260
- var normalizeToolPathSegment = function(toolName) {
282
+ function normalizeToolPathSegment(toolName) {
261
283
  const trimmed = toolName.trim().replace(/^\/+/, "");
262
284
  return encodeURIComponent(trimmed || "tool");
263
- };
285
+ }
264
286
  function resolveWorkerBaseUrl(baseUrl) {
265
287
  const trimmed = baseUrl.replace(/\/$/, "");
266
288
  const workerEnv = process.env.OPENPOND_TOOL_URL;
@@ -287,8 +309,7 @@ function resolveWorkerBaseUrl(baseUrl) {
287
309
  if (isLocal && port === "3000") {
288
310
  return trimmed;
289
311
  }
290
- } catch {
291
- }
312
+ } catch {}
292
313
  return trimmed;
293
314
  }
294
315
  async function executeHostedTool(baseUrl, token, payload) {
@@ -320,13 +341,17 @@ async function executeHostedTool(baseUrl, token, payload) {
320
341
  }
321
342
 
322
343
  // src/cache.ts
323
- import {promises as fs} from "node:fs";
344
+ import { promises as fs } from "node:fs";
324
345
  import os from "node:os";
325
346
  import path from "node:path";
326
- var getCachePath = function() {
347
+ var CACHE_DIR = ".openpond";
348
+ var CACHE_FILENAME = "cache.json";
349
+ var DEFAULT_STORE = { version: 1, byKey: {} };
350
+ var DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000;
351
+ function getCachePath() {
327
352
  return path.join(os.homedir(), CACHE_DIR, CACHE_FILENAME);
328
- };
329
- var buildCacheKey = function(apiBase, apiKey) {
353
+ }
354
+ function buildCacheKey(apiBase, apiKey) {
330
355
  const trimmed = apiKey.trim();
331
356
  const hint = trimmed.length > 12 ? `${trimmed.slice(0, 8)}_${trimmed.slice(-4)}` : trimmed;
332
357
  try {
@@ -335,14 +360,14 @@ var buildCacheKey = function(apiBase, apiKey) {
335
360
  } catch {
336
361
  return `${apiBase}:${hint}`;
337
362
  }
338
- };
339
- var isFresh = function(updatedAt, ttlMs) {
363
+ }
364
+ function isFresh(updatedAt, ttlMs) {
340
365
  const timestamp = Date.parse(updatedAt);
341
366
  if (Number.isNaN(timestamp)) {
342
367
  return false;
343
368
  }
344
369
  return Date.now() - timestamp < ttlMs;
345
- };
370
+ }
346
371
  async function loadCache() {
347
372
  try {
348
373
  const raw = await fs.readFile(getCachePath(), "utf-8");
@@ -402,18 +427,16 @@ async function setCachedTools(params) {
402
427
  store.byKey[cacheKey] = bucket;
403
428
  await saveCache(store);
404
429
  }
405
- var CACHE_DIR = ".openpond";
406
- var CACHE_FILENAME = "cache.json";
407
- var DEFAULT_STORE = { version: 1, byKey: {} };
408
- var DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000;
409
430
 
410
431
  // src/config.ts
411
- import {promises as fs2} from "node:fs";
432
+ import { promises as fs2 } from "node:fs";
412
433
  import os2 from "node:os";
413
434
  import path2 from "node:path";
414
- var getGlobalConfigPath = function() {
435
+ var GLOBAL_DIRNAME = ".openpond";
436
+ var GLOBAL_CONFIG_FILENAME = "config.json";
437
+ function getGlobalConfigPath() {
415
438
  return path2.join(os2.homedir(), GLOBAL_DIRNAME, GLOBAL_CONFIG_FILENAME);
416
- };
439
+ }
417
440
  async function loadConfigFile(filePath) {
418
441
  try {
419
442
  const raw = await fs2.readFile(filePath, "utf-8");
@@ -445,8 +468,6 @@ async function saveGlobalConfig(next) {
445
468
  const payload = JSON.stringify(merged, null, 2);
446
469
  await fs2.writeFile(filePath, payload, "utf-8");
447
470
  }
448
- var GLOBAL_DIRNAME = ".openpond";
449
- var GLOBAL_CONFIG_FILENAME = "config.json";
450
471
 
451
472
  // src/stream.ts
452
473
  function normalizeDataFrames(raw) {
@@ -485,7 +506,7 @@ function normalizeDataFrames(raw) {
485
506
  }
486
507
  return { conversationId, items };
487
508
  }
488
- var extractUsage = function(raw) {
509
+ function extractUsage(raw) {
489
510
  const frames = Array.isArray(raw) ? raw : raw && typeof raw === "object" && Array.isArray(raw.data) ? raw.data : [raw];
490
511
  for (const frame of frames) {
491
512
  if (!frame || typeof frame !== "object")
@@ -502,7 +523,7 @@ var extractUsage = function(raw) {
502
523
  return { promptTokens, completionTokens, totalTokens };
503
524
  }
504
525
  return null;
505
- };
526
+ }
506
527
  async function consumeStream(response, callbacks) {
507
528
  if (!response.body) {
508
529
  throw new Error("Missing response body");
@@ -517,8 +538,7 @@ async function consumeStream(response, callbacks) {
517
538
  }
518
539
  try {
519
540
  await reader.cancel();
520
- } catch {
521
- }
541
+ } catch {}
522
542
  callbacks.onStop?.();
523
543
  return true;
524
544
  };
@@ -528,7 +548,8 @@ async function consumeStream(response, callbacks) {
528
548
  break;
529
549
  const chunk = decoder.decode(value, { stream: true });
530
550
  const textChunk = remainder + chunk;
531
- const lines = textChunk.split("\n");
551
+ const lines = textChunk.split(`
552
+ `);
532
553
  remainder = lines.pop() || "";
533
554
  for (const line of lines) {
534
555
  if (!line)
@@ -565,8 +586,7 @@ async function consumeStream(response, callbacks) {
565
586
  if (typeof message === "string") {
566
587
  throw new Error(message);
567
588
  }
568
- } catch {
569
- }
589
+ } catch {}
570
590
  continue;
571
591
  }
572
592
  if (line.startsWith("2:")) {
@@ -589,8 +609,7 @@ async function consumeStream(response, callbacks) {
589
609
  if (await stopIfNeeded()) {
590
610
  return;
591
611
  }
592
- } catch {
593
- }
612
+ } catch {}
594
613
  }
595
614
  if (await stopIfNeeded()) {
596
615
  return;
@@ -623,7 +642,7 @@ function formatStreamItem(item) {
623
642
  }
624
643
 
625
644
  // src/cli-package.ts
626
- var parseArgs = function(argv) {
645
+ function parseArgs(argv) {
627
646
  const args = [...argv];
628
647
  const command = args.shift() || "";
629
648
  const options = {};
@@ -640,18 +659,18 @@ var parseArgs = function(argv) {
640
659
  }
641
660
  }
642
661
  return { command, options, rest };
643
- };
644
- var resolveBaseUrl = function(config2) {
662
+ }
663
+ function resolveBaseUrl(config) {
645
664
  const envBase = process.env.OPENPOND_BASE_URL;
646
- const base = envBase || config2.baseUrl || "https://openpond.ai";
665
+ const base = envBase || config.baseUrl || "https://openpond.ai";
647
666
  return base.replace(/\/$/, "");
648
- };
649
- var resolvePublicApiBaseUrl = function() {
667
+ }
668
+ function resolvePublicApiBaseUrl() {
650
669
  const envBase = process.env.OPENPOND_API_URL;
651
670
  const base = envBase || "https://api.openpond.ai";
652
671
  return base.replace(/\/$/, "");
653
- };
654
- var normalizeTemplateRepoUrl = function(input2, baseUrl) {
672
+ }
673
+ function normalizeTemplateRepoUrl(input2, baseUrl) {
655
674
  const trimmed = input2.trim();
656
675
  if (!trimmed) {
657
676
  throw new Error("template must be non-empty");
@@ -666,23 +685,23 @@ var normalizeTemplateRepoUrl = function(input2, baseUrl) {
666
685
  throw new Error("template must be <owner>/<repo> or a full https URL");
667
686
  }
668
687
  return `${normalizedBase}/${owner}/${repo}.git`;
669
- };
670
- var parseJsonOption = function(value, label) {
688
+ }
689
+ function parseJsonOption(value, label) {
671
690
  try {
672
691
  return JSON.parse(value);
673
692
  } catch {
674
693
  throw new Error(`${label} must be valid JSON`);
675
694
  }
676
- };
677
- var parseBooleanOption = function(value) {
695
+ }
696
+ function parseBooleanOption(value) {
678
697
  if (value === true)
679
698
  return true;
680
699
  if (typeof value === "string") {
681
700
  return value.toLowerCase() === "true";
682
701
  }
683
702
  return false;
684
- };
685
- var parseTimeOption = function(value, label) {
703
+ }
704
+ function parseTimeOption(value, label) {
686
705
  if (typeof value !== "string")
687
706
  return;
688
707
  const trimmed = value.trim();
@@ -695,20 +714,20 @@ var parseTimeOption = function(value, label) {
695
714
  return String(parsed);
696
715
  }
697
716
  throw new Error(`${label} must be a unix ms timestamp or ISO date`);
698
- };
699
- var resolveApiKey = function(config2) {
717
+ }
718
+ function resolveApiKey(config) {
700
719
  const envKey = process.env.OPENPOND_API_KEY?.trim();
701
720
  if (envKey)
702
721
  return envKey;
703
- const stored = config2.apiKey?.trim();
722
+ const stored = config.apiKey?.trim();
704
723
  if (stored)
705
724
  return stored;
706
- const legacy = config2.token?.trim();
725
+ const legacy = config.token?.trim();
707
726
  if (legacy && legacy.startsWith("opk_"))
708
727
  return legacy;
709
728
  return null;
710
- };
711
- var resolveTemplateEnvironment = function(value) {
729
+ }
730
+ function resolveTemplateEnvironment(value) {
712
731
  if (!value)
713
732
  return "production";
714
733
  const normalized = value.toLowerCase();
@@ -716,7 +735,8 @@ var resolveTemplateEnvironment = function(value) {
716
735
  return normalized;
717
736
  }
718
737
  throw new Error("env must be preview or production");
719
- };
738
+ }
739
+ var UI_API_KEY_URL = "https://openpond.ai/settings/api-keys";
720
740
  async function promptForApiKey() {
721
741
  console.log("Open the OpenPond UI to create an API key:");
722
742
  console.log(UI_API_KEY_URL);
@@ -734,8 +754,8 @@ async function promptForApiKey() {
734
754
  rl.close();
735
755
  }
736
756
  }
737
- async function ensureApiKey(config2, baseUrl) {
738
- const existing = resolveApiKey(config2);
757
+ async function ensureApiKey(config, baseUrl) {
758
+ const existing = resolveApiKey(config);
739
759
  if (existing)
740
760
  return existing;
741
761
  const apiKey = await promptForApiKey();
@@ -793,27 +813,27 @@ async function getGitRemoteUrl(cwd, remoteName) {
793
813
  const url = result.stdout.trim();
794
814
  return url.length > 0 ? url : null;
795
815
  }
796
- var resolveRepoUrl = function(response) {
816
+ function resolveRepoUrl(response) {
797
817
  if (response.repoUrl)
798
818
  return response.repoUrl;
799
819
  if (response.gitHost && response.gitOwner && response.gitRepo) {
800
820
  return `https://${response.gitHost}/${response.gitOwner}/${response.gitRepo}.git`;
801
821
  }
802
822
  throw new Error("repoUrl missing from API response");
803
- };
804
- var formatTokenizedRepoUrl = function(repoUrl, token) {
823
+ }
824
+ function formatTokenizedRepoUrl(repoUrl, token) {
805
825
  const url = new URL(repoUrl);
806
826
  const encodedToken = encodeURIComponent(token);
807
827
  return `${url.protocol}//x-access-token:${encodedToken}@${url.host}${url.pathname}`;
808
- };
809
- var formatTokenizedRepoUrlForPrint = function(repoUrl) {
828
+ }
829
+ function formatTokenizedRepoUrlForPrint(repoUrl) {
810
830
  const url = new URL(repoUrl);
811
- return `${url.protocol}//x-access-token:\$OPENPOND_API_KEY@${url.host}${url.pathname}`;
812
- };
813
- var redactToken = function(value) {
831
+ return `${url.protocol}//x-access-token:$OPENPOND_API_KEY@${url.host}${url.pathname}`;
832
+ }
833
+ function redactToken(value) {
814
834
  return value.replace(/x-access-token:[^@]+@/g, "x-access-token:***@");
815
- };
816
- var warnOnRepoHostMismatch = function(repoUrl) {
835
+ }
836
+ function warnOnRepoHostMismatch(repoUrl) {
817
837
  const envBase = process.env.OPENPOND_BASE_URL;
818
838
  if (!envBase)
819
839
  return;
@@ -822,21 +842,20 @@ var warnOnRepoHostMismatch = function(repoUrl) {
822
842
  const repoHost = new URL(repoUrl).hostname;
823
843
  if (baseHost && repoHost && baseHost !== repoHost) {
824
844
  console.warn(`warning: repo host (${repoHost}) does not match OPENPOND_BASE_URL (${baseHost})`);
825
- console.warn("warning: if this is staging, ensure INTERNAL_GIT_HOST is set on the deployment worker.");
845
+ console.warn("warning: verify your git host configuration matches OPENPOND_BASE_URL.");
826
846
  }
827
- } catch {
828
- }
829
- };
830
- var parseHandleRepo = function(value) {
847
+ } catch {}
848
+ }
849
+ function parseHandleRepo(value) {
831
850
  const parts = value.split("/").filter(Boolean);
832
851
  if (parts.length !== 2) {
833
852
  throw new Error("expected <handle>/<repo>");
834
853
  }
835
854
  return { handle: parts[0], repo: parts[1] };
836
- };
837
- var normalizeRepoName = function(value) {
855
+ }
856
+ function normalizeRepoName(value) {
838
857
  return (value || "").trim().toLowerCase();
839
- };
858
+ }
840
859
  async function fetchAppsWithCache(params) {
841
860
  if (!params.forceRefresh) {
842
861
  const cached = await getCachedApps({
@@ -926,28 +945,28 @@ async function pollDeploymentLogs(params) {
926
945
  console.log(`${params.prefix}deployment still in progress`);
927
946
  }
928
947
  async function runTemplateStatus(_options, target) {
929
- const config2 = await loadConfig();
930
- const uiBase = resolveBaseUrl(config2);
948
+ const config = await loadConfig();
949
+ const uiBase = resolveBaseUrl(config);
931
950
  const apiBase = resolvePublicApiBaseUrl();
932
- const apiKey = await ensureApiKey(config2, uiBase);
951
+ const apiKey = await ensureApiKey(config, uiBase);
933
952
  const { app } = await resolveAppTarget(apiBase, apiKey, target);
934
953
  const status = await getTemplateStatus(apiBase, apiKey, app.id);
935
954
  console.log(JSON.stringify(status, null, 2));
936
955
  }
937
956
  async function runTemplateBranches(_options, target) {
938
- const config2 = await loadConfig();
939
- const uiBase = resolveBaseUrl(config2);
957
+ const config = await loadConfig();
958
+ const uiBase = resolveBaseUrl(config);
940
959
  const apiBase = resolvePublicApiBaseUrl();
941
- const apiKey = await ensureApiKey(config2, uiBase);
960
+ const apiKey = await ensureApiKey(config, uiBase);
942
961
  const { app } = await resolveAppTarget(apiBase, apiKey, target);
943
962
  const branches = await listTemplateBranches(apiBase, apiKey, app.id);
944
963
  console.log(JSON.stringify(branches, null, 2));
945
964
  }
946
965
  async function runTemplateUpdate(options, target) {
947
- const config2 = await loadConfig();
948
- const uiBase = resolveBaseUrl(config2);
966
+ const config = await loadConfig();
967
+ const uiBase = resolveBaseUrl(config);
949
968
  const apiBase = resolvePublicApiBaseUrl();
950
- const apiKey = await ensureApiKey(config2, uiBase);
969
+ const apiKey = await ensureApiKey(config, uiBase);
951
970
  const { app } = await resolveAppTarget(apiBase, apiKey, target);
952
971
  const envRaw = typeof options.env === "string" ? options.env : typeof options.environment === "string" ? options.environment : undefined;
953
972
  const environment = resolveTemplateEnvironment(envRaw);
@@ -956,7 +975,7 @@ async function runTemplateUpdate(options, target) {
956
975
  });
957
976
  console.log(JSON.stringify(result, null, 2));
958
977
  }
959
- var printHelp = function() {
978
+ function printHelp() {
960
979
  console.log("OpenPond CLI (API key only)");
961
980
  console.log("");
962
981
  console.log("Usage:");
@@ -975,19 +994,21 @@ var printHelp = function() {
975
994
  console.log(" openpond apps env get <handle>/<repo>");
976
995
  console.log(" openpond apps env set <handle>/<repo> --env <json>");
977
996
  console.log(" openpond apps performance [--app-id <id>]");
997
+ console.log(" openpond apps summary <handle>/<repo>");
998
+ console.log(" openpond apps assistant <plan|performance> <handle>/<repo> --prompt <text>");
978
999
  console.log(" openpond apps store events [--source <source>] [--status <csv>] [--symbol <symbol>] [--wallet-address <0x...>] [--since <ms|iso>] [--until <ms|iso>] [--limit <n>] [--cursor <cursor>] [--history <true|false>] [--params <json>]");
979
1000
  console.log(" openpond apps trade-facts [--app-id <id>]");
980
1001
  console.log(" openpond apps agent create --prompt <text> [--template-id <id>]");
981
- console.log(" openpond apps tools execute <appId> <deploymentId> <tool> [--body <json>] [--method <METHOD>] [--headers <json>]");
1002
+ console.log(" openpond apps tools execute <appId> <deploymentId> <tool> [--body <json>] [--method <METHOD>] [--headers <json>] [--summary <true|false>]");
982
1003
  console.log(" openpond apps positions tx [--method <GET|POST>] [--body <json>] [--params <json>]");
983
1004
  console.log(" openpond opentool <init|validate|build> [args]");
984
1005
  console.log("");
985
1006
  console.log("Env:");
986
1007
  console.log(" OPENPOND_API_KEY, OPENPOND_BASE_URL, OPENPOND_API_URL, OPENPOND_TOOL_URL");
987
- };
1008
+ }
988
1009
  async function runLogin(options) {
989
- const config2 = await loadConfig();
990
- const baseUrl = resolveBaseUrl(config2);
1010
+ const config = await loadConfig();
1011
+ const baseUrl = resolveBaseUrl(config);
991
1012
  const rawApiKey = typeof options.apiKey === "string" ? options.apiKey : typeof options.key === "string" ? options.key : null;
992
1013
  const apiKey = rawApiKey ? rawApiKey.trim() : await promptForApiKey();
993
1014
  if (!apiKey) {
@@ -1000,10 +1021,10 @@ async function runLogin(options) {
1000
1021
  console.log("saved api key to ~/.openpond/config.json");
1001
1022
  }
1002
1023
  async function runToolList(options, target) {
1003
- const config2 = await loadConfig();
1004
- const uiBase = resolveBaseUrl(config2);
1024
+ const config = await loadConfig();
1025
+ const uiBase = resolveBaseUrl(config);
1005
1026
  const apiBase = resolvePublicApiBaseUrl();
1006
- const apiKey = await ensureApiKey(config2, uiBase);
1027
+ const apiKey = await ensureApiKey(config, uiBase);
1007
1028
  const { app } = await resolveAppTarget(apiBase, apiKey, target);
1008
1029
  const branch = typeof options.branch === "string" ? String(options.branch) : undefined;
1009
1030
  const latest = await getLatestDeploymentForApp(apiBase, apiKey, app.id, { branch });
@@ -1027,10 +1048,10 @@ async function runToolList(options, target) {
1027
1048
  }
1028
1049
  }
1029
1050
  async function runToolRun(options, target, toolName) {
1030
- const config2 = await loadConfig();
1031
- const uiBase = resolveBaseUrl(config2);
1051
+ const config = await loadConfig();
1052
+ const uiBase = resolveBaseUrl(config);
1032
1053
  const apiBase = resolvePublicApiBaseUrl();
1033
- const apiKey = await ensureApiKey(config2, uiBase);
1054
+ const apiKey = await ensureApiKey(config, uiBase);
1034
1055
  const { app } = await resolveAppTarget(apiBase, apiKey, target);
1035
1056
  const branch = typeof options.branch === "string" ? String(options.branch) : undefined;
1036
1057
  const latest = await getLatestDeploymentForApp(apiBase, apiKey, app.id, { branch });
@@ -1061,10 +1082,10 @@ async function runToolRun(options, target, toolName) {
1061
1082
  console.log(JSON.stringify(output2, null, 2));
1062
1083
  }
1063
1084
  async function runDeployWatch(options, target) {
1064
- const config2 = await loadConfig();
1065
- const uiBase = resolveBaseUrl(config2);
1085
+ const config = await loadConfig();
1086
+ const uiBase = resolveBaseUrl(config);
1066
1087
  const apiBase = resolvePublicApiBaseUrl();
1067
- const apiKey = await ensureApiKey(config2, uiBase);
1088
+ const apiKey = await ensureApiKey(config, uiBase);
1068
1089
  const { app, handle, repo } = await resolveAppTarget(apiBase, apiKey, target);
1069
1090
  const branch = typeof options.branch === "string" ? String(options.branch) : undefined;
1070
1091
  const deploymentId = typeof options.deploymentId === "string" ? String(options.deploymentId) : undefined;
@@ -1090,9 +1111,9 @@ async function runRepoCreate(options, nameParts) {
1090
1111
  if (!trimmedName) {
1091
1112
  throw new Error("usage: repo create --name <name> [--path <dir>] [--template <owner/repo|url>] [--template-branch <branch>] [--empty|--opentool] [--token] [--auto-schedule-migration <true|false>]");
1092
1113
  }
1093
- const config2 = await loadConfig();
1094
- const uiBase = resolveBaseUrl(config2);
1095
- const apiKey = await ensureApiKey(config2, uiBase);
1114
+ const config = await loadConfig();
1115
+ const uiBase = resolveBaseUrl(config);
1116
+ const apiKey = await ensureApiKey(config, uiBase);
1096
1117
  const apiBase = resolvePublicApiBaseUrl();
1097
1118
  const templateInput = typeof options.template === "string" ? options.template.trim() : "";
1098
1119
  if (templateInput && (options.empty === "true" || options.opentool === "true")) {
@@ -1214,7 +1235,7 @@ async function runRepoCreate(options, nameParts) {
1214
1235
  console.log(`repo: ${response.gitOwner}/${response.gitRepo}`);
1215
1236
  }
1216
1237
  console.log(`remote: ${displayRemote}`);
1217
- console.log("next: git add . && git commit -m \"init\"");
1238
+ console.log('next: git add . && git commit -m "init"');
1218
1239
  const defaultBranch = response.defaultBranch || "master";
1219
1240
  console.log(`next: openpond repo push --path ${repoPath} --branch ${defaultBranch}`);
1220
1241
  if (!useTokenRemote) {
@@ -1236,9 +1257,9 @@ async function resolveGitBranch(repoPath) {
1236
1257
  return branch.length > 0 ? branch : null;
1237
1258
  }
1238
1259
  async function runRepoPush(options) {
1239
- const config2 = await loadConfig();
1240
- const baseUrl = resolveBaseUrl(config2);
1241
- const apiKey = await ensureApiKey(config2, baseUrl);
1260
+ const config = await loadConfig();
1261
+ const baseUrl = resolveBaseUrl(config);
1262
+ const apiKey = await ensureApiKey(config, baseUrl);
1242
1263
  const rawPath = typeof options.path === "string" ? options.path : typeof options.dir === "string" ? options.dir : null;
1243
1264
  const repoPath = path3.resolve(rawPath && rawPath.trim().length > 0 ? rawPath.trim() : ".");
1244
1265
  const gitDir = path3.join(repoPath, ".git");
@@ -1303,18 +1324,18 @@ async function runOpentool(rawArgs) {
1303
1324
  }
1304
1325
  }
1305
1326
  async function runAppsTools() {
1306
- const config2 = await loadConfig();
1307
- const uiBase = resolveBaseUrl(config2);
1308
- const apiKey = await ensureApiKey(config2, uiBase);
1327
+ const config = await loadConfig();
1328
+ const uiBase = resolveBaseUrl(config);
1329
+ const apiKey = await ensureApiKey(config, uiBase);
1309
1330
  const apiBase = resolvePublicApiBaseUrl();
1310
1331
  const tools = await fetchToolsWithCache({ apiBase, apiKey });
1311
1332
  console.log(JSON.stringify(tools, null, 2));
1312
1333
  }
1313
1334
  async function runAppsList(options) {
1314
- const config2 = await loadConfig();
1315
- const uiBase = resolveBaseUrl(config2);
1335
+ const config = await loadConfig();
1336
+ const uiBase = resolveBaseUrl(config);
1316
1337
  const apiBase = resolvePublicApiBaseUrl();
1317
- const apiKey = await ensureApiKey(config2, uiBase);
1338
+ const apiKey = await ensureApiKey(config, uiBase);
1318
1339
  const handle = typeof options.handle === "string" ? String(options.handle) : undefined;
1319
1340
  const normalizedHandle = handle ? normalizeRepoName(handle) : null;
1320
1341
  const forceRefresh = options.refresh !== undefined ? parseBooleanOption(options.refresh) : undefined;
@@ -1340,18 +1361,44 @@ async function runAppsList(options) {
1340
1361
  }
1341
1362
  }
1342
1363
  async function runAppsPerformance(options) {
1343
- const config2 = await loadConfig();
1344
- const uiBase = resolveBaseUrl(config2);
1345
- const apiKey = await ensureApiKey(config2, uiBase);
1364
+ const config = await loadConfig();
1365
+ const uiBase = resolveBaseUrl(config);
1366
+ const apiKey = await ensureApiKey(config, uiBase);
1346
1367
  const apiBase = resolvePublicApiBaseUrl();
1347
1368
  const appId = typeof options.appId === "string" ? String(options.appId) : undefined;
1348
1369
  const performance = await getUserPerformance(apiBase, apiKey, { appId });
1349
1370
  console.log(JSON.stringify(performance, null, 2));
1350
1371
  }
1372
+ async function runAppsSummary(_options, target) {
1373
+ const config = await loadConfig();
1374
+ const uiBase = resolveBaseUrl(config);
1375
+ const apiBase = resolvePublicApiBaseUrl();
1376
+ const apiKey = await ensureApiKey(config, uiBase);
1377
+ const { app } = await resolveAppTarget(apiBase, apiKey, target);
1378
+ const summary = await getAppRuntimeSummary(apiBase, apiKey, app.id);
1379
+ console.log(JSON.stringify(summary, null, 2));
1380
+ }
1381
+ async function runAppsAssistant(options, mode, target, contentParts) {
1382
+ const prompt = (typeof options.prompt === "string" ? options.prompt : null) || contentParts.join(" ");
1383
+ if (!prompt.trim()) {
1384
+ throw new Error("usage: apps assistant <plan|performance> <handle>/<repo> --prompt <text>");
1385
+ }
1386
+ const config = await loadConfig();
1387
+ const uiBase = resolveBaseUrl(config);
1388
+ const apiBase = resolvePublicApiBaseUrl();
1389
+ const apiKey = await ensureApiKey(config, uiBase);
1390
+ const { app } = await resolveAppTarget(apiBase, apiKey, target);
1391
+ const result = await runAssistantMode(apiBase, apiKey, {
1392
+ appId: app.id,
1393
+ mode,
1394
+ prompt: prompt.trim()
1395
+ });
1396
+ console.log(JSON.stringify(result, null, 2));
1397
+ }
1351
1398
  async function runAppsAgentCreate(options, contentParts) {
1352
- const config2 = await loadConfig();
1353
- const uiBase = resolveBaseUrl(config2);
1354
- const apiKey = await ensureApiKey(config2, uiBase);
1399
+ const config = await loadConfig();
1400
+ const uiBase = resolveBaseUrl(config);
1401
+ const apiKey = await ensureApiKey(config, uiBase);
1355
1402
  const apiBase = resolvePublicApiBaseUrl();
1356
1403
  const prompt = (typeof options.prompt === "string" ? options.prompt : null) || contentParts.join(" ");
1357
1404
  if (!prompt.trim()) {
@@ -1435,9 +1482,9 @@ async function runAppsAgentCreate(options, contentParts) {
1435
1482
  }
1436
1483
  }
1437
1484
  async function runAppsToolsExecute(options, appId, deploymentId, toolName) {
1438
- const config2 = await loadConfig();
1439
- const uiBase = resolveBaseUrl(config2);
1440
- const apiKey = await ensureApiKey(config2, uiBase);
1485
+ const config = await loadConfig();
1486
+ const uiBase = resolveBaseUrl(config);
1487
+ const apiKey = await ensureApiKey(config, uiBase);
1441
1488
  const apiBase = resolvePublicApiBaseUrl();
1442
1489
  const methodRaw = typeof options.method === "string" ? String(options.method).toUpperCase() : undefined;
1443
1490
  const method = methodRaw && ["GET", "POST", "PUT", "DELETE"].includes(methodRaw) ? methodRaw : undefined;
@@ -1448,6 +1495,7 @@ async function runAppsToolsExecute(options, appId, deploymentId, toolName) {
1448
1495
  const headers = typeof options.headers === "string" ? parseJsonOption(String(options.headers), "headers") : undefined;
1449
1496
  const scheduleId = typeof options.scheduleId === "string" ? String(options.scheduleId) : undefined;
1450
1497
  const notifyEmail = parseBooleanOption(options.notifyEmail);
1498
+ const withSummary = parseBooleanOption(options.summary) || parseBooleanOption(options.withSummary);
1451
1499
  const result = await executeUserTool(apiBase, apiKey, {
1452
1500
  appId,
1453
1501
  deploymentId,
@@ -1459,6 +1507,10 @@ async function runAppsToolsExecute(options, appId, deploymentId, toolName) {
1459
1507
  notifyEmail: notifyEmail || undefined
1460
1508
  });
1461
1509
  console.log(JSON.stringify(result, null, 2));
1510
+ if (withSummary && result.ok) {
1511
+ const summary = await getAppRuntimeSummary(apiBase, apiKey, appId);
1512
+ console.log(JSON.stringify({ summary }, null, 2));
1513
+ }
1462
1514
  }
1463
1515
  async function runAppsEnvSet(options, target) {
1464
1516
  const rawEnv = typeof options.env === "string" ? options.env : typeof options.vars === "string" ? options.vars : typeof options.envVars === "string" ? options.envVars : null;
@@ -1479,28 +1531,28 @@ async function runAppsEnvSet(options, target) {
1479
1531
  }
1480
1532
  envVars[key] = value;
1481
1533
  }
1482
- const config2 = await loadConfig();
1483
- const uiBase = resolveBaseUrl(config2);
1534
+ const config = await loadConfig();
1535
+ const uiBase = resolveBaseUrl(config);
1484
1536
  const apiBase = resolvePublicApiBaseUrl();
1485
- const apiKey = await ensureApiKey(config2, uiBase);
1537
+ const apiKey = await ensureApiKey(config, uiBase);
1486
1538
  const { app } = await resolveAppTarget(apiBase, apiKey, target);
1487
1539
  const result = await updateAppEnvironment(apiBase, apiKey, app.id, { envVars });
1488
1540
  console.log(JSON.stringify(result, null, 2));
1489
1541
  }
1490
1542
  async function runAppsEnvGet(_options, target) {
1491
- const config2 = await loadConfig();
1492
- const uiBase = resolveBaseUrl(config2);
1543
+ const config = await loadConfig();
1544
+ const uiBase = resolveBaseUrl(config);
1493
1545
  const apiBase = resolvePublicApiBaseUrl();
1494
- const apiKey = await ensureApiKey(config2, uiBase);
1546
+ const apiKey = await ensureApiKey(config, uiBase);
1495
1547
  const { app } = await resolveAppTarget(apiBase, apiKey, target);
1496
1548
  const result = await getAppEnvironment(apiBase, apiKey, app.id);
1497
1549
  console.log(JSON.stringify(result, null, 2));
1498
1550
  }
1499
1551
  async function runAppsDeploy(options, target) {
1500
- const config2 = await loadConfig();
1501
- const uiBase = resolveBaseUrl(config2);
1552
+ const config = await loadConfig();
1553
+ const uiBase = resolveBaseUrl(config);
1502
1554
  const apiBase = resolvePublicApiBaseUrl();
1503
- const apiKey = await ensureApiKey(config2, uiBase);
1555
+ const apiKey = await ensureApiKey(config, uiBase);
1504
1556
  const { app, handle, repo } = await resolveAppTarget(apiBase, apiKey, target);
1505
1557
  const envRaw = typeof options.env === "string" ? options.env : typeof options.environment === "string" ? options.environment : undefined;
1506
1558
  const environment = resolveTemplateEnvironment(envRaw);
@@ -1519,9 +1571,9 @@ async function runAppsDeploy(options, target) {
1519
1571
  });
1520
1572
  }
1521
1573
  async function runAppsPositionsTx(options) {
1522
- const config2 = await loadConfig();
1523
- const uiBase = resolveBaseUrl(config2);
1524
- const apiKey = await ensureApiKey(config2, uiBase);
1574
+ const config = await loadConfig();
1575
+ const uiBase = resolveBaseUrl(config);
1576
+ const apiKey = await ensureApiKey(config, uiBase);
1525
1577
  const apiBase = resolvePublicApiBaseUrl();
1526
1578
  const methodRaw = typeof options.method === "string" ? String(options.method).toUpperCase() : "POST";
1527
1579
  const method = methodRaw === "GET" ? "GET" : "POST";
@@ -1549,7 +1601,7 @@ async function runAppsPositionsTx(options) {
1549
1601
  });
1550
1602
  console.log(JSON.stringify(result, null, 2));
1551
1603
  }
1552
- var resolveStoreEventsParams = function(options) {
1604
+ function resolveStoreEventsParams(options) {
1553
1605
  let params = {};
1554
1606
  if (typeof options.params === "string") {
1555
1607
  const parsed = parseJsonOption(String(options.params), "params");
@@ -1585,11 +1637,11 @@ var resolveStoreEventsParams = function(options) {
1585
1637
  addParam("history", parseBooleanOption(options.history) ? "true" : "false");
1586
1638
  }
1587
1639
  return Object.keys(params).length ? params : undefined;
1588
- };
1640
+ }
1589
1641
  async function runAppsStoreEvents(options) {
1590
- const config2 = await loadConfig();
1591
- const uiBase = resolveBaseUrl(config2);
1592
- const apiKey = await ensureApiKey(config2, uiBase);
1642
+ const config = await loadConfig();
1643
+ const uiBase = resolveBaseUrl(config);
1644
+ const apiKey = await ensureApiKey(config, uiBase);
1593
1645
  const apiBase = resolvePublicApiBaseUrl();
1594
1646
  const query = resolveStoreEventsParams(options);
1595
1647
  const result = await submitPositionsTx(apiBase, apiKey, {
@@ -1599,9 +1651,9 @@ async function runAppsStoreEvents(options) {
1599
1651
  console.log(JSON.stringify(result, null, 2));
1600
1652
  }
1601
1653
  async function runAppsTradeFacts(options) {
1602
- const config2 = await loadConfig();
1603
- const uiBase = resolveBaseUrl(config2);
1604
- const apiKey = await ensureApiKey(config2, uiBase);
1654
+ const config = await loadConfig();
1655
+ const uiBase = resolveBaseUrl(config);
1656
+ const apiKey = await ensureApiKey(config, uiBase);
1605
1657
  const apiBase = resolvePublicApiBaseUrl();
1606
1658
  const appId = typeof options.appId === "string" ? options.appId : undefined;
1607
1659
  const performance = await getUserPerformance(apiBase, apiKey, { appId });
@@ -1734,6 +1786,23 @@ async function main() {
1734
1786
  await runAppsPerformance(options);
1735
1787
  return;
1736
1788
  }
1789
+ if (subcommand === "summary") {
1790
+ const target = rest[1];
1791
+ if (!target) {
1792
+ throw new Error("usage: apps summary <handle>/<repo>");
1793
+ }
1794
+ await runAppsSummary(options, target);
1795
+ return;
1796
+ }
1797
+ if (subcommand === "assistant") {
1798
+ const mode = rest[1];
1799
+ const target = rest[2];
1800
+ if (mode !== "plan" && mode !== "performance" || !target) {
1801
+ throw new Error("usage: apps assistant <plan|performance> <handle>/<repo> --prompt <text>");
1802
+ }
1803
+ await runAppsAssistant(options, mode, target, rest.slice(3));
1804
+ return;
1805
+ }
1737
1806
  if (subcommand === "store" && rest[1] === "events") {
1738
1807
  await runAppsStoreEvents(options);
1739
1808
  return;
@@ -1750,7 +1819,7 @@ async function main() {
1750
1819
  await runAppsPositionsTx(options);
1751
1820
  return;
1752
1821
  }
1753
- throw new Error("usage: apps <list|tools|deploy|env get|env set|performance|store events|trade-facts|agent create|positions tx> [args]");
1822
+ throw new Error("usage: apps <list|tools|deploy|env get|env set|performance|summary|assistant|store events|trade-facts|agent create|positions tx> [args]");
1754
1823
  }
1755
1824
  if (command === "opentool") {
1756
1825
  await runOpentool(process.argv.slice(3));
@@ -1759,7 +1828,6 @@ async function main() {
1759
1828
  printHelp();
1760
1829
  process.exit(1);
1761
1830
  }
1762
- var UI_API_KEY_URL = "https://openpond.ai/settings/api-keys";
1763
1831
  main().catch((error) => {
1764
1832
  const message = error instanceof Error ? error.message : String(error);
1765
1833
  console.error(message);
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { type AgentCreateRequest, type AppEnvironmentGetResponse, type AppEnvironmentUpdateResponse, type AppListItem, type CreateRepoRequest, type CreateRepoResponse, type DeploymentLogEntry, type TemplateBranchesResponse, type TemplateDeployLatestRequest, type TemplateDeployLatestResponse, type TemplateStatusResponse, type ToolExecuteRequest, type ToolExecuteResponse } from "./api";
1
+ import { type AssistantMode, type AssistantRunResponse, type AgentCreateRequest, type AppEnvironmentGetResponse, type AppEnvironmentUpdateResponse, type AppListItem, type AppRuntimeSummary, type CreateRepoRequest, type CreateRepoResponse, type DeploymentLogEntry, type TemplateBranchesResponse, type TemplateDeployLatestRequest, type TemplateDeployLatestResponse, type TemplateStatusResponse, type ToolExecuteRequest, type ToolExecuteResponse } from "./api";
2
2
  import type { StreamCallbacks } from "./stream";
3
3
  export type { StreamCallbacks } from "./stream";
4
- export type { AgentCreateRequest, AppEnvironmentGetResponse, AppEnvironmentUpdateRequest, AppEnvironmentUpdateResponse, AppListItem, CreateRepoRequest, CreateRepoResponse, DeploymentDetail, DeploymentLogEntry, TemplateBranchesResponse, TemplateDeployLatestRequest, TemplateDeployLatestResponse, TemplateStatusResponse, ToolExecuteRequest, ToolExecuteResponse, } from "./api";
4
+ export type { AssistantMode, AssistantRunResponse, AgentCreateRequest, AppEnvironmentGetResponse, AppEnvironmentUpdateRequest, AppEnvironmentUpdateResponse, AppListItem, AppRuntimeSummary, CreateRepoRequest, CreateRepoResponse, DeploymentDetail, DeploymentLogEntry, TemplateBranchesResponse, TemplateDeployLatestRequest, TemplateDeployLatestResponse, TemplateStatusResponse, ToolExecuteRequest, ToolExecuteResponse, } from "./api";
5
5
  export type { ChatRequestBody, ResponseItem, ResponseMessageItem, TemplateBootstrap, ToolCallItem, ToolOutputItem, UsageInfo, } from "./types";
6
6
  export type { Bar as IndicatorBar, BollingerResult, MacdResult, MaCrossResult, MaCrossSignal, PriceChangeResult, } from "./indicators";
7
- export { apiFetch, commitFiles, createAgentFromPrompt, createRepo, createHeadlessApps, createLocalProject, deployApp, deployLatestTemplate, getAppEnvironment, updateAppEnvironment, executeHostedTool, executeUserTool, fetchToolManifest, getDeploymentDetail, getDeploymentLogs, getDeploymentStatus, getLatestDeploymentForApp, getTemplateStatus, getUserPerformance, listApps, listTemplateBranches, listUserTools, pollDeviceLogin, postAgentDigest, resolveWorkerBaseUrl, startDeviceLogin, submitPositionsTx, } from "./api";
7
+ export { apiFetch, getAppRuntimeSummary, commitFiles, createAgentFromPrompt, createRepo, createHeadlessApps, createLocalProject, deployApp, deployLatestTemplate, getAppEnvironment, updateAppEnvironment, executeHostedTool, executeUserTool, fetchToolManifest, getDeploymentDetail, getDeploymentLogs, getDeploymentStatus, getLatestDeploymentForApp, getTemplateStatus, getUserPerformance, runAssistantMode, listApps, listTemplateBranches, listUserTools, pollDeviceLogin, postAgentDigest, resolveWorkerBaseUrl, startDeviceLogin, submitPositionsTx, } from "./api";
8
8
  export { computeAtr, computeBollinger, computeEma, computeEmaSeries, computeMacd, computeMaCross, computePriceChange, computeRsi, computeSma, computeSmaSeries, } from "./indicators";
9
9
  export { DEFAULT_CACHE_TTL_MS, getCachedApps, getCachedTools, setCachedApps, setCachedTools, } from "./cache";
10
10
  export { getConfigPath, loadConfig, loadGlobalConfig, saveConfig, saveGlobalConfig, } from "./config";
@@ -62,6 +62,8 @@ export type OpenPondClient = {
62
62
  list: (options?: AppsListOptions) => Promise<AppListItem[]>;
63
63
  tools: (options?: AppsToolsOptions) => Promise<unknown[]>;
64
64
  performance: (options?: AppsPerformanceOptions) => Promise<unknown>;
65
+ summary: (input: AppSummaryOptions) => Promise<AppRuntimeSummary>;
66
+ assistantRun: (input: AppsAssistantRunOptions) => Promise<AssistantRunResponse>;
65
67
  agentCreate: (input: AgentCreateRequest & {
66
68
  refreshCache?: boolean;
67
69
  }, callbacks?: AgentCreateStreamCallbacks) => Promise<AgentCreateStreamResult>;
@@ -121,6 +123,14 @@ export type AppsToolsOptions = {
121
123
  export type AppsPerformanceOptions = {
122
124
  appId?: string;
123
125
  };
126
+ export type AppSummaryOptions = {
127
+ appId: string;
128
+ };
129
+ export type AppsAssistantRunOptions = {
130
+ appId: string;
131
+ mode: AssistantMode;
132
+ prompt: string;
133
+ };
124
134
  export type ExecuteUserToolOptions = {
125
135
  appId: string;
126
136
  deploymentId: string;
package/dist/index.js CHANGED
@@ -181,6 +181,28 @@ async function getUserPerformance(baseUrl, token, options) {
181
181
  }
182
182
  return await response.json();
183
183
  }
184
+ async function getAppRuntimeSummary(baseUrl, token, appId) {
185
+ const params = new URLSearchParams({ appId });
186
+ const response = await apiFetch(baseUrl, token, `/apps/summary?${params.toString()}`, {
187
+ method: "GET"
188
+ });
189
+ if (!response.ok) {
190
+ const text = await response.text().catch(() => "");
191
+ throw new Error(`Summary lookup failed: ${response.status} ${text}`);
192
+ }
193
+ return await response.json();
194
+ }
195
+ async function runAssistantMode(baseUrl, token, payload) {
196
+ const response = await apiFetch(baseUrl, token, "/apps/assistant/run", {
197
+ method: "POST",
198
+ body: JSON.stringify(payload)
199
+ });
200
+ if (!response.ok) {
201
+ const text = await response.text().catch(() => "");
202
+ throw new Error(`Assistant run failed: ${response.status} ${text}`);
203
+ }
204
+ return await response.json();
205
+ }
184
206
  async function postAgentDigest(baseUrl, token, body) {
185
207
  const response = await apiFetch(baseUrl, token, "/apps/agent/digest", {
186
208
  method: "POST",
@@ -317,10 +339,10 @@ async function getDeploymentDetail(apiBase, token, deploymentId) {
317
339
  const payload = await response.json().catch(() => ({}));
318
340
  return payload.deployment ?? null;
319
341
  }
320
- var normalizeToolPathSegment = function(toolName) {
342
+ function normalizeToolPathSegment(toolName) {
321
343
  const trimmed = toolName.trim().replace(/^\/+/, "");
322
344
  return encodeURIComponent(trimmed || "tool");
323
- };
345
+ }
324
346
  function resolveWorkerBaseUrl(baseUrl) {
325
347
  const trimmed = baseUrl.replace(/\/$/, "");
326
348
  const workerEnv = process.env.OPENPOND_TOOL_URL;
@@ -347,8 +369,7 @@ function resolveWorkerBaseUrl(baseUrl) {
347
369
  if (isLocal && port === "3000") {
348
370
  return trimmed;
349
371
  }
350
- } catch {
351
- }
372
+ } catch {}
352
373
  return trimmed;
353
374
  }
354
375
  async function executeHostedTool(baseUrl, token, payload) {
@@ -380,13 +401,17 @@ async function executeHostedTool(baseUrl, token, payload) {
380
401
  }
381
402
 
382
403
  // src/cache.ts
383
- import {promises as fs} from "node:fs";
404
+ import { promises as fs } from "node:fs";
384
405
  import os from "node:os";
385
406
  import path from "node:path";
386
- var getCachePath = function() {
407
+ var CACHE_DIR = ".openpond";
408
+ var CACHE_FILENAME = "cache.json";
409
+ var DEFAULT_STORE = { version: 1, byKey: {} };
410
+ var DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000;
411
+ function getCachePath() {
387
412
  return path.join(os.homedir(), CACHE_DIR, CACHE_FILENAME);
388
- };
389
- var buildCacheKey = function(apiBase, apiKey) {
413
+ }
414
+ function buildCacheKey(apiBase, apiKey) {
390
415
  const trimmed = apiKey.trim();
391
416
  const hint = trimmed.length > 12 ? `${trimmed.slice(0, 8)}_${trimmed.slice(-4)}` : trimmed;
392
417
  try {
@@ -395,14 +420,14 @@ var buildCacheKey = function(apiBase, apiKey) {
395
420
  } catch {
396
421
  return `${apiBase}:${hint}`;
397
422
  }
398
- };
399
- var isFresh = function(updatedAt, ttlMs) {
423
+ }
424
+ function isFresh(updatedAt, ttlMs) {
400
425
  const timestamp = Date.parse(updatedAt);
401
426
  if (Number.isNaN(timestamp)) {
402
427
  return false;
403
428
  }
404
429
  return Date.now() - timestamp < ttlMs;
405
- };
430
+ }
406
431
  async function loadCache() {
407
432
  try {
408
433
  const raw = await fs.readFile(getCachePath(), "utf-8");
@@ -462,10 +487,6 @@ async function setCachedTools(params) {
462
487
  store.byKey[cacheKey] = bucket;
463
488
  await saveCache(store);
464
489
  }
465
- var CACHE_DIR = ".openpond";
466
- var CACHE_FILENAME = "cache.json";
467
- var DEFAULT_STORE = { version: 1, byKey: {} };
468
- var DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000;
469
490
 
470
491
  // src/stream.ts
471
492
  function normalizeDataFrames(raw) {
@@ -504,7 +525,7 @@ function normalizeDataFrames(raw) {
504
525
  }
505
526
  return { conversationId, items };
506
527
  }
507
- var extractUsage = function(raw) {
528
+ function extractUsage(raw) {
508
529
  const frames = Array.isArray(raw) ? raw : raw && typeof raw === "object" && Array.isArray(raw.data) ? raw.data : [raw];
509
530
  for (const frame of frames) {
510
531
  if (!frame || typeof frame !== "object")
@@ -521,7 +542,7 @@ var extractUsage = function(raw) {
521
542
  return { promptTokens, completionTokens, totalTokens };
522
543
  }
523
544
  return null;
524
- };
545
+ }
525
546
  async function consumeStream(response, callbacks) {
526
547
  if (!response.body) {
527
548
  throw new Error("Missing response body");
@@ -536,8 +557,7 @@ async function consumeStream(response, callbacks) {
536
557
  }
537
558
  try {
538
559
  await reader.cancel();
539
- } catch {
540
- }
560
+ } catch {}
541
561
  callbacks.onStop?.();
542
562
  return true;
543
563
  };
@@ -547,7 +567,8 @@ async function consumeStream(response, callbacks) {
547
567
  break;
548
568
  const chunk = decoder.decode(value, { stream: true });
549
569
  const textChunk = remainder + chunk;
550
- const lines = textChunk.split("\n");
570
+ const lines = textChunk.split(`
571
+ `);
551
572
  remainder = lines.pop() || "";
552
573
  for (const line of lines) {
553
574
  if (!line)
@@ -584,8 +605,7 @@ async function consumeStream(response, callbacks) {
584
605
  if (typeof message === "string") {
585
606
  throw new Error(message);
586
607
  }
587
- } catch {
588
- }
608
+ } catch {}
589
609
  continue;
590
610
  }
591
611
  if (line.startsWith("2:")) {
@@ -608,8 +628,7 @@ async function consumeStream(response, callbacks) {
608
628
  if (await stopIfNeeded()) {
609
629
  return;
610
630
  }
611
- } catch {
612
- }
631
+ } catch {}
613
632
  }
614
633
  if (await stopIfNeeded()) {
615
634
  return;
@@ -803,15 +822,17 @@ function computeAtr(bars, period = 14) {
803
822
  return sum / period;
804
823
  }
805
824
  // src/config.ts
806
- import {promises as fs2} from "node:fs";
825
+ import { promises as fs2 } from "node:fs";
807
826
  import os2 from "node:os";
808
827
  import path2 from "node:path";
828
+ var GLOBAL_DIRNAME = ".openpond";
829
+ var GLOBAL_CONFIG_FILENAME = "config.json";
809
830
  function getConfigPath() {
810
831
  return getGlobalConfigPath();
811
832
  }
812
- var getGlobalConfigPath = function() {
833
+ function getGlobalConfigPath() {
813
834
  return path2.join(os2.homedir(), GLOBAL_DIRNAME, GLOBAL_CONFIG_FILENAME);
814
- };
835
+ }
815
836
  async function loadConfigFile(filePath) {
816
837
  try {
817
838
  const raw = await fs2.readFile(filePath, "utf-8");
@@ -849,29 +870,29 @@ async function saveGlobalConfig(next) {
849
870
  const payload = JSON.stringify(merged, null, 2);
850
871
  await fs2.writeFile(filePath, payload, "utf-8");
851
872
  }
852
- var GLOBAL_DIRNAME = ".openpond";
853
- var GLOBAL_CONFIG_FILENAME = "config.json";
854
873
 
855
874
  // src/index.ts
856
- var resolveUrl = function(value) {
875
+ var DEFAULT_BASE_URL = "https://openpond.ai";
876
+ var DEFAULT_API_URL = "https://api.openpond.ai";
877
+ function resolveUrl(value) {
857
878
  return value.replace(/\/$/, "");
858
- };
859
- var resolveBaseUrl = function(options) {
879
+ }
880
+ function resolveBaseUrl(options) {
860
881
  const envBase = process.env.OPENPOND_BASE_URL;
861
882
  const base = options.baseUrl || envBase || DEFAULT_BASE_URL;
862
883
  return resolveUrl(base.trim());
863
- };
864
- var resolveApiUrl = function(options) {
884
+ }
885
+ function resolveApiUrl(options) {
865
886
  const envBase = process.env.OPENPOND_API_URL;
866
887
  const base = options.apiUrl || envBase || DEFAULT_API_URL;
867
888
  return resolveUrl(base.trim());
868
- };
869
- var resolveToolUrl = function(options, baseUrl) {
889
+ }
890
+ function resolveToolUrl(options, baseUrl) {
870
891
  const envBase = process.env.OPENPOND_TOOL_URL;
871
892
  const base = options.toolUrl || envBase || baseUrl;
872
893
  return resolveUrl(base.trim());
873
- };
874
- var resolveApiKey = function(options) {
894
+ }
895
+ function resolveApiKey(options) {
875
896
  const explicit = options.apiKey?.trim();
876
897
  if (explicit)
877
898
  return explicit;
@@ -879,18 +900,18 @@ var resolveApiKey = function(options) {
879
900
  if (envKey)
880
901
  return envKey;
881
902
  throw new Error("OPENPOND_API_KEY is required");
882
- };
883
- var parseHandleRepo = function(value) {
903
+ }
904
+ function parseHandleRepo(value) {
884
905
  const parts = value.split("/").filter(Boolean);
885
906
  if (parts.length !== 2) {
886
907
  throw new Error("expected <handle>/<repo>");
887
908
  }
888
909
  return { handle: parts[0], repo: parts[1] };
889
- };
890
- var normalizeRepoName = function(value) {
910
+ }
911
+ function normalizeRepoName(value) {
891
912
  return (value || "").trim().toLowerCase();
892
- };
893
- var normalizeToolSummary = function(tool) {
913
+ }
914
+ function normalizeToolSummary(tool) {
894
915
  if (!tool || typeof tool !== "object") {
895
916
  return { name: "unknown", raw: tool };
896
917
  }
@@ -899,8 +920,8 @@ var normalizeToolSummary = function(tool) {
899
920
  const name = typeof record.name === "string" ? record.name : typeof profile?.name === "string" ? profile.name : "unknown";
900
921
  const description = typeof record.description === "string" ? record.description : typeof profile?.description === "string" ? profile.description : undefined;
901
922
  return { name, description, raw: tool };
902
- };
903
- var extractDeploymentTools = function(detail) {
923
+ }
924
+ function extractDeploymentTools(detail) {
904
925
  if (!detail)
905
926
  return [];
906
927
  if (Array.isArray(detail.toolsJson)) {
@@ -913,7 +934,7 @@ var extractDeploymentTools = function(detail) {
913
934
  }
914
935
  }
915
936
  return [];
916
- };
937
+ }
917
938
  async function resolveAppTarget(params) {
918
939
  const { handle, repo } = parseHandleRepo(params.target);
919
940
  const apps = await fetchAppsWithCache({
@@ -985,7 +1006,7 @@ async function fetchToolsWithCache(params) {
985
1006
  }
986
1007
  return tools;
987
1008
  }
988
- var normalizeMethod = function(method) {
1009
+ function normalizeMethod(method) {
989
1010
  if (!method)
990
1011
  return "POST";
991
1012
  const upper = method.toUpperCase();
@@ -998,7 +1019,7 @@ var normalizeMethod = function(method) {
998
1019
  default:
999
1020
  throw new Error("method must be GET, POST, PUT, or DELETE");
1000
1021
  }
1001
- };
1022
+ }
1002
1023
  async function consumeAgentCreateStream(response, callbacks) {
1003
1024
  let conversationId;
1004
1025
  let appId;
@@ -1211,6 +1232,12 @@ function createClient(options) {
1211
1232
  performance: async (options2) => {
1212
1233
  return getUserPerformance(apiUrl, apiKey, { appId: options2?.appId });
1213
1234
  },
1235
+ summary: async (input) => {
1236
+ return getAppRuntimeSummary(apiUrl, apiKey, input.appId);
1237
+ },
1238
+ assistantRun: async (input) => {
1239
+ return runAssistantMode(apiUrl, apiKey, input);
1240
+ },
1214
1241
  agentCreate: async (input, callbacks) => {
1215
1242
  const { refreshCache: refreshCacheFlag, ...rest } = input;
1216
1243
  const payload = {
@@ -1226,8 +1253,7 @@ function createClient(options) {
1226
1253
  if (useCache && refreshCacheFlag !== false) {
1227
1254
  try {
1228
1255
  await refreshCache();
1229
- } catch {
1230
- }
1256
+ } catch {}
1231
1257
  }
1232
1258
  return result;
1233
1259
  },
@@ -1277,8 +1303,7 @@ function createClient(options) {
1277
1303
  if (useCache && refreshCacheFlag !== false) {
1278
1304
  try {
1279
1305
  await refreshCache();
1280
- } catch {
1281
- }
1306
+ } catch {}
1282
1307
  }
1283
1308
  return result;
1284
1309
  }
@@ -1288,8 +1313,6 @@ function createClient(options) {
1288
1313
  }
1289
1314
  };
1290
1315
  }
1291
- var DEFAULT_BASE_URL = "https://openpond.ai";
1292
- var DEFAULT_API_URL = "https://api.openpond.ai";
1293
1316
  export {
1294
1317
  updateAppEnvironment,
1295
1318
  submitPositionsTx,
@@ -1298,6 +1321,7 @@ export {
1298
1321
  setCachedApps,
1299
1322
  saveGlobalConfig,
1300
1323
  saveConfig,
1324
+ runAssistantMode,
1301
1325
  resolveWorkerBaseUrl,
1302
1326
  postAgentDigest,
1303
1327
  pollDeviceLogin,
@@ -1316,6 +1340,7 @@ export {
1316
1340
  getConfigPath,
1317
1341
  getCachedTools,
1318
1342
  getCachedApps,
1343
+ getAppRuntimeSummary,
1319
1344
  getAppEnvironment,
1320
1345
  formatStreamItem,
1321
1346
  fetchToolManifest,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openpond-code",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "OpenPond CLI (API key only)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -36,6 +36,14 @@
36
36
  "publishConfig": {
37
37
  "access": "public"
38
38
  },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/openpond/openpond-code"
42
+ },
43
+ "homepage": "https://github.com/openpond/openpond-code",
44
+ "bugs": {
45
+ "url": "https://github.com/openpond/openpond-code/issues"
46
+ },
39
47
  "engines": {
40
48
  "node": ">=20.0.0"
41
49
  },