@codified/cli 0.1.0 → 0.1.1

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 (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -259,7 +259,7 @@ ${r}
259
259
  Respond with JSON only. No markdown, no explanation.`,o=(await this.anthropic.messages.create({model:"claude-sonnet-4-20250514",max_tokens:4096,system:O3,messages:[{role:"user",content:i}]})).content.find(s=>s.type==="text");return!o||o.type!=="text"?(console.error("[git-miner] No text response from Claude"),{nodes:[],edges:[]}):this.parseResponse(o.text,e)}parseResponse(e,r){let i=e.replace(/^```json?\n?/,"").replace(/\n?```$/,"").trim(),n;try{n=JSON.parse(i)}catch(u){return console.error("[git-miner] Failed to parse Claude response:",u),console.error("[git-miner] Raw response:",e.slice(0,500)),{nodes:[],edges:[]}}let o=r[0]?.connectorId??"unknown",s=u=>({...N3,reference:`${o}:${u}`}),a=(n.nodes??[]).map(u=>{let l=u;return{type:l.type??"CodeArtifact",sourceRef:l.sourceRef??"",properties:l.properties??{},confidence:Math.max(0,Math.min(1,l.confidence??.5)),tags:Array.isArray(l.tags)?l.tags:[],source:s(l.sourceRef??"")}}),c=(n.edges??[]).map(u=>{let l=u;return{type:l.type??"relates_to",fromRef:l.fromRef??"",toRef:l.toRef??"",confidence:Math.max(0,Math.min(1,l.confidence??.5)),evidence:l.evidence??null,source:s(`${l.fromRef}\u2192${l.toRef}`)}});return console.log(`[git-miner] Extracted ${a.length} nodes and ${c.length} edges from ${r.length} artifact(s)`),{nodes:a,edges:c}}}});var Fs,Xy=m(()=>{"use strict";Ne();Ne();Ne();Ne();Fs=class{constructor(e){this.config=e}async process(e){let r={created:[],merged:[],conflicted:[],rejected:[]},i=new Map;for(let n of e.nodes)try{let o=await this.processNode(n);switch(o.action){case"created":r.created.push(o.nodeId),i.set(n.sourceRef,o.nodeId);break;case"merged":r.merged.push(o.nodeId),i.set(n.sourceRef,o.nodeId);break;case"conflicted":r.conflicted.push(o.nodeId),i.set(n.sourceRef,o.nodeId);break}}catch(o){console.error(`[pipeline] Failed to process node ${n.sourceRef}:`,o),r.rejected.push(n.sourceRef)}for(let n of e.edges)try{await this.processEdge(n,i)}catch(o){console.error(`[pipeline] Failed to process edge ${n.fromRef}\u2192${n.toRef}:`,o)}for(let n of r.created)try{await this.maybePromote(n)}catch(o){console.error(`[pipeline] Failed to auto-promote ${n}:`,o)}return console.log(`[pipeline] Processed: ${r.created.length} created, ${r.merged.length} merged, ${r.conflicted.length} conflicted, ${r.rejected.length} rejected`),r}async processNode(e){if(this.config.enableDedup){let i=await this.findBySourceRef(e.sourceRef);if(i)return await lr(i,{properties:e.properties,tags:e.tags,confidence:e.confidence}),{action:"merged",nodeId:i}}if(!this.isValidNodeType(e.type))throw new Error(`Invalid node type: ${e.type}`);return{action:"created",nodeId:(await qr({type:e.type,layer:"draft",confidence:e.confidence,source:e.source,properties:{...e.properties,_sourceRef:e.sourceRef},tags:e.tags})).id}}async processEdge(e,r){let i=r.get(e.fromRef)??await this.resolveRef(e.fromRef),n=r.get(e.toRef)??await this.resolveRef(e.toRef);if(!i||!n){console.warn(`[pipeline] Skipping edge ${e.fromRef}\u2192${e.toRef}: unresolved refs`);return}(await wr({type:e.type,sourceId:i,targetId:n,limit:1})).length>0||await Ir({type:e.type,sourceId:i,targetId:n,confidence:e.confidence,evidence:e.evidence??void 0,source:e.source})}async maybePromote(e){let r=await Ze(e,{layers:["draft"]});r&&r.confidence>=this.config.autoPromoteThreshold&&(await ho(e,"permanent"),console.log(`[pipeline] Auto-promoted node ${e} (confidence: ${r.confidence.toFixed(2)})`))}async findBySourceRef(e){let r=await ae(`SELECT id FROM nodes
260
260
  WHERE properties->>'_sourceRef' = $1
261
261
  AND superseded_by IS NULL
262
- LIMIT 1`,[e]);return r.rows.length===0?null:r.rows[0].id}async resolveRef(e){let r=await Ze(e,{layers:["permanent","draft"]});return r?r.id:this.findBySourceRef(e)}isValidNodeType(e){return["Decision","Feature","Metric","CustomerSignal","CodeArtifact","Discussion","Gap","Study","Person"].includes(e)}}});var Us,eb=m(()=>{"use strict";Us=class{constructor(e,r,i,n,o){this.registry=e;this.miner=r;this.pipeline=i;this.config=n;this.eventBus=o}async run(e){let r=this.registry.get(e);if(!r)throw new Error(`Connector "${e}" not found`);let i=this.registry.getConnection(e);if(!i)throw new Error(`Connector "${e}" is not connected. Call connect() first.`);let n=Date.now();console.log(`[bootstrap] Starting full sync for connector: ${r.name}`),this.registry.updateSyncState(e,{status:"syncing"});let o={created:[],merged:[],conflicted:[],rejected:[]},s=0,a=[];try{for await(let u of r.fullSync(i))if(a.push(u),s++,a.length>=this.config.minerBatchSize){let l=await this.processBatch(a);this.mergeResults(o,l),a=[],s%100===0&&console.log(`[bootstrap] Processed ${s} artifacts...`)}if(a.length>0){let u=await this.processBatch(a);this.mergeResults(o,u)}this.registry.updateSyncState(e,{status:"idle",lastSyncAt:new Date,artifactCount:s});let c=Date.now()-n;return console.log(`[bootstrap] Completed for ${r.name}: ${s} artifacts, ${o.created.length} nodes created, ${o.merged.length} merged (${(c/1e3).toFixed(1)}s)`),{connectorId:e,totalArtifacts:s,pipeline:o,durationMs:c}}catch(c){throw this.registry.updateSyncState(e,{status:"error",error:c instanceof Error?c.message:String(c)}),c}}async incrementalSync(e){let r=this.registry.get(e);if(!r)throw new Error(`Connector "${e}" not found`);let i=this.registry.getConnection(e);if(!i)throw new Error(`Connector "${e}" is not connected`);let n=this.registry.getSyncState(e);if(!n?.lastSyncAt)return console.log(`[bootstrap] No previous sync found for ${e}, running full sync`),this.run(e);let o=Date.now(),s=n.lastSyncAt;console.log(`[bootstrap] Incremental sync for ${r.name} since ${s.toISOString()}`),this.registry.updateSyncState(e,{status:"syncing"});let a={created:[],merged:[],conflicted:[],rejected:[]},c=0,u=[];try{for await(let d of r.incrementalSync(i,s))if(u.push(d),c++,u.length>=this.config.minerBatchSize){let p=await this.processBatch(u);this.mergeResults(a,p),u=[]}if(u.length>0){let d=await this.processBatch(u);this.mergeResults(a,d)}this.registry.updateSyncState(e,{status:"idle",lastSyncAt:new Date,artifactCount:(n.artifactCount??0)+c});let l=Date.now()-o;return console.log(`[bootstrap] Incremental sync completed for ${r.name}: ${c} new artifacts (${(l/1e3).toFixed(1)}s)`),{connectorId:e,totalArtifacts:c,pipeline:a,durationMs:l}}catch(l){throw this.registry.updateSyncState(e,{status:"error",error:l instanceof Error?l.message:String(l)}),l}}async processBatch(e){let r=await this.miner.mine(e);return this.pipeline.process(r)}mergeResults(e,r){e.created.push(...r.created),e.merged.push(...r.merged),e.conflicted.push(...r.conflicted),e.rejected.push(...r.rejected)}}});var tb,rb=m(()=>{"use strict";tb={minerBatchSize:10,enableDedup:!0,autoPromoteThreshold:.7}});function k3(t,e){let r={...tb,...t},i=new As,n=new js,o=new Fs(r),s=new Us(i,n,o,r,e);return i.register(new Cs),i.register(new Ls),console.log("[ingest] Service initialized"),{registry:i,miner:n,pipeline:o,bootstrap:s}}var C$=m(()=>{"use strict";Hy();Zy();Jy();Yy();Xy();eb();rb();Hy();Zy();Jy();Yy();Xy();eb();rb()});var L$,j$,F$=m(()=>{"use strict";L$={missing_data:["customer_interview","team_dm","document_request"],stale:["customer_interview","market_signal"],contradiction:["customer_interview","team_dm"],untested_assumption:["customer_interview","micro_survey"],missing_validation:["customer_interview","micro_survey"],coverage_gap:["tribal_knowledge_mining","team_dm","document_request"]},j$={missing_data:"discovery",stale:"discovery",contradiction:"concept-test",untested_assumption:"concept-test",missing_validation:"sentiment",coverage_gap:"discovery"}});import{randomUUID as U$}from"node:crypto";var Ms,Wd,Gs,nb=m(()=>{"use strict";Ne();F$();Ms=new Map,Wd=new Map,Gs=class{constructor(e){this.eventBus=e}async start(){this.eventBus.subscriber.subscribe("gap.detected.>",async e=>{await this.handleGapDetected(e)},{group:"collection-planner"})}async handleGapDetected(e){let r=await Ze(e.gapNodeId,{layers:["permanent","draft"]});if(!r)return;let i=r.metadata?.gapType??"missing_data",n=this.computeBatchKey(r),o=Wd.get(n);if(o&&o.length>0){let a=Ms.get(o[0]);if(a&&a.status==="planned"){a.gapIds.push(e.gapNodeId);let c=this.generateQuestions(r);a.questions.push(...c);return}}let s=await this.createPlan(e.gapNodeId,i,r);Wd.has(n)||Wd.set(n,[]),Wd.get(n).push(s.id)}async createPlan(e,r,i){i||(i=await Ze(e,{layers:["permanent","draft"]}));let n=this.selectMethod(r,i),o=this.generateQuestions(i),s=this.generateSuccessCriteria(r,i),a={id:U$(),gapIds:[e],method:n,questions:o,successCriteria:s,priority:this.computePriority(i),batchId:null,status:"planned",externalStudyId:null,createdAt:new Date().toISOString(),completedAt:null};return Ms.set(a.id,a),a}async approvePlan(e){let r=Ms.get(e);return!r||r.status!=="planned"?null:(r.status="approved",r)}getPlan(e){return Ms.get(e)??null}listPlans(e){let r=Array.from(Ms.values());e?.status&&(r=r.filter(o=>e.status.includes(o.status))),e?.batchId&&(r=r.filter(o=>o.batchId===e.batchId)),e?.gapId&&(r=r.filter(o=>o.gapIds.includes(e.gapId))),r.sort((o,s)=>s.priority-o.priority);let i=e?.offset??0,n=e?.limit??50;return r.slice(i,i+n)}updatePlanStatus(e,r){let i=Ms.get(e);i&&(i.status=r,(r==="completed"||r==="failed")&&(i.completedAt=new Date().toISOString()))}selectMethod(e,r){let n=(L$[e]??["customer_interview"])[0],o=r?.metadata?.description??"";switch(n){case"customer_interview":return{type:"customer_interview",studyType:j$[e]??"discovery",segment:r?.metadata?.customerSegment??void 0};case"micro_survey":return{type:"micro_survey",trigger:"contextual",question:o};case"market_signal":return{type:"market_signal",sources:["web","competitors"],query:o};case"team_dm":return{type:"team_dm",targetRole:this.inferTargetRole(r),channel:"slack"};case"document_request":return{type:"document_request",targetPerson:"",topic:o};case"tribal_knowledge_mining":return{type:"tribal_knowledge_mining",targetTeam:this.inferTargetTeam(r),topic:o};default:return{type:"customer_interview",studyType:"discovery"}}}generateQuestions(e){if(!e)return["What can you tell us about this topic?"];let r=e.metadata?.description??"";switch(e.metadata?.gapType??"missing_data"){case"missing_data":return[`We're missing data on: ${r}. What has been your experience?`,"What factors are most important to you in this area?"];case"stale":return[`Our information about "${r}" may be outdated. Has anything changed recently?`,"What's different now compared to 3-6 months ago?"];case"contradiction":return[`We're seeing conflicting signals about: ${r}. What's your perspective?`,"In what context is this true vs. not true?"];case"untested_assumption":return[`We've assumed: ${r}. Does this match your experience?`,"What would change your mind about this?"];case"missing_validation":return[`We'd like to validate: ${r}. How accurate is this?`,"What's missing from this picture?"];default:return[`Tell us about your experience with: ${r}`]}}generateSuccessCriteria(e,r){let i=r?.metadata?.description??"this topic";switch(e){case"missing_data":return`Obtain at least 3 independent data points about: ${i}`;case"stale":return`Get current information (< 30 days old) about: ${i}`;case"contradiction":return"Identify which perspective is more accurate, or under what conditions each is true";case"untested_assumption":return"Validate or invalidate the assumption with at least 5 data points";case"missing_validation":return"Confirm or deny with direct evidence from users/stakeholders";case"coverage_gap":return"Document the missing context with source attribution";default:return"Resolve the gap with supporting evidence"}}computeBatchKey(e){if(!e)return U$();let r=e.metadata?.gapType??"unknown",i=e.tags[0]??r;return`${r}:${i}`}computePriority(e){if(!e)return .5;let r={critical:1,high:.75,medium:.5,low:.25},i=e.metadata?.severity??"medium";return r[i]??.5}inferTargetRole(e){if(!e)return"engineering";let r=e.metadata?.gapType??"";return r==="missing_data"||r==="missing_validation"?"product":"engineering"}inferTargetTeam(e){if(!e)return"engineering";let r=e.tags;return r.includes("pricing")||r.includes("business")?"product":r.includes("customer")||r.includes("churn")?"sales":"engineering"}}});function M$(t){return{system:"codify-interviews",reference:t,agentId:null,reliability:.85}}function P3(t){let e=t.match(/(?:on|about|validate):\s*(.+?)(?:\.|What|How|$)/i);if(e)return e[1].trim();let r=t.match(/"([^"]+)"/);return r?r[1].trim():t.replace(/^(Tell us about|What can you tell us about)\s*/i,"").slice(0,50).trim()||null}var $3,Bs,ib=m(()=>{"use strict";$3={progressPollIntervalMs:6e4,minInterviewsForSynthesis:3},Bs=class{constructor(e,r,i,n){this.mcp=e;this.planner=r;this.eventBus=i;this.config={...$3,...n}}config;activeStudies=new Map;pollTimers=new Map;async execute(e){if(e.method.type!=="customer_interview")return null;let r=e.method,i=await this.mcp.runStudy({type:r.studyType,description:e.questions.join(`
262
+ LIMIT 1`,[e]);return r.rows.length===0?null:r.rows[0].id}async resolveRef(e){let r=await Ze(e,{layers:["permanent","draft"]});return r?r.id:this.findBySourceRef(e)}isValidNodeType(e){return["Decision","Feature","Metric","CustomerSignal","CodeArtifact","Discussion","Gap","Study","Person"].includes(e)}}});var Us,eb=m(()=>{"use strict";Us=class{constructor(e,r,i,n,o){this.registry=e;this.miner=r;this.pipeline=i;this.config=n;this.eventBus=o}async run(e){let r=this.registry.get(e);if(!r)throw new Error(`Connector "${e}" not found`);let i=this.registry.getConnection(e);if(!i)throw new Error(`Connector "${e}" is not connected. Call connect() first.`);let n=Date.now();console.log(`[bootstrap] Starting full sync for connector: ${r.name}`),this.registry.updateSyncState(e,{status:"syncing"});let o={created:[],merged:[],conflicted:[],rejected:[]},s=0,a=0,c=[];try{for await(let l of r.fullSync(i))if(c.push(l),s++,c.length>=this.config.minerBatchSize){a++,console.log(`[bootstrap] Batch ${a}: mining ${c.length} artifacts (${s} total)...`);let d=await this.processBatch(c);this.mergeResults(o,d),console.log(`[bootstrap] Batch ${a} done: +${d.created.length} created, +${d.merged.length} merged (running total: ${o.created.length} nodes, ${o.merged.length} merged)`),c=[]}if(c.length>0){a++,console.log(`[bootstrap] Batch ${a}: mining ${c.length} artifacts (${s} total)...`);let l=await this.processBatch(c);this.mergeResults(o,l),console.log(`[bootstrap] Batch ${a} done: +${l.created.length} created, +${l.merged.length} merged (running total: ${o.created.length} nodes, ${o.merged.length} merged)`)}this.registry.updateSyncState(e,{status:"idle",lastSyncAt:new Date,artifactCount:s});let u=Date.now()-n;return console.log(`[bootstrap] Completed for ${r.name}: ${s} artifacts, ${o.created.length} nodes created, ${o.merged.length} merged (${(u/1e3).toFixed(1)}s)`),{connectorId:e,totalArtifacts:s,pipeline:o,durationMs:u}}catch(u){throw this.registry.updateSyncState(e,{status:"error",error:u instanceof Error?u.message:String(u)}),u}}async incrementalSync(e){let r=this.registry.get(e);if(!r)throw new Error(`Connector "${e}" not found`);let i=this.registry.getConnection(e);if(!i)throw new Error(`Connector "${e}" is not connected`);let n=this.registry.getSyncState(e);if(!n?.lastSyncAt)return console.log(`[bootstrap] No previous sync found for ${e}, running full sync`),this.run(e);let o=Date.now(),s=n.lastSyncAt;console.log(`[bootstrap] Incremental sync for ${r.name} since ${s.toISOString()}`),this.registry.updateSyncState(e,{status:"syncing"});let a={created:[],merged:[],conflicted:[],rejected:[]},c=0,u=[];try{for await(let d of r.incrementalSync(i,s))if(u.push(d),c++,u.length>=this.config.minerBatchSize){let p=await this.processBatch(u);this.mergeResults(a,p),u=[]}if(u.length>0){let d=await this.processBatch(u);this.mergeResults(a,d)}this.registry.updateSyncState(e,{status:"idle",lastSyncAt:new Date,artifactCount:(n.artifactCount??0)+c});let l=Date.now()-o;return console.log(`[bootstrap] Incremental sync completed for ${r.name}: ${c} new artifacts (${(l/1e3).toFixed(1)}s)`),{connectorId:e,totalArtifacts:c,pipeline:a,durationMs:l}}catch(l){throw this.registry.updateSyncState(e,{status:"error",error:l instanceof Error?l.message:String(l)}),l}}async processBatch(e){let r=await this.miner.mine(e);return this.pipeline.process(r)}mergeResults(e,r){e.created.push(...r.created),e.merged.push(...r.merged),e.conflicted.push(...r.conflicted),e.rejected.push(...r.rejected)}}});var tb,rb=m(()=>{"use strict";tb={minerBatchSize:10,enableDedup:!0,autoPromoteThreshold:.7}});function k3(t,e){let r={...tb,...t},i=new As,n=new js,o=new Fs(r),s=new Us(i,n,o,r,e);return i.register(new Cs),i.register(new Ls),console.log("[ingest] Service initialized"),{registry:i,miner:n,pipeline:o,bootstrap:s}}var C$=m(()=>{"use strict";Hy();Zy();Jy();Yy();Xy();eb();rb();Hy();Zy();Jy();Yy();Xy();eb();rb()});var L$,j$,F$=m(()=>{"use strict";L$={missing_data:["customer_interview","team_dm","document_request"],stale:["customer_interview","market_signal"],contradiction:["customer_interview","team_dm"],untested_assumption:["customer_interview","micro_survey"],missing_validation:["customer_interview","micro_survey"],coverage_gap:["tribal_knowledge_mining","team_dm","document_request"]},j$={missing_data:"discovery",stale:"discovery",contradiction:"concept-test",untested_assumption:"concept-test",missing_validation:"sentiment",coverage_gap:"discovery"}});import{randomUUID as U$}from"node:crypto";var Ms,Wd,Gs,nb=m(()=>{"use strict";Ne();F$();Ms=new Map,Wd=new Map,Gs=class{constructor(e){this.eventBus=e}async start(){this.eventBus.subscriber.subscribe("gap.detected.>",async e=>{await this.handleGapDetected(e)},{group:"collection-planner"})}async handleGapDetected(e){let r=await Ze(e.gapNodeId,{layers:["permanent","draft"]});if(!r)return;let i=r.metadata?.gapType??"missing_data",n=this.computeBatchKey(r),o=Wd.get(n);if(o&&o.length>0){let a=Ms.get(o[0]);if(a&&a.status==="planned"){a.gapIds.push(e.gapNodeId);let c=this.generateQuestions(r);a.questions.push(...c);return}}let s=await this.createPlan(e.gapNodeId,i,r);Wd.has(n)||Wd.set(n,[]),Wd.get(n).push(s.id)}async createPlan(e,r,i){i||(i=await Ze(e,{layers:["permanent","draft"]}));let n=this.selectMethod(r,i),o=this.generateQuestions(i),s=this.generateSuccessCriteria(r,i),a={id:U$(),gapIds:[e],method:n,questions:o,successCriteria:s,priority:this.computePriority(i),batchId:null,status:"planned",externalStudyId:null,createdAt:new Date().toISOString(),completedAt:null};return Ms.set(a.id,a),a}async approvePlan(e){let r=Ms.get(e);return!r||r.status!=="planned"?null:(r.status="approved",r)}getPlan(e){return Ms.get(e)??null}listPlans(e){let r=Array.from(Ms.values());e?.status&&(r=r.filter(o=>e.status.includes(o.status))),e?.batchId&&(r=r.filter(o=>o.batchId===e.batchId)),e?.gapId&&(r=r.filter(o=>o.gapIds.includes(e.gapId))),r.sort((o,s)=>s.priority-o.priority);let i=e?.offset??0,n=e?.limit??50;return r.slice(i,i+n)}updatePlanStatus(e,r){let i=Ms.get(e);i&&(i.status=r,(r==="completed"||r==="failed")&&(i.completedAt=new Date().toISOString()))}selectMethod(e,r){let n=(L$[e]??["customer_interview"])[0],o=r?.metadata?.description??"";switch(n){case"customer_interview":return{type:"customer_interview",studyType:j$[e]??"discovery",segment:r?.metadata?.customerSegment??void 0};case"micro_survey":return{type:"micro_survey",trigger:"contextual",question:o};case"market_signal":return{type:"market_signal",sources:["web","competitors"],query:o};case"team_dm":return{type:"team_dm",targetRole:this.inferTargetRole(r),channel:"slack"};case"document_request":return{type:"document_request",targetPerson:"",topic:o};case"tribal_knowledge_mining":return{type:"tribal_knowledge_mining",targetTeam:this.inferTargetTeam(r),topic:o};default:return{type:"customer_interview",studyType:"discovery"}}}generateQuestions(e){if(!e)return["What can you tell us about this topic?"];let r=e.metadata?.description??"";switch(e.metadata?.gapType??"missing_data"){case"missing_data":return[`We're missing data on: ${r}. What has been your experience?`,"What factors are most important to you in this area?"];case"stale":return[`Our information about "${r}" may be outdated. Has anything changed recently?`,"What's different now compared to 3-6 months ago?"];case"contradiction":return[`We're seeing conflicting signals about: ${r}. What's your perspective?`,"In what context is this true vs. not true?"];case"untested_assumption":return[`We've assumed: ${r}. Does this match your experience?`,"What would change your mind about this?"];case"missing_validation":return[`We'd like to validate: ${r}. How accurate is this?`,"What's missing from this picture?"];default:return[`Tell us about your experience with: ${r}`]}}generateSuccessCriteria(e,r){let i=r?.metadata?.description??"this topic";switch(e){case"missing_data":return`Obtain at least 3 independent data points about: ${i}`;case"stale":return`Get current information (< 30 days old) about: ${i}`;case"contradiction":return"Identify which perspective is more accurate, or under what conditions each is true";case"untested_assumption":return"Validate or invalidate the assumption with at least 5 data points";case"missing_validation":return"Confirm or deny with direct evidence from users/stakeholders";case"coverage_gap":return"Document the missing context with source attribution";default:return"Resolve the gap with supporting evidence"}}computeBatchKey(e){if(!e)return U$();let r=e.metadata?.gapType??"unknown",i=e.tags[0]??r;return`${r}:${i}`}computePriority(e){if(!e)return .5;let r={critical:1,high:.75,medium:.5,low:.25},i=e.metadata?.severity??"medium";return r[i]??.5}inferTargetRole(e){if(!e)return"engineering";let r=e.metadata?.gapType??"";return r==="missing_data"||r==="missing_validation"?"product":"engineering"}inferTargetTeam(e){if(!e)return"engineering";let r=e.tags;return r.includes("pricing")||r.includes("business")?"product":r.includes("customer")||r.includes("churn")?"sales":"engineering"}}});function M$(t){return{system:"codify-interviews",reference:t,agentId:null,reliability:.85}}function P3(t){let e=t.match(/(?:on|about|validate):\s*(.+?)(?:\.|What|How|$)/i);if(e)return e[1].trim();let r=t.match(/"([^"]+)"/);return r?r[1].trim():t.replace(/^(Tell us about|What can you tell us about)\s*/i,"").slice(0,50).trim()||null}var $3,Bs,ib=m(()=>{"use strict";$3={progressPollIntervalMs:6e4,minInterviewsForSynthesis:3},Bs=class{constructor(e,r,i,n){this.mcp=e;this.planner=r;this.eventBus=i;this.config={...$3,...n}}config;activeStudies=new Map;pollTimers=new Map;async execute(e){if(e.method.type!=="customer_interview")return null;let r=e.method,i=await this.mcp.runStudy({type:r.studyType,description:e.questions.join(`
263
263
  `),segment:r.segment,skipContext:!1});return await this.mcp.approveStudy(i.studyId),this.activeStudies.set(e.id,i.studyId),this.planner.updatePlanStatus(e.id,"in_progress"),e.externalStudyId=i.studyId,await this.mcp.sendToParticipant(i.studyId),null}startPolling(e){let r=this.activeStudies.get(e);if(!r)return;let i=setInterval(async()=>{try{await this.checkStudyProgress(e,r)}catch(n){console.error(`[collection/external] Error polling study ${r}:`,n)}},this.config.progressPollIntervalMs);this.pollTimers.set(e,i)}stopPolling(e){let r=this.pollTimers.get(e);r&&(clearInterval(r),this.pollTimers.delete(e))}async checkStudyProgress(e,r){(await this.mcp.getStudyProgress(r)).completed>=this.config.minInterviewsForSynthesis&&await this.collectResults(e,r)&&(this.stopPolling(e),this.planner.updatePlanStatus(e,"completed"))}async collectResults(e,r){let i=this.planner.getPlan(e);if(!i)return null;let n=[];for(let o of i.questions){let s=P3(o);if(!s)continue;let a=await this.mcp.queryInsights(s);a.quotes.length>0&&n.push({source:M$(r),content:JSON.stringify(a),metadata:{type:"insight",topic:s,quoteCount:a.quotes.length,studyId:r}})}for(let o of i.questions){let s=await this.mcp.searchTranscripts(o);for(let a of s)n.push({source:M$(r),content:a.excerpt,metadata:{type:"transcript_excerpt",interviewId:a.interviewId,userId:a.userId,studyId:r}})}return n.length===0?null:{planId:e,rawData:n,structuredOutput:null,completedAt:new Date().toISOString()}}async addParticipants(e,r){let i=this.activeStudies.get(e);i&&(await this.mcp.registerUsers(r),await this.mcp.sendToParticipant(i,r.map(n=>n.userId)))}getStudyId(e){return this.activeStudies.get(e)}stopAll(){for(let[e]of this.pollTimers)this.stopPolling(e)}}});function G$(t,e){return{system:`internal-${t}`,reference:e,agentId:null,reliability:.7}}var R3,zs,ob=m(()=>{"use strict";Ne();R3={responseTimeoutMs:4320*60*1e3,channels:{}},zs=class{constructor(e,r,i){this.planner=e;this.eventBus=r;this.config={...R3,...i}}config;pendingRequests=new Map;async execute(e){switch(e.method.type){case"team_dm":return this.executeTeamDm(e);case"document_request":return this.executeDocumentRequest(e);case"tribal_knowledge_mining":return this.executeTribalKnowledgeMining(e);default:return null}}async executeTeamDm(e){let r=e.method,i=r.channel,n=this.config.channels[i];if(!n)return console.warn(`[collection/internal] Channel "${i}" not configured`),null;let o=await this.buildGapContext(e.gapIds),s=await n.sendRequest({recipient:r.targetRole,subject:`Context request: ${o.summary}`,body:this.formatTeamDmBody(o,e.questions),questions:e.questions,metadata:{planId:e.id,gapIds:e.gapIds,method:"team_dm"}});return s?this.responseToResult(e.id,s,i):(this.trackPendingRequest(e.id,i),this.planner.updatePlanStatus(e.id,"in_progress"),null)}async executeDocumentRequest(e){let r=e.method,i=this.config.channels.slack??this.config.channels.email;if(!i)return console.warn("[collection/internal] No channel configured for document request"),null;let n=await this.buildGapContext(e.gapIds),o=await i.sendRequest({recipient:r.targetPerson,subject:`Document request: ${r.topic}`,body:this.formatDocumentRequestBody(r.topic,n),questions:[`Can you share documentation about: ${r.topic}?`,...e.questions],metadata:{planId:e.id,gapIds:e.gapIds,method:"document_request",topic:r.topic}});return o?this.responseToResult(e.id,o,"document_request"):(this.trackPendingRequest(e.id,"document_request"),this.planner.updatePlanStatus(e.id,"in_progress"),null)}async executeTribalKnowledgeMining(e){let r=e.method,i=this.config.channels.slack??this.config.channels.email;if(!i)return console.warn("[collection/internal] No channel configured for tribal knowledge mining"),null;let n=await this.buildGapContext(e.gapIds),o=await i.sendRequest({recipient:r.targetTeam,subject:`Knowledge request: ${r.topic}`,body:this.formatTribalKnowledgeBody(r.topic,r.targetTeam,n,e.questions),questions:e.questions,metadata:{planId:e.id,gapIds:e.gapIds,method:"tribal_knowledge_mining",targetTeam:r.targetTeam,topic:r.topic}});return o?this.responseToResult(e.id,o,"tribal_knowledge_mining"):(this.trackPendingRequest(e.id,"tribal_knowledge_mining"),this.planner.updatePlanStatus(e.id,"in_progress"),null)}async handleResponse(e,r){let i=this.pendingRequests.get(e);return i?(this.pendingRequests.delete(e),this.responseToResult(e,r,i.channel)):null}checkTimeouts(){let e=Date.now(),r=[];for(let[i,n]of this.pendingRequests)e-n.sentAt>this.config.responseTimeoutMs&&(r.push(i),this.pendingRequests.delete(i),this.planner.updatePlanStatus(i,"failed"));return r}trackPendingRequest(e,r){this.pendingRequests.set(e,{planId:e,sentAt:Date.now(),channel:r})}responseToResult(e,r,i){let n=[];n.push({source:G$(i,r.responderId),content:r.rawText,metadata:{responderId:r.responderId,responderName:r.responderName,respondedAt:r.respondedAt,channel:i}});for(let[o,s]of Object.entries(r.answers))n.push({source:G$(i,r.responderId),content:s,metadata:{question:o,responderId:r.responderId,channel:i,type:"structured_answer"}});return{planId:e,rawData:n,structuredOutput:null,completedAt:new Date().toISOString()}}async buildGapContext(e){let r=[];for(let i of e){let n=await Ze(i,{layers:["permanent","draft"]});if(n){let o=n.metadata?.description??"Unknown context gap";r.push(o)}}return{summary:r.length>0?r[0]:"Context gap requiring team input",descriptions:r}}formatTeamDmBody(e,r){let i=["Hi! We've identified a gap in our product context that your expertise could help fill.","",`Context: ${e.summary}`];if(e.descriptions.length>1){i.push("","Related gaps:");for(let n of e.descriptions)i.push(` - ${n}`)}i.push("","Questions:");for(let n of r)i.push(` - ${n}`);return i.join(`
264
264
  `)}formatDocumentRequestBody(e,r){return[`We're looking for documentation or artifacts related to: ${e}`,"",`This will help fill a context gap: ${r.summary}`,"","Any of the following would be helpful:"," - Design docs, RFCs, or decision records"," - Meeting notes or discussion summaries"," - Data analysis or research findings"," - Links to relevant internal wiki pages"].join(`
265
265
  `)}formatTribalKnowledgeBody(e,r,i,n){let o=[`Hi ${r} team! We're trying to capture institutional knowledge about: ${e}`,"",`Background: ${i.summary}`,"","We'd love to hear the team's perspective on:"];for(let s of n)o.push(` - ${s}`);return o.push("","Any context \u2014 even informal, partial, or anecdotal \u2014 is valuable."),o.join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codified/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "Codify — Living Context Graph for AI-Native Teams",
6
6
  "repository": {