spawnfile 0.1.8 → 0.1.10

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.
@@ -131,6 +131,7 @@ export const createMoltnetNativeServerConfig = ({ networkId, networkName, rooms,
131
131
  listen_addr: renderMoltnetListenAddr(server),
132
132
  ...(server.human_ingress !== undefined ? { human_ingress: server.human_ingress } : {}),
133
133
  ...(server.direct_messages !== undefined ? { direct_messages: server.direct_messages } : {}),
134
+ ...(server.debug_events !== undefined ? { debug_events: server.debug_events } : {}),
134
135
  ...(server.trust_forwarded_proto !== undefined
135
136
  ? { trust_forwarded_proto: server.trust_forwarded_proto }
136
137
  : {}),
@@ -31,6 +31,7 @@ const buildTreeNetworkSummaries = (node) => {
31
31
  }
32
32
  return (node.value.networks ?? []).map((network) => ({
33
33
  authMode: network.server?.auth.mode,
34
+ debugEvents: network.server?.mode === "managed" ? network.server.debug_events : undefined,
34
35
  directMessages: network.server?.mode === "managed" ? network.server.direct_messages : undefined,
35
36
  expose: network.server?.mode === "managed" ? network.server.human_ingress : undefined,
36
37
  httpEnabled: network.server?.mode === "managed" ? network.server.human_ingress === true : false,
@@ -107,6 +108,7 @@ const toNetworkMemberView = (membership) => ({
107
108
  const createNetworkKey = (provider, networkId) => `${provider}::${networkId}`;
108
109
  const buildNetworkDeclaration = (teamNode, network, roomMemberships) => ({
109
110
  authMode: network.server?.auth.mode,
111
+ debugEvents: network.server?.mode === "managed" ? network.server.debug_events : undefined,
110
112
  declaringTeamName: teamNode.name,
111
113
  declaringTeamSource: teamNode.source,
112
114
  directMessages: network.server?.mode === "managed" ? network.server.direct_messages : undefined,
@@ -150,6 +152,7 @@ const buildNetworks = (plan) => {
150
152
  declaringTeamSource: declaration.declaringTeamSource,
151
153
  declarations: [declaration],
152
154
  authMode: declaration.authMode,
155
+ debugEvents: declaration.debugEvents,
153
156
  directMessages: declaration.directMessages,
154
157
  expose: declaration.expose,
155
158
  httpEnabled: declaration.httpEnabled,
@@ -43,6 +43,7 @@ const getDeclarations = (network) => network.declarations ?? [
43
43
  authMode: network.authMode,
44
44
  declaringTeamName: network.declaringTeamName,
45
45
  declaringTeamSource: network.declaringTeamSource,
46
+ debugEvents: network.debugEvents,
46
47
  directMessages: network.directMessages,
47
48
  expose: network.expose,
48
49
  httpEnabled: network.httpEnabled,
@@ -58,6 +59,7 @@ const formatDeclaration = (network, declaration, options, projectRoot) => {
58
59
  declaration.url ? `url=${declaration.url}` : undefined,
59
60
  declaration.authMode ? `auth=${declaration.authMode}` : undefined,
60
61
  declaration.directMessages === false ? "dms=disabled" : undefined,
62
+ declaration.debugEvents === true ? "debug_events" : undefined,
61
63
  declaration.expose === true || declaration.httpEnabled ? "human_ingress" : undefined
62
64
  ].filter((entry) => entry !== undefined);
63
65
  const source = options.paths
@@ -29,6 +29,7 @@ const formatNetworkSummary = (network, options) => {
29
29
  network.url ? `url=${network.url}` : undefined,
30
30
  network.authMode ? `auth=${network.authMode}` : undefined,
31
31
  network.directMessages === false ? "dms=disabled" : undefined,
32
+ network.debugEvents === true ? "debug_events" : undefined,
32
33
  network.expose === true || network.httpEnabled ? "human_ingress" : undefined
33
34
  ].filter((entry) => entry !== undefined);
34
35
  const rooms = network.rooms
@@ -18,6 +18,7 @@ export interface OrganizationTreeNetworkRoomSummary {
18
18
  }
19
19
  export interface OrganizationTreeNetworkSummary {
20
20
  authMode?: "bearer" | "none" | "open";
21
+ debugEvents?: boolean;
21
22
  directMessages?: boolean;
22
23
  expose?: boolean;
23
24
  httpEnabled?: boolean;
@@ -48,6 +49,7 @@ export interface OrganizationNetworkMemberView {
48
49
  }
49
50
  export interface OrganizationNetworkDeclarationView {
50
51
  authMode?: "bearer" | "none" | "open";
52
+ debugEvents?: boolean;
51
53
  declaringTeamName: string;
52
54
  declaringTeamSource: string;
53
55
  directMessages?: boolean;
@@ -65,6 +67,7 @@ export interface OrganizationNetworkRoomView {
65
67
  }
66
68
  export interface OrganizationNetworkView {
67
69
  authMode?: "bearer" | "none" | "open";
70
+ debugEvents?: boolean;
68
71
  declaringTeamName: string;
69
72
  declaringTeamSource: string;
70
73
  directMessages?: boolean;
@@ -58,6 +58,7 @@ const orderTeamAuth = (server) => withDefinedEntries([
58
58
  ],
59
59
  ["human_ingress", server.mode === "managed" ? server.human_ingress : undefined],
60
60
  ["direct_messages", server.mode === "managed" ? server.direct_messages : undefined],
61
+ ["debug_events", server.mode === "managed" ? server.debug_events : undefined],
61
62
  [
62
63
  "trust_forwarded_proto",
63
64
  server.mode === "managed" ? server.trust_forwarded_proto : undefined
@@ -658,6 +658,7 @@ declare const teamManifestSchema: z.ZodObject<{
658
658
  }>>;
659
659
  }, z.core.$strict>>>;
660
660
  }, z.core.$strict>;
661
+ debug_events: z.ZodOptional<z.ZodBoolean>;
661
662
  direct_messages: z.ZodOptional<z.ZodBoolean>;
662
663
  human_ingress: z.ZodOptional<z.ZodBoolean>;
663
664
  listen: z.ZodObject<{
@@ -1313,6 +1314,7 @@ export declare const manifestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1313
1314
  }>>;
1314
1315
  }, z.core.$strict>>>;
1315
1316
  }, z.core.$strict>;
1317
+ debug_events: z.ZodOptional<z.ZodBoolean>;
1316
1318
  direct_messages: z.ZodOptional<z.ZodBoolean>;
1317
1319
  human_ingress: z.ZodOptional<z.ZodBoolean>;
1318
1320
  listen: z.ZodObject<{
@@ -81,6 +81,7 @@ declare const teamNetworkServerSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
81
81
  }>>;
82
82
  }, z.core.$strict>>>;
83
83
  }, z.core.$strict>;
84
+ debug_events: z.ZodOptional<z.ZodBoolean>;
84
85
  direct_messages: z.ZodOptional<z.ZodBoolean>;
85
86
  human_ingress: z.ZodOptional<z.ZodBoolean>;
86
87
  listen: z.ZodObject<{
@@ -195,6 +196,7 @@ export declare const teamNetworkSchema: z.ZodObject<{
195
196
  }>>;
196
197
  }, z.core.$strict>>>;
197
198
  }, z.core.$strict>;
199
+ debug_events: z.ZodOptional<z.ZodBoolean>;
198
200
  direct_messages: z.ZodOptional<z.ZodBoolean>;
199
201
  human_ingress: z.ZodOptional<z.ZodBoolean>;
200
202
  listen: z.ZodObject<{
@@ -182,6 +182,7 @@ const teamNetworkManagedServerSchema = z
182
182
  .object({
183
183
  allowed_origins: z.array(z.string().trim().min(1)).optional(),
184
184
  auth: teamNetworkAuthSchema,
185
+ debug_events: z.boolean().optional(),
185
186
  direct_messages: z.boolean().optional(),
186
187
  human_ingress: z.boolean().optional(),
187
188
  listen: teamNetworkListenSchema,
@@ -3,6 +3,7 @@ import { SpawnfileError } from "../../shared/index.js";
3
3
  import { createAgentCapabilities, createDiagnostic, createDocumentFiles, createSkillFiles } from "../common.js";
4
4
  import { preparePicoClawRuntimeAuth } from "./runAuth.js";
5
5
  import { createPicoClawAgentScaffold } from "./scaffold.js";
6
+ import { createPicoClawCronStoreFile, createScheduleDiagnostics, scheduleOutcomeFor } from "./schedules.js";
6
7
  import { assertSupportedPicoClawSurfaces, buildPicoClawChannelConfig, buildPicoClawSurfaceEnvBindings } from "./surfaces.js";
7
8
  import { PICOCLAW_GATEWAY_BASE_PORT, PICOCLAW_INTERNAL_PICO_TOKEN } from "./pico.js";
8
9
  const formatModelName = (node) => {
@@ -89,6 +90,11 @@ const buildMcpServers = (servers) => {
89
90
  };
90
91
  const buildPicoClawToolsConfig = (node) => {
91
92
  const tools = {};
93
+ if (node.schedule?.kind === "cron") {
94
+ tools.cron = {
95
+ enabled: true
96
+ };
97
+ }
92
98
  if (node.surfaces?.moltnet) {
93
99
  tools.exec = {
94
100
  enabled: true
@@ -199,12 +205,18 @@ export const picoClawAdapter = {
199
205
  }
200
206
  },
201
207
  async compileAgent(node) {
208
+ const scheduleOutcome = scheduleOutcomeFor(node);
209
+ const cronStoreFile = createPicoClawCronStoreFile(node);
202
210
  return {
203
- capabilities: createAgentCapabilities(node),
204
- diagnostics: [],
211
+ capabilities: createAgentCapabilities(node, {
212
+ scheduleMessage: scheduleOutcome.message,
213
+ scheduleOutcome: scheduleOutcome.outcome
214
+ }),
215
+ diagnostics: createScheduleDiagnostics(node),
205
216
  files: [
206
217
  ...createDocumentFiles("workspace", node.docs),
207
218
  ...createSkillFiles("workspace/skills", node.skills),
219
+ ...(cronStoreFile ? [cronStoreFile] : []),
208
220
  {
209
221
  content: buildPicoClawConfig(node),
210
222
  path: "config.json"
@@ -0,0 +1,9 @@
1
+ import type { ResolvedAgentNode } from "../../compiler/types.js";
2
+ import type { CapabilityReport } from "../../report/index.js";
3
+ import type { EmittedFile } from "../types.js";
4
+ export declare const createPicoClawCronStoreFile: (node: ResolvedAgentNode) => EmittedFile | null;
5
+ export declare const scheduleOutcomeFor: (node: ResolvedAgentNode) => {
6
+ message?: string;
7
+ outcome?: CapabilityReport["outcome"];
8
+ };
9
+ export declare const createScheduleDiagnostics: (node: ResolvedAgentNode) => import("../../report/types.js").DiagnosticReport[];
@@ -0,0 +1,65 @@
1
+ import { createDiagnostic } from "../common.js";
2
+ const createPicoClawCronJob = (node) => {
3
+ if (!node.schedule || node.schedule.kind !== "cron") {
4
+ return null;
5
+ }
6
+ return {
7
+ createdAtMs: 0,
8
+ deleteAfterRun: false,
9
+ enabled: true,
10
+ id: `spawnfile-${node.name}`,
11
+ name: `spawnfile-${node.name}`,
12
+ payload: {
13
+ deliver: false,
14
+ kind: "agent_turn",
15
+ message: node.schedule.prompt ?? "Run the scheduled Spawnfile task."
16
+ },
17
+ schedule: {
18
+ expr: node.schedule.cron,
19
+ kind: "cron",
20
+ ...(node.schedule.timezone ? { tz: node.schedule.timezone } : {})
21
+ },
22
+ state: {},
23
+ updatedAtMs: 0
24
+ };
25
+ };
26
+ export const createPicoClawCronStoreFile = (node) => {
27
+ const job = createPicoClawCronJob(node);
28
+ if (!job) {
29
+ return null;
30
+ }
31
+ const store = {
32
+ jobs: [job],
33
+ version: 1
34
+ };
35
+ return {
36
+ content: `${JSON.stringify(store, null, 2)}\n`,
37
+ path: "workspace/cron/jobs.json"
38
+ };
39
+ };
40
+ export const scheduleOutcomeFor = (node) => {
41
+ if (!node.schedule) {
42
+ return {};
43
+ }
44
+ if (node.schedule.kind === "cron") {
45
+ return {
46
+ message: "PicoClaw native cron scheduler is emitted as workspace/cron/jobs.json",
47
+ outcome: "supported"
48
+ };
49
+ }
50
+ if (node.schedule.kind === "disabled") {
51
+ return {
52
+ message: "Disabled schedule emits no wake registration",
53
+ outcome: "supported"
54
+ };
55
+ }
56
+ return {
57
+ message: "PicoClaw native schedule lowering supports cron schedules in Spawnfile v0.1",
58
+ outcome: "degraded"
59
+ };
60
+ };
61
+ export const createScheduleDiagnostics = (node) => node.schedule?.kind === "every"
62
+ ? [
63
+ createDiagnostic("warn", "PicoClaw native schedule lowering supports cron schedules in Spawnfile v0.1; every schedules are degraded")
64
+ ]
65
+ : [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spawnfile",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Canonical source compiler for autonomous agents and teams.",
5
5
  "license": "MIT",
6
6
  "type": "module",