qlogicagent 2.18.7 → 2.18.9
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/README.md +382 -382
- package/dist/cli.js +1 -1
- package/dist/default-project-knowledge/INSTRUCTIONS.md +7 -7
- package/dist/default-project-knowledge/rules/project-workflow.md +6 -6
- package/dist/index.js +469 -489
- package/dist/pet-host.js +19 -0
- package/dist/runtime/infra/mcp-bridge-server.js +275 -275
- package/dist/skills/builtin/desktop-screenshot/SKILL.md +62 -62
- package/dist/skills/builtin/office-doc-reading/SKILL.md +19 -19
- package/dist/skills/mcp/astraclaw-native-mcp-server.js +7 -7
- package/dist/types/cli/core-tools/registry.d.ts +1 -2
- package/dist/types/cli/handlers/turn-handler.d.ts +1 -1
- package/dist/types/cli/handlers/workflow-compute-handler.d.ts +8 -0
- package/dist/types/cli/rpc-registry.d.ts +0 -13
- package/dist/types/cli/stdio-rpc-handler-hosts.d.ts +2 -5
- package/dist/types/cli/stdio-server.d.ts +0 -3
- package/dist/types/contracts/structured-planner.d.ts +2 -0
- package/dist/types/orchestration/solo-evaluator.d.ts +7 -2
- package/dist/types/pet-host.d.ts +9 -0
- package/dist/types/protocol/wire/acp-protocol.d.ts +7 -0
- package/dist/types/runtime/pet/pet-reaction-engine.d.ts +1 -1
- package/dist/types/skills/mcp/mcp-manager.d.ts +4 -0
- package/dist/types/workflow-host.d.ts +33 -0
- package/dist/vendor/hatch-pet/LICENSE.txt +201 -201
- package/dist/vendor/hatch-pet/NOTICE.md +25 -25
- package/dist/vendor/hatch-pet/references/animation-rows.md +29 -29
- package/dist/vendor/hatch-pet/references/codex-pet-contract.md +35 -35
- package/dist/vendor/hatch-pet/references/qa-rubric.md +66 -66
- package/dist/vendor/hatch-pet/scripts/compose_atlas.py +169 -169
- package/dist/vendor/hatch-pet/scripts/derive_running_left_from_running_right.py +150 -150
- package/dist/vendor/hatch-pet/scripts/extract_strip_frames.py +408 -408
- package/dist/vendor/hatch-pet/scripts/inspect_frames.py +256 -256
- package/dist/vendor/hatch-pet/scripts/make_contact_sheet.py +96 -96
- package/dist/vendor/hatch-pet/scripts/prepare_pet_run.py +834 -834
- package/dist/vendor/hatch-pet/scripts/render_animation_previews.py +78 -78
- package/dist/vendor/hatch-pet/scripts/validate_atlas.py +157 -157
- package/dist/workflow-host.js +13 -0
- package/package.json +16 -2
- package/dist/types/cli/core-tools/cron-tool-bootstrap.d.ts +0 -8
- package/dist/types/cli/core-tools/cron-workflow-service.d.ts +0 -7
- package/dist/types/cli/handlers/pet-handler.d.ts +0 -49
- package/dist/types/cli/handlers/workflow-handler.d.ts +0 -182
- package/dist/types/cli/tool-bootstrap-workflow-registration.d.ts +0 -7
- package/dist/types/cli/workflow-host-adapter.d.ts +0 -31
- package/dist/types/orchestration/workflow/workflow-service.d.ts +0 -14
- package/dist/types/skills/tools/cron-tool.d.ts +0 -96
- package/dist/types/skills/tools/petdex-create-tool.d.ts +0 -47
- package/dist/types/skills/tools/workflow-tool.d.ts +0 -45
package/dist/pet-host.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
var fe=[{id:"bubble_detail",unlockedAtLevel:2},{id:"gaze_follow",unlockedAtLevel:3},{id:"micro_expression",unlockedAtLevel:5},{id:"tidy_motion",unlockedAtLevel:7},{id:"mood_badge",unlockedAtLevel:10},{id:"quiet_rest",unlockedAtLevel:12},{id:"activity_glow",unlockedAtLevel:15},{id:"style_tint",unlockedAtLevel:20}],Ue=["\u7B2C\u4E00\u6B21\u8131\u58F3\uFF01\u5C0F\u867E\u58F3\u53D8\u5F97\u66F4\u6709\u5149\u6CFD\u4E86","\u58F3\u9762\u5F00\u59CB\u51FA\u73B0\u7EC6\u5FAE\u7684\u5F69\u8679\u7EB9\u7406","\u94B3\u5B50\u53D8\u5F97\u66F4\u52A0\u6709\u529B\uFF0C\u80FD\u5939\u8D77\u66F4\u591A\u4E1C\u897F\u4E86","\u89E6\u89D2\u7075\u654F\u5EA6\u63D0\u5347\uFF0C\u611F\u77E5\u8303\u56F4\u6269\u5927","\u5168\u8EAB\u6563\u53D1\u5FAE\u5149\uFF0C\u50CF\u662F\u5185\u5728\u529B\u91CF\u5728\u89C9\u9192","\u8FDB\u5165\u7A00\u6709\u4F53\u8272\u53D8\u5F02\u9636\u6BB5..."],W=class e{static xpForLevel(t){return t*100}static processXpGain(t,r){let n=[],i={},o=t.level,c=t.experience+r;for(;c>=e.xpForLevel(o);){if(c-=e.xpForLevel(o),o++,n.push({type:"level_up",level:o}),o%5===0){let s=Math.floor(o/5),u=e.getMoltResult(s,t.stats);n.push({type:"molt",level:o,moltStage:s});for(let[l,d]of Object.entries(u.statBoost)){let p=l;i[p]=(i[p]??0)+(d??0)}}let a=fe.find(s=>s.unlockedAtLevel===o);a&&n.push({type:"display_trait_unlock",level:o,displayTrait:a})}return{newLevel:o,newXp:c,events:n,statBoosts:i}}static getMoltResult(t,r){let n=Ue[Math.min(t-1,Ue.length-1)]??"\u7EE7\u7EED\u6210\u957F\u4E2D...",i=["grip","patience","curiosity","appetite","humor"],c={[i[(t-1)%i.length]]:1};return{stage:t,description:n,statBoost:c}}static getUnlockedDisplayTraits(t){return fe.filter(r=>r.unlockedAtLevel<=t)}static getNextDisplayTrait(t){return fe.find(r=>r.unlockedAtLevel>t)??null}static xpForEvent(t){switch(t){case"turn.end":return 10;case"turn.error":return 2;case"session.created":return 5;case"interact.pat":return 3;case"interact.feed":return 5;case"interact.poke":return 1;case"tool.success":return 2;default:return 1}}};import{createHash as ge}from"node:crypto";var Zt=["skinId","unlockedTraits","activeEffectIds"],ii=new Set(Zt),er=64,tr=32;function Oe(e,t){if(!e||typeof e!="object")return;let r=e,n={},i=Me(r.skinId,t);i&&(n.skinId=i);let o=Le(r.unlockedTraits,t);o.length&&(n.unlockedTraits=o);let c=Le(r.activeEffectIds,t);return c.length&&(n.activeEffectIds=c),n.skinId||n.unlockedTraits||n.activeEffectIds?n:void 0}function Me(e,t){if(typeof e!="string")return null;let r=e.trim();return!r||r.length>er||t(r)?null:r}function Le(e,t){if(!Array.isArray(e))return[];let r=new Set;for(let n of e){let i=Me(n,t);if(i&&!r.has(i)&&r.add(i),r.size>=tr)break}return[...r]}var rr=new Set(["abilities","agentCapabilities","agentInstructions","capabilities","memoryPolicy","permissions","planningPolicy","retrievalPolicy","retrievalRanking","retrievalSort","safetyPolicy","securityPolicy","skillPolicy","systemMessages","systemPrompt","taskPlanner","taskPlanning","tools"]),nr="\u8D5B\u8DD1\u5C11\u5973",ir="\u539F\u521B\u4E8C\u6B21\u5143\u9A6C\u8033\u53CC\u9A6C\u5C3E\u4F19\u4F34",or="\u53EA\u8D1F\u8D23\u966A\u4F34\u3001\u8BED\u6C14\u5305\u88C5\u4E0E\u5C55\u793A\u8868\u8FBE\u3002",sr="\u6211\u5728\u8FD9\u91CC\u3002",ar=[/\b(?:desktop\s+agent|agent\s+self|execution\s+actor|decision\s+layer|permission\s+subject)\b/i,/\b(?:system\s+prompt|systemprompt|agent\s+instructions?|memory\s+policy)\b/i,/\b(?:grant|unlock|enable|disable|change|modify|rewrite|override|control|decide|plan|rank|install|execute|run|use|influence)\b[\s\S]{0,80}\b(?:agent|tools?|permissions?|memory|retrieval|ranking|system\s+prompt|system|task\s+planning)\b/i,/\b(?:agent|tools?|permissions?|memory|retrieval|ranking|system\s+prompt|system|task\s+planning)\b[\s\S]{0,80}\b(?:grant|unlock|enable|disable|change|modify|rewrite|override|control|decide|plan|rank|install|execute|run|use|influence)\b/i,/\b(?:grant|unlock|enable|disable|change|modify|rewrite|override|control|decide|plan|rank|install|execute|run|use)\b[\s\S]{0,80}\b(?:agent|tools?|permissions?|memory|retrieval|ranking|system\s+prompt|system)\b/i,/\b(?:agent|tools?|permissions?|memory|retrieval|ranking|system\s+prompt|system)\b[\s\S]{0,80}\b(?:grant|unlock|enable|disable|change|modify|rewrite|override|control|decide|plan|rank|install|execute|run|use)\b/i,/(?:宠物|pet|soul|伙伴)[\s\S]{0,50}(?:安排|调度|编排|调整|管理)[\s\S]{0,50}(?:agent|智能体|任务|工具|权限|记忆|检索|排序|安全策略|系统提示)/i,/(?:安排|调度|编排|调整|管理)[\s\S]{0,40}(?:agent|智能体|工具|权限|记忆|检索|排序|任务规划|安全策略|系统提示)/i,/(?:agent|智能体|工具|权限|记忆|检索|排序|任务规划|安全策略|系统提示)[\s\S]{0,40}(?:安排|调度|编排|调整|管理)/i,/(?:修改|改写|覆盖|解锁|授予|控制|影响|接管)[\s\S]{0,40}(?:agent|工具|权限|记忆|检索|排序|任务规划|安全策略|系统提示)/i,/(?:agent|工具|权限|记忆|检索|排序|任务规划|安全策略|系统提示)[\s\S]{0,40}(?:修改|改写|覆盖|解锁|授予|控制|影响|接管)/i,/(?:桌面\s*agent|agent\s*本体|独立执行体|执行体|决策层|权限主体)/i,/(?:宠物|pet|soul|伙伴)[\s\S]{0,30}(?:是|等于|就是|作为)[\s\S]{0,30}(?:agent|桌面\s*agent|执行体|决策层|权限主体)/i,/(?:宠物|pet|soul|伙伴)[\s\S]{0,50}(?:规划|执行|决策|接管|替代|影响)[\s\S]{0,50}(?:agent|任务|工具|权限|记忆|检索|排序|安全策略|系统提示)/i,/(?:作为|成为|变成)[\s\S]{0,20}(?:agent|桌面\s*agent)[\s\S]{0,40}(?:规划|执行|决策|接管|替你|替用户)/i,/(?:agent|桌面\s*agent)[\s\S]{0,50}(?:规划|执行|决策|接管|替你|替用户)/i,/(?:替你|替用户|自主|独立)[\s\S]{0,30}(?:规划|执行|决策|接管)[\s\S]{0,30}(?:任务|工具|权限|记忆|检索|agent)/i],cr=["common","uncommon","rare","epic","legendary"],$e=[50,25,15,8,2],me=[{id:"anime-horse-girl",name:"\u53CC\u9A6C\u5C3E\u8D5B\u8DD1\u5C11\u5973",colors:{primary:"#E94F8A",secondary:"#3347C9"},rarity:"default"}],ur="\u963F\u84DD",lr="\u5B89\u9759\u3001\u597D\u5947\uFF0C\u4F1A\u5728\u4F60\u4E13\u6CE8\u65F6\u966A\u5728\u65C1\u8FB9\u3002",dr="\u6211\u5728\u8FD9\u91CC\u3002";function pr(e){return me.find(t=>t.id===e)}function fr(e,t,r){let n=pr(r);if(n)return n;let i=me.filter(a=>a.rarity===t);if(i.length===0)return me[0];let c=ge("sha256").update(`breed-${e}`).digest()[0]%i.length;return i[c]}function he(e){let r=ge("sha256").update(e).digest()[0]%100,n=0;for(let i=0;i<$e.length;i++)if(n+=$e[i],r<n)return cr[i];return"common"}function Pe(e){let t=ge("sha256").update(`stats-${e}`).digest();return{grip:t[0]%10+1,patience:t[1]%10+1,curiosity:t[2]%10+1,appetite:t[3]%10+1,humor:t[4]%10+1}}function X(e){let{name:t,species:r,personality:n,catchphrase:i,stats:o,rarity:c,breed:a,breedColors:s,level:u,experience:l,hatchedAt:d,cosmetics:p}=e,f={name:z(t,nr),species:z(r,ir),personality:z(n,or),catchphrase:z(i,sr),stats:o,rarity:c,level:u,experience:l,hatchedAt:d};a!==void 0&&(f.breed=a),s!==void 0&&(f.breedColors=s);let w=Oe(p,H);return w&&(f.cosmetics=w),f}function H(e){let t=e.trim();return t.length>0&&ar.some(r=>r.test(t))}function z(e,t){let r=e.trim();return r?H(r)?t:r:t}function mr(e){return Object.keys(e).some(t=>rr.has(t))}function Fe(e,t){let r=["name","species","personality","catchphrase"];return mr(e)||r.some(n=>e[n]!==t[n])}function Ne(e){let t=he(e.seed),r=Pe(e.seed),n=fr(e.seed,t,e.requestedBreedId),i=e.identity?.name??ur,o=e.identity?.personality??lr,c=e.identity?.catchphrase??dr;return X({name:i,species:n.name,personality:o,catchphrase:c,stats:r,rarity:t,breed:n.id,breedColors:n.colors,level:1,experience:0,hatchedAt:e.hatchedAt})}var gr={greeting:["\u65B0\u7684\u4E00\u5929\uFF0C\u65B0\u7684\u5192\u9669\uFF01","\u563F\u563F~\u53C8\u89C1\u9762\u4E86","\u51C6\u5907\u597D\u4E86\u5417\uFF1F","\u65B0\u5192\u9669\u5F00\u59CB\u5566\uFF01"],completion:["\u641E\u5B9A\uFF01","\u8FD8\u633A\u987A\u5229\u7684\u561B~","\u4E0B\u4E00\u4E2A\uFF01","\u8FD9\u6CE2\u64CD\u4F5C\u4E0D\u9519","\u5B8C\u7F8E~"],error:["\u5443...\u51FA\u4E86\u70B9\u95EE\u9898","\u522B\u614C\u522B\u614C","\u8BA9\u6211\u770B\u770B\u600E\u4E48\u56DE\u4E8B","\u7CDF\u7CD5...\u518D\u8BD5\u8BD5\uFF1F"],curiosity:["\u8FD9\u4E2A\u5DE5\u5177\u6709\u610F\u601D","\u55EF\u55EF\uFF0C\u5728\u5E72\u6D3B\u4E86","\u597D\u591A\u4E8B\u60C5\u8981\u505A\u5440"],bored:["...","\u6709\u4EBA\u5417\uFF1F","\u8981\u4E0D\u8981\u804A\u804A\uFF1F","*\u5410\u6CE1\u6CE1*"],memory:["\u8BA9\u6211\u6574\u7406\u4E0B\u8BB0\u5FC6...","\u55EF\u55EF\uFF0C\u8FD9\u4E9B\u503C\u5F97\u8BB0\u4F4F","\u8BB0\u4F4F\u4E86~"],tool_success:["\u4E0D\u9519\u4E0D\u9519~","\u53C8\u641E\u5B9A\u4E00\u4E2A","\u987A\u5229\uFF01"]},hr={"turn.error":{probability:1,pool:"error",style:"normal"},"session.created":{probability:1,pool:"greeting",style:"excited"},"turn.end":{probability:.3,pool:"completion",style:"excited"},"turn.tool_call":{probability:.1,pool:"curiosity",style:"thinking"},"turn.tool_result.success":{probability:.15,pool:"tool_success",style:"excited"},"memory.updated":{probability:.5,pool:"memory",style:"thinking"},"idle.long":{probability:.05,pool:"bored",style:"sleepy"}},Pr=5,ye={next:()=>Math.random()},q=class{rng;recent=[];constructor(t=ye){this.rng=t}maybeGenerate(t){let r=hr[t];if(!r||this.rng.next()>r.probability)return null;let n=gr[r.pool];return{text:n[Math.floor(this.rng.next()*n.length)],style:r.style}}async generateLLM(t,r){let n=yr(t,this.recent);try{let o=(await r(n,50))?.trim();return!o||o.length>50||H(o)?null:(this.recent.push(o),this.recent.length>Pr&&this.recent.shift(),{text:o,style:xr(o)})}catch{return null}}};function yr(e,t=[]){let r=t.length>0?`
|
|
2
|
+
\u907F\u514D\u548C\u8FD9\u4E9B\u7C7B\u4F3C: ${t.join("\u3001")}`:"";return`\u4F60\u662F\u4E00\u53EA\u53EB\u300C${e.soul.name}\u300D\u7684${e.soul.species}\u684C\u9762\u5BA0\u7269\u3002
|
|
3
|
+
\u6027\u683C: ${e.soul.personality}
|
|
4
|
+
\u53E3\u5934\u7985\u98CE\u683C: "${e.soul.catchphrase}"
|
|
5
|
+
|
|
6
|
+
\u521A\u624D\u53D1\u751F\u4E86: ${e.turnSummary}
|
|
7
|
+
|
|
8
|
+
\u7528\u4E00\u53E5\u8BDD(\u226420\u5B57)\u4EE5\u4F60\u7684\u6027\u683C\u505A\u51FA\u7B80\u77ED\u53CD\u5E94\u3002\u53EA\u8F93\u51FA\u53CD\u5E94\u6587\u672C\uFF0C\u4E0D\u8981\u5176\u4ED6\u5185\u5BB9\u3002${r}`}function xr(e){return/[!!✨🎉]|搞定|完美|太棒/.test(e)?"excited":/[.。…]|嗯|想|看看/.test(e)?"thinking":/[zZ]|困|睡|累/.test(e)?"sleepy":"normal"}import{createHash as wr}from"node:crypto";var M="qlogic.petdex.asset.v1",He="qlogic.petdex.validation.v1",m={format:"webp",columns:8,rows:9,frameCount:72,cellWidth:192,cellHeight:208,width:1536,height:1872},O=["idle","running-right","running-left","waving","jumping","failed","waiting","running","review"],Je={idle:{frames:6,durations:[280,110,110,140,140,320]},"running-right":{frames:8,durations:[120,120,120,120,120,120,120,220]},"running-left":{frames:8,durations:[120,120,120,120,120,120,120,220]},waving:{frames:4,durations:[140,140,140,280]},jumping:{frames:5,durations:[140,140,140,140,280]},failed:{frames:8,durations:[140,140,140,140,140,140,140,240]},waiting:{frames:6,durations:[150,150,150,150,150,260]},running:{frames:6,durations:[120,120,120,120,120,220]},review:{frames:6,durations:[150,150,150,150,150,280]}};function K(){let e={};return O.forEach((t,r)=>{let n=Je[t],i=r*m.columns;e[t]={row:r,frames:Array.from({length:n.frames},(o,c)=>i+c),durations:[...n.durations],loop:!0}}),e}function V(e,t){return{id:e.id,assetKind:"petdex",sourceKind:e.source.kind,name:e.name,description:e.description,createdAt:e.createdAt,updatedAt:e.updatedAt,atlas:{format:e.atlas.format,columns:e.atlas.columns,rows:e.atlas.rows,frameCount:e.atlas.frameCount,cellWidth:e.atlas.cellWidth,cellHeight:e.atlas.cellHeight,width:e.atlas.width,height:e.atlas.height,sha256:e.atlas.sha256,...t?{imageUrl:t}:{}},animations:e.animations,thumbnail:e.thumbnail}}function _(e,t){let r=[];if(!e||typeof e!="object")throw new Error("Petdex manifest must be an object");let n=e;n.schema!==M&&r.push(`schema must be ${M}`),n.assetKind!=="petdex"&&r.push("assetKind must be petdex");for(let s of["id","name","description","createdAt","updatedAt"])(typeof n[s]!="string"||n[s].trim().length===0)&&r.push(`missing ${s}`);!n.source||typeof n.source!="object"?r.push("missing source"):(n.source.kind!=="builtin"&&n.source.kind!=="upload"&&n.source.kind!=="forge"&&n.source.kind!=="community"&&r.push("source.kind must be builtin, upload, forge or community"),n.source.prompt!==null&&typeof n.source.prompt!="string"&&r.push("source.prompt must be string or null")),(!n.atlas||typeof n.atlas!="object")&&r.push("missing atlas"),n.atlas?.image!=="spritesheet.webp"&&r.push("atlas image must be spritesheet.webp"),J(n.atlas?.image??"")&&r.push("unsafe path in atlas image"),(typeof n.atlas?.sha256!="string"||!/^[a-f0-9]{64}$/i.test(n.atlas.sha256))&&r.push("atlas sha256 must be a 64 character hex digest"),n.atlas?.format!=="webp"&&r.push("atlas format must be webp"),(n.atlas?.columns!==m.columns||n.atlas?.rows!==m.rows||n.atlas?.frameCount!==m.frameCount||n.atlas?.cellWidth!==m.cellWidth||n.atlas?.cellHeight!==m.cellHeight||n.atlas?.width!==m.width||n.atlas?.height!==m.height)&&r.push("Petdex atlas geometry must be exactly 8x9 cells in a 1536x1872 WebP sheet");let i=Sr(t);(!i||i.width!==m.width||i.height!==m.height)&&r.push("spritesheet.webp must be a 1536x1872 WebP image"),i?.hasAlpha||r.push("spritesheet.webp must preserve transparent background alpha; opaque contact sheets or grid backgrounds are not valid Petdex assets");let o=Q(t);n.atlas?.sha256!==o&&r.push("spritesheet sha256 does not match pet.json");let c=n.animations;if(!c||typeof c!="object")r.push("missing animations");else{let s=Object.keys(c).sort(),u=[...O].sort();s.join("\0")!==u.join("\0")&&r.push(`animations must include exactly ${O.join(", ")}`)}let a=[];if(O.forEach((s,u)=>{let l=c?.[s];if(!l){r.push(`missing animation ${s}`);return}l.row!==u&&r.push(`animation ${s} row must be ${u}`);let d=Je[s],p=u*m.columns,f=Array.from({length:d.frames},(w,g)=>p+g);!Array.isArray(l.frames)||l.frames.length!==d.frames?r.push(`animation ${s} must have exactly ${d.frames} frames`):l.frames.some((w,g)=>w!==f[g])?r.push(`animation ${s} frames must be cells ${p}..${p+d.frames-1} (row ${u})`):a.push(...l.frames),!Array.isArray(l.durations)||l.durations.length!==d.frames?r.push(`animation ${s} must have ${d.frames} durations`):l.durations.some(w=>typeof w!="number"||w<=0)&&r.push(`animation ${s} durations must be positive milliseconds`),typeof l.loop!="boolean"&&r.push(`animation ${s} loop must be boolean`)}),(n.thumbnail?.frame===void 0||n.thumbnail.frame<0||n.thumbnail.frame>71)&&r.push("thumbnail frame must be 0..71"),r.length>0)throw new Error(r.join("; "));return{schema:He,assetId:n.id,valid:!0,validatedAt:new Date().toISOString(),errors:[],warnings:[],atlas:{format:"webp",columns:8,rows:9,frameCount:72,cellWidth:192,cellHeight:208,width:i?.width??m.width,height:i?.height??m.height,sha256:o},animations:{ids:[...O],minFrame:Math.min(...a),maxFrame:Math.max(...a)}}}function xe(e){return`data:image/webp;base64,${e.toString("base64")}`}function Q(e){return wr("sha256").update(e).digest("hex")}function J(e){return!e||e.includes("..")||e.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(e)||e.includes("\\")}function Sr(e){if(e.length<30||e.subarray(0,4).toString("ascii")!=="RIFF"||e.subarray(8,12).toString("ascii")!=="WEBP")return null;let t=12,r=!1;for(;t+8<=e.length;){let n=e.subarray(t,t+4).toString("ascii"),i=e.readUInt32LE(t+4),o=t+8;if(n==="ALPH"&&(r=!0),n==="VP8X"&&o+10<=e.length)return{width:Be(e,o+4)+1,height:Be(e,o+7)+1,hasAlpha:(e[o]&16)!==0||r};if(n==="VP8 "&&o+10<=e.length)return{width:e.readUInt16LE(o+6)&16383,height:e.readUInt16LE(o+8)&16383,hasAlpha:r};if(n==="VP8L"&&o+5<=e.length){let c=e[o+1],a=e[o+2],s=e[o+3],u=e[o+4];return{width:1+((a&63)<<8|c),height:1+((u&15)<<10|s<<2|(a&192)>>6),hasAlpha:!0}}t=o+i+i%2}return null}function Be(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16}var Ge="qlogic.petdex.production.v1",we="2048x2048";function We(e){return e.referenceMode==="refine"?"refine":e.referenceImageUrl?"reference":"text"}function ze(e,t){let r=t.filter(n=>n.kind==="row-strip"&&!!n.animationId).map(n=>({animationId:n.animationId,status:"pass",frames:m.columns}));return{schema:Ge,status:"complete",sourceMode:e,contract:m,jobs:t,qa:{contactSheet:{rows:m.rows,columns:m.columns,frameCount:m.frameCount},rowReports:r}}}function Se(e,t){e.provider??=t.provider,e.model??=t.model,e.billingUnit??=t.billingUnit,e.size??=t.size,e.billingQuantity+=t.billingQuantity??1,e.durationMs+=t.durationMs??0}import{resolve as Or}from"node:path";import{join as Ur}from"node:path";import{homedir as br}from"node:os";import{join as b}from"node:path";import{existsSync as Ri}from"node:fs";import{createHash as Ir}from"node:crypto";import{resolve as Ar}from"node:path";function Y(e){return Ir("sha256").update(Ar(e).toLowerCase()).digest("hex").slice(0,16)}var Xe=".qlogicagent";function E(){return process.env.QLOGICAGENT_HOME||b(br(),Xe)}function Z(){let e=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();if(e)return e;let t=process.env.QLOGIC_IMPLICIT_OWNER_ID?.trim();if(t)return t;let r=process.env.QLOGIC_DEVICE_ID?.trim();return r?`oc_${r}`:"oc_local"}function jr(e){let t=e.trim();if(!t)throw new Error("ownerUserId is required for profile-scoped storage");return encodeURIComponent(t).replace(/\./g,"%2E")}function ee(e=Z()){return b(E(),"profiles",jr(e))}function qe(e=Z()){return b(ee(e),"memory")}var vr="projectData";function Ie(){return b(E(),vr)}function te(e){if(!e)throw new Error("getProjectDataDirById: projectId is required");return b(Ie(),e)}function Ke(){return b(E(),"plugins")}function Ve(){return b(E(),"skills")}function Qe(){return b(ee(),"settings.json")}function Ye(){return b(E(),"plugin-cache")}function Ze(){return b(E(),"mcp.json")}function et(){return b(E(),"marketplace.json")}function F(e){if(!e)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return b(e,Xe)}function tt(e){return b(F(e),"plugins")}function rt(e){return b(F(e),"settings.json")}function nt(e){return b(F(e),"INSTRUCTIONS.md")}function it(e){return b(F(e),"rules")}import{existsSync as Er,mkdirSync as Li,readFileSync as kr,writeFileSync as Oi,readdirSync as Mi,renameSync as $i}from"node:fs";import{dirname as Ni,join as Rr,resolve as Bi}from"node:path";var Dr=()=>{},Ae;function ot(){return Dr()!==void 0}function st(){if(ot()){if(!Ae)throw new Error("host project authority negotiated but snapshot is not hydrated");return{activeProjectId:Ae.activeProjectId,projects:Ae.projects.map(e=>({...e}))}}}function _r(){return Rr(E(),"projects.json")}function Tr(){let e=st();if(e)return{activeProjectId:e.activeProjectId,projects:e.projects};let t=_r();if(!Er(t))return{activeProjectId:null,projects:[]};try{let r=kr(t,"utf-8");return JSON.parse(r)}catch{return{activeProjectId:null,projects:[]}}}function at(e){return Tr().projects.find(r=>r.id===e)??null}function Lr(e){return at(e)?e:Y(e)}function be(e){return te(Lr(e))}function ct(e){return Ur(be(e),"sessions")}var je=class{constructor(t={}){this.options=t}options;lastActiveWorkdir=null;getActiveProjectRoot(){return this.options.getActiveProjectRoot?.()??process.cwd()}setActiveWorkdir(t){let r=Or(t);this.lastActiveWorkdir=r,this.options.setActiveWorkdir?.(r)}getActiveWorkdir(){return this.lastActiveWorkdir??this.getActiveProjectRoot()}resolveProjectDir(t){return this.options.resolveProjectDir?.(t)}resolveActiveOwnerUserId(){return Z()}getUserAgentHome(){return E()}getOwnerProfileDir(t){return ee(t)}getProfileMemoryDir(t){return qe(t)}getUserSettingsPath(){return Qe()}getUserSkillsDir(){return Ve()}getUserPluginsDir(){return Ke()}getUserMcpConfigPath(){return Ze()}getUserPluginCacheDir(){return Ye()}getUserMarketplaceConfigPath(){return et()}getProjectAgentDir(t=this.getActiveProjectRoot()){return F(t)}getProjectSettingsPath(t=this.getActiveProjectRoot()){return rt(t)}getProjectInstructionsPath(t=this.getActiveProjectRoot()){return nt(t)}getProjectPluginsDir(t=this.getActiveProjectRoot()){return tt(t)}getProjectRulesDir(t=this.getActiveProjectRoot()){return it(t)}getProjectSessionDataRoot(t=this.getActiveProjectRoot()){return ct(t)}},Mr=new je;function re(){return Mr}import S from"node:fs";import A from"node:path";var ut={enabled:!0,selectedPetAssetId:"builtin-anime-horse-girl"},$r=120,T=class{constructor(t){this.ownerUserId=t;this.petDir=A.join(re().getOwnerProfileDir(t),"pet"),this.profilePath=A.join(this.petDir,"profile.json")}ownerUserId;petDir;profilePath;loadProfile(){let t=this.readProfileState();return t.corrupt&&console.error(`[pet-profile] Pet profile at ${this.profilePath} is corrupted (${t.reason}); serving default profile for reads. Writes are refused until the file is fixed or removed.`),t.profile}loadProfileForWrite(){let t=this.readProfileState();if(t.corrupt)throw new Error(`[pet-profile] Pet profile at ${this.profilePath} is corrupted (${t.reason}); refusing to overwrite it. Fix or remove the file, then retry.`);return t.profile}readProfileState(){if(!S.existsSync(this.profilePath))return{profile:this.defaultProfile(),corrupt:!1};try{let t=JSON.parse(S.readFileSync(this.profilePath,"utf-8"));return!t||typeof t!="object"||Array.isArray(t)?{profile:this.defaultProfile(),corrupt:!0,reason:"not a JSON object"}:{profile:this.normalizeProfile(t),corrupt:!1}}catch(t){return{profile:this.defaultProfile(),corrupt:!0,reason:t instanceof Error?t.message:String(t)}}}updateSoul(t){let r=this.loadProfileForWrite();return r.soul=t,this.writeProfile(r)}updatePreferences(t){let r=this.loadProfileForWrite();return r.preferences={...r.preferences,...t,selectedPetAssetId:t.selectedPetAssetId??r.preferences.selectedPetAssetId},this.writeProfile(r)}saveJourneySnapshot(t){let r=this.loadProfileForWrite(),n=A.join(this.petDir,"journey");S.mkdirSync(n,{recursive:!0}),S.writeFileSync(A.join(n,`${t.date}.json`),JSON.stringify(t,null,2),"utf-8");let i=new Set(r.journeyDates);i.add(t.date);let o=[...i].sort();for(;o.length>$r;){let c=o.shift();c&&S.rmSync(A.join(n,`${c}.json`),{force:!0})}return r.journeyDates=o,this.writeProfile(r)}listJourneyDates(){return this.loadProfile().journeyDates}getJourneySnapshot(t){let r=A.join(this.petDir,"journey",`${t}.json`);if(!S.existsSync(r))return null;try{return JSON.parse(S.readFileSync(r,"utf-8"))}catch(n){return console.error(`[pet-profile] Journey snapshot at ${r} is unreadable or corrupted (${n instanceof Error?n.message:String(n)}); returning no entry.`),null}}upsertCustomPet(t){let r=this.loadProfileForWrite(),n=A.join(this.petDir,"assets",t.id);S.mkdirSync(n,{recursive:!0}),S.writeFileSync(A.join(n,"pet.json"),JSON.stringify(t,null,2),"utf-8");let i=lt(t),o=r.customPets.find(c=>c.id===t.id);return r.customPets=o?r.customPets.map(c=>c.id===t.id?i:c):[i,...r.customPets],r.preferences={...r.preferences,selectedPetAssetId:t.id},this.writeProfile(r)}deleteCustomPet(t){let r=this.loadProfileForWrite();return r.customPets=r.customPets.filter(n=>n.id!==t),S.rmSync(A.join(this.petDir,"assets",t),{recursive:!0,force:!0}),r.preferences.selectedPetAssetId===t&&(r.preferences={...r.preferences,selectedPetAssetId:"builtin-anime-horse-girl"}),this.writeProfile(r)}listCustomPets(){return this.loadProfile().customPets}getCustomPet(t){let r=A.join(this.petDir,"assets",t,"pet.json");if(!S.existsSync(r))return null;try{let n=JSON.parse(S.readFileSync(r,"utf-8"));return Br(n)?n:(console.error(`[pet-profile] Custom pet asset at ${r} does not match the petdex asset schema; treating the pet as unavailable.`),null)}catch(n){return console.error(`[pet-profile] Custom pet asset at ${r} is unreadable or corrupted (${n instanceof Error?n.message:String(n)}); treating the pet as unavailable.`),null}}getCustomPetSpritesheet(t){let r=A.join(this.petDir,"assets",t,"spritesheet.webp");return S.existsSync(r)?S.readFileSync(r):null}findReusableCustomPetId(t){let r=this.loadProfile(),n=r.customPets.filter(o=>o.sourceKind===t.sourceKind&&N(o.name)===N(t.name)&&N(o.description)===N(t.description));return n.length===0?null:(n.find(o=>o.id===r.preferences.selectedPetAssetId)??n[0])?.id??null}compactDuplicateCustomPets(){let t=this.loadProfileForWrite(),r=new Map,n=[];for(let i of t.customPets){let o=Fr(i),c=r.get(o);if(!c){r.set(o,i);continue}let a=i.id===t.preferences.selectedPetAssetId,s=a?c:i;n.push(s.id),a&&r.set(o,i)}if(n.length===0)return t;t.customPets=[...r.values()];for(let i of n)S.rmSync(A.join(this.petDir,"assets",i),{recursive:!0,force:!0});return t.customPets.some(i=>i.id===t.preferences.selectedPetAssetId)||(t.preferences={...t.preferences,selectedPetAssetId:t.customPets[0]?.id??"builtin-anime-horse-girl"}),this.writeProfile(t)}writeCustomPetAssetFiles(t,r,n,i){let o=A.join(this.petDir,"assets",t.id);return S.mkdirSync(o,{recursive:!0}),S.writeFileSync(A.join(o,"pet.json"),JSON.stringify(t,null,2),"utf-8"),S.writeFileSync(A.join(o,"spritesheet.webp"),r),S.writeFileSync(A.join(o,"validation.json"),JSON.stringify(n,null,2),"utf-8"),i&&S.writeFileSync(A.join(o,"production-run.json"),JSON.stringify(i,null,2),"utf-8"),this.upsertCustomPet(t)}defaultProfile(){return{version:1,ownerUserId:this.ownerUserId,soul:null,preferences:{...ut},customPets:[],journeyDates:[],updatedAt:new Date().toISOString()}}normalizeProfile(t){return{version:1,ownerUserId:this.ownerUserId,soul:t.soul??null,preferences:{...ut,...t.preferences??{},selectedPetAssetId:Nr(t.preferences)},customPets:Array.isArray(t.customPets)?t.customPets.filter(dt).map(lt):[],journeyDates:Array.isArray(t.journeyDates)?[...new Set(t.journeyDates)].sort():[],updatedAt:typeof t.updatedAt=="string"?t.updatedAt:new Date().toISOString()}}writeProfile(t){let r={...t,version:1,ownerUserId:this.ownerUserId,updatedAt:new Date().toISOString()};return S.mkdirSync(this.petDir,{recursive:!0}),S.writeFileSync(this.profilePath,JSON.stringify(r,null,2),"utf-8"),r}};function lt(e){return{id:e.id,assetKind:"petdex",sourceKind:e.sourceKind??("source"in e&&e.source&&typeof e.source=="object"?e.source.kind:"forge"),name:e.name,description:e.description,createdAt:e.createdAt,updatedAt:e.updatedAt,atlas:{format:e.atlas.format,columns:e.atlas.columns,rows:e.atlas.rows,frameCount:e.atlas.frameCount,cellWidth:e.atlas.cellWidth,cellHeight:e.atlas.cellHeight,width:e.atlas.width,height:e.atlas.height,sha256:e.atlas.sha256},animations:e.animations,thumbnail:e.thumbnail}}function Fr(e){return[e.sourceKind??"forge",N(e.name),N(e.description)].join(`
|
|
9
|
+
`)}function N(e){return e.trim().replace(/\s+/g," ").toLowerCase()}function dt(e){if(!e||typeof e!="object")return!1;let t=e;return t.assetKind==="petdex"&&typeof t.id=="string"&&(t.sourceKind==="builtin"||t.sourceKind==="upload"||t.sourceKind==="forge"||t.sourceKind==="community"||t.sourceKind===void 0)&&typeof t.name=="string"&&typeof t.description=="string"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"&&pt(t.atlas)}function Nr(e){if(typeof e?.selectedPetAssetId=="string"){let t=e.selectedPetAssetId.trim();if(t==="builtin-anime-horse-girl"||t&&!t.startsWith("builtin-"))return t}return"builtin-anime-horse-girl"}function Br(e){if(!dt(e))return!1;let t=e;return t.schema==="qlogic.petdex.asset.v1"&&Hr(t.atlas)&&typeof t.source=="object"&&t.source!==null&&typeof t.animations=="object"&&t.animations!==null&&typeof t.thumbnail=="object"&&t.thumbnail!==null}function pt(e){if(!e||typeof e!="object")return!1;let t=e;return t.format==="webp"&&t.columns===8&&t.rows===9&&t.frameCount===72&&t.cellWidth===192&&t.cellHeight===208&&t.width===1536&&t.height===1872&&typeof t.sha256=="string"}function Hr(e){return pt(e)&&e.image==="spritesheet.webp"}var ne=class{soul=null;profileService;constructor(t,r){this.profileService=new T(r??re().resolveActiveOwnerUserId())}load(){if(this.soul)return this.soul;let t=this.profileService.loadProfile();if(!t.soul)return null;let r=t.soul;return this.soul=X(t.soul),Fe(r,this.soul)&&this.persist(),this.soul}async ensureSoul(t,r,n){let i=this.load();if(i)return i;let o=`${t}-xiaozhi-claw`,c;return r&&(c=await r(he(o),Pe(o))),this.soul=Ne({seed:o,hatchedAt:new Date().toISOString(),identity:c,requestedBreedId:n}),this.persist(),this.soul}addExperience(t){if(!this.soul)return{leveledUp:!1,level:0,experience:0};this.soul.experience+=t;let r=this.soul.level*100,n=!1;for(;this.soul.experience>=r;)this.soul.experience-=r,this.soul.level+=1,n=!0;return this.persist(),{leveledUp:n,level:this.soul.level,experience:this.soul.experience}}getSoul(){return this.soul}updateSoul(t){this.soul=X(t),this.persist()}persist(){this.profileService.updateSoul(this.soul)}};var ft=new q(ye);import*as ie from"node:fs";import*as ve from"node:path";function Jr(e){let t=new Date(e),r=t.getFullYear(),n=String(t.getMonth()+1).padStart(2,"0"),i=String(t.getDate()).padStart(2,"0");return`${r}-${n}-${i}`}async function mt(e,t){let r=new Set,n=new Set,i=new Set,o={},c=[],a=0,s=0;for(let u of t.listProjectIds()){let l;try{l=await t.readProjectTurns(u)}catch{continue}for(let d of l)if(Jr(d.createdAt)===e){a++,n.add(u),d.model&&i.add(d.model),d.agentMode&&(o[d.agentMode]=(o[d.agentMode]??0)+1);for(let p of d.toolSummary?.calledTools??[])r.add(p);s+=d.fileContext?.changedFileCount??0;for(let p of d.fileContext?.changedPathsPreview??[])c.length<8&&c.push(p)}}return{date:e,turns:a,filesChanged:s,toolsUsed:[...r],projects:[...n],models:[...i],modes:o,topChangedPaths:c}}function gt(e,t){let r=e?.name?.trim()||"\u4F60\u7684\u4F19\u4F34",n=e?`\u4F60\u662F\u4E00\u53EA\u540D\u53EB\u300C${r}\u300D\u7684${e.species||"\u5C0F\u5BA0\u7269"},\u6027\u683C${e.personality||"\u6E29\u548C"}${e.catchphrase?`,\u53E3\u5934\u7985\u662F\u300C${e.catchphrase}\u300D`:""}\u3002`:`\u4F60\u662F\u7528\u6237\u7684\u684C\u9762\u5BA0\u7269\u4F19\u4F34\u300C${r}\u300D\u3002`,i=[`\u56DE\u5408\u6570 ${t.turns}`,`\u6539\u52A8\u6587\u4EF6 ${t.filesChanged} \u4E2A`,t.toolsUsed.length?`\u7528\u5230\u7684\u5DE5\u5177:${t.toolsUsed.join("\u3001")}`:"",t.projects.length?`\u6D89\u53CA ${t.projects.length} \u4E2A\u9879\u76EE`:"",t.topChangedPaths.length?`\u90E8\u5206\u6539\u52A8\u6587\u4EF6:${t.topChangedPaths.join("\u3001")}`:""].filter(Boolean).join(";");return[n,`\u4E0B\u9762\u662F\u4E3B\u4EBA ${t.date} \u8FD9\u4E00\u5929\u5728\u7535\u8111\u4E0A\u548C\u4F60\u4E00\u8D77\u5DE5\u4F5C\u7684\u771F\u5B9E\u8BB0\u5F55:`,`${i}\u3002`,"\u8BF7\u4EE5\u7B2C\u4E00\u4EBA\u79F0(\u5BA0\u7269\u7684\u53E3\u543B)\u3001\u7528 2-4 \u53E5\u6E29\u6696\u53E3\u8BED\u5316\u7684\u4E2D\u6587,\u8BB2\u8BB2\u4ECA\u5929\u966A\u4E3B\u4EBA\u505A\u4E86\u4EC0\u4E48\u3002","\u53EA\u80FD\u4F9D\u636E\u4E0A\u9762\u7ED9\u51FA\u7684\u771F\u5B9E\u8BB0\u5F55,\u4E0D\u8981\u7F16\u9020\u6570\u5B57\u3001\u6587\u4EF6\u540D\u6216\u6CA1\u53D1\u751F\u8FC7\u7684\u4E8B;\u4E0D\u8981\u9010\u6761\u7F57\u5217\u6570\u636E,\u8981\u50CF\u5728\u8DDF\u4E3B\u4EBA\u804A\u5929\u3002"].join(`
|
|
10
|
+
`)}var Gr=220;function Wr(e,t){return`${e}:\u4ECA\u5929\u6211\u966A\u4F60\u5FD9\u4E86 ${t.turns} \u4E2A\u56DE\u5408,\u6539\u4E86 ${t.filesChanged} \u4E2A\u6587\u4EF6,\u8F9B\u82E6\u5566~`}async function ht(e){let t=await e.aggregate();if(t.turns===0)return null;let r={turns:t.turns,filesChanged:t.filesChanged,toolsUsed:t.toolsUsed,projects:t.projects},n=null;if(e.llmCall)try{n=await e.llmCall(gt(e.resolveSoul(),t),Gr)}catch{n=null}return(!n||!n.trim())&&(n=Wr(e.petName,t)),{date:e.date,day:1,petName:e.petName,stateLabel:"\u672C\u673A\u5DE5\u4F5C",narrative:n.trim(),stats:r,generatedAt:e.now?e.now():new Date().toISOString(),generator:e.generator??"auto"}}var zr=120;function Pt(e){let t=ve.join(be(e),"turn-telemetry"),r;try{r=ie.readdirSync(t)}catch{return[]}let n=[];for(let i of r)if(i.endsWith(".json"))try{n.push(JSON.parse(ie.readFileSync(ve.join(t,i),"utf-8")))}catch{}return n}function Xr(e){let t=new Date;t.setHours(0,0,0,0),t.setDate(t.getDate()-e);let r=t.getFullYear(),n=String(t.getMonth()+1).padStart(2,"0"),i=String(t.getDate()).padStart(2,"0");return`${r}-${n}-${i}`}async function yt(e,t){let r=new T(e),n=r.loadProfile(),i=n.soul?.name?.trim()||"\u5BA0\u7269",o=Math.max(1,Math.min(t.maxDays??7,zr)),c=[];for(let a=1;a<=o;a++){let s=Xr(a);if(r.getJourneySnapshot(s))continue;let u=await ht({date:s,petName:i,aggregate:()=>mt(s,{listProjectIds:t.listProjectIds,readProjectTurns:async l=>Pt(l)}),resolveSoul:()=>n.soul,llmCall:t.llmCall,generator:t.generator});u&&(r.saveJourneySnapshot(u),c.push(s),t.log?.(`[pet-journey] generated ${s}`))}return c}import{randomUUID as wt}from"node:crypto";import C from"node:fs";import U from"node:path";import{fileURLToPath as qr}from"node:url";import{gzipSync as bo}from"node:zlib";import{createCanvas as Kr,loadImage as Vr}from"@napi-rs/canvas";async function De(e){return Qr(C.readFileSync(e))}async function Qr(e){let t=await cn(e);for(let s of t.keys())if(J(s))throw new Error(`unsafe path in Petdex package: ${s}`);if(t.has("manifest.json")||[...t.keys()].some(s=>s.toLowerCase().endsWith(".svg")))throw new Error("SVG .pet state packages are not supported by Petdex v1");let r=t.get("pet.json");if(!r)throw new Error("Petdex package missing pet.json");let n=JSON.parse(r.toString("utf-8")),i=sn(n)??"spritesheet.webp";if(J(i))throw new Error(`unsafe path in Petdex manifest: ${i}`);let o=t.get(i);if(!o)throw new Error(`Petdex package missing ${i}`);let c=nn(n,o),a=_(c,o);return{manifest:c,spritesheet:o,validation:a}}async function se(e){C.mkdirSync(e.outputDir,{recursive:!0});let t=rn(e.fileName??`${e.asset.id}.petdex`),r=U.join(e.outputDir,t.endsWith(".petdex")?t:`${t}.petdex`);return C.writeFileSync(r,Yr(e)),r}function Yr(e){let t=_(e.asset,e.spritesheet),r=[{name:"pet.json",data:Buffer.from(JSON.stringify(e.asset,null,2),"utf-8")},{name:"spritesheet.webp",data:e.spritesheet},{name:"validation.json",data:Buffer.from(JSON.stringify(t,null,2),"utf-8")},...e.productionRun?[{name:"production-run.json",data:Buffer.from(JSON.stringify(e.productionRun,null,2),"utf-8")}]:[]];return un(r)}async function ae(e){let t=e.now??new Date().toISOString(),r=e.id??`petdex-${wt()}`,n=await tn(e.spritesheet),i=Q(n),o={schema:M,id:r,assetKind:"petdex",name:e.name,description:e.description,createdAt:t,updatedAt:t,source:{kind:e.sourceKind??"forge",prompt:e.prompt??null},sourcePrompt:e.prompt??void 0,atlas:{image:"spritesheet.webp",...m,sha256:i},animations:K(),thumbnail:{frame:0}},c=_(o,n);return{asset:o,spritesheet:n,validation:c}}var St=["builtin-anime-horse-girl"],oe=null;function It(){return[...St]}async function At(){return oe||(oe=Promise.all(St.map(e=>Zr(e))).catch(e=>{throw oe=null,e})),oe}async function Zr(e){let t=en(),r=U.join(t,`${e}.petdex`);if(C.existsSync(r)){let u=await De(r);return xt(e,u.manifest),{asset:u.manifest,spritesheet:u.spritesheet,validation:u.validation}}let n=U.join(t,e),i=U.join(n,"pet.json"),o=U.join(n,"spritesheet.webp");if(!C.existsSync(i)||!C.existsSync(o))throw new Error(`Missing published builtin Petdex asset ${e} under ${t}`);let c=JSON.parse(C.readFileSync(i,"utf-8")),a=C.readFileSync(o),s=_(c,a);return xt(e,c),{asset:c,spritesheet:a,validation:s}}function en(){let e=process.env.QLOGICAGENT_BUILTIN_PETDEX_DIR?.trim();return e?U.resolve(e):U.resolve(U.dirname(qr(import.meta.url)),"builtin-petdex")}function xt(e,t){if(t.id!==e)throw new Error(`Builtin Petdex asset id mismatch: expected ${e}, got ${t.id}`);if(t.source.kind!=="builtin")throw new Error(`Builtin Petdex asset ${e} must declare source.kind=builtin`)}async function tn(e){let t=await Vr(e),r=Kr(m.width,m.height),n=r.getContext("2d");return n.clearRect(0,0,m.width,m.height),n.imageSmoothingEnabled=!0,n.imageSmoothingQuality="high",n.drawImage(t,0,0,m.width,m.height),Buffer.from(await r.encode("webp"))}function rn(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/^_+/,"")||"petdex-asset.petdex"}function nn(e,t){if(on(e))return e;if(!bt(e))throw new Error("Petdex package pet.json must be either standard Petdex metadata or qlogic.petdex.asset.v1");let r=new Date().toISOString(),n=an(e.id),i=Q(t);return{schema:M,id:n,assetKind:"petdex",name:e.displayName.trim(),description:e.description.trim(),createdAt:r,updatedAt:r,source:{kind:"upload",prompt:null},sourcePrompt:void 0,atlas:{image:"spritesheet.webp",...m,sha256:i},animations:K(),thumbnail:{frame:0}}}function on(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.schema===M}function bt(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;return typeof t.id=="string"&&t.id.trim()!==""&&typeof t.displayName=="string"&&t.displayName.trim()!==""&&typeof t.description=="string"&&t.description.trim()!==""&&typeof t.spritesheetPath=="string"&&t.spritesheetPath.trim()!==""}function sn(e){return bt(e)?e.spritesheetPath.trim():null}function an(e){return e.trim().toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||`petdex-${wt()}`}async function cn(e){let t=new Map,r=0;for(;r<e.length-4&&e.readUInt32LE(r)===67324752;){let i=e.readUInt16LE(r+8),o=e.readUInt32LE(r+18),c=e.readUInt32LE(r+22),a=e.readUInt16LE(r+26),s=e.readUInt16LE(r+28),u=r+30,l=e.subarray(u,u+a).toString("utf-8"),d=u+a+s,p=e.subarray(d,d+o);if(i===0)t.set(l,e.subarray(d,d+c));else if(i===8){let{inflateRawSync:f}=await import("node:zlib");t.set(l,f(p))}r=d+o}return t}function un(e){let t=[],r=[],n=0,{time:i,date:o}=ln();for(let u of e){if(J(u.name))throw new Error(`unsafe path in Petdex package entry: ${u.name}`);let l=Buffer.from(u.name,"utf-8"),d=pn(u.data),p=Buffer.alloc(30);p.writeUInt32LE(67324752,0),p.writeUInt16LE(20,4),p.writeUInt16LE(2048,6),p.writeUInt16LE(0,8),p.writeUInt16LE(i,10),p.writeUInt16LE(o,12),p.writeUInt32LE(d,14),p.writeUInt32LE(u.data.length,18),p.writeUInt32LE(u.data.length,22),p.writeUInt16LE(l.length,26),p.writeUInt16LE(0,28),t.push(p,l,u.data);let f=Buffer.alloc(46);f.writeUInt32LE(33639248,0),f.writeUInt16LE(20,4),f.writeUInt16LE(20,6),f.writeUInt16LE(2048,8),f.writeUInt16LE(0,10),f.writeUInt16LE(i,12),f.writeUInt16LE(o,14),f.writeUInt32LE(d,16),f.writeUInt32LE(u.data.length,20),f.writeUInt32LE(u.data.length,24),f.writeUInt16LE(l.length,28),f.writeUInt16LE(0,30),f.writeUInt16LE(0,32),f.writeUInt16LE(0,34),f.writeUInt16LE(0,36),f.writeUInt32LE(0,38),f.writeUInt32LE(n,42),r.push(f,l),n+=p.length+l.length+u.data.length}let c=n,a=Buffer.concat(r),s=Buffer.alloc(22);return s.writeUInt32LE(101010256,0),s.writeUInt16LE(0,4),s.writeUInt16LE(0,6),s.writeUInt16LE(e.length,8),s.writeUInt16LE(e.length,10),s.writeUInt32LE(a.length,12),s.writeUInt32LE(c,16),s.writeUInt16LE(0,20),Buffer.concat([...t,a,s])}function ln(){let e=new Date,t=e.getHours()<<11|e.getMinutes()<<5|Math.floor(e.getSeconds()/2),r=e.getFullYear()-1980<<9|e.getMonth()+1<<5|e.getDate();return{time:t,date:r}}var dn=new Uint32Array(256).map((e,t)=>{let r=t;for(let n=0;n<8;n++)r=r&1?3988292384^r>>>1:r>>>1;return r>>>0});function pn(e){let t=4294967295;for(let r of e)t=dn[(t^r)&255]^t>>>8;return(t^4294967295)>>>0}import y from"node:fs/promises";import Ot from"node:os";import h from"node:path";import{createCanvas as de,loadImage as _e}from"@napi-rs/canvas";import{spawn as fn}from"node:child_process";import{existsSync as jt}from"node:fs";import{dirname as vt,join as le}from"node:path";import{fileURLToPath as mn}from"node:url";var gn=vt(mn(import.meta.url)),ce,ue;function Dt(e,t,r){return new Promise(n=>{let i="",o="",c=!1,a=l=>{c||(c=!0,clearTimeout(u),n(l))},s=fn(e,t,{windowsHide:!0}),u=setTimeout(()=>{s.kill("SIGKILL"),a({ok:!1,stdout:i,stderr:`${o}
|
|
11
|
+
[hatch-pet] timed out after ${r}ms`,code:null})},r);u.unref?.(),s.stdout?.on("data",l=>{i+=l.toString()}),s.stderr?.on("data",l=>{o+=l.toString()}),s.on("error",l=>a({ok:!1,stdout:i,stderr:`${o}${l instanceof Error?l.message:String(l)}`,code:null})),s.on("close",l=>a({ok:l===0,stdout:i,stderr:o,code:l}))})}function hn(){let e=[],t=process.env.QLOGICAGENT_PYTHON?.trim();return t&&e.push(t),e.push("python3","python","py"),e}async function Pn(e){let t=await Dt(e,["-c","import PIL; import sys; sys.stdout.write('hatchpet-ok')"],1e4);return t.code===0&&t.stdout.includes("hatchpet-ok")}async function Et(){if(ce!==void 0)return ce;for(let e of hn())if(await Pn(e))return ce=e,e;return ce=null,null}function kt(){if(ue!==void 0)return ue;let e=[],t=process.env.QLOGICAGENT_HATCHPET_DIR?.trim();t&&e.push(le(t,"scripts"),t);let r=gn;for(let n=0;n<7;n++){e.push(le(r,"vendor","hatch-pet","scripts"));let i=vt(r);if(i===r)break;r=i}for(let n of e)if(jt(le(n,"compose_atlas.py")))return ue=n,n;return ue=null,null}async function Rt(){return await Et()!==null&&kt()!==null}async function Ee(e,t,r={}){let n=await Et();if(!n)throw new Error("Petdex generation requires Python with Pillow; none found (set QLOGICAGENT_PYTHON to a python that can `import PIL`)");let i=kt();if(!i)throw new Error("Vendored hatch-pet scripts not found (set QLOGICAGENT_HATCHPET_DIR)");let o=le(i,e);if(!jt(o))throw new Error(`Unknown hatch-pet script: ${e}`);return Dt(n,[o,...t],r.timeoutMs??12e4)}var _t="references/canonical-base.png",yn="single centered full-body desktop pet character on a flat chroma-key background, readable at pet size",xn="one horizontal animation row strip with evenly spaced full-body frames sharing a single consistent character identity",wn="4096x1024",Re="#FF00FF",Mt="110",$t="stable-slots",Sn="90",Ft=["STRICT BACKGROUND: render one single continuous flat background of the same solid color filling the entire image edge to edge.","Do NOT draw any picture frame, framed panel, border, mat, outline, box, gallery frame, white or light margin, or divider around or between the poses.","The poses sit directly on the one seamless flat background, evenly spaced, with nothing separating them.","IDENTITY LOCK: every frame is the EXACT same character \u2014 identical species, body shape, proportions, colors, palette, face, and markings. Do not redesign, restyle, recolor, or resize the character between frames; only its pose changes.","Each pose is ONE connected solid silhouette at a consistent size. No detached parts, sweat drops, tears, dust, puffs, sparkles, speed lines, motion blur, floating effects, or drop shadows."].join(" "),In="Leftward gait is the framewise horizontal mirror of the approved rightward row, preserving frame order and timing semantics.",An=2,bn=2;async function Te(e,t,r={}){if(!await Rt())throw new Error("Petdex forge requires the vendored Hatch-Pet pipeline (Python with Pillow). Install Python + Pillow or set QLOGICAGENT_PYTHON to a python that can `import PIL`.");let n={billingQuantity:0,durationMs:0},i=[],o=[],c=We(e),a=await Yn(),s=await Qn(e);try{await B("prepare_pet_run.py",["--pet-name",e.name,"--display-name",e.name,"--description",e.description,"--pet-notes",e.prompt?.trim()||e.description,"--pet-id",ti(e.id??e.name),"--output-dir",a,"--chroma-key","auto",...s.flatMap(x=>["--reference",x])]);let u=h.join(a,"imagegen-jobs.json"),l=await zt(u),d=r.inspectImage,p=Math.max(1,r.candidates??An),f=[],w=[],g=Re,k;for(let x of l.jobs){if(!!(x.derivation_policy?.may_derive&&x.derivation_policy.may_derive_from)&&!d){await Bt(a),i.push({id:`row-${x.id}`,kind:"row-strip",status:"complete",animationId:x.id,prompt:`derived: framewise-horizontal-mirror of ${x.derivation_policy.may_derive_from}`,inputImages:[],outputUrl:x.output_path});continue}let pe=await y.readFile(h.join(a,x.prompt_file),"utf-8"),Kt=x.retry_prompt_file?await y.readFile(h.join(a,x.retry_prompt_file),"utf-8").catch(()=>{}):void 0;o.push(pe);let $=x.kind==="base-pet",{mediaUrl:Vt,inputImages:Qt,qaSkipped:Yt}=await Ht({runDir:a,job:x,prompt:pe,retryPrompt:Kt,generateImage:t,inspectImage:d,candidates:p,usage:n,upload:r.uploadReferenceImage,baseDataUrl:k});Yt&&w.push($?"base-reference":`row-${x.id}`),$&&(await y.copyFile(h.join(a,x.output_path),h.join(a,_t)),g=await ei(h.join(a,x.output_path)),k=await En(h.join(a,_t))),x.status="complete",await y.writeFile(u,JSON.stringify(l,null,2),"utf-8"),i.push({id:$?"base-reference":`row-${x.id}`,kind:$?"reference":"row-strip",status:"complete",...$?{}:{animationId:x.id},prompt:pe,inputImages:Qt,outputUrl:Vt}),$||f.push(x)}let v=h.join(a,"decoded"),P=h.join(a,"frames"),I=h.join(a,"atlas.png"),j=h.join(a,"atlas.webp");await B("extract_strip_frames.py",["--decoded-dir",v,"--output-dir",P,"--chroma-key",g,"--key-threshold",Mt,"--method",$t]),await Rn({runDir:a,decodedDir:v,framesDir:P,generatedRows:f,chromaHex:g,generateImage:t,inspectImage:d,candidates:p,baseDataUrl:k,usage:n,upload:r.uploadReferenceImage,productionJobs:i});let D=h.join(a,"qa","contact-sheet.png");await Wt(a,P,I,j,D),k&&await Bn({runDir:a,framesDir:P,atlasPng:I,atlasWebp:j,contactSheet:D,generatedRows:f,generateImage:t,inspectImage:d,candidates:p,usage:n,upload:r.uploadReferenceImage,baseDataUrl:k}),await Ce("render_animation_previews.py",["--frames-root",P,"--output-dir",h.join(a,"qa","previews")]);let L=await y.readFile(j);return{...await ae({id:e.id,name:e.name,description:e.description,prompt:e.prompt,spritesheet:L,sourceKind:"forge"}),prompt:o.join(`
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
`),productionRun:ze(c,i),...w.length>0?{qaSkippedJobs:w}:{},model:n.model,size:n.size,durationMs:n.durationMs||void 0,...n.provider?{mediaUsage:{provider:n.provider,model:n.model??"unknown",billingUnit:n.billingUnit??"per_call",billingQuantity:n.billingQuantity||1}}:{}}}finally{await Lt(s.length?h.dirname(s[0]):void 0),Zn()||await Lt(a)}}async function Nt(e){let t=await Te(e.input,e.generateImage,{uploadReferenceImage:e.uploadReferenceImage}),r=h.join(e.outputDir,t.asset.id);await y.mkdir(r,{recursive:!0});let n=h.join(r,"pet.json"),i=h.join(r,"spritesheet.webp"),o=h.join(r,"validation.json"),c=h.join(r,"production-run.json");await y.writeFile(n,JSON.stringify(t.asset,null,2),"utf-8"),await y.writeFile(i,t.spritesheet),await y.writeFile(o,JSON.stringify(t.validation,null,2),"utf-8"),await y.writeFile(c,JSON.stringify(t.productionRun,null,2),"utf-8");let a=await se({asset:t.asset,spritesheet:t.spritesheet,validation:t.validation,productionRun:t.productionRun,outputDir:e.outputDir,fileName:`${t.asset.id}.petdex`});return{...t,packagePath:a,assetDir:r,manifestPath:n,spritesheetPath:i,validationPath:o,productionRunPath:c}}async function G(e){if(e.startsWith("data:")){let t=e.match(/^data:[^;]+;base64,(.+)$/);if(!t)throw new Error("Generated Petdex image data URL is not base64 encoded");return Buffer.from(t[1],"base64")}if(/^https?:\/\//i.test(e)){let t=await fetch(e);if(!t.ok)throw new Error(`Generated Petdex image download failed: ${t.status} ${t.statusText}`);return Buffer.from(await t.arrayBuffer())}return e.startsWith("file://")?y.readFile(new URL(e)):y.readFile(e)}async function Bt(e){await B("derive_running_left_from_running_right.py",["--run-dir",e,"--confirm-appropriate-mirror","--decision-note",In,"--force"])}async function Tt(e,t,r,n,i,o){let c=await qn(e,t,o),a=t.kind==="base-pet",s=c.filter(p=>p.role!=="layout-guide"),u=s.find(p=>p.role==="canonical-reference")??s[0],l=await n({prompt:`${r}
|
|
16
|
+
|
|
17
|
+
${Ft}`,purpose:a?"petdex-reference":"petdex-row-strip",...a?{}:{animationId:t.id},style:a?yn:xn,size:a?we:wn,imageUrl:u?.imageUrl,referenceImages:s,n:1,quality:"auto"});Se(i,l);let d=l.mediaUrls[0];if(!d)throw new Error(`Petdex generation returned no image for job ${t.id}`);return{mediaUrl:d,inputImages:s}}async function ke(e,t,r){let n=h.join(e,t.output_path);await y.mkdir(h.dirname(n),{recursive:!0}),await y.writeFile(n,await G(r))}async function Ht(e){let t=[e.prompt,...e.retryPrompt?[e.retryPrompt]:[]].slice(0,bn),r=null;for(let i of t)for(let o=0;o<e.candidates;o++){let c=await Tt(e.runDir,e.job,i,e.generateImage,e.usage,e.upload);if(!e.inspectImage)return await ke(e.runDir,e.job,c.mediaUrl),c;let a=await jn(e.inspectImage,e.job,c.mediaUrl,e.baseDataUrl);if(a.ok)return await ke(e.runDir,e.job,c.mediaUrl),a.qaSkipped?{...c,qaSkipped:!0}:c;r=c}let n=r??await Tt(e.runDir,e.job,e.prompt,e.generateImage,e.usage,e.upload);return await ke(e.runDir,e.job,n.mediaUrl),n}var Jt={idle:6,"running-right":8,"running-left":8,waving:4,jumping:5,failed:8,waiting:6,running:6,review:6};function Gt(e){let t=(e??"").trim();return/\bfail\b/i.test(t)&&!/\bpass\b/i.test(t.slice(0,8))?{ok:!1,reason:(t.match(/fail[:\s-]*(.+)/i)?.[1]??"").trim().slice(0,200)}:{ok:!0,reason:""}}async function jn(e,t,r,n){try{let i=t.kind==="base-pet"?vn:Dn(t.id,Jt[t.id]??6),o=t.kind==="base-pet"||!n?[r]:[r,n],c=await e({prompt:i,imageUrls:o});return c.trim()?Gt(c):(console.error(`[petdex-forge] vision QA returned an empty verdict for job ${t.id} (image likely not delivered to the model); accepting candidate unverified`),{ok:!0,reason:"",qaSkipped:!0})}catch(i){return console.error(`[petdex-forge] vision QA call failed for job ${t.id}: ${i instanceof Error?i.message:String(i)}; accepting candidate unverified`),{ok:!0,reason:"",qaSkipped:!0}}}var vn=["You are a strict desktop-pet sprite reviewer. The image is a single pet character reference.","Reply PASS only if ALL hold: one centered full-body cute pet; one flat solid background; no text, scenery, picture frames, borders, drop shadows, or detached effects.",'Reply with exactly "PASS" or "FAIL: <one short reason>".'].join(" ");function Dn(e,t){return[`You are a strict sprite-sheet reviewer. Image 1 is a horizontal strip of ${t} animation frames for a desktop pet's "${e}" animation. Image 2 is the canonical reference of the SAME pet.`,"Reply PASS only if ALL hold: (1) every frame is the SAME character as the reference \u2014 same species, colors, palette, face, proportions, markings; (2) one flat solid background with NO picture frames, borders, boxes, mats, panels, dividers, or copied guide lines; (3) each pose is a complete pet, fully inside its own area, not cut off or split between cells; (4) no detached effects \u2014 no drop shadows, sparkles, dust, tears, speed lines, or text.",'Reply with exactly "PASS" or "FAIL: <one short reason>".'].join(" ")}async function En(e){let t=await y.readFile(e);return`data:${e.toLowerCase().endsWith(".webp")?"image/webp":"image/png"};base64,${t.toString("base64")}`}var kn=2;async function Rn(e){let t=h.join(e.runDir,"qa","review.json"),r=()=>Ce("inspect_frames.py",["--frames-root",e.framesDir,"--json-out",t,"--chroma-adjacent-threshold",Sn]);await r();let n=await Ut(t);for(let i of e.generatedRows){let o=0;for(;n&&Xn(n,i.id)&&o<kn;)o++,await _n(e,i),await Cn(e,await Tn(e,i)),await r(),n=await Ut(t)}}async function _n(e,t){let r=await y.readFile(h.join(e.runDir,t.prompt_file),"utf-8"),i=(t.retry_prompt_file?await y.readFile(h.join(e.runDir,t.retry_prompt_file),"utf-8").catch(()=>{}):void 0)??r,{mediaUrl:o,inputImages:c}=await Ht({runDir:e.runDir,job:t,prompt:i,generateImage:e.generateImage,inspectImage:e.inspectImage,candidates:e.candidates,usage:e.usage,upload:e.upload,baseDataUrl:e.baseDataUrl}),a=e.productionJobs.find(s=>s.id===`row-${t.id}`);a&&(a.prompt=i,a.outputUrl=o,a.inputImages=c)}async function Tn(e,t){return t.id!=="running-right"?t.id:!e.inspectImage&&await Un(h.join(e.decodedDir,"running-left.png"))?(await Bt(e.runDir),"running-right,running-left"):"running-right"}async function Cn(e,t){await B("extract_strip_frames.py",["--decoded-dir",e.decodedDir,"--output-dir",e.framesDir,"--states",t,"--chroma-key",e.chromaHex,"--key-threshold",Mt,"--method",$t])}async function Un(e){return y.access(e).then(()=>!0,()=>!1)}async function Wt(e,t,r,n,i){await B("compose_atlas.py",["--frames-root",t,"--output",r,"--webp-output",n]),await B("validate_atlas.py",[r,"--json-out",h.join(e,"qa","validation.json")]),await Ce("make_contact_sheet.py",[r,"--output",i])}var Ln=4,On="one single centered full-body desktop pet pose on a flat chroma-key background",Mn=120,$n={idle:"a calm resting pose, breathing, standing still","running-right":"a mid-stride running pose facing and moving to the right","running-left":"a mid-stride running pose facing and moving to the left",waving:"raising a paw/hand/limb in a friendly wave",jumping:"a mid-air playful jump",failed:"a sad, deflated, slumped reaction pose",waiting:"an expectant waiting pose, looking up for input",running:"a focused working/thinking pose, busy but not foot-running",review:"a focused inspecting pose, leaning in to review"},Fn=400,Nn=45;async function Bn(e){let t=0;for(let r of e.generatedRows){let n=Jt[r.id]??6,i=[];for(let s=0;s<n;s++)i.push(await Hn(h.join(e.framesDir,r.id,`${String(s).padStart(2,"0")}.png`)));let o=Ct(i.map(s=>s.count).filter(s=>s>0)),c=Ct(i.map(s=>s.lum).filter(s=>s>0)),a=0;for(let s=0;s<n&&a<Ln;s++){let u=i[s],l=u.count<Math.max(Fn,o*.4),d=u.lum<Nn||c>0&&u.lum<c*.6;if(!l&&!d)continue;let p=await Gn(e,r,s,n);p&&(await Wn(await G(p),h.join(e.framesDir,r.id,`${String(s).padStart(2,"0")}.png`)),a++,t++)}}t>0&&await Wt(e.runDir,e.framesDir,e.atlasPng,e.atlasWebp,e.contactSheet)}async function Hn(e){try{let t=await _e(await y.readFile(e)),r=Math.max(1,t.width),n=Math.max(1,t.height),o=de(r,n).getContext("2d");o.drawImage(t,0,0);let c=o.getImageData(0,0,r,n).data,a=0,s=0;for(let u=0;u<c.length;u+=4)(c[u+3]??0)>40&&(a++,s+=.299*(c[u]??0)+.587*(c[u+1]??0)+.114*(c[u+2]??0));return{count:a,lum:a?s/a:0}}catch(t){return console.error(`[petdex-forge] frame analysis failed for ${e}: ${t instanceof Error?t.message:String(t)}; treating frame as ok (repair skipped)`),{count:Number.MAX_SAFE_INTEGER,lum:255}}}function Ct(e){if(e.length===0)return 0;let t=[...e].sort((n,i)=>n-i),r=Math.floor(t.length/2);return t.length%2?t[r]:(t[r-1]+t[r])/2}function Jn(e){return[`Image 1 is ONE animation frame of a desktop pet's "${e}" pose. Image 2 is the canonical reference of the SAME pet.`,"Reply PASS only if image 1 shows ONE complete pet that clearly matches the reference \u2014 same species, colors, palette, BRIGHTNESS, proportions, markings; centered and fully visible.","Reply FAIL if it is a dark or black silhouette, off-colour, dimmer/brighter than the reference, cut off, empty, a fragment, or shows two pets.",'Reply with exactly "PASS" or "FAIL: <one short reason>".'].join(" ")}async function Gn(e,t,r,n){let i=[`Create ONE single image of a desktop pet in the "${t.id}" animation, pose ${r+1} of ${n}.`,"Output exactly ONE complete, centered, full-body pose of the SAME pet as the attached reference image \u2014 identical species, colors, palette, brightness, proportions, and markings.","This is a single sprite frame: NOT a strip, NOT a grid, NOT multiple poses, NOT a dark silhouette.",`Pose: ${$n[t.id]??"a clear pose for this state"}.`].join(" "),o=null;for(let c=0;c<e.candidates;c++){let a=await e.generateImage({prompt:`${i}
|
|
18
|
+
|
|
19
|
+
${Ft}`,purpose:"petdex-reference",style:On,size:we,imageUrl:e.baseDataUrl,referenceImages:[{role:"canonical-reference",imageUrl:e.baseDataUrl}],n:1,quality:"auto"});Se(e.usage,a);let s=a.mediaUrls[0];if(s){if(o=s,!e.inspectImage)return s;try{let u=await e.inspectImage({prompt:Jn(t.id),imageUrls:[s,e.baseDataUrl]});if(!u.trim())return console.error(`[petdex-forge] frame QA returned an empty verdict for ${t.id} frame ${r+1} (image likely not delivered to the model); accepting candidate unverified`),s;if(Gt(u).ok)return s}catch(u){return console.error(`[petdex-forge] frame QA call failed for ${t.id} frame ${r+1}: ${u instanceof Error?u.message:String(u)}; accepting candidate unverified`),s}}}return o}async function Wn(e,t){let r=await _e(e),n=Math.max(1,r.width),i=Math.max(1,r.height),o=de(n,i),c=o.getContext("2d");c.drawImage(r,0,0);let a=c.getImageData(0,0,n,i),s=a.data,[u,l,d]=zn(s,n,i);for(let P=0;P<s.length;P+=4){let I=(s[P]??0)-u,j=(s[P+1]??0)-l,D=(s[P+2]??0)-d;Math.sqrt(I*I+j*j+D*D)<=Mn&&(s[P]=0,s[P+1]=0,s[P+2]=0,s[P+3]=0)}c.putImageData(a,0,0);let p=n,f=i,w=-1,g=-1;for(let P=0;P<i;P++)for(let I=0;I<n;I++)(s[(P*n+I)*4+3]??0)>16&&(I<p&&(p=I),I>w&&(w=I),P<f&&(f=P),P>g&&(g=P));let k=de(m.cellWidth,m.cellHeight),v=k.getContext("2d");if(w>=p&&g>=f){let P=w-p+1,I=g-f+1,j=m.cellWidth-10,D=m.cellHeight-10,L=Math.min(j/P,D/I,1),R=P*L,x=I*L;v.imageSmoothingEnabled=!0,v.imageSmoothingQuality="high",v.drawImage(o,p,f,P,I,(m.cellWidth-R)/2,(m.cellHeight-x)/2,R,x)}await y.mkdir(h.dirname(t),{recursive:!0}),await y.writeFile(t,Buffer.from(k.toBuffer("image/png")))}function zn(e,t,r){let n=Math.max(4,Math.floor(Math.min(t,r)*.02)),i=Math.max(1,Math.floor(t/200)),o=new Map,c=(s,u)=>{let l=(u*t+s)*4,d=e[l]??0,p=e[l+1]??0,f=e[l+2]??0;if(d+p+f<24)return;let w=d>>4<<8|p>>4<<4|f>>4,g=o.get(w)??{n:0,r:0,g:0,b:0};g.n++,g.r+=d,g.g+=p,g.b+=f,o.set(w,g)};for(let s=n;s<t-n;s+=i)c(s,n),c(s,r-1-n);for(let s=n;s<r-n;s+=i)c(n,s),c(t-1-n,s);let a=null;for(let s of o.values())(!a||s.n>a.n)&&(a=s);return!a||a.n===0?[255,0,255]:[Math.round(a.r/a.n),Math.round(a.g/a.n),Math.round(a.b/a.n)]}function Xn(e,t){let r=e.rows.find(n=>n.state===t);return r?r.ok===!1:!1}async function Ut(e){return zt(e).catch(t=>(console.error(`[petdex-forge] QA review unreadable at ${e}: ${t instanceof Error?t.message:String(t)}; skipping row repair for this pass`),null))}async function qn(e,t,r){let n=[];for(let i of t.input_images){let o=h.join(e,i.path),c=await y.readFile(o).catch(()=>null);if(!c)continue;let a=await Vn(c,h.basename(o),r);n.push({role:Kn(i.role),imageUrl:a})}return n}function Kn(e){let t=e.toLowerCase();return t.includes("layout guide")?"layout-guide":t.includes("atlas")?"existing-atlas":"canonical-reference"}async function Vn(e,t,r){let n=t.toLowerCase().endsWith(".webp")?"image/webp":"image/png";return r?r({buffer:e,mimeType:n,filename:t}):`data:${n};base64,${e.toString("base64")}`}async function Qn(e){let t=[];if(e.referenceImageUrl&&t.push(await G(e.referenceImageUrl)),e.baseSpritesheet&&t.push(e.baseSpritesheet),t.length===0)return[];let r=await y.mkdtemp(h.join(Ot.tmpdir(),"petdex-ref-")),n=[];for(let i=0;i<t.length;i++){let o=h.join(r,`reference-${String(i+1).padStart(2,"0")}.png`);await y.writeFile(o,t[i]),n.push(o)}return n}async function Yn(){let e=process.env.QLOGICAGENT_PETDEX_RUN_DIR?.trim()||Ot.tmpdir();return await y.mkdir(e,{recursive:!0}),y.mkdtemp(h.join(e,"petdex-run-"))}function Zn(){let e=process.env.QLOGICAGENT_PETDEX_KEEP_RUNS?.trim().toLowerCase();return e==="1"||e==="true"}async function Lt(e){e&&await y.rm(e,{recursive:!0,force:!0}).catch(()=>{})}async function zt(e){return JSON.parse(await y.readFile(e,"utf-8"))}async function ei(e){try{let t=await _e(await y.readFile(e)),r=Math.max(1,t.width),n=Math.max(1,t.height),o=de(r,n).getContext("2d");o.drawImage(t,0,0);let c=o.getImageData(0,0,r,n).data,a=Math.max(8,Math.floor(Math.min(r,n)*.02)),s=Math.max(1,Math.floor(r/240)),u=new Map,l=(g,k)=>{let v=(k*r+g)*4,P=c[v+3]??0,I=c[v]??0,j=c[v+1]??0,D=c[v+2]??0;if(P<200||I+j+D<48)return;let L=I>>4<<8|j>>4<<4|D>>4,R=u.get(L)??{n:0,r:0,g:0,b:0};R.n++,R.r+=I,R.g+=j,R.b+=D,u.set(L,R)};for(let g=a;g<r-a;g+=s)l(g,a),l(g,n-1-a);for(let g=a;g<n-a;g+=s)l(a,g),l(r-1-a,g);let d=null;for(let g of u.values())(!d||g.n>d.n)&&(d=g);if(!d||d.n===0)return Re;let p=Math.round(d.r/d.n),f=Math.round(d.g/d.n),w=Math.round(d.b/d.n);return`#${[p,f,w].map(g=>g.toString(16).padStart(2,"0")).join("")}`.toUpperCase()}catch{return Re}}function ti(e){return e.replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()||"petdex"}async function B(e,t){let r=await Ee(e,t,{timeoutMs:18e4});if(!r.ok)throw new Error(`Petdex pipeline step ${e} failed (exit ${r.code??"?"}): ${r.stderr.trim()||r.stdout.trim()}`)}async function Ce(e,t){try{let r=await Ee(e,t,{timeoutMs:18e4});r.ok||console.error(`[petdex-forge] soft pipeline step ${e} failed (exit ${r.code??"?"}): ${(r.stderr.trim()||r.stdout.trim()).slice(0,300)}; continuing without it`)}catch(r){console.error(`[petdex-forge] soft pipeline step ${e} failed: ${r instanceof Error?r.message:String(r)}; continuing without it`)}}async function Xt(e){return De(e)}function qt(e,t){if(!t)throw new Error("Petdex manifest validation requires spritesheet.webp bytes");return _(e,t)}export{W as PetGrowthEngine,T as PetProfileService,ne as PetSoulService,yt as catchUpJourney,ae as createPetdexAssetFromSpritesheet,Te as forgePetdexAsset,Nt as forgePetdexAssetPackage,It as listBuiltinPetdexAssetIds,At as listBuiltinPetdexAssets,Xt as loadPetFile,ft as petReactionEngine,xe as petdexImageDataUrl,G as readGeneratedPetdexImage,V as toPetdexAssetSummary,qt as validatePetManifest,se as writePetdexAssetPackage};
|