@bytetrue/byspace 0.17.0 → 0.18.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 (54) hide show
  1. package/node_modules/@bytetrue/client/package.json +3 -3
  2. package/node_modules/@bytetrue/highlight/package.json +1 -1
  3. package/node_modules/@bytetrue/protocol/package.json +1 -1
  4. package/node_modules/@bytetrue/relay/package.json +1 -1
  5. package/node_modules/@bytetrue/server/dist/server/server/agent/agent-manager.d.ts +30 -0
  6. package/node_modules/@bytetrue/server/dist/server/server/agent/agent-manager.js +118 -8
  7. package/node_modules/@bytetrue/server/dist/server/server/agent/mcp-shared.d.ts +1 -1
  8. package/node_modules/@bytetrue/server/dist/server/server/agent/{providers/claude/subagents → provider-subagents}/observation.d.ts +2 -2
  9. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/claude/agent.js +1 -1
  10. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/claude/subagents/live-source.d.ts +1 -1
  11. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/claude/subagents/replay-source.d.ts +1 -1
  12. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/claude/subagents/workflow-replay-source.d.ts +1 -1
  13. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/omp/rpc-types.d.ts +6 -6
  14. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/agent-subagents.d.ts +45 -0
  15. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/agent-subagents.js +159 -0
  16. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/agent.d.ts +2 -2
  17. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/agent.js +86 -151
  18. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/runtime.d.ts +0 -2
  19. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/runtime.js +0 -4
  20. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/session-descriptor.d.ts +2 -0
  21. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/session-descriptor.js +2 -2
  22. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/subagent-session-tailer.d.ts +47 -0
  23. package/node_modules/@bytetrue/server/dist/server/server/agent/providers/pi/subagent-session-tailer.js +212 -0
  24. package/node_modules/@bytetrue/server/dist/server/server/bootstrap.d.ts +6 -0
  25. package/node_modules/@bytetrue/server/dist/server/server/bootstrap.js +49 -0
  26. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{index-8d553cf4f8b1937dcd7c1da125243e39.js → index-5762beef0f3c7a285c88f6cb383d0f16.js} +485 -484
  27. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-5762beef0f3c7a285c88f6cb383d0f16.js.br +0 -0
  28. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-5762beef0f3c7a285c88f6cb383d0f16.js.gz +0 -0
  29. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-9f3696181e42915ed4f9cb01f7595007.js → indexeddb-attachment-store-433f8ff1c621845eba95cc633f47b72d.js} +1 -1
  30. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-433f8ff1c621845eba95cc633f47b72d.js.br +0 -0
  31. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-433f8ff1c621845eba95cc633f47b72d.js.gz +0 -0
  32. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{native-file-attachment-store-f829a425d0a064f4a9b4b153d185a3fb.js → native-file-attachment-store-6ed537a199e954caec287e6d28945868.js} +3 -3
  33. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-6ed537a199e954caec287e6d28945868.js.br +0 -0
  34. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-6ed537a199e954caec287e6d28945868.js.gz +0 -0
  35. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html +1 -1
  36. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html.br +0 -0
  37. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html.gz +0 -0
  38. package/node_modules/@bytetrue/server/dist/src/server/agent/agent-manager.js +118 -8
  39. package/node_modules/@bytetrue/server/dist/src/server/agent/providers/claude/agent.js +1 -1
  40. package/node_modules/@bytetrue/server/dist/src/server/agent/providers/pi/agent-subagents.js +159 -0
  41. package/node_modules/@bytetrue/server/dist/src/server/agent/providers/pi/agent.js +86 -151
  42. package/node_modules/@bytetrue/server/dist/src/server/agent/providers/pi/runtime.js +0 -4
  43. package/node_modules/@bytetrue/server/dist/src/server/agent/providers/pi/session-descriptor.js +2 -2
  44. package/node_modules/@bytetrue/server/dist/src/server/agent/providers/pi/subagent-session-tailer.js +212 -0
  45. package/node_modules/@bytetrue/server/package.json +5 -5
  46. package/package.json +7 -7
  47. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-8d553cf4f8b1937dcd7c1da125243e39.js.br +0 -0
  48. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-8d553cf4f8b1937dcd7c1da125243e39.js.gz +0 -0
  49. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-9f3696181e42915ed4f9cb01f7595007.js.br +0 -0
  50. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-9f3696181e42915ed4f9cb01f7595007.js.gz +0 -0
  51. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-f829a425d0a064f4a9b4b153d185a3fb.js.br +0 -0
  52. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-f829a425d0a064f4a9b4b153d185a3fb.js.gz +0 -0
  53. /package/node_modules/@bytetrue/server/dist/server/server/agent/{providers/claude/subagents → provider-subagents}/observation.js +0 -0
  54. /package/node_modules/@bytetrue/server/dist/src/server/agent/{providers/claude/subagents → provider-subagents}/observation.js +0 -0
@@ -1 +1 @@
1
- __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createIndexedDbAttachmentStore=function(){return{storageType:"web-indexeddb",async save(n){const o=n.id??(0,t.generateAttachmentId)(),s=Date.now(),{blob:c,mimeType:u}=await b(n),w=n.fileName??null,p=await l();try{await y(p,"readwrite",t=>t.put({id:o,blob:c,createdAt:s,fileName:w}))}finally{p.close()}return{id:o,mimeType:u,storageType:"web-indexeddb",storageKey:o,fileName:w,byteSize:c.size,createdAt:s}},async loadBlob({attachment:t}){const n=await l();try{return await u(n,t.storageKey)}finally{n.close()}},async encodeBase64({attachment:n}){const o=await l();try{const s=await u(o,n.storageKey);return await(0,t.blobToBase64)(s)}finally{o.close()}},async resolvePreviewUrl({attachment:t}){const n=await l();try{const o=await u(n,t.storageKey);return URL.createObjectURL(o)}finally{n.close()}},async releasePreviewUrl({url:t}){URL.revokeObjectURL(t)},async delete({attachment:t}){const n=await l();try{await y(n,"readwrite",n=>n.delete(t.storageKey))}finally{n.close()}},async garbageCollect({referencedIds:t}){const n=await l();try{await new Promise((s,c)=>{const l=n.transaction(o,"readwrite"),y=l.objectStore(o).openCursor();y.addEventListener("error",()=>{c(y.error??new Error("Failed to iterate IndexedDB attachment store."))}),y.addEventListener("success",()=>{const n=y.result;if(!n)return void s();const o=String(n.key);t.has(o)||n.delete(),n.continue()}),l.addEventListener("error",()=>{c(l.error??new Error("Failed to garbage collect IndexedDB attachments."))})})}finally{n.close()}}}};var t=r(d[0]);const n="byspace-attachment-bytes",o="attachments",s=1;function c(){const t=globalThis.indexedDB;if(!t)throw new Error("IndexedDB is unavailable in this runtime.");return t}function l(){return new Promise((t,l)=>{const y=c().open(n,s);y.onupgradeneeded=()=>{const t=y.result;t.objectStoreNames.contains(o)||t.createObjectStore(o,{keyPath:"id"})},y.addEventListener("success",()=>{t(y.result)}),y.addEventListener("error",()=>{l(y.error??new Error("Failed to open attachment IndexedDB."))})})}function y(t,n,s){return new Promise((c,l)=>{const y=t.transaction(o,n),b=y.objectStore(o),u=s(b);u.addEventListener("success",()=>{c(u.result)}),u.addEventListener("error",()=>{l(u.error??new Error("IndexedDB transaction request failed."))}),y.addEventListener("error",()=>{l(y.error??new Error("IndexedDB transaction failed."))})})}async function b(n){const o=n.source;if("bytes"===o.kind){const s=(0,t.normalizeMimeType)(n.mimeType),c=new ArrayBuffer(o.bytes.byteLength);return new Uint8Array(c).set(o.bytes),{blob:new Blob([c],{type:s}),mimeType:s}}if("blob"===o.kind){const s=(0,t.normalizeMimeType)(n.mimeType??o.blob.type);return{blob:o.blob.type===s?o.blob:o.blob.slice(0,o.blob.size,s),mimeType:s}}if("data_url"===o.kind){const s=(0,t.parseDataUrl)(o.dataUrl),c=await fetch(o.dataUrl),l=await c.blob(),y=(0,t.normalizeMimeType)(n.mimeType??s.mimeType??l.type);return{blob:l.type===y?l:l.slice(0,l.size,y),mimeType:y}}const s=await fetch(o.uri),c=await s.blob(),l=(0,t.normalizeMimeType)(n.mimeType??c.type);return{blob:c.type===l?c:c.slice(0,c.size,l),mimeType:l}}async function u(t,n){const o=await y(t,"readonly",t=>t.get(n));if(!o?.blob)throw new Error(`Attachment ${n} was not found in IndexedDB.`);return o.blob}},4884,[3584]);
1
+ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createIndexedDbAttachmentStore=function(){return{storageType:"web-indexeddb",async save(n){const o=n.id??(0,t.generateAttachmentId)(),s=Date.now(),{blob:c,mimeType:u}=await b(n),w=n.fileName??null,p=await l();try{await y(p,"readwrite",t=>t.put({id:o,blob:c,createdAt:s,fileName:w}))}finally{p.close()}return{id:o,mimeType:u,storageType:"web-indexeddb",storageKey:o,fileName:w,byteSize:c.size,createdAt:s}},async loadBlob({attachment:t}){const n=await l();try{return await u(n,t.storageKey)}finally{n.close()}},async encodeBase64({attachment:n}){const o=await l();try{const s=await u(o,n.storageKey);return await(0,t.blobToBase64)(s)}finally{o.close()}},async resolvePreviewUrl({attachment:t}){const n=await l();try{const o=await u(n,t.storageKey);return URL.createObjectURL(o)}finally{n.close()}},async releasePreviewUrl({url:t}){URL.revokeObjectURL(t)},async delete({attachment:t}){const n=await l();try{await y(n,"readwrite",n=>n.delete(t.storageKey))}finally{n.close()}},async garbageCollect({referencedIds:t}){const n=await l();try{await new Promise((s,c)=>{const l=n.transaction(o,"readwrite"),y=l.objectStore(o).openCursor();y.addEventListener("error",()=>{c(y.error??new Error("Failed to iterate IndexedDB attachment store."))}),y.addEventListener("success",()=>{const n=y.result;if(!n)return void s();const o=String(n.key);t.has(o)||n.delete(),n.continue()}),l.addEventListener("error",()=>{c(l.error??new Error("Failed to garbage collect IndexedDB attachments."))})})}finally{n.close()}}}};var t=r(d[0]);const n="byspace-attachment-bytes",o="attachments",s=1;function c(){const t=globalThis.indexedDB;if(!t)throw new Error("IndexedDB is unavailable in this runtime.");return t}function l(){return new Promise((t,l)=>{const y=c().open(n,s);y.onupgradeneeded=()=>{const t=y.result;t.objectStoreNames.contains(o)||t.createObjectStore(o,{keyPath:"id"})},y.addEventListener("success",()=>{t(y.result)}),y.addEventListener("error",()=>{l(y.error??new Error("Failed to open attachment IndexedDB."))})})}function y(t,n,s){return new Promise((c,l)=>{const y=t.transaction(o,n),b=y.objectStore(o),u=s(b);u.addEventListener("success",()=>{c(u.result)}),u.addEventListener("error",()=>{l(u.error??new Error("IndexedDB transaction request failed."))}),y.addEventListener("error",()=>{l(y.error??new Error("IndexedDB transaction failed."))})})}async function b(n){const o=n.source;if("bytes"===o.kind){const s=(0,t.normalizeMimeType)(n.mimeType),c=new ArrayBuffer(o.bytes.byteLength);return new Uint8Array(c).set(o.bytes),{blob:new Blob([c],{type:s}),mimeType:s}}if("blob"===o.kind){const s=(0,t.normalizeMimeType)(n.mimeType??o.blob.type);return{blob:o.blob.type===s?o.blob:o.blob.slice(0,o.blob.size,s),mimeType:s}}if("data_url"===o.kind){const s=(0,t.parseDataUrl)(o.dataUrl),c=await fetch(o.dataUrl),l=await c.blob(),y=(0,t.normalizeMimeType)(n.mimeType??s.mimeType??l.type);return{blob:l.type===y?l:l.slice(0,l.size,y),mimeType:y}}const s=await fetch(o.uri),c=await s.blob(),l=(0,t.normalizeMimeType)(n.mimeType??c.type);return{blob:c.type===l?c:c.slice(0,c.size,l),mimeType:l}}async function u(t,n){const o=await y(t,"readonly",t=>t.get(n));if(!o?.blob)throw new Error(`Attachment ${n} was not found in IndexedDB.`);return o.blob}},4885,[3584]);
@@ -1,3 +1,3 @@
1
- __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createNativeFileAttachmentStore=function(){return(0,s.createLocalFileAttachmentStore)({storageType:"native-file",baseDirectoryName:"byspace-native-attachments",fileSystem:(0,t.createExpoAttachmentFileSystem)(),resolvePreviewUrl:async t=>t.storageKey.startsWith("file://")?t.storageKey:(0,o.isAbsolutePath)(t.storageKey)?t.storageKey.startsWith("/")?`file://${t.storageKey}`:t.storageKey.startsWith("\\\\")?`file:${t.storageKey.replace(/\\/g,"/")}`:`file:///${t.storageKey.replace(/\\/g,"/")}`:t.storageKey})};var t=r(d[0]),s=r(d[1]),o=r(d[2])},4885,[4886,4887,3585]);
2
- __d(function(g,r,i,a,m,_e,_d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),_e.createExpoAttachmentFileSystem=function(){return{cacheDirectory:t.cacheDirectory,async getInfo(e){const n=await t.getInfoAsync(e);if(!n.exists)return{exists:!1};const c="number"==typeof n.size?n.size:null;return{exists:!0,isDirectory:n.isDirectory??!1,size:c}},async makeDirectory(e,n){await t.makeDirectoryAsync(e,n)},async writeBytes(t,n){new e.File(t).write(n)},async copy(e){await t.copyAsync(e)},readAsBase64:async e=>await t.readAsStringAsync(e,{encoding:t.EncodingType.Base64}),async delete(e,n){await t.deleteAsync(e,n)},listDirectory:async e=>await t.readDirectoryAsync(e)}};var e=r(_d[0]),t=(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach(function(n){var c=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,c.get?c:{enumerable:!0,get:function(){return e[n]}})}),t.default=e,t})(r(_d[1]))},4886,[3829,3837]);
3
- __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createLocalFileAttachmentStore=function(n){const{fileSystem:o}=n,l=o.cacheDirectory?`${o.cacheDirectory}${n.baseDirectoryName}/`:null;async function u(n){if(!l)throw new Error("Attachment file-system cacheDirectory is unavailable.");await c(o,l);const y=n.id??(0,t.generateAttachmentId)();let f;f="data_url"===n.source.kind?(0,t.parseDataUrl)(n.source.dataUrl).mimeType:"blob"===n.source.kind?n.source.blob.type:void 0;const u=(0,t.normalizeMimeType)(n.mimeType??f),p=n.fileName??null,w=s({fileName:p,mimeType:u}),U=Date.now(),b=`${l}${y}${w}`;return{id:y,mimeType:u,fileName:p,createdAt:U,targetUri:b,storageKey:(0,t.fileUriToPath)(b)}}return Object.assign({storageType:n.storageType,async save(t){const s=await u(t);await y({fileSystem:o,source:t.source,targetUri:s.targetUri,mimeType:s.mimeType});const c=await o.getInfo(s.targetUri),l=c.exists?c.size:null;return{id:s.id,mimeType:s.mimeType,storageType:n.storageType,storageKey:s.storageKey,fileName:s.fileName,byteSize:l,createdAt:s.createdAt}},encodeBase64:async({attachment:t})=>await o.readAsBase64(f(t)),resolvePreviewUrl:async({attachment:t})=>await n.resolvePreviewUrl(t)},n.releasePreviewUrl?{async releasePreviewUrl(t){await(n.releasePreviewUrl?.(t))}}:{},{async delete({attachment:t}){await o.delete(f(t),{idempotent:!0})},async garbageCollect({referencedIds:t}){if(!l)return;await c(o,l);const n=await o.listDirectory(l);await Promise.all(n.map(async n=>{const s=n.split(".",1)[0]??"";s&&!t.has(s)&&await o.delete(`${l}${n}`,{idempotent:!0})}))}})};var t=r(d[0]);const n={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/gif":".gif","image/webp":".webp","image/avif":".avif","image/heic":".heic","image/heif":".heif","image/tiff":".tiff","image/bmp":".bmp","image/svg+xml":".svg"};function s(s){const c=(0,t.getFileExtensionFromName)(s.fileName);return c||(n[s.mimeType]??".img")}async function c(t,n){const s=await t.getInfo(n);s.exists&&s.isDirectory||await t.makeDirectory(n,{intermediates:!0})}async function o(t){const n=await fetch(t);return new Uint8Array(await n.arrayBuffer())}async function l(t){return new Uint8Array(await t.arrayBuffer())}async function y(n){if("file_uri"===n.source.kind){const s=(0,t.pathToFileUri)(n.source.uri);if(s===n.targetUri)return;return void await n.fileSystem.copy({from:s,to:n.targetUri})}let s;s="data_url"===n.source.kind?await o(n.source.dataUrl):"blob"===n.source.kind?await l(n.source.blob):n.source.bytes,await n.fileSystem.writeBytes(n.targetUri,s)}function f(n){return(0,t.pathToFileUri)(n.storageKey)}},4887,[3584]);
1
+ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createNativeFileAttachmentStore=function(){return(0,s.createLocalFileAttachmentStore)({storageType:"native-file",baseDirectoryName:"byspace-native-attachments",fileSystem:(0,t.createExpoAttachmentFileSystem)(),resolvePreviewUrl:async t=>t.storageKey.startsWith("file://")?t.storageKey:(0,o.isAbsolutePath)(t.storageKey)?t.storageKey.startsWith("/")?`file://${t.storageKey}`:t.storageKey.startsWith("\\\\")?`file:${t.storageKey.replace(/\\/g,"/")}`:`file:///${t.storageKey.replace(/\\/g,"/")}`:t.storageKey})};var t=r(d[0]),s=r(d[1]),o=r(d[2])},4886,[4887,4888,3585]);
2
+ __d(function(g,r,i,a,m,_e,_d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),_e.createExpoAttachmentFileSystem=function(){return{cacheDirectory:t.cacheDirectory,async getInfo(e){const n=await t.getInfoAsync(e);if(!n.exists)return{exists:!1};const c="number"==typeof n.size?n.size:null;return{exists:!0,isDirectory:n.isDirectory??!1,size:c}},async makeDirectory(e,n){await t.makeDirectoryAsync(e,n)},async writeBytes(t,n){new e.File(t).write(n)},async copy(e){await t.copyAsync(e)},readAsBase64:async e=>await t.readAsStringAsync(e,{encoding:t.EncodingType.Base64}),async delete(e,n){await t.deleteAsync(e,n)},listDirectory:async e=>await t.readDirectoryAsync(e)}};var e=r(_d[0]),t=(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach(function(n){var c=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,c.get?c:{enumerable:!0,get:function(){return e[n]}})}),t.default=e,t})(r(_d[1]))},4887,[3829,3837]);
3
+ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createLocalFileAttachmentStore=function(n){const{fileSystem:o}=n,l=o.cacheDirectory?`${o.cacheDirectory}${n.baseDirectoryName}/`:null;async function u(n){if(!l)throw new Error("Attachment file-system cacheDirectory is unavailable.");await c(o,l);const y=n.id??(0,t.generateAttachmentId)();let f;f="data_url"===n.source.kind?(0,t.parseDataUrl)(n.source.dataUrl).mimeType:"blob"===n.source.kind?n.source.blob.type:void 0;const u=(0,t.normalizeMimeType)(n.mimeType??f),p=n.fileName??null,w=s({fileName:p,mimeType:u}),U=Date.now(),b=`${l}${y}${w}`;return{id:y,mimeType:u,fileName:p,createdAt:U,targetUri:b,storageKey:(0,t.fileUriToPath)(b)}}return Object.assign({storageType:n.storageType,async save(t){const s=await u(t);await y({fileSystem:o,source:t.source,targetUri:s.targetUri,mimeType:s.mimeType});const c=await o.getInfo(s.targetUri),l=c.exists?c.size:null;return{id:s.id,mimeType:s.mimeType,storageType:n.storageType,storageKey:s.storageKey,fileName:s.fileName,byteSize:l,createdAt:s.createdAt}},encodeBase64:async({attachment:t})=>await o.readAsBase64(f(t)),resolvePreviewUrl:async({attachment:t})=>await n.resolvePreviewUrl(t)},n.releasePreviewUrl?{async releasePreviewUrl(t){await(n.releasePreviewUrl?.(t))}}:{},{async delete({attachment:t}){await o.delete(f(t),{idempotent:!0})},async garbageCollect({referencedIds:t}){if(!l)return;await c(o,l);const n=await o.listDirectory(l);await Promise.all(n.map(async n=>{const s=n.split(".",1)[0]??"";s&&!t.has(s)&&await o.delete(`${l}${n}`,{idempotent:!0})}))}})};var t=r(d[0]);const n={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/gif":".gif","image/webp":".webp","image/avif":".avif","image/heic":".heic","image/heif":".heif","image/tiff":".tiff","image/bmp":".bmp","image/svg+xml":".svg"};function s(s){const c=(0,t.getFileExtensionFromName)(s.fileName);return c||(n[s.mimeType]??".img")}async function c(t,n){const s=await t.getInfo(n);s.exists&&s.isDirectory||await t.makeDirectory(n,{intermediates:!0})}async function o(t){const n=await fetch(t);return new Uint8Array(await n.arrayBuffer())}async function l(t){return new Uint8Array(await t.arrayBuffer())}async function y(n){if("file_uri"===n.source.kind){const s=(0,t.pathToFileUri)(n.source.uri);if(s===n.targetUri)return;return void await n.fileSystem.copy({from:s,to:n.targetUri})}let s;s="data_url"===n.source.kind?await o(n.source.dataUrl):"blob"===n.source.kind?await l(n.source.blob):n.source.bytes,await n.fileSystem.writeBytes(n.targetUri,s)}function f(n){return(0,t.pathToFileUri)(n.storageKey)}},4888,[3584]);
@@ -86,6 +86,6 @@
86
86
  <body>
87
87
  <noscript>You need to enable JavaScript to run this app.</noscript>
88
88
  <div id="root"></div>
89
- <script src="/_expo/static/js/web/index-8d553cf4f8b1937dcd7c1da125243e39.js" defer></script>
89
+ <script src="/_expo/static/js/web/index-5762beef0f3c7a285c88f6cb383d0f16.js" defer></script>
90
90
  </body>
91
91
  </html>
@@ -1,4 +1,4 @@
1
- import { randomUUID } from "node:crypto";
1
+ import { randomBytes, randomUUID } from "node:crypto";
2
2
  import { basename, resolve } from "node:path";
3
3
  import { stat } from "node:fs/promises";
4
4
  import { AGENT_LIFECYCLE_STATUSES, } from "@bytetrue/protocol/agent-lifecycle";
@@ -17,6 +17,9 @@ import { stripInternalBySpaceMcpServer, withRuntimeBySpaceMcpServer, } from "./r
17
17
  import { resolveCreateAgentTitles } from "./create-agent-title.js";
18
18
  import { isBySpaceToolPolicyEnabled } from "./byspace-tool-policy.js";
19
19
  import { ProviderSubagentStore, } from "./provider-subagents/store.js";
20
+ import { foldSubagentObservations, } from "./provider-subagents/observation.js";
21
+ import { observePiSubagentRecord } from "./providers/pi/agent-subagents.js";
22
+ import { PI_SUBAGENT_TERMINAL_STATUSES, parsePiSubagentTailerSnapshot, PiSubagentSessionTailers, } from "./providers/pi/subagent-session-tailer.js";
20
23
  import { withTimeout } from "../../utils/promise-timeout.js";
21
24
  const RELOAD_SESSION_CLOSE_TIMEOUT_MS = 3000;
22
25
  const INTERRUPT_SESSION_TIMEOUT_MS = 2000;
@@ -263,6 +266,13 @@ export class AgentManager {
263
266
  this.agents = new Map();
264
267
  this.timelineStore = new InMemoryAgentTimelineStore();
265
268
  this.providerSubagents = new ProviderSubagentStore();
269
+ this.piSubagentReportTokens = new Map();
270
+ this.piSubagentReportBaseUrl = null;
271
+ this.piSubagentTailers = new PiSubagentSessionTailers({
272
+ emit: (agentId, observation) => {
273
+ this.applyExternalProviderSubagentObservation(agentId, "pi", observation);
274
+ },
275
+ });
266
276
  this.agentsAwaitingInitialSnapshotPersist = new Set();
267
277
  this.sessionEventTails = new Map();
268
278
  this.steerEventBarriers = new Map();
@@ -353,8 +363,87 @@ export class AgentManager {
353
363
  setMcpBaseUrl(url) {
354
364
  this.mcpBaseUrl = url;
355
365
  }
366
+ setPiSubagentReportBaseUrl(url) {
367
+ this.piSubagentReportBaseUrl = url;
368
+ if (!url) {
369
+ this.piSubagentReportTokens.clear();
370
+ }
371
+ }
372
+ /**
373
+ * Resolve the agent a pi-subagent report token was minted for. Tokens are random
374
+ * per pi launch, so the token alone identifies the agent — the reporter extension
375
+ * never needs to know its own BySpace agent id.
376
+ */
377
+ resolvePiSubagentReportAgentId(token) {
378
+ if (!token)
379
+ return null;
380
+ for (const [agentId, minted] of this.piSubagentReportTokens) {
381
+ if (minted === token && this.agents.has(agentId))
382
+ return agentId;
383
+ }
384
+ return null;
385
+ }
386
+ /**
387
+ * Apply a provider-subagent store event with the terminal latch: a running upsert for an
388
+ * already-terminal subagent is dropped. HTTP reports and transcript replays have no ordering
389
+ * guarantee, so a stale running snapshot must not reopen a finished subagent. New launches
390
+ * get fresh ids and are unaffected.
391
+ */
392
+ applyProviderSubagentEvent(agentId, provider, event) {
393
+ if (event.type === "upsert" && event.status === "running") {
394
+ const current = this.providerSubagents.get(agentId, event.id)?.status;
395
+ if (current && PI_SUBAGENT_TERMINAL_STATUSES.includes(current)) {
396
+ return null;
397
+ }
398
+ }
399
+ return this.providerSubagents.apply(agentId, provider, event);
400
+ }
401
+ /**
402
+ * Apply a provider-subagent observation reported from outside the agent stream (the pi
403
+ * subagent extension POSTs progress snapshots over loopback) and dispatch the resulting
404
+ * store event.
405
+ */
406
+ applyExternalProviderSubagentObservation(agentId, provider, observation) {
407
+ const agent = this.agents.get(agentId);
408
+ if (!agent) {
409
+ return false;
410
+ }
411
+ const [event] = foldSubagentObservations([observation]);
412
+ if (!event) {
413
+ return false;
414
+ }
415
+ const update = this.applyProviderSubagentEvent(agentId, provider, event);
416
+ if (!update) {
417
+ return false;
418
+ }
419
+ this.dispatch({ type: "provider_subagent", event: update });
420
+ return true;
421
+ }
422
+ /**
423
+ * Apply a pi-subagent progress report POSTed by the pi-subagent extension over loopback:
424
+ * verify the per-launch token, fold each record into a provider-subagent observation, and
425
+ * feed session references to the jsonl tailers that stream child-session timelines.
426
+ */
427
+ applyPiSubagentReport(token, records) {
428
+ const agentId = this.resolvePiSubagentReportAgentId(token);
429
+ if (!agentId) {
430
+ return "unauthorized";
431
+ }
432
+ for (const record of records) {
433
+ const observation = observePiSubagentRecord(record);
434
+ if (observation) {
435
+ this.applyExternalProviderSubagentObservation(agentId, "pi", observation);
436
+ }
437
+ const snapshot = parsePiSubagentTailerSnapshot(record);
438
+ if (snapshot) {
439
+ this.piSubagentTailers.update(agentId, snapshot);
440
+ }
441
+ }
442
+ return "ok";
443
+ }
356
444
  prepareForShutdown() {
357
445
  this.acceptingAgentRegistrations = false;
446
+ this.piSubagentTailers.dispose();
358
447
  }
359
448
  setBySpaceToolsEnabled(enabled) {
360
449
  this.byspaceToolsEnabled = enabled;
@@ -778,8 +867,10 @@ export class AgentManager {
778
867
  publishWhenReady: true,
779
868
  });
780
869
  for (const event of imported.providerSubagentEvents ?? []) {
781
- const update = this.providerSubagents.apply(agent.id, event.provider, event.event);
782
- this.dispatch({ type: "provider_subagent", event: update });
870
+ const update = this.applyProviderSubagentEvent(agent.id, event.provider, event.event);
871
+ if (update) {
872
+ this.dispatch({ type: "provider_subagent", event: update });
873
+ }
783
874
  }
784
875
  return agent;
785
876
  }
@@ -2511,6 +2602,10 @@ export class AgentManager {
2511
2602
  this.agentStreamCoalescer.flushAndDiscard(agent.id);
2512
2603
  this.agents.delete(agent.id);
2513
2604
  this.previousStatuses.delete(agent.id);
2605
+ // Child-session tailers and report tokens are live-process state: on close (and reload,
2606
+ // whose new process re-reports) they have no owner and would poll until daemon shutdown.
2607
+ this.piSubagentReportTokens.delete(agent.id);
2608
+ this.piSubagentTailers.removeAgent(agent.id);
2514
2609
  if (agent.unsubscribeSession) {
2515
2610
  agent.unsubscribeSession();
2516
2611
  agent.unsubscribeSession = null;
@@ -2541,6 +2636,8 @@ export class AgentManager {
2541
2636
  discardRetainedAgentState(agentId) {
2542
2637
  this.timelineStore.delete(agentId);
2543
2638
  this.byspaceToolPolicies.delete(agentId);
2639
+ this.piSubagentReportTokens.delete(agentId);
2640
+ this.piSubagentTailers.removeAgent(agentId);
2544
2641
  for (const event of this.providerSubagents.deleteParent(agentId)) {
2545
2642
  this.dispatch({ type: "provider_subagent", event });
2546
2643
  }
@@ -2627,8 +2724,10 @@ export class AgentManager {
2627
2724
  }
2628
2725
  async dispatchSessionEvent(agent, event) {
2629
2726
  if (event.type === "provider_subagent") {
2630
- const update = this.providerSubagents.apply(agent.id, event.provider, event.event);
2631
- this.dispatch({ type: "provider_subagent", event: update });
2727
+ const update = this.applyProviderSubagentEvent(agent.id, event.provider, event.event);
2728
+ if (update) {
2729
+ this.dispatch({ type: "provider_subagent", event: update });
2730
+ }
2632
2731
  return;
2633
2732
  }
2634
2733
  const turnId = getAgentStreamEventTurnId(event);
@@ -2766,8 +2865,8 @@ export class AgentManager {
2766
2865
  }
2767
2866
  }
2768
2867
  for (const event of providerSubagentEvents) {
2769
- const update = this.providerSubagents.apply(agent.id, event.provider, event.event);
2770
- if (broadcast) {
2868
+ const update = this.applyProviderSubagentEvent(agent.id, event.provider, event.event);
2869
+ if (update && broadcast) {
2771
2870
  this.dispatch({ type: "provider_subagent", event: update });
2772
2871
  }
2773
2872
  }
@@ -2793,7 +2892,9 @@ export class AgentManager {
2793
2892
  for await (const rawEvent of agent.session.streamHistory()) {
2794
2893
  const event = limitAgentStreamEventContent(rawEvent);
2795
2894
  if (event.type === "provider_subagent") {
2796
- const update = this.providerSubagents.apply(agent.id, event.provider, event.event);
2895
+ const update = this.applyProviderSubagentEvent(agent.id, event.provider, event.event);
2896
+ if (!update)
2897
+ continue;
2797
2898
  const managerEvent = { type: "provider_subagent", event: update };
2798
2899
  if (deferredBroadcast) {
2799
2900
  providerSubagentEvents.push(managerEvent);
@@ -3625,6 +3726,15 @@ export class AgentManager {
3625
3726
  BYSPACE_AGENT_CWD: cwd,
3626
3727
  },
3627
3728
  };
3729
+ if (client.provider === "pi" && this.piSubagentReportBaseUrl) {
3730
+ const reportToken = randomBytes(32).toString("base64url");
3731
+ this.piSubagentReportTokens.set(agentId, reportToken);
3732
+ context.env = {
3733
+ ...context.env,
3734
+ BYSPACE_SUBAGENT_REPORT_URL: `${this.piSubagentReportBaseUrl}/api/subagent-report`,
3735
+ BYSPACE_SUBAGENT_REPORT_TOKEN: reportToken,
3736
+ };
3737
+ }
3628
3738
  if (this.byspaceToolsEnabled &&
3629
3739
  isBySpaceToolPolicyEnabled(byspaceToolPolicy) &&
3630
3740
  client.capabilities.supportsNativeBySpaceTools &&
@@ -12,7 +12,7 @@ import { ClaudeSidechainTracker } from "./sidechain-tracker.js";
12
12
  import { ClaudeTaskState } from "./task-state.js";
13
13
  import { ClaudeTaskProtocolSource, } from "./subagents/live-source.js";
14
14
  import { observeReplaySubagents, parseClaudeSubagentMeta, } from "./subagents/replay-source.js";
15
- import { foldSubagentObservations } from "./subagents/observation.js";
15
+ import { foldSubagentObservations, } from "../../provider-subagents/observation.js";
16
16
  import { observeReplayWorkflows, parseClaudeWorkflowRun, } from "./subagents/workflow-replay-source.js";
17
17
  import { readClaudeWorkflowResultFile } from "./subagents/workflow-output.js";
18
18
  import { buildClaudeFeatures, claudeModelSupportsFastMode } from "./feature-definitions.js";
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Pi announces background subagents through the @bytetrue/pi-subagent extension. Three wire
3
+ * origins carry the facts, and all three reduce to the shared observation vocabulary:
4
+ *
5
+ * - the `subagent` tool result (launch): details `{ id, status: "running" }`, the task
6
+ * description lives on the tool call arguments;
7
+ * - `subagent_status` / `subagent_stop` tool results and `subagent-exit` custom
8
+ * messages: details are the extension's full task record (`toMessageDetails`).
9
+ *
10
+ * The extension strips live objects before details cross the wire, so every field here is
11
+ * clone-safe JSON. Both the live event stream and the persisted session replay read through
12
+ * these functions, so a fact is derived once for both paths.
13
+ */
14
+ /** Tool the extension registers to launch a background child. */
15
+ const PI_SUBAGENT_LAUNCH_TOOL = "subagent";
16
+ /** Tools whose results carry the full task record. */
17
+ const PI_SUBAGENT_RECORD_TOOLS = new Set(["subagent_status", "subagent_stop"]);
18
+ /** Custom message type the extension sends when a child finishes. */
19
+ const PI_SUBAGENT_EXIT_CUSTOM_TYPE = "subagent-exit";
20
+ export function isPiSubagentToolName(toolName) {
21
+ return toolName === PI_SUBAGENT_LAUNCH_TOOL || PI_SUBAGENT_RECORD_TOOLS.has(toolName);
22
+ }
23
+ /**
24
+ * The descriptor has no paused state and paused is not terminal, so it reads as running.
25
+ * Unknown statuses map to undefined: the caller's upsert then preserves the stored status.
26
+ */
27
+ export function mapPiSubagentStatus(status) {
28
+ switch (status) {
29
+ case "running":
30
+ case "pending":
31
+ case "paused":
32
+ return "running";
33
+ case "succeeded":
34
+ return "completed";
35
+ case "failed":
36
+ return "failed";
37
+ case "cancelled":
38
+ return "canceled";
39
+ default:
40
+ return undefined;
41
+ }
42
+ }
43
+ /**
44
+ * The subset of `toMessageDetails` this source reads. Every field is optional except the
45
+ * id: the extension adds fields across releases and older runtimes omit newer ones, so a
46
+ * wrong-typed field reads as absent rather than failing the record.
47
+ */
48
+ export function parsePiSubagentRecordDetails(details) {
49
+ if (typeof details !== "object" || details === null || Array.isArray(details)) {
50
+ return null;
51
+ }
52
+ const record = details;
53
+ if (typeof record.id !== "string" || record.id.length === 0) {
54
+ return null;
55
+ }
56
+ return {
57
+ id: record.id,
58
+ ...(typeof record.status === "string" ? { status: record.status } : {}),
59
+ ...(typeof record.description === "string" ? { description: record.description } : {}),
60
+ ...(typeof record.agent === "string" && record.agent.length > 0 ? { agent: record.agent } : {}),
61
+ };
62
+ }
63
+ function readStringArg(value) {
64
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
65
+ }
66
+ /** Launch observation from the `subagent` tool result plus its call arguments. */
67
+ export function observePiSubagentLaunch(input) {
68
+ const record = parsePiSubagentRecordDetails(input.details);
69
+ if (!record) {
70
+ return null;
71
+ }
72
+ const args = typeof input.args === "object" && input.args !== null
73
+ ? input.args
74
+ : {};
75
+ const agent = readStringArg(args.agent);
76
+ const task = readStringArg(args.task) ?? record.description;
77
+ return {
78
+ kind: "declared",
79
+ id: record.id,
80
+ toolCallId: input.toolCallId,
81
+ ...(agent ? { title: agent } : {}),
82
+ ...(task ? { description: task } : {}),
83
+ };
84
+ }
85
+ /** Status observation from a full task record (status/stop tool result or exit message). */
86
+ export function observePiSubagentRecord(details) {
87
+ const record = parsePiSubagentRecordDetails(details);
88
+ if (!record) {
89
+ return null;
90
+ }
91
+ const status = mapPiSubagentStatus(record.status);
92
+ if (!status) {
93
+ return null;
94
+ }
95
+ return { kind: "status", id: record.id, status };
96
+ }
97
+ /**
98
+ * Exit custom messages carry one record, or an array when several children finished before
99
+ * the extension could deliver the notification (its exit-batch path).
100
+ */
101
+ export function observePiSubagentExit(details) {
102
+ if (Array.isArray(details)) {
103
+ return details
104
+ .map((entry) => observePiSubagentRecord(entry))
105
+ .filter((observation) => observation !== null);
106
+ }
107
+ const observation = observePiSubagentRecord(details);
108
+ return observation ? [observation] : [];
109
+ }
110
+ /**
111
+ * Rebuilds subagent observations from a persisted session, producing the same vocabulary the
112
+ * live source produces. Identical observations in means identical descriptor state out.
113
+ *
114
+ * The transcript carries all three origins: assistant toolCall blocks with their toolResult
115
+ * messages (launch and record results), and `subagent-exit` custom messages. Tool calls
116
+ * precede their results in an assistant turn, so a single pass with a pending map pairs them.
117
+ */
118
+ export function replayPiSubagentObservations(messages) {
119
+ const observations = [];
120
+ const pendingLaunches = new Map();
121
+ for (const message of messages) {
122
+ if (message.role === "assistant") {
123
+ for (const content of message.content) {
124
+ if (content.type === "toolCall" && isPiSubagentToolName(content.name)) {
125
+ pendingLaunches.set(content.id, { name: content.name, args: content.arguments });
126
+ }
127
+ }
128
+ continue;
129
+ }
130
+ if (message.role === "toolResult") {
131
+ const launch = pendingLaunches.get(message.toolCallId);
132
+ pendingLaunches.delete(message.toolCallId);
133
+ if (!launch) {
134
+ continue;
135
+ }
136
+ if (launch.name === PI_SUBAGENT_LAUNCH_TOOL) {
137
+ const observation = observePiSubagentLaunch({
138
+ toolCallId: message.toolCallId,
139
+ args: launch.args,
140
+ details: message.details,
141
+ });
142
+ if (observation) {
143
+ observations.push(observation);
144
+ }
145
+ continue;
146
+ }
147
+ const observation = observePiSubagentRecord(message.details);
148
+ if (observation) {
149
+ observations.push(observation);
150
+ }
151
+ continue;
152
+ }
153
+ if (message.role === "custom" && message.customType === PI_SUBAGENT_EXIT_CUSTOM_TYPE) {
154
+ observations.push(...observePiSubagentExit(message.details));
155
+ }
156
+ }
157
+ return observations;
158
+ }
159
+ //# sourceMappingURL=agent-subagents.js.map