@poncho-ai/cli 0.26.0 → 0.27.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 +4 -4
- package/CHANGELOG.md +11 -0
- package/dist/{chunk-P3D4E4FZ.js → chunk-LPT2RFZ5.js} +36 -6
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{run-interactive-ink-4YCKM2JH.js → run-interactive-ink-OUX42GU4.js} +1 -1
- package/package.json +2 -2
- package/src/index.ts +32 -6
- package/src/web-ui.ts +3 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @poncho-ai/cli@0.
|
|
2
|
+
> @poncho-ai/cli@0.27.0 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-
|
|
12
|
+
[32mESM[39m [1mdist/run-interactive-ink-OUX42GU4.js [22m[32m56.74 KB[39m
|
|
13
|
+
[32mESM[39m [1mdist/chunk-LPT2RFZ5.js [22m[32m422.53 KB[39m
|
|
14
14
|
[32mESM[39m ⚡️ Build success in 63ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 4319ms
|
|
17
17
|
[32mDTS[39m [1mdist/cli.d.ts [22m[32m20.00 B[39m
|
|
18
18
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.70 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @poncho-ai/cli
|
|
2
2
|
|
|
3
|
+
## 0.27.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`aee4f17`](https://github.com/cesr/poncho-ai/commit/aee4f17237d33b2cc134ed9934b709d967ca3f10) Thanks [@cesr](https://github.com/cesr)! - Add `edit_file` built-in tool with str_replace semantics for targeted file edits. The tool takes `path`, `old_str`, and `new_str` parameters, enforces uniqueness of the match, and is write-gated like `write_file` (disabled in production by default). Also improves browser SSE frame streaming with backpressure handling and auto-stops screencast when all listeners disconnect.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`aee4f17`](https://github.com/cesr/poncho-ai/commit/aee4f17237d33b2cc134ed9934b709d967ca3f10)]:
|
|
12
|
+
- @poncho-ai/harness@0.24.0
|
|
13
|
+
|
|
3
14
|
## 0.26.0
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
|
@@ -5126,6 +5126,7 @@ self.addEventListener("fetch", (event) => {
|
|
|
5126
5126
|
var renderWebUiHtml = (options) => {
|
|
5127
5127
|
const agentInitial = (options?.agentName ?? "A").charAt(0).toUpperCase();
|
|
5128
5128
|
const agentName = options?.agentName ?? "Agent";
|
|
5129
|
+
const pageTitle = options?.isDev ? `[dev] ${agentName}` : agentName;
|
|
5129
5130
|
return `<!doctype html>
|
|
5130
5131
|
<html lang="en">
|
|
5131
5132
|
<head>
|
|
@@ -5139,7 +5140,7 @@ var renderWebUiHtml = (options) => {
|
|
|
5139
5140
|
<link rel="manifest" href="/manifest.json">
|
|
5140
5141
|
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
|
5141
5142
|
<link rel="apple-touch-icon" href="/icon-192.png">
|
|
5142
|
-
<title>${
|
|
5143
|
+
<title>${pageTitle}</title>
|
|
5143
5144
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inconsolata:400,700">
|
|
5144
5145
|
<style>
|
|
5145
5146
|
${WEB_UI_STYLES}
|
|
@@ -6774,12 +6775,14 @@ export default {
|
|
|
6774
6775
|
list_directory: true,
|
|
6775
6776
|
read_file: true,
|
|
6776
6777
|
write_file: true, // gated by environment for writes
|
|
6778
|
+
edit_file: true, // gated by environment for writes
|
|
6777
6779
|
delete_file: 'approval', // requires human approval
|
|
6778
6780
|
delete_directory: 'approval', // requires human approval
|
|
6779
6781
|
send_email: 'approval', // requires human approval
|
|
6780
6782
|
byEnvironment: {
|
|
6781
6783
|
production: {
|
|
6782
6784
|
write_file: false,
|
|
6785
|
+
edit_file: false,
|
|
6783
6786
|
delete_file: false,
|
|
6784
6787
|
delete_directory: false,
|
|
6785
6788
|
},
|
|
@@ -8847,7 +8850,7 @@ data: ${JSON.stringify(statusPayload)}
|
|
|
8847
8850
|
const requestUrl = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
|
|
8848
8851
|
if (webUiEnabled) {
|
|
8849
8852
|
if (request.method === "GET" && (pathname === "/" || pathname.startsWith("/c/"))) {
|
|
8850
|
-
writeHtml(response, 200, renderWebUiHtml({ agentName }));
|
|
8853
|
+
writeHtml(response, 200, renderWebUiHtml({ agentName, isDev: !isProduction }));
|
|
8851
8854
|
return;
|
|
8852
8855
|
}
|
|
8853
8856
|
if (pathname === "/manifest.json" && request.method === "GET") {
|
|
@@ -9016,6 +9019,9 @@ data: ${JSON.stringify(statusPayload)}
|
|
|
9016
9019
|
});
|
|
9017
9020
|
response.flushHeaders();
|
|
9018
9021
|
let frameCount = 0;
|
|
9022
|
+
let droppedFrames = 0;
|
|
9023
|
+
let draining = false;
|
|
9024
|
+
let pendingFrame = null;
|
|
9019
9025
|
const sendSse = (event, data) => {
|
|
9020
9026
|
if (response.destroyed) return;
|
|
9021
9027
|
response.write(`event: ${event}
|
|
@@ -9023,6 +9029,29 @@ data: ${JSON.stringify(data)}
|
|
|
9023
9029
|
|
|
9024
9030
|
`);
|
|
9025
9031
|
};
|
|
9032
|
+
const sendFrame = (frame) => {
|
|
9033
|
+
if (response.destroyed) return;
|
|
9034
|
+
if (draining) {
|
|
9035
|
+
pendingFrame = frame;
|
|
9036
|
+
droppedFrames++;
|
|
9037
|
+
return;
|
|
9038
|
+
}
|
|
9039
|
+
const ok = response.write(`event: browser:frame
|
|
9040
|
+
data: ${JSON.stringify(frame)}
|
|
9041
|
+
|
|
9042
|
+
`);
|
|
9043
|
+
if (!ok) {
|
|
9044
|
+
draining = true;
|
|
9045
|
+
response.once("drain", () => {
|
|
9046
|
+
draining = false;
|
|
9047
|
+
if (pendingFrame && !response.destroyed) {
|
|
9048
|
+
const f = pendingFrame;
|
|
9049
|
+
pendingFrame = null;
|
|
9050
|
+
sendFrame(f);
|
|
9051
|
+
}
|
|
9052
|
+
});
|
|
9053
|
+
}
|
|
9054
|
+
};
|
|
9026
9055
|
sendSse("browser:status", {
|
|
9027
9056
|
active: browserSession.isActiveFor(cid),
|
|
9028
9057
|
url: browserSession.getUrl(cid),
|
|
@@ -9031,9 +9060,9 @@ data: ${JSON.stringify(data)}
|
|
|
9031
9060
|
const removeFrame = browserSession.onFrame(cid, (frame) => {
|
|
9032
9061
|
frameCount++;
|
|
9033
9062
|
if (frameCount <= 3 || frameCount % 50 === 0) {
|
|
9034
|
-
console.log(`[poncho][browser-sse] Frame ${frameCount}: ${frame.width}x${frame.height}, data bytes: ${frame.data?.length ?? 0}`);
|
|
9063
|
+
console.log(`[poncho][browser-sse] Frame ${frameCount}: ${frame.width}x${frame.height}, data bytes: ${frame.data?.length ?? 0}${droppedFrames > 0 ? `, dropped: ${droppedFrames}` : ""}`);
|
|
9035
9064
|
}
|
|
9036
|
-
|
|
9065
|
+
sendFrame(frame);
|
|
9037
9066
|
});
|
|
9038
9067
|
const removeStatus = browserSession.onStatus(cid, (status) => {
|
|
9039
9068
|
sendSse("browser:status", status);
|
|
@@ -9041,7 +9070,7 @@ data: ${JSON.stringify(data)}
|
|
|
9041
9070
|
if (browserSession.isActiveFor(cid)) {
|
|
9042
9071
|
browserSession.screenshot(cid).then((data) => {
|
|
9043
9072
|
if (!response.destroyed) {
|
|
9044
|
-
|
|
9073
|
+
sendFrame({ data, width: 1280, height: 720, timestamp: Date.now() });
|
|
9045
9074
|
}
|
|
9046
9075
|
return browserSession.startScreencast(cid);
|
|
9047
9076
|
}).catch((err) => {
|
|
@@ -9051,6 +9080,7 @@ data: ${JSON.stringify(data)}
|
|
|
9051
9080
|
request.on("close", () => {
|
|
9052
9081
|
removeFrame();
|
|
9053
9082
|
removeStatus();
|
|
9083
|
+
pendingFrame = null;
|
|
9054
9084
|
});
|
|
9055
9085
|
return;
|
|
9056
9086
|
}
|
|
@@ -10583,7 +10613,7 @@ var runInteractive = async (workingDir, params) => {
|
|
|
10583
10613
|
await harness.initialize();
|
|
10584
10614
|
const identity = await ensureAgentIdentity2(workingDir);
|
|
10585
10615
|
try {
|
|
10586
|
-
const { runInteractiveInk } = await import("./run-interactive-ink-
|
|
10616
|
+
const { runInteractiveInk } = await import("./run-interactive-ink-OUX42GU4.js");
|
|
10587
10617
|
await runInteractiveInk({
|
|
10588
10618
|
harness,
|
|
10589
10619
|
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.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "CLI for building and deploying AI agents",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,7 +27,7 @@
|
|
|
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.
|
|
30
|
+
"@poncho-ai/harness": "0.24.0",
|
|
31
31
|
"@poncho-ai/messaging": "0.7.0",
|
|
32
32
|
"@poncho-ai/sdk": "1.5.0"
|
|
33
33
|
},
|
package/src/index.ts
CHANGED
|
@@ -550,12 +550,14 @@ export default {
|
|
|
550
550
|
list_directory: true,
|
|
551
551
|
read_file: true,
|
|
552
552
|
write_file: true, // gated by environment for writes
|
|
553
|
+
edit_file: true, // gated by environment for writes
|
|
553
554
|
delete_file: 'approval', // requires human approval
|
|
554
555
|
delete_directory: 'approval', // requires human approval
|
|
555
556
|
send_email: 'approval', // requires human approval
|
|
556
557
|
byEnvironment: {
|
|
557
558
|
production: {
|
|
558
559
|
write_file: false,
|
|
560
|
+
edit_file: false,
|
|
559
561
|
delete_file: false,
|
|
560
562
|
delete_directory: false,
|
|
561
563
|
},
|
|
@@ -2892,7 +2894,7 @@ export const createRequestHandler = async (options?: {
|
|
|
2892
2894
|
|
|
2893
2895
|
if (webUiEnabled) {
|
|
2894
2896
|
if (request.method === "GET" && (pathname === "/" || pathname.startsWith("/c/"))) {
|
|
2895
|
-
writeHtml(response, 200, renderWebUiHtml({ agentName }));
|
|
2897
|
+
writeHtml(response, 200, renderWebUiHtml({ agentName, isDev: !isProduction }));
|
|
2896
2898
|
return;
|
|
2897
2899
|
}
|
|
2898
2900
|
|
|
@@ -3112,11 +3114,36 @@ export const createRequestHandler = async (options?: {
|
|
|
3112
3114
|
response.flushHeaders();
|
|
3113
3115
|
|
|
3114
3116
|
let frameCount = 0;
|
|
3117
|
+
let droppedFrames = 0;
|
|
3118
|
+
let draining = false;
|
|
3119
|
+
let pendingFrame: { data: string; width: number; height: number; timestamp: number } | null = null;
|
|
3120
|
+
|
|
3115
3121
|
const sendSse = (event: string, data: unknown) => {
|
|
3116
3122
|
if (response.destroyed) return;
|
|
3117
3123
|
response.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
3118
3124
|
};
|
|
3119
3125
|
|
|
3126
|
+
const sendFrame = (frame: { data: string; width: number; height: number; timestamp: number }) => {
|
|
3127
|
+
if (response.destroyed) return;
|
|
3128
|
+
if (draining) {
|
|
3129
|
+
pendingFrame = frame;
|
|
3130
|
+
droppedFrames++;
|
|
3131
|
+
return;
|
|
3132
|
+
}
|
|
3133
|
+
const ok = response.write(`event: browser:frame\ndata: ${JSON.stringify(frame)}\n\n`);
|
|
3134
|
+
if (!ok) {
|
|
3135
|
+
draining = true;
|
|
3136
|
+
response.once("drain", () => {
|
|
3137
|
+
draining = false;
|
|
3138
|
+
if (pendingFrame && !response.destroyed) {
|
|
3139
|
+
const f = pendingFrame;
|
|
3140
|
+
pendingFrame = null;
|
|
3141
|
+
sendFrame(f);
|
|
3142
|
+
}
|
|
3143
|
+
});
|
|
3144
|
+
}
|
|
3145
|
+
};
|
|
3146
|
+
|
|
3120
3147
|
sendSse("browser:status", {
|
|
3121
3148
|
active: browserSession.isActiveFor(cid),
|
|
3122
3149
|
url: browserSession.getUrl(cid),
|
|
@@ -3126,20 +3153,18 @@ export const createRequestHandler = async (options?: {
|
|
|
3126
3153
|
const removeFrame = browserSession.onFrame(cid, (frame) => {
|
|
3127
3154
|
frameCount++;
|
|
3128
3155
|
if (frameCount <= 3 || frameCount % 50 === 0) {
|
|
3129
|
-
console.log(`[poncho][browser-sse] Frame ${frameCount}: ${frame.width}x${frame.height}, data bytes: ${frame.data?.length ?? 0}`);
|
|
3156
|
+
console.log(`[poncho][browser-sse] Frame ${frameCount}: ${frame.width}x${frame.height}, data bytes: ${frame.data?.length ?? 0}${droppedFrames > 0 ? `, dropped: ${droppedFrames}` : ""}`);
|
|
3130
3157
|
}
|
|
3131
|
-
|
|
3158
|
+
sendFrame(frame);
|
|
3132
3159
|
});
|
|
3133
3160
|
const removeStatus = browserSession.onStatus(cid, (status) => {
|
|
3134
3161
|
sendSse("browser:status", status);
|
|
3135
3162
|
});
|
|
3136
3163
|
|
|
3137
3164
|
if (browserSession.isActiveFor(cid)) {
|
|
3138
|
-
// Send a screenshot as the first frame for immediate visual feedback,
|
|
3139
|
-
// then start the live screencast for subsequent frames.
|
|
3140
3165
|
browserSession.screenshot(cid).then((data) => {
|
|
3141
3166
|
if (!response.destroyed) {
|
|
3142
|
-
|
|
3167
|
+
sendFrame({ data, width: 1280, height: 720, timestamp: Date.now() });
|
|
3143
3168
|
}
|
|
3144
3169
|
return browserSession.startScreencast(cid);
|
|
3145
3170
|
}).catch((err: unknown) => {
|
|
@@ -3150,6 +3175,7 @@ export const createRequestHandler = async (options?: {
|
|
|
3150
3175
|
request.on("close", () => {
|
|
3151
3176
|
removeFrame();
|
|
3152
3177
|
removeStatus();
|
|
3178
|
+
pendingFrame = null;
|
|
3153
3179
|
});
|
|
3154
3180
|
return;
|
|
3155
3181
|
}
|
package/src/web-ui.ts
CHANGED
|
@@ -92,9 +92,10 @@ self.addEventListener("fetch", (event) => {
|
|
|
92
92
|
});
|
|
93
93
|
`;
|
|
94
94
|
|
|
95
|
-
export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
95
|
+
export const renderWebUiHtml = (options?: { agentName?: string; isDev?: boolean }): string => {
|
|
96
96
|
const agentInitial = (options?.agentName ?? "A").charAt(0).toUpperCase();
|
|
97
97
|
const agentName = options?.agentName ?? "Agent";
|
|
98
|
+
const pageTitle = options?.isDev ? `[dev] ${agentName}` : agentName;
|
|
98
99
|
return `<!doctype html>
|
|
99
100
|
<html lang="en">
|
|
100
101
|
<head>
|
|
@@ -108,7 +109,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
108
109
|
<link rel="manifest" href="/manifest.json">
|
|
109
110
|
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
|
110
111
|
<link rel="apple-touch-icon" href="/icon-192.png">
|
|
111
|
-
<title>${
|
|
112
|
+
<title>${pageTitle}</title>
|
|
112
113
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inconsolata:400,700">
|
|
113
114
|
<style>
|
|
114
115
|
${WEB_UI_STYLES}
|