@hachej/boring-ui-plugin-cli 0.1.40 → 0.1.42
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/README.md +79 -0
- package/dist/bin.js +2 -2
- package/dist/{chunk-PYNOFBR6.js → chunk-4ZXW5O2M.js} +8 -2
- package/dist/{chunk-3WN35EV3.js → chunk-KTILPA2U.js} +9 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -3
- package/dist/plugin-sources.d.ts +20 -1
- package/dist/plugin-sources.js +5 -3
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# @hachej/boring-ui-plugin-cli
|
|
2
|
+
|
|
3
|
+
Plugin authoring CLI for the boring-ui workspace runtime. The binary is
|
|
4
|
+
`boring-ui-plugin`; it is also bundled into `@hachej/boring-ui-cli` and reached
|
|
5
|
+
as `boring-ui plugin <subcommand>`.
|
|
6
|
+
|
|
7
|
+
It scaffolds, verifies, tests, and manages boring-ui plugins, and exports the
|
|
8
|
+
plugin-source resolution helpers the CLI uses to discover plugins.
|
|
9
|
+
|
|
10
|
+
## Two kinds of plugin
|
|
11
|
+
|
|
12
|
+
| | `create` | `scaffold` |
|
|
13
|
+
|--|----------|------------|
|
|
14
|
+
| Output | npm-package plugin under `plugins/<name>/` (copied from `templates/plugin/`) | workspace runtime plugin under `<workspace>/.pi/extensions/<name>/` |
|
|
15
|
+
| Build | has a build step (`tsup`), `workspace:*` deps | no build step, hot-reloadable via `/reload` |
|
|
16
|
+
| Use for | app/internal publishable plugins | per-workspace plugins authored from inside the running UI |
|
|
17
|
+
|
|
18
|
+
## Commands
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
boring-ui-plugin status [--json]
|
|
22
|
+
boring-ui-plugin create <name> [--path <dir>]
|
|
23
|
+
boring-ui-plugin scaffold <name> [workspace]
|
|
24
|
+
boring-ui-plugin verify [name] [workspace]
|
|
25
|
+
boring-ui-plugin test <name> [--url <url>] [--workspace <id>] [--panel-id <id>] [--timeout-ms <ms>] [--json]
|
|
26
|
+
boring-ui-plugin install [-l|--local|--global] [--workspace <dir>] <source>
|
|
27
|
+
boring-ui-plugin list [--local|--global|--all] [--workspace <dir>] [--json]
|
|
28
|
+
boring-ui-plugin remove [-l|--local|--global] [--workspace <dir>] <id-or-source>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- **status** — reports whether workspace-local plugin roots are enabled (driven
|
|
32
|
+
by `BORING_AGENT_WORKSPACE_LOCAL_PLUGIN_ROOTS`) and the resolved
|
|
33
|
+
`.pi/extensions` dir.
|
|
34
|
+
- **verify** — validates plugin manifests on disk *without* a running server
|
|
35
|
+
(manifest validity + `boring.front` / `boring.server` / `pi.extensions` file
|
|
36
|
+
existence). It does not execute plugin code, so syntax errors only surface on
|
|
37
|
+
a real `/reload`. Prints hints for known errors and exits non-zero on failure.
|
|
38
|
+
- **test** — drives a self-test against a running workspace server (default URL
|
|
39
|
+
inferred, override with `--url`) to catch panel render / front-import
|
|
40
|
+
failures that don't appear in the `/reload` banner.
|
|
41
|
+
- **install / list / remove** — manage plugin *sources* in two scopes: `local`
|
|
42
|
+
(`<workspace>/.pi`, default) and `global` (`~/.pi/agent`). Sources can be a
|
|
43
|
+
local path, a git URL, or an npm spec. Dependencies are **not** installed for
|
|
44
|
+
you — run your package manager in the plugin folder, then `/reload` in the UI.
|
|
45
|
+
|
|
46
|
+
Run `boring-ui-plugin` with no command for usage.
|
|
47
|
+
|
|
48
|
+
## Plugin manifest
|
|
49
|
+
|
|
50
|
+
Plugins are declared in `package.json` via two fields (`src/manifest.ts`):
|
|
51
|
+
|
|
52
|
+
- `boring` — workspace/UI discovery: `front` (browser entry default-exporting a
|
|
53
|
+
`BoringFrontFactory`), `server` (backend entry), labels.
|
|
54
|
+
- `pi` — agent/Pi runtime contributions: `extensions`, `skills`, prompt
|
|
55
|
+
fragments, Pi packages, and slash commands.
|
|
56
|
+
|
|
57
|
+
## Programmatic API
|
|
58
|
+
|
|
59
|
+
The package exports its building blocks for embedding hosts (e.g. the CLI):
|
|
60
|
+
`runBoringUiPluginCli`, `createPlugin`, `scaffoldPlugin`, `verifyPlugin`,
|
|
61
|
+
`runPluginSelfTest`, `installPluginSource` / `listPluginSources` /
|
|
62
|
+
`removePluginSource`, and source-scope helpers
|
|
63
|
+
(`resolvePluginSourceScopePaths`, `readPluginSourceRecords`) via the
|
|
64
|
+
`./plugin-sources` subpath. See `src/index.ts` for the full surface.
|
|
65
|
+
|
|
66
|
+
## Templates
|
|
67
|
+
|
|
68
|
+
`templates/plugin/` is the canonical npm-package plugin shape copied by
|
|
69
|
+
`create`; its [README](./templates/plugin/README.md) documents the front /
|
|
70
|
+
server / shared layout and invariants. `templates/*-canonical.*` are the
|
|
71
|
+
single-file canonical sources used by `scaffold`.
|
|
72
|
+
|
|
73
|
+
## Docs
|
|
74
|
+
|
|
75
|
+
- [`docs/README.md`](./docs/README.md) — architecture and internals.
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
MIT
|
package/dist/bin.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
listPluginSources,
|
|
6
6
|
removePluginSource,
|
|
7
7
|
validateBoringPluginManifest
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-KTILPA2U.js";
|
|
9
9
|
|
|
10
10
|
// src/server/index.ts
|
|
11
11
|
import { join as join4, resolve as resolve4 } from "path";
|
|
@@ -679,6 +679,11 @@ function collectRuntimeDiagnostics(pluginId, body) {
|
|
|
679
679
|
if (!plugin) return { events };
|
|
680
680
|
if (typeof plugin.serverLoadedRevision === "number") revision = plugin.serverLoadedRevision;
|
|
681
681
|
if (typeof plugin.serverError === "string") events.push(event("PLUGIN_SERVER_ERROR", plugin.serverError));
|
|
682
|
+
if (isObject2(plugin.frontError)) {
|
|
683
|
+
if (typeof plugin.frontError.revision === "number") revision = plugin.frontError.revision;
|
|
684
|
+
const message = typeof plugin.frontError.message === "string" ? plugin.frontError.message : "front module failed to load";
|
|
685
|
+
events.push(event("PLUGIN_FRONT_ERROR", message));
|
|
686
|
+
}
|
|
682
687
|
if (isObject2(plugin.host)) {
|
|
683
688
|
if (typeof plugin.host.revision === "number") revision = plugin.host.revision;
|
|
684
689
|
const code = typeof plugin.host.lastErrorCode === "string" ? plugin.host.lastErrorCode : "PLUGIN_RUNTIME_HOST_ERROR";
|
|
@@ -896,7 +901,8 @@ function handleScaffold(positionals) {
|
|
|
896
901
|
console.log(" 3. bash `boring-ui-plugin verify` \u2014 confirms manifests + files are valid");
|
|
897
902
|
console.log(" 4. if the UI is open, bash `boring-ui-plugin test <name>` \u2014 catches panel render failures");
|
|
898
903
|
console.log(" 5. ask the user: /reload");
|
|
899
|
-
console.log(" 6. after /reload, call the plugin_diagnostics tool
|
|
904
|
+
console.log(" 6. after /reload, ALWAYS call the plugin_diagnostics tool AND re-run `boring-ui-plugin test <name>` \u2014 front import failures only show up there (source plugin-front / PLUGIN_FRONT_ERROR), not in the /reload banner");
|
|
905
|
+
console.log(" 7. iterate (fix -> /reload -> plugin_diagnostics + test) until both are clean before reporting success");
|
|
900
906
|
}
|
|
901
907
|
function handleVerify(positionals) {
|
|
902
908
|
const result = verifyPlugin(parseVerifyArgs(positionals));
|
|
@@ -503,6 +503,14 @@ function readPluginSourceRecordsForRoots(opts) {
|
|
|
503
503
|
const global = resolvePluginSourceScopePaths("global", opts);
|
|
504
504
|
return [...readPluginSourceRecords(global), ...readPluginSourceRecords(local)];
|
|
505
505
|
}
|
|
506
|
+
function resolveRegisteredPluginSourceDirs(paths) {
|
|
507
|
+
return packageEntries(readPiSettings(paths.settingsPath)).flatMap((entry) => {
|
|
508
|
+
const source = packageEntrySource(entry);
|
|
509
|
+
if (!source) return [];
|
|
510
|
+
const rootDir = resolvePackageSourcePath(paths.baseDir, source);
|
|
511
|
+
return rootDir ? [{ source, rootDir }] : [];
|
|
512
|
+
});
|
|
513
|
+
}
|
|
506
514
|
function upsertPackageSource(paths, record) {
|
|
507
515
|
const settings = readPiSettings(paths.settingsPath);
|
|
508
516
|
const entries = packageEntries(settings);
|
|
@@ -621,6 +629,7 @@ export {
|
|
|
621
629
|
resolvePluginSourceScopePaths,
|
|
622
630
|
readPluginSourceRecords,
|
|
623
631
|
readPluginSourceRecordsForRoots,
|
|
632
|
+
resolveRegisteredPluginSourceDirs,
|
|
624
633
|
installPluginSource,
|
|
625
634
|
listPluginSources,
|
|
626
635
|
removePluginSource,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { InstallPluginSourceOptions, ListPluginSourcesOptions, PluginInstallResult, PluginInstallScope, PluginListResult, PluginRemoveResult, PluginSourceKind, PluginSourceRecord, PluginSourceScopePaths, RemovePluginSourceOptions, formatPluginSourceList, installPluginSource, listPluginSources, readPluginSourceRecords, readPluginSourceRecordsForRoots, removePluginSource, resolvePluginSourceScopePaths } from './plugin-sources.js';
|
|
1
|
+
export { InstallPluginSourceOptions, ListPluginSourcesOptions, PluginInstallResult, PluginInstallScope, PluginListResult, PluginRemoveResult, PluginSourceKind, PluginSourceRecord, PluginSourceScopePaths, RegisteredPluginSourceDir, RemovePluginSourceOptions, formatPluginSourceList, installPluginSource, listPluginSources, readPluginSourceRecords, readPluginSourceRecordsForRoots, removePluginSource, resolvePluginSourceScopePaths, resolveRegisteredPluginSourceDirs } from './plugin-sources.js';
|
|
2
2
|
|
|
3
3
|
interface CreatePluginOptions {
|
|
4
4
|
name: string;
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
runPluginSelfTest,
|
|
9
9
|
scaffoldPlugin,
|
|
10
10
|
verifyPlugin
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-4ZXW5O2M.js";
|
|
12
12
|
import {
|
|
13
13
|
formatPluginSourceList,
|
|
14
14
|
installPluginSource,
|
|
@@ -16,8 +16,9 @@ import {
|
|
|
16
16
|
readPluginSourceRecords,
|
|
17
17
|
readPluginSourceRecordsForRoots,
|
|
18
18
|
removePluginSource,
|
|
19
|
-
resolvePluginSourceScopePaths
|
|
20
|
-
|
|
19
|
+
resolvePluginSourceScopePaths,
|
|
20
|
+
resolveRegisteredPluginSourceDirs
|
|
21
|
+
} from "./chunk-KTILPA2U.js";
|
|
21
22
|
export {
|
|
22
23
|
createPlugin,
|
|
23
24
|
findHintForError,
|
|
@@ -31,6 +32,7 @@ export {
|
|
|
31
32
|
readPluginSourceRecordsForRoots,
|
|
32
33
|
removePluginSource,
|
|
33
34
|
resolvePluginSourceScopePaths,
|
|
35
|
+
resolveRegisteredPluginSourceDirs,
|
|
34
36
|
runBoringUiPluginCli,
|
|
35
37
|
runPluginSelfTest,
|
|
36
38
|
scaffoldPlugin,
|
package/dist/plugin-sources.d.ts
CHANGED
|
@@ -63,9 +63,28 @@ declare function readPluginSourceRecordsForRoots(opts: {
|
|
|
63
63
|
workspaceRoot: string;
|
|
64
64
|
globalRoot?: string;
|
|
65
65
|
}): PluginSourceRecord[];
|
|
66
|
+
interface RegisteredPluginSourceDir {
|
|
67
|
+
/** Raw package source string as written in settings.json. */
|
|
68
|
+
source: string;
|
|
69
|
+
/** Absolute directory the source resolves to (may not exist). */
|
|
70
|
+
rootDir: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve every local-path `packages` entry in the scope's settings.json
|
|
74
|
+
* to its directory WITHOUT validating the plugin root. Remote specs
|
|
75
|
+
* (npm:, git:, URLs) are skipped — their installed copies live under the
|
|
76
|
+
* scope's npm/git dirs, which hosts already scan directly.
|
|
77
|
+
*
|
|
78
|
+
* Unlike `readPluginSourceRecords`, broken entries are returned rather
|
|
79
|
+
* than dropped: hosts pass these dirs to the Boring plugin scanner with
|
|
80
|
+
* `registered: true`, so a deleted dir or stripped package.json surfaces
|
|
81
|
+
* as a preflight error in the plugin UI instead of the plugin silently
|
|
82
|
+
* vanishing.
|
|
83
|
+
*/
|
|
84
|
+
declare function resolveRegisteredPluginSourceDirs(paths: PluginSourceScopePaths): RegisteredPluginSourceDir[];
|
|
66
85
|
declare function installPluginSource(opts: InstallPluginSourceOptions): PluginInstallResult;
|
|
67
86
|
declare function listPluginSources(opts?: ListPluginSourcesOptions): PluginListResult;
|
|
68
87
|
declare function removePluginSource(opts: RemovePluginSourceOptions): PluginRemoveResult;
|
|
69
88
|
declare function formatPluginSourceList(result: PluginListResult): string;
|
|
70
89
|
|
|
71
|
-
export { type InstallPluginSourceOptions, type ListPluginSourcesOptions, type PluginInstallResult, type PluginInstallScope, type PluginListResult, type PluginRemoveResult, type PluginSourceKind, type PluginSourceRecord, type PluginSourceScopePaths, type RemovePluginSourceOptions, formatPluginSourceList, installPluginSource, listPluginSources, readPluginSourceRecords, readPluginSourceRecordsForRoots, removePluginSource, resolvePluginSourceScopePaths };
|
|
90
|
+
export { type InstallPluginSourceOptions, type ListPluginSourcesOptions, type PluginInstallResult, type PluginInstallScope, type PluginListResult, type PluginRemoveResult, type PluginSourceKind, type PluginSourceRecord, type PluginSourceScopePaths, type RegisteredPluginSourceDir, type RemovePluginSourceOptions, formatPluginSourceList, installPluginSource, listPluginSources, readPluginSourceRecords, readPluginSourceRecordsForRoots, removePluginSource, resolvePluginSourceScopePaths, resolveRegisteredPluginSourceDirs };
|
package/dist/plugin-sources.js
CHANGED
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
readPluginSourceRecords,
|
|
6
6
|
readPluginSourceRecordsForRoots,
|
|
7
7
|
removePluginSource,
|
|
8
|
-
resolvePluginSourceScopePaths
|
|
9
|
-
|
|
8
|
+
resolvePluginSourceScopePaths,
|
|
9
|
+
resolveRegisteredPluginSourceDirs
|
|
10
|
+
} from "./chunk-KTILPA2U.js";
|
|
10
11
|
export {
|
|
11
12
|
formatPluginSourceList,
|
|
12
13
|
installPluginSource,
|
|
@@ -14,5 +15,6 @@ export {
|
|
|
14
15
|
readPluginSourceRecords,
|
|
15
16
|
readPluginSourceRecordsForRoots,
|
|
16
17
|
removePluginSource,
|
|
17
|
-
resolvePluginSourceScopePaths
|
|
18
|
+
resolvePluginSourceScopePaths,
|
|
19
|
+
resolveRegisteredPluginSourceDirs
|
|
18
20
|
};
|