@contractspec/example.product-intent 3.7.24 → 3.7.26

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.
@@ -2,25 +2,25 @@ $ contractspec-bun-build prebuild
2
2
  $ bun run build:bundle && bun run build:types
3
3
  $ contractspec-bun-build transpile
4
4
  [contractspec-bun-build] transpile target=bun root=src entries=10 noBundle=false
5
- Bundled 10 modules in 22ms
5
+ Bundled 10 modules in 34ms
6
6
 
7
7
  docs/index.js 1.23 KB (entry point)
8
8
  ./script.js 9.32 KB (entry point)
9
- ./sync-actions.js 9.22 KB (entry point)
9
+ ./sync-actions.js 9.26 KB (entry point)
10
10
  docs/product-intent.docblock.js 1.23 KB (entry point)
11
11
  ./index.js 8.91 KB (entry point)
12
12
  ./example.js 0.65 KB (entry point)
13
- ./load-evidence.js 5.33 KB (entry point)
13
+ ./load-evidence.js 5.34 KB (entry point)
14
14
  ./posthog-signals.js 4.34 KB (entry point)
15
15
  ./product-intent.discovery.js 2.44 KB (entry point)
16
16
  ./product-intent.feature.js 470 bytes (entry point)
17
17
 
18
18
  [contractspec-bun-build] transpile target=node root=src entries=10 noBundle=false
19
- Bundled 10 modules in 43ms
19
+ Bundled 10 modules in 26ms
20
20
 
21
21
  docs/index.js 1.22 KB (entry point)
22
22
  ./script.js 9.33 KB (entry point)
23
- ./sync-actions.js 9.22 KB (entry point)
23
+ ./sync-actions.js 9.26 KB (entry point)
24
24
  docs/product-intent.docblock.js 1.22 KB (entry point)
25
25
  ./index.js 8.91 KB (entry point)
26
26
  ./example.js 0.64 KB (entry point)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # @contractspec/example.product-intent
2
2
 
3
+ ## 3.7.26
4
+
5
+ ### Patch Changes
6
+
7
+ - chore: auto-bump internal dependents
8
+ - Updated dependencies because of chore: auto-bump internal dependents
9
+ - Updated dependencies because of Remove avoidable Node crypto imports from ContractSpec runtime surfaces and keep signing helpers isolated.
10
+ - Updated dependencies because of Improve FormSpec autocomplete rendering and resolver-backed search.
11
+ - Updated dependencies because of Add first-class FormSpec email fields with native renderer affordances.
12
+ - Updated dependencies because of Add progressive FormSpec section and step layout metadata with shared React and design-system rendering support.
13
+ - @contractspec/integration.provider.analytics@0.2.1
14
+ - @contractspec/integration.provider.project-management@0.2.1
15
+ - @contractspec/lib.ai-agent@8.0.13
16
+ - @contractspec/lib.analytics@3.7.25
17
+ - @contractspec/lib.contracts-integrations@3.8.17
18
+ - @contractspec/lib.product-intent-utils@3.7.25
19
+ - @contractspec/lib.contracts-spec@6.0.0
20
+
21
+ ## 3.7.25
22
+
23
+ ### Patch Changes
24
+
25
+ - Split provider implementations into targeted integration packages while preserving the legacy providers-impls facade.
26
+ - Packages: @contractspec/integration.providers-impls (minor), @contractspec/integration.provider.analytics (minor), @contractspec/integration.provider.calendar (minor), @contractspec/integration.provider.database (minor), @contractspec/integration.provider.email (minor), @contractspec/integration.provider.embedding (minor), @contractspec/integration.provider.health (minor), @contractspec/integration.provider.llm (minor), @contractspec/integration.provider.meeting-recorder (minor), @contractspec/integration.provider.messaging (minor), @contractspec/integration.provider.openbanking (minor), @contractspec/integration.provider.payments (minor), @contractspec/integration.provider.project-management (minor), @contractspec/integration.provider.sms (minor), @contractspec/integration.provider.storage (minor), @contractspec/integration.provider.vector-store (minor), @contractspec/integration.provider.voice (minor), @contractspec/app.api-library (patch), @contractspec/example.calendar-google (patch), @contractspec/example.email-gmail (patch), @contractspec/example.integration-posthog (patch), @contractspec/example.meeting-recorder-providers (patch), @contractspec/example.openbanking-powens (patch), @contractspec/example.product-intent (patch), @contractspec/example.project-management-sync (patch), @contractspec/example.voice-providers (patch)
27
+ - Migration: Replace direct provider imports such as `@contractspec/integration.providers-impls/impls/gmail-inbound` with targeted packages such as `@contractspec/integration.provider.email/impls/gmail-inbound`.; Continue importing `IntegrationProviderFactory` from `@contractspec/integration.providers-impls/impls/provider-factory` when you need broad provider routing.
28
+ - Updated dependencies because of chore: auto-bump internal dependents
29
+ - Updated dependencies because of Add mobile-safe FormSpec layout helpers and scoped DataView filters.
30
+
31
+ FormSpec authors can now use `responsiveFormColumns(...)` for explicit mobile-first column metadata without changing legacy numeric `layout.columns` behavior. DataView contracts can declare `filterScope.initial` and `filterScope.locked` filters so generic list/search contracts can be reused in context-restricted screens while keeping locked constraints out of user-editable URL state.
32
+
33
+ - Updated dependencies because of Add OSS harness CLI verification with deterministic Playwright, optional agent-browser visual runs, auth profile refs, visual diff evidence, replay bundles, and core scenario success semantics.
34
+ - Updated dependencies because of Split provider implementations into targeted integration packages while preserving the legacy providers-impls facade.
35
+ - @contractspec/lib.ai-agent@8.0.12
36
+ - @contractspec/lib.analytics@3.7.24
37
+ - @contractspec/lib.contracts-integrations@3.8.16
38
+ - @contractspec/lib.product-intent-utils@3.7.24
39
+ - @contractspec/lib.contracts-spec@5.7.0
40
+ - @contractspec/integration.provider.analytics@0.2.0
41
+ - @contractspec/integration.provider.project-management@0.2.0
42
+
3
43
  ## 3.7.24
4
44
 
5
45
  ### Patch Changes
package/README.md CHANGED
@@ -74,4 +74,4 @@ Use `@contractspec/example.product-intent` as a reference implementation, or imp
74
74
 
75
75
  ## Notes
76
76
 
77
- - Works alongside `@contractspec/integration.providers-impls`, `@contractspec/lib.ai-agent`, `@contractspec/lib.analytics`, `@contractspec/lib.contracts-integrations`, `@contractspec/lib.contracts-spec`, ...
77
+ - Works alongside `@contractspec/integration.provider.analytics`, `@contractspec/integration.provider.project-management`, `@contractspec/lib.ai-agent`, `@contractspec/lib.analytics`, `@contractspec/lib.contracts-integrations`, `@contractspec/lib.contracts-spec`, ...
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{defineExample as C}from"@contractspec/lib.contracts-spec/examples";var D=C({meta:{key:"examples.product-intent",version:"1.0.0",title:"Product Intent",description:"Product intent example: evidence ingestion and prompt-ready outputs.",kind:"template",visibility:"experimental",stability:"experimental",owners:["@contractspec-core"],tags:["package","examples","product-intent"]},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["playground","specs"]},studio:{enabled:!1,installable:!1},mcp:{enabled:!1}},entrypoints:{packageName:"@contractspec/example.product-intent"}}),x=D;import{PosthogAnalyticsProvider as I}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as F}from"@contractspec/lib.analytics/funnel";async function Y(O){let W=[],q=w(O.dateRange),G=await S(O,q);if(G)W.push(G);let H=await E(O,q);if(H)W.push(H);let J=await y(O);if(J)W.push(J);return W}async function S(O,W){if(!O.reader.queryHogQL)return null;let q=b(O.eventNames),G=O.limit??10,H=await O.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",q.clause?`and ${q.clause}`:"","group by eventName","order by total desc",`limit ${G}`].filter(Boolean).join(`
2
+ import{defineExample as C}from"@contractspec/lib.contracts-spec/examples";var D=C({meta:{key:"examples.product-intent",version:"1.0.0",title:"Product Intent",description:"Product intent example: evidence ingestion and prompt-ready outputs.",kind:"template",visibility:"experimental",stability:"experimental",owners:["@contractspec-core"],tags:["package","examples","product-intent"]},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["playground","specs"]},studio:{enabled:!1,installable:!1},mcp:{enabled:!1}},entrypoints:{packageName:"@contractspec/example.product-intent"}}),x=D;import{PosthogAnalyticsProvider as I}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as F}from"@contractspec/lib.analytics/funnel";async function Y(O){let W=[],q=w(O.dateRange),G=await S(O,q);if(G)W.push(G);let H=await E(O,q);if(H)W.push(H);let J=await y(O);if(J)W.push(J);return W}async function S(O,W){if(!O.reader.queryHogQL)return null;let q=b(O.eventNames),G=O.limit??10,H=await O.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",q.clause?`and ${q.clause}`:"","group by eventName","order by total desc",`limit ${G}`].filter(Boolean).join(`
3
3
  `),values:{dateFrom:W.from.toISOString(),dateTo:W.to.toISOString(),...q.values}}),J=R(H);if(J.length===0)return null;let V=J.map((Q)=>{let Z=N(Q.eventName)??"unknown",X=h(Q.total);return`- ${Z}: ${X}`});return{chunkId:`posthog:event_summary:${W.from.toISOString()}`,text:[`PostHog event summary (${W.from.toISOString()} \u2192 ${W.to.toISOString()}):`,...V].join(`
4
4
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:W.from.toISOString(),dateTo:W.to.toISOString()}}}async function E(O,W){if(!O.funnel)return null;if(!O.reader.getEvents)return null;let q=[],G=O.funnel.steps.map((Q)=>Q.eventName);for(let Q of G)(await O.reader.getEvents({event:Q,dateRange:{from:W.from,to:W.to},limit:O.limit??500})).results.forEach((X)=>{q.push({name:X.event,userId:X.distinctId,tenantId:typeof X.properties?.tenantId==="string"?X.properties.tenantId:void 0,timestamp:X.timestamp,properties:X.properties})});if(q.length===0)return null;let V=new F().analyze(q,O.funnel).steps.map((Q)=>{return`- ${Q.step.eventName}: ${Q.count} (conversion ${Q.conversionRate}, drop-off ${Q.dropOffRate})`});return{chunkId:`posthog:funnel:${O.funnel.name}`,text:[`PostHog funnel analysis \u2014 ${O.funnel.name}:`,...V].join(`
5
5
  `),meta:{source:"posthog",kind:"funnel",funnelName:O.funnel.name,dateFrom:W.from.toISOString(),dateTo:W.to.toISOString()}}}async function y(O){if(!O.includeFeatureFlags)return null;if(!O.reader.getFeatureFlags)return null;let W=await O.reader.getFeatureFlags({limit:10});if(!W.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...W.results.map((G)=>{let H=G.key??"unknown",J=G.active?"active":"inactive";return`- ${H}: ${J}`})].join(`
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{PosthogAnalyticsProvider as U}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as _}from"@contractspec/lib.analytics/funnel";async function L(q){let G=[],J=C(q.dateRange),Q=await A(q,J);if(Q)G.push(Q);let W=await T(q,J);if(W)G.push(W);let X=await x(q);if(X)G.push(X);return G}async function A(q,G){if(!q.reader.queryHogQL)return null;let J=D(q.eventNames),Q=q.limit??10,W=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",J.clause?`and ${J.clause}`:"","group by eventName","order by total desc",`limit ${Q}`].filter(Boolean).join(`
2
+ import{PosthogAnalyticsProvider as U}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as _}from"@contractspec/lib.analytics/funnel";async function L(q){let G=[],J=C(q.dateRange),Q=await A(q,J);if(Q)G.push(Q);let W=await T(q,J);if(W)G.push(W);let X=await x(q);if(X)G.push(X);return G}async function A(q,G){if(!q.reader.queryHogQL)return null;let J=D(q.eventNames),Q=q.limit??10,W=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",J.clause?`and ${J.clause}`:"","group by eventName","order by total desc",`limit ${Q}`].filter(Boolean).join(`
3
3
  `),values:{dateFrom:G.from.toISOString(),dateTo:G.to.toISOString(),...J.values}}),X=I(W);if(X.length===0)return null;let B=X.map(($)=>{let V=F($.eventName)??"unknown",H=S($.total);return`- ${V}: ${H}`});return{chunkId:`posthog:event_summary:${G.from.toISOString()}`,text:[`PostHog event summary (${G.from.toISOString()} \u2192 ${G.to.toISOString()}):`,...B].join(`
4
4
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function T(q,G){if(!q.funnel)return null;if(!q.reader.getEvents)return null;let J=[],Q=q.funnel.steps.map(($)=>$.eventName);for(let $ of Q)(await q.reader.getEvents({event:$,dateRange:{from:G.from,to:G.to},limit:q.limit??500})).results.forEach((H)=>{J.push({name:H.event,userId:H.distinctId,tenantId:typeof H.properties?.tenantId==="string"?H.properties.tenantId:void 0,timestamp:H.timestamp,properties:H.properties})});if(J.length===0)return null;let B=new _().analyze(J,q.funnel).steps.map(($)=>{return`- ${$.step.eventName}: ${$.count} (conversion ${$.conversionRate}, drop-off ${$.dropOffRate})`});return{chunkId:`posthog:funnel:${q.funnel.name}`,text:[`PostHog funnel analysis \u2014 ${q.funnel.name}:`,...B].join(`
5
5
  `),meta:{source:"posthog",kind:"funnel",funnelName:q.funnel.name,dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function x(q){if(!q.includeFeatureFlags)return null;if(!q.reader.getFeatureFlags)return null;let G=await q.reader.getFeatureFlags({limit:10});if(!G.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...G.results.map((Q)=>{let W=Q.key??"unknown",X=Q.active?"active":"inactive";return`- ${W}: ${X}`})].join(`
@@ -1,4 +1,4 @@
1
- import{defineExample as C}from"@contractspec/lib.contracts-spec/examples";var D=C({meta:{key:"examples.product-intent",version:"1.0.0",title:"Product Intent",description:"Product intent example: evidence ingestion and prompt-ready outputs.",kind:"template",visibility:"experimental",stability:"experimental",owners:["@contractspec-core"],tags:["package","examples","product-intent"]},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["playground","specs"]},studio:{enabled:!1,installable:!1},mcp:{enabled:!1}},entrypoints:{packageName:"@contractspec/example.product-intent"}}),x=D;import{PosthogAnalyticsProvider as I}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as F}from"@contractspec/lib.analytics/funnel";async function Y(O){let W=[],q=w(O.dateRange),G=await S(O,q);if(G)W.push(G);let H=await E(O,q);if(H)W.push(H);let J=await y(O);if(J)W.push(J);return W}async function S(O,W){if(!O.reader.queryHogQL)return null;let q=b(O.eventNames),G=O.limit??10,H=await O.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",q.clause?`and ${q.clause}`:"","group by eventName","order by total desc",`limit ${G}`].filter(Boolean).join(`
1
+ import{defineExample as C}from"@contractspec/lib.contracts-spec/examples";var D=C({meta:{key:"examples.product-intent",version:"1.0.0",title:"Product Intent",description:"Product intent example: evidence ingestion and prompt-ready outputs.",kind:"template",visibility:"experimental",stability:"experimental",owners:["@contractspec-core"],tags:["package","examples","product-intent"]},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["playground","specs"]},studio:{enabled:!1,installable:!1},mcp:{enabled:!1}},entrypoints:{packageName:"@contractspec/example.product-intent"}}),x=D;import{PosthogAnalyticsProvider as I}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as F}from"@contractspec/lib.analytics/funnel";async function Y(O){let W=[],q=w(O.dateRange),G=await S(O,q);if(G)W.push(G);let H=await E(O,q);if(H)W.push(H);let J=await y(O);if(J)W.push(J);return W}async function S(O,W){if(!O.reader.queryHogQL)return null;let q=b(O.eventNames),G=O.limit??10,H=await O.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",q.clause?`and ${q.clause}`:"","group by eventName","order by total desc",`limit ${G}`].filter(Boolean).join(`
2
2
  `),values:{dateFrom:W.from.toISOString(),dateTo:W.to.toISOString(),...q.values}}),J=R(H);if(J.length===0)return null;let V=J.map((Q)=>{let Z=N(Q.eventName)??"unknown",X=h(Q.total);return`- ${Z}: ${X}`});return{chunkId:`posthog:event_summary:${W.from.toISOString()}`,text:[`PostHog event summary (${W.from.toISOString()} → ${W.to.toISOString()}):`,...V].join(`
3
3
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:W.from.toISOString(),dateTo:W.to.toISOString()}}}async function E(O,W){if(!O.funnel)return null;if(!O.reader.getEvents)return null;let q=[],G=O.funnel.steps.map((Q)=>Q.eventName);for(let Q of G)(await O.reader.getEvents({event:Q,dateRange:{from:W.from,to:W.to},limit:O.limit??500})).results.forEach((X)=>{q.push({name:X.event,userId:X.distinctId,tenantId:typeof X.properties?.tenantId==="string"?X.properties.tenantId:void 0,timestamp:X.timestamp,properties:X.properties})});if(q.length===0)return null;let V=new F().analyze(q,O.funnel).steps.map((Q)=>{return`- ${Q.step.eventName}: ${Q.count} (conversion ${Q.conversionRate}, drop-off ${Q.dropOffRate})`});return{chunkId:`posthog:funnel:${O.funnel.name}`,text:[`PostHog funnel analysis — ${O.funnel.name}:`,...V].join(`
4
4
  `),meta:{source:"posthog",kind:"funnel",funnelName:O.funnel.name,dateFrom:W.from.toISOString(),dateTo:W.to.toISOString()}}}async function y(O){if(!O.includeFeatureFlags)return null;if(!O.reader.getFeatureFlags)return null;let W=await O.reader.getFeatureFlags({limit:10});if(!W.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...W.results.map((G)=>{let H=G.key??"unknown",J=G.active?"active":"inactive";return`- ${H}: ${J}`})].join(`
@@ -1,4 +1,4 @@
1
- import{PosthogAnalyticsProvider as U}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as _}from"@contractspec/lib.analytics/funnel";async function L(q){let G=[],J=C(q.dateRange),Q=await A(q,J);if(Q)G.push(Q);let W=await T(q,J);if(W)G.push(W);let X=await x(q);if(X)G.push(X);return G}async function A(q,G){if(!q.reader.queryHogQL)return null;let J=D(q.eventNames),Q=q.limit??10,W=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",J.clause?`and ${J.clause}`:"","group by eventName","order by total desc",`limit ${Q}`].filter(Boolean).join(`
1
+ import{PosthogAnalyticsProvider as U}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as _}from"@contractspec/lib.analytics/funnel";async function L(q){let G=[],J=C(q.dateRange),Q=await A(q,J);if(Q)G.push(Q);let W=await T(q,J);if(W)G.push(W);let X=await x(q);if(X)G.push(X);return G}async function A(q,G){if(!q.reader.queryHogQL)return null;let J=D(q.eventNames),Q=q.limit??10,W=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",J.clause?`and ${J.clause}`:"","group by eventName","order by total desc",`limit ${Q}`].filter(Boolean).join(`
2
2
  `),values:{dateFrom:G.from.toISOString(),dateTo:G.to.toISOString(),...J.values}}),X=I(W);if(X.length===0)return null;let B=X.map(($)=>{let V=F($.eventName)??"unknown",H=S($.total);return`- ${V}: ${H}`});return{chunkId:`posthog:event_summary:${G.from.toISOString()}`,text:[`PostHog event summary (${G.from.toISOString()} → ${G.to.toISOString()}):`,...B].join(`
3
3
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function T(q,G){if(!q.funnel)return null;if(!q.reader.getEvents)return null;let J=[],Q=q.funnel.steps.map(($)=>$.eventName);for(let $ of Q)(await q.reader.getEvents({event:$,dateRange:{from:G.from,to:G.to},limit:q.limit??500})).results.forEach((H)=>{J.push({name:H.event,userId:H.distinctId,tenantId:typeof H.properties?.tenantId==="string"?H.properties.tenantId:void 0,timestamp:H.timestamp,properties:H.properties})});if(J.length===0)return null;let B=new _().analyze(J,q.funnel).steps.map(($)=>{return`- ${$.step.eventName}: ${$.count} (conversion ${$.conversionRate}, drop-off ${$.dropOffRate})`});return{chunkId:`posthog:funnel:${q.funnel.name}`,text:[`PostHog funnel analysis — ${q.funnel.name}:`,...B].join(`
4
4
  `),meta:{source:"posthog",kind:"funnel",funnelName:q.funnel.name,dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function x(q){if(!q.includeFeatureFlags)return null;if(!q.reader.getFeatureFlags)return null;let G=await q.reader.getFeatureFlags({limit:10});if(!G.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...G.results.map((Q)=>{let W=Q.key??"unknown",X=Q.active?"active":"inactive";return`- ${W}: ${X}`})].join(`
@@ -1,4 +1,4 @@
1
- import{PosthogAnalyticsProvider as Z}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as _}from"@contractspec/lib.analytics/funnel";async function x(q){let G=[],H=D(q.dateRange),J=await $(q,H);if(J)G.push(J);let L=await z(q,H);if(L)G.push(L);let M=await B(q);if(M)G.push(M);return G}async function $(q,G){if(!q.reader.queryHogQL)return null;let H=j(q.eventNames),J=q.limit??10,L=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",H.clause?`and ${H.clause}`:"","group by eventName","order by total desc",`limit ${J}`].filter(Boolean).join(`
1
+ import{PosthogAnalyticsProvider as Z}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as _}from"@contractspec/lib.analytics/funnel";async function x(q){let G=[],H=D(q.dateRange),J=await $(q,H);if(J)G.push(J);let L=await z(q,H);if(L)G.push(L);let M=await B(q);if(M)G.push(M);return G}async function $(q,G){if(!q.reader.queryHogQL)return null;let H=j(q.eventNames),J=q.limit??10,L=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",H.clause?`and ${H.clause}`:"","group by eventName","order by total desc",`limit ${J}`].filter(Boolean).join(`
2
2
  `),values:{dateFrom:G.from.toISOString(),dateTo:G.to.toISOString(),...H.values}}),M=C(L);if(M.length===0)return null;let U=M.map((O)=>{let T=I(O.eventName)??"unknown",Q=K(O.total);return`- ${T}: ${Q}`});return{chunkId:`posthog:event_summary:${G.from.toISOString()}`,text:[`PostHog event summary (${G.from.toISOString()} → ${G.to.toISOString()}):`,...U].join(`
3
3
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function z(q,G){if(!q.funnel)return null;if(!q.reader.getEvents)return null;let H=[],J=q.funnel.steps.map((O)=>O.eventName);for(let O of J)(await q.reader.getEvents({event:O,dateRange:{from:G.from,to:G.to},limit:q.limit??500})).results.forEach((Q)=>{H.push({name:Q.event,userId:Q.distinctId,tenantId:typeof Q.properties?.tenantId==="string"?Q.properties.tenantId:void 0,timestamp:Q.timestamp,properties:Q.properties})});if(H.length===0)return null;let U=new _().analyze(H,q.funnel).steps.map((O)=>{return`- ${O.step.eventName}: ${O.count} (conversion ${O.conversionRate}, drop-off ${O.dropOffRate})`});return{chunkId:`posthog:funnel:${q.funnel.name}`,text:[`PostHog funnel analysis — ${q.funnel.name}:`,...U].join(`
4
4
  `),meta:{source:"posthog",kind:"funnel",funnelName:q.funnel.name,dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function B(q){if(!q.includeFeatureFlags)return null;if(!q.reader.getFeatureFlags)return null;let G=await q.reader.getFeatureFlags({limit:10});if(!G.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...G.results.map((J)=>{let L=J.key??"unknown",M=J.active?"active":"inactive";return`- ${L}: ${M}`})].join(`
@@ -1,4 +1,4 @@
1
- import{PosthogAnalyticsProvider as E}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as h}from"@contractspec/lib.analytics/funnel";async function w(q){let G=[],$=c(q.dateRange),B=await f(q,$);if(B)G.push(B);let H=await m(q,$);if(H)G.push(H);let J=await g(q);if(J)G.push(J);return G}async function f(q,G){if(!q.reader.queryHogQL)return null;let $=d(q.eventNames),B=q.limit??10,H=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",$.clause?`and ${$.clause}`:"","group by eventName","order by total desc",`limit ${B}`].filter(Boolean).join(`
1
+ import{PosthogAnalyticsProvider as E}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as h}from"@contractspec/lib.analytics/funnel";async function w(q){let G=[],$=c(q.dateRange),B=await f(q,$);if(B)G.push(B);let H=await m(q,$);if(H)G.push(H);let J=await g(q);if(J)G.push(J);return G}async function f(q,G){if(!q.reader.queryHogQL)return null;let $=d(q.eventNames),B=q.limit??10,H=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",$.clause?`and ${$.clause}`:"","group by eventName","order by total desc",`limit ${B}`].filter(Boolean).join(`
2
2
  `),values:{dateFrom:G.from.toISOString(),dateTo:G.to.toISOString(),...$.values}}),J=u(H);if(J.length===0)return null;let Z=J.map((W)=>{let V=v(W.eventName)??"unknown",Y=p(W.total);return`- ${V}: ${Y}`});return{chunkId:`posthog:event_summary:${G.from.toISOString()}`,text:[`PostHog event summary (${G.from.toISOString()} → ${G.to.toISOString()}):`,...Z].join(`
3
3
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function m(q,G){if(!q.funnel)return null;if(!q.reader.getEvents)return null;let $=[],B=q.funnel.steps.map((W)=>W.eventName);for(let W of B)(await q.reader.getEvents({event:W,dateRange:{from:G.from,to:G.to},limit:q.limit??500})).results.forEach((Y)=>{$.push({name:Y.event,userId:Y.distinctId,tenantId:typeof Y.properties?.tenantId==="string"?Y.properties.tenantId:void 0,timestamp:Y.timestamp,properties:Y.properties})});if($.length===0)return null;let Z=new h().analyze($,q.funnel).steps.map((W)=>{return`- ${W.step.eventName}: ${W.count} (conversion ${W.conversionRate}, drop-off ${W.dropOffRate})`});return{chunkId:`posthog:funnel:${q.funnel.name}`,text:[`PostHog funnel analysis — ${q.funnel.name}:`,...Z].join(`
4
4
  `),meta:{source:"posthog",kind:"funnel",funnelName:q.funnel.name,dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function g(q){if(!q.includeFeatureFlags)return null;if(!q.reader.getFeatureFlags)return null;let G=await q.reader.getFeatureFlags({limit:10});if(!G.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...G.results.map((B)=>{let H=B.key??"unknown",J=B.active?"active":"inactive";return`- ${H}: ${J}`})].join(`
@@ -1,5 +1,5 @@
1
- import{PosthogAnalyticsProvider as I}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as x}from"@contractspec/lib.analytics/funnel";async function D(q){let G=[],Q=w(q.dateRange),W=await b(q,Q);if(W)G.push(W);let $=await S(q,Q);if($)G.push($);let X=await E(q);if(X)G.push(X);return G}async function b(q,G){if(!q.reader.queryHogQL)return null;let Q=N(q.eventNames),W=q.limit??10,$=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",Q.clause?`and ${Q.clause}`:"","group by eventName","order by total desc",`limit ${W}`].filter(Boolean).join(`
1
+ import{PosthogAnalyticsProvider as I}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as x}from"@contractspec/lib.analytics/funnel";async function D(q){let G=[],Q=w(q.dateRange),W=await b(q,Q);if(W)G.push(W);let $=await S(q,Q);if($)G.push($);let X=await E(q);if(X)G.push(X);return G}async function b(q,G){if(!q.reader.queryHogQL)return null;let Q=N(q.eventNames),W=q.limit??10,$=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",Q.clause?`and ${Q.clause}`:"","group by eventName","order by total desc",`limit ${W}`].filter(Boolean).join(`
2
2
  `),values:{dateFrom:G.from.toISOString(),dateTo:G.to.toISOString(),...Q.values}}),X=R($);if(X.length===0)return null;let H=X.map((B)=>{let V=h(B.eventName)??"unknown",J=k(B.total);return`- ${V}: ${J}`});return{chunkId:`posthog:event_summary:${G.from.toISOString()}`,text:[`PostHog event summary (${G.from.toISOString()} → ${G.to.toISOString()}):`,...H].join(`
3
3
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function S(q,G){if(!q.funnel)return null;if(!q.reader.getEvents)return null;let Q=[],W=q.funnel.steps.map((B)=>B.eventName);for(let B of W)(await q.reader.getEvents({event:B,dateRange:{from:G.from,to:G.to},limit:q.limit??500})).results.forEach((J)=>{Q.push({name:J.event,userId:J.distinctId,tenantId:typeof J.properties?.tenantId==="string"?J.properties.tenantId:void 0,timestamp:J.timestamp,properties:J.properties})});if(Q.length===0)return null;let H=new x().analyze(Q,q.funnel).steps.map((B)=>{return`- ${B.step.eventName}: ${B.count} (conversion ${B.conversionRate}, drop-off ${B.dropOffRate})`});return{chunkId:`posthog:funnel:${q.funnel.name}`,text:[`PostHog funnel analysis — ${q.funnel.name}:`,...H].join(`
4
4
  `),meta:{source:"posthog",kind:"funnel",funnelName:q.funnel.name,dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function E(q){if(!q.includeFeatureFlags)return null;if(!q.reader.getFeatureFlags)return null;let G=await q.reader.getFeatureFlags({limit:10});if(!G.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...G.results.map((W)=>{let $=W.key??"unknown",X=W.active?"active":"inactive";return`- ${$}: ${X}`})].join(`
5
- `),meta:{source:"posthog",kind:"feature_flags"}}}function w(q){let G=new Date,Q=q?.from instanceof Date?q.from:q?.from?new Date(q.from):new Date(G.getTime()-2592000000),W=q?.to instanceof Date?q.to:q?.to?new Date(q.to):G;return{from:Q,to:W}}function N(q){if(!q||q.length===0)return{};if(q.length===1)return{clause:"event = {event0}",values:{event0:q[0]}};let G={};return{clause:`(${q.map((W,$)=>{return G[`event${$}`]=W,`event = {event${$}}`}).join(" or ")})`,values:G}}function R(q){if(!Array.isArray(q.results)||!Array.isArray(q.columns))return[];let G=q.columns;return q.results.flatMap((Q)=>{if(!Array.isArray(Q))return[];let W={};return G.forEach(($,X)=>{W[$]=Q[X]}),[W]})}function h(q){if(typeof q==="string"&&q.trim())return q;if(typeof q==="number")return String(q);return null}function k(q){if(typeof q==="number"&&Number.isFinite(q))return q;if(typeof q==="string"&&q.trim()){let G=Number(q);if(Number.isFinite(G))return G}return 0}function L(q={}){let G=process.env.POSTHOG_PROJECT_ID,Q=process.env.POSTHOG_PERSONAL_API_KEY;if(!G||!Q)return null;let W=z("POSTHOG_EVIDENCE_LOOKBACK_DAYS",q.defaultLookbackDays??30),$=z("POSTHOG_EVIDENCE_LIMIT",q.defaultLimit??10),X=new Date,H=new Date(X.getTime()-W*24*60*60*1000),B=U("POSTHOG_EVIDENCE_EVENTS"),V=U("POSTHOG_EVIDENCE_FUNNEL_STEPS"),J=V&&V.length?{name:"posthog-evidence-funnel",steps:V.map((K,M)=>({id:`step_${M+1}`,eventName:K}))}:void 0;return{reader:new I({host:process.env.POSTHOG_HOST,projectId:G,personalApiKey:Q}),dateRange:{from:H,to:X},eventNames:B,limit:$,funnel:J,includeFeatureFlags:y("POSTHOG_EVIDENCE_FEATURE_FLAGS",!0)}}function U(q){let G=process.env[q];if(!G)return;return G.split(",").map((Q)=>Q.trim()).filter(Boolean)}function z(q,G){let Q=process.env[q];if(!Q)return G;let W=Number(Q);return Number.isFinite(W)?W:G}function y(q,G){let Q=process.env[q];if(Q===void 0)return G;return Q.toLowerCase()==="true"}import _ from"node:fs";import Y from"node:path";import{fileURLToPath as f}from"node:url";var m=Y.dirname(f(import.meta.url)),g=Y.join(m,"../evidence"),c=["interviews","tickets","public"],u=800;function d(q){let G=q.indexOf("---");if(G===-1)return q;let Q=q.indexOf("---",G+3);if(Q===-1)return q;return q.slice(Q+3).trimStart()}function v(q,G,Q){let W=[],$=G.trim();for(let X=0,H=0;X<$.length;H+=1){let B=$.slice(X,X+Q);W.push({chunkId:`${q}#c_${String(H).padStart(2,"0")}`,text:B,meta:{source:q}}),X+=Q}return W}function p(q={}){let G=q.evidenceRoot??g,Q=q.transcriptDirs??c,W=q.chunkSize??u,$=[];for(let X of Q){let H=Y.join(G,X);if(!_.existsSync(H))continue;for(let B of _.readdirSync(H)){if(Y.extname(B).toLowerCase()!==".md")continue;let J=Y.join(H,B),T=_.readFileSync(J,"utf8"),K=d(T),M=Y.parse(B).name,F=v(M,K,W);$.push(...F)}}return $}async function P(q={}){let G=p(q);if(!q.posthog)return G;let Q=await D(q.posthog);return[...G,...Q]}import{JiraProjectManagementProvider as l}from"@contractspec/integration.providers-impls/impls/jira";import{LinearProjectManagementProvider as i}from"@contractspec/integration.providers-impls/impls/linear";import{NotionProjectManagementProvider as r}from"@contractspec/integration.providers-impls/impls/notion";import{createAgentJsonRunner as s}from"@contractspec/lib.ai-agent/agent/json-runner";import{buildProjectManagementSyncPayload as o,extractEvidence as a,generateTickets as t,groupProblems as n,impactEngine as e,suggestPatch as qq}from"@contractspec/lib.product-intent-utils";var O="Which activation and onboarding friction should we prioritize next?";function Gq(){let q=(process.env.CONTRACTSPEC_PM_PROVIDER??"").toLowerCase();if(q==="linear"||q==="jira"||q==="notion")return q;throw Error("Set CONTRACTSPEC_PM_PROVIDER to one of: linear, jira, notion")}async function Qq(){let q=Wq(),G=Xq(q),Q=process.env.CONTRACTSPEC_AI_PROXY_URL,W=process.env.CONTRACTSPEC_ORG_ID,$=process.env.OLLAMA_BASE_URL,X=process.env.CONTRACTSPEC_AI_MODEL??process.env.AI_MODEL??void 0;if(q!=="ollama"&&!G&&!Q&&!W)throw Error(`Missing API credentials for ${q}. Set provider API key or CONTRACTSPEC_AI_PROXY_URL.`);return s({provider:{provider:q,model:X,apiKey:G,baseUrl:$,proxyUrl:Q,organizationId:W},temperature:0,system:"You are a product discovery analyst. Respond with strict JSON only and use exact quotes for citations."})}function Wq(){let q=process.env.CONTRACTSPEC_AI_PROVIDER??process.env.AI_PROVIDER??"openai",G=q.toLowerCase(),Q=["openai","anthropic","mistral","gemini","ollama"];if(!Q.includes(G))throw Error(`Unsupported AI provider: ${q}. Use one of: ${Q.join(", ")}`);return G}function Xq(q){switch(q.toLowerCase()){case"openai":return process.env.OPENAI_API_KEY;case"anthropic":return process.env.ANTHROPIC_API_KEY;case"mistral":return process.env.MISTRAL_API_KEY;case"gemini":return process.env.GOOGLE_API_KEY??process.env.GEMINI_API_KEY;case"ollama":return;default:return}}function j(){return{log:()=>{return}}}async function $q(){let q=Gq(),G=await Qq(),Q=await P({posthog:L()??void 0}),W=await a(Q,O,{modelRunner:G,logger:j(),maxAttempts:2}),$=await n(W,O,{modelRunner:G,logger:j(),maxAttempts:2}),X=await t($,W,O,{modelRunner:G,logger:j(),maxAttempts:2}),H=X[0]?await qq(X[0],{modelRunner:G,logger:j(),maxAttempts:2}):void 0,B=H?e(H):void 0,V=o({question:O,tickets:X,patchIntent:H,impact:B,options:{includeSummary:!0,baseTags:["product-intent"],defaultPriority:"medium"}});if(process.env.CONTRACTSPEC_PM_DRY_RUN==="true"){console.log(JSON.stringify(V,null,2));return}let J=await Bq(q,V);console.log(JSON.stringify(J,null,2))}async function Bq(q,G){if(q==="linear"){let W=new i({apiKey:Z("LINEAR_API_KEY"),teamId:Z("LINEAR_TEAM_ID"),projectId:process.env.LINEAR_PROJECT_ID,stateId:process.env.LINEAR_STATE_ID,assigneeId:process.env.LINEAR_ASSIGNEE_ID,labelIds:C(process.env.LINEAR_LABEL_IDS)});return A(W,G)}if(q==="jira"){let W=new l({siteUrl:Z("JIRA_SITE_URL"),email:Z("JIRA_EMAIL"),apiToken:Z("JIRA_API_TOKEN"),projectKey:process.env.JIRA_PROJECT_KEY,issueType:process.env.JIRA_ISSUE_TYPE,defaultLabels:C(process.env.JIRA_DEFAULT_LABELS)});return A(W,G)}let Q=new r({apiKey:Z("NOTION_API_KEY"),databaseId:process.env.NOTION_DATABASE_ID,summaryParentPageId:process.env.NOTION_SUMMARY_PARENT_PAGE_ID,titleProperty:process.env.NOTION_TITLE_PROPERTY,statusProperty:process.env.NOTION_STATUS_PROPERTY,priorityProperty:process.env.NOTION_PRIORITY_PROPERTY,tagsProperty:process.env.NOTION_TAGS_PROPERTY,dueDateProperty:process.env.NOTION_DUE_DATE_PROPERTY,descriptionProperty:process.env.NOTION_DESCRIPTION_PROPERTY});return A(Q,G)}async function A(q,G){let Q=G.summary?await q.createWorkItem(G.summary):void 0,W=await q.createWorkItems(G.items);return{summary:Q,items:W}}function Z(q){let G=process.env[q];if(!G)throw Error(`Missing required env var: ${q}`);return G}function C(q){if(!q)return;let G=q.split(",").map((Q)=>Q.trim()).filter(Boolean);return G.length>0?G:void 0}$q().catch((q)=>{console.error(q),process.exitCode=1});
5
+ `),meta:{source:"posthog",kind:"feature_flags"}}}function w(q){let G=new Date,Q=q?.from instanceof Date?q.from:q?.from?new Date(q.from):new Date(G.getTime()-2592000000),W=q?.to instanceof Date?q.to:q?.to?new Date(q.to):G;return{from:Q,to:W}}function N(q){if(!q||q.length===0)return{};if(q.length===1)return{clause:"event = {event0}",values:{event0:q[0]}};let G={};return{clause:`(${q.map((W,$)=>{return G[`event${$}`]=W,`event = {event${$}}`}).join(" or ")})`,values:G}}function R(q){if(!Array.isArray(q.results)||!Array.isArray(q.columns))return[];let G=q.columns;return q.results.flatMap((Q)=>{if(!Array.isArray(Q))return[];let W={};return G.forEach(($,X)=>{W[$]=Q[X]}),[W]})}function h(q){if(typeof q==="string"&&q.trim())return q;if(typeof q==="number")return String(q);return null}function k(q){if(typeof q==="number"&&Number.isFinite(q))return q;if(typeof q==="string"&&q.trim()){let G=Number(q);if(Number.isFinite(G))return G}return 0}function L(q={}){let G=process.env.POSTHOG_PROJECT_ID,Q=process.env.POSTHOG_PERSONAL_API_KEY;if(!G||!Q)return null;let W=z("POSTHOG_EVIDENCE_LOOKBACK_DAYS",q.defaultLookbackDays??30),$=z("POSTHOG_EVIDENCE_LIMIT",q.defaultLimit??10),X=new Date,H=new Date(X.getTime()-W*24*60*60*1000),B=U("POSTHOG_EVIDENCE_EVENTS"),V=U("POSTHOG_EVIDENCE_FUNNEL_STEPS"),J=V&&V.length?{name:"posthog-evidence-funnel",steps:V.map((K,M)=>({id:`step_${M+1}`,eventName:K}))}:void 0;return{reader:new I({host:process.env.POSTHOG_HOST,projectId:G,personalApiKey:Q}),dateRange:{from:H,to:X},eventNames:B,limit:$,funnel:J,includeFeatureFlags:y("POSTHOG_EVIDENCE_FEATURE_FLAGS",!0)}}function U(q){let G=process.env[q];if(!G)return;return G.split(",").map((Q)=>Q.trim()).filter(Boolean)}function z(q,G){let Q=process.env[q];if(!Q)return G;let W=Number(Q);return Number.isFinite(W)?W:G}function y(q,G){let Q=process.env[q];if(Q===void 0)return G;return Q.toLowerCase()==="true"}import _ from"node:fs";import Y from"node:path";import{fileURLToPath as f}from"node:url";var m=Y.dirname(f(import.meta.url)),g=Y.join(m,"../evidence"),c=["interviews","tickets","public"],u=800;function d(q){let G=q.indexOf("---");if(G===-1)return q;let Q=q.indexOf("---",G+3);if(Q===-1)return q;return q.slice(Q+3).trimStart()}function v(q,G,Q){let W=[],$=G.trim();for(let X=0,H=0;X<$.length;H+=1){let B=$.slice(X,X+Q);W.push({chunkId:`${q}#c_${String(H).padStart(2,"0")}`,text:B,meta:{source:q}}),X+=Q}return W}function p(q={}){let G=q.evidenceRoot??g,Q=q.transcriptDirs??c,W=q.chunkSize??u,$=[];for(let X of Q){let H=Y.join(G,X);if(!_.existsSync(H))continue;for(let B of _.readdirSync(H)){if(Y.extname(B).toLowerCase()!==".md")continue;let J=Y.join(H,B),T=_.readFileSync(J,"utf8"),K=d(T),M=Y.parse(B).name,F=v(M,K,W);$.push(...F)}}return $}async function P(q={}){let G=p(q);if(!q.posthog)return G;let Q=await D(q.posthog);return[...G,...Q]}import{JiraProjectManagementProvider as l}from"@contractspec/integration.provider.project-management/impls/jira";import{LinearProjectManagementProvider as i}from"@contractspec/integration.provider.project-management/impls/linear";import{NotionProjectManagementProvider as r}from"@contractspec/integration.provider.project-management/impls/notion";import{createAgentJsonRunner as s}from"@contractspec/lib.ai-agent/agent/json-runner";import{buildProjectManagementSyncPayload as o,extractEvidence as a,generateTickets as t,groupProblems as n,impactEngine as e,suggestPatch as qq}from"@contractspec/lib.product-intent-utils";var O="Which activation and onboarding friction should we prioritize next?";function Gq(){let q=(process.env.CONTRACTSPEC_PM_PROVIDER??"").toLowerCase();if(q==="linear"||q==="jira"||q==="notion")return q;throw Error("Set CONTRACTSPEC_PM_PROVIDER to one of: linear, jira, notion")}async function Qq(){let q=Wq(),G=Xq(q),Q=process.env.CONTRACTSPEC_AI_PROXY_URL,W=process.env.CONTRACTSPEC_ORG_ID,$=process.env.OLLAMA_BASE_URL,X=process.env.CONTRACTSPEC_AI_MODEL??process.env.AI_MODEL??void 0;if(q!=="ollama"&&!G&&!Q&&!W)throw Error(`Missing API credentials for ${q}. Set provider API key or CONTRACTSPEC_AI_PROXY_URL.`);return s({provider:{provider:q,model:X,apiKey:G,baseUrl:$,proxyUrl:Q,organizationId:W},temperature:0,system:"You are a product discovery analyst. Respond with strict JSON only and use exact quotes for citations."})}function Wq(){let q=process.env.CONTRACTSPEC_AI_PROVIDER??process.env.AI_PROVIDER??"openai",G=q.toLowerCase(),Q=["openai","anthropic","mistral","gemini","ollama"];if(!Q.includes(G))throw Error(`Unsupported AI provider: ${q}. Use one of: ${Q.join(", ")}`);return G}function Xq(q){switch(q.toLowerCase()){case"openai":return process.env.OPENAI_API_KEY;case"anthropic":return process.env.ANTHROPIC_API_KEY;case"mistral":return process.env.MISTRAL_API_KEY;case"gemini":return process.env.GOOGLE_API_KEY??process.env.GEMINI_API_KEY;case"ollama":return;default:return}}function j(){return{log:()=>{return}}}async function $q(){let q=Gq(),G=await Qq(),Q=await P({posthog:L()??void 0}),W=await a(Q,O,{modelRunner:G,logger:j(),maxAttempts:2}),$=await n(W,O,{modelRunner:G,logger:j(),maxAttempts:2}),X=await t($,W,O,{modelRunner:G,logger:j(),maxAttempts:2}),H=X[0]?await qq(X[0],{modelRunner:G,logger:j(),maxAttempts:2}):void 0,B=H?e(H):void 0,V=o({question:O,tickets:X,patchIntent:H,impact:B,options:{includeSummary:!0,baseTags:["product-intent"],defaultPriority:"medium"}});if(process.env.CONTRACTSPEC_PM_DRY_RUN==="true"){console.log(JSON.stringify(V,null,2));return}let J=await Bq(q,V);console.log(JSON.stringify(J,null,2))}async function Bq(q,G){if(q==="linear"){let W=new i({apiKey:Z("LINEAR_API_KEY"),teamId:Z("LINEAR_TEAM_ID"),projectId:process.env.LINEAR_PROJECT_ID,stateId:process.env.LINEAR_STATE_ID,assigneeId:process.env.LINEAR_ASSIGNEE_ID,labelIds:C(process.env.LINEAR_LABEL_IDS)});return A(W,G)}if(q==="jira"){let W=new l({siteUrl:Z("JIRA_SITE_URL"),email:Z("JIRA_EMAIL"),apiToken:Z("JIRA_API_TOKEN"),projectKey:process.env.JIRA_PROJECT_KEY,issueType:process.env.JIRA_ISSUE_TYPE,defaultLabels:C(process.env.JIRA_DEFAULT_LABELS)});return A(W,G)}let Q=new r({apiKey:Z("NOTION_API_KEY"),databaseId:process.env.NOTION_DATABASE_ID,summaryParentPageId:process.env.NOTION_SUMMARY_PARENT_PAGE_ID,titleProperty:process.env.NOTION_TITLE_PROPERTY,statusProperty:process.env.NOTION_STATUS_PROPERTY,priorityProperty:process.env.NOTION_PRIORITY_PROPERTY,tagsProperty:process.env.NOTION_TAGS_PROPERTY,dueDateProperty:process.env.NOTION_DUE_DATE_PROPERTY,descriptionProperty:process.env.NOTION_DESCRIPTION_PROPERTY});return A(Q,G)}async function A(q,G){let Q=G.summary?await q.createWorkItem(G.summary):void 0,W=await q.createWorkItems(G.items);return{summary:Q,items:W}}function Z(q){let G=process.env[q];if(!G)throw Error(`Missing required env var: ${q}`);return G}function C(q){if(!q)return;let G=q.split(",").map((Q)=>Q.trim()).filter(Boolean);return G.length>0?G:void 0}$q().catch((q)=>{console.error(q),process.exitCode=1});
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{PosthogAnalyticsProvider as Z}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as _}from"@contractspec/lib.analytics/funnel";async function x(q){let G=[],H=D(q.dateRange),J=await $(q,H);if(J)G.push(J);let L=await z(q,H);if(L)G.push(L);let M=await B(q);if(M)G.push(M);return G}async function $(q,G){if(!q.reader.queryHogQL)return null;let H=j(q.eventNames),J=q.limit??10,L=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",H.clause?`and ${H.clause}`:"","group by eventName","order by total desc",`limit ${J}`].filter(Boolean).join(`
2
+ import{PosthogAnalyticsProvider as Z}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as _}from"@contractspec/lib.analytics/funnel";async function x(q){let G=[],H=D(q.dateRange),J=await $(q,H);if(J)G.push(J);let L=await z(q,H);if(L)G.push(L);let M=await B(q);if(M)G.push(M);return G}async function $(q,G){if(!q.reader.queryHogQL)return null;let H=j(q.eventNames),J=q.limit??10,L=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",H.clause?`and ${H.clause}`:"","group by eventName","order by total desc",`limit ${J}`].filter(Boolean).join(`
3
3
  `),values:{dateFrom:G.from.toISOString(),dateTo:G.to.toISOString(),...H.values}}),M=C(L);if(M.length===0)return null;let U=M.map((O)=>{let T=I(O.eventName)??"unknown",Q=K(O.total);return`- ${T}: ${Q}`});return{chunkId:`posthog:event_summary:${G.from.toISOString()}`,text:[`PostHog event summary (${G.from.toISOString()} \u2192 ${G.to.toISOString()}):`,...U].join(`
4
4
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function z(q,G){if(!q.funnel)return null;if(!q.reader.getEvents)return null;let H=[],J=q.funnel.steps.map((O)=>O.eventName);for(let O of J)(await q.reader.getEvents({event:O,dateRange:{from:G.from,to:G.to},limit:q.limit??500})).results.forEach((Q)=>{H.push({name:Q.event,userId:Q.distinctId,tenantId:typeof Q.properties?.tenantId==="string"?Q.properties.tenantId:void 0,timestamp:Q.timestamp,properties:Q.properties})});if(H.length===0)return null;let U=new _().analyze(H,q.funnel).steps.map((O)=>{return`- ${O.step.eventName}: ${O.count} (conversion ${O.conversionRate}, drop-off ${O.dropOffRate})`});return{chunkId:`posthog:funnel:${q.funnel.name}`,text:[`PostHog funnel analysis \u2014 ${q.funnel.name}:`,...U].join(`
5
5
  `),meta:{source:"posthog",kind:"funnel",funnelName:q.funnel.name,dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function B(q){if(!q.includeFeatureFlags)return null;if(!q.reader.getFeatureFlags)return null;let G=await q.reader.getFeatureFlags({limit:10});if(!G.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...G.results.map((J)=>{let L=J.key??"unknown",M=J.active?"active":"inactive";return`- ${L}: ${M}`})].join(`
package/dist/script.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{PosthogAnalyticsProvider as E}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as h}from"@contractspec/lib.analytics/funnel";async function w(q){let G=[],$=c(q.dateRange),B=await f(q,$);if(B)G.push(B);let H=await m(q,$);if(H)G.push(H);let J=await g(q);if(J)G.push(J);return G}async function f(q,G){if(!q.reader.queryHogQL)return null;let $=d(q.eventNames),B=q.limit??10,H=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",$.clause?`and ${$.clause}`:"","group by eventName","order by total desc",`limit ${B}`].filter(Boolean).join(`
2
+ import{PosthogAnalyticsProvider as E}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as h}from"@contractspec/lib.analytics/funnel";async function w(q){let G=[],$=c(q.dateRange),B=await f(q,$);if(B)G.push(B);let H=await m(q,$);if(H)G.push(H);let J=await g(q);if(J)G.push(J);return G}async function f(q,G){if(!q.reader.queryHogQL)return null;let $=d(q.eventNames),B=q.limit??10,H=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",$.clause?`and ${$.clause}`:"","group by eventName","order by total desc",`limit ${B}`].filter(Boolean).join(`
3
3
  `),values:{dateFrom:G.from.toISOString(),dateTo:G.to.toISOString(),...$.values}}),J=u(H);if(J.length===0)return null;let Z=J.map((W)=>{let V=v(W.eventName)??"unknown",Y=p(W.total);return`- ${V}: ${Y}`});return{chunkId:`posthog:event_summary:${G.from.toISOString()}`,text:[`PostHog event summary (${G.from.toISOString()} \u2192 ${G.to.toISOString()}):`,...Z].join(`
4
4
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function m(q,G){if(!q.funnel)return null;if(!q.reader.getEvents)return null;let $=[],B=q.funnel.steps.map((W)=>W.eventName);for(let W of B)(await q.reader.getEvents({event:W,dateRange:{from:G.from,to:G.to},limit:q.limit??500})).results.forEach((Y)=>{$.push({name:Y.event,userId:Y.distinctId,tenantId:typeof Y.properties?.tenantId==="string"?Y.properties.tenantId:void 0,timestamp:Y.timestamp,properties:Y.properties})});if($.length===0)return null;let Z=new h().analyze($,q.funnel).steps.map((W)=>{return`- ${W.step.eventName}: ${W.count} (conversion ${W.conversionRate}, drop-off ${W.dropOffRate})`});return{chunkId:`posthog:funnel:${q.funnel.name}`,text:[`PostHog funnel analysis \u2014 ${q.funnel.name}:`,...Z].join(`
5
5
  `),meta:{source:"posthog",kind:"funnel",funnelName:q.funnel.name,dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function g(q){if(!q.includeFeatureFlags)return null;if(!q.reader.getFeatureFlags)return null;let G=await q.reader.getFeatureFlags({limit:10});if(!G.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...G.results.map((B)=>{let H=B.key??"unknown",J=B.active?"active":"inactive";return`- ${H}: ${J}`})].join(`
@@ -1,6 +1,6 @@
1
1
  // @bun
2
- import{PosthogAnalyticsProvider as I}from"@contractspec/integration.providers-impls/impls/posthog";import{FunnelAnalyzer as x}from"@contractspec/lib.analytics/funnel";async function D(q){let G=[],Q=w(q.dateRange),W=await b(q,Q);if(W)G.push(W);let $=await S(q,Q);if($)G.push($);let X=await E(q);if(X)G.push(X);return G}async function b(q,G){if(!q.reader.queryHogQL)return null;let Q=N(q.eventNames),W=q.limit??10,$=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",Q.clause?`and ${Q.clause}`:"","group by eventName","order by total desc",`limit ${W}`].filter(Boolean).join(`
2
+ import{PosthogAnalyticsProvider as I}from"@contractspec/integration.provider.analytics/impls/posthog";import{FunnelAnalyzer as x}from"@contractspec/lib.analytics/funnel";async function D(q){let G=[],Q=w(q.dateRange),W=await b(q,Q);if(W)G.push(W);let $=await S(q,Q);if($)G.push($);let X=await E(q);if(X)G.push(X);return G}async function b(q,G){if(!q.reader.queryHogQL)return null;let Q=N(q.eventNames),W=q.limit??10,$=await q.reader.queryHogQL({query:["select"," event as eventName,"," count() as total","from events","where timestamp >= {dateFrom} and timestamp < {dateTo}",Q.clause?`and ${Q.clause}`:"","group by eventName","order by total desc",`limit ${W}`].filter(Boolean).join(`
3
3
  `),values:{dateFrom:G.from.toISOString(),dateTo:G.to.toISOString(),...Q.values}}),X=R($);if(X.length===0)return null;let H=X.map((B)=>{let V=h(B.eventName)??"unknown",J=k(B.total);return`- ${V}: ${J}`});return{chunkId:`posthog:event_summary:${G.from.toISOString()}`,text:[`PostHog event summary (${G.from.toISOString()} \u2192 ${G.to.toISOString()}):`,...H].join(`
4
4
  `),meta:{source:"posthog",kind:"event_summary",dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function S(q,G){if(!q.funnel)return null;if(!q.reader.getEvents)return null;let Q=[],W=q.funnel.steps.map((B)=>B.eventName);for(let B of W)(await q.reader.getEvents({event:B,dateRange:{from:G.from,to:G.to},limit:q.limit??500})).results.forEach((J)=>{Q.push({name:J.event,userId:J.distinctId,tenantId:typeof J.properties?.tenantId==="string"?J.properties.tenantId:void 0,timestamp:J.timestamp,properties:J.properties})});if(Q.length===0)return null;let H=new x().analyze(Q,q.funnel).steps.map((B)=>{return`- ${B.step.eventName}: ${B.count} (conversion ${B.conversionRate}, drop-off ${B.dropOffRate})`});return{chunkId:`posthog:funnel:${q.funnel.name}`,text:[`PostHog funnel analysis \u2014 ${q.funnel.name}:`,...H].join(`
5
5
  `),meta:{source:"posthog",kind:"funnel",funnelName:q.funnel.name,dateFrom:G.from.toISOString(),dateTo:G.to.toISOString()}}}async function E(q){if(!q.includeFeatureFlags)return null;if(!q.reader.getFeatureFlags)return null;let G=await q.reader.getFeatureFlags({limit:10});if(!G.results.length)return null;return{chunkId:"posthog:feature_flags",text:["PostHog feature flags:",...G.results.map((W)=>{let $=W.key??"unknown",X=W.active?"active":"inactive";return`- ${$}: ${X}`})].join(`
6
- `),meta:{source:"posthog",kind:"feature_flags"}}}function w(q){let G=new Date,Q=q?.from instanceof Date?q.from:q?.from?new Date(q.from):new Date(G.getTime()-2592000000),W=q?.to instanceof Date?q.to:q?.to?new Date(q.to):G;return{from:Q,to:W}}function N(q){if(!q||q.length===0)return{};if(q.length===1)return{clause:"event = {event0}",values:{event0:q[0]}};let G={};return{clause:`(${q.map((W,$)=>{return G[`event${$}`]=W,`event = {event${$}}`}).join(" or ")})`,values:G}}function R(q){if(!Array.isArray(q.results)||!Array.isArray(q.columns))return[];let G=q.columns;return q.results.flatMap((Q)=>{if(!Array.isArray(Q))return[];let W={};return G.forEach(($,X)=>{W[$]=Q[X]}),[W]})}function h(q){if(typeof q==="string"&&q.trim())return q;if(typeof q==="number")return String(q);return null}function k(q){if(typeof q==="number"&&Number.isFinite(q))return q;if(typeof q==="string"&&q.trim()){let G=Number(q);if(Number.isFinite(G))return G}return 0}function L(q={}){let G=process.env.POSTHOG_PROJECT_ID,Q=process.env.POSTHOG_PERSONAL_API_KEY;if(!G||!Q)return null;let W=z("POSTHOG_EVIDENCE_LOOKBACK_DAYS",q.defaultLookbackDays??30),$=z("POSTHOG_EVIDENCE_LIMIT",q.defaultLimit??10),X=new Date,H=new Date(X.getTime()-W*24*60*60*1000),B=U("POSTHOG_EVIDENCE_EVENTS"),V=U("POSTHOG_EVIDENCE_FUNNEL_STEPS"),J=V&&V.length?{name:"posthog-evidence-funnel",steps:V.map((K,M)=>({id:`step_${M+1}`,eventName:K}))}:void 0;return{reader:new I({host:process.env.POSTHOG_HOST,projectId:G,personalApiKey:Q}),dateRange:{from:H,to:X},eventNames:B,limit:$,funnel:J,includeFeatureFlags:y("POSTHOG_EVIDENCE_FEATURE_FLAGS",!0)}}function U(q){let G=process.env[q];if(!G)return;return G.split(",").map((Q)=>Q.trim()).filter(Boolean)}function z(q,G){let Q=process.env[q];if(!Q)return G;let W=Number(Q);return Number.isFinite(W)?W:G}function y(q,G){let Q=process.env[q];if(Q===void 0)return G;return Q.toLowerCase()==="true"}import _ from"fs";import Y from"path";import{fileURLToPath as f}from"url";var m=Y.dirname(f(import.meta.url)),g=Y.join(m,"../evidence"),c=["interviews","tickets","public"],u=800;function d(q){let G=q.indexOf("---");if(G===-1)return q;let Q=q.indexOf("---",G+3);if(Q===-1)return q;return q.slice(Q+3).trimStart()}function v(q,G,Q){let W=[],$=G.trim();for(let X=0,H=0;X<$.length;H+=1){let B=$.slice(X,X+Q);W.push({chunkId:`${q}#c_${String(H).padStart(2,"0")}`,text:B,meta:{source:q}}),X+=Q}return W}function p(q={}){let G=q.evidenceRoot??g,Q=q.transcriptDirs??c,W=q.chunkSize??u,$=[];for(let X of Q){let H=Y.join(G,X);if(!_.existsSync(H))continue;for(let B of _.readdirSync(H)){if(Y.extname(B).toLowerCase()!==".md")continue;let J=Y.join(H,B),T=_.readFileSync(J,"utf8"),K=d(T),M=Y.parse(B).name,F=v(M,K,W);$.push(...F)}}return $}async function P(q={}){let G=p(q);if(!q.posthog)return G;let Q=await D(q.posthog);return[...G,...Q]}import{JiraProjectManagementProvider as l}from"@contractspec/integration.providers-impls/impls/jira";import{LinearProjectManagementProvider as i}from"@contractspec/integration.providers-impls/impls/linear";import{NotionProjectManagementProvider as r}from"@contractspec/integration.providers-impls/impls/notion";import{createAgentJsonRunner as s}from"@contractspec/lib.ai-agent/agent/json-runner";import{buildProjectManagementSyncPayload as o,extractEvidence as a,generateTickets as t,groupProblems as n,impactEngine as e,suggestPatch as qq}from"@contractspec/lib.product-intent-utils";var O="Which activation and onboarding friction should we prioritize next?";function Gq(){let q=(process.env.CONTRACTSPEC_PM_PROVIDER??"").toLowerCase();if(q==="linear"||q==="jira"||q==="notion")return q;throw Error("Set CONTRACTSPEC_PM_PROVIDER to one of: linear, jira, notion")}async function Qq(){let q=Wq(),G=Xq(q),Q=process.env.CONTRACTSPEC_AI_PROXY_URL,W=process.env.CONTRACTSPEC_ORG_ID,$=process.env.OLLAMA_BASE_URL,X=process.env.CONTRACTSPEC_AI_MODEL??process.env.AI_MODEL??void 0;if(q!=="ollama"&&!G&&!Q&&!W)throw Error(`Missing API credentials for ${q}. Set provider API key or CONTRACTSPEC_AI_PROXY_URL.`);return s({provider:{provider:q,model:X,apiKey:G,baseUrl:$,proxyUrl:Q,organizationId:W},temperature:0,system:"You are a product discovery analyst. Respond with strict JSON only and use exact quotes for citations."})}function Wq(){let q=process.env.CONTRACTSPEC_AI_PROVIDER??process.env.AI_PROVIDER??"openai",G=q.toLowerCase(),Q=["openai","anthropic","mistral","gemini","ollama"];if(!Q.includes(G))throw Error(`Unsupported AI provider: ${q}. Use one of: ${Q.join(", ")}`);return G}function Xq(q){switch(q.toLowerCase()){case"openai":return process.env.OPENAI_API_KEY;case"anthropic":return process.env.ANTHROPIC_API_KEY;case"mistral":return process.env.MISTRAL_API_KEY;case"gemini":return process.env.GOOGLE_API_KEY??process.env.GEMINI_API_KEY;case"ollama":return;default:return}}function j(){return{log:()=>{return}}}async function $q(){let q=Gq(),G=await Qq(),Q=await P({posthog:L()??void 0}),W=await a(Q,O,{modelRunner:G,logger:j(),maxAttempts:2}),$=await n(W,O,{modelRunner:G,logger:j(),maxAttempts:2}),X=await t($,W,O,{modelRunner:G,logger:j(),maxAttempts:2}),H=X[0]?await qq(X[0],{modelRunner:G,logger:j(),maxAttempts:2}):void 0,B=H?e(H):void 0,V=o({question:O,tickets:X,patchIntent:H,impact:B,options:{includeSummary:!0,baseTags:["product-intent"],defaultPriority:"medium"}});if(process.env.CONTRACTSPEC_PM_DRY_RUN==="true"){console.log(JSON.stringify(V,null,2));return}let J=await Bq(q,V);console.log(JSON.stringify(J,null,2))}async function Bq(q,G){if(q==="linear"){let W=new i({apiKey:Z("LINEAR_API_KEY"),teamId:Z("LINEAR_TEAM_ID"),projectId:process.env.LINEAR_PROJECT_ID,stateId:process.env.LINEAR_STATE_ID,assigneeId:process.env.LINEAR_ASSIGNEE_ID,labelIds:C(process.env.LINEAR_LABEL_IDS)});return A(W,G)}if(q==="jira"){let W=new l({siteUrl:Z("JIRA_SITE_URL"),email:Z("JIRA_EMAIL"),apiToken:Z("JIRA_API_TOKEN"),projectKey:process.env.JIRA_PROJECT_KEY,issueType:process.env.JIRA_ISSUE_TYPE,defaultLabels:C(process.env.JIRA_DEFAULT_LABELS)});return A(W,G)}let Q=new r({apiKey:Z("NOTION_API_KEY"),databaseId:process.env.NOTION_DATABASE_ID,summaryParentPageId:process.env.NOTION_SUMMARY_PARENT_PAGE_ID,titleProperty:process.env.NOTION_TITLE_PROPERTY,statusProperty:process.env.NOTION_STATUS_PROPERTY,priorityProperty:process.env.NOTION_PRIORITY_PROPERTY,tagsProperty:process.env.NOTION_TAGS_PROPERTY,dueDateProperty:process.env.NOTION_DUE_DATE_PROPERTY,descriptionProperty:process.env.NOTION_DESCRIPTION_PROPERTY});return A(Q,G)}async function A(q,G){let Q=G.summary?await q.createWorkItem(G.summary):void 0,W=await q.createWorkItems(G.items);return{summary:Q,items:W}}function Z(q){let G=process.env[q];if(!G)throw Error(`Missing required env var: ${q}`);return G}function C(q){if(!q)return;let G=q.split(",").map((Q)=>Q.trim()).filter(Boolean);return G.length>0?G:void 0}$q().catch((q)=>{console.error(q),process.exitCode=1});
6
+ `),meta:{source:"posthog",kind:"feature_flags"}}}function w(q){let G=new Date,Q=q?.from instanceof Date?q.from:q?.from?new Date(q.from):new Date(G.getTime()-2592000000),W=q?.to instanceof Date?q.to:q?.to?new Date(q.to):G;return{from:Q,to:W}}function N(q){if(!q||q.length===0)return{};if(q.length===1)return{clause:"event = {event0}",values:{event0:q[0]}};let G={};return{clause:`(${q.map((W,$)=>{return G[`event${$}`]=W,`event = {event${$}}`}).join(" or ")})`,values:G}}function R(q){if(!Array.isArray(q.results)||!Array.isArray(q.columns))return[];let G=q.columns;return q.results.flatMap((Q)=>{if(!Array.isArray(Q))return[];let W={};return G.forEach(($,X)=>{W[$]=Q[X]}),[W]})}function h(q){if(typeof q==="string"&&q.trim())return q;if(typeof q==="number")return String(q);return null}function k(q){if(typeof q==="number"&&Number.isFinite(q))return q;if(typeof q==="string"&&q.trim()){let G=Number(q);if(Number.isFinite(G))return G}return 0}function L(q={}){let G=process.env.POSTHOG_PROJECT_ID,Q=process.env.POSTHOG_PERSONAL_API_KEY;if(!G||!Q)return null;let W=z("POSTHOG_EVIDENCE_LOOKBACK_DAYS",q.defaultLookbackDays??30),$=z("POSTHOG_EVIDENCE_LIMIT",q.defaultLimit??10),X=new Date,H=new Date(X.getTime()-W*24*60*60*1000),B=U("POSTHOG_EVIDENCE_EVENTS"),V=U("POSTHOG_EVIDENCE_FUNNEL_STEPS"),J=V&&V.length?{name:"posthog-evidence-funnel",steps:V.map((K,M)=>({id:`step_${M+1}`,eventName:K}))}:void 0;return{reader:new I({host:process.env.POSTHOG_HOST,projectId:G,personalApiKey:Q}),dateRange:{from:H,to:X},eventNames:B,limit:$,funnel:J,includeFeatureFlags:y("POSTHOG_EVIDENCE_FEATURE_FLAGS",!0)}}function U(q){let G=process.env[q];if(!G)return;return G.split(",").map((Q)=>Q.trim()).filter(Boolean)}function z(q,G){let Q=process.env[q];if(!Q)return G;let W=Number(Q);return Number.isFinite(W)?W:G}function y(q,G){let Q=process.env[q];if(Q===void 0)return G;return Q.toLowerCase()==="true"}import _ from"fs";import Y from"path";import{fileURLToPath as f}from"url";var m=Y.dirname(f(import.meta.url)),g=Y.join(m,"../evidence"),c=["interviews","tickets","public"],u=800;function d(q){let G=q.indexOf("---");if(G===-1)return q;let Q=q.indexOf("---",G+3);if(Q===-1)return q;return q.slice(Q+3).trimStart()}function v(q,G,Q){let W=[],$=G.trim();for(let X=0,H=0;X<$.length;H+=1){let B=$.slice(X,X+Q);W.push({chunkId:`${q}#c_${String(H).padStart(2,"0")}`,text:B,meta:{source:q}}),X+=Q}return W}function p(q={}){let G=q.evidenceRoot??g,Q=q.transcriptDirs??c,W=q.chunkSize??u,$=[];for(let X of Q){let H=Y.join(G,X);if(!_.existsSync(H))continue;for(let B of _.readdirSync(H)){if(Y.extname(B).toLowerCase()!==".md")continue;let J=Y.join(H,B),T=_.readFileSync(J,"utf8"),K=d(T),M=Y.parse(B).name,F=v(M,K,W);$.push(...F)}}return $}async function P(q={}){let G=p(q);if(!q.posthog)return G;let Q=await D(q.posthog);return[...G,...Q]}import{JiraProjectManagementProvider as l}from"@contractspec/integration.provider.project-management/impls/jira";import{LinearProjectManagementProvider as i}from"@contractspec/integration.provider.project-management/impls/linear";import{NotionProjectManagementProvider as r}from"@contractspec/integration.provider.project-management/impls/notion";import{createAgentJsonRunner as s}from"@contractspec/lib.ai-agent/agent/json-runner";import{buildProjectManagementSyncPayload as o,extractEvidence as a,generateTickets as t,groupProblems as n,impactEngine as e,suggestPatch as qq}from"@contractspec/lib.product-intent-utils";var O="Which activation and onboarding friction should we prioritize next?";function Gq(){let q=(process.env.CONTRACTSPEC_PM_PROVIDER??"").toLowerCase();if(q==="linear"||q==="jira"||q==="notion")return q;throw Error("Set CONTRACTSPEC_PM_PROVIDER to one of: linear, jira, notion")}async function Qq(){let q=Wq(),G=Xq(q),Q=process.env.CONTRACTSPEC_AI_PROXY_URL,W=process.env.CONTRACTSPEC_ORG_ID,$=process.env.OLLAMA_BASE_URL,X=process.env.CONTRACTSPEC_AI_MODEL??process.env.AI_MODEL??void 0;if(q!=="ollama"&&!G&&!Q&&!W)throw Error(`Missing API credentials for ${q}. Set provider API key or CONTRACTSPEC_AI_PROXY_URL.`);return s({provider:{provider:q,model:X,apiKey:G,baseUrl:$,proxyUrl:Q,organizationId:W},temperature:0,system:"You are a product discovery analyst. Respond with strict JSON only and use exact quotes for citations."})}function Wq(){let q=process.env.CONTRACTSPEC_AI_PROVIDER??process.env.AI_PROVIDER??"openai",G=q.toLowerCase(),Q=["openai","anthropic","mistral","gemini","ollama"];if(!Q.includes(G))throw Error(`Unsupported AI provider: ${q}. Use one of: ${Q.join(", ")}`);return G}function Xq(q){switch(q.toLowerCase()){case"openai":return process.env.OPENAI_API_KEY;case"anthropic":return process.env.ANTHROPIC_API_KEY;case"mistral":return process.env.MISTRAL_API_KEY;case"gemini":return process.env.GOOGLE_API_KEY??process.env.GEMINI_API_KEY;case"ollama":return;default:return}}function j(){return{log:()=>{return}}}async function $q(){let q=Gq(),G=await Qq(),Q=await P({posthog:L()??void 0}),W=await a(Q,O,{modelRunner:G,logger:j(),maxAttempts:2}),$=await n(W,O,{modelRunner:G,logger:j(),maxAttempts:2}),X=await t($,W,O,{modelRunner:G,logger:j(),maxAttempts:2}),H=X[0]?await qq(X[0],{modelRunner:G,logger:j(),maxAttempts:2}):void 0,B=H?e(H):void 0,V=o({question:O,tickets:X,patchIntent:H,impact:B,options:{includeSummary:!0,baseTags:["product-intent"],defaultPriority:"medium"}});if(process.env.CONTRACTSPEC_PM_DRY_RUN==="true"){console.log(JSON.stringify(V,null,2));return}let J=await Bq(q,V);console.log(JSON.stringify(J,null,2))}async function Bq(q,G){if(q==="linear"){let W=new i({apiKey:Z("LINEAR_API_KEY"),teamId:Z("LINEAR_TEAM_ID"),projectId:process.env.LINEAR_PROJECT_ID,stateId:process.env.LINEAR_STATE_ID,assigneeId:process.env.LINEAR_ASSIGNEE_ID,labelIds:C(process.env.LINEAR_LABEL_IDS)});return A(W,G)}if(q==="jira"){let W=new l({siteUrl:Z("JIRA_SITE_URL"),email:Z("JIRA_EMAIL"),apiToken:Z("JIRA_API_TOKEN"),projectKey:process.env.JIRA_PROJECT_KEY,issueType:process.env.JIRA_ISSUE_TYPE,defaultLabels:C(process.env.JIRA_DEFAULT_LABELS)});return A(W,G)}let Q=new r({apiKey:Z("NOTION_API_KEY"),databaseId:process.env.NOTION_DATABASE_ID,summaryParentPageId:process.env.NOTION_SUMMARY_PARENT_PAGE_ID,titleProperty:process.env.NOTION_TITLE_PROPERTY,statusProperty:process.env.NOTION_STATUS_PROPERTY,priorityProperty:process.env.NOTION_PRIORITY_PROPERTY,tagsProperty:process.env.NOTION_TAGS_PROPERTY,dueDateProperty:process.env.NOTION_DUE_DATE_PROPERTY,descriptionProperty:process.env.NOTION_DESCRIPTION_PROPERTY});return A(Q,G)}async function A(q,G){let Q=G.summary?await q.createWorkItem(G.summary):void 0,W=await q.createWorkItems(G.items);return{summary:Q,items:W}}function Z(q){let G=process.env[q];if(!G)throw Error(`Missing required env var: ${q}`);return G}function C(q){if(!q)return;let G=q.split(",").map((Q)=>Q.trim()).filter(Boolean);return G.length>0?G:void 0}$q().catch((q)=>{console.error(q),process.exitCode=1});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/example.product-intent",
3
- "version": "3.7.24",
3
+ "version": "3.7.26",
4
4
  "description": "Product intent example: evidence ingestion and prompt-ready outputs.",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -89,12 +89,13 @@
89
89
  "typecheck": "tsc --noEmit"
90
90
  },
91
91
  "dependencies": {
92
- "@contractspec/lib.analytics": "3.7.23",
93
- "@contractspec/lib.contracts-spec": "5.6.0",
94
- "@contractspec/lib.contracts-integrations": "3.8.15",
95
- "@contractspec/lib.ai-agent": "8.0.11",
96
- "@contractspec/lib.product-intent-utils": "3.7.23",
97
- "@contractspec/integration.providers-impls": "4.0.2"
92
+ "@contractspec/integration.provider.analytics": "0.2.1",
93
+ "@contractspec/integration.provider.project-management": "0.2.1",
94
+ "@contractspec/lib.ai-agent": "8.0.13",
95
+ "@contractspec/lib.analytics": "3.7.25",
96
+ "@contractspec/lib.contracts-integrations": "3.8.17",
97
+ "@contractspec/lib.contracts-spec": "6.0.0",
98
+ "@contractspec/lib.product-intent-utils": "3.7.25"
98
99
  },
99
100
  "devDependencies": {
100
101
  "@contractspec/tool.typescript": "3.7.13",
@@ -1,4 +1,4 @@
1
- import { PosthogAnalyticsProvider } from '@contractspec/integration.providers-impls/impls/posthog';
1
+ import { PosthogAnalyticsProvider } from '@contractspec/integration.provider.analytics/impls/posthog';
2
2
  import type {
3
3
  AnalyticsEvent,
4
4
  FunnelDefinition,
@@ -1,6 +1,6 @@
1
- import { JiraProjectManagementProvider } from '@contractspec/integration.providers-impls/impls/jira';
2
- import { LinearProjectManagementProvider } from '@contractspec/integration.providers-impls/impls/linear';
3
- import { NotionProjectManagementProvider } from '@contractspec/integration.providers-impls/impls/notion';
1
+ import { JiraProjectManagementProvider } from '@contractspec/integration.provider.project-management/impls/jira';
2
+ import { LinearProjectManagementProvider } from '@contractspec/integration.provider.project-management/impls/linear';
3
+ import { NotionProjectManagementProvider } from '@contractspec/integration.provider.project-management/impls/notion';
4
4
  import { createAgentJsonRunner } from '@contractspec/lib.ai-agent/agent/json-runner';
5
5
  import type { ProjectManagementProvider } from '@contractspec/lib.contracts-integrations';
6
6
  import type { TicketPipelineModelRunner } from '@contractspec/lib.product-intent-utils';