@contractspec/module.lifecycle-core 1.57.0 → 1.58.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 (34) hide show
  1. package/dist/__tests__/stage-scorer.test.d.ts +2 -0
  2. package/dist/__tests__/stage-scorer.test.d.ts.map +1 -0
  3. package/dist/adapters/analytics-adapter.d.ts +7 -11
  4. package/dist/adapters/analytics-adapter.d.ts.map +1 -1
  5. package/dist/adapters/intent-adapter.d.ts +5 -9
  6. package/dist/adapters/intent-adapter.d.ts.map +1 -1
  7. package/dist/adapters/questionnaire-adapter.d.ts +7 -11
  8. package/dist/adapters/questionnaire-adapter.d.ts.map +1 -1
  9. package/dist/browser/index.js +427 -0
  10. package/dist/collectors/signal-collector.d.ts +17 -21
  11. package/dist/collectors/signal-collector.d.ts.map +1 -1
  12. package/dist/index.d.ts +8 -8
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +427 -5
  15. package/dist/node/index.js +427 -0
  16. package/dist/orchestrator/lifecycle-orchestrator.d.ts +16 -19
  17. package/dist/orchestrator/lifecycle-orchestrator.d.ts.map +1 -1
  18. package/dist/planning/milestone-planner.d.ts +5 -9
  19. package/dist/planning/milestone-planner.d.ts.map +1 -1
  20. package/dist/scoring/stage-scorer.d.ts +18 -19
  21. package/dist/scoring/stage-scorer.d.ts.map +1 -1
  22. package/package.json +20 -15
  23. package/dist/collectors/signal-collector.js +0 -65
  24. package/dist/collectors/signal-collector.js.map +0 -1
  25. package/dist/data/milestones-catalog.js +0 -74
  26. package/dist/data/milestones-catalog.js.map +0 -1
  27. package/dist/data/stage-weights.js +0 -170
  28. package/dist/data/stage-weights.js.map +0 -1
  29. package/dist/orchestrator/lifecycle-orchestrator.js +0 -53
  30. package/dist/orchestrator/lifecycle-orchestrator.js.map +0 -1
  31. package/dist/planning/milestone-planner.js +0 -17
  32. package/dist/planning/milestone-planner.js.map +0 -1
  33. package/dist/scoring/stage-scorer.js +0 -64
  34. package/dist/scoring/stage-scorer.js.map +0 -1
@@ -0,0 +1,427 @@
1
+ // src/collectors/signal-collector.ts
2
+ import {
3
+ CapitalPhase,
4
+ CompanyPhase,
5
+ ProductPhase
6
+ } from "@contractspec/lib.lifecycle";
7
+ var DEFAULT_AXES = {
8
+ product: ProductPhase.Sketch,
9
+ company: CompanyPhase.Solo,
10
+ capital: CapitalPhase.Bootstrapped
11
+ };
12
+
13
+ class StageSignalCollector {
14
+ options;
15
+ constructor(options) {
16
+ this.options = options;
17
+ }
18
+ async collect(input = {}) {
19
+ const axes = {
20
+ ...DEFAULT_AXES,
21
+ ...input.axes ?? {}
22
+ };
23
+ const metricsSnapshots = [];
24
+ const aggregatedSignals = [...input.signals ?? []];
25
+ const questionnaireAnswers = {
26
+ ...input.questionnaireAnswers ?? {}
27
+ };
28
+ if (input.metrics) {
29
+ metricsSnapshots.push(input.metrics);
30
+ }
31
+ if (this.options.analyticsAdapter) {
32
+ const result = await this.options.analyticsAdapter.fetch();
33
+ if (result.axes)
34
+ Object.assign(axes, result.axes);
35
+ if (result.metrics)
36
+ metricsSnapshots.push(result.metrics);
37
+ if (result.signals)
38
+ aggregatedSignals.push(...result.signals);
39
+ }
40
+ if (this.options.questionnaireAdapter) {
41
+ const result = await this.options.questionnaireAdapter.fetch();
42
+ if (result.axes)
43
+ Object.assign(axes, result.axes);
44
+ if (result.signals)
45
+ aggregatedSignals.push(...result.signals);
46
+ Object.assign(questionnaireAnswers, result.answers);
47
+ }
48
+ if (this.options.intentAdapter) {
49
+ const result = await this.options.intentAdapter.fetch();
50
+ if (result.signals)
51
+ aggregatedSignals.push(...result.signals);
52
+ }
53
+ const metrics = mergeMetricSnapshots(metricsSnapshots);
54
+ return {
55
+ axes,
56
+ metrics,
57
+ signals: dedupeSignals(aggregatedSignals),
58
+ questionnaireAnswers: Object.keys(questionnaireAnswers).length ? questionnaireAnswers : undefined
59
+ };
60
+ }
61
+ }
62
+ var mergeMetricSnapshots = (snapshots) => snapshots.reduce((acc, snapshot) => {
63
+ Object.entries(snapshot ?? {}).forEach(([key, value]) => {
64
+ if (value !== undefined && value !== null) {
65
+ acc[key] = value;
66
+ }
67
+ });
68
+ return acc;
69
+ }, {});
70
+ var dedupeSignals = (signals) => {
71
+ const seen = new Set;
72
+ return signals.filter((signal) => {
73
+ if (!signal.id)
74
+ return true;
75
+ if (seen.has(signal.id))
76
+ return false;
77
+ seen.add(signal.id);
78
+ return true;
79
+ });
80
+ };
81
+ // src/scoring/stage-scorer.ts
82
+ import {
83
+ LIFECYCLE_STAGE_META,
84
+ LifecycleStage
85
+ } from "@contractspec/lib.lifecycle";
86
+ // src/data/stage-weights.json
87
+ var stage_weights_default = {
88
+ Exploration: {
89
+ base: 0.35,
90
+ metrics: {
91
+ activeUsers: { weight: 0.3, direction: "lte", threshold: 5 },
92
+ customerCount: { weight: 0.2, direction: "lte", threshold: 3 },
93
+ teamSize: { weight: 0.1, direction: "lte", threshold: 3 }
94
+ },
95
+ signalKinds: {
96
+ qualitative: 0.4,
97
+ metric: 0.1
98
+ }
99
+ },
100
+ ProblemSolutionFit: {
101
+ base: 0.4,
102
+ metrics: {
103
+ activeUsers: { weight: 0.2, direction: "gte", threshold: 5 },
104
+ customerCount: { weight: 0.2, direction: "gte", threshold: 3 }
105
+ },
106
+ signalKinds: {
107
+ qualitative: 0.3,
108
+ event: 0.1
109
+ }
110
+ },
111
+ MvpEarlyTraction: {
112
+ base: 0.45,
113
+ metrics: {
114
+ activeUsers: { weight: 0.25, direction: "gte", threshold: 25 },
115
+ weeklyActiveUsers: {
116
+ weight: 0.25,
117
+ direction: "gte",
118
+ threshold: 20
119
+ },
120
+ retentionRate: { weight: 0.2, direction: "gte", threshold: 0.25 }
121
+ },
122
+ signalKinds: {
123
+ metric: 0.15,
124
+ event: 0.1
125
+ }
126
+ },
127
+ ProductMarketFit: {
128
+ base: 0.5,
129
+ metrics: {
130
+ retentionRate: {
131
+ weight: 0.35,
132
+ direction: "gte",
133
+ threshold: 0.45
134
+ },
135
+ monthlyRecurringRevenue: {
136
+ weight: 0.25,
137
+ direction: "gte",
138
+ threshold: 1e4
139
+ },
140
+ customerCount: { weight: 0.2, direction: "gte", threshold: 30 }
141
+ },
142
+ signalKinds: {
143
+ metric: 0.15,
144
+ event: 0.1
145
+ }
146
+ },
147
+ GrowthScaleUp: {
148
+ base: 0.55,
149
+ metrics: {
150
+ retentionRate: { weight: 0.2, direction: "gte", threshold: 0.55 },
151
+ monthlyRecurringRevenue: {
152
+ weight: 0.3,
153
+ direction: "gte",
154
+ threshold: 50000
155
+ },
156
+ teamSize: { weight: 0.15, direction: "gte", threshold: 15 }
157
+ },
158
+ signalKinds: {
159
+ event: 0.2,
160
+ metric: 0.15
161
+ }
162
+ },
163
+ ExpansionPlatform: {
164
+ base: 0.6,
165
+ metrics: {
166
+ monthlyRecurringRevenue: {
167
+ weight: 0.35,
168
+ direction: "gte",
169
+ threshold: 150000
170
+ },
171
+ customerCount: { weight: 0.2, direction: "gte", threshold: 100 },
172
+ teamSize: { weight: 0.15, direction: "gte", threshold: 40 }
173
+ },
174
+ signalKinds: {
175
+ event: 0.2,
176
+ milestone: 0.1
177
+ }
178
+ },
179
+ MaturityRenewal: {
180
+ base: 0.6,
181
+ metrics: {
182
+ monthlyRecurringRevenue: {
183
+ weight: 0.25,
184
+ direction: "gte",
185
+ threshold: 250000
186
+ },
187
+ teamSize: { weight: 0.15, direction: "gte", threshold: 80 },
188
+ burnMultiple: { weight: 0.2, direction: "lte", threshold: 1.5 }
189
+ },
190
+ signalKinds: {
191
+ event: 0.2,
192
+ milestone: 0.15
193
+ }
194
+ }
195
+ };
196
+
197
+ // src/scoring/stage-scorer.ts
198
+ var DEFAULT_WEIGHTS = stage_weights_default;
199
+
200
+ class StageScorer {
201
+ weights;
202
+ constructor(weights = DEFAULT_WEIGHTS) {
203
+ this.weights = weights;
204
+ }
205
+ score(input) {
206
+ const kindStrength = evaluateSignalKinds(input.signals);
207
+ const scores = Object.values(LifecycleStage).filter(isStageValue).map((stage) => {
208
+ const stageName = LifecycleStage[stage];
209
+ const config = this.weights[stageName] ?? { base: 0.5 };
210
+ let score = config.base ?? 0.5;
211
+ let contributions = 0;
212
+ const totalPossible = Object.keys(config.metrics ?? {}).length + Object.keys(config.signalKinds ?? {}).length || 1;
213
+ const supportingSignals = [];
214
+ if (config.metrics) {
215
+ Object.entries(config.metrics).forEach(([metricKey, metricConfig]) => {
216
+ const value = input.metrics[metricKey];
217
+ if (value === undefined || value === null)
218
+ return;
219
+ if (passesThreshold(value, metricConfig)) {
220
+ score += metricConfig.weight;
221
+ contributions += 1;
222
+ supportingSignals.push(`metric:${metricKey}`);
223
+ } else {
224
+ score += metricConfig.weight * 0.25;
225
+ }
226
+ });
227
+ }
228
+ if (config.signalKinds) {
229
+ Object.entries(config.signalKinds).forEach(([kind, weight]) => {
230
+ const strength = kindStrength[kind] ?? 0;
231
+ if (strength > 0 && typeof weight === "number") {
232
+ score += weight;
233
+ contributions += 1;
234
+ supportingSignals.push(`signal:${kind}`);
235
+ }
236
+ });
237
+ }
238
+ score = clamp(score, 0, 1.25);
239
+ const confidence = clamp(contributions / totalPossible, 0.1, 1);
240
+ return {
241
+ stage,
242
+ score,
243
+ confidence,
244
+ supportingSignals
245
+ };
246
+ });
247
+ return scores.sort((a, b) => {
248
+ if (b.score === a.score) {
249
+ return b.confidence - a.confidence;
250
+ }
251
+ return b.score - a.score;
252
+ });
253
+ }
254
+ }
255
+ var passesThreshold = (value, config) => {
256
+ const direction = config.direction ?? "gte";
257
+ if (direction === "gte") {
258
+ return value >= config.threshold;
259
+ }
260
+ return value <= config.threshold;
261
+ };
262
+ var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
263
+ var evaluateSignalKinds = (signals) => signals.reduce((acc, signal) => {
264
+ const key = signal.kind ?? "unknown";
265
+ acc[key] = (acc[key] ?? 0) + (signal.weight ?? 1);
266
+ return acc;
267
+ }, {});
268
+ var isStageValue = (value) => typeof value === "number" && (value in LIFECYCLE_STAGE_META);
269
+ // src/orchestrator/lifecycle-orchestrator.ts
270
+ import {
271
+ LIFECYCLE_STAGE_META as LIFECYCLE_STAGE_META2,
272
+ LifecycleStage as LifecycleStage2
273
+ } from "@contractspec/lib.lifecycle";
274
+
275
+ class LifecycleOrchestrator {
276
+ collector;
277
+ scorer;
278
+ planner;
279
+ constructor(options) {
280
+ this.collector = options.collector;
281
+ this.scorer = options.scorer;
282
+ this.planner = options.milestonePlanner;
283
+ }
284
+ async run(input) {
285
+ const collected = await this.collector.collect(input);
286
+ const scorecard = this.scorer.score({
287
+ metrics: collected.metrics,
288
+ signals: collected.signals
289
+ });
290
+ const top = scorecard[0] ?? fallbackScore();
291
+ const meta = LIFECYCLE_STAGE_META2[top.stage];
292
+ return {
293
+ stage: top.stage,
294
+ confidence: top.confidence,
295
+ axes: collected.axes,
296
+ signals: collected.signals,
297
+ metrics: toMetricRecord(collected.metrics),
298
+ gaps: meta.focusAreas.slice(0, 3),
299
+ focusAreas: meta.focusAreas,
300
+ scorecard,
301
+ generatedAt: new Date().toISOString()
302
+ };
303
+ }
304
+ getUpcomingMilestones(stage, completedMilestoneIds = [], limit = 5) {
305
+ if (!this.planner)
306
+ return [];
307
+ return this.planner.getUpcoming(stage, completedMilestoneIds, limit);
308
+ }
309
+ }
310
+ var fallbackScore = () => ({
311
+ stage: LifecycleStage2.Exploration,
312
+ score: 0.3,
313
+ confidence: 0.3,
314
+ supportingSignals: []
315
+ });
316
+ var toMetricRecord = (snapshot) => Object.entries(snapshot ?? {}).reduce((acc, [key, value]) => {
317
+ if (typeof value === "number") {
318
+ acc[key] = value;
319
+ }
320
+ return acc;
321
+ }, {});
322
+ // src/data/milestones-catalog.json
323
+ var milestones_catalog_default = [
324
+ {
325
+ id: "stage0-problem-statement",
326
+ stage: 0,
327
+ category: "product",
328
+ title: "Write the pain statement",
329
+ description: "Capture the clearest description of the top problem in the customer’s own words.",
330
+ priority: 1,
331
+ actionItems: [
332
+ "Interview at least 5 ideal customers",
333
+ "Synthesize quotes into a one-page brief"
334
+ ]
335
+ },
336
+ {
337
+ id: "stage1-prototype-loop",
338
+ stage: 1,
339
+ category: "product",
340
+ title: "Prototype feedback loop",
341
+ description: "Ship a clickable prototype and gather 3 rounds of feedback.",
342
+ priority: 2,
343
+ actionItems: [
344
+ "Create a low-fidelity prototype",
345
+ "Schedule standing feedback calls"
346
+ ]
347
+ },
348
+ {
349
+ id: "stage2-activation",
350
+ stage: 2,
351
+ category: "operations",
352
+ title: "Activation checklist",
353
+ description: "Define the minimum steps required for a new user to succeed.",
354
+ priority: 1,
355
+ actionItems: [
356
+ "Document onboarding flow",
357
+ "Instrument activation analytics"
358
+ ]
359
+ },
360
+ {
361
+ id: "stage3-retention-narrative",
362
+ stage: 3,
363
+ category: "product",
364
+ title: "Retention narrative",
365
+ description: "Create the before/after story that proves why users stay.",
366
+ priority: 2,
367
+ actionItems: [
368
+ "Interview 3 retained users",
369
+ "Publish a one-pager with concrete metrics"
370
+ ]
371
+ },
372
+ {
373
+ id: "stage4-growth-loop",
374
+ stage: 4,
375
+ category: "growth",
376
+ title: "Install a growth loop",
377
+ description: "Stand up a repeatable acquisition → activation → referral motion.",
378
+ priority: 1,
379
+ actionItems: [
380
+ "Define loop metrics",
381
+ "Assign owners for each stage",
382
+ "Review weekly"
383
+ ]
384
+ },
385
+ {
386
+ id: "stage5-platform-blueprint",
387
+ stage: 5,
388
+ category: "product",
389
+ title: "Platform blueprint",
390
+ description: "Align on APIs, integrations, and governance for partners.",
391
+ priority: 2,
392
+ actionItems: [
393
+ "Create integration scoring rubric",
394
+ "Publish partner onboarding checklist"
395
+ ]
396
+ },
397
+ {
398
+ id: "stage6-renewal-ops",
399
+ stage: 6,
400
+ category: "operations",
401
+ title: "Renewal operating rhythm",
402
+ description: "Decide whether to optimize, reinvest, or sunset each major surface.",
403
+ priority: 1,
404
+ actionItems: [
405
+ "Hold quarterly renewal review",
406
+ "Document reinvestment bets"
407
+ ]
408
+ }
409
+ ];
410
+
411
+ // src/planning/milestone-planner.ts
412
+ class LifecycleMilestonePlanner {
413
+ milestones;
414
+ constructor(customCatalog) {
415
+ this.milestones = customCatalog ?? milestones_catalog_default;
416
+ }
417
+ getUpcoming(stage, completedIds = [], limit = 5) {
418
+ const completedSet = new Set(completedIds);
419
+ return this.milestones.filter((milestone) => milestone.stage === stage && !completedSet.has(milestone.id)).sort((a, b) => a.priority - b.priority).slice(0, limit);
420
+ }
421
+ }
422
+ export {
423
+ StageSignalCollector,
424
+ StageScorer,
425
+ LifecycleOrchestrator,
426
+ LifecycleMilestonePlanner
427
+ };
@@ -1,22 +1,19 @@
1
- import { StageSignalCollector } from "../collectors/signal-collector.js";
2
- import { StageScorer } from "../scoring/stage-scorer.js";
3
- import { LifecycleMilestonePlanner } from "../planning/milestone-planner.js";
4
- import { LifecycleAssessment, LifecycleAssessmentInput, LifecycleMilestone, LifecycleStage } from "@contractspec/lib.lifecycle";
5
-
6
- //#region src/orchestrator/lifecycle-orchestrator.d.ts
7
- interface LifecycleOrchestratorOptions {
8
- collector: StageSignalCollector;
9
- scorer: StageScorer;
10
- milestonePlanner?: LifecycleMilestonePlanner;
1
+ import type { LifecycleAssessment, LifecycleAssessmentInput, LifecycleMilestone } from '@contractspec/lib.lifecycle';
2
+ import { LifecycleStage } from '@contractspec/lib.lifecycle';
3
+ import { StageSignalCollector } from '../collectors/signal-collector';
4
+ import { StageScorer } from '../scoring/stage-scorer';
5
+ import { LifecycleMilestonePlanner } from '../planning/milestone-planner';
6
+ export interface LifecycleOrchestratorOptions {
7
+ collector: StageSignalCollector;
8
+ scorer: StageScorer;
9
+ milestonePlanner?: LifecycleMilestonePlanner;
11
10
  }
12
- declare class LifecycleOrchestrator {
13
- private readonly collector;
14
- private readonly scorer;
15
- private readonly planner?;
16
- constructor(options: LifecycleOrchestratorOptions);
17
- run(input?: LifecycleAssessmentInput): Promise<LifecycleAssessment>;
18
- getUpcomingMilestones(stage: LifecycleStage, completedMilestoneIds?: string[], limit?: number): LifecycleMilestone[];
11
+ export declare class LifecycleOrchestrator {
12
+ private readonly collector;
13
+ private readonly scorer;
14
+ private readonly planner?;
15
+ constructor(options: LifecycleOrchestratorOptions);
16
+ run(input?: LifecycleAssessmentInput): Promise<LifecycleAssessment>;
17
+ getUpcomingMilestones(stage: LifecycleStage, completedMilestoneIds?: string[], limit?: number): LifecycleMilestone[];
19
18
  }
20
- //#endregion
21
- export { LifecycleOrchestrator, LifecycleOrchestratorOptions };
22
19
  //# sourceMappingURL=lifecycle-orchestrator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-orchestrator.d.ts","names":[],"sources":["../../src/orchestrator/lifecycle-orchestrator.ts"],"mappings":";;;;;;UAciB,4BAAA;EACf,SAAA,EAAW,oBAAA;EACX,MAAA,EAAQ,WAAA;EACR,gBAAA,GAAmB,yBAAA;AAAA;AAAA,cAGR,qBAAA;EAAA,iBACM,SAAA;EAAA,iBACA,MAAA;EAAA,iBACA,OAAA;cAEL,OAAA,EAAS,4BAAA;EAMf,GAAA,CAAI,KAAA,GAAQ,wBAAA,GAA2B,OAAA,CAAQ,mBAAA;EAsBrD,qBAAA,CACE,KAAA,EAAO,cAAA,EACP,qBAAA,aACA,KAAA,YACC,kBAAA;AAAA"}
1
+ {"version":3,"file":"lifecycle-orchestrator.d.ts","sourceRoot":"","sources":["../../src/orchestrator/lifecycle-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAEnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,cAAc,EACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,oBAAoB,CAAC;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;CAC9C;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA4B;gBAEzC,OAAO,EAAE,4BAA4B;IAM3C,GAAG,CAAC,KAAK,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsBzE,qBAAqB,CACnB,KAAK,EAAE,cAAc,EACrB,qBAAqB,GAAE,MAAM,EAAO,EACpC,KAAK,SAAI,GACR,kBAAkB,EAAE;CAIxB"}
@@ -1,11 +1,7 @@
1
- import { LifecycleMilestone, LifecycleStage } from "@contractspec/lib.lifecycle";
2
-
3
- //#region src/planning/milestone-planner.d.ts
4
- declare class LifecycleMilestonePlanner {
5
- private readonly milestones;
6
- constructor(customCatalog?: LifecycleMilestone[]);
7
- getUpcoming(stage: LifecycleStage, completedIds?: string[], limit?: number): LifecycleMilestone[];
1
+ import type { LifecycleMilestone, LifecycleStage } from '@contractspec/lib.lifecycle';
2
+ export declare class LifecycleMilestonePlanner {
3
+ private readonly milestones;
4
+ constructor(customCatalog?: LifecycleMilestone[]);
5
+ getUpcoming(stage: LifecycleStage, completedIds?: string[], limit?: number): LifecycleMilestone[];
8
6
  }
9
- //#endregion
10
- export { LifecycleMilestonePlanner };
11
7
  //# sourceMappingURL=milestone-planner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"milestone-planner.d.ts","names":[],"sources":["../../src/planning/milestone-planner.ts"],"mappings":";;;cAMa,yBAAA;EAAA,iBACM,UAAA;cAEL,aAAA,GAAgB,kBAAA;EAI5B,WAAA,CACE,KAAA,EAAO,cAAA,EACP,YAAA,aACA,KAAA,YACC,kBAAA;AAAA"}
1
+ {"version":3,"file":"milestone-planner.d.ts","sourceRoot":"","sources":["../../src/planning/milestone-planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACf,MAAM,6BAA6B,CAAC;AAGrC,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;gBAEtC,aAAa,CAAC,EAAE,kBAAkB,EAAE;IAIhD,WAAW,CACT,KAAK,EAAE,cAAc,EACrB,YAAY,GAAE,MAAM,EAAO,EAC3B,KAAK,SAAI,GACR,kBAAkB,EAAE;CAUxB"}
@@ -1,27 +1,26 @@
1
- import { LifecycleMetricSnapshot, LifecycleScore, LifecycleSignal } from "@contractspec/lib.lifecycle";
2
-
3
- //#region src/scoring/stage-scorer.d.ts
4
- type NumericMetricKey = Extract<{ [Key in keyof LifecycleMetricSnapshot]: LifecycleMetricSnapshot[Key] extends number | undefined ? Key : never }[keyof LifecycleMetricSnapshot], string>;
1
+ import type { LifecycleMetricSnapshot, LifecycleScore, LifecycleSignal } from '@contractspec/lib.lifecycle';
2
+ type NumericMetricKey = Extract<{
3
+ [Key in keyof LifecycleMetricSnapshot]: LifecycleMetricSnapshot[Key] extends number | undefined ? Key : never;
4
+ }[keyof LifecycleMetricSnapshot], string>;
5
5
  interface MetricWeightConfig {
6
- weight: number;
7
- threshold: number;
8
- direction?: 'gte' | 'lte';
6
+ weight: number;
7
+ threshold: number;
8
+ direction?: 'gte' | 'lte';
9
9
  }
10
10
  interface StageWeightConfig {
11
- base: number;
12
- metrics?: Partial<Record<NumericMetricKey, MetricWeightConfig>>;
13
- signalKinds?: Partial<Record<string, number>>;
11
+ base: number;
12
+ metrics?: Partial<Record<NumericMetricKey, MetricWeightConfig>>;
13
+ signalKinds?: Partial<Record<string, number>>;
14
14
  }
15
15
  type StageWeights = Record<string, StageWeightConfig>;
16
- interface StageScoreInput {
17
- metrics: LifecycleMetricSnapshot;
18
- signals: LifecycleSignal[];
16
+ export interface StageScoreInput {
17
+ metrics: LifecycleMetricSnapshot;
18
+ signals: LifecycleSignal[];
19
19
  }
20
- declare class StageScorer {
21
- private readonly weights;
22
- constructor(weights?: StageWeights);
23
- score(input: StageScoreInput): LifecycleScore[];
20
+ export declare class StageScorer {
21
+ private readonly weights;
22
+ constructor(weights?: StageWeights);
23
+ score(input: StageScoreInput): LifecycleScore[];
24
24
  }
25
- //#endregion
26
- export { StageScoreInput, StageScorer };
25
+ export {};
27
26
  //# sourceMappingURL=stage-scorer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stage-scorer.d.ts","names":[],"sources":["../../src/scoring/stage-scorer.ts"],"mappings":";;;KAWK,gBAAA,GAAmB,OAAA,iBAEN,uBAAA,GAA0B,uBAAA,CAAwB,GAAA,+BAG5D,GAAA,iBAEE,uBAAA;AAAA,UAIA,kBAAA;EACR,MAAA;EACA,SAAA;EACA,SAAA;AAAA;AAAA,UAGQ,iBAAA;EACR,IAAA;EACA,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,gBAAA,EAAkB,kBAAA;EAC3C,WAAA,GAAc,OAAA,CAAQ,MAAA;AAAA;AAAA,KAGnB,YAAA,GAAe,MAAA,SAAe,iBAAA;AAAA,UAIlB,eAAA;EACf,OAAA,EAAS,uBAAA;EACT,OAAA,EAAS,eAAA;AAAA;AAAA,cAGE,WAAA;EAAA,iBACM,OAAA;cAEL,OAAA,GAAS,YAAA;EAIrB,KAAA,CAAM,KAAA,EAAO,eAAA,GAAkB,cAAA;AAAA"}
1
+ {"version":3,"file":"stage-scorer.d.ts","sourceRoot":"","sources":["../../src/scoring/stage-scorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,cAAc,EACd,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAOrC,KAAK,gBAAgB,GAAG,OAAO,CAC7B;KACG,GAAG,IAAI,MAAM,uBAAuB,GAAG,uBAAuB,CAAC,GAAG,CAAC,SAChE,MAAM,GACN,SAAS,GACT,GAAG,GACH,KAAK;CACV,CAAC,MAAM,uBAAuB,CAAC,EAChC,MAAM,CACP,CAAC;AAEF,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;CAC3B;AAED,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAChE,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC/C;AAED,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAItD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,uBAAuB,CAAC;IACjC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;gBAE3B,OAAO,GAAE,YAA8B;IAInD,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,cAAc,EAAE;CA4DhD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/module.lifecycle-core",
3
- "version": "1.57.0",
3
+ "version": "1.58.0",
4
4
  "description": "Core lifecycle stage definitions and transitions",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -20,34 +20,39 @@
20
20
  "scripts": {
21
21
  "publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
22
22
  "publish:pkg:canary": "bun publish:pkg --tag canary",
23
- "build": "bun build:types && bun build:bundle",
24
- "build:bundle": "tsdown",
25
- "build:types": "tsc --noEmit",
26
- "dev": "bun build:bundle --watch",
23
+ "build": "bun run prebuild && bun run build:bundle && bun run build:types",
24
+ "build:bundle": "contractspec-bun-build transpile",
25
+ "build:types": "contractspec-bun-build types",
26
+ "dev": "contractspec-bun-build dev",
27
27
  "clean": "rimraf dist .turbo",
28
28
  "lint": "bun lint:fix",
29
29
  "lint:fix": "eslint src --fix",
30
30
  "lint:check": "eslint src",
31
- "test": "bun test"
31
+ "test": "bun test",
32
+ "prebuild": "contractspec-bun-build prebuild",
33
+ "typecheck": "tsc --noEmit"
32
34
  },
33
35
  "dependencies": {
34
- "@contractspec/lib.lifecycle": "1.57.0"
36
+ "@contractspec/lib.lifecycle": "1.58.0"
35
37
  },
36
38
  "devDependencies": {
37
- "@contractspec/tool.tsdown": "1.57.0",
38
- "@contractspec/tool.typescript": "1.57.0",
39
- "tsdown": "^0.20.3",
40
- "typescript": "^5.9.3"
39
+ "@contractspec/tool.typescript": "1.58.0",
40
+ "typescript": "^5.9.3",
41
+ "@contractspec/tool.bun": "1.57.0"
41
42
  },
42
43
  "exports": {
43
- ".": "./dist/index.js",
44
- "./*": "./*"
44
+ ".": "./src/index.ts"
45
45
  },
46
46
  "publishConfig": {
47
47
  "access": "public",
48
48
  "exports": {
49
- ".": "./dist/index.js",
50
- "./*": "./*"
49
+ ".": {
50
+ "types": "./dist/index.d.ts",
51
+ "bun": "./dist/index.js",
52
+ "node": "./dist/node/index.mjs",
53
+ "browser": "./dist/browser/index.js",
54
+ "default": "./dist/index.js"
55
+ }
51
56
  },
52
57
  "registry": "https://registry.npmjs.org/"
53
58
  },
@@ -1,65 +0,0 @@
1
- import { CapitalPhase, CompanyPhase, ProductPhase } from "@contractspec/lib.lifecycle";
2
-
3
- //#region src/collectors/signal-collector.ts
4
- const DEFAULT_AXES = {
5
- product: ProductPhase.Sketch,
6
- company: CompanyPhase.Solo,
7
- capital: CapitalPhase.Bootstrapped
8
- };
9
- var StageSignalCollector = class {
10
- options;
11
- constructor(options) {
12
- this.options = options;
13
- }
14
- async collect(input = {}) {
15
- const axes = {
16
- ...DEFAULT_AXES,
17
- ...input.axes ?? {}
18
- };
19
- const metricsSnapshots = [];
20
- const aggregatedSignals = [...input.signals ?? []];
21
- const questionnaireAnswers = { ...input.questionnaireAnswers ?? {} };
22
- if (input.metrics) metricsSnapshots.push(input.metrics);
23
- if (this.options.analyticsAdapter) {
24
- const result = await this.options.analyticsAdapter.fetch();
25
- if (result.axes) Object.assign(axes, result.axes);
26
- if (result.metrics) metricsSnapshots.push(result.metrics);
27
- if (result.signals) aggregatedSignals.push(...result.signals);
28
- }
29
- if (this.options.questionnaireAdapter) {
30
- const result = await this.options.questionnaireAdapter.fetch();
31
- if (result.axes) Object.assign(axes, result.axes);
32
- if (result.signals) aggregatedSignals.push(...result.signals);
33
- Object.assign(questionnaireAnswers, result.answers);
34
- }
35
- if (this.options.intentAdapter) {
36
- const result = await this.options.intentAdapter.fetch();
37
- if (result.signals) aggregatedSignals.push(...result.signals);
38
- }
39
- return {
40
- axes,
41
- metrics: mergeMetricSnapshots(metricsSnapshots),
42
- signals: dedupeSignals(aggregatedSignals),
43
- questionnaireAnswers: Object.keys(questionnaireAnswers).length ? questionnaireAnswers : void 0
44
- };
45
- }
46
- };
47
- const mergeMetricSnapshots = (snapshots) => snapshots.reduce((acc, snapshot) => {
48
- Object.entries(snapshot ?? {}).forEach(([key, value]) => {
49
- if (value !== void 0 && value !== null) acc[key] = value;
50
- });
51
- return acc;
52
- }, {});
53
- const dedupeSignals = (signals) => {
54
- const seen = /* @__PURE__ */ new Set();
55
- return signals.filter((signal) => {
56
- if (!signal.id) return true;
57
- if (seen.has(signal.id)) return false;
58
- seen.add(signal.id);
59
- return true;
60
- });
61
- };
62
-
63
- //#endregion
64
- export { StageSignalCollector };
65
- //# sourceMappingURL=signal-collector.js.map