@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.
Files changed (44) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/LICENSE +21 -0
  3. package/README.md +92 -0
  4. package/bin/cwe-plugin.mjs +14 -0
  5. package/dist/cli.js +10400 -0
  6. package/package.json +62 -0
  7. package/templates/blank/README.md +60 -0
  8. package/templates/blank/_gitignore +3 -0
  9. package/templates/blank/cwe-plugin.json +9 -0
  10. package/templates/blank/package.json +31 -0
  11. package/templates/blank/settings.dev.json +8 -0
  12. package/templates/blank/src/handlers/hooks.ts +29 -0
  13. package/templates/blank/src/handlers/jobs.ts +9 -0
  14. package/templates/blank/src/handlers/routes.ts +44 -0
  15. package/templates/blank/src/index.ts +68 -0
  16. package/templates/blank/src/settings.ts +23 -0
  17. package/templates/blank/test/hooks.test.ts +43 -0
  18. package/templates/blank/tsconfig.json +14 -0
  19. package/templates/cashback/README.md +61 -0
  20. package/templates/cashback/_gitignore +3 -0
  21. package/templates/cashback/cwe-plugin.json +9 -0
  22. package/templates/cashback/package.json +31 -0
  23. package/templates/cashback/settings.dev.json +9 -0
  24. package/templates/cashback/src/handlers/hooks.ts +19 -0
  25. package/templates/cashback/src/handlers/jobs.ts +23 -0
  26. package/templates/cashback/src/handlers/routes.ts +188 -0
  27. package/templates/cashback/src/index.ts +128 -0
  28. package/templates/cashback/src/settings.ts +29 -0
  29. package/templates/cashback/test/hooks.test.ts +83 -0
  30. package/templates/cashback/tsconfig.json +14 -0
  31. package/templates/provider-skeleton/README.md +63 -0
  32. package/templates/provider-skeleton/_gitignore +3 -0
  33. package/templates/provider-skeleton/cwe-plugin.json +9 -0
  34. package/templates/provider-skeleton/package.json +31 -0
  35. package/templates/provider-skeleton/settings.dev.json +10 -0
  36. package/templates/provider-skeleton/src/adapter.ts +164 -0
  37. package/templates/provider-skeleton/src/fake-backend.ts +56 -0
  38. package/templates/provider-skeleton/src/handlers/hooks.ts +30 -0
  39. package/templates/provider-skeleton/src/handlers/jobs.ts +16 -0
  40. package/templates/provider-skeleton/src/handlers/routes.ts +128 -0
  41. package/templates/provider-skeleton/src/index.ts +83 -0
  42. package/templates/provider-skeleton/src/settings.ts +37 -0
  43. package/templates/provider-skeleton/test/hooks.test.ts +83 -0
  44. 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);