@awebai/oats 0.22.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/LICENSE +21 -0
- package/README.md +380 -0
- package/bin/oats.mjs +3294 -0
- package/capabilities/oats-authoring/oats.json +12 -0
- package/capabilities/oats-aweb/bin/oats-aweb.mjs +297 -0
- package/capabilities/oats-aweb/injects/aweb.md +55 -0
- package/capabilities/oats-aweb/oats.json +47 -0
- package/capabilities/oats-aweb/package.json +20 -0
- package/capabilities/oats-jira/bin/oats-jira.mjs +40 -0
- package/capabilities/oats-jira/injects/jira.md +10 -0
- package/capabilities/oats-jira/oats.json +22 -0
- package/capabilities/oats-jira/package.json +25 -0
- package/capabilities/oats-jira/skills/jira-tasks/SKILL.md +176 -0
- package/capabilities/oats-linear/README.md +234 -0
- package/capabilities/oats-linear/bin/oats-linear-hook.mjs +32 -0
- package/capabilities/oats-linear/bin/oats-linear.mjs +344 -0
- package/capabilities/oats-linear/injects/linear.md +8 -0
- package/capabilities/oats-linear/oats.json +24 -0
- package/capabilities/oats-linear/package.json +29 -0
- package/capabilities/oats-linear/skills/linear-tasks/SKILL.md +217 -0
- package/capabilities/oats-linear/test/oats-linear.test.mjs +168 -0
- package/capabilities/oats-okf/agents/memory-harvest.md +25 -0
- package/capabilities/oats-okf/bin/oats-okf.mjs +283 -0
- package/capabilities/oats-okf/injects/okf.md +62 -0
- package/capabilities/oats-okf/oats.json +20 -0
- package/capabilities/oats-okf/package.json +22 -0
- package/capabilities/oats-okf/skills/memory-harvest/SKILL.md +100 -0
- package/capabilities/oats-okf/skills/okf/SKILL.md +107 -0
- package/capabilities/oats-okf/skills/okf/scripts/okf-validate.mjs +123 -0
- package/capabilities/oats-review/agents/reviewer/AGENTS.md +53 -0
- package/capabilities/oats-review/agents/reviewer/soul.yaml +6 -0
- package/capabilities/oats-review/injects/review.md +68 -0
- package/capabilities/oats-review/oats.json +10 -0
- package/capabilities/oats-review/skills/code-review/SKILL.md +44 -0
- package/capabilities/oats-review/skills/security-review/SKILL.md +59 -0
- package/docs/capabilities.md +505 -0
- package/docs/capability-manifest.schema.json +223 -0
- package/docs/configuration.md +482 -0
- package/docs/conventions.md +73 -0
- package/docs/design/desktop-ux-plan.md +362 -0
- package/docs/design/package-engine-contract.md +813 -0
- package/docs/design/package-runtime-api.md +414 -0
- package/docs/desktop-cli-api.md +89 -0
- package/docs/desktop-succession.md +51 -0
- package/docs/desktop.md +187 -0
- package/docs/implementation.md +282 -0
- package/docs/integrations.md +123 -0
- package/docs/knowledge-theory.md +97 -0
- package/docs/knowledge.md +139 -0
- package/docs/layers.md +110 -0
- package/docs/migration-from-oas.md +122 -0
- package/docs/oats-config.schema.json +140 -0
- package/docs/oats-lock.schema.json +175 -0
- package/docs/oats-package.schema.json +129 -0
- package/docs/packages.md +442 -0
- package/docs/release-lane.md +132 -0
- package/docs/release-notes/v0.18.2.md +79 -0
- package/docs/release-notes/v0.18.3.md +63 -0
- package/docs/release-notes/v0.18.4.md +65 -0
- package/docs/release-notes/v0.18.5.md +66 -0
- package/docs/release-notes/v0.18.6.md +87 -0
- package/docs/release-notes/v0.19.0.md +186 -0
- package/docs/release-notes/v0.19.1.md +24 -0
- package/docs/release-notes/v0.19.2.md +32 -0
- package/docs/release-notes/v0.19.3.md +16 -0
- package/docs/release-notes/v0.19.4.md +12 -0
- package/docs/release-notes/v0.20.0.md +89 -0
- package/docs/release-notes/v0.22.0.md +180 -0
- package/docs/souls-and-instances.md +344 -0
- package/injects/framework-workspace.md +7 -0
- package/injects/instance-boundary.md +43 -0
- package/injects/local-soul.md +19 -0
- package/injects/oats.md +11 -0
- package/injects/work-attached.md +16 -0
- package/injects/work-checkout.md +12 -0
- package/injects/work-workspace.md +22 -0
- package/injects/work-worktree.md +13 -0
- package/lib/core.mjs +6792 -0
- package/lib/packages.mjs +1375 -0
- package/lib/tmux-config.mjs +35 -0
- package/package-catalog.json +44 -0
- package/package.json +55 -0
- package/packages/record/README.md +151 -0
- package/packages/record/bin/capture.mjs +256 -0
- package/packages/record/bin/recall.mjs +102 -0
- package/packages/record/bin/setup.mjs +281 -0
- package/packages/record/bin/turn-record.mjs +47 -0
- package/packages/record/docs/turn-record-sot.md +350 -0
- package/packages/record/lib/canonical.mjs +151 -0
- package/packages/record/lib/capture-aw.mjs +179 -0
- package/packages/record/lib/capture-cc.mjs +322 -0
- package/packages/record/lib/formats.mjs +296 -0
- package/packages/record/lib/ignore.mjs +155 -0
- package/packages/record/lib/index-db.mjs +524 -0
- package/packages/record/lib/project-aweb.mjs +251 -0
- package/packages/record/lib/segments.mjs +186 -0
- package/packages/record/lib/store.mjs +447 -0
- package/packages/record/lib/tags.mjs +114 -0
- package/packages/record/package.json +45 -0
- package/packages/record/test/vectors/README.md +34 -0
- package/packages/record/test/vectors/aweb-projection-v1.json +231 -0
- package/packages/record/test/vectors/journal-merge-v1.json +261 -0
- package/packages/record/test/vectors/turn-id-v1.json +152 -0
- package/packages/record/test/vectors/validate.mjs +391 -0
- package/skills/integration-authoring/SKILL.md +76 -0
- package/skills/oats/SKILL.md +151 -0
- package/skills/oats-config/SKILL.md +162 -0
- package/skills/oats-getting-started/SKILL.md +159 -0
- package/skills/oats-packages/SKILL.md +180 -0
- package/skills/oats-support/SKILL.md +79 -0
- package/skills/skill-craft/SKILL.md +109 -0
- package/skills/soul-craft/SKILL.md +109 -0
package/docs/packages.md
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# Distribution packages — capabilities, config templates, and host requirements
|
|
2
|
+
|
|
3
|
+
An **OATS distribution package** is the acquire, update, and review unit above
|
|
4
|
+
capabilities. It is *transport*, not the installed entity. A package is one
|
|
5
|
+
`oats-package.json` at a package root that declares one or more **capabilities**
|
|
6
|
+
and, optionally, one or more reference **config templates**.
|
|
7
|
+
|
|
8
|
+
Acquisition stages the package in a temporary transaction directory, validates
|
|
9
|
+
the whole selected payload, **materializes each declared capability** into
|
|
10
|
+
`.agents/capabilities/installed/<id>/`, writes the exact lock, and discards the
|
|
11
|
+
staging directory. There is no persistent package store. The engine side
|
|
12
|
+
(acquisition, materialization, lock, per-capability trust) has its own contract
|
|
13
|
+
in [`design/package-engine-contract.md`](design/package-engine-contract.md);
|
|
14
|
+
this document covers the config side — adopting templates, whole-workspace
|
|
15
|
+
reconciliation, and consented host-requirement installs.
|
|
16
|
+
|
|
17
|
+
A Git repository **contains** a package rather than being one. Which directory
|
|
18
|
+
holds it is part of the source contract:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
oats install git:github.com/org/repo@v1.0.0 # → repo's oats-package/ (the DEFAULT)
|
|
22
|
+
oats install git:github.com/org/repo@v1.0.0#dist/oats # → repo's dist/oats/
|
|
23
|
+
oats install git:github.com/org/repo@v1.0.0#. # → the repository ROOT
|
|
24
|
+
oats install /repo/custom-root # local: that EXACT directory
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Official examples, scaffolds, and conventions use `oats-package/`. Catalog
|
|
28
|
+
entries carry their own `path`. Local paths take no fragment and never apply the
|
|
29
|
+
default. Only the selected subtree is installed and hashed, so repository docs,
|
|
30
|
+
CI configuration, owner souls, and sibling packages stay outside the package's
|
|
31
|
+
payload and integrity. One repository may ship several packages at different
|
|
32
|
+
paths. The lock pins the selected root in its own `path` field, and only an
|
|
33
|
+
explicit `oats update <package>` may move it. See
|
|
34
|
+
[`design/package-engine-contract.md` §1.1](design/package-engine-contract.md).
|
|
35
|
+
|
|
36
|
+
Ground truth for the contract: [`oats-package.schema.json`](oats-package.schema.json),
|
|
37
|
+
[`oats-lock.schema.json`](oats-lock.schema.json), and
|
|
38
|
+
[`design/package-engine-contract.md`](design/package-engine-contract.md).
|
|
39
|
+
|
|
40
|
+
## Package is transport; capability is the installed entity
|
|
41
|
+
|
|
42
|
+
Installing a package materializes **every** capability it exports. Each installed
|
|
43
|
+
capability is a self-contained, independently hashable directory at
|
|
44
|
+
`.agents/capabilities/installed/<capability-id>/`, containing that capability's
|
|
45
|
+
own `oats.json`, skills, injections, commands, hooks, and any runtime closure.
|
|
46
|
+
That directory is where you inspect installed behavior, and it is the only thing
|
|
47
|
+
executable trust binds to.
|
|
48
|
+
|
|
49
|
+
Every package must export at least one capability. Config-only and empty
|
|
50
|
+
packages are rejected. A capability ID is unique at a scope, so two packages may
|
|
51
|
+
not both supply the same capability there.
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
<scope>/
|
|
55
|
+
oats-config.yaml # zero or one active config
|
|
56
|
+
oats-lock.json # committed provenance
|
|
57
|
+
.agents/
|
|
58
|
+
capabilities/
|
|
59
|
+
owned/<capability-id>/ # authored source; committed
|
|
60
|
+
installed/<capability-id>/ # materialized artifact; gitignored
|
|
61
|
+
config-templates/
|
|
62
|
+
adopted/<package-id>/<template-name>/
|
|
63
|
+
oats-config.yaml # the exact adopted base; commit-safe
|
|
64
|
+
adoption.json # source/version/commit/path/hash
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
At a Git-backed scope, OATS keeps `.agents/capabilities/.gitignore` ignoring only
|
|
68
|
+
`installed/`. Authored `owned/` capabilities and everything under
|
|
69
|
+
`.agents/config-templates/adopted/` are meant to be reviewed and committed, so
|
|
70
|
+
they are never ignored. Non-Git scopes use the same layout without pretending
|
|
71
|
+
Git owns their durability.
|
|
72
|
+
|
|
73
|
+
## Package config templates (`oats init --package`)
|
|
74
|
+
|
|
75
|
+
A **config template** is a complete reference `oats-config.yaml` a package ships,
|
|
76
|
+
named in `oats-package.json` under `configTemplates`. It is a recommended
|
|
77
|
+
starting point, not installed policy. Adopting one is explicit and always
|
|
78
|
+
separate from installing capabilities:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
oats init --package example.engineering # official catalog id (latest)
|
|
82
|
+
oats init --package example.engineering@1.2.0 # catalog id + pinned selector
|
|
83
|
+
oats init --package ../engineering-oats --config minimal # local path + named template
|
|
84
|
+
oats init --package https://example.invalid/pkg.git # git URL (default branch)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`oats install <package>` never adopts a template — it materializes capabilities
|
|
88
|
+
and reports available templates as optional follow-ups. Only `oats init --package`
|
|
89
|
+
(and the guided `oats config adopt`) adopt one.
|
|
90
|
+
|
|
91
|
+
New packages ship templates under a `config-templates/` directory and name them
|
|
92
|
+
with the manifest's `configTemplates` map. Each package must also give every
|
|
93
|
+
capability a dedicated self-contained root. The legacy `configs` manifest
|
|
94
|
+
spelling and a `.` (package-root) capability root stay readable only so
|
|
95
|
+
already-published tags remain consumable — new authoring never emits them.
|
|
96
|
+
|
|
97
|
+
Behavior:
|
|
98
|
+
|
|
99
|
+
- **Preview and validation first.** The template must be valid against the
|
|
100
|
+
config schema. Every `from: installed` capability it references must be
|
|
101
|
+
supplied by the package or its dependency closure. Layer bindings must agree
|
|
102
|
+
with the capability manifests. Agent types must be syntactically valid. No
|
|
103
|
+
path — injection overrides, work-mode setup scripts — may escape the target
|
|
104
|
+
scope. A failing template is never written, and the scope is left untouched.
|
|
105
|
+
- **Default selection.** A template marked `"default": true` is chosen when
|
|
106
|
+
`--config` is omitted. A single template is chosen implicitly. Several
|
|
107
|
+
unmarked templates require `--config <name>`, and refusing to guess is the
|
|
108
|
+
point.
|
|
109
|
+
- **Overwrite refusal.** `oats init --package` refuses when an `oats-config.yaml`
|
|
110
|
+
already exists at the scope. Use `oats config adopt` to switch an existing
|
|
111
|
+
scope to another template.
|
|
112
|
+
- **The adopted base is recorded.** Adoption writes the exact template as a
|
|
113
|
+
commit-safe base under `.agents/config-templates/adopted/<package>/<template>/`,
|
|
114
|
+
alongside an `adoption.json` recording source, version, commit, path, and hash.
|
|
115
|
+
Commit it — `oats config diff` and `oats config sync` compare against it. For a
|
|
116
|
+
local `path:` source, `adoption.json` records `source: null` with
|
|
117
|
+
`localSource: true`, so no absolute machine path leaks into the committed
|
|
118
|
+
metadata; the exact source stays only in the authoritative lock.
|
|
119
|
+
|
|
120
|
+
### Your config is yours (adopter sovereignty)
|
|
121
|
+
|
|
122
|
+
The adopted config is an **ordinary scoped config**. It is not live inheritance
|
|
123
|
+
and not ambient package policy. `oats use`, `oats type`, `oats inject eject`, and
|
|
124
|
+
hand edits keep their meaning, and package updates never rewrite it or the
|
|
125
|
+
adopted base. Every capability an installed package exports stays individually
|
|
126
|
+
addressable, so you may
|
|
127
|
+
|
|
128
|
+
- **retarget** a capability from global to an agent type or soul
|
|
129
|
+
(`oats use example.review --type reviewers`);
|
|
130
|
+
- **disable** something the template enabled
|
|
131
|
+
(`oats use example.review --global --disable`, or `knowledge: none` for a
|
|
132
|
+
layer);
|
|
133
|
+
- **re-set settings** per family (`oats use example.review --soul dev
|
|
134
|
+
--settings depth=high`);
|
|
135
|
+
- **replace** an exclusive-layer provider with another capability; and
|
|
136
|
+
- **override from a nested repository** — a closer repo's `oats-config.yaml`
|
|
137
|
+
wins per the normal cascade:
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
# member-repo/oats-config.yaml — this repo opts out of the workspace default
|
|
141
|
+
name: member
|
|
142
|
+
capabilities:
|
|
143
|
+
layers:
|
|
144
|
+
knowledge: none
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Nothing a package ships is mandatory. Every copied setting is fully locally
|
|
148
|
+
editable, and the resolved local config is always authoritative.
|
|
149
|
+
|
|
150
|
+
### Guided template sync (`oats config diff | sync | adopt`)
|
|
151
|
+
|
|
152
|
+
Your config and a package's template drift as you edit locally and as the
|
|
153
|
+
package updates. Three commands manage that, and all three share one three-way
|
|
154
|
+
comparison — the recorded **adopted base**, your current local
|
|
155
|
+
`oats-config.yaml`, and the selected template read from the currently locked
|
|
156
|
+
package.
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
oats config diff # report only; nothing is written
|
|
160
|
+
oats config sync # apply upstream changes; keep local edits
|
|
161
|
+
oats config sync --accept <id>=local # resolve one conflict region in favor of local
|
|
162
|
+
oats config sync --accept <id>=package # resolve one conflict region in favor of the template
|
|
163
|
+
oats config sync --reset --yes # discard local changes; take the template verbatim
|
|
164
|
+
oats config adopt other.package --config default # switch to a different base
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
- **`oats config diff`** reports how your config, the adopted base, and the
|
|
168
|
+
package's current template differ. It classifies each region as
|
|
169
|
+
upstream-only, local-only, or a conflict, and writes nothing.
|
|
170
|
+
- **`oats config sync`** applies upstream-only changes and keeps local-only
|
|
171
|
+
edits. It presents the complete plan before touching anything, preserves the
|
|
172
|
+
untouched bytes, comments, order, and formatting of your file, and advances
|
|
173
|
+
the adopted base only after a successful write. A recoverable `.bak` backup
|
|
174
|
+
survives the run.
|
|
175
|
+
- **Conflicts require an explicit choice.** A region changed both locally and
|
|
176
|
+
upstream is a conflict. `oats config sync` never picks a side for you.
|
|
177
|
+
Interactively it prompts per region. Noninteractively (or with `--json`) it
|
|
178
|
+
fails with `E_SYNC_AMBIGUOUS` unless you pass `--accept <regionId>=local` or
|
|
179
|
+
`--accept <regionId>=package` for each one.
|
|
180
|
+
- **`oats config sync --reset`** is the exact-template replacement path. It
|
|
181
|
+
previews every local change region it will discard, backs up the current
|
|
182
|
+
config, then replaces both the config and the adopted-base metadata. It
|
|
183
|
+
demands strong confirmation interactively, and `--yes` to accept the loss
|
|
184
|
+
noninteractively.
|
|
185
|
+
- **`oats config adopt <package> --config <name>`** switches the one local config
|
|
186
|
+
to a different base. It rebases your config against the new template rather
|
|
187
|
+
than creating a second config, and exactly one adopted base remains afterward.
|
|
188
|
+
|
|
189
|
+
## Workspace reconciliation (bare `oats install`)
|
|
190
|
+
|
|
191
|
+
At a config scope that declares `team:`, bare `oats install` reconciles the whole
|
|
192
|
+
workspace instead of only the ancestor chain:
|
|
193
|
+
|
|
194
|
+
1. prints the chosen boundary **before any network or host work**;
|
|
195
|
+
2. restores the boundary scope's locked graph;
|
|
196
|
+
3. discovers descendant scopes containing `oats-config.yaml` or `oats-lock.json`,
|
|
197
|
+
in deterministic path order, pruning `.git`, generated stores (`.agents/`),
|
|
198
|
+
dependency/vendor directories (`node_modules`, `vendor`, virtualenvs), agent
|
|
199
|
+
instances/worktrees, `local-agents/`, **package payload** (below), and
|
|
200
|
+
**nested team boundaries** (each is its own reconciliation unit);
|
|
201
|
+
4. restores each descendant scope once;
|
|
202
|
+
5. validates that every config-referenced installed capability is supplied by a
|
|
203
|
+
visible locked package (or capability lock); and
|
|
204
|
+
6. aggregates missing requirements and failures **by scope**.
|
|
205
|
+
|
|
206
|
+
**Package payload is never a scope.** A directory holding an `oats-package.json`
|
|
207
|
+
is a package root, and everything beneath it is content the package *exports* —
|
|
208
|
+
including the `configTemplates` files under `config-templates/`. Those templates
|
|
209
|
+
bind layers to capabilities the adopting deployment has not installed yet, so
|
|
210
|
+
reconciling one as a live scope would report phantom "supplied by no visible
|
|
211
|
+
locked package" failures for the whole team. Discovery therefore excludes any
|
|
212
|
+
candidate whose containing **ancestor** directory carries an `oats-package.json`,
|
|
213
|
+
whatever the payload root is named — templates are never reconciled, validated,
|
|
214
|
+
or acquired. The rule is the manifest, not the path: a repository that ships a
|
|
215
|
+
package *and* is itself a deployment scope (its own `oats-config.yaml` at the
|
|
216
|
+
root, with the manifest in a subdirectory) stays a scope exactly as before.
|
|
217
|
+
|
|
218
|
+
At a non-team scope, bare `oats install` keeps current-chain behavior. Pass
|
|
219
|
+
`--recursive` to request descendant reconciliation outside a team boundary — the
|
|
220
|
+
boundary is still printed first. OATS never scans downward from the laptop/home
|
|
221
|
+
config by default.
|
|
222
|
+
|
|
223
|
+
## Host requirements — a separate consent gate
|
|
224
|
+
|
|
225
|
+
A capability `requires` entry may declare structured, platform-aware install
|
|
226
|
+
methods (the legacy `install: "https://…"` docs URL still works):
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"command": "example-cli",
|
|
231
|
+
"why": "send and receive team messages",
|
|
232
|
+
"install": {
|
|
233
|
+
"docs": "https://example.invalid/install",
|
|
234
|
+
"methods": [
|
|
235
|
+
{ "platform": "darwin", "manager": "npm-global", "package": "@example/cli@1.2.3" }
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Rules (all enforced):
|
|
242
|
+
|
|
243
|
+
- **Allowlisted managers only**: `npm-global` and `brew`
|
|
244
|
+
(download-with-checksum is declared but not implemented yet). Recipes are
|
|
245
|
+
data — argv arrays, never shell snippets, no sudo, no shell metacharacters, no
|
|
246
|
+
authentication.
|
|
247
|
+
- **Informed, per-requirement consent.** Interactive `oats install` shows the
|
|
248
|
+
exact command, source, version, and whether it changes user- or machine-level
|
|
249
|
+
state, then asks per requirement. A plan may take more than one command — a
|
|
250
|
+
runtime package can need its source registered first — so both the human and
|
|
251
|
+
`--json` renderings carry `steps`, the ordered argv sequence that will run,
|
|
252
|
+
alongside `argv` (its final command). What you consent to is the whole
|
|
253
|
+
sequence. Nothing runs that the plan did not show.
|
|
254
|
+
- **Aggregation is scoped**: only capabilities *activated somewhere in the
|
|
255
|
+
reconciled scopes* are considered, deduplicated by required command, and the
|
|
256
|
+
report names which capabilities requested each command.
|
|
257
|
+
- **Noninteractive runs never install by default.** Automation names each
|
|
258
|
+
accepted requirement: `oats install --accept-requirement example-cli`.
|
|
259
|
+
`--no-requirements` restores packages only (CI). A **consented** install that
|
|
260
|
+
fails (manager error, or the command still absent from PATH) makes
|
|
261
|
+
`oats install` exit nonzero so automation can detect it. Unaccepted or skipped
|
|
262
|
+
requirements stay non-fatal.
|
|
263
|
+
- **PATH verification** runs after each install. A tool that does not land on
|
|
264
|
+
PATH is reported honestly.
|
|
265
|
+
- **Skipping is safe**: `oats doctor` keeps an actionable warning (the consent
|
|
266
|
+
command to run) until the command is on PATH.
|
|
267
|
+
- **Trust and requirement consent are distinct gates.** Installing a binary
|
|
268
|
+
neither activates nor approves any capability, and capability trust never
|
|
269
|
+
authorizes host installs.
|
|
270
|
+
|
|
271
|
+
When no safe recipe matches the host, OATS prints the documented install URL.
|
|
272
|
+
|
|
273
|
+
## Lock, trust, and restore
|
|
274
|
+
|
|
275
|
+
The scope's `oats-lock.json` uses `lockfileVersion: 2` and records both levels of
|
|
276
|
+
the model in separate top-level maps:
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
{
|
|
280
|
+
"lockfileVersion": 2,
|
|
281
|
+
"packages": {
|
|
282
|
+
"example.engineering": {
|
|
283
|
+
"source": "git:https://example.invalid/engineering.git@v3.0.0",
|
|
284
|
+
"version": "3.0.0",
|
|
285
|
+
"commit": "0123456789abcdef0123456789abcdef01234567",
|
|
286
|
+
"path": "oats-package",
|
|
287
|
+
"integrity": "sha256-…",
|
|
288
|
+
"dependencies": []
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"capabilities": {
|
|
292
|
+
"example.review": {
|
|
293
|
+
"version": "2.1.0",
|
|
294
|
+
"package": "example.engineering",
|
|
295
|
+
"path": "capabilities/example-review",
|
|
296
|
+
"integrity": "sha256-…",
|
|
297
|
+
"trusted": false
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
- The `packages` map proves **where the bytes came from** — exact source,
|
|
304
|
+
commit, selected root path, payload integrity, and package-identity
|
|
305
|
+
dependencies. It does not describe an installed directory, because there is no
|
|
306
|
+
persistent package store.
|
|
307
|
+
- The `capabilities` map proves **each materialized artifact** — its version,
|
|
308
|
+
its provider package (a key of the `packages` map), its dedicated root path
|
|
309
|
+
inside that package, its artifact integrity, and its executable trust.
|
|
310
|
+
- **Trust binds to the capability artifact integrity, never to package
|
|
311
|
+
identity.** `oats trust <capability>` approves that capability's commands and
|
|
312
|
+
hooks at exactly its current artifact integrity. Any integrity change,
|
|
313
|
+
including `oats update`, resets `trusted` to false and forces re-review.
|
|
314
|
+
Official catalog identity grants no executable trust, and there is no
|
|
315
|
+
package-level approval.
|
|
316
|
+
- Bare `oats install` fetches the exact locked source, verifies package
|
|
317
|
+
integrity, re-materializes any missing capability artifact, verifies its
|
|
318
|
+
individual integrity, and never advances source, version, or commit.
|
|
319
|
+
|
|
320
|
+
## Upgrading a 0.18 deployment to the official packages
|
|
321
|
+
|
|
322
|
+
Deployments created before official packages existed hold ordinary
|
|
323
|
+
`oats-config.yaml` files, **v1** `oats-lock.json` files, and acquired capability
|
|
324
|
+
artifacts under `.agents/capabilities/installed/`. Those keep working. A valid
|
|
325
|
+
v1 lock still restores, activates, trusts, and spawns, and installing this
|
|
326
|
+
release migrates nothing on its own.
|
|
327
|
+
|
|
328
|
+
The upgrade is one explicit, guided command, and it lands directly in the
|
|
329
|
+
revised `lockfileVersion: 2`:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
oats migrate --official --recursive --dry-run --dir <team-root> # plan first
|
|
333
|
+
oats migrate --official --recursive --dir <team-root> # apply
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
- **Scope discovery** is deterministic and covers every *visible* lock-owning
|
|
337
|
+
scope: the explicit scope's ancestor chain (so an outer repo/laptop lock the
|
|
338
|
+
deployment actually reads is migrated too), the team boundary, and descendant
|
|
339
|
+
config/lock scopes found with reconciliation's pruning (nested team boundaries
|
|
340
|
+
stay self-owned). Scopes are planned and applied in path order, ancestors
|
|
341
|
+
first. Without `--recursive` only the named scope is migrated.
|
|
342
|
+
- **Plan first, always.** The complete per-scope plan is printed (and available
|
|
343
|
+
as stable JSON) before anything is applied. `--dry-run` stops after it.
|
|
344
|
+
- **Which package supplies which capability is catalog data**, never code. The
|
|
345
|
+
catalog maps identity by default (capability `oats.okf` → package `oats.okf`)
|
|
346
|
+
and carries explicit aliases for capabilities a package exports under another
|
|
347
|
+
identity (`oats.review` → package `oats.dev`). See the catalog shape below.
|
|
348
|
+
- **Config files are not rewritten.** Packages export the same capability IDs,
|
|
349
|
+
so activation, layer bindings, targets, settings, exclusions, and injection
|
|
350
|
+
overrides remain valid byte-for-byte.
|
|
351
|
+
- **Held, never half-converted.** If any official capability cannot map, the
|
|
352
|
+
whole scope stays byte-identical v1 and the run is nonzero. A `--dry-run`
|
|
353
|
+
reports the same blocked status, so readiness cannot be mistaken for success.
|
|
354
|
+
- **Custom entries block a mixed guided scope.** `git:`/`path:`/unknown v1
|
|
355
|
+
sources are never acquired by `--official`. A scope containing only those
|
|
356
|
+
entries is skipped and reports their IDs under `retained`; a scope mixing them
|
|
357
|
+
with official capabilities is refused before any write. Plain `oats migrate`
|
|
358
|
+
can convert custom sources only when every entry in the scope maps to a
|
|
359
|
+
package. There is no residue container.
|
|
360
|
+
- **One package, several capabilities.** When catalog aliases map more than one
|
|
361
|
+
legacy capability onto the same package, all of them convert together and the
|
|
362
|
+
package is acquired once.
|
|
363
|
+
- **Per scope transactional.** Each scope acquires its package closure, writes
|
|
364
|
+
a fresh revised v2 lock, and only then removes the superseded v1 artifacts. A
|
|
365
|
+
failing scope is rolled back byte-identically. Other scopes keep their
|
|
366
|
+
(truthfully reported) result, and the aggregate exit is nonzero.
|
|
367
|
+
- **Trust is re-earned, never transferred.** A capability's materialized
|
|
368
|
+
integrity is not its v1 artifact's integrity, so approvals do not carry over.
|
|
369
|
+
The run prints the exact `oats trust <capability> --dir <scope>` commands, then
|
|
370
|
+
the bare `oats install --dir <scope>` pass (already-installed host requirements
|
|
371
|
+
verify and are not reinstalled; anything missing gets its
|
|
372
|
+
`oats install --accept-requirement <cmd>` consent command).
|
|
373
|
+
|
|
374
|
+
Rerunning the command after a successful migration changes nothing.
|
|
375
|
+
|
|
376
|
+
### The transitional v2 lock is not migrated
|
|
377
|
+
|
|
378
|
+
An earlier, unreleased shape of `lockfileVersion: 2` stored capability lists and
|
|
379
|
+
trust on the package rows and used a persistent `.agents/packages/installed/`
|
|
380
|
+
store. That transitional shape receives no product migration path. The reader
|
|
381
|
+
rejects it centrally as `invalid-lock` with actionable guidance. It is recreated
|
|
382
|
+
by a fresh acquisition, never converted or partially interpreted. There is no
|
|
383
|
+
`lockfileVersion: 3`. Because the transitional contract had no external
|
|
384
|
+
adoption, the founder chose to replace it in place rather than carry a migration
|
|
385
|
+
for it.
|
|
386
|
+
|
|
387
|
+
### Catalog shape
|
|
388
|
+
|
|
389
|
+
The official catalog is data (`package-catalog.json`, or the file named by
|
|
390
|
+
`OATS_PACKAGE_CATALOG`):
|
|
391
|
+
|
|
392
|
+
```json
|
|
393
|
+
{
|
|
394
|
+
"packages": {
|
|
395
|
+
"oats.okf": { "url": "https://github.com/awebai/oats-okf.git", "ref": "v1.4.1", "path": "oats-package" },
|
|
396
|
+
"oats.dev": { "url": "https://github.com/awebai/oats-dev.git", "ref": "v1.0.0", "path": "oats-package" }
|
|
397
|
+
},
|
|
398
|
+
"capabilities": { "oats.review": "oats.dev" }
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
`packages` is identity and discovery only — resolving through it never advances
|
|
403
|
+
a lock and never grants executable trust. The released kernel bundles the
|
|
404
|
+
official awebai entries. Once a short id appears there, `oats install <id>`
|
|
405
|
+
prefers the distribution package over the legacy bundled capability marketplace.
|
|
406
|
+
Existing v1 locks and artifacts remain supported until you run guided migration.
|
|
407
|
+
`capabilities` is the legacy-capability → package alias map the guided migration
|
|
408
|
+
reads; identity mappings need no entry. An alias value may also be spelled
|
|
409
|
+
`{ "package": "<id>" }`.
|
|
410
|
+
|
|
411
|
+
## Doctor
|
|
412
|
+
|
|
413
|
+
`oats doctor` reports, in addition to its capability diagnostics:
|
|
414
|
+
|
|
415
|
+
- **Distribution packages** visible in the lock (`packages:` in
|
|
416
|
+
`oats-lock.json`), with source and the capabilities each supplies;
|
|
417
|
+
- **adopted config templates** in the chain — the package and template each
|
|
418
|
+
scope adopted, its recorded base, and whether local changes have drifted from
|
|
419
|
+
it;
|
|
420
|
+
- **available-but-unadopted templates** — a locked, installed package exporting
|
|
421
|
+
config templates that no scope has adopted;
|
|
422
|
+
- **missing host commands** for active capabilities, with the exact consent
|
|
423
|
+
command when a safe installer exists;
|
|
424
|
+
- **official capability migration** (`officialMigration` in `--json`) when the
|
|
425
|
+
chain still holds legacy `marketplace:` locks: each capability with the
|
|
426
|
+
package that supplies it, and either `ready` with the exact
|
|
427
|
+
`oats migrate --official --recursive --dir <boundary>` command, or `unavailable`
|
|
428
|
+
with the reason — the catalog has no mapping yet and the legacy capabilities
|
|
429
|
+
remain supported.
|
|
430
|
+
|
|
431
|
+
## Engine integration
|
|
432
|
+
|
|
433
|
+
The package engine (acquisition, capability materialization, revised v2 lock,
|
|
434
|
+
exact restore, capability indexing, per-capability trust — see
|
|
435
|
+
[`design/package-engine-contract.md`](design/package-engine-contract.md) and
|
|
436
|
+
[`design/package-runtime-api.md`](design/package-runtime-api.md)) is merged.
|
|
437
|
+
`oats init --package` acquires and exact-locks the full closure through the
|
|
438
|
+
engine's `acquirePackage` for every source kind (git, catalog, local path), then
|
|
439
|
+
adopts exactly one template. The team-boundary reconciliation above wraps the
|
|
440
|
+
engine's exact-restore primitive (integrity, capability, and runtime-closure
|
|
441
|
+
verification) per scope. Legacy v1 capability locks keep restoring via the
|
|
442
|
+
capability path and are reported as LEGACY with the `oats migrate` pointer.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# The runnerless release lane
|
|
2
|
+
|
|
3
|
+
`scripts/release-lane.mjs` releases OATS without GitHub Actions. It is the
|
|
4
|
+
same release as [`.github/workflows/release.yml`](../.github/workflows/release.yml),
|
|
5
|
+
run phase by phase on operator machines, with every output written under a
|
|
6
|
+
stage directory so the release can stop and resume at any phase.
|
|
7
|
+
|
|
8
|
+
The policy it satisfies: no release capability may permanently depend on
|
|
9
|
+
GitHub or GitHub Actions. Registry publish works on its own; tags and hosted
|
|
10
|
+
release assets can follow later.
|
|
11
|
+
|
|
12
|
+
## When to use it
|
|
13
|
+
|
|
14
|
+
- **Runner outage.** GitHub Actions is down, queued, or a runner image has
|
|
15
|
+
broken under the workflow. Build and publish here; push the tag and let the
|
|
16
|
+
workflow catch up when it can.
|
|
17
|
+
- **Urgent release.** The kernel fix must reach npm now. `build` and
|
|
18
|
+
`publish-npm` are enough for that; Desktop installers and the GitHub Release
|
|
19
|
+
follow when they are ready.
|
|
20
|
+
- **By choice.** Any release may be cut this way. The gates are the workflow's
|
|
21
|
+
gates; only the host differs.
|
|
22
|
+
|
|
23
|
+
## Phases
|
|
24
|
+
|
|
25
|
+
Every phase takes `--tag vX.Y.Z` and reads or writes `stage/<tag>/`
|
|
26
|
+
(gitignored; `--stage <dir>` overrides). `MANIFEST.json` there records the
|
|
27
|
+
SHA, the tarballs and their digests, the assets, and which phases completed.
|
|
28
|
+
Every external command is printed before it runs and its output is logged
|
|
29
|
+
under `stage/<tag>/logs/`; a failing step exits non-zero with the log path.
|
|
30
|
+
|
|
31
|
+
| Phase | Mirrors in `release.yml` | Writes |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| `build --tag vX.Y.Z [--sha <commit>]` | job `build-and-test`: notes gate, three-manifest bump, `node --check`, `npm ci`, `npm run check`, Desktop test deps, `npm test`, `pack:check` and the tarball greps, `smoke:tarball`, the `version --json` probe | `npm/*.tgz`, `MANIFEST.json` |
|
|
34
|
+
| `desktop --tag vX.Y.Z --arch arm64\|x64` | one `desktop-build` matrix leg: desktop `npm ci`, `npm test`, `npm run dist -- --<arch>`, strict deep `codesign --verify` (macOS), `dist:smoke` in build-verify mode | `assets/oats-desktop-*` |
|
|
35
|
+
| `stage --tag vX.Y.Z` | publish job, "Checksums" (`shasum -a 256`) | `assets/SHA256SUMS.txt` |
|
|
36
|
+
| `publish-npm --tag vX.Y.Z [--dry-run] --yes` | publish job, the two guarded `npm publish --access public` steps, kernel then adapter | — |
|
|
37
|
+
| `tag --tag vX.Y.Z [--push --yes]` | the tag push that triggers the workflow | annotated tag |
|
|
38
|
+
| `release-github --tag vX.Y.Z --yes` | publish job, `gh release create` / `gh release upload --clobber` | GitHub Release |
|
|
39
|
+
| `status --tag vX.Y.Z` | — | prints what ran, what exists, what remains |
|
|
40
|
+
|
|
41
|
+
`build` refuses on a dirty working tree and, like the workflow, refuses a SHA
|
|
42
|
+
that is not on `origin/main` (`--allow-off-main` is the explicit human
|
|
43
|
+
override; report the risk you accepted). It never touches the checkout it
|
|
44
|
+
runs from: it exports the SHA into a detached worktree under the system
|
|
45
|
+
temporary directory (recorded in `MANIFEST.json`, `--export <dir>` overrides)
|
|
46
|
+
and runs every build step there. The bumped manifests exist only in that
|
|
47
|
+
export; the version-bump commit to `main` remains the workflow's job, or a
|
|
48
|
+
manual PR.
|
|
49
|
+
|
|
50
|
+
`publish-npm` and `release-github` print their plan and refuse without
|
|
51
|
+
`--yes`. `tag` creates the local tag without `--yes` but pushes only with
|
|
52
|
+
`--push --yes`. Authentication for npm is whatever `npm whoami` reports, or
|
|
53
|
+
`NPM_TOKEN` when set: the token goes into a temporary `.npmrc` handed to npm
|
|
54
|
+
through `NPM_CONFIG_USERCONFIG` and deleted afterwards, never into the repo.
|
|
55
|
+
|
|
56
|
+
## A full release from a Mac plus a Linux host
|
|
57
|
+
|
|
58
|
+
Release notes must exist at `docs/release-notes/<tag>.md` on the commit being
|
|
59
|
+
released, and the commit must be on `origin/main`. On the Mac:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
git fetch origin
|
|
63
|
+
node scripts/release-lane.mjs build --tag v0.22.0 # minutes
|
|
64
|
+
node scripts/release-lane.mjs desktop --tag v0.22.0 --arch arm64
|
|
65
|
+
node scripts/release-lane.mjs desktop --tag v0.22.0 --arch x64 # needs Rosetta on an arm64 Mac
|
|
66
|
+
node scripts/release-lane.mjs status --tag v0.22.0
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
On the Linux host, from a checkout of the same commit:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
node scripts/release-lane.mjs build --tag v0.22.0
|
|
73
|
+
node scripts/release-lane.mjs desktop --tag v0.22.0 --arch x64
|
|
74
|
+
# then copy stage/v0.22.0/assets/oats-desktop-*-linux-x64.* back to the Mac's stage/v0.22.0/assets/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The Linux `build` repeats the kernel checks on that host; its tarballs are
|
|
78
|
+
not used. Only the assets travel. Back on the Mac:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
node scripts/release-lane.mjs stage --tag v0.22.0 # SHA256SUMS.txt over all six assets
|
|
82
|
+
node scripts/release-lane.mjs publish-npm --tag v0.22.0 --dry-run --yes
|
|
83
|
+
node scripts/release-lane.mjs publish-npm --tag v0.22.0 --yes # kernel, then adapter
|
|
84
|
+
node scripts/release-lane.mjs tag --tag v0.22.0 --push --yes
|
|
85
|
+
node scripts/release-lane.mjs release-github --tag v0.22.0 --yes
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
An urgent kernel-only release is `build`, `publish-npm --yes`, and `tag --push
|
|
89
|
+
--yes`; the Desktop legs, `stage`, and `release-github` run later against the
|
|
90
|
+
same stage directory.
|
|
91
|
+
|
|
92
|
+
## What is resumable
|
|
93
|
+
|
|
94
|
+
Everything after `build` reads `MANIFEST.json` and the files already staged:
|
|
95
|
+
|
|
96
|
+
- A failed step is rerun by rerunning its phase. `build` is build-once: it
|
|
97
|
+
recreates the export and the tarballs; it refuses a stage directory built
|
|
98
|
+
from a different SHA unless `--force`.
|
|
99
|
+
- `desktop` legs run in any order, on any number of hosts, days apart. A
|
|
100
|
+
missing export is recreated from the recorded SHA.
|
|
101
|
+
- `stage` recomputes the checksums over whatever is in `assets/` and lists
|
|
102
|
+
the legs still missing.
|
|
103
|
+
- `publish-npm` skips any version `npm view` already reports live, exactly as
|
|
104
|
+
the workflow does on a same-tag retry, so it can be rerun after a partial
|
|
105
|
+
failure or after the workflow published one of the two.
|
|
106
|
+
- `release-github` uploads with `--clobber` when the release exists.
|
|
107
|
+
|
|
108
|
+
## What the lane cannot produce
|
|
109
|
+
|
|
110
|
+
- **Build-provenance attestations.** `actions/attest-build-provenance` and
|
|
111
|
+
npm's provenance both require the GitHub OIDC identity; nothing off-runner
|
|
112
|
+
can mint them. A lane-published npm version has no provenance badge, and a
|
|
113
|
+
lane-created GitHub Release has no attestation. Pushing the tag afterwards
|
|
114
|
+
runs `release.yml`, whose steps are idempotent: it skips the live npm
|
|
115
|
+
versions, re-uploads the same assets, and attaches the attestations. That
|
|
116
|
+
later pass is the way to add provenance; nothing is republished.
|
|
117
|
+
- **The version-bump PR.** The workflow's final step; open it by hand if the
|
|
118
|
+
workflow does not run.
|
|
119
|
+
- **Legs for hosts you do not have.** The Linux AppImage/DEB need a Linux
|
|
120
|
+
host; the lane says so and `stage` lists what is missing.
|
|
121
|
+
|
|
122
|
+
## How it relates to `release.yml`
|
|
123
|
+
|
|
124
|
+
`release.yml` is unchanged and remains the default path: pushing a tag runs
|
|
125
|
+
it end to end. The lane mirrors its jobs and steps rather than reimplementing
|
|
126
|
+
their checks — it calls the same `npm run check`, `npm test`, `pack:check`,
|
|
127
|
+
`smoke:tarball`, `dist`, and `dist:smoke` scripts with the same environment
|
|
128
|
+
the workflow sets. `test/release-workflow.test.mjs` pins the workflow's
|
|
129
|
+
contract; `test/release-lane.test.mjs` covers the lane's gates and phase
|
|
130
|
+
logic against fixtures, with `npm` stubbed. The two can run in either order:
|
|
131
|
+
a lane release followed by a workflow run, or a broken workflow run finished
|
|
132
|
+
by the lane, and neither republishes what the other already did.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# OATS v0.18.2
|
|
2
|
+
|
|
3
|
+
One public release, built from one tag: `@awebai/oats@0.18.2`,
|
|
4
|
+
`@awebai/oats-pi@0.18.2`, and **OATS Desktop 0.18.2** (attached to this
|
|
5
|
+
GitHub Release).
|
|
6
|
+
|
|
7
|
+
## OATS Desktop
|
|
8
|
+
|
|
9
|
+
The Desktop app is the control panel for OATS deployments: roster/hierarchy,
|
|
10
|
+
brain/markdown/task/state views, terminal attach to existing tmux windows,
|
|
11
|
+
and — with a compatible CLI installed — spawning agents from the Soul
|
|
12
|
+
roster.
|
|
13
|
+
|
|
14
|
+
Downloads (assets on this release):
|
|
15
|
+
|
|
16
|
+
| Platform | Artifacts |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| macOS arm64 (Apple Silicon) | DMG + ZIP |
|
|
19
|
+
| macOS x64 (Intel) | DMG + ZIP |
|
|
20
|
+
| Linux x64 | AppImage + DEB |
|
|
21
|
+
|
|
22
|
+
Verify with `SHA256SUMS.txt`; GitHub build-provenance attestations are
|
|
23
|
+
published for all assets.
|
|
24
|
+
|
|
25
|
+
**Windows and Linux arm64 are not supported in 0.18.2.**
|
|
26
|
+
|
|
27
|
+
The 0.18.2 installers are **unsigned and not notarized**. On macOS, open via
|
|
28
|
+
right-click → Open (or `xattr -dr com.apple.quarantine` the app) the first
|
|
29
|
+
time. On Linux, `tmux` is a prerequisite.
|
|
30
|
+
|
|
31
|
+
### CLI compatibility
|
|
32
|
+
|
|
33
|
+
Desktop 0.18 requires an `oats` CLI with Desktop API v1: version
|
|
34
|
+
`>=0.18.0 <0.19.0`. Install or update:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install -g @awebai/oats@0.18.2
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Without a compatible CLI, Desktop remains usable read-only (roster, files,
|
|
41
|
+
existing terminals); Spawn is disabled with guidance to install the CLI
|
|
42
|
+
(memory harvest runs through the same CLI boundary in the backend; no
|
|
43
|
+
dedicated button in this release). The probe contract is documented in
|
|
44
|
+
`docs/desktop-cli-api.md`; the full install/migration/support guide is
|
|
45
|
+
[docs/desktop.md](https://github.com/awebai/oats/blob/main/docs/desktop.md).
|
|
46
|
+
|
|
47
|
+
## Breaking changes (root package)
|
|
48
|
+
|
|
49
|
+
This release removes the legacy web/TUI panel surfaces. Removal was approved
|
|
50
|
+
after the operator confirmed there were no other legacy-panel users.
|
|
51
|
+
|
|
52
|
+
- **`oats.web` capability removed.** Deployments that still declare it get a
|
|
53
|
+
doctor-guided migration error: remove the `oats.web` entry from
|
|
54
|
+
`oats-config.yaml` (`capabilities.additive`) and from `oats-lock.json` at
|
|
55
|
+
that scope. `oats doctor`/`oats doctor --json` reports stale config entries,
|
|
56
|
+
stale locks (`retiredLocks`), and leftover installed artifacts
|
|
57
|
+
(`retiredArtifacts`) with the cleanup instruction.
|
|
58
|
+
- **`oats pane` removed.** The command now errors with a pointer to the
|
|
59
|
+
Desktop app.
|
|
60
|
+
- **`@awebai/oats/control-pane` export removed.** No replacement —
|
|
61
|
+
the Desktop app bundles its own server.
|
|
62
|
+
|
|
63
|
+
## New in the CLI
|
|
64
|
+
|
|
65
|
+
- `oats version [--json]` — the Desktop API v1 probe:
|
|
66
|
+
`{"schemaVersion":1,"name":"@awebai/oats","version":"0.18.2","desktopApi":1}`.
|
|
67
|
+
- `oats spawn … --json` and `oats okf harvest --json` now emit the stable
|
|
68
|
+
Desktop API v1 envelope (`{"schemaVersion":1,"ok":…}`), with exactly one
|
|
69
|
+
JSON object on stdout and stable error codes. Non-JSON output is unchanged.
|
|
70
|
+
|
|
71
|
+
## Migration
|
|
72
|
+
|
|
73
|
+
1. Update the CLI everywhere: `npm install -g @awebai/oats@0.18.2`
|
|
74
|
+
(the pi bridge `@awebai/oats-pi` publishes in lockstep; restart pi
|
|
75
|
+
sessions).
|
|
76
|
+
2. Run `oats doctor` at each workspace/repo scope and follow its guidance to
|
|
77
|
+
remove stale `oats.web` config entries, locks, and installed artifacts.
|
|
78
|
+
3. Replace any `oats pane` / control-pane usage with the Desktop app
|
|
79
|
+
(download above).
|