@poncho-ai/cli 0.11.1 → 0.13.0
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/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +24 -0
- package/dist/{chunk-T2F6ICXI.js → chunk-CUCEDHME.js} +542 -18
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +1 -1
- package/dist/{run-interactive-ink-7FP5PT7Q.js → run-interactive-ink-VZBOYJYS.js} +1 -1
- package/package.json +5 -3
- package/src/index.ts +594 -19
- package/src/init-feature-context.ts +6 -0
- package/src/init-onboarding.ts +10 -2
- package/test/cli.test.ts +42 -2
|
@@ -29,11 +29,15 @@ const summarizeConfig = (config: PonchoConfig | undefined): string[] => {
|
|
|
29
29
|
const memoryEnabled = config?.storage?.memory?.enabled ?? config?.memory?.enabled ?? false;
|
|
30
30
|
const authRequired = config?.auth?.required ?? false;
|
|
31
31
|
const telemetryEnabled = config?.telemetry?.enabled ?? true;
|
|
32
|
+
const messagingPlatforms = (config?.messaging ?? []).map((m) => m.platform);
|
|
32
33
|
return [
|
|
33
34
|
`storage: ${provider}`,
|
|
34
35
|
`memory tools: ${memoryEnabled ? "enabled" : "disabled"}`,
|
|
35
36
|
`auth: ${authRequired ? "required" : "not required"}`,
|
|
36
37
|
`telemetry: ${telemetryEnabled ? "enabled" : "disabled"}`,
|
|
38
|
+
...(messagingPlatforms.length > 0
|
|
39
|
+
? [`messaging: ${messagingPlatforms.join(", ")}`]
|
|
40
|
+
: []),
|
|
37
41
|
];
|
|
38
42
|
};
|
|
39
43
|
|
|
@@ -126,6 +130,8 @@ export const consumeFirstRunIntro = async (
|
|
|
126
130
|
"- **Enable auth**: Add bearer tokens or custom authentication",
|
|
127
131
|
"- **Turn on telemetry**: Track usage with OpenTelemetry/OTLP",
|
|
128
132
|
"- **Add MCP servers**: Connect external tool servers",
|
|
133
|
+
"- **Schedule cron jobs**: Set up recurring tasks in AGENT.md frontmatter",
|
|
134
|
+
"- **Connect to Slack**: Set up messaging so users can @mention this agent in Slack",
|
|
129
135
|
"",
|
|
130
136
|
"Just let me know what you'd like to work on!\n",
|
|
131
137
|
].join("\n");
|
package/src/init-onboarding.ts
CHANGED
|
@@ -339,12 +339,20 @@ export const buildConfigFromOnboardingAnswers = (
|
|
|
339
339
|
};
|
|
340
340
|
maybeSet(telemetry, "otlp", answers["telemetry.otlp"]);
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
const messagingPlatform = String(answers["messaging.platform"] ?? "none");
|
|
343
|
+
|
|
344
|
+
const config: PonchoConfig = {
|
|
343
345
|
mcp: [],
|
|
344
346
|
auth,
|
|
345
347
|
storage,
|
|
346
348
|
telemetry,
|
|
347
349
|
};
|
|
350
|
+
|
|
351
|
+
if (messagingPlatform !== "none") {
|
|
352
|
+
config.messaging = [{ platform: messagingPlatform as "slack" }];
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return config;
|
|
348
356
|
};
|
|
349
357
|
|
|
350
358
|
export const isDefaultOnboardingConfig = (
|
|
@@ -354,7 +362,7 @@ export const isDefaultOnboardingConfig = (
|
|
|
354
362
|
return true;
|
|
355
363
|
}
|
|
356
364
|
const topLevelKeys = Object.keys(config);
|
|
357
|
-
const allowedTopLevel = new Set(["mcp", "auth", "storage", "telemetry"]);
|
|
365
|
+
const allowedTopLevel = new Set(["mcp", "auth", "storage", "telemetry", "messaging"]);
|
|
358
366
|
if (topLevelKeys.some((key) => !allowedTopLevel.has(key))) {
|
|
359
367
|
return false;
|
|
360
368
|
}
|
package/test/cli.test.ts
CHANGED
|
@@ -11,7 +11,10 @@ import {
|
|
|
11
11
|
initializeOnboardingMarker,
|
|
12
12
|
} from "../src/init-feature-context.js";
|
|
13
13
|
|
|
14
|
-
vi.mock("@poncho-ai/harness", () =>
|
|
14
|
+
vi.mock("@poncho-ai/harness", async (importOriginal) => {
|
|
15
|
+
const actual = await importOriginal<typeof import("@poncho-ai/harness")>();
|
|
16
|
+
return {
|
|
17
|
+
parseAgentMarkdown: actual.parseAgentMarkdown,
|
|
15
18
|
AgentHarness: class MockHarness {
|
|
16
19
|
async initialize(): Promise<void> {}
|
|
17
20
|
listTools(): Array<{ name: string; description: string }> {
|
|
@@ -160,7 +163,7 @@ vi.mock("@poncho-ai/harness", () => ({
|
|
|
160
163
|
get: async () => Buffer.from(""),
|
|
161
164
|
delete: async () => {},
|
|
162
165
|
}),
|
|
163
|
-
})
|
|
166
|
+
};});
|
|
164
167
|
|
|
165
168
|
import {
|
|
166
169
|
buildTarget,
|
|
@@ -920,6 +923,43 @@ describe("cli", () => {
|
|
|
920
923
|
expect(result.failed).toBe(0);
|
|
921
924
|
});
|
|
922
925
|
|
|
926
|
+
it("includes crons in vercel.json when AGENT.md has cron jobs", async () => {
|
|
927
|
+
await initProject("cron-agent", { workingDir: tempDir });
|
|
928
|
+
const projectDir = join(tempDir, "cron-agent");
|
|
929
|
+
const agentMdPath = join(projectDir, "AGENT.md");
|
|
930
|
+
const agentMd = await readFile(agentMdPath, "utf8");
|
|
931
|
+
// Insert cron block before the closing --- of frontmatter
|
|
932
|
+
const updatedAgentMd = agentMd.replace(
|
|
933
|
+
/^(---\n[\s\S]*?)(---\n)/m,
|
|
934
|
+
`$1cron:\n daily-report:\n schedule: "0 9 * * *"\n task: "Generate the daily report"\n health-check:\n schedule: "*/30 * * * *"\n task: "Check all APIs"\n$2`,
|
|
935
|
+
);
|
|
936
|
+
await writeFile(agentMdPath, updatedAgentMd, "utf8");
|
|
937
|
+
await buildTarget(projectDir, "vercel", { force: true });
|
|
938
|
+
const vercelConfig = JSON.parse(
|
|
939
|
+
await readFile(join(projectDir, "vercel.json"), "utf8"),
|
|
940
|
+
) as { crons?: Array<{ path: string; schedule: string }> };
|
|
941
|
+
expect(vercelConfig.crons).toBeDefined();
|
|
942
|
+
expect(vercelConfig.crons).toHaveLength(2);
|
|
943
|
+
expect(vercelConfig.crons).toContainEqual({
|
|
944
|
+
path: "/api/cron/daily-report",
|
|
945
|
+
schedule: "0 9 * * *",
|
|
946
|
+
});
|
|
947
|
+
expect(vercelConfig.crons).toContainEqual({
|
|
948
|
+
path: "/api/cron/health-check",
|
|
949
|
+
schedule: "*/30 * * * *",
|
|
950
|
+
});
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
it("omits crons from vercel.json when AGENT.md has no cron jobs", async () => {
|
|
954
|
+
await initProject("no-cron-agent", { workingDir: tempDir });
|
|
955
|
+
const projectDir = join(tempDir, "no-cron-agent");
|
|
956
|
+
await buildTarget(projectDir, "vercel", { force: true });
|
|
957
|
+
const vercelConfig = JSON.parse(
|
|
958
|
+
await readFile(join(projectDir, "vercel.json"), "utf8"),
|
|
959
|
+
) as { crons?: unknown };
|
|
960
|
+
expect(vercelConfig.crons).toBeUndefined();
|
|
961
|
+
});
|
|
962
|
+
|
|
923
963
|
it("fails on existing deploy files unless force is enabled", async () => {
|
|
924
964
|
await initProject("collision-agent", { workingDir: tempDir });
|
|
925
965
|
const projectDir = join(tempDir, "collision-agent");
|