guild-agents 1.5.0 → 2.0.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/README.md +71 -67
- package/bin/guild.js +4 -85
- package/package.json +1 -1
- package/src/commands/doctor.js +11 -33
- package/src/commands/init.js +1 -1
- package/src/templates/skills/build-feature/SKILL.md +7 -38
- package/src/templates/skills/build-feature/evals/evals.json +2 -2
- package/src/templates/skills/council/SKILL.md +4 -14
- package/src/templates/skills/council/evals/evals.json +3 -13
- package/src/templates/skills/create-pr/SKILL.md +2 -5
- package/src/templates/skills/guild-specialize/SKILL.md +2 -5
- package/src/templates/skills/qa-cycle/SKILL.md +0 -7
- package/src/templates/skills/re-specialize/SKILL.md +0 -3
- package/src/templates/skills/session-end/SKILL.md +77 -30
- package/src/templates/skills/session-start/SKILL.md +51 -20
- package/src/utils/eval-runner.js +2 -8
- package/src/utils/generators.js +3 -4
- package/src/utils/skill-parser.js +83 -0
- package/src/utils/trigger-runner.js +1 -1
- package/src/commands/logs.js +0 -63
- package/src/commands/reset-learnings.js +0 -44
- package/src/commands/run.js +0 -105
- package/src/commands/stats.js +0 -147
- package/src/templates/agents/learnings-extractor.md +0 -49
- package/src/templates/skills/dev-flow/SKILL.md +0 -81
- package/src/templates/skills/dev-flow/evals/evals.json +0 -36
- package/src/templates/skills/dev-flow/evals/triggers.json +0 -16
- package/src/templates/skills/new-feature/SKILL.md +0 -119
- package/src/templates/skills/new-feature/evals/evals.json +0 -41
- package/src/templates/skills/new-feature/evals/triggers.json +0 -16
- package/src/templates/skills/review/SKILL.md +0 -97
- package/src/templates/skills/review/evals/evals.json +0 -43
- package/src/templates/skills/review/evals/triggers.json +0 -16
- package/src/templates/skills/status/SKILL.md +0 -100
- package/src/templates/skills/status/evals/evals.json +0 -40
- package/src/templates/skills/status/evals/triggers.json +0 -16
- package/src/templates/skills/verify/SKILL.md +0 -114
- package/src/templates/skills/verify/evals/triggers.json +0 -16
- package/src/utils/accounting.js +0 -139
- package/src/utils/dispatch-protocol.js +0 -71
- package/src/utils/dispatch.js +0 -172
- package/src/utils/executor.js +0 -293
- package/src/utils/learnings-io.js +0 -76
- package/src/utils/learnings.js +0 -204
- package/src/utils/orchestrator-io.js +0 -356
- package/src/utils/orchestrator.js +0 -590
- package/src/utils/pricing.js +0 -28
- package/src/utils/providers/claude-code.js +0 -43
- package/src/utils/skill-loader.js +0 -83
- package/src/utils/trace.js +0 -400
- package/src/utils/workflow-parser.js +0 -225
package/src/commands/run.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* run.js — Executes a skill workflow (or displays the plan in dry-run mode)
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as p from '@clack/prompts';
|
|
6
|
-
import chalk from 'chalk';
|
|
7
|
-
import { ensureProjectRoot } from '../utils/files.js';
|
|
8
|
-
import { orchestrate, finalizeWorkflowTrace } from '../utils/orchestrator-io.js';
|
|
9
|
-
import { execute } from '../utils/executor.js';
|
|
10
|
-
import { createClaudeCodeProvider } from '../utils/providers/claude-code.js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Displays the execution plan without running it.
|
|
14
|
-
* @param {object} plan
|
|
15
|
-
* @param {object} dispatchInfoMap
|
|
16
|
-
*/
|
|
17
|
-
function displayPlan(plan, dispatchInfoMap) {
|
|
18
|
-
for (let i = 0; i < plan.groups.length; i++) {
|
|
19
|
-
const group = plan.groups[i];
|
|
20
|
-
const label = group.parallel ? `Group ${i + 1} (parallel)` : `Group ${i + 1}`;
|
|
21
|
-
p.log.step(chalk.bold(label));
|
|
22
|
-
|
|
23
|
-
for (const step of group.steps) {
|
|
24
|
-
const dispatch = dispatchInfoMap[step.id] || {};
|
|
25
|
-
const roleLabel = step.role === 'system' ? chalk.yellow('system') : chalk.blue(step.role);
|
|
26
|
-
const modelLabel = dispatch.model ? chalk.gray(` → ${dispatch.model}`) : '';
|
|
27
|
-
const gateLabel = step.gate ? chalk.red(' GATE') : '';
|
|
28
|
-
|
|
29
|
-
p.log.info(` ${chalk.white.bold(step.id)} ${roleLabel}${modelLabel}${gateLabel}`);
|
|
30
|
-
p.log.info(chalk.gray(` ${step.intent}`));
|
|
31
|
-
|
|
32
|
-
if (step.requires && step.requires.length > 0) {
|
|
33
|
-
p.log.info(chalk.gray(` requires: ${step.requires.join(', ')}`));
|
|
34
|
-
}
|
|
35
|
-
if (step.produces && step.produces.length > 0) {
|
|
36
|
-
p.log.info(chalk.gray(` produces: ${step.produces.join(', ')}`));
|
|
37
|
-
}
|
|
38
|
-
if (step.condition) {
|
|
39
|
-
p.log.info(chalk.gray(` condition: ${step.condition}`));
|
|
40
|
-
}
|
|
41
|
-
if (step.commands && step.commands.length > 0) {
|
|
42
|
-
p.log.info(chalk.gray(` commands: ${step.commands.join(', ')}`));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Runs the `guild run <skill>` command.
|
|
50
|
-
*
|
|
51
|
-
* @param {string} skillName - Name of the skill to run
|
|
52
|
-
* @param {string} [input=''] - Optional input text for the skill
|
|
53
|
-
* @param {object} [options={}] - Options
|
|
54
|
-
* @param {string} [options.profile='max'] - Model profile
|
|
55
|
-
* @param {boolean} [options.dryRun=false] - Show plan without executing
|
|
56
|
-
*/
|
|
57
|
-
export async function runRun(skillName, input = '', options = {}) {
|
|
58
|
-
const root = ensureProjectRoot();
|
|
59
|
-
const { profile = 'max', dryRun = false } = options;
|
|
60
|
-
|
|
61
|
-
p.intro(chalk.bold.cyan(' Guild — Run: ' + skillName + ' '));
|
|
62
|
-
|
|
63
|
-
const { plan, trace, dispatchInfoMap } = await orchestrate(skillName, input, {
|
|
64
|
-
profile,
|
|
65
|
-
projectRoot: root,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
p.log.info(chalk.gray(`Profile: ${profile} | Steps: ${plan.totalSteps}`));
|
|
69
|
-
|
|
70
|
-
if (dryRun) {
|
|
71
|
-
displayPlan(plan, dispatchInfoMap);
|
|
72
|
-
p.outro(chalk.gray('Plan generated (dry-run). No steps were executed.'));
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Real execution
|
|
77
|
-
const provider = createClaudeCodeProvider({ projectRoot: root });
|
|
78
|
-
|
|
79
|
-
const finalPlan = await execute(plan, dispatchInfoMap, {
|
|
80
|
-
provider,
|
|
81
|
-
skillBody: input,
|
|
82
|
-
trace,
|
|
83
|
-
projectRoot: root,
|
|
84
|
-
|
|
85
|
-
onStepStart(step, dispatch) {
|
|
86
|
-
const roleLabel = step.role === 'system' ? chalk.yellow('system') : chalk.blue(step.role);
|
|
87
|
-
const modelLabel = dispatch.model ? chalk.gray(` (${dispatch.model})`) : '';
|
|
88
|
-
p.log.step(`${chalk.bold(step.id)} ${roleLabel}${modelLabel}`);
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
onStepEnd(step, result) {
|
|
92
|
-
const icon = result.status === 'passed' ? chalk.green('✓') : chalk.red('✗');
|
|
93
|
-
p.log.info(` ${icon} ${result.status}`);
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Finalize trace
|
|
98
|
-
const { executionSummary } = finalizeWorkflowTrace(trace, finalPlan);
|
|
99
|
-
|
|
100
|
-
const statusLabel = finalPlan.status === 'completed'
|
|
101
|
-
? chalk.green('completed')
|
|
102
|
-
: chalk.red(finalPlan.status);
|
|
103
|
-
|
|
104
|
-
p.outro(`${statusLabel} | ${executionSummary}`);
|
|
105
|
-
}
|
package/src/commands/stats.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* stats.js — Token usage stats command.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as p from '@clack/prompts';
|
|
6
|
-
import chalk from 'chalk';
|
|
7
|
-
import { existsSync, unlinkSync, copyFileSync } from 'fs';
|
|
8
|
-
import { join } from 'path';
|
|
9
|
-
import { loadUsage, aggregate, estimateWithProfile } from '../utils/accounting.js';
|
|
10
|
-
import { getModelShortName } from '../utils/pricing.js';
|
|
11
|
-
|
|
12
|
-
const USAGE_PATH = join('.claude', 'guild', 'usage.json');
|
|
13
|
-
|
|
14
|
-
function fmt(n) {
|
|
15
|
-
return n.toLocaleString('en-US');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function usd(n) {
|
|
19
|
-
return `$${n.toFixed(2)}`;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function pct(part, total) {
|
|
23
|
-
if (total === 0) return '0%';
|
|
24
|
-
return `${Math.round((part / total) * 100)}%`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const PERIOD_LABELS = {
|
|
28
|
-
today: 'Today',
|
|
29
|
-
week: 'Last 7 days',
|
|
30
|
-
month: 'Last 30 days',
|
|
31
|
-
all: 'All time',
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export function formatCsv(entries) {
|
|
35
|
-
const headers = 'timestamp,workflow,agent,tier,model,inputTokens,outputTokens,totalTokens,estimatedCostUSD';
|
|
36
|
-
const rows = entries.map(e =>
|
|
37
|
-
`${e.timestamp},${e.workflow},${e.agent},${e.tier},${e.model},${e.inputTokens},${e.outputTokens},${e.totalTokens},${e.estimatedCostUSD.toFixed(6)}`
|
|
38
|
-
);
|
|
39
|
-
return [headers, ...rows].join('\n') + '\n';
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function runStats(options = {}) {
|
|
43
|
-
const root = process.cwd();
|
|
44
|
-
|
|
45
|
-
if (options.reset) {
|
|
46
|
-
return handleReset(root, options.force);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (options.export === 'csv') {
|
|
50
|
-
const usage = loadUsage(root);
|
|
51
|
-
if (usage.entries.length === 0) {
|
|
52
|
-
console.log('No usage data to export.');
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
process.stdout.write(formatCsv(usage.entries));
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const period = options.period || 'month';
|
|
60
|
-
const totals = aggregate(root, period);
|
|
61
|
-
|
|
62
|
-
p.intro(chalk.bold.cyan(`Guild Usage Stats — ${PERIOD_LABELS[period] || period}`));
|
|
63
|
-
|
|
64
|
-
if (totals.totalTokens === 0) {
|
|
65
|
-
p.log.info('No usage data yet. Token tracking will begin when workflows record usage.');
|
|
66
|
-
p.outro('');
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
p.log.step('Summary');
|
|
71
|
-
p.log.info(` Workflows executed: ${chalk.bold(fmt(totals.workflowCount))}`);
|
|
72
|
-
p.log.info(` Total tokens: ${chalk.bold(fmt(totals.totalTokens))}`);
|
|
73
|
-
p.log.info(` Estimated cost: ${chalk.bold.green(usd(totals.totalCostUSD))}`);
|
|
74
|
-
|
|
75
|
-
if (Object.keys(totals.tokensByTier).length > 0) {
|
|
76
|
-
p.log.step('By tier');
|
|
77
|
-
for (const [tier, tokens] of Object.entries(totals.tokensByTier)) {
|
|
78
|
-
p.log.info(` ${tier.padEnd(12)} ${fmt(tokens).padStart(10)} tok (${pct(tokens, totals.totalTokens).padStart(4)})`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (Object.keys(totals.tokensByModel).length > 0) {
|
|
83
|
-
p.log.step('By model');
|
|
84
|
-
for (const [model, tokens] of Object.entries(totals.tokensByModel)) {
|
|
85
|
-
p.log.info(` ${getModelShortName(model).padEnd(12)} ${fmt(tokens).padStart(10)} tok`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (Object.keys(totals.tokensByWorkflow).length > 0) {
|
|
90
|
-
p.log.step('Top workflows');
|
|
91
|
-
const sorted = Object.entries(totals.tokensByWorkflow).sort((a, b) => b[1] - a[1]);
|
|
92
|
-
for (const [wf, tokens] of sorted) {
|
|
93
|
-
p.log.info(` ${wf.padEnd(20)} ${fmt(tokens).padStart(10)} tok`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (options.compare) {
|
|
98
|
-
const usage = loadUsage(root);
|
|
99
|
-
const filtered = usage.entries;
|
|
100
|
-
const maxCost = estimateWithProfile(filtered, 'max');
|
|
101
|
-
const proCost = estimateWithProfile(filtered, 'pro');
|
|
102
|
-
const allOpusCost = estimateWithProfile(filtered, 'all-opus');
|
|
103
|
-
|
|
104
|
-
p.log.step('Profile comparison');
|
|
105
|
-
p.log.info(` ${'max'.padEnd(12)} ${usd(maxCost).padStart(10)} —`);
|
|
106
|
-
p.log.info(` ${'pro'.padEnd(12)} ${usd(proCost).padStart(10)} ${diffLabel(proCost, maxCost)}`);
|
|
107
|
-
p.log.info(` ${'all-opus'.padEnd(12)} ${usd(allOpusCost).padStart(10)} ${diffLabel(allOpusCost, maxCost)}`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
p.outro('');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function diffLabel(cost, baseline) {
|
|
114
|
-
if (baseline === 0) return '';
|
|
115
|
-
const diff = ((cost - baseline) / baseline) * 100;
|
|
116
|
-
const sign = diff >= 0 ? '+' : '';
|
|
117
|
-
return chalk.gray(`${sign}${Math.round(diff)}%`);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async function handleReset(root, force) {
|
|
121
|
-
const filePath = join(root, USAGE_PATH);
|
|
122
|
-
|
|
123
|
-
p.intro(chalk.bold.cyan('Guild — Reset Usage Stats'));
|
|
124
|
-
|
|
125
|
-
if (!existsSync(filePath)) {
|
|
126
|
-
p.log.info('No usage data found. Nothing to reset.');
|
|
127
|
-
p.outro('');
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (!force) {
|
|
132
|
-
const confirmed = await p.confirm({
|
|
133
|
-
message: 'This will delete all usage history. Continue?',
|
|
134
|
-
initialValue: false,
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
if (p.isCancel(confirmed) || !confirmed) {
|
|
138
|
-
p.cancel('Reset cancelled.');
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
copyFileSync(filePath, filePath + '.bak');
|
|
144
|
-
unlinkSync(filePath);
|
|
145
|
-
p.log.success(`${chalk.green('✓')} Usage history deleted. Backup saved as usage.json.bak.`);
|
|
146
|
-
p.outro('');
|
|
147
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: learnings-extractor
|
|
3
|
-
description: "Extracts compound learnings from pipeline executions"
|
|
4
|
-
tools: Read, Glob, Grep
|
|
5
|
-
permissionMode: plan
|
|
6
|
-
default-tier: routine
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Learnings Extractor
|
|
10
|
-
|
|
11
|
-
You are the Learnings Extractor for [PROJECT]. Your job is to analyze completed pipeline traces and extract reusable patterns, recurring issues, and optimization opportunities that improve future executions.
|
|
12
|
-
|
|
13
|
-
## Responsibilities
|
|
14
|
-
|
|
15
|
-
- Read pipeline trace files from `.claude/guild/traces/`
|
|
16
|
-
- Identify patterns across multiple executions (recurring review loops, common failures)
|
|
17
|
-
- Extract actionable learnings that reduce future iteration count
|
|
18
|
-
- Update `.claude/guild/learnings.md` with new findings
|
|
19
|
-
- Prioritize learnings by impact (reduces tokens, reduces loops, improves quality)
|
|
20
|
-
|
|
21
|
-
## What you do NOT do
|
|
22
|
-
|
|
23
|
-
- You do not implement features — that is the Developer's role
|
|
24
|
-
- You do not evaluate strategy — that is the Advisor's role
|
|
25
|
-
- You do not modify source code — you only read traces and write learnings
|
|
26
|
-
|
|
27
|
-
## Process
|
|
28
|
-
|
|
29
|
-
1. Read the pipeline trace provided as input
|
|
30
|
-
2. Analyze step results, loop counts, and failure patterns
|
|
31
|
-
3. Compare with existing learnings in `.claude/guild/learnings.md`
|
|
32
|
-
4. Extract new learnings or reinforce existing ones
|
|
33
|
-
5. Write updated learnings in a structured format
|
|
34
|
-
|
|
35
|
-
## Output format
|
|
36
|
-
|
|
37
|
-
Each learning should include:
|
|
38
|
-
|
|
39
|
-
- **Pattern**: What was observed
|
|
40
|
-
- **Frequency**: How often it occurs (first-seen or recurring)
|
|
41
|
-
- **Recommendation**: What to do differently next time
|
|
42
|
-
- **Impact**: Expected reduction in loops, tokens, or failures
|
|
43
|
-
|
|
44
|
-
## Behavior rules
|
|
45
|
-
|
|
46
|
-
- Never duplicate an existing learning — update its frequency instead
|
|
47
|
-
- Focus on actionable recommendations, not observations
|
|
48
|
-
- Keep learnings concise — one paragraph maximum per entry
|
|
49
|
-
- Tag learnings with the workflow they came from
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: dev-flow
|
|
3
|
-
description: "Shows current pipeline phase and what comes next"
|
|
4
|
-
user-invocable: true
|
|
5
|
-
workflow:
|
|
6
|
-
version: 1
|
|
7
|
-
steps:
|
|
8
|
-
- id: read-state
|
|
9
|
-
role: system
|
|
10
|
-
intent: "Read SESSION.md to determine current feature and pipeline phase."
|
|
11
|
-
commands: [cat SESSION.md]
|
|
12
|
-
produces: [session-state, feature-name, current-phase]
|
|
13
|
-
- id: present-flow
|
|
14
|
-
role: system
|
|
15
|
-
intent: "Display pipeline progress with phase checklist and suggest next step."
|
|
16
|
-
requires: [session-state, feature-name, current-phase]
|
|
17
|
-
produces: [flow-display]
|
|
18
|
-
gate: true
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
# Dev Flow
|
|
22
|
-
|
|
23
|
-
Shows the current phase of the development pipeline and suggests the next step. Useful for resuming work when you do not remember where you left off in the flow.
|
|
24
|
-
|
|
25
|
-
## When to use
|
|
26
|
-
|
|
27
|
-
- When resuming work and you do not remember the current phase
|
|
28
|
-
- To see the progress of the build-feature pipeline
|
|
29
|
-
- To decide which skill to run next
|
|
30
|
-
|
|
31
|
-
## Usage
|
|
32
|
-
|
|
33
|
-
`/dev-flow`
|
|
34
|
-
|
|
35
|
-
## Process
|
|
36
|
-
|
|
37
|
-
### Step 1 — Read state
|
|
38
|
-
|
|
39
|
-
Read `SESSION.md` to determine:
|
|
40
|
-
|
|
41
|
-
- Whether there is a feature in progress
|
|
42
|
-
- Which pipeline phase it is in
|
|
43
|
-
- What has been completed and what remains
|
|
44
|
-
|
|
45
|
-
### Step 2 — Determine current phase
|
|
46
|
-
|
|
47
|
-
The pipeline phases are:
|
|
48
|
-
|
|
49
|
-
1. **Evaluation** (Advisor) — go/no-go
|
|
50
|
-
2. **Specification & Technical Approach** (Tech Lead) — tasks, acceptance criteria, implementation plan
|
|
51
|
-
3. **Implementation** (Developer) — code and tests
|
|
52
|
-
4. **Review** (Code Reviewer) — quality review
|
|
53
|
-
5. **QA** — functional validation
|
|
54
|
-
|
|
55
|
-
### Step 3 — Present flow state
|
|
56
|
-
|
|
57
|
-
```text
|
|
58
|
-
Dev Flow — [feature name]
|
|
59
|
-
|
|
60
|
-
[x] Phase 1 — Evaluation (completed)
|
|
61
|
-
[x] Phase 2 — Specification & Technical Approach (completed)
|
|
62
|
-
[ ] Phase 3 — Implementation (pending) <-- you are here
|
|
63
|
-
[ ] Phase 4 — Review
|
|
64
|
-
[ ] Phase 5 — QA
|
|
65
|
-
|
|
66
|
-
Next step: Run /build-feature to continue from Phase 3.
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
If there is no feature in progress, report that there is no active pipeline and suggest `/new-feature` or `/build-feature`.
|
|
70
|
-
|
|
71
|
-
## Example Session
|
|
72
|
-
|
|
73
|
-
```text
|
|
74
|
-
User: /dev-flow
|
|
75
|
-
|
|
76
|
-
Current pipeline: build-feature "add user preferences"
|
|
77
|
-
Phase: 3 of 5 — Implementation
|
|
78
|
-
Developer agent active.
|
|
79
|
-
|
|
80
|
-
Next: Phase 4 — Code Review
|
|
81
|
-
```
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"skill": "dev-flow",
|
|
3
|
-
"evals": [
|
|
4
|
-
{
|
|
5
|
-
"id": "df-has-steps",
|
|
6
|
-
"description": "Dev flow has read-state and present-flow steps",
|
|
7
|
-
"expectations": [
|
|
8
|
-
{ "text": "Has read-state step", "assertion": "step-exists:read-state" },
|
|
9
|
-
{ "text": "Has present-flow step", "assertion": "step-exists:present-flow" }
|
|
10
|
-
]
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"id": "df-all-system",
|
|
14
|
-
"description": "All steps are system role",
|
|
15
|
-
"expectations": [
|
|
16
|
-
{ "text": "read-state is system", "assertion": "step-role:read-state:system" },
|
|
17
|
-
{ "text": "present-flow is system", "assertion": "step-role:present-flow:system" }
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"id": "df-presentation-gate",
|
|
22
|
-
"description": "Present-flow step has a gate for user confirmation",
|
|
23
|
-
"expectations": [
|
|
24
|
-
{ "text": "present-flow has gate", "assertion": "gate-exists:present-flow" }
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"id": "df-dependencies",
|
|
29
|
-
"description": "Present-flow requires session state",
|
|
30
|
-
"expectations": [
|
|
31
|
-
{ "text": "present-flow requires session-state", "assertion": "step-requires:present-flow:session-state" },
|
|
32
|
-
{ "text": "present-flow requires current-phase", "assertion": "step-requires:present-flow:current-phase" }
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"skill": "dev-flow",
|
|
3
|
-
"matcherType": "keyword",
|
|
4
|
-
"description": "Shows current pipeline phase and what comes next",
|
|
5
|
-
"threshold": 0.3,
|
|
6
|
-
"tests": [
|
|
7
|
-
{ "prompt": "what phase am I in", "shouldTrigger": true },
|
|
8
|
-
{ "prompt": "show the current pipeline phase", "shouldTrigger": true },
|
|
9
|
-
{ "prompt": "what comes next in the flow", "shouldTrigger": true },
|
|
10
|
-
{ "prompt": "where did I leave off", "shouldTrigger": true, "keywordExpected": false },
|
|
11
|
-
{ "prompt": "create a pull request", "shouldTrigger": false },
|
|
12
|
-
{ "prompt": "review my code", "shouldTrigger": false },
|
|
13
|
-
{ "prompt": "fix this bug", "shouldTrigger": false },
|
|
14
|
-
{ "prompt": "run the tests", "shouldTrigger": false }
|
|
15
|
-
]
|
|
16
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: new-feature
|
|
3
|
-
description: "Creates branch and scaffold for a new feature"
|
|
4
|
-
user-invocable: true
|
|
5
|
-
workflow:
|
|
6
|
-
version: 1
|
|
7
|
-
steps:
|
|
8
|
-
- id: get-name
|
|
9
|
-
role: system
|
|
10
|
-
intent: "Obtain feature name from user input or prompt for it."
|
|
11
|
-
produces: [feature-name, feature-description]
|
|
12
|
-
gate: true
|
|
13
|
-
- id: create-branch
|
|
14
|
-
role: system
|
|
15
|
-
intent: "Create feature branch (simple checkout or worktree for parallel execution)."
|
|
16
|
-
commands: [git checkout -b]
|
|
17
|
-
requires: [feature-name]
|
|
18
|
-
produces: [branch-name]
|
|
19
|
-
- id: update-session
|
|
20
|
-
role: system
|
|
21
|
-
intent: "Update SESSION.md with new feature context, date, and state."
|
|
22
|
-
requires: [feature-name, feature-description, branch-name]
|
|
23
|
-
produces: [session-update]
|
|
24
|
-
gate: true
|
|
25
|
-
- id: create-issue
|
|
26
|
-
role: system
|
|
27
|
-
intent: "Optionally create GitHub Issue for the feature via gh CLI."
|
|
28
|
-
commands: [gh issue create]
|
|
29
|
-
requires: [feature-name, feature-description]
|
|
30
|
-
produces: [issue-url]
|
|
31
|
-
condition: user-wants-issue
|
|
32
|
-
- id: confirm
|
|
33
|
-
role: system
|
|
34
|
-
intent: "Confirm branch created, SESSION.md updated, issue created. Suggest /build-feature."
|
|
35
|
-
requires: [branch-name, session-update]
|
|
36
|
-
produces: [confirmation]
|
|
37
|
-
gate: true
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
# New Feature
|
|
41
|
-
|
|
42
|
-
Prepares the environment for working on a new feature: creates a branch, updates SESSION.md, and optionally creates a GitHub Issue.
|
|
43
|
-
|
|
44
|
-
## When to use
|
|
45
|
-
|
|
46
|
-
- When starting a new feature before writing code
|
|
47
|
-
- When you want to record the feature context in SESSION.md
|
|
48
|
-
|
|
49
|
-
## Usage
|
|
50
|
-
|
|
51
|
-
`/new-feature [feature-name]`
|
|
52
|
-
|
|
53
|
-
## Process
|
|
54
|
-
|
|
55
|
-
### Step 1 — Get name
|
|
56
|
-
|
|
57
|
-
If the user did not provide a name, ask for:
|
|
58
|
-
|
|
59
|
-
- Short name for the feature (will be used in the branch name)
|
|
60
|
-
- Brief description (1-2 sentences)
|
|
61
|
-
|
|
62
|
-
### Step 2 — Create branch with worktree isolation
|
|
63
|
-
|
|
64
|
-
When running in parallel with other agents, use git worktrees for isolation. When running standalone, a simple branch is sufficient.
|
|
65
|
-
|
|
66
|
-
**For parallel execution (multiple build-features at once):**
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
git worktree add .claude/worktrees/feature-[name] -b feature/[feature-name] develop
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
All subsequent operations should use `.claude/worktrees/feature-[name]` as the working directory.
|
|
73
|
-
|
|
74
|
-
**For standalone execution:**
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
git checkout -b feature/[feature-name]
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
If the branch already exists, ask whether to switch to it or create a new one.
|
|
81
|
-
|
|
82
|
-
**Cleanup:** At skill exit, if using worktrees, the caller is responsible for cleanup via `git worktree remove .claude/worktrees/feature-[name]` after the PR is merged.
|
|
83
|
-
|
|
84
|
-
### Step 3 — Update SESSION.md
|
|
85
|
-
|
|
86
|
-
Update SESSION.md with the new feature context:
|
|
87
|
-
|
|
88
|
-
- **Date:** current date
|
|
89
|
-
- **Task in progress:** feature name
|
|
90
|
-
- **State:** Feature started — pending implementation
|
|
91
|
-
|
|
92
|
-
## Example Session
|
|
93
|
-
|
|
94
|
-
```text
|
|
95
|
-
User: /new-feature user-preferences
|
|
96
|
-
|
|
97
|
-
Branch created: feature/user-preferences
|
|
98
|
-
SESSION.md updated with feature context.
|
|
99
|
-
GitHub Issue #42 created.
|
|
100
|
-
|
|
101
|
-
Next: Run /build-feature to implement.
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Step 4 — GitHub Issue (optional)
|
|
105
|
-
|
|
106
|
-
If the project has GitHub integration configured in PROJECT.md:
|
|
107
|
-
|
|
108
|
-
1. Ask whether to create a GitHub Issue for the feature
|
|
109
|
-
2. If accepted, create the issue with `gh issue create`
|
|
110
|
-
3. Record the issue URL in SESSION.md
|
|
111
|
-
|
|
112
|
-
### Step 5 — Confirm
|
|
113
|
-
|
|
114
|
-
Confirm to the user:
|
|
115
|
-
|
|
116
|
-
- Branch created: `feature/[name]`
|
|
117
|
-
- SESSION.md updated
|
|
118
|
-
- GitHub Issue created (if applicable)
|
|
119
|
-
- Suggest: "Run /build-feature to implement the full feature"
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"skill": "new-feature",
|
|
3
|
-
"evals": [
|
|
4
|
-
{
|
|
5
|
-
"id": "nf-has-core-steps",
|
|
6
|
-
"description": "New feature has name, branch, session, confirm steps",
|
|
7
|
-
"expectations": [
|
|
8
|
-
{ "text": "Has get-name step", "assertion": "step-exists:get-name" },
|
|
9
|
-
{ "text": "Has create-branch step", "assertion": "step-exists:create-branch" },
|
|
10
|
-
{ "text": "Has update-session step", "assertion": "step-exists:update-session" },
|
|
11
|
-
{ "text": "Has confirm step", "assertion": "step-exists:confirm" }
|
|
12
|
-
]
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"id": "nf-optional-issue",
|
|
16
|
-
"description": "GitHub issue creation step exists",
|
|
17
|
-
"expectations": [
|
|
18
|
-
{ "text": "Has create-issue step", "assertion": "step-exists:create-issue" }
|
|
19
|
-
]
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"id": "nf-gates",
|
|
23
|
-
"description": "Gates at name input, session update, and confirmation",
|
|
24
|
-
"expectations": [
|
|
25
|
-
{ "text": "get-name has gate", "assertion": "gate-exists:get-name" },
|
|
26
|
-
{ "text": "update-session has gate", "assertion": "gate-exists:update-session" },
|
|
27
|
-
{ "text": "confirm has gate", "assertion": "gate-exists:confirm" }
|
|
28
|
-
]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"id": "nf-all-system",
|
|
32
|
-
"description": "All steps are system role",
|
|
33
|
-
"expectations": [
|
|
34
|
-
{ "text": "get-name is system", "assertion": "step-role:get-name:system" },
|
|
35
|
-
{ "text": "create-branch is system", "assertion": "step-role:create-branch:system" },
|
|
36
|
-
{ "text": "update-session is system", "assertion": "step-role:update-session:system" },
|
|
37
|
-
{ "text": "confirm is system", "assertion": "step-role:confirm:system" }
|
|
38
|
-
]
|
|
39
|
-
}
|
|
40
|
-
]
|
|
41
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"skill": "new-feature",
|
|
3
|
-
"matcherType": "keyword",
|
|
4
|
-
"description": "Creates branch and scaffold for a new feature",
|
|
5
|
-
"threshold": 0.3,
|
|
6
|
-
"tests": [
|
|
7
|
-
{ "prompt": "create a new feature branch", "shouldTrigger": true },
|
|
8
|
-
{ "prompt": "scaffold a new feature", "shouldTrigger": true },
|
|
9
|
-
{ "prompt": "start a new feature called user-auth", "shouldTrigger": true },
|
|
10
|
-
{ "prompt": "prepare the branch for a new feature", "shouldTrigger": true },
|
|
11
|
-
{ "prompt": "review my code", "shouldTrigger": false },
|
|
12
|
-
{ "prompt": "create a pull request", "shouldTrigger": false },
|
|
13
|
-
{ "prompt": "debug this bug", "shouldTrigger": false },
|
|
14
|
-
{ "prompt": "save my session", "shouldTrigger": false }
|
|
15
|
-
]
|
|
16
|
-
}
|