veryfront 0.1.16 → 0.1.17

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 (45) hide show
  1. package/esm/cli/app/handlers/view-handlers.d.ts +0 -9
  2. package/esm/cli/app/handlers/view-handlers.d.ts.map +1 -1
  3. package/esm/cli/app/handlers/view-handlers.js +4 -32
  4. package/esm/cli/app/shell.d.ts.map +1 -1
  5. package/esm/cli/app/shell.js +5 -41
  6. package/esm/cli/app/views/dashboard.d.ts.map +1 -1
  7. package/esm/cli/app/views/dashboard.js +1 -12
  8. package/esm/cli/app/views/index.d.ts +0 -1
  9. package/esm/cli/app/views/index.d.ts.map +1 -1
  10. package/esm/cli/app/views/index.js +0 -1
  11. package/esm/cli/app/views/new-project.d.ts.map +1 -1
  12. package/esm/cli/app/views/new-project.js +0 -1
  13. package/esm/cli/commands/start/command-help.d.ts.map +1 -1
  14. package/esm/cli/commands/start/command-help.js +0 -1
  15. package/esm/cli/commands/start/command.js +2 -2
  16. package/esm/deno.js +1 -1
  17. package/esm/src/agent/chat-handler.d.ts.map +1 -1
  18. package/esm/src/agent/chat-handler.js +11 -2
  19. package/esm/src/modules/server/module-server.d.ts.map +1 -1
  20. package/esm/src/modules/server/module-server.js +46 -14
  21. package/esm/src/rendering/rsc/client-boot.ts +161 -0
  22. package/esm/src/rendering/rsc/client-dom.ts +169 -0
  23. package/esm/src/rendering/rsc/client-hydrator.ts +207 -0
  24. package/esm/src/rendering/rsc/hydrate-client.ts +207 -0
  25. package/esm/src/server/runtime-handler/adapter-factory.js +1 -1
  26. package/esm/src/server/runtime-handler/local-project-discovery.d.ts +1 -1
  27. package/esm/src/server/runtime-handler/local-project-discovery.d.ts.map +1 -1
  28. package/esm/src/server/runtime-handler/local-project-discovery.js +2 -2
  29. package/package.json +1 -1
  30. package/src/cli/app/handlers/view-handlers.ts +4 -42
  31. package/src/cli/app/shell.ts +3 -47
  32. package/src/cli/app/views/dashboard.ts +1 -16
  33. package/src/cli/app/views/index.ts +0 -1
  34. package/src/cli/app/views/new-project.ts +0 -1
  35. package/src/cli/commands/start/command-help.ts +0 -1
  36. package/src/cli/commands/start/command.ts +2 -2
  37. package/src/deno.js +1 -1
  38. package/src/src/agent/chat-handler.ts +14 -2
  39. package/src/src/modules/server/module-server.ts +47 -15
  40. package/src/src/server/runtime-handler/adapter-factory.ts +1 -1
  41. package/src/src/server/runtime-handler/local-project-discovery.ts +2 -2
  42. package/esm/cli/app/views/examples.d.ts +0 -8
  43. package/esm/cli/app/views/examples.d.ts.map +0 -1
  44. package/esm/cli/app/views/examples.js +0 -25
  45. package/src/cli/app/views/examples.ts +0 -35
@@ -6,13 +6,11 @@
6
6
  */
7
7
  import type { AppState, StateUpdater } from "../state.js";
8
8
  import type { InitTemplate } from "../../commands/init/types.js";
9
- import type { ProjectInfo } from "../state.js";
10
9
  export interface ViewHandlerContext {
11
10
  state: AppState;
12
11
  render: () => void;
13
12
  update: (updater: StateUpdater) => void;
14
13
  promptForProjectName: (template: InitTemplate, onCancel: () => void) => void;
15
- promptForExampleProject: (example: ProjectInfo, onCancel: () => void) => void;
16
14
  }
17
15
  /**
18
16
  * Handle keyboard input in the templates view
@@ -21,13 +19,6 @@ export declare function handleTemplatesKey(key: string, ctx: ViewHandlerContext)
21
19
  state: AppState;
22
20
  handled: boolean;
23
21
  };
24
- /**
25
- * Handle keyboard input in the examples view
26
- */
27
- export declare function handleExamplesKey(key: string, ctx: ViewHandlerContext): {
28
- state: AppState;
29
- handled: boolean;
30
- };
31
22
  /**
32
23
  * Handle keyboard input in the new-project view
33
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"view-handlers.d.ts","sourceRoot":"","sources":["../../../../src/cli/app/handlers/view-handlers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAU/C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC7E,uBAAuB,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC/E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,kBAAkB,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAyBvC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,kBAAkB,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAyBvC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,kBAAkB,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA0CvC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,kBAAkB,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA2DvC"}
1
+ {"version":3,"file":"view-handlers.d.ts","sourceRoot":"","sources":["../../../../src/cli/app/handlers/view-handlers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAUjE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC9E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,kBAAkB,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAyBvC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,kBAAkB,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAuCvC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,kBAAkB,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA2DvC"}
@@ -38,31 +38,6 @@ export function handleTemplatesKey(key, ctx) {
38
38
  }
39
39
  return { state, handled: false };
40
40
  }
41
- /**
42
- * Handle keyboard input in the examples view
43
- */
44
- export function handleExamplesKey(key, ctx) {
45
- const { state, render, promptForExampleProject } = ctx;
46
- if (key === KEY_UP || key === "k") {
47
- const newState = { ...state, examples: moveUp(state.examples) };
48
- return { state: newState, handled: true };
49
- }
50
- if (key === KEY_DOWN || key === "j") {
51
- const newState = {
52
- ...state,
53
- examples: moveDown(state.examples, state.examples.items.length),
54
- };
55
- return { state: newState, handled: true };
56
- }
57
- if (key === KEY_ENTER || key === KEY_NEWLINE) {
58
- const selected = state.examples.items[state.examples.selectedIndex];
59
- if (selected?.data) {
60
- promptForExampleProject(selected.data, () => render());
61
- }
62
- return { state, handled: true };
63
- }
64
- return { state, handled: false };
65
- }
66
41
  /**
67
42
  * Handle keyboard input in the new-project view
68
43
  */
@@ -71,22 +46,22 @@ export function handleNewProjectKey(key, ctx) {
71
46
  if (key === KEY_UP || key === "k") {
72
47
  const newState = {
73
48
  ...state,
74
- newProjectIndex: state.newProjectIndex > 0 ? state.newProjectIndex - 1 : 2,
49
+ newProjectIndex: state.newProjectIndex > 0 ? state.newProjectIndex - 1 : 1,
75
50
  };
76
51
  return { state: newState, handled: true };
77
52
  }
78
53
  if (key === KEY_DOWN || key === "j") {
79
54
  const newState = {
80
55
  ...state,
81
- newProjectIndex: state.newProjectIndex < 2 ? state.newProjectIndex + 1 : 0,
56
+ newProjectIndex: state.newProjectIndex < 1 ? state.newProjectIndex + 1 : 0,
82
57
  };
83
58
  return { state: newState, handled: true };
84
59
  }
85
- if (key >= "1" && key <= "3") {
60
+ if (key >= "1" && key <= "2") {
86
61
  const newState = { ...state, newProjectIndex: parseInt(key, 10) - 1 };
87
62
  return { state: newState, handled: true };
88
63
  }
89
- if (key !== KEY_ENTER && key !== KEY_NEWLINE && !(key >= "1" && key <= "3")) {
64
+ if (key !== KEY_ENTER && key !== KEY_NEWLINE && !(key >= "1" && key <= "2")) {
90
65
  return { state, handled: false };
91
66
  }
92
67
  // Handle selection
@@ -95,9 +70,6 @@ export function handleNewProjectKey(key, ctx) {
95
70
  update(navigateTo("templates"));
96
71
  return { state, handled: true };
97
72
  case 1:
98
- update(navigateTo("examples"));
99
- return { state, handled: true };
100
- case 2:
101
73
  promptForProjectName("minimal", () => render());
102
74
  return { state, handled: true };
103
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/cli/app/shell.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAqEjD;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,GAAG,CAymBhD"}
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/cli/app/shell.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAiEjD;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,GAAG,CAikBhD"}
@@ -11,10 +11,10 @@ import { createEscapeBuffer, getStdinReader, setRawMode } from "../../src/platfo
11
11
  import { cursor, screen } from "../ui/ansi.js";
12
12
  import { dim } from "../ui/colors.js";
13
13
  import { getTerminalWidth } from "../ui/layout.js";
14
- import { addLog, createInitialState, endInput, getActiveSelection, goBack, navigateTo, scrollLogs, setActiveList, setExamples, setProjects, setTemplates, startInput, toggleHelp, toggleLogsExpanded, updateActiveList, updateInputValue, updateMCP, updateRemote, updateServer, } from "./state.js";
14
+ import { addLog, createInitialState, endInput, getActiveSelection, goBack, navigateTo, scrollLogs, setActiveList, setProjects, setTemplates, startInput, toggleHelp, toggleLogsExpanded, updateActiveList, updateInputValue, updateMCP, updateRemote, updateServer, } from "./state.js";
15
15
  import { moveDown, moveUp, selectByNumber } from "./components/list-select.js";
16
16
  import { handleInputKey, renderInput, renderLogs } from "./components/inline-input.js";
17
- import { renderAuthView, renderDashboard, renderEmptyState, renderExamplesView, renderHelpView, renderNewProjectView, renderTemplatesView, } from "./views/index.js";
17
+ import { renderAuthView, renderDashboard, renderEmptyState, renderHelpView, renderNewProjectView, renderTemplatesView, } from "./views/index.js";
18
18
  import { openInBrowser, openInIDE, openInStudio, openMCPSettings } from "./actions.js";
19
19
  import { generateRandomSlug, pullRemoteProject } from "./utils.js";
20
20
  import { logout, validateToken } from "../auth/login.js";
@@ -25,8 +25,8 @@ import { pullCommand } from "../commands/pull/index.js";
25
25
  import { pushCommand } from "../commands/push/index.js";
26
26
  // Import extracted modules
27
27
  import { moveRemoteFocusDown, moveRemoteFocusUp, updateRemoteFocus, } from "./handlers/remote-navigation.js";
28
- import { handleAuthKey, handleExamplesKey, handleNewProjectKey, handleTemplatesKey, } from "./handlers/view-handlers.js";
29
- import { createProject, createProjectFromExample } from "./operations/project-creation.js";
28
+ import { handleAuthKey, handleNewProjectKey, handleTemplatesKey, } from "./handlers/view-handlers.js";
29
+ import { createProject } from "./operations/project-creation.js";
30
30
  import { interceptConsole } from "./logging/console-interceptor.js";
31
31
  const KEY_UP = "\x1b[A";
32
32
  const KEY_DOWN = "\x1b[B";
@@ -43,15 +43,9 @@ export function createApp(config) {
43
43
  let spinnerInterval = null;
44
44
  const isInteractiveMode = !config.headless && isInteractive() && isStdoutTTY();
45
45
  state = setProjects(Array.from(config.projects.entries()).map(([slug, path]) => ({ slug, path })))(state);
46
- if (config.examples) {
47
- state = setExamples(Array.from(config.examples.entries()).map(([slug, path]) => ({ slug, path })))(state);
48
- }
49
46
  if (state.projects.items.length > 0) {
50
47
  state = { ...state, activeList: "projects" };
51
48
  }
52
- else if (state.examples.items.length > 0) {
53
- state = { ...state, activeList: "examples" };
54
- }
55
49
  state = setTemplates([
56
50
  { id: "chat", name: "AI Chatbot", description: "Agent + chat UI + streaming" },
57
51
  { id: "rag", name: "Chat with Docs", description: "RAG with source citations" },
@@ -94,7 +88,7 @@ export function createApp(config) {
94
88
  let content;
95
89
  switch (state.view) {
96
90
  case "dashboard":
97
- content = state.projects.items.length > 0 || state.examples.items.length > 0
91
+ content = state.projects.items.length > 0
98
92
  ? renderDashboard(state)
99
93
  : renderEmptyState(state);
100
94
  break;
@@ -104,9 +98,6 @@ export function createApp(config) {
104
98
  case "templates":
105
99
  content = renderTemplatesView(state);
106
100
  break;
107
- case "examples":
108
- content = renderExamplesView(state);
109
- break;
110
101
  case "auth":
111
102
  content = renderAuthView(state);
112
103
  break;
@@ -177,9 +168,6 @@ export function createApp(config) {
177
168
  function promptForProjectName(template, onCancel) {
178
169
  return promptForProjectWithSource(template, createProject, onCancel);
179
170
  }
180
- function promptForExampleProject(example, onCancel) {
181
- return promptForProjectWithSource(example, createProjectFromExample, onCancel);
182
- }
183
171
  // View handler context for delegating to extracted handlers
184
172
  function getViewHandlerContext() {
185
173
  return {
@@ -187,7 +175,6 @@ export function createApp(config) {
187
175
  render,
188
176
  update,
189
177
  promptForProjectName,
190
- promptForExampleProject,
191
178
  };
192
179
  }
193
180
  async function handleKey(key) {
@@ -237,14 +224,6 @@ export function createApp(config) {
237
224
  }
238
225
  return;
239
226
  }
240
- case "examples": {
241
- const result = handleExamplesKey(key, ctx);
242
- if (result.handled) {
243
- state = result.state;
244
- render();
245
- }
246
- return;
247
- }
248
227
  case "new-project": {
249
228
  const result = handleNewProjectKey(key, ctx);
250
229
  if (result.handled) {
@@ -302,15 +281,12 @@ export function createApp(config) {
302
281
  // Tab to switch sections
303
282
  if (key === "\t") {
304
283
  const hasProjects = state.projects.items.length > 0;
305
- const hasExamples = state.examples.items.length > 0;
306
284
  const hasRemoteProjects = !!state.remote.user && state.remote.projects.length > 0;
307
285
  const sections = [];
308
286
  if (hasProjects)
309
287
  sections.push("projects");
310
288
  if (hasRemoteProjects)
311
289
  sections.push("remoteProjects");
312
- if (hasExamples)
313
- sections.push("examples");
314
290
  if (sections.length > 1) {
315
291
  const currentIndex = sections.indexOf(state.activeList);
316
292
  const nextIndex = (currentIndex + 1) % sections.length;
@@ -361,18 +337,6 @@ export function createApp(config) {
361
337
  return;
362
338
  }
363
339
  }
364
- if (key >= "a" && key <= "z" && key !== "j" && key !== "k" && key !== "p" && key !== "u" &&
365
- state.activeList === "examples") {
366
- const num = key.charCodeAt(0) - 96;
367
- if (num <= state.examples.items.length) {
368
- state = { ...state, examples: selectByNumber(state.examples, num) };
369
- render();
370
- const selected = state.examples.items[num - 1];
371
- if (selected?.data)
372
- await openInBrowser(selected.data, state.server.port);
373
- return;
374
- }
375
- }
376
340
  // Open selected item
377
341
  if (key === KEY_ENTER || key === KEY_NEWLINE) {
378
342
  if (state.activeList === "remoteProjects") {
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../../src/cli/app/views/dashboard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAwEvD;AAwGD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAY5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAQxD"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../../src/cli/app/views/dashboard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAyDvD;AAwGD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAY5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAQxD"}
@@ -17,7 +17,6 @@ export function renderDashboard(state) {
17
17
  const lines = [];
18
18
  lines.push(renderBanner(state), "");
19
19
  const hasProjects = state.projects.items.length > 0;
20
- const hasExamples = state.examples.items.length > 0;
21
20
  const hasRemoteProjects = !!state.remote.user && state.remote.projects.length > 0;
22
21
  if (hasProjects) {
23
22
  const isActive = state.activeList === "projects";
@@ -53,16 +52,6 @@ export function renderDashboard(state) {
53
52
  }
54
53
  lines.push("");
55
54
  }
56
- if (hasExamples) {
57
- const isActive = state.activeList === "examples";
58
- lines.push(renderSection("Examples", isActive));
59
- lines.push(renderList(state.examples, {
60
- maxWidth: maxListWidth,
61
- visibleCount: 5,
62
- showNumbers: true,
63
- showSelection: isActive,
64
- }), "");
65
- }
66
55
  lines.push(renderHelpBar(state));
67
56
  return lines.join("\n");
68
57
  }
@@ -126,7 +115,7 @@ function renderSection(title, isActive = true) {
126
115
  * Render the help bar at the bottom
127
116
  */
128
117
  function renderHelpBar(state) {
129
- const hasItems = state.projects.items.length > 0 || state.examples.items.length > 0 ||
118
+ const hasItems = state.projects.items.length > 0 ||
130
119
  (!!state.remote.user && state.remote.projects.length > 0);
131
120
  if (!state.showHelp) {
132
121
  const userInfo = state.remote.user ? ` ${dim("-")} ${brand(state.remote.user.email)}` : "";
@@ -6,7 +6,6 @@
6
6
  export { renderDashboard, renderEmptyState } from "./dashboard.js";
7
7
  export { createStartupState, incrementFrame, renderStartup, setStepActive } from "./startup.js";
8
8
  export { renderTemplatesView } from "./templates.js";
9
- export { renderExamplesView } from "./examples.js";
10
9
  export { renderHelpView } from "./help.js";
11
10
  export { renderNewProjectView } from "./new-project.js";
12
11
  export { renderAuthView } from "./auth.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/app/views/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/app/views/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
@@ -6,7 +6,6 @@
6
6
  export { renderDashboard, renderEmptyState } from "./dashboard.js";
7
7
  export { createStartupState, incrementFrame, renderStartup, setStepActive } from "./startup.js";
8
8
  export { renderTemplatesView } from "./templates.js";
9
- export { renderExamplesView } from "./examples.js";
10
9
  export { renderHelpView } from "./help.js";
11
10
  export { renderNewProjectView } from "./new-project.js";
12
11
  export { renderAuthView } from "./auth.js";
@@ -1 +1 @@
1
- {"version":3,"file":"new-project.d.ts","sourceRoot":"","sources":["../../../../src/cli/app/views/new-project.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CA2B5D"}
1
+ {"version":3,"file":"new-project.d.ts","sourceRoot":"","sources":["../../../../src/cli/app/views/new-project.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CA0B5D"}
@@ -7,7 +7,6 @@ import { brand, dim } from "../../ui/colors.js";
7
7
  export function renderNewProjectView(state) {
8
8
  const options = [
9
9
  { label: "From template", desc: "Start with a pre-built template" },
10
- { label: "From example", desc: "Copy an example project" },
11
10
  { label: "From scratch", desc: "Empty project" },
12
11
  ];
13
12
  const lines = [
@@ -1 +1 @@
1
- {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/start/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,SAAS,EAAE,WAiDvB,CAAC"}
1
+ {"version":3,"file":"command-help.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/start/command-help.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,SAAS,EAAE,WAgDvB,CAAC"}
@@ -45,6 +45,5 @@ export const startHelp = {
45
45
  " app/",
46
46
  " site-b/ # auto-discovered",
47
47
  " app/",
48
- " examples/ # also scanned",
49
48
  ],
50
49
  };
@@ -40,10 +40,10 @@ async function findProjectsInDirs(baseDirs) {
40
40
  return projects;
41
41
  }
42
42
  async function discoverProjects(explicitPath) {
43
- const [projects, examples] = await Promise.all([
43
+ const [projects] = await Promise.all([
44
44
  findProjectsInDirs(["data/projects", "projects"]),
45
- findProjectsInDirs(["examples"]),
46
45
  ]);
46
+ const examples = new Map();
47
47
  const fs = createFileSystem();
48
48
  let defaultProject = null;
49
49
  if (explicitPath) {
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "nodeModulesDir": "auto",
5
5
  "exclude": [
6
6
  "npm/",
@@ -1 +1 @@
1
- {"version":3,"file":"chat-handler.d.ts","sourceRoot":"","sources":["../../../src/src/agent/chat-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AA4H/C,MAAM,WAAW,kBAAkB;IACjC,uFAAuF;IACvF,OAAO,CAAC,EACJ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,CAAC,CACD,OAAO,EAAE,OAAO,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACpE;AAeD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kBAAkB,IAGD,cAAc,GAAG,KAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CA0EzE"}
1
+ {"version":3,"file":"chat-handler.d.ts","sourceRoot":"","sources":["../../../src/src/agent/chat-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AA4H/C,MAAM,WAAW,kBAAkB;IACjC,uFAAuF;IACvF,OAAO,CAAC,EACJ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,CAAC,CACD,OAAO,EAAE,OAAO,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACpE;AA2BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kBAAkB,IAGD,cAAc,GAAG,KAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CA0EzE"}
@@ -95,12 +95,21 @@ function transformUIMessages(messages) {
95
95
  * Pages Router handlers receive `(ctx)` where `ctx.request` is the Request.
96
96
  * App Router handlers receive `(request, context)` where `request` IS the Request.
97
97
  */
98
+ function isRequest(obj) {
99
+ // Use duck-typing instead of instanceof because dnt replaces `Request`
100
+ // with undici's version, which doesn't match Deno's native Request.
101
+ return (typeof obj === "object" &&
102
+ obj !== null &&
103
+ typeof obj.json === "function" &&
104
+ typeof obj.url === "string" &&
105
+ typeof obj.method === "string");
106
+ }
98
107
  function extractRequest(requestOrCtx) {
99
- if (requestOrCtx instanceof dntShim.Request)
108
+ if (isRequest(requestOrCtx))
100
109
  return requestOrCtx;
101
110
  // Pages Router APIContext — has a .request property
102
111
  const ctx = requestOrCtx;
103
- if (ctx.request instanceof dntShim.Request)
112
+ if (isRequest(ctx.request))
104
113
  return ctx.request;
105
114
  throw new Error("Invalid handler argument: expected Request or APIContext");
106
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"module-server.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAIlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAmBtE;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsBrD,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuB/D;AASD,MAAM,WAAW,mBAAmB;IAClC,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAiTzG;AA+MD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAG7D"}
1
+ {"version":3,"file":"module-server.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAIlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAmBtE;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkDrD,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuB/D;AASD,MAAM,WAAW,mBAAmB;IAClC,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAiTzG;AAmND;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAG7D"}
@@ -49,6 +49,34 @@ export class AsyncLocalStorage {
49
49
  */
50
50
  export default {};
51
51
  `,
52
+ // dnt build artifacts — no-op in browser. These imports are injected by
53
+ // dnt when building the npm package and must resolve when the module
54
+ // server serves framework files from the npm cache.
55
+ "_veryfront/_dnt.shims": [
56
+ `export const Deno = undefined;`,
57
+ `export const dntGlobalThis = globalThis;`,
58
+ // Re-export browser globals that dnt would normally shim from Node packages.
59
+ // Methods like fetch/setTimeout must be bound — destructuring detaches them
60
+ // from window, causing "Illegal invocation" when called.
61
+ `export const fetch = globalThis.fetch.bind(globalThis);`,
62
+ `export const setTimeout = globalThis.setTimeout.bind(globalThis);`,
63
+ `export const setInterval = globalThis.setInterval.bind(globalThis);`,
64
+ `export const { Request, Response, Headers, Blob, File, FormData, crypto } = globalThis;`,
65
+ `export default {};`,
66
+ ].join("\n") + "\n",
67
+ "_veryfront/_dnt.polyfills": `export default {};\n`,
68
+ // Relative imports from deeply nested modules (e.g. ../../../../_dnt.shims.js)
69
+ // resolve to paths outside the _veryfront/ prefix. Register without prefix too.
70
+ "_dnt.shims": [
71
+ `export const Deno = undefined;`,
72
+ `export const dntGlobalThis = globalThis;`,
73
+ `export const fetch = globalThis.fetch.bind(globalThis);`,
74
+ `export const setTimeout = globalThis.setTimeout.bind(globalThis);`,
75
+ `export const setInterval = globalThis.setInterval.bind(globalThis);`,
76
+ `export const { Request, Response, Headers, Blob, File, FormData, crypto } = globalThis;`,
77
+ `export default {};`,
78
+ ].join("\n") + "\n",
79
+ "_dnt.polyfills": `export default {};\n`,
52
80
  };
53
81
  /**
54
82
  * Validate that all required polyfills are embedded.
@@ -353,21 +381,25 @@ async function findSourceFile(secureFs, projectDir, basePath) {
353
381
  ["_veryfront/", join(projectDir, "src"), "_veryfront-project", true],
354
382
  ];
355
383
  const isFrameworkPath = basePathWithoutExt.startsWith("_veryfront/");
384
+ // Check embedded polyfills first (no filesystem access needed).
385
+ // These cover both compiled-binary polyfills (node:async_hooks etc.)
386
+ // and dnt build artifacts (_dnt.shims, _dnt.polyfills) that don't
387
+ // exist as source files but are imported by npm-cached framework modules.
388
+ // Note: checked before isFrameworkPath guard because relative imports from
389
+ // deeply nested modules (e.g. ../../../../_dnt.shims.js) resolve outside
390
+ // the _veryfront/ prefix.
391
+ const embeddedContent = EMBEDDED_POLYFILLS[basePathWithoutExt];
392
+ if (embeddedContent) {
393
+ logger.debug("Using embedded polyfill", {
394
+ basePath: basePathWithoutExt,
395
+ });
396
+ return {
397
+ path: `embedded:${basePathWithoutExt}`,
398
+ isFrameworkFile: true,
399
+ embeddedContent,
400
+ };
401
+ }
356
402
  async function resolveFrameworkFile(lookups) {
357
- // In compiled binaries, check for embedded polyfills first (no filesystem access)
358
- if (isDenoCompiled) {
359
- const embeddedContent = EMBEDDED_POLYFILLS[basePathWithoutExt];
360
- if (embeddedContent) {
361
- logger.debug("Using embedded polyfill for compiled binary", {
362
- basePath: basePathWithoutExt,
363
- });
364
- return {
365
- path: `embedded:${basePathWithoutExt}`,
366
- isFrameworkFile: true,
367
- embeddedContent,
368
- };
369
- }
370
- }
371
403
  // Look for framework files using native filesystem (not secureFs which goes to API)
372
404
  const platformFs = createFileSystem();
373
405
  for (const [prefix, frameworkDir, label, stripPrefix] of lookups) {
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Client boot script for RSC hydration and streaming
3
+ * This file is bundled by esbuild at runtime and served as client.js
4
+ */
5
+
6
+ import {
7
+ getReactCDNUrl,
8
+ getReactDOMClientCDNUrl,
9
+ REACT_DEFAULT_VERSION,
10
+ } from "#veryfront/utils/constants/cdn.ts";
11
+ import { validateTrustedHtml } from "#veryfront/security/client/html-sanitizer.ts";
12
+ import { consumeNdjsonStream, getContainer } from "./client-dom.ts";
13
+ import { FS_PATH_PREFIX, HYDRATION_DATA_ID, RSC_PATH_PREFIX, RSC_ROOT_ID } from "./constants.ts";
14
+
15
+ function toBase64Url(str: string): string | null {
16
+ try {
17
+ const base64 = btoa(unescape(encodeURIComponent(str)));
18
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
19
+ } catch (e) {
20
+ console.debug?.("[RSC] toBase64Url failed", e);
21
+ return null;
22
+ }
23
+ }
24
+
25
+ function getHydrationData(): { pagePath?: string } | null {
26
+ try {
27
+ const el = document.getElementById(HYDRATION_DATA_ID);
28
+ if (!el) return null;
29
+ return JSON.parse(el.textContent || "{}");
30
+ } catch (e) {
31
+ console.debug?.("[RSC] hydration data parse failed", e);
32
+ return null;
33
+ }
34
+ }
35
+
36
+ async function tryStream(q: string): Promise<boolean> {
37
+ try {
38
+ const res = await fetch(RSC_PATH_PREFIX + "stream" + q);
39
+ if (!res.ok || !res.body) return false;
40
+
41
+ const ctrl = new AbortController();
42
+ addEventListener("pagehide", () => ctrl.abort(), { once: true });
43
+
44
+ await consumeNdjsonStream(res, document, ctrl.signal);
45
+ return true;
46
+ } catch (e) {
47
+ console.debug?.("[RSC] tryStream failed", e);
48
+ return false;
49
+ }
50
+ }
51
+
52
+ async function hydrateMarkers(): Promise<void> {
53
+ try {
54
+ const mod = await import(RSC_PATH_PREFIX + "hydrate.js");
55
+ mod.bootHydration?.();
56
+ } catch (e) {
57
+ console.debug?.("[RSC] hydrate import failed", e);
58
+ }
59
+ }
60
+
61
+ async function hydratePageComponent(pagePath: string): Promise<boolean> {
62
+ try {
63
+ const React = await import(getReactCDNUrl(REACT_DEFAULT_VERSION));
64
+ const ReactDOM = await import(getReactDOMClientCDNUrl(REACT_DEFAULT_VERSION));
65
+
66
+ const base64Path = toBase64Url(pagePath);
67
+ if (!base64Path) {
68
+ console.debug?.("[RSC] Failed to encode page path");
69
+ return false;
70
+ }
71
+
72
+ const moduleUrl = FS_PATH_PREFIX + base64Path + ".js";
73
+ console.debug?.("[RSC] Loading component from:", moduleUrl);
74
+
75
+ const mod = await import(moduleUrl);
76
+ const Component = mod.default;
77
+
78
+ if (typeof Component !== "function") {
79
+ console.debug?.("[RSC] Page component is not a function");
80
+ return false;
81
+ }
82
+
83
+ const root = document.body.querySelector("div[class]") ??
84
+ document.body.firstElementChild ??
85
+ document.body;
86
+
87
+ ReactDOM.hydrateRoot(root, React.createElement(Component, {}), {
88
+ identifierPrefix: "vf",
89
+ onRecoverableError: () => {},
90
+ });
91
+
92
+ console.debug?.("[RSC] Page component hydrated successfully");
93
+ return true;
94
+ } catch (e) {
95
+ console.error("[RSC] Page hydration failed", e);
96
+ return false;
97
+ }
98
+ }
99
+
100
+ async function applyPayload(q: string): Promise<boolean> {
101
+ try {
102
+ const res = await fetch(RSC_PATH_PREFIX + "payload" + q);
103
+ if (!res.ok) return false;
104
+
105
+ const data = await res.json();
106
+
107
+ if (data?.slots) {
108
+ for (const [id, html] of Object.entries(data.slots)) {
109
+ getContainer(document, id).innerHTML = validateTrustedHtml(String(html || ""));
110
+ }
111
+ return true;
112
+ }
113
+
114
+ getContainer(document, RSC_ROOT_ID).innerHTML = validateTrustedHtml(String(data?.html || ""));
115
+ return true;
116
+ } catch (e) {
117
+ console.debug?.("[RSC] payload fetch failed", e);
118
+ return false;
119
+ }
120
+ }
121
+
122
+ export async function boot(): Promise<void> {
123
+ try {
124
+ const q = globalThis.window?.location.search ?? "";
125
+
126
+ const pagePath = getHydrationData()?.pagePath;
127
+ if (pagePath) {
128
+ console.debug?.("[RSC] Found page component in hydration data:", pagePath);
129
+ if (await hydratePageComponent(pagePath)) {
130
+ console.debug?.("[RSC] Client component hydrated successfully");
131
+ return;
132
+ }
133
+ }
134
+
135
+ if (await tryStream(q)) {
136
+ await hydrateMarkers();
137
+ return;
138
+ }
139
+
140
+ if (await applyPayload(q)) {
141
+ await hydrateMarkers();
142
+ return;
143
+ }
144
+
145
+ await hydrateMarkers();
146
+ } catch (e) {
147
+ console.error("[RSC] boot failed", e);
148
+ }
149
+ }
150
+
151
+ if (typeof document !== "undefined") {
152
+ const run = (): void => {
153
+ void boot();
154
+ };
155
+
156
+ if (document.readyState === "loading") {
157
+ document.addEventListener("DOMContentLoaded", run);
158
+ } else {
159
+ run();
160
+ }
161
+ }