@tunnelbox/core 0.1.17 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -202,7 +202,7 @@ var zh_CN_default = {
202
202
  "install.scanHint": "\u624B\u673A\u6253\u5F00 tunnelbox App\u300C\u626B\u4E00\u626B\u914D\u5BF9\u300D\uFF0C\u626B\u63CF\u4E0A\u65B9\u4E8C\u7EF4\u7801\u5373\u53EF\u8FDE\u63A5\uFF1A",
203
203
  "pair.heading": "tunnelbox \u624B\u673A\u914D\u5BF9",
204
204
  "pair.howTo": "\u5728\u624B\u673A\u4E0A\u6253\u5F00 tunnelbox App\uFF0C\u7528\u300C\u626B\u4E00\u626B\u914D\u5BF9\u300D\u626B\u63CF\u4E0A\u65B9\u4E8C\u7EF4\u7801\uFF0C\u6216\u624B\u52A8\u8F93\u5165\u914D\u5BF9\u7801\u3002",
205
- "pair.oneTime": "\u914D\u5BF9\u7801\u4E3A\u4E00\u6B21\u6027\uFF0C\u4F7F\u7528\u540E\u5373\u5931\u6548\uFF1B\u5982\u9700\u65B0\u7801\uFF0C\u53EF\u8981\u6C42\u201C\u5237\u65B0\u914D\u5BF9\u7801\u201D\u3002",
205
+ "pair.oneTime": "\u914D\u5BF9\u7801\u4E3A\u4E00\u6B21\u6027\uFF0C\u7EA6 10 \u5206\u949F\u5185\u6709\u6548\uFF1B\u4F7F\u7528\u6216\u8FC7\u671F\u540E\u5373\u5931\u6548\uFF0C\u5982\u9700\u65B0\u7801\u53EF\u8981\u6C42\u201C\u5237\u65B0\u914D\u5BF9\u7801\u201D\u3002",
206
206
  "pair.promptBody": "\u8BF7\u5E2E\u6211\u67E5\u770B\u672C\u673A\u624B\u673A\u8FDC\u7A0B\u914D\u5BF9\u4FE1\u606F\uFF1A\u663E\u793A\u914D\u5BF9\u7801\u4E0E\u53EF\u4F9B\u626B\u7801\u7684\u4E8C\u7EF4\u7801\u3002\u4E8C\u7EF4\u7801\u8BF7\u653E\u5728\u7B49\u5BBD\u4EE3\u7801\u5757\u91CC\u5E76\u9010\u5B57\u539F\u6837\u4FDD\u7559\uFF0C\u65B9\u4FBF\u6211\u7528\u624B\u673A\u626B\u7801\u3002",
207
207
  "pair.promptDescription": "\u663E\u793A\u624B\u673A\u8FDC\u7A0B\u914D\u5BF9\u7684\u914D\u5BF9\u7801\u4E0E\u626B\u7801\u4E8C\u7EF4\u7801",
208
208
  "pair.scanIntro": "**\u626B\u4E00\u626B\u914D\u5BF9**\uFF1A\u624B\u673A\u6253\u5F00 tunnelbox App\u300C\u626B\u4E00\u626B\u914D\u5BF9\u300D\uFF0C\u626B\u63CF\u4E0B\u65B9\u4E8C\u7EF4\u7801\u5373\u53EF\u81EA\u52A8\u8FDE\u63A5\u3002",
@@ -317,7 +317,118 @@ var zh_CN_default = {
317
317
  "hermes.pairTimeout": "\u7533\u8BF7\u914D\u5BF9\u7801\u8D85\u65F6\uFF08\u4E2D\u7EE7\u672A\u54CD\u5E94\uFF09",
318
318
  "hermes.errToolPair": "tunnelbox_pair \u5931\u8D25: {err}",
319
319
  "hermes.errToolStatus": "tunnelbox_status \u5931\u8D25: {err}",
320
- "hermes.cliUsage": "\u7528\u6CD5: /tunnelbox <pair|status>\n pair \u5411\u4E2D\u7EE7\u7533\u8BF7\u624B\u673A\u914D\u5BF9\u7801\u5E76\u6253\u5370\n status \u663E\u793A\u4E2D\u7EE7/\u7ED1\u5B9A/\u8FDE\u63A5\u72B6\u6001"
320
+ "hermes.cliUsage": "\u7528\u6CD5: /tunnelbox <pair|status>\n pair \u5411\u4E2D\u7EE7\u7533\u8BF7\u624B\u673A\u914D\u5BF9\u7801\u5E76\u6253\u5370\n status \u663E\u793A\u4E2D\u7EE7/\u7ED1\u5B9A/\u8FDE\u63A5\u72B6\u6001",
321
+ "qr.validFor": "\u914D\u5BF9\u7801\u7EA6 10 \u5206\u949F\u5185\u6709\u6548\uFF0C\u8FC7\u671F\u8BF7\u5728\u7535\u8111\u7AEF\u91CD\u65B0\u83B7\u53D6\u3002",
322
+ "pair.toolDesc": "\u663E\u793A\u672C\u673A\u7684\u624B\u673A\u914D\u5BF9\u4FE1\u606F\uFF08\u914D\u5BF9\u7801\u4E0E\u53EF\u626B\u63CF\u4E8C\u7EF4\u7801\uFF09\u3002\u5F53\u7528\u6237\u8BE2\u95EE\u914D\u5BF9\u3001\u626B\u63CF\u4E8C\u7EF4\u7801\u6216\u7528\u624B\u673A\u63A7\u5236\u672C\u673A\u65F6\u8C03\u7528\u3002",
323
+ "pair.toolRefreshDesc": "\u662F\u5426\u5411\u4E2D\u7EE7\u7533\u8BF7\u65B0\u7684\u914D\u5BF9\u7801",
324
+ "state.errSaveState": "\u4FDD\u5B58\u72B6\u6001\u5931\u8D25",
325
+ "adapter.logConnected": "\u5DF2\u8FDE\u63A5\u4E2D\u7EE7 {url}",
326
+ "adapter.logDisconnected": "\u4E0E\u4E2D\u7EE7\u65AD\u5F00\uFF0C\u6B63\u5728\u81EA\u52A8\u91CD\u8FDE\u2026",
327
+ "adapter.logPairCode": "\u751F\u6210\u914D\u5BF9\u7801: {code}",
328
+ "adapter.logClaimed": "\u5DF2\u7ED1\u5B9A\u5230\u624B\u673A\u8D26\u53F7\uFF0C\u4E4B\u540E\u624B\u673A\u4ECE\u300C\u6211\u7684\u7535\u8111\u300D\u76F4\u63A5\u8FDE\u63A5",
329
+ "adapter.logResetIdentity": "\u88AB\u8D26\u53F7\u89E3\u7ED1\uFF0C\u6B63\u5728\u91CD\u7F6E\u8EAB\u4EFD\u5E76\u91CD\u65B0\u751F\u6210\u914D\u5BF9\u7801\u2026",
330
+ "adapter.logUnhandledType": "\u672A\u5904\u7406\u7684\u6D88\u606F\u7C7B\u578B: {type}",
331
+ "adapter.errNoRelay": "\u672A\u914D\u7F6E\u4E2D\u7EE7\u5730\u5740\uFF1A\u6784\u5EFA\u65F6\u7528 --env \u6CE8\u5165\u9ED8\u8BA4\u503C\uFF0C\u6216\u8FD0\u884C\u65F6\u7528 TUNNELBOX_RELAY_URL \u8986\u76D6",
332
+ "adapter.errBusy": "\u8BE5\u4F1A\u8BDD\u6B63\u5728\u751F\u6210\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u6216\u5148\u505C\u6B62",
333
+ "adapter.errBadWorkspaceEmpty": "\u7F3A\u5C11\u5DE5\u4F5C\u533A\u8DEF\u5F84",
334
+ "adapter.errBadWorkspaceNotDir": "\u8BE5\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u7528",
335
+ "adapter.errWorkspaceMissing": "\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728: {dir}",
336
+ "adapter.cmdNew": "\u65B0\u5EFA\u4F1A\u8BDD",
337
+ "adapter.cmdHelp": "\u663E\u793A\u5E2E\u52A9",
338
+ "adapter.helpText": "\u652F\u6301\u7684\u547D\u4EE4\uFF1A\n- /new \u65B0\u5EFA\u4F1A\u8BDD\n- /help \u663E\u793A\u5E2E\u52A9",
339
+ "adapter.newSessionTitle": "\u65B0\u4F1A\u8BDD",
340
+ "install.langHelpTitle": "install-local \u652F\u6301\u8BED\u8A00\uFF08--lang <tag>\uFF09\uFF1A",
341
+ "install.langHelpExample": "\u793A\u4F8B: npm run install-local -- --lang de-DE",
342
+ "install.unknownLang": '\u672A\u77E5\u8BED\u8A00 "{raw}"\uFF0C\u5DF2\u56DE\u9000 en-US\u3002\u652F\u6301\uFF1A{list}',
343
+ "hermes.errAskRequired": "question \u5FC5\u586B",
344
+ "hermes.msgPhoneUnavailable": "\u624B\u673A\u4E0D\u53EF\u7528\u6216\u672A\u5E94\u7B54\uFF1A\u8BF7\u6539\u7528\u5185\u7F6E clarify \u5728\u672C\u673A\u63D0\u95EE\uFF0C\u6216\u81EA\u884C\u5224\u65AD\u7EE7\u7EED\u3002",
345
+ "hermes.errClarifyUnavailable": "clarify \u652F\u6301\u4E0D\u53EF\u7528",
346
+ "hermes.errAskFailed": "tunnelbox_ask \u5931\u8D25: {err}",
347
+ "hermes.errClarifyFailed": "clarify \u5931\u8D25: {err}",
348
+ "bin.denied": "\u624B\u673A\u5DF2\u62D2\u7EDD",
349
+ "bin.timeout": "\u5BA1\u6279\u8D85\u65F6\uFF08fail-closed\uFF09",
350
+ "bin.reqRun": "Claude Code \u8BF7\u6C42\u6267\u884C {tool}",
351
+ "bin.pairTitle": "tunnelbox \u624B\u673A\u914D\u5BF9",
352
+ "bin.pairCodeLine": " \u914D\u5BF9\u7801: {code}",
353
+ "bin.pairHint": "\u6253\u5F00 tunnelbox App\uFF0C\u7528\u300C\u626B\u4E00\u626B\u914D\u5BF9\u300D\u626B\u63CF\u4E8C\u7EF4\u7801\uFF0C\u6216\u624B\u52A8\u8F93\u5165\u914D\u5BF9\u7801\uFF08\u4E00\u6B21\u6027\uFF09\u3002",
354
+ "bin.pairWritten": " \u914D\u5BF9\u4FE1\u606F\u5DF2\u5199\u5165: {path}",
355
+ "bin.pairRequestFailed": "\u5411\u4E2D\u7EE7\u7533\u8BF7\u914D\u5BF9\u7801\u5931\u8D25\u3002",
356
+ "bin.alreadyClaimed": "\u672C\u673A\u5DF2\u7ED1\u5B9A\u624B\u673A\u8D26\u53F7\uFF0C\u53EF\u76F4\u63A5\u5728\u624B\u673A\u300C\u6211\u7684\u7535\u8111\u300D\u91CC\u8FDE\u63A5\uFF1B\u5982\u9700\u91CD\u65B0\u914D\u5BF9\uFF0C\u8BF7\u5148\u5728\u624B\u673A\u7AEF\u89E3\u7ED1\u3002",
357
+ "bin.noRelay": "\u672A\u914D\u7F6E\u4E2D\u7EE7\u5730\u5740\uFF1A\u8BF7\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF TUNNELBOX_RELAY_URL \u540E\u91CD\u8BD5\u3002",
358
+ "bin.connectFailed": "\u65E0\u6CD5\u8FDE\u63A5\u4E2D\u7EE7\uFF1A{relay}\n\u8BF7\u8BBE\u7F6E TUNNELBOX_RELAY_URL \u6216\u5728\u5B98\u65B9-plugin \u72B6\u6001\u6587\u4EF6\u4E2D\u914D\u7F6E\u3002",
359
+ "bin.statusRelay": "\u4E2D\u7EE7: {value}",
360
+ "bin.statusAgent": "agent \u6807\u8BC6: {value}",
361
+ "bin.statusClaimed": "\u5DF2\u7ED1\u5B9A\u624B\u673A: {value}",
362
+ "bin.statusStateFile": "\u72B6\u6001\u6587\u4EF6: {value}",
363
+ "bin.statusLatest": "\u6700\u65B0\u914D\u5BF9\u4FE1\u606F\uFF1A",
364
+ "bin.usage": "\u7528\u6CD5: tunnelbox <pair|status|ask>",
365
+ "bin.usagePair": " pair \u53D6\u624B\u673A\u914D\u5BF9\u7801\u5E76\u6253\u5370",
366
+ "bin.usageStatus": " status \u663E\u793A\u4E2D\u7EE7/\u7ED1\u5B9A\u72B6\u6001",
367
+ "bin.usageAsk": " ask \u628A\u5DE5\u5177\u5BA1\u6279\u8F6C\u53D1\u5230\u624B\u673A",
368
+ "adapter.logMsgUncaught": "\u6D88\u606F\u5904\u7406\u672A\u6355\u83B7\u5F02\u5E38: {message}",
369
+ "adapter.logHandleFailed": "\u5904\u7406 {type} \u5931\u8D25: {message}",
370
+ "adapter.logPromptFailed": "session.prompt \u5931\u8D25: {message}",
371
+ "adapter.logAbortSent": "\u5DF2\u53D1\u9001\u4E2D\u6B62 (session={session})",
372
+ "adapter.errUserDenied": "\u7528\u6237\u62D2\u7EDD",
373
+ "adapter.logPendingResent": "session.pending \u8865\u53D1\u5F85\u5BA1\u6279 {count} \u6761",
374
+ "adapter.logWorkspaceSwitched": "\u5207\u6362\u5DE5\u4F5C\u533A: {path}",
375
+ "adapter.logNewSession": "\u65B0\u4F1A\u8BDD\u843D\u76D8 codexId={codexId} (alias={session})",
376
+ "adapter.logSessionError": "\u56DE\u5408\u51FA\u9519 (session={session}): {message}",
377
+ "adapter.logDshSent": "\u5DF2\u53D1\u9001\u5230 dsh (session={session})",
378
+ "adapter.logReadHistoryFailed": "\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2\u5931\u8D25({session}): {message}",
379
+ "adapter.logAnswererInitFailed": "\u5E94\u7B54\u5668\u521D\u59CB\u5316\u5931\u8D25: {message}",
380
+ "adapter.logRemoteMode": "\u53CC\u7AEF\u540C\u663E\u6A21\u5F0F\uFF1A\u9009\u62E9/\u5BA1\u6279\u8D70 typert \u591A\u7AEF\u5E7F\u64AD\uFF0C\u624B\u673A\u4E0E dsh web \u540C\u663E\u3001\u8C01\u7B54\u8C01\u5F97",
381
+ "adapter.logRemoteProbeFailed": "typert \u8FDC\u7A0B\u4E8B\u4EF6\u6E90\u63A2\u6D4B\u5931\u8D25\uFF0C\u56DE\u9000\u672C\u5730\u5E94\u7B54\u6A21\u5F0F: {message}",
382
+ "adapter.logLocalMode": "\u672C\u5730\u5E94\u7B54\u6A21\u5F0F\uFF1A\u9009\u62E9/\u5BA1\u6279\u7531\u624B\u673A\u4F5C\u7B54\uFF08headless\uFF0C\u65E0 dsh web \u5E7F\u64AD\uFF09",
383
+ "adapter.logRemoteStreamInterrupted": "remote events \u6D41\u4E2D\u65AD: {message}",
384
+ "adapter.logResultRejected": "$events/result \u672A\u63A5\u53D7({eventId}): {message}",
385
+ "adapter.logResultBackfillFailed": "$events/result \u56DE\u586B\u5931\u8D25({eventId}): {message}",
386
+ "adapter.logRemoteQuestion": "remote \u63D0\u95EE\u5E7F\u64AD \u2192 \u624B\u673A\u63D0\u95EE\u5361 questionID={id} (session={session})",
387
+ "adapter.errRemoteReadyFrame": "remote events \u9996\u5E27\u5F02\u5E38",
388
+ "adapter.logRemoteApproval": "remote \u5BA1\u6279\u5E7F\u64AD \u2192 \u624B\u673A\u6743\u9650\u5361 permissionID={id} (session={session})",
389
+ "adapter.logUserQuestionRoute": "user-questions \u9009\u62E9 \u2192 \u8DEF\u7531 session={session}",
390
+ "adapter.errDshQuestionEmpty": "dsh \u63D0\u95EE\u5185\u5BB9\u4E3A\u7A7A",
391
+ "adapter.errQuestionTimeout": "\u63D0\u95EE\u8D85\u65F6({seconds}s)\uFF0C\u5DF2\u53D6\u6D88",
392
+ "adapter.errQuestionCancelledAbort": "\u63D0\u95EE\u5DF2\u53D6\u6D88\uFF08agent \u4E2D\u6B62\uFF09",
393
+ "adapter.errQuestionCancelledRelay": "\u4E2D\u7EE7\u4E0D\u53EF\u8FBE\uFF0C\u63D0\u95EE\u5DF2\u53D6\u6D88",
394
+ "adapter.logQuestionToPhone": "user-questions \u9009\u62E9 \u2192 \u53D1\u9001\u5230\u624B\u673A\u63D0\u95EE\u5361 questionID={id} (session={session})",
395
+ "adapter.errQuestionUserCancelled": "\u7528\u6237\u5728\u624B\u673A\u7AEF\u53D6\u6D88/\u62D2\u7EDD\u4E86\u63D0\u95EE",
396
+ "adapter.logApprovalRequest": "\u5BA1\u6279\u8BF7\u6C42(tool={tool}) \u2192 \u53D1\u9001\u5230\u624B\u673A\u6743\u9650\u5361 permissionID={id}",
397
+ "adapter.logAgentPresetFailed": "agentPreset \u89E3\u6790\u5931\u8D25({preset})\uFF0C\u964D\u7EA7\u4E3A\u65E0 preset: {message}",
398
+ "adapter.logSessionLiveAdopted": "\u4F1A\u8BDD {session} \u5DF2\u7531\u672C\u8FDB\u7A0B\u5176\u5B83 agent \u6301\u6709\uFF08live\uFF09\uFF0C\u91C7\u7EB3\u73B0\u6709 agent \u7EE7\u7EED\u9A71\u52A8: {message}",
399
+ "adapter.logDisposeSkipped": "\u5DF2\u91C7\u7EB3\u7684\u5916\u90E8 live agent \u4E0D\u6267\u884C dispose\uFF08\u4F1A\u8BDD {session} \u7531\u539F\u6301\u6709\u8005\u7BA1\u7406\uFF09",
400
+ "adapter.logAgentCreateFailed": "\u521B\u5EFA/\u6062\u590D agent \u5931\u8D25({session}): {message}",
401
+ "adapter.errSessionBusyLive": "\u4F1A\u8BDD {session} \u6B63\u88AB\u5360\u7528\uFF08live\uFF09\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
402
+ "adapter.errAgentsUnavailable": "agents \u670D\u52A1\u4E0D\u53EF\u7528",
403
+ "adapter.logToolReason": "dsh \u8BF7\u6C42\u6267\u884C\u5DE5\u5177 {tool}",
404
+ "adapter.logGatewayConnected": "\u5DF2\u8FDE\u63A5\u672C\u673A OpenClaw Gateway\uFF08{version}\uFF09",
405
+ "adapter.logGatewayDisconnected": "\u4E0E OpenClaw Gateway \u65AD\u5F00\uFF0C\u6B63\u5728\u7531\u5B98\u65B9\u5BA2\u6237\u7AEF\u91CD\u8FDE\u2026",
406
+ "adapter.logGatewayConnectFailed": "\u65E0\u6CD5\u8FDE\u63A5\u672C\u673A OpenClaw Gateway\uFF08\u9996\u6B21\u9700\u5728\u672C\u673A\u653E\u884C\u8BBE\u5907\uFF1A`openclaw devices list` + `openclaw devices approve <requestId>`\uFF09",
407
+ "adapter.errGatewayNoSessionKey": "Gateway \u672A\u8FD4\u56DE\u4F1A\u8BDD key",
408
+ "adapter.logDeleteSessionFailed": "\u5220\u9664\u4F1A\u8BDD\u5931\u8D25({session}): {message}\uFF08\u4ECD\u6309\u5DF2\u5220\u9664\u56DE\u6267\uFF09",
409
+ "adapter.logApprovalReplyFailed": "\u5BA1\u6279\u5E94\u7B54\u5931\u8D25({id}): {message}",
410
+ "adapter.logPendingApproval": "session.pending \u8865\u53D1\u5F85\u5BA1\u6279 {count} \u6761 (session={session})",
411
+ "adapter.workspaceDefault": "\u9ED8\u8BA4",
412
+ "adapter.cursorSessionTitle": "Cursor \u4F1A\u8BDD",
413
+ "adapter.reasonDisconnect": "\u4E2D\u7EE7\u65AD\u5F00\uFF0C\u81EA\u52A8\u62D2\u7EDD\uFF08fail-closed\uFF09",
414
+ "adapter.warnInvalidEnv": "\u5FFD\u7565\u65E0\u6548 {name}: {raw}\uFF08{list}\uFF09",
415
+ "adapter.errStartFailed": "\u542F\u52A8\u5931\u8D25:",
416
+ "adapter.msgStarted": "{name} \u9002\u914D\u5668\u5DF2\u542F\u52A8\uFF08Ctrl+C \u9000\u51FA\uFF09",
417
+ "adapter.warnCliMissing": "\u672A\u627E\u5230\u53EF\u6267\u884C\u6587\u4EF6\u300C{bin}\u300D\uFF1B\u8BF7\u5148\u5B89\u88C5\uFF08\u5982 npm i -g @openai/codex\uFF09\uFF0C\u6216\u7528 TUNNELBOX_CODEX_BIN \u6307\u5B9A\u53EF\u6267\u884C\u6587\u4EF6\u8DEF\u5F84",
418
+ "adapter.errCliNotFound": "\u672A\u627E\u5230 {name} \u53EF\u6267\u884C\u6587\u4EF6\u300C{bin}\u300D\uFF1A\u8BF7\u5B89\u88C5 Codex CLI\uFF08npm i -g @openai/codex\uFF09\u6216\u8BBE\u7F6E TUNNELBOX_CODEX_BIN",
419
+ "adapter.errSessionNotFound": "\u4F1A\u8BDD\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664",
420
+ "adapter.checkHeader": "tunnelbox-codex \u73AF\u5883\u81EA\u68C0",
421
+ "adapter.checkCliOk": "{name} \u53EF\u6267\u884C\u6587\u4EF6: {path}",
422
+ "adapter.checkCliMissing": "\u672A\u627E\u5230 {name} \u53EF\u6267\u884C\u6587\u4EF6\uFF08{bin}\uFF09",
423
+ "bin.yes": "\u662F",
424
+ "bin.no": "\u5426",
425
+ "adapter.errAppServerSpawn": "\u65E0\u6CD5\u542F\u52A8 codex app-server\uFF1A{message}\uFF08\u8BF7\u786E\u8BA4 Codex CLI \u652F\u6301 `codex app-server`\uFF09",
426
+ "adapter.errAppServerExit": "codex app-server \u5DF2\u9000\u51FA\uFF0C\u8FDB\u884C\u4E2D\u7684\u5BA1\u6279/\u9009\u62E9\u5DF2\u81EA\u52A8\u62D2\u7EDD",
427
+ "adapter.logUnsupportedServerRequest": "\u6682\u4E0D\u652F\u6301\u7684 app-server \u8BF7\u6C42: {method}",
428
+ "adapter.logQuestionNative": "\u9009\u62E9\u8BF7\u6C42 \u2192 \u624B\u673A\u9009\u62E9\u5361 questionID={id} (session={session})",
429
+ "adapter.logPermissionNative": "\u5BA1\u6279\u8BF7\u6C42 \u2192 \u624B\u673A\u6743\u9650\u5361 permissionID={id} (session={session})",
430
+ "adapter.checkAppServerOk": "codex app-server \u53EF\u7528",
431
+ "adapter.checkAppServerMissing": "\u5F53\u524D Codex CLI \u4E0D\u652F\u6301 `codex app-server`\uFF08\u8BF7\u5347\u7EA7 Codex CLI\uFF09"
321
432
  };
322
433
 
323
434
  // locales/zh-TW.json
@@ -370,7 +481,7 @@ var zh_TW_default = {
370
481
  "install.scanHint": "\u624B\u6A5F\u958B\u555F tunnelbox App\u300C\u6383\u63CF\u914D\u5C0D\u300D\uFF0C\u6383\u63CF\u4E0A\u65B9 QR Code \u5373\u53EF\u9023\u63A5\uFF1A",
371
482
  "pair.heading": "tunnelbox \u624B\u6A5F\u914D\u5C0D",
372
483
  "pair.howTo": "\u5728\u624B\u6A5F\u4E0A\u958B\u555F tunnelbox App\uFF0C\u7528\u300C\u6383\u63CF\u914D\u5C0D\u300D\u6383\u63CF\u4E0A\u65B9 QR Code\uFF0C\u6216\u624B\u52D5\u8F38\u5165\u914D\u5C0D\u78BC\u3002",
373
- "pair.oneTime": "\u914D\u5C0D\u78BC\u70BA\u4E00\u6B21\u6027\uFF0C\u4F7F\u7528\u5F8C\u5373\u5931\u6548\uFF1B\u5982\u9700\u65B0\u78BC\uFF0C\u53EF\u8981\u6C42\u300C\u91CD\u65B0\u6574\u7406\u914D\u5C0D\u78BC\u300D\u3002",
484
+ "pair.oneTime": "\u914D\u5C0D\u78BC\u70BA\u4E00\u6B21\u6027\uFF0C\u7D04 10 \u5206\u9418\u5167\u6709\u6548\uFF1B\u4F7F\u7528\u6216\u904E\u671F\u5F8C\u5373\u5931\u6548\uFF0C\u5982\u9700\u65B0\u78BC\u53EF\u8981\u6C42\u300C\u91CD\u65B0\u6574\u7406\u914D\u5C0D\u78BC\u300D\u3002",
374
485
  "pair.promptBody": "\u8ACB\u5E6B\u6211\u67E5\u770B\u672C\u6A5F\u624B\u6A5F\u9060\u7AEF\u914D\u5C0D\u8CC7\u8A0A\uFF1A\u986F\u793A\u914D\u5C0D\u78BC\u8207\u53EF\u4F9B\u6383\u78BC\u7684 QR Code\u3002QR Code \u8ACB\u653E\u5728\u7B49\u5BEC\u7A0B\u5F0F\u78BC\u5340\u584A\u5167\u4E26\u9010\u5B57\u539F\u6A23\u4FDD\u7559\uFF0C\u65B9\u4FBF\u6211\u7528\u624B\u6A5F\u6383\u63CF\u3002",
375
486
  "pair.promptDescription": "\u986F\u793A\u624B\u6A5F\u9060\u7AEF\u914D\u5C0D\u7684\u914D\u5C0D\u78BC\u8207\u6383\u78BC QR Code",
376
487
  "pair.scanIntro": "**\u6383\u78BC\u914D\u5C0D**\uFF1A\u624B\u6A5F\u958B\u555F tunnelbox App\u300C\u6383\u63CF\u914D\u5C0D\u300D\uFF0C\u6383\u63CF\u4E0B\u65B9 QR Code \u5373\u53EF\u81EA\u52D5\u9023\u63A5\u3002",
@@ -485,7 +596,118 @@ var zh_TW_default = {
485
596
  "hermes.pairTimeout": "\u7533\u8ACB\u914D\u5C0D\u78BC\u903E\u6642\uFF08\u4E2D\u7E7C\u672A\u56DE\u61C9\uFF09",
486
597
  "hermes.errToolPair": "tunnelbox_pair \u5931\u6557: {err}",
487
598
  "hermes.errToolStatus": "tunnelbox_status \u5931\u6557: {err}",
488
- "hermes.cliUsage": "\u7528\u6CD5: /tunnelbox <pair|status>\n pair \u5411\u4E2D\u7E7C\u7533\u8ACB\u624B\u6A5F\u914D\u5C0D\u78BC\u4E26\u5217\u5370\n status \u986F\u793A\u4E2D\u7E7C/\u7D81\u5B9A/\u9023\u7DDA\u72C0\u614B"
599
+ "hermes.cliUsage": "\u7528\u6CD5: /tunnelbox <pair|status>\n pair \u5411\u4E2D\u7E7C\u7533\u8ACB\u624B\u6A5F\u914D\u5C0D\u78BC\u4E26\u5217\u5370\n status \u986F\u793A\u4E2D\u7E7C/\u7D81\u5B9A/\u9023\u7DDA\u72C0\u614B",
600
+ "qr.validFor": "\u914D\u5C0D\u78BC\u7D04 10 \u5206\u9418\u5167\u6709\u6548\uFF0C\u904E\u671F\u8ACB\u5728\u96FB\u8166\u7AEF\u91CD\u65B0\u53D6\u5F97\u3002",
601
+ "pair.toolDesc": "\u986F\u793A\u672C\u6A5F\u7684\u624B\u6A5F\u914D\u5C0D\u8CC7\u8A0A\uFF08\u914D\u5C0D\u78BC\u8207\u53EF\u6383\u63CF QR code\uFF09\u3002\u7576\u4F7F\u7528\u8005\u8A62\u554F\u914D\u5C0D\u3001\u6383\u63CF QR code \u6216\u7528\u624B\u6A5F\u63A7\u5236\u672C\u6A5F\u6642\u547C\u53EB\u3002",
602
+ "pair.toolRefreshDesc": "\u662F\u5426\u5411\u4E2D\u7E7C\u7533\u8ACB\u65B0\u7684\u914D\u5C0D\u78BC",
603
+ "state.errSaveState": "\u5132\u5B58\u72C0\u614B\u5931\u6557",
604
+ "adapter.logConnected": "\u5DF2\u9023\u63A5\u4E2D\u7E7C {url}",
605
+ "adapter.logDisconnected": "\u8207\u4E2D\u7E7C\u65B7\u958B\uFF0C\u6B63\u5728\u81EA\u52D5\u91CD\u9023\u2026",
606
+ "adapter.logPairCode": "\u7522\u751F\u914D\u5C0D\u78BC: {code}",
607
+ "adapter.logClaimed": "\u5DF2\u7D81\u5B9A\u5230\u624B\u6A5F\u5E33\u865F\uFF0C\u4E4B\u5F8C\u624B\u6A5F\u5F9E\u300C\u6211\u7684\u96FB\u8166\u300D\u76F4\u63A5\u9023\u63A5",
608
+ "adapter.logResetIdentity": "\u88AB\u5E33\u865F\u89E3\u7D81\uFF0C\u6B63\u5728\u91CD\u8A2D\u8EAB\u5206\u4E26\u91CD\u65B0\u7522\u751F\u914D\u5C0D\u78BC\u2026",
609
+ "adapter.logUnhandledType": "\u672A\u8655\u7406\u7684\u8A0A\u606F\u985E\u578B: {type}",
610
+ "adapter.errNoRelay": "\u672A\u8A2D\u5B9A\u4E2D\u7E7C\u4F4D\u5740\uFF1A\u5EFA\u7F6E\u6642\u7528 --env \u6CE8\u5165\u9810\u8A2D\u503C\uFF0C\u6216\u57F7\u884C\u6642\u7528 TUNNELBOX_RELAY_URL \u8986\u5BEB",
611
+ "adapter.errBusy": "\u8A72\u5DE5\u4F5C\u968E\u6BB5\u6B63\u5728\u751F\u6210\u4E2D\uFF0C\u8ACB\u7B49\u5F85\u5B8C\u6210\u6216\u5148\u505C\u6B62",
612
+ "adapter.errBadWorkspaceEmpty": "\u7F3A\u5C11\u5DE5\u4F5C\u5340\u8DEF\u5F91",
613
+ "adapter.errBadWorkspaceNotDir": "\u8A72\u76EE\u9304\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u7528",
614
+ "adapter.errWorkspaceMissing": "\u5DE5\u4F5C\u5340\u4E0D\u5B58\u5728: {dir}",
615
+ "adapter.cmdNew": "\u65B0\u5EFA\u5DE5\u4F5C\u968E\u6BB5",
616
+ "adapter.cmdHelp": "\u986F\u793A\u8AAA\u660E",
617
+ "adapter.helpText": "\u652F\u63F4\u7684\u547D\u4EE4\uFF1A\n- /new \u65B0\u5EFA\u5DE5\u4F5C\u968E\u6BB5\n- /help \u986F\u793A\u8AAA\u660E",
618
+ "adapter.newSessionTitle": "\u65B0\u5DE5\u4F5C\u968E\u6BB5",
619
+ "install.langHelpTitle": "install-local \u652F\u63F4\u8A9E\u8A00\uFF08--lang <tag>\uFF09\uFF1A",
620
+ "install.langHelpExample": "\u7BC4\u4F8B: npm run install-local -- --lang de-DE",
621
+ "install.unknownLang": '\u672A\u77E5\u8A9E\u8A00 "{raw}"\uFF0C\u5DF2\u56DE\u9000 en-US\u3002\u652F\u63F4\uFF1A{list}',
622
+ "hermes.errAskRequired": "question \u5FC5\u586B",
623
+ "hermes.msgPhoneUnavailable": "\u624B\u6A5F\u4E0D\u53EF\u7528\u6216\u672A\u56DE\u61C9\uFF1A\u8ACB\u6539\u7528\u5167\u5EFA clarify \u5728\u672C\u6A5F\u63D0\u554F\uFF0C\u6216\u81EA\u884C\u5224\u65B7\u7E7C\u7E8C\u3002",
624
+ "hermes.errClarifyUnavailable": "clarify \u652F\u63F4\u4E0D\u53EF\u7528",
625
+ "hermes.errAskFailed": "tunnelbox_ask \u5931\u6557: {err}",
626
+ "hermes.errClarifyFailed": "clarify \u5931\u6557: {err}",
627
+ "bin.denied": "\u624B\u6A5F\u5DF2\u62D2\u7D55",
628
+ "bin.timeout": "\u5BE9\u6279\u903E\u6642\uFF08fail-closed\uFF09",
629
+ "bin.reqRun": "Claude Code \u8ACB\u6C42\u57F7\u884C {tool}",
630
+ "bin.pairTitle": "tunnelbox \u624B\u6A5F\u914D\u5C0D",
631
+ "bin.pairCodeLine": " \u914D\u5C0D\u78BC: {code}",
632
+ "bin.pairHint": "\u6253\u958B tunnelbox App\uFF0C\u7528\u300C\u6383\u4E00\u6383\u914D\u5C0D\u300D\u6383\u63CF QR code\uFF0C\u6216\u624B\u52D5\u8F38\u5165\u914D\u5C0D\u78BC\uFF08\u4E00\u6B21\u6027\uFF09\u3002",
633
+ "bin.pairWritten": " \u914D\u5C0D\u8CC7\u8A0A\u5DF2\u5BEB\u5165: {path}",
634
+ "bin.pairRequestFailed": "\u5411\u4E2D\u7E7C\u7533\u8ACB\u914D\u5C0D\u78BC\u5931\u6557\u3002",
635
+ "bin.alreadyClaimed": "\u672C\u6A5F\u5DF2\u7D81\u5B9A\u624B\u6A5F\u5E33\u865F\uFF0C\u53EF\u76F4\u63A5\u5728\u624B\u6A5F\u300C\u6211\u7684\u96FB\u8166\u300D\u88E1\u9023\u63A5\uFF1B\u5982\u9700\u91CD\u65B0\u914D\u5C0D\uFF0C\u8ACB\u5148\u5728\u624B\u6A5F\u7AEF\u89E3\u7D81\u3002",
636
+ "bin.noRelay": "\u672A\u8A2D\u5B9A\u4E2D\u7E7C\u4F4D\u5740\uFF1A\u8ACB\u8A2D\u5B9A\u74B0\u5883\u8B8A\u6578 TUNNELBOX_RELAY_URL \u5F8C\u91CD\u8A66\u3002",
637
+ "bin.connectFailed": "\u7121\u6CD5\u9023\u63A5\u4E2D\u7E7C\uFF1A{relay}\n\u8ACB\u8A2D\u5B9A TUNNELBOX_RELAY_URL \u6216\u5728\u5B98\u65B9-plugin \u72C0\u614B\u6A94\u6848\u4E2D\u8A2D\u5B9A\u3002",
638
+ "bin.statusRelay": "\u4E2D\u7E7C: {value}",
639
+ "bin.statusAgent": "agent \u8B58\u5225\u78BC: {value}",
640
+ "bin.statusClaimed": "\u5DF2\u7D81\u5B9A\u624B\u6A5F: {value}",
641
+ "bin.statusStateFile": "\u72C0\u614B\u6A94\u6848: {value}",
642
+ "bin.statusLatest": "\u6700\u65B0\u914D\u5C0D\u8CC7\u8A0A\uFF1A",
643
+ "bin.usage": "\u7528\u6CD5: tunnelbox <pair|status|ask>",
644
+ "bin.usagePair": " pair \u53D6\u624B\u6A5F\u914D\u5C0D\u78BC\u4E26\u5217\u5370",
645
+ "bin.usageStatus": " status \u986F\u793A\u4E2D\u7E7C/\u7D81\u5B9A\u72C0\u614B",
646
+ "bin.usageAsk": " ask \u628A\u5DE5\u5177\u5BE9\u6279\u8F49\u767C\u5230\u624B\u6A5F",
647
+ "adapter.logMsgUncaught": "\u8A0A\u606F\u8655\u7406\u672A\u6355\u6349\u4F8B\u5916: {message}",
648
+ "adapter.logHandleFailed": "\u8655\u7406 {type} \u5931\u6557: {message}",
649
+ "adapter.logPromptFailed": "session.prompt \u5931\u6557: {message}",
650
+ "adapter.logAbortSent": "\u5DF2\u767C\u9001\u4E2D\u6B62 (session={session})",
651
+ "adapter.errUserDenied": "\u4F7F\u7528\u8005\u62D2\u7D55",
652
+ "adapter.logPendingResent": "session.pending \u88DC\u767C\u5F85\u5BE9\u6279 {count} \u689D",
653
+ "adapter.logWorkspaceSwitched": "\u5207\u63DB\u5DE5\u4F5C\u5340: {path}",
654
+ "adapter.logNewSession": "\u65B0\u5DE5\u4F5C\u968E\u6BB5\u843D\u76E4 codexId={codexId} (alias={session})",
655
+ "adapter.logSessionError": "\u56DE\u5408\u51FA\u932F (session={session}): {message}",
656
+ "adapter.logDshSent": "\u5DF2\u767C\u9001\u5230 dsh (session={session})",
657
+ "adapter.logReadHistoryFailed": "\u8B80\u53D6\u5DE5\u4F5C\u968E\u6BB5\u6B77\u53F2\u5931\u6557({session}): {message}",
658
+ "adapter.logAnswererInitFailed": "\u61C9\u7B54\u5668\u521D\u59CB\u5316\u5931\u6557: {message}",
659
+ "adapter.logRemoteMode": "\u96D9\u7AEF\u540C\u986F\u6A21\u5F0F\uFF1A\u9078\u64C7/\u5BE9\u6279\u8D70 typert \u591A\u7AEF\u5EE3\u64AD\uFF0C\u624B\u6A5F\u8207 dsh web \u540C\u986F\u3001\u8AB0\u7B54\u8AB0\u5F97",
660
+ "adapter.logRemoteProbeFailed": "typert \u9060\u7AEF\u4E8B\u4EF6\u6E90\u63A2\u6E2C\u5931\u6557\uFF0C\u56DE\u9000\u672C\u5730\u61C9\u7B54\u6A21\u5F0F: {message}",
661
+ "adapter.logLocalMode": "\u672C\u5730\u61C9\u7B54\u6A21\u5F0F\uFF1A\u9078\u64C7/\u5BE9\u6279\u7531\u624B\u6A5F\u4F5C\u7B54\uFF08headless\uFF0C\u7121 dsh web \u5EE3\u64AD\uFF09",
662
+ "adapter.logRemoteStreamInterrupted": "remote events \u4E32\u6D41\u4E2D\u65B7: {message}",
663
+ "adapter.logResultRejected": "$events/result \u672A\u63A5\u53D7({eventId}): {message}",
664
+ "adapter.logResultBackfillFailed": "$events/result \u56DE\u586B\u5931\u6557({eventId}): {message}",
665
+ "adapter.logRemoteQuestion": "remote \u63D0\u554F\u5EE3\u64AD \u2192 \u624B\u6A5F\u63D0\u554F\u5361 questionID={id} (session={session})",
666
+ "adapter.errRemoteReadyFrame": "remote events \u9996\u5E40\u7570\u5E38",
667
+ "adapter.logRemoteApproval": "remote \u5BE9\u6279\u5EE3\u64AD \u2192 \u624B\u6A5F\u6B0A\u9650\u5361 permissionID={id} (session={session})",
668
+ "adapter.logUserQuestionRoute": "user-questions \u9078\u64C7 \u2192 \u8DEF\u7531 session={session}",
669
+ "adapter.errDshQuestionEmpty": "dsh \u63D0\u554F\u5167\u5BB9\u70BA\u7A7A",
670
+ "adapter.errQuestionTimeout": "\u63D0\u554F\u903E\u6642({seconds}s)\uFF0C\u5DF2\u53D6\u6D88",
671
+ "adapter.errQuestionCancelledAbort": "\u63D0\u554F\u5DF2\u53D6\u6D88\uFF08agent \u4E2D\u6B62\uFF09",
672
+ "adapter.errQuestionCancelledRelay": "\u4E2D\u7E7C\u4E0D\u53EF\u9054\uFF0C\u63D0\u554F\u5DF2\u53D6\u6D88",
673
+ "adapter.logQuestionToPhone": "user-questions \u9078\u64C7 \u2192 \u767C\u9001\u5230\u624B\u6A5F\u63D0\u554F\u5361 questionID={id} (session={session})",
674
+ "adapter.errQuestionUserCancelled": "\u4F7F\u7528\u8005\u5728\u624B\u6A5F\u7AEF\u53D6\u6D88/\u62D2\u7D55\u4E86\u63D0\u554F",
675
+ "adapter.logApprovalRequest": "\u5BE9\u6279\u8ACB\u6C42(tool={tool}) \u2192 \u767C\u9001\u5230\u624B\u6A5F\u6B0A\u9650\u5361 permissionID={id}",
676
+ "adapter.logAgentPresetFailed": "agentPreset \u89E3\u6790\u5931\u6557({preset})\uFF0C\u964D\u7D1A\u70BA\u7121 preset: {message}",
677
+ "adapter.logSessionLiveAdopted": "\u5DE5\u4F5C\u968E\u6BB5 {session} \u5DF2\u7531\u672C\u884C\u7A0B\u5176\u5B83 agent \u6301\u6709\uFF08live\uFF09\uFF0C\u63A1\u7D0D\u73FE\u6709 agent \u7E7C\u7E8C\u9A45\u52D5: {message}",
678
+ "adapter.logDisposeSkipped": "\u5DF2\u63A1\u7D0D\u7684\u5916\u90E8 live agent \u4E0D\u57F7\u884C dispose\uFF08\u5DE5\u4F5C\u968E\u6BB5 {session} \u7531\u539F\u6301\u6709\u8005\u7BA1\u7406\uFF09",
679
+ "adapter.logAgentCreateFailed": "\u5EFA\u7ACB/\u6062\u5FA9 agent \u5931\u6557({session}): {message}",
680
+ "adapter.errSessionBusyLive": "\u5DE5\u4F5C\u968E\u6BB5 {session} \u6B63\u88AB\u4F54\u7528\uFF08live\uFF09\uFF0C\u8ACB\u7A0D\u5F8C\u91CD\u8A66",
681
+ "adapter.errAgentsUnavailable": "agents \u670D\u52D9\u4E0D\u53EF\u7528",
682
+ "adapter.logToolReason": "dsh \u8ACB\u6C42\u57F7\u884C\u5DE5\u5177 {tool}",
683
+ "adapter.logGatewayConnected": "\u5DF2\u9023\u63A5\u672C\u6A5F OpenClaw Gateway\uFF08{version}\uFF09",
684
+ "adapter.logGatewayDisconnected": "\u8207 OpenClaw Gateway \u65B7\u958B\uFF0C\u6B63\u5728\u7531\u5B98\u65B9\u5BA2\u6236\u7AEF\u91CD\u9023\u2026",
685
+ "adapter.logGatewayConnectFailed": "\u7121\u6CD5\u9023\u63A5\u672C\u6A5F OpenClaw Gateway\uFF08\u9996\u6B21\u9700\u5728\u672C\u6A5F\u653E\u884C\u88DD\u7F6E\uFF1A`openclaw devices list` + `openclaw devices approve <requestId>`\uFF09",
686
+ "adapter.errGatewayNoSessionKey": "Gateway \u672A\u8FD4\u56DE\u5DE5\u4F5C\u968E\u6BB5 key",
687
+ "adapter.logDeleteSessionFailed": "\u522A\u9664\u5DE5\u4F5C\u968E\u6BB5\u5931\u6557({session}): {message}\uFF08\u4ECD\u6309\u5DF2\u522A\u9664\u56DE\u57F7\uFF09",
688
+ "adapter.logApprovalReplyFailed": "\u5BE9\u6279\u61C9\u7B54\u5931\u6557({id}): {message}",
689
+ "adapter.logPendingApproval": "session.pending \u88DC\u767C\u5F85\u5BE9\u6279 {count} \u689D (session={session})",
690
+ "adapter.workspaceDefault": "\u9810\u8A2D",
691
+ "adapter.cursorSessionTitle": "Cursor \u5DE5\u4F5C\u968E\u6BB5",
692
+ "adapter.reasonDisconnect": "\u4E2D\u7E7C\u65B7\u958B\uFF0C\u81EA\u52D5\u62D2\u7D55\uFF08fail-closed\uFF09",
693
+ "adapter.warnInvalidEnv": "\u5FFD\u7565\u7121\u6548 {name}: {raw}\uFF08{list}\uFF09",
694
+ "adapter.errStartFailed": "\u555F\u52D5\u5931\u6557:",
695
+ "adapter.msgStarted": "{name} \u9069\u914D\u5668\u5DF2\u555F\u52D5\uFF08Ctrl+C \u9000\u51FA\uFF09",
696
+ "adapter.warnCliMissing": "\u672A\u627E\u5230\u57F7\u884C\u6A94\u300C{bin}\u300D\uFF1B\u8ACB\u5148\u5B89\u88DD\uFF08\u5982 npm i -g @openai/codex\uFF09\uFF0C\u6216\u7528 TUNNELBOX_CODEX_BIN \u6307\u5B9A\u57F7\u884C\u6A94\u8DEF\u5F91",
697
+ "adapter.errCliNotFound": "\u672A\u627E\u5230 {name} \u57F7\u884C\u6A94\u300C{bin}\u300D\uFF1A\u8ACB\u5B89\u88DD Codex CLI\uFF08npm i -g @openai/codex\uFF09\u6216\u8A2D\u5B9A TUNNELBOX_CODEX_BIN",
698
+ "adapter.errSessionNotFound": "\u6703\u8A71\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u522A\u9664",
699
+ "adapter.checkHeader": "tunnelbox-codex \u74B0\u5883\u81EA\u6AA2",
700
+ "adapter.checkCliOk": "{name} \u57F7\u884C\u6A94: {path}",
701
+ "adapter.checkCliMissing": "\u672A\u627E\u5230 {name} \u57F7\u884C\u6A94\uFF08{bin}\uFF09",
702
+ "bin.yes": "\u662F",
703
+ "bin.no": "\u5426",
704
+ "adapter.errAppServerSpawn": "\u7121\u6CD5\u555F\u52D5 codex app-server\uFF1A{message}\uFF08\u8ACB\u78BA\u8A8D Codex CLI \u652F\u63F4 `codex app-server`\uFF09",
705
+ "adapter.errAppServerExit": "codex app-server \u5DF2\u7D50\u675F\uFF0C\u9032\u884C\u4E2D\u7684\u5BE9\u6279/\u9078\u64C7\u5DF2\u81EA\u52D5\u62D2\u7D55",
706
+ "adapter.logUnsupportedServerRequest": "\u66AB\u4E0D\u652F\u63F4\u7684 app-server \u8ACB\u6C42: {method}",
707
+ "adapter.logQuestionNative": "\u9078\u64C7\u8ACB\u6C42 \u2192 \u624B\u6A5F\u9078\u64C7\u5361 questionID={id} (session={session})",
708
+ "adapter.logPermissionNative": "\u5BE9\u6279\u8ACB\u6C42 \u2192 \u624B\u6A5F\u6B0A\u9650\u5361 permissionID={id} (session={session})",
709
+ "adapter.checkAppServerOk": "codex app-server \u53EF\u7528",
710
+ "adapter.checkAppServerMissing": "\u76EE\u524D Codex CLI \u4E0D\u652F\u63F4 `codex app-server`\uFF08\u8ACB\u5347\u7D1A Codex CLI\uFF09"
489
711
  };
490
712
 
491
713
  // locales/en-US.json
@@ -538,7 +760,7 @@ var en_US_default = {
538
760
  "install.scanHint": "Open tunnelbox on your phone, tap \u201CScan to pair\u201D, and scan the QR code above to connect:",
539
761
  "pair.heading": "tunnelbox phone pairing",
540
762
  "pair.howTo": "Open the tunnelbox app on your phone and scan the QR code above with \u201CScan to pair\u201D, or enter the pairing code manually.",
541
- "pair.oneTime": "The pairing code is single-use and invalidates after it is claimed; ask to \u201Crefresh the pairing code\u201D for a new one.",
763
+ "pair.oneTime": "The pairing code is single-use and valid for about 10 minutes; it stops working once claimed or expired. Ask to \u201Crefresh the pairing code\u201D for a new one.",
542
764
  "pair.promptBody": "Please show this computer's phone pairing info: the pairing code and a QR code I can scan. Keep the QR code inside a monospaced code block and reproduce it character-for-character so my phone can scan it.",
543
765
  "pair.promptDescription": "Show the phone pairing code and scan-able QR code",
544
766
  "pair.scanIntro": "**Pair by scanning**: open the tunnelbox app on your phone, tap \u201CScan to pair\u201D, and scan the QR code below to connect automatically.",
@@ -653,7 +875,118 @@ var en_US_default = {
653
875
  "hermes.pairTimeout": "Timed out requesting a pairing code (relay did not respond)",
654
876
  "hermes.errToolPair": "tunnelbox_pair failed: {err}",
655
877
  "hermes.errToolStatus": "tunnelbox_status failed: {err}",
656
- "hermes.cliUsage": "Usage: /tunnelbox <pair|status>\n pair request and print a phone pairing code\n status show relay/binding/connection status"
878
+ "hermes.cliUsage": "Usage: /tunnelbox <pair|status>\n pair request and print a phone pairing code\n status show relay/binding/connection status",
879
+ "qr.validFor": "The pairing code is valid for about 10 minutes; get a new one on your computer if it expires.",
880
+ "pair.toolDesc": "Show this computer's opencode phone pairing info (pairing code and a scan-able QR code). Call when the user asks about pairing, scanning a QR code, or controlling this computer from their phone.",
881
+ "pair.toolRefreshDesc": "Whether to request a new pairing code from the relay",
882
+ "state.errSaveState": "Failed to save state",
883
+ "adapter.logConnected": "Connected to relay {url}",
884
+ "adapter.logDisconnected": "Disconnected from relay, reconnecting automatically\u2026",
885
+ "adapter.logPairCode": "Generated pairing code: {code}",
886
+ "adapter.logClaimed": "Bound to your phone account. From now on the phone connects directly from My Computers",
887
+ "adapter.logResetIdentity": "Unbound from the account; resetting identity and generating a new pairing code\u2026",
888
+ "adapter.logUnhandledType": "Unhandled message type: {type}",
889
+ "adapter.errNoRelay": "No relay URL configured: build with --env to inject a default, or override at runtime with TUNNELBOX_RELAY_URL",
890
+ "adapter.errBusy": "This session is still running; wait for it to finish or stop it first",
891
+ "adapter.errBadWorkspaceEmpty": "Missing workspace path",
892
+ "adapter.errBadWorkspaceNotDir": "Directory does not exist or is unusable",
893
+ "adapter.errWorkspaceMissing": "Workspace does not exist: {dir}",
894
+ "adapter.cmdNew": "New session",
895
+ "adapter.cmdHelp": "Show help",
896
+ "adapter.helpText": "Supported commands:\n- /new new session\n- /help show help",
897
+ "adapter.newSessionTitle": "New session",
898
+ "install.langHelpTitle": "install-local supported languages (--lang <tag>):",
899
+ "install.langHelpExample": "Example: npm run install-local -- --lang de-DE",
900
+ "install.unknownLang": 'Unknown language "{raw}", falling back to en-US. Supported: {list}',
901
+ "hermes.errAskRequired": "question is required",
902
+ "hermes.msgPhoneUnavailable": "Phone unavailable or no response: use the built-in clarify to ask locally, or decide on your own.",
903
+ "hermes.errClarifyUnavailable": "clarify support unavailable",
904
+ "hermes.errAskFailed": "tunnelbox_ask failed: {err}",
905
+ "hermes.errClarifyFailed": "clarify failed: {err}",
906
+ "bin.denied": "Rejected from your phone",
907
+ "bin.timeout": "Approval timed out (fail-closed)",
908
+ "bin.reqRun": "Claude Code requests to run {tool}",
909
+ "bin.pairTitle": "tunnelbox phone pairing",
910
+ "bin.pairCodeLine": " Pairing code: {code}",
911
+ "bin.pairHint": "Open the tunnelbox app, tap \u201CScan to pair\u201D and scan the QR code, or enter the pairing code manually (single-use).",
912
+ "bin.pairWritten": " Pairing info written to: {path}",
913
+ "bin.pairRequestFailed": "Failed to request a pairing code from the relay.",
914
+ "bin.alreadyClaimed": "This computer is already bound to a phone account; connect directly from \u201CMy Computers\u201D. To re-pair, unbind it on your phone first.",
915
+ "bin.noRelay": "No relay URL configured: set TUNNELBOX_RELAY_URL and try again.",
916
+ "bin.connectFailed": "Cannot connect to the relay: {relay}\nSet TUNNELBOX_RELAY_URL or configure it in the official-plugin state file.",
917
+ "bin.statusRelay": "Relay: {value}",
918
+ "bin.statusAgent": "Agent ID: {value}",
919
+ "bin.statusClaimed": "Phone bound: {value}",
920
+ "bin.statusStateFile": "State file: {value}",
921
+ "bin.statusLatest": "Latest pairing info:",
922
+ "bin.usage": "Usage: tunnelbox <pair|status|ask>",
923
+ "bin.usagePair": " pair request and print a phone pairing code",
924
+ "bin.usageStatus": " status show relay/binding status",
925
+ "bin.usageAsk": " ask forward a tool approval to the phone",
926
+ "adapter.logMsgUncaught": "Uncaught exception while handling message: {message}",
927
+ "adapter.logHandleFailed": "Failed to handle {type}: {message}",
928
+ "adapter.logPromptFailed": "session.prompt failed: {message}",
929
+ "adapter.logAbortSent": "Abort sent (session={session})",
930
+ "adapter.errUserDenied": "Rejected by user",
931
+ "adapter.logPendingResent": "session.pending: resent {count} pending request(s)",
932
+ "adapter.logWorkspaceSwitched": "Switched workspace: {path}",
933
+ "adapter.logNewSession": "New session persisted codexId={codexId} (alias={session})",
934
+ "adapter.logSessionError": "Turn error (session={session}): {message}",
935
+ "adapter.logDshSent": "Sent to dsh (session={session})",
936
+ "adapter.logReadHistoryFailed": "Failed to read session history ({session}): {message}",
937
+ "adapter.logAnswererInitFailed": "Answerer initialization failed: {message}",
938
+ "adapter.logRemoteMode": "Dual-display mode: selections/approvals use typert multi-client broadcast; phone and dsh web share the view, first answer wins",
939
+ "adapter.logRemoteProbeFailed": "typert remote event source probe failed; falling back to local answering mode: {message}",
940
+ "adapter.logLocalMode": "Local answering mode: selections/approvals answered by the phone (headless, no dsh web broadcast)",
941
+ "adapter.logRemoteStreamInterrupted": "remote events stream interrupted: {message}",
942
+ "adapter.logResultRejected": "$events/result not accepted ({eventId}): {message}",
943
+ "adapter.logResultBackfillFailed": "$events/result backfill failed ({eventId}): {message}",
944
+ "adapter.logRemoteQuestion": "remote question broadcast \u2192 phone question card questionID={id} (session={session})",
945
+ "adapter.errRemoteReadyFrame": "Unexpected remote events first frame",
946
+ "adapter.logRemoteApproval": "remote approval broadcast \u2192 phone permission card permissionID={id} (session={session})",
947
+ "adapter.logUserQuestionRoute": "user-questions selection \u2192 routed to session={session}",
948
+ "adapter.errDshQuestionEmpty": "dsh question content is empty",
949
+ "adapter.errQuestionTimeout": "Question timed out ({seconds}s), cancelled",
950
+ "adapter.errQuestionCancelledAbort": "Question cancelled (agent aborted)",
951
+ "adapter.errQuestionCancelledRelay": "Relay unreachable, question cancelled",
952
+ "adapter.logQuestionToPhone": "user-questions selection \u2192 sent to phone question card questionID={id} (session={session})",
953
+ "adapter.errQuestionUserCancelled": "User cancelled/rejected the question on the phone",
954
+ "adapter.logApprovalRequest": "Approval request (tool={tool}) \u2192 sent to phone permission card permissionID={id}",
955
+ "adapter.logAgentPresetFailed": "agentPreset resolution failed ({preset}); falling back to no preset: {message}",
956
+ "adapter.logSessionLiveAdopted": "Session {session} is already held by another agent in this process (live); adopting the existing agent to continue: {message}",
957
+ "adapter.logDisposeSkipped": "Adopted external live agent does not run dispose (session {session} is managed by its original holder)",
958
+ "adapter.logAgentCreateFailed": "Failed to create/resume agent ({session}): {message}",
959
+ "adapter.errSessionBusyLive": "Session {session} is busy (live); try again later",
960
+ "adapter.errAgentsUnavailable": "agents service unavailable",
961
+ "adapter.logToolReason": "dsh requests to run tool {tool}",
962
+ "adapter.logGatewayConnected": "Connected to local OpenClaw Gateway ({version})",
963
+ "adapter.logGatewayDisconnected": "Disconnected from OpenClaw Gateway; the official client is reconnecting\u2026",
964
+ "adapter.logGatewayConnectFailed": "Cannot connect to local OpenClaw Gateway (first time, approve the device locally: `openclaw devices list` + `openclaw devices approve <requestId>`)",
965
+ "adapter.errGatewayNoSessionKey": "Gateway did not return a session key",
966
+ "adapter.logDeleteSessionFailed": "Failed to delete session ({session}): {message} (still acking as deleted)",
967
+ "adapter.logApprovalReplyFailed": "Approval reply failed ({id}): {message}",
968
+ "adapter.logPendingApproval": "session.pending: resent {count} pending approval(s) (session={session})",
969
+ "adapter.workspaceDefault": "Default",
970
+ "adapter.cursorSessionTitle": "Cursor session",
971
+ "adapter.reasonDisconnect": "Relay disconnected, auto-rejecting (fail-closed)",
972
+ "adapter.warnInvalidEnv": "Ignoring invalid {name}: {raw} ({list})",
973
+ "adapter.errStartFailed": "Failed to start:",
974
+ "adapter.msgStarted": "{name} adapter started (Ctrl+C to quit)",
975
+ "adapter.warnCliMissing": 'Executable "{bin}" not found; install it (e.g. npm i -g @openai/codex) or set TUNNELBOX_CODEX_BIN to its path',
976
+ "adapter.errCliNotFound": '{name} executable "{bin}" not found: install the Codex CLI (npm i -g @openai/codex) or set TUNNELBOX_CODEX_BIN',
977
+ "adapter.errSessionNotFound": "Session not found or already deleted",
978
+ "adapter.checkHeader": "tunnelbox-codex environment check",
979
+ "adapter.checkCliOk": "{name} executable: {path}",
980
+ "adapter.checkCliMissing": "{name} executable not found ({bin})",
981
+ "bin.yes": "yes",
982
+ "bin.no": "no",
983
+ "adapter.errAppServerSpawn": "Failed to start codex app-server: {message} (make sure your Codex CLI supports `codex app-server`)",
984
+ "adapter.errAppServerExit": "codex app-server exited; pending approvals/choices were auto-declined",
985
+ "adapter.logUnsupportedServerRequest": "unsupported app-server request: {method}",
986
+ "adapter.logQuestionNative": "choice request -> phone choice card questionID={id} (session={session})",
987
+ "adapter.logPermissionNative": "approval request -> phone approval card permissionID={id} (session={session})",
988
+ "adapter.checkAppServerOk": "codex app-server available",
989
+ "adapter.checkAppServerMissing": "this Codex CLI does not support `codex app-server` (please upgrade Codex CLI)"
657
990
  };
658
991
 
659
992
  // locales/ja-JP.json
@@ -706,7 +1039,7 @@ var ja_JP_default = {
706
1039
  "install.scanHint": "\u30B9\u30DE\u30DB\u3067 tunnelbox App\u300C\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30DA\u30A2\u30EA\u30F3\u30B0\u300D\u3092\u958B\u304D\u3001\u4E0A\u306E QR \u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u63A5\u7D9A\uFF1A",
707
1040
  "pair.heading": "tunnelbox \u30B9\u30DE\u30DB\u30DA\u30A2\u30EA\u30F3\u30B0",
708
1041
  "pair.howTo": "\u30B9\u30DE\u30DB\u3067 tunnelbox App \u3092\u958B\u304D\u3001\u300C\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30DA\u30A2\u30EA\u30F3\u30B0\u300D\u3067\u4E0A\u306E QR \u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3\u3059\u308B\u304B\u3001\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u624B\u52D5\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
709
- "pair.oneTime": "\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u306F\u4E00\u5EA6\u304D\u308A\u3067\u3001\u4F7F\u7528\u5F8C\u306F\u7121\u52B9\u306B\u306A\u308A\u307E\u3059\u3002\u65B0\u3057\u3044\u30B3\u30FC\u30C9\u304C\u5FC5\u8981\u306A\u5834\u5408\u306F\u300C\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u66F4\u65B0\u300D\u3068\u4F9D\u983C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
1042
+ "pair.oneTime": "\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u306F1\u56DE\u9650\u308A\u3067\u3001\u6709\u52B9\u671F\u9650\u306F\u7D0410\u5206\u3067\u3059\u3002\u4F7F\u7528\u307E\u305F\u306F\u671F\u9650\u5207\u308C\u3067\u7121\u52B9\u306B\u306A\u308A\u307E\u3059\u3002\u65B0\u3057\u3044\u30B3\u30FC\u30C9\u304C\u5FC5\u8981\u306A\u5834\u5408\u306F\u300C\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u66F4\u65B0\u300D\u3068\u4F9D\u983C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
710
1043
  "pair.promptBody": "\u3053\u306E PC \u306E\u30B9\u30DE\u30DB\u9060\u9694\u30DA\u30A2\u30EA\u30F3\u30B0\u60C5\u5831\u3092\u8868\u793A\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3068\u3001\u30B9\u30AD\u30E3\u30F3\u3067\u304D\u308B QR \u30B3\u30FC\u30C9\u3002QR \u30B3\u30FC\u30C9\u306F\u7B49\u5E45\u30B3\u30FC\u30C9\u30D6\u30ED\u30C3\u30AF\u306B\u5165\u308C\u30011 \u6587\u5B57\u3082\u5909\u3048\u305A\u305D\u306E\u307E\u307E\u51FA\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30B9\u30DE\u30DB\u3067\u30B9\u30AD\u30E3\u30F3\u3067\u304D\u308B\u3088\u3046\u306B\u3059\u308B\u305F\u3081\u3067\u3059\u3002",
711
1044
  "pair.promptDescription": "\u30B9\u30DE\u30DB\u9060\u9694\u30DA\u30A2\u30EA\u30F3\u30B0\u306E\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u30FB\u30B9\u30AD\u30E3\u30F3\u7528 QR \u30B3\u30FC\u30C9\u3092\u8868\u793A",
712
1045
  "pair.scanIntro": "**\u30B9\u30AD\u30E3\u30F3\u3067\u30DA\u30A2\u30EA\u30F3\u30B0**\uFF1A\u30B9\u30DE\u30DB\u3067 tunnelbox App\u300C\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30DA\u30A2\u30EA\u30F3\u30B0\u300D\u3092\u958B\u304D\u3001\u4E0B\u306E QR \u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3\u3059\u308B\u3068\u81EA\u52D5\u7684\u306B\u63A5\u7D9A\u3055\u308C\u307E\u3059\u3002",
@@ -821,7 +1154,118 @@ var ja_JP_default = {
821
1154
  "hermes.pairTimeout": "\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u8981\u6C42\u304C\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\uFF08\u30EA\u30EC\u30FC\u672A\u5FDC\u7B54\uFF09",
822
1155
  "hermes.errToolPair": "tunnelbox_pair \u5931\u6557: {err}",
823
1156
  "hermes.errToolStatus": "tunnelbox_status \u5931\u6557: {err}",
824
- "hermes.cliUsage": "\u4F7F\u7528\u65B9\u6CD5: /tunnelbox <pair|status>\n pair \u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u53D6\u5F97\u3057\u3066\u8868\u793A\n status \u30EA\u30EC\u30FC/\u30D0\u30A4\u30F3\u30C9/\u63A5\u7D9A\u72B6\u614B\u3092\u8868\u793A"
1157
+ "hermes.cliUsage": "\u4F7F\u7528\u65B9\u6CD5: /tunnelbox <pair|status>\n pair \u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u53D6\u5F97\u3057\u3066\u8868\u793A\n status \u30EA\u30EC\u30FC/\u30D0\u30A4\u30F3\u30C9/\u63A5\u7D9A\u72B6\u614B\u3092\u8868\u793A",
1158
+ "qr.validFor": "\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u306F\u7D0410\u5206\u3067\u3059\u3002\u671F\u9650\u5207\u308C\u306E\u5834\u5408\u306F\u30D1\u30BD\u30B3\u30F3\u5074\u3067\u518D\u53D6\u5F97\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
1159
+ "pair.toolDesc": "\u3053\u306E\u30D1\u30BD\u30B3\u30F3\u306E\u30B9\u30DE\u30DB\u9023\u643A\u60C5\u5831\uFF08\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3068\u30B9\u30AD\u30E3\u30F3\u53EF\u80FD\u306AQR\u30B3\u30FC\u30C9\uFF09\u3092\u8868\u793A\u3057\u307E\u3059\u3002\u30DA\u30A2\u30EA\u30F3\u30B0\u3084QR\u30B3\u30FC\u30C9\u306E\u30B9\u30AD\u30E3\u30F3\u3001\u30B9\u30DE\u30DB\u304B\u3089\u306E\u64CD\u4F5C\u306B\u3064\u3044\u3066\u8CEA\u554F\u3055\u308C\u305F\u3068\u304D\u306B\u547C\u3073\u51FA\u3057\u307E\u3059\u3002",
1160
+ "pair.toolRefreshDesc": "\u30EA\u30EC\u30FC\u306B\u65B0\u3057\u3044\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u8981\u6C42\u3059\u308B\u304B\u3069\u3046\u304B",
1161
+ "state.errSaveState": "\u72B6\u614B\u306E\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
1162
+ "adapter.logConnected": "\u30EA\u30EC\u30FC\u306B\u63A5\u7D9A\u3057\u307E\u3057\u305F {url}",
1163
+ "adapter.logDisconnected": "\u30EA\u30EC\u30FC\u304B\u3089\u5207\u65AD\u3055\u308C\u307E\u3057\u305F\u3002\u81EA\u52D5\u7684\u306B\u518D\u63A5\u7D9A\u3057\u3066\u3044\u307E\u3059\u2026",
1164
+ "adapter.logPairCode": "\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u751F\u6210\u3057\u307E\u3057\u305F: {code}",
1165
+ "adapter.logClaimed": "\u30B9\u30DE\u30DB\u30A2\u30AB\u30A6\u30F3\u30C8\u306B\u7D10\u4ED8\u3051\u307E\u3057\u305F\u3002\u4EE5\u964D\u306F\u30B9\u30DE\u30DB\u306E\u300C\u30DE\u30A4\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u30FC\u300D\u304B\u3089\u76F4\u63A5\u63A5\u7D9A\u3057\u307E\u3059",
1166
+ "adapter.logResetIdentity": "\u30A2\u30AB\u30A6\u30F3\u30C8\u304B\u3089\u89E3\u9664\u3055\u308C\u307E\u3057\u305F\u3002ID\u3092\u30EA\u30BB\u30C3\u30C8\u3057\u3001\u65B0\u3057\u3044\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u751F\u6210\u3057\u3066\u3044\u307E\u3059\u2026",
1167
+ "adapter.logUnhandledType": "\u672A\u51E6\u7406\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u30BF\u30A4\u30D7: {type}",
1168
+ "adapter.errNoRelay": "\u30EA\u30EC\u30FCURL\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u30D3\u30EB\u30C9\u6642\u306B --env \u3067\u65E2\u5B9A\u5024\u3092\u6CE8\u5165\u3059\u308B\u304B\u3001\u5B9F\u884C\u6642\u306B TUNNELBOX_RELAY_URL \u3067\u4E0A\u66F8\u304D\u3057\u3066\u304F\u3060\u3055\u3044",
1169
+ "adapter.errBusy": "\u3053\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306F\u5B9F\u884C\u4E2D\u3067\u3059\u3002\u5B8C\u4E86\u3092\u5F85\u3064\u304B\u3001\u5148\u306B\u505C\u6B62\u3057\u3066\u304F\u3060\u3055\u3044",
1170
+ "adapter.errBadWorkspaceEmpty": "\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E\u30D1\u30B9\u304C\u3042\u308A\u307E\u305B\u3093",
1171
+ "adapter.errBadWorkspaceNotDir": "\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u5B58\u5728\u3057\u306A\u3044\u304B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093",
1172
+ "adapter.errWorkspaceMissing": "\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u304C\u5B58\u5728\u3057\u307E\u305B\u3093: {dir}",
1173
+ "adapter.cmdNew": "\u65B0\u3057\u3044\u30BB\u30C3\u30B7\u30E7\u30F3",
1174
+ "adapter.cmdHelp": "\u30D8\u30EB\u30D7\u3092\u8868\u793A",
1175
+ "adapter.helpText": "\u4F7F\u7528\u53EF\u80FD\u306A\u30B3\u30DE\u30F3\u30C9\uFF1A\n- /new \u65B0\u3057\u3044\u30BB\u30C3\u30B7\u30E7\u30F3\n- /help \u30D8\u30EB\u30D7\u3092\u8868\u793A",
1176
+ "adapter.newSessionTitle": "\u65B0\u3057\u3044\u30BB\u30C3\u30B7\u30E7\u30F3",
1177
+ "install.langHelpTitle": "install-local \u304C\u5BFE\u5FDC\u3059\u308B\u8A00\u8A9E\uFF08--lang <tag>\uFF09\uFF1A",
1178
+ "install.langHelpExample": "\u4F8B: npm run install-local -- --lang de-DE",
1179
+ "install.unknownLang": '\u4E0D\u660E\u306A\u8A00\u8A9E "{raw}" \u306E\u305F\u3081 en-US \u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3057\u307E\u3059\u3002\u5BFE\u5FDC: {list}',
1180
+ "hermes.errAskRequired": "question \u306F\u5FC5\u9808\u3067\u3059",
1181
+ "hermes.msgPhoneUnavailable": "\u30B9\u30DE\u30DB\u304C\u5229\u7528\u3067\u304D\u306A\u3044\u304B\u5FDC\u7B54\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u7D44\u307F\u8FBC\u307F\u306E clarify \u3067\u30ED\u30FC\u30AB\u30EB\u306B\u8CEA\u554F\u3059\u308B\u304B\u3001\u3054\u81EA\u8EAB\u3067\u5224\u65AD\u3057\u3066\u7D9A\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
1182
+ "hermes.errClarifyUnavailable": "clarify \u30B5\u30DD\u30FC\u30C8\u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093",
1183
+ "hermes.errAskFailed": "tunnelbox_ask \u306B\u5931\u6557\u3057\u307E\u3057\u305F: {err}",
1184
+ "hermes.errClarifyFailed": "clarify \u306B\u5931\u6557\u3057\u307E\u3057\u305F: {err}",
1185
+ "bin.denied": "\u30B9\u30DE\u30DB\u3067\u62D2\u5426\u3055\u308C\u307E\u3057\u305F",
1186
+ "bin.timeout": "\u627F\u8A8D\u304C\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F\uFF08fail-closed\uFF09",
1187
+ "bin.reqRun": "Claude Code \u304C {tool} \u306E\u5B9F\u884C\u3092\u8981\u6C42\u3057\u3066\u3044\u307E\u3059",
1188
+ "bin.pairTitle": "tunnelbox \u30B9\u30DE\u30DB\u9023\u643A",
1189
+ "bin.pairCodeLine": " \u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9: {code}",
1190
+ "bin.pairHint": "tunnelbox \u30A2\u30D7\u30EA\u3092\u958B\u304D\u300C\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30DA\u30A2\u30EA\u30F3\u30B0\u300D\u3067QR\u30B3\u30FC\u30C9\u3092\u8AAD\u307F\u53D6\u308B\u304B\u3001\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u3092\u624B\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\uFF081\u56DE\u9650\u308A\uFF09\u3002",
1191
+ "bin.pairWritten": " \u9023\u643A\u60C5\u5831\u3092\u66F8\u304D\u8FBC\u307F\u307E\u3057\u305F: {path}",
1192
+ "bin.pairRequestFailed": "\u30EA\u30EC\u30FC\u3078\u306E\u30DA\u30A2\u30EA\u30F3\u30B0\u30B3\u30FC\u30C9\u8981\u6C42\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002",
1193
+ "bin.alreadyClaimed": "\u3053\u306E\u30D1\u30BD\u30B3\u30F3\u306F\u65E2\u306B\u30B9\u30DE\u30DB\u30A2\u30AB\u30A6\u30F3\u30C8\u306B\u7D10\u4ED8\u3051\u3089\u308C\u3066\u3044\u307E\u3059\u3002\u30B9\u30DE\u30DB\u306E\u300C\u30DE\u30A4\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u30FC\u300D\u304B\u3089\u76F4\u63A5\u63A5\u7D9A\u3067\u304D\u307E\u3059\u3002\u518D\u30DA\u30A2\u30EA\u30F3\u30B0\u3059\u308B\u306B\u306F\u3001\u5148\u306B\u30B9\u30DE\u30DB\u5074\u3067\u89E3\u9664\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
1194
+ "bin.noRelay": "\u30EA\u30EC\u30FCURL\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u74B0\u5883\u5909\u6570 TUNNELBOX_RELAY_URL \u3092\u8A2D\u5B9A\u3057\u3066\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
1195
+ "bin.connectFailed": "\u30EA\u30EC\u30FC\u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093: {relay}\nTUNNELBOX_RELAY_URL \u3092\u8A2D\u5B9A\u3059\u308B\u304B\u3001official-plugin \u306E\u72B6\u614B\u30D5\u30A1\u30A4\u30EB\u3067\u69CB\u6210\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
1196
+ "bin.statusRelay": "\u30EA\u30EC\u30FC: {value}",
1197
+ "bin.statusAgent": "\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8ID: {value}",
1198
+ "bin.statusClaimed": "\u30B9\u30DE\u30DB\u9023\u643A: {value}",
1199
+ "bin.statusStateFile": "\u72B6\u614B\u30D5\u30A1\u30A4\u30EB: {value}",
1200
+ "bin.statusLatest": "\u6700\u65B0\u306E\u9023\u643A\u60C5\u5831:",
1201
+ "bin.usage": "\u4F7F\u7528\u6CD5: tunnelbox <pair|status|ask>",
1202
+ "bin.usagePair": " pair \u30B9\u30DE\u30DB\u9023\u643A\u30B3\u30FC\u30C9\u3092\u53D6\u5F97\u3057\u3066\u8868\u793A",
1203
+ "bin.usageStatus": " status \u30EA\u30EC\u30FC/\u9023\u643A\u72B6\u614B\u3092\u8868\u793A",
1204
+ "bin.usageAsk": " ask \u30C4\u30FC\u30EB\u627F\u8A8D\u3092\u30B9\u30DE\u30DB\u306B\u8EE2\u9001",
1205
+ "adapter.logMsgUncaught": "\u30E1\u30C3\u30BB\u30FC\u30B8\u51E6\u7406\u3067\u672A\u6355\u6349\u306E\u4F8B\u5916: {message}",
1206
+ "adapter.logHandleFailed": "{type} \u306E\u51E6\u7406\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {message}",
1207
+ "adapter.logPromptFailed": "session.prompt \u306B\u5931\u6557\u3057\u307E\u3057\u305F: {message}",
1208
+ "adapter.logAbortSent": "\u4E2D\u6B62\u3092\u9001\u4FE1\u3057\u307E\u3057\u305F (session={session})",
1209
+ "adapter.errUserDenied": "\u30E6\u30FC\u30B6\u30FC\u304C\u62D2\u5426\u3057\u307E\u3057\u305F",
1210
+ "adapter.logPendingResent": "session.pending: \u672A\u51E6\u7406\u30EA\u30AF\u30A8\u30B9\u30C8\u3092 {count} \u4EF6\u518D\u9001\u3057\u307E\u3057\u305F",
1211
+ "adapter.logWorkspaceSwitched": "\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092\u5207\u308A\u66FF\u3048\u307E\u3057\u305F: {path}",
1212
+ "adapter.logNewSession": "\u65B0\u898F\u30BB\u30C3\u30B7\u30E7\u30F3\u3092\u4FDD\u5B58 codexId={codexId} (alias={session})",
1213
+ "adapter.logSessionError": "\u30BF\u30FC\u30F3\u30A8\u30E9\u30FC (session={session}): {message}",
1214
+ "adapter.logDshSent": "dsh \u306B\u9001\u4FE1\u3057\u307E\u3057\u305F (session={session})",
1215
+ "adapter.logReadHistoryFailed": "\u30BB\u30C3\u30B7\u30E7\u30F3\u5C65\u6B74\u306E\u8AAD\u307F\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F ({session}): {message}",
1216
+ "adapter.logAnswererInitFailed": "\u5FDC\u7B54\u8005\u306E\u521D\u671F\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {message}",
1217
+ "adapter.logRemoteMode": "\u4E21\u5074\u540C\u6642\u8868\u793A\u30E2\u30FC\u30C9: \u9078\u629E/\u627F\u8A8D\u306F typert \u30DE\u30EB\u30C1\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u653E\u9001\u3092\u4F7F\u7528\u3002\u30B9\u30DE\u30DB\u3068 dsh web \u304C\u540C\u3058\u753B\u9762\u3092\u5171\u6709\u3057\u3001\u5148\u306B\u56DE\u7B54\u3057\u305F\u65B9\u304C\u6709\u52B9",
1218
+ "adapter.logRemoteProbeFailed": "typert \u30EA\u30E2\u30FC\u30C8\u30A4\u30D9\u30F3\u30C8\u30BD\u30FC\u30B9\u306E\u691C\u51FA\u306B\u5931\u6557\u3002\u30ED\u30FC\u30AB\u30EB\u5FDC\u7B54\u30E2\u30FC\u30C9\u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3057\u307E\u3059: {message}",
1219
+ "adapter.logLocalMode": "\u30ED\u30FC\u30AB\u30EB\u5FDC\u7B54\u30E2\u30FC\u30C9: \u9078\u629E/\u627F\u8A8D\u306F\u30B9\u30DE\u30DB\u304C\u56DE\u7B54\uFF08headless\u3001dsh web \u653E\u9001\u306A\u3057\uFF09",
1220
+ "adapter.logRemoteStreamInterrupted": "remote events \u30B9\u30C8\u30EA\u30FC\u30E0\u304C\u4E2D\u65AD\u3057\u307E\u3057\u305F: {message}",
1221
+ "adapter.logResultRejected": "$events/result \u304C\u53D7\u7406\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F ({eventId}): {message}",
1222
+ "adapter.logResultBackfillFailed": "$events/result \u306E\u66F8\u304D\u623B\u3057\u306B\u5931\u6557\u3057\u307E\u3057\u305F ({eventId}): {message}",
1223
+ "adapter.logRemoteQuestion": "remote \u8CEA\u554F\u653E\u9001 \u2192 \u30B9\u30DE\u30DB\u8CEA\u554F\u30AB\u30FC\u30C9 questionID={id} (session={session})",
1224
+ "adapter.errRemoteReadyFrame": "remote events \u306E\u6700\u521D\u306E\u30D5\u30EC\u30FC\u30E0\u304C\u7570\u5E38\u3067\u3059",
1225
+ "adapter.logRemoteApproval": "remote \u627F\u8A8D\u653E\u9001 \u2192 \u30B9\u30DE\u30DB\u6A29\u9650\u30AB\u30FC\u30C9 permissionID={id} (session={session})",
1226
+ "adapter.logUserQuestionRoute": "user-questions \u9078\u629E \u2192 session={session} \u306B\u30EB\u30FC\u30C6\u30A3\u30F3\u30B0",
1227
+ "adapter.errDshQuestionEmpty": "dsh \u306E\u8CEA\u554F\u5185\u5BB9\u304C\u7A7A\u3067\u3059",
1228
+ "adapter.errQuestionTimeout": "\u8CEA\u554F\u304C\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F ({seconds}s)\u3001\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F",
1229
+ "adapter.errQuestionCancelledAbort": "\u8CEA\u554F\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F\uFF08\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u4E2D\u6B62\uFF09",
1230
+ "adapter.errQuestionCancelledRelay": "\u30EA\u30EC\u30FC\u306B\u5230\u9054\u3067\u304D\u305A\u3001\u8CEA\u554F\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F",
1231
+ "adapter.logQuestionToPhone": "user-questions \u9078\u629E \u2192 \u30B9\u30DE\u30DB\u8CEA\u554F\u30AB\u30FC\u30C9\u306B\u9001\u4FE1 questionID={id} (session={session})",
1232
+ "adapter.errQuestionUserCancelled": "\u30E6\u30FC\u30B6\u30FC\u304C\u30B9\u30DE\u30DB\u3067\u8CEA\u554F\u3092\u30AD\u30E3\u30F3\u30BB\u30EB/\u62D2\u5426\u3057\u307E\u3057\u305F",
1233
+ "adapter.logApprovalRequest": "\u627F\u8A8D\u30EA\u30AF\u30A8\u30B9\u30C8 (tool={tool}) \u2192 \u30B9\u30DE\u30DB\u6A29\u9650\u30AB\u30FC\u30C9\u306B\u9001\u4FE1 permissionID={id}",
1234
+ "adapter.logAgentPresetFailed": "agentPreset \u306E\u89E3\u6C7A\u306B\u5931\u6557\u3057\u307E\u3057\u305F ({preset})\u3002preset \u306A\u3057\u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF: {message}",
1235
+ "adapter.logSessionLiveAdopted": "\u30BB\u30C3\u30B7\u30E7\u30F3 {session} \u306F\u3053\u306E\u30D7\u30ED\u30BB\u30B9\u306E\u5225\u306E\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u304C\u4FDD\u6301\u4E2D\uFF08live\uFF09\u3002\u65E2\u5B58\u306E\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u63A1\u7528\u3057\u3066\u7D99\u7D9A\u3057\u307E\u3059: {message}",
1236
+ "adapter.logDisposeSkipped": "\u63A1\u7528\u3057\u305F\u5916\u90E8 live \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306F dispose \u3092\u5B9F\u884C\u3057\u307E\u305B\u3093\uFF08\u30BB\u30C3\u30B7\u30E7\u30F3 {session} \u306F\u5143\u306E\u4FDD\u6301\u8005\u304C\u7BA1\u7406\uFF09",
1237
+ "adapter.logAgentCreateFailed": "\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306E\u4F5C\u6210/\u518D\u958B\u306B\u5931\u6557\u3057\u307E\u3057\u305F ({session}): {message}",
1238
+ "adapter.errSessionBusyLive": "\u30BB\u30C3\u30B7\u30E7\u30F3 {session} \u306F\u4F7F\u7528\u4E2D\u3067\u3059\uFF08live\uFF09\u3002\u5F8C\u3067\u3082\u3046\u4E00\u5EA6\u304A\u8A66\u3057\u304F\u3060\u3055\u3044",
1239
+ "adapter.errAgentsUnavailable": "agents \u30B5\u30FC\u30D3\u30B9\u304C\u5229\u7528\u3067\u304D\u307E\u305B\u3093",
1240
+ "adapter.logToolReason": "dsh \u304C\u30C4\u30FC\u30EB {tool} \u306E\u5B9F\u884C\u3092\u8981\u6C42\u3057\u3066\u3044\u307E\u3059",
1241
+ "adapter.logGatewayConnected": "\u30ED\u30FC\u30AB\u30EB OpenClaw Gateway \u306B\u63A5\u7D9A\u3057\u307E\u3057\u305F\uFF08{version}\uFF09",
1242
+ "adapter.logGatewayDisconnected": "OpenClaw Gateway \u304B\u3089\u5207\u65AD\u3055\u308C\u307E\u3057\u305F\u3002\u516C\u5F0F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u304C\u518D\u63A5\u7D9A\u3057\u3066\u3044\u307E\u3059\u2026",
1243
+ "adapter.logGatewayConnectFailed": "\u30ED\u30FC\u30AB\u30EB OpenClaw Gateway \u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\uFF08\u521D\u56DE\u306F\u672C\u6A5F\u3067\u30C7\u30D0\u30A4\u30B9\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044: `openclaw devices list` + `openclaw devices approve <requestId>`\uFF09",
1244
+ "adapter.errGatewayNoSessionKey": "Gateway \u304C\u30BB\u30C3\u30B7\u30E7\u30F3 key \u3092\u8FD4\u3057\u307E\u305B\u3093\u3067\u3057\u305F",
1245
+ "adapter.logDeleteSessionFailed": "\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u524A\u9664\u306B\u5931\u6557\u3057\u307E\u3057\u305F ({session}): {message}\uFF08\u524A\u9664\u6E08\u307F\u3068\u3057\u3066\u5FDC\u7B54\uFF09",
1246
+ "adapter.logApprovalReplyFailed": "\u627F\u8A8D\u5FDC\u7B54\u306B\u5931\u6557\u3057\u307E\u3057\u305F ({id}): {message}",
1247
+ "adapter.logPendingApproval": "session.pending: \u672A\u51E6\u7406\u306E\u627F\u8A8D\u3092 {count} \u4EF6\u518D\u9001\u3057\u307E\u3057\u305F (session={session})",
1248
+ "adapter.workspaceDefault": "\u30C7\u30D5\u30A9\u30EB\u30C8",
1249
+ "adapter.cursorSessionTitle": "Cursor \u30BB\u30C3\u30B7\u30E7\u30F3",
1250
+ "adapter.reasonDisconnect": "\u30EA\u30EC\u30FC\u5207\u65AD\u3001\u81EA\u52D5\u62D2\u5426\uFF08fail-closed\uFF09",
1251
+ "adapter.warnInvalidEnv": "\u7121\u52B9\u306A {name} \u3092\u7121\u8996\u3057\u307E\u3059: {raw}\uFF08{list}\uFF09",
1252
+ "adapter.errStartFailed": "\u8D77\u52D5\u306B\u5931\u6557\u3057\u307E\u3057\u305F:",
1253
+ "adapter.msgStarted": "{name} \u30A2\u30C0\u30D7\u30BF\u30FC\u3092\u8D77\u52D5\u3057\u307E\u3057\u305F\uFF08Ctrl+C \u3067\u7D42\u4E86\uFF09",
1254
+ "adapter.warnCliMissing": "\u5B9F\u884C\u30D5\u30A1\u30A4\u30EB\u300C{bin}\u300D\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3059\u308B\uFF08\u4F8B: npm i -g @openai/codex\uFF09\u304B\u3001TUNNELBOX_CODEX_BIN \u3067\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044",
1255
+ "adapter.errCliNotFound": "{name} \u306E\u5B9F\u884C\u30D5\u30A1\u30A4\u30EB\u300C{bin}\u300D\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\uFF1ACodex CLI \u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\uFF08npm i -g @openai/codex\uFF09\u3059\u308B\u304B TUNNELBOX_CODEX_BIN \u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044",
1256
+ "adapter.errSessionNotFound": "\u30BB\u30C3\u30B7\u30E7\u30F3\u304C\u5B58\u5728\u3057\u306A\u3044\u304B\u3001\u3059\u3067\u306B\u524A\u9664\u3055\u308C\u3066\u3044\u307E\u3059",
1257
+ "adapter.checkHeader": "tunnelbox-codex \u74B0\u5883\u30C1\u30A7\u30C3\u30AF",
1258
+ "adapter.checkCliOk": "{name} \u5B9F\u884C\u30D5\u30A1\u30A4\u30EB: {path}",
1259
+ "adapter.checkCliMissing": "{name} \u5B9F\u884C\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\uFF08{bin}\uFF09",
1260
+ "bin.yes": "\u306F\u3044",
1261
+ "bin.no": "\u3044\u3044\u3048",
1262
+ "adapter.errAppServerSpawn": "codex app-server \u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093: {message}\uFF08Codex CLI \u304C `codex app-server` \u306B\u5BFE\u5FDC\u3057\u3066\u3044\u308B\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\uFF09",
1263
+ "adapter.errAppServerExit": "codex app-server \u304C\u7D42\u4E86\u3057\u307E\u3057\u305F\u3002\u4FDD\u7559\u4E2D\u306E\u627F\u8A8D/\u9078\u629E\u306F\u81EA\u52D5\u7684\u306B\u62D2\u5426\u3055\u308C\u307E\u3057\u305F",
1264
+ "adapter.logUnsupportedServerRequest": "\u672A\u5BFE\u5FDC\u306E app-server \u30EA\u30AF\u30A8\u30B9\u30C8: {method}",
1265
+ "adapter.logQuestionNative": "\u9078\u629E\u30EA\u30AF\u30A8\u30B9\u30C8 -> \u30B9\u30DE\u30DB\u9078\u629E\u30AB\u30FC\u30C9 questionID={id} (session={session})",
1266
+ "adapter.logPermissionNative": "\u627F\u8A8D\u30EA\u30AF\u30A8\u30B9\u30C8 -> \u30B9\u30DE\u30DB\u627F\u8A8D\u30AB\u30FC\u30C9 permissionID={id} (session={session})",
1267
+ "adapter.checkAppServerOk": "codex app-server \u5229\u7528\u53EF\u80FD",
1268
+ "adapter.checkAppServerMissing": "\u3053\u306E Codex CLI \u306F `codex app-server` \u306B\u5BFE\u5FDC\u3057\u3066\u3044\u307E\u305B\u3093\uFF08Codex CLI \u3092\u66F4\u65B0\u3057\u3066\u304F\u3060\u3055\u3044\uFF09"
825
1269
  };
826
1270
 
827
1271
  // locales/ko-KR.json
@@ -874,7 +1318,7 @@ var ko_KR_default = {
874
1318
  "install.scanHint": "\uD734\uB300\uD3F0\uC5D0\uC11C tunnelbox \uC571 \u201C\uC2A4\uCE94\uD558\uC5EC \uC5F0\uACB0\u201D\uC744 \uC5F4\uACE0 \uC704 QR \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD558\uC5EC \uC5F0\uACB0\uD558\uC138\uC694:",
875
1319
  "pair.heading": "tunnelbox \uD734\uB300\uD3F0 \uD398\uC5B4\uB9C1",
876
1320
  "pair.howTo": "\uD734\uB300\uD3F0\uC5D0\uC11C tunnelbox \uC571\uC744 \uC5F4\uACE0 \u201C\uC2A4\uCE94\uD558\uC5EC \uC5F0\uACB0\u201D\uB85C \uC704 QR \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD558\uAC70\uB098 \uD398\uC5B4\uB9C1 \uCF54\uB4DC\uB97C \uC9C1\uC811 \uC785\uB825\uD558\uC138\uC694.",
877
- "pair.oneTime": "\uD398\uC5B4\uB9C1 \uCF54\uB4DC\uB294 \uC77C\uD68C\uC6A9\uC774\uBA70 \uC0AC\uC6A9 \uD6C4\uC5D0\uB294 \uB9CC\uB8CC\uB429\uB2C8\uB2E4. \uC0C8 \uCF54\uB4DC\uAC00 \uD544\uC694\uD558\uBA74 \u201C\uD398\uC5B4\uB9C1 \uCF54\uB4DC \uC0C8\uB85C\uACE0\uCE68\u201D\uC744 \uC694\uCCAD\uD558\uC138\uC694.",
1321
+ "pair.oneTime": '\uD398\uC5B4\uB9C1 \uCF54\uB4DC\uB294 1\uD68C\uC6A9\uC774\uBA70 \uC57D 10\uBD84\uAC04 \uC720\uD6A8\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uD558\uAC70\uB098 \uB9CC\uB8CC\uB418\uBA74 \uBB34\uD6A8\uAC00 \uB429\uB2C8\uB2E4. \uC0C8 \uCF54\uB4DC\uAC00 \uD544\uC694\uD558\uBA74 "\uD398\uC5B4\uB9C1 \uCF54\uB4DC \uC0C8\uB85C \uACE0\uCE68"\uC744 \uC694\uCCAD\uD558\uC138\uC694.',
878
1322
  "pair.promptBody": "\uC774 PC\uC758 \uD734\uB300\uD3F0 \uC6D0\uACA9 \uD398\uC5B4\uB9C1 \uC815\uBCF4\uB97C \uBCF4\uC5EC\uC8FC\uC138\uC694: \uD398\uC5B4\uB9C1 \uCF54\uB4DC\uC640 \uC2A4\uCE94\uD560 \uC218 \uC788\uB294 QR \uCF54\uB4DC. QR \uCF54\uB4DC\uB294 \uACE0\uC815\uD3ED \uCF54\uB4DC \uBE14\uB85D\uC5D0 \uB123\uACE0 \uD55C \uAE00\uC790\uB3C4 \uBC14\uAFB8\uC9C0 \uB9D0\uACE0 \uADF8\uB300\uB85C \uD45C\uC2DC\uD574 \uC8FC\uC138\uC694. \uD734\uB300\uD3F0\uC73C\uB85C \uC2A4\uCE94\uD560 \uC218 \uC788\uB3C4\uB85D \uD558\uAE30 \uC704\uD568\uC785\uB2C8\uB2E4.",
879
1323
  "pair.promptDescription": "\uD734\uB300\uD3F0 \uC6D0\uACA9 \uD398\uC5B4\uB9C1\uC758 \uD398\uC5B4\uB9C1 \uCF54\uB4DC\xB7\uC2A4\uCE94\uC6A9 QR \uCF54\uB4DC \uD45C\uC2DC",
880
1324
  "pair.scanIntro": "**\uC2A4\uCE94\uC73C\uB85C \uC5F0\uACB0**: \uD734\uB300\uD3F0\uC5D0\uC11C tunnelbox \uC571 \u201C\uC2A4\uCE94\uD558\uC5EC \uC5F0\uACB0\u201D\uC744 \uC5F4\uACE0 \uC544\uB798 QR \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uC5F0\uACB0\uB429\uB2C8\uB2E4.",
@@ -989,7 +1433,118 @@ var ko_KR_default = {
989
1433
  "hermes.pairTimeout": "\uD398\uC5B4\uB9C1 \uCF54\uB4DC \uC694\uCCAD \uC2DC\uAC04 \uCD08\uACFC(\uB9B4\uB808\uC774 \uBBF8\uC751\uB2F5)",
990
1434
  "hermes.errToolPair": "tunnelbox_pair \uC2E4\uD328: {err}",
991
1435
  "hermes.errToolStatus": "tunnelbox_status \uC2E4\uD328: {err}",
992
- "hermes.cliUsage": "\uC0AC\uC6A9\uBC95: /tunnelbox <pair|status>\n pair \uD734\uB300\uD3F0 \uD398\uC5B4\uB9C1 \uCF54\uB4DC \uC694\uCCAD/\uCD9C\uB825\n status \uB9B4\uB808\uC774/\uBC14\uC778\uB529/\uC5F0\uACB0 \uC0C1\uD0DC \uD45C\uC2DC"
1436
+ "hermes.cliUsage": "\uC0AC\uC6A9\uBC95: /tunnelbox <pair|status>\n pair \uD734\uB300\uD3F0 \uD398\uC5B4\uB9C1 \uCF54\uB4DC \uC694\uCCAD/\uCD9C\uB825\n status \uB9B4\uB808\uC774/\uBC14\uC778\uB529/\uC5F0\uACB0 \uC0C1\uD0DC \uD45C\uC2DC",
1437
+ "qr.validFor": "\uD398\uC5B4\uB9C1 \uCF54\uB4DC\uB294 \uC57D 10\uBD84\uAC04 \uC720\uD6A8\uD569\uB2C8\uB2E4. \uB9CC\uB8CC\uB418\uBA74 \uCEF4\uD4E8\uD130\uC5D0\uC11C \uC0C8\uB85C \uBC1B\uC73C\uC138\uC694.",
1438
+ "pair.toolDesc": "\uC774 \uCEF4\uD4E8\uD130\uC758 \uC2A4\uB9C8\uD2B8\uD3F0 \uD398\uC5B4\uB9C1 \uC815\uBCF4(\uD398\uC5B4\uB9C1 \uCF54\uB4DC\uC640 \uC2A4\uCE94 \uAC00\uB2A5\uD55C QR \uCF54\uB4DC)\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4. \uD398\uC5B4\uB9C1, QR \uCF54\uB4DC \uC2A4\uCE94, \uC2A4\uB9C8\uD2B8\uD3F0\uC73C\uB85C \uC774 \uCEF4\uD4E8\uD130 \uC81C\uC5B4\uC5D0 \uB300\uD574 \uBB3C\uC5B4\uBCFC \uB54C \uD638\uCD9C\uD558\uC138\uC694.",
1439
+ "pair.toolRefreshDesc": "\uB9B4\uB808\uC774\uC5D0 \uC0C8 \uD398\uC5B4\uB9C1 \uCF54\uB4DC\uB97C \uC694\uCCAD\uD560\uC9C0 \uC5EC\uBD80",
1440
+ "state.errSaveState": "\uC0C1\uD0DC \uC800\uC7A5 \uC2E4\uD328",
1441
+ "adapter.logConnected": "\uB9B4\uB808\uC774\uC5D0 \uC5F0\uACB0\uB428 {url}",
1442
+ "adapter.logDisconnected": "\uB9B4\uB808\uC774\uC640 \uC5F0\uACB0\uC774 \uB04A\uC5B4\uC84C\uC2B5\uB2C8\uB2E4. \uC790\uB3D9\uC73C\uB85C \uC7AC\uC5F0\uACB0 \uC911\u2026",
1443
+ "adapter.logPairCode": "\uD398\uC5B4\uB9C1 \uCF54\uB4DC \uC0DD\uC131\uB428: {code}",
1444
+ "adapter.logClaimed": "\uC2A4\uB9C8\uD2B8\uD3F0 \uACC4\uC815\uC5D0 \uC5F0\uACB0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC774\uC81C\uBD80\uD130 \uC2A4\uB9C8\uD2B8\uD3F0\uC758 '\uB0B4 \uCEF4\uD4E8\uD130'\uC5D0\uC11C \uC9C1\uC811 \uC5F0\uACB0\uD569\uB2C8\uB2E4",
1445
+ "adapter.logResetIdentity": "\uACC4\uC815\uC5D0\uC11C \uD574\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4. ID\uB97C \uC7AC\uC124\uC815\uD558\uACE0 \uC0C8 \uD398\uC5B4\uB9C1 \uCF54\uB4DC\uB97C \uC0DD\uC131 \uC911\u2026",
1446
+ "adapter.logUnhandledType": "\uCC98\uB9AC\uB418\uC9C0 \uC54A\uC740 \uBA54\uC2DC\uC9C0 \uC720\uD615: {type}",
1447
+ "adapter.errNoRelay": "\uB9B4\uB808\uC774 URL\uC774 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uBE4C\uB4DC \uC2DC --env\uB85C \uAE30\uBCF8\uAC12\uC744 \uC8FC\uC785\uD558\uAC70\uB098 \uB7F0\uD0C0\uC784\uC5D0 TUNNELBOX_RELAY_URL\uB85C \uC7AC\uC815\uC758\uD558\uC138\uC694",
1448
+ "adapter.errBusy": "\uC774 \uC138\uC158\uC774 \uC544\uC9C1 \uC2E4\uD589 \uC911\uC785\uB2C8\uB2E4. \uC644\uB8CC\uB97C \uAE30\uB2E4\uB9AC\uAC70\uB098 \uBA3C\uC800 \uC911\uC9C0\uD558\uC138\uC694",
1449
+ "adapter.errBadWorkspaceEmpty": "\uC791\uC5C5 \uACF5\uAC04 \uACBD\uB85C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4",
1450
+ "adapter.errBadWorkspaceNotDir": "\uB514\uB809\uD130\uB9AC\uAC00 \uC5C6\uAC70\uB098 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",
1451
+ "adapter.errWorkspaceMissing": "\uC791\uC5C5 \uACF5\uAC04\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: {dir}",
1452
+ "adapter.cmdNew": "\uC0C8 \uC138\uC158",
1453
+ "adapter.cmdHelp": "\uB3C4\uC6C0\uB9D0 \uD45C\uC2DC",
1454
+ "adapter.helpText": "\uC9C0\uC6D0\uB418\uB294 \uBA85\uB839:\n- /new \uC0C8 \uC138\uC158\n- /help \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC",
1455
+ "adapter.newSessionTitle": "\uC0C8 \uC138\uC158",
1456
+ "install.langHelpTitle": "install-local \uC9C0\uC6D0 \uC5B8\uC5B4(--lang <tag>):",
1457
+ "install.langHelpExample": "\uC608: npm run install-local -- --lang de-DE",
1458
+ "install.unknownLang": '\uC54C \uC218 \uC5C6\uB294 \uC5B8\uC5B4 "{raw}"\uC774\uBBC0\uB85C en-US\uB85C \uB300\uCCB4\uD569\uB2C8\uB2E4. \uC9C0\uC6D0: {list}',
1459
+ "hermes.errAskRequired": "question\uC740 \uD544\uC218\uC785\uB2C8\uB2E4",
1460
+ "hermes.msgPhoneUnavailable": "\uC2A4\uB9C8\uD2B8\uD3F0\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uAC70\uB098 \uC751\uB2F5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uB0B4\uC7A5 clarify\uB85C \uB85C\uCEEC\uC5D0\uC11C \uC9C8\uBB38\uD558\uAC70\uB098 \uC9C1\uC811 \uD310\uB2E8\uD558\uC5EC \uACC4\uC18D\uD558\uC138\uC694.",
1461
+ "hermes.errClarifyUnavailable": "clarify \uC9C0\uC6D0\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",
1462
+ "hermes.errAskFailed": "tunnelbox_ask \uC2E4\uD328: {err}",
1463
+ "hermes.errClarifyFailed": "clarify \uC2E4\uD328: {err}",
1464
+ "bin.denied": "\uC2A4\uB9C8\uD2B8\uD3F0\uC5D0\uC11C \uAC70\uBD80\uB428",
1465
+ "bin.timeout": "\uC2B9\uC778 \uC2DC\uAC04 \uCD08\uACFC(fail-closed)",
1466
+ "bin.reqRun": "Claude Code\uAC00 {tool} \uC2E4\uD589\uC744 \uC694\uCCAD\uD569\uB2C8\uB2E4",
1467
+ "bin.pairTitle": "tunnelbox \uC2A4\uB9C8\uD2B8\uD3F0 \uD398\uC5B4\uB9C1",
1468
+ "bin.pairCodeLine": " \uD398\uC5B4\uB9C1 \uCF54\uB4DC: {code}",
1469
+ "bin.pairHint": "tunnelbox \uC571\uC744 \uC5F4\uACE0 '\uC2A4\uCE94\uD558\uC5EC \uD398\uC5B4\uB9C1'\uC73C\uB85C QR \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD558\uAC70\uB098 \uD398\uC5B4\uB9C1 \uCF54\uB4DC\uB97C \uC9C1\uC811 \uC785\uB825\uD558\uC138\uC694(1\uD68C\uC6A9).",
1470
+ "bin.pairWritten": " \uD398\uC5B4\uB9C1 \uC815\uBCF4 \uC800\uC7A5\uB428: {path}",
1471
+ "bin.pairRequestFailed": "\uB9B4\uB808\uC774\uC5D0 \uD398\uC5B4\uB9C1 \uCF54\uB4DC \uC694\uCCAD \uC2E4\uD328.",
1472
+ "bin.alreadyClaimed": "\uC774 \uCEF4\uD4E8\uD130\uB294 \uC774\uBBF8 \uC2A4\uB9C8\uD2B8\uD3F0 \uACC4\uC815\uC5D0 \uC5F0\uACB0\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4. \uC2A4\uB9C8\uD2B8\uD3F0\uC758 '\uB0B4 \uCEF4\uD4E8\uD130'\uC5D0\uC11C \uC9C1\uC811 \uC5F0\uACB0\uD558\uC138\uC694. \uB2E4\uC2DC \uD398\uC5B4\uB9C1\uD558\uB824\uBA74 \uBA3C\uC800 \uC2A4\uB9C8\uD2B8\uD3F0\uC5D0\uC11C \uD574\uC81C\uD558\uC138\uC694.",
1473
+ "bin.noRelay": "\uB9B4\uB808\uC774 URL\uC774 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uD658\uACBD \uBCC0\uC218 TUNNELBOX_RELAY_URL\uC744 \uC124\uC815\uD55C \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.",
1474
+ "bin.connectFailed": "\uB9B4\uB808\uC774\uC5D0 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: {relay}\nTUNNELBOX_RELAY_URL\uC744 \uC124\uC815\uD558\uAC70\uB098 official-plugin \uC0C1\uD0DC \uD30C\uC77C\uC5D0\uC11C \uAD6C\uC131\uD558\uC138\uC694.",
1475
+ "bin.statusRelay": "\uB9B4\uB808\uC774: {value}",
1476
+ "bin.statusAgent": "\uC5D0\uC774\uC804\uD2B8 ID: {value}",
1477
+ "bin.statusClaimed": "\uC2A4\uB9C8\uD2B8\uD3F0 \uC5F0\uACB0: {value}",
1478
+ "bin.statusStateFile": "\uC0C1\uD0DC \uD30C\uC77C: {value}",
1479
+ "bin.statusLatest": "\uCD5C\uC2E0 \uD398\uC5B4\uB9C1 \uC815\uBCF4:",
1480
+ "bin.usage": "\uC0AC\uC6A9\uBC95: tunnelbox <pair|status|ask>",
1481
+ "bin.usagePair": " pair \uC2A4\uB9C8\uD2B8\uD3F0 \uD398\uC5B4\uB9C1 \uCF54\uB4DC \uC694\uCCAD \uBC0F \uCD9C\uB825",
1482
+ "bin.usageStatus": " status \uB9B4\uB808\uC774/\uC5F0\uACB0 \uC0C1\uD0DC \uD45C\uC2DC",
1483
+ "bin.usageAsk": " ask \uB3C4\uAD6C \uC2B9\uC778\uC744 \uC2A4\uB9C8\uD2B8\uD3F0\uC73C\uB85C \uC804\uB2EC",
1484
+ "adapter.logMsgUncaught": "\uBA54\uC2DC\uC9C0 \uCC98\uB9AC \uC911 \uCC98\uB9AC\uB418\uC9C0 \uC54A\uC740 \uC608\uC678: {message}",
1485
+ "adapter.logHandleFailed": "{type} \uCC98\uB9AC \uC2E4\uD328: {message}",
1486
+ "adapter.logPromptFailed": "session.prompt \uC2E4\uD328: {message}",
1487
+ "adapter.logAbortSent": "\uC911\uB2E8 \uC804\uC1A1\uB428 (session={session})",
1488
+ "adapter.errUserDenied": "\uC0AC\uC6A9\uC790\uAC00 \uAC70\uBD80\uD568",
1489
+ "adapter.logPendingResent": "session.pending: \uBCF4\uB958 \uC911\uC778 \uC694\uCCAD {count}\uAC74 \uC7AC\uC804\uC1A1",
1490
+ "adapter.logWorkspaceSwitched": "\uC791\uC5C5 \uACF5\uAC04 \uC804\uD658: {path}",
1491
+ "adapter.logNewSession": "\uC0C8 \uC138\uC158 \uC800\uC7A5\uB428 codexId={codexId} (alias={session})",
1492
+ "adapter.logSessionError": "\uD134 \uC624\uB958 (session={session}): {message}",
1493
+ "adapter.logDshSent": "dsh\uB85C \uC804\uC1A1\uB428 (session={session})",
1494
+ "adapter.logReadHistoryFailed": "\uC138\uC158 \uAE30\uB85D \uC77D\uAE30 \uC2E4\uD328({session}): {message}",
1495
+ "adapter.logAnswererInitFailed": "\uC751\uB2F5\uC790 \uCD08\uAE30\uD654 \uC2E4\uD328: {message}",
1496
+ "adapter.logRemoteMode": "\uC591\uB2E8 \uB3D9\uC2DC \uD45C\uC2DC \uBAA8\uB4DC: \uC120\uD0DD/\uC2B9\uC778\uC740 typert \uB2E4\uC911 \uD074\uB77C\uC774\uC5B8\uD2B8 \uBE0C\uB85C\uB4DC\uCE90\uC2A4\uD2B8\uB97C \uC0AC\uC6A9\uD558\uBA70 \uC2A4\uB9C8\uD2B8\uD3F0\uACFC dsh web\uC774 \uAC19\uC740 \uD654\uBA74\uC744 \uACF5\uC720\uD558\uACE0 \uBA3C\uC800 \uB2F5\uD55C \uCABD\uC774 \uC801\uC6A9\uB429\uB2C8\uB2E4",
1497
+ "adapter.logRemoteProbeFailed": "typert \uC6D0\uACA9 \uC774\uBCA4\uD2B8 \uC18C\uC2A4 \uD0D0\uC0C9 \uC2E4\uD328. \uB85C\uCEEC \uC751\uB2F5 \uBAA8\uB4DC\uB85C \uB300\uCCB4\uD569\uB2C8\uB2E4: {message}",
1498
+ "adapter.logLocalMode": "\uB85C\uCEEC \uC751\uB2F5 \uBAA8\uB4DC: \uC120\uD0DD/\uC2B9\uC778\uC740 \uC2A4\uB9C8\uD2B8\uD3F0\uC774 \uC751\uB2F5(headless, dsh web \uBE0C\uB85C\uB4DC\uCE90\uC2A4\uD2B8 \uC5C6\uC74C)",
1499
+ "adapter.logRemoteStreamInterrupted": "remote events \uC2A4\uD2B8\uB9BC \uC911\uB2E8: {message}",
1500
+ "adapter.logResultRejected": "$events/result \uC218\uB77D\uB418\uC9C0 \uC54A\uC74C({eventId}): {message}",
1501
+ "adapter.logResultBackfillFailed": "$events/result \uC7AC\uAE30\uC785 \uC2E4\uD328({eventId}): {message}",
1502
+ "adapter.logRemoteQuestion": "remote \uC9C8\uBB38 \uBE0C\uB85C\uB4DC\uCE90\uC2A4\uD2B8 \u2192 \uC2A4\uB9C8\uD2B8\uD3F0 \uC9C8\uBB38 \uCE74\uB4DC questionID={id} (session={session})",
1503
+ "adapter.errRemoteReadyFrame": "remote events \uCCAB \uD504\uB808\uC784 \uC774\uC0C1",
1504
+ "adapter.logRemoteApproval": "remote \uC2B9\uC778 \uBE0C\uB85C\uB4DC\uCE90\uC2A4\uD2B8 \u2192 \uC2A4\uB9C8\uD2B8\uD3F0 \uAD8C\uD55C \uCE74\uB4DC permissionID={id} (session={session})",
1505
+ "adapter.logUserQuestionRoute": "user-questions \uC120\uD0DD \u2192 session={session}\uC73C\uB85C \uB77C\uC6B0\uD305",
1506
+ "adapter.errDshQuestionEmpty": "dsh \uC9C8\uBB38 \uB0B4\uC6A9\uC774 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4",
1507
+ "adapter.errQuestionTimeout": "\uC9C8\uBB38 \uC2DC\uAC04 \uCD08\uACFC({seconds}s), \uCDE8\uC18C\uB428",
1508
+ "adapter.errQuestionCancelledAbort": "\uC9C8\uBB38 \uCDE8\uC18C\uB428(\uC5D0\uC774\uC804\uD2B8 \uC911\uB2E8)",
1509
+ "adapter.errQuestionCancelledRelay": "\uB9B4\uB808\uC774\uC5D0 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC5B4 \uC9C8\uBB38\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4",
1510
+ "adapter.logQuestionToPhone": "user-questions \uC120\uD0DD \u2192 \uC2A4\uB9C8\uD2B8\uD3F0 \uC9C8\uBB38 \uCE74\uB4DC\uB85C \uC804\uC1A1 questionID={id} (session={session})",
1511
+ "adapter.errQuestionUserCancelled": "\uC0AC\uC6A9\uC790\uAC00 \uC2A4\uB9C8\uD2B8\uD3F0\uC5D0\uC11C \uC9C8\uBB38\uC744 \uCDE8\uC18C/\uAC70\uBD80\uD588\uC2B5\uB2C8\uB2E4",
1512
+ "adapter.logApprovalRequest": "\uC2B9\uC778 \uC694\uCCAD(tool={tool}) \u2192 \uC2A4\uB9C8\uD2B8\uD3F0 \uAD8C\uD55C \uCE74\uB4DC\uB85C \uC804\uC1A1 permissionID={id}",
1513
+ "adapter.logAgentPresetFailed": "agentPreset \uD574\uC11D \uC2E4\uD328({preset}), preset \uC5C6\uC774 \uB300\uCCB4: {message}",
1514
+ "adapter.logSessionLiveAdopted": "\uC138\uC158 {session}\uC740 \uC774 \uD504\uB85C\uC138\uC2A4\uC758 \uB2E4\uB978 \uC5D0\uC774\uC804\uD2B8\uAC00 \uBCF4\uC720 \uC911(live)\uC785\uB2C8\uB2E4. \uAE30\uC874 \uC5D0\uC774\uC804\uD2B8\uB97C \uCC44\uD0DD\uD558\uC5EC \uACC4\uC18D\uD569\uB2C8\uB2E4: {message}",
1515
+ "adapter.logDisposeSkipped": "\uCC44\uD0DD\uD55C \uC678\uBD80 live \uC5D0\uC774\uC804\uD2B8\uB294 dispose\uB97C \uC2E4\uD589\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uC138\uC158 {session}\uC740 \uC6D0\uB798 \uBCF4\uC720\uC790\uAC00 \uAD00\uB9AC)",
1516
+ "adapter.logAgentCreateFailed": "\uC5D0\uC774\uC804\uD2B8 \uC0DD\uC131/\uBCF5\uC6D0 \uC2E4\uD328({session}): {message}",
1517
+ "adapter.errSessionBusyLive": "\uC138\uC158 {session}\uC774 \uC0AC\uC6A9 \uC911(live)\uC785\uB2C8\uB2E4. \uB098\uC911\uC5D0 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694",
1518
+ "adapter.errAgentsUnavailable": "agents \uC11C\uBE44\uC2A4\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",
1519
+ "adapter.logToolReason": "dsh\uAC00 \uB3C4\uAD6C {tool} \uC2E4\uD589\uC744 \uC694\uCCAD\uD569\uB2C8\uB2E4",
1520
+ "adapter.logGatewayConnected": "\uB85C\uCEEC OpenClaw Gateway\uC5D0 \uC5F0\uACB0\uB428({version})",
1521
+ "adapter.logGatewayDisconnected": "OpenClaw Gateway\uC640 \uC5F0\uACB0\uC774 \uB04A\uC5B4\uC84C\uC2B5\uB2C8\uB2E4. \uACF5\uC2DD \uD074\uB77C\uC774\uC5B8\uD2B8\uAC00 \uC7AC\uC5F0\uACB0 \uC911\u2026",
1522
+ "adapter.logGatewayConnectFailed": "\uB85C\uCEEC OpenClaw Gateway\uC5D0 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(\uCD5C\uCD08\uC5D0\uB294 \uB85C\uCEEC\uC5D0\uC11C \uC7A5\uCE58\uB97C \uC2B9\uC778\uD558\uC138\uC694: `openclaw devices list` + `openclaw devices approve <requestId>`)",
1523
+ "adapter.errGatewayNoSessionKey": "Gateway\uAC00 \uC138\uC158 key\uB97C \uBC18\uD658\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4",
1524
+ "adapter.logDeleteSessionFailed": "\uC138\uC158 \uC0AD\uC81C \uC2E4\uD328({session}): {message}(\uC0AD\uC81C\uB428\uC73C\uB85C \uC751\uB2F5)",
1525
+ "adapter.logApprovalReplyFailed": "\uC2B9\uC778 \uC751\uB2F5 \uC2E4\uD328({id}): {message}",
1526
+ "adapter.logPendingApproval": "session.pending: \uBCF4\uB958 \uC911\uC778 \uC2B9\uC778 {count}\uAC74 \uC7AC\uC804\uC1A1 (session={session})",
1527
+ "adapter.workspaceDefault": "\uAE30\uBCF8",
1528
+ "adapter.cursorSessionTitle": "Cursor \uC138\uC158",
1529
+ "adapter.reasonDisconnect": "\uB9B4\uB808\uC774 \uC5F0\uACB0 \uB04A\uAE40, \uC790\uB3D9 \uAC70\uBD80(fail-closed)",
1530
+ "adapter.warnInvalidEnv": "\uC798\uBABB\uB41C {name} \uBB34\uC2DC: {raw}({list})",
1531
+ "adapter.errStartFailed": "\uC2DC\uC791 \uC2E4\uD328:",
1532
+ "adapter.msgStarted": "{name} \uC5B4\uB311\uD130 \uC2DC\uC791\uB428(Ctrl+C\uB85C \uC885\uB8CC)",
1533
+ "adapter.warnCliMissing": "\uC2E4\uD589 \uD30C\uC77C '{bin}'\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uC124\uCE58\uD558\uAC70\uB098(\uC608: npm i -g @openai/codex) TUNNELBOX_CODEX_BIN\uC73C\uB85C \uACBD\uB85C\uB97C \uC9C0\uC815\uD558\uC138\uC694",
1534
+ "adapter.errCliNotFound": "{name} \uC2E4\uD589 \uD30C\uC77C '{bin}'\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: Codex CLI\uB97C \uC124\uCE58(npm i -g @openai/codex)\uD558\uAC70\uB098 TUNNELBOX_CODEX_BIN\uC744 \uC124\uC815\uD558\uC138\uC694",
1535
+ "adapter.errSessionNotFound": "\uC138\uC158\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uAC70\uB098 \uC774\uBBF8 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4",
1536
+ "adapter.checkHeader": "tunnelbox-codex \uD658\uACBD \uC810\uAC80",
1537
+ "adapter.checkCliOk": "{name} \uC2E4\uD589 \uD30C\uC77C: {path}",
1538
+ "adapter.checkCliMissing": "{name} \uC2E4\uD589 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4({bin})",
1539
+ "bin.yes": "\uC608",
1540
+ "bin.no": "\uC544\uB2C8\uC694",
1541
+ "adapter.errAppServerSpawn": "codex app-server \uB97C \uC2DC\uC791\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: {message} (Codex CLI \uAC00 `codex app-server` \uB97C \uC9C0\uC6D0\uD558\uB294\uC9C0 \uD655\uC778\uD558\uC138\uC694)",
1542
+ "adapter.errAppServerExit": "codex app-server \uAC00 \uC885\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uB300\uAE30 \uC911\uC778 \uC2B9\uC778/\uC120\uD0DD\uC740 \uC790\uB3D9\uC73C\uB85C \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4",
1543
+ "adapter.logUnsupportedServerRequest": "\uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 app-server \uC694\uCCAD: {method}",
1544
+ "adapter.logQuestionNative": "\uC120\uD0DD \uC694\uCCAD -> \uD734\uB300\uD3F0 \uC120\uD0DD \uCE74\uB4DC questionID={id} (session={session})",
1545
+ "adapter.logPermissionNative": "\uC2B9\uC778 \uC694\uCCAD -> \uD734\uB300\uD3F0 \uC2B9\uC778 \uCE74\uB4DC permissionID={id} (session={session})",
1546
+ "adapter.checkAppServerOk": "codex app-server \uC0AC\uC6A9 \uAC00\uB2A5",
1547
+ "adapter.checkAppServerMissing": "\uC774 Codex CLI \uB294 `codex app-server` \uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 (Codex CLI \uB97C \uC5C5\uADF8\uB808\uC774\uB4DC\uD558\uC138\uC694)"
993
1548
  };
994
1549
 
995
1550
  // locales/fr-FR.json
@@ -1042,7 +1597,7 @@ var fr_FR_default = {
1042
1597
  "install.scanHint": "Ouvrez tunnelbox sur votre t\xE9l\xE9phone, touchez \u201CScanner pour appairer\u201D, puis scannez le QR ci-dessus pour connecter :",
1043
1598
  "pair.heading": "Appairage t\xE9l\xE9phone tunnelbox",
1044
1599
  "pair.howTo": "Ouvrez l'application tunnelbox sur votre t\xE9l\xE9phone, scannez le QR ci-dessus avec \u201CScanner pour appairer\u201D, ou saisissez le code d'appairage manuellement.",
1045
- "pair.oneTime": "Le code d'appairage est \xE0 usage unique et expire apr\xE8s utilisation ; demandez \xE0 \u201Craffra\xEEchir le code d'appairage\u201D pour en obtenir un nouveau.",
1600
+ "pair.oneTime": "Le code d'appairage est \xE0 usage unique et valable environ 10 minutes ; il devient inutilisable une fois utilis\xE9 ou expir\xE9. Demandez \xAB rafra\xEEchir le code d'appairage \xBB pour en obtenir un nouveau.",
1046
1601
  "pair.promptBody": "Veuillez afficher les informations d'appairage t\xE9l\xE9phone de cet ordinateur : le code d'appairage et un QR code scannable. Gardez le QR code dans un bloc de code \xE0 largeur fixe et reproduisez-le caract\xE8re par caract\xE8re pour que mon t\xE9l\xE9phone puisse le scanner.",
1047
1602
  "pair.promptDescription": "Afficher le code d'appairage et le QR code scannable",
1048
1603
  "pair.scanIntro": "**Appairer par scan** : ouvrez l'application tunnelbox sur votre t\xE9l\xE9phone, touchez \u201CScanner pour appairer\u201D, puis scannez le QR ci-dessous pour vous connecter automatiquement.",
@@ -1157,7 +1712,118 @@ var fr_FR_default = {
1157
1712
  "hermes.pairTimeout": "D\xE9lai d\xE9pass\xE9 pour le code d'appairage (relais sans r\xE9ponse)",
1158
1713
  "hermes.errToolPair": "\xE9chec de tunnelbox_pair : {err}",
1159
1714
  "hermes.errToolStatus": "\xE9chec de tunnelbox_status : {err}",
1160
- "hermes.cliUsage": "Utilisation : /tunnelbox <pair|status>\n pair demander et afficher un code d'appairage\n status afficher l'\xE9tat relais/liaison/connexion"
1715
+ "hermes.cliUsage": "Utilisation : /tunnelbox <pair|status>\n pair demander et afficher un code d'appairage\n status afficher l'\xE9tat relais/liaison/connexion",
1716
+ "qr.validFor": "Le code d'appairage est valable environ 10 minutes ; s'il expire, r\xE9cup\xE9rez-en un nouveau sur votre ordinateur.",
1717
+ "pair.toolDesc": "Affiche les informations d'appairage t\xE9l\xE9phone de cet ordinateur (code d'appairage et QR code scannable). \xC0 appeler lorsque l'utilisateur parle d'appairage, de scan de QR code ou de contr\xF4le de cet ordinateur depuis son t\xE9l\xE9phone.",
1718
+ "pair.toolRefreshDesc": "Demander ou non un nouveau code d'appairage au relais",
1719
+ "state.errSaveState": "\xC9chec de l'enregistrement de l'\xE9tat",
1720
+ "adapter.logConnected": "Connect\xE9 au relais {url}",
1721
+ "adapter.logDisconnected": "D\xE9connect\xE9 du relais, reconnexion automatique\u2026",
1722
+ "adapter.logPairCode": "Code d'appairage g\xE9n\xE9r\xE9 : {code}",
1723
+ "adapter.logClaimed": "Associ\xE9 \xE0 votre compte t\xE9l\xE9phone. D\xE9sormais, le t\xE9l\xE9phone se connecte directement depuis \xAB Mes ordinateurs \xBB",
1724
+ "adapter.logResetIdentity": "Dissoci\xE9 du compte ; r\xE9initialisation de l'identit\xE9 et g\xE9n\xE9ration d'un nouveau code d'appairage\u2026",
1725
+ "adapter.logUnhandledType": "Type de message non g\xE9r\xE9 : {type}",
1726
+ "adapter.errNoRelay": "Aucune URL de relais configur\xE9e : compilez avec --env pour injecter une valeur par d\xE9faut, ou remplacez-la \xE0 l'ex\xE9cution avec TUNNELBOX_RELAY_URL",
1727
+ "adapter.errBusy": "Cette session est toujours en cours ; attendez la fin ou arr\xEAtez-la d'abord",
1728
+ "adapter.errBadWorkspaceEmpty": "Chemin d'espace de travail manquant",
1729
+ "adapter.errBadWorkspaceNotDir": "Le r\xE9pertoire n'existe pas ou est inutilisable",
1730
+ "adapter.errWorkspaceMissing": "L'espace de travail n'existe pas : {dir}",
1731
+ "adapter.cmdNew": "Nouvelle session",
1732
+ "adapter.cmdHelp": "Afficher l'aide",
1733
+ "adapter.helpText": "Commandes prises en charge :\n- /new nouvelle session\n- /help afficher l'aide",
1734
+ "adapter.newSessionTitle": "Nouvelle session",
1735
+ "install.langHelpTitle": "Langues prises en charge par install-local (--lang <tag>) :",
1736
+ "install.langHelpExample": "Exemple : npm run install-local -- --lang de-DE",
1737
+ "install.unknownLang": "Langue inconnue \xAB {raw} \xBB, retour \xE0 en-US. Prises en charge : {list}",
1738
+ "hermes.errAskRequired": "question est obligatoire",
1739
+ "hermes.msgPhoneUnavailable": "T\xE9l\xE9phone indisponible ou sans r\xE9ponse : utilisez le clarify int\xE9gr\xE9 pour poser la question localement, ou d\xE9cidez par vous-m\xEAme.",
1740
+ "hermes.errClarifyUnavailable": "Prise en charge de clarify indisponible",
1741
+ "hermes.errAskFailed": "\xC9chec de tunnelbox_ask : {err}",
1742
+ "hermes.errClarifyFailed": "\xC9chec de clarify : {err}",
1743
+ "bin.denied": "Refus\xE9 depuis votre t\xE9l\xE9phone",
1744
+ "bin.timeout": "D\xE9lai d'approbation d\xE9pass\xE9 (fail-closed)",
1745
+ "bin.reqRun": "Claude Code demande d'ex\xE9cuter {tool}",
1746
+ "bin.pairTitle": "Appairage t\xE9l\xE9phone tunnelbox",
1747
+ "bin.pairCodeLine": " Code d'appairage : {code}",
1748
+ "bin.pairHint": "Ouvrez l'app tunnelbox, touchez \xAB Scanner pour appairer \xBB et scannez le QR code, ou saisissez le code d'appairage manuellement (usage unique).",
1749
+ "bin.pairWritten": " Infos d'appairage \xE9crites dans : {path}",
1750
+ "bin.pairRequestFailed": "\xC9chec de la demande de code d'appairage au relais.",
1751
+ "bin.alreadyClaimed": "Cet ordinateur est d\xE9j\xE0 associ\xE9 \xE0 un compte t\xE9l\xE9phone ; connectez-vous directement depuis \xAB Mes ordinateurs \xBB. Pour r\xE9appairer, dissociez-le d'abord sur votre t\xE9l\xE9phone.",
1752
+ "bin.noRelay": "Aucune URL de relais configur\xE9e : d\xE9finissez TUNNELBOX_RELAY_URL puis r\xE9essayez.",
1753
+ "bin.connectFailed": "Impossible de se connecter au relais : {relay}\nD\xE9finissez TUNNELBOX_RELAY_URL ou configurez-le dans le fichier d'\xE9tat official-plugin.",
1754
+ "bin.statusRelay": "Relais : {value}",
1755
+ "bin.statusAgent": "ID de l'agent : {value}",
1756
+ "bin.statusClaimed": "T\xE9l\xE9phone associ\xE9 : {value}",
1757
+ "bin.statusStateFile": "Fichier d'\xE9tat : {value}",
1758
+ "bin.statusLatest": "Derni\xE8res infos d'appairage :",
1759
+ "bin.usage": "Utilisation : tunnelbox <pair|status|ask>",
1760
+ "bin.usagePair": " pair demander et afficher un code d'appairage t\xE9l\xE9phone",
1761
+ "bin.usageStatus": " status afficher l'\xE9tat du relais/de l'association",
1762
+ "bin.usageAsk": " ask transf\xE9rer une approbation d'outil au t\xE9l\xE9phone",
1763
+ "adapter.logMsgUncaught": "Exception non intercept\xE9e lors du traitement du message : {message}",
1764
+ "adapter.logHandleFailed": "\xC9chec du traitement de {type} : {message}",
1765
+ "adapter.logPromptFailed": "\xC9chec de session.prompt : {message}",
1766
+ "adapter.logAbortSent": "Interruption envoy\xE9e (session={session})",
1767
+ "adapter.errUserDenied": "Refus\xE9 par l'utilisateur",
1768
+ "adapter.logPendingResent": "session.pending : {count} demande(s) en attente renvoy\xE9e(s)",
1769
+ "adapter.logWorkspaceSwitched": "Espace de travail chang\xE9 : {path}",
1770
+ "adapter.logNewSession": "Nouvelle session enregistr\xE9e codexId={codexId} (alias={session})",
1771
+ "adapter.logSessionError": "Erreur de tour (session={session}) : {message}",
1772
+ "adapter.logDshSent": "Envoy\xE9 \xE0 dsh (session={session})",
1773
+ "adapter.logReadHistoryFailed": "\xC9chec de lecture de l'historique de session ({session}) : {message}",
1774
+ "adapter.logAnswererInitFailed": "\xC9chec d'initialisation du r\xE9pondeur : {message}",
1775
+ "adapter.logRemoteMode": "Mode double affichage : les s\xE9lections/approbations passent par la diffusion multi-clients typert ; t\xE9l\xE9phone et dsh web partagent la vue, la premi\xE8re r\xE9ponse l'emporte",
1776
+ "adapter.logRemoteProbeFailed": "\xC9chec de d\xE9tection de la source d'\xE9v\xE9nements distante typert ; retour au mode de r\xE9ponse local : {message}",
1777
+ "adapter.logLocalMode": "Mode de r\xE9ponse local : s\xE9lections/approbations trait\xE9es par le t\xE9l\xE9phone (headless, sans diffusion dsh web)",
1778
+ "adapter.logRemoteStreamInterrupted": "Flux remote events interrompu : {message}",
1779
+ "adapter.logResultRejected": "$events/result non accept\xE9 ({eventId}) : {message}",
1780
+ "adapter.logResultBackfillFailed": "\xC9chec du renvoi de $events/result ({eventId}) : {message}",
1781
+ "adapter.logRemoteQuestion": "Diffusion de question remote \u2192 carte de question t\xE9l\xE9phone questionID={id} (session={session})",
1782
+ "adapter.errRemoteReadyFrame": "Premi\xE8re trame remote events inattendue",
1783
+ "adapter.logRemoteApproval": "Diffusion d'approbation remote \u2192 carte d'autorisation t\xE9l\xE9phone permissionID={id} (session={session})",
1784
+ "adapter.logUserQuestionRoute": "S\xE9lection user-questions \u2192 rout\xE9e vers session={session}",
1785
+ "adapter.errDshQuestionEmpty": "Le contenu de la question dsh est vide",
1786
+ "adapter.errQuestionTimeout": "D\xE9lai de question d\xE9pass\xE9 ({seconds}s), annul\xE9e",
1787
+ "adapter.errQuestionCancelledAbort": "Question annul\xE9e (agent interrompu)",
1788
+ "adapter.errQuestionCancelledRelay": "Relais injoignable, question annul\xE9e",
1789
+ "adapter.logQuestionToPhone": "S\xE9lection user-questions \u2192 envoy\xE9e \xE0 la carte de question du t\xE9l\xE9phone questionID={id} (session={session})",
1790
+ "adapter.errQuestionUserCancelled": "L'utilisateur a annul\xE9/refus\xE9 la question sur le t\xE9l\xE9phone",
1791
+ "adapter.logApprovalRequest": "Demande d'approbation (tool={tool}) \u2192 envoy\xE9e \xE0 la carte d'autorisation du t\xE9l\xE9phone permissionID={id}",
1792
+ "adapter.logAgentPresetFailed": "\xC9chec de r\xE9solution d'agentPreset ({preset}) ; retour sans preset : {message}",
1793
+ "adapter.logSessionLiveAdopted": "La session {session} est d\xE9j\xE0 d\xE9tenue par un autre agent de ce processus (live) ; adoption de l'agent existant pour continuer : {message}",
1794
+ "adapter.logDisposeSkipped": "L'agent live externe adopt\xE9 n'ex\xE9cute pas dispose (la session {session} est g\xE9r\xE9e par son d\xE9tenteur d'origine)",
1795
+ "adapter.logAgentCreateFailed": "\xC9chec de cr\xE9ation/reprise de l'agent ({session}) : {message}",
1796
+ "adapter.errSessionBusyLive": "La session {session} est occup\xE9e (live) ; r\xE9essayez plus tard",
1797
+ "adapter.errAgentsUnavailable": "Service agents indisponible",
1798
+ "adapter.logToolReason": "dsh demande d'ex\xE9cuter l'outil {tool}",
1799
+ "adapter.logGatewayConnected": "Connect\xE9 au Gateway OpenClaw local ({version})",
1800
+ "adapter.logGatewayDisconnected": "D\xE9connect\xE9 du Gateway OpenClaw ; le client officiel se reconnecte\u2026",
1801
+ "adapter.logGatewayConnectFailed": "Impossible de se connecter au Gateway OpenClaw local (la premi\xE8re fois, approuvez l'appareil en local : `openclaw devices list` + `openclaw devices approve <requestId>`)",
1802
+ "adapter.errGatewayNoSessionKey": "Le Gateway n'a pas renvoy\xE9 de cl\xE9 de session",
1803
+ "adapter.logDeleteSessionFailed": "\xC9chec de suppression de session ({session}) : {message} (accus\xE9 de suppression tout de m\xEAme)",
1804
+ "adapter.logApprovalReplyFailed": "\xC9chec de la r\xE9ponse d'approbation ({id}) : {message}",
1805
+ "adapter.logPendingApproval": "session.pending : {count} approbation(s) en attente renvoy\xE9e(s) (session={session})",
1806
+ "adapter.workspaceDefault": "Par d\xE9faut",
1807
+ "adapter.cursorSessionTitle": "Session Cursor",
1808
+ "adapter.reasonDisconnect": "Relais d\xE9connect\xE9, refus automatique (fail-closed)",
1809
+ "adapter.warnInvalidEnv": "Valeur {name} invalide ignor\xE9e : {raw} ({list})",
1810
+ "adapter.errStartFailed": "\xC9chec du d\xE9marrage :",
1811
+ "adapter.msgStarted": "Adaptateur {name} d\xE9marr\xE9 (Ctrl+C pour quitter)",
1812
+ "adapter.warnCliMissing": "Ex\xE9cutable \xAB {bin} \xBB introuvable ; installez-le (ex. npm i -g @openai/codex) ou d\xE9finissez TUNNELBOX_CODEX_BIN avec son chemin",
1813
+ "adapter.errCliNotFound": "Ex\xE9cutable {name} \xAB {bin} \xBB introuvable : installez le Codex CLI (npm i -g @openai/codex) ou d\xE9finissez TUNNELBOX_CODEX_BIN",
1814
+ "adapter.errSessionNotFound": "Session introuvable ou d\xE9j\xE0 supprim\xE9e",
1815
+ "adapter.checkHeader": "V\xE9rification de l'environnement tunnelbox-codex",
1816
+ "adapter.checkCliOk": "Ex\xE9cutable {name} : {path}",
1817
+ "adapter.checkCliMissing": "Ex\xE9cutable {name} introuvable ({bin})",
1818
+ "bin.yes": "oui",
1819
+ "bin.no": "non",
1820
+ "adapter.errAppServerSpawn": "Impossible de d\xE9marrer codex app-server : {message} (v\xE9rifiez que votre Codex CLI prend en charge `codex app-server`)",
1821
+ "adapter.errAppServerExit": "codex app-server s'est arr\xEAt\xE9 ; les approbations/choix en attente ont \xE9t\xE9 refus\xE9s automatiquement",
1822
+ "adapter.logUnsupportedServerRequest": "requ\xEAte app-server non prise en charge : {method}",
1823
+ "adapter.logQuestionNative": "demande de choix -> carte de choix du t\xE9l\xE9phone questionID={id} (session={session})",
1824
+ "adapter.logPermissionNative": "demande d'approbation -> carte d'approbation du t\xE9l\xE9phone permissionID={id} (session={session})",
1825
+ "adapter.checkAppServerOk": "codex app-server disponible",
1826
+ "adapter.checkAppServerMissing": "ce Codex CLI ne prend pas en charge `codex app-server` (veuillez mettre \xE0 jour Codex CLI)"
1161
1827
  };
1162
1828
 
1163
1829
  // locales/de-DE.json
@@ -1210,7 +1876,7 @@ var de_DE_default = {
1210
1876
  "install.scanHint": "\xD6ffnen Sie tunnelbox auf dem Telefon, tippen Sie auf \u201CZum Pairing scannen\u201D und scannen Sie den QR-Code oben zum Verbinden:",
1211
1877
  "pair.heading": "tunnelbox Telefon-Pairing",
1212
1878
  "pair.howTo": "\xD6ffnen Sie die tunnelbox-App auf dem Telefon und scannen Sie den QR-Code oben mit \u201CZum Pairing scannen\u201D, oder geben Sie den Pairing-Code manuell ein.",
1213
- "pair.oneTime": "Der Pairing-Code ist einmalig und verf\xE4llt nach der Nutzung; f\xFCr einen neuen Code \u201CPairing-Code aktualisieren\u201D anfordern.",
1879
+ "pair.oneTime": "Der Kopplungscode ist einmalig und etwa 10 Minuten g\xFCltig; nach Nutzung oder Ablauf wird er ung\xFCltig. Fordern Sie zum Erneuern \u201EKopplungscode aktualisieren\u201C an.",
1214
1880
  "pair.promptBody": "Zeigen Sie bitte die Telefon-Pairing-Informationen dieses Computers an: den Pairing-Code und einen scannbaren QR-Code. Behalten Sie den QR-Code in einem Codeblock mit fester Breite und geben Sie ihn zeichengenau wieder, damit mein Telefon ihn scannen kann.",
1215
1881
  "pair.promptDescription": "Pairing-Code und scannbaren QR-Code anzeigen",
1216
1882
  "pair.scanIntro": "**Per Scan pairen**: \xD6ffnen Sie die tunnelbox-App auf dem Telefon, tippen Sie auf \u201CZum Pairing scannen\u201D und scannen Sie den QR-Code unten, um sich automatisch zu verbinden.",
@@ -1325,7 +1991,118 @@ var de_DE_default = {
1325
1991
  "hermes.pairTimeout": "Zeit\xFCberschreitung bei der Pairing-Code-Anfrage (Relay antwortete nicht)",
1326
1992
  "hermes.errToolPair": "tunnelbox_pair fehlgeschlagen: {err}",
1327
1993
  "hermes.errToolStatus": "tunnelbox_status fehlgeschlagen: {err}",
1328
- "hermes.cliUsage": "Verwendung: /tunnelbox <pair|status>\n pair Pairing-Code anfordern und anzeigen\n status Relay/Bindung/Verbindung anzeigen"
1994
+ "hermes.cliUsage": "Verwendung: /tunnelbox <pair|status>\n pair Pairing-Code anfordern und anzeigen\n status Relay/Bindung/Verbindung anzeigen",
1995
+ "qr.validFor": "Der Kopplungscode ist etwa 10 Minuten g\xFCltig; holen Sie bei Ablauf einen neuen auf Ihrem Computer.",
1996
+ "pair.toolDesc": "Zeigt die Telefon-Kopplungsinfo dieses Computers (Kopplungscode und scannbarer QR-Code). Aufrufen, wenn der Nutzer nach Kopplung, QR-Code-Scan oder Steuerung dieses Computers vom Telefon fragt.",
1997
+ "pair.toolRefreshDesc": "Ob ein neuer Kopplungscode vom Relay angefordert werden soll",
1998
+ "state.errSaveState": "Status konnte nicht gespeichert werden",
1999
+ "adapter.logConnected": "Mit Relay verbunden {url}",
2000
+ "adapter.logDisconnected": "Vom Relay getrennt, automatische Wiederverbindung\u2026",
2001
+ "adapter.logPairCode": "Kopplungscode erzeugt: {code}",
2002
+ "adapter.logClaimed": "Mit Ihrem Telefonkonto verkn\xFCpft. Ab jetzt verbindet sich das Telefon direkt \xFCber \u201EMeine Computer\u201C",
2003
+ "adapter.logResetIdentity": "Vom Konto getrennt; Identit\xE4t wird zur\xFCckgesetzt und neuer Kopplungscode erzeugt\u2026",
2004
+ "adapter.logUnhandledType": "Unbehandelter Nachrichtentyp: {type}",
2005
+ "adapter.errNoRelay": "Keine Relay-URL konfiguriert: mit --env einen Standardwert einbauen oder zur Laufzeit mit TUNNELBOX_RELAY_URL \xFCberschreiben",
2006
+ "adapter.errBusy": "Diese Sitzung l\xE4uft noch; warten Sie auf den Abschluss oder stoppen Sie sie zuerst",
2007
+ "adapter.errBadWorkspaceEmpty": "Arbeitsbereich-Pfad fehlt",
2008
+ "adapter.errBadWorkspaceNotDir": "Verzeichnis existiert nicht oder ist unbrauchbar",
2009
+ "adapter.errWorkspaceMissing": "Arbeitsbereich existiert nicht: {dir}",
2010
+ "adapter.cmdNew": "Neue Sitzung",
2011
+ "adapter.cmdHelp": "Hilfe anzeigen",
2012
+ "adapter.helpText": "Unterst\xFCtzte Befehle:\n- /new neue Sitzung\n- /help Hilfe anzeigen",
2013
+ "adapter.newSessionTitle": "Neue Sitzung",
2014
+ "install.langHelpTitle": "Von install-local unterst\xFCtzte Sprachen (--lang <tag>):",
2015
+ "install.langHelpExample": "Beispiel: npm run install-local -- --lang de-DE",
2016
+ "install.unknownLang": 'Unbekannte Sprache "{raw}", R\xFCckfall auf en-US. Unterst\xFCtzt: {list}',
2017
+ "hermes.errAskRequired": "question ist erforderlich",
2018
+ "hermes.msgPhoneUnavailable": "Telefon nicht verf\xFCgbar oder keine Antwort: Nutzen Sie das integrierte clarify f\xFCr eine lokale Frage oder entscheiden Sie selbst.",
2019
+ "hermes.errClarifyUnavailable": "clarify-Unterst\xFCtzung nicht verf\xFCgbar",
2020
+ "hermes.errAskFailed": "tunnelbox_ask fehlgeschlagen: {err}",
2021
+ "hermes.errClarifyFailed": "clarify fehlgeschlagen: {err}",
2022
+ "bin.denied": "Vom Telefon abgelehnt",
2023
+ "bin.timeout": "Genehmigung Zeit\xFCberschreitung (fail-closed)",
2024
+ "bin.reqRun": "Claude Code fordert die Ausf\xFChrung von {tool} an",
2025
+ "bin.pairTitle": "tunnelbox Telefon-Kopplung",
2026
+ "bin.pairCodeLine": " Kopplungscode: {code}",
2027
+ "bin.pairHint": "\xD6ffnen Sie die tunnelbox-App, tippen Sie auf \u201EZum Koppeln scannen\u201C und scannen Sie den QR-Code, oder geben Sie den Kopplungscode manuell ein (einmalig).",
2028
+ "bin.pairWritten": " Kopplungsinfo geschrieben nach: {path}",
2029
+ "bin.pairRequestFailed": "Anforderung eines Kopplungscodes vom Relay fehlgeschlagen.",
2030
+ "bin.alreadyClaimed": "Dieser Computer ist bereits mit einem Telefonkonto verkn\xFCpft; verbinden Sie sich direkt \xFCber \u201EMeine Computer\u201C. Zum erneuten Koppeln zuerst am Telefon trennen.",
2031
+ "bin.noRelay": "Keine Relay-URL konfiguriert: setzen Sie TUNNELBOX_RELAY_URL und versuchen Sie es erneut.",
2032
+ "bin.connectFailed": "Verbindung zum Relay nicht m\xF6glich: {relay}\nSetzen Sie TUNNELBOX_RELAY_URL oder konfigurieren Sie es in der official-plugin-Statusdatei.",
2033
+ "bin.statusRelay": "Relay: {value}",
2034
+ "bin.statusAgent": "Agent-ID: {value}",
2035
+ "bin.statusClaimed": "Telefon verkn\xFCpft: {value}",
2036
+ "bin.statusStateFile": "Statusdatei: {value}",
2037
+ "bin.statusLatest": "Neueste Kopplungsinfo:",
2038
+ "bin.usage": "Verwendung: tunnelbox <pair|status|ask>",
2039
+ "bin.usagePair": " pair Telefon-Kopplungscode anfordern und ausgeben",
2040
+ "bin.usageStatus": " status Relay-/Verkn\xFCpfungsstatus anzeigen",
2041
+ "bin.usageAsk": " ask eine Tool-Genehmigung ans Telefon weiterleiten",
2042
+ "adapter.logMsgUncaught": "Unabgefangene Ausnahme bei der Nachrichtenverarbeitung: {message}",
2043
+ "adapter.logHandleFailed": "Verarbeitung von {type} fehlgeschlagen: {message}",
2044
+ "adapter.logPromptFailed": "session.prompt fehlgeschlagen: {message}",
2045
+ "adapter.logAbortSent": "Abbruch gesendet (session={session})",
2046
+ "adapter.errUserDenied": "Vom Nutzer abgelehnt",
2047
+ "adapter.logPendingResent": "session.pending: {count} ausstehende Anfrage(n) erneut gesendet",
2048
+ "adapter.logWorkspaceSwitched": "Arbeitsbereich gewechselt: {path}",
2049
+ "adapter.logNewSession": "Neue Sitzung gespeichert codexId={codexId} (alias={session})",
2050
+ "adapter.logSessionError": "Turn-Fehler (session={session}): {message}",
2051
+ "adapter.logDshSent": "An dsh gesendet (session={session})",
2052
+ "adapter.logReadHistoryFailed": "Sitzungsverlauf lesen fehlgeschlagen ({session}): {message}",
2053
+ "adapter.logAnswererInitFailed": "Initialisierung des Antwortgebers fehlgeschlagen: {message}",
2054
+ "adapter.logRemoteMode": "Dualanzeige-Modus: Auswahl/Genehmigung \xFCber typert-Multi-Client-Broadcast; Telefon und dsh web teilen die Ansicht, die erste Antwort gewinnt",
2055
+ "adapter.logRemoteProbeFailed": "typert-Remote-Ereignisquellen-Pr\xFCfung fehlgeschlagen; R\xFCckfall auf lokalen Antwortmodus: {message}",
2056
+ "adapter.logLocalMode": "Lokaler Antwortmodus: Auswahl/Genehmigung erfolgt durch das Telefon (headless, ohne dsh web-Broadcast)",
2057
+ "adapter.logRemoteStreamInterrupted": "remote events-Stream unterbrochen: {message}",
2058
+ "adapter.logResultRejected": "$events/result nicht akzeptiert ({eventId}): {message}",
2059
+ "adapter.logResultBackfillFailed": "$events/result-R\xFCckschreiben fehlgeschlagen ({eventId}): {message}",
2060
+ "adapter.logRemoteQuestion": "remote-Frage-Broadcast \u2192 Telefon-Fragekarte questionID={id} (session={session})",
2061
+ "adapter.errRemoteReadyFrame": "Unerwarteter erster Frame von remote events",
2062
+ "adapter.logRemoteApproval": "remote-Genehmigungs-Broadcast \u2192 Telefon-Berechtigungskarte permissionID={id} (session={session})",
2063
+ "adapter.logUserQuestionRoute": "user-questions-Auswahl \u2192 weitergeleitet an session={session}",
2064
+ "adapter.errDshQuestionEmpty": "dsh-Frageinhalt ist leer",
2065
+ "adapter.errQuestionTimeout": "Frage-Zeit\xFCberschreitung ({seconds}s), abgebrochen",
2066
+ "adapter.errQuestionCancelledAbort": "Frage abgebrochen (Agent abgebrochen)",
2067
+ "adapter.errQuestionCancelledRelay": "Relay nicht erreichbar, Frage abgebrochen",
2068
+ "adapter.logQuestionToPhone": "user-questions-Auswahl \u2192 an Telefon-Fragekarte gesendet questionID={id} (session={session})",
2069
+ "adapter.errQuestionUserCancelled": "Nutzer hat die Frage am Telefon abgebrochen/abgelehnt",
2070
+ "adapter.logApprovalRequest": "Genehmigungsanfrage (tool={tool}) \u2192 an Telefon-Berechtigungskarte gesendet permissionID={id}",
2071
+ "adapter.logAgentPresetFailed": "agentPreset-Aufl\xF6sung fehlgeschlagen ({preset}); R\xFCckfall ohne Preset: {message}",
2072
+ "adapter.logSessionLiveAdopted": "Sitzung {session} wird bereits von einem anderen Agent in diesem Prozess gehalten (live); vorhandener Agent wird \xFCbernommen: {message}",
2073
+ "adapter.logDisposeSkipped": "\xDCbernommener externer Live-Agent f\xFChrt dispose nicht aus (Sitzung {session} wird vom urspr\xFCnglichen Halter verwaltet)",
2074
+ "adapter.logAgentCreateFailed": "Agent erstellen/fortsetzen fehlgeschlagen ({session}): {message}",
2075
+ "adapter.errSessionBusyLive": "Sitzung {session} ist belegt (live); versuchen Sie es sp\xE4ter erneut",
2076
+ "adapter.errAgentsUnavailable": "agents-Dienst nicht verf\xFCgbar",
2077
+ "adapter.logToolReason": "dsh fordert die Ausf\xFChrung des Tools {tool} an",
2078
+ "adapter.logGatewayConnected": "Mit lokalem OpenClaw Gateway verbunden ({version})",
2079
+ "adapter.logGatewayDisconnected": "Vom OpenClaw Gateway getrennt; der offizielle Client verbindet sich neu\u2026",
2080
+ "adapter.logGatewayConnectFailed": "Verbindung zum lokalen OpenClaw Gateway nicht m\xF6glich (beim ersten Mal das Ger\xE4t lokal freigeben: `openclaw devices list` + `openclaw devices approve <requestId>`)",
2081
+ "adapter.errGatewayNoSessionKey": "Gateway hat keinen Sitzungsschl\xFCssel zur\xFCckgegeben",
2082
+ "adapter.logDeleteSessionFailed": "Sitzung l\xF6schen fehlgeschlagen ({session}): {message} (wird dennoch als gel\xF6scht best\xE4tigt)",
2083
+ "adapter.logApprovalReplyFailed": "Genehmigungsantwort fehlgeschlagen ({id}): {message}",
2084
+ "adapter.logPendingApproval": "session.pending: {count} ausstehende Genehmigung(en) erneut gesendet (session={session})",
2085
+ "adapter.workspaceDefault": "Standard",
2086
+ "adapter.cursorSessionTitle": "Cursor-Sitzung",
2087
+ "adapter.reasonDisconnect": "Relay getrennt, automatische Ablehnung (fail-closed)",
2088
+ "adapter.warnInvalidEnv": "Ung\xFCltiges {name} ignoriert: {raw} ({list})",
2089
+ "adapter.errStartFailed": "Start fehlgeschlagen:",
2090
+ "adapter.msgStarted": "{name}-Adapter gestartet (Ctrl+C zum Beenden)",
2091
+ "adapter.warnCliMissing": "Ausf\xFChrbare Datei \u201E{bin}\u201C nicht gefunden; installieren Sie sie (z. B. npm i -g @openai/codex) oder setzen Sie TUNNELBOX_CODEX_BIN auf ihren Pfad",
2092
+ "adapter.errCliNotFound": "Ausf\xFChrbare Datei {name} \u201E{bin}\u201C nicht gefunden: Installieren Sie die Codex CLI (npm i -g @openai/codex) oder setzen Sie TUNNELBOX_CODEX_BIN",
2093
+ "adapter.errSessionNotFound": "Sitzung nicht gefunden oder bereits gel\xF6scht",
2094
+ "adapter.checkHeader": "tunnelbox-codex-Umgebungspr\xFCfung",
2095
+ "adapter.checkCliOk": "Ausf\xFChrbare Datei {name}: {path}",
2096
+ "adapter.checkCliMissing": "Ausf\xFChrbare Datei {name} nicht gefunden ({bin})",
2097
+ "bin.yes": "ja",
2098
+ "bin.no": "nein",
2099
+ "adapter.errAppServerSpawn": "codex app-server konnte nicht gestartet werden: {message} (pr\xFCfen Sie, ob Ihre Codex CLI `codex app-server` unterst\xFCtzt)",
2100
+ "adapter.errAppServerExit": "codex app-server wurde beendet; ausstehende Genehmigungen/Auswahlen wurden automatisch abgelehnt",
2101
+ "adapter.logUnsupportedServerRequest": "nicht unterst\xFCtzte app-server-Anfrage: {method}",
2102
+ "adapter.logQuestionNative": "Auswahlanfrage -> Auswahlkarte am Handy questionID={id} (session={session})",
2103
+ "adapter.logPermissionNative": "Genehmigungsanfrage -> Genehmigungskarte am Handy permissionID={id} (session={session})",
2104
+ "adapter.checkAppServerOk": "codex app-server verf\xFCgbar",
2105
+ "adapter.checkAppServerMissing": "diese Codex CLI unterst\xFCtzt `codex app-server` nicht (bitte Codex CLI aktualisieren)"
1329
2106
  };
1330
2107
 
1331
2108
  // locales/es-ES.json
@@ -1378,7 +2155,7 @@ var es_ES_default = {
1378
2155
  "install.scanHint": "Abra tunnelbox en el tel\xE9fono, pulse \u201CEscanear para emparejar\u201D y escanee el c\xF3digo QR superior para conectar:",
1379
2156
  "pair.heading": "Emparejamiento de tel\xE9fono tunnelbox",
1380
2157
  "pair.howTo": "Abra la aplicaci\xF3n tunnelbox en el tel\xE9fono y escanee el c\xF3digo QR superior con \u201CEscanear para emparejar\u201D, o introduzca el c\xF3digo de emparejamiento manualmente.",
1381
- "pair.oneTime": "El c\xF3digo de emparejamiento es de un solo uso y caduca al utilizarse; pida \u201Cactualizar el c\xF3digo de emparejamiento\u201D para obtener uno nuevo.",
2158
+ "pair.oneTime": "El c\xF3digo de emparejamiento es de un solo uso y v\xE1lido unos 10 minutos; deja de funcionar al usarse o caducar. Pida \xABactualizar el c\xF3digo de emparejamiento\xBB para obtener uno nuevo.",
1382
2159
  "pair.promptBody": "Mu\xE9strame la informaci\xF3n de emparejamiento con el tel\xE9fono de este ordenador: el c\xF3digo de emparejamiento y un c\xF3digo QR escaneable. Mant\xE9n el c\xF3digo QR dentro de un bloque de c\xF3digo de ancho fijo y reprod\xFAcelo car\xE1cter por car\xE1cter para que mi tel\xE9fono pueda escanearlo.",
1383
2160
  "pair.promptDescription": "Mostrar el c\xF3digo de emparejamiento y el QR escaneable",
1384
2161
  "pair.scanIntro": "**Emparejar escaneando**: abra la aplicaci\xF3n tunnelbox en el tel\xE9fono, pulse \u201CEscanear para emparejar\u201D y escanee el c\xF3digo QR inferior para conectar autom\xE1ticamente.",
@@ -1493,7 +2270,118 @@ var es_ES_default = {
1493
2270
  "hermes.pairTimeout": "Tiempo de espera agotado al solicitar el c\xF3digo de emparejamiento (rel\xE9 sin respuesta)",
1494
2271
  "hermes.errToolPair": "fallo de tunnelbox_pair: {err}",
1495
2272
  "hermes.errToolStatus": "fallo de tunnelbox_status: {err}",
1496
- "hermes.cliUsage": "Uso: /tunnelbox <pair|status>\n pair solicitar e imprimir un c\xF3digo de emparejamiento\n status mostrar estado de rel\xE9/enlace/conexi\xF3n"
2273
+ "hermes.cliUsage": "Uso: /tunnelbox <pair|status>\n pair solicitar e imprimir un c\xF3digo de emparejamiento\n status mostrar estado de rel\xE9/enlace/conexi\xF3n",
2274
+ "qr.validFor": "El c\xF3digo de emparejamiento es v\xE1lido durante unos 10 minutos; si caduca, obtenga uno nuevo en su computadora.",
2275
+ "pair.toolDesc": "Muestra la informaci\xF3n de emparejamiento telef\xF3nico de esta computadora (c\xF3digo de emparejamiento y c\xF3digo QR escaneable). Llamar cuando el usuario pregunte sobre emparejamiento, escaneo de QR o controlar esta computadora desde el tel\xE9fono.",
2276
+ "pair.toolRefreshDesc": "Si se debe solicitar un nuevo c\xF3digo de emparejamiento al rel\xE9",
2277
+ "state.errSaveState": "No se pudo guardar el estado",
2278
+ "adapter.logConnected": "Conectado al rel\xE9 {url}",
2279
+ "adapter.logDisconnected": "Desconectado del rel\xE9, reconectando autom\xE1ticamente\u2026",
2280
+ "adapter.logPairCode": "C\xF3digo de emparejamiento generado: {code}",
2281
+ "adapter.logClaimed": "Vinculado a su cuenta de tel\xE9fono. A partir de ahora el tel\xE9fono se conecta directamente desde \xABMis computadoras\xBB",
2282
+ "adapter.logResetIdentity": "Desvinculado de la cuenta; restableciendo identidad y generando un nuevo c\xF3digo de emparejamiento\u2026",
2283
+ "adapter.logUnhandledType": "Tipo de mensaje no gestionado: {type}",
2284
+ "adapter.errNoRelay": "No hay URL de rel\xE9 configurada: compile con --env para inyectar un valor predeterminado, o sobrescr\xEDbala en tiempo de ejecuci\xF3n con TUNNELBOX_RELAY_URL",
2285
+ "adapter.errBusy": "Esta sesi\xF3n sigue en ejecuci\xF3n; espere a que termine o det\xE9ngala primero",
2286
+ "adapter.errBadWorkspaceEmpty": "Falta la ruta del espacio de trabajo",
2287
+ "adapter.errBadWorkspaceNotDir": "El directorio no existe o no es utilizable",
2288
+ "adapter.errWorkspaceMissing": "El espacio de trabajo no existe: {dir}",
2289
+ "adapter.cmdNew": "Nueva sesi\xF3n",
2290
+ "adapter.cmdHelp": "Mostrar ayuda",
2291
+ "adapter.helpText": "Comandos admitidos:\n- /new nueva sesi\xF3n\n- /help mostrar ayuda",
2292
+ "adapter.newSessionTitle": "Nueva sesi\xF3n",
2293
+ "install.langHelpTitle": "Idiomas admitidos por install-local (--lang <tag>):",
2294
+ "install.langHelpExample": "Ejemplo: npm run install-local -- --lang de-DE",
2295
+ "install.unknownLang": "Idioma desconocido \xAB{raw}\xBB, se usar\xE1 en-US. Admitidos: {list}",
2296
+ "hermes.errAskRequired": "question es obligatorio",
2297
+ "hermes.msgPhoneUnavailable": "Tel\xE9fono no disponible o sin respuesta: use el clarify integrado para preguntar localmente, o decida por su cuenta.",
2298
+ "hermes.errClarifyUnavailable": "Compatibilidad con clarify no disponible",
2299
+ "hermes.errAskFailed": "tunnelbox_ask fall\xF3: {err}",
2300
+ "hermes.errClarifyFailed": "clarify fall\xF3: {err}",
2301
+ "bin.denied": "Rechazado desde su tel\xE9fono",
2302
+ "bin.timeout": "Aprobaci\xF3n agotada (fail-closed)",
2303
+ "bin.reqRun": "Claude Code solicita ejecutar {tool}",
2304
+ "bin.pairTitle": "Emparejamiento telef\xF3nico tunnelbox",
2305
+ "bin.pairCodeLine": " C\xF3digo de emparejamiento: {code}",
2306
+ "bin.pairHint": "Abra la app tunnelbox, toque \xABEscanear para emparejar\xBB y escanee el c\xF3digo QR, o introduzca el c\xF3digo de emparejamiento manualmente (un solo uso).",
2307
+ "bin.pairWritten": " Informaci\xF3n de emparejamiento escrita en: {path}",
2308
+ "bin.pairRequestFailed": "No se pudo solicitar un c\xF3digo de emparejamiento al rel\xE9.",
2309
+ "bin.alreadyClaimed": "Esta computadora ya est\xE1 vinculada a una cuenta de tel\xE9fono; con\xE9ctese directamente desde \xABMis computadoras\xBB. Para volver a emparejar, desvinc\xFAlela primero en el tel\xE9fono.",
2310
+ "bin.noRelay": "No hay URL de rel\xE9 configurada: defina TUNNELBOX_RELAY_URL e int\xE9ntelo de nuevo.",
2311
+ "bin.connectFailed": "No se puede conectar al rel\xE9: {relay}\nDefina TUNNELBOX_RELAY_URL o config\xFArelo en el archivo de estado de official-plugin.",
2312
+ "bin.statusRelay": "Rel\xE9: {value}",
2313
+ "bin.statusAgent": "ID del agente: {value}",
2314
+ "bin.statusClaimed": "Tel\xE9fono vinculado: {value}",
2315
+ "bin.statusStateFile": "Archivo de estado: {value}",
2316
+ "bin.statusLatest": "\xDAltima informaci\xF3n de emparejamiento:",
2317
+ "bin.usage": "Uso: tunnelbox <pair|status|ask>",
2318
+ "bin.usagePair": " pair solicitar e imprimir un c\xF3digo de emparejamiento",
2319
+ "bin.usageStatus": " status mostrar estado del rel\xE9/vinculaci\xF3n",
2320
+ "bin.usageAsk": " ask reenviar una aprobaci\xF3n de herramienta al tel\xE9fono",
2321
+ "adapter.logMsgUncaught": "Excepci\xF3n no capturada al procesar el mensaje: {message}",
2322
+ "adapter.logHandleFailed": "Error al procesar {type}: {message}",
2323
+ "adapter.logPromptFailed": "session.prompt fall\xF3: {message}",
2324
+ "adapter.logAbortSent": "Cancelaci\xF3n enviada (session={session})",
2325
+ "adapter.errUserDenied": "Rechazado por el usuario",
2326
+ "adapter.logPendingResent": "session.pending: {count} solicitud(es) pendiente(s) reenviada(s)",
2327
+ "adapter.logWorkspaceSwitched": "Espacio de trabajo cambiado: {path}",
2328
+ "adapter.logNewSession": "Nueva sesi\xF3n guardada codexId={codexId} (alias={session})",
2329
+ "adapter.logSessionError": "Error de turno (session={session}): {message}",
2330
+ "adapter.logDshSent": "Enviado a dsh (session={session})",
2331
+ "adapter.logReadHistoryFailed": "Error al leer el historial de sesi\xF3n ({session}): {message}",
2332
+ "adapter.logAnswererInitFailed": "Error al inicializar el respondedor: {message}",
2333
+ "adapter.logRemoteMode": "Modo de visualizaci\xF3n dual: selecciones/aprobaciones usan difusi\xF3n multicliente typert; tel\xE9fono y dsh web comparten la vista, gana la primera respuesta",
2334
+ "adapter.logRemoteProbeFailed": "Fall\xF3 la detecci\xF3n de la fuente de eventos remota typert; se usar\xE1 el modo de respuesta local: {message}",
2335
+ "adapter.logLocalMode": "Modo de respuesta local: selecciones/aprobaciones respondidas por el tel\xE9fono (headless, sin difusi\xF3n de dsh web)",
2336
+ "adapter.logRemoteStreamInterrupted": "Flujo remote events interrumpido: {message}",
2337
+ "adapter.logResultRejected": "$events/result no aceptado ({eventId}): {message}",
2338
+ "adapter.logResultBackfillFailed": "Error al rellenar $events/result ({eventId}): {message}",
2339
+ "adapter.logRemoteQuestion": "Difusi\xF3n de pregunta remote \u2192 tarjeta de pregunta del tel\xE9fono questionID={id} (session={session})",
2340
+ "adapter.errRemoteReadyFrame": "Primer fotograma de remote events inesperado",
2341
+ "adapter.logRemoteApproval": "Difusi\xF3n de aprobaci\xF3n remote \u2192 tarjeta de permiso del tel\xE9fono permissionID={id} (session={session})",
2342
+ "adapter.logUserQuestionRoute": "Selecci\xF3n de user-questions \u2192 enrutada a session={session}",
2343
+ "adapter.errDshQuestionEmpty": "El contenido de la pregunta de dsh est\xE1 vac\xEDo",
2344
+ "adapter.errQuestionTimeout": "Pregunta agotada ({seconds}s), cancelada",
2345
+ "adapter.errQuestionCancelledAbort": "Pregunta cancelada (agente abortado)",
2346
+ "adapter.errQuestionCancelledRelay": "Rel\xE9 inaccesible, pregunta cancelada",
2347
+ "adapter.logQuestionToPhone": "Selecci\xF3n de user-questions \u2192 enviada a la tarjeta de pregunta del tel\xE9fono questionID={id} (session={session})",
2348
+ "adapter.errQuestionUserCancelled": "El usuario cancel\xF3/rechaz\xF3 la pregunta en el tel\xE9fono",
2349
+ "adapter.logApprovalRequest": "Solicitud de aprobaci\xF3n (tool={tool}) \u2192 enviada a la tarjeta de permiso del tel\xE9fono permissionID={id}",
2350
+ "adapter.logAgentPresetFailed": "Error al resolver agentPreset ({preset}); se usar\xE1 sin preset: {message}",
2351
+ "adapter.logSessionLiveAdopted": "La sesi\xF3n {session} ya est\xE1 retenida por otro agente de este proceso (live); se adopta el agente existente para continuar: {message}",
2352
+ "adapter.logDisposeSkipped": "El agente live externo adoptado no ejecuta dispose (la sesi\xF3n {session} la gestiona su titular original)",
2353
+ "adapter.logAgentCreateFailed": "Error al crear/reanudar el agente ({session}): {message}",
2354
+ "adapter.errSessionBusyLive": "La sesi\xF3n {session} est\xE1 ocupada (live); int\xE9ntelo m\xE1s tarde",
2355
+ "adapter.errAgentsUnavailable": "Servicio agents no disponible",
2356
+ "adapter.logToolReason": "dsh solicita ejecutar la herramienta {tool}",
2357
+ "adapter.logGatewayConnected": "Conectado al Gateway OpenClaw local ({version})",
2358
+ "adapter.logGatewayDisconnected": "Desconectado del Gateway OpenClaw; el cliente oficial se est\xE1 reconectando\u2026",
2359
+ "adapter.logGatewayConnectFailed": "No se puede conectar al Gateway OpenClaw local (la primera vez, apruebe el dispositivo localmente: `openclaw devices list` + `openclaw devices approve <requestId>`)",
2360
+ "adapter.errGatewayNoSessionKey": "El Gateway no devolvi\xF3 una clave de sesi\xF3n",
2361
+ "adapter.logDeleteSessionFailed": "Error al eliminar la sesi\xF3n ({session}): {message} (se confirma como eliminada igualmente)",
2362
+ "adapter.logApprovalReplyFailed": "Error en la respuesta de aprobaci\xF3n ({id}): {message}",
2363
+ "adapter.logPendingApproval": "session.pending: {count} aprobaci\xF3n(es) pendiente(s) reenviada(s) (session={session})",
2364
+ "adapter.workspaceDefault": "Predeterminado",
2365
+ "adapter.cursorSessionTitle": "Sesi\xF3n de Cursor",
2366
+ "adapter.reasonDisconnect": "Rel\xE9 desconectado, rechazo autom\xE1tico (fail-closed)",
2367
+ "adapter.warnInvalidEnv": "Se ignora {name} no v\xE1lido: {raw} ({list})",
2368
+ "adapter.errStartFailed": "Error al iniciar:",
2369
+ "adapter.msgStarted": "Adaptador {name} iniciado (Ctrl+C para salir)",
2370
+ "adapter.warnCliMissing": "Ejecutable \xAB{bin}\xBB no encontrado; inst\xE1lelo (p. ej. npm i -g @openai/codex) o defina TUNNELBOX_CODEX_BIN con su ruta",
2371
+ "adapter.errCliNotFound": "Ejecutable {name} \xAB{bin}\xBB no encontrado: instale el Codex CLI (npm i -g @openai/codex) o defina TUNNELBOX_CODEX_BIN",
2372
+ "adapter.errSessionNotFound": "Sesi\xF3n no encontrada o ya eliminada",
2373
+ "adapter.checkHeader": "Comprobaci\xF3n del entorno de tunnelbox-codex",
2374
+ "adapter.checkCliOk": "Ejecutable {name}: {path}",
2375
+ "adapter.checkCliMissing": "Ejecutable {name} no encontrado ({bin})",
2376
+ "bin.yes": "s\xED",
2377
+ "bin.no": "no",
2378
+ "adapter.errAppServerSpawn": "No se pudo iniciar codex app-server: {message} (comprueba que tu Codex CLI admita `codex app-server`)",
2379
+ "adapter.errAppServerExit": "codex app-server se cerr\xF3; las aprobaciones/elecciones pendientes se rechazaron autom\xE1ticamente",
2380
+ "adapter.logUnsupportedServerRequest": "solicitud de app-server no admitida: {method}",
2381
+ "adapter.logQuestionNative": "solicitud de elecci\xF3n -> tarjeta de elecci\xF3n del tel\xE9fono questionID={id} (session={session})",
2382
+ "adapter.logPermissionNative": "solicitud de aprobaci\xF3n -> tarjeta de aprobaci\xF3n del tel\xE9fono permissionID={id} (session={session})",
2383
+ "adapter.checkAppServerOk": "codex app-server disponible",
2384
+ "adapter.checkAppServerMissing": "este Codex CLI no admite `codex app-server` (actualiza Codex CLI)"
1497
2385
  };
1498
2386
 
1499
2387
  // src/i18n.ts
@@ -1581,7 +2469,7 @@ function saveState(st, type) {
1581
2469
  mkdirSync(dirname(p), { recursive: true });
1582
2470
  writeFileSync(p, JSON.stringify(st, null, 2), "utf8");
1583
2471
  } catch (e) {
1584
- console.error("[tunnelbox] \u4FDD\u5B58\u72B6\u6001\u5931\u8D25", e);
2472
+ console.error(`[tunnelbox] ${t(st.lang ?? resolveLang(), "state.errSaveState")}`, e);
1585
2473
  }
1586
2474
  }
1587
2475
  function loadState(type) {
@@ -1609,11 +2497,12 @@ function loadState(type) {
1609
2497
  return fallback;
1610
2498
  }
1611
2499
  }
1612
- function writePairingFile(code, type) {
2500
+ function writePairingFile(code, type, lang) {
1613
2501
  const p = join(baseName(), `remote-pairing${suffix(type)}.txt`);
1614
2502
  try {
1615
2503
  mkdirSync(dirname(p), { recursive: true });
1616
- writeFileSync(p, `\u914D\u5BF9\u7801: ${code}
2504
+ const label = t(lang ?? resolveLang(), "qr.codeLabel");
2505
+ writeFileSync(p, `${label}: ${code}
1617
2506
  `, "utf8");
1618
2507
  } catch {
1619
2508
  }
@@ -1677,7 +2566,7 @@ function padVisual(s, width, align = "left") {
1677
2566
  }
1678
2567
  async function printPairing(code, type, name, lang) {
1679
2568
  const resolved = lang ? normalizeLang(lang) : resolveLang();
1680
- const file = writePairingFile(code, type);
2569
+ const file = writePairingFile(code, type, resolved);
1681
2570
  const tt = (key, vars) => t(resolved, key, vars);
1682
2571
  const title = type ? tt("qr.titleWithType", { type }) : tt("qr.titleNoType");
1683
2572
  const codeLine = `${tt("qr.codeLabel")}: ${code}`;
@@ -1692,6 +2581,7 @@ async function printPairing(code, type, name, lang) {
1692
2581
  console.log("\u2502 " + padVisual(codeLine, W - 2) + " \u2502");
1693
2582
  console.log("\u2514" + bar + "\u2518");
1694
2583
  console.log(" " + hint);
2584
+ console.log(" " + tt("qr.validFor"));
1695
2585
  try {
1696
2586
  const mod = await import("qrcode");
1697
2587
  const render = mod.default ?? mod;
@@ -1804,6 +2694,90 @@ var MessagesCache = class {
1804
2694
  }
1805
2695
  };
1806
2696
  var messagesCache = new MessagesCache();
2697
+
2698
+ // src/cli.ts
2699
+ import { spawnSync } from "child_process";
2700
+ import { existsSync as existsSync2, statSync } from "fs";
2701
+ import { isAbsolute, join as join2, resolve } from "path";
2702
+ function needsCmdQuote(s) {
2703
+ return s === "" || /[ \t&|<>^"%]/.test(s);
2704
+ }
2705
+ function cmdLineFor(shimPath, args) {
2706
+ const parts = [`"${shimPath}"`, ...args.map((a) => needsCmdQuote(a) ? `"${a}"` : a)];
2707
+ return parts.join(" ");
2708
+ }
2709
+ function findWinShim(name) {
2710
+ if (name.includes("/") || name.includes("\\")) return null;
2711
+ const dirs = (process.env.PATH || "").split(";").filter(Boolean);
2712
+ for (const dir of dirs) {
2713
+ for (const ext of [".cmd", ".bat"]) {
2714
+ const p = join2(dir, name + ext);
2715
+ if (existsSync2(p)) return p;
2716
+ }
2717
+ }
2718
+ return null;
2719
+ }
2720
+ var WIN_CLI_EXTS = [".exe", ".cmd", ".bat"];
2721
+ function hasPathSep(name) {
2722
+ return name.includes("/") || name.includes("\\");
2723
+ }
2724
+ function fileExists(p) {
2725
+ try {
2726
+ return statSync(p).isFile();
2727
+ } catch {
2728
+ return false;
2729
+ }
2730
+ }
2731
+ function whichInPath(name) {
2732
+ const dirs = (process.env.PATH || "").split(";").filter(Boolean);
2733
+ for (const dir of dirs) {
2734
+ for (const ext of WIN_CLI_EXTS) {
2735
+ const p = join2(dir, name + ext);
2736
+ if (fileExists(p)) return { path: p, viaShell: ext !== ".exe" };
2737
+ }
2738
+ }
2739
+ return null;
2740
+ }
2741
+ function resolveCliBinary(name) {
2742
+ const raw = (name || "").trim();
2743
+ if (!raw) return null;
2744
+ if (hasPathSep(raw)) {
2745
+ const base = isAbsolute(raw) ? raw : resolve(process.cwd(), raw);
2746
+ const candidates = [base];
2747
+ if (process.platform === "win32" && !/\.[a-z0-9]+$/i.test(base)) {
2748
+ for (const ext of WIN_CLI_EXTS) candidates.push(base + ext);
2749
+ }
2750
+ for (const p of candidates) {
2751
+ if (fileExists(p)) return { path: p, viaShell: /\.(cmd|bat)$/i.test(p) };
2752
+ }
2753
+ return null;
2754
+ }
2755
+ if (process.platform === "win32") return whichInPath(raw);
2756
+ return { path: raw, viaShell: false };
2757
+ }
2758
+ function killCliTree(child) {
2759
+ if (!child || child.exitCode !== null) return;
2760
+ if (process.platform === "win32") {
2761
+ const pid = child.pid;
2762
+ if (pid) {
2763
+ try {
2764
+ spawnSync("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
2765
+ } catch {
2766
+ }
2767
+ }
2768
+ return;
2769
+ }
2770
+ try {
2771
+ child.kill("SIGTERM");
2772
+ } catch {
2773
+ }
2774
+ setTimeout(() => {
2775
+ try {
2776
+ if (child.exitCode === null) child.kill("SIGKILL");
2777
+ } catch {
2778
+ }
2779
+ }, 1500);
2780
+ }
1807
2781
  export {
1808
2782
  DEFAULT_LANG,
1809
2783
  DEFAULT_PAGE_SIZE,
@@ -1815,15 +2789,20 @@ export {
1815
2789
  RelayClient,
1816
2790
  capMessage,
1817
2791
  capMessages,
2792
+ cmdLineFor,
1818
2793
  detectSystemLang,
1819
2794
  envelope,
2795
+ findWinShim,
1820
2796
  injectedRelayUrl,
2797
+ killCliTree,
1821
2798
  loadState,
1822
2799
  makeT,
1823
2800
  messagesCache,
2801
+ needsCmdQuote,
1824
2802
  normalizeLang,
1825
2803
  printPairing,
1826
2804
  renderPairingQrText,
2805
+ resolveCliBinary,
1827
2806
  resolveLang,
1828
2807
  saveState,
1829
2808
  sliceWindow,