@gapi/gcli 1.8.236 → 1.8.238

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.
@@ -0,0 +1,18 @@
1
+ ## 2026-10-11 - repo: Tests workflow runs lint and tests on every branch push
2
+
3
+ **Feature:** repo · **Type:** tooling
4
+
5
+ - New `.github/workflows/tests.yml` at the gapi repo root ("Tests"): on
6
+ every push to a non-master branch (skippable with `[ci-skip]`), Node 24,
7
+ `npx @rxdi/bolt install`, `npm run lint`, `npm test` across all
8
+ workspaces; dependencies cached by `yarn.lock` + package manifests. Same
9
+ shape as graphql-server's Tests / graphql-server-lambdas' Specs. Before,
10
+ lint/test only ran in Publish - after the merge to master.
11
+ - **Test:** push a branch -> the "Tests" check appears on the PR. Locally,
12
+ from the gapi root: `npm run lint && npm test`.
13
+ - **Debug:** a red Tests run names the workspace in its log prefix
14
+ (`(@gapi/gcli) $ npm test ...`); reproduce with the same root command or
15
+ `npm test` inside that package.
16
+ - **Verification:** locally from the root: lint exit 0 (all 14 eslint
17
+ workspaces), tests exit 0 (@gapi/ac 1/1, @gapi/cli-builder 1/1,
18
+ @gapi/gcli 27/27); workflow YAML parsed with js-yaml.
@@ -0,0 +1,51 @@
1
+ # Changelog fragments (by feature)
2
+
3
+ One file per change: `YYYY-MM-DD-<feature>-<slug>.md`, each a complete entry
4
+ in the template below. Create one with
5
+
6
+ node scripts/changelog.mjs new <feature> "<summary>" [--type feat|fix|perf|refactor|test|docs|tooling|repo]
7
+
8
+ fill in every `<...>` placeholder, run `node scripts/changelog.mjs check`, and
9
+ commit it **together with the change**.
10
+
11
+ The tool is plain Node (>= 18, no dependencies - runs in any Node
12
+ container, no Python needed); `npm run changelog -- <command> ...` is an
13
+ alias.
14
+
15
+ Why this shape:
16
+
17
+ - **Fragments, not one file** - two branches prepending to the same
18
+ `CHANGELOG.md` conflict on every rebase; two new files never do.
19
+ `docs/CHANGELOG.md` is the archive and is written only by
20
+ `node scripts/changelog.mjs compact` (default branch, own commit).
21
+ - **Keyed by feature** - every entry names its feature (`**Feature:**`), and
22
+ each feature has a living doc in `docs/features/<feature>.md` (`check`
23
+ enforces it). `node scripts/changelog.mjs render --feature <f>` prints the whole
24
+ history of one feature, archive included - the starting point when you
25
+ need to debug or extend it later. `node scripts/changelog.mjs features` lists
26
+ them all.
27
+ - **Test / Debug / Verification are mandatory** - an entry records how to
28
+ test the change and where to look when it breaks, not just what changed.
29
+
30
+ Use the feature `repo` for changes that belong to no single feature (repo
31
+ setup, tooling, dependency bumps). The same feature slug is used across the
32
+ Lambforge repos (gql-fission, graphql-server, graphql-server-lambdas,
33
+ graphql-server-functions, gcli), so a cross-repo feature reads the same
34
+ everywhere.
35
+
36
+ ## Template
37
+
38
+ ```markdown
39
+ ## YYYY-MM-DD - <feature>: <one-line summary>
40
+
41
+ **Feature:** <feature> · **Type:** feat | fix | perf | refactor | test | docs | tooling | repo
42
+
43
+ - What is now true and why - one bullet per logical change; name the
44
+ files/modules that own it. Mention the sibling-repo halves of a
45
+ cross-repo change.
46
+ - **Test:** the specs/commands to run and what passing looks like; manual
47
+ steps if there is no automated coverage.
48
+ - **Debug:** where to look when it breaks - log prefixes, collections,
49
+ env flags, likely failure modes and their symptoms.
50
+ - **Verification:** what was actually run for this change and its result.
51
+ ```
@@ -0,0 +1,33 @@
1
+ # Features
2
+
3
+ Living docs, one per feature (current state). The change history of a
4
+ feature is in `docs/changelog.d/` - `node scripts/changelog.mjs render --feature <slug>`.
5
+
6
+ ## Writing a feature doc
7
+
8
+ One file per feature, `docs/features/<feature>.md`, named by the same
9
+ kebab-case slug the changelog uses (`node scripts/changelog.mjs features`). It
10
+ describes what is true NOW - history goes in `docs/changelog.d/`
11
+ (`node scripts/changelog.mjs render --feature <feature>`). Update it in the same
12
+ commit as the change. A feature spanning several repos has ONE canonical doc
13
+ (in the repo that owns most of it) and a short slice doc in each other repo
14
+ that links to it.
15
+
16
+ Outline (drop sections that don't apply):
17
+
18
+ 1. **Header** - status + date, feature slug, one paragraph: what the user gets.
19
+ 2. **How it works** - the flow, end to end; a small diagram if it helps.
20
+ 3. **Files** - where each part lives (path -> responsibility).
21
+ 4. **Config / limits** - env vars, timeouts, quotas, entitlements.
22
+ 5. **How to test** - exact commands/specs, plus manual steps for what has
23
+ no automated coverage.
24
+ 6. **How to debug** - symptom -> where to look (log prefixes, collections,
25
+ flags). This is the section future-you will need most.
26
+ 7. **Security model** - who can do what, what is validated where.
27
+ 8. **Known limits / next steps.**
28
+
29
+ ## Features
30
+
31
+ | Feature | Doc | Notes |
32
+ |---|---|---|
33
+ | `local-ai-runners` | [local-ai-runners.md](local-ai-runners.md) | `runner:*` commands; canonical doc in graphql-server |
@@ -0,0 +1,64 @@
1
+ # Local AI runners - gcli slice
2
+
3
+ **Feature slug:** `local-ai-runners` · canonical doc (architecture, protocol,
4
+ security, debugging table):
5
+ `graphql-server/docs/features/local-ai-runners.md`. This file covers only
6
+ what lives in gcli.
7
+
8
+ ## Commands
9
+
10
+ | Command | What it does |
11
+ |---|---|
12
+ | `gcli runner:start [--name] [--token] [--ollama] [--wsUrl] [--reset]` | Connects this machine's Ollama to the chat. First run registers a runner with the `gcli login` session and saves it to `~/.graphql-server/runner.json` (0600); `--token` instead uses a token from Profile -> Local AI runners (headless machines); `--reset` forgets the saved runner and registers a new one. Runs until Ctrl+C, reconnecting with backoff (1s -> 30s). |
13
+ | `gcli runner:list` | Your runners: online, last seen, models |
14
+ | `gcli runner:models [--id] [--show a,b \| --all \| --none]` | Which models appear in the chat picker; no flag = list |
15
+ | `gcli runner:delete [--id]` | Delete a runner and revoke its token (default: the saved one) |
16
+
17
+ Endpoints: `--wsUrl` > `runner.json` > derived from the `gcli login` URL
18
+ (`https://api.lambforge.com` -> `wss://api.lambforge.com/subscriptions`;
19
+ `http://localhost:9004/...` -> `ws://localhost:9000/subscriptions`).
20
+ Ollama: `--ollama` > `$OLLAMA_HOST` (scheme optional, `0.0.0.0` -> `127.0.0.1`)
21
+ > `http://127.0.0.1:11434`. Requires Node >= 22 (global `WebSocket`).
22
+
23
+ ## Code
24
+
25
+ `src/commands/runner/`:
26
+
27
+ - `connection.ts` - `RunnerConnection`: subscriptions-transport-ws client
28
+ (`connection_init` with `{ runnerToken }`, subscription
29
+ `subscribeToRunnerRequests`, mutations `runnerHeartbeat` / `runnerRespond`
30
+ over the same socket), heartbeat every 30s (a failed heartbeat forces a
31
+ reconnect), request proxying to Ollama, `cancel` -> abort, `ping` every
32
+ 30s while Ollama keeps a request queued. `FrameSender` numbers frames
33
+ (`seq`), merges consecutive chunks (<= 32KB) and sends batches every 50ms,
34
+ sequentially. `RunnerAuthError` = token refused -> exit 1 with a `--reset` hint.
35
+ - `ollama.ts` - `ALLOWED_REQUESTS` (only `POST /v1/chat/completions`; the
36
+ backend has its own copy), `OllamaModels` (`/api/tags` + cached
37
+ `/api/show` per digest; drops models without the `completion` capability).
38
+ - `config.ts` (saved runner, URL derivation), `start.ts`, `list.ts`,
39
+ `models.ts`, `delete.ts`, `index.ts` (command registration), `types.ts`.
40
+ - `src/services/gql-client.ts` - `createLocalRunner`, `listLocalRunners`,
41
+ `setLocalRunnerModels`, `deleteLocalRunner` (through the gateway, with the
42
+ login session).
43
+
44
+ ## How to test
45
+
46
+ ```bash
47
+ npx jest test/runner.spec.ts --coverage=false # fake server socket + fake streaming Ollama
48
+ npm run build && node release/index.js runner:start --help
49
+ ```
50
+
51
+ `test/runner.spec.ts` plays both the Lambforge server (protocol replies) and
52
+ Ollama (streamed body, multi-byte UTF-8 split across reads, held-open
53
+ streams). Full end-to-end steps: the canonical doc's "How to test".
54
+
55
+ `npm run build` rewrites the committed `release/index.js` - don't commit
56
+ that from a feature branch unless you are releasing.
57
+
58
+ ## How to debug
59
+
60
+ Runner log lines: `-> chat request (<model>)`, `<- <status> (<model>) in Ns`,
61
+ `x cancelled`, `x <error>`, `Heartbeat failed: ...`, `Cannot reach Ollama
62
+ at ...`. `Disconnected from Lambforge; reconnecting in Ns` = socket closed
63
+ (backend restart, network). For the backend side and the symptom table see
64
+ the canonical doc.
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@gapi/gcli",
3
- "version": "1.8.236",
3
+ "version": "1.8.238",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/Stradivario/gapi.git"
7
7
  },
8
8
  "scripts": {
9
+ "changelog": "node scripts/changelog.mjs",
9
10
  "start": "gapi start --outDir release --outFile index.js",
10
11
  "patch": "npm run build && npm version patch && npm publish --update-readme --access public && npm run delete-dist",
11
12
  "delete-dist": "rm -rf dist",