hanoman 0.9.21 → 0.9.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/cli.js +9 -6
  3. package/dist/server.js +19 -15
  4. package/package.json +1 -1
  5. package/web/assets/DalangHanomanScreen--M-xLwH5.js +16 -0
  6. package/web/assets/DalangHanomanScreen-DhDPV6e8.css +1 -0
  7. package/web/assets/{DocPreviewModal-CJP6d0Hx.js → DocPreviewModal-CYdmHEb_.js} +1 -1
  8. package/web/assets/{DocsWorkspace-zGpPd7u3.js → DocsWorkspace-BFzb87Ye.js} +1 -1
  9. package/web/assets/{IdeScreen-DTvfuR2n.js → IdeScreen-CDMJaERU.js} +1 -1
  10. package/web/assets/{LeadScreen-DWbunLkQ.js → LeadScreen-DJjFTkyZ.js} +1 -1
  11. package/web/assets/{ReviewScreen-Ch9UiKlx.js → ReviewScreen-DG0xSBou.js} +1 -1
  12. package/web/assets/{SchedulerScreen-zIUh-Vbe.js → SchedulerScreen-ChEZ01CH.js} +1 -1
  13. package/web/assets/{SettingsScreen-CLMuCJ6R.js → SettingsScreen-BnINOj5X.js} +1 -1
  14. package/web/assets/{TeamScreen-CV1R5Ekk.js → TeamScreen-5cFDPm3o.js} +1 -1
  15. package/web/assets/{TerminalScreen-QVjhjrxx.js → TerminalScreen-CIROrYjO.js} +1 -1
  16. package/web/assets/TerminalScreen-D0NdFmR-.css +1 -0
  17. package/web/assets/{TriageScreen-Dpj4YrBQ.js → TriageScreen-BWnuGOmQ.js} +1 -1
  18. package/web/assets/{VpsScreen-DX_HEquM.js → VpsScreen-PqOkFriA.js} +1 -1
  19. package/web/assets/hnm-blencong-v01-CBBfchr0.webp +0 -0
  20. package/web/assets/hnm-hero-rig-arm-ml-v01-Kts3pjTf.webp +0 -0
  21. package/web/assets/hnm-hero-rig-arm-mr-v01-DQgnE6bD.webp +0 -0
  22. package/web/assets/hnm-hero-rig-arm-ul-v01-CIAWAxFe.webp +0 -0
  23. package/web/assets/hnm-hero-rig-arm-ur-v01-C0R0CZnp.webp +0 -0
  24. package/web/assets/hnm-hero-rig-body-v01-DmbKJJHB.webp +0 -0
  25. package/web/assets/hnm-wayang-panakawan-v01-1LGv-V8N.webp +0 -0
  26. package/web/assets/hnm-wayang-putri-v01-F6p69kHq.webp +0 -0
  27. package/web/assets/hnm-wayang-satria-alus-v01-CpfoXKTy.webp +0 -0
  28. package/web/assets/hnm-wayang-satria-gagah-v01-bLfIYAsv.webp +0 -0
  29. package/web/assets/{index-DmnwLncG.js → index-DYWU10xI.js} +3 -3
  30. package/web/assets/index-T4aiSGoI.css +32 -0
  31. package/web/assets/{live-B193WtZm.js → live-C90Zx0h6.js} +1 -1
  32. package/web/assets/{sched-lead-shared-BjMO8Q_k.js → sched-lead-shared-Qn3NA7WO.js} +1 -1
  33. package/web/assets/{settings-rebase-BI7-Bk98.js → settings-rebase-3Z15zUKI.js} +1 -1
  34. package/web/index.html +2 -2
  35. package/web/assets/DalangHanomanScreen-Us_5qG25.js +0 -13
  36. package/web/assets/DalangHanomanScreen-gk7fa9dl.css +0 -1
  37. package/web/assets/TerminalScreen-DrgZKlw2.css +0 -1
  38. package/web/assets/index-CL0_zz87.css +0 -32
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.9.21",
3
- "sha": "3996fa51",
4
- "builtAt": "2026-10-12T06:33:47.572Z"
2
+ "version": "0.9.23",
3
+ "sha": "e856b8ac",
4
+ "builtAt": "2026-10-12T08:04:06.309Z"
5
5
  }
package/dist/cli.js CHANGED
@@ -15518,7 +15518,7 @@ function repairSpawnHelper(resolve6, notify) {
15518
15518
  mode: (p3) => statSync(p3).mode,
15519
15519
  chmod: (p3, m) => chmodSync(p3, m)
15520
15520
  });
15521
- if (fixed.length) notify?.("hanoman \xB7 memperbaiki izin `spawn-helper` node-pty (sekali per instalasi)\n");
15521
+ if (fixed.length) notify?.("hanoman \xB7 memperbaiki izin `spawn-helper` node-pty (hilang setelah pemasangan/pembaruan paket)\n");
15522
15522
  return fixed;
15523
15523
  }
15524
15524
  var init_spawn_helper = __esm({
@@ -15781,6 +15781,7 @@ __export(update_exports, {
15781
15781
  planUpdate: () => planUpdate
15782
15782
  });
15783
15783
  import { execFileSync as execFileSync2 } from "node:child_process";
15784
+ import { createRequire } from "node:module";
15784
15785
  function planUpdate(current, latest) {
15785
15786
  if (!latest) return { action: "unknown", current, latest: null };
15786
15787
  return compareSemver(latest, current) > 0 ? { action: "install", current, latest } : { action: "up-to-date", current, latest };
@@ -15823,6 +15824,7 @@ async function update(argv, ctx) {
15823
15824
  ctx.stderr("npm i -g gagal \u2014 jalankan manual (mungkin butuh sudo)\n");
15824
15825
  return 1;
15825
15826
  }
15827
+ repairSpawnHelper(createRequire(import.meta.url).resolve, ctx.stdout);
15826
15828
  ctx.stdout(`terpasang hanoman ${plan.latest} \xB7 restart instance yang berjalan
15827
15829
  `);
15828
15830
  return 0;
@@ -15832,6 +15834,7 @@ var init_update = __esm({
15832
15834
  "src/commands/update.ts"() {
15833
15835
  "use strict";
15834
15836
  init_src();
15837
+ init_src2();
15835
15838
  init_router();
15836
15839
  PKG = "hanoman";
15837
15840
  INSTALL_ARGS = ["i", "-g", `${PKG}@latest`, "--prefer-online"];
@@ -15857,7 +15860,7 @@ __export(start_exports, {
15857
15860
  spawnEnv: () => spawnEnv
15858
15861
  });
15859
15862
  import { spawn, execFileSync as execFileSync3 } from "node:child_process";
15860
- import { createRequire } from "node:module";
15863
+ import { createRequire as createRequire2 } from "node:module";
15861
15864
  import { existsSync as existsSync3, mkdirSync as mkdirSync2, chmodSync as chmodSync3 } from "node:fs";
15862
15865
  import { dirname as dirname4, resolve as resolvePath } from "node:path";
15863
15866
  import { fileURLToPath } from "node:url";
@@ -15903,7 +15906,7 @@ function distDir() {
15903
15906
  return dirname4(fileURLToPath(import.meta.url));
15904
15907
  }
15905
15908
  function runPrisma(args, dbUrl) {
15906
- const prismaCli = prismaCliPath(createRequire(import.meta.url).resolve);
15909
+ const prismaCli = prismaCliPath(createRequire2(import.meta.url).resolve);
15907
15910
  try {
15908
15911
  const out = execFileSync3(process.execPath, [prismaCli, ...args], {
15909
15912
  env: { ...process.env, DATABASE_URL: dbUrl },
@@ -15952,7 +15955,7 @@ async function ensurePrismaClient(schema, dbUrl, ctx) {
15952
15955
  }
15953
15956
  }
15954
15957
  function repairSpawnHelperEarly(ctx) {
15955
- repairSpawnHelper(createRequire(import.meta.url).resolve, ctx.stdout);
15958
+ repairSpawnHelper(createRequire2(import.meta.url).resolve, ctx.stdout);
15956
15959
  }
15957
15960
  function planSupervisorStep(code, restartsUsed, configRestartsUsed = 0) {
15958
15961
  if (code === MANUAL_RESTART_EXIT) return { action: "restart" };
@@ -38289,10 +38292,10 @@ var init_verify_packed = __esm({
38289
38292
  });
38290
38293
 
38291
38294
  // src/router.ts
38292
- import { createRequire as createRequire2 } from "node:module";
38295
+ import { createRequire as createRequire3 } from "node:module";
38293
38296
  function currentVersion() {
38294
38297
  try {
38295
- return createRequire2(import.meta.url)("../package.json").version ?? "0.0.0";
38298
+ return createRequire3(import.meta.url)("../package.json").version ?? "0.0.0";
38296
38299
  } catch {
38297
38300
  return "0.0.0";
38298
38301
  }
package/dist/server.js CHANGED
@@ -19528,22 +19528,25 @@ function repairSpawnHelper(resolve24, notify) {
19528
19528
  mode: (p3) => statSync(p3).mode,
19529
19529
  chmod: (p3, m) => chmodSync3(p3, m)
19530
19530
  });
19531
- if (fixed.length) notify?.("hanoman \xB7 memperbaiki izin `spawn-helper` node-pty (sekali per instalasi)\n");
19531
+ if (fixed.length) notify?.("hanoman \xB7 memperbaiki izin `spawn-helper` node-pty (hilang setelah pemasangan/pembaruan paket)\n");
19532
19532
  return fixed;
19533
19533
  }
19534
- function ensureSpawnHelperOnce(resolve24, notify) {
19535
- if (repaired) return [];
19536
- repaired = true;
19534
+ function ensureSpawnHelper(resolve24, notify) {
19537
19535
  return repairSpawnHelper(resolve24, notify);
19538
19536
  }
19539
- function resetSpawnHelperMemo() {
19540
- repaired = false;
19537
+ function spawnWithHelperRecovery(doSpawn, repair) {
19538
+ repair();
19539
+ try {
19540
+ return doSpawn();
19541
+ } catch (e) {
19542
+ if (!String(e?.message ?? e).includes("posix_spawnp")) throw e;
19543
+ if (repair().length === 0) throw e;
19544
+ return doSpawn();
19545
+ }
19541
19546
  }
19542
- var repaired;
19543
19547
  var init_spawn_helper = __esm({
19544
19548
  "../runner/src/spawn-helper.ts"() {
19545
19549
  "use strict";
19546
- repaired = false;
19547
19550
  }
19548
19551
  });
19549
19552
 
@@ -20055,7 +20058,7 @@ __export(src_exports, {
20055
20058
  defaultGoalCondition: () => defaultGoalCondition,
20056
20059
  deleteSkillDir: () => deleteSkillDir,
20057
20060
  deleteSkillEntry: () => deleteSkillEntry,
20058
- ensureSpawnHelperOnce: () => ensureSpawnHelperOnce,
20061
+ ensureSpawnHelper: () => ensureSpawnHelper,
20059
20062
  ensureSpawnHelpersExecutable: () => ensureSpawnHelpersExecutable,
20060
20063
  executeAgentEvaluation: () => executeAgentEvaluation,
20061
20064
  formatConfigEnv: () => formatConfigEnv,
@@ -20093,7 +20096,6 @@ __export(src_exports, {
20093
20096
  renderAgentsJson: () => renderAgentsJson,
20094
20097
  renderCodexAgentToml: () => renderCodexAgentToml,
20095
20098
  repairSpawnHelper: () => repairSpawnHelper,
20096
- resetSpawnHelperMemo: () => resetSpawnHelperMemo,
20097
20099
  resolveDataDirs: () => resolveDataDirs,
20098
20100
  resolveDbUrl: () => resolveDbUrl,
20099
20101
  resolveDeployment: () => resolveDeployment,
@@ -20112,6 +20114,7 @@ __export(src_exports, {
20112
20114
  skillTree: () => skillTree,
20113
20115
  skillsUnder: () => skillsUnder,
20114
20116
  spawnHelperPaths: () => spawnHelperPaths,
20117
+ spawnWithHelperRecovery: () => spawnWithHelperRecovery,
20115
20118
  specContext: () => specContext,
20116
20119
  startBreakdownPrompt: () => startBreakdownPrompt,
20117
20120
  startGoalPrompt: () => startGoalPrompt,
@@ -48439,14 +48442,15 @@ function detachAll() {
48439
48442
  for (const id2 of [...attached.keys()]) drop(id2);
48440
48443
  }
48441
48444
  function spawnPty(...args) {
48442
- ensureSpawnHelperOnce(createRequire(import.meta.url).resolve, (m) => process.stdout.write(m));
48445
+ const resolve24 = createRequire(import.meta.url).resolve;
48446
+ const repair = () => ensureSpawnHelper(resolve24, (m) => process.stdout.write(m));
48443
48447
  try {
48444
- return spawn("tmux", ["-L", socket(), "-f", "/dev/null", ...args], {
48448
+ return spawnWithHelperRecovery(() => spawn("tmux", ["-L", socket(), "-f", "/dev/null", ...args], {
48445
48449
  name: "xterm-256color",
48446
48450
  cols: 80,
48447
48451
  rows: 24,
48448
48452
  env: process.env
48449
- });
48453
+ }), repair);
48450
48454
  } catch (e) {
48451
48455
  const msg = e.message;
48452
48456
  if (!msg.includes("posix_spawnp")) throw e;
@@ -81808,12 +81812,12 @@ async function escalateTask(task, opts2) {
81808
81812
  const spec2 = await prisma.spec.findUnique({ where: { id: task.specId } });
81809
81813
  if (spec2) {
81810
81814
  if (task.projectId === spec2.projectId) return { spec: spec2, task, created: false };
81811
- const repaired2 = await prisma.task.update({
81815
+ const repaired = await prisma.task.update({
81812
81816
  where: { id: task.id },
81813
81817
  data: { projectId: spec2.projectId }
81814
81818
  });
81815
81819
  await notifySynced("task", task.id);
81816
- return { spec: spec2, task: repaired2, created: false };
81820
+ return { spec: spec2, task: repaired, created: false };
81817
81821
  }
81818
81822
  }
81819
81823
  const member = task.memberId ? await prisma.member.findUnique({ where: { id: task.memberId } }) : null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hanoman",
3
- "version": "0.9.21",
3
+ "version": "0.9.23",
4
4
  "description": "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
5
5
  "type": "module",
6
6
  "repository": {
@@ -0,0 +1,16 @@
1
+ import{j as e,u as be,I as C,l as I,S as se,F as te}from"./index-DYWU10xI.js";import{R as d}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";function ye({height:s,color:a,rod:l}){return e.jsxs("svg",{viewBox:"0 0 64 128",width:s*64/128,height:s,"aria-hidden":"true",focusable:"false",children:[e.jsx("path",{d:"M31.2 74 L30.2 127 L33.8 127 L32.8 74 Z",fill:l}),e.jsx("path",{d:"M51 79 L50.2 122 L53 122 L52.4 79 Z",fill:l}),e.jsx("path",{d:`M32 73
2
+ C 24 76, 19 88, 17.5 103 C 17 106, 20 107, 24 106.4
3
+ C 28 106, 30 104, 32 104 C 34 104, 36 106, 40 106.4 C 44 107, 47 106, 46.5 103
4
+ C 45 88, 40 76, 32 73 Z`,fill:a}),e.jsx("path",{d:"M32 74 C 29.5 66, 29.5 60, 31 53 L 37 53 C 38.5 60, 37.5 67, 34.5 74 Z",fill:a}),e.jsx("path",{d:`M31 53
5
+ C 28.5 48, 29 43.5, 31.5 40.5
6
+ C 28 38.5, 25 34, 25.5 28.5
7
+ C 26 22, 30 16.5, 36 15
8
+ C 34 20, 34.5 24, 37.5 27.5
9
+ C 41 31.5, 44.5 33.5, 46.5 37.5
10
+ C 48 40.5, 47 43.5, 44.5 44.5
11
+ C 46 46.5, 46.5 49, 45 51.5
12
+ C 43 54.5, 38 55, 34.5 53.8 Z`,fill:a}),e.jsx("path",{d:`M35 55 C 40 58, 44.5 63, 47.5 69 C 49.5 73, 51 76, 51.8 79.5 L 49.4 80.5
13
+ C 47 76.5, 44.5 72.5, 41.5 68.5 C 38.5 64.5, 35.5 61, 33 58.5 Z`,fill:a})]})}const ve="/assets/hnm-hero-rig-body-v01-DmbKJJHB.webp",we="/assets/hnm-hero-rig-arm-ul-v01-CIAWAxFe.webp",ke="/assets/hnm-hero-rig-arm-ur-v01-C0R0CZnp.webp",Ae="/assets/hnm-hero-rig-arm-ml-v01-Kts3pjTf.webp",Ee="/assets/hnm-hero-rig-arm-mr-v01-DQgnE6bD.webp",Ie="/assets/hnm-blencong-v01-CBBfchr0.webp",Me="/assets/hnm-wayang-satria-alus-v01-CpfoXKTy.webp",Ce="/assets/hnm-wayang-satria-gagah-v01-bLfIYAsv.webp",Se="/assets/hnm-wayang-putri-v01-F6p69kHq.webp",$e="/assets/hnm-wayang-panakawan-v01-1LGv-V8N.webp",le=[Me,Ce,Se,$e],ie=s=>le[[...s].reduce((a,l)=>a+l.charCodeAt(0),0)%le.length],re=["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agu","Sep","Okt","Nov","Des"],F=s=>String(s).padStart(2,"0");function De(s){if(!s)return!1;const a=new Date(s);if(Number.isNaN(a.getTime()))return!1;const l=new Date;return a.getFullYear()===l.getFullYear()&&a.getMonth()===l.getMonth()&&a.getDate()===l.getDate()}const O=s=>!!s.decision&&!s.deciding,de="(prefers-reduced-motion: reduce)";function Re(){return typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia(de).matches}function Ue(){const[s,a]=d.useState(Re);return d.useEffect(()=>{if(typeof window>"u"||typeof window.matchMedia!="function")return;const l=window.matchMedia(de),c=()=>a(l.matches);return l.addEventListener("change",c),()=>l.removeEventListener("change",c)},[]),s}function Te(s,a){const[l,c]=d.useState(0);return d.useEffect(()=>{if(a)return;const p=performance.now(),x=900;let m=0;const i=h=>{const o=Math.min(1,(h-p)/x);c(Math.round(s*(1-Math.pow(1-o,3)))),o<1&&(m=requestAnimationFrame(i))};return m=requestAnimationFrame(i),()=>cancelAnimationFrame(m)},[s,a]),a?s:l}const Be=(s,a)=>s.reduced===a.reduced&&s.lines.join(`
14
+ `)===a.lines.join(`
15
+ `),Le=d.memo(function({lines:a,reduced:l}){const[c,p]=d.useState(""),x=a.join(`
16
+ `);return d.useEffect(()=>{if(l||a.length===0)return;let m=0,i=0,h=null,o=null;const f=()=>{const v=a[m%a.length]??"";i=0,h=setInterval(()=>{i++,p(v.slice(0,i)),i>=v.length&&h&&(clearInterval(h),h=null,o=setTimeout(()=>{m++,f()},3200))},26)};return f(),()=>{h&&clearInterval(h),o&&clearTimeout(o)}},[x,l]),e.jsx("p",{className:"hn-dlg-boot","aria-live":"off",children:l?a[0]??"":c})},Be),Ke=d.memo(function(){const[a,l]=d.useState(()=>new Date);return d.useEffect(()=>{const c=setInterval(()=>l(new Date),1e3);return()=>clearInterval(c)},[]),e.jsxs("span",{className:"hn-dlg-clock","aria-hidden":"true",children:[e.jsxs("span",{className:"hn-dlg-chip",children:[e.jsx(C,{name:"calendar-clock",size:13}),a.getDate()," ",re[a.getMonth()]," ",a.getFullYear()]}),e.jsxs("span",{className:"hn-dlg-chip",children:[e.jsx(C,{name:"history",size:13}),F(a.getHours()),":",F(a.getMinutes()),":",F(a.getSeconds())]})]})}),M=d.memo(function({icon:a,tone:l,label:c,value:p,sub:x,reduced:m}){const i=Te(p,m);return e.jsxs("div",{className:"hn-dlg-kpi",children:[e.jsx("span",{className:`hn-dlg-kpi-ic hn-dlg-tone-${l}`,children:e.jsx(C,{name:a,size:17})}),e.jsxs("span",{className:"hn-dlg-kpi-body",children:[e.jsx("span",{className:"hn-dlg-kpi-l",children:c}),e.jsx("span",{className:"hn-dlg-kpi-v",children:i}),e.jsx("span",{className:"hn-dlg-kpi-s",children:x})]})]})});function Fe({name:s,fase:a,sesi:l,onClick:c}){return e.jsxs("button",{type:"button",className:"hn-dlg-row",onClick:c,children:[e.jsx("span",{className:"hn-dlg-glyph","aria-hidden":"true",children:e.jsx(ye,{height:24,color:"var(--amber-500)",rod:"var(--brass-300)"})}),e.jsx("span",{className:"hn-dlg-name",children:s}),e.jsx("span",{className:"hn-dlg-fase",children:a}),l&&e.jsx("span",{className:"hn-dlg-sesi",children:l}),e.jsx("span",{className:"hn-dlg-aksi",children:"Jawab"})]})}function Oe(s,a){return s?{tone:"ok",text:"Terhubung"}:a?{tone:"idle",text:"Jeda · tab tersembunyi"}:{tone:"err",text:"Koneksi terputus · menyambung ulang"}}function We({projects:s,backlog:a,sessions:l,onOpenSession:c,onOpenProject:p,onGoto:x,onExit:m,previous:i}){const h=be(),o=Ue(),f=i?i.onBack:m,v=d.useRef(f);v.current=f,d.useEffect(()=>{const n=t=>{t.key==="Escape"&&v.current()};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[]);const g=l.filter(n=>!n.exited).sort((n,t)=>n.id.localeCompare(t.id)),G=new Set(g.map(n=>n.projectId)),S=g.filter(O),E=s.filter(n=>!G.has(n.id)),Y=new Map(a.map(n=>[n.id,n])),ce=new Map(s.map(n=>[n.id,n.name])),H=n=>ce.get(n)??n,he=n=>{const t=n.specId?Y.get(n.specId):void 0;return t?I(se,t.stage):n.flow?I(te,n.flow):"Sesi terminal"},J=n=>{if(O(n))return"menunggu jawabanmu";const t=n.specId?Y.get(n.specId):void 0;return t?`${t.id} · ${I(se,t.stage)}`:n.flow?I(te,n.flow):"sesi terminal"},P=a.filter(n=>De(n.startedAt)).length,w=S.length,W=Oe(h.connected,h.paused),oe=[h.connected?`HANOMAN ONLINE · ${g.length>0?`${g.length} SESI HIDUP`:"KELIR SUNYI"}`:h.paused?"JEDA · TAB TERSEMBUNYI":"KONEKSI TERPUTUS · MENYAMBUNG ULANG",`${P} TASK DIKERJAKAN HARI INI`,w>0?`${w} SESI MENUNGGU JAWABANMU`:"TIDAK ADA YANG MENUNGGU JAWABANMU",`${s.length} PROYEK DALAM PANTAUAN`],ge=[g.length===0?"Tidak ada sesi berjalan":`${g.length} sesi berjalan`,w>0?`${w} menunggu jawabanmu`:null,`${s.length} project`].filter(Boolean).join(" · "),N={done:0,executing:0,planned:0,spec:0};for(const n of a)n.stage==="done"?N.done++:n.stage==="executing"?N.executing++:n.stage==="planned"?N.planned++:N.spec++;const $=a.length,q=[{key:"executing",cls:"executing",label:"Execute"},{key:"done",cls:"done",label:"Done"},{key:"planned",cls:"planned",label:"Plan"},{key:"spec",cls:"spec",label:"Spec"}].map(n=>({...n,n:N[n.key],frac:$?N[n.key]/$*100:0})),me={executing:"var(--wind-500)",done:"var(--leaf-500)",planned:"var(--amber-500)",spec:"var(--brass-400)"};let D=0;const Z=q.filter(n=>n.frac>0).map(n=>{const t=D;return D+=n.frac,`${me[n.cls]} ${t}% ${D}%`}),ue=Z.length?`conic-gradient(${Z.join(", ")})`:"conic-gradient(var(--term-line) 0% 100%)",R=new Date,b=[];for(let n=6;n>=0;n--){const t=new Date(R.getFullYear(),R.getMonth(),R.getDate()-n),j=a.filter(r=>{if(!r.startedAt)return!1;const u=new Date(r.startedAt);return u.getFullYear()===t.getFullYear()&&u.getMonth()===t.getMonth()&&u.getDate()===t.getDate()}).length;b.push({label:`${t.getDate()} ${re[t.getMonth()]}`,n:j})}const U=Math.max(1,...b.map(n=>n.n)),pe=b.map((n,t)=>`${32+t*35},${78-n.n/U*60}`).join(" "),xe=`${g.map(n=>n.id).join("|")}#${E.map(n=>n.id).join("|")}`,z=d.useRef(null),[_,Q]=d.useState([]);d.useLayoutEffect(()=>{const n=z.current;if(!n||g.length===0&&E.length===0){Q([]);return}const t=()=>{var ae;const r=n.getBoundingClientRect();if(r.width<60)return;const u=(ae=n.querySelector(".hn-dlg-hero-art"))==null?void 0:ae.getBoundingClientRect(),X=u?u.left+u.width/2-r.left:r.width/2,ee={};n.querySelectorAll("[data-hand]").forEach(y=>{const k=y.getBoundingClientRect();ee[y.dataset.hand??""]={x:k.left+k.width/2-r.left,y:k.top+k.height/2-r.top}});const je={x:X,y:u?u.top-r.top+u.height*.36:r.height*.35},ne=[];n.querySelectorAll(".hn-dlg-prj").forEach(y=>{const T=(y.querySelector(".hn-dlg-puppet img")??y).getBoundingClientRect(),B=T.left+T.width/2-r.left,L=T.top-r.top+1,K=!y.hasAttribute("data-puppet"),fe=B<X?"l":"r",A=ee[(K?"m":"u")+fe]??je,Ne=K?Math.max(A.y,L)+26:Math.min(A.y,L)-16;ne.push({d:`M ${A.x.toFixed(1)} ${A.y.toFixed(1)} Q ${((A.x+B)/2).toFixed(1)} ${Ne.toFixed(1)}, ${B.toFixed(1)} ${L.toFixed(1)}`,slack:K})}),Q(ne)};if(t(),typeof ResizeObserver>"u")return;const j=new ResizeObserver(t);return j.observe(n),()=>j.disconnect()},[xe,g.length,E.length]);const V=s.slice(0,6).map(n=>({id:n.id,name:n.name,text:n.activity,live:G.has(n.id)}));return e.jsxs("main",{className:"hn-dlg","aria-label":"Dalang Hanoman",children:[e.jsxs("header",{className:"hn-dlg-top",children:[e.jsxs("div",{className:"hn-dlg-brand",children:[e.jsx("img",{className:"hn-dlg-blencong",src:Ie,alt:"","aria-hidden":"true","data-lit":g.length>0||void 0}),e.jsxs("div",{className:"hn-dlg-head",children:[e.jsx("h2",{className:"hn-dlg-title",children:"Dalang Hanoman"}),e.jsx(Le,{lines:oe,reduced:o}),e.jsx("p",{className:"hn-dlg-summary",children:ge}),e.jsxs("p",{className:`hn-dlg-link hn-dlg-link--${W.tone}`,role:"status",children:[e.jsx("span",{className:"hn-dlg-dot","aria-hidden":"true"}),W.text]})]})]}),e.jsxs("div",{className:"hn-dlg-bar",children:[e.jsx(Ke,{}),e.jsx("button",{type:"button",className:"hn-dlg-exit",onClick:f,"aria-label":i?`Kembali ke ${i.label}`:"Keluar dari panggung (Esc)",title:i?`Kembali ke ${i.label}`:"Keluar dari panggung (Esc)",children:e.jsx(C,{name:i?"arrow-left":"x",size:18})})]})]}),S.length>0&&e.jsxs("section",{className:"hn-dlg-section hn-dlg-section--wait","aria-labelledby":"dlg-wait",children:[e.jsx("h3",{id:"dlg-wait",className:"hn-dlg-rt",children:"Menunggu jawabanmu"}),e.jsx("ul",{className:"hn-dlg-list",children:S.map(n=>e.jsx("li",{children:e.jsx(Fe,{name:H(n.projectId),fase:he(n),sesi:n.specId??"",onClick:()=>c(n.id)})},n.id))})]}),e.jsxs("div",{className:"hn-dlg-kpis",children:[e.jsx(M,{icon:"layout-grid",tone:"proyek",label:"TOTAL PROYEK",value:s.length,sub:"dalam pantauan",reduced:o}),e.jsx(M,{icon:"check-circle-2",tone:"hari",label:"TASK HARI INI",value:P,sub:"mulai dikerjakan",reduced:o}),e.jsx(M,{icon:"activity",tone:"sesi",label:"SESI BERJALAN",value:g.length,sub:"wayang dimainkan",reduced:o}),e.jsx(M,{icon:"hand",tone:"tunggu",label:"MENUNGGU KAMU",value:w,sub:"butuh keputusan",reduced:o})]}),e.jsxs("div",{className:"hn-dlg-grid",children:[e.jsxs("div",{className:"hn-dlg-main",children:[e.jsxs("div",{className:"hn-dlg-hero",ref:z,children:[e.jsxs("svg",{className:"hn-dlg-hud",viewBox:"0 0 330 330","aria-hidden":"true",focusable:"false",children:[e.jsx("g",{className:"hn-dlg-hud-a",children:e.jsx("circle",{cx:"165",cy:"165",r:"150",strokeDasharray:"3 14"})}),e.jsx("g",{className:"hn-dlg-hud-b",children:e.jsx("circle",{cx:"165",cy:"165",r:"126",strokeDasharray:"40 22"})})]}),_.length>0&&e.jsx("svg",{className:"hn-dlg-threads","aria-hidden":"true",focusable:"false",children:_.map((n,t)=>e.jsx("path",{d:n.d,className:n.slack?"hn-dlg-thread--slack":void 0,style:n.slack?void 0:{"--d":`${t%6*.3}s`}},t))}),e.jsx("div",{className:"hn-dlg-scan","aria-hidden":"true"}),e.jsxs("div",{className:"hn-dlg-hero-art","aria-hidden":"true",children:[e.jsx("img",{className:"hn-dlg-rig-arm hn-dlg-rig-arm--ul",src:we,alt:""}),e.jsx("img",{className:"hn-dlg-rig-arm hn-dlg-rig-arm--ur",src:ke,alt:""}),e.jsx("img",{className:"hn-dlg-rig-arm hn-dlg-rig-arm--ml",src:Ae,alt:""}),e.jsx("img",{className:"hn-dlg-rig-arm hn-dlg-rig-arm--mr",src:Ee,alt:""}),e.jsx("img",{className:"hn-dlg-rig-body",src:ve,alt:""}),e.jsx("span",{className:"hn-dlg-hand","data-hand":"ul"}),e.jsx("span",{className:"hn-dlg-hand","data-hand":"ur"}),e.jsx("span",{className:"hn-dlg-hand","data-hand":"ml"}),e.jsx("span",{className:"hn-dlg-hand","data-hand":"mr"})]}),s.length===0?e.jsxs("div",{className:"hn-dlg-empty",children:[e.jsx("div",{children:"Panggung sunyi — belum ada project di workspace."}),e.jsx("div",{className:"hn-dlg-empty-hint",children:"Tambahkan project dan sang dalang mengangkat wayangnya."})]}):e.jsxs("ul",{className:"hn-dlg-cards","aria-label":"Wayang project",children:[g.map((n,t)=>{const j=H(n.projectId),r=O(n);return e.jsx("li",{children:e.jsxs("button",{type:"button",className:"hn-dlg-prj","data-puppet":!0,"data-waiting":r||void 0,onClick:()=>c(n.id),"aria-label":`Buka terminal — ${j}, ${J(n)}`,children:[e.jsx("span",{className:r?"hn-dlg-puppet hn-dlg-puppet--still":"hn-dlg-puppet",style:{"--d":`${t%6*.6}s`},children:e.jsx("img",{src:ie(n.projectId),alt:"","aria-hidden":"true"})}),e.jsx("span",{className:"hn-dlg-prj-name",children:j}),e.jsx("span",{className:r?"hn-dlg-prj-sub hn-dlg-prj-sub--amber":"hn-dlg-prj-sub",children:J(n)})]})},n.id)}),E.map(n=>e.jsx("li",{children:e.jsxs("button",{type:"button",className:"hn-dlg-prj hn-dlg-prj--off",onClick:()=>p(n),"aria-label":`Buka project ${n.name}`,children:[e.jsx("span",{className:"hn-dlg-puppet hn-dlg-puppet--still",children:e.jsx("img",{src:ie(n.id),alt:"","aria-hidden":"true"})}),e.jsx("span",{className:"hn-dlg-prj-name",children:n.name}),e.jsx("span",{className:"hn-dlg-prj-sub hn-dlg-prj-sub--off",children:"tersandar di debog"})]})},n.id))]})]}),e.jsxs("button",{type:"button",className:"hn-dlg-cmd",onClick:()=>x("terminal"),"aria-label":"Buka terminal — pusat kendali sesi",children:[e.jsx("span",{className:"hn-dlg-mic","aria-hidden":"true"}),e.jsxs("span",{className:"hn-dlg-cmd-t",children:[e.jsx("b",{children:"Perintah dalang"})," — buka Terminal untuk mengarahkan sesi yang berjalan…"]}),e.jsx("span",{className:"hn-dlg-cmd-k",children:"Terminal"})]})]}),e.jsxs("aside",{className:"hn-dlg-rail",children:[e.jsxs("div",{className:"hn-dlg-card",children:[e.jsx("div",{className:"hn-dlg-rt",children:"AKTIVITAS TERAKHIR"}),V.length===0?e.jsx("div",{className:"hn-dlg-mut",children:"Belum ada project."}):V.map(n=>e.jsxs("div",{className:"hn-dlg-act",children:[e.jsx("span",{className:n.live?"hn-dlg-dot2 hn-dlg-dot2--on":"hn-dlg-dot2"}),e.jsxs("span",{className:"hn-dlg-act-x",children:[e.jsx("b",{children:n.name})," ",n.text]})]},n.id))]}),e.jsxs("div",{className:"hn-dlg-card",children:[e.jsx("div",{className:"hn-dlg-rt",children:"DISTRIBUSI BACKLOG"}),e.jsxs("div",{className:"hn-dlg-donut-wrap",children:[e.jsx("div",{className:"hn-dlg-donut",style:{"--donut":ue},children:e.jsxs("div",{className:"hn-dlg-donut-c",children:[e.jsx("b",{children:$}),e.jsx("span",{children:"backlog"})]})}),e.jsx("div",{className:"hn-dlg-leg",children:q.map(n=>e.jsxs("span",{children:[e.jsx("i",{className:`hn-dlg-seg--${n.cls}`}),n.label," ",e.jsx("b",{children:n.n})]},n.key))})]})]}),e.jsxs("div",{className:"hn-dlg-card",children:[e.jsx("div",{className:"hn-dlg-rt",children:"DIMULAI · 7 HARI"}),e.jsxs("p",{className:"hn-sr-only",children:["Item mulai dikerjakan, 7 hari terakhir: ",b.map(n=>`${n.label} ${n.n}`).join(", ")]}),e.jsxs("div",{className:"hn-dlg-chart-box",children:[e.jsxs("div",{className:"hn-dlg-chart-y","aria-hidden":"true",children:[e.jsx("span",{style:{"--y":"18%"},children:U}),e.jsx("span",{style:{"--y":"78%"},children:"0"})]}),e.jsxs("svg",{viewBox:"0 0 280 100",className:"hn-dlg-chart","aria-hidden":"true",focusable:"false",children:[e.jsx("line",{x1:"24",y1:"18",x2:"252",y2:"18"}),e.jsx("line",{x1:"24",y1:"48",x2:"252",y2:"48"}),e.jsx("line",{x1:"24",y1:"78",x2:"252",y2:"78"}),e.jsx("polyline",{className:"hn-dlg-trend",points:pe}),b.map((n,t)=>e.jsx("circle",{cx:32+t*35,cy:78-n.n/U*60,r:"2.4"},t))]}),e.jsx("div",{className:"hn-dlg-chart-x","aria-hidden":"true",children:b.map((n,t)=>t%2===0?e.jsx("span",{style:{"--x":`${(22+t*35)/280*100}%`},children:n.label},t):null)})]})]})]})]}),e.jsxs("footer",{className:"hn-dlg-foot",children:[e.jsx("span",{"aria-hidden":"true",children:"◈"}),"  HANOMAN · ORKESTRASI CERDAS · EKSEKUSI SEMPURNA  ",e.jsx("span",{"aria-hidden":"true",children:"◈"})]})]})}export{We as DalangHanomanScreen,De as isToday};
@@ -0,0 +1 @@
1
+ .hn-dlg{position:fixed;top:0;right:0;bottom:0;left:0;z-index:100;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;background:var(--term-bg);color:var(--term-fg);padding:max(20px,var(--safe-top, 0px)) 26px max(12px,var(--safe-bottom, 0px))}@media (max-width: 767px){.hn-dlg{padding-inline:var(--space-4)}}.hn-dlg-top{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px 16px}.hn-dlg-brand{display:flex;align-items:center;gap:14px;flex:1 1 260px;min-width:0}.hn-dlg-blencong{height:44px;width:auto;flex:0 0 auto}.hn-dlg-blencong[data-lit]{filter:drop-shadow(0 0 12px color-mix(in srgb,var(--brass-400) 65%,transparent))}.hn-dlg-head{min-width:0;flex:1 1 auto}.hn-dlg-title{margin:0;font-family:var(--font-display);font-size:21px;font-weight:var(--weight-semibold);line-height:var(--leading-tight);color:var(--term-fg)}.hn-dlg-boot{margin:4px 0 0;min-height:15px;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--brass-300)}.hn-dlg-boot:after{content:"▍";color:var(--brass-400);margin-left:2px;animation:hn-dlg-blink 1s steps(1) infinite}@keyframes hn-dlg-blink{50%{opacity:0}}.hn-dlg-summary{margin:var(--space-1) 0 0;font-size:var(--text-md);color:var(--term-fg)}.hn-dlg-link{display:inline-flex;align-items:center;gap:var(--space-2);margin:var(--space-1) 0 0;font-size:var(--text-xs);color:var(--term-dim)}.hn-dlg-dot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--term-dim)}.hn-dlg-link--ok .hn-dlg-dot{background:var(--leaf-500)}.hn-dlg-link--err .hn-dlg-dot{background:var(--clay-500)}.hn-dlg-link--idle .hn-dlg-dot{background:var(--amber-600)}.hn-dlg-bar{display:flex;flex:0 0 auto;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:8px}.hn-dlg-clock{display:inline-flex;flex-wrap:wrap;gap:8px}.hn-dlg-chip{display:inline-flex;align-items:center;gap:7px;padding:7px 12px;white-space:nowrap;border:1px solid var(--term-line);border-radius:var(--radius-md);background:transparent;font-family:var(--font-mono);font-size:12px;color:var(--brass-300);font-variant-numeric:tabular-nums}.hn-dlg-exit{-webkit-appearance:none;-moz-appearance:none;appearance:none;flex:none;width:var(--touch-target);height:var(--touch-target);padding:0;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;border:1px solid var(--term-line);border-radius:var(--radius-md);background:transparent;color:var(--term-dim);transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}.hn-dlg-exit:hover{color:var(--term-fg);border-color:var(--brass-700)}.hn-dlg-exit:focus-visible,.hn-dlg-prj:focus-visible,.hn-dlg-row:focus-visible,.hn-dlg-cmd:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}.hn-dlg-section{margin-top:var(--space-5);min-width:0}.hn-dlg-rt{margin:0 0 var(--space-2);font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;font-weight:var(--weight-medium);color:var(--brass-300)}.hn-dlg-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--term-line)}.hn-dlg-list>li{border-bottom:1px solid var(--term-line)}.hn-dlg-row{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;min-height:var(--touch-target);margin:0;display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-1) var(--space-3);padding:var(--space-2);border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}.hn-dlg-row:hover{background:color-mix(in srgb,var(--term-fg) 4%,transparent)}.hn-dlg-glyph{flex:0 0 24px;display:inline-flex;justify-content:center}.hn-dlg-name{flex:1 1 160px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-mono);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--term-fg)}.hn-dlg-fase{font-size:var(--text-xs);color:var(--term-fg)}.hn-dlg-sesi{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--term-dim)}.hn-dlg-aksi{margin-left:auto;font-size:var(--text-xs);font-weight:var(--weight-medium);color:var(--amber-500);white-space:nowrap}@media (max-width: 767px){.hn-dlg-aksi{margin-left:0}}.hn-dlg-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-top:16px}.hn-dlg-kpi{display:flex;gap:11px;align-items:flex-start;min-width:0;padding:12px 14px;border:1px solid var(--term-line);border-radius:var(--radius-md);background:transparent}.hn-dlg-kpi-body{min-width:0}.hn-dlg-kpi-ic{--tone: var(--brass-400);width:34px;height:34px;flex:none;border-radius:var(--radius-sm);display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--tone) 18%,transparent)}.hn-dlg-kpi-ic svg{stroke:var(--tone)}.hn-dlg-tone-proyek{--tone: var(--wind-500)}.hn-dlg-tone-hari{--tone: var(--leaf-500)}.hn-dlg-tone-sesi{--tone: var(--brass-400)}.hn-dlg-tone-tunggu{--tone: var(--amber-500)}.hn-dlg-kpi-l{display:block;font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;color:var(--term-dim)}.hn-dlg-kpi-v{display:block;font-family:var(--font-display);font-size:25px;font-weight:700;line-height:1.15;color:var(--term-fg);font-variant-numeric:tabular-nums}.hn-dlg-kpi-s{display:block;font-size:11px;color:var(--term-dim);margin-top:1px}.hn-dlg-grid{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:14px;align-items:start;margin-top:14px}.hn-dlg-main{min-width:0}.hn-dlg-hero{position:relative;overflow:hidden;border:1px solid var(--term-line);border-radius:var(--radius-lg);background:radial-gradient(ellipse 75% 95% at 50% 0%,color-mix(in srgb,var(--brass-400) 20%,transparent),transparent 62%);padding:16px 16px 0}.hn-dlg-hud{position:absolute;left:50%;top:128px;transform:translate(-50%,-50%);width:300px;height:300px;pointer-events:none;opacity:.5}.hn-dlg-hud circle{fill:none;stroke:var(--brass-700);stroke-width:1}.hn-dlg-hud-a,.hn-dlg-hud-b{transform-origin:50% 50%}.hn-dlg-hud-a{animation:hn-dlg-rot 26s linear infinite}.hn-dlg-hud-b{animation:hn-dlg-rotr 40s linear infinite}@keyframes hn-dlg-rot{to{transform:rotate(360deg)}}@keyframes hn-dlg-rotr{to{transform:rotate(-360deg)}}.hn-dlg-threads{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;pointer-events:none}.hn-dlg-threads path{fill:none;stroke:var(--brass-500);stroke-width:1.4;stroke-linecap:round;stroke-dasharray:4 8;opacity:.8;animation:hn-dlg-flow 1.5s linear infinite;animation-delay:var(--d, 0s)}.hn-dlg-threads path.hn-dlg-thread--slack{stroke:var(--brass-700);stroke-dasharray:none;opacity:.3;animation:none}@keyframes hn-dlg-flow{to{stroke-dashoffset:-28}}.hn-dlg-scan{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;background:linear-gradient(180deg,transparent 0%,color-mix(in srgb,var(--brass-400) 5%,transparent) 48%,color-mix(in srgb,var(--brass-300) 9%,transparent) 50%,color-mix(in srgb,var(--brass-400) 5%,transparent) 52%,transparent 100%);background-size:100% 240px;background-repeat:no-repeat;background-position:0 -240px;animation:hn-dlg-scan 7s linear infinite}@keyframes hn-dlg-scan{0%{background-position:0 -240px}60%{background-position:0 460px}to{background-position:0 460px}}.hn-dlg-hero-art{position:relative;width:min(540px,94%);aspect-ratio:835 / 582;margin:0 auto;animation:hn-dlg-float 6s ease-in-out infinite}.hn-dlg-hero-art img{position:absolute;display:block;height:auto;filter:drop-shadow(0 0 18px color-mix(in srgb,var(--brass-400) 35%,transparent))}.hn-dlg-rig-body{left:25.88%;top:16.32%;width:48.73%;z-index:2}.hn-dlg-rig-arm{z-index:1;will-change:transform}.hn-dlg-rig-arm--ul{left:5.48%;top:.39%;width:32.03%;transform-origin:85.5% 86.8%;animation:hn-dlg-arm-a 5s ease-in-out infinite}.hn-dlg-rig-arm--ur{left:61.65%;top:0%;width:30.82%;transform-origin:15.1% 87.1%;animation:hn-dlg-arm-b 5.6s ease-in-out infinite}.hn-dlg-rig-arm--ml{left:0%;top:58.84%;width:37.36%;transform-origin:89.2% 24.2%;animation:hn-dlg-arm-b 6.4s ease-in-out infinite}.hn-dlg-rig-arm--mr{left:61.8%;top:58.32%;width:38.2%;transform-origin:11.1% 24.3%;animation:hn-dlg-arm-a 7s ease-in-out infinite}@keyframes hn-dlg-arm-a{0%,to{transform:rotate(-2.5deg)}50%{transform:rotate(3deg)}}@keyframes hn-dlg-arm-b{0%,to{transform:rotate(2.5deg)}50%{transform:rotate(-3deg)}}.hn-dlg-hand{position:absolute;width:2px;height:2px;pointer-events:none}.hn-dlg-hand[data-hand=ul]{left:15.5%;top:9.9%}.hn-dlg-hand[data-hand=ur]{left:82.7%;top:9.6%}.hn-dlg-hand[data-hand=ml]{left:10.2%;top:76.1%}.hn-dlg-hand[data-hand=mr]{left:89.5%;top:75.5%}@keyframes hn-dlg-float{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@media (max-width: 767px){.hn-dlg-hero-art{width:min(360px,100%)}}.hn-dlg-empty{position:relative;text-align:center;padding:26px 0 30px;color:var(--term-dim);font-size:12.5px;line-height:1.7}.hn-dlg-empty-hint{margin-top:var(--space-1);font-size:var(--text-sm);color:var(--term-dim)}.hn-dlg-cards{position:relative;list-style:none;margin:0;padding:18px 0 16px;display:flex;flex-wrap:wrap;gap:12px;align-items:stretch;justify-content:center}.hn-dlg-cards>li{display:flex;min-width:0}.hn-dlg-prj{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;text-align:left;cursor:pointer;width:168px;max-width:100%;background:color-mix(in srgb,var(--term-bg) 85%,black);border:1px solid color-mix(in srgb,var(--brass-500) 45%,transparent);border-radius:var(--radius-md);padding:8px 12px 10px;color:var(--term-fg);box-shadow:0 0 16px color-mix(in srgb,var(--brass-500) 22%,transparent);transition:transform var(--dur-base) var(--ease-out),box-shadow var(--dur-base) var(--ease-out)}.hn-dlg-prj:hover{transform:translateY(-3px);box-shadow:0 0 24px color-mix(in srgb,var(--brass-500) 40%,transparent)}.hn-dlg-prj[data-waiting]{border-color:var(--amber-600);box-shadow:0 0 16px color-mix(in srgb,var(--amber-500) 30%,transparent)}.hn-dlg-prj--off{border-color:var(--term-line);box-shadow:none}.hn-dlg-prj--off:hover{box-shadow:0 0 14px color-mix(in srgb,var(--brass-500) 14%,transparent)}.hn-dlg-prj--off .hn-dlg-puppet img{filter:grayscale(.85) brightness(.55)}.hn-dlg-prj--off .hn-dlg-prj-name{color:var(--term-dim)}.hn-dlg-puppet{display:block;width:fit-content;margin:0 auto 6px;transform-origin:50% 0%;animation:hn-dlg-sway 3.6s var(--ease-inout) infinite alternate;animation-delay:var(--d, 0s)}.hn-dlg-puppet--still{animation:none;transform:rotate(-3deg)}.hn-dlg-puppet img{display:block;height:108px;width:auto;filter:drop-shadow(0 0 10px color-mix(in srgb,var(--brass-300) 50%,transparent))}.hn-dlg-prj--off .hn-dlg-puppet img{height:88px}@keyframes hn-dlg-sway{0%{transform:rotate(-2.5deg)}to{transform:rotate(2.5deg)}}.hn-dlg-prj-name{display:block;font-family:var(--font-mono);font-size:12px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hn-dlg-prj-sub{display:block;font-family:var(--font-mono);font-size:11px;color:var(--brass-400);margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hn-dlg-prj-sub--amber{color:var(--amber-500)}.hn-dlg-prj-sub--off{color:var(--term-dim)}.hn-dlg-cmd{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;cursor:pointer;width:100%;margin-top:12px;display:flex;align-items:center;gap:12px;padding:11px 15px;text-align:left;border:1px solid var(--brass-700);border-radius:var(--radius-lg);background:linear-gradient(90deg,color-mix(in srgb,var(--brass-400) 12%,transparent),color-mix(in srgb,var(--brass-400) 3%,transparent));color:var(--term-fg);transition:border-color var(--dur-base) var(--ease-out)}.hn-dlg-cmd:hover{border-color:var(--brass-500)}.hn-dlg-mic{position:relative;width:11px;height:11px;border-radius:50%;background:var(--brass-500);flex:none}.hn-dlg-mic:before{content:"";position:absolute;top:-5px;right:-5px;bottom:-5px;left:-5px;border-radius:50%;border:1px solid var(--brass-500);opacity:0;animation:hn-dlg-ping 1.8s ease-out infinite}@keyframes hn-dlg-ping{0%{transform:scale(.85);opacity:.8}70%{transform:scale(1.4);opacity:0}to{opacity:0}}.hn-dlg-cmd-t{font-family:var(--font-mono);font-size:12px;color:var(--term-dim);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hn-dlg-cmd-t b{color:var(--brass-300);font-weight:500}.hn-dlg-cmd-k{margin-left:auto;flex:none;font-family:var(--font-mono);font-size:11px;color:var(--term-dim);border:1px solid var(--term-line);border-radius:var(--radius-sm);padding:2px 8px}.hn-dlg-rail{display:flex;flex-direction:column;gap:12px;min-width:0}.hn-dlg-card{border:1px solid var(--term-line);border-radius:var(--radius-md);background:transparent;padding:12px 14px}.hn-dlg-card .hn-dlg-rt{margin-bottom:9px}.hn-dlg-mut{font-size:12px;color:var(--term-dim)}.hn-dlg-act{display:flex;gap:9px;align-items:flex-start;padding:6px 0;border-bottom:1px solid var(--term-line);font-size:11.5px}.hn-dlg-act:last-of-type{border-bottom:0}.hn-dlg-dot2{width:7px;height:7px;border-radius:50%;background:var(--term-line);flex:none;margin-top:4px}.hn-dlg-dot2--on{background:var(--brass-500)}.hn-dlg-act-x{color:var(--term-dim);line-height:1.5;min-width:0;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.hn-dlg-act-x b{color:var(--term-fg);font-family:var(--font-mono);font-size:11px;font-weight:500}.hn-dlg-donut-wrap{display:flex;align-items:center;gap:12px}.hn-dlg-donut{position:relative;width:112px;height:112px;flex:none;border-radius:50%;background:var(--donut, conic-gradient(var(--term-line) 0% 100%))}.hn-dlg-donut-c{position:absolute;top:13px;right:13px;bottom:13px;left:13px;border-radius:50%;background:var(--term-bg);display:flex;flex-direction:column;align-items:center;justify-content:center}.hn-dlg-donut-c b{font-family:var(--font-display);font-size:23px;color:var(--term-fg);line-height:1}.hn-dlg-donut-c span{font-size:11px;color:var(--term-dim);margin-top:2px}.hn-dlg-leg{display:flex;flex-direction:column;gap:6px;font-size:11px;color:var(--term-dim)}.hn-dlg-leg b{color:var(--term-fg)}.hn-dlg-leg i{display:inline-block;width:9px;height:9px;border-radius:3px;margin-right:7px}.hn-dlg-leg i.hn-dlg-seg--executing{background:var(--wind-500)}.hn-dlg-leg i.hn-dlg-seg--done{background:var(--leaf-500)}.hn-dlg-leg i.hn-dlg-seg--planned{background:var(--amber-500)}.hn-dlg-leg i.hn-dlg-seg--spec{background:var(--brass-400)}.hn-dlg-chart-box{display:grid;grid-template-columns:18px minmax(0,1fr);column-gap:4px}.hn-dlg-chart-y{position:relative;grid-column:1;grid-row:1}.hn-dlg-chart-y span{position:absolute;left:0;top:var(--y);transform:translateY(-50%);font-family:var(--font-mono);font-size:11px;color:var(--term-dim)}.hn-dlg-chart{grid-column:2;grid-row:1;display:block;width:100%;height:auto;pointer-events:none}.hn-dlg-chart line{stroke:var(--term-line);stroke-width:.6}.hn-dlg-chart circle{fill:var(--wind-500)}.hn-dlg-trend{fill:none;stroke:var(--wind-500);stroke-width:1.6}.hn-dlg-chart-x{position:relative;grid-column:2;grid-row:2;height:16px}.hn-dlg-chart-x span{position:absolute;top:2px;left:var(--x);white-space:nowrap;font-family:var(--font-mono);font-size:11px;color:var(--term-dim)}.hn-dlg-foot{text-align:center;font-family:var(--font-mono);font-size:11px;letter-spacing:.28em;color:var(--term-dim);padding:12px 0 4px}@media (max-width: 1199px){.hn-dlg-grid{grid-template-columns:1fr}}@media (max-width: 767px){.hn-dlg-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (prefers-reduced-motion: reduce){.hn-dlg-hud-a,.hn-dlg-hud-b,.hn-dlg-scan,.hn-dlg-hero-art,.hn-dlg-rig-arm,.hn-dlg-puppet,.hn-dlg-threads path,.hn-dlg-boot:after,.hn-dlg-mic:before{animation:none}}
@@ -1 +1 @@
1
- import{j as e,M as r,aO as d,aQ as a,m as x}from"./index-DmnwLncG.js";import"./react-DfGhg7ZW.js";function f({path:i,text:o,eyebrow:n,download:t,onClose:s}){const l=i.slice(i.lastIndexOf("/")+1)||i;return e.jsx(r,{open:!0,title:l,eyebrow:n??i,icon:"book-open",onClose:s,width:980,fillHeight:!0,children:e.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",minHeight:0},children:[t&&e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",paddingBottom:6,borderBottom:"1px solid var(--border-hair)",marginBottom:8},children:e.jsx(d,{href:t})}),e.jsx("div",{"data-testid":"doc-preview-scroll",style:{flex:"1 1 0",minHeight:0,overflow:"auto",padding:"0 4px 8px"},children:o?e.jsx(a,{text:o,name:i}):e.jsx(x,{kind:"empty",icon:"file-text",title:"Berkas kosong",hint:i})})]})})}export{f as D};
1
+ import{j as e,M as r,aO as d,aQ as a,m as x}from"./index-DYWU10xI.js";import"./react-DfGhg7ZW.js";function f({path:i,text:o,eyebrow:n,download:t,onClose:s}){const l=i.slice(i.lastIndexOf("/")+1)||i;return e.jsx(r,{open:!0,title:l,eyebrow:n??i,icon:"book-open",onClose:s,width:980,fillHeight:!0,children:e.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",minHeight:0},children:[t&&e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",paddingBottom:6,borderBottom:"1px solid var(--border-hair)",marginBottom:8},children:e.jsx(d,{href:t})}),e.jsx("div",{"data-testid":"doc-preview-scroll",style:{flex:"1 1 0",minHeight:0,overflow:"auto",padding:"0 4px 8px"},children:o?e.jsx(a,{text:o,name:i}):e.jsx(x,{kind:"empty",icon:"file-text",title:"Berkas kosong",hint:i})})]})})}export{f as D};
@@ -1,3 +1,3 @@
1
- import{q as Ne,d as De,h as S,j as e,m as w,I as N,U as Se,Y as Ce,B as O,f as Ke,n as q,O as Le,aO as Me,aQ as te,D as $e,aT as ze,i as ie}from"./index-DmnwLncG.js";import{R as o}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";function de(n){let t={...n,kids:n.kids.map(de)};for(;!t.cat&&t.kids.length===1;){const i=t.kids[0];t={...i,label:t.label+"/"+i.label}}return t}function re(n){const t={path:"",kids:[]};for(const i of n){if(i.cat==="."){t.kids.push({path:".",label:".",cat:i,kids:[]});continue}let l=t;for(const u of i.cat.split("/")){const k=l.path?l.path+"/"+u:u;let m=l.kids.find(s=>s.path===k);m||(m={path:k,label:u,kids:[]},l.kids.push(m)),l=m}l.cat=i}return t.kids.map(de)}function le(n){const t=n.find(i=>i.scored&&i.linked)??n.find(i=>i.scored)??n[0];return t&&t.files[0]?`${t.cat}/${t.files[0]}`:""}function oe(n){return/(^|\/)adr(s)?(\/|$)/i.test(n)?"ADR":/(^|\/)prd(s)?(\/|$)/i.test(n)?"PRD":/(^|\/)spec(s|ification)?(\/|$)/i.test(n)?"Spec":"Lainnya"}const Fe=["PRD","Spec","ADR","Lainnya"],ue=n=>`dir:${n}`,Pe=(n,t)=>!!t&&t.startsWith(n.path+"/");function he({node:n,depth:t,ctx:i}){var h,p,y;const l=Pe(n,i.selected),[u,k]=o.useState(l);o.useEffect(()=>{l&&k(!0)},[l]);const m=((h=n.cat)==null?void 0:h.scored)??!0,s=((p=n.cat)==null?void 0:p.linked)??!0,v=ue(n.path),b=()=>k(d=>!d),c=d=>{d.key==="Enter"||d.key===" "?(d.preventDefault(),b()):d.key==="ArrowRight"&&!u?(d.preventDefault(),k(!0)):d.key==="ArrowLeft"&&u&&(d.preventDefault(),k(!1))};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{role:"treeitem","aria-level":t+1,"aria-expanded":u,tabIndex:i.tabbable===v?0:-1,className:"hn-docs-node hn-docs-node-dir",style:{paddingLeft:6+t*12},onClick:b,onKeyDown:c,onFocus:()=>i.setFocusKey(v),children:[e.jsx(N,{name:u?"chevron-down":"chevron-right",size:14,color:"var(--text-subtle)"}),e.jsx(N,{name:"folder",size:15,color:m?s?"var(--brass-500)":"var(--clay-500)":"var(--text-subtle)"}),e.jsxs("span",{className:"hn-docs-dir-label",children:[n.label,"/"]}),n.cat&&m&&(n.cat.linked?e.jsx(N,{name:"link",size:13,color:"var(--leaf-600)"}):e.jsx(N,{name:"unlink",size:13,color:"var(--clay-500)"}))]}),u&&e.jsxs("div",{role:"group",className:"hn-docs-group",children:[n.kids.map(d=>e.jsx(he,{node:d,depth:t+1,ctx:i},d.path)),(y=n.cat)==null?void 0:y.files.map(d=>{const f=n.path+"/"+d,j=f===i.selected;return e.jsxs("div",{role:"treeitem","aria-level":t+2,"aria-selected":j,"aria-current":j?"true":void 0,tabIndex:i.tabbable===f?0:-1,className:`hn-docs-node hn-docs-node-file${j?" is-selected":""}`,style:{paddingLeft:18+t*12},onClick:()=>i.onSelect(f),onFocus:()=>i.setFocusKey(f),onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),i.onSelect(f))},children:[e.jsx(N,{name:"file-text",size:13,color:j?"var(--brass-700)":"var(--text-subtle)"}),e.jsx("span",{className:`hn-docs-file-label${!m||s?"":" is-unlinked"}`,children:d})]},d)})]})]})}function ce({label:n,nodes:t,selected:i,onSelect:l}){const[u,k]=o.useState(null),m=t[0]?ue(t[0].path):"",v={selected:i,onSelect:l,tabbable:u??(i||m),setFocusKey:c=>k(c)},b=c=>{if(c.key!=="ArrowDown"&&c.key!=="ArrowUp")return;const h=Array.from(c.currentTarget.querySelectorAll('[role="treeitem"]')),p=h.indexOf(document.activeElement);if(p<0)return;c.preventDefault();const y=h[Math.min(h.length-1,Math.max(0,p+(c.key==="ArrowDown"?1:-1)))];y==null||y.focus()};return e.jsx("div",{role:"tree","aria-label":n,className:"hn-docs-tree",onKeyDown:b,children:t.map(c=>e.jsx(he,{node:c,depth:0,ctx:v},c.path))})}function Ie({projectId:n,projectName:t,docStatus:i}){const[l,u]=o.useState([]),[k,m]=o.useState(0),[s,v]=Ne(ze("docs",n),"selected","",$e),[b,c]=o.useState({}),[h,p]=o.useState("preview"),[y,d]=o.useState("tree"),[f,j]=o.useState(""),[g,U]=o.useState(!1),[L,W]=o.useState(!1),[G,C]=o.useState(""),[$,Q]=o.useState(""),[D,z]=o.useState("all"),{confirm:J,dialog:me}=De(),[F,K]=o.useState("loading"),[pe,ke]=o.useState(0);o.useEffect(()=>{let a=!0;return K("loading"),S.getDocs(n).then(r=>{if(!a)return;const x=r.tree;u(x),m(r.coverage),c({}),p("preview"),K("ready"),C(""),Q(""),z("all"),v(le(x))}).catch(()=>{a&&(u([]),v(""),K("error"))}),()=>{a=!1}},[n,pe]),o.useEffect(()=>{if(!s||s in b)return;let a=!0;return S.getDoc(n,s).then(r=>{a&&c(x=>({...x,[s]:r.content}))}).catch(()=>{a&&c(r=>({...r,[s]:null}))}),()=>{a=!1}},[s,n,b]);const P=!!s&&!(s in b),A=s?b[s]===null:!1,fe=()=>c(a=>{const r={...a};return delete r[s],r}),V=a=>D==="all"||oe(a.cat)===D,xe=re(l.filter(a=>a.scored&&V(a))),Y=re(l.filter(a=>!a.scored&&V(a))),B=b[s]??"",be=s.includes("/")?s.slice(0,s.lastIndexOf("/")):".",T=l.find(a=>a.cat===be),_=s,E=h==="edit"&&f!==B,I=o.useMemo(()=>l.flatMap(a=>a.files.map(r=>({key:`${a.cat}/${r}`,scored:a.scored,linked:a.linked,kind:oe(a.cat)}))),[l]),R=$.trim().toLowerCase(),X=R?I.filter(a=>(D==="all"||a.kind===D)&&a.key.toLowerCase().includes(R)):[],ve=o.useMemo(()=>{const a={PRD:0,Spec:0,ADR:0,Lainnya:0};for(const r of I)a[r.kind]+=1;return a},[I]),ye=i==="broken"?"broken":i==="drift"?"drift":"ok";function Z(a){if(!E){p("preview"),a();return}J({title:"Buang perubahan?",eyebrow:s,message:"Isi dokumen yang kamu ubah belum disimpan.",impact:["Perubahan di editor hilang dan tak bisa dikembalikan dari dashboard."],confirmLabel:"Buang perubahan",cancelLabel:"Lanjut mengedit",tone:"danger",icon:"trash-2"}).then(r=>{r&&(p("preview"),a())})}function ge(){C(""),j(B),p("edit")}const ee=()=>Z(()=>{});async function ae(){if(!(L||!s)){W(!0),C("");try{await S.putDoc(n,s,f),c(a=>({...a,[s]:f})),p("preview")}catch(a){C(ie("menyimpan dokumen",a))}finally{W(!1)}}}function H(a){Z(()=>{v(a),p("preview"),d("viewer")})}async function se(){const a=await S.getDocs(n),r=a.tree;u(r),m(a.coverage),r.some(x=>x.files.some(M=>`${x.cat}/${M}`===s))||v(le(r))}async function ne(){if(!g){U(!0);try{await se()}catch{K("error")}finally{U(!1)}}}async function je(){if(!s)return;const a=s;let r=!1;try{r=await J({title:`Hapus ${a}?`,eyebrow:"Source of Truth",message:"Dokumen ini adalah Source of Truth project. Berkas aslinya di disk ikut dihapus.",impact:["Berkas di disk dihapus dan tak bisa dikembalikan dari dashboard.","Kategori indeks dihitung ulang setelah penghapusan."],confirmLabel:"Hapus dokumen",tone:"danger",icon:"trash-2",run:()=>S.deleteDoc(n,a)})}catch(x){C(ie("menghapus dokumen",x));return}if(r){c(x=>{const M={...x};return delete M[a],M});try{await se()}catch{K("error")}}}const we=F==="loading"?e.jsx(w,{kind:"loading",compact:!0,title:"Memuat indeks…"}):F==="error"?e.jsx(w,{kind:"error",compact:!0,title:"Gagal memuat indeks dokumen",hint:t,action:()=>ke(a=>a+1)}):l.length===0?e.jsx(w,{kind:"empty",compact:!0,icon:"folder-open",title:"Belum ada dokumen",hint:"Belum ada Markdown di repo ini.",action:ne,actionLabel:"Muat ulang",actionIcon:"radar"}):R?X.length===0?e.jsx(w,{kind:"empty",compact:!0,icon:"search",title:"Tak ada berkas cocok",hint:`Tak ada yang cocok dengan “${$.trim()}”.`}):e.jsx("div",{role:"list","aria-label":"Hasil pencarian berkas",className:"hn-docs-results",children:X.map(a=>e.jsxs("button",{type:"button","aria-current":a.key===s?"true":void 0,onClick:()=>H(a.key),className:`hn-docs-result${a.key===s?" is-selected":""}`,children:[e.jsx(N,{name:"file-text",size:13,color:"var(--text-subtle)"}),e.jsx("span",{className:"hn-prj-mono",children:a.key}),e.jsx("span",{className:"hn-docs-result-kind",children:a.kind})]},a.key))}):e.jsxs(e.Fragment,{children:[e.jsx(ce,{label:"Berkas dokumen",nodes:xe,selected:s,onSelect:H}),Y.length>0&&e.jsxs("div",{className:"hn-docs-unscored",children:[e.jsx("div",{className:"hn-eyebrow hn-docs-unscored-label",children:"Lainnya (tidak dinilai)"}),e.jsx(ce,{label:"Dokumen tidak dinilai",nodes:Y,selected:s,onSelect:H})]})]});return e.jsxs(e.Fragment,{children:[e.jsx(Se,{ariaLabel:"Panel Dokumen",active:y,onActiveChange:a=>d(a),masterWidth:288,className:"hn-workspace-panels",panels:[{id:"tree",label:"Indeks",className:"hn-panel-flex",content:e.jsxs("aside",{"aria-label":"Indeks dokumen",className:"hn-docs-index",children:[e.jsxs("div",{className:"hn-docs-index-head",children:[e.jsxs("span",{className:"hn-eyebrow",children:["dokumen · ",t]}),e.jsxs("div",{className:"hn-docs-index-actions",children:[e.jsx(Ce,{status:ye,size:"sm"}),e.jsx(O,{size:"sm",variant:"ghost",leftIcon:g?"loader":"radar",onClick:ne,disabled:g,children:g?"Memuat…":"Muat ulang"})]})]}),F==="ready"&&l.length>0&&e.jsxs("div",{className:"hn-docs-index-tools",children:[e.jsx(Ke,{size:"sm","aria-label":"Cari berkas dokumen",leftIcon:"search",value:$,placeholder:"mis. product/prd",onChange:a=>Q(a.target.value),className:"hn-prj-full"}),e.jsxs("div",{role:"group","aria-label":"Kategori dokumen",className:"hn-prj-chips",children:[e.jsx("button",{type:"button",className:"hn-prj-chip hn-touch-target","aria-pressed":D==="all",onClick:()=>z("all"),children:"Semua"}),Fe.map(a=>e.jsxs("button",{type:"button",className:"hn-prj-chip hn-touch-target","aria-pressed":D===a,onClick:()=>z(a),children:[a,e.jsx("span",{className:"hn-prj-chip-count",children:ve[a]})]},a))]}),e.jsxs("span",{className:"hn-docs-cov",title:"Persentase kategori yang terindeks",children:["Cakupan ",Math.round(k),"%"]})]}),e.jsx("div",{className:"hn-docs-tree-scroll",children:we})]})},{id:"viewer",label:"Dokumen",className:"hn-panel-flex",content:e.jsxs("section",{"aria-label":"Isi dokumen",className:"hn-docs-viewer",style:{display:"flex",flexDirection:"column",minHeight:0},children:[e.jsxs("div",{className:"hn-docs-viewer-head",children:[e.jsx(N,{name:"file-text",size:15,color:"var(--text-muted)"}),e.jsx("span",{className:"hn-prj-mono hn-docs-path",children:_}),T&&T.scored&&(T.linked?e.jsx(q,{tone:"ok",size:"sm",icon:"link",children:"terindeks"}):e.jsx(q,{tone:"err",size:"sm",icon:"unlink",children:"tak tertaut"})),e.jsx("span",{className:"hn-grow"}),e.jsxs("div",{role:"group","aria-label":"Mode dokumen",className:"hn-prj-seg",children:[e.jsx("button",{type:"button","aria-pressed":h==="preview",className:"hn-touch-target",onClick:()=>{h==="edit"&&ee()},children:"Baca"}),e.jsx("button",{type:"button","aria-pressed":h==="edit",className:"hn-touch-target",onClick:()=>{h!=="edit"&&ge()},disabled:!s||P||A,children:"Edit"})]}),h==="preview"&&e.jsx(Le,{label:"Aksi untuk dokumen",icon:"ellipsis",items:[{key:"delete",label:"Hapus dokumen…",icon:"trash-2",tone:"danger",disabled:!s,onSelect:()=>{je()}}],children:e.jsx(Me,{href:a=>S.docDownloadUrl(n,s,a),disabled:!s||P||A})})]}),h==="edit"&&e.jsxs("div",{role:"region","aria-label":"Simpan perubahan",className:"hn-docs-savebar",children:[E?e.jsx(q,{tone:"warn",size:"sm",children:"belum disimpan"}):e.jsx("span",{className:"hn-prj-hint",children:"Tak ada perubahan"}),e.jsx("span",{className:"hn-grow"}),e.jsx(O,{size:"sm",variant:"ghost",onClick:ee,disabled:L,children:"Batal"}),e.jsx(O,{size:"sm",leftIcon:"check",onClick:()=>void ae(),loading:L,disabled:L||!E,children:"Simpan"})]}),G&&e.jsx("div",{role:"alert",className:"hn-docs-error",children:G}),h==="preview"?e.jsx("div",{"data-testid":"doc-preview-scroll",className:"hn-docs-body",style:{flex:"1 1 auto",minHeight:0,overflow:"auto"},children:s?P?e.jsx(w,{kind:"loading",title:"Memuat dokumen…",hint:s}):A?e.jsx(w,{kind:"error",title:"Gagal memuat dokumen",hint:s,action:fe}):e.jsx("div",{className:"hn-docs-read",children:e.jsx(te,{text:B,name:s})}):e.jsx(w,{kind:"empty",icon:"file-text",title:"Tidak ada dokumen dipilih",hint:"Pilih file dari indeks di kiri."})}):e.jsxs("div",{className:"hn-docs-edit",children:[e.jsxs("div",{className:"hn-docs-edit-pane",children:[e.jsx("div",{className:"hn-docs-edit-label",children:e.jsx("span",{className:"hn-eyebrow",children:"Markdown"})}),e.jsx("textarea",{"aria-label":`Isi ${_}`,value:f,spellCheck:!1,onChange:a=>j(a.target.value),onKeyDown:a=>{(a.metaKey||a.ctrlKey)&&a.key.toLowerCase()==="s"&&(a.preventDefault(),ae())},placeholder:`# Judul dokumen
1
+ import{q as Ne,d as De,h as S,j as e,m as w,I as N,U as Se,Y as Ce,B as O,f as Ke,n as q,O as Le,aO as Me,aQ as te,D as $e,aT as ze,i as ie}from"./index-DYWU10xI.js";import{R as o}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";function de(n){let t={...n,kids:n.kids.map(de)};for(;!t.cat&&t.kids.length===1;){const i=t.kids[0];t={...i,label:t.label+"/"+i.label}}return t}function re(n){const t={path:"",kids:[]};for(const i of n){if(i.cat==="."){t.kids.push({path:".",label:".",cat:i,kids:[]});continue}let l=t;for(const u of i.cat.split("/")){const k=l.path?l.path+"/"+u:u;let m=l.kids.find(s=>s.path===k);m||(m={path:k,label:u,kids:[]},l.kids.push(m)),l=m}l.cat=i}return t.kids.map(de)}function le(n){const t=n.find(i=>i.scored&&i.linked)??n.find(i=>i.scored)??n[0];return t&&t.files[0]?`${t.cat}/${t.files[0]}`:""}function oe(n){return/(^|\/)adr(s)?(\/|$)/i.test(n)?"ADR":/(^|\/)prd(s)?(\/|$)/i.test(n)?"PRD":/(^|\/)spec(s|ification)?(\/|$)/i.test(n)?"Spec":"Lainnya"}const Fe=["PRD","Spec","ADR","Lainnya"],ue=n=>`dir:${n}`,Pe=(n,t)=>!!t&&t.startsWith(n.path+"/");function he({node:n,depth:t,ctx:i}){var h,p,y;const l=Pe(n,i.selected),[u,k]=o.useState(l);o.useEffect(()=>{l&&k(!0)},[l]);const m=((h=n.cat)==null?void 0:h.scored)??!0,s=((p=n.cat)==null?void 0:p.linked)??!0,v=ue(n.path),b=()=>k(d=>!d),c=d=>{d.key==="Enter"||d.key===" "?(d.preventDefault(),b()):d.key==="ArrowRight"&&!u?(d.preventDefault(),k(!0)):d.key==="ArrowLeft"&&u&&(d.preventDefault(),k(!1))};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{role:"treeitem","aria-level":t+1,"aria-expanded":u,tabIndex:i.tabbable===v?0:-1,className:"hn-docs-node hn-docs-node-dir",style:{paddingLeft:6+t*12},onClick:b,onKeyDown:c,onFocus:()=>i.setFocusKey(v),children:[e.jsx(N,{name:u?"chevron-down":"chevron-right",size:14,color:"var(--text-subtle)"}),e.jsx(N,{name:"folder",size:15,color:m?s?"var(--brass-500)":"var(--clay-500)":"var(--text-subtle)"}),e.jsxs("span",{className:"hn-docs-dir-label",children:[n.label,"/"]}),n.cat&&m&&(n.cat.linked?e.jsx(N,{name:"link",size:13,color:"var(--leaf-600)"}):e.jsx(N,{name:"unlink",size:13,color:"var(--clay-500)"}))]}),u&&e.jsxs("div",{role:"group",className:"hn-docs-group",children:[n.kids.map(d=>e.jsx(he,{node:d,depth:t+1,ctx:i},d.path)),(y=n.cat)==null?void 0:y.files.map(d=>{const f=n.path+"/"+d,j=f===i.selected;return e.jsxs("div",{role:"treeitem","aria-level":t+2,"aria-selected":j,"aria-current":j?"true":void 0,tabIndex:i.tabbable===f?0:-1,className:`hn-docs-node hn-docs-node-file${j?" is-selected":""}`,style:{paddingLeft:18+t*12},onClick:()=>i.onSelect(f),onFocus:()=>i.setFocusKey(f),onKeyDown:g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),i.onSelect(f))},children:[e.jsx(N,{name:"file-text",size:13,color:j?"var(--brass-700)":"var(--text-subtle)"}),e.jsx("span",{className:`hn-docs-file-label${!m||s?"":" is-unlinked"}`,children:d})]},d)})]})]})}function ce({label:n,nodes:t,selected:i,onSelect:l}){const[u,k]=o.useState(null),m=t[0]?ue(t[0].path):"",v={selected:i,onSelect:l,tabbable:u??(i||m),setFocusKey:c=>k(c)},b=c=>{if(c.key!=="ArrowDown"&&c.key!=="ArrowUp")return;const h=Array.from(c.currentTarget.querySelectorAll('[role="treeitem"]')),p=h.indexOf(document.activeElement);if(p<0)return;c.preventDefault();const y=h[Math.min(h.length-1,Math.max(0,p+(c.key==="ArrowDown"?1:-1)))];y==null||y.focus()};return e.jsx("div",{role:"tree","aria-label":n,className:"hn-docs-tree",onKeyDown:b,children:t.map(c=>e.jsx(he,{node:c,depth:0,ctx:v},c.path))})}function Ie({projectId:n,projectName:t,docStatus:i}){const[l,u]=o.useState([]),[k,m]=o.useState(0),[s,v]=Ne(ze("docs",n),"selected","",$e),[b,c]=o.useState({}),[h,p]=o.useState("preview"),[y,d]=o.useState("tree"),[f,j]=o.useState(""),[g,U]=o.useState(!1),[L,W]=o.useState(!1),[G,C]=o.useState(""),[$,Q]=o.useState(""),[D,z]=o.useState("all"),{confirm:J,dialog:me}=De(),[F,K]=o.useState("loading"),[pe,ke]=o.useState(0);o.useEffect(()=>{let a=!0;return K("loading"),S.getDocs(n).then(r=>{if(!a)return;const x=r.tree;u(x),m(r.coverage),c({}),p("preview"),K("ready"),C(""),Q(""),z("all"),v(le(x))}).catch(()=>{a&&(u([]),v(""),K("error"))}),()=>{a=!1}},[n,pe]),o.useEffect(()=>{if(!s||s in b)return;let a=!0;return S.getDoc(n,s).then(r=>{a&&c(x=>({...x,[s]:r.content}))}).catch(()=>{a&&c(r=>({...r,[s]:null}))}),()=>{a=!1}},[s,n,b]);const P=!!s&&!(s in b),A=s?b[s]===null:!1,fe=()=>c(a=>{const r={...a};return delete r[s],r}),V=a=>D==="all"||oe(a.cat)===D,xe=re(l.filter(a=>a.scored&&V(a))),Y=re(l.filter(a=>!a.scored&&V(a))),B=b[s]??"",be=s.includes("/")?s.slice(0,s.lastIndexOf("/")):".",T=l.find(a=>a.cat===be),_=s,E=h==="edit"&&f!==B,I=o.useMemo(()=>l.flatMap(a=>a.files.map(r=>({key:`${a.cat}/${r}`,scored:a.scored,linked:a.linked,kind:oe(a.cat)}))),[l]),R=$.trim().toLowerCase(),X=R?I.filter(a=>(D==="all"||a.kind===D)&&a.key.toLowerCase().includes(R)):[],ve=o.useMemo(()=>{const a={PRD:0,Spec:0,ADR:0,Lainnya:0};for(const r of I)a[r.kind]+=1;return a},[I]),ye=i==="broken"?"broken":i==="drift"?"drift":"ok";function Z(a){if(!E){p("preview"),a();return}J({title:"Buang perubahan?",eyebrow:s,message:"Isi dokumen yang kamu ubah belum disimpan.",impact:["Perubahan di editor hilang dan tak bisa dikembalikan dari dashboard."],confirmLabel:"Buang perubahan",cancelLabel:"Lanjut mengedit",tone:"danger",icon:"trash-2"}).then(r=>{r&&(p("preview"),a())})}function ge(){C(""),j(B),p("edit")}const ee=()=>Z(()=>{});async function ae(){if(!(L||!s)){W(!0),C("");try{await S.putDoc(n,s,f),c(a=>({...a,[s]:f})),p("preview")}catch(a){C(ie("menyimpan dokumen",a))}finally{W(!1)}}}function H(a){Z(()=>{v(a),p("preview"),d("viewer")})}async function se(){const a=await S.getDocs(n),r=a.tree;u(r),m(a.coverage),r.some(x=>x.files.some(M=>`${x.cat}/${M}`===s))||v(le(r))}async function ne(){if(!g){U(!0);try{await se()}catch{K("error")}finally{U(!1)}}}async function je(){if(!s)return;const a=s;let r=!1;try{r=await J({title:`Hapus ${a}?`,eyebrow:"Source of Truth",message:"Dokumen ini adalah Source of Truth project. Berkas aslinya di disk ikut dihapus.",impact:["Berkas di disk dihapus dan tak bisa dikembalikan dari dashboard.","Kategori indeks dihitung ulang setelah penghapusan."],confirmLabel:"Hapus dokumen",tone:"danger",icon:"trash-2",run:()=>S.deleteDoc(n,a)})}catch(x){C(ie("menghapus dokumen",x));return}if(r){c(x=>{const M={...x};return delete M[a],M});try{await se()}catch{K("error")}}}const we=F==="loading"?e.jsx(w,{kind:"loading",compact:!0,title:"Memuat indeks…"}):F==="error"?e.jsx(w,{kind:"error",compact:!0,title:"Gagal memuat indeks dokumen",hint:t,action:()=>ke(a=>a+1)}):l.length===0?e.jsx(w,{kind:"empty",compact:!0,icon:"folder-open",title:"Belum ada dokumen",hint:"Belum ada Markdown di repo ini.",action:ne,actionLabel:"Muat ulang",actionIcon:"radar"}):R?X.length===0?e.jsx(w,{kind:"empty",compact:!0,icon:"search",title:"Tak ada berkas cocok",hint:`Tak ada yang cocok dengan “${$.trim()}”.`}):e.jsx("div",{role:"list","aria-label":"Hasil pencarian berkas",className:"hn-docs-results",children:X.map(a=>e.jsxs("button",{type:"button","aria-current":a.key===s?"true":void 0,onClick:()=>H(a.key),className:`hn-docs-result${a.key===s?" is-selected":""}`,children:[e.jsx(N,{name:"file-text",size:13,color:"var(--text-subtle)"}),e.jsx("span",{className:"hn-prj-mono",children:a.key}),e.jsx("span",{className:"hn-docs-result-kind",children:a.kind})]},a.key))}):e.jsxs(e.Fragment,{children:[e.jsx(ce,{label:"Berkas dokumen",nodes:xe,selected:s,onSelect:H}),Y.length>0&&e.jsxs("div",{className:"hn-docs-unscored",children:[e.jsx("div",{className:"hn-eyebrow hn-docs-unscored-label",children:"Lainnya (tidak dinilai)"}),e.jsx(ce,{label:"Dokumen tidak dinilai",nodes:Y,selected:s,onSelect:H})]})]});return e.jsxs(e.Fragment,{children:[e.jsx(Se,{ariaLabel:"Panel Dokumen",active:y,onActiveChange:a=>d(a),masterWidth:288,className:"hn-workspace-panels",panels:[{id:"tree",label:"Indeks",className:"hn-panel-flex",content:e.jsxs("aside",{"aria-label":"Indeks dokumen",className:"hn-docs-index",children:[e.jsxs("div",{className:"hn-docs-index-head",children:[e.jsxs("span",{className:"hn-eyebrow",children:["dokumen · ",t]}),e.jsxs("div",{className:"hn-docs-index-actions",children:[e.jsx(Ce,{status:ye,size:"sm"}),e.jsx(O,{size:"sm",variant:"ghost",leftIcon:g?"loader":"radar",onClick:ne,disabled:g,children:g?"Memuat…":"Muat ulang"})]})]}),F==="ready"&&l.length>0&&e.jsxs("div",{className:"hn-docs-index-tools",children:[e.jsx(Ke,{size:"sm","aria-label":"Cari berkas dokumen",leftIcon:"search",value:$,placeholder:"mis. product/prd",onChange:a=>Q(a.target.value),className:"hn-prj-full"}),e.jsxs("div",{role:"group","aria-label":"Kategori dokumen",className:"hn-prj-chips",children:[e.jsx("button",{type:"button",className:"hn-prj-chip hn-touch-target","aria-pressed":D==="all",onClick:()=>z("all"),children:"Semua"}),Fe.map(a=>e.jsxs("button",{type:"button",className:"hn-prj-chip hn-touch-target","aria-pressed":D===a,onClick:()=>z(a),children:[a,e.jsx("span",{className:"hn-prj-chip-count",children:ve[a]})]},a))]}),e.jsxs("span",{className:"hn-docs-cov",title:"Persentase kategori yang terindeks",children:["Cakupan ",Math.round(k),"%"]})]}),e.jsx("div",{className:"hn-docs-tree-scroll",children:we})]})},{id:"viewer",label:"Dokumen",className:"hn-panel-flex",content:e.jsxs("section",{"aria-label":"Isi dokumen",className:"hn-docs-viewer",style:{display:"flex",flexDirection:"column",minHeight:0},children:[e.jsxs("div",{className:"hn-docs-viewer-head",children:[e.jsx(N,{name:"file-text",size:15,color:"var(--text-muted)"}),e.jsx("span",{className:"hn-prj-mono hn-docs-path",children:_}),T&&T.scored&&(T.linked?e.jsx(q,{tone:"ok",size:"sm",icon:"link",children:"terindeks"}):e.jsx(q,{tone:"err",size:"sm",icon:"unlink",children:"tak tertaut"})),e.jsx("span",{className:"hn-grow"}),e.jsxs("div",{role:"group","aria-label":"Mode dokumen",className:"hn-prj-seg",children:[e.jsx("button",{type:"button","aria-pressed":h==="preview",className:"hn-touch-target",onClick:()=>{h==="edit"&&ee()},children:"Baca"}),e.jsx("button",{type:"button","aria-pressed":h==="edit",className:"hn-touch-target",onClick:()=>{h!=="edit"&&ge()},disabled:!s||P||A,children:"Edit"})]}),h==="preview"&&e.jsx(Le,{label:"Aksi untuk dokumen",icon:"ellipsis",items:[{key:"delete",label:"Hapus dokumen…",icon:"trash-2",tone:"danger",disabled:!s,onSelect:()=>{je()}}],children:e.jsx(Me,{href:a=>S.docDownloadUrl(n,s,a),disabled:!s||P||A})})]}),h==="edit"&&e.jsxs("div",{role:"region","aria-label":"Simpan perubahan",className:"hn-docs-savebar",children:[E?e.jsx(q,{tone:"warn",size:"sm",children:"belum disimpan"}):e.jsx("span",{className:"hn-prj-hint",children:"Tak ada perubahan"}),e.jsx("span",{className:"hn-grow"}),e.jsx(O,{size:"sm",variant:"ghost",onClick:ee,disabled:L,children:"Batal"}),e.jsx(O,{size:"sm",leftIcon:"check",onClick:()=>void ae(),loading:L,disabled:L||!E,children:"Simpan"})]}),G&&e.jsx("div",{role:"alert",className:"hn-docs-error",children:G}),h==="preview"?e.jsx("div",{"data-testid":"doc-preview-scroll",className:"hn-docs-body",style:{flex:"1 1 auto",minHeight:0,overflow:"auto"},children:s?P?e.jsx(w,{kind:"loading",title:"Memuat dokumen…",hint:s}):A?e.jsx(w,{kind:"error",title:"Gagal memuat dokumen",hint:s,action:fe}):e.jsx("div",{className:"hn-docs-read",children:e.jsx(te,{text:B,name:s})}):e.jsx(w,{kind:"empty",icon:"file-text",title:"Tidak ada dokumen dipilih",hint:"Pilih file dari indeks di kiri."})}):e.jsxs("div",{className:"hn-docs-edit",children:[e.jsxs("div",{className:"hn-docs-edit-pane",children:[e.jsx("div",{className:"hn-docs-edit-label",children:e.jsx("span",{className:"hn-eyebrow",children:"Markdown"})}),e.jsx("textarea",{"aria-label":`Isi ${_}`,value:f,spellCheck:!1,onChange:a=>j(a.target.value),onKeyDown:a=>{(a.metaKey||a.ctrlKey)&&a.key.toLowerCase()==="s"&&(a.preventDefault(),ae())},placeholder:`# Judul dokumen
2
2
 
3
3
  Paragraf pembuka…`,className:"hn-docs-textarea"})]}),e.jsxs("div",{className:"hn-docs-edit-pane",children:[e.jsx("div",{className:"hn-docs-edit-label",children:e.jsx("span",{className:"hn-eyebrow",children:"Pratinjau langsung"})}),e.jsx("div",{className:"hn-docs-preview",children:e.jsx(te,{text:f,name:s})})]})]})]})}]}),me]})}export{Ie as DocsWorkspace,re as buildTree,oe as docKind,le as firstDoc};