@poncho-ai/cli 0.30.3 → 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.
- package/.turbo/turbo-build.log +5 -5
- package/CHANGELOG.md +19 -0
- package/dist/{chunk-FA546WPW.js → chunk-V3H773RB.js} +50 -35
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{run-interactive-ink-FUMHN6DS.js → run-interactive-ink-KA5V5BSJ.js} +1 -1
- package/package.json +1 -1
- package/src/index.ts +58 -38
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/cli@0.30.
|
|
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
|
[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-KA5V5BSJ.js [22m[32m56.86 KB[39m
|
|
13
|
+
[32mESM[39m [1mdist/chunk-V3H773RB.js [22m[32m492.00 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 62ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 4158ms
|
|
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,24 @@
|
|
|
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
|
+
|
|
13
|
+
## 0.30.4
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [`ea8b5da`](https://github.com/cesr/poncho-ai/commit/ea8b5da1bca5d45c05a68a43c4850aacee612ffb) Thanks [@cesr](https://github.com/cesr)! - Fix internal self-fetch blocked by Vercel Deployment Protection and PONCHO_AUTH_TOKEN
|
|
18
|
+
- Include x-vercel-protection-bypass header when VERCEL_AUTOMATION_BYPASS_SECRET is set
|
|
19
|
+
- Internal requests with valid x-poncho-internal header bypass the PONCHO_AUTH_TOKEN auth gate
|
|
20
|
+
- Better error messages distinguishing Vercel Deployment Protection from internal auth failures
|
|
21
|
+
|
|
3
22
|
## 0.30.3
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -9821,6 +9821,12 @@ ${resultBody}`,
|
|
|
9821
9821
|
const doWaitUntil = (promise) => {
|
|
9822
9822
|
if (waitUntilHook) waitUntilHook(promise);
|
|
9823
9823
|
};
|
|
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
|
+
}
|
|
9824
9830
|
const selfFetchWithRetry = async (path, body, retries = 3) => {
|
|
9825
9831
|
if (!selfBaseUrl) {
|
|
9826
9832
|
console.error(`[poncho][self-fetch] Missing self base URL for ${path}`);
|
|
@@ -9829,12 +9835,16 @@ ${resultBody}`,
|
|
|
9829
9835
|
let lastError;
|
|
9830
9836
|
for (let attempt = 0; attempt < retries; attempt++) {
|
|
9831
9837
|
try {
|
|
9838
|
+
const headers = {
|
|
9839
|
+
"Content-Type": "application/json",
|
|
9840
|
+
"x-poncho-internal": internalSecret
|
|
9841
|
+
};
|
|
9842
|
+
if (vercelBypassSecret) {
|
|
9843
|
+
headers["x-vercel-protection-bypass"] = vercelBypassSecret;
|
|
9844
|
+
}
|
|
9832
9845
|
const result = await fetch(`${selfBaseUrl}${path}`, {
|
|
9833
9846
|
method: "POST",
|
|
9834
|
-
headers
|
|
9835
|
-
"Content-Type": "application/json",
|
|
9836
|
-
"x-poncho-internal": internalSecret
|
|
9837
|
-
},
|
|
9847
|
+
headers,
|
|
9838
9848
|
body: body ? JSON.stringify(body) : void 0
|
|
9839
9849
|
});
|
|
9840
9850
|
if (result.ok) {
|
|
@@ -9858,9 +9868,15 @@ ${resultBody}`,
|
|
|
9858
9868
|
lastError instanceof Error ? lastError.message : String(lastError)
|
|
9859
9869
|
);
|
|
9860
9870
|
if (lastError instanceof Error && (lastError.message.includes("HTTP 403") || lastError.message.includes("HTTP 401"))) {
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9871
|
+
if (lastError.message.includes("HTTP 401") && lastError.message.includes("<!doctype")) {
|
|
9872
|
+
console.error(
|
|
9873
|
+
"[poncho][self-fetch] Blocked by Vercel Deployment Protection. Set VERCEL_AUTOMATION_BYPASS_SECRET in your Vercel project settings and env vars."
|
|
9874
|
+
);
|
|
9875
|
+
} else {
|
|
9876
|
+
console.error(
|
|
9877
|
+
"[poncho][self-fetch] Internal auth failed. Ensure all serverless instances share PONCHO_INTERNAL_SECRET."
|
|
9878
|
+
);
|
|
9879
|
+
}
|
|
9864
9880
|
}
|
|
9865
9881
|
} else {
|
|
9866
9882
|
console.error(`[poncho][self-fetch] Failed ${path} after ${retries} attempt(s).`);
|
|
@@ -10309,8 +10325,10 @@ ${resultBody}`,
|
|
|
10309
10325
|
return;
|
|
10310
10326
|
}
|
|
10311
10327
|
if (pathname.startsWith("/api/")) {
|
|
10328
|
+
const isInternalPath = pathname.startsWith("/api/internal/") || pathname.startsWith("/api/cron/");
|
|
10329
|
+
const isInternal = isInternalPath && request.method === "POST" && isValidInternalRequest(request.headers);
|
|
10312
10330
|
const hasBearerToken = request.headers.authorization?.startsWith("Bearer ");
|
|
10313
|
-
const isAuthenticated = !requireAuth || session || validateBearerToken(request.headers.authorization);
|
|
10331
|
+
const isAuthenticated = isInternal || !requireAuth || session || validateBearerToken(request.headers.authorization);
|
|
10314
10332
|
if (!isAuthenticated) {
|
|
10315
10333
|
writeJson(response, 401, {
|
|
10316
10334
|
code: "AUTH_ERROR",
|
|
@@ -11592,7 +11610,7 @@ ${cronJob.task}`;
|
|
|
11592
11610
|
});
|
|
11593
11611
|
return;
|
|
11594
11612
|
}
|
|
11595
|
-
historyMessages = [...conversation.messages];
|
|
11613
|
+
historyMessages = conversation._continuationMessages?.length ? [...conversation._continuationMessages] : [...conversation.messages];
|
|
11596
11614
|
} else {
|
|
11597
11615
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
11598
11616
|
conversation = await conversationStore.create(
|
|
@@ -11610,6 +11628,7 @@ ${cronJob.task}`;
|
|
|
11610
11628
|
const abortController = new AbortController();
|
|
11611
11629
|
let assistantResponse = "";
|
|
11612
11630
|
let latestRunId = "";
|
|
11631
|
+
let runContinuationMessages;
|
|
11613
11632
|
const toolTimeline = [];
|
|
11614
11633
|
const sections = [];
|
|
11615
11634
|
let currentTools = [];
|
|
@@ -11668,6 +11687,9 @@ ${cronJob.task}`;
|
|
|
11668
11687
|
contextTokens: event.result.contextTokens,
|
|
11669
11688
|
contextWindow: event.result.contextWindow
|
|
11670
11689
|
};
|
|
11690
|
+
if (event.result.continuation && event.result.continuationMessages) {
|
|
11691
|
+
runContinuationMessages = event.result.continuationMessages;
|
|
11692
|
+
}
|
|
11671
11693
|
if (!assistantResponse && event.result.response) {
|
|
11672
11694
|
assistantResponse = event.result.response;
|
|
11673
11695
|
}
|
|
@@ -11695,37 +11717,30 @@ ${cronJob.task}`;
|
|
|
11695
11717
|
];
|
|
11696
11718
|
const freshConv = await conversationStore.get(convId);
|
|
11697
11719
|
if (freshConv) {
|
|
11698
|
-
|
|
11720
|
+
if (runContinuationMessages) {
|
|
11721
|
+
freshConv._continuationMessages = runContinuationMessages;
|
|
11722
|
+
} else {
|
|
11723
|
+
freshConv._continuationMessages = void 0;
|
|
11724
|
+
freshConv.messages = messages;
|
|
11725
|
+
}
|
|
11699
11726
|
freshConv.runtimeRunId = latestRunId || freshConv.runtimeRunId;
|
|
11700
11727
|
if (runResult.contextTokens) freshConv.contextTokens = runResult.contextTokens;
|
|
11701
11728
|
if (runResult.contextWindow) freshConv.contextWindow = runResult.contextWindow;
|
|
11702
11729
|
freshConv.updatedAt = Date.now();
|
|
11703
11730
|
await conversationStore.update(freshConv);
|
|
11704
11731
|
}
|
|
11705
|
-
if (runResult.continuation
|
|
11706
|
-
const
|
|
11707
|
-
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
finalResult: selfBody,
|
|
11718
|
-
duration: Date.now() - start
|
|
11719
|
-
});
|
|
11720
|
-
} catch (continueError) {
|
|
11721
|
-
writeJson(response, 200, {
|
|
11722
|
-
conversationId: convId,
|
|
11723
|
-
status: "continuation_failed",
|
|
11724
|
-
error: continueError instanceof Error ? continueError.message : "Unknown error",
|
|
11725
|
-
duration: Date.now() - start,
|
|
11726
|
-
steps: runResult.steps
|
|
11727
|
-
});
|
|
11728
|
-
}
|
|
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
|
+
});
|
|
11729
11744
|
return;
|
|
11730
11745
|
}
|
|
11731
11746
|
writeJson(response, 200, {
|
|
@@ -12171,7 +12186,7 @@ var runInteractive = async (workingDir, params) => {
|
|
|
12171
12186
|
await harness.initialize();
|
|
12172
12187
|
const identity = await ensureAgentIdentity2(workingDir);
|
|
12173
12188
|
try {
|
|
12174
|
-
const { runInteractiveInk } = await import("./run-interactive-ink-
|
|
12189
|
+
const { runInteractiveInk } = await import("./run-interactive-ink-KA5V5BSJ.js");
|
|
12175
12190
|
await runInteractiveInk({
|
|
12176
12191
|
harness,
|
|
12177
12192
|
params,
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -3074,6 +3074,16 @@ export const createRequestHandler = async (options?: {
|
|
|
3074
3074
|
if (waitUntilHook) waitUntilHook(promise);
|
|
3075
3075
|
};
|
|
3076
3076
|
|
|
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
|
+
|
|
3077
3087
|
const selfFetchWithRetry = async (path: string, body?: Record<string, unknown>, retries = 3): Promise<Response | void> => {
|
|
3078
3088
|
if (!selfBaseUrl) {
|
|
3079
3089
|
console.error(`[poncho][self-fetch] Missing self base URL for ${path}`);
|
|
@@ -3082,12 +3092,16 @@ export const createRequestHandler = async (options?: {
|
|
|
3082
3092
|
let lastError: unknown;
|
|
3083
3093
|
for (let attempt = 0; attempt < retries; attempt++) {
|
|
3084
3094
|
try {
|
|
3095
|
+
const headers: Record<string, string> = {
|
|
3096
|
+
"Content-Type": "application/json",
|
|
3097
|
+
"x-poncho-internal": internalSecret,
|
|
3098
|
+
};
|
|
3099
|
+
if (vercelBypassSecret) {
|
|
3100
|
+
headers["x-vercel-protection-bypass"] = vercelBypassSecret;
|
|
3101
|
+
}
|
|
3085
3102
|
const result = await fetch(`${selfBaseUrl}${path}`, {
|
|
3086
3103
|
method: "POST",
|
|
3087
|
-
headers
|
|
3088
|
-
"Content-Type": "application/json",
|
|
3089
|
-
"x-poncho-internal": internalSecret,
|
|
3090
|
-
},
|
|
3104
|
+
headers,
|
|
3091
3105
|
body: body ? JSON.stringify(body) : undefined,
|
|
3092
3106
|
});
|
|
3093
3107
|
if (result.ok) {
|
|
@@ -3114,9 +3128,15 @@ export const createRequestHandler = async (options?: {
|
|
|
3114
3128
|
lastError instanceof Error
|
|
3115
3129
|
&& (lastError.message.includes("HTTP 403") || lastError.message.includes("HTTP 401"))
|
|
3116
3130
|
) {
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3131
|
+
if (lastError.message.includes("HTTP 401") && lastError.message.includes("<!doctype")) {
|
|
3132
|
+
console.error(
|
|
3133
|
+
"[poncho][self-fetch] Blocked by Vercel Deployment Protection. Set VERCEL_AUTOMATION_BYPASS_SECRET in your Vercel project settings and env vars.",
|
|
3134
|
+
);
|
|
3135
|
+
} else {
|
|
3136
|
+
console.error(
|
|
3137
|
+
"[poncho][self-fetch] Internal auth failed. Ensure all serverless instances share PONCHO_INTERNAL_SECRET.",
|
|
3138
|
+
);
|
|
3139
|
+
}
|
|
3120
3140
|
}
|
|
3121
3141
|
} else {
|
|
3122
3142
|
console.error(`[poncho][self-fetch] Failed ${path} after ${retries} attempt(s).`);
|
|
@@ -3634,9 +3654,13 @@ export const createRequestHandler = async (options?: {
|
|
|
3634
3654
|
}
|
|
3635
3655
|
|
|
3636
3656
|
if (pathname.startsWith("/api/")) {
|
|
3637
|
-
//
|
|
3657
|
+
// Internal self-fetch requests bypass user-facing auth
|
|
3658
|
+
const isInternalPath = pathname.startsWith("/api/internal/") || pathname.startsWith("/api/cron/");
|
|
3659
|
+
const isInternal = isInternalPath && request.method === "POST" && isValidInternalRequest(request.headers);
|
|
3660
|
+
|
|
3661
|
+
// Check authentication: either valid session (Web UI), valid Bearer token (API), or valid internal request
|
|
3638
3662
|
const hasBearerToken = request.headers.authorization?.startsWith("Bearer ");
|
|
3639
|
-
const isAuthenticated = !requireAuth || session || validateBearerToken(request.headers.authorization);
|
|
3663
|
+
const isAuthenticated = isInternal || !requireAuth || session || validateBearerToken(request.headers.authorization);
|
|
3640
3664
|
|
|
3641
3665
|
if (!isAuthenticated) {
|
|
3642
3666
|
writeJson(response, 401, {
|
|
@@ -5095,7 +5119,9 @@ export const createRequestHandler = async (options?: {
|
|
|
5095
5119
|
});
|
|
5096
5120
|
return;
|
|
5097
5121
|
}
|
|
5098
|
-
historyMessages =
|
|
5122
|
+
historyMessages = conversation._continuationMessages?.length
|
|
5123
|
+
? [...conversation._continuationMessages]
|
|
5124
|
+
: [...conversation.messages];
|
|
5099
5125
|
} else {
|
|
5100
5126
|
const timestamp = new Date().toISOString();
|
|
5101
5127
|
conversation = await conversationStore.create(
|
|
@@ -5115,6 +5141,7 @@ export const createRequestHandler = async (options?: {
|
|
|
5115
5141
|
const abortController = new AbortController();
|
|
5116
5142
|
let assistantResponse = "";
|
|
5117
5143
|
let latestRunId = "";
|
|
5144
|
+
let runContinuationMessages: Message[] | undefined;
|
|
5118
5145
|
const toolTimeline: string[] = [];
|
|
5119
5146
|
const sections: Array<{ type: "text" | "tools"; content: string | string[] }> = [];
|
|
5120
5147
|
let currentTools: string[] = [];
|
|
@@ -5177,6 +5204,9 @@ export const createRequestHandler = async (options?: {
|
|
|
5177
5204
|
contextTokens: event.result.contextTokens,
|
|
5178
5205
|
contextWindow: event.result.contextWindow,
|
|
5179
5206
|
};
|
|
5207
|
+
if (event.result.continuation && event.result.continuationMessages) {
|
|
5208
|
+
runContinuationMessages = event.result.continuationMessages;
|
|
5209
|
+
}
|
|
5180
5210
|
if (!assistantResponse && event.result.response) {
|
|
5181
5211
|
assistantResponse = event.result.response;
|
|
5182
5212
|
}
|
|
@@ -5216,7 +5246,12 @@ export const createRequestHandler = async (options?: {
|
|
|
5216
5246
|
];
|
|
5217
5247
|
const freshConv = await conversationStore.get(convId);
|
|
5218
5248
|
if (freshConv) {
|
|
5219
|
-
|
|
5249
|
+
if (runContinuationMessages) {
|
|
5250
|
+
freshConv._continuationMessages = runContinuationMessages;
|
|
5251
|
+
} else {
|
|
5252
|
+
freshConv._continuationMessages = undefined;
|
|
5253
|
+
freshConv.messages = messages;
|
|
5254
|
+
}
|
|
5220
5255
|
freshConv.runtimeRunId = latestRunId || freshConv.runtimeRunId;
|
|
5221
5256
|
if (runResult.contextTokens) freshConv.contextTokens = runResult.contextTokens;
|
|
5222
5257
|
if (runResult.contextWindow) freshConv.contextWindow = runResult.contextWindow;
|
|
@@ -5224,33 +5259,18 @@ export const createRequestHandler = async (options?: {
|
|
|
5224
5259
|
await conversationStore.update(freshConv);
|
|
5225
5260
|
}
|
|
5226
5261
|
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
const
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
conversationId: convId,
|
|
5240
|
-
status: "continued",
|
|
5241
|
-
continuations: continuationCount + 1,
|
|
5242
|
-
finalResult: selfBody,
|
|
5243
|
-
duration: Date.now() - start,
|
|
5244
|
-
});
|
|
5245
|
-
} catch (continueError) {
|
|
5246
|
-
writeJson(response, 200, {
|
|
5247
|
-
conversationId: convId,
|
|
5248
|
-
status: "continuation_failed",
|
|
5249
|
-
error: continueError instanceof Error ? continueError.message : "Unknown error",
|
|
5250
|
-
duration: Date.now() - start,
|
|
5251
|
-
steps: runResult.steps,
|
|
5252
|
-
});
|
|
5253
|
-
}
|
|
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
|
+
});
|
|
5254
5274
|
return;
|
|
5255
5275
|
}
|
|
5256
5276
|
|