@oddessentials/agent-guild 1.21.1 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/bin/agent-guild-report.mjs +5 -106
  2. package/bin/agent-guild.mjs +2 -0
  3. package/bin/native/darwin-arm64/agent-guild-report +0 -0
  4. package/bin/native/darwin-x64/agent-guild-report +0 -0
  5. package/bin/native/linux-arm64/agent-guild-report +0 -0
  6. package/bin/native/linux-x64/agent-guild-report +0 -0
  7. package/bin/native/win32-arm64/agent-guild-report.exe +0 -0
  8. package/bin/native/win32-x64/agent-guild-report.exe +0 -0
  9. package/bin/windows/arm64/agent-guild-start.exe +0 -0
  10. package/bin/windows/x64/agent-guild-start.exe +0 -0
  11. package/config/providers.default.json +4 -0
  12. package/docs/api.md +27 -5
  13. package/examples/terminal-ai-chat.json +27 -0
  14. package/node_modules/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  15. package/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  16. package/node_modules/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  17. package/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  18. package/package.json +2 -1
  19. package/src/manager/install-channels.mjs +3 -0
  20. package/src/manager/main.mjs +6 -2
  21. package/src/manager/mcp-connect.mjs +249 -0
  22. package/src/manager/providers.mjs +23 -4
  23. package/src/manager/report-shims.mjs +47 -3
  24. package/src/manager/server.mjs +31 -3
  25. package/src/manager/session-manager.mjs +36 -2
  26. package/src/manager/session.mjs +2 -1
  27. package/src/report/hook-event.mjs +40 -0
  28. package/src/report/transcripts.mjs +95 -0
  29. package/web/app.js +52 -3
  30. package/web/index.html +7 -1
  31. package/web/styles.css +2 -0
  32. package/web/yard/art.json +1 -1
  33. package/web/yard/renderer.js +110 -36
  34. package/web/yard/view.js +13 -3
@@ -20,7 +20,8 @@ const GLOW = { off: 0, low: .55, high: 1 }, GLOW_GAIN = { light: .9, dark: 2.2 }
20
20
  // fronts, and a generated hall's baked glow map.
21
21
  const glows = m => m.name === 'window' || m.name === 'magic' || m.name === 'officeGlass' || m.emissiveMap;
22
22
  const PARTICLES = 640;
23
- const FIREWORK_COLORS = [0xffd36b, 0xff6b8a, 0x7bd7ff, 0xa8ff7b, 0xffffff];
23
+ const FIREWORK_COLORS = [0xffc857, 0xff507c, 0x53cfff, 0xb28aff, 0x7dffae];
24
+ const FIREWORKS = { points: 1024, batches: 8, bursts: 24, stars: 32, trail: 4, launch: .5, life: 1.7 };
24
25
  // How many tags' heights a character's tag may rise above its character
25
26
  // before it hides: any higher, it reads as another's.
26
27
  const RISE = 2, CHIP_GAP = 4;
@@ -186,7 +187,7 @@ export class YardRenderer {
186
187
  if(this.disposed||request!==this.worldRequest){disposeWorld(loaded.scene);return;}
187
188
  this.request++;
188
189
  this.clearUnits();
189
- this.clearProps();this.releaseStation();this.releaseEffects();
190
+ this.clearProps();this.releaseStation();this.releaseEffects();this.clearFireworks();
190
191
  this.closeCrowd(false);
191
192
  for(const item of this.halls.values()){item.label.remove();item.chip.remove();}
192
193
  this.halls.clear();
@@ -886,50 +887,119 @@ export class YardRenderer {
886
887
  this.scatter(positions,velocity,{color:0xffc46b,size:.09,life:.55,gravity:9});
887
888
  }
888
889
  fireworks() {
889
- if(this.reduced||this.disposed||!this.world)return;
890
- const spots=[{x:0,y:4,z:0}];
890
+ if(this.reduced||this.disposed||!this.world||this.shows.length||this.sparks.some(s=>s.firework))return;
891
+ this.camera.updateMatrixWorld();
892
+ const spots=[{x:0,y:6.5,z:0}];
893
+ vector.set(0,6.5,0).project(this.camera);
894
+ if(Math.abs(vector.x)>.7||Math.abs(vector.y)>.7)spots[0]={x:this.controls.target.x,y:this.controls.target.y+3,z:this.controls.target.z};
891
895
  for(const item of this.halls.values()){
892
- if(!item.root.visible)continue;
893
- (item.smoke||item.root).getWorldPosition(vector);spots.push({x:vector.x,y:vector.y+3.5,z:vector.z});
896
+ if(!item.root.visible||spots.length>=FIREWORKS.bursts-3)continue;
897
+ (item.smoke||item.root).getWorldPosition(vector);vector.y+=5.5;
898
+ const spot={x:vector.x,y:vector.y,z:vector.z};
899
+ vector.project(this.camera);
900
+ if(Math.abs(vector.x)<.9&&Math.abs(vector.y)<.8)spots.push(spot);
894
901
  }
895
- for(const spot of spots)this.shows.push({...spot,due:Math.random()*1.2,left:4});
896
- this.drawOnce();
897
- }
898
- burst({x,y,z}) {
899
- const count=90,positions=new Float32Array(count*3),velocity=[];
900
- const ox=x+(Math.random()-.5)*2,oy=y+Math.random()*2,oz=z+(Math.random()-.5)*2;
901
- for(let i=0;i<count;i++){
902
- positions.set([ox,oy,oz],i*3);
903
- const u=Math.random()*2-1,a=Math.random()*Math.PI*2,r=Math.sqrt(1-u*u),s=2.8+Math.random()*1.6;
904
- velocity.push([r*Math.cos(a)*s,u*s+.8,r*Math.sin(a)*s]);
902
+ const count=Math.min(FIREWORKS.bursts,Math.max(12,spots.length+5)),regular=count-3;
903
+ const offset=Math.floor(Math.random()*FIREWORK_COLORS.length);
904
+ for(let i=0;i<count;i++)this.shows.push({...spots[i%spots.length],index:i,color:FIREWORK_COLORS[(i+offset)%FIREWORK_COLORS.length],
905
+ finale:i>=regular,due:i<regular?i*2.2/(regular-1):2.8+(i-regular)*.13});
906
+ this.updateShows(0);this.drawOnce();
907
+ }
908
+ fireworkMap() {
909
+ if(this.fireworkTexture)return this.fireworkTexture;
910
+ const canvas=Object.assign(document.createElement('canvas'),{width:32,height:32}),c=canvas.getContext('2d');
911
+ const glow=c.createRadialGradient(16,16,0,16,16,16);
912
+ glow.addColorStop(0,'#fff');glow.addColorStop(.18,'#fff');glow.addColorStop(.45,'rgba(255,255,255,.45)');glow.addColorStop(1,'rgba(255,255,255,0)');
913
+ c.fillStyle=glow;c.fillRect(0,0,32,32);
914
+ this.fireworkTexture=new T.TextureLoader().load(canvas.toDataURL(),()=>{this.dirty=true;this.drawOnce();});
915
+ return this.fireworkTexture;
916
+ }
917
+ burst(show) {
918
+ const count=FIREWORKS.stars*FIREWORKS.trail;
919
+ let batches=0,live=0;
920
+ for(const spark of this.sparks)if(spark.firework){batches++;live+=spark.points.geometry.attributes.position.count;}
921
+ if(this.sparks.length>=48||batches>=FIREWORKS.batches-(show.finale?0:3)||live+count>FIREWORKS.points)return;
922
+ const width=(this.camera.right-this.camera.left)/this.camera.zoom,height=(this.camera.top-this.camera.bottom)/this.camera.zoom;
923
+ const scale=Math.min(1.3,width/14,height/14);
924
+ this.camera.updateMatrixWorld();
925
+ vector.set(show.x+(Math.random()-.5)*2*scale,show.y+(Math.random()-.5)*scale,show.z).project(this.camera);
926
+ vector.x=T.MathUtils.clamp(vector.x,-.55,.55);vector.y=T.MathUtils.clamp(vector.y,-.1,.55);vector.unproject(this.camera);
927
+ const firework={x:vector.x,y:vector.y,z:vector.z,scale,size:show.finale?8:6,kind:show.index%3,bloom:false,colors:new Float32Array(count*3)};
928
+ const positions=new Float32Array(count*3),velocity=new Float32Array(FIREWORKS.stars*3),color=new T.Color(show.color),gold=new T.Color(0xffcf78);
929
+ const turn=Math.random()*Math.PI*2,{right,up}=viewBasis();
930
+ for(let i=0;i<FIREWORKS.stars;i++){
931
+ const u=1-2*(i+.5)/FIREWORKS.stars,a=i*Math.PI*(3-Math.sqrt(5))+turn,r=Math.sqrt(1-u*u),speed=(3.5+Math.random())*scale*(show.finale?1.2:1);
932
+ if(firework.kind===1){
933
+ const angle=i/FIREWORKS.stars*Math.PI*2;
934
+ for(let k=0;k<3;k++)velocity[i*3+k]=(right[k]*Math.cos(angle)+up[k]*Math.sin(angle))*speed;
935
+ } else velocity.set([r*Math.cos(a)*speed,(u+.2)*speed,r*Math.sin(a)*speed],i*3);
936
+ for(let j=0;j<FIREWORKS.trail;j++){
937
+ const at=(i*FIREWORKS.trail+j)*3,brightness=1-j*.23;
938
+ positions.set([firework.x,firework.y-3*scale,firework.z],at);
939
+ firework.colors.set([color.r*brightness,color.g*brightness,color.b*brightness],at);
940
+ if(j===0)for(let k=0;k<3;k++)firework.colors[at+k]=firework.colors[at+k]*.55+.45;
941
+ }
905
942
  }
906
- this.scatter(positions,velocity,{color:FIREWORK_COLORS[Math.floor(Math.random()*FIREWORK_COLORS.length)],size:.3,life:1.5,gravity:2});
943
+ const colors=new Float32Array(count*3);
944
+ for(let i=0;i<12;i++)colors.set([gold.r*(1-i/13),gold.g*(1-i/13),gold.b*(1-i/13)],i*3);
945
+ firework.initialColors=colors;
946
+ this.scatter(positions,velocity,{color:0xffffff,size:firework.size,life:FIREWORKS.launch+FIREWORKS.life,gravity:0,firework});
907
947
  }
908
- scatter(positions,velocity,{color,size,life,gravity}) {
948
+ scatter(positions,velocity,{color,size,life,gravity,firework=null}) {
909
949
  if(this.sparks.length>=48)return;
910
950
  const geometry=new T.BufferGeometry();geometry.setAttribute('position',new T.BufferAttribute(positions,3));
911
- const material=new T.PointsMaterial({color,size,transparent:true,opacity:1,blending:T.AdditiveBlending,depthWrite:false});
951
+ if(firework){geometry.setAttribute('color',new T.BufferAttribute(firework.initialColors,3));geometry.setDrawRange(0,12);}
952
+ const material=new T.PointsMaterial({color,size,transparent:true,opacity:1,blending:T.AdditiveBlending,depthWrite:false,
953
+ ...(firework?{map:this.fireworkMap(),vertexColors:true,toneMapped:false}: {})});
912
954
  const points=new T.Points(geometry,material);points.frustumCulled=false;
913
- this.scene.add(points);this.sparks.push({points,velocity,age:0,life,gravity});
955
+ this.scene.add(points);this.sparks.push({points,velocity,age:0,life,gravity,firework});
914
956
  }
915
957
  updateShows(dt) {
916
- for(const show of this.shows){
917
- show.due-=dt;
918
- if(show.due>0)continue;
919
- this.burst(show);show.left--;show.due=.3+Math.random()*.4;
958
+ for(let i=0;i<this.shows.length;){
959
+ const show=this.shows[i];show.due-=dt;
960
+ if(show.due>0){i++;continue;}
961
+ this.burst(show);this.shows.splice(i,1);
920
962
  }
921
- this.shows=this.shows.filter(show=>show.left>0);
963
+ }
964
+ updateFirework(spark) {
965
+ const {firework:f,points,velocity,age}=spark,{position,color}=points.geometry.attributes;
966
+ const t=age-FIREWORKS.launch;
967
+ if(t<0){
968
+ for(let i=0;i<12;i++){
969
+ const u=Math.max(0,age-i*.014)/FIREWORKS.launch;
970
+ position.setXYZ(i,f.x-.25*f.scale*(1-u),f.y-3*f.scale*(1-u)*(1-u),f.z);
971
+ }
972
+ return;
973
+ }
974
+ if(!f.bloom){color.array.set(f.colors);color.needsUpdate=true;points.geometry.setDrawRange(0,FIREWORKS.stars*FIREWORKS.trail);f.bloom=true;}
975
+ const gravity=(f.kind===2?2.4:1.2)*f.scale;
976
+ for(let j=0;j<FIREWORKS.trail;j++){
977
+ const time=Math.max(0,t-j*.055),travel=(1-Math.exp(-1.5*time))/1.5,fall=gravity*time*time/2;
978
+ for(let i=0;i<FIREWORKS.stars;i++)position.setXYZ(i*FIREWORKS.trail+j,f.x+velocity[i*3]*travel,f.y+velocity[i*3+1]*travel-fall,f.z+velocity[i*3+2]*travel);
979
+ }
980
+ points.material.size=f.size*(1-t/FIREWORKS.life/3);
981
+ points.material.opacity=Math.pow(Math.max(0,1-t/FIREWORKS.life),.65);
982
+ }
983
+ clearFireworks() {
984
+ this.shows=[];
985
+ for(let i=this.sparks.length-1;i>=0;i--)if(this.sparks[i].firework){
986
+ const {points}=this.sparks[i];this.scene.remove(points);points.geometry.dispose();points.material.dispose();this.sparks.splice(i,1);
987
+ }
988
+ this.dirty=true;
922
989
  }
923
990
  updateSparks(dt) {
924
- for(const spark of [...this.sparks]){
925
- spark.age+=dt;
926
- const array=spark.points.geometry.attributes.position.array;
927
- spark.velocity.forEach((v,i)=>{v[1]-=spark.gravity*dt;array[i*3]+=v[0]*dt;array[i*3+1]=Math.max(.02,array[i*3+1]+v[1]*dt);array[i*3+2]+=v[2]*dt;});
991
+ if(this.sparks.length)this.dirty=true;
992
+ for(let n=this.sparks.length-1;n>=0;n--){
993
+ const spark=this.sparks[n];spark.age+=dt;
994
+ if(spark.age>=spark.life){this.scene.remove(spark.points);spark.points.geometry.dispose();spark.points.material.dispose();this.sparks.splice(n,1);continue;}
995
+ if(spark.firework)this.updateFirework(spark);
996
+ else {
997
+ const array=spark.points.geometry.attributes.position.array;
998
+ spark.velocity.forEach((v,i)=>{v[1]-=spark.gravity*dt;array[i*3]+=v[0]*dt;array[i*3+1]=Math.max(.02,array[i*3+1]+v[1]*dt);array[i*3+2]+=v[2]*dt;});
999
+ spark.points.material.opacity=Math.max(0,1-spark.age/spark.life);
1000
+ }
928
1001
  spark.points.geometry.attributes.position.needsUpdate=true;
929
- spark.points.material.opacity=Math.max(0,1-spark.age/spark.life);
930
- if(spark.age>spark.life){this.scene.remove(spark.points);spark.points.geometry.dispose();spark.points.material.dispose();this.sparks.splice(this.sparks.indexOf(spark),1);}
931
1002
  }
932
- if(this.sparks.length)this.dirty=true;
933
1003
  }
934
1004
  helperClip(helper,name) {
935
1005
  const clip=helper.clips.find(c=>c.name===name)||helper.clips.find(c=>c.name===LEGACY[name])||helper.clips[0];
@@ -994,11 +1064,14 @@ export class YardRenderer {
994
1064
  const size=photoSize(w,h,buffer.x,buffer.y);
995
1065
  const viewport=this.renderer.getViewport({copy:v=>v.clone()}),ratio=this.renderer.getPixelRatio();
996
1066
  const particleScale=this.effects?.points.material.uniforms.scale,scale=particleScale?.value;
997
- const radius=(this.effects?Math.max(...this.effects.preset.size):0)*size.height*this.camera.projectionMatrix.elements[5]/4;
1067
+ const fireworks=this.sparks.filter(s=>s.firework).map(s=>({material:s.points.material,size:s.points.material.size}));
1068
+ const radius=Math.max((this.effects?Math.max(...this.effects.preset.size):0)*size.height*this.camera.projectionMatrix.elements[5]/4,
1069
+ ...fireworks.map(s=>s.size*size.scale/2));
998
1070
  const pad=Math.ceil(radius)+1,tw=buffer.x+2*pad,th=buffer.y+2*pad;
999
1071
  const canvas=Object.assign(document.createElement('canvas'),{width:size.width,height:size.height});
1000
1072
  let tags;
1001
1073
  try {
1074
+ for(const spark of fireworks)spark.material.size=spark.size*size.scale/ratio;
1002
1075
  this.positionLabels();
1003
1076
  tags=this.tags();
1004
1077
  for(const unit of this.units.values()){unit.ring.material.color.set(unit.session?.provider.color||0xbaaa80);unit.ring.scale.setScalar(1);}
@@ -1013,6 +1086,7 @@ export class YardRenderer {
1013
1086
  context.drawImage(this.canvas,x,y);
1014
1087
  }
1015
1088
  } finally {
1089
+ for(const spark of fireworks)spark.material.size=spark.size;
1016
1090
  this.renderer.setViewport(viewport);
1017
1091
  if(particleScale)particleScale.value=scale;
1018
1092
  this.camera.clearViewOffset();
@@ -1118,8 +1192,7 @@ export class YardRenderer {
1118
1192
  this.reduced=value;
1119
1193
  if(value)for(const unit of this.units.values()){this.unlook(unit);unit.lookYaw=0;unit.lookPitch=0;}
1120
1194
  if(value)for(const unit of this.units.values())if(unit.moving&&unit.target){this.arrive(unit);this.play(unit);}
1121
- // Reduced motion shows each hall's glow as it stands, and no effects.
1122
- if(value){for(const item of this.halls.values())item.level=item.target;this.glow();this.stillEffects();this.shows=[];}
1195
+ if(value){for(const item of this.halls.values())item.level=item.target;this.glow();this.stillEffects();this.clearFireworks();}
1123
1196
  this.dirty=true;this.drawOnce();
1124
1197
  }
1125
1198
  setActive(value) {
@@ -1220,7 +1293,8 @@ export class YardRenderer {
1220
1293
  dispose() {
1221
1294
  if(this.disposed)return;
1222
1295
  this.disposed=true;this.request++;this.worldRequest++;cancelAnimationFrame(this.frame);clearTimeout(this.stageTimer);
1223
- for(const spark of this.sparks){spark.points.geometry.dispose();spark.points.material.dispose();}this.sparks=[];this.shows=[];
1296
+ this.clearFireworks();this.fireworkTexture?.dispose();
1297
+ for(const spark of this.sparks){spark.points.geometry.dispose();spark.points.material.dispose();}this.sparks=[];
1224
1298
  this.releaseEffects();this.clearProps();
1225
1299
  this.loadingManager.abort();this.pending?.close();this.pending=null;
1226
1300
  this.resizeObserver.disconnect();this.controls.dispose();this.clearUnits();
package/web/yard/view.js CHANGED
@@ -29,6 +29,12 @@ export function initYard(controller) {
29
29
  let view = root.dataset.view === 'yard' ? 'yard' : 'cards';
30
30
  let snapshot = controller.snapshot();
31
31
  let lastSkin = '', lastTheme = '', wasConnected = false;
32
+ const celebrate = () => { if (!disposed && sceneVisible()) renderer?.fireworks(); };
33
+ const fireworksButton = () => {
34
+ const button = $('yard-fireworks');
35
+ button.disabled = !renderer || disposed || motion.matches;
36
+ button.title = motion.matches ? 'Fireworks off: reduced motion is enabled' : 'Fireworks in this Yard only';
37
+ };
32
38
  const sceneVisible = () => view === 'yard' && !$('app').hidden && document.visibilityState !== 'hidden' && $('terminal-panel').hidden;
33
39
  const skinEntry = (skin = root.dataset.skin) => (window.agentGuildSkins || []).find((item) => item.id === skin) || null;
34
40
  const yardOff = root.dataset.yard === 'none';
@@ -161,6 +167,7 @@ export function initYard(controller) {
161
167
  hideLoading();
162
168
  $('yard-stage').dataset.ready = 'true';
163
169
  $('yard-photo').disabled = false;
170
+ fireworksButton();
164
171
  } catch (err) {
165
172
  candidate?.dispose();
166
173
  if (attempt === sceneAttempt && !disposed) {
@@ -183,6 +190,7 @@ export function initYard(controller) {
183
190
  $('yard-failure').hidden = false;
184
191
  $('yard-stage').dataset.ready = 'false';
185
192
  $('yard-photo').disabled = true;
193
+ fireworksButton();
186
194
  if (restoreFocus) $('yard-retry').focus();
187
195
  }
188
196
  function roster() {
@@ -309,6 +317,8 @@ export function initYard(controller) {
309
317
  $('yard-focus').addEventListener('click',() => renderer?.focus(selected));
310
318
  $('yard-zoom-in').addEventListener('click',() => renderer?.zoom(1.2));
311
319
  $('yard-zoom-out').addEventListener('click',() => renderer?.zoom(1/1.2));
320
+ $('yard-fireworks').addEventListener('click',celebrate);
321
+ fireworksButton();
312
322
  $('yard-photo').hidden = !controller.photo;
313
323
  $('yard-photo').addEventListener('click',async () => {
314
324
  let YardPhoto;
@@ -334,7 +344,7 @@ export function initYard(controller) {
334
344
  setView(preferYard && skinAllowsYard() ? 'yard' : 'cards', { remember: false });
335
345
  renderer?.setActive(sceneVisible());
336
346
  };
337
- const motionChange = () => renderer?.setReducedMotion(motion.matches);
347
+ const motionChange = () => { renderer?.setReducedMotion(motion.matches); fireworksButton(); };
338
348
  const pageHide = () => renderer?.setActive(false);
339
349
  const observer = new MutationObserver((records) => {
340
350
  if (records.some((record) => record.attributeName === 'data-skin' || record.attributeName === 'data-theme')) onAppearance();
@@ -348,10 +358,10 @@ export function initYard(controller) {
348
358
  window.addEventListener('pagehide',pageHide);
349
359
  window.addEventListener('pageshow',visibility);
350
360
  setView(view,{remember:false});
351
- const celebrate = () => { if (sceneVisible()) renderer?.fireworks(); };
352
361
  return { update, select, setView, closePhoto, celebrate, dispose() {
353
362
  closePhoto();
354
- disposed=true; sceneAttempt++; worldAttempt++; clearTimeout(swapReveal); observer.disconnect(); pendingRenderer?.dispose(); renderer?.dispose();
363
+ $('yard-fireworks').removeEventListener('click',celebrate);
364
+ disposed=true; fireworksButton(); sceneAttempt++; worldAttempt++; clearTimeout(swapReveal); observer.disconnect(); pendingRenderer?.dispose(); renderer?.dispose();
355
365
  document.removeEventListener('visibilitychange',visibility);
356
366
  motion.removeEventListener('change',motionChange);
357
367
  window.removeEventListener('pagehide',pageHide);