devflow-kit 1.2.0 → 1.3.0
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/CHANGELOG.md +31 -2
- package/dist/cli.js +2 -0
- package/dist/commands/ambient.js +5 -4
- package/dist/commands/init.js +4 -2
- package/dist/commands/memory.js +4 -4
- package/dist/commands/skills.d.ts +11 -0
- package/dist/commands/skills.js +116 -0
- package/dist/commands/uninstall.js +11 -1
- package/dist/utils/installer.js +20 -2
- package/package.json +3 -2
- package/plugins/devflow-accessibility/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-ambient/.claude-plugin/plugin.json +4 -2
- package/plugins/devflow-ambient/README.md +8 -8
- package/plugins/devflow-ambient/commands/ambient.md +14 -14
- package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +15 -8
- package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +2 -2
- package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-code-review/.claude-plugin/plugin.json +13 -3
- package/plugins/devflow-code-review/skills/architecture-patterns/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/complexity-patterns/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/consistency-patterns/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/database-patterns/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/dependencies-patterns/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/documentation-patterns/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/performance-patterns/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/regression-patterns/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/review-methodology/SKILL.md +1 -1
- package/plugins/devflow-code-review/skills/security-patterns/SKILL.md +1 -1
- package/plugins/devflow-core-skills/.claude-plugin/plugin.json +9 -2
- package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +5 -8
- package/plugins/devflow-debug/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-go/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-implement/.claude-plugin/plugin.json +19 -3
- package/plugins/devflow-implement/skills/self-review/SKILL.md +1 -1
- package/plugins/devflow-java/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-python/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-react/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-resolve/.claude-plugin/plugin.json +13 -3
- package/plugins/devflow-resolve/skills/security-patterns/SKILL.md +1 -1
- package/plugins/devflow-rust/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-self-review/.claude-plugin/plugin.json +10 -3
- package/plugins/devflow-self-review/skills/self-review/SKILL.md +1 -1
- package/plugins/devflow-specify/.claude-plugin/plugin.json +15 -4
- package/plugins/devflow-typescript/.claude-plugin/plugin.json +10 -3
- package/scripts/hooks/{ambient-prompt.sh → ambient-prompt} +4 -4
- package/scripts/hooks/{background-memory-update.sh → background-memory-update} +3 -3
- package/scripts/hooks/{ensure-memory-gitignore.sh → ensure-memory-gitignore} +1 -1
- package/scripts/hooks/{pre-compact-memory.sh → pre-compact-memory} +2 -2
- package/scripts/hooks/run-hook +23 -0
- package/scripts/hooks/session-start-memory +151 -0
- package/scripts/hooks/{stop-update-memory.sh → stop-update-memory} +4 -4
- package/shared/skills/ambient-router/SKILL.md +15 -8
- package/shared/skills/ambient-router/references/skill-catalog.md +2 -2
- package/shared/skills/architecture-patterns/SKILL.md +1 -1
- package/shared/skills/complexity-patterns/SKILL.md +1 -1
- package/shared/skills/consistency-patterns/SKILL.md +1 -1
- package/shared/skills/database-patterns/SKILL.md +1 -1
- package/shared/skills/dependencies-patterns/SKILL.md +1 -1
- package/shared/skills/documentation-patterns/SKILL.md +1 -1
- package/shared/skills/performance-patterns/SKILL.md +1 -1
- package/shared/skills/regression-patterns/SKILL.md +1 -1
- package/shared/skills/review-methodology/SKILL.md +1 -1
- package/shared/skills/security-patterns/SKILL.md +1 -1
- package/shared/skills/self-review/SKILL.md +1 -1
- package/shared/skills/test-driven-development/SKILL.md +5 -8
- package/src/templates/settings.json +3 -3
- package/scripts/hooks/session-start-memory.sh +0 -126
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,35 @@ All notable changes to DevFlow will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [1.3.0] - 2026-03-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Skill shadowing** — `devflow skills shadow <name>` copies a skill for personal overrides
|
|
12
|
+
- `devflow skills unshadow <name>` restores the original
|
|
13
|
+
- `devflow skills list-shadowed` shows active overrides
|
|
14
|
+
- Shadowed skills are preserved during `devflow init` (not overwritten)
|
|
15
|
+
- Uninstall warns about remaining shadow files
|
|
16
|
+
- **Cross-platform hook wrapper** — `run-hook` polyglot entry point for Windows compatibility
|
|
17
|
+
- Discovers bash on Windows (Git Bash, WSL, MSYS2) via standard paths
|
|
18
|
+
- All hook scripts renamed to drop `.sh` extension
|
|
19
|
+
- **Ambient skill injection at session start** — `session-start-memory` hook injects `ambient-router` SKILL.md directly into context
|
|
20
|
+
- Eliminates the need for a Read tool call to load the ambient router
|
|
21
|
+
- Only activates when ambient mode is enabled
|
|
22
|
+
- **Skill activation integration tests** — `vitest.integration.config.ts` + helpers for live classification tests
|
|
23
|
+
- Separate `npm run test:integration` for tests requiring `claude` CLI
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- **Ambient depth labels renamed** — STANDARD→GUIDED, ESCALATE→ELEVATE for clarity
|
|
27
|
+
- GUIDED: skills guide the response; ELEVATE: elevate to a full workflow
|
|
28
|
+
- **Hook commands use `run-hook` dispatch** — Settings template and CLI now register hooks via `run-hook <name>` instead of direct `.sh` paths
|
|
29
|
+
- **`devflow init` auto-upgrades hook format** — Removes old `.sh`-style hooks before re-adding, ensuring existing installs migrate seamlessly
|
|
30
|
+
- **Skill descriptions audited** — All 12 review-only skills updated to trigger-format (`"This skill should be used when..."`)
|
|
31
|
+
- **Skills architecture docs** — Added description rules section with good/bad examples
|
|
32
|
+
- **`chmod` skipped on Windows** — `chmodRecursive` no longer runs on `win32` platform
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- **Ambient preamble missing skill path** — Hook now tells Claude to `Read` skills from `~/.claude/skills/<name>/SKILL.md`
|
|
36
|
+
- **Ambient `--status` hook path parsing** — Handles `run-hook <name>` format instead of assuming direct `.sh` path
|
|
9
37
|
|
|
10
38
|
---
|
|
11
39
|
|
|
@@ -48,7 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
48
76
|
### Added
|
|
49
77
|
- **Ambient mode** — New `devflow-ambient` plugin with `/ambient` command for proportional quality enforcement
|
|
50
78
|
- Intent classification (BUILD/DEBUG/REVIEW/PLAN/EXPLORE/CHAT) auto-loads relevant skills
|
|
51
|
-
- Three depth tiers: QUICK (zero overhead),
|
|
79
|
+
- Three depth tiers: QUICK (zero overhead), GUIDED (2-3 skills), ELEVATE (nudge to workflows)
|
|
52
80
|
- Always-on mode via `devflow ambient --enable` or `devflow init --ambient`
|
|
53
81
|
- New `ambient-router` skill for intent/depth classification
|
|
54
82
|
- New `test-driven-development` skill (auto-activates for BUILD tasks)
|
|
@@ -787,6 +815,7 @@ devflow init
|
|
|
787
815
|
|
|
788
816
|
---
|
|
789
817
|
|
|
818
|
+
[1.3.0]: https://github.com/dean0x/devflow/compare/v1.2.0...v1.3.0
|
|
790
819
|
[1.2.0]: https://github.com/dean0x/devflow/compare/v1.1.0...v1.2.0
|
|
791
820
|
[1.1.0]: https://github.com/dean0x/devflow/compare/v1.0.0...v1.1.0
|
|
792
821
|
[1.0.0]: https://github.com/dean0x/devflow/compare/v0.9.0...v1.0.0
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,7 @@ import { uninstallCommand } from './commands/uninstall.js';
|
|
|
8
8
|
import { listCommand } from './commands/list.js';
|
|
9
9
|
import { ambientCommand } from './commands/ambient.js';
|
|
10
10
|
import { memoryCommand } from './commands/memory.js';
|
|
11
|
+
import { skillsCommand } from './commands/skills.js';
|
|
11
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
13
|
const __dirname = dirname(__filename);
|
|
13
14
|
// Read version from package.json
|
|
@@ -25,6 +26,7 @@ program.addCommand(uninstallCommand);
|
|
|
25
26
|
program.addCommand(listCommand);
|
|
26
27
|
program.addCommand(ambientCommand);
|
|
27
28
|
program.addCommand(memoryCommand);
|
|
29
|
+
program.addCommand(skillsCommand);
|
|
28
30
|
// Handle no command
|
|
29
31
|
program.action(() => {
|
|
30
32
|
program.help();
|
package/dist/commands/ambient.js
CHANGED
|
@@ -4,7 +4,7 @@ import * as path from 'path';
|
|
|
4
4
|
import * as p from '@clack/prompts';
|
|
5
5
|
import color from 'picocolors';
|
|
6
6
|
import { getClaudeDirectory } from '../utils/paths.js';
|
|
7
|
-
const AMBIENT_HOOK_MARKER = 'ambient-prompt
|
|
7
|
+
const AMBIENT_HOOK_MARKER = 'ambient-prompt';
|
|
8
8
|
/**
|
|
9
9
|
* Add the ambient UserPromptSubmit hook to settings JSON.
|
|
10
10
|
* Idempotent — returns unchanged JSON if hook already exists.
|
|
@@ -17,7 +17,7 @@ export function addAmbientHook(settingsJson, devflowDir) {
|
|
|
17
17
|
if (!settings.hooks) {
|
|
18
18
|
settings.hooks = {};
|
|
19
19
|
}
|
|
20
|
-
const hookCommand = path.join(devflowDir, 'scripts', 'hooks',
|
|
20
|
+
const hookCommand = path.join(devflowDir, 'scripts', 'hooks', 'run-hook') + ' ambient-prompt';
|
|
21
21
|
const newEntry = {
|
|
22
22
|
hooks: [
|
|
23
23
|
{
|
|
@@ -103,8 +103,9 @@ export const ambientCommand = new Command('ambient')
|
|
|
103
103
|
// Try to extract devflowDir from existing hooks (e.g., Stop hook path)
|
|
104
104
|
const stopHook = settings.hooks?.Stop?.[0]?.hooks?.[0]?.command;
|
|
105
105
|
if (stopHook) {
|
|
106
|
-
// e.g., /
|
|
107
|
-
|
|
106
|
+
// e.g., "run-hook stop-update-memory" or "/path/to/.devflow/scripts/hooks/run-hook stop-update-memory"
|
|
107
|
+
const hookBinary = stopHook.split(' ')[0];
|
|
108
|
+
devflowDir = path.resolve(hookBinary, '..', '..', '..');
|
|
108
109
|
}
|
|
109
110
|
else {
|
|
110
111
|
devflowDir = path.join(process.env.HOME || '~', '.devflow');
|
package/dist/commands/init.js
CHANGED
|
@@ -379,9 +379,11 @@ export const initCommand = new Command('init')
|
|
|
379
379
|
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
380
380
|
try {
|
|
381
381
|
const content = await fs.readFile(settingsPath, 'utf-8');
|
|
382
|
+
// Always remove-then-add to upgrade hook format (e.g., .sh → run-hook)
|
|
383
|
+
const cleaned = removeMemoryHooks(content);
|
|
382
384
|
const updated = memoryEnabled
|
|
383
|
-
? addMemoryHooks(
|
|
384
|
-
:
|
|
385
|
+
? addMemoryHooks(cleaned, devflowDir)
|
|
386
|
+
: cleaned;
|
|
385
387
|
if (updated !== content) {
|
|
386
388
|
await fs.writeFile(settingsPath, updated, 'utf-8');
|
|
387
389
|
if (verbose) {
|
package/dist/commands/memory.js
CHANGED
|
@@ -9,9 +9,9 @@ import { createMemoryDir, migrateMemoryFiles } from '../utils/post-install.js';
|
|
|
9
9
|
* Map of hook event type → filename marker for the 3 memory hooks.
|
|
10
10
|
*/
|
|
11
11
|
const MEMORY_HOOK_CONFIG = {
|
|
12
|
-
Stop: 'stop-update-memory
|
|
13
|
-
SessionStart: 'session-start-memory
|
|
14
|
-
PreCompact: 'pre-compact-memory
|
|
12
|
+
Stop: 'stop-update-memory',
|
|
13
|
+
SessionStart: 'session-start-memory',
|
|
14
|
+
PreCompact: 'pre-compact-memory',
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
17
|
* Add all 3 memory hooks (Stop, SessionStart, PreCompact) to settings JSON.
|
|
@@ -30,7 +30,7 @@ export function addMemoryHooks(settingsJson, devflowDir) {
|
|
|
30
30
|
const existing = settings.hooks[hookType] ?? [];
|
|
31
31
|
const alreadyPresent = existing.some((matcher) => matcher.hooks.some((h) => h.command.includes(marker)));
|
|
32
32
|
if (!alreadyPresent) {
|
|
33
|
-
const hookCommand = path.join(devflowDir, 'scripts', 'hooks', marker
|
|
33
|
+
const hookCommand = path.join(devflowDir, 'scripts', 'hooks', 'run-hook') + ` ${marker}`;
|
|
34
34
|
const newEntry = {
|
|
35
35
|
hooks: [
|
|
36
36
|
{
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a skill has a shadow (personal override).
|
|
4
|
+
*/
|
|
5
|
+
export declare function hasShadow(skillName: string, devflowDir?: string): Promise<boolean>;
|
|
6
|
+
/**
|
|
7
|
+
* List all shadowed skill names.
|
|
8
|
+
*/
|
|
9
|
+
export declare function listShadowed(devflowDir?: string): Promise<string[]>;
|
|
10
|
+
export declare const skillsCommand: Command;
|
|
11
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as p from '@clack/prompts';
|
|
5
|
+
import color from 'picocolors';
|
|
6
|
+
import { getClaudeDirectory, getDevFlowDirectory } from '../utils/paths.js';
|
|
7
|
+
import { getAllSkillNames } from '../plugins.js';
|
|
8
|
+
import { copyDirectory } from '../utils/installer.js';
|
|
9
|
+
/**
|
|
10
|
+
* Check if a directory exists.
|
|
11
|
+
*/
|
|
12
|
+
async function dirExists(dirPath) {
|
|
13
|
+
try {
|
|
14
|
+
const stat = await fs.stat(dirPath);
|
|
15
|
+
return stat.isDirectory();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get the shadow directory for a skill.
|
|
23
|
+
*/
|
|
24
|
+
function getShadowDir(devflowDir, skillName) {
|
|
25
|
+
return path.join(devflowDir, 'skills', skillName);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Check if a skill has a shadow (personal override).
|
|
29
|
+
*/
|
|
30
|
+
export async function hasShadow(skillName, devflowDir) {
|
|
31
|
+
const dir = devflowDir ?? getDevFlowDirectory();
|
|
32
|
+
return dirExists(getShadowDir(dir, skillName));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* List all shadowed skill names.
|
|
36
|
+
*/
|
|
37
|
+
export async function listShadowed(devflowDir) {
|
|
38
|
+
const dir = devflowDir ?? getDevFlowDirectory();
|
|
39
|
+
const shadowsRoot = path.join(dir, 'skills');
|
|
40
|
+
try {
|
|
41
|
+
const entries = await fs.readdir(shadowsRoot, { withFileTypes: true });
|
|
42
|
+
return entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export const skillsCommand = new Command('skills')
|
|
49
|
+
.description('Manage skill overrides (shadow/unshadow/list)')
|
|
50
|
+
.argument('<action>', 'Action: shadow, unshadow, or list-shadowed')
|
|
51
|
+
.argument('[name]', 'Skill name (required for shadow/unshadow)')
|
|
52
|
+
.action(async (action, name) => {
|
|
53
|
+
const devflowDir = getDevFlowDirectory();
|
|
54
|
+
const claudeDir = getClaudeDirectory();
|
|
55
|
+
const allSkills = getAllSkillNames();
|
|
56
|
+
if (action === 'shadow') {
|
|
57
|
+
if (!name) {
|
|
58
|
+
p.log.error('Skill name required. Usage: devflow skills shadow <name>');
|
|
59
|
+
p.log.info(`Available skills: ${allSkills.join(', ')}`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
if (!allSkills.includes(name)) {
|
|
63
|
+
p.log.error(`Unknown skill: ${name}`);
|
|
64
|
+
p.log.info(`Available skills: ${allSkills.join(', ')}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
const installedSkillDir = path.join(claudeDir, 'skills', name);
|
|
68
|
+
if (!await dirExists(installedSkillDir)) {
|
|
69
|
+
p.log.error(`Skill not installed: ${name}. Run devflow init first.`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const shadowDir = getShadowDir(devflowDir, name);
|
|
73
|
+
if (await dirExists(shadowDir)) {
|
|
74
|
+
p.log.info(`${name} is already shadowed`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
// Create shadow directory and copy original as reference backup
|
|
78
|
+
await fs.mkdir(path.join(devflowDir, 'skills'), { recursive: true });
|
|
79
|
+
await copyDirectory(installedSkillDir, shadowDir);
|
|
80
|
+
p.log.success(`Shadowed ${color.cyan(name)}`);
|
|
81
|
+
p.log.info(`Edit ${color.dim(path.join(claudeDir, 'skills', name, 'SKILL.md'))} — it won't be overwritten on next init.`);
|
|
82
|
+
}
|
|
83
|
+
else if (action === 'unshadow') {
|
|
84
|
+
if (!name) {
|
|
85
|
+
p.log.error('Skill name required. Usage: devflow skills unshadow <name>');
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
const shadowDir = getShadowDir(devflowDir, name);
|
|
89
|
+
if (!await dirExists(shadowDir)) {
|
|
90
|
+
p.log.info(`${name} is not shadowed`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
await fs.rm(shadowDir, { recursive: true, force: true });
|
|
94
|
+
p.log.success(`Unshadowed ${color.cyan(name)}`);
|
|
95
|
+
p.log.info('Run devflow init to restore DevFlow\'s version.');
|
|
96
|
+
}
|
|
97
|
+
else if (action === 'list-shadowed') {
|
|
98
|
+
const shadowed = await listShadowed(devflowDir);
|
|
99
|
+
if (shadowed.length === 0) {
|
|
100
|
+
p.log.info('No shadowed skills');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
p.log.info(`Shadowed skills (${shadowed.length}):`);
|
|
104
|
+
for (const skill of shadowed) {
|
|
105
|
+
const isKnown = allSkills.includes(skill);
|
|
106
|
+
const status = isKnown ? color.green('active') : color.yellow('unknown skill');
|
|
107
|
+
p.log.info(` ${color.cyan(skill)} — ${status}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
p.log.error(`Unknown action: ${action}`);
|
|
112
|
+
p.log.info('Usage: devflow skills <shadow|unshadow|list-shadowed> [name]');
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -5,12 +5,13 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
6
|
import * as p from '@clack/prompts';
|
|
7
7
|
import color from 'picocolors';
|
|
8
|
-
import { getInstallationPaths, getClaudeDirectory, getManagedSettingsPath } from '../utils/paths.js';
|
|
8
|
+
import { getInstallationPaths, getClaudeDirectory, getDevFlowDirectory, getManagedSettingsPath } from '../utils/paths.js';
|
|
9
9
|
import { getGitRoot } from '../utils/git.js';
|
|
10
10
|
import { isClaudeCliAvailable } from '../utils/cli.js';
|
|
11
11
|
import { DEVFLOW_PLUGINS, getAllSkillNames, LEGACY_SKILL_NAMES } from '../plugins.js';
|
|
12
12
|
import { removeAmbientHook } from './ambient.js';
|
|
13
13
|
import { removeMemoryHooks } from './memory.js';
|
|
14
|
+
import { listShadowed } from './skills.js';
|
|
14
15
|
import { detectShell, getProfilePath } from '../utils/safe-delete.js';
|
|
15
16
|
import { isAlreadyInstalled, removeFromProfile } from '../utils/safe-delete-install.js';
|
|
16
17
|
import { removeManagedSettings } from '../utils/post-install.js';
|
|
@@ -403,6 +404,15 @@ export const uninstallCommand = new Command('uninstall')
|
|
|
403
404
|
}
|
|
404
405
|
}
|
|
405
406
|
}
|
|
407
|
+
// Warn about personal skill overrides
|
|
408
|
+
if (!isSelectiveUninstall) {
|
|
409
|
+
const shadowed = await listShadowed();
|
|
410
|
+
if (shadowed.length > 0) {
|
|
411
|
+
const shadowPath = path.join(getDevFlowDirectory(), 'skills');
|
|
412
|
+
p.log.warn(`Personal skill overrides remain in ${shadowPath}: ${shadowed.join(', ')}`);
|
|
413
|
+
p.log.info(color.dim(`Remove manually or run: rm -rf ${shadowPath}`));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
406
416
|
const status = color.green('DevFlow uninstalled successfully');
|
|
407
417
|
p.outro(`${status}${color.dim(' Reinstall: npx devflow-kit init')}`);
|
|
408
418
|
});
|
package/dist/utils/installer.js
CHANGED
|
@@ -105,6 +105,14 @@ export async function installViaFileCopy(options) {
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
for (const skill of allSkills) {
|
|
108
|
+
// Skip cleanup for shadowed skills — user has a personal override
|
|
109
|
+
const shadowDir = path.join(devflowDir, 'skills', skill);
|
|
110
|
+
try {
|
|
111
|
+
const stat = await fs.stat(shadowDir);
|
|
112
|
+
if (stat.isDirectory())
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
catch { /* no shadow — proceed with cleanup */ }
|
|
108
116
|
try {
|
|
109
117
|
await fs.rm(path.join(claudeDir, 'skills', skill), { recursive: true, force: true });
|
|
110
118
|
}
|
|
@@ -148,13 +156,21 @@ export async function installViaFileCopy(options) {
|
|
|
148
156
|
}
|
|
149
157
|
}
|
|
150
158
|
catch { /* no agents directory */ }
|
|
151
|
-
// Install skills (deduplicated)
|
|
159
|
+
// Install skills (deduplicated, respects shadows)
|
|
152
160
|
const skillsSource = path.join(pluginSourceDir, 'skills');
|
|
153
161
|
try {
|
|
154
162
|
const skillDirs = await fs.readdir(skillsSource, { withFileTypes: true });
|
|
155
163
|
for (const skillDir of skillDirs) {
|
|
156
164
|
if (skillDir.isDirectory()) {
|
|
157
165
|
if (skillsMap.get(skillDir.name) === plugin.name) {
|
|
166
|
+
// Skip copy for shadowed skills — user has a personal override
|
|
167
|
+
const shadowDir = path.join(devflowDir, 'skills', skillDir.name);
|
|
168
|
+
try {
|
|
169
|
+
const stat = await fs.stat(shadowDir);
|
|
170
|
+
if (stat.isDirectory())
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
catch { /* no shadow — proceed with copy */ }
|
|
158
174
|
const skillTarget = path.join(claudeDir, 'skills', skillDir.name);
|
|
159
175
|
await copyDirectory(path.join(skillsSource, skillDir.name), skillTarget);
|
|
160
176
|
}
|
|
@@ -169,7 +185,9 @@ export async function installViaFileCopy(options) {
|
|
|
169
185
|
try {
|
|
170
186
|
await fs.mkdir(scriptsTarget, { recursive: true });
|
|
171
187
|
await copyDirectory(scriptsSource, scriptsTarget);
|
|
172
|
-
|
|
188
|
+
if (process.platform !== 'win32') {
|
|
189
|
+
await chmodRecursive(scriptsTarget, 0o755);
|
|
190
|
+
}
|
|
173
191
|
}
|
|
174
192
|
catch { /* scripts may not exist */ }
|
|
175
193
|
spinner.stop('Components installed via file copy');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devflow-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Agentic Development Toolkit for Claude Code - Enhance AI-assisted development with intelligent commands and workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"prepublishOnly": "npm run build",
|
|
27
27
|
"version:bump": "npx tsx scripts/bump-version.ts",
|
|
28
28
|
"test": "vitest run",
|
|
29
|
-
"test:watch": "vitest"
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"test:integration": "vitest run --config vitest.integration.config.ts"
|
|
30
31
|
},
|
|
31
32
|
"keywords": [
|
|
32
33
|
"claude",
|
|
@@ -5,11 +5,18 @@
|
|
|
5
5
|
"name": "DevFlow Contributors",
|
|
6
6
|
"email": "dean@keren.dev"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.3.0",
|
|
9
9
|
"homepage": "https://github.com/dean0x/devflow",
|
|
10
10
|
"repository": "https://github.com/dean0x/devflow",
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"keywords": [
|
|
12
|
+
"keywords": [
|
|
13
|
+
"accessibility",
|
|
14
|
+
"wcag",
|
|
15
|
+
"aria",
|
|
16
|
+
"a11y"
|
|
17
|
+
],
|
|
13
18
|
"agents": [],
|
|
14
|
-
"skills": [
|
|
19
|
+
"skills": [
|
|
20
|
+
"accessibility"
|
|
21
|
+
]
|
|
15
22
|
}
|
|
@@ -9,10 +9,10 @@ Ambient mode — auto-loads relevant skills based on each prompt, no explicit co
|
|
|
9
9
|
Classify user intent and apply proportional skill enforcement to any prompt.
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
/ambient add a login form # BUILD/
|
|
13
|
-
/ambient fix the auth error # DEBUG/
|
|
12
|
+
/ambient add a login form # BUILD/GUIDED — loads TDD + implementation-patterns
|
|
13
|
+
/ambient fix the auth error # DEBUG/GUIDED — loads test-patterns + core-patterns
|
|
14
14
|
/ambient where is the config? # EXPLORE/QUICK — responds normally, zero overhead
|
|
15
|
-
/ambient refactor the auth system # BUILD/
|
|
15
|
+
/ambient refactor the auth system # BUILD/ELEVATE — suggests /implement
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Always-On Mode
|
|
@@ -30,19 +30,19 @@ When enabled, a `UserPromptSubmit` hook injects a classification preamble before
|
|
|
30
30
|
## How It Works
|
|
31
31
|
|
|
32
32
|
1. **Classify intent** — BUILD, DEBUG, REVIEW, PLAN, EXPLORE, or CHAT
|
|
33
|
-
2. **Classify depth** — QUICK (zero overhead),
|
|
33
|
+
2. **Classify depth** — QUICK (zero overhead), GUIDED (2-3 skills), or ELEVATE (workflow nudge)
|
|
34
34
|
3. **Apply proportionally**:
|
|
35
35
|
- QUICK: respond normally
|
|
36
|
-
-
|
|
37
|
-
-
|
|
36
|
+
- GUIDED: load relevant skills, enforce TDD for BUILD
|
|
37
|
+
- ELEVATE: respond + recommend full workflow command
|
|
38
38
|
|
|
39
39
|
## Depth Tiers
|
|
40
40
|
|
|
41
41
|
| Depth | When | Overhead |
|
|
42
42
|
|-------|------|----------|
|
|
43
43
|
| QUICK | Chat, simple exploration, git/devops ops, single-word confirmations | ~0 tokens |
|
|
44
|
-
|
|
|
45
|
-
|
|
|
44
|
+
| GUIDED | BUILD/DEBUG/REVIEW/PLAN, 1-5 file scope | ~500-1000 tokens (skill reads) |
|
|
45
|
+
| ELEVATE | Multi-file, architectural, system-wide scope | ~0 extra tokens (nudge only) |
|
|
46
46
|
|
|
47
47
|
## Skills
|
|
48
48
|
|
|
@@ -25,7 +25,7 @@ Read the `ambient-router` skill:
|
|
|
25
25
|
Apply the ambient-router classification to `$ARGUMENTS`:
|
|
26
26
|
|
|
27
27
|
1. **Intent:** BUILD | DEBUG | REVIEW | PLAN | EXPLORE | CHAT
|
|
28
|
-
2. **Depth:** QUICK |
|
|
28
|
+
2. **Depth:** QUICK | GUIDED | ELEVATE
|
|
29
29
|
|
|
30
30
|
If no arguments provided, output:
|
|
31
31
|
|
|
@@ -37,10 +37,10 @@ Classify intent and auto-load relevant skills.
|
|
|
37
37
|
Usage: /ambient <your prompt>
|
|
38
38
|
|
|
39
39
|
Examples:
|
|
40
|
-
/ambient add a login form → BUILD/
|
|
41
|
-
/ambient fix the auth error → DEBUG/
|
|
40
|
+
/ambient add a login form → BUILD/GUIDED (loads TDD + implementation-patterns)
|
|
41
|
+
/ambient fix the auth error → DEBUG/GUIDED (loads test-patterns + core-patterns)
|
|
42
42
|
/ambient where is the config? → EXPLORE/QUICK (responds normally)
|
|
43
|
-
/ambient refactor the auth system → BUILD/
|
|
43
|
+
/ambient refactor the auth system → BUILD/ELEVATE (suggests /implement)
|
|
44
44
|
|
|
45
45
|
Always-on: devflow ambient --enable
|
|
46
46
|
```
|
|
@@ -50,15 +50,15 @@ Then stop.
|
|
|
50
50
|
### Phase 3: State Classification
|
|
51
51
|
|
|
52
52
|
- **QUICK:** Skip this phase entirely. Respond directly in Phase 4.
|
|
53
|
-
- **
|
|
54
|
-
- **
|
|
53
|
+
- **GUIDED:** Output one line: `Ambient: {INTENT}/{DEPTH}. Loading: {skill1}, {skill2}.`
|
|
54
|
+
- **ELEVATE:** Skip — recommendation happens in Phase 4.
|
|
55
55
|
|
|
56
56
|
### Phase 4: Apply
|
|
57
57
|
|
|
58
58
|
**QUICK:**
|
|
59
59
|
Respond to the user's prompt normally. Zero skill loading. Zero overhead.
|
|
60
60
|
|
|
61
|
-
**
|
|
61
|
+
**GUIDED:**
|
|
62
62
|
Read the selected skills based on the ambient-router's skill selection matrix:
|
|
63
63
|
|
|
64
64
|
| Intent | Primary Skills | Secondary (conditional) |
|
|
@@ -72,7 +72,7 @@ Read up to 3 skills from `~/.claude/skills/{name}/SKILL.md`. Apply their pattern
|
|
|
72
72
|
|
|
73
73
|
For BUILD intent: enforce RED-GREEN-REFACTOR from test-driven-development. Write failing tests before production code.
|
|
74
74
|
|
|
75
|
-
**
|
|
75
|
+
**ELEVATE:**
|
|
76
76
|
Respond to the user's prompt with your best effort, then append:
|
|
77
77
|
|
|
78
78
|
> This task spans multiple files/systems. Consider `/implement` for full lifecycle management (exploration → planning → implementation → review).
|
|
@@ -84,11 +84,11 @@ Respond to the user's prompt with your best effort, then append:
|
|
|
84
84
|
│
|
|
85
85
|
├─ Phase 1: Load ambient-router skill
|
|
86
86
|
├─ Phase 2: Classify intent + depth
|
|
87
|
-
├─ Phase 3: State classification (
|
|
87
|
+
├─ Phase 3: State classification (GUIDED only)
|
|
88
88
|
└─ Phase 4: Apply
|
|
89
89
|
├─ QUICK → respond directly
|
|
90
|
-
├─
|
|
91
|
-
└─
|
|
90
|
+
├─ GUIDED → load 2-3 skills, apply patterns, respond
|
|
91
|
+
└─ ELEVATE → respond + workflow nudge
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
## Edge Cases
|
|
@@ -104,7 +104,7 @@ Respond to the user's prompt with your best effort, then append:
|
|
|
104
104
|
## Principles
|
|
105
105
|
|
|
106
106
|
1. **No agents** — Ambient enhances the main session, never spawns subagents
|
|
107
|
-
2. **Proportional** — QUICK gets zero overhead,
|
|
108
|
-
3. **Transparent** — State classification for
|
|
107
|
+
2. **Proportional** — QUICK gets zero overhead, GUIDED gets 2-3 skills, ELEVATE gets a nudge
|
|
108
|
+
3. **Transparent** — State classification for GUIDED/ELEVATE, silent for QUICK
|
|
109
109
|
4. **Respectful** — Never over-classify; when in doubt, go one tier lower
|
|
110
|
-
5. **TDD for BUILD** —
|
|
110
|
+
5. **TDD for BUILD** — GUIDED depth BUILD tasks enforce test-first workflow
|
|
@@ -36,7 +36,7 @@ Determine what the user is trying to do from their prompt.
|
|
|
36
36
|
| **EXPLORE** | "what is", "where is", "find", "show me", "explain", "how does" | "where is the config?", "explain this function" |
|
|
37
37
|
| **CHAT** | greetings, meta-questions, confirmations, short responses | "thanks", "yes", "what can you do?" |
|
|
38
38
|
|
|
39
|
-
**Ambiguous prompts:** Default to the lowest-overhead classification. "Update the README" → BUILD/
|
|
39
|
+
**Ambiguous prompts:** Default to the lowest-overhead classification. "Update the README" → BUILD/GUIDED. Git operations like "commit this" → QUICK.
|
|
40
40
|
|
|
41
41
|
## Step 2: Classify Depth
|
|
42
42
|
|
|
@@ -45,10 +45,10 @@ Determine how much enforcement the prompt warrants.
|
|
|
45
45
|
| Depth | Criteria | Action |
|
|
46
46
|
|-------|----------|--------|
|
|
47
47
|
| **QUICK** | CHAT intent. EXPLORE with no analytical depth ("where is X?"). Git/devops operations (commit, push, merge, branch, pr, deploy, reinstall). Single-word continuations. | Respond normally. Zero overhead. Do not state classification. |
|
|
48
|
-
| **
|
|
49
|
-
| **
|
|
48
|
+
| **GUIDED** | BUILD/DEBUG/REVIEW/PLAN intent (any word count). EXPLORE with analytical depth ("analyze our X", "discuss how Y works"). | Read and apply 2-3 relevant skills from the selection matrix below. State classification briefly. |
|
|
49
|
+
| **ELEVATE** | Multi-file architectural change, system-wide scope, > 5 files. Detailed implementation plan (100+ words with plan structure). | Respond at best effort + recommend: "This looks like it would benefit from `/implement` for full lifecycle management." |
|
|
50
50
|
|
|
51
|
-
## Step 3: Select Skills (
|
|
51
|
+
## Step 3: Select Skills (GUIDED depth only)
|
|
52
52
|
|
|
53
53
|
Based on classified intent, read the following skills to inform your response.
|
|
54
54
|
|
|
@@ -65,19 +65,26 @@ See `references/skill-catalog.md` for the full skill-to-intent mapping with file
|
|
|
65
65
|
|
|
66
66
|
## Step 4: Apply
|
|
67
67
|
|
|
68
|
+
<IMPORTANT>
|
|
69
|
+
When classification is GUIDED or ELEVATE, skill application is NON-NEGOTIABLE.
|
|
70
|
+
Do not rationalize skipping skills. Do not respond without loading them first.
|
|
71
|
+
If test-driven-development is selected, you MUST write the failing test before ANY production code.
|
|
72
|
+
</IMPORTANT>
|
|
73
|
+
|
|
68
74
|
- **QUICK:** Respond directly. No preamble, no classification statement.
|
|
69
|
-
- **
|
|
70
|
-
- **
|
|
75
|
+
- **GUIDED:** State classification briefly: `Ambient: BUILD/GUIDED. Loading: test-driven-development, implementation-patterns.` Then read the selected skills and apply their patterns. No exceptions.
|
|
76
|
+
- **ELEVATE:** Respond with your best effort, then append: `> This task spans multiple files/systems. Consider \`/implement\` for full lifecycle.`
|
|
71
77
|
|
|
72
78
|
---
|
|
73
79
|
|
|
74
80
|
## Transparency Rules
|
|
75
81
|
|
|
76
82
|
1. **QUICK → silent.** No classification output.
|
|
77
|
-
2. **
|
|
78
|
-
3. **
|
|
83
|
+
2. **GUIDED → brief statement + full skill enforcement.** One line: intent, depth, skills loaded. Then follow every skill requirement without shortcuts.
|
|
84
|
+
3. **ELEVATE → recommendation.** Best-effort response + workflow nudge.
|
|
79
85
|
4. **Never lie about classification.** If uncertain, say so.
|
|
80
86
|
5. **Never over-classify.** When in doubt, go one tier lower.
|
|
87
|
+
6. **Never under-apply.** Rationalization is the enemy of quality. If a skill requires a step, do the step.
|
|
81
88
|
|
|
82
89
|
## Edge Cases
|
|
83
90
|
|
|
@@ -4,7 +4,7 @@ Full mapping of DevFlow skills to ambient intents and file-type triggers. The am
|
|
|
4
4
|
|
|
5
5
|
## Skills Available for Ambient Loading
|
|
6
6
|
|
|
7
|
-
These skills may be loaded during
|
|
7
|
+
These skills may be loaded during GUIDED-depth ambient routing.
|
|
8
8
|
|
|
9
9
|
### BUILD Intent
|
|
10
10
|
|
|
@@ -65,4 +65,4 @@ These skills are loaded only by explicit DevFlow commands (primarily `/code-revi
|
|
|
65
65
|
- **Maximum 3 skills** per ambient response (primary + up to 2 secondary)
|
|
66
66
|
- **Primary skills** are always loaded for the classified intent
|
|
67
67
|
- **Secondary skills** are loaded only when file patterns match conversation context
|
|
68
|
-
- If more than 3 skills seem relevant, this is an
|
|
68
|
+
- If more than 3 skills seem relevant, this is an ELEVATE signal
|
|
@@ -5,12 +5,22 @@
|
|
|
5
5
|
"name": "DevFlow Contributors",
|
|
6
6
|
"email": "dean@keren.dev"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.3.0",
|
|
9
9
|
"homepage": "https://github.com/dean0x/devflow",
|
|
10
10
|
"repository": "https://github.com/dean0x/devflow",
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"keywords": [
|
|
13
|
-
|
|
12
|
+
"keywords": [
|
|
13
|
+
"review",
|
|
14
|
+
"code-quality",
|
|
15
|
+
"security",
|
|
16
|
+
"architecture",
|
|
17
|
+
"pr-review"
|
|
18
|
+
],
|
|
19
|
+
"agents": [
|
|
20
|
+
"git",
|
|
21
|
+
"reviewer",
|
|
22
|
+
"synthesizer"
|
|
23
|
+
],
|
|
14
24
|
"skills": [
|
|
15
25
|
"agent-teams",
|
|
16
26
|
"architecture-patterns",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: architecture-patterns
|
|
3
|
-
description:
|
|
3
|
+
description: This skill should be used when reviewing code for SOLID violations, tight coupling, or layering issues.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read, Grep, Glob
|
|
6
6
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: complexity-patterns
|
|
3
|
-
description:
|
|
3
|
+
description: This skill should be used when reviewing code for high cyclomatic complexity, deep nesting, or long functions.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read, Grep, Glob
|
|
6
6
|
---
|