@specforge/mcp 3.0.7 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autopilot/agents/agent-runner.d.ts.map +1 -1
- package/dist/autopilot/agents/agent-runner.js +7 -0
- package/dist/autopilot/agents/agent-runner.js.map +1 -1
- package/dist/autopilot/api/autopilot-api-client.d.ts +5 -4
- package/dist/autopilot/api/autopilot-api-client.d.ts.map +1 -1
- package/dist/autopilot/api/autopilot-api-client.js +21 -26
- package/dist/autopilot/api/autopilot-api-client.js.map +1 -1
- package/dist/autopilot/cli/run.d.ts.map +1 -1
- package/dist/autopilot/cli/run.js +28 -0
- package/dist/autopilot/cli/run.js.map +1 -1
- package/dist/autopilot/core/dependency-resolver.d.ts +10 -1
- package/dist/autopilot/core/dependency-resolver.d.ts.map +1 -1
- package/dist/autopilot/core/dependency-resolver.js +27 -1
- package/dist/autopilot/core/dependency-resolver.js.map +1 -1
- package/dist/autopilot/core/dispatcher.d.ts +26 -0
- package/dist/autopilot/core/dispatcher.d.ts.map +1 -1
- package/dist/autopilot/core/dispatcher.js +116 -6
- package/dist/autopilot/core/dispatcher.js.map +1 -1
- package/dist/autopilot/readiness/aggregation.d.ts +56 -0
- package/dist/autopilot/readiness/aggregation.d.ts.map +1 -0
- package/dist/autopilot/readiness/aggregation.js +94 -0
- package/dist/autopilot/readiness/aggregation.js.map +1 -0
- package/dist/autopilot/readiness/config.d.ts +15 -0
- package/dist/autopilot/readiness/config.d.ts.map +1 -0
- package/dist/autopilot/readiness/config.js +76 -0
- package/dist/autopilot/readiness/config.js.map +1 -0
- package/dist/autopilot/readiness/index.d.ts +16 -0
- package/dist/autopilot/readiness/index.d.ts.map +1 -0
- package/dist/autopilot/readiness/index.js +11 -0
- package/dist/autopilot/readiness/index.js.map +1 -0
- package/dist/autopilot/readiness/post-scoring.d.ts +28 -0
- package/dist/autopilot/readiness/post-scoring.d.ts.map +1 -0
- package/dist/autopilot/readiness/post-scoring.js +41 -0
- package/dist/autopilot/readiness/post-scoring.js.map +1 -0
- package/dist/autopilot/readiness/preflight.d.ts +36 -0
- package/dist/autopilot/readiness/preflight.d.ts.map +1 -0
- package/dist/autopilot/readiness/preflight.js +93 -0
- package/dist/autopilot/readiness/preflight.js.map +1 -0
- package/dist/autopilot/readiness/prompt-section.d.ts +19 -0
- package/dist/autopilot/readiness/prompt-section.d.ts.map +1 -0
- package/dist/autopilot/readiness/prompt-section.js +33 -0
- package/dist/autopilot/readiness/prompt-section.js.map +1 -0
- package/dist/autopilot/readiness/types.d.ts +25 -0
- package/dist/autopilot/readiness/types.d.ts.map +1 -0
- package/dist/autopilot/readiness/types.js +8 -0
- package/dist/autopilot/readiness/types.js.map +1 -0
- package/dist/autopilot/sync/sync-manager.d.ts.map +1 -1
- package/dist/autopilot/sync/sync-manager.js +2 -1
- package/dist/autopilot/sync/sync-manager.js.map +1 -1
- package/dist/autopilot/types.d.ts +28 -0
- package/dist/autopilot/types.d.ts.map +1 -1
- package/dist/autopilot/types.js.map +1 -1
- package/dist/cli/commands/index.d.ts +5 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +5 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +184 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.types.d.ts +37 -0
- package/dist/cli/commands/init.types.d.ts.map +1 -1
- package/dist/cli/commands/init.types.js +18 -0
- package/dist/cli/commands/init.types.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +18 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +154 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/plan.types.d.ts +60 -0
- package/dist/cli/commands/plan.types.d.ts.map +1 -0
- package/dist/cli/commands/plan.types.js +8 -0
- package/dist/cli/commands/plan.types.js.map +1 -0
- package/dist/cli/commands/review-implementation.d.ts +16 -0
- package/dist/cli/commands/review-implementation.d.ts.map +1 -0
- package/dist/cli/commands/review-implementation.js +226 -0
- package/dist/cli/commands/review-implementation.js.map +1 -0
- package/dist/cli/commands/review-planning.d.ts +15 -0
- package/dist/cli/commands/review-planning.d.ts.map +1 -0
- package/dist/cli/commands/review-planning.js +177 -0
- package/dist/cli/commands/review-planning.js.map +1 -0
- package/dist/cli/commands/score/display.d.ts +20 -0
- package/dist/cli/commands/score/display.d.ts.map +1 -0
- package/dist/cli/commands/score/display.js +111 -0
- package/dist/cli/commands/score/display.js.map +1 -0
- package/dist/cli/commands/score/index.d.ts +9 -0
- package/dist/cli/commands/score/index.d.ts.map +1 -0
- package/dist/cli/commands/score/index.js +12 -0
- package/dist/cli/commands/score/index.js.map +1 -0
- package/dist/cli/commands/score/score.d.ts +17 -0
- package/dist/cli/commands/score/score.d.ts.map +1 -0
- package/dist/cli/commands/score/score.js +144 -0
- package/dist/cli/commands/score/score.js.map +1 -0
- package/dist/cli/commands/score/types.d.ts +79 -0
- package/dist/cli/commands/score/types.d.ts.map +1 -0
- package/dist/cli/commands/score/types.js +51 -0
- package/dist/cli/commands/score/types.js.map +1 -0
- package/dist/cli/commands/spec-activate.d.ts +29 -0
- package/dist/cli/commands/spec-activate.d.ts.map +1 -0
- package/dist/cli/commands/spec-activate.js +155 -0
- package/dist/cli/commands/spec-activate.js.map +1 -0
- package/dist/cli/commands/spec-activate.types.d.ts +24 -0
- package/dist/cli/commands/spec-activate.types.d.ts.map +1 -0
- package/dist/cli/commands/spec-activate.types.js +8 -0
- package/dist/cli/commands/spec-activate.types.js.map +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +89 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/status.types.d.ts +2 -0
- package/dist/cli/commands/status.types.d.ts.map +1 -1
- package/dist/cli/commands/status.types.js.map +1 -1
- package/dist/cli/config/agent-teams.types.d.ts +194 -0
- package/dist/cli/config/agent-teams.types.d.ts.map +1 -0
- package/dist/cli/config/agent-teams.types.js +36 -0
- package/dist/cli/config/agent-teams.types.js.map +1 -0
- package/dist/cli/config/index.d.ts +2 -0
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -0
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/config/loader.d.ts +36 -2
- package/dist/cli/config/loader.d.ts.map +1 -1
- package/dist/cli/config/loader.js +65 -0
- package/dist/cli/config/loader.js.map +1 -1
- package/dist/cli/config/validation.d.ts +69 -0
- package/dist/cli/config/validation.d.ts.map +1 -0
- package/dist/cli/config/validation.js +295 -0
- package/dist/cli/config/validation.js.map +1 -0
- package/dist/cli/config/writer.d.ts +39 -0
- package/dist/cli/config/writer.d.ts.map +1 -1
- package/dist/cli/config/writer.js +58 -0
- package/dist/cli/config/writer.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +10 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +3 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/monorepo-detector.d.ts +31 -0
- package/dist/lib/monorepo-detector.d.ts.map +1 -0
- package/dist/lib/monorepo-detector.js +271 -0
- package/dist/lib/monorepo-detector.js.map +1 -0
- package/dist/lib/prompt-generator.d.ts +65 -0
- package/dist/lib/prompt-generator.d.ts.map +1 -0
- package/dist/lib/prompt-generator.js +174 -0
- package/dist/lib/prompt-generator.js.map +1 -0
- package/dist/lib/strategy-analyzer.d.ts +59 -0
- package/dist/lib/strategy-analyzer.d.ts.map +1 -0
- package/dist/lib/strategy-analyzer.js +137 -0
- package/dist/lib/strategy-analyzer.js.map +1 -0
- package/dist/tools/core/context-helper.d.ts +22 -0
- package/dist/tools/core/context-helper.d.ts.map +1 -1
- package/dist/tools/core/context-helper.js +37 -1
- package/dist/tools/core/context-helper.js.map +1 -1
- package/dist/tools/core/workspace-files.d.ts +49 -0
- package/dist/tools/core/workspace-files.d.ts.map +1 -0
- package/dist/tools/core/workspace-files.js +259 -0
- package/dist/tools/core/workspace-files.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +147 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +3 -2
- package/src/cli/templates/agents/content/core/sfag-implementer.ts +113 -0
- package/src/cli/templates/agents/content/core/sfag-orchestrator.ts +107 -0
- package/src/cli/templates/agents/content/core/sfag-spec-creator.ts +126 -0
- package/src/cli/templates/agents/content/core/sfag-ticket-implementer.ts +132 -0
- package/src/cli/templates/agents/content/research/sfag-package-researcher.ts +153 -0
- package/src/cli/templates/agents/content/task-type/sfag-api-implementer.ts +132 -0
- package/src/cli/templates/agents/content/task-type/sfag-docs-writer.ts +183 -0
- package/src/cli/templates/agents/content/task-type/sfag-frontend-builder.ts +141 -0
- package/src/cli/templates/agents/content/task-type/sfag-infra-architect.ts +149 -0
- package/src/cli/templates/agents/content/task-type/sfag-schema-designer.ts +132 -0
- package/src/cli/templates/agents/content/task-type/sfag-test-writer.ts +171 -0
- package/src/cli/templates/agents/index.ts +74 -0
- package/src/cli/templates/commands.ts +179 -0
- package/src/cli/templates/content/sf-autonomous.ts +78 -0
- package/src/cli/templates/content/sf-blockers.ts +68 -0
- package/src/cli/templates/content/sf-commit.ts +78 -0
- package/src/cli/templates/content/sf-context.ts +64 -0
- package/src/cli/templates/content/sf-create-epics.ts +129 -0
- package/src/cli/templates/content/sf-create-spec.ts +136 -0
- package/src/cli/templates/content/sf-create-tickets.ts +148 -0
- package/src/cli/templates/content/sf-epic.ts +69 -0
- package/src/cli/templates/content/sf-help.ts +61 -0
- package/src/cli/templates/content/sf-import.ts +88 -0
- package/src/cli/templates/content/sf-init.ts +61 -0
- package/src/cli/templates/content/sf-next.ts +67 -0
- package/src/cli/templates/content/sf-reset.ts +78 -0
- package/src/cli/templates/content/sf-review.ts +67 -0
- package/src/cli/templates/content/sf-search.ts +64 -0
- package/src/cli/templates/content/sf-status.ts +67 -0
- package/src/cli/templates/content/sf-ticket.ts +76 -0
- package/src/cli/templates/content/sf-validate.ts +78 -0
- package/src/cli/templates/index.ts +16 -0
- package/src/cli/templates/skills/specforge-conventions.md +109 -0
- package/src/cli/templates/skills/specforge-orchestrator.md +401 -0
- package/src/cli/templates/skills/specforge-validator.md +122 -0
- package/src/cli/templates/skills/specforge-worker.md +378 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SFAG-Test-Writer Agent Template
|
|
3
|
+
*
|
|
4
|
+
* Specialized agent for writing comprehensive tests.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { AgentTemplate } from '../../../../commands/scaffold/agent-types.js';
|
|
8
|
+
|
|
9
|
+
export const SFAG_TEST_WRITER: AgentTemplate = {
|
|
10
|
+
name: 'sfag-test-writer',
|
|
11
|
+
description: 'Unit, integration, e2e tests',
|
|
12
|
+
triggerDescription: `Use this agent for writing unit tests, integration tests, and end-to-end tests.
|
|
13
|
+
|
|
14
|
+
<example>
|
|
15
|
+
Context: User implemented a new feature and needs tests
|
|
16
|
+
user: "Write tests for the new authentication service"
|
|
17
|
+
assistant: "I'll use the sfag-test-writer agent to write comprehensive tests for the authentication service."
|
|
18
|
+
</example>
|
|
19
|
+
|
|
20
|
+
<example>
|
|
21
|
+
Context: User wants to add e2e tests
|
|
22
|
+
user: "Add Playwright tests for the checkout flow"
|
|
23
|
+
assistant: "Let me use the sfag-test-writer agent to create e2e tests for the checkout flow."
|
|
24
|
+
</example>`,
|
|
25
|
+
model: 'haiku',
|
|
26
|
+
color: 'yellow',
|
|
27
|
+
category: 'TaskType',
|
|
28
|
+
content: `# SpecForge Test Writer Agent
|
|
29
|
+
|
|
30
|
+
You are the SpecForge Test Writer - an expert at writing comprehensive, maintainable tests.
|
|
31
|
+
|
|
32
|
+
## Role
|
|
33
|
+
|
|
34
|
+
Your primary responsibilities:
|
|
35
|
+
1. **Analyze** - Understand what needs to be tested
|
|
36
|
+
2. **Design** - Plan test cases for comprehensive coverage
|
|
37
|
+
3. **Write** - Create clear, maintainable tests
|
|
38
|
+
4. **Verify** - Ensure tests are reliable and not flaky
|
|
39
|
+
5. **Document** - Write clear test descriptions
|
|
40
|
+
|
|
41
|
+
## Testing Principles
|
|
42
|
+
|
|
43
|
+
### Test Pyramid
|
|
44
|
+
- Many unit tests (fast, isolated)
|
|
45
|
+
- Some integration tests (components together)
|
|
46
|
+
- Few e2e tests (full system)
|
|
47
|
+
|
|
48
|
+
### Good Test Properties
|
|
49
|
+
- **Fast** - Tests should run quickly
|
|
50
|
+
- **Isolated** - No dependencies between tests
|
|
51
|
+
- **Repeatable** - Same result every time
|
|
52
|
+
- **Self-validating** - Pass or fail, no manual checking
|
|
53
|
+
- **Timely** - Written close to the code
|
|
54
|
+
|
|
55
|
+
## Unit Tests
|
|
56
|
+
|
|
57
|
+
\`\`\`typescript
|
|
58
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
59
|
+
import { calculateTotal } from './cart';
|
|
60
|
+
|
|
61
|
+
describe('calculateTotal', () => {
|
|
62
|
+
it('returns 0 for empty cart', () => {
|
|
63
|
+
expect(calculateTotal([])).toBe(0);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('sums item prices correctly', () => {
|
|
67
|
+
const items = [
|
|
68
|
+
{ price: 10, quantity: 2 },
|
|
69
|
+
{ price: 5, quantity: 1 },
|
|
70
|
+
];
|
|
71
|
+
expect(calculateTotal(items)).toBe(25);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('applies discount when provided', () => {
|
|
75
|
+
const items = [{ price: 100, quantity: 1 }];
|
|
76
|
+
expect(calculateTotal(items, 0.1)).toBe(90);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
## Integration Tests
|
|
82
|
+
|
|
83
|
+
\`\`\`typescript
|
|
84
|
+
describe('UserService', () => {
|
|
85
|
+
let db: Database;
|
|
86
|
+
let userService: UserService;
|
|
87
|
+
|
|
88
|
+
beforeEach(async () => {
|
|
89
|
+
db = await createTestDatabase();
|
|
90
|
+
userService = new UserService(db);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
afterEach(async () => {
|
|
94
|
+
await db.close();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('creates user and stores in database', async () => {
|
|
98
|
+
const user = await userService.create({
|
|
99
|
+
email: 'test@example.com',
|
|
100
|
+
name: 'Test User',
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const stored = await db.users.findById(user.id);
|
|
104
|
+
expect(stored).toMatchObject({
|
|
105
|
+
email: 'test@example.com',
|
|
106
|
+
name: 'Test User',
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
\`\`\`
|
|
111
|
+
|
|
112
|
+
## E2E Tests
|
|
113
|
+
|
|
114
|
+
\`\`\`typescript
|
|
115
|
+
import { test, expect } from '@playwright/test';
|
|
116
|
+
|
|
117
|
+
test('user can complete checkout', async ({ page }) => {
|
|
118
|
+
await page.goto('/products');
|
|
119
|
+
|
|
120
|
+
// Add item to cart
|
|
121
|
+
await page.click('[data-testid="add-to-cart"]');
|
|
122
|
+
|
|
123
|
+
// Go to checkout
|
|
124
|
+
await page.click('[data-testid="checkout-button"]');
|
|
125
|
+
|
|
126
|
+
// Fill shipping info
|
|
127
|
+
await page.fill('[name="address"]', '123 Test St');
|
|
128
|
+
await page.fill('[name="city"]', 'Test City');
|
|
129
|
+
|
|
130
|
+
// Complete purchase
|
|
131
|
+
await page.click('[data-testid="place-order"]');
|
|
132
|
+
|
|
133
|
+
// Verify success
|
|
134
|
+
await expect(page.locator('.order-confirmation')).toBeVisible();
|
|
135
|
+
});
|
|
136
|
+
\`\`\`
|
|
137
|
+
|
|
138
|
+
## Mocking Strategies
|
|
139
|
+
|
|
140
|
+
\`\`\`typescript
|
|
141
|
+
// Mock functions
|
|
142
|
+
const mockFetch = vi.fn().mockResolvedValue({ data: [] });
|
|
143
|
+
|
|
144
|
+
// Mock modules
|
|
145
|
+
vi.mock('./api', () => ({
|
|
146
|
+
fetchUsers: vi.fn().mockResolvedValue([]),
|
|
147
|
+
}));
|
|
148
|
+
|
|
149
|
+
// Spy on methods
|
|
150
|
+
const spy = vi.spyOn(service, 'send');
|
|
151
|
+
\`\`\`
|
|
152
|
+
|
|
153
|
+
## Test Coverage
|
|
154
|
+
|
|
155
|
+
Focus on:
|
|
156
|
+
- Happy path (normal usage)
|
|
157
|
+
- Edge cases (boundaries, empty, null)
|
|
158
|
+
- Error cases (invalid input, failures)
|
|
159
|
+
- Security cases (auth, permissions)
|
|
160
|
+
|
|
161
|
+
## Guidelines
|
|
162
|
+
|
|
163
|
+
- Write descriptive test names
|
|
164
|
+
- One assertion per test (when practical)
|
|
165
|
+
- Test behavior, not implementation
|
|
166
|
+
- Don't test third-party code
|
|
167
|
+
- Keep tests DRY but readable
|
|
168
|
+
- Avoid flaky tests
|
|
169
|
+
- Run tests before committing
|
|
170
|
+
`,
|
|
171
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Templates Module
|
|
3
|
+
*
|
|
4
|
+
* Defines all SpecForge agent templates for scaffolding to AI CLI tools.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { AgentTemplate, AgentCategory } from '../../commands/scaffold/agent-types.js';
|
|
8
|
+
|
|
9
|
+
// Import core agents
|
|
10
|
+
import { SFAG_ORCHESTRATOR } from './content/core/sfag-orchestrator.js';
|
|
11
|
+
import { SFAG_IMPLEMENTER } from './content/core/sfag-implementer.js';
|
|
12
|
+
import { SFAG_SPEC_CREATOR } from './content/core/sfag-spec-creator.js';
|
|
13
|
+
import { SFAG_TICKET_IMPLEMENTER } from './content/core/sfag-ticket-implementer.js';
|
|
14
|
+
|
|
15
|
+
// Import task-type agents
|
|
16
|
+
import { SFAG_API_IMPLEMENTER } from './content/task-type/sfag-api-implementer.js';
|
|
17
|
+
import { SFAG_SCHEMA_DESIGNER } from './content/task-type/sfag-schema-designer.js';
|
|
18
|
+
import { SFAG_FRONTEND_BUILDER } from './content/task-type/sfag-frontend-builder.js';
|
|
19
|
+
import { SFAG_INFRA_ARCHITECT } from './content/task-type/sfag-infra-architect.js';
|
|
20
|
+
import { SFAG_TEST_WRITER } from './content/task-type/sfag-test-writer.js';
|
|
21
|
+
import { SFAG_DOCS_WRITER } from './content/task-type/sfag-docs-writer.js';
|
|
22
|
+
|
|
23
|
+
// Import research agents
|
|
24
|
+
import { SFAG_PACKAGE_RESEARCHER } from './content/research/sfag-package-researcher.js';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* All agent templates
|
|
28
|
+
*/
|
|
29
|
+
const AGENT_TEMPLATES: AgentTemplate[] = [
|
|
30
|
+
// Core agents
|
|
31
|
+
SFAG_ORCHESTRATOR,
|
|
32
|
+
SFAG_IMPLEMENTER,
|
|
33
|
+
SFAG_SPEC_CREATOR,
|
|
34
|
+
SFAG_TICKET_IMPLEMENTER,
|
|
35
|
+
|
|
36
|
+
// Task-type agents
|
|
37
|
+
SFAG_API_IMPLEMENTER,
|
|
38
|
+
SFAG_SCHEMA_DESIGNER,
|
|
39
|
+
SFAG_FRONTEND_BUILDER,
|
|
40
|
+
SFAG_INFRA_ARCHITECT,
|
|
41
|
+
SFAG_TEST_WRITER,
|
|
42
|
+
SFAG_DOCS_WRITER,
|
|
43
|
+
|
|
44
|
+
// Research agents
|
|
45
|
+
SFAG_PACKAGE_RESEARCHER,
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get all agent templates
|
|
50
|
+
*/
|
|
51
|
+
export function getAgentTemplates(): AgentTemplate[] {
|
|
52
|
+
return AGENT_TEMPLATES;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get a specific agent template by name
|
|
57
|
+
*/
|
|
58
|
+
export function getAgentTemplate(name: string): AgentTemplate | undefined {
|
|
59
|
+
return AGENT_TEMPLATES.find(t => t.name === name);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get agent templates by category
|
|
64
|
+
*/
|
|
65
|
+
export function getAgentsByCategory(category: AgentCategory): AgentTemplate[] {
|
|
66
|
+
return AGENT_TEMPLATES.filter(t => t.category === category);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get all agent template names
|
|
71
|
+
*/
|
|
72
|
+
export function getAgentNames(): string[] {
|
|
73
|
+
return AGENT_TEMPLATES.map(t => t.name);
|
|
74
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Templates Module
|
|
3
|
+
*
|
|
4
|
+
* Defines all SpecForge slash commands with their full markdown content
|
|
5
|
+
* for scaffolding to AI CLI tools.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { CommandTemplate } from '../commands/scaffold/types.js';
|
|
9
|
+
|
|
10
|
+
// Import all command content
|
|
11
|
+
import { SF_INIT_CONTENT } from './content/sf-init.js';
|
|
12
|
+
import { SF_STATUS_CONTENT } from './content/sf-status.js';
|
|
13
|
+
import { SF_NEXT_CONTENT } from './content/sf-next.js';
|
|
14
|
+
import { SF_TICKET_IMPLEMENTATION_CONTENT } from './content/sf-ticket.js';
|
|
15
|
+
import { SF_RUN_AUTONOMOUS_CONTENT } from './content/sf-autonomous.js';
|
|
16
|
+
import { SF_REVIEW_CONTENT } from './content/sf-review.js';
|
|
17
|
+
import { SF_VALIDATE_CONTENT } from './content/sf-validate.js';
|
|
18
|
+
import { SF_RESET_CONTENT } from './content/sf-reset.js';
|
|
19
|
+
import { SF_ANALYZE_BLOCKERS_CONTENT } from './content/sf-blockers.js';
|
|
20
|
+
import { SF_IMPORT_PLAN_CONTENT } from './content/sf-import.js';
|
|
21
|
+
import { SF_CREATE_SPEC_CONTENT } from './content/sf-create-spec.js';
|
|
22
|
+
import { SF_CREATE_EPICS_CONTENT } from './content/sf-create-epics.js';
|
|
23
|
+
import { SF_CREATE_TICKETS_CONTENT } from './content/sf-create-tickets.js';
|
|
24
|
+
import { SF_CONTEXT_CONTENT } from './content/sf-context.js';
|
|
25
|
+
import { SF_SEARCH_CONTENT } from './content/sf-search.js';
|
|
26
|
+
import { SF_EPIC_CONTENT } from './content/sf-epic.js';
|
|
27
|
+
import { SF_COMMIT_CONTENT } from './content/sf-commit.js';
|
|
28
|
+
import { SF_HELP_CONTENT } from './content/sf-help.js';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get all command templates
|
|
32
|
+
*/
|
|
33
|
+
export function getCommandTemplates(): CommandTemplate[] {
|
|
34
|
+
return [
|
|
35
|
+
// Setup
|
|
36
|
+
{
|
|
37
|
+
name: 'sf-init',
|
|
38
|
+
description: 'Initialize ticket system for a specification',
|
|
39
|
+
argumentHint: '[specification-id]',
|
|
40
|
+
content: SF_INIT_CONTENT,
|
|
41
|
+
category: 'Setup',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'sf-context',
|
|
45
|
+
description: 'View or switch working context',
|
|
46
|
+
argumentHint: '[project-or-spec-id]',
|
|
47
|
+
content: SF_CONTEXT_CONTENT,
|
|
48
|
+
category: 'Setup',
|
|
49
|
+
},
|
|
50
|
+
// Status
|
|
51
|
+
{
|
|
52
|
+
name: 'sf-status',
|
|
53
|
+
description: 'Display implementation status with consolidated tools',
|
|
54
|
+
argumentHint: '[specification-id]',
|
|
55
|
+
content: SF_STATUS_CONTENT,
|
|
56
|
+
category: 'Status',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'sf-validate',
|
|
60
|
+
description: 'Validate ticket system health',
|
|
61
|
+
argumentHint: '[specification-id]',
|
|
62
|
+
content: SF_VALIDATE_CONTENT,
|
|
63
|
+
category: 'Status',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'sf-analyze-blockers',
|
|
67
|
+
description: 'Analyze blockers and dependency bottlenecks',
|
|
68
|
+
content: SF_ANALYZE_BLOCKERS_CONTENT,
|
|
69
|
+
category: 'Status',
|
|
70
|
+
},
|
|
71
|
+
// Implementation
|
|
72
|
+
{
|
|
73
|
+
name: 'sf-next',
|
|
74
|
+
description: 'Quick start the next ready ticket',
|
|
75
|
+
content: SF_NEXT_CONTENT,
|
|
76
|
+
category: 'Implementation',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'sf-ticket-implementation',
|
|
80
|
+
description: 'Implement a ticket with streamlined workflow',
|
|
81
|
+
argumentHint: '[ticket-id]',
|
|
82
|
+
content: SF_TICKET_IMPLEMENTATION_CONTENT,
|
|
83
|
+
category: 'Implementation',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'sf-run-autonomous',
|
|
87
|
+
description: 'Run autonomous implementation for multiple tickets',
|
|
88
|
+
argumentHint: '[max-tickets]',
|
|
89
|
+
content: SF_RUN_AUTONOMOUS_CONTENT,
|
|
90
|
+
category: 'Implementation',
|
|
91
|
+
},
|
|
92
|
+
// Planning
|
|
93
|
+
{
|
|
94
|
+
name: 'sf-import-plan',
|
|
95
|
+
description: 'Transform a plan into a complete SpecForge specification',
|
|
96
|
+
argumentHint: '<plan-file-path>',
|
|
97
|
+
content: SF_IMPORT_PLAN_CONTENT,
|
|
98
|
+
category: 'Planning',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'sf-create-spec',
|
|
102
|
+
description: 'Create a SpecForge specification with patterns',
|
|
103
|
+
argumentHint: '<plan-file-path>',
|
|
104
|
+
content: SF_CREATE_SPEC_CONTENT,
|
|
105
|
+
category: 'Planning',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'sf-create-epics',
|
|
109
|
+
description: 'Create epics with epic-level patterns',
|
|
110
|
+
argumentHint: '<specification-id>',
|
|
111
|
+
content: SF_CREATE_EPICS_CONTENT,
|
|
112
|
+
category: 'Planning',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'sf-create-tickets',
|
|
116
|
+
description: 'Create detailed tickets with full implementation context',
|
|
117
|
+
argumentHint: '<epic-id>',
|
|
118
|
+
content: SF_CREATE_TICKETS_CONTENT,
|
|
119
|
+
category: 'Planning',
|
|
120
|
+
},
|
|
121
|
+
// Review
|
|
122
|
+
{
|
|
123
|
+
name: 'sf-review',
|
|
124
|
+
description: 'Review accomplishments and progress analysis',
|
|
125
|
+
argumentHint: '[specification-id]',
|
|
126
|
+
content: SF_REVIEW_CONTENT,
|
|
127
|
+
category: 'Review',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'sf-search',
|
|
131
|
+
description: 'Search tickets by text, tags, or filters',
|
|
132
|
+
argumentHint: '<query>',
|
|
133
|
+
content: SF_SEARCH_CONTENT,
|
|
134
|
+
category: 'Review',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'sf-epic',
|
|
138
|
+
description: 'View epic details and progress',
|
|
139
|
+
argumentHint: '<epic-id>',
|
|
140
|
+
content: SF_EPIC_CONTENT,
|
|
141
|
+
category: 'Review',
|
|
142
|
+
},
|
|
143
|
+
// Utilities
|
|
144
|
+
{
|
|
145
|
+
name: 'sf-reset',
|
|
146
|
+
description: 'Reset ticket statuses with dependency awareness',
|
|
147
|
+
argumentHint: '[specification-id]',
|
|
148
|
+
content: SF_RESET_CONTENT,
|
|
149
|
+
category: 'Utilities',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'sf-commit',
|
|
153
|
+
description: 'Commit changes with SpecForge ticket metadata',
|
|
154
|
+
argumentHint: '[ticket-id]',
|
|
155
|
+
content: SF_COMMIT_CONTENT,
|
|
156
|
+
category: 'Utilities',
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'sf-help',
|
|
160
|
+
description: 'Quick reference for all SpecForge commands',
|
|
161
|
+
content: SF_HELP_CONTENT,
|
|
162
|
+
category: 'Utilities',
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get a specific command template by name
|
|
169
|
+
*/
|
|
170
|
+
export function getCommandTemplate(name: string): CommandTemplate | undefined {
|
|
171
|
+
return getCommandTemplates().find(t => t.name === name);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get command templates by category
|
|
176
|
+
*/
|
|
177
|
+
export function getCommandsByCategory(category: string): CommandTemplate[] {
|
|
178
|
+
return getCommandTemplates().filter(t => t.category === category);
|
|
179
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SF-Run-Autonomous Command Template
|
|
3
|
+
*
|
|
4
|
+
* Template for running autonomous implementation for multiple tickets.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const SF_RUN_AUTONOMOUS_CONTENT = `# Run Autonomous Implementation (SpecForge)
|
|
8
|
+
|
|
9
|
+
Execute autonomous batch implementation of ready tickets.
|
|
10
|
+
|
|
11
|
+
## Arguments
|
|
12
|
+
- \`$ARGUMENTS\` - Optional: Maximum number of tickets to implement (default: 5)
|
|
13
|
+
|
|
14
|
+
## Task
|
|
15
|
+
|
|
16
|
+
### 1. Get Ready Tickets
|
|
17
|
+
|
|
18
|
+
**MCP Calls:**
|
|
19
|
+
\`\`\`typescript
|
|
20
|
+
get_working_context()
|
|
21
|
+
list_tickets({
|
|
22
|
+
specificationId,
|
|
23
|
+
status: 'ready',
|
|
24
|
+
sortBy: 'priority'
|
|
25
|
+
})
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
### 2. For Each Ticket (up to max)
|
|
29
|
+
|
|
30
|
+
**MCP Calls:**
|
|
31
|
+
\`\`\`typescript
|
|
32
|
+
// Set context
|
|
33
|
+
set_working_context({ ticketId: ticket.id })
|
|
34
|
+
|
|
35
|
+
// Update status
|
|
36
|
+
update_ticket({
|
|
37
|
+
ticketId: ticket.id,
|
|
38
|
+
status: 'in_progress'
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// Get full details
|
|
42
|
+
get_ticket(ticket.id)
|
|
43
|
+
|
|
44
|
+
// Implement ticket
|
|
45
|
+
// ... implementation logic ...
|
|
46
|
+
|
|
47
|
+
// Mark complete
|
|
48
|
+
update_ticket({
|
|
49
|
+
ticketId: ticket.id,
|
|
50
|
+
status: 'done'
|
|
51
|
+
})
|
|
52
|
+
\`\`\`
|
|
53
|
+
|
|
54
|
+
### 3. Display Summary
|
|
55
|
+
|
|
56
|
+
**Output:**
|
|
57
|
+
\`\`\`
|
|
58
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
59
|
+
AUTONOMOUS IMPLEMENTATION COMPLETE
|
|
60
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
61
|
+
Completed: {completedCount}/{attemptedCount}
|
|
62
|
+
Duration: {duration}
|
|
63
|
+
|
|
64
|
+
COMPLETED TICKETS
|
|
65
|
+
─────────────────────────────────────────────────────────────────
|
|
66
|
+
✓ E{n}-T{m} │ {title}
|
|
67
|
+
|
|
68
|
+
FAILED TICKETS
|
|
69
|
+
─────────────────────────────────────────────────────────────────
|
|
70
|
+
✗ E{n}-T{m} │ {title} │ {reason}
|
|
71
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
72
|
+
\`\`\`
|
|
73
|
+
|
|
74
|
+
## Notes
|
|
75
|
+
- Implements tickets in priority order
|
|
76
|
+
- Stops on errors or when max reached
|
|
77
|
+
- Use /sf-review to see detailed results
|
|
78
|
+
`;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SF-Analyze-Blockers Command Template
|
|
3
|
+
*
|
|
4
|
+
* Template for analyzing blockers and dependency bottlenecks.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const SF_ANALYZE_BLOCKERS_CONTENT = `# Analyze Blockers (SpecForge)
|
|
8
|
+
|
|
9
|
+
Analyze dependency bottlenecks and identify critical path tickets.
|
|
10
|
+
|
|
11
|
+
## Task
|
|
12
|
+
|
|
13
|
+
### 1. Get Implementation Data
|
|
14
|
+
|
|
15
|
+
**MCP Calls:**
|
|
16
|
+
\`\`\`typescript
|
|
17
|
+
get_working_context()
|
|
18
|
+
get_specification(specificationId)
|
|
19
|
+
list_epics({ specificationId })
|
|
20
|
+
list_tickets({ specificationId })
|
|
21
|
+
\`\`\`
|
|
22
|
+
|
|
23
|
+
### 2. Analyze Dependencies
|
|
24
|
+
|
|
25
|
+
**Logic:**
|
|
26
|
+
- Build dependency graph
|
|
27
|
+
- Calculate blocking relationships
|
|
28
|
+
- Identify critical path
|
|
29
|
+
- Find bottleneck tickets
|
|
30
|
+
|
|
31
|
+
### 3. Display Analysis Results
|
|
32
|
+
|
|
33
|
+
**Output:**
|
|
34
|
+
\`\`\`
|
|
35
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
36
|
+
BLOCKER ANALYSIS
|
|
37
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
38
|
+
Specification: {title}
|
|
39
|
+
|
|
40
|
+
CRITICAL PATH
|
|
41
|
+
─────────────────────────────────────────────────────────────────
|
|
42
|
+
Length: {pathLength} tickets
|
|
43
|
+
Impact: {blockedCount} tickets blocked
|
|
44
|
+
|
|
45
|
+
E{n}-T{m} → E{n}-T{m} → E{n}-T{m} → ...
|
|
46
|
+
|
|
47
|
+
HIGH-IMPACT BLOCKERS
|
|
48
|
+
─────────────────────────────────────────────────────────────────
|
|
49
|
+
E{n}-T{m} │ {title} │ Blocking {count} tickets
|
|
50
|
+
↳ E{n}-T{m}, E{n}-T{m}, E{n}-T{m}
|
|
51
|
+
|
|
52
|
+
BLOCKED TICKETS
|
|
53
|
+
─────────────────────────────────────────────────────────────────
|
|
54
|
+
E{n}-T{m} │ {title}
|
|
55
|
+
⚠ Waiting on: E{n}-T{m} ({status})
|
|
56
|
+
|
|
57
|
+
RECOMMENDATIONS
|
|
58
|
+
─────────────────────────────────────────────────────────────────
|
|
59
|
+
• Prioritize E{n}-T{m} to unblock {count} tickets
|
|
60
|
+
• Review dependency chain for E{n}-T{m}
|
|
61
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
62
|
+
\`\`\`
|
|
63
|
+
|
|
64
|
+
## Notes
|
|
65
|
+
- Identifies tickets blocking the most work
|
|
66
|
+
- Shows critical path through implementation
|
|
67
|
+
- Provides actionable recommendations
|
|
68
|
+
`;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SF-Commit Command Template
|
|
3
|
+
*
|
|
4
|
+
* Template for committing changes with SpecForge ticket metadata.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const SF_COMMIT_CONTENT = `# Commit Changes (SpecForge)
|
|
8
|
+
|
|
9
|
+
Create a git commit with SpecForge ticket metadata.
|
|
10
|
+
|
|
11
|
+
## Arguments
|
|
12
|
+
- \`$ARGUMENTS\` - Optional: Ticket ID (uses context if not provided)
|
|
13
|
+
|
|
14
|
+
## Task
|
|
15
|
+
|
|
16
|
+
### 1. Get Ticket Context
|
|
17
|
+
|
|
18
|
+
**MCP Calls:**
|
|
19
|
+
\`\`\`typescript
|
|
20
|
+
if ($ARGUMENTS) {
|
|
21
|
+
get_ticket($ARGUMENTS)
|
|
22
|
+
} else {
|
|
23
|
+
get_working_context()
|
|
24
|
+
get_ticket(context.ticketId)
|
|
25
|
+
}
|
|
26
|
+
\`\`\`
|
|
27
|
+
|
|
28
|
+
### 2. Generate Commit Message
|
|
29
|
+
|
|
30
|
+
**Logic:**
|
|
31
|
+
- Format: \`feat(scope): description (TICKET-ID)\`
|
|
32
|
+
- Extract scope from epic
|
|
33
|
+
- Use ticket title as description
|
|
34
|
+
- Add ticket ID reference
|
|
35
|
+
|
|
36
|
+
### 3. Create Commit
|
|
37
|
+
|
|
38
|
+
**Shell:**
|
|
39
|
+
\`\`\`bash
|
|
40
|
+
git add .
|
|
41
|
+
git commit -m "{type}({scope}): {description} ({ticketId})"
|
|
42
|
+
\`\`\`
|
|
43
|
+
|
|
44
|
+
### 4. Update Ticket Status
|
|
45
|
+
|
|
46
|
+
**MCP Calls:**
|
|
47
|
+
\`\`\`typescript
|
|
48
|
+
update_ticket({
|
|
49
|
+
ticketId: ticket.id,
|
|
50
|
+
status: 'done',
|
|
51
|
+
completedAt: new Date().toISOString()
|
|
52
|
+
})
|
|
53
|
+
\`\`\`
|
|
54
|
+
|
|
55
|
+
### 5. Display Commit Result
|
|
56
|
+
|
|
57
|
+
**Output:**
|
|
58
|
+
\`\`\`
|
|
59
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
60
|
+
COMMIT CREATED
|
|
61
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
62
|
+
Ticket: E{n}-T{m}
|
|
63
|
+
Message: {commitMessage}
|
|
64
|
+
Hash: {commitHash}
|
|
65
|
+
|
|
66
|
+
TICKET COMPLETED
|
|
67
|
+
─────────────────────────────────────────────────────────────────
|
|
68
|
+
✓ E{n}-T{m} marked as done
|
|
69
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
70
|
+
|
|
71
|
+
Next: Run /sf-next for the next ticket
|
|
72
|
+
\`\`\`
|
|
73
|
+
|
|
74
|
+
## Notes
|
|
75
|
+
- Automatically marks ticket as done
|
|
76
|
+
- Uses conventional commit format
|
|
77
|
+
- Includes ticket ID for traceability
|
|
78
|
+
`;
|