@adobe/data-ai 0.9.82 → 0.9.84
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/README.md +42 -0
- package/.claude/rules/archetypes.md +60 -0
- package/.claude/rules/cohesion.md +66 -0
- package/.claude/rules/data-modelling.md +71 -0
- package/.claude/rules/element.md +130 -0
- package/.claude/rules/features/data/index.md +35 -0
- package/.claude/rules/features/data/state.md +54 -0
- package/.claude/rules/features/ecs/actions.md +32 -0
- package/.claude/rules/features/ecs/archetypes.md +46 -0
- package/.claude/rules/features/ecs/components.md +41 -0
- package/.claude/rules/features/ecs/computed.md +26 -0
- package/.claude/rules/features/ecs/conformance.md +69 -0
- package/.claude/rules/features/ecs/index.md +179 -0
- package/.claude/rules/features/ecs/indexes.md +63 -0
- package/.claude/rules/features/ecs/resources.md +28 -0
- package/.claude/rules/features/ecs/services.md +24 -0
- package/.claude/rules/features/ecs/systems.md +133 -0
- package/.claude/rules/features/ecs/transactions.md +45 -0
- package/.claude/rules/features/index.md +95 -0
- package/.claude/rules/features/services/index.md +34 -0
- package/.claude/rules/features/ui/index.md +31 -0
- package/.claude/rules/function-references.md +35 -0
- package/.claude/rules/lazy-element.md +127 -0
- package/.claude/rules/namespace.md +179 -0
- package/.claude/rules/plugin-modelling.md +170 -0
- package/.claude/rules/presentation.md +83 -0
- package/.claude/rules/type-casts.md +94 -0
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +39 -81
- package/bin/cli.mjs +81 -26
- package/package.json +9 -2
- package/skills/build-actions/SKILL.md +14 -0
- package/skills/build-app-entry/SKILL.md +15 -0
- package/skills/build-application/SKILL.md +10 -0
- package/skills/build-computed/SKILL.md +14 -0
- package/skills/build-core-database/SKILL.md +24 -0
- package/skills/build-data/SKILL.md +18 -0
- package/skills/build-feature/SKILL.md +21 -0
- package/skills/build-game/SKILL.md +19 -0
- package/skills/build-indexes/SKILL.md +14 -0
- package/skills/build-service-database/SKILL.md +16 -0
- package/skills/build-services/SKILL.md +14 -0
- package/skills/build-systems/SKILL.md +24 -0
- package/skills/build-transactions/SKILL.md +15 -0
- package/skills/build-ui/SKILL.md +13 -0
- package/skills/meta-build/SKILL.md +43 -0
- package/skills/review/SKILL.md +25 -0
- package/skills/structure/SKILL.md +7 -0
- package/skills/x-alpha/SKILL.md +7 -0
- package/skills/x-beta/SKILL.md +7 -0
- package/skills/x-double/SKILL.md +7 -0
- package/skills/x-execute/SKILL.md +16 -0
- package/skills/x-log/SKILL.md +12 -0
- package/skills/x-pow/SKILL.md +9 -0
- package/skills/x-subagent/SKILL.md +8 -0
- package/skills/x-trace/SKILL.md +11 -0
- package/skills/x-validate/SKILL.md +67 -0
- package/skills/bar/SKILL.md +0 -8
- 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.
|
package/README.md
CHANGED
|
@@ -1,102 +1,60 @@
|
|
|
1
1
|
# @adobe/data-ai
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
9
|
+
It installs two things:
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
- **skills** — `build-*` commands that scaffold features and applications.
|
|
12
|
+
- **rules** — the path-scoped conventions those skills follow while building.
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
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
|
|
19
|
+
## Install — Claude Code
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
```sh
|
|
17
|
-
npx @adobe/data-ai@latest install
|
|
18
|
-
```
|
|
19
|
-
|
|
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:
|
|
23
|
-
|
|
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
|
-
```
|
|
29
|
-
|
|
30
|
-
## Install (Claude Code plugin)
|
|
31
|
-
|
|
32
|
-
Claude Code does not scan `.agents/`; it consumes the skills as a native plugin from the `adobe/data` marketplace — no npm needed.
|
|
33
|
-
|
|
34
|
-
Interactive:
|
|
21
|
+
Skills load as a marketplace plugin; rules install into the project.
|
|
35
22
|
|
|
36
23
|
```
|
|
37
24
|
/plugin marketplace add adobe/data
|
|
38
25
|
/plugin install adobe-data-ai@adobe-data-skills
|
|
26
|
+
npx @adobe/data-ai@latest install
|
|
39
27
|
```
|
|
40
28
|
|
|
41
|
-
|
|
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
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
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.
|
|
29
|
+
- Skills → the `adobe-data-ai` plugin. **Update:** `/plugin` → update `adobe-data-ai`.
|
|
30
|
+
- Rules → `.claude/rules/adobe-data-ai/`. **Update:** re-run `npx @adobe/data-ai@latest install`.
|
|
57
31
|
|
|
58
|
-
|
|
32
|
+
## Install — Cursor (and Codex / other `.agents` agents)
|
|
59
33
|
|
|
60
|
-
|
|
34
|
+
One command installs both:
|
|
61
35
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
## Goals
|
|
67
|
-
|
|
68
|
-
The goal of effective software engineers is to generate a high rate of value per unit time.
|
|
69
|
-
|
|
70
|
-
rate = value / time
|
|
71
|
-
|
|
72
|
-
We can improve the rate by either increasing value or decreasing time.
|
|
73
|
-
|
|
74
|
-
- Quality: Write better applications. ▲value
|
|
75
|
-
- Velocity: Write applications faster. ▼time
|
|
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
|
|
36
|
+
```
|
|
37
|
+
npx @adobe/data-ai@latest install
|
|
38
|
+
```
|
|
86
39
|
|
|
87
|
-
-
|
|
40
|
+
- Skills → `.agents/skills/adobe-data-ai/`.
|
|
41
|
+
- Rules → `.claude/rules/adobe-data-ai/`.
|
|
42
|
+
- **Update:** re-run the same command.
|
|
88
43
|
|
|
89
|
-
|
|
44
|
+
## Use
|
|
90
45
|
|
|
91
|
-
|
|
46
|
+
Ask your agent to run a build command — skills are available by name:
|
|
92
47
|
|
|
93
|
-
|
|
48
|
+
- **`build-application`** — build a whole app: a base feature that hosts
|
|
49
|
+
lazily-loaded peer features.
|
|
50
|
+
- **`build-feature`** — build one feature end to end. Pipes the per-layer skills
|
|
51
|
+
(`data → core-database → transactions → … → ui`), then conformance-tests the
|
|
52
|
+
result against its pure `data/` spec.
|
|
94
53
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- Avoid side effects: Pure functions are easier to comprehend and test.
|
|
54
|
+
Both compose finer-grained skills that are installed alongside and discoverable
|
|
55
|
+
by name when you want a single phase or a specialized flow: `build-data`,
|
|
56
|
+
`build-core-database`, `build-indexes`, `build-transactions`, `build-computed`,
|
|
57
|
+
`build-services`, `build-service-database`, `build-actions`, `build-systems`,
|
|
58
|
+
`build-ui`, `build-app-entry`; plus `build-game`, `meta-build` (phase-by-phase
|
|
59
|
+
in subagents), `review` (audit output against the rules), and `structure`
|
|
60
|
+
(reason about layout).
|
package/bin/cli.mjs
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Installer for the @adobe/data-ai
|
|
2
|
+
// Installer for the @adobe/data-ai bundle (Cursor / Codex / .agents-standard agents).
|
|
3
3
|
//
|
|
4
|
-
//
|
|
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
|
|
10
|
-
// wipe-and-recopy — it never touches
|
|
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/`,
|
|
13
|
-
// copying into `.claude/skills/` could collide with a user's own skills
|
|
14
|
-
//
|
|
15
|
-
//
|
|
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
|
-
|
|
48
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
|
76
|
-
|
|
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
|
|
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
|
|
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
|
|
123
|
-
|
|
124
|
-
|
|
177
|
+
const skillsDir = installSkills(base, skills);
|
|
178
|
+
const rulesDir = installRules(base);
|
|
179
|
+
const ruleCount = countRules(rulesSrc);
|
|
125
180
|
|
|
126
|
-
process.stdout.write(`Installed ${
|
|
127
|
-
process.stdout.write(` ${
|
|
128
|
-
process.stdout.write(`
|
|
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.
|
|
3
|
+
"version": "0.9.84",
|
|
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.84"
|
|
33
|
+
},
|
|
30
34
|
"devDependencies": {
|
|
31
|
-
"
|
|
35
|
+
"typescript": "^5.8.3",
|
|
36
|
+
"vitest": "^1.6.0",
|
|
37
|
+
"@adobe/data": "0.9.84"
|
|
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,14 @@
|
|
|
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.
|
|
4
|
+
input: feature
|
|
5
|
+
output: feature
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Create `ecs/action-database/`: `action-database.ts` (extends `ServiceDatabase`, adds `actions`
|
|
9
|
+
from `./actions/index.js`) plus an `actions/` folder — one async orchestrator per file. An action
|
|
10
|
+
takes `db: ServiceDatabase`, awaits `services/` ports, then commits **exactly one** transaction.
|
|
11
|
+
|
|
12
|
+
The top ecs layer; comes after `service-database`.
|
|
13
|
+
|
|
14
|
+
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,14 @@
|
|
|
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
|
+
Create `ecs/computed-database/`: `computed-database.ts` (extends the previous layer, adds
|
|
9
|
+
`computed` from `./computed/index.js`) plus a `computed/` folder — one `cached` derived value
|
|
10
|
+
per file + barrel. Derivation logic lives in `data/`; a computed only wires a db observable to it.
|
|
11
|
+
|
|
12
|
+
Comes after `transaction-database`.
|
|
13
|
+
|
|
14
|
+
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,18 @@
|
|
|
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
|
+
The schema is the single source of truth; the type derives from it (`Schema.ToType`).
|
|
15
|
+
Helpers are pure and unit-tested. Run this first — every other layer imports `data/`.
|
|
16
|
+
|
|
17
|
+
The how is in the auto-loading rules: `features/data/index.md`, `features/data/state.md`, and
|
|
18
|
+
`namespace.md`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build-feature
|
|
3
|
+
description: Build a complete feature by piping the per-layer build-* skills bottom-up.
|
|
4
|
+
input: feature
|
|
5
|
+
output: feature
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
/build-data
|
|
9
|
+
|> /build-services
|
|
10
|
+
|> /build-core-database
|
|
11
|
+
|> /build-indexes
|
|
12
|
+
|> /build-transactions
|
|
13
|
+
|> /build-computed
|
|
14
|
+
|> /build-systems
|
|
15
|
+
|> /build-service-database
|
|
16
|
+
|> /build-actions
|
|
17
|
+
|> /build-ui
|
|
18
|
+
|
|
19
|
+
Run with /x-execute. Each step is a no-op for a layer the feature doesn't use
|
|
20
|
+
(`build-systems` only for real-time features; `build-services` / `build-service-database` /
|
|
21
|
+
`build-actions` only when the feature has async flows).
|
|
@@ -0,0 +1,19 @@
|
|
|
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. This is where components, archetypes, indexes, and systems all
|
|
19
|
+
carry real weight — see `features/ecs/systems.md`.
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
Create `ecs/index-database/`: `index-database.ts` (extends `CoreDatabase`, adds the `indexes`
|
|
9
|
+
facet from `./indexes/index.js`) plus an `indexes/` folder — one index per file + an `index.ts`
|
|
10
|
+
barrel.
|
|
11
|
+
|
|
12
|
+
Only if the feature needs indexed lookups. Comes after `core-database`.
|
|
13
|
+
|
|
14
|
+
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.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build-services
|
|
3
|
+
description: Build a feature's services/ layer — async capability contracts (ports to the outside world). Optional.
|
|
4
|
+
input: feature
|
|
5
|
+
output: feature
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Create the feature's `services/` layer: one `<name>-service/` namespace folder per async
|
|
9
|
+
contract — an `interface` (validated with `AsyncDataService.IsValid`), async-only members,
|
|
10
|
+
and `create*` factories.
|
|
11
|
+
|
|
12
|
+
Only if the feature talks to the outside world. Comes after `data/`, before `ecs/`.
|
|
13
|
+
|
|
14
|
+
The how is in the auto-loading `features/services/index.md` rule (and `namespace.md`).
|