@zenera/cli 1.1.24 → 1.1.25
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.md +53 -0
- package/dist/ask.js +28 -5
- package/dist/banner.js +2 -2
- package/dist/batch.d.ts +6 -0
- package/dist/batch.js +76 -1
- package/dist/catalog.d.ts +11 -1
- package/dist/catalog.js +80 -7
- package/dist/commands/inspect.d.ts +47 -1
- package/dist/commands/inspect.js +167 -18
- package/dist/commands/memory.js +128 -29
- package/dist/commands/meta.js +311 -21
- package/dist/commands/models.js +96 -12
- package/dist/commands/open.js +4 -4
- package/dist/commands/run.js +38 -4
- package/dist/commands/sandbox.js +76 -14
- package/dist/engine.d.ts +5 -0
- package/dist/engine.js +1 -0
- package/dist/eventlog.d.ts +59 -0
- package/dist/eventlog.js +146 -0
- package/dist/liveness.d.ts +7 -0
- package/dist/liveness.js +15 -1
- package/dist/meta/editor.d.ts +9 -0
- package/dist/meta/editor.js +60 -0
- package/dist/meta/finetune/children.d.ts +8 -0
- package/dist/meta/finetune/children.js +76 -0
- package/dist/meta/finetune/command.d.ts +30 -0
- package/dist/meta/finetune/command.js +338 -0
- package/dist/meta/finetune/dataset/anchors.d.ts +41 -0
- package/dist/meta/finetune/dataset/anchors.js +239 -0
- package/dist/meta/finetune/dataset/changes.d.ts +36 -0
- package/dist/meta/finetune/dataset/changes.js +319 -0
- package/dist/meta/finetune/dataset/command.d.ts +17 -0
- package/dist/meta/finetune/dataset/command.js +1011 -0
- package/dist/meta/finetune/dataset/drift.d.ts +33 -0
- package/dist/meta/finetune/dataset/drift.js +71 -0
- package/dist/meta/finetune/dataset/export.d.ts +26 -0
- package/dist/meta/finetune/dataset/export.js +51 -0
- package/dist/meta/finetune/dataset/index.d.ts +2 -0
- package/dist/meta/finetune/dataset/index.js +2 -0
- package/dist/meta/finetune/dataset/sample.d.ts +50 -0
- package/dist/meta/finetune/dataset/sample.js +197 -0
- package/dist/meta/finetune/dataset/schema.d.ts +33 -0
- package/dist/meta/finetune/dataset/schema.js +216 -0
- package/dist/meta/finetune/dataset/store.d.ts +35 -0
- package/dist/meta/finetune/dataset/store.js +177 -0
- package/dist/meta/finetune/dataset/types.d.ts +125 -0
- package/dist/meta/finetune/dataset/types.js +39 -0
- package/dist/meta/finetune/failure.d.ts +15 -0
- package/dist/meta/finetune/failure.js +26 -0
- package/dist/meta/finetune/feedback.d.ts +45 -0
- package/dist/meta/finetune/feedback.js +85 -0
- package/dist/meta/finetune/improvements.d.ts +51 -0
- package/dist/meta/finetune/improvements.js +244 -0
- package/dist/meta/finetune/index.d.ts +2 -0
- package/dist/meta/finetune/index.js +2 -0
- package/dist/meta/finetune/journal.d.ts +35 -0
- package/dist/meta/finetune/journal.js +135 -0
- package/dist/meta/finetune/live.d.ts +74 -0
- package/dist/meta/finetune/live.js +226 -0
- package/dist/meta/finetune/loop.d.ts +3 -0
- package/dist/meta/finetune/loop.js +114 -0
- package/dist/meta/finetune/memories.d.ts +47 -0
- package/dist/meta/finetune/memories.js +154 -0
- package/dist/meta/finetune/report.d.ts +33 -0
- package/dist/meta/finetune/report.js +1284 -0
- package/dist/meta/finetune/retry.d.ts +24 -0
- package/dist/meta/finetune/retry.js +96 -0
- package/dist/meta/finetune/sampler.d.ts +18 -0
- package/dist/meta/finetune/sampler.js +41 -0
- package/dist/meta/finetune/system.d.ts +27 -0
- package/dist/meta/finetune/system.js +132 -0
- package/dist/meta/finetune/train.d.ts +39 -0
- package/dist/meta/finetune/train.js +391 -0
- package/dist/meta/finetune/tui.d.ts +16 -0
- package/dist/meta/finetune/tui.js +291 -0
- package/dist/meta/finetune/tuning.d.ts +167 -0
- package/dist/meta/finetune/tuning.js +289 -0
- package/dist/meta/finetune/usage.d.ts +62 -0
- package/dist/meta/finetune/usage.js +225 -0
- package/dist/meta/host.d.ts +14 -0
- package/dist/meta/host.js +20 -0
- package/dist/meta/index.d.ts +11 -0
- package/dist/meta/index.js +11 -0
- package/dist/meta/launch.d.ts +81 -0
- package/dist/meta/launch.js +286 -0
- package/dist/meta/model.d.ts +44 -0
- package/dist/meta/model.js +119 -0
- package/dist/meta/prompts.d.ts +18 -0
- package/dist/meta/prompts.js +61 -0
- package/dist/meta/relay.d.ts +20 -0
- package/dist/meta/relay.js +123 -0
- package/dist/meta/tokens.d.ts +52 -0
- package/dist/meta/tokens.js +226 -0
- package/dist/meta/window.d.ts +61 -0
- package/dist/meta/window.js +198 -0
- package/dist/meta/wire.d.ts +42 -0
- package/dist/meta/wire.js +129 -0
- package/dist/modelref.d.ts +16 -0
- package/dist/modelref.js +41 -0
- package/dist/narrate.js +5 -2
- package/dist/podman.d.ts +26 -0
- package/dist/podman.js +83 -3
- package/dist/projects.d.ts +0 -5
- package/dist/projects.js +2 -15
- package/dist/sandbox.d.ts +2 -0
- package/dist/sandbox.js +10 -3
- package/dist/scaffold.d.ts +15 -6
- package/dist/scaffold.js +5 -60
- package/dist/session.js +4 -29
- package/dist/term.d.ts +2 -0
- package/dist/term.js +11 -2
- package/dist/trace.js +53 -2
- package/dist/tui/models.d.ts +33 -0
- package/dist/tui/models.js +389 -0
- package/dist/tui/wrap.d.ts +5 -0
- package/dist/tui/wrap.js +12 -0
- package/dist/usage.d.ts +78 -0
- package/dist/usage.js +51 -0
- package/package.json +3 -2
- package/templates/editor/.github/copilot-instructions.md +31 -102
- package/templates/editor/.github/prompts/analyze.prompt.md +31 -0
- package/templates/editor/.github/prompts/dataset.prompt.md +108 -0
- package/templates/editor/.github/prompts/finetune-apply.prompt.md +91 -0
- package/templates/editor/.github/prompts/finetune.prompt.md +691 -198
- package/templates/editor/.github/prompts/new-agent.prompt.md +3 -1
- package/templates/editor/.github/prompts/new-skill.prompt.md +2 -0
- package/templates/editor/.github/prompts/project-review.prompt.md +4 -3
- package/templates/editor/.github/skills/zen-analyze-run/SKILL.md +483 -0
- package/templates/editor/.github/skills/zen-cli/SKILL.md +9 -1
- package/templates/editor/.github/skills/zen-cli/references/dataset.md +34 -0
- package/templates/editor/.github/skills/zen-cli/references/finetune.md +77 -0
- package/templates/editor/.github/skills/zen-cli/references/inspect.md +47 -9
- package/templates/editor/.github/skills/zen-cli/references/memory.md +33 -10
- package/templates/editor/.github/skills/zen-cli/references/meta.md +61 -0
- package/templates/editor/.github/skills/zen-cli/references/models.md +5 -1
- package/templates/editor/.github/skills/zen-cli/references/rag.md +24 -6
- package/templates/editor/.github/skills/zen-cli/references/sandbox.md +10 -1
- package/templates/editor/.github/skills/zen-code-python/SKILL.md +123 -0
- package/templates/editor/.github/skills/zen-code-python/references/code_python.md +48 -0
- package/templates/editor/.github/skills/zen-dataset/SKILL.md +253 -0
- package/templates/editor/.github/skills/zen-finetune/SKILL.md +1449 -658
- package/templates/editor/.github/skills/zen-finetune/references/readme-template.md +268 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/batch.mjs +390 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/difficult.mjs +243 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/memory.mjs +280 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/next.mjs +398 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/report.mjs +797 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/select.mjs +354 -0
- package/templates/editor/.github/skills/zen-finetune/scripts/usage.mjs +722 -0
- package/templates/editor/.github/skills/zen-inspect/SKILL.md +60 -25
- package/templates/editor/.github/skills/zen-inspect-ask/SKILL.md +270 -0
- package/templates/editor/.github/skills/zen-memory/SKILL.md +18 -14
- package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +20 -8
- package/templates/editor/.github/skills/zen-review/SKILL.md +5 -3
- package/templates/editor/.github/skills/zen-review/scripts/check-paths.sh +5 -4
- package/templates/editor/.github/skills/zen-sandbox/SKILL.md +7 -3
- package/templates/editor/.github/skills/zen-sandbox-capacity/SKILL.md +2 -2
- package/templates/editor/.github/skills/zen-topology/SKILL.md +283 -0
- package/templates/editor/.vscode/settings.json +1 -0
- package/templates/project/agents/files-instructions.md +29 -20
- package/templates/project/agents/memory-instructions.md +31 -32
- package/templates/project/agents/tools-instructions.md +7 -4
- package/templates/project/gitignore +2 -0
- package/dist/meta.d.ts +0 -221
- package/dist/meta.js +0 -684
- package/templates/editor/.github/skills/zen-finetune/scripts/collect.sh +0 -432
- package/templates/editor/.github/skills/zen-finetune/scripts/sample.sh +0 -199
package/dist/eventlog.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { isCheckpoint } from '@zenera/neo';
|
|
2
|
+
import { appendFileSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
const MAX_TEXT = 400;
|
|
5
|
+
const clip = (text) => {
|
|
6
|
+
const one = text.replace(/\s+/g, ' ').trim();
|
|
7
|
+
return one.length > MAX_TEXT ? `${one.slice(0, MAX_TEXT - 1)}…` : one;
|
|
8
|
+
};
|
|
9
|
+
/** A line that cannot be written is dropped: watching a run must not break it. */
|
|
10
|
+
export function eventLog(path) {
|
|
11
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
12
|
+
return (body) => {
|
|
13
|
+
try {
|
|
14
|
+
appendFileSync(path, `${JSON.stringify({ t: new Date().toISOString(), ...body })}\n`);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// See above.
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** For `zen run`: the runtime's own events, folded to the shared lines. */
|
|
22
|
+
export function agentEventLog(path) {
|
|
23
|
+
const write = eventLog(path);
|
|
24
|
+
// Keyed by branch, since a fork has several model calls open at once.
|
|
25
|
+
const began = new Map();
|
|
26
|
+
const said = new Map();
|
|
27
|
+
return (event) => {
|
|
28
|
+
const key = event.branch?.name ?? '';
|
|
29
|
+
if (!isCheckpoint(event)) {
|
|
30
|
+
if (event.type === 'text_delta') {
|
|
31
|
+
said.set(key, (said.get(key) ?? '') + event.delta);
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
switch (event.type) {
|
|
36
|
+
case 'before_llm_call':
|
|
37
|
+
began.set(key, Date.now());
|
|
38
|
+
said.delete(key);
|
|
39
|
+
break;
|
|
40
|
+
case 'after_llm_call': {
|
|
41
|
+
const u = event.node.usage;
|
|
42
|
+
const at = began.get(key);
|
|
43
|
+
write({
|
|
44
|
+
type: 'llm',
|
|
45
|
+
model: event.node.model,
|
|
46
|
+
in: u.inputTokens,
|
|
47
|
+
cached: u.cachedInputTokens ?? 0,
|
|
48
|
+
out: u.outputTokens,
|
|
49
|
+
reasoning: u.reasoningTokens ?? 0,
|
|
50
|
+
...(at !== undefined ? { ms: Date.now() - at } : {}),
|
|
51
|
+
});
|
|
52
|
+
const text = said.get(key)?.trim();
|
|
53
|
+
said.delete(key);
|
|
54
|
+
if (text) {
|
|
55
|
+
write({ type: 'say', text: clip(text) });
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case 'before_tool_call':
|
|
60
|
+
write({
|
|
61
|
+
type: 'tool',
|
|
62
|
+
phase: 'start',
|
|
63
|
+
id: event.call.callId,
|
|
64
|
+
name: event.call.name,
|
|
65
|
+
subject: clip(event.call.args.preview ?? ''),
|
|
66
|
+
});
|
|
67
|
+
break;
|
|
68
|
+
case 'after_tool_call':
|
|
69
|
+
write({
|
|
70
|
+
type: 'tool',
|
|
71
|
+
phase: 'end',
|
|
72
|
+
id: event.node.callId,
|
|
73
|
+
name: event.node.name,
|
|
74
|
+
ok: !event.node.isError,
|
|
75
|
+
...(event.node.durationMs !== undefined ? { ms: event.node.durationMs } : {}),
|
|
76
|
+
});
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* For `zen meta run`: copilot's events and spans, folded to the same lines.
|
|
85
|
+
* Its JSONL has no token counts, so `llm` lines come from the spans instead,
|
|
86
|
+
* about a second after each call.
|
|
87
|
+
*/
|
|
88
|
+
export function copilotEventLog(path) {
|
|
89
|
+
const write = eventLog(path);
|
|
90
|
+
// Its completion names no tool, so the start is remembered by call id.
|
|
91
|
+
const began = new Map();
|
|
92
|
+
return {
|
|
93
|
+
event: (event) => {
|
|
94
|
+
const data = event.data ?? {};
|
|
95
|
+
const id = String(data.toolCallId ?? '');
|
|
96
|
+
switch (event.type) {
|
|
97
|
+
case 'assistant.message': {
|
|
98
|
+
const text = String(data.content ?? '').trim();
|
|
99
|
+
if (text) {
|
|
100
|
+
write({ type: 'say', text: clip(text) });
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case 'tool.execution_start': {
|
|
105
|
+
const args = (data.arguments ?? {});
|
|
106
|
+
const subject = args.command ?? args.description ?? args.path ?? args.skill ?? '';
|
|
107
|
+
const name = String(data.toolName ?? 'tool');
|
|
108
|
+
began.set(id, { at: Date.now(), name });
|
|
109
|
+
write({
|
|
110
|
+
type: 'tool',
|
|
111
|
+
phase: 'start',
|
|
112
|
+
id,
|
|
113
|
+
name,
|
|
114
|
+
subject: clip(typeof subject === 'string' ? subject : JSON.stringify(subject)),
|
|
115
|
+
});
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case 'tool.execution_complete': {
|
|
119
|
+
const start = began.get(id);
|
|
120
|
+
began.delete(id);
|
|
121
|
+
write({
|
|
122
|
+
type: 'tool',
|
|
123
|
+
phase: 'end',
|
|
124
|
+
id,
|
|
125
|
+
name: start?.name ?? String(data.toolName ?? 'tool'),
|
|
126
|
+
ok: data.success !== false,
|
|
127
|
+
...(start ? { ms: Date.now() - start.at } : {}),
|
|
128
|
+
});
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
default:
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
call: (call) => write({
|
|
136
|
+
type: 'llm',
|
|
137
|
+
model: call.model,
|
|
138
|
+
in: call.usage.inputTokens,
|
|
139
|
+
cached: call.usage.cachedInputTokens,
|
|
140
|
+
out: call.usage.outputTokens,
|
|
141
|
+
reasoning: call.usage.reasoningTokens,
|
|
142
|
+
ms: call.durationMs,
|
|
143
|
+
}),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=eventlog.js.map
|
package/dist/liveness.d.ts
CHANGED
|
@@ -54,6 +54,13 @@ export interface ModelProbe {
|
|
|
54
54
|
/** embeddings only: the width the model actually returned */
|
|
55
55
|
dimensions?: number;
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* A chat model sized for a probe: 16 output tokens is enough for "ok", and
|
|
59
|
+
* Anthropic requires a cap at all. Only the adapters that read `maxTokens` are
|
|
60
|
+
* given one — the registry refuses a knob its adapter would never send, and the
|
|
61
|
+
* OpenAI adapters have no such knob.
|
|
62
|
+
*/
|
|
63
|
+
export declare function probeChat(provider: string, id: string): Model;
|
|
57
64
|
export declare function probeModel(target: ModelTarget): Promise<ModelProbe>;
|
|
58
65
|
/**
|
|
59
66
|
* One round trip per model, run together — they are independent questions, and
|
package/dist/liveness.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EXA_BASE_URL, isUnfunded, ModelRegistry, text, } from '@zenera/neo';
|
|
1
|
+
import { createModel, EXA_BASE_URL, isUnfunded, ModelRegistry, text, vertexRoute, } from '@zenera/neo';
|
|
2
2
|
import { envOf, SHAPES, } from "./keys.js";
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
// Liveness
|
|
@@ -389,6 +389,17 @@ const UNSERVED = [
|
|
|
389
389
|
'no access',
|
|
390
390
|
];
|
|
391
391
|
const targetId = (target) => target.kind === 'model' ? target.model.id : target.embedder.id;
|
|
392
|
+
/**
|
|
393
|
+
* A chat model sized for a probe: 16 output tokens is enough for "ok", and
|
|
394
|
+
* Anthropic requires a cap at all. Only the adapters that read `maxTokens` are
|
|
395
|
+
* given one — the registry refuses a knob its adapter would never send, and the
|
|
396
|
+
* OpenAI adapters have no such knob.
|
|
397
|
+
*/
|
|
398
|
+
export function probeChat(provider, id) {
|
|
399
|
+
const capped = { provider, model: id, maxTokens: 16 };
|
|
400
|
+
const unread = new ModelRegistry().knobs(capped).some((k) => k.knob === 'maxTokens');
|
|
401
|
+
return createModel(unread ? { provider, model: id } : capped);
|
|
402
|
+
}
|
|
392
403
|
/**
|
|
393
404
|
* Refused by the provider, unreachable, or served.
|
|
394
405
|
*
|
|
@@ -413,6 +424,9 @@ function classifyModel(err, target) {
|
|
|
413
424
|
/** The command that finds something this account can actually use. */
|
|
414
425
|
function instead(target) {
|
|
415
426
|
const provider = target.ref.includes(':') ? target.ref.split(':')[0] : undefined;
|
|
427
|
+
if (provider === 'vertex' && vertexRoute(targetId(target)) !== 'gemini') {
|
|
428
|
+
return 'enable it for this project in Model Garden: https://console.cloud.google.com/vertex-ai/model-garden';
|
|
429
|
+
}
|
|
416
430
|
return provider
|
|
417
431
|
? `zen models ls ${provider}`
|
|
418
432
|
: `zen models pick --${target.kind === 'embedding' ? 'embedding' : 'chat'}`;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writes the editor's files under `dir`, replacing what is there. They are
|
|
3
|
+
* ours: they say how the editor is to treat a directory the agents write into,
|
|
4
|
+
* and they describe the file formats of the version of `zen` in hand, so the
|
|
5
|
+
* current answer is the only one worth having and a stale one is worse than
|
|
6
|
+
* none. Returns the relative paths written.
|
|
7
|
+
*/
|
|
8
|
+
export declare function editorFiles(dir: string): string[];
|
|
9
|
+
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { copyFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { copyTree, MEMORY_RULES, TEMPLATES } from "./host.js";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Telling the editor which instructions are not for it
|
|
6
|
+
//
|
|
7
|
+
// The project's house rules are `agents/instructions.md`, deliberately not
|
|
8
|
+
// `AGENTS.md`: every coding assistant now reads that name out of an open
|
|
9
|
+
// folder and feeds it to itself as always-on instructions, and `zen open`
|
|
10
|
+
// opens exactly this directory. A name nobody else claims means the two are
|
|
11
|
+
// never confused, and `chat.useAgentsMdFile` no longer has to be switched off
|
|
12
|
+
// to keep them apart.
|
|
13
|
+
//
|
|
14
|
+
// They sit under `agents/` because there is rarely only one of them. Anything
|
|
15
|
+
// named `agents/<topic>-instructions.md` is read too, in filename order, so a
|
|
16
|
+
// subject that is true for every agent but is about one capability — memory,
|
|
17
|
+
// say — gets its own document instead of another section in a file that keeps
|
|
18
|
+
// growing.
|
|
19
|
+
//
|
|
20
|
+
// `chat.useNestedAgentsMdFiles` is still written. It is already false by
|
|
21
|
+
// default, but it is opt-in globally, and this is a directory the agent itself
|
|
22
|
+
// writes into — someone who turned it on would otherwise have the editor pick
|
|
23
|
+
// up whatever `AGENTS.md` a run happened to leave behind. It is a *restricted*
|
|
24
|
+
// setting, so it applies only in a trusted workspace; that is the right way
|
|
25
|
+
// round, since an untrusted folder is not one to run agents in either.
|
|
26
|
+
//
|
|
27
|
+
// `agents/instructions.md` addresses the *project's* agents. The editor's
|
|
28
|
+
// assistant still needs a brief of its own, and what it needs to know is how
|
|
29
|
+
// this kind of project is put together — the file formats, how a prompt is
|
|
30
|
+
// written, when to add a skill rather than an agent. That is what the
|
|
31
|
+
// `.github/` tree is: the standing brief, plus the prompt files and skills the
|
|
32
|
+
// editor picks up from the same place.
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
/** The same bytes, kept in the `zen-memory` skill to restore or diff against. */
|
|
35
|
+
const MEMORY_REFERENCE = join('.github', 'skills', 'zen-memory', 'references', 'memory-instructions.md');
|
|
36
|
+
/**
|
|
37
|
+
* Writes the editor's files under `dir`, replacing what is there. They are
|
|
38
|
+
* ours: they say how the editor is to treat a directory the agents write into,
|
|
39
|
+
* and they describe the file formats of the version of `zen` in hand, so the
|
|
40
|
+
* current answer is the only one worth having and a stale one is worse than
|
|
41
|
+
* none. Returns the relative paths written.
|
|
42
|
+
*/
|
|
43
|
+
export function editorFiles(dir) {
|
|
44
|
+
const written = copyTree(join(TEMPLATES, 'editor'), dir, '', {});
|
|
45
|
+
// The one file that belongs to both trees. It is a project file first —
|
|
46
|
+
// house rules reaching every agent that can see the graph — and it is
|
|
47
|
+
// written once and edited from then on, like every other project file. But
|
|
48
|
+
// a project whose copy drifted, or that deleted it and turned memory back
|
|
49
|
+
// on later, needs somewhere to get the current text from, and the editor
|
|
50
|
+
// tree is replaced on every `init` and `open`. Copying the same bytes into
|
|
51
|
+
// the skill's references is what makes `diff` between the two mean
|
|
52
|
+
// something, and what stops a second copy of these rules existing in the
|
|
53
|
+
// repository to fall out of step with the first.
|
|
54
|
+
const reference = join(dir, MEMORY_REFERENCE);
|
|
55
|
+
mkdirSync(dirname(reference), { recursive: true });
|
|
56
|
+
copyFileSync(join(TEMPLATES, 'project', MEMORY_RULES), reference);
|
|
57
|
+
written.push(MEMORY_REFERENCE);
|
|
58
|
+
return written;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=editor.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function remember(tuningDir: string, pid: number, marker: string): void;
|
|
2
|
+
export declare function forget(tuningDir: string, pid: number): void;
|
|
3
|
+
/**
|
|
4
|
+
* Stops every child a dead loop left running, and waits until they are gone.
|
|
5
|
+
* Only under the loop's lock: a live loop's children look the same.
|
|
6
|
+
*/
|
|
7
|
+
export declare function reap(tuningDir: string, graceMs?: number): Promise<number[]>;
|
|
8
|
+
//# sourceMappingURL=children.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
5
|
+
const folder = (tuningDir) => join(tuningDir, 'children');
|
|
6
|
+
export function remember(tuningDir, pid, marker) {
|
|
7
|
+
mkdirSync(folder(tuningDir), { recursive: true });
|
|
8
|
+
const row = { pid, marker, at: new Date().toISOString() };
|
|
9
|
+
writeFileSync(join(folder(tuningDir), `${pid}.json`), `${JSON.stringify(row)}\n`);
|
|
10
|
+
}
|
|
11
|
+
export function forget(tuningDir, pid) {
|
|
12
|
+
rmSync(join(folder(tuningDir), `${pid}.json`), { force: true });
|
|
13
|
+
}
|
|
14
|
+
const alive = (pid) => {
|
|
15
|
+
try {
|
|
16
|
+
process.kill(pid, 0);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
return err.code === 'EPERM';
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const commandOf = (pid) => spawnSync('ps', ['-o', 'command=', '-p', String(pid)], { encoding: 'utf8' }).stdout ?? '';
|
|
24
|
+
const signal = (pid, sig) => {
|
|
25
|
+
try {
|
|
26
|
+
process.kill(-pid, sig);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
try {
|
|
30
|
+
process.kill(pid, sig);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Gone already.
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Stops every child a dead loop left running, and waits until they are gone.
|
|
39
|
+
* Only under the loop's lock: a live loop's children look the same.
|
|
40
|
+
*/
|
|
41
|
+
export async function reap(tuningDir, graceMs = 10_000) {
|
|
42
|
+
let names = [];
|
|
43
|
+
try {
|
|
44
|
+
names = readdirSync(folder(tuningDir)).filter((n) => n.endsWith('.json'));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
const left = [];
|
|
50
|
+
for (const name of names) {
|
|
51
|
+
let child;
|
|
52
|
+
try {
|
|
53
|
+
child = JSON.parse(readFileSync(join(folder(tuningDir), name), 'utf8'));
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// A row torn by the kill itself.
|
|
57
|
+
}
|
|
58
|
+
if (child && alive(child.pid) && commandOf(child.pid).includes(child.marker)) {
|
|
59
|
+
signal(child.pid, 'SIGTERM');
|
|
60
|
+
left.push(child.pid);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const until = Date.now() + graceMs;
|
|
64
|
+
while (left.some(alive) && Date.now() < until) {
|
|
65
|
+
await sleep(100);
|
|
66
|
+
}
|
|
67
|
+
for (const pid of left.filter(alive)) {
|
|
68
|
+
signal(pid, 'SIGKILL');
|
|
69
|
+
}
|
|
70
|
+
while (left.some(alive) && Date.now() < until + 2000) {
|
|
71
|
+
await sleep(50);
|
|
72
|
+
}
|
|
73
|
+
rmSync(folder(tuningDir), { recursive: true, force: true });
|
|
74
|
+
return left;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=children.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Config, type Zen } from './tuning.ts';
|
|
2
|
+
export declare const FINETUNE_USAGE = "zen meta finetune <start|status|stop|retry|session> [options]";
|
|
3
|
+
export declare const FINETUNE_HELP: string[];
|
|
4
|
+
export declare const FINETUNE_SUMMARY = "Tune the project's prose on its dataset, a case at a time, N cases at once.";
|
|
5
|
+
/** The page `zen meta finetune --help` prints. */
|
|
6
|
+
export declare const FINETUNE_DETAILS: string[];
|
|
7
|
+
export interface FinetuneContext {
|
|
8
|
+
readonly args: readonly string[];
|
|
9
|
+
readonly json: boolean;
|
|
10
|
+
readonly cwd: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function finetuneProjectFlag(args: readonly string[]): string | undefined;
|
|
13
|
+
export interface FinetuneOptions {
|
|
14
|
+
/** stands in for the `zen` binary - tests */
|
|
15
|
+
zen?: Zen;
|
|
16
|
+
tickMs?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function runFinetune(ctx: FinetuneContext, project: {
|
|
19
|
+
dir: string;
|
|
20
|
+
name: string;
|
|
21
|
+
}, options?: FinetuneOptions): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* A tuning used to live in `.finetune/`. Moves it to `finetune/` once, so a
|
|
24
|
+
* project tuned before the rename resumes where it stopped. Refuses while a
|
|
25
|
+
* loop of the old version still holds its lock there: renaming its folder out
|
|
26
|
+
* from under it would split one tuning across two directories.
|
|
27
|
+
*/
|
|
28
|
+
export declare function moveLegacyDir(projectDir: string): void;
|
|
29
|
+
export declare function readConfig(dir: string): Config;
|
|
30
|
+
//# sourceMappingURL=command.d.ts.map
|