@kodax-ai/kodax 0.7.70 → 0.7.71

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +73 -23
  3. package/README_CN.md +53 -11
  4. package/config-templates/integrations/a2a.example.jsonc +62 -18
  5. package/dist/chunks/{agent-T72XYPW4.js → agent-X2EWQADL.js} +1 -1
  6. package/dist/chunks/argument-completer-BLNXDO2F.js +2 -0
  7. package/dist/chunks/chunk-23X6REO4.js +46 -0
  8. package/dist/chunks/{chunk-Y4WOTWUC.js → chunk-44QXPEEE.js} +1 -1
  9. package/dist/chunks/chunk-4DY756KL.js +70 -0
  10. package/dist/chunks/{chunk-AWMTNUDS.js → chunk-52JSZ77P.js} +1 -1
  11. package/dist/chunks/{chunk-I4TPQEJN.js → chunk-64NQBOSN.js} +1 -1
  12. package/dist/chunks/{chunk-F4NOOBRZ.js → chunk-A2TFSV5M.js} +1 -1
  13. package/dist/chunks/{chunk-4P4L3WEK.js → chunk-A574DBTV.js} +2 -2
  14. package/dist/chunks/{chunk-K7RYV2SE.js → chunk-F7KGYHJ3.js} +2 -2
  15. package/dist/chunks/{chunk-P2UKNYYS.js → chunk-GVTM4Z6O.js} +66 -22
  16. package/dist/chunks/{chunk-GOQRVDFP.js → chunk-PHH4TRGF.js} +2 -2
  17. package/dist/chunks/{chunk-AQGNRBEJ.js → chunk-PVUXONQB.js} +140 -140
  18. package/dist/chunks/{chunk-WW2O2DEP.js → chunk-SX2WFHIS.js} +1 -1
  19. package/dist/chunks/{chunk-RY5OLVQV.js → chunk-T7LYK53M.js} +2 -2
  20. package/dist/chunks/{chunk-F7C7J6IM.js → chunk-VRSVNU2Y.js} +3 -3
  21. package/dist/chunks/chunk-Y5XKAN7C.js +755 -0
  22. package/dist/chunks/{chunk-XNQ2O7NI.js → chunk-Z535BARK.js} +4 -4
  23. package/dist/chunks/chunk-ZJIMT5I3.js +78 -0
  24. package/dist/chunks/compaction-config-5KKKXYFT.js +2 -0
  25. package/dist/chunks/{construction-bootstrap-BPRXZK4A.js → construction-bootstrap-OXDDDW6O.js} +1 -1
  26. package/dist/chunks/{dist-DRBKYVHF.js → dist-GOUP4YVE.js} +1 -1
  27. package/dist/chunks/{dist-UENHF5OS.js → dist-IXJRJ27U.js} +1 -1
  28. package/dist/chunks/host-VRKDAN26.js +2 -0
  29. package/dist/chunks/run-manager-Z3W6MDO7.js +2 -0
  30. package/dist/chunks/{utils-TMMH6PKT.js → utils-CFOXDCB5.js} +1 -1
  31. package/dist/index.d.ts +15 -15
  32. package/dist/index.js +1 -1
  33. package/dist/kodax_cli.js +1168 -1114
  34. package/dist/provider-capabilities.json +101 -57
  35. package/dist/runtime-worker.js +1073 -1019
  36. package/dist/sdk-a2a.d.ts +185 -20
  37. package/dist/sdk-a2a.js +8 -8
  38. package/dist/sdk-agent.d.ts +47 -18
  39. package/dist/sdk-agent.js +1 -1
  40. package/dist/sdk-coding.d.ts +18 -18
  41. package/dist/sdk-coding.js +1 -1
  42. package/dist/sdk-experimental-memory.d.ts +1 -1
  43. package/dist/sdk-experimental-memory.js +1 -1
  44. package/dist/sdk-llm.d.ts +6 -6
  45. package/dist/sdk-llm.js +1 -1
  46. package/dist/sdk-mcp.js +1 -1
  47. package/dist/sdk-media.d.ts +1 -1
  48. package/dist/sdk-media.js +1 -1
  49. package/dist/sdk-repl.d.ts +16 -16
  50. package/dist/sdk-repl.js +1 -1
  51. package/dist/sdk-runtime.d.ts +22 -12
  52. package/dist/sdk-runtime.js +1 -1
  53. package/dist/sdk-session.d.ts +6 -6
  54. package/dist/sdk-session.js +1 -1
  55. package/dist/sdk-skills.js +1 -1
  56. package/dist/semantic-worker.js +9 -9
  57. package/dist/types-chunks/{base.d-CYjtB68X.d.ts → base.d-Cz_rwpOi.d.ts} +2 -1
  58. package/dist/types-chunks/{bash-prefix-extractor.d-h9AwGqmO.d.ts → bash-prefix-extractor.d-YoiZl5yt.d.ts} +3 -3
  59. package/dist/types-chunks/{capability-learning.d-WtsyRv3O.d.ts → capability-learning.d-_lR0J4iR.d.ts} +1 -1
  60. package/dist/types-chunks/{capsule.d-xJvfh4YR.d.ts → capsule.d-CK5Pfz1k.d.ts} +3 -3
  61. package/dist/types-chunks/{commands.d-DxiVanpI.d.ts → commands.d-D6g2jq8V.d.ts} +4 -4
  62. package/dist/types-chunks/{guardrail.d-R7AiGfrI.d.ts → guardrail.d-DdeDWnVu.d.ts} +3 -3
  63. package/dist/types-chunks/{guardrail.d-6ZDbNbHO.d.ts → guardrail.d-DilYC1dh.d.ts} +1 -1
  64. package/dist/types-chunks/{public-api.d-BqFKI5fK.d.ts → public-api.d-BvCp5VkW.d.ts} +3 -3
  65. package/dist/types-chunks/{resolver.d-CIVoGc97.d.ts → resolver.d-ssgNSlrh.d.ts} +2 -2
  66. package/dist/types-chunks/{run-manager.d-BaXtkryp.d.ts → run-manager.d-DxU3SSGR.d.ts} +1 -1
  67. package/dist/types-chunks/{sdk-session-tcoxrMHQ.d.ts → sdk-session-wGpa7X_U.d.ts} +4 -4
  68. package/dist/types-chunks/{types.d-CJR7t6iW.d.ts → types.d-CEZZSY9s.d.ts} +2 -2
  69. package/dist/types-chunks/{types.d-BtC4yLYO.d.ts → types.d-CRCaLt_s.d.ts} +55 -7
  70. package/dist/types-chunks/{types.d-TTvpAGWf.d.ts → types.d-Cqaw71Ax.d.ts} +4 -2
  71. package/dist/types-chunks/{types.d-DZaYznxo.d.ts → types.d-CzsLFqmf.d.ts} +4 -4
  72. package/dist/types-chunks/{utils.d-B4zc7oot.d.ts → utils.d-Cb6vdvFM.d.ts} +5 -5
  73. package/docs/SDK_EMBEDDER_GUIDE.md +250 -41
  74. package/package.json +4 -1
  75. package/dist/chunks/argument-completer-QXJC36UP.js +0 -2
  76. package/dist/chunks/chunk-34L74PEG.js +0 -60
  77. package/dist/chunks/chunk-7PV577LP.js +0 -755
  78. package/dist/chunks/chunk-NGHQIGVW.js +0 -46
  79. package/dist/chunks/chunk-UJEMSPM5.js +0 -78
  80. package/dist/chunks/compaction-config-TC6C2PJ6.js +0 -2
  81. package/dist/chunks/host-XUVAICP7.js +0 -2
  82. package/dist/chunks/run-manager-T7ALQZNT.js +0 -2
@@ -1296,7 +1296,7 @@ import {
1296
1296
  ```ts
1297
1297
  interface KodaXModelCapabilities {
1298
1298
  provider: string; // 'anthropic' | 'kimi' | 'ark-coding' | <custom-name>
1299
- model: string; // model id (e.g. 'claude-sonnet-4-6', 'kimi-k2.6')
1299
+ model: string; // model id (e.g. 'claude-sonnet-4-6', 'kimi-k2.7-code')
1300
1300
  displayName: string; // human label — falls back to model id
1301
1301
  supportsThinking: boolean; // native reasoning is available?
1302
1302
  reasoningCapability: 'native-budget' | 'native-effort' | 'native-toggle' | 'prompt-only' | 'none' | 'unknown'; // legacy mechanism label
@@ -1328,8 +1328,8 @@ for (const caps of listAllModelCapabilities()) {
1328
1328
  ```ts
1329
1329
  import { resolveModelCapabilities } from '@kodax-ai/kodax/llm';
1330
1330
 
1331
- const caps = resolveModelCapabilities('kimi', 'kimi-k2.6');
1332
- // => { contextWindow: 256_000, supportsThinking: true, reasoningProfile: { defaultEffort: 'high', ... }, ... }
1331
+ const caps = resolveModelCapabilities('kimi', 'kimi-k2.7-code');
1332
+ // => { contextWindow: 262_144, supportsThinking: true, reasoningProfile: { defaultEffort: 'high', ... }, ... }
1333
1333
  ```
1334
1334
 
1335
1335
  For picker/status UIs, use `reasoningProfile.supportedEfforts` and
@@ -1466,11 +1466,11 @@ and loaded into the in-memory `KODAX_PROVIDER_SNAPSHOTS` export. When upstream
1466
1466
  providers publish a new model or change a context-window cap, the JSON file is
1467
1467
  the patch site — the new value flows to runtime (via `buildProviderConfig`) AND
1468
1468
  to SDK consumers (via the getters) in a single edit. The current snapshot is
1469
- dated 2026-06-14 and includes the GPT-5.4, Kimi K2.7 Code, GLM-5.2, MiniMax
1469
+ dated 2026-07-16 and includes the GPT-5.4, Kimi K2.7 Code / HighSpeed, GLM-5.2, MiniMax
1470
1470
  M3/M2.7, DeepSeek V4, and Doubao Seed 2.0 route refreshes where supported. The
1471
1471
  test suite at
1472
1472
  [`packages/llm/src/providers/model-capabilities.test.ts`](../packages/llm/src/providers/model-capabilities.test.ts)
1473
- locks in specific values (e.g. kimi-k2.6 at 256K, deepseek-v4-pro at 1M)
1473
+ locks in specific values (e.g. the public Kimi lineup at 262,144 tokens, deepseek-v4-pro at 1M)
1474
1474
  so accidental drift is caught at PR time.
1475
1475
 
1476
1476
  The probe scripts that surveyed upstream APIs live at
@@ -1954,7 +1954,7 @@ Cli-bridge providers (`gemini-cli`, `codex-cli`) return their CLI binary's known
1954
1954
 
1955
1955
  ### Reference
1956
1956
 
1957
- - Source: `packages/llm/src/providers/verify-credential.ts` (orchestrator + classifier) + `verify-credential.test.ts` (19 unit tests) + `verify-credential-integration.test.ts` (10 real-key tests, gated on `KODAX_INTEGRATION_TEST=1`).
1957
+ - Source: `packages/llm/src/providers/verify-credential.ts` (orchestrator + classifier) + `verify-credential.test.ts` (27 unit tests) + `verify-credential-integration.test.ts` (12 gated real-key/fake-key tests, enabled by `KODAX_INTEGRATION_TEST=1`).
1958
1958
  - Data: `packages/llm/src/providers/provider-capabilities.json` `verifyStrategy` field per provider.
1959
1959
  - Design notes + probe matrix: [docs/features/v0.7.45.md FEATURE_216](features/v0.7.45.md#feature_216-provider-credential-verification-api).
1960
1960
 
@@ -2348,7 +2348,7 @@ The important creation options are:
2348
2348
  | `worker.resourceLimits` | unset | Optional V8 heap/stack limits; requires `isolation: 'worker'`. |
2349
2349
  | `worker.shutdownTimeoutMs` | `2000` | Grace before the parent terminates the Runtime Worker. |
2350
2350
  | `requirements.hardDispose` | `false` | Rejects inline and daemon forms; prevents an accidental weaker ownership form. |
2351
- | `homeDir` | OS user home | Root for `.kodax` config/state and default sessions. Use a private value in tests. |
2351
+ | `homeDir` | unset | When omitted, use the exact resolved `KODAX_HOME`. When set, this is the base directory that owns `.kodax`, with the same meaning as CLI `daemon --home`; daemon state/config live under `<homeDir>/.kodax`. |
2352
2352
  | `profile` | `'default'` | Daemon uniqueness and runtime configuration namespace. |
2353
2353
  | `sessionsDir` | `<homeDir>/.kodax/sessions` | Explicit session storage override. |
2354
2354
  | `daemonStartupTimeoutMs` | `60000` | Total cold-start/concurrent-owner wait budget. |
@@ -2429,10 +2429,20 @@ no explicit `daemonEndpoint` or `daemonTransport` is supplied it starts or reuse
2429
2429
  the local profile daemon. `connectKodaXRuntime()` is attach-only unless
2430
2430
  `autoStart: true` is passed.
2431
2431
 
2432
- SDK auto-start allows `daemonStartupTimeoutMs` (default 60 seconds) and
2433
- `daemonConnectTimeoutMs`. The longer startup budget covers cold machines and
2434
- concurrent test/desktop startup without weakening PID, endpoint, token, or
2435
- runtime-identity validation.
2432
+ SDK auto-start allows `daemonStartupTimeoutMs` (default 60 seconds) and
2433
+ `daemonConnectTimeoutMs`. The longer startup budget covers cold machines and
2434
+ concurrent test/desktop startup without weakening PID, endpoint, token, or
2435
+ runtime-identity validation.
2436
+
2437
+ `homeDir` and `KODAX_HOME` deliberately name different levels. Runtime SDK and
2438
+ CLI daemon `--home` accept the **base directory that contains `.kodax`**;
2439
+ lower-level `KODAX_HOME` points at the **data directory itself** and need not be
2440
+ named `.kodax`. To share the default CLI daemon, omit `homeDir`; this honors the
2441
+ exact resolved `KODAX_HOME`. Passing `os.homedir()` explicitly instead selects
2442
+ `<os.homedir()>/.kodax`, regardless of an ambient custom `KODAX_HOME`. For an
2443
+ isolated embedder namespace, pass a private base directory and expect data at
2444
+ `<homeDir>/.kodax`. Passing `~/.kodax` as `homeDir` would instead select
2445
+ `~/.kodax/.kodax` and a different daemon namespace.
2436
2446
 
2437
2447
  ### Worker-hosted embedded usage
2438
2448
 
@@ -2575,7 +2585,7 @@ Every `KodaXRuntime` exposes the same service set in inline, Worker, and daemon
2575
2585
  | `artifacts` | Create/get/delete runtime artifact references for file/image/video inputs. |
2576
2586
  | `status` | Runtime snapshot with sessions, runs, permissions, workflows, and daemon counters. |
2577
2587
  | `diagnostics` | Latest context-budget and tool-exposure decisions for GUI/debug surfaces. |
2578
- | `admin.agentRegistrations` | List/upsert/remove redacted external-agent registrations. With no plane, list is empty and mutations fail clearly. |
2588
+ | `admin.agentRegistrations` | List/upsert, atomically set `enabled` while preserving the full registration, or remove redacted external-agent registrations. Owner/revision-conditional mutation prevents a stale manager from changing a same-ID replacement. With no plane, list is empty and mutations fail clearly. |
2579
2589
  | `agents` | Check `enabled`, list/describe policy-filtered dispatchable agents, and preflight a selected route. |
2580
2590
  | `agentTasks` | Start/list/get/wait/continue/cancel/reconcile durable external-agent tasks and read their ordered event stream. |
2581
2591
 
@@ -2915,7 +2925,7 @@ fail clearly. Set
2915
2925
 
2916
2926
  | Surface | Methods | Contract |
2917
2927
  |---|---|---|
2918
- | `runtime.admin.agentRegistrations` | `list`, `upsert`, `remove` | Durable owner configuration. List results expose `credentialConfigured`, never a credential value. With no plane, `list()` is empty and mutations fail clearly. |
2928
+ | `runtime.admin.agentRegistrations` | `list`, `upsert`, `setEnabled`, `remove` | Durable owner configuration. `setEnabled` preserves the complete captured executor registration while changing admission. Mutations accept both `expectedConfigurationRevision` and `expectedManagementOwner`; `setEnabled` can also atomically `claimOwner` on an unowned registration and rejects another owner. List results expose `managementOwner` and `credentialConfigured`, never a credential value. The same contract is carried across the daemon transport. With no plane, `list()` is empty and mutations fail clearly. |
2919
2929
  | `runtime.agents` | `enabled`, `listDispatchable`, `describe`, `preflight` | Applies health, capability, effect, concurrency, credential-presence, configuration-revision, and host-policy checks before dispatch. |
2920
2930
  | `runtime.agentTasks` | `start`, `list`, `get`, `events`, `wait`, `sendInput`, `cancel`, `reconcile` | Durable snapshots and append-only events for external tasks. The task keeps the immutable registration/executor binding captured at start. |
2921
2931
 
@@ -2926,12 +2936,34 @@ is valid only while the task reports `input-required` or `auth-required`.
2926
2936
  `reconcile()` asks the bound executor for authoritative remote state after an
2927
2937
  owner restart or uncertain failure.
2928
2938
 
2939
+ For external tasks, the built-in stores persist an internal full registration
2940
+ snapshot before the public task ledger. It is keyed by Agent ID and revision,
2941
+ is never returned by task or daemon APIs, and lets an admitted task keep using
2942
+ its original executor route after registration update/removal and Runtime
2943
+ restart. The internal form fixes `enabled: true` and omits management ownership
2944
+ and health diagnostics. The task's public route summary is validated against that internal
2945
+ snapshot before recovery. Terminal task state is durable before the last
2946
+ unreferenced snapshot is removed; startup cleans crash-window orphans.
2947
+
2948
+ Custom `AgentExecutorPlaneStore` implementations should implement
2949
+ `loadTaskRegistrationSnapshots()` and `saveTaskRegistrationSnapshots()` as a
2950
+ pair and give one Runtime exclusive write ownership of that store. Omitting
2951
+ both remains compatible, but restart recovery then succeeds only while the
2952
+ exact current registration still exists. Store only non-secret executor config
2953
+ or secret references in `executorConfig`/`credentialRef`; the broker resolves
2954
+ the current referenced credential just in time, so removing a registration is
2955
+ not equivalent to revoking that credential at its issuer.
2956
+
2929
2957
  The owner plane has a terminal close contract. Closing it rejects every pending
2930
2958
  `wait()` (including a wait without `timeoutMs`), disposes its executor instances,
2931
2959
  and makes subsequent registration, catalog, preflight, and task calls reject
2932
- with `Agent executor plane is closed.` Repeated `close()` calls are safe. SDK
2933
- hosts should stop accepting work before closing the owner and must not retain a
2934
- plane service as a reusable handle after Runtime shutdown.
2960
+ with `Agent executor plane is closed.` One overall deadline covers admitted
2961
+ work plus executor disposal: the default is 30 seconds, and direct
2962
+ `createAgentExecutorPlane()` hosts may supply a positive finite
2963
+ `closeTimeoutMs`. A timeout rejects visibly even though already-admitted cleanup
2964
+ may finish in the background. Repeated `close()` calls are safe. SDK hosts
2965
+ should stop accepting work before closing the owner and must not retain a plane
2966
+ service as a reusable handle after Runtime shutdown.
2935
2967
 
2936
2968
  Restricted Workflow scripts use the same route as direct SDK calls. Both
2937
2969
  `wf.spawnAgent()` and `wf.runAgent()` validate and forward
@@ -2948,8 +2980,18 @@ silently falling back to the native child backend.
2948
2980
  each artifact before it materializes in the host boundary.
2949
2981
  - External agents may declare workspace effect `none` or `proposal`; direct
2950
2982
  workspace mutation is intentionally not a valid external registration.
2951
- - Use `expectedConfigurationRevision` to prevent dispatching against a stale
2952
- endpoint/configuration seen by an earlier catalog read.
2983
+ - Use `expectedConfigurationRevision` for dispatch. For registration mutations,
2984
+ compare both it and `expectedManagementOwner` so a same-revision ownership
2985
+ change cannot be overwritten from an earlier catalog read. Config managers
2986
+ should set a stable `managementOwner`; they may atomically claim an unowned
2987
+ legacy registration while disabling it, but must not mutate a registration
2988
+ owned by another manager.
2989
+ - Treat `configurationRevision` as the stable identity of immutable execution
2990
+ content, not as a small counter. The same content may deterministically reuse
2991
+ the same revision across remove/re-add or Runtime restart, but different
2992
+ endpoint, protocol, executor/auth config, capabilities, effects, Skills,
2993
+ modalities, or resource limits must never reuse it. Built-in A2A
2994
+ configuration derives it from content.
2953
2995
  - A remote start followed by uncertain local persistence is recorded as
2954
2996
  `unknown` with its executor reference preserved; reconcile it rather than
2955
2997
  blindly starting a duplicate. Stable idempotency keys protect retries.
@@ -3208,11 +3250,23 @@ time/body/redirects, and strips authorization on a cross-origin redirect. A
3208
3250
  custom `fetch` option is a trusted transport override: the embedder then owns
3209
3251
  equivalent DNS-to-connection binding in that transport or proxy.
3210
3252
 
3211
- Starting in v0.7.70, the interface selected from the Agent Card must remain on
3212
- the Card's trusted origin. A configured `credentialRef` is used only when the
3213
- Card advertises the A2A 1.0 Bearer security scheme; discovery fails closed
3214
- rather than sending a secret to an unadvertised or differently secured
3215
- endpoint.
3253
+ The selected interface must remain on the Card's trusted origin. KodaX parses
3254
+ typed Card-level and Skill-level security declarations: requirement objects are
3255
+ alternatives (OR), every scheme inside one object is conjunctive (AND), and an
3256
+ empty requirement is anonymous. A configured credential is used only when one
3257
+ complete requirement is satisfiable; protected Skills that the configured
3258
+ profile cannot satisfy are not advertised to the Runtime catalog.
3259
+
3260
+ The built-in profiles are HTTP Bearer and OAuth 2.0 Client Credentials. The
3261
+ OAuth profile pins the Card scheme, issuer, exact token endpoint, client ID,
3262
+ secret reference, scopes, optional RFC 8707 resource, and client authentication
3263
+ method. The external Authorization Server—not the Agent and not KodaX—issues
3264
+ the access token. KodaX resolves the client secret only for refresh, keeps an
3265
+ expiring token in process memory, coalesces refreshes, and retries one RPC once
3266
+ with a fresh token after `401`. Card, Agent RPC, and token endpoints remain
3267
+ separate safe-fetch trust boundaries, so a remote Agent cannot redirect a task
3268
+ payload to the token origin. API key, Basic, interactive OAuth, OIDC, mTLS, and
3269
+ multi-scheme AND requirements fail explicitly in the built-in client.
3216
3270
 
3217
3271
  ```ts
3218
3272
  import {
@@ -3223,7 +3277,8 @@ import { createKodaXRuntime } from '@kodax-ai/kodax/runtime';
3223
3277
 
3224
3278
  const client = {
3225
3279
  networkPolicy: {
3226
- allowedOrigins: ['https://reviewer.example'],
3280
+ // Card/RPC and OAuth token endpoints are separate trust boundaries.
3281
+ allowedOrigins: ['https://reviewer.example', 'https://identity.example'],
3227
3282
  allowPrivateAddresses: false,
3228
3283
  requestTimeoutMs: 10_000,
3229
3284
  maxResponseBytes: 1_048_576,
@@ -3246,8 +3301,13 @@ const runtime = await createKodaXRuntime({
3246
3301
  factories: [createA2AAgentExecutorFactory(client)],
3247
3302
  credentialBroker: {
3248
3303
  async withCredential(ref, use) {
3249
- if (ref !== 'a2a/reviewer') throw new Error('Unknown credential reference.');
3250
- return use(process.env.A2A_REVIEWER_TOKEN ?? '');
3304
+ const value = ref === 'a2a/reviewer'
3305
+ ? process.env.A2A_REVIEWER_TOKEN
3306
+ : ref === 'a2a/reviewer-client-secret'
3307
+ ? process.env.A2A_REVIEWER_CLIENT_SECRET
3308
+ : undefined;
3309
+ if (!value) throw new Error(`Missing credential for reference: ${ref}.`);
3310
+ return use(value);
3251
3311
  },
3252
3312
  },
3253
3313
  policy: ({ registration }) => ({ allowed: registration.effects.remote === 'read' }),
@@ -3266,6 +3326,30 @@ const started = await runtime.agentTasks.start({
3266
3326
  const terminal = await runtime.agentTasks.wait(started.taskId, 60_000);
3267
3327
  ```
3268
3328
 
3329
+ For OAuth, replace the legacy `credentialRef` input with the structured form;
3330
+ the same F258 `credentialBroker` must resolve `clientSecretRef`. The shared
3331
+ network policy must admit both origins, while each Card, RPC, and token request
3332
+ is still narrowed to its own exact origin:
3333
+
3334
+ ```ts
3335
+ const discovered = await discoverA2ARegistration({
3336
+ agentId: 'external:a2a-reviewer',
3337
+ agentCardUrl: 'https://reviewer.example/.well-known/agent-card.json',
3338
+ authentication: {
3339
+ type: 'oauth2-client-credentials',
3340
+ scheme: 'enterprise-oauth',
3341
+ issuer: 'https://identity.example/',
3342
+ tokenUrl: 'https://identity.example/oauth/token',
3343
+ clientId: 'kodax-reviewer',
3344
+ clientSecretRef: 'a2a/reviewer-client-secret',
3345
+ scopes: ['a2a.invoke'],
3346
+ resource: 'https://reviewer.example/',
3347
+ clientAuthentication: 'client-secret-basic',
3348
+ },
3349
+ effects: { remote: 'read' },
3350
+ }, client);
3351
+ ```
3352
+
3269
3353
  The executor supports durable task start/get, input continuation, cancel,
3270
3354
  reconcile, SSE events, and polling fallback. An ambiguous start is not retried
3271
3355
  automatically. A `credentialRef` is resolved just in time by the F258 broker;
@@ -3289,6 +3373,24 @@ kodax a2a test reviewer
3289
3373
  kodax a2a call reviewer "Review this document"
3290
3374
  ```
3291
3375
 
3376
+ The no-code OAuth path stores only the environment-variable name for the client
3377
+ secret. It can be staged disabled and hot-activated later:
3378
+
3379
+ ```bash
3380
+ export A2A_REVIEWER_CLIENT_SECRET='provisioned-out-of-band'
3381
+ # PowerShell: $env:A2A_REVIEWER_CLIENT_SECRET='provisioned-out-of-band'
3382
+ # PowerShell: use one line or replace each trailing \ with a backtick.
3383
+ kodax a2a add reviewer https://reviewer.example/.well-known/agent-card.json \
3384
+ --disabled --effect read --oauth-scheme enterprise-oauth \
3385
+ --oauth-issuer https://identity.example/ \
3386
+ --oauth-token-url https://identity.example/oauth/token \
3387
+ --oauth-client-id kodax-reviewer \
3388
+ --oauth-client-secret-env A2A_REVIEWER_CLIENT_SECRET \
3389
+ --oauth-scope a2a.invoke --oauth-resource https://reviewer.example/
3390
+ kodax a2a enable reviewer
3391
+ kodax a2a disable reviewer
3392
+ ```
3393
+
3292
3394
  Embedded CLI Runtimes and the user-owned daemon automatically reconcile these
3293
3395
  entries as `external:<name>`. Discovery/update failure retains that entry's
3294
3396
  last-known-good registration; another entry can still update. The environment
@@ -3296,15 +3398,107 @@ broker resolves `credentialEnv` only at call time. Automatic Runtime
3296
3398
  registration accepts public HTTPS and exact loopback targets; explicit private
3297
3399
  network access remains an operator action on the direct CLI/SDK path.
3298
3400
 
3401
+ `enabled` is desired state in `a2a.json`, not a fabricated cross-process live
3402
+ flag. `a2a list` reports configured entries and that desired state. The owning
3403
+ Runtime's `admin.agentRegistrations.list()` is authoritative for applied
3404
+ registrations. Automatic reconciliation handles disables/removals first,
3405
+ skips unchanged peers, performs no Card or token request for disabled entries,
3406
+ and rediscovers before re-enable. Once the owning Runtime observes and applies
3407
+ the revision, disable blocks all new starts, including an explicit
3408
+ `external:<name>` target, but does not cancel or break an already admitted task.
3409
+ The CLI mutation returning is not cross-process acknowledgement. A failed
3410
+ activation remains retryable through the owning
3411
+ `ConfiguredA2ARuntimeHandle.reload()` even when the disk revision is unchanged;
3412
+ the passive `kodax integrations reload` command validates only its own process.
3413
+
3414
+ `kodax a2a test` performs Card discovery and security planning only. It never
3415
+ requests an OAuth access token; token acquisition starts at `a2a call` or the
3416
+ first Runtime dispatch.
3417
+
3299
3418
  Inbound publication is also no-code:
3300
3419
 
3301
3420
  ```bash
3302
3421
  export KODAX_A2A_TOKEN='replace-with-a-long-random-token'
3422
+ # PowerShell: $env:KODAX_A2A_TOKEN='replace-with-a-long-random-token'
3303
3423
  kodax a2a expose # Runtime default Agent
3304
3424
  kodax a2a expose document-agent # ~/.kodax/agents/document-agent.md
3305
3425
  kodax a2a serve --port 8765
3306
3426
  ```
3307
3427
 
3428
+ The fixed token above is the compatibility profile. For dynamic production
3429
+ tokens, configure KodaX as an OAuth Resource Server and point it at an external
3430
+ issuer:
3431
+
3432
+ ```bash
3433
+ kodax a2a expose document-agent --auth oauth2-jwt \
3434
+ --oauth-scheme enterprise-oauth \
3435
+ --oauth-issuer https://identity.example/ \
3436
+ --oauth-audience https://kodax.example/a2a \
3437
+ --oauth-jwks-url https://identity.example/.well-known/jwks.json \
3438
+ --oauth-token-url https://identity.example/oauth/token \
3439
+ --oauth-metadata-url https://identity.example/.well-known/oauth-authorization-server \
3440
+ --required-scope a2a.invoke
3441
+ kodax a2a serve --port 8765
3442
+ ```
3443
+
3444
+ The Authorization Server authenticates clients, provisions client IDs/secrets,
3445
+ issues/rotates/revokes tokens and, for JWT access tokens, signs them and
3446
+ publishes metadata/JWKS. The calling A2A
3447
+ client obtains a token out of band or with Client Credentials and sends it in
3448
+ the Bearer header. KodaX validates JWT type, asymmetric signature, issuer,
3449
+ audience, lifetime, subject, and required scopes before task lookup, then maps
3450
+ `sub` to the A2A principal. Missing/invalid credentials return `401`; a valid
3451
+ token without the required scope returns `403 insufficient_scope`. KodaX does
3452
+ not hold the issuer signing key or expose token, refresh, client-registration,
3453
+ login, or consent endpoints. Opaque-token introspection and mTLS deployments
3454
+ must use a host authentication adapter or reverse proxy. Offline JWT/JWKS
3455
+ validation also cannot observe immediate per-token revocation: use short access
3456
+ token lifetimes, signing-key rotation, or an introspecting proxy/adapter when
3457
+ that property is required.
3458
+
3459
+ #### Upgrade retained pre-realm tasks
3460
+
3461
+ Realm-aware task ownership intentionally has no normal-request legacy fallback:
3462
+ an authority switch must never adopt tasks merely because it reuses a subject.
3463
+ If a v0.7.70 task store must remain addressable after upgrading, stop the A2A
3464
+ server and first inspect an exact-owner migration plan:
3465
+
3466
+ ```bash
3467
+ kodax a2a migrate-tasks
3468
+ kodax a2a migrate-tasks --apply --confirm-server-stopped
3469
+
3470
+ # OAuth identity is token-specific, so provide the known historical subject.
3471
+ kodax a2a migrate-tasks --subject trusted-orchestrator
3472
+ ```
3473
+
3474
+ The configured Bearer profile supplies its fixed `principalId`; OAuth requires
3475
+ `--subject`. Dry-run does not rewrite `tasks.json`. Apply rekeys only exact
3476
+ matches, preserves unmatched records, and refuses a live task-store owner.
3477
+ Custom SDK hosts can plan multiple known owners without exposing raw tokens:
3478
+
3479
+ ```ts
3480
+ import { migrateA2ALegacyTaskOwners } from '@kodax-ai/kodax/a2a';
3481
+
3482
+ const mappings = [{
3483
+ securityRealm: 'oauth2-jwt:https://identity.example/',
3484
+ subject: 'trusted-orchestrator',
3485
+ }] as const;
3486
+ const plan = migrateA2ALegacyTaskOwners({
3487
+ dataDir: '/var/lib/kodax/a2a', mappings, apply: false,
3488
+ });
3489
+
3490
+ // After the host/operator verifies the plan:
3491
+ if (plan.matchedLegacyTaskCount > 0) {
3492
+ migrateA2ALegacyTaskOwners({
3493
+ dataDir: '/var/lib/kodax/a2a', mappings, apply: true,
3494
+ });
3495
+ }
3496
+ ```
3497
+
3498
+ The SDK also accepts `tenant` when a custom authentication adapter historically
3499
+ returned one. Two mappings that claim the same legacy owner for different
3500
+ realms are ambiguous and rejected; split or guessed ownership is never applied.
3501
+
3308
3502
  `a2a serve` resolves its Runtime provider in this order: explicit CLI option,
3309
3503
  environment, core configuration, then the built-in default. Provider-compatible
3310
3504
  model selection follows the normal hosted Runtime rule. A selected Markdown
@@ -3323,7 +3517,7 @@ projection and never reveal the private Skill inventory.
3323
3517
  The running server pins Agent, Skill, workspace, tool registration, process and
3324
3518
  store revisions. Card/auth/limits can hot reload; execution-authority changes
3325
3519
  require an explicit restart. Managed contexts live below
3326
- `~/kodax_a2a_server_workspace/<profile>/contexts/`. Exact Skill scripts require
3520
+ `~/kodax_a2a_server_workspace/<runtime-profile>/contexts/<context-key>/`. Exact Skill scripts require
3327
3521
  `process: isolated`, an admitted `scripts/...` path, and a passing
3328
3522
  `kodax sandbox doctor`; KodaX never falls back to an unsandboxed shell.
3329
3523
 
@@ -3338,7 +3532,10 @@ configured Agent, media types, and skills. Authentication runs before task
3338
3532
  lookup; authorization runs per operation; task visibility is principal-scoped.
3339
3533
 
3340
3534
  ```ts
3341
- import { createKodaXA2AServer } from '@kodax-ai/kodax/a2a';
3535
+ import {
3536
+ createBearerEnvA2AAuthentication,
3537
+ createKodaXA2AServer,
3538
+ } from '@kodax-ai/kodax/a2a';
3342
3539
  import { createKodaXRuntime } from '@kodax-ai/kodax/runtime';
3343
3540
 
3344
3541
  const runtime = await createKodaXRuntime({ mode: 'embedded', isolation: 'inline' });
@@ -3354,16 +3551,12 @@ const server = createKodaXA2AServer({
3354
3551
  inputModes: ['text/plain'],
3355
3552
  outputModes: ['text/plain'],
3356
3553
  },
3357
- authentication: {
3358
- securitySchemes: { bearer: { httpAuthSecurityScheme: { scheme: 'Bearer' } } },
3359
- securityRequirements: [{ schemes: { bearer: { list: [] } } }],
3360
- async authenticate(request) {
3361
- return request.headers.get('authorization') === `Bearer ${process.env.KODAX_A2A_TOKEN}`
3362
- ? { subject: 'trusted-orchestrator', scopes: ['a2a'] }
3363
- : null;
3364
- },
3365
- },
3366
- async authorize({ principal }) { return principal.scopes.includes('a2a'); },
3554
+ authentication: createBearerEnvA2AAuthentication({
3555
+ type: 'bearer-env',
3556
+ tokenEnv: 'KODAX_A2A_TOKEN',
3557
+ principalId: 'trusted-orchestrator',
3558
+ }),
3559
+ async authorize({ principal }) { return principal.scopes.includes('a2a:invoke'); },
3367
3560
  limits: {
3368
3561
  maxRequestBytes: 1_048_576,
3369
3562
  maxPartBytes: 524_288,
@@ -3381,9 +3574,9 @@ const server = createKodaXA2AServer({
3381
3574
  const localBaseUrl = await server.listen({ hostname: '127.0.0.1', port: 0 });
3382
3575
  ```
3383
3576
 
3384
- Production hosts route `GET /.well-known/agent-card.json` and JSON-RPC `POST /`
3385
- to `server.handle(request)` behind their own TLS terminator. `POST /a2a` remains
3386
- an accepted compatibility alias. `listen()` waits for durable recovery before
3577
+ Production hosts route `GET /.well-known/agent-card.json` and canonical
3578
+ JSON-RPC `POST /a2a` to `server.handle(request)` behind their own TLS
3579
+ terminator. `POST /` remains an accepted compatibility alias. `listen()` waits for durable recovery before
3387
3580
  it resolves. A host that wires `handle()` directly may explicitly await
3388
3581
  `server.whenReady()` before it starts accepting traffic; `handle()` also waits
3389
3582
  for the same recovery promise. The durable edge store supports get/list,
@@ -3448,12 +3641,28 @@ from renderer or model output. `connectKodaXRuntime()` is attach-only unless `au
3448
3641
  An explicit inline rollback policy blocks auto-start until the owner policy is
3449
3642
  explicitly changed back to daemon.
3450
3643
 
3644
+ For Electron, `homeDir` is still the CLI-style base directory, not
3645
+ `process.env.KODAX_HOME`. Packaged/asar applications may use `autoStart: true`
3646
+ directly; the SDK launches only the daemon child in Electron's Node execution
3647
+ mode and does not mutate the application's environment or start a second GUI
3648
+ instance. `ELECTRON_RUN_AS_NODE` exists only at the child exec boundary and is
3649
+ removed before daemon application code loads, so Bash, MCP, LSP, sandboxed
3650
+ commands, and ordinary external processes do not inherit Electron Node mode.
3651
+
3652
+ Packaged auto-start requires Electron's `RunAsNode` fuse, which Electron enables
3653
+ by default. If an embedder deliberately disables that fuse, the packaged
3654
+ executable cannot serve as a detached Node host: start the daemon with an
3655
+ ordinary Node/CLI process and use attach-only mode instead. A packaged
3656
+ `autoStart: true` timeout includes this fuse requirement in its diagnostic; the
3657
+ SDK does not relaunch the GUI or silently fall back to an inline Runtime.
3658
+
3451
3659
  ```ts
3452
3660
  import { connectKodaXRuntime } from '@kodax-ai/kodax/runtime';
3453
3661
 
3454
3662
  const runtime = await connectKodaXRuntime({
3455
3663
  profile: 'coder',
3456
3664
  autoStart: true,
3665
+ homeDir: coderRuntimeBaseDir, // owns <coderRuntimeBaseDir>/.kodax
3457
3666
  clientInfo: {
3458
3667
  name: 'kodax-space',
3459
3668
  version: '0.1.32',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kodax-ai/kodax",
3
- "version": "0.7.70",
3
+ "version": "0.7.71",
4
4
  "description": "KodaX lightweight coding agent - TypeScript implementation with 15 built-in LLM provider aliases, published as a Node-free single-file CLI and SDK",
5
5
  "type": "module",
6
6
  "private": false,
@@ -85,6 +85,8 @@
85
85
  "test": "vitest run",
86
86
  "test:watch": "vitest",
87
87
  "test:eval": "vitest run -c vitest.eval.config.ts",
88
+ "test:electron-daemon": "npm run build && node scripts/test-electron-daemon-smoke.mjs",
89
+ "test:electron-daemon:built": "node scripts/test-electron-daemon-smoke.mjs",
88
90
  "bench:perf": "tsx benchmark/perf/repl-render-perf.bench.ts",
89
91
  "bench:perf:e2e": "tsx benchmark/perf/repl-render-engine-e2e.bench.ts",
90
92
  "bench:repo-intel": "tsx benchmark/perf/repo-intelligence-index.bench.ts",
@@ -126,6 +128,7 @@
126
128
  "is-in-ci": "^2.0.0",
127
129
  "jimp": "^1.6.0",
128
130
  "js-tiktoken": "^1.0.12",
131
+ "oauth4webapi": "3.8.6",
129
132
  "openai": "^6.32.0",
130
133
  "partial-json": "^0.1.7",
131
134
  "patch-console": "^2.0.0",
@@ -1,2 +0,0 @@
1
- // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{Ba as a,Ca as b}from"./chunk-K7RYV2SE.js";import"./chunk-P2UKNYYS.js";import"./chunk-WW2O2DEP.js";import"./chunk-4P4L3WEK.js";import"./chunk-F4NOOBRZ.js";import"./chunk-GOQRVDFP.js";import"./chunk-RY5OLVQV.js";import"./chunk-I4TPQEJN.js";import"./chunk-Y4WOTWUC.js";import"./chunk-AQGNRBEJ.js";import"./chunk-UJEMSPM5.js";import"./chunk-7PV577LP.js";import"./chunk-AWMTNUDS.js";import"./chunk-F7C7J6IM.js";import"./chunk-NGHQIGVW.js";import"./chunk-ONUPGMER.js";export{a as ArgumentCompleter,b as createArgumentCompleter};