@adobe/data-ai 0.9.83 → 0.9.86

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/.claude/rules/README.md +42 -0
  2. package/.claude/rules/archetypes.md +60 -0
  3. package/.claude/rules/cohesion.md +66 -0
  4. package/.claude/rules/data-modelling.md +71 -0
  5. package/.claude/rules/element.md +130 -0
  6. package/.claude/rules/features/data/index.md +35 -0
  7. package/.claude/rules/features/data/state.md +56 -0
  8. package/.claude/rules/features/ecs/actions.md +32 -0
  9. package/.claude/rules/features/ecs/archetypes.md +46 -0
  10. package/.claude/rules/features/ecs/components.md +41 -0
  11. package/.claude/rules/features/ecs/computed.md +26 -0
  12. package/.claude/rules/features/ecs/conformance.md +71 -0
  13. package/.claude/rules/features/ecs/index.md +179 -0
  14. package/.claude/rules/features/ecs/indexes.md +63 -0
  15. package/.claude/rules/features/ecs/resources.md +28 -0
  16. package/.claude/rules/features/ecs/services.md +24 -0
  17. package/.claude/rules/features/ecs/systems.md +132 -0
  18. package/.claude/rules/features/ecs/transactions.md +45 -0
  19. package/.claude/rules/features/index.md +95 -0
  20. package/.claude/rules/features/services/index.md +34 -0
  21. package/.claude/rules/features/ui/index.md +31 -0
  22. package/.claude/rules/function-references.md +35 -0
  23. package/.claude/rules/lazy-element.md +127 -0
  24. package/.claude/rules/namespace.md +179 -0
  25. package/.claude/rules/plugin-modelling.md +170 -0
  26. package/.claude/rules/presentation.md +83 -0
  27. package/.claude/rules/type-casts.md +94 -0
  28. package/.claude-plugin/plugin.json +1 -1
  29. package/README.md +54 -76
  30. package/bin/cli.mjs +81 -26
  31. package/package.json +9 -2
  32. package/skills/build-actions/SKILL.md +16 -0
  33. package/skills/build-app-entry/SKILL.md +15 -0
  34. package/skills/build-application/SKILL.md +12 -0
  35. package/skills/build-computed/SKILL.md +16 -0
  36. package/skills/build-core-database/SKILL.md +24 -0
  37. package/skills/build-data/SKILL.md +22 -0
  38. package/skills/build-feature/SKILL.md +18 -0
  39. package/skills/build-game/SKILL.md +21 -0
  40. package/skills/build-indexes/SKILL.md +16 -0
  41. package/skills/build-service-database/SKILL.md +16 -0
  42. package/skills/build-services/SKILL.md +16 -0
  43. package/skills/build-systems/SKILL.md +24 -0
  44. package/skills/build-transactions/SKILL.md +15 -0
  45. package/skills/build-ui/SKILL.md +13 -0
  46. package/skills/graph-execute/SKILL.md +13 -0
  47. package/skills/meta-build/SKILL.md +43 -0
  48. package/skills/review/SKILL.md +25 -0
  49. package/skills/structure/SKILL.md +7 -0
  50. package/skills/x-alpha/SKILL.md +7 -0
  51. package/skills/x-beta/SKILL.md +7 -0
  52. package/skills/x-double/SKILL.md +7 -0
  53. package/skills/x-execute/SKILL.md +16 -0
  54. package/skills/x-log/SKILL.md +12 -0
  55. package/skills/x-pow/SKILL.md +9 -0
  56. package/skills/x-subagent/SKILL.md +8 -0
  57. package/skills/x-trace/SKILL.md +11 -0
  58. package/skills/x-validate/SKILL.md +67 -0
  59. package/skills/bar/SKILL.md +0 -8
  60. package/skills/foo/SKILL.md +0 -8
@@ -0,0 +1,94 @@
1
+ ---
2
+ paths:
3
+ - 'packages/**/*.ts'
4
+ - 'packages/**/*.tsx'
5
+ ---
6
+
7
+ # Type casts — only two valid uses
8
+
9
+ `as` is dangerous. It silently turns off the type checker for the cast
10
+ expression. Every cast is a place a future refactor can break in
11
+ silence. There are exactly two valid uses:
12
+
13
+ 1. **Proving a type the compiler cannot see.** A runtime invariant you
14
+ have established but TypeScript has no way to verify — e.g.
15
+ "validated JSON matches `User.schema`", "this `unknown` from a loose
16
+ API is `number` because the schema declared it", "this DOM node is
17
+ `HTMLInputElement` because the selector matched `input`".
18
+
19
+ 2. **Widening a literal or default to a useful container type.** A
20
+ resource or component default is `0` (the literal) without help.
21
+ `0 as F32` widens it to `F32` so the resource can hold any number,
22
+ not just zero. Same for `[] as User[]`, `false as boolean`,
23
+ `{} as State`. Without the cast, the inferred type is so narrow it
24
+ blocks every later assignment.
25
+
26
+ Anything else is the cast hiding a real defect. Most often: an identity
27
+ cast that neither narrows nor widens, used to make a type error go
28
+ away without fixing the underlying type.
29
+
30
+ ## The acceptance test
31
+
32
+ Before every `as`, articulate in one sentence which of the two it is:
33
+
34
+ - **Case 1:** "I know `<expr>` is `<T>` because <runtime invariant>."
35
+ - **Case 2:** "I'm widening `<literal>` so the container can hold any `<T>`."
36
+
37
+ If your sentence reduces to "TypeScript is wrong" or "I just want this
38
+ to compile", the cast is hiding a real defect — fix the type at its
39
+ source, do not cast at the consumer.
40
+
41
+ ## Common violations
42
+
43
+ ### Identity casts (neither widening nor narrowing)
44
+
45
+ ```ts
46
+ // ❌ `cameraAngle + delta` is already F32 (= number). Cast does nothing.
47
+ t.resources.cameraAngle = (t.resources.cameraAngle + delta) as F32;
48
+
49
+ // ✅
50
+ t.resources.cameraAngle = t.resources.cameraAngle + delta;
51
+ ```
52
+
53
+ ### Casting `any` to a specific shape just to call a property
54
+
55
+ ```ts
56
+ // ❌ `prev` is already any; the cast adds no information.
57
+ const n = (prev as ArrayLike<number>).length;
58
+
59
+ // ✅
60
+ const n = prev.length;
61
+ ```
62
+
63
+ ### Casting wider than necessary
64
+
65
+ ```ts
66
+ // ❌ Loses the value-side type for no reason.
67
+ const map = t.componentSchemas as Record<string, any>;
68
+
69
+ // ✅ Same key widening, but values stay typed as Schema.
70
+ const map = t.componentSchemas as Record<string, Schema>;
71
+ ```
72
+
73
+ ### Casting to silence an error you should fix at the source
74
+
75
+ ```ts
76
+ // declaration (your code)
77
+ export const emit = (name: string, payload: unknown): void => {
78
+ return inner.send(name, payload); // actually returns Promise<Ack>
79
+ };
80
+
81
+ // ❌ cast hides the lie; every caller will duplicate it
82
+ const ack = await (emit("save", data) as Promise<Ack>);
83
+
84
+ // ✅ fix the declaration once; every consumer benefits
85
+ export const emit = (name: string, payload: unknown): Promise<Ack> => {
86
+ return inner.send(name, payload);
87
+ };
88
+ ```
89
+
90
+ ## When the lying type is in code you control
91
+
92
+ Fix the declaration. A consumer-side cast is a leaky patch every other
93
+ caller will duplicate; one declaration change removes the cast
94
+ everywhere and protects future call sites the compiler will now catch.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adobe-data-ai",
3
- "version": "0.9.75",
3
+ "version": "0.9.86",
4
4
  "description": "Architecture skills for @adobe/data — data-oriented modelling, archetype iteration, hot-path performance, and related conventions.",
5
5
  "author": {
6
6
  "name": "Adobe"
package/README.md CHANGED
@@ -1,102 +1,80 @@
1
1
  # @adobe/data-ai
2
2
 
3
- Cross-agent architecture skills for [`@adobe/data`](https://www.npmjs.com/package/@adobe/data). One skill bundle, authored once, distributed two ways.
3
+ AI architecture skills + rules for building applications with
4
+ [`@adobe/data`](https://www.npmjs.com/package/@adobe/data) — a layered,
5
+ spec-first feature structure (`data → ecs → ui`) kept honest by conformance
6
+ tests. Versioned in lockstep with the library: `@adobe/data-ai@x.y.z` targets
7
+ `@adobe/data@x.y.z`.
4
8
 
5
- Skills version in lockstep with the library: `@adobe/data-ai@x.y.z` describes `@adobe/data@x.y.z`.
9
+ It installs two things:
6
10
 
7
- There are two distribution paths, one per agent family — they do **not** overlap:
11
+ - **skills** — `build-*` commands that scaffold features and applications.
12
+ - **rules** — the path-scoped conventions those skills follow while building.
8
13
 
9
- - **Claude Code → marketplace plugin** (see below). The installer never writes into `.claude/skills/`, so it can't collide with your own Claude skills.
10
- - **Cursor / Codex / other `.agents`-standard agents → `npx … install`** (below).
14
+ > **For the installing agent:** find the block below that matches your host
15
+ > (Claude Code or Cursor/other), run its commands, and stop. Each install owns a
16
+ > namespaced folder and is a clean wipe-and-recopy, so re-running is also how you
17
+ > **update** — it never touches files you authored.
11
18
 
12
- ## Install (Cursor, Codex, `.agents` agents)
19
+ ## Install — Claude Code
13
20
 
14
- The installer copies the skill folders into a single namespaced bundle directory that agents which recurse `.agents/skills/` discover:
21
+ Skills load as a marketplace plugin; rules install into the project. Run these
22
+ three from a shell (agent-runnable):
15
23
 
16
- ```sh
24
+ ```
25
+ claude plugin marketplace add adobe/data --scope project
26
+ claude plugin install adobe-data-ai@adobe-data-skills --scope project
17
27
  npx @adobe/data-ai@latest install
18
28
  ```
19
29
 
20
- This writes `.agents/skills/adobe-data-ai/<name>/SKILL.md` for each skill. The whole `adobe-data-ai/` directory belongs to this package, so a re-run is a clean wipe-and-recopy that never touches skills you authored elsewhere. Commit the result to share it with your team.
21
-
22
- Options:
30
+ In an interactive Claude session you can instead use the slash-command form of
31
+ the first two — `/plugin marketplace add adobe/data` then
32
+ `/plugin install adobe-data-ai@adobe-data-skills` — but an agent driving a shell
33
+ should use the `claude plugin …` commands above (slash commands aren't
34
+ shell-runnable).
23
35
 
24
- ```sh
25
- npx @adobe/data-ai@latest install --global # into ~/.agents/skills/adobe-data-ai/
26
- npx @adobe/data-ai@latest install --dir=./sub # into a specific base dir
27
- npx @adobe/data-ai@latest list # show bundled skills
28
- ```
36
+ - Skills → the `adobe-data-ai` plugin. **Update:** `claude plugin update adobe-data-ai`.
37
+ - Rules → `.claude/rules/adobe-data-ai/`. **Update:** re-run `npx @adobe/data-ai@latest install`.
29
38
 
30
- ## Install (Claude Code plugin)
39
+ ## Install — Cursor (and Codex / other `.agents` agents)
31
40
 
32
- Claude Code does not scan `.agents/`; it consumes the skills as a native plugin from the `adobe/data` marketplace — no npm needed.
41
+ One command installs both:
33
42
 
34
- Interactive:
35
-
36
- ```
37
- /plugin marketplace add adobe/data
38
- /plugin install adobe-data-ai@adobe-data-skills
39
43
  ```
40
-
41
- Or declaratively, so collaborators are prompted to auto-install on next launch — commit to your repo's `.claude/settings.json`:
42
-
43
- ```json
44
- {
45
- "extraKnownMarketplaces": {
46
- "adobe-data-skills": {
47
- "source": { "source": "github", "repo": "adobe/data" }
48
- }
49
- },
50
- "enabledPlugins": {
51
- "adobe-data-ai@adobe-data-skills": true
52
- }
53
- }
44
+ npx @adobe/data-ai@latest install
54
45
  ```
55
46
 
56
- The plugin cache is version-hashed and garbage-collected, so it is not a stable path to symlink against — prefer the `npx … install` copy model when you need a durable, cross-agent artifact.
57
-
58
- ---
59
-
60
- # Pragmatic Programming
47
+ - Skills → `.agents/skills/adobe-data-ai/`.
48
+ - Rules → `.claude/rules/adobe-data-ai/`.
49
+ - **Update:** re-run the same command.
61
50
 
62
- ## Target Audience
51
+ ## Use
63
52
 
64
- Software engineers who want to build high quality applications with a sustainable velocity.
53
+ Ask your agent to run a build command — skills are available by name:
65
54
 
66
- ## Goals
55
+ - **`build-application`** — build a whole app: a base feature that hosts
56
+ lazily-loaded peer features.
57
+ - **`build-feature`** — build one feature end to end. Pipes the per-layer skills
58
+ (`data → core-database → transactions → … → ui`), then conformance-tests the
59
+ result against its pure `data/` spec.
67
60
 
68
- The goal of effective software engineers is to generate a high rate of value per unit time.
61
+ Both compose finer-grained skills that are installed alongside and discoverable
62
+ by name when you want a single phase or a specialized flow: `build-data`,
63
+ `build-core-database`, `build-indexes`, `build-transactions`, `build-computed`,
64
+ `build-services`, `build-service-database`, `build-actions`, `build-systems`,
65
+ `build-ui`, `build-app-entry`; plus `build-game`, `meta-build` (phase-by-phase
66
+ in subagents), `review` (audit output against the rules), and `structure`
67
+ (reason about layout).
69
68
 
70
- rate = value / time
69
+ ## One-liner: install + build an app
71
70
 
72
- We can improve the rate by either increasing value or decreasing time.
71
+ Paste one of these into a shell, replacing the quoted text with your own app
72
+ description. It installs the bundle, then runs `build-application` headlessly on
73
+ your prompt.
73
74
 
74
- - Quality: Write better applications. ▲value
75
- - Velocity: Write applications faster. ▼time
75
+ This presumes you are already running the agent within the directory you want to use as your project root.
76
76
 
77
- ### Code Priorities
78
-
79
- 1. Correct: Does the job. This one is non-negotiable.
80
- 2. Clear: Easily understood by both humans and AI.
81
- 3. Changeable: Quickly and safely modified or extended.
82
-
83
- There is occasionally some tension between clarity and changeability. More abstraction or generic parameters may make things more changeable at the cost of some clarity.
84
-
85
- ### Code Challenges
86
-
87
- - Complexity: Undermines every single one of our code priorities.
88
-
89
- Complexity is the limiting factor which defines the upper limit on how sophisticated of an application we are able to create and maintain at a practical velocity.
90
-
91
- The difficulty of dealing with complexity tends to increase at a greater than linear rate, especially once the short term context window of a human or ai agent is exceeded.
92
-
93
- ### General Principles
94
-
95
- - Separation of Concerns: If two concerns can be separated then do it.
96
- - Avoid mutation: Immutable values are easier to reason about.
97
- - Use Small files: Aim for less than 200 loc. Decompose if > 500 loc.
98
- - Single concern per file: Export only a single declaration per file.
99
- - Avoid object oriented classes: Combines data concerns with functions.
100
- - Distinguish services from data: Services do things, data stores things.
101
- - Use static typing: Finds errors earlier and guides both AI and humans.
102
- - Avoid side effects: Pure functions are easier to comprehend and test.
77
+ ```
78
+ Find the @adobe/data-ai package on npmjs and then install it in the current directory.
79
+ Next use it's /build-application skill to build <promt here>
80
+ ```
package/bin/cli.mjs CHANGED
@@ -1,18 +1,21 @@
1
1
  #!/usr/bin/env node
2
- // Installer for the @adobe/data-ai skill bundle (Cursor / Codex / .agents-standard agents).
2
+ // Installer for the @adobe/data-ai bundle (Cursor / Codex / .agents-standard agents).
3
3
  //
4
- // Copies the SKILL.md folders shipped in this package into a single namespaced
5
- // bundle directory that agents which recurse `.agents/skills/` will discover:
4
+ // Lays down two managed, namespaced directories the agent discovers:
6
5
  //
7
- // .agents/skills/adobe-data-ai/<name>/SKILL.md
6
+ // .agents/skills/adobe-data-ai/<name>/SKILL.md — the build-* skills
7
+ // .claude/rules/adobe-data-ai/**/*.md — the architecture rules
8
8
  //
9
- // We own the `adobe-data-ai/` directory outright, so a refresh is a clean
10
- // wipe-and-recopy — it never touches skills you authored elsewhere.
9
+ // We own both `adobe-data-ai/` directories outright, so a refresh is a clean
10
+ // wipe-and-recopy — it never touches files you authored elsewhere. Re-running
11
+ // the installer is therefore also how you update.
11
12
  //
12
- // Claude Code is intentionally NOT a target: it does not scan `.agents/`, and
13
- // copying into `.claude/skills/` could collide with a user's own skills.
14
- // Claude consumes these as the `adobe-data-ai` marketplace plugin instead
15
- // (see README).
13
+ // Claude Code is intentionally NOT a skills target: it does not scan `.agents/`,
14
+ // and copying into `.claude/skills/` could collide with a user's own skills — it
15
+ // consumes the skills as the `adobe-data-ai` marketplace plugin instead. The
16
+ // rules, however, install into `.claude/rules/adobe-data-ai/` for every agent
17
+ // (Claude auto-injects them by their `paths:` globs; other agents read them by
18
+ // name as their skills run). See README.
16
19
 
17
20
  import {
18
21
  cpSync,
@@ -30,12 +33,39 @@ import { fileURLToPath } from "node:url";
30
33
  const here = dirname(fileURLToPath(import.meta.url));
31
34
  const pkgRoot = resolve(here, "..");
32
35
  const skillsSrc = join(pkgRoot, "skills");
36
+ const rulesSrc = join(pkgRoot, ".claude", "rules");
33
37
  const pkg = JSON.parse(readFileSync(join(pkgRoot, "package.json"), "utf8"));
34
38
  const { name: PKG_NAME, version: VERSION } = pkg;
35
39
 
36
- // Namespaced bundle folder — the whole directory belongs to this package.
40
+ // Namespaced bundle folder — the whole directory belongs to this package, under
41
+ // each agent root.
37
42
  const BUNDLE = "adobe-data-ai";
38
43
 
44
+ // A do-not-edit notice dropped at each bundle root. Claude Code loads nested
45
+ // CLAUDE.md files when working in a subtree, so an agent that opens one of these
46
+ // folders sees the notice before touching anything. `extra` adds a pointer to
47
+ // the companion bundle.
48
+ function notice(extra) {
49
+ return `# Externally managed — do not edit
50
+
51
+ The files in this folder are installed and managed by the \`${PKG_NAME}\`
52
+ package. This entire directory is **deleted and rebuilt** on every
53
+ \`npx ${PKG_NAME} install\`, so any local edit here is silently discarded on the
54
+ next reinstall or version upgrade.
55
+
56
+ To change them, edit upstream in the \`${PKG_NAME}\` package and publish a new
57
+ version, then reinstall — do not modify these files in place.
58
+ ${extra ? `\n${extra}\n` : ""}`;
59
+ }
60
+
61
+ function writeMeta(bundleDir, noticeBody, extraMeta) {
62
+ writeFileSync(join(bundleDir, "CLAUDE.md"), noticeBody);
63
+ writeFileSync(
64
+ join(bundleDir, ".data-ai.json"),
65
+ JSON.stringify({ package: PKG_NAME, version: VERSION, ...extraMeta }, null, 2) + "\n",
66
+ );
67
+ }
68
+
39
69
  function discoverSkills() {
40
70
  if (!existsSync(skillsSrc)) return [];
41
71
  return readdirSync(skillsSrc, { withFileTypes: true })
@@ -44,17 +74,41 @@ function discoverSkills() {
44
74
  .sort();
45
75
  }
46
76
 
47
- function installTo(bundleDir, skills) {
48
- // We own this directory — wipe and recopy for a clean refresh.
77
+ // Recursively count the rule `.md` files, excluding the top-level README.md
78
+ // (rules-authoring meta doc, not a rule — and it carries no `paths:` guard).
79
+ function countRules(dir) {
80
+ let n = 0;
81
+ for (const d of readdirSync(dir, { withFileTypes: true })) {
82
+ if (d.isDirectory()) n += countRules(join(dir, d.name));
83
+ else if (d.name.endsWith(".md") && !(dir === rulesSrc && d.name === "README.md")) n += 1;
84
+ }
85
+ return n;
86
+ }
87
+
88
+ function installSkills(base, skills) {
89
+ const bundleDir = join(base, ".agents", "skills", BUNDLE);
49
90
  rmSync(bundleDir, { recursive: true, force: true });
50
91
  mkdirSync(bundleDir, { recursive: true });
51
92
  for (const name of skills) {
52
93
  cpSync(join(skillsSrc, name), join(bundleDir, name), { recursive: true });
53
94
  }
54
- writeFileSync(
55
- join(bundleDir, ".data-ai.json"),
56
- JSON.stringify({ package: PKG_NAME, version: VERSION, skills }, null, 2) + "\n",
95
+ writeMeta(
96
+ bundleDir,
97
+ notice("The architecture rules these skills follow are installed at\n`.claude/rules/adobe-data-ai/` (referenced by name from each SKILL.md)."),
98
+ { skills },
57
99
  );
100
+ return bundleDir;
101
+ }
102
+
103
+ function installRules(base) {
104
+ const bundleDir = join(base, ".claude", "rules", BUNDLE);
105
+ rmSync(bundleDir, { recursive: true, force: true });
106
+ mkdirSync(bundleDir, { recursive: true });
107
+ // Copy the whole rules tree, minus the top-level README.md meta doc.
108
+ const readme = join(rulesSrc, "README.md");
109
+ cpSync(rulesSrc, bundleDir, { recursive: true, filter: (src) => src !== readme });
110
+ writeMeta(bundleDir, notice(), { rules: countRules(rulesSrc) });
111
+ return bundleDir;
58
112
  }
59
113
 
60
114
  function parseArgs(argv) {
@@ -72,19 +126,20 @@ function parseArgs(argv) {
72
126
 
73
127
  const HELP = `${PKG_NAME} v${VERSION}
74
128
 
75
- Install the architecture-skill bundle for Cursor, Codex, and other agents
76
- that scan .agents/skills/. (Claude Code uses the marketplace plugin instead.)
129
+ Install the architecture skills + rules for Cursor, Codex, and other agents.
130
+ (Claude Code gets the skills from the marketplace plugin; the rules install the
131
+ same way for every agent — see README.)
77
132
 
78
133
  Usage:
79
134
  npx ${PKG_NAME}@latest install [options]
80
135
  npx ${PKG_NAME}@latest list
81
136
 
82
137
  Commands:
83
- install Copy skills into .agents/skills/${BUNDLE}/ (default).
138
+ install Skills → .agents/skills/${BUNDLE}/, rules → .claude/rules/${BUNDLE}/ (default).
84
139
  list Print the skills bundled in this package.
85
140
 
86
141
  Options:
87
- --global, -g Install into your home directory (~/.agents/skills/${BUNDLE}/)
142
+ --global, -g Install into your home directory (~/.agents, ~/.claude)
88
143
  instead of the current project.
89
144
  --dir=<path> Base directory to install into (default: cwd).
90
145
  --help, -h Show this help.
@@ -119,13 +174,13 @@ function main() {
119
174
  }
120
175
 
121
176
  const base = flags.has("global") ? homedir() : dir ? resolve(dir) : process.cwd();
122
- const bundleDir = join(base, ".agents", "skills", BUNDLE);
123
-
124
- installTo(bundleDir, skills);
177
+ const skillsDir = installSkills(base, skills);
178
+ const rulesDir = installRules(base);
179
+ const ruleCount = countRules(rulesSrc);
125
180
 
126
- process.stdout.write(`Installed ${skills.length} skill(s) from ${PKG_NAME} v${VERSION}\n`);
127
- process.stdout.write(` ${bundleDir}\n`);
128
- process.stdout.write(`Skills: ${skills.join(", ")}\n`);
181
+ process.stdout.write(`Installed ${PKG_NAME} v${VERSION}\n`);
182
+ process.stdout.write(` ${skills.length} skills → ${skillsDir}\n`);
183
+ process.stdout.write(` ${ruleCount} rules → ${rulesDir}\n`);
129
184
  }
130
185
 
131
186
  main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/data-ai",
3
- "version": "0.9.83",
3
+ "version": "0.9.86",
4
4
  "description": "Cross-agent architecture skills for @adobe/data — installable as a Claude Code plugin or copied into any Agent-Skills-compatible agent (Cursor, Codex).",
5
5
  "type": "module",
6
6
  "private": false,
@@ -13,6 +13,7 @@
13
13
  },
14
14
  "files": [
15
15
  "skills",
16
+ ".claude",
16
17
  "bin",
17
18
  ".claude-plugin",
18
19
  "README.md",
@@ -27,12 +28,18 @@
27
28
  "codex",
28
29
  "skills"
29
30
  ],
31
+ "peerDependencies": {
32
+ "@adobe/data": "0.9.86"
33
+ },
30
34
  "devDependencies": {
31
- "vitest": "^1.6.0"
35
+ "typescript": "^5.8.3",
36
+ "vitest": "^1.6.0",
37
+ "@adobe/data": "0.9.86"
32
38
  },
33
39
  "license": "MIT",
34
40
  "scripts": {
35
41
  "build": "cp ../../LICENSE .",
42
+ "typecheck": "true",
36
43
  "test": "vitest --run --passWithNoTests",
37
44
  "publish-public": "pnpm build && pnpm publish --no-git-checks --access public"
38
45
  }
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: build-actions
3
+ description: Build a feature's ecs action-database — async orchestration over services and transactions. If the feature has async flows or side effects outside of the main store.
4
+ input: feature
5
+ output: feature
6
+ ---
7
+
8
+ Skip if this feature doesn't contain or require actions.
9
+
10
+ Create `ecs/action-database/`: `action-database.ts` (extends `ServiceDatabase`, adds `actions`
11
+ from `./actions/index.js`) plus an `actions/` folder — one async orchestrator per file. An action
12
+ takes `db: ServiceDatabase`, awaits `services/` ports, then commits **exactly one** transaction.
13
+
14
+ The top ecs layer; comes after `service-database`.
15
+
16
+ The how is in the auto-loading `features/ecs/actions.md` rule.
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: build-app-entry
3
+ description: Wire built features into a running application — import peer schemas, lazy-load peers, and mount the root UI.
4
+ input: app
5
+ output: app
6
+ ---
7
+
8
+ - The base (`features/main`) core-database `imports` each peer feature's core-database
9
+ plugin, so all schemas coexist, persist, and sync while the base type stays decoupled.
10
+ - The base reaches a peer only through a lazy element wrapper (dynamic import), so peers
11
+ load on demand.
12
+ - The entry point creates the live database from `FeatureDatabase.plugin` (the base
13
+ feature's assembled database — see `features/ecs/index.md`) and mounts the root UI.
14
+
15
+ See `features/index.md` (one-app-many-features) for the wiring rules.
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: build-application
3
+ description: Build an application — a base feature hosting lazily-loaded peer features.
4
+ input: app
5
+ output: app
6
+ ---
7
+
8
+ /graph-execute
9
+ /build-feature (base — features/main)
10
+ for each sub feature
11
+ /build-feature
12
+ /build-app-entry
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: build-computed
3
+ description: Build a feature's ecs computed-database — derived observable values.
4
+ input: feature
5
+ output: feature
6
+ ---
7
+
8
+ Skip if this feature doesn't contain or require computed values.
9
+
10
+ Create `ecs/computed-database/`: `computed-database.ts` (extends the previous layer, adds
11
+ `computed` from `./computed/index.js`) plus a `computed/` folder — one `cached` derived value
12
+ per file + barrel. Derivation logic lives in `data/`; a computed only wires a db observable to it.
13
+
14
+ Comes after `transaction-database`.
15
+
16
+ The how is in the auto-loading `features/ecs/computed.md` rule.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: build-core-database
3
+ description: Build a feature's ecs schema — the core-database (components, resources, archetypes). The first ecs layer.
4
+ input: feature
5
+ output: feature
6
+ ---
7
+
8
+ Create `ecs/core-database/` — `core-database.ts` plus one single-export file per facet
9
+ the feature actually uses (`components`, `resources`, `archetypes` are each optional on
10
+ `Database.Plugin.create`). Create only the facet files you need; omit the rest rather than
11
+ shipping empty `Database.components({})` boilerplate. A feature with **no entities** (a
12
+ singleton whose whole state is resources) is just `resources.ts` + `core-database.ts`.
13
+
14
+ - `components.ts` → `Database.components({ document, settings, presence, session })` (scopes optional) — only if the feature has entities.
15
+ - `resources.ts` → `Database.resources({ … })` (every entry needs a `default`) — for singleton / global state.
16
+ - `archetypes.ts` → `Database.archetypes(components, { … })` — only alongside components.
17
+ - `core-database.ts` → `Database.Plugin.create({ imports?, components?, resources?, archetypes? })`, exporting the `CoreDatabase` namespace.
18
+
19
+ The schema root; comes after `data/` (and `services/`). Bind each schema from its `data/`
20
+ type — don't author shapes here. Components use JSON schemas; resources use the
21
+ `{ default }` convention (a schemaless aggregate binds via `{ default: State.create() }`).
22
+
23
+ The how is in the auto-loading `features/ecs/index.md` + `components.md` / `resources.md` /
24
+ `archetypes.md` rules.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: build-data
3
+ description: Build a feature's data/ layer — data-type namespaces and the State spec. The first, foundational feature phase.
4
+ input: feature
5
+ output: feature
6
+ ---
7
+
8
+ Create the feature's `data/` layer (pure spec; depends on nothing but `@adobe/data`
9
+ and other `data/` declarations):
10
+
11
+ - one namespace folder per data type — `<type>/{<type>.ts, schema.ts, public.ts, <helper>.ts}`;
12
+ - `data/state/` — the `State` aggregate plus its pure transforms/derivations.
13
+
14
+ **Always create `data/state/`** — even for a shell feature whose only field is a
15
+ boolean or enum. A feature with ECS resources/transactions but no `State` is
16
+ incomplete: the transaction must wrap a pure transform, not invent the logic. In rare circumstances, there may be no real state in a feature in which case the state type = {}
17
+
18
+ The schema is the single source of truth; the type derives from it (`Schema.ToType`).
19
+ Helpers are pure and unit-tested. Run this first — every other layer imports `data/`.
20
+
21
+ The how is in the auto-loading rules: `features/data/index.md`, `features/data/state.md`, and
22
+ `namespace.md`.
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: build-feature
3
+ description: Build a complete feature step by step
4
+ input: feature
5
+ output: feature
6
+ ---
7
+
8
+ /graph-execute
9
+ /build-data
10
+ /build-services
11
+ /build-core-database
12
+ /build-indexes
13
+ /build-transactions
14
+ /build-computed
15
+ /build-service-database
16
+ /build-actions
17
+ /build-systems
18
+ /build-ui
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: build-game
3
+ description: Build a game — an application whose features model game state, rules, and rendering.
4
+ input: game
5
+ output: game
6
+ ---
7
+
8
+ /build-application — a game is an application.
9
+
10
+ Map game concepts to feature layers: data/ = state + rules (+ per-tick step math),
11
+ components/archetypes = entity kinds, indexes = spatial/lookup queries,
12
+ transactions = moves/spawns, computed = score/status/winner, ui = view + input.
13
+
14
+ - **Turn-based** uses the reactive transaction → computed → ui loop, no systems
15
+ (see data-lit-tictactoe).
16
+ - **Real-time** adds the `build-systems` phase: a per-frame tick loop (movement,
17
+ collision, lifetime) driven by the scheduler, over many entities in distinct
18
+ archetypes. Systems must stay O(1) per touched entity — never project the whole
19
+ `State` into/out of the store each frame (see `features/ecs/systems.md`).
20
+ This is where components, archetypes, indexes, and systems all carry real
21
+ weight.
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: build-indexes
3
+ description: Build a feature's ecs index-database — component/archetype indexes for O(1) lookup. As needed.
4
+ input: feature
5
+ output: feature
6
+ ---
7
+
8
+ Skip if this feature doesn't contain or require indexes.
9
+
10
+ Create `ecs/index-database/`: `index-database.ts` (extends `CoreDatabase`, adds the `indexes`
11
+ facet from `./indexes/index.js`) plus an `indexes/` folder — one index per file + an `index.ts`
12
+ barrel.
13
+
14
+ Only if the feature needs indexed lookups. Comes after `core-database`.
15
+
16
+ The how is in the auto-loading `features/ecs/indexes.md` rule.
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: build-service-database
3
+ description: Build a feature's ecs service-database — db-bound service factories. If the feature exposes services.
4
+ input: feature
5
+ output: feature
6
+ ---
7
+
8
+ Create `ecs/service-database/`: `service-database.ts` (extends the previous layer, registers the
9
+ `services` facet). Two forms:
10
+
11
+ - db-bound factories `create<Name>Service(db, …)` in `service-database/services/` (one per file + barrel), for services that read `db.observe.*` / call `db.transactions.*`; or
12
+ - plain async ports registered straight from the feature's `services/` contracts.
13
+
14
+ Comes after `computed-database`.
15
+
16
+ The how is in the auto-loading `features/ecs/services.md` rule.