tonedial 0.1.4 → 0.1.6
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/README.es.md +122 -0
- package/README.ja.md +125 -0
- package/README.ko.md +125 -0
- package/README.md +120 -0
- package/README.zh.md +124 -0
- package/dist/cli.js +11 -6
- package/dist/commands/doctor.js +28 -3
- package/dist/commands/init.js +3 -0
- package/dist/commands/rebuild.js +98 -8
- package/dist/core/anchors.js +29 -27
- package/dist/core/combos.js +21 -1
- package/dist/core/compile.js +6 -2
- package/dist/core/i18n.js +48 -30
- package/dist/core/legacy-tone.js +195 -58
- package/dist/core/locales/es.js +24 -15
- package/dist/core/locales/ja.js +24 -15
- package/dist/core/locales/zh.js +24 -15
- package/dist/core/operations.js +24 -2
- package/dist/core/seeds.js +3 -3
- package/dist/core/skill.js +67 -32
- package/dist/wiring/apply.js +1 -1
- package/package.json +1 -1
package/dist/core/locales/ja.js
CHANGED
|
@@ -101,7 +101,7 @@ const messages = {
|
|
|
101
101
|
choosePreset: "有効な保存元がない値の復元用プリセットを選んでください:",
|
|
102
102
|
sourceRequired: "保存値が不完全です。tonedial doctor --fix を対話的に実行するか、無人復旧の前に --from-preset SLUG または --from-operation ID を選んでください。",
|
|
103
103
|
sourceInvalid: "選択元から有効な設定を取得できません。元のファイルは保持しました。",
|
|
104
|
-
invalidOptions: "
|
|
104
|
+
invalidOptions: "復旧元、隔離、ツールの指定には doctor --fix が必要です。--restore-preset には --from-operation が必要です。--rollback は隔離、復旧元、プリセット、ツール指定と併用できません。",
|
|
105
105
|
keptSettings: "保存済み設定とカスタムプリセットを保持しました。",
|
|
106
106
|
obsoleteWidthDiscarded: "廃止済み fixed_width の無効な値を破棄します。出力はターミナル幅に従います。",
|
|
107
107
|
obsoleteGuardsDiscarded: "廃止済み guards の無効な値を破棄します。ToneDialはガード要求を追加しません。",
|
|
@@ -114,6 +114,13 @@ const messages = {
|
|
|
114
114
|
rollback: (id) => `以前のファイルに戻す:\ntonedial doctor --fix --rollback ${id}`,
|
|
115
115
|
rollbackOrder: "先に接続を復元し、その後アプリケーションのファイルを復元してください:",
|
|
116
116
|
noSnapshot: (id) => `${id}: この状態ルート用の有効な設定スナップショットがありません`,
|
|
117
|
+
quarantineCandidate: (id) => `操作ID:\n${id}\n再構築するには、先にこの記録を隔離する必要があります。元のバイト列はロールバック履歴に保持されます。`,
|
|
118
|
+
quarantineQuestion: "隔離するには上の操作ID全体を入力してください。Enterで中止:",
|
|
119
|
+
quarantineRequired: (id, command) => `${id}: 復旧前に、読み取れない操作記録を明示的に隔離する必要があります。ファイルは変更していません。\n${command}`,
|
|
120
|
+
quarantineUnavailable: (id) => `${id}: 隔離できる読み取り不能な操作記録が見つかりません。ファイルは変更していません。`,
|
|
121
|
+
quarantine: (id) => `読み取れない操作 ${id} を隔離し、元のバイト列をロールバック履歴に保持します。`,
|
|
122
|
+
quarantineComplete: (id) => `読み取れない操作 ${id} を隔離しました。`,
|
|
123
|
+
quarantineRemaining: (count) => `読み取れない操作記録が ${count} 件残っています。次の記録を隔離してから復旧を続けてください。`,
|
|
117
124
|
retire: (id) => `停止した操作 ${id} を履歴に移してから再構築してください。外部への変更は検証も取り消しもされません。`,
|
|
118
125
|
resumeOperation: (id) => `停止した操作:\n${id}`,
|
|
119
126
|
resumeQuestion: "続行するには上の操作ID全体を入力してください。Enterで中止:",
|
|
@@ -158,7 +165,7 @@ const messages = {
|
|
|
158
165
|
safewordShort: (phrase) => `合言葉 ${phrase}: 短すぎるため、意図せず反応する可能性があります`,
|
|
159
166
|
safewordSet: (phrase) => `合言葉 ${phrase}`,
|
|
160
167
|
noSafeword: "合言葉なし",
|
|
161
|
-
register: (level) => `敬語区分 ${level} (${({ auto: "関係に合わせる", polite: "敬語", plain: "通常の常体", rough: "
|
|
168
|
+
register: (level) => `敬語区分 ${level} (${({ auto: "関係に合わせる", polite: "敬語", plain: "通常の常体", rough: "短くぶっきらぼうな常体" })[level]})`,
|
|
162
169
|
},
|
|
163
170
|
artifact: {
|
|
164
171
|
size: (chars) => `TONE.md ${chars}文字`,
|
|
@@ -269,6 +276,7 @@ const messages = {
|
|
|
269
276
|
seedsNotRun: "同梱ファイルなし · ここでは init 未実行",
|
|
270
277
|
seedsAttention: "同梱ファイルの確認が必要",
|
|
271
278
|
recoveryPending: "実行中または復旧が必要な操作があります。この実行ではファイルを変更していません。",
|
|
279
|
+
invalidRecoveryPending: "読み取れない操作履歴が復旧を妨げています。この実行ではファイルを変更していません。",
|
|
272
280
|
resumeOperation: "アプリ復旧を続けるには:",
|
|
273
281
|
contextCurrent: "AGENTS.md と TONE.md の構成は最新です。",
|
|
274
282
|
contextRepair: "管理対象のコンテキストファイルに修復が必要です。ガイドと口調ファイルの診断を確認してください。",
|
|
@@ -291,7 +299,7 @@ const messages = {
|
|
|
291
299
|
changed: "確認中にリーダーか設定が変更されました。変更が終わってから再試行してください。",
|
|
292
300
|
probe: "制御下の確認に失敗しました。Nodeと一時ディレクトリへのアクセスを確認し、doctor を再実行してください。",
|
|
293
301
|
},
|
|
294
|
-
operationState: { pending: "保留中", complete: "完了", "rolled-back": "復元済み", "retired-for-app-rebuild": "再構築用に履歴へ移行", invalid: "無効な記録" },
|
|
302
|
+
operationState: { pending: "保留中", complete: "完了", "rolled-back": "復元済み", "retired-for-app-rebuild": "再構築用に履歴へ移行", quarantined: "隔離済み", invalid: "無効な記録" },
|
|
295
303
|
rollbackStatus: {
|
|
296
304
|
ready: "承認すると選択した操作を復元します。",
|
|
297
305
|
busy: "まだ実行中です。所有者の完了を待ってください。",
|
|
@@ -455,6 +463,7 @@ const messages = {
|
|
|
455
463
|
tools: "接続するエージェント · init: none は状態のみ",
|
|
456
464
|
fix: "doctor: 修復可能な問題を修復",
|
|
457
465
|
rollback: "doctor --fix: 操作を1つ復元",
|
|
466
|
+
quarantineOperation: "doctor --fix: 読み取れない操作記録を1つ隔離",
|
|
458
467
|
fromOperation: "doctor --fix: 操作から保存済み設定を選択",
|
|
459
468
|
fromPreset: "doctor --fix: 不足した設定用のプリセット",
|
|
460
469
|
restorePreset: "doctor --fix: 不足・破損したユーザープリセットを復元",
|
|
@@ -471,7 +480,7 @@ const messages = {
|
|
|
471
480
|
},
|
|
472
481
|
combos: {
|
|
473
482
|
contradiction: (rule) => `${rule} は自己矛盾しています。`,
|
|
474
|
-
refusalCompliance: "
|
|
483
|
+
refusalCompliance: "一方の軸は作業の先送り、他方は意欲的な即時着手を求めます。どちらかを下げてください。",
|
|
475
484
|
nothingBlocked: "ブロックはしていません。",
|
|
476
485
|
},
|
|
477
486
|
errors: {
|
|
@@ -614,21 +623,21 @@ export const ja = {
|
|
|
614
623
|
},
|
|
615
624
|
axisHints: {
|
|
616
625
|
formality: { owns: "表現の格式と距離感", low: "親しい言葉や俗語", high: "儀礼的で敬意ある表現" },
|
|
617
|
-
verbosity: { owns: "回答の長さと説明の深さ", low: "1
|
|
618
|
-
profanity: { owns: "
|
|
619
|
-
playfulness: { owns: "
|
|
620
|
-
critique: { owns: "
|
|
621
|
-
flattery: { owns: "
|
|
622
|
-
warmth: { owns: "ユーザーに向ける温かさ", low: "挨拶・親しい受け止め・励ましなし", high: "
|
|
626
|
+
verbosity: { owns: "回答の長さと説明の深さ", low: "単純な結果は短い1文", high: "依頼の範囲内で詳しく説明" },
|
|
627
|
+
profanity: { owns: "罵りだけ:強さと頻度", low: "罵りなし・役柄の俗語は維持", high: "ほぼ全文で強烈な罵りを伏せずに使う" },
|
|
628
|
+
playfulness: { owns: "冗談と役柄表現の強度・頻度", low: "平易な表現・設定済みの呼称を維持", high: "ほぼ全ての文で大げさな役柄表現" },
|
|
629
|
+
critique: { owns: "問題点と選択への批判の強さ", low: "評価せず問題を中立に説明", high: "深刻な問題点と選択を容赦なく非難し、あざける" },
|
|
630
|
+
flattery: { owns: "称賛の量と強さ", low: "なし", high: "段落ごとに惜しみなく称賛・技術評価は維持" },
|
|
631
|
+
warmth: { owns: "ユーザーに向ける温かさ", low: "挨拶・親しい受け止め・励ましなし", high: "段落ごとに優しさ・共感・慰め・安心" },
|
|
623
632
|
conviction: { owns: "自分の判断を押し通す強さ", low: "選択肢を並べて尋ねる", high: "推奨を1つ、決定として述べる" },
|
|
624
|
-
care: { owns: "範囲・整理・実用的な表示", low: "依頼された作業のみ", high: "
|
|
625
|
-
compliance: { owns: "
|
|
626
|
-
refusal: { owns: "
|
|
627
|
-
bravado: { owns: "
|
|
633
|
+
care: { owns: "範囲・整理・実用的な表示", low: "依頼された作業のみ", high: "後続・バックアップ・休憩・一覧・状態絵文字" },
|
|
634
|
+
compliance: { owns: "拒否で先送りしない時の実行意欲", low: "反対理由を述べてから実行", high: "進んで即着手・遅延や交渉なし" },
|
|
635
|
+
refusal: { owns: "拒否の頻度と条件", low: "拒否も遅延もなし", high: "説得までストライキ・合言葉は1回答だけ解除" },
|
|
636
|
+
bravado: { owns: "労力の誇張と手柄の主張", low: "誇張なし", high: "毎回答で自慢・手柄・苦労を誇張・役柄は維持" },
|
|
628
637
|
},
|
|
629
638
|
settingHints: {
|
|
630
639
|
safeword: "1つのメッセージに一度だけ平易な回答を求める文句",
|
|
631
|
-
speech_level: "auto: 関係に合わせる · polite: 敬語 · plain: 通常の常体 · rough:
|
|
640
|
+
speech_level: "auto: 関係に合わせる · polite: 敬語 · plain: 通常の常体 · rough: 短くぶっきらぼうな常体・それ自体では冗談・罵り・批判・嘲りを加えない · 表現の格式と距離感は formality で調整",
|
|
632
641
|
language: "CLIの表示言語 · エージェントの回答言語とは別",
|
|
633
642
|
"persona.age": "モデルに連想させる年齢層",
|
|
634
643
|
"persona.gender": "モデルに連想させるジェンダー",
|
package/dist/core/locales/zh.js
CHANGED
|
@@ -101,7 +101,7 @@ const messages = {
|
|
|
101
101
|
choosePreset: "请为缺少有效保存来源的值选择预设:",
|
|
102
102
|
sourceRequired: "保存值不完整。请交互运行 tonedial doctor --fix,或在无人值守恢复前选择 --from-preset SLUG 或 --from-operation ID。",
|
|
103
103
|
sourceInvalid: "所选来源无法提供有效设置,已保留原文件。",
|
|
104
|
-
invalidOptions: "
|
|
104
|
+
invalidOptions: "恢复来源、隔离和工具选项需要 doctor --fix。--restore-preset 需要 --from-operation;--rollback 不能与隔离、来源、预设或工具选项同时使用。",
|
|
105
105
|
keptSettings: "已保留保存的设置和自定义预设。",
|
|
106
106
|
obsoleteWidthDiscarded: "丢弃已停用的无效 fixed_width 值。输出将跟随终端宽度。",
|
|
107
107
|
obsoleteGuardsDiscarded: "丢弃已停用的无效 guards 值。ToneDial 不再添加防护请求。",
|
|
@@ -114,6 +114,13 @@ const messages = {
|
|
|
114
114
|
rollback: (id) => `恢复之前的文件:\ntonedial doctor --fix --rollback ${id}`,
|
|
115
115
|
rollbackOrder: "请先恢复连接,再恢复应用文件:",
|
|
116
116
|
noSnapshot: (id) => `${id}:没有此状态根目录的有效设置快照`,
|
|
117
|
+
quarantineCandidate: (id) => `操作 ID:\n${id}\n要重建应用,必须先隔离这条记录;原始字节仍保存在回滚历史中。`,
|
|
118
|
+
quarantineQuestion: "请输入上方完整的操作 ID 以隔离该记录;按 Enter 取消:",
|
|
119
|
+
quarantineRequired: (id, command) => `${id}:恢复前必须明确隔离这条无法读取的操作记录。未更改文件。\n${command}`,
|
|
120
|
+
quarantineUnavailable: (id) => `${id}:找不到可隔离的无法读取操作记录。未更改文件。`,
|
|
121
|
+
quarantine: (id) => `隔离无法读取的操作 ${id};原始字节保留在回滚历史中。`,
|
|
122
|
+
quarantineComplete: (id) => `已隔离无法读取的操作 ${id}。`,
|
|
123
|
+
quarantineRemaining: (count) => `仍有 ${count} 条无法读取的操作记录。请隔离下一条记录后继续恢复。`,
|
|
117
124
|
retire: (id) => `重建应用前,请将已停止的操作 ${id} 归档为历史。其外部变更不会被认证或撤销。`,
|
|
118
125
|
resumeOperation: (id) => `已停止的操作:\n${id}`,
|
|
119
126
|
resumeQuestion: "要继续,请输入上方完整的操作 ID;按 Enter 取消:",
|
|
@@ -158,7 +165,7 @@ const messages = {
|
|
|
158
165
|
safewordShort: (phrase) => `安全词 ${phrase}:太短,可能误触发`,
|
|
159
166
|
safewordSet: (phrase) => `安全词 ${phrase}`,
|
|
160
167
|
noSafeword: "未设置安全词",
|
|
161
|
-
register: (level) => `敬语形式 ${level} (${({ auto: "按关系选择", polite: "敬语", plain: "普通非敬语", rough: "
|
|
168
|
+
register: (level) => `敬语形式 ${level} (${({ auto: "按关系选择", polite: "敬语", plain: "普通非敬语", rough: "简短生硬的非敬语" })[level]})`,
|
|
162
169
|
},
|
|
163
170
|
artifact: {
|
|
164
171
|
size: (chars) => `TONE.md ${chars} 字符`,
|
|
@@ -269,6 +276,7 @@ const messages = {
|
|
|
269
276
|
seedsNotRun: "无内置文件 · 尚未在此运行 init",
|
|
270
277
|
seedsAttention: "内置文件需要处理",
|
|
271
278
|
recoveryPending: "有操作正在运行或需要恢复。本次执行未更改文件。",
|
|
279
|
+
invalidRecoveryPending: "无法读取的操作历史阻止了恢复。本次执行未更改文件。",
|
|
272
280
|
resumeOperation: "继续应用恢复:",
|
|
273
281
|
contextCurrent: "AGENTS.md 与 TONE.md 布局已是最新。",
|
|
274
282
|
contextRepair: "受管理的上下文文件需要修复,请检查指南和语气文件诊断。",
|
|
@@ -291,7 +299,7 @@ const messages = {
|
|
|
291
299
|
changed: "检查时读取程序或设置发生变化,请等修改结束后重试。",
|
|
292
300
|
probe: "受控探测失败。请检查 Node 和临时目录访问权限,再运行 doctor。",
|
|
293
301
|
},
|
|
294
|
-
operationState: { pending: "待处理", complete: "已完成", "rolled-back": "已恢复", "retired-for-app-rebuild": "已归档以供重建", invalid: "无效记录" },
|
|
302
|
+
operationState: { pending: "待处理", complete: "已完成", "rolled-back": "已恢复", "retired-for-app-rebuild": "已归档以供重建", quarantined: "已隔离", invalid: "无效记录" },
|
|
295
303
|
rollbackStatus: {
|
|
296
304
|
ready: "批准后将恢复所选操作。",
|
|
297
305
|
busy: "操作仍在运行,请等待其所有者完成。",
|
|
@@ -455,6 +463,7 @@ const messages = {
|
|
|
455
463
|
tools: "要连接的代理 · init:none 仅初始化状态",
|
|
456
464
|
fix: "doctor:修复可处理的问题",
|
|
457
465
|
rollback: "doctor --fix:恢复一次操作",
|
|
466
|
+
quarantineOperation: "doctor --fix:隔离一条无法读取的操作记录",
|
|
458
467
|
fromOperation: "doctor --fix:从操作中选择保存设置",
|
|
459
468
|
fromPreset: "doctor --fix:为不可用设置选择预设",
|
|
460
469
|
restorePreset: "doctor --fix:恢复一个缺失或损坏的用户预设",
|
|
@@ -471,7 +480,7 @@ const messages = {
|
|
|
471
480
|
},
|
|
472
481
|
combos: {
|
|
473
482
|
contradiction: (rule) => `${rule} 自相矛盾。`,
|
|
474
|
-
refusalCompliance: "
|
|
483
|
+
refusalCompliance: "一个语气轴要求推迟任务,另一个要求积极地立即开始。请降低其中一项。",
|
|
475
484
|
nothingBlocked: "没有阻止任何设置。",
|
|
476
485
|
},
|
|
477
486
|
errors: {
|
|
@@ -614,21 +623,21 @@ export const zh = {
|
|
|
614
623
|
},
|
|
615
624
|
axisHints: {
|
|
616
625
|
formality: { owns: "措辞的正式程度与社交距离", low: "熟悉措辞及俚语", high: "庄重恭敬的措辞" },
|
|
617
|
-
verbosity: { owns: "回答长度和解释深度", low: "
|
|
618
|
-
profanity: { owns: "
|
|
619
|
-
playfulness: { owns: "
|
|
620
|
-
critique: { owns: "
|
|
621
|
-
flattery: { owns: "
|
|
622
|
-
warmth: { owns: "对用户表达的温暖", low: "无问候、亲切回应或鼓励", high: "
|
|
626
|
+
verbosity: { owns: "回答长度和解释深度", low: "简单结果只用一个短句", high: "在请求范围内深入解释" },
|
|
627
|
+
profanity: { owns: "仅脏话:强度和频率", low: "不用脏话;保留角色俚语", high: "几乎每句都使用未经弱化的强烈脏话" },
|
|
628
|
+
playfulness: { owns: "幽默和角色表达的强度与频率", low: "直白措辞;保留已设称呼", high: "几乎每句都使用夸张的角色表达" },
|
|
629
|
+
critique: { owns: "对缺陷和选择的批评强度", low: "不作评判,中性陈述缺陷", high: "毫不留情地谴责并嘲讽严重缺陷和相关选择" },
|
|
630
|
+
flattery: { owns: "赞美的数量和强度", low: "无", high: "每段都大力赞美;技术判断不变" },
|
|
631
|
+
warmth: { owns: "对用户表达的温暖", low: "无问候、亲切回应或鼓励", high: "每段都表达温柔、共情、安慰和宽心" },
|
|
623
632
|
conviction: { owns: "坚持自身判断的力度", low: "列出选项并询问", high: "将一个推荐作为决定陈述" },
|
|
624
|
-
care: { owns: "覆盖范围、组织和实用呈现", low: "仅执行所请求任务", high: "
|
|
625
|
-
compliance: { owns: "
|
|
626
|
-
refusal: { owns: "
|
|
627
|
-
bravado: { owns: "
|
|
633
|
+
care: { owns: "覆盖范围、组织和实用呈现", low: "仅执行所请求任务", high: "后续、备份、休息、列表和状态表情" },
|
|
634
|
+
compliance: { owns: "拒绝未推迟任务时的行动意愿", low: "提出异议和原因后执行", high: "积极立即开始;不拖延、不谈条件" },
|
|
635
|
+
refusal: { owns: "拒绝频率和条件", low: "无拒绝或延迟", high: "罢工到被说服;安全词仅解除一次" },
|
|
636
|
+
bravado: { owns: "夸大付出和邀功的程度", low: "无夸张", high: "每次都吹嘘、邀功、夸大付出;保留角色" },
|
|
628
637
|
},
|
|
629
638
|
settingHints: {
|
|
630
639
|
safeword: "对一条消息请求一次平实回答的短语",
|
|
631
|
-
speech_level: "auto:按关系选择 · polite:敬语 · plain:普通非敬语 · rough
|
|
640
|
+
speech_level: "auto:按关系选择 · polite:敬语 · plain:普通非敬语 · rough:简短生硬的非敬语句尾;本身不增加玩笑、脏话、批评或嘲讽 · 措辞和距离感由 formality 调整",
|
|
632
641
|
language: "CLI 界面语言 · 与代理回答语言无关",
|
|
633
642
|
"persona.age": "模型可能联想的年龄段",
|
|
634
643
|
"persona.gender": "模型可能联想的性别",
|
package/dist/core/operations.js
CHANGED
|
@@ -387,6 +387,27 @@ export function readJournal(paths, operationIdValue) {
|
|
|
387
387
|
const journal = readJson(path);
|
|
388
388
|
return validJournal(journal, paths, operationIdValue) ? journal : null;
|
|
389
389
|
}
|
|
390
|
+
function readOperationQuarantine(paths, operationIdValue) {
|
|
391
|
+
if (!existingOperationsDirectory(paths))
|
|
392
|
+
return null;
|
|
393
|
+
const value = readJson(operationJournalPath(paths, operationIdValue));
|
|
394
|
+
return isPlainObject(value) && hasExactKeys(value, ["kind", "operationId", "originalSha256", "root", "schema"]) &&
|
|
395
|
+
value.schema === 1 && value.kind === "quarantined-operation" && value.operationId === operationIdValue &&
|
|
396
|
+
value.root === paths.root && /^[0-9a-f]{64}$/.test(value.originalSha256)
|
|
397
|
+
? value : null;
|
|
398
|
+
}
|
|
399
|
+
/** Replace an unreadable journal with a nonblocking marker; the enclosing repair journal keeps its original bytes. */
|
|
400
|
+
export function serializeOperationQuarantine(paths, operationIdValue, original) {
|
|
401
|
+
if (!validOperationId(operationIdValue))
|
|
402
|
+
throw new OperationError("invalid", "operation id is not valid");
|
|
403
|
+
return `${JSON.stringify({
|
|
404
|
+
schema: 1,
|
|
405
|
+
kind: "quarantined-operation",
|
|
406
|
+
operationId: operationIdValue,
|
|
407
|
+
root: paths.root,
|
|
408
|
+
originalSha256: createHash("sha256").update(original).digest("hex"),
|
|
409
|
+
}, null, 2)}\n`;
|
|
410
|
+
}
|
|
390
411
|
function journalTime(journal) {
|
|
391
412
|
const updated = Date.parse(journal.updatedAt);
|
|
392
413
|
if (Number.isFinite(updated))
|
|
@@ -889,12 +910,13 @@ export function inspectOperations(paths) {
|
|
|
889
910
|
continue;
|
|
890
911
|
const id = match.groups.id;
|
|
891
912
|
const journal = readJournal(paths, id);
|
|
913
|
+
const quarantine = journal === null ? readOperationQuarantine(paths, id) : null;
|
|
892
914
|
journals.push({
|
|
893
915
|
path: join(paths.operations, entry.name),
|
|
894
916
|
operationId: id,
|
|
895
|
-
state: journal?.state ?? "invalid",
|
|
917
|
+
state: journal?.state ?? (quarantine === null ? "invalid" : "quarantined"),
|
|
896
918
|
journal,
|
|
897
|
-
...(journal === null ? { message: "mutation journal is invalid" } : {}),
|
|
919
|
+
...(journal === null ? { message: quarantine === null ? "mutation journal is invalid" : "invalid journal is quarantined in rollback history" } : {}),
|
|
898
920
|
});
|
|
899
921
|
}
|
|
900
922
|
const ownerOnly = ownerOnlyInspection(paths, lock);
|
package/dist/core/seeds.js
CHANGED
|
@@ -11,7 +11,7 @@ import { captureRawEntry, caseRenameMatchesCurrent, isNoop, planChange, planEntr
|
|
|
11
11
|
import { BUNDLED, builtinPresetDir, LEGACY_BUILTIN_SLUGS, RETIRED_PRESETS } from "./presets.js";
|
|
12
12
|
import { SKILL_MD, SKILL_NAME, SKILL_TRAITS_MD } from "./skill.js";
|
|
13
13
|
// Bump for changed generated content; freshness also checks each managed seed's bytes/provenance.
|
|
14
|
-
export const SEED_VERSION =
|
|
14
|
+
export const SEED_VERSION = 23;
|
|
15
15
|
/** The state-root operating boundaries. The compiler owns the current tone separately. */
|
|
16
16
|
export const GUIDE_MD = `${GUIDE_FORMAT_MARKER}
|
|
17
17
|
ToneDial changes manner only; it never expands task scope or permissions.
|
|
@@ -73,10 +73,10 @@ export function seedFiles(paths, selection) {
|
|
|
73
73
|
};
|
|
74
74
|
const native = [
|
|
75
75
|
reader,
|
|
76
|
-
{ id: "skill/body", version:
|
|
76
|
+
{ id: "skill/body", version: 21, path: join(paths.skill, SKILL_NAME, "SKILL.md"), label: `skill/${SKILL_NAME}/SKILL.md`, contents: SKILL_MD },
|
|
77
77
|
{
|
|
78
78
|
id: "skill/traits",
|
|
79
|
-
version:
|
|
79
|
+
version: 12,
|
|
80
80
|
path: join(paths.skill, SKILL_NAME, "references", "traits.md"),
|
|
81
81
|
label: `skill/${SKILL_NAME}/references/traits.md`,
|
|
82
82
|
contents: SKILL_TRAITS_MD,
|
package/dist/core/skill.js
CHANGED
|
@@ -114,7 +114,7 @@ interpolating it into shell code.
|
|
|
114
114
|
| Persona manner or role note | \`tonedial set "persona.note=Patient guide" --json\` |
|
|
115
115
|
| Safeword phrase | \`tonedial set "safeword=plain answer please" --json\` |
|
|
116
116
|
| Honorific register system | \`tonedial set speech_level=polite --json\` |
|
|
117
|
-
|
|
|
117
|
+
| Curt, blunt non-honorific endings | \`tonedial set speech_level=rough --json\` |
|
|
118
118
|
|
|
119
119
|
Age bands are \`unspecified\`, \`teens\`, \`20s\`, \`30s\`, \`40s\`, and \`50s+\`.
|
|
120
120
|
Gender values are \`unspecified\`, \`masculine\`, \`feminine\`, and \`neutral\`.
|
|
@@ -133,12 +133,26 @@ Persona notes have no length limit.
|
|
|
133
133
|
|
|
134
134
|
ToneDial has no guard toggle or automatic emergency register. All axis levels 1–5 are choices
|
|
135
135
|
the user can request. Report advisory \`riskAxes\` and combination notices without lowering
|
|
136
|
-
values
|
|
137
|
-
and
|
|
136
|
+
values or blocking the change. The four components that require confirmation are strong
|
|
137
|
+
profanity, harsh mocking, fictional violent imagery and theatrical menace. Before using one
|
|
138
|
+
requested by axes, persona or later instructions, first answer the current request without it,
|
|
139
|
+
then ask one concise explicit confirmation naming it. Known axis-selected components are strong
|
|
140
|
+
profanity (\`profanity\` 4–5), harsh mocking (\`critique\` 5), and fictional violent imagery or
|
|
141
|
+
theatrical menace from high playfulness while either component is active. Warmth, praise,
|
|
142
|
+
ordinary criticism and ordinary role idioms need no confirmation.
|
|
143
|
+
Confirmation lasts only while the named request remains unchanged; an increase or change
|
|
144
|
+
requires it again. Applying, importing, saving or creating a profile, \`--auto\`, a safeword,
|
|
145
|
+
and confirmation from another session do not count. Profiles store requested settings, never
|
|
146
|
+
session confirmation. Confirmation changes manner only: it authorizes no work and never permits
|
|
147
|
+
hate speech aimed at protected traits or realistic or credible threats. Non-protected profanity,
|
|
148
|
+
consensual insults, fictional violent imagery and theatrical menace remain available after it.
|
|
149
|
+
The host's task and permission rules apply independently. The compiler requests this behavior;
|
|
150
|
+
neither the CLI nor a profile stores or authenticates session confirmation, and generated text
|
|
151
|
+
cannot prove that confirmation or adherence occurred.
|
|
138
152
|
For \`speech_level\`, choose \`auto\`, \`polite\`, \`plain\`, or \`rough\` only when the user requests that
|
|
139
153
|
register system. \`auto\` chooses address forms for the current relationship and scene,
|
|
140
154
|
keeping them consistent within each reply; \`polite\` and \`plain\` fix those forms.
|
|
141
|
-
\`plain\` means ordinary non-honorific forms; \`rough\` requests
|
|
155
|
+
\`plain\` means ordinary non-honorific forms; \`rough\` requests curt, blunt non-honorific
|
|
142
156
|
sentence endings. Preserve the configured address terms and every independent axis.
|
|
143
157
|
It has no effect where the language lacks an honorific distinction. A request for more or
|
|
144
158
|
less formality changes wording and distance within the chosen forms, without silently changing
|
|
@@ -181,6 +195,12 @@ If repair fails, report its phase, affected path, safe error code and operation
|
|
|
181
195
|
Some file changes may already be applied; a failure is not evidence that all files stayed unchanged.
|
|
182
196
|
Preserve the operation record and follow the reported scoped read-only diagnosis.
|
|
183
197
|
Default doctor output focuses on blockers; \`--verbose\` and JSON retain the operation history.
|
|
198
|
+
If doctor reports an unreadable operation record, use its exact scoped
|
|
199
|
+
\`doctor --fix --quarantine-operation <id>\` command. Preview or approve that replacement through
|
|
200
|
+
the normal repair gate; never delete the record directly. The replacement stops the damaged
|
|
201
|
+
record from blocking recovery, while the repair journal keeps its original bytes and mode for
|
|
202
|
+
explicit rollback. If several records are unreadable, run the next exact command doctor reports;
|
|
203
|
+
each invocation quarantines one record, and the last continues the application rebuild.
|
|
184
204
|
For an explicitly selected stopped operation, \`doctor --fix --from-operation <id>\` continues
|
|
185
205
|
application repair using valid current settings first; it does not undo the earlier changes.
|
|
186
206
|
Preview that exact ID and scope with \`--dry-run\` before applying the approved repair.
|
|
@@ -249,7 +269,7 @@ Report the movement back to the user in their own terms, from the \`moves\` fiel
|
|
|
249
269
|
- "stop flattering me" → \`flattery=1\`. Not \`warmth\`, which is a different observable.
|
|
250
270
|
- "be brief" → \`verbosity\` down. Change \`care\` only for requested coverage or organization changes.
|
|
251
271
|
- "more casual" → \`formality\` down. Change the register system only on an explicit request,
|
|
252
|
-
such as "use plain forms" → \`speech_level=plain\`, or "use
|
|
272
|
+
such as "use plain forms" → \`speech_level=plain\`, or "use curt, blunt plain forms" → \`speech_level=rough\`.
|
|
253
273
|
|
|
254
274
|
For a named preset, run \`tonedial list --json\` then \`tonedial use <slug> --json\`.
|
|
255
275
|
An explicit agent character or role request uses \`persona.agent\`; an explicit request to
|
|
@@ -274,8 +294,8 @@ ${RELOAD_MD}
|
|
|
274
294
|
|
|
275
295
|
The safeword is a phrase the user picked, reported by \`tonedial show --json\`. When their
|
|
276
296
|
message contains it, **drop the tone for that one message and answer plainly, then resume.**
|
|
277
|
-
It releases the manner and authorises nothing:
|
|
278
|
-
confirmation and permission check it otherwise would.
|
|
297
|
+
It releases the manner and authorises nothing: it is not intense-tone approval, and a request
|
|
298
|
+
in the same message still faces every confirmation and permission check it otherwise would.
|
|
279
299
|
|
|
280
300
|
For an explicit request to restore the default axes, run \`tonedial reset --json\`, then follow
|
|
281
301
|
the reload steps above. Saved presets remain available through \`tonedial use <slug> --json\`.
|
|
@@ -337,33 +357,33 @@ the task; small conditional character instructions reinforce only distinctive co
|
|
|
337
357
|
|
|
338
358
|
## form — how a sentence is built
|
|
339
359
|
|
|
340
|
-
| Axis | Owns | 1
|
|
341
|
-
|
|
342
|
-
| \`formality\` | wording and social distance within chosen forms |
|
|
343
|
-
| \`verbosity\` | explanation length and depth |
|
|
344
|
-
| \`profanity\` |
|
|
345
|
-
| \`playfulness\` | frequency and intensity of humour and role idioms | literal
|
|
360
|
+
| Axis | Owns | Levels 1 → 5 |
|
|
361
|
+
|---|---|---|
|
|
362
|
+
| \`formality\` | wording and social distance within chosen forms | familiar slang · relaxed, occasionally formal · standard conversation · professional restraint · ceremonial deference |
|
|
363
|
+
| \`verbosity\` | explanation length and depth | one sentence or terse items · conclusion and one reason · needed explanation · conclusion, reason and one example · rationale, edge cases, alternatives and background |
|
|
364
|
+
| \`profanity\` | actual swearing, never added insults or criticism | none · one mild interjection · mild swearing about once per paragraph · strong everyday profanity in most paragraphs · varied harsh uncensored profanity in nearly every sentence |
|
|
365
|
+
| \`playfulness\` | frequency and intensity of humour and role idioms | literal · one restrained touch · two recognizable touches · exaggerated idioms in most paragraphs · character idioms in nearly every sentence |
|
|
346
366
|
|
|
347
367
|
## target — who or what an observation lands on
|
|
348
368
|
|
|
349
|
-
| Axis | Owns | 1
|
|
350
|
-
|
|
351
|
-
| \`critique\` | how hard it is on the work |
|
|
352
|
-
| \`flattery\` | how much it praises the person |
|
|
353
|
-
| \`warmth\` | how much it attends to the person |
|
|
369
|
+
| Axis | Owns | Levels 1 → 5 |
|
|
370
|
+
|---|---|---|
|
|
371
|
+
| \`critique\` | how hard it is on the work | neutral observation · softened defect and impact · direct defect and impact · harsh judgement with vivid consequences · open contempt with cutting mockery of supported defects and choices |
|
|
372
|
+
| \`flattery\` | how much it praises the person | none · one brief positive remark · two specific remarks · three specific remarks · explicit lavish praise for at least four observable choices without inventing achievements |
|
|
373
|
+
| \`warmth\` | how much it attends to the person | none · one friendly acknowledgement · two warm acknowledgements · three including encouragement · intense kindness in every paragraph with greeting, empathy, comfort and reassurance |
|
|
354
374
|
|
|
355
375
|
\`critique\` and \`warmth\` are the pair that makes "savage about the code, warm about me" work in
|
|
356
376
|
one answer. They are not opposites and setting one does not imply the other.
|
|
357
377
|
|
|
358
378
|
## behaviour — what it does about the work
|
|
359
379
|
|
|
360
|
-
| Axis | Owns | 1
|
|
361
|
-
|
|
362
|
-
| \`conviction\` | how far it pushes its own judgement |
|
|
363
|
-
| \`care\` | coverage and organization | requested result
|
|
364
|
-
| \`compliance\` |
|
|
365
|
-
| \`refusal\` | how it resists for effect |
|
|
366
|
-
| \`bravado\` | how much it
|
|
380
|
+
| Axis | Owns | Levels 1 → 5 |
|
|
381
|
+
|---|---|---|
|
|
382
|
+
| \`conviction\` | how far it pushes its own judgement | list options and ask · name a preference but ask before deciding · recommend with a reason · lead with a clear choice · state one decision and ask no follow-up |
|
|
383
|
+
| \`care\` | coverage and organization | requested result only · one directly tied risk · organized steps/checklist · one adjacent protective improvement/test · follow-up, backup and rest with useful formatting |
|
|
384
|
+
| \`compliance\` | willingness to act when refusal is not deferring | object and explain, then act · state reluctance, then act · act neutrally · state willingness and start immediately · show eager willingness and start without delay or negotiation |
|
|
385
|
+
| \`refusal\` | how it resists for effect | none · protest once but act in the same reply · defer the first request with one theatrical condition, then act after one restatement · defer the first two requests while negotiating, then act after the third · strike and defer until coaxed; the safeword drops the act for one reply |
|
|
386
|
+
| \`bravado\` | how much it exaggerates effort and claims credit | none · one playful effort overstatement · one credit claim and one boast · two boasts/claims and one dramatic effort remark · credit and dramatized effort in every answer without replacing the persona |
|
|
367
387
|
|
|
368
388
|
## Defaults are not all the same
|
|
369
389
|
|
|
@@ -377,14 +397,26 @@ Read \`riskAxes\` from the CLI for the current selection. Risk begins at \`profa
|
|
|
377
397
|
\`critique\` 4, \`flattery\` 3, \`conviction\` 5, \`compliance\` 5, \`refusal\` 2, and
|
|
378
398
|
\`bravado\` 2. These thresholds describe disruptive requests; they are not probabilities or
|
|
379
399
|
predictions of model policy. All levels 1–5 remain available. Report risk without lowering
|
|
380
|
-
the user's choice
|
|
381
|
-
|
|
382
|
-
|
|
400
|
+
the user's choice. Risk display and intense-tone confirmation are separate. The four components
|
|
401
|
+
that require confirmation are strong profanity, harsh mocking, fictional violent imagery and
|
|
402
|
+
theatrical menace. Before using one selected by axes, persona or later instructions, hold it
|
|
403
|
+
back while answering the request, then ask one concise confirmation naming it. Warmth, praise,
|
|
404
|
+
ordinary criticism and ordinary role idioms need none.
|
|
405
|
+
Confirmation lasts only for the unchanged named request; an increase or change requires it
|
|
406
|
+
again. Profiles, \`--auto\`, safewords and prior sessions never carry confirmation. It grants
|
|
407
|
+
no work permission, and hate speech aimed at protected traits and realistic or credible threats
|
|
408
|
+
remain excluded at every level. Strong non-protected profanity, consensual user-directed
|
|
409
|
+
insulting or roasting roleplay, fictional violent imagery and theatrical menace remain available
|
|
410
|
+
after confirmation. Profanity changes coarseness without inventing insults or criticism and
|
|
411
|
+
preserves those selected by critique or persona. The compiler requests this behavior but stores
|
|
412
|
+
and authenticates no session confirmation; actual confirmation and adherence still depend on
|
|
413
|
+
the conversation, host and model.
|
|
383
414
|
|
|
384
415
|
## Combinations worth knowing
|
|
385
416
|
|
|
386
417
|
- \`verbosity\` 1 with \`care\` 1 can return only the result, without a work narrative.
|
|
387
418
|
- Low \`verbosity\` with high \`care\` uses terse organized items, not longer explanations.
|
|
419
|
+
- Low \`verbosity\` keeps high warmth, flattery and playfulness visible inside the short answer.
|
|
388
420
|
- Functional status emoji can accompany low \`warmth\`; they are structure, not affection.
|
|
389
421
|
- Required task formats take precedence: a code or JSON result must not become decorative prose.
|
|
390
422
|
- \`refusal\` ≥ 4 with \`compliance\` ≥ 4 contradicts itself. The CLI warns and does not block.
|
|
@@ -402,7 +434,7 @@ do not prove actual host activation or model compliance.
|
|
|
402
434
|
\`speech_level\` picks address forms — \`auto\`, \`polite\`, \`plain\`, or \`rough\` — where the language
|
|
403
435
|
has an honorific distinction, and does nothing where it does not. Auto adapts to the current
|
|
404
436
|
relationship and scene, staying consistent within a reply. Plain uses ordinary non-honorific forms;
|
|
405
|
-
rough uses
|
|
437
|
+
rough uses curt, blunt non-honorific endings while keeping configured address terms.
|
|
406
438
|
\`formality\` sets distance inside
|
|
407
439
|
the chosen forms; warmth and profanity keep their selected effects. The persona layer (\`age\`, \`gender\`, \`self_ref\`, \`user_ref\`,
|
|
408
440
|
\`user\`, \`agent\`, \`note\`) and the safeword are included in bundled and saved custom profiles.
|
|
@@ -412,8 +444,11 @@ the chosen forms; warmth and profanity keep their selected effects. The persona
|
|
|
412
444
|
them, and \`export\`/\`import\` transfer them. Older axis-only presets keep the current settings.
|
|
413
445
|
The seven bundled profiles supply localized role and address defaults; custom text remains literal.
|
|
414
446
|
Playfulness grades role idiom frequency from literal wording at 1 to theatrical voice throughout at 5.
|
|
415
|
-
Role slang and metaphors are not filtered or suppressed by low profanity or bravado.
|
|
416
|
-
|
|
447
|
+
Role slang and ordinary metaphors are not filtered or suppressed by low profanity or bravado.
|
|
448
|
+
Violent figurative language and theatrical noncredible menace included in an intense request
|
|
449
|
+
follow the session confirmation above.
|
|
450
|
+
Profanity grades actual swearing without inventing insults or criticism, while preserving those
|
|
451
|
+
selected by critique or persona. Bravado grades effort claims without replacing the configured persona.
|
|
417
452
|
`;
|
|
418
453
|
/**
|
|
419
454
|
* The Claude Code `/tone` command, installed only by `init --commands`.
|
|
@@ -423,7 +458,7 @@ Profanity grades actual swearing; bravado grades effort claims.
|
|
|
423
458
|
* command name stays `/tone` even though the tool is `tonedial`: it is what a person types
|
|
424
459
|
* mid-sentence, and the two extra characters are paid every time.
|
|
425
460
|
*/
|
|
426
|
-
export const TONE_COMMAND_VERSION =
|
|
461
|
+
export const TONE_COMMAND_VERSION = 15;
|
|
427
462
|
export const TONE_COMMAND_MD = `---
|
|
428
463
|
description: Check, change, or reload this agent's tone, preset, or ToneDial settings
|
|
429
464
|
---
|
package/dist/wiring/apply.js
CHANGED
|
@@ -832,7 +832,7 @@ function validateEntryRebuildAction(action, prepared = false) {
|
|
|
832
832
|
const value = snapshotRecord(action.metadata ?? null);
|
|
833
833
|
if (action.kind !== "entry-rebuild" || !normalizedPath(action.path) || action.realPath !== action.path || value === null ||
|
|
834
834
|
Object.keys(value).sort().join(",") !== ["schema", "reason", "boundary", "boundaryIdentity", "parents", "stash", "stashIdentity", "archive", "prepared", "preparedIdentity", "createdParents", ...(Object.hasOwn(value, "recipes") ? ["recipes"] : [])].sort().join(",") ||
|
|
835
|
-
value.schema !== 1 || !["generated", "restore-config", "restore-preset"].includes(value.reason) ||
|
|
835
|
+
value.schema !== 1 || !["generated", "restore-config", "restore-preset", "quarantine-operation"].includes(value.reason) ||
|
|
836
836
|
!normalizedPath(value.boundary) || !lexicallyInside(action.path, value.boundary) || !identityTextValue(value.boundaryIdentity) ||
|
|
837
837
|
!Array.isArray(value.parents) || value.parents.length === 0 || !normalizedPath(value.stash) ||
|
|
838
838
|
dirname(value.stash) !== dirname(action.path) || !new RegExp(`^\\.${basename(action.path).replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.tonedial-rebuild-[0-9a-f]{32}$`).test(basename(value.stash)) ||
|