@owlmeans/planning 0.1.18-rc.13 → 0.1.18-rc.15
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/README.md +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/planning/SKILL.md +16 -43
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ the executor with `@owlmeans/server-planning` and reads remotely with `@owlmeans
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
bun add @owlmeans/planning@^0.1.18-rc.
|
|
12
|
+
bun add @owlmeans/planning@^0.1.18-rc.15 ajv ajv-formats
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Concepts
|
|
@@ -188,7 +188,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
188
188
|
your project's skill store (`.agents/skills/`):
|
|
189
189
|
|
|
190
190
|
```sh
|
|
191
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
191
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.46
|
|
192
192
|
```
|
|
193
193
|
|
|
194
194
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/planning",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18-rc.15",
|
|
5
|
+
"generatedAt": "2026-10-03T11:19:50.783Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/planning
|
|
9
9
|
|
|
10
10
|
**Layer:** Cross-cutting domain
|
|
11
|
-
**Install:** `"@owlmeans/planning": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/planning": "^0.1.18-rc.15"` in `dependencies` (`ajv` and `ajv-formats` are peers)
|
|
12
12
|
|
|
13
13
|
The contracts of project planning: record shapes, schemas, refusals, the protocol tree, the pure
|
|
14
14
|
fold and the models. No database, no fastify, no React. The executor, the plugin registry, the
|
|
@@ -37,26 +37,8 @@ entityId, profileId })`) and the remote one (`@owlmeans/client-planning`).
|
|
|
37
37
|
- The **options** are `{ wait?, timeout? }`, always the second argument. Only the wire body
|
|
38
38
|
(`ExecuteRequest`) carries them beside the execution.
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const drill = await planning.execute({
|
|
44
|
-
action: TransitionAction.Create,
|
|
45
|
-
card: { kind: WorkcardKind.Card, type: 'shed:tool', parent: shedId, title: 'Cordless drill', fields: { brand: 'Acme' } },
|
|
46
|
-
}, { wait: true }) // drill.card — the committed record
|
|
47
|
-
await planning.cards.get(drill.card!.id!)
|
|
48
|
-
await planning.execute({ action: TransitionAction.Transit, card: drill.card!.id!, transition: 'lend' }, { wait: true })
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
| Wrong | What happens | Right |
|
|
52
|
-
|---|---|---|
|
|
53
|
-
| `{ action, draft: { … } }` | `planning:malformed:create-without-draft` | the draft goes under `card` |
|
|
54
|
-
| `{ …, wait: true }` in the execution | ignored in process: the receipt returns before the commit, with no `card` | `execute(exec, { wait: true })` |
|
|
55
|
-
| `action: 'create'` | a type error — `TransitionAction` is an enum | `TransitionAction.Create` |
|
|
56
|
-
|
|
57
|
-
Each is a compile error against the typed `TransitionExecution`; it reaches run time only through a
|
|
58
|
-
value typed `any`. `server-planning` carries the full example (facade, read back, data-defined
|
|
59
|
-
type and flow).
|
|
40
|
+
The worked example (facade, create, read back, transit, a data-defined type and flow) and the wrong
|
|
41
|
+
forms generated code keeps writing are `server-planning` → Creating and reading a card.
|
|
60
42
|
|
|
61
43
|
## Key exports
|
|
62
44
|
|
|
@@ -91,7 +73,9 @@ type and flow).
|
|
|
91
73
|
`status`, `labels`, `order`, `parent` are generic and indexable; everything a type adds lives in
|
|
92
74
|
`fields` and is validated by the type's `fields` JSON schema. Generic code reads only the top.
|
|
93
75
|
A `fields` key never holds `.` or `$` at any depth (`invalidFieldKeys`).
|
|
94
|
-
- **`entityId` is the organization's stable id
|
|
76
|
+
- **`entityId` is the organization's stable record id** — never the wire `entitySlug`, never a body
|
|
77
|
+
value. Every read is scoped by it; where a request's comes from is `server-planning` → Scope and
|
|
78
|
+
security.
|
|
95
79
|
- **Membership is `parent` + `parents`, never a relationship.** `parents` always contains `parent`
|
|
96
80
|
(first), so many-to-many membership needs no junction row. `within` queries `parents`.
|
|
97
81
|
- **Specification is a workcard** (`kind: specification`) with `category`, `format`, `body`, `ref`,
|
|
@@ -162,7 +146,7 @@ excess-property check catches it — keep the literal typed.
|
|
|
162
146
|
Card types and status flows may also be DATA — `ScopedSchemaRecord`s a store keeps behind the
|
|
163
147
|
optional `PlanningStore.schemas` port — layered **code → entity → project**:
|
|
164
148
|
|
|
165
|
-
- `code` is the plugin registry (
|
|
149
|
+
- `code` is the plugin registry (the default), `entity` an organization-wide record
|
|
166
150
|
(`project` absent), `project` a record of one project card. A project record overrides an
|
|
167
151
|
organization one of the same key.
|
|
168
152
|
- **Only card types and flows are data.** A code key is sealed unless its declaration says
|
|
@@ -189,18 +173,8 @@ optional `PlanningStore.schemas` port — layered **code → entity → project*
|
|
|
189
173
|
`define` (each at its layer's next version, flows first), `seed` (only the keys the layer lacks),
|
|
190
174
|
`retire(kind, key, { project? })`. The declaration still carries its own `version` (any number
|
|
191
175
|
≥ 1 for `define`/`seed`, which assign the layer's next one; the exact next one for `put*`), and
|
|
192
|
-
a project layer is `{ project: <project card id> }` in the second argument:
|
|
193
|
-
|
|
194
|
-
```ts
|
|
195
|
-
await planning.definitions!.define({
|
|
196
|
-
flows: [{ id: 'shed:repair', version: 1, label: 'Repair',
|
|
197
|
-
statuses: [{ key: 'reported', intrinsic: IntrinsicStatus.Planned, initial: true },
|
|
198
|
-
{ key: 'fixed', intrinsic: IntrinsicStatus.Closed, terminal: true }],
|
|
199
|
-
transitions: [{ name: 'fix', from: ['reported'], to: 'fixed', explicit: true }] }],
|
|
200
|
-
types: [{ type: 'shed:repair', kind: WorkcardKind.Card, version: 1, label: 'Repair ticket',
|
|
201
|
-
fields: { type: 'object' }, flows: ['shed:repair'], specifications: [] }],
|
|
202
|
-
}, { project: shedId }) // admitted under the shed when its type says `scopedCardTypes: true` (or lists it in `cardTypes`)
|
|
203
|
-
```
|
|
176
|
+
a project layer is `{ project: <project card id> }` in the second argument (a `define` call:
|
|
177
|
+
`server-planning` → Creating and reading a card).
|
|
204
178
|
|
|
205
179
|
## The fold
|
|
206
180
|
|
|
@@ -215,9 +189,9 @@ await planning.definitions!.define({
|
|
|
215
189
|
never written or cleared;
|
|
216
190
|
- `link`/`unlink` move only `seq`/`head`/`updatedAt`; `delete` answers `null`;
|
|
217
191
|
- every result carries `seq = transition.seq`, `head = max(head, seq)`, `updatedAt = transition.at`;
|
|
218
|
-
- the log is replayed AS WRITTEN: a row
|
|
219
|
-
`createdBy
|
|
220
|
-
|
|
192
|
+
- the log is replayed AS WRITTEN: a stored row admission would refuse (an update naming
|
|
193
|
+
`createdBy`) still folds. Guards live at admission (`assertMutable`, the executor), never in the
|
|
194
|
+
fold, so a stored log never stops projecting.
|
|
221
195
|
|
|
222
196
|
`applyRelationship(links, transition)` folds the edges: a create's `links`, `link`, `unlink`, and a
|
|
223
197
|
`delete` dropping every edge touching the card. An existing edge is kept, so re-folding adds nothing.
|
|
@@ -234,7 +208,6 @@ await planning.definitions!.define({
|
|
|
234
208
|
- transit — `flows[flow] = rule.to`, `status` on the primary flow, `intrinsic` when it moves,
|
|
235
209
|
`closedAt` set on entering closed and cleared on leaving; throws `IllegalTransition`;
|
|
236
210
|
- link/unlink/delete — nothing.
|
|
237
|
-
- `createdBy` only ever comes from a create's draft: `changes` and `unset` never carry it.
|
|
238
211
|
|
|
239
212
|
`assertMutable(exec, type)` refuses (`planning:immutable:<field>`) identity keys (`createdAt`
|
|
240
213
|
among them), `createdBy` in `changes` or `unset` on any action (a create included),
|
|
@@ -251,8 +224,8 @@ description `$ilike` (wildcards escaped) and code `$startsWith`, `updatedSince`
|
|
|
251
224
|
$gte }`. `entityId` always comes from the scope; `undefined` is omitted. Paging and sort are
|
|
252
225
|
`listOptionsOf` (`size: 0` = no limit). `summaryOf(cards, parents)` counts DIRECT children by
|
|
253
226
|
intrinsic state and gives no key to a parent with none. A scope naming `projects` is narrowed by
|
|
254
|
-
the SERVER facade on top of this translation (`server-planning`);
|
|
255
|
-
`RelationshipWhere.project` take one id or a list.
|
|
227
|
+
the SERVER facade on top of this translation (`server-planning` → The access resolver);
|
|
228
|
+
`TransitionWhere.project` and `RelationshipWhere.project` take one id or a list.
|
|
256
229
|
|
|
257
230
|
**A query crosses HTTP in its wire form.** The OwlMeans transport cannot carry arrays or nested
|
|
258
231
|
objects in a query string (the client writes `key[]=`, the server reads that key literally), so
|
|
@@ -264,7 +237,7 @@ A client calls `encodeWorkcardQuery(query)` before `call({ query })`; a handler
|
|
|
264
237
|
|
|
265
238
|
## The protocol tree and mounting
|
|
266
239
|
|
|
267
|
-
`makePlanningProtocols({ base: { alias, path?, parent?, service? }, guards, gate?, socketBase? })`:
|
|
240
|
+
`makePlanningProtocols({ base: { alias, path?, parent?, service? }, guards, gate?, socketBase?, definitions? })`:
|
|
268
241
|
|
|
269
242
|
| Leaf | Route | Request → reply |
|
|
270
243
|
|---|---|---|
|
|
@@ -349,7 +322,7 @@ throw a `ResilientError` that declares nothing.
|
|
|
349
322
|
|
|
350
323
|
## i18n
|
|
351
324
|
|
|
352
|
-
Importing the package registers, in
|
|
325
|
+
Importing the package registers, in eight languages (en, pl, ru, be, uk, es, de, fr), `lib:planning.*` labels (`kind.*`,
|
|
353
326
|
`intrinsic.*`, `action.*`, `commit.*`, `format.*`) and one text per refusal type under the shared
|
|
354
327
|
`errors` resource (`errors.<TypeName>`), where a panel's error lookup finds it.
|
|
355
328
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/planning",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.15",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Runtime-free project-planning contracts — the workcard super type, projects, specifications, typed relationships, status flows with three intrinsic states, the transition event and its pure fold, the schema registry, the models and the protocol tree.",
|
|
6
6
|
"type": "module",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
26
|
+
"@owlmeans/auth": "^0.1.18-rc.38",
|
|
27
27
|
"@owlmeans/basic-ids": "^0.1.18-rc.34",
|
|
28
28
|
"@owlmeans/context": "^0.1.18-rc.32",
|
|
29
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
29
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.39",
|
|
30
30
|
"@owlmeans/error": "^0.1.18-rc.36",
|
|
31
31
|
"@owlmeans/i18n": "^0.1.18-rc.37",
|
|
32
32
|
"@owlmeans/resource": "^0.1.18-rc.37",
|