@parlor/scaffold 0.0.0-stage → 0.1.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 (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -2
  3. package/dist/add/addon.d.ts +101 -0
  4. package/dist/add/addon.d.ts.map +1 -0
  5. package/dist/add/addon.js +6 -0
  6. package/dist/add/addon.js.map +1 -0
  7. package/dist/add/plan.d.ts +72 -0
  8. package/dist/add/plan.d.ts.map +1 -0
  9. package/dist/add/plan.js +237 -0
  10. package/dist/add/plan.js.map +1 -0
  11. package/dist/add/run.d.ts +92 -0
  12. package/dist/add/run.d.ts.map +1 -0
  13. package/dist/add/run.js +167 -0
  14. package/dist/add/run.js.map +1 -0
  15. package/dist/add/transaction.d.ts +67 -0
  16. package/dist/add/transaction.d.ts.map +1 -0
  17. package/dist/add/transaction.js +181 -0
  18. package/dist/add/transaction.js.map +1 -0
  19. package/dist/addons/agent.d.ts +61 -0
  20. package/dist/addons/agent.d.ts.map +1 -0
  21. package/dist/addons/agent.js +50 -0
  22. package/dist/addons/agent.js.map +1 -0
  23. package/dist/addons/auth.d.ts +106 -0
  24. package/dist/addons/auth.d.ts.map +1 -0
  25. package/dist/addons/auth.js +93 -0
  26. package/dist/addons/auth.js.map +1 -0
  27. package/dist/addons/index.d.ts +165 -0
  28. package/dist/addons/index.d.ts.map +1 -0
  29. package/dist/addons/index.js +8 -0
  30. package/dist/addons/index.js.map +1 -0
  31. package/dist/catalog.d.ts +3 -0
  32. package/dist/catalog.d.ts.map +1 -0
  33. package/dist/catalog.js +23 -0
  34. package/dist/catalog.js.map +1 -0
  35. package/dist/create.d.ts +45 -0
  36. package/dist/create.d.ts.map +1 -0
  37. package/dist/create.js +162 -0
  38. package/dist/create.js.map +1 -0
  39. package/dist/docs.d.ts +12 -0
  40. package/dist/docs.d.ts.map +1 -0
  41. package/dist/docs.js +66 -0
  42. package/dist/docs.js.map +1 -0
  43. package/dist/edit/inspect.d.ts +15 -0
  44. package/dist/edit/inspect.d.ts.map +1 -0
  45. package/dist/edit/inspect.js +73 -0
  46. package/dist/edit/inspect.js.map +1 -0
  47. package/dist/edit/ops.d.ts +92 -0
  48. package/dist/edit/ops.d.ts.map +1 -0
  49. package/dist/edit/ops.js +516 -0
  50. package/dist/edit/ops.js.map +1 -0
  51. package/dist/edit/source.d.ts +24 -0
  52. package/dist/edit/source.d.ts.map +1 -0
  53. package/dist/edit/source.js +36 -0
  54. package/dist/edit/source.js.map +1 -0
  55. package/dist/edit/syntax.d.ts +34 -0
  56. package/dist/edit/syntax.d.ts.map +1 -0
  57. package/dist/edit/syntax.js +114 -0
  58. package/dist/edit/syntax.js.map +1 -0
  59. package/dist/errors.d.ts +5 -0
  60. package/dist/errors.d.ts.map +1 -0
  61. package/dist/errors.js +5 -0
  62. package/dist/errors.js.map +1 -0
  63. package/dist/files.d.ts +15 -0
  64. package/dist/files.d.ts.map +1 -0
  65. package/dist/files.js +65 -0
  66. package/dist/files.js.map +1 -0
  67. package/dist/fixtures.d.ts +28 -0
  68. package/dist/fixtures.d.ts.map +1 -0
  69. package/dist/fixtures.js +66 -0
  70. package/dist/fixtures.js.map +1 -0
  71. package/dist/git.d.ts +22 -0
  72. package/dist/git.d.ts.map +1 -0
  73. package/dist/git.js +56 -0
  74. package/dist/git.js.map +1 -0
  75. package/dist/identity.d.ts +9 -0
  76. package/dist/identity.d.ts.map +1 -0
  77. package/dist/identity.js +23 -0
  78. package/dist/identity.js.map +1 -0
  79. package/dist/index.d.ts +9 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +8 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/package-manager.d.ts +49 -0
  84. package/dist/package-manager.d.ts.map +1 -0
  85. package/dist/package-manager.js +118 -0
  86. package/dist/package-manager.js.map +1 -0
  87. package/dist/version.d.ts +6 -0
  88. package/dist/version.d.ts.map +1 -0
  89. package/dist/version.js +9 -0
  90. package/dist/version.js.map +1 -0
  91. package/package.json +46 -3
  92. package/templates/auth/auth.ts +20 -0
  93. package/templates/auth/schema/auth.ts +1 -0
  94. package/templates/auth/src/auth/client.ts +3 -0
  95. package/templates/auth/src/auth/sign-in-gate.tsx +17 -0
  96. package/templates/auth/src/auth/sign-out-button.tsx +17 -0
  97. package/templates/auth/src/routes/link.tsx +92 -0
  98. package/templates/auth/src/routes/sign-in.tsx +117 -0
  99. package/templates/default/_gitignore +7 -0
  100. package/templates/default/actions/index.ts +58 -0
  101. package/templates/default/actions/todos.spec.ts +38 -0
  102. package/templates/default/index.html +13 -0
  103. package/templates/default/migrations/0000_init.sql +9 -0
  104. package/templates/default/migrations/meta/0000_snapshot.json +87 -0
  105. package/templates/default/migrations/meta/_journal.json +13 -0
  106. package/templates/default/package.json +44 -0
  107. package/templates/default/parlor.config.ts +12 -0
  108. package/templates/default/schema/index.ts +1 -0
  109. package/templates/default/schema/todos.ts +13 -0
  110. package/templates/default/server.ts +13 -0
  111. package/templates/default/src/agent/agent-button.tsx +120 -0
  112. package/templates/default/src/agent/agent-sidebar.tsx +821 -0
  113. package/templates/default/src/agent/agent.css +5 -0
  114. package/templates/default/src/agent/confirmation-card.tsx +42 -0
  115. package/templates/default/src/agent/sidebar-view.ts +36 -0
  116. package/templates/default/src/agent/views.ts +9 -0
  117. package/templates/default/src/app.css +1 -0
  118. package/templates/default/src/header-actions.tsx +9 -0
  119. package/templates/default/src/main.tsx +24 -0
  120. package/templates/default/src/parlor.d.ts +9 -0
  121. package/templates/default/src/routeTree.gen.ts +59 -0
  122. package/templates/default/src/routes/__root.tsx +28 -0
  123. package/templates/default/src/routes/index.tsx +136 -0
  124. package/templates/default/tsconfig.json +8 -0
  125. package/templates/default/vitest.config.ts +5 -0
@@ -0,0 +1,87 @@
1
+ {
2
+ "id": "d877853a-ee64-4c03-9a26-1c6dc29be490",
3
+ "prevId": "00000000-0000-0000-0000-000000000000",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.todos": {
8
+ "name": "todos",
9
+ "schema": "",
10
+ "columns": {
11
+ "id": {
12
+ "name": "id",
13
+ "type": "text",
14
+ "primaryKey": true,
15
+ "notNull": true
16
+ },
17
+ "scope": {
18
+ "name": "scope",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "default": "'default'"
23
+ },
24
+ "title": {
25
+ "name": "title",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": true
29
+ },
30
+ "done": {
31
+ "name": "done",
32
+ "type": "boolean",
33
+ "primaryKey": false,
34
+ "notNull": true,
35
+ "default": false
36
+ },
37
+ "created_at": {
38
+ "name": "created_at",
39
+ "type": "timestamp with time zone",
40
+ "primaryKey": false,
41
+ "notNull": true,
42
+ "default": "now()"
43
+ }
44
+ },
45
+ "indexes": {
46
+ "todos_scope_created_at_idx": {
47
+ "name": "todos_scope_created_at_idx",
48
+ "columns": [
49
+ {
50
+ "expression": "scope",
51
+ "isExpression": false,
52
+ "asc": true,
53
+ "nulls": "last"
54
+ },
55
+ {
56
+ "expression": "created_at",
57
+ "isExpression": false,
58
+ "asc": true,
59
+ "nulls": "last"
60
+ }
61
+ ],
62
+ "isUnique": false,
63
+ "concurrently": false,
64
+ "method": "btree",
65
+ "with": {}
66
+ }
67
+ },
68
+ "foreignKeys": {},
69
+ "compositePrimaryKeys": {},
70
+ "uniqueConstraints": {},
71
+ "policies": {},
72
+ "checkConstraints": {},
73
+ "isRLSEnabled": false
74
+ }
75
+ },
76
+ "enums": {},
77
+ "schemas": {},
78
+ "sequences": {},
79
+ "roles": {},
80
+ "policies": {},
81
+ "views": {},
82
+ "_meta": {
83
+ "columns": {},
84
+ "schemas": {},
85
+ "tables": {}
86
+ }
87
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": "7",
3
+ "dialect": "postgresql",
4
+ "entries": [
5
+ {
6
+ "idx": 0,
7
+ "version": "7",
8
+ "when": 1792687346970,
9
+ "tag": "0000_init",
10
+ "breakpoints": true
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "parlor-template-default",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "parlor dev",
8
+ "build": "parlor build",
9
+ "typecheck": "parlor typegen && tsc --noEmit",
10
+ "test": "vitest run",
11
+ "db:generate": "parlor db generate",
12
+ "db:migrate": "parlor db migrate"
13
+ },
14
+ "dependencies": {
15
+ "@parlor/chat": "workspace:*",
16
+ "@parlor/client": "workspace:*",
17
+ "@parlor/core": "workspace:*",
18
+ "@parlor/data": "workspace:*",
19
+ "@parlor/server": "workspace:*",
20
+ "@tanstack/react-query": "catalog:",
21
+ "@tanstack/react-router": "catalog:",
22
+ "drizzle-orm": "^0.45.4",
23
+ "react": "catalog:",
24
+ "react-dom": "catalog:",
25
+ "uqr": "^0.1.3",
26
+ "zod": "catalog:"
27
+ },
28
+ "devDependencies": {
29
+ "@parlor/agent-host": "workspace:*",
30
+ "@parlor/cli": "workspace:*",
31
+ "@parlor/config": "workspace:*",
32
+ "@tailwindcss/vite": "^4.3.3",
33
+ "@types/node": "catalog:",
34
+ "@types/react": "catalog:",
35
+ "@types/react-dom": "catalog:",
36
+ "tailwindcss": "^4.3.3",
37
+ "typescript": "catalog:",
38
+ "vite": "catalog:",
39
+ "vitest": "catalog:"
40
+ },
41
+ "engines": {
42
+ "node": ">=24"
43
+ }
44
+ }
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from "@parlor/config";
2
+ import tailwindcss from "@tailwindcss/vite";
3
+
4
+ export default defineConfig({
5
+ app: {
6
+ id: "com.example.parlorapp",
7
+ name: "Parlor App",
8
+ },
9
+ vite: {
10
+ plugins: [tailwindcss()],
11
+ },
12
+ });
@@ -0,0 +1 @@
1
+ export { todos } from "./todos.js";
@@ -0,0 +1,13 @@
1
+ import { boolean, index, pgTable, text, timestamp } from "drizzle-orm/pg-core";
2
+
3
+ export const todos = pgTable(
4
+ "todos",
5
+ {
6
+ id: text("id").primaryKey(),
7
+ scope: text("scope").notNull().default("default"),
8
+ title: text("title").notNull(),
9
+ done: boolean("done").notNull().default(false),
10
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
11
+ },
12
+ (table) => [index("todos_scope_created_at_idx").on(table.scope, table.createdAt)],
13
+ );
@@ -0,0 +1,13 @@
1
+ import { chat } from "@parlor/chat/server";
2
+ import { createDatabase } from "@parlor/data";
3
+ import { createServer } from "@parlor/server";
4
+
5
+ import { registry } from "./actions/index.js";
6
+
7
+ const database = await createDatabase({ migrationsFolder: "migrations" });
8
+
9
+ export default createServer({
10
+ actions: registry,
11
+ database,
12
+ plugins: [chat()],
13
+ });
@@ -0,0 +1,120 @@
1
+ import { useAgentConfirmations, useAgentView } from "@parlor/client/react";
2
+ import {
3
+ lazy,
4
+ startTransition,
5
+ Suspense,
6
+ useCallback,
7
+ useEffect,
8
+ useId,
9
+ useRef,
10
+ useState,
11
+ } from "react";
12
+ import { createPortal } from "react-dom";
13
+
14
+ import "./agent.css";
15
+ import { sidebarView } from "./sidebar-view.js";
16
+ import { agentPanel } from "./views.js";
17
+
18
+ const AgentSidebar = lazy(() => import("./agent-sidebar.js"));
19
+
20
+ export function AgentButton() {
21
+ const regionId = useId();
22
+ const titleId = useId();
23
+ const button = useRef<HTMLButtonElement | null>(null);
24
+ const region = useRef<HTMLElement | null>(null);
25
+ const [open, setOpen] = useState(false);
26
+ const [everOpened, setEverOpened] = useState(false);
27
+ const pending = useAgentConfirmations().length;
28
+ const { ref } = useAgentView(agentPanel, { get: () => ({ open }) });
29
+ const attach = useCallback(
30
+ (element: HTMLElement | null) => {
31
+ region.current = element;
32
+ ref(element);
33
+ },
34
+ [ref],
35
+ );
36
+
37
+ useEffect(() => {
38
+ if (open) region.current?.querySelector("textarea")?.focus();
39
+ }, [open]);
40
+ useEffect(() => {
41
+ sidebarView.set({ open });
42
+ return () => sidebarView.set({ open: false });
43
+ }, [open]);
44
+ useEffect(() => {
45
+ if (!open) return;
46
+ const dismiss = (event: KeyboardEvent) => {
47
+ if (event.key !== "Escape" || event.defaultPrevented || event.isComposing) return;
48
+ const focus = document.activeElement;
49
+ const inside =
50
+ focus === document.body ||
51
+ focus === button.current ||
52
+ region.current?.contains(focus);
53
+ if (!inside) return;
54
+ event.preventDefault();
55
+ setOpen(false);
56
+ button.current?.focus();
57
+ };
58
+ document.addEventListener("keydown", dismiss);
59
+ return () => document.removeEventListener("keydown", dismiss);
60
+ }, [open]);
61
+
62
+ const toggle = () => {
63
+ startTransition(() => {
64
+ setOpen(!open);
65
+ setEverOpened(true);
66
+ });
67
+ };
68
+ const close = () => {
69
+ setOpen(false);
70
+ button.current?.focus();
71
+ };
72
+
73
+ return (
74
+ <>
75
+ <button
76
+ ref={button}
77
+ type="button"
78
+ aria-expanded={open}
79
+ aria-controls={regionId}
80
+ aria-label={pending > 0 ? `Agent, ${pending} pending` : undefined}
81
+ onClick={toggle}
82
+ className="inline-flex items-center gap-2 rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm font-medium hover:bg-zinc-100 aria-expanded:bg-zinc-900 aria-expanded:text-white"
83
+ >
84
+ Agent
85
+ {pending > 0 ? (
86
+ <span className="rounded-full bg-amber-500 px-1.5 text-xs text-white">
87
+ {pending}
88
+ </span>
89
+ ) : null}
90
+ </button>
91
+ {createPortal(
92
+ <section
93
+ id={regionId}
94
+ ref={attach}
95
+ aria-labelledby={titleId}
96
+ data-agent-sidebar
97
+ hidden={!open}
98
+ className="fixed inset-y-0 right-0 z-50 flex w-full max-w-md flex-col border-l border-zinc-200 bg-white shadow-xl"
99
+ >
100
+ <header className="flex items-center justify-between border-b border-zinc-200 px-4 py-3">
101
+ <h2 id={titleId} className="font-semibold">
102
+ Agent
103
+ </h2>
104
+ <button
105
+ type="button"
106
+ onClick={close}
107
+ className="rounded-md px-2 py-1 text-sm text-zinc-600 hover:bg-zinc-100"
108
+ >
109
+ Close
110
+ </button>
111
+ </header>
112
+ <Suspense fallback={<p className="p-4 text-sm text-zinc-500">Loading...</p>}>
113
+ {everOpened ? <AgentSidebar /> : null}
114
+ </Suspense>
115
+ </section>,
116
+ document.body,
117
+ )}
118
+ </>
119
+ );
120
+ }