dsh-brief-sidebar 0.9.0 → 0.9.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.
package/lib/index.mjs CHANGED
@@ -5515,9 +5515,15 @@ const CAPS = {
5515
5515
  /** Skills kept in the latest-turn bucket of the wire view. */
5516
5516
  latest: 20,
5517
5517
  /** Distinct skills kept in the wire view. */
5518
- view: 20
5518
+ view: 20,
5519
+ /**
5520
+ * Available-skill names kept in state. Real catalogs measured 71–88 entries
5521
+ * on this machine, so the bound sits above them with room to spare — the
5522
+ * wire only ever carries `CAPS.available` names plus the truthful count.
5523
+ */
5524
+ available: 120
5519
5525
  };
5520
- /** The fold's initial state: no skill has been loaded yet. */
5526
+ /** The fold's initial state: no skill has been referenced or offered yet. */
5521
5527
  function initSkillUsageState() {
5522
5528
  return {
5523
5529
  turn: 0,
@@ -5525,7 +5531,9 @@ function initSkillUsageState() {
5525
5531
  latest: null,
5526
5532
  items: [],
5527
5533
  sessionTotal: 0,
5528
- callTotal: 0
5534
+ callTotal: 0,
5535
+ catalog: [],
5536
+ catalogCount: 0
5529
5537
  };
5530
5538
  }
5531
5539
  /**
@@ -5548,6 +5556,36 @@ function skillNameFromArgs(name, argsRaw) {
5548
5556
  return typeof skill === "string" && skill.trim().length > 0 ? skill : null;
5549
5557
  }
5550
5558
  /**
5559
+ * Advance one reference tally. Both channels of "this skill was referenced"
5560
+ * land here, so a direct invocation and a tool load of the same skill share one
5561
+ * row rather than appearing twice.
5562
+ * @param state - the state before the reference.
5563
+ * @param skill - the skill name, exactly as published.
5564
+ * @param turn - the turn whose call/injection this reference belongs to.
5565
+ */
5566
+ function tally(state, skill, turn) {
5567
+ const existing = state.items.find((item) => item.name === skill);
5568
+ const withoutSkill = state.items.filter((item) => item.name !== skill);
5569
+ const items = [{
5570
+ name: skill,
5571
+ count: (existing?.count ?? 0) + 1,
5572
+ lastTurn: turn
5573
+ }, ...withoutSkill].slice(0, CAPS.session);
5574
+ const sessionTotal = existing === void 0 ? state.sessionTotal + 1 : state.sessionTotal;
5575
+ const latest = state.latest;
5576
+ const nextLatest = latest !== null && latest.turn === turn && !latest.names.includes(skill) ? {
5577
+ turn: latest.turn,
5578
+ names: [...latest.names, skill]
5579
+ } : latest;
5580
+ return {
5581
+ ...state,
5582
+ latest: nextLatest,
5583
+ items,
5584
+ sessionTotal,
5585
+ callTotal: state.callTotal + 1
5586
+ };
5587
+ }
5588
+ /**
5551
5589
  * The next state after one committed event. Events this fold does not own
5552
5590
  * return the SAME reference — an unchanged reference produces zero downstream
5553
5591
  * work in the registry's `Object.is` drive.
@@ -5589,6 +5627,32 @@ function applySkillUsageEvent(state, event) {
5589
5627
  }
5590
5628
  };
5591
5629
  }
5630
+ if (event.type === "user/message") {
5631
+ const message = event.data;
5632
+ if (message?.source === null || typeof message.source !== "object") return state;
5633
+ const source = message.source;
5634
+ if (source.kind === "skill-invocation") {
5635
+ const skill = typeof source.name === "string" && source.name.trim().length > 0 ? source.name : null;
5636
+ if (skill === null) return state;
5637
+ return tally(state, skill, state.turn);
5638
+ }
5639
+ if (source.kind === "skill-catalog") {
5640
+ if (!Array.isArray(source.entries)) return state;
5641
+ const names = [];
5642
+ for (const entry of source.entries) {
5643
+ if (entry === null || typeof entry !== "object") continue;
5644
+ const published = entry["name"];
5645
+ if (typeof published !== "string" || published.trim().length === 0) continue;
5646
+ if (!names.includes(published)) names.push(published);
5647
+ }
5648
+ return {
5649
+ ...state,
5650
+ catalog: names.slice(0, CAPS.available),
5651
+ catalogCount: names.length
5652
+ };
5653
+ }
5654
+ return state;
5655
+ }
5592
5656
  if (event.type !== "tool/result") return state;
5593
5657
  const result = event.data;
5594
5658
  const callId = result?.message?.source?.callId;
@@ -5596,27 +5660,7 @@ function applySkillUsageEvent(state, event) {
5596
5660
  if (result?.message?.content?.[0]?.isError === true) return state;
5597
5661
  const recorded = state.calls[callId];
5598
5662
  if (recorded === void 0) return state;
5599
- const skill = recorded.skill;
5600
- const existing = state.items.find((item) => item.name === skill);
5601
- const withoutSkill = state.items.filter((item) => item.name !== skill);
5602
- const items = [{
5603
- name: skill,
5604
- count: (existing?.count ?? 0) + 1,
5605
- lastTurn: recorded.turn
5606
- }, ...withoutSkill].slice(0, CAPS.session);
5607
- const sessionTotal = existing === void 0 ? state.sessionTotal + 1 : state.sessionTotal;
5608
- const latest = state.latest;
5609
- const nextLatest = latest !== null && latest.turn === recorded.turn && !latest.names.includes(skill) ? {
5610
- turn: latest.turn,
5611
- names: [...latest.names, skill]
5612
- } : latest;
5613
- return {
5614
- ...state,
5615
- latest: nextLatest,
5616
- items,
5617
- sessionTotal,
5618
- callTotal: state.callTotal + 1
5619
- };
5663
+ return tally(state, recorded.skill, recorded.turn);
5620
5664
  }
5621
5665
  //#endregion
5622
5666
  //#region src/projection/keys.ts
@@ -5745,7 +5789,9 @@ const skillStateSchema = object({
5745
5789
  lastTurn: number()
5746
5790
  })),
5747
5791
  sessionTotal: number(),
5748
- callTotal: number()
5792
+ callTotal: number(),
5793
+ catalog: array(string()).default([]),
5794
+ catalogCount: number().default(0)
5749
5795
  });
5750
5796
  /** Zod schema of the skill-usage wire view. */
5751
5797
  const skillViewSchema = object({
@@ -5759,7 +5805,9 @@ const skillViewSchema = object({
5759
5805
  lastTurn: number()
5760
5806
  })),
5761
5807
  sessionTotal: number(),
5762
- callTotal: number()
5808
+ callTotal: number(),
5809
+ available: array(string()),
5810
+ availableCount: number()
5763
5811
  });
5764
5812
  /** Same reference-stability memo as above, for the skill-usage unit. */
5765
5813
  const skillViewMemo = /* @__PURE__ */ new WeakMap();
@@ -5774,7 +5822,9 @@ function skillView(state) {
5774
5822
  },
5775
5823
  session: state.items.slice(0, CAPS.view),
5776
5824
  sessionTotal: state.sessionTotal,
5777
- callTotal: state.callTotal
5825
+ callTotal: state.callTotal,
5826
+ available: state.catalog.slice(0, CAPS.available),
5827
+ availableCount: state.catalogCount
5778
5828
  };
5779
5829
  skillViewMemo.set(state, next);
5780
5830
  return next;
@@ -5797,7 +5847,7 @@ function registerSkillUsageProjection(ctx) {
5797
5847
  viewSchema: skillViewSchema,
5798
5848
  view: skillView
5799
5849
  },
5800
- stateVersion: 0
5850
+ stateVersion: 1
5801
5851
  });
5802
5852
  });
5803
5853
  }