@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,167 @@
1
+ import { indentLines } from "../edit/ops.js";
2
+ import { projectFiles, templateFiles, writeFiles } from "../files.js";
3
+ import { uncommittedChanges } from "../git.js";
4
+ import { commandsFor, formatCommand } from "../package-manager.js";
5
+ import { planAddons } from "./plan.js";
6
+ import { commitStaging, discardStaging, generateInStaging, installDependencies, pendingInstallCommands, restoreManifests, snapshotManifests, stageProject, } from "./transaction.js";
7
+ /**
8
+ * The one entry point behind `parlor add`. A transaction in stages, so a failure never leaves
9
+ * an app that cannot boot and a crash is finished by the next run (every step it already did
10
+ * is `done`):
11
+ * 1. plan (no writes); `blocked`, `done` and `dry-run` return here
12
+ * 2. git: `uncommittedChanges(rootDir)` non-empty and `gitCheck` -> `dirty`
13
+ * 3. install: snapshot `package.json` and the lockfile; round one adds every dependency whose
14
+ * version is known (`<pm> add`), round two resolves each `FromPackage` from the manifest
15
+ * round one installed and adds those; any failure restores the snapshot -> `failed`
16
+ * 4. stage: `stageProject` copies the tree (minus node_modules, .git, .parlor) into
17
+ * `.parlor/add/<run id>/` and lays the planned writes over it
18
+ * 5. generate: each pending generation's tool runs in the staging dir; `generationDone`
19
+ * against the staging copy must then hold, else the copy is discarded -> `failed`
20
+ * 6. commit: every staged file whose bytes differ from the project is written through a temp
21
+ * file and a rename; the staging dir is removed
22
+ * `install: false` skips 3 and 5; `pending` then names the install commands and a second
23
+ * `parlor add` to generate.
24
+ */
25
+ export async function addAddons(request) {
26
+ const { layout, addons, packageManager, log } = request;
27
+ const { rootDir } = layout;
28
+ const plan = await planAddons(layout, addons, projectFiles(rootDir), templateFiles());
29
+ if (plan.kind === "done")
30
+ return plan;
31
+ if (plan.kind === "blocked")
32
+ return { kind: "blocked", addons, manual: plan.manual };
33
+ if (request.mode === "dry-run")
34
+ return { kind: "planned", plan };
35
+ if (request.gitCheck) {
36
+ const files = await uncommittedChanges(rootDir);
37
+ if (files && files.length > 0)
38
+ return { kind: "dirty", addons, files };
39
+ }
40
+ if (!request.install) {
41
+ await writeFiles(rootDir, new Map(plan.writes.map((write) => [write.path, write.content])));
42
+ const pm = commandsFor(packageManager);
43
+ const rerun = plan.generate.length > 0 ||
44
+ plan.dependencies.some((dependency) => typeof dependency.version !== "string");
45
+ return {
46
+ kind: "applied",
47
+ plan,
48
+ generated: [],
49
+ pending: [
50
+ ...pendingInstallCommands(plan.dependencies, packageManager).map(formatCommand),
51
+ ...(rerun ? [pm.exec("parlor", ["add", ...addons])] : []),
52
+ ],
53
+ };
54
+ }
55
+ let snapshot;
56
+ if (plan.dependencies.length > 0) {
57
+ snapshot = await snapshotManifests(rootDir);
58
+ const installed = await installDependencies(rootDir, plan.dependencies, packageManager, projectFiles(rootDir), log);
59
+ if (!installed.ok) {
60
+ await restoreManifests(rootDir, snapshot);
61
+ return { kind: "failed", addons, stage: "install", message: installed.message };
62
+ }
63
+ }
64
+ const staging = await stageProject(rootDir, plan.writes);
65
+ if (plan.generate.length > 0) {
66
+ log(`generating ${plan.generate
67
+ .map((generation) => generation.kind === "route-tree"
68
+ ? "the route tree"
69
+ : `the migration "${generation.name}"`)
70
+ .join(", then ")}`);
71
+ const generated = await generateInStaging(layout, staging, plan.generate, request.tools);
72
+ if (!generated.ok) {
73
+ await discardStaging(staging);
74
+ if (snapshot)
75
+ await restoreManifests(rootDir, snapshot);
76
+ return { kind: "failed", addons, stage: "generate", message: generated.message };
77
+ }
78
+ }
79
+ const written = await commitStaging(rootDir, staging);
80
+ const planned = new Set(plan.writes.map((write) => write.path));
81
+ return {
82
+ kind: "applied",
83
+ plan,
84
+ generated: written.filter((path) => !planned.has(path)),
85
+ pending: [],
86
+ };
87
+ }
88
+ function planLines(plan, generated) {
89
+ const width = Math.max(0, ...plan.writes
90
+ .filter((write) => write.change === "update")
91
+ .map((write) => write.path.length));
92
+ return [
93
+ ...plan.writes
94
+ .filter((write) => write.change === "create")
95
+ .map((write) => `+ ${write.path}`),
96
+ ...plan.writes
97
+ .filter((write) => write.change === "update")
98
+ .map((write) => write.summary.length > 0
99
+ ? `~ ${write.path.padEnd(width)} ${write.summary.join(", ")}`
100
+ : `~ ${write.path}`),
101
+ ...(generated.length > 0 ? [`~ ${generated.join(", ")}`] : []),
102
+ ];
103
+ }
104
+ /** The terminal text for a result and the exit code: 1 for `blocked`, `dirty` and `failed`, else 0. */
105
+ export function formatAddResult(result, manager) {
106
+ const pm = commandsFor(manager);
107
+ const command = (addons) => `parlor add ${addons.join(" ")}`;
108
+ switch (result.kind) {
109
+ case "done":
110
+ return {
111
+ text: `${result.addons.join(", ")} ${result.addons.length === 1 ? "is" : "are"} already added. Nothing changed.`,
112
+ exitCode: 0,
113
+ };
114
+ case "blocked": {
115
+ const files = [...new Set(result.manual.map((change) => change.file))];
116
+ const rerun = pm.exec("parlor", ["add", ...result.addons]);
117
+ return {
118
+ text: [
119
+ `${command(result.addons)}: cannot edit ${files.join(", ")} safely, so nothing was changed.`,
120
+ ...result.manual.flatMap((change) => [
121
+ "",
122
+ ` ${change.file}: ${change.reason}`,
123
+ ` Make this change by hand, then run \`${rerun}\` again:`,
124
+ "",
125
+ indentLines(change.change, " "),
126
+ ]),
127
+ ].join("\n"),
128
+ exitCode: 1,
129
+ };
130
+ }
131
+ case "dirty":
132
+ return {
133
+ text: `${command(result.addons)}: this project has uncommitted changes (${result.files.join(", ")}).\nCommit or stash them so the change is easy to review, or pass --no-git-check.`,
134
+ exitCode: 1,
135
+ };
136
+ case "failed":
137
+ return {
138
+ text: `${command(result.addons)}: ${result.message}\nNothing was changed.`,
139
+ exitCode: 1,
140
+ };
141
+ case "planned": {
142
+ const installs = result.plan.dependencies.map((dependency) => typeof dependency.version === "string"
143
+ ? `${dependency.name}@${dependency.version}`
144
+ : `${dependency.name} (pinned by ${dependency.version.fromPackage})`);
145
+ return {
146
+ text: [
147
+ ...planLines(result.plan, []),
148
+ ...(installs.length > 0 ? [`would install ${installs.join(", ")}`] : []),
149
+ "Nothing was written (--dry-run).",
150
+ ].join("\n"),
151
+ exitCode: 0,
152
+ };
153
+ }
154
+ case "applied":
155
+ return {
156
+ text: [
157
+ ...planLines(result.plan, result.generated),
158
+ ...result.plan.notes,
159
+ ...(result.pending.length > 0
160
+ ? ["", "Run these to finish:", ...result.pending.map((line) => ` ${line}`)]
161
+ : []),
162
+ ].join("\n"),
163
+ exitCode: 0,
164
+ };
165
+ }
166
+ }
167
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/add/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { type Command, type InstallOutcome, type PackageManager } from "../package-manager.js";
2
+ import type { Generation, ProjectLayout } from "./addon.js";
3
+ import { type PlannedDependency, type PlannedWrite, type ProjectFiles } from "./plan.js";
4
+ import type { AddTools } from "./run.js";
5
+ /** Under `.parlor/`, which every project ignores, so a crash leaves nothing a commit would pick up. */
6
+ export declare const STAGING_DIR = ".parlor/add";
7
+ /** Never copied into a staging dir and never committed back from one. */
8
+ export declare const NOT_STAGED: ReadonlySet<string>;
9
+ /** `package.json` plus whichever lockfile the project has, as they were before the install. */
10
+ export interface ManifestSnapshot {
11
+ readonly files: ReadonlyMap<string, Buffer | undefined>;
12
+ }
13
+ export declare const LOCKFILES: readonly ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock", "bun.lockb"];
14
+ export declare function snapshotManifests(rootDir: string): Promise<ManifestSnapshot>;
15
+ /** Puts every snapshotted file back, deleting the ones that did not exist. */
16
+ export declare function restoreManifests(rootDir: string, snapshot: ManifestSnapshot): Promise<void>;
17
+ export type InstallResult = {
18
+ readonly ok: true;
19
+ readonly outcome: InstallOutcome;
20
+ } | {
21
+ readonly ok: false;
22
+ readonly message: string;
23
+ };
24
+ /**
25
+ * Two rounds of `<pm> add`, because a `FromPackage` version is readable only once that package
26
+ * is in `node_modules`: round one adds every dependency with a known version, round two reads
27
+ * each `FromPackage` through `project.manifest` and adds those. A `listed` dependency with no
28
+ * known version is a plain `<pm> install`. Nothing here touches files other than the ones the
29
+ * package manager owns.
30
+ */
31
+ export declare function installDependencies(rootDir: string, dependencies: readonly PlannedDependency[], manager: PackageManager, project: ProjectFiles, log: (line: string) => void): Promise<InstallResult>;
32
+ /** The install commands `--no-install` left for the developer, in the order to run them. */
33
+ export declare function pendingInstallCommands(dependencies: readonly PlannedDependency[], manager: PackageManager): readonly Command[];
34
+ export interface Staging {
35
+ /** Absolute: `<rootDir>/.parlor/add/<run id>`. */
36
+ readonly dir: string;
37
+ /** A `ProjectFiles` over `dir`, for `generationDone` and the commit diff. */
38
+ readonly files: ProjectFiles;
39
+ }
40
+ /**
41
+ * Copies the project tree except `NOT_STAGED` into a fresh staging dir and lays `writes` over
42
+ * it. Module resolution from the staging dir walks up to the project's `node_modules`, so the
43
+ * generators run there unchanged.
44
+ */
45
+ export declare function stageProject(rootDir: string, writes: readonly PlannedWrite[]): Promise<Staging>;
46
+ export type GenerateResult = {
47
+ readonly ok: true;
48
+ } | {
49
+ readonly ok: false;
50
+ readonly generation: Generation;
51
+ readonly message: string;
52
+ };
53
+ /**
54
+ * Runs each generation's tool in the staging dir, then checks `generationDone` there. A tool
55
+ * that throws, or whose declared outputs are not in the copy afterwards, fails the whole run
56
+ * before anything reaches the project.
57
+ */
58
+ export declare function generateInStaging(layout: ProjectLayout, staging: Staging, generations: readonly Generation[], tools: AddTools): Promise<GenerateResult>;
59
+ /**
60
+ * Every file in the staging dir whose bytes differ from the project's is written through
61
+ * `<path>.parlor-tmp` and a rename, then the staging dir is removed. Returns the project paths
62
+ * written. A crash between two renames leaves whole files, and the next run's plan finds each
63
+ * written step `done`.
64
+ */
65
+ export declare function commitStaging(rootDir: string, staging: Staging): Promise<readonly string[]>;
66
+ export declare function discardStaging(staging: Staging): Promise<void>;
67
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/add/transaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,181 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { cp, mkdir, readdir, readFile, rename, rm, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { projectFiles } from "../files.js";
5
+ import { commandsFor, formatCommand, runInstall, } from "../package-manager.js";
6
+ import { generationDone, resolveFromPackage, } from "./plan.js";
7
+ /** Under `.parlor/`, which every project ignores, so a crash leaves nothing a commit would pick up. */
8
+ export const STAGING_DIR = ".parlor/add";
9
+ /** Never copied into a staging dir and never committed back from one. */
10
+ export const NOT_STAGED = new Set([
11
+ "node_modules",
12
+ ".git",
13
+ ".parlor",
14
+ ]);
15
+ export const LOCKFILES = [
16
+ "pnpm-lock.yaml",
17
+ "package-lock.json",
18
+ "yarn.lock",
19
+ "bun.lock",
20
+ "bun.lockb",
21
+ ];
22
+ export async function snapshotManifests(rootDir) {
23
+ const files = new Map();
24
+ for (const name of ["package.json", ...LOCKFILES]) {
25
+ files.set(name, await readFile(join(rootDir, name)).catch(() => undefined));
26
+ }
27
+ return { files };
28
+ }
29
+ /** Puts every snapshotted file back, deleting the ones that did not exist. */
30
+ export async function restoreManifests(rootDir, snapshot) {
31
+ for (const [name, content] of snapshot.files) {
32
+ const path = join(rootDir, name);
33
+ if (content === undefined)
34
+ await rm(path, { force: true });
35
+ else
36
+ await writeFile(path, content);
37
+ }
38
+ }
39
+ /**
40
+ * Two rounds of `<pm> add`, because a `FromPackage` version is readable only once that package
41
+ * is in `node_modules`: round one adds every dependency with a known version, round two reads
42
+ * each `FromPackage` through `project.manifest` and adds those. A `listed` dependency with no
43
+ * known version is a plain `<pm> install`. Nothing here touches files other than the ones the
44
+ * package manager owns.
45
+ */
46
+ export async function installDependencies(rootDir, dependencies, manager, project, log) {
47
+ const add = commandsFor(manager).add;
48
+ let outcome = { kind: "installed" };
49
+ const round = async (resolved) => {
50
+ for (const dev of [false, true]) {
51
+ const group = resolved.filter((dependency) => dependency.dev === dev);
52
+ if (group.length === 0)
53
+ continue;
54
+ const command = add(group.map((dependency) => `${dependency.name}@${dependency.version}`), { dev });
55
+ const result = await runInstall(rootDir, command, log);
56
+ if (result.kind === "failed") {
57
+ return {
58
+ ok: false,
59
+ message: `${formatCommand(command)} failed (exit ${result.exitCode}).`,
60
+ };
61
+ }
62
+ if (result.kind === "ignored-builds")
63
+ outcome = result;
64
+ }
65
+ return undefined;
66
+ };
67
+ const known = dependencies.filter((dependency) => typeof dependency.version === "string");
68
+ if (known.length > 0) {
69
+ log(`installing ${known.map((dependency) => `${dependency.name}@${dependency.version}`).join(", ")}`);
70
+ const failed = await round(known);
71
+ if (failed)
72
+ return failed;
73
+ }
74
+ const pinned = [];
75
+ for (const dependency of dependencies) {
76
+ if (typeof dependency.version === "string")
77
+ continue;
78
+ const version = await resolveFromPackage(dependency.version, project);
79
+ if (version === undefined) {
80
+ return {
81
+ ok: false,
82
+ message: `${dependency.version.fromPackage} does not declare ${dependency.version.dependency}`,
83
+ };
84
+ }
85
+ log(`installing ${dependency.name}@${version} (pinned by ${dependency.version.fromPackage})`);
86
+ pinned.push({ ...dependency, version });
87
+ }
88
+ const failed = await round(pinned);
89
+ return failed ?? { ok: true, outcome };
90
+ }
91
+ /** The install commands `--no-install` left for the developer, in the order to run them. */
92
+ export function pendingInstallCommands(dependencies, manager) {
93
+ const add = commandsFor(manager).add;
94
+ return [false, true].flatMap((dev) => {
95
+ const group = dependencies.filter((dependency) => dependency.dev === dev && typeof dependency.version === "string");
96
+ return group.length === 0
97
+ ? []
98
+ : [
99
+ add(group.map((dependency) => `${dependency.name}@${String(dependency.version)}`), { dev }),
100
+ ];
101
+ });
102
+ }
103
+ /**
104
+ * Copies the project tree except `NOT_STAGED` into a fresh staging dir and lays `writes` over
105
+ * it. Module resolution from the staging dir walks up to the project's `node_modules`, so the
106
+ * generators run there unchanged.
107
+ */
108
+ export async function stageProject(rootDir, writes) {
109
+ const dir = join(rootDir, STAGING_DIR, randomUUID());
110
+ await mkdir(dir, { recursive: true });
111
+ for (const entry of await readdir(rootDir)) {
112
+ if (NOT_STAGED.has(entry))
113
+ continue;
114
+ await cp(join(rootDir, entry), join(dir, entry), { recursive: true });
115
+ }
116
+ for (const write of writes) {
117
+ const target = join(dir, write.path);
118
+ await mkdir(dirname(target), { recursive: true });
119
+ await writeFile(target, write.content);
120
+ }
121
+ return { dir, files: projectFiles(dir) };
122
+ }
123
+ /**
124
+ * Runs each generation's tool in the staging dir, then checks `generationDone` there. A tool
125
+ * that throws, or whose declared outputs are not in the copy afterwards, fails the whole run
126
+ * before anything reaches the project.
127
+ */
128
+ export async function generateInStaging(layout, staging, generations, tools) {
129
+ for (const generation of generations) {
130
+ const tool = generation.kind === "route-tree" ? "parlor typegen" : "parlor db generate";
131
+ try {
132
+ if (generation.kind === "route-tree")
133
+ await tools.routeTree(staging.dir);
134
+ else
135
+ await tools.migration(staging.dir, generation.name);
136
+ }
137
+ catch (error) {
138
+ return {
139
+ ok: false,
140
+ generation,
141
+ message: `${tool} failed: ${error.message}`,
142
+ };
143
+ }
144
+ if (!(await generationDone({ ...layout, rootDir: staging.dir }, generation, staging.files))) {
145
+ return {
146
+ ok: false,
147
+ generation,
148
+ message: generation.kind === "route-tree"
149
+ ? `${tool} wrote no route ${generation.routes.join(", ")}`
150
+ : `${tool} wrote no migration with tables ${generation.tables.join(", ")}`,
151
+ };
152
+ }
153
+ }
154
+ return { ok: true };
155
+ }
156
+ /**
157
+ * Every file in the staging dir whose bytes differ from the project's is written through
158
+ * `<path>.parlor-tmp` and a rename, then the staging dir is removed. Returns the project paths
159
+ * written. A crash between two renames leaves whole files, and the next run's plan finds each
160
+ * written step `done`.
161
+ */
162
+ export async function commitStaging(rootDir, staging) {
163
+ const written = [];
164
+ for (const path of await staging.files.list("")) {
165
+ const staged = await readFile(join(staging.dir, path));
166
+ const current = await readFile(join(rootDir, path)).catch(() => undefined);
167
+ if (current?.equals(staged))
168
+ continue;
169
+ const target = join(rootDir, path);
170
+ await mkdir(dirname(target), { recursive: true });
171
+ await writeFile(`${target}.parlor-tmp`, staged);
172
+ await rename(`${target}.parlor-tmp`, target);
173
+ written.push(path);
174
+ }
175
+ await discardStaging(staging);
176
+ return written;
177
+ }
178
+ export async function discardStaging(staging) {
179
+ await rm(staging.dir, { recursive: true, force: true });
180
+ }
181
+ //# sourceMappingURL=transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/add/transaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { SERVER_ENTRY } from "../add/addon.js";
2
+ /**
3
+ * The default template already contains all of this; a test runs this add-on on it and expects
4
+ * no change, which is what keeps the two from drifting.
5
+ */
6
+ export declare const agent: {
7
+ readonly summary: "The agent sidebar: chat with your own coding agent inside the app.";
8
+ readonly requires: {
9
+ readonly routesDir: "src/routes";
10
+ };
11
+ readonly dependencies: {
12
+ readonly "@parlor/chat": "framework";
13
+ };
14
+ readonly files: readonly [{
15
+ readonly template: "default";
16
+ readonly dir: "src/agent";
17
+ }];
18
+ readonly edits: readonly [{
19
+ readonly file: typeof SERVER_ENTRY;
20
+ readonly ops: readonly [{
21
+ readonly kind: "import";
22
+ readonly names: readonly ["chat"];
23
+ readonly from: "@parlor/chat/server";
24
+ }, {
25
+ readonly kind: "append-element";
26
+ readonly call: {
27
+ readonly callee: "createServer";
28
+ readonly from: "@parlor/server";
29
+ };
30
+ readonly path: readonly ["plugins"];
31
+ readonly element: "chat()";
32
+ }];
33
+ }, {
34
+ readonly file: "src/routes/__root.tsx";
35
+ readonly ops: readonly [{
36
+ readonly kind: "import";
37
+ readonly names: readonly ["agentPanel"];
38
+ readonly from: "../agent/views.js";
39
+ }, {
40
+ readonly kind: "append-element";
41
+ readonly call: {
42
+ readonly callee: "createRootRoute";
43
+ readonly from: "@tanstack/react-router";
44
+ };
45
+ readonly path: readonly ["staticData", "views"];
46
+ readonly element: "agentPanel";
47
+ }];
48
+ }];
49
+ readonly mounts: readonly [{
50
+ readonly component: "AgentButton";
51
+ readonly module: "src/agent/agent-button.tsx";
52
+ readonly into: {
53
+ readonly file: "src/header-actions.tsx";
54
+ readonly parent: "HeaderActions";
55
+ };
56
+ }];
57
+ readonly env: readonly [];
58
+ readonly generate: readonly [];
59
+ readonly notes: readonly ["Restart the dev server. Open the Agent button to chat with the coding agents on this computer."];
60
+ };
61
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/addons/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2ChB,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { defineAddon, SERVER_ENTRY } from "../add/addon.js";
2
+ /**
3
+ * The default template already contains all of this; a test runs this add-on on it and expects
4
+ * no change, which is what keeps the two from drifting.
5
+ */
6
+ export const agent = defineAddon({
7
+ summary: "The agent sidebar: chat with your own coding agent inside the app.",
8
+ requires: { routesDir: "src/routes" },
9
+ dependencies: { "@parlor/chat": "framework" },
10
+ files: [{ template: "default", dir: "src/agent" }],
11
+ edits: [
12
+ {
13
+ file: SERVER_ENTRY,
14
+ ops: [
15
+ { kind: "import", names: ["chat"], from: "@parlor/chat/server" },
16
+ {
17
+ kind: "append-element",
18
+ call: { callee: "createServer", from: "@parlor/server" },
19
+ path: ["plugins"],
20
+ element: "chat()",
21
+ },
22
+ ],
23
+ },
24
+ {
25
+ file: "src/routes/__root.tsx",
26
+ ops: [
27
+ { kind: "import", names: ["agentPanel"], from: "../agent/views.js" },
28
+ {
29
+ kind: "append-element",
30
+ call: { callee: "createRootRoute", from: "@tanstack/react-router" },
31
+ path: ["staticData", "views"],
32
+ element: "agentPanel",
33
+ },
34
+ ],
35
+ },
36
+ ],
37
+ mounts: [
38
+ {
39
+ component: "AgentButton",
40
+ module: "src/agent/agent-button.tsx",
41
+ into: { file: "src/header-actions.tsx", parent: "HeaderActions" },
42
+ },
43
+ ],
44
+ env: [],
45
+ generate: [],
46
+ notes: [
47
+ "Restart the dev server. Open the Agent button to chat with the coding agents on this computer.",
48
+ ],
49
+ });
50
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/addons/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC;IAC/B,OAAO,EAAE,oEAAoE;IAC7E,QAAQ,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE;IACrC,YAAY,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE;IAC7C,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IAClD,KAAK,EAAE;QACL;YACE,IAAI,EAAE,YAAY;YAClB,GAAG,EAAE;gBACH,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE;gBAChE;oBACE,IAAI,EAAE,gBAAgB;oBACtB,IAAI,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,gBAAgB,EAAE;oBACxD,IAAI,EAAE,CAAC,SAAS,CAAC;oBACjB,OAAO,EAAE,QAAQ;iBAClB;aACF;SACF;QACD;YACE,IAAI,EAAE,uBAAuB;YAC7B,GAAG,EAAE;gBACH,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE;gBACpE;oBACE,IAAI,EAAE,gBAAgB;oBACtB,IAAI,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,wBAAwB,EAAE;oBACnE,IAAI,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;oBAC7B,OAAO,EAAE,YAAY;iBACtB;aACF;SACF;KACF;IACD,MAAM,EAAE;QACN;YACE,SAAS,EAAE,aAAa;YACxB,MAAM,EAAE,4BAA4B;YACpC,IAAI,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,MAAM,EAAE,eAAe,EAAE;SAClE;KACF;IACD,GAAG,EAAE,EAAE;IACP,QAAQ,EAAE,EAAE;IACZ,KAAK,EAAE;QACL,gGAAgG;KACjG;CACF,CAAC,CAAC"}