@pylabmit/agent-cmdb 1.5.0 → 2.0.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 (64) hide show
  1. package/README.md +29 -4
  2. package/dist/brain.d.ts.map +1 -1
  3. package/dist/brain.js +119 -44
  4. package/dist/brain.js.map +1 -1
  5. package/dist/checkpoint.d.ts +6 -0
  6. package/dist/checkpoint.d.ts.map +1 -0
  7. package/dist/checkpoint.js +137 -0
  8. package/dist/checkpoint.js.map +1 -0
  9. package/dist/cli.js +162 -7
  10. package/dist/cli.js.map +1 -1
  11. package/dist/cost.d.ts +3 -0
  12. package/dist/cost.d.ts.map +1 -0
  13. package/dist/cost.js +49 -0
  14. package/dist/cost.js.map +1 -0
  15. package/dist/digest.d.ts +2 -1
  16. package/dist/digest.d.ts.map +1 -1
  17. package/dist/digest.js +18 -2
  18. package/dist/digest.js.map +1 -1
  19. package/dist/engine.d.ts +0 -2
  20. package/dist/engine.d.ts.map +1 -1
  21. package/dist/engine.js +0 -2
  22. package/dist/engine.js.map +1 -1
  23. package/dist/health.d.ts +9 -0
  24. package/dist/health.d.ts.map +1 -0
  25. package/dist/health.js +222 -0
  26. package/dist/health.js.map +1 -0
  27. package/dist/interface.d.ts +15 -2
  28. package/dist/interface.d.ts.map +1 -1
  29. package/dist/interface.js +47 -3
  30. package/dist/interface.js.map +1 -1
  31. package/dist/internal.d.ts +3 -0
  32. package/dist/internal.d.ts.map +1 -0
  33. package/dist/internal.js +3 -0
  34. package/dist/internal.js.map +1 -0
  35. package/dist/loader.js +54 -3
  36. package/dist/loader.js.map +1 -1
  37. package/dist/policy-engine.js +7 -7
  38. package/dist/policy-engine.js.map +1 -1
  39. package/dist/preflight.d.ts +5 -3
  40. package/dist/preflight.d.ts.map +1 -1
  41. package/dist/preflight.js +144 -20
  42. package/dist/preflight.js.map +1 -1
  43. package/dist/route-resolver.d.ts.map +1 -1
  44. package/dist/route-resolver.js +47 -6
  45. package/dist/route-resolver.js.map +1 -1
  46. package/dist/slo.d.ts +4 -0
  47. package/dist/slo.d.ts.map +1 -0
  48. package/dist/slo.js +147 -0
  49. package/dist/slo.js.map +1 -0
  50. package/dist/store.d.ts +10 -0
  51. package/dist/store.d.ts.map +1 -1
  52. package/dist/store.js +165 -12
  53. package/dist/store.js.map +1 -1
  54. package/dist/types.d.ts +75 -4
  55. package/dist/types.d.ts.map +1 -1
  56. package/package.json +9 -1
  57. package/dist/agent-preflight.d.ts +0 -6
  58. package/dist/agent-preflight.d.ts.map +0 -1
  59. package/dist/agent-preflight.js +0 -55
  60. package/dist/agent-preflight.js.map +0 -1
  61. package/dist/preflight-action.d.ts +0 -3
  62. package/dist/preflight-action.d.ts.map +0 -1
  63. package/dist/preflight-action.js +0 -101
  64. package/dist/preflight-action.js.map +0 -1
package/dist/preflight.js CHANGED
@@ -1,36 +1,160 @@
1
- import { createAgentCmdb } from './interface.js';
2
- export async function agentPreflight(request, options = {}) {
3
- const cmdb = createAgentCmdb(options);
4
- const result = cmdb.preflight(request);
5
- const now = new Date().toISOString();
1
+ import { evaluatePolicy, normalizePolicyRequest } from './policy-engine.js';
2
+ import { inspectProfile, resolveSourceRoute } from './route-resolver.js';
3
+ import { isSourceAvailable, listSourceHealth } from './health.js';
4
+ import { updateSloCache } from './slo.js';
5
+ import { appendChange, appendEvidence } from './store.js';
6
+ export function evaluatePreflight(controlPlane, request, options = {}) {
7
+ const normalizedRequest = normalizePreflightRequest(request);
8
+ const decision = evaluatePolicy(controlPlane, normalizedRequest);
9
+ let finalDecision = decision;
10
+ let route;
11
+ const warnings = [];
12
+ if (normalizedRequest.intent) {
13
+ try {
14
+ route = resolveSourceRoute(controlPlane, {
15
+ profile: normalizedRequest.profile,
16
+ intent: normalizedRequest.intent,
17
+ freshness: normalizedRequest.freshness,
18
+ health: options.health
19
+ });
20
+ if (decision.effect === 'allow' && route.blockOnStale && route.staleSourceIds.length > 0) {
21
+ const reason = `Route contains stale sources and blockOnStale is enabled: ${route.staleSourceIds.join(', ')}.`;
22
+ warnings.push(reason);
23
+ finalDecision = denyDecision(normalizedRequest, 'stale-source-blocked', 'stale_source_blocked', reason, 'Refresh the source freshness snapshots or choose a fresh route.');
24
+ }
25
+ if (decision.effect === 'allow' && route.sources.length === 0 && route.skippedSources.length > 0) {
26
+ const reason = `All route sources are down: ${route.skippedSources.join(', ')}.`;
27
+ warnings.push(reason);
28
+ finalDecision = denyDecision(normalizedRequest, 'all-sources-down', 'all_sources_down', reason, 'Wait for source recovery or reset source health after manual verification.');
29
+ }
30
+ if (finalDecision.effect === 'allow'
31
+ && normalizedRequest.tool
32
+ && skippedSourcesIncludeTool(route.skippedSources, normalizedRequest.tool)) {
33
+ const reason = `Requested tool ${normalizedRequest.tool} is down.`;
34
+ warnings.push(reason);
35
+ finalDecision = denyDecision(normalizedRequest, 'requested-tool-down', 'requested_tool_down', reason, 'Use one of the returned route fallback sources instead of the down requested tool.');
36
+ }
37
+ }
38
+ catch (error) {
39
+ const message = error instanceof Error ? error.message : String(error);
40
+ const reason = `Route resolution failed: ${message}`;
41
+ warnings.push(reason);
42
+ if (decision.effect === 'allow' || decision.effect === 'approval_required') {
43
+ finalDecision = denyDecision(normalizedRequest, 'route-resolution-failed', 'route_resolution_failed', reason, 'Fix the source route for this profile and intent before executing.');
44
+ }
45
+ }
46
+ }
47
+ const profile = inspectProfile(controlPlane, normalizedRequest.profile);
48
+ return {
49
+ allowed: finalDecision.effect === 'allow',
50
+ approvalRequired: finalDecision.effect === 'approval_required',
51
+ decision: finalDecision,
52
+ route,
53
+ routeExecutable: finalDecision.effect === 'allow' && Boolean(route),
54
+ guardrails: route?.guardrails ?? profile.guardrails,
55
+ warnings,
56
+ dryRun: Boolean(normalizedRequest.dryRun)
57
+ };
58
+ }
59
+ export async function preflight(controlPlane, storeDir, request) {
60
+ await Promise.all(controlPlane.sources.map((source) => isSourceAvailable(controlPlane, storeDir, source.id)));
61
+ const health = await listSourceHealth(controlPlane, storeDir);
62
+ const result = evaluatePreflight(controlPlane, request, { health });
6
63
  if (result.dryRun) {
7
64
  return result;
8
65
  }
9
- if (result.decision.effect === 'deny') {
10
- await cmdb.logEvidence({
66
+ if (!result.allowed) {
67
+ await appendEvidence(storeDir, {
11
68
  profile: result.decision.profile,
12
69
  source: 'agent-cmdb-preflight',
13
70
  intent: request.intent ?? result.decision.action,
14
- summary: `Denied: ${result.decision.reason}`,
71
+ summary: `Denied by ${result.decision.ruleId}: ${result.decision.reason}`,
15
72
  trust: 'high',
16
- capturedAt: now,
17
- tags: ['agent-cmdb', 'preflight', 'deny', result.decision.ruleId]
73
+ capturedAt: new Date().toISOString(),
74
+ estimatedCost: estimateCost(controlPlane, result),
75
+ tags: ['preflight', 'deny', result.decision.ruleId]
18
76
  });
19
77
  }
20
- await cmdb.logChange({
21
- target: result.decision.ruleId,
78
+ await appendChange(storeDir, {
79
+ target: `policy.${result.decision.ruleId}`,
22
80
  targetType: 'policy',
23
81
  action: 'verify',
24
82
  actor: 'agent-cmdb-preflight',
25
- reason: `Preflight ${result.decision.effect} for ${result.decision.profile}/${result.decision.action}.`,
26
- changedAt: now,
27
- after: {
28
- allowed: result.allowed,
29
- approvalRequired: result.approvalRequired,
30
- routeExecutable: result.routeExecutable,
31
- decision: result.decision
32
- }
83
+ reason: `Preflight ${result.decision.effect} for ${result.decision.profile}:${result.decision.action}.`,
84
+ changedAt: new Date().toISOString(),
85
+ after: result
33
86
  });
87
+ await updateSloCache(controlPlane, storeDir, result);
34
88
  return result;
35
89
  }
90
+ function normalizePreflightRequest(request) {
91
+ const normalizedPolicy = normalizePolicyRequest(request);
92
+ const record = requireRecord(request, 'Preflight request');
93
+ const intent = record.intent === undefined
94
+ ? undefined
95
+ : requireNonEmptyString(record.intent, 'Preflight request intent', 'when provided');
96
+ const dryRun = record.dryRun === undefined ? undefined : requireBoolean(record.dryRun, 'Preflight request dryRun');
97
+ const freshness = normalizeFreshness(record.freshness);
98
+ return {
99
+ ...normalizedPolicy,
100
+ intent,
101
+ dryRun,
102
+ freshness
103
+ };
104
+ }
105
+ function denyDecision(request, ruleId, code, reason, suggestedAlternative) {
106
+ return {
107
+ effect: 'deny',
108
+ ruleId,
109
+ code,
110
+ reason,
111
+ profile: request.profile,
112
+ action: request.action,
113
+ tool: request.tool,
114
+ canEscalate: false,
115
+ suggestedAlternative
116
+ };
117
+ }
118
+ function normalizeFreshness(value) {
119
+ if (value === undefined)
120
+ return undefined;
121
+ if (!Array.isArray(value)) {
122
+ throw new Error('Preflight request freshness must be an array.');
123
+ }
124
+ return value.map((entry) => {
125
+ const record = requireRecord(entry, 'Preflight freshness input');
126
+ return {
127
+ sourceId: requireNonEmptyString(record.sourceId, 'Preflight freshness sourceId'),
128
+ lastUpdated: requireNonEmptyString(record.lastUpdated, 'Preflight freshness lastUpdated')
129
+ };
130
+ });
131
+ }
132
+ function requireBoolean(value, label) {
133
+ if (typeof value !== 'boolean') {
134
+ throw new Error(`${label} must be a boolean.`);
135
+ }
136
+ return value;
137
+ }
138
+ function requireRecord(value, label) {
139
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
140
+ throw new Error(`${label} must be an object.`);
141
+ }
142
+ return value;
143
+ }
144
+ function requireNonEmptyString(value, label, suffix) {
145
+ if (typeof value !== 'string' || value.trim().length === 0) {
146
+ const suffixText = suffix ? ` ${suffix}` : '';
147
+ throw new Error(`${label} must be a non-empty string${suffixText}.`);
148
+ }
149
+ return value;
150
+ }
151
+ function estimateCost(controlPlane, result) {
152
+ const sourceId = result.decision.tool ?? result.route?.sources[0]?.id;
153
+ if (!sourceId)
154
+ return 0;
155
+ return controlPlane.sources.find((source) => source.id === sourceId)?.costPerCall ?? 0;
156
+ }
157
+ function skippedSourcesIncludeTool(skippedSources, tool) {
158
+ return skippedSources.includes(tool) || skippedSources.includes(`source.${tool}`) || skippedSources.includes(`tool.${tool}`);
159
+ }
36
160
  //# sourceMappingURL=preflight.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAyB,MAAM,gBAAgB,CAAC;AAGxE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAyB,EACzB,UAA4B,EAAE;IAE9B,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACtC,MAAM,IAAI,CAAC,WAAW,CAAC;YACrB,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;YAChC,MAAM,EAAE,sBAAsB;YAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM;YAChD,OAAO,EAAE,WAAW,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC5C,KAAK,EAAE,MAAM;YACb,UAAU,EAAE,GAAG;YACf,IAAI,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;SAClE,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,CAAC,SAAS,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC9B,UAAU,EAAE,QAAQ;QACpB,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,sBAAsB;QAC7B,MAAM,EAAE,aAAa,MAAM,CAAC,QAAQ,CAAC,MAAM,QAAQ,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG;QACvG,SAAS,EAAE,GAAG;QACd,KAAK,EAAE;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"preflight.js","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"route-resolver.d.ts","sourceRoot":"","sources":["../src/route-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EAGnB,SAAS,EACT,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,kBAAkB,GAC1B,mBAAmB,CAuBrB;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAc/F;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAMzF;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAMpF"}
1
+ {"version":3,"file":"route-resolver.d.ts","sourceRoot":"","sources":["../src/route-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EAGnB,SAAS,EACT,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,kBAAkB,GAC1B,mBAAmB,CA+BrB;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAe/F;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAMzF;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAMpF"}
@@ -6,13 +6,21 @@ export function resolveSourceRoute(controlPlane, request) {
6
6
  if (!route) {
7
7
  throw new Error(`No source route configured for profile ${normalizedRequest.profile} and intent ${normalizedRequest.intent}.`);
8
8
  }
9
+ const healthBySource = new Map((normalizedRequest.health ?? []).map((health) => [health.sourceId, health]));
10
+ const routeSources = route.sources.map((sourceId) => ensureSource(controlPlane, sourceId));
11
+ const sources = routeSources.filter((source) => healthBySource.get(source.id)?.status !== 'down');
12
+ const skippedSources = routeSources
13
+ .filter((source) => healthBySource.get(source.id)?.status === 'down')
14
+ .map((source) => source.id);
9
15
  return {
10
16
  profile: profile.id,
11
17
  intent: normalizedRequest.intent,
12
- sources: route.sources.map((sourceId) => ensureSource(controlPlane, sourceId)),
18
+ sources,
19
+ skippedSources,
13
20
  guardrails: profile.guardrails,
14
21
  notes: route.notes,
15
- ...resolveFreshness(route.sources.map((sourceId) => ensureSource(controlPlane, sourceId)), normalizedRequest.freshness, normalizedRequest.now)
22
+ blockOnStale: Boolean(route.blockOnStale),
23
+ ...resolveFreshness(sources, normalizedRequest.freshness)
16
24
  };
17
25
  }
18
26
  export function inspectProfile(controlPlane, profileId) {
@@ -25,7 +33,8 @@ export function inspectProfile(controlPlane, profileId) {
25
33
  routes: profile.routes.map((route) => ({
26
34
  intent: route.intent,
27
35
  sources: [...route.sources],
28
- notes: route.notes
36
+ notes: route.notes,
37
+ blockOnStale: route.blockOnStale
29
38
  }))
30
39
  };
31
40
  }
@@ -49,10 +58,36 @@ function normalizeSourceRouteRequest(request) {
49
58
  profile: requireNonEmptyString(record.profile, 'Source route request profile'),
50
59
  intent: requireNonEmptyString(record.intent, 'Source route request intent'),
51
60
  freshness: normalizeFreshness(record.freshness),
52
- now: record.now === undefined ? undefined : requireNonEmptyString(record.now, 'Source route request now')
61
+ health: normalizeHealth(record.health)
53
62
  };
54
63
  }
55
- function resolveFreshness(sources, freshness, nowInput) {
64
+ function normalizeHealth(value) {
65
+ if (value === undefined)
66
+ return undefined;
67
+ if (!Array.isArray(value)) {
68
+ throw new Error('Source route request health must be an array.');
69
+ }
70
+ return value.map((entry) => {
71
+ const record = requireRecord(entry, 'Source health input');
72
+ const status = requireNonEmptyString(record.status, 'Source health status');
73
+ if (!['up', 'down', 'half-open'].includes(status)) {
74
+ throw new Error(`Source health status must be one of: up, down, half-open.`);
75
+ }
76
+ return {
77
+ sourceId: requireNonEmptyString(record.sourceId, 'Source health sourceId'),
78
+ status: status,
79
+ consecutiveFailures: readNonNegativeNumber(record.consecutiveFailures, 'Source health consecutiveFailures'),
80
+ lastChecked: requireNonEmptyString(record.lastChecked, 'Source health lastChecked'),
81
+ lastFailure: record.lastFailure === undefined
82
+ ? undefined
83
+ : requireNonEmptyString(record.lastFailure, 'Source health lastFailure'),
84
+ lastSuccess: record.lastSuccess === undefined
85
+ ? undefined
86
+ : requireNonEmptyString(record.lastSuccess, 'Source health lastSuccess')
87
+ };
88
+ });
89
+ }
90
+ function resolveFreshness(sources, freshness) {
56
91
  if (!freshness || freshness.length === 0) {
57
92
  return {
58
93
  staleSourceIds: [],
@@ -60,7 +95,7 @@ function resolveFreshness(sources, freshness, nowInput) {
60
95
  };
61
96
  }
62
97
  const bySource = new Map(freshness.map((entry) => [entry.sourceId, entry]));
63
- const now = nowInput ? parseTimestamp(nowInput, 'Source route request now') : Date.now();
98
+ const now = Date.now();
64
99
  const statuses = sources
65
100
  .filter((source) => source.freshnessTtl)
66
101
  .map((source) => {
@@ -127,4 +162,10 @@ function requireNonEmptyString(value, label) {
127
162
  }
128
163
  return value;
129
164
  }
165
+ function readNonNegativeNumber(value, label) {
166
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
167
+ throw new Error(`${label} must be a non-negative number.`);
168
+ }
169
+ return value;
170
+ }
130
171
  //# sourceMappingURL=route-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"route-resolver.js","sourceRoot":"","sources":["../src/route-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route-resolver.js","sourceRoot":"","sources":["../src/route-resolver.ts"],"names":[],"mappings":"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"}
package/dist/slo.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { ControlPlane, PreflightResult, SloResult } from './types.js';
2
+ export declare function updateSloCache(controlPlane: ControlPlane, storeDir: string, result: PreflightResult): Promise<void>;
3
+ export declare function calculateSlo(controlPlane: ControlPlane, storeDir: string, profileId: string): Promise<SloResult>;
4
+ //# sourceMappingURL=slo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slo.d.ts","sourceRoot":"","sources":["../src/slo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAa,SAAS,EAAE,MAAM,YAAY,CAAC;AAiBtF,wBAAsB,cAAc,CAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,wBAAsB,YAAY,CAChC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,SAAS,CAAC,CAwDpB"}
package/dist/slo.js ADDED
@@ -0,0 +1,147 @@
1
+ import { readJsonState, writeJsonState } from './store.js';
2
+ export async function updateSloCache(controlPlane, storeDir, result) {
3
+ const profile = controlPlane.profiles.find((candidate) => candidate.id === result.decision.profile);
4
+ if (!profile?.slo)
5
+ return;
6
+ const now = new Date();
7
+ const cache = await readSloCache(storeDir, profile.id);
8
+ const windowStartMs = now.getTime() - profile.slo.windowHours * 60 * 60 * 1000;
9
+ const bucketStart = hourBucket(now);
10
+ const buckets = cache.buckets.filter((bucket) => Date.parse(bucket.bucketStart) >= windowStartMs);
11
+ const bucket = buckets.find((candidate) => candidate.bucketStart === bucketStart);
12
+ const nextBucket = bucket ?? { bucketStart, total: 0, allowed: 0, denied: 0 };
13
+ nextBucket.total += 1;
14
+ if (result.allowed) {
15
+ nextBucket.allowed += 1;
16
+ }
17
+ else {
18
+ nextBucket.denied += 1;
19
+ }
20
+ if (!bucket)
21
+ buckets.push(nextBucket);
22
+ await writeSloCache(storeDir, {
23
+ profile: profile.id,
24
+ metric: profile.slo.metric,
25
+ buckets: buckets.sort((left, right) => left.bucketStart.localeCompare(right.bucketStart)),
26
+ lastUpdated: now.toISOString()
27
+ });
28
+ }
29
+ export async function calculateSlo(controlPlane, storeDir, profileId) {
30
+ const profile = controlPlane.profiles.find((candidate) => candidate.id === profileId);
31
+ if (!profile) {
32
+ throw new Error(`Unknown profile: ${profileId}.`);
33
+ }
34
+ const config = profile.slo ?? {
35
+ target: 1,
36
+ windowHours: 24,
37
+ metric: 'allow_rate'
38
+ };
39
+ const now = new Date();
40
+ const windowStartMs = now.getTime() - config.windowHours * 60 * 60 * 1000;
41
+ const cache = await readSloCache(storeDir, profile.id);
42
+ const bucketWarnings = cache.buckets
43
+ .filter((bucket) => bucket.total !== bucket.allowed + bucket.denied)
44
+ .map((bucket) => `SLO cache bucket ${bucket.bucketStart} has inconsistent totals.`);
45
+ const warnings = [...(cache.warnings ?? []), ...bucketWarnings];
46
+ if (warnings.length > 0) {
47
+ return {
48
+ profile: profile.id,
49
+ target: config.target,
50
+ actual: 0,
51
+ withinBudget: false,
52
+ errorBudgetRemaining: 0,
53
+ totalDecisions: 0,
54
+ allowedCount: 0,
55
+ deniedCount: 0,
56
+ windowStart: new Date(windowStartMs).toISOString(),
57
+ windowEnd: now.toISOString(),
58
+ warnings
59
+ };
60
+ }
61
+ const buckets = cache.buckets.filter((bucket) => Date.parse(bucket.bucketStart) >= windowStartMs);
62
+ const totalDecisions = buckets.reduce((sum, bucket) => sum + bucket.total, 0);
63
+ const allowedCount = buckets.reduce((sum, bucket) => sum + bucket.allowed, 0);
64
+ const deniedCount = buckets.reduce((sum, bucket) => sum + bucket.denied, 0);
65
+ const actual = totalDecisions === 0 ? 1 : allowedCount / totalDecisions;
66
+ const allowedErrorRate = totalDecisions === 0 ? 0 : deniedCount / totalDecisions;
67
+ const errorBudget = 1 - config.target;
68
+ const errorBudgetRemaining = Math.max(0, errorBudget - allowedErrorRate);
69
+ return {
70
+ profile: profile.id,
71
+ target: config.target,
72
+ actual,
73
+ withinBudget: actual >= config.target,
74
+ errorBudgetRemaining,
75
+ totalDecisions,
76
+ allowedCount,
77
+ deniedCount,
78
+ windowStart: new Date(windowStartMs).toISOString(),
79
+ windowEnd: now.toISOString()
80
+ };
81
+ }
82
+ async function readSloCache(storeDir, profile) {
83
+ return readJsonState(storeDir, cachePath(profile), { profile, metric: 'allow_rate', buckets: [], lastUpdated: new Date(0).toISOString() }, parseSloCache);
84
+ }
85
+ async function writeSloCache(storeDir, cache) {
86
+ await writeJsonState(storeDir, cachePath(cache.profile), cache, parseSloCache);
87
+ }
88
+ function cachePath(profile) {
89
+ return `slo-cache/${safeSegment(profile)}.json`;
90
+ }
91
+ function hourBucket(date) {
92
+ const bucket = new Date(date);
93
+ bucket.setUTCMinutes(0, 0, 0);
94
+ return bucket.toISOString();
95
+ }
96
+ function safeSegment(value) {
97
+ if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(value)) {
98
+ throw new Error('SLO profile must be a safe filename segment.');
99
+ }
100
+ return value;
101
+ }
102
+ function parseSloCache(value) {
103
+ const record = requireRecord(value, 'SLO cache');
104
+ const metric = readString(record, 'metric', 'SLO metric');
105
+ if (metric !== 'allow_rate') {
106
+ throw new Error('SLO metric must be allow_rate.');
107
+ }
108
+ return {
109
+ profile: safeSegment(readString(record, 'profile', 'SLO profile')),
110
+ metric,
111
+ buckets: Array.isArray(record.buckets) ? record.buckets.map(parseBucket) : [],
112
+ lastUpdated: readString(record, 'lastUpdated', 'SLO lastUpdated'),
113
+ warnings: Array.isArray(record.warnings)
114
+ ? record.warnings.filter((warning) => typeof warning === 'string')
115
+ : undefined
116
+ };
117
+ }
118
+ function parseBucket(value) {
119
+ const record = requireRecord(value, 'SLO bucket');
120
+ return {
121
+ bucketStart: readString(record, 'bucketStart', 'SLO bucketStart'),
122
+ total: readNumber(record, 'total', 'SLO bucket total'),
123
+ allowed: readNumber(record, 'allowed', 'SLO bucket allowed'),
124
+ denied: readNumber(record, 'denied', 'SLO bucket denied')
125
+ };
126
+ }
127
+ function requireRecord(value, label) {
128
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
129
+ throw new Error(`${label} must be an object.`);
130
+ }
131
+ return value;
132
+ }
133
+ function readString(record, key, label) {
134
+ const value = record[key];
135
+ if (typeof value !== 'string' || value.trim().length === 0) {
136
+ throw new Error(`${label} must be a non-empty string.`);
137
+ }
138
+ return value;
139
+ }
140
+ function readNumber(record, key, label) {
141
+ const value = record[key];
142
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
143
+ throw new Error(`${label} must be a non-negative number.`);
144
+ }
145
+ return value;
146
+ }
147
+ //# sourceMappingURL=slo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slo.js","sourceRoot":"","sources":["../src/slo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAkB3D,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,YAA0B,EAC1B,QAAgB,EAChB,MAAuB;IAEvB,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACpG,IAAI,CAAC,OAAO,EAAE,GAAG;QAAE,OAAO;IAE1B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC/E,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,aAAa,CAAC,CAAC;IAClG,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,KAAK,WAAW,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,MAAM,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC9E,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC;IACtB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;IAC1B,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAEtC,MAAM,aAAa,CAAC,QAAQ,EAAE;QAC5B,OAAO,EAAE,OAAO,CAAC,EAAE;QACnB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM;QAC1B,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACzF,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,YAA0B,EAC1B,QAAgB,EAChB,SAAiB;IAEjB,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IACtF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,SAAS,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI;QAC5B,MAAM,EAAE,CAAC;QACT,WAAW,EAAE,EAAE;QACf,MAAM,EAAE,YAAqB;KAC9B,CAAC;IACF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC1E,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO;SACjC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;SACnE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,oBAAoB,MAAM,CAAC,WAAW,2BAA2B,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,cAAc,CAAC,CAAC;IAEhE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,EAAE;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,CAAC;YACT,YAAY,EAAE,KAAK;YACnB,oBAAoB,EAAE,CAAC;YACvB,cAAc,EAAE,CAAC;YACjB,YAAY,EAAE,CAAC;YACf,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;YAClD,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;YAC5B,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,aAAa,CAAC,CAAC;IAClG,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,cAAc,CAAC;IACxE,MAAM,gBAAgB,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,cAAc,CAAC;IACjF,MAAM,WAAW,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,gBAAgB,CAAC,CAAC;IAEzE,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,EAAE;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM;QACN,YAAY,EAAE,MAAM,IAAI,MAAM,CAAC,MAAM;QACrC,oBAAoB;QACpB,cAAc;QACd,YAAY;QACZ,WAAW;QACX,WAAW,EAAE,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;QAClD,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;KAC7B,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,OAAe;IAC3D,OAAO,aAAa,CAClB,QAAQ,EACR,SAAS,CAAC,OAAO,CAAC,EAClB,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,EACtF,aAAa,CACd,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,KAAe;IAC5D,MAAM,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,SAAS,CAAC,OAAe;IAChC,OAAO,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,IAAU;IAC5B,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC1D,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO;QACL,OAAO,EAAE,WAAW,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;QAClE,MAAM;QACN,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;QAC7E,WAAW,EAAE,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,iBAAiB,CAAC;QACjE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;YACtC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAqB,EAAE,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC;YACrF,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAClD,OAAO;QACL,WAAW,EAAE,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,iBAAiB,CAAC;QACjE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,kBAAkB,CAAC;QACtD,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,oBAAoB,CAAC;QAC5D,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,mBAAmB,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,KAAa;IAClD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qBAAqB,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,KAAgC,CAAC;AAC1C,CAAC;AAED,SAAS,UAAU,CAAC,MAA+B,EAAE,GAAW,EAAE,KAAa;IAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,8BAA8B,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,MAA+B,EAAE,GAAW,EAAE,KAAa;IAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,iCAAiC,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
package/dist/store.d.ts CHANGED
@@ -9,7 +9,17 @@ export declare function appendEvidence(storeDir: string, input: EvidenceInput):
9
9
  export declare function listEvidence(storeDir: string, query?: EvidenceQuery): Promise<EvidenceRecord[]>;
10
10
  export declare function appendChange(storeDir: string, input: ChangeInput): Promise<ChangeRecord>;
11
11
  export declare function listChanges(storeDir: string, query?: ChangeQuery): Promise<ChangeRecord[]>;
12
+ export declare function readJsonState<T extends object>(storeDir: string, relativePath: string, fallback: T, parse: (value: unknown) => T): Promise<T & {
13
+ prevHash: string;
14
+ warnings?: string[];
15
+ }>;
16
+ export declare function writeJsonState<T extends object>(storeDir: string, relativePath: string, payload: T, parse?: (value: unknown) => T): Promise<T & {
17
+ prevHash: string;
18
+ }>;
19
+ export declare function deleteJsonState(storeDir: string, relativePath: string): Promise<void>;
20
+ export declare function listJsonStateFiles(storeDir: string, relativeDir: string): Promise<string[]>;
12
21
  export declare function sanitizeText(value: string, options?: {
13
22
  preserveLineBreaks?: boolean;
14
23
  }): string;
24
+ export declare function detectInjectionWarnings(value: string): string[];
15
25
  //# sourceMappingURL=store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EAEX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EAGf,MAAM,YAAY,CAAC;AAOpB,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIjE;AAED,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI/D;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAiBpG;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAYzG;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAiB9F;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAWpG;AAoDD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAYlG"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EAEX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EAGf,MAAM,YAAY,CAAC;AAYpB,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIjE;AAED,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI/D;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAkBpG;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAYzG;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAgB9F;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAWpG;AAED,wBAAsB,aAAa,CAAC,CAAC,SAAS,MAAM,EAClD,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,GAC3B,OAAO,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAuCxD;AAED,wBAAsB,cAAc,CAAC,CAAC,SAAS,MAAM,EACnD,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,CAAC,EACV,KAAK,GAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAyB,GACnD,OAAO,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAMnC;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3F;AAED,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOjG;AA4GD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CAclG;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/D"}