selftune 0.2.30 → 0.2.32
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 +83 -56
- package/apps/local-dashboard/dist/assets/index-B-ut4w0B.js +15 -0
- package/apps/local-dashboard/dist/assets/index-BFGfCVrL.css +1 -0
- package/apps/local-dashboard/dist/assets/vendor-ui-DfowE3Hu.js +1 -0
- package/apps/local-dashboard/dist/index.html +3 -3
- package/cli/selftune/command-surface.ts +613 -2
- package/cli/selftune/create/baseline.ts +429 -0
- package/cli/selftune/create/check.ts +35 -0
- package/cli/selftune/create/init.ts +115 -0
- package/cli/selftune/create/package-candidate-state.ts +771 -0
- package/cli/selftune/create/package-evaluator.ts +710 -0
- package/cli/selftune/create/package-fingerprint.ts +142 -0
- package/cli/selftune/create/package-search.ts +377 -0
- package/cli/selftune/create/publish.ts +431 -0
- package/cli/selftune/create/readiness.ts +495 -0
- package/cli/selftune/create/replay.ts +330 -0
- package/cli/selftune/create/report.ts +74 -0
- package/cli/selftune/create/scaffold.ts +121 -0
- package/cli/selftune/create/skills-ref-adapter.ts +177 -0
- package/cli/selftune/create/status.ts +33 -0
- package/cli/selftune/create/templates.ts +249 -0
- package/cli/selftune/cron/setup.ts +1 -1
- package/cli/selftune/dashboard-action-events.ts +4 -1
- package/cli/selftune/dashboard-action-result.ts +789 -24
- package/cli/selftune/dashboard-action-stream.ts +80 -0
- package/cli/selftune/dashboard-contract.ts +146 -3
- package/cli/selftune/dashboard-server.ts +5 -4
- package/cli/selftune/eval/hooks-to-evals.ts +58 -35
- package/cli/selftune/eval/synthetic-evals.ts +145 -17
- package/cli/selftune/evolution/bounded-mutations.ts +1045 -0
- package/cli/selftune/evolution/evolve-body.ts +9 -36
- package/cli/selftune/evolution/evolve.ts +8 -72
- package/cli/selftune/evolution/stopping-criteria.ts +5 -13
- package/cli/selftune/evolution/unblock-suggestions.ts +0 -16
- package/cli/selftune/evolution/validate-host-replay.ts +115 -15
- package/cli/selftune/improve.ts +206 -0
- package/cli/selftune/index.ts +123 -6
- package/cli/selftune/init.ts +1 -1
- package/cli/selftune/localdb/queries/dashboard.ts +30 -0
- package/cli/selftune/localdb/schema.ts +52 -0
- package/cli/selftune/monitoring/watch.ts +257 -23
- package/cli/selftune/orchestrate/execute.ts +300 -1
- package/cli/selftune/orchestrate/finalize.ts +14 -0
- package/cli/selftune/orchestrate/plan.ts +22 -5
- package/cli/selftune/orchestrate/prepare.ts +59 -4
- package/cli/selftune/orchestrate/report.ts +1 -1
- package/cli/selftune/orchestrate.ts +34 -1
- package/cli/selftune/publish.ts +35 -0
- package/cli/selftune/registry/github-install.ts +256 -0
- package/cli/selftune/registry/index.ts +1 -1
- package/cli/selftune/registry/install.ts +58 -7
- package/cli/selftune/routes/actions.ts +81 -15
- package/cli/selftune/routes/overview.ts +1 -1
- package/cli/selftune/routes/skill-report.ts +147 -2
- package/cli/selftune/run.ts +18 -0
- package/cli/selftune/schedule.ts +3 -3
- package/cli/selftune/search-run.ts +703 -0
- package/cli/selftune/status.ts +35 -11
- package/cli/selftune/testing-readiness.ts +431 -40
- package/cli/selftune/types.ts +316 -0
- package/cli/selftune/utils/eval-readiness.ts +1 -0
- package/cli/selftune/utils/json-output.ts +11 -0
- package/cli/selftune/utils/lifecycle-surface.ts +48 -0
- package/cli/selftune/utils/query-filter.ts +82 -1
- package/cli/selftune/utils/tui.ts +85 -2
- package/cli/selftune/verify.ts +205 -0
- package/cli/selftune/workflows/proposals.ts +1 -1
- package/cli/selftune/workflows/skill-scaffold.ts +141 -63
- package/cli/selftune/workflows/workflows.ts +4 -4
- package/package.json +1 -1
- package/packages/dashboard-core/src/routes/manifest.ts +2 -2
- package/packages/ui/src/components/SkillReportPanels.tsx +7 -7
- package/packages/ui/src/primitives/button.tsx +5 -0
- package/skill/SKILL.md +148 -85
- package/skill/references/cli-quick-reference.md +16 -1
- package/skill/references/creator-playbook.md +31 -10
- package/skill/workflows/Baseline.md +8 -9
- package/skill/workflows/Contributions.md +4 -4
- package/skill/workflows/Create.md +173 -0
- package/skill/workflows/CreateTestDeploy.md +34 -30
- package/skill/workflows/Cron.md +2 -2
- package/skill/workflows/Dashboard.md +3 -3
- package/skill/workflows/Evals.md +13 -7
- package/skill/workflows/Evolve.md +75 -32
- package/skill/workflows/EvolveBody.md +22 -15
- package/skill/workflows/Hook.md +1 -1
- package/skill/workflows/Improve.md +168 -0
- package/skill/workflows/Initialize.md +3 -3
- package/skill/workflows/Orchestrate.md +49 -12
- package/skill/workflows/Publish.md +100 -0
- package/skill/workflows/Registry.md +19 -13
- package/skill/workflows/Run.md +72 -0
- package/skill/workflows/Schedule.md +2 -2
- package/skill/workflows/SearchRun.md +89 -0
- package/skill/workflows/SignalsDashboard.md +2 -2
- package/skill/workflows/UnitTest.md +13 -4
- package/skill/workflows/Verify.md +136 -0
- package/skill/workflows/Watch.md +114 -47
- package/skill/workflows/Workflows.md +13 -8
- package/apps/local-dashboard/dist/assets/index-BcXquWFB.css +0 -1
- package/apps/local-dashboard/dist/assets/index-Coq42hE4.js +0 -15
- package/apps/local-dashboard/dist/assets/vendor-ui-B0H8s1mP.js +0 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { parseArgs } from "node:util";
|
|
2
|
+
|
|
3
|
+
import { PUBLIC_COMMAND_SURFACES, renderCommandHelp } from "../command-surface.js";
|
|
4
|
+
import { handleCLIError } from "../utils/cli-error.js";
|
|
5
|
+
import { computeCreateCheckResult, formatCreateCheckResult } from "./readiness.js";
|
|
6
|
+
|
|
7
|
+
export async function cliMain(): Promise<void> {
|
|
8
|
+
const { values } = parseArgs({
|
|
9
|
+
options: {
|
|
10
|
+
"skill-path": { type: "string" },
|
|
11
|
+
json: { type: "boolean", default: false },
|
|
12
|
+
help: { type: "boolean", short: "h", default: false },
|
|
13
|
+
},
|
|
14
|
+
strict: true,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
if (values.help) {
|
|
18
|
+
console.log(renderCommandHelp(PUBLIC_COMMAND_SURFACES.createStatus));
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const result = await computeCreateCheckResult(values["skill-path"] ?? "");
|
|
23
|
+
if (values.json || !process.stdout.isTTY) {
|
|
24
|
+
console.log(JSON.stringify(result, null, 2));
|
|
25
|
+
} else {
|
|
26
|
+
console.log(formatCreateCheckResult(result));
|
|
27
|
+
}
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (import.meta.main) {
|
|
32
|
+
cliMain().catch(handleCLIError);
|
|
33
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
|
|
3
|
+
import { findGitRepositoryRoot } from "../utils/skill-discovery.js";
|
|
4
|
+
|
|
5
|
+
export interface CreateSkillManifest {
|
|
6
|
+
version: 1;
|
|
7
|
+
entry_workflow: string;
|
|
8
|
+
supports_package_replay: boolean;
|
|
9
|
+
expected_resources: {
|
|
10
|
+
workflows: boolean;
|
|
11
|
+
references: boolean;
|
|
12
|
+
scripts: boolean;
|
|
13
|
+
assets: boolean;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CreateSkillDraftFile {
|
|
18
|
+
relative_path: string;
|
|
19
|
+
absolute_path: string;
|
|
20
|
+
content: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface CreateSkillDraft {
|
|
24
|
+
display_name: string;
|
|
25
|
+
skill_name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
output_dir: string;
|
|
28
|
+
skill_dir: string;
|
|
29
|
+
skill_path: string;
|
|
30
|
+
manifest: CreateSkillManifest;
|
|
31
|
+
directories: string[];
|
|
32
|
+
files: CreateSkillDraftFile[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CreateSkillDraftOptions {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
outputDir?: string;
|
|
39
|
+
cwd?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function splitWords(value: string): string[] {
|
|
43
|
+
return value
|
|
44
|
+
.replace(/[^A-Za-z0-9]+/g, " ")
|
|
45
|
+
.trim()
|
|
46
|
+
.split(/\s+/)
|
|
47
|
+
.filter(Boolean);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function slugifyCreateSkillName(value: string): string {
|
|
51
|
+
return splitWords(value)
|
|
52
|
+
.map((word) => word.toLowerCase())
|
|
53
|
+
.join("-")
|
|
54
|
+
.replace(/-+/g, "-")
|
|
55
|
+
.replace(/^-|-$/g, "");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function getDefaultCreateSkillOutputDir(cwd: string = process.cwd()): string {
|
|
59
|
+
const repoRoot = findGitRepositoryRoot(cwd);
|
|
60
|
+
return join(repoRoot ?? cwd, ".agents", "skills");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function wrapFoldedScalar(value: string, width = 78): string[] {
|
|
64
|
+
const words = value.split(/\s+/).filter(Boolean);
|
|
65
|
+
const lines: string[] = [];
|
|
66
|
+
let current = "";
|
|
67
|
+
|
|
68
|
+
for (const word of words) {
|
|
69
|
+
const candidate = current.length === 0 ? word : `${current} ${word}`;
|
|
70
|
+
if (candidate.length > width && current.length > 0) {
|
|
71
|
+
lines.push(` ${current}`);
|
|
72
|
+
current = word;
|
|
73
|
+
} else {
|
|
74
|
+
current = candidate;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (current.length > 0) {
|
|
79
|
+
lines.push(` ${current}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return lines.length > 0 ? lines : [" "];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function buildCreateSkillManifest(): CreateSkillManifest {
|
|
86
|
+
return {
|
|
87
|
+
version: 1,
|
|
88
|
+
entry_workflow: "workflows/default.md",
|
|
89
|
+
supports_package_replay: true,
|
|
90
|
+
expected_resources: {
|
|
91
|
+
workflows: true,
|
|
92
|
+
references: false,
|
|
93
|
+
scripts: false,
|
|
94
|
+
assets: false,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function buildSkillContent(displayName: string, skillName: string, description: string): string {
|
|
100
|
+
const foldedDescription = wrapFoldedScalar(description).join("\n");
|
|
101
|
+
return `---
|
|
102
|
+
name: ${skillName}
|
|
103
|
+
description: >
|
|
104
|
+
${foldedDescription}
|
|
105
|
+
metadata:
|
|
106
|
+
author: selftune-create
|
|
107
|
+
version: 0.1.0
|
|
108
|
+
category: custom
|
|
109
|
+
generated_by: selftune create init
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
# ${displayName}
|
|
113
|
+
|
|
114
|
+
This draft skill package was initialized by selftune. Review the trigger
|
|
115
|
+
language, workflow steps, references, and scripts before broad distribution.
|
|
116
|
+
|
|
117
|
+
## When to Use
|
|
118
|
+
|
|
119
|
+
- Replace these bullets with the user-language triggers that should activate
|
|
120
|
+
this skill.
|
|
121
|
+
- Current starting point: ${description}
|
|
122
|
+
|
|
123
|
+
## Workflow Routing
|
|
124
|
+
|
|
125
|
+
| Trigger | Workflow | File |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| Default execution path | Default | workflows/default.md |
|
|
128
|
+
|
|
129
|
+
## Package Resources
|
|
130
|
+
|
|
131
|
+
- \`workflows/default.md\` is the primary execution path once the skill triggers.
|
|
132
|
+
- \`references/overview.md\` is where background context and terminology should
|
|
133
|
+
live instead of bloating the router.
|
|
134
|
+
- \`scripts/\` is reserved for deterministic helpers and repeatable mechanics.
|
|
135
|
+
- \`assets/\` is reserved for templates or static artifacts.
|
|
136
|
+
|
|
137
|
+
## Notes
|
|
138
|
+
|
|
139
|
+
- This is a draft package scaffold, not a published skill.
|
|
140
|
+
- Tighten the scope, add concrete examples, and validate the package before
|
|
141
|
+
shipping it.
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function buildDefaultWorkflowContent(displayName: string): string {
|
|
146
|
+
return `# ${displayName} Default Workflow
|
|
147
|
+
|
|
148
|
+
## When to Use
|
|
149
|
+
|
|
150
|
+
Use this after \`../SKILL.md\` has already matched the request.
|
|
151
|
+
|
|
152
|
+
## Goal
|
|
153
|
+
|
|
154
|
+
Replace this placeholder with the concrete execution flow for the skill.
|
|
155
|
+
|
|
156
|
+
## Steps
|
|
157
|
+
|
|
158
|
+
1. Confirm the request still matches the boundaries in \`../SKILL.md\`.
|
|
159
|
+
2. Load only the reference material needed from \`../references/\`.
|
|
160
|
+
3. Use deterministic helpers from \`../scripts/\` when the task has repeatable
|
|
161
|
+
mechanics.
|
|
162
|
+
4. Produce the requested result and surface any unresolved ambiguity.
|
|
163
|
+
|
|
164
|
+
## Authoring Notes
|
|
165
|
+
|
|
166
|
+
- Keep routing guidance in \`../SKILL.md\`; keep execution detail here.
|
|
167
|
+
- Move reusable background context into \`../references/overview.md\`.
|
|
168
|
+
- Prefer scripts for mechanical steps that need to stay stable.
|
|
169
|
+
`;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function buildOverviewReferenceContent(displayName: string, description: string): string {
|
|
173
|
+
return `# ${displayName} Overview
|
|
174
|
+
|
|
175
|
+
Use this file for domain context that should be loaded on demand instead of
|
|
176
|
+
living in the top-level router.
|
|
177
|
+
|
|
178
|
+
## Starting Point
|
|
179
|
+
|
|
180
|
+
- Working description: ${description}
|
|
181
|
+
- Add boundaries, vocabulary, examples, and source material here.
|
|
182
|
+
- Keep this file concise enough that the agent can load it only when needed.
|
|
183
|
+
`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function buildCreateSkillDraft(options: CreateSkillDraftOptions): CreateSkillDraft {
|
|
187
|
+
const displayName = options.name.trim();
|
|
188
|
+
const description = options.description.trim();
|
|
189
|
+
const skillName = slugifyCreateSkillName(displayName);
|
|
190
|
+
const outputDir = options.outputDir?.trim() || getDefaultCreateSkillOutputDir(options.cwd);
|
|
191
|
+
const skillDir = join(outputDir, skillName);
|
|
192
|
+
const workflowsDir = join(skillDir, "workflows");
|
|
193
|
+
const referencesDir = join(skillDir, "references");
|
|
194
|
+
const scriptsDir = join(skillDir, "scripts");
|
|
195
|
+
const assetsDir = join(skillDir, "assets");
|
|
196
|
+
const skillPath = join(skillDir, "SKILL.md");
|
|
197
|
+
const manifest = buildCreateSkillManifest();
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
display_name: displayName,
|
|
201
|
+
skill_name: skillName,
|
|
202
|
+
description,
|
|
203
|
+
output_dir: outputDir,
|
|
204
|
+
skill_dir: skillDir,
|
|
205
|
+
skill_path: skillPath,
|
|
206
|
+
manifest,
|
|
207
|
+
directories: [skillDir, workflowsDir, referencesDir, scriptsDir, assetsDir],
|
|
208
|
+
files: [
|
|
209
|
+
{
|
|
210
|
+
relative_path: "SKILL.md",
|
|
211
|
+
absolute_path: skillPath,
|
|
212
|
+
content: buildSkillContent(displayName, skillName, description),
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
relative_path: "workflows/default.md",
|
|
216
|
+
absolute_path: join(workflowsDir, "default.md"),
|
|
217
|
+
content: buildDefaultWorkflowContent(displayName),
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
relative_path: "references/overview.md",
|
|
221
|
+
absolute_path: join(referencesDir, "overview.md"),
|
|
222
|
+
content: buildOverviewReferenceContent(displayName, description),
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
relative_path: "selftune.create.json",
|
|
226
|
+
absolute_path: join(skillDir, "selftune.create.json"),
|
|
227
|
+
content: `${JSON.stringify(manifest, null, 2)}\n`,
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function formatCreateSkillDraft(draft: CreateSkillDraft): string {
|
|
234
|
+
const lines = [
|
|
235
|
+
`Draft skill package: ${draft.display_name}`,
|
|
236
|
+
`Skill name: ${draft.skill_name}`,
|
|
237
|
+
`Directory: ${draft.skill_dir}`,
|
|
238
|
+
`Entry workflow: ${draft.manifest.entry_workflow}`,
|
|
239
|
+
"",
|
|
240
|
+
"Files:",
|
|
241
|
+
...draft.files.map((file) => ` - ${file.relative_path}`),
|
|
242
|
+
"",
|
|
243
|
+
"Empty directories:",
|
|
244
|
+
" - scripts/",
|
|
245
|
+
" - assets/",
|
|
246
|
+
];
|
|
247
|
+
|
|
248
|
+
return lines.join("\n");
|
|
249
|
+
}
|
|
@@ -50,7 +50,7 @@ export const DEFAULT_CRON_JOBS: CronJobConfig[] = [
|
|
|
50
50
|
name: "selftune-orchestrate",
|
|
51
51
|
cron: "0 */2 * * *",
|
|
52
52
|
message:
|
|
53
|
-
"Run selftune
|
|
53
|
+
"Run selftune run --max-skills 3. This performs source-truth sync, selects candidate skills, evolves validated low-risk descriptions autonomously, and watches recent deployments for regressions.",
|
|
54
54
|
description: "Autonomous improvement loop every 2 hours",
|
|
55
55
|
},
|
|
56
56
|
];
|
|
@@ -38,6 +38,8 @@ function appendDashboardActionEvent(event: DashboardActionEvent): void {
|
|
|
38
38
|
|
|
39
39
|
function isDashboardActionName(value: string | undefined): value is DashboardActionName {
|
|
40
40
|
return (
|
|
41
|
+
value === "create-check" ||
|
|
42
|
+
value === "report-package" ||
|
|
41
43
|
value === "generate-evals" ||
|
|
42
44
|
value === "generate-unit-tests" ||
|
|
43
45
|
value === "replay-dry-run" ||
|
|
@@ -45,7 +47,8 @@ function isDashboardActionName(value: string | undefined): value is DashboardAct
|
|
|
45
47
|
value === "deploy-candidate" ||
|
|
46
48
|
value === "watch" ||
|
|
47
49
|
value === "orchestrate" ||
|
|
48
|
-
value === "rollback"
|
|
50
|
+
value === "rollback" ||
|
|
51
|
+
value === "search-run"
|
|
49
52
|
);
|
|
50
53
|
}
|
|
51
54
|
|