@gapi/gcli 1.8.237 → 1.8.239
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/.agents/skills/changelog/SKILL.md +59 -0
- package/.agents/skills/cluster-targeting/SKILL.md +70 -0
- package/.agents/skills/gcli-command/SKILL.md +55 -0
- package/.agents/skills/local-ai-runners/SKILL.md +40 -0
- package/.claude/README.md +33 -0
- package/AGENTS.md +105 -0
- package/CLAUDE.md +20 -0
- package/README-CLI.md +385 -23
- package/README.md +40 -0
- package/docs/CHANGELOG.md +8 -0
- package/docs/changelog.d/2026-10-11-local-ai-runners-gcli-runner-commands-bridge-ollama-to-the-chat.md +25 -0
- package/docs/changelog.d/2026-10-11-local-ai-runners-gcli-runner-models-chooses-the-models-shown-in-chat.md +12 -0
- package/docs/changelog.d/2026-10-11-local-ai-runners-runner-reports-each-model-s-loaded-context-window.md +22 -0
- package/docs/changelog.d/2026-10-11-repo-ai-ready-package-setup-agents-md-skills-feature-changelog.md +18 -0
- package/docs/changelog.d/2026-10-11-repo-tests-workflow-runs-lint-and-tests-on-every-branch-push.md +18 -0
- package/docs/changelog.d/README.md +51 -0
- package/docs/features/README.md +33 -0
- package/docs/features/local-ai-runners.md +71 -0
- package/package.json +2 -1
- package/release/index.js +921 -92
- package/scripts/changelog.mjs +348 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## 2026-10-11 - repo: AI-ready package setup - AGENTS.md, skills, feature-keyed changelog
|
|
2
|
+
|
|
3
|
+
**Feature:** repo · **Type:** repo
|
|
4
|
+
|
|
5
|
+
- `AGENTS.md` (canonical guide for this package) + thin `CLAUDE.md`;
|
|
6
|
+
skills in `.agents/skills/` (`cluster-targeting` moved there, new
|
|
7
|
+
`gcli-command`, `local-ai-runners`, `changelog`) with `.claude/skills`
|
|
8
|
+
symlink; feature-keyed changelog (`docs/changelog.d/`,
|
|
9
|
+
`scripts/changelog.mjs`) and `docs/features/`.
|
|
10
|
+
- `README.md`: new "Local AI Models (Ollama runner)" section.
|
|
11
|
+
`README-CLI.md` regenerated from `--all-help` - it was missing the cron,
|
|
12
|
+
cluster, rabbitmq, plugin and `lambda:package` commands.
|
|
13
|
+
- `jest.config.js` maps the tsconfig path aliases (`~/`, `@introspection/`,
|
|
14
|
+
`@commands/`) - specs importing command code could not resolve before.
|
|
15
|
+
- **Test:** `node scripts/changelog.mjs check`; `npx jest --coverage=false`.
|
|
16
|
+
- **Debug:** spec fails with "Cannot find module '~/...'" -> the
|
|
17
|
+
`moduleNameMapper` was lost.
|
|
18
|
+
- **Verification:** `check` OK; jest 27/27.
|
package/docs/changelog.d/2026-10-11-repo-tests-workflow-runs-lint-and-tests-on-every-branch-push.md
ADDED
|
@@ -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,71 @@
|
|
|
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
|
+
and models `/api/show` answers 404/410 for - e.g. retired `:cloud`
|
|
39
|
+
models, cached so they aren't re-asked every heartbeat). Each heartbeat
|
|
40
|
+
also reads `/api/ps` and reports `runtimeContextLength` - the window a
|
|
41
|
+
LOADED model actually runs with (OLLAMA_CONTEXT_LENGTH / Ollama default).
|
|
42
|
+
The backend fits every request to it, because Ollama silently drops the
|
|
43
|
+
oldest messages of a prompt that is too long (see the canonical doc,
|
|
44
|
+
"Context window").
|
|
45
|
+
- `config.ts` (saved runner, URL derivation), `start.ts`, `list.ts`,
|
|
46
|
+
`models.ts`, `delete.ts`, `index.ts` (command registration), `types.ts`.
|
|
47
|
+
- `src/services/gql-client.ts` - `createLocalRunner`, `listLocalRunners`,
|
|
48
|
+
`setLocalRunnerModels`, `deleteLocalRunner` (through the gateway, with the
|
|
49
|
+
login session).
|
|
50
|
+
|
|
51
|
+
## How to test
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx jest test/runner.spec.ts --coverage=false # fake server socket + fake streaming Ollama
|
|
55
|
+
npm run build && node release/index.js runner:start --help
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`test/runner.spec.ts` plays both the Lambforge server (protocol replies) and
|
|
59
|
+
Ollama (streamed body, multi-byte UTF-8 split across reads, held-open
|
|
60
|
+
streams). Full end-to-end steps: the canonical doc's "How to test".
|
|
61
|
+
|
|
62
|
+
`npm run build` rewrites the committed `release/index.js` - don't commit
|
|
63
|
+
that from a feature branch unless you are releasing.
|
|
64
|
+
|
|
65
|
+
## How to debug
|
|
66
|
+
|
|
67
|
+
Runner log lines: `-> chat request (<model>)`, `<- <status> (<model>) in Ns`,
|
|
68
|
+
`x cancelled`, `x <error>`, `Heartbeat failed: ...`, `Cannot reach Ollama
|
|
69
|
+
at ...`. `Disconnected from Lambforge; reconnecting in Ns` = socket closed
|
|
70
|
+
(backend restart, network). For the backend side and the symptom table see
|
|
71
|
+
the canonical doc.
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gapi/gcli",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.239",
|
|
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",
|