@poncho-ai/cli 0.30.4 → 0.30.5

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @poncho-ai/cli@0.30.4 build /home/runner/work/poncho-ai/poncho-ai/packages/cli
2
+ > @poncho-ai/cli@0.30.5 build /home/runner/work/poncho-ai/poncho-ai/packages/cli
3
3
  > tsup src/index.ts src/cli.ts --format esm --dts
4
4
 
5
5
  CLI Building entry: src/cli.ts, src/index.ts
@@ -9,10 +9,10 @@
9
9
  ESM Build start
10
10
  ESM dist/cli.js 94.00 B
11
11
  ESM dist/index.js 857.00 B
12
- ESM dist/run-interactive-ink-VEUZATR3.js 56.86 KB
13
- ESM dist/chunk-EZUW7UI3.js 491.51 KB
12
+ ESM dist/run-interactive-ink-KA5V5BSJ.js 56.86 KB
13
+ ESM dist/chunk-V3H773RB.js 492.00 KB
14
14
  ESM ⚡️ Build success in 62ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 3983ms
16
+ DTS ⚡️ Build success in 4158ms
17
17
  DTS dist/cli.d.ts 20.00 B
18
18
  DTS dist/index.d.ts 4.16 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @poncho-ai/cli
2
2
 
3
+ ## 0.30.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [`031abc7`](https://github.com/cesr/poncho-ai/commit/031abc770b85141da5fdd209c6bf8f594f5552e4) Thanks [@cesr](https://github.com/cesr)! - Fix cron job continuation on serverless
8
+ - Persist \_continuationMessages so cron continuations resume from correct harness state
9
+ - Use selfFetchWithRetry with doWaitUntil instead of raw fetch for cron continuation trigger
10
+ - Extend internal auth bypass to /api/cron/ paths for continuation self-fetch
11
+ - Add startup warning when VERCEL_AUTOMATION_BYPASS_SECRET is missing
12
+
3
13
  ## 0.30.4
4
14
 
5
15
  ### Patch Changes
@@ -9822,6 +9822,11 @@ ${resultBody}`,
9822
9822
  if (waitUntilHook) waitUntilHook(promise);
9823
9823
  };
9824
9824
  const vercelBypassSecret = process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();
9825
+ if (process.env.VERCEL && !vercelBypassSecret) {
9826
+ console.warn(
9827
+ "\n[poncho] Vercel Deployment Protection will block subagents and auto-continuation.\n Enable 'Protection Bypass for Automation' in your Vercel project settings:\n -> Project Settings > Deployment Protection > Protection Bypass for Automation\n The secret is auto-provisioned as VERCEL_AUTOMATION_BYPASS_SECRET.\n"
9828
+ );
9829
+ }
9825
9830
  const selfFetchWithRetry = async (path, body, retries = 3) => {
9826
9831
  if (!selfBaseUrl) {
9827
9832
  console.error(`[poncho][self-fetch] Missing self base URL for ${path}`);
@@ -10320,7 +10325,8 @@ ${resultBody}`,
10320
10325
  return;
10321
10326
  }
10322
10327
  if (pathname.startsWith("/api/")) {
10323
- const isInternal = pathname.startsWith("/api/internal/") && request.method === "POST" && isValidInternalRequest(request.headers);
10328
+ const isInternalPath = pathname.startsWith("/api/internal/") || pathname.startsWith("/api/cron/");
10329
+ const isInternal = isInternalPath && request.method === "POST" && isValidInternalRequest(request.headers);
10324
10330
  const hasBearerToken = request.headers.authorization?.startsWith("Bearer ");
10325
10331
  const isAuthenticated = isInternal || !requireAuth || session || validateBearerToken(request.headers.authorization);
10326
10332
  if (!isAuthenticated) {
@@ -11604,7 +11610,7 @@ ${cronJob.task}`;
11604
11610
  });
11605
11611
  return;
11606
11612
  }
11607
- historyMessages = [...conversation.messages];
11613
+ historyMessages = conversation._continuationMessages?.length ? [...conversation._continuationMessages] : [...conversation.messages];
11608
11614
  } else {
11609
11615
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
11610
11616
  conversation = await conversationStore.create(
@@ -11622,6 +11628,7 @@ ${cronJob.task}`;
11622
11628
  const abortController = new AbortController();
11623
11629
  let assistantResponse = "";
11624
11630
  let latestRunId = "";
11631
+ let runContinuationMessages;
11625
11632
  const toolTimeline = [];
11626
11633
  const sections = [];
11627
11634
  let currentTools = [];
@@ -11680,6 +11687,9 @@ ${cronJob.task}`;
11680
11687
  contextTokens: event.result.contextTokens,
11681
11688
  contextWindow: event.result.contextWindow
11682
11689
  };
11690
+ if (event.result.continuation && event.result.continuationMessages) {
11691
+ runContinuationMessages = event.result.continuationMessages;
11692
+ }
11683
11693
  if (!assistantResponse && event.result.response) {
11684
11694
  assistantResponse = event.result.response;
11685
11695
  }
@@ -11707,37 +11717,30 @@ ${cronJob.task}`;
11707
11717
  ];
11708
11718
  const freshConv = await conversationStore.get(convId);
11709
11719
  if (freshConv) {
11710
- freshConv.messages = messages;
11720
+ if (runContinuationMessages) {
11721
+ freshConv._continuationMessages = runContinuationMessages;
11722
+ } else {
11723
+ freshConv._continuationMessages = void 0;
11724
+ freshConv.messages = messages;
11725
+ }
11711
11726
  freshConv.runtimeRunId = latestRunId || freshConv.runtimeRunId;
11712
11727
  if (runResult.contextTokens) freshConv.contextTokens = runResult.contextTokens;
11713
11728
  if (runResult.contextWindow) freshConv.contextWindow = runResult.contextWindow;
11714
11729
  freshConv.updatedAt = Date.now();
11715
11730
  await conversationStore.update(freshConv);
11716
11731
  }
11717
- if (runResult.continuation && softDeadlineMs > 0) {
11718
- const selfUrl = `http://${request.headers.host ?? "localhost"}${pathname}?continue=${encodeURIComponent(convId)}&continuation=${continuationCount + 1}`;
11719
- try {
11720
- const selfRes = await fetch(selfUrl, {
11721
- method: "GET",
11722
- headers: request.headers.authorization ? { authorization: request.headers.authorization } : {}
11723
- });
11724
- const selfBody = await selfRes.json();
11725
- writeJson(response, 200, {
11726
- conversationId: convId,
11727
- status: "continued",
11728
- continuations: continuationCount + 1,
11729
- finalResult: selfBody,
11730
- duration: Date.now() - start
11731
- });
11732
- } catch (continueError) {
11733
- writeJson(response, 200, {
11734
- conversationId: convId,
11735
- status: "continuation_failed",
11736
- error: continueError instanceof Error ? continueError.message : "Unknown error",
11737
- duration: Date.now() - start,
11738
- steps: runResult.steps
11739
- });
11740
- }
11732
+ if (runResult.continuation) {
11733
+ const continuationPath = `/api/cron/${encodeURIComponent(jobName)}?continue=${encodeURIComponent(convId)}&continuation=${continuationCount + 1}`;
11734
+ const work = selfFetchWithRetry(continuationPath).catch(
11735
+ (err) => console.error(`[poncho][cron] Continuation self-fetch failed:`, err instanceof Error ? err.message : err)
11736
+ );
11737
+ doWaitUntil(work);
11738
+ writeJson(response, 200, {
11739
+ conversationId: convId,
11740
+ status: "continued",
11741
+ continuations: continuationCount + 1,
11742
+ duration: Date.now() - start
11743
+ });
11741
11744
  return;
11742
11745
  }
11743
11746
  writeJson(response, 200, {
@@ -12183,7 +12186,7 @@ var runInteractive = async (workingDir, params) => {
12183
12186
  await harness.initialize();
12184
12187
  const identity = await ensureAgentIdentity2(workingDir);
12185
12188
  try {
12186
- const { runInteractiveInk } = await import("./run-interactive-ink-VEUZATR3.js");
12189
+ const { runInteractiveInk } = await import("./run-interactive-ink-KA5V5BSJ.js");
12187
12190
  await runInteractiveInk({
12188
12191
  harness,
12189
12192
  params,
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  main
4
- } from "./chunk-EZUW7UI3.js";
4
+ } from "./chunk-V3H773RB.js";
5
5
 
6
6
  // src/cli.ts
7
7
  void main();
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  runTests,
24
24
  startDevServer,
25
25
  updateAgentGuidance
26
- } from "./chunk-EZUW7UI3.js";
26
+ } from "./chunk-V3H773RB.js";
27
27
  export {
28
28
  addSkill,
29
29
  buildCli,
@@ -2,7 +2,7 @@ import {
2
2
  consumeFirstRunIntro,
3
3
  inferConversationTitle,
4
4
  resolveHarnessEnvironment
5
- } from "./chunk-EZUW7UI3.js";
5
+ } from "./chunk-V3H773RB.js";
6
6
 
7
7
  // src/run-interactive-ink.ts
8
8
  import * as readline from "readline";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poncho-ai/cli",
3
- "version": "0.30.4",
3
+ "version": "0.30.5",
4
4
  "description": "CLI for building and deploying AI agents",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,9 +27,9 @@
27
27
  "react": "^19.2.4",
28
28
  "react-devtools-core": "^6.1.5",
29
29
  "yaml": "^2.8.1",
30
- "@poncho-ai/messaging": "0.7.2",
30
+ "@poncho-ai/harness": "0.28.3",
31
31
  "@poncho-ai/sdk": "1.6.1",
32
- "@poncho-ai/harness": "0.28.3"
32
+ "@poncho-ai/messaging": "0.7.2"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/busboy": "^1.5.4",
package/src/index.ts CHANGED
@@ -3075,6 +3075,14 @@ export const createRequestHandler = async (options?: {
3075
3075
  };
3076
3076
 
3077
3077
  const vercelBypassSecret = process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();
3078
+ if (process.env.VERCEL && !vercelBypassSecret) {
3079
+ console.warn(
3080
+ "\n[poncho] Vercel Deployment Protection will block subagents and auto-continuation." +
3081
+ "\n Enable 'Protection Bypass for Automation' in your Vercel project settings:" +
3082
+ "\n -> Project Settings > Deployment Protection > Protection Bypass for Automation" +
3083
+ "\n The secret is auto-provisioned as VERCEL_AUTOMATION_BYPASS_SECRET.\n",
3084
+ );
3085
+ }
3078
3086
 
3079
3087
  const selfFetchWithRetry = async (path: string, body?: Record<string, unknown>, retries = 3): Promise<Response | void> => {
3080
3088
  if (!selfBaseUrl) {
@@ -3647,7 +3655,8 @@ export const createRequestHandler = async (options?: {
3647
3655
 
3648
3656
  if (pathname.startsWith("/api/")) {
3649
3657
  // Internal self-fetch requests bypass user-facing auth
3650
- const isInternal = pathname.startsWith("/api/internal/") && request.method === "POST" && isValidInternalRequest(request.headers);
3658
+ const isInternalPath = pathname.startsWith("/api/internal/") || pathname.startsWith("/api/cron/");
3659
+ const isInternal = isInternalPath && request.method === "POST" && isValidInternalRequest(request.headers);
3651
3660
 
3652
3661
  // Check authentication: either valid session (Web UI), valid Bearer token (API), or valid internal request
3653
3662
  const hasBearerToken = request.headers.authorization?.startsWith("Bearer ");
@@ -5110,7 +5119,9 @@ export const createRequestHandler = async (options?: {
5110
5119
  });
5111
5120
  return;
5112
5121
  }
5113
- historyMessages = [...conversation.messages];
5122
+ historyMessages = conversation._continuationMessages?.length
5123
+ ? [...conversation._continuationMessages]
5124
+ : [...conversation.messages];
5114
5125
  } else {
5115
5126
  const timestamp = new Date().toISOString();
5116
5127
  conversation = await conversationStore.create(
@@ -5130,6 +5141,7 @@ export const createRequestHandler = async (options?: {
5130
5141
  const abortController = new AbortController();
5131
5142
  let assistantResponse = "";
5132
5143
  let latestRunId = "";
5144
+ let runContinuationMessages: Message[] | undefined;
5133
5145
  const toolTimeline: string[] = [];
5134
5146
  const sections: Array<{ type: "text" | "tools"; content: string | string[] }> = [];
5135
5147
  let currentTools: string[] = [];
@@ -5192,6 +5204,9 @@ export const createRequestHandler = async (options?: {
5192
5204
  contextTokens: event.result.contextTokens,
5193
5205
  contextWindow: event.result.contextWindow,
5194
5206
  };
5207
+ if (event.result.continuation && event.result.continuationMessages) {
5208
+ runContinuationMessages = event.result.continuationMessages;
5209
+ }
5195
5210
  if (!assistantResponse && event.result.response) {
5196
5211
  assistantResponse = event.result.response;
5197
5212
  }
@@ -5231,7 +5246,12 @@ export const createRequestHandler = async (options?: {
5231
5246
  ];
5232
5247
  const freshConv = await conversationStore.get(convId);
5233
5248
  if (freshConv) {
5234
- freshConv.messages = messages;
5249
+ if (runContinuationMessages) {
5250
+ freshConv._continuationMessages = runContinuationMessages;
5251
+ } else {
5252
+ freshConv._continuationMessages = undefined;
5253
+ freshConv.messages = messages;
5254
+ }
5235
5255
  freshConv.runtimeRunId = latestRunId || freshConv.runtimeRunId;
5236
5256
  if (runResult.contextTokens) freshConv.contextTokens = runResult.contextTokens;
5237
5257
  if (runResult.contextWindow) freshConv.contextWindow = runResult.contextWindow;
@@ -5239,33 +5259,18 @@ export const createRequestHandler = async (options?: {
5239
5259
  await conversationStore.update(freshConv);
5240
5260
  }
5241
5261
 
5242
- // Self-continuation for serverless timeouts
5243
- if (runResult.continuation && softDeadlineMs > 0) {
5244
- const selfUrl = `http://${request.headers.host ?? "localhost"}${pathname}?continue=${encodeURIComponent(convId)}&continuation=${continuationCount + 1}`;
5245
- try {
5246
- const selfRes = await fetch(selfUrl, {
5247
- method: "GET",
5248
- headers: request.headers.authorization
5249
- ? { authorization: request.headers.authorization }
5250
- : {},
5251
- });
5252
- const selfBody = await selfRes.json() as Record<string, unknown>;
5253
- writeJson(response, 200, {
5254
- conversationId: convId,
5255
- status: "continued",
5256
- continuations: continuationCount + 1,
5257
- finalResult: selfBody,
5258
- duration: Date.now() - start,
5259
- });
5260
- } catch (continueError) {
5261
- writeJson(response, 200, {
5262
- conversationId: convId,
5263
- status: "continuation_failed",
5264
- error: continueError instanceof Error ? continueError.message : "Unknown error",
5265
- duration: Date.now() - start,
5266
- steps: runResult.steps,
5267
- });
5268
- }
5262
+ if (runResult.continuation) {
5263
+ const continuationPath = `/api/cron/${encodeURIComponent(jobName)}?continue=${encodeURIComponent(convId)}&continuation=${continuationCount + 1}`;
5264
+ const work = selfFetchWithRetry(continuationPath).catch(err =>
5265
+ console.error(`[poncho][cron] Continuation self-fetch failed:`, err instanceof Error ? err.message : err),
5266
+ );
5267
+ doWaitUntil(work);
5268
+ writeJson(response, 200, {
5269
+ conversationId: convId,
5270
+ status: "continued",
5271
+ continuations: continuationCount + 1,
5272
+ duration: Date.now() - start,
5273
+ });
5269
5274
  return;
5270
5275
  }
5271
5276