@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,76 @@
1
+ /**
2
+ * The `noodle devtools` chat playground agent loop. Runs entirely inside the local preview server: it
3
+ * calls an OpenAI-compatible chat-completions endpoint, and whenever the model requests a tool it invokes
4
+ * the caller-supplied `callTool` (which the preview server wires to the loopback `dev` MCP endpoint through
5
+ * its `/rpc` forwarder). The OpenAI API key stays server-side — it is never sent to the browser or logged.
6
+ *
7
+ * This is an extension of `dev`'s local, loopback-only tool exercise, not a general MCP client (ADR 0043):
8
+ * the agent can only reach the tools of the local server the devtools session is already previewing.
9
+ */
10
+ /** The default model — overridable per session via `--model` or `OPENAI_MODEL`. */
11
+ export declare const DEFAULT_CHAT_MODEL = "gpt-5.5";
12
+ /** An OpenAI chat-completions message (subset we produce/consume). */
13
+ export interface ChatMessage {
14
+ readonly role: 'system' | 'user' | 'assistant' | 'tool';
15
+ readonly content?: string | null;
16
+ readonly tool_calls?: ReadonlyArray<{
17
+ readonly id: string;
18
+ readonly type: 'function';
19
+ readonly function: {
20
+ readonly name: string;
21
+ readonly arguments: string;
22
+ };
23
+ }>;
24
+ readonly tool_call_id?: string;
25
+ }
26
+ /** A tool the agent may call, projected from the MCP `tools/list` entry. */
27
+ export interface ChatToolDef {
28
+ readonly name: string;
29
+ readonly description?: string;
30
+ readonly inputSchema?: Record<string, unknown>;
31
+ /** `ui://` resource URI when the tool renders a widget — carried through for inline rendering. */
32
+ readonly resourceUri?: string;
33
+ }
34
+ export interface OpenAiFunctionTool {
35
+ readonly type: 'function';
36
+ readonly function: {
37
+ readonly name: string;
38
+ readonly description?: string;
39
+ readonly parameters: Record<string, unknown>;
40
+ };
41
+ }
42
+ /** A tool the agent actually called this turn, with its inputs/outputs, for inline rendering. */
43
+ export interface ChatToolInvocation {
44
+ readonly name: string;
45
+ readonly arguments: unknown;
46
+ readonly result: unknown;
47
+ readonly isError: boolean;
48
+ readonly resourceUri?: string;
49
+ }
50
+ export interface ChatTurnResult {
51
+ /** The full conversation including the new assistant/tool messages — the browser resends it next turn. */
52
+ readonly messages: ChatMessage[];
53
+ readonly toolCalls: ChatToolInvocation[];
54
+ readonly text: string;
55
+ }
56
+ /** Project MCP tool defs into OpenAI function-tool schema. */
57
+ export declare function toOpenAiTools(tools: readonly ChatToolDef[]): OpenAiFunctionTool[];
58
+ /**
59
+ * Run one playground turn: call the model, execute any tool calls it requests against `callTool`, feed the
60
+ * results back, and repeat until the model returns a plain answer (or the iteration cap is hit).
61
+ */
62
+ export declare function runChatTurn(opts: {
63
+ readonly messages: readonly ChatMessage[];
64
+ readonly tools: readonly ChatToolDef[];
65
+ readonly apiKey: string;
66
+ readonly model: string;
67
+ readonly callTool: (name: string, args: unknown) => Promise<{
68
+ result: unknown;
69
+ isError: boolean;
70
+ }>;
71
+ readonly fetchImpl?: typeof fetch;
72
+ readonly baseUrl?: string;
73
+ readonly maxIterations?: number;
74
+ readonly timeoutMs?: number;
75
+ }): Promise<ChatTurnResult>;
76
+ //# sourceMappingURL=devtools-chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools-chat.d.ts","sourceRoot":"","sources":["../src/devtools-chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,mFAAmF;AACnF,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAO5C,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC;QAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;QAC1B,QAAQ,CAAC,QAAQ,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;KAC1E,CAAC,CAAC;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,kGAAkG;IAClG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC9C,CAAC;CACH;AAED,iGAAiG;AACjG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,0GAA0G;IAC1G,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,kBAAkB,EAAE,CASjF;AAMD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,CACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,KACV,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B,GAAG,OAAO,CAAC,cAAc,CAAC,CAkF1B"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * The `noodle devtools` chat playground agent loop. Runs entirely inside the local preview server: it
3
+ * calls an OpenAI-compatible chat-completions endpoint, and whenever the model requests a tool it invokes
4
+ * the caller-supplied `callTool` (which the preview server wires to the loopback `dev` MCP endpoint through
5
+ * its `/rpc` forwarder). The OpenAI API key stays server-side — it is never sent to the browser or logged.
6
+ *
7
+ * This is an extension of `dev`'s local, loopback-only tool exercise, not a general MCP client (ADR 0043):
8
+ * the agent can only reach the tools of the local server the devtools session is already previewing.
9
+ */
10
+ /** The default model — overridable per session via `--model` or `OPENAI_MODEL`. */
11
+ export const DEFAULT_CHAT_MODEL = 'gpt-5.5';
12
+ const OPENAI_DEFAULT_BASE = 'https://api.openai.com/v1';
13
+ const DEFAULT_MAX_ITERATIONS = 8;
14
+ /** Per-request timeout so a hung/slow OpenAI-compatible endpoint can't block the /chat route forever. */
15
+ const DEFAULT_REQUEST_TIMEOUT_MS = 60_000;
16
+ /** Project MCP tool defs into OpenAI function-tool schema. */
17
+ export function toOpenAiTools(tools) {
18
+ return tools.map((t) => ({
19
+ type: 'function',
20
+ function: {
21
+ name: t.name,
22
+ ...(t.description ? { description: t.description } : {}),
23
+ parameters: t.inputSchema ?? { type: 'object', properties: {} },
24
+ },
25
+ }));
26
+ }
27
+ /**
28
+ * Run one playground turn: call the model, execute any tool calls it requests against `callTool`, feed the
29
+ * results back, and repeat until the model returns a plain answer (or the iteration cap is hit).
30
+ */
31
+ export async function runChatTurn(opts) {
32
+ const doFetch = opts.fetchImpl ?? fetch;
33
+ const base = (opts.baseUrl ?? OPENAI_DEFAULT_BASE).replace(/\/+$/, '');
34
+ const openAiTools = toOpenAiTools(opts.tools);
35
+ const byName = new Map(opts.tools.map((t) => [t.name, t]));
36
+ const messages = [...opts.messages];
37
+ const toolCalls = [];
38
+ const maxIterations = opts.maxIterations ?? DEFAULT_MAX_ITERATIONS;
39
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
40
+ for (let iteration = 0; iteration < maxIterations; iteration += 1) {
41
+ // Bound each request: a hung OpenAI-compatible endpoint (BYO baseUrl/key) must not block the /chat
42
+ // route forever. Abort after timeoutMs and surface it as a clear timeout error, not a raw AbortError.
43
+ const controller = new AbortController();
44
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
45
+ let res;
46
+ try {
47
+ res = await doFetch(`${base}/chat/completions`, {
48
+ method: 'POST',
49
+ headers: { 'content-type': 'application/json', authorization: `Bearer ${opts.apiKey}` },
50
+ body: JSON.stringify({
51
+ model: opts.model,
52
+ messages,
53
+ ...(openAiTools.length > 0 ? { tools: openAiTools, tool_choice: 'auto' } : {}),
54
+ }),
55
+ signal: controller.signal,
56
+ });
57
+ }
58
+ catch (error) {
59
+ if (controller.signal.aborted) {
60
+ throw new Error(`OpenAI request timed out after ${Math.round(timeoutMs / 1000)}s`);
61
+ }
62
+ throw error;
63
+ }
64
+ finally {
65
+ clearTimeout(timer);
66
+ }
67
+ if (!res.ok) {
68
+ const detail = await res.text().catch(() => '');
69
+ throw new Error(`OpenAI request failed (${res.status}): ${detail.slice(0, 500)}`);
70
+ }
71
+ const data = (await res.json());
72
+ const message = data.choices?.[0]?.message;
73
+ if (!message)
74
+ throw new Error('OpenAI returned no message in the completion.');
75
+ messages.push(message);
76
+ const calls = message.tool_calls ?? [];
77
+ if (calls.length === 0) {
78
+ return {
79
+ messages,
80
+ toolCalls,
81
+ text: typeof message.content === 'string' ? message.content : '',
82
+ };
83
+ }
84
+ for (const call of calls) {
85
+ let args = {};
86
+ try {
87
+ args = call.function.arguments ? JSON.parse(call.function.arguments) : {};
88
+ }
89
+ catch {
90
+ args = {};
91
+ }
92
+ const def = byName.get(call.function.name);
93
+ const { result, isError } = await opts.callTool(call.function.name, args);
94
+ toolCalls.push({
95
+ name: call.function.name,
96
+ arguments: args,
97
+ result,
98
+ isError,
99
+ ...(def?.resourceUri ? { resourceUri: def.resourceUri } : {}),
100
+ });
101
+ messages.push({
102
+ role: 'tool',
103
+ tool_call_id: call.id,
104
+ content: typeof result === 'string' ? result : JSON.stringify(result ?? null),
105
+ });
106
+ }
107
+ }
108
+ return {
109
+ messages,
110
+ toolCalls,
111
+ text: 'Stopped after reaching the tool-call limit for this turn. Ask a follow-up to continue.',
112
+ };
113
+ }
114
+ //# sourceMappingURL=devtools-chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools-chat.js","sourceRoot":"","sources":["../src/devtools-chat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Parse dotenv-style `KEY=VALUE` text, tolerating comments, blank lines, `export`, and simple quotes. */
2
+ export declare function parseDotenv(text: string): Record<string, string>;
3
+ export interface LoadedDevtoolsEnv {
4
+ /** The env file the values came from (relative name), or undefined if none was found/applied. */
5
+ readonly file?: string;
6
+ /** The `OPENAI_*` key names applied to the environment (never the values). */
7
+ readonly keys: string[];
8
+ }
9
+ /**
10
+ * Read `.env.local` then `.env` from `dir` and apply any `OPENAI_*` keys to `env` (default `process.env`)
11
+ * without overriding values that are already set. Returns which file and keys were applied for logging.
12
+ */
13
+ export declare function loadDevtoolsEnv(dir: string, opts?: {
14
+ env?: Record<string, string | undefined>;
15
+ }): LoadedDevtoolsEnv;
16
+ //# sourceMappingURL=devtools-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools-env.d.ts","sourceRoot":"","sources":["../src/devtools-env.ts"],"names":[],"mappings":"AAkBA,0GAA0G;AAC1G,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoBhE;AAED,MAAM,WAAW,iBAAiB;IAChC,iGAAiG;IACjG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CAAO,GACtD,iBAAiB,CAsBnB"}
@@ -0,0 +1,71 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ /**
4
+ * Load the OpenAI playground credentials for `noodle devtools` from a git-ignored `.env.local` (or `.env`)
5
+ * in the project directory. This is developer-tooling config — NOT an app secret. It is intentionally kept
6
+ * out of the managed `.env.noodle` / `noodle secrets` store (which is brokered to the deployed app runtime).
7
+ *
8
+ * Safety rules:
9
+ * - only `OPENAI_*` keys are read from the file, so a stray `.env` can never clobber `PATH` or other env;
10
+ * - a value already present in the environment always wins (shell/flag precedence over the file);
11
+ * - values are never logged — only key names and the file name are surfaced.
12
+ */
13
+ const ENV_FILES = ['.env.local', '.env'];
14
+ const KEY_PREFIX = 'OPENAI_';
15
+ const LINE = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/;
16
+ /** Parse dotenv-style `KEY=VALUE` text, tolerating comments, blank lines, `export`, and simple quotes. */
17
+ export function parseDotenv(text) {
18
+ const out = {};
19
+ for (const raw of text.split(/\r?\n/)) {
20
+ const line = raw.trim();
21
+ if (line === '' || line.startsWith('#'))
22
+ continue;
23
+ const match = LINE.exec(line);
24
+ if (!match)
25
+ continue;
26
+ const key = match[1];
27
+ if (key === undefined)
28
+ continue;
29
+ let value = (match[2] ?? '').trim();
30
+ if (value.length >= 2 &&
31
+ ((value.startsWith('"') && value.endsWith('"')) ||
32
+ (value.startsWith("'") && value.endsWith("'")))) {
33
+ value = value.slice(1, -1);
34
+ }
35
+ out[key] = value;
36
+ }
37
+ return out;
38
+ }
39
+ /**
40
+ * Read `.env.local` then `.env` from `dir` and apply any `OPENAI_*` keys to `env` (default `process.env`)
41
+ * without overriding values that are already set. Returns which file and keys were applied for logging.
42
+ */
43
+ export function loadDevtoolsEnv(dir, opts = {}) {
44
+ const env = opts.env ?? process.env;
45
+ const keys = [];
46
+ let file;
47
+ for (const name of ENV_FILES) {
48
+ const path = join(dir, name);
49
+ if (!existsSync(path))
50
+ continue;
51
+ let parsed;
52
+ try {
53
+ parsed = parseDotenv(readFileSync(path, 'utf8'));
54
+ }
55
+ catch {
56
+ continue;
57
+ }
58
+ for (const [key, value] of Object.entries(parsed)) {
59
+ if (!key.startsWith(KEY_PREFIX))
60
+ continue;
61
+ if (env[key] !== undefined && env[key] !== '')
62
+ continue;
63
+ env[key] = value;
64
+ keys.push(key);
65
+ if (file === undefined)
66
+ file = name;
67
+ }
68
+ }
69
+ return { keys, ...(file !== undefined ? { file } : {}) };
70
+ }
71
+ //# sourceMappingURL=devtools-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools-env.js","sourceRoot":"","sources":["../src/devtools-env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The `noodle devtools` browser harness: the three-pane shell HTML/CSS, the client script, the
3
+ * `window.openai` shim injected into widget iframes, and small HTML helpers. Kept separate from the
4
+ * preview server (`devtools-preview.ts`) so each file owns one concern.
5
+ *
6
+ * The client script is plain (no template literals / no `${...}`) so it splices safely into the shell
7
+ * and so the shim's classic script runs before the widget's deferred bridge module.
8
+ */
9
+ export type PreviewTheme = 'light' | 'dark' | 'both';
10
+ export type PreviewDevice = 'desktop' | 'mobile' | 'both';
11
+ /** Build the classic (non-module) `window.openai` shim injected ahead of the deferred widget bridge. */
12
+ export declare function openAiShimScript(init: {
13
+ readonly toolInput?: unknown;
14
+ readonly toolOutput?: unknown;
15
+ readonly toolResponseMetadata?: unknown;
16
+ readonly theme?: 'light' | 'dark';
17
+ }): string;
18
+ /** Insert the reset + shim into the widget document so they run before the (deferred) bridge module script. */
19
+ export declare function wrapWidgetHtml(html: string, shimScript: string): string;
20
+ /** The three-pane harness shell. */
21
+ export declare function harnessHtml(options: {
22
+ readonly mcpUrl: string;
23
+ readonly theme: PreviewTheme;
24
+ readonly device: PreviewDevice;
25
+ /** True when the server already has an OPENAI_API_KEY, so the chat key-entry gate can be skipped. */
26
+ readonly hasServerKey?: boolean;
27
+ }): string;
28
+ //# sourceMappingURL=devtools-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools-harness.d.ts","sourceRoot":"","sources":["../src/devtools-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AACrD,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;AAgB1D,wGAAwG;AACxG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACnC,GAAG,MAAM,CA4BT;AAUD,+GAA+G;AAC/G,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAcvE;AAcD,oCAAoC;AACpC,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,qGAAqG;IACrG,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC,GAAG,MAAM,CA8ET"}