@lenne.tech/cli 1.24.0 → 1.24.1
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.
|
@@ -301,6 +301,18 @@ const NewCommand = {
|
|
|
301
301
|
else {
|
|
302
302
|
renameSpinner.succeed(`Renamed nest-base → ${projectDir} in projects/api`);
|
|
303
303
|
}
|
|
304
|
+
// Flip .claude/upstream.json from the template-self default to the
|
|
305
|
+
// downstream shape so `/upstream-pr` can contribute core fixes back
|
|
306
|
+
// to nest-base. Independent of the rename above — run it even if
|
|
307
|
+
// the rename failed. Non-fatal when the file is absent.
|
|
308
|
+
const upstreamResult = (0, workspace_integration_1.reconfigureUpstreamForDownstream)({
|
|
309
|
+
apiDir: apiDest,
|
|
310
|
+
filesystem,
|
|
311
|
+
upstreamBranch: apiBranch,
|
|
312
|
+
});
|
|
313
|
+
if (upstreamResult.updated) {
|
|
314
|
+
info('Configured .claude/upstream.json for downstream contributions');
|
|
315
|
+
}
|
|
304
316
|
}
|
|
305
317
|
// Persist apiMode + frameworkMode for downstream generators.
|
|
306
318
|
if (apiResult.method !== 'link') {
|
|
@@ -559,6 +559,18 @@ const NewCommand = {
|
|
|
559
559
|
catch (err) {
|
|
560
560
|
renameSpinner.warn(`Auto-rename failed (${err.message}). Run \`bun run rename ${projectDir}\` manually inside projects/api.`);
|
|
561
561
|
}
|
|
562
|
+
// Flip .claude/upstream.json from the template-self default to the
|
|
563
|
+
// downstream shape so `/upstream-pr` can contribute core fixes back
|
|
564
|
+
// to nest-base. Independent of the rename above — run it even if the
|
|
565
|
+
// rename failed. Non-fatal when the file is absent.
|
|
566
|
+
const upstreamResult = (0, workspace_integration_1.reconfigureUpstreamForDownstream)({
|
|
567
|
+
apiDir: apiDest,
|
|
568
|
+
filesystem,
|
|
569
|
+
upstreamBranch: apiBranch,
|
|
570
|
+
});
|
|
571
|
+
if (upstreamResult.updated) {
|
|
572
|
+
info('Configured .claude/upstream.json for downstream contributions');
|
|
573
|
+
}
|
|
562
574
|
}
|
|
563
575
|
// Create lt.config.json for API
|
|
564
576
|
// Note: frameworkMode is persisted under meta so that subsequent `lt
|
|
@@ -376,6 +376,21 @@ const NewCommand = {
|
|
|
376
376
|
}
|
|
377
377
|
return `created server symlink ${name}`;
|
|
378
378
|
}
|
|
379
|
+
// For the experimental nest-base template, flip .claude/upstream.json
|
|
380
|
+
// from the template-self default to the downstream shape so
|
|
381
|
+
// `/upstream-pr` can contribute core fixes back to nest-base. The
|
|
382
|
+
// standalone clone lands directly at `projectDir`. Non-fatal when the
|
|
383
|
+
// file is absent (older templates).
|
|
384
|
+
if (experimental) {
|
|
385
|
+
const upstreamResult = (0, workspace_integration_1.reconfigureUpstreamForDownstream)({
|
|
386
|
+
apiDir: projectDir,
|
|
387
|
+
filesystem,
|
|
388
|
+
upstreamBranch: branch,
|
|
389
|
+
});
|
|
390
|
+
if (upstreamResult.updated) {
|
|
391
|
+
info('Configured .claude/upstream.json for downstream contributions');
|
|
392
|
+
}
|
|
393
|
+
}
|
|
379
394
|
// Git initialization (after npm install which is done in setupServer).
|
|
380
395
|
// When cwd is not inside a repo, `git rev-parse` exits 128 — treat as false.
|
|
381
396
|
if (git) {
|
|
@@ -40,6 +40,7 @@ exports.detectSubProjectContext = detectSubProjectContext;
|
|
|
40
40
|
exports.detectWorkspaceLayout = detectWorkspaceLayout;
|
|
41
41
|
exports.findWorkspaceRoot = findWorkspaceRoot;
|
|
42
42
|
exports.isNonInteractive = isNonInteractive;
|
|
43
|
+
exports.reconfigureUpstreamForDownstream = reconfigureUpstreamForDownstream;
|
|
43
44
|
exports.runExperimentalNestBaseRename = runExperimentalNestBaseRename;
|
|
44
45
|
exports.runStandaloneWorkspaceGate = runStandaloneWorkspaceGate;
|
|
45
46
|
exports.shouldProceedAsStandalone = shouldProceedAsStandalone;
|
|
@@ -140,6 +141,60 @@ function isNonInteractive(noConfirmFlag) {
|
|
|
140
141
|
// process.stdin may be undefined in some test runners — guard.
|
|
141
142
|
return Boolean(process.stdin && process.stdin.isTTY === false);
|
|
142
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Reconfigure the cloned nest-base template's `.claude/upstream.json`
|
|
146
|
+
* into its downstream shape.
|
|
147
|
+
*
|
|
148
|
+
* WHY: nest-base ships `.claude/upstream.json` with `isTemplate: true`
|
|
149
|
+
* and `upstream: null` — the template-self default. The `/upstream-pr`
|
|
150
|
+
* slash command and the `contributing-upstream` skill key off
|
|
151
|
+
* `isTemplate` and refuse to open upstream PRs when it is still `true`
|
|
152
|
+
* ("this repo IS the template"). The template's own notes document a
|
|
153
|
+
* manual post-fork step (flip `isTemplate` to false, fill `upstream`)
|
|
154
|
+
* that humans and agents both forget. The `bun run rename` step only
|
|
155
|
+
* rewrites four files and never touches this one, so without this
|
|
156
|
+
* helper every scaffolded project keeps `isTemplate: true` and can
|
|
157
|
+
* never contribute core fixes back to nest-base.
|
|
158
|
+
*
|
|
159
|
+
* Behaviour:
|
|
160
|
+
* - Missing file (or unparseable JSON) → `{ updated: false }`, no
|
|
161
|
+
* throw. Older templates may not ship the file at all; that is not
|
|
162
|
+
* an error, just nothing to do.
|
|
163
|
+
* - Otherwise sets `isTemplate = false` and
|
|
164
|
+
* `upstream = { repo, branch }`, preserving `$schema` and
|
|
165
|
+
* `syncedPaths` exactly as the template defined them.
|
|
166
|
+
*
|
|
167
|
+
* Idempotent: running twice yields identical output.
|
|
168
|
+
*/
|
|
169
|
+
function reconfigureUpstreamForDownstream(options) {
|
|
170
|
+
const { apiDir, filesystem, upstreamBranch, upstreamRepo } = options;
|
|
171
|
+
const upstreamPath = filesystem.path(apiDir, '.claude', 'upstream.json');
|
|
172
|
+
// Non-fatal when absent — older templates may not ship the file.
|
|
173
|
+
if (filesystem.exists(upstreamPath) !== 'file') {
|
|
174
|
+
return { updated: false };
|
|
175
|
+
}
|
|
176
|
+
const current = filesystem.read(upstreamPath, 'json');
|
|
177
|
+
if (!current) {
|
|
178
|
+
// Unparseable / empty JSON — leave it untouched rather than risk
|
|
179
|
+
// clobbering hand-edited content with a guessed shape.
|
|
180
|
+
return { updated: false };
|
|
181
|
+
}
|
|
182
|
+
const next = Object.assign(Object.assign({}, current), {
|
|
183
|
+
// The whole point of the fix: this is a fork, not the template.
|
|
184
|
+
isTemplate: false,
|
|
185
|
+
// Replace the template-self notes (no longer applicable) with a
|
|
186
|
+
// short downstream-appropriate marker. Kept as a fixed array so the
|
|
187
|
+
// operation is idempotent.
|
|
188
|
+
notes: [
|
|
189
|
+
'Downstream project forked from the nest-base template.',
|
|
190
|
+
'Core fixes flow back upstream via the /upstream-pr command.',
|
|
191
|
+
], upstream: {
|
|
192
|
+
branch: upstreamBranch !== null && upstreamBranch !== void 0 ? upstreamBranch : 'main',
|
|
193
|
+
repo: upstreamRepo !== null && upstreamRepo !== void 0 ? upstreamRepo : 'lenneTech/nest-base',
|
|
194
|
+
} });
|
|
195
|
+
filesystem.write(upstreamPath, next, { jsonIndent: 2 });
|
|
196
|
+
return { updated: true };
|
|
197
|
+
}
|
|
143
198
|
/**
|
|
144
199
|
* Run the experimental `bun run rename <projectDir>` step. Only relevant
|
|
145
200
|
* for the `--next` nest-base template (it ships hard-coded `nest-base`
|