@modus-ai/modus 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +28 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +75 -216
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +15 -6
- package/dist/commands/update.js.map +1 -1
- package/dist/generators/claude.d.ts +9 -0
- package/dist/generators/claude.d.ts.map +1 -0
- package/dist/generators/claude.js +256 -0
- package/dist/generators/claude.js.map +1 -0
- package/dist/generators/copilot.d.ts +9 -0
- package/dist/generators/copilot.d.ts.map +1 -0
- package/dist/generators/copilot.js +154 -0
- package/dist/generators/copilot.js.map +1 -0
- package/dist/generators/cursor.d.ts +9 -0
- package/dist/generators/cursor.d.ts.map +1 -0
- package/dist/generators/cursor.js +220 -0
- package/dist/generators/cursor.js.map +1 -0
- package/dist/generators/index.d.ts +9 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +26 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/utils/config.d.ts +15 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js.map +1 -1
- package/package.json +1 -1
- package/templates/hooks/session-start.py +51 -1
- package/templates/skills/modus-init/SKILL.md +75 -0
- package/templates/skills/modus-plan/SKILL.md +22 -0
- package/templates/skills/modus-spec/SKILL.md +22 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ModusConfig } from '../utils/config.js';
|
|
2
|
+
import type { GenerateOptions } from './codebuddy.js';
|
|
3
|
+
export declare function generateClaudeFiles(projectRoot: string, config: ModusConfig, _opts?: GenerateOptions): void;
|
|
4
|
+
/**
|
|
5
|
+
* Sync a single business Skill (already written to .codebuddy/) to Claude format.
|
|
6
|
+
* Creates a sub-agent definition at .claude/agents/modus-biz-{domain}.md
|
|
7
|
+
*/
|
|
8
|
+
export declare function syncBizSkillToClaude(projectRoot: string, domain: string, skillContent: string): void;
|
|
9
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/generators/claude.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA8EtD,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,GAAE,eAAoB,GAC1B,IAAI,CAMN;AAkMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,IAAI,CAIN"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { writeFile, readTemplate, fileExists, readFile } from '../utils/file-system.js';
|
|
3
|
+
const COMMANDS_BASE = path.join('.claude', 'commands', 'modus');
|
|
4
|
+
const AGENTS_BASE = path.join('.claude', 'agents');
|
|
5
|
+
const RULES_BASE = path.join('.claude', 'rules');
|
|
6
|
+
const SETTINGS_PATH = path.join('.claude', 'settings.json');
|
|
7
|
+
const CLAUDE_MD = 'CLAUDE.md';
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Commands — Claude slash commands under .claude/commands/modus/
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
const COMMAND_IDS = ['init', 'vibe', 'plan', 'spec', 'auto', 'harness'];
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Framework Skills → Commands (Claude uses .claude/commands/ as slash commands)
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const FRAMEWORK_SKILL_IDS = [
|
|
16
|
+
'modus-init',
|
|
17
|
+
'modus-vibe',
|
|
18
|
+
'modus-plan',
|
|
19
|
+
'modus-spec',
|
|
20
|
+
'modus-auto',
|
|
21
|
+
'modus-harness',
|
|
22
|
+
'modus-harness-00-skills-builder',
|
|
23
|
+
'modus-harness-01-analysis',
|
|
24
|
+
'modus-harness-02-dev',
|
|
25
|
+
'modus-harness-03-test',
|
|
26
|
+
'modus-harness-04-perf',
|
|
27
|
+
'modus-harness-05-security',
|
|
28
|
+
'modus-harness-06-review',
|
|
29
|
+
'modus-harness-07-deploy',
|
|
30
|
+
];
|
|
31
|
+
/** Map skill ID → template path (same as CodeBuddy) */
|
|
32
|
+
const SKILL_TEMPLATE_MAP = {
|
|
33
|
+
'modus-init': 'skills/modus-init/SKILL.md',
|
|
34
|
+
'modus-vibe': 'skills/modus-vibe/SKILL.md',
|
|
35
|
+
'modus-plan': 'skills/modus-plan/SKILL.md',
|
|
36
|
+
'modus-spec': 'skills/modus-spec/SKILL.md',
|
|
37
|
+
'modus-auto': 'skills/modus-auto/SKILL.md',
|
|
38
|
+
'modus-harness': 'skills/modus-harness/SKILL.md',
|
|
39
|
+
'modus-harness-00-skills-builder': 'skills/modus-harness-agents/00-skills-builder/SKILL.md',
|
|
40
|
+
'modus-harness-01-analysis': 'skills/modus-harness-agents/01-analysis/SKILL.md',
|
|
41
|
+
'modus-harness-02-dev': 'skills/modus-harness-agents/02-dev/SKILL.md',
|
|
42
|
+
'modus-harness-03-test': 'skills/modus-harness-agents/03-test/SKILL.md',
|
|
43
|
+
'modus-harness-04-perf': 'skills/modus-harness-agents/04-perf/SKILL.md',
|
|
44
|
+
'modus-harness-05-security': 'skills/modus-harness-agents/05-security/SKILL.md',
|
|
45
|
+
'modus-harness-06-review': 'skills/modus-harness-agents/06-review/SKILL.md',
|
|
46
|
+
'modus-harness-07-deploy': 'skills/modus-harness-agents/07-deploy/SKILL.md',
|
|
47
|
+
};
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Harness sub-agents — Native .claude/agents/ sub-agent definitions
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
const HARNESS_AGENTS = [
|
|
52
|
+
'modus-harness-00-skills-builder',
|
|
53
|
+
'modus-harness-01-analysis',
|
|
54
|
+
'modus-harness-02-dev',
|
|
55
|
+
'modus-harness-03-test',
|
|
56
|
+
'modus-harness-04-perf',
|
|
57
|
+
'modus-harness-05-security',
|
|
58
|
+
'modus-harness-06-review',
|
|
59
|
+
'modus-harness-07-deploy',
|
|
60
|
+
];
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Rules — modus-workflow, modus-constitution
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
const RULE_DIRS = ['modus-workflow', 'modus-constitution'];
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Main entry
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
export function generateClaudeFiles(projectRoot, config, _opts = {}) {
|
|
69
|
+
generateClaudeCommands(projectRoot, config);
|
|
70
|
+
generateClaudeAgents(projectRoot);
|
|
71
|
+
generateClaudeRules(projectRoot, config);
|
|
72
|
+
generateClaudeMd(projectRoot, config);
|
|
73
|
+
generateClaudeSettings(projectRoot, config);
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Commands — copy framework Skills as slash commands
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
function generateClaudeCommands(projectRoot, config) {
|
|
79
|
+
// Root modus command
|
|
80
|
+
try {
|
|
81
|
+
const rootContent = readTemplate('commands/modus.md');
|
|
82
|
+
writeFile(path.join(projectRoot, '.claude', 'commands', 'modus.md'), rootContent);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// template not found — non-fatal
|
|
86
|
+
}
|
|
87
|
+
const enabled = new Set(config.commands.enabled);
|
|
88
|
+
for (const cmdId of COMMAND_IDS) {
|
|
89
|
+
if (!enabled.has(cmdId))
|
|
90
|
+
continue;
|
|
91
|
+
try {
|
|
92
|
+
const content = readTemplate(`commands/${cmdId}.md`);
|
|
93
|
+
writeFile(path.join(projectRoot, COMMANDS_BASE, `${cmdId}.md`), content);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// template not found — non-fatal
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// Sub-Agents — native Claude sub-agent definitions (.claude/agents/)
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
function generateClaudeAgents(projectRoot) {
|
|
104
|
+
for (const agentId of HARNESS_AGENTS) {
|
|
105
|
+
try {
|
|
106
|
+
const content = readTemplate(`agents/${agentId}.md`);
|
|
107
|
+
writeFile(path.join(projectRoot, AGENTS_BASE, `${agentId}.md`), content);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// template not found — non-fatal
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
// Rules — .claude/rules/*.md
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
function generateClaudeRules(projectRoot, config) {
|
|
118
|
+
for (const ruleDir of RULE_DIRS) {
|
|
119
|
+
try {
|
|
120
|
+
let content = readTemplate(`rules/${ruleDir}/RULE.mdc`);
|
|
121
|
+
if (ruleDir === 'modus-constitution') {
|
|
122
|
+
content = fillConstitutionTemplate(content, config);
|
|
123
|
+
}
|
|
124
|
+
// Claude rules live directly as .md files (no subdirectory needed)
|
|
125
|
+
writeFile(path.join(projectRoot, RULES_BASE, `${ruleDir}.md`), content);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// template not found — non-fatal
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// CLAUDE.md — inject modus constitution block
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
const CLAUDE_MD_SECTION_START = '<!-- modus:constitution:start -->';
|
|
136
|
+
const CLAUDE_MD_SECTION_END = '<!-- modus:constitution:end -->';
|
|
137
|
+
function buildConstitutionBlock(config) {
|
|
138
|
+
const any = config;
|
|
139
|
+
const constitution = any['constitution'] ?? {};
|
|
140
|
+
const techStack = String(constitution['tech_stack'] ?? config.techStack ?? '');
|
|
141
|
+
const buildCmd = String(constitution['build_command'] ?? '');
|
|
142
|
+
const testCmd = String(constitution['test_command'] ?? '');
|
|
143
|
+
const hardRules = Array.isArray(constitution['hard_rules'])
|
|
144
|
+
? constitution['hard_rules'].map((r) => `- ${r}`).join('\n')
|
|
145
|
+
: '';
|
|
146
|
+
const keyPatterns = Array.isArray(constitution['key_patterns'])
|
|
147
|
+
? constitution['key_patterns'].map((p) => `- ${p}`).join('\n')
|
|
148
|
+
: '';
|
|
149
|
+
const context = config.context ?? '';
|
|
150
|
+
const lines = [
|
|
151
|
+
CLAUDE_MD_SECTION_START,
|
|
152
|
+
'',
|
|
153
|
+
'## Modus Project Constitution',
|
|
154
|
+
'',
|
|
155
|
+
];
|
|
156
|
+
if (context) {
|
|
157
|
+
lines.push(`> ${context}`, '');
|
|
158
|
+
}
|
|
159
|
+
if (techStack) {
|
|
160
|
+
lines.push(`**Tech Stack:** ${techStack}`, '');
|
|
161
|
+
}
|
|
162
|
+
if (buildCmd) {
|
|
163
|
+
lines.push(`**Build Command:** \`${buildCmd}\``, '');
|
|
164
|
+
}
|
|
165
|
+
if (testCmd) {
|
|
166
|
+
lines.push(`**Test Command:** \`${testCmd}\``, '');
|
|
167
|
+
}
|
|
168
|
+
if (hardRules) {
|
|
169
|
+
lines.push('**Hard Rules (must never violate):**', hardRules, '');
|
|
170
|
+
}
|
|
171
|
+
if (keyPatterns) {
|
|
172
|
+
lines.push('**Key Patterns:**', keyPatterns, '');
|
|
173
|
+
}
|
|
174
|
+
lines.push('**Modus Commands:** `/modus:init` · `/modus:vibe` · `/modus:plan` · `/modus:spec` · `/modus:auto` · `/modus:harness`', '', '**Auto-Vibe Mode (always active):** For every conversation in this project, automatically', 'apply vibe-mode behavior without waiting for `/modus:vibe`. Read `modus/knowledge-catalog.md`,', 'identify relevant domains from the user\'s request, load the corresponding', '`.claude/agents/modus-biz-{domain}.md` sub-agent context, and respond as a developer', 'who deeply understands this codebase. Switch to plan/spec/harness mode only when', 'the user explicitly triggers those commands.', '', CLAUDE_MD_SECTION_END);
|
|
175
|
+
return lines.join('\n');
|
|
176
|
+
}
|
|
177
|
+
function generateClaudeMd(projectRoot, config) {
|
|
178
|
+
const claudeMdPath = path.join(projectRoot, CLAUDE_MD);
|
|
179
|
+
const block = buildConstitutionBlock(config);
|
|
180
|
+
if (!fileExists(claudeMdPath)) {
|
|
181
|
+
writeFile(claudeMdPath, block + '\n');
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
let existing = readFile(claudeMdPath);
|
|
185
|
+
// Replace existing modus block or append
|
|
186
|
+
if (existing.includes(CLAUDE_MD_SECTION_START)) {
|
|
187
|
+
const startIdx = existing.indexOf(CLAUDE_MD_SECTION_START);
|
|
188
|
+
const endIdx = existing.indexOf(CLAUDE_MD_SECTION_END);
|
|
189
|
+
if (endIdx !== -1) {
|
|
190
|
+
existing =
|
|
191
|
+
existing.slice(0, startIdx) +
|
|
192
|
+
block +
|
|
193
|
+
existing.slice(endIdx + CLAUDE_MD_SECTION_END.length);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
existing = existing.trimEnd() + '\n\n' + block + '\n';
|
|
198
|
+
}
|
|
199
|
+
writeFile(claudeMdPath, existing);
|
|
200
|
+
}
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Settings — merge MCP servers into .claude/settings.json
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
function generateClaudeSettings(projectRoot, config) {
|
|
205
|
+
if (!config.mcpServers || Object.keys(config.mcpServers).length === 0)
|
|
206
|
+
return;
|
|
207
|
+
const settingsPath = path.join(projectRoot, SETTINGS_PATH);
|
|
208
|
+
let existing = {};
|
|
209
|
+
if (fileExists(settingsPath)) {
|
|
210
|
+
try {
|
|
211
|
+
existing = JSON.parse(readFile(settingsPath));
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
existing = {};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Preserve existing mcpServers; add only new keys
|
|
218
|
+
const existingServers = existing['mcpServers'] ?? {};
|
|
219
|
+
existing['mcpServers'] = { ...config.mcpServers, ...existingServers };
|
|
220
|
+
writeFile(settingsPath, JSON.stringify(existing, null, 2) + '\n');
|
|
221
|
+
}
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
// Helpers
|
|
224
|
+
// ---------------------------------------------------------------------------
|
|
225
|
+
function fillConstitutionTemplate(template, config) {
|
|
226
|
+
const any = config;
|
|
227
|
+
const constitution = any['constitution'] ?? {};
|
|
228
|
+
const techStack = String(constitution['tech_stack'] ?? config.techStack ?? '(请在 modus/config.yaml 中填写 constitution.tech_stack)');
|
|
229
|
+
const buildCmd = String(constitution['build_command'] ?? '(请在 modus/config.yaml 中填写 constitution.build_command)');
|
|
230
|
+
const testCmd = String(constitution['test_command'] ?? '(请在 modus/config.yaml 中填写 constitution.test_command)');
|
|
231
|
+
const hardRules = Array.isArray(constitution['hard_rules'])
|
|
232
|
+
? constitution['hard_rules'].map((r) => `- ${r}`).join('\n')
|
|
233
|
+
: '(请在 modus/config.yaml 中填写 constitution.hard_rules)';
|
|
234
|
+
const keyPatterns = Array.isArray(constitution['key_patterns'])
|
|
235
|
+
? constitution['key_patterns'].map((p) => `- ${p}`).join('\n')
|
|
236
|
+
: '(暂无,可在 modus/config.yaml 中填写 constitution.key_patterns)';
|
|
237
|
+
return template
|
|
238
|
+
.replace('{{TECH_STACK}}', techStack)
|
|
239
|
+
.replace('{{BUILD_COMMAND}}', buildCmd)
|
|
240
|
+
.replace('{{TEST_COMMAND}}', testCmd)
|
|
241
|
+
.replace('{{HARD_RULES}}', hardRules)
|
|
242
|
+
.replace('{{KEY_PATTERNS}}', keyPatterns);
|
|
243
|
+
}
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
// Business Skill sync (called from modus-init SKILL at runtime)
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
/**
|
|
248
|
+
* Sync a single business Skill (already written to .codebuddy/) to Claude format.
|
|
249
|
+
* Creates a sub-agent definition at .claude/agents/modus-biz-{domain}.md
|
|
250
|
+
*/
|
|
251
|
+
export function syncBizSkillToClaude(projectRoot, domain, skillContent) {
|
|
252
|
+
const agentPath = path.join(projectRoot, AGENTS_BASE, `modus-biz-${domain}.md`);
|
|
253
|
+
const header = `# modus-biz-${domain}\n\nBusiness knowledge agent for the **${domain}** domain.\n\n`;
|
|
254
|
+
writeFile(agentPath, header + skillContent);
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/generators/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ModusConfig } from '../utils/config.js';
|
|
2
|
+
import type { GenerateOptions } from './codebuddy.js';
|
|
3
|
+
export declare function generateCopilotFiles(projectRoot: string, config: ModusConfig, _opts?: GenerateOptions): void;
|
|
4
|
+
/**
|
|
5
|
+
* Append or update a single business Skill section in copilot-instructions.md.
|
|
6
|
+
* The section is identified by domain-specific markers.
|
|
7
|
+
*/
|
|
8
|
+
export declare function syncBizSkillToCopilot(projectRoot: string, domain: string, skillContent: string): void;
|
|
9
|
+
//# sourceMappingURL=copilot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot.d.ts","sourceRoot":"","sources":["../../src/generators/copilot.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAsBtD,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,GAAE,eAAoB,GAC1B,IAAI,CASN;AAqFD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,IAAI,CAYN"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// GitHub Copilot file generator.
|
|
2
|
+
// Writes all modus configuration to a single .github/copilot-instructions.md file.
|
|
3
|
+
// Uses section markers for idempotent updates — repeated runs replace existing sections
|
|
4
|
+
// rather than appending duplicates.
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { writeFile, readTemplate, fileExists, readFile } from '../utils/file-system.js';
|
|
7
|
+
const COPILOT_MD = path.join('.github', 'copilot-instructions.md');
|
|
8
|
+
/** Section markers — must be unique across the file */
|
|
9
|
+
const MARKER = {
|
|
10
|
+
constitution: { start: '<!-- modus:constitution:start -->', end: '<!-- modus:constitution:end -->' },
|
|
11
|
+
commands: { start: '<!-- modus:commands:start -->', end: '<!-- modus:commands:end -->' },
|
|
12
|
+
skills: { start: '<!-- modus:skills:start -->', end: '<!-- modus:skills:end -->' },
|
|
13
|
+
bizSkills: { start: '<!-- modus:biz-skills:start -->', end: '<!-- modus:biz-skills:end -->' },
|
|
14
|
+
};
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Command templates to embed
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
const COMMAND_IDS = ['init', 'vibe', 'plan', 'spec', 'auto', 'harness'];
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Main entry
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
export function generateCopilotFiles(projectRoot, config, _opts = {}) {
|
|
23
|
+
const copilotMdPath = path.join(projectRoot, COPILOT_MD);
|
|
24
|
+
let existing = fileExists(copilotMdPath) ? readFile(copilotMdPath) : '';
|
|
25
|
+
existing = upsertSection(existing, MARKER.constitution, buildConstitutionSection(config));
|
|
26
|
+
existing = upsertSection(existing, MARKER.commands, buildCommandsSection(config));
|
|
27
|
+
existing = upsertSection(existing, MARKER.skills, buildSkillsSection());
|
|
28
|
+
writeFile(copilotMdPath, existing);
|
|
29
|
+
}
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Section builders
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
function buildConstitutionSection(config) {
|
|
34
|
+
const any = config;
|
|
35
|
+
const constitution = any['constitution'] ?? {};
|
|
36
|
+
const techStack = String(constitution['tech_stack'] ?? config.techStack ?? '');
|
|
37
|
+
const buildCmd = String(constitution['build_command'] ?? '');
|
|
38
|
+
const testCmd = String(constitution['test_command'] ?? '');
|
|
39
|
+
const context = config.context ?? '';
|
|
40
|
+
const hardRules = Array.isArray(constitution['hard_rules'])
|
|
41
|
+
? constitution['hard_rules'].map((r) => `- ${r}`).join('\n')
|
|
42
|
+
: '';
|
|
43
|
+
const keyPatterns = Array.isArray(constitution['key_patterns'])
|
|
44
|
+
? constitution['key_patterns'].map((p) => `- ${p}`).join('\n')
|
|
45
|
+
: '';
|
|
46
|
+
const lines = ['## Modus Project Constitution', ''];
|
|
47
|
+
if (context) {
|
|
48
|
+
lines.push(`> ${context}`, '');
|
|
49
|
+
}
|
|
50
|
+
if (techStack) {
|
|
51
|
+
lines.push(`**Tech Stack:** ${techStack}`, '');
|
|
52
|
+
}
|
|
53
|
+
if (buildCmd) {
|
|
54
|
+
lines.push(`**Build Command:** \`${buildCmd}\``, '');
|
|
55
|
+
}
|
|
56
|
+
if (testCmd) {
|
|
57
|
+
lines.push(`**Test Command:** \`${testCmd}\``, '');
|
|
58
|
+
}
|
|
59
|
+
if (hardRules) {
|
|
60
|
+
lines.push('**Hard Rules (must never violate):**', hardRules, '');
|
|
61
|
+
}
|
|
62
|
+
if (keyPatterns) {
|
|
63
|
+
lines.push('**Key Patterns:**', keyPatterns, '');
|
|
64
|
+
}
|
|
65
|
+
return lines.join('\n');
|
|
66
|
+
}
|
|
67
|
+
function buildCommandsSection(config) {
|
|
68
|
+
const enabled = new Set(config.commands.enabled);
|
|
69
|
+
const lines = ['## Modus Commands', ''];
|
|
70
|
+
for (const cmdId of COMMAND_IDS) {
|
|
71
|
+
if (!enabled.has(cmdId))
|
|
72
|
+
continue;
|
|
73
|
+
let body;
|
|
74
|
+
try {
|
|
75
|
+
body = readTemplate(`commands/${cmdId}.md`);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
lines.push(`### /modus:${cmdId}`, '', body, '');
|
|
81
|
+
}
|
|
82
|
+
return lines.join('\n');
|
|
83
|
+
}
|
|
84
|
+
function buildSkillsSection() {
|
|
85
|
+
const lines = [
|
|
86
|
+
'## Modus Auto-Vibe Mode (Always Active)',
|
|
87
|
+
'',
|
|
88
|
+
'This project has Modus initialized. **For every conversation, automatically apply',
|
|
89
|
+
'vibe-mode behavior** — do not wait for the user to type `/modus:vibe`.',
|
|
90
|
+
'',
|
|
91
|
+
'**Auto-Vibe Instructions:**',
|
|
92
|
+
'1. Read `modus/knowledge-catalog.md` to understand available Business Skills.',
|
|
93
|
+
'2. Based on the user\'s request, identify relevant business domain(s).',
|
|
94
|
+
'3. Apply business rules, naming conventions, and known pitfalls from those domains.',
|
|
95
|
+
'4. Respond as a developer who deeply understands this codebase.',
|
|
96
|
+
'5. Switch to plan/spec/harness mode only when the user explicitly triggers those commands.',
|
|
97
|
+
'',
|
|
98
|
+
'## Modus Framework Skills',
|
|
99
|
+
'',
|
|
100
|
+
'The following AI skills are available for this project.',
|
|
101
|
+
'',
|
|
102
|
+
'| Skill | Trigger | Purpose |',
|
|
103
|
+
'|-------|---------|---------|',
|
|
104
|
+
'| modus-init | `/modus:init` | Scan codebase, build Business Skills per domain |',
|
|
105
|
+
'| modus-vibe | `/modus:vibe` | Explicit vibe mode with full Skill preloading |',
|
|
106
|
+
'| modus-plan | `/modus:plan` | Feature planning with complexity grading |',
|
|
107
|
+
'| modus-spec | `/modus:spec` | OpenSpec-driven development with GIVEN/WHEN/THEN |',
|
|
108
|
+
'| modus-auto | `/modus:auto` | TAPD-aware mode recommendation |',
|
|
109
|
+
'| modus-harness | `/modus:harness` | Dual-loop multi-agent full development pipeline |',
|
|
110
|
+
'',
|
|
111
|
+
'> Note: GitHub Copilot does not support Sub-Agents. Harness runs in single-agent mode.',
|
|
112
|
+
];
|
|
113
|
+
return lines.join('\n');
|
|
114
|
+
}
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Business Skill sync
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
/**
|
|
119
|
+
* Append or update a single business Skill section in copilot-instructions.md.
|
|
120
|
+
* The section is identified by domain-specific markers.
|
|
121
|
+
*/
|
|
122
|
+
export function syncBizSkillToCopilot(projectRoot, domain, skillContent) {
|
|
123
|
+
const copilotMdPath = path.join(projectRoot, COPILOT_MD);
|
|
124
|
+
let existing = fileExists(copilotMdPath) ? readFile(copilotMdPath) : '';
|
|
125
|
+
const domainMarker = {
|
|
126
|
+
start: `<!-- modus:biz-skill:${domain}:start -->`,
|
|
127
|
+
end: `<!-- modus:biz-skill:${domain}:end -->`,
|
|
128
|
+
};
|
|
129
|
+
const section = `### Business Skill: ${domain}\n\n${skillContent}`;
|
|
130
|
+
existing = upsertSection(existing, domainMarker, section);
|
|
131
|
+
writeFile(copilotMdPath, existing);
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Idempotent section upsert helper
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
/**
|
|
137
|
+
* Replace content between start/end markers in `existing`, or append if absent.
|
|
138
|
+
* Preserves all content outside the markers.
|
|
139
|
+
*/
|
|
140
|
+
function upsertSection(existing, markers, newContent) {
|
|
141
|
+
const block = `${markers.start}\n\n${newContent}\n\n${markers.end}`;
|
|
142
|
+
if (existing.includes(markers.start)) {
|
|
143
|
+
const startIdx = existing.indexOf(markers.start);
|
|
144
|
+
const endIdx = existing.indexOf(markers.end);
|
|
145
|
+
if (endIdx !== -1) {
|
|
146
|
+
return (existing.slice(0, startIdx) +
|
|
147
|
+
block +
|
|
148
|
+
existing.slice(endIdx + markers.end.length));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Section not present yet — append
|
|
152
|
+
return existing.trimEnd() + (existing.length > 0 ? '\n\n' : '') + block + '\n';
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=copilot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../src/generators/copilot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ModusConfig } from '../utils/config.js';
|
|
2
|
+
import type { GenerateOptions } from './codebuddy.js';
|
|
3
|
+
export declare function generateCursorFiles(projectRoot: string, config: ModusConfig, _opts?: GenerateOptions): void;
|
|
4
|
+
/**
|
|
5
|
+
* Sync a single business Skill to Cursor format.
|
|
6
|
+
* Creates a rule at .cursor/rules/modus-biz-{domain}.mdc
|
|
7
|
+
*/
|
|
8
|
+
export declare function syncBizSkillToCursor(projectRoot: string, domain: string, skillContent: string): void;
|
|
9
|
+
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/generators/cursor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA0DtD,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,GAAE,eAAoB,GAC1B,IAAI,CAMN;AAgLD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,IAAI,CAON"}
|