@bitmagic/cli 0.1.61-dev.9 → 0.1.62-dev.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 (60) hide show
  1. package/README.md +27 -3
  2. package/assets/unity-import/README.md +13 -0
  3. package/assets/unity-import/blender_build.py +462 -0
  4. package/assets/unity-import/build_parts.py +263 -0
  5. package/assets/unity-import/convert_assets.py +193 -0
  6. package/assets/unity-import/fbx_ascii.py +156 -0
  7. package/assets/unity-import/fbx_axis.py +174 -0
  8. package/assets/unity-import/fbx_bounds.py +202 -0
  9. package/assets/unity-import/import_config.py +86 -0
  10. package/assets/unity-import/level_patches.example.json +23 -0
  11. package/assets/unity-import/mesh_walls.py +78 -0
  12. package/assets/unity-import/render_topdown.py +33 -0
  13. package/assets/unity-import/unity-import.example.json +27 -0
  14. package/assets/unity-import/unity_assets.py +114 -0
  15. package/assets/unity-import/unity_colliders2d.py +127 -0
  16. package/assets/unity-import/unity_extract.py +774 -0
  17. package/assets/unity-import/unity_markers.py +249 -0
  18. package/assets/unity-import/unity_renderers.py +279 -0
  19. package/assets/unity-import/write_arena_data.py +198 -0
  20. package/dist/cli.d.ts +12 -0
  21. package/dist/commands/import.d.ts +4 -0
  22. package/dist/commands/import.js +5 -0
  23. package/dist/commands/import.js.map +1 -1
  24. package/dist/commands/init.d.ts +4 -0
  25. package/dist/commands/init.js +20 -0
  26. package/dist/commands/init.js.map +1 -1
  27. package/dist/commands/upgrade.d.ts +4 -0
  28. package/dist/commands/upgrade.js +31 -5
  29. package/dist/commands/upgrade.js.map +1 -1
  30. package/dist/editor/server.js +3 -3
  31. package/dist/editor/shell-page.js +16 -1
  32. package/dist/editor/shell-page.js.map +1 -1
  33. package/dist/project/context.d.ts +9 -0
  34. package/dist/project/context.js +4 -1
  35. package/dist/project/context.js.map +1 -1
  36. package/dist/scaffold/agent-targets.d.ts +126 -0
  37. package/dist/scaffold/agent-targets.js +180 -0
  38. package/dist/scaffold/agent-targets.js.map +1 -0
  39. package/dist/scaffold/agents-md.d.ts +4 -1
  40. package/dist/scaffold/agents-md.js +6 -2
  41. package/dist/scaffold/agents-md.js.map +1 -1
  42. package/dist/scaffold/project-files.d.ts +40 -5
  43. package/dist/scaffold/project-files.js +67 -25
  44. package/dist/scaffold/project-files.js.map +1 -1
  45. package/dist/scaffold/project.d.ts +42 -15
  46. package/dist/scaffold/project.js +100 -38
  47. package/dist/scaffold/project.js.map +1 -1
  48. package/dist/scaffold/reference-guidance.d.ts +1 -1
  49. package/dist/scaffold/reference-guidance.js +2 -1
  50. package/dist/scaffold/reference-guidance.js.map +1 -1
  51. package/dist/scaffold/skill-files.d.ts +32 -9
  52. package/dist/scaffold/skill-files.js +71 -15
  53. package/dist/scaffold/skill-files.js.map +1 -1
  54. package/dist/scaffold/unity-skill-files.d.ts +30 -0
  55. package/dist/scaffold/unity-skill-files.js +474 -0
  56. package/dist/scaffold/unity-skill-files.js.map +1 -0
  57. package/dist/scaffold/upgrade-project.d.ts +31 -11
  58. package/dist/scaffold/upgrade-project.js +35 -23
  59. package/dist/scaffold/upgrade-project.js.map +1 -1
  60. package/package.json +4 -4
@@ -1388,6 +1388,21 @@ ${ASSET_DETAIL_HTML}
1388
1388
  return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
1389
1389
  }
1390
1390
 
1391
+ /**
1392
+ * The head's summary: how many assets the catalog holds, and what they weigh together. Not
1393
+ * every asset carries a size — template assets often ship without one — so the total is the
1394
+ * bytes the list knows about, and it stays off entirely when it knows none.
1395
+ */
1396
+ function catalogSummary(assets) {
1397
+ var totalBytes = 0;
1398
+ for (var i = 0; i < assets.length; i++) {
1399
+ var size = assets[i].size;
1400
+ if (typeof size === 'number' && isFinite(size) && size > 0) totalBytes += size;
1401
+ }
1402
+ var total = formatSize(totalBytes);
1403
+ return total ? assets.length + ' · ' + total : String(assets.length);
1404
+ }
1405
+
1391
1406
  /**
1392
1407
  * A span of time in the panel's vocabulary: seconds under a minute, then minutes and seconds.
1393
1408
  * One formatter for a step's duration and a job's elapsed time alike, so two rows of the same
@@ -1725,7 +1740,7 @@ ${ASSET_DETAIL_HTML}
1725
1740
 
1726
1741
  lastJobs = jobs;
1727
1742
  if (loaded) pushGeneratingAssets(jobs);
1728
- assetsCount.textContent = String(sorted.length);
1743
+ assetsCount.textContent = catalogSummary(sorted);
1729
1744
  assetsEmpty.style.display = (sorted.length === 0 && jobs.length === 0) ? 'block' : 'none';
1730
1745
  }
1731
1746
 
@@ -1 +1 @@
1
- {"version":3,"file":"shell-page.js","sourceRoot":"","sources":["../../src/editor/shell-page.ts"],"names":[],"mappings":"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;;;;;;0BAQF,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA42BvC,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAktC1C,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmChB,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"shell-page.js","sourceRoot":"","sources":["../../src/editor/shell-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,EACL,qBAAqB,EAAE,kBAAkB,GAC1C,MAAM,qDAAqD,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE7F,oGAAoG;AACpG,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;;;;;;;;;;GAYG;AACH,SAAS,sBAAsB;IAC7B,OAAO;QACL,6BAA6B,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,GAAG;QACjE,iCAAiC,qBAAqB,CAAC,QAAQ,EAAE,GAAG;QACpE,8BAA8B,kBAAkB,CAAC,QAAQ,EAAE,GAAG;KAC/D,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAEnC,kGAAkG;AAClG,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,CAAC;AAmBD,oGAAoG;AACpG,MAAM,oBAAoB,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAElE,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IAC3D,MAAM,OAAO,GAAG,oBAAoB,OAAO,CAAC,QAAQ,2BAA2B,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IACpH,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC;IAC1C,MAAM,SAAS,GAAG,OAAO;QACvB,CAAC,CAAC,YAAY,OAAO,CAAC,UAAU,uDAAuD;QACvF,CAAC,CAAC,YAAY,OAAO,CAAC,UAAU,qCAAqC,CAAC;IACxE,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,QAAQ,kBAAkB,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACnF,OAAO;;;;SAIA,UAAU,CAAC,KAAK,CAAC;EACxB,kBAAkB;;EAElB,mBAAmB;EACnB,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkIrB,gBAAgB;EAChB,iBAAiB;EACjB,mBAAmB;EACnB,gBAAgB;EAChB,eAAe;;;;;;yCAMwB,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,YAAY,UAAU,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;oFAC/D,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC;2DACrD,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;kFACH,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4C/G,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;EAyBhB,kBAAkB;EAClB,oBAAoB;EACpB,iBAAiB;EACjB,iBAAiB;;;;mBAIA,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;kBACxB,gBAAgB;yBACT,qBAAqB;2BACnB,gBAAgB;;IAEvC,sBAAsB,EAAE;;;;;;;;0BAQF,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA42BvC,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiuC1C,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmChB,CAAC;AACF,CAAC"}
@@ -16,6 +16,15 @@ export interface ProjectMetadata {
16
16
  * documents for `defaultEnvironment`, and the reason this module must not import that table.
17
17
  */
18
18
  environment?: string;
19
+ /**
20
+ * Which agent tools this project is set up for. Absent on projects scaffolded before the field
21
+ * existed, which reads as the always-present set — see scaffold/agent-targets.ts.
22
+ *
23
+ * Typed `string[]` rather than `AgentId[]` for the same reason `environment` is typed `string`:
24
+ * this file is hand-editable, so a narrow type here would be a claim the parser cannot back.
25
+ * `readRecordedAgents` does the narrowing, and reports what it dropped.
26
+ */
27
+ agents?: string[];
19
28
  }
20
29
  export interface ProjectContext {
21
30
  root: string;
@@ -20,7 +20,10 @@ const REQUIRED_STRING_FIELDS = [
20
20
  * review found a bare cast let malformed data through unnoticed.
21
21
  */
22
22
  function findMissingField(value) {
23
- return REQUIRED_STRING_FIELDS.find((field) => typeof value[field] !== 'string' || value[field].length === 0);
23
+ return REQUIRED_STRING_FIELDS.find((field) => {
24
+ const entry = value[field];
25
+ return typeof entry !== 'string' || entry.length === 0;
26
+ });
24
27
  }
25
28
  /**
26
29
  * The nearest ancestor of `startDir` (itself included) holding `fileName`, or null at the root.
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/project/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Which agent tools a project is set up for, and where each one looks for its skills.
3
+ *
4
+ * The GDK is a bring-your-own-agent product, but for most of its life the scaffold wrote to
5
+ * `.claude/skills/` and nothing else — so a creator on Cursor, Codex or Kiro received a directory of
6
+ * skill files their agent never opened, and `bitmagic upgrade`, the only route by which an existing
7
+ * project learns about a new CLI capability, kept refreshing files nobody read.
8
+ *
9
+ * ── Why `.agents/skills/` is unconditional ───────────────────────────────────────────────────────
10
+ *
11
+ * Cursor, Codex, GitHub Copilot, Cline and OpenCode all load `.agents/skills/` by themselves, and
12
+ * all of them read the root `AGENTS.md` this scaffold already writes. So writing that one directory
13
+ * into every project supports five agents with no flag to pass and no environment to sniff — which
14
+ * is the whole point, because neither of the alternatives survives contact:
15
+ *
16
+ * - Detection cannot be built honestly. `../telemetry/command-context.ts` states the policy —
17
+ * an agent gets a marker here only once that marker is verified against the real thing, because
18
+ * a guessed variable never fires and misleads whoever reads the table next — and `CLAUDECODE` is
19
+ * the only marker anyone has verified. An `init` run by Cursor's agent proves nothing, so
20
+ * detection-as-default would silently produce a Cursor-less project.
21
+ * - A required flag cannot be relied on either. The GDK bootstrap that runs `bitmagic init` is
22
+ * read BY the agent, so it could pass its own id — but nothing upgrades an installed copy of
23
+ * that bootstrap (see `agent-plugin/README.md`), so a creator on last month's copy would get
24
+ * nothing, and the failure is silent.
25
+ *
26
+ * What is left for this table is therefore narrow: agents that read a VENDOR directory and nothing
27
+ * else. Claude Code (`.claude/skills/`) is one, and it is unconditional too — every project on disk
28
+ * today has that directory, and an upgrade that stopped writing it would be the first destructive
29
+ * thing the command has ever done. Kiro (`.kiro/skills/`) is the other, and it is the only reason
30
+ * `--agent` exists: an unasked-for `.kiro/` is pure noise in a project that does not use Kiro.
31
+ *
32
+ * ── Why the directory, not the agent, is the unit ────────────────────────────────────────────────
33
+ *
34
+ * Four agents map onto three directories, so every caller works in terms of the deduped set of
35
+ * DIRECTORIES (`skillDirsFor`). Writing per agent instead would put the same files into
36
+ * `.agents/skills/` twice for a creator who named both Cursor and Codex.
37
+ */
38
+ export type AgentId = 'claude-code' | 'cursor' | 'codex' | 'kiro';
39
+ export interface AgentTarget {
40
+ id: AgentId;
41
+ /** How the agent is named in output a creator reads. */
42
+ label: string;
43
+ /**
44
+ * The agent's own skills directory, or absent when it reads `SHARED_SKILLS_DIR` itself — in which
45
+ * case there is nothing to write for it and `--agent <id>` is a no-op we report rather than
46
+ * refuse. Relative to the project root, POSIX-separated.
47
+ */
48
+ skillsDir?: string;
49
+ /** Where this agent reads its startup instructions. Output copy only; nothing branches on it. */
50
+ instructions: string;
51
+ }
52
+ /**
53
+ * The directory every agent following the AGENTS.md / agent-skills convention reads by itself.
54
+ * Written into every project whatever agent scaffolded it — see the file header.
55
+ */
56
+ export declare const SHARED_SKILLS_DIR = ".agents/skills";
57
+ /**
58
+ * Declaration order is output order, so the file set a project receives is a function of WHICH
59
+ * agents were selected and not of how they were typed.
60
+ */
61
+ export declare const AGENT_TARGETS: readonly AgentTarget[];
62
+ export declare const AGENT_IDS: readonly AgentId[];
63
+ /**
64
+ * In every project's set, and not removable.
65
+ *
66
+ * `--agent` adds; it never takes away. Both of the unconditional directories are already on disk in
67
+ * every existing project (`.claude/skills/`) or are what makes five agents work for free
68
+ * (`.agents/skills/`), and `upgrade` has never deleted a file under a skills directory.
69
+ */
70
+ export declare const ALWAYS_AGENTS: readonly AgentId[];
71
+ /**
72
+ * `--agent`'s help text, shared by `init` and `upgrade` so the two cannot describe the same flag
73
+ * differently. It names what the flag is FOR, because the honest answer is "usually nothing": the
74
+ * default already covers every agent but Kiro.
75
+ */
76
+ export declare const AGENT_FLAG_DESCRIPTION: string;
77
+ export declare function isAgentId(value: unknown): value is AgentId;
78
+ export declare function agentTarget(id: AgentId): AgentTarget;
79
+ /** In table order, each agent once. */
80
+ export declare function dedupeAgents(agents: readonly AgentId[]): AgentId[];
81
+ /**
82
+ * "Cursor", "Cursor and Codex", "Cursor, Codex and Kiro" — for a sentence a creator reads, not a
83
+ * list a parser does. Exported because the scaffolded AGENTS.md joins its skills directories the
84
+ * same way, and two hand-written copies of this join is how the two come to punctuate differently.
85
+ */
86
+ export declare function joinWithAnd(items: readonly string[]): string;
87
+ /** The agents named, in table order, as a clause for a sentence a creator reads. */
88
+ export declare function agentLabels(agents: readonly AgentId[]): string;
89
+ /**
90
+ * `--agent kiro,cursor` → `['cursor', 'kiro']`, unioned with the always-present set.
91
+ *
92
+ * Comma-separated rather than a repeatable flag because citty's string args are single-valued. An
93
+ * unknown id is a hard error naming the valid ones: a typo that silently scaffolded the default set
94
+ * would look like the flag working, and the creator would find out when their agent loaded nothing.
95
+ */
96
+ export declare function parseAgentFlag(raw: string | undefined): AgentId[];
97
+ /** The `agents` field of a `bitmagic.json`, keeping only ids this CLI recognises. */
98
+ export declare function readRecordedAgents(value: unknown): AgentId[];
99
+ /** Values in a project's `agents` field that this CLI does not recognise — reported, never fatal. */
100
+ export declare function unrecognisedAgents(value: unknown): string[];
101
+ /**
102
+ * The directories to write, deduped and in a stable order, always starting with the shared one.
103
+ *
104
+ * A duplicate here would double-write a file and list its path twice in `UpgradeResult.replaced`,
105
+ * so the dedupe is load-bearing rather than tidiness: `--agent cursor,codex` names two agents that
106
+ * share a directory.
107
+ */
108
+ export declare function skillDirsFor(agents: readonly AgentId[]): string[];
109
+ /**
110
+ * The directory `AGENTS.md` names when it cross-references a skill.
111
+ *
112
+ * Every project has more than one copy of the shipped skills, but `AGENTS.md` is ONE file at the
113
+ * root read by every agent in the project, so it has to name a single path — and the only honest
114
+ * choice is the one that exists in every project and that most agents load from. Its Layout section
115
+ * names the other copies, so a Claude Code reader still learns where its own loader looks.
116
+ */
117
+ export declare const PRIMARY_SKILLS_DIR = ".agents/skills";
118
+ /**
119
+ * The agents named by `--agent` that this scaffold writes nothing extra for, because the directory
120
+ * and the instructions file they read are already unconditional.
121
+ *
122
+ * Accepting such a flag and explaining it beats refusing one a creator reasonably typed.
123
+ */
124
+ export declare function noOpAgents(agents: readonly AgentId[]): AgentId[];
125
+ /** Which agents load a given skills directory, as a clause for a sentence the creator reads. */
126
+ export declare function describeSkillsDir(dir: string): string;
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Which agent tools a project is set up for, and where each one looks for its skills.
3
+ *
4
+ * The GDK is a bring-your-own-agent product, but for most of its life the scaffold wrote to
5
+ * `.claude/skills/` and nothing else — so a creator on Cursor, Codex or Kiro received a directory of
6
+ * skill files their agent never opened, and `bitmagic upgrade`, the only route by which an existing
7
+ * project learns about a new CLI capability, kept refreshing files nobody read.
8
+ *
9
+ * ── Why `.agents/skills/` is unconditional ───────────────────────────────────────────────────────
10
+ *
11
+ * Cursor, Codex, GitHub Copilot, Cline and OpenCode all load `.agents/skills/` by themselves, and
12
+ * all of them read the root `AGENTS.md` this scaffold already writes. So writing that one directory
13
+ * into every project supports five agents with no flag to pass and no environment to sniff — which
14
+ * is the whole point, because neither of the alternatives survives contact:
15
+ *
16
+ * - Detection cannot be built honestly. `../telemetry/command-context.ts` states the policy —
17
+ * an agent gets a marker here only once that marker is verified against the real thing, because
18
+ * a guessed variable never fires and misleads whoever reads the table next — and `CLAUDECODE` is
19
+ * the only marker anyone has verified. An `init` run by Cursor's agent proves nothing, so
20
+ * detection-as-default would silently produce a Cursor-less project.
21
+ * - A required flag cannot be relied on either. The GDK bootstrap that runs `bitmagic init` is
22
+ * read BY the agent, so it could pass its own id — but nothing upgrades an installed copy of
23
+ * that bootstrap (see `agent-plugin/README.md`), so a creator on last month's copy would get
24
+ * nothing, and the failure is silent.
25
+ *
26
+ * What is left for this table is therefore narrow: agents that read a VENDOR directory and nothing
27
+ * else. Claude Code (`.claude/skills/`) is one, and it is unconditional too — every project on disk
28
+ * today has that directory, and an upgrade that stopped writing it would be the first destructive
29
+ * thing the command has ever done. Kiro (`.kiro/skills/`) is the other, and it is the only reason
30
+ * `--agent` exists: an unasked-for `.kiro/` is pure noise in a project that does not use Kiro.
31
+ *
32
+ * ── Why the directory, not the agent, is the unit ────────────────────────────────────────────────
33
+ *
34
+ * Four agents map onto three directories, so every caller works in terms of the deduped set of
35
+ * DIRECTORIES (`skillDirsFor`). Writing per agent instead would put the same files into
36
+ * `.agents/skills/` twice for a creator who named both Cursor and Codex.
37
+ */
38
+ import { CliError } from '../errors.js';
39
+ /**
40
+ * The directory every agent following the AGENTS.md / agent-skills convention reads by itself.
41
+ * Written into every project whatever agent scaffolded it — see the file header.
42
+ */
43
+ export const SHARED_SKILLS_DIR = '.agents/skills';
44
+ /**
45
+ * Declaration order is output order, so the file set a project receives is a function of WHICH
46
+ * agents were selected and not of how they were typed.
47
+ */
48
+ export const AGENT_TARGETS = [
49
+ {
50
+ id: 'claude-code',
51
+ label: 'Claude Code',
52
+ // Claude Code does NOT read `.agents/skills/`; `.claude/skills/` is its only project path.
53
+ skillsDir: '.claude/skills',
54
+ instructions: 'CLAUDE.md, which imports AGENTS.md',
55
+ },
56
+ { id: 'cursor', label: 'Cursor', instructions: 'AGENTS.md' },
57
+ { id: 'codex', label: 'Codex', instructions: 'AGENTS.md' },
58
+ { id: 'kiro', label: 'Kiro', skillsDir: '.kiro/skills', instructions: '.kiro/steering/*.md' },
59
+ ];
60
+ export const AGENT_IDS = AGENT_TARGETS.map((target) => target.id);
61
+ /**
62
+ * In every project's set, and not removable.
63
+ *
64
+ * `--agent` adds; it never takes away. Both of the unconditional directories are already on disk in
65
+ * every existing project (`.claude/skills/`) or are what makes five agents work for free
66
+ * (`.agents/skills/`), and `upgrade` has never deleted a file under a skills directory.
67
+ */
68
+ export const ALWAYS_AGENTS = ['claude-code'];
69
+ /**
70
+ * `--agent`'s help text, shared by `init` and `upgrade` so the two cannot describe the same flag
71
+ * differently. It names what the flag is FOR, because the honest answer is "usually nothing": the
72
+ * default already covers every agent but Kiro.
73
+ */
74
+ export const AGENT_FLAG_DESCRIPTION = `Agent tools to write skills for, comma-separated (${AGENT_IDS.join(', ')}). ` +
75
+ `Adds to what a project already has; never removes. Only needed for kiro — ` +
76
+ `${SHARED_SKILLS_DIR}/ and .claude/skills/ are always written, which covers the rest.`;
77
+ export function isAgentId(value) {
78
+ return typeof value === 'string' && AGENT_IDS.includes(value);
79
+ }
80
+ export function agentTarget(id) {
81
+ // Non-null by construction: AgentId is derived from this same table.
82
+ return AGENT_TARGETS.find((target) => target.id === id);
83
+ }
84
+ /** In table order, each agent once. */
85
+ export function dedupeAgents(agents) {
86
+ return AGENT_IDS.filter((id) => agents.includes(id));
87
+ }
88
+ /**
89
+ * "Cursor", "Cursor and Codex", "Cursor, Codex and Kiro" — for a sentence a creator reads, not a
90
+ * list a parser does. Exported because the scaffolded AGENTS.md joins its skills directories the
91
+ * same way, and two hand-written copies of this join is how the two come to punctuate differently.
92
+ */
93
+ export function joinWithAnd(items) {
94
+ if (items.length <= 1)
95
+ return items[0] ?? '';
96
+ return `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`;
97
+ }
98
+ /** The agents named, in table order, as a clause for a sentence a creator reads. */
99
+ export function agentLabels(agents) {
100
+ return joinWithAnd(dedupeAgents(agents).map((id) => agentTarget(id).label));
101
+ }
102
+ /**
103
+ * `--agent kiro,cursor` → `['cursor', 'kiro']`, unioned with the always-present set.
104
+ *
105
+ * Comma-separated rather than a repeatable flag because citty's string args are single-valued. An
106
+ * unknown id is a hard error naming the valid ones: a typo that silently scaffolded the default set
107
+ * would look like the flag working, and the creator would find out when their agent loaded nothing.
108
+ */
109
+ export function parseAgentFlag(raw) {
110
+ if (raw === undefined)
111
+ return dedupeAgents(ALWAYS_AGENTS);
112
+ const requested = raw
113
+ .split(',')
114
+ .map((part) => part.trim().toLowerCase())
115
+ .filter((part) => part !== '');
116
+ if (requested.length === 0) {
117
+ throw new CliError(`--agent needs at least one agent. Valid values: ${AGENT_IDS.join(', ')}.`);
118
+ }
119
+ const unknown = requested.filter((part) => !isAgentId(part));
120
+ if (unknown.length > 0) {
121
+ throw new CliError(`Unknown agent${unknown.length > 1 ? 's' : ''} ${unknown.map((u) => `"${u}"`).join(', ')}. ` +
122
+ `Valid values: ${AGENT_IDS.join(', ')}.`);
123
+ }
124
+ return dedupeAgents([...ALWAYS_AGENTS, ...requested]);
125
+ }
126
+ /** The `agents` field of a `bitmagic.json`, keeping only ids this CLI recognises. */
127
+ export function readRecordedAgents(value) {
128
+ if (!Array.isArray(value))
129
+ return [];
130
+ return dedupeAgents(value.filter(isAgentId));
131
+ }
132
+ /** Values in a project's `agents` field that this CLI does not recognise — reported, never fatal. */
133
+ export function unrecognisedAgents(value) {
134
+ if (!Array.isArray(value))
135
+ return [];
136
+ return value.filter((entry) => typeof entry === 'string' && !isAgentId(entry));
137
+ }
138
+ /**
139
+ * The directories to write, deduped and in a stable order, always starting with the shared one.
140
+ *
141
+ * A duplicate here would double-write a file and list its path twice in `UpgradeResult.replaced`,
142
+ * so the dedupe is load-bearing rather than tidiness: `--agent cursor,codex` names two agents that
143
+ * share a directory.
144
+ */
145
+ export function skillDirsFor(agents) {
146
+ const dirs = [SHARED_SKILLS_DIR];
147
+ for (const id of dedupeAgents([...ALWAYS_AGENTS, ...agents])) {
148
+ const dir = agentTarget(id).skillsDir;
149
+ if (dir !== undefined && !dirs.includes(dir))
150
+ dirs.push(dir);
151
+ }
152
+ return dirs;
153
+ }
154
+ /**
155
+ * The directory `AGENTS.md` names when it cross-references a skill.
156
+ *
157
+ * Every project has more than one copy of the shipped skills, but `AGENTS.md` is ONE file at the
158
+ * root read by every agent in the project, so it has to name a single path — and the only honest
159
+ * choice is the one that exists in every project and that most agents load from. Its Layout section
160
+ * names the other copies, so a Claude Code reader still learns where its own loader looks.
161
+ */
162
+ export const PRIMARY_SKILLS_DIR = SHARED_SKILLS_DIR;
163
+ /**
164
+ * The agents named by `--agent` that this scaffold writes nothing extra for, because the directory
165
+ * and the instructions file they read are already unconditional.
166
+ *
167
+ * Accepting such a flag and explaining it beats refusing one a creator reasonably typed.
168
+ */
169
+ export function noOpAgents(agents) {
170
+ return dedupeAgents(agents).filter((id) => agentTarget(id).skillsDir === undefined);
171
+ }
172
+ /** Which agents load a given skills directory, as a clause for a sentence the creator reads. */
173
+ export function describeSkillsDir(dir) {
174
+ if (dir === SHARED_SKILLS_DIR) {
175
+ return 'read by Cursor, Codex and every agent that follows the AGENTS.md convention';
176
+ }
177
+ const owner = AGENT_TARGETS.find((target) => target.skillsDir === dir);
178
+ return owner === undefined ? 'read by your agent' : `where ${owner.label} looks`;
179
+ }
180
+ //# sourceMappingURL=agent-targets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-targets.js","sourceRoot":"","sources":["../../src/scaffold/agent-targets.ts"],"names":[],"mappings":"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"}
@@ -48,5 +48,8 @@ export interface AgentsMdOutcome {
48
48
  *
49
49
  * `storedHash` is `bitmagic.json`'s `agentsMdHash` — absent for any project scaffolded before this
50
50
  * existed, which is exactly the population that most needs the suggestion path.
51
+ *
52
+ * `skillDirs` is passed for the same reason `environment` is: the template names the skills
53
+ * directories the project actually holds, so a Kiro project's copy differs from a default one's.
51
54
  */
52
- export declare function reconcileAgentsMd(root: string, storedHash: string | undefined, environment: EnvironmentName | undefined): AgentsMdOutcome;
55
+ export declare function reconcileAgentsMd(root: string, storedHash: string | undefined, environment: EnvironmentName | undefined, skillDirs?: readonly string[]): AgentsMdOutcome;
@@ -29,6 +29,7 @@ import { createHash } from 'crypto';
29
29
  import * as fs from 'fs';
30
30
  import * as path from 'path';
31
31
  import { renderAgentsMd } from './project-files.js';
32
+ import { ALWAYS_AGENTS, skillDirsFor } from './agent-targets.js';
32
33
  export const AGENTS_MD_FILE = 'AGENTS.md';
33
34
  /**
34
35
  * Where the current template is written when the creator's own file is kept. Under `.bitmagic/`
@@ -70,10 +71,13 @@ export function missingSections(theirs, ours) {
70
71
  *
71
72
  * `storedHash` is `bitmagic.json`'s `agentsMdHash` — absent for any project scaffolded before this
72
73
  * existed, which is exactly the population that most needs the suggestion path.
74
+ *
75
+ * `skillDirs` is passed for the same reason `environment` is: the template names the skills
76
+ * directories the project actually holds, so a Kiro project's copy differs from a default one's.
73
77
  */
74
- export function reconcileAgentsMd(root, storedHash, environment) {
78
+ export function reconcileAgentsMd(root, storedHash, environment, skillDirs = skillDirsFor(ALWAYS_AGENTS)) {
75
79
  const target = path.join(root, AGENTS_MD_FILE);
76
- const current = renderAgentsMd(environment);
80
+ const current = renderAgentsMd(environment, skillDirs);
77
81
  const currentHash = hashAgentsMd(current);
78
82
  let existing;
79
83
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../../src/scaffold/agents-md.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../../src/scaffold/agents-md.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type AgentId } from './agent-targets.js';
1
2
  import type { EnvironmentName } from '../config/environments.js';
2
3
  /**
3
4
  * The legal notice stamped into every game this project publishes.
@@ -93,11 +94,35 @@ export declare function renderVitePublishConfig(): string;
93
94
  */
94
95
  export declare function renderVitePublishStandaloneConfig(): string;
95
96
  export declare function renderGitignore(): string;
97
+ /**
98
+ * What a shipped skill's renderer is handed.
99
+ *
100
+ * Only `renderSkillsReadme` reads it today — every other body is agent-independent, and
101
+ * assigning a `() => string` to this type is legal TypeScript, so they need no parameter at all.
102
+ * The type exists so a renderer that DOES need to name its own directory can, without the
103
+ * `SHIPPED_SKILLS` table growing two shapes.
104
+ */
105
+ export interface SkillRenderContext {
106
+ /** The directory this copy is being written into, relative to the project root. */
107
+ skillsDir: string;
108
+ /** Every skills directory this project holds, so a renderer can name the sibling copies. */
109
+ skillDirs: readonly string[];
110
+ }
111
+ export type SkillRenderer = (context: SkillRenderContext) => string;
96
112
  export interface ProjectMetadata {
97
113
  gameId: string;
98
114
  engineVersion: string;
99
115
  genre: string;
100
116
  template: string;
117
+ /**
118
+ * Which agent tools this project is set up for, deciding which skills directories `init` writes
119
+ * and `upgrade` refreshes. See `agent-targets.ts`: the entry that matters is Kiro, since the
120
+ * shared and Claude Code directories are written unconditionally.
121
+ *
122
+ * Optional: every project scaffolded before this existed has none, which reads as the
123
+ * always-present set — exactly what those projects have on disk.
124
+ */
125
+ agents?: AgentId[];
101
126
  /**
102
127
  * sha256 of the AGENTS.md the CLI last wrote, so `bitmagic upgrade` can tell an untouched file
103
128
  * (safe to refresh) from one the creator edited (never overwritten — see scaffold/agents-md.ts).
@@ -120,9 +145,19 @@ export interface ProjectMetadata {
120
145
  environment?: EnvironmentName;
121
146
  }
122
147
  export declare function renderBitmagicJson(metadata: ProjectMetadata): string;
123
- export declare function renderAgentsMd(environment: EnvironmentName | undefined): string;
124
148
  /**
125
- * `.claude/skills/planning-a-game/SKILL.md` — the slice contract and the mechanic-recipe routing.
149
+ * `skillDirs` is every skills directory this project holds, in `skillDirsFor` order. It is a
150
+ * parameter for the same reason `environment` is (see `agents-md.ts`): this file has to describe
151
+ * the project it is written into, and a Kiro project holds a directory a default one does not.
152
+ *
153
+ * Cross-references name `PRIMARY_SKILLS_DIR` rather than the reader's own directory, because this
154
+ * is ONE file read by every agent in the project and it has to pick a path that exists in all of
155
+ * them. The Layout section names the rest, so a Claude Code reader still learns where its own
156
+ * loader looks.
157
+ */
158
+ export declare function renderAgentsMd(environment: EnvironmentName | undefined, skillDirs?: readonly string[]): string;
159
+ /**
160
+ * `<skills dir>/planning-a-game/SKILL.md` — the slice contract and the mechanic-recipe routing.
126
161
  *
127
162
  * These are one skill rather than two on purpose: you route to a recipe *in order to* scope slice
128
163
  * 1, and slice 1 is the first section of the plan file the recipe tells you to write. Split, the
@@ -138,7 +173,7 @@ export declare function renderAgentsMd(environment: EnvironmentName | undefined)
138
173
  */
139
174
  export declare function renderPlanningSkill(): string;
140
175
  /**
141
- * `.claude/skills/finding-engine-apis/SKILL.md` — the discovery protocol in full.
176
+ * `<skills dir>/finding-engine-apis/SKILL.md` — the discovery protocol in full.
142
177
  *
143
178
  * The problem this exists to solve is measured, not hypothetical. game-play-agent's
144
179
  * engine-api-digest.ts opens with it: session analysis showed the hosted coding agent spending most
@@ -150,7 +185,7 @@ export declare function renderPlanningSkill(): string;
150
185
  export declare function renderEngineApiSkill(): string;
151
186
  export declare function renderGenerateSkill(): string;
152
187
  /**
153
- * `.claude/skills/checking-usage/SKILL.md` — what the creator's sparks bought.
188
+ * `<skills dir>/checking-usage/SKILL.md` — what the creator's sparks bought.
154
189
  *
155
190
  * Exists because the agent is what spends the money and the human is what pays
156
191
  * for it. Before this, the only way to learn a balance was to be REFUSED one:
@@ -159,7 +194,7 @@ export declare function renderGenerateSkill(): string;
159
194
  */
160
195
  export declare function renderUsageSkill(): string;
161
196
  /**
162
- * `.claude/skills/judging-quality/SKILL.md` — when and how to run `bitmagic judge`.
197
+ * `<skills dir>/judging-quality/SKILL.md` — when and how to run `bitmagic judge`.
163
198
  *
164
199
  * The point the skill has to land is the discipline, not the mechanics: judge after milestones,
165
200
  * fix the findings, confirm once, stop. An agent that loops on the judge is spending the