@sbugallo/opencode-vpet 0.1.1 → 0.2.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.
Files changed (44) hide show
  1. package/README.md +4 -5
  2. package/dist/adapters/opencode/server-plugin.d.ts +78 -0
  3. package/dist/adapters/opencode/server-plugin.d.ts.map +1 -0
  4. package/dist/adapters/opencode/session-messages.d.ts +4 -9
  5. package/dist/adapters/opencode/session-messages.d.ts.map +1 -1
  6. package/dist/adapters/opencode/usage-event-mapper.d.ts +6 -3
  7. package/dist/adapters/opencode/usage-event-mapper.d.ts.map +1 -1
  8. package/dist/adapters/opencode/vpet-toast.d.ts +4 -2
  9. package/dist/adapters/opencode/vpet-toast.d.ts.map +1 -1
  10. package/dist/cli/install.d.ts.map +1 -1
  11. package/dist/cli.js +3 -3
  12. package/dist/cli.js.map +4 -4
  13. package/dist/commands/vpet-command-result.d.ts +2 -2
  14. package/dist/commands/vpet-command-result.d.ts.map +1 -1
  15. package/dist/commands/vpet-freeze.d.ts +1 -5
  16. package/dist/commands/vpet-freeze.d.ts.map +1 -1
  17. package/dist/commands/vpet-set.d.ts +0 -2
  18. package/dist/commands/vpet-set.d.ts.map +1 -1
  19. package/dist/commands/vpet-spawn.d.ts +0 -2
  20. package/dist/commands/vpet-spawn.d.ts.map +1 -1
  21. package/dist/commands/vpet-unfreeze.d.ts +1 -5
  22. package/dist/commands/vpet-unfreeze.d.ts.map +1 -1
  23. package/dist/index.d.ts +4 -8
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +535 -470
  26. package/dist/index.js.map +22 -21
  27. package/dist/package.json +10 -0
  28. package/dist/rpc.d.ts +32 -0
  29. package/dist/rpc.d.ts.map +1 -0
  30. package/dist/tui/theme.d.ts +27 -0
  31. package/dist/tui/theme.d.ts.map +1 -0
  32. package/dist/tui/vpet-command-layer.d.ts +32 -5
  33. package/dist/tui/vpet-command-layer.d.ts.map +1 -1
  34. package/dist/tui/vpet-dex-dialog.d.ts +2 -2
  35. package/dist/tui/vpet-dex-dialog.d.ts.map +1 -1
  36. package/dist/tui/vpet-history-dialog.d.ts +2 -2
  37. package/dist/tui/vpet-history-dialog.d.ts.map +1 -1
  38. package/dist/tui.d.ts +22 -12
  39. package/dist/tui.d.ts.map +1 -1
  40. package/dist/tui.js +203 -66
  41. package/dist/tui.js.map +10 -7
  42. package/package.json +9 -12
  43. package/dist/adapters/opencode/create-server-hooks.d.ts +0 -39
  44. package/dist/adapters/opencode/create-server-hooks.d.ts.map +0 -1
package/dist/tui.js CHANGED
@@ -1,7 +1,81 @@
1
1
  // @bun
2
2
  // src/tui.tsx
3
+ import { Plugin } from "@opencode/plugin/tui";
3
4
  import { createSignal } from "solid-js";
4
5
 
6
+ // src/adapters/opencode/vpet-toast.ts
7
+ var toVpetToastPayload = (data) => {
8
+ if (typeof data !== "object" || data === null || Array.isArray(data))
9
+ return;
10
+ const { title, message, variant, duration } = data;
11
+ if (typeof title !== "string" || typeof message !== "string" || variant !== "info" && variant !== "success" && variant !== "warning" || typeof duration !== "number") {
12
+ return;
13
+ }
14
+ return { title, message, variant, duration };
15
+ };
16
+ var assertNever = (value) => {
17
+ throw new Error(`Unhandled VPet toast event: ${JSON.stringify(value)}`);
18
+ };
19
+ var selectName = (node, language) => {
20
+ switch (language) {
21
+ case "en":
22
+ return node.nameEn;
23
+ case "jp":
24
+ return node.nameJp;
25
+ default:
26
+ return assertNever(language);
27
+ }
28
+ };
29
+ var namedPayload = (nodeId, language, catalog) => {
30
+ const node = catalog.byId.get(nodeId);
31
+ return node === undefined ? undefined : selectName(node, language);
32
+ };
33
+ var formatVpetToast = (event, language, catalog) => {
34
+ switch (event.kind) {
35
+ case "spawn": {
36
+ const name = namedPayload(event.nodeId, language, catalog);
37
+ return name === undefined ? undefined : {
38
+ title: "VPet",
39
+ message: `Spawned ${name} (Generation ${event.generation}).`,
40
+ variant: "success",
41
+ duration: 5000
42
+ };
43
+ }
44
+ case "freeze":
45
+ return { title: "VPet", message: "Digimon progression frozen.", variant: "info", duration: 3000 };
46
+ case "unfreeze":
47
+ return { title: "VPet", message: "Digimon progression resumed.", variant: "info", duration: 3000 };
48
+ case "set": {
49
+ const name = namedPayload(event.nodeId, language, catalog);
50
+ return name === undefined ? undefined : {
51
+ title: "VPet",
52
+ message: `VPet set to ${name} (${event.nodeId}).`,
53
+ variant: "info",
54
+ duration: 3000
55
+ };
56
+ }
57
+ case "evolution": {
58
+ const fromName = namedPayload(event.fromNodeId, language, catalog);
59
+ const toName = namedPayload(event.toNodeId, language, catalog);
60
+ return fromName === undefined || toName === undefined ? undefined : {
61
+ title: "Digi-evolution",
62
+ message: `${fromName} evolved into ${toName}!`,
63
+ variant: "success",
64
+ duration: 5000
65
+ };
66
+ }
67
+ default:
68
+ return assertNever(event);
69
+ }
70
+ };
71
+ var createBestEffortVpetToastNotifier = (transport) => {
72
+ return async (payload) => await Promise.resolve().then(() => transport(payload)).then(() => {
73
+ return;
74
+ }, () => {
75
+ return;
76
+ });
77
+ };
78
+
5
79
  // src/adapters/sqlite/sqlite-sidebar-snapshot-reader.ts
6
80
  import { existsSync } from "fs";
7
81
 
@@ -57877,6 +57951,28 @@ var MONSTER_FRAME_CATALOG = new MonsterFrameCatalog(MONSTER_FRAME_DATA.map(([spr
57877
57951
  frames.map(([frameName, content]) => [frameName, new MonsterFrame(content)])
57878
57952
  ]));
57879
57953
 
57954
+ // src/rpc.ts
57955
+ import { Rpc } from "@opencode/plugin/rpc";
57956
+ var VpetRpc = Rpc.define({
57957
+ id: "vpet",
57958
+ methods: {},
57959
+ events: {
57960
+ toast: {
57961
+ schema: {
57962
+ type: "object",
57963
+ properties: {
57964
+ title: { type: "string" },
57965
+ message: { type: "string" },
57966
+ variant: { enum: ["info", "success", "warning"] },
57967
+ duration: { type: "number" }
57968
+ },
57969
+ required: ["title", "message", "variant", "duration"],
57970
+ additionalProperties: false
57971
+ }
57972
+ }
57973
+ }
57974
+ });
57975
+
57880
57976
  // src/tui/sidebar-card.tsx
57881
57977
  import { createTextAttributes } from "@opentui/core";
57882
57978
  import { createEffect } from "solid-js";
@@ -58194,7 +58290,7 @@ var normalizedRandom = (random) => {
58194
58290
  };
58195
58291
 
58196
58292
  // src/tui/monster-walking-policy.ts
58197
- var assertNever = (value) => {
58293
+ var assertNever2 = (value) => {
58198
58294
  throw new Error(`Unexpected walking policy variant: ${JSON.stringify(value)}`);
58199
58295
  };
58200
58296
  var initialWalkingPolicy = (frameName) => ({
@@ -58229,7 +58325,7 @@ var tickWalkingPolicy = (state, sprite, catalog) => {
58229
58325
  case "queued_action":
58230
58326
  return { kind: "action", action: state };
58231
58327
  default:
58232
- return assertNever(state.bout);
58328
+ return assertNever2(state.bout);
58233
58329
  }
58234
58330
  };
58235
58331
  var resizeWalkingPolicy = (state, width, random) => {
@@ -58246,7 +58342,7 @@ var resizeWalkingPolicy = (state, width, random) => {
58246
58342
  case "suspended":
58247
58343
  return planBout({ ...resized, bout: { kind: "suspended" } }, random);
58248
58344
  default:
58249
- return assertNever(state.bout);
58345
+ return assertNever2(state.bout);
58250
58346
  }
58251
58347
  };
58252
58348
  var resizeActionBoundary = (state, width) => {
@@ -58299,7 +58395,7 @@ var normalizedRandom2 = (random) => {
58299
58395
  // src/tui/monster-animation.ts
58300
58396
  var ORIGIN = { offset: 0, facing: "left" };
58301
58397
  var SLEEP_AFTER_MS = 300000;
58302
- var assertNever2 = (value) => {
58398
+ var assertNever3 = (value) => {
58303
58399
  throw new Error(`Unexpected monster animation variant: ${JSON.stringify(value)}`);
58304
58400
  };
58305
58401
  var sameIdentity = (left, right) => left.sprite === right.sprite && left.isDigitama === right.isDigitama;
@@ -58333,7 +58429,7 @@ class MonsterAnimationController {
58333
58429
  this.#state = this.#resize(event.width);
58334
58430
  break;
58335
58431
  default:
58336
- return assertNever2(event);
58432
+ return assertNever3(event);
58337
58433
  }
58338
58434
  return this.output();
58339
58435
  }
@@ -58368,7 +58464,7 @@ class MonsterAnimationController {
58368
58464
  facing: state.boundary.facing
58369
58465
  };
58370
58466
  default:
58371
- return assertNever2(state);
58467
+ return assertNever3(state);
58372
58468
  }
58373
58469
  }
58374
58470
  setSprite(sprite) {
@@ -58422,7 +58518,7 @@ class MonsterAnimationController {
58422
58518
  case "sleeping":
58423
58519
  return { ...state, phase: state.phase === 0 ? 1 : 0 };
58424
58520
  default:
58425
- return assertNever2(state);
58521
+ return assertNever3(state);
58426
58522
  }
58427
58523
  }
58428
58524
  #tickWalking(state) {
@@ -58433,7 +58529,7 @@ class MonsterAnimationController {
58433
58529
  case "action":
58434
58530
  return this.#startAction(state.identity, tick.action);
58435
58531
  default:
58436
- return assertNever2(tick);
58532
+ return assertNever3(tick);
58437
58533
  }
58438
58534
  }
58439
58535
  #resize(width) {
@@ -58494,7 +58590,7 @@ class MonsterAnimationController {
58494
58590
  case "sleeping":
58495
58591
  return state.identity;
58496
58592
  default:
58497
- return assertNever2(state);
58593
+ return assertNever3(state);
58498
58594
  }
58499
58595
  }
58500
58596
  #firstWalkFrame(sprite) {
@@ -58618,9 +58714,18 @@ var buildSidebarCardModel = (inputs, settings = DEFAULT_VPET_SETTINGS) => {
58618
58714
  };
58619
58715
  };
58620
58716
 
58717
+ // src/tui/theme.ts
58718
+ var toVpetTheme = (theme) => ({
58719
+ current: {
58720
+ primary: theme.text.action.primary.base,
58721
+ success: theme.text.feedback.success.base,
58722
+ textMuted: theme.text.muted
58723
+ }
58724
+ });
58725
+
58621
58726
  // src/tui/dex-view-model.ts
58622
58727
  var REDACTED_NAME = "------";
58623
- var assertNever3 = (value) => {
58728
+ var assertNever4 = (value) => {
58624
58729
  throw new Error(`Unexpected archive result: ${JSON.stringify(value)}`);
58625
58730
  };
58626
58731
  var compareCatalogNodes = (left, right) => {
@@ -58666,12 +58771,12 @@ var buildDexViewModel = (archive, catalog, settings) => {
58666
58771
  case "unavailable":
58667
58772
  return { kind: "unavailable", message: archive.message };
58668
58773
  default:
58669
- return assertNever3(archive);
58774
+ return assertNever4(archive);
58670
58775
  }
58671
58776
  };
58672
58777
 
58673
58778
  // src/tui/history-view-model.ts
58674
- var assertNever4 = (value) => {
58779
+ var assertNever5 = (value) => {
58675
58780
  throw new Error(`Unexpected archive result: ${JSON.stringify(value)}`);
58676
58781
  };
58677
58782
  var comparePartners = (left, right) => {
@@ -58716,7 +58821,7 @@ var buildHistoryViewModel = (archive, catalog, settings) => {
58716
58821
  case "unavailable":
58717
58822
  return { kind: "unavailable", message: archive.message };
58718
58823
  default:
58719
- return assertNever4(archive);
58824
+ return assertNever5(archive);
58720
58825
  }
58721
58826
  };
58722
58827
 
@@ -59035,25 +59140,25 @@ var registerVpetCommandLayer = ({
59035
59140
  api.ui.dialog.setSize("medium");
59036
59141
  };
59037
59142
  const disposeLayer = api.keymap.registerLayer({
59038
- name: "opencode-vpet.layer",
59039
- namespace: "opencode-vpet",
59143
+ mode: "global",
59144
+ priority: 10,
59040
59145
  commands: [
59041
59146
  {
59042
- name: "vpet.dex",
59147
+ id: "vpet.dex",
59043
59148
  title: "VPet Dex",
59044
59149
  description: "Browse the VPet discovery archive.",
59045
- category: "VPet",
59046
- namespace: "palette",
59047
- slashName: "vpet-dex",
59150
+ group: "VPet",
59151
+ palette: true,
59152
+ slash: { name: "vpet-dex" },
59048
59153
  run: openDex
59049
59154
  },
59050
59155
  {
59051
- name: "vpet.history",
59156
+ id: "vpet.history",
59052
59157
  title: "VPet History",
59053
59158
  description: "Browse VPet generation history.",
59054
- category: "VPet",
59055
- namespace: "palette",
59056
- slashName: "vpet-history",
59159
+ group: "VPet",
59160
+ palette: true,
59161
+ slash: { name: "vpet-history" },
59057
59162
  run: openHistory
59058
59163
  }
59059
59164
  ]
@@ -59071,7 +59176,7 @@ var registerVpetCommandLayer = ({
59071
59176
  import { jsxDEV as jsxDEV5 } from "@opentui/solid/jsx-dev-runtime";
59072
59177
  var VISUAL_INTERVAL_MS = 500;
59073
59178
  var getStringOption = (options, name) => {
59074
- const value = options?.[name];
59179
+ const value = options[name];
59075
59180
  return typeof value === "string" ? value : undefined;
59076
59181
  };
59077
59182
  var readerOptions = (options) => {
@@ -59139,10 +59244,11 @@ var createTui = (loadInputs, settings, scheduling = {}) => async (api) => {
59139
59244
  api.renderer.requestRender();
59140
59245
  };
59141
59246
  const unsubscribes = [
59142
- api.event.on("message.updated", activity),
59143
- api.event.on("message.part.updated", activity),
59247
+ api.event.on("session.text.delta", activity),
59248
+ api.event.on("session.tool.called", activity),
59249
+ api.event.on("session.execution.succeeded", activity),
59144
59250
  api.event.on("session.status", (event) => {
59145
- switch (event.properties.status.type) {
59251
+ switch (event.data.status.type) {
59146
59252
  case "busy":
59147
59253
  case "retry":
59148
59254
  activity();
@@ -59150,7 +59256,7 @@ var createTui = (loadInputs, settings, scheduling = {}) => async (api) => {
59150
59256
  case "idle":
59151
59257
  return;
59152
59258
  default: {
59153
- const unexpectedStatus = event.properties.status;
59259
+ const unexpectedStatus = event.data.status;
59154
59260
  return unexpectedStatus;
59155
59261
  }
59156
59262
  }
@@ -59159,11 +59265,7 @@ var createTui = (loadInputs, settings, scheduling = {}) => async (api) => {
59159
59265
  poller.start();
59160
59266
  const disposeLayer = api.keymap === undefined || api.ui === undefined || api.theme === undefined ? () => {
59161
59267
  return;
59162
- } : scheduling.archiveReader === undefined ? api.keymap.registerLayer({
59163
- name: "opencode-vpet.layer",
59164
- namespace: "opencode-vpet",
59165
- commands: []
59166
- }) : registerVpetCommandLayer({
59268
+ } : scheduling.archiveReader === undefined ? api.keymap.registerLayer({ commands: [] }) : registerVpetCommandLayer({
59167
59269
  api: { keymap: api.keymap, ui: api.ui, theme: api.theme },
59168
59270
  reader: scheduling.archiveReader,
59169
59271
  catalog: DIGIMON_CATALOG,
@@ -59197,45 +59299,80 @@ var createTui = (loadInputs, settings, scheduling = {}) => async (api) => {
59197
59299
  }
59198
59300
  });
59199
59301
  };
59200
- var tui = async (api, options) => {
59201
- const reader = createSqliteSidebarSnapshotReader(readerOptions(options));
59202
- const archiveReader = createSqliteVpetArchiveReader(readerOptions(options));
59203
- const settings = await loadGlobalVpetSettings();
59204
- await createTui(() => getSidebarCardInputs(reader, DIGIMON_CATALOG), settings, { archiveReader })({
59205
- event: {
59206
- on: (...subscription) => {
59207
- switch (subscription[0]) {
59208
- case "message.updated":
59209
- return api.event.on(subscription[0], subscription[1]);
59210
- case "message.part.updated":
59211
- return api.event.on(subscription[0], subscription[1]);
59212
- case "session.status":
59213
- return api.event.on(subscription[0], subscription[1]);
59302
+ var plugin = Plugin.define({
59303
+ id: "opencode-vpet.tui",
59304
+ async setup(context) {
59305
+ const reader = createSqliteSidebarSnapshotReader(readerOptions(context.options));
59306
+ const archiveReader = createSqliteVpetArchiveReader(readerOptions(context.options));
59307
+ const settings = await loadGlobalVpetSettings();
59308
+ const cleanups = [];
59309
+ const pushCleanup = (cleanup) => {
59310
+ cleanups.push(cleanup);
59311
+ return () => {
59312
+ const index = cleanups.indexOf(cleanup);
59313
+ if (index >= 0)
59314
+ cleanups.splice(index, 1);
59315
+ };
59316
+ };
59317
+ pushCleanup(context.client.rpc(VpetRpc).events.on("toast", (event) => {
59318
+ const payload = toVpetToastPayload(event.data);
59319
+ if (payload !== undefined)
59320
+ context.ui.toast.show(payload);
59321
+ }));
59322
+ await createTui(() => getSidebarCardInputs(reader, DIGIMON_CATALOG), settings, { archiveReader })({
59323
+ event: {
59324
+ on: (...subscription) => {
59325
+ switch (subscription[0]) {
59326
+ case "session.status":
59327
+ return context.data.on("session.status", subscription[1]);
59328
+ case "session.text.delta":
59329
+ return context.data.on("session.text.delta", subscription[1]);
59330
+ case "session.tool.called":
59331
+ return context.data.on("session.tool.called", subscription[1]);
59332
+ case "session.execution.succeeded":
59333
+ return context.data.on("session.execution.succeeded", subscription[1]);
59334
+ }
59214
59335
  }
59215
- }
59216
- },
59217
- renderer: api.renderer,
59218
- lifecycle: api.lifecycle,
59219
- slots: api.slots,
59220
- keymap: { registerLayer: api.keymap.registerLayer.bind(api.keymap) },
59221
- ui: {
59222
- dialog: {
59223
- replace: api.ui.dialog.replace.bind(api.ui.dialog),
59224
- clear: api.ui.dialog.clear.bind(api.ui.dialog),
59225
- setSize: api.ui.dialog.setSize.bind(api.ui.dialog)
59226
59336
  },
59227
- Dialog: api.ui.Dialog
59228
- },
59229
- theme: api.theme
59230
- });
59231
- };
59232
- var plugin = { id: "opencode-vpet", tui };
59337
+ renderer: context.renderer,
59338
+ lifecycle: { onDispose: pushCleanup },
59339
+ slots: {
59340
+ register: (registered) => {
59341
+ pushCleanup(context.ui.slot({
59342
+ prepend: "sidebar.content",
59343
+ render: () => registered.slots.sidebar_content()
59344
+ }));
59345
+ return "opencode-vpet";
59346
+ }
59347
+ },
59348
+ keymap: {
59349
+ registerLayer: (layer) => {
59350
+ context.keymap.layer(() => layer);
59351
+ return () => {
59352
+ return;
59353
+ };
59354
+ }
59355
+ },
59356
+ ui: {
59357
+ dialog: {
59358
+ replace: (render, onClose) => context.ui.dialog.show(render, onClose),
59359
+ clear: () => context.ui.dialog.clear(),
59360
+ setSize: (size) => context.ui.dialog.set({ size })
59361
+ }
59362
+ },
59363
+ theme: toVpetTheme(context.theme)
59364
+ });
59365
+ return () => {
59366
+ for (let index = cleanups.length - 1;index >= 0; index -= 1)
59367
+ cleanups[index]?.();
59368
+ };
59369
+ }
59370
+ });
59233
59371
  var tui_default = plugin;
59234
59372
  export {
59235
- tui,
59236
59373
  tui_default as default,
59237
59374
  createTui
59238
59375
  };
59239
59376
 
59240
- //# debugId=B06D4BB88D9B412A64756E2164756E21
59377
+ //# debugId=25BF8E68C114596364756E2164756E21
59241
59378
  //# sourceMappingURL=tui.js.map