@clovnet/plugin-cli 0.2.2
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 +75 -0
- package/LICENSE +21 -0
- package/README.md +92 -0
- package/bin/cwe-plugin.mjs +14 -0
- package/dist/cli.js +10400 -0
- package/package.json +62 -0
- package/templates/blank/README.md +60 -0
- package/templates/blank/_gitignore +3 -0
- package/templates/blank/cwe-plugin.json +9 -0
- package/templates/blank/package.json +31 -0
- package/templates/blank/settings.dev.json +8 -0
- package/templates/blank/src/handlers/hooks.ts +29 -0
- package/templates/blank/src/handlers/jobs.ts +9 -0
- package/templates/blank/src/handlers/routes.ts +44 -0
- package/templates/blank/src/index.ts +68 -0
- package/templates/blank/src/settings.ts +23 -0
- package/templates/blank/test/hooks.test.ts +43 -0
- package/templates/blank/tsconfig.json +14 -0
- package/templates/cashback/README.md +61 -0
- package/templates/cashback/_gitignore +3 -0
- package/templates/cashback/cwe-plugin.json +9 -0
- package/templates/cashback/package.json +31 -0
- package/templates/cashback/settings.dev.json +9 -0
- package/templates/cashback/src/handlers/hooks.ts +19 -0
- package/templates/cashback/src/handlers/jobs.ts +23 -0
- package/templates/cashback/src/handlers/routes.ts +188 -0
- package/templates/cashback/src/index.ts +128 -0
- package/templates/cashback/src/settings.ts +29 -0
- package/templates/cashback/test/hooks.test.ts +83 -0
- package/templates/cashback/tsconfig.json +14 -0
- package/templates/provider-skeleton/README.md +63 -0
- package/templates/provider-skeleton/_gitignore +3 -0
- package/templates/provider-skeleton/cwe-plugin.json +9 -0
- package/templates/provider-skeleton/package.json +31 -0
- package/templates/provider-skeleton/settings.dev.json +10 -0
- package/templates/provider-skeleton/src/adapter.ts +164 -0
- package/templates/provider-skeleton/src/fake-backend.ts +56 -0
- package/templates/provider-skeleton/src/handlers/hooks.ts +30 -0
- package/templates/provider-skeleton/src/handlers/jobs.ts +16 -0
- package/templates/provider-skeleton/src/handlers/routes.ts +128 -0
- package/templates/provider-skeleton/src/index.ts +83 -0
- package/templates/provider-skeleton/src/settings.ts +37 -0
- package/templates/provider-skeleton/test/hooks.test.ts +83 -0
- package/templates/provider-skeleton/tsconfig.json +14 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Changelog — @clovnet/plugin-cli
|
|
2
|
+
|
|
3
|
+
## 0.2.2 (2026-07)
|
|
4
|
+
|
|
5
|
+
- `--version` reports the real package version. `CLI_VERSION` was a hardcoded literal in
|
|
6
|
+
`src/program.ts` that nobody bumped, so 0.2.1 shipped to npm announcing itself as `0.2.0`. It is
|
|
7
|
+
now read from `package.json` (`../package.json` resolves to the package root from both the source
|
|
8
|
+
tree and the bundled `dist/cli.js`), and `test/cli.test.ts` asserts the built binary's `--version`
|
|
9
|
+
matches `package.json` so it cannot drift again.
|
|
10
|
+
|
|
11
|
+
## 0.2.1 (2026-07)
|
|
12
|
+
|
|
13
|
+
Hardening release — adversarial review (5 dimensions + verify pass) confirmed 11 findings, all
|
|
14
|
+
fixed with regression coverage. No CLI surface or config-schema changes; 0.2.0 projects work as-is.
|
|
15
|
+
|
|
16
|
+
**Security:**
|
|
17
|
+
|
|
18
|
+
- `env status` no longer sends the stored refresh token to a fingerprint-mismatched environment —
|
|
19
|
+
the environment pin is enforced *before* any authenticated call.
|
|
20
|
+
- `refresh` only discards credentials on a genuine auth failure (401 / known auth codes). 5xx and
|
|
21
|
+
429 now surface `RUNTIME_UNAVAILABLE` and keep the token, so a runtime blip no longer logs you out.
|
|
22
|
+
- A failed `secret-tool` keychain write is reported instead of silently falling through.
|
|
23
|
+
|
|
24
|
+
**Fixes:**
|
|
25
|
+
|
|
26
|
+
- SSE client tolerates a runtime restart: handles the `cursorReset` marker and a low-seq heuristic,
|
|
27
|
+
so log streaming no longer goes dark after an api restart.
|
|
28
|
+
- `publish` loads the freshly built bundle before running the remote doctor (was doctoring a stale
|
|
29
|
+
bundle).
|
|
30
|
+
- `lifecycle install --version` pins the requested version instead of resolving max semver.
|
|
31
|
+
- `lifecycle` load-first is unconditional for `install`/`enable`/`configure`/`upgrade` and the cycle
|
|
32
|
+
sweep — a no-op install against an already-installed plugin used to leave a fresh api without the
|
|
33
|
+
code, breaking a later `configure`.
|
|
34
|
+
- `dev` coalesces rebuilds that land while a build is already in flight.
|
|
35
|
+
|
|
36
|
+
## 0.2.0 (2026-07)
|
|
37
|
+
|
|
38
|
+
Complete rebuild in TypeScript per `PLUGIN_DEV_CLI_PROMPT.md` — the CLI is now the full plugin
|
|
39
|
+
developer product, not a sideload script.
|
|
40
|
+
|
|
41
|
+
**Breaking changes (migration from 0.1.x):**
|
|
42
|
+
|
|
43
|
+
- `cwe-plugin.json` schema changed: flat `{runtimeUrl, pluginKey, devToken?, bundle?}` →
|
|
44
|
+
`{plugin, entry, environments: {name: {runtimeUrl}}, defaultEnvironment}` (Zod-validated,
|
|
45
|
+
unknown keys rejected). A leftover `devToken` key is rejected with a migration hint —
|
|
46
|
+
**tokens no longer live in the project file** (they were committed plaintext); credentials
|
|
47
|
+
now live in the OS keychain (fallback `~/.config/cwe/credentials.json`, 0600).
|
|
48
|
+
- `login` switched from email/password (cookie scrape) to the RFC-8628-shaped device-code flow
|
|
49
|
+
against `/auth/staff/device*`; refresh tokens rotate automatically (single-flight, file-locked).
|
|
50
|
+
`CWE_STAFF_EMAIL`/`CWE_STAFF_PASSWORD` relogin is gone; CI uses `CWE_PLUGIN_TOKEN`
|
|
51
|
+
(`cwe-plugin token create --ttl 1h --scope publish`).
|
|
52
|
+
- `push` is gone — `dev` hot-loads via the new `POST /dev/plugins/:key/load`
|
|
53
|
+
(`bundleBase64` + checksum + manifestHash); builds use esbuild directly (single ESM bundle,
|
|
54
|
+
SDK + zod external, inline sourcemaps in dev, 10 MB cap) instead of spawning the project's tsup.
|
|
55
|
+
- Dev-loop commands enforce the environment class policy (descriptor handshake, fingerprint
|
|
56
|
+
pinning, exit 2 on violation, no `--force`).
|
|
57
|
+
|
|
58
|
+
**New:**
|
|
59
|
+
|
|
60
|
+
- `create` (three templates: blank, cashback, provider-skeleton) + `pnpm create cwe-plugin`.
|
|
61
|
+
- `env add/use/list/status`; `whoami`/`logout`/`token create`.
|
|
62
|
+
- `dev` interactive session: live log/trace streaming (SSE with cursor resume), lifecycle keys,
|
|
63
|
+
manifest-change reinstall prompts, `--auto-install`/`--auto-reinstall`.
|
|
64
|
+
- `logs` standalone tail with `--level/--surface/--grep/--json`.
|
|
65
|
+
- `lifecycle …` with full hook traces (capability calls, audit refs, outbox events),
|
|
66
|
+
`--debug` (10-minute hook watchdog for breakpoint sessions), `lifecycle cycle` conformance sweep.
|
|
67
|
+
- `settings schema/get/set/apply`, `sandbox reset`, `invoke`, `jobs list/run`, `tasks run`,
|
|
68
|
+
`doctor [--remote]`, `publish/promote/yank/versions`.
|
|
69
|
+
- `codegen client` carried over unchanged (still runs via the target project's own SDK copy).
|
|
70
|
+
|
|
71
|
+
## 0.1.2 (2026-07)
|
|
72
|
+
|
|
73
|
+
Legacy JS CLI: `login` (password), `build` (tsup), `codegen client`, `validate`, `push`, `dev`
|
|
74
|
+
(watch + sideload via `PUT /dev/plugins/:key/bundle`). The `PUT /bundle` endpoint remains
|
|
75
|
+
supported by current runtimes, so 0.1.x keeps working during migration.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Clovnet
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# @clovnet/plugin-cli
|
|
2
|
+
|
|
3
|
+
`cwe-plugin` — the CasinoWebEngine plugin developer CLI. One tool that carries you from
|
|
4
|
+
`create` → `login` → `env` → `dev` (hot reload + live logs) → lifecycle testing → `publish`.
|
|
5
|
+
|
|
6
|
+
## The golden path
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pnpm create cwe-plugin my-cashback # scaffold: manifest, handlers, tests, config
|
|
10
|
+
cd my-cashback && pnpm install
|
|
11
|
+
|
|
12
|
+
pnpm dev # = cwe-plugin dev
|
|
13
|
+
# → first contact with the scaffold's preset `local` environment: the handshake verifies
|
|
14
|
+
# class=local + devHarness=true and pins its fingerprint → green banner
|
|
15
|
+
# → doctor passes → sandbox tenant resolved → plugin installed+enabled (prompted)
|
|
16
|
+
# → esbuild watch starts, bundle hot-loaded, log stream attached
|
|
17
|
+
# → edit src/handlers/routes.ts, save → rebuilt + hot-reloaded in <2s, logs streaming live
|
|
18
|
+
|
|
19
|
+
# in the dev session (keyboard): i install · e enable · c configure · x disable · u uninstall
|
|
20
|
+
# r reload · d doctor · l clear · q quit
|
|
21
|
+
|
|
22
|
+
pnpm test # unit tests via @clovnet/plugin-sdk/testing
|
|
23
|
+
|
|
24
|
+
cwe-plugin lifecycle cycle # conformance sweep: install→enable→configure→
|
|
25
|
+
# disable→uninstall→reinstall, asserts idempotency
|
|
26
|
+
|
|
27
|
+
cwe-plugin login # only needed for shared dev clusters / publishing
|
|
28
|
+
cwe-plugin env add dev-eu https://dev-eu.example && cwe-plugin env use dev-eu
|
|
29
|
+
pnpm dev # same loop against the shared cluster
|
|
30
|
+
|
|
31
|
+
pnpm publish:dev # = cwe-plugin publish — always the dev channel
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Environments & safety
|
|
35
|
+
|
|
36
|
+
The CLI resolves every runtime's `GET /.well-known/cwe-environment` descriptor and enforces a
|
|
37
|
+
fail-closed policy: dev-loop commands (`dev`, `logs`, `lifecycle`, `settings`, `invoke`, `jobs`,
|
|
38
|
+
`tasks`, `sandbox`, `doctor --remote`) run ONLY against environments with the dev harness mounted
|
|
39
|
+
and `class` ∈ {local, development}. An environment that does not declare itself is treated as
|
|
40
|
+
production. **There is no `--force`.** Environment fingerprints are pinned on `env add`
|
|
41
|
+
(SSH known_hosts style) — if a URL later resolves to a different environment the CLI hard-stops.
|
|
42
|
+
|
|
43
|
+
Project config lives in `cwe-plugin.json` (committed — never holds secrets):
|
|
44
|
+
|
|
45
|
+
```jsonc
|
|
46
|
+
{
|
|
47
|
+
"$schema": "https://cwe.dev/schemas/cwe-plugin.json",
|
|
48
|
+
"plugin": "my-cashback", // must equal manifest.key
|
|
49
|
+
"entry": "src/index.ts",
|
|
50
|
+
"environments": {
|
|
51
|
+
"local": { "runtimeUrl": "http://localhost:3000" },
|
|
52
|
+
"dev-eu": { "runtimeUrl": "https://dev-eu.example" }
|
|
53
|
+
},
|
|
54
|
+
"defaultEnvironment": "local"
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Machine-local state (env override, pinned fingerprints, log cursor) lives in `.cwe/state.json`
|
|
59
|
+
(gitignored, safe to delete). Credentials live in the OS keychain (macOS Keychain / libsecret),
|
|
60
|
+
falling back to `~/.config/cwe/credentials.json` chmod 0600.
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
|
|
64
|
+
| Command | What it does |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `create [name]` | Scaffold a plugin (`--kind`, `--template blank\|cashback\|provider-skeleton`) |
|
|
67
|
+
| `env add/use/list/status` | Manage runtime environments (handshake, fingerprint pin, live status) |
|
|
68
|
+
| `login` / `whoami` / `logout` | Device-code staff login (per the environment's `auth.cli` mode) |
|
|
69
|
+
| `token create --ttl 1h --scope publish` | Mint a non-refreshable CI token (`CWE_PLUGIN_TOKEN`) |
|
|
70
|
+
| `dev` | The dev session: watch → bundle → hot load → live logs → interactive keys |
|
|
71
|
+
| `logs` | Standalone log/trace tail (`--level`, `--surface`, `--grep`, `--json`, `--since`) |
|
|
72
|
+
| `lifecycle install/enable/configure/disable/uninstall/upgrade [--debug]` | Run real lifecycle commands, print full hook traces |
|
|
73
|
+
| `lifecycle cycle` | CI-grade conformance sweep with idempotency assertions |
|
|
74
|
+
| `settings schema/get/set/apply` | Inspect + change sandbox settings (secrets write-only) |
|
|
75
|
+
| `sandbox reset [--yes]` | Wipe this plugin's state on the sandbox tenant |
|
|
76
|
+
| `invoke <METHOD> <path>` | Route console: execute a declared route, print response + capability trace |
|
|
77
|
+
| `jobs list/run` · `tasks run` | Job dry-runs and task runs with live progress |
|
|
78
|
+
| `doctor [--remote]` | Static manifest checks; `--remote` runs the full runtime doctor |
|
|
79
|
+
| `build` / `codegen client` | One-off bundle / deterministic `@cwe-plugins/<key>-client` codegen |
|
|
80
|
+
| `publish` / `promote` / `yank` / `versions` | Publish to the dev channel; manage released versions |
|
|
81
|
+
|
|
82
|
+
Every read command supports `--json`. `--env <name>` overrides the default environment per
|
|
83
|
+
invocation. Auth is auto-refreshing (single-flight, 30s server-side rotation grace); in CI set
|
|
84
|
+
`CWE_PLUGIN_TOKEN` — it is used verbatim, never refreshed, never stored.
|
|
85
|
+
|
|
86
|
+
## Requirements
|
|
87
|
+
|
|
88
|
+
- Node ≥ 20, a CWE runtime with the dev harness enabled (`DEV_HARNESS_ENABLED=true`,
|
|
89
|
+
`CWE_ENV_CLASS=local|development`, sandbox tenant seeded — see the Runtime Core repo's
|
|
90
|
+
`docker-compose.plugindev.yml` for the one-command local stack).
|
|
91
|
+
- The target plugin project must have `@clovnet/plugin-sdk` installed (the CLI loads the
|
|
92
|
+
project's own SDK copy for doctor/codegen, so CLI and SDK versions never skew).
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin launcher — all logic lives in the tsup-built dist/cli.js. In the
|
|
3
|
+
// workspace, run `pnpm --filter @clovnet/plugin-cli build` once first.
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const dist = new URL("../dist/cli.js", import.meta.url);
|
|
8
|
+
if (!existsSync(fileURLToPath(dist))) {
|
|
9
|
+
console.error(
|
|
10
|
+
"cwe-plugin: dist/cli.js not found — build the CLI first: pnpm --filter @clovnet/plugin-cli build",
|
|
11
|
+
);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
await import(dist.href);
|