@monster-orange/den 0.4.22 → 0.4.24
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/CHANGELOG.md +73 -0
- package/docs/distributions.md +91 -30
- package/package.json +1 -1
- package/service/install.sh +5 -3
- package/src/shared/agents/guardrails/rotation-hook.ts +5 -0
- package/src/shared/agents/rotate-settings.ts +309 -0
- package/src/shared/agents/rotation.ts +110 -5
- package/src/shared/den-config.ts +27 -12
- package/src/ui/cli/agent-ops.ts +514 -15
- package/src/ui/cli/agents-command.ts +169 -3
- package/src/ui/cli/doctor-command.ts +24 -1
- package/src/ui/cli/doctor-where.ts +59 -13
- package/src/ui/cli/server-agent-ops.ts +2 -2
- package/src/ui/cli/web-command.ts +32 -5
- package/src/ui/cli/web-service.ts +160 -0
- package/src/ui/server/agent-routes.ts +161 -5
- package/src/ui/server/index.ts +13 -5
- package/src/ui/server/public/agents-page.js +214 -22
- package/src/ui/server/public/agents.html +32 -0
- package/src/ui/server/public/combobox.js +150 -0
- package/src/ui/server/public/error-page.js +26 -14
- package/src/ui/server/public/i18n/es.js +47 -4
- package/src/ui/server/public/i18n/ja.js +43 -4
- package/src/ui/server/public/settings-registry.js +318 -0
- package/src/ui/server/public/settings.html +166 -4
- package/src/ui/server/public/shell.js +62 -16
- package/src/ui/server/public/svc-panel.js +54 -15
- package/src/ui/server/route-classes.ts +21 -0
- package/src/ui/server/session-routes.ts +23 -5
- package/src/ui/server/ui-assets.ts +2 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A searchable picker (D30): a text field (role=combobox) over a listbox.
|
|
3
|
+
* Type to filter (the command palette's ranking, rankCommands), ↑/↓ to
|
|
4
|
+
* move, Enter (or a click) picks, Esc closes. What is picked is an id; what
|
|
5
|
+
* is shown is its name. One shared control, so a form never asks a person
|
|
6
|
+
* to type an id.
|
|
7
|
+
*
|
|
8
|
+
* comboHtml({ id, label, placeholder }) the markup (a <label>, the
|
|
9
|
+
* field, its list)
|
|
10
|
+
* wireCombo(root, id, { items, onPick }) makes it work; items() is read
|
|
11
|
+
* each time it opens, so it
|
|
12
|
+
* follows live data. Returns
|
|
13
|
+
* { value(), set(id), clear() }.
|
|
14
|
+
*
|
|
15
|
+
* An item: { id, label, sub?, keywords?, off? } (off: shown, not pickable).
|
|
16
|
+
*/
|
|
17
|
+
import { rankCommands } from "./topbar.js";
|
|
18
|
+
|
|
19
|
+
const esc = (s) =>
|
|
20
|
+
String(s ?? "").replace(
|
|
21
|
+
/[&<>"']/g,
|
|
22
|
+
(c) =>
|
|
23
|
+
({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[
|
|
24
|
+
c
|
|
25
|
+
],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export function comboHtml({ id, label, placeholder = "" }) {
|
|
29
|
+
return (
|
|
30
|
+
`<span class="den-combo" data-combo="${esc(id)}">` +
|
|
31
|
+
`<label for="${esc(id)}">${esc(label)}</label>` +
|
|
32
|
+
`<span class="den-combo-box">` +
|
|
33
|
+
`<input type="text" id="${esc(id)}" role="combobox" aria-expanded="false" aria-controls="${esc(id)}-list" aria-autocomplete="list" autocomplete="off" spellcheck="false" placeholder="${esc(placeholder)}">` +
|
|
34
|
+
`<ul id="${esc(id)}-list" role="listbox" aria-label="${esc(label)}" class="den-combo-list" hidden></ul>` +
|
|
35
|
+
`</span></span>`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Rows ranked for `q` (every item when it is empty). */
|
|
40
|
+
export function comboMatches(items, q) {
|
|
41
|
+
const list = items.map((x) => ({
|
|
42
|
+
...x,
|
|
43
|
+
keywords: [x.id, x.sub ?? "", ...(x.keywords ?? [])],
|
|
44
|
+
}));
|
|
45
|
+
return rankCommands(list, q, { limit: 50, emptyLimit: 50 });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function wireCombo(root, id, { items, onPick }) {
|
|
49
|
+
const input = root.querySelector(`#${CSS.escape(id)}`);
|
|
50
|
+
const ul = root.querySelector(`#${CSS.escape(id)}-list`);
|
|
51
|
+
if (!input || !ul) return null;
|
|
52
|
+
let picked = "";
|
|
53
|
+
let shown = [];
|
|
54
|
+
let sel = 0;
|
|
55
|
+
const close = () => {
|
|
56
|
+
ul.hidden = true;
|
|
57
|
+
input.setAttribute("aria-expanded", "false");
|
|
58
|
+
input.removeAttribute("aria-activedescendant");
|
|
59
|
+
};
|
|
60
|
+
const draw = () => {
|
|
61
|
+
shown = comboMatches(
|
|
62
|
+
items(),
|
|
63
|
+
input.value === labelOf(picked) ? "" : input.value,
|
|
64
|
+
);
|
|
65
|
+
sel = Math.min(sel, Math.max(0, shown.length - 1));
|
|
66
|
+
ul.innerHTML = shown.length
|
|
67
|
+
? shown
|
|
68
|
+
.map(
|
|
69
|
+
(x, i) =>
|
|
70
|
+
`<li role="option" id="${esc(id)}-o-${i}" data-i="${i}" aria-selected="${i === sel}"${x.off ? ' aria-disabled="true"' : ""}>` +
|
|
71
|
+
`<span class="den-combo-l">${esc(x.label)}</span>` +
|
|
72
|
+
(x.sub ? `<span class="den-combo-s">${esc(x.sub)}</span>` : "") +
|
|
73
|
+
`</li>`,
|
|
74
|
+
)
|
|
75
|
+
.join("")
|
|
76
|
+
: `<li class="den-combo-none" aria-disabled="true">No match</li>`;
|
|
77
|
+
ul.hidden = false;
|
|
78
|
+
input.setAttribute("aria-expanded", "true");
|
|
79
|
+
if (shown.length)
|
|
80
|
+
input.setAttribute("aria-activedescendant", `${id}-o-${sel}`);
|
|
81
|
+
ul.querySelector(`[data-i="${sel}"]`)?.scrollIntoView?.({
|
|
82
|
+
block: "nearest",
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
const labelOf = (v) => items().find((x) => x.id === v)?.label ?? "";
|
|
86
|
+
const pick = (x) => {
|
|
87
|
+
if (!x || x.off) return;
|
|
88
|
+
picked = x.id;
|
|
89
|
+
input.value = x.label;
|
|
90
|
+
input.dataset.value = x.id;
|
|
91
|
+
close();
|
|
92
|
+
onPick?.(x);
|
|
93
|
+
};
|
|
94
|
+
input.addEventListener("focus", () => {
|
|
95
|
+
sel = 0;
|
|
96
|
+
draw();
|
|
97
|
+
});
|
|
98
|
+
input.addEventListener("input", () => {
|
|
99
|
+
picked = "";
|
|
100
|
+
delete input.dataset.value;
|
|
101
|
+
sel = 0;
|
|
102
|
+
draw();
|
|
103
|
+
});
|
|
104
|
+
input.addEventListener("keydown", (e) => {
|
|
105
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
106
|
+
e.preventDefault();
|
|
107
|
+
if (ul.hidden) return draw();
|
|
108
|
+
const n = shown.length;
|
|
109
|
+
if (!n) return;
|
|
110
|
+
sel = (sel + (e.key === "ArrowDown" ? 1 : n - 1)) % n;
|
|
111
|
+
draw();
|
|
112
|
+
} else if (e.key === "Enter") {
|
|
113
|
+
if (ul.hidden) return;
|
|
114
|
+
e.preventDefault();
|
|
115
|
+
pick(shown[sel]);
|
|
116
|
+
} else if (e.key === "Escape") {
|
|
117
|
+
if (!ul.hidden) {
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
e.stopPropagation();
|
|
120
|
+
close();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// mousedown, not click: the field keeps its focus (no blur close first).
|
|
125
|
+
ul.addEventListener("mousedown", (e) => {
|
|
126
|
+
const li = e.target.closest?.("[data-i]");
|
|
127
|
+
if (!li) return;
|
|
128
|
+
e.preventDefault();
|
|
129
|
+
pick(shown[Number(li.dataset.i)]);
|
|
130
|
+
});
|
|
131
|
+
input.addEventListener("blur", () => {
|
|
132
|
+
close();
|
|
133
|
+
// Leaving with a half-typed name: back to what was picked.
|
|
134
|
+
if (input.value !== labelOf(picked)) input.value = labelOf(picked);
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
value: () => picked,
|
|
138
|
+
set: (v) => {
|
|
139
|
+
picked = v;
|
|
140
|
+
input.value = labelOf(v);
|
|
141
|
+
if (v) input.dataset.value = v;
|
|
142
|
+
else delete input.dataset.value;
|
|
143
|
+
},
|
|
144
|
+
clear: () => {
|
|
145
|
+
picked = "";
|
|
146
|
+
input.value = "";
|
|
147
|
+
delete input.dataset.value;
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
@@ -305,10 +305,15 @@ function githubBlock(s, t) {
|
|
|
305
305
|
|
|
306
306
|
/**
|
|
307
307
|
* D17: a Den with no owner yet that a rule lets someone claim. It leads the
|
|
308
|
-
* page: Connect your GitHub account.
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
308
|
+
* page: Connect your GitHub account.
|
|
309
|
+
*
|
|
310
|
+
* - "Sign in as @login" (web.owner_github) works from any browser: when
|
|
311
|
+
* it is there, it is the primary button.
|
|
312
|
+
* - The localhost trip (web.allowed_github_org) only works in a browser
|
|
313
|
+
* on the machine Den runs on, so its button says so ("On <host>
|
|
314
|
+
* itself: connect GitHub"), never a footnote (D29).
|
|
315
|
+
* - Only the org rule: the page says to open it on <host>, or to set
|
|
316
|
+
* web.owner_github to sign in from anywhere.
|
|
312
317
|
*/
|
|
313
318
|
function claimBlock(s, t) {
|
|
314
319
|
const g = s.github;
|
|
@@ -316,24 +321,31 @@ function claimBlock(s, t) {
|
|
|
316
321
|
const host = s.machine || "";
|
|
317
322
|
const back = location.origin + location.pathname + location.search;
|
|
318
323
|
const here = g.attest ? `${g.attest}?return=${encodeURIComponent(back)}` : "";
|
|
324
|
+
const as = g.ownerGithub
|
|
325
|
+
? `<button type="button" class="btn primary" id="den-gh-start">${esc(t("err.signin.claimAs", { login: g.ownerGithub }))}</button>`
|
|
326
|
+
: "";
|
|
327
|
+
const hereBtn = here
|
|
328
|
+
? `<a class="btn${as ? "" : " primary"}" id="den-claim-here" href="${esc(here)}">${
|
|
329
|
+
host
|
|
330
|
+
? withHost(t, "err.signin.claimHereOn", { host })
|
|
331
|
+
: esc(t("err.signin.claimHere"))
|
|
332
|
+
}</a>`
|
|
333
|
+
: "";
|
|
319
334
|
return (
|
|
320
335
|
`<div id="den-gh" class="den-claim">` +
|
|
321
336
|
`<h2 class="den-h" id="den-claim-title">${esc(t("err.signin.claimTitle"))}</h2>` +
|
|
322
337
|
`<p class="lead" id="den-claim-lead">${esc(t("err.signin.claimLead", { name: s.name || "Den" }))}</p>` +
|
|
323
338
|
(g.org
|
|
324
|
-
? `<p id="den-claim-org">${withHost(
|
|
339
|
+
? `<p id="den-claim-org">${withHost(
|
|
340
|
+
t,
|
|
341
|
+
g.ownerGithub ? "err.signin.claimOrg" : "err.signin.claimOrgOnly",
|
|
342
|
+
{ org: g.org, host },
|
|
343
|
+
)}</p>`
|
|
325
344
|
: "") +
|
|
326
345
|
`<div class="acts" style="margin-top:0">` +
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
: "") +
|
|
330
|
-
(g.ownerGithub
|
|
331
|
-
? `<button type="button" class="btn${here ? "" : " primary"}" id="den-gh-start">${esc(t("err.signin.claimAs", { login: g.ownerGithub }))}</button>`
|
|
332
|
-
: "") +
|
|
346
|
+
as +
|
|
347
|
+
hereBtn +
|
|
333
348
|
`</div><div id="den-gh-flow" aria-live="polite"></div>` +
|
|
334
|
-
(here
|
|
335
|
-
? `<p class="den-gh-note" id="den-claim-note">${withHost(t, "err.signin.claimHereNote", { host })}</p>`
|
|
336
|
-
: "") +
|
|
337
349
|
`</div>`
|
|
338
350
|
);
|
|
339
351
|
}
|
|
@@ -311,9 +311,10 @@
|
|
|
311
311
|
"err.signin.claimOrg":
|
|
312
312
|
"Los miembros de la organización {org} de GitHub pueden reclamarlo, en un navegador en {host}.",
|
|
313
313
|
"err.signin.claimHere": "Este es mi ordenador: conectar GitHub",
|
|
314
|
+
"err.signin.claimHereOn": "En {host}: conectar GitHub",
|
|
315
|
+
"err.signin.claimOrgOnly":
|
|
316
|
+
"Los miembros de la organización {org} de GitHub pueden reclamarlo desde un navegador en {host}. Abre esta página en {host}, o define web.owner_github para iniciar sesión desde cualquier sitio.",
|
|
314
317
|
"err.signin.claimAs": "Iniciar sesión como @{login}",
|
|
315
|
-
"err.signin.claimHereNote":
|
|
316
|
-
"«Este es mi ordenador» solo funciona en un navegador en {host}. En otro sitio no abre nada.",
|
|
317
318
|
"err.signin.claimChecking": "Comprobando que esto es {host}…",
|
|
318
319
|
"err.signin.githubRefused":
|
|
319
320
|
"@{login} no es el propietario de este {name}. Solo la cuenta del propietario puede usar Iniciar sesión con GitHub. Usa «Aprueba este ordenador» en su lugar.",
|
|
@@ -487,9 +488,50 @@
|
|
|
487
488
|
"Su sesión rotó ({why}), pero no escribió handoff.md. Reanúdalo para que lo escriba, o empieza de cero.",
|
|
488
489
|
"ag.rot.badHandoff":
|
|
489
490
|
"Su sesión rotó ({why}), pero su handoff.md no está completo. Reanúdalo para arreglarlo, o empieza de cero.",
|
|
490
|
-
"ag.relaunch": "Relanzar
|
|
491
|
-
"ag.relaunchName": "Relanzar {id}
|
|
491
|
+
"ag.relaunch": "Relanzar ahora",
|
|
492
|
+
"ag.relaunchName": "Relanzar {id} ahora",
|
|
492
493
|
"ag.relaunched": "{id} relanzado desde su traspaso",
|
|
494
|
+
"ag.rc.autoAsk":
|
|
495
|
+
"Toca rotar ({why}). Den le pide el traspaso cuando esté libre y luego lo relanza.",
|
|
496
|
+
"ag.rc.autoReady":
|
|
497
|
+
"Toca rotar ({why}). Su traspaso está listo: Den lo relanza cuando esté libre.",
|
|
498
|
+
"ag.rc.ready": "Toca rotar ({why}). Su traspaso está listo.",
|
|
499
|
+
"ag.rc.missing": "Toca rotar ({why}). Aún no tiene traspaso.",
|
|
500
|
+
"ag.rc.bad": "Toca rotar ({why}). Su traspaso no está completo.",
|
|
501
|
+
"ag.rc.fellBack":
|
|
502
|
+
"Toca rotar ({why}). No escribió el traspaso tras pedírselo 2 veces.",
|
|
503
|
+
"ag.rc.wanted":
|
|
504
|
+
"Toca rotar ({why}). Den lo relanza en cuanto escriba su traspaso.",
|
|
505
|
+
"ag.rc.write": "Escribir traspaso",
|
|
506
|
+
"ag.rc.writeName": "Pedir a {id} que escriba su traspaso",
|
|
507
|
+
"ag.rc.keep": "Mantener esta conversación",
|
|
508
|
+
"ag.rc.keepName": "Mantener la conversación de {id}",
|
|
509
|
+
"ag.rc.never": "No volver a preguntar para este agente",
|
|
510
|
+
"ag.rc.settings": "Ajustes",
|
|
511
|
+
"ag.rc.from":
|
|
512
|
+
"Rota tras {n} compactaciones ({src}); al tocar: {mode} ({src2})",
|
|
513
|
+
"ag.rc.fellBackBad":
|
|
514
|
+
"Toca rotar ({why}). Su traspaso sigue sin pasar la revisión tras pedírselo 2 veces.",
|
|
515
|
+
"ag.rc.from.one":
|
|
516
|
+
"Rota tras {n} compactación ({src}); al tocar: {mode} ({src2})",
|
|
517
|
+
"ag.rc.fromNever": "Nunca rota ({src}); al tocar: {mode} ({src2})",
|
|
518
|
+
"ag.rc.midTurn":
|
|
519
|
+
"{id} está a mitad de turno: pídelo de nuevo cuando termine",
|
|
520
|
+
"ag.rc.neverN": "nunca",
|
|
521
|
+
"ag.rc.mode.auto": "relanzar solo",
|
|
522
|
+
"ag.rc.mode.ask": "preguntar",
|
|
523
|
+
"ag.rc.mode.off": "nada",
|
|
524
|
+
"ag.rc.menu": "Ajustes de rotación",
|
|
525
|
+
"ag.rc.noState": "Aún no rota: cuenta desde su próximo inicio.",
|
|
526
|
+
"ag.rc.asked": "Se pidió a {id} su traspaso",
|
|
527
|
+
"ag.rc.askedRelaunch":
|
|
528
|
+
"Se pidió a {id} su traspaso. Den lo relanza en cuanto pase la revisión.",
|
|
529
|
+
"ag.rc.askedResumed":
|
|
530
|
+
"{id} reanudado para escribir su traspaso. Den lo relanza en cuanto pase la revisión.",
|
|
531
|
+
"ag.rc.kept": "Conversación de {id} mantenida: su cuenta vuelve a empezar",
|
|
532
|
+
"ag.rc.keptNever": "Conversación de {id} mantenida: ya no rotará",
|
|
533
|
+
"ag.rc.autoRelaunched":
|
|
534
|
+
"{id} relanzado desde su traspaso tras {why}. La conversación anterior {old} se conserva.",
|
|
493
535
|
"ag.remove": "Quitar",
|
|
494
536
|
"ag.removeName": "Quitar {id}",
|
|
495
537
|
"ag.removed": "{id} quitado",
|
|
@@ -705,6 +747,7 @@
|
|
|
705
747
|
"ver.pinned": "fijada {v}",
|
|
706
748
|
"ver.usedLatest": "{n} ahora sigue la versión más reciente",
|
|
707
749
|
"set.agents.personas": "Personas",
|
|
750
|
+
"set.agents.rotation": "Rotación",
|
|
708
751
|
// The Agents tab (AG-4a-term, agents-page.js).
|
|
709
752
|
"n.agents": "Agentes",
|
|
710
753
|
"kind.agent": "Agente",
|
|
@@ -299,9 +299,10 @@
|
|
|
299
299
|
"err.signin.claimOrg":
|
|
300
300
|
"GitHub の {org} 組織のメンバーは、{host} 上のブラウザーでこれを登録できます。",
|
|
301
301
|
"err.signin.claimHere": "これは自分のコンピューター: GitHub を接続",
|
|
302
|
+
"err.signin.claimHereOn": "{host} 上で: GitHub を接続",
|
|
303
|
+
"err.signin.claimOrgOnly":
|
|
304
|
+
"GitHub の {org} 組織のメンバーは、{host} 上のブラウザーからこれを登録できます。このページを {host} で開くか、どこからでもサインインできるよう web.owner_github を設定してください。",
|
|
302
305
|
"err.signin.claimAs": "@{login} としてサインイン",
|
|
303
|
-
"err.signin.claimHereNote":
|
|
304
|
-
"「これは自分のコンピューター」は {host} 上のブラウザーでだけ使えます。ほかの場所では何も開きません。",
|
|
305
306
|
"err.signin.claimChecking": "ここが {host} か確認しています…",
|
|
306
307
|
"err.signin.githubRefused":
|
|
307
308
|
"@{login} はこの {name} のオーナーではありません。GitHub でサインインを使えるのはオーナーのアカウントだけです。代わりに「このコンピューターを承認」を使ってください。",
|
|
@@ -473,9 +474,46 @@
|
|
|
473
474
|
"セッションは交代しました({why})が、handoff.md がありません。再開して書かせるか、新しく始めてください。",
|
|
474
475
|
"ag.rot.badHandoff":
|
|
475
476
|
"セッションは交代しました({why})が、handoff.md が不完全です。再開して直すか、新しく始めてください。",
|
|
476
|
-
"ag.relaunch": "
|
|
477
|
-
"ag.relaunchName": "{id}
|
|
477
|
+
"ag.relaunch": "今すぐ再起動",
|
|
478
|
+
"ag.relaunchName": "{id} を今すぐ再起動",
|
|
478
479
|
"ag.relaunched": "{id} を引き継ぎから再起動しました",
|
|
480
|
+
"ag.rc.autoAsk":
|
|
481
|
+
"交代の時期です({why})。待機中になったら Den が引き継ぎを書かせ、再起動します。",
|
|
482
|
+
"ag.rc.autoReady":
|
|
483
|
+
"交代の時期です({why})。引き継ぎは準備済み: 待機中になったら Den が再起動します。",
|
|
484
|
+
"ag.rc.ready": "交代の時期です({why})。引き継ぎは準備済みです。",
|
|
485
|
+
"ag.rc.missing": "交代の時期です({why})。引き継ぎがまだありません。",
|
|
486
|
+
"ag.rc.bad": "交代の時期です({why})。引き継ぎが不完全です。",
|
|
487
|
+
"ag.rc.fellBack":
|
|
488
|
+
"交代の時期です({why})。2 回頼んでも引き継ぎを書きませんでした。",
|
|
489
|
+
"ag.rc.wanted":
|
|
490
|
+
"交代の時期です({why})。引き継ぎが書かれたら Den が再起動します。",
|
|
491
|
+
"ag.rc.write": "引き継ぎを書かせる",
|
|
492
|
+
"ag.rc.writeName": "{id} に引き継ぎを書かせる",
|
|
493
|
+
"ag.rc.keep": "この会話を続ける",
|
|
494
|
+
"ag.rc.keepName": "{id} の会話を続ける",
|
|
495
|
+
"ag.rc.never": "このエージェントには今後たずねない",
|
|
496
|
+
"ag.rc.settings": "設定",
|
|
497
|
+
"ag.rc.from": "圧縮 {n} 回で交代({src})。時期が来たら: {mode}({src2})",
|
|
498
|
+
"ag.rc.fellBackBad":
|
|
499
|
+
"交代の時期です({why})。2 回頼んでも引き継ぎが確認を通りません。",
|
|
500
|
+
"ag.rc.fromNever": "交代しません({src})。時期が来たら: {mode}({src2})",
|
|
501
|
+
"ag.rc.midTurn": "{id} は応答中です: ターンが終わってから頼んでください",
|
|
502
|
+
"ag.rc.neverN": "しない",
|
|
503
|
+
"ag.rc.mode.auto": "自動で再起動",
|
|
504
|
+
"ag.rc.mode.ask": "たずねる",
|
|
505
|
+
"ag.rc.mode.off": "何もしない",
|
|
506
|
+
"ag.rc.menu": "交代の設定",
|
|
507
|
+
"ag.rc.noState": "まだ交代の記録がありません: 次の起動から数えます。",
|
|
508
|
+
"ag.rc.asked": "{id} に引き継ぎを頼みました",
|
|
509
|
+
"ag.rc.askedRelaunch":
|
|
510
|
+
"{id} に引き継ぎを頼みました。確認が通ったら Den が再起動します。",
|
|
511
|
+
"ag.rc.askedResumed":
|
|
512
|
+
"引き継ぎを書かせるため {id} を再開しました。確認が通ったら Den が再起動します。",
|
|
513
|
+
"ag.rc.kept": "{id} の会話を続けます: 回数はやり直しです",
|
|
514
|
+
"ag.rc.keptNever": "{id} の会話を続けます: 今後は交代しません",
|
|
515
|
+
"ag.rc.autoRelaunched":
|
|
516
|
+
"{why}のあと {id} を引き継ぎから再起動しました。前の会話 {old} は残っています。",
|
|
479
517
|
"ag.remove": "削除",
|
|
480
518
|
"ag.removeName": "{id} を削除",
|
|
481
519
|
"ag.removed": "{id} を削除しました",
|
|
@@ -691,6 +729,7 @@
|
|
|
691
729
|
"ver.pinned": "{v} に固定",
|
|
692
730
|
"ver.usedLatest": "{n} は最新バージョンに追従します",
|
|
693
731
|
"set.agents.personas": "ペルソナ",
|
|
732
|
+
"set.agents.rotation": "交代",
|
|
694
733
|
// The Agents tab (AG-4a-term, agents-page.js).
|
|
695
734
|
"n.agents": "エージェント",
|
|
696
735
|
"kind.agent": "エージェント",
|