dreamteamer 0.32.0 → 0.33.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.
Files changed (66) hide show
  1. package/README.md +4 -2
  2. package/collections/agents.collection.yaml +41 -32
  3. package/collections/collections.collection.yaml +68 -230
  4. package/collections/command-bindings.collection.yaml +37 -43
  5. package/collections/commands.collection.yaml +50 -35
  6. package/collections/mixins.collection.yaml +49 -0
  7. package/collections/modules.collection.yaml +76 -122
  8. package/collections/repos.collection.yaml +53 -56
  9. package/collections/skills.collection.yaml +32 -21
  10. package/collections/ui-views.collection.yaml +57 -46
  11. package/mixins/docs.mixin.yaml +21 -0
  12. package/mixins/entity.mixin.yaml +22 -0
  13. package/package.json +5 -3
  14. package/scripts/migrate-descriptors-v2.mjs +795 -0
  15. package/skills/using-dreamteamer/SKILL.md +27 -24
  16. package/skills/using-dreamteamer/references/agents.md +1 -1
  17. package/skills/using-dreamteamer/references/before-you-build.md +1 -5
  18. package/skills/using-dreamteamer/references/collections.md +450 -348
  19. package/skills/using-dreamteamer/references/commands.md +49 -35
  20. package/skills/using-dreamteamer/references/data-modeling.md +342 -319
  21. package/skills/using-dreamteamer/references/extensions.md +8 -5
  22. package/skills/using-dreamteamer/references/getting-started.md +6 -4
  23. package/skills/using-dreamteamer/references/records.md +43 -34
  24. package/skills/using-dreamteamer/references/skills.md +4 -3
  25. package/skills/using-dreamteamer/references/ui-components.md +30 -32
  26. package/skills/using-dreamteamer/references/ui-views.md +122 -124
  27. package/src/api.d.ts +22 -2
  28. package/src/api.js +16 -1
  29. package/src/check.js +55 -40
  30. package/src/checkout.js +14 -13
  31. package/src/cli.js +118 -71
  32. package/src/collections-cli.js +136 -144
  33. package/src/commit.js +9 -8
  34. package/src/compile-collections.js +346 -0
  35. package/src/compile.js +217 -1063
  36. package/src/descriptor-v2.js +165 -0
  37. package/src/descriptor.js +90 -0
  38. package/src/doctor.js +57 -0
  39. package/src/events.js +11 -10
  40. package/src/extensions.js +48 -10
  41. package/src/field-values.js +7 -6
  42. package/src/fields.js +254 -0
  43. package/src/filter.js +45 -1
  44. package/src/fractional-index.js +2 -2
  45. package/src/harnesses.js +80 -52
  46. package/src/init.js +74 -46
  47. package/src/namespace.js +23 -9
  48. package/src/placement.js +26 -16
  49. package/src/presentation.js +153 -299
  50. package/src/record-commands.js +12 -12
  51. package/src/records-api.d.ts +106 -7
  52. package/src/records-api.js +2 -1
  53. package/src/records.js +15 -13
  54. package/src/ref.js +3 -39
  55. package/src/relations.js +23 -24
  56. package/src/runtime.js +12 -35
  57. package/src/schema-ops.js +1181 -1275
  58. package/src/store.js +210 -81
  59. package/src/template.js +100 -24
  60. package/src/temporal.js +11 -3
  61. package/src/views.js +176 -0
  62. package/src/workspace.js +14 -0
  63. package/src/yaml.js +66 -5
  64. package/collection-templates/docs.collection-template.yaml +0 -17
  65. package/collection-templates/entity.collection-template.yaml +0 -20
  66. package/collections/collection-templates.collection.yaml +0 -20
@@ -1,123 +1,77 @@
1
+ # The modules this workspace compiled, PROJECTED by compile from what it discovered. `package.json`
2
+ # stays the source of truth and compile keeps reading it, so a record here is a projection, never an
3
+ # input: editing one would be editing a photograph. It earns its place because the engine reads the
4
+ # DATA — `dependencies` is checked for cycles, `peer_collections` is what lets a cross-module
5
+ # reference compile — and because, as a collection, its EDGES are browsable, diagrammable and
6
+ # listable with no code written for any of them.
1
7
  name: modules
2
- # The modules this workspace compiled, PROJECTED by compile from what it discovered — the first
3
- # derived collection in core, and the shape is deliberate enough to name.
4
- #
5
- # Every other runtime-stored collection (skills, commands, ui-views…) is STAGED from a module's
6
- # source folder and read back by the engine. This one is neither: `package.json` stays the source of
7
- # truth and compile keeps reading it, so a record here is a projection, never an input. Editing one
8
- # would be editing a photograph.
9
- #
10
- # Why it earns a place anyway, against the three questions:
11
- # 1. Does the ENGINE read it? It reads the DATA, which is the test that matters. `dependencies`
12
- # names modules and is checked for cycles; `peerDependencies` names collections and is what
13
- # lets a cross-module reference compile at all (compile.js — "cyclic module dependencies",
14
- # "an overlay cannot compile without its base"). This is enforced structure, not annotation.
15
- # 2. Recipe creeping into core? No. A module is the engine's own concept.
16
- # 3. Could a module do it instead? No — nothing inside a module can enumerate the module set.
17
- #
18
- # What it buys is the thing a `group:` label cannot express: EDGES. A group is a partition; a
19
- # dependency is a relation, and it has two kinds that mean different things. Once it is a
20
- # collection, the browse, the diagram, `dt modules list` and the nav all work with no code written
21
- # for any of them.
22
- storage: { path: modules, codec: yaml, shape: file, suffix: module }
23
- id:
24
- generate: "{{ name | slug }}"
25
- pattern: "^[a-z0-9-]+$"
26
- title_template: "{{ name }}"
27
- schema:
28
- type: object
29
- required: [name, location]
30
- properties:
31
- name:
32
- type: string
33
- description: The module's package name, verbatim — `@dreamteamer/crm`, `acme-workspace`.
34
- title:
35
- type: string
36
- description: >-
37
- What to CALL this module — authored as `dreamteamer.title` in its package.json, else derived
38
- from the id. Authored because deriving cannot know an acronym: titleCase("crm") is "Crm".
39
- A module names itself, which is what replaces a display-name map maintained in a surface.
40
- description:
41
- type: string
42
- description: >-
43
- What this module is FOR, in one line — authored as `dreamteamer.description` in its
44
- package.json, never derived. Written by `dt add modules --description` and
45
- `dt set modules/<id> description=…`.
46
- namespaces:
47
- type: array
48
- items: { type: string }
49
- description: >-
50
- The namespaces this module DECLARES and owns — authored as `dreamteamer.namespaces` in its
51
- package.json (§8). The workspace's effective set is the union of every module's declarations
52
- plus its own; two modules declaring one namespace is a compile error, and USING another
53
- module's namespace requires that module in `dependencies`. ABSENT means this module ships
54
- into the default namespace — the empty prefix, which is the commons.
55
- location:
56
- type: string
57
- enum: [modules, git_modules, node_modules, root]
58
- description: >-
59
- WHERE this module's sources sit — the folder name the operator already knows, so `dt status`
60
- needs no legend. `root` is the classic no-workspace-module layout, where the workspace's own
61
- sources live at its root rather than under `modules/<id>/`.
62
- ⚠ Renamed from `channel` in 0.19.0, and the enum's `path` value was DELETED rather than
63
- renamed: discovery never emitted it, so it was an enum advertising work nobody had done.
64
- `origin` was rejected (one token from `origin/main`, which `update` literally pulls) and
65
- `shape` was rejected (`storage.shape` owns that word).
66
- path:
67
- type: string
68
- description: Workspace-relative root of the module's sources.
69
- bin:
70
- type: array
71
- description: >-
72
- The module's runnable entry points — every file under its `bin/`, module-relative, projected by
73
- compile. Rendered into the orientation block beside the module's skills and commands as the
74
- POINTER that a procedure is a script here (how to run it stays in the module's skill); a module
75
- with no `bin/` has no field.
76
- items:
77
- type: string
78
- owns_data:
79
- type: boolean
80
- description: >-
81
- The module keeps its records in its OWN clone rather than this workspace's data/ — so a
82
- write there commits in that repo, and a rename spanning both is unavoidably two commits.
83
- dependencies:
84
- type: array
85
- description: >-
86
- Modules this one cannot compile without — an overlay needs its base. HARD and acyclic;
87
- compile fails on a ring and names the peer escape hatch.
88
- items:
89
- type: string
90
- x-reference: modules
91
- peer_dependencies:
92
- type: array
93
- description: >-
94
- Collections this module REFERENCES but does not own. Soft on purpose: naming a concept
95
- rather than a module is what keeps two modules from forming a ring, and what lets a module
96
- ship an unused reference without dragging in a whole CRM.
97
- items:
98
- type: string
99
- x-reference: collections
100
- # SOFT, because the normal state of a module opened on its own is that its peers are NOT
101
- # installed — that is the whole reason a peer is declared rather than depended on. Validated
102
- # hard, this field made the record it is projected onto fail `check` for saying exactly what
103
- # it exists to say, and there was no state in which an optional cross-module reference
104
- # passed: dropping the declaration made `compile` fail instead, naming peerDependencies as
105
- # the remedy. Present peers still resolve, and a peer that names a collection nobody ever
106
- # installs is reported by `check` as a warning off `unresolved_peers`, not silently.
107
- x-reference-soft: true
108
- collections:
109
- type: array
110
- description: >-
111
- Collections this module contributed a source for. A collection merged from several modules
112
- appears under EVERY one of them — which is the honest answer the flat "which module owns
113
- this" provenance could not give (it took the first source and dropped the overlay).
114
- items:
115
- type: string
116
- x-reference: collections
117
- order: 140
118
- # ⚠ ALL THREE IDENTITY SPELLINGS. A module is one string after `add modules` (folder = package name
119
- # = id), and three strings for anything that predates it — so the listing shows the id (always
120
- # printed first), the package `name` and the `path`, which is how an operator sees the fork at all.
121
- list_fields: [location, path, namespaces, name, collections]
122
- icon: deployed_code
123
- group: system
8
+ record_title: '{{ name }}'
9
+ description: A module this workspace compiled — where its sources sit, what it declares, and the modules and collections it reaches.
10
+ use_when: >-
11
+ asked which module ships a collection, what a module depends on, or where its sources live — read
12
+ here; a record is projected from the module's package.json, so change the package, not the record
13
+ internal: true
14
+ storage:
15
+ path: modules
16
+ format: yaml
17
+ ids:
18
+ from: '{{ name | slug }}'
19
+ pattern: '^[a-z0-9-]+$'
20
+ fields:
21
+ name:
22
+ type: string
23
+ required: true
24
+ description: The module's package name, verbatim — `@dreamteamer/crm`, `acme-workspace`.
25
+ title:
26
+ type: string
27
+ description: What to CALL this module — `dreamteamer.title` in its package.json, else derived from the id. Authored where deriving cannot know an acronym (`crm` → `CRM`).
28
+ description:
29
+ type: string
30
+ description: What this module is FOR, in one line — `dreamteamer.description` in its package.json, never derived.
31
+ namespaces:
32
+ type: string
33
+ many: true
34
+ description: >-
35
+ The namespaces this module declares and owns — `dreamteamer.namespaces` in its package.json. The
36
+ workspace's set is the union of every module's declarations plus its own; two modules declaring
37
+ one namespace is a compile error, and using another module's namespace requires that module in
38
+ `dependencies`. Absent: the module ships into the default namespace, the empty prefix.
39
+ location:
40
+ type: string
41
+ required: true
42
+ enum: [modules, git_modules, node_modules, root]
43
+ passthrough: true
44
+ description: >-
45
+ Where this module's sources sit — the folder name, so `dt status` needs no legend. `root` is the
46
+ classic layout, where the workspace's own sources live at its root rather than under `modules/<id>/`.
47
+ path:
48
+ type: string
49
+ description: Workspace-relative root of the module's sources.
50
+ bin:
51
+ type: string
52
+ many: true
53
+ description: The module's runnable entry points — every file under its `bin/`, module-relative. Rendered into the orientation block as the pointer that a procedure is a script here.
54
+ owns_data:
55
+ type: boolean
56
+ description: The module keeps its records in its OWN clone rather than this workspace's data/ — a write there commits in that repo, and a rename spanning both is two commits.
57
+ dependencies:
58
+ type: modules
59
+ many: true
60
+ description: Modules this one cannot compile without — an overlay needs its base. Hard and acyclic; compile fails on a ring and names the peer escape hatch.
61
+ peer_collections:
62
+ type: string
63
+ many: true
64
+ description: >-
65
+ Collections this module references but does not own. Soft by design: naming a concept rather than
66
+ a module keeps two modules from forming a ring, and lets a module ship a reference to a
67
+ collection nobody installed. A plain list of names, because the point is that the target may be absent.
68
+ collections:
69
+ type: collections
70
+ many: true
71
+ description: Collections this module contributed a source to. A collection merged from several modules appears under every one of them.
72
+ display:
73
+ nav:
74
+ icon: deployed_code
75
+ order: 140
76
+ list:
77
+ columns: [location, path, namespaces, name, collections]
@@ -1,61 +1,58 @@
1
1
  name: repos
2
- description: >-
3
- A git repository this workspace knows about — where it lives and how a working tree is
4
- materialized on demand.
2
+ record_title: '{{ name }}'
3
+ description: A git repository this workspace knows about — where it lives and how a working tree is materialized on demand.
5
4
  use_when: >-
6
5
  a repository this workspace depends on is named — its own engine or extension clone, a client's
7
- repo — read the record here for WHERE it lives (`path`, a `${env:…}` template `dt resolve` renders
6
+ repo — read the record here for WHERE it lives (`path`, a `${env:…}` variable `dt resolve` renders
8
7
  per machine) before assuming a path or concluding a clone is unreachable; `dt status` reports
9
8
  each one and `dt install repos/<id>` materializes it
10
- # An external git repo attached to this workspace. Owns CLONE LIFECYCLE ONLY — a repo record
11
- # never contributes schema, skills or UI (that is what a module is, declared in package.json
12
- # `dreamteamer.git-modules`, because modules must be restorable BEFORE compile can run).
13
- # Working trees are materialized ON DEMAND via `dreamteamer install repos/<id>`, and never as part
14
- # of making a checkout ready: the record count only grows and any given session needs almost none
15
- # of them.
16
- storage: { path: data/repos, codec: yaml, shape: file, suffix: repo }
17
- id:
18
- generate: "{{ name | slug }}"
19
- pattern: "^[a-z0-9-]+$"
20
- schema:
21
- type: object
22
- required: [name, url]
23
- properties:
24
- name:
25
- type: string
26
- description: The CLONE FOLDER name, not a display title — this is what appears on disk.
27
- description:
28
- type: string
29
- description: What this repo is, in one line.
30
- url:
31
- type: string
32
- description: The git remote to clone from.
33
- ref:
34
- type: string
35
- default: main
36
- description: Branch or tag to check out.
37
- identity:
38
- type: string
39
- description: 'Opaque path segment grouping clones by the account that owns them: <repos-path>/<identity>/<name>.'
40
- path:
41
- type: string
42
- description: >-
43
- Where the working tree goes, winning over the derived <repos-path>/<identity>/<name>. Takes
44
- the ${env:NAME} / ${workspaceFolder} / ${userHome} templates, rendered when the path is
45
- needed — which is how a repo that lives OUTSIDE this workspace is expressed, since an
46
- absolute rendering escapes the root while a plain relative one still anchors to it.
47
- visibility:
48
- type: string
49
- enum: [private, public]
50
- default: private
51
- description: Whether the repo is public. Defaults to private, because assuming otherwise is the expensive mistake.
52
- order: 145
53
- list_fields: [name, identity, ref, url]
54
- icon: source
55
- # MACHINERY, NOT A DOMAIN NOUN, and `group: system` is the whole statement of it. `repos` is the
56
- # engine's only collection whose records live in `data/`, which used to make every workspace render
57
- # a **System** module group with one collection under it — the group the block's own renderer says
58
- # should not exist (harnesses.js). Being in the `system` partition folds it out of the block's
59
- # domain listing and onto the schema surface instead. The records stay real, writable and committed;
60
- # only the presentation changes.
61
- group: system
9
+ # Owns CLONE LIFECYCLE ONLY — a repo record never contributes schema, skills or UI (that is what a
10
+ # module is, declared in package.json `dreamteamer.git_modules`, because modules must be restorable
11
+ # BEFORE compile can run). Working trees are materialized on demand, never as part of making a
12
+ # checkout ready. Internal: workspace plumbing rather than a domain noun, so it is drawn on the
13
+ # schema surface; its records are ordinary, writable, committed data.
14
+ internal: true
15
+ storage:
16
+ path: data/repos
17
+ format: yaml
18
+ ids:
19
+ from: '{{ name | slug }}'
20
+ pattern: '^[a-z0-9-]+$'
21
+ fields:
22
+ name:
23
+ type: string
24
+ required: true
25
+ description: The CLONE FOLDER name, not a display title — this is what appears on disk.
26
+ description:
27
+ type: string
28
+ description: What this repo is, in one line.
29
+ url:
30
+ type: string
31
+ required: true
32
+ title: URL
33
+ description: The git remote to clone from.
34
+ ref:
35
+ type: string
36
+ default: main
37
+ description: Branch or tag to check out.
38
+ identity:
39
+ type: string
40
+ description: 'Opaque path segment grouping clones by the account that owns them: <repos-path>/<identity>/<name>.'
41
+ path:
42
+ type: string
43
+ description: >-
44
+ Where the working tree goes, winning over the derived <repos-path>/<identity>/<name>. Takes the
45
+ ${env:NAME} / ${workspaceFolder} / ${userHome} variables, rendered when the path is needed — which
46
+ is how a repo that lives OUTSIDE this workspace is expressed, since an absolute rendering escapes
47
+ the root while a plain relative one still anchors to it.
48
+ visibility:
49
+ type: string
50
+ default: private
51
+ enum: [private, public]
52
+ description: Whether the repo is public. Defaults to private, because assuming otherwise is the expensive mistake.
53
+ display:
54
+ nav:
55
+ icon: source
56
+ order: 145
57
+ list:
58
+ columns: [name, identity, ref, url]
@@ -1,22 +1,33 @@
1
1
  name: skills
2
- storage: { path: skills, codec: md, shape: folder, entry: SKILL.md }
3
- id: { generate: "{{ name | slug }}" }
4
- schema:
5
- type: object
6
- required: [name, description]
7
- properties:
8
- name:
9
- type: string
10
- description: The skill id — must equal the folder name.
11
- description:
12
- type: string
13
- description: WHEN to load this skill, not what it contains. A session matches its situation against this line, so a description that describes the contents is a skill that never triggers.
14
- instructions:
15
- type: string
16
- format: markdown
17
- x-body: true
18
- description: The skill itself. Keep it a digest with references/ beside it — a skill nobody can afford to load is not a capability.
19
- order: 20
20
- list_fields: [name, last-modified, description]
21
- icon: psychology
22
- group: system
2
+ record_title: '{{ name }}'
3
+ description: A procedure a session loads on its own when its situation matches — its `description` is the trigger, never a summary.
4
+ use_when: >-
5
+ a job recurs and a session should find the know-how for it without being told — write the procedure
6
+ here; not a command (an operator has to remember to run one) and not an agent (a whole context)
7
+ internal: true
8
+ storage:
9
+ path: skills
10
+ format: md
11
+ shape: folder
12
+ entry: SKILL.md
13
+ ids:
14
+ from: '{{ name | slug }}'
15
+ fields:
16
+ name:
17
+ type: string
18
+ required: true
19
+ description: The skill id — must equal the folder name.
20
+ description:
21
+ type: string
22
+ required: true
23
+ description: WHEN to load this skill, not what it contains. A session matches its situation against this line, so a description that describes the contents is a skill that never triggers.
24
+ instructions:
25
+ type: markdown
26
+ body: true
27
+ description: The skill itself. Keep it a digest with references/ beside it — a skill nobody can afford to load is not a capability.
28
+ display:
29
+ nav:
30
+ icon: psychology
31
+ order: 20
32
+ list:
33
+ columns: [name, last_modified, description]
@@ -1,48 +1,59 @@
1
+ # A view is a named variant of a collection's default view. The default view is the collection's own
2
+ # `display`; a view carries the same block and compile merges it over the collection's, so a view
3
+ # states only what it changes.
1
4
  name: ui-views
2
5
  title: UI Views
3
- storage: { path: ui-views, codec: yaml, shape: file, suffix: ui-view }
4
- id: { generate: "{{ path | slug }}" }
5
- schema:
6
- type: object
7
- required: [path, target, layout]
8
- properties:
9
- path:
10
- type: string
11
- description: The route this view renders at. The record id is derived from it, so a view saved from the CLI and one saved from the UI land on the same record.
12
- nav:
13
- type: object
14
- description: How the view appears in navigation. Omit it entirely for a route with no nav entry.
15
- properties:
16
- label:
17
- type: string
18
- description: What the nav entry reads.
19
- icon:
20
- type: string
21
- description: material-symbols-outlined icon name for the nav entry.
22
- order:
23
- type: number
24
- description: Sort position among its siblings.
25
- target:
26
- type: string
27
- enum: [list, item, page]
28
- description: What the view renders — a collection listing, one record, or a standalone page.
29
- collection:
30
- type: string
31
- x-reference: collections
32
- description: Which collection this view is of.
33
- default:
34
- type: boolean
35
- description: 'Marks the view a bare /content/<collection> renders. Directus-parity: a collection''s default presentation is an ordinary view record, not a second mechanism. At most one per collection, and never its own route — it IS the collection page.'
36
- layout:
37
- type: string
38
- description: A REGISTERED layout/component id (table, cards, kanban, calendar, map…). An unregistered id degrades visibly rather than erroring.
39
- options:
40
- type: object
41
- description: Layout-specific settings — columns, sort, grouping. Deliberately open, since each layout wants different things.
42
- filter:
43
- type: object
44
- description: The saved filter this view applies, in the studio's operator set.
45
- order: 50
46
- list_fields: [path, last-modified, target, collection, layout]
47
- icon: dashboard_customize
48
- group: system
6
+ record_title: '{{ route }}'
7
+ description: A named way to draw a collection, a record or a page — a route, a scope, a filter, and the display keys it changes from the collection's own.
8
+ use_when: >-
9
+ a collection needs a second way to be looked at (a board by status, today's rows, a map) — write
10
+ the view here with only the display keys it changes; the collection's default list and record page
11
+ are its descriptor's `display`, never a view
12
+ internal: true
13
+ storage:
14
+ path: ui-views
15
+ format: yaml
16
+ ids:
17
+ from: '{{ route | slug }}'
18
+ fields:
19
+ name:
20
+ type: string
21
+ description: A short handle for the view, for people reading the sources.
22
+ title:
23
+ type: string
24
+ description: The view's heading where a surface draws one.
25
+ description:
26
+ type: string
27
+ description: What the view shows and who it is for, in one line.
28
+ route:
29
+ type: string
30
+ required: true
31
+ description: The path this view renders at, starting with /. The record id is derived from it, so a view saved from the CLI and one saved from a surface land on the same record.
32
+ scope:
33
+ type: string
34
+ required: true
35
+ enum: [record, collection, page]
36
+ description: What the view draws — one record, a collection's rows, or a standalone page.
37
+ collection:
38
+ type: collections
39
+ description: The collection the view is of. A page may omit it.
40
+ filter:
41
+ type: map
42
+ description: The rows the view keeps, as field → condition in the filter operator set. Accepts the value tokens `$today` and `$now`.
43
+ display:
44
+ type: map
45
+ description: >-
46
+ The display keys this view changes, in the collection's own block — `nav` (title · icon · order),
47
+ `list` (layout · columns · sort · options), `record` (layout · subtitle · badge · color_by ·
48
+ options), `form` (sections). Merged over the collection's display sub-block by sub-block, a key
49
+ set here winning; a view with no `nav` has no nav entry.
50
+ compiled:
51
+ type: map
52
+ derived: true
53
+ description: Written by compile — `display`, the view's display merged over its collection's. What a surface draws.
54
+ display:
55
+ nav:
56
+ icon: dashboard_customize
57
+ order: 50
58
+ list:
59
+ columns: [route, scope, collection, last_modified]
@@ -0,0 +1,21 @@
1
+ name: docs
2
+ description: >-
3
+ title / content / tags, under a dated id (`2026-07-23--<title>`) — the shape of a thing that
4
+ HAPPENED or was written on a day: a note, a report, a meeting write-up. For a thing that IS, use `entity`.
5
+ use_when: a collection holds documents written on a day — list this mixin rather than restating the fields and the dated id
6
+ ids:
7
+ from: '{{ created | date }}--{{ title | slug }}'
8
+ pattern: '^\d{4}-\d{2}-\d{2}--[a-z0-9-]+$'
9
+ fields:
10
+ title:
11
+ type: string
12
+ required: true
13
+ tags:
14
+ type: string
15
+ many: true
16
+ content:
17
+ type: markdown
18
+ body: true
19
+ display:
20
+ list:
21
+ columns: [title, tags]
@@ -0,0 +1,22 @@
1
+ name: entity
2
+ description: >-
3
+ name / notes / tags, under a bare slug id (`<name>`) — the shape of a thing that IS: a person, a
4
+ supplier, a tool. No date in the id, because an entity does not happen on a day. For a dated
5
+ document, use `docs`.
6
+ use_when: a collection holds named things — list this mixin rather than restating the fields and the slug id
7
+ ids:
8
+ from: '{{ name | slug }}'
9
+ pattern: '^[a-z0-9][a-z0-9-]*$'
10
+ fields:
11
+ name:
12
+ type: string
13
+ required: true
14
+ tags:
15
+ type: string
16
+ many: true
17
+ notes:
18
+ type: markdown
19
+ body: true
20
+ display:
21
+ list:
22
+ columns: [name, tags]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dreamteamer",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "description": "A workspace compiler for coding agents — schema-validated records as plain files over git, compiled into every harness",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Gilad Khen <giladkhen@gmail.com>",
@@ -55,7 +55,8 @@
55
55
  "commands",
56
56
  "command-bindings",
57
57
  "ui-views",
58
- "collection-templates"
58
+ "mixins",
59
+ "scripts/migrate-descriptors-v2.mjs"
59
60
  ],
60
61
  "dependencies": {
61
62
  "ajv": "^8.17.1",
@@ -75,6 +76,7 @@
75
76
  "metrics": "node scripts/metrics.mjs",
76
77
  "metrics:check": "node scripts/metrics.mjs --check",
77
78
  "layers": "node scripts/layers.mjs",
78
- "verify": "node scripts/layers.mjs && node scripts/metrics.mjs --check && node scripts/test.mjs"
79
+ "verify": "node scripts/layers.mjs && node scripts/metrics.mjs --check && node scripts/test.mjs",
80
+ "verify:fast": "node scripts/layers.mjs && node scripts/metrics.mjs --check && node scripts/test.mjs --changed"
79
81
  }
80
82
  }