@mrclrchtr/supi-skills 11.0.1 → 11.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "11.0.1",
3
+ "version": "11.2.0",
4
4
  "description": "Shared settings, configuration, reporting, and session infrastructure",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -14,6 +14,8 @@ export interface DebugRegistryConfig {
14
14
  enabled: boolean;
15
15
  /** What the agent-callable debug tool may return. */
16
16
  agentAccess: DebugAgentAccess;
17
+ /** Whether Agent Run retrospective capture is explicitly enabled. */
18
+ agentRunRetrospectivesEnabled: boolean;
17
19
  /** Maximum number of session-local events to keep in memory. */
18
20
  maxEvents: number;
19
21
  }
@@ -21,6 +23,7 @@ export interface DebugRegistryConfig {
21
23
  export const DEBUG_REGISTRY_DEFAULTS: DebugRegistryConfig = {
22
24
  enabled: false,
23
25
  agentAccess: "sanitized",
26
+ agentRunRetrospectivesEnabled: false,
24
27
  maxEvents: 100,
25
28
  };
26
29
 
@@ -75,6 +78,9 @@ export interface DebugEventQueryResult {
75
78
  /** Receives a sanitized event whenever the registry records one. */
76
79
  export type DebugEventListener = (event: DebugEventView) => void;
77
80
 
81
+ /** Receives sanitized events for persistence; separate from ordinary event subscriptions. */
82
+ export type DebugPersistenceSink = (event: DebugEventView) => void;
83
+
78
84
  export interface DebugSummary {
79
85
  total: number;
80
86
  byLevel: Partial<Record<DebugLevel, number>>;
@@ -85,6 +91,7 @@ interface DebugRegistryState {
85
91
  config: DebugRegistryConfig;
86
92
  events: DebugEvent[];
87
93
  listeners: Set<DebugEventListener>;
94
+ persistenceSinks: Set<DebugPersistenceSink>;
88
95
  nextId: number;
89
96
  }
90
97
 
@@ -111,13 +118,15 @@ function getState(): DebugRegistryState {
111
118
  config: cloneConfig(DEBUG_REGISTRY_DEFAULTS),
112
119
  events: [],
113
120
  listeners: new Set(),
121
+ persistenceSinks: new Set(),
114
122
  nextId: 1,
115
123
  };
116
124
  (globalThis as Record<symbol, unknown>)[REGISTRY_KEY] = state;
117
125
  }
118
126
  // Keep the shared registry compatible with extension reloads that reuse an
119
- // instance created before listeners existed.
127
+ // instance created before listener sets existed.
120
128
  if (!state.listeners) state.listeners = new Set();
129
+ if (!state.persistenceSinks) state.persistenceSinks = new Set();
121
130
  return state;
122
131
  }
123
132
 
@@ -200,6 +209,19 @@ export function isDebugRegistryEnabled(): boolean {
200
209
  return getState().config.enabled;
201
210
  }
202
211
 
212
+ /**
213
+ * Return whether a retrospective can be captured: Debug and its explicit opt-in
214
+ * must be enabled, and at least one persistence sink must be registered.
215
+ */
216
+ export function canRecordAgentRunRetrospective(): boolean {
217
+ const state = getState();
218
+ return (
219
+ state.config.enabled &&
220
+ state.config.agentRunRetrospectivesEnabled &&
221
+ state.persistenceSinks.size > 0
222
+ );
223
+ }
224
+
203
225
  /** Best-effort redaction helper for data exposed through sanitized debug views. */
204
226
  export function redactDebugData<T>(value: T): T {
205
227
  return redactValue(value, 8) as T;
@@ -226,6 +248,16 @@ export function subscribeDebugEvents(listener: DebugEventListener): () => void {
226
248
  return () => state.listeners.delete(listener);
227
249
  }
228
250
 
251
+ /**
252
+ * Register a sanitized event persistence sink. Sinks are tracked separately from
253
+ * ordinary listeners so eligibility checks only succeed when logging is active.
254
+ */
255
+ export function subscribeDebugPersistence(sink: DebugPersistenceSink): () => void {
256
+ const state = getState();
257
+ state.persistenceSinks.add(sink);
258
+ return () => state.persistenceSinks.delete(sink);
259
+ }
260
+
229
261
  /** Record a session-local debug event if debugging is enabled. */
230
262
  export function recordDebugEvent(input: DebugEventInput): DebugEvent | null {
231
263
  const state = getState();
@@ -251,6 +283,13 @@ export function recordDebugEvent(input: DebugEventInput): DebugEvent | null {
251
283
  // Debug-event consumers must not alter producer behavior.
252
284
  }
253
285
  }
286
+ for (const sink of state.persistenceSinks) {
287
+ try {
288
+ sink(toSanitizedView(event));
289
+ } catch {
290
+ // Persistence failures must not alter producer behavior.
291
+ }
292
+ }
254
293
  return {
255
294
  ...event,
256
295
  data: event.data === undefined ? undefined : redactDebugData(event.data),
@@ -309,5 +348,6 @@ export function resetDebugRegistry(): void {
309
348
  state.config = cloneConfig(DEBUG_REGISTRY_DEFAULTS);
310
349
  state.events = [];
311
350
  state.listeners.clear();
351
+ state.persistenceSinks.clear();
312
352
  state.nextId = 1;
313
353
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-skills",
3
- "version": "11.0.1",
3
+ "version": "11.2.0",
4
4
  "description": "Scoped skill controls and skill input shortcuts for PI",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -30,7 +30,7 @@
30
30
  "README.md"
31
31
  ],
32
32
  "dependencies": {
33
- "@mrclrchtr/supi-core": "11.0.1"
33
+ "@mrclrchtr/supi-core": "11.2.0"
34
34
  },
35
35
  "bundledDependencies": [
36
36
  "@mrclrchtr/supi-core"