Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-monorepo",
"version": "0.9.90",
"version": "0.9.91",
"private": true,
"engines": {
"node": ">=24"
Expand Down
2 changes: 1 addition & 1 deletion packages/data-ai/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "adobe-data-ai",
"version": "0.9.90",
"version": "0.9.91",
"description": "Architecture skills for @adobe/data — data-oriented modelling, archetype iteration, hot-path performance, and related conventions.",
"author": {
"name": "Adobe"
Expand Down
17 changes: 11 additions & 6 deletions packages/data-ai/.claude/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ folder's own `index.md` holds just enough to understand that folder; each
child gets its own file (recursing wherever the source tree does):

```
global/ # always-on conventions — deliberately repo-wide globs
namespace.md cohesion.md type-casts.md function-references.md react.md
features/
index.md # the feature layering as a whole (ui → services → data)
data/
Expand All @@ -28,12 +30,15 @@ features/
ui/index.md # UI (points to element / presentation / lazy-element file rules)
```

Alongside `features/`, the rules-root `.md` files hold the **cross-cutting**
patterns the feature rules reference — `namespace.md`, `data-modelling.md`,
`type-casts.md`, `function-references.md`, `cohesion.md`, `archetypes.md` (row
iteration), `plugin-modelling.md`, and the UI file rules (`element.md`,
`lazy-element.md`, `presentation.md`). They live here so the bundle is self-contained; this repo
symlinks them into its own `.claude/rules/` (as it does `features/`).
The `global/` rules (`namespace.md`, `cohesion.md`, `type-casts.md`,
`function-references.md`, `react.md`) are **intentionally repo-wide** — their
`paths:` globs (`**/*.ts` etc.) apply everywhere, by design, so the folder name
makes that explicit. Alongside `features/`, the remaining rules-root `.md` files
hold the other **cross-cutting** patterns the feature rules reference —
`data-modelling.md`, `archetypes.md` (row iteration), `plugin-modelling.md`, and
the UI file rules (`element.md`, `lazy-element.md`, `presentation.md`). They live
here so the bundle is self-contained; this repo symlinks them into its own
`.claude/rules/` (as it does `features/`).

Each rule's `paths:` glob is scoped to `**/features/*/<layer>/…`, so these
rules apply only once an application opts into the feature-folder pattern
Expand Down
2 changes: 1 addition & 1 deletion packages/data-ai/.claude/rules/features/data/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ communication over the wire — no functions, no handles, just plain data.
It depends on nothing but `@adobe/data` and other `data/` declarations, and
needs no knowledge of anything built on top of it.

Each data type is its own namespace folder (see `namespace.md`), holding
Each data type is its own namespace folder (see `global/namespace.md`), holding
its schema, its derived type, and its pure synchronous helpers together:

```
Expand Down
7 changes: 4 additions & 3 deletions packages/data-ai/.claude/rules/features/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ current examples of this structure. `data-lit-todo` is the most complete
See the rules under each folder: `data/`, `services/` — the `main-service/`
subtree (components, resources, archetypes, computed, indexes, transactions,
systems, conformance) and capability-contract services — and `ui/`.
Cross-cutting patterns live at the rules root — `namespace.md`,
`data-modelling.md`, `archetypes.md` (row iteration), `type-casts.md`,
`cohesion.md`.
Always-on conventions live in `global/` (`namespace.md`, `cohesion.md`,
`type-casts.md`, `function-references.md`, `react.md` — deliberately repo-wide);
other cross-cutting patterns at the rules root — `data-modelling.md`,
`archetypes.md` (row iteration).
2 changes: 1 addition & 1 deletion packages/data-ai/.claude/rules/features/services/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ its own subtree.

## Capability contracts

Each is a namespace folder (`namespace.md`); the export and folder both carry the
Each is a namespace folder (`global/namespace.md`); the export and folder both carry the
`-service` suffix. A service is the boundary between pure feature code and the
outside world, which is why its members are async — enabling cross-process
portability and lazy loading (`AsyncDataService.createLazy`).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import { Database, scheduler } from "@adobe/data/ecs";
import { Motion } from "../../data/motion/motion.js";

const plugin = Database.Plugin.create({
// combine scheduler with the CURRENT TOP layer — ComputedDatabase here, but
// ActionDatabase / ServiceDatabase if the feature built those (systems come last).
extends: Database.Plugin.combine(ComputedDatabase.plugin, scheduler),
systems: {
control: { create: (db) => () => { /* input → ship; db.transactions.fireBullet() */ } },
Expand Down Expand Up @@ -119,8 +121,10 @@ with no rAF and no rendering attached.

## Layer

`system-database.ts` extends the previous main-service layer (usually `ComputedDatabase`),
combined with `scheduler`, and declares the `systems` map **inline** (see above —
`system-database.ts` extends the feature's **current top** main-service layer (`ActionDatabase` /
`ServiceDatabase` / `ComputedDatabase` — whichever it built; systems come last in the pipeline, so
they must sit atop any service/action layers, not a hardcoded `ComputedDatabase`), combined with
`scheduler`, and declares the `systems` map **inline** (see above —
this is the one facet not split one-per-file, because `create`'s `db` is only typed
inline and standalone declarations break name inference). A `systems/` folder is
optional: it holds extracted per-frame body helpers (`(db) => () => void`) only when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ export const playMove = (t: CoreDatabase.Store, { index }: PlayMoveArgs) => {
transactions (`readShip`, `readBoard` — a `(t) => value` function) may live
beside them in `transactions/`, but keep it **out of the barrel**, or it gets
registered as a dispatchable transaction. (These are related helpers, so they
belong here, not in a separate folder — `cohesion.md`'s peer-level caution
belong here, not in a separate folder — `global/cohesion.md`'s peer-level caution
doesn't apply.)
4 changes: 2 additions & 2 deletions packages/data-ai/.claude/rules/features/ui/binding-element.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ Presentation files (`*-presentation.ts`), CSS files (`*.css.ts`), tests (`*.test
A binding element is a thin wire between a service and a presentation. The class body contains:

1. Optional static `styles` property definition
2. Zero or more `@property` declarations (whitelisted below).
2. Zero or more `@property` declarations (allowed below).
3. One `render()` method whose body is: one `useObservableValues(...)` call, another lifecycle hook call (in rare cases), a null-guard, and
`return presentation.render({ ...values, ...callbacks })`.

No other members. No `@state`. No private handler fields. No lifecycle methods (`connectedCallback`, `updated`, `firstUpdated`,
`disconnectedCallback`) except on app-entrypoint classes where the lifecycle concern is app-boot shaped but cannot be expressed as a hook
(see `.claude/rules/hooks.md` for hook-first lifecycle).

## `@property` whitelist
## `@property` allowlist

The allowed set depends on **class role**:

Expand Down
2 changes: 1 addition & 1 deletion packages/data-ai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

AI architecture skills + rules for building applications with
[`@adobe/data`](https://www.npmjs.com/package/@adobe/data) — a layered,
spec-first feature structure (`data → ecs → ui`) kept honest by conformance
spec-first feature structure (`data → services → ui`) kept honest by conformance
tests. Versioned in lockstep with the library: `@adobe/data-ai@x.y.z` targets
`@adobe/data@x.y.z`.

Expand Down
54 changes: 51 additions & 3 deletions packages/data-ai/bin/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ function notice(extra) {

The files in this folder are installed and managed by the \`${PKG_NAME}\`
package. This entire directory is **deleted and rebuilt** on every
\`npx ${PKG_NAME} install\`, so any local edit here is silently discarded on the
next reinstall or version upgrade.
\`npx ${PKG_NAME}@${VERSION} install\`, so any local edit here is silently discarded on
the next reinstall or version upgrade.

To change them, edit upstream in the \`${PKG_NAME}\` package and publish a new
version, then reinstall — do not modify these files in place.
Expand All @@ -66,10 +66,21 @@ function writeMeta(bundleDir, noticeBody, extraMeta) {
);
}

// Skills that author/evolve the bundle itself (the self-improvement loop and its
// rule review). They mutate or critique the managed files, so they belong only to
// the source repo — never a consumer install, where those files are read-only
// managed copies. Both also carry `disable-model-invocation: true`.
const MAINTAINER_ONLY = new Set(["meta-build", "review"]);

function discoverSkills() {
if (!existsSync(skillsSrc)) return [];
return readdirSync(skillsSrc, { withFileTypes: true })
.filter((d) => d.isDirectory() && existsSync(join(skillsSrc, d.name, "SKILL.md")))
.filter(
(d) =>
d.isDirectory() &&
!MAINTAINER_ONLY.has(d.name) &&
existsSync(join(skillsSrc, d.name, "SKILL.md")),
)
.map((d) => d.name)
.sort();
}
Expand Down Expand Up @@ -111,6 +122,41 @@ function installRules(base) {
return bundleDir;
}

// A single managed rule (namespaced by its `adobe-data-ai-` filename prefix) telling
// an agent to (re)install the bundle when the skills are absent — pinned to THIS
// reviewed version, never `@latest`, so a drifted or compromised release cannot execute
// during install. Rewritten with the matching version on every install. It sits beside
// (not inside) the wiped bundle dir, so it survives and is simply overwritten.
function installBootstrap(base) {
const file = join(base, ".claude", "rules", `${BUNDLE}-bootstrap.md`);
mkdirSync(dirname(file), { recursive: true });
writeFileSync(
file,
`---
paths:
- '**/features/*/data/**/*.ts'
- '**/features/*/services/**/*.ts'
- '**/features/*/ui/**/*.ts'
---

# ${PKG_NAME} skills — ensure installed

Before using an \`@adobe/data\` build workflow, confirm the skills are present: look for
a skill named \`build-feature\` (or \`build-application\`). If it is missing, install the
pinned, reviewed bundle, then re-check:

\`\`\`sh
npx ${PKG_NAME}@${VERSION} install
\`\`\`

Pin the version to the reviewed bundle (never \`@latest\`) so a compromised or drifted
release cannot execute during install. This file is regenerated with the matching
version on every install. Package: <https://www.npmjs.com/package/${PKG_NAME}>
`,
);
return file;
}

function parseArgs(argv) {
const positional = [];
const flags = new Set();
Expand Down Expand Up @@ -176,11 +222,13 @@ function main() {
const base = flags.has("global") ? homedir() : dir ? resolve(dir) : process.cwd();
const skillsDir = installSkills(base, skills);
const rulesDir = installRules(base);
const bootstrapFile = installBootstrap(base);
const ruleCount = countRules(rulesSrc);

process.stdout.write(`Installed ${PKG_NAME} v${VERSION}\n`);
process.stdout.write(` ${skills.length} skills → ${skillsDir}\n`);
process.stdout.write(` ${ruleCount} rules → ${rulesDir}\n`);
process.stdout.write(` bootstrap → ${bootstrapFile}\n`);
}

main();
2 changes: 1 addition & 1 deletion packages/data-ai/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-ai",
"version": "0.9.90",
"version": "0.9.91",
"description": "Cross-agent architecture skills for @adobe/data — installable as a Claude Code plugin or copied into any Agent-Skills-compatible agent (Cursor, Codex).",
"type": "module",
"private": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-ai/skills/build-data/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ The schema is the single source of truth; the type derives from it (`Schema.ToTy
Helpers are pure and unit-tested. Run this first — every other layer imports `data/`.

The how is in the auto-loading rules: `features/data/index.md`, `features/data/state.md`, and
`namespace.md`.
`global/namespace.md`.
2 changes: 1 addition & 1 deletion packages/data-ai/skills/build-services/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ and `create*` factories.

Only if the feature talks to the outside world. Comes after `data/`, before `services/main-service/`.

The how is in the auto-loading `features/services/index.md` rule (and `namespace.md`).
The how is in the auto-loading `features/services/index.md` rule (and `global/namespace.md`).
5 changes: 4 additions & 1 deletion packages/data-ai/skills/build-systems/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ Skip if this feature doesn't contain or require systems.
Most games that use a canvas will use systems but most applications will not.

Create `services/main-service/system-database/system-database.ts`: `Database.Plugin.create({ extends:
Database.Plugin.combine(ComputedDatabase.plugin, scheduler), systems })` where the `systems`
Database.Plugin.combine(<currentTop>.plugin, scheduler), systems })` — combine `scheduler` with the
feature's **current top** main-service layer (`ActionDatabase` / `ServiceDatabase` / `ComputedDatabase`,
whichever it built), never a hardcoded `ComputedDatabase`, so systems *and* any services/actions
compose into the one `FeatureDatabase`. The `systems`
map is declared **inline** (see `features/services/main-service/systems.md` — inline is required for `db` to be
typed and for system-name inference; a `systems/` folder is optional, only for extracted
per-frame body helpers).
Expand Down
3 changes: 2 additions & 1 deletion packages/data-ai/skills/build-transactions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ input: feature
output: feature
---

Create `services/main-service/transaction-database/`: `transaction-database.ts` (extends `IndexDatabase`, adds
Create `services/main-service/transaction-database/`: `transaction-database.ts` (extends the
preceding layer — `IndexDatabase` if the feature built indexes, else `CoreDatabase` — adds
`transactions` from `./transactions/index.js`) plus a `transactions/` folder — one mutation per
file + barrel. Type the store param `CoreDatabase.Store` (entities/resources/archetypes) or
`IndexDatabase.Store` (reads an index).
Expand Down
1 change: 1 addition & 0 deletions packages/data-ai/skills/meta-build/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: meta-build
disable-model-invocation: true
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.
input: a prompt describing the application or game to build
options:
Expand Down
1 change: 1 addition & 0 deletions packages/data-ai/skills/review/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: review
disable-model-invocation: true
description: Review built feature/application output against the @adobe/data feature rules; report whether it is optimal and where any fix belongs. Read-only.
input: a path to built output (a layer, a feature, or a whole app)
output: a review — OPTIMAL, or a list of issues each tagged code | skill | rule
Expand Down
2 changes: 1 addition & 1 deletion packages/data-gpu-hopper/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-gpu-hopper",
"version": "0.9.90",
"version": "0.9.91",
"description": "Hopper sample - real-time ECS game rendered as colored cubes via @adobe/data-gpu",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-gpu-samples/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-gpu-samples",
"version": "0.9.90",
"version": "0.9.91",
"description": "WebGPU samples built on @adobe/data-gpu",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-gpu/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-gpu",
"version": "0.9.90",
"version": "0.9.91",
"description": "Adobe data WebGPU plugins and types for graphics and compute",
"type": "module",
"private": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-lit-space-rock-game/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-lit-space-rock-game",
"version": "0.9.90",
"version": "0.9.91",
"description": "Space Rock Game sample - real-time ECS game with Lit and @adobe/data",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-lit-tictactoe/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-lit-tictactoe",
"version": "0.9.90",
"version": "0.9.91",
"description": "Tic-Tac-Toe sample - Lit web components with @adobe/data-lit and AgenticService",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-lit-todo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-lit-todo",
"version": "0.9.90",
"version": "0.9.91",
"description": "Todo application - Lit web components with @adobe/data ECS",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-lit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-lit",
"version": "0.9.90",
"version": "0.9.91",
"description": "Adobe data Lit bindings - hooks, elements, decorators",
"type": "module",
"private": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-p2p-tictactoe/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-p2p-tictactoe",
"version": "0.9.90",
"version": "0.9.91",
"description": "Serverless P2P tic-tac-toe — WebRTC DataChannel + @adobe/data-sync",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-persistence/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-persistence",
"version": "0.9.90",
"version": "0.9.91",
"description": "Worker-based incremental persistence layer for @adobe/data ECS over OPFS (browser) and node:fs (server).",
"type": "module",
"sideEffects": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-react-hello/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-react-hello",
"version": "0.9.90",
"version": "0.9.91",
"description": "Hello World sample - click counter using @adobe/data-react",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-react-pixie/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-react-pixie",
"version": "0.9.90",
"version": "0.9.91",
"description": "PixiJS React sample - ECS sprites (bunny, fox) with @adobe/data-react",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-react",
"version": "0.9.90",
"version": "0.9.91",
"description": "Adobe data React bindings — hooks and context for ECS database",
"type": "module",
"private": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-solid-dashboard/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-solid-dashboard",
"version": "0.9.90",
"version": "0.9.91",
"description": "Mini dashboard sample — multiple components sharing one @adobe/data ECS database with SolidJS",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-solid/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-solid",
"version": "0.9.90",
"version": "0.9.91",
"description": "Adobe data SolidJS bindings — context and provider for ECS database",
"type": "module",
"private": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-sync/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-sync",
"version": "0.9.90",
"version": "0.9.91",
"description": "Multi-user real-time synchronisation for @adobe/data ECS — server, client, and in-process loopback.",
"type": "module",
"sideEffects": false,
Expand Down
Loading