@adobe/data-ai 0.9.90 → 0.9.91

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.
@@ -13,6 +13,8 @@ folder's own `index.md` holds just enough to understand that folder; each
13
13
  child gets its own file (recursing wherever the source tree does):
14
14
 
15
15
  ```
16
+ global/ # always-on conventions — deliberately repo-wide globs
17
+ namespace.md cohesion.md type-casts.md function-references.md react.md
16
18
  features/
17
19
  index.md # the feature layering as a whole (ui → services → data)
18
20
  data/
@@ -28,12 +30,15 @@ features/
28
30
  ui/index.md # UI (points to element / presentation / lazy-element file rules)
29
31
  ```
30
32
 
31
- Alongside `features/`, the rules-root `.md` files hold the **cross-cutting**
32
- patterns the feature rules reference — `namespace.md`, `data-modelling.md`,
33
- `type-casts.md`, `function-references.md`, `cohesion.md`, `archetypes.md` (row
34
- iteration), `plugin-modelling.md`, and the UI file rules (`element.md`,
35
- `lazy-element.md`, `presentation.md`). They live here so the bundle is self-contained; this repo
36
- symlinks them into its own `.claude/rules/` (as it does `features/`).
33
+ The `global/` rules (`namespace.md`, `cohesion.md`, `type-casts.md`,
34
+ `function-references.md`, `react.md`) are **intentionally repo-wide** — their
35
+ `paths:` globs (`**/*.ts` etc.) apply everywhere, by design, so the folder name
36
+ makes that explicit. Alongside `features/`, the remaining rules-root `.md` files
37
+ hold the other **cross-cutting** patterns the feature rules reference —
38
+ `data-modelling.md`, `archetypes.md` (row iteration), `plugin-modelling.md`, and
39
+ the UI file rules (`element.md`, `lazy-element.md`, `presentation.md`). They live
40
+ here so the bundle is self-contained; this repo symlinks them into its own
41
+ `.claude/rules/` (as it does `features/`).
37
42
 
38
43
  Each rule's `paths:` glob is scoped to `**/features/*/<layer>/…`, so these
39
44
  rules apply only once an application opts into the feature-folder pattern
@@ -11,7 +11,7 @@ communication over the wire — no functions, no handles, just plain data.
11
11
  It depends on nothing but `@adobe/data` and other `data/` declarations, and
12
12
  needs no knowledge of anything built on top of it.
13
13
 
14
- Each data type is its own namespace folder (see `namespace.md`), holding
14
+ Each data type is its own namespace folder (see `global/namespace.md`), holding
15
15
  its schema, its derived type, and its pure synchronous helpers together:
16
16
 
17
17
  ```
@@ -106,6 +106,7 @@ current examples of this structure. `data-lit-todo` is the most complete
106
106
  See the rules under each folder: `data/`, `services/` — the `main-service/`
107
107
  subtree (components, resources, archetypes, computed, indexes, transactions,
108
108
  systems, conformance) and capability-contract services — and `ui/`.
109
- Cross-cutting patterns live at the rules root — `namespace.md`,
110
- `data-modelling.md`, `archetypes.md` (row iteration), `type-casts.md`,
111
- `cohesion.md`.
109
+ Always-on conventions live in `global/` (`namespace.md`, `cohesion.md`,
110
+ `type-casts.md`, `function-references.md`, `react.md` — deliberately repo-wide);
111
+ other cross-cutting patterns at the rules root — `data-modelling.md`,
112
+ `archetypes.md` (row iteration).
@@ -22,7 +22,7 @@ its own subtree.
22
22
 
23
23
  ## Capability contracts
24
24
 
25
- Each is a namespace folder (`namespace.md`); the export and folder both carry the
25
+ Each is a namespace folder (`global/namespace.md`); the export and folder both carry the
26
26
  `-service` suffix. A service is the boundary between pure feature code and the
27
27
  outside world, which is why its members are async — enabling cross-process
28
28
  portability and lazy loading (`AsyncDataService.createLazy`).
@@ -32,6 +32,8 @@ import { Database, scheduler } from "@adobe/data/ecs";
32
32
  import { Motion } from "../../data/motion/motion.js";
33
33
 
34
34
  const plugin = Database.Plugin.create({
35
+ // combine scheduler with the CURRENT TOP layer — ComputedDatabase here, but
36
+ // ActionDatabase / ServiceDatabase if the feature built those (systems come last).
35
37
  extends: Database.Plugin.combine(ComputedDatabase.plugin, scheduler),
36
38
  systems: {
37
39
  control: { create: (db) => () => { /* input → ship; db.transactions.fireBullet() */ } },
@@ -119,8 +121,10 @@ with no rAF and no rendering attached.
119
121
 
120
122
  ## Layer
121
123
 
122
- `system-database.ts` extends the previous main-service layer (usually `ComputedDatabase`),
123
- combined with `scheduler`, and declares the `systems` map **inline** (see above —
124
+ `system-database.ts` extends the feature's **current top** main-service layer (`ActionDatabase` /
125
+ `ServiceDatabase` / `ComputedDatabase` — whichever it built; systems come last in the pipeline, so
126
+ they must sit atop any service/action layers, not a hardcoded `ComputedDatabase`), combined with
127
+ `scheduler`, and declares the `systems` map **inline** (see above —
124
128
  this is the one facet not split one-per-file, because `create`'s `db` is only typed
125
129
  inline and standalone declarations break name inference). A `systems/` folder is
126
130
  optional: it holds extracted per-frame body helpers (`(db) => () => void`) only when
@@ -41,5 +41,5 @@ export const playMove = (t: CoreDatabase.Store, { index }: PlayMoveArgs) => {
41
41
  transactions (`readShip`, `readBoard` — a `(t) => value` function) may live
42
42
  beside them in `transactions/`, but keep it **out of the barrel**, or it gets
43
43
  registered as a dispatchable transaction. (These are related helpers, so they
44
- belong here, not in a separate folder — `cohesion.md`'s peer-level caution
44
+ belong here, not in a separate folder — `global/cohesion.md`'s peer-level caution
45
45
  doesn't apply.)
@@ -32,7 +32,7 @@ Presentation files (`*-presentation.ts`), CSS files (`*.css.ts`), tests (`*.test
32
32
  A binding element is a thin wire between a service and a presentation. The class body contains:
33
33
 
34
34
  1. Optional static `styles` property definition
35
- 2. Zero or more `@property` declarations (whitelisted below).
35
+ 2. Zero or more `@property` declarations (allowed below).
36
36
  3. One `render()` method whose body is: one `useObservableValues(...)` call, another lifecycle hook call (in rare cases), a null-guard, and
37
37
  `return presentation.render({ ...values, ...callbacks })`.
38
38
 
@@ -40,7 +40,7 @@ No other members. No `@state`. No private handler fields. No lifecycle methods (
40
40
  `disconnectedCallback`) except on app-entrypoint classes where the lifecycle concern is app-boot shaped but cannot be expressed as a hook
41
41
  (see `.claude/rules/hooks.md` for hook-first lifecycle).
42
42
 
43
- ## `@property` whitelist
43
+ ## `@property` allowlist
44
44
 
45
45
  The allowed set depends on **class role**:
46
46
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adobe-data-ai",
3
- "version": "0.9.90",
3
+ "version": "0.9.91",
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  AI architecture skills + rules for building applications with
4
4
  [`@adobe/data`](https://www.npmjs.com/package/@adobe/data) — a layered,
5
- spec-first feature structure (`data → ecs → ui`) kept honest by conformance
5
+ spec-first feature structure (`data → services → ui`) kept honest by conformance
6
6
  tests. Versioned in lockstep with the library: `@adobe/data-ai@x.y.z` targets
7
7
  `@adobe/data@x.y.z`.
8
8
 
package/bin/cli.mjs CHANGED
@@ -50,8 +50,8 @@ function notice(extra) {
50
50
 
51
51
  The files in this folder are installed and managed by the \`${PKG_NAME}\`
52
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.
53
+ \`npx ${PKG_NAME}@${VERSION} install\`, so any local edit here is silently discarded on
54
+ the next reinstall or version upgrade.
55
55
 
56
56
  To change them, edit upstream in the \`${PKG_NAME}\` package and publish a new
57
57
  version, then reinstall — do not modify these files in place.
@@ -66,10 +66,21 @@ function writeMeta(bundleDir, noticeBody, extraMeta) {
66
66
  );
67
67
  }
68
68
 
69
+ // Skills that author/evolve the bundle itself (the self-improvement loop and its
70
+ // rule review). They mutate or critique the managed files, so they belong only to
71
+ // the source repo — never a consumer install, where those files are read-only
72
+ // managed copies. Both also carry `disable-model-invocation: true`.
73
+ const MAINTAINER_ONLY = new Set(["meta-build", "review"]);
74
+
69
75
  function discoverSkills() {
70
76
  if (!existsSync(skillsSrc)) return [];
71
77
  return readdirSync(skillsSrc, { withFileTypes: true })
72
- .filter((d) => d.isDirectory() && existsSync(join(skillsSrc, d.name, "SKILL.md")))
78
+ .filter(
79
+ (d) =>
80
+ d.isDirectory() &&
81
+ !MAINTAINER_ONLY.has(d.name) &&
82
+ existsSync(join(skillsSrc, d.name, "SKILL.md")),
83
+ )
73
84
  .map((d) => d.name)
74
85
  .sort();
75
86
  }
@@ -111,6 +122,41 @@ function installRules(base) {
111
122
  return bundleDir;
112
123
  }
113
124
 
125
+ // A single managed rule (namespaced by its `adobe-data-ai-` filename prefix) telling
126
+ // an agent to (re)install the bundle when the skills are absent — pinned to THIS
127
+ // reviewed version, never `@latest`, so a drifted or compromised release cannot execute
128
+ // during install. Rewritten with the matching version on every install. It sits beside
129
+ // (not inside) the wiped bundle dir, so it survives and is simply overwritten.
130
+ function installBootstrap(base) {
131
+ const file = join(base, ".claude", "rules", `${BUNDLE}-bootstrap.md`);
132
+ mkdirSync(dirname(file), { recursive: true });
133
+ writeFileSync(
134
+ file,
135
+ `---
136
+ paths:
137
+ - '**/features/*/data/**/*.ts'
138
+ - '**/features/*/services/**/*.ts'
139
+ - '**/features/*/ui/**/*.ts'
140
+ ---
141
+
142
+ # ${PKG_NAME} skills — ensure installed
143
+
144
+ Before using an \`@adobe/data\` build workflow, confirm the skills are present: look for
145
+ a skill named \`build-feature\` (or \`build-application\`). If it is missing, install the
146
+ pinned, reviewed bundle, then re-check:
147
+
148
+ \`\`\`sh
149
+ npx ${PKG_NAME}@${VERSION} install
150
+ \`\`\`
151
+
152
+ Pin the version to the reviewed bundle (never \`@latest\`) so a compromised or drifted
153
+ release cannot execute during install. This file is regenerated with the matching
154
+ version on every install. Package: <https://www.npmjs.com/package/${PKG_NAME}>
155
+ `,
156
+ );
157
+ return file;
158
+ }
159
+
114
160
  function parseArgs(argv) {
115
161
  const positional = [];
116
162
  const flags = new Set();
@@ -176,11 +222,13 @@ function main() {
176
222
  const base = flags.has("global") ? homedir() : dir ? resolve(dir) : process.cwd();
177
223
  const skillsDir = installSkills(base, skills);
178
224
  const rulesDir = installRules(base);
225
+ const bootstrapFile = installBootstrap(base);
179
226
  const ruleCount = countRules(rulesSrc);
180
227
 
181
228
  process.stdout.write(`Installed ${PKG_NAME} v${VERSION}\n`);
182
229
  process.stdout.write(` ${skills.length} skills → ${skillsDir}\n`);
183
230
  process.stdout.write(` ${ruleCount} rules → ${rulesDir}\n`);
231
+ process.stdout.write(` bootstrap → ${bootstrapFile}\n`);
184
232
  }
185
233
 
186
234
  main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/data-ai",
3
- "version": "0.9.90",
3
+ "version": "0.9.91",
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,
@@ -29,12 +29,12 @@
29
29
  "skills"
30
30
  ],
31
31
  "peerDependencies": {
32
- "@adobe/data": "0.9.90"
32
+ "@adobe/data": "0.9.91"
33
33
  },
34
34
  "devDependencies": {
35
35
  "typescript": "^5.8.3",
36
36
  "vitest": "^1.6.0",
37
- "@adobe/data": "0.9.90"
37
+ "@adobe/data": "0.9.91"
38
38
  },
39
39
  "license": "MIT",
40
40
  "scripts": {
@@ -19,4 +19,4 @@ The schema is the single source of truth; the type derives from it (`Schema.ToTy
19
19
  Helpers are pure and unit-tested. Run this first — every other layer imports `data/`.
20
20
 
21
21
  The how is in the auto-loading rules: `features/data/index.md`, `features/data/state.md`, and
22
- `namespace.md`.
22
+ `global/namespace.md`.
@@ -13,4 +13,4 @@ and `create*` factories.
13
13
 
14
14
  Only if the feature talks to the outside world. Comes after `data/`, before `services/main-service/`.
15
15
 
16
- The how is in the auto-loading `features/services/index.md` rule (and `namespace.md`).
16
+ The how is in the auto-loading `features/services/index.md` rule (and `global/namespace.md`).
@@ -9,7 +9,10 @@ Skip if this feature doesn't contain or require systems.
9
9
  Most games that use a canvas will use systems but most applications will not.
10
10
 
11
11
  Create `services/main-service/system-database/system-database.ts`: `Database.Plugin.create({ extends:
12
- Database.Plugin.combine(ComputedDatabase.plugin, scheduler), systems })` where the `systems`
12
+ Database.Plugin.combine(<currentTop>.plugin, scheduler), systems })` — combine `scheduler` with the
13
+ feature's **current top** main-service layer (`ActionDatabase` / `ServiceDatabase` / `ComputedDatabase`,
14
+ whichever it built), never a hardcoded `ComputedDatabase`, so systems *and* any services/actions
15
+ compose into the one `FeatureDatabase`. The `systems`
13
16
  map is declared **inline** (see `features/services/main-service/systems.md` — inline is required for `db` to be
14
17
  typed and for system-name inference; a `systems/` folder is optional, only for extracted
15
18
  per-frame body helpers).
@@ -5,7 +5,8 @@ input: feature
5
5
  output: feature
6
6
  ---
7
7
 
8
- Create `services/main-service/transaction-database/`: `transaction-database.ts` (extends `IndexDatabase`, adds
8
+ Create `services/main-service/transaction-database/`: `transaction-database.ts` (extends the
9
+ preceding layer — `IndexDatabase` if the feature built indexes, else `CoreDatabase` — adds
9
10
  `transactions` from `./transactions/index.js`) plus a `transactions/` folder — one mutation per
10
11
  file + barrel. Type the store param `CoreDatabase.Store` (entities/resources/archetypes) or
11
12
  `IndexDatabase.Store` (reads an index).
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: meta-build
3
+ disable-model-invocation: true
3
4
  description: Iteratively build an application or game phase-by-phase in clean subagents, reviewing each phase and refining the build-* skills / rules until each is optimal, then summarizing.
4
5
  input: a prompt describing the application or game to build
5
6
  options:
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: review
3
+ disable-model-invocation: true
3
4
  description: Review built feature/application output against the @adobe/data feature rules; report whether it is optimal and where any fix belongs. Read-only.
4
5
  input: a path to built output (a layer, a feature, or a whole app)
5
6
  output: a review — OPTIMAL, or a list of issues each tagged code | skill | rule
File without changes