@vendoai/vendo 0.4.0

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 (212) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +28 -0
  3. package/bin/vendo.mjs +4 -0
  4. package/dist/ai-sdk.d.ts +35 -0
  5. package/dist/ai-sdk.js +62 -0
  6. package/dist/auth-presets/auth-js.d.ts +14 -0
  7. package/dist/auth-presets/auth-js.js +91 -0
  8. package/dist/auth-presets/auth0.d.ts +23 -0
  9. package/dist/auth-presets/auth0.js +98 -0
  10. package/dist/auth-presets/clerk.d.ts +23 -0
  11. package/dist/auth-presets/clerk.js +65 -0
  12. package/dist/auth-presets/conformance.d.ts +42 -0
  13. package/dist/auth-presets/conformance.js +139 -0
  14. package/dist/auth-presets/identity.d.ts +56 -0
  15. package/dist/auth-presets/identity.js +152 -0
  16. package/dist/auth-presets/index.d.ts +14 -0
  17. package/dist/auth-presets/index.js +12 -0
  18. package/dist/auth-presets/jwt.d.ts +16 -0
  19. package/dist/auth-presets/jwt.js +54 -0
  20. package/dist/auth-presets/shared.d.ts +35 -0
  21. package/dist/auth-presets/shared.js +1 -0
  22. package/dist/auth-presets/supabase.d.ts +42 -0
  23. package/dist/auth-presets/supabase.js +229 -0
  24. package/dist/byo-approvals.d.ts +37 -0
  25. package/dist/byo-approvals.js +189 -0
  26. package/dist/capability-misses.d.ts +38 -0
  27. package/dist/capability-misses.js +172 -0
  28. package/dist/catalog.d.ts +19 -0
  29. package/dist/catalog.js +152 -0
  30. package/dist/cli/cloud/args.d.ts +3 -0
  31. package/dist/cli/cloud/args.js +32 -0
  32. package/dist/cli/cloud/auth.d.ts +17 -0
  33. package/dist/cli/cloud/auth.js +123 -0
  34. package/dist/cli/cloud/client.d.ts +28 -0
  35. package/dist/cli/cloud/client.js +133 -0
  36. package/dist/cli/cloud/command.d.ts +22 -0
  37. package/dist/cli/cloud/command.js +73 -0
  38. package/dist/cli/cloud/deploy.d.ts +26 -0
  39. package/dist/cli/cloud/deploy.js +187 -0
  40. package/dist/cli/cloud/device-login.d.ts +32 -0
  41. package/dist/cli/cloud/device-login.js +259 -0
  42. package/dist/cli/cloud/index.d.ts +5 -0
  43. package/dist/cli/cloud/index.js +59 -0
  44. package/dist/cli/cloud/keys.d.ts +2 -0
  45. package/dist/cli/cloud/keys.js +31 -0
  46. package/dist/cli/cloud/members.d.ts +3 -0
  47. package/dist/cli/cloud/members.js +25 -0
  48. package/dist/cli/cloud/output.d.ts +4 -0
  49. package/dist/cli/cloud/output.js +12 -0
  50. package/dist/cli/cloud/pending-claim.d.ts +29 -0
  51. package/dist/cli/cloud/pending-claim.js +38 -0
  52. package/dist/cli/cloud/read.d.ts +3 -0
  53. package/dist/cli/cloud/read.js +12 -0
  54. package/dist/cli/cloud/services.d.ts +2 -0
  55. package/dist/cli/cloud/services.js +9 -0
  56. package/dist/cli/cloud/session.d.ts +13 -0
  57. package/dist/cli/cloud/session.js +41 -0
  58. package/dist/cli/cloud-init.d.ts +60 -0
  59. package/dist/cli/cloud-init.js +149 -0
  60. package/dist/cli/dep-versions.d.ts +26 -0
  61. package/dist/cli/dep-versions.js +77 -0
  62. package/dist/cli/doctor-codes.d.ts +58 -0
  63. package/dist/cli/doctor-codes.js +60 -0
  64. package/dist/cli/doctor-live.d.ts +67 -0
  65. package/dist/cli/doctor-live.js +169 -0
  66. package/dist/cli/doctor.d.ts +52 -0
  67. package/dist/cli/doctor.js +467 -0
  68. package/dist/cli/eject.d.ts +29 -0
  69. package/dist/cli/eject.js +141 -0
  70. package/dist/cli/extract/apply.d.ts +26 -0
  71. package/dist/cli/extract/apply.js +123 -0
  72. package/dist/cli/extract/claude-cli-harness.d.ts +18 -0
  73. package/dist/cli/extract/claude-cli-harness.js +132 -0
  74. package/dist/cli/extract/claude-harness.d.ts +14 -0
  75. package/dist/cli/extract/claude-harness.js +127 -0
  76. package/dist/cli/extract/codex-cli-harness.d.ts +31 -0
  77. package/dist/cli/extract/codex-cli-harness.js +154 -0
  78. package/dist/cli/extract/delegate.d.ts +21 -0
  79. package/dist/cli/extract/delegate.js +77 -0
  80. package/dist/cli/extract/extraction.d.ts +65 -0
  81. package/dist/cli/extract/extraction.js +300 -0
  82. package/dist/cli/extract/gateway-fuel.d.ts +69 -0
  83. package/dist/cli/extract/gateway-fuel.js +69 -0
  84. package/dist/cli/extract/harness.d.ts +114 -0
  85. package/dist/cli/extract/harness.js +84 -0
  86. package/dist/cli/extract/index.d.ts +9 -0
  87. package/dist/cli/extract/index.js +9 -0
  88. package/dist/cli/extract/npx-engine-harness.d.ts +73 -0
  89. package/dist/cli/extract/npx-engine-harness.js +225 -0
  90. package/dist/cli/extract/stages.d.ts +149 -0
  91. package/dist/cli/extract/stages.js +398 -0
  92. package/dist/cli/framework.d.ts +8 -0
  93. package/dist/cli/framework.js +36 -0
  94. package/dist/cli/init-auth.d.ts +67 -0
  95. package/dist/cli/init-auth.js +142 -0
  96. package/dist/cli/init-scaffolds.d.ts +28 -0
  97. package/dist/cli/init-scaffolds.js +235 -0
  98. package/dist/cli/init.d.ts +115 -0
  99. package/dist/cli/init.js +1008 -0
  100. package/dist/cli/mcp/index.d.ts +7 -0
  101. package/dist/cli/mcp/index.js +59 -0
  102. package/dist/cli/mcp/registry.d.ts +9 -0
  103. package/dist/cli/mcp/registry.js +117 -0
  104. package/dist/cli/mcp/server-json.d.ts +12 -0
  105. package/dist/cli/mcp/server-json.js +65 -0
  106. package/dist/cli/mcp/server.schema.json +574 -0
  107. package/dist/cli/mcp/verify-domain.d.ts +11 -0
  108. package/dist/cli/mcp/verify-domain.js +48 -0
  109. package/dist/cli/playground/app/embed-entry.d.ts +20 -0
  110. package/dist/cli/playground/app/embed-entry.js +46 -0
  111. package/dist/cli/playground/app/fake-client.d.ts +3 -0
  112. package/dist/cli/playground/app/fake-client.js +215 -0
  113. package/dist/cli/playground/app/fixtures.d.ts +47 -0
  114. package/dist/cli/playground/app/fixtures.js +472 -0
  115. package/dist/cli/playground/app/main.d.ts +1 -0
  116. package/dist/cli/playground/app/main.js +108 -0
  117. package/dist/cli/playground/app/scenario-mount.d.ts +13 -0
  118. package/dist/cli/playground/app/scenario-mount.js +48 -0
  119. package/dist/cli/playground/app/scenarios.d.ts +25 -0
  120. package/dist/cli/playground/app/scenarios.js +152 -0
  121. package/dist/cli/playground/app/theme-editor.d.ts +13 -0
  122. package/dist/cli/playground/app/theme-editor.js +149 -0
  123. package/dist/cli/playground/app/theme-state.d.ts +29 -0
  124. package/dist/cli/playground/app/theme-state.js +151 -0
  125. package/dist/cli/playground/bundle.gen.d.ts +2 -0
  126. package/dist/cli/playground/bundle.gen.js +2 -0
  127. package/dist/cli/playground/embed-bundle.gen.d.ts +2 -0
  128. package/dist/cli/playground/embed-bundle.gen.js +2 -0
  129. package/dist/cli/playground.d.ts +33 -0
  130. package/dist/cli/playground.js +120 -0
  131. package/dist/cli/pretty.d.ts +48 -0
  132. package/dist/cli/pretty.js +330 -0
  133. package/dist/cli/refine.d.ts +43 -0
  134. package/dist/cli/refine.js +181 -0
  135. package/dist/cli/semantics.d.ts +31 -0
  136. package/dist/cli/semantics.js +122 -0
  137. package/dist/cli/shared.d.ts +68 -0
  138. package/dist/cli/shared.js +184 -0
  139. package/dist/cli/sync.d.ts +36 -0
  140. package/dist/cli/sync.js +202 -0
  141. package/dist/cli/theme/color.d.ts +15 -0
  142. package/dist/cli/theme/color.js +188 -0
  143. package/dist/cli/theme/css-vars.d.ts +13 -0
  144. package/dist/cli/theme/css-vars.js +40 -0
  145. package/dist/cli/theme/entry-candidates.d.ts +5 -0
  146. package/dist/cli/theme/entry-candidates.js +22 -0
  147. package/dist/cli/theme/extract-theme.d.ts +184 -0
  148. package/dist/cli/theme/extract-theme.js +358 -0
  149. package/dist/cli/theme/walk.d.ts +2 -0
  150. package/dist/cli/theme/walk.js +24 -0
  151. package/dist/cli.d.ts +2 -0
  152. package/dist/cli.js +333 -0
  153. package/dist/cloud-apps.d.ts +17 -0
  154. package/dist/cloud-apps.js +46 -0
  155. package/dist/cloud-console.d.ts +32 -0
  156. package/dist/cloud-console.js +72 -0
  157. package/dist/cloud-tools.d.ts +23 -0
  158. package/dist/cloud-tools.js +196 -0
  159. package/dist/connections.d.ts +71 -0
  160. package/dist/connections.js +192 -0
  161. package/dist/deployment-identity.d.ts +12 -0
  162. package/dist/deployment-identity.js +69 -0
  163. package/dist/dev-creds/model.d.ts +65 -0
  164. package/dist/dev-creds/model.js +159 -0
  165. package/dist/dev-creds/resolve.d.ts +36 -0
  166. package/dist/dev-creds/resolve.js +57 -0
  167. package/dist/hosted-store.d.ts +52 -0
  168. package/dist/hosted-store.js +322 -0
  169. package/dist/index.d.ts +13 -0
  170. package/dist/index.js +1 -0
  171. package/dist/mastra.d.ts +46 -0
  172. package/dist/mastra.js +88 -0
  173. package/dist/react.d.ts +10 -0
  174. package/dist/react.js +32 -0
  175. package/dist/refine.d.ts +244 -0
  176. package/dist/refine.js +599 -0
  177. package/dist/remixable.d.ts +18 -0
  178. package/dist/remixable.js +42 -0
  179. package/dist/runtime-capture.d.ts +18 -0
  180. package/dist/runtime-capture.js +111 -0
  181. package/dist/sandbox-wire.d.ts +101 -0
  182. package/dist/sandbox-wire.js +101 -0
  183. package/dist/sandbox.d.ts +38 -0
  184. package/dist/sandbox.js +389 -0
  185. package/dist/server.d.ts +216 -0
  186. package/dist/server.js +1320 -0
  187. package/dist/sync-impact.d.ts +14 -0
  188. package/dist/sync-impact.js +75 -0
  189. package/dist/turn-liveness.d.ts +33 -0
  190. package/dist/turn-liveness.js +105 -0
  191. package/dist/wire/approvals.d.ts +10 -0
  192. package/dist/wire/approvals.js +59 -0
  193. package/dist/wire/apps.d.ts +5 -0
  194. package/dist/wire/apps.js +155 -0
  195. package/dist/wire/automations.d.ts +5 -0
  196. package/dist/wire/automations.js +57 -0
  197. package/dist/wire/box.d.ts +3 -0
  198. package/dist/wire/box.js +268 -0
  199. package/dist/wire/connections.d.ts +5 -0
  200. package/dist/wire/connections.js +47 -0
  201. package/dist/wire/context.d.ts +22 -0
  202. package/dist/wire/context.js +190 -0
  203. package/dist/wire/doctor.d.ts +19 -0
  204. package/dist/wire/doctor.js +116 -0
  205. package/dist/wire/misc.d.ts +18 -0
  206. package/dist/wire/misc.js +227 -0
  207. package/dist/wire/shared.d.ts +158 -0
  208. package/dist/wire/shared.js +134 -0
  209. package/dist/wire/threads.d.ts +3 -0
  210. package/dist/wire/threads.js +68 -0
  211. package/package.json +151 -0
  212. package/skills/vendo-setup/SKILL.md +128 -0
@@ -0,0 +1,68 @@
1
+ import { VendoError } from "@vendoai/core";
2
+ import { registerActiveTurn, touchActiveTurn, trackTurnResponse } from "../turn-liveness.js";
3
+ import { json, requestJson, route, string } from "./shared.js";
4
+ /** The effective thread id the agent stamps on every turn response (03 §1). */
5
+ const THREAD_ID_HEADER = "x-vendo-thread-id";
6
+ /** 09 §3 — the /threads wire area: chat streaming plus thread list/get/delete. */
7
+ export const threadRoutes = [
8
+ route("POST", "/threads", async ({ request, deps, context }) => {
9
+ const body = await requestJson(request);
10
+ const ctx = await context("chat");
11
+ void deps.telemetry?.track("agent_run", {});
12
+ // AGENT-3 (fast path): a propagated client disconnect aborts the request,
13
+ // which cancels the agent loop — provider calls stop instead of running to
14
+ // completion for a reader that is gone.
15
+ // ENG-353 (fallback): some runtimes never surface a graceful disconnect
16
+ // (`next dev` fires neither the signal nor a cancel), so a heartbeat-armed
17
+ // idle watchdog can abort the turn through the same controller. Consumers
18
+ // that never beat keep run-to-completion semantics.
19
+ const turnAbort = new AbortController();
20
+ if (request.signal.aborted)
21
+ turnAbort.abort();
22
+ else
23
+ request.signal.addEventListener("abort", () => turnAbort.abort(), { once: true });
24
+ const turn = await deps.agent.stream({
25
+ ...(body["threadId"] === undefined ? {} : { threadId: string(body["threadId"], "threadId") }),
26
+ message: body["message"],
27
+ ctx,
28
+ signal: turnAbort.signal,
29
+ });
30
+ const threadId = turn.headers.get(THREAD_ID_HEADER);
31
+ if (threadId === null)
32
+ return turn;
33
+ const unregister = registerActiveTurn({
34
+ threadId,
35
+ subject: ctx.principal.subject,
36
+ abort: () => turnAbort.abort(),
37
+ });
38
+ return trackTurnResponse(turn, unregister);
39
+ }),
40
+ // ENG-353 — turn-liveness beat. Principal-scoped: it refreshes only the
41
+ // caller's own in-flight turns, and unknown/foreign ids answer
42
+ // `active: false` (no oracle).
43
+ route("POST", "/threads/:id/heartbeat", async ({ context, params }) => {
44
+ const ctx = await context("chat");
45
+ const id = string(params["id"], "thread id");
46
+ return json({ active: touchActiveTurn(id, ctx.principal.subject) });
47
+ }),
48
+ route("GET", "/threads", async ({ deps, context }) => {
49
+ return json(await deps.agent.threads.list(await context("chat")));
50
+ }),
51
+ // Grouped like the old if-chain arm: ANY method resolves context first, and
52
+ // an unhandled method falls through to the table's not-found.
53
+ route("*", "/threads/:id", async ({ request, deps, context, params }) => {
54
+ const ctx = await context("chat");
55
+ const id = string(params["id"], "thread id");
56
+ if (request.method === "GET") {
57
+ const thread = await deps.agent.threads.get(id, ctx);
58
+ if (thread === null)
59
+ throw new VendoError("not-found", `thread not found: ${id}`);
60
+ return json(thread);
61
+ }
62
+ if (request.method === "DELETE") {
63
+ await deps.agent.threads.delete(id, ctx);
64
+ return json({});
65
+ }
66
+ return undefined;
67
+ }),
68
+ ];
package/package.json ADDED
@@ -0,0 +1,151 @@
1
+ {
2
+ "name": "@vendoai/vendo",
3
+ "version": "0.4.0",
4
+ "description": "The Vendo umbrella: default composition, public wire routes, React provider, and the vendo CLI.",
5
+ "keywords": [
6
+ "ai",
7
+ "agent",
8
+ "genui",
9
+ "react",
10
+ "vendo"
11
+ ],
12
+ "license": "Apache-2.0",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/runvendo/vendo.git",
16
+ "directory": "packages/vendo"
17
+ },
18
+ "homepage": "https://vendo.run",
19
+ "bugs": "https://github.com/runvendo/vendo/issues",
20
+ "engines": {
21
+ "node": ">=20"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "type": "module",
27
+ "sideEffects": false,
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "bin": {
31
+ "vendo": "bin/vendo.mjs"
32
+ },
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "default": "./dist/index.js"
37
+ },
38
+ "./server": {
39
+ "types": "./dist/server.d.ts",
40
+ "default": "./dist/server.js"
41
+ },
42
+ "./extract": {
43
+ "types": "./dist/cli/extract/index.d.ts",
44
+ "default": "./dist/cli/extract/index.js"
45
+ },
46
+ "./react": {
47
+ "types": "./dist/react.d.ts",
48
+ "default": "./dist/react.js"
49
+ },
50
+ "./ai-sdk": {
51
+ "types": "./dist/ai-sdk.d.ts",
52
+ "default": "./dist/ai-sdk.js"
53
+ },
54
+ "./mastra": {
55
+ "types": "./dist/mastra.d.ts",
56
+ "default": "./dist/mastra.js"
57
+ },
58
+ "./auth/auth0": {
59
+ "types": "./dist/auth-presets/auth0.d.ts",
60
+ "default": "./dist/auth-presets/auth0.js"
61
+ },
62
+ "./auth/auth-js": {
63
+ "types": "./dist/auth-presets/auth-js.d.ts",
64
+ "default": "./dist/auth-presets/auth-js.js"
65
+ },
66
+ "./auth/clerk": {
67
+ "types": "./dist/auth-presets/clerk.d.ts",
68
+ "default": "./dist/auth-presets/clerk.js"
69
+ },
70
+ "./auth/jwt": {
71
+ "types": "./dist/auth-presets/jwt.d.ts",
72
+ "default": "./dist/auth-presets/jwt.js"
73
+ },
74
+ "./auth/supabase": {
75
+ "types": "./dist/auth-presets/supabase.d.ts",
76
+ "default": "./dist/auth-presets/supabase.js"
77
+ }
78
+ },
79
+ "files": [
80
+ "dist",
81
+ "bin",
82
+ "skills",
83
+ "README.md"
84
+ ],
85
+ "dependencies": {
86
+ "ajv": "^8.20.0",
87
+ "ajv-formats": "^3.0.1",
88
+ "zod": "^3.25.0",
89
+ "@vendoai/actions": "0.4.0",
90
+ "@vendoai/core": "0.4.0",
91
+ "@vendoai/apps": "0.4.0",
92
+ "@vendoai/guard": "0.4.0",
93
+ "@vendoai/mcp": "0.4.0",
94
+ "@vendoai/agent": "0.4.0",
95
+ "@vendoai/automations": "0.4.0",
96
+ "@vendoai/ui": "0.4.0",
97
+ "@vendoai/telemetry": "0.3.0",
98
+ "@vendoai/store": "0.4.0"
99
+ },
100
+ "peerDependencies": {
101
+ "@auth/core": "^0.34.3",
102
+ "@clerk/backend": ">=1.0.0",
103
+ "@mastra/core": ">=1.0.0 <2",
104
+ "ai": ">=6.0.0 <7",
105
+ "jose": ">=5.0.0",
106
+ "react": "^18.0.0 || ^19.0.0",
107
+ "react-dom": "^18.0.0 || ^19.0.0"
108
+ },
109
+ "peerDependenciesMeta": {
110
+ "@auth/core": {
111
+ "optional": true
112
+ },
113
+ "@mastra/core": {
114
+ "optional": true
115
+ },
116
+ "@clerk/backend": {
117
+ "optional": true
118
+ },
119
+ "jose": {
120
+ "optional": true
121
+ }
122
+ },
123
+ "devDependencies": {
124
+ "@ai-sdk/anthropic": "3.0.12",
125
+ "@auth/core": "^0.34.3",
126
+ "@clerk/backend": "^3.11.7",
127
+ "@mastra/core": "1.51.0",
128
+ "@types/json-schema": "^7.0.15",
129
+ "@types/node": "^22.0.0",
130
+ "@types/react": "^19.2.0",
131
+ "@types/react-dom": "^19.2.0",
132
+ "ai": "6.0.28",
133
+ "jose": "^6.2.3",
134
+ "react": "^19.0.0",
135
+ "react-dom": "^19.0.0",
136
+ "typescript": "^5.6.0",
137
+ "vite": "^6.0.0",
138
+ "vitest": "^2.1.0"
139
+ },
140
+ "scripts": {
141
+ "build:playground": "node scripts/build-playground.mjs",
142
+ "prebuild": "pnpm run build:playground",
143
+ "build": "tsc -p tsconfig.json",
144
+ "pretest": "pnpm run build:playground",
145
+ "test": "vitest run",
146
+ "pretypecheck": "pnpm run build:playground",
147
+ "typecheck": "tsc -p tsconfig.json --noEmit",
148
+ "pretest:coverage": "pnpm run build:playground",
149
+ "test:coverage": "vitest run --coverage"
150
+ }
151
+ }
@@ -0,0 +1,128 @@
1
+ ---
2
+ name: vendo-setup
3
+ description: Install and configure Vendo (the embedded product agent) in a host repo. Use when asked to add Vendo to an app, run vendo init/doctor/sync, wire the Vendo handler or VendoRoot, or debug a Vendo install until doctor exits 0.
4
+ ---
5
+
6
+ # Vendo setup
7
+
8
+ Vendo embeds an agent inside a host product: it extracts the host's API as
9
+ tools, renders generated UI in a sandboxed brand-native surface, and acts as
10
+ the signed-in user. This skill installs and verifies Vendo in a host repo.
11
+
12
+ The canonical agent playbook lives at https://vendo.run/agents.md —
13
+ fetch it when you need more detail than this skill carries.
14
+
15
+ ## Stage 1 — base install
16
+
17
+ 1. Install the umbrella package (either name; `vendoai` is a thin alias):
18
+
19
+ ```bash
20
+ npm install @vendoai/vendo
21
+ ```
22
+
23
+ 2. Run init. As an agent, plan first, then apply:
24
+
25
+ ```bash
26
+ npx vendo init --agent # read-only JSON plan: framework, code diffs, extracted tools, risk recommendations, aiPolish delegation contract
27
+ npx vendo init --yes
28
+ ```
29
+
30
+ `--agent` writes nothing. Init applies its bounded change set and lists
31
+ it; the only questions are an auth confirm when detection is uncertain, a
32
+ review of uncertain theme slots, and the end-of-init cloud-login offer
33
+ (`--yes` skips it). Each question has a non-interactive answer flag:
34
+ `--auth <preset>`, `--framework <name>`, `--theme <slot=value>`
35
+ (repeatable), `--cloud-key <key>` or `--byo`, and `--ai-polish` to consent
36
+ to the AI extraction pass. Prefer the interactive run when a human is
37
+ present.
38
+
39
+ 3. What init does (framework detected from `package.json`, `next` beats
40
+ `express`; anything else is treated as Next):
41
+ - Writes `.vendo/` — `tools.json` (extracted tools), `overrides.json`
42
+ (your risk/critical edits, respected forever), `policy.json`,
43
+ `brief.md`, `theme.json` (brand extracted from the host CSS), and a
44
+ gitignored `.vendo/data/` for the PGlite store. Commit `.vendo/`,
45
+ never `.vendo/data/`.
46
+ - Next.js: proposes `app/api/vendo/[...vendo]/route.ts` (or under
47
+ `src/app`), wraps the root layout in `<VendoRoot theme={...}>`, and
48
+ scaffolds a starter model module when the import cannot resolve.
49
+ - Express: proposes `vendo/server.ts` (`.mjs` without a tsconfig) plus a
50
+ starter `vendo/ai.ts`; you must still mount
51
+ `app.use("/api/vendo", mountVendo())` and wrap the client in
52
+ `<VendoRoot>` yourself.
53
+ - Adds `predev`/`prebuild` sync hooks to `package.json` (consent-gated).
54
+
55
+ 4. Model credential: the starter model module uses
56
+ `createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY })`. Install its
57
+ pinned peers and set the key:
58
+
59
+ ```bash
60
+ npm install ai@^6 @ai-sdk/anthropic@^3
61
+ echo 'ANTHROPIC_API_KEY=sk-ant-...' >> .env.local
62
+ ```
63
+
64
+ Never invent a key; ask the user for one if none is set. Any AI SDK
65
+ provider works — point `vendo refine --model-import` at the host's own
66
+ model module when one exists.
67
+
68
+ 5. Verify. Start the dev server, then:
69
+
70
+ ```bash
71
+ npx vendo doctor
72
+ ```
73
+
74
+ Doctor checks wiring plus one live `/status` round-trip against
75
+ `http://localhost:3000/api/vendo` (override with `--url` or `VENDO_URL`).
76
+ Exit 0 = green; exit 1 prints each `broken:` line. Fix and re-run until 0.
77
+ Common fixes: dev server not running (start it), missing `.vendo/*` file
78
+ (re-run `npx vendo init`), layout not wrapped (apply the skipped diff by
79
+ re-running init and approving it).
80
+
81
+ ## Stage 2 — review and keep extraction fresh
82
+
83
+ - AI polish, delegated to you: the `--agent` plan's `aiPolish` object is a
84
+ contract you can execute yourself. Read the codebase per
85
+ `aiPolish.instructions` (task-oriented tool descriptions, risk review,
86
+ wakes with reasoning, the product brief), write one JSON draft matching
87
+ `aiPolish.draftSchema` to a file, then:
88
+
89
+ ```bash
90
+ npx vendo extract --apply draft.json
91
+ ```
92
+
93
+ Vendo runs the same deterministic guards as init's built-in pass (only
94
+ extracted tool names accepted, risk raised never lowered, wakes need
95
+ reasoning plus a grade, human decisions win), writes
96
+ `.vendo/overrides.json` and `.vendo/brief.md`, and re-syncs. Non-zero exit
97
+ means the draft was rejected with the reason printed; fix and re-apply.
98
+ `--force` replaces a hand-edited brief; leave it off otherwise.
99
+ - Re-extract after API changes: `npx vendo sync` (fail-soft). In CI use
100
+ `npx vendo sync --strict` — exit 2 on breaking tool changes, 3 when saved
101
+ apps/automations/grants are impacted. `--json` emits one machine-readable
102
+ report object on stdout.
103
+ - Review `.vendo/tools.json`; put corrections in `.vendo/overrides.json`
104
+ (`{"tools": {"host_invoices_delete": {"critical": true}}}`) — never edit
105
+ `tools.json` by hand, sync regenerates it.
106
+ - Tighten `.vendo/policy.json` rules (`ask` for destructive, `run` for read)
107
+ and write a real product brief in `.vendo/brief.md`.
108
+
109
+ ## Stage 3 — unlocks
110
+
111
+ - **MCP door** (agents like Claude/ChatGPT use the product's tools): a host
112
+ decision, never a default. Needs a `HostOAuthAdapter` and
113
+ `createVendo({ mcp: true, oauth })`, then `npx vendo mcp server-json` and
114
+ `npx vendo mcp verify-domain`. Doctor validates the discovery documents.
115
+ - **Sandbox / connectors / voice / persistence on Postgres**: doctor's final
116
+ ladder line names what each remaining block unlocks; see
117
+ https://docs.vendo.run for each capability.
118
+ - **Vendo Cloud**: sharing, org overlays, and hosted automations activate
119
+ with `VENDO_API_KEY` (`npx vendo login`).
120
+
121
+ ## Rules
122
+
123
+ - Show the user every proposed code diff before applying it unless they
124
+ explicitly asked for unattended setup.
125
+ - Do not hand-edit generated files (`.vendo/tools.json`, theme regeneration);
126
+ use `overrides.json` and re-run sync.
127
+ - Done means `npx vendo doctor` exits 0 against a running dev server, not
128
+ merely that files exist.