@standardagents/code-plugin-sdk 1.0.0-alpha.0 → 1.0.0-alpha.10-rows.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/README.md CHANGED
@@ -11,8 +11,8 @@ Its `package.json` includes a static `standardPlugin` manifest.
11
11
  {
12
12
  "name": "example-status",
13
13
  "type": "module",
14
- "peerDependencies": { "@standardagents/code-plugin-sdk": "^1.0.0-alpha.0" },
15
- "devDependencies": { "@standardagents/code-plugin-sdk": "^1.0.0-alpha.0" },
14
+ "peerDependencies": { "@standardagents/code-plugin-sdk": "^1.0.0-alpha.10-rows.0" },
15
+ "devDependencies": { "@standardagents/code-plugin-sdk": "^1.0.0-alpha.10-rows.0" },
16
16
  "standardPlugin": {
17
17
  "apiVersion": 1,
18
18
  "id": "example-status",
@@ -44,6 +44,20 @@ package, such as `@standardagents/code-plugin-sdk/testing`, are refused when
44
44
  the plugin runs inside Standard Code. The `testing` export serves the
45
45
  plugin's own test suite.
46
46
 
47
+ The complete rendering contract is in [REFERENCE.md](./REFERENCE.md). It
48
+ covers rows, styled text, badges, cards, slots, panels, overlays, host-rendered
49
+ views, ANSI canvases, styled canvas hover text, input focus,
50
+ popover/column/pane presentations, remote read-only behavior, and the frontend
51
+ surfaces that are still planned.
52
+
53
+ Plugin source imports the default package entry. Plugin tests may import
54
+ `@standardagents/code-plugin-sdk/testing` for `createHarness`. Runner internals,
55
+ raw host request envelopes, and internal module paths are outside the public
56
+ package exports. First-party plugins use these same public entries and receive
57
+ the same manifest validation, capability checks, request bounds, and remote
58
+ ownership rules as third-party plugins. A plugin ID does not grant a host
59
+ operation or fetch exception.
60
+
47
61
  The runtime disposes publishers, subscriptions, schedules and pending requests.
48
62
  Plugins register additional cleanup through `ctx.onDispose` or an activation return value.
49
63
  Handlers receive an abort signal.
@@ -54,6 +68,89 @@ Plugins retain Node access to files, networking and subprocesses under the user'
54
68
  Worker threads provide JavaScript fault isolation.
55
69
  Memory exhaustion outside V8 limits and native crashes can affect the runner process.
56
70
 
71
+ ## Collections
72
+
73
+ A plugin installs from a Git repository or an npm package. One source holds
74
+ one plugin or a collection of plugins.
75
+
76
+ A collection lists its plugins in `standard-plugins.json` at the root of the
77
+ repository or package:
78
+
79
+ ```json
80
+ {
81
+ "schema": 1,
82
+ "plugins": [
83
+ { "id": "builds-monitor", "path": "builds-monitor" },
84
+ { "id": "pong", "path": "games/pong" }
85
+ ]
86
+ }
87
+ ```
88
+
89
+ `schema` is `1`. `plugins` holds 1 to 256 entries. Each `id` follows the
90
+ plugin id pattern of the manifest and equals the `standardPlugin.id` in that
91
+ entry's `package.json`. Each `path` is a relative POSIX path of at most 512
92
+ characters with no leading slash, no backslash, and no empty, `.`, or `..`
93
+ segment. Ids and paths are unique within one collection. An installer
94
+ selects one entry with `--plugin <id>`.
95
+
96
+ A root without `standard-plugins.json` is a single plugin when its
97
+ `package.json` carries a valid `standardPlugin` manifest. Discovery treats it
98
+ as one entry at path `""`.
99
+
100
+ `validateCollection(value)` checks a parsed collection file and returns a
101
+ frozen `PluginCollection`. `resolveCollection({ collection, packageJson })`
102
+ applies the single-plugin fallback. `COLLECTION_FILE` names the file.
103
+
104
+ ## Dependencies
105
+
106
+ A plugin with `dependencies` or `optionalDependencies` ships a lockfile
107
+ beside its `package.json`, so every machine installs the same dependency
108
+ tree. The installer refuses a plugin with dependencies and no lockfile.
109
+
110
+ For an npm package the lockfile is `npm-shrinkwrap.json`. npm never
111
+ publishes `package-lock.json`; `npm shrinkwrap` converts an existing
112
+ `package-lock.json` into `npm-shrinkwrap.json`, and npm includes that file
113
+ when it publishes the package. For a Git repository either
114
+ `package-lock.json` or `npm-shrinkwrap.json` satisfies the rule.
115
+
116
+ The SDK belongs under `peerDependencies`, with a `devDependencies` copy for
117
+ the plugin's own tests. Inside Standard Code the bundled runtime supplies it.
118
+
119
+ `lockfileRequirement({ packageJson, sourceKind })` returns whether the rule
120
+ applies and which lockfile names satisfy it for `"npm"` or `"git"`.
121
+ `checkPackageForPublish({ packageJson, files })` reports problems as
122
+ `{ code, message }` objects: a missing lockfile, the SDK under
123
+ `dependencies`, a missing peer declaration, a missing or invalid manifest, an
124
+ entry outside the package files, or an id that differs from the collection
125
+ entry. Both helpers are pure; they read no files.
126
+
127
+ In a collection, each plugin directory holds its own `package.json` and its
128
+ own lockfile.
129
+
130
+ ## Publishing a plugin
131
+
132
+ The package installs a `standard-plugin` command for authoring.
133
+
134
+ ```sh
135
+ npx standard-plugin check
136
+ npx standard-plugin pack
137
+ npm publish
138
+ ```
139
+
140
+ `check [dir] [--source npm|git]` reads `package.json`, the optional
141
+ `standard-plugins.json`, every collection entry's `package.json`, and the
142
+ lockfiles. It prints each problem as `<path>: <code>: <message>` and exits
143
+ with status 1 when it finds one. `--source git` applies the Git lockfile
144
+ rule; the default is `npm`.
145
+
146
+ `pack [dir]` runs `check`. When a plugin has dependencies and no
147
+ `npm-shrinkwrap.json`, it runs `npm shrinkwrap`, which converts
148
+ `package-lock.json`, and asks you to commit the new file. It then runs
149
+ `npm pack --dry-run` and prints the files that npm will publish.
150
+
151
+ The command is authoring tooling. The SDK entry never imports it, and a
152
+ plugin never depends on it at run time.
153
+
57
154
  ## Testing
58
155
 
59
156
  `@standardagents/code-plugin-sdk/testing` exports `createHarness`.
@@ -65,8 +162,9 @@ The harness starts no subprocesses.
65
162
 
66
163
  ## Supported interface
67
164
 
68
- The public interface is the package's default export, its `testing` export,
69
- and the declarations in `src/index.d.ts` and `src/testing.d.ts`.
165
+ The public interface is the package root export, its `testing` export,
166
+ the declarations in `src/index.d.ts` and `src/testing.d.ts`, and the
167
+ `standard-plugin` command's `check` and `pack` behavior.
70
168
 
71
169
  The harness records the frames that the SDK runtime exchanges with its host,
72
170
  and `harness.receive` accepts such a frame. That wire protocol between the
@@ -77,15 +175,92 @@ without notice. Plugin code and plugin tests should treat recorded frames as
77
175
  opaque values and drive the plugin through `PluginContext` and the harness
78
176
  methods.
79
177
 
80
- Local `ctx.state` belongs to one machine.
178
+ `ctx.state` is per-plugin key and value storage. Standard Code stores these
179
+ values in the user's account, so every machine the user has reads and writes
180
+ the same keys. `ctx.state.keys()` returns the sorted key names for this
181
+ plugin's account namespace. It returns an empty array when the plugin has no
182
+ keys and accepts only `RequestOptions`; it has no prefix or pagination
183
+ arguments. Another plugin cannot read these keys, even when it uses the same
184
+ account. Key names are 1 to 128 bytes. The first character is ASCII
185
+ alphanumeric or `_`; later characters are ASCII alphanumeric, `_`, `.`, `:`,
186
+ or `-`. A plugin holds at most 256 keys, and one value is at most 64 KiB of
187
+ JSON. The host applies the same account authority and revocation checks to
188
+ `keys()` as it applies to `get()` and `set()`.
81
189
  The public context declarations are in `src/index.d.ts`.
82
190
 
83
191
  ## Releases
84
192
 
85
193
  The Standard Code build workflow publishes this package when the version in
86
- `package.json` changes. Prereleases publish under the `next` dist-tag and
87
- releases under `latest`.
194
+ `package.json` changes. Main prereleases publish under `next` and main releases
195
+ under `latest`. Feature branches publish under their product branch tag. Authors
196
+ can install a published prerelease by its exact version.
197
+
198
+ ## Sidebar card titles
199
+
200
+ Sidebar card titles use muted, regular-weight text. A card declaration may
201
+ supply an `icon` containing one Nerd Font private-use glyph, for example
202
+ `"icon": "\uDB81\uDCC5"` (a gauge). The author chooses the card's topic icon.
203
+ The host shows it only on the viewer's Nerd Font tier. Other tiers omit the
204
+ icon and its spacing. Omitted icons have no fallback. This applies to bordered
205
+ and borderless cards. Empty titles remain empty.
206
+
207
+ A card view may replace its declared title through
208
+ `ui.view(root, { title: [{ text: 'Builds ' }, { text: '●', foreground: 'green' }] })`.
209
+ The optional `title` uses native `TextSpan` fields, including `#RRGGBB` and the terminal colors `black`, `red`, `green`,
210
+ `yellow`, `blue`, `magenta`, `cyan`, and `white`;
211
+ `ui.span()` is a body-view builder with a different shape. Titles accept 1–32
212
+ passive spans and at most 512 UTF-8 bytes of combined, nonblank single-line text.
213
+ Actions, control characters, and bidi formatting are rejected. Each replacement
214
+ updates the body and title together. Omitting `title` restores the manifest title.
215
+ This option belongs to card views. Plugins own the meaning and color of any
216
+ status light; the SDK adds no health indicator. Host title styling and supported
217
+ author-selected Nerd Font icons apply around the author-supplied spans.
88
218
 
89
219
  ## License
90
220
 
91
221
  MIT. See `LICENSE`.
222
+
223
+ ## Responsive pane rows
224
+
225
+ A pane header or footer slot can publish `rows` containing a `layout` and empty
226
+ `spans`. `layout.fields` is an ordered list of passive text fields. The host
227
+ resolves its geometry separately for every viewer, including pane resizes.
228
+ No resize event or producer repaint is needed.
229
+
230
+ ```js
231
+ slot.replace({ kind: 'rows', rows: [{ id: 'status', spans: [], layout: {
232
+ projectTint: true,
233
+ fields: [
234
+ { text: 'org/repo', bold: true },
235
+ { text: '~/src/repo', gap: 2, flex: true, tone: 'muted',
236
+ shrink: { priority: 1, min: 8, mode: 'middle' } },
237
+ { text: ' +24 ', gap: 2, flex: true, tone: 'ok', surface: true },
238
+ { text: ' −6 ', tone: 'error', surface: true },
239
+ ],
240
+ } }] })
241
+ ```
242
+
243
+ `gap` reserves 0–8 cells before a field. `flex` distributes spare width across
244
+ marked gaps; related fields without flexible gaps stay together. The first
245
+ field starts at the left edge and the final field reaches the right edge when
246
+ at least one visible flexible gap exists. `projectTint` fills the whole row
247
+ with the pane project's identity tint. `tone` accepts `muted`, `ok`, `error`,
248
+ `info`, `warning`, or `project`; semantic colors resolve against the viewer's
249
+ terminal palette. `surface` shades that field's background and `bold` emphasizes
250
+ its text. Include spaces in a field for padded color blocks.
251
+
252
+ `icon` is one Nerd Font private-use glyph. `fallback` is an optional ASCII
253
+ replacement (up to 16 bytes); viewers without Nerd Font support use the fallback.
254
+ The host supplies one space after an icon or fallback.
255
+
256
+ `shrink` policies run by increasing `priority` (0–255), then field order.
257
+ `min` is the retained text width in cells. `start`, `middle`, and `end` select
258
+ where an ellipsis replaces removed text. `hide` removes a field including its
259
+ icon and gap; all hide policies with equal priority are removed together.
260
+ Trimming preserves grapheme boundaries. If the declared minimum widths still
261
+ exceed the pane, remaining content clips at the right edge.
262
+
263
+ Layouts allow 1–32 fields, 2,048 UTF-8 bytes per text field and 8,192 total text
264
+ bytes. Controls and bidi formatting characters are rejected. Layouts are
265
+ supported only in pane header/footer slots. Ordinary rows and full/half slot
266
+ stacking retain their existing behavior.