@anyforge/control 0.6.1 → 0.6.2

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/README.md CHANGED
@@ -87,9 +87,9 @@ remains read only.
87
87
  Use Shift+Enter for multiline input. Type `/` for the command palette:
88
88
  `/help`, `/status` (session, access, model, last turn, usage and limits),
89
89
  `/new`, `/clear`, `/resume`, `/context`, `/attach`, `/copy`, `/files`,
90
- `/usage`, `/model` and `/exit`. `/design [topic]` and `/catchup` are answered
91
- by the Oracle itself, as in the web widget; acting on `/catchup` decisions
92
- needs a session started with `--write --approve`.
90
+ `/usage`, `/model` and `/exit`. `/design [topic]`, `/catchup` and
91
+ `/remember [what]` are answered by the Oracle itself, as in the web widget;
92
+ acting on `/catchup` decisions needs a session started with `--write --approve`.
93
93
 
94
94
  While Oracle works, a status line shows what it is doing, how long it has
95
95
  taken and which step it is on, and each tool appears as it runs. Enter queues
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var Ei=Object.defineProperty;var _i=(t,e)=>()=>(t&&(e=t(t=0)),e);var $i=(t,e)=>{for(var n in e)Ei(t,n,{get:e[n],enumerable:!0})};var ir={};$i(ir,{default:()=>pc});var pc,sr=_i(()=>{pc={name:"@anyforge/control",version:"0.6.1",description:"AnyForge CLI \u2014 hosted Oracle conversations, a governed LLM proxy, and a scriptable client for approvals, crews, work items and workflows.",license:"Apache-2.0",homepage:"https://anyforge.ai",repository:{type:"git",url:"git+https://github.com/pootonline/sovereign-engineering.git",directory:"packages/control/cli"},publishConfig:{access:"public"},type:"module",main:"dist/cli.js",bin:{anyforge:"dist/cli.js",control:"dist/cli.js"},files:["dist","README.md"],scripts:{build:"esbuild src/cli.ts --bundle --minify --platform=node --format=esm --outfile=dist/cli.js --packages=external && chmod +x dist/cli.js","type-check":"tsc --noEmit",test:"npm run build && node scripts/test.mjs",dev:"tsx src/cli.ts",prepublishOnly:"npm run build","publish:beta":"npm publish --access public --tag beta","publish:stable":"npm publish --access public"},engines:{node:">=22.19.0"},dependencies:{"@earendil-works/pi-tui":"^0.87.1",kleur:"^4.1.5",open:"^10.0.0",prompts:"^2.4.2","proper-lockfile":"^4.1.2"},devDependencies:{"@types/node":"^22.20.0","@types/prompts":"^2.4.9","@types/proper-lockfile":"^4.1.4",esbuild:"^0.25.0","node-pty":"^1.1.0",tsx:"^4.7.0",typescript:"^7.0.2"}}});import{red as fi,yellow as Nc,dim as xt,bold as B}from"kleur/colors";import{execFileSync as On}from"child_process";import Bi from"open";import vn from"prompts";import{green as et,dim as L,bold as Z,yellow as ke,cyan as Lt}from"kleur/colors";import{promises as _t}from"fs";import{homedir as Pi}from"os";import{join as yr,dirname as Jc}from"path";var vr=yr(Pi(),".anyforge"),hn=yr(vr,"credentials");async function Or(t){await _t.mkdir(vr,{recursive:!0,mode:448}),await _t.writeFile(hn,JSON.stringify(t,null,2),{mode:384})}async function ve(){try{let t=await _t.readFile(hn,"utf8");return JSON.parse(t)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function br(){try{return await _t.unlink(hn),!0}catch(t){if(t.code==="ENOENT")return!1;throw t}}import{promises as P}from"fs";import{execFileSync as Li}from"child_process";import{homedir as le}from"os";import{join as M}from"path";import $t from"prompts";import{dim as X,green as yn,yellow as Pt}from"kleur/colors";var Oe="# === AnyForge Control \u2014 added by `anyforge init` ===",Ze="# === end AnyForge Control ===",xe=".anyforge-bak",Fi=/claude_(max|pro|team|enterprise)/i,Ni=["CLAUDE_CODE_ENABLE_TELEMETRY","OTEL_METRICS_EXPORTER","OTEL_EXPORTER_OTLP_PROTOCOL","OTEL_EXPORTER_OTLP_ENDPOINT","OTEL_EXPORTER_OTLP_HEADERS","OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE"];async function Sr(t){let e=[],n=await qi(t);if(n&&e.push(n),t.scope==="repo"){let r=await Mi(t);return r&&e.push(r),e}for(let r of ji){let o=await r.detect();if(!(!o||!(await $t({type:"confirm",name:"go",message:`Patch ${r.label} via shell rc (${X(o.path)}) ?`,initial:!0})).go))try{await r.patch(o,t),e.push({label:r.label,path:o.path}),console.log(yn(" \u2714")+" "+r.label)}catch(s){console.warn(" \u26A0 Skipped "+r.label+": "+s.message)}}return e}async function qi(t){let e=t.scope==="repo"&&t.repoRoot?{dir:M(t.repoRoot,".claude"),file:"settings.local.json"}:{dir:M(le(),".claude"),file:"settings.json"},n=M(e.dir,e.file);if(!(await $t({type:"confirm",name:"go",message:`Patch Claude Code config at ${X(n)} ?`,initial:!0})).go)return null;await P.mkdir(e.dir,{recursive:!0});let o=await P.readFile(n,"utf8").catch(()=>"{}"),i;try{i=JSON.parse(o)}catch{i={}}let s=i.env??{},a=s.ANTHROPIC_BASE_URL;return a&&!a.includes(t.endpoint)&&(a.includes("localhost")||a.includes("127.0.0.1")||a.includes("0.0.0.0"))&&(console.log(),console.log(Pt(" \u26A0 Local LLM proxy detected: ")+X(a)),console.log(X(" AnyForge only routes Anthropic Claude models. Local models (Ollama,")),console.log(X(" LM Studio, etc.) will not work in Claude Code after this patch.")),console.log(X(" To restore: remove ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN")),console.log(X(` from ${n}`)),console.log(),!(await $t({type:"confirm",name:"go",message:"Overwrite existing local LLM proxy config?",initial:!1})).go)?null:(await re(n)&&!await re(n+xe)&&await P.copyFile(n,n+xe),s.ANTHROPIC_BASE_URL=`${t.endpoint}/v1/anthropic`,s.ANTHROPIC_AUTH_TOKEN=t.apiKey,delete s.ANTHROPIC_API_KEY,i.env=s,await P.writeFile(n,JSON.stringify(i,null,2)+`
2
+ var Ei=Object.defineProperty;var _i=(t,e)=>()=>(t&&(e=t(t=0)),e);var $i=(t,e)=>{for(var n in e)Ei(t,n,{get:e[n],enumerable:!0})};var ir={};$i(ir,{default:()=>pc});var pc,sr=_i(()=>{pc={name:"@anyforge/control",version:"0.6.2",description:"AnyForge CLI \u2014 hosted Oracle conversations, a governed LLM proxy, and a scriptable client for approvals, crews, work items and workflows.",license:"Apache-2.0",homepage:"https://anyforge.ai",repository:{type:"git",url:"git+https://github.com/pootonline/sovereign-engineering.git",directory:"packages/control/cli"},publishConfig:{access:"public"},type:"module",main:"dist/cli.js",bin:{anyforge:"dist/cli.js",control:"dist/cli.js"},files:["dist","README.md"],scripts:{build:"esbuild src/cli.ts --bundle --minify --platform=node --format=esm --outfile=dist/cli.js --packages=external && chmod +x dist/cli.js","type-check":"tsc --noEmit",test:"npm run build && node scripts/test.mjs",dev:"tsx src/cli.ts",prepublishOnly:"npm run build","publish:beta":"npm publish --access public --tag beta","publish:stable":"npm publish --access public"},engines:{node:">=22.19.0"},dependencies:{"@earendil-works/pi-tui":"^0.87.1",kleur:"^4.1.5",open:"^10.0.0",prompts:"^2.4.2","proper-lockfile":"^4.1.2"},devDependencies:{"@types/node":"^22.20.0","@types/prompts":"^2.4.9","@types/proper-lockfile":"^4.1.4",esbuild:"^0.25.0","node-pty":"^1.1.0",tsx:"^4.7.0",typescript:"^7.0.2"}}});import{red as fi,yellow as Nc,dim as xt,bold as B}from"kleur/colors";import{execFileSync as On}from"child_process";import Bi from"open";import vn from"prompts";import{green as et,dim as L,bold as Z,yellow as ke,cyan as Lt}from"kleur/colors";import{promises as _t}from"fs";import{homedir as Pi}from"os";import{join as yr,dirname as Jc}from"path";var vr=yr(Pi(),".anyforge"),hn=yr(vr,"credentials");async function Or(t){await _t.mkdir(vr,{recursive:!0,mode:448}),await _t.writeFile(hn,JSON.stringify(t,null,2),{mode:384})}async function ve(){try{let t=await _t.readFile(hn,"utf8");return JSON.parse(t)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function br(){try{return await _t.unlink(hn),!0}catch(t){if(t.code==="ENOENT")return!1;throw t}}import{promises as P}from"fs";import{execFileSync as Li}from"child_process";import{homedir as le}from"os";import{join as M}from"path";import $t from"prompts";import{dim as X,green as yn,yellow as Pt}from"kleur/colors";var Oe="# === AnyForge Control \u2014 added by `anyforge init` ===",Ze="# === end AnyForge Control ===",xe=".anyforge-bak",Fi=/claude_(max|pro|team|enterprise)/i,Ni=["CLAUDE_CODE_ENABLE_TELEMETRY","OTEL_METRICS_EXPORTER","OTEL_EXPORTER_OTLP_PROTOCOL","OTEL_EXPORTER_OTLP_ENDPOINT","OTEL_EXPORTER_OTLP_HEADERS","OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE"];async function Sr(t){let e=[],n=await qi(t);if(n&&e.push(n),t.scope==="repo"){let r=await Mi(t);return r&&e.push(r),e}for(let r of ji){let o=await r.detect();if(!(!o||!(await $t({type:"confirm",name:"go",message:`Patch ${r.label} via shell rc (${X(o.path)}) ?`,initial:!0})).go))try{await r.patch(o,t),e.push({label:r.label,path:o.path}),console.log(yn(" \u2714")+" "+r.label)}catch(s){console.warn(" \u26A0 Skipped "+r.label+": "+s.message)}}return e}async function qi(t){let e=t.scope==="repo"&&t.repoRoot?{dir:M(t.repoRoot,".claude"),file:"settings.local.json"}:{dir:M(le(),".claude"),file:"settings.json"},n=M(e.dir,e.file);if(!(await $t({type:"confirm",name:"go",message:`Patch Claude Code config at ${X(n)} ?`,initial:!0})).go)return null;await P.mkdir(e.dir,{recursive:!0});let o=await P.readFile(n,"utf8").catch(()=>"{}"),i;try{i=JSON.parse(o)}catch{i={}}let s=i.env??{},a=s.ANTHROPIC_BASE_URL;return a&&!a.includes(t.endpoint)&&(a.includes("localhost")||a.includes("127.0.0.1")||a.includes("0.0.0.0"))&&(console.log(),console.log(Pt(" \u26A0 Local LLM proxy detected: ")+X(a)),console.log(X(" AnyForge only routes Anthropic Claude models. Local models (Ollama,")),console.log(X(" LM Studio, etc.) will not work in Claude Code after this patch.")),console.log(X(" To restore: remove ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN")),console.log(X(` from ${n}`)),console.log(),!(await $t({type:"confirm",name:"go",message:"Overwrite existing local LLM proxy config?",initial:!1})).go)?null:(await re(n)&&!await re(n+xe)&&await P.copyFile(n,n+xe),s.ANTHROPIC_BASE_URL=`${t.endpoint}/v1/anthropic`,s.ANTHROPIC_AUTH_TOKEN=t.apiKey,delete s.ANTHROPIC_API_KEY,i.env=s,await P.writeFile(n,JSON.stringify(i,null,2)+`
3
3
  `),console.log(yn(" \u2714")+" Claude Code"),{label:t.scope==="repo"?"Claude Code (repo)":"Claude Code (global)",path:n})}async function Ir(t){let e=M(le(),".claude"),n=M(e,"settings.json");await P.mkdir(e,{recursive:!0});let r=await P.readFile(n,"utf8").catch(()=>"{}"),o;try{o=JSON.parse(r)}catch{o={}}let i=o.env??{},s=i.OTEL_EXPORTER_OTLP_ENDPOINT;return s&&!wn(s,Er(t.endpoint))?(console.log(Pt(" \u26A0 An OpenTelemetry endpoint is already configured: ")+X(s)),console.log(X(" Leaving it untouched. To send Claude Code usage to AnyForge, point")),console.log(X(" OTEL_EXPORTER_OTLP_ENDPOINT at "+t.endpoint+"/api/otel")),null):(await re(n)&&!await re(n+xe)&&await P.copyFile(n,n+xe),i.CLAUDE_CODE_ENABLE_TELEMETRY="1",i.OTEL_METRICS_EXPORTER="otlp",i.OTEL_EXPORTER_OTLP_PROTOCOL="http/json",i.OTEL_EXPORTER_OTLP_ENDPOINT=`${t.endpoint}/api/otel`,i.OTEL_EXPORTER_OTLP_HEADERS=`Authorization=Bearer ${t.apiKey}`,i.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE="delta",o.env=i,await P.writeFile(n,JSON.stringify(o,null,2)+`
4
4
  `),{label:"Claude Code usage telemetry (global)",path:n})}async function Mi(t){if(!t.repoRoot)return null;let e=M(t.repoRoot,".env");if(!(await $t({type:"confirm",name:"go",message:`Write AnyForge env block to ${X(e)} ?`,initial:!0})).go)return null;let r=[Oe,`ANYFORGE_API_KEY=${t.apiKey}`,`ANTHROPIC_BASE_URL=${t.endpoint}/v1/anthropic`,`ANTHROPIC_AUTH_TOKEN=${t.apiKey}`,`OPENAI_BASE_URL=${t.endpoint}/v1/openai`,`OPENAI_API_KEY=${t.apiKey}`,Ze,""].join(`
5
5
  `),o="";try{o=await P.readFile(e,"utf8")}catch{}let i;return o.includes(Oe)?i=o.replace(new RegExp(`${Oe}[\\s\\S]*?${Ze}\\n?`),r):o.length===0?i=r:i=o.endsWith(`
@@ -422,6 +422,7 @@ ${B("IN THE CONVERSATION")}
422
422
  /design [topic] Talk through a technical design with Oracle
423
423
  /catchup What needs you, what landed, what is running
424
424
  (acting on its decisions needs --write --approve)
425
+ /remember [what] Save what this conversation established
425
426
 
426
427
  Enter sends; while Oracle works it queues one message. Shift+Enter adds a
427
428
  line. Esc or Ctrl+C interrupts an answer and keeps the session open; press
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anyforge/control",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "AnyForge CLI — hosted Oracle conversations, a governed LLM proxy, and a scriptable client for approvals, crews, work items and workflows.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://anyforge.ai",