@bitmagic/cli 0.1.16 → 0.1.18
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.
- package/README.md +31 -6
- package/dist/commands/upgrade.d.ts +28 -0
- package/dist/commands/upgrade.js +76 -0
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/project/context.d.ts +2 -0
- package/dist/project/context.js.map +1 -1
- package/dist/scaffold/agents-md.d.ts +51 -0
- package/dist/scaffold/agents-md.js +102 -0
- package/dist/scaffold/agents-md.js.map +1 -0
- package/dist/scaffold/project-files.d.ts +8 -0
- package/dist/scaffold/project-files.js +19 -0
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.d.ts +15 -3
- package/dist/scaffold/project.js +23 -7
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/upgrade-project.d.ts +19 -4
- package/dist/scaffold/upgrade-project.js +33 -6
- package/dist/scaffold/upgrade-project.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ bitmagic publish # verify-gate, build, and ship — private by defa
|
|
|
38
38
|
| `bitmagic verify [--timeout <ms>]` | Build, boot the game in a headless browser, click the engine's Play button like a player would, and report what broke. A game without the button passes as long as gameplay starts by itself (auto-starting genres, custom start UIs); a run where gameplay never starts fails. `--timeout` is settle time in ms measured after gameplay starts, so the screenshot captures gameplay. Writes the artifacts the publish gate reads (see below). |
|
|
39
39
|
| `bitmagic build` | Bundle the game into one self-contained `.bitmagic/build/index.html`. Rarely needs to be run by hand — `publish` builds automatically when the project changed. |
|
|
40
40
|
| `bitmagic publish [--visibility public\|private] [--name <name>] [--description <desc>] [--force]` | Verify-gate, build if needed, and upload straight to GCS. **Private unless `--visibility public` is passed.** |
|
|
41
|
-
| `bitmagic upgrade [--engine <version>] [--force]` | Refresh vendored platform files to the currently published engine. Refuses a dirty git tree unless `--force`. |
|
|
41
|
+
| `bitmagic upgrade [--engine <version>] [--force]` | Refresh vendored platform files and the CLI's own skills to the currently published engine. Refuses a dirty git tree unless `--force`. |
|
|
42
42
|
| `bitmagic generate <skybox\|sound\|image\|character\|animation> ...` | Generate one asset directly into `src/work/world.json`. Costs sparks. |
|
|
43
43
|
| `bitmagic cover [--prompt "..."] [--force] [--no-start-screen]` | Generate the game's cover art from `GAME-DESIGN.md`: sets the start screen, saves `.bitmagic/cover.webp`, becomes the publish thumbnail. Costs sparks. |
|
|
44
44
|
| `bitmagic forge --prompt "..." [--city\|--dungeon\|--platformer\|--freeform] [--name <name>] [--resume <jobId>]` | Design and bake a whole playable level into `world.json`. Slow and expensive; supports `--resume`. |
|
|
@@ -62,6 +62,7 @@ my-game/
|
|
|
62
62
|
.bitmagic/
|
|
63
63
|
cover.webp # bitmagic cover's artwork — the publish thumbnail when present
|
|
64
64
|
cover.json # its URL and the design hash it was generated from
|
|
65
|
+
AGENTS.md.latest # the current AGENTS.md template, when upgrade kept your edited one
|
|
65
66
|
build/
|
|
66
67
|
index.html # bitmagic build's output bundle
|
|
67
68
|
manifest.json # engineVersion, fingerprint, bytes, sha256, builtAt
|
|
@@ -137,11 +138,35 @@ invalidate the verify you just checked.
|
|
|
137
138
|
|
|
138
139
|
## Upgrading
|
|
139
140
|
|
|
140
|
-
`bitmagic upgrade` refreshes the vendored `engine/`, the generated config files,
|
|
141
|
-
to the currently published engine version. It
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
`bitmagic upgrade` refreshes the vendored `engine/`, the generated config files, `index.html`, and
|
|
142
|
+
**the skills this CLI ships** (`.claude/skills/`) to the currently published engine version. It
|
|
143
|
+
refuses to run against a dirty git working tree unless `--force`, so the upgrade always shows up as
|
|
144
|
+
its own reviewable diff.
|
|
145
|
+
|
|
146
|
+
What is yours and never touched: `src/`, `world.json`, `game.json`, `package.json`, `CLAUDE.md`,
|
|
147
|
+
`GAME-DESIGN.md`, `.gitignore`, and any skill you wrote yourself.
|
|
148
|
+
|
|
149
|
+
`AGENTS.md` is the one conditional case, and it can never lose your work. The CLI records a hash of
|
|
150
|
+
the `AGENTS.md` it writes. On a later upgrade:
|
|
151
|
+
|
|
152
|
+
- **Still byte-identical to what we wrote** — you never edited it, so refreshing it only replaces
|
|
153
|
+
our words with our newer ones. It is refreshed, and the output says so.
|
|
154
|
+
- **Edited by you (or scaffolded before this existed)** — it is left exactly as it is. The output
|
|
155
|
+
names the sections the current template has that yours does not, and writes the current template
|
|
156
|
+
to `.bitmagic/AGENTS.md.latest` so you (or your agent) can diff and merge the parts you want.
|
|
157
|
+
|
|
158
|
+
That is why `bitmagic cover` could ship and stay invisible: an agent only knows what its `AGENTS.md`
|
|
159
|
+
tells it, and nothing was updating that file.
|
|
160
|
+
|
|
161
|
+
The shipped skills are on the refreshed side deliberately. They describe what the **CLI** can do,
|
|
162
|
+
not what your game is, so a project holding the version that came with its scaffold has an agent
|
|
163
|
+
that cannot discover anything added since — which is exactly what happened when `bitmagic cover`
|
|
164
|
+
shipped. The cost is that edits to *our* skill files are lost on upgrade; put your own guidance in
|
|
165
|
+
`AGENTS.md` or a skill of your own, both of which are left alone.
|
|
166
|
+
|
|
167
|
+
Where an upgrade leaves a project unable to use something the CLI can now do, it says so rather
|
|
168
|
+
than fixing it silently: a project with no `GAME-DESIGN.md` is told what to write and that
|
|
169
|
+
`bitmagic cover` needs it.
|
|
145
170
|
|
|
146
171
|
`upgrade` **reports** missing or outdated dependencies rather than installing them — it prints the
|
|
147
172
|
exact install command to run, using your project's own package manager (detected from
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Output } from '../output.js';
|
|
2
|
+
import type { AgentsMdOutcome } from '../scaffold/agents-md.js';
|
|
2
3
|
import { type DependencyMismatch } from '../scaffold/dependency-diff.js';
|
|
3
4
|
export interface GitStatus {
|
|
4
5
|
dirty: boolean;
|
|
@@ -26,6 +27,33 @@ export declare function assertCleanTree(status: GitStatus, force: boolean): void
|
|
|
26
27
|
* calling this proves the printed line actually uses them.
|
|
27
28
|
*/
|
|
28
29
|
export declare function printDependencyReport(output: Output, root: string): DependencyMismatch[];
|
|
30
|
+
/**
|
|
31
|
+
* Say what became of AGENTS.md, and — when it was kept — what the current template has that it
|
|
32
|
+
* does not.
|
|
33
|
+
*
|
|
34
|
+
* Only `kept` is worth more than a line. `current` says nothing at all: reporting "unchanged" on
|
|
35
|
+
* every upgrade of every project is the kind of output people stop reading, which costs the
|
|
36
|
+
* messages that do matter.
|
|
37
|
+
*/
|
|
38
|
+
export declare function reportAgentsMd(output: Output, outcome: AgentsMdOutcome): void;
|
|
39
|
+
/**
|
|
40
|
+
* Tell a project scaffolded before GAME-DESIGN.md existed that it is missing one, and return
|
|
41
|
+
* whether it was.
|
|
42
|
+
*
|
|
43
|
+
* The same shape as the dependency report above, and for the same reason: `upgrade` deliberately
|
|
44
|
+
* never writes a creator-owned file, so where an upgrade leaves a project unable to use something
|
|
45
|
+
* the CLI can now do, it has to say so rather than let the gap sit there silently. Cover art is
|
|
46
|
+
* exactly that case — the command reached every project the moment the CLI updated, but its input
|
|
47
|
+
* only reaches projects scaffolded since.
|
|
48
|
+
*
|
|
49
|
+
* Conditioned on the file genuinely being absent, never on a version number. A "what's new in this
|
|
50
|
+
* release" banner would be printed to projects that already have the thing, and would rot into a
|
|
51
|
+
* lie the release after next; this cannot, because it is reporting a fact about the disk.
|
|
52
|
+
*
|
|
53
|
+
* It stays a nudge: writing the design document for someone would be putting our words in their
|
|
54
|
+
* game's mouth, and the file is theirs.
|
|
55
|
+
*/
|
|
56
|
+
export declare function reportMissingDesignDoc(output: Output, root: string): boolean;
|
|
29
57
|
export declare const upgradeCommand: import("citty").CommandDef<{
|
|
30
58
|
readonly engine: {
|
|
31
59
|
readonly type: "string";
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -109,6 +109,70 @@ export function printDependencyReport(output, root) {
|
|
|
109
109
|
}
|
|
110
110
|
return mismatches;
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Say what became of AGENTS.md, and — when it was kept — what the current template has that it
|
|
114
|
+
* does not.
|
|
115
|
+
*
|
|
116
|
+
* Only `kept` is worth more than a line. `current` says nothing at all: reporting "unchanged" on
|
|
117
|
+
* every upgrade of every project is the kind of output people stop reading, which costs the
|
|
118
|
+
* messages that do matter.
|
|
119
|
+
*/
|
|
120
|
+
export function reportAgentsMd(output, outcome) {
|
|
121
|
+
if (outcome.action === 'current')
|
|
122
|
+
return;
|
|
123
|
+
output.info('');
|
|
124
|
+
if (outcome.action === 'rewritten') {
|
|
125
|
+
output.info('Refreshed AGENTS.md — it was still exactly as the CLI last wrote it, so nothing was lost.');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (outcome.action === 'created') {
|
|
129
|
+
output.info('Wrote AGENTS.md — this project had none.');
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
output.info('AGENTS.md has your edits, so it was left alone.');
|
|
133
|
+
if (outcome.missingSections.length > 0) {
|
|
134
|
+
output.info(` It is missing ${outcome.missingSections.length} section${outcome.missingSections.length === 1 ? '' : 's'} the current template has:`);
|
|
135
|
+
for (const heading of outcome.missingSections) {
|
|
136
|
+
output.info(` - ${heading}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
output.info(' It has every section the current template has, but the wording has moved on.');
|
|
141
|
+
}
|
|
142
|
+
if (outcome.templatePath !== undefined) {
|
|
143
|
+
output.info(` Current template: ${outcome.templatePath}`);
|
|
144
|
+
output.info(' Diff it against your AGENTS.md and merge what you want to keep.');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Tell a project scaffolded before GAME-DESIGN.md existed that it is missing one, and return
|
|
149
|
+
* whether it was.
|
|
150
|
+
*
|
|
151
|
+
* The same shape as the dependency report above, and for the same reason: `upgrade` deliberately
|
|
152
|
+
* never writes a creator-owned file, so where an upgrade leaves a project unable to use something
|
|
153
|
+
* the CLI can now do, it has to say so rather than let the gap sit there silently. Cover art is
|
|
154
|
+
* exactly that case — the command reached every project the moment the CLI updated, but its input
|
|
155
|
+
* only reaches projects scaffolded since.
|
|
156
|
+
*
|
|
157
|
+
* Conditioned on the file genuinely being absent, never on a version number. A "what's new in this
|
|
158
|
+
* release" banner would be printed to projects that already have the thing, and would rot into a
|
|
159
|
+
* lie the release after next; this cannot, because it is reporting a fact about the disk.
|
|
160
|
+
*
|
|
161
|
+
* It stays a nudge: writing the design document for someone would be putting our words in their
|
|
162
|
+
* game's mouth, and the file is theirs.
|
|
163
|
+
*/
|
|
164
|
+
export function reportMissingDesignDoc(output, root) {
|
|
165
|
+
if (fs.existsSync(path.join(root, 'GAME-DESIGN.md')))
|
|
166
|
+
return false;
|
|
167
|
+
output.info('');
|
|
168
|
+
output.info('This project has no GAME-DESIGN.md — it predates one. `bitmagic cover` generates the ' +
|
|
169
|
+
"game's cover art from that file, and cannot run without it.");
|
|
170
|
+
output.info(' Write GAME-DESIGN.md (pitch, core loop, world & look), then run `bitmagic cover`.');
|
|
171
|
+
output.info(' Or generate from a one-off description: `bitmagic cover --prompt "..."`.');
|
|
172
|
+
output.info(' Your AGENTS.md is yours and was not touched, so it may not mention this yet — the ' +
|
|
173
|
+
'generating-assets skill, which upgrade DID refresh, does.');
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
112
176
|
export const upgradeCommand = defineCommand({
|
|
113
177
|
meta: {
|
|
114
178
|
name: 'upgrade',
|
|
@@ -168,6 +232,8 @@ export const upgradeCommand = defineCommand({
|
|
|
168
232
|
output.info(` ${file}`);
|
|
169
233
|
}
|
|
170
234
|
const mismatches = printDependencyReport(output, context.root);
|
|
235
|
+
reportAgentsMd(output, result.agentsMd);
|
|
236
|
+
const needsDesignDoc = reportMissingDesignDoc(output, context.root);
|
|
171
237
|
output.result({
|
|
172
238
|
ok: true,
|
|
173
239
|
engineVersion: result.engineVersion,
|
|
@@ -176,6 +242,16 @@ export const upgradeCommand = defineCommand({
|
|
|
176
242
|
// The install command is printed as prose; an agent gets the structured form instead of
|
|
177
243
|
// parsing it back out of a sentence.
|
|
178
244
|
missingDependencies: mismatches,
|
|
245
|
+
// True for projects scaffolded before GAME-DESIGN.md existed: `bitmagic cover` has nothing
|
|
246
|
+
// to read until one is written.
|
|
247
|
+
missingDesignDoc: needsDesignDoc,
|
|
248
|
+
// Enough for an agent to act without parsing prose: whether its own guidance was refreshed,
|
|
249
|
+
// which sections it is behind on, and the file to diff against.
|
|
250
|
+
agentsMd: {
|
|
251
|
+
action: result.agentsMd.action,
|
|
252
|
+
missingSections: result.agentsMd.missingSections,
|
|
253
|
+
templatePath: result.agentsMd.templatePath ?? null,
|
|
254
|
+
},
|
|
179
255
|
});
|
|
180
256
|
}
|
|
181
257
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,YAAY,EAAe,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACvG,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,8 @@ export interface ProjectMetadata {
|
|
|
3
3
|
engineVersion: string;
|
|
4
4
|
genre: string;
|
|
5
5
|
template: string;
|
|
6
|
+
/** See the same field in scaffold/project-files.ts. Absent on projects scaffolded before it. */
|
|
7
|
+
agentsMdHash?: string;
|
|
6
8
|
}
|
|
7
9
|
export interface ProjectContext {
|
|
8
10
|
root: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare const AGENTS_MD_FILE = "AGENTS.md";
|
|
2
|
+
/**
|
|
3
|
+
* Where the current template is written when the creator's own file is kept. Under `.bitmagic/`
|
|
4
|
+
* so it is gitignored and outside the publish fingerprint — a suggestion must not make a passing
|
|
5
|
+
* verify stale, or taking the suggestion would cost a re-verify.
|
|
6
|
+
*/
|
|
7
|
+
export declare const AGENTS_MD_TEMPLATE_FILE: string;
|
|
8
|
+
export declare function hashAgentsMd(contents: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* The `## ` headings of a markdown document, in order.
|
|
11
|
+
*
|
|
12
|
+
* Section granularity is the level that survives ordinary editing: a creator who rewrites a
|
|
13
|
+
* paragraph, or appends notes of their own, still has the section. Comparing whole files would
|
|
14
|
+
* report "different" for every project that has ever been touched, which is noise rather than
|
|
15
|
+
* information. `#` (the title) and `###` (sub-points within a section) are deliberately ignored.
|
|
16
|
+
*/
|
|
17
|
+
export declare function sectionHeadings(markdown: string): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Sections the current template has that theirs does not.
|
|
20
|
+
*
|
|
21
|
+
* Matched on the heading text, so a renamed heading reads as missing. That is the right way to be
|
|
22
|
+
* wrong for a suggestion nobody is forced to act on: a false positive costs a line of output, a
|
|
23
|
+
* false negative silently withholds the guidance this exists to deliver.
|
|
24
|
+
*/
|
|
25
|
+
export declare function missingSections(theirs: string, ours: string): string[];
|
|
26
|
+
export type AgentsMdAction =
|
|
27
|
+
/** Did not exist — written fresh. */
|
|
28
|
+
'created'
|
|
29
|
+
/** Byte-identical to the stamp, so replaced with the current template. */
|
|
30
|
+
| 'rewritten'
|
|
31
|
+
/** Already the current template. Nothing to do, nothing to say. */
|
|
32
|
+
| 'current'
|
|
33
|
+
/** Carries edits (or predates stamping) — left exactly as it was. */
|
|
34
|
+
| 'kept';
|
|
35
|
+
export interface AgentsMdOutcome {
|
|
36
|
+
action: AgentsMdAction;
|
|
37
|
+
/** The stamp to record, or undefined to leave whatever is already there alone. */
|
|
38
|
+
hashToStore?: string;
|
|
39
|
+
/** Only for `kept`: sections of the current template their file does not have. */
|
|
40
|
+
missingSections: string[];
|
|
41
|
+
/** Only for `kept` with something to show: where the current template was written. */
|
|
42
|
+
templatePath?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Bring a project's AGENTS.md up to date as far as is provably safe, and report what to tell the
|
|
46
|
+
* creator. See the file header for the rule; this is where it is applied.
|
|
47
|
+
*
|
|
48
|
+
* `storedHash` is `bitmagic.json`'s `agentsMdHash` — absent for any project scaffolded before this
|
|
49
|
+
* existed, which is exactly the population that most needs the suggestion path.
|
|
50
|
+
*/
|
|
51
|
+
export declare function reconcileAgentsMd(root: string, storedHash: string | undefined): AgentsMdOutcome;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeping a project's AGENTS.md current without ever destroying what its creator wrote.
|
|
3
|
+
*
|
|
4
|
+
* AGENTS.md is the file that decides what an agent working in a scaffolded project knows how to
|
|
5
|
+
* do, and the template grows: `bitmagic cover` is the case that exposed the problem, but the
|
|
6
|
+
* coordinate-system warning and the publish exit-code table arrived the same way. It is also the
|
|
7
|
+
* file a creator is most likely to have customised, so `upgrade` cannot simply overwrite it the
|
|
8
|
+
* way it overwrites the skills.
|
|
9
|
+
*
|
|
10
|
+
* The way out is to know whether it was edited at all, rather than guessing. `scaffoldProject` and
|
|
11
|
+
* every rewrite here stamp a hash of exactly what was written into `bitmagic.json`. On a later
|
|
12
|
+
* upgrade the file is re-hashed:
|
|
13
|
+
*
|
|
14
|
+
* - hash matches the stamp → the creator never touched it, so rewriting it can only replace our
|
|
15
|
+
* own words with our own newer words. Provably lossless, so just do it.
|
|
16
|
+
* - hash differs, or there is no stamp (every project scaffolded before this shipped) → their
|
|
17
|
+
* edits are in there. Keep the file, name the sections of the current template it does not
|
|
18
|
+
* have, and write the current template next to it for diffing.
|
|
19
|
+
*
|
|
20
|
+
* The fallback is the safe direction in every ambiguous case: an unstamped project is treated as
|
|
21
|
+
* edited, so the worst outcome is a suggestion the creator ignores.
|
|
22
|
+
*/
|
|
23
|
+
import { createHash } from 'crypto';
|
|
24
|
+
import * as fs from 'fs';
|
|
25
|
+
import * as path from 'path';
|
|
26
|
+
import { renderAgentsMd } from './project-files.js';
|
|
27
|
+
export const AGENTS_MD_FILE = 'AGENTS.md';
|
|
28
|
+
/**
|
|
29
|
+
* Where the current template is written when the creator's own file is kept. Under `.bitmagic/`
|
|
30
|
+
* so it is gitignored and outside the publish fingerprint — a suggestion must not make a passing
|
|
31
|
+
* verify stale, or taking the suggestion would cost a re-verify.
|
|
32
|
+
*/
|
|
33
|
+
export const AGENTS_MD_TEMPLATE_FILE = path.join('.bitmagic', 'AGENTS.md.latest');
|
|
34
|
+
export function hashAgentsMd(contents) {
|
|
35
|
+
return createHash('sha256').update(contents, 'utf-8').digest('hex');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The `## ` headings of a markdown document, in order.
|
|
39
|
+
*
|
|
40
|
+
* Section granularity is the level that survives ordinary editing: a creator who rewrites a
|
|
41
|
+
* paragraph, or appends notes of their own, still has the section. Comparing whole files would
|
|
42
|
+
* report "different" for every project that has ever been touched, which is noise rather than
|
|
43
|
+
* information. `#` (the title) and `###` (sub-points within a section) are deliberately ignored.
|
|
44
|
+
*/
|
|
45
|
+
export function sectionHeadings(markdown) {
|
|
46
|
+
return markdown
|
|
47
|
+
.split('\n')
|
|
48
|
+
.filter((line) => line.startsWith('## '))
|
|
49
|
+
.map((line) => line.slice(3).trim());
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Sections the current template has that theirs does not.
|
|
53
|
+
*
|
|
54
|
+
* Matched on the heading text, so a renamed heading reads as missing. That is the right way to be
|
|
55
|
+
* wrong for a suggestion nobody is forced to act on: a false positive costs a line of output, a
|
|
56
|
+
* false negative silently withholds the guidance this exists to deliver.
|
|
57
|
+
*/
|
|
58
|
+
export function missingSections(theirs, ours) {
|
|
59
|
+
const have = new Set(sectionHeadings(theirs));
|
|
60
|
+
return sectionHeadings(ours).filter((heading) => !have.has(heading));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Bring a project's AGENTS.md up to date as far as is provably safe, and report what to tell the
|
|
64
|
+
* creator. See the file header for the rule; this is where it is applied.
|
|
65
|
+
*
|
|
66
|
+
* `storedHash` is `bitmagic.json`'s `agentsMdHash` — absent for any project scaffolded before this
|
|
67
|
+
* existed, which is exactly the population that most needs the suggestion path.
|
|
68
|
+
*/
|
|
69
|
+
export function reconcileAgentsMd(root, storedHash) {
|
|
70
|
+
const target = path.join(root, AGENTS_MD_FILE);
|
|
71
|
+
const current = renderAgentsMd();
|
|
72
|
+
const currentHash = hashAgentsMd(current);
|
|
73
|
+
let existing;
|
|
74
|
+
try {
|
|
75
|
+
existing = fs.readFileSync(target, 'utf-8');
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Deleted, or a project assembled by hand. There is nothing to preserve, and a project with no
|
|
79
|
+
// agent guidance at all is worse off than one with ours.
|
|
80
|
+
fs.writeFileSync(target, current);
|
|
81
|
+
return { action: 'created', hashToStore: currentHash, missingSections: [] };
|
|
82
|
+
}
|
|
83
|
+
const existingHash = hashAgentsMd(existing);
|
|
84
|
+
if (existingHash === currentHash) {
|
|
85
|
+
// Already ours and already current — including the case where they were stamped long ago and
|
|
86
|
+
// the template has not moved since.
|
|
87
|
+
return { action: 'current', hashToStore: currentHash, missingSections: [] };
|
|
88
|
+
}
|
|
89
|
+
if (storedHash !== undefined && existingHash === storedHash) {
|
|
90
|
+
// Unmodified since we last wrote it: replacing our own words with our own newer ones.
|
|
91
|
+
fs.writeFileSync(target, current);
|
|
92
|
+
return { action: 'rewritten', hashToStore: currentHash, missingSections: [] };
|
|
93
|
+
}
|
|
94
|
+
// Theirs. Leave the stamp alone too — it still records the last thing WE wrote, which is what a
|
|
95
|
+
// future comparison needs.
|
|
96
|
+
const missing = missingSections(existing, current);
|
|
97
|
+
const templatePath = path.join(root, AGENTS_MD_TEMPLATE_FILE);
|
|
98
|
+
fs.mkdirSync(path.dirname(templatePath), { recursive: true });
|
|
99
|
+
fs.writeFileSync(templatePath, current);
|
|
100
|
+
return { action: 'kept', missingSections: missing, templatePath };
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=agents-md.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../../src/scaffold/agents-md.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,14 @@ export interface ProjectMetadata {
|
|
|
30
30
|
engineVersion: string;
|
|
31
31
|
genre: string;
|
|
32
32
|
template: string;
|
|
33
|
+
/**
|
|
34
|
+
* sha256 of the AGENTS.md the CLI last wrote, so `bitmagic upgrade` can tell an untouched file
|
|
35
|
+
* (safe to refresh) from one the creator edited (never overwritten — see scaffold/agents-md.ts).
|
|
36
|
+
*
|
|
37
|
+
* Optional: every project scaffolded before this existed has none, and those are treated as
|
|
38
|
+
* edited, which is the safe direction.
|
|
39
|
+
*/
|
|
40
|
+
agentsMdHash?: string;
|
|
33
41
|
}
|
|
34
42
|
export declare function renderBitmagicJson(metadata: ProjectMetadata): string;
|
|
35
43
|
export declare function renderAgentsMd(): string;
|
|
@@ -304,6 +304,15 @@ export function renderAgentsMd() {
|
|
|
304
304
|
- \`engine/docs/\` — the engine's deep-dive documentation. Read it before guessing.
|
|
305
305
|
- \`GAME-DESIGN.md\` — **what this game is.** Yours to write and keep current. Nothing compiles it,
|
|
306
306
|
but \`bitmagic cover\` generates the cover art from it, so it is not decoration.
|
|
307
|
+
- \`.claude/skills/generating-assets/\` — **shipped by the CLI, re-rendered by \`bitmagic upgrade\`.**
|
|
308
|
+
It documents the CLI's own commands, so it stays current with them; edits to it are lost. Skills
|
|
309
|
+
you add yourself are never touched.
|
|
310
|
+
- \`AGENTS.md\` — this file. Yours to edit, and \`upgrade\` will never overwrite your edits. It
|
|
311
|
+
refreshes this file only while it is still byte-identical to what the CLI wrote; once you change
|
|
312
|
+
anything, it stops and instead tells you which sections of the current template you are missing,
|
|
313
|
+
leaving that template in \`.bitmagic/AGENTS.md.latest\` to diff against. **If you edit this file,
|
|
314
|
+
re-read that diff after an upgrade** — new CLI capabilities are documented here, and an edited
|
|
315
|
+
copy will not learn about them on its own.
|
|
307
316
|
|
|
308
317
|
\`engine/types/work-game.d.ts\` declares \`module 'work/Game.js'\`, which is how the engine
|
|
309
318
|
imports your game. Renaming or removing the \`VoxelGame\` export from \`src/work/Game.ts\` still
|
|
@@ -598,6 +607,16 @@ export function renderSkillsReadme() {
|
|
|
598
607
|
|
|
599
608
|
Claude Code skills placed in this directory apply to this project. See \`AGENTS.md\` at the
|
|
600
609
|
project root for the guidance an agent should read before editing this game.
|
|
610
|
+
|
|
611
|
+
## Which of these are yours
|
|
612
|
+
|
|
613
|
+
\`generating-assets/\` — and this README — are shipped by the Bitmagic CLI and **re-rendered by
|
|
614
|
+
\`bitmagic upgrade\`**. They describe what the CLI can do, so they have to stay current with it;
|
|
615
|
+
edits to them are lost on the next upgrade.
|
|
616
|
+
|
|
617
|
+
Every other directory here is yours. \`upgrade\` never opens a skill it does not ship, and never
|
|
618
|
+
deletes anything under \`.claude/\`. Put project-specific guidance in a skill of your own, or in
|
|
619
|
+
\`AGENTS.md\` — both are left alone.
|
|
601
620
|
`;
|
|
602
621
|
}
|
|
603
622
|
//# sourceMappingURL=project-files.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-files.js","sourceRoot":"","sources":["../../src/scaffold/project-files.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"project-files.js","sourceRoot":"","sources":["../../src/scaffold/project-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,9 +22,21 @@ export declare const VENDORED_DIRS: string[];
|
|
|
22
22
|
* platform-owned, and engine/ + sw-cache-buster.js, handled separately since they are copied, not
|
|
23
23
|
* rendered).
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
* creator's
|
|
27
|
-
*
|
|
25
|
+
* **Every skill this CLI deploys belongs here.** A skill documents what the CLI can do — not the
|
|
26
|
+
* creator's game — so a project stuck on the version that shipped with its scaffold is a project
|
|
27
|
+
* whose agent cannot discover anything added since. That is not hypothetical: `bitmagic cover`
|
|
28
|
+
* shipped and was invisible in every existing project, because the skill listing the generate
|
|
29
|
+
* commands was written once at init and never revisited. Whatever we add next would repeat it.
|
|
30
|
+
* Add a new skill to this list and existing projects receive it on their next `bitmagic upgrade`.
|
|
31
|
+
*
|
|
32
|
+
* Only the paths named here are rewritten; anything else under `.claude/` — a skill the creator
|
|
33
|
+
* wrote themselves — is never opened. The trade is deliberate and one-directional: an edit to one
|
|
34
|
+
* of OUR skill files is lost on upgrade, which is the price of those files staying current.
|
|
35
|
+
*
|
|
36
|
+
* Deliberately excludes package.json (creators add dependencies to it), AGENTS.md/CLAUDE.md and
|
|
37
|
+
* GAME-DESIGN.md (the creator's own guidance and design — ours to seed once, theirs to own), and
|
|
38
|
+
* .gitignore (same reasoning) — those are generated once by `scaffoldProject` but are creator-owned
|
|
39
|
+
* from that point on.
|
|
28
40
|
*
|
|
29
41
|
* Exported so `scaffoldProject` and `upgradeProject` share one definition instead of two lists
|
|
30
42
|
* that can drift — the exact failure that motivated this: `vite.publish.config.js` was added
|
package/dist/scaffold/project.js
CHANGED
|
@@ -3,6 +3,7 @@ import * as path from 'path';
|
|
|
3
3
|
import { CliError } from '../errors.js';
|
|
4
4
|
import { aliasSourceDir } from './aliases.js';
|
|
5
5
|
import { renderPackageJson, renderTsconfig, renderIndexHtml, renderViteConfig, renderVitePublishConfig, renderGitignore, renderBitmagicJson, renderAgentsMd, renderGameDesignMd, renderClaudeMd, renderSkillsReadme, renderGenerateSkill, } from './project-files.js';
|
|
6
|
+
import { hashAgentsMd } from './agents-md.js';
|
|
6
7
|
/**
|
|
7
8
|
* Directories moved out of the extracted tree into the project's vendored engine/.
|
|
8
9
|
*
|
|
@@ -31,9 +32,21 @@ export const VENDORED_DIRS = [
|
|
|
31
32
|
* platform-owned, and engine/ + sw-cache-buster.js, handled separately since they are copied, not
|
|
32
33
|
* rendered).
|
|
33
34
|
*
|
|
34
|
-
*
|
|
35
|
-
* creator's
|
|
36
|
-
*
|
|
35
|
+
* **Every skill this CLI deploys belongs here.** A skill documents what the CLI can do — not the
|
|
36
|
+
* creator's game — so a project stuck on the version that shipped with its scaffold is a project
|
|
37
|
+
* whose agent cannot discover anything added since. That is not hypothetical: `bitmagic cover`
|
|
38
|
+
* shipped and was invisible in every existing project, because the skill listing the generate
|
|
39
|
+
* commands was written once at init and never revisited. Whatever we add next would repeat it.
|
|
40
|
+
* Add a new skill to this list and existing projects receive it on their next `bitmagic upgrade`.
|
|
41
|
+
*
|
|
42
|
+
* Only the paths named here are rewritten; anything else under `.claude/` — a skill the creator
|
|
43
|
+
* wrote themselves — is never opened. The trade is deliberate and one-directional: an edit to one
|
|
44
|
+
* of OUR skill files is lost on upgrade, which is the price of those files staying current.
|
|
45
|
+
*
|
|
46
|
+
* Deliberately excludes package.json (creators add dependencies to it), AGENTS.md/CLAUDE.md and
|
|
47
|
+
* GAME-DESIGN.md (the creator's own guidance and design — ours to seed once, theirs to own), and
|
|
48
|
+
* .gitignore (same reasoning) — those are generated once by `scaffoldProject` but are creator-owned
|
|
49
|
+
* from that point on.
|
|
37
50
|
*
|
|
38
51
|
* Exported so `scaffoldProject` and `upgradeProject` share one definition instead of two lists
|
|
39
52
|
* that can drift — the exact failure that motivated this: `vite.publish.config.js` was added
|
|
@@ -45,6 +58,8 @@ export const PLATFORM_GENERATED_FILES = [
|
|
|
45
58
|
['vite.config.js', renderViteConfig],
|
|
46
59
|
['vite.publish.config.js', renderVitePublishConfig],
|
|
47
60
|
['index.html', renderIndexHtml],
|
|
61
|
+
['.claude/skills/README.md', renderSkillsReadme],
|
|
62
|
+
['.claude/skills/generating-assets/SKILL.md', renderGenerateSkill],
|
|
48
63
|
];
|
|
49
64
|
export function resolveTemplate(templatesDir, requestedId) {
|
|
50
65
|
const indexPath = path.join(templatesDir, 'index.json');
|
|
@@ -118,18 +133,19 @@ export function scaffoldProject(options) {
|
|
|
118
133
|
if (fs.existsSync(serviceWorker)) {
|
|
119
134
|
fs.cpSync(serviceWorker, path.join(targetDir, 'sw-cache-buster.js'));
|
|
120
135
|
}
|
|
136
|
+
// Stamped as it is written, so a later `bitmagic upgrade` can tell whether the creator has
|
|
137
|
+
// edited it since — see scaffold/agents-md.ts for what that decides.
|
|
138
|
+
const agentsMd = renderAgentsMd();
|
|
121
139
|
const files = [
|
|
122
140
|
['package.json', renderPackageJson(projectName)],
|
|
123
141
|
...PLATFORM_GENERATED_FILES.map((entry) => [entry[0], entry[1]()]),
|
|
124
|
-
['bitmagic.json', renderBitmagicJson(metadata)],
|
|
125
|
-
['AGENTS.md',
|
|
142
|
+
['bitmagic.json', renderBitmagicJson({ ...metadata, agentsMdHash: hashAgentsMd(agentsMd) })],
|
|
143
|
+
['AGENTS.md', agentsMd],
|
|
126
144
|
// Creator-owned from here on (see PLATFORM_GENERATED_FILES): the agent rewrites it as the
|
|
127
145
|
// game takes shape, and `bitmagic cover` reads whatever it says at the time.
|
|
128
146
|
['GAME-DESIGN.md', renderGameDesignMd(idea)],
|
|
129
147
|
['CLAUDE.md', renderClaudeMd()],
|
|
130
148
|
['.gitignore', renderGitignore()],
|
|
131
|
-
['.claude/skills/README.md', renderSkillsReadme()],
|
|
132
|
-
['.claude/skills/generating-assets/SKILL.md', renderGenerateSkill()],
|
|
133
149
|
];
|
|
134
150
|
for (const [name, contents] of files) {
|
|
135
151
|
const filePath = path.join(targetDir, name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/scaffold/project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/scaffold/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AgentsMdOutcome } from './agents-md.js';
|
|
1
2
|
export interface UpgradeOptions {
|
|
2
3
|
root: string;
|
|
3
4
|
/** Where extractEngine unpacked the new engine tree, same shape scaffoldProject reads from. */
|
|
@@ -10,14 +11,28 @@ export interface UpgradeResult {
|
|
|
10
11
|
previousEngineVersion: string;
|
|
11
12
|
/** Every top-level path this run actually rewrote, in the order it rewrote them. */
|
|
12
13
|
replaced: string[];
|
|
14
|
+
/** What happened to AGENTS.md, and what to suggest about it. See scaffold/agents-md.ts. */
|
|
15
|
+
agentsMd: AgentsMdOutcome;
|
|
13
16
|
}
|
|
14
17
|
/**
|
|
15
18
|
* Refreshes the platform-owned parts of a scaffolded project in place, and nothing else. This is
|
|
16
19
|
* the file-boundary described in the task brief: `engine/` (every VENDORED_DIRS entry) and
|
|
17
|
-
* sw-cache-buster.js are wholesale-replaced, the config files
|
|
18
|
-
* re-rendered, and bitmagic.json is read-modified-written so only its
|
|
19
|
-
* changes. Everything else on disk — src/, world.json, game.json,
|
|
20
|
-
*
|
|
20
|
+
* sw-cache-buster.js are wholesale-replaced, the config files AND SHIPPED SKILLS in
|
|
21
|
+
* PLATFORM_GENERATED_FILES are re-rendered, and bitmagic.json is read-modified-written so only its
|
|
22
|
+
* engineVersion field changes. Everything else on disk — src/, world.json, game.json,
|
|
23
|
+
* package.json, GAME-DESIGN.md, CLAUDE.md, .gitignore, and any skill the creator wrote themselves
|
|
24
|
+
* — is never opened.
|
|
25
|
+
*
|
|
26
|
+
* AGENTS.md is the one conditional case, and never a destructive one: it is refreshed only when it
|
|
27
|
+
* still hashes to what the CLI itself last wrote, and otherwise left untouched with a suggestion.
|
|
28
|
+
* See scaffold/agents-md.ts for why that is worth the machinery.
|
|
29
|
+
*
|
|
30
|
+
* The skills are in that list on purpose (see PLATFORM_GENERATED_FILES): they describe the CLI, so
|
|
31
|
+
* a project that never receives an updated one has an agent that cannot discover anything the CLI
|
|
32
|
+
* learned since the project was scaffolded. Note the asymmetry with the rest of `.claude/`: paths
|
|
33
|
+
* we render are overwritten, paths we do not are left entirely alone. Nothing under `.claude/` is
|
|
34
|
+
* ever deleted, so a skill we stop shipping stays behind rather than being cleaned up — a stale
|
|
35
|
+
* file being much cheaper than deleting one a creator wrote.
|
|
21
36
|
*
|
|
22
37
|
* Mirrors scaffoldProject's copy behaviour (same VENDORED_DIRS loop, same corrupt-tarball error
|
|
23
38
|
* when a directory is missing from the extracted tree), except it clears engine/ first: unlike a
|
|
@@ -2,13 +2,26 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { CliError } from '../errors.js';
|
|
4
4
|
import { VENDORED_DIRS, PLATFORM_GENERATED_FILES } from './project.js';
|
|
5
|
+
import { reconcileAgentsMd, AGENTS_MD_FILE } from './agents-md.js';
|
|
5
6
|
/**
|
|
6
7
|
* Refreshes the platform-owned parts of a scaffolded project in place, and nothing else. This is
|
|
7
8
|
* the file-boundary described in the task brief: `engine/` (every VENDORED_DIRS entry) and
|
|
8
|
-
* sw-cache-buster.js are wholesale-replaced, the config files
|
|
9
|
-
* re-rendered, and bitmagic.json is read-modified-written so only its
|
|
10
|
-
* changes. Everything else on disk — src/, world.json, game.json,
|
|
11
|
-
*
|
|
9
|
+
* sw-cache-buster.js are wholesale-replaced, the config files AND SHIPPED SKILLS in
|
|
10
|
+
* PLATFORM_GENERATED_FILES are re-rendered, and bitmagic.json is read-modified-written so only its
|
|
11
|
+
* engineVersion field changes. Everything else on disk — src/, world.json, game.json,
|
|
12
|
+
* package.json, GAME-DESIGN.md, CLAUDE.md, .gitignore, and any skill the creator wrote themselves
|
|
13
|
+
* — is never opened.
|
|
14
|
+
*
|
|
15
|
+
* AGENTS.md is the one conditional case, and never a destructive one: it is refreshed only when it
|
|
16
|
+
* still hashes to what the CLI itself last wrote, and otherwise left untouched with a suggestion.
|
|
17
|
+
* See scaffold/agents-md.ts for why that is worth the machinery.
|
|
18
|
+
*
|
|
19
|
+
* The skills are in that list on purpose (see PLATFORM_GENERATED_FILES): they describe the CLI, so
|
|
20
|
+
* a project that never receives an updated one has an agent that cannot discover anything the CLI
|
|
21
|
+
* learned since the project was scaffolded. Note the asymmetry with the rest of `.claude/`: paths
|
|
22
|
+
* we render are overwritten, paths we do not are left entirely alone. Nothing under `.claude/` is
|
|
23
|
+
* ever deleted, so a skill we stop shipping stays behind rather than being cleaned up — a stale
|
|
24
|
+
* file being much cheaper than deleting one a creator wrote.
|
|
12
25
|
*
|
|
13
26
|
* Mirrors scaffoldProject's copy behaviour (same VENDORED_DIRS loop, same corrupt-tarball error
|
|
14
27
|
* when a directory is missing from the extracted tree), except it clears engine/ first: unlike a
|
|
@@ -47,7 +60,13 @@ export function upgradeProject(options) {
|
|
|
47
60
|
replaced.push('sw-cache-buster.js');
|
|
48
61
|
}
|
|
49
62
|
for (const [name, render] of PLATFORM_GENERATED_FILES) {
|
|
50
|
-
|
|
63
|
+
const filePath = path.join(root, name);
|
|
64
|
+
// The skills nest two directories deep, and a project scaffolded before they existed — or
|
|
65
|
+
// before a newly added one existed — has no such directory. Without this, writeFileSync ENOENTs
|
|
66
|
+
// and the upgrade dies AFTER engine/ has already been replaced. mkdir on an existing directory
|
|
67
|
+
// is a no-op, so the flat entries pay nothing for it.
|
|
68
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
69
|
+
fs.writeFileSync(filePath, render());
|
|
51
70
|
replaced.push(name);
|
|
52
71
|
}
|
|
53
72
|
// Read-modify-write, not re-rendered from renderBitmagicJson: re-rendering would discard any
|
|
@@ -56,8 +75,16 @@ export function upgradeProject(options) {
|
|
|
56
75
|
const meta = JSON.parse(fs.readFileSync(bitmagicJsonPath, 'utf-8'));
|
|
57
76
|
const previousEngineVersion = typeof meta.engineVersion === 'string' ? meta.engineVersion : '';
|
|
58
77
|
meta.engineVersion = engineVersion;
|
|
78
|
+
// AGENTS.md last, because it is the one file here whose treatment depends on reading the stamp
|
|
79
|
+
// out of the metadata above — and whose result is written back into it below.
|
|
80
|
+
const storedHash = typeof meta.agentsMdHash === 'string' ? meta.agentsMdHash : undefined;
|
|
81
|
+
const agentsMd = reconcileAgentsMd(root, storedHash);
|
|
82
|
+
if (agentsMd.hashToStore !== undefined)
|
|
83
|
+
meta.agentsMdHash = agentsMd.hashToStore;
|
|
84
|
+
if (agentsMd.action === 'created' || agentsMd.action === 'rewritten')
|
|
85
|
+
replaced.push(AGENTS_MD_FILE);
|
|
59
86
|
fs.writeFileSync(bitmagicJsonPath, `${JSON.stringify(meta, null, 2)}\n`);
|
|
60
87
|
replaced.push('bitmagic.json');
|
|
61
|
-
return { engineVersion, previousEngineVersion, replaced };
|
|
88
|
+
return { engineVersion, previousEngineVersion, replaced, agentsMd };
|
|
62
89
|
}
|
|
63
90
|
//# sourceMappingURL=upgrade-project.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade-project.js","sourceRoot":"","sources":["../../src/scaffold/upgrade-project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"upgrade-project.js","sourceRoot":"","sources":["../../src/scaffold/upgrade-project.ts"],"names":[],"mappings":"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"}
|