@poncho-ai/cli 0.30.4 → 0.30.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/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +16 -0
- package/dist/{chunk-EZUW7UI3.js → chunk-3QT2S6AJ.js} +38 -28
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{run-interactive-ink-VEUZATR3.js → run-interactive-ink-OX4CI23D.js} +1 -1
- package/package.json +3 -3
- package/src/index.ts +45 -30
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/cli@0.30.
|
|
2
|
+
> @poncho-ai/cli@0.30.6 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
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[32mESM[39m [1mdist/cli.js [22m[32m94.00 B[39m
|
|
11
11
|
[32mESM[39m [1mdist/index.js [22m[32m857.00 B[39m
|
|
12
|
-
[32mESM[39m [1mdist/run-interactive-ink-
|
|
13
|
-
[32mESM[39m [1mdist/chunk-
|
|
14
|
-
[32mESM[39m ⚡️ Build success in
|
|
12
|
+
[32mESM[39m [1mdist/run-interactive-ink-OX4CI23D.js [22m[32m56.86 KB[39m
|
|
13
|
+
[32mESM[39m [1mdist/chunk-3QT2S6AJ.js [22m[32m492.58 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 65ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 4618ms
|
|
17
17
|
[32mDTS[39m [1mdist/cli.d.ts [22m[32m20.00 B[39m
|
|
18
18
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m4.16 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @poncho-ai/cli
|
|
2
2
|
|
|
3
|
+
## 0.30.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`56001f5`](https://github.com/cesr/poncho-ai/commit/56001f52f599f013a08e57e5de4891c02ca358d5) Thanks [@cesr](https://github.com/cesr)! - Warn at startup when CRON_SECRET is missing on Vercel with auth enabled and cron jobs configured
|
|
8
|
+
|
|
9
|
+
## 0.30.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`031abc7`](https://github.com/cesr/poncho-ai/commit/031abc770b85141da5fdd209c6bf8f594f5552e4) Thanks [@cesr](https://github.com/cesr)! - Fix cron job continuation on serverless
|
|
14
|
+
- Persist \_continuationMessages so cron continuations resume from correct harness state
|
|
15
|
+
- Use selfFetchWithRetry with doWaitUntil instead of raw fetch for cron continuation trigger
|
|
16
|
+
- Extend internal auth bypass to /api/cron/ paths for continuation self-fetch
|
|
17
|
+
- Add startup warning when VERCEL_AUTOMATION_BYPASS_SECRET is missing
|
|
18
|
+
|
|
3
19
|
## 0.30.4
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -9822,6 +9822,18 @@ ${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
|
+
}
|
|
9830
|
+
const hasCronJobs = Object.keys(cronJobs).length > 0;
|
|
9831
|
+
const authTokenConfigured = !!process.env[config?.auth?.tokenEnv ?? "PONCHO_AUTH_TOKEN"] && (config?.auth?.required ?? false);
|
|
9832
|
+
if (process.env.VERCEL && hasCronJobs && authTokenConfigured && !process.env.CRON_SECRET) {
|
|
9833
|
+
console.warn(
|
|
9834
|
+
"\n[poncho] Cron jobs are configured but CRON_SECRET is not set.\n Vercel sends CRON_SECRET as a Bearer token when invoking cron endpoints.\n Set CRON_SECRET to the same value as PONCHO_AUTH_TOKEN in your Vercel env vars,\n otherwise cron invocations will be rejected with 401.\n"
|
|
9835
|
+
);
|
|
9836
|
+
}
|
|
9825
9837
|
const selfFetchWithRetry = async (path, body, retries = 3) => {
|
|
9826
9838
|
if (!selfBaseUrl) {
|
|
9827
9839
|
console.error(`[poncho][self-fetch] Missing self base URL for ${path}`);
|
|
@@ -10320,7 +10332,8 @@ ${resultBody}`,
|
|
|
10320
10332
|
return;
|
|
10321
10333
|
}
|
|
10322
10334
|
if (pathname.startsWith("/api/")) {
|
|
10323
|
-
const
|
|
10335
|
+
const isInternalPath = pathname.startsWith("/api/internal/") || pathname.startsWith("/api/cron/");
|
|
10336
|
+
const isInternal = isInternalPath && request.method === "POST" && isValidInternalRequest(request.headers);
|
|
10324
10337
|
const hasBearerToken = request.headers.authorization?.startsWith("Bearer ");
|
|
10325
10338
|
const isAuthenticated = isInternal || !requireAuth || session || validateBearerToken(request.headers.authorization);
|
|
10326
10339
|
if (!isAuthenticated) {
|
|
@@ -11604,7 +11617,7 @@ ${cronJob.task}`;
|
|
|
11604
11617
|
});
|
|
11605
11618
|
return;
|
|
11606
11619
|
}
|
|
11607
|
-
historyMessages = [...conversation.messages];
|
|
11620
|
+
historyMessages = conversation._continuationMessages?.length ? [...conversation._continuationMessages] : [...conversation.messages];
|
|
11608
11621
|
} else {
|
|
11609
11622
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
11610
11623
|
conversation = await conversationStore.create(
|
|
@@ -11622,6 +11635,7 @@ ${cronJob.task}`;
|
|
|
11622
11635
|
const abortController = new AbortController();
|
|
11623
11636
|
let assistantResponse = "";
|
|
11624
11637
|
let latestRunId = "";
|
|
11638
|
+
let runContinuationMessages;
|
|
11625
11639
|
const toolTimeline = [];
|
|
11626
11640
|
const sections = [];
|
|
11627
11641
|
let currentTools = [];
|
|
@@ -11680,6 +11694,9 @@ ${cronJob.task}`;
|
|
|
11680
11694
|
contextTokens: event.result.contextTokens,
|
|
11681
11695
|
contextWindow: event.result.contextWindow
|
|
11682
11696
|
};
|
|
11697
|
+
if (event.result.continuation && event.result.continuationMessages) {
|
|
11698
|
+
runContinuationMessages = event.result.continuationMessages;
|
|
11699
|
+
}
|
|
11683
11700
|
if (!assistantResponse && event.result.response) {
|
|
11684
11701
|
assistantResponse = event.result.response;
|
|
11685
11702
|
}
|
|
@@ -11707,37 +11724,30 @@ ${cronJob.task}`;
|
|
|
11707
11724
|
];
|
|
11708
11725
|
const freshConv = await conversationStore.get(convId);
|
|
11709
11726
|
if (freshConv) {
|
|
11710
|
-
|
|
11727
|
+
if (runContinuationMessages) {
|
|
11728
|
+
freshConv._continuationMessages = runContinuationMessages;
|
|
11729
|
+
} else {
|
|
11730
|
+
freshConv._continuationMessages = void 0;
|
|
11731
|
+
freshConv.messages = messages;
|
|
11732
|
+
}
|
|
11711
11733
|
freshConv.runtimeRunId = latestRunId || freshConv.runtimeRunId;
|
|
11712
11734
|
if (runResult.contextTokens) freshConv.contextTokens = runResult.contextTokens;
|
|
11713
11735
|
if (runResult.contextWindow) freshConv.contextWindow = runResult.contextWindow;
|
|
11714
11736
|
freshConv.updatedAt = Date.now();
|
|
11715
11737
|
await conversationStore.update(freshConv);
|
|
11716
11738
|
}
|
|
11717
|
-
if (runResult.continuation
|
|
11718
|
-
const
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
|
|
11728
|
-
|
|
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
|
-
}
|
|
11739
|
+
if (runResult.continuation) {
|
|
11740
|
+
const continuationPath = `/api/cron/${encodeURIComponent(jobName)}?continue=${encodeURIComponent(convId)}&continuation=${continuationCount + 1}`;
|
|
11741
|
+
const work = selfFetchWithRetry(continuationPath).catch(
|
|
11742
|
+
(err) => console.error(`[poncho][cron] Continuation self-fetch failed:`, err instanceof Error ? err.message : err)
|
|
11743
|
+
);
|
|
11744
|
+
doWaitUntil(work);
|
|
11745
|
+
writeJson(response, 200, {
|
|
11746
|
+
conversationId: convId,
|
|
11747
|
+
status: "continued",
|
|
11748
|
+
continuations: continuationCount + 1,
|
|
11749
|
+
duration: Date.now() - start
|
|
11750
|
+
});
|
|
11741
11751
|
return;
|
|
11742
11752
|
}
|
|
11743
11753
|
writeJson(response, 200, {
|
|
@@ -12183,7 +12193,7 @@ var runInteractive = async (workingDir, params) => {
|
|
|
12183
12193
|
await harness.initialize();
|
|
12184
12194
|
const identity = await ensureAgentIdentity2(workingDir);
|
|
12185
12195
|
try {
|
|
12186
|
-
const { runInteractiveInk } = await import("./run-interactive-ink-
|
|
12196
|
+
const { runInteractiveInk } = await import("./run-interactive-ink-OX4CI23D.js");
|
|
12187
12197
|
await runInteractiveInk({
|
|
12188
12198
|
harness,
|
|
12189
12199
|
params,
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poncho-ai/cli",
|
|
3
|
-
"version": "0.30.
|
|
3
|
+
"version": "0.30.6",
|
|
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/harness": "0.28.3",
|
|
30
31
|
"@poncho-ai/messaging": "0.7.2",
|
|
31
|
-
"@poncho-ai/sdk": "1.6.1"
|
|
32
|
-
"@poncho-ai/harness": "0.28.3"
|
|
32
|
+
"@poncho-ai/sdk": "1.6.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/busboy": "^1.5.4",
|
package/src/index.ts
CHANGED
|
@@ -3075,6 +3075,24 @@ 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
|
+
}
|
|
3086
|
+
const hasCronJobs = Object.keys(cronJobs).length > 0;
|
|
3087
|
+
const authTokenConfigured = !!(process.env[config?.auth?.tokenEnv ?? "PONCHO_AUTH_TOKEN"]) && (config?.auth?.required ?? false);
|
|
3088
|
+
if (process.env.VERCEL && hasCronJobs && authTokenConfigured && !process.env.CRON_SECRET) {
|
|
3089
|
+
console.warn(
|
|
3090
|
+
"\n[poncho] Cron jobs are configured but CRON_SECRET is not set." +
|
|
3091
|
+
"\n Vercel sends CRON_SECRET as a Bearer token when invoking cron endpoints." +
|
|
3092
|
+
"\n Set CRON_SECRET to the same value as PONCHO_AUTH_TOKEN in your Vercel env vars," +
|
|
3093
|
+
"\n otherwise cron invocations will be rejected with 401.\n",
|
|
3094
|
+
);
|
|
3095
|
+
}
|
|
3078
3096
|
|
|
3079
3097
|
const selfFetchWithRetry = async (path: string, body?: Record<string, unknown>, retries = 3): Promise<Response | void> => {
|
|
3080
3098
|
if (!selfBaseUrl) {
|
|
@@ -3647,7 +3665,8 @@ export const createRequestHandler = async (options?: {
|
|
|
3647
3665
|
|
|
3648
3666
|
if (pathname.startsWith("/api/")) {
|
|
3649
3667
|
// Internal self-fetch requests bypass user-facing auth
|
|
3650
|
-
const
|
|
3668
|
+
const isInternalPath = pathname.startsWith("/api/internal/") || pathname.startsWith("/api/cron/");
|
|
3669
|
+
const isInternal = isInternalPath && request.method === "POST" && isValidInternalRequest(request.headers);
|
|
3651
3670
|
|
|
3652
3671
|
// Check authentication: either valid session (Web UI), valid Bearer token (API), or valid internal request
|
|
3653
3672
|
const hasBearerToken = request.headers.authorization?.startsWith("Bearer ");
|
|
@@ -5110,7 +5129,9 @@ export const createRequestHandler = async (options?: {
|
|
|
5110
5129
|
});
|
|
5111
5130
|
return;
|
|
5112
5131
|
}
|
|
5113
|
-
historyMessages =
|
|
5132
|
+
historyMessages = conversation._continuationMessages?.length
|
|
5133
|
+
? [...conversation._continuationMessages]
|
|
5134
|
+
: [...conversation.messages];
|
|
5114
5135
|
} else {
|
|
5115
5136
|
const timestamp = new Date().toISOString();
|
|
5116
5137
|
conversation = await conversationStore.create(
|
|
@@ -5130,6 +5151,7 @@ export const createRequestHandler = async (options?: {
|
|
|
5130
5151
|
const abortController = new AbortController();
|
|
5131
5152
|
let assistantResponse = "";
|
|
5132
5153
|
let latestRunId = "";
|
|
5154
|
+
let runContinuationMessages: Message[] | undefined;
|
|
5133
5155
|
const toolTimeline: string[] = [];
|
|
5134
5156
|
const sections: Array<{ type: "text" | "tools"; content: string | string[] }> = [];
|
|
5135
5157
|
let currentTools: string[] = [];
|
|
@@ -5192,6 +5214,9 @@ export const createRequestHandler = async (options?: {
|
|
|
5192
5214
|
contextTokens: event.result.contextTokens,
|
|
5193
5215
|
contextWindow: event.result.contextWindow,
|
|
5194
5216
|
};
|
|
5217
|
+
if (event.result.continuation && event.result.continuationMessages) {
|
|
5218
|
+
runContinuationMessages = event.result.continuationMessages;
|
|
5219
|
+
}
|
|
5195
5220
|
if (!assistantResponse && event.result.response) {
|
|
5196
5221
|
assistantResponse = event.result.response;
|
|
5197
5222
|
}
|
|
@@ -5231,7 +5256,12 @@ export const createRequestHandler = async (options?: {
|
|
|
5231
5256
|
];
|
|
5232
5257
|
const freshConv = await conversationStore.get(convId);
|
|
5233
5258
|
if (freshConv) {
|
|
5234
|
-
|
|
5259
|
+
if (runContinuationMessages) {
|
|
5260
|
+
freshConv._continuationMessages = runContinuationMessages;
|
|
5261
|
+
} else {
|
|
5262
|
+
freshConv._continuationMessages = undefined;
|
|
5263
|
+
freshConv.messages = messages;
|
|
5264
|
+
}
|
|
5235
5265
|
freshConv.runtimeRunId = latestRunId || freshConv.runtimeRunId;
|
|
5236
5266
|
if (runResult.contextTokens) freshConv.contextTokens = runResult.contextTokens;
|
|
5237
5267
|
if (runResult.contextWindow) freshConv.contextWindow = runResult.contextWindow;
|
|
@@ -5239,33 +5269,18 @@ export const createRequestHandler = async (options?: {
|
|
|
5239
5269
|
await conversationStore.update(freshConv);
|
|
5240
5270
|
}
|
|
5241
5271
|
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
const
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
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
|
-
}
|
|
5272
|
+
if (runResult.continuation) {
|
|
5273
|
+
const continuationPath = `/api/cron/${encodeURIComponent(jobName)}?continue=${encodeURIComponent(convId)}&continuation=${continuationCount + 1}`;
|
|
5274
|
+
const work = selfFetchWithRetry(continuationPath).catch(err =>
|
|
5275
|
+
console.error(`[poncho][cron] Continuation self-fetch failed:`, err instanceof Error ? err.message : err),
|
|
5276
|
+
);
|
|
5277
|
+
doWaitUntil(work);
|
|
5278
|
+
writeJson(response, 200, {
|
|
5279
|
+
conversationId: convId,
|
|
5280
|
+
status: "continued",
|
|
5281
|
+
continuations: continuationCount + 1,
|
|
5282
|
+
duration: Date.now() - start,
|
|
5283
|
+
});
|
|
5269
5284
|
return;
|
|
5270
5285
|
}
|
|
5271
5286
|
|