@javierfrancoleal/plugin-authoring 1.0.1 → 1.0.3

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.
@@ -131,8 +131,9 @@ Rules:
131
131
 
132
132
  | Slot | Alcance | Para qué |
133
133
  |---|---|---|
134
- | `shell.bottom` | root | **global full-width bottom bar** (empty by default) |
135
- | `shell.overlay` / `shell.leading` | root | overlay / top-left corner |
134
+ | `shell.bottom` | root | **global full-width bottom bar** (empty by default) — **single: a 2nd occupant THROWS** |
135
+ | `shell.overlay` | root | **list (additive)** — overlays/pills without conflict |
136
+ | `shell.leading` | root | top-left corner (macOS) |
136
137
  | `sidebar` / `rightbar` / `main` | root | columns / central panel |
137
138
  | `conversation.input.dock` | sesión | bar above the composer |
138
139
 
@@ -164,6 +165,63 @@ This adds the dependency + bundle and runs pnpm for you; restart the app after.
164
165
  2. `cd ~/.dsh/profiles/<perfil> && pnpm install`.
165
166
  3. **Restart the app** (a new bundle needs a host recomposition).
166
167
 
168
+ ## Dynamic host→client data (Remote/Typert)
169
+
170
+ When the client needs changing data (balance, host state…), expose a **Remote** on
171
+ the host and read it from the client. Verified recipe (`jfranco-balance`,
172
+ 2026-11-04); `dsh-goal` uses a code generator that a `link:` without build cannot
173
+ use, so write everything by hand:
174
+
175
+ **Host** (`lib/index.js`):
176
+
177
+ ```js
178
+ import { TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
179
+
180
+ class MiService extends TypertRemoteService {
181
+ constructor(ctx) { super(ctx, "miServicio"); this.ctx = ctx; }
182
+ async getSnapshot() { /* JSON-serializable object */ }
183
+ }
184
+ const MARKER = "@deepseek-ai/dsh-typert-protocol/remote-methods";
185
+ Object.defineProperty(MiService.prototype, MARKER, {
186
+ configurable: true,
187
+ value: Object.freeze({ version: 1, methods: Object.freeze([
188
+ Object.freeze({ method: "getSnapshot", invocation: Object.freeze({ kind: "direct" }) }),
189
+ ]) }),
190
+ });
191
+ export default MiService; // default export = the Cordis plugin
192
+ ```
193
+
194
+ The gateway's SRC discovery exposes endpoint `miServicio/getSnapshot` with no
195
+ generated `./typert` artifact.
196
+
197
+ **Client** (`lib/client.js`):
198
+
199
+ ```js
200
+ const inject = ["slots", "locale", "remote"];
201
+ const CONTRIBUTION = {
202
+ package: "@javierfrancoleal/mi-plugin",
203
+ descriptors: [{
204
+ id: "@javierfrancoleal/mi-plugin#miServicio/getSnapshot",
205
+ service: "miServicio", namespace: "miServicio", method: "getSnapshot",
206
+ invocation: { kind: "direct" }, parameters: [], result: { mode: "src-json" },
207
+ }],
208
+ };
209
+ async function apply(ctx) {
210
+ await ctx.remote.$mount(CONTRIBUTION);
211
+ const handle = ctx.get("remote.miServicio");
212
+ const res = await handle.getSnapshot(); // { ok: true, value } | { ok: false, error }
213
+ }
214
+ ```
215
+
216
+ **DeepSeek credentials** (authenticated APIs, e.g. `GET /user/balance`):
217
+
218
+ - API key: `ctx.get("credentials").resolve("DEEPSEEK_API_KEY")` → `{ value }`
219
+ (header `Authorization: Bearer <key>`).
220
+ - Account token (fallback, live-verified 2026-11-04):
221
+ `ctx.get("deepseekAccount").resolveToken("https://api.deepseek.com")` →
222
+ header `x-dsh-auth-token`. `/user/balance` accepts it, so the plugin works
223
+ with account sign-in.
224
+
167
225
  ## Gotchas
168
226
 
169
227
  1. The checkout lives inside `app.asar` — use `_dsh-inspect/asar-tool.mjs list|extract`.
@@ -172,6 +230,13 @@ This adds the dependency + bundle and runs pnpm for you; restart the app after.
172
230
  3. New bundles are NOT picked up by HMR on external edits — restart the app.
173
231
  4. `dsh.bundle.patch` + `dsh.client` can coexist (dual-face).
174
232
  5. React / slots / primitives are baseline; don't list them in `dsh.client.inject`.
233
+ 6. **Bundle URLs are revisioned**: `/plugins/??<id>/client.js&rev=<rev>`; the bare
234
+ `/plugins/<id>/client.js` **always 404s**. Derive `rev` LOCALLY (no need to
235
+ scrape the HTML, which requires auth): sha1 over
236
+ `"plugin-artifact\0" + "<len>:mtimeMs" + "<len>:ctimeMs" + "<len>:size"`
237
+ (file stats of `lib/client.js`), first 12 hex chars — see the checklist.
238
+ The `/plugins` endpoint needs **no auth**.
239
+ 7. **The app may change port after a restart** — re-read the advertised URL.
175
240
 
176
241
  ## Validation checklist
177
242
 
@@ -179,7 +244,8 @@ This adds the dependency + bundle and runs pnpm for you; restart the app after.
179
244
  node --check lib/index.js && node --check lib/client.js
180
245
  node tools/check-client.mjs lib/client.js
181
246
  dsh --profile testprices --dump-config | grep mi-plugin # throwaway profile, not desktop
182
- curl -sS http://127.0.0.1:<puerto>/plugins/@scope/mi-plugin/client.js # 200 after restart
247
+ REV=$(node -e 'const fs=require("fs"),crypto=require("crypto");const st=fs.statSync("lib/client.js");const h=crypto.createHash("sha1").update("plugin-artifact").update("\0");for(const p of [String(st.mtimeMs),String(st.ctimeMs),String(st.size)])h.update(String(Buffer.byteLength(p))+":").update(p);console.log(h.digest("hex").slice(0,12))')
248
+ curl -sS "http://127.0.0.1:<puerto>/plugins/??@scope/mi-plugin/client.js&rev=$REV" # 200 (no auth needed)
183
249
  ```
184
250
 
185
251
  Full reference: `docs/PLUGIN-AUTHORING.md`. Template: `templates/dsh-plugin/`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@javierfrancoleal/plugin-authoring",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Plugin-authoring skill for DeepSeek Harness: the distilled anatomy, client-UI recipe, slots, locale, theme tokens, install steps, gotchas, and validation checklist for building and publishing new DSH plugins.",
5
5
  "author": "J.Franco",
6
6
  "license": "MIT",