devlyn-cli 3.3.1 → 4.0.1
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/AGENTS.md +8 -8
- package/CLAUDE.md +17 -17
- package/README.md +43 -30
- package/bin/devlyn.js +123 -105
- package/bin/instruction-templates.json +26 -0
- package/config/skills/_shared/adapters/README.md +1 -1
- package/config/skills/_shared/adapters/omp.md +2 -2
- package/config/skills/_shared/archive_run.py +2 -2
- package/config/skills/_shared/codex-config.md +15 -15
- package/config/skills/_shared/engine-doctor.sh +1 -1
- package/config/skills/_shared/engine-preflight.md +5 -5
- package/config/skills/_shared/finish-gate.py +1 -1
- package/config/skills/_shared/resolve-bootstrap.py +2 -2
- package/config/skills/_shared/runtime-principles.md +6 -6
- package/config/skills/_shared/spec-verify-check.py +3 -3
- package/config/skills/_shared/task-complete.py +1 -1
- package/config/skills/{devlyn:design-ui → devlyn-design-ui}/SKILL.md +1 -1
- package/config/skills/{devlyn:engines → devlyn-engines}/SKILL.md +37 -11
- package/config/skills/{devlyn:ideate → devlyn-ideate}/SKILL.md +42 -24
- package/config/skills/{devlyn:ideate → devlyn-ideate}/references/elicitation.md +2 -2
- package/config/skills/{devlyn:ideate → devlyn-ideate}/references/from-spec-mode.md +2 -2
- package/config/skills/{devlyn:ideate → devlyn-ideate}/references/project-mode.md +5 -5
- package/config/skills/{devlyn:ideate → devlyn-ideate}/references/spec-template.md +1 -1
- package/config/skills/{devlyn:queue → devlyn-queue}/SKILL.md +39 -16
- package/config/skills/devlyn-queue/scripts/append.py +94 -0
- package/config/skills/{devlyn:resolve → devlyn-resolve}/SKILL.md +38 -19
- package/config/skills/{devlyn:resolve → devlyn-resolve}/references/free-form-mode.md +3 -3
- package/config/skills/{devlyn:resolve → devlyn-resolve}/references/outer-loop.md +1 -1
- package/config/skills/{devlyn:resolve → devlyn-resolve}/references/state-schema.md +1 -1
- package/config/skills/{devlyn:resolve → devlyn-resolve}/references/task-completion.md +9 -2
- package/config/templates/prompt-templates.md +2 -2
- package/optional-skills/better-auth-setup/SKILL.md +24 -18
- package/optional-skills/{devlyn:pencil-pull → devlyn-pencil-pull}/SKILL.md +1 -1
- package/optional-skills/{devlyn:pencil-push → devlyn-pencil-push}/SKILL.md +1 -1
- package/optional-skills/{devlyn:reap → devlyn-reap}/SKILL.md +36 -5
- package/optional-skills/{devlyn:reap → devlyn-reap}/scripts/reap.sh +1 -1
- package/optional-skills/{devlyn:reap → devlyn-reap}/scripts/scan.sh +1 -1
- package/optional-skills/dokkit/COMMANDS.md +4 -4
- package/optional-skills/dokkit/EXPORT.md +3 -3
- package/optional-skills/dokkit/FILLING.md +4 -4
- package/optional-skills/dokkit/IMAGE-SOURCING.md +2 -2
- package/optional-skills/dokkit/INGESTION.md +3 -3
- package/optional-skills/dokkit/PIPELINE.md +5 -4
- package/optional-skills/dokkit/SKILL.md +35 -5
- package/optional-skills/dokkit/STATE.md +1 -1
- package/optional-skills/dokkit/references/image-opportunity-heuristics.md +1 -1
- package/optional-skills/generate-skill/REFERENCE.md +10 -13
- package/optional-skills/generate-skill/SKILL.md +13 -5
- package/package.json +3 -1
- /package/config/skills/{devlyn:ideate → devlyn-ideate}/references/templates/decision.md +0 -0
- /package/config/skills/{devlyn:ideate → devlyn-ideate}/references/templates/roadmap.md +0 -0
- /package/config/skills/{devlyn:ideate → devlyn-ideate}/references/templates/vision.md +0 -0
- /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/build-gate.md +0 -0
- /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/cleanup.md +0 -0
- /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/implement.md +0 -0
- /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/plan.md +0 -0
- /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/probe-derive.md +0 -0
- /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/surface-close.md +0 -0
- /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/verify.md +0 -0
package/bin/devlyn.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
const crypto = require('crypto');
|
|
3
4
|
const fs = require('fs');
|
|
4
5
|
const path = require('path');
|
|
5
6
|
const os = require('os');
|
|
@@ -14,35 +15,57 @@ const { updateInstructions, InstructionError } = require('./instructions');
|
|
|
14
15
|
// The devlyn skill bundle installed into every skill-capable agent's loader
|
|
15
16
|
// directory. Single source of truth so codex/omp/pi stay in lockstep — adding a
|
|
16
17
|
// skill here installs it everywhere.
|
|
17
|
-
const DEVLYN_CORE_SKILLS = ['devlyn
|
|
18
|
-
|
|
18
|
+
const DEVLYN_CORE_SKILLS = ['devlyn-resolve', 'devlyn-ideate', 'devlyn-design-ui', 'devlyn-engines', 'devlyn-queue', '_shared'];
|
|
19
|
+
// 4.0.0 renamed the colon-named skills to the Agent Skills standard (`[a-z0-9-]`, name ==
|
|
20
|
+
// folder): Git for Windows cannot check out a folder with ':' in its name. Installs from 3.x
|
|
21
|
+
// and earlier keep the old folder under either spelling (':' or npm's U+F03A extraction
|
|
22
|
+
// alias). Both are removed, and an optional skill that was installed is installed again
|
|
23
|
+
// under its new name in the same place.
|
|
24
|
+
const RENAMED_SKILLS = {
|
|
25
|
+
'devlyn:resolve': 'devlyn-resolve',
|
|
26
|
+
'devlyn:ideate': 'devlyn-ideate',
|
|
27
|
+
'devlyn:design-ui': 'devlyn-design-ui',
|
|
28
|
+
'devlyn:engines': 'devlyn-engines',
|
|
29
|
+
'devlyn:queue': 'devlyn-queue',
|
|
30
|
+
'devlyn:pencil-pull': 'devlyn-pencil-pull',
|
|
31
|
+
'devlyn:pencil-push': 'devlyn-pencil-push',
|
|
32
|
+
'devlyn:reap': 'devlyn-reap',
|
|
33
|
+
};
|
|
19
34
|
const DEVLYN_INSTALL_MARKER = '.devlyn-install.json';
|
|
20
35
|
|
|
21
|
-
|
|
22
|
-
|
|
36
|
+
// Every spelling a colon name can have on disk: its own and npm's U+F03A extraction alias.
|
|
37
|
+
function legacySkillPaths(root, name) {
|
|
38
|
+
return [...new Set([name, name.replace(/:/g, '\uF03A')])].map((spelling) => path.join(root, spelling));
|
|
23
39
|
}
|
|
24
40
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
// SKILL.md of the pencil skills 0.6.0-0.7.1 installed under today's names, without the
|
|
42
|
+
// frontmatter the standard requires, hashed with LF line endings (a Windows checkout may hold
|
|
43
|
+
// CRLF). 3.x deleted these copies; 4.0 replaces them.
|
|
44
|
+
const PRE_STANDARD_SKILL_MD_SHA256 = new Set([
|
|
45
|
+
'dfdd3d19ca676558bfa2bb3ce398181b0a081ab88d1feaf69c54c706a9671631', // devlyn-pencil-pull
|
|
46
|
+
'5f2e8b29609cbb2af72941579823bec598265ebf29cd3a375d6aa47d95b74354', // devlyn-pencil-push
|
|
47
|
+
]);
|
|
28
48
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
// Skills devlyn-cli shipped and later deleted without listing them, by SHA-256 of their only
|
|
50
|
+
// file, SKILL.md (LF endings): a user's own folder of the same name is never removed.
|
|
51
|
+
const RETIRED_SKILL_MD_SHA256 = {
|
|
52
|
+
// 0.2.0-1.15.0; deleted in iter-0034, it still routes agents to retired commands.
|
|
53
|
+
'workflow-routing': new Set([
|
|
54
|
+
'7fec2bb20d808a873a975d64a6223e404bc5b328c800760bb77257ae6b2f467a',
|
|
55
|
+
'8bfdaeff2ce48d5a79b5653de3bbe0d56a61a7fd750ed3ad11149fec5a502ecf',
|
|
56
|
+
]),
|
|
57
|
+
};
|
|
37
58
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
59
|
+
// Whether `dir` is a real folder whose only file (dotfiles such as .DS_Store aside) is a SKILL.md
|
|
60
|
+
// with an LF-normalized SHA-256 in `hashes`: an unedited copy devlyn-cli shipped, not something
|
|
61
|
+
// the user added to or wrote.
|
|
62
|
+
function isShippedCopy(dir, hashes) {
|
|
63
|
+
const skill = path.join(dir, 'SKILL.md');
|
|
64
|
+
return fs.lstatSync(dir, { throwIfNoEntry: false })?.isDirectory() === true
|
|
65
|
+
&& fs.readdirSync(dir).filter((name) => !name.startsWith('.')).length === 1
|
|
66
|
+
&& fs.lstatSync(skill, { throwIfNoEntry: false })?.isFile() === true
|
|
67
|
+
&& hashes.has(crypto.createHash('sha256')
|
|
68
|
+
.update(fs.readFileSync(skill, 'utf8').replace(/\r\n/g, '\n')).digest('hex'));
|
|
46
69
|
}
|
|
47
70
|
|
|
48
71
|
// Cross-agent shared skills directory read by BOTH oh-my-pi and Pi. Verified
|
|
@@ -134,21 +157,17 @@ const DEPRECATED_DIRS = [
|
|
|
134
157
|
// v0.7.x rename: devlyn-* → devlyn:*
|
|
135
158
|
'skills/devlyn-clean',
|
|
136
159
|
'skills/devlyn-design-system',
|
|
137
|
-
'skills/devlyn-design-ui',
|
|
138
160
|
'skills/devlyn-discover-product',
|
|
139
161
|
'skills/devlyn-evaluate',
|
|
140
162
|
'skills/devlyn-feature-spec',
|
|
141
163
|
'skills/devlyn-implement-ui',
|
|
142
164
|
'skills/devlyn-product-spec',
|
|
143
165
|
'skills/devlyn-recommend-features',
|
|
144
|
-
'skills/devlyn-resolve',
|
|
145
166
|
'skills/devlyn-review',
|
|
146
167
|
'skills/devlyn-team-design-ui',
|
|
147
168
|
'skills/devlyn-team-resolve',
|
|
148
169
|
'skills/devlyn-team-review',
|
|
149
170
|
'skills/devlyn-update-docs',
|
|
150
|
-
'skills/devlyn-pencil-pull',
|
|
151
|
-
'skills/devlyn-pencil-push',
|
|
152
171
|
// iter-0034 Phase 4 cutover: deleted user skills
|
|
153
172
|
'skills/devlyn:auto-resolve',
|
|
154
173
|
'skills/devlyn:browser-validate',
|
|
@@ -164,10 +183,6 @@ const DEPRECATED_DIRS = [
|
|
|
164
183
|
'skills/devlyn:team-resolve',
|
|
165
184
|
'skills/devlyn:team-review',
|
|
166
185
|
'skills/devlyn:update-docs',
|
|
167
|
-
// iter-0034 Phase 4 cutover: moved to optional-skills/. Force-removed on
|
|
168
|
-
// upgrade so users only have them if they opt in via the interactive
|
|
169
|
-
// installer (matches the pencil-pull / pencil-push pattern).
|
|
170
|
-
'skills/devlyn:reap',
|
|
171
186
|
// 0221 Session 1: standards skills moved to optional-skills/ (opt-in).
|
|
172
187
|
'skills/code-health-standards',
|
|
173
188
|
'skills/code-review-standards',
|
|
@@ -238,9 +253,9 @@ const OPTIONAL_ADDONS = [
|
|
|
238
253
|
{ name: 'polar-billing-setup', desc: 'Polar usage-based / metered billing — correct setup + diagnose silent $0-billing failures', type: 'local' },
|
|
239
254
|
{ name: 'pyx-scan', desc: 'Check whether an AI agent skill is safe before installing', type: 'local' },
|
|
240
255
|
{ name: 'dokkit', desc: 'Document template filling for DOCX/HWPX — ingest, fill, review, export', type: 'local' },
|
|
241
|
-
{ name: 'devlyn
|
|
242
|
-
{ name: 'devlyn
|
|
243
|
-
{ name: 'devlyn
|
|
256
|
+
{ name: 'devlyn-pencil-pull', desc: 'Pull Pencil designs into code with exact visual fidelity', type: 'local' },
|
|
257
|
+
{ name: 'devlyn-pencil-push', desc: 'Push codebase UI to Pencil canvas for design sync', type: 'local' },
|
|
258
|
+
{ name: 'devlyn-reap', desc: 'Safely reap orphaned MCP / codex / Superset child processes left behind by long Claude sessions', type: 'local' },
|
|
244
259
|
{ name: 'code-health-standards', desc: 'Maintainability standards — dead code, dependencies, complexity, naming, hygiene', type: 'local' },
|
|
245
260
|
{ name: 'code-review-standards', desc: 'Severity framework and approval criteria for reviewing a change', type: 'local' },
|
|
246
261
|
{ name: 'root-cause-analysis', desc: 'Evidence-first why-chain debugging to the actionable root cause', type: 'local' },
|
|
@@ -255,7 +270,7 @@ const OPTIONAL_ADDONS = [
|
|
|
255
270
|
// Note: the Codex integration uses the local `codex` CLI binary (not MCP).
|
|
256
271
|
// Install the CLI separately per https://platform.openai.com/docs/codex — the
|
|
257
272
|
// pair/risk-probe routes fail closed when Codex is required but unavailable.
|
|
258
|
-
{ name: 'playwright', desc: 'Playwright MCP for browser testing — powers /devlyn
|
|
273
|
+
{ name: 'playwright', desc: 'Playwright MCP for browser testing — powers /devlyn-resolve BUILD_GATE browser tier', type: 'mcp', command: 'npx -y @playwright/mcp@latest' },
|
|
259
274
|
];
|
|
260
275
|
|
|
261
276
|
function log(msg, color = 'reset') {
|
|
@@ -349,8 +364,8 @@ function listContents() {
|
|
|
349
364
|
|
|
350
365
|
function cleanupDeprecated(targetDir) {
|
|
351
366
|
let removed = 0;
|
|
352
|
-
const deprecated = DEPRECATED_DIRS.
|
|
353
|
-
|
|
367
|
+
const deprecated = DEPRECATED_DIRS.flatMap((relPath) =>
|
|
368
|
+
legacySkillPaths(path.join(targetDir, 'skills'), path.basename(relPath)).map((fullPath) => [relPath, fullPath]));
|
|
354
369
|
for (const relPath of DEPRECATED_FILES) {
|
|
355
370
|
const fullPath = path.join(targetDir, relPath);
|
|
356
371
|
if (fs.existsSync(fullPath)) {
|
|
@@ -366,22 +381,46 @@ function cleanupDeprecated(targetDir) {
|
|
|
366
381
|
removed++;
|
|
367
382
|
}
|
|
368
383
|
}
|
|
384
|
+
for (const [name, hashes] of Object.entries(RETIRED_SKILL_MD_SHA256)) {
|
|
385
|
+
const fullPath = path.join(targetDir, 'skills', name);
|
|
386
|
+
if (isShippedCopy(fullPath, hashes)) {
|
|
387
|
+
fs.rmSync(fullPath, { recursive: true });
|
|
388
|
+
log(` ✕ skills/${name}/ (removed)`, 'dim');
|
|
389
|
+
removed++;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
369
392
|
return removed;
|
|
370
393
|
}
|
|
371
394
|
|
|
395
|
+
// Remove every old spelling of the renamed skills in `skillsDir`, after the new core skills
|
|
396
|
+
// are in place. An optional skill found under an old spelling is installed under its new name
|
|
397
|
+
// before the old copy goes, so an interrupted migration never loses it. An unedited 0.6.0-0.7.1
|
|
398
|
+
// copy is refreshed in place. Any other folder under a 4.0 name is the user's own; `-y` leaves it.
|
|
399
|
+
function retireRenamedSkills(skillsDir) {
|
|
400
|
+
const optional = new Set(OPTIONAL_ADDONS.filter((addon) => addon.type === 'local').map((addon) => addon.name));
|
|
401
|
+
for (const [oldName, newName] of Object.entries(RENAMED_SKILLS)) {
|
|
402
|
+
const found = legacySkillPaths(skillsDir, oldName).filter((fullPath) => fs.existsSync(fullPath));
|
|
403
|
+
if (found.length > 0 && optional.has(newName)) installOptionalSkillInto(skillsDir, newName);
|
|
404
|
+
else if (isShippedCopy(path.join(skillsDir, newName), PRE_STANDARD_SKILL_MD_SHA256)) refreshPreStandardCopy(skillsDir, newName);
|
|
405
|
+
for (const fullPath of found) {
|
|
406
|
+
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
407
|
+
log(` ✕ ${path.basename(fullPath)}/ (renamed to ${newName})`, 'dim');
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
372
412
|
function copyRecursive(src, dest, baseDir) {
|
|
373
413
|
const stats = fs.statSync(src);
|
|
374
414
|
|
|
375
415
|
if (stats.isDirectory()) {
|
|
376
416
|
// Never install dev workspaces, even when running from source repo.
|
|
377
|
-
if (UNSHIPPED_SKILL_DIRS.has(
|
|
417
|
+
if (UNSHIPPED_SKILL_DIRS.has(path.basename(src))) return;
|
|
378
418
|
if (!fs.existsSync(dest)) {
|
|
379
419
|
fs.mkdirSync(dest, { recursive: true });
|
|
380
420
|
}
|
|
381
421
|
|
|
382
422
|
for (const item of fs.readdirSync(src)) {
|
|
383
|
-
|
|
384
|
-
copyRecursive(path.join(src, item), path.join(dest, name), baseDir);
|
|
423
|
+
copyRecursive(path.join(src, item), path.join(dest, item), baseDir);
|
|
385
424
|
}
|
|
386
425
|
} else {
|
|
387
426
|
const destDir = path.dirname(dest);
|
|
@@ -407,8 +446,8 @@ function assertCompleteSkillInstall(sourceSkillsDir, skillsDir, skillNames) {
|
|
|
407
446
|
return fs.statSync(dest).isFile();
|
|
408
447
|
}
|
|
409
448
|
const missing = skillNames.filter((name) => {
|
|
410
|
-
const src =
|
|
411
|
-
const dest =
|
|
449
|
+
const src = path.join(sourceSkillsDir, name);
|
|
450
|
+
const dest = path.join(skillsDir, name);
|
|
412
451
|
return !complete(src, dest) || (name !== '_shared' && !fs.existsSync(path.join(src, 'SKILL.md')));
|
|
413
452
|
});
|
|
414
453
|
if (missing.length > 0) {
|
|
@@ -436,45 +475,12 @@ function writeInstallMarker(skillsDir) {
|
|
|
436
475
|
}
|
|
437
476
|
}
|
|
438
477
|
|
|
439
|
-
function shellDoubleQuoteDefault(value) {
|
|
440
|
-
if (value.includes('\n')) {
|
|
441
|
-
throw new Error(`Cannot stamp skill path with newline: ${value}`);
|
|
442
|
-
}
|
|
443
|
-
return value.replace(/[\\$"`}]/g, '\\$&');
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
function stampInstalledSkillDir(rootDir, skillDir) {
|
|
447
|
-
// Stamp ONLY the assignment-default occurrence. The sentinel comparison
|
|
448
|
-
// literal on the guard line must stay intact: stamping it makes the guard
|
|
449
|
-
// compare the stamped default to itself and false-positive
|
|
450
|
-
// BLOCKED:shared-dir-unresolved on every codex/omp run that executes the
|
|
451
|
-
// block (CLAUDE_SKILL_DIR unset) — iter-0040 R3 latent finding.
|
|
452
|
-
const assignmentStamp = '${CLAUDE_SKILL_DIR:-' + DEVLYN_SKILL_DIR_STAMP + '}';
|
|
453
|
-
const stampedAssignment = '${CLAUDE_SKILL_DIR:-' + shellDoubleQuoteDefault(skillDir) + '}';
|
|
454
|
-
|
|
455
|
-
function visit(current) {
|
|
456
|
-
const stats = fs.statSync(current);
|
|
457
|
-
if (stats.isDirectory()) {
|
|
458
|
-
for (const item of fs.readdirSync(current)) {
|
|
459
|
-
visit(path.join(current, item));
|
|
460
|
-
}
|
|
461
|
-
return;
|
|
462
|
-
}
|
|
463
|
-
if (path.extname(current) !== '.md') return;
|
|
464
|
-
|
|
465
|
-
const content = fs.readFileSync(current, 'utf8');
|
|
466
|
-
if (!content.includes(assignmentStamp)) return;
|
|
467
|
-
fs.writeFileSync(current, content.split(assignmentStamp).join(stampedAssignment));
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
visit(rootDir);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
478
|
// Dev artifacts that live under config/skills/ but must never ship or install.
|
|
474
479
|
// Mirrors the `!` exclusions in package.json files[].
|
|
475
480
|
const UNSHIPPED_SKILL_DIRS = new Set([
|
|
476
481
|
'devlyn:auto-resolve-workspace',
|
|
477
482
|
'devlyn:ideate-workspace',
|
|
483
|
+
'devlyn-ideate-workspace',
|
|
478
484
|
'preflight-workspace',
|
|
479
485
|
'roadmap-archival-workspace',
|
|
480
486
|
]);
|
|
@@ -488,12 +494,11 @@ const UNSHIPPED_SKILL_DIRS = new Set([
|
|
|
488
494
|
// no counterpart in source. Dev workspaces are skipped entirely.
|
|
489
495
|
function cleanManagedSkillDirs(sourceSkillsDir, targetSkillsDir) {
|
|
490
496
|
if (!fs.existsSync(sourceSkillsDir) || !fs.existsSync(targetSkillsDir)) return 0;
|
|
491
|
-
preflightSkillDirs(sourceSkillsDir, targetSkillsDir, fs.readdirSync(sourceSkillsDir));
|
|
492
497
|
let cleaned = 0;
|
|
493
498
|
for (const entry of fs.readdirSync(sourceSkillsDir, { withFileTypes: true })) {
|
|
494
499
|
if (!entry.isDirectory()) continue;
|
|
495
|
-
if (UNSHIPPED_SKILL_DIRS.has(
|
|
496
|
-
const targetPath =
|
|
500
|
+
if (UNSHIPPED_SKILL_DIRS.has(entry.name)) continue;
|
|
501
|
+
const targetPath = path.join(targetSkillsDir, entry.name);
|
|
497
502
|
if (fs.existsSync(targetPath)) {
|
|
498
503
|
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
499
504
|
cleaned++;
|
|
@@ -596,11 +601,10 @@ function multiSelect(items, preselectedIndices = []) {
|
|
|
596
601
|
}
|
|
597
602
|
|
|
598
603
|
function installLocalSkill(skillName) {
|
|
599
|
-
const src =
|
|
604
|
+
const src = path.join(OPTIONAL_SKILLS_SOURCE, skillName);
|
|
600
605
|
const targetDir = getTargetDir();
|
|
601
606
|
const targets = new Set([path.join(targetDir, 'skills'), ...Object.values(CLI_TARGETS)
|
|
602
607
|
.map((cli) => cli.skillsDir).filter((dir) => dir && fs.existsSync(dir))]);
|
|
603
|
-
for (const target of targets) skillPath(target, skillName);
|
|
604
608
|
|
|
605
609
|
if (!fs.existsSync(src)) {
|
|
606
610
|
log(` ⚠️ Skill "${skillName}" not found`, 'yellow');
|
|
@@ -615,16 +619,37 @@ function installLocalSkill(skillName) {
|
|
|
615
619
|
// create an agent install just because someone opted into a Claude-side skill.
|
|
616
620
|
// De-dup by directory: omp and Pi share ~/.agents/skills, so the mirror runs
|
|
617
621
|
// once per unique destination.
|
|
618
|
-
for (const target of targets)
|
|
619
|
-
fs.rmSync(skillPath(target, skillName), { recursive: true, force: true });
|
|
620
|
-
const dest = path.join(target, physicalSkillName(skillName));
|
|
621
|
-
copyRecursive(src, dest, target);
|
|
622
|
-
stampInstalledSkillDir(dest, dest);
|
|
623
|
-
assertCompleteSkillInstall(OPTIONAL_SKILLS_SOURCE, target, [skillName]);
|
|
624
|
-
}
|
|
622
|
+
for (const target of targets) installOptionalSkillInto(target, skillName);
|
|
625
623
|
return true;
|
|
626
624
|
}
|
|
627
625
|
|
|
626
|
+
// One optional skill into one skill-loader directory, replacing any older copy of it. A
|
|
627
|
+
// copy under its name before the 4.0.0 rename goes only once the new one is complete.
|
|
628
|
+
function installOptionalSkillInto(target, skillName) {
|
|
629
|
+
const dest = path.join(target, skillName);
|
|
630
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
631
|
+
copyRecursive(path.join(OPTIONAL_SKILLS_SOURCE, skillName), dest, target);
|
|
632
|
+
assertCompleteSkillInstall(OPTIONAL_SKILLS_SOURCE, target, [skillName]);
|
|
633
|
+
const oldName = Object.keys(RENAMED_SKILLS).find((name) => RENAMED_SKILLS[name] === skillName);
|
|
634
|
+
for (const fullPath of oldName ? legacySkillPaths(target, oldName) : []) {
|
|
635
|
+
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// A 0.6.0-0.7.1 copy is one SKILL.md, the file that identifies it. Renaming the new one over it is
|
|
640
|
+
// atomic, so an interrupted run leaves the old copy, which the retry finds again, or the new.
|
|
641
|
+
function refreshPreStandardCopy(target, skillName) {
|
|
642
|
+
const skill = path.join(target, skillName, 'SKILL.md');
|
|
643
|
+
const staged = `${skill}.${process.pid}.tmp`;
|
|
644
|
+
try {
|
|
645
|
+
fs.copyFileSync(path.join(OPTIONAL_SKILLS_SOURCE, skillName, 'SKILL.md'), staged);
|
|
646
|
+
fs.renameSync(staged, skill);
|
|
647
|
+
} finally {
|
|
648
|
+
fs.rmSync(staged, { force: true });
|
|
649
|
+
}
|
|
650
|
+
assertCompleteSkillInstall(OPTIONAL_SKILLS_SOURCE, target, [skillName]);
|
|
651
|
+
}
|
|
652
|
+
|
|
628
653
|
function installMcpServer(name, command) {
|
|
629
654
|
try {
|
|
630
655
|
log(`\n🔌 Installing MCP server: ${name}...`, 'cyan');
|
|
@@ -681,7 +706,6 @@ function installSkillsForCLI(cliKey) {
|
|
|
681
706
|
fs.mkdirSync(cli.skillsDir, { recursive: true });
|
|
682
707
|
}
|
|
683
708
|
clearInstallMarker(cli.skillsDir);
|
|
684
|
-
preflightSkillDirs(sourceSkillsDir, cli.skillsDir, cli.skillsToInstall);
|
|
685
709
|
|
|
686
710
|
const removed = cleanupDeprecated(path.dirname(cli.skillsDir));
|
|
687
711
|
if (removed > 0) {
|
|
@@ -690,21 +714,20 @@ function installSkillsForCLI(cliKey) {
|
|
|
690
714
|
|
|
691
715
|
let copied = 0;
|
|
692
716
|
for (const skillName of cli.skillsToInstall) {
|
|
693
|
-
const src =
|
|
694
|
-
const
|
|
695
|
-
const dest = path.join(cli.skillsDir, physicalSkillName(skillName));
|
|
717
|
+
const src = path.join(sourceSkillsDir, skillName);
|
|
718
|
+
const dest = path.join(cli.skillsDir, skillName);
|
|
696
719
|
if (!fs.existsSync(src)) continue;
|
|
697
720
|
// Full replace per cleanManagedSkillDirs semantics: stale files in the
|
|
698
721
|
// installed mirror would otherwise persist forever.
|
|
699
|
-
if (fs.existsSync(
|
|
700
|
-
fs.rmSync(
|
|
722
|
+
if (fs.existsSync(dest)) {
|
|
723
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
701
724
|
}
|
|
702
725
|
copyRecursive(src, dest, cli.skillsDir);
|
|
703
|
-
stampInstalledSkillDir(dest, dest);
|
|
704
726
|
copied++;
|
|
705
727
|
log(` → ${cli.skillsDir.replace(os.homedir(), '~')}/${skillName}`, 'dim');
|
|
706
728
|
}
|
|
707
729
|
assertCompleteSkillInstall(sourceSkillsDir, cli.skillsDir, cli.skillsToInstall);
|
|
730
|
+
retireRenamedSkills(cli.skillsDir);
|
|
708
731
|
writeInstallMarker(cli.skillsDir);
|
|
709
732
|
return copied;
|
|
710
733
|
}
|
|
@@ -803,6 +826,10 @@ function installClaudeCore() {
|
|
|
803
826
|
log('\n📁 Installing Claude Code config to .claude/', 'green');
|
|
804
827
|
if (!fs.existsSync(skillsDir)) fs.mkdirSync(skillsDir, { recursive: true });
|
|
805
828
|
clearInstallMarker(skillsDir);
|
|
829
|
+
const removed = cleanupDeprecated(targetDir);
|
|
830
|
+
if (removed > 0) {
|
|
831
|
+
log(`\n🧹 Cleaned up ${removed} deprecated file${removed > 1 ? 's' : ''}`, 'yellow');
|
|
832
|
+
}
|
|
806
833
|
const refreshed = cleanManagedSkillDirs(
|
|
807
834
|
path.join(CONFIG_SOURCE, 'skills'),
|
|
808
835
|
skillsDir,
|
|
@@ -812,18 +839,9 @@ function installClaudeCore() {
|
|
|
812
839
|
}
|
|
813
840
|
copyRecursive(CONFIG_SOURCE, targetDir, targetDir);
|
|
814
841
|
assertCompleteSkillInstall(path.join(CONFIG_SOURCE, 'skills'), skillsDir, DEVLYN_CORE_SKILLS);
|
|
815
|
-
|
|
816
|
-
const dest = skillPath(skillsDir, name);
|
|
817
|
-
stampInstalledSkillDir(dest, dest);
|
|
818
|
-
}
|
|
842
|
+
retireRenamedSkills(skillsDir);
|
|
819
843
|
writeInstallMarker(skillsDir);
|
|
820
844
|
|
|
821
|
-
// Remove deprecated files from previous versions
|
|
822
|
-
const removed = cleanupDeprecated(targetDir);
|
|
823
|
-
if (removed > 0) {
|
|
824
|
-
log(`\n🧹 Cleaned up ${removed} deprecated file${removed > 1 ? 's' : ''}`, 'yellow');
|
|
825
|
-
}
|
|
826
|
-
|
|
827
845
|
// Keep installer-managed pipeline state and install metadata out of git.
|
|
828
846
|
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
829
847
|
const gitignoreEntries = ['.devlyn/', '.claude/skills/.devlyn-install.json'];
|
|
@@ -149,10 +149,13 @@
|
|
|
149
149
|
"4bbcb7fefd5366ed4151ce588e8482b747bdd85a7ecf795862a1c243218a162f",
|
|
150
150
|
"4c3c4295f7cb794d0466f93886bf89b316382feafec68606385eb6b4c36eebbc",
|
|
151
151
|
"4c4ee4b0948bc84b130c39b9846a5317ec76a6e3a8d95281a78e740192081662",
|
|
152
|
+
"4cae665b0a714cd7b20b59ef356b53e21dec1cf4679458de2a23b5077bceafff",
|
|
153
|
+
"4d42f91b8ff88de40921f825ec3a9aeeba30e85c7442ea2f8876b7c68555c39c",
|
|
152
154
|
"4d756bc5c6a7c7ca1589efc6c340c75fb389699fe14d114aa211a29921e7effe",
|
|
153
155
|
"4dcba526b49c91411d98925a7f638d990acea0f904ba8f143f195f7f99f85e33",
|
|
154
156
|
"4e114313a6fbf27b89bebe7847f9aebb4ca2c61d23d167997efd459fa091e602",
|
|
155
157
|
"4f6bf3fa8b8b706d234a7d5a3dda34e52ce1fcba68770aadf606c1717543bd5a",
|
|
158
|
+
"50fe2edc6da214c0ae4bfce43d8d210f98ff15da2d2f9bca88269dab9a4ed179",
|
|
156
159
|
"53a8f3196d2320ba46bf1299bfabb38dff495218bb47b35a43ac5072308f9deb",
|
|
157
160
|
"54cdf7a05afb97642d06a0d8284f17d51fed5ce0fdcdac949655c47734802893",
|
|
158
161
|
"55ff3f39ef7341cfb1e8b50271821d574eeddc455461d6df317caa9c5b55827f",
|
|
@@ -193,6 +196,7 @@
|
|
|
193
196
|
"76517a747d47a3986b7181db4bbe5898ad3d6d82644ce39d8bf62edc998cecb9",
|
|
194
197
|
"766c776b750cb84f084c49679fa377899693acf5f8d4e00751ca0fab97b4f030",
|
|
195
198
|
"78690fc75b54ee634413fd0d5f6892692b2557e8838fbb8453f7bdd4b6519cc5",
|
|
199
|
+
"7a0d897737f705b0276b829df5b62fd9541e3897b872b2a2668f54e08b88dfff",
|
|
196
200
|
"7aab816bfa43d73b4eb8bd9136242e8a4938f3610e7ad3c32e033b7ee3d28a1e",
|
|
197
201
|
"7fde023e25658ff48c67b6708c5b6f383a6497a509946cb3bdc5da7d35e4f3f6",
|
|
198
202
|
"8211bb3dcc9d7df40c393a4ef8e620526d84ded9faec25655cfa74801458515d",
|
|
@@ -200,6 +204,7 @@
|
|
|
200
204
|
"8574b17a21f98a1cf558a7b88780eda07e8c39943168d0be49cbf4575edc23f1",
|
|
201
205
|
"8694f41265b0f74734ce6801434fe255a4c2261501bcf13d37fe2e5b85a859e9",
|
|
202
206
|
"870810ca9060fa45ef2eafd41c21282a21b9493cbec9632e2893556d07f3301f",
|
|
207
|
+
"890e3bdec4212b404e6c3675021922215d96705bb8def099a0d04ee65286585c",
|
|
203
208
|
"892c26f1d54958622f5615734666f3b1aedb07e7a3ac225c416a5d3f1508312c",
|
|
204
209
|
"8954f0209ecdac5a48f68c9ba5da95840ba745aabfb3751c6c216a06d809d1c9",
|
|
205
210
|
"897d0d57a5ab67b082a3fbaf078ac3e9c724acb033b6df35b8959ae28c26bc93",
|
|
@@ -221,6 +226,7 @@
|
|
|
221
226
|
"9e65019acb60433529160c929b840398fe6e5d72dcfd219cb79e69ba2d3cd5e9",
|
|
222
227
|
"9f62c5b2a94e8b5e81528ccbdb6f78d147d14882108568b2cb3b7f85212694c0",
|
|
223
228
|
"a02eb2d8d77553327fb77377dbfedeab059b2e68e0a33c469b9be54a5d55182b",
|
|
229
|
+
"a27ec7f5f0f0a2798e53695f20dc43fe28378d551fc060e2c772d0b522a336e5",
|
|
224
230
|
"a3a15249968f64085b0cec8c0826688a4c3a1e4cf09b4879054baa086d5cbca1",
|
|
225
231
|
"a4da26a46ab83815d8ca5d747c68a907ad67dad485adbc6c863b982ee23b307e",
|
|
226
232
|
"a5d6ff585d696254d6727cd1e6d7f8825881f90210eff744265e211ced715ea3",
|
|
@@ -228,6 +234,7 @@
|
|
|
228
234
|
"aafc680a7ac73e100f4a17d2c4070190e68563f78614c39f4c2f58f1e291d9a9",
|
|
229
235
|
"ab7f6d08d95cf1c22b7ec6e2e113158b7f767b73d8dde04fd1c3b33788922c93",
|
|
230
236
|
"ac432d9179f245fec0beaf4010355613dcd6d476d8c9268c9cd430c98e73ff35",
|
|
237
|
+
"af3a498714fecb29ebdc1e43e5cc0425efaf1c290130e6913cabd75fe4c9cc67",
|
|
231
238
|
"af77f01317665c50815eb3cfefe481519efcc9c8b81bac06fc110abf723c7868",
|
|
232
239
|
"b3921b2317558010f99625aff30f3ed7a7a0dd4f37c586a6c4f9e1001e100134",
|
|
233
240
|
"b3ac898e73c5b7923c1050bdbc36144dc6f4ad8bd9b83c8515394c418ef447ed",
|
|
@@ -266,12 +273,14 @@
|
|
|
266
273
|
"d189a2002b4ef0e858acb734c4ed14f6af6f0b7bb250b178f65d439369a9149a",
|
|
267
274
|
"d41692aa7577bbd85144fe73d111947f98e1304f4aceb891d712daa5907d550d",
|
|
268
275
|
"d486a0b267c9425bde2cba737d802d2412a9b4b4b339e925500c1643327d2a3d",
|
|
276
|
+
"d5d8d02a1fb53cd28ed1c33e7184067b76defbfcc6cab9498b365dee35579013",
|
|
269
277
|
"d75bdfc9cf08cfcb46214f69dac4f20b1a0a30b86d91127007fe587de9eaaeb0",
|
|
270
278
|
"d768a149b5842e0d50eda941872188c8b29bcfb4b1aa0f4190fd4299f237fce0",
|
|
271
279
|
"d8c50cb04441e6b568236bc6cd494b4de296dfc7e8b33cf96e7aeb94612df3b8",
|
|
272
280
|
"da019f3edfb762b9216016a3ea9cf7211b2ba698a55ddda5cec2e478218b0288",
|
|
273
281
|
"ddb200267b43942de3c061b449d08cc3f73441258b74816cfe13da091377b428",
|
|
274
282
|
"dff43f9976c68267baf13f6a460f24af8e76be233c8440ac4684dc664106deae",
|
|
283
|
+
"e05f671dbf45aef8e7e4211195d46be8554c188d8df8899093359c414ffef2fe",
|
|
275
284
|
"e237f12ed08800ccc4c6eb4ae57cdd59d61198711f6a3b02dcb668aa08fddb93",
|
|
276
285
|
"e289dbab99dadb30d8315b32b8243154148c82955f238936bce4c1fe1c3ae525",
|
|
277
286
|
"e2bac40f3ff0b39726f95caaa9b19aa3b21596f165ac7a9dc68ebf42681d58cb",
|
|
@@ -328,6 +337,7 @@
|
|
|
328
337
|
"07d5c3147813efd7b5cf262709d4ee1643f962e5442f1f6e0f374d12d8d8c346",
|
|
329
338
|
"07ec9e6c76821368b71110413acf43edd6e3c91b93e380eebed8f363a1915c7a",
|
|
330
339
|
"080051ed34915b572971d9fc734b95ba7a7984f6e799a7286055d41a7aeaa3b6",
|
|
340
|
+
"0845abb4d59bce13c33c80b3292ba829bace0abe26d67a100a3bbc07e5db2b7d",
|
|
331
341
|
"086b65c51d3342970968f4c3c6554a605b8740ed82809d26587cbd08f87d19f8",
|
|
332
342
|
"0ab05e7ec571a8c899901514ab0655622817e8a77254ec2ec763fd78dad7f5bd",
|
|
333
343
|
"0b45db686d97f33be4dc2b091ed259de534c2e3f97f8787574e722d2e86a0c1d",
|
|
@@ -367,6 +377,7 @@
|
|
|
367
377
|
"18b3b8a84421d45d2f1cfd2d3bc936bb1635eb9fb426587ffb8b10ab224f5562",
|
|
368
378
|
"18d96415b31677a8efe1d8e5d3246c62456fdee9f6371e8bc7817de6c062eb50",
|
|
369
379
|
"1a7c6046a588a2608c146e5cb4403d943ef1d70f3779be1920a245442b48d7af",
|
|
380
|
+
"1af26e8d5dc8268e6372c1f2429aa2531a5780ae1956530a5b2978451121b4eb",
|
|
370
381
|
"1b0c98cba21a4d616442124ed1e29259006398777a40fac41ba6b1894727c31f",
|
|
371
382
|
"1c12577abd7db4345386fc7f24148dcbf6dabfe2ac89de3089fd27cca797aa0c",
|
|
372
383
|
"1c14e388ba39b4953aa51b2b73a92d287027f6849e25ee8725d9e3ea51f78fa1",
|
|
@@ -401,6 +412,7 @@
|
|
|
401
412
|
"2712e0f66046a30d80b9127688c67c73e809521dddedef1c10fad373d9a22114",
|
|
402
413
|
"278bed8b8219c30412f09523678c050173875c14aa8545062e718669a4e76ee8",
|
|
403
414
|
"27fe72a818b59177a7e692df7b02048eb7b8dd3b34e6e5a7717f2898df66ea00",
|
|
415
|
+
"284c050b55f96ae3c30d7f006aedd815f6b9601ceab010d569bc8622ee389fc3",
|
|
404
416
|
"287fa116a8235756a8b0e28caa951a9ad981667443434e13dbfde3c23f1590e6",
|
|
405
417
|
"28c5b42a58dca1a093576c8c35369c346caaf3963e14a4702ab3330d0d93e4d4",
|
|
406
418
|
"2939f7a22fd12f3ca3fdd0a08fc52535cf25dae38b9b445aceed09dc331fc1de",
|
|
@@ -444,6 +456,7 @@
|
|
|
444
456
|
"3ab5f6021b62f21624e3eed505cc6849c66972d01ac67337533cff0e81dc9dc8",
|
|
445
457
|
"3afe3870751373b6059ebddfb6c179ab70b7a1f3a9299555ecf5ea47c2970422",
|
|
446
458
|
"3b5bf36be5ad797443dc5c1c407684c6f86b28894ca9a975a3fb5c18b3066fbb",
|
|
459
|
+
"3ba1747fbe0662a0aa9c42e6e442748f013a8e90febc330e2854ab9ad841dd77",
|
|
447
460
|
"3cfc73fecd13c54fd400f5b04b2c4113cc776c102f6f09eaa401252276818e17",
|
|
448
461
|
"3d321af4f48efc92735cc8772cf092f15789ac63e1e20f857ba20c0532453eac",
|
|
449
462
|
"3def30362c96b6238021ab82e6f2ebd2974005ca94a84008f43528aaa7eb435f",
|
|
@@ -452,6 +465,7 @@
|
|
|
452
465
|
"3ed5bcfca2cccfb1da4c181b27f9f44b6e53bd9c47c3b12990dd2e0c0ea51c32",
|
|
453
466
|
"3ee9206330fd3a17b04c5a5d136b92c2abf4792831c3c706bca463db3668fbcc",
|
|
454
467
|
"3ef2dde760ee9b50380364f83f368268a7c7a91cbdda6e0f629ebb09258cffaf",
|
|
468
|
+
"40464d8ac0f0395c447e7e502f262d5b05398716259b109e9ee7929fa1fa0105",
|
|
455
469
|
"40cc672b94e87300a3b317348d99f4c939e38316b5b9aa7f81e95f2ccf848f10",
|
|
456
470
|
"40fc22e1faeaa5a3be482334a312717b259f384e991c70e962ebef12d16120e7",
|
|
457
471
|
"41323b1c12be256f604edf8c49ff505acbaa75b6a1b938b76286d5eebec1ce95",
|
|
@@ -475,6 +489,7 @@
|
|
|
475
489
|
"477c7b699d1d2f66b63f04b30c3f78ddb4208b6346af58ed3dfa48d0568191cf",
|
|
476
490
|
"47bac4155f4e8f3d8e9eedce9dc7fc8039d74bc18c23213979fbe55e786d71a1",
|
|
477
491
|
"480420a6bcf31ae06cf1d4fcf34c24d949be485d2e13c2827b54331bec129053",
|
|
492
|
+
"4846658fe0742e27b3e2fccbbf222dbb4b23f47b5a31792249fc818e4ab4a659",
|
|
478
493
|
"484dc70c61110ccc7f4ba15e1a3e010b6653920e1bd852b9de61625942f7b056",
|
|
479
494
|
"485f3e37ba8a27b5027fd887f7baeea98a9099c6c7421d0e67e848d99905dc54",
|
|
480
495
|
"4923c02dff4a34a20d2f104ec3b17311cf269330932b7cf29addb2f4369dd23c",
|
|
@@ -494,6 +509,7 @@
|
|
|
494
509
|
"4dda6aecfc27e1a2889a30e12310abdc986d59cb8a7034ee9da3ee43c274dbf6",
|
|
495
510
|
"4e9eb8208ccd7fc7ec25010de2d9fa3df043452f3fa808ec520e283b7ebfa156",
|
|
496
511
|
"500e680bebe35b368080d6a1f6d39183323f519612fc9a776509ed0a2effcaf7",
|
|
512
|
+
"50bdeff1ac1044668a9692a076ff3bb504a42fdcb5abc6b41ccc4f05d57e9acd",
|
|
497
513
|
"5111747b387a61c55834df35d588156d2ef1e72b5530f4c33453754e4d35fcf1",
|
|
498
514
|
"5111bcf0edbbdb07d24a854086303f0f76a489fae171e7e441c1ec5dd62dd109",
|
|
499
515
|
"51ac33809c5f2a830a22d1f67f0f38f3b1e26acb47673fb3f691deb93d7e42b4",
|
|
@@ -522,6 +538,7 @@
|
|
|
522
538
|
"5b29b4f80abac3c4f6748a16f38b3bb72c61a639f65c845d0569a87f8f8a0cf0",
|
|
523
539
|
"5b79e4d8b7b75485b9be3341ec0d49ef4754c31d527bfb170d5cec1af92539e8",
|
|
524
540
|
"5b82f9020d952e89ccf8803bce90dd5b9c38b39fa59a629349c9d15cc14c9597",
|
|
541
|
+
"5d1183e08f92cb76c9fb41131742771101daebd65199b32050818a554e1ca185",
|
|
525
542
|
"5d56b35a8b69aabc401bb42cf93f38d0eebcb1219f3a8a032e124c45d4e4b5d8",
|
|
526
543
|
"5dec4f3f015629b0c29c802b30a9e373c570fca85bb3e260c0dac9662d2685cd",
|
|
527
544
|
"5dfd01e48b8b3eb9d6eec85d68624b2af0dd0eeb483307865ef88b0fc916bc97",
|
|
@@ -572,11 +589,13 @@
|
|
|
572
589
|
"76fdf7a80d7948c3007f8c54d3d710e8855a4227cefc915b8b07c0cdb299ceb0",
|
|
573
590
|
"77071010460d4aa8c89841d31a6f18600b804496de948710953dbd6f6fffc816",
|
|
574
591
|
"7766a3152ac33c155748ef3a7c9f500a7927870409100f55e1070f32f3667c54",
|
|
592
|
+
"793c5984744c21dfd4e8720e6319d61ff51ed30117c633b410024aaffa5ba048",
|
|
575
593
|
"7aaf7227bd67650944c709f4143b6b9161834d391e5cfd4aaeea105f5e840594",
|
|
576
594
|
"7af6e9be693d906ba1f942430f46b288176e418d35eefb869d3cc35570e3daff",
|
|
577
595
|
"7b47b07e3062f3dc839f11397bc3265120e01a35b0fda094d738e28a6729e6c3",
|
|
578
596
|
"7c0dacd603b4381539d6d3cf21f5fe625cf54b05eb4aa750fce658529b11d81d",
|
|
579
597
|
"7c79750557c7d7156df6f135fb582ec09cc5f4987ac8e2af0f5113e42c117224",
|
|
598
|
+
"7d083db061c678113c12453eb73299caa9e207dd6418ad63406154fd330f3309",
|
|
580
599
|
"7d2239e2cd4893c57ac0bf1373a2ef46419f614d0ce18a12df51222bc7795327",
|
|
581
600
|
"7e529bc76ca67f2023890da254ef0b09596f7d924d1a4eb93c72262783dc6c18",
|
|
582
601
|
"7eab506921c339be748106aa49468dba61ebd5a93aabc111621ccc8a9df52cc9",
|
|
@@ -609,6 +628,7 @@
|
|
|
609
628
|
"8b417f12b79e7328ab8998bde222da856470a9fe2a5eff838c710d5fc66c850e",
|
|
610
629
|
"8c89d0106c4051f7400670c2e83e6e3cfd95533b6d4d5f715124f28dbf41c37e",
|
|
611
630
|
"8cff7c530e70102f9506012e91f305c306c56a6e68073f44aba74a827c87f679",
|
|
631
|
+
"8d0079bdee4cf4dc86c1cca826f81584fe2c97db04514fdd666167df8b509979",
|
|
612
632
|
"8d3788c5b6eb17b9c58873208bbd36df9e4d3f969563165095a9dbb17d6c73fe",
|
|
613
633
|
"8db63678d5615054312a1b20b4383358fb0ec689e6ba6cb0d650bb133a2e3452",
|
|
614
634
|
"9101242a1f901484fc6110064e8e3ff4d4935c0ed69ee76003b57f8faf020765",
|
|
@@ -647,9 +667,11 @@
|
|
|
647
667
|
"a292850ee0ceb0549d2e0cd50e48c8596594a509597f7210f59acbad7b45b475",
|
|
648
668
|
"a2b7ab33386255547ecd6fce85b574d0354ef8e93d2bafb58e0cb77d7fee46b7",
|
|
649
669
|
"a2cb37971755afd2b67d7f91f0857ce9e0dee7464e8e16d79c72070bc0e5a5ef",
|
|
670
|
+
"a309b4f27f5733300e22b7b04a044b6c30df42b7ad51c9d03369e8d8d3da2f79",
|
|
650
671
|
"a35c41356dc27962435aafef3aaad9060a987aa83ea01992da6f7c26612468c9",
|
|
651
672
|
"a53c30ff3a184f3192f7c528b6cfe50dd917e8185edf31d66c5c1454abcbea9d",
|
|
652
673
|
"a5700a94e3e29b246bd9e2e29b2292287687cedbb69902f0b87ffbdcf382915c",
|
|
674
|
+
"a5de90a81e905134db282ef1cd50e17a684c8ea3217630147a47e2d5058edc3f",
|
|
653
675
|
"a624d3a28050dba8ceaf70f1e940c8a2d090c22a63118eee78fc1df154a88e2b",
|
|
654
676
|
"a6bc0c56d741f39aea2dbceb9bdd671326f12cebf7468c9c0f1c2d8ae733acc4",
|
|
655
677
|
"a880b449c712d425187e6119469d719a96f01f7a603de858022b385f47f84602",
|
|
@@ -701,6 +723,7 @@
|
|
|
701
723
|
"bf636ba39e22c5f06aa4e4850e7e4c16e87eab4439b1c18d7bc5313d6c402cc6",
|
|
702
724
|
"bfd30b5a63ea49031fefd4a7c7804c72731ea35ea47884d0aa154e9aeb83e805",
|
|
703
725
|
"bfe131637d915e23907418c2ea412a31e4a0e3e90da24c96b3d23380d7f3ceaa",
|
|
726
|
+
"c115b2ba9ec7abe2fa5261a5894e3c4899794b527f01ec682ae7fd2479199c08",
|
|
704
727
|
"c150c40a04099d7b726eb8aecc8eec8e92f9f9248a6a5c15556c08000c4bd231",
|
|
705
728
|
"c16ff4fe013ee2cef905d767a09305d9c1b2f778a06b439f0bc4645ac05bc82b",
|
|
706
729
|
"c1c7e45fedafb97770b6726539694eb0668c70677c2031fe2db2bc8b5339423a",
|
|
@@ -751,6 +774,7 @@
|
|
|
751
774
|
"d606733e95736b3e28e4dce4847b9775effc0944c4cd54c733400074991934ef",
|
|
752
775
|
"d660cb0c81a7032782da6910fa05eafa83d36520ca5fdb95e7077da96216a3ca",
|
|
753
776
|
"d6df42e35e82f71f257f5e79d038bf60a96e4965dbdb6bf08bc95c250754e5fe",
|
|
777
|
+
"d905ca576280d8a3d774bcadebfa57a9e22bdf7c1678ca9a548a1c25d643bf17",
|
|
754
778
|
"d94088aedb09a1feb3ad388a69e242043b4a921ca8d76b4660d94e18e2836546",
|
|
755
779
|
"d9547a0d7d9a97bffa84178d8ab73f3556f22c34120759d50eaa165c3ef0c318",
|
|
756
780
|
"d9683236273b7f1759c34a892267b1c57d59dec57415bb762201a50b5925c408",
|
|
@@ -772,6 +796,7 @@
|
|
|
772
796
|
"e031aef2a9adb0d0900e8269cf84c892f77b9938984e26df54826d1771861629",
|
|
773
797
|
"e0cecf4838b7ba38afa78577855d5bf7fab251d3f1b1ba01c51c0f76b97aea90",
|
|
774
798
|
"e160cfba0b71557be31005767ee845cab16d8c3a9bafde3d12ec31e8af0a1339",
|
|
799
|
+
"e16ebeb4c7803de28999a926918b42bec8d548691719827a636d84bc47941d80",
|
|
775
800
|
"e2070548ec9a6244c569ef0b9a43c2e5dd99cf9c0fa4540a21fd0595b291e444",
|
|
776
801
|
"e29fec7d54a144ea4867a3764fccdee6849d58d0f32eacdd56b2c317863fa1c6",
|
|
777
802
|
"e2e0fc585321ee2013cccaed95d47c49fbca71b54c67abad9080d19d70e3c1a5",
|
|
@@ -791,6 +816,7 @@
|
|
|
791
816
|
"e97387270720794226b6f1c657a0d5a961dbe06f8b873d6150b2f6246e54891f",
|
|
792
817
|
"eabe96ee6140792fb6d7c188c3ce031cba5e2c6663aecdeb019d9d51d5a90a43",
|
|
793
818
|
"eaf6d28a8d55fb98dcd4ddb84ab4645b4bf6d328a26811ddfcc1423b0b8ea604",
|
|
819
|
+
"ed4a68efc0af88b2192a06ae6b208992b617aae54b768d125b95442b987d517b",
|
|
794
820
|
"edb34ab257304ae32df0fd5b8d4b41e982ff5e956231e56b05c7bbc1e8ae44ca",
|
|
795
821
|
"edd212c7b0941068f6fd2d2051ad28651acd16ee12d9400f060553af6274ed2e",
|
|
796
822
|
"eddcbf50ba05f1f633fea0ad0a384300670be2ec6b45f8cc4f622aaa7a431b88",
|
|
@@ -46,7 +46,7 @@ Keep each section to ≤ 8 lines. Adapters are deltas, not full prompts. If an a
|
|
|
46
46
|
|
|
47
47
|
Adapters may add two more sections beyond the base format:
|
|
48
48
|
|
|
49
|
-
- **`## Role eligibility`** — fixed ASCII fields, one per line: `executor: yes|no`, `pair_judge: yes|no`. Absent section = eligible for both roles (every adapter shipped before iter-0051). Present only when a backend is structurally unable or not certified for a role — e.g. a completion-only local model has no tool/file-edit access, so it declares `executor: no`. `_shared/engine-preflight.md` and `/devlyn
|
|
49
|
+
- **`## Role eligibility`** — fixed ASCII fields, one per line: `executor: yes|no`, `pair_judge: yes|no`. Absent section = eligible for both roles (every adapter shipped before iter-0051). Present only when a backend is structurally unable or not certified for a role — e.g. a completion-only local model has no tool/file-edit access, so it declares `executor: no`. `_shared/engine-preflight.md` and `/devlyn-engines` read this section as a structured marker, not prose, so it validates mechanically.
|
|
50
50
|
- **`## Invocation`** — for backends called over an API or CLI backends with non-default invocation contracts: the concrete request shape (endpoint, JSON body, timeout) and the adapter-declared availability probe (`_shared/engine-preflight.md#role-resolution`'s "an adapter may declare a different probe" hook).
|
|
51
51
|
|
|
52
52
|
## When to add a new adapter
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Identity
|
|
4
4
|
|
|
5
|
-
You are the model running behind the `omp` CLI. Follow the canonical phase prompt exactly; this adapter exists so oh-my-pi can be selected as a first-class native task worker by `/devlyn
|
|
5
|
+
You are the model running behind the `omp` CLI. Follow the canonical phase prompt exactly; this adapter exists so oh-my-pi can be selected as a first-class native task worker by `/devlyn-resolve`.
|
|
6
6
|
|
|
7
7
|
## Output Discipline
|
|
8
8
|
|
|
@@ -10,4 +10,4 @@ Keep phase output machine-consumable and concise. Write the artifacts the canoni
|
|
|
10
10
|
|
|
11
11
|
## Fresh Context
|
|
12
12
|
|
|
13
|
-
Each native `task` tool invocation with a fresh `context` is a fresh phase worker. Do not call `/devlyn
|
|
13
|
+
Each native `task` tool invocation with a fresh `context` is a fresh phase worker. Do not call `/devlyn-resolve` recursively from inside a phase prompt; execute only the phase body you received.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Archive devlyn
|
|
2
|
+
"""Archive devlyn-resolve run artifacts per references/pipeline-state.md#archive-contract.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
5
|
python3 scripts/archive_run.py [--devlyn-dir .devlyn]
|
|
@@ -67,7 +67,7 @@ PER_RUN_PATTERNS = (
|
|
|
67
67
|
"verify.primary.timeout.json",
|
|
68
68
|
"verify.pair.timeout.json",
|
|
69
69
|
"finish-gate.summary.json",
|
|
70
|
-
# iter-0033a/2026-04-30 archive-fix iter: NEW /devlyn
|
|
70
|
+
# iter-0033a/2026-04-30 archive-fix iter: NEW /devlyn-resolve emits
|
|
71
71
|
# plan.md (PLAN output) + final-report.md (PHASE 6 render) +
|
|
72
72
|
# cumulative.patch (cumulative diff). Smoke 2's archive listing
|
|
73
73
|
# captured all three; archive_run.py was missing them because the
|