@nac3/forge-cli 0.2.1-alpha.60 → 1.0.1

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 (303) hide show
  1. package/README.md +5 -1
  2. package/dist/agents/bridge.d.ts.map +1 -1
  3. package/dist/agents/bridge.js +27 -0
  4. package/dist/agents/bridge.js.map +1 -1
  5. package/dist/agents/config_resolver.d.ts.map +1 -1
  6. package/dist/agents/config_resolver.js +15 -15
  7. package/dist/agents/config_resolver.js.map +1 -1
  8. package/dist/agents/runner.d.ts +8 -0
  9. package/dist/agents/runner.d.ts.map +1 -1
  10. package/dist/agents/runner.js +58 -11
  11. package/dist/agents/runner.js.map +1 -1
  12. package/dist/agents/system_prompt.d.ts.map +1 -1
  13. package/dist/agents/system_prompt.js +2 -1
  14. package/dist/agents/system_prompt.js.map +1 -1
  15. package/dist/bin/yf.d.ts.map +1 -1
  16. package/dist/bin/yf.js +18 -0
  17. package/dist/bin/yf.js.map +1 -1
  18. package/dist/chat/claude.d.ts +13 -0
  19. package/dist/chat/claude.d.ts.map +1 -1
  20. package/dist/chat/claude.js +95 -10
  21. package/dist/chat/claude.js.map +1 -1
  22. package/dist/chat/claude_cli.d.ts +10 -0
  23. package/dist/chat/claude_cli.d.ts.map +1 -1
  24. package/dist/chat/claude_cli.js +97 -16
  25. package/dist/chat/claude_cli.js.map +1 -1
  26. package/dist/chat/completion_hallucination_detector.d.ts +11 -0
  27. package/dist/chat/completion_hallucination_detector.d.ts.map +1 -1
  28. package/dist/chat/completion_hallucination_detector.js +37 -2
  29. package/dist/chat/completion_hallucination_detector.js.map +1 -1
  30. package/dist/chat/doctrine_digest.d.ts.map +1 -1
  31. package/dist/chat/doctrine_digest.js +10 -6
  32. package/dist/chat/doctrine_digest.js.map +1 -1
  33. package/dist/chat/panel.d.ts.map +1 -1
  34. package/dist/chat/panel.js +923 -50
  35. package/dist/chat/panel.js.map +1 -1
  36. package/dist/chat/refusal_detector.d.ts.map +1 -1
  37. package/dist/chat/refusal_detector.js +2 -1
  38. package/dist/chat/refusal_detector.js.map +1 -1
  39. package/dist/chat/server.d.ts +1 -0
  40. package/dist/chat/server.d.ts.map +1 -1
  41. package/dist/chat/server.js +960 -73
  42. package/dist/chat/server.js.map +1 -1
  43. package/dist/chat/session_projects.d.ts +31 -0
  44. package/dist/chat/session_projects.d.ts.map +1 -0
  45. package/dist/chat/session_projects.js +36 -0
  46. package/dist/chat/session_projects.js.map +1 -0
  47. package/dist/chat/session_store.d.ts +32 -0
  48. package/dist/chat/session_store.d.ts.map +1 -0
  49. package/dist/chat/session_store.js +58 -0
  50. package/dist/chat/session_store.js.map +1 -0
  51. package/dist/chat/tooling_section.d.ts +11 -0
  52. package/dist/chat/tooling_section.d.ts.map +1 -0
  53. package/dist/chat/tooling_section.js +70 -0
  54. package/dist/chat/tooling_section.js.map +1 -0
  55. package/dist/chat/tools/app_backend_dispatch.d.ts.map +1 -1
  56. package/dist/chat/tools/app_backend_dispatch.js +44 -1
  57. package/dist/chat/tools/app_backend_dispatch.js.map +1 -1
  58. package/dist/chat/tools/fs_editor.d.ts.map +1 -1
  59. package/dist/chat/tools/fs_editor.js +53 -3
  60. package/dist/chat/tools/fs_editor.js.map +1 -1
  61. package/dist/chat/tools/graph.js +2 -2
  62. package/dist/chat/tools/graph.js.map +1 -1
  63. package/dist/chat/tools/keys.d.ts.map +1 -1
  64. package/dist/chat/tools/keys.js +5 -18
  65. package/dist/chat/tools/keys.js.map +1 -1
  66. package/dist/chat/tools/nac3_invoke.d.ts.map +1 -1
  67. package/dist/chat/tools/nac3_invoke.js +16 -7
  68. package/dist/chat/tools/nac3_invoke.js.map +1 -1
  69. package/dist/chat/tools/shell.d.ts +6 -0
  70. package/dist/chat/tools/shell.d.ts.map +1 -1
  71. package/dist/chat/tools/shell.js +39 -0
  72. package/dist/chat/tools/shell.js.map +1 -1
  73. package/dist/chat/tools/workflow.d.ts +20 -0
  74. package/dist/chat/tools/workflow.d.ts.map +1 -1
  75. package/dist/chat/tools/workflow.js +98 -0
  76. package/dist/chat/tools/workflow.js.map +1 -1
  77. package/dist/chat/tools.d.ts.map +1 -1
  78. package/dist/chat/tools.js +79 -1
  79. package/dist/chat/tools.js.map +1 -1
  80. package/dist/chat/turn_control.d.ts +42 -0
  81. package/dist/chat/turn_control.d.ts.map +1 -0
  82. package/dist/chat/turn_control.js +53 -0
  83. package/dist/chat/turn_control.js.map +1 -0
  84. package/dist/commands/brain.js +1 -1
  85. package/dist/commands/chat.d.ts.map +1 -1
  86. package/dist/commands/chat.js +61 -10
  87. package/dist/commands/chat.js.map +1 -1
  88. package/dist/commands/graph.js +9 -9
  89. package/dist/commands/graph.js.map +1 -1
  90. package/dist/commands/keys_setup.d.ts +10 -28
  91. package/dist/commands/keys_setup.d.ts.map +1 -1
  92. package/dist/commands/keys_setup.js +54 -228
  93. package/dist/commands/keys_setup.js.map +1 -1
  94. package/dist/commands/license.d.ts.map +1 -1
  95. package/dist/commands/license.js +52 -28
  96. package/dist/commands/license.js.map +1 -1
  97. package/dist/commands/mcp.d.ts.map +1 -1
  98. package/dist/commands/mcp.js +62 -6
  99. package/dist/commands/mcp.js.map +1 -1
  100. package/dist/commands/mobile.d.ts +1 -1
  101. package/dist/commands/mobile.d.ts.map +1 -1
  102. package/dist/commands/mobile.js +32 -28
  103. package/dist/commands/mobile.js.map +1 -1
  104. package/dist/commands/onboard.d.ts +19 -0
  105. package/dist/commands/onboard.d.ts.map +1 -0
  106. package/dist/commands/onboard.js +126 -0
  107. package/dist/commands/onboard.js.map +1 -0
  108. package/dist/commands/pending.d.ts.map +1 -1
  109. package/dist/commands/pending.js +25 -1
  110. package/dist/commands/pending.js.map +1 -1
  111. package/dist/commands/projects.js +25 -1
  112. package/dist/commands/projects.js.map +1 -1
  113. package/dist/commands/review-screens.js +28 -1
  114. package/dist/commands/review-screens.js.map +1 -1
  115. package/dist/commands/workflow.d.ts +18 -0
  116. package/dist/commands/workflow.d.ts.map +1 -0
  117. package/dist/commands/workflow.js +253 -0
  118. package/dist/commands/workflow.js.map +1 -0
  119. package/dist/core/brain_config.d.ts +2 -0
  120. package/dist/core/brain_config.d.ts.map +1 -1
  121. package/dist/core/brain_config.js +18 -3
  122. package/dist/core/brain_config.js.map +1 -1
  123. package/dist/core/cf_tunnel.d.ts.map +1 -1
  124. package/dist/core/cf_tunnel.js +8 -2
  125. package/dist/core/cf_tunnel.js.map +1 -1
  126. package/dist/core/cost_router.d.ts.map +1 -1
  127. package/dist/core/cost_router.js +11 -2
  128. package/dist/core/cost_router.js.map +1 -1
  129. package/dist/core/desktop_open.d.ts +16 -0
  130. package/dist/core/desktop_open.d.ts.map +1 -0
  131. package/dist/core/desktop_open.js +114 -0
  132. package/dist/core/desktop_open.js.map +1 -0
  133. package/dist/core/keys_envelope.d.ts.map +1 -1
  134. package/dist/core/keys_envelope.js +5 -1
  135. package/dist/core/keys_envelope.js.map +1 -1
  136. package/dist/core/limits_config.d.ts +5 -0
  137. package/dist/core/limits_config.d.ts.map +1 -1
  138. package/dist/core/limits_config.js +5 -0
  139. package/dist/core/limits_config.js.map +1 -1
  140. package/dist/core/logger.d.ts.map +1 -1
  141. package/dist/core/logger.js +3 -0
  142. package/dist/core/logger.js.map +1 -1
  143. package/dist/core/pairing.d.ts +6 -0
  144. package/dist/core/pairing.d.ts.map +1 -1
  145. package/dist/core/pairing.js +41 -2
  146. package/dist/core/pairing.js.map +1 -1
  147. package/dist/core/provider_keys.d.ts.map +1 -1
  148. package/dist/core/provider_keys.js +25 -12
  149. package/dist/core/provider_keys.js.map +1 -1
  150. package/dist/core/provider_models.js +1 -1
  151. package/dist/deploy/cloudflare.d.ts.map +1 -1
  152. package/dist/deploy/cloudflare.js +13 -2
  153. package/dist/deploy/cloudflare.js.map +1 -1
  154. package/dist/design/yujin_design_resolver.d.ts +16 -0
  155. package/dist/design/yujin_design_resolver.d.ts.map +1 -1
  156. package/dist/design/yujin_design_resolver.js +103 -20
  157. package/dist/design/yujin_design_resolver.js.map +1 -1
  158. package/dist/docs/doctrine/default-design-system.md +32 -0
  159. package/dist/docs/doctrine/office-tools.md +20 -0
  160. package/dist/docs/doctrine/pizarron.md +40 -0
  161. package/dist/docs/doctrine/verb-composition.md +16 -0
  162. package/dist/docs/doctrine/workflow-kinds.md +39 -22
  163. package/dist/docs/doctrine/workflow.md +12 -4
  164. package/dist/license/auto_sync.d.ts +22 -0
  165. package/dist/license/auto_sync.d.ts.map +1 -0
  166. package/dist/license/auto_sync.js +91 -0
  167. package/dist/license/auto_sync.js.map +1 -0
  168. package/dist/license/handle_key.d.ts +32 -0
  169. package/dist/license/handle_key.d.ts.map +1 -0
  170. package/dist/license/handle_key.js +56 -0
  171. package/dist/license/handle_key.js.map +1 -0
  172. package/dist/license/hito4_client.d.ts.map +1 -1
  173. package/dist/license/hito4_client.js +63 -25
  174. package/dist/license/hito4_client.js.map +1 -1
  175. package/dist/llm/gemini_client.d.ts.map +1 -1
  176. package/dist/llm/gemini_client.js +5 -2
  177. package/dist/llm/gemini_client.js.map +1 -1
  178. package/dist/llm/managed_client.d.ts.map +1 -1
  179. package/dist/llm/managed_client.js +14 -9
  180. package/dist/llm/managed_client.js.map +1 -1
  181. package/dist/mcp/plan_bridges.d.ts +17 -0
  182. package/dist/mcp/plan_bridges.d.ts.map +1 -0
  183. package/dist/mcp/plan_bridges.js +119 -0
  184. package/dist/mcp/plan_bridges.js.map +1 -0
  185. package/dist/migrate/ai-apply.d.ts.map +1 -1
  186. package/dist/migrate/ai-apply.js +25 -2
  187. package/dist/migrate/ai-apply.js.map +1 -1
  188. package/dist/nac3/internal_manifest.d.ts.map +1 -1
  189. package/dist/nac3/internal_manifest.js +200 -10
  190. package/dist/nac3/internal_manifest.js.map +1 -1
  191. package/dist/nac3/verb_tier_map.d.ts.map +1 -1
  192. package/dist/nac3/verb_tier_map.js +3 -0
  193. package/dist/nac3/verb_tier_map.js.map +1 -1
  194. package/dist/onboarding/concierge_client.d.ts +34 -0
  195. package/dist/onboarding/concierge_client.d.ts.map +1 -0
  196. package/dist/onboarding/concierge_client.js +80 -0
  197. package/dist/onboarding/concierge_client.js.map +1 -0
  198. package/dist/onboarding/next_step.d.ts +32 -0
  199. package/dist/onboarding/next_step.d.ts.map +1 -0
  200. package/dist/onboarding/next_step.js +60 -0
  201. package/dist/onboarding/next_step.js.map +1 -0
  202. package/dist/pending/store.d.ts +7 -0
  203. package/dist/pending/store.d.ts.map +1 -1
  204. package/dist/pending/store.js +19 -0
  205. package/dist/pending/store.js.map +1 -1
  206. package/dist/pending/types.d.ts +20 -0
  207. package/dist/pending/types.d.ts.map +1 -1
  208. package/dist/pending/types.js.map +1 -1
  209. package/dist/reader/parsers/epub.d.ts.map +1 -1
  210. package/dist/reader/parsers/epub.js +6 -1
  211. package/dist/reader/parsers/epub.js.map +1 -1
  212. package/dist/relay/board_snapshot.d.ts +69 -0
  213. package/dist/relay/board_snapshot.d.ts.map +1 -0
  214. package/dist/relay/board_snapshot.js +149 -0
  215. package/dist/relay/board_snapshot.js.map +1 -0
  216. package/dist/relay/command_consumer.d.ts +97 -0
  217. package/dist/relay/command_consumer.d.ts.map +1 -0
  218. package/dist/relay/command_consumer.js +135 -0
  219. package/dist/relay/command_consumer.js.map +1 -0
  220. package/dist/relay/mock_relay.d.ts +34 -0
  221. package/dist/relay/mock_relay.d.ts.map +1 -0
  222. package/dist/relay/mock_relay.js +93 -0
  223. package/dist/relay/mock_relay.js.map +1 -0
  224. package/dist/relay/relay_client.d.ts +28 -0
  225. package/dist/relay/relay_client.d.ts.map +1 -0
  226. package/dist/relay/relay_client.js +80 -0
  227. package/dist/relay/relay_client.js.map +1 -0
  228. package/dist/relay/relay_publisher.d.ts +59 -0
  229. package/dist/relay/relay_publisher.d.ts.map +1 -0
  230. package/dist/relay/relay_publisher.js +101 -0
  231. package/dist/relay/relay_publisher.js.map +1 -0
  232. package/dist/relay/types.d.ts +54 -0
  233. package/dist/relay/types.d.ts.map +1 -0
  234. package/dist/relay/types.js +8 -0
  235. package/dist/relay/types.js.map +1 -0
  236. package/dist/semantic_graph/ast_extract.d.ts +5 -0
  237. package/dist/semantic_graph/ast_extract.d.ts.map +1 -1
  238. package/dist/semantic_graph/ast_extract.js +46 -0
  239. package/dist/semantic_graph/ast_extract.js.map +1 -1
  240. package/dist/semantic_graph/derive.d.ts +12 -0
  241. package/dist/semantic_graph/derive.d.ts.map +1 -1
  242. package/dist/semantic_graph/derive.js +325 -6
  243. package/dist/semantic_graph/derive.js.map +1 -1
  244. package/dist/semantic_graph/store.d.ts +9 -0
  245. package/dist/semantic_graph/store.d.ts.map +1 -1
  246. package/dist/semantic_graph/store.js +23 -1
  247. package/dist/semantic_graph/store.js.map +1 -1
  248. package/dist/semantic_graph/types.d.ts +1 -1
  249. package/dist/semantic_graph/types.d.ts.map +1 -1
  250. package/dist/support/github_dispatcher.d.ts.map +1 -1
  251. package/dist/support/github_dispatcher.js +30 -2
  252. package/dist/support/github_dispatcher.js.map +1 -1
  253. package/dist/tasks/supervisor.d.ts +88 -0
  254. package/dist/tasks/supervisor.d.ts.map +1 -0
  255. package/dist/tasks/supervisor.js +308 -0
  256. package/dist/tasks/supervisor.js.map +1 -0
  257. package/dist/tasks/task_type.d.ts +11 -0
  258. package/dist/tasks/task_type.d.ts.map +1 -0
  259. package/dist/tasks/task_type.js +21 -0
  260. package/dist/tasks/task_type.js.map +1 -0
  261. package/dist/vault/store.d.ts.map +1 -1
  262. package/dist/vault/store.js +6 -1
  263. package/dist/vault/store.js.map +1 -1
  264. package/dist/version.d.ts +3 -5
  265. package/dist/version.d.ts.map +1 -1
  266. package/dist/version.js +3 -5
  267. package/dist/version.js.map +1 -1
  268. package/dist/voice/providers/google.d.ts.map +1 -1
  269. package/dist/voice/providers/google.js +6 -4
  270. package/dist/voice/providers/google.js.map +1 -1
  271. package/dist/workflow/config.d.ts +43 -0
  272. package/dist/workflow/config.d.ts.map +1 -0
  273. package/dist/workflow/config.js +199 -0
  274. package/dist/workflow/config.js.map +1 -0
  275. package/dist/workflow/instances.d.ts +40 -0
  276. package/dist/workflow/instances.d.ts.map +1 -0
  277. package/dist/workflow/instances.js +122 -0
  278. package/dist/workflow/instances.js.map +1 -0
  279. package/dist/workflow/multi_view.d.ts +27 -0
  280. package/dist/workflow/multi_view.d.ts.map +1 -0
  281. package/dist/workflow/multi_view.js +76 -0
  282. package/dist/workflow/multi_view.js.map +1 -0
  283. package/dist/workflow/orchestrator.d.ts +111 -0
  284. package/dist/workflow/orchestrator.d.ts.map +1 -0
  285. package/dist/workflow/orchestrator.js +241 -0
  286. package/dist/workflow/orchestrator.js.map +1 -0
  287. package/docs/doctrine/default-design-system.md +32 -0
  288. package/docs/doctrine/office-tools.md +20 -0
  289. package/docs/doctrine/pizarron.md +40 -0
  290. package/docs/doctrine/verb-composition.md +16 -0
  291. package/docs/doctrine/workflow-kinds.md +39 -22
  292. package/docs/doctrine/workflow.md +12 -4
  293. package/package.json +2 -1
  294. package/src/i18n/catalogs/ar.json +223 -210
  295. package/src/i18n/catalogs/de.json +223 -210
  296. package/src/i18n/catalogs/en.json +223 -210
  297. package/src/i18n/catalogs/es.json +223 -210
  298. package/src/i18n/catalogs/fr.json +223 -210
  299. package/src/i18n/catalogs/hi.json +223 -210
  300. package/src/i18n/catalogs/it.json +223 -210
  301. package/src/i18n/catalogs/ja.json +223 -210
  302. package/src/i18n/catalogs/pt.json +223 -210
  303. package/src/i18n/catalogs/zh.json +223 -210
@@ -21,32 +21,49 @@ changed. No doc drift.
21
21
 
22
22
  ## How Forge decides + acts
23
23
 
24
- 1. **Classify + ASK.** From the request + whether the project has
25
- code, suggest a kind (the classifier is `src/workflow/select.ts`).
26
- When confidence is low, ASK the user "esto es correctivo o
27
- evolutivo?" before committing. Do NOT silently assume.
28
- 2. **Set the kind.** Persist with `yujin.workflow.set({group:"kind",
29
- patch:{kind:"corrective"}, top_level:true})`.
30
- 3. **Run the right workflow.** Greenfield -> the 18-step flow.
31
- corrective/evolutive -> the compact 6-stage flow above.
32
- 4. **Log the evolution.** As you cross each stage/step boundary,
33
- call `yujin.workflow.log-step({kind, stage_id, step_id?, event,
34
- content})`. It writes the per-project doc `docs/WORKFLOW_LOG.md`
35
- (auditable) + the mirror in `workflow.evolution[]`. The project
36
- then documents its own workflow evolution -- steps + stages with
37
- start/end/content.
24
+ The orchestration is DETERMINISTIC code (`src/workflow/orchestrator.ts`),
25
+ not LLM judgement. You drive it through verbs:
26
+
27
+ 1. **Open a workflow with `yujin.workflow.start({request})`.** It
28
+ classifies the kind (regex over the request + whether the project
29
+ has code -- `src/workflow/select.ts`). When the result is
30
+ `needs_confirm:true`, ASK the user "greenfield, correctivo o
31
+ evolutivo?" and call again with `{kind}`. Do NOT silently assume.
32
+ `start` then creates the instance (WFL-NNN) + **spawns one pending
33
+ per canonical task, in mandatory order**. Several workflows can
34
+ coexist (keyed by name) -- a fix and a feature run side by side.
35
+ 2. **Stages are NOT pendings; tasks are.** Work the task pendings in
36
+ order. The `yf pending close` gate REFUSES to close a task while an
37
+ earlier-order task is still open (override: `--force-order`). When
38
+ every task closes, the workflow **auto-closes** -- you do not close
39
+ it by hand.
40
+ 3. **Add tasks at discretion.** If the user OR you decide a
41
+ corrective/evolutive task is needed mid-workflow, add it with
42
+ `yujin.workflow.add-task({code, title})` -- it appends at the end of
43
+ the order (flagged `ad_hoc`).
44
+ 4. **Edit the phases/tasks on request.** `yujin.workflow.configure({patch})`
45
+ rewrites the project's editable definitions
46
+ (`.forge/workflow-config.json`); the code default stays recoverable
47
+ (`yf workflow config --reset`).
48
+ 5. **Log the evolution.** As you cross stage/step boundaries, call
49
+ `yujin.workflow.log-step(...)` -- it writes `docs/WORKFLOW_LOG.md` +
50
+ `workflow.evolution[]` so the project records its own workflow
51
+ history. Greenfield detail = the 18-step flow (`workflow`,
52
+ `workflow-phases`); never force it on a live project.
38
53
 
39
54
  ## Relation to the request lifecycle
40
55
 
41
56
  The pending request-lifecycle (add -> note -> close with history) is
42
- the MICRO level (per request). The workflow is the MACRO level (per
43
- project, with stages). They compose: the macro workflow names the
44
- stage; each request inside it runs the micro lifecycle. Do not
45
- duplicate -- a corrective run IS a pending item whose work crosses
46
- the corrective stages.
57
+ the MICRO level (per task). The workflow is the MACRO level (per
58
+ project, with stages). They are now the SAME store: a workflow task IS
59
+ a pending item (with a `workflow` link). The instance names the stages;
60
+ its tasks are pendings closed in mandatory order.
47
61
 
48
62
  ## Canonical steps source
49
63
 
50
- The canonical step definitions come from the worker (general,
51
- shared) with a LOCAL fallback (`src/workflow/definitions.ts`) so
52
- Forge keeps working offline -- same pattern as doctrines + lessons.
64
+ The canonical step definitions live in `src/workflow/definitions.ts`
65
+ (the immutable DEFAULT + disaster-recovery source). A project may
66
+ override them in `.forge/workflow-config.json` (edited via
67
+ `yujin.workflow.configure`); a `.default.json` snapshot keeps the
68
+ default recoverable. The worker-canonical layer plugs in later, same
69
+ pattern as doctrines + lessons.
@@ -1,8 +1,16 @@
1
- # Workflow doctrine -- 6 phases / 18 steps
1
+ # Workflow doctrine -- 6 phases / 18 steps (GREENFIELD)
2
2
 
3
- Yujin Forge guides delivery through 6 phases / 18 steps (PRODUCT_WORKFLOW.md).
4
- The LLM picks the right phase based on what the user is asking; if the user
5
- jumps mid-phase the LLM respects that but flags the risk.
3
+ SCOPE: this 6-phase / 18-step methodology is the GREENFIELD workflow --
4
+ building a new app from zero. A LIVE project uses the compact
5
+ corrective / evolutive flow instead (see `workflow-kinds`). Never force
6
+ these 18 steps on an existing project. Open any workflow with
7
+ `yujin.workflow.start` (it classifies the kind + spawns the task
8
+ pendings in order); this doc is the detail for the greenfield case.
9
+
10
+ Yujin Forge guides greenfield delivery through 6 phases / 18 steps
11
+ (PRODUCT_WORKFLOW.md). The LLM picks the right phase based on what the
12
+ user is asking; if the user jumps mid-phase the LLM respects that but
13
+ flags the risk.
6
14
 
7
15
  PHASE I -- INTAKE (steps 1-3.5)
8
16
  1. Complexity triage Simple / Medium / Full tier
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nac3/forge-cli",
3
- "version": "0.2.1-alpha.60",
3
+ "version": "1.0.1",
4
4
  "description": "Yujin Forge -- voice-first NAC-3 React development framework. CLI + chat panel + spec ingest + 10-format document reader + voice loop.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Pablo Kuschnirof <pablo@rpaforce.com>",
@@ -16,6 +16,7 @@
16
16
  ".": "./dist/index.js"
17
17
  },
18
18
  "scripts": {
19
+ "version": "node scripts/sync_version.mjs && git add src/version.ts",
19
20
  "build": "tsc && node scripts/copy_qa_assets.mjs",
20
21
  "dev": "tsx watch src/bin/yf.ts",
21
22
  "typecheck": "tsc --noEmit",
@@ -1,210 +1,223 @@
1
- {
2
- "panel.brand": "Yujin Forge",
3
- "panel.brand.kanji": "侑",
4
- "panel.tagline": "مساعد تطوير صوتي أولاً",
5
- "panel.input.placeholder": "اسأل Yujin",
6
- "panel.button.send": "إرسال",
7
- "panel.button.mic": "تحدث (اضغط مع الاستمرار)",
8
- "panel.button.mic.recording": "اضغط لإيقاف التسجيل",
9
- "panel.button.tts": "الصوت مفعل",
10
- "panel.button.keys": "المفاتيح",
11
- "panel.button.minimise": "تصغير",
12
- "panel.button.maximise": "تكبير",
13
- "panel.button.close": "إغلاق",
14
- "panel.button.language": "اللغة",
15
- "panel.trace.title": "سجل الإجراءات",
16
- "panel.trace.count.one": "{n} استدعاء أداة",
17
- "panel.trace.count.other": "{n} استدعاءات أدوات",
18
- "panel.trace.empty.kanji": "空",
19
- "panel.trace.empty.body": "يعرض Yujin Forge هنا كل أداة يستدعيها للرد عليك: قراءة البيان، البحث في SPEC، تحرير المكونات، قراءة المستندات. اطرح سؤالاً يتطلب الرجوع إليها.",
20
- "panel.trace.badge.tool": "أداة",
21
- "panel.trace.badge.voice": "صوت",
22
- "panel.trace.badge.error": "خطأ",
23
- "panel.stream.empty.kanji": "侑仁",
24
- "panel.stream.empty.body": "Yujin Forge متصل. اطلب تغييرات على المشروع.",
25
- "panel.status.no_audio": "لم يُلتقط أي صوت. ربما لم يستقبل الميكروفون شيئاً.",
26
- "panel.status.did_not_catch": "لم أفهم. لنجرب مرة أخرى.",
27
- "panel.status.mic_denied": "إذن الميكروفون مرفوض أو غير متاح: {error}",
28
- "panel.status.voice_failed": "فشل الصوت: {error}",
29
- "panel.status.voice_reply_failed": "تعذر تشغيل الرد: {error}",
30
- "panel.status.audio_play_error": "تعذر تشغيل الصوت: {error}",
31
- "panel.status.reading": "جارٍ قراءة {filename}...",
32
- "panel.status.ingest_failed": "فشل الاستيعاب: {error}",
33
- "panel.status.read_failed": "تعذرت قراءة المواصفات: {error}",
34
- "panel.drop.title": "أفلت المواصفات هنا",
35
- "panel.drop.hint": "PDF, DOCX, HTML, MD, RTF, EPUB, CSV, XLSX, TXT",
36
- "panel.ingest.spec_attached": "تم إرفاق المواصفات: {filename}، {kb} KB",
37
- "panel.ingest.read_label": "تمت القراءة.",
38
- "panel.ingest.title_label": "العنوان: {title}",
39
- "panel.ingest.no_title": "(بدون عنوان)",
40
- "panel.ingest.format_label": "التنسيق: {format} / {sections} قسم / {kb} KB",
41
- "panel.ingest.first_lines": "الأسطر الأولى:",
42
- "panel.ingest.action_done": "اكتمل الإجراء {tool}.",
43
- "vault.modal.title": "بيانات الاعتماد (الخزنة)",
44
- "vault.modal.aria.close": "إغلاق نافذة بيانات الاعتماد",
45
- "vault.tab.list": "الخانات المحملة",
46
- "vault.tab.add": "إضافة",
47
- "vault.list.loading": "جارٍ التحميل...",
48
- "vault.list.empty": "لم تقم بتحميل أي مفتاح بعد. انقر على \"إضافة\" للبدء.",
49
- "vault.add.slot_label": "اسم الخانة",
50
- "vault.add.slot_hint": "أحرف صغيرة، أرقام، شرطة سفلية، واصلة. يجب أن يبدأ بحرف.",
51
- "vault.add.value_label": "القيمة النصية (مخفية)",
52
- "vault.add.value_hint": "تُعرض مرة واحدة فقط عند الحفظ. بعد ذلك يمكن استبدالها وليس قراءتها.",
53
- "vault.add.button_save": "حفظ",
54
- "vault.add.button_cancel": "إلغاء",
55
- "vault.add.success": "تم حفظ الخانة {slot}.",
56
- "vault.add.overwrite": "تم استبدال الخانة {slot}.",
57
- "manual.intro": "Yujin Forge -- دليل المستخدم",
58
- "manual.section.welcome": "مرحباً",
59
- "manual.section.install": "التثبيت",
60
- "manual.section.first_run": "التشغيل الأول",
61
- "manual.section.voice": "الأوامر الصوتية",
62
- "manual.section.spec_ingest": "استيعاب المواصفات",
63
- "manual.section.troubleshooting": "حل المشكلات",
64
- "manual.section.support": "الدعم",
65
- "lang.name.es": "الإسبانية",
66
- "lang.name.en": "الإنجليزية",
67
- "lang.name.pt": "البرتغالية",
68
- "lang.name.fr": "الفرنسية",
69
- "lang.name.ja": "اليابانية",
70
- "lang.name.zh": "الصينية",
71
- "lang.name.hi": "الهندية",
72
- "lang.name.ar": "العربية",
73
- "lang.name.de": "الألمانية",
74
- "lang.name.it": "الإيطالية",
75
- "recap.fallback_period": ".",
76
- "recap.empty": "لا يوجد ما يمكن تلخيصه بعد.",
77
- "error_ui.severity.info": "معلومات",
78
- "error_ui.severity.warning": "تحذير",
79
- "error_ui.severity.error": "خطأ",
80
- "error_ui.severity.fatal": "فادح",
81
- "error_ui.label.what": "ماذا حدث",
82
- "error_ui.label.why": "لماذا",
83
- "error_ui.label.fix": "كيفية الإصلاح",
84
- "error_ui.label.cmd": "الأمر",
85
- "error_ui.label.docs": "الوثائق المحلية",
86
- "error_ui.label.retry": "إعادة المحاولة في",
87
- "error_ui.copy_btn": "نسخ الأمر",
88
- "error_ui.unknown.what": "واجه Forge خطأ داخليا (رمز غير معروف).",
89
- "error_ui.unknown.why": "الرمز {code} ليس في الكتالوج. هذا خطأ برمجي.",
90
- "error_ui.unknown.fix": "افتح issue في https://github.com/yujinapp/yujin-forge/issues مع الرمز و traceback.",
91
- "error.cap_frontier_exhausted.what": "نفد الحد الشهري لرموز طبقة frontier (نموذج كبير).",
92
- "error.cap_frontier_exhausted.why": "خطتك {plan} تسمح بحد أقصى {cap} رمز/شهر على frontier. استخدمت {used}. يعاد الضبط في بداية الشهر UTC التالي.",
93
- "error.cap_frontier_exhausted.fix": "انتقل إلى BYOK Anthropic مباشرة: يتجاوز الحد الشهري لـ worker. تصبح تكلفتك ما تتقاضاه Anthropic مباشرة.",
94
- "error.cap_frontier_exhausted.cmd": "yf brain config --frontier-provider anthropic --frontier-model claude-opus-4-7",
95
- "error.cap_eco_exhausted.what": "نفد الحد الشهري لرموز طبقة eco (نموذج صغير).",
96
- "error.cap_eco_exhausted.why": "خطتك {plan} تسمح بحد أقصى {cap} رمز/شهر على eco. استخدمت {used}. يعاد الضبط في بداية الشهر UTC التالي.",
97
- "error.cap_eco_exhausted.fix": "انتقل إلى BYOK مباشرة أو قم بترقية الخطة. BYOK يتجاوز حد worker.",
98
- "error.cap_eco_exhausted.cmd": "yf brain config --eco-provider google_ai --eco-model gemini-2.5-flash-lite",
99
- "error.tier_not_in_plan.what": "الطبقة {tier} غير مفعلة على خطتك.",
100
- "error.tier_not_in_plan.why": "خطتك {plan} لا تتضمن طبقة {tier}. ربما أنت على free-public أو انتهت صلاحية ترخيصك.",
101
- "error.tier_not_in_plan.fix": "فعل ترخيصا مدفوعا أو انتقل إلى BYOK مباشرة (تكلفتك، دون حد worker).",
102
- "error.tier_not_in_plan.cmd": "yf license activate --key <jwt>",
103
- "error.response_truncated.what": "تم قطع استجابة النموذج قبل الانتهاء.",
104
- "error.response_truncated.why": "تم الوصول إلى حد managed_max_tokens_per_turn = {limit} رمز في منتصف الدور. توقف النموذج عن التوليد.",
105
- "error.response_truncated.fix": "ارفع الحد عبر yf limits. ينطبق على الدور التالي دون إعادة تشغيل الدردشة.",
106
- "error.response_truncated.cmd": "yf limits set managed_max_tokens_per_turn 16384",
107
- "error.response_truncated.banner": "[الاستجابة مقتطعة بواسطة max_tokens={max}. ارفع الحد بـ: yf limits set managed_max_tokens_per_turn {suggested}]",
108
- "error.modal_trace_stale.what": "انتهت صلاحية مودال الموافقة أو أصبح يتيما.",
109
- "error.modal_trace_stale.why": "trace_id {trace_id} ليس له موافقة معلقة في dispatcher. ربما race condition بين invoke وحالة panel، أو ترك cancel سابق trace في حالة zombie.",
110
- "error.modal_trace_stale.fix": "استدع verb من الدردشة مرة أخرى: يبدأ trace جديد نظيف. إذا استمر، شغل yf doctor لفحص panel.",
111
- "error.modal_trace_stale.cmd": "yf doctor",
112
- "error.byok_key_missing.what": "مفتاح API مفقود للمزود {provider}.",
113
- "error.byok_key_missing.why": "لقد أعددت {provider} كمزود لطبقة {tier} لكن الفتحة byok_{slot} ليست في Vault المشفر.",
114
- "error.byok_key_missing.fix": "كون المفتاح بـ yf keys set (ذري، mode 0600، لا يسجل أبدا).",
115
- "error.byok_key_missing.cmd": "yf keys set {slot}",
116
- "error.worker_unreachable.what": "لم أستطع الوصول إلى worker yujin.app.",
117
- "error.worker_unreachable.why": "انتهاء مهلة الشبكة أو worker معطل (HTTP {status}). أعدت المحاولة {attempts} مرات.",
118
- "error.worker_unreachable.fix": "افحص إنترنتك. إذا كان جيدا، انتقل مؤقتا إلى BYOK مباشرة لتجنب الاعتماد على worker.",
119
- "error.worker_unreachable.cmd": "yf brain config --frontier-provider anthropic",
120
- "error.vault_decrypt_failed.what": "لم أستطع فك تشفير مفتاح من Vault.",
121
- "error.vault_decrypt_failed.why": "مفتاح master غير صحيح أو ملف Vault تالف. يمكن أن يحدث إذا نقلت config بين الأجهزة دون نقل master، أو بسبب disk error.",
122
- "error.vault_decrypt_failed.fix": "اسحب نسخة الخادم (يعيد التشفير بـ master المحلي) إذا كان لديك server backup نشط.",
123
- "error.vault_decrypt_failed.cmd": "yf keys setup --pull",
124
- "error.shell_exec_rejected.what": "رفضت مودال R8 لـ yujin.shell.exec.",
125
- "error.shell_exec_rejected.why": "تم تصنيف الأمر {command} على أنه {classification}. shell.exec يطلب الموافقة دائما للأمان، حتى لو كان الأمر read-only.",
126
- "error.shell_exec_rejected.fix": "إذا كان الأمر read-only (yf projects active، git status، ls)، استخدم verb الأصلي المكافئ. إذا كان ضروريا ورفضته بالخطأ، استدعه مرة أخرى.",
127
- "error.project_not_registered.what": "لا يوجد مشروع adopter مسجل.",
128
- "error.project_not_registered.why": "يتطلب verb المستدعى project root نشط لكن ~/.yujin-forge/projects.json ليس به إدخالات.",
129
- "error.project_not_registered.fix": "أنشئ واحدا بـ yujin.project.init أو سجل واحدا موجودا بـ yf projects add.",
130
- "error.project_not_registered.cmd": "yf projects scan",
131
- "panel.button.agents": "الوكلاء",
132
- "panel.agents.title": "الوكلاء",
133
- "panel.agents.subtitle": "المدير والوكلاء الفرعيون المسجلون في هذا المشروع",
134
- "panel.agents.empty.title": "لا يوجد وكلاء بعد",
135
- "panel.agents.empty.body": "قم بتشغيل `yf agent install --defaults` لتسجيل المدير ووكلائه الفرعيين الأربعة (المحلل، المبرمج، المختبر، المُجهز).",
136
- "panel.agents.legend.eco": "اقتصادي",
137
- "panel.agents.legend.managed": "مُدار",
138
- "panel.agents.legend.frontier": "حدود",
139
- "panel.agents.status.disabled": "وقت تشغيل الوكلاء غير مُشغّل",
140
- "panel.agents.event.running": "قيد التشغيل",
141
- "panel.agents.event.idle": "خامل",
142
- "panel.agents.tick.live": "متصل",
143
- "panel.agents.tick.lost": "الاتصال مفقود",
144
- "workflow.phase.i": "الفرز والنية",
145
- "workflow.phase.ii": "التوضيح (الوظيفي + 4 NFR + الكتل)",
146
- "workflow.phase.iii": "المواصفات (RFP + المعمارية + التصميم + الموافقات)",
147
- "workflow.phase.iv": "التهيئة",
148
- "workflow.phase.v": "تطوير الكتل",
149
- "workflow.phase.vi": "النشر + ما بعد الإطلاق",
150
- "wizard.title": "مرحبا بك في Yujin Forge",
151
- "wizard.close": "إغلاق",
152
- "wizard.intro": "للبدء، اختر كيف يتصل Forge بنموذج الذكاء الاصطناعي. يمكنك تغيير ذلك لاحقا من Settings.",
153
- "wizard.back": "رجوع",
154
- "wizard.start": "ابدأ",
155
- "wizard.plan.badge": "موصى به",
156
- "wizard.plan.title": "خطة Claude",
157
- "wizard.plan.desc": "اشتراك Claude الشهري. الخيار الأكثر اقتصاديا للاستخدام المستمر. Forge يستخدم جلسة claude -p الخاصة بك.",
158
- "wizard.plan.price": "رسم شهري ثابت (الخطة)",
159
- "wizard.plan.step.title": "وصل خطة Claude الخاصة بك",
160
- "wizard.plan.step.1": "افتح موجه أوامر جديد.",
161
- "wizard.plan.step.2": "نفذ الأمر claude (بدون وسائط) وأكمل تسجيل الدخول في المتصفح.",
162
- "wizard.plan.step.3": "عد إلى هنا واضغط أنا مسجل الدخول للتحقق.",
163
- "wizard.plan.done": "أنا مسجل الدخول",
164
- "wizard.byok.title": "مفتاح API الخاص بك (BYOK)",
165
- "wizard.byok.desc": "مفتاح Anthropic Console الخاص بك. دفع حسب الاستخدام. أكثر مرونة لكن التكلفة متغيرة.",
166
- "wizard.byok.price": "دفع حسب الاستخدام (Console)",
167
- "wizard.byok.step.title": "الصق مفتاح Anthropic API الخاص بك",
168
- "wizard.byok.step.intro": "يبدأ مفتاحك بـ sk-ant- ويتم الحصول عليه من console.anthropic.com. يخزنه Forge مشفرا في Vault المحلي؛ لا يغادر جهازك أبدا.",
169
- "wizard.byok.test": "تحقق واحفظ",
170
- "wizard.skip.title": "أنا بالفعل معد",
171
- "wizard.skip.desc": "تخطي المعالج. يمكنك إعادة فتحه من Settings لاحقا.",
172
- "wizard.done.kanji": "تم",
173
- "wizard.done.title": "تم",
174
- "wizard.done.msg": "Forge جاهز. ابدأ الدردشة.",
175
- "pizarron.button.read": "اقرأ بصوت",
176
- "pizarron.button.copy": "نسخ",
177
- "pizarron.button.edit": "تحرير",
178
- "pizarron.graph.refresh": "تحديث",
179
- "pizarron.graph.regenerating": "جارٍ إعادة التوليد...",
180
- "pizarron.graph.detail.hint": "انقر على عقدة لعرض التفاصيل.",
181
- "pizarron.graph.detail.empty": "لا توجد تفاصيل لهذه العقدة.",
182
- "pizarron.graph.detail.weight": "الوزن",
183
- "startup.tab.graph": "رسم بياني مرئي",
184
- "startup.tab.graphSem": "الرسم الدلالي",
185
- "startup.tab.pendings": "معلق",
186
- "startup.tab.workflow": "سير العمل",
187
- "settings.startupTabs": "علامات التبويب عند الفتح",
188
- "graph.term.nodes": "عقد",
189
- "graph.term.edges": "حواف",
190
- "coding.read": "جارٍ قراءة {x}",
191
- "coding.read_bare": "جارٍ قراءة ملف",
192
- "coding.edit": "جارٍ تعديل {x}",
193
- "coding.edit_bare": "جارٍ تعديل ملف",
194
- "coding.write": "جارٍ كتابة {x}",
195
- "coding.write_bare": "جارٍ كتابة ملف",
196
- "coding.notebook_bare": "جارٍ تعديل الدفتر",
197
- "coding.bash": "جارٍ التنفيذ: {x}",
198
- "coding.bash_bare": "جارٍ تنفيذ أمر",
199
- "coding.grep": "جارٍ البحث \"{x}\"",
200
- "coding.grep_bare": "جارٍ البحث في الكود",
201
- "coding.glob": "جارٍ سرد {x}",
202
- "coding.glob_bare": "جارٍ سرد الملفات",
203
- "coding.web_bare": "جارٍ قراءة الويب",
204
- "coding.websearch": "بحث في الويب: {x}",
205
- "coding.websearch_bare": "جارٍ البحث في الويب",
206
- "coding.task": "وكيل فرعي: {x}",
207
- "coding.task_bare": "جارٍ تشغيل وكيل فرعي",
208
- "coding.todo": "جارٍ تحديث قائمة مهامه",
209
- "coding.verb_bare": "جارٍ تنفيذ فعل yujin"
210
- }
1
+ {
2
+ "panel.brand": "Yujin Forge",
3
+ "panel.brand.kanji": "侑",
4
+ "panel.tagline": "مساعد تطوير صوتي أولاً",
5
+ "panel.input.placeholder": "اسأل Yujin",
6
+ "panel.button.send": "إرسال",
7
+ "panel.button.mic": "تحدث (اضغط مع الاستمرار)",
8
+ "panel.button.mic.recording": "اضغط لإيقاف التسجيل",
9
+ "panel.button.tts": "الصوت مفعل",
10
+ "panel.button.keys": "المفاتيح",
11
+ "panel.button.minimise": "تصغير",
12
+ "panel.button.maximise": "تكبير",
13
+ "panel.button.close": "إغلاق",
14
+ "panel.button.language": "اللغة",
15
+ "panel.trace.title": "سجل الإجراءات",
16
+ "panel.trace.count.one": "{n} استدعاء أداة",
17
+ "panel.trace.count.other": "{n} استدعاءات أدوات",
18
+ "panel.trace.empty.kanji": "空",
19
+ "panel.trace.empty.body": "يعرض Yujin Forge هنا كل أداة يستدعيها للرد عليك: قراءة البيان، البحث في SPEC، تحرير المكونات، قراءة المستندات. اطرح سؤالاً يتطلب الرجوع إليها.",
20
+ "panel.trace.badge.tool": "أداة",
21
+ "panel.trace.badge.voice": "صوت",
22
+ "panel.trace.badge.error": "خطأ",
23
+ "panel.stream.empty.kanji": "侑仁",
24
+ "panel.stream.empty.body": "Yujin Forge متصل. اطلب تغييرات على المشروع.",
25
+ "panel.status.no_audio": "لم يُلتقط أي صوت. ربما لم يستقبل الميكروفون شيئاً.",
26
+ "panel.status.did_not_catch": "لم أفهم. لنجرب مرة أخرى.",
27
+ "panel.status.mic_denied": "إذن الميكروفون مرفوض أو غير متاح: {error}",
28
+ "panel.status.voice_failed": "فشل الصوت: {error}",
29
+ "panel.status.voice_reply_failed": "تعذر تشغيل الرد: {error}",
30
+ "panel.status.audio_play_error": "تعذر تشغيل الصوت: {error}",
31
+ "panel.status.reading": "جارٍ قراءة {filename}...",
32
+ "panel.status.ingest_failed": "فشل الاستيعاب: {error}",
33
+ "panel.status.read_failed": "تعذرت قراءة المواصفات: {error}",
34
+ "panel.drop.title": "أفلت المواصفات هنا",
35
+ "panel.drop.hint": "PDF, DOCX, HTML, MD, RTF, EPUB, CSV, XLSX, TXT",
36
+ "panel.ingest.spec_attached": "تم إرفاق المواصفات: {filename}، {kb} KB",
37
+ "panel.ingest.read_label": "تمت القراءة.",
38
+ "panel.ingest.title_label": "العنوان: {title}",
39
+ "panel.ingest.no_title": "(بدون عنوان)",
40
+ "panel.ingest.format_label": "التنسيق: {format} / {sections} قسم / {kb} KB",
41
+ "panel.ingest.first_lines": "الأسطر الأولى:",
42
+ "panel.ingest.action_done": "اكتمل الإجراء {tool}.",
43
+ "vault.modal.title": "بيانات الاعتماد (الخزنة)",
44
+ "vault.modal.aria.close": "إغلاق نافذة بيانات الاعتماد",
45
+ "vault.tab.list": "الخانات المحملة",
46
+ "vault.tab.add": "إضافة",
47
+ "vault.list.loading": "جارٍ التحميل...",
48
+ "vault.list.empty": "لم تقم بتحميل أي مفتاح بعد. انقر على \"إضافة\" للبدء.",
49
+ "vault.add.slot_label": "اسم الخانة",
50
+ "vault.add.slot_hint": "أحرف صغيرة، أرقام، شرطة سفلية، واصلة. يجب أن يبدأ بحرف.",
51
+ "vault.add.value_label": "القيمة النصية (مخفية)",
52
+ "vault.add.value_hint": "تُعرض مرة واحدة فقط عند الحفظ. بعد ذلك يمكن استبدالها وليس قراءتها.",
53
+ "vault.add.button_save": "حفظ",
54
+ "vault.add.button_cancel": "إلغاء",
55
+ "vault.add.success": "تم حفظ الخانة {slot}.",
56
+ "vault.add.overwrite": "تم استبدال الخانة {slot}.",
57
+ "manual.intro": "Yujin Forge -- دليل المستخدم",
58
+ "manual.section.welcome": "مرحباً",
59
+ "manual.section.install": "التثبيت",
60
+ "manual.section.first_run": "التشغيل الأول",
61
+ "manual.section.voice": "الأوامر الصوتية",
62
+ "manual.section.spec_ingest": "استيعاب المواصفات",
63
+ "manual.section.troubleshooting": "حل المشكلات",
64
+ "manual.section.support": "الدعم",
65
+ "lang.name.es": "الإسبانية",
66
+ "lang.name.en": "الإنجليزية",
67
+ "lang.name.pt": "البرتغالية",
68
+ "lang.name.fr": "الفرنسية",
69
+ "lang.name.ja": "اليابانية",
70
+ "lang.name.zh": "الصينية",
71
+ "lang.name.hi": "الهندية",
72
+ "lang.name.ar": "العربية",
73
+ "lang.name.de": "الألمانية",
74
+ "lang.name.it": "الإيطالية",
75
+ "recap.fallback_period": ".",
76
+ "recap.empty": "لا يوجد ما يمكن تلخيصه بعد.",
77
+ "error_ui.severity.info": "معلومات",
78
+ "error_ui.severity.warning": "تحذير",
79
+ "error_ui.severity.error": "خطأ",
80
+ "error_ui.severity.fatal": "فادح",
81
+ "error_ui.label.what": "ماذا حدث",
82
+ "error_ui.label.why": "لماذا",
83
+ "error_ui.label.fix": "كيفية الإصلاح",
84
+ "error_ui.label.cmd": "الأمر",
85
+ "error_ui.label.docs": "الوثائق المحلية",
86
+ "error_ui.label.retry": "إعادة المحاولة في",
87
+ "error_ui.copy_btn": "نسخ الأمر",
88
+ "error_ui.unknown.what": "واجه Forge خطأ داخليا (رمز غير معروف).",
89
+ "error_ui.unknown.why": "الرمز {code} ليس في الكتالوج. هذا خطأ برمجي.",
90
+ "error_ui.unknown.fix": "افتح issue في https://github.com/yujinapp/yujin-forge/issues مع الرمز و traceback.",
91
+ "error.cap_frontier_exhausted.what": "نفد الحد الشهري لرموز طبقة frontier (نموذج كبير).",
92
+ "error.cap_frontier_exhausted.why": "خطتك {plan} تسمح بحد أقصى {cap} رمز/شهر على frontier. استخدمت {used}. يعاد الضبط في بداية الشهر UTC التالي.",
93
+ "error.cap_frontier_exhausted.fix": "انتقل إلى BYOK Anthropic مباشرة: يتجاوز الحد الشهري لـ worker. تصبح تكلفتك ما تتقاضاه Anthropic مباشرة.",
94
+ "error.cap_frontier_exhausted.cmd": "yf brain config --frontier-provider anthropic --frontier-model claude-opus-4-7",
95
+ "error.cap_eco_exhausted.what": "نفد الحد الشهري لرموز طبقة eco (نموذج صغير).",
96
+ "error.cap_eco_exhausted.why": "خطتك {plan} تسمح بحد أقصى {cap} رمز/شهر على eco. استخدمت {used}. يعاد الضبط في بداية الشهر UTC التالي.",
97
+ "error.cap_eco_exhausted.fix": "انتقل إلى BYOK مباشرة أو قم بترقية الخطة. BYOK يتجاوز حد worker.",
98
+ "error.cap_eco_exhausted.cmd": "yf brain config --eco-provider google_ai --eco-model gemini-2.5-flash-lite",
99
+ "error.tier_not_in_plan.what": "الطبقة {tier} غير مفعلة على خطتك.",
100
+ "error.tier_not_in_plan.why": "خطتك {plan} لا تتضمن طبقة {tier}. ربما أنت على free-public أو انتهت صلاحية ترخيصك.",
101
+ "error.tier_not_in_plan.fix": "فعل ترخيصا مدفوعا أو انتقل إلى BYOK مباشرة (تكلفتك، دون حد worker).",
102
+ "error.tier_not_in_plan.cmd": "yf license activate --key <jwt>",
103
+ "error.response_truncated.what": "تم قطع استجابة النموذج قبل الانتهاء.",
104
+ "error.response_truncated.why": "تم الوصول إلى حد managed_max_tokens_per_turn = {limit} رمز في منتصف الدور. توقف النموذج عن التوليد.",
105
+ "error.response_truncated.fix": "ارفع الحد عبر yf limits. ينطبق على الدور التالي دون إعادة تشغيل الدردشة.",
106
+ "error.response_truncated.cmd": "yf limits set managed_max_tokens_per_turn 16384",
107
+ "error.response_truncated.banner": "[الاستجابة مقتطعة بواسطة max_tokens={max}. ارفع الحد بـ: yf limits set managed_max_tokens_per_turn {suggested}]",
108
+ "error.modal_trace_stale.what": "انتهت صلاحية مودال الموافقة أو أصبح يتيما.",
109
+ "error.modal_trace_stale.why": "trace_id {trace_id} ليس له موافقة معلقة في dispatcher. ربما race condition بين invoke وحالة panel، أو ترك cancel سابق trace في حالة zombie.",
110
+ "error.modal_trace_stale.fix": "استدع verb من الدردشة مرة أخرى: يبدأ trace جديد نظيف. إذا استمر، شغل yf doctor لفحص panel.",
111
+ "error.modal_trace_stale.cmd": "yf doctor",
112
+ "error.byok_key_missing.what": "مفتاح API مفقود للمزود {provider}.",
113
+ "error.byok_key_missing.why": "لقد أعددت {provider} كمزود لطبقة {tier} لكن الفتحة byok_{slot} ليست في Vault المشفر.",
114
+ "error.byok_key_missing.fix": "كون المفتاح بـ yf keys set (ذري، mode 0600، لا يسجل أبدا).",
115
+ "error.byok_key_missing.cmd": "yf keys set {slot}",
116
+ "error.worker_unreachable.what": "لم أستطع الوصول إلى worker yujin.app.",
117
+ "error.worker_unreachable.why": "انتهاء مهلة الشبكة أو worker معطل (HTTP {status}). أعدت المحاولة {attempts} مرات.",
118
+ "error.worker_unreachable.fix": "افحص إنترنتك. إذا كان جيدا، انتقل مؤقتا إلى BYOK مباشرة لتجنب الاعتماد على worker.",
119
+ "error.worker_unreachable.cmd": "yf brain config --frontier-provider anthropic",
120
+ "error.vault_decrypt_failed.what": "لم أستطع فك تشفير مفتاح من Vault.",
121
+ "error.vault_decrypt_failed.why": "مفتاح master غير صحيح أو ملف Vault تالف. يمكن أن يحدث إذا نقلت config بين الأجهزة دون نقل master، أو بسبب disk error.",
122
+ "error.vault_decrypt_failed.fix": "اسحب نسخة الخادم (يعيد التشفير بـ master المحلي) إذا كان لديك server backup نشط.",
123
+ "error.vault_decrypt_failed.cmd": "yf keys setup --pull",
124
+ "error.shell_exec_rejected.what": "رفضت مودال R8 لـ yujin.shell.exec.",
125
+ "error.shell_exec_rejected.why": "تم تصنيف الأمر {command} على أنه {classification}. shell.exec يطلب الموافقة دائما للأمان، حتى لو كان الأمر read-only.",
126
+ "error.shell_exec_rejected.fix": "إذا كان الأمر read-only (yf projects active، git status، ls)، استخدم verb الأصلي المكافئ. إذا كان ضروريا ورفضته بالخطأ، استدعه مرة أخرى.",
127
+ "error.project_not_registered.what": "لا يوجد مشروع adopter مسجل.",
128
+ "error.project_not_registered.why": "يتطلب verb المستدعى project root نشط لكن ~/.yujin-forge/projects.json ليس به إدخالات.",
129
+ "error.project_not_registered.fix": "أنشئ واحدا بـ yujin.project.init أو سجل واحدا موجودا بـ yf projects add.",
130
+ "error.project_not_registered.cmd": "yf projects scan",
131
+ "panel.button.agents": "الوكلاء",
132
+ "panel.agents.title": "الوكلاء",
133
+ "panel.agents.subtitle": "المدير والوكلاء الفرعيون المسجلون في هذا المشروع",
134
+ "panel.agents.empty.title": "لا يوجد وكلاء بعد",
135
+ "panel.agents.empty.body": "قم بتشغيل `yf agent install --defaults` لتسجيل المدير ووكلائه الفرعيين الأربعة (المحلل، المبرمج، المختبر، المُجهز).",
136
+ "panel.agents.legend.eco": "اقتصادي",
137
+ "panel.agents.legend.managed": "مُدار",
138
+ "panel.agents.legend.frontier": "حدود",
139
+ "panel.agents.status.disabled": "وقت تشغيل الوكلاء غير مُشغّل",
140
+ "panel.agents.event.running": "قيد التشغيل",
141
+ "panel.agents.event.idle": "خامل",
142
+ "panel.agents.tick.live": "متصل",
143
+ "panel.agents.tick.lost": "الاتصال مفقود",
144
+ "workflow.phase.i": "الفرز والنية",
145
+ "workflow.phase.ii": "التوضيح (الوظيفي + 4 NFR + الكتل)",
146
+ "workflow.phase.iii": "المواصفات (RFP + المعمارية + التصميم + الموافقات)",
147
+ "workflow.phase.iv": "التهيئة",
148
+ "workflow.phase.v": "تطوير الكتل",
149
+ "workflow.phase.vi": "النشر + ما بعد الإطلاق",
150
+ "wizard.title": "مرحبا بك في Yujin Forge",
151
+ "wizard.close": "إغلاق",
152
+ "wizard.intro": "للبدء، اختر كيف يتصل Forge بنموذج الذكاء الاصطناعي. يمكنك تغيير ذلك لاحقا من Settings.",
153
+ "wizard.back": "رجوع",
154
+ "wizard.start": "ابدأ",
155
+ "wizard.plan.badge": "موصى به",
156
+ "wizard.plan.title": "خطة Claude",
157
+ "wizard.plan.desc": "اشتراك Claude الشهري. الخيار الأكثر اقتصاديا للاستخدام المستمر. Forge يستخدم جلسة claude -p الخاصة بك.",
158
+ "wizard.plan.price": "رسم شهري ثابت (الخطة)",
159
+ "wizard.plan.step.title": "وصل خطة Claude الخاصة بك",
160
+ "wizard.plan.step.1": "افتح موجه أوامر جديد.",
161
+ "wizard.plan.step.2": "نفذ الأمر claude (بدون وسائط) وأكمل تسجيل الدخول في المتصفح.",
162
+ "wizard.plan.step.3": "عد إلى هنا واضغط أنا مسجل الدخول للتحقق.",
163
+ "wizard.plan.done": "أنا مسجل الدخول",
164
+ "wizard.byok.title": "مفتاح API الخاص بك (BYOK)",
165
+ "wizard.byok.desc": "مفتاح Anthropic Console الخاص بك. دفع حسب الاستخدام. أكثر مرونة لكن التكلفة متغيرة.",
166
+ "wizard.byok.price": "دفع حسب الاستخدام (Console)",
167
+ "wizard.byok.step.title": "الصق مفتاح Anthropic API الخاص بك",
168
+ "wizard.byok.step.intro": "يبدأ مفتاحك بـ sk-ant- ويتم الحصول عليه من console.anthropic.com. يخزنه Forge مشفرا في Vault المحلي؛ لا يغادر جهازك أبدا.",
169
+ "wizard.byok.test": "تحقق واحفظ",
170
+ "wizard.skip.title": "أنا بالفعل معد",
171
+ "wizard.skip.desc": "تخطي المعالج. يمكنك إعادة فتحه من Settings لاحقا.",
172
+ "wizard.done.kanji": "تم",
173
+ "wizard.done.title": "تم",
174
+ "wizard.done.msg": "Forge جاهز. ابدأ الدردشة.",
175
+ "pizarron.button.read": "اقرأ بصوت",
176
+ "pizarron.button.copy": "نسخ",
177
+ "pizarron.button.edit": "تحرير",
178
+ "pizarron.graph.refresh": "تحديث",
179
+ "pizarron.graph.regenerating": "جارٍ إعادة التوليد...",
180
+ "pizarron.graph.detail.hint": "انقر على عقدة لعرض التفاصيل.",
181
+ "pizarron.graph.detail.empty": "لا توجد تفاصيل لهذه العقدة.",
182
+ "pizarron.graph.detail.weight": "الوزن",
183
+ "startup.tab.graph": "رسم بياني مرئي",
184
+ "startup.tab.graphSem": "الرسم الدلالي",
185
+ "startup.tab.pendings": "معلق",
186
+ "startup.tab.workflow": "سير العمل",
187
+ "settings.startupTabs": "علامات التبويب عند الفتح",
188
+ "graph.term.nodes": "عقد",
189
+ "graph.term.edges": "حواف",
190
+ "coding.read": "جارٍ قراءة {x}",
191
+ "coding.read_bare": "جارٍ قراءة ملف",
192
+ "coding.edit": "جارٍ تعديل {x}",
193
+ "coding.edit_bare": "جارٍ تعديل ملف",
194
+ "coding.write": "جارٍ كتابة {x}",
195
+ "coding.write_bare": "جارٍ كتابة ملف",
196
+ "coding.notebook_bare": "جارٍ تعديل الدفتر",
197
+ "coding.bash": "جارٍ التنفيذ: {x}",
198
+ "coding.bash_bare": "جارٍ تنفيذ أمر",
199
+ "coding.grep": "جارٍ البحث \"{x}\"",
200
+ "coding.grep_bare": "جارٍ البحث في الكود",
201
+ "coding.glob": "جارٍ سرد {x}",
202
+ "coding.glob_bare": "جارٍ سرد الملفات",
203
+ "coding.web_bare": "جارٍ قراءة الويب",
204
+ "coding.websearch": "بحث في الويب: {x}",
205
+ "coding.websearch_bare": "جارٍ البحث في الويب",
206
+ "coding.task": "وكيل فرعي: {x}",
207
+ "coding.task_bare": "جارٍ تشغيل وكيل فرعي",
208
+ "coding.todo": "جارٍ تحديث قائمة مهامه",
209
+ "coding.verb_bare": "جارٍ تنفيذ فعل yujin",
210
+ "panel.button.stop": "إيقاف",
211
+ "panel.status.stopping": "جارٍ الإيقاف...",
212
+ "panel.status.noActiveTurn": "لم تكن هناك جولة قيد التنفيذ.",
213
+ "panel.status.interruptFailed": "تعذّر إرسال المقاطعة.",
214
+ "panel.status.turnInterrupted": "تمت مقاطعة الجولة.",
215
+ "panel.label.interrupted": "(تمت المقاطعة)",
216
+ "panel.queue.label": "في الانتظار",
217
+ "panel.queue.remove": "إزالة من قائمة الانتظار",
218
+ "panel.project.switchHint": "تبديل المشروع",
219
+ "panel.project.title": "المشاريع",
220
+ "panel.project.add": "إضافة مشروع...",
221
+ "panel.project.addPrompt": "المسار المطلق للمشروع المراد إضافته:",
222
+ "panel.project.switching": "جارٍ تبديل المشروع..."
223
+ }