@noodleseed/one 0.8.0 → 0.10.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 (165) hide show
  1. package/dist/commands/author-loop.d.ts.map +1 -1
  2. package/dist/commands/author-loop.js +78 -3
  3. package/dist/commands/author-loop.js.map +1 -1
  4. package/dist/commands/deploy-ops.d.ts +1 -30
  5. package/dist/commands/deploy-ops.d.ts.map +1 -1
  6. package/dist/commands/deploy-ops.js +55 -87
  7. package/dist/commands/deploy-ops.js.map +1 -1
  8. package/dist/commands/deploy-output.d.ts +31 -0
  9. package/dist/commands/deploy-output.d.ts.map +1 -0
  10. package/dist/commands/deploy-output.js +86 -0
  11. package/dist/commands/deploy-output.js.map +1 -0
  12. package/dist/commands/deploy-version-resolution.d.ts +20 -0
  13. package/dist/commands/deploy-version-resolution.d.ts.map +1 -0
  14. package/dist/commands/deploy-version-resolution.js +77 -0
  15. package/dist/commands/deploy-version-resolution.js.map +1 -0
  16. package/dist/commands/docs-mcp.d.ts +32 -0
  17. package/dist/commands/docs-mcp.d.ts.map +1 -0
  18. package/dist/commands/docs-mcp.js +66 -0
  19. package/dist/commands/docs-mcp.js.map +1 -0
  20. package/dist/commands/mcp-apps.d.ts.map +1 -1
  21. package/dist/commands/mcp-apps.js +38 -37
  22. package/dist/commands/mcp-apps.js.map +1 -1
  23. package/dist/commands/project-setup.d.ts.map +1 -1
  24. package/dist/commands/project-setup.js +29 -0
  25. package/dist/commands/project-setup.js.map +1 -1
  26. package/dist/commands/shared.d.ts +1 -0
  27. package/dist/commands/shared.d.ts.map +1 -1
  28. package/dist/commands/shared.js +8 -4
  29. package/dist/commands/shared.js.map +1 -1
  30. package/dist/deploy-version.d.ts +3 -0
  31. package/dist/deploy-version.d.ts.map +1 -0
  32. package/dist/deploy-version.js +28 -0
  33. package/dist/deploy-version.js.map +1 -0
  34. package/dist/deploy.d.ts +5 -1
  35. package/dist/deploy.d.ts.map +1 -1
  36. package/dist/deploy.js +27 -3
  37. package/dist/deploy.js.map +1 -1
  38. package/dist/devtools-chat.d.ts +76 -0
  39. package/dist/devtools-chat.d.ts.map +1 -0
  40. package/dist/devtools-chat.js +114 -0
  41. package/dist/devtools-chat.js.map +1 -0
  42. package/dist/devtools-env.d.ts +16 -0
  43. package/dist/devtools-env.d.ts.map +1 -0
  44. package/dist/devtools-env.js +71 -0
  45. package/dist/devtools-env.js.map +1 -0
  46. package/dist/devtools-harness.d.ts +28 -0
  47. package/dist/devtools-harness.d.ts.map +1 -0
  48. package/dist/devtools-harness.js +387 -0
  49. package/dist/devtools-harness.js.map +1 -0
  50. package/dist/devtools-preview.d.ts +42 -0
  51. package/dist/devtools-preview.d.ts.map +1 -0
  52. package/dist/devtools-preview.js +394 -0
  53. package/dist/devtools-preview.js.map +1 -0
  54. package/dist/preview-session.d.ts +46 -0
  55. package/dist/preview-session.d.ts.map +1 -0
  56. package/dist/preview-session.js +132 -0
  57. package/dist/preview-session.js.map +1 -0
  58. package/dist/project.d.ts +2 -0
  59. package/dist/project.d.ts.map +1 -1
  60. package/dist/project.js +2 -0
  61. package/dist/project.js.map +1 -1
  62. package/dist/react-widget-build.js +3 -1
  63. package/dist/react-widget-build.js.map +1 -1
  64. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  65. package/node_modules/@noodle-borg/connector-defs/dist/compile-expr.d.ts +23 -0
  66. package/node_modules/@noodle-borg/connector-defs/dist/compile-expr.d.ts.map +1 -0
  67. package/node_modules/@noodle-borg/connector-defs/dist/compile-expr.js +41 -0
  68. package/node_modules/@noodle-borg/connector-defs/dist/compile-expr.js.map +1 -0
  69. package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts +2 -6
  70. package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts.map +1 -1
  71. package/node_modules/@noodle-borg/connector-defs/dist/compile.js +10 -32
  72. package/node_modules/@noodle-borg/connector-defs/dist/compile.js.map +1 -1
  73. package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts +16 -0
  74. package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts.map +1 -1
  75. package/node_modules/@noodle-borg/connector-defs/dist/schema.js +6 -0
  76. package/node_modules/@noodle-borg/connector-defs/dist/schema.js.map +1 -1
  77. package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts +7 -0
  78. package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts.map +1 -1
  79. package/node_modules/@noodle-borg/connector-http/dist/http-connector.js +14 -5
  80. package/node_modules/@noodle-borg/connector-http/dist/http-connector.js.map +1 -1
  81. package/node_modules/@noodle-borg/module/dist/contract.d.ts +12 -0
  82. package/node_modules/@noodle-borg/module/dist/contract.d.ts.map +1 -1
  83. package/node_modules/@noodle-borg/module/dist/contract.js +41 -0
  84. package/node_modules/@noodle-borg/module/dist/contract.js.map +1 -1
  85. package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.d.ts +20 -2
  86. package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.d.ts.map +1 -1
  87. package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.js +37 -2
  88. package/node_modules/@noodle-borg/service/dist/auth/deploy-gate.js.map +1 -1
  89. package/node_modules/@noodle-borg/service/dist/deployment-versioning.d.ts +18 -0
  90. package/node_modules/@noodle-borg/service/dist/deployment-versioning.d.ts.map +1 -0
  91. package/node_modules/@noodle-borg/service/dist/deployment-versioning.js +29 -0
  92. package/node_modules/@noodle-borg/service/dist/deployment-versioning.js.map +1 -0
  93. package/node_modules/@noodle-borg/service/dist/main.js +7 -0
  94. package/node_modules/@noodle-borg/service/dist/main.js.map +1 -1
  95. package/node_modules/@noodle-borg/service/dist/oauth/app.d.ts.map +1 -1
  96. package/node_modules/@noodle-borg/service/dist/oauth/app.js +2 -1
  97. package/node_modules/@noodle-borg/service/dist/oauth/app.js.map +1 -1
  98. package/node_modules/@noodle-borg/service/dist/oauth/branding.d.ts +30 -0
  99. package/node_modules/@noodle-borg/service/dist/oauth/branding.d.ts.map +1 -0
  100. package/node_modules/@noodle-borg/service/dist/oauth/branding.js +224 -0
  101. package/node_modules/@noodle-borg/service/dist/oauth/branding.js.map +1 -0
  102. package/node_modules/@noodle-borg/service/dist/oauth/consent.d.ts +0 -6
  103. package/node_modules/@noodle-borg/service/dist/oauth/consent.d.ts.map +1 -1
  104. package/node_modules/@noodle-borg/service/dist/oauth/consent.js +23 -34
  105. package/node_modules/@noodle-borg/service/dist/oauth/consent.js.map +1 -1
  106. package/node_modules/@noodle-borg/service/dist/oauth/customer-bridge.d.ts.map +1 -1
  107. package/node_modules/@noodle-borg/service/dist/oauth/customer-bridge.js +13 -28
  108. package/node_modules/@noodle-borg/service/dist/oauth/customer-bridge.js.map +1 -1
  109. package/node_modules/@noodle-borg/service/dist/registry-helpers.d.ts +1 -1
  110. package/node_modules/@noodle-borg/service/dist/registry-helpers.d.ts.map +1 -1
  111. package/node_modules/@noodle-borg/service/dist/registry-helpers.js +5 -3
  112. package/node_modules/@noodle-borg/service/dist/registry-helpers.js.map +1 -1
  113. package/node_modules/@noodle-borg/service/dist/registry-targets.d.ts +1 -0
  114. package/node_modules/@noodle-borg/service/dist/registry-targets.d.ts.map +1 -1
  115. package/node_modules/@noodle-borg/service/dist/registry-targets.js +4 -0
  116. package/node_modules/@noodle-borg/service/dist/registry-targets.js.map +1 -1
  117. package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +59 -0
  118. package/node_modules/@noodle-borg/service/dist/registry-types.d.ts.map +1 -0
  119. package/node_modules/@noodle-borg/service/dist/registry-types.js +2 -0
  120. package/node_modules/@noodle-borg/service/dist/registry-types.js.map +1 -0
  121. package/node_modules/@noodle-borg/service/dist/registry.d.ts +8 -65
  122. package/node_modules/@noodle-borg/service/dist/registry.d.ts.map +1 -1
  123. package/node_modules/@noodle-borg/service/dist/registry.js +100 -82
  124. package/node_modules/@noodle-borg/service/dist/registry.js.map +1 -1
  125. package/node_modules/@noodle-borg/service/dist/routes/access-mode.d.ts +4 -0
  126. package/node_modules/@noodle-borg/service/dist/routes/access-mode.d.ts.map +1 -0
  127. package/node_modules/@noodle-borg/service/dist/routes/access-mode.js +15 -0
  128. package/node_modules/@noodle-borg/service/dist/routes/access-mode.js.map +1 -0
  129. package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts +1 -1
  130. package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts.map +1 -1
  131. package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +34 -21
  132. package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
  133. package/node_modules/@noodle-borg/service/dist/routes/rollback.d.ts.map +1 -1
  134. package/node_modules/@noodle-borg/service/dist/routes/rollback.js +4 -6
  135. package/node_modules/@noodle-borg/service/dist/routes/rollback.js.map +1 -1
  136. package/node_modules/@noodle-borg/service/dist/serve.d.ts +6 -0
  137. package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
  138. package/node_modules/@noodle-borg/service/dist/serve.js +72 -32
  139. package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
  140. package/node_modules/@noodle-borg/service/dist/server-auth-bindings.d.ts +7 -0
  141. package/node_modules/@noodle-borg/service/dist/server-auth-bindings.d.ts.map +1 -0
  142. package/node_modules/@noodle-borg/service/dist/server-auth-bindings.js +14 -0
  143. package/node_modules/@noodle-borg/service/dist/server-auth-bindings.js.map +1 -0
  144. package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
  145. package/node_modules/@noodle-borg/service/dist/service.js +32 -3
  146. package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
  147. package/node_modules/@noodle-borg/service/dist/store/postgres-schema.d.ts.map +1 -1
  148. package/node_modules/@noodle-borg/service/dist/store/postgres-schema.js +13 -2
  149. package/node_modules/@noodle-borg/service/dist/store/postgres-schema.js.map +1 -1
  150. package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts +3 -2
  151. package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts.map +1 -1
  152. package/node_modules/@noodle-borg/service/dist/store/postgres.js +41 -9
  153. package/node_modules/@noodle-borg/service/dist/store/postgres.js.map +1 -1
  154. package/node_modules/@noodle-borg/service/dist/store.d.ts +9 -3
  155. package/node_modules/@noodle-borg/service/dist/store.d.ts.map +1 -1
  156. package/node_modules/@noodle-borg/service/dist/store.js +29 -27
  157. package/node_modules/@noodle-borg/service/dist/store.js.map +1 -1
  158. package/node_modules/@noodle-borg/transport-http/dist/handler.d.ts +1 -0
  159. package/node_modules/@noodle-borg/transport-http/dist/handler.d.ts.map +1 -1
  160. package/node_modules/@noodle-borg/transport-http/dist/handler.js +37 -0
  161. package/node_modules/@noodle-borg/transport-http/dist/handler.js.map +1 -1
  162. package/node_modules/@noodle-borg/transport-http/dist/index.d.ts +1 -1
  163. package/node_modules/@noodle-borg/transport-http/dist/index.d.ts.map +1 -1
  164. package/node_modules/@noodle-borg/transport-http/dist/index.js.map +1 -1
  165. package/package.json +3 -2
@@ -0,0 +1,394 @@
1
+ import { createServer } from 'node:http';
2
+ import { DEFAULT_CHAT_MODEL, runChatTurn, } from './devtools-chat.js';
3
+ import { harnessHtml, openAiShimScript, wrapWidgetHtml, } from './devtools-harness.js';
4
+ // Re-exported so `devtools-preview` stays the single import surface for the command and tests.
5
+ export { harnessHtml, openAiShimScript, wrapWidgetHtml };
6
+ const CHAT_SYSTEM_PROMPT = 'You are an assistant embedded in the Noodle Seed devtools playground. You can call the MCP tools ' +
7
+ 'exposed by the local server the developer is previewing. Call a tool whenever it can answer the ' +
8
+ 'request or render a widget, then explain the result briefly. Keep answers concise.';
9
+ const DEFAULT_PROTOCOL_VERSION = '2025-11-25';
10
+ /** Parse the `/widget?args=` query param (a JSON object) into tool-call arguments; `{}` on absent/invalid. */
11
+ function parseArgsParam(raw) {
12
+ if (!raw)
13
+ return {};
14
+ try {
15
+ const parsed = JSON.parse(raw);
16
+ return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)
17
+ ? parsed
18
+ : {};
19
+ }
20
+ catch {
21
+ return {};
22
+ }
23
+ }
24
+ /** Cap a value for the inspector log so a huge tool result does not flood the SSE stream. */
25
+ function capForLog(value, max = 20000) {
26
+ if (value === undefined)
27
+ return undefined;
28
+ try {
29
+ const serialized = JSON.stringify(value);
30
+ if (serialized.length > max) {
31
+ return `${serialized.slice(0, max)}… (truncated ${serialized.length - max} chars)`;
32
+ }
33
+ return value;
34
+ }
35
+ catch {
36
+ return '[unserializable]';
37
+ }
38
+ }
39
+ function summarize(method, result) {
40
+ if (result === undefined)
41
+ return method;
42
+ if (method === 'tools/list') {
43
+ const tools = Array.isArray(result.tools) ? result.tools : [];
44
+ return `${tools.length} tool(s)`;
45
+ }
46
+ if (method === 'tools/call') {
47
+ return result.isError ? 'tool error' : 'ok';
48
+ }
49
+ if (method === 'resources/read') {
50
+ const contents = Array.isArray(result.contents) ? result.contents : [];
51
+ return `${contents.length} content block(s)`;
52
+ }
53
+ return 'ok';
54
+ }
55
+ function toolName(body) {
56
+ if (body.method === 'tools/call' && body.params && typeof body.params.name === 'string') {
57
+ return body.params.name;
58
+ }
59
+ return undefined;
60
+ }
61
+ /** One JSON-RPC value from a dev-endpoint response body (JSON, or an SSE `data:` frame as a fallback). */
62
+ function parseRpcBody(text) {
63
+ try {
64
+ return JSON.parse(text);
65
+ }
66
+ catch {
67
+ for (const line of text.split(/\r?\n/)) {
68
+ const trimmed = line.trim();
69
+ if (trimmed.startsWith('data:')) {
70
+ try {
71
+ return JSON.parse(trimmed.slice(5).trim());
72
+ }
73
+ catch {
74
+ // keep scanning
75
+ }
76
+ }
77
+ }
78
+ return undefined;
79
+ }
80
+ }
81
+ export async function startPreview(options) {
82
+ const protocolVersion = options.protocolVersion ?? DEFAULT_PROTOCOL_VERSION;
83
+ const initialTheme = options.theme === 'dark' ? 'dark' : 'light';
84
+ const log = [];
85
+ const subscribers = new Set();
86
+ const reloadSubscribers = new Set();
87
+ // The OpenAI key lives ONLY in this server process (session) or the env — never in the browser. The
88
+ // /widget iframes are same-origin and unsandboxed, so anything the page holds (localStorage or a JS var)
89
+ // is readable by widget scripts and could be exfiltrated. The browser sets it via POST /chat/key and then
90
+ // drops it; the gate state comes from GET /chat/status. The key is never logged or sent back to the page.
91
+ let sessionApiKey;
92
+ function resolveApiKey() {
93
+ return sessionApiKey ?? process.env.OPENAI_API_KEY;
94
+ }
95
+ function apiKeySource() {
96
+ if (sessionApiKey)
97
+ return 'session';
98
+ if (process.env.OPENAI_API_KEY)
99
+ return 'env';
100
+ return 'none';
101
+ }
102
+ function record(entry) {
103
+ log.push(entry);
104
+ if (log.length > 500)
105
+ log.shift();
106
+ const line = `data: ${JSON.stringify(entry)}\n\n`;
107
+ for (const res of subscribers)
108
+ res.write(line);
109
+ }
110
+ function signalReload() {
111
+ for (const res of reloadSubscribers)
112
+ res.write('data: reload\n\n');
113
+ }
114
+ async function forward(body) {
115
+ const start = Date.now();
116
+ const name = toolName(body);
117
+ try {
118
+ const res = await fetch(options.mcpUrl, {
119
+ method: 'POST',
120
+ headers: {
121
+ 'content-type': 'application/json',
122
+ accept: 'application/json, text/event-stream',
123
+ 'mcp-protocol-version': protocolVersion,
124
+ },
125
+ // Always send a well-formed JSON-RPC envelope. Internal calls (readWidget) build the body without
126
+ // `jsonrpc`; the browser's /rpc calls already include it (the spread keeps the same value).
127
+ body: JSON.stringify({ jsonrpc: '2.0', ...body }),
128
+ });
129
+ const json = parseRpcBody(await res.text());
130
+ const status = json?.error ? 'error' : 'ok';
131
+ record({
132
+ time: start,
133
+ method: body.method,
134
+ ...(name !== undefined ? { name } : {}),
135
+ status,
136
+ durationMs: Date.now() - start,
137
+ summary: json?.error?.message ?? summarize(body.method, json?.result),
138
+ ...(body.params !== undefined ? { request: capForLog(body.params) } : {}),
139
+ ...(json !== undefined ? { response: capForLog(json.error ?? json.result) } : {}),
140
+ });
141
+ return { httpStatus: res.status, json };
142
+ }
143
+ catch (error) {
144
+ record({
145
+ time: start,
146
+ method: body.method,
147
+ ...(name !== undefined ? { name } : {}),
148
+ status: 'error',
149
+ durationMs: Date.now() - start,
150
+ summary: error instanceof Error ? error.message : String(error),
151
+ ...(body.params !== undefined ? { request: capForLog(body.params) } : {}),
152
+ });
153
+ throw error;
154
+ }
155
+ }
156
+ async function readWidget(toolNameParam, toolArguments = {}) {
157
+ const list = await forward({ method: 'tools/list', id: 'list', params: {} });
158
+ const tools = list.json?.result?.tools ?? [];
159
+ const tool = tools.find((t) => t.name === toolNameParam);
160
+ const uri = tool?._meta?.ui?.resourceUri;
161
+ if (uri === undefined)
162
+ return '<!doctype html><p>No widget resource for this tool.</p>';
163
+ const read = await forward({ method: 'resources/read', id: 'read', params: { uri } });
164
+ const contents = read.json?.result?.contents ?? [];
165
+ const widgetHtml = typeof contents[0]?.text === 'string' ? contents[0].text : '';
166
+ const call = await forward({
167
+ method: 'tools/call',
168
+ id: 'call',
169
+ params: { name: toolNameParam, arguments: toolArguments },
170
+ });
171
+ const toolOutput = call.json?.result?.structuredContent ?? null;
172
+ const toolResponseMetadata = call.json?.result?._meta ?? null;
173
+ const shim = openAiShimScript({
174
+ toolInput: toolArguments,
175
+ toolOutput,
176
+ toolResponseMetadata,
177
+ theme: initialTheme,
178
+ });
179
+ return wrapWidgetHtml(widgetHtml, shim);
180
+ }
181
+ /** Project the live tool list into chat tool defs (carrying widget resourceUri for inline rendering). */
182
+ async function chatToolDefs() {
183
+ const list = await forward({ method: 'tools/list', id: 'chat-list', params: {} });
184
+ const tools = list.json?.result?.tools ?? [];
185
+ return tools.map((t) => {
186
+ const resourceUri = t._meta?.ui
187
+ ?.resourceUri;
188
+ return {
189
+ name: String(t.name),
190
+ ...(typeof t.description === 'string' ? { description: t.description } : {}),
191
+ ...(t.inputSchema && typeof t.inputSchema === 'object'
192
+ ? { inputSchema: t.inputSchema }
193
+ : {}),
194
+ ...(typeof resourceUri === 'string' ? { resourceUri } : {}),
195
+ };
196
+ });
197
+ }
198
+ /** Run one chat-playground turn against the local tools; the API key is read fresh and never logged. */
199
+ async function handleChat(incoming, apiKey) {
200
+ const messages = incoming[0]?.role === 'system'
201
+ ? incoming
202
+ : [{ role: 'system', content: CHAT_SYSTEM_PROMPT }, ...incoming];
203
+ return runChatTurn({
204
+ messages,
205
+ tools: await chatToolDefs(),
206
+ apiKey,
207
+ model: options.openaiModel ?? process.env.OPENAI_MODEL ?? DEFAULT_CHAT_MODEL,
208
+ ...(process.env.OPENAI_BASE_URL ? { baseUrl: process.env.OPENAI_BASE_URL } : {}),
209
+ callTool: async (name, args) => {
210
+ const call = await forward({
211
+ method: 'tools/call',
212
+ id: 'chat-call',
213
+ params: { name, arguments: args ?? {} },
214
+ });
215
+ const result = call.json?.result ?? call.json?.error ?? null;
216
+ const isError = call.json?.error !== undefined ||
217
+ call.json?.result?.isError === true;
218
+ return { result, isError };
219
+ },
220
+ });
221
+ }
222
+ const server = createServer((req, res) => {
223
+ const url = new URL(req.url ?? '/', 'http://localhost');
224
+ if (req.method === 'GET' && url.pathname === '/') {
225
+ res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
226
+ res.end(harnessHtml({ ...options, hasServerKey: Boolean(resolveApiKey()) }));
227
+ return;
228
+ }
229
+ if (req.method === 'GET' && url.pathname === '/widget') {
230
+ const name = url.searchParams.get('name') ?? '';
231
+ readWidget(name, parseArgsParam(url.searchParams.get('args')))
232
+ .then((html) => {
233
+ res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
234
+ res.end(html);
235
+ })
236
+ .catch(() => {
237
+ res.writeHead(502, { 'content-type': 'text/html; charset=utf-8' });
238
+ res.end('<!doctype html><p>Failed to load widget.</p>');
239
+ });
240
+ return;
241
+ }
242
+ if (req.method === 'GET' && url.pathname === '/rpc/log') {
243
+ res.writeHead(200, {
244
+ 'content-type': 'text/event-stream',
245
+ 'cache-control': 'no-cache',
246
+ connection: 'keep-alive',
247
+ });
248
+ res.flushHeaders(); // open the stream immediately (headers otherwise wait for the first write)
249
+ for (const entry of log)
250
+ res.write(`data: ${JSON.stringify(entry)}\n\n`);
251
+ subscribers.add(res);
252
+ req.on('close', () => subscribers.delete(res));
253
+ return;
254
+ }
255
+ if (req.method === 'GET' && url.pathname === '/reload') {
256
+ res.writeHead(200, {
257
+ 'content-type': 'text/event-stream',
258
+ 'cache-control': 'no-cache',
259
+ connection: 'keep-alive',
260
+ });
261
+ res.flushHeaders(); // open the stream immediately so the client connects before the first event
262
+ reloadSubscribers.add(res);
263
+ req.on('close', () => reloadSubscribers.delete(res));
264
+ return;
265
+ }
266
+ if (req.method === 'GET' && url.pathname === '/chat/status') {
267
+ // Report only whether a key is available (and its source) — never the value.
268
+ res.writeHead(200, { 'content-type': 'application/json' });
269
+ res.end(JSON.stringify({ hasKey: Boolean(resolveApiKey()), source: apiKeySource() }));
270
+ return;
271
+ }
272
+ if (req.method === 'POST' && url.pathname === '/chat/key') {
273
+ // Store the browser-supplied key in this process only (loopback). Set '' to clear it. Never logged.
274
+ const chunks = [];
275
+ req.on('data', (c) => chunks.push(c));
276
+ req.on('end', () => {
277
+ let key = '';
278
+ try {
279
+ key = String(JSON.parse(Buffer.concat(chunks).toString('utf8')).key ?? '');
280
+ }
281
+ catch {
282
+ res.writeHead(400, { 'content-type': 'application/json' });
283
+ res.end(JSON.stringify({ error: { code: 'invalid_json', message: 'invalid JSON' } }));
284
+ return;
285
+ }
286
+ const trimmed = key.trim();
287
+ sessionApiKey = trimmed === '' ? undefined : trimmed;
288
+ res.writeHead(200, { 'content-type': 'application/json' });
289
+ res.end(JSON.stringify({ ok: true, hasKey: Boolean(resolveApiKey()), source: apiKeySource() }));
290
+ });
291
+ return;
292
+ }
293
+ if (req.method === 'POST' && url.pathname === '/chat') {
294
+ // The key lives server-side (session key set via /chat/key, or the env). The browser never sends it.
295
+ const apiKey = resolveApiKey();
296
+ if (!apiKey) {
297
+ res.writeHead(200, { 'content-type': 'application/json' });
298
+ res.end(JSON.stringify({
299
+ error: {
300
+ code: 'no_api_key',
301
+ message: 'No OpenAI key set. Add one in the Chat tab or set OPENAI_API_KEY.',
302
+ },
303
+ }));
304
+ return;
305
+ }
306
+ const chunks = [];
307
+ req.on('data', (c) => chunks.push(c));
308
+ req.on('end', () => {
309
+ let body;
310
+ try {
311
+ body = JSON.parse(Buffer.concat(chunks).toString('utf8'));
312
+ }
313
+ catch {
314
+ res.writeHead(400, { 'content-type': 'application/json' });
315
+ res.end(JSON.stringify({ error: { code: 'invalid_json', message: 'invalid JSON' } }));
316
+ return;
317
+ }
318
+ handleChat(Array.isArray(body.messages) ? body.messages : [], apiKey)
319
+ .then((result) => {
320
+ res.writeHead(200, { 'content-type': 'application/json' });
321
+ res.end(JSON.stringify(result));
322
+ })
323
+ .catch((error) => {
324
+ res.writeHead(200, { 'content-type': 'application/json' });
325
+ res.end(JSON.stringify({
326
+ error: {
327
+ code: 'chat_failed',
328
+ message: error instanceof Error ? error.message : 'chat failed',
329
+ },
330
+ }));
331
+ });
332
+ });
333
+ return;
334
+ }
335
+ if (req.method === 'POST' && url.pathname === '/rpc') {
336
+ const chunks = [];
337
+ req.on('data', (c) => chunks.push(c));
338
+ req.on('end', () => {
339
+ let body;
340
+ try {
341
+ body = JSON.parse(Buffer.concat(chunks).toString('utf8'));
342
+ }
343
+ catch {
344
+ res.writeHead(400, { 'content-type': 'application/json' });
345
+ res.end(JSON.stringify({ error: 'invalid JSON' }));
346
+ return;
347
+ }
348
+ forward(body)
349
+ .then(({ httpStatus, json }) => {
350
+ res.writeHead(httpStatus, { 'content-type': 'application/json' });
351
+ res.end(JSON.stringify(json ?? { error: 'empty response' }));
352
+ })
353
+ .catch((error) => {
354
+ res.writeHead(502, { 'content-type': 'application/json' });
355
+ res.end(JSON.stringify({
356
+ jsonrpc: '2.0',
357
+ id: body.id,
358
+ error: { message: error instanceof Error ? error.message : 'proxy error' },
359
+ }));
360
+ });
361
+ });
362
+ return;
363
+ }
364
+ res.writeHead(404, { 'content-type': 'text/plain' });
365
+ res.end('not found');
366
+ });
367
+ await new Promise((resolve, reject) => {
368
+ // Reject on a bind failure (port in use, permission) so it surfaces as a catchable error instead of an
369
+ // unhandled 'error' event that crashes the CLI and leaves this promise pending. Drop the listener on bind.
370
+ const onError = (error) => reject(error);
371
+ server.once('error', onError);
372
+ server.listen(options.port ?? 0, '127.0.0.1', () => {
373
+ server.removeListener('error', onError);
374
+ resolve();
375
+ });
376
+ });
377
+ const address = server.address();
378
+ const port = typeof address === 'object' && address !== null ? address.port : options.port;
379
+ return {
380
+ url: `http://127.0.0.1:${port}/`,
381
+ log,
382
+ signalReload,
383
+ close: () => new Promise((resolve, reject) => {
384
+ for (const res of subscribers)
385
+ res.end();
386
+ for (const res of reloadSubscribers)
387
+ res.end();
388
+ subscribers.clear();
389
+ reloadSubscribers.clear();
390
+ server.close((error) => (error ? reject(error) : resolve()));
391
+ }),
392
+ };
393
+ }
394
+ //# sourceMappingURL=devtools-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools-preview.js","sourceRoot":"","sources":["../src/devtools-preview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { DevHandle } from './dev.js';
2
+ import { type LoadedDevtoolsEnv } from './devtools-env.js';
3
+ import { type PreviewDevice, type PreviewHandle, type PreviewTheme } from './devtools-preview.js';
4
+ /**
5
+ * The devtools preview attached to an already-booted in-process `dev` runtime. Both `noodle dev` (preview
6
+ * on by default in a TTY) and `noodle devtools` (preview always on) drive this — there is never a second
7
+ * process, port, or reload channel to coordinate: the caller owns the `DevHandle`, and this session owns the
8
+ * preview server + a recursive source watcher that reloads the runtime and refreshes connected browsers.
9
+ */
10
+ export interface PreviewSessionOptions {
11
+ /** The already-booted dev runtime (boot it with `watch: false` — this session owns the watcher). */
12
+ readonly handle: DevHandle;
13
+ /** Project source root to watch recursively (so imported view files like `views/*.tsx` trigger reloads). */
14
+ readonly watchDir: string;
15
+ readonly theme: PreviewTheme;
16
+ readonly device: PreviewDevice;
17
+ readonly port?: number;
18
+ readonly model?: string;
19
+ readonly log?: (message: string) => void;
20
+ }
21
+ export interface PreviewSession {
22
+ readonly preview: PreviewHandle;
23
+ /** OPENAI_* keys pulled from a git-ignored `.env.local`, for the banner (values are never surfaced). */
24
+ readonly loadedEnv: LoadedDevtoolsEnv;
25
+ readonly watching: boolean;
26
+ /** Stop the watcher and close the preview server. Does NOT close the dev handle — the caller owns it. */
27
+ close(): Promise<void>;
28
+ }
29
+ /**
30
+ * Start the preview server for `handle` and a debounced recursive watcher that recompiles + live-reloads.
31
+ * Throws if the preview server cannot bind (port in use / permission) — the caller should close the handle.
32
+ */
33
+ export declare function startPreviewSession(opts: PreviewSessionOptions): Promise<PreviewSession>;
34
+ /**
35
+ * The branded banner for a running preview — the same warm palette + glyphs as `noodle init`. Returns lines
36
+ * (the caller prints them) so it stays testable; ANSI is emitted only on an interactive stdout.
37
+ */
38
+ export declare function previewBannerLines(session: PreviewSession, opts: {
39
+ title: string;
40
+ mcpUrl: string;
41
+ theme: string;
42
+ device: string;
43
+ model?: string;
44
+ watchDir: string;
45
+ }): string[];
46
+ //# sourceMappingURL=preview-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-session.d.ts","sourceRoot":"","sources":["../src/preview-session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAElB,MAAM,uBAAuB,CAAC;AAG/B;;;;;GAKG;AAEH,MAAM,WAAW,qBAAqB;IACpC,oGAAoG;IACpG,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,4GAA4G;IAC5G,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,wGAAwG;IACxG,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yGAAyG;IACzG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiF9F;AAQD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE;IACJ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,MAAM,EAAE,CA8BV"}
@@ -0,0 +1,132 @@
1
+ import { watch } from 'node:fs';
2
+ import { loadDevtoolsEnv } from './devtools-env.js';
3
+ import { startPreview, } from './devtools-preview.js';
4
+ import { AMBER, detectColorMode, detectGlyphMode, ORANGE, paint } from './gradient.js';
5
+ /**
6
+ * Start the preview server for `handle` and a debounced recursive watcher that recompiles + live-reloads.
7
+ * Throws if the preview server cannot bind (port in use / permission) — the caller should close the handle.
8
+ */
9
+ export async function startPreviewSession(opts) {
10
+ const log = opts.log ?? ((message) => console.log(message));
11
+ // OPENAI_* playground credentials come from a git-ignored .env.local (dev tooling, not an app secret).
12
+ const loadedEnv = loadDevtoolsEnv(process.cwd());
13
+ const preview = await startPreview({
14
+ mcpUrl: opts.handle.url,
15
+ theme: opts.theme,
16
+ device: opts.device,
17
+ ...(opts.port !== undefined ? { port: opts.port } : {}),
18
+ ...(opts.model !== undefined ? { openaiModel: opts.model } : {}),
19
+ });
20
+ // Watch the whole source tree, recompile/re-bundle via dev.reload(), then push a browser reload so the
21
+ // iframe + tool list refresh. Debounced (fs.watch fires multiple events per save); best-effort.
22
+ let reloadTimer;
23
+ let watcher;
24
+ // Single-flight: `ServerRegistry.deploy()` (behind handle.reload) mutates shared state and is not
25
+ // re-entrant. The debounce only coalesces a burst; it does NOT stop a save during a slow in-flight reload
26
+ // from starting a second, racing deploy. So run one reload at a time and coalesce mid-flight saves into
27
+ // exactly one trailing reload — otherwise an older deploy could finish last and leave a stale build.
28
+ let reloading = false;
29
+ let pendingReload = false;
30
+ function runReload() {
31
+ if (reloading) {
32
+ pendingReload = true;
33
+ return;
34
+ }
35
+ reloading = true;
36
+ void opts.handle
37
+ .reload()
38
+ .then((r) => {
39
+ if (r.ok) {
40
+ log('↻ reloaded');
41
+ preview.signalReload();
42
+ }
43
+ else {
44
+ log('↻ reload failed — keeping the last good build');
45
+ for (const e of r.errors ?? [])
46
+ log(` ${e.code}: ${e.message}`);
47
+ }
48
+ })
49
+ .catch((error) => {
50
+ log(`↻ reload error: ${error instanceof Error ? error.message : String(error)}`);
51
+ })
52
+ .finally(() => {
53
+ reloading = false;
54
+ if (pendingReload) {
55
+ pendingReload = false;
56
+ runReload();
57
+ }
58
+ });
59
+ }
60
+ try {
61
+ watcher = watch(opts.watchDir, { recursive: true }, (_event, filename) => {
62
+ const name = typeof filename === 'string' ? filename : '';
63
+ if (name.includes('node_modules') || name.includes('.git') || name.endsWith('~'))
64
+ return;
65
+ if (reloadTimer)
66
+ clearTimeout(reloadTimer);
67
+ reloadTimer = setTimeout(runReload, 150);
68
+ });
69
+ // A later recursive-watch failure emits 'error'; without a listener Node would crash the process.
70
+ // Degrade gracefully instead — stop watching, keep the preview server running.
71
+ watcher.on('error', (error) => {
72
+ log(`↻ hot reload stopped (watch error): ${error instanceof Error ? error.message : String(error)}`);
73
+ if (reloadTimer)
74
+ clearTimeout(reloadTimer);
75
+ watcher?.close();
76
+ watcher = undefined;
77
+ });
78
+ }
79
+ catch {
80
+ // Recursive watch is unsupported on some platforms; hot-reload is best-effort.
81
+ }
82
+ return {
83
+ preview,
84
+ loadedEnv,
85
+ watching: watcher !== undefined,
86
+ close: async () => {
87
+ if (reloadTimer)
88
+ clearTimeout(reloadTimer);
89
+ watcher?.close();
90
+ await preview.close();
91
+ },
92
+ };
93
+ }
94
+ // Warm-on-stone palette shared with `noodle init` / first-run. Auto-degrades to plain text off a TTY.
95
+ const INK = [231, 229, 228];
96
+ const DIM = [168, 162, 158];
97
+ const FAINT = [120, 113, 108];
98
+ const GREEN = [74, 222, 128];
99
+ /**
100
+ * The branded banner for a running preview — the same warm palette + glyphs as `noodle init`. Returns lines
101
+ * (the caller prints them) so it stays testable; ANSI is emitted only on an interactive stdout.
102
+ */
103
+ export function previewBannerLines(session, opts) {
104
+ const mode = detectColorMode(process.stdout);
105
+ const glyph = detectGlyphMode();
106
+ const gg = (unicode, ascii) => (glyph === 'ascii' ? ascii : unicode);
107
+ const p = (rgb, s) => paint(rgb, s, mode);
108
+ const key = (s) => p(DIM, s.padEnd(9));
109
+ const model = opts.model ?? process.env.OPENAI_MODEL ?? 'gpt-5.5';
110
+ const lines = [
111
+ '',
112
+ `${p(ORANGE, gg('◆', '*'))} ${p(INK, opts.title)} ${p(FAINT, gg('· preview ready', '- preview ready'))}`,
113
+ ` ${key('preview')}${p(ORANGE, session.preview.url)}`,
114
+ ` ${key('mcp')}${p(DIM, opts.mcpUrl)}`,
115
+ ` ${key('view')}${p(FAINT, `theme ${opts.theme} · device ${opts.device}`)}`,
116
+ ];
117
+ if (process.env.OPENAI_API_KEY) {
118
+ const src = session.loadedEnv.keys.includes('OPENAI_API_KEY')
119
+ ? ` · from ${session.loadedEnv.file}`
120
+ : '';
121
+ lines.push(` ${key('chat')}${p(GREEN, gg('✔', '+'))} ${p(FAINT, `model ${model}${src}`)}`);
122
+ }
123
+ else {
124
+ lines.push(` ${key('chat')}${p(AMBER, gg('⚠', '!'))} ${p(FAINT, `add your OpenAI key in the Chat tab · model ${model}`)}`);
125
+ }
126
+ if (session.watching) {
127
+ lines.push(` ${key('watch')}${p(FAINT, `${opts.watchDir} · edit + save to hot-reload`)}`);
128
+ }
129
+ lines.push('');
130
+ return lines;
131
+ }
132
+ //# sourceMappingURL=preview-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-session.js","sourceRoot":"","sources":["../src/preview-session.ts"],"names":[],"mappings":"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"}
package/dist/project.d.ts CHANGED
@@ -23,7 +23,9 @@ export interface NoodleProjectConfig {
23
23
  }
24
24
  export interface ProjectDeployment {
25
25
  readonly deploymentId: string;
26
+ readonly serverVersion?: string;
26
27
  readonly url: string;
28
+ readonly defaultUrl?: string;
27
29
  readonly org: string;
28
30
  readonly app: string;
29
31
  readonly env: string;
@@ -1 +1 @@
1
- {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}