create-objectstack 17.3.0 → 17.4.0
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/CHANGELOG.md +97 -0
- package/README.md +6 -3
- package/dist/index.js +34 -5
- package/dist/templates/AGENTS.md +9 -3
- package/dist/templates/blank/.github/workflows/ci.yml +67 -0
- package/dist/templates/blank/README.md +9 -2
- package/dist/templates/blank/package.json +2 -1
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,102 @@
|
|
|
1
1
|
# create-objectstack
|
|
2
2
|
|
|
3
|
+
## 17.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4998efa: Scaffolded projects now ship a CI workflow, and a `lint` script for it to run.
|
|
8
|
+
The blank template carries `.github/workflows/ci.yml` — one job, on `push` and
|
|
9
|
+
`pull_request`: checkout, pnpm, Node 22, `pnpm install --frozen-lockfile`, then
|
|
10
|
+
`pnpm validate`, `pnpm lint` and `pnpm typecheck`.
|
|
11
|
+
|
|
12
|
+
`lint` is new to the template (`objectstack lint`). It is not a second spelling
|
|
13
|
+
of `validate`: the two share the authoring-rule engine but only `lint` runs the
|
|
14
|
+
hook-body lowering check, which catches handlers that have silently stopped
|
|
15
|
+
lowering to metadata-only bodies — a change of deployment shape produced by a
|
|
16
|
+
refactor that looks like tidying.
|
|
17
|
+
|
|
18
|
+
The scaffolder already created `.github/` at runtime for a single file
|
|
19
|
+
(`copilot-instructions.md`) while the template's gates shipped as npm scripts
|
|
20
|
+
nothing ever ran, so a fresh project started with no CI at all — and ObjectStack
|
|
21
|
+
metadata mistakes fail silently at runtime, which makes `objectstack validate`
|
|
22
|
+
the only place they surface early. That gate is now unskippable for a human and
|
|
23
|
+
for an AI agent authoring metadata in the project, instead of advisory.
|
|
24
|
+
|
|
25
|
+
Existing projects are unaffected; copy the file from a fresh scaffold to adopt
|
|
26
|
+
it.
|
|
27
|
+
- 813d6c5: `npx create-objectstack` now declares the same TypeScript range as `os init` and
|
|
28
|
+
`os create`, and the value is generated rather than restated.
|
|
29
|
+
|
|
30
|
+
Three scaffolders write a new project's `package.json`, and the range that
|
|
31
|
+
decides whether that project type-checks at all had split: `os init` and
|
|
32
|
+
`os create` emitted `typescript: ^5.3.0` from a shared emission policy, while
|
|
33
|
+
this package's bundled template carried `^6.0.0`. Two projects created the same
|
|
34
|
+
day got different TypeScript **majors** depending on which documented entry
|
|
35
|
+
point the reader followed.
|
|
36
|
+
|
|
37
|
+
- **What changed for a scaffolded project.** Its declared `typescript`
|
|
38
|
+
devDependency floor moves from `^6.0.0` to `^5.3.0`. Both resolve to the same
|
|
39
|
+
installed compiler on a fresh install; what moves is the floor the project
|
|
40
|
+
**declares**, and a floor is a support promise. `^5.3.0` is the promise the
|
|
41
|
+
docs already make — "ObjectStack works with TypeScript 5.3+" on the getting
|
|
42
|
+
started page, "TypeScript 5.3.0 or later" in the deployment troubleshooting
|
|
43
|
+
page — and it is measured rather than assumed: TypeScript 5.3.3 type-checks
|
|
44
|
+
every shape these scaffolders emit with results identical to 6.0.3. The repo's
|
|
45
|
+
own `typescript@^6.0.3` devDependency is deliberately not this value; the same
|
|
46
|
+
doc sentence states both halves ("…but the project itself is built and tested
|
|
47
|
+
against TypeScript 6.x"). `engines.pnpm` was already in agreement and is now
|
|
48
|
+
held there by the same mechanism.
|
|
49
|
+
- **Why the value is generated.** This package cannot import from
|
|
50
|
+
`@objectstack/cli`: the dependency edge runs the other way, and the `npx`
|
|
51
|
+
package must not pull the CLI's package closure. So the values are stamped
|
|
52
|
+
into the bundled template at build time by
|
|
53
|
+
`scripts/sync-scaffold-emission-policy.mjs`, read out of the same
|
|
54
|
+
`SCAFFOLD_*` constants the other two scaffolders import, and
|
|
55
|
+
`pnpm check:scaffold-emission-policy` reddens the moment the inlined values
|
|
56
|
+
disagree with that source. Editing the two into agreement by hand would have
|
|
57
|
+
left them free to diverge again on the next move, silently, for the same
|
|
58
|
+
structural reason — which is how they diverged the first time.
|
|
59
|
+
- fd75728: Scaffolded projects now install the AI skills bundle for **one** agent runtime
|
|
60
|
+
instead of every runtime the skills CLI knows, so the bundle is committed once.
|
|
61
|
+
|
|
62
|
+
**Route B of the two the card offered was taken**, and the choice was measured
|
|
63
|
+
rather than argued. Against `skills@1.5.23` and the 11-skill catalog, the old
|
|
64
|
+
`--all` (shorthand for `--skill '*' --agent '*' -y`) wrote the same bundle to
|
|
65
|
+
three destinations — `.agents/` (46 real files, 604,102 B), `agent/` (46 real
|
|
66
|
+
files, 602,682 B, identical bodies with re-serialised frontmatter) and
|
|
67
|
+
`.claude/` (11 symlinks into `.agents/`). The template's `.gitignore` excluded
|
|
68
|
+
none of it, so a new project's first `git add -A` staged 22 `SKILL.md` paths
|
|
69
|
+
plus 11 symlinks. That reached the initial commit of a real app before anyone
|
|
70
|
+
noticed.
|
|
71
|
+
|
|
72
|
+
The scaffolder now runs
|
|
73
|
+
`npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y`,
|
|
74
|
+
which writes 46 real files to `.claude/skills/` and nothing else: 11 staged
|
|
75
|
+
`SKILL.md` paths, no symlinks, and a clone of that commit has readable skill
|
|
76
|
+
files on every platform.
|
|
77
|
+
|
|
78
|
+
Route A (keep `--all`, exclude the duplicates in the template `_gitignore`) was
|
|
79
|
+
built and cloned, not reasoned about, and both of its shapes were rejected.
|
|
80
|
+
Ignoring `.agents/` and `agent/` while committing `.claude/` gives a fresh
|
|
81
|
+
cloner 11 dangling symlinks and zero readable `SKILL.md`. Ignoring only
|
|
82
|
+
`agent/` works on POSIX but commits 11 symlinks that a `core.symlinks=false`
|
|
83
|
+
clone — git-for-Windows' default — materialises as ordinary files whose whole
|
|
84
|
+
content is the link target. `--all --copy`, the other way to make `.claude/`
|
|
85
|
+
real, fans out to 56 destination directories totalling 33.8 MB. A denylist is
|
|
86
|
+
also the wrong shape regardless of which paths it names: this package does not
|
|
87
|
+
choose the destination set, the skills CLI does, and it moves with that
|
|
88
|
+
package's releases.
|
|
89
|
+
|
|
90
|
+
The cost is the multi-runtime default, and it is paid in the open: the closing
|
|
91
|
+
summary now always prints an **AI Skills** block naming where the bundle landed
|
|
92
|
+
and the one-line command for any other runtime, one agent at a time. The
|
|
93
|
+
bundle is identical whichever agent is named.
|
|
94
|
+
|
|
95
|
+
Existing projects are unaffected. To shrink one that already carries the
|
|
96
|
+
triplicate, delete `.agents/` and `agent/` and re-run the single-agent command
|
|
97
|
+
above; `skills-lock.json` records source and hash, not paths, so it does not
|
|
98
|
+
change.
|
|
99
|
+
|
|
3
100
|
## 17.3.0
|
|
4
101
|
|
|
5
102
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -56,9 +56,12 @@ you so rather than failing as an unknown template.
|
|
|
56
56
|
every object name in the template is re-prefixed to match
|
|
57
57
|
(`blank_note` → `my_app_note`).
|
|
58
58
|
2. Installs dependencies (pnpm if available, otherwise npm).
|
|
59
|
-
3. Installs the ObjectStack AI skills bundle for coding
|
|
60
|
-
|
|
61
|
-
curated `skills/` catalog
|
|
59
|
+
3. Installs the ObjectStack AI skills bundle for **one** coding agent —
|
|
60
|
+
`npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y`,
|
|
61
|
+
scoped to the curated `skills/` catalog. One agent, not `--all`, so the
|
|
62
|
+
bundle lands in exactly one directory (`.claude/skills/`) and a scaffolded
|
|
63
|
+
project commits it once; `src/skills-install.ts` carries the measurement.
|
|
64
|
+
The closing summary prints the same command for any other runtime.
|
|
62
65
|
4. Writes `AGENTS.md` and `.github/copilot-instructions.md` with the project
|
|
63
66
|
conventions — unless the template ships its own.
|
|
64
67
|
|
package/dist/index.js
CHANGED
|
@@ -245,6 +245,19 @@ function pinRuntimeImage(targetDir, version) {
|
|
|
245
245
|
return { pinned: true, tag: version };
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
// src/skills-install.ts
|
|
249
|
+
var SKILLS_CATALOG = "objectstack-ai/objectstack/skills";
|
|
250
|
+
var DEFAULT_SKILLS_AGENT = "claude-code";
|
|
251
|
+
var DEFAULT_SKILLS_DIR = ".claude/skills/";
|
|
252
|
+
var EXAMPLE_OTHER_AGENT = "codex";
|
|
253
|
+
function skillsAddArgs(agent) {
|
|
254
|
+
return `skills add ${SKILLS_CATALOG} --skill '*' --agent ${agent} -y`;
|
|
255
|
+
}
|
|
256
|
+
var SKILLS_INSTALL_COMMAND = `npx -y ${skillsAddArgs(DEFAULT_SKILLS_AGENT)}`;
|
|
257
|
+
function skillsInstallHint(agent) {
|
|
258
|
+
return `npx ${skillsAddArgs(agent)}`;
|
|
259
|
+
}
|
|
260
|
+
|
|
248
261
|
// src/banner.ts
|
|
249
262
|
import chalk from "chalk";
|
|
250
263
|
var PREFIX = " \u25C6 Create ObjectStack ";
|
|
@@ -526,17 +539,20 @@ var program = new Command().name("create-objectstack").description("Create a new
|
|
|
526
539
|
}
|
|
527
540
|
}
|
|
528
541
|
const beforeSkills = topLevelNames(targetDir);
|
|
542
|
+
let skillsInstalled = false;
|
|
529
543
|
if (!options.skipInstall && !options.skipSkills) {
|
|
530
544
|
printStep("Installing AI skills for your coding agent...");
|
|
531
545
|
try {
|
|
532
|
-
execSync2(
|
|
546
|
+
execSync2(SKILLS_INSTALL_COMMAND, {
|
|
533
547
|
stdio: "inherit",
|
|
534
548
|
cwd: targetDir
|
|
535
549
|
});
|
|
550
|
+
skillsInstalled = true;
|
|
536
551
|
console.log("");
|
|
537
552
|
} catch {
|
|
538
553
|
printWarning(
|
|
539
|
-
|
|
554
|
+
`Skills installation skipped. Run manually:
|
|
555
|
+
${skillsInstallHint(DEFAULT_SKILLS_AGENT)}`
|
|
540
556
|
);
|
|
541
557
|
console.log("");
|
|
542
558
|
}
|
|
@@ -560,10 +576,23 @@ var program = new Command().name("create-objectstack").description("Create a new
|
|
|
560
576
|
console.log(chalk2.dim(` ${devLabel.padEnd(labelWidth)}# Start development server`));
|
|
561
577
|
console.log(chalk2.dim(` ${validateLabel.padEnd(labelWidth)}# Verify metadata: schema + predicates + bindings`));
|
|
562
578
|
console.log(chalk2.dim(` ${" ".repeat(labelWidth)}# (run after every metadata edit \u2014 see AGENTS.md)`));
|
|
563
|
-
|
|
564
|
-
|
|
579
|
+
console.log("");
|
|
580
|
+
if (skillsInstalled) {
|
|
581
|
+
console.log(chalk2.bold(" AI Skills:"));
|
|
582
|
+
console.log(
|
|
583
|
+
chalk2.dim(
|
|
584
|
+
` Installed for ${DEFAULT_SKILLS_AGENT} \u2192 ${DEFAULT_SKILLS_DIR} \u2014 commit it with your project.`
|
|
585
|
+
)
|
|
586
|
+
);
|
|
587
|
+
console.log(chalk2.dim(" Using a different agent? Add it one runtime at a time:"));
|
|
588
|
+
console.log(chalk2.dim(` ${skillsInstallHint(EXAMPLE_OTHER_AGENT)}`));
|
|
589
|
+
console.log(chalk2.dim(" (`npx skills add --help` lists every agent name)"));
|
|
590
|
+
} else {
|
|
565
591
|
console.log(chalk2.bold(" AI Skills (recommended):"));
|
|
566
|
-
console.log(chalk2.dim(
|
|
592
|
+
console.log(chalk2.dim(` ${skillsInstallHint(DEFAULT_SKILLS_AGENT)}`));
|
|
593
|
+
console.log(
|
|
594
|
+
chalk2.dim(` Replace \`${DEFAULT_SKILLS_AGENT}\` with your own agent runtime if it differs.`)
|
|
595
|
+
);
|
|
567
596
|
}
|
|
568
597
|
console.log("");
|
|
569
598
|
} catch (error) {
|
package/dist/templates/AGENTS.md
CHANGED
|
@@ -73,13 +73,19 @@ Run `npm run build` when you need the compiled `dist/objectstack.json` artifact.
|
|
|
73
73
|
|
|
74
74
|
## AI Skills
|
|
75
75
|
|
|
76
|
-
This project uses ObjectStack skills from `objectstack-ai/objectstack`.
|
|
77
|
-
|
|
76
|
+
This project uses ObjectStack skills from `objectstack-ai/objectstack`. They
|
|
77
|
+
were installed for one agent runtime, live in `.claude/skills/`, and are
|
|
78
|
+
committed with the project. Install or update them with the standard
|
|
79
|
+
[skills CLI](https://skills.sh/), naming your runtime:
|
|
78
80
|
|
|
79
81
|
```bash
|
|
80
|
-
npx skills add objectstack-ai/objectstack/skills
|
|
82
|
+
npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y
|
|
81
83
|
```
|
|
82
84
|
|
|
85
|
+
Adding a second runtime? Re-run it with that runtime's `--agent` name.
|
|
86
|
+
⛔ Do not use `--all`: it writes the same bundle to `.agents/`, `agent/` and
|
|
87
|
+
`.claude/` at once, and all three then land in your next commit.
|
|
88
|
+
|
|
83
89
|
Skills are triggered automatically based on task context:
|
|
84
90
|
|
|
85
91
|
| Skill | Trigger Context |
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Continuous integration for this ObjectStack app.
|
|
2
|
+
#
|
|
3
|
+
# ObjectStack metadata fails SILENTLY at runtime, not at edit time: a mistyped
|
|
4
|
+
# permission grant or a bare field name in an action predicate raises nothing,
|
|
5
|
+
# it just behaves wrongly for whoever hits it first. `objectstack validate` is
|
|
6
|
+
# where that class surfaces — and running it is something a human, or an AI
|
|
7
|
+
# agent authoring metadata in this project, has to remember. This workflow is
|
|
8
|
+
# what makes it unskippable. AGENTS.md carries the authoring conventions it
|
|
9
|
+
# enforces.
|
|
10
|
+
#
|
|
11
|
+
# One job, one file: a starting point, not a CI framework. Grow it with the
|
|
12
|
+
# project — add a step when you add a script, a second job when you deploy.
|
|
13
|
+
|
|
14
|
+
name: CI
|
|
15
|
+
|
|
16
|
+
on: [push, pull_request]
|
|
17
|
+
|
|
18
|
+
# Read-only. Nothing here writes to the repository or publishes anything.
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
verify:
|
|
24
|
+
name: Validate
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 15
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v7
|
|
29
|
+
|
|
30
|
+
# pnpm BEFORE setup-node, deliberately. `cache: pnpm` below makes
|
|
31
|
+
# setup-node shell out to pnpm to locate the store, so pnpm has to be on
|
|
32
|
+
# PATH by then. Reversed, this does not degrade — the job dies in the
|
|
33
|
+
# setup step with "Unable to locate executable file: pnpm".
|
|
34
|
+
#
|
|
35
|
+
# `version` is explicit because this project declares no `packageManager`
|
|
36
|
+
# field — pinning one would make the project pnpm-only, and a
|
|
37
|
+
# corepack-driven npm or yarn then refuses to run in it — so
|
|
38
|
+
# pnpm/action-setup has nothing to resolve from. Keep this in step with
|
|
39
|
+
# the `engines.pnpm` floor in package.json.
|
|
40
|
+
- uses: pnpm/action-setup@v6
|
|
41
|
+
with:
|
|
42
|
+
version: 10
|
|
43
|
+
|
|
44
|
+
- uses: actions/setup-node@v7
|
|
45
|
+
with:
|
|
46
|
+
node-version: '22'
|
|
47
|
+
cache: pnpm
|
|
48
|
+
|
|
49
|
+
# `--frozen-lockfile` installs exactly what the lockfile records and fails
|
|
50
|
+
# when the two disagree, so `pnpm-lock.yaml` has to be committed.
|
|
51
|
+
# Scaffolding wrote it for you unless you passed `--skip-install`; in that
|
|
52
|
+
# case run `pnpm install` once and commit the result.
|
|
53
|
+
- run: pnpm install --frozen-lockfile
|
|
54
|
+
|
|
55
|
+
# The gate this file exists for: schema, CEL predicates and widget
|
|
56
|
+
# bindings. The same checks `pnpm build` runs, without producing an
|
|
57
|
+
# artifact.
|
|
58
|
+
- run: pnpm validate
|
|
59
|
+
|
|
60
|
+
# Not a second spelling of `validate`. The two share the authoring-rule
|
|
61
|
+
# engine but not the rule set — the hook-body lowering check, which
|
|
62
|
+
# catches handlers that silently stop lowering to metadata-only bodies
|
|
63
|
+
# (a change of deployment shape, from a refactor that looks like
|
|
64
|
+
# tidying), runs here and nowhere else.
|
|
65
|
+
- run: pnpm lint
|
|
66
|
+
|
|
67
|
+
- run: pnpm typecheck
|
|
@@ -100,6 +100,8 @@ After editing any metadata, run:
|
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
102
|
pnpm validate # schema + CEL predicates + widget bindings (no artifact)
|
|
103
|
+
pnpm lint # authoring rules validate does not run — e.g. a handler that
|
|
104
|
+
# stopped lowering to a metadata-only body
|
|
103
105
|
pnpm typecheck # TypeScript types against @objectstack/spec
|
|
104
106
|
```
|
|
105
107
|
|
|
@@ -138,5 +140,10 @@ covered in [Self-Hosted Deployment](https://objectstack.ai/docs/deployment/self-
|
|
|
138
140
|
- Add a flow or automation: see `objectstack-automation`.
|
|
139
141
|
- Add an AI agent: see `objectstack-ai`.
|
|
140
142
|
|
|
141
|
-
Skills are
|
|
142
|
-
(see `AGENTS.md`) and also show
|
|
143
|
+
Skills live in `.claude/skills/` and are committed with this project, once.
|
|
144
|
+
They are installed one agent runtime at a time (see `AGENTS.md`), and also show
|
|
145
|
+
up in the in-IDE assistant catalog:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y
|
|
149
|
+
```
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"start": "objectstack start",
|
|
12
12
|
"build": "objectstack build",
|
|
13
13
|
"validate": "objectstack validate",
|
|
14
|
+
"lint": "objectstack lint",
|
|
14
15
|
"typecheck": "tsc --noEmit"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
@@ -23,6 +24,6 @@
|
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@objectstack/cli": "^17.0.0",
|
|
26
|
-
"typescript": "^
|
|
27
|
+
"typescript": "^5.3.0"
|
|
27
28
|
}
|
|
28
29
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-objectstack",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.4.0",
|
|
4
4
|
"description": "Create a new ObjectStack project — npx create-objectstack",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-objectstack": "./bin/create-objectstack.js"
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"@types/node": "^26.2.0",
|
|
29
29
|
"tsup": "^8.5.1",
|
|
30
30
|
"typescript": "^6.0.3",
|
|
31
|
-
"vitest": "^4.1.10"
|
|
31
|
+
"vitest": "^4.1.10",
|
|
32
|
+
"yaml": "^2.9.0"
|
|
32
33
|
},
|
|
33
34
|
"repository": {
|
|
34
35
|
"type": "git",
|
|
@@ -49,7 +50,7 @@
|
|
|
49
50
|
"node": ">=22.0.0"
|
|
50
51
|
},
|
|
51
52
|
"scripts": {
|
|
52
|
-
"build": "tsup && node ../../scripts/check-dts-emitted.mjs",
|
|
53
|
+
"build": "node ../../scripts/sync-scaffold-emission-policy.mjs && tsup && node ../../scripts/check-dts-emitted.mjs",
|
|
53
54
|
"typecheck": "tsc --noEmit",
|
|
54
55
|
"dev": "tsup --watch",
|
|
55
56
|
"test": "vitest run"
|