kronk-cli 0.1.0 → 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/README.md CHANGED
@@ -23,8 +23,67 @@ entirely on your machine. No network, no API key, no per-token cost.
23
23
  2104→812 tok · 61.3 tok/s · ttft 240ms · 1980 cached
24
24
  ```
25
25
 
26
+ [![ci](https://github.com/BardiaN/kronk-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/BardiaN/kronk-cli/actions/workflows/ci.yml)
27
+ [![security](https://github.com/BardiaN/kronk-cli/actions/workflows/security.yml/badge.svg)](https://github.com/BardiaN/kronk-cli/actions/workflows/security.yml)
28
+ [![codeql](https://github.com/BardiaN/kronk-cli/actions/workflows/codeql.yml/badge.svg)](https://github.com/BardiaN/kronk-cli/actions/workflows/codeql.yml)
29
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/BardiaN/kronk-cli/badge)](https://scorecard.dev/viewer/?uri=github.com/BardiaN/kronk-cli)
30
+ [![npm](https://img.shields.io/npm/v/kronk-cli?logo=npm)](https://www.npmjs.com/package/kronk-cli)
31
+
26
32
  **Zero dependencies.** It is `fetch` and `readline` against Kronk's OpenAI-compatible API.
27
33
 
34
+ **It talks to your Kronk server and nothing else** — enforced in CI by running the whole thing
35
+ inside a network namespace with only loopback. See [Verifying this build](#verifying-this-build).
36
+
37
+ ---
38
+
39
+ ## Verifying this build
40
+
41
+ This tool reads your files and runs your commands. You should not have to take anyone's word for
42
+ what it does with them — so every claim here is machine-checkable.
43
+
44
+ ### Check the artifact came from this source
45
+
46
+ Every release tarball carries a signed attestation binding it to the repository, commit and
47
+ workflow run that produced it:
48
+
49
+ ```bash
50
+ gh attestation verify kronk-cli-*.tgz --repo BardiaN/kronk-cli
51
+ ```
52
+
53
+ npm packages carry the same provenance, shown as a **Provenance** panel on the
54
+ [package page](https://www.npmjs.com/package/kronk-cli), and verifiable locally:
55
+
56
+ ```bash
57
+ npm audit signatures
58
+ ```
59
+
60
+ Both fail if the artifact was built anywhere other than this repository's CI.
61
+
62
+ ### Read the scan results yourself
63
+
64
+ | | |
65
+ |---|---|
66
+ | [Security tab](https://github.com/BardiaN/kronk-cli/security/code-scanning) | every CodeQL and Scorecard finding, open and closed |
67
+ | [Scorecard report](https://scorecard.dev/viewer/?uri=github.com/BardiaN/kronk-cli) | per-check supply-chain scores, updated weekly |
68
+ | [Actions](https://github.com/BardiaN/kronk-cli/actions/workflows/security.yml) | full logs of every scan, including the egress proof |
69
+
70
+ These are published by GitHub and the OpenSSF, not by this project. Nobody here can edit them.
71
+
72
+ ### Check it does not phone home
73
+
74
+ The strongest claim, and the easiest to test yourself:
75
+
76
+ ```bash
77
+ # Linux — run it with no network except loopback
78
+ sudo unshare --net bash -c 'ip link set lo up; kronk-cli --models'
79
+ ```
80
+
81
+ CI runs exactly this on every pull request against a stub server, and a second step proves the
82
+ namespace was really isolated so a pass cannot be a false negative.
83
+
84
+ Or just read `src/` — it is under 1,500 lines with no dependencies, and every network call goes
85
+ through one function in `src/client.js`.
86
+
28
87
  ---
29
88
 
30
89
  ## Requirements
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kronk-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A Claude-Code-style terminal agent for local models served by Kronk.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
package/src/config.js CHANGED
@@ -35,6 +35,27 @@ export const config = {
35
35
  rcPath: RC,
36
36
  };
37
37
 
38
+ /**
39
+ * File contents and command output leave this process in request bodies, which
40
+ * is the whole job. Over loopback that is fine. Pointed at a remote host over
41
+ * plain HTTP it is not, so say so once rather than letting it pass silently.
42
+ */
43
+ export function warnIfInsecure(warn = console.error) {
44
+ let url;
45
+ try { url = new URL(config.baseUrl); } catch { return false; }
46
+
47
+ const local = ['localhost', '127.0.0.1', '::1', '0.0.0.0'].includes(url.hostname)
48
+ || url.hostname.endsWith('.local')
49
+ || url.hostname === 'host.docker.internal';
50
+
51
+ if (url.protocol === 'https:' || local) return false;
52
+
53
+ warn(` warning: ${config.baseUrl} is remote and unencrypted.`);
54
+ warn(' File contents and command output will cross the network in clear text.');
55
+ warn(' Use https, or an SSH tunnel to keep the endpoint on localhost.');
56
+ return true;
57
+ }
58
+
38
59
  export const headers = () => ({
39
60
  'Content-Type': 'application/json',
40
61
  Authorization: `Bearer ${config.token}`,
package/src/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import readline from 'node:readline/promises';
3
3
  import { stdin, stdout } from 'node:process';
4
4
  import { readFile } from 'node:fs/promises';
5
- import { config, DEFAULT_MODEL } from './config.js';
5
+ import { config, DEFAULT_MODEL, warnIfInsecure } from './config.js';
6
6
  import { listModels, listModelDetails, listLoaded, modelLimits, tokenize } from './client.js';
7
7
  import { runTurn, SYSTEM, SYSTEM_AUTO } from './agent.js';
8
8
  import { c, banner, fmtContext, statusLine } from './ui.js';
@@ -322,6 +322,9 @@ async function oneShot(prompt) {
322
322
  }
323
323
 
324
324
  async function main() {
325
+ // Before anything reaches the network, on every path through the program.
326
+ warnIfInsecure();
327
+
325
328
  if (SHOW_MODELS) { await showModels(); return; }
326
329
  if (SHOW_MCP) { await showMcp(); process.exit(0); }
327
330