selftune 0.2.31 → 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.
Files changed (95) hide show
  1. package/README.md +83 -56
  2. package/apps/local-dashboard/dist/assets/index-B-ut4w0B.js +15 -0
  3. package/apps/local-dashboard/dist/assets/index-BFGfCVrL.css +1 -0
  4. package/apps/local-dashboard/dist/assets/vendor-ui-DfowE3Hu.js +1 -0
  5. package/apps/local-dashboard/dist/index.html +3 -3
  6. package/cli/selftune/command-surface.ts +613 -2
  7. package/cli/selftune/create/baseline.ts +429 -0
  8. package/cli/selftune/create/check.ts +35 -0
  9. package/cli/selftune/create/init.ts +115 -0
  10. package/cli/selftune/create/package-candidate-state.ts +771 -0
  11. package/cli/selftune/create/package-evaluator.ts +710 -0
  12. package/cli/selftune/create/package-fingerprint.ts +142 -0
  13. package/cli/selftune/create/package-search.ts +377 -0
  14. package/cli/selftune/create/publish.ts +431 -0
  15. package/cli/selftune/create/readiness.ts +495 -0
  16. package/cli/selftune/create/replay.ts +330 -0
  17. package/cli/selftune/create/report.ts +74 -0
  18. package/cli/selftune/create/scaffold.ts +121 -0
  19. package/cli/selftune/create/skills-ref-adapter.ts +177 -0
  20. package/cli/selftune/create/status.ts +33 -0
  21. package/cli/selftune/create/templates.ts +249 -0
  22. package/cli/selftune/cron/setup.ts +1 -1
  23. package/cli/selftune/dashboard-action-events.ts +4 -1
  24. package/cli/selftune/dashboard-action-result.ts +789 -24
  25. package/cli/selftune/dashboard-action-stream.ts +80 -0
  26. package/cli/selftune/dashboard-contract.ts +146 -3
  27. package/cli/selftune/dashboard-server.ts +5 -4
  28. package/cli/selftune/eval/hooks-to-evals.ts +58 -35
  29. package/cli/selftune/eval/synthetic-evals.ts +145 -17
  30. package/cli/selftune/evolution/bounded-mutations.ts +1045 -0
  31. package/cli/selftune/evolution/evolve-body.ts +9 -36
  32. package/cli/selftune/evolution/evolve.ts +8 -72
  33. package/cli/selftune/evolution/stopping-criteria.ts +5 -13
  34. package/cli/selftune/evolution/unblock-suggestions.ts +0 -16
  35. package/cli/selftune/evolution/validate-host-replay.ts +115 -15
  36. package/cli/selftune/improve.ts +206 -0
  37. package/cli/selftune/index.ts +123 -6
  38. package/cli/selftune/init.ts +1 -1
  39. package/cli/selftune/localdb/queries/dashboard.ts +30 -0
  40. package/cli/selftune/localdb/schema.ts +52 -0
  41. package/cli/selftune/monitoring/watch.ts +257 -23
  42. package/cli/selftune/orchestrate/execute.ts +300 -1
  43. package/cli/selftune/orchestrate/finalize.ts +14 -0
  44. package/cli/selftune/orchestrate/plan.ts +22 -5
  45. package/cli/selftune/orchestrate/prepare.ts +59 -4
  46. package/cli/selftune/orchestrate/report.ts +1 -1
  47. package/cli/selftune/orchestrate.ts +34 -1
  48. package/cli/selftune/publish.ts +35 -0
  49. package/cli/selftune/routes/actions.ts +81 -15
  50. package/cli/selftune/routes/overview.ts +1 -1
  51. package/cli/selftune/routes/skill-report.ts +147 -2
  52. package/cli/selftune/run.ts +18 -0
  53. package/cli/selftune/schedule.ts +3 -3
  54. package/cli/selftune/search-run.ts +703 -0
  55. package/cli/selftune/status.ts +35 -11
  56. package/cli/selftune/testing-readiness.ts +431 -40
  57. package/cli/selftune/types.ts +316 -0
  58. package/cli/selftune/utils/eval-readiness.ts +1 -0
  59. package/cli/selftune/utils/json-output.ts +11 -0
  60. package/cli/selftune/utils/lifecycle-surface.ts +48 -0
  61. package/cli/selftune/utils/query-filter.ts +82 -1
  62. package/cli/selftune/utils/tui.ts +85 -2
  63. package/cli/selftune/verify.ts +205 -0
  64. package/cli/selftune/workflows/proposals.ts +1 -1
  65. package/cli/selftune/workflows/skill-scaffold.ts +141 -63
  66. package/cli/selftune/workflows/workflows.ts +4 -4
  67. package/package.json +1 -1
  68. package/skill/SKILL.md +148 -85
  69. package/skill/references/cli-quick-reference.md +16 -1
  70. package/skill/references/creator-playbook.md +31 -10
  71. package/skill/workflows/Baseline.md +8 -9
  72. package/skill/workflows/Contributions.md +4 -4
  73. package/skill/workflows/Create.md +173 -0
  74. package/skill/workflows/CreateTestDeploy.md +34 -30
  75. package/skill/workflows/Cron.md +2 -2
  76. package/skill/workflows/Dashboard.md +3 -3
  77. package/skill/workflows/Evals.md +13 -7
  78. package/skill/workflows/Evolve.md +75 -32
  79. package/skill/workflows/EvolveBody.md +22 -15
  80. package/skill/workflows/Hook.md +1 -1
  81. package/skill/workflows/Improve.md +168 -0
  82. package/skill/workflows/Initialize.md +3 -3
  83. package/skill/workflows/Orchestrate.md +49 -12
  84. package/skill/workflows/Publish.md +100 -0
  85. package/skill/workflows/Run.md +72 -0
  86. package/skill/workflows/Schedule.md +2 -2
  87. package/skill/workflows/SearchRun.md +89 -0
  88. package/skill/workflows/SignalsDashboard.md +2 -2
  89. package/skill/workflows/UnitTest.md +13 -4
  90. package/skill/workflows/Verify.md +136 -0
  91. package/skill/workflows/Watch.md +114 -47
  92. package/skill/workflows/Workflows.md +13 -8
  93. package/apps/local-dashboard/dist/assets/index-B7v_o1WC.js +0 -15
  94. package/apps/local-dashboard/dist/assets/index-CrO77SVi.css +0 -1
  95. 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 orchestrate --max-skills 3. This performs source-truth sync, selects candidate skills, evolves validated low-risk descriptions autonomously, and watches recent deployments for regressions.",
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