@jskit-ai/agent-docs 0.1.95 → 0.1.97
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/guide/agent/app-setup/initial-scaffolding.md +2 -2
- package/guide/agent/app-setup/working-with-the-jskit-cli.md +1 -1
- package/guide/agent/generators/crud-generators.md +18 -0
- package/package.json +2 -2
- package/patterns/crud-scaffolding.md +43 -1
- package/reference/autogen/packages/crud-server-generator.md +1 -0
- package/reference/autogen/packages/database-runtime-mysql.md +4 -0
- package/reference/autogen/packages/workspaces-web.md +2 -0
- package/reference/autogen/tooling/jskit-cli.md +3 -2
- package/templates/app/AGENTS.md +3 -0
|
@@ -196,14 +196,14 @@ The most important parts look like this:
|
|
|
196
196
|
"@jskit-ai/jskit-cli": "0.x",
|
|
197
197
|
"@playwright/test": "1.61.1",
|
|
198
198
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
199
|
-
"eslint": "^
|
|
199
|
+
"eslint": "^10.8.0",
|
|
200
200
|
"vite": "^8.0.16",
|
|
201
201
|
"vitest": "^4.1.9"
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
-
Published JSKIT libraries and tooling support Node.js 22 from 22.
|
|
206
|
+
Published JSKIT libraries and tooling support Node.js 22 from 22.13.0 onward, Node.js 24, and Node.js 26. Newly generated applications deliberately require Node 26: their app-level `engines` contract, `.nvmrc`, and JSKIT-managed verification workflow all name that runtime. The app-level contract is the runtime boundary for the app and its installed JSKIT runtime packages, while independently consumed JSKIT CLI and tooling packages retain the wider supported range. The dependency on `@local/main` points at `file:packages/main`, which means your app already contains its own local JSKIT package. The maintenance scripts are also useful to notice early, because they show an important ownership boundary in JSKIT.
|
|
207
207
|
|
|
208
208
|
`verify`, `jskit:update`, and `release` are intentionally thin wrappers. They stay in `package.json` because they are convenient app-local shortcuts, but the real implementation lives in `jskit app ...`, not in copied scaffold scripts.
|
|
209
209
|
|
|
@@ -78,7 +78,7 @@ This gives you a clean ownership split:
|
|
|
78
78
|
|
|
79
79
|
That split is worth keeping in mind through the rest of the guide. When you see `npm run verify`, read it as "run the app's JSKIT baseline verification policy, then any app-specific extra verification hook".
|
|
80
80
|
|
|
81
|
-
The starter scaffold also includes `.github/workflows/jskit-verify.yml`. This is a JSKIT-managed projection, not a static template. Installed package descriptors can contribute CI environment values, services, and preparation steps through their top-level `ci` contract. Published JSKIT libraries and tooling support Node.js 22 from 22.
|
|
81
|
+
The starter scaffold also includes `.github/workflows/jskit-verify.yml`. This is a JSKIT-managed projection, not a static template. Installed package descriptors can contribute CI environment values, services, and preparation steps through their top-level `ci` contract. Published JSKIT libraries and tooling support Node.js 22 from 22.13.0 onward, Node.js 24, and Node.js 26, while newly generated applications require Node 26. The managed workflow enforces that application runtime for dependency installation and verification. JSKIT composes the contributions and renders the workflow in this order: checkout, Node 26 setup, `npm ci`, package-contributed `before-verify` steps, and `npm run verify`.
|
|
82
82
|
|
|
83
83
|
For example, `database-runtime` contributes the `database-migrations` step. Its MySQL driver contributes a MariaDB service with `DB_CLIENT=mysql2`, while its Postgres driver contributes a Postgres service with `DB_CLIENT=pg`. Each driver supplies matching synthetic CI-only `DB_*` values; local `.env` values are never copied into the workflow.
|
|
84
84
|
|
|
@@ -230,6 +230,24 @@ w/[workspaceSlug]/admin/...
|
|
|
230
230
|
|
|
231
231
|
then `workspace` is usually the normal default. If you are generating a CRUD for a global operator or account area, `public` or `user` may make more sense.
|
|
232
232
|
|
|
233
|
+
## Schema contract for generated CRUD
|
|
234
|
+
|
|
235
|
+
Generated CRUD tables use one single-column integer primary key, normally
|
|
236
|
+
`id`. Each foreign key must also be single-column and must reference the target
|
|
237
|
+
table's single-column primary key. Composite indexes remain useful for business
|
|
238
|
+
uniqueness such as `(workspace_id, slug)`, but they are never relationship
|
|
239
|
+
targets.
|
|
240
|
+
|
|
241
|
+
Tenant isolation comes from a direct `workspace_id` and/or `user_id` ownership
|
|
242
|
+
column, the exactly matching generated ownership filter, scoped service
|
|
243
|
+
lookups, and cross-tenant tests. Do not encode ownership into a composite
|
|
244
|
+
foreign key such as `(workspace_id, parent_id) -> (workspace_id, id)`.
|
|
245
|
+
|
|
246
|
+
The generator rejects unsupported key shapes. If an approved application truly
|
|
247
|
+
needs a different persistence model, record the durable decision in
|
|
248
|
+
`.jskit/APP_BLUEPRINT.md` and use the explicit table-ownership exception path
|
|
249
|
+
instead of modifying generated CRUD files.
|
|
250
|
+
|
|
233
251
|
## Example 1: `contacts`
|
|
234
252
|
|
|
235
253
|
This is the baseline pattern. If you understand this example, the rest of the chapter becomes much easier.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/agent-docs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.97",
|
|
4
4
|
"description": "Distributed JSKIT agent references, prompts, guides, and generated reference maps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"test": "node --test"
|
|
15
15
|
},
|
|
16
16
|
"engines": {
|
|
17
|
-
"node": "^22.
|
|
17
|
+
"node": "^22.13.0 || ^24.0.0 || ^26.0.0"
|
|
18
18
|
},
|
|
19
19
|
"publishConfig": {
|
|
20
20
|
"access": "public"
|
|
@@ -14,9 +14,38 @@ Check first:
|
|
|
14
14
|
- `jskit show crud-server-generator --details`
|
|
15
15
|
- whether the request is server-only CRUD or server-plus-UI CRUD
|
|
16
16
|
|
|
17
|
+
## Non-negotiable database contract
|
|
18
|
+
|
|
19
|
+
Before database, schema, CRUD, repository, or persistence work, read this
|
|
20
|
+
pattern completely. Use the database selected for this app's development
|
|
21
|
+
runtime; never alter a production, legacy, historical, or other valuable
|
|
22
|
+
database to develop or verify schema changes. Prove the complete migration
|
|
23
|
+
chain against a fresh disposable database before reporting completion.
|
|
24
|
+
|
|
25
|
+
For normal app-owned CRUD tables:
|
|
26
|
+
|
|
27
|
+
- use exactly one non-null integer primary-key column, normally
|
|
28
|
+
`id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY`
|
|
29
|
+
- make every foreign key single-column and point it directly to the referenced
|
|
30
|
+
table's single-column primary key
|
|
31
|
+
- use multi-column unique indexes only for business uniqueness, never as
|
|
32
|
+
relationship targets
|
|
33
|
+
- use only direct `workspace_id` and/or `user_id` columns for generated JSKIT
|
|
34
|
+
ownership, and select the ownership filter that matches those columns exactly
|
|
35
|
+
- express tenant-safe relationships as direct ownership plus a normal
|
|
36
|
+
`parent_id -> parent.id` relationship; resolve related IDs through the
|
|
37
|
+
workspace-scoped service and test both allowed and cross-workspace cases
|
|
38
|
+
|
|
39
|
+
Do not use composite primary keys or composite foreign keys to encode tenant
|
|
40
|
+
ownership, target a business key from a foreign key, or duplicate parent
|
|
41
|
+
identity when the related row ID already identifies it. Stop before generation
|
|
42
|
+
if the proposed table violates these constraints.
|
|
43
|
+
|
|
17
44
|
Rules:
|
|
18
45
|
|
|
19
|
-
- For a CRUD-backed entity,
|
|
46
|
+
- For a CRUD-backed entity, create the validated table in the managed
|
|
47
|
+
development database first. Then make
|
|
48
|
+
`jskit generate crud-server-generator scaffold ...` the first JSKIT scaffold.
|
|
20
49
|
- Unless the table is already owned by a JSKIT baseline package or is an explicit narrow exception recorded in `.jskit/table-ownership.json`, every persisted app-owned table must go through that server CRUD step first.
|
|
21
50
|
- That server scaffold is the crucial first step even if no CRUD UI will be created yet.
|
|
22
51
|
- If the table should already be CRUD-owned but should not expose public CRUD HTTP routes yet, scaffold it with `jskit generate crud-server-generator scaffold ... --internal` instead of dropping to direct knex or a hand-built pseudo-repository.
|
|
@@ -64,6 +93,19 @@ When a weird-custom persistence lane is proposed:
|
|
|
64
93
|
- Record the exact approval and the approved exception in `.jskit/WORKBOARD.md` before coding.
|
|
65
94
|
- If that exception changes the durable architecture rather than only the current chunk, record it in `.jskit/APP_BLUEPRINT.md` too.
|
|
66
95
|
- Without that explicit approval record, do not take the weird-custom persistence path.
|
|
96
|
+
- Record durable, approved schema exceptions in `.jskit/APP_BLUEPRINT.md` as
|
|
97
|
+
well as the table-ownership exception; an exception must not silently weaken
|
|
98
|
+
the normal generated CRUD contract.
|
|
99
|
+
|
|
100
|
+
Before reporting completion:
|
|
101
|
+
|
|
102
|
+
- verify there are no composite primary or foreign keys in the generated CRUD
|
|
103
|
+
tables
|
|
104
|
+
- verify every generated CRUD foreign key targets a single-column primary key
|
|
105
|
+
- apply the generated migrations from zero to a fresh disposable database
|
|
106
|
+
- compare the recreated schema with the intended development schema
|
|
107
|
+
- run positive and negative cross-workspace relationship tests where ownership
|
|
108
|
+
applies, then run JSKIT Doctor and the project's normal verifier
|
|
67
109
|
|
|
68
110
|
Avoid:
|
|
69
111
|
|
|
@@ -68,6 +68,7 @@ Local functions
|
|
|
68
68
|
- `renderJsonRestSearchSchemaLines(columns = [])`
|
|
69
69
|
- `renderJsonRestDefaultSortLine(columns = [])`
|
|
70
70
|
- `renderResourceDefaultSortLiteral(columns = [])`
|
|
71
|
+
- `renderCurrentTimestampExpression(expression, column)`
|
|
71
72
|
- `renderMigrationDefaultClause(column)`
|
|
72
73
|
- `renderMigrationSpecificStringType(column, { tableCollation = "" } = {})`
|
|
73
74
|
- `renderTemporalColumnBuilder(column, methodName)`
|
|
@@ -44,15 +44,19 @@ Local functions
|
|
|
44
44
|
- `toBoolean(value)`
|
|
45
45
|
- `toNullableNumber(value)`
|
|
46
46
|
- `normalizeColumnDefault(value)`
|
|
47
|
+
- `normalizeCurrentTimestampExpression(value)`
|
|
48
|
+
- `normalizeOnUpdateExpression(value)`
|
|
47
49
|
- `parseEnumValues(columnType = "")`
|
|
48
50
|
- `resolveTypeKind(column)`
|
|
49
51
|
- `normalizeColumn(row = {})`
|
|
50
52
|
- `normalizePrimaryKeyColumns(rows = [])`
|
|
53
|
+
- `normalizePrimaryKeyColumnsByTable(rows = [])`
|
|
51
54
|
- `normalizeIndexes(rows = [])`
|
|
52
55
|
- `normalizeForeignKeys(rows = [])`
|
|
53
56
|
- `normalizeCheckConstraints(rows = [])`
|
|
54
57
|
- `requireIdColumn(columns, idColumn)`
|
|
55
58
|
- `requirePrimaryKeyContainsId(primaryKeyColumns, idColumn)`
|
|
59
|
+
- `requireSupportedForeignKeys(foreignKeys, primaryKeyColumnsByTable)`
|
|
56
60
|
|
|
57
61
|
### root
|
|
58
62
|
|
|
@@ -465,7 +465,7 @@ Exports
|
|
|
465
465
|
- `isSensitiveManagedTextRecord({ packageEntry = {}, record = {} } = {})`
|
|
466
466
|
- `isSensitivePackageOption(packageEntry = {}, optionName = "")`
|
|
467
467
|
- `isSensitiveTextMutation({ packageEntry = {}, mutation = {}, resolvedKey = "" } = {})`
|
|
468
|
-
- `resolveSensitiveOptionEnvFallbacks({ packageEntry = {}, appRoot = "", optionInput = {}, readFileBufferIfExists } = {})`
|
|
468
|
+
- `resolveSensitiveOptionEnvFallbacks({ packageEntry = {}, appRoot = "", optionInput = {}, readFileBufferIfExists, environment = process.env } = {})`
|
|
469
469
|
- `sanitizeInstalledPackageRecordForLock(record = {}, packageEntry = {})`
|
|
470
470
|
- `sanitizeLockSecretsForWrite(lock = {}, packageRegistry = null)`
|
|
471
471
|
- `sanitizeManagedTextForLock(packageEntry = {}, managedText = {})`
|
|
@@ -550,8 +550,9 @@ Local functions
|
|
|
550
550
|
- `cookieHeader(setCookie = [])`
|
|
551
551
|
- `responsePayload(response = {})`
|
|
552
552
|
- `upstreamError(payload = {}, response = {}, extra = {})`
|
|
553
|
+
- `request(fetchImpl, href, options)`
|
|
553
554
|
- `postJson(fetchImpl, href, body, headers = {})`
|
|
554
|
-
- `readSession(fetchImpl, targetOrigin
|
|
555
|
+
- `readSession(fetchImpl, targetOrigin)`
|
|
555
556
|
- `logout(fetchImpl, targetOrigin, session)`
|
|
556
557
|
- `login(fetchImpl, targetOrigin, identity, secret, session)`
|
|
557
558
|
|
package/templates/app/AGENTS.md
CHANGED
|
@@ -7,4 +7,7 @@ Recommended references:
|
|
|
7
7
|
- `node_modules/@jskit-ai/agent-docs/guide/agent/index.md`
|
|
8
8
|
- `node_modules/@jskit-ai/agent-docs/patterns/INDEX.md`
|
|
9
9
|
|
|
10
|
+
Before database, schema, CRUD, repository, or persistence work, read and follow
|
|
11
|
+
`node_modules/@jskit-ai/agent-docs/patterns/crud-scaffolding.md`.
|
|
12
|
+
|
|
10
13
|
Keep changes scoped to the user request and verify runtime behavior with tests or explicit checks.
|