@modus-ai/modus 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +121 -0
  2. package/bin/modus.js +2 -0
  3. package/dist/cli/index.d.ts +2 -0
  4. package/dist/cli/index.d.ts.map +1 -0
  5. package/dist/cli/index.js +39 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/commands/config.d.ts +2 -0
  8. package/dist/commands/config.d.ts.map +1 -0
  9. package/dist/commands/config.js +66 -0
  10. package/dist/commands/config.js.map +1 -0
  11. package/dist/commands/init.d.ts +2 -0
  12. package/dist/commands/init.d.ts.map +1 -0
  13. package/dist/commands/init.js +89 -0
  14. package/dist/commands/init.js.map +1 -0
  15. package/dist/commands/update.d.ts +2 -0
  16. package/dist/commands/update.d.ts.map +1 -0
  17. package/dist/commands/update.js +19 -0
  18. package/dist/commands/update.js.map +1 -0
  19. package/dist/generators/codebuddy.d.ts +3 -0
  20. package/dist/generators/codebuddy.d.ts.map +1 -0
  21. package/dist/generators/codebuddy.js +77 -0
  22. package/dist/generators/codebuddy.js.map +1 -0
  23. package/dist/index.d.ts +4 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +4 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/utils/config.d.ts +13 -0
  28. package/dist/utils/config.d.ts.map +1 -0
  29. package/dist/utils/config.js +25 -0
  30. package/dist/utils/config.js.map +1 -0
  31. package/dist/utils/file-system.d.ts +11 -0
  32. package/dist/utils/file-system.d.ts.map +1 -0
  33. package/dist/utils/file-system.js +41 -0
  34. package/dist/utils/file-system.js.map +1 -0
  35. package/package.json +55 -0
  36. package/schemas/harness-schema.yaml +91 -0
  37. package/schemas/knowledge-schema.yaml +174 -0
  38. package/schemas/plan-schema.yaml +42 -0
  39. package/schemas/spec-schema.yaml +64 -0
  40. package/templates/commands/harness.md +46 -0
  41. package/templates/commands/init.md +16 -0
  42. package/templates/commands/plan.md +28 -0
  43. package/templates/commands/spec.md +37 -0
  44. package/templates/commands/vibe.md +18 -0
  45. package/templates/knowledge-catalog.md +26 -0
  46. package/templates/skills/modus-harness/SKILL.md +247 -0
  47. package/templates/skills/modus-harness-agents/00-skills-builder/SKILL.md +293 -0
  48. package/templates/skills/modus-harness-agents/01-analysis/SKILL.md +135 -0
  49. package/templates/skills/modus-harness-agents/02-dev/SKILL.md +102 -0
  50. package/templates/skills/modus-harness-agents/03-test/SKILL.md +84 -0
  51. package/templates/skills/modus-harness-agents/04-perf/SKILL.md +109 -0
  52. package/templates/skills/modus-harness-agents/05-security/SKILL.md +116 -0
  53. package/templates/skills/modus-harness-agents/06-review/SKILL.md +123 -0
  54. package/templates/skills/modus-harness-agents/07-deploy/SKILL.md +101 -0
  55. package/templates/skills/modus-init/SKILL.md +227 -0
  56. package/templates/skills/modus-plan/SKILL.md +246 -0
  57. package/templates/skills/modus-spec/SKILL.md +255 -0
  58. package/templates/skills/modus-vibe/SKILL.md +150 -0
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ <p align="center">
2
+ <strong>Modus</strong> — Business-grounded AI coding accelerator for CodeBuddy IDE
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/@modus-ai/modus"><img alt="npm version" src="https://img.shields.io/npm/v/@modus-ai/modus?style=flat-square" /></a>
7
+ <a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
8
+ </p>
9
+
10
+ ## 设计哲学
11
+
12
+ ```
13
+ → context-aware 不 context-blind — 编码前先加载业务上下文
14
+ → business-grounded 不 feature-fragmented — 以领域知识驱动 AI
15
+ → spec-driven 不 chat-driven — 变更有文档,决策有留痕
16
+ → multi-agent 不 single-brain — 专业分工,各司其职
17
+ → iterative 不 waterfall — 随时更新 Skill,随时归档
18
+ → knowledge-compounding 不 cold-start — 每次执行都在积累,越用越快
19
+ ```
20
+
21
+ ## 快速开始
22
+
23
+ **需要 Node.js 18.0.0 或以上版本。**
24
+
25
+ 全局安装 Modus:
26
+
27
+ ```bash
28
+ npm install -g @modus-ai/modus
29
+ ```
30
+
31
+ 进入你的项目目录并初始化:
32
+
33
+ ```bash
34
+ cd your-project
35
+ modus init
36
+ ```
37
+
38
+ 然后在 CodeBuddy IDE 中运行:
39
+
40
+ ```
41
+ /modus:init
42
+ ```
43
+
44
+ ## 5 个核心命令
45
+
46
+ | 命令 | 用途 |
47
+ |------|------|
48
+ | `/modus:init` | 分析项目,生成业务/团队/技术三层知识库 + 知识目录 |
49
+ | `/modus:vibe` | 氛围编程,三级渐进加载业务上下文(`--quick` 快速模式)|
50
+ | `/modus:plan` | 功能规划,生成 proposal/design/tasks,支持断点续跑 |
51
+ | `/modus:spec` | 规范开发,生成 delta specs(场景驱动验收)+ 知识提取 |
52
+ | `/modus:harness` | 全自动双 Loop 多智能体流程,含知识注入/提取闭环 |
53
+
54
+ ## 典型工作流
55
+
56
+ ```text
57
+ 你: /modus:init
58
+ AI: 识别到 3 个业务域:order, payment, user
59
+ 生成 Business Skills (Layer 2)...
60
+ 生成 modus-team-conventions (Layer 0-T)...
61
+ 生成 modus-tech-wiki (Layer 1)...
62
+ 生成 modus/knowledge-catalog.md(知识全景索引)
63
+ ✅ 初始化完成 | 建议填写 modus/config.yaml 的 constitution 字段
64
+
65
+ 你: /modus:vibe 帮我给订单模块加一个批量审批接口
66
+ AI: [Level 1] 读取知识目录(200 tokens)
67
+ [Level 2] 加载 order 域业务知识(3000 tokens,仅此一个域)
68
+ 我来实现批量审批接口...
69
+ 📝 Skill 更新建议:发现 OrderStatus.PENDING_REVIEW 状态,建议更新 Skill
70
+
71
+ 你: /modus:harness https://tapd.cn/xxx/stories/view/1234567
72
+ AI: [INIT] 注入知识:order[verified] | payment[proven]
73
+ ✅ SubAgent 01 完成 → 01-analysis.md(影响范围: 5 个类 | domains: order,payment)
74
+ 🔄 SubAgent 02 执行中...(Sprint 2/3 | token: 3/5 Skill 预算已用)
75
+ ⏳ 并行等待 03/04/05(2/3 完成)
76
+ ✅ Gate C 通过,无 P1/P2
77
+ 📚 ARCHIVE 完成 → 提取知识 4 条(decision:1 | pitfall:2 | guideline:1)
78
+ ⏸️ 等待人工 Final Review
79
+ ```
80
+
81
+ ## 知识体系(核心竞争力)
82
+
83
+ Modus 的知识体系让 AI 从「冷启动」变为「越用越快」:
84
+
85
+ ```
86
+ 第1次开发 → 45 分钟(AI 需理解项目背景)
87
+ 第N次开发 → 15 分钟(knowledge-catalog + proven Skill,精准命中)
88
+ ```
89
+
90
+ **三层知识结构:**
91
+ - **Layer 0-T** `modus-team-conventions` — 团队约定(代码规范、提交规范)
92
+ - **Layer 1** `modus-tech-wiki` — 技术知识(架构决策、反模式库,跨项目积累)
93
+ - **Layer 2** `modus-biz-*` — 业务知识(领域模型、业务规则、API 契约)
94
+
95
+ **知识成熟度:** `draft` → `verified` → `proven`(自动提升 + 自动衰减,保持知识库健康)
96
+
97
+ **渐进加载:** Level 1(catalog,~200 tokens)→ Level 2(Skill,~3000 tokens/个)→ Level 3(代码文件,按需)节省约 59% token。
98
+
99
+ **项目宪法:** `modus/config.yaml` 的 `constitution.hard_rules` 是所有 SubAgent 的最高优先级约束,一次配置,永久生效。
100
+
101
+ ## 文档
102
+
103
+ → **[Getting Started](docs/getting-started.md)**: 第一步
104
+ → **[Commands](docs/commands.md)**: 命令详情
105
+ → **[Concepts](docs/concepts.md)**: 核心概念(含知识分层架构)
106
+ → **[Harness](docs/harness.md)**: 双 Loop 多智能体原理(含 HANDOFF 协议)
107
+ → **[Knowledge](docs/knowledge.md)**: 知识体系详解
108
+
109
+ ## CLI 命令
110
+
111
+ ```bash
112
+ modus init # 初始化项目(生成 .codebuddy/ 文件 + 知识目录)
113
+ modus update # 升级后刷新文件
114
+ modus config show # 查看当前配置
115
+ modus config profile # 选择启用哪些命令
116
+ modus config set # 修改单个配置项
117
+ ```
118
+
119
+ ## License
120
+
121
+ MIT
package/bin/modus.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/cli/index.js';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,39 @@
1
+ import { Command } from 'commander';
2
+ import path from 'node:path';
3
+ import { createRequire } from 'node:module';
4
+ import { runInit } from '../commands/init.js';
5
+ import { runUpdate } from '../commands/update.js';
6
+ import { runConfig } from '../commands/config.js';
7
+ const require = createRequire(import.meta.url);
8
+ const pkg = require('../../package.json');
9
+ const program = new Command();
10
+ program
11
+ .name('modus')
12
+ .description('Modus — Business-grounded AI coding accelerator for CodeBuddy IDE')
13
+ .version(pkg.version);
14
+ program
15
+ .command('init')
16
+ .description('Initialize Modus in the current project (generates .codebuddy/ files)')
17
+ .option('--root <path>', 'Project root directory', process.cwd())
18
+ .action(async (opts) => {
19
+ const projectRoot = path.resolve(opts.root);
20
+ await runInit(projectRoot);
21
+ });
22
+ program
23
+ .command('update')
24
+ .description('Re-generate .codebuddy/ skill and command files from latest templates')
25
+ .option('--root <path>', 'Project root directory', process.cwd())
26
+ .action(async (opts) => {
27
+ const projectRoot = path.resolve(opts.root);
28
+ await runUpdate(projectRoot);
29
+ });
30
+ program
31
+ .command('config [subcommand]')
32
+ .description('View or update Modus config. Subcommands: show | profile | set')
33
+ .option('--root <path>', 'Project root directory', process.cwd())
34
+ .action(async (subcommand, opts) => {
35
+ const projectRoot = path.resolve(opts.root);
36
+ await runConfig(projectRoot, subcommand);
37
+ });
38
+ program.parse(process.argv);
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAE1C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,mEAAmE,CAAC;KAChF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,uEAAuE,CAAC;KACpF,MAAM,CAAC,eAAe,EAAE,wBAAwB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAChE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,uEAAuE,CAAC;KACpF,MAAM,CAAC,eAAe,EAAE,wBAAwB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAChE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,qBAAqB,CAAC;KAC9B,WAAW,CAAC,gEAAgE,CAAC;KAC7E,MAAM,CAAC,eAAe,EAAE,wBAAwB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAChE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;IACjC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runConfig(projectRoot: string, subcommand?: string): Promise<void>;
2
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAUA,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA+Df"}
@@ -0,0 +1,66 @@
1
+ import chalk from 'chalk';
2
+ import inquirer from 'inquirer';
3
+ import yaml from 'js-yaml';
4
+ import path from 'node:path';
5
+ import { loadConfig, saveConfig } from '../utils/config.js';
6
+ import { generateCodeBuddyFiles } from '../generators/codebuddy.js';
7
+ import { fileExists } from '../utils/file-system.js';
8
+ const SUBCOMMANDS = ['show', 'profile', 'set'];
9
+ export async function runConfig(projectRoot, subcommand) {
10
+ const configPath = path.join(projectRoot, 'modus', 'config.yaml');
11
+ if (!fileExists(configPath)) {
12
+ console.error(chalk.red(' Error: Modus is not initialized. Run `modus init` first.'));
13
+ process.exit(1);
14
+ }
15
+ const config = loadConfig(projectRoot);
16
+ if (!subcommand || subcommand === 'show') {
17
+ console.log(chalk.bold('\n modus/config.yaml\n'));
18
+ console.log(yaml.dump(config));
19
+ return;
20
+ }
21
+ if (subcommand === 'profile') {
22
+ const { enabledCommands } = await inquirer.prompt([
23
+ {
24
+ type: 'checkbox',
25
+ name: 'enabledCommands',
26
+ message: 'Select active commands:',
27
+ choices: [
28
+ { name: '/modus:init', value: 'init', checked: config.commands.enabled.includes('init') },
29
+ { name: '/modus:vibe', value: 'vibe', checked: config.commands.enabled.includes('vibe') },
30
+ { name: '/modus:plan', value: 'plan', checked: config.commands.enabled.includes('plan') },
31
+ { name: '/modus:spec', value: 'spec', checked: config.commands.enabled.includes('spec') },
32
+ { name: '/modus:harness', value: 'harness', checked: config.commands.enabled.includes('harness') },
33
+ ],
34
+ },
35
+ ]);
36
+ config.commands.enabled = enabledCommands;
37
+ saveConfig(projectRoot, config);
38
+ console.log(chalk.green(' ✓ Profile updated.'));
39
+ const { doUpdate } = await inquirer.prompt([
40
+ {
41
+ type: 'confirm',
42
+ name: 'doUpdate',
43
+ message: 'Run `modus update` to apply changes?',
44
+ default: true,
45
+ },
46
+ ]);
47
+ if (doUpdate) {
48
+ generateCodeBuddyFiles(projectRoot, config);
49
+ console.log(chalk.green(' ✓ CodeBuddy files regenerated.'));
50
+ }
51
+ return;
52
+ }
53
+ if (subcommand === 'set') {
54
+ const { key, value } = await inquirer.prompt([
55
+ { type: 'input', name: 'key', message: 'Config key (e.g. techStack, context, tapdProjectId):' },
56
+ { type: 'input', name: 'value', message: 'Value:' },
57
+ ]);
58
+ config[key] = value;
59
+ saveConfig(projectRoot, config);
60
+ console.log(chalk.green(` ✓ ${key} updated.`));
61
+ return;
62
+ }
63
+ console.error(chalk.red(` Unknown subcommand: ${subcommand}. Use: ${SUBCOMMANDS.join(', ')}`));
64
+ process.exit(1);
65
+ }
66
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runInit(projectRoot: string): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,wBAAsB,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6FhE"}
@@ -0,0 +1,89 @@
1
+ import path from 'node:path';
2
+ import chalk from 'chalk';
3
+ import inquirer from 'inquirer';
4
+ import { loadConfig, saveConfig } from '../utils/config.js';
5
+ import { generateCodeBuddyFiles } from '../generators/codebuddy.js';
6
+ import { fileExists, ensureDir } from '../utils/file-system.js';
7
+ export async function runInit(projectRoot) {
8
+ console.log(chalk.bold('\n Modus — init\n'));
9
+ const configPath = path.join(projectRoot, 'modus', 'config.yaml');
10
+ const isFirstRun = !fileExists(configPath);
11
+ if (!isFirstRun) {
12
+ const { overwrite } = await inquirer.prompt([
13
+ {
14
+ type: 'confirm',
15
+ name: 'overwrite',
16
+ message: 'Modus is already initialized. Re-generate all files?',
17
+ default: true,
18
+ },
19
+ ]);
20
+ if (!overwrite) {
21
+ console.log(chalk.gray(' Aborted.'));
22
+ return;
23
+ }
24
+ }
25
+ // Collect project context on first run
26
+ let config = loadConfig(projectRoot);
27
+ if (isFirstRun) {
28
+ const answers = await inquirer.prompt([
29
+ {
30
+ type: 'input',
31
+ name: 'techStack',
32
+ message: 'Tech stack (e.g. "Java Spring Boot, MySQL, Redis"):',
33
+ default: '',
34
+ },
35
+ {
36
+ type: 'input',
37
+ name: 'context',
38
+ message: 'Brief project description (used as AI context):',
39
+ default: '',
40
+ },
41
+ {
42
+ type: 'input',
43
+ name: 'tapdProjectId',
44
+ message: 'TAPD Project ID (optional, for /harness command):',
45
+ default: '',
46
+ },
47
+ ]);
48
+ config = {
49
+ ...config,
50
+ techStack: answers.techStack || undefined,
51
+ context: answers.context || undefined,
52
+ tapdProjectId: answers.tapdProjectId || undefined,
53
+ };
54
+ }
55
+ // Command selection
56
+ const { enabledCommands } = await inquirer.prompt([
57
+ {
58
+ type: 'checkbox',
59
+ name: 'enabledCommands',
60
+ message: 'Enable commands:',
61
+ choices: [
62
+ { name: '/modus:init — Analyze project and build business Skills', value: 'init', checked: true },
63
+ { name: '/modus:vibe — Context-aware vibe coding', value: 'vibe', checked: true },
64
+ { name: '/modus:plan — Plan mode with Skill-backed context', value: 'plan', checked: true },
65
+ { name: '/modus:spec — OpenSpec-style spec-driven development', value: 'spec', checked: true },
66
+ { name: '/modus:harness — Full dual-loop multi-agent Harness', value: 'harness', checked: true },
67
+ ],
68
+ },
69
+ ]);
70
+ config.commands = { enabled: enabledCommands };
71
+ config.version = '1';
72
+ // Ensure modus/ dir exists
73
+ ensureDir(path.join(projectRoot, 'modus', 'specs'));
74
+ ensureDir(path.join(projectRoot, 'modus', 'changes'));
75
+ ensureDir(path.join(projectRoot, 'modus', 'plans'));
76
+ saveConfig(projectRoot, config);
77
+ console.log(chalk.green(' ✓ modus/config.yaml written'));
78
+ // Generate .codebuddy/ files
79
+ console.log(chalk.cyan('\n Generating CodeBuddy files...'));
80
+ generateCodeBuddyFiles(projectRoot, config);
81
+ const skillCount = 13; // 5 command skills + 8 harness agent skills
82
+ const cmdCount = enabledCommands.length;
83
+ console.log(chalk.green(` ✓ ${skillCount} skills → .codebuddy/skills/modus-*/SKILL.md`));
84
+ console.log(chalk.green(` ✓ ${cmdCount} commands → .codebuddy/commands/modus/*.md`));
85
+ console.log(chalk.bold('\n Ready! Open CodeBuddy and run:'));
86
+ console.log(chalk.yellow(' /modus:init') + ' — scan your codebase and build business Skills');
87
+ console.log(chalk.yellow(' /modus:vibe') + ' — start context-aware coding\n');
88
+ }
89
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runUpdate(projectRoot: string): Promise<void>;
2
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAMA,wBAAsB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlE"}
@@ -0,0 +1,19 @@
1
+ import chalk from 'chalk';
2
+ import { loadConfig } from '../utils/config.js';
3
+ import { generateCodeBuddyFiles } from '../generators/codebuddy.js';
4
+ import { fileExists } from '../utils/file-system.js';
5
+ import path from 'node:path';
6
+ export async function runUpdate(projectRoot) {
7
+ console.log(chalk.bold('\n Modus — update\n'));
8
+ const configPath = path.join(projectRoot, 'modus', 'config.yaml');
9
+ if (!fileExists(configPath)) {
10
+ console.error(chalk.red(' Error: Modus is not initialized. Run `modus init` first.'));
11
+ process.exit(1);
12
+ }
13
+ const config = loadConfig(projectRoot);
14
+ console.log(chalk.cyan(' Re-generating CodeBuddy files from latest templates...'));
15
+ generateCodeBuddyFiles(projectRoot, config);
16
+ console.log(chalk.green(' ✓ All skill and command files updated.'));
17
+ console.log(chalk.gray(' Tip: Restart CodeBuddy to pick up the new files.\n'));
18
+ }
19
+ //# sourceMappingURL=update.js.map
@@ -0,0 +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,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,WAAmB;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAClE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC,CAAC;QACvF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC,CAAC;IACpF,sBAAsB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC,CAAC;AAClF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ModusConfig } from '../utils/config.js';
2
+ export declare function generateCodeBuddyFiles(projectRoot: string, config: ModusConfig): void;
3
+ //# sourceMappingURL=codebuddy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebuddy.d.ts","sourceRoot":"","sources":["../../src/generators/codebuddy.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2CtD,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,IAAI,CAGN"}
@@ -0,0 +1,77 @@
1
+ // CodeBuddy-specific file generator.
2
+ // Writes SKILL.md files to .codebuddy/skills/modus-{name}/
3
+ // and command files to .codebuddy/commands/modus/{name}.md
4
+ import path from 'node:path';
5
+ import { writeFile, readTemplate } from '../utils/file-system.js';
6
+ const SKILLS_BASE = path.join('.codebuddy', 'skills');
7
+ const COMMANDS_BASE = path.join('.codebuddy', 'commands', 'modus');
8
+ /** All framework skills (non-business) that are always generated */
9
+ const FRAMEWORK_SKILLS = [
10
+ 'modus-init',
11
+ 'modus-vibe',
12
+ 'modus-plan',
13
+ 'modus-spec',
14
+ 'modus-harness',
15
+ 'modus-harness-00-skills-builder',
16
+ 'modus-harness-01-analysis',
17
+ 'modus-harness-02-dev',
18
+ 'modus-harness-03-test',
19
+ 'modus-harness-04-perf',
20
+ 'modus-harness-05-security',
21
+ 'modus-harness-06-review',
22
+ 'modus-harness-07-deploy',
23
+ ];
24
+ /** Map skill ID to template file path (relative to templates/skills/) */
25
+ const SKILL_TEMPLATE_MAP = {
26
+ 'modus-init': 'modus-init/SKILL.md',
27
+ 'modus-vibe': 'modus-vibe/SKILL.md',
28
+ 'modus-plan': 'modus-plan/SKILL.md',
29
+ 'modus-spec': 'modus-spec/SKILL.md',
30
+ 'modus-harness': 'modus-harness/SKILL.md',
31
+ 'modus-harness-00-skills-builder': 'modus-harness-agents/00-skills-builder/SKILL.md',
32
+ 'modus-harness-01-analysis': 'modus-harness-agents/01-analysis/SKILL.md',
33
+ 'modus-harness-02-dev': 'modus-harness-agents/02-dev/SKILL.md',
34
+ 'modus-harness-03-test': 'modus-harness-agents/03-test/SKILL.md',
35
+ 'modus-harness-04-perf': 'modus-harness-agents/04-perf/SKILL.md',
36
+ 'modus-harness-05-security': 'modus-harness-agents/05-security/SKILL.md',
37
+ 'modus-harness-06-review': 'modus-harness-agents/06-review/SKILL.md',
38
+ 'modus-harness-07-deploy': 'modus-harness-agents/07-deploy/SKILL.md',
39
+ };
40
+ const COMMAND_IDS = ['init', 'vibe', 'plan', 'spec', 'harness'];
41
+ export function generateCodeBuddyFiles(projectRoot, config) {
42
+ generateSkills(projectRoot, config);
43
+ generateCommands(projectRoot, config);
44
+ }
45
+ function generateSkills(projectRoot, config) {
46
+ for (const skillId of FRAMEWORK_SKILLS) {
47
+ const templatePath = `skills/${SKILL_TEMPLATE_MAP[skillId]}`;
48
+ let content;
49
+ try {
50
+ content = readTemplate(templatePath);
51
+ }
52
+ catch {
53
+ console.warn(` [warn] Template not found: ${templatePath}`);
54
+ continue;
55
+ }
56
+ const destPath = path.join(projectRoot, SKILLS_BASE, skillId, 'SKILL.md');
57
+ writeFile(destPath, content);
58
+ }
59
+ }
60
+ function generateCommands(projectRoot, config) {
61
+ const enabled = new Set(config.commands.enabled);
62
+ for (const cmdId of COMMAND_IDS) {
63
+ if (!enabled.has(cmdId))
64
+ continue;
65
+ let content;
66
+ try {
67
+ content = readTemplate(`commands/${cmdId}.md`);
68
+ }
69
+ catch {
70
+ console.warn(` [warn] Command template not found: ${cmdId}.md`);
71
+ continue;
72
+ }
73
+ const destPath = path.join(projectRoot, COMMANDS_BASE, `${cmdId}.md`);
74
+ writeFile(destPath, content);
75
+ }
76
+ }
77
+ //# sourceMappingURL=codebuddy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebuddy.js","sourceRoot":"","sources":["../../src/generators/codebuddy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './utils/file-system.js';
2
+ export * from './utils/config.js';
3
+ export * from './generators/codebuddy.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './utils/file-system.js';
2
+ export * from './utils/config.js';
3
+ export * from './generators/codebuddy.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface ModusConfig {
2
+ version: string;
3
+ commands: {
4
+ enabled: string[];
5
+ };
6
+ context?: string;
7
+ techStack?: string;
8
+ tapdProjectId?: string;
9
+ }
10
+ export declare function getConfigPath(projectRoot: string): string;
11
+ export declare function loadConfig(projectRoot: string): ModusConfig;
12
+ export declare function saveConfig(projectRoot: string, config: ModusConfig): void;
13
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAIA,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;CACxB;AASD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAK3D;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAIzE"}
@@ -0,0 +1,25 @@
1
+ import path from 'node:path';
2
+ import yaml from 'js-yaml';
3
+ import { fileExists, readFile, writeFile } from './file-system.js';
4
+ const DEFAULT_CONFIG = {
5
+ version: '1',
6
+ commands: {
7
+ enabled: ['init', 'vibe', 'plan', 'spec', 'harness'],
8
+ },
9
+ };
10
+ export function getConfigPath(projectRoot) {
11
+ return path.join(projectRoot, 'modus', 'config.yaml');
12
+ }
13
+ export function loadConfig(projectRoot) {
14
+ const configPath = getConfigPath(projectRoot);
15
+ if (!fileExists(configPath))
16
+ return { ...DEFAULT_CONFIG };
17
+ const raw = readFile(configPath);
18
+ return yaml.load(raw);
19
+ }
20
+ export function saveConfig(projectRoot, config) {
21
+ const configPath = getConfigPath(projectRoot);
22
+ const content = yaml.dump(config, { lineWidth: 120 });
23
+ writeFile(configPath, content);
24
+ }
25
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAYnE,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,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"}
@@ -0,0 +1,11 @@
1
+ export declare function ensureDir(dirPath: string): void;
2
+ export declare function writeFile(filePath: string, content: string): void;
3
+ export declare function readFile(filePath: string): string;
4
+ export declare function fileExists(filePath: string): boolean;
5
+ export declare function listDirs(dirPath: string): string[];
6
+ export declare function listFiles(dirPath: string, ext?: string): string[];
7
+ /** Find all modus business skill directories under .codebuddy/skills/ */
8
+ export declare function findBizSkillDirs(projectRoot: string): string[];
9
+ /** Read a template file bundled with the package */
10
+ export declare function readTemplate(templateRelPath: string): string;
11
+ //# sourceMappingURL=file-system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-system.d.ts","sourceRoot":"","sources":["../../src/utils/file-system.ts"],"names":[],"mappings":"AAGA,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAGjE;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAKlD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAMjE;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAG9D;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAG5D"}
@@ -0,0 +1,41 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export function ensureDir(dirPath) {
4
+ fs.mkdirSync(dirPath, { recursive: true });
5
+ }
6
+ export function writeFile(filePath, content) {
7
+ ensureDir(path.dirname(filePath));
8
+ fs.writeFileSync(filePath, content, 'utf-8');
9
+ }
10
+ export function readFile(filePath) {
11
+ return fs.readFileSync(filePath, 'utf-8');
12
+ }
13
+ export function fileExists(filePath) {
14
+ return fs.existsSync(filePath);
15
+ }
16
+ export function listDirs(dirPath) {
17
+ if (!fs.existsSync(dirPath))
18
+ return [];
19
+ return fs.readdirSync(dirPath, { withFileTypes: true })
20
+ .filter(d => d.isDirectory())
21
+ .map(d => d.name);
22
+ }
23
+ export function listFiles(dirPath, ext) {
24
+ if (!fs.existsSync(dirPath))
25
+ return [];
26
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true })
27
+ .filter(d => d.isFile())
28
+ .map(d => d.name);
29
+ return ext ? entries.filter(f => f.endsWith(ext)) : entries;
30
+ }
31
+ /** Find all modus business skill directories under .codebuddy/skills/ */
32
+ export function findBizSkillDirs(projectRoot) {
33
+ const skillsDir = path.join(projectRoot, '.codebuddy', 'skills');
34
+ return listDirs(skillsDir).filter(d => d.startsWith('modus-biz-'));
35
+ }
36
+ /** Read a template file bundled with the package */
37
+ export function readTemplate(templateRelPath) {
38
+ const templateBase = new URL('../../templates/', import.meta.url).pathname;
39
+ return readFile(path.join(templateBase, templateRelPath));
40
+ }
41
+ //# sourceMappingURL=file-system.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-system.js","sourceRoot":"","sources":["../../src/utils/file-system.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAe;IACzD,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClC,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,OAAO,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SACpD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,GAAY;IACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC7D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpB,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9D,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,YAAY,CAAC,eAAuB;IAClD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC3E,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;AAC5D,CAAC"}