foundruu 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -3
- package/dist/cli.js +61 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/mcp.d.ts +1 -0
- package/dist/commands/mcp.js +65 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/session.d.ts +2 -0
- package/dist/commands/session.js +13 -8
- package/dist/commands/session.js.map +1 -1
- package/dist/core/logger.d.ts +2 -0
- package/dist/core/logger.js +9 -4
- package/dist/core/logger.js.map +1 -1
- package/dist/core/plugins.d.ts +38 -0
- package/dist/core/plugins.js +58 -0
- package/dist/core/plugins.js.map +1 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -9,9 +9,13 @@ AI開発を標準化するためのプラットフォーム **FoundRuu** の CLI
|
|
|
9
9
|
## インストール
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
npm install -g foundruu # または npx foundruu <command>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
ソースから使う場合:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install && npm run build && npm link
|
|
15
19
|
```
|
|
16
20
|
|
|
17
21
|
## コマンド
|
|
@@ -25,6 +29,8 @@ npm link # foundruu コマンドとして使えるようにする
|
|
|
25
29
|
| `foundruu update [--force]` | Workflow / Prompt / Rules を最新へ更新 |
|
|
26
30
|
| `foundruu session start <name>` / `session list` | AI開発セッションの作成 / 一覧 |
|
|
27
31
|
| `foundruu templates` | 利用可能なテンプレート一覧 |
|
|
32
|
+
| `foundruu plugins` | 読み込まれているプラグイン一覧 |
|
|
33
|
+
| `foundruu mcp` | MCP サーバーを起動(AIエージェント連携) |
|
|
28
34
|
| `foundruu --help` / `--version` | ヘルプ / バージョン |
|
|
29
35
|
|
|
30
36
|
## 利用フロー
|
|
@@ -82,6 +88,35 @@ Docker / GitHub Actions / AI Rules / Workflow / Prompt / foundruu.json
|
|
|
82
88
|
`foundruu doctor --deep` は DevDoctor 由来の品質診断で、docs/(および最新の `.ai/sessions/`)の
|
|
83
89
|
要件・設計・テスト・AI指示ドキュメントをスコア化し、不足観点と改善案を提示します。
|
|
84
90
|
|
|
91
|
+
## MCP Server として使う
|
|
92
|
+
|
|
93
|
+
Claude Code 等の MCP クライアントに登録すると、AIエージェントが doctor / session / workflow / update をツールとして直接呼べます:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
claude mcp add foundruu -- npx foundruu mcp
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
公開ツール: `doctor` / `doctor_deep` / `session_start` / `session_list` / `workflow_install` / `update`
|
|
100
|
+
|
|
101
|
+
## プラグイン
|
|
102
|
+
|
|
103
|
+
`foundruu-plugin-*` という名前の npm パッケージを入れる(または `foundruu.json` の `plugins` にパスを書く)と自動で読み込まれ、コマンドと doctor チェックを拡張できます:
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
// foundruu-plugin-security/index.js
|
|
107
|
+
module.exports = {
|
|
108
|
+
name: "security",
|
|
109
|
+
register({ program, addDoctorCheck, log }) {
|
|
110
|
+
addDoctorCheck({
|
|
111
|
+
id: "security-md", label: "SECURITY.md", category: "セキュリティ",
|
|
112
|
+
severity: "warn", hint: "SECURITY.md を追加してください",
|
|
113
|
+
check: (ctx) => ctx.exists("SECURITY.md"),
|
|
114
|
+
});
|
|
115
|
+
program.command("audit").action(() => log.success("audit 実行"));
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
|
|
85
120
|
## GitHub Actions として使う
|
|
86
121
|
|
|
87
122
|
他リポジトリの PR チェックとして doctor を実行できます:
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
3
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
37
|
const commander_1 = require("commander");
|
|
5
38
|
const init_1 = require("./commands/init");
|
|
@@ -10,6 +43,8 @@ const session_1 = require("./commands/session");
|
|
|
10
43
|
const config_1 = require("./core/config");
|
|
11
44
|
const logger_1 = require("./core/logger");
|
|
12
45
|
const templates_1 = require("./registry/templates");
|
|
46
|
+
const plugins_1 = require("./core/plugins");
|
|
47
|
+
const checks_1 = require("./doctor/checks");
|
|
13
48
|
const program = new commander_1.Command();
|
|
14
49
|
program
|
|
15
50
|
.name("foundruu")
|
|
@@ -64,6 +99,13 @@ program
|
|
|
64
99
|
.action(async (opts) => {
|
|
65
100
|
await wrap(() => (0, update_1.runUpdate)(process.cwd(), opts));
|
|
66
101
|
});
|
|
102
|
+
program
|
|
103
|
+
.command("mcp")
|
|
104
|
+
.description("MCP サーバーを起動する(AIエージェントから doctor / session 等をツールとして利用)")
|
|
105
|
+
.action(async () => {
|
|
106
|
+
const { runMcpServer } = await Promise.resolve().then(() => __importStar(require("./commands/mcp")));
|
|
107
|
+
await wrap(() => runMcpServer(process.cwd()));
|
|
108
|
+
});
|
|
67
109
|
const session = program.command("session").description("AI開発セッションを管理する");
|
|
68
110
|
session
|
|
69
111
|
.command("start <name>")
|
|
@@ -85,5 +127,24 @@ program
|
|
|
85
127
|
logger_1.log.info(` ${t.id.padEnd(16)} ${t.label}${t.status === "planned" ? "(準備中)" : ""}`);
|
|
86
128
|
}
|
|
87
129
|
});
|
|
130
|
+
// プラグイン読み込み(コマンド・doctor チェックの拡張)
|
|
131
|
+
const loadedPlugins = (0, plugins_1.loadPlugins)(process.cwd(), {
|
|
132
|
+
program,
|
|
133
|
+
addDoctorCheck: (check) => checks_1.checks.push(check),
|
|
134
|
+
log: logger_1.log,
|
|
135
|
+
});
|
|
136
|
+
program
|
|
137
|
+
.command("plugins")
|
|
138
|
+
.description("読み込まれているプラグインを一覧表示する")
|
|
139
|
+
.action(() => {
|
|
140
|
+
if (loadedPlugins.length === 0) {
|
|
141
|
+
logger_1.log.info("プラグインは読み込まれていません。");
|
|
142
|
+
logger_1.log.info(" node_modules の foundruu-plugin-* または foundruu.json の plugins で追加できます。");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
for (const p of loadedPlugins) {
|
|
146
|
+
logger_1.log.info(` ${p.name.padEnd(24)} ${p.source}`);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
88
149
|
program.parse();
|
|
89
150
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runMcpServer(cwd: string): Promise<void>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runMcpServer = runMcpServer;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
9
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
const config_1 = require("../core/config");
|
|
12
|
+
const logger_1 = require("../core/logger");
|
|
13
|
+
const runner_1 = require("../doctor/runner");
|
|
14
|
+
const deep_1 = require("../doctor/deep");
|
|
15
|
+
const workflow_1 = require("./workflow");
|
|
16
|
+
const session_1 = require("./session");
|
|
17
|
+
const update_1 = require("./update");
|
|
18
|
+
/**
|
|
19
|
+
* FoundRuu MCP Server(stdio)。
|
|
20
|
+
* Claude Code / Codex 等の AI エージェントが doctor / session / workflow / update を
|
|
21
|
+
* ツールとして直接呼べるようにする。
|
|
22
|
+
*
|
|
23
|
+
* 登録例(Claude Code):
|
|
24
|
+
* claude mcp add foundruu -- npx foundruu mcp
|
|
25
|
+
*/
|
|
26
|
+
const resolveDir = (base, dir) => dir ? path_1.default.resolve(base, dir) : base;
|
|
27
|
+
const text = (value) => ({
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: typeof value === "string" ? value : JSON.stringify(value, null, 2),
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
async function runMcpServer(cwd) {
|
|
36
|
+
// stdout は JSON-RPC 専用。CLI ログはすべて stderr へ
|
|
37
|
+
logger_1.log.useStderr();
|
|
38
|
+
const server = new mcp_js_1.McpServer({ name: "foundruu", version: (0, config_1.cliVersion)() });
|
|
39
|
+
const dirSchema = zod_1.z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("対象ディレクトリ(省略時はサーバー起動ディレクトリ)");
|
|
43
|
+
server.tool("doctor", "リポジトリがAI開発可能な状態か診断する(README / AI Rules / Workflow 等の健全性チェック)", { directory: dirSchema }, async ({ directory }) => text((0, runner_1.runDoctor)(resolveDir(cwd, directory))));
|
|
44
|
+
server.tool("doctor_deep", "docs/ と git 差分から AI開発プロセスの品質(要件/設計/テスト/AI指示)をスコア診断する", { directory: dirSchema, since: zod_1.z.string().optional().describe("差分比較基準(デフォルト main)") }, async ({ directory, since }) => text((0, deep_1.runDeepDoctor)(resolveDir(cwd, directory), since ?? "main")));
|
|
45
|
+
server.tool("session_start", "AI開発セッションを作成する(.ai/sessions/<name>/ に requirements/design/tasks 等を生成)", { name: zod_1.z.string().describe("セッション名(英数字・ハイフン)"), directory: dirSchema }, async ({ name, directory }) => {
|
|
46
|
+
(0, session_1.startSession)(resolveDir(cwd, directory), name);
|
|
47
|
+
return text(`セッション .ai/sessions/${name}/ を作成しました。requirements.md に要件を書き、.ai/prompts/session-workflow.md のルールに従って進めてください。`);
|
|
48
|
+
});
|
|
49
|
+
server.tool("session_list", "既存のAI開発セッションを一覧する", { directory: dirSchema }, async ({ directory }) => text({ sessions: (0, session_1.sessionNames)(resolveDir(cwd, directory)) }));
|
|
50
|
+
server.tool("workflow_install", "Workflow / Prompt / Rules(.ai/)をリポジトリへ導入する", { directory: dirSchema }, async ({ directory }) => {
|
|
51
|
+
(0, workflow_1.installWorkflow)(resolveDir(cwd, directory));
|
|
52
|
+
return text("Workflow を導入しました(.ai/prompts, .ai/workflows, .ai/templates/session)。");
|
|
53
|
+
});
|
|
54
|
+
server.tool("update", "Workflow / Prompt / Rules を最新へ更新する(ユーザー編集済みファイルは保護される)", {
|
|
55
|
+
directory: dirSchema,
|
|
56
|
+
diff: zod_1.z.boolean().optional().describe("true なら差分確認のみで書き込まない"),
|
|
57
|
+
}, async ({ directory, diff }) => {
|
|
58
|
+
(0, update_1.runUpdate)(resolveDir(cwd, directory), { diff });
|
|
59
|
+
return text(diff ? "差分を確認しました(stderr ログ参照)。" : "更新を実行しました。");
|
|
60
|
+
});
|
|
61
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
62
|
+
await server.connect(transport);
|
|
63
|
+
logger_1.log.info(`foundruu MCP server v${(0, config_1.cliVersion)()} started (stdio)`);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
/** .ai を持つリポジトリルートを特定する(git toplevel 優先、なければ上方向へ探索) */
|
|
6
6
|
export declare function findAiRoot(cwd: string): string | null;
|
|
7
7
|
export declare function startSession(cwd: string, name: string): void;
|
|
8
|
+
/** 既存セッション名の一覧を返す(MCP からも利用) */
|
|
9
|
+
export declare function sessionNames(cwd: string): string[];
|
|
8
10
|
export declare function listSessions(cwd: string): void;
|
package/dist/commands/session.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.findAiRoot = findAiRoot;
|
|
7
7
|
exports.startSession = startSession;
|
|
8
|
+
exports.sessionNames = sessionNames;
|
|
8
9
|
exports.listSessions = listSessions;
|
|
9
10
|
const child_process_1 = require("child_process");
|
|
10
11
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -73,16 +74,20 @@ function startSession(cwd, name) {
|
|
|
73
74
|
logger_1.log.info(" 2. AI に .ai/prompts/session-workflow.md と requirements.md を渡す");
|
|
74
75
|
logger_1.log.info(" 3. AI が「進める / 質問する」を判断します");
|
|
75
76
|
}
|
|
76
|
-
|
|
77
|
+
/** 既存セッション名の一覧を返す(MCP からも利用) */
|
|
78
|
+
function sessionNames(cwd) {
|
|
77
79
|
const root = requireAiRoot(cwd);
|
|
78
80
|
const sessionsDir = path_1.default.join(root, ".ai", "sessions");
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
if (!fs_1.default.existsSync(sessionsDir))
|
|
82
|
+
return [];
|
|
83
|
+
return fs_1.default
|
|
84
|
+
.readdirSync(sessionsDir, { withFileTypes: true })
|
|
85
|
+
.filter((e) => e.isDirectory())
|
|
86
|
+
.map((e) => e.name)
|
|
87
|
+
.sort();
|
|
88
|
+
}
|
|
89
|
+
function listSessions(cwd) {
|
|
90
|
+
const sessions = sessionNames(cwd);
|
|
86
91
|
if (sessions.length === 0) {
|
|
87
92
|
logger_1.log.info("セッションはまだありません。");
|
|
88
93
|
logger_1.log.info(" 作成: foundruu session start <session-name>");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":";;;;;AAWA,gCAgBC;AAYD,oCAiCC;AAED,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"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"}
|
package/dist/core/logger.d.ts
CHANGED
package/dist/core/logger.js
CHANGED
|
@@ -5,11 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.log = void 0;
|
|
7
7
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
8
|
+
let out = (msg) => console.log(msg);
|
|
8
9
|
exports.log = {
|
|
9
|
-
info: (msg) =>
|
|
10
|
-
step: (msg) =>
|
|
11
|
-
success: (msg) =>
|
|
12
|
-
warn: (msg) =>
|
|
10
|
+
info: (msg) => out(msg),
|
|
11
|
+
step: (msg) => out(picocolors_1.default.cyan(`▸ ${msg}`)),
|
|
12
|
+
success: (msg) => out(picocolors_1.default.green(`✔ ${msg}`)),
|
|
13
|
+
warn: (msg) => out(picocolors_1.default.yellow(`⚠ ${msg}`)),
|
|
13
14
|
error: (msg) => console.error(picocolors_1.default.red(`✖ ${msg}`)),
|
|
15
|
+
/** MCP(stdio) 等、stdout をプロトコルに使うモードでログを stderr へ逃がす */
|
|
16
|
+
useStderr: () => {
|
|
17
|
+
out = (msg) => console.error(msg);
|
|
18
|
+
},
|
|
14
19
|
};
|
|
15
20
|
//# sourceMappingURL=logger.js.map
|
package/dist/core/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":";;;;;;AAAA,4DAA4B;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":";;;;;;AAAA,4DAA4B;AAE5B,IAAI,GAAG,GAA0B,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE9C,QAAA,GAAG,GAAG;IACjB,IAAI,EAAE,CAAC,GAAW,EAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;IACrC,IAAI,EAAE,CAAC,GAAW,EAAQ,EAAE,CAAC,GAAG,CAAC,oBAAE,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACrD,OAAO,EAAE,CAAC,GAAW,EAAQ,EAAE,CAAC,GAAG,CAAC,oBAAE,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACzD,IAAI,EAAE,CAAC,GAAW,EAAQ,EAAE,CAAC,GAAG,CAAC,oBAAE,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACvD,KAAK,EAAE,CAAC,GAAW,EAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAE,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAC/D,uDAAuD;IACvD,SAAS,EAAE,GAAS,EAAE;QACpB,GAAG,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { DoctorCheck } from "../doctor/types";
|
|
3
|
+
import { log } from "./logger";
|
|
4
|
+
/**
|
|
5
|
+
* プラグインシステム。
|
|
6
|
+
*
|
|
7
|
+
* 読み込み対象:
|
|
8
|
+
* 1. プロジェクトの node_modules にある `foundruu-plugin-*` / `@scope/foundruu-plugin-*`
|
|
9
|
+
* 2. foundruu.json の `plugins` 配列(モジュール名 or 相対パス)
|
|
10
|
+
*
|
|
11
|
+
* プラグインは register(ctx) でコマンド追加・doctor チェック追加ができる:
|
|
12
|
+
*
|
|
13
|
+
* module.exports = {
|
|
14
|
+
* name: "my-plugin",
|
|
15
|
+
* register({ program, addDoctorCheck }) {
|
|
16
|
+
* program.command("hello").action(() => console.log("hi"));
|
|
17
|
+
* addDoctorCheck({ id: "...", label: "...", category: "...",
|
|
18
|
+
* severity: "warn", hint: "...", check: (ctx) => true });
|
|
19
|
+
* },
|
|
20
|
+
* };
|
|
21
|
+
*/
|
|
22
|
+
export interface PluginContext {
|
|
23
|
+
program: Command;
|
|
24
|
+
addDoctorCheck(check: DoctorCheck): void;
|
|
25
|
+
log: typeof log;
|
|
26
|
+
}
|
|
27
|
+
export interface FoundruuPlugin {
|
|
28
|
+
name: string;
|
|
29
|
+
register(ctx: PluginContext): void;
|
|
30
|
+
}
|
|
31
|
+
export interface LoadedPlugin {
|
|
32
|
+
name: string;
|
|
33
|
+
source: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* プラグインを発見して register を呼ぶ。壊れたプラグインは警告してスキップする。
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadPlugins(cwd: string, ctx: PluginContext): LoadedPlugin[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadPlugins = loadPlugins;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const config_1 = require("./config");
|
|
10
|
+
const logger_1 = require("./logger");
|
|
11
|
+
const PLUGIN_PREFIX = "foundruu-plugin-";
|
|
12
|
+
function discoverNodeModules(cwd) {
|
|
13
|
+
const nm = path_1.default.join(cwd, "node_modules");
|
|
14
|
+
if (!fs_1.default.existsSync(nm))
|
|
15
|
+
return [];
|
|
16
|
+
const found = [];
|
|
17
|
+
for (const entry of fs_1.default.readdirSync(nm, { withFileTypes: true })) {
|
|
18
|
+
if (entry.name.startsWith(PLUGIN_PREFIX)) {
|
|
19
|
+
found.push(path_1.default.join(nm, entry.name));
|
|
20
|
+
}
|
|
21
|
+
else if (entry.name.startsWith("@") && entry.isDirectory()) {
|
|
22
|
+
for (const scoped of fs_1.default.readdirSync(path_1.default.join(nm, entry.name))) {
|
|
23
|
+
if (scoped.startsWith(PLUGIN_PREFIX))
|
|
24
|
+
found.push(path_1.default.join(nm, entry.name, scoped));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return found;
|
|
29
|
+
}
|
|
30
|
+
function configuredPlugins(cwd) {
|
|
31
|
+
const config = (0, config_1.readConfig)(cwd);
|
|
32
|
+
return (config?.plugins ?? []).map((p) => p.startsWith(".") || p.startsWith("/") ? path_1.default.resolve(cwd, p) : path_1.default.join(cwd, "node_modules", p));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* プラグインを発見して register を呼ぶ。壊れたプラグインは警告してスキップする。
|
|
36
|
+
*/
|
|
37
|
+
function loadPlugins(cwd, ctx) {
|
|
38
|
+
const specs = [...new Set([...discoverNodeModules(cwd), ...configuredPlugins(cwd)])];
|
|
39
|
+
const loaded = [];
|
|
40
|
+
for (const spec of specs) {
|
|
41
|
+
try {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
43
|
+
const mod = require(spec);
|
|
44
|
+
const plugin = ("default" in mod ? mod.default : mod);
|
|
45
|
+
if (!plugin?.name || typeof plugin.register !== "function") {
|
|
46
|
+
logger_1.log.warn(`プラグインの形式が不正です(name / register が必要): ${spec}`);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
plugin.register(ctx);
|
|
50
|
+
loaded.push({ name: plugin.name, source: spec });
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
logger_1.log.warn(`プラグインの読み込みに失敗しました: ${spec} (${err.message})`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return loaded;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/core/plugins.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "foundruu",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "FoundRuu CLI - AI開発を標準化するためのプラットフォームCLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@inquirer/prompts": "^7.10.1",
|
|
24
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
24
25
|
"commander": "^12.1.0",
|
|
25
26
|
"handlebars": "^4.7.8",
|
|
26
|
-
"picocolors": "^1.1.0"
|
|
27
|
+
"picocolors": "^1.1.0",
|
|
28
|
+
"zod": "^4.4.3"
|
|
27
29
|
},
|
|
28
30
|
"devDependencies": {
|
|
29
31
|
"@types/node": "^20.14.0",
|