@netlify/agent-runner-cli 1.137.0 → 1.138.0-pty.1
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/dist/bin-local.js +138 -133
- package/dist/bin.js +217 -207
- package/dist/index.js +136 -131
- package/dist/pty-client.d.ts +1 -0
- package/dist/pty-client.js +29 -0
- package/package.json +7 -3
- package/scripts/postinstall.js +30 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; import { fileURLToPath as __ftu } from 'node:url'; import { dirname as __dnn } from 'node:path'; const require = __cr(import.meta.url); const __filename = __ftu(import.meta.url); const __dirname = __dnn(__filename);
|
|
3
|
+
var q=Object.create;var U=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty;var V=(t,o)=>()=>(o||t((o={exports:{}}).exports,o),o.exports);var X=(t,o,e,f)=>{if(o&&typeof o=="object"||typeof o=="function")for(let c of Q(o))!G.call(t,c)&&c!==e&&U(t,c,{get:()=>o[c],enumerable:!(f=H(o,c))||f.enumerable});return t};var x=(t,o,e)=>(e=t!=null?q(Z(t)):{},X(o||!t||!t.__esModule?U(e,"default",{value:t,enumerable:!0}):e,t));var g=V((lt,W)=>{"use strict";function y(t,o){var e=t;o.slice(0,-1).forEach(function(c){e=e[c]||{}});var f=o[o.length-1];return f in e}function Y(t){return typeof t=="number"||/^0x[0-9a-f]+$/i.test(t)?!0:/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(t)}function z(t,o){return o==="constructor"&&typeof t[o]=="function"||o==="__proto__"}W.exports=function(t,o){o||(o={});var e={bools:{},strings:{},unknownFn:null};typeof o.unknown=="function"&&(e.unknownFn=o.unknown),typeof o.boolean=="boolean"&&o.boolean?e.allBools=!0:[].concat(o.boolean).filter(Boolean).forEach(function(n){e.bools[n]=!0});var f={};function c(n){return f[n].some(function(l){return e.bools[l]})}Object.keys(o.alias||{}).forEach(function(n){f[n]=[].concat(o.alias[n]),f[n].forEach(function(l){f[l]=[n].concat(f[n].filter(function(b){return l!==b}))})}),[].concat(o.string).filter(Boolean).forEach(function(n){e.strings[n]=!0,f[n]&&[].concat(f[n]).forEach(function(l){e.strings[l]=!0})});var _=o.default||{},m={_:[]};function J(n,l){return e.allBools&&/^--[^=]+$/.test(l)||e.strings[n]||e.bools[n]||f[n]}function $(n,l,b){for(var i=n,T=0;T<l.length-1;T++){var w=l[T];if(z(i,w))return;i[w]===void 0&&(i[w]={}),(i[w]===Object.prototype||i[w]===Number.prototype||i[w]===String.prototype)&&(i[w]={}),i[w]===Array.prototype&&(i[w]=[]),i=i[w]}var O=l[l.length-1];z(i,O)||((i===Object.prototype||i===Number.prototype||i===String.prototype)&&(i={}),i===Array.prototype&&(i=[]),i[O]===void 0||e.bools[O]||typeof i[O]=="boolean"?i[O]=b:Array.isArray(i[O])?i[O].push(b):i[O]=[i[O],b])}function d(n,l,b){if(!(b&&e.unknownFn&&!J(n,b)&&e.unknownFn(b)===!1)){var i=!e.strings[n]&&Y(l)?Number(l):l;$(m,n.split("."),i),(f[n]||[]).forEach(function(T){$(m,T.split("."),i)})}}Object.keys(e.bools).forEach(function(n){d(n,_[n]===void 0?!1:_[n])});var N=[];t.indexOf("--")!==-1&&(N=t.slice(t.indexOf("--")+1),t=t.slice(0,t.indexOf("--")));for(var a=0;a<t.length;a++){var r=t[a],s,h;if(/^--.+=/.test(r)){var R=r.match(/^--([^=]+)=([\s\S]*)$/);s=R[1];var P=R[2];e.bools[s]&&(P=P!=="false"),d(s,P,r)}else if(/^--no-.+/.test(r))s=r.match(/^--no-(.+)/)[1],d(s,!1,r);else if(/^--.+/.test(r))s=r.match(/^--(.+)/)[1],h=t[a+1],h!==void 0&&!/^(-|--)[^-]/.test(h)&&!e.bools[s]&&!e.allBools&&(!f[s]||!c(s))?(d(s,h,r),a+=1):/^(true|false)$/.test(h)?(d(s,h==="true",r),a+=1):d(s,e.strings[s]?"":!0,r);else if(/^-[^-]+/.test(r)){for(var v=r.slice(1,-1).split(""),A=!1,p=0;p<v.length;p++){if(h=r.slice(p+2),h==="-"){d(v[p],h,r);continue}if(/[A-Za-z]/.test(v[p])&&h[0]==="="){d(v[p],h.slice(1),r),A=!0;break}if(/[A-Za-z]/.test(v[p])&&/-?\d+(\.\d*)?(e-?\d+)?$/.test(h)){d(v[p],h,r),A=!0;break}if(v[p+1]&&v[p+1].match(/\W/)){d(v[p],r.slice(p+2),r),A=!0;break}else d(v[p],e.strings[v[p]]?"":!0,r)}s=r.slice(-1)[0],!A&&s!=="-"&&(t[a+1]&&!/^(-|--)[^-]/.test(t[a+1])&&!e.bools[s]&&(!f[s]||!c(s))?(d(s,t[a+1],r),a+=1):t[a+1]&&/^(true|false)$/.test(t[a+1])?(d(s,t[a+1]==="true",r),a+=1):d(s,e.strings[s]?"":!0,r))}else if((!e.unknownFn||e.unknownFn(r)!==!1)&&m._.push(e.strings._||!Y(r)?r:Number(r)),o.stopEarly){m._.push.apply(m._,t.slice(a+1));break}}return Object.keys(_).forEach(function(n){y(m,n.split("."))||($(m,n.split("."),_[n]),(f[n]||[]).forEach(function(l){$(m,l.split("."),_[n])}))}),o["--"]?m["--"]=N.slice():N.forEach(function(n){m._.push(n)}),m}});var M=x(g(),1);import j from"fs";import k from"path";import u from"process";import B from"ws";var tt=29,et=()=>{try{let t=j.readFileSync(k.join(u.cwd(),".env"),"utf8");for(let o of t.split(`
|
|
4
|
+
`)){let e=o.trim();if(!e||e.startsWith("#"))continue;let f=e.indexOf("=");if(f===-1||e.slice(0,f).trim()!=="PTY_COOKIE")continue;let c=e.slice(f+1).trim();if(/^(".*"|'.*')$/.test(c)&&(c=c.slice(1,-1)),c)return c}}catch{}return u.env.PTY_COOKIE||void 0},S=(0,M.default)(u.argv.slice(2),{string:["url","host","port","cwd","model"],boolean:["help"],alias:{h:"help"}}),ot=()=>{u.stdout.write(`
|
|
5
|
+
agent-runner-pty - Interactive terminal client for a remote Claude PTY
|
|
6
|
+
|
|
7
|
+
USAGE:
|
|
8
|
+
agent-runner-pty [options]
|
|
9
|
+
|
|
10
|
+
OPTIONS:
|
|
11
|
+
--url <ws-url> Full WebSocket URL (overrides --host/--port)
|
|
12
|
+
--host <host> Server host (default: localhost)
|
|
13
|
+
--port <port> Server port (default: 8888)
|
|
14
|
+
--cwd <path> Directory Claude should run in on the server
|
|
15
|
+
--model <name> Model to run Claude with
|
|
16
|
+
--help, -h Show this help message
|
|
17
|
+
|
|
18
|
+
AUTH:
|
|
19
|
+
PTY_COOKIE (from a .env file in the working directory, or the environment)
|
|
20
|
+
is sent as a Cookie header on the connection when set.
|
|
21
|
+
|
|
22
|
+
QUIT:
|
|
23
|
+
Exit Claude normally (e.g. /exit), or press Ctrl-] to force quit.
|
|
24
|
+
`)};S.help&&(ot(),u.exit(0));var nt=()=>{if(S.url)return S.url;let t=S.host||"localhost",o=S.port||"8888",e=new URLSearchParams;return S.cwd&&e.set("cwd",S.cwd),S.model&&e.set("model",S.model),e.set("cols",String(u.stdout.columns||80)),e.set("rows",String(u.stdout.rows||24)),`ws://${t}:${o}/pty?${e.toString()}`},rt=nt(),L=et(),C=new B(rt,L?{headers:{Cookie:`PTY_COOKIE=${L}`}}:void 0),E=u.stdin,F=!1,I=0,K=()=>{F&&E.isTTY&&(E.setRawMode(!1),F=!1),E.pause()},D=t=>{K(),E.removeAllListeners("data"),u.stdout.removeAllListeners("resize"),u.exit(t)},it=()=>{C.readyState===B.OPEN&&C.send(JSON.stringify({type:"resize",cols:u.stdout.columns||80,rows:u.stdout.rows||24}))},st=t=>{if(t.length===1&&t[0]===tt){D(0);return}C.readyState===B.OPEN&&C.send(JSON.stringify({type:"stdin",data:t.toString("utf8")}))};C.on("open",()=>{E.isTTY&&(E.setRawMode(!0),F=!0),E.resume(),E.on("data",st),u.stdout.on("resize",it)});C.on("message",(t,o)=>{if(o){u.stdout.write(t);return}try{let e=JSON.parse(t.toString());e.type==="exit"?I=e.code??0:e.type==="error"&&(K(),u.stderr.write(`
|
|
25
|
+
[agent-runner-pty] ${e.message??"server error"}
|
|
26
|
+
`),I=1)}catch{}});C.on("close",()=>{D(I)});C.on("error",t=>{K(),u.stderr.write(`
|
|
27
|
+
[agent-runner-pty] connection error: ${t.message}
|
|
28
|
+
`),u.exit(1)});
|
|
29
|
+
//# sourceMappingURL=pty-client.js.map
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/agent-runner-cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.138.0-pty.1",
|
|
5
5
|
"description": "CLI tool for running Netlify agents",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": "./dist/index.js",
|
|
9
9
|
"bin": {
|
|
10
10
|
"agent-runner-cli": "./dist/bin.js",
|
|
11
|
-
"agent-runner-cli-local": "./dist/bin-local.js"
|
|
11
|
+
"agent-runner-cli-local": "./dist/bin-local.js",
|
|
12
|
+
"agent-runner-pty": "./dist/pty-client.js"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
15
|
"dist/**/*.js",
|
|
@@ -63,6 +64,7 @@
|
|
|
63
64
|
"@netlify/axis": "^1.17.0",
|
|
64
65
|
"@netlify/eslint-config-node": "^7.0.1",
|
|
65
66
|
"@types/node": "^24.5.0",
|
|
67
|
+
"@types/ws": "^8.5.12",
|
|
66
68
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
67
69
|
"@typescript-eslint/parser": "^8.0.0",
|
|
68
70
|
"@vitest/coverage-v8": "^4.1.5",
|
|
@@ -92,6 +94,8 @@
|
|
|
92
94
|
"execa": "^9.6.1",
|
|
93
95
|
"fastify": "5.8.5",
|
|
94
96
|
"minimist": "^1.2.8",
|
|
95
|
-
"
|
|
97
|
+
"node-pty": "1.1.0",
|
|
98
|
+
"openai": "6.34.0",
|
|
99
|
+
"ws": "8.21.0"
|
|
96
100
|
}
|
|
97
101
|
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -13,6 +13,36 @@ console.log(`[postinstall] cwd=${cwd}`)
|
|
|
13
13
|
console.log(`[postinstall] INIT_CWD=${initCwd}`)
|
|
14
14
|
console.log('[postinstall] using patchesDir =', patchesDir)
|
|
15
15
|
|
|
16
|
+
// node-pty (used by the interactive PTY endpoint) ships a prebuilt
|
|
17
|
+
// `spawn-helper` that it execs to fork the child. Some install paths — notably
|
|
18
|
+
// the allow-scripts gate that blocks node-pty's own install step — drop the
|
|
19
|
+
// executable bit, and then every spawn fails with "posix_spawnp failed". Make
|
|
20
|
+
// it executable defensively; it's a no-op when already correct.
|
|
21
|
+
const ensureSpawnHelperExecutable = () => {
|
|
22
|
+
const candidates = [
|
|
23
|
+
path.join(cwd, '..', 'node-pty'),
|
|
24
|
+
path.join(cwd, 'node_modules', 'node-pty'),
|
|
25
|
+
path.join(targetCwd, 'node_modules', 'node-pty'),
|
|
26
|
+
]
|
|
27
|
+
for (const ptyDir of candidates) {
|
|
28
|
+
const prebuildsDir = path.join(ptyDir, 'prebuilds')
|
|
29
|
+
if (!fs.existsSync(prebuildsDir)) continue
|
|
30
|
+
for (const platform of fs.readdirSync(prebuildsDir)) {
|
|
31
|
+
const helper = path.join(prebuildsDir, platform, 'spawn-helper')
|
|
32
|
+
try {
|
|
33
|
+
if (fs.existsSync(helper)) {
|
|
34
|
+
fs.chmodSync(helper, 0o755)
|
|
35
|
+
console.log(`[postinstall] chmod +x ${helper}`)
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.warn(`[postinstall] Failed to chmod ${helper}:`, error.message)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
ensureSpawnHelperExecutable()
|
|
45
|
+
|
|
16
46
|
if (fs.existsSync(patchesDir)) {
|
|
17
47
|
const files = fs.readdirSync(patchesDir).filter((file) => file.endsWith('.patch'))
|
|
18
48
|
|