@agentdeploymentco/bishop 0.3.2 → 0.3.3
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/harness/codex.js +4 -4
- package/dist/worktrees.js +3 -2
- package/package.json +1 -1
package/dist/harness/codex.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import{existsSync as
|
|
2
|
-
`)}function Z(e,t){const o=Array.isArray(e)?e:[],i=[...new Set([...o,...t??[]])];return i.length>0?{additionalDirectories:i}:{}}function k(e){return{model:e.model,modelReasoningEffort:e.effort}}function q(e){return Object.fromEntries(Object.entries(k(e)).filter(([,t])=>t!==void 0))}const ee={model:"model",modelReasoningEffort:"model_reasoning_effort"};function te(e,t){const o=e?.config,i=o&&typeof o=="object"?Object.entries(ee).filter(([s,l])=>t[s]!==void 0&&l in o).map(([,s])=>`config.${s}`):[];return[...X(e,t),...i]}function pe(e={}){const t=G(e.options);t.length>0&&g.warn({ignored:t},"these agent.options are set by Bishop and cannot be overridden; ignoring them");const o=k(e),i=te(e.options,o);i.length>0&&g.warn({shadowed:i},"agent.model and agent.effort override these agent.options");const s=L({defaults:F,...e.options?{configOptions:e.options}:{},general:o,controlledKeys:x}),l={},u={};for(const[r,n]of Object.entries(s))V.has(r)?l[r]=n:u[r]=n;const E=l.env;e.apiKey&&(l.apiKey=e.apiKey);const b=e.worktrees,
|
|
1
|
+
import{existsSync as K}from"node:fs";import{homedir as D}from"node:os";import{join as _}from"node:path";import{Codex as A}from"@openai/codex-sdk";import{log as g}from"../log.js";import{SERVER_NAME as I}from"../tools/server.js";import{ensureWorktree as P,gitDirs as j,isolates as M}from"../worktrees.js";import{ignoredKeys as R,layerOptions as L,mergeEnv as N,shadowedKeys as X}from"./layers.js";import{buildPrompt as Y,principalInstructions as $}from"./principal.js";const U=10,W=60;function B(e,t){const o=e??void 0;return t?{...o,[I]:{url:t.url,bearer_token_env_var:t.tokenEnvVar,required:!0,default_tools_approval_mode:"auto",startup_timeout_sec:U,tool_timeout_sec:W}}:o}const F={approvalPolicy:"never",sandboxMode:"workspace-write",networkAccessEnabled:!0,skipGitRepoCheck:!0},x=["workingDirectory","developer_instructions"];function G(e){const t=e?.config,o=t&&typeof t=="object"&&"developer_instructions"in t?["config.developer_instructions"]:[];return[...R(e,x),...o]}const V=new Set(["apiKey","baseUrl","config","configOverrides","env","codexPathOverride"]);function H(e){switch(e.type){case"command_execution":return{type:"tool",name:"Bash"};case"file_change":{const t=e.changes.length;if(t>1)return{type:"tool",name:"Edit",detail:`${t} files`};const o=t===1?e.changes[0]?.path.split("/").pop():void 0;return{type:"tool",name:"Edit",...o?{detail:o}:{}}}case"mcp_tool_call":return{type:"tool",name:`mcp__${e.server}__${e.tool}`};case"web_search":return{type:"tool",name:"WebSearch",...e.query?{detail:e.query}:{}};case"todo_list":return{type:"tool",name:"TodoWrite"};case"reasoning":return{type:"thinking"};default:return}}const z=new Set(["command_execution","mcp_tool_call","web_search","reasoning"]);function J(e){const t=new Set;let o="";return i=>{switch(i.type){case"thread.started":return[{type:"session",sessionId:i.thread_id,...e?{model:e}:{}}];case"item.started":case"item.completed":{const s=i.item,l=z.has(s.type)?"item.started":"item.completed";if(i.type!==l||t.has(s.id))return[];if(t.add(s.id),s.type==="agent_message")return o=s.text,s.text.trim()?[{type:"text",text:s.text}]:[];if(s.type==="error")return g.warn({message:s.message},"codex reported a non-fatal error"),[];const u=H(s);return u?[u]:[]}case"turn.completed":return[{type:"done",text:o,usage:{inputTokens:i.usage.input_tokens,cachedInputTokens:i.usage.cached_input_tokens,outputTokens:i.usage.output_tokens}}];case"turn.failed":return[{type:"error",kind:"turn_failed",message:i.error.message}];case"error":return[{type:"error",kind:"stream_error",message:i.message}];default:return[]}}}function Q(e){return[`You are working in a git worktree of your own, on the branch "${e}", created for this`,"conversation. Other conversations are working in their own worktrees at the same time.","","Work normally. Commit what you finish on this branch and say which branch it is, since that's","how a person finds your work."].join(`
|
|
2
|
+
`)}function Z(e,t){const o=Array.isArray(e)?e:[],i=[...new Set([...o,...t??[]])];return i.length>0?{additionalDirectories:i}:{}}function k(e){return{model:e.model,modelReasoningEffort:e.effort}}function q(e){return Object.fromEntries(Object.entries(k(e)).filter(([,t])=>t!==void 0))}const ee={model:"model",modelReasoningEffort:"model_reasoning_effort"};function te(e,t){const o=e?.config,i=o&&typeof o=="object"?Object.entries(ee).filter(([s,l])=>t[s]!==void 0&&l in o).map(([,s])=>`config.${s}`):[];return[...X(e,t),...i]}function pe(e={}){const t=G(e.options);t.length>0&&g.warn({ignored:t},"these agent.options are set by Bishop and cannot be overridden; ignoring them");const o=k(e),i=te(e.options,o);i.length>0&&g.warn({shadowed:i},"agent.model and agent.effort override these agent.options");const s=L({defaults:F,...e.options?{configOptions:e.options}:{},general:o,controlledKeys:x}),l={},u={};for(const[r,n]of Object.entries(s))V.has(r)?l[r]=n:u[r]=n;const E=l.env;e.apiKey&&(l.apiKey=e.apiKey);const b=e.worktrees,y=(r,n,a)=>{const d=l.config??{},c=B(d.mcp_servers,a),m=N(E,a?{[a.tokenEnvVar]:a.token}:{}),f={...d,developer_instructions:[n&&$(n),r].filter(p=>!!p?.trim()).join(`
|
|
3
3
|
|
|
4
|
-
`)};return c&&(f.mcp_servers=c),new A({...l,...m?{env:m}:{},config:f})};async function v(r){if(!M(b))return{cwd:r.cwd};const n=await P(r.cwd,r.worktree),a=await j(n);return a
|
|
4
|
+
`)};return c&&(f.mcp_servers=c),new A({...l,...m?{env:m}:{},config:f})};async function v(r){if(!M(b))return{cwd:r.cwd};const n=await P(r.cwd,r.worktree),a=await j(n);return a.length===0&&g.warn({worktree:n},"couldn't resolve the worktree's git directories, so the agent probably can't commit"),{cwd:n,note:Q(r.worktree),...a.length>0?{writable:a}:{}}}return{name:"codex",describeStartupFailure(r,n){return`The Codex agent couldn't start in ${r}:
|
|
5
5
|
${n}
|
|
6
6
|
|
|
7
7
|
Bishop does not manage OpenAI credentials. The agent authenticates the
|
|
8
8
|
same way \`codex\` does on this machine, so make sure that works first:
|
|
9
9
|
CODEX_API_KEY in the environment or .env, or
|
|
10
|
-
an existing \`codex login\` on this machine.`},async check(r){const n=new AbortController,a=u.model;try{const c=
|
|
10
|
+
an existing \`codex login\` on this machine.`},async check(r){const n=new AbortController,a=u.model;try{const c=y(void 0,void 0).startThread({...u,workingDirectory:r}),{events:m}=await c.runStreamed("ping",{signal:n.signal});for await(const f of m){if(f.type==="thread.started"){n.abort();const p=re(e.apiKey);return oe(p),{ok:!0,...p?{credentialSource:p}:{},...a?{model:a}:{}}}if(f.type==="error")return{ok:!1,error:f.message}}return{ok:!1,error:"the harness exited without starting a thread"}}catch(d){return n.signal.aborted?{ok:!0}:{ok:!1,error:d instanceof Error?d.message:String(d)}}},async*runTurn(r){const n=new AbortController,a=()=>n.abort();r.signal.addEventListener("abort",a,{once:!0});let d=!1;try{const{cwd:c,note:m,writable:f}=await v(r),p=y(m,r.origin,r.tools),h={...u,...q(r),workingDirectory:c,...Z(u.additionalDirectories,f)},C=r.sessionId?p.resumeThread(r.sessionId,h):p.startThread(h),S=J(h.model),{events:T}=await C.runStreamed(Y(r),{signal:n.signal});for await(const O of T)for(const w of S(O))(w.type==="done"||w.type==="error")&&(d=!0),yield w}catch(c){n.signal.aborted?g.debug({thread:r.threadKey},"codex turn aborted"):d?g.debug({err:c},"codex threw after reporting a result"):(g.error({err:c},"harness turn failed"),yield{type:"error",kind:"harness_failure",message:c instanceof Error?c.message:String(c)})}finally{r.signal.removeEventListener("abort",a)}}}}function re(e){if(e)return"CODEX_API_KEY";const t=process.env.CODEX_HOME??_(D(),".codex");if(K(_(t,"auth.json")))return"existing codex login"}function oe(e){e||g.warn("no CODEX_API_KEY and no codex login found, so the first turn will probably fail to authenticate; run `codex login`, or set CODEX_API_KEY")}export{x as CONTROLLED_CODEX_KEYS,F as DEFAULT_CODEX_OPTIONS,q as chosenCodexOptions,k as codexGeneralOptions,pe as codexHarness,J as codexTranslator,G as ignoredCodexKeys,B as mergeMcpServers,te as shadowedCodexKeys,Z as withWritable,Q as worktreeNote};
|
package/dist/worktrees.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import{createHash as w}from"node:crypto";import{existsSync as
|
|
2
|
-
and, retrying with the existing branch: ${o}`}function f(t,r){if(!r)return t;const e=
|
|
1
|
+
import{createHash as w}from"node:crypto";import{existsSync as a,mkdirSync as h}from"node:fs";import{join as p,resolve as u}from"node:path";import{BishopError as l}from"./errors.js";import{exec as i}from"./exec.js";const d=64,s="bishop-",g=".claude/worktrees";function R(t){const r=t.replaceAll(/[^a-zA-Z0-9]+/g,"-").replaceAll(/-+/g,"-").replaceAll(/^-+|-+$/g,""),e=`${s}${r}`;if(e.length<=d)return e;const o=w("sha256").update(t).digest("hex").slice(0,8),n=d-s.length-o.length-1;return`${s}${r.slice(0,n)}-${o}`}function m(t,r){return u(t,g,r)}function I(t){return`\`${t}\` isn't a git repository, so I'm working in it directly. Another thread changing the same files at the same time can conflict.`}function N(t){return!!(t?.enabled&&t.isRepo)}function x(t){return a(p(t,".git"))}async function y(t){const r=await i("git",["rev-parse","--show-prefix"],{cwd:t});return r.code===0?r.stdout.trim():""}async function M(t,r){const e=m(t,r),o=await y(t);if(x(e))return f(e,o);if(a(e))throw new l(`${e} exists but is not a git worktree, which usually means an earlier attempt failed partway. Remove the directory and this thread will get a fresh one.`);const n=await i("git",["worktree","add","-b",r,e,"HEAD"],{cwd:t});if(n.code!==0){await i("git",["worktree","prune"],{cwd:t});const c=await i("git",["worktree","add",e,r],{cwd:t});if(c.code!==0)throw new l(`Couldn't create a git worktree for this thread at ${e}: ${k(n,c)}`)}return f(e,o)}function k(t,r){const e=t.stderr.trim(),o=r.stderr.trim();return!o||o===e?e:`${e}
|
|
2
|
+
and, retrying with the existing branch: ${o}`}function f(t,r){if(!r)return t;const e=u(t,r);return h(e,{recursive:!0}),e}async function P(t){const r=await i("git",["rev-parse","--path-format=absolute","--git-dir","--git-common-dir"],{cwd:t}),e=r.stdout.split(`
|
|
3
|
+
`).filter(o=>o.trim()!=="");return r.code!==0||e.length!==2?[]:[...new Set(e)]}async function S(t){return(await i("git",["rev-parse","--show-toplevel"],{cwd:t})).code===0}async function W(t){const r=await i("git",["config","--get","user.email"],{cwd:t}),e=await i("git",["config","--get","user.name"],{cwd:t});return r.code===0&&r.stdout.trim()!==""&&e.code===0&&e.stdout.trim()!==""}export{g as WORKTREE_DIR,M as ensureWorktree,P as gitDirs,W as hasGitIdentity,S as isGitRepo,N as isolates,I as sharedDirNotice,R as worktreeName,m as worktreePath};
|