tonedial 0.1.5 → 0.1.7
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 +37 -26
- package/README.ja.md +37 -26
- package/README.ko.md +37 -26
- package/README.md +37 -26
- package/README.zh.md +37 -26
- package/dist/cli.js +22 -14
- package/dist/commands/compile.js +1 -1
- package/dist/commands/doctor.js +34 -5
- package/dist/commands/get.js +3 -1
- package/dist/commands/init.js +3 -0
- package/dist/commands/rebuild.js +99 -9
- package/dist/commands/show.js +3 -1
- package/dist/commands/test.js +2 -1
- package/dist/commands/toggle.js +23 -0
- package/dist/core/anchors.js +2 -0
- package/dist/core/compile.js +7 -2
- package/dist/core/config.js +8 -2
- package/dist/core/i18n.js +48 -12
- package/dist/core/legacy-tone.js +7 -2
- package/dist/core/locales/es.js +24 -6
- package/dist/core/locales/ja.js +24 -6
- package/dist/core/locales/zh.js +24 -6
- package/dist/core/operations.js +24 -2
- package/dist/core/reader.js +16 -2
- package/dist/core/resolve.js +1 -0
- package/dist/core/seeds.js +3 -3
- package/dist/core/skill.js +43 -10
- package/dist/wiring/apply.js +1 -1
- package/package.json +1 -1
package/dist/core/reader.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Hooks may run without PATH or after the package moves. The seeded reader is standalone.
|
|
2
2
|
import { CONTEXT_ARTIFACT_FILENAME, CONTEXT_GUIDE_FILENAME, } from "./paths.js";
|
|
3
|
-
|
|
3
|
+
import { DELIVERY_OFF_MARKER } from "./anchors.js";
|
|
4
|
+
export const READER_PROTOCOL_VERSION = 3;
|
|
4
5
|
export const GUIDE_FORMAT_VERSION = 1;
|
|
5
6
|
export const GUIDE_FORMAT_MARKER = `<!-- tonedial-guide:${GUIDE_FORMAT_VERSION} -->`;
|
|
6
7
|
/** Stable, short repair guidance shared by the emitted source and diagnostics. */
|
|
@@ -25,6 +26,7 @@ export const READER_REPAIR_HINTS = {
|
|
|
25
26
|
event: "use a supported hook event",
|
|
26
27
|
input: "retry the hook with a valid event payload",
|
|
27
28
|
response: "retry the hook when the response is available",
|
|
29
|
+
"delivery-marker": "regenerate the tone artifact",
|
|
28
30
|
"style-marker": "regenerate the tone artifact",
|
|
29
31
|
unreadable: "run tonedial doctor and resolve the reported path",
|
|
30
32
|
};
|
|
@@ -50,6 +52,7 @@ const GUIDE_FILENAME = ${JSON.stringify(CONTEXT_GUIDE_FILENAME)};
|
|
|
50
52
|
const ARTIFACT_FILENAME = ${JSON.stringify(CONTEXT_ARTIFACT_FILENAME)};
|
|
51
53
|
const LOCK_FILENAME = "operations.lock";
|
|
52
54
|
const GUIDE_MARKER = ${JSON.stringify(GUIDE_FORMAT_MARKER)};
|
|
55
|
+
const DELIVERY_OFF_MARKER = ${JSON.stringify(DELIVERY_OFF_MARKER)};
|
|
53
56
|
const REPAIR_HINTS = ${JSON.stringify(READER_REPAIR_HINTS)};
|
|
54
57
|
const PROVIDERS = new Set(["codex", "claude", "antigravity"]);
|
|
55
58
|
const EVENTS = new Set(["SessionStart", "UserPromptSubmit", "Stop", "PreInvocation"]);
|
|
@@ -338,6 +341,13 @@ function styleMarker(artifact) {
|
|
|
338
341
|
return match === null ? null : { verbosity: Number(match[1]), care: Number(match[2]) };
|
|
339
342
|
}
|
|
340
343
|
|
|
344
|
+
function deliveryEnabled(artifact) {
|
|
345
|
+
const line = artifact.split(/\r?\n/, 3)[2] ?? "";
|
|
346
|
+
if (line === DELIVERY_OFF_MARKER) return false;
|
|
347
|
+
if (line.startsWith("<!-- tonedial-delivery:")) throw new ReaderFailure("delivery-marker");
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
|
|
341
351
|
// shortcut: ambiguous data-like prose skips feedback; refine only with verified host format metadata.
|
|
342
352
|
function literalPayload(text) {
|
|
343
353
|
const value = text.trim();
|
|
@@ -400,8 +410,12 @@ async function main() {
|
|
|
400
410
|
const hint = providerHint(args);
|
|
401
411
|
try {
|
|
402
412
|
const { provider, state, event } = parseArgs(args);
|
|
403
|
-
const input = event === "Stop" ? await hookInput() : null;
|
|
404
413
|
const pair = readPair(state);
|
|
414
|
+
if (!deliveryEnabled(pair.artifact)) {
|
|
415
|
+
empty(provider, event);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const input = event === "Stop" ? await hookInput() : null;
|
|
405
419
|
if (event === "Stop") {
|
|
406
420
|
const result = styleFeedback(pair, input);
|
|
407
421
|
if (result.diagnostic !== null) {
|
package/dist/core/resolve.js
CHANGED
|
@@ -5,6 +5,7 @@ export function toCompileInput(stored) {
|
|
|
5
5
|
// The slug rides in the generation comment, so the model reads it. `unsaved` is what the
|
|
6
6
|
// artifact says once tone settings have moved away from the profile that named them.
|
|
7
7
|
preset: stored.unsaved ? null : stored.preset,
|
|
8
|
+
...(stored.enabled ? {} : { enabled: false }),
|
|
8
9
|
axes: stored.axes,
|
|
9
10
|
speech_level: stored.speech_level,
|
|
10
11
|
persona: hasPersona ? p : null,
|
package/dist/core/seeds.js
CHANGED
|
@@ -11,13 +11,13 @@ 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 = 24;
|
|
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.
|
|
18
18
|
Use the ToneDial CLI for configuration changes.
|
|
19
19
|
AGENTS.md is the operating guide, TONE.md is the current compiled tone, and the ToneDial skill
|
|
20
|
-
explains explicit in-session tuning and reloads.
|
|
20
|
+
explains delivery controls, explicit in-session tuning and reloads.
|
|
21
21
|
`;
|
|
22
22
|
/** Existing generated runtime families are repaired without inferring any native connection. */
|
|
23
23
|
export function generatedSeedSelection(paths, config, native, t = catalogue("en").cli) {
|
|
@@ -73,7 +73,7 @@ export function seedFiles(paths, selection) {
|
|
|
73
73
|
};
|
|
74
74
|
const native = [
|
|
75
75
|
reader,
|
|
76
|
-
{ id: "skill/body", version:
|
|
76
|
+
{ id: "skill/body", version: 22, 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
79
|
version: 12,
|
package/dist/core/skill.js
CHANGED
|
@@ -5,6 +5,7 @@ export const SKILL_NAME = "tonedial";
|
|
|
5
5
|
/** The current command envelope, shared by both installed control entry points. */
|
|
6
6
|
const JSON_MD = `Require zero exit status and a JSON result with \`ok: true\` and \`schema: 3\`
|
|
7
7
|
for every successful CLI step before continuing. Parse JSON rather than scraping human output.
|
|
8
|
+
\`get --json\`, \`show --json\`, and \`compile --check --json\` report the shared \`enabled\` delivery state.
|
|
8
9
|
\`chars\` reports the current TONE.md Unicode character count; no size target or maximum applies.
|
|
9
10
|
Schema 3 removes guard and ceiling fields and reports advisory \`riskAxes\`; persisted config
|
|
10
11
|
remains schema 2. Custom profiles use preset schema 2; legacy schema 1 and journal formats
|
|
@@ -65,6 +66,10 @@ Require zero exit status, \`ok: true\`, and \`schema: 3\` before continuing.
|
|
|
65
66
|
This read-only command reports destinations; it does not prove that either file exists,
|
|
66
67
|
matches the saved settings, or has been loaded.
|
|
67
68
|
|
|
69
|
+
If it reports \`enabled: false\`, do not read or apply the context pair. Report that the settings
|
|
70
|
+
are saved but delivery remains off. This also applies to tone changes made while delivery is off.
|
|
71
|
+
Continue below only when it reports \`enabled: true\`.
|
|
72
|
+
|
|
68
73
|
Read the complete UTF-8 file at the returned absolute \`agentsPath\` first (\`AGENTS.md\`).
|
|
69
74
|
Its first line must be \`${GUIDE_FORMAT_MARKER}\`; otherwise stop the reload.
|
|
70
75
|
Then read the complete UTF-8 file at the returned absolute \`path\` (\`TONE.md\`).
|
|
@@ -86,6 +91,22 @@ This reload affects only the current conversation. It does not fire a lifecycle
|
|
|
86
91
|
earlier context, or reload other open sessions. Future delivery still depends on an installed,
|
|
87
92
|
enabled, and trusted native hook.
|
|
88
93
|
`;
|
|
94
|
+
const DELIVERY_MD = `## Pause and resume delivery
|
|
95
|
+
|
|
96
|
+
For an explicit request to turn ToneDial off, run \`tonedial off --json\`, then run
|
|
97
|
+
\`tonedial compile --check --json\`. Require both results to report \`enabled: false\`.
|
|
98
|
+
Do not read the guide or artifact afterward. Report that saved settings, profiles and the full
|
|
99
|
+
\`TONE.md\` remain. The current ToneDial reader emits no ToneDial context.
|
|
100
|
+
Already delivered context cannot be removed from an open conversation; stop applying the saved
|
|
101
|
+
manner where possible and name a fresh conversation as the clean check. Do not promise a perfect reset.
|
|
102
|
+
The successful command proves the marker was saved, not that a native reader ran.
|
|
103
|
+
A reader installed before this switch must be refreshed through the user's existing tools and scope
|
|
104
|
+
before it can honor the marker.
|
|
105
|
+
|
|
106
|
+
For an explicit request to turn ToneDial on, run \`tonedial on --json\`, then follow the reload
|
|
107
|
+
procedure below. Turning delivery on does not prove that a native hook is installed, trusted,
|
|
108
|
+
enabled or running. Neither command changes axes, persona, address, register, safeword or profiles.
|
|
109
|
+
`;
|
|
89
110
|
/** Explicit setting requests use the same CLI mapping through either installed entry point. */
|
|
90
111
|
const SETTINGS_MD = `## Explicit settings
|
|
91
112
|
|
|
@@ -195,6 +216,12 @@ If repair fails, report its phase, affected path, safe error code and operation
|
|
|
195
216
|
Some file changes may already be applied; a failure is not evidence that all files stayed unchanged.
|
|
196
217
|
Preserve the operation record and follow the reported scoped read-only diagnosis.
|
|
197
218
|
Default doctor output focuses on blockers; \`--verbose\` and JSON retain the operation history.
|
|
219
|
+
If doctor reports an unreadable operation record, use its exact scoped
|
|
220
|
+
\`doctor --fix --quarantine-operation <id>\` command. Preview or approve that replacement through
|
|
221
|
+
the normal repair gate; never delete the record directly. The replacement stops the damaged
|
|
222
|
+
record from blocking recovery, while the repair journal keeps its original bytes and mode for
|
|
223
|
+
explicit rollback. If several records are unreadable, run the next exact command doctor reports;
|
|
224
|
+
each invocation quarantines one record, and the last continues the application rebuild.
|
|
198
225
|
For an explicitly selected stopped operation, \`doctor --fix --from-operation <id>\` continues
|
|
199
226
|
application repair using valid current settings first; it does not undo the earlier changes.
|
|
200
227
|
Preview that exact ID and scope with \`--dry-run\` before applying the approved repair.
|
|
@@ -214,7 +241,7 @@ Do not claim that setup, repair, or migration proves host activation or model ad
|
|
|
214
241
|
*/
|
|
215
242
|
export const SKILL_MD = `---
|
|
216
243
|
name: tonedial
|
|
217
|
-
description: Use when the user wants to check, change, or reload ToneDial manner, tone, personality, register, preset, user description, agent role, address terms, or safeword — including requests like "be gentler", "act as a database specialist", "remember my background in ToneDial", "more formal", "call me friend", or asking what the current tone settings are.
|
|
244
|
+
description: Use when the user wants to check, change, pause, resume, or reload ToneDial manner, tone, personality, register, preset, user description, agent role, address terms, or safeword — including requests like "turn ToneDial off", "be gentler", "act as a database specialist", "remember my background in ToneDial", "more formal", "call me friend", or asking what the current tone settings are.
|
|
218
245
|
---
|
|
219
246
|
|
|
220
247
|
# tonedial
|
|
@@ -233,6 +260,7 @@ the user to complete CLI installation and explicit setup; do not install it or g
|
|
|
233
260
|
tonedial get --json
|
|
234
261
|
\`\`\`
|
|
235
262
|
|
|
263
|
+
The top-level \`enabled\` field reports whether native delivery is on.
|
|
236
264
|
The \`values\` object carries the twelve axis levels and the separate settings under their
|
|
237
265
|
editable keys. An unset setting is \`null\`; description text is returned in full.
|
|
238
266
|
For the formatted overview, preset state and advisory \`riskAxes\`, use \`tonedial show --json\`.
|
|
@@ -277,9 +305,11 @@ ${SETTINGS_MD}
|
|
|
277
305
|
|
|
278
306
|
${SETUP_MD}
|
|
279
307
|
|
|
308
|
+
${DELIVERY_MD}
|
|
309
|
+
|
|
280
310
|
## Apply it in this session
|
|
281
311
|
|
|
282
|
-
Successful \`set\`, \`address\`, \`persona\`, \`use\`, \`reset\`, \`save\`, and approved \`create\` commands recompile \`TONE.md\`; that is a saved state
|
|
312
|
+
Successful \`on\`, \`off\`, \`set\`, \`address\`, \`persona\`, \`use\`, \`reset\`, \`save\`, and approved \`create\` commands recompile \`TONE.md\`; that is a saved state
|
|
283
313
|
change, not evidence of a session reload.
|
|
284
314
|
|
|
285
315
|
${RELOAD_MD}
|
|
@@ -294,9 +324,9 @@ in the same message still faces every confirmation and permission check it other
|
|
|
294
324
|
For an explicit request to restore the default axes, run \`tonedial reset --json\`, then follow
|
|
295
325
|
the reload steps above. Saved presets remain available through \`tonedial use <slug> --json\`.
|
|
296
326
|
Reset restores axes only; it does not disable hooks, unload instructions, or clear persona,
|
|
297
|
-
safeword, or other settings.
|
|
298
|
-
For
|
|
299
|
-
|
|
327
|
+
safeword, or other settings. Use \`tonedial off --json\` to pause delivery without changing them.
|
|
328
|
+
For an ambiguous "go back to normal", ask whether the user means delivery off or an axis reset;
|
|
329
|
+
do not silently equate them.
|
|
300
330
|
|
|
301
331
|
## A separate test conversation
|
|
302
332
|
|
|
@@ -452,12 +482,13 @@ selected by critique or persona. Bravado grades effort claims without replacing
|
|
|
452
482
|
* command name stays `/tone` even though the tool is `tonedial`: it is what a person types
|
|
453
483
|
* mid-sentence, and the two extra characters are paid every time.
|
|
454
484
|
*/
|
|
455
|
-
export const TONE_COMMAND_VERSION =
|
|
485
|
+
export const TONE_COMMAND_VERSION = 16;
|
|
456
486
|
export const TONE_COMMAND_MD = `---
|
|
457
|
-
description: Check, change, or reload this agent's tone, preset, or ToneDial settings
|
|
487
|
+
description: Check, change, pause, resume, or reload this agent's tone, preset, or ToneDial settings
|
|
458
488
|
---
|
|
459
489
|
|
|
460
|
-
Run \`tonedial get --json\` and report the requested current settings from \`values\`
|
|
490
|
+
Run \`tonedial get --json\` and report the requested current settings from \`values\` and the
|
|
491
|
+
delivery state from \`enabled\` in plain language.
|
|
461
492
|
Use the same installed CLI and environment throughout.
|
|
462
493
|
${JSON_MD}
|
|
463
494
|
Otherwise report the failed step and stop that flow.
|
|
@@ -479,13 +510,15 @@ ${SETTINGS_MD}
|
|
|
479
510
|
|
|
480
511
|
${SETUP_MD}
|
|
481
512
|
|
|
513
|
+
${DELIVERY_MD}
|
|
514
|
+
|
|
482
515
|
${RELOAD_MD}
|
|
483
516
|
|
|
484
517
|
An explicit axis-reset request uses \`tonedial reset --json\` followed by the same reload steps.
|
|
485
518
|
Reset restores axes only; it does not disable hooks, unload instructions, or clear persona,
|
|
486
519
|
safeword, or other settings. Saved presets remain available.
|
|
487
|
-
|
|
488
|
-
|
|
520
|
+
For an ambiguous \`/tone normal\`, ask whether the user means delivery off or an axis reset;
|
|
521
|
+
never silently equate them.
|
|
489
522
|
|
|
490
523
|
Never edit ToneDial's config, guide, or artifact directly; the CLI is the source of truth.
|
|
491
524
|
`;
|
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)) ||
|