@hyperez/regna-code 0.1.3 → 0.1.5

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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{spawn as w}from"node:child_process";import{fileURLToPath as P}from"node:url";import{dirname as E,join as o}from"node:path";import{existsSync as l,readFileSync as A,writeFileSync as k,mkdirSync as N,unlinkSync as I,chmodSync as G}from"node:fs";import{homedir as L}from"node:os";import{createRequire as U}from"node:module";import{createInterface as $}from"node:readline/promises";var D=E(P(import.meta.url)),u=E(D),f=o(u,"extensions"),_=o(u,"themes","regna.json"),h=o(u,"APPEND_SYSTEM.md"),T="https://regnax.ai/v1",C="regna/regna-pro",R=o(L(),".regna"),m=o(R,"auth.json"),x=o(R,"engine"),a=process.argv.slice(2),g=(...e)=>a.some(r=>e.some(n=>!!(r===n||r.startsWith(`${n}=`)||/^-[a-z]$/i.test(n)&&r.startsWith(n)&&r.length>n.length)));function y(){for(let e of[o(u,"package.json"),o(u,"..","package.json")])try{let r=JSON.parse(A(e,"utf8")).version;if(r)return`v${r}`}catch{}return""}var O=`Regna Code ${y()} - a terminal coding agent on Regna
2
+ import{spawn as v}from"node:child_process";import{fileURLToPath as P}from"node:url";import{dirname as m,join as o}from"node:path";import{existsSync as p,readFileSync as w,writeFileSync as I,mkdirSync as N,unlinkSync as G,chmodSync as L}from"node:fs";import{homedir as k}from"node:os";import{createInterface as U}from"node:readline/promises";var $=m(P(import.meta.url)),c=m($),g=o(c,"extensions"),_=o(c,"themes","regna.json"),f=o(c,"APPEND_SYSTEM.md"),T="https://regnax.ai/v1",D="regna/regna-pro",h=o(k(),".regna"),d=o(h,"auth.json"),x=o(h,"engine"),a=process.argv.slice(2),u=(...e)=>a.some(r=>e.some(n=>!!(r===n||r.startsWith(`${n}=`)||/^-[a-z]$/i.test(n)&&r.startsWith(n)&&r.length>n.length)));function E(){for(let e of[o(c,"package.json"),o(c,"..","package.json")])try{let r=JSON.parse(w(e,"utf8")).version;if(r)return`v${r}`}catch{}return""}var C=`Regna Code ${E()} - a terminal coding agent on Regna
3
3
 
4
4
  Usage:
5
5
  regna [message...] start interactive, optionally with a first message
@@ -23,27 +23,27 @@ Environment:
23
23
  REGNA_POLICY network egress guard: off | warn | enforce
24
24
 
25
25
  Docs: https://github.com/HyperEZ/regna-code
26
- `;function v(){try{let e=JSON.parse(A(m,"utf8"));return e&&typeof e.apiKey=="string"?e:null}catch{return null}}function B(e,r){N(R,{recursive:!0}),k(m,`${JSON.stringify({apiKey:e,baseUrl:r},null,2)}
27
- `);try{G(m,384)}catch{}}function j(){try{return I(m),!0}catch{return!1}}function q(e){try{return`${new URL(e).origin}/console`}catch{return"https://regnax.ai/console"}}function F(e){try{let[r,n]=process.platform==="darwin"?["open",[e]]:process.platform==="win32"?["cmd",["/c","start","",e]]:["xdg-open",[e]];w(r,n,{stdio:"ignore",detached:!0}).unref()}catch{}}async function K(e,r){try{let n=new AbortController,s=setTimeout(()=>n.abort(),8e3),t=await fetch(`${e.replace(/\/+$/,"")}/models`,{headers:{Authorization:`Bearer ${r}`},signal:n.signal});return clearTimeout(s),t.status===401||t.status===403?"invalid":t.ok?"ok":"unknown"}catch{return"unknown"}}async function b(){let e=(process.env.REGNA_BASE_URL||"").trim()||v()?.baseUrl||T,r=q(e);process.stdout.write(`
28
- Regna Code ${y()}
26
+ `;function A(){try{let e=JSON.parse(w(d,"utf8"));return e&&typeof e.apiKey=="string"?e:null}catch{return null}}function B(e,r){N(h,{recursive:!0}),I(d,`${JSON.stringify({apiKey:e,baseUrl:r},null,2)}
27
+ `);try{L(d,384)}catch{}}function O(){try{return G(d),!0}catch{return!1}}function j(e){try{return`${new URL(e).origin}/console`}catch{return"https://regnax.ai/console"}}function F(e){try{let[r,n]=process.platform==="darwin"?["open",[e]]:process.platform==="win32"?["cmd",["/c","start","",e]]:["xdg-open",[e]];v(r,n,{stdio:"ignore",detached:!0}).unref()}catch{}}async function K(e,r){try{let n=new AbortController,s=setTimeout(()=>n.abort(),8e3),t=await fetch(`${e.replace(/\/+$/,"")}/models`,{headers:{Authorization:`Bearer ${r}`},signal:n.signal});return clearTimeout(s),t.status===401||t.status===403?"invalid":t.ok?"ok":"unknown"}catch{return"unknown"}}async function S(){let e=(process.env.REGNA_BASE_URL||"").trim()||A()?.baseUrl||T,r=j(e);process.stdout.write(`
28
+ Regna Code ${E()}
29
29
  Log in to continue.
30
30
 
31
31
  1) Get an API key at ${r}
32
32
  2) Paste it below.
33
33
 
34
- `),F(r);let n=$({input:process.stdin,output:process.stdout}),s="";try{s=(await n.question(" API key: ")).trim()}finally{n.close()}s||(process.stderr.write(` No key entered. Aborting.
34
+ `),F(r);let n=U({input:process.stdin,output:process.stdout}),s="";try{s=(await n.question(" API key: ")).trim()}finally{n.close()}s||(process.stderr.write(` No key entered. Aborting.
35
35
  `),process.exit(1));let t=await K(e,s);return t==="invalid"&&(process.stderr.write(` That key was rejected. Check it and run: regna login
36
36
  `),process.exit(1)),B(s,e),process.stdout.write(t==="ok"?` Logged in.
37
37
 
38
38
  `:` Saved (could not verify right now).
39
39
 
40
- `),s}(g("--help","-h")||a[0]==="help")&&(process.stdout.write(O),process.exit(0));(g("--version")||a[0]==="version")&&(process.stdout.write(`Regna Code ${y()}
41
- `),process.exit(0));a[0]==="login"&&(await b(),process.exit(0));a[0]==="logout"&&(process.stdout.write(j()?`Logged out.
40
+ `),s}(u("--help","-h")||a[0]==="help")&&(process.stdout.write(C),process.exit(0));(u("--version")||a[0]==="version")&&(process.stdout.write(`Regna Code ${E()}
41
+ `),process.exit(0));a[0]==="login"&&(await S(),process.exit(0));a[0]==="logout"&&(process.stdout.write(O()?`Logged out.
42
42
  `:`Not logged in.
43
- `),process.exit(0));var d=(process.env.REGNA_API_KEY||"").trim();if(!d){let e=v();e?.apiKey&&(d=e.apiKey.trim(),!process.env.REGNA_BASE_URL&&e.baseUrl&&(process.env.REGNA_BASE_URL=e.baseUrl))}if(!d)if(process.stdin.isTTY&&process.stdout.isTTY){if(d=await b(),!process.env.REGNA_BASE_URL){let e=v();e?.baseUrl&&(process.env.REGNA_BASE_URL=e.baseUrl)}}else process.stderr.write(`[regna] Not logged in. Run: regna login
44
- `),process.exit(1);process.env.REGNA_API_KEY=d;var i=[],Y=process.env.REGNA_DISCOVER==="1";if(!Y){i.push("--no-extensions");let e=["provider","policy","branding","model","docs-search","docs-analysis"],r=t=>{let p=o(f,`${t}.js`);if(l(p))return p;let c=o(f,`${t}.ts`);return l(c)?c:null},n=e.map(t=>[t,r(t)]),s=n.filter(([,t])=>!t).map(([t])=>t);s.length>0&&(process.stderr.write(`[regna] Missing required extensions: ${s.join(", ")} (in ${f}). Install is corrupted. Aborting.
45
- `),process.exit(1));for(let[,t]of n)i.push("-e",t)}!g("--theme")&&l(_)&&i.push("--theme",_);g("--system-prompt")||(l(h)||(process.stderr.write(`[regna] Missing required prompt: APPEND_SYSTEM.md (${h}). Install is corrupted. Aborting.
43
+ `),process.exit(0));var l=(process.env.REGNA_API_KEY||"").trim();if(!l){let e=A();e?.apiKey&&(l=e.apiKey.trim(),!process.env.REGNA_BASE_URL&&e.baseUrl&&(process.env.REGNA_BASE_URL=e.baseUrl))}if(!l)if(process.stdin.isTTY&&process.stdout.isTTY){if(l=await S(),!process.env.REGNA_BASE_URL){let e=A();e?.baseUrl&&(process.env.REGNA_BASE_URL=e.baseUrl)}}else process.stderr.write(`[regna] Not logged in. Run: regna login
44
+ `),process.exit(1);process.env.REGNA_API_KEY=l;var i=[],Y=process.env.REGNA_DISCOVER==="1";if(!Y){i.push("--no-extensions");let e=["provider","policy","branding","model","docs-search","docs-analysis"],r=t=>{let R=o(g,`${t}.js`);if(p(R))return R;let y=o(g,`${t}.ts`);return p(y)?y:null},n=e.map(t=>[t,r(t)]),s=n.filter(([,t])=>!t).map(([t])=>t);s.length>0&&(process.stderr.write(`[regna] Missing required extensions: ${s.join(", ")} (in ${g}). Install is corrupted. Aborting.
45
+ `),process.exit(1));for(let[,t]of n)i.push("-e",t)}!u("--theme")&&p(_)&&i.push("--theme",_);u("--system-prompt")||(p(f)||(process.stderr.write(`[regna] Missing required prompt: APPEND_SYSTEM.md (${f}). Install is corrupted. Aborting.
46
46
  (To set the prompt yourself on purpose, run with --system-prompt.)
47
- `),process.exit(1)),i.push("--append-system-prompt",`@${h}`));g("--model","-m")||i.push("--model",process.env.REGNA_MODEL||C);i.push(...a);try{N(x,{recursive:!0})}catch{}var M={...process.env,PI_OFFLINE:"1",PI_CODING_AGENT_DIR:x};function H(){let e=process.env.REGNA_ENGINE;if(e)return{cmd:e,prefix:[],label:e};try{let n=U(import.meta.url).resolve("@earendil-works/pi-coding-agent/package.json"),s=E(n),t=JSON.parse(A(n,"utf8")),p=typeof t.bin=="string"?t.bin:t.bin?.pi;if(p){let c=o(s,p);if(l(c))return{cmd:process.execPath,prefix:[c],label:c}}}catch{}return{cmd:"pi",prefix:[],label:"runtime (PATH)"}}var{cmd:z,prefix:J,label:V}=H(),S=w(z,[...J,...i],{stdio:"inherit",env:M});S.on("error",e=>{e&&e.code==="ENOENT"&&(process.stderr.write(`[regna] Runtime executable not found (${V}). Reinstall (npm i -g @hyperez/regna-code) or set REGNA_ENGINE.
47
+ `),process.exit(1)),i.push("--append-system-prompt",`@${f}`));u("--model","-m")||i.push("--model",process.env.REGNA_MODEL||D);i.push(...a);try{N(x,{recursive:!0})}catch{}var q={...process.env,PI_OFFLINE:"1",PI_CODING_AGENT_DIR:x};function M(){let e=o("node_modules","@earendil-works","pi-coding-agent","dist","cli.js"),r=c;for(let n=0;n<10;n++){let s=o(r,e);if(p(s))return s;let t=m(r);if(t===r)break;r=t}return null}function H(){let e=process.env.REGNA_ENGINE;if(e)return{cmd:e,prefix:[],label:e};let r=M();return r?{cmd:process.execPath,prefix:[r],label:r}:{cmd:"pi",prefix:[],label:"runtime (PATH)"}}var{cmd:z,prefix:J,label:V}=H(),b=v(z,[...J,...i],{stdio:"inherit",env:q});b.on("error",e=>{e&&e.code==="ENOENT"&&(process.stderr.write(`[regna] Runtime executable not found (${V}). Reinstall (npm i -g @hyperez/regna-code) or set REGNA_ENGINE.
48
48
  `),process.exit(127)),process.stderr.write(`[regna] Failed to start the runtime: ${e?.message??String(e)}
49
- `),process.exit(1)});S.on("exit",(e,r)=>{if(r){process.kill(process.pid,r);return}process.exit(e??0)});
49
+ `),process.exit(1)});b.on("exit",(e,r)=>{if(r){process.kill(process.pid,r);return}process.exit(e??0)});
@@ -1 +1 @@
1
- import{VERSION as c}from"@earendil-works/pi-coding-agent";import{truncateToWidth as f}from"@earendil-works/pi-tui";var _="Regna Code",d="Terminal coding agent on Regna",g="regna-brand",o=!0,m=[" ____ _____ ____ _ _ _","| _ \\| ____/ ___| \\ | | / \\","| |_) | _|| | _| \\| | / _ \\","| _ <| |__| |_| | |\\ |/ ___ \\","|_| \\_\\_____\\____|_| \\_/_/ \\_\\"],l=m.reduce((n,i)=>Math.max(n,i.length),0);function p(n,i,e,a){let t=s=>i(s,e);if(e<l+4)return["",t(` ${n("accent",_)}`),t(` ${n("muted",d)}`),t(` ${n("dim","/help for commands")}`),""];let r=[""];for(let s of m)r.push(t(` ${n("accent",s)}`));return r.push(""),r.push(t(` ${n("muted",`${_} \xB7 ${d}`)}`)),r.push(t(` ${n("dim","set REGNA_API_KEY, then /help for commands")}`)),r.push(""),r}function u(n){n.setHeader((i,e)=>({render(a){return p((t,r)=>e.fg(t,r),f,a,c)},invalidate(){}})),n.setStatus(g,_),n.setTitle(_)}function h(n){n.setHeader(void 0),n.setStatus(g,void 0)}function E(n){n.on("session_start",async(i,e)=>{e.mode!=="tui"||!o||u(e.ui)}),n.registerCommand("regna-brand",{description:"Toggle Regna Code header/title branding",handler:async(i,e)=>{o=!o,o?(u(e.ui),e.ui.notify("Regna branding on","info")):(h(e.ui),e.ui.notify("Regna branding off (default header)","info"))}})}export{p as buildBrandHeaderLines,E as default};
1
+ import{VERSION as c}from"@earendil-works/pi-coding-agent";import{truncateToWidth as f}from"@earendil-works/pi-tui";var _="Regna Code",d="Terminal coding agent on Regna",g="regna-brand",o=!0,m=[" ____ _____ ____ _ _ _","| _ \\| ____/ ___| \\ | | / \\","| |_) | _|| | _| \\| | / _ \\","| _ <| |__| |_| | |\\ |/ ___ \\","|_| \\_\\_____\\____|_| \\_/_/ \\_\\"],l=m.reduce((n,i)=>Math.max(n,i.length),0);function p(n,i,e,a){let t=s=>i(s,e);if(e<l+4)return["",t(` ${n("accent",_)}`),t(` ${n("muted",d)}`),t(` ${n("dim","/help for commands")}`),""];let r=[""];for(let s of m)r.push(t(` ${n("accent",s)}`));return r.push(""),r.push(t(` ${n("muted",`${_} \xB7 ${d}`)}`)),r.push(t(` ${n("dim","/help for commands")}`)),r.push(""),r}function u(n){n.setHeader((i,e)=>({render(a){return p((t,r)=>e.fg(t,r),f,a,c)},invalidate(){}})),n.setStatus(g,_),n.setTitle(_)}function h(n){n.setHeader(void 0),n.setStatus(g,void 0)}function x(n){n.on("session_start",async(i,e)=>{e.mode!=="tui"||!o||u(e.ui)}),n.registerCommand("regna-brand",{description:"Toggle Regna Code header/title branding",handler:async(i,e)=>{o=!o,o?(u(e.ui),e.ui.notify("Regna branding on","info")):(h(e.ui),e.ui.notify("Regna branding off (default header)","info"))}})}export{p as buildBrandHeaderLines,x as default};
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Postinstall: brand the terminal/tab title as "Regna".
4
+ *
5
+ * The runtime composes the terminal title as `${APP_TITLE} - <cwd>` and re-asserts it on
6
+ * every turn/cwd change, so a one-time setTitle from an extension cannot win the race.
7
+ * APP_TITLE is a compiled constant whose fallback is the engine's own mark. We surgically
8
+ * rewrite ONLY that fallback string to "Regna" in the installed dependency.
9
+ *
10
+ * Scope is deliberately narrow:
11
+ * - Only the `APP_TITLE = piConfigName ? APP_NAME : "<x>"` literal is touched.
12
+ * - APP_NAME, the config dir name, and the agent-dir env var are left untouched, so the
13
+ * launcher's state isolation (PI_CODING_AGENT_DIR) keeps working regardless.
14
+ *
15
+ * Best effort: any failure is swallowed and the install still succeeds. If the patch does
16
+ * not apply (e.g. the engine changed its layout), the only effect is the title stays as the
17
+ * engine default. This is idempotent and safe to run on every install.
18
+ */
19
+
20
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
21
+ import { dirname, join } from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+
24
+ const TITLE = "Regna";
25
+
26
+ // The engine's package.json "exports" map blocks require.resolve of its package.json/main,
27
+ // so we locate the installed file by walking up node_modules from this script's location.
28
+ // Handles both nested (under our package) and hoisted installs, dev and global.
29
+ function findEngineFile(relInsidePackage) {
30
+ const rel = join("node_modules", "@earendil-works", "pi-coding-agent", relInsidePackage);
31
+ let dir = dirname(fileURLToPath(import.meta.url));
32
+ for (let i = 0; i < 10; i++) {
33
+ const cand = join(dir, rel);
34
+ if (existsSync(cand)) return cand;
35
+ const parent = dirname(dir);
36
+ if (parent === dir) break;
37
+ dir = parent;
38
+ }
39
+ return null;
40
+ }
41
+
42
+ try {
43
+ const configPath = findEngineFile(join("dist", "config.js"));
44
+ if (!configPath) throw new Error("engine config.js not found");
45
+ const src = readFileSync(configPath, "utf8");
46
+ // Match: APP_TITLE = piConfigName ? APP_NAME : "<anything>"
47
+ const re = /(APP_TITLE\s*=\s*piConfigName\s*\?\s*APP_NAME\s*:\s*)"[^"]*"/;
48
+ if (re.test(src)) {
49
+ const out = src.replace(re, `$1"${TITLE}"`);
50
+ if (out !== src) writeFileSync(configPath, out);
51
+ }
52
+ } catch {
53
+ /* cosmetic only; never fail the install */
54
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperez/regna-code",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Regna Code. A terminal coding agent on Regna. Install with `npm i -g @hyperez/regna-code` and run `regna`. Works with the Regna cloud API and on-premise deployments.",
5
5
  "license": "PolyForm-Noncommercial-1.0.0",
6
6
  "private": false,
@@ -23,6 +23,9 @@
23
23
  "bin": {
24
24
  "regna": "dist/bin/regna.mjs"
25
25
  },
26
+ "scripts": {
27
+ "postinstall": "node dist/postinstall.mjs"
28
+ },
26
29
  "files": [
27
30
  "dist",
28
31
  "README.md",