octwin-cli 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +91 -0
- package/README.md +13 -1
- package/dist/index.js +1413 -323
- package/dist/lib/render-check.js +64 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,97 @@ Format: [Keep a Changelog](https://keepachangelog.com/) — newest first, bucket
|
|
|
5
5
|
**Added · Changed · Deprecated · Removed · Fixed · Security**. The platform-wide view lives in the
|
|
6
6
|
repo root [`CHANGELOG.md`](../../CHANGELOG.md); this file is the CLI-only cut that ships with the package.
|
|
7
7
|
|
|
8
|
+
## [0.8.0] - 2026-08-27
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Five new command families, closing the gap between what a token reaches and what the CLI can
|
|
12
|
+
ask.** A **Full CLI access** token spans the whole scope registry, and four of those domains had
|
|
13
|
+
no command at all — so the reach existed and there was nothing to type.
|
|
14
|
+
- `octwin automation [campaigns]` — every job the pack's declaration produced, with status,
|
|
15
|
+
interval and last result (matched / acted / errors), under a health line whose counts come from
|
|
16
|
+
SQL rather than from filtering the page (the job list is capped server-side, so a client-side
|
|
17
|
+
count would depend on the cap). Writes: `run` · `pause` · `resume` · `send <campaignId>`.
|
|
18
|
+
- `octwin integrations` — what the pack **declares** beside what is actually **configured**, in
|
|
19
|
+
one view, because a connection declared and never configured is the commonest reason an
|
|
20
|
+
integration silently never fires and neither list alone can show it. Plus
|
|
21
|
+
`preflight <key>` (diagnosis, no outbound call, `integrations:read`), `test <key>` (a live call,
|
|
22
|
+
`integrations:write`, exits 1 on failure), `deliveries [id]`, `retry|cancel|send-now <id>`,
|
|
23
|
+
and `events` for what arrived inbound.
|
|
24
|
+
- `octwin journeys [id] [--funnel|--overview|--goals|--trends|--cost|--definition] [--stage <id>]`
|
|
25
|
+
— the declared journeys, measured. Same flag grammar as `octwin analytics` on purpose: a journey
|
|
26
|
+
funnel and an entity funnel are the same question about different subjects. `--definition` is
|
|
27
|
+
the one view that works with no traffic.
|
|
28
|
+
- `octwin performance [--detail]` — the project's business indicators, each with its delta against
|
|
29
|
+
the previous window and the `why` naming the declaration it came from. Needs `records:read`, not
|
|
30
|
+
a `performance:*` scope (there is none), so a read-only token already reaches it.
|
|
31
|
+
- `octwin usage` — model calls, tokens and cost, by model / kind / agent / channel; project when
|
|
32
|
+
one is pinned, workspace otherwise. Needs no particular scope. **Model spend only** —
|
|
33
|
+
WhatsApp/Meta message billing is operator-only and outside the token scope registry, which the
|
|
34
|
+
output says rather than leaving as an absence.
|
|
35
|
+
- **`octwin automation run|pause|resume|send` accept the declaration KEY.** The routes take a UUID
|
|
36
|
+
and answer a bare *"Malformed identifier in the URL"* 400 for anything else — but the key
|
|
37
|
+
(`cart_recovery_nudge`) is what the list prints and what the author wrote in their own YAML. The
|
|
38
|
+
key is now resolved against the list route, and an unknown one fails naming the keys that exist.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- **A body-less write sent `content-type: application/json` and no body, so Fastify answered a bare
|
|
42
|
+
`400 Bad Request`.** `apiSend` set the header unconditionally; every caller until now passed an
|
|
43
|
+
object, so the branch was dead and the bug latent. The first body-less POST (`automation run`) hit
|
|
44
|
+
it immediately. The header is now omitted when there is no body — rather than each caller learning
|
|
45
|
+
to pass `{}`, which is the per-site divergence that helper exists to prevent.
|
|
46
|
+
- **Four URLs were exempt from the route guard.** `cli-routes.test.ts` reads a template literal in
|
|
47
|
+
the first argument position, so `apiGet(base, t)` — a bare identifier — was never checked. That
|
|
48
|
+
covered the `scheduling` engine-state and `agents` roster calls, and would have covered the new
|
|
49
|
+
`journeys`, `performance` and `usage` ones. All now spelled as literals: the guard checks **62**
|
|
50
|
+
URLs, up from 45.
|
|
51
|
+
|
|
52
|
+
## [0.7.3] - 2026-08-26
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
- **A marketplace listing request is now OPT-IN: `octwin deploy --request-listing`.** A plain
|
|
56
|
+
`octwin deploy` says nothing about the public marketplace — it neither asks for a listing nor
|
|
57
|
+
gives one up. `--withdraw-listing` retracts, including an approved listing.
|
|
58
|
+
**Why:** the request was read from the manifest's `listing.public` on every deploy, and deploying
|
|
59
|
+
is how you *test*. 17 of the 23 published packs carry that key, so an edit-deploy-chat loop filed
|
|
60
|
+
a review request every time round. Worse, the *absence* of the key meant **retract** — so an
|
|
61
|
+
ordinary deploy of a pack whose manifest you had not yet annotated could wipe a listing you
|
|
62
|
+
already had. `--request-listing` still requires `listing.public: true` in the manifest (the
|
|
63
|
+
manifest states that the pack is a product; the flag is you choosing to ask), and the flag
|
|
64
|
+
without the key is a clean error rather than a silent no-op.
|
|
65
|
+
- **The listing verdict distinguishes "you submitted this" from "your approval expired".** They are
|
|
66
|
+
both `pending` and they mean opposite things to an author. A deploy that changes the content of an
|
|
67
|
+
approved pack now says so in those words — an approval covers only the content it was made
|
|
68
|
+
against, so it cannot survive an edit.
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
- **A one-line nudge when your manifest asks and your deploy did not.** A pack carrying
|
|
72
|
+
`listing.public: true` that has never been submitted now prints the flag to use, so an opt-in
|
|
73
|
+
default cannot turn into waiting for a review nobody requested.
|
|
74
|
+
|
|
75
|
+
### Fixed
|
|
76
|
+
- **The "newer CLI" and "KB drifted" notices now print when a command FAILS.** All three nudges
|
|
77
|
+
(CLI upgrade · KB drift · unread memos) were awaited at the very end of `main()`, which silently
|
|
78
|
+
meant *only on success* — `die()` is a hard exit, so a failed deploy, an auth error or a bad
|
|
79
|
+
manifest printed none of them. That is backwards: a stale capability reference is a leading cause
|
|
80
|
+
of the failure an author is staring at, so the run that most needed the nudge was the only one
|
|
81
|
+
that never got it. They are now computed before the command and printed however it ends.
|
|
82
|
+
- **The CLI-upgrade notice is no longer hidden from piped output.** It began with
|
|
83
|
+
`if (!process.stdout.isTTY) return`, so every agent-driven and CI run — the readers that cannot
|
|
84
|
+
notice an outdated CLI on their own — was the one audience never told. Its two siblings had
|
|
85
|
+
already dropped that gate for exactly this reason; now all three agree. Still skipped under
|
|
86
|
+
`npx`, where there is nothing to upgrade.
|
|
87
|
+
- **`octwin login` now reports KB drift too.** It is networked and usually the first command of a
|
|
88
|
+
session, i.e. the best possible moment to say the reference moved, and it was excluded.
|
|
89
|
+
- **A memo poll can no longer fail the command it was annotating.** It went through `apiGet` →
|
|
90
|
+
`fetchOrDie`, whose job is to `die` on a network failure — so an unreachable platform turned an
|
|
91
|
+
observer into a command failure. It now uses a plain, timed, fail-silent fetch.
|
|
92
|
+
- **A failing command reports its real exit code again on Windows.** Moving the polls before the
|
|
93
|
+
command made `process.exit()` abort with `Assertion failed: !(handle->flags & UV_HANDLE_CLOSING)`
|
|
94
|
+
and return **127** instead of 1 — so CI saw neither success nor the documented failure code. The
|
|
95
|
+
CLI now unwinds through a `CliExit` and lets the event loop drain, which is the only teardown
|
|
96
|
+
that is clean once the polls have opened sockets. `--check`'s exit 2 and the streaming commands
|
|
97
|
+
were re-verified.
|
|
98
|
+
|
|
8
99
|
## [0.7.2] - 2026-08-20
|
|
9
100
|
|
|
10
101
|
### Fixed
|
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ octwin status # "✓ live and current" once it's warm
|
|
|
67
67
|
| `octwin validate` | Check the pack locally (structure + pure-YAML rules). `--remote` runs **the same validation the platform runs to load your pack** — every declaration file (`xrm.yaml`, `scheduling.yaml`, `worklist.yaml`, `roles.yaml`, `automation.yaml`, `integrations.yaml`, `surveys.yaml`, `taps.yaml`, `commands.yaml`, `journeys/`, `messages.<lang>.yaml`), the cross-file checks between them, and the **flow lint** — conventions the schema can't express, like an `assign:` whose value is a quoted literal or a `$t()` key with no namespace. These need template expansion and the platform's own schemas, which only the server has, so a local ✓ does not cover them. A `--remote` ✓ and a successful deploy are now the same answer by construction, not by convention. |
|
|
68
68
|
| `octwin login` | Save a deploy token for a platform URL **and make that URL the default target** (both stored in `~/.octwin/credentials.json`). `--url`, `--token`. |
|
|
69
69
|
| `octwin whoami` | Verify the saved/passed token is valid for a tenant. `--url`, `--tenant`. |
|
|
70
|
-
| `octwin deploy` | Upload + install the pack onto your tenant's project. `--seed` also runs the pack's demo seed.
|
|
70
|
+
| `octwin deploy` | Upload + install the pack onto your tenant's project. `--seed` also runs the pack's demo seed. Says **nothing** about the public marketplace unless asked: `--request-listing` submits the pack for operator review (needs `listing.public: true` in the manifest too), `--withdraw-listing` retracts. Reports the **listing verdict** whenever one exists. |
|
|
71
71
|
| `octwin status` | Report what the platform has live for this pack — installed version, the **content sha** the instance loaded vs. the one the catalog holds (a redeploy of the *same* version changes it), its flows, and whether it is live on the public marketplace. |
|
|
72
72
|
| `octwin pull <packId>` | Write a **deployed** pack's source back to disk — the inverse of `deploy`, and how a pack pushed from one machine is recovered. Defaults to the version installed on the target project; `--version` overrides, `--dir` defaults to `./<packId>`, a non-empty dir needs `--force`. You may pull a pack your tenant **owns**. |
|
|
73
73
|
| `octwin chat "msg"` | Drive a turn through the dev web channel and print **every render with its tap ids**. `--as <handle>` picks the test user; `--tap "<tap-id>"` presses a rendered button/list row; `--json` dumps the raw envelopes. |
|
|
@@ -80,6 +80,11 @@ octwin status # "✓ live and current" once it's warm
|
|
|
80
80
|
| `octwin analytics` | Stage-by-stage conversion for **any** entity declared with a `pipeline:` (`--overview` / `--milestones` / `--trends` / `--cost`; `--stage <id>` lists the records currently at a stage). Needs `records:read`. |
|
|
81
81
|
| `octwin catalog` | Commerce products with price / availability / stock, plus the WhatsApp catalog binding. `--readiness` runs the Meta Graph checklist. Needs `catalog:read` + the `catalog` plan feature. |
|
|
82
82
|
| `octwin scheduling` | The scheduling engine's state, or `--slots <resourceRecordId>` for the slots one bookable resource actually computes — how you verify the availability rules `deploy --seed` created. Needs `scheduling:read`. |
|
|
83
|
+
| `octwin automation` | The jobs your pack's automation declaration produced — status, interval and each one's **last result** (matched / acted / errors) — under a health line counted in SQL. `campaigns` lists the campaigns. Jobs are derived from declarations, so there is no `create`. Needs `automation:read`. |
|
|
84
|
+
| `octwin integrations` | What the pack **declares** beside what is actually **configured**, and it flags the gap: a connection declared and never configured is the commonest reason an integration silently never fires, and neither list alone shows it. `preflight <key>` diagnoses without calling out (`integrations:read`); `deliveries [id]` is the outbound log; `events` is what arrived inbound. Needs `integrations:read`. |
|
|
85
|
+
| `octwin journeys` | The customer journeys your pack declares, measured: `--funnel` (default) · `--overview` · `--goals` · `--trends` · `--cost` · `--definition` (what was declared, works with no traffic), plus `--stage <id>` for the runs sitting at a stage now. Same flag grammar as `octwin analytics` — a journey funnel and an entity funnel are the same question about different subjects. Needs `journeys:read`. |
|
|
86
|
+
| `octwin performance` | The project's business indicators — value produced, conversion, duration — each with its delta against the previous window and a `why` naming the declaration it came from. `--detail` adds the breakdown. Needs `records:read`, **not** a `performance:*` scope (there is none). |
|
|
87
|
+
| `octwin usage` | Model calls, tokens and cost, by model / kind / agent / channel. Project when one is pinned, workspace otherwise. Needs no particular scope. **Model spend only** — WhatsApp/Meta message billing is operator-only and no API token can read it. |
|
|
83
88
|
| `octwin media generate "<prompt>"` | AI-generate an image, store it as a public asset, and print its `MEDIA-` handle + serve URL. `--out` downloads the bytes (WhatsApp renders only `.png`/`.jpg`); `--json`. Pairs with `octwin chat --media` to drive media-collect flows. Needs `media:generate`. |
|
|
84
89
|
| `octwin platform-kb pull` | Pull the platform's capability reference into `.octwin/platform-kb/` for the **`octwin-pack`** Claude Code authoring plugin: guides as markdown, plus **one JSON file per capability** (`primitives/record_list.json`, `render-intents/carousel.json`, `declarations/xrm.json`, …) and **three maps** — `INDEX.md` (the corpus, by family and size), `SYMBOLS.md` (every name → its exact file; grep this), `OUTLINE.md` (every heading with its line number). **No token needed** — the reference is served anonymously. `--if-stale` skips the download when your copy is current (cheap enough for every session); `--check` writes nothing and exits 0 current / 2 stale / 1 could-not-tell. |
|
|
85
90
|
| `octwin test` | Alias for `octwin validate --remote` — the platform's full manifest + flow-DSL check. |
|
|
@@ -100,6 +105,8 @@ lists the verbs and their exact flags.
|
|
|
100
105
|
| `octwin catalog` | `availability <sku> --to "in stock"` · `stock <sku> [--set-on-hand n]` |
|
|
101
106
|
| `octwin scheduling` | `rules --resource <id>` · `rule add\|rm` · `exception add\|rm` |
|
|
102
107
|
| `octwin agents` | `set <ref> [--model m] [--enable-tool t] [--disable-tool t]` |
|
|
108
|
+
| `octwin automation` | `run <jobId>` · `pause\|resume <jobId>` · `send <campaignId>` — the id may be the declaration **key** the list prints; the CLI resolves it to the uuid the route wants |
|
|
109
|
+
| `octwin integrations` | `test <key>` (a live call to the connection's `health:` operation) · `retry\|cancel\|send-now <deliveryId>` |
|
|
103
110
|
|
|
104
111
|
`--set k=v` coerces JSON scalars (`--set rating=4.5` sends a number); `--fields-json` takes anything
|
|
105
112
|
nested. Destructive verbs want `--force` rather than a prompt — the CLI is non-interactive by
|
|
@@ -134,6 +141,11 @@ octwin orders # then: octwin orders <reference_i
|
|
|
134
141
|
octwin analytics # then: octwin analytics <entity> [--stage <id>]
|
|
135
142
|
octwin catalog # products + stock + the WhatsApp binding
|
|
136
143
|
octwin scheduling --slots <resourceRecordId> # the slots your availability rules compute
|
|
144
|
+
octwin automation # did your declared jobs run, and what did they touch
|
|
145
|
+
octwin integrations # declared vs configured — the silent-never-fires check
|
|
146
|
+
octwin journeys # then: octwin journeys <id> [--overview|--goals|--cost]
|
|
147
|
+
octwin performance # value, conversion and duration, each with its `why`
|
|
148
|
+
octwin usage # what your testing actually cost in model spend
|
|
137
149
|
```
|
|
138
150
|
|
|
139
151
|
Three things worth knowing when you read the output:
|