@azure-id/orc 0.56.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/CHANGELOG.md +219 -0
  2. package/README-id.md +49 -107
  3. package/README.md +694 -719
  4. package/bin/build-agents.js +18 -11
  5. package/bin/cli.js +33699 -29855
  6. package/bin/onboarding-content.js +0 -3
  7. package/bin/test-run.js +491 -0
  8. package/bin/verify-contracts.js +4330 -3277
  9. package/bin/verify-package.js +76 -6
  10. package/bin/webui/api.js +1201 -1163
  11. package/bin/webui/app.html +210 -198
  12. package/bin/webui/css/06-responsive.css +120 -108
  13. package/bin/webui/css/panels/extra.css +29 -0
  14. package/bin/webui/css/panels/lanes.css +134 -0
  15. package/bin/webui/css/panels/settings.css +79 -3
  16. package/bin/webui/css/panels/wait.css +123 -0
  17. package/bin/webui/fixtures/extra.js +2036 -1934
  18. package/bin/webui/fixtures/flow.js +2 -2
  19. package/bin/webui/fixtures/index.js +510 -486
  20. package/bin/webui/fixtures/lanes.js +218 -0
  21. package/bin/webui/fixtures/settings.js +261 -34
  22. package/bin/webui/fixtures/stats.js +3 -3
  23. package/bin/webui/fixtures/wait.js +97 -0
  24. package/bin/webui/i18n/TERMS.md +135 -134
  25. package/bin/webui/i18n/en/extra.json +345 -313
  26. package/bin/webui/i18n/en/lanes.json +29 -0
  27. package/bin/webui/i18n/en/nav.json +21 -19
  28. package/bin/webui/i18n/en/overview.json +2 -0
  29. package/bin/webui/i18n/en/settings.json +16 -5
  30. package/bin/webui/i18n/en/wait.json +41 -0
  31. package/bin/webui/i18n/id/extra.json +345 -313
  32. package/bin/webui/i18n/id/lanes.json +29 -0
  33. package/bin/webui/i18n/id/nav.json +21 -19
  34. package/bin/webui/i18n/id/overview.json +2 -0
  35. package/bin/webui/i18n/id/settings.json +15 -4
  36. package/bin/webui/i18n/id/wait.json +41 -0
  37. package/bin/webui/js/01-i18n.js +151 -149
  38. package/bin/webui/js/panels/extra.js +3199 -3011
  39. package/bin/webui/js/panels/lanes.js +259 -0
  40. package/bin/webui/js/panels/overview.js +10 -0
  41. package/bin/webui/js/panels/settings.js +149 -3
  42. package/bin/webui/js/panels/wait.js +253 -0
  43. package/package.json +39 -39
  44. package/templates/agents/MODEL-MAPPING.md +23 -35
  45. package/templates/agents/orc-executor-opus-4-7-high.md +1 -1
  46. package/templates/agents/orc-executor-opus-4-7-med.md +1 -1
  47. package/templates/agents/orc-executor-opus-4-8-high.md +1 -1
  48. package/templates/agents/orc-executor-opus-5-high.md +1 -1
  49. package/templates/agents/orc-executor-opus-5-low.md +1 -1
  50. package/templates/agents/orc-executor-opus-5-med.md +1 -1
  51. package/templates/agents/orc-retro-opus-5-med.md +73 -73
  52. package/templates/agents/orc-retro-sonnet-5-high.md +72 -72
  53. package/templates/agents/orc-trace-writer-haiku-4-5.md +107 -107
  54. package/templates/commands/orc-route.md +1 -1
  55. package/templates/commands/orc-wait.md +19 -0
  56. package/templates/commands/orc.md +1 -1
  57. package/templates/hooks/orc-statusline.js +39 -0
  58. package/templates/skills/_shared/README.md +7 -3
  59. package/templates/skills/_shared/config-precedence.md +198 -0
  60. package/templates/skills/_shared/drift-recovery.md +1 -1
  61. package/templates/skills/_shared/extra-dispatch.md +159 -7
  62. package/templates/skills/_shared/interview.md +1 -1
  63. package/templates/skills/_shared/opus5-only.md +9 -7
  64. package/templates/skills/_shared/phases/README.md +82 -0
  65. package/templates/skills/{orc/references → _shared/phases}/analyst-gates.md +15 -3
  66. package/templates/skills/_shared/phases/execution.md +143 -0
  67. package/templates/skills/{orc/references → _shared/phases}/house-rules.md +13 -1
  68. package/templates/skills/{orc/references → _shared/phases}/intake.md +15 -2
  69. package/templates/skills/_shared/phases/mock-example.md +56 -0
  70. package/templates/skills/{orc/references → _shared/phases}/plan-handoff.md +16 -3
  71. package/templates/skills/_shared/phases/planning.md +135 -0
  72. package/templates/skills/_shared/phases/preflight.md +98 -0
  73. package/templates/skills/_shared/phases/review.md +53 -0
  74. package/templates/skills/_shared/phases/scoring.md +65 -0
  75. package/templates/skills/{orc/references → _shared/phases}/security-checklist.md +12 -1
  76. package/templates/skills/_shared/phases/security.md +55 -0
  77. package/templates/skills/_shared/phases/ship.md +88 -0
  78. package/templates/skills/{orc/references/stop-and-resume.md → _shared/phases/stop-resume.md} +169 -160
  79. package/templates/skills/_shared/phases/summary.md +48 -0
  80. package/templates/skills/_shared/phases/testgen.md +51 -0
  81. package/templates/skills/{orc/references/trace-protocol.md → _shared/phases/trace.md} +49 -6
  82. package/templates/skills/_shared/phases/verify.md +70 -0
  83. package/templates/skills/{orc/references → _shared/phases}/wave-grouping.md +14 -2
  84. package/templates/skills/{orc/references → _shared/phases}/wiki-consult.md +13 -1
  85. package/templates/skills/_shared/read-ladder.md +48 -0
  86. package/templates/skills/_shared/wait.md +240 -0
  87. package/templates/skills/context-combiner/SKILL.md +214 -187
  88. package/templates/skills/orc/README.md +148 -150
  89. package/templates/skills/orc/SKILL.md +75 -358
  90. package/templates/skills/orc/config.md +137 -389
  91. package/templates/skills/orc/examples/full-run-mock.md +1 -1
  92. package/templates/skills/orc/references/effort-and-mode.md +16 -18
  93. package/templates/skills/orc/references/phases/intake.md +47 -0
  94. package/templates/skills/orc/references/phases/integration.md +19 -0
  95. package/templates/skills/orc/references/preflight-report.md +4 -4
  96. package/templates/skills/orc/references/ultra-mode.md +117 -123
  97. package/templates/skills/orc/schemas/planning-output.md +279 -279
  98. package/templates/skills/orc/subskills/orc-planner/SKILL.md +260 -264
  99. package/templates/skills/orc/subskills/orc-pr/stack-gate.md +4 -1
  100. package/templates/skills/orc-aftermath/SKILL.md +158 -136
  101. package/templates/skills/orc-analyze/SKILL.md +252 -220
  102. package/templates/skills/orc-analyze/references/branching.md +51 -51
  103. package/templates/skills/orc-analyze/references/thin-input.md +1 -1
  104. package/templates/skills/orc-analyze-mini/SKILL.md +128 -112
  105. package/templates/skills/orc-boundary/SKILL.md +249 -208
  106. package/templates/skills/orc-brainstorm/SKILL.md +377 -339
  107. package/templates/skills/orc-budget/SKILL.md +248 -225
  108. package/templates/skills/orc-challenge/README.md +1 -1
  109. package/templates/skills/orc-challenge/SKILL.md +298 -255
  110. package/templates/skills/orc-challenge/examples/council-full-roster.md +1 -1
  111. package/templates/skills/orc-claude/SKILL.md +221 -199
  112. package/templates/skills/orc-diy/README.md +2 -1
  113. package/templates/skills/orc-diy/SKILL.md +132 -68
  114. package/templates/skills/orc-diy/references/blocks/analyze.md +1 -1
  115. package/templates/skills/orc-diy/references/compile.md +21 -7
  116. package/templates/skills/orc-diy/references/flow-schema.md +2 -2
  117. package/templates/skills/orc-doc/SKILL.md +49 -7
  118. package/templates/skills/orc-explain/SKILL.md +24 -0
  119. package/templates/skills/orc-export/SKILL.md +31 -5
  120. package/templates/skills/orc-fast/SKILL.md +218 -185
  121. package/templates/skills/orc-grill/SKILL.md +238 -207
  122. package/templates/skills/orc-handoff/SKILL.md +223 -204
  123. package/templates/skills/orc-learn/SKILL.md +181 -156
  124. package/templates/skills/orc-mini/SKILL.md +47 -24
  125. package/templates/skills/orc-pact/SKILL.md +255 -218
  126. package/templates/skills/orc-pattern/SKILL.md +154 -124
  127. package/templates/skills/orc-poly/SKILL.md +242 -216
  128. package/templates/skills/orc-poly/references/gather.md +1 -1
  129. package/templates/skills/orc-pr-driver/SKILL.md +196 -167
  130. package/templates/skills/orc-pr-driver/references/orc-run-split.md +1 -1
  131. package/templates/skills/orc-pr-setup/SKILL.md +212 -184
  132. package/templates/skills/orc-quick/README.md +2 -2
  133. package/templates/skills/orc-quick/SKILL.md +51 -13
  134. package/templates/skills/orc-quick/references/dispatch-gate.md +2 -3
  135. package/templates/skills/orc-retro/SKILL.md +249 -222
  136. package/templates/skills/orc-retro/examples/retro-mock.md +171 -171
  137. package/templates/skills/orc-route/SKILL.md +188 -165
  138. package/templates/skills/orc-verify/SKILL.md +103 -84
  139. package/templates/skills/orc-wait/SKILL.md +163 -0
  140. package/templates/skills/orc-wiki/SKILL.md +60 -206
  141. package/templates/skills/orc-wiki/references/phases/phase-0.md +71 -0
  142. package/templates/skills/orc-wiki/references/phases/phase-1.md +35 -0
  143. package/templates/skills/orc-wiki/references/phases/phase-2.md +52 -0
  144. package/templates/skills/orc-wiki/references/phases/phase-3.md +57 -0
  145. package/templates/skills/orc-wiki/references/phases/phase-3c.md +36 -0
  146. package/templates/agents/orc-advisor-fable-5.md +0 -50
  147. package/templates/agents/orc-analyst-fable-5.md +0 -115
  148. package/templates/agents/orc-judge-fable-5.md +0 -79
  149. package/templates/agents/orc-planner-fable-5.md +0 -152
  150. package/templates/agents/orc-reviewer-fable-5.md +0 -57
  151. package/templates/skills/_shared/fable5-override.md +0 -56
  152. package/templates/skills/orc-diy/references/blocks/execution.md +0 -42
  153. package/templates/skills/orc-diy/references/blocks/mock-example.md +0 -22
  154. package/templates/skills/orc-diy/references/blocks/planning.md +0 -34
  155. package/templates/skills/orc-diy/references/blocks/review.md +0 -18
  156. package/templates/skills/orc-diy/references/blocks/scoring.md +0 -16
  157. package/templates/skills/orc-diy/references/blocks/security.md +0 -25
  158. package/templates/skills/orc-diy/references/blocks/ship.md +0 -25
  159. package/templates/skills/orc-diy/references/blocks/summary.md +0 -18
  160. package/templates/skills/orc-diy/references/blocks/testgen.md +0 -17
  161. package/templates/skills/orc-diy/references/blocks/trace.md +0 -28
  162. package/templates/skills/orc-diy/references/blocks/verify.md +0 -25
@@ -0,0 +1,29 @@
1
+ {
2
+ "lanes.calls.calledBy": "Dipanggil oleh:",
3
+ "lanes.calls.canonical": "Teks kanonis",
4
+ "lanes.calls.exits": "Kode keluar:",
5
+ "lanes.calls.lanes": "{n} lane",
6
+ "lanes.calls.lanesPlural": "{n} lane",
7
+ "lanes.calls.never": "Jangan pernah",
8
+ "lanes.calls.none": "Tidak ada panggilan dalam katalog.",
9
+ "lanes.calls.note": "Setiap panggilan CLI yang boleh dibuat sebuah lane. Buka satu baris untuk melihat kode keluar, biayanya, dan apa yang harus dilakukan lane bila jawabannya kosong.",
10
+ "lanes.calls.onAbsent": "Bila jawabannya kosong",
11
+ "lanes.calls.states": "Status:",
12
+ "lanes.calls.title": "Katalog panggilan ({n})",
13
+ "lanes.calls.what": "Apa yang dijawabnya",
14
+ "lanes.calls.when": "Kapan memanggilnya",
15
+ "lanes.none": "Tidak ada lane — CLI melaporkan registri kosong.",
16
+ "lanes.phases.calls": "Panggilan:",
17
+ "lanes.phases.foot": "Hanya baca. Urutan, berkas, dan lapisannya semua berasal dari CLI — halaman ini tidak menambah salinannya.",
18
+ "lanes.phases.inSpine": "Lane ini menyimpan alurnya di berkas spine-nya sendiri, jadi tidak menjalankan fase bersama. Itu fakta tentang lane ini, bukan pembacaan yang gagal.",
19
+ "lanes.phases.title": "Fase, dalam urutan jalannya",
20
+ "lanes.phases.trace": "Jejak:",
21
+ "lanes.phases.unknown": "CLI tidak mengenal lane itu.",
22
+ "lanes.picker.aria": "Lane yang fasenya ditampilkan",
23
+ "lanes.picker.note": "Setiap lane yang dikirim ORC, dengan perintah yang membukanya. Lane tanpa perintah adalah lane yang dikirim oleh hal lain.",
24
+ "lanes.picker.title": "Pilih satu lane",
25
+ "lanes.sub": "Apa yang dijalankan tiap lane: fase bersama yang dibacanya, berurutan, dan panggilan CLI yang dibuatnya.",
26
+ "lanes.tab.calls": "Panggilan",
27
+ "lanes.tab.phases": "Fase",
28
+ "lanes.title": "Lane"
29
+ }
@@ -1,19 +1,21 @@
1
- {
2
- "nav.overview": "Ringkasan",
3
- "nav.settings": "Pengaturan",
4
- "nav.runs": "Run",
5
- "nav.knowledge": "Pengetahuan",
6
- "nav.stats": "Statistik",
7
- "nav.flow": "Flow",
8
- "nav.crosslink": "Crosslink",
9
- "nav.learn": "Belajar",
10
- "nav.mockrun": "Contoh Penggunaan Skill",
11
- "nav.experiment": "Eksperimen",
12
- "nav.maintenance": "Pemeliharaan",
13
- "nav.pact": "Janji",
14
- "nav.boundary": "Batas",
15
- "nav.handoff": "Ubah Sendiri",
16
- "nav.challenge": "Challenge",
17
- "nav.extra": "Extra",
18
- "nav.docs": "Dokumen"
19
- }
1
+ {
2
+ "nav.overview": "Ringkasan",
3
+ "nav.settings": "Pengaturan",
4
+ "nav.lanes": "Lane",
5
+ "nav.runs": "Run",
6
+ "nav.knowledge": "Pengetahuan",
7
+ "nav.stats": "Statistik",
8
+ "nav.flow": "Flow",
9
+ "nav.crosslink": "Crosslink",
10
+ "nav.learn": "Belajar",
11
+ "nav.mockrun": "Contoh Penggunaan Skill",
12
+ "nav.experiment": "Eksperimen",
13
+ "nav.maintenance": "Pemeliharaan",
14
+ "nav.pact": "Janji",
15
+ "nav.boundary": "Batas",
16
+ "nav.handoff": "Ubah Sendiri",
17
+ "nav.challenge": "Challenge",
18
+ "nav.extra": "Extra",
19
+ "nav.wait": "Tunggu",
20
+ "nav.docs": "Dokumen"
21
+ }
@@ -81,6 +81,8 @@
81
81
  "overview.item.wikiDebt.cta": "Buka Pengetahuan",
82
82
  "overview.item.extraFindings.cta": "Buka Extra",
83
83
  "overview.item.legacyGlobalPackage.cta": "Buka Pemeliharaan",
84
+ "overview.item.extraDemotedRun.cta": "Buka Extra",
85
+ "overview.item.laneKeysDrifted.cta": "Buka Pemeliharaan",
84
86
  "overview.extraOrphan.title": "Sebuah pengiriman tidak melapor kembali",
85
87
  "overview.extraOrphan.note": "ORC mengirim pekerjaan ke pekerja non-Claude dan tidak pernah menerima hasilnya. Perubahannya mungkin masih ada di disk.",
86
88
  "overview.extraOrphan.chip": "{n} pengiriman",
@@ -23,10 +23,8 @@
23
23
  "settings.file.absent": "belum dibuat (semua kunci masih default)",
24
24
  "settings.file.traceNote": "Pencatatan behavior-trace SELALU aktif dan tidak bisa dikonfigurasi. Setiap run menulis satu trace; hanya foldernya (log_dir) yang merupakan pengaturan.",
25
25
  "settings.tier.common": "Umum",
26
- "settings.tier.fable5": "Override peran Fable 5",
27
26
  "settings.tier.advanced": "Lanjutan",
28
27
  "settings.tierDesc.common": "Kunci yang paling sering disentuh. Kalau Anda hanya mengubah satu hal, kemungkinan besar ada di sini.",
29
- "settings.tierDesc.fable5": "Override Fable 5 per peran. Seluruh blok ini mati selama opus5_only aktif — itu aturan presedensi, bukan bug.",
30
28
  "settings.tierDesc.advanced": "Sisa dari semua yang dikenal ORC. Default-nya disengaja; ubah kalau Anda punya alasan.",
31
29
  "settings.inert": "mati",
32
30
  "settings.shadowed": "tertutup",
@@ -34,7 +32,7 @@
34
32
  "settings.handEdited.note": "Kunci ini tidak ada di registry config, jadi `orc config set` menolaknya dan panel ini tidak akan menulisnya. rubric_bands_override memang dirancang begitu: ditulis tangan dengan sengaja. Edit langsung berkas YAML-nya.",
35
33
  "settings.handEdited.readonly": "hanya baca di sini — edit manual orc.config.yaml",
36
34
  "settings.ladder.title": "Tangga skor → model",
37
- "settings.ladder.opus5": "opus5_only AKTIF — executor memakai tangga effort 3 pita yang tetap. Ini mengalahkan tabel default, rubric_bands_override, dan seluruh blok fable5_*.",
35
+ "settings.ladder.opus5": "opus5_only AKTIF — executor memakai tangga effort 3 pita yang tetap. Ini mengalahkan tabel default dan rubric_bands_override.",
38
36
  "settings.ladder.override": "Ada rubric_bands_override tulisan tangan di berkas. Itu menggantikan tabel default (dan sendirinya dikalahkan oleh opus5_only).",
39
37
  "settings.ladder.default": "Tabel default 8 pita. Tabel diselesaikan dengan yang tertinggi menang: opus5_only > rubric_bands_override > yang ini.",
40
38
  "settings.ladder.note": "Hanya baca — ini diagram, bukan editor. Datanya dari tabel milik CLI, jadi panel tidak menyimpan salinan kedua.",
@@ -45,5 +43,18 @@
45
43
  "profiles.noChange": "repo ini sudah memakai profil itu — tidak ada yang berubah",
46
44
  "recommend.title": "Profil yang disarankan",
47
45
  "recommend.note": "Hanya baca: ini melihat repo Anda dan menyarankan satu profil. Tidak ada yang diubah.",
48
- "recommend.applyIt": "Terapkan {name}"
46
+ "recommend.applyIt": "Terapkan {name}",
47
+ "settings.retired.title": "Setelan yang sudah ditarik",
48
+ "settings.retired.note": "Kunci ini sudah dihapus dari ORC. Barisnya masih ada di berkas konfigurasi Anda. ORC tidak membacanya dan tidak mengubahnya. Anda boleh menghapus barisnya kapan saja.",
49
+ "settings.retired.badge": "tidak dibaca",
50
+ "settings.retired.readonly": "Sudah dihapus. ORC tidak lagi membaca kunci ini.",
51
+ "settings.retired.removedIn": "Dihapus di v",
52
+ "settings.ranks.title": "Apa yang menentukan",
53
+ "settings.ranks.note": "Beberapa pengaturan menjawab pertanyaan yang sama. Baca satu keluarga dari atas ke bawah dan berhenti di peringkat pertama yang menjawab. Ini yang dilakukan berkas konfigurasi Anda, bukan yang bisa dilakukannya.",
54
+ "settings.ranks.none": "Tidak ada keluarga yang bersaing — setiap pengaturan di sini menjawab pertanyaannya sendiri.",
55
+ "settings.ranks.answeredBy": "Dijawab di {prio} oleh {key}.",
56
+ "settings.ranks.answeredByDefault": "Dijawab di {prio} oleh bawaan bawaan paket — tidak ada peringkat di atasnya yang menjawab.",
57
+ "settings.ranks.legend": "Status:",
58
+ "settings.lanes.label": "Dibaca oleh:",
59
+ "settings.lanes.none": "tidak ada lane — jembatan orc extra yang membacanya"
49
60
  }
@@ -0,0 +1,41 @@
1
+ {
2
+ "wait.title": "Tunggu",
3
+ "wait.sub": "Seberapa penuh jendela pemakaian Anda, dan penantian yang menjawabnya. Menunggu tidak memakai token - sebuah perintah terpisah yang menunggu, dan tidak ada model yang berjalan.",
4
+ "wait.window": "Jendela Anda",
5
+ "wait.worst": "terburuk: {w}",
6
+ "wait.age": "dibaca 1 menit lalu",
7
+ "wait.agePlural": "dibaca {n} menit lalu",
8
+ "wait.left": "sisa {n}%",
9
+ "wait.resets": "reset dalam {t}",
10
+ "wait.context": "Percakapan ini memakai {n}% konteksnya.",
11
+ "wait.contextUnknown": "Pemakaian konteks: tidak terukur.",
12
+ "wait.contextLarge": "Konteksnya besar. Setelah menunggu lebih dari satu jam, mulai sesi baru dan jalankan `orc resume` - biayanya lebih kecil daripada melanjutkan di sini.",
13
+ "wait.gateOff": "usage_gate mati, jadi ORC tidak pernah menghentikan run untuk Anda. Tidak ada yang terjadi sampai Anda menyalakannya.",
14
+ "wait.gateOn": "usage_gate adalah `{gate}`. Sebuah wave perlu sisa {pct}% dari satu jendela sebelum mulai.",
15
+ "wait.run": "Run ini",
16
+ "wait.noRun": "Tidak ada run yang berjalan",
17
+ "wait.noRunHint": "Penantian milik sebuah run. Tanpa run, `/orc-wait` hanya menunggu, dan tidak ada yang perlu diserahkan kembali.",
18
+ "wait.startWhy": "Panel tidak bisa memulai penantian. Penantian hidup di sesi Claude Code Anda, dan panel ini tidak pernah menjalankan lane.",
19
+ "wait.waiting": "menunggu",
20
+ "wait.blocked": "diblokir",
21
+ "wait.idle": "tidak menunggu",
22
+ "wait.hops": "Mode `{mode}` - hop {done} dari {planned}, selesai {ends}.",
23
+ "wait.zeroTokens": "Sebuah perintah terpisah yang menunggu. Tidak ada model yang berjalan, dan tidak ada token yang terpakai.",
24
+ "wait.cancel": "Berhenti menunggu",
25
+ "wait.cancelWhy": "Penantian berakhir pada hop berikutnya. Serah-terima sudah ada di disk, jadi tidak ada yang hilang.",
26
+ "wait.cancelPending": "Permintaan berhenti tertunda. Penantian berakhir pada hop berikutnya.",
27
+ "wait.blockHead": "Anda memblokir gerbangnya",
28
+ "wait.blockAge": "Dipasang 1 menit lalu.",
29
+ "wait.blockAgePlural": "Dipasang {n} menit lalu.",
30
+ "wait.blockRisk": "ORC tidak menghentikan run ini. Risikonya milik Anda: jika sebuah jendela habis saat wave berjalan, wave berhenti di tengah. Penantian yang Anda ketik sendiri tetap berjalan.",
31
+ "wait.unblock": "Pulihkan gerbangnya",
32
+ "wait.unblockWhy": "ORC boleh menghentikan run ini lagi saat sebuah jendela hampir penuh.",
33
+ "wait.blockWhy": "Untuk memblokir gerbangnya, ketik ini di Claude Code. Blokir perlu alasan, dan alasan harus ditulis saat Anda memutuskan - catatan itulah yang membuat risikonya milik Anda.",
34
+ "wait.lanes": "Lane mana yang mendukung penantian",
35
+ "wait.lanesWhy": "Tiap lane menyimpan pekerjaan yang berbeda sebelum berhenti. `full` menulis checkpoint; `none` tidak punya yang perlu ditulis, karena lane itu satu dispatch atau satu bacaan.",
36
+ "wait.settings": "Pengaturan",
37
+ "wait.settingsWhy": "Kunci-kunci ini diubah di halaman Pengaturan, bersama kunci lainnya. Dua editor untuk satu kunci adalah satu editor terlalu banyak.",
38
+ "wait.openSettings": "Buka Pengaturan",
39
+ "wait.done": "Selesai",
40
+ "wait.failed": "Tidak berhasil"
41
+ }
@@ -1,149 +1,151 @@
1
- "use strict";
2
- /* 01-i18n.js — orc ui client
3
- LANGS, loadLang, setLang, t, applyStaticText, cycleLang.
4
-
5
- Keys are written out IN FULL, never assembled from a fragment. The v0.48.1
6
- file split is by key PREFIX only; `docs.ship.confirm` is still spelled
7
- `docs.ship.confirm` at every call site.
8
-
9
- Loaded by app.html in the order its numeric prefix names. Classic
10
- script, no import/export: an ES module import carries no query string,
11
- and every static request here needs the per-launch session token. */
12
-
13
- /* ------------------------------------------------------------------- i18n -- */
14
- /*
15
- THE SCOPE RULE, and it is deliberately narrow: only the panel's OWN prose is
16
- translated. Everything that arrives from `bin/cli.js --json` stays exactly as
17
- the CLI wrote it — config keys and their descriptions, values, agent names,
18
- model ids, file paths, commands, `orc doctor` messages, command output. Those
19
- are identifiers, not sentences: a translated config key is a key that does not
20
- exist, and a translated command is a command you cannot type. So `t()` is
21
- never applied to a value read out of a payload, and neither string table
22
- contains a single ORC key name.
23
-
24
- The tables are plain JSON served as static assets. Adding a language is a
25
- FOLDER in i18n/ plus one row in LANGS — no build step, no library, no
26
- dependency, and no server change (serve.js walks i18n/ at boot).
27
- */
28
- const LANGS = [
29
- { code: "en", label: "English" },
30
- { code: "id", label: "Bahasa Indonesia" },
31
- ];
32
- const LANG_KEY = "orc-ui-lang";
33
-
34
- // v0.48.1 — one file per namespace instead of one 53 KB table, so changing the
35
- // Docs panel's wording means opening i18n/en/docs.json rather than paging
36
- // through every string in the panel.
37
- //
38
- // A plain array, and deliberately NOT an index file to fetch: an index would be
39
- // one more round trip and one more thing to forget to update. A namespace owns
40
- // one or more key PREFIXES (`stats` owns `stats.*` and `cost.*`), which the
41
- // test suite asserts — a key whose prefix belongs to no namespace would load
42
- // nowhere and render as a raw dotted string.
43
- const NAMESPACES = [
44
- "common",
45
- "nav",
46
- "banner",
47
- "overview",
48
- "settings",
49
- "runs",
50
- "knowledge",
51
- "stats",
52
- "flow",
53
- "crosslink",
54
- "learn",
55
- "mockrun",
56
- "maintenance",
57
- "pact",
58
- "boundary",
59
- "handoff",
60
- "challenge",
61
- "docs",
62
- "extra",
63
- "experiment",
64
- "tour",
65
- ];
66
-
67
- let lang = "en";
68
- // English is loaded first and kept as the FALLBACK table: a key the other
69
- // language has not translated yet renders in English rather than as a raw
70
- // dotted key. A half-finished translation degrades to mixed prose, never to
71
- // debug output on somebody's screen.
72
- let DICT = {};
73
- let DICT_EN = {};
74
-
75
- // The namespaces are fetched in parallel and merged into ONE flat table, so
76
- // `t()` is unchanged and no call site knows the split happened.
77
- //
78
- // A namespace that fails to load falls back to ENGLISH for its keys rather than
79
- // rejecting the whole language: a network hiccup on one file should cost that
80
- // file's prose, not the entire panel. English itself has no fallback below it,
81
- // so a failure there rejects and boot() lands on raw keys ugly, never blank.
82
- function loadLang(code) {
83
- return Promise.all(
84
- NAMESPACES.map((ns) =>
85
- fetch(`/i18n/${code}/${ns}.json`, { headers: { "x-orc-token": TOKEN }, cache: "no-store" })
86
- .then((r) => {
87
- if (!r.ok) throw new Error(`i18n ${code}/${ns} ${r.status}`);
88
- return r.json();
89
- })
90
- .catch((e) => {
91
- if (code === "en") throw e;
92
- return null;
93
- })
94
- )
95
- ).then((parts) => Object.assign({}, ...parts.filter(Boolean)));
96
- }
97
-
98
- // A missing or broken table must never blank the UI. Every failure path here
99
- // lands on English, so the worst case is untranslated text — never empty text.
100
- async function setLang(code, opts) {
101
- const rerender = !opts || opts.rerender !== false;
102
- const want = LANGS.some((l) => l.code === code) ? code : "en";
103
- try {
104
- DICT = want === "en" ? DICT_EN : await loadLang(want);
105
- lang = want;
106
- } catch (_) {
107
- DICT = DICT_EN;
108
- lang = "en";
109
- }
110
- try {
111
- localStorage.setItem(LANG_KEY, lang);
112
- } catch (_) {}
113
- document.documentElement.setAttribute("lang", lang);
114
- applyStaticText();
115
- if (rerender) route();
116
- }
117
-
118
- function t(key, vars) {
119
- let s = DICT[key];
120
- if (s === undefined) s = DICT_EN[key];
121
- if (s === undefined) s = key;
122
- if (vars) for (const k of Object.keys(vars)) s = s.split("{" + k + "}").join(String(vars[k]));
123
- return s;
124
- }
125
-
126
- // English has one plural form and Indonesian has none, so count-aware lookup is
127
- // a second key rather than a plural-rules engine: `n === 1` picks the singular.
128
- const tn = (n, key, vars) => t(n === 1 ? key : key + "Plural", Object.assign({ n }, vars || {}));
129
-
130
- // The parts of the shell that are markup rather than a render function. Called
131
- // on every language change; panels re-render themselves through `route()`.
132
- function applyStaticText() {
133
- for (const node of document.querySelectorAll("[data-i18n]")) node.textContent = t(node.dataset.i18n);
134
- const tt = $("#theme-toggle");
135
- if (tt) tt.textContent = document.documentElement.getAttribute("data-theme") === "light" ? t("rail.dark") : t("rail.light");
136
- const hint = $("#shortcut-hint");
137
- if (hint) hint.title = t("rail.shortcuts");
138
- const label = $("#lang-label");
139
- if (label) label.textContent = (LANGS.find((l) => l.code === lang) || LANGS[0]).label;
140
- const btn = $("#lang-toggle");
141
- if (btn) btn.title = t("lang.title");
142
- }
143
-
144
- // Two languages, so the control is a TOGGLE rather than a menu: one click, no
145
- // dropdown to open. A third language would make this a <select>; two do not.
146
- function cycleLang() {
147
- const i = LANGS.findIndex((l) => l.code === lang);
148
- setLang(LANGS[(i + 1) % LANGS.length].code);
149
- }
1
+ "use strict";
2
+ /* 01-i18n.js — orc ui client
3
+ LANGS, loadLang, setLang, t, applyStaticText, cycleLang.
4
+
5
+ Keys are written out IN FULL, never assembled from a fragment. The v0.48.1
6
+ file split is by key PREFIX only; `docs.ship.confirm` is still spelled
7
+ `docs.ship.confirm` at every call site.
8
+
9
+ Loaded by app.html in the order its numeric prefix names. Classic
10
+ script, no import/export: an ES module import carries no query string,
11
+ and every static request here needs the per-launch session token. */
12
+
13
+ /* ------------------------------------------------------------------- i18n -- */
14
+ /*
15
+ THE SCOPE RULE, and it is deliberately narrow: only the panel's OWN prose is
16
+ translated. Everything that arrives from `bin/cli.js --json` stays exactly as
17
+ the CLI wrote it — config keys and their descriptions, values, agent names,
18
+ model ids, file paths, commands, `orc doctor` messages, command output. Those
19
+ are identifiers, not sentences: a translated config key is a key that does not
20
+ exist, and a translated command is a command you cannot type. So `t()` is
21
+ never applied to a value read out of a payload, and neither string table
22
+ contains a single ORC key name.
23
+
24
+ The tables are plain JSON served as static assets. Adding a language is a
25
+ FOLDER in i18n/ plus one row in LANGS — no build step, no library, no
26
+ dependency, and no server change (serve.js walks i18n/ at boot).
27
+ */
28
+ const LANGS = [
29
+ { code: "en", label: "English" },
30
+ { code: "id", label: "Bahasa Indonesia" },
31
+ ];
32
+ const LANG_KEY = "orc-ui-lang";
33
+
34
+ // v0.48.1 — one file per namespace instead of one 53 KB table, so changing the
35
+ // Docs panel's wording means opening i18n/en/docs.json rather than paging
36
+ // through every string in the panel.
37
+ //
38
+ // A plain array, and deliberately NOT an index file to fetch: an index would be
39
+ // one more round trip and one more thing to forget to update. A namespace owns
40
+ // one or more key PREFIXES (`stats` owns `stats.*` and `cost.*`), which the
41
+ // test suite asserts — a key whose prefix belongs to no namespace would load
42
+ // nowhere and render as a raw dotted string.
43
+ const NAMESPACES = [
44
+ "common",
45
+ "nav",
46
+ "banner",
47
+ "overview",
48
+ "settings",
49
+ "lanes",
50
+ "runs",
51
+ "knowledge",
52
+ "stats",
53
+ "flow",
54
+ "crosslink",
55
+ "learn",
56
+ "mockrun",
57
+ "maintenance",
58
+ "pact",
59
+ "boundary",
60
+ "wait",
61
+ "handoff",
62
+ "challenge",
63
+ "docs",
64
+ "extra",
65
+ "experiment",
66
+ "tour",
67
+ ];
68
+
69
+ let lang = "en";
70
+ // English is loaded first and kept as the FALLBACK table: a key the other
71
+ // language has not translated yet renders in English rather than as a raw
72
+ // dotted key. A half-finished translation degrades to mixed prose, never to
73
+ // debug output on somebody's screen.
74
+ let DICT = {};
75
+ let DICT_EN = {};
76
+
77
+ // The namespaces are fetched in parallel and merged into ONE flat table, so
78
+ // `t()` is unchanged and no call site knows the split happened.
79
+ //
80
+ // A namespace that fails to load falls back to ENGLISH for its keys rather than
81
+ // rejecting the whole language: a network hiccup on one file should cost that
82
+ // file's prose, not the entire panel. English itself has no fallback below it,
83
+ // so a failure there rejects and boot() lands on raw keys — ugly, never blank.
84
+ function loadLang(code) {
85
+ return Promise.all(
86
+ NAMESPACES.map((ns) =>
87
+ fetch(`/i18n/${code}/${ns}.json`, { headers: { "x-orc-token": TOKEN }, cache: "no-store" })
88
+ .then((r) => {
89
+ if (!r.ok) throw new Error(`i18n ${code}/${ns} ${r.status}`);
90
+ return r.json();
91
+ })
92
+ .catch((e) => {
93
+ if (code === "en") throw e;
94
+ return null;
95
+ })
96
+ )
97
+ ).then((parts) => Object.assign({}, ...parts.filter(Boolean)));
98
+ }
99
+
100
+ // A missing or broken table must never blank the UI. Every failure path here
101
+ // lands on English, so the worst case is untranslated text — never empty text.
102
+ async function setLang(code, opts) {
103
+ const rerender = !opts || opts.rerender !== false;
104
+ const want = LANGS.some((l) => l.code === code) ? code : "en";
105
+ try {
106
+ DICT = want === "en" ? DICT_EN : await loadLang(want);
107
+ lang = want;
108
+ } catch (_) {
109
+ DICT = DICT_EN;
110
+ lang = "en";
111
+ }
112
+ try {
113
+ localStorage.setItem(LANG_KEY, lang);
114
+ } catch (_) {}
115
+ document.documentElement.setAttribute("lang", lang);
116
+ applyStaticText();
117
+ if (rerender) route();
118
+ }
119
+
120
+ function t(key, vars) {
121
+ let s = DICT[key];
122
+ if (s === undefined) s = DICT_EN[key];
123
+ if (s === undefined) s = key;
124
+ if (vars) for (const k of Object.keys(vars)) s = s.split("{" + k + "}").join(String(vars[k]));
125
+ return s;
126
+ }
127
+
128
+ // English has one plural form and Indonesian has none, so count-aware lookup is
129
+ // a second key rather than a plural-rules engine: `n === 1` picks the singular.
130
+ const tn = (n, key, vars) => t(n === 1 ? key : key + "Plural", Object.assign({ n }, vars || {}));
131
+
132
+ // The parts of the shell that are markup rather than a render function. Called
133
+ // on every language change; panels re-render themselves through `route()`.
134
+ function applyStaticText() {
135
+ for (const node of document.querySelectorAll("[data-i18n]")) node.textContent = t(node.dataset.i18n);
136
+ const tt = $("#theme-toggle");
137
+ if (tt) tt.textContent = document.documentElement.getAttribute("data-theme") === "light" ? t("rail.dark") : t("rail.light");
138
+ const hint = $("#shortcut-hint");
139
+ if (hint) hint.title = t("rail.shortcuts");
140
+ const label = $("#lang-label");
141
+ if (label) label.textContent = (LANGS.find((l) => l.code === lang) || LANGS[0]).label;
142
+ const btn = $("#lang-toggle");
143
+ if (btn) btn.title = t("lang.title");
144
+ }
145
+
146
+ // Two languages, so the control is a TOGGLE rather than a menu: one click, no
147
+ // dropdown to open. A third language would make this a <select>; two do not.
148
+ function cycleLang() {
149
+ const i = LANGS.findIndex((l) => l.code === lang);
150
+ setLang(LANGS[(i + 1) % LANGS.length].code);
151
+ }