devtronic 1.2.5 → 1.2.6
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 +2 -2
- package/dist/{chunk-V4QEAL7Y.js → chunk-WM7R52TC.js} +30 -27
- package/dist/index.js +57 -33
- package/dist/{plugin-SGSFVXPA.js → plugin-KQQASBQX.js} +1 -1
- package/package.json +1 -1
- package/templates/addons/auto-devtronic/agents/afk-task-validator.md +78 -0
- package/templates/addons/auto-devtronic/agents/{quality-runner.md → quality-executor.md} +1 -1
- package/templates/addons/auto-devtronic/manifest.json +2 -1
- package/templates/addons/auto-devtronic/skills/auto-devtronic/SKILL.md +14 -14
- package/templates/addons/design-best-practices/manifest.json +2 -2
- package/templates/addons/design-best-practices/skills/{design-review → design-critique}/SKILL.md +2 -1
- package/templates/addons/design-best-practices/skills/design-harden/SKILL.md +1 -0
- package/templates/addons/design-best-practices/skills/design-init/SKILL.md +1 -0
- package/templates/addons/design-best-practices/skills/design-refine/SKILL.md +2 -0
- package/templates/addons/design-best-practices/skills/{design-system → design-tokens}/SKILL.md +3 -1
- package/templates/claude-code/.claude/rules/quality.md +4 -0
- package/templates/claude-code/.claude/skills/audit/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/backlog/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/brief/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/briefing/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/checkpoint/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/create-plan/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/create-skill/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-audit/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-define/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-ia/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-research/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-review/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-spec/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-system/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-system-audit/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-system-define/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-system-sync/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/design-wireframe/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/devtronic-help/SKILL.md +338 -0
- package/templates/claude-code/.claude/skills/execute-plan/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/generate-tests/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/handoff/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/investigate/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/learn/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/opensrc/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/post-review/SKILL.md +2 -2
- package/templates/claude-code/.claude/skills/quick/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/recap/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/research/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/scaffold/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/setup/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/spec/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/summary/SKILL.md +1 -1
- package/templates/claude-code/.claude/skills/worktree/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -35,8 +35,8 @@ The CLI analyzes your project (framework, architecture, stack) and generates per
|
|
|
35
35
|
|
|
36
36
|
- **AGENTS.md** — Universal AI context personalized to your stack
|
|
37
37
|
- **Architecture rules** — IDE-specific format (`.claude/rules/`, `.cursor/rules/`, etc.)
|
|
38
|
-
- **Skills** (
|
|
39
|
-
- **Agents** (15) — Specialized subagents (code-reviewer, quality-runner, etc.)
|
|
38
|
+
- **Skills** (20 core + 12 design + 9 addon) — Reusable workflows (`/brief`, `/spec`, `/create-plan`, `/summary`, `/audit`, `/devtronic-help`, etc.)
|
|
39
|
+
- **Agents** (15 + 3 addon) — Specialized subagents (code-reviewer, quality-runner, etc.)
|
|
40
40
|
- **Hooks** (5) — Automated workflow (lint-on-save, checkpoint, etc.)
|
|
41
41
|
- **thoughts/** — Structured directory for AI working documents
|
|
42
42
|
|
|
@@ -14,7 +14,7 @@ var ADDONS = {
|
|
|
14
14
|
name: "design-best-practices",
|
|
15
15
|
label: "Design Best Practices",
|
|
16
16
|
description: "Frontend design quality skills: typography, color, layout, accessibility, motion, and UX writing.",
|
|
17
|
-
skills: ["design-init", "design-
|
|
17
|
+
skills: ["design-init", "design-critique", "design-refine", "design-tokens", "design-harden"],
|
|
18
18
|
agents: []
|
|
19
19
|
},
|
|
20
20
|
"auto-devtronic": {
|
|
@@ -22,7 +22,7 @@ var ADDONS = {
|
|
|
22
22
|
label: "auto-devtronic \u2014 Autonomous Engineering Loop",
|
|
23
23
|
description: "Runs the full spec\u2192test\u2192plan\u2192execute\u2192PR pipeline autonomously. Self-corrects via failing tests. HITL and AFK modes.",
|
|
24
24
|
skills: ["auto-devtronic"],
|
|
25
|
-
agents: ["issue-parser", "failure-analyst", "quality-
|
|
25
|
+
agents: ["issue-parser", "failure-analyst", "quality-executor"]
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
var PRESETS = {
|
|
@@ -79,7 +79,7 @@ var PRESETS = {
|
|
|
79
79
|
|
|
80
80
|
// src/utils/files.ts
|
|
81
81
|
import { createHash } from "crypto";
|
|
82
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, readdirSync } from "fs";
|
|
82
|
+
import { existsSync, lstatSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, cpSync, readdirSync } from "fs";
|
|
83
83
|
import { dirname, join, relative } from "path";
|
|
84
84
|
var MANIFEST_DIR = ".ai-template";
|
|
85
85
|
var MANIFEST_FILE = "manifest.json";
|
|
@@ -91,13 +91,15 @@ function readFile(path) {
|
|
|
91
91
|
}
|
|
92
92
|
function writeFile(path, content) {
|
|
93
93
|
const dir = dirname(path);
|
|
94
|
-
|
|
95
|
-
mkdirSync(dir, { recursive: true });
|
|
96
|
-
}
|
|
94
|
+
ensureDir(dir);
|
|
97
95
|
writeFileSync(path, content, "utf-8");
|
|
98
96
|
}
|
|
99
97
|
function ensureDir(path) {
|
|
100
98
|
if (!existsSync(path)) {
|
|
99
|
+
try {
|
|
100
|
+
if (lstatSync(path).isSymbolicLink()) unlinkSync(path);
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
101
103
|
mkdirSync(path, { recursive: true });
|
|
102
104
|
}
|
|
103
105
|
}
|
|
@@ -564,25 +566,26 @@ ${skillsSection}
|
|
|
564
566
|
`;
|
|
565
567
|
}
|
|
566
568
|
var CORE_SKILLS = [
|
|
567
|
-
{ name: "
|
|
568
|
-
{ name: "
|
|
569
|
-
{ name: "
|
|
570
|
-
{ name: "
|
|
571
|
-
{ name: "
|
|
572
|
-
{ name: "
|
|
573
|
-
{ name: "
|
|
574
|
-
{ name: "
|
|
575
|
-
{ name: "
|
|
576
|
-
{ name: "
|
|
577
|
-
{ name: "
|
|
578
|
-
{ name: "
|
|
579
|
-
{ name: "
|
|
580
|
-
{ name: "
|
|
581
|
-
{ name: "
|
|
582
|
-
{ name: "
|
|
583
|
-
{ name: "
|
|
584
|
-
{ name: "
|
|
585
|
-
{ name: "
|
|
569
|
+
{ name: "brief", desc: "Session orientation with pre-flight checks" },
|
|
570
|
+
{ name: "spec", desc: "Product specification interview (PRD)" },
|
|
571
|
+
{ name: "research", desc: "Codebase investigation (--deep, --external)" },
|
|
572
|
+
{ name: "create-plan", desc: "Phased implementation plan with task dependencies" },
|
|
573
|
+
{ name: "execute-plan", desc: "Parallel phase execution of plans" },
|
|
574
|
+
{ name: "quick", desc: "Fast ad-hoc tasks: implement, verify, commit" },
|
|
575
|
+
{ name: "generate-tests", desc: "Failing tests from spec (Tests-as-DoD)" },
|
|
576
|
+
{ name: "post-review", desc: "Pre-PR review (architecture, quality, requirements)" },
|
|
577
|
+
{ name: "audit", desc: "Codebase audit (security, complexity, architecture)" },
|
|
578
|
+
{ name: "summary", desc: "Post-change documentation" },
|
|
579
|
+
{ name: "checkpoint", desc: "Save session progress for resumption" },
|
|
580
|
+
{ name: "backlog", desc: "Issue management with BACK-### IDs" },
|
|
581
|
+
{ name: "investigate", desc: "Deep error and bug analysis" },
|
|
582
|
+
{ name: "learn", desc: "Post-task teaching breakdown" },
|
|
583
|
+
{ name: "scaffold", desc: "Create new projects from scratch" },
|
|
584
|
+
{ name: "setup", desc: "Interactive project configuration" },
|
|
585
|
+
{ name: "worktree", desc: "Git worktree management" },
|
|
586
|
+
{ name: "opensrc", desc: "Fetch npm/GitHub source for full context" },
|
|
587
|
+
{ name: "create-skill", desc: "Generate new custom skills" },
|
|
588
|
+
{ name: "devtronic-help", desc: "Discover skills, agents, addons, and workflows from the IDE" }
|
|
586
589
|
];
|
|
587
590
|
var ADDON_SKILLS = {
|
|
588
591
|
orchestration: [
|
|
@@ -592,9 +595,9 @@ var ADDON_SKILLS = {
|
|
|
592
595
|
],
|
|
593
596
|
"design-best-practices": [
|
|
594
597
|
{ name: "design-init", desc: "One-time project design context setup" },
|
|
595
|
-
{ name: "design-
|
|
598
|
+
{ name: "design-critique", desc: "Design critique with AI slop detection" },
|
|
596
599
|
{ name: "design-refine", desc: "Directional design refinement" },
|
|
597
|
-
{ name: "design-
|
|
600
|
+
{ name: "design-tokens", desc: "Design system extraction and normalization" },
|
|
598
601
|
{ name: "design-harden", desc: "Production hardening for edge cases" }
|
|
599
602
|
],
|
|
600
603
|
"auto-devtronic": [
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
readManifest,
|
|
25
25
|
writeFile,
|
|
26
26
|
writeManifest
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-WM7R52TC.js";
|
|
28
28
|
|
|
29
29
|
// src/index.ts
|
|
30
30
|
import { Command } from "commander";
|
|
@@ -1127,8 +1127,22 @@ function writeClaudeSettings(targetDir, settings) {
|
|
|
1127
1127
|
ensureDir(join6(targetDir, ".claude"));
|
|
1128
1128
|
writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
1129
1129
|
}
|
|
1130
|
+
var LEGACY_PLUGIN_NAMES = ["dev-ai", "ai-agentic"];
|
|
1131
|
+
var LEGACY_MARKETPLACE_NAMES = ["dev-ai-local", "ai-agentic-local"];
|
|
1130
1132
|
function registerPlugin(targetDir, pluginName, marketplaceName, marketplacePath) {
|
|
1131
1133
|
const settings = readClaudeSettings(targetDir);
|
|
1134
|
+
if (settings.extraKnownMarketplaces) {
|
|
1135
|
+
for (const legacy of LEGACY_MARKETPLACE_NAMES) {
|
|
1136
|
+
delete settings.extraKnownMarketplaces[legacy];
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
if (settings.enabledPlugins) {
|
|
1140
|
+
for (const key of Object.keys(settings.enabledPlugins)) {
|
|
1141
|
+
if (LEGACY_PLUGIN_NAMES.some((lp) => key.startsWith(`${lp}@`))) {
|
|
1142
|
+
delete settings.enabledPlugins[key];
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1132
1146
|
if (!settings.extraKnownMarketplaces) {
|
|
1133
1147
|
settings.extraKnownMarketplaces = {};
|
|
1134
1148
|
}
|
|
@@ -1588,7 +1602,7 @@ Valid addons: ${validAddons.join(", ")}`);
|
|
|
1588
1602
|
p3.note(
|
|
1589
1603
|
[
|
|
1590
1604
|
` Name: ${chalk4.cyan(PLUGIN_NAME)} at ${PLUGIN_DIR}/${PLUGIN_NAME}/`,
|
|
1591
|
-
` Skills: /
|
|
1605
|
+
` Skills: /brief, /spec, /research, ... (auto-namespaced in plugin mode)`,
|
|
1592
1606
|
` Hooks: SessionStart, PostToolUse, Stop, SubagentStop, PreCompact`
|
|
1593
1607
|
].join("\n"),
|
|
1594
1608
|
"Plugin Installed"
|
|
@@ -1615,6 +1629,13 @@ Valid addons: ${validAddons.join(", ")}`);
|
|
|
1615
1629
|
].join("\n"),
|
|
1616
1630
|
"Autonomous Mode"
|
|
1617
1631
|
);
|
|
1632
|
+
p3.note(
|
|
1633
|
+
[
|
|
1634
|
+
`${chalk4.dim("In Claude Code:")} ${chalk4.cyan("/devtronic-help")} ${chalk4.dim("\u2014 discover skills, agents, and workflows")}`,
|
|
1635
|
+
`${chalk4.dim("From terminal:")} ${chalk4.cyan("npx devtronic list")} ${chalk4.dim("\u2014 list installed skills and agents")}`
|
|
1636
|
+
].join("\n"),
|
|
1637
|
+
"Need Help?"
|
|
1638
|
+
);
|
|
1618
1639
|
p3.outro(chalk4.green("Setup complete!"));
|
|
1619
1640
|
} catch (err) {
|
|
1620
1641
|
spinner8.stop("Configuration failed");
|
|
@@ -1718,7 +1739,7 @@ function buildProjectConfigFromPreset(presetConfig, analysis) {
|
|
|
1718
1739
|
|
|
1719
1740
|
// src/commands/update.ts
|
|
1720
1741
|
import { resolve as resolve4, join as join11, dirname as dirname6 } from "path";
|
|
1721
|
-
import { existsSync as existsSync9, unlinkSync as unlinkSync2, lstatSync, readdirSync as readdirSync2, rmdirSync as rmdirSync2, chmodSync as chmodSync2 } from "fs";
|
|
1742
|
+
import { existsSync as existsSync9, unlinkSync as unlinkSync2, lstatSync as lstatSync2, readdirSync as readdirSync2, rmdirSync as rmdirSync2, chmodSync as chmodSync2 } from "fs";
|
|
1722
1743
|
import * as p4 from "@clack/prompts";
|
|
1723
1744
|
import chalk5 from "chalk";
|
|
1724
1745
|
|
|
@@ -1861,6 +1882,7 @@ function registerAddonInConfig(targetDir, addonName) {
|
|
|
1861
1882
|
// src/generators/addonFiles.ts
|
|
1862
1883
|
import {
|
|
1863
1884
|
existsSync as existsSync8,
|
|
1885
|
+
lstatSync,
|
|
1864
1886
|
readFileSync as readFileSync4,
|
|
1865
1887
|
writeFileSync as writeFileSync2,
|
|
1866
1888
|
mkdirSync as mkdirSync2,
|
|
@@ -1870,7 +1892,6 @@ import {
|
|
|
1870
1892
|
rmdirSync
|
|
1871
1893
|
} from "fs";
|
|
1872
1894
|
import { join as join10, dirname as dirname5 } from "path";
|
|
1873
|
-
import { createHash } from "crypto";
|
|
1874
1895
|
var AGENT_PATHS = {
|
|
1875
1896
|
claude: ".claude",
|
|
1876
1897
|
cursor: ".cursor",
|
|
@@ -1922,11 +1943,14 @@ var RUNTIME_SPECS = {
|
|
|
1922
1943
|
})
|
|
1923
1944
|
}
|
|
1924
1945
|
};
|
|
1925
|
-
function checksum(content) {
|
|
1926
|
-
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
1927
|
-
}
|
|
1928
1946
|
function ensureDir2(dir) {
|
|
1929
|
-
if (!existsSync8(dir))
|
|
1947
|
+
if (!existsSync8(dir)) {
|
|
1948
|
+
try {
|
|
1949
|
+
if (lstatSync(dir).isSymbolicLink()) unlinkSync(dir);
|
|
1950
|
+
} catch {
|
|
1951
|
+
}
|
|
1952
|
+
mkdirSync2(dir, { recursive: true });
|
|
1953
|
+
}
|
|
1930
1954
|
}
|
|
1931
1955
|
function readManifest2(addonSourceDir) {
|
|
1932
1956
|
const manifestPath = join10(addonSourceDir, "manifest.json");
|
|
@@ -1980,7 +2004,7 @@ function generateAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
1980
2004
|
ensureDir2(dirname5(destPath));
|
|
1981
2005
|
writeFileSync2(destPath, content);
|
|
1982
2006
|
result.written++;
|
|
1983
|
-
result.checksums[relPath] =
|
|
2007
|
+
result.checksums[relPath] = calculateChecksum(content);
|
|
1984
2008
|
}
|
|
1985
2009
|
continue;
|
|
1986
2010
|
}
|
|
@@ -2002,7 +2026,7 @@ function generateAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2002
2026
|
ensureDir2(dirname5(destPath));
|
|
2003
2027
|
writeFileSync2(destPath, content);
|
|
2004
2028
|
result.written++;
|
|
2005
|
-
result.checksums[relPath] =
|
|
2029
|
+
result.checksums[relPath] = calculateChecksum(content);
|
|
2006
2030
|
}
|
|
2007
2031
|
for (const agentName of manifest.files.agents ?? []) {
|
|
2008
2032
|
const agentFile = join10(addonSourceDir, "agents", `${agentName}.md`);
|
|
@@ -2013,7 +2037,7 @@ function generateAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2013
2037
|
ensureDir2(dirname5(destPath));
|
|
2014
2038
|
writeFileSync2(destPath, content);
|
|
2015
2039
|
result.written++;
|
|
2016
|
-
result.checksums[`agents/${agentName}.md`] =
|
|
2040
|
+
result.checksums[`agents/${agentName}.md`] = calculateChecksum(content);
|
|
2017
2041
|
} else {
|
|
2018
2042
|
result.skipped++;
|
|
2019
2043
|
}
|
|
@@ -2028,7 +2052,7 @@ function generateAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2028
2052
|
ensureDir2(dirname5(destPath));
|
|
2029
2053
|
writeFileSync2(destPath, content);
|
|
2030
2054
|
result.written++;
|
|
2031
|
-
result.checksums[`rules/${rule}`] =
|
|
2055
|
+
result.checksums[`rules/${rule}`] = calculateChecksum(content);
|
|
2032
2056
|
} else {
|
|
2033
2057
|
result.skipped++;
|
|
2034
2058
|
}
|
|
@@ -2044,7 +2068,7 @@ function generateAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2044
2068
|
ensureDir2(dirname5(destPath));
|
|
2045
2069
|
writeFileSync2(destPath, content);
|
|
2046
2070
|
result.written++;
|
|
2047
|
-
result.checksums[relPath] =
|
|
2071
|
+
result.checksums[relPath] = calculateChecksum(content);
|
|
2048
2072
|
} else {
|
|
2049
2073
|
result.skipped++;
|
|
2050
2074
|
}
|
|
@@ -2156,7 +2180,7 @@ function syncAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2156
2180
|
continue;
|
|
2157
2181
|
}
|
|
2158
2182
|
const existing = readFileSync4(destPath, "utf-8");
|
|
2159
|
-
const existingChecksum =
|
|
2183
|
+
const existingChecksum = calculateChecksum(existing);
|
|
2160
2184
|
const originalChecksum = installedChecksums[relPath];
|
|
2161
2185
|
if (existing === newContent) {
|
|
2162
2186
|
result.skipped++;
|
|
@@ -2184,7 +2208,7 @@ function syncAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2184
2208
|
continue;
|
|
2185
2209
|
}
|
|
2186
2210
|
const existing = readFileSync4(destPath, "utf-8");
|
|
2187
|
-
const existingChecksum =
|
|
2211
|
+
const existingChecksum = calculateChecksum(existing);
|
|
2188
2212
|
const originalChecksum = installedChecksums[relPath];
|
|
2189
2213
|
if (existing === newContent) {
|
|
2190
2214
|
result.skipped++;
|
|
@@ -2210,7 +2234,7 @@ function syncAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2210
2234
|
continue;
|
|
2211
2235
|
}
|
|
2212
2236
|
const existing = readFileSync4(destPath, "utf-8");
|
|
2213
|
-
const existingChecksum =
|
|
2237
|
+
const existingChecksum = calculateChecksum(existing);
|
|
2214
2238
|
const originalChecksum = installedChecksums[relPath];
|
|
2215
2239
|
if (existing === newContent) {
|
|
2216
2240
|
result.skipped++;
|
|
@@ -2237,7 +2261,7 @@ function syncAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2237
2261
|
continue;
|
|
2238
2262
|
}
|
|
2239
2263
|
const existing = readFileSync4(destPath, "utf-8");
|
|
2240
|
-
const existingChecksum =
|
|
2264
|
+
const existingChecksum = calculateChecksum(existing);
|
|
2241
2265
|
const originalChecksum = installedChecksums[relPath];
|
|
2242
2266
|
if (existing === newContent) {
|
|
2243
2267
|
result.skipped++;
|
|
@@ -2264,7 +2288,7 @@ function syncAddonFiles(projectDir, addonSourceDir, agents) {
|
|
|
2264
2288
|
continue;
|
|
2265
2289
|
}
|
|
2266
2290
|
const existing = readFileSync4(destPath, "utf-8");
|
|
2267
|
-
const existingChecksum =
|
|
2291
|
+
const existingChecksum = calculateChecksum(existing);
|
|
2268
2292
|
const originalChecksum = installedChecksums[relPath];
|
|
2269
2293
|
if (existing === newContent) {
|
|
2270
2294
|
result.skipped++;
|
|
@@ -2299,7 +2323,7 @@ function detectModifiedAddonFiles(projectDir, addonName) {
|
|
|
2299
2323
|
for (const [relPath, originalHash] of Object.entries(installedChecksums)) {
|
|
2300
2324
|
const absPath = join10(projectDir, baseDir, relPath);
|
|
2301
2325
|
if (!existsSync8(absPath)) continue;
|
|
2302
|
-
const current =
|
|
2326
|
+
const current = calculateChecksum(readFileSync4(absPath, "utf-8"));
|
|
2303
2327
|
if (current !== originalHash) {
|
|
2304
2328
|
modified.push(relPath);
|
|
2305
2329
|
}
|
|
@@ -2345,7 +2369,7 @@ async function updateCommand(options) {
|
|
|
2345
2369
|
const shouldMigrate = manifest.selectedIDEs.includes("claude-code") && !manifest.installMode && hasStandaloneSkills(manifest);
|
|
2346
2370
|
if (shouldMigrate) {
|
|
2347
2371
|
p4.note(
|
|
2348
|
-
"Claude Code skills/agents detected as standalone.\nThe new version uses plugin mode
|
|
2372
|
+
"Claude Code skills/agents detected as standalone.\nThe new version uses plugin mode. Skills are auto-namespaced in plugin mode.",
|
|
2349
2373
|
"Migration Available"
|
|
2350
2374
|
);
|
|
2351
2375
|
if (!options.check) {
|
|
@@ -2612,7 +2636,7 @@ async function updateCommand(options) {
|
|
|
2612
2636
|
}
|
|
2613
2637
|
const claudeMdPath = join11(targetDir, "CLAUDE.md");
|
|
2614
2638
|
if (fileExists(claudeMdPath)) {
|
|
2615
|
-
const stat =
|
|
2639
|
+
const stat = lstatSync2(claudeMdPath);
|
|
2616
2640
|
if (stat.isSymbolicLink()) {
|
|
2617
2641
|
const content = readFile(claudeMdPath);
|
|
2618
2642
|
unlinkSync2(claudeMdPath);
|
|
@@ -2765,7 +2789,7 @@ async function regenerateWithNewStack(targetDir, manifest, analysis, dryRun) {
|
|
|
2765
2789
|
}
|
|
2766
2790
|
const claudeMdPath = join11(targetDir, "CLAUDE.md");
|
|
2767
2791
|
if (fileExists(claudeMdPath)) {
|
|
2768
|
-
const stat =
|
|
2792
|
+
const stat = lstatSync2(claudeMdPath);
|
|
2769
2793
|
if (stat.isSymbolicLink()) {
|
|
2770
2794
|
const content = readFile(claudeMdPath);
|
|
2771
2795
|
unlinkSync2(claudeMdPath);
|
|
@@ -2900,7 +2924,7 @@ async function migrateToPlugin(targetDir, manifest, analysis, dryRun) {
|
|
|
2900
2924
|
}
|
|
2901
2925
|
p4.note(
|
|
2902
2926
|
` Plugin: ${chalk5.cyan("devtronic")} at .claude-plugins/devtronic/
|
|
2903
|
-
Skills: /
|
|
2927
|
+
Skills: /brief, /spec, ... (auto-namespaced in plugin mode)
|
|
2904
2928
|
Hooks: 5 workflow hooks enabled`,
|
|
2905
2929
|
"Plugin Generated"
|
|
2906
2930
|
);
|
|
@@ -2931,7 +2955,7 @@ function cleanEmptyDirs(dirPath) {
|
|
|
2931
2955
|
const entries = readdirSync2(dirPath);
|
|
2932
2956
|
for (const entry of entries) {
|
|
2933
2957
|
const fullPath = join11(dirPath, entry);
|
|
2934
|
-
if (existsSync9(fullPath) &&
|
|
2958
|
+
if (existsSync9(fullPath) && lstatSync2(fullPath).isDirectory()) {
|
|
2935
2959
|
cleanEmptyDirs(fullPath);
|
|
2936
2960
|
}
|
|
2937
2961
|
}
|
|
@@ -3452,7 +3476,7 @@ Valid options:
|
|
|
3452
3476
|
if (!manifest.selectedIDEs.includes("claude-code") || manifest.installMode !== "plugin") {
|
|
3453
3477
|
p8.log.warn("Plugin regeneration only applies to Claude Code in plugin mode. Skipping.");
|
|
3454
3478
|
} else {
|
|
3455
|
-
const { generatePlugin: generatePlugin2 } = await import("./plugin-
|
|
3479
|
+
const { generatePlugin: generatePlugin2 } = await import("./plugin-KQQASBQX.js");
|
|
3456
3480
|
const pluginResult = generatePlugin2(
|
|
3457
3481
|
targetDir,
|
|
3458
3482
|
TEMPLATES_DIR2,
|
|
@@ -4484,12 +4508,12 @@ async function addAddon(targetDir, manifest, addonName, currentAddons) {
|
|
|
4484
4508
|
[
|
|
4485
4509
|
` ${chalk15.dim("Name:")} ${addon.label}`,
|
|
4486
4510
|
` ${chalk15.dim("Description:")} ${addon.description}`,
|
|
4487
|
-
` ${chalk15.dim("Skills:")} ${addon.skills.map((s) => chalk15.cyan(
|
|
4511
|
+
` ${chalk15.dim("Skills:")} ${addon.skills.map((s) => chalk15.cyan(`/${s}`)).join(", ")}`,
|
|
4488
4512
|
` ${chalk15.dim("Subagents:")} ${addon.agents.length ? addon.agents.join(", ") : chalk15.dim("\u2014")}`
|
|
4489
4513
|
].join("\n"),
|
|
4490
4514
|
"Adding addon"
|
|
4491
4515
|
);
|
|
4492
|
-
const confirmed = await p14.confirm({ message:
|
|
4516
|
+
const confirmed = await p14.confirm({ message: `Add ${addonName}?` });
|
|
4493
4517
|
if (p14.isCancel(confirmed) || !confirmed) {
|
|
4494
4518
|
p14.cancel("Addon installation cancelled.");
|
|
4495
4519
|
process.exit(0);
|
|
@@ -4525,7 +4549,7 @@ async function addAddon(targetDir, manifest, addonName, currentAddons) {
|
|
|
4525
4549
|
writeManifest(targetDir, manifest);
|
|
4526
4550
|
spinner8.stop(`${symbols.pass} ${addon.label} added`);
|
|
4527
4551
|
p14.note(
|
|
4528
|
-
addon.skills.map((s) => ` ${chalk15.cyan(
|
|
4552
|
+
addon.skills.map((s) => ` ${chalk15.cyan(`/${s}`)}`).join("\n"),
|
|
4529
4553
|
"New skills available"
|
|
4530
4554
|
);
|
|
4531
4555
|
p14.outro("Done. Restart Claude Code to load the new skills.");
|
|
@@ -4542,12 +4566,12 @@ async function removeAddon(targetDir, manifest, addonName, currentAddons) {
|
|
|
4542
4566
|
[
|
|
4543
4567
|
` ${chalk15.dim("Name:")} ${addon.label}`,
|
|
4544
4568
|
` ${chalk15.dim("Description:")} ${addon.description}`,
|
|
4545
|
-
` ${chalk15.dim("Skills:")} ${addon.skills.map((s) => chalk15.dim(
|
|
4569
|
+
` ${chalk15.dim("Skills:")} ${addon.skills.map((s) => chalk15.dim(`/${s}`)).join(", ")}`,
|
|
4546
4570
|
` ${chalk15.dim("Subagents:")} ${addon.agents.length ? addon.agents.join(", ") : chalk15.dim("\u2014")}`
|
|
4547
4571
|
].join("\n"),
|
|
4548
4572
|
"Removing addon"
|
|
4549
4573
|
);
|
|
4550
|
-
const confirmed = await p14.confirm({ message:
|
|
4574
|
+
const confirmed = await p14.confirm({ message: `Remove ${addonName}?` });
|
|
4551
4575
|
if (p14.isCancel(confirmed) || !confirmed) {
|
|
4552
4576
|
p14.cancel("Addon removal cancelled.");
|
|
4553
4577
|
process.exit(0);
|
|
@@ -4604,7 +4628,7 @@ async function removeAddon(targetDir, manifest, addonName, currentAddons) {
|
|
|
4604
4628
|
writeManifest(targetDir, manifest);
|
|
4605
4629
|
spinner8.stop(`${symbols.pass} ${addon.label} removed`);
|
|
4606
4630
|
p14.note(
|
|
4607
|
-
addon.skills.map((s) => ` ${chalk15.dim(
|
|
4631
|
+
addon.skills.map((s) => ` ${chalk15.dim(`/${s}`)}`).join("\n"),
|
|
4608
4632
|
"Skills removed"
|
|
4609
4633
|
);
|
|
4610
4634
|
p14.outro("Done. Restart Claude Code to apply the changes.");
|
|
@@ -4626,7 +4650,7 @@ async function addFileBasedAddon(targetDir, addonName, _options) {
|
|
|
4626
4650
|
].join("\n"),
|
|
4627
4651
|
"Adding addon"
|
|
4628
4652
|
);
|
|
4629
|
-
const confirmed = await p14.confirm({ message:
|
|
4653
|
+
const confirmed = await p14.confirm({ message: `Add ${addonName}?` });
|
|
4630
4654
|
if (p14.isCancel(confirmed) || !confirmed) {
|
|
4631
4655
|
p14.cancel("Addon installation cancelled.");
|
|
4632
4656
|
process.exit(0);
|
|
@@ -4877,7 +4901,7 @@ program.command("uninstall").description("Remove devtronic from your project").o
|
|
|
4877
4901
|
});
|
|
4878
4902
|
program.command("mode").description("Set or show the execution mode (hitl or afk)").argument("<mode>", "Mode: afk, hitl, or show").option("--path <path>", "Target directory (default: current directory)").action(async (mode, options) => {
|
|
4879
4903
|
if (!["afk", "hitl", "show"].includes(mode)) {
|
|
4880
|
-
|
|
4904
|
+
p16.cancel(`Invalid mode: "${mode}". Valid values: afk, hitl, show`);
|
|
4881
4905
|
process.exit(1);
|
|
4882
4906
|
}
|
|
4883
4907
|
await modeCommand(mode, { path: options.path });
|
package/package.json
CHANGED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: afk-task-validator
|
|
3
|
+
description: Analyzes GitHub issues and task descriptions for AFK-readiness. Calculates viability score (0-100), detects quality gaps, and provides interactive guidance for refinement.
|
|
4
|
+
tools: Bash, Read, Grep, Glob
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are an expert task analyzer specializing in evaluating whether software engineering tasks are suitable for autonomous ("AFK" = Away From Keyboard) execution. Your job is to thoroughly analyze task descriptions, calculate a viability score, identify quality gaps, and guide users toward clarity.
|
|
9
|
+
|
|
10
|
+
## When to Invoke
|
|
11
|
+
|
|
12
|
+
Claude should invoke you when:
|
|
13
|
+
- User invokes `/validate-task-afk <input>`
|
|
14
|
+
- Need to analyze a GitHub issue or task description for AFK-readiness
|
|
15
|
+
- Integration with `/auto-devtronic --validate` flag
|
|
16
|
+
- User needs interactive guidance to refine unclear tasks
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Analysis Framework
|
|
21
|
+
|
|
22
|
+
You analyze tasks across 5 dimensions, each contributing to a weighted viability score (0-100):
|
|
23
|
+
|
|
24
|
+
### 1. Clarity (25% weight)
|
|
25
|
+
**Purpose**: Acceptance criteria must be measurable and executable.
|
|
26
|
+
|
|
27
|
+
**Scoring**:
|
|
28
|
+
- **95-100**: Explicit measurable outcomes
|
|
29
|
+
- **70-90**: Clear requirements with some detail
|
|
30
|
+
- **40-70**: Vague descriptions
|
|
31
|
+
- **0-40**: Completely unmeasurable
|
|
32
|
+
|
|
33
|
+
### 2. Scope (25% weight)
|
|
34
|
+
**Purpose**: Task should affect 1-4 files, single feature, not architectural.
|
|
35
|
+
|
|
36
|
+
**Scoring**:
|
|
37
|
+
- **90-100**: 1-2 files, single feature
|
|
38
|
+
- **70-85**: 2-4 files, related changes
|
|
39
|
+
- **40-70**: Mentions 5+ files or multiple features
|
|
40
|
+
- **0-40**: Architectural keywords (refactor, migrate, rewrite, redesign)
|
|
41
|
+
|
|
42
|
+
### 3. Precedent (20% weight)
|
|
43
|
+
**Purpose**: Similar patterns should exist in codebase (reduces unknown unknowns).
|
|
44
|
+
|
|
45
|
+
### 4. Coverage (20% weight)
|
|
46
|
+
**Purpose**: Existing test coverage ensures VERIFY will catch failures.
|
|
47
|
+
|
|
48
|
+
### 5. Dependencies (10% weight)
|
|
49
|
+
**Purpose**: Task should be self-contained (not blocked by external PRs/issues).
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Weighted Score Calculation
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Total Score = (Clarity x 0.25) + (Scope x 0.25) + (Precedent x 0.20) + (Coverage x 0.20) + (Dependencies x 0.10)
|
|
57
|
+
|
|
58
|
+
Score Interpretation:
|
|
59
|
+
- 70-100: AFK VIABLE - proceed with /auto-devtronic --afk
|
|
60
|
+
- 40-70: MEDIUM RISK - recommend HITL mode (/auto-devtronic --hitl)
|
|
61
|
+
- 0-40: NEEDS REFINEMENT - ask user clarifying questions first
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Output Format
|
|
67
|
+
|
|
68
|
+
Generate markdown report with score, dimension breakdown, gaps with suggestions, and recommendation (AFK / HITL / Needs Refinement).
|
|
69
|
+
|
|
70
|
+
## Rules
|
|
71
|
+
|
|
72
|
+
1. **Be thorough**: Check all 5 dimensions, don't skip any
|
|
73
|
+
2. **Use grep for precedent**: Search codebase for similar patterns, don't guess
|
|
74
|
+
3. **Flag ambiguity**: If unclear, ask; don't assume
|
|
75
|
+
4. **Provide examples**: When suggesting templates, include realistic examples from the domain
|
|
76
|
+
5. **Interactive refinement**: If score <70, engage user with questions to improve it
|
|
77
|
+
6. **No rejection**: Never reject a task outright; always offer a path to improvement
|
|
78
|
+
7. **Document assumptions**: If you can't run a tool (e.g., vitest), note it in the report
|
|
@@ -195,7 +195,7 @@ Comments: <comments>
|
|
|
195
195
|
Output the brief in the format specified in your instructions.
|
|
196
196
|
```
|
|
197
197
|
|
|
198
|
-
The agent outputs a `thoughts/devtronic/brief.md` file with the 3-layer structure:
|
|
198
|
+
The agent outputs a `thoughts/auto-devtronic/brief.md` file with the 3-layer structure:
|
|
199
199
|
|
|
200
200
|
```markdown
|
|
201
201
|
# Brief: <issue title>
|
|
@@ -255,11 +255,11 @@ the human review gate. Equivalent to running AFK mode for this one step only.
|
|
|
255
255
|
|
|
256
256
|
Follow the same process as `/generate-tests`:
|
|
257
257
|
|
|
258
|
-
Read `thoughts/devtronic/brief.md`, specifically the **Validation** layer, and generate failing tests that encode each acceptance criterion.
|
|
258
|
+
Read `thoughts/auto-devtronic/brief.md`, specifically the **Validation** layer, and generate failing tests that encode each acceptance criterion.
|
|
259
259
|
|
|
260
260
|
Save to:
|
|
261
261
|
- Test files in the appropriate test directory (detect from project structure)
|
|
262
|
-
- `thoughts/devtronic/tests-manifest.md` — traceability: criterion → test name → file
|
|
262
|
+
- `thoughts/auto-devtronic/tests-manifest.md` — traceability: criterion → test name → file
|
|
263
263
|
|
|
264
264
|
**Test naming convention**: `[feature].[criterion-slug].test.ts` or follow existing conventions.
|
|
265
265
|
|
|
@@ -293,10 +293,10 @@ Options:
|
|
|
293
293
|
## Step 4: Create Plan
|
|
294
294
|
|
|
295
295
|
Follow the same process as `/create-plan`, using:
|
|
296
|
-
- `thoughts/devtronic/brief.md` as the spec
|
|
297
|
-
- `thoughts/devtronic/tests-manifest.md` as the DoD
|
|
296
|
+
- `thoughts/auto-devtronic/brief.md` as the spec
|
|
297
|
+
- `thoughts/auto-devtronic/tests-manifest.md` as the DoD
|
|
298
298
|
|
|
299
|
-
Save plan to `thoughts/devtronic/plan.md`.
|
|
299
|
+
Save plan to `thoughts/auto-devtronic/plan.md`.
|
|
300
300
|
|
|
301
301
|
The plan **must include**:
|
|
302
302
|
- `## Task Dependencies` YAML block (required for parallel execution)
|
|
@@ -314,7 +314,7 @@ This is the RALPH core. Runs until tests pass or retries are exhausted.
|
|
|
314
314
|
attempt = 1
|
|
315
315
|
max_retries = N (from --max-retries, default 3)
|
|
316
316
|
last_failure = null
|
|
317
|
-
plan_path = thoughts/devtronic/plan.md
|
|
317
|
+
plan_path = thoughts/auto-devtronic/plan.md
|
|
318
318
|
```
|
|
319
319
|
|
|
320
320
|
### Loop body
|
|
@@ -327,7 +327,7 @@ WHILE attempt <= max_retries:
|
|
|
327
327
|
Include last_failure context in subagent prompts (if attempt > 1).
|
|
328
328
|
|
|
329
329
|
── 5b. Run Quality Checks ──────────────────────────────
|
|
330
|
-
Invoke the quality-
|
|
330
|
+
Invoke the quality-executor agent:
|
|
331
331
|
"Run all quality checks (typecheck, lint, test)"
|
|
332
332
|
|
|
333
333
|
── 5c. Evaluate Result ─────────────────────────────────
|
|
@@ -337,7 +337,7 @@ WHILE attempt <= max_retries:
|
|
|
337
337
|
IF checks fail:
|
|
338
338
|
last_failure = {
|
|
339
339
|
attempt: N,
|
|
340
|
-
output: <quality-
|
|
340
|
+
output: <quality-executor output>,
|
|
341
341
|
affected_files: <list from git diff>
|
|
342
342
|
}
|
|
343
343
|
|
|
@@ -376,7 +376,7 @@ When retries are exhausted or analyst recommends escalating:
|
|
|
376
376
|
## devtronic: Cannot Self-Correct ⚠️
|
|
377
377
|
|
|
378
378
|
**Attempts**: N / max_retries
|
|
379
|
-
**Last failure**: [quality-
|
|
379
|
+
**Last failure**: [quality-executor output summary]
|
|
380
380
|
|
|
381
381
|
**Failure analysis**:
|
|
382
382
|
- Root cause: [description]
|
|
@@ -536,9 +536,9 @@ git stash list | grep "devtronic" && git stash pop
|
|
|
536
536
|
| `path/to/file.ts` | Added / Modified |
|
|
537
537
|
|
|
538
538
|
### Session artifacts
|
|
539
|
-
- Brief: `thoughts/devtronic/brief.md`
|
|
540
|
-
- Tests manifest: `thoughts/devtronic/tests-manifest.md`
|
|
541
|
-
- Plan: `thoughts/devtronic/plan.md`
|
|
539
|
+
- Brief: `thoughts/auto-devtronic/brief.md`
|
|
540
|
+
- Tests manifest: `thoughts/auto-devtronic/tests-manifest.md`
|
|
541
|
+
- Plan: `thoughts/auto-devtronic/plan.md`
|
|
542
542
|
```
|
|
543
543
|
|
|
544
544
|
---
|
|
@@ -608,4 +608,4 @@ If a subagent task fails due to conflicts:
|
|
|
608
608
|
- **Requires devtronic core skills** — devtronic uses the same logic as `/generate-tests`, `/create-plan`, and `/execute-plan`. Those skills must be installed.
|
|
609
609
|
- **Requires `gh` CLI** — authenticated with repo write access.
|
|
610
610
|
- **AFK is not magic** — it reduces friction, not mistakes. Start with HITL on unfamiliar codebases.
|
|
611
|
-
- **Session artifacts** — all intermediate files are saved to `thoughts/devtronic/`. Do not delete them until the PR is merged.
|
|
611
|
+
- **Session artifacts** — all intermediate files are saved to `thoughts/auto-devtronic/`. Do not delete them until the PR is merged.
|
package/templates/addons/design-best-practices/skills/{design-review → design-critique}/SKILL.md
RENAMED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: design-
|
|
2
|
+
name: design-critique
|
|
3
3
|
description: Design critique with AI slop detection — visual hierarchy, information architecture, emotional resonance, actionable report
|
|
4
4
|
user-invokable: true
|
|
5
|
+
allowed-tools: Read, Glob, Grep
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# Design Review
|