harness-wingman 0.6.0 → 0.7.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.
- package/apps/cli/dist/main.js +12852 -12048
- package/apps/panel/dist/assets/index-DARnsisU.css +1 -0
- package/apps/panel/dist/assets/index-uKsu2f4j.js +228 -0
- package/apps/panel/dist/index.html +2 -2
- package/package.json +2 -2
- package/apps/panel/dist/assets/index-CA8Z9FKi.js +0 -225
- package/apps/panel/dist/assets/index-CPB2aToL.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{color-scheme:dark;--page: #0d0d0d;--surface: #1a1a19;--pill: #050505;--ink: #ffffff;--ink2: #c3c2b7;--muted: #898781;--hairline: rgba(255, 255, 255, .1);--grid: #2c2c2a;--s1: #3987e5;--s2: #d95926;--s3: #199e70;--s4: #c98500;--s5: #d55181;--warn: #fab219;--bad: #e5534b}*{box-sizing:border-box;margin:0;padding:0}body{background:var(--page);color:var(--ink);font-family:system-ui,-apple-system,Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:28px 16px 48px}.wrap{display:flex;flex-direction:column;align-items:center}.pill{display:flex;align-items:center;gap:10px;background:var(--pill);border:1px solid var(--hairline);border-radius:999px;padding:10px 18px;cursor:pointer;-webkit-user-select:none;user-select:none;box-shadow:0 8px 30px #0000008c;transition:transform .15s ease}.pill:hover{transform:scale(1.03)}.dot{width:8px;height:8px;border-radius:50%;background:var(--s1);animation:pulse 1.6s infinite;flex:none}@keyframes pulse{0%,to{opacity:1}50%{opacity:.35}}.dot.quiet{animation:none;background:var(--muted);opacity:.6}.dot.live{background:var(--s3);box-shadow:0 0 8px #199e70cc}.pill .t1{font-size:13px;font-weight:600}.pill .t2{font-size:12px;color:var(--ink2)}.pill .tok{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}.pill .chev{color:var(--muted);font-size:11px}.dot.wait{background:var(--warn);box-shadow:0 0 8px #fab219cc;animation:pulse 1.2s infinite}.pill.waiting{border-color:#fab2198c}.pill.waiting .t2{color:var(--warn)}.panel{display:none;width:min(700px,94vw);background:var(--surface);border:1px solid var(--hairline);border-radius:20px;padding:20px 22px 16px;box-shadow:0 18px 60px #0009;transform-origin:top center}.open .panel{display:block;animation:drop .22s ease}.open .pill{display:none}.panel-region{display:contents}@keyframes drop{0%{opacity:0;transform:scale(.92) translateY(-8px)}to{opacity:1;transform:none}}.head{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}.head .title{font-size:15px;font-weight:700}.head .meta{font-size:12px;color:var(--muted)}.badge{font-size:10px;letter-spacing:.1em;color:var(--warn);border:1px solid var(--warn);border-radius:4px;padding:2px 6px}.collapse{margin-left:auto;background:none;border:1px solid var(--hairline);color:var(--ink2);border-radius:8px;padding:4px 10px;font-size:12px;cursor:pointer}.collapse:hover{border-color:var(--muted)}.tabs{display:flex;gap:4px;background:var(--pill);border:1px solid var(--hairline);border-radius:10px;padding:3px;width:max-content;margin-bottom:6px}.tab{border:none;background:none;color:var(--muted);font-size:12.5px;padding:5px 14px;border-radius:8px;cursor:pointer;font-family:inherit}.tab.act{background:var(--surface);color:var(--ink);font-weight:600;border:1px solid var(--hairline)}.tabnum{display:inline-block;margin-left:6px;min-width:16px;text-align:center;font-size:10px;color:var(--ink2);background:var(--grid);border-radius:999px;padding:0 4px;font-variant-numeric:tabular-nums}.now{background:var(--pill);border:1px solid var(--hairline);border-radius:12px;padding:10px 14px;margin:8px 0 10px}.now .ntask{font-size:14px;font-weight:700;display:flex;align-items:center;gap:8px}.now .ntask .muted{color:var(--muted);font-weight:400}.now .ndoing{font-size:12px;color:var(--ink2);margin-top:5px}.now .ndoing b{color:var(--ink);font-weight:600}.now .nquote{font-size:11.5px;color:var(--muted);margin-top:5px;line-height:1.6}.now .nwait{font-size:12px;color:var(--warn);border:1px solid rgba(250,178,25,.55);border-radius:8px;padding:5px 9px;margin-bottom:8px;animation:pulse 1.2s infinite}.taskflow{background:var(--pill);border:1px solid var(--hairline);border-radius:12px;padding:10px 14px;margin:8px 0 10px;font-size:12px;line-height:1.55}.taskflow>*+*{margin-top:8px}.wflabel{display:inline-block;margin-right:8px;color:var(--muted);font-size:10px;letter-spacing:.08em}.wfsource{color:var(--muted);font-size:10px}.wfsteps{margin-top:5px}.wfstep{display:flex;gap:7px;align-items:baseline}.wfstep.completed{color:var(--muted)}.wfstep.in_progress{font-weight:600}.wfrecent{display:flex;flex-wrap:wrap;gap:4px 8px}.wfrecent-step{color:var(--ink2)}.wfproject{display:flex;align-items:center;flex-wrap:wrap;gap:4px 6px}.wfproject-node{padding:1px 7px}.wfproject-link{border:1px solid var(--hairline);border-radius:999px;background:transparent;color:var(--ink2);cursor:pointer;font:inherit;font-size:10.5px;padding:2px 8px}.wfverify{display:flex;align-items:center;flex-wrap:wrap;gap:6px;color:var(--ink2)}.wfverify-sep{color:var(--muted)}.wfverify-action{border:1px solid var(--hairline);border-radius:999px;background:transparent;color:var(--ink2);cursor:pointer;font:inherit;font-size:10.5px;padding:2px 8px}.wfverify-error{margin-top:5px}.wffeedback.urgent{color:var(--warn)}.evidencegroup+.evidencegroup{margin-top:6px}.vtabs{display:flex;gap:22px;border-bottom:1px solid var(--grid);margin-bottom:4px}.vtab{background:none;border:none;font-family:inherit;font-size:13px;color:var(--muted);padding:8px 2px;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px}.vtab.act{color:var(--ink);font-weight:700;border-bottom-color:var(--s1)}.vtab .vcnt{font-size:11px;color:var(--muted);font-weight:400;font-variant-numeric:tabular-nums}.pane{display:none}.pane.act{display:block}.td{padding:8px 0;border-top:1px dashed var(--grid);font-size:13px}.td:first-child{border-top:none}.tdr{display:flex;align-items:center;gap:9px}.tdr[data-act]{cursor:pointer}.mk{width:16px;flex:none;text-align:center;font-size:12px;color:var(--s3)}.mk.doing{color:var(--s1)}.td .tdc{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.td.done .tdr{color:var(--muted)}.td.done .tdc{text-decoration:line-through}.td.todo .tdr{color:var(--muted)}.td .tdc b{font-weight:700}.ag{font-size:10px;color:var(--s1);border:1px solid rgba(57,135,229,.5);border-radius:999px;padding:0 8px;flex:none}.loc{margin-left:auto;flex:none;font-size:10.5px;font-family:inherit;color:var(--ink2);background:none;border:1px solid var(--grid);border-radius:7px;padding:2px 8px;cursor:pointer}.loc:hover{border-color:var(--muted)}.trace{margin:8px 0 2px 24px;border-left:2px solid var(--grid);padding-left:14px}.tr{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:12px;color:var(--ink2);cursor:pointer}.tr .ic{width:8px;height:8px;border-radius:50%;background:var(--s3);flex:none;margin-left:-19px;border:2px solid var(--surface)}.tr.bad .ic{background:var(--bad)}.tr.run .ic{background:var(--s1)}.tr .trlabel{flex:none}.tr .dur,.trs .dur{margin-left:auto;color:var(--muted);font-size:10.5px;font-variant-numeric:tabular-nums;flex:none;white-space:nowrap}.failchip{font-size:10px;color:var(--bad);border:1px solid var(--bad);border-radius:999px;padding:0 7px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.steps{margin-left:6px;padding:2px 0 4px}.trs{display:flex;align-items:center;gap:8px;padding:3px 0;font-size:11.5px;color:var(--muted)}.trs .cmd{font-family:ui-monospace,SF Mono,Menlo,Consolas,monospace;font-size:11px;color:var(--ink2);flex:none}.trs .sdetail{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trs.bad .cmd{color:var(--bad)}.rawsec .rawhead{background:none;border:none;font-family:inherit;font-size:11px;letter-spacing:.14em;color:var(--muted);padding:0;cursor:pointer}.rawsec .rawhead:hover{color:var(--ink2)}.rawsec .rawbody{display:none}.rawsec .rawbody.open{display:block;margin-top:8px}.ubox{max-height:220px;overflow-y:auto;border:1px solid var(--grid);border-radius:8px;padding:2px 10px}.urow{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:11.5px;border-top:1px dashed var(--grid);color:var(--ink2)}.urow:first-child{border-top:none}.urow .utime{color:var(--muted);font-size:10.5px;font-variant-numeric:tabular-nums;flex:none}.urow .unums{color:var(--muted);font-variant-numeric:tabular-nums;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.urow .utot{margin-left:auto;color:var(--ink);font-variant-numeric:tabular-nums;flex:none}.urow .ucost{color:var(--s3);font-variant-numeric:tabular-nums;flex:none}.sessions-empty,.session-notice{margin-top:8px;padding:7px 10px;border:1px solid var(--grid);border-radius:6px;color:var(--ink2);font-size:11px}.session-notice{display:flex;gap:8px;cursor:pointer}.session-notice-close{margin-left:auto;color:var(--ink3)}.schips{display:flex;flex-wrap:wrap;gap:6px;padding:8px 0 2px}.schip{display:inline-flex;align-items:center;gap:5px;background:none;border:1px solid var(--grid);border-radius:999px;padding:2px 10px;font-family:inherit;font-size:11px;color:var(--ink2);cursor:pointer}.schip:hover{border-color:var(--ink2)}.schip.act{color:var(--ink);border-color:var(--ink2);font-weight:600}.schip.ended{opacity:.55}.schip .sdot{width:6px;height:6px;border-radius:50%;background:var(--s1);flex:none}.schip .sdot.wait{background:var(--warn);animation:pulse 1.2s infinite}.schip .snew{padding:0 5px;border:1px solid var(--s1);border-radius:999px;color:var(--s1);font-size:9px;font-weight:700}.feedbacksignal{margin:8px 0 2px;border:1px solid rgba(250,178,25,.4);border-radius:8px;padding:5px 9px;color:var(--warn);font-size:12px}.suggslot:empty{display:none}.suggslot{border-top:1px solid var(--grid);padding:8px 0 2px}.sugg{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:12px;color:var(--ink2)}.sugg .sugtext{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sugg.r-waiting-timeout .sugtext{color:var(--warn)}.sugg .sugbtn,.sugg .sugdismiss{background:none;border:1px solid var(--grid);border-radius:6px;padding:1px 8px;font-family:inherit;font-size:11px;color:var(--ink2);cursor:pointer;flex:none}.sugg .sugbtn{color:var(--ink);border-color:var(--ink2);margin-left:auto}.sugg .sugbtn:hover{background:var(--grid)}.sugg .sugdismiss{color:var(--muted)}.sugg .sugbtn+.sugdismiss{margin-left:0}.sugg .sugdismiss:only-of-type{margin-left:auto}.sugg .sugdismiss:hover{color:var(--ink2)}.tr.waitrow{cursor:default}.tr.waitrow .trlabel{color:var(--warn)}.sec{border-top:1px solid var(--grid);padding:13px 0}.sec.first{border-top:none;padding-top:2px}.sec .label{font-size:11px;letter-spacing:.14em;color:var(--muted);margin-bottom:8px;display:flex;align-items:center;gap:8px}.tier{font-size:10px;letter-spacing:0;color:var(--ink2);border:1px solid var(--grid);border-radius:999px;padding:1px 8px;font-weight:400}.sec .headline{font-size:13px;color:var(--ink2);margin-bottom:10px}.sec .headline b{color:var(--ink);font-weight:700}.stack{display:flex;height:16px;margin-bottom:10px}.seg{margin-right:2px;cursor:default}.seg:last-child{margin-right:0}.seg:first-child{border-radius:4px 0 0 4px}.seg:last-child{border-radius:0 4px 4px 0}.seg:hover{filter:brightness(1.18)}.legend{display:grid;grid-template-columns:1fr 1fr;gap:5px 18px}@media(max-width:560px){.legend{grid-template-columns:1fr}}.lrow{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink2);min-width:0}.sw{width:10px;height:10px;border-radius:3px;flex:none}.lrow .nat,.gtitle .nat{font-size:10.5px;color:var(--muted);border:1px solid var(--grid);border-radius:4px;padding:0 5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.lrow .v{margin-left:auto;color:var(--ink);font-variant-numeric:tabular-nums;flex:none}.lrow .cnt{color:var(--muted);font-size:10.5px;flex:none}.lrow.na,.lrow.na .v{color:var(--muted)}.grp{margin-bottom:10px}.grp:last-child{margin-bottom:0}.gtitle{font-size:11.5px;color:var(--muted);margin-bottom:4px;display:flex;align-items:center;gap:7px}.gdot{width:8px;height:8px;border-radius:2px;flex:none}.crow{display:flex;align-items:center;gap:10px;padding:6px 0;font-size:12.5px;border-top:1px dashed var(--grid)}.cname{color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.offrow .cname{color:var(--muted)}.chip{font-size:10px;color:var(--muted);border:1px solid var(--grid);border-radius:999px;padding:1px 7px;flex:none}.statechip{font-size:10px;border-radius:999px;padding:1px 7px;flex:none}.statechip.off{color:var(--warn);border:1px solid var(--warn)}.statechip.nofile{color:var(--muted);border:1px dashed var(--grid)}.ctok{margin-left:auto;color:var(--muted);font-size:11.5px;font-variant-numeric:tabular-nums;flex:none}.crow.emptyrow{color:var(--muted);font-size:12px}.livenone{font-size:12.5px;color:var(--muted);border:1px dashed var(--grid);border-radius:8px;padding:10px 12px;margin-bottom:8px;line-height:1.7}.livenone:last-child{margin-bottom:0}.livenone code{color:var(--ink2);background:var(--pill);border:1px solid var(--grid);border-radius:4px;padding:1px 5px}.tier.none{color:var(--muted);border-style:dashed}.conn{font-size:10px;letter-spacing:0;font-weight:400;border-radius:999px;padding:1px 8px;border:1px solid var(--grid);color:var(--muted)}.conn.open{color:var(--s3);border-color:var(--s3)}.conn.retrying{color:var(--warn);border-color:var(--warn)}.conn.replay{color:var(--warn);border-style:dashed}.demobtn{margin-left:auto;background:none;border:1px dashed var(--warn);color:var(--warn);border-radius:6px;padding:2px 8px;font-size:10.5px;letter-spacing:0;cursor:pointer;font-family:inherit}.demobtn:hover:not(:disabled){border-style:solid}.demobtn:disabled{opacity:.5;cursor:default}.feed{max-height:240px;overflow-y:auto;border:1px solid var(--grid);border-radius:8px;padding:2px 10px}.lvrow{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:12px;border-top:1px dashed var(--grid)}.lvrow:first-child{border-top:none}.lvtime{color:var(--muted);font-size:11px;font-variant-numeric:tabular-nums;flex:none}.lvname{color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.lvrow.own .lvname{font-weight:600}.lvrow.other{opacity:.45}.lvharness{margin-left:auto;font-size:10px;color:var(--muted);border:1px solid var(--grid);border-radius:4px;padding:0 5px;flex:none}.lvrow.own .lvharness{color:var(--ink2);border-color:var(--hairline)}.mockchip{font-size:9px;letter-spacing:.08em;color:var(--warn);border:1px solid var(--warn);border-radius:4px;padding:0 4px;flex:none}.labr{margin-left:auto;display:flex;align-items:center;gap:8px}.sharelink{background:none;border:1px solid var(--grid);color:var(--muted);border-radius:6px;padding:2px 8px;font-size:10.5px;letter-spacing:0;cursor:pointer;font-family:inherit}.sharelink:hover{color:var(--ink2);border-color:var(--muted)}.sharebox{max-height:320px;overflow:auto;border:1px solid var(--grid);border-radius:8px;background:var(--pill);padding:6px 8px;font-family:ui-monospace,SF Mono,Menlo,Consolas,monospace;font-size:11px;line-height:1.5}.shline{display:flex;gap:7px;align-items:flex-start;padding:1px 0}.shdel{flex:none;background:none;border:1px solid var(--grid);color:var(--muted);border-radius:4px;font-size:9px;line-height:1.3;padding:0 4px;margin-top:1px;cursor:pointer}.shdel:hover{color:var(--s2);border-color:var(--s2)}.shtext{color:var(--ink2);white-space:pre-wrap;word-break:break-all}.btn:disabled{opacity:.45;cursor:default}.btn:disabled:hover{filter:none}.empty-state{display:flex;flex-direction:column;align-items:center}.empty-card{width:min(460px,94vw);background:var(--surface);border:1px solid var(--hairline);border-radius:16px;padding:28px 26px;text-align:center}.empty-title{font-size:15px;font-weight:700;margin-bottom:8px}.empty-detail{font-size:12px;color:var(--warn);margin-bottom:8px;word-break:break-all}.empty-hint{font-size:12.5px;color:var(--muted);line-height:1.7}.empty-hint code{color:var(--ink2);background:var(--pill);border:1px solid var(--grid);border-radius:4px;padding:1px 5px}#tip{position:fixed;display:none;pointer-events:none;z-index:9;background:#050505;border:1px solid var(--hairline);border-radius:8px;padding:6px 10px;font-size:12px;color:var(--ink);max-width:300px;box-shadow:0 8px 24px #00000080;white-space:pre-line;line-height:1.5}.toggle{width:30px;height:17px;border-radius:999px;background:var(--grid);position:relative;cursor:pointer;flex:none;transition:background .15s;border:none;padding:0}.toggle:after{content:"";position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:var(--ink2);transition:left .15s}.toggle.on{background:var(--s1)}.toggle.on:after{left:15px;background:#fff}.cright{display:flex;align-items:center;gap:8px;flex:none}.cfgnote{font-size:11px;color:var(--muted);padding:5px 0 2px;border-top:1px dashed var(--grid);line-height:1.6}.licbar{display:block;width:100%;text-align:left;font-size:12px;font-family:inherit;color:var(--warn);background:none;border:1px solid var(--warn);border-radius:8px;padding:6px 10px;margin-bottom:10px;cursor:pointer}.licbar.expired{color:var(--s2);border-color:var(--s2)}.licbar:hover{filter:brightness(1.12)}.licrow{display:flex;align-items:stretch;gap:8px;margin-bottom:10px}.licrow .licbar{flex:1;margin-bottom:0}.licimport{flex:none;font-size:11px;font-family:inherit;color:var(--muted);background:none;border:1px solid var(--grid);border-radius:8px;padding:6px 10px;cursor:pointer}.licimport:hover{color:var(--ink2);border-color:var(--muted)}.licfoot{margin-top:12px;text-align:center}.licfootlink{font-size:11px;font-family:inherit;color:var(--muted);background:none;border:none;padding:2px 4px;cursor:pointer;text-decoration:underline;text-decoration-color:var(--grid);text-underline-offset:3px}.licfootlink:hover{color:var(--ink2)}.feedbackfoot{display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap;padding:0 18px 16px;color:var(--muted);font-size:10.5px;line-height:1.45;text-align:center}.feedbackfoot a{color:var(--ink2);text-underline-offset:2px}.feedbackfoot a:hover{color:var(--ink)}.feedbacklink{font-weight:650}.lictrial{margin:-2px 0 8px;text-align:right}.lictrial .licfootlink{text-decoration:none}#drop{position:fixed;inset:0;z-index:40;display:none;align-items:center;justify-content:center;background:#000000a6;border:2px dashed var(--s1);color:var(--ink);font-size:15px;pointer-events:none}.overlay{position:fixed;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;padding:20px}.scrim{position:absolute;inset:0;background:#0009}.modal{position:relative;width:min(560px,94vw);max-height:86vh;overflow-y:auto;background:var(--surface);border:1px solid var(--hairline);border-radius:16px;padding:16px 18px;box-shadow:0 18px 60px #0009;animation:drop .18s ease}.mhead{display:flex;align-items:center;gap:8px;margin-bottom:10px}.mtitle{font-size:14px;font-weight:700}.mclose{margin-left:auto;background:none;border:1px solid var(--hairline);color:var(--ink2);border-radius:8px;padding:2px 8px;font-size:12px;cursor:pointer}.mclose:hover{border-color:var(--muted)}.mnote{font-size:11px;color:var(--warn);border:1px dashed var(--warn);border-radius:8px;padding:8px 10px;margin-bottom:10px;line-height:1.6}.msec{border-top:1px solid var(--grid);padding:10px 0}.mlabel{font-size:11px;letter-spacing:.1em;color:var(--muted);margin-bottom:6px}.mtext{font-size:12.5px;color:var(--ink2);line-height:1.7;word-break:break-all}.mtext.muted{color:var(--muted)}.mtext code,.mpath{color:var(--ink2);background:var(--pill);border:1px solid var(--grid);border-radius:4px;padding:1px 5px;font-size:11px;word-break:break-all}.mfile{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:12px;flex-wrap:wrap}.mkind{font-size:10px;border-radius:4px;padding:1px 6px;flex:none;border:1px solid var(--grid);color:var(--ink2)}.mkind.create{color:var(--s3);border-color:var(--s3)}.mkind.modify{color:var(--s4);border-color:var(--s4)}.mkind.delete{color:var(--s2);border-color:var(--s2)}.mlines{margin-left:auto;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums;flex:none}.mref{display:flex;gap:8px;padding:4px 0;font-size:12px;align-items:baseline;flex-wrap:wrap}.mctx{color:var(--muted);font-size:11.5px;line-height:1.5}.merror{font-size:12px;color:var(--warn);border:1px solid var(--warn);border-radius:8px;padding:8px 10px;margin-bottom:8px;white-space:pre-wrap;word-break:break-all}.mact{display:flex;gap:8px;justify-content:flex-end;margin-top:12px}.btn{border-radius:8px;padding:6px 14px;font-size:12.5px;cursor:pointer;font-family:inherit}.btn.ghost{background:none;border:1px solid var(--hairline);color:var(--ink2)}.btn.ghost:hover{border-color:var(--muted)}.btn.primary{background:var(--s1);border:1px solid var(--s1);color:#fff;font-weight:600}.btn.primary:hover{filter:brightness(1.1)}.projects{display:grid;gap:12px;padding:12px 14px 16px}.projects-empty,.project-empty{color:var(--muted);font-size:12px;padding:8px 0}.project-card{border:1px solid var(--hairline);border-radius:12px;padding:12px;background:var(--surface)}.project-card.unavailable,.project-last-good{background:color-mix(in srgb,var(--surface) 88%,var(--grid))}.project-card-head{display:flex;justify-content:space-between;gap:12px;align-items:baseline}.project-title{font-size:15px;font-weight:700}.project-source{margin-left:7px;color:var(--muted);font-size:10.5px}.project-presence{color:var(--muted);font-size:11px;margin-top:4px}.project-memory-warning,.anatomy-refresh-warning{color:var(--warn);font-size:11px}.project-memory-warning{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.project-memory-warning button{color:inherit;background:transparent;border:0;cursor:pointer}.project-root,.project-meta,.project-counts,.project-facts{color:var(--muted);font-size:11px;overflow-wrap:anywhere}.project-meta{margin-top:4px}.project-protocols{display:grid;gap:6px;margin-top:8px}.project-protocol-row{display:flex;align-items:center;flex-wrap:wrap;gap:5px}.project-protocol-chip,.project-protocol-copy{border:1px solid var(--hairline);border-radius:999px;color:var(--ink2);font-family:inherit;font-size:10.5px;padding:2px 7px}.project-protocol-chip.plan_present,.project-protocol-chip.session_wrote_plan{border-color:var(--s3);color:var(--s3)}.project-protocol-chip.installed_not_loaded{border-color:var(--warn);color:var(--warn)}.project-protocol-note{color:var(--muted);font-size:10px;overflow-wrap:anywhere}.project-protocol-copy{background:transparent;cursor:pointer;padding-inline:6px}.project-protocol-copy:hover{border-color:var(--s1)}.project-goal,.project-section,.project-counts,.project-facts,.project-complete,.project-l0,.project-error,.project-last-good{margin-top:10px}.project-label{color:var(--ink2);font-size:11px;font-weight:650;margin-right:8px}.project-l0,.project-error{border:1px solid var(--hairline);border-radius:8px;padding:8px 10px;font-size:12px}.project-error{color:var(--warn);border-color:var(--warn)}.project-complete{color:var(--s3);font-size:12px;font-weight:650}.project-points{display:flex;flex-wrap:wrap;gap:6px;margin-top:5px}.project-checkpoints{margin-top:5px}.project-checkpoint{font-size:12px;font-weight:400}.project-crumb{border:1px solid var(--hairline);border-radius:999px;background:transparent;color:var(--ink2);cursor:pointer;font-family:inherit;font-size:11px;padding:3px 8px}.project-crumb:hover{border-color:var(--s1)}.project-node-text,.project-crumb,.project-checkpoint{display:-webkit-box;min-width:0;max-width:100%;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;overflow-wrap:anywhere}.project-node-text{flex:1}.project-facts-group+.project-facts-group{margin-top:4px}.project-facts-toggle{border:0;background:transparent;color:inherit;cursor:pointer;font:inherit;padding:0;text-align:left}.project-facts-items{display:grid;gap:3px;margin:4px 0 0 14px}.task-filters{display:grid;gap:7px;padding:12px 14px 0}.task-filter-group{display:flex;align-items:center;flex-wrap:wrap;gap:5px;color:var(--muted);font-size:10.5px}.task-filter-chip,.task-badge,.task-status{border:1px solid var(--hairline);border-radius:999px;background:transparent;color:var(--ink2);font-family:inherit;font-size:10.5px;padding:2px 7px}.task-filter-chip{cursor:pointer}.task-filter-chip:hover,.task-filter-chip.act{border-color:var(--s1);color:var(--s1)}.task-filter-summary,.task-hidden{color:var(--muted);font-size:11px}.task-filter-summary{padding:7px 14px 0}.task-hidden{margin:5px 0 0 19px}.task-card-list{display:grid;grid-template-columns:minmax(0,1fr);gap:7px;margin-top:6px}.task-card{display:block;width:100%;border:1px solid var(--hairline);border-radius:10px;background:color-mix(in srgb,var(--surface) 94%,var(--grid));color:var(--ink);cursor:pointer;font-family:inherit;padding:9px 38px 9px 10px;text-align:left}.task-card:hover{border-color:var(--s1)}.task-card-head,.task-card-meta{display:flex;align-items:center;flex-wrap:wrap;gap:6px}.task-card-meta{margin-top:7px}.task-title{font-size:12px;font-weight:650;overflow-wrap:anywhere}.task-title-source,.task-progress,.task-activity,.task-context,.task-feedback,.task-checks,.task-accept{color:var(--muted);font-size:10.5px}.task-title-source:before{content:"来源:"}.task-status.waiting{border-color:var(--warn);color:var(--warn)}.task-status.active,.task-status.complete{border-color:var(--s3);color:var(--s3)}.task-status.ended{color:var(--muted)}.task-feedback,.task-context{display:block;margin-top:6px}.task-feedback{color:var(--warn)}.task-card-wrap{position:relative}.task-menu-button{position:absolute;top:6px;right:7px;width:28px;height:26px;border:1px solid transparent;border-radius:7px;background:transparent;color:var(--muted);cursor:pointer;font:700 17px / 1 inherit}.task-menu-button:hover,.task-menu-button[aria-expanded=true]{border-color:var(--hairline);color:var(--ink)}.task-menu{display:grid;gap:7px;max-width:100%;margin-top:5px;padding:8px;border:1px solid var(--hairline);border-radius:9px;background:color-mix(in srgb,var(--surface) 92%,var(--grid))}.task-menu label{display:grid;grid-template-columns:auto minmax(0,1fr);gap:7px;align-items:center;color:var(--muted);font-size:10.5px}.task-menu input{min-width:0;border:1px solid var(--hairline);border-radius:6px;background:var(--surface);color:var(--ink);font:inherit;padding:5px 7px}.task-menu-actions{display:flex;flex-wrap:wrap;gap:6px}.return-target-option,.return-settings-dismiss,.task-menu-actions button,.task-resume-command button,.task-unhide,.task-hidden-toggle{border:1px solid var(--hairline);border-radius:999px;background:transparent;color:var(--ink2);cursor:pointer;font:inherit;font-size:10.5px;padding:3px 8px}.task-resume-command{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:center}.task-resume-command code{min-width:0;overflow-wrap:anywhere;white-space:pre-wrap}.task-return-result,.task-resume-note,.task-resume-unavailable,.task-error{grid-column:1 / -1;color:var(--muted);font-size:10.5px;overflow-wrap:anywhere}.task-error{margin-top:5px;color:var(--warn)}.task-pin-mark{color:var(--s1);font-size:10px;font-weight:700}.task-hidden-group{margin-top:6px}.task-hidden-toggle{color:var(--muted)}.task-card-hidden{opacity:.58}.task-unhide{margin-top:5px}@media(max-width:560px){.task-menu label{grid-template-columns:1fr}}.project-tree,.project-tree ul,.project-session-plan ul{list-style:none;margin:5px 0 0;padding-left:17px}.project-tree{padding-left:0}.project-node{margin:4px 0;font-size:12px}.project-node-line{display:flex;gap:7px;align-items:baseline}.project-node.in_progress>.project-node-line{color:var(--s3)}.project-node.completed,.project-node.cancelled,.project-node.collapsed{color:var(--muted)}.project-mark{width:12px;flex:none;text-align:center}.project-verify{color:var(--muted);font-size:11px;margin:3px 0 0 19px}.project-session-wrap,.task-card-wrap{margin:5px 0 6px 19px}.project-session-plan{border-left:1px solid var(--hairline);margin:5px 0 0 8px;padding-left:8px;font-size:11px}.project-session-plan .project-source{margin-left:0}.project-last-good{opacity:.72;border-radius:8px;padding:8px}html.island,html.island body{background:transparent}html.island body{padding:8px 0 12px;overflow:hidden}html.island .open .panel{height:calc(100vh - 20px);overflow-y:auto}html.island .scrim{border-radius:20px}.return-target-options{display:flex;flex-wrap:wrap;gap:6px}.return-target-option.act{color:var(--s1);border-color:var(--s1);background:var(--surface)}.return-target-option:hover,.return-settings-dismiss:hover{color:var(--ink)}.return-target-option:focus-visible,.return-settings-dismiss:focus-visible{outline:2px solid var(--s1);outline-offset:2px}.return-target-option:disabled{opacity:.6;cursor:default}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))s(a);new MutationObserver(a=>{for(const i of a)if(i.type==="childList")for(const c of i.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&s(c)}).observe(document,{childList:!0,subtree:!0});function n(a){const i={};return a.integrity&&(i.integrity=a.integrity),a.referrerPolicy&&(i.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?i.credentials="include":a.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function s(a){if(a.ep)return;a.ep=!0;const i=n(a);fetch(a.href,i)}})();const Y=["base","rules","skills","tools","gates","history"],B={base:"基础指令",rules:"你的规则",skills:"技能包",tools:"工具定义",gates:"闸门 hooks",history:"对话历史"},le={base:"#3987e5",rules:"#d95926",skills:"#199e70",tools:"#c98500",gates:"#898781",history:"#d55181"},j={cc:"Claude Code",codex:"Codex",dsh:"dsh"},Re={cc:{base:"内置 system prompt",rules:"CLAUDE.md · rules/*.md",skills:"Skills · SKILL.md",tools:"MCP servers",gates:"hooks · permissions",history:"projects/*.jsonl"},codex:{base:"内置 instructions",rules:"AGENTS.md · config.toml",skills:"plugins",tools:"mcp_servers",gates:"approval_policy · hooks",history:"history.jsonl"},dsh:{base:"core 插件(一切皆插件)",rules:"profile · patch",skills:"skill 插件",tools:"tool-* 插件",gates:"approval · permission 插件",history:"session log 插件"}};function T(e){return e<1e3?String(e):`${(Math.round(e/100)/10).toFixed(1)}k`}function D(e){if(!e)return"—";const t=T(e.value);return e.kind==="estimate"?`约 ${t}`:t}function Gt(e){return e.onTriggerTokens?`常驻 ${D(e.tokens)} · 触发后 ${D(e.onTriggerTokens)}`:D(e.tokens)}function et(e){let t=0,n=!1,s="exact";for(const a of e)!a.enabled||!a.tokens||(t+=a.tokens.value,n=!0,a.tokens.kind==="estimate"&&(s="estimate"));return n?{kind:s,value:t}:void 0}function tt(e){let t=0,n=!1,s="exact";for(const a of Y){const i=et(e.slots[a]??[]);i&&(t+=i.value,n=!0,i.kind==="estimate"&&(s="estimate"))}return n?{kind:s,value:t}:void 0}function Jt(e){return e==="full"?"完整 · 插件 API":e==="push"?"推送 · hooks":"未接线"}function Qt(e){return`${e.slice(0,16).replace("T"," ")} UTC`}function nt(e){const t=[];return t.push(e.nativePath?`文件:${e.nativePath}`:`无文件实体(source: ${e.source})`),e.__source_note&&t.push(e.__source_note),(e.tokens?.kind==="estimate"||e.onTriggerTokens?.kind==="estimate")&&t.push("估算 = 字节 ÷ 3.5,故标「约」"),e.tokens?.kind==="exact"&&t.push(`精确值(harness 自报 usage):${e.tokens.value.toLocaleString("en-US")} tokens`),t.join(`
|
|
2
|
+
`)}function Xt(e){const t=[],n=[];for(const s of Y){const a=(e.slots[s]??[]).filter(i=>i.toggleable);a.length>0?t.push({slot:s,items:a}):n.push(s)}return{groups:t,slotsWithoutToggle:n}}function Yt(e){return e.tokens?e.enabled?`关掉可省 ${D(e.tokens)}`:`开启将 +${D(e.tokens)}`:""}function ae(e){return e===""?0:e.split(`
|
|
3
|
+
`).length-(e.endsWith(`
|
|
4
|
+
`)?1:0)}function zt(e){return e==="create"?"新建":e==="delete"?"删除":"修改"}function Zt(e){return e.kind==="create"?`${ae(e.after??"")} 行`:e.kind==="delete"?`原 ${ae(e.before??"")} 行`:`${ae(e.before??"")} 行 → ${ae(e.after??"")} 行`}function en(e){return e==="immediate"?"立即生效 —— 该机制被 harness 实时监听,当前 session 也会更新":e==="reconnect"?"重连后生效 —— 需重启该 harness(或重连其 MCP server)才加载":"下个 session 生效 —— 正在进行的对话不受影响,新开会话才加载新配置"}function st(e,t){return`${t?"打开":"关闭"} ${e}`}function tn(e){const t=e.action.itemId.split(":");return t.length>=4?t.slice(3).join(":"):e.action.itemId}const nn=["cc","codex","dsh"],sn=["immediate","next_session","reconnect"],an=["create","modify","delete"];function b(e){throw new Error(`plan 载荷不合合同,拒绝渲染:${e}`)}function on(e,t){(typeof e!="object"||e===null)&&b(`writes[${t}] 不是对象`);const n=e;(typeof n.file!="string"||n.file==="")&&b(`writes[${t}].file 不是非空字符串`),an.includes(n.kind)||b(`writes[${t}].kind 未知值 ${JSON.stringify(n.kind)}`),n.kind!=="create"&&typeof n.before!="string"&&b(`writes[${t}].before 缺失(kind=${String(n.kind)} 必须携带变更前完整内容)`),n.kind!=="delete"&&typeof n.after!="string"&&b(`writes[${t}].after 缺失(kind=${String(n.kind)} 必须携带变更后完整内容)`)}function rn(e,t){(typeof e!="object"||e===null)&&b(`references[${t}] 不是对象`);const n=e;(typeof n.file!="string"||n.file==="")&&b(`references[${t}].file 不是非空字符串`),(typeof n.line!="number"||!Number.isInteger(n.line)||n.line<1)&&b(`references[${t}].line 不是 1-based 行号`),typeof n.matchedName!="string"&&b(`references[${t}].matchedName 不是字符串`),typeof n.context!="string"&&b(`references[${t}].context 不是字符串`)}function at(e){(typeof e!="object"||e===null)&&b("不是对象");const t=e;nn.includes(t.harness)||b(`harness 未知值 ${JSON.stringify(t.harness)}`),(typeof t.action!="object"||t.action===null)&&b("action 不是对象");const n=t.action;return n.kind!=="toggle"&&b(`action.kind 未知值 ${JSON.stringify(n.kind)}(v1 仅 toggle 走 plan)`),(typeof n.itemId!="string"||n.itemId==="")&&b("action.itemId 不是非空字符串"),typeof n.enable!="boolean"&&b("action.enable 不是布尔值"),Array.isArray(t.writes)||b("writes 不是数组"),t.writes.forEach(on),(typeof t.backupDir!="string"||t.backupDir==="")&&b("backupDir 不是非空字符串"),Array.isArray(t.references)||b("references 不是数组"),t.references.forEach(rn),sn.includes(t.effectiveAt)||b(`effectiveAt 未知值 ${JSON.stringify(t.effectiveAt)}`),e}function cn(e){if(typeof e!="object"||e===null)throw new Error("apply 响应不合合同:不是对象");const t=e;if(t.ok===!0){if(typeof t.backupDir!="string"||t.backupDir==="")throw new Error("apply 响应不合合同:ok=true 但缺 backupDir");return{ok:!0,backupDir:t.backupDir}}if(t.ok===!1){if(typeof t.error!="string"||t.error==="")throw new Error("apply 响应不合合同:ok=false 但缺 error 原文");return{ok:!1,error:t.error}}throw new Error("apply 响应不合合同:ok 不是布尔值")}function ln(e,t){return t.includes("fixtures 模式只读")?{phase:"demo",title:e}:{phase:"error",title:e,message:t}}function dn(e){return e===null?!1:e.sessions.some(t=>t.waiting)?!0:Object.values(e.states).some(t=>t.taskWorkflow?.feedback.state==="needs_user")}function un(e,t,n,s=1e4){return setInterval(()=>{dn(e())&&(t(),n())},s)}function pn(e){return new URLSearchParams(e).get("island")==="1"}function fn(e,t,n=null,s=null){const a=e?"#island=open":`#island=pill:${vn(t??{x:0,y:0,w:0,h:0})}`,i=n?`;focus:${n.target},${n.seq}`:"",c=s?`;waiting:${Math.round(s.sinceMs)},${encodeURIComponent(s.message)}`:"";return`${a}${i}${c}`}function vn(e){return`${Math.round(e.x)},${Math.round(e.y)},${Math.round(e.w)},${Math.round(e.h)}`}function mn(e){return e.island&&e.open&&!e.inPanel&&!e.modalOpen}const it="https://billing.stripe.com/p/login/14AcMZ8Z147F4MmaTKcMM00",$n="https://buy.stripe.com/6oUbIV5MPbA792C8LCcMM04",gn=["none","invalid","active","grace","expired"];function Me(e){if(typeof e!="object"||e===null)return null;const t=e;return!gn.includes(t.state)||typeof t.detail!="string"||t.plan!==void 0&&t.plan!=="trial"&&t.plan!=="subscription"||t.exp!==void 0&&typeof t.exp!="string"?null:{state:t.state,detail:t.detail,...t.plan===void 0?{}:{plan:t.plan},...t.exp===void 0?{}:{exp:t.exp}}}function ot(e){if(e?.plan==="trial"){if(e.state==="active")return"trial-active";if(e.state==="expired")return"trial-expired"}return e&&(e.state==="grace"||e.state==="expired")?e.state:null}function hn(e){return e?`license 已导入 —— ${e.detail}`:"license 已导入(新状态未知,刷新本页查看)"}function bn(e){if(e.length!==1)return`一次拖入 1 个 license.json 文件(收到 ${e.length} 个)`;const t=e[0]??"";return t.toLowerCase().endsWith(".json")?null:`只认 .json 文件(收到 ${t})`}const yn=50,kn=15e3,wn={SessionStart:"会话开始",SessionEnd:"会话结束",UserPromptSubmit:"提交提示",PreToolUse:"工具调用开始",PostToolUse:"工具调用完成",PostToolBatch:"工具批次完成",Stop:"回合结束",SubagentStart:"子代理启动",SubagentStop:"子代理结束",PreCompact:"压缩开始",PostCompact:"压缩完成",ConfigChange:"配置变更",InstructionsLoaded:"指令加载",Notification:"通知",PermissionRequest:"权限请求"};function rt(e){return wn[e]??e}function Tn(e,t,n=yn){if(t.sseId!==void 0&&e.some(a=>a.sseId===t.sseId))return[...e];const s=[...e,t];return s.length>n?s.slice(s.length-n):s}function ct(e){return e.slice(11,19)}function Sn(e){const t={cc:0,codex:0,dsh:0};for(const{event:n}of e)t[n.harness]+=1;return t}function jn(e,t){const n=[];for(const{event:s}of e){if(s.harness!==t)continue;const{hook_event_name:a,session_id:i,tool_name:c}=s.payload,l=typeof i=="string"?i:"";if(a==="PreToolUse"&&typeof c=="string")n.push({session:l,tool:c});else if(a==="PostToolUse"&&typeof c=="string")for(let d=n.length-1;d>=0;d--){const u=n[d];if(u&&u.session===l&&u.tool===c){n.splice(d,1);break}}else if(a==="Stop"||a==="SessionEnd")for(let d=n.length-1;d>=0;d--)n[d]?.session===l&&n.splice(d,1)}return n[n.length-1]?.tool}function lt(e,t,n,s){const a=e.filter(d=>d.event.harness===t),i=a[a.length-1];if(!i)return{active:!1,label:n==="none"?"未接线":"等待事件"};const c=Date.parse(i.event.received_at);if(!Number.isFinite(c)||s-c>kn)return{active:!1,label:"静默"};const l=jn(e,t);return{active:!0,label:l?`${l} 运行中`:rt(i.event.payload.hook_event_name)}}function En(e){return e.replaying?"演示重放中 · MOCK":e.connection==="open"?"实况已连接":e.connection==="retrying"?"连接断开 · 自动重连中":"连接中…"}function _n(e){return m(e)&&(e.activated===!0&&x(e,["activated","name"])&&typeof e.name=="string"&&e.name!==""||e.activated===!1&&x(e,["activated","reason"])&&typeof e.reason=="string"&&e.reason!=="")?e:null}function An(e){return!m(e)||!x(e,["available","selected","settings"])||!Array.isArray(e.available)||!e.available.every(t=>m(t)&&x(t,["name","bundlePath"])&&typeof t.name=="string"&&t.name!==""&&typeof t.bundlePath=="string"&&t.bundlePath!=="")||e.selected!==void 0&&!dt(e.selected)||e.settings!==void 0&&(!ut(e.settings)||e.settings.unavailable==="")?null:e}function xn(e){return!m(e)||!x(e,["selected"])||!dt(e.selected)?null:e}function dt(e){return m(e)&&x(e,["bundlePath"])&&typeof e.bundlePath=="string"&&e.bundlePath!==""}function Pn(e){if(typeof e!="object"||e===null)return null;const t=e;return typeof t.harness!="string"||!Array.isArray(t.todos)||!Array.isArray(t.traces)||!Array.isArray(t.turnUsages)||typeof t.updatedAt!="string"||t.taskWorkflow!==void 0&&!zn(t.taskWorkflow)||t.project!==void 0&&!Qn(t.project)?null:e}function On(e){if(!m(e)||!Array.isArray(e.projects)||e.memory!==void 0&&!ut(e.memory))return null;const t=e.projects.map((n,s)=>Mn(n)?n:Rn(n,s));return e.memory===void 0?{projects:t}:{projects:t,memory:e.memory}}function ut(e){return m(e)&&x(e,["unavailable"])&&typeof e.unavailable=="string"}function Ln(e){if(typeof e!="object"||e===null)return null;const t=e;if(typeof t.harness!="string"||typeof t.startedAt!="string"||!Array.isArray(t.notices)||!t.notices.every(Cn)||!Array.isArray(t.sessions))return null;const n=[];for(const i of t.sessions){if(typeof i!="object"||i===null)return null;const c=i;if(typeof c.id!="string"||typeof c.label!="string"||c.cwd!==void 0&&typeof c.cwd!="string"||typeof c.lastActivity!="string"||typeof c.waiting!="boolean"||typeof c.ended!="boolean")return null;if(c.feedback!==void 0&&c.feedback!=="available"&&c.feedback!=="not_wired"&&c.feedback!=="unavailable"){n.push({id:c.id,label:c.label,lastActivity:c.lastActivity,waiting:c.waiting,ended:c.ended});continue}n.push(i)}if(typeof t.states!="object"||t.states===null||Array.isArray(t.states))return null;const s=t.states,a={};for(const i of n)a[i.id]=Pn(s[i.id])??Yn(t.harness,i);return{harness:t.harness,startedAt:t.startedAt,notices:t.notices,sessions:n,states:a}}function Cn(e){return m(e)?e.kind==="evicted"?Object.keys(e).length===5&&typeof e.sessionId=="string"&&typeof e.label=="string"&&typeof e.at=="string"&&e.reason==="已达 8 个会话上限":e.kind==="dsh_legacy_hooks_retired"&&Object.keys(e).length===4&&typeof e.at=="string"&&(e.restored==="byte-identical"||e.restored==="surgical"||e.restored==="unavailable")&&typeof e.command=="string":!1}function Rn(e,t){const n=m(e)&&typeof e.root=="string"?e.root:`不可用项目 ${t+1}`,s=m(e)&&m(e.title)&&typeof e.title.text=="string"?e.title.text:n;return{root:n,title:{text:s,source:"工作目录"},plan:{availability:"unavailable",reason:"项目载荷不可用"},payloadUnavailable:!0}}function Mn(e){return!m(e)||typeof e.root!="string"||!In(e.title)||e.presence!=="active"&&e.presence!=="remembered"||typeof e.seenSinceStart!="boolean"||e.goal!==void 0&&typeof e.goal!="string"||!Dn(e.plan)||e.revision!==void 0&&!K(e.revision)||e.mtime!==void 0&&typeof e.mtime!="string"||e.lastWriter!==void 0&&!Un(e.lastWriter)||typeof e.currentPointLabel!="string"||e.currentPointEmptyText!==void 0&&typeof e.currentPointEmptyText!="string"||!Ke(e.currentPoints)||!Ke(e.checkpoints)||!Wn(e.counts)||typeof e.allLeavesDone!="boolean"||e.completionLabel!==void 0&&e.completionLabel!=="Agent 标记项目步骤全部完成"||!Array.isArray(e.contradictions)||!e.contradictions.every(qn)||!Array.isArray(e.facts)||!e.facts.every(t=>typeof t=="string")||!Nn(e.protocol)?!1:Array.isArray(e.sessions)&&e.sessions.every(Bn)}function Nn(e){return m(e)&&be(e.cc)&&be(e.codex)&&be(e.dsh)}function be(e){return m(e)&&pt(e.state)&&typeof e.targetPath=="string"&&(e.version===void 0||K(e.version))&&(e.planMtime===void 0||typeof e.planMtime=="string")&&(e.message===void 0||typeof e.message=="string")&&(e.reason===void 0||typeof e.reason=="string")}function In(e){return m(e)&&typeof e.text=="string"&&(e.source===".wingman/plan.md H1"||e.source==="工作目录")}function Dn(e){return m(e)?e.availability==="available"?L(e.ignoredLineCount)&&Hn(e.ignoredLines)&&e.ignoredLines.length===e.ignoredLineCount&&Array.isArray(e.nodes)&&e.nodes.every(Ne)&&Array.isArray(e.higherPlanPaths)&&e.higherPlanPaths.every(t=>typeof t=="string"):e.availability==="missing"?Array.isArray(e.lookedUp)&&e.lookedUp.every(t=>typeof t=="string"):e.availability!=="unavailable"||typeof e.reason!="string"||e.line!==void 0&&!K(e.line)?!1:e.lastGood===void 0||Fn(e.lastGood):!1}function Hn(e){return Array.isArray(e)&&e.every(t=>m(t)&&K(t.line)&&typeof t.preview=="string")}function Ne(e){return m(e)&&typeof e.key=="string"&&typeof e.text=="string"&&Xn(e.status)&&K(e.line)&&(e.verification===void 0||typeof e.verification=="string")&&Array.isArray(e.children)&&e.children.every(Ne)}function Fn(e){return m(e)&&K(e.revision)&&typeof e.mtime=="string"&&(e.title===void 0||typeof e.title=="string")&&(e.goal===void 0||typeof e.goal=="string")&&L(e.ignoredLineCount)&&Array.isArray(e.nodes)&&e.nodes.every(Ne)}function Un(e){return m(e)&&ft(e.harness)&&typeof e.id=="string"&&typeof e.label=="string"&&typeof e.at=="string"}function Ke(e){return Array.isArray(e)&&e.every(t=>m(t)&&typeof t.key=="string"&&typeof t.text=="string"&&Array.isArray(t.path)&&t.path.every(n=>typeof n=="string"))}function Wn(e){return m(e)&&L(e.pending)&&L(e.inProgress)&&L(e.completed)&&L(e.cancelled)&&L(e.checkpoint)}function qn(e){return m(e)&&typeof e.key=="string"&&typeof e.text=="string"}function Bn(e){return!m(e)||!ft(e.harness)||typeof e.id!="string"||typeof e.label!="string"||typeof e.ended!="boolean"||!Kn(e.title)||!Vn(e.user)||typeof e.waiting!="boolean"||e.cwd!==void 0&&typeof e.cwd!="string"||e.lastActivity!==void 0&&typeof e.lastActivity!="string"||e.attachedTo!==void 0&&typeof e.attachedTo!="string"||e.attachedBy!==void 0&&!Jn(e.attachedBy)||e.attachedTo===void 0!=(e.attachedBy===void 0)||e.unattachedReason!==void 0&&typeof e.unattachedReason!="string"||e.sessionPlan!==void 0&&!gt(e.sessionPlan)||e.feedback!==void 0&&!ht(e.feedback)||e.checks!==void 0&&!vt(e.checks)||e.acceptance!==void 0&&!$t(e.acceptance)?!1:Gn(e.compliance)}function Vn(e){return m(e)&&(e.title===void 0||typeof e.title=="string")&&typeof e.pinned=="boolean"&&typeof e.hidden=="boolean"}function Kn(e){return m(e)&&typeof e.text=="string"&&(e.source==="plan.md 步骤"||e.source==="最新指令"||e.source==="工作目录")}function Gn(e){return!m(e)||!pt(e.level)||!L(e.writeCount)||e.latestWriteAt!==void 0&&typeof e.latestWriteAt!="string"||e.writeSummary!==void 0&&typeof e.writeSummary!="string"?!1:e.timing===void 0?!0:m(e.timing)&&(e.timing.relation==="before"||e.timing.relation==="after")&&K(e.timing.nonPlanToolStep)&&typeof e.timing.text=="string"}function pt(e){return e==="not_installed"||e==="installed"||e==="installed_not_loaded"||e==="plan_present"||e==="session_wrote_plan"}function Jn(e){return m(e)&&e.kind==="plan_file_write"&&typeof e.node=="string"&&typeof e.method=="string"&&(e.at===void 0||typeof e.at=="string")}function Qn(e){return m(e)&&typeof e.root=="string"&&(e.attachedTo===void 0||typeof e.attachedTo=="string")}function Xn(e){return e==="pending"||e==="in_progress"||e==="completed"||e==="cancelled"||e==="checkpoint"}function ft(e){return e==="cc"||e==="codex"||e==="dsh"}function K(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=1}function Yn(e,t){return{harness:e,sessionId:t.id,transcriptPath:null,todos:[],traces:[],turnUsages:[],currentAction:null,waiting:null,agentQuote:null,lastPrompt:null,taskWorkflow:{plan:{availability:"unavailable",source:e,reason:"会话叙事载荷不可用"},execution:{evidenceCount:0,failureCount:0},feedback:{state:"unavailable",reason:"会话叙事载荷不可用"}},updatedAt:t.lastActivity}}function zn(e){return!m(e)||e.goal!==void 0&&!ye(e.goal)||e.latestInstruction!==void 0&&!ye(e.latestInstruction)||!gt(e.plan)||!m(e.execution)||!L(e.execution.evidenceCount)||!L(e.execution.failureCount)||e.execution.failureCount>e.execution.evidenceCount||e.execution.currentAction!==void 0&&!ye(e.execution.currentAction)||!ht(e.feedback)?!1:e.verification===void 0||Zn(e.verification)}function Zn(e){return!m(e)||!x(e,["agentMarkedComplete","checks","currentStep","acceptance"])||typeof e.agentMarkedComplete!="boolean"||!vt(e.checks)||!$t(e.acceptance)?!1:e.currentStep===void 0?!0:m(e.currentStep)&&x(e.currentStep,["text","runs","failures"])&&typeof e.currentStep.text=="string"&&mt(e.currentStep)}function vt(e){return!m(e)||!x(e,["runs","failures","latestFailure","source"])||e.source!=="Harness tool_result(is_error / exit_code)"||!mt(e)?!1:e.latestFailure===void 0?!0:m(e.latestFailure)&&x(e.latestFailure,["toolName","brief","at"])&&typeof e.latestFailure.toolName=="string"&&(e.latestFailure.brief===void 0||typeof e.latestFailure.brief=="string")&&(e.latestFailure.at===void 0||typeof e.latestFailure.at=="string")}function mt(e){return L(e.runs)&&L(e.failures)&&e.failures<=e.runs}function $t(e){return!m(e)||typeof e.state!="string"?!1:e.state==="none"?x(e,["state"]):e.state==="accepted"?x(e,["state","at"])&&typeof e.at=="string":e.state==="unavailable"&&x(e,["state","reason"])&&typeof e.reason=="string"}function x(e,t){return Object.keys(e).every(n=>t.includes(n))}function gt(e){return!m(e)||typeof e.source!="string"?!1:e.availability==="missing"?e.toolGate===void 0||es(e.toolGate):e.availability==="unavailable"?typeof e.reason=="string":e.availability!=="available"||!Number.isSafeInteger(e.revision)||e.revision<1||e.semantics!==void 0&&e.semantics!=="current_snapshot"||!Array.isArray(e.steps)?!1:e.steps.every(t=>m(t)&&typeof t.id=="string"&&typeof t.text=="string"&&(t.description===void 0||typeof t.description=="string")&&ts(t.status))}function es(e){return m(e)&&typeof e.harnessVersion=="string"&&(e.model===void 0||typeof e.model=="string")&&(e.affected==="known"||e.affected==="unknown")&&e.since==="2.1.233"&&e.enable==="CLAUDE_CODE_ENABLE_TODO_TOOLS=1"}function ht(e){return m(e)?e.state==="unavailable"?typeof e.reason=="string":typeof e.source!="string"?!1:e.state==="no_open_request"?!0:e.state==="needs_user"?typeof e.since=="string"&&(e.message===void 0||typeof e.message=="string"):e.state==="activity_resumed_unknown"?typeof e.requestSince=="string"&&typeof e.resumedAt=="string"&&(e.message===void 0||typeof e.message=="string"):!1:!1}function ye(e){return m(e)&&typeof e.text=="string"&&typeof e.source=="string"&&(e.observedAt===void 0||typeof e.observedAt=="string")}function ts(e){return e==="pending"||e==="in_progress"||e==="completed"}function L(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0}function m(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function fe(e,t){return!e||e.sessions.length===0?null:t!==void 0&&e.states[t]!==void 0?t:e.sessions[0]?.id??null}function bt(e){if(!e)return null;for(const t of e.sessions){if(!t.waiting)continue;const n=e.states[t.id]?.waiting;if(n)return{label:t.label,message:n.message,since:n.since}}return null}function yt(e){return e?e.todos.length>0||e.traces.length>0||e.turnUsages.length>0||e.currentAction!==null||e.waiting!==null||e.taskWorkflow!==void 0:!1}const Ie={completed:"✓",in_progress:"▶",pending:"○"};function ns(e){const t=e.taskWorkflow;return t?.goal!==void 0?{label:"目标",fact:t.goal}:t?.latestInstruction!==void 0?{label:"最新指令",fact:t.latestInstruction}:null}function ss(e){const t=e.taskWorkflow?.plan;return t?.availability==="available"?t.steps.filter(n=>n.status==="in_progress").map(n=>n.text):[]}function as(e){return e.availability==="available"?`${e.source} · revision ${e.revision}`:e.source}function is(e){const t=e.todos.find(n=>n.status==="in_progress");return t?t.activeForm??t.content:e.lastPrompt}function kt(e){return e?e.kind==="tool"?e.detail===""?e.toolName:`${e.toolName} · ${e.detail}`:wt(e.name):null}const os={SessionStart:"会话开始",SessionEnd:"会话结束",UserPromptSubmit:"收到新提示",PreToolUse:"工具调用开始",PostToolUse:"工具调用完成",Stop:"回合结束",Notification:"收到通知",PermissionRequest:"等待授权",SubagentStart:"子代理启动",SubagentStop:"子代理结束",PreCompact:"压缩开始",PostCompact:"压缩完成"};function wt(e){return os[e]??e}function Tt(e){return e?e.turnUsages[e.turnUsages.length-1]??null:null}function St(e){return e<.005?"<$0.01":`$${e.toFixed(2)}`}function jt(e){return e.totalTokens??e.contextTotal?.value??e.inputTotalTokens??null}function oe(e){const t=jt(e);if(t===null)return"—";const n=e.status==="aborted"?"(中断)":e.status==="incomplete"?"(未收口)":"",s=`${T(t)} ${e.totalTokens===void 0&&e.contextTotal===void 0?"input":"tok"}${n}`;return e.costUsd===void 0?s:`${s} ≈ ${St(e.costUsd)}`}function ve(e){if(e<1e3)return"<1s";const t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m${t%60===0?"":` ${t%60}s`}`}function rs(e,t){return e.agents.length>0?"子 agent":t&&t.nodes.length>0?"主 agent":null}function cs(e){return!e||e.todos.length===0?null:`${e.todos.filter(n=>n.status==="completed").length}/${e.todos.length}`}const ls=6e4;function ds(e,t,n,s,a){const i=Tt(e),c=s!==void 0?s:e?.waiting?{label:"",message:e.waiting.message,since:e.waiting.since}:null;if(c){const l=c.label===""?"":`(${c.label})`,d=Date.parse(c.since),u=a!==void 0&&Number.isFinite(d)?a-d:Number.NaN,f=Number.isFinite(u)&&u>ls?` · 已等 ${Math.floor(u/6e4)}m+`:"";return{mode:"waiting",label:`等你${l}:${c.message}${f}`,tok:i?oe(i):n}}return t.active?{mode:"working",label:(e?kt(e.currentAction):null)??t.label,tok:i?`本轮 ${oe(i)}`:n}:{mode:"idle",label:t.label,tok:i?`${i.status==="incomplete"?"本轮":"上轮"} ${oe(i)}`:n}}function Et(e,t){const n=t[e.id];return n!==void 0?n:e.status==="in_progress"}async function Ae(e,t=globalThis.navigator?.clipboard){if(t===void 0)return!1;try{return await t.writeText(e),!0}catch{return!1}}function De(e){return`npx harness-wingman${e?`@${e}`:""}`}function de(e,t){return`${De(t)} hook install ${e}`}function us(e){return`'${e.replaceAll("'",`'"'"'`)}'`}function _t(e,t,n){return`${De(n)} protocol install ${e} --project ${us(t)}`}const ps=["tray","panel","site"],fs=["codex","claude-code","dsh"];function vs(e,t){const n=new URL(e);if(n.protocol!=="https:")throw new Error("反馈表单必须使用 HTTPS");if(!ps.includes(t.source))throw new Error("反馈入口来源不合法");return n.search="",n.hash="",n.searchParams.set("source",t.source),ke(n,"wingman_version",t.wingmanVersion),ke(n,"os",t.os),t.harness!==void 0&&fs.includes(t.harness)&&n.searchParams.set("harness",t.harness),ke(n,"harness_version",t.harnessVersion),n.toString()}function ke(e,t,n){if(n===void 0)return;const s=n.trim();s.length===0||/[\r\n\u2028\u2029]/u.test(s)||[...s].length>64||e.searchParams.set(t,s)}const ms="https://tally.so/r/aQMeVW",Ge="support@getwingman.dev",$s={cc:"claude-code",codex:"codex",dsh:"dsh"};function gs(e){const t=e?.harnessVersion;return vs(ms,{source:"panel",...e===void 0?{}:{harness:$s[e.harness]},...t===void 0?{}:{harnessVersion:t}})}const hs="https://api.getwingman.dev/samples",bs=256*1024;function ys(e){if(e.__mock_note)return[];const t={harness:e.harness,...e.harnessVersion===void 0?{}:{harnessVersion:e.harnessVersion},scannedAt:e.scannedAt,slots:e.slots,capabilities:e.capabilities};return JSON.stringify(t,null,2).split(`
|
|
5
|
+
`)}function ks(e){return e.filter(t=>!t.mock&&!xe(t.event)).map(t=>JSON.stringify(t.event))}function xe(e){if(typeof e=="string")return/(?:^|[\\/])\.wingman[\\/]plan\.md(?:$|\s)/u.test(e);if(Array.isArray(e))return e.some(xe);if(e===null||typeof e!="object")return!1;for(const[t,n]of Object.entries(e))if(/^(?:project|project_?(?:root|path)|plan|plan_?text)$/iu.test(t)||xe(n))return!0;return!1}function ws(e,t){return!Number.isInteger(t)||t<0||t>=e.length?[...e]:e.filter((n,s)=>s!==t)}function Ts(e){return e.join(`
|
|
6
|
+
`)}function At(e,t){return JSON.stringify({kind:e,sample:Ts(t)})}function xt(e,t){return new TextEncoder().encode(At(e,t)).length}function Pt(e,t){return xt(e,t)>bs}function Ss(e,t){const n=(xt(e,t)/1024).toFixed(1);return`共 ${t.length} 行 · 约 ${n} KB / 上限 256 KB`}const te={harness:"all",status:"all"};function js(e){return e.user.title===void 0?e.title:{text:e.user.title,source:"用户命名"}}function ue(e){const t=e.sessionPlan?.availability==="available"&&e.sessionPlan.steps.length>0&&e.sessionPlan.steps.every(n=>n.status==="completed");return e.waiting||e.feedback?.state==="needs_user"?{kind:"waiting",label:"等你",agentComplete:t}:e.ended?{kind:"ended",label:"已结束",agentComplete:t}:{kind:"active",label:"进行中",agentComplete:t}}function Es(e){if(e?.availability==="available")return{completed:e.steps.filter(t=>t.status==="completed").length,total:e.steps.length}}function He(e){const t={waiting:0,active:1,ended:2};return[...e].sort((n,s)=>{const a=Number(s.user.pinned)-Number(n.user.pinned);if(a!==0)return a;const i=ue(n).kind,c=ue(s).kind,l=t[i]-t[c];return l!==0?l:i!=="active"?0:n.lastActivity===void 0?s.lastActivity===void 0?0:1:s.lastActivity===void 0?-1:s.lastActivity.localeCompare(n.lastActivity)})}function Fe(e){return{visible:e.filter(t=>!t.user.hidden),hidden:e.filter(t=>t.user.hidden)}}function Ot(e){return e.harness==="dsh"?{unavailable:"dsh 未提供按会话恢复的命令(未观察到),请在原终端继续"}:e.harness==="codex"?{command:`codex resume ${e.id}`,note:"来源:会话 id 来自 hook 事件;命令形式来自 codex resume --help"}:e.cwd===void 0?{command:`claude --resume ${e.id}`,note:"来源:会话 id 来自 hook 事件;命令形式来自 claude --help;需在原项目目录运行"}:{command:`cd "${_s(e.cwd)}" && claude --resume ${e.id}`,note:"来源:会话 id 与工作目录来自 hook 事件;命令形式来自 claude --help"}}function _s(e){return e.replace(/[\\"$`]/g,"\\$&")}function Ue(e,t){return e.filter(n=>(t.harness==="all"||n.harness===t.harness)&&(t.status==="all"||ue(n).kind===t.status))}function As(e,t){const n=Math.max(0,t-Date.parse(e)),s=Math.floor(n/6e4);if(s<1)return"刚刚";if(s<60)return`${s} 分钟前`;const a=Math.floor(s/60);return a<24?`${a} 小时前`:`${Math.floor(a/24)} 天前`}function xs(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}const o=xs;function Ps(e,t){return`<div class="empty-card">
|
|
7
|
+
<div class="empty-title">未检测到 harness</div>
|
|
8
|
+
${e?`<div class="empty-detail">${o(e)}</div>`:'<div class="empty-detail">/api/anatomy 返回了空数组</div>'}
|
|
9
|
+
<div class="empty-hint">先运行 <code>${o(De(t))} serve</code>${J(t)},面板从 GET /api/anatomy 读取解剖数据。</div>
|
|
10
|
+
</div>`}function J(e){return e===null?'<span class="muted">(版本未知,可能装到别的版本)</span>':""}function Os(e,t){const n=t.mode==="waiting"?" wait":t.mode==="working"?" live":" quiet",s=t.mode==="waiting"?"有未决的权限请求/通知(PermissionRequest/Notification 事件);点击展开处理":t.mode==="working"?"有活跃 session(最近 15s 内收到 hook 事件);点击展开面板":"点击展开面板";return`<div class="pill${t.mode==="waiting"?" waiting":""}" data-act="toggle" data-tip="${o(s)}">
|
|
11
|
+
<span class="dot${n}"></span>
|
|
12
|
+
<span class="t1">${o(j[e.harness])}</span>
|
|
13
|
+
<span class="t2">${o(t.label)}</span>
|
|
14
|
+
${t.tok===""?"":`<span class="tok">${o(t.tok)}</span>`}
|
|
15
|
+
<span class="chev">▾</span>
|
|
16
|
+
</div>`}function Ls(e,t,n){const s=`<button class="tab${t==="projects"?" act":""}" data-tab="projects">项目</button>`,a=e.map(i=>{const c=i.harness===t,l=n[i.harness],d=!c&&l>0?`<span class="tabnum" data-tip="实况流内 ${j[i.harness]} 事件 ${l} 条">${l}</span>`:"";return`<button class="tab${c?" act":""}" data-tab="${i.harness}">${o(j[i.harness])}${d}</button>`}).join("");return`<div class="tabs">${s}${a}</div>`}function Cs(e,t){const n=Y.map(f=>({slot:f,total:et(e.slots[f]??[])})),s=n.reduce((f,v)=>f+(v.total?.value??0),0),a=tt(e),i=a?`常驻合计 <b data-tip="合计 = 各槽位启用条目的常驻 token 之和;${a.kind==="estimate"?"含估算值,故标「约」":"全部为 harness 自报精确值"}">${o(D(a))} token</b>`:"本次扫描未采到 token 数值(无可估算的字节来源)",c=s>0?n.filter(f=>f.total&&f.total.value>0).map(f=>{const v=(f.total?.value??0)/s*100,g=`${B[f.slot]} · ${D(f.total)}`;return`<div class="seg" style="width:${v.toFixed(1)}%;background:${le[f.slot]}" data-tip="${o(g)}"></div>`}).join(""):"",l=c?`<div class="stack">${c}</div>`:"",d=n.map(({slot:f,total:v})=>{const g=!v,S=e.slots[f]??[],y=g?`${B[f]}:本次扫描该槽位无带 token 来源的启用条目`:`${B[f]} 启用条目常驻合计(逐条来源见下方明细)`;return`<div class="lrow${g?" na":""}" data-tip="${o(y)}">
|
|
17
|
+
<span class="sw" style="background:${g?"var(--grid)":le[f]}"></span>${B[f]}
|
|
18
|
+
<span class="nat">${o(Re[e.harness][f])}</span>
|
|
19
|
+
<span class="v">${o(D(v))}</span>
|
|
20
|
+
<span class="cnt">${S.length} 项</span>
|
|
21
|
+
</div>`}).join("");let u="";if(t.anatomyRefreshFailed&&t.anatomyLoadedAt!==null){const f=new Date(t.anatomyLoadedAt),v=`${String(f.getHours()).padStart(2,"0")}:${String(f.getMinutes()).padStart(2,"0")}`;u=`<div class="anatomy-refresh-warning" data-tip="来源:上次成功 GET /api/anatomy 的面板时间 ${o(t.anatomyLoadedAt)}">刷新失败,显示的是 ${o(v)} 的数据</div>`}return`<div class="sec">
|
|
22
|
+
<div class="label">CONTEXT 组成<span class="labr"><button class="sharelink" data-act="share-config" data-tip="打开预览弹层:先看到将发送的完整内容,可逐行删,点「发送」才会发出;关闭 = 什么都不发">分享配置样本</button></span></div>${u}
|
|
23
|
+
<div class="headline">${i}</div>
|
|
24
|
+
${l}
|
|
25
|
+
<div class="legend">${d}</div>
|
|
26
|
+
</div>`}function Rs(e){const t=e.enabled?"":'<span class="statechip off" data-tip="该条目当前被关闭;可开关条目在下方 CONFIGURE 区一键打开">已关闭</span>',n=e.nativePath?"":'<span class="statechip nofile" data-tip="无文件实体:该条目不来自可读文件(如内置注入 / boot 树行)">无文件实体</span>';return`<div class="crow${e.enabled?"":" offrow"}" data-tip="${o(nt(e))}">
|
|
27
|
+
<span class="cname">${o(e.nativeName)}</span>
|
|
28
|
+
<span class="chip">${o(e.source)}</span>
|
|
29
|
+
${t}${n}
|
|
30
|
+
<span class="ctok">${o(Gt(e))}</span>
|
|
31
|
+
</div>`}function Ms(e){return`<div class="sec">
|
|
32
|
+
<div class="label">六槽位明细 · hover 查看来源</div>
|
|
33
|
+
${Y.map(n=>{const s=e.slots[n]??[],a=s.length?s.map(i=>Rs(i)).join(""):'<div class="crow emptyrow">本次扫描无条目(该槽位在此 harness 无可读来源)</div>';return`<div class="grp">
|
|
34
|
+
<div class="gtitle"><span class="gdot" style="background:${le[n]}"></span>${B[n]}
|
|
35
|
+
<span class="nat">${o(Re[e.harness][n])}</span>
|
|
36
|
+
</div>
|
|
37
|
+
${a}
|
|
38
|
+
</div>`}).join("")}
|
|
39
|
+
</div>`}function Ns(e){const t=Yt(e),n=e.enabled?"":'<span class="statechip off">关闭中</span>';return`<div class="crow${e.enabled?"":" offrow"}" data-tip="${o(nt(e))}">
|
|
40
|
+
<span class="cname">${o(e.nativeName)}</span>
|
|
41
|
+
<span class="chip">${o(e.source)}</span>
|
|
42
|
+
${n}
|
|
43
|
+
<span class="ctok">${o(t)}</span>
|
|
44
|
+
<span class="cright"><button class="toggle${e.enabled?" on":""}" data-act="tgl" data-id="${o(e.id)}" role="switch" aria-checked="${e.enabled}" aria-label="${o(`${e.enabled?"关闭":"打开"} ${e.nativeName}`)}" data-tip="点击预览改动 —— 先 plan 后 apply:确认前不写任何文件;写前自动备份,可 byte-identical 回退"></button></span>
|
|
45
|
+
</div>`}function Is(e){const t=Xt(e);let n;if(t.groups.length===0)n='<div class="crow emptyrow">该 harness 本次扫描没有可在面板开关的条目 —— 开关范围仅限各家原生支持的机制,其余条目请在源文件里改</div>';else if(n=t.groups.map(s=>{const a=s.items.map(c=>Ns(c)).join(""),i=e.harness==="codex"&&s.slot==="tools"?'<div class="cfgnote" data-tip="PLAN §4b 实测:config.toml 的 enabled_tools/disabled_tools 按单个工具开关;CC 只能整 server 开关,dsh 只能整插件开关">Codex 独有:enabled_tools / disabled_tools 可精确到单个工具 —— 三家里粒度最细</div>':"";return`<div class="grp">
|
|
46
|
+
<div class="gtitle"><span class="gdot" style="background:${le[s.slot]}"></span>${B[s.slot]}
|
|
47
|
+
<span class="nat">${o(Re[e.harness][s.slot])}</span>
|
|
48
|
+
</div>
|
|
49
|
+
${a}${i}
|
|
50
|
+
</div>`}).join(""),t.slotsWithoutToggle.length>0){const s=t.slotsWithoutToggle.map(a=>B[a]).join(" · ");n+=`<div class="cfgnote">其余槽位(${s})本次扫描无可开关条目 —— 开关范围仅限各家原生支持的机制</div>`}return`<div class="sec">
|
|
51
|
+
<div class="label">CONFIGURE</div>
|
|
52
|
+
${n}
|
|
53
|
+
</div>`}function Ds(e){const t=e.returnTargets;if(t==null)return"";const n=t.available.length===0?'<div class="cfgnote">本机未检测到支持的终端应用(Terminal / iTerm / Ghostty / WezTerm / Warp / Alacritty / kitty / VS Code)</div>':t.available.map(i=>{const c=t.selected?.bundlePath===i.bundlePath;return`<button class="return-target-option${c?" act":""}" data-act="return-target-select" data-bundle-path="${o(i.bundlePath)}" type="button" aria-pressed="${c}"${e.returnTargetSaving?" disabled":""}>${o(i.name)}</button>`}).join(""),s=t.settings!==void 0&&!e.returnSettingsDismissed?`<div class="task-error">${o(t.settings.unavailable)} <button class="return-settings-dismiss" data-act="return-settings-dismiss" type="button">关闭</button></div>`:"",a=e.returnTargetError===null||e.returnTargetError===void 0?"":`<div class="task-error" role="status">${o(e.returnTargetError)}</div>`;return`<div class="sec return-targets" data-tip="来源:GET /api/return-target 本机应用检测与 ~/.wingman/state/settings.json 用户选择">
|
|
54
|
+
<div class="label">回到会话时切换到</div>
|
|
55
|
+
<div class="return-target-options">${n}</div>${s}${a}
|
|
56
|
+
</div>`}function Hs(e,t){const n=e.writes.length?e.writes.map(i=>`<div class="mfile"><span class="mkind ${i.kind}">${zt(i.kind)}</span><code class="mpath">${o(i.file)}</code><span class="mlines">${o(Zt(i))}</span></div>`).join(""):'<div class="mtext muted">plan 未包含任何文件变更</div>',s=e.references.length?e.references.map(i=>`<div class="mref"><code class="mpath">${o(`${i.file}:${i.line}`)}</code><span class="mctx">${o(i.context)}</span></div>`).join(""):'<div class="mtext muted">引用语料里没有别处提到它</div>';return`${t?`<div class="mnote">${o(t)}</div>`:""}
|
|
57
|
+
<div class="msec"><div class="mlabel">将写入的文件 — 确认前一个字节都不动</div>${n}</div>
|
|
58
|
+
<div class="msec"><div class="mlabel">引用命中 ${e.references.length} 处 — 这些地方提到了它;只提醒,不修复</div>${s}</div>
|
|
59
|
+
<div class="msec"><div class="mlabel">生效时机</div><div class="mtext">${o(en(e.effectiveAt))}</div></div>
|
|
60
|
+
<div class="msec"><div class="mlabel">备份</div><div class="mtext">写入前,原件先备份到 <code>${o(e.backupDir)}</code>;回退 = 原样拷回(byte-identical)</div></div>
|
|
61
|
+
<div class="mact">
|
|
62
|
+
<button class="btn ghost" data-act="plan-cancel">取消</button>
|
|
63
|
+
<button class="btn primary" data-act="plan-confirm">确认写入</button>
|
|
64
|
+
</div>`}function Fs(e){const t=e.phase==="confirm"&&e.mockNote?`<span class="mockchip" data-tip="${o(e.mockNote)}">MOCK</span>`:"";let n;e.phase==="planning"?n='<div class="mtext muted">正在生成 plan…(纯读:不写盘、不建备份目录)</div>':e.phase==="applying"?n='<div class="mtext muted">正在写入…(原件已先备份到 plan 里的备份目录)</div>':e.phase==="confirm"?n=Hs(e.plan,e.mockNote):e.phase==="applied"?n=`<div class="mtext">已写入,面板数据已重拉刷新。</div>
|
|
65
|
+
<div class="mtext">备份:<code>${o(e.backupDir)}</code>(回退 = 原样拷回)</div>
|
|
66
|
+
<div class="mact"><button class="btn primary" data-act="plan-cancel">关闭</button></div>`:e.phase==="demo"?n=`<div class="mtext">演示模式:动作只到 plan 为止 —— 当前数据源只读(fixtures / dev 演示),不写任何真实文件。</div>
|
|
67
|
+
<div class="mact"><button class="btn primary" data-act="plan-cancel">知道了</button></div>`:n=`<div class="merror">${o(e.message)}</div>
|
|
68
|
+
<div class="mtext muted">常见原因:文件在 plan 之后被外部改过(关闭后重新点开关生成新 plan)、itemId 不存在、或目标格式未知被拒写(不猜,如实拒绝)。</div>
|
|
69
|
+
<div class="mact"><button class="btn ghost" data-act="plan-cancel">关闭</button></div>`;const s=e.phase!=="applying";return`<div class="overlay">
|
|
70
|
+
<div class="scrim"${s?' data-act="plan-cancel"':""}></div>
|
|
71
|
+
<div class="modal" role="dialog" aria-modal="true" aria-label="${o(e.title)}">
|
|
72
|
+
<div class="mhead"><span class="mtitle">${o(e.title)}</span>${t}${s?'<button class="mclose" data-act="plan-cancel" aria-label="关闭弹窗">✕</button>':""}</div>
|
|
73
|
+
${n}
|
|
74
|
+
</div>
|
|
75
|
+
</div>`}function Us(e){const t=ot(e??null);if(!t||!e)return"";if(t==="trial-active"){const s=e.exp?.match(/^\d{4}-\d{2}-\d{2}/)?.[0],a=s?`30 天免费试用至 ${s}`:"30 天免费试用中";return`<div class="lictrial"><button class="licfootlink" data-act="lic-open" data-tip="${o(e.detail)}">${a}</button></div>`}if(t==="trial-expired")return`<div class="licrow"><button class="licbar expired" data-act="lic-open" data-tip="${o(e.detail)}">免费试用已结束 · 刷新或订阅</button></div>`;const n=t==="grace"?"订阅已到期,宽限期内 · 点此续期":"订阅已到期,写动作已锁";return`<div class="licrow"><button class="licbar ${t}" data-act="lic-open" data-tip="${o(e.detail)}">${o(n)}</button>${Lt("licimport")}</div>`}function Lt(e){return`<button class="${e}" data-act="lic-import" data-tip="选择激活页下载的 license.json 导入(写入 ~/.wingman/license.json,旧文件自动备份);也可把文件直接拖进本面板">导入 license</button>`}function Ws(e){return`<div class="overlay">
|
|
76
|
+
<div class="scrim" data-act="import-close"></div>
|
|
77
|
+
<div class="modal" role="dialog" aria-modal="true" aria-label="导入 license">
|
|
78
|
+
<div class="mhead"><span class="mtitle">导入 license</span><button class="mclose" data-act="import-close" aria-label="关闭弹窗">✕</button></div>
|
|
79
|
+
${e.ok?`<div class="mtext">${o(e.message)}</div>`:`<div class="merror">${o(e.message)}</div>`}
|
|
80
|
+
<div class="mact"><button class="btn primary" data-act="import-close">关闭</button></div>
|
|
81
|
+
</div>
|
|
82
|
+
</div>`}function qs(e,t=it,n=!1,s=null,a=!1){const i=e.plan==="trial",c=i&&e.state==="expired",l=t===""?"取消订阅或更换付款方式需在 Stripe 侧操作,入口在订阅邮箱收到的 Stripe 邮件里。":`<a href="${o(t)}" target="_blank" rel="noreferrer">管理订阅(取消/换卡/发票)</a>`,d=i&&!c?"":'<div class="msec"><div class="mlabel">刷新授权</div><div class="mtext">付款成功或订阅仍有效时,点击刷新即可恢复最新状态。仅此按钮会联系授权服务。</div></div>',u=c&&a?`<div class="msec"><div class="mlabel">继续使用写功能</div><div class="mtext"><a href="${o($n)}" target="_blank" rel="noreferrer">订阅 Wingman</a></div></div>`:"",f=s?`<div class="${s.ok?"mtext":"merror"}" aria-live="polite">${o(s.message)}</div>`:"",v=i&&!c?"":`<button class="btn primary" data-act="lic-refresh"${n?" disabled":""}>${n?"刷新中…":"刷新授权"}</button>`;return`<div class="overlay">
|
|
83
|
+
<div class="scrim" data-act="lic-close"></div>
|
|
84
|
+
<div class="modal" role="dialog" aria-modal="true" aria-label="${i?"免费试用":"授权状态"}">
|
|
85
|
+
<div class="mhead"><span class="mtitle">${c?"免费试用已结束":i?"30 天免费试用":"授权状态"}</span><button class="mclose" data-act="lic-close" aria-label="关闭弹窗">✕</button></div>
|
|
86
|
+
<div class="msec"><div class="mlabel">当前状态</div><div class="mtext">${o(e.detail)}</div></div>${d}${u}
|
|
87
|
+
<div class="msec"><div class="mlabel">订阅管理</div><div class="mtext">${l}</div></div>
|
|
88
|
+
${f}<div class="mact"><button class="btn ghost" data-act="lic-close">关闭</button>${v}</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>`}function Bs(e){let t;if(e.phase==="preview"){const n=e.lines.length?e.lines.map((c,l)=>`<div class="shline"><button class="shdel" data-act="share-del" data-i="${l}" aria-label="删除第 ${l+1} 行" data-tip="删掉这一行(只影响本次发送)">✕</button><span class="shtext">${o(c)}</span></div>`).join(""):'<div class="mtext muted">没有可发送的内容(MOCK 演示数据不外发;删光了也一样不发)</div>',s=Pt(e.kind,e.lines),a=s?'<div class="merror">样本超过 256 KB 上限,删减后才能发送</div>':"",i=e.lines.length===0||s?" disabled":"";t=`<div class="mtext">分享样本帮助 Wingman 适配更多真实环境。下面就是将要发送的全部内容:逐行检查,不想发的行点 ✕ 删掉;点「发送」才会发出,关闭则什么都不发。样本不含任何账号或设备标识,服务端也不记录 IP。</div>
|
|
91
|
+
<div class="msec"><div class="mlabel">将发送的内容 · ${o(Ss(e.kind,e.lines))}</div>
|
|
92
|
+
<div class="sharebox">${n}</div>${a}</div>
|
|
93
|
+
<div class="mact">
|
|
94
|
+
<button class="btn ghost" data-act="share-close">关闭(不发送)</button>
|
|
95
|
+
<button class="btn primary" data-act="share-send"${i}>发送</button>
|
|
96
|
+
</div>`}else e.phase==="sending"?t=`<div class="mtext muted">发送中…(POST ${o("api.getwingman.dev/samples")})</div>`:e.phase==="sent"?t=`<div class="mtext">已发送。样本只用于适配真实环境,90 天后在服务端自动过期。</div>
|
|
97
|
+
<div class="mact"><button class="btn primary" data-act="share-close">关闭</button></div>`:t=`<div class="merror">${o(e.message??"发送失败")}</div>
|
|
98
|
+
<div class="mtext muted">没有发出任何内容;稍后可重新分享。</div>
|
|
99
|
+
<div class="mact"><button class="btn ghost" data-act="share-close">关闭</button></div>`;return`<div class="overlay">
|
|
100
|
+
<div class="scrim" data-act="share-close"></div>
|
|
101
|
+
<div class="modal" role="dialog" aria-modal="true" aria-label="${o(e.title)}">
|
|
102
|
+
<div class="mhead"><span class="mtitle">${o(e.title)}</span><button class="mclose" data-act="share-close" aria-label="关闭弹窗">✕</button></div>
|
|
103
|
+
${t}
|
|
104
|
+
</div>
|
|
105
|
+
</div>`}function Vs(e,t){const{event:n}=e,s=n.payload.hook_event_name,a=typeof n.payload.tool_name=="string"?n.payload.tool_name:"",i=typeof n.payload.session_id=="string"?n.payload.session_id:"(无 session_id)",c=[`事件:${s}(hook_event_name 原文)`,`时间 = receiver 收到时刻 received_at:${n.received_at}`,`session:${i}`];return e.mock&&c.push("MOCK:dev 演示重放注入,非真实 harness 推送(增补条款 10)"),`<div class="lvrow${n.harness===t?" own":" other"}" data-tip="${o(c.join(`
|
|
106
|
+
`))}">
|
|
107
|
+
<span class="lvtime">${o(ct(n.received_at))}</span>
|
|
108
|
+
<span class="lvname">${o(rt(s))}</span>
|
|
109
|
+
${a?`<span class="chip">${o(a)}</span>`:""}
|
|
110
|
+
${e.mock?'<span class="mockchip">MOCK</span>':""}
|
|
111
|
+
<span class="lvharness">${o(n.harness)}</span>
|
|
112
|
+
</div>`}function Ks(e,t,n,s){const a=e.capabilities.live,i=a==="full"?`接线配置完整 · ${s?"已收到事件":"事件未验证"}`:Jt(a),c=t.entries.filter(u=>u.event.harness===e.harness);let l;t.entries.length>0?(l=`<div class="feed">${[...t.entries].reverse().map(f=>Vs(f,e.harness)).join("")}</div>`,a==="none"&&c.length===0?l=`<div class="livenone">○ ${o(j[e.harness])} 未接线 —— 运行 <code>${o(de(e.harness,n))}</code>${J(n)} 接线后重启一次该 harness(它只在启动时读 hooks 配置;Codex 首次还需在其界面信任 hook),其 hook 事件才会出现在下方流里(当前流内是别家事件)</div>`+l:e.harness==="codex"&&c.length===0&&(l='<div class="livenone">○ 检测到 Codex hooks 配置,但尚未收到事件 —— 在 Codex 输入 <code>/hooks</code>,确认 Wingman 为 Trusted 且 Enabled;若当前任务仍无事件,完整退出并重开 Codex 后新建任务验证</div>'+l)):a==="none"?l=`<div class="livenone">○ 未接线 —— 运行 <code>${o(de(e.harness,n))}</code>${J(n)} 把该 harness 的 hooks 指到本面板(幂等、可 uninstall 恢复),然后重启一次该 harness 生效——它只在启动时读 hooks 配置;接线前这里不显示任何数据</div>`:e.harness==="codex"?l='<div class="livenone">○ 检测到 Codex hooks 配置,但尚未收到事件 —— 这还不能证明已连通。请在 Codex 输入 <code>/hooks</code>,确认 Wingman 为 Trusted 且 Enabled;若当前任务仍无事件,完整退出并重开 Codex 后新建任务验证</div>':l=a==="full"?`<div class="livenone">○ ${o(i)}${s?" —— narrative 概览已有该 Harness 会话":` —— 在 ${o(j[e.harness])} 产生事件后这里才会显示实况流`}</div>`:`<div class="livenone">○ 检测到接线配置(推送),尚未收到事件 —— 在 ${o(j[e.harness])} 产生事件后这里才会显示实况流</div>`;const d=t.connection==="retrying"?`<button class="demobtn" data-act="demo" ${t.replaying?"disabled":""} data-tip="EventSource 连不上(dev 模式无 SSE 端点)时的本地演示:以 200ms 间隔重放 fixtures 的 cc 事件序列,注入事件全部带 MOCK 徽章">重放 fixtures 演示 · MOCK</button>`:"";return`<div class="sec">
|
|
113
|
+
<div class="label">实况 <span class="tier${a==="none"?" none":""}">${o(i)}</span>
|
|
114
|
+
<span class="conn ${t.replaying?"replay":t.connection}" data-tip="GET /api/events(SSE)连接状态;断线由 EventSource 自动重连">${o(En(t))}</span>
|
|
115
|
+
<span class="labr">${d}<button class="sharelink" data-act="share-events" data-tip="打开预览弹层:先看到将发送的完整事件流,可逐行删,点「发送」才会发出;关闭 = 什么都不发">分享事件样本</button></span>
|
|
116
|
+
</div>
|
|
117
|
+
${l}
|
|
118
|
+
</div>`}const Ct={wingmanVersion:void 0,view:"tasks",narrative:null,projects:null,anatomyLoadedAt:null,anatomyRefreshFailed:!1,projectMemoryDismissed:!1,startedAt:null,notices:[],noticeDismissed:{},sessions:[],selectedSession:null,sessionSeen:{},suggHidden:{},island:!1,todoOpen:{},nodeOpen:{},evidenceOpen:!1,rawOpen:!1,taskFilter:te,taskMenuOpen:null,taskResumeOpen:null,returnTargets:null,returnSettingsDismissed:!1,returnTargetSaving:!1,returnTargetError:null,taskReturnResults:{},hiddenOpen:{},factsOpen:{},taskError:null};function We(e){return e.replace(/^session-/u,"").slice(0,8)}function Gs(e,t){if(e.sessions.length<2)return"";const n=new Map;for(const a of e.sessions)n.set(a.label,(n.get(a.label)??0)+1);return`<div class="schips">${e.sessions.map(a=>{const i=a.id===e.selectedSession,c=e.sessionSeen[`${t}:${a.id}`]??"",l=!i&&a.lastActivity>c,d=[`session:${a.id}`,`最近活动:${a.lastActivity||"(未观察到)"}`,a.ended?"已结束(SessionEnd,或 Stop 后 10 分钟无事件)":"进行中",a.waiting?"等你:有未决的权限请求/通知":"",l?"有新活动(上次查看后)":""].filter(v=>v!=="").join(`
|
|
119
|
+
`),u=a.waiting?'<span class="sdot wait"></span>':l?'<span class="sdot"></span>':"",f=(n.get(a.label)??0)>=2?`${a.label} ·${We(a.id)}`:a.label;return`<button class="schip${i?" act":""}${a.ended?" ended":""}" data-act="session" data-id="${o(a.id)}" data-tip="${o(d)}">${u}${o(f)}${l?'<span class="snew">新活动</span>':""}</button>`}).join("")}</div>`}function Js(e,t){return e.sessions.length!==0||e.startedAt===null?"":`<div class="sessions-empty">Wingman 启动(${o(e.startedAt)})后尚未收到 ${o(j[t])} 的 hook 事件;会话只由事件建立,重启不恢复历史。</div>`}function Je(e,t){return t.kind==="evicted"?`${e}:${t.sessionId}:${t.at}`:`${e}:${t.kind}:${t.at}`}function Qs(e,t){return e.notices.filter(n=>!e.noticeDismissed[Je(t,n)]).map(n=>{const s=Je(t,n);if(n.kind==="dsh_legacy_hooks_retired"){if(t!=="dsh")return"";const a=n.restored==="unavailable"?"旧版家目录层接线无法自动解除,请手动解线后重新接线:":"旧版(0.6.0 及更早)家目录层接线已解除,避免 dsh 无法启动;重新接线:";return`<div class="session-notice" data-kind="dsh_legacy_hooks_retired" data-act="notice-dismiss" data-key="${o(s)}">${o(a)}<code>${o(n.command)}</code><span class="session-notice-close">关闭</span></div>`}return`<div class="session-notice" data-act="notice-dismiss" data-key="${o(s)}">已驱逐 ${o(n.label)}(${o(We(n.sessionId))}) · ${o(ct(n.at))} · ${o(n.reason)}<span class="session-notice-close">关闭</span></div>`}).join("")}function Xs(e,t){const n=e.sessions.find(s=>s.id===e.selectedSession)??e.sessions[0];return n?.feedback==="not_wired"?`<div class="feedbacksignal">反馈信号未接线:${o(de(t,e.wingmanVersion))}${J(e.wingmanVersion)}</div>`:n?.feedback==="unavailable"?'<div class="feedbacksignal">反馈信号不可用</div>':""}function Ys(e,t){const n=e.narrative?.suggestions??[];if(n.length===0)return"";const s=e.selectedSession??"";return n.filter(a=>e.suggHidden[`${t}:${s}:${a.id}`]!==!0).map(a=>{const i=a.action?`<button class="sugbtn" data-act="sugg-plan" data-item="${o(a.action.itemId)}" data-enable="${a.action.enable?"1":"0"}" data-tip="打开 M3 plan 弹窗:先看方案(写哪些文件/生效时机/备份),确认才写入">看方案</button>`:"";return`<div class="sugg r-${a.rule}" data-tip="${o(a.source)}">
|
|
120
|
+
<span class="sugtext">${o(a.text)}</span>${i}<button class="sugdismiss" data-act="sugg-dismiss" data-sugg="${o(a.id)}" data-tip="本 session 不再提示这条(内存态,重开面板恢复)">不再提示</button>
|
|
121
|
+
</div>`}).join("")}function zs(e){const t=is(e),s=e.todos.some(v=>v.status==="in_progress")?"第一条进行中 todo(来源:transcript 的 TaskCreate/TaskUpdate 事件)":"最新用户提示摘要(本会话暂无进行中 todo)",a=kt(e.currentAction),i=Tt(e),c=e.__mock_note?`<span class="mockchip" data-tip="${o(e.__mock_note)}">MOCK</span>`:"",l=e.waiting?`<div class="nwait" data-tip="${o(`未决 ${e.waiting.kind==="permission"?"PermissionRequest":"Notification"} 事件,发生于 ${e.waiting.since}`)}">等你:${o(e.waiting.message)}</div>`:"",d=i?`<span data-tip="${o([i.totalTokens!==void 0?`本轮总 token(harness 自报) = ${i.totalTokens}`:i.contextTotal!==void 0?`本轮 context(harness 自报) = ${i.contextTotal.value}`:`本轮累计 input(harness 累计值差分) = ${i.inputTotalTokens??"—"}`,i.costUsd===void 0?"":"$ 按内置价目表换算(约)"].filter(v=>v!=="").join(`
|
|
122
|
+
`))}">本轮 ${o(oe(i))}</span>`:"",u=a!==null?`<div class="ndoing">正在:<b>${o(a)}</b>${d===""?"":` · ${d}`}</div>`:d===""?"":`<div class="ndoing">消耗:${d}</div>`,f=e.agentQuote?`<div class="nquote" data-tip="agent 自述原话(transcript assistant 文本块);引用,不生成">「${o(e.agentQuote)}」</div>`:"";return`<div class="now">
|
|
123
|
+
${l}
|
|
124
|
+
<div class="ntask" data-tip="${o(s)}">${t===null?'<span class="muted">(本会话暂无任务信息)</span>':o(t)}${c}</div>
|
|
125
|
+
${u}
|
|
126
|
+
${f}
|
|
127
|
+
</div>`}function Zs(e,t){const n=e.taskWorkflow;if(n===void 0)return zs(e);const s=ns(e),a=s===null?'<div class="wflead"><span class="muted">目标不可用</span></div>':`<div class="wflead" data-tip="来源:${o(s.fact.source)}"><span class="wflabel">${s.label}</span>${o(s.fact.text)}${s.label==="最新指令"?'<span class="muted wfgoalna"> · 目标不可用</span>':""}</div>`;let i;if(n.plan.availability==="missing"){const E=n.plan.toolGate;if(E===void 0)i='<div class="wfplan"><span class="wflabel">Agent 声明计划</span><div class="cfgnote">Agent 尚未提供结构化计划</div></div>';else{const I=E.model??"未观察到",R=E.affected==="known"?`(本会话模型 ${I})`:`(本会话模型 ${I},是否受影响未知)`,z=`Claude Code ${E.harnessVersion} 自 ${E.since} 起对 Opus 4.8 / Sonnet 5 / Fable 5 / Mythos 5 及更新模型默认不提供计划工具${R}。启用:${E.enable};或安装 Plan Protocol:${_t("cc","<项目>",t.wingmanVersion)}`;i=`<div class="wfplan"><span class="wflabel">Agent 声明计划</span><div class="cfgnote">Agent 尚未提供结构化计划</div><div class="cfgnote wfgate" data-tip="来源:transcript version / message.model;Claude Code CHANGELOG 2.1.233">${o(z)}${J(t.wingmanVersion)}。若已设置该开关,则 Agent 只是没有建计划。</div></div>`}}else if(n.plan.availability==="unavailable")i=`<div class="wfplan"><span class="wflabel">Agent 声明计划</span><div class="cfgnote">计划来源不可用 · ${o(e.harness)} · ${o(n.plan.reason)}</div></div>`;else{const E=n.plan.steps.length>0&&n.plan.steps.every(R=>R.status==="completed"),I=n.plan.steps.map(R=>`<div class="wfstep ${R.status}"><span class="mk">${Ie[R.status]}</span><span>${o(R.text)}</span></div>`).join("");i=`<div class="wfplan"><span class="wflabel">Agent 声明计划</span><span class="wfsource">${o(as(n.plan))}</span>${E?'<span class="statechip">Agent 标记完成</span>':""}<div class="wfsteps">${I}</div></div>`}const c=n.plan.availability==="missing"?ea(e.traces):"",l=ss(e),d=l.length===0?"":`<div class="wfcurrent"><span class="wflabel">${l.length>1?"当前点(并行)":"当前点"}</span>${l.map(o).join(" · ")}</div>`,u=na(e,t),f=ta(e,t),v=n.feedback,g=v.state==="needs_user"?`${v.message??"收到显式反馈请求"} · ${v.since}`:v.state==="activity_resumed_unknown"?"检测到活动恢复":v.state==="no_open_request"?"当前未观察到待处理请求":v.reason,S=`<div class="wffeedback${v.state==="needs_user"?" urgent":""}"><span class="wflabel">需要你</span>${o(g)}</div>`,y=n.execution,A=y.failureCount>0?` · ${y.failureCount} 失败`:"",w=y.currentAction?.text,h=w===void 0?"":` · 正在:${o(w)}`,C=`<div class="wfevidence rawsec">
|
|
128
|
+
<button class="rawhead" data-act="evidence">${t.evidenceOpen?"▾":"▸"} 执行证据 · ${y.evidenceCount} 条${A}${h}</button>
|
|
129
|
+
<div class="rawbody${t.evidenceOpen?" open":""}">${t.evidenceOpen?sa(e,t):""}</div>
|
|
130
|
+
</div>`,W=e.__mock_note?`<span class="mockchip" data-tip="${o(e.__mock_note)}">MOCK</span>`:"";return`<div class="taskflow">${a}${W}${i}${c}${d}${f}${u}${S}${C}</div>`}function ea(e){const t=e.flatMap(s=>s.nodes.flatMap(a=>a.steps)).filter(s=>s.ts!==void 0).sort((s,a)=>a.ts.localeCompare(s.ts)).slice(0,3);return t.length===0?"":`<div class="wfrecent"><span class="wflabel">最近步骤</span>${t.map(s=>{const a=s.detail.length<=60?s.detail:`${s.detail.slice(0,59)}…`,i=s.endTs===void 0?Number.NaN:Date.parse(s.endTs)-Date.parse(s.ts),c=Number.isFinite(i)&&i>=0?` · ${ve(i)}`:"",l=s.isError?" · 失败":"",d=[s.toolName,a].filter(u=>u!=="").join(" · ");return`<span class="wfrecent-step" data-tip="来源:transcript / hook tool event">${o(d)}${c}${l}</span>`}).join("")}</div>`}function ta(e,t){const n=e.project?.root;if(n===void 0)return"";if(t.projects===null)return`<div class="wfproject"><span class="wflabel">项目</span><code>${o(n)}</code><span class="muted">项目载荷载入中</span></div>`;const s=t.projects.projects.find(l=>l.root===n);if(s===void 0)return`<div class="wfproject"><span class="wflabel">项目</span><code>${o(n)}</code></div>`;if("payloadUnavailable"in s)return`<div class="wfproject"><span class="wflabel">项目</span><span>${o(s.title.text)}</span><span class="wfsource">${o(s.title.source)}</span><span class="muted">项目载荷不可用</span><button class="wfproject-link" data-act="project-card-link" data-root="${o(n)}" type="button">查看项目</button></div>`;const a=s.plan.availability==="missing"?"没有 .wingman/plan.md":s.currentPoints.length>0?s.currentPoints.map(l=>l.path.join(" → ")).join(" · "):s.currentPointEmptyText,i=s.sessions.find(l=>l.harness===e.harness&&l.id===e.sessionId),c=i?.attachedTo!==void 0?`<span>本会话:归属</span><button class="project-crumb wfproject-node" data-tip="${o(i.attachedTo.replaceAll(" > "," → "))}" data-act="project-node-link" data-node-target="${Be(n,i.attachedTo)}" type="button">${o(i.attachedTo.replaceAll(" > "," → "))}</button>`:i?.unattachedReason===void 0?"":`<span>本会话:未关联(${o(i.unattachedReason)})</span>`;return`<div class="wfproject"><span class="wflabel">项目</span><span>${o(s.title.text)}</span><span class="wfsource">${o(s.title.source)}</span>${a===void 0?"":`<span>当前点:${o(a)}</span>`}${c}<button class="wfproject-link" data-act="project-card-link" data-root="${o(n)}" type="button">查看项目</button></div>`}function na(e,t){const n=e.taskWorkflow?.verification;if(n===void 0)return"";const s=n.checks,a=s.runs===0?"无可观察检查":`检查:${s.runs} 次运行 · ${s.failures} 次失败`,i=n.currentStep,c=i===void 0?"":` · 当前步骤 ${i.failures} 次失败 / ${i.runs} 次运行`,l=s.latestFailure,d=l===void 0?"":` · 最近失败:${o(l.brief??l.toolName)}${l.at===void 0?"":` ${o(l.at)}`}`,u=n.acceptance,f=u.state==="accepted"?`你已于 ${u.at} 标记`:u.state==="none"?"未标记":`不可用 · ${u.reason}`,v=e.sessionId===null?void 0:`${e.harness}:${e.sessionId}`,g=v===void 0||u.state==="unavailable"?"":`<button class="wfverify-action" data-act="task-accept" data-key="${o(v)}" data-value="${u.state!=="accepted"}" type="button">${u.state==="accepted"?"取消验收":"标记验收"}</button>`,S=v!==void 0&&t.taskError?.key===v?`<div class="task-error wfverify-error">${o(t.taskError.message)}</div>`:"";return`<div class="wfverify"><span class="wflabel">验证证据</span><span data-tip="来源:Agent 结构化计划步骤状态">Agent 标记完成:${n.agentMarkedComplete?"是":"否"}</span><span class="wfverify-sep">·</span><span data-tip="来源:Harness tool_result(is_error / exit_code)">${a}${c}${d}</span><span class="wfverify-sep">·</span><span data-tip="来源:本机 task-overlay.json accepted">用户验收:${o(f)}</span>${g}</div>${S}`}function sa(e,t){const n=e.traces.map(s=>{const a=s.todoId===null?void 0:e.todos.find(c=>c.id===s.todoId),i=a===void 0?"其他":a.content;return`<div class="evidencegroup"><div class="cfgnote">执行归属:${o(i)}</div>${qe(s,s.todoId??"__other__",t.nodeOpen)}</div>`}).join("");return n===""?'<div class="livenone">○ 尚无执行证据</div>':n}function aa(e){const t=cs(e.narrative),n=e.narrative?.turnUsages.length??0,s=(a,i,c)=>`<button class="vtab${e.view===a?" act":""}" data-act="view" data-view="${a}">${i}${c===null?"":` <span class="vcnt">${o(c)}</span>`}</button>`;return`<div class="vtabs">
|
|
131
|
+
${s("tasks","任务",t)}
|
|
132
|
+
${s("control","控制",null)}
|
|
133
|
+
${s("billing","账单",n>0?`${n} 轮`:null)}
|
|
134
|
+
</div>`}function ia(e){const t=e.ts!==void 0&&e.endTs!==void 0?ve(Date.parse(e.endTs)-Date.parse(e.ts)):e.endTs===void 0?"…":"",n=e.estTokens===void 0?"":` · 约 ${T(e.estTokens)}`,s=e.isError&&e.errorBrief!==void 0?`<span class="failchip">${o(e.errorBrief)}</span>`:"",a=e.agentId!==void 0?'<span class="ag">子 agent</span>':"";return`<div class="trs${e.isError?" bad":""}" data-tip="${o(`工具:${e.toolName}${e.ts===void 0?"":`
|
|
135
|
+
开始:${e.ts}`}${e.estTokens===void 0?"":`
|
|
136
|
+
约 token = 工具输入+结果字节 ÷ 3.5(估算)`}`)}">
|
|
137
|
+
<span class="cmd">${o(e.toolName)}</span>
|
|
138
|
+
${e.detail===""?"":`<span class="sdetail">${o(e.detail)}</span>`}
|
|
139
|
+
${s}${a}
|
|
140
|
+
<span class="dur">${o(t)}${o(n)}</span>
|
|
141
|
+
</div>`}function oa(e){const t=e.wait?.resolvedBy!==void 0,n=e.durationMs===void 0?"":`等了 ${ve(e.durationMs)}`,s=t?` · ${n===""?"":`${n} → `}${wt(e.wait?.resolvedBy??"")}`:" · 等待中…",a=[`${e.wait?.kind==="permission"?"PermissionRequest":"Notification"} 事件起止(hook 层观察)`,e.startTs===void 0?"":`开始:${e.startTs}`,t?`解除:${e.endTs??""}(事件 ${e.wait?.resolvedBy??""})`:"尚未解除"].filter(i=>i!=="").join(`
|
|
142
|
+
`);return`<div class="tr waitrow" data-tip="${o(a)}">
|
|
143
|
+
<span class="ic"></span>
|
|
144
|
+
<span class="trlabel">⏸ ${o(e.label)}:${o(e.wait?.message??"")}${o(s)}</span>
|
|
145
|
+
</div>`}function ra(e,t,n){if(e.phase==="wait")return oa(e);const s=e.steps.some(u=>u.endTs===void 0),a=e.durationMs===void 0?s?"…":"":ve(e.durationMs),i=e.estTokens===void 0?"":` · 约 ${T(e.estTokens)}`,c=e.steps.find(u=>u.isError&&u.errorBrief!==void 0),l=e.failed&&c!==void 0&&!n?`<span class="failchip">${o(c.errorBrief??"")}</span>`:"",d=n?e.steps.map(u=>ia(u)).join(""):"";return`<div class="tr${e.failed?" bad":s?" run":""}" data-act="node" data-key="${o(t)}" data-tip="${o(`阶段归类:工具类型规则(规则表公开);点击${n?"收起":"展开"}步骤${e.estTokens===void 0?"":`
|
|
146
|
+
约 token = 节点内步骤字节估算之和`}`)}">
|
|
147
|
+
<span class="ic"></span>
|
|
148
|
+
<span class="trlabel">${o(e.label)} · ${e.steps.length} 步</span>
|
|
149
|
+
${l}
|
|
150
|
+
<span class="dur">${o(a)}${o(i)}</span>
|
|
151
|
+
</div>${d===""?"":`<div class="steps">${d}</div>`}`}function qe(e,t,n){return`<div class="trace">${e.nodes.map((a,i)=>{const c=`${t}:${i}`;return ra(a,c,n[c]===!0)}).join("")}</div>`}function ca(e,t){return""}function la(e,t,n,s){const a=Et(e,n.todoOpen)&&t!==void 0&&t.nodes.length>0,i=t!==void 0&&t.nodes.length>0,c=e.status==="in_progress"&&i?a?"▾":"▸":Ie[e.status],l=rs(e,t),d=l===null?"":`<span class="ag" data-tip="${o(l==="子 agent"?`步骤归属含子代理(${e.agents.join(", ")});归属 = 时间窗 + Agent 跨度推断,归不准会进「其他」`:"步骤归属:主 agent(时间窗推断)")}">${o(l)}</span>`;return`<div class="td${e.status==="completed"?" done":e.status==="in_progress"?" doing":" todo"}">
|
|
152
|
+
<div class="tdr"${i?` data-act="todo" data-id="${o(e.id)}"`:""}>
|
|
153
|
+
<span class="mk${e.status==="in_progress"?" doing":""}">${c}</span>
|
|
154
|
+
<span class="tdc">${e.status==="in_progress"?`<b>${o(e.content)}</b>`:o(e.content)}</span>
|
|
155
|
+
${d}
|
|
156
|
+
${ca()}
|
|
157
|
+
</div>
|
|
158
|
+
${a&&t?qe(t,e.id,n.nodeOpen):""}
|
|
159
|
+
</div>`}function Pe(e,t){const n=t.traces.find(a=>a.todoId===null);if(!n||n.nodes.length===0)return"";const s=e.todoOpen.__other__!==!1;return`<div class="td doing other">
|
|
160
|
+
<div class="tdr" data-act="todo" data-id="__other__" data-tip="归不到具体 todo 的步骤进「其他」桶(无时间戳/无进行中 todo/多任务并行归不准);推断规则如实降级,不硬塞">
|
|
161
|
+
<span class="mk">${s?"▾":"▸"}</span>
|
|
162
|
+
<span class="tdc">其他(归不准的步骤)</span>
|
|
163
|
+
</div>
|
|
164
|
+
${s?qe(n,"__other__",e.nodeOpen):""}
|
|
165
|
+
</div>`}function da(e,t){return`<div class="sec first todolist">
|
|
166
|
+
<div class="cfgnote" data-tip="来源:assistant 文本里的 markdown 勾选清单(- [ ] / - [x]);会话没用工具清单时的降级展示,工具清单一旦出现立即让位">文本清单(agent 手写)</div>
|
|
167
|
+
${(e.textTodos??[]).map(s=>`<div class="td${s.checked?" done":" todo"}">
|
|
168
|
+
<div class="tdr"><span class="mk">${s.checked?"✓":"○"}</span><span class="tdc">${o(s.content)}</span></div>
|
|
169
|
+
</div>`).join("")}${Pe(t,e)}
|
|
170
|
+
</div>`}function ua(e,t){const n=t.narrative;let s="";return n?.taskWorkflow!==void 0?s="":n&&n.todos.length>0?s=`<div class="sec first todolist">${n.todos.map(i=>la(i,n.traces.find(c=>c.todoId===i.id),t,e.harness)).join("")}${Pe(t,n)}</div>`:n&&(n.textTodos?.length??0)>0?s=da(n,t):n&&yt(n)?s=`<div class="sec first">
|
|
171
|
+
<div class="cfgnote">${e.harness==="dsh"?"该 harness 不产生任务清单 —— 以下为执行轨迹":"本次会话未使用任务清单 —— 以下为执行轨迹"}</div>
|
|
172
|
+
${Pe(t,n)}
|
|
173
|
+
</div>`:s=`<div class="sec first"><div class="livenone">○ 暂无叙事数据 —— 接线(<code>${o(de(e.harness,t.wingmanVersion))}</code>${J(t.wingmanVersion)},接线后重启该 harness 生效)并跑一轮对话后,这里按任务展示执行轨迹</div></div>`,s}function pa(e,t,n){return`<div class="sec rawsec">
|
|
174
|
+
<button class="rawhead" data-act="raw" data-tip="逐条 hook 事件原始流(0.2 的实况视图);默认折叠">${n.rawOpen?"▾":"▸"} 原始事件</button>
|
|
175
|
+
<div class="rawbody${n.rawOpen?" open":""}">${Ks(e,t,n.wingmanVersion,n.sessions.length>=1)}</div>
|
|
176
|
+
</div>`}function fa(e,t){const n=t.narrative?.turnUsages??[],s=n.map(i=>va(i,e.harness)).join(""),a=n.length>0?`<div class="ubox">${s}</div>`:e.harness==="codex"&&t.narrative!==null?'<div class="livenone">○ 已收到本会话事件,但尚未解析到 Codex usage 数据 —— 这不代表零消耗,此处不显示估算值</div>':e.harness==="codex"?'<div class="livenone">○ 尚未收到 Codex session/usage 数据 —— 请先在 Codex 输入 <code>/hooks</code> 确认 Wingman 为 Trusted 且 Enabled</div>':'<div class="livenone">○ 本会话尚未收到可读的 usage 数据 —— 有精确来源后才会逐轮列出,此处不作估算</div>';return`<div class="sec first">
|
|
177
|
+
<div class="label">${e.harness==="codex"?"每轮消耗 · Codex token_count 自报精确值;本地事件不提供订阅美元账单":"每轮消耗 · usage 三字段为 harness 自报精确值"}</div>
|
|
178
|
+
${a}
|
|
179
|
+
</div>
|
|
180
|
+
${Cs(e,t)}
|
|
181
|
+
${Ms(e)}`}function va(e,t){const n=e.ts===void 0?"":e.ts.slice(11,19),s=e.costUsd===void 0?"":`<span class="ucost">≈ ${o(St(e.costUsd))}</span>`,a=e.reasoningOutputTokens===void 0?"":` · reasoning ${T(e.reasoningOutputTokens)}(含在 out 内)`,i=jt(e),c=["usage 原文(harness 自报,精确):",t==="codex"?`本轮累计 input(累计值相邻 turn 差) ${e.inputTotalTokens??"—"} · 非缓存 ${e.inputTokens} · cache_write 字段 ${e.cacheCreationInputTokens} · 缓存读 ${e.cacheReadInputTokens} · output ${e.outputTokens}${a}`:`input ${e.inputTokens} · 缓存写 ${e.cacheCreationInputTokens} · 缓存读 ${e.cacheReadInputTokens} · output ${e.outputTokens}${a}`,e.contextTotal===void 0?"":`本轮 context = 三个 input 字段之和 = ${e.contextTotal.value}`,e.totalTokens===void 0?"":`本轮总 token(自报) = ${e.totalTokens}`,e.status==="aborted"?"本轮状态 = 中断(已保留中断前自报消耗)":"",e.status==="incomplete"?"本轮状态 = 未收口(仅显示目前已自报消耗)":"",t==="codex"?"$:ChatGPT/Codex 订阅实际账单不在本地事件中,不换算":e.costUsd===void 0?"$:该模型不在内置价目表,不换算(宁缺勿编)":"$ 按内置价目表换算(缓存读 ×0.1、缓存写 ×1.25/×2),标 ≈"].filter(l=>l!=="").join(`
|
|
182
|
+
`);return`<div class="urow" data-tip="${o(c)}">
|
|
183
|
+
<span class="utime">${o(n)}</span>
|
|
184
|
+
${e.model===void 0?"":`<span class="chip">${o(e.model)}</span>`}
|
|
185
|
+
${e.status==="aborted"?'<span class="chip">中断</span>':""}
|
|
186
|
+
${e.status==="incomplete"?'<span class="chip">未收口</span>':""}
|
|
187
|
+
<span class="unums">${t==="codex"?`累计 in ${e.inputTotalTokens===void 0?"—":o(T(e.inputTotalTokens))} · 非缓存 ${o(T(e.inputTokens))} · cache_write ${o(T(e.cacheCreationInputTokens))} · 缓读 ${o(T(e.cacheReadInputTokens))} · out ${o(T(e.outputTokens))}`:`in ${o(T(e.inputTokens))} · 缓写 ${o(T(e.cacheCreationInputTokens))} · 缓读 ${o(T(e.cacheReadInputTokens))} · out ${o(T(e.outputTokens))}`}${e.reasoningOutputTokens===void 0?"":` <small>(reasoning ${o(T(e.reasoningOutputTokens))})</small>`}</span>
|
|
188
|
+
<span class="utot">${i===null?"Σ —":e.totalTokens!==void 0||e.contextTotal!==void 0?`Σ ${o(T(i))}`:`Σ input ${o(T(i))}`}</span>
|
|
189
|
+
${s}
|
|
190
|
+
</div>`}function Rt(e){const t=gs(e);return`<div class="feedbackfoot">
|
|
191
|
+
<a class="feedbacklink" data-act="feedback" href="${o(t)}" target="_blank" rel="noreferrer">报告问题</a>
|
|
192
|
+
<span>点击会向 Tally 发送白名单复现提示,服务商也可能处理连接信息;问题正文和截图仅在你提交时发送。请勿提交 prompt、源码、路径、账号信息或凭证。</span>
|
|
193
|
+
<a href="mailto:${Ge}" target="_blank" rel="noreferrer">${Ge}</a>
|
|
194
|
+
</div>`}function Qe(e,t){return`<div class="empty-state">${Ps(e,t)}${Rt()}</div>`}const ma={pending:"○",in_progress:"●",completed:"✔",cancelled:"—",checkpoint:"?"},$a={pending:"待做",in_progress:"进行中",completed:"Agent/用户标记完成",cancelled:"已取消",checkpoint:"检查点"},ga={not_installed:"协议未安装",installed:"协议已安装",installed_not_loaded:"已安装但未加载",plan_present:"计划已存在",session_wrote_plan:"本会话已写计划"};function Be(e,t){return`project-node-${encodeURIComponent(`${e}:${t}`)}`}function ee(e){return`project-card-${encodeURIComponent(e)}`}function ha(e,t){return`<div class="project-protocols">${["cc","codex","dsh"].map(a=>{const i=e.protocol[a],c=e.sessions.find(f=>f.harness===a&&f.compliance.level==="session_wrote_plan")?.compliance,l=[i.message,c?.writeSummary,c?.timing?.text,i.state==="not_installed"&&t.wingmanVersion===null?"Wingman 版本未知,安装命令未钉版本":void 0].filter(f=>f!==void 0).join(" · "),d=`<span class="project-protocol-chip ${i.state}"${l===""?"":` data-tip="${o(l)}"`}>${o(j[a])} · ${o(ga[i.state])}</span>`;if(i.state!=="not_installed"){const f=i.state==="installed_not_loaded"?`<span class="project-protocol-note">${o(i.message??"dsh 指令加载插件已禁用,见控制页开关")}</span>`:"";return`<div class="project-protocol-row">${d}${f}</div>`}const u=_t(a,e.root,t.wingmanVersion);return`<div class="project-protocol-row">${d}<button class="project-protocol-copy" data-act="protocol-copy" data-command="${o(u)}" data-tip="${o(u)}" type="button">复制安装命令</button></div>`}).join("")}</div>`}function ba(e){const t=e.sessionPlan;if(t===void 0)return"";if(t.availability==="missing")return`<div class="project-session-plan"><span class="project-source">会话计划 · ${o(t.source)}</span><span class="muted">未提供结构化计划</span></div>`;if(t.availability==="unavailable")return`<div class="project-session-plan"><span class="project-source">会话计划 · ${o(t.source)}</span><span class="muted">不可用:${o(t.reason)}</span></div>`;const n=t.steps.map(s=>`<li class="${s.status}"><span>${Ie[s.status]}</span> ${o(s.text)}</li>`).join("");return`<div class="project-session-plan"><span class="project-source">会话计划 · ${o(t.source)} · revision ${t.revision}</span><ul>${n}</ul></div>`}function ya(e,t=Date.now()){const n=ue(e),s=js(e),a=Es(e.sessionPlan),i=e.sessionPlan?.availability==="available"&&a!==void 0?`会话计划 revision ${e.sessionPlan.revision} · Agent 标记 ${a.completed}/${a.total} 完成`:e.sessionPlan?.availability==="unavailable"?`会话计划不可用:${e.sessionPlan.reason}`:"未提供结构化计划",c=e.lastActivity===void 0?"":`<span class="task-activity" data-tip="${o(`绝对时间:${e.lastActivity} · 来源:hook 事件`)}">最近活动:${o(As(e.lastActivity,t))}</span>`,l=e.feedback?.state==="needs_user"?`<span class="task-feedback">需要你:${o(e.feedback.message??"收到显式反馈请求")} · ${o(e.feedback.since)}</span>`:"",d=e.checks===void 0?"":`<span class="task-checks" data-tip="来源:Harness tool_result(is_error / exit_code)">${e.checks.runs===0?"无可观察检查":`检查 ${e.checks.failures} 次失败 / ${e.checks.runs} 次运行`}</span>`,u=e.acceptance===void 0?"":`<span class="task-accept">${e.acceptance.state==="accepted"?`已验收 ${o(e.acceptance.at)}`:e.acceptance.state==="none"?"未验收":`验收不可用:${o(e.acceptance.reason)}`}</span>`,f=e.attachedTo===void 0?`未关联:${e.unattachedReason??"未关联到步骤"}`:`归属:${e.attachedTo.replaceAll(" > "," → ")}`;return`<button class="task-card" data-act="project-session" data-harness="${e.harness}" data-session="${o(e.id)}" data-tip="${o(`session:${We(e.id)}`)}" type="button">
|
|
195
|
+
<span class="task-card-head"><span class="task-badge">${o(j[e.harness])}</span>${e.user.pinned?'<span class="task-pin-mark">置顶</span>':""}<span class="task-title">${o(s.text)}</span><span class="task-title-source">${o(s.source)}</span></span>
|
|
196
|
+
<span class="task-card-meta"><span class="task-status ${n.kind}">${n.label}</span>${n.agentComplete?'<span class="task-status complete">Agent 标记完成</span>':""}<span class="task-progress">${o(i)}</span>${c}${d}${u}</span>
|
|
197
|
+
${l}<span class="task-context">${o(f)}</span>
|
|
198
|
+
</button>`}function Mt(e){return`${e.harness}:${e.id}`}function ka(e){if(e===void 0)return"";const t=e.clipboard==="copied"?"命令已复制":e.clipboard==="failed"?"命令复制失败":"该 Harness 无按会话恢复命令",n=e.activation.activated===null?"未设置回跳应用":e.activation.activated?`已切到 ${e.activation.name}`:`切换失败:${e.activation.reason}`,s=e.clipboard==="unavailable"?" · dsh 没有按会话恢复的命令,请回到原终端继续":"",a=e.activationSource??(e.activation.activated===null?"GET /api/return-target":"POST /api/return"),i=`来源:剪贴板写入结果${e.clipboard==="unavailable"?"(该 Harness 无恢复命令,未写入)":""};${a} 返回或请求失败;Harness 恢复命令能力`;return`<div class="task-return-result" role="status" data-tip="${o(i)}">${o(`${t} · ${n}${s}`)}</div>`}function wa(e,t){const n=Mt(e),s=t.taskMenuOpen===n,a=`<button class="task-menu-button" data-act="task-menu" data-key="${o(n)}" type="button" aria-label="任务卡菜单" aria-expanded="${s}">⋯</button>`;if(!s)return a;const i=Ot(e),c=t.taskResumeOpen!==n?"":"unavailable"in i?`<div class="task-resume-unavailable">${o(i.unavailable)}</div>`:`<div class="task-resume-command"><code>${o(i.command)}</code><button data-act="task-copy" data-key="${o(n)}" data-command="${o(i.command)}" type="button">复制</button><div class="task-resume-note">${o(i.note)}</div></div>`,l=e.acceptance===void 0||e.acceptance.state==="unavailable"?"":`<button data-act="task-accept" data-key="${o(n)}" data-value="${e.acceptance.state!=="accepted"}" type="button">${e.acceptance.state==="accepted"?"取消验收":"标记验收"}</button>`;return`${a}<div class="task-menu" data-task-menu="${o(n)}">
|
|
199
|
+
<label>重命名<input data-act="task-rename-input" data-key="${o(n)}" value="${o(e.user.title??"")}" placeholder="清空后恢复自动标题"></label>
|
|
200
|
+
<div class="task-menu-actions"><button data-act="task-pin" data-key="${o(n)}" data-value="${!e.user.pinned}" type="button">${e.user.pinned?"取消置顶":"置顶"}</button><button data-act="task-hide" data-key="${o(n)}" data-value="${!e.user.hidden}" type="button">${e.user.hidden?"取消隐藏":"隐藏"}</button>${l}<button data-act="task-resume" data-key="${o(n)}" type="button">回到会话</button></div>
|
|
201
|
+
${ka(t.taskReturnResults?.[n])}${c}
|
|
202
|
+
</div>`}function Ve(e,t,n,s,a=!1){const i=Mt(e),c=a?`<button class="task-unhide" data-act="task-hide" data-key="${o(i)}" data-value="false" type="button">取消隐藏</button>`:"",l=t.taskError?.key===i?`<div class="task-error">${o(t.taskError.message)}</div>`:"";return`<div class="${s}${a?" task-card-hidden":""}">${ya(e,n)}${wa(e,t)}${c}${l}${ba(e)}</div>`}function Nt(e,t,n,s,a){if(e.length===0)return"";const i=n.hiddenOpen[t]===!0,c=i?He(e).map(l=>Ve(l,n,s,a,!0)).join(""):"";return`<div class="task-hidden-group"><button class="task-hidden-toggle" data-act="task-hidden-toggle" data-group="${o(t)}" type="button">已隐藏 ${e.length} 张 · ${i?"收起":"显示"}</button>${c}</div>`}function It(e){return e.children.length===0?1:e.children.reduce((t,n)=>t+It(n),0)}function Dt(e){return e.status==="in_progress"||e.children.some(Dt)}function Oe(e,t,n,s){const a=e.sessions.filter(w=>w.attachedTo===t.key),i=Fe(a),c=He(Ue(i.visible,n.taskFilter)),l=i.visible.length-c.length,d=`${e.root}:${t.key}`,u=t.children.length>0&&(t.status==="completed"||t.status==="cancelled"||!Dt(t)),f=u?` (${It(t)})`:"",v=t.verification?`<div class="project-verify">计划验收:${o(t.verification)}</div>`:"",g=c.map(w=>Ve(w,n,s,"project-session-wrap task-card-wrap")).join(""),S=l===0?"":`<div class="task-hidden">${l} 张卡被筛选隐藏</div>`,y=Nt(i.hidden,d,n,s,"project-session-wrap task-card-wrap"),A=u?"":t.children.map(w=>Oe(e,w,n,s)).join("");return`<li class="project-node ${t.status}${u?" collapsed":""}" id="${Be(e.root,t.key)}" data-project-node="${o(t.key)}">
|
|
203
|
+
<div class="project-node-line"><span class="project-mark" data-tip="${o($a[t.status])}">${ma[t.status]}</span><span class="project-node-text" data-tip="${o(t.text)}">${o(t.text)}${f}</span></div>
|
|
204
|
+
${v}${g}${S}${y}${A===""?"":`<ul>${A}</ul>`}
|
|
205
|
+
</li>`}function we(e,t,n,s){if(e.length===0)return'<div class="project-empty">没有观察到会话</div>';const a=Fe(e),i=He(Ue(a.visible,n.taskFilter)),c=a.visible.length-i.length,l=i.map(f=>Ve(f,n,s,"task-card-wrap")).join(""),d=c===0?"":`<div class="task-hidden">${c} 张卡被筛选隐藏</div>`,u=Nt(a.hidden,t,n,s,"task-card-wrap");return l===""&&u===""?`<div class="project-empty">没有符合筛选的任务卡(${c} 张被筛掉)</div>`:`${l===""?"":`<div class="task-card-list">${l}</div>`}${d}${u}`}function Ta(e){const t=e.revision===void 0?"":`revision ${e.revision}`,n=e.mtime===void 0?"":`文件时间 ${e.mtime}`,s=e.lastWriter?`最近写入者:${j[e.lastWriter.harness]} ${e.lastWriter.label} · ${e.lastWriter.at}`:"最近写入者:外部编辑/未观察到";return[t,n,s].filter(a=>a!=="").map(o).join(" · ")}function Sa(e,t){const n=e.facts.filter(i=>/步骤下当前没有观察到活跃会话$/u.test(i)),s=e.facts.filter(i=>!/步骤下当前没有观察到活跃会话$/u.test(i)),a=[{key:"contradictions",label:`父子矛盾 ${e.contradictions.length} 处`,items:e.contradictions.map(i=>i.text)},{key:"no-active-session",label:`进行中步骤下无活跃会话 ${n.length} 处`,items:n},{key:"other",label:`其他 ${s.length} 条`,items:s}].filter(i=>i.items.length>0);return a.length===0?"":`<div class="project-facts">${a.map(i=>{const c=`${e.root}:${i.key}`,l=t.factsOpen[c]===!0,d=l?`<div class="project-facts-items">${i.items.map(u=>`<div class="project-facts-item">${o(u)}</div>`).join("")}</div>`:"";return`<div class="project-facts-group"><button class="project-facts-toggle" data-act="facts-toggle" data-group="${o(c)}" type="button" aria-expanded="${l}">${l?"▾":"▸"} ${i.label}</button>${d}</div>`}).join("")}</div>`}function ja(e,t,n){if("payloadUnavailable"in e)return`<section class="project-card unavailable" id="${ee(e.root)}" data-project-root="${o(e.root)}"><div class="project-title">${o(e.title.text)}</div><div class="project-error">项目载荷不可用</div></section>`;const s=`<div class="project-card-head"><div><span class="project-title">${o(e.title.text)}</span><span class="project-source">${o(e.title.source)}</span></div><code class="project-root">${o(e.root)}</code></div>`,a=e.presence==="remembered"&&e.sessions.length===0?`<div class="project-presence">${e.seenSinceStart?"当前无活跃会话(此项目的会话已不在面板)":"当前无活跃会话(Wingman 启动后尚未收到此项目的事件)"}</div>`:"",i=ha(e,t),c=`<div class="project-meta">${Ta(e)}</div>`,l=e.sessions.filter(h=>h.attachedTo===void 0);if(e.plan.availability==="missing")return`<section class="project-card missing" id="${ee(e.root)}" data-project-root="${o(e.root)}">${s}${a}${i}${c}<div class="project-l0">此项目没有 <code>.wingman/plan.md</code>,手写一份即可生效</div><div class="project-section"><div class="project-label">项目会话</div>${we(e.sessions,`${e.root}:__all`,t,n)}</div></section>`;if(e.plan.availability==="unavailable"){const h=e.plan.line===void 0?"":` · 第 ${e.plan.line} 行`,C=e.plan.lastGood,W=C===void 0?"":`<div class="project-last-good"><div class="project-label">上次可解析版本 · revision ${C.revision} · ${o(C.mtime)}</div>${C.nodes.length===0?'<div class="project-empty">上次版本没有步骤</div>':`<ul class="project-tree">${C.nodes.map(E=>Oe(e,E,t,n)).join("")}</ul>`}</div>`;return`<section class="project-card unavailable" id="${ee(e.root)}" data-project-root="${o(e.root)}">${s}${a}${i}${c}<div class="project-error">计划不可用:${o(e.plan.reason)}${h}</div>${W}<div class="project-section"><div class="project-label">未关联到步骤的会话</div>${we(e.sessions,`${e.root}:__all`,t,n)}</div></section>`}const d=e.goal?`<div class="project-goal"><span class="project-label">目标</span>${o(e.goal)}</div>`:"",u=e.currentPoints.length===0?`<div class="project-empty">${o(e.currentPointEmptyText??e.currentPointLabel)}</div>`:e.currentPoints.map(h=>`<button class="project-crumb" data-tip="${o(h.path.join(" → "))}" data-act="project-node-link" data-node-target="${Be(e.root,h.key)}">${o(h.path.join(" → "))}</button>`).join(""),f=e.plan.nodes.length===0?'<div class="project-empty">计划没有步骤</div>':`<ul class="project-tree">${e.plan.nodes.map(h=>Oe(e,h,t,n)).join("")}</ul>`,v=e.checkpoints.length===0?'<span class="muted">无</span>':`<div class="project-checkpoints">${e.checkpoints.map(h=>`<div class="project-checkpoint" data-tip="${o(h.path.join(" → "))}">${o(h.path.join(" → "))}</div>`).join("")}</div>`,g=e.counts,S=e.completionLabel?`<div class="project-complete">${o(e.completionLabel)}</div>`:"",y=Sa(e,t),A=e.plan.higherPlanPaths.length?`<div class="project-facts">上层还存在计划文件:${e.plan.higherPlanPaths.map(o).join(" · ")}</div>`:"",w=e.plan.ignoredLineCount>0?`<span class="muted" data-tip="${o(e.plan.ignoredLines.map(h=>`第 ${h.line} 行:${h.preview}`).join(`
|
|
206
|
+
`))}"> · 忽略 ${e.plan.ignoredLineCount} 行</span>`:"";return`<section class="project-card" id="${ee(e.root)}" data-project-root="${o(e.root)}">${s}${a}${i}${c}${d}<div class="project-section"><div class="project-label">${o(e.currentPointLabel)}</div><div class="project-points">${u}</div></div><div class="project-section"><div class="project-label">计划树${w}</div>${f}</div><div class="project-section"><div class="project-label">检查点</div>${v}</div><div class="project-counts">Agent/用户标记 · 待做 ${g.pending} · 进行中 ${g.inProgress} · 完成 ${g.completed} · 取消 ${g.cancelled} · 检查点 ${g.checkpoint}</div>${S}${y}${A}<div class="project-section"><div class="project-label">未关联到步骤的会话</div>${we(l,`${e.root}:__unassigned`,t,n)}</div></section>`}function Ea(e){const t=[["all","全部"],["cc",j.cc],["codex",j.codex],["dsh",j.dsh]],n=[["all","全部"],["waiting","等你"],["active","进行中"],["ended","已结束"]],s=(a,i,c)=>c.map(([l,d])=>`<button class="task-filter-chip${i===l?" act":""}" data-act="task-filter" data-kind="${a}" data-value="${l}" type="button" aria-pressed="${i===l}">${o(d)}</button>`).join("");return`<div class="task-filters"><div class="task-filter-group"><span>Harness</span>${s("harness",e.harness,t)}</div><div class="task-filter-group"><span>状态</span>${s("status",e.status,n)}</div></div>`}function _a(e,t=te,n=Date.now(),s={...Ct,taskFilter:t}){if(e===null)return'<div class="projects-empty">项目载荷尚不可用</div>';const a=e.memory===void 0||s.projectMemoryDismissed?"":`<div class="project-memory-warning" role="status"><span>${o(e.memory.unavailable)}</span><button data-act="project-memory-dismiss" type="button" aria-label="关闭项目记忆提示">关闭</button></div>`;if(e.projects.length===0)return`${a}<div class="projects-empty">尚未观察到带工作目录的会话</div>`;const i=e.projects.flatMap(v=>"payloadUnavailable"in v?[]:v.sessions),c=Fe(i).visible,l=Ue(c,t).length,d=c.length-l,u=s.taskFilter===t?s:{...s,taskFilter:t},f=d===0?"":l===0?`<div class="task-filter-summary">没有符合筛选的任务卡(${d} 张被筛掉)</div>`:`<div class="task-filter-summary">${d} 张卡被筛选隐藏</div>`;return`${a}${Ea(t)}${f}<div class="projects">${e.projects.map(v=>ja(v,u,n)).join("")}</div>`}function Aa(e,t,n,s,a,i=t.harness,c=null,l=Date.now()){const d=i==="projects",u=t.__mock_note?`<span class="badge" data-tip="${o(t.__mock_note)}">MOCK 演示数据</span>`:"",f=t.harnessVersion?` ${t.harnessVersion}`:"",v=d?"跨 Harness 项目计划 · 本机只读":`${j[t.harness]}${f} · 扫描于 ${Qt(t.scannedAt)}`,g=a.narrative,S=g&&yt(g)?Zs(g,a):"",y=ot(s),A=y==="grace"||y==="expired";return{top:`<div class="head">
|
|
207
|
+
<span class="dot"></span>
|
|
208
|
+
<span class="title">Wingman</span>
|
|
209
|
+
<span class="meta">${o(v)}</span>
|
|
210
|
+
${d?"":u}
|
|
211
|
+
<button class="collapse" data-act="toggle">收起 ▴</button>
|
|
212
|
+
</div>
|
|
213
|
+
${Us(s)}${Ls(e,i,Sn(n.entries))}`,sessions:d?"":`${Js(a,t.harness)}${Gs(a,t.harness)}${Qs(a,t.harness)}${g?.taskWorkflow===void 0?Xs(a,t.harness):""}`,now:d?"":S,viewTabs:d?"":aa(a),tasks:ua(t,a),rawEvents:pa(t,n,a),control:Is(t)+Ds(a),billing:fa(t,a),projects:_a(c,a.taskFilter,l,a),bottom:`<div class="suggslot">${Ys(a,t.harness)}</div>
|
|
214
|
+
${A?"":`<div class="licfoot">${Lt("licfootlink")}</div>`}
|
|
215
|
+
${Rt(t)}`}}function xa(e,t){const n=e.narratives?.[t]??null,s=fe(n,e.sessionSel?.[t]);return{wingmanVersion:e.wingmanVersion,view:e.view??Ct.view,narrative:n!==null&&s!==null?n.states[s]??null:null,projects:e.projects??null,anatomyLoadedAt:e.anatomyLoadedAt??null,anatomyRefreshFailed:e.anatomyRefreshFailed??!1,projectMemoryDismissed:e.projectMemoryDismissed??!1,startedAt:n?.startedAt??null,notices:n?.notices??[],noticeDismissed:e.noticeDismissed??{},sessions:n?.sessions??[],selectedSession:s,sessionSeen:e.sessionSeen??{},suggHidden:e.suggHidden??{},island:e.island??!1,todoOpen:e.todoOpen??{},nodeOpen:e.nodeOpen??{},evidenceOpen:e.evidenceOpen??!1,rawOpen:e.rawOpen??!1,taskFilter:e.taskFilter??te,taskMenuOpen:e.taskMenuOpen??null,taskResumeOpen:e.taskResumeOpen??null,returnTargets:e.returnTargets??null,returnSettingsDismissed:e.returnSettingsDismissed??!1,returnTargetSaving:e.returnTargetSaving??!1,returnTargetError:e.returnTargetError??null,taskReturnResults:e.taskReturnResults??{},hiddenOpen:e.hiddenOpen??{},factsOpen:e.factsOpen??{},taskError:e.taskError??null}}function Pa(e){const t=e.license??null,n=e.flow?Fs(e.flow):"",s=e.licenseOpen&&t?qs(t,it,e.licenseRefreshing??!1,e.licenseRefreshResult??null,e.licenseCanSubscribe??!1):"",a=e.importResult?Ws(e.importResult):"",i=e.share?Bs(e.share):"";return`${n}${s}${a}${i}`}function Oa(e,t){const n=e.configs.find(f=>f.harness===e.active)??e.configs[0];if(!n)return null;const s=xa(e,n.harness),a=lt(e.live.entries,n.harness,n.capabilities.live,t),i=tt(n),c=i?`Σ ${D(i)} tok`:"Σ —",l=bt(e.narratives?.[n.harness]??null),d=ds(s.narrative,a,c,l,t),u=e.license??null;return{story:s,pill:Os(n,d),panel:Aa(e.configs,n,e.live,u,s,e.active,e.projects??null,t),overlays:Pa(e)}}function Xe(e,t){return{layout:e,visibility:"",pill:"",top:t,sessions:"",now:"","view-tabs":"",tasks:"","raw-events":"",control:"",billing:"",projects:"",bottom:"",overlays:""}}function La(e,t){if(e.error)return Xe("error",`<div class="wrap">${Qe(e.error,e.wingmanVersion)}</div>`);const n=Oa(e,t);return n?{layout:"panel",visibility:`${e.open?"open":"closed"}:${e.active==="projects"?"projects":n.story.view}`,pill:n.pill,top:n.panel.top,sessions:n.panel.sessions,now:n.panel.now,"view-tabs":n.panel.viewTabs,tasks:n.panel.tasks,"raw-events":n.panel.rawEvents,control:n.panel.control,billing:n.panel.billing,projects:n.panel.projects,bottom:n.panel.bottom,overlays:n.overlays}:Xe("empty",`<div class="wrap">${Qe(void 0,e.wingmanVersion)}</div>`)}function O(e,t){return`<div class="panel-region" data-panel-region="${e}">${t}</div>`}function Te(e){if(e.layout!=="panel")return e.top;const[t,n="tasks"]=e.visibility.split(":");return`<div class="wrap${t==="open"?" open":""}">
|
|
216
|
+
${O("pill",e.pill)}
|
|
217
|
+
<div class="panel">
|
|
218
|
+
${O("top",e.top)}
|
|
219
|
+
${O("sessions",e.sessions)}
|
|
220
|
+
${O("now",e.now)}
|
|
221
|
+
${O("view-tabs",e["view-tabs"])}
|
|
222
|
+
<div class="pane${n==="projects"?" act":""}" data-panel-view="projects">${O("projects",e.projects)}</div>
|
|
223
|
+
<div class="pane${n==="tasks"?" act":""}" data-panel-view="tasks">${O("tasks",e.tasks)}${O("raw-events",e["raw-events"])}</div>
|
|
224
|
+
<div class="pane${n==="control"?" act":""}" data-panel-view="control">${O("control",e.control)}</div>
|
|
225
|
+
<div class="pane${n==="billing"?" act":""}" data-panel-view="billing">${O("billing",e.billing)}</div>
|
|
226
|
+
${O("bottom",e.bottom)}
|
|
227
|
+
</div>
|
|
228
|
+
</div>${O("overlays",e.overlays)}`}const Ht=50;function Ca(e,t,n=Ht){const s={};let a;const i=()=>{a!==void 0&&(clearTimeout(a),a=void 0);const c=e(),l=Object.keys(c).filter(d=>s[d]!==c[d]);if(l.length!==0){t({regions:l,html:c});for(const d of l)s[d]=c[d]}};return{request(){a!==void 0&&clearTimeout(a),a=setTimeout(i,n)},flush:i,cancel(){a!==void 0&&clearTimeout(a),a=void 0}}}const M=pn(window.location.search);M&&document.documentElement.classList.add("island");const P={entries:[],connection:"connecting",replaying:!1},r={wingmanVersion:void 0,configs:[],active:"",open:!M,error:null,anatomyLoadedAt:null,anatomyRefreshFailed:!1,live:P,flow:null,license:null,licenseOpen:!1,licenseRefreshing:!1,licenseRefreshResult:null,licenseCanSubscribe:!1,importResult:null,share:null,view:"tasks",narratives:{},projects:null,projectMemoryDismissed:!1,taskFilter:te,taskMenuOpen:null,taskResumeOpen:null,hiddenOpen:{},factsOpen:{},taskError:null,sessionSel:{},sessionSeen:{},noticeDismissed:{},suggHidden:{},island:M,todoOpen:{},nodeOpen:{},evidenceOpen:!1,rawOpen:!1};let re=null,Se=0;const k=document.querySelector("#app");function me(){return k!==null&&typeof k.querySelector=="function"}function Ra(){if(!k||!me())return{panes:[],rawEvents:null};const e=Array.from(k.querySelectorAll("[data-panel-view]")).map(n=>[n.dataset.panelView??"",n.scrollTop]),t=k.querySelector('[data-panel-region="raw-events"] .feed');return{panes:e,rawEvents:t?.scrollTop??null}}function Ma(e){if(!k||!me())return;for(const[n,s]of e.panes){const a=k.querySelector(`[data-panel-view="${n}"]`);a&&(a.scrollTop=s)}const t=k.querySelector('[data-panel-region="raw-events"] .feed');t&&e.rawEvents!==null&&(t.scrollTop=e.rawEvents)}function Na(){if(!k||!me())return;k.querySelector(".wrap")?.classList.toggle("open",r.open);const e=r.active==="projects"?"projects":r.view??"tasks";for(const t of k.querySelectorAll("[data-panel-view]"))t.classList.toggle("act",t.dataset.panelView===e)}function Ia(e){return e!=="layout"&&e!=="visibility"}function Da(e){if(!k)return;if(!me()){k.innerHTML=Te(e.html),M&&pe();return}const t=Ra(),n=e.html.layout;if(k.dataset.panelLayout!==n||n!=="panel")k.innerHTML=Te(e.html),k.dataset.panelLayout=n;else{const a=e.regions.filter(Ia),i=a.map(c=>k.querySelector(`[data-panel-region="${c}"]`));if(i.some(c=>c===null))k.innerHTML=Te(e.html);else for(let c=0;c<a.length;c+=1){const l=i[c];l&&(l.innerHTML=e.html[a[c]])}}Na(),Ma(t),M&&pe()}const Ha=Ca(()=>La(r,Date.now()),Da,0);function p(){Ha.request()}function pe(){let e=null;if(!r.open){const n=document.querySelector(".pill")??document.querySelector(".empty-state");if(n){const s=n.getBoundingClientRect();e={x:s.x,y:s.y,w:s.width,h:s.height}}}const t=fn(r.open,e,re,Fa());window.location.hash!==t&&history.replaceState(null,"",t)}function Fa(){let e=null;for(const t of H){const n=bt(r.narratives?.[t]??null);if(!n)continue;const s=Date.parse(n.since);Number.isFinite(s)&&(e===null||s>e.sinceMs)&&(e={sinceMs:s,message:`${j[t]} 在等你:${n.message}`})}return e}function Ua(e){Se+=1,re={target:e,seq:Se},pe();const t=Se;setTimeout(()=>{re?.seq===t&&(re=null,pe())},600)}function Wa(e){if(!Array.isArray(e))throw new Error("载荷不是 JSON 数组");for(const t of e){if(typeof t!="object"||t===null)throw new Error("载荷元素不是对象");const n=t;if(typeof n.harness!="string"||typeof n.scannedAt!="string")throw new Error("载荷元素缺少 harness/scannedAt 字段");const s=n.slots;for(const a of Y)if(!s||!Array.isArray(s[a]))throw new Error(`harness ${n.harness} 缺少槽位 ${a}`)}return e}async function ne(){try{const e=r.wingmanVersion===void 0?fetch("/api/version").then(async a=>{if(!a.ok)return null;const i=await a.json();if(typeof i!="object"||i===null||!("version"in i))return null;const c=i.version;return typeof c=="string"&&c!==""?c:null}).catch(()=>null):Promise.resolve(r.wingmanVersion),[t,n]=await Promise.all([fetch("/api/anatomy"),e]);if(r.wingmanVersion=n,!t.ok)throw new Error(`GET /api/anatomy → HTTP ${t.status}`);const s=Wa(await t.json());r.configs=s,r.anatomyLoadedAt=new Date().toISOString(),r.anatomyRefreshFailed=!1,r.active=r.active==="projects"||s.some(a=>a.harness===r.active)?r.active:s[0]?.harness??"",r.error=null}catch(e){r.configs.length===0?r.error=e instanceof Error?e.message:String(e):(r.anatomyRefreshFailed=!0,r.error=null)}p()}async function Ft(){try{const e=await fetch("/api/return-target");if(!e.ok)return!1;const t=An(await e.json());return t===null?!1:(r.returnTargets?.settings?.unavailable!==t.settings?.unavailable&&(r.returnSettingsDismissed=!1),r.returnTargets=t,p(),!0)}catch{return!1}}async function qa(e){if(!(r.returnTargetSaving||!r.returnTargets?.available.some(t=>t.bundlePath===e))){r.returnTargetSaving=!0,r.returnTargetError=null,p();try{const t=await fetch("/api/return-target",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({bundlePath:e})});if(!t.ok){r.returnTargetError=await U(t);return}const n=xn(await t.json());if(n===null||n.selected.bundlePath!==e){r.returnTargetError="回跳设置响应不可用";return}r.returnTargets={available:r.returnTargets.available,selected:n.selected},r.returnSettingsDismissed=!1}catch{r.returnTargetError="回跳设置保存失败"}finally{r.returnTargetSaving=!1,p()}}}let ie=0;async function $e(){const e=++ie;try{const t=await fetch("/api/projects");if(e!==ie||!t.ok)return;const n=On(await t.json());if(e!==ie)return;n!==null&&(r.projects?.memory!==void 0&&n.memory===void 0&&(r.projectMemoryDismissed=!1),r.projects=n)}catch{}finally{e===ie&&p()}}const je=new Set;async function Ba(e){if(je.has(e))return;const t=r.projects?.projects.flatMap(c=>"payloadUnavailable"in c?[]:c.sessions).find(c=>`${c.harness}:${c.id}`===e);if(t===void 0)return;je.add(e),r.taskResumeOpen=e;const n=Ot(t),s="unavailable"in n?"unavailable":await Ae(n.command)?"copied":"failed";let a,i="GET /api/return-target";if(r.returnTargets==null&&!await Ft())a={activated:!1,reason:"回跳设置读取失败"};else if(r.returnTargets?.settings!==void 0)a={activated:!1,reason:r.returnTargets.settings.unavailable};else if(r.returnTargets?.selected===void 0)a={activated:null};else{i="POST /api/return";try{const c=await fetch("/api/return",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({bundlePath:r.returnTargets.selected.bundlePath})});a=c.ok?_n(await c.json())??{activated:!1,reason:"激活响应不可用"}:{activated:!1,reason:await U(c)}}catch{a={activated:!1,reason:"激活请求失败"}}}r.taskReturnResults={...r.taskReturnResults,[e]:{clipboard:s,activation:a,activationSource:i}},je.delete(e),p()}async function ce(e,t){const n=e.indexOf(":");if(n<1||n===e.length-1)return;const s=e.slice(0,n),a=e.slice(n+1);let i;try{i=await fetch("/api/task-overlay",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({harness:s,sessionId:a,patch:t})})}catch(c){r.taskError={key:e,message:`整理请求失败:${F(c)}`},p();return}if(!i.ok){r.taskError={key:e,message:await U(i)},p();return}r.taskError=null,r.taskMenuOpen=null,r.taskResumeOpen=null,await $e(),t.accepted!==void 0&&H.includes(s)&&await Q(s)}async function Va(){try{const e=await fetch("/api/license");if(!e.ok)return;const t=Me(await e.json());t&&(r.license=t,p())}catch{}}async function Ka(){if(r.licenseRefreshing)return;r.licenseRefreshing=!0,r.licenseRefreshResult=null,r.licenseCanSubscribe=!1,p();let e;try{e=await fetch("/api/license/refresh",{method:"POST",headers:{"x-wingman-panel-action":"refresh-license"}})}catch(s){r.licenseRefreshing=!1,r.licenseRefreshResult={ok:!1,message:`刷新失败:${F(s)}`},p();return}if(!e.ok){const s=await oi(e);r.licenseRefreshing=!1,r.licenseCanSubscribe=s.canSubscribe,r.licenseRefreshResult={ok:!1,message:s.message},p();return}let t;try{t=await e.json()}catch{t=null}const n=Me(t);n&&(r.license=n),r.licenseRefreshing=!1,r.licenseCanSubscribe=!1,r.licenseRefreshResult={ok:!0,message:n?`授权已刷新:${n.detail}`:"授权已刷新,请重新打开面板查看最新状态"},p()}function Ga(){const e=document.createElement("input");e.type="file",e.accept=".json,application/json";const t=()=>{M&&!r.open&&(r.open=!0,p())};if(e.addEventListener("change",()=>{t();const n=e.files?.[0];n&&Ut(n)}),e.addEventListener("cancel",t),M&&r.open){r.open=!1,p(),window.setTimeout(()=>e.click(),200);return}e.click()}async function Ut(e){let t;try{t=await e.text()}catch(n){r.importResult={ok:!1,message:`读取文件失败:${F(n)}`},p();return}await Ja(t)}async function Ja(e){let t;try{t=await fetch("/api/license/install",{method:"POST",headers:{"content-type":"application/json"},body:e})}catch(s){r.importResult={ok:!1,message:`导入请求失败:${F(s)}`},p();return}if(!t.ok){r.importResult={ok:!1,message:await U(t)},p();return}let n=null;try{n=Me(await t.json())}catch{n=null}n&&(r.license=n,r.licenseCanSubscribe=!1),r.importResult={ok:!0,message:hn(n)},p()}if(M)document.addEventListener("dragover",e=>e.preventDefault()),document.addEventListener("drop",e=>e.preventDefault());else{const e=document.createElement("div");e.id="drop",e.textContent="松开导入 license",document.body.appendChild(e);let t=0;const n=s=>Array.from(s.dataTransfer?.types??[]).includes("Files");document.addEventListener("dragenter",s=>{n(s)&&(s.preventDefault(),t+=1,e.style.display="flex")}),document.addEventListener("dragover",s=>{n(s)&&s.preventDefault()}),document.addEventListener("dragleave",s=>{n(s)&&(t=Math.max(0,t-1),t===0&&(e.style.display="none"))}),document.addEventListener("drop",s=>{if(!n(s))return;s.preventDefault(),t=0,e.style.display="none";const a=Array.from(s.dataTransfer?.files??[]),i=bn(a.map(l=>l.name));if(i){r.importResult={ok:!1,message:i},p();return}const c=a[0];c&&Ut(c)})}const Wt=Ht,Ee={},Z={};let _e;async function Q(e){const t=(Z[e]??0)+1;Z[e]=t;try{const n=await fetch(`/api/narrative?harness=${e}`);if(Z[e]!==t||!n.ok)return;const s=await n.json();if(Z[e]!==t)return;const a=Ln(s);if(a){r.narratives||(r.narratives={}),r.narratives[e]=a;const i=fe(a,r.sessionSel?.[e]);i!==null&&(r.sessionSel||(r.sessionSel={}),r.sessionSel[e]=i,Le(e,i))}}catch{}finally{Z[e]===t&&p()}}function Le(e,t){const n=r.narratives?.[e]?.sessions.find(s=>s.id===t);n&&(r.sessionSeen||(r.sessionSeen={}),r.sessionSeen[`${e}:${t}`]=n.lastActivity)}function Ce(e){Ee[e]===void 0&&(Ee[e]=window.setTimeout(()=>{delete Ee[e],Q(e)},Wt))}function Ye(){_e===void 0&&(_e=window.setTimeout(()=>{_e=void 0,$e()},Wt))}function Qa(){const e=new EventSource("/api/narrative/events");e.onopen=()=>{for(const t of H)Ce(t);Ye()},e.onmessage=t=>{try{const n=JSON.parse(t.data);H.includes(n.harness)&&(Ce(n.harness),Ye())}catch{}}}function Xa(){const e=r.configs.find(s=>s.harness===r.active)??r.configs[0];if(!e)return null;const t=r.narratives?.[e.harness]??null,n=fe(t,r.sessionSel?.[e.harness]);return t===null||n===null?null:t.states[n]??null}function Ya(e){r.active="projects",p(),window.setTimeout(()=>{document.getElementById(e)?.scrollIntoView({block:"center"})},0)}function za(e){r.active="projects",p(),window.setTimeout(()=>{document.getElementById(ee(e))?.scrollIntoView({block:"center"})},0)}function Za(e){const t=r.todoOpen??{};let n;if(e==="__other__")n=t[e]!==!1;else{const s=Xa()?.todos.find(a=>a.id===e);n=s?Et(s,t):t[e]===!0}r.todoOpen={...t,[e]:!n},p()}const H=["cc","codex","dsh"],ei=["all","waiting","active","ended"];function ti(e){if(typeof e!="object"||e===null)return null;const t=e;if(!H.includes(t.harness)||typeof t.received_at!="string")return null;const n=t.payload;return typeof n!="object"||n===null||typeof n.hook_event_name!="string"?null:e}function qt(e,t,n){const s={event:e,...t===void 0?{}:{mock:t},...n===void 0?{}:{sseId:n}};P.entries=Tn(P.entries,s),Ce(e.harness)}function ni(){const e=new EventSource("/api/events");e.onopen=()=>{P.connection!=="open"&&(P.connection="open",p())},e.onmessage=t=>{try{const n=ti(JSON.parse(t.data));n&&qt(n,void 0,t.lastEventId||void 0)}catch{}},e.onerror=()=>{P.connection!=="retrying"&&(P.connection="retrying",p())}}const si=200;async function ai(){if(!P.replaying){P.replaying=!0,p();try{const e=await fetch("/api/live-demo.json");if(!e.ok)throw new Error(`GET /api/live-demo.json → HTTP ${e.status}`);const t=await e.json();for(const n of t.events)qt({harness:t.harness,received_at:new Date().toISOString(),payload:n},!0),await new Promise(s=>setTimeout(s,si))}catch{}P.replaying=!1,p()}}let _=0;function X(){return r.configs.find(e=>e.harness===r.active)??r.configs[0]}function ii(e,t){for(const n of Y){const s=(e.slots[n]??[]).find(a=>a.id===t);if(s)return s}}function Bt(){_+=1,r.flow=null,p()}function F(e){return e instanceof Error?e.message:String(e)}async function U(e){const t=await e.text();try{const n=JSON.parse(t);if(typeof n.error=="string"&&n.error!=="")return n.error}catch{}return`HTTP ${e.status}${t?` — ${t}`:""}`}async function oi(e){const t=await e.text();try{const n=JSON.parse(t);if(typeof n.error=="string"&&n.error!=="")return{message:n.error,canSubscribe:n.canSubscribe===!0}}catch{}return{message:`HTTP ${e.status}${t?` — ${t}`:""}`,canSubscribe:!1}}async function ri(e,t){try{const n=await fetch("/api/action-plan-demo.json");if(!n.ok)throw new Error(`GET /api/action-plan-demo.json → HTTP ${n.status}`);const s=await n.json(),a=typeof s.__mock_note=="string"?s.__mock_note:"";if(!a.includes("MOCK"))throw new Error("演示件缺 MOCK 标注(增补条款 10)");const i=at(s.plan);if(e!==_)return;r.flow={phase:"confirm",title:st(tn(i),i.action.enable),plan:i,mockNote:a}}catch(n){if(e!==_)return;r.flow={phase:"error",title:t,message:`服务器无动作端点(dev 模式?),且演示件不可用:${F(n)}`}}p()}async function ze(e,t){const n=X();if(!n)return;const s=ii(n,e);if(!s)return;const a=t??!s.enabled,i=st(s.nativeName,a),c=++_;r.flow={phase:"planning",title:i},p();const l={kind:"toggle",itemId:e,enable:a};let d=null;try{d=await fetch("/api/action/plan",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({harness:n.harness,action:l})})}catch{d=null}if(c===_){if(d===null||d.status===404||d.status===405){await ri(c,i);return}if(!d.ok){const u=await U(d);if(c!==_)return;r.flow={phase:"error",title:i,message:u},p();return}try{const u=at(await d.json());if(c!==_)return;r.flow={phase:"confirm",title:i,plan:u}}catch(u){if(c!==_)return;r.flow={phase:"error",title:i,message:F(u)}}p()}}async function ci(){if(r.flow?.phase!=="confirm")return;const{title:e,plan:t,mockNote:n}=r.flow;if(n){r.flow={phase:"demo",title:e},p();return}const s=++_;r.flow={phase:"applying",title:e},p();let a;try{a=await fetch("/api/action/apply",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({harness:t.harness,plan:t})})}catch(i){if(s!==_)return;r.flow={phase:"error",title:e,message:`apply 请求失败:${F(i)}`},p();return}if(s===_){if(a.status===403){const i=await U(a);if(s!==_)return;r.flow=ln(e,i),p();return}if(!a.ok){const i=await U(a);if(s!==_)return;r.flow={phase:"error",title:e,message:i},p();return}try{const i=cn(await a.json());if(s!==_)return;i.ok?(r.flow={phase:"applied",title:e,backupDir:i.backupDir},ne()):r.flow={phase:"error",title:e,message:i.error}}catch(i){if(s!==_)return;r.flow={phase:"error",title:e,message:F(i)}}p()}}let V=0;function li(){const e=X();e&&(V+=1,r.share={kind:"config",title:`分享配置样本 · ${j[e.harness]}`,lines:ys(e),phase:"preview"},p())}function di(){V+=1,r.share={kind:"events",title:"分享事件样本",lines:ks(P.entries),phase:"preview"},p()}function Vt(){V+=1,r.share=null,p()}function ui(e){r.share?.phase==="preview"&&(r.share={...r.share,lines:ws(r.share.lines,e)},p())}async function pi(){const e=r.share;if(e?.phase!=="preview"||e.lines.length===0||Pt(e.kind,e.lines))return;const t=++V;r.share={...e,phase:"sending"},p();let n;try{n=await fetch(hs,{method:"POST",headers:{"content-type":"application/json"},body:At(e.kind,e.lines)})}catch(s){if(t!==V)return;r.share={...e,phase:"error",message:`发送失败:${F(s)}`},p();return}if(t===V){if(n.ok)r.share={...e,phase:"sent"};else{const s=await U(n);if(t!==V)return;r.share={...e,phase:"error",message:s}}p()}}document.addEventListener("click",e=>{const t=e.target;if(!t)return;if(mn({island:M,open:r.open,inPanel:t.closest(".panel")!==null||t.closest(".pill")!==null||t.closest(".empty-state")!==null||t.closest(".overlay")!==null,modalOpen:!!(r.flow||r.share||r.licenseOpen||r.importResult)})){r.open=!1,p();return}const n=t.closest('[data-act="locate"]');if(n instanceof HTMLElement&&n.dataset.target){Ua(n.dataset.target);return}const s=t.closest('[data-act="view"]');if(s instanceof HTMLElement&&s.dataset.view){r.view=s.dataset.view,p();return}const a=t.closest('[data-act="return-target-select"]');if(a instanceof HTMLElement&&a.dataset.bundlePath!==void 0){qa(a.dataset.bundlePath);return}if(t.closest('[data-act="return-settings-dismiss"]')){r.returnSettingsDismissed=!0,p();return}const i=t.closest('[data-act="protocol-copy"]');if(i instanceof HTMLElement&&i.dataset.command!==void 0){Ae(i.dataset.command);return}const c=t.closest('[data-act="task-menu"]');if(c instanceof HTMLElement&&c.dataset.key!==void 0){e.stopPropagation();const $=c.dataset.key;r.taskMenuOpen=r.taskMenuOpen===$?null:$,r.taskMenuOpen===null&&(r.taskResumeOpen=null),p();return}if(t.closest('[data-act="task-rename-input"]')){e.stopPropagation();return}const d=t.closest('[data-act="task-accept"]');if(d instanceof HTMLElement&&d.dataset.key!==void 0&&d.dataset.value!==void 0){e.stopPropagation(),ce(d.dataset.key,{accepted:d.dataset.value==="true"});return}const u=t.closest('[data-act="task-pin"]');if(u instanceof HTMLElement&&u.dataset.key!==void 0&&u.dataset.value!==void 0){e.stopPropagation(),ce(u.dataset.key,{pinned:u.dataset.value==="true"});return}const f=t.closest('[data-act="task-hide"]');if(f instanceof HTMLElement&&f.dataset.key!==void 0&&f.dataset.value!==void 0){e.stopPropagation(),ce(f.dataset.key,{hidden:f.dataset.value==="true"});return}const v=t.closest('[data-act="task-resume"]');if(v instanceof HTMLElement&&v.dataset.key!==void 0){e.stopPropagation();const $=v.dataset.key;Ba($);return}const g=t.closest('[data-act="task-copy"]');if(g instanceof HTMLElement&&g.dataset.command!==void 0){e.stopPropagation(),Ae(g.dataset.command);return}const S=t.closest('[data-act="task-hidden-toggle"]');if(S instanceof HTMLElement&&S.dataset.group!==void 0){e.stopPropagation();const $=r.hiddenOpen??{};r.hiddenOpen={...$,[S.dataset.group]:$[S.dataset.group]!==!0},p();return}const y=t.closest('[data-act="facts-toggle"]');if(y instanceof HTMLElement&&y.dataset.group!==void 0){e.stopPropagation();const $=r.factsOpen??{};r.factsOpen={...$,[y.dataset.group]:$[y.dataset.group]!==!0},p();return}const A=t.closest('[data-act="task-filter"]');if(A instanceof HTMLElement&&A.dataset.value!==void 0){const $=r.taskFilter??te,q=A.dataset.value;if(A.dataset.kind==="harness"&&(q==="all"||H.includes(q))){r.taskFilter={...$,harness:q},p();return}if(A.dataset.kind==="status"&&ei.includes(q)){r.taskFilter={...$,status:q},p();return}}const w=t.closest('[data-act="project-session"]');if(w instanceof HTMLElement&&H.includes(w.dataset.harness)&&w.dataset.session!==void 0){const $=w.dataset.harness;r.active=$,r.sessionSel||(r.sessionSel={}),r.sessionSel[$]=w.dataset.session,Le($,w.dataset.session),Q($),p();return}const h=t.closest('[data-act="project-node-link"]');if(h instanceof HTMLElement&&h.dataset.nodeTarget!==void 0){Ya(h.dataset.nodeTarget);return}const C=t.closest('[data-act="project-card-link"]');if(C instanceof HTMLElement&&C.dataset.root!==void 0){za(C.dataset.root);return}const W=t.closest('[data-act="notice-dismiss"]');if(W instanceof HTMLElement&&W.dataset.key!==void 0){r.noticeDismissed||(r.noticeDismissed={}),r.noticeDismissed[W.dataset.key]=!0,p();return}if(t.closest('[data-act="project-memory-dismiss"]')){r.projectMemoryDismissed=!0,p();return}const E=t.closest('[data-act="session"]');if(E instanceof HTMLElement&&E.dataset.id!==void 0){const $=X();$&&(r.sessionSel||(r.sessionSel={}),r.sessionSel[$.harness]=E.dataset.id,Le($.harness,E.dataset.id),p());return}const I=t.closest('[data-act="sugg-plan"]');if(I instanceof HTMLElement&&I.dataset.item!==void 0){ze(I.dataset.item,I.dataset.enable==="1");return}const R=t.closest('[data-act="sugg-dismiss"]');if(R instanceof HTMLElement&&R.dataset.sugg!==void 0){const $=X();if($){const q=r.narratives?.[$.harness]??null,Kt=fe(q,r.sessionSel?.[$.harness])??"";r.suggHidden||(r.suggHidden={}),r.suggHidden[`${$.harness}:${Kt}:${R.dataset.sugg}`]=!0,p()}return}const z=t.closest('[data-act="todo"]');if(z instanceof HTMLElement&&z.dataset.id!==void 0){Za(z.dataset.id);return}const se=t.closest('[data-act="node"]');if(se instanceof HTMLElement&&se.dataset.key!==void 0){const $=r.nodeOpen??{};r.nodeOpen={...$,[se.dataset.key]:$[se.dataset.key]!==!0},p();return}if(t.closest('[data-act="evidence"]')){r.evidenceOpen=!r.evidenceOpen,p();return}if(t.closest('[data-act="raw"]')){r.rawOpen=!r.rawOpen,p();return}if(t.closest('[data-act="toggle"]')){const $=!r.open;r.open=$,M&&$&&ne(),p();return}if(t.closest('[data-act="demo"]')){ai();return}if(t.closest('[data-act="lic-open"]')){r.licenseOpen=!0,r.licenseRefreshResult=null,p();return}if(t.closest('[data-act="lic-refresh"]')){Ka();return}if(t.closest('[data-act="lic-close"]')){r.licenseOpen=!1,r.licenseRefreshResult=null,p();return}if(t.closest('[data-act="lic-import"]')){Ga();return}if(t.closest('[data-act="import-close"]')){r.importResult=null,p();return}if(t.closest('[data-act="share-config"]')){li();return}if(t.closest('[data-act="share-events"]')){di();return}const ge=t.closest('[data-act="share-del"]');if(ge instanceof HTMLElement&&ge.dataset.i!==void 0){ui(Number(ge.dataset.i));return}if(t.closest('[data-act="share-send"]')){pi();return}if(t.closest('[data-act="share-close"]')){Vt();return}const he=t.closest('[data-act="tgl"]');if(he instanceof HTMLElement&&he.dataset.id){ze(he.dataset.id);return}if(t.closest('[data-act="plan-confirm"]')){ci();return}if(t.closest('[data-act="plan-cancel"]')){Bt();return}const G=t.closest("[data-tab]");G instanceof HTMLElement&&G.dataset.tab&&(r.active=G.dataset.tab,G.dataset.tab==="projects"?$e():H.includes(G.dataset.tab)&&Q(G.dataset.tab),p())});document.addEventListener("keydown",e=>{const t=e.target;if(t instanceof HTMLElement&&t.dataset.act==="task-rename-input"&&t.dataset.key!==void 0){const n=t;if(e.key==="Enter"){e.preventDefault(),e.stopPropagation(),ce(t.dataset.key,{title:n.value});return}if(e.key==="Escape"){e.preventDefault(),e.stopPropagation(),r.taskMenuOpen=null,r.taskResumeOpen=null,p();return}}if(e.key==="Escape"){if(r.share){Vt();return}if(r.importResult){r.importResult=null,p();return}if(r.licenseOpen){r.licenseOpen=!1,p();return}if(r.flow){r.flow.phase!=="applying"&&Bt();return}M&&r.open&&(r.open=!1,p())}});const N=document.createElement("div");N.id="tip";document.body.appendChild(N);document.addEventListener("mousemove",e=>{const n=e.target?.closest("[data-tip]");if(!(n instanceof HTMLElement)||!n.dataset.tip){N.style.display="none";return}N.textContent=n.dataset.tip,N.style.display="block";const s=N.offsetWidth;let a=e.clientX+14;a+s>window.innerWidth-8&&(a=e.clientX-s-14),N.style.left=`${a}px`,N.style.top=`${e.clientY+14}px`});document.addEventListener("mousedown",()=>{N.style.display="none"});window.addEventListener("blur",()=>{N.style.display="none"});let Ze="";setInterval(()=>{const e=r.configs.find(s=>s.harness===r.active)??r.configs[0];if(!e||P.entries.length===0)return;const t=lt(P.entries,e.harness,e.capabilities.live,Date.now()),n=`${t.active}:${t.label}`;n!==Ze&&(Ze=n,p())},1e3);setInterval(()=>{document.visibilityState==="visible"&&ne()},6e4);document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(r.anatomyLoadedAt===null||r.anatomyLoadedAt===void 0||Date.now()-Date.parse(r.anatomyLoadedAt)>6e4)&&ne()});un(()=>r.narratives?.[X()?.harness??"cc"]??null,p,()=>{const e=X();e&&Q(e.harness)});ne();Va();$e();Ft();for(const e of H)Q(e);ni();Qa();
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>Wingman</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-uKsu2f4j.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DARnsisU.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="app"></div>
|