@vendoai/vendo 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/cloud/device-login.js +13 -10
- package/dist/cli/cloud/pending-claim.d.ts +6 -3
- package/dist/cli/cloud/pending-claim.js +32 -8
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.js +11 -0
- package/dist/cli/provider-deps.d.ts +26 -0
- package/dist/cli/provider-deps.js +100 -0
- package/dist/cli/shared.d.ts +1 -1
- package/dist/cli/shared.js +1 -1
- package/dist/wire/shared.d.ts +1 -1
- package/dist/wire/shared.js +1 -1
- package/package.json +10 -10
|
@@ -91,13 +91,16 @@ export async function runDeviceLogin(args, options = {}) {
|
|
|
91
91
|
const waitSeconds = waitRaw !== undefined && /^\d+$/.test(waitRaw) ? Number(waitRaw) : undefined;
|
|
92
92
|
const waitMs = waitSeconds === undefined ? undefined : waitSeconds * 1000;
|
|
93
93
|
const pendingHome = options.home === undefined ? {} : { home: options.home };
|
|
94
|
+
const claimCwd = options.root ?? process.cwd();
|
|
94
95
|
try {
|
|
95
96
|
// A still-open claim from a dead process (#479): resume polling it so the
|
|
96
97
|
// human's late approval — against the code they were already shown —
|
|
97
|
-
// still lands the key.
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
// still lands the key. Claims are scoped per project directory (0.4.2):
|
|
99
|
+
// only THIS cwd's ceremony is ever resumed, so concurrent logins in other
|
|
100
|
+
// repos neither clobber this one nor get resumed by it. An expired or
|
|
101
|
+
// unreadable file is discarded (a fresh ceremony overwrites it below).
|
|
102
|
+
const pending = await readPendingClaim(claimCwd, pendingHome);
|
|
103
|
+
const resume = pending !== null && pending.api_url === base && pending.cwd === claimCwd && pending.expires_at > now()
|
|
101
104
|
? pending
|
|
102
105
|
: null;
|
|
103
106
|
let claimToken;
|
|
@@ -174,7 +177,7 @@ export async function runDeviceLogin(args, options = {}) {
|
|
|
174
177
|
throw new Error("Vendo Cloud returned an invalid credential");
|
|
175
178
|
}
|
|
176
179
|
await upsertEnvLocal(root, "VENDO_API_KEY", key);
|
|
177
|
-
await deletePendingClaim(pendingHome);
|
|
180
|
+
await deletePendingClaim(claimCwd, pendingHome);
|
|
178
181
|
// Never print the key itself — .env.local is the hand-off, last4 the
|
|
179
182
|
// receipt. A resumed run names the full path: it may differ from cwd.
|
|
180
183
|
output.log(`Approved — wrote VENDO_API_KEY (…${key.slice(-4)}) to ${resume !== null ? join(root, ".env.local") : ".env.local"}.`);
|
|
@@ -190,11 +193,11 @@ export async function runDeviceLogin(args, options = {}) {
|
|
|
190
193
|
if (error === "slow_down")
|
|
191
194
|
return "slow_down"; // RFC 8628 §3.5
|
|
192
195
|
if (error === "expired_token") {
|
|
193
|
-
await deletePendingClaim(pendingHome);
|
|
196
|
+
await deletePendingClaim(claimCwd, pendingHome);
|
|
194
197
|
throw new Error("The code expired before it was approved; run `vendo login` again.");
|
|
195
198
|
}
|
|
196
199
|
if (error === "access_denied") {
|
|
197
|
-
await deletePendingClaim(pendingHome);
|
|
200
|
+
await deletePendingClaim(claimCwd, pendingHome);
|
|
198
201
|
throw new Error("Your human denied the request — no key was minted.");
|
|
199
202
|
}
|
|
200
203
|
// Any other token error is terminal for THIS claim (invalid_grant =
|
|
@@ -202,7 +205,7 @@ export async function runDeviceLogin(args, options = {}) {
|
|
|
202
205
|
// again). Delete the pending file so the next `vendo login` opens a
|
|
203
206
|
// fresh claim instead of resuming into the same error forever — the
|
|
204
207
|
// exact trap a live install hit.
|
|
205
|
-
await deletePendingClaim(pendingHome);
|
|
208
|
+
await deletePendingClaim(claimCwd, pendingHome);
|
|
206
209
|
const description = poll.body?.error_description;
|
|
207
210
|
throw new Error(typeof description === "string"
|
|
208
211
|
? description
|
|
@@ -230,7 +233,7 @@ export async function runDeviceLogin(args, options = {}) {
|
|
|
230
233
|
if (result === "slow_down")
|
|
231
234
|
intervalMs += 5000;
|
|
232
235
|
}
|
|
233
|
-
await deletePendingClaim(pendingHome);
|
|
236
|
+
await deletePendingClaim(claimCwd, pendingHome);
|
|
234
237
|
throw new Error("The code expired before it was approved; run `vendo login` again.");
|
|
235
238
|
}
|
|
236
239
|
// Bounded budget: poll immediately, then pace by interval, stopping at
|
|
@@ -243,7 +246,7 @@ export async function runDeviceLogin(args, options = {}) {
|
|
|
243
246
|
if (result === "slow_down")
|
|
244
247
|
intervalMs += 5000;
|
|
245
248
|
if (now() >= deadline) {
|
|
246
|
-
await deletePendingClaim(pendingHome);
|
|
249
|
+
await deletePendingClaim(claimCwd, pendingHome);
|
|
247
250
|
throw new Error("The code expired before it was approved; run `vendo login` again.");
|
|
248
251
|
}
|
|
249
252
|
if (now() >= pollDeadline)
|
|
@@ -23,7 +23,10 @@ export interface PendingClaimOptions {
|
|
|
23
23
|
home?: string;
|
|
24
24
|
}
|
|
25
25
|
/** An unreadable or malformed file reads as "no pending claim" — the caller
|
|
26
|
-
discards it by opening (and persisting) a fresh ceremony.
|
|
27
|
-
|
|
26
|
+
discards it by opening (and persisting) a fresh ceremony. Only a claim
|
|
27
|
+
opened for THIS cwd is ever returned. A pre-0.4.2 machine-global file is
|
|
28
|
+
honored (and migrated) only when its recorded cwd matches; someone else's
|
|
29
|
+
ceremony is never resumed. */
|
|
30
|
+
export declare function readPendingClaim(cwd: string, options?: PendingClaimOptions): Promise<PendingClaim | null>;
|
|
28
31
|
export declare function writePendingClaim(claim: PendingClaim, options?: PendingClaimOptions): Promise<void>;
|
|
29
|
-
export declare function deletePendingClaim(options?: PendingClaimOptions): Promise<void>;
|
|
32
|
+
export declare function deletePendingClaim(cwd: string, options?: PendingClaimOptions): Promise<void>;
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
4
|
import { join } from "node:path";
|
|
4
|
-
|
|
5
|
+
/** Claims are keyed by the project directory they were opened for. A single
|
|
6
|
+
machine-global file let two concurrent `vendo login` runs clobber each
|
|
7
|
+
other, and let project A resume (and receive the key for) project B's
|
|
8
|
+
ceremony — found by the 0.4.1 E2E certification campaign. */
|
|
9
|
+
function pendingClaimPath(cwd, options = {}) {
|
|
10
|
+
const name = `${createHash("sha256").update(cwd).digest("hex").slice(0, 16)}.json`;
|
|
11
|
+
return join(options.home ?? homedir(), ".vendo", "pending-claims", name);
|
|
12
|
+
}
|
|
13
|
+
/** The pre-0.4.2 machine-global location — read once for migration. */
|
|
14
|
+
function legacyPendingClaimPath(options = {}) {
|
|
5
15
|
return join(options.home ?? homedir(), ".vendo", "pending-claim.json");
|
|
6
16
|
}
|
|
7
17
|
function isPendingClaim(value) {
|
|
@@ -16,23 +26,37 @@ function isPendingClaim(value) {
|
|
|
16
26
|
&& typeof claim.api_url === "string"
|
|
17
27
|
&& typeof claim.cwd === "string";
|
|
18
28
|
}
|
|
19
|
-
|
|
20
|
-
discards it by opening (and persisting) a fresh ceremony. */
|
|
21
|
-
export async function readPendingClaim(options = {}) {
|
|
29
|
+
async function readClaimFile(path) {
|
|
22
30
|
try {
|
|
23
|
-
const value = JSON.parse(await readFile(
|
|
31
|
+
const value = JSON.parse(await readFile(path, "utf8"));
|
|
24
32
|
return isPendingClaim(value) ? value : null;
|
|
25
33
|
}
|
|
26
34
|
catch {
|
|
27
35
|
return null;
|
|
28
36
|
}
|
|
29
37
|
}
|
|
38
|
+
/** An unreadable or malformed file reads as "no pending claim" — the caller
|
|
39
|
+
discards it by opening (and persisting) a fresh ceremony. Only a claim
|
|
40
|
+
opened for THIS cwd is ever returned. A pre-0.4.2 machine-global file is
|
|
41
|
+
honored (and migrated) only when its recorded cwd matches; someone else's
|
|
42
|
+
ceremony is never resumed. */
|
|
43
|
+
export async function readPendingClaim(cwd, options = {}) {
|
|
44
|
+
const scoped = await readClaimFile(pendingClaimPath(cwd, options));
|
|
45
|
+
if (scoped !== null)
|
|
46
|
+
return scoped.cwd === cwd ? scoped : null;
|
|
47
|
+
const legacy = await readClaimFile(legacyPendingClaimPath(options));
|
|
48
|
+
if (legacy === null || legacy.cwd !== cwd)
|
|
49
|
+
return null;
|
|
50
|
+
await writePendingClaim(legacy, options);
|
|
51
|
+
await rm(legacyPendingClaimPath(options), { force: true });
|
|
52
|
+
return legacy;
|
|
53
|
+
}
|
|
30
54
|
export async function writePendingClaim(claim, options = {}) {
|
|
31
|
-
const path = pendingClaimPath(options);
|
|
55
|
+
const path = pendingClaimPath(claim.cwd, options);
|
|
32
56
|
await mkdir(join(path, ".."), { recursive: true, mode: 0o700 });
|
|
33
57
|
await writeFile(path, `${JSON.stringify(claim, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
34
58
|
await chmod(path, 0o600);
|
|
35
59
|
}
|
|
36
|
-
export async function deletePendingClaim(options = {}) {
|
|
37
|
-
await rm(pendingClaimPath(options), { force: true });
|
|
60
|
+
export async function deletePendingClaim(cwd, options = {}) {
|
|
61
|
+
await rm(pendingClaimPath(cwd, options), { force: true });
|
|
38
62
|
}
|
package/dist/cli/init.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { type AiExtractionOptions } from "./extract/extraction.js";
|
|
|
4
4
|
import { type DevCredential } from "../dev-creds/resolve.js";
|
|
5
5
|
import { type HostFramework } from "./framework.js";
|
|
6
6
|
import { type AuthPresetName } from "./init-auth.js";
|
|
7
|
+
import { type InstallRunner } from "./provider-deps.js";
|
|
7
8
|
import { type SelectOption } from "./pretty.js";
|
|
8
9
|
import { type ThemeSummary } from "./theme/extract-theme.js";
|
|
9
10
|
import { type Output } from "./shared.js";
|
|
@@ -76,6 +77,8 @@ export interface InitOptions {
|
|
|
76
77
|
resolveCredential?: (options: {
|
|
77
78
|
env: Record<string, string | undefined>;
|
|
78
79
|
}) => Promise<DevCredential>;
|
|
80
|
+
/** Test seam: the provider-dependency install subprocess (provider-deps.ts). */
|
|
81
|
+
installProvider?: InstallRunner;
|
|
79
82
|
/** Test seam (ENG-339): cloud-in-init step overrides. */
|
|
80
83
|
cloud?: Partial<Omit<CloudStepOptions, "root" | "output" | "yes" | "credential">>;
|
|
81
84
|
/** Test seam: AI extraction step overrides (harnesses, consent). */
|
package/dist/cli/init.js
CHANGED
|
@@ -14,6 +14,7 @@ import { BRIEF_TEMPLATE } from "./extract/stages.js";
|
|
|
14
14
|
import { ENV_KEY_VARS, resolveDevCredential, describeDevCredential } from "../dev-creds/resolve.js";
|
|
15
15
|
import { detectFramework, detectVendoWiring } from "./framework.js";
|
|
16
16
|
import { resolveScaffoldAuth } from "./init-auth.js";
|
|
17
|
+
import { ensureProviderDeps } from "./provider-deps.js";
|
|
17
18
|
import { expressServerSource, registrySource, routeSource, serverActionsModuleSource, VENDO_ENV_EXAMPLE, wiringServerActions, } from "./init-scaffolds.js";
|
|
18
19
|
import { createPrettyOutput, plainSelect, usePrettyOutput } from "./pretty.js";
|
|
19
20
|
import { contrastingText } from "./theme/color.js";
|
|
@@ -927,6 +928,16 @@ export async function runInit(options) {
|
|
|
927
928
|
wiringMs,
|
|
928
929
|
...(await cloudProjectProps(root)),
|
|
929
930
|
});
|
|
931
|
+
// The credential's runtime provider must be resolvable from the host or
|
|
932
|
+
// the FIRST turn 500s (dev-creds/model.ts loads it host-side; nothing
|
|
933
|
+
// declares @ai-sdk/* — 0.4.1 E2E cert finding). Install exactly what the
|
|
934
|
+
// resolved credential needs; a failure degrades to the manual command.
|
|
935
|
+
await ensureProviderDeps({
|
|
936
|
+
root,
|
|
937
|
+
credential,
|
|
938
|
+
output,
|
|
939
|
+
...(options.installProvider === undefined ? {} : { run: options.installProvider }),
|
|
940
|
+
});
|
|
930
941
|
// The one short Cloud reminder in the end-of-run summary — ONLY while no
|
|
931
942
|
// key exists (the full emphasized block already ran up top; no repeat).
|
|
932
943
|
if (credential.rung === "none") {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DevCredential } from "../dev-creds/resolve.js";
|
|
2
|
+
import type { Output } from "./shared.js";
|
|
3
|
+
/** Which provider module the resolved credential will load at runtime.
|
|
4
|
+
The Vendo Cloud gateway speaks the Anthropic-compatible /messages API
|
|
5
|
+
through the host-installed @ai-sdk/anthropic (dev-creds/model.ts). */
|
|
6
|
+
export declare function providerModuleFor(credential: DevCredential): {
|
|
7
|
+
module: string;
|
|
8
|
+
spec: string;
|
|
9
|
+
} | null;
|
|
10
|
+
/** Lockfile-sniffed installer; npm is the fallback. */
|
|
11
|
+
export declare function installCommandFor(root: string): Promise<{
|
|
12
|
+
command: string;
|
|
13
|
+
args: string[];
|
|
14
|
+
}>;
|
|
15
|
+
/** Test seam: resolves to the child's exit code (null on spawn error). */
|
|
16
|
+
export type InstallRunner = (command: string, args: string[], cwd: string) => Promise<number | null>;
|
|
17
|
+
export interface EnsureProviderDepsOptions {
|
|
18
|
+
root: string;
|
|
19
|
+
credential: DevCredential;
|
|
20
|
+
output: Output;
|
|
21
|
+
run?: InstallRunner;
|
|
22
|
+
}
|
|
23
|
+
/** Installs `ai@^6` + the credential's provider when the host can't resolve
|
|
24
|
+
them. Never fatal: a failed install degrades to the exact manual command
|
|
25
|
+
(the same one doctor's E-DEP-001 story names). */
|
|
26
|
+
export declare function ensureProviderDeps(options: EnsureProviderDepsOptions): Promise<void>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* The starter model ladder resolves its provider from the HOST's
|
|
6
|
+
* node_modules at runtime (dev-creds/model.ts) — nothing declares
|
|
7
|
+
* `@ai-sdk/*` as a dependency, so a fresh install 500s on the first turn
|
|
8
|
+
* until the user reads the dev-server error and installs it by hand (0.4.1
|
|
9
|
+
* E2E certification finding). Init knows the resolved credential, so it can
|
|
10
|
+
* install exactly the provider that credential needs, up front.
|
|
11
|
+
*/
|
|
12
|
+
const PROVIDER_SPECS = {
|
|
13
|
+
anthropic: { module: "@ai-sdk/anthropic", spec: "@ai-sdk/anthropic@^3" },
|
|
14
|
+
openai: { module: "@ai-sdk/openai", spec: "@ai-sdk/openai@^3" },
|
|
15
|
+
google: { module: "@ai-sdk/google", spec: "@ai-sdk/google@^3" },
|
|
16
|
+
};
|
|
17
|
+
const AI_SPEC = "ai@^6";
|
|
18
|
+
/** Which provider module the resolved credential will load at runtime.
|
|
19
|
+
The Vendo Cloud gateway speaks the Anthropic-compatible /messages API
|
|
20
|
+
through the host-installed @ai-sdk/anthropic (dev-creds/model.ts). */
|
|
21
|
+
export function providerModuleFor(credential) {
|
|
22
|
+
if (credential.rung === "env-key")
|
|
23
|
+
return PROVIDER_SPECS[credential.provider];
|
|
24
|
+
if (credential.rung === "vendo-cloud")
|
|
25
|
+
return PROVIDER_SPECS.anthropic;
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
/** Resolvability is what the runtime ladder checks, so node_modules is the
|
|
29
|
+
evidence — not package.json (a hoisting monorepo satisfies the import
|
|
30
|
+
without a local entry). */
|
|
31
|
+
async function isInstalled(root, moduleName) {
|
|
32
|
+
try {
|
|
33
|
+
await readFile(join(root, "node_modules", ...moduleName.split("/"), "package.json"), "utf8");
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function fileExists(root, name) {
|
|
41
|
+
try {
|
|
42
|
+
await readFile(join(root, name));
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Lockfile-sniffed installer; npm is the fallback. */
|
|
50
|
+
export async function installCommandFor(root) {
|
|
51
|
+
if (await fileExists(root, "pnpm-lock.yaml"))
|
|
52
|
+
return { command: "pnpm", args: ["add"] };
|
|
53
|
+
if (await fileExists(root, "yarn.lock"))
|
|
54
|
+
return { command: "yarn", args: ["add"] };
|
|
55
|
+
if ((await fileExists(root, "bun.lockb")) || (await fileExists(root, "bun.lock"))) {
|
|
56
|
+
return { command: "bun", args: ["add"] };
|
|
57
|
+
}
|
|
58
|
+
return { command: "npm", args: ["install"] };
|
|
59
|
+
}
|
|
60
|
+
const INSTALL_TIMEOUT_MS = 240_000;
|
|
61
|
+
const defaultRunner = (command, args, cwd) => new Promise((resolve) => {
|
|
62
|
+
const child = spawn(command, args, { cwd, stdio: "ignore" });
|
|
63
|
+
const timer = setTimeout(() => {
|
|
64
|
+
child.kill();
|
|
65
|
+
resolve(null);
|
|
66
|
+
}, INSTALL_TIMEOUT_MS);
|
|
67
|
+
child.on("error", () => {
|
|
68
|
+
clearTimeout(timer);
|
|
69
|
+
resolve(null);
|
|
70
|
+
});
|
|
71
|
+
child.on("exit", (code) => {
|
|
72
|
+
clearTimeout(timer);
|
|
73
|
+
resolve(code);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
/** Installs `ai@^6` + the credential's provider when the host can't resolve
|
|
77
|
+
them. Never fatal: a failed install degrades to the exact manual command
|
|
78
|
+
(the same one doctor's E-DEP-001 story names). */
|
|
79
|
+
export async function ensureProviderDeps(options) {
|
|
80
|
+
const provider = providerModuleFor(options.credential);
|
|
81
|
+
if (provider === null)
|
|
82
|
+
return;
|
|
83
|
+
const specs = [];
|
|
84
|
+
if (!(await isInstalled(options.root, "ai")))
|
|
85
|
+
specs.push(AI_SPEC);
|
|
86
|
+
if (!(await isInstalled(options.root, provider.module)))
|
|
87
|
+
specs.push(provider.spec);
|
|
88
|
+
if (specs.length === 0)
|
|
89
|
+
return;
|
|
90
|
+
const { command, args } = await installCommandFor(options.root);
|
|
91
|
+
const invocation = `${command} ${[...args, ...specs].join(" ")}`;
|
|
92
|
+
options.output.log(`Installing the model provider this credential uses: ${specs.join(" ")} (${command})…`);
|
|
93
|
+
const code = await (options.run ?? defaultRunner)(command, [...args, ...specs], options.root);
|
|
94
|
+
if (code === 0) {
|
|
95
|
+
options.output.log(`Installed ${specs.join(" ")}.`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
options.output.error(`warning: could not install ${specs.join(" ")} — run \`${invocation}\` yourself before the first turn, or it fails at runtime (E-DEP-001).`);
|
|
99
|
+
}
|
|
100
|
+
}
|
package/dist/cli/shared.d.ts
CHANGED
package/dist/cli/shared.js
CHANGED
|
@@ -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.
|
|
7
|
+
export const CLI_VERSION = "0.4.2";
|
|
8
8
|
export const consoleOutput = {
|
|
9
9
|
log: (message) => console.log(message),
|
|
10
10
|
error: (message) => console.error(message),
|
package/dist/wire/shared.d.ts
CHANGED
|
@@ -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.
|
|
17
|
+
export declare const VERSION = "0.4.2";
|
|
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
|
package/dist/wire/shared.js
CHANGED
|
@@ -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.
|
|
7
|
+
export const VERSION = "0.4.2";
|
|
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
|
+
"version": "0.4.2",
|
|
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.
|
|
90
|
-
"@vendoai/
|
|
91
|
-
"@vendoai/
|
|
92
|
-
"@vendoai/
|
|
93
|
-
"@vendoai/
|
|
94
|
-
"@vendoai/
|
|
95
|
-
"@vendoai/mcp": "0.4.
|
|
89
|
+
"@vendoai/actions": "0.4.2",
|
|
90
|
+
"@vendoai/apps": "0.4.2",
|
|
91
|
+
"@vendoai/automations": "0.4.2",
|
|
92
|
+
"@vendoai/agent": "0.4.2",
|
|
93
|
+
"@vendoai/core": "0.4.2",
|
|
94
|
+
"@vendoai/guard": "0.4.2",
|
|
95
|
+
"@vendoai/mcp": "0.4.2",
|
|
96
|
+
"@vendoai/store": "0.4.2",
|
|
96
97
|
"@vendoai/telemetry": "0.3.1",
|
|
97
|
-
"@vendoai/
|
|
98
|
-
"@vendoai/ui": "0.4.1"
|
|
98
|
+
"@vendoai/ui": "0.4.2"
|
|
99
99
|
},
|
|
100
100
|
"peerDependencies": {
|
|
101
101
|
"@auth/core": "^0.34.3",
|