@agentskit/doc-bridge 1.6.0 → 1.6.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.
- package/CHANGELOG.md +6 -0
- package/action.yml +1 -1
- package/dist/cli/program.js +7 -4
- package/dist/cli/program.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/mcpb/manifest.json +1 -1
- package/package.json +1 -1
- package/skills/doc-bridge-handoff/scripts/resolve-handoff.mjs +1 -1
- package/src/report/html.ts +6 -3
- package/src/version.ts +1 -1
package/mcpb/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "doc-bridge",
|
|
4
4
|
"display_name": "Doc Bridge",
|
|
5
|
-
"version": "1.6.
|
|
5
|
+
"version": "1.6.1",
|
|
6
6
|
"description": "Deterministic repository handoffs for coding agents, running locally without an LLM or API key.",
|
|
7
7
|
"long_description": "Doc Bridge turns a repository's own documentation and ownership metadata into deterministic handoffs: where an agent should start, which paths it may edit, which checks it must run, and when a human must take over. The local connector exposes the same read-only contract available through Doc Bridge CLI and CI.",
|
|
8
8
|
"author": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentskit/doc-bridge",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"mcpName": "io.github.AgentsKit-io/doc-bridge",
|
|
5
5
|
"description": "Human↔agent documentation bridge — deterministic handoffs, doc-site links, memory→docs, optional AgentsKit RAG/chat.",
|
|
6
6
|
"type": "module",
|
package/src/report/html.ts
CHANGED
|
@@ -75,19 +75,22 @@ const byId=new Map(data.entities.map((entity)=>[entity.id,entity]));
|
|
|
75
75
|
const parent=new Map();
|
|
76
76
|
const relationById=new Map(data.relations.map((relation)=>[relation.id,relation]));
|
|
77
77
|
data.relations.forEach((relation)=>{if(relation.kind==='contains'&&!parent.has(relation.to))parent.set(relation.to,relation.from)});
|
|
78
|
+
const findingIndex=new Map(),relationFindingIndex=new Map();
|
|
79
|
+
const addFinding=(index,id,finding)=>{const findings=index.get(id)||[];findings.push(finding);index.set(id,findings)};
|
|
80
|
+
data.diagnostics.forEach((finding)=>{(finding.entityIds||[]).forEach((id)=>addFinding(findingIndex,id,finding));(finding.relationIds||[]).forEach((id)=>addFinding(relationFindingIndex,id,finding));});
|
|
78
81
|
const state={lens:'architecture',level:'overview',selected:null,query:'',status:'',severity:''};
|
|
79
82
|
const rootOf=(id)=>{let current=id;const seen=new Set();while(parent.has(current)&&!seen.has(current)){seen.add(current);current=parent.get(current)}return current};
|
|
80
83
|
const packageNodes=()=>data.entities.filter((entity)=>entity.kind==='package'||entity.kind==='external');
|
|
81
84
|
const groupFor=(id)=>{const entity=byId.get(id);if(!entity)return id;if(entity.kind==='package'||entity.kind==='external')return entity.id;const root=rootOf(id);return byId.has(root)?root:id};
|
|
82
85
|
const label=(entity)=>entity?.name||entity?.id||'Unknown';
|
|
83
86
|
const short=(value,max)=>{const text=String(value??'');return text.length>max?text.slice(0,max-1)+'…':text};
|
|
84
|
-
const diagnosticsFor=(id)=>
|
|
85
|
-
const relationHealth=(relation)=>{const findings=
|
|
87
|
+
const diagnosticsFor=(id)=>findingIndex.get(id)||[];
|
|
88
|
+
const relationHealth=(relation)=>{const findings=relationFindingIndex.get(relation.id)||[];return findings.some((finding)=>finding.severity==='error')?'error':findings.length?'warn':''};
|
|
86
89
|
const degreeMap=(relations)=>{const degrees=new Map();relations.forEach((relation)=>{degrees.set(relation.from,(degrees.get(relation.from)||0)+1);degrees.set(relation.to,(degrees.get(relation.to)||0)+1)});return degrees};
|
|
87
90
|
const selectedScope=()=>{if(!state.selected)return null;const selected=byId.get(state.selected);return selected?.kind==='package'?selected.id:groupFor(state.selected)};
|
|
88
91
|
const nodesFor=()=>{const packages=packageNodes();if(state.level==='overview'||(state.level==='package'&&!state.selected))return packages.length?packages:data.entities.filter((entity)=>entity.kind!=='document').slice(0,80);const scope=selectedScope();let nodes=data.entities.filter((entity)=>{if(entity.kind==='package'||entity.kind==='external')return false;if(entity.kind==='document'&&state.level==='module')return false;return !scope||groupFor(entity.id)===scope});if(state.level==='module')nodes=nodes.filter((entity)=>entity.kind==='module');if(state.level==='file')nodes=nodes.filter((entity)=>Boolean(entity.path));const degrees=degreeMap(data.relations);return nodes.sort((a,b)=>(degrees.get(b.id)||0)-(degrees.get(a.id)||0)||a.id.localeCompare(b.id)).slice(0,160)};
|
|
89
92
|
const graphModel=()=>{const nodes=nodesFor();const ids=new Set(nodes.map((node)=>node.id));const aggregate=state.level==='overview'||(state.level==='package'&&!state.selected);const edges=new Map();data.relations.forEach((relation)=>{const from=aggregate?groupFor(relation.from):relation.from;const to=aggregate?groupFor(relation.to):relation.to;if(from===to||!ids.has(from)||!ids.has(to))return;const key=from+'→'+to;const current=edges.get(key)||{from,to,count:0,kinds:new Set(),health:''};current.count++;current.kinds.add(relation.kind);current.health=current.health==='error'||relationHealth(relation)==='error'?'error':current.health||relationHealth(relation);edges.set(key,current)});return{nodes,edges:[...edges.values()].sort((a,b)=>b.count-a.count||a.from.localeCompare(b.from)).slice(0,600)}};
|
|
90
|
-
const nodeIssues=(nodeId)=>{const ids=new Set([nodeId]);data.entities.forEach((entity)=>{if(groupFor(entity.id)===nodeId)ids.add(entity.id)});
|
|
93
|
+
const nodeIssues=(nodeId)=>{const ids=new Set([nodeId]);data.entities.forEach((entity)=>{if(groupFor(entity.id)===nodeId)ids.add(entity.id)});const findings=new Set();ids.forEach((id)=>(findingIndex.get(id)||[]).forEach((finding)=>findings.add(finding)));data.relations.forEach((relation)=>{if(ids.has(relation.from)||ids.has(relation.to))(relationFindingIndex.get(relation.id)||[]).forEach((finding)=>findings.add(finding))});return[...findings]};
|
|
91
94
|
const renderInsights=()=>{const undocumented=data.diagnostics.filter((finding)=>finding.status==='undocumented').length;const drift=data.diagnostics.filter((finding)=>finding.status==='stale-or-unverified'||finding.status==='conflict').length;const unsupported=data.coverage.filter((entry)=>entry.status==='not-analyzed'||entry.status==='partial').length;const model=graphModel();const degrees=degreeMap(model.edges);const values=[...degrees.values()].sort((a,b)=>a-b);const median=values.length?values[Math.floor(values.length/2)]:0;const hot=[...degrees.values()].filter((value)=>value>=Math.max(4,median*2)).length;const isolated=model.nodes.filter((node)=>!model.edges.some((edge)=>edge.from===node.id||edge.to===node.id)).length;document.querySelector('#insights').innerHTML=[['Documentation drift',undocumented+drift,'Relations or docs needing comparison.',''],['Unanalyzed scope',unsupported,'Coverage gaps are explicit.',''],['Connectivity hotspots',hot,'Heuristic: unusually connected nodes.','heuristic'],['Disconnected nodes',isolated,'Heuristic: no visible edge at this level.','heuristic']].map(([title,count,copy,tag])=>'<article class="insight"><h3>'+esc(title)+' <span class="tag '+tag+'">'+(tag?'heuristic':'signal')+'</span></h3><p><strong>'+count+'</strong> · '+esc(copy)+'</p></article>').join('')};
|
|
92
95
|
const renderGraph=()=>{const model=graphModel();const svg=document.querySelector('#graph');if(!model.nodes.length){svg.innerHTML='<text x="500" y="270" text-anchor="middle" class="subtle">No entities match this level.</text>';return}const width=1000,height=560,pad=56,columns=Math.max(1,Math.ceil(Math.sqrt(model.nodes.length))),rows=Math.ceil(model.nodes.length/columns),positions=new Map();model.nodes.forEach((node,index)=>{const col=index%columns,row=Math.floor(index/columns);positions.set(node.id,{x:pad+(col+0.5)*(width-2*pad)/columns,y:pad+(row+0.5)*(height-2*pad)/rows})});const defs='<defs><marker id="arrow" markerWidth="8" markerHeight="8" refX="7" refY="3" orient="auto"><path d="M0,0 L0,6 L7,3 z" fill="#9eb0a4"/></marker></defs>';const edges=model.edges.map((edge)=>{const from=positions.get(edge.from),to=positions.get(edge.to);if(!from||!to)return '';const midX=(from.x+to.x)/2,midY=(from.y+to.y)/2;return '<g><line class="edge '+(edge.health?'alert':'')+'" x1="'+from.x+'" y1="'+from.y+'" x2="'+to.x+'" y2="'+to.y+'" marker-end="url(#arrow)"/><text class="edge-label" x="'+midX+'" y="'+midY+'">'+esc(edge.count>1?edge.count+'×':'')+'</text></g>'}).join('');const nodes=model.nodes.map((node)=>{const pos=positions.get(node.id),issues=nodeIssues(node.id),degree=(degreeMap(model.edges).get(node.id)||0),selected=state.selected===node.id?' selected':'',issue=issues.length?' issue':'';return '<g class="graph-node'+selected+issue+'" role="button" tabindex="0" data-node="'+esc(node.id)+'" transform="translate('+(pos.x-62)+','+(pos.y-27)+')"><title>'+esc(label(node))+' · '+esc(node.kind)+'</title><rect width="124" height="54" rx="8"></rect><text class="node-label" x="10" y="19">'+esc(short(label(node),18))+'</text><text class="node-kind" x="10" y="34">'+esc(short(node.kind,18))+'</text><text class="node-count" x="112" y="19" text-anchor="end">'+(degree||'')+'</text></g>'}).join('');svg.innerHTML=defs+edges+nodes;svg.querySelectorAll('[data-node]').forEach((node)=>{node.addEventListener('click',()=>{state.selected=node.dataset.node;render()});node.addEventListener('keydown',(event)=>{if(event.key==='Enter'||event.key===' '){event.preventDefault();state.selected=node.dataset.node;render()}})});document.querySelector('#map-note').textContent=(state.level==='overview'?'Grouped package/external view. ':state.level+' view. ')+'Edges are aggregated from canonical relations; '+model.edges.length+' visible connection groups.'};
|
|
93
96
|
const renderDetails=()=>{const panel=document.querySelector('#details'),entity=state.selected?byId.get(state.selected):null;if(!entity){panel.innerHTML='<p class="subtle">Select a node in the map to inspect its evidence, connectivity, and findings.</p>';return}const incoming=data.relations.filter((relation)=>relation.to===entity.id),outgoing=data.relations.filter((relation)=>relation.from===entity.id),findings=diagnosticsFor(entity.id),evidence=[...(entity.evidence||[]),...incoming.flatMap((relation)=>relation.evidence||[]),...outgoing.flatMap((relation)=>relation.evidence||[])].slice(0,8);panel.innerHTML='<div class="eyebrow">Selected entity</div><h2 class="detail-title">'+esc(label(entity))+'</h2><span class="tag">'+esc(entity.kind)+'</span><p class="path">'+esc(entity.path||entity.id)+'</p><div class="detail-grid"><div><b>'+incoming.length+'</b><span>incoming</span></div><div><b>'+outgoing.length+'</b><span>outgoing</span></div><div><b>'+findings.length+'</b><span>findings</span></div><div><b>'+evidence.length+'</b><span>evidence items</span></div></div><h3>Evidence</h3><ul class="list">'+(evidence.length?evidence.map((item)=>'<li>'+esc(item.path+(item.lineStart?':'+item.lineStart:'')+(item.context?' — '+item.context:''))+'</li>').join(''):'<li>No evidence recorded.</li>')+'</ul>'+(findings.length?'<h3 style="margin-top:16px">Attention</h3><ul class="list">'+findings.slice(0,5).map((finding)=>'<li><span class="tag '+esc(finding.severity)+'">'+esc(finding.severity)+'</span> '+esc(finding.code)+'</li>').join('')+'</ul>':'')};
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '1.6.
|
|
1
|
+
export const PACKAGE_VERSION = '1.6.1'
|