@netlify/agent-runner-cli 1.138.0-pty.4 → 1.139.0-alpha.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.
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: asking-questions
3
+ description: When the request is ambiguous or a choice would materially change the outcome and only the user can decide, ask them with the `ask` tool instead of guessing or asking in plain text. Calling it pauses the run until they answer.
4
+ ---
5
+
6
+ # Asking the user questions
7
+
8
+ When a decision is genuinely the user's to make and would change what you build, ask rather than assume.
9
+
10
+ Use the `ask` tool: pass one to four questions, each with a short `header`, the `question` text, and `options` when there is a clear set of choices. Calling it pauses the run until the user answers, so ask everything you need in a single call and stop. A plain-text question does not reach the user.
package/package.json CHANGED
@@ -1,15 +1,14 @@
1
1
  {
2
2
  "name": "@netlify/agent-runner-cli",
3
3
  "type": "module",
4
- "version": "1.138.0-pty.4",
4
+ "version": "1.139.0-alpha.0",
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",
12
- "agent-runner-pty": "./dist/pty-client.js"
11
+ "agent-runner-cli-local": "./dist/bin-local.js"
13
12
  },
14
13
  "files": [
15
14
  "dist/**/*.js",
@@ -64,7 +63,6 @@
64
63
  "@netlify/axis": "^1.17.0",
65
64
  "@netlify/eslint-config-node": "^7.0.1",
66
65
  "@types/node": "^24.5.0",
67
- "@types/ws": "^8.5.12",
68
66
  "@typescript-eslint/eslint-plugin": "^8.0.0",
69
67
  "@typescript-eslint/parser": "^8.0.0",
70
68
  "@vitest/coverage-v8": "^4.1.5",
@@ -84,6 +82,7 @@
84
82
  "@anthropic-ai/claude-code": "2.1.197",
85
83
  "@anthropic-ai/sdk": "0.91.1",
86
84
  "@google/gemini-cli": "0.42.0",
85
+ "@modelcontextprotocol/sdk": "^1.29.0",
87
86
  "@netlify/cache-utils": "^6.0.5",
88
87
  "@netlify/database-proxy": "^0.1.5",
89
88
  "@netlify/otel": "^6.0.3",
@@ -94,8 +93,7 @@
94
93
  "execa": "^9.6.1",
95
94
  "fastify": "5.8.5",
96
95
  "minimist": "^1.2.8",
97
- "node-pty": "1.1.0",
98
96
  "openai": "6.34.0",
99
- "ws": "8.21.0"
97
+ "zod": "^4.4.3"
100
98
  }
101
99
  }
@@ -13,36 +13,6 @@ 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
-
46
16
  if (fs.existsSync(patchesDir)) {
47
17
  const files = fs.readdirSync(patchesDir).filter((file) => file.endsWith('.patch'))
48
18
 
@@ -1 +0,0 @@
1
- #!/usr/bin/env node
@@ -1,30 +0,0 @@
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 g=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty;var x=(t,o)=>()=>(o||t((o={exports:{}}).exports,o),o.exports);var y=(t,o,e,i)=>{if(o&&typeof o=="object"||typeof o=="function")for(let f of G(o))!X.call(t,f)&&f!==e&&g(t,f,{get:()=>o[f],enumerable:!(i=Z(o,f))||i.enumerable});return t};var j=(t,o,e)=>(e=t!=null?Q(V(t)):{},y(o||!t||!t.__esModule?g(e,"default",{value:t,enumerable:!0}):e,t));var Y=x((lt,W)=>{"use strict";function k(t,o){var e=t;o.slice(0,-1).forEach(function(f){e=e[f]||{}});var i=o[o.length-1];return i in e}function z(t){return typeof t=="number"||/^0x[0-9a-f]+$/i.test(t)?!0:/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(t)}function K(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 i={};function f(n){return i[n].some(function(u){return e.bools[u]})}Object.keys(o.alias||{}).forEach(function(n){i[n]=[].concat(o.alias[n]),i[n].forEach(function(u){i[u]=[n].concat(i[n].filter(function(S){return u!==S}))})}),[].concat(o.string).filter(Boolean).forEach(function(n){e.strings[n]=!0,i[n]&&[].concat(i[n]).forEach(function(u){e.strings[u]=!0})});var T=o.default||{},m={_:[]};function q(n,u){return e.allBools&&/^--[^=]+$/.test(u)||e.strings[n]||e.bools[n]||i[n]}function _(n,u,S){for(var s=n,C=0;C<u.length-1;C++){var v=u[C];if(K(s,v))return;s[v]===void 0&&(s[v]={}),(s[v]===Object.prototype||s[v]===Number.prototype||s[v]===String.prototype)&&(s[v]={}),s[v]===Array.prototype&&(s[v]=[]),s=s[v]}var O=u[u.length-1];K(s,O)||((s===Object.prototype||s===Number.prototype||s===String.prototype)&&(s={}),s===Array.prototype&&(s=[]),s[O]===void 0||e.bools[O]||typeof s[O]=="boolean"?s[O]=S:Array.isArray(s[O])?s[O].push(S):s[O]=[s[O],S])}function d(n,u,S){if(!(S&&e.unknownFn&&!q(n,S)&&e.unknownFn(S)===!1)){var s=!e.strings[n]&&z(u)?Number(u):u;_(m,n.split("."),s),(i[n]||[]).forEach(function(C){_(m,C.split("."),s)})}}Object.keys(e.bools).forEach(function(n){d(n,T[n]===void 0?!1:T[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],l,p;if(/^--.+=/.test(r)){var U=r.match(/^--([^=]+)=([\s\S]*)$/);l=U[1];var P=U[2];e.bools[l]&&(P=P!=="false"),d(l,P,r)}else if(/^--no-.+/.test(r))l=r.match(/^--no-(.+)/)[1],d(l,!1,r);else if(/^--.+/.test(r))l=r.match(/^--(.+)/)[1],p=t[a+1],p!==void 0&&!/^(-|--)[^-]/.test(p)&&!e.bools[l]&&!e.allBools&&(!i[l]||!f(l))?(d(l,p,r),a+=1):/^(true|false)$/.test(p)?(d(l,p==="true",r),a+=1):d(l,e.strings[l]?"":!0,r);else if(/^-[^-]+/.test(r)){for(var w=r.slice(1,-1).split(""),A=!1,h=0;h<w.length;h++){if(p=r.slice(h+2),p==="-"){d(w[h],p,r);continue}if(/[A-Za-z]/.test(w[h])&&p[0]==="="){d(w[h],p.slice(1),r),A=!0;break}if(/[A-Za-z]/.test(w[h])&&/-?\d+(\.\d*)?(e-?\d+)?$/.test(p)){d(w[h],p,r),A=!0;break}if(w[h+1]&&w[h+1].match(/\W/)){d(w[h],r.slice(h+2),r),A=!0;break}else d(w[h],e.strings[w[h]]?"":!0,r)}l=r.slice(-1)[0],!A&&l!=="-"&&(t[a+1]&&!/^(-|--)[^-]/.test(t[a+1])&&!e.bools[l]&&(!i[l]||!f(l))?(d(l,t[a+1],r),a+=1):t[a+1]&&/^(true|false)$/.test(t[a+1])?(d(l,t[a+1]==="true",r),a+=1):d(l,e.strings[l]?"":!0,r))}else if((!e.unknownFn||e.unknownFn(r)!==!1)&&m._.push(e.strings._||!z(r)?r:Number(r)),o.stopEarly){m._.push.apply(m._,t.slice(a+1));break}}return Object.keys(T).forEach(function(n){k(m,n.split("."))||(_(m,n.split("."),T[n]),(i[n]||[]).forEach(function(u){_(m,u.split("."),T[n])}))}),o["--"]?m["--"]=N.slice():N.forEach(function(n){m._.push(n)}),m}});var D=j(Y(),1);import tt from"fs";import et from"path";import c from"process";import I from"ws";var ot=29,nt=()=>{try{let t=tt.readFileSync(et.join(c.cwd(),".env"),"utf8");for(let o of t.split(`
4
- `)){let e=o.trim();if(!e||e.startsWith("#"))continue;let i=e.indexOf("=");if(i===-1||e.slice(0,i).trim()!=="PTY_COOKIE")continue;let f=e.slice(i+1).trim();if(/^(".*"|'.*')$/.test(f)&&(f=f.slice(1,-1)),f)return f}}catch{}return c.env.PTY_COOKIE||void 0},b=(0,D.default)(c.argv.slice(2),{string:["url","host","port","cwd","model"],boolean:["help"],alias:{h:"help"}}),rt=()=>{c.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
- `)};b.help&&(rt(),c.exit(0));var st=()=>{if(b.url)return b.url;let t=b.host||"localhost",o=/^(localhost|127\.0\.0\.1|\[::1\])$/.test(t),e=o?"ws":"wss",i=b.port?`${t}:${b.port}`:o?`${t}:8888`:t,f=new URLSearchParams;return b.cwd&&f.set("cwd",b.cwd),b.model&&f.set("model",b.model),f.set("cols",String(c.stdout.columns||80)),f.set("rows",String(c.stdout.rows||24)),`${e}://${i}/pty?${f.toString()}`},H=st(),L=nt(),$=new I(H,{followRedirects:!0,...L?{headers:{Cookie:`${L}`}}:{}}),E=c.stdin,F=!1,B=0,R=()=>{F&&E.isTTY&&(E.setRawMode(!1),F=!1),E.pause()},J=t=>{R(),E.removeAllListeners("data"),c.stdout.removeAllListeners("resize"),c.exit(t)},M=()=>{$.readyState===I.OPEN&&$.send(JSON.stringify({type:"resize",cols:c.stdout.columns||80,rows:c.stdout.rows||24}))},it=t=>{if(t.length===1&&t[0]===ot){J(0);return}$.readyState===I.OPEN&&$.send(JSON.stringify({type:"stdin",data:t.toString("utf8")}))};$.on("open",()=>{E.isTTY&&(E.setRawMode(!0),F=!0),E.resume(),E.on("data",it),c.stdout.on("resize",M),M()});$.on("message",(t,o)=>{if(o){c.stdout.write(t);return}try{let e=JSON.parse(t.toString());e.type==="exit"?B=e.code??0:e.type==="error"&&(R(),c.stderr.write(`
25
- [agent-runner-pty] ${e.message??"server error"}
26
- `),B=1)}catch{}});$.on("close",()=>{J(B)});$.on("error",t=>{R(),c.stderr.write(`
27
- [agent-runner-pty] connection error: ${t.message}
28
- `),/response: 3\d\d/.test(t.message)&&H.startsWith("ws://")&&c.stderr.write(`[agent-runner-pty] hint: this host redirects to HTTPS \u2014 use wss:// instead of ws://
29
- `),c.exit(1)});
30
- //# sourceMappingURL=pty-client.js.map