@contractspec/example.product-intent 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 (42) hide show
  1. package/.turbo/turbo-build.log +21 -96
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +15 -0
  4. package/dist/example.d.ts +2 -6
  5. package/dist/example.d.ts.map +1 -1
  6. package/dist/example.js +27 -37
  7. package/dist/index.d.ts +6 -4
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +342 -4
  10. package/dist/load-evidence.d.ts +13 -17
  11. package/dist/load-evidence.d.ts.map +1 -1
  12. package/dist/load-evidence.js +307 -68
  13. package/dist/load-evidence.test.d.ts +2 -0
  14. package/dist/load-evidence.test.d.ts.map +1 -0
  15. package/dist/node/example.js +28 -0
  16. package/dist/node/index.js +342 -0
  17. package/dist/node/load-evidence.js +313 -0
  18. package/dist/node/posthog-signals.js +248 -0
  19. package/dist/node/script.js +512 -0
  20. package/dist/node/sync-actions.js +491 -0
  21. package/dist/posthog-signals.d.ts +15 -19
  22. package/dist/posthog-signals.d.ts.map +1 -1
  23. package/dist/posthog-signals.js +222 -178
  24. package/dist/script.d.ts +2 -1
  25. package/dist/script.d.ts.map +1 -0
  26. package/dist/script.js +493 -152
  27. package/dist/sync-actions.d.ts +2 -1
  28. package/dist/sync-actions.d.ts.map +1 -0
  29. package/dist/sync-actions.js +466 -128
  30. package/package.json +57 -27
  31. package/tsdown.config.js +1 -2
  32. package/.turbo/turbo-build$colon$bundle.log +0 -99
  33. package/dist/example.js.map +0 -1
  34. package/dist/libs/analytics/dist/funnel/analyzer.js +0 -64
  35. package/dist/libs/analytics/dist/funnel/analyzer.js.map +0 -1
  36. package/dist/libs/analytics/dist/types.d.ts +0 -22
  37. package/dist/libs/analytics/dist/types.d.ts.map +0 -1
  38. package/dist/load-evidence.js.map +0 -1
  39. package/dist/posthog-signals.js.map +0 -1
  40. package/dist/script.js.map +0 -1
  41. package/dist/sync-actions.js.map +0 -1
  42. package/tsconfig.tsbuildinfo +0 -1
@@ -1,100 +1,25 @@
1
- $ bun build:types && bun build:bundle
2
- $ tsc --noEmit
3
- $ tsdown
4
- ℹ tsdown v0.20.3 powered by rolldown v1.0.0-rc.3
5
- ℹ config file: /home/runner/work/contractspec/contractspec/packages/examples/product-intent/tsdown.config.js
6
- ℹ entry: src/example.ts, src/index.ts, src/load-evidence.ts, src/posthog-signals.ts, src/script.ts, src/sync-actions.ts
7
- ℹ target: esnext
8
- ℹ tsconfig: tsconfig.json
9
- ℹ Build start
10
- ℹ dist/posthog-signals.js  6.96 kB │ gzip: 2.20 kB
11
- ℹ dist/script.js  6.55 kB │ gzip: 2.29 kB
12
- ℹ dist/sync-actions.js  5.88 kB │ gzip: 2.07 kB
13
- ℹ dist/load-evidence.js  2.67 kB │ gzip: 1.12 kB
14
- ℹ dist/example.js  0.81 kB │ gzip: 0.44 kB
15
- ℹ dist/index.js  0.50 kB │ gzip: 0.21 kB
16
- ℹ dist/posthog-signals.js.map 14.02 kB │ gzip: 4.15 kB
17
- ℹ dist/script.js.map 11.64 kB │ gzip: 3.74 kB
18
- ℹ dist/sync-actions.js.map 10.53 kB │ gzip: 3.37 kB
19
- ℹ dist/load-evidence.js.map  4.79 kB │ gzip: 1.86 kB
20
- ℹ dist/libs/analytics/dist/funnel/analyzer.js.map  3.65 kB │ gzip: 1.39 kB
21
- ℹ dist/libs/analytics/dist/funnel/analyzer.js  2.00 kB │ gzip: 0.84 kB
22
- ℹ dist/example.js.map  1.22 kB │ gzip: 0.63 kB
23
- ℹ dist/libs/analytics/dist/types.d.ts.map  0.95 kB │ gzip: 0.48 kB
24
- ℹ dist/posthog-signals.d.ts.map  0.37 kB │ gzip: 0.23 kB
25
- ℹ dist/load-evidence.d.ts.map  0.37 kB │ gzip: 0.23 kB
26
- ℹ dist/example.d.ts.map  0.13 kB │ gzip: 0.13 kB
27
- ℹ dist/load-evidence.d.ts  1.10 kB │ gzip: 0.49 kB
28
- ℹ dist/posthog-signals.d.ts  1.00 kB │ gzip: 0.43 kB
29
- ℹ dist/index.d.ts  0.67 kB │ gzip: 0.24 kB
30
- ℹ dist/example.d.ts  0.25 kB │ gzip: 0.17 kB
31
- ℹ dist/script.d.ts  0.01 kB │ gzip: 0.03 kB
32
- ℹ dist/sync-actions.d.ts  0.01 kB │ gzip: 0.03 kB
33
- ℹ dist/libs/analytics/dist/types.d.ts  0.50 kB │ gzip: 0.28 kB
34
- ℹ 24 files, total: 76.58 kB
35
- src/load-evidence.ts (1:15) [UNRESOLVED_IMPORT] Warning: Could not resolve 'node:fs' in src/load-evidence.ts
36
- ╭─[ src/load-evidence.ts:1:16 ]
37
- │
38
- 1 │ import fs from 'node:fs';
39
-  │ ────┬────
40
-  │ ╰────── Module not found, treating it as an external dependency
41
-  │
42
-  │ Help: The "main" field here was ignored. Main fields must be configured explicitly when using the "neutral" platform.
43
- ───╯
1
+ $ contractspec-bun-build prebuild
2
+ $ bun run prebuild && bun run build:bundle && bun run build:types
3
+ $ contractspec-bun-build prebuild
4
+ $ contractspec-bun-build transpile
5
+ [contractspec-bun-build] transpile target=bun root=src entries=6
6
+ Bundled 6 modules in 29ms
44
7
 
45
- src/load-evidence.ts (2:17) [UNRESOLVED_IMPORT] Warning: Could not resolve 'node:path' in src/load-evidence.ts
46
- ╭─[ src/load-evidence.ts:2:18 ]
47
- │
48
- 2 │ import path from 'node:path';
49
-  │ ─────┬─────
50
-  │ ╰─────── Module not found, treating it as an external dependency
51
-  │
52
-  │ Help: The "main" field here was ignored. Main fields must be configured explicitly when using the "neutral" platform.
53
- ───╯
8
+ ./example.js 0.80 KB (entry point)
9
+ ./index.js 10.71 KB (entry point)
10
+ ./script.js 16.47 KB (entry point)
11
+ ./sync-actions.js 15.95 KB (entry point)
12
+ ./load-evidence.js 9.86 KB (entry point)
13
+ ./posthog-signals.js 7.59 KB (entry point)
54
14
 
55
- src/load-evidence.ts (3:30) [UNRESOLVED_IMPORT] Warning: Could not resolve 'node:url' in src/load-evidence.ts
56
- ╭─[ src/load-evidence.ts:3:31 ]
57
- │
58
- 3 │ import { fileURLToPath } from 'node:url';
59
-  │ ─────┬────
60
-  │ ╰────── Module not found, treating it as an external dependency
61
-  │
62
-  │ Help: The "main" field here was ignored. Main fields must be configured explicitly when using the "neutral" platform.
63
- ───╯
15
+ [contractspec-bun-build] transpile target=node root=src entries=6
16
+ Bundled 6 modules in 14ms
64
17
 
65
- src/script.ts (1:15) [UNRESOLVED_IMPORT] Warning: Could not resolve 'node:fs' in src/script.ts
66
- ╭─[ src/script.ts:1:16 ]
67
- │
68
- 1 │ import fs from 'node:fs';
69
-  │ ────┬────
70
-  │ ╰────── Module not found, treating it as an external dependency
71
-  │
72
-  │ Help: The "main" field here was ignored. Main fields must be configured explicitly when using the "neutral" platform.
73
- ───╯
74
-
75
- src/script.ts (2:17) [UNRESOLVED_IMPORT] Warning: Could not resolve 'node:path' in src/script.ts
76
- ╭─[ src/script.ts:2:18 ]
77
- │
78
- 2 │ import path from 'node:path';
79
-  │ ─────┬─────
80
-  │ ╰─────── Module not found, treating it as an external dependency
81
-  │
82
-  │ Help: The "main" field here was ignored. Main fields must be configured explicitly when using the "neutral" platform.
83
- ───╯
84
-
85
- src/script.ts (3:30) [UNRESOLVED_IMPORT] Warning: Could not resolve 'node:url' in src/script.ts
86
- ╭─[ src/script.ts:3:31 ]
87
- │
88
- 3 │ import { fileURLToPath } from 'node:url';
89
-  │ ─────┬────
90
-  │ ╰────── Module not found, treating it as an external dependency
91
-  │
92
-  │ Help: The "main" field here was ignored. Main fields must be configured explicitly when using the "neutral" platform.
93
- ───╯
94
-
95
- [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
96
- ✔ Build complete in 23955ms
97
- - rolldown-plugin-dts:generate (51%)
98
- - tsdown:external (48%)
99
- See https://rolldown.rs/options/checks#plugintimings for more details.
18
+ ./example.js 0.79 KB (entry point)
19
+ ./index.js 10.71 KB (entry point)
20
+ ./script.js 16.49 KB (entry point)
21
+ ./sync-actions.js 15.95 KB (entry point)
22
+ ./load-evidence.js 9.86 KB (entry point)
23
+ ./posthog-signals.js 7.58 KB (entry point)
100
24
 
25
+ $ contractspec-bun-build types
@@ -0,0 +1 @@
1
+ $ contractspec-bun-build prebuild
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @contractspec/example.product-intent
2
2
 
3
+ ## 1.58.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d1f0fd0: chore: Migrate non-app package builds from tsdown to shared Bun tooling, add `@contractspec/tool.bun`, and standardize `prebuild`/`build`/`typecheck` with platform-aware exports and `tsc` declaration emission into `dist`.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [d1f0fd0]
12
+ - Updated dependencies [4355a9e]
13
+ - @contractspec/integration.providers-impls@1.58.0
14
+ - @contractspec/lib.product-intent-utils@1.58.0
15
+ - @contractspec/lib.contracts@1.58.0
16
+ - @contractspec/lib.ai-agent@1.58.0
17
+
3
18
  ## 1.57.0
4
19
 
5
20
  ### Minor Changes
package/dist/example.d.ts CHANGED
@@ -1,7 +1,3 @@
1
- import * as _contractspec_lib_contracts0 from "@contractspec/lib.contracts";
2
-
3
- //#region src/example.d.ts
4
- declare const example: _contractspec_lib_contracts0.ExampleSpec;
5
- //#endregion
6
- export { example as default };
1
+ declare const example: import("@contractspec/lib.contracts").ExampleSpec;
2
+ export default example;
7
3
  //# sourceMappingURL=example.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"example.d.ts","names":[],"sources":["../src/example.ts"],"mappings":";;;cAEM,OAAA,EAsBJ,4BAAA,CAtBW,WAAA"}
1
+ {"version":3,"file":"example.d.ts","sourceRoot":"","sources":["../src/example.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,OAAO,mDAsBX,CAAC;AAEH,eAAe,OAAO,CAAC"}
package/dist/example.js CHANGED
@@ -1,39 +1,29 @@
1
+ // @bun
2
+ // src/example.ts
1
3
  import { defineExample } from "@contractspec/lib.contracts";
2
-
3
- //#region src/example.ts
4
- const example = defineExample({
5
- meta: {
6
- key: "product-intent",
7
- version: "1.0.0",
8
- title: "Product Intent Discovery",
9
- description: "Evidence ingestion and product-intent workflow for PM discovery.",
10
- kind: "script",
11
- visibility: "public",
12
- stability: "experimental",
13
- owners: ["@platform.core"],
14
- tags: [
15
- "product-intent",
16
- "discovery",
17
- "pm",
18
- "evidence",
19
- "llm"
20
- ]
21
- },
22
- entrypoints: { packageName: "@contractspec/example.product-intent" },
23
- surfaces: {
24
- templates: false,
25
- sandbox: {
26
- enabled: false,
27
- modes: []
28
- },
29
- studio: {
30
- enabled: false,
31
- installable: false
32
- },
33
- mcp: { enabled: false }
34
- }
4
+ var example = defineExample({
5
+ meta: {
6
+ key: "product-intent",
7
+ version: "1.0.0",
8
+ title: "Product Intent Discovery",
9
+ description: "Evidence ingestion and product-intent workflow for PM discovery.",
10
+ kind: "script",
11
+ visibility: "public",
12
+ stability: "experimental",
13
+ owners: ["@platform.core"],
14
+ tags: ["product-intent", "discovery", "pm", "evidence", "llm"]
15
+ },
16
+ entrypoints: {
17
+ packageName: "@contractspec/example.product-intent"
18
+ },
19
+ surfaces: {
20
+ templates: false,
21
+ sandbox: { enabled: false, modes: [] },
22
+ studio: { enabled: false, installable: false },
23
+ mcp: { enabled: false }
24
+ }
35
25
  });
36
-
37
- //#endregion
38
- export { example as default };
39
- //# sourceMappingURL=example.js.map
26
+ var example_default = example;
27
+ export {
28
+ example_default as default
29
+ };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import example from "./example.js";
2
- import { PosthogEvidenceOptions, loadPosthogEvidenceChunks, resolvePosthogEvidenceOptionsFromEnv } from "./posthog-signals.js";
3
- import { DEFAULT_CHUNK_SIZE, DEFAULT_EVIDENCE_ROOT, DEFAULT_TRANSCRIPT_DIRS, EvidenceLoadOptions, EvidenceLoadWithSignalsOptions, loadEvidenceChunks, loadEvidenceChunksWithSignals } from "./load-evidence.js";
4
- export { DEFAULT_CHUNK_SIZE, DEFAULT_EVIDENCE_ROOT, DEFAULT_TRANSCRIPT_DIRS, type EvidenceLoadOptions, type EvidenceLoadWithSignalsOptions, type PosthogEvidenceOptions, example, loadEvidenceChunks, loadEvidenceChunksWithSignals, loadPosthogEvidenceChunks, resolvePosthogEvidenceOptionsFromEnv };
1
+ export { default as example } from './example';
2
+ export { DEFAULT_CHUNK_SIZE, DEFAULT_EVIDENCE_ROOT, DEFAULT_TRANSCRIPT_DIRS, loadEvidenceChunks, loadEvidenceChunksWithSignals, } from './load-evidence';
3
+ export type { EvidenceLoadOptions, EvidenceLoadWithSignalsOptions, } from './load-evidence';
4
+ export { loadPosthogEvidenceChunks, resolvePosthogEvidenceOptionsFromEnv, } from './posthog-signals';
5
+ export type { PosthogEvidenceOptions } from './posthog-signals';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,yBAAyB,EACzB,oCAAoC,GACrC,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,343 @@
1
- import example from "./example.js";
2
- import { loadPosthogEvidenceChunks, resolvePosthogEvidenceOptionsFromEnv } from "./posthog-signals.js";
3
- import { DEFAULT_CHUNK_SIZE, DEFAULT_EVIDENCE_ROOT, DEFAULT_TRANSCRIPT_DIRS, loadEvidenceChunks, loadEvidenceChunksWithSignals } from "./load-evidence.js";
1
+ // @bun
2
+ // src/example.ts
3
+ import { defineExample } from "@contractspec/lib.contracts";
4
+ var example = defineExample({
5
+ meta: {
6
+ key: "product-intent",
7
+ version: "1.0.0",
8
+ title: "Product Intent Discovery",
9
+ description: "Evidence ingestion and product-intent workflow for PM discovery.",
10
+ kind: "script",
11
+ visibility: "public",
12
+ stability: "experimental",
13
+ owners: ["@platform.core"],
14
+ tags: ["product-intent", "discovery", "pm", "evidence", "llm"]
15
+ },
16
+ entrypoints: {
17
+ packageName: "@contractspec/example.product-intent"
18
+ },
19
+ surfaces: {
20
+ templates: false,
21
+ sandbox: { enabled: false, modes: [] },
22
+ studio: { enabled: false, installable: false },
23
+ mcp: { enabled: false }
24
+ }
25
+ });
26
+ var example_default = example;
4
27
 
5
- export { DEFAULT_CHUNK_SIZE, DEFAULT_EVIDENCE_ROOT, DEFAULT_TRANSCRIPT_DIRS, example, loadEvidenceChunks, loadEvidenceChunksWithSignals, loadPosthogEvidenceChunks, resolvePosthogEvidenceOptionsFromEnv };
28
+ // src/posthog-signals.ts
29
+ import { FunnelAnalyzer } from "@contractspec/lib.analytics/funnel";
30
+ import { PosthogAnalyticsProvider } from "@contractspec/integration.providers-impls/impls/posthog";
31
+ async function loadPosthogEvidenceChunks(options) {
32
+ const chunks = [];
33
+ const range = resolveRange(options.dateRange);
34
+ const eventSummary = await loadEventSummary(options, range);
35
+ if (eventSummary) {
36
+ chunks.push(eventSummary);
37
+ }
38
+ const funnelEvidence = await loadFunnelEvidence(options, range);
39
+ if (funnelEvidence) {
40
+ chunks.push(funnelEvidence);
41
+ }
42
+ const featureFlags = await loadFeatureFlagEvidence(options);
43
+ if (featureFlags) {
44
+ chunks.push(featureFlags);
45
+ }
46
+ return chunks;
47
+ }
48
+ async function loadEventSummary(options, range) {
49
+ if (!options.reader.queryHogQL)
50
+ return null;
51
+ const eventFilter = buildEventFilter(options.eventNames);
52
+ const limit = options.limit ?? 10;
53
+ const result = await options.reader.queryHogQL({
54
+ query: [
55
+ "select",
56
+ " event as eventName,",
57
+ " count() as total",
58
+ "from events",
59
+ "where timestamp >= {dateFrom} and timestamp < {dateTo}",
60
+ eventFilter.clause ? `and ${eventFilter.clause}` : "",
61
+ "group by eventName",
62
+ "order by total desc",
63
+ `limit ${limit}`
64
+ ].filter(Boolean).join(`
65
+ `),
66
+ values: {
67
+ dateFrom: range.from.toISOString(),
68
+ dateTo: range.to.toISOString(),
69
+ ...eventFilter.values
70
+ }
71
+ });
72
+ const rows = mapRows(result);
73
+ if (rows.length === 0)
74
+ return null;
75
+ const lines = rows.map((row) => {
76
+ const name = asString(row.eventName) ?? "unknown";
77
+ const total = asNumber(row.total);
78
+ return `- ${name}: ${total}`;
79
+ });
80
+ return {
81
+ chunkId: `posthog:event_summary:${range.from.toISOString()}`,
82
+ text: [
83
+ `PostHog event summary (${range.from.toISOString()} \u2192 ${range.to.toISOString()}):`,
84
+ ...lines
85
+ ].join(`
86
+ `),
87
+ meta: {
88
+ source: "posthog",
89
+ kind: "event_summary",
90
+ dateFrom: range.from.toISOString(),
91
+ dateTo: range.to.toISOString()
92
+ }
93
+ };
94
+ }
95
+ async function loadFunnelEvidence(options, range) {
96
+ if (!options.funnel)
97
+ return null;
98
+ if (!options.reader.getEvents)
99
+ return null;
100
+ const events = [];
101
+ const eventNames = options.funnel.steps.map((step) => step.eventName);
102
+ for (const eventName of eventNames) {
103
+ const response = await options.reader.getEvents({
104
+ event: eventName,
105
+ dateRange: {
106
+ from: range.from,
107
+ to: range.to
108
+ },
109
+ limit: options.limit ?? 500
110
+ });
111
+ response.results.forEach((event) => {
112
+ events.push({
113
+ name: event.event,
114
+ userId: event.distinctId,
115
+ tenantId: typeof event.properties?.tenantId === "string" ? event.properties.tenantId : undefined,
116
+ timestamp: event.timestamp,
117
+ properties: event.properties
118
+ });
119
+ });
120
+ }
121
+ if (events.length === 0)
122
+ return null;
123
+ const analyzer = new FunnelAnalyzer;
124
+ const analysis = analyzer.analyze(events, options.funnel);
125
+ const lines = analysis.steps.map((step) => {
126
+ return `- ${step.step.eventName}: ${step.count} (conversion ${step.conversionRate}, drop-off ${step.dropOffRate})`;
127
+ });
128
+ return {
129
+ chunkId: `posthog:funnel:${options.funnel.name}`,
130
+ text: [`PostHog funnel analysis \u2014 ${options.funnel.name}:`, ...lines].join(`
131
+ `),
132
+ meta: {
133
+ source: "posthog",
134
+ kind: "funnel",
135
+ funnelName: options.funnel.name,
136
+ dateFrom: range.from.toISOString(),
137
+ dateTo: range.to.toISOString()
138
+ }
139
+ };
140
+ }
141
+ async function loadFeatureFlagEvidence(options) {
142
+ if (!options.includeFeatureFlags)
143
+ return null;
144
+ if (!options.reader.getFeatureFlags)
145
+ return null;
146
+ const response = await options.reader.getFeatureFlags({ limit: 10 });
147
+ if (!response.results.length)
148
+ return null;
149
+ const lines = response.results.map((flag) => {
150
+ const key = flag.key ?? "unknown";
151
+ const active = flag.active ? "active" : "inactive";
152
+ return `- ${key}: ${active}`;
153
+ });
154
+ return {
155
+ chunkId: "posthog:feature_flags",
156
+ text: ["PostHog feature flags:", ...lines].join(`
157
+ `),
158
+ meta: {
159
+ source: "posthog",
160
+ kind: "feature_flags"
161
+ }
162
+ };
163
+ }
164
+ function resolveRange(dateRange) {
165
+ const now = new Date;
166
+ const from = dateRange?.from instanceof Date ? dateRange.from : dateRange?.from ? new Date(dateRange.from) : new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
167
+ const to = dateRange?.to instanceof Date ? dateRange.to : dateRange?.to ? new Date(dateRange.to) : now;
168
+ return { from, to };
169
+ }
170
+ function buildEventFilter(eventNames) {
171
+ if (!eventNames || eventNames.length === 0)
172
+ return {};
173
+ if (eventNames.length === 1) {
174
+ return {
175
+ clause: "event = {event0}",
176
+ values: { event0: eventNames[0] }
177
+ };
178
+ }
179
+ const values = {};
180
+ const clauses = eventNames.map((eventName, index) => {
181
+ values[`event${index}`] = eventName;
182
+ return `event = {event${index}}`;
183
+ });
184
+ return {
185
+ clause: `(${clauses.join(" or ")})`,
186
+ values
187
+ };
188
+ }
189
+ function mapRows(result) {
190
+ if (!Array.isArray(result.results) || !Array.isArray(result.columns)) {
191
+ return [];
192
+ }
193
+ const columns = result.columns;
194
+ return result.results.flatMap((row) => {
195
+ if (!Array.isArray(row))
196
+ return [];
197
+ const record = {};
198
+ columns.forEach((column, index) => {
199
+ record[column] = row[index];
200
+ });
201
+ return [record];
202
+ });
203
+ }
204
+ function asString(value) {
205
+ if (typeof value === "string" && value.trim())
206
+ return value;
207
+ if (typeof value === "number")
208
+ return String(value);
209
+ return null;
210
+ }
211
+ function asNumber(value) {
212
+ if (typeof value === "number" && Number.isFinite(value))
213
+ return value;
214
+ if (typeof value === "string" && value.trim()) {
215
+ const parsed = Number(value);
216
+ if (Number.isFinite(parsed))
217
+ return parsed;
218
+ }
219
+ return 0;
220
+ }
221
+ function resolvePosthogEvidenceOptionsFromEnv(options = {}) {
222
+ const projectId = process.env.POSTHOG_PROJECT_ID;
223
+ const personalApiKey = process.env.POSTHOG_PERSONAL_API_KEY;
224
+ if (!projectId || !personalApiKey)
225
+ return null;
226
+ const lookbackDays = resolveNumberEnv("POSTHOG_EVIDENCE_LOOKBACK_DAYS", options.defaultLookbackDays ?? 30);
227
+ const limit = resolveNumberEnv("POSTHOG_EVIDENCE_LIMIT", options.defaultLimit ?? 10);
228
+ const now = new Date;
229
+ const from = new Date(now.getTime() - lookbackDays * 24 * 60 * 60 * 1000);
230
+ const eventNames = resolveCsvEnv("POSTHOG_EVIDENCE_EVENTS");
231
+ const funnelSteps = resolveCsvEnv("POSTHOG_EVIDENCE_FUNNEL_STEPS");
232
+ const funnel = funnelSteps && funnelSteps.length ? {
233
+ name: "posthog-evidence-funnel",
234
+ steps: funnelSteps.map((eventName, index) => ({
235
+ id: `step_${index + 1}`,
236
+ eventName
237
+ }))
238
+ } : undefined;
239
+ const reader = new PosthogAnalyticsProvider({
240
+ host: process.env.POSTHOG_HOST,
241
+ projectId,
242
+ personalApiKey
243
+ });
244
+ return {
245
+ reader,
246
+ dateRange: { from, to: now },
247
+ eventNames,
248
+ limit,
249
+ funnel,
250
+ includeFeatureFlags: resolveBooleanEnv("POSTHOG_EVIDENCE_FEATURE_FLAGS", true)
251
+ };
252
+ }
253
+ function resolveCsvEnv(key) {
254
+ const value = process.env[key];
255
+ if (!value)
256
+ return;
257
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
258
+ }
259
+ function resolveNumberEnv(key, fallback) {
260
+ const value = process.env[key];
261
+ if (!value)
262
+ return fallback;
263
+ const parsed = Number(value);
264
+ return Number.isFinite(parsed) ? parsed : fallback;
265
+ }
266
+ function resolveBooleanEnv(key, fallback) {
267
+ const value = process.env[key];
268
+ if (value === undefined)
269
+ return fallback;
270
+ return value.toLowerCase() === "true";
271
+ }
272
+
273
+ // src/load-evidence.ts
274
+ import fs from "fs";
275
+ import path from "path";
276
+ import { fileURLToPath } from "url";
277
+ var MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
278
+ var DEFAULT_EVIDENCE_ROOT = path.join(MODULE_DIR, "../evidence");
279
+ var DEFAULT_TRANSCRIPT_DIRS = ["interviews", "tickets", "public"];
280
+ var DEFAULT_CHUNK_SIZE = 800;
281
+ function stripYamlFrontMatter(contents) {
282
+ const start = contents.indexOf("---");
283
+ if (start === -1)
284
+ return contents;
285
+ const end = contents.indexOf("---", start + 3);
286
+ if (end === -1)
287
+ return contents;
288
+ return contents.slice(end + 3).trimStart();
289
+ }
290
+ function chunkTranscript(fileId, text, chunkSize) {
291
+ const chunks = [];
292
+ const clean = text.trim();
293
+ for (let offset = 0, idx = 0;offset < clean.length; idx += 1) {
294
+ const slice = clean.slice(offset, offset + chunkSize);
295
+ chunks.push({
296
+ chunkId: `${fileId}#c_${String(idx).padStart(2, "0")}`,
297
+ text: slice,
298
+ meta: { source: fileId }
299
+ });
300
+ offset += chunkSize;
301
+ }
302
+ return chunks;
303
+ }
304
+ function loadEvidenceChunks(options = {}) {
305
+ const evidenceRoot = options.evidenceRoot ?? DEFAULT_EVIDENCE_ROOT;
306
+ const transcriptDirs = options.transcriptDirs ?? DEFAULT_TRANSCRIPT_DIRS;
307
+ const chunkSize = options.chunkSize ?? DEFAULT_CHUNK_SIZE;
308
+ const chunks = [];
309
+ for (const dir of transcriptDirs) {
310
+ const fullDir = path.join(evidenceRoot, dir);
311
+ if (!fs.existsSync(fullDir))
312
+ continue;
313
+ for (const fileName of fs.readdirSync(fullDir)) {
314
+ const ext = path.extname(fileName).toLowerCase();
315
+ if (ext !== ".md")
316
+ continue;
317
+ const filePath = path.join(fullDir, fileName);
318
+ const raw = fs.readFileSync(filePath, "utf8");
319
+ const withoutFrontMatter = stripYamlFrontMatter(raw);
320
+ const baseId = path.parse(fileName).name;
321
+ const fileChunks = chunkTranscript(baseId, withoutFrontMatter, chunkSize);
322
+ chunks.push(...fileChunks);
323
+ }
324
+ }
325
+ return chunks;
326
+ }
327
+ async function loadEvidenceChunksWithSignals(options = {}) {
328
+ const baseChunks = loadEvidenceChunks(options);
329
+ if (!options.posthog)
330
+ return baseChunks;
331
+ const posthogChunks = await loadPosthogEvidenceChunks(options.posthog);
332
+ return [...baseChunks, ...posthogChunks];
333
+ }
334
+ export {
335
+ resolvePosthogEvidenceOptionsFromEnv,
336
+ loadPosthogEvidenceChunks,
337
+ loadEvidenceChunksWithSignals,
338
+ loadEvidenceChunks,
339
+ example_default as example,
340
+ DEFAULT_TRANSCRIPT_DIRS,
341
+ DEFAULT_EVIDENCE_ROOT,
342
+ DEFAULT_CHUNK_SIZE
343
+ };
@@ -1,24 +1,20 @@
1
- import { PosthogEvidenceOptions } from "./posthog-signals.js";
2
- import { EvidenceChunk } from "@contractspec/lib.contracts/product-intent/types";
3
-
4
- //#region src/load-evidence.d.ts
5
- declare const DEFAULT_EVIDENCE_ROOT: string;
6
- declare const DEFAULT_TRANSCRIPT_DIRS: string[];
7
- declare const DEFAULT_CHUNK_SIZE = 800;
8
- interface EvidenceLoadOptions {
9
- evidenceRoot?: string;
10
- transcriptDirs?: string[];
11
- chunkSize?: number;
1
+ import type { EvidenceChunk } from '@contractspec/lib.contracts/product-intent/types';
2
+ import type { PosthogEvidenceOptions } from './posthog-signals';
3
+ export declare const DEFAULT_EVIDENCE_ROOT: string;
4
+ export declare const DEFAULT_TRANSCRIPT_DIRS: string[];
5
+ export declare const DEFAULT_CHUNK_SIZE = 800;
6
+ export interface EvidenceLoadOptions {
7
+ evidenceRoot?: string;
8
+ transcriptDirs?: string[];
9
+ chunkSize?: number;
12
10
  }
13
- interface EvidenceLoadWithSignalsOptions extends EvidenceLoadOptions {
14
- posthog?: PosthogEvidenceOptions;
11
+ export interface EvidenceLoadWithSignalsOptions extends EvidenceLoadOptions {
12
+ posthog?: PosthogEvidenceOptions;
15
13
  }
16
14
  /**
17
15
  * Load all transcript files under the given directories and return
18
16
  * EvidenceChunk objects ready for prompt formatting.
19
17
  */
20
- declare function loadEvidenceChunks(options?: EvidenceLoadOptions): EvidenceChunk[];
21
- declare function loadEvidenceChunksWithSignals(options?: EvidenceLoadWithSignalsOptions): Promise<EvidenceChunk[]>;
22
- //#endregion
23
- export { DEFAULT_CHUNK_SIZE, DEFAULT_EVIDENCE_ROOT, DEFAULT_TRANSCRIPT_DIRS, EvidenceLoadOptions, EvidenceLoadWithSignalsOptions, loadEvidenceChunks, loadEvidenceChunksWithSignals };
18
+ export declare function loadEvidenceChunks(options?: EvidenceLoadOptions): EvidenceChunk[];
19
+ export declare function loadEvidenceChunksWithSignals(options?: EvidenceLoadWithSignalsOptions): Promise<EvidenceChunk[]>;
24
20
  //# sourceMappingURL=load-evidence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-evidence.d.ts","names":[],"sources":["../src/load-evidence.ts"],"mappings":";;;;cASa,qBAAA;AAAA,cACA,uBAAA;AAAA,cACA,kBAAA;AAAA,UAEI,mBAAA;EACf,YAAA;EACA,cAAA;EACA,SAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,mBAAA;EACtD,OAAA,GAAU,sBAAA;AAAA;;AATZ;;;iBAkDgB,kBAAA,CACd,OAAA,GAAS,mBAAA,GACR,aAAA;AAAA,iBAuBmB,6BAAA,CACpB,OAAA,GAAS,8BAAA,GACR,OAAA,CAAQ,aAAA"}
1
+ {"version":3,"file":"load-evidence.d.ts","sourceRoot":"","sources":["../src/load-evidence.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kDAAkD,CAAC;AACtF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAKhE,eAAO,MAAM,qBAAqB,QAAuC,CAAC;AAC1E,eAAO,MAAM,uBAAuB,UAAsC,CAAC;AAC3E,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,8BAA+B,SAAQ,mBAAmB;IACzE,OAAO,CAAC,EAAE,sBAAsB,CAAC;CAClC;AAoCD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,mBAAwB,GAChC,aAAa,EAAE,CAqBjB;AAED,wBAAsB,6BAA6B,CACjD,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,aAAa,EAAE,CAAC,CAK1B"}