@lssm/lib.evolution 0.0.0-canary-20251217080011 → 0.0.0-canary-20251219202229
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/LICENSE +21 -0
- package/dist/analyzer/spec-analyzer.d.ts +2 -1
- package/dist/analyzer/spec-analyzer.d.ts.map +1 -0
- package/dist/analyzer/spec-analyzer.js +2 -1
- package/dist/analyzer/spec-analyzer.js.map +1 -0
- package/dist/approval/integration.d.ts +2 -1
- package/dist/approval/integration.d.ts.map +1 -0
- package/dist/approval/integration.js +2 -1
- package/dist/approval/integration.js.map +1 -0
- package/dist/generator/ai-spec-generator.d.ts +2 -1
- package/dist/generator/ai-spec-generator.d.ts.map +1 -0
- package/dist/generator/ai-spec-generator.js +2 -1
- package/dist/generator/ai-spec-generator.js.map +1 -0
- package/dist/generator/spec-generator.d.ts +2 -1
- package/dist/generator/spec-generator.d.ts.map +1 -0
- package/dist/generator/spec-generator.js +2 -1
- package/dist/generator/spec-generator.js.map +1 -0
- package/dist/lifecycle/dist/types/stages.js +2 -1
- package/dist/lifecycle/dist/types/stages.js.map +1 -0
- package/dist/observability/dist/intent/aggregator.js +2 -1
- package/dist/observability/dist/intent/aggregator.js.map +1 -0
- package/dist/observability/dist/lifecycle/dist/types/stages.js +2 -1
- package/dist/observability/dist/lifecycle/dist/types/stages.js.map +1 -0
- package/dist/observability/dist/logging/index.js +2 -1
- package/dist/observability/dist/logging/index.js.map +1 -0
- package/dist/observability/dist/metrics/index.js +2 -1
- package/dist/observability/dist/metrics/index.js.map +1 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -0
- package/package.json +12 -11
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Chaman Ventures, SASU
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-analyzer.d.ts","names":[],"sources":["../../src/analyzer/spec-analyzer.ts"],"sourcesContent":[],"mappings":";;;;;UAciB,mBAAA;WACN;EADM,aAAA,CAAA,EAAA,MAAmB;EAmBvB,kBAAY,CAAA,EAAA,MAAA;EAOF,qBAAA,CAAA,EAAA,MAAA;EAUK,uBAAA,CAAA,EAAA,MAAA;;AAoCjB,cArDE,YAAA,CAqDF;EACI,iBAAA,MAAA;EACV,iBAAA,aAAA;EAsFU,iBAAA,kBAAA;EACJ,iBAAA,qBAAA;EACN,iBAAA,uBAAA;EA8BM,WAAA,CAAA,OAAA,CAAA,EAtKY,mBAsKZ;EACI,gBAAA,CAAA,OAAA,EA7Ja,qBA6Jb,EAAA,CAAA,EA7JuC,cA6JvC,EAAA;EACiB,eAAA,CAAA,KAAA,EA1HrB,cA0HqB,EAAA,EAAA,QAAA,CAAA,EAzHjB,cAyHiB,EAAA,CAAA,EAxH3B,WAwH2B,EAAA;EAC3B,gBAAA,CAAA,SAAA,EAnCU,WAmCV,EAAA,EAAA,KAAA,EAlCM,cAkCN,EAAA,CAAA,EAjCA,aAiCA,EAAA;EAAgB,oBAAA,CAAA,KAAA,EAHV,cAGU,EAAA,EAAA,SAAA,EAFN,WAEM,EAAA,EAAA,iBAAA,EAAA;WADW;MAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-analyzer.js","names":["DEFAULT_OPTIONS: Required<\n Pick<\n SpecAnalyzerOptions,\n 'minSampleSize' | 'errorRateThreshold' | 'latencyP99ThresholdMs'\n >\n>","anomalies: SpecAnomaly[]","evidence: SuggestionEvidence[]","confidence: PatternConfidence","hints: OptimizationHint[]","LIFECYCLE_HINTS: Record<\n StageBand,\n Partial<\n Record<\n OptimizationHint['category'],\n { message: string; supplementalActions: string[] }\n >\n >\n>","ordered: string[]"],"sources":["../../src/analyzer/spec-analyzer.ts"],"sourcesContent":["import { Logger } from '@lssm/lib.observability';\nimport { randomUUID } from 'node:crypto';\nimport { LifecycleStage } from '@lssm/lib.lifecycle';\nimport {\n type IntentPattern,\n type OperationCoordinate,\n type OperationMetricSample,\n type OptimizationHint,\n type PatternConfidence,\n type SpecAnomaly,\n type SpecUsageStats,\n type SuggestionEvidence,\n} from '../types';\n\nexport interface SpecAnalyzerOptions {\n logger?: Logger;\n minSampleSize?: number;\n errorRateThreshold?: number;\n latencyP99ThresholdMs?: number;\n throughputDropThreshold?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<\n Pick<\n SpecAnalyzerOptions,\n 'minSampleSize' | 'errorRateThreshold' | 'latencyP99ThresholdMs'\n >\n> = {\n minSampleSize: 50,\n errorRateThreshold: 0.05,\n latencyP99ThresholdMs: 750,\n};\n\nexport class SpecAnalyzer {\n private readonly logger?: Logger;\n private readonly minSampleSize: number;\n private readonly errorRateThreshold: number;\n private readonly latencyP99ThresholdMs: number;\n private readonly throughputDropThreshold: number;\n\n constructor(options: SpecAnalyzerOptions = {}) {\n this.logger = options.logger;\n this.minSampleSize = options.minSampleSize ?? DEFAULT_OPTIONS.minSampleSize;\n this.errorRateThreshold =\n options.errorRateThreshold ?? DEFAULT_OPTIONS.errorRateThreshold;\n this.latencyP99ThresholdMs =\n options.latencyP99ThresholdMs ?? DEFAULT_OPTIONS.latencyP99ThresholdMs;\n this.throughputDropThreshold = options.throughputDropThreshold ?? 0.2;\n }\n\n analyzeSpecUsage(samples: OperationMetricSample[]): SpecUsageStats[] {\n if (!samples.length) {\n this.logger?.debug('SpecAnalyzer.analyzeSpecUsage.skip', {\n reason: 'no-samples',\n });\n return [];\n }\n\n const groups = new Map<string, OperationMetricSample[]>();\n for (const sample of samples) {\n const key = this.operationKey(sample);\n const arr = groups.get(key) ?? [];\n arr.push(sample);\n groups.set(key, arr);\n }\n\n const entries = [...groups.values()];\n const usable = entries.filter((samplesForOp) => {\n const valid = samplesForOp.length >= this.minSampleSize;\n if (!valid) {\n this.logger?.debug('SpecAnalyzer.analyzeSpecUsage.skipOperation', {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n operation: this.operationKey(samplesForOp[0]!),\n sampleSize: samplesForOp.length,\n minSampleSize: this.minSampleSize,\n });\n }\n return valid;\n });\n\n return usable.map((operationSamples) =>\n this.buildUsageStats(operationSamples)\n );\n }\n\n detectAnomalies(\n stats: SpecUsageStats[],\n baseline?: SpecUsageStats[]\n ): SpecAnomaly[] {\n const anomalies: SpecAnomaly[] = [];\n if (!stats.length) {\n this.logger?.debug('SpecAnalyzer.detectAnomalies.skip', {\n reason: 'no-stats',\n });\n return anomalies;\n }\n const baselineByOp = new Map(\n (baseline ?? []).map((item) => [this.operationKey(item.operation), item])\n );\n\n for (const stat of stats) {\n const evidence: SuggestionEvidence[] = [];\n\n if (stat.errorRate >= this.errorRateThreshold) {\n evidence.push({\n type: 'telemetry',\n description: `Error rate ${stat.errorRate.toFixed(2)} exceeded threshold ${this.errorRateThreshold}`,\n data: { errorRate: stat.errorRate },\n });\n anomalies.push({\n operation: stat.operation,\n severity: this.toSeverity(stat.errorRate / this.errorRateThreshold),\n metric: 'error-rate',\n description: 'Error rate spike',\n detectedAt: new Date(),\n threshold: this.errorRateThreshold,\n observedValue: stat.errorRate,\n evidence,\n });\n continue;\n }\n\n if (stat.p99LatencyMs >= this.latencyP99ThresholdMs) {\n evidence.push({\n type: 'telemetry',\n description: `P99 latency ${stat.p99LatencyMs}ms exceeded threshold ${this.latencyP99ThresholdMs}ms`,\n data: { p99LatencyMs: stat.p99LatencyMs },\n });\n anomalies.push({\n operation: stat.operation,\n severity: this.toSeverity(\n stat.p99LatencyMs / this.latencyP99ThresholdMs\n ),\n metric: 'latency',\n description: 'Latency regression detected',\n detectedAt: new Date(),\n threshold: this.latencyP99ThresholdMs,\n observedValue: stat.p99LatencyMs,\n evidence,\n });\n continue;\n }\n\n const baselineStat = baselineByOp.get(this.operationKey(stat.operation));\n if (baselineStat) {\n const drop =\n (baselineStat.totalCalls - stat.totalCalls) / baselineStat.totalCalls;\n if (drop >= this.throughputDropThreshold) {\n evidence.push({\n type: 'telemetry',\n description: `Throughput dropped by ${(drop * 100).toFixed(1)}% compared to baseline`,\n data: {\n baselineCalls: baselineStat.totalCalls,\n currentCalls: stat.totalCalls,\n },\n });\n anomalies.push({\n operation: stat.operation,\n severity: this.toSeverity(drop / this.throughputDropThreshold),\n metric: 'throughput',\n description: 'Usage drop detected',\n detectedAt: new Date(),\n threshold: this.throughputDropThreshold,\n observedValue: drop,\n evidence,\n });\n }\n }\n }\n\n return anomalies;\n }\n\n toIntentPatterns(\n anomalies: SpecAnomaly[],\n stats: SpecUsageStats[]\n ): IntentPattern[] {\n const statsByOp = new Map(\n stats.map((item) => [this.operationKey(item.operation), item])\n );\n return anomalies.map((anomaly) => {\n const stat = statsByOp.get(this.operationKey(anomaly.operation));\n const confidence: PatternConfidence = {\n score: Math.min(\n 1,\n (anomaly.observedValue ?? 0) / (anomaly.threshold ?? 1)\n ),\n sampleSize: stat?.totalCalls ?? 0,\n pValue: undefined,\n };\n return {\n id: randomUUID(),\n type: this.mapMetricToIntent(anomaly.metric),\n description: anomaly.description,\n operation: anomaly.operation,\n confidence,\n metadata: {\n observedValue: anomaly.observedValue,\n threshold: anomaly.threshold,\n },\n evidence: anomaly.evidence,\n };\n });\n }\n\n suggestOptimizations(\n stats: SpecUsageStats[],\n anomalies: SpecAnomaly[],\n lifecycleContext?: { stage: LifecycleStage }\n ): OptimizationHint[] {\n const anomaliesByOp = new Map<string, SpecAnomaly[]>(\n this.groupByOperation(anomalies)\n );\n const hints: OptimizationHint[] = [];\n\n for (const stat of stats) {\n const opKey = this.operationKey(stat.operation);\n const opAnomalies = anomaliesByOp.get(opKey) ?? [];\n for (const anomaly of opAnomalies) {\n if (anomaly.metric === 'latency') {\n hints.push(\n this.applyLifecycleContext(\n {\n operation: stat.operation,\n category: 'performance',\n summary: 'Latency regression detected',\n justification: `P99 latency at ${stat.p99LatencyMs}ms`,\n recommendedActions: [\n 'Add batching or caching layer',\n 'Replay golden tests to capture slow inputs',\n ],\n },\n lifecycleContext?.stage\n )\n );\n } else if (anomaly.metric === 'error-rate') {\n const topError = Object.entries(stat.topErrors).sort(\n (a, b) => b[1] - a[1]\n )[0]?.[0];\n hints.push(\n this.applyLifecycleContext(\n {\n operation: stat.operation,\n category: 'error-handling',\n summary: 'Error spike detected',\n justification: topError\n ? `Dominant error code ${topError}`\n : 'Increase in failures',\n recommendedActions: [\n 'Generate regression spec from failing payloads',\n 'Add policy guardrails before rollout',\n ],\n },\n lifecycleContext?.stage\n )\n );\n } else if (anomaly.metric === 'throughput') {\n hints.push(\n this.applyLifecycleContext(\n {\n operation: stat.operation,\n category: 'performance',\n summary: 'Throughput drop detected',\n justification:\n 'Significant traffic reduction relative to baseline',\n recommendedActions: [\n 'Validate routing + feature flag bucketing',\n 'Backfill spec variant to rehydrate demand',\n ],\n },\n lifecycleContext?.stage\n )\n );\n }\n }\n }\n return hints;\n }\n\n private operationKey(\n op:\n | OperationCoordinate\n | SpecUsageStats\n | SpecAnomaly\n | OperationMetricSample\n ) {\n const coordinate =\n 'operation' in op ? (op.operation as OperationCoordinate) : op;\n return `${coordinate.name}.v${coordinate.version}${\n coordinate.tenantId ? `@${coordinate.tenantId}` : ''\n }`;\n }\n\n private buildUsageStats(samples: OperationMetricSample[]): SpecUsageStats {\n const durations = samples.map((s) => s.durationMs).sort((a, b) => a - b);\n const errors = samples.filter((s) => !s.success);\n const totalCalls = samples.length;\n const successRate = (totalCalls - errors.length) / totalCalls;\n const errorRate = errors.length / totalCalls;\n const averageLatencyMs =\n durations.reduce((sum, value) => sum + value, 0) / totalCalls;\n\n const topErrors = errors.reduce<Record<string, number>>((acc, sample) => {\n if (!sample.errorCode) return acc;\n acc[sample.errorCode] = (acc[sample.errorCode] ?? 0) + 1;\n return acc;\n }, {});\n\n const timestamps = samples.map((s) => s.timestamp.getTime());\n const windowStart = new Date(Math.min(...timestamps));\n const windowEnd = new Date(Math.max(...timestamps));\n\n return {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n operation: samples[0]!.operation,\n totalCalls,\n successRate,\n errorRate,\n averageLatencyMs,\n p95LatencyMs: percentile(durations, 0.95),\n p99LatencyMs: percentile(durations, 0.99),\n maxLatencyMs: Math.max(...durations),\n lastSeenAt: windowEnd,\n windowStart,\n windowEnd,\n topErrors,\n };\n }\n\n private toSeverity(ratio: number): SpecAnomaly['severity'] {\n if (ratio >= 2) return 'high';\n if (ratio >= 1.3) return 'medium';\n return 'low';\n }\n\n private mapMetricToIntent(\n metric: SpecAnomaly['metric']\n ): IntentPattern['type'] {\n switch (metric) {\n case 'error-rate':\n return 'error-spike';\n case 'latency':\n return 'latency-regression';\n case 'throughput':\n return 'throughput-drop';\n default:\n return 'schema-mismatch';\n }\n }\n\n private groupByOperation<T extends { operation: OperationCoordinate }>(\n items: T[]\n ): Map<string, T[]> {\n const map = new Map<string, T[]>();\n for (const item of items) {\n const key = this.operationKey(item.operation);\n const arr = map.get(key) ?? [];\n arr.push(item);\n map.set(key, arr);\n }\n return map;\n }\n\n private applyLifecycleContext(\n hint: OptimizationHint,\n stage?: LifecycleStage\n ): OptimizationHint {\n if (stage === undefined) return hint;\n const band = mapStageBand(stage);\n const advice = LIFECYCLE_HINTS[band]?.[hint.category];\n if (!advice) {\n return { ...hint, lifecycleStage: stage };\n }\n return {\n ...hint,\n lifecycleStage: stage,\n lifecycleNotes: advice.message,\n recommendedActions: dedupeActions([\n ...hint.recommendedActions,\n ...advice.supplementalActions,\n ]),\n };\n }\n}\n\nfunction percentile(values: number[], p: number): number {\n if (!values.length) return 0;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (values.length === 1) return values[0]!;\n const idx = Math.min(values.length - 1, Math.floor(p * values.length));\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return values[idx]!;\n}\n\ntype StageBand = 'early' | 'pmf' | 'scale' | 'mature';\n\nconst mapStageBand = (stage: LifecycleStage): StageBand => {\n if (stage <= 2) return 'early';\n if (stage === LifecycleStage.ProductMarketFit) return 'pmf';\n if (\n stage === LifecycleStage.GrowthScaleUp ||\n stage === LifecycleStage.ExpansionPlatform\n ) {\n return 'scale';\n }\n return 'mature';\n};\n\nconst LIFECYCLE_HINTS: Record<\n StageBand,\n Partial<\n Record<\n OptimizationHint['category'],\n { message: string; supplementalActions: string[] }\n >\n >\n> = {\n early: {\n performance: {\n message:\n 'Favor guardrails that protect learning velocity before heavy rewrites.',\n supplementalActions: [\n 'Wrap risky changes behind progressive delivery flags',\n ],\n },\n 'error-handling': {\n message: 'Make failures loud and recoverable so you can learn faster.',\n supplementalActions: ['Add auto-rollbacks or manual kill switches'],\n },\n },\n pmf: {\n performance: {\n message:\n 'Stabilize the core use case to avoid regressions while demand grows.',\n supplementalActions: ['Instrument regression tests on critical specs'],\n },\n },\n scale: {\n performance: {\n message:\n 'Prioritize resilience and multi-tenant safety as volumes expand.',\n supplementalActions: [\n 'Introduce workload partitioning or isolation per tenant',\n ],\n },\n 'error-handling': {\n message:\n 'Contain blast radius with policy fallbacks and circuit breakers.',\n supplementalActions: ['Add circuit breakers to high-risk operations'],\n },\n },\n mature: {\n performance: {\n message: 'Optimize for margins and predictable SLAs.',\n supplementalActions: [\n 'Capture unit-cost impacts alongside latency fixes',\n ],\n },\n 'error-handling': {\n message:\n 'Prevent regressions with automated regression specs before deploy.',\n supplementalActions: [\n 'Run auto-evolution simulations on renewal scenarios',\n ],\n },\n },\n};\n\nconst dedupeActions = (actions: string[]): string[] => {\n const seen = new Set<string>();\n const ordered: string[] = [];\n for (const action of actions) {\n if (seen.has(action)) continue;\n seen.add(action);\n ordered.push(action);\n }\n return ordered;\n};\n"],"mappings":"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"}
|
|
@@ -39,4 +39,5 @@ declare class InMemorySpecSuggestionRepository implements SpecSuggestionReposito
|
|
|
39
39
|
list(filters?: SpecSuggestionFilters): Promise<SpecSuggestion[]>;
|
|
40
40
|
}
|
|
41
41
|
//#endregion
|
|
42
|
-
export { FileSystemSuggestionWriter, FileSystemSuggestionWriterOptions, InMemorySpecSuggestionRepository, SpecSuggestionOrchestrator, SpecSuggestionOrchestratorOptions };
|
|
42
|
+
export { FileSystemSuggestionWriter, FileSystemSuggestionWriterOptions, InMemorySpecSuggestionRepository, SpecSuggestionOrchestrator, SpecSuggestionOrchestratorOptions };
|
|
43
|
+
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.d.ts","names":[],"sources":["../../src/approval/integration.ts"],"sourcesContent":[],"mappings":";;;;;UAYiB,iCAAA;cACH;EADG,QAAA,CAAA,EAEJ,gBAFI;EACH,MAAA,CAAA,EAEH,oBAFG;;AAEH,cAGE,0BAAA,CAHF;EAAoB,iBAAA,OAAA;EAGlB,WAAA,CAAA,OAAA,EAC2B,iCADD;EACC,MAAA,CAAA,UAAA,EAGxB,cAHwB,EAAA,OAAA,CAAA,EAI1B,iBAJ0B,EAAA,cAAA,CAAA,EAAA,MAAA,CAAA,EAKb,OALa,CAKb,cALa,CAAA;EAGxB,OAAA,CAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,KAAA,CAAA,EAAA,MAAA,CAAA,EAqB4C,OArB5C,CAAA,IAAA,CAAA;EACF,MAAA,CAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,KAAA,CAAA,EAAA,MAAA,CAAA,EAyC6C,OAzC7C,CAAA,IAAA,CAAA;EACa,IAAA,CAAA,OAAA,CAAA,EAgDV,qBAhDU,CAAA,EAgDW,OAhDX,CAgDW,cAhDX,EAAA,CAAA;EAAA,QAAA,gBAAA;;AAwCgC,UAmB1C,iCAAA,CAnB0C;EAQ1C,SAAA,CAAA,EAAA,MAAA;EAAqB,gBAAA,CAAA,EAAA,CAAA,UAAA,EAaJ,cAbI,EAAA,GAAA,MAAA;;AAAA,cAgBzB,0BAAA,YAAsC,oBAhBb,CAAA;EAWrB,iBAAA,SAAA;EAKJ,iBAAA,gBAA2B;EAMjB,WAAA,CAAA,OAAA,CAAA,EAAA,iCAAA;EAUG,KAAA,CAAA,UAAA,EAAA,cAAA,CAAA,EAAiB,OAAjB,CAAA,MAAA,CAAA;;AAhByB,cA0BtC,gCAAA,YAA4C,wBA1BN,CAAA;EAAoB,iBAAA,KAAA;EA0B1D,MAAA,CAAA,UAAA,EAGc,cAHd,CAAA,EAG+B,OAHE,CAAA,IAAA,CAAA;EAGnB,OAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAIE,OAJF,CAIU,cAJV,GAAA,SAAA,CAAA;EAAiB,YAAA,CAAA,EAAA,EAAA,MAAA,EAAA,MAAA,EAUhC,gBAVgC,EAAA,QAWoB,CAXpB,EAAA;IAIP,QAAA,CAAA,EAAA,MAAA;IAAR,KAAA,CAAA,EAAA,MAAA;IAMjB,SAAA,CAAA,EACoD,IADpD;EACoD,CAAA,CAAA,EAC3D,OAD2D,CAAA,IAAA,CAAA;EAC3D,IAAA,CAAA,OAAA,CAAA,EAekB,qBAflB,CAAA,EAeuC,OAfvC,CAeuC,cAfvC,EAAA,CAAA"}
|
|
@@ -122,4 +122,5 @@ function serializeSuggestion(suggestion) {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
//#endregion
|
|
125
|
-
export { FileSystemSuggestionWriter, InMemorySpecSuggestionRepository, SpecSuggestionOrchestrator };
|
|
125
|
+
export { FileSystemSuggestionWriter, InMemorySpecSuggestionRepository, SpecSuggestionOrchestrator };
|
|
126
|
+
//# sourceMappingURL=integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.js","names":["options: SpecSuggestionOrchestratorOptions"],"sources":["../../src/approval/integration.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { ApprovalWorkflow } from '@lssm/lib.ai-agent/approval';\nimport type { AgentSessionState } from '@lssm/lib.ai-agent/types';\nimport {\n type SpecSuggestion,\n type SpecSuggestionFilters,\n type SpecSuggestionRepository,\n type SpecSuggestionWriter,\n type SuggestionStatus,\n} from '../types';\n\nexport interface SpecSuggestionOrchestratorOptions {\n repository: SpecSuggestionRepository;\n approval?: ApprovalWorkflow;\n writer?: SpecSuggestionWriter;\n}\n\nexport class SpecSuggestionOrchestrator {\n constructor(private readonly options: SpecSuggestionOrchestratorOptions) {}\n\n async submit(\n suggestion: SpecSuggestion,\n session?: AgentSessionState,\n approvalReason?: string\n ) {\n await this.options.repository.create(suggestion);\n if (session && this.options.approval) {\n // AI SDK v6: requestApproval takes a single params object\n await this.options.approval.requestApproval({\n sessionId: session.sessionId,\n agentId: session.agentId,\n tenantId: session.tenantId,\n toolName: 'evolution.apply_suggestion',\n toolCallId: suggestion.id,\n toolArgs: { suggestionId: suggestion.id },\n reason: approvalReason ?? suggestion.proposal.summary,\n payload: { suggestionId: suggestion.id },\n });\n }\n return suggestion;\n }\n\n async approve(id: string, reviewer: string, notes?: string) {\n const suggestion = await this.ensureSuggestion(id);\n await this.options.repository.updateStatus(id, 'approved', {\n reviewer,\n notes,\n decidedAt: new Date(),\n });\n if (this.options.writer) {\n await this.options.writer.write({\n ...suggestion,\n status: 'approved',\n approvals: {\n reviewer,\n notes,\n decidedAt: new Date(),\n status: 'approved',\n },\n });\n }\n }\n\n async reject(id: string, reviewer: string, notes?: string) {\n await this.options.repository.updateStatus(id, 'rejected', {\n reviewer,\n notes,\n decidedAt: new Date(),\n });\n }\n\n list(filters?: SpecSuggestionFilters) {\n return this.options.repository.list(filters);\n }\n\n private async ensureSuggestion(id: string) {\n const suggestion = await this.options.repository.getById(id);\n if (!suggestion) throw new Error(`Spec suggestion ${id} not found`);\n return suggestion;\n }\n}\n\nexport interface FileSystemSuggestionWriterOptions {\n outputDir?: string;\n filenameTemplate?: (suggestion: SpecSuggestion) => string;\n}\n\nexport class FileSystemSuggestionWriter implements SpecSuggestionWriter {\n private readonly outputDir: string;\n private readonly filenameTemplate: NonNullable<\n FileSystemSuggestionWriterOptions['filenameTemplate']\n >;\n\n constructor(options: FileSystemSuggestionWriterOptions = {}) {\n this.outputDir =\n options.outputDir ??\n join(process.cwd(), 'packages/libs/contracts/src/generated');\n this.filenameTemplate =\n options.filenameTemplate ??\n ((suggestion) =>\n `${suggestion.target?.name ?? suggestion.intent.id}.v${suggestion.target?.version ?? 'next'}.suggestion.json`);\n }\n\n async write(suggestion: SpecSuggestion): Promise<string> {\n await mkdir(this.outputDir, { recursive: true });\n const filename = this.filenameTemplate(suggestion);\n const filepath = join(this.outputDir, filename);\n const payload = serializeSuggestion(suggestion);\n await writeFile(filepath, JSON.stringify(payload, null, 2));\n return filepath;\n }\n}\n\nexport class InMemorySpecSuggestionRepository implements SpecSuggestionRepository {\n private readonly items = new Map<string, SpecSuggestion>();\n\n async create(suggestion: SpecSuggestion): Promise<void> {\n this.items.set(suggestion.id, suggestion);\n }\n\n async getById(id: string): Promise<SpecSuggestion | undefined> {\n return this.items.get(id);\n }\n\n async updateStatus(\n id: string,\n status: SuggestionStatus,\n metadata?: { reviewer?: string; notes?: string; decidedAt?: Date }\n ): Promise<void> {\n const suggestion = await this.getById(id);\n if (!suggestion) return;\n this.items.set(id, {\n ...suggestion,\n status,\n approvals: {\n reviewer: metadata?.reviewer,\n notes: metadata?.notes,\n decidedAt: metadata?.decidedAt,\n status,\n },\n });\n }\n\n async list(filters?: SpecSuggestionFilters) {\n const values = [...this.items.values()];\n if (!filters) return values;\n return values.filter((item) => {\n if (filters.status && item.status !== filters.status) return false;\n if (filters.operationName && item.target?.name !== filters.operationName)\n return false;\n return true;\n });\n }\n}\n\nfunction serializeSuggestion(suggestion: SpecSuggestion) {\n const { proposal, ...rest } = suggestion;\n const { spec, ...proposalRest } = proposal;\n return {\n ...rest,\n proposal: {\n ...proposalRest,\n specMeta: spec?.meta,\n },\n createdAt: suggestion.createdAt.toISOString(),\n intent: {\n ...suggestion.intent,\n confidence: { ...suggestion.intent.confidence },\n evidence: suggestion.intent.evidence,\n },\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction deserializeSuggestion(payload: unknown): SpecSuggestion | undefined {\n if (!payload || typeof payload !== 'object') return undefined;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const raw = payload as Record<string, any>;\n return {\n ...raw,\n createdAt: raw.createdAt ? new Date(raw.createdAt) : new Date(),\n intent: {\n ...raw.intent,\n confidence: raw.intent?.confidence,\n evidence: raw.intent?.evidence ?? [],\n },\n proposal: {\n ...raw.proposal,\n metadata: {\n ...(raw.proposal?.metadata ?? {}),\n specMeta: raw.proposal?.specMeta,\n },\n },\n } as SpecSuggestion;\n}\n"],"mappings":"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"}
|
|
@@ -52,4 +52,5 @@ declare class AISpecGenerator {
|
|
|
52
52
|
*/
|
|
53
53
|
declare function createAISpecGenerator(config: AISpecGeneratorConfig): AISpecGenerator;
|
|
54
54
|
//#endregion
|
|
55
|
-
export { AISpecGenerator, AISpecGeneratorConfig, createAISpecGenerator };
|
|
55
|
+
export { AISpecGenerator, AISpecGeneratorConfig, createAISpecGenerator };
|
|
56
|
+
//# sourceMappingURL=ai-spec-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-spec-generator.d.ts","names":[],"sources":["../../src/generator/ai-spec-generator.ts"],"sourcesContent":[],"mappings":";;;;;;;AA2CA;AAea,UAfI,qBAAA,CAeW;EAKL;EAmBX,KAAA,EArCH,aAqCG;EAGS;EAER,eAAA,CAAA,EAxCO,eAwCP;EAAR;EAoBQ,YAAA,CAAA,EAAA,MAAA;;;;;;;AA4Lb;cA7Oa,eAAA;;;;uBAKU;;;;6BAmBX;;mBAGS;MAEhB,QAAQ;;;;yBAoBA;;MAER,QAAQ;;;;gCAmByB,iBAAiB,QAAQ;;;;;;;;;iBAuK/C,qBAAA,SACN,wBACP"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-spec-generator.js","names":["results: SpecSuggestion[]","proposal: SpecSuggestionProposal"],"sources":["../../src/generator/ai-spec-generator.ts"],"sourcesContent":["import type { LanguageModel } from 'ai';\nimport { generateText, Output } from 'ai';\nimport * as z from 'zod';\nimport { randomUUID } from 'node:crypto';\nimport type {\n EvolutionConfig,\n IntentPattern,\n SpecSuggestion,\n SpecSuggestionProposal,\n SuggestionStatus,\n} from '../types';\n\n/**\n * Zod schema for AI-generated spec suggestions.\n */\nconst SpecSuggestionProposalSchema = z.object({\n summary: z.string().describe('Brief summary of the proposed change'),\n rationale: z\n .string()\n .describe('Detailed explanation of why this change is needed'),\n changeType: z\n .enum(['new-spec', 'revision', 'policy-update', 'schema-update'])\n .describe('Type of change being proposed'),\n recommendedActions: z\n .array(z.string())\n .describe('List of specific actions to implement the change'),\n estimatedImpact: z\n .enum(['low', 'medium', 'high'])\n .describe('Estimated impact of implementing this change'),\n riskLevel: z\n .enum(['low', 'medium', 'high'])\n .describe('Risk level associated with this change'),\n diff: z\n .string()\n .optional()\n .describe('Optional diff or code snippet showing the change'),\n});\n\ntype AIGeneratedProposal = z.infer<typeof SpecSuggestionProposalSchema>;\n\n/**\n * Configuration for the AI-powered spec generator.\n */\nexport interface AISpecGeneratorConfig {\n /** AI SDK language model */\n model: LanguageModel;\n /** Evolution configuration */\n evolutionConfig?: EvolutionConfig;\n /** Custom system prompt */\n systemPrompt?: string;\n}\n\n/**\n * AI-powered spec generator using AI SDK v6.\n *\n * Uses structured output (Output.object) to generate\n * well-formed spec suggestions from intent patterns.\n */\nexport class AISpecGenerator {\n private readonly model: LanguageModel;\n private readonly config: EvolutionConfig;\n private readonly systemPrompt: string;\n\n constructor(options: AISpecGeneratorConfig) {\n this.model = options.model;\n this.config = options.evolutionConfig ?? {};\n this.systemPrompt =\n options.systemPrompt ??\n `You are a ContractSpec evolution expert. Your role is to analyze telemetry data, anomalies, and usage patterns to suggest improvements to API contracts and specifications.\n\nWhen generating suggestions:\n1. Be specific and actionable\n2. Consider backwards compatibility\n3. Prioritize stability and reliability\n4. Explain the rationale clearly\n5. Estimate impact and risk accurately`;\n }\n\n /**\n * Generate a spec suggestion from an intent pattern using AI.\n */\n async generateFromIntent(\n intent: IntentPattern,\n options: {\n additionalContext?: string;\n existingSpec?: Record<string, unknown>;\n } = {}\n ): Promise<SpecSuggestion> {\n const prompt = this.buildPrompt(intent, options);\n\n // AI SDK v6: Output.object() only takes { schema }\n const { output } = await generateText({\n model: this.model,\n system: this.systemPrompt,\n prompt,\n output: Output.object({\n schema: SpecSuggestionProposalSchema,\n }),\n });\n\n return this.buildSuggestion(intent, output);\n }\n\n /**\n * Generate multiple suggestions for a batch of intents.\n */\n async generateBatch(\n intents: IntentPattern[],\n options: { maxConcurrent?: number } = {}\n ): Promise<SpecSuggestion[]> {\n const maxConcurrent = options.maxConcurrent ?? 3;\n const results: SpecSuggestion[] = [];\n\n // Process in batches to avoid overwhelming the API\n for (let i = 0; i < intents.length; i += maxConcurrent) {\n const batch = intents.slice(i, i + maxConcurrent);\n const batchResults = await Promise.all(\n batch.map((intent) => this.generateFromIntent(intent))\n );\n results.push(...batchResults);\n }\n\n return results;\n }\n\n /**\n * Validate and enhance an existing suggestion using AI.\n */\n async enhanceSuggestion(suggestion: SpecSuggestion): Promise<SpecSuggestion> {\n const prompt = `Review and enhance this spec suggestion:\n\nIntent: ${suggestion.intent.type} - ${suggestion.intent.description}\nCurrent Summary: ${suggestion.proposal.summary}\nCurrent Rationale: ${suggestion.proposal.rationale}\n\nEvidence:\n${suggestion.evidence.map((e) => `- ${e.type}: ${e.description}`).join('\\n')}\n\nPlease provide an improved version with more specific recommendations.`;\n\n // AI SDK v6: Output.object() only takes { schema }\n const { output } = await generateText({\n model: this.model,\n system: this.systemPrompt,\n prompt,\n output: Output.object({\n schema: SpecSuggestionProposalSchema,\n }),\n });\n\n return {\n ...suggestion,\n proposal: {\n ...suggestion.proposal,\n summary: output.summary,\n rationale: output.rationale,\n changeType: output.changeType,\n diff: output.diff,\n metadata: {\n ...suggestion.proposal.metadata,\n aiEnhanced: true,\n recommendedActions: output.recommendedActions,\n estimatedImpact: output.estimatedImpact,\n riskLevel: output.riskLevel,\n },\n },\n };\n }\n\n private buildPrompt(\n intent: IntentPattern,\n options: {\n additionalContext?: string;\n existingSpec?: Record<string, unknown>;\n }\n ): string {\n const parts = [\n `Analyze this intent pattern and generate a spec suggestion:`,\n ``,\n `Intent Type: ${intent.type}`,\n `Description: ${intent.description}`,\n `Confidence: ${(intent.confidence.score * 100).toFixed(0)}% (sample size: ${intent.confidence.sampleSize})`,\n ];\n\n if (intent.operation) {\n parts.push(\n `Operation: ${intent.operation.name} v${intent.operation.version}`\n );\n }\n\n if (intent.evidence.length > 0) {\n parts.push(``, `Evidence:`);\n for (const evidence of intent.evidence) {\n parts.push(`- [${evidence.type}] ${evidence.description}`);\n }\n }\n\n if (intent.metadata) {\n parts.push(``, `Metadata: ${JSON.stringify(intent.metadata, null, 2)}`);\n }\n\n if (options.existingSpec) {\n parts.push(\n ``,\n `Existing Spec:`,\n '```json',\n JSON.stringify(options.existingSpec, null, 2),\n '```'\n );\n }\n\n if (options.additionalContext) {\n parts.push(``, `Additional Context:`, options.additionalContext);\n }\n\n return parts.join('\\n');\n }\n\n private buildSuggestion(\n intent: IntentPattern,\n aiOutput: AIGeneratedProposal\n ): SpecSuggestion {\n const now = new Date();\n\n const proposal: SpecSuggestionProposal = {\n summary: aiOutput.summary,\n rationale: aiOutput.rationale,\n changeType: aiOutput.changeType,\n diff: aiOutput.diff,\n metadata: {\n aiGenerated: true,\n recommendedActions: aiOutput.recommendedActions,\n estimatedImpact: aiOutput.estimatedImpact,\n riskLevel: aiOutput.riskLevel,\n },\n };\n\n return {\n id: randomUUID(),\n intent,\n target: intent.operation,\n proposal,\n confidence: intent.confidence.score,\n priority: this.calculatePriority(intent, aiOutput),\n createdAt: now,\n createdBy: 'ai-spec-generator',\n status: this.determineInitialStatus(intent),\n evidence: intent.evidence,\n tags: ['ai-generated', intent.type],\n };\n }\n\n private calculatePriority(\n intent: IntentPattern,\n aiOutput: AIGeneratedProposal\n ): 'low' | 'medium' | 'high' {\n // Combine AI assessment with intent severity\n const impactScore =\n aiOutput.estimatedImpact === 'high'\n ? 1\n : aiOutput.estimatedImpact === 'medium'\n ? 0.5\n : 0.25;\n\n const intentScore = intent.confidence.score;\n const urgency =\n intent.type === 'error-spike'\n ? 0.3\n : intent.type === 'latency-regression'\n ? 0.2\n : 0;\n\n const combined = impactScore * 0.4 + intentScore * 0.4 + urgency;\n\n if (combined >= 0.7) return 'high';\n if (combined >= 0.4) return 'medium';\n return 'low';\n }\n\n private determineInitialStatus(intent: IntentPattern): SuggestionStatus {\n // Auto-approve high-confidence, low-risk suggestions if configured\n if (\n this.config.autoApproveThreshold &&\n intent.confidence.score >= this.config.autoApproveThreshold &&\n !this.config.requireApproval\n ) {\n return 'approved';\n }\n return 'pending';\n }\n}\n\n/**\n * Create an AI-powered spec generator.\n */\nexport function createAISpecGenerator(\n config: AISpecGeneratorConfig\n): AISpecGenerator {\n return new AISpecGenerator(config);\n}\n"],"mappings":";;;;;;;;AAeA,MAAM,+BAA+B,EAAE,OAAO;CAC5C,SAAS,EAAE,QAAQ,CAAC,SAAS,uCAAuC;CACpE,WAAW,EACR,QAAQ,CACR,SAAS,oDAAoD;CAChE,YAAY,EACT,KAAK;EAAC;EAAY;EAAY;EAAiB;EAAgB,CAAC,CAChE,SAAS,gCAAgC;CAC5C,oBAAoB,EACjB,MAAM,EAAE,QAAQ,CAAC,CACjB,SAAS,mDAAmD;CAC/D,iBAAiB,EACd,KAAK;EAAC;EAAO;EAAU;EAAO,CAAC,CAC/B,SAAS,+CAA+C;CAC3D,WAAW,EACR,KAAK;EAAC;EAAO;EAAU;EAAO,CAAC,CAC/B,SAAS,yCAAyC;CACrD,MAAM,EACH,QAAQ,CACR,UAAU,CACV,SAAS,mDAAmD;CAChE,CAAC;;;;;;;AAsBF,IAAa,kBAAb,MAA6B;CAC3B,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,SAAgC;AAC1C,OAAK,QAAQ,QAAQ;AACrB,OAAK,SAAS,QAAQ,mBAAmB,EAAE;AAC3C,OAAK,eACH,QAAQ,gBACR;;;;;;;;;;;;CAaJ,MAAM,mBACJ,QACA,UAGI,EAAE,EACmB;EACzB,MAAM,SAAS,KAAK,YAAY,QAAQ,QAAQ;EAGhD,MAAM,EAAE,WAAW,MAAM,aAAa;GACpC,OAAO,KAAK;GACZ,QAAQ,KAAK;GACb;GACA,QAAQ,OAAO,OAAO,EACpB,QAAQ,8BACT,CAAC;GACH,CAAC;AAEF,SAAO,KAAK,gBAAgB,QAAQ,OAAO;;;;;CAM7C,MAAM,cACJ,SACA,UAAsC,EAAE,EACb;EAC3B,MAAM,gBAAgB,QAAQ,iBAAiB;EAC/C,MAAMA,UAA4B,EAAE;AAGpC,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,eAAe;GACtD,MAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI,cAAc;GACjD,MAAM,eAAe,MAAM,QAAQ,IACjC,MAAM,KAAK,WAAW,KAAK,mBAAmB,OAAO,CAAC,CACvD;AACD,WAAQ,KAAK,GAAG,aAAa;;AAG/B,SAAO;;;;;CAMT,MAAM,kBAAkB,YAAqD;EAC3E,MAAM,SAAS;;UAET,WAAW,OAAO,KAAK,KAAK,WAAW,OAAO,YAAY;mBACjD,WAAW,SAAS,QAAQ;qBAC1B,WAAW,SAAS,UAAU;;;EAGjD,WAAW,SAAS,KAAK,MAAM,KAAK,EAAE,KAAK,IAAI,EAAE,cAAc,CAAC,KAAK,KAAK,CAAC;;;EAKzE,MAAM,EAAE,WAAW,MAAM,aAAa;GACpC,OAAO,KAAK;GACZ,QAAQ,KAAK;GACb;GACA,QAAQ,OAAO,OAAO,EACpB,QAAQ,8BACT,CAAC;GACH,CAAC;AAEF,SAAO;GACL,GAAG;GACH,UAAU;IACR,GAAG,WAAW;IACd,SAAS,OAAO;IAChB,WAAW,OAAO;IAClB,YAAY,OAAO;IACnB,MAAM,OAAO;IACb,UAAU;KACR,GAAG,WAAW,SAAS;KACvB,YAAY;KACZ,oBAAoB,OAAO;KAC3B,iBAAiB,OAAO;KACxB,WAAW,OAAO;KACnB;IACF;GACF;;CAGH,AAAQ,YACN,QACA,SAIQ;EACR,MAAM,QAAQ;GACZ;GACA;GACA,gBAAgB,OAAO;GACvB,gBAAgB,OAAO;GACvB,gBAAgB,OAAO,WAAW,QAAQ,KAAK,QAAQ,EAAE,CAAC,kBAAkB,OAAO,WAAW,WAAW;GAC1G;AAED,MAAI,OAAO,UACT,OAAM,KACJ,cAAc,OAAO,UAAU,KAAK,IAAI,OAAO,UAAU,UAC1D;AAGH,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,SAAM,KAAK,IAAI,YAAY;AAC3B,QAAK,MAAM,YAAY,OAAO,SAC5B,OAAM,KAAK,MAAM,SAAS,KAAK,IAAI,SAAS,cAAc;;AAI9D,MAAI,OAAO,SACT,OAAM,KAAK,IAAI,aAAa,KAAK,UAAU,OAAO,UAAU,MAAM,EAAE,GAAG;AAGzE,MAAI,QAAQ,aACV,OAAM,KACJ,IACA,kBACA,WACA,KAAK,UAAU,QAAQ,cAAc,MAAM,EAAE,EAC7C,MACD;AAGH,MAAI,QAAQ,kBACV,OAAM,KAAK,IAAI,uBAAuB,QAAQ,kBAAkB;AAGlE,SAAO,MAAM,KAAK,KAAK;;CAGzB,AAAQ,gBACN,QACA,UACgB;EAChB,MAAM,sBAAM,IAAI,MAAM;EAEtB,MAAMC,WAAmC;GACvC,SAAS,SAAS;GAClB,WAAW,SAAS;GACpB,YAAY,SAAS;GACrB,MAAM,SAAS;GACf,UAAU;IACR,aAAa;IACb,oBAAoB,SAAS;IAC7B,iBAAiB,SAAS;IAC1B,WAAW,SAAS;IACrB;GACF;AAED,SAAO;GACL,IAAI,YAAY;GAChB;GACA,QAAQ,OAAO;GACf;GACA,YAAY,OAAO,WAAW;GAC9B,UAAU,KAAK,kBAAkB,QAAQ,SAAS;GAClD,WAAW;GACX,WAAW;GACX,QAAQ,KAAK,uBAAuB,OAAO;GAC3C,UAAU,OAAO;GACjB,MAAM,CAAC,gBAAgB,OAAO,KAAK;GACpC;;CAGH,AAAQ,kBACN,QACA,UAC2B;EAE3B,MAAM,cACJ,SAAS,oBAAoB,SACzB,IACA,SAAS,oBAAoB,WAC3B,KACA;EAER,MAAM,cAAc,OAAO,WAAW;EACtC,MAAM,UACJ,OAAO,SAAS,gBACZ,KACA,OAAO,SAAS,uBACd,KACA;EAER,MAAM,WAAW,cAAc,KAAM,cAAc,KAAM;AAEzD,MAAI,YAAY,GAAK,QAAO;AAC5B,MAAI,YAAY,GAAK,QAAO;AAC5B,SAAO;;CAGT,AAAQ,uBAAuB,QAAyC;AAEtE,MACE,KAAK,OAAO,wBACZ,OAAO,WAAW,SAAS,KAAK,OAAO,wBACvC,CAAC,KAAK,OAAO,gBAEb,QAAO;AAET,SAAO;;;;;;AAOX,SAAgB,sBACd,QACiB;AACjB,QAAO,IAAI,gBAAgB,OAAO"}
|
|
@@ -43,4 +43,5 @@ declare class SpecGenerator {
|
|
|
43
43
|
private inferChangeType;
|
|
44
44
|
}
|
|
45
45
|
//#endregion
|
|
46
|
-
export { GenerateSpecOptions, SpecGenerator, SpecGeneratorOptions, SpecPatch };
|
|
46
|
+
export { GenerateSpecOptions, SpecGenerator, SpecGeneratorOptions, SpecPatch };
|
|
47
|
+
//# sourceMappingURL=spec-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-generator.d.ts","names":[],"sources":["../../src/generator/spec-generator.ts"],"sourcesContent":[],"mappings":";;;;;;KAaK,WAAA,GAAc,aACjB,gBACA,iBAAiB;UAGF,oBAAA;EALZ,MAAA,CAAA,EAMM,eANK;EACd,MAAA,CAAA,EAMS,MANT;EACA,KAAA,CAAA,EAAA,GAAA,GAMc,IANd;EAAiB,OAAA,CAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,GAO6B,WAP7B,GAAA,SAAA;;AAFY,UAYd,mBAAA,CAZc;EAKd,OAAA,CAAA,EAAA,MAAA;EACN,SAAA,CAAA,EAAA,MAAA;EACA,UAAA,CAAA,EAQI,sBARJ,CAAA,YAAA,CAAA;EACK,IAAA,CAAA,EAQP,sBARO,CAAA,MAAA,CAAA;EACgC,IAAA,CAAA,EAQvC,WARuC;EAAW,IAAA,CAAA,EAAA,MAAA;EAG1C,QAAA,CAAA,EAOJ,MAPI,CAAA,MAAmB,EAAA,OAAA,CAAA;EAGrB,MAAA,CAAA,EAKJ,gBALI;EACN,IAAA,CAAA,EAAA,MAAA,EAAA;EACA,SAAA,CAAA,EAAA,MAAA;;AAGE,KAKC,SAAA,GAAY,OALb,CAMT,YANS,CAMI,cANJ,EAMoB,cANpB,GAMqC,qBANrC,CAAA,OAAA,CAAA,CAAA,CAAA,GAAA;EAAgB,IAAA,CAAA,EAOd,OAPc,CAON,WAPM,CAAA,MAAA,CAAA,CAAA;AAK3B,CAAA;AACe,cAGF,aAAA,CAHE;EAAgB,iBAAA,MAAA;EAAiB,iBAAA,MAAA;EAA9C,iBAAA,KAAA;EADsB,iBAAA,OAAA;EAEH,WAAA,CAAA,OAAA,CAAA,EAQE,oBARF;EAAR,kBAAA,CAAA,MAAA,EAgBD,aAhBC,EAAA,OAAA,CAAA,EAiBA,mBAjBA,CAAA,EAkBR,cAlBQ;EAAO,eAAA,CAAA,SAAA,EA2DL,mBA3DK,EAAA,KAAA,EA4DT,SA5DS,EAAA,MAAA,EA6DR,aA7DQ,EAAA,OAAA,CAAA,EA8DP,IA9DO,CA8DF,mBA9DE,EAAA,MAAA,CAAA,CAAA,EA8D+B,cA9D/B;EAEP,kBAAa,CAAA,UAAA,EA4EV,cA5EU,EAAA,MAAA,CAAA,EA6Ed,eA7Ec,CAAA,EAAA;IAMH,EAAA,EAAA,OAAA;IAQX,OAAA,EAAA,MAAA,EAAA;EACC,CAAA;EACR,QAAA,YAAA;EAyCU,QAAA,gBAAA;EACJ,QAAA,eAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-generator.js","names":["reasons: string[]"],"sources":["../../src/generator/spec-generator.ts"],"sourcesContent":["import type { ContractSpec, ResourceRefDescriptor } from '@lssm/lib.contracts';\nimport type { AnySchemaModel } from '@lssm/lib.schema';\nimport { Logger } from '@lssm/lib.observability';\nimport { randomUUID } from 'node:crypto';\nimport {\n type EvolutionConfig,\n type IntentPattern,\n type OperationCoordinate,\n type SpecSuggestion,\n type SpecSuggestionProposal,\n type SuggestionStatus,\n} from '../types';\n\ntype AnyContract = ContractSpec<\n AnySchemaModel,\n AnySchemaModel | ResourceRefDescriptor<boolean>\n>;\n\nexport interface SpecGeneratorOptions {\n config?: EvolutionConfig;\n logger?: Logger;\n clock?: () => Date;\n getSpec?: (name: string, version?: number) => AnyContract | undefined;\n}\n\nexport interface GenerateSpecOptions {\n summary?: string;\n rationale?: string;\n changeType?: SpecSuggestionProposal['changeType'];\n kind?: SpecSuggestionProposal['kind'];\n spec?: AnyContract;\n diff?: string;\n metadata?: Record<string, unknown>;\n status?: SuggestionStatus;\n tags?: string[];\n createdBy?: string;\n}\n\nexport type SpecPatch = Partial<\n ContractSpec<AnySchemaModel, AnySchemaModel | ResourceRefDescriptor<boolean>>\n> & { meta?: Partial<AnyContract['meta']> };\n\nexport class SpecGenerator {\n private readonly config: EvolutionConfig;\n private readonly logger?: Logger;\n private readonly clock: () => Date;\n private readonly getSpec?: SpecGeneratorOptions['getSpec'];\n\n constructor(options: SpecGeneratorOptions = {}) {\n this.config = options.config ?? {};\n this.logger = options.logger;\n this.clock = options.clock ?? (() => new Date());\n this.getSpec = options.getSpec;\n }\n\n generateFromIntent(\n intent: IntentPattern,\n options: GenerateSpecOptions = {}\n ): SpecSuggestion {\n const now = this.clock();\n const summary =\n options.summary ??\n `${this.intentToVerb(intent.type)} ${intent.operation?.name ?? 'operation'}`;\n const rationale =\n options.rationale ??\n [\n intent.description,\n intent.metadata?.observedValue\n ? `Observed ${intent.metadata.observedValue}`\n : undefined,\n ]\n .filter(Boolean)\n .join(' — ');\n\n const suggestion: SpecSuggestion = {\n id: randomUUID(),\n intent,\n target: intent.operation,\n proposal: {\n summary,\n rationale,\n changeType: options.changeType ?? this.inferChangeType(intent),\n kind: options.kind,\n spec: options.spec,\n diff: options.diff,\n metadata: options.metadata,\n },\n confidence: intent.confidence.score,\n priority: this.intentToPriority(intent),\n createdAt: now,\n createdBy: options.createdBy ?? 'auto-evolution',\n status: options.status ?? 'pending',\n evidence: intent.evidence,\n tags: options.tags,\n };\n return suggestion;\n }\n\n generateVariant(\n operation: OperationCoordinate,\n patch: SpecPatch,\n intent: IntentPattern,\n options: Omit<GenerateSpecOptions, 'spec'> = {}\n ) {\n if (!this.getSpec) {\n throw new Error('SpecGenerator requires getSpec() to generate variants');\n }\n const base = this.getSpec(operation.name, operation.version);\n if (!base) {\n throw new Error(\n `Cannot generate variant; spec ${operation.name}.v${operation.version} not found`\n );\n }\n const merged = mergeContract(base, patch);\n return this.generateFromIntent(intent, { ...options, spec: merged });\n }\n\n validateSuggestion(\n suggestion: SpecSuggestion,\n config: EvolutionConfig = this.config\n ) {\n const reasons: string[] = [];\n if (\n config.minConfidence != null &&\n suggestion.confidence < config.minConfidence\n ) {\n reasons.push(\n `Confidence ${suggestion.confidence.toFixed(2)} below minimum ${config.minConfidence}`\n );\n }\n if (config.requireApproval && suggestion.status === 'approved') {\n reasons.push(\n 'Suggestion cannot be auto-approved when approval is required'\n );\n }\n if (suggestion.proposal.spec && !suggestion.proposal.spec.meta?.name) {\n reasons.push('Proposal spec must include meta.name');\n }\n if (!suggestion.proposal.summary) {\n reasons.push('Proposal summary is required');\n }\n const ok = reasons.length === 0;\n if (!ok) {\n this.logger?.warn('SpecGenerator.validateSuggestion.failed', {\n suggestionId: suggestion.id,\n reasons,\n });\n }\n return { ok, reasons };\n }\n\n private intentToVerb(intent: IntentPattern['type']) {\n switch (intent) {\n case 'error-spike':\n return 'Stabilize';\n case 'latency-regression':\n return 'Optimize';\n case 'missing-operation':\n return 'Introduce';\n case 'throughput-drop':\n return 'Rebalance';\n default:\n return 'Adjust';\n }\n }\n\n private intentToPriority(intent: IntentPattern) {\n const severity = intent.confidence.score;\n if (intent.type === 'error-spike' || severity >= 0.8) return 'high';\n if (severity >= 0.5) return 'medium';\n return 'low';\n }\n\n private inferChangeType(\n intent: IntentPattern\n ): SpecSuggestionProposal['changeType'] {\n switch (intent.type) {\n case 'missing-operation':\n return 'new-spec';\n case 'schema-mismatch':\n return 'schema-update';\n case 'error-spike':\n return 'policy-update';\n default:\n return 'revision';\n }\n }\n}\n\nfunction mergeContract(base: AnyContract, patch: SpecPatch): AnyContract {\n return {\n ...base,\n ...patch,\n meta: { ...base.meta, ...patch.meta },\n io: {\n ...base.io,\n ...patch.io,\n },\n policy: {\n ...base.policy,\n ...patch.policy,\n },\n telemetry: {\n ...base.telemetry,\n ...patch.telemetry,\n },\n sideEffects: {\n ...base.sideEffects,\n ...patch.sideEffects,\n },\n } as AnyContract;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stages.js","names":[],"sources":["../../../../../lifecycle/dist/types/stages.js"],"sourcesContent":["//#region src/types/stages.ts\nlet LifecycleStage = /* @__PURE__ */ function(LifecycleStage$1) {\n\tLifecycleStage$1[LifecycleStage$1[\"Exploration\"] = 0] = \"Exploration\";\n\tLifecycleStage$1[LifecycleStage$1[\"ProblemSolutionFit\"] = 1] = \"ProblemSolutionFit\";\n\tLifecycleStage$1[LifecycleStage$1[\"MvpEarlyTraction\"] = 2] = \"MvpEarlyTraction\";\n\tLifecycleStage$1[LifecycleStage$1[\"ProductMarketFit\"] = 3] = \"ProductMarketFit\";\n\tLifecycleStage$1[LifecycleStage$1[\"GrowthScaleUp\"] = 4] = \"GrowthScaleUp\";\n\tLifecycleStage$1[LifecycleStage$1[\"ExpansionPlatform\"] = 5] = \"ExpansionPlatform\";\n\tLifecycleStage$1[LifecycleStage$1[\"MaturityRenewal\"] = 6] = \"MaturityRenewal\";\n\treturn LifecycleStage$1;\n}({});\nconst LIFECYCLE_STAGE_ORDER = [\n\tLifecycleStage.Exploration,\n\tLifecycleStage.ProblemSolutionFit,\n\tLifecycleStage.MvpEarlyTraction,\n\tLifecycleStage.ProductMarketFit,\n\tLifecycleStage.GrowthScaleUp,\n\tLifecycleStage.ExpansionPlatform,\n\tLifecycleStage.MaturityRenewal\n];\nconst LIFECYCLE_STAGE_META = {\n\t[LifecycleStage.Exploration]: {\n\t\tid: LifecycleStage.Exploration,\n\t\torder: 0,\n\t\tslug: \"exploration\",\n\t\tname: \"Exploration / Ideation\",\n\t\tquestion: \"Is there a problem worth my time?\",\n\t\tsignals: [\n\t\t\t\"20+ discovery interviews\",\n\t\t\t\"Clear problem statement\",\n\t\t\t\"Named ICP\"\n\t\t],\n\t\ttraps: [\"Branding before discovery\", \"Premature tooling decisions\"],\n\t\tfocusAreas: [\n\t\t\t\"Customer discovery\",\n\t\t\t\"Problem definition\",\n\t\t\t\"Segment clarity\"\n\t\t]\n\t},\n\t[LifecycleStage.ProblemSolutionFit]: {\n\t\tid: LifecycleStage.ProblemSolutionFit,\n\t\torder: 1,\n\t\tslug: \"problem-solution-fit\",\n\t\tname: \"Problem–Solution Fit\",\n\t\tquestion: \"Do people care enough about this solution?\",\n\t\tsignals: [\n\t\t\t\"Prototype reuse\",\n\t\t\t\"Referral energy\",\n\t\t\t\"Pre-pay interest\"\n\t\t],\n\t\ttraps: [\"“Market is huge” without users\", \"Skipping qualitative loops\"],\n\t\tfocusAreas: [\n\t\t\t\"Solution hypothesis\",\n\t\t\t\"Value messaging\",\n\t\t\t\"Feedback capture\"\n\t\t]\n\t},\n\t[LifecycleStage.MvpEarlyTraction]: {\n\t\tid: LifecycleStage.MvpEarlyTraction,\n\t\torder: 2,\n\t\tslug: \"mvp-early-traction\",\n\t\tname: \"MVP & Early Traction\",\n\t\tquestion: \"Can we get real usage and learn fast?\",\n\t\tsignals: [\n\t\t\t\"20–50 named active users\",\n\t\t\t\"Weekly releases\",\n\t\t\t\"Noisy feedback\"\n\t\t],\n\t\ttraps: [\"Overbuilt infra for 10 users\", \"Undefined retention metric\"],\n\t\tfocusAreas: [\n\t\t\t\"Activation\",\n\t\t\t\"Cohort tracking\",\n\t\t\t\"Feedback rituals\"\n\t\t]\n\t},\n\t[LifecycleStage.ProductMarketFit]: {\n\t\tid: LifecycleStage.ProductMarketFit,\n\t\torder: 3,\n\t\tslug: \"product-market-fit\",\n\t\tname: \"Product–Market Fit\",\n\t\tquestion: \"Is this pulling us forward?\",\n\t\tsignals: [\n\t\t\t\"Retention without heroics\",\n\t\t\t\"Organic word-of-mouth\",\n\t\t\t\"Value stories\"\n\t\t],\n\t\ttraps: [\"Hero growth that does not scale\", \"Ignoring churn signals\"],\n\t\tfocusAreas: [\n\t\t\t\"Retention\",\n\t\t\t\"Reliability\",\n\t\t\t\"ICP clarity\"\n\t\t]\n\t},\n\t[LifecycleStage.GrowthScaleUp]: {\n\t\tid: LifecycleStage.GrowthScaleUp,\n\t\torder: 4,\n\t\tslug: \"growth-scale-up\",\n\t\tname: \"Growth / Scale-up\",\n\t\tquestion: \"Can we grow this repeatably?\",\n\t\tsignals: [\n\t\t\t\"Predictable channels\",\n\t\t\t\"Specialized hires\",\n\t\t\t\"Unit economics on track\"\n\t\t],\n\t\ttraps: [\"Paid spend masking retention gaps\", \"Infra debt blocking launches\"],\n\t\tfocusAreas: [\n\t\t\t\"Ops systems\",\n\t\t\t\"Growth loops\",\n\t\t\t\"Reliability engineering\"\n\t\t]\n\t},\n\t[LifecycleStage.ExpansionPlatform]: {\n\t\tid: LifecycleStage.ExpansionPlatform,\n\t\torder: 5,\n\t\tslug: \"expansion-platform\",\n\t\tname: \"Expansion / Platform\",\n\t\tquestion: \"What is the next growth curve?\",\n\t\tsignals: [\n\t\t\t\"Stable core metrics\",\n\t\t\t\"Partner/API demand\",\n\t\t\t\"Ecosystem pull\"\n\t\t],\n\t\ttraps: [\"Platform theater before wedge is solid\"],\n\t\tfocusAreas: [\n\t\t\t\"Partnerships\",\n\t\t\t\"APIs\",\n\t\t\t\"New market validation\"\n\t\t]\n\t},\n\t[LifecycleStage.MaturityRenewal]: {\n\t\tid: LifecycleStage.MaturityRenewal,\n\t\torder: 6,\n\t\tslug: \"maturity-renewal\",\n\t\tname: \"Maturity / Renewal\",\n\t\tquestion: \"Optimize, reinvent, or sunset?\",\n\t\tsignals: [\n\t\t\t\"Margin focus\",\n\t\t\t\"Portfolio bets\",\n\t\t\t\"Narrative refresh\"\n\t\t],\n\t\ttraps: [\"Assuming past success is enough\"],\n\t\tfocusAreas: [\n\t\t\t\"Cost optimization\",\n\t\t\t\"Reinvention bets\",\n\t\t\t\"Sunset planning\"\n\t\t]\n\t}\n};\nconst getLifecycleStageBySlug = (slug) => {\n\tconst entry = Object.values(LIFECYCLE_STAGE_META).find((meta) => meta.slug === slug);\n\tif (!entry) throw new Error(`Unknown lifecycle stage slug: ${slug}`);\n\treturn entry.id;\n};\n\n//#endregion\nexport { LIFECYCLE_STAGE_META, LIFECYCLE_STAGE_ORDER, LifecycleStage, getLifecycleStageBySlug };\n//# sourceMappingURL=stages.js.map"],"mappings":";AACA,IAAI,iBAAiC,yBAAS,kBAAkB;AAC/D,kBAAiB,iBAAiB,iBAAiB,KAAK;AACxD,kBAAiB,iBAAiB,wBAAwB,KAAK;AAC/D,kBAAiB,iBAAiB,sBAAsB,KAAK;AAC7D,kBAAiB,iBAAiB,sBAAsB,KAAK;AAC7D,kBAAiB,iBAAiB,mBAAmB,KAAK;AAC1D,kBAAiB,iBAAiB,uBAAuB,KAAK;AAC9D,kBAAiB,iBAAiB,qBAAqB,KAAK;AAC5D,QAAO;EACN,EAAE,CAAC;AACL,MAAM,wBAAwB;CAC7B,eAAe;CACf,eAAe;CACf,eAAe;CACf,eAAe;CACf,eAAe;CACf,eAAe;CACf,eAAe;CACf;AACD,MAAM,uBAAuB;EAC3B,eAAe,cAAc;EAC7B,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,6BAA6B,8BAA8B;EACnE,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,qBAAqB;EACpC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,kCAAkC,6BAA6B;EACvE,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,mBAAmB;EAClC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,gCAAgC,6BAA6B;EACrE,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,mBAAmB;EAClC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,mCAAmC,yBAAyB;EACpE,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,gBAAgB;EAC/B,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,qCAAqC,+BAA+B;EAC5E,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,oBAAoB;EACnC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,yCAAyC;EACjD,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,kBAAkB;EACjC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,kCAAkC;EAC1C,YAAY;GACX;GACA;GACA;GACA;EACD;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregator.js","names":[],"sources":["../../../../../observability/dist/intent/aggregator.mjs"],"sourcesContent":["//#region src/intent/aggregator.ts\nconst DEFAULT_WINDOW_MS = 900 * 1e3;\nvar IntentAggregator = class {\n\twindowMs;\n\tsequenceSampleSize;\n\tsamples = [];\n\tconstructor(options = {}) {\n\t\tthis.windowMs = options.windowMs ?? DEFAULT_WINDOW_MS;\n\t\tthis.sequenceSampleSize = options.sequenceSampleSize ?? 1e3;\n\t}\n\tadd(sample) {\n\t\tthis.samples.push(sample);\n\t}\n\tflush(now = /* @__PURE__ */ new Date()) {\n\t\tconst minTimestamp = now.getTime() - this.windowMs;\n\t\tconst windowSamples = this.samples.filter((sample) => sample.timestamp.getTime() >= minTimestamp);\n\t\tthis.samples.length = 0;\n\t\tconst metrics = this.aggregateMetrics(windowSamples);\n\t\tconst sequences = this.buildSequences(windowSamples);\n\t\tconst timestamps = windowSamples.map((sample) => sample.timestamp.getTime());\n\t\treturn {\n\t\t\tmetrics,\n\t\t\tsequences,\n\t\t\tsampleCount: windowSamples.length,\n\t\t\twindowStart: timestamps.length ? new Date(Math.min(...timestamps)) : void 0,\n\t\t\twindowEnd: timestamps.length ? new Date(Math.max(...timestamps)) : void 0\n\t\t};\n\t}\n\taggregateMetrics(samples) {\n\t\tif (!samples.length) return [];\n\t\tconst groups = /* @__PURE__ */ new Map();\n\t\tfor (const sample of samples) {\n\t\t\tconst key = `${sample.operation.name}.v${sample.operation.version}`;\n\t\t\tconst arr = groups.get(key) ?? [];\n\t\t\tarr.push(sample);\n\t\t\tgroups.set(key, arr);\n\t\t}\n\t\treturn [...groups.values()].map((group) => {\n\t\t\tconst durations = group.map((s) => s.durationMs).sort((a, b) => a - b);\n\t\t\tconst errors = group.filter((s) => !s.success);\n\t\t\tconst totalCalls = group.length;\n\t\t\tconst topErrors = errors.reduce((acc, sample) => {\n\t\t\t\tif (!sample.errorCode) return acc;\n\t\t\t\tacc[sample.errorCode] = (acc[sample.errorCode] ?? 0) + 1;\n\t\t\t\treturn acc;\n\t\t\t}, {});\n\t\t\tconst timestamps = group.map((s) => s.timestamp.getTime());\n\t\t\treturn {\n\t\t\t\toperation: group[0].operation,\n\t\t\t\ttotalCalls,\n\t\t\t\tsuccessRate: (totalCalls - errors.length) / totalCalls,\n\t\t\t\terrorRate: errors.length / totalCalls,\n\t\t\t\taverageLatencyMs: durations.reduce((sum, value) => sum + value, 0) / totalCalls,\n\t\t\t\tp95LatencyMs: percentile(durations, .95),\n\t\t\t\tp99LatencyMs: percentile(durations, .99),\n\t\t\t\tmaxLatencyMs: Math.max(...durations),\n\t\t\t\twindowStart: new Date(Math.min(...timestamps)),\n\t\t\t\twindowEnd: new Date(Math.max(...timestamps)),\n\t\t\t\ttopErrors\n\t\t\t};\n\t\t});\n\t}\n\tbuildSequences(samples) {\n\t\tconst byTrace = /* @__PURE__ */ new Map();\n\t\tfor (const sample of samples.slice(-this.sequenceSampleSize)) {\n\t\t\tif (!sample.traceId) continue;\n\t\t\tconst arr = byTrace.get(sample.traceId) ?? [];\n\t\t\tarr.push(sample);\n\t\t\tbyTrace.set(sample.traceId, arr);\n\t\t}\n\t\tconst sequences = {};\n\t\tfor (const [traceId, events] of byTrace.entries()) {\n\t\t\tconst ordered = events.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n\t\t\tconst steps = ordered.map((event) => event.operation.name);\n\t\t\tif (steps.length < 2) continue;\n\t\t\tconst key = `${steps.join(\">\")}@${ordered[0]?.tenantId ?? \"global\"}`;\n\t\t\tconst existing = sequences[key];\n\t\t\tif (existing) existing.count += 1;\n\t\t\telse sequences[key] = {\n\t\t\t\tsteps,\n\t\t\t\ttenantId: ordered[0]?.tenantId,\n\t\t\t\tcount: 1\n\t\t\t};\n\t\t}\n\t\treturn Object.values(sequences).sort((a, b) => b.count - a.count);\n\t}\n};\nfunction percentile(values, ratio) {\n\tif (!values.length) return 0;\n\tif (values.length === 1) return values[0];\n\treturn values[Math.min(values.length - 1, Math.floor(ratio * values.length))];\n}\n\n//#endregion\nexport { IntentAggregator };\n//# sourceMappingURL=aggregator.mjs.map"],"mappings":";AACA,MAAM,oBAAoB,MAAM"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stages.js","names":[],"sources":["../../../../../../../observability/dist/lifecycle/dist/types/stages.mjs"],"sourcesContent":["//#region ../lifecycle/dist/types/stages.js\nlet LifecycleStage = /* @__PURE__ */ function(LifecycleStage$1) {\n\tLifecycleStage$1[LifecycleStage$1[\"Exploration\"] = 0] = \"Exploration\";\n\tLifecycleStage$1[LifecycleStage$1[\"ProblemSolutionFit\"] = 1] = \"ProblemSolutionFit\";\n\tLifecycleStage$1[LifecycleStage$1[\"MvpEarlyTraction\"] = 2] = \"MvpEarlyTraction\";\n\tLifecycleStage$1[LifecycleStage$1[\"ProductMarketFit\"] = 3] = \"ProductMarketFit\";\n\tLifecycleStage$1[LifecycleStage$1[\"GrowthScaleUp\"] = 4] = \"GrowthScaleUp\";\n\tLifecycleStage$1[LifecycleStage$1[\"ExpansionPlatform\"] = 5] = \"ExpansionPlatform\";\n\tLifecycleStage$1[LifecycleStage$1[\"MaturityRenewal\"] = 6] = \"MaturityRenewal\";\n\treturn LifecycleStage$1;\n}({});\nconst LIFECYCLE_STAGE_ORDER = [\n\tLifecycleStage.Exploration,\n\tLifecycleStage.ProblemSolutionFit,\n\tLifecycleStage.MvpEarlyTraction,\n\tLifecycleStage.ProductMarketFit,\n\tLifecycleStage.GrowthScaleUp,\n\tLifecycleStage.ExpansionPlatform,\n\tLifecycleStage.MaturityRenewal\n];\nconst LIFECYCLE_STAGE_META = {\n\t[LifecycleStage.Exploration]: {\n\t\tid: LifecycleStage.Exploration,\n\t\torder: 0,\n\t\tslug: \"exploration\",\n\t\tname: \"Exploration / Ideation\",\n\t\tquestion: \"Is there a problem worth my time?\",\n\t\tsignals: [\n\t\t\t\"20+ discovery interviews\",\n\t\t\t\"Clear problem statement\",\n\t\t\t\"Named ICP\"\n\t\t],\n\t\ttraps: [\"Branding before discovery\", \"Premature tooling decisions\"],\n\t\tfocusAreas: [\n\t\t\t\"Customer discovery\",\n\t\t\t\"Problem definition\",\n\t\t\t\"Segment clarity\"\n\t\t]\n\t},\n\t[LifecycleStage.ProblemSolutionFit]: {\n\t\tid: LifecycleStage.ProblemSolutionFit,\n\t\torder: 1,\n\t\tslug: \"problem-solution-fit\",\n\t\tname: \"Problem–Solution Fit\",\n\t\tquestion: \"Do people care enough about this solution?\",\n\t\tsignals: [\n\t\t\t\"Prototype reuse\",\n\t\t\t\"Referral energy\",\n\t\t\t\"Pre-pay interest\"\n\t\t],\n\t\ttraps: [\"“Market is huge” without users\", \"Skipping qualitative loops\"],\n\t\tfocusAreas: [\n\t\t\t\"Solution hypothesis\",\n\t\t\t\"Value messaging\",\n\t\t\t\"Feedback capture\"\n\t\t]\n\t},\n\t[LifecycleStage.MvpEarlyTraction]: {\n\t\tid: LifecycleStage.MvpEarlyTraction,\n\t\torder: 2,\n\t\tslug: \"mvp-early-traction\",\n\t\tname: \"MVP & Early Traction\",\n\t\tquestion: \"Can we get real usage and learn fast?\",\n\t\tsignals: [\n\t\t\t\"20–50 named active users\",\n\t\t\t\"Weekly releases\",\n\t\t\t\"Noisy feedback\"\n\t\t],\n\t\ttraps: [\"Overbuilt infra for 10 users\", \"Undefined retention metric\"],\n\t\tfocusAreas: [\n\t\t\t\"Activation\",\n\t\t\t\"Cohort tracking\",\n\t\t\t\"Feedback rituals\"\n\t\t]\n\t},\n\t[LifecycleStage.ProductMarketFit]: {\n\t\tid: LifecycleStage.ProductMarketFit,\n\t\torder: 3,\n\t\tslug: \"product-market-fit\",\n\t\tname: \"Product–Market Fit\",\n\t\tquestion: \"Is this pulling us forward?\",\n\t\tsignals: [\n\t\t\t\"Retention without heroics\",\n\t\t\t\"Organic word-of-mouth\",\n\t\t\t\"Value stories\"\n\t\t],\n\t\ttraps: [\"Hero growth that does not scale\", \"Ignoring churn signals\"],\n\t\tfocusAreas: [\n\t\t\t\"Retention\",\n\t\t\t\"Reliability\",\n\t\t\t\"ICP clarity\"\n\t\t]\n\t},\n\t[LifecycleStage.GrowthScaleUp]: {\n\t\tid: LifecycleStage.GrowthScaleUp,\n\t\torder: 4,\n\t\tslug: \"growth-scale-up\",\n\t\tname: \"Growth / Scale-up\",\n\t\tquestion: \"Can we grow this repeatably?\",\n\t\tsignals: [\n\t\t\t\"Predictable channels\",\n\t\t\t\"Specialized hires\",\n\t\t\t\"Unit economics on track\"\n\t\t],\n\t\ttraps: [\"Paid spend masking retention gaps\", \"Infra debt blocking launches\"],\n\t\tfocusAreas: [\n\t\t\t\"Ops systems\",\n\t\t\t\"Growth loops\",\n\t\t\t\"Reliability engineering\"\n\t\t]\n\t},\n\t[LifecycleStage.ExpansionPlatform]: {\n\t\tid: LifecycleStage.ExpansionPlatform,\n\t\torder: 5,\n\t\tslug: \"expansion-platform\",\n\t\tname: \"Expansion / Platform\",\n\t\tquestion: \"What is the next growth curve?\",\n\t\tsignals: [\n\t\t\t\"Stable core metrics\",\n\t\t\t\"Partner/API demand\",\n\t\t\t\"Ecosystem pull\"\n\t\t],\n\t\ttraps: [\"Platform theater before wedge is solid\"],\n\t\tfocusAreas: [\n\t\t\t\"Partnerships\",\n\t\t\t\"APIs\",\n\t\t\t\"New market validation\"\n\t\t]\n\t},\n\t[LifecycleStage.MaturityRenewal]: {\n\t\tid: LifecycleStage.MaturityRenewal,\n\t\torder: 6,\n\t\tslug: \"maturity-renewal\",\n\t\tname: \"Maturity / Renewal\",\n\t\tquestion: \"Optimize, reinvent, or sunset?\",\n\t\tsignals: [\n\t\t\t\"Margin focus\",\n\t\t\t\"Portfolio bets\",\n\t\t\t\"Narrative refresh\"\n\t\t],\n\t\ttraps: [\"Assuming past success is enough\"],\n\t\tfocusAreas: [\n\t\t\t\"Cost optimization\",\n\t\t\t\"Reinvention bets\",\n\t\t\t\"Sunset planning\"\n\t\t]\n\t}\n};\n\n//#endregion\nexport { LIFECYCLE_STAGE_META, LifecycleStage };\n//# sourceMappingURL=stages.mjs.map"],"mappings":";AACA,IAAI,iBAAiC,yBAAS,kBAAkB;AAC/D,kBAAiB,iBAAiB,iBAAiB,KAAK;AACxD,kBAAiB,iBAAiB,wBAAwB,KAAK;AAC/D,kBAAiB,iBAAiB,sBAAsB,KAAK;AAC7D,kBAAiB,iBAAiB,sBAAsB,KAAK;AAC7D,kBAAiB,iBAAiB,mBAAmB,KAAK;AAC1D,kBAAiB,iBAAiB,uBAAuB,KAAK;AAC9D,kBAAiB,iBAAiB,qBAAqB,KAAK;AAC5D,QAAO;EACN,EAAE,CAAC;AAEJ,eAAe,aACf,eAAe,oBACf,eAAe,kBACf,eAAe,kBACf,eAAe,eACf,eAAe,mBACf,eAAe;AAEhB,MAAM,uBAAuB;EAC3B,eAAe,cAAc;EAC7B,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,6BAA6B,8BAA8B;EACnE,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,qBAAqB;EACpC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,kCAAkC,6BAA6B;EACvE,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,mBAAmB;EAClC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,gCAAgC,6BAA6B;EACrE,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,mBAAmB;EAClC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,mCAAmC,yBAAyB;EACpE,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,gBAAgB;EAC/B,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,qCAAqC,+BAA+B;EAC5E,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,oBAAoB;EACnC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,yCAAyC;EACjD,YAAY;GACX;GACA;GACA;GACA;EACD;EACA,eAAe,kBAAkB;EACjC,IAAI,eAAe;EACnB,OAAO;EACP,MAAM;EACN,MAAM;EACN,UAAU;EACV,SAAS;GACR;GACA;GACA;GACA;EACD,OAAO,CAAC,kCAAkC;EAC1C,YAAY;GACX;GACA;GACA;GACA;EACD;CACD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../observability/dist/logging/index.mjs"],"sourcesContent":["import { context, trace } from \"@opentelemetry/api\";\n\n//#region src/logging/index.ts\nvar Logger = class {\n\tconstructor(serviceName) {\n\t\tthis.serviceName = serviceName;\n\t}\n\tlog(level, message, meta = {}) {\n\t\tconst span = trace.getSpan(context.active());\n\t\tconst traceId = span?.spanContext().traceId;\n\t\tconst spanId = span?.spanContext().spanId;\n\t\tconst entry = {\n\t\t\ttimestamp: (/* @__PURE__ */ new Date()).toISOString(),\n\t\t\tservice: this.serviceName,\n\t\t\tlevel,\n\t\t\tmessage,\n\t\t\ttraceId,\n\t\t\tspanId,\n\t\t\t...meta\n\t\t};\n\t\tconsole.log(JSON.stringify(entry));\n\t}\n\tdebug(message, meta) {\n\t\tthis.log(\"debug\", message, meta);\n\t}\n\tinfo(message, meta) {\n\t\tthis.log(\"info\", message, meta);\n\t}\n\twarn(message, meta) {\n\t\tthis.log(\"warn\", message, meta);\n\t}\n\terror(message, meta) {\n\t\tthis.log(\"error\", message, meta);\n\t}\n};\nconst logger = new Logger(process.env.OTEL_SERVICE_NAME || \"unknown-service\");\n\n//#endregion\nexport { Logger, logger };\n//# sourceMappingURL=index.mjs.map"],"mappings":";;;AAGA,IAAI,SAAS,MAAM;CAClB,YAAY,aAAa;AACxB,OAAK,cAAc;;CAEpB,IAAI,OAAO,SAAS,OAAO,EAAE,EAAE;EAC9B,MAAM,OAAO,MAAM,QAAQ,QAAQ,QAAQ,CAAC;EAC5C,MAAM,UAAU,MAAM,aAAa,CAAC;EACpC,MAAM,SAAS,MAAM,aAAa,CAAC;EACnC,MAAM,QAAQ;GACb,4BAA4B,IAAI,MAAM,EAAE,aAAa;GACrD,SAAS,KAAK;GACd;GACA;GACA;GACA;GACA,GAAG;GACH;AACD,UAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;;CAEnC,MAAM,SAAS,MAAM;AACpB,OAAK,IAAI,SAAS,SAAS,KAAK;;CAEjC,KAAK,SAAS,MAAM;AACnB,OAAK,IAAI,QAAQ,SAAS,KAAK;;CAEhC,KAAK,SAAS,MAAM;AACnB,OAAK,IAAI,QAAQ,SAAS,KAAK;;CAEhC,MAAM,SAAS,MAAM;AACpB,OAAK,IAAI,SAAS,SAAS,KAAK;;;AAGlC,MAAM,SAAS,IAAI,OAAO,QAAQ,IAAI,qBAAqB,kBAAkB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../observability/dist/metrics/index.mjs"],"sourcesContent":["import { metrics } from \"@opentelemetry/api\";\n\n//#region src/metrics/index.ts\nconst DEFAULT_METER_NAME = \"@lssm/lib.observability\";\nfunction getMeter(name = DEFAULT_METER_NAME) {\n\treturn metrics.getMeter(name);\n}\nfunction createCounter(name, description, meterName) {\n\treturn getMeter(meterName).createCounter(name, { description });\n}\nfunction createUpDownCounter(name, description, meterName) {\n\treturn getMeter(meterName).createUpDownCounter(name, { description });\n}\nfunction createHistogram(name, description, meterName) {\n\treturn getMeter(meterName).createHistogram(name, { description });\n}\nconst standardMetrics = {\n\thttpRequests: createCounter(\"http_requests_total\", \"Total HTTP requests\"),\n\thttpDuration: createHistogram(\"http_request_duration_seconds\", \"HTTP request duration\"),\n\toperationErrors: createCounter(\"operation_errors_total\", \"Total operation errors\"),\n\tworkflowDuration: createHistogram(\"workflow_duration_seconds\", \"Workflow execution duration\")\n};\n\n//#endregion\nexport { createCounter, createHistogram, createUpDownCounter, getMeter, standardMetrics };\n//# sourceMappingURL=index.mjs.map"],"mappings":";;;AAGA,MAAM,qBAAqB;AAC3B,SAAS,SAAS,OAAO,oBAAoB;AAC5C,QAAO,QAAQ,SAAS,KAAK;;AAE9B,SAAS,cAAc,MAAM,aAAa,WAAW;AACpD,QAAO,SAAS,UAAU,CAAC,cAAc,MAAM,EAAE,aAAa,CAAC;;AAKhE,SAAS,gBAAgB,MAAM,aAAa,WAAW;AACtD,QAAO,SAAS,UAAU,CAAC,gBAAgB,MAAM,EAAE,aAAa,CAAC;;AAElE,MAAM,kBAAkB;CACvB,cAAc,cAAc,uBAAuB,sBAAsB;CACzE,cAAc,gBAAgB,iCAAiC,wBAAwB;CACvF,iBAAiB,cAAc,0BAA0B,yBAAyB;CAClF,kBAAkB,gBAAgB,6BAA6B,8BAA8B;CAC7F"}
|
package/dist/types.d.ts
CHANGED
|
@@ -128,4 +128,5 @@ interface OptimizationHint {
|
|
|
128
128
|
lifecycleNotes?: string;
|
|
129
129
|
}
|
|
130
130
|
//#endregion
|
|
131
|
-
export { AnomalySeverity, EvolutionConfig, IntentPattern, OperationCoordinate, OperationMetricSample, OptimizationHint, PatternConfidence, SpecAnomaly, SpecSuggestion, SpecSuggestionFilters, SpecSuggestionProposal, SpecSuggestionRepository, SpecSuggestionWriter, SpecUsageStats, SuggestionEvidence, SuggestionStatus };
|
|
131
|
+
export { AnomalySeverity, EvolutionConfig, IntentPattern, OperationCoordinate, OperationMetricSample, OptimizationHint, PatternConfidence, SpecAnomaly, SpecSuggestion, SpecSuggestionFilters, SpecSuggestionProposal, SpecSuggestionRepository, SpecSuggestionWriter, SpecUsageStats, SuggestionEvidence, SuggestionStatus };
|
|
132
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;;;KAQY,eAAA;KACA,gBAAA;AADA,UAGK,mBAAA,CAHU;EACf,IAAA,EAAA,MAAA;EAEK,OAAA,EAAA,MAAA;EAMA,QAAA,CAAA,EAAA,MAAA;;AAIJ,UAJI,qBAAA,CAIJ;EAOA,SAAA,EAVA,mBAUA;EAAM,UAAA,EAAA,MAAA;EAGF,OAAA,EAAA,OAAA;EACJ,SAAA,EAXA,IAWA;EAQC,gBAAA,CAAA,EAAA,MAAA;EACC,SAAA,CAAA,EAAA,MAAA;EACF,YAAA,CAAA,EAAA,MAAA;EACA,KAAA,CAAA,EAAA,MAAA;EAAM,OAAA,CAAA,EAAA,MAAA;EAGF,OAAA,CAAA,EAAA,MAAA;EAMA,QAAA,CAAA,EAxBJ,MAwBe,CAAA,MAAA,EAAA,OAAA,CAAA;;AAEhB,UAvBK,cAAA,CAuBL;EAGE,SAAA,EAzBD,mBAyBC;EAGF,UAAA,EAAA,MAAA;EAAkB,WAAA,EAAA,MAAA;EAGb,SAAA,EAAA,MAAA;EAMA,gBAAa,EAAA,MAAA;EAUhB,YAAA,EAAA,MAAA;EACA,YAAA,EAAA,MAAA;EACD,YAAA,EAAA,MAAA;EACD,UAAA,EA1CE,IA0CF;EAAkB,WAAA,EAzCf,IAyCe;EAGb,SAAA,EA3CJ,IA2CI;EAIR,SAAA,EA9CI,MA8CJ,CAAA,MAAA,EAAA,MAAA,CAAA;;AAGL,UA9Ca,kBAAA,CA8Cb;EAAiB,IAAA,EAAA,WAAA,GAAA,eAAA,GAAA,YAAA,GAAA,MAAA;EAFZ,WAAA,EAAA,MAAA;EAKI,IAAA,CAAA,EA9CJ,MA8CI,CAAA,MAAA,EAAA,OAAA,CAAA;;AAGI,UA9CA,WAAA,CA8Cc;EAErB,SAAA,EA/CG,mBA+CH;EACC,QAAA,EA/CC,eA+CD;EACC,MAAA,EAAA,SAAA,GAAA,YAAA,GAAA,YAAA,GAAA,QAAA,GAAA,QAAA;EAEC,WAAA,EAAA,MAAA;EAEH,UAAA,EAjDI,IAiDJ;EACE,SAAA,CAAA,EAAA,MAAA;EAMI,aAAA,CAAA,EAAA,MAAA;EACH,QAAA,EAtDD,kBAsDC,EAAA;;AAII,UAvDA,iBAAA,CAuDe;EAQf,KAAA,EAAA,MAAA;EAKA,UAAA,EAAA,MAAA;EACI,MAAA,CAAA,EAAA,MAAA;;AACU,UAhEd,aAAA,CAgEc;EAAR,EAAA,EAAA,MAAA;EAGX,IAAA,EAAA,oBAAA,GAAA,aAAA,GAAA,mBAAA,GAAA,gBAAA,GAAA,iBAAA,GAAA,iBAAA;EACoD,WAAA,EAAA,MAAA;EAC3D,SAAA,CAAA,EA3DS,mBA2DT;EACY,UAAA,EA3DH,iBA2DG;EAAgC,QAAA,CAAA,EA1DpC,MA0DoC,CAAA,MAAA,EAAA,OAAA,CAAA;EAAR,QAAA,EAzD7B,kBAyD6B,EAAA;;AAGxB,UAzDA,sBAAA,CA0DG;EAGH,OAAA,EAAA,MAAA;;;SAzDR;SACA,aACL,gBACA,iBAAiB;;aAGR;;UAGI,cAAA;;UAEP;WACC;YACC;;aAEC;;UAEH;YACE;;;;;;gBAMI;aACH;;;UAII,eAAA;;;;;;;UAQA,qBAAA;WACN;;;UAIM,wBAAA;qBACI,iBAAiB;uBACf,QAAQ;mCAGnB;;;gBACoD;MAC3D;iBACY,wBAAwB,QAAQ;;UAGhC,oBAAA;oBACG,iBAAiB;;UAGpB,gBAAA;aACJ;;;;;mBAKM"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lssm/lib.evolution",
|
|
3
|
-
"version": "0.0.0-canary-
|
|
3
|
+
"version": "0.0.0-canary-20251219202229",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -25,19 +25,19 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"ai": "beta",
|
|
27
27
|
"zod": "^4.1.13",
|
|
28
|
-
"@lssm/lib.ai-agent": "0.0.0-canary-
|
|
29
|
-
"@lssm/lib.contracts": "0.0.0-canary-
|
|
30
|
-
"@lssm/lib.lifecycle": "0.0.0-canary-
|
|
31
|
-
"@lssm/lib.observability": "0.0.0-canary-
|
|
32
|
-
"@lssm/lib.schema": "0.0.0-canary-
|
|
28
|
+
"@lssm/lib.ai-agent": "0.0.0-canary-20251219202229",
|
|
29
|
+
"@lssm/lib.contracts": "0.0.0-canary-20251219202229",
|
|
30
|
+
"@lssm/lib.lifecycle": "0.0.0-canary-20251219202229",
|
|
31
|
+
"@lssm/lib.observability": "0.0.0-canary-20251219202229",
|
|
32
|
+
"@lssm/lib.schema": "0.0.0-canary-20251219202229"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@prisma/client": "7.
|
|
35
|
+
"@prisma/client": "7.2.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@lssm/tool.tsdown": "0.0.0-canary-
|
|
39
|
-
"@lssm/tool.typescript": "0.0.0-canary-
|
|
40
|
-
"tsdown": "^0.
|
|
38
|
+
"@lssm/tool.tsdown": "0.0.0-canary-20251219202229",
|
|
39
|
+
"@lssm/tool.typescript": "0.0.0-canary-20251219202229",
|
|
40
|
+
"tsdown": "^0.18.1",
|
|
41
41
|
"typescript": "^5.9.3"
|
|
42
42
|
},
|
|
43
43
|
"exports": {
|
|
@@ -50,5 +50,6 @@
|
|
|
50
50
|
".": "./dist/index.js",
|
|
51
51
|
"./*": "./*"
|
|
52
52
|
}
|
|
53
|
-
}
|
|
53
|
+
},
|
|
54
|
+
"license": "MIT"
|
|
54
55
|
}
|