@modus-ai/modus 0.1.4 → 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.
Files changed (58) hide show
  1. package/README.md +76 -28
  2. package/dist/cli/index.js +206 -12
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/doctor.d.ts +2 -0
  5. package/dist/commands/doctor.d.ts.map +1 -0
  6. package/dist/commands/doctor.js +180 -0
  7. package/dist/commands/doctor.js.map +1 -0
  8. package/dist/commands/init.d.ts +18 -0
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +314 -201
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/skill.d.ts +7 -0
  13. package/dist/commands/skill.d.ts.map +1 -0
  14. package/dist/commands/skill.js +175 -0
  15. package/dist/commands/skill.js.map +1 -0
  16. package/dist/commands/status.d.ts +2 -0
  17. package/dist/commands/status.d.ts.map +1 -0
  18. package/dist/commands/status.js +133 -0
  19. package/dist/commands/status.js.map +1 -0
  20. package/dist/commands/update.d.ts.map +1 -1
  21. package/dist/commands/update.js +15 -6
  22. package/dist/commands/update.js.map +1 -1
  23. package/dist/generators/claude.d.ts +9 -0
  24. package/dist/generators/claude.d.ts.map +1 -0
  25. package/dist/generators/claude.js +256 -0
  26. package/dist/generators/claude.js.map +1 -0
  27. package/dist/generators/codebuddy.d.ts +7 -0
  28. package/dist/generators/codebuddy.d.ts.map +1 -1
  29. package/dist/generators/codebuddy.js +35 -3
  30. package/dist/generators/codebuddy.js.map +1 -1
  31. package/dist/generators/copilot.d.ts +9 -0
  32. package/dist/generators/copilot.d.ts.map +1 -0
  33. package/dist/generators/copilot.js +154 -0
  34. package/dist/generators/copilot.js.map +1 -0
  35. package/dist/generators/cursor.d.ts +9 -0
  36. package/dist/generators/cursor.d.ts.map +1 -0
  37. package/dist/generators/cursor.js +220 -0
  38. package/dist/generators/cursor.js.map +1 -0
  39. package/dist/generators/index.d.ts +9 -0
  40. package/dist/generators/index.d.ts.map +1 -0
  41. package/dist/generators/index.js +26 -0
  42. package/dist/generators/index.js.map +1 -0
  43. package/dist/utils/analytics.d.ts +14 -0
  44. package/dist/utils/analytics.d.ts.map +1 -0
  45. package/dist/utils/analytics.js +81 -0
  46. package/dist/utils/analytics.js.map +1 -0
  47. package/dist/utils/config.d.ts +25 -0
  48. package/dist/utils/config.d.ts.map +1 -1
  49. package/dist/utils/config.js.map +1 -1
  50. package/package.json +1 -1
  51. package/templates/commands/auto.md +38 -0
  52. package/templates/commands/modus.md +14 -2
  53. package/templates/hooks/session-start.py +103 -1
  54. package/templates/hooks/stop-update-skills.py +58 -0
  55. package/templates/skills/modus-auto/SKILL.md +210 -0
  56. package/templates/skills/modus-init/SKILL.md +208 -11
  57. package/templates/skills/modus-plan/SKILL.md +154 -19
  58. package/templates/skills/modus-spec/SKILL.md +131 -6
@@ -0,0 +1,220 @@
1
+ import path from 'node:path';
2
+ import { writeFile, readTemplate, fileExists, readFile } from '../utils/file-system.js';
3
+ const RULES_BASE = path.join('.cursor', 'rules');
4
+ const MCP_PATH = path.join('.cursor', 'mcp.json');
5
+ // ---------------------------------------------------------------------------
6
+ // Framework Skills → individual .mdc rules
7
+ // ---------------------------------------------------------------------------
8
+ const SKILL_RULES = [
9
+ {
10
+ id: 'modus-init',
11
+ templatePath: 'skills/modus-init/SKILL.md',
12
+ description: 'Run /modus:init to scan the codebase and build Business Skills for each domain',
13
+ },
14
+ {
15
+ id: 'modus-vibe',
16
+ templatePath: 'skills/modus-vibe/SKILL.md',
17
+ description: 'Run /modus:vibe to start context-aware vibe coding with business Skill preloading',
18
+ },
19
+ {
20
+ id: 'modus-plan',
21
+ templatePath: 'skills/modus-plan/SKILL.md',
22
+ description: 'Run /modus:plan to create structured feature proposals with complexity grading',
23
+ },
24
+ {
25
+ id: 'modus-spec',
26
+ templatePath: 'skills/modus-spec/SKILL.md',
27
+ description: 'Run /modus:spec for OpenSpec-driven development with delta specs and GIVEN/WHEN/THEN scenarios',
28
+ },
29
+ {
30
+ id: 'modus-auto',
31
+ templatePath: 'skills/modus-auto/SKILL.md',
32
+ description: 'Run /modus:auto with a TAPD story URL to get AI-recommended mode (vibe/plan/spec/harness)',
33
+ },
34
+ {
35
+ id: 'modus-harness',
36
+ templatePath: 'skills/modus-harness/SKILL.md',
37
+ description: 'Run /modus:harness to execute the full dual-loop multi-agent development pipeline',
38
+ },
39
+ ];
40
+ // Harness sub-agent templates to merge into the single harness rule
41
+ const HARNESS_SUB_AGENT_TEMPLATES = [
42
+ { id: '00-skills-builder', templatePath: 'skills/modus-harness-agents/00-skills-builder/SKILL.md' },
43
+ { id: '01-analysis', templatePath: 'skills/modus-harness-agents/01-analysis/SKILL.md' },
44
+ { id: '02-dev', templatePath: 'skills/modus-harness-agents/02-dev/SKILL.md' },
45
+ { id: '03-test', templatePath: 'skills/modus-harness-agents/03-test/SKILL.md' },
46
+ { id: '04-perf', templatePath: 'skills/modus-harness-agents/04-perf/SKILL.md' },
47
+ { id: '05-security', templatePath: 'skills/modus-harness-agents/05-security/SKILL.md' },
48
+ { id: '06-review', templatePath: 'skills/modus-harness-agents/06-review/SKILL.md' },
49
+ { id: '07-deploy', templatePath: 'skills/modus-harness-agents/07-deploy/SKILL.md' },
50
+ ];
51
+ // ---------------------------------------------------------------------------
52
+ // Main entry
53
+ // ---------------------------------------------------------------------------
54
+ export function generateCursorFiles(projectRoot, config, _opts = {}) {
55
+ generateCursorSkillRules(projectRoot, config);
56
+ generateCursorHarnessRule(projectRoot);
57
+ generateCursorConstitution(projectRoot, config);
58
+ generateCursorAutoVibe(projectRoot);
59
+ generateCursorMcp(projectRoot, config);
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // Individual skill rules
63
+ // ---------------------------------------------------------------------------
64
+ function generateCursorSkillRules(projectRoot, config) {
65
+ const enabled = new Set(config.commands.enabled);
66
+ for (const skill of SKILL_RULES) {
67
+ // Only generate command-backed skills if the command is enabled
68
+ const cmdId = skill.id.replace('modus-', '');
69
+ if (['init', 'vibe', 'plan', 'spec', 'auto', 'harness'].includes(cmdId) && !enabled.has(cmdId)) {
70
+ continue;
71
+ }
72
+ let body;
73
+ try {
74
+ body = readTemplate(skill.templatePath);
75
+ }
76
+ catch {
77
+ continue;
78
+ }
79
+ const content = buildMdcFile(skill.description, false, body);
80
+ writeFile(path.join(projectRoot, RULES_BASE, `${skill.id}.mdc`), content);
81
+ }
82
+ }
83
+ // ---------------------------------------------------------------------------
84
+ // Harness rule — single-agent degradation
85
+ // ---------------------------------------------------------------------------
86
+ function generateCursorHarnessRule(projectRoot) {
87
+ const sections = [
88
+ '# Modus Harness — Single-Agent Mode',
89
+ '',
90
+ '> **Note:** Cursor does not support native Sub-Agents. The Harness pipeline runs in',
91
+ '> single-agent mode: the orchestrator executes each step sequentially within one context.',
92
+ '> For full parallel Sub-Agent support, use CodeBuddy or Claude Code.',
93
+ '',
94
+ '## Pipeline Steps (sequential)',
95
+ '',
96
+ ];
97
+ for (const agent of HARNESS_SUB_AGENT_TEMPLATES) {
98
+ let body;
99
+ try {
100
+ body = readTemplate(agent.templatePath);
101
+ }
102
+ catch {
103
+ continue;
104
+ }
105
+ sections.push(`### Step ${agent.id}`, '', body, '', '---', '');
106
+ }
107
+ const content = buildMdcFile('Modus Harness orchestration steps (single-agent mode for Cursor)', false, sections.join('\n'));
108
+ writeFile(path.join(projectRoot, RULES_BASE, 'modus-harness-agents.mdc'), content);
109
+ }
110
+ // ---------------------------------------------------------------------------
111
+ // Constitution rule
112
+ // ---------------------------------------------------------------------------
113
+ function generateCursorConstitution(projectRoot, config) {
114
+ const any = config;
115
+ const constitution = any['constitution'] ?? {};
116
+ const techStack = String(constitution['tech_stack'] ?? config.techStack ?? '');
117
+ const buildCmd = String(constitution['build_command'] ?? '');
118
+ const testCmd = String(constitution['test_command'] ?? '');
119
+ const context = config.context ?? '';
120
+ const hardRules = Array.isArray(constitution['hard_rules'])
121
+ ? constitution['hard_rules'].map((r) => `- ${r}`).join('\n')
122
+ : '';
123
+ const keyPatterns = Array.isArray(constitution['key_patterns'])
124
+ ? constitution['key_patterns'].map((p) => `- ${p}`).join('\n')
125
+ : '';
126
+ const lines = ['# Modus Project Constitution', ''];
127
+ if (context) {
128
+ lines.push(`> ${context}`, '');
129
+ }
130
+ if (techStack) {
131
+ lines.push(`**Tech Stack:** ${techStack}`, '');
132
+ }
133
+ if (buildCmd) {
134
+ lines.push(`**Build Command:** \`${buildCmd}\``, '');
135
+ }
136
+ if (testCmd) {
137
+ lines.push(`**Test Command:** \`${testCmd}\``, '');
138
+ }
139
+ if (hardRules) {
140
+ lines.push('**Hard Rules (must never violate):**', hardRules, '');
141
+ }
142
+ if (keyPatterns) {
143
+ lines.push('**Key Patterns:**', keyPatterns, '');
144
+ }
145
+ lines.push('**Modus Commands:** `/modus:init` · `/modus:vibe` · `/modus:plan` · `/modus:spec` · `/modus:auto` · `/modus:harness`');
146
+ const content = buildMdcFile('Modus project constitution — tech stack, hard rules, and key patterns', true, lines.join('\n'));
147
+ writeFile(path.join(projectRoot, RULES_BASE, 'modus-constitution.mdc'), content);
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Auto-vibe — always-on rule that activates vibe behavior automatically
151
+ // ---------------------------------------------------------------------------
152
+ function generateCursorAutoVibe(projectRoot) {
153
+ const body = [
154
+ '# Modus Auto-Vibe Mode',
155
+ '',
156
+ 'This project has Modus initialized. **For every conversation, automatically apply',
157
+ 'vibe-mode behavior** — do not wait for the user to type `/modus:vibe`.',
158
+ '',
159
+ '## Auto-Vibe Instructions',
160
+ '',
161
+ '1. At the start of each conversation, read `modus/knowledge-catalog.md` to understand',
162
+ ' available Business Skills and their domains.',
163
+ '2. Based on the user\'s request, identify the relevant business domain(s).',
164
+ '3. Load the corresponding `.cursor/rules/modus-biz-{domain}.mdc` rule(s) to get',
165
+ ' business context (entities, rules, pitfalls, key files).',
166
+ '4. Respond as a developer who deeply understands this project — apply the',
167
+ ' business rules, naming conventions, and known pitfalls from the loaded Skills.',
168
+ '5. If the user explicitly triggers `/modus:plan`, `/modus:spec`, or `/modus:harness`,',
169
+ ' switch to that mode\'s workflow.',
170
+ '',
171
+ '## Token Efficiency',
172
+ '',
173
+ '- Load Skills **on demand** (only for domains relevant to the current request).',
174
+ '- Skip loading if the request is clearly out of project scope (e.g. general questions).',
175
+ '- Re-use already-loaded Skill context within the same conversation.',
176
+ ].join('\n');
177
+ const content = buildMdcFile('Auto-apply Modus vibe mode for every conversation — load Business Skills based on user request', true, body);
178
+ writeFile(path.join(projectRoot, RULES_BASE, 'modus-auto-vibe.mdc'), content);
179
+ }
180
+ // ---------------------------------------------------------------------------
181
+ // MCP config — .cursor/mcp.json
182
+ // ---------------------------------------------------------------------------
183
+ function generateCursorMcp(projectRoot, config) {
184
+ if (!config.mcpServers || Object.keys(config.mcpServers).length === 0)
185
+ return;
186
+ const mcpPath = path.join(projectRoot, MCP_PATH);
187
+ let existing = {};
188
+ if (fileExists(mcpPath)) {
189
+ try {
190
+ existing = JSON.parse(readFile(mcpPath));
191
+ }
192
+ catch {
193
+ existing = {};
194
+ }
195
+ }
196
+ const existingServers = existing['mcpServers'] ?? {};
197
+ existing['mcpServers'] = { ...config.mcpServers, ...existingServers };
198
+ writeFile(mcpPath, JSON.stringify(existing, null, 2) + '\n');
199
+ }
200
+ // ---------------------------------------------------------------------------
201
+ // Helpers
202
+ // ---------------------------------------------------------------------------
203
+ /**
204
+ * Wrap markdown body in a Cursor .mdc frontmatter header.
205
+ */
206
+ function buildMdcFile(description, alwaysApply, body) {
207
+ return `---\ndescription: "${description.replace(/"/g, '\\"')}"\nalwaysApply: ${alwaysApply}\n---\n\n${body}\n`;
208
+ }
209
+ // ---------------------------------------------------------------------------
210
+ // Business Skill sync
211
+ // ---------------------------------------------------------------------------
212
+ /**
213
+ * Sync a single business Skill to Cursor format.
214
+ * Creates a rule at .cursor/rules/modus-biz-{domain}.mdc
215
+ */
216
+ export function syncBizSkillToCursor(projectRoot, domain, skillContent) {
217
+ const content = buildMdcFile(`Business rules and conventions for the ${domain} domain`, false, skillContent);
218
+ writeFile(path.join(projectRoot, RULES_BASE, `modus-biz-${domain}.mdc`), content);
219
+ }
220
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/generators/cursor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type GenerateOptions } from './codebuddy.js';
2
+ import type { ModusConfig } from '../utils/config.js';
3
+ export type { GenerateOptions };
4
+ /**
5
+ * Generate configuration files for every platform listed in `config.platforms`.
6
+ * Defaults to ['codebuddy'] when the field is absent to preserve backward compat.
7
+ */
8
+ export declare function generateAllPlatformFiles(projectRoot: string, config: ModusConfig, opts?: GenerateOptions): void;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAI9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE,eAAoB,GACzB,IAAI,CAeN"}
@@ -0,0 +1,26 @@
1
+ // Platform dispatcher — generates configuration files for all selected AI platforms.
2
+ // Called by `modus init` and `modus update`; replaces direct calls to generateCodeBuddyFiles.
3
+ import { generateCodeBuddyFiles } from './codebuddy.js';
4
+ import { generateClaudeFiles } from './claude.js';
5
+ import { generateCursorFiles } from './cursor.js';
6
+ import { generateCopilotFiles } from './copilot.js';
7
+ /**
8
+ * Generate configuration files for every platform listed in `config.platforms`.
9
+ * Defaults to ['codebuddy'] when the field is absent to preserve backward compat.
10
+ */
11
+ export function generateAllPlatformFiles(projectRoot, config, opts = {}) {
12
+ const platforms = config.platforms ?? ['codebuddy'];
13
+ if (platforms.includes('codebuddy')) {
14
+ generateCodeBuddyFiles(projectRoot, config, opts);
15
+ }
16
+ if (platforms.includes('claude')) {
17
+ generateClaudeFiles(projectRoot, config, opts);
18
+ }
19
+ if (platforms.includes('cursor')) {
20
+ generateCursorFiles(projectRoot, config, opts);
21
+ }
22
+ if (platforms.includes('copilot')) {
23
+ generateCopilotFiles(projectRoot, config, opts);
24
+ }
25
+ }
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,8FAA8F;AAC9F,OAAO,EAAE,sBAAsB,EAAwB,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAKpD;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,WAAmB,EACnB,MAAmB,EACnB,OAAwB,EAAE;IAE1B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,WAAW,CAAC,CAAC;IAEpD,IAAI,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACpC,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface TrackEvent {
2
+ event_type: string;
3
+ command?: string;
4
+ sub_agent?: string;
5
+ result?: string;
6
+ payload?: Record<string, unknown>;
7
+ }
8
+ /**
9
+ * Send a usage event to the Modus Collector API.
10
+ * Fire-and-forget: errors are silently swallowed so they never block the CLI.
11
+ * Respects MODUS_ANALYTICS_DISABLED=1 env var.
12
+ */
13
+ export declare function track(projectRoot: string, event: TrackEvent): void;
14
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/utils/analytics.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AA2BD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CA+ClE"}
@@ -0,0 +1,81 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { execSync } from 'node:child_process';
3
+ import os from 'node:os';
4
+ import { loadConfig } from './config.js';
5
+ /**
6
+ * Derive an anonymized user ID from git email or hostname (MD5, not reversible).
7
+ * Never sends the raw email.
8
+ */
9
+ function resolveUserId() {
10
+ try {
11
+ const email = execSync('git config --global user.email', {
12
+ timeout: 2000,
13
+ stdio: ['ignore', 'pipe', 'ignore'],
14
+ })
15
+ .toString()
16
+ .trim();
17
+ if (email)
18
+ return createHash('md5').update(email).digest('hex').slice(0, 16);
19
+ }
20
+ catch {
21
+ // git not available or no config
22
+ }
23
+ return createHash('md5').update(os.hostname()).digest('hex').slice(0, 16);
24
+ }
25
+ let _userId = null;
26
+ function getUserId() {
27
+ if (!_userId)
28
+ _userId = resolveUserId();
29
+ return _userId;
30
+ }
31
+ /**
32
+ * Send a usage event to the Modus Collector API.
33
+ * Fire-and-forget: errors are silently swallowed so they never block the CLI.
34
+ * Respects MODUS_ANALYTICS_DISABLED=1 env var.
35
+ */
36
+ export function track(projectRoot, event) {
37
+ // Env-level opt-out
38
+ if (process.env['MODUS_ANALYTICS_DISABLED'] === '1')
39
+ return;
40
+ // Read config lazily; if it fails, just skip
41
+ let collectorUrl;
42
+ let token;
43
+ let projectId;
44
+ let teamName;
45
+ try {
46
+ const config = loadConfig(projectRoot);
47
+ const analytics = config.analytics;
48
+ if (analytics?.enabled === false)
49
+ return;
50
+ collectorUrl = analytics?.collectorUrl?.trim();
51
+ token = analytics?.token?.trim();
52
+ projectId = config.tapdProjectId ?? undefined;
53
+ teamName = config.teamName ?? undefined;
54
+ }
55
+ catch {
56
+ return;
57
+ }
58
+ if (!collectorUrl)
59
+ return;
60
+ const body = JSON.stringify({
61
+ event_type: event.event_type,
62
+ command: event.command,
63
+ sub_agent: event.sub_agent,
64
+ user_id: getUserId(),
65
+ project_id: projectId,
66
+ team_name: teamName,
67
+ result: event.result,
68
+ payload: event.payload,
69
+ });
70
+ // Defer so the main CLI flow is never blocked
71
+ setImmediate(() => {
72
+ const url = `${collectorUrl}/track`;
73
+ const headers = { 'Content-Type': 'application/json' };
74
+ if (token)
75
+ headers['Authorization'] = `Bearer ${token}`;
76
+ fetch(url, { method: 'POST', headers, body, signal: AbortSignal.timeout(3000) }).catch(() => {
77
+ // Intentionally silent
78
+ });
79
+ });
80
+ }
81
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/utils/analytics.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,13 @@
1
+ /** Supported AI platform targets for file generation. */
2
+ export type PlatformId = 'codebuddy' | 'claude' | 'cursor' | 'copilot';
3
+ export interface ModusAnalyticsConfig {
4
+ /** Whether to send usage events. Defaults to true. */
5
+ enabled?: boolean;
6
+ /** URL of the Modus Collector API, e.g. http://43.139.34.70:3456 */
7
+ collectorUrl?: string;
8
+ /** Bearer token for the collector API (optional). */
9
+ token?: string;
10
+ }
1
11
  export interface ModusConfig {
2
12
  version: string;
3
13
  commands: {
@@ -13,6 +23,21 @@ export interface ModusConfig {
13
23
  teamName?: string;
14
24
  /** MCP server configs collected during `modus init`. Written to .codebuddy/settings.json. */
15
25
  mcpServers?: Record<string, unknown>;
26
+ /** Usage analytics — sends command/subagent events to the Collector API. */
27
+ analytics?: ModusAnalyticsConfig;
28
+ /**
29
+ * AI platforms to generate configuration files for.
30
+ * Set during `modus init`; refreshed by `modus update`.
31
+ * Defaults to ['codebuddy'] when omitted.
32
+ */
33
+ platforms?: PlatformId[];
34
+ /**
35
+ * The modus CLI version that last wrote the platform files.
36
+ * Written by `modus init` and `modus update`.
37
+ * The session-start hook compares this against the currently installed version
38
+ * and auto-runs `modus update` when they differ (silent auto-update).
39
+ */
40
+ modusBuildVersion?: string;
16
41
  }
17
42
  export declare function getConfigPath(projectRoot: string): string;
18
43
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AASD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAK3D;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAIzE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAKA,yDAAyD;AACzD,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,oBAAoB;IACnC,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,4EAA4E;IAC5E,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,UAAU,EAAE,CAAC;IACzB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AASD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAK3D;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAIzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAmBnE,MAAM,cAAc,GAAgB;IAClC,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE;QACR,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;KACrD;CACF,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,WAAmB;IAC5C,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC1D,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACjC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAgB,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,MAAmB;IACjE,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA8CnE,MAAM,cAAc,GAAgB;IAClC,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE;QACR,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;KACrD;CACF,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,WAAmB;IAC5C,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC1D,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACjC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAgB,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,MAAmB;IACjE,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modus-ai/modus",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Modus — Business-grounded AI coding accelerator for CodeBuddy IDE",
5
5
  "keywords": [
6
6
  "ai",
@@ -0,0 +1,38 @@
1
+ # /modus:auto
2
+
3
+ Smart mode recommendation. Reads a TAPD Story, scores it across 4 dimensions, recommends the best Modus mode, then launches it after human confirmation.
4
+
5
+ ## Instructions
6
+
7
+ Read and follow the skill at `.codebuddy/skills/modus-auto/SKILL.md` to execute this command.
8
+
9
+ ## Quick Summary
10
+
11
+ 1. Accept a TAPD Story URL (or prompt for manual input if omitted)
12
+ 2. Read Story content via TAPD MCP
13
+ 3. Score the story across 4 dimensions: Complexity / Risk / Clarity / Contract Impact
14
+ 4. Apply the decision tree → recommend one of: vibe / plan / spec / harness
15
+ 5. Show recommendation with reasoning + comparison table of other options
16
+ 6. Wait for human mode selection
17
+ 7. Show parameter confirmation window (second confirmation step)
18
+ 8. Auto-launch the selected mode with TAPD context pre-filled
19
+
20
+ ## Usage
21
+
22
+ ```
23
+ /modus:auto https://tapd.cn/company/stories/view/1234567890
24
+ /modus:auto (without URL — will prompt for manual Story content)
25
+ ```
26
+
27
+ ## Decision Tree (summary)
28
+
29
+ | Score | Recommended Mode |
30
+ |-------|-----------------|
31
+ | Low complexity + Low risk + No contract change | vibe |
32
+ | Medium complexity + High clarity + No contract change | plan |
33
+ | Any contract change OR High risk OR needs testable acceptance criteria | spec |
34
+ | Low clarity OR High complexity + High risk OR full automation needed | harness |
35
+
36
+ ## When to Use
37
+
38
+ Use `/modus:auto` when you have a TAPD Story but are unsure which Modus mode fits best. The AI analyzes the story and presents a reasoned recommendation — you still make the final call.
@@ -10,13 +10,25 @@ Modus — Business-grounded AI coding accelerator.
10
10
  | `/modus:vibe` | Context-aware vibe coding with business Skill backing |
11
11
  | `/modus:plan` | Plan mode with Skill-backed business context |
12
12
  | `/modus:spec` | OpenSpec-style spec-driven development |
13
+ | `/modus:auto` | Smart mode recommendation — reads TAPD Story, scores 4 dimensions, recommends vibe/plan/spec/harness |
13
14
  | `/modus:harness` | Full dual-loop multi-agent Harness (analyze → dev → test → review → deploy) |
14
15
 
15
16
  ## Quick Start
16
17
 
17
18
  1. Run `/modus:init` once to scan your project and build business Skills
18
- 2. Use `/modus:vibe` for day-to-day coding with project context
19
- 3. Use `/modus:harness` for full-cycle feature delivery from a TAPD Story URL
19
+ 2. Use `/modus:auto [tapd-url]` when unsure which mode fits — AI recommends based on story analysis
20
+ 3. Use `/modus:vibe` for day-to-day coding with project context
21
+ 4. Use `/modus:harness` for full-cycle feature delivery from a TAPD Story URL
22
+
23
+ ## Mode Selection Guide
24
+
25
+ | Situation | Recommended Command |
26
+ |-----------|-------------------|
27
+ | Not sure which mode to use | `/modus:auto [tapd-url]` |
28
+ | Quick bug fix / small change | `/modus:vibe` |
29
+ | Feature with design docs, no spec needed | `/modus:plan` |
30
+ | Interface contract changes / testable acceptance criteria | `/modus:spec` |
31
+ | Full automation from TAPD story to deployment | `/modus:harness` |
20
32
 
21
33
  ## Tips
22
34