@vibesdotdev/runtime-client 0.0.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.
Files changed (63) hide show
  1. package/README.md +97 -0
  2. package/SPEC.md +44 -0
  3. package/dist/base.d.ts +49 -0
  4. package/dist/base.d.ts.map +1 -0
  5. package/dist/base.js +86 -0
  6. package/dist/base.js.map +1 -0
  7. package/dist/contract.d.ts +23 -0
  8. package/dist/contract.d.ts.map +1 -0
  9. package/dist/contract.js +2 -0
  10. package/dist/contract.js.map +1 -0
  11. package/dist/docs/runtime-client.api.docs.descriptor.d.ts +8 -0
  12. package/dist/docs/runtime-client.api.docs.descriptor.d.ts.map +1 -0
  13. package/dist/docs/runtime-client.api.docs.descriptor.js +344 -0
  14. package/dist/docs/runtime-client.api.docs.descriptor.js.map +1 -0
  15. package/dist/docs/runtime-client.helpers.docs.descriptor.d.ts +8 -0
  16. package/dist/docs/runtime-client.helpers.docs.descriptor.d.ts.map +1 -0
  17. package/dist/docs/runtime-client.helpers.docs.descriptor.js +352 -0
  18. package/dist/docs/runtime-client.helpers.docs.descriptor.js.map +1 -0
  19. package/dist/docs/runtime-client.surface.docs.descriptor.d.ts +8 -0
  20. package/dist/docs/runtime-client.surface.docs.descriptor.d.ts.map +1 -0
  21. package/dist/docs/runtime-client.surface.docs.descriptor.js +464 -0
  22. package/dist/docs/runtime-client.surface.docs.descriptor.js.map +1 -0
  23. package/dist/docs/types.d.ts +19 -0
  24. package/dist/docs/types.d.ts.map +1 -0
  25. package/dist/docs/types.js +2 -0
  26. package/dist/docs/types.js.map +1 -0
  27. package/dist/helper.d.ts +14 -0
  28. package/dist/helper.d.ts.map +1 -0
  29. package/dist/helper.js +27 -0
  30. package/dist/helper.js.map +1 -0
  31. package/dist/index.d.ts +8 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +8 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/kind.d.ts +10 -0
  36. package/dist/kind.d.ts.map +1 -0
  37. package/dist/kind.js +12 -0
  38. package/dist/kind.js.map +1 -0
  39. package/dist/plugin.d.ts +10 -0
  40. package/dist/plugin.d.ts.map +1 -0
  41. package/dist/plugin.js +17 -0
  42. package/dist/plugin.js.map +1 -0
  43. package/dist/runtime-client.plugin.d.ts +13 -0
  44. package/dist/runtime-client.plugin.d.ts.map +1 -0
  45. package/dist/runtime-client.plugin.js +27 -0
  46. package/dist/runtime-client.plugin.js.map +1 -0
  47. package/dist/schema.d.ts +32 -0
  48. package/dist/schema.d.ts.map +1 -0
  49. package/dist/schema.js +8 -0
  50. package/dist/schema.js.map +1 -0
  51. package/package.json +61 -0
  52. package/src/base.ts +100 -0
  53. package/src/contract.ts +23 -0
  54. package/src/docs/runtime-client.api.docs.descriptor.ts +346 -0
  55. package/src/docs/runtime-client.helpers.docs.descriptor.ts +354 -0
  56. package/src/docs/runtime-client.surface.docs.descriptor.ts +466 -0
  57. package/src/docs/types.ts +18 -0
  58. package/src/helper.ts +32 -0
  59. package/src/index.ts +11 -0
  60. package/src/kind.ts +14 -0
  61. package/src/plugin.ts +19 -0
  62. package/src/runtime-client.plugin.ts +32 -0
  63. package/src/schema.ts +27 -0
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @vibesdotdev/runtime-client
2
+
3
+ The `runtime/client` kind and `BaseRuntimeClient`. Every module that exposes
4
+ functionality across the monorepo does so through exactly one client registered
5
+ under this kind.
6
+
7
+ ## Authoring a new client
8
+
9
+ Mechanical recipe. No variation.
10
+
11
+ ### 1. Define the client class
12
+
13
+ ```ts
14
+ // <module>/src/lib/client/runtime-client.ts
15
+ import { BaseRuntimeClient, type RuntimeClientDescriptor } from '@vibesdotdev/runtime-client';
16
+ import type { VibesRuntime } from '@vibesdotdev/runtime';
17
+
18
+ export class MyModuleClient extends BaseRuntimeClient {
19
+ constructor(
20
+ descriptor: RuntimeClientDescriptor = { id: 'my-module', kind: 'runtime/client' },
21
+ context?: unknown,
22
+ runtime?: VibesRuntime,
23
+ ) {
24
+ super(descriptor, context, runtime);
25
+ }
26
+
27
+ async doSomething(/* … */) {
28
+ // resolve other kinds via this.runtime.query(...)
29
+ }
30
+ }
31
+ ```
32
+
33
+ ### 2. Register in the module's plugin
34
+
35
+ ```ts
36
+ export default createRuntimePlugin({
37
+ id: 'my-module',
38
+ dependencies: ['runtime-client', /* … */],
39
+ onRegister(runtime) {
40
+ runtime.registerDescriptor('runtime/client', {
41
+ id: 'my-module',
42
+ kind: 'runtime/client',
43
+ description: 'Canonical MyModule client',
44
+ });
45
+ runtime.registerLoader('runtime/client', 'my-module', async () => {
46
+ const { MyModuleClient } = await import('./client/runtime-client.js');
47
+ return { impl: MyModuleClient };
48
+ });
49
+ },
50
+ });
51
+ ```
52
+
53
+ ### 3. Export the ambient helper
54
+
55
+ ```ts
56
+ // <module>/src/lib/client/helper.ts
57
+ import { getVibesClient } from '@vibesdotdev/runtime-client';
58
+ import type { MyModuleClient } from './runtime-client';
59
+
60
+ export async function getVibesMyModuleClient(): Promise<MyModuleClient> {
61
+ return getVibesClient<MyModuleClient>('my-module');
62
+ }
63
+ ```
64
+
65
+ ### 4. Expose via module barrel + `package.json` subpath
66
+
67
+ ```ts
68
+ // <module>/src/lib/client/index.ts
69
+ export { MyModuleClient } from './runtime-client';
70
+ export { getVibesMyModuleClient } from './helper';
71
+ export type * from './contracts';
72
+ ```
73
+
74
+ Add `"./client"` to the module's `package.json#exports`.
75
+
76
+ ## Consuming another module's client
77
+
78
+ ```ts
79
+ import { getVibesToolsClient } from '@vibesdotdev/tools/client';
80
+ const tools = await getVibesToolsClient();
81
+ const agent = await tools.getAgent('assistant');
82
+ ```
83
+
84
+ If the other module exposes only kinds (no client), use `runtime.query('<kind>').…`
85
+ directly. Never deep-import another module's internals.
86
+
87
+ ## Test
88
+
89
+ ```bash
90
+ bun test src/__tests__/
91
+ ```
92
+
93
+ ## Docs
94
+
95
+ - [SPEC.md](./SPEC.md) — package contract, owned surfaces, hard rules
96
+ - [runtime](../runtime/SPEC.md) — registry/query layer this builds on
97
+ - [client](../client/SPEC.md) — sister `api/client` kind for HTTP clients
package/SPEC.md ADDED
@@ -0,0 +1,44 @@
1
+ # @vibesdotdev/runtime-client
2
+
3
+ The `runtime/client` kind + the shared base every module-level client extends. One client per module, runtime-resolved.
4
+
5
+ ## Owns
6
+
7
+ - `runtime/client` kind (registered via `./plugin`)
8
+ - `BaseRuntimeClient` abstract class — ambient runtime acquisition, idempotent `load()`/`ensureLoaded()`, optional `config/manifest` auto-load via `descriptor.configManifestId`, `onLoad`/`onDispose` hooks, `(descriptor, context?, runtime?)` constructor signature
9
+ - `RuntimeClient` interface (`./contract`)
10
+ - `RuntimeClientDescriptor` zod schema (`./schema`)
11
+ - `getVibesClient<T>(id)` ambient helper
12
+
13
+ ## Does not own
14
+
15
+ - HTTP abstraction → [`@vibesdotdev/client`](../client/SPEC.md) (`api/client` kind)
16
+ - Config manager → [`@vibesdotdev/config`](../config/SPEC.md) (`config/manifest` kind)
17
+ - Registry / kind resolution → [`@vibesdotdev/runtime`](../runtime/SPEC.md)
18
+ - Any module's domain methods — those live on each module's subclass
19
+
20
+ ## Hard rules
21
+
22
+ - **One client per module.** No split HTTP-vs-in-process clients. No module-specific factories competing with the canonical one.
23
+ - **All module clients extend `BaseRuntimeClient`.** They do not reimplement lifecycle, config-load, or runtime acquisition.
24
+ - **Scope selection lives inside the client**, never in consumers. Consumers call `client.foo()` and never branch on hardware/connection mode.
25
+ - **Cross-module access goes through (1) the other module's client, or (2) direct `runtime.query('<kind>')` for primitives.** Never deep-import another module's internals. Never duplicate another module's types.
26
+ - **Two sanctioned client flavors only:** `runtime/client` (this package) and `api/client` ([`@vibesdotdev/client`](../client/SPEC.md)). New flavors require a SPEC update.
27
+ - This package depends only on `@vibesdotdev/runtime` and `zod`. It does not import any module's domain code.
28
+
29
+ ## Public entrypoints
30
+
31
+ - `.` — `BaseRuntimeClient`, `getVibesClient`, `RuntimeClient` type, descriptor schema (barrel)
32
+ - `./plugin` — `runtimeClientPlugin` (registers the kind)
33
+ - `./contract` — `RuntimeClient` (type-only)
34
+ - `./schema` — `RuntimeClientDescriptor` zod schema
35
+ - `./base` — `BaseRuntimeClient`
36
+
37
+ ## Verification
38
+
39
+ `bun test src/__tests__/`. Covers kind registration, base lifecycle, `getVibesClient` resolution, descriptor schema.
40
+
41
+ ## Links
42
+
43
+ - [runtime/SPEC.md](../runtime/SPEC.md)
44
+ - [client/SPEC.md](../client/SPEC.md) — sister `api/client` kind
package/dist/base.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import { type VibesRuntime } from '@vibesdotdev/runtime';
2
+ import type { RuntimeClient } from './contract.ts';
3
+ import type { RuntimeClientDescriptor } from './schema.ts';
4
+ /**
5
+ * Shared base for module-level clients.
6
+ *
7
+ * Handles:
8
+ * - ambient runtime acquisition (via `getVibesRuntime()`)
9
+ * - idempotent lazy init (`ensureLoaded()`)
10
+ * - `config/manifest` auto-loading when `descriptor.configManifestId` is set
11
+ * - lifecycle hooks (`onLoad`, `onDispose`) for subclasses
12
+ *
13
+ * Subclasses (AIClient, ToolsClient, …) add their domain methods and call
14
+ * `this.ensureLoaded()` at method entry points when their behavior depends
15
+ * on loaded config.
16
+ *
17
+ * Constructor signature matches the runtime's kind-instantiation contract:
18
+ * `(descriptor, context?)`. Context is not currently consumed — runtime
19
+ * access goes through the ambient singleton — but remains a parameter for
20
+ * forward compatibility with kind contexts that carry scope metadata.
21
+ */
22
+ export declare abstract class BaseRuntimeClient implements RuntimeClient {
23
+ readonly id: string;
24
+ readonly runtime: VibesRuntime;
25
+ protected readonly descriptor: RuntimeClientDescriptor;
26
+ protected configValues: unknown | null;
27
+ private loadPromise?;
28
+ constructor(descriptor: RuntimeClientDescriptor, _context?: unknown, runtime?: VibesRuntime);
29
+ /**
30
+ * Idempotent lazy init. First call drives `onLoad()`; subsequent calls
31
+ * await the same promise. Subclasses call this at method entry points
32
+ * when they need config loaded.
33
+ */
34
+ ensureLoaded(): Promise<void>;
35
+ /** Public `load()` matching the `RuntimeClient` contract. Alias of `ensureLoaded()`. */
36
+ load(): Promise<void>;
37
+ dispose(): void;
38
+ /**
39
+ * Override to perform module-specific initialization. Default behavior:
40
+ * if `descriptor.configManifestId` is set, resolve the corresponding
41
+ * `config/manifest` and load its values into `this.configValues`.
42
+ */
43
+ protected onLoad(): Promise<void>;
44
+ protected onDispose(): void;
45
+ /** Subclass accessor for loaded config values (null if load hasn't run or failed). */
46
+ protected getConfigValues<T = unknown>(): T | null;
47
+ private runLoad;
48
+ }
49
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D;;;;;;;;;;;;;;;;;GAiBG;AACH,8BAAsB,iBAAkB,YAAW,aAAa;IAC/D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAE/B,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,uBAAuB,CAAC;IACvD,SAAS,CAAC,YAAY,EAAE,OAAO,GAAG,IAAI,CAAQ;IAE9C,OAAO,CAAC,WAAW,CAAC,CAAgB;gBAGnC,UAAU,EAAE,uBAAuB,EACnC,QAAQ,CAAC,EAAE,OAAO,EAClB,OAAO,CAAC,EAAE,YAAY;IAUvB;;;;OAIG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC,wFAAwF;IAClF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,OAAO,IAAI,IAAI;IAMf;;;;OAIG;cACa,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvC,SAAS,CAAC,SAAS,IAAI,IAAI;IAE3B,sFAAsF;IACtF,SAAS,CAAC,eAAe,CAAC,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,IAAI;YAIpC,OAAO;CAGrB"}
package/dist/base.js ADDED
@@ -0,0 +1,86 @@
1
+ import { getVibesRuntime } from '@vibesdotdev/runtime';
2
+ /**
3
+ * Shared base for module-level clients.
4
+ *
5
+ * Handles:
6
+ * - ambient runtime acquisition (via `getVibesRuntime()`)
7
+ * - idempotent lazy init (`ensureLoaded()`)
8
+ * - `config/manifest` auto-loading when `descriptor.configManifestId` is set
9
+ * - lifecycle hooks (`onLoad`, `onDispose`) for subclasses
10
+ *
11
+ * Subclasses (AIClient, ToolsClient, …) add their domain methods and call
12
+ * `this.ensureLoaded()` at method entry points when their behavior depends
13
+ * on loaded config.
14
+ *
15
+ * Constructor signature matches the runtime's kind-instantiation contract:
16
+ * `(descriptor, context?)`. Context is not currently consumed — runtime
17
+ * access goes through the ambient singleton — but remains a parameter for
18
+ * forward compatibility with kind contexts that carry scope metadata.
19
+ */
20
+ export class BaseRuntimeClient {
21
+ id;
22
+ runtime;
23
+ descriptor;
24
+ configValues = null;
25
+ loadPromise;
26
+ constructor(descriptor, _context, runtime) {
27
+ this.descriptor = descriptor;
28
+ this.id = descriptor.id;
29
+ // Ambient runtime is the default path (matches `getVibesClient<T>(id)`).
30
+ // Explicit runtime override is available for legacy factory callers and
31
+ // advanced scenarios (e.g. multi-runtime test harnesses).
32
+ this.runtime = runtime ?? getVibesRuntime();
33
+ }
34
+ /**
35
+ * Idempotent lazy init. First call drives `onLoad()`; subsequent calls
36
+ * await the same promise. Subclasses call this at method entry points
37
+ * when they need config loaded.
38
+ */
39
+ async ensureLoaded() {
40
+ if (!this.loadPromise) {
41
+ this.loadPromise = this.runLoad();
42
+ }
43
+ return this.loadPromise;
44
+ }
45
+ /** Public `load()` matching the `RuntimeClient` contract. Alias of `ensureLoaded()`. */
46
+ async load() {
47
+ return this.ensureLoaded();
48
+ }
49
+ dispose() {
50
+ this.loadPromise = undefined;
51
+ this.configValues = null;
52
+ this.onDispose();
53
+ }
54
+ /**
55
+ * Override to perform module-specific initialization. Default behavior:
56
+ * if `descriptor.configManifestId` is set, resolve the corresponding
57
+ * `config/manifest` and load its values into `this.configValues`.
58
+ */
59
+ async onLoad() {
60
+ const manifestId = this.descriptor.configManifestId;
61
+ if (!manifestId)
62
+ return;
63
+ try {
64
+ const manifest = (await this.runtime
65
+ .query('config/manifest')
66
+ .withId(manifestId)
67
+ .resolve());
68
+ if (manifest?.load) {
69
+ this.configValues = await manifest.load();
70
+ }
71
+ }
72
+ catch {
73
+ // Config is best-effort at the base layer. Subclasses handle required/missing config.
74
+ this.configValues = null;
75
+ }
76
+ }
77
+ onDispose() { }
78
+ /** Subclass accessor for loaded config values (null if load hasn't run or failed). */
79
+ getConfigValues() {
80
+ return this.configValues;
81
+ }
82
+ async runLoad() {
83
+ await this.onLoad();
84
+ }
85
+ }
86
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAqB,MAAM,sBAAsB,CAAC;AAI1E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAgB,iBAAiB;IAC7B,EAAE,CAAS;IACX,OAAO,CAAe;IAEZ,UAAU,CAA0B;IAC7C,YAAY,GAAmB,IAAI,CAAC;IAEtC,WAAW,CAAiB;IAEpC,YACC,UAAmC,EACnC,QAAkB,EAClB,OAAsB;QAEtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC;QACxB,yEAAyE;QACzE,wEAAwE;QACxE,0DAA0D;QAC1D,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,eAAe,EAAE,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY;QACjB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED,wFAAwF;IACxF,KAAK,CAAC,IAAI;QACT,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO;QACN,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,SAAS,EAAE,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACO,KAAK,CAAC,MAAM;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC;QACpD,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO;iBAClC,KAAK,CAAC,iBAAiB,CAAC;iBACxB,MAAM,CAAC,UAAU,CAAC;iBAClB,OAAO,EAAE,CAAkD,CAAC;YAC9D,IAAI,QAAQ,EAAE,IAAI,EAAE,CAAC;gBACpB,IAAI,CAAC,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC3C,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,sFAAsF;YACtF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC1B,CAAC;IACF,CAAC;IAES,SAAS,KAAU,CAAC;IAE9B,sFAAsF;IAC5E,eAAe;QACxB,OAAO,IAAI,CAAC,YAAwB,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,OAAO;QACpB,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IACrB,CAAC;CACD"}
@@ -0,0 +1,23 @@
1
+ import type { VibesRuntime } from '@vibesdotdev/runtime';
2
+ /**
3
+ * Base contract every module-level client satisfies.
4
+ *
5
+ * Module-specific clients extend this with domain methods:
6
+ * AIClient adds `generate`, `getProvider`, `listModels`, …
7
+ * ToolsClient adds `listTools`, `runTool`, …
8
+ * KnowledgeClient adds `search`, `ingest`, …
9
+ *
10
+ * All clients share the same shape for lifecycle + runtime access so that
11
+ * consumers, tests, and tooling can treat them uniformly.
12
+ */
13
+ export interface RuntimeClient {
14
+ /** The descriptor id this client was registered with. */
15
+ readonly id: string;
16
+ /** Runtime reference the client uses for internal resolution. */
17
+ readonly runtime: VibesRuntime;
18
+ /** Idempotent load. Safe to call repeatedly; internal state cached. */
19
+ load(): Promise<void>;
20
+ /** Release any client-held resources (subscriptions, caches, etc.). */
21
+ dispose(): void;
22
+ }
23
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,aAAa;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,uEAAuE;IACvE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,uEAAuE;IACvE,OAAO,IAAI,IAAI,CAAC;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import type { DocsTopicDescriptor } from './types.ts';
2
+ /**
3
+ * Descriptor for runtime-client.api
4
+ * BaseRuntimeClient class, client patterns, how to extend
5
+ */
6
+ declare const descriptor: DocsTopicDescriptor;
7
+ export default descriptor;
8
+ //# sourceMappingURL=runtime-client.api.docs.descriptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-client.api.docs.descriptor.d.ts","sourceRoot":"","sources":["../../src/docs/runtime-client.api.docs.descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;GAGG;AACH,QAAA,MAAM,UAAU,EAAE,mBAiVjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,344 @@
1
+ /**
2
+ * Descriptor for runtime-client.api
3
+ * BaseRuntimeClient class, client patterns, how to extend
4
+ */
5
+ const descriptor = {
6
+ kind: 'docs/topic',
7
+ id: 'runtime-client.api',
8
+ title: 'Runtime Client API',
9
+ summary: 'BaseRuntimeClient base class and patterns for extending module-level clients',
10
+ body: {
11
+ type: 'markdown',
12
+ sourceType: 'raw',
13
+ source: `---
14
+ title: Runtime Client API
15
+ summary: BaseRuntimeClient base class and patterns for extending module-level clients
16
+ tags: [runtime-client, base-class, extension, api, patterns]
17
+ parent: runtime-client
18
+ order: 1
19
+ surfaces: [cli, web, in-app]
20
+ hardware: [consumer, cloud]
21
+ ---
22
+
23
+ # Runtime Client API
24
+
25
+ The \`BaseRuntimeClient\` class provides a shared foundation for module-level clients (AIClient, ToolsClient, KnowledgeClient, etc.). It handles runtime acquisition, idempotent lazy initialization, config loading, and lifecycle management.
26
+
27
+ ## Architecture
28
+
29
+ Module clients follow a **one-client-per-module** pattern:
30
+
31
+ \`\`\`
32
+ ┌─────────────────────────────────────────────────────────┐
33
+ │ Module Plugin (ai, tools, knowledge, etc.) │
34
+ │ - Registers runtime/client descriptor │
35
+ │ - Provides implementation class via loader │
36
+ └─────────────────────────────────────────────────────────┘
37
+
38
+
39
+ ┌─────────────────────────────────────────────────────────┐
40
+ │ RuntimeClient Implementation (extends BaseRuntimeClient)│
41
+ │ - Domain methods (generate, listTools, search, etc.) │
42
+ │ - Config access via this.getConfigValues<T>() │
43
+ │ - Runtime access via this.runtime │
44
+ └─────────────────────────────────────────────────────────┘
45
+
46
+
47
+ ┌─────────────────────────────────────────────────────────┐
48
+ │ BaseRuntimeClient (shared base) │
49
+ │ - Ambient runtime acquisition │
50
+ │ - Idempotent lazy init (ensureLoaded()) │
51
+ │ - Config manifest auto-loading │
52
+ │ - Lifecycle hooks (onLoad, onDispose) │
53
+ └─────────────────────────────────────────────────────────┘
54
+ \`\`\`
55
+
56
+ ## BaseRuntimeClient
57
+
58
+ ### Constructor
59
+
60
+ \`\`\`ts
61
+ constructor(
62
+ descriptor: RuntimeClientDescriptor,
63
+ _context?: unknown,
64
+ runtime?: VibesRuntime
65
+ )
66
+ \`\`\`
67
+
68
+ **Parameters:**
69
+ - \`descriptor\` — The \`runtime/client\` descriptor this client represents
70
+ - \`_context\` — Reserved for future scope metadata (not currently used)
71
+ - \`runtime\` — Optional explicit runtime override (defaults to \`getVibesRuntime()\`)
72
+
73
+ ### Properties
74
+
75
+ \`\`\`ts
76
+ readonly id: string; // From descriptor.id
77
+ readonly runtime: VibesRuntime; // Ambient runtime singleton
78
+ \`\`\`
79
+
80
+ ### Lifecycle Methods
81
+
82
+ #### ensureLoaded() / load()
83
+
84
+ Idempotent lazy initialization. First call drives \`onLoad()\`; subsequent calls await the same promise.
85
+
86
+ \`\`\`ts
87
+ async ensureLoaded(): Promise<void>
88
+ async load(): Promise<void> // Alias of ensureLoaded()
89
+ \`\`\`
90
+
91
+ **When to call:** At method entry points when your client depends on loaded config.
92
+
93
+ \`\`\`ts
94
+ export class AIClient extends BaseRuntimeClient {
95
+ async generate(prompt: string): Promise<GenerationResponse> {
96
+ await this.ensureLoaded(); // Ensure config is loaded
97
+
98
+ const config = this.getConfigValues<AIConfig>();
99
+ const provider = await this.runtime.query('ai/provider')
100
+ .withId(config?.defaultProvider ?? 'anthropic')
101
+ .resolve();
102
+
103
+ return provider.generate({ prompt });
104
+ }
105
+ }
106
+ \`\`\`
107
+
108
+ #### dispose()
109
+
110
+ Releases client-held resources:
111
+
112
+ \`\`\`ts
113
+ dispose(): void {
114
+ this.loadPromise = undefined;
115
+ this.configValues = null;
116
+ this.onDispose(); // Subclass hook
117
+ }
118
+ \`\`\`
119
+
120
+ Call when shutting down the client (e.g., test teardown, hot reload).
121
+
122
+ ### Protected Hooks for Subclasses
123
+
124
+ #### onLoad()
125
+
126
+ Override to perform module-specific initialization. Default behavior: if \`descriptor.configManifestId\` is set, resolves the corresponding \`config/manifest\` and loads its values.
127
+
128
+ \`\`\`ts
129
+ protected async onLoad(): Promise<void> {
130
+ // Default: load config manifest if specified
131
+ const manifestId = this.descriptor.configManifestId;
132
+ if (!manifestId) return;
133
+
134
+ try {
135
+ const manifest = await this.runtime
136
+ .query('config/manifest')
137
+ .withId(manifestId)
138
+ .resolve();
139
+
140
+ if (manifest?.load) {
141
+ this.configValues = await manifest.load();
142
+ }
143
+ } catch {
144
+ // Config is best-effort at base layer
145
+ this.configValues = null;
146
+ }
147
+
148
+ // Subclasses can extend:
149
+ // - Initialize domain-specific caches
150
+ // - Validate required config
151
+ // - Establish connections
152
+ }
153
+ \`\`\`
154
+
155
+ #### onDispose()
156
+
157
+ Override to release resources:
158
+
159
+ \`\`\`ts
160
+ protected onDispose(): void {
161
+ // Close connections, clear caches, cancel subscriptions
162
+ }
163
+ \`\`\`
164
+
165
+ #### getConfigValues<T>()
166
+
167
+ Accessor for loaded config values (null if load hasn't run or failed):
168
+
169
+ \`\`\`ts
170
+ protected getConfigValues<T = unknown>(): T | null
171
+ \`\`\`
172
+
173
+ ## Extending BaseRuntimeClient
174
+
175
+ ### Minimal Example
176
+
177
+ \`\`\`ts
178
+ // packages/my-module/src/client.ts
179
+ import { BaseRuntimeClient, type RuntimeClientDescriptor } from '@vibesdotdev/runtime-client';
180
+
181
+ export interface MyModuleDescriptor extends RuntimeClientDescriptor {
182
+ kind: 'runtime/client';
183
+ id: 'my-module';
184
+ configManifestId?: string;
185
+ }
186
+
187
+ export class MyModuleClient extends BaseRuntimeClient {
188
+ constructor(descriptor: MyModuleDescriptor) {
189
+ super(descriptor);
190
+ }
191
+
192
+ async doSomething(input: string): Promise<string> {
193
+ await this.ensureLoaded();
194
+
195
+ const runtime = this.runtime;
196
+ // Use runtime APIs...
197
+ return \`Processed: \${input}\`;
198
+ }
199
+ }
200
+ \`\`\`
201
+
202
+ ### Full Example with Config
203
+
204
+ \`\`\`ts
205
+ // packages/ai/src/client/ai-client.ts
206
+ import { BaseRuntimeClient, type RuntimeClientDescriptor } from '@vibesdotdev/runtime-client';
207
+
208
+ interface AIConfig {
209
+ defaultProvider: string;
210
+ maxTokens: number;
211
+ temperature: number;
212
+ }
213
+
214
+ export class AIClient extends BaseRuntimeClient {
215
+ constructor(descriptor: RuntimeClientDescriptor) {
216
+ super(descriptor);
217
+ }
218
+
219
+ async generate(options: {
220
+ prompt: string;
221
+ model?: string;
222
+ maxTokens?: number;
223
+ }): Promise<string> {
224
+ await this.ensureLoaded();
225
+
226
+ const config = this.getConfigValues<AIConfig>();
227
+ if (!config) {
228
+ throw new Error('AI config not loaded');
229
+ }
230
+
231
+ const provider = await this.runtime
232
+ .query('ai/provider')
233
+ .withId(config.defaultProvider)
234
+ .resolve();
235
+
236
+ const response = await provider.generate({
237
+ prompt: options.prompt,
238
+ model: options.model,
239
+ maxTokens: options.maxTokens ?? config.maxTokens,
240
+ temperature: config.temperature
241
+ });
242
+
243
+ return response.text;
244
+ }
245
+
246
+ async listModels(): Promise<string[]> {
247
+ await this.ensureLoaded();
248
+
249
+ const models = await this.runtime
250
+ .query('ai/model')
251
+ .descriptors();
252
+
253
+ return models.map(m => m.id);
254
+ }
255
+
256
+ protected async onLoad(): Promise<void> {
257
+ await super.onLoad(); // Load config manifest
258
+
259
+ // Additional AI-specific initialization
260
+ // e.g., warm provider caches, validate API keys
261
+ }
262
+
263
+ protected onDispose(): void {
264
+ // Cancel pending generations, clear caches
265
+ super.onDispose();
266
+ }
267
+ }
268
+ \`\`\`
269
+
270
+ ### Registering the Client
271
+
272
+ \`\`\`ts
273
+ // packages/ai/src/ai.plugin.ts
274
+ import { createRuntimePlugin } from '@vibesdotdev/runtime';
275
+ import { AIClient } from './client/ai-client';
276
+
277
+ export const aiPlugin = createRuntimePlugin({
278
+ id: 'ai',
279
+ name: 'AI Module',
280
+ onRegister(runtime) {
281
+ // Register per-id loader for runtime/client kind
282
+ runtime.registerLoader('runtime/client', 'ai', async () => {
283
+ return new AIClient({
284
+ kind: 'runtime/client',
285
+ id: 'ai',
286
+ configManifestId: 'ai/config'
287
+ });
288
+ });
289
+ }
290
+ });
291
+ \`\`\`
292
+
293
+ ## WRONG patterns
294
+
295
+ :::card{title="Anti-patterns"}
296
+ - ❌ **Direct runtime instantiation** — Don't \`new VibesRuntime()\`; use ambient \`this.runtime\`
297
+ - ❌ **Storing runtime references** — Call \`getVibesRuntime()\` at construction, store as \`this.runtime\`
298
+ - ❌ **Skipping ensureLoaded()** — Always call at method entry if you need config
299
+ - ❌ **Multiple config loads** — Base class handles idempotent loading; don't re-implement
300
+ - ❌ **Throwing on missing config** — Config is best-effort; validate in subclass if required
301
+ - ❌ **Direct config manifest resolution** — Use base class \`onLoad()\` pattern
302
+ :::
303
+
304
+ ## Code paths
305
+
306
+ - Base class: [\`packages/runtime-client/src/base.ts\`](https://github.com/vibesdotdev/monorepo/tree/main/packages/runtime-client/src/base.ts)
307
+ - Contract: [\`packages/runtime-client/src/contract.ts\`](https://github.com/vibesdotdev/monorepo/tree/main/packages/runtime-client/src/contract.ts)
308
+ - Schema: [\`packages/runtime-client/src/schema.ts\`](https://github.com/vibesdotdev/monorepo/tree/main/packages/runtime-client/src/schema.ts)
309
+ - Kind: [\`packages/runtime-client/src/kind.ts\`](https://github.com/vibesdotdev/monorepo/tree/main/packages/runtime-client/src/kind.ts)
310
+
311
+ :::card{title="See also"}
312
+ - [\`runtime-client.helpers\`](runtime-client.helpers) — \`getVibesClient()\` helper functions
313
+ - [\`runtime-client.surface\`](runtime-client.surface) — Surface initialization patterns
314
+ - [\`runtime.query\`](runtime.query) — Runtime query API for resolving clients
315
+ - [\`runtime.plugins\`](runtime.plugins) — Plugin registration and loaders
316
+ :::
317
+ `
318
+ },
319
+ parent: 'runtime-client',
320
+ order: 1,
321
+ tags: ['runtime-client', 'base-class', 'extension', 'api', 'patterns'],
322
+ surfaces: ['cli', 'web', 'in-app'],
323
+ hardware: ['consumer', 'cloud'],
324
+ enabled: true,
325
+ man: {
326
+ name: 'runtime-client.api — BaseRuntimeClient and extension patterns',
327
+ section: 1,
328
+ synopsis: 'vibes man runtime-client.api',
329
+ options: [],
330
+ examples: [
331
+ {
332
+ description: 'Extend BaseRuntimeClient',
333
+ command: 'class MyClient extends BaseRuntimeClient { ... }'
334
+ },
335
+ {
336
+ description: 'Load config in onLoad()',
337
+ command: 'protected async onLoad() { await super.onLoad(); ... }'
338
+ }
339
+ ],
340
+ seeAlso: ['runtime-client.helpers', 'runtime-client.surface', 'runtime.query']
341
+ }
342
+ };
343
+ export default descriptor;
344
+ //# sourceMappingURL=runtime-client.api.docs.descriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-client.api.docs.descriptor.js","sourceRoot":"","sources":["../../src/docs/runtime-client.api.docs.descriptor.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,GAAwB;IACtC,IAAI,EAAE,YAAY;IAClB,EAAE,EAAE,oBAAoB;IACxB,KAAK,EAAE,oBAAoB;IAC3B,OAAO,EAAE,8EAA8E;IACvF,IAAI,EAAE;QACJ,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,KAAK;QACjB,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgTX;KACE;IACD,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC;IACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC;IAClC,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;IAC/B,OAAO,EAAE,IAAI;IACb,GAAG,EAAE;QACH,IAAI,EAAE,+DAA+D;QACrE,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,8BAA8B;QACxC,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE;YACR;gBACE,WAAW,EAAE,0BAA0B;gBACvC,OAAO,EAAE,kDAAkD;aAC5D;YACD;gBACE,WAAW,EAAE,yBAAyB;gBACtC,OAAO,EAAE,wDAAwD;aAClE;SACF;QACD,OAAO,EAAE,CAAC,wBAAwB,EAAE,wBAAwB,EAAE,eAAe,CAAC;KAC/E;CACF,CAAC;AAEF,eAAe,UAAU,CAAC"}