@adobe/data-ai 0.9.91 → 0.9.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/rules/data-modelling.md +4 -3
- package/.claude/rules/ecs.md +1 -1
- package/.claude/rules/element.md +1 -1
- package/.claude/rules/features/data/index.md +59 -14
- package/.claude/rules/features/data/state.md +204 -44
- package/.claude/rules/features/index.md +29 -10
- package/.claude/rules/features/services/index.md +19 -0
- package/.claude/rules/features/services/main-service/actions.md +39 -5
- package/.claude/rules/features/services/main-service/computed.md +54 -3
- package/.claude/rules/features/services/main-service/conformance.md +209 -62
- package/.claude/rules/features/services/main-service/index.md +14 -10
- package/.claude/rules/features/services/main-service/services.md +8 -7
- package/.claude/rules/features/services/main-service/transactions.md +15 -6
- package/.claude/rules/features/ui/binding-element.md +4 -4
- package/.claude/rules/global/namespace.md +38 -10
- package/.claude/rules/global/react.md +1 -1
- package/.claude/rules/lit.md +3 -3
- package/.claude/rules/observe.md +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +82 -32
- package/bin/cli.mjs +84 -2
- package/package.json +3 -3
- package/skills/build-app-entry/SKILL.md +1 -1
- package/skills/build-data/SKILL.md +2 -2
- package/skills/build-systems/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -11,46 +11,95 @@ It installs two things:
|
|
|
11
11
|
- **skills** — `build-*` commands that scaffold features and applications.
|
|
12
12
|
- **rules** — the path-scoped conventions those skills follow while building.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
> **update** — it never touches files you authored.
|
|
14
|
+
The **rules** are the part that evolves often, so `install` pins the package and
|
|
15
|
+
re-copies them automatically on every install: bump the version and they refresh —
|
|
16
|
+
no manual step, no committed diff, no hand-editing.
|
|
18
17
|
|
|
19
|
-
##
|
|
18
|
+
## Quick start
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
From your project folder root:
|
|
21
|
+
|
|
22
|
+
**1. Install** — one command:
|
|
23
23
|
|
|
24
24
|
```
|
|
25
|
-
claude plugin marketplace add adobe/data --scope project
|
|
26
|
-
claude plugin install adobe-data-ai@adobe-data-skills --scope project
|
|
27
25
|
npx @adobe/data-ai@latest install
|
|
28
26
|
```
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
the
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
*(Claude Code only:* also add the skills plugin once — see
|
|
29
|
+
[Claude Code](#claude-code--add-the-skills-plugin-one-time). Cursor/Codex need
|
|
30
|
+
nothing extra; `install` copies their skills.*)*
|
|
31
|
+
|
|
32
|
+
**2. Restart your AI agent** so it loads the newly installed skills and rules.
|
|
33
|
+
|
|
34
|
+
**3. Create an application** — ask your agent:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
/build-application <a description of the app you want>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
That's the whole flow. Everything below explains what `install` does and the
|
|
41
|
+
other build skills available.
|
|
42
|
+
|
|
43
|
+
## What `install` does
|
|
44
|
+
|
|
45
|
+
`install` does two things: it **copies the bundle now** (rules →
|
|
46
|
+
`.claude/rules/adobe-data-ai/`, and for Cursor/Codex skills →
|
|
47
|
+
`.agents/skills/adobe-data-ai/`), and it **wires the repo so future installs
|
|
48
|
+
self-update**, editing your `package.json` and `.gitignore` to:
|
|
35
49
|
|
|
36
|
-
|
|
37
|
-
|
|
50
|
+
1. pin `@adobe/data-ai` in `devDependencies` at the **exact version it just
|
|
51
|
+
resolved** (never a range, so a later install can't silently pull an
|
|
52
|
+
unreviewed release);
|
|
53
|
+
2. add `data-ai install` to **your own** `postinstall` script (chaining if one
|
|
54
|
+
exists) — it must be *your* script: pnpm does not run a dependency's lifecycle
|
|
55
|
+
scripts, so a `postinstall` shipped inside the package would silently not fire;
|
|
56
|
+
3. gitignore the managed bundle folders.
|
|
38
57
|
|
|
39
|
-
|
|
58
|
+
The copied files are regenerated artifacts — never committed, never edited in
|
|
59
|
+
place. The wiring is idempotent, so re-running is harmless; with `--global` or in a
|
|
60
|
+
directory with no `package.json`, `install` just copies (no wiring).
|
|
40
61
|
|
|
41
|
-
|
|
62
|
+
After that first run, sync your lockfile with a normal install (`pnpm install`) so
|
|
63
|
+
the pinned dev-dependency is recorded; from then on every install refreshes the
|
|
64
|
+
bundle via the postinstall.
|
|
65
|
+
|
|
66
|
+
**Why `@latest` for the first command but a pinned version afterward?** The one
|
|
67
|
+
command you type is a one-time, human-initiated bootstrap, so `@latest` is fine
|
|
68
|
+
(the same posture as `npm create …@latest`). The part that *repeats* — every
|
|
69
|
+
teammate's and CI's install — runs from the **exact version `install` pinned into
|
|
70
|
+
your `devDependencies`**, never a moving tag, so no unreviewed release ever
|
|
71
|
+
auto-executes. Pinning happens where it matters, automatically.
|
|
72
|
+
|
|
73
|
+
**Update:** bump the `@adobe/data-ai` version in `package.json` and install again.
|
|
74
|
+
That's it.
|
|
75
|
+
|
|
76
|
+
### Claude Code — add the skills plugin (one time)
|
|
77
|
+
|
|
78
|
+
Claude Code loads skills from a marketplace plugin, not from `.claude/skills/`, so
|
|
79
|
+
its skills are a separate one-time install (the `install` step above already
|
|
80
|
+
handles the rules for Claude Code):
|
|
42
81
|
|
|
43
82
|
```
|
|
44
|
-
|
|
83
|
+
claude plugin marketplace add adobe/data --scope project
|
|
84
|
+
claude plugin install adobe-data-ai@adobe-data-skills --scope project
|
|
45
85
|
```
|
|
46
86
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
87
|
+
(Interactive sessions can use `/plugin marketplace add adobe/data` then
|
|
88
|
+
`/plugin install adobe-data-ai@adobe-data-skills`.) **Update the skills:**
|
|
89
|
+
`claude plugin update adobe-data-ai`. Cursor/Codex need no plugin — `install`
|
|
90
|
+
copies their skills too.
|
|
91
|
+
|
|
92
|
+
### Just the files, no managed dependency
|
|
50
93
|
|
|
51
|
-
|
|
94
|
+
If you don't want the auto-update wiring — a throwaway scaffold, a non-Node repo,
|
|
95
|
+
or you'd rather commit the bundle and update it on your own schedule — run
|
|
96
|
+
`install` where it can't wire (no `package.json`, or pass `--global`), or simply
|
|
97
|
+
delete the `postinstall`/dev-dependency lines it added. Re-running `install` is
|
|
98
|
+
always a clean wipe-and-recopy; you then update by re-running it yourself.
|
|
52
99
|
|
|
53
|
-
|
|
100
|
+
## Build skills
|
|
101
|
+
|
|
102
|
+
Step 3 above uses `build-application`; the skills are available by name:
|
|
54
103
|
|
|
55
104
|
- **`build-application`** — build a whole app: a base feature that hosts
|
|
56
105
|
lazily-loaded peer features.
|
|
@@ -66,15 +115,16 @@ by name when you want a single phase or a specialized flow: `build-data`,
|
|
|
66
115
|
in subagents), `review` (audit output against the rules), and `structure`
|
|
67
116
|
(reason about layout).
|
|
68
117
|
|
|
69
|
-
## One-liner: install + build an app
|
|
70
|
-
|
|
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.
|
|
118
|
+
## One-liner: install + build an app (headless)
|
|
74
119
|
|
|
75
|
-
|
|
120
|
+
Paste this into an agent already running in your project root, replacing the
|
|
121
|
+
quoted text with your own app description. It installs the bundle, then runs
|
|
122
|
+
`build-application` on your prompt:
|
|
76
123
|
|
|
77
124
|
```
|
|
78
|
-
|
|
79
|
-
|
|
125
|
+
Set up @adobe/data-ai in the current directory: run
|
|
126
|
+
`npx @adobe/data-ai@latest install` (this copies the bundle and pins the exact
|
|
127
|
+
version so rules auto-update on every install). On Claude Code also add the
|
|
128
|
+
skills plugin per the package README. Then use its /build-application skill to
|
|
129
|
+
build <prompt here>
|
|
80
130
|
```
|
package/bin/cli.mjs
CHANGED
|
@@ -157,6 +157,78 @@ version on every install. Package: <https://www.npmjs.com/package/${PKG_NAME}>
|
|
|
157
157
|
return file;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
// Wire the consumer repo for auto-updating installs (part of `install`, not a
|
|
161
|
+
// separate step). Idempotently:
|
|
162
|
+
// 1. pins `@adobe/data-ai` in devDependencies (exact version — never a range,
|
|
163
|
+
// so an install can't silently pull an unreviewed release),
|
|
164
|
+
// 2. adds `data-ai install` to the consumer's OWN `postinstall` (a dependency's
|
|
165
|
+
// lifecycle script does NOT run under pnpm, so it must live here), and
|
|
166
|
+
// 3. gitignores the managed, regenerated bundle folders.
|
|
167
|
+
// After this, bumping the pinned version and re-installing recopies the bundle —
|
|
168
|
+
// no manual step, no committed diff. Skips gracefully with a note when there is
|
|
169
|
+
// no package.json (the bundle is still copied; the repo just isn't auto-wired).
|
|
170
|
+
const MANAGED_GITIGNORE = [
|
|
171
|
+
`# ${PKG_NAME} — managed, regenerated on install; do not edit or commit`,
|
|
172
|
+
".claude/rules/adobe-data-ai/",
|
|
173
|
+
".claude/rules/adobe-data-ai-bootstrap.md",
|
|
174
|
+
".agents/skills/adobe-data-ai/",
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
function wireManagedUpdates(base) {
|
|
178
|
+
const pkgPath = join(base, "package.json");
|
|
179
|
+
if (!existsSync(pkgPath)) {
|
|
180
|
+
process.stdout.write(
|
|
181
|
+
` (no package.json in ${base} — auto-update not wired; the bundle was still copied.\n` +
|
|
182
|
+
` Add one, re-run install to wire it, or re-run manually to update.)\n`,
|
|
183
|
+
);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const consumer = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
187
|
+
const changes = [];
|
|
188
|
+
|
|
189
|
+
// 1. pinned devDependency
|
|
190
|
+
consumer.devDependencies ??= {};
|
|
191
|
+
let pinnedDep = false;
|
|
192
|
+
if (consumer.devDependencies[PKG_NAME] !== VERSION) {
|
|
193
|
+
consumer.devDependencies[PKG_NAME] = VERSION;
|
|
194
|
+
changes.push(`devDependencies["${PKG_NAME}"] = "${VERSION}" (exact)`);
|
|
195
|
+
pinnedDep = true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// 2. own postinstall runs the installer (chain if one already exists)
|
|
199
|
+
consumer.scripts ??= {};
|
|
200
|
+
const INSTALL = "data-ai install";
|
|
201
|
+
const post = consumer.scripts.postinstall;
|
|
202
|
+
if (!post) {
|
|
203
|
+
consumer.scripts.postinstall = INSTALL;
|
|
204
|
+
changes.push(`scripts.postinstall = "${INSTALL}"`);
|
|
205
|
+
} else if (!post.includes(INSTALL)) {
|
|
206
|
+
consumer.scripts.postinstall = `${post} && ${INSTALL}`;
|
|
207
|
+
changes.push(`scripts.postinstall += " && ${INSTALL}"`);
|
|
208
|
+
}
|
|
209
|
+
if (changes.length) writeFileSync(pkgPath, JSON.stringify(consumer, null, 2) + "\n");
|
|
210
|
+
|
|
211
|
+
// 3. gitignore the managed bundle folders
|
|
212
|
+
const giPath = join(base, ".gitignore");
|
|
213
|
+
const gi = existsSync(giPath) ? readFileSync(giPath, "utf8") : "";
|
|
214
|
+
if (!gi.includes(MANAGED_GITIGNORE[0])) {
|
|
215
|
+
const sep = gi === "" ? "" : gi.endsWith("\n") ? "\n" : "\n\n";
|
|
216
|
+
writeFileSync(giPath, gi + sep + MANAGED_GITIGNORE.join("\n") + "\n");
|
|
217
|
+
changes.push(".gitignore += managed bundle paths");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
for (const c of changes) process.stdout.write(` wired: ${c}\n`);
|
|
221
|
+
if (!changes.length) process.stdout.write(" auto-update already wired\n");
|
|
222
|
+
// Adding/repinning the dev-dependency leaves the lockfile out of sync until a
|
|
223
|
+
// normal install records it (and CI with a frozen lockfile would fail until then).
|
|
224
|
+
if (pinnedDep) {
|
|
225
|
+
process.stdout.write(
|
|
226
|
+
"\nNext: run your package manager's install to sync the lockfile\n" +
|
|
227
|
+
" pnpm install # or npm install / yarn\n",
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
160
232
|
function parseArgs(argv) {
|
|
161
233
|
const positional = [];
|
|
162
234
|
const flags = new Set();
|
|
@@ -177,11 +249,17 @@ Install the architecture skills + rules for Cursor, Codex, and other agents.
|
|
|
177
249
|
same way for every agent — see README.)
|
|
178
250
|
|
|
179
251
|
Usage:
|
|
180
|
-
npx ${PKG_NAME}@latest install
|
|
252
|
+
npx ${PKG_NAME}@latest install # copy the bundle AND wire auto-updates (default)
|
|
181
253
|
npx ${PKG_NAME}@latest list
|
|
182
254
|
|
|
183
255
|
Commands:
|
|
184
|
-
install
|
|
256
|
+
install Copy the bundle (skills → .agents/skills/${BUNDLE}/, rules →
|
|
257
|
+
.claude/rules/${BUNDLE}/) AND wire this repo for auto-updating installs:
|
|
258
|
+
pin ${PKG_NAME} in devDependencies (exact), add \`data-ai install\` to the
|
|
259
|
+
repo's own postinstall, and gitignore the managed bundle folders. Run once;
|
|
260
|
+
thereafter a plain install refreshes the bundle and bumping the pinned
|
|
261
|
+
version updates it. Skips the wiring (copies only) with \`--global\` or when
|
|
262
|
+
there's no package.json.
|
|
185
263
|
list Print the skills bundled in this package.
|
|
186
264
|
|
|
187
265
|
Options:
|
|
@@ -229,6 +307,10 @@ function main() {
|
|
|
229
307
|
process.stdout.write(` ${skills.length} skills → ${skillsDir}\n`);
|
|
230
308
|
process.stdout.write(` ${ruleCount} rules → ${rulesDir}\n`);
|
|
231
309
|
process.stdout.write(` bootstrap → ${bootstrapFile}\n`);
|
|
310
|
+
|
|
311
|
+
// A project install also wires the repo for auto-updating installs (idempotent).
|
|
312
|
+
// A global install has no consumer package.json to wire, so it only copies.
|
|
313
|
+
if (!flags.has("global")) wireManagedUpdates(base);
|
|
232
314
|
}
|
|
233
315
|
|
|
234
316
|
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/data-ai",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.93",
|
|
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.
|
|
32
|
+
"@adobe/data": "0.9.93"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"typescript": "^5.8.3",
|
|
36
36
|
"vitest": "^1.6.0",
|
|
37
|
-
"@adobe/data": "0.9.
|
|
37
|
+
"@adobe/data": "0.9.93"
|
|
38
38
|
},
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"scripts": {
|
|
@@ -9,7 +9,7 @@ output: app
|
|
|
9
9
|
plugin, so all schemas coexist, persist, and sync while the base type stays decoupled.
|
|
10
10
|
- The base reaches a peer only through a lazy element wrapper (dynamic import), so peers
|
|
11
11
|
load on demand.
|
|
12
|
-
- The entry point creates the live database from `
|
|
12
|
+
- The entry point creates the live database from `MainService.plugin` (the base
|
|
13
13
|
feature's assembled database — see `features/services/main-service/index.md`) and mounts the root UI.
|
|
14
14
|
|
|
15
15
|
See `features/index.md` (one-app-many-features) for the wiring rules.
|
|
@@ -8,14 +8,14 @@ output: feature
|
|
|
8
8
|
Create the feature's `data/` layer (pure spec; depends on nothing but `@adobe/data`
|
|
9
9
|
and other `data/` declarations):
|
|
10
10
|
|
|
11
|
-
- one namespace folder per data type — `<type>/{<type>.ts,
|
|
11
|
+
- one namespace folder per data type — `<type>/{<type>.ts, public.ts, <helper>.ts}` (+ `schema.ts` only when a runtime boundary needs it);
|
|
12
12
|
- `data/state/` — the `State` aggregate plus its pure transforms/derivations.
|
|
13
13
|
|
|
14
14
|
**Always create `data/state/`** — even for a shell feature whose only field is a
|
|
15
15
|
boolean or enum. A feature with ECS resources/transactions but no `State` is
|
|
16
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
17
|
|
|
18
|
-
The
|
|
18
|
+
The hand-authored type in `<type>.ts` is the source of truth. The schema is optional up front — add `schema.ts` only when a runtime boundary (persistence, wire, or an ECS component/resource) needs one, write it to match the type, and pin it with `type _Pin = Assert<Equal<Schema.ToType<typeof schema>, <Type>>>` so it cannot drift. `Schema.ToType` is used only in that assertion, never as the exported type.
|
|
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
|
|
@@ -12,7 +12,7 @@ Create `services/main-service/system-database/system-database.ts`: `Database.Plu
|
|
|
12
12
|
Database.Plugin.combine(<currentTop>.plugin, scheduler), systems })` — combine `scheduler` with the
|
|
13
13
|
feature's **current top** main-service layer (`ActionDatabase` / `ServiceDatabase` / `ComputedDatabase`,
|
|
14
14
|
whichever it built), never a hardcoded `ComputedDatabase`, so systems *and* any services/actions
|
|
15
|
-
compose into the one `
|
|
15
|
+
compose into the one `MainService`. The `systems`
|
|
16
16
|
map is declared **inline** (see `features/services/main-service/systems.md` — inline is required for `db` to be
|
|
17
17
|
typed and for system-name inference; a `systems/` folder is optional, only for extracted
|
|
18
18
|
per-frame body helpers).
|