@hyperez/regna-code 0.1.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/LICENSE ADDED
@@ -0,0 +1,75 @@
1
+ # PolyForm Noncommercial License 1.0.0
2
+
3
+ <https://polyformproject.org/licenses/noncommercial/1.0.0>
4
+
5
+ Required Notice: Copyright © 2026 HyperEZ Inc. (https://hyperez.io)
6
+
7
+ ## Acceptance
8
+
9
+ In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
10
+
11
+ ## Copyright License
12
+
13
+ The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to Distribution License and make changes or new works based on the software according to Changes and New Works License.
14
+
15
+ ## Distribution License
16
+
17
+ The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by Changes and New Works License.
18
+
19
+ ## Notices
20
+
21
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software.
22
+
23
+ ## Changes and New Works License
24
+
25
+ The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
26
+
27
+ ## Patent License
28
+
29
+ The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
30
+
31
+ ## Noncommercial Purposes
32
+
33
+ Any noncommercial purpose is a permitted purpose.
34
+
35
+ ## Personal Uses
36
+
37
+ Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
38
+
39
+ ## Noncommercial Organizations
40
+
41
+ Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
42
+
43
+ ## Fair Use
44
+
45
+ You may have "fair use" rights for the software under the law. These terms do not limit them.
46
+
47
+ ## No Other Rights
48
+
49
+ These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
50
+
51
+ ## Patent Defense
52
+
53
+ If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
54
+
55
+ ## Violations
56
+
57
+ The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
58
+
59
+ ## No Liability
60
+
61
+ As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.
62
+
63
+ ## Definitions
64
+
65
+ The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
66
+
67
+ **You** refers to the individual or entity agreeing to these terms.
68
+
69
+ **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
70
+
71
+ **Your licenses** are all the licenses granted to you for the software under these terms.
72
+
73
+ **Use** means anything you do with the software requiring one of your licenses.
74
+
75
+ © PolyForm Project Inc.
package/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # Regna Code
2
+
3
+ A terminal coding agent on Regna. One command, `regna`, gives you an AI coding assistant in your terminal: read, edit, write, run, and multi-step automation, backed by Regna models.
4
+
5
+ Regna Code is a thin client. The models, knowledge, and routing live behind the Regna API, so the same `regna` command works against the Regna cloud or an on-premise (air-gapped) deployment, just by pointing it at a different endpoint.
6
+
7
+ ## Requirements
8
+
9
+ - Node.js >= 22.19.0
10
+ - A Regna API endpoint and key.
11
+
12
+ ## Install
13
+
14
+ ```
15
+ npm i -g @hyperez/regna-code
16
+ ```
17
+
18
+ Set your key and run:
19
+
20
+ ```
21
+ export REGNA_API_KEY="..." # your Regna API key
22
+
23
+ regna # interactive
24
+ regna "explain this repo" # with a prompt
25
+ regna -p "summarize today's changes" < /dev/null # headless/scripted (close stdin)
26
+ ```
27
+
28
+ By default Regna Code talks to the Regna cloud API (`https://regnax.ai/v1`). To use a self-hosted or air-gapped deployment, point it at your own endpoint:
29
+
30
+ ```
31
+ export REGNA_BASE_URL="http://<your-gateway>/v1"
32
+ ```
33
+
34
+ ## Environment variables
35
+
36
+ | Variable | Default | Description |
37
+ |---|---|---|
38
+ | `REGNA_API_KEY` | (none) | Regna API key. Required. Read from the environment only. |
39
+ | `REGNA_BASE_URL` | `https://regnax.ai/v1` | Regna API base URL (OpenAI-compatible). Point this at a self-hosted endpoint for on-premise use. |
40
+ | `REGNA_MODEL` | `regna/default` | Starting model pattern. |
41
+ | `REGNA_CODER_MODEL` | (none) | Exact model id that `/regna-coder` selects. |
42
+ | `REGNA_GENERAL_MODEL` | (none) | Exact model id that `/regna-general` selects. |
43
+ | `REGNA_EXPOSE_ALIASES` | (unset) | `1` also exposes path-style (slash) model ids. Hidden by default. Ids pinned via `REGNA_MODEL`/`REGNA_CODER_MODEL`/`REGNA_GENERAL_MODEL` are always shown. |
44
+ | `REGNA_POLICY` | `off` | Network egress guard: `off` / `warn` (notify, allow) / `enforce` (block external network tools). Set `enforce` for locked-down or air-gapped use. |
45
+ | `REGNA_ALLOW_HOSTS` | (none) | Extra allowed hosts (comma-separated) when the policy is on. URL or `host:port` accepted. |
46
+ | `REGNA_OFFLINE` | (unset) | `1` runs in air-gapped mode: blocks the runtime's own outbound network (update checks and the like). Your Regna API calls are unaffected. |
47
+ | `REGNA_DISCOVER` | (unset) | `1` lets the runtime auto-discover extensions instead of loading the verified set explicitly. |
48
+ | `REGNA_ENGINE` | (bundled) | Override the path to the runtime executable. Resolved from the bundled dependency by default. |
49
+ | `REGNA_DOCS_ENABLED` | (unset) | `1` enables the document search tool (`regna_docs_search`) and the `/regna-docs` skill. Only turn this on when the backend's retrieval endpoint is available. |
50
+ | `REGNA_RETRIEVAL_PATH` | `/api/retrieval/search` | Override the retrieval endpoint path. |
51
+ | `REGNA_DOCS_TIMEOUT_MS` | `15000` | Retrieval timeout (clamped 1000~120000). |
52
+
53
+ ## Commands
54
+
55
+ | Command | Action |
56
+ |---|---|
57
+ | `/regna-coder` | Switch to a coding model (prefers an id containing `coder`, else default). |
58
+ | `/regna-general` | Switch to a general model (prefers `instruct`, else default). |
59
+ | `/regna-brand` | Toggle the Regna Code header/title branding. |
60
+ | `/regna-docs <question>` | Document-grounded query. Searches indexed documents with `regna_docs_search`, answers using only retrieved evidence with `[source n]` citations, and says it does not know when there is no evidence. Requires `REGNA_DOCS_ENABLED=1`. |
61
+
62
+ ## Document search (`REGNA_DOCS_ENABLED=1`)
63
+
64
+ When enabled, two features turn on. Use them only where the backend's retrieval endpoint is available.
65
+
66
+ - Search tool `regna_docs_search`: the model fetches evidence chunks and answers with `[source n]` citations. Documents outside the caller's permissions are not returned (key = identity).
67
+ - Citation check gate: every answer in a turn that searched for evidence is checked. If it cites a source number not in the evidence (hallucination), or asserts a claim without any citation after searching, a non-blocking warning is shown. "I don't know" answers pass.
68
+
69
+ `/regna-docs <question>` sets up this flow in one command.
70
+
71
+ ## Air-gapped mode
72
+
73
+ Regna Code runs fully offline against a self-hosted deployment. Set:
74
+
75
+ ```
76
+ export REGNA_BASE_URL="http://<your-gateway>/v1"
77
+ export REGNA_OFFLINE=1 # block the runtime's own outbound network
78
+ export REGNA_POLICY=enforce # block external network tools; allow the gateway, localhost, and private/internal ranges
79
+ ```
80
+
81
+ The egress guard is a defense layer, not a hard sandbox. Enforce real boundaries with OS and network controls and an internal mirror.
82
+
83
+ ## Troubleshooting
84
+
85
+ | Symptom | Action |
86
+ |---|---|
87
+ | `401 status code` | Check `REGNA_API_KEY`. |
88
+ | Headless run hangs | Close stdin: `regna -p ... < /dev/null`. |
89
+ | Only `regna/default` shows | Check `REGNA_BASE_URL` and key, then `/reload`. |
90
+ | `[regna policy] blocked` | If legitimate, add `REGNA_ALLOW_HOSTS` or set `REGNA_POLICY=warn`/`off`. |
91
+ | Missing extension/prompt, aborted | Reinstall. Fail-closed behavior is intentional. |
92
+ | Runtime executable not found | Reinstall (`npm i -g @hyperez/regna-code`) or set `REGNA_ENGINE`. |
93
+
94
+ ## License
95
+
96
+ PolyForm Noncommercial License 1.0.0. Noncommercial use is permitted. For commercial use, contact HyperEZ (https://hyperez.io). See `LICENSE`.
@@ -0,0 +1,12 @@
1
+ You are Regna Code, a terminal coding agent running on Regna models. You help with coding, automation, and document-grounded questions.
2
+
3
+ Operating principles:
4
+ - Prefer correctness over speed. Work autonomously on ordinary implementation, but verify what you do. Stop and confirm before actions that are hard to reverse, security-sensitive, outward-facing, or where the requirement is ambiguous. Never claim something works without verifying it.
5
+ - Match the conventions of the surrounding code: naming, comment density, and idioms.
6
+ - Do not add external network calls on your own. When the network policy is enforced, limit calls to the Regna endpoint, localhost, and allowlisted hosts; if you need something outside that, stop and confirm.
7
+
8
+ Security:
9
+ - Never expose API keys, credentials, or passwords in responses, logs, or outputs.
10
+
11
+ Style:
12
+ - Be concise and precise. Do not overstate. Mark numbers or performance you cannot guarantee as estimates.
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ import{spawn as A}from"node:child_process";import{fileURLToPath as x}from"node:url";import{dirname as f,join as n}from"node:path";import{existsSync as c,readFileSync as E}from"node:fs";import{createRequire as b}from"node:module";var w=f(x(import.meta.url)),p=f(w),m=n(p,"extensions"),h=n(p,"themes","regna.json"),g=n(p,"APPEND_SYSTEM.md"),l=process.argv.slice(2),d=(...e)=>l.some(s=>e.some(t=>!!(s===t||s.startsWith(`${t}=`)||/^-[a-z]$/i.test(t)&&s.startsWith(t)&&s.length>t.length)));function R(){for(let e of[n(p,"package.json"),n(p,"..","package.json")])try{let s=JSON.parse(E(e,"utf8")).version;if(s)return`v${s}`}catch{}return""}var y=`Regna Code ${R()} - a terminal coding agent on Regna
3
+
4
+ Usage:
5
+ regna [message...] start interactive, optionally with a first message
6
+ regna "explain this repo" run with a prompt
7
+ regna -p "summarize changes" < /dev/null headless/scripted (close stdin)
8
+
9
+ In-session commands:
10
+ /regna-coder switch to a coding model
11
+ /regna-general switch to a general model
12
+ /regna-brand toggle the Regna Code branding
13
+ /regna-docs <q> document-grounded query (requires REGNA_DOCS_ENABLED=1)
14
+
15
+ Key environment variables:
16
+ REGNA_API_KEY Regna API key (required)
17
+ REGNA_BASE_URL Regna API base URL (default https://regnax.ai/v1)
18
+ REGNA_MODEL starting model (default regna/default)
19
+ REGNA_POLICY network egress guard: off | warn | enforce
20
+ REGNA_OFFLINE=1 air-gapped mode (block the runtime's own outbound network)
21
+
22
+ Docs: https://github.com/HyperEZ/regna-code
23
+ `;(d("--help","-h")||l[0]==="help")&&(process.stdout.write(y),process.exit(0));(d("--version")||l[0]==="version")&&(process.stdout.write(`Regna Code ${R()}
24
+ `),process.exit(0));var o=[],P=process.env.REGNA_DISCOVER==="1";if(!P){o.push("--no-extensions");let e=["provider","policy","branding","model","docs-search","docs-analysis"],s=r=>{let a=n(m,`${r}.js`);if(c(a))return a;let i=n(m,`${r}.ts`);return c(i)?i:null},t=e.map(r=>[r,s(r)]),u=t.filter(([,r])=>!r).map(([r])=>r);u.length>0&&(process.stderr.write(`[regna] Missing required extensions: ${u.join(", ")} (in ${m}). Install is corrupted. Aborting.
25
+ `),process.exit(1));for(let[,r]of t)o.push("-e",r)}!d("--theme")&&c(h)&&o.push("--theme",h);d("--system-prompt")||(c(g)||(process.stderr.write(`[regna] Missing required prompt: APPEND_SYSTEM.md (${g}). Install is corrupted. Aborting.
26
+ (To set the prompt yourself on purpose, run with --system-prompt.)
27
+ `),process.exit(1)),o.push("--append-system-prompt",`@${g}`));d("--model","-m")||o.push("--model",process.env.REGNA_MODEL||"regna/default");o.push(...l);var N={...process.env};process.env.REGNA_OFFLINE==="1"&&(N.PI_OFFLINE="1");function _(){let e=process.env.REGNA_ENGINE;if(e)return{cmd:e,prefix:[],label:e};try{let t=b(import.meta.url).resolve("@earendil-works/pi-coding-agent/package.json"),u=f(t),r=JSON.parse(E(t,"utf8")),a=typeof r.bin=="string"?r.bin:r.bin?.pi;if(a){let i=n(u,a);if(c(i))return{cmd:process.execPath,prefix:[i],label:i}}}catch{}return{cmd:"pi",prefix:[],label:"runtime (PATH)"}}var{cmd:G,prefix:I,label:k}=_(),v=A(G,[...I,...o],{stdio:"inherit",env:N});v.on("error",e=>{e&&e.code==="ENOENT"&&(process.stderr.write(`[regna] Runtime executable not found (${k}). Reinstall (npm i -g @hyperez/regna-code) or set REGNA_ENGINE.
28
+ `),process.exit(127)),process.stderr.write(`[regna] Failed to start the runtime: ${e?.message??String(e)}
29
+ `),process.exit(1)});v.on("exit",(e,s)=>{if(s){process.kill(process.pid,s);return}process.exit(e??0)});
@@ -0,0 +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};
@@ -0,0 +1,8 @@
1
+ var l="regna_docs_search",d=/\[source\s*(\d+)\]/gi,m=/(do(?:n['’]t| not)\s+know|cannot\s+(?:find|determine|answer|tell)|can['’]t\s+(?:find|determine|answer|tell)|no\s+(?:evidence|sources?|documents?|information|relevant)|not\s+(?:found|available)|unable\s+to\s+(?:find|determine|answer))/i;function f(n){if(typeof n=="string")return n;if(!Array.isArray(n))return"";let e=[];for(let t of n)t&&t.type==="text"&&typeof t.text=="string"&&e.push(t.text);return e.join(`
2
+ `)}function h(n){return!n||typeof n!="object"?"":f(n.content)}function p(n){let e=0;for(let t of g(n))t>e&&(e=t);return e}function g(n){let e=[];if(typeof n!="string")return e;d.lastIndex=0;let t;for(;(t=d.exec(n))!==null;){let o=Number.parseInt(t[1],10);Number.isFinite(o)&&e.push(o)}return e}function y(n){return Array.from(new Set(g(n))).sort((e,t)=>e-t)}function w(n,e){let t=y(n),o=[],s=t.filter(r=>r<1||r>e);return s.length>0&&o.push({code:"INVALID_SOURCE",detail:`Cited source numbers not in the evidence: ${s.map(r=>`[source ${r}]`).join(", ")} (${e} evidence chunks retrieved)`}),n.trim().length>0&&e>0&&t.length===0&&!m.test(n)&&o.push({code:"NO_CITATION",detail:"Evidence was retrieved but the answer has no [source n] citation (possible guessing). Cite evidence for each claim."}),{ok:o.length===0,violations:o,referenced:t,available:e}}function x(n){return`Answer the following question grounded in the indexed documents.
3
+ 1) First search for evidence with the ${l} tool.
4
+ 2) Answer using only the retrieved evidence. Mark each claim with [source n].
5
+ 3) If there is no evidence, say you do not know. Do not guess.
6
+
7
+ Question: ${n}`}function A(n){n.registerCommand("regna-docs",{description:"Document-grounded query (search, cite, verify). Usage: /regna-docs <question>",handler:async(e,t)=>{let o=(e||"").trim();if(!o){t.ui.notify("Usage: /regna-docs <question>","info");return}if(process.env.REGNA_DOCS_ENABLED!=="1"){t.ui.notify("Document search is disabled. Enable it with REGNA_DOCS_ENABLED=1.","warning");return}n.sendUserMessage(x(o))}}),n.on("turn_end",async(e,t)=>{try{let s=(Array.isArray(e.toolResults)?e.toolResults:[]).filter(i=>i&&i.toolName===l);if(s.length===0)return;let u=s.map(i=>f(i.content)).join(`
8
+ `),r=p(u);if(r===0)return;let c=h(e.message);if(!c.trim())return;let a=w(c,r);a.ok||t.ui.notify(`Citation check warning: ${a.violations.map(i=>i.detail).join(" / ")}`,"warning")}catch{}})}export{h as assistantText,p as availableSourceCount,x as buildDocPrompt,A as default,f as extractText,y as referencedSources,w as verifyCitations};
@@ -0,0 +1,14 @@
1
+ import{Type as h}from"typebox";var T="https://regnax.ai/v1",x="/api/retrieval/search",D=15e3,w=1e3,S=12e4,A=1024*1024,g=8192,b=5,E=20;function k(o,n){let r=(o??"").trim(),i=r||T,a;try{let t=new URL(i);if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("scheme");a=t.origin}catch{if(r)throw new Error(`Invalid REGNA_BASE_URL (http/https required): ${r}`);a="https://regnax.ai"}let e=(n??"").trim()||x;return e.startsWith("/")||(e=`/${e}`),`${a}${e}`}function v(o){let n=typeof o=="number"?Math.floor(o):NaN;return!Number.isFinite(n)||n<=0?b:Math.min(E,n)}function N(o){let n=Number(o);return!Number.isFinite(n)||n<=0?D:Math.min(S,Math.max(w,n))}function $(o,n){if(n.length===0)return`Query: ${o}
2
+
3
+ No accessible document evidence was found. Do not guess; say you do not know.`;let r=(e,t)=>e.citation||[e.document_title,e.location].filter(Boolean).join(" ")||e.document_id||`chunk ${t}`,i=n.map((e,t)=>`[source ${t+1}] ${r(e,t+1)}
4
+ ${(e.text??"").trim()}`),a=n.map((e,t)=>`[source ${t+1}] ${r(e,t+1)}`);return`Query: ${o}
5
+
6
+ Use only the evidence below to answer, and mark each claim with [source n]. If there is no evidence, say you do not know.
7
+
8
+ ${i.join(`
9
+
10
+ `)}
11
+
12
+ Sources:
13
+ ${a.join(`
14
+ `)}`}var s=o=>({content:[{type:"text",text:o}],details:{count:0}});async function U(o,n){let r=o.body;if(!r||typeof r.getReader!="function"){let u=await o.text();return u.length>n?null:u}let i=r.getReader(),a=new TextDecoder,e=0,t="";for(;;){let{done:u,value:l}=await i.read();if(u)break;if(l){if(e+=l.byteLength,e>n){try{await i.cancel()}catch{}return null}t+=a.decode(l,{stream:!0})}}return t+=a.decode(),t}function I(o){(process.env.REGNA_DOCS_ENABLED??"").trim()==="1"&&o.registerTool({name:"regna_docs_search",label:"Document search",description:"Search the indexed documents (Regna index) and fetch evidence chunks. Use when you need knowledge from the document corpus such as rules, contracts, or policies. Results come with [source n] citations, and you must answer using only that evidence. Documents outside the caller's permissions are not returned.",promptSnippet:"regna_docs_search: search documents and fetch cited evidence",parameters:h.Object({query:h.String({description:"natural-language search query",maxLength:g}),top_k:h.Optional(h.Number({description:`number of evidence chunks (default ${b}, max ${E})`}))}),async execute(n,r,i,a,e){let t=(process.env.REGNA_API_KEY??"").trim();if(!t)return s("Document search failed: REGNA_API_KEY is unset.");if(i?.aborted)return s("Document search was cancelled.");if(typeof r.query!="string"||r.query.trim()==="")return s("Document search failed: empty query.");if(r.query.length>g)return s(`Document search failed: query too long (max ${g} chars).`);let u;try{u=k(process.env.REGNA_BASE_URL,process.env.REGNA_RETRIEVAL_PATH)}catch(c){return s(`Document search failed: ${c.message}`)}let l=v(r.top_k),p=new AbortController,R=setTimeout(()=>p.abort(),N(process.env.REGNA_DOCS_TIMEOUT_MS)),y=()=>p.abort();i?.addEventListener("abort",y);try{let c=await fetch(u,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({query:r.query,top_k:l}),signal:p.signal});if(c.status===401)return s("Document search failed: auth error (check REGNA_API_KEY).");if(c.status===409)return s("Document search is not enabled yet (RAG disabled or no index).");if(!c.ok)return s(`Document search failed: HTTP ${c.status}.`);let d=Number(c.headers.get("content-length"));if(Number.isFinite(d)&&d>A)return s("Document search failed: response is abnormally large.");let m=await U(c,A);if(m===null)return s("Document search failed: response is abnormally large.");let f;try{f=JSON.parse(m)}catch{return s("Document search failed: response parse error.")}let _=Array.isArray(f.results)?f.results:[];return{content:[{type:"text",text:$(r.query,_)}],details:{count:_.length}}}catch(c){let d=c,m=d?.name==="AbortError"?"timed out or cancelled":d?.message||"network error";return s(`Document search failed: ${m}.`)}finally{clearTimeout(R),i?.removeEventListener("abort",y)}}})}export{I as default,$ as formatResults,N as normalizeTimeout,v as normalizeTopK,U as readCapped,k as resolveRetrievalUrl};
@@ -0,0 +1 @@
1
+ var l="regna";function g(n,c,i){if(n.length===0)return;if(i&&n.includes(i))return i;let d=(r,s)=>r.toLowerCase().includes(s),o=n.find(r=>d(r,"coder"));if(c==="coder")return o??(n.includes("default")?"default":n[0]);let e=n.find(r=>d(r,"instruct")&&!d(r,"coder"));return e||(n.includes("default")?"default":n.find(r=>r!==o)??n[0])}function m(n){let c={coder:process.env.REGNA_CODER_MODEL?.trim()||void 0,general:process.env.REGNA_GENERAL_MODEL?.trim()||void 0},i=!1,d=async(o,e)=>{let r=e.modelRegistry.getAll().filter(t=>t.provider===l).map(t=>t.id);if(r.length===0){e.ui.notify("No regna provider models. Check the provider extension and REGNA_API_KEY.","warning");return}let s=c[o];if(s&&!r.includes(s)){let t=o==="coder"?"REGNA_CODER_MODEL":"REGNA_GENERAL_MODEL";e.ui.notify(`${t}='${s}' is not in the registered list; ignoring. Available: ${r.join(", ")}`,"warning")}let a=g(r,o,s),f=a?e.modelRegistry.find(l,a):void 0;if(!f){e.ui.notify(`Could not find a ${o} model (${l}/${a??"?"}).`,"warning");return}if(i=!0,!await n.setModel(f))i=!1,e.ui.notify(`Switch failed (API key may be missing): ${l}/${a}`,"warning");else{let t=a==="default"?" (active model)":"";e.ui.notify(`Model set: ${l}/${a}${t}`,"info")}};n.registerCommand("regna-coder",{description:"Switch to a Regna coding model (/regna-coder)",handler:async(o,e)=>d("coder",e)}),n.registerCommand("regna-general",{description:"Switch to a Regna general model (/regna-general)",handler:async(o,e)=>d("general",e)}),n.on("model_select",async(o,e)=>{if(i){i=!1;return}o.source!=="restore"&&o.model.provider===l&&e.ui.notify(`Regna model: ${o.model.id}`,"info")})}export{m as default,g as pickRegnaModelId};
@@ -0,0 +1 @@
1
+ var a=e=>({block:!0,reason:e}),l={block:!1};function g(e){return e.replace(/(^|\s)#.*$/,"$1")}function h(e){let n=[];for(let t of e.matchAll(/\b[a-z][a-z0-9+.-]*:\/\/([^\s/'"`)]+)/gi))n.push(t[1]);for(let t of e.matchAll(/(?:^|[\s;&|(`])[\w.-]+@([^\s:/'"`)]+)/gi))n.push(t[1]);return n}function f(e){let n=e.trim().toLowerCase(),t=n.match(/^\[([^\]]+)\](?::\d+)?$/);return t?t[1]:(n.match(/:/g)?.length??0)===1?n.replace(/:\d+$/,""):n}function p(e,n){let t=f(e);return t?!!(n.has(t)||t==="localhost"||t==="::1"||t==="0.0.0.0"||/^127\./.test(t)||/^10\./.test(t)||/^192\.168\./.test(t)||/^172\.(1[6-9]|2\d|3[01])\./.test(t)||/^169\.254\./.test(t)||/\.(local|internal|lan|intra)$/.test(t)):!1}var d="(?:[\\w./-]*/)?",b=new RegExp(`(?:^|[\\s;&|(\`])${d}(?:curl|wget|httpie|http|https|nc|ncat|netcat|telnet|ftp|ftps)(?=[\\s;&|)\`]|$)`,"i"),m=new RegExp(`(?:^|[\\s;&|(\`])${d}(?:ssh|scp|sftp|rsync)(?=[\\s;&|)\`]|$)`,"i"),w=/(?:\blocalhost\b|\b127\.\d{1,3}\.\d{1,3}\.\d{1,3}\b|\b0\.0\.0\.0\b|\[?::1\]?|\b10\.\d{1,3}\.\d{1,3}\.\d{1,3}\b|\b192\.168\.\d{1,3}\.\d{1,3}\b|\b172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}\b|\b169\.254\.\d{1,3}\.\d{1,3}\b|\b[a-z0-9-]+\.(?:local|internal|lan|intra)\b)/i,y=/\.(json|txt|md|js|ts|tsx|jsx|mjs|cjs|py|sh|ya?ml|toml|lock|log|csv|xml|html?|css|scss|png|jpe?g|gif|svg|webp|pdf|zip|tar|gz|tgz|bz2|env|cfg|ini|conf|sql|go|rs|rb|java|kt|c|cpp|h|hpp|php|tsv|map)$/i;function $(e){let n=[];for(let t of e.split(/\s+/)){if(!t||t.startsWith("-")||(t=t.replace(/^['"`]+|['"`]+$/g,""),/^[a-z][a-z0-9+.-]*:\/\//i.test(t)))continue;let r=t.match(/^(?:[\w.-]+@)?(\[[0-9a-f:]+\]|[a-z0-9.-]+)(?::\d+)?(?:\/.*)?$/i);if(!r)continue;let o=r[1];(/^\[[0-9a-f:]+\]$/i.test(o)||/^\d{1,3}(?:\.\d{1,3}){3}$/.test(o)||/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/i.test(o))&&(y.test(o)||n.push(o))}return n}function k(e,n){let t=g(e??""),r=h(t);for(let c of r)if(!p(c,n))return a(`Blocked external host access: ${f(c)}`);let o=r.length>0,s=b.test(t),i=m.test(t);if(!s&&!i)return l;let u=!1;for(let c of $(t))if(p(c,n))u=!0;else return a(`Blocked external host access: ${f(c)}`);return i&&!s||o||u||w.test(t)?l:a("Blocked: could not determine the target host of a network tool")}var _=/(?:web[._-]?(?:fetch|search|run|open|browse)|url[._-]?(?:fetch|open|get)|http[._-]?(?:request|get|post|fetch)|browser|playwright|puppeteer|scrape|^fetch$|^download$)/i;function x(e){return _.test(e)?a(`Blocked network tool: ${e}`):l}function E(){let e=(process.env.REGNA_POLICY??"off").trim().toLowerCase();return e==="warn"||e==="enforce"?e:"off"}function L(){let e=new Set,n=t=>{let r=t.trim().toLowerCase();if(!r)return;if(/:\/\//.test(r))try{r=new URL(r).hostname}catch{}let o=f(r);o&&e.add(o)};for(let t of(process.env.REGNA_ALLOW_HOSTS??"").split(","))n(t);try{let t=new URL(process.env.REGNA_BASE_URL??"https://regnax.ai/v1");t.hostname&&n(t.hostname)}catch{}return e}function A(e){let n=E();if(n==="off")return;let t=L(),r=(o,s)=>{try{o.hasUI&&o.ui?.notify&&o.ui.notify(s,"warning")}catch{}};e.on("tool_call",async(o,s)=>{let i=o.toolName==="bash"?k(String(o.input?.command??""),t):x(o.toolName);if(i.block){if(n==="warn"){r(s,`[regna policy] ${i.reason} (warn: allowed)`);return}return r(s,`[regna policy] blocked: ${i.reason}`),{block:!0,reason:`[regna policy] ${i.reason}`}}})}export{$ as bareHostOperands,A as default,k as evaluateBash,x as evaluateToolName,h as explicitHosts,p as isLocalHost,f as normalizeHost};
@@ -0,0 +1 @@
1
+ var d="regna",l="https://regnax.ai/v1";function u(){let r=(process.env.REGNA_BASE_URL??"").trim(),t=r===""?l:r,e;try{e=new URL(t)}catch{return l}if(e.protocol!=="http:"&&e.protocol!=="https:")return l;let o=`${e.origin}${e.pathname}`.replace(/\/+$/,"");return/\/v\d+$/.test(o)?o:`${o}/v1`}function A(r){let t=r.toLowerCase(),e=t==="default"||t==="current"||t==="auto",o=/qwq|qwen3|think|reason/.test(t);return{id:r,name:e?"Regna (active model)":`Regna \xB7 ${r}`,reasoning:o,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:32768,maxTokens:8192}}async function _(r,t){let e=new AbortController,o=setTimeout(()=>e.abort(),4e3);try{let s=await fetch(`${r}/models`,{headers:{Authorization:`Bearer ${t}`},signal:e.signal});if(!s.ok)return[];let c=await s.text();if(c.length>524288)return[];let i;try{i=JSON.parse(c)}catch{return[]}let a=(Array.isArray(i.data)?i.data:[]).map(n=>n&&typeof n.id=="string"?n.id:"").filter(n=>n.length>0&&n.length<=200);return Array.from(new Set(a)).slice(0,24)}catch{return[]}finally{clearTimeout(o)}}async function g(r){let t=u(),e=(process.env.REGNA_API_KEY??"").trim(),o=(process.env.REGNA_EXPOSE_ALIASES??"").trim()==="1",s=e?await _(t,e):[],c=new Set,i=a=>{let n=(a??"").trim();n&&c.add(n.startsWith(`${d}/`)?n.slice(d.length+1):n)};i(process.env.REGNA_MODEL),i(process.env.REGNA_CODER_MODEL),i(process.env.REGNA_GENERAL_MODEL),o||(s=s.filter(a=>a==="default"||!a.includes("/")||c.has(a))),s.includes("default")||s.unshift("default"),s.some(a=>a!=="default")||console.warn(`[regna] Model discovery failed or REGNA_API_KEY is unset. Registering 'regna/default' only. Set REGNA_API_KEY and run /reload. (base=${t})`),r.registerProvider(d,{name:"Regna",baseUrl:t,apiKey:"$REGNA_API_KEY",api:"openai-completions",models:s.map(A)})}export{g as default};
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "regna",
3
+ "vars": {
4
+ "primary": "#3A43FF",
5
+ "indigo": "#6E78FF",
6
+ "blue": "#1A7EFF",
7
+ "magenta": "#EC4CFF",
8
+ "peri": "#8086FF",
9
+ "green": "#3DD68C",
10
+ "red": "#FF5C72",
11
+ "amber": "#F5B544",
12
+ "muted": "#8B90A6",
13
+ "dim": "#6B7188",
14
+ "line": "#3A3F52",
15
+ "lineSubtle": "#2A2E3D"
16
+ },
17
+ "colors": {
18
+ "accent": "indigo",
19
+ "border": "line",
20
+ "borderAccent": "blue",
21
+ "borderMuted": "lineSubtle",
22
+ "success": "green",
23
+ "error": "red",
24
+ "warning": "amber",
25
+ "muted": "muted",
26
+ "dim": "dim",
27
+ "text": "",
28
+ "thinkingText": "muted",
29
+
30
+ "selectedBg": "#23263A",
31
+ "userMessageBg": "#20233A",
32
+ "userMessageText": "",
33
+ "customMessageBg": "#1E2138",
34
+ "customMessageText": "",
35
+ "customMessageLabel": "indigo",
36
+ "toolPendingBg": "#1B1E2E",
37
+ "toolSuccessBg": "#17241C",
38
+ "toolErrorBg": "#2A1A20",
39
+ "toolTitle": "indigo",
40
+ "toolOutput": "",
41
+
42
+ "mdHeading": "blue",
43
+ "mdLink": "indigo",
44
+ "mdLinkUrl": "muted",
45
+ "mdCode": "magenta",
46
+ "mdCodeBlock": "",
47
+ "mdCodeBlockBorder": "line",
48
+ "mdQuote": "muted",
49
+ "mdQuoteBorder": "peri",
50
+ "mdHr": "line",
51
+ "mdListBullet": "blue",
52
+
53
+ "toolDiffAdded": "green",
54
+ "toolDiffRemoved": "red",
55
+ "toolDiffContext": "muted",
56
+
57
+ "syntaxComment": "dim",
58
+ "syntaxKeyword": "indigo",
59
+ "syntaxFunction": "blue",
60
+ "syntaxVariable": "peri",
61
+ "syntaxString": "green",
62
+ "syntaxNumber": "magenta",
63
+ "syntaxType": "blue",
64
+ "syntaxOperator": "muted",
65
+ "syntaxPunctuation": "muted",
66
+
67
+ "thinkingOff": "dim",
68
+ "thinkingMinimal": "muted",
69
+ "thinkingLow": "peri",
70
+ "thinkingMedium": "blue",
71
+ "thinkingHigh": "primary",
72
+ "thinkingXhigh": "magenta",
73
+
74
+ "bashMode": "amber"
75
+ },
76
+ "export": {
77
+ "pageBg": "#14151C",
78
+ "cardBg": "#1B1D2A",
79
+ "infoBg": "#23263A"
80
+ }
81
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@hyperez/regna-code",
3
+ "version": "0.1.1",
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
+ "license": "PolyForm-Noncommercial-1.0.0",
6
+ "private": false,
7
+ "type": "module",
8
+ "keywords": [
9
+ "regna",
10
+ "coding-agent",
11
+ "ai",
12
+ "cli",
13
+ "terminal"
14
+ ],
15
+ "homepage": "https://github.com/HyperEZ/regna-code#readme",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/HyperEZ/regna-code.git"
19
+ },
20
+ "bugs": {
21
+ "url": "https://github.com/HyperEZ/regna-code/issues"
22
+ },
23
+ "bin": {
24
+ "regna": "dist/bin/regna.mjs"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "README.md",
29
+ "LICENSE"
30
+ ],
31
+ "dependencies": {
32
+ "@earendil-works/pi-coding-agent": "^0.79.4",
33
+ "@earendil-works/pi-tui": "^0.79.4",
34
+ "typebox": "^1.3.1"
35
+ },
36
+ "engines": {
37
+ "node": ">=22.19.0"
38
+ }
39
+ }