@epoch-agent/infra 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +128 -12
- package/dist/index.js +52 -6
- package/dist/locales/en.yaml +156 -22
- package/dist/locales/zh.yaml +157 -23
- package/package.json +4 -4
package/dist/locales/en.yaml
CHANGED
|
@@ -249,6 +249,10 @@ web:
|
|
|
249
249
|
mkdir_parent_not_absolute: 'the location to create in must be an absolute path: {parent}'
|
|
250
250
|
mkdir_bad_name: 'the directory name must be a single segment with no path separators, and cannot be . or ..: {name}'
|
|
251
251
|
mkdir_failed: 'could not create that directory: {path}'
|
|
252
|
+
pick_prompt: Choose a workspace directory
|
|
253
|
+
pick_unavailable: 'this machine cannot open a system directory dialog: it is only enabled when the server and the browser are on the same machine (loopback bind, not started over ssh, macOS or Windows) — use the built-in browser instead'
|
|
254
|
+
pick_busy: a directory dialog is already open — go answer it (this window may be covering it)
|
|
255
|
+
pick_failed: 'the system directory dialog could not be opened: {detail}'
|
|
252
256
|
plan_mode_unavailable: this process has no plan mode (the permission layer did not start)
|
|
253
257
|
plan_mode_bad_action: action must be one of {actions}
|
|
254
258
|
permission_unavailable: this process has no permission layer, so the level cannot be changed (what you see is the value from the config file)
|
|
@@ -260,7 +264,7 @@ web:
|
|
|
260
264
|
rewind_bad_overwrite: overwrite must be a list of file paths (the ones the user confirmed one by one); omit the field entirely if there is nothing to overwrite
|
|
261
265
|
rewind_no_checkpoint: no checkpoint for turn {turn}
|
|
262
266
|
settings_write_bad_request: the body needs key (the dotted path of the setting), layer (one of {layers}) and value (string / number / boolean)
|
|
263
|
-
settings_write_unknown_key: that key cannot be
|
|
267
|
+
settings_write_unknown_key: 'that key cannot be written this way: either it is not on the writable list at all (the fallback chain, for one — it is an ordered chain, not a scalar), or the key only writes to the user layer while the request asked for project-local. The project layers accept permissions / model / maxTurns only; anything else lands as an "unknown setting" in the startup diagnostics'
|
|
264
268
|
settings_write_bad_value: that value is outside this setting's domain (maxTurns must be a positive integer, for one), so nothing was written
|
|
265
269
|
settings_write_unwritable: this layer does not recognise how {path} is written (or the file is already broken), so it was left alone — please edit that file yourself
|
|
266
270
|
settings_write_io: 'writing {path} failed: possibly no write permission, or the directory could not be created'
|
|
@@ -268,6 +272,8 @@ web:
|
|
|
268
272
|
mcp_unknown_server: This process has no MCP server named "{name}" — connections are built from mcp.json at startup, so the list you are holding may be stale. Refresh and look again.
|
|
269
273
|
skill_unknown: No skill named "{name}" — the capability page list may be stale. Refresh and look again.
|
|
270
274
|
provider_unknown: No provider named "{name}" is supported — the selectable set is a fixed list, so the one you are holding may be stale. Refresh and look again.
|
|
275
|
+
provider_key_not_applicable: '{name} does not use an API key — one stored here would never be read, and that provider already works as is'
|
|
276
|
+
provider_key_empty: No key received — paste it into the box and save. (There is no way to revoke an already-stored key from here yet; delete it from ~/.epoch or your keychain.)
|
|
271
277
|
mcp_add_lan_exposed: 'MCP servers cannot be added in this mode — the server was bound outside the loopback interface with --host, so we cannot tell whether the browser sending this request is on this machine. Adding one writes "which executable to launch" into mcp.json; that server is started right away, and every future epoch run on this machine (including the CLI and the TUI) starts it too. Two ways forward: edit that file directly on the machine running the server, or drop --host and restart.'
|
|
272
278
|
mcp_add_bad_transport: Transport must be one of stdio / sse / http
|
|
273
279
|
mcp_add_bad_name: The server name "{name}" cannot be used — it becomes part of the tool name verbatim, so only names starting with a letter or digit and made of letters, digits, _ and - are accepted (48 max). A hand-written mcp.json is not subject to this; only names added from the UI are.
|
|
@@ -301,6 +307,17 @@ web:
|
|
|
301
307
|
reference_store_unavailable: This machine has no session database (SQLite did not come up), so no historical session can be referenced
|
|
302
308
|
file_candidates_no_workspace: This session has no workspace bound, so no file list can be offered — pick a directory from the bar under the input box first
|
|
303
309
|
file_list_unavailable: The workspace file list could not be produced (no .git and not a readable directory), so completion is unavailable — typing the path still attaches the file
|
|
310
|
+
file_view_no_workspace: This session has no workspace bound, so no file can be shown — pick a directory from the bar under the input box first
|
|
311
|
+
file_view_missing_path: No file was named (path is missing)
|
|
312
|
+
file_view_denied: That file is outside the workspace, or a permission rule blocks it — what the model cannot read is not readable here either
|
|
313
|
+
file_view_missing: That file is no longer there
|
|
314
|
+
file_view_not_a_file: That is a directory, not a file
|
|
315
|
+
file_view_unreadable: That file could not be read (permission bits, a write in progress, or a disk problem)
|
|
316
|
+
file_view_too_large: That file is too large to view in place (limit {max} bytes) — open it with the default app, or download it
|
|
317
|
+
file_view_not_text: That is not a text file, so there is no body to fetch — images, PDFs and media go through the bytes route
|
|
318
|
+
file_open_extension_not_allowed: That kind of file is not handed to a system app — code and text are viewable in place, and "opening" an archive would extract it
|
|
319
|
+
file_open_not_same_machine: This browser is not on the machine running the server, so any window would open on someone else screen
|
|
320
|
+
file_open_launch_failed: The system app did not start
|
|
304
321
|
ui:
|
|
305
322
|
conn:
|
|
306
323
|
connecting: Connecting
|
|
@@ -327,10 +344,14 @@ web:
|
|
|
327
344
|
cav_no_tools: switched, but {model} does not support tool calls — it can only chat, and cannot read or write files
|
|
328
345
|
pick_provider: Provider
|
|
329
346
|
pick_provider_none: Pick one…
|
|
347
|
+
pick_model: Model name
|
|
348
|
+
suggest_open: See which models were found
|
|
330
349
|
provider_no_key: '{label} (no key configured)'
|
|
331
350
|
probe_probing: Asking {provider} which models it has… no need to wait — you can just type one above.
|
|
332
351
|
probe_no_key: No key configured for {provider}, so its model list cannot be fetched. Set {env}, or run epoch model.
|
|
333
352
|
probe_no_key_bare: No key configured for {provider}, so its model list cannot be fetched. Run epoch model to set one up.
|
|
353
|
+
probe_no_key_here: No key configured for {provider}, so its model list cannot be fetched — fill in the API Key box above.
|
|
354
|
+
key_goto: Configure it in settings
|
|
334
355
|
probe_failed_cache: Could not reach {provider} (network / bad key / that base URL has no /models). Below is what was fetched last time, which may be stale — you can also just type a name.
|
|
335
356
|
probe_failed_static: Could not reach {provider} (network / bad key / that base URL has no /models). Below is the built-in list, which may be stale — you can also just type a name.
|
|
336
357
|
probe_empty: '{provider} returned no model names at all, and the built-in list is empty too — just type one.'
|
|
@@ -338,11 +359,22 @@ web:
|
|
|
338
359
|
suggest_note: These are fetched suggestions, not the full set — new or self-hosted models will not be here. You can still just type one.
|
|
339
360
|
refresh: Re-fetch
|
|
340
361
|
refresh_hint: Bypass the cache and ask this provider again
|
|
362
|
+
key_label: API Key
|
|
363
|
+
key_placeholder: Paste a key here
|
|
364
|
+
key_save: Save key
|
|
365
|
+
key_saving: Saving key…
|
|
366
|
+
key_show: Show
|
|
367
|
+
key_hide: Hide
|
|
368
|
+
key_has: 'Configured: {hint} ({env}). Saving a new one overwrites it.'
|
|
369
|
+
key_none: This key goes into the system keychain when one is available, otherwise into ~/.epoch/.env (mode 0600). It is stored as {env}.
|
|
370
|
+
key_saved_secure: Stored in {backend} (encrypted). The model list has been re-fetched with the new key.
|
|
371
|
+
key_saved_plain: ⚠️ The system keychain was unavailable, so this key was stored in plaintext at {path} (mode 0600). Anyone who can read that file on this machine has the key.
|
|
341
372
|
newsession:
|
|
342
373
|
open: New session
|
|
343
374
|
dirpick:
|
|
344
375
|
back: Back
|
|
345
376
|
anchors: Common places
|
|
377
|
+
anchors_detail: Home, the server process directory, and workspaces you have visited
|
|
346
378
|
up: Up one level
|
|
347
379
|
loading: Loading…
|
|
348
380
|
empty: No subdirectories here — pick this one, or type a path below
|
|
@@ -350,7 +382,10 @@ web:
|
|
|
350
382
|
show_hidden: Show hidden directories (starting with .)
|
|
351
383
|
show_hidden_count: Show hidden directories (starting with ., {count} here)
|
|
352
384
|
unreadable: 'no permission to enter this directory: {path}'
|
|
353
|
-
|
|
385
|
+
into_of: Enter {name} ({path})
|
|
386
|
+
use: Use {name}
|
|
387
|
+
use_here: Use this folder
|
|
388
|
+
use_here_of: 'Use this folder: {path}'
|
|
354
389
|
known: visited
|
|
355
390
|
manual_label: Or type an absolute path
|
|
356
391
|
manual_hint: e.g. /Users/you/work/repo
|
|
@@ -363,14 +398,10 @@ web:
|
|
|
363
398
|
title: What would you like to do?
|
|
364
399
|
sidebar:
|
|
365
400
|
search: Search sessions
|
|
366
|
-
capability: Identities · Skills · Connectors
|
|
367
|
-
plugins: Plugins
|
|
368
401
|
automation: Automation
|
|
369
402
|
automation_pending: '{count} scheduled tasks are missing a grant; they will stall again on the next run'
|
|
370
403
|
settings: Settings
|
|
371
|
-
|
|
372
|
-
usage_session: Session usage
|
|
373
|
-
usage_run: Last run usage
|
|
404
|
+
host_menu: Host menu
|
|
374
405
|
cost: Spend
|
|
375
406
|
cost_of: ~${spent} / ${limit}
|
|
376
407
|
cost_est: Estimate
|
|
@@ -386,6 +417,7 @@ web:
|
|
|
386
417
|
running: Running
|
|
387
418
|
updated_at: Last active
|
|
388
419
|
count: '{count} sessions'
|
|
420
|
+
new_in_space: New session in “{name}”
|
|
389
421
|
empty: No sessions yet
|
|
390
422
|
no_match: No matching sessions
|
|
391
423
|
acts: Actions for “{title}”
|
|
@@ -457,6 +489,18 @@ web:
|
|
|
457
489
|
clip_lines: Only the first {shown} lines are shown; this file has {total} lines.
|
|
458
490
|
clip_chars: Cut off on line {line} — that line is too long. This file has {total} lines.
|
|
459
491
|
binary_note: These files cannot be viewed here — open them with the program your system uses.
|
|
492
|
+
file:
|
|
493
|
+
loading: Opening…
|
|
494
|
+
denied: That file is outside the workspace, or a permission rule blocks it — what the model cannot read is not viewable here either.
|
|
495
|
+
missing: That file is no longer there.
|
|
496
|
+
not_a_file: That is a directory, not a file.
|
|
497
|
+
too_large: That file is too large to view here.
|
|
498
|
+
unreadable: That file could not be read.
|
|
499
|
+
no_answer: The server gave no answer for that path.
|
|
500
|
+
no_session: No session yet, so no file can be shown.
|
|
501
|
+
opaque: The browser cannot render this kind of file. Open it with the default app on your machine, or download it.
|
|
502
|
+
open_with_app: Open with default app
|
|
503
|
+
download: Download
|
|
460
504
|
plan:
|
|
461
505
|
empty: No approved plan in this session yet
|
|
462
506
|
empty_hint: A plan the model hands in has to be approved once on the panel above the composer; only the approved one stays here.
|
|
@@ -506,7 +550,7 @@ web:
|
|
|
506
550
|
dismiss: Got it
|
|
507
551
|
session_gone: This conversation is gone on the server — most likely it restarted, and a restart starts a fresh session. This one is not coming back, but you can pick up in the new one.
|
|
508
552
|
session_gone_open: Go to the current session
|
|
509
|
-
session_gone_stuck: This conversation is gone on the server
|
|
553
|
+
session_gone_stuck: This conversation is gone on the server.
|
|
510
554
|
thread:
|
|
511
555
|
thinking_label: Reasoning
|
|
512
556
|
head_estimate: expected {tokens} tokens
|
|
@@ -539,6 +583,8 @@ web:
|
|
|
539
583
|
art_no_file: Not spooled to disk — this artifact cannot be opened.
|
|
540
584
|
art_download: Download {name}
|
|
541
585
|
art_download_any: Download this artifact
|
|
586
|
+
user_image_alt: Image attached to this message ({mediaType})
|
|
587
|
+
user_image_alt_any: Image attached to this message
|
|
542
588
|
expand: Expand {count} more lines
|
|
543
589
|
collapse: Collapse
|
|
544
590
|
todo_title: Delivery checklist
|
|
@@ -662,6 +708,7 @@ web:
|
|
|
662
708
|
stalled: “{title}” was going in circles and stopped
|
|
663
709
|
aborted: “{title}” was stopped mid-run
|
|
664
710
|
filtered: “{title}” was refused by the model
|
|
711
|
+
compliance: “{title}” ran into a content compliance limit
|
|
665
712
|
budget: “{title}” hit the budget cap and stopped early
|
|
666
713
|
failed: “{title}” hit an error
|
|
667
714
|
go: View
|
|
@@ -686,6 +733,9 @@ web:
|
|
|
686
733
|
placeholder_gone: This conversation is gone on the server; there is nothing to send to
|
|
687
734
|
hint_queue: to queue
|
|
688
735
|
send: Send
|
|
736
|
+
usage_session: Session
|
|
737
|
+
usage_run: Last run
|
|
738
|
+
usage_detail: '{scope} usage: {up}↑ {down}↓'
|
|
689
739
|
commands_label: Slash commands
|
|
690
740
|
command_warnings: 'A few things to know about how /{name} expanded:'
|
|
691
741
|
builtin_notice: /{name}
|
|
@@ -705,7 +755,8 @@ web:
|
|
|
705
755
|
workspace_pick_note: The list is the directories recently used on this machine. To start a session somewhere new, run epoch there once first.
|
|
706
756
|
workspace_browse: Open a local folder…
|
|
707
757
|
workspace_browse_detail: Walk down to a directory, or type an absolute path (lists directories on the machine running epoch)
|
|
708
|
-
|
|
758
|
+
workspace_browse_native: Opens a system dialog (on the machine running epoch)
|
|
759
|
+
permission: 'Permissions: {level}'
|
|
709
760
|
plan_mode: Plan mode
|
|
710
761
|
plan_on_hint: 'Enter plan mode: the model researches read-only and hands you a plan to approve; it touches no files meanwhile'
|
|
711
762
|
plan_off_hint: Leave plan mode and go back to the permission level you were on
|
|
@@ -757,6 +808,10 @@ web:
|
|
|
757
808
|
lvl_bypass: Skip every check
|
|
758
809
|
lvl_bypass_detail: Nothing is ever asked, and the whole rail turns red
|
|
759
810
|
blocked_managed: This machine has enterprise managed settings, and they turn off the "Skip every check" level. See Settings › Security centre for details
|
|
811
|
+
keep_env_pinned: 'This level applies to the current run only: EPOCH_PERMISSION overrides it, so the next start will use that instead'
|
|
812
|
+
keep_unwritable: 'This level applies to the current run only: your config file''s layout isn''t one this path recognises, so it was left alone'
|
|
813
|
+
keep_io: 'This level applies to the current run only: the config file could not be written (read-only disk, or no permission)'
|
|
814
|
+
keep_no_config: 'This level applies to the current run only: this process cannot tell where your user config file is'
|
|
760
815
|
fatal:
|
|
761
816
|
unauthorized: No access credential
|
|
762
817
|
unauthorized_hint: Go back to the terminal running epoch web and reopen the tokenised URL it printed.
|
|
@@ -768,6 +823,7 @@ web:
|
|
|
768
823
|
pane_model: Model & provider
|
|
769
824
|
pane_memory: Memory & context
|
|
770
825
|
pane_spend: Usage & spend
|
|
826
|
+
history_only: 'This session is history only — no engine is running it yet. Opening an old session just replays the conversation; the engine is built when you send your next message. This pane asks that engine for its current state, so there is nothing to show yet: go back to the session, send a message, and it will be picked back up.'
|
|
771
827
|
pane_budget: Budget
|
|
772
828
|
pane_tools: Tools
|
|
773
829
|
pane_about: About
|
|
@@ -793,8 +849,6 @@ web:
|
|
|
793
849
|
none_recorded: This conversation has run, but the per-turn records were never written down (the session predates the change that records them). The numbers will not come back.
|
|
794
850
|
g_total: Totals
|
|
795
851
|
g_turns: Per turn
|
|
796
|
-
total: Across {turns} turns, {tokens} tokens in total, about {cost}.
|
|
797
|
-
total_tokens: Across {turns} turns, {tokens} tokens in total.
|
|
798
852
|
total_unmeasured: This session ran {turns} turns, but no usage was ever reported, so there is not even a token total.
|
|
799
853
|
partial: The amount above only covers {priced} of those turns — the other {unpriced} reported usage, but the model they ran on has no pricing data. In the table below they are the rows with an empty cost cell.
|
|
800
854
|
unknown: 'The amount is unknown, not zero: the models used in these turns have no pricing data on this machine, so only the provider knows how much was really spent.'
|
|
@@ -805,7 +859,7 @@ web:
|
|
|
805
859
|
tok_output: Output
|
|
806
860
|
tok_reasoning: 'Of which reasoning: {n}. It is already included in the number above.'
|
|
807
861
|
tok_cache_note: Cache hits are priced separately, usually far below the full rate — the more hits, the cheaper the same amount of context.
|
|
808
|
-
col_turn:
|
|
862
|
+
col_turn: Turns
|
|
809
863
|
col_model: Model
|
|
810
864
|
col_tokens: Tokens
|
|
811
865
|
col_cost: Cost
|
|
@@ -820,6 +874,7 @@ web:
|
|
|
820
874
|
why: Why this value
|
|
821
875
|
chain_win: wins
|
|
822
876
|
g_other: Other
|
|
877
|
+
overridable_sum: Which keys upper layers can override
|
|
823
878
|
overridable: 'Only these keys can be overridden by the project, project-local, command-line or managed layers: {keys}. Every other setting has just two layers, built-in and user — putting one in .epoch/settings.json does nothing, and startup diagnostics will report it as an unknown config key.'
|
|
824
879
|
overridable_perm: The permissions entry on that list is three lists (allow / ask / deny) merged as a union rather than an override, so its provenance is per rule — see Security › Permission rules.
|
|
825
880
|
managed_locked: This one is set by the managed settings on this machine; changing it at the user or project level has no effect. That file is not writable by an ordinary user — ask an administrator.
|
|
@@ -828,12 +883,13 @@ web:
|
|
|
828
883
|
save: Save
|
|
829
884
|
new_value: New value
|
|
830
885
|
write_layer: Write to
|
|
886
|
+
write_file: Into file
|
|
831
887
|
dirty: Unsaved
|
|
832
888
|
futile_shadowed: 'Writing to {layer} will have no effect: {by} sets this too, and it ranks higher, so on load it overrides what you write here. To make it take effect, write to {by} or above.'
|
|
833
889
|
futile_untrusted: 'This workspace is not trusted yet, so settings in {layer} are dropped wholesale on load (deny rules are the one exception) — writing there does nothing. Trust the directory under Security › Workspace & trust first, or write to the user layer instead: it does not go through the trust gate.'
|
|
834
890
|
wrote: 'Written to {layer}: {value}'
|
|
835
891
|
wrote_stale: This process read the config once at startup and never re-reads it, so it is still using {value} — restarting epoch web is what switches it to the value you just wrote. Starting a new session will not do it either; the config is one per process.
|
|
836
|
-
lede_model:
|
|
892
|
+
lede_model: The model this process is using right now. Changing a row here writes to ~/.epoch/config.yaml. The provider and API key are not on this screen — run epoch model for those.
|
|
837
893
|
k_model: Main model
|
|
838
894
|
k_models_utility: Utility model
|
|
839
895
|
h_models_utility: Used for chores like compacting context and titling sessions. Unset means everything goes to the main model.
|
|
@@ -841,7 +897,7 @@ web:
|
|
|
841
897
|
k_fallback_providers: Fallback chain
|
|
842
898
|
h_fallback_providers: Tried in this order when the main provider is unreachable.
|
|
843
899
|
lede_memory: The first two decide how much fits in a turn and how many steps it may take; the last two decide what happens when it no longer fits. Setting a context window larger than the model really has buys you a 400.
|
|
844
|
-
k_context_length: Context window
|
|
900
|
+
k_context_length: Context window (tokens)
|
|
845
901
|
h_context_length: Only used as a fallback when the model metadata cannot be read; when it can, metadata wins and a configured value has no effect. The compression line below uses the window the engine actually runs on.
|
|
846
902
|
k_max_turns: Max steps per turn
|
|
847
903
|
h_max_turns: How many tool calls the model may make in one turn. On reaching the cap it stops and finishes its answer.
|
|
@@ -852,8 +908,7 @@ web:
|
|
|
852
908
|
ctx_line: With this configuration, compaction starts once the prompt reaches {tokens} tokens — {percent}% of the {window}-token context window.
|
|
853
909
|
ctx_line_caveat: That is the line itself. Just after a compaction, or once several compactions in a row have failed, crossing it will not compact yet.
|
|
854
910
|
ctx_off: Auto-compaction is off. When a long session hits the context window there is no automatic rescue — that turn simply fails, and the context does not shrink on its own. Manual /compact is unaffected by this switch and still works.
|
|
855
|
-
|
|
856
|
-
ctx_restart: Restart the epoch web process for this to take effect — it reads the config once at startup and never re-reads it.
|
|
911
|
+
ctx_not_overridable: 'These two rows can only be written to the user level: only three keys can be overridden by project-level config (the list below), and compaction is not one of them — otherwise a repository could quietly let long sessions opened inside it run into the window.'
|
|
857
912
|
budget_title: Where it is going right now
|
|
858
913
|
budget_used: '{used} used — {percent}% of the {limit} window.'
|
|
859
914
|
budget_used_only: '{used} used. This model has no known context window, so there is no percentage to report.'
|
|
@@ -863,13 +918,21 @@ web:
|
|
|
863
918
|
budget_compacting: Compacting…
|
|
864
919
|
budget_compact_hint: Rewrites earlier messages into a summary to free up window for what comes next. It sends one model request (so it costs money), but not a single line of this conversation is removed — only what gets sent to the model next turn changes.
|
|
865
920
|
lede_budget: Amounts only appear in the UI once a cap is configured. With no cap these rows read "Not set", which is also the default.
|
|
866
|
-
k_budget_max_cost: Spend cap
|
|
921
|
+
k_budget_max_cost: Spend cap (USD)
|
|
922
|
+
h_budget_max_cost: 'Accumulates per session — not a per-request cap — and --resume picks the count back up. The turn that crosses the line is not charged first and reported after: the gate stops it before the next request goes out.'
|
|
867
923
|
k_budget_max_tokens: Token cap
|
|
868
924
|
h_budget_max_tokens: With both rulers configured, the gate reports whichever is tighter.
|
|
869
925
|
k_budget_warn_at: Warn at
|
|
870
926
|
h_budget_warn_at: Percent. Warns once, on crossing — not every turn.
|
|
871
927
|
k_budget_unknown_pricing: When the model has no pricing data
|
|
872
928
|
h_budget_unknown_pricing: block stops the call, warn lets it through with a warning. With no pricing data the cost is "unknown", not 0, and the two must be handled separately.
|
|
929
|
+
ex_budget_max_cost: e.g. 5
|
|
930
|
+
ex_budget_max_tokens: e.g. 1000000
|
|
931
|
+
ex_budget_warn_at: e.g. 80
|
|
932
|
+
blocked_empty: This cannot be empty. Clearing it is not the same as removing the setting — this path has no delete-key at all; to get the default back, delete that line in the file named above.
|
|
933
|
+
blocked_pick: Pick one from the row above.
|
|
934
|
+
blocked_number: This takes a number, and "{text}" does not read as one. No unit, no thousands separators.
|
|
935
|
+
blocked_boolean: This takes exactly true or false — those are the two literals that go into the yaml.
|
|
873
936
|
sec:
|
|
874
937
|
lede: What this agent can touch right now, and what is holding it back.
|
|
875
938
|
no_session: 'No session yet. Three things here are bound per session: the workspace, its trust verdict, and the project-level policy directory that follows that trust — with no session there is no "which one" to answer.'
|
|
@@ -993,7 +1056,7 @@ web:
|
|
|
993
1056
|
audit_code_headless_unauthorized: Non-interactive, not pre-authorized
|
|
994
1057
|
audit_code_user_approved: You approved it
|
|
995
1058
|
audit_code_user_denied: You denied it
|
|
996
|
-
perm_where: '
|
|
1059
|
+
perm_where: 'Both come from the row under the composer: picking a level takes effect immediately and is recorded as the starting point below (written to ~/.epoch/config.yaml), which new sessions and the next start begin from.'
|
|
997
1060
|
perm_now: Now
|
|
998
1061
|
perm_default: Default
|
|
999
1062
|
perm_now_changed: (changed in this session)
|
|
@@ -1065,7 +1128,7 @@ web:
|
|
|
1065
1128
|
skill_unindexed: not in the index
|
|
1066
1129
|
skills_capped_note: '{count} skills are held out of the index by `skills.maxIndexed`: they cost nothing per turn, and the model cannot list them either. Raise or remove that setting to get them back.'
|
|
1067
1130
|
skills_role_note: '{count} skills are outside this session identity''s skill allowlist, so they are not indexed. ⚠️ That is not a lock: the bodies stay readable — narrowing is a context budget, not reachability.'
|
|
1068
|
-
no_toggle: 'There is no "turn this skill off" switch: as long as the file is in the directory, it gets picked up. To drop one,
|
|
1131
|
+
no_toggle: 'There is no "turn this skill off" switch: as long as the file is in the directory, it gets picked up. To drop one, use Delete on its row — that removes its directory for good; to just save context, `skills.maxIndexed` caps the index.'
|
|
1069
1132
|
import_entry: Import a skill
|
|
1070
1133
|
import_title: Import a skill
|
|
1071
1134
|
import_lede: Import from the machine running the server. Accepts a folder containing SKILL.md, a two-level category/name skill tree, a .zip of either, or a single .md with frontmatter.
|
|
@@ -1096,6 +1159,11 @@ web:
|
|
|
1096
1159
|
skill_view_no_count: Looking at this will not affect its score — that tally only counts times the model actually used it.
|
|
1097
1160
|
skill_truncated: This SKILL.md is large ({bytes} bytes in total); below is only the first stretch of it. Open the file directly to read the whole thing.
|
|
1098
1161
|
skill_bytes: '{bytes} bytes in total'
|
|
1162
|
+
skill_remove: Delete
|
|
1163
|
+
skill_remove_ask: Delete {name}? Its whole directory goes with it, and this cannot be undone.
|
|
1164
|
+
skill_remove_yes: Delete
|
|
1165
|
+
skill_cancel: Cancel
|
|
1166
|
+
skill_removed: 'Deleted {name}. This is the directory that was just removed:'
|
|
1099
1167
|
plugins: Plugins
|
|
1100
1168
|
plug_lede: 'A plugin is a bundle of extensions: slash commands, identities, skills, hooks, deny rules, MCP servers. Pick one from a marketplace already added on this machine — this page can only pick from that list; it cannot take a path and cannot upload a file.'
|
|
1101
1169
|
plug_installed_head: Installed ({count})
|
|
@@ -1297,6 +1365,9 @@ web:
|
|
|
1297
1365
|
how_to_block: To block a tool, add a deny rule to the permission table. Rules only count once they are in a config file, and this interface never writes config — the security centre shows which rules exist today and which layer each came from.
|
|
1298
1366
|
goto_rules: Open the rule table
|
|
1299
1367
|
mcp_note: Tools from MCP servers are in this table too, named mcp__<server>__<tool>. The Source column says which server each one came from.
|
|
1368
|
+
tip:
|
|
1369
|
+
what: What this is
|
|
1370
|
+
about: About {name}
|
|
1300
1371
|
about:
|
|
1301
1372
|
loading: Reading…
|
|
1302
1373
|
lede: When something goes wrong, paste a screenshot of this into the issue — it beats describing the symptoms.
|
|
@@ -1422,15 +1493,26 @@ web:
|
|
|
1422
1493
|
remove_confirm: Delete "{name}"? Its registration in the OS scheduler goes with it. Run recordings are kept.
|
|
1423
1494
|
form_new: New scheduled task
|
|
1424
1495
|
form_edit: Edit scheduled task
|
|
1496
|
+
g_what: What it does
|
|
1497
|
+
g_what_note: The thing it runs when the time comes
|
|
1498
|
+
g_where: Where it runs
|
|
1499
|
+
g_where_note: Both optional — each has a definite default
|
|
1500
|
+
g_when: When it runs
|
|
1501
|
+
g_may: What it may do
|
|
1502
|
+
g_may_note: This group decides which confirmations it presses for you at night
|
|
1503
|
+
g_cost: How much it may spend
|
|
1504
|
+
g_cost_note: Three limits; hitting any one stops the run
|
|
1505
|
+
required: Required
|
|
1425
1506
|
f_name: Name
|
|
1426
1507
|
f_prompt: Prompt
|
|
1427
1508
|
f_prompt_hint: What the agent should do when it fires. Say what it should leave behind — nobody will be there to ask.
|
|
1428
1509
|
f_workdir: Workspace (optional)
|
|
1429
|
-
|
|
1430
|
-
f_workdir_note: Left empty, it runs in ~/.epoch/automation/<task id>/. It does **not** inherit any terminal's current directory.
|
|
1510
|
+
f_workdir_note: Left empty, it runs in ~/.epoch/automation/<task id>/. It never inherits any terminal's current directory.
|
|
1431
1511
|
f_workdir_default: ~/.epoch/automation/<task id>/
|
|
1512
|
+
f_workdir_none: No specific workspace
|
|
1432
1513
|
f_model: Model (optional)
|
|
1433
1514
|
f_model_hint: Empty uses the configured one
|
|
1515
|
+
f_model_provider_note: Whichever provider you pick is saved with the task and used when it fires. If that provider has no key on this machine at fire time, the run falls back to the default model and records a line about it.
|
|
1434
1516
|
f_kind: Frequency
|
|
1435
1517
|
k_daily: Daily
|
|
1436
1518
|
k_weekly: Weekly
|
|
@@ -1446,11 +1528,14 @@ web:
|
|
|
1446
1528
|
f_days_note: The 31st does not fire in short months — that is the native behaviour on both platforms.
|
|
1447
1529
|
f_start: Active from (optional)
|
|
1448
1530
|
f_end: Active until (optional)
|
|
1531
|
+
f_window_note: Both ends are inclusive. Leave an end blank and that end is unbounded. Firings that fall outside the range are recorded as "skipped (outside active range)" and are not made up later.
|
|
1532
|
+
f_window_once: A run-once task cannot carry an active range — it already is a single date, so these two cannot be filled in on this kind.
|
|
1449
1533
|
f_permission: Permission level
|
|
1450
1534
|
f_bypass_ack: 'I understand: this task will do anything without asking inside {workDir}, including deleting files and running arbitrary commands.'
|
|
1451
1535
|
f_turns: Max turns
|
|
1536
|
+
f_turns_hint: How many times the model may call a tool in one turn, 1 to 1000. On hitting the cap it stops and finishes its answer.
|
|
1452
1537
|
f_timeout: Timeout (minutes)
|
|
1453
|
-
f_timeout_note: The only ruler that catches "a command hung" — turns and spend both stop growing there.
|
|
1538
|
+
f_timeout_note: The only ruler that catches "a command hung" — turns and spend both stop growing there. 24 hours at most.
|
|
1454
1539
|
f_budget: Max spend per run (USD)
|
|
1455
1540
|
f_budget_why: 'Required, and we give no default: nobody is watching this task, and a fake default would make "woke up to $40" our fault.'
|
|
1456
1541
|
save_and_run: Save and run once
|
|
@@ -1800,6 +1885,8 @@ skill:
|
|
|
1800
1885
|
import_bad_name_dots: A skill name cannot be . or ..
|
|
1801
1886
|
import_bad_name_char: 'The skill name "{name}" contains characters that cannot be used in a directory name (< > : " / \ | ? * and control characters). The colon in particular separates the plugin/host prefix — a user-level skill taking it would masquerade as a plugin skill'
|
|
1802
1887
|
import_bad_name_trailing: The skill name "{name}" ends with a dot or a space — on Windows such a directory can be created but not opened
|
|
1888
|
+
remove_no_system: The skill system did not start this run — no skills are loaded in this process, so there is nothing to delete. Check the Skill entries in the startup diagnostics
|
|
1889
|
+
remove_unknown: There is no skill named "{name}" — the list you are looking at may be stale; refresh it
|
|
1803
1890
|
host_capabilities:
|
|
1804
1891
|
loaded: '{namespace}: {roles} identity/identities, {skillDirs} skill directory/directories, {mcpServers} MCP server(s), {tools} tool(s) (the first two get the {namespace}: prefix, the last two get {namespace}__ — both end up inside a tool name, and tool names cannot contain a colon)'
|
|
1805
1892
|
bad_role_name: Identity "{name}" has an invalid name (lowercase letters, digits and hyphens only, and it may not start with a hyphen); that one was skipped, the rest were injected as usual
|
|
@@ -1934,6 +2021,7 @@ mcp_write:
|
|
|
1934
2021
|
invalid: the configuration is not valid
|
|
1935
2022
|
mcp_config:
|
|
1936
2023
|
invalid_json: 'Nothing was written — this content is not valid JSON: {why}'
|
|
2024
|
+
stale_disk: nothing was written — ~/.epoch/mcp.json changed while this edit was being computed; read it again and redo the change
|
|
1937
2025
|
role_write:
|
|
1938
2026
|
bad_name: The identity name "{name}" cannot be used — lowercase letters, digits and hyphens only, and it may not start with a hyphen. This name is both the file name and the word used to delegate work (the `role` argument of delegate_task, the value of --agent), which is why it is validated strictly.
|
|
1939
2027
|
taken: 'There is already an identity named "{name}" — pick another name. Nothing is overwritten and nothing is auto-renamed here: overwriting would delete the prose you wrote in that file, and renaming would make the word used to delegate work disagree with what you typed.'
|
|
@@ -2073,6 +2161,7 @@ provider:
|
|
|
2073
2161
|
label_openai_compatible: OpenAI Compatible (generic adapter)
|
|
2074
2162
|
response_format_with_tools: 'A single request cannot ask for both tools and responseFormat: the model either calls tools or emits one JSON document, pick one'
|
|
2075
2163
|
response_format_dropped: '{model} did not honour this round''s forced-JSON constraint (the request was still sent), so this round''s output may not be JSON'
|
|
2164
|
+
key_not_applicable: '{provider} does not use an API key — one stored here would never be read'
|
|
2076
2165
|
utility:
|
|
2077
2166
|
aborted: This one-shot completion was aborted before it was sent (not sent, not billed)
|
|
2078
2167
|
terminal_setup:
|
|
@@ -3125,6 +3214,7 @@ untrusted:
|
|
|
3125
3214
|
skipped: The workspace is not trusted, so project {what} were not loaded (epoch trust can trust this directory)
|
|
3126
3215
|
what_commands: commands
|
|
3127
3216
|
what_policy: policy rules
|
|
3217
|
+
what_compliance: compliance lexicons
|
|
3128
3218
|
what_skills: skills
|
|
3129
3219
|
what_roles: roles
|
|
3130
3220
|
hooks_tail: The workspace is not trusted, so project hooks were not loaded (epoch trust can trust this directory) — hooks run commands, and there is no "the narrowing part still applies" exception here
|
|
@@ -3181,6 +3271,40 @@ policy_load:
|
|
|
3181
3271
|
not_kv: 'Neither [[rule]] nor key = "value"; ignored: {preview}'
|
|
3182
3272
|
before_first_rule: '{key} appears before the first [[rule]]; ignored'
|
|
3183
3273
|
rule_skipped: '{message}; this rule was skipped'
|
|
3274
|
+
compliance_cmd:
|
|
3275
|
+
cmd_root: Self-check for the content compliance gate
|
|
3276
|
+
cmd_check: Check whether a piece of text would be blocked, and which characters matched
|
|
3277
|
+
cmd_status: Show the current state on this machine (switches, rule counts, per-category action)
|
|
3278
|
+
arg_text: the text to check
|
|
3279
|
+
opt_stdin: read from standard input (useful for checking a whole file)
|
|
3280
|
+
need_text: Check what? Pass some text, or add --stdin to read from standard input
|
|
3281
|
+
disabled: 'Content compliance is not enabled (compliance.enabled: false), so nothing is checked'
|
|
3282
|
+
clean: 'Clean: nothing matched'
|
|
3283
|
+
verdict: 'Verdict: {action}, {count} matches'
|
|
3284
|
+
hit: ' [{category}] {action} <- {excerpt} (rule {rule})'
|
|
3285
|
+
blocked: 'This is the block tier: on the input side the request is never sent (and never billed); with the output side enabled, the sentence that matched never reaches the screen'
|
|
3286
|
+
released: 'After filtering: {text}'
|
|
3287
|
+
status_enabled: 'Enabled: {enabled}'
|
|
3288
|
+
status_rules: 'Rules: {active} active ({builtin} built-in + {user} from your lexicons)'
|
|
3289
|
+
status_dir: 'User lexicon directory: {dir}'
|
|
3290
|
+
status_scope: 'Channels: output {output} / input {input} / skip code {code}'
|
|
3291
|
+
status_action: ' {category} -> {action}'
|
|
3292
|
+
status_project_note: 'Note: project-level lexicons (<project root>/.epoch/compliance/) go through the workspace trust gate, and this command does not read them — a real session does'
|
|
3293
|
+
compliance:
|
|
3294
|
+
category_sep: ', '
|
|
3295
|
+
category:
|
|
3296
|
+
sexual: sexual content
|
|
3297
|
+
political: political / national security
|
|
3298
|
+
hate: ethnic or racial discrimination
|
|
3299
|
+
violence: violence and terrorism
|
|
3300
|
+
illegal: illegal activity
|
|
3301
|
+
self_harm: self-harm
|
|
3302
|
+
privacy: personal sensitive data
|
|
3303
|
+
compliance_load:
|
|
3304
|
+
dir_read_failed: 'Could not read the compliance lexicon directory: {reason}'
|
|
3305
|
+
file_read_failed: 'Could not read it, so the whole file was skipped: {reason}'
|
|
3306
|
+
unknown_file: 'The file name is not a category name, so the whole file was skipped. Known categories: {categories} (regexes go in <category>.regex.txt, exemptions in exempt.txt)'
|
|
3307
|
+
bad_regex: 'The regex did not compile, so this entry was skipped: {reason}'
|
|
3184
3308
|
skill_load:
|
|
3185
3309
|
degraded: '{message}; loaded as if it had no frontmatter'
|
|
3186
3310
|
not_a_map: The frontmatter is not key/value pairs (the top level has to be a YAML object); loaded as if it had no frontmatter
|
|
@@ -3283,7 +3407,12 @@ context_breakdown:
|
|
|
3283
3407
|
agent_run:
|
|
3284
3408
|
error: 'Error: {message}'
|
|
3285
3409
|
images_unsupported: The current model does not support image input, so this request was cancelled (not sent, not billed). Switch to a vision-capable model (gpt-4o / claude-sonnet-4-6 / gemini-2.5-flash), or drop the {count} images and retry.
|
|
3410
|
+
images_dropped: '{provider} dropped the {count} images in this turn (its own words: {feature}), so the model never saw them — do not trust this turn''s answer. The request was sent and billed. Most likely this provider''s SDK version cannot carry images yet, or this model does not actually accept them.'
|
|
3411
|
+
images_dropped_provider_unknown: The current provider
|
|
3286
3412
|
content_filter: The model refused to respond for safety reasons; try asking a different way.
|
|
3413
|
+
compliance_output: This reply ran into a content compliance limit ({categories}), so output stopped.
|
|
3414
|
+
compliance_input: Your message ran into a content compliance limit ({categories}); the request was not sent and nothing was billed.
|
|
3415
|
+
compliance_input_masked: Your message contained wording that runs into a content compliance limit ({categories}), so it was masked before being sent — the model did not see the text exactly as it appears on your screen.
|
|
3287
3416
|
stalled: 'Detected a loop: {info}. The task was terminated.'
|
|
3288
3417
|
stall_info: '{tool}({args}) was called {count} turns in a row, which looks like a loop'
|
|
3289
3418
|
max_turns: Reached the maximum of {max} turns; the task was terminated unfinished.
|
|
@@ -3472,6 +3601,7 @@ secret:
|
|
|
3472
3601
|
infra_misc:
|
|
3473
3602
|
shell_not_on_path: 'shell: the configured {kind} ({exe}) is not on PATH; fell back to cmd.exe'
|
|
3474
3603
|
ripgrep_install_windows: winget install BurntSushi.ripgrep.MSVC (or scoop install ripgrep)
|
|
3604
|
+
ripgrep_chmod_hint: chmod +x "{path}" — prefix with sudo if that directory is root-owned
|
|
3475
3605
|
schema_failed: '{path} failed validation ({count} problems):\n{detail}'
|
|
3476
3606
|
schema_more: '{count} more problems not listed'
|
|
3477
3607
|
schema_unknown_key: Unknown setting, ignored (other settings still apply)
|
|
@@ -3517,6 +3647,9 @@ boot:
|
|
|
3517
3647
|
managed_hooks_only: Managed enterprise settings turned on allowManagedHooksOnly, so neither user-level nor project-level hooks load ({path})
|
|
3518
3648
|
policy_load_failed: loading failed (skipped)
|
|
3519
3649
|
perm_rules: '{total} permission rules (allow {allow} / ask {ask} / deny {deny})'
|
|
3650
|
+
compliance_ready: '{active} rules active ({builtin} built-in + {external} from lexicon files)'
|
|
3651
|
+
compliance_off: 'not enabled (compliance.enabled: false)'
|
|
3652
|
+
compliance_load_failed: the external lexicons could not be loaded, so only the built-in seed list is in use
|
|
3520
3653
|
commands_all_failed: None of the {count} files could be loaded, so there are no usable custom commands
|
|
3521
3654
|
command_allowed_tools: '{tools} in the allowed-tools of {name} do not exist and were ignored'
|
|
3522
3655
|
tools_cost: '{count} tools ({split}) ≈ {tokens}k tokens/turn'
|
|
@@ -3526,6 +3659,7 @@ boot:
|
|
|
3526
3659
|
shell_kind: '{kind} (terminal tool commands are handed to it)'
|
|
3527
3660
|
plugin_register_failed: registration failed ({reason})
|
|
3528
3661
|
ripgrep_missing: not installed, so file_search is unavailable ({hint})
|
|
3662
|
+
ripgrep_not_executable: shipped but not executable, so file_search is unavailable for now ({hint})
|
|
3529
3663
|
ripgrep_system: using the system rg
|
|
3530
3664
|
ripgrep_builtin: using the bundled rg{version}
|
|
3531
3665
|
mcp_none: not configured (~/.epoch/mcp.json is missing or empty)
|