@vendoai/vendo 0.4.3 → 0.4.5

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 (47) hide show
  1. package/dist/capability-misses.js +2 -3
  2. package/dist/cli/cloud/client.d.ts +2 -5
  3. package/dist/cli/cloud/client.js +4 -4
  4. package/dist/cli/dep-versions.d.ts +1 -1
  5. package/dist/cli/dep-versions.js +1 -1
  6. package/dist/cli/doctor-codes.d.ts +5 -0
  7. package/dist/cli/doctor-codes.js +5 -0
  8. package/dist/cli/doctor.d.ts +1 -0
  9. package/dist/cli/doctor.js +86 -2
  10. package/dist/cli/extract/apply.js +1 -1
  11. package/dist/cli/extract/delegate.js +9 -1
  12. package/dist/cli/extract/extraction.d.ts +4 -0
  13. package/dist/cli/extract/extraction.js +29 -2
  14. package/dist/cli/extract/harness.d.ts +12 -0
  15. package/dist/cli/extract/harness.js +3 -0
  16. package/dist/cli/extract/stages.js +5 -1
  17. package/dist/cli/init-scaffolds.d.ts +10 -1
  18. package/dist/cli/init-scaffolds.js +93 -1
  19. package/dist/cli/init.d.ts +3 -3
  20. package/dist/cli/init.js +53 -5
  21. package/dist/cli/playground/app/fake-client.js +11 -5
  22. package/dist/cli/playground/app/main.js +23 -13
  23. package/dist/cli/playground/app/scenario-mount.js +4 -1
  24. package/dist/cli/playground/app/theme-editor.js +27 -27
  25. package/dist/cli/playground/bundle.gen.d.ts +1 -1
  26. package/dist/cli/playground/bundle.gen.js +1 -1
  27. package/dist/cli/playground/embed-bundle.gen.d.ts +1 -1
  28. package/dist/cli/playground/embed-bundle.gen.js +1 -1
  29. package/dist/cli/shared.d.ts +1 -1
  30. package/dist/cli/shared.js +1 -1
  31. package/dist/cli/sync.d.ts +1 -1
  32. package/dist/cli/sync.js +1 -1
  33. package/dist/cloud-apps.js +2 -1
  34. package/dist/cloud-key-fetch.d.ts +16 -0
  35. package/dist/cloud-key-fetch.js +40 -0
  36. package/dist/cloud-tools.js +2 -1
  37. package/dist/connections.js +2 -2
  38. package/dist/dev-creds/model-edge.d.ts +21 -0
  39. package/dist/dev-creds/model-edge.js +24 -0
  40. package/dist/hosted-store.js +2 -1
  41. package/dist/refine.js +2 -1
  42. package/dist/sandbox.js +2 -2
  43. package/dist/server.d.ts +1 -1
  44. package/dist/server.js +56 -22
  45. package/dist/wire/shared.d.ts +2 -2
  46. package/dist/wire/shared.js +1 -1
  47. package/package.json +20 -11
@@ -1,5 +1,5 @@
1
1
  import { type Telemetry } from "@vendoai/telemetry";
2
- export declare const CLI_VERSION = "0.4.3";
2
+ export declare const CLI_VERSION = "0.4.5";
3
3
  export interface Output {
4
4
  log(message: string): void;
5
5
  error(message: string): void;
@@ -4,7 +4,7 @@ import { dirname, join } from "node:path";
4
4
  import { createInterface } from "node:readline/promises";
5
5
  import { stdin, stdout } from "node:process";
6
6
  import { initTelemetry, repoHost } from "@vendoai/telemetry";
7
- export const CLI_VERSION = "0.4.3";
7
+ export const CLI_VERSION = "0.4.5";
8
8
  export const consoleOutput = {
9
9
  log: (message) => console.log(message),
10
10
  error: (message) => console.error(message),
@@ -1,4 +1,4 @@
1
- import { vendoSync, type SyncReportWithWarnings } from "@vendoai/actions";
1
+ import { vendoSync, type SyncReportWithWarnings } from "@vendoai/actions/sync";
2
2
  import type { ToolImpact } from "../sync-impact.js";
3
3
  import { type Output, type TelemetryOptions } from "./shared.js";
4
4
  export interface SyncReportPayload {
package/dist/cli/sync.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { join, resolve } from "node:path";
2
- import { vendoSync } from "@vendoai/actions";
2
+ import { vendoSync } from "@vendoai/actions/sync";
3
3
  import { pushSyncReport } from "./cloud/services.js";
4
4
  import { syncSemantics } from "./semantics.js";
5
5
  import { consoleOutput, withCommandRun } from "./shared.js";
@@ -1,5 +1,6 @@
1
1
  import { publishRecordSchema, shareSnapshotSchema, } from "@vendoai/apps";
2
2
  import { consoleSender, raiseCloudError } from "./cloud-console.js";
3
+ import { defaultFetch } from "@vendoai/core";
3
4
  const DEFAULT_TIMEOUT_MS = 30_000;
4
5
  /** The console mounts the share/publish surface here. */
5
6
  const CONSOLE_APPS_PATH = "/api/v1/apps";
@@ -17,7 +18,7 @@ export function cloudApps(options) {
17
18
  mountPath: CONSOLE_APPS_PATH,
18
19
  apiKey: options.apiKey,
19
20
  timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
20
- fetchImpl: options.fetch ?? globalThis.fetch,
21
+ fetchImpl: options.fetch ?? defaultFetch,
21
22
  raise: raiseAppsError,
22
23
  });
23
24
  const post = async (path, appId, doc, schema) => {
@@ -0,0 +1,16 @@
1
+ export interface CloudUrlOptions {
2
+ apiUrl?: string;
3
+ env?: Record<string, string | undefined>;
4
+ }
5
+ export declare function resolveCloudBaseUrl(options?: CloudUrlOptions): string;
6
+ export interface CloudKeyFetchOptions extends CloudUrlOptions {
7
+ apiKey?: string;
8
+ method?: string;
9
+ body?: unknown;
10
+ fetchImpl?: typeof fetch;
11
+ signal?: AbortSignal;
12
+ }
13
+ /** POST/GET a console API path with VENDO_API_KEY bearer auth. The console's
14
+ * shared auth middleware upserts deployment inventory and meters usage from
15
+ * the identity headers on real service calls (deployment-identity.ts). */
16
+ export declare function cloudKeyFetch<T = unknown>(path: string, options?: CloudKeyFetchOptions): Promise<T>;
@@ -0,0 +1,40 @@
1
+ /** Portable key-authenticated console calls for RUNTIME code (capability
2
+ * misses today). The CLI's cloudFetch adds user sessions, refresh, and disk
3
+ * state on top — Node-only concerns that used to ride into Worker bundles
4
+ * whenever runtime code borrowed it. Keep this module free of node builtins
5
+ * and CLI imports; the portability gate bundles it. */
6
+ import { defaultFetch } from "@vendoai/core";
7
+ import { deploymentIdentityHeaders } from "./deployment-identity.js";
8
+ import { VERSION } from "./wire/shared.js";
9
+ const DEFAULT_CLOUD_URL = "https://console.vendo.run";
10
+ const processEnv = () => globalThis.process?.env ?? {};
11
+ export function resolveCloudBaseUrl(options = {}) {
12
+ const value = options.apiUrl ?? (options.env ?? processEnv()).VENDO_CLOUD_URL ?? DEFAULT_CLOUD_URL;
13
+ return value.replace(/\/+$/, "");
14
+ }
15
+ /** POST/GET a console API path with VENDO_API_KEY bearer auth. The console's
16
+ * shared auth middleware upserts deployment inventory and meters usage from
17
+ * the identity headers on real service calls (deployment-identity.ts). */
18
+ export async function cloudKeyFetch(path, options = {}) {
19
+ const token = options.apiKey ?? (options.env ?? processEnv()).VENDO_API_KEY;
20
+ if (token === undefined || token === "") {
21
+ throw new Error("Vendo Cloud key call without a key: pass apiKey or set VENDO_API_KEY");
22
+ }
23
+ const headers = {
24
+ accept: "application/json",
25
+ authorization: `Bearer ${token}`,
26
+ "user-agent": `vendo-cli/${VERSION}`,
27
+ ...(options.body === undefined ? {} : { "content-type": "application/json" }),
28
+ ...(await deploymentIdentityHeaders()),
29
+ };
30
+ const response = await (options.fetchImpl ?? defaultFetch)(`${resolveCloudBaseUrl(options)}${path}`, {
31
+ method: options.method ?? (options.body === undefined ? "GET" : "POST"),
32
+ headers,
33
+ body: options.body === undefined ? undefined : JSON.stringify(options.body),
34
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
35
+ });
36
+ if (!response.ok) {
37
+ throw new Error(`Vendo Cloud ${path} answered ${response.status}`);
38
+ }
39
+ return await response.json();
40
+ }
@@ -1,5 +1,6 @@
1
1
  import { composioToolRisk, normalizeToolName } from "@vendoai/actions";
2
2
  import { deploymentIdentityHeaders } from "./deployment-identity.js";
3
+ import { defaultFetch } from "@vendoai/core";
3
4
  function errorOutcome(message) {
4
5
  return { status: "error", error: { code: "connector-error", message } };
5
6
  }
@@ -8,7 +9,7 @@ function withIdentity(outcome, identity) {
8
9
  }
9
10
  export function cloudTools(options) {
10
11
  const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
11
- const fetchImpl = options.fetch ?? globalThis.fetch;
12
+ const fetchImpl = options.fetch ?? defaultFetch;
12
13
  let normalizedToRaw = new Map();
13
14
  async function cloudFetch(path, init) {
14
15
  const response = await fetchImpl(`${base}${path}`, {
@@ -1,4 +1,4 @@
1
- import { VendoError } from "@vendoai/core";
1
+ import { defaultFetch, VendoError } from "@vendoai/core";
2
2
  import { consoleSender, raiseCloudError } from "./cloud-console.js";
3
3
  /** Subjects the runtime mints for machine principals (automations webhook
4
4
  * triggers today; the reserved `vendo:` namespace going forward). A synthetic
@@ -95,7 +95,7 @@ const raiseConnectionsError = (response) => raiseCloudError(response, "connectio
95
95
  * the wire it must serve. */
96
96
  export function cloudConnections(options) {
97
97
  const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
98
- const fetchImpl = options.fetch ?? globalThis.fetch;
98
+ const fetchImpl = options.fetch ?? defaultFetch;
99
99
  // The key-authed console sender (cloud-console.ts): Bearer auth + deployment
100
100
  // identity (the console meters usage from real traffic) + per-request abort
101
101
  // timeout, raising through the shared error table on any non-2xx.
@@ -0,0 +1,21 @@
1
+ /** Web-standard-runtime build of the dev credential ladder, selected by the
2
+ * package's `worker`/`workerd`/`edge-light`/`browser` import conditions
3
+ * (see `#dev-creds/model` in package.json).
4
+ *
5
+ * The real ladder is Node by design: it resolves the host's own @ai-sdk
6
+ * provider install via createRequire from the project root, reads `vendo
7
+ * login` sessions off disk, and anchors on process.cwd(). None of that
8
+ * exists inside a Worker bundle — Mohamed's field report had the ladder
9
+ * dying on runtime require.resolve under Wrangler even with VENDO_API_KEY
10
+ * set. On these runtimes the model seam is explicit by contract: the host
11
+ * wiring constructs the provider (init generates it; the Cloud gateway is
12
+ * the stock Anthropic provider pointed at the console). The ladder's edge
13
+ * build therefore resolves to honest guidance instead of half-working
14
+ * magic. Keep this module free of node builtins and CLI imports; the
15
+ * portability gate bundles it. */
16
+ import type { LanguageModel } from "ai";
17
+ import type { DevModelOptions } from "./model.js";
18
+ export type { DevModelOptions };
19
+ /** Same seam as the Node build; announces its unavailability once on first
20
+ * use through the server log, like the Node ladder's unavailable rung. */
21
+ export declare function devModel(_options?: DevModelOptions): LanguageModel;
@@ -0,0 +1,24 @@
1
+ const EDGE_MESSAGE = "the dev model ladder needs Node (it resolves the host's provider install and dev credentials from disk); "
2
+ + "on this runtime pass `model:` to createVendo explicitly — with a Vendo Cloud key that is the stock Anthropic "
3
+ + "provider pointed at the console gateway: createAnthropic({ apiKey: VENDO_API_KEY, baseURL: `${VENDO_CLOUD_URL ?? \"https://console.vendo.run\"}/api/v1` })(\"vendo-default\")";
4
+ /** Same seam as the Node build; announces its unavailability once on first
5
+ * use through the server log, like the Node ladder's unavailable rung. */
6
+ export function devModel(_options = {}) {
7
+ let announced = false;
8
+ const refuse = () => {
9
+ if (!announced) {
10
+ announced = true;
11
+ console.error(`[vendo] model: ${EDGE_MESSAGE}`);
12
+ }
13
+ throw new Error(EDGE_MESSAGE);
14
+ };
15
+ const model = {
16
+ specificationVersion: "v3",
17
+ provider: "vendo-dev",
18
+ modelId: "dev-env",
19
+ supportedUrls: {},
20
+ doGenerate: () => Promise.resolve().then(refuse),
21
+ doStream: () => Promise.resolve().then(refuse),
22
+ };
23
+ return model;
24
+ }
@@ -2,6 +2,7 @@ import { vendoRecordSchema, } from "@vendoai/core";
2
2
  import { DEDICATED_RECORD_COLLECTIONS, RESERVED_COLLECTIONS, } from "@vendoai/store";
3
3
  import { consoleSender, raiseCloudError, toArrayBuffer } from "./cloud-console.js";
4
4
  import { deploymentIdentityHeaders } from "./deployment-identity.js";
5
+ import { defaultFetch } from "@vendoai/core";
5
6
  /** The console mounts the hosted-store surface here
6
7
  * (apps/console/app/api/v1/store/*). */
7
8
  const CONSOLE_STORE_PATH = "/api/v1/store";
@@ -77,7 +78,7 @@ function parseNullableRecord(value) {
77
78
  export function hostedStore(options) {
78
79
  const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
79
80
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
80
- const fetchImpl = options.fetch ?? globalThis.fetch;
81
+ const fetchImpl = options.fetch ?? defaultFetch;
81
82
  const send = consoleSender({
82
83
  base,
83
84
  mountPath: CONSOLE_STORE_PATH,
package/dist/refine.js CHANGED
@@ -4,6 +4,7 @@ import { validateCapabilities, capabilitiesFileSchema, overridesFileSchema, tool
4
4
  import { TOOL_NAME_PATTERN, VENDO_CAPABILITIES_FORMAT, VENDO_OVERRIDES_FORMAT, capabilityMissEventSchema, } from "@vendoai/core";
5
5
  import { generateObject } from "ai";
6
6
  import { z } from "zod";
7
+ import { defaultFetch } from "@vendoai/core";
7
8
  /**
8
9
  * The refine engine (ENG-250, extraction spec §3). One engine, two surfaces:
9
10
  * the `vendo refine` CLI command and the end-of-init offer — both call
@@ -496,7 +497,7 @@ const stringify = (value) => `${JSON.stringify(value, null, 2)}\n`;
496
497
  // ---------------------------------------------------------------------------
497
498
  export async function runRefine(options) {
498
499
  const root = resolve(options.root);
499
- const fetchImpl = options.fetchImpl ?? fetch;
500
+ const fetchImpl = options.fetchImpl ?? defaultFetch;
500
501
  const interview = options.interview ?? [];
501
502
  const startedAt = new Date().toISOString();
502
503
  const inputs = await loadInputs(root, options);
package/dist/sandbox.js CHANGED
@@ -1,4 +1,4 @@
1
- import { VendoError } from "@vendoai/core";
1
+ import { defaultFetch, VendoError } from "@vendoai/core";
2
2
  import { deploymentIdentityHeaders } from "./deployment-identity.js";
3
3
  import { CLOUD_BOX_PORT, CLOUD_SANDBOX_PATH, CLOUD_SNAPSHOT_REF_PREFIX, CLOUD_SNAPSHOTS_SUBPATH, CONSOLE_SNAPSHOT_REF_PREFIX, } from "./sandbox-wire.js";
4
4
  /** Console error codes forwarded as-is when they are wire-legal VendoError
@@ -142,7 +142,7 @@ const isGone = (error) => error instanceof VendoError && error.code === "not-fou
142
142
  export function cloudSandbox(options) {
143
143
  const base = (options.baseUrl ?? "https://console.vendo.run").replace(/\/$/, "");
144
144
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
145
- const fetchImpl = options.fetch ?? globalThis.fetch;
145
+ const fetchImpl = options.fetch ?? defaultFetch;
146
146
  const send = async (path, init = {}) => {
147
147
  const response = await fetchImpl(`${base}${CLOUD_SANDBOX_PATH}${path}`, {
148
148
  ...init,
package/dist/server.d.ts CHANGED
@@ -11,7 +11,7 @@ export { createStore, envSecrets, secretStore, storeSecrets } from "@vendoai/sto
11
11
  export { hostAuthPresetConformance, type HostAuthPreset, type HostAuthPresetConformanceOptions, type HostAuthPresetOptions, type HostAuthPresetUser, type HostAuthPresetUserResolver, type SupabaseHostAuthPresetOptions, } from "./auth-presets/index.js";
12
12
  import type { HostAuthPreset } from "./auth-presets/index.js";
13
13
  import type { LanguageModel } from "ai";
14
- export { devModel, type DevModelOptions } from "./dev-creds/model.js";
14
+ export { devModel, type DevModelOptions } from "#dev-creds/model";
15
15
  import { type ConnectionsService } from "./connections.js";
16
16
  export { byoConnections, cloudConnections, unconfiguredConnections, type CloudConnectionsOptions, type ConnectionsService, } from "./connections.js";
17
17
  export { cloudSandbox, type CloudSandboxOptions } from "./sandbox.js";
package/dist/server.js CHANGED
@@ -28,11 +28,11 @@ import { createByoApprovals } from "./byo-approvals.js";
28
28
  import { initTelemetry } from "@vendoai/telemetry";
29
29
  import { capabilitySurfaceSnapshot, createCapabilityMissCapture, } from "./capability-misses.js";
30
30
  import { catalogThemeSummary, mergeRuntimeCatalog, normalizeCatalogConfig, runtimeCatalogFromJson } from "./catalog.js";
31
- import { devModel } from "./dev-creds/model.js";
31
+ import { devModel } from "#dev-creds/model";
32
32
  // install-dx v1 — `devModel()` is the env-resolving model createVendo composes
33
33
  // when the host passes none; the resolver is shared by init and doctor (one
34
34
  // credential story, real keys only).
35
- export { devModel } from "./dev-creds/model.js";
35
+ export { devModel } from "#dev-creds/model";
36
36
  import { byoConnections, cloudConnections, hasConnections, unconfiguredConnections, } from "./connections.js";
37
37
  // The shipped connections adapters ride the server surface so a host can pass
38
38
  // one explicitly via createVendo({ connections }) — see selectConnections.
@@ -594,7 +594,7 @@ function createWireHandler(deps) {
594
594
  // addressing a real Vendo WIRE route may (04 §4), and the door's paths are
595
595
  // the door's, not wire routes.
596
596
  if (deps.door !== undefined && isDoorPath(url.pathname)) {
597
- await deps.ready;
597
+ await deps.ready();
598
598
  return await deps.door.handler(request);
599
599
  }
600
600
  const path = relativePath(url);
@@ -606,7 +606,7 @@ function createWireHandler(deps) {
606
606
  if (jsonMutationRequired(request, path) && !isJsonRequest(request)) {
607
607
  throw new VendoError("validation", "content-type must be application/json");
608
608
  }
609
- await deps.ready;
609
+ await deps.ready();
610
610
  // The per-request view the route table dispatches on (kill-list B4).
611
611
  // Segments decode lazily so raw-matched pre-routes (proxy, webhooks,
612
612
  // doctor) never decode — preserving the old chain's decode timing.
@@ -688,10 +688,23 @@ export function createVendo(config) {
688
688
  // Inference, selected by the adapter rule at this composition seam
689
689
  // (selectModel above) — the one model the agent and apps blocks consume.
690
690
  const inference = selectModel(config.model);
691
- const ready = store.ensureSchema();
692
- // Keep eager schema readiness for hosts that reach into composed blocks,
693
- // while preventing an unhandled rejection before the first handler/emit awaits it.
694
- void ready.catch(() => undefined);
691
+ // Construction stays PURE — no I/O, no timers — because the common edge
692
+ // wiring calls createVendo() at module init, where Workers forbids both
693
+ // (Mohamed's field report: "Disallowed operation called within global
694
+ // scope"). The first handler/emit touch starts schema readiness and the
695
+ // background sweep together through this once-latch; on Node the first
696
+ // request pays the same cost the old eager kick merely front-loaded.
697
+ let startBackgroundSweep = () => undefined;
698
+ let readyState;
699
+ const ready = () => {
700
+ if (readyState === undefined) {
701
+ readyState = store.ensureSchema();
702
+ // No unhandled rejection before a handler/emit awaits the latch.
703
+ void readyState.catch(() => undefined);
704
+ startBackgroundSweep();
705
+ }
706
+ return readyState;
707
+ };
695
708
  let resolveAppToolRisk;
696
709
  const guard = createGuard({
697
710
  store,
@@ -1101,16 +1114,21 @@ export function createVendo(config) {
1101
1114
  // engine pattern) so an idle process still reclaims sessions with no traffic;
1102
1115
  // unref'd means it never keeps the event loop alive. Torn down with the store.
1103
1116
  if (sweepEnabled) {
1104
- const sweepTimer = setInterval(() => {
1105
- runSweep().catch((error) => {
1106
- console.warn(`[vendo] session sweep failed; will retry next interval: ${error instanceof Error ? error.message : String(error)}`);
1107
- });
1108
- }, sessionsConfig.sweepIntervalMs);
1109
- sweepTimer.unref?.();
1110
- const closeStore = store.close.bind(store);
1111
- store.close = async () => {
1112
- clearInterval(sweepTimer);
1113
- await closeStore();
1117
+ // Armed by the ready() latch above, NOT at construction: timers are
1118
+ // illegal in Workers global scope, and a process that never serves a
1119
+ // request has nothing to sweep.
1120
+ startBackgroundSweep = () => {
1121
+ const sweepTimer = setInterval(() => {
1122
+ runSweep().catch((error) => {
1123
+ console.warn(`[vendo] session sweep failed; will retry next interval: ${error instanceof Error ? error.message : String(error)}`);
1124
+ });
1125
+ }, sessionsConfig.sweepIntervalMs);
1126
+ sweepTimer.unref?.();
1127
+ const closeStore = store.close.bind(store);
1128
+ store.close = async () => {
1129
+ clearInterval(sweepTimer);
1130
+ await closeStore();
1131
+ };
1114
1132
  };
1115
1133
  }
1116
1134
  // Wave 2 (Cloud auto): a keyed deployment's schedule- and external-triggered
@@ -1196,7 +1214,11 @@ export function createVendo(config) {
1196
1214
  ...(theme === undefined ? {} : { theme }),
1197
1215
  });
1198
1216
  }
1199
- const sessionId = `session_${globalThis.crypto.randomUUID()}`;
1217
+ // Minted on first request via the deps getter below — Workers forbids
1218
+ // generating random values in global scope, and createVendo runs at module
1219
+ // init in the edge wiring. Still one fallback id per process.
1220
+ let processSessionId;
1221
+ const sessionId = () => (processSessionId ??= `session_${globalThis.crypto.randomUUID()}`);
1200
1222
  // Anonymous principals are minted per-CLIENT in the handler (opaque cookie
1201
1223
  // pointer; the store's vendo_sessions row is the authority — kill-list B3).
1202
1224
  // An https VENDO_BASE_URL means TLS terminates at a trusted proxy and requests
@@ -1220,7 +1242,7 @@ export function createVendo(config) {
1220
1242
  principal: resolvePrincipal,
1221
1243
  ready,
1222
1244
  trustedBaseIsHttps,
1223
- sessionId,
1245
+ get sessionId() { return sessionId(); },
1224
1246
  store,
1225
1247
  telemetry: telemetryClient(config.telemetry),
1226
1248
  agent,
@@ -1267,12 +1289,24 @@ export function createVendo(config) {
1267
1289
  return {
1268
1290
  handler,
1269
1291
  async emit(event, payload, principal) {
1270
- await ready;
1292
+ await ready();
1271
1293
  return automations.emit(event, payload, principal);
1272
1294
  },
1273
1295
  agent,
1274
1296
  guard,
1275
- guardedTools: byoApprovals.registry,
1297
+ // The BYO seam (ai-sdk.ts / mastra.ts tool packs) reaches the store
1298
+ // without ever touching handler/emit, so its execute leg arms the same
1299
+ // ready() latch — the composed-block head start the old eager kick gave
1300
+ // such hosts, without the construction-time I/O Workers forbids. Direct
1301
+ // vendo.store/automations reach-ins still own their readiness (await
1302
+ // store.ensureSchema(), as the mastra example and defer tests do).
1303
+ guardedTools: {
1304
+ ...byoApprovals.registry,
1305
+ execute: async (call, ctx) => {
1306
+ await ready();
1307
+ return byoApprovals.registry.execute(call, ctx);
1308
+ },
1309
+ },
1276
1310
  apps,
1277
1311
  automations,
1278
1312
  actions,
@@ -14,7 +14,7 @@ import type { RuntimeCaptureHandler } from "../runtime-capture.js";
14
14
  shares. The anonymous-session + RunContext resolution lives in
15
15
  wire/context.ts; server.ts assembles the table from the per-area modules
16
16
  under src/wire/. */
17
- export declare const VERSION = "0.4.3";
17
+ export declare const VERSION = "0.4.5";
18
18
  export declare const BASE_PATH = "/api/vendo";
19
19
  export type SandboxVenue = "e2b" | "cloud" | "custom" | false;
20
20
  /** How inference is served: "custom" (a host-passed model) or "ladder" (the
@@ -24,7 +24,7 @@ export type SandboxVenue = "e2b" | "cloud" | "custom" | false;
24
24
  export type ModelVenue = "custom" | "ladder";
25
25
  export interface WireDeps {
26
26
  principal: (req: Request) => Promise<Principal | null>;
27
- ready: Promise<void>;
27
+ ready: () => Promise<void>;
28
28
  /** VENDO_BASE_URL is https → TLS terminates upstream; see secureRequest. */
29
29
  trustedBaseIsHttps: boolean;
30
30
  sessionId: string;
@@ -4,7 +4,7 @@ import { VendoError, } from "@vendoai/core";
4
4
  shares. The anonymous-session + RunContext resolution lives in
5
5
  wire/context.ts; server.ts assembles the table from the per-area modules
6
6
  under src/wire/. */
7
- export const VERSION = "0.4.3";
7
+ export const VERSION = "0.4.5";
8
8
  export const BASE_PATH = "/api/vendo";
9
9
  const STATUS_BY_CODE = {
10
10
  validation: 400,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vendoai/vendo",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "The Vendo umbrella: default composition, public wire routes, React provider, and the vendo CLI.",
5
5
  "keywords": [
6
6
  "ai",
@@ -86,16 +86,16 @@
86
86
  "ajv": "^8.20.0",
87
87
  "ajv-formats": "^3.0.1",
88
88
  "zod": "^3.25.0",
89
- "@vendoai/actions": "0.4.3",
90
- "@vendoai/apps": "0.4.3",
91
- "@vendoai/automations": "0.4.3",
92
- "@vendoai/agent": "0.4.3",
93
- "@vendoai/core": "0.4.3",
94
- "@vendoai/guard": "0.4.3",
95
- "@vendoai/telemetry": "0.3.1",
96
- "@vendoai/ui": "0.4.3",
97
- "@vendoai/mcp": "0.4.3",
98
- "@vendoai/store": "0.4.3"
89
+ "@vendoai/apps": "0.4.5",
90
+ "@vendoai/automations": "0.4.5",
91
+ "@vendoai/guard": "0.4.5",
92
+ "@vendoai/agent": "0.4.5",
93
+ "@vendoai/mcp": "0.4.5",
94
+ "@vendoai/store": "0.4.5",
95
+ "@vendoai/telemetry": "0.3.2",
96
+ "@vendoai/core": "0.4.5",
97
+ "@vendoai/ui": "0.4.5",
98
+ "@vendoai/actions": "0.4.5"
99
99
  },
100
100
  "peerDependencies": {
101
101
  "@auth/core": "^0.34.3",
@@ -137,6 +137,15 @@
137
137
  "vite": "^6.0.0",
138
138
  "vitest": "^2.1.0"
139
139
  },
140
+ "imports": {
141
+ "#dev-creds/model": {
142
+ "workerd": "./dist/dev-creds/model-edge.js",
143
+ "worker": "./dist/dev-creds/model-edge.js",
144
+ "edge-light": "./dist/dev-creds/model-edge.js",
145
+ "browser": "./dist/dev-creds/model-edge.js",
146
+ "default": "./dist/dev-creds/model.js"
147
+ }
148
+ },
140
149
  "scripts": {
141
150
  "build:playground": "node scripts/build-playground.mjs",
142
151
  "prebuild": "pnpm run build:playground",