create-thally-docs 0.9.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.
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ downloadStarter
4
+ } from "./chunk-ENQIF6MA.js";
5
+ import {
6
+ applyStarterRuntimeSyncPlan,
7
+ mergeStarterOwnershipContracts,
8
+ parseStarterReleaseManifest,
9
+ planStarterRuntimeSync,
10
+ readStarterReleaseManifest,
11
+ starterManifestSha256
12
+ } from "./chunk-KXJT2MG5.js";
13
+ import {
14
+ STABLE_SCAFFOLD_RELEASE,
15
+ SUPPORTED_SCAFFOLD_RELEASES
16
+ } from "./chunk-WMHBVXWW.js";
17
+
18
+ // src/starter-update.ts
19
+ import {
20
+ existsSync,
21
+ mkdirSync,
22
+ mkdtempSync,
23
+ readFileSync,
24
+ rmSync
25
+ } from "fs";
26
+ import { tmpdir } from "os";
27
+ import { join } from "path";
28
+ var EMPTY_PLAN = {
29
+ copyPaths: [],
30
+ deletePaths: [],
31
+ conflictPaths: [],
32
+ manualReviewPaths: [],
33
+ preservedPaths: [],
34
+ unchangedPaths: [],
35
+ targetPreconditions: {}
36
+ };
37
+ function readDownstreamManifest(targetDir, manifestPath) {
38
+ const path = join(targetDir, manifestPath);
39
+ if (!existsSync(path)) {
40
+ throw new Error(
41
+ `This project has no ${manifestPath}; update it from a versioned Thally starter first.`
42
+ );
43
+ }
44
+ return readFileSync(path, "utf8");
45
+ }
46
+ function resolveStarterReleaseFromManifest(source, releases = SUPPORTED_SCAFFOLD_RELEASES) {
47
+ const hash = starterManifestSha256(source);
48
+ const matching = releases.filter(
49
+ (release) => release.source.manifestSha256 === hash
50
+ );
51
+ if (matching.length !== 1) {
52
+ throw new Error(
53
+ "The project starter manifest is edited, unknown, or ambiguously registered; refusing to update."
54
+ );
55
+ }
56
+ parseStarterReleaseManifest(source, matching[0]);
57
+ return matching[0];
58
+ }
59
+ function assertForwardRelease(previous, target) {
60
+ if (previous.source.repository !== target.source.repository || previous.source.manifestPath !== target.source.manifestPath) {
61
+ throw new Error("Starter updates cannot cross repository or manifest contracts.");
62
+ }
63
+ if (previous.source.commitSha !== target.source.commitSha && previous.starterVersion >= target.starterVersion) {
64
+ throw new Error("The installed CLI does not contain a newer starter release.");
65
+ }
66
+ }
67
+ async function updateStarterProject(options) {
68
+ const targetRelease = options.targetRelease ?? STABLE_SCAFFOLD_RELEASE;
69
+ const releases = options.releases ?? SUPPORTED_SCAFFOLD_RELEASES;
70
+ const manifestPath = targetRelease.source.manifestPath;
71
+ const downstreamManifest = readDownstreamManifest(options.targetDir, manifestPath);
72
+ const previousRelease = resolveStarterReleaseFromManifest(
73
+ downstreamManifest,
74
+ releases
75
+ );
76
+ assertForwardRelease(previousRelease, targetRelease);
77
+ if (previousRelease.source.commitSha === targetRelease.source.commitSha) {
78
+ return {
79
+ previousRelease,
80
+ targetRelease,
81
+ plan: EMPTY_PLAN,
82
+ isUpToDate: true,
83
+ applied: false
84
+ };
85
+ }
86
+ if (options.apply && !options.confirmed) {
87
+ throw new Error("Pass explicit confirmation before applying a starter update.");
88
+ }
89
+ const workspace = mkdtempSync(join(tmpdir(), "thally-starter-update-"));
90
+ const oldStarterDir = join(workspace, "old");
91
+ const newStarterDir = join(workspace, "new");
92
+ mkdirSync(oldStarterDir);
93
+ mkdirSync(newStarterDir);
94
+ const download = options.download ?? (async (targetDir, release) => {
95
+ await downloadStarter(targetDir, void 0, release, { announce: false });
96
+ });
97
+ try {
98
+ await download(oldStarterDir, previousRelease);
99
+ await download(newStarterDir, targetRelease);
100
+ const oldManifest = readStarterReleaseManifest(oldStarterDir, previousRelease);
101
+ const newManifest = readStarterReleaseManifest(newStarterDir, targetRelease);
102
+ const ownership = mergeStarterOwnershipContracts(
103
+ oldManifest.ownership,
104
+ newManifest.ownership
105
+ );
106
+ const plan = planStarterRuntimeSync(
107
+ oldStarterDir,
108
+ newStarterDir,
109
+ options.targetDir,
110
+ ownership
111
+ );
112
+ if (!options.apply) {
113
+ return {
114
+ previousRelease,
115
+ targetRelease,
116
+ plan,
117
+ isUpToDate: false,
118
+ applied: false
119
+ };
120
+ }
121
+ if (plan.conflictPaths.length > 0) {
122
+ throw new Error("Resolve starter synchronization conflicts before applying.");
123
+ }
124
+ if (readDownstreamManifest(options.targetDir, manifestPath) !== downstreamManifest) {
125
+ throw new Error("The project starter manifest changed during update planning.");
126
+ }
127
+ applyStarterRuntimeSyncPlan(
128
+ newStarterDir,
129
+ options.targetDir,
130
+ plan,
131
+ ownership,
132
+ {
133
+ confirmed: true,
134
+ provenance: {
135
+ sourcePath: join(newStarterDir, manifestPath),
136
+ targetPath: join(options.targetDir, manifestPath),
137
+ expectedSha256: previousRelease.source.manifestSha256
138
+ }
139
+ }
140
+ );
141
+ return {
142
+ previousRelease,
143
+ targetRelease,
144
+ plan,
145
+ isUpToDate: false,
146
+ applied: true
147
+ };
148
+ } finally {
149
+ rmSync(workspace, { recursive: true, force: true });
150
+ }
151
+ }
152
+ export {
153
+ resolveStarterReleaseFromManifest,
154
+ updateStarterProject
155
+ };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "create-thally-docs",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Scaffold the first documentation surface in a Thally product-knowledge pipeline.",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=18"
8
8
  },
9
9
  "bin": {
10
- "create-thally-docs": "./dist/index.js"
10
+ "create-thally-docs": "dist/index.js"
11
11
  },
12
12
  "exports": {
13
13
  ".": "./dist/index.js",
@@ -20,6 +20,14 @@
20
20
  "types": "./dist/release.d.ts",
21
21
  "import": "./dist/release.js"
22
22
  },
23
+ "./starter-sync": {
24
+ "types": "./dist/starter-sync.d.ts",
25
+ "import": "./dist/starter-sync.js"
26
+ },
27
+ "./starter-update": {
28
+ "types": "./dist/starter-update.d.ts",
29
+ "import": "./dist/starter-update.js"
30
+ },
23
31
  "./migrate": "./dist/migrate/index.js",
24
32
  "./package.json": "./package.json"
25
33
  },