@nextclaw/server 0.5.4 → 0.5.6

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/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import * as NextclawCore from '@nextclaw/core';
2
+ import { CronService, Config, ConfigActionExecuteRequest as ConfigActionExecuteRequest$1, ConfigActionExecuteResult as ConfigActionExecuteResult$1 } from '@nextclaw/core';
1
3
  import { Hono } from 'hono';
2
- import { Config, ConfigActionExecuteRequest as ConfigActionExecuteRequest$1, ConfigActionExecuteResult as ConfigActionExecuteResult$1 } from '@nextclaw/core';
3
4
 
4
5
  type ApiError = {
5
6
  code: string;
@@ -85,6 +86,55 @@ type SessionPatchUpdate = {
85
86
  preferredModel?: string | null;
86
87
  clearHistory?: boolean;
87
88
  };
89
+ type CronScheduleView = {
90
+ kind: "at";
91
+ atMs?: number | null;
92
+ } | {
93
+ kind: "every";
94
+ everyMs?: number | null;
95
+ } | {
96
+ kind: "cron";
97
+ expr?: string | null;
98
+ tz?: string | null;
99
+ };
100
+ type CronPayloadView = {
101
+ kind?: "system_event" | "agent_turn";
102
+ message: string;
103
+ deliver?: boolean;
104
+ channel?: string | null;
105
+ to?: string | null;
106
+ };
107
+ type CronJobStateView = {
108
+ nextRunAt?: string | null;
109
+ lastRunAt?: string | null;
110
+ lastStatus?: "ok" | "error" | "skipped" | null;
111
+ lastError?: string | null;
112
+ };
113
+ type CronJobView = {
114
+ id: string;
115
+ name: string;
116
+ enabled: boolean;
117
+ schedule: CronScheduleView;
118
+ payload: CronPayloadView;
119
+ state: CronJobStateView;
120
+ createdAt: string;
121
+ updatedAt: string;
122
+ deleteAfterRun: boolean;
123
+ };
124
+ type CronListView = {
125
+ jobs: CronJobView[];
126
+ total: number;
127
+ };
128
+ type CronEnableRequest = {
129
+ enabled: boolean;
130
+ };
131
+ type CronRunRequest = {
132
+ force?: boolean;
133
+ };
134
+ type CronActionResult = {
135
+ job: CronJobView | null;
136
+ executed?: boolean;
137
+ };
88
138
  type RuntimeConfigUpdate = {
89
139
  agents?: {
90
140
  defaults?: {
@@ -363,6 +413,7 @@ type UiServerOptions = {
363
413
  corsOrigins?: string[] | "*";
364
414
  staticDir?: string;
365
415
  marketplace?: MarketplaceApiConfig;
416
+ cronService?: CronService;
366
417
  };
367
418
  type UiServerHandle = {
368
419
  host: string;
@@ -377,6 +428,7 @@ type UiRouterOptions = {
377
428
  configPath: string;
378
429
  publish: (event: UiServerEvent) => void;
379
430
  marketplace?: MarketplaceApiConfig;
431
+ cronService?: InstanceType<typeof NextclawCore.CronService>;
380
432
  };
381
433
  declare function createUiRouter(options: UiRouterOptions): Hono;
382
434
 
@@ -410,4 +462,4 @@ declare function patchSession(configPath: string, key: string, patch: SessionPat
410
462
  declare function deleteSession(configPath: string, key: string): boolean;
411
463
  declare function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, "agents" | "bindings" | "session">;
412
464
 
413
- export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type BindingPeerView, type ChannelSpecView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallRequest, type MarketplaceInstallResult, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplaceManageAction, type MarketplaceManageRequest, type MarketplaceManageResult, type MarketplaceRecommendationView, type MarketplaceSort, type ProviderConfigUpdate, type ProviderConfigView, type ProviderSpecView, type RuntimeConfigUpdate, type SessionConfigView, type SessionEntryView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, type SessionsListView, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createUiRouter, deleteSession, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, updateChannel, updateModel, updateProvider, updateRuntime };
465
+ export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type BindingPeerView, type ChannelSpecView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type CronActionResult, type CronEnableRequest, type CronJobStateView, type CronJobView, type CronListView, type CronPayloadView, type CronRunRequest, type CronScheduleView, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallRequest, type MarketplaceInstallResult, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplaceManageAction, type MarketplaceManageRequest, type MarketplaceManageResult, type MarketplaceRecommendationView, type MarketplaceSort, type ProviderConfigUpdate, type ProviderConfigView, type ProviderSpecView, type RuntimeConfigUpdate, type SessionConfigView, type SessionEntryView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, type SessionsListView, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createUiRouter, deleteSession, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, updateChannel, updateModel, updateProvider, updateRuntime };
package/dist/index.js CHANGED
@@ -691,6 +691,38 @@ function ok(data) {
691
691
  function err(code, message, details) {
692
692
  return { ok: false, error: { code, message, details } };
693
693
  }
694
+ function toIsoTime(value) {
695
+ if (typeof value !== "number" || !Number.isFinite(value)) {
696
+ return null;
697
+ }
698
+ const date = new Date(value);
699
+ if (Number.isNaN(date.getTime())) {
700
+ return null;
701
+ }
702
+ return date.toISOString();
703
+ }
704
+ function buildCronJobView(job) {
705
+ return {
706
+ id: job.id,
707
+ name: job.name,
708
+ enabled: job.enabled,
709
+ schedule: job.schedule,
710
+ payload: job.payload,
711
+ state: {
712
+ nextRunAt: toIsoTime(job.state.nextRunAtMs),
713
+ lastRunAt: toIsoTime(job.state.lastRunAtMs),
714
+ lastStatus: job.state.lastStatus ?? null,
715
+ lastError: job.state.lastError ?? null
716
+ },
717
+ createdAt: new Date(job.createdAtMs).toISOString(),
718
+ updatedAt: new Date(job.updatedAtMs).toISOString(),
719
+ deleteAfterRun: job.deleteAfterRun
720
+ };
721
+ }
722
+ function findCronJob(service, id) {
723
+ const jobs = service.listJobs(true);
724
+ return jobs.find((job) => job.id === id) ?? null;
725
+ }
694
726
  async function readJson(req) {
695
727
  try {
696
728
  const data = await req.json();
@@ -1306,6 +1338,66 @@ function createUiRouter(options) {
1306
1338
  options.publish({ type: "config.updated", payload: { path: "session" } });
1307
1339
  return c.json(ok({ deleted: true }));
1308
1340
  });
1341
+ app.get("/api/cron", (c) => {
1342
+ if (!options.cronService) {
1343
+ return c.json(err("NOT_AVAILABLE", "cron service unavailable"), 503);
1344
+ }
1345
+ const query = c.req.query();
1346
+ const includeDisabled = query.all === "1" || query.all === "true" || query.all === "yes";
1347
+ const jobs = options.cronService.listJobs(includeDisabled).map((job) => buildCronJobView(job));
1348
+ return c.json(ok({ jobs, total: jobs.length }));
1349
+ });
1350
+ app.delete("/api/cron/:id", (c) => {
1351
+ if (!options.cronService) {
1352
+ return c.json(err("NOT_AVAILABLE", "cron service unavailable"), 503);
1353
+ }
1354
+ const id = decodeURIComponent(c.req.param("id"));
1355
+ const deleted = options.cronService.removeJob(id);
1356
+ if (!deleted) {
1357
+ return c.json(err("NOT_FOUND", `cron job not found: ${id}`), 404);
1358
+ }
1359
+ return c.json(ok({ deleted: true }));
1360
+ });
1361
+ app.put("/api/cron/:id/enable", async (c) => {
1362
+ if (!options.cronService) {
1363
+ return c.json(err("NOT_AVAILABLE", "cron service unavailable"), 503);
1364
+ }
1365
+ const id = decodeURIComponent(c.req.param("id"));
1366
+ const body = await readJson(c.req.raw);
1367
+ if (!body.ok) {
1368
+ return c.json(err("INVALID_BODY", "invalid json body"), 400);
1369
+ }
1370
+ if (typeof body.data.enabled !== "boolean") {
1371
+ return c.json(err("INVALID_BODY", "enabled must be boolean"), 400);
1372
+ }
1373
+ const job = options.cronService.enableJob(id, body.data.enabled);
1374
+ if (!job) {
1375
+ return c.json(err("NOT_FOUND", `cron job not found: ${id}`), 404);
1376
+ }
1377
+ const data = { job: buildCronJobView(job) };
1378
+ return c.json(ok(data));
1379
+ });
1380
+ app.post("/api/cron/:id/run", async (c) => {
1381
+ if (!options.cronService) {
1382
+ return c.json(err("NOT_AVAILABLE", "cron service unavailable"), 503);
1383
+ }
1384
+ const id = decodeURIComponent(c.req.param("id"));
1385
+ const body = await readJson(c.req.raw);
1386
+ if (!body.ok) {
1387
+ return c.json(err("INVALID_BODY", "invalid json body"), 400);
1388
+ }
1389
+ const existing = findCronJob(options.cronService, id);
1390
+ if (!existing) {
1391
+ return c.json(err("NOT_FOUND", `cron job not found: ${id}`), 404);
1392
+ }
1393
+ const executed = await options.cronService.runJob(id, Boolean(body.data.force));
1394
+ const after = findCronJob(options.cronService, id);
1395
+ const data = {
1396
+ job: after ? buildCronJobView(after) : null,
1397
+ executed
1398
+ };
1399
+ return c.json(ok(data));
1400
+ });
1309
1401
  app.put("/api/config/runtime", async (c) => {
1310
1402
  const body = await readJson(c.req.raw);
1311
1403
  if (!body.ok || !body.data || typeof body.data !== "object") {
@@ -1365,7 +1457,8 @@ function startUiServer(options) {
1365
1457
  createUiRouter({
1366
1458
  configPath: options.configPath,
1367
1459
  publish,
1368
- marketplace: options.marketplace
1460
+ marketplace: options.marketplace,
1461
+ cronService: options.cronService
1369
1462
  })
1370
1463
  );
1371
1464
  const staticDir = options.staticDir;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/server",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "private": false,
5
5
  "description": "Nextclaw UI/API server.",
6
6
  "type": "module",
@@ -15,10 +15,10 @@
15
15
  ],
16
16
  "dependencies": {
17
17
  "@hono/node-server": "^1.13.3",
18
- "@nextclaw/openclaw-compat": "^0.1.21",
18
+ "@nextclaw/openclaw-compat": "^0.1.23",
19
19
  "hono": "^4.6.2",
20
20
  "ws": "^8.18.0",
21
- "@nextclaw/core": "^0.6.28"
21
+ "@nextclaw/core": "^0.6.30"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^20.17.6",