genaicode 2.17.0 → 2.17.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 +117 -96
- package/{CHANGELOG.md → docs/CHANGELOG.md} +9 -6
- package/docs/pivot.md +2 -2
- package/docs/semver.md +1 -1
- package/package.json +35 -13
package/README.md
CHANGED
|
@@ -1,89 +1,47 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<picture>
|
|
3
|
-
<source media="(prefers-color-scheme: dark)" srcset="media/logo-dark.png">
|
|
4
|
-
<source media="(prefers-color-scheme: light)" srcset="media/logo.png">
|
|
5
|
-
<img alt="GenAIcode Logo." src="media/logo.png" width="100%" height="auto">
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/media/logo-dark.png">
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/media/logo.png">
|
|
5
|
+
<img alt="GenAIcode Logo." src="docs/media/logo.png" width="100%" height="auto">
|
|
6
6
|
</picture>
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
# GenAIcode
|
|
10
10
|
|
|
11
|
-
GenAIcode
|
|
11
|
+
GenAIcode drives the coding-agent CLIs you already have (Claude Code, Codex, GitHub Copilot
|
|
12
|
+
CLI, Cursor, Gemini CLI, opencode, Muse, Mistral Vibe, Antigravity) behind one API and one
|
|
13
|
+
CLI. Script them, swap them with one flag, and let your tests decide when the job is done.
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
**Like jQuery**, the common case starts with one small function and becomes more specific
|
|
22
|
-
through chaining—configure a request, follow up across multiple prompts, and keep history
|
|
23
|
-
portable without adopting a full agent framework.
|
|
24
|
-
|
|
25
|
-
GenAIcode 1.x was a coding agent; see [Migration from 1.x](#migration-from-1x) if you need
|
|
26
|
-
the old product or the 2.0 scope decisions.
|
|
27
|
-
|
|
28
|
-
## Install
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="docs/media/showcase.mp4">
|
|
17
|
+
<img alt="genaicode in 20 seconds: the Vite overlay fixes a broken page, run --verify sends a failed test back to the agent, and an agent inside an app waits for Approve." src="docs/media/screenshots/showcase.gif" width="100%">
|
|
18
|
+
</a>
|
|
19
|
+
<br>
|
|
20
|
+
<sub>Recorded live with Claude Code and Codex. <a href="docs/media/showcase.mp4">Full video (87 s)</a>.</sub>
|
|
21
|
+
</p>
|
|
29
22
|
|
|
30
23
|
```bash
|
|
31
|
-
npm
|
|
24
|
+
npx genaicode run --verify "npm test" "fix the failing tests"
|
|
32
25
|
```
|
|
33
26
|
|
|
34
|
-
|
|
27
|
+
That runs the first agent CLI installed on your machine in the current directory, then runs
|
|
28
|
+
`npm test`. If the check fails, its output goes back to the agent for another attempt. Add
|
|
29
|
+
`-a codex` (or `claude`, `copilot`, `opencode`...) to pick the agent; the command stays the
|
|
30
|
+
same. From there, the same drivers are a TypeScript API, a chat in your terminal or browser,
|
|
31
|
+
a panel inside your Vite app, and an agent inside your own app.
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
GenAIcode also ships [a thin LLM layer](#also-a-thin-llm-layer) for calling model providers
|
|
34
|
+
from backend code. The two halves are separate subpaths: importing `genaicode` never spawns an
|
|
35
|
+
agent, and `genaicode/agents` loads no provider SDK.
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
yourself. The cost shows up when the same backend needs a second provider, a test double,
|
|
40
|
-
or shared policy (timeouts, JSON parsing, rate limits, fallback) without copying glue.
|
|
41
|
-
|
|
42
|
-
GenAIcode is that thin shared layer:
|
|
43
|
-
|
|
44
|
-
- One portable prompt/tool IR (`PromptItem`) instead of OpenAI messages vs Anthropic
|
|
45
|
-
blocks vs Gemini contents.
|
|
46
|
-
- One request API (`.text()`, `.json()`, `.stream()`, chains) over those adapters.
|
|
47
|
-
- A tiny `ModelProvider` seam so tests and custom gateways do not mock vendor HTTP.
|
|
48
|
-
- Opt-in middleware and retry helpers—no hidden tool runners, no silent retries, no
|
|
49
|
-
agent loop.
|
|
50
|
-
|
|
51
|
-
If you are happy importing one SDK and never swapping models or providers, stay on the
|
|
52
|
-
SDK. If you want the call site to look the same while the edge stays replaceable, use
|
|
53
|
-
GenAIcode.
|
|
54
|
-
|
|
55
|
-
## A prompt in three lines
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
import { genaicode } from 'genaicode';
|
|
59
|
-
import { openai } from 'genaicode/providers';
|
|
60
|
-
|
|
61
|
-
const ai = genaicode(openai({ model: 'your-model-name' }));
|
|
62
|
-
const answer = await ai('Explain why the sky is blue in two sentences.').text();
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
The client is callable on purpose. Configuration is ordinary method chaining—system
|
|
66
|
-
instructions, temperature, token limits, and more—without a separate options object or
|
|
67
|
-
framework setup:
|
|
37
|
+
## Install
|
|
68
38
|
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
.system('You are a concise technical writer.')
|
|
72
|
-
.temperature(0.2)
|
|
73
|
-
.maxOutputTokens(500)
|
|
74
|
-
.text();
|
|
39
|
+
```bash
|
|
40
|
+
npm install genaicode
|
|
75
41
|
```
|
|
76
42
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```ts
|
|
80
|
-
const releaseNote = ai('Create a release note from these commits')
|
|
81
|
-
.system('You are a concise technical writer.')
|
|
82
|
-
.temperature(0.2);
|
|
83
|
-
|
|
84
|
-
const short = await releaseNote.maxOutputTokens(200).text();
|
|
85
|
-
const long = await releaseNote.maxOutputTokens(800).text();
|
|
86
|
-
```
|
|
43
|
+
Node.js 20 or newer is required. The agent CLIs are yours to install and log in to;
|
|
44
|
+
`npx genaicode agents` lists which ones it finds.
|
|
87
45
|
|
|
88
46
|
## Coding agents
|
|
89
47
|
|
|
@@ -168,15 +126,15 @@ session; `/help` lists the rest.
|
|
|
168
126
|
|
|
169
127
|
<p align="center">
|
|
170
128
|
<picture>
|
|
171
|
-
<source media="(prefers-reduced-motion: reduce)" srcset="media/screenshots/chat-terminal.png">
|
|
172
|
-
<img alt="genaicode chat in a terminal: the agent fixes a failing test, then takes queued follow-ups." src="media/screenshots/chat-terminal.gif" width="49%">
|
|
129
|
+
<source media="(prefers-reduced-motion: reduce)" srcset="docs/media/screenshots/chat-terminal.png">
|
|
130
|
+
<img alt="genaicode chat in a terminal: the agent fixes a failing test, then takes queued follow-ups." src="docs/media/screenshots/chat-terminal.gif" width="49%">
|
|
173
131
|
</picture>
|
|
174
132
|
<picture>
|
|
175
|
-
<source media="(prefers-reduced-motion: reduce) and (prefers-color-scheme: dark)" srcset="media/screenshots/wolf-dark.png">
|
|
176
|
-
<source media="(prefers-reduced-motion: reduce)" srcset="media/screenshots/wolf-light.png">
|
|
177
|
-
<source media="(prefers-color-scheme: dark)" srcset="media/screenshots/chat-browser-dark.gif">
|
|
178
|
-
<source media="(prefers-color-scheme: light)" srcset="media/screenshots/chat-browser-light.gif">
|
|
179
|
-
<img alt="genaicode ui in a browser: the same fix and a follow-up." src="media/screenshots/chat-browser-light.gif" width="49%">
|
|
133
|
+
<source media="(prefers-reduced-motion: reduce) and (prefers-color-scheme: dark)" srcset="docs/media/screenshots/wolf-dark.png">
|
|
134
|
+
<source media="(prefers-reduced-motion: reduce)" srcset="docs/media/screenshots/wolf-light.png">
|
|
135
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/media/screenshots/chat-browser-dark.gif">
|
|
136
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/media/screenshots/chat-browser-light.gif">
|
|
137
|
+
<img alt="genaicode ui in a browser: the same fix and a follow-up." src="docs/media/screenshots/chat-browser-light.gif" width="49%">
|
|
180
138
|
</picture>
|
|
181
139
|
</p>
|
|
182
140
|
|
|
@@ -186,9 +144,9 @@ The terminal UI rings the terminal bell instead. `/bark off` (or the Bark button
|
|
|
186
144
|
|
|
187
145
|
<p align="center">
|
|
188
146
|
<picture>
|
|
189
|
-
<source media="(prefers-color-scheme: dark)" srcset="media/screenshots/wolf-dark.png">
|
|
190
|
-
<source media="(prefers-color-scheme: light)" srcset="media/screenshots/wolf-light.png">
|
|
191
|
-
<img alt="The browser UI with the wolf behind a finished turn." src="media/screenshots/wolf-light.png" width="80%">
|
|
147
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/media/screenshots/wolf-dark.png">
|
|
148
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/media/screenshots/wolf-light.png">
|
|
149
|
+
<img alt="The browser UI with the wolf behind a finished turn." src="docs/media/screenshots/wolf-light.png" width="80%">
|
|
192
150
|
</picture>
|
|
193
151
|
</p>
|
|
194
152
|
|
|
@@ -213,9 +171,9 @@ export default defineConfig({ plugins: [genaicode()] });
|
|
|
213
171
|
|
|
214
172
|
<p align="center">
|
|
215
173
|
<picture>
|
|
216
|
-
<source media="(prefers-color-scheme: dark)" srcset="media/screenshots/vite-dark.png">
|
|
217
|
-
<source media="(prefers-color-scheme: light)" srcset="media/screenshots/vite-light.png">
|
|
218
|
-
<img alt="The genaicode panel over a Vite app: the agent fixed the page's two errors." src="media/screenshots/vite-light.png" width="80%">
|
|
174
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/media/screenshots/vite-dark.png">
|
|
175
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/media/screenshots/vite-light.png">
|
|
176
|
+
<img alt="The genaicode panel over a Vite app: the agent fixed the page's two errors." src="docs/media/screenshots/vite-light.png" width="80%">
|
|
219
177
|
</picture>
|
|
220
178
|
</p>
|
|
221
179
|
|
|
@@ -409,7 +367,7 @@ import 'genaicode/react/styles.css';
|
|
|
409
367
|
```
|
|
410
368
|
|
|
411
369
|
<p align="center">
|
|
412
|
-
<img alt="A shop admin with the agent drawer: the agent proposed a refund, waiting for Approve." src="media/screenshots/app-agent.png" width="80%">
|
|
370
|
+
<img alt="A shop admin with the agent drawer: the agent proposed a refund, waiting for Approve." src="docs/media/screenshots/app-agent.png" width="80%">
|
|
413
371
|
</p>
|
|
414
372
|
|
|
415
373
|
Under it, `/api/agent` serves `GET /events` (a stream of `AppAgentState`: the session, earlier
|
|
@@ -431,7 +389,70 @@ bearer and refuses browser requests; every other route asks `authorize` and refu
|
|
|
431
389
|
cross-site requests. Without `authorize` only a loopback `Host` is accepted (add names with
|
|
432
390
|
`allowedHosts`), so a DNS-rebinding page cannot reach the agent.
|
|
433
391
|
|
|
434
|
-
##
|
|
392
|
+
## Also: a thin LLM layer
|
|
393
|
+
|
|
394
|
+
Besides driving agents, GenAIcode is a small TypeScript toolkit for calling LLMs from backend
|
|
395
|
+
code. It sits between raw provider SDKs and full agent frameworks: one prompt representation,
|
|
396
|
+
thin provider adapters, a convenient request API, and lightweight conversation chains. This
|
|
397
|
+
layer does not inspect repositories, execute shell commands, edit files, or run an agent UI.
|
|
398
|
+
|
|
399
|
+
**Like jQuery**, the common case starts with one small function and becomes more specific
|
|
400
|
+
through chaining—configure a request, follow up across multiple prompts, and keep history
|
|
401
|
+
portable without adopting a full agent framework.
|
|
402
|
+
|
|
403
|
+
### A prompt in three lines
|
|
404
|
+
|
|
405
|
+
```ts
|
|
406
|
+
import { genaicode } from 'genaicode';
|
|
407
|
+
import { openai } from 'genaicode/providers';
|
|
408
|
+
|
|
409
|
+
const ai = genaicode(openai({ model: 'your-model-name' }));
|
|
410
|
+
const answer = await ai('Explain why the sky is blue in two sentences.').text();
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
The client is callable on purpose. Configuration is ordinary method chaining—system
|
|
414
|
+
instructions, temperature, token limits, and more—without a separate options object or
|
|
415
|
+
framework setup:
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
const result = await ai('Create a release note from these commits')
|
|
419
|
+
.system('You are a concise technical writer.')
|
|
420
|
+
.temperature(0.2)
|
|
421
|
+
.maxOutputTokens(500)
|
|
422
|
+
.text();
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Builders are immutable, so a configured base request can be safely reused:
|
|
426
|
+
|
|
427
|
+
```ts
|
|
428
|
+
const releaseNote = ai('Create a release note from these commits')
|
|
429
|
+
.system('You are a concise technical writer.')
|
|
430
|
+
.temperature(0.2);
|
|
431
|
+
|
|
432
|
+
const short = await releaseNote.maxOutputTokens(200).text();
|
|
433
|
+
const long = await releaseNote.maxOutputTokens(800).text();
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Why this vs a raw SDK
|
|
437
|
+
|
|
438
|
+
Provider SDKs are the right tool when you call one vendor and own every request shape
|
|
439
|
+
yourself. The cost shows up when the same backend needs a second provider, a test double,
|
|
440
|
+
or shared policy (timeouts, JSON parsing, rate limits, fallback) without copying glue.
|
|
441
|
+
|
|
442
|
+
GenAIcode is that thin shared layer:
|
|
443
|
+
|
|
444
|
+
- One portable prompt/tool IR (`PromptItem`) instead of OpenAI messages vs Anthropic
|
|
445
|
+
blocks vs Gemini contents.
|
|
446
|
+
- One request API (`.text()`, `.json()`, `.stream()`, chains) over those adapters.
|
|
447
|
+
- A tiny `ModelProvider` seam so tests and custom gateways do not mock vendor HTTP.
|
|
448
|
+
- Opt-in middleware and retry helpers—no hidden tool runners, no silent retries, no
|
|
449
|
+
agent loop.
|
|
450
|
+
|
|
451
|
+
If you are happy importing one SDK and never swapping models or providers, stay on the
|
|
452
|
+
SDK. If you want the call site to look the same while the edge stays replaceable, use
|
|
453
|
+
GenAIcode.
|
|
454
|
+
|
|
455
|
+
### Chaining prompts
|
|
435
456
|
|
|
436
457
|
A chain remembers successful user and assistant turns. Each new prompt sees the complete
|
|
437
458
|
history, so multi-step work stays in ordinary application code:
|
|
@@ -449,7 +470,7 @@ const answer3 = await chain.text('Prompt 3: summarize the final contract.');
|
|
|
449
470
|
This is `prompt1 → response1 → prompt2 → response2 → prompt3 → response3`. The history
|
|
450
471
|
is available as portable `PromptItem[]` through `chain.history()`.
|
|
451
472
|
|
|
452
|
-
|
|
473
|
+
### Using a chain in a loop
|
|
453
474
|
|
|
454
475
|
A chain is ordinary application state, so normal control flow works:
|
|
455
476
|
|
|
@@ -492,7 +513,7 @@ for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
|
492
513
|
|
|
493
514
|
The application owns validation, attempt limits, and failure policy.
|
|
494
515
|
|
|
495
|
-
|
|
516
|
+
### Schema adapters
|
|
496
517
|
|
|
497
518
|
`json(...)` and `parseJsonResult(...)` accept either a parser function or a schema adapter
|
|
498
519
|
with a `parse(value)` method. This keeps schema validation library-agnostic:
|
|
@@ -512,7 +533,7 @@ Calling `.json()` also sets `responseFormat: { type: 'json' }` on the request wh
|
|
|
512
533
|
not already chosen a format, so providers that support JSON mode (OpenAI, Gemini/Vertex)
|
|
513
534
|
are asked for JSON rather than free text.
|
|
514
535
|
|
|
515
|
-
|
|
536
|
+
### Response format and thinking
|
|
516
537
|
|
|
517
538
|
Portable request fields cover the two knobs backends usually poke through provider-specific
|
|
518
539
|
config:
|
|
@@ -543,7 +564,7 @@ Providers map what they support and ignore the rest. `ProviderCapabilities.jsonR
|
|
|
543
564
|
and `ProviderCapabilities.thinking` advertise support. Vendor-specific escapes such as
|
|
544
565
|
Vertex `generationConfig` remain available for anything not covered here.
|
|
545
566
|
|
|
546
|
-
|
|
567
|
+
### PromptItem: the portable prompt IR
|
|
547
568
|
|
|
548
569
|
`PromptItem` is GenAIcode's provider-neutral intermediate representation:
|
|
549
570
|
|
|
@@ -576,7 +597,7 @@ const supportTicket = (ticket: Ticket) =>
|
|
|
576
597
|
await ai(supportTicket(ticket)).text();
|
|
577
598
|
```
|
|
578
599
|
|
|
579
|
-
|
|
600
|
+
### Tools
|
|
580
601
|
|
|
581
602
|
```ts
|
|
582
603
|
const calls = await ai('What is the weather in Warsaw?')
|
|
@@ -598,7 +619,7 @@ const calls = await ai('What is the weather in Warsaw?')
|
|
|
598
619
|
GenAIcode normalizes tool calls but deliberately does not execute them. The application
|
|
599
620
|
owns permissions, retries, and side effects.
|
|
600
621
|
|
|
601
|
-
|
|
622
|
+
### Streaming
|
|
602
623
|
|
|
603
624
|
Providers that support native streaming expose a provider-neutral `StreamEvent` IR.
|
|
604
625
|
Request builders and chains offer `.stream()` and `.streamText()`. If a provider has no
|
|
@@ -618,7 +639,7 @@ ai.provider.capabilities;
|
|
|
618
639
|
// { streaming: true, tools: true, images: 'input', systemPrompt: true }
|
|
619
640
|
```
|
|
620
641
|
|
|
621
|
-
|
|
642
|
+
### Middleware
|
|
622
643
|
|
|
623
644
|
Hook-style plugins remain the extension point. Built-in helpers cover common backend
|
|
624
645
|
needs without restoring a global registry:
|
|
@@ -637,7 +658,7 @@ const ai = genaicode(openai({ model: 'your-model-name' }), {
|
|
|
637
658
|
});
|
|
638
659
|
```
|
|
639
660
|
|
|
640
|
-
|
|
661
|
+
### Retries
|
|
641
662
|
|
|
642
663
|
Retries stay in application code. Use `classifyError`, `isRetryable`, and `withRetry`
|
|
643
664
|
when you want shared classification without hidden policy:
|
|
@@ -654,7 +675,7 @@ const text = await withRetry(() => ai('Summarize the deploy notes.').text(), {
|
|
|
654
675
|
See [retry guidance](docs/retry.md), [semver policy](docs/semver.md), and the
|
|
655
676
|
[provider package evaluation](docs/provider-packages.md).
|
|
656
677
|
|
|
657
|
-
|
|
678
|
+
### Providers
|
|
658
679
|
|
|
659
680
|
Models are provided in the adapter, through `.model(...)`, or with environment variables:
|
|
660
681
|
|
|
@@ -718,7 +739,7 @@ const provider: ModelProvider = {
|
|
|
718
739
|
All Anthropic, Google, and OpenAI conversion functions are public from
|
|
719
740
|
`genaicode/providers`, so gateways and tests can reuse them without instantiating clients.
|
|
720
741
|
|
|
721
|
-
|
|
742
|
+
### Provider E2E tests
|
|
722
743
|
|
|
723
744
|
Run real-provider E2E tests locally with:
|
|
724
745
|
|
|
@@ -739,7 +760,7 @@ Beyond the smoke call, E2E also covers portable `responseFormat: { type: 'json'
|
|
|
739
760
|
CI/CD is configured in `.github/workflows/provider-e2e.yaml`. Each provider runs in its own
|
|
740
761
|
job and only starts when both required secrets are configured in GitHub Actions.
|
|
741
762
|
|
|
742
|
-
|
|
763
|
+
### Plugins and hooks
|
|
743
764
|
|
|
744
765
|
A provider plugin no longer needs registration in global configuration. It exports the
|
|
745
766
|
same small `ModelProvider` contract as a built-in adapter:
|
|
@@ -787,7 +808,7 @@ Plugins run in registration order, and each plugin may call `next()` once. This
|
|
|
787
808
|
extension mechanism compatible with npm packages and ordinary imports without restoring
|
|
788
809
|
the 1.x runtime TypeScript loader or process-global plugin registry.
|
|
789
810
|
|
|
790
|
-
Framework-shaped examples live under `examples/` (`http-handler`, `queue-worker`,
|
|
811
|
+
Framework-shaped examples live under [`docs/examples/`](docs/examples/) (`http-handler`, `queue-worker`,
|
|
791
812
|
`cron-job`).
|
|
792
813
|
|
|
793
814
|
## Design boundaries
|
|
@@ -53,6 +53,9 @@
|
|
|
53
53
|
|
|
54
54
|
### Changed
|
|
55
55
|
|
|
56
|
+
- README and the package description lead with the coding agents: a 20-second demo, the
|
|
57
|
+
`npx genaicode run --verify` one-liner, then `genaicode/agents`. The LLM layer moved below
|
|
58
|
+
them as "Also: a thin LLM layer", and the 1.x note to the end.
|
|
56
59
|
- `defaultAppAgents`: Claude cannot start subagents (`Task`, `Agent`) in either mode; one can
|
|
57
60
|
outlive the turn, so its answer never reaches the user.
|
|
58
61
|
|
|
@@ -265,7 +268,7 @@
|
|
|
265
268
|
### Notes
|
|
266
269
|
|
|
267
270
|
- Releases are published from GitHub Actions when a version tag is pushed. See
|
|
268
|
-
[docs/releasing.md](
|
|
271
|
+
[docs/releasing.md](releasing.md).
|
|
269
272
|
|
|
270
273
|
## 2.4.0 — 2026-09-24
|
|
271
274
|
|
|
@@ -275,7 +278,7 @@
|
|
|
275
278
|
`CodingAgent` interface. Drivers `claude()`, `codex()`, `muse()`; agent-neutral
|
|
276
279
|
`AgentEvent` stream and `AgentResult`; abort, timeout and process-group kill;
|
|
277
280
|
`detectAgents` / `findExecutable`; `cliAgent()` for custom drivers. See
|
|
278
|
-
[docs/agents.md](
|
|
281
|
+
[docs/agents.md](agents.md).
|
|
279
282
|
- Live agent sessions over JSON-RPC: `codexLive()` (`codex app-server`) and `museLive()`
|
|
280
283
|
(`muse serve`) with `AgentRun.steer()` and `AgentTask.onApproval`; `liveAgent()` and
|
|
281
284
|
`RpcPeer` for custom live drivers; `approval-resolved` event.
|
|
@@ -316,7 +319,7 @@
|
|
|
316
319
|
|
|
317
320
|
Publishes the Phase 3–4 work already on `master`. npm `2.0.0` shipped the 2.0
|
|
318
321
|
kernel and provider adapters only; this minor adds the remaining public surface
|
|
319
|
-
documented in the README and [semver policy](
|
|
322
|
+
documented in the README and [semver policy](semver.md).
|
|
320
323
|
|
|
321
324
|
### Added
|
|
322
325
|
|
|
@@ -324,12 +327,12 @@ documented in the README and [semver policy](docs/semver.md).
|
|
|
324
327
|
native streams for OpenAI / Anthropic / Google with generate→stream fallback)
|
|
325
328
|
- Built-in middleware: `timingPlugin`, `rateLimitPlugin`, `cachePlugin`,
|
|
326
329
|
`fallbackPlugin`, `fallbackProvider`
|
|
327
|
-
- Retry helpers: `classifyError`, `isRetryable`, `withRetry` (+ [docs/retry.md](
|
|
330
|
+
- Retry helpers: `classifyError`, `isRetryable`, `withRetry` (+ [docs/retry.md](retry.md))
|
|
328
331
|
- `ProviderCapabilities` on `ModelProvider`
|
|
329
332
|
- Compatibility fixtures for multimodal and tool-call round trips
|
|
330
333
|
- Framework examples under `examples/` (HTTP handler, queue worker, cron job)
|
|
331
|
-
- Written guidance: [docs/semver.md](
|
|
332
|
-
[docs/provider-packages.md](
|
|
334
|
+
- Written guidance: [docs/semver.md](semver.md),
|
|
335
|
+
[docs/provider-packages.md](provider-packages.md)
|
|
333
336
|
|
|
334
337
|
### Notes
|
|
335
338
|
|
package/docs/pivot.md
CHANGED
|
@@ -91,7 +91,7 @@ and in the 1.x npm line.
|
|
|
91
91
|
`fallbackProvider`).
|
|
92
92
|
- First-class schema adapters without requiring a specific validation library — implemented.
|
|
93
93
|
- Small framework examples for HTTP handlers, queues, and cron jobs — implemented
|
|
94
|
-
under `examples/`.
|
|
94
|
+
under `docs/examples/`.
|
|
95
95
|
- Re-evaluate separate provider packages if dependency size becomes material —
|
|
96
96
|
evaluated; keep bundled for 2.x (see [provider-packages.md](./provider-packages.md)).
|
|
97
97
|
|
|
@@ -113,7 +113,7 @@ and in the 1.x npm line.
|
|
|
113
113
|
helpers, fixtures, examples, and related docs).
|
|
114
114
|
- `2.2.0` adds portable `responseFormat` and `thinking` request fields (so apps
|
|
115
115
|
need fewer provider-specific `generationConfig` casts). See
|
|
116
|
-
[CHANGELOG.md](
|
|
116
|
+
[CHANGELOG.md](CHANGELOG.md).
|
|
117
117
|
|
|
118
118
|
## Success measures
|
|
119
119
|
|
package/docs/semver.md
CHANGED
|
@@ -52,7 +52,7 @@ Require a new major version:
|
|
|
52
52
|
- Timing of stream events beyond the `StreamEvent` discriminant
|
|
53
53
|
- Dependency versions of underlying provider SDKs within a major (may bump in
|
|
54
54
|
minors when needed for security or API drift)
|
|
55
|
-
- Example apps under `examples/` (illustrative only)
|
|
55
|
+
- Example apps under `docs/examples/` (illustrative only)
|
|
56
56
|
|
|
57
57
|
## Plugin and provider authors
|
|
58
58
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genaicode",
|
|
3
|
-
"version": "2.17.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.17.1",
|
|
4
|
+
"description": "Drive the coding-agent CLIs you already have (Claude Code, Codex, Copilot, Cursor, Gemini, opencode...) behind one API and one CLI, plus a thin provider-neutral LLM layer.",
|
|
5
5
|
"author": "Grzegorz Tańczyk",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"files": [
|
|
34
34
|
"dist",
|
|
35
35
|
"docs",
|
|
36
|
-
"
|
|
36
|
+
"!docs/examples",
|
|
37
|
+
"!docs/media",
|
|
37
38
|
"README.md",
|
|
38
39
|
"LICENSE"
|
|
39
40
|
],
|
|
@@ -70,16 +71,17 @@
|
|
|
70
71
|
},
|
|
71
72
|
"scripts": {
|
|
72
73
|
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
73
|
-
"build": "npm run clean && tsc -p tsconfig.build.json && node scripts/build-ui.mjs",
|
|
74
|
+
"build": "npm run clean && tsc -p scripts/tsconfig.build.json && node scripts/build-ui.mjs",
|
|
74
75
|
"lint": "eslint . --ext js,ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
75
|
-
"test": "vitest --config vitest.
|
|
76
|
-
"test:e2e": "vitest --config vitest.
|
|
77
|
-
"test:browser": "vitest --config vitest.
|
|
78
|
-
"test:watch": "vitest --config vitest.
|
|
76
|
+
"test": "vitest --config scripts/vitest.config.ts --run --project unit",
|
|
77
|
+
"test:e2e": "vitest --config scripts/vitest.config.ts --run --project e2e",
|
|
78
|
+
"test:browser": "vitest --config scripts/vitest.config.ts --run --project browser",
|
|
79
|
+
"test:watch": "vitest --config scripts/vitest.config.ts --project unit",
|
|
79
80
|
"type-check": "tsc --noEmit",
|
|
80
81
|
"check": "npm run type-check && npm run lint && npm test && npm run build",
|
|
81
82
|
"prepublishOnly": "npm run check",
|
|
82
|
-
"prepare": "npm run build"
|
|
83
|
+
"prepare": "npm run build",
|
|
84
|
+
"format": "prettier --write ."
|
|
83
85
|
},
|
|
84
86
|
"dependencies": {
|
|
85
87
|
"@anthropic-ai/sdk": "^0.74.0",
|
|
@@ -96,10 +98,8 @@
|
|
|
96
98
|
"eslint": "^8.54.0",
|
|
97
99
|
"eslint-config-prettier": "^9.0.0",
|
|
98
100
|
"happy-dom": "^20.14.5",
|
|
99
|
-
"husky": "^9.1.1",
|
|
100
101
|
"ink": "^6.8.0",
|
|
101
102
|
"ink-testing-library": "^4.0.0",
|
|
102
|
-
"lint-staged": "^16.4.0",
|
|
103
103
|
"playwright": "^1.56.1",
|
|
104
104
|
"prettier": "^3.1.0",
|
|
105
105
|
"react": "^19.3.0",
|
|
@@ -108,7 +108,29 @@
|
|
|
108
108
|
"vite": "^6.4.3",
|
|
109
109
|
"vitest": "^4.1.11"
|
|
110
110
|
},
|
|
111
|
-
"
|
|
112
|
-
"
|
|
111
|
+
"prettier": {
|
|
112
|
+
"trailingComma": "all",
|
|
113
|
+
"tabWidth": 2,
|
|
114
|
+
"semi": true,
|
|
115
|
+
"singleQuote": true,
|
|
116
|
+
"printWidth": 120,
|
|
117
|
+
"bracketSpacing": true,
|
|
118
|
+
"endOfLine": "lf"
|
|
119
|
+
},
|
|
120
|
+
"eslintConfig": {
|
|
121
|
+
"root": true,
|
|
122
|
+
"env": {
|
|
123
|
+
"node": true
|
|
124
|
+
},
|
|
125
|
+
"extends": [
|
|
126
|
+
"eslint:recommended",
|
|
127
|
+
"plugin:@typescript-eslint/recommended"
|
|
128
|
+
],
|
|
129
|
+
"ignorePatterns": [
|
|
130
|
+
"docs/examples/**/*",
|
|
131
|
+
"dist",
|
|
132
|
+
"coverage"
|
|
133
|
+
],
|
|
134
|
+
"parser": "@typescript-eslint/parser"
|
|
113
135
|
}
|
|
114
136
|
}
|