foundruu 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.
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/assets/templates/ai/_common/company/coding-standard.md +35 -0
- package/assets/templates/ai/_common/company/git-workflow.md +40 -0
- package/assets/templates/ai/_common/company/review-policy.md +30 -0
- package/assets/templates/ai/_common/company/security.md +25 -0
- package/assets/templates/ai/_common/project/architecture.md.hbs +29 -0
- package/assets/templates/ai/_common/project/conventions.md +24 -0
- package/assets/templates/ai/_common/project/overview.md.hbs +37 -0
- package/assets/templates/ai/_common/project/testing.md +32 -0
- package/assets/templates/ai/claude/CLAUDE.md.hbs +65 -0
- package/assets/templates/ai/codex/CODEX.md.hbs +60 -0
- package/assets/templates/base/.env.example +4 -0
- package/assets/templates/base/README.md.hbs +73 -0
- package/assets/templates/features/discord/.env.example.patch +3 -0
- package/assets/templates/features/discord/package.json.patch +5 -0
- package/assets/templates/features/docker/Dockerfile.hbs +38 -0
- package/assets/templates/features/docker/docker-compose.yml.hbs +11 -0
- package/assets/templates/features/eslint/eslint.config.js +14 -0
- package/assets/templates/features/eslint/package.json.patch +11 -0
- package/assets/templates/features/github-actions/.github/workflows/ci.yml.hbs +51 -0
- package/assets/templates/features/lark/.env.example.patch +3 -0
- package/assets/templates/features/lark/package.json.patch +5 -0
- package/assets/templates/features/line-bot/.env.example.patch +2 -0
- package/assets/templates/features/line-bot/package.json.patch +5 -0
- package/assets/templates/features/prettier/.prettierignore +3 -0
- package/assets/templates/features/prettier/.prettierrc +7 -0
- package/assets/templates/features/prettier/package.json.patch +9 -0
- package/assets/templates/features/react/index.html.hbs +12 -0
- package/assets/templates/features/react/package.json.patch +17 -0
- package/assets/templates/features/react/src/web/App.tsx.hbs +8 -0
- package/assets/templates/features/react/src/web/main.tsx +9 -0
- package/assets/templates/features/react/vite.config.ts +6 -0
- package/assets/templates/features/react-laravel/package.json.patch +19 -0
- package/assets/templates/features/react-laravel/resources/js/app.jsx.hbs +17 -0
- package/assets/templates/features/react-laravel/vite.config.js +13 -0
- package/assets/templates/features/vitest/package.json.patch +10 -0
- package/assets/templates/features/vitest/tests/index.test.ts.hbs +7 -0
- package/assets/templates/features/vitest/vitest.config.ts +11 -0
- package/assets/templates/languages/laravel/.env.example.patch +12 -0
- package/assets/templates/languages/laravel/composer.json.hbs +41 -0
- package/assets/templates/languages/laravel/docs/SETUP.md.hbs +24 -0
- package/assets/templates/languages/typescript/package.json.patch +20 -0
- package/assets/templates/languages/typescript/src/index.ts.hbs +1 -0
- package/assets/templates/languages/typescript/tsconfig.json +17 -0
- package/assets/workflow/.ai/prompts/session-workflow.md +72 -0
- package/assets/workflow/.ai/templates/session/design.md +21 -0
- package/assets/workflow/.ai/templates/session/questions.md +34 -0
- package/assets/workflow/.ai/templates/session/requirements.md +25 -0
- package/assets/workflow/.ai/templates/session/summary.md +21 -0
- package/assets/workflow/.ai/templates/session/tasks.md +13 -0
- package/assets/workflow/.ai/templates/session/test.md +15 -0
- package/assets/workflow/.ai/workflows/bugfix.md +19 -0
- package/assets/workflow/.ai/workflows/development.md +27 -0
- package/assets/workflow/.ai/workflows/feature.md +20 -0
- package/assets/workflow/.ai/workflows/review.md +19 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +89 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/doctor.d.ts +6 -0
- package/dist/commands/doctor.js +64 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.js +94 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/session.d.ts +8 -0
- package/dist/commands/session.js +96 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/update.d.ts +13 -0
- package/dist/commands/update.js +64 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/workflow.d.ts +7 -0
- package/dist/commands/workflow.js +64 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/core/assets.d.ts +8 -0
- package/dist/core/assets.js +29 -0
- package/dist/core/assets.js.map +1 -0
- package/dist/core/config.d.ts +17 -0
- package/dist/core/config.js +31 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/copier.d.ts +25 -0
- package/dist/core/copier.js +103 -0
- package/dist/core/copier.js.map +1 -0
- package/dist/core/fetcher.d.ts +10 -0
- package/dist/core/fetcher.js +56 -0
- package/dist/core/fetcher.js.map +1 -0
- package/dist/core/logger.d.ts +7 -0
- package/dist/core/logger.js +15 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/sync.d.ts +26 -0
- package/dist/core/sync.js +69 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/doctor/checks.d.ts +5 -0
- package/dist/doctor/checks.js +97 -0
- package/dist/doctor/checks.js.map +1 -0
- package/dist/doctor/deep.d.ts +39 -0
- package/dist/doctor/deep.js +144 -0
- package/dist/doctor/deep.js.map +1 -0
- package/dist/doctor/rc.d.ts +13 -0
- package/dist/doctor/rc.js +31 -0
- package/dist/doctor/rc.js.map +1 -0
- package/dist/doctor/runner.d.ts +3 -0
- package/dist/doctor/runner.js +39 -0
- package/dist/doctor/runner.js.map +1 -0
- package/dist/doctor/types.d.ts +32 -0
- package/dist/doctor/types.js +3 -0
- package/dist/doctor/types.js.map +1 -0
- package/dist/registry/templates.d.ts +18 -0
- package/dist/registry/templates.js +45 -0
- package/dist/registry/templates.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Review Workflow
|
|
2
|
+
|
|
3
|
+
コードレビュー(人間 / AI)のフロー。
|
|
4
|
+
|
|
5
|
+
## ステップ
|
|
6
|
+
|
|
7
|
+
1. **コンテキスト把握** — 要件(`requirements.md`)・設計(`design.md`)と差分を突き合わせる
|
|
8
|
+
2. **正しさ** — 要件を満たしているか、異常系・境界値・権限・競合状態に問題がないか
|
|
9
|
+
3. **影響範囲** — 既存機能・DBスキーマ・API互換性への影響が設計どおりか
|
|
10
|
+
4. **品質** — 既存の規約・アーキテクチャに沿っているか、重複・過剰な複雑さがないか
|
|
11
|
+
5. **テスト** — テストが観点(正常系 / 異常系 / 境界値 / 既存影響)を網羅しているか
|
|
12
|
+
6. **セキュリティ** — 入力検証、認証・認可、秘密情報のハードコード、インジェクション
|
|
13
|
+
7. **指摘** — 重要度順(blocker / should / nit)に、理由と修正案をセットで書く
|
|
14
|
+
|
|
15
|
+
## ルール
|
|
16
|
+
|
|
17
|
+
- 指摘には必ず「なぜ問題か」と「どう直すか」を添える
|
|
18
|
+
- 好みの問題(nit)と修正必須(blocker)を明確に区別する
|
|
19
|
+
- 差分に現れないが影響を受ける箇所(呼び出し元・設定・ドキュメント)も確認する
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const init_1 = require("./commands/init");
|
|
6
|
+
const workflow_1 = require("./commands/workflow");
|
|
7
|
+
const doctor_1 = require("./commands/doctor");
|
|
8
|
+
const update_1 = require("./commands/update");
|
|
9
|
+
const session_1 = require("./commands/session");
|
|
10
|
+
const config_1 = require("./core/config");
|
|
11
|
+
const logger_1 = require("./core/logger");
|
|
12
|
+
const templates_1 = require("./registry/templates");
|
|
13
|
+
const program = new commander_1.Command();
|
|
14
|
+
program
|
|
15
|
+
.name("foundruu")
|
|
16
|
+
.description("FoundRuu CLI — AI開発を標準化するためのプラットフォーム")
|
|
17
|
+
.version((0, config_1.cliVersion)());
|
|
18
|
+
const wrap = async (fn) => {
|
|
19
|
+
try {
|
|
20
|
+
await fn();
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
// Ctrl+C でプロンプトを中断した場合は静かに終了する
|
|
24
|
+
if (err.name === "ExitPromptError") {
|
|
25
|
+
process.exitCode = 130;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
logger_1.log.error(err.message);
|
|
29
|
+
process.exitCode = 1;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
program
|
|
33
|
+
.command("init")
|
|
34
|
+
.description("AI開発環境(テンプレート / Workflow / Rules / Doctor設定)を一括導入する")
|
|
35
|
+
.option("-t, --template <id>", "使用するテンプレートID(未指定なら対話で選択)")
|
|
36
|
+
.option("-n, --name <name>", "プロジェクト名(デフォルト: ディレクトリ名)")
|
|
37
|
+
.option("-d, --description <text>", "プロジェクトの説明")
|
|
38
|
+
.option("-y, --yes", "対話プロンプトを出さずデフォルト値で実行する")
|
|
39
|
+
.action(async (opts) => {
|
|
40
|
+
await wrap(() => (0, init_1.runInit)(process.cwd(), opts));
|
|
41
|
+
});
|
|
42
|
+
const workflow = program.command("workflow").description("Workflow / Prompt / Rules を管理する");
|
|
43
|
+
workflow
|
|
44
|
+
.command("install")
|
|
45
|
+
.description("Workflow / Prompt / Rules(.ai/)のみを既存リポジトリへ導入する")
|
|
46
|
+
.action(() => {
|
|
47
|
+
wrap(() => (0, workflow_1.installWorkflow)(process.cwd()));
|
|
48
|
+
});
|
|
49
|
+
program
|
|
50
|
+
.command("doctor")
|
|
51
|
+
.description("リポジトリがAI開発可能な状態か診断する(.foundruurc でカスタマイズ可能)")
|
|
52
|
+
.option("--json", "JSON形式で出力する")
|
|
53
|
+
.option("--deep", "docs/ と git 差分から AI開発プロセスの品質をスコア診断する")
|
|
54
|
+
.option("--since <ref>", "--deep の差分比較基準", "main")
|
|
55
|
+
.action(async (opts) => {
|
|
56
|
+
await wrap(() => (0, doctor_1.runDoctorCommand)(process.cwd(), opts));
|
|
57
|
+
});
|
|
58
|
+
program
|
|
59
|
+
.command("update")
|
|
60
|
+
.description("Workflow / Prompt / Rules を最新へ更新する(GitHub から取得、失敗時は同梱アセット)")
|
|
61
|
+
.option("-f, --force", "ユーザー編集済みファイルも上書きする")
|
|
62
|
+
.option("--diff", "差分の表示のみで書き込まない")
|
|
63
|
+
.option("--local", "GitHub から取得せず CLI 同梱アセットを使う")
|
|
64
|
+
.action(async (opts) => {
|
|
65
|
+
await wrap(() => (0, update_1.runUpdate)(process.cwd(), opts));
|
|
66
|
+
});
|
|
67
|
+
const session = program.command("session").description("AI開発セッションを管理する");
|
|
68
|
+
session
|
|
69
|
+
.command("start <name>")
|
|
70
|
+
.description("セッション作業ファイル一式を .ai/sessions/<name>/ に作成する")
|
|
71
|
+
.action(async (name) => {
|
|
72
|
+
await wrap(() => (0, session_1.startSession)(process.cwd(), name));
|
|
73
|
+
});
|
|
74
|
+
session
|
|
75
|
+
.command("list")
|
|
76
|
+
.description("既存セッションを一覧表示する")
|
|
77
|
+
.action(async () => {
|
|
78
|
+
await wrap(() => (0, session_1.listSessions)(process.cwd()));
|
|
79
|
+
});
|
|
80
|
+
program
|
|
81
|
+
.command("templates")
|
|
82
|
+
.description("利用可能なテンプレートを一覧表示する")
|
|
83
|
+
.action(() => {
|
|
84
|
+
for (const t of templates_1.templates) {
|
|
85
|
+
logger_1.log.info(` ${t.id.padEnd(16)} ${t.label}${t.status === "planned" ? "(準備中)" : ""}`);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
program.parse();
|
|
89
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
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.runDoctorCommand = runDoctorCommand;
|
|
7
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
8
|
+
const runner_1 = require("../doctor/runner");
|
|
9
|
+
const deep_1 = require("../doctor/deep");
|
|
10
|
+
const logger_1 = require("../core/logger");
|
|
11
|
+
function scoreColor(score) {
|
|
12
|
+
return score >= 80 ? picocolors_1.default.green : score >= 50 ? picocolors_1.default.yellow : picocolors_1.default.red;
|
|
13
|
+
}
|
|
14
|
+
function runDeep(cwd, options) {
|
|
15
|
+
const report = (0, deep_1.runDeepDoctor)(cwd, options.since ?? "main");
|
|
16
|
+
if (options.json) {
|
|
17
|
+
console.log(JSON.stringify(report, null, 2));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
logger_1.log.info(picocolors_1.default.bold("FoundRuu Doctor --deep — AI開発プロセス品質診断\n"));
|
|
21
|
+
logger_1.log.info(`差分(${report.since} 基準): ${report.diff.files}ファイル +${report.diff.insertions} -${report.diff.deletions}\n`);
|
|
22
|
+
for (const s of report.scores) {
|
|
23
|
+
const color = scoreColor(s.score);
|
|
24
|
+
const bar = "█".repeat(Math.round(s.score / 10)).padEnd(10, "░");
|
|
25
|
+
logger_1.log.info(`${color(bar)} ${String(s.score).padStart(3)}点 ${s.label}${s.docPath ? picocolors_1.default.dim(`(${s.docPath})`) : ""}`);
|
|
26
|
+
for (const f of s.failed) {
|
|
27
|
+
logger_1.log.info(picocolors_1.default.dim(` - ${f.label} → ${f.improvement}`));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
logger_1.log.info("");
|
|
31
|
+
logger_1.log.info(`総合スコア: ${scoreColor(report.overall)(picocolors_1.default.bold(`${report.overall}点`))}`);
|
|
32
|
+
}
|
|
33
|
+
function runDoctorCommand(cwd, options) {
|
|
34
|
+
if (options.deep) {
|
|
35
|
+
runDeep(cwd, options);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const report = (0, runner_1.runDoctor)(cwd);
|
|
39
|
+
if (options.json) {
|
|
40
|
+
console.log(JSON.stringify(report, null, 2));
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
logger_1.log.info(picocolors_1.default.bold("FoundRuu Doctor — リポジトリ健全性診断\n"));
|
|
44
|
+
let currentCategory = "";
|
|
45
|
+
for (const r of report.results) {
|
|
46
|
+
if (r.category !== currentCategory) {
|
|
47
|
+
currentCategory = r.category;
|
|
48
|
+
logger_1.log.info(picocolors_1.default.bold(`[${currentCategory}]`));
|
|
49
|
+
}
|
|
50
|
+
const mark = r.status === "pass" ? picocolors_1.default.green("✔") : r.status === "warn" ? picocolors_1.default.yellow("⚠") : picocolors_1.default.red("✖");
|
|
51
|
+
logger_1.log.info(` ${mark} ${r.label}`);
|
|
52
|
+
if (r.hint)
|
|
53
|
+
logger_1.log.info(picocolors_1.default.dim(` → ${r.hint}`));
|
|
54
|
+
}
|
|
55
|
+
logger_1.log.info("");
|
|
56
|
+
logger_1.log.info(`結果: ${picocolors_1.default.green(`${report.passed} pass`)} / ${picocolors_1.default.yellow(`${report.warned} warn`)} / ${picocolors_1.default.red(`${report.failed} fail`)}`);
|
|
57
|
+
logger_1.log.info(report.ok
|
|
58
|
+
? picocolors_1.default.green("AIが安全に開発できる状態です。")
|
|
59
|
+
: picocolors_1.default.red("AI開発を始める前に fail 項目の解消を推奨します。"));
|
|
60
|
+
}
|
|
61
|
+
if (!report.ok)
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
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.runInit = runInit;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const assets_1 = require("../core/assets");
|
|
10
|
+
const config_1 = require("../core/config");
|
|
11
|
+
const copier_1 = require("../core/copier");
|
|
12
|
+
const logger_1 = require("../core/logger");
|
|
13
|
+
const templates_1 = require("../registry/templates");
|
|
14
|
+
const workflow_1 = require("./workflow");
|
|
15
|
+
/** --template 未指定かつ TTY のとき、対話で不足オプションを埋める */
|
|
16
|
+
async function promptMissing(cwd, options) {
|
|
17
|
+
const interactive = process.stdin.isTTY && !options.yes && !options.template;
|
|
18
|
+
if (!interactive)
|
|
19
|
+
return options;
|
|
20
|
+
// @inquirer/prompts は ESM 専用。CommonJS ビルドで tsc が import() を require() へ
|
|
21
|
+
// 変換しないよう、動的 import を明示的に保持する
|
|
22
|
+
const importEsm = new Function("specifier", "return import(specifier)");
|
|
23
|
+
const { select, input } = await importEsm("@inquirer/prompts");
|
|
24
|
+
const template = await select({
|
|
25
|
+
message: "テンプレートを選択してください",
|
|
26
|
+
choices: templates_1.templates.map((t) => ({
|
|
27
|
+
name: `${t.label}${t.status === "planned" ? "(準備中)" : ""}`,
|
|
28
|
+
value: t.id,
|
|
29
|
+
disabled: t.status === "planned" ? "(準備中)" : false,
|
|
30
|
+
})),
|
|
31
|
+
default: templates_1.DEFAULT_TEMPLATE,
|
|
32
|
+
});
|
|
33
|
+
const name = options.name ?? (await input({ message: "プロジェクト名", default: path_1.default.basename(cwd) }));
|
|
34
|
+
const description = options.description ?? (await input({ message: "プロジェクトの説明(任意)" }));
|
|
35
|
+
return { ...options, template, name, description };
|
|
36
|
+
}
|
|
37
|
+
async function runInit(cwd, rawOptions) {
|
|
38
|
+
const options = await promptMissing(cwd, rawOptions);
|
|
39
|
+
const templateId = options.template ?? templates_1.DEFAULT_TEMPLATE;
|
|
40
|
+
const template = (0, templates_1.findTemplate)(templateId);
|
|
41
|
+
if (!template) {
|
|
42
|
+
const available = templates_1.templates.map((t) => `${t.id}${t.status === "planned" ? " (準備中)" : ""}`).join(", ");
|
|
43
|
+
throw new Error(`テンプレート "${templateId}" は存在しません。利用可能: ${available}`);
|
|
44
|
+
}
|
|
45
|
+
if (template.status === "planned") {
|
|
46
|
+
throw new Error(`テンプレート "${templateId}" は準備中です。現在利用可能なテンプレート: ` +
|
|
47
|
+
templates_1.templates.filter((t) => t.status === "available").map((t) => t.id).join(", "));
|
|
48
|
+
}
|
|
49
|
+
const ctx = {
|
|
50
|
+
projectName: options.name ?? path_1.default.basename(cwd),
|
|
51
|
+
description: options.description ?? "",
|
|
52
|
+
language: template.language,
|
|
53
|
+
languageLabel: template.languageLabel,
|
|
54
|
+
aiProviders: template.aiProviders,
|
|
55
|
+
aiProviderLabels: template.aiProviders,
|
|
56
|
+
features: template.features,
|
|
57
|
+
featureLabels: template.features,
|
|
58
|
+
year: new Date().getFullYear(),
|
|
59
|
+
};
|
|
60
|
+
const root = (0, assets_1.templatesRoot)();
|
|
61
|
+
let written = 0;
|
|
62
|
+
// 合成順: base → language → features → ai(共通 + プロバイダー別)
|
|
63
|
+
const layers = [
|
|
64
|
+
path_1.default.join(root, "base"),
|
|
65
|
+
path_1.default.join(root, "languages", template.language),
|
|
66
|
+
...template.features.map((f) => path_1.default.join(root, "features", f)),
|
|
67
|
+
path_1.default.join(root, "ai", "_common"),
|
|
68
|
+
...template.aiProviders.map((p) => path_1.default.join(root, "ai", p)),
|
|
69
|
+
];
|
|
70
|
+
for (const layer of layers) {
|
|
71
|
+
if (!fs_1.default.existsSync(layer)) {
|
|
72
|
+
logger_1.log.warn(`テンプレートレイヤーが見つからないためスキップ: ${path_1.default.relative(root, layer)}`);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
// ai/_common は docs/ai 配下へ、それ以外はルートへ展開
|
|
76
|
+
const dest = layer === path_1.default.join(root, "ai", "_common") ? path_1.default.join(cwd, "docs", "ai") : cwd;
|
|
77
|
+
const result = (0, copier_1.copyTree)(layer, dest, ctx);
|
|
78
|
+
written += result.written.length;
|
|
79
|
+
}
|
|
80
|
+
// Workflow / Prompt / Rules / Doctor設定も一括導入
|
|
81
|
+
(0, workflow_1.installWorkflow)(cwd, { overwrite: false });
|
|
82
|
+
const config = (0, config_1.readConfig)(cwd) ?? { version: (0, config_1.cliVersion)() };
|
|
83
|
+
config.version = (0, config_1.cliVersion)();
|
|
84
|
+
config.template = template.id;
|
|
85
|
+
config.projectName = ctx.projectName;
|
|
86
|
+
config.installedAt = new Date().toISOString();
|
|
87
|
+
(0, config_1.writeConfig)(cwd, config);
|
|
88
|
+
logger_1.log.success(`テンプレート "${template.id}" で初期化しました(${written}ファイル)`);
|
|
89
|
+
logger_1.log.info("");
|
|
90
|
+
logger_1.log.info("次のステップ:");
|
|
91
|
+
logger_1.log.info(" 1. foundruu doctor でリポジトリの状態を確認");
|
|
92
|
+
logger_1.log.info(" 2. .ai/prompts/session-workflow.md を AI エージェントに読ませて開発を開始");
|
|
93
|
+
}
|
|
94
|
+
//# 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,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI開発セッション管理(dev-workflow の bin/ai-session を TypeScript へ移植)。
|
|
3
|
+
* .ai/templates/session/ を元に .ai/sessions/<name>/ へ作業ファイル一式を作成する。
|
|
4
|
+
*/
|
|
5
|
+
/** .ai を持つリポジトリルートを特定する(git toplevel 優先、なければ上方向へ探索) */
|
|
6
|
+
export declare function findAiRoot(cwd: string): string | null;
|
|
7
|
+
export declare function startSession(cwd: string, name: string): void;
|
|
8
|
+
export declare function listSessions(cwd: string): void;
|
|
@@ -0,0 +1,96 @@
|
|
|
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.findAiRoot = findAiRoot;
|
|
7
|
+
exports.startSession = startSession;
|
|
8
|
+
exports.listSessions = listSessions;
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const logger_1 = require("../core/logger");
|
|
13
|
+
/**
|
|
14
|
+
* AI開発セッション管理(dev-workflow の bin/ai-session を TypeScript へ移植)。
|
|
15
|
+
* .ai/templates/session/ を元に .ai/sessions/<name>/ へ作業ファイル一式を作成する。
|
|
16
|
+
*/
|
|
17
|
+
/** .ai を持つリポジトリルートを特定する(git toplevel 優先、なければ上方向へ探索) */
|
|
18
|
+
function findAiRoot(cwd) {
|
|
19
|
+
try {
|
|
20
|
+
const top = (0, child_process_1.execFileSync)("git", ["-C", cwd, "rev-parse", "--show-toplevel"], { stdio: "pipe" })
|
|
21
|
+
.toString()
|
|
22
|
+
.trim();
|
|
23
|
+
if (fs_1.default.existsSync(path_1.default.join(top, ".ai")))
|
|
24
|
+
return top;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// git 管理外は上方向探索へフォールバック
|
|
28
|
+
}
|
|
29
|
+
let dir = path_1.default.resolve(cwd);
|
|
30
|
+
for (;;) {
|
|
31
|
+
if (fs_1.default.existsSync(path_1.default.join(dir, ".ai")))
|
|
32
|
+
return dir;
|
|
33
|
+
const parent = path_1.default.dirname(dir);
|
|
34
|
+
if (parent === dir)
|
|
35
|
+
return null;
|
|
36
|
+
dir = parent;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function requireAiRoot(cwd) {
|
|
40
|
+
const root = findAiRoot(cwd);
|
|
41
|
+
if (!root) {
|
|
42
|
+
throw new Error(".ai ディレクトリが見つかりません。foundruu workflow install で導入するか、リポジトリ内で実行してください。");
|
|
43
|
+
}
|
|
44
|
+
return root;
|
|
45
|
+
}
|
|
46
|
+
function startSession(cwd, name) {
|
|
47
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) {
|
|
48
|
+
throw new Error(`セッション名が不正です(英数字で始まり / や空白を含まないこと): ${name}`);
|
|
49
|
+
}
|
|
50
|
+
const root = requireAiRoot(cwd);
|
|
51
|
+
const templateDir = path_1.default.join(root, ".ai", "templates", "session");
|
|
52
|
+
if (!fs_1.default.existsSync(templateDir)) {
|
|
53
|
+
throw new Error(`セッションテンプレートが見つかりません: ${path_1.default.relative(cwd, templateDir)}`);
|
|
54
|
+
}
|
|
55
|
+
const dest = path_1.default.join(root, ".ai", "sessions", name);
|
|
56
|
+
if (fs_1.default.existsSync(dest)) {
|
|
57
|
+
throw new Error(`セッションは既に存在します: .ai/sessions/${name}`);
|
|
58
|
+
}
|
|
59
|
+
fs_1.default.mkdirSync(dest, { recursive: true });
|
|
60
|
+
const files = fs_1.default.readdirSync(templateDir).filter((f) => f.endsWith(".md"));
|
|
61
|
+
for (const file of files) {
|
|
62
|
+
fs_1.default.copyFileSync(path_1.default.join(templateDir, file), path_1.default.join(dest, file));
|
|
63
|
+
}
|
|
64
|
+
logger_1.log.success(`セッションを作成しました: .ai/sessions/${name}`);
|
|
65
|
+
logger_1.log.info("");
|
|
66
|
+
logger_1.log.info("作成ファイル:");
|
|
67
|
+
for (const file of files.sort()) {
|
|
68
|
+
logger_1.log.info(` - .ai/sessions/${name}/${file}`);
|
|
69
|
+
}
|
|
70
|
+
logger_1.log.info("");
|
|
71
|
+
logger_1.log.info("次のステップ:");
|
|
72
|
+
logger_1.log.info(" 1. requirements.md に要件を書く");
|
|
73
|
+
logger_1.log.info(" 2. AI に .ai/prompts/session-workflow.md と requirements.md を渡す");
|
|
74
|
+
logger_1.log.info(" 3. AI が「進める / 質問する」を判断します");
|
|
75
|
+
}
|
|
76
|
+
function listSessions(cwd) {
|
|
77
|
+
const root = requireAiRoot(cwd);
|
|
78
|
+
const sessionsDir = path_1.default.join(root, ".ai", "sessions");
|
|
79
|
+
const sessions = fs_1.default.existsSync(sessionsDir)
|
|
80
|
+
? fs_1.default
|
|
81
|
+
.readdirSync(sessionsDir, { withFileTypes: true })
|
|
82
|
+
.filter((e) => e.isDirectory())
|
|
83
|
+
.map((e) => e.name)
|
|
84
|
+
.sort()
|
|
85
|
+
: [];
|
|
86
|
+
if (sessions.length === 0) {
|
|
87
|
+
logger_1.log.info("セッションはまだありません。");
|
|
88
|
+
logger_1.log.info(" 作成: foundruu session start <session-name>");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
logger_1.log.info("セッション一覧 (.ai/sessions/):");
|
|
92
|
+
for (const name of sessions) {
|
|
93
|
+
logger_1.log.info(` - ${name}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface UpdateOptions {
|
|
2
|
+
/** ユーザー編集済みファイルも上書きする */
|
|
3
|
+
force?: boolean;
|
|
4
|
+
/** 差分表示のみで書き込まない */
|
|
5
|
+
diff?: boolean;
|
|
6
|
+
/** GitHub から取得せず CLI 同梱アセットを使う */
|
|
7
|
+
local?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Workflow / Prompt / Rules を最新アセットへ同期する。
|
|
11
|
+
* 導入時に記録したハッシュと比較し、ユーザーが編集したファイルは --force なしでは上書きしない。
|
|
12
|
+
*/
|
|
13
|
+
export declare function runUpdate(cwd: string, options: UpdateOptions): void;
|
|
@@ -0,0 +1,64 @@
|
|
|
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.runUpdate = runUpdate;
|
|
7
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
8
|
+
const config_1 = require("../core/config");
|
|
9
|
+
const fetcher_1 = require("../core/fetcher");
|
|
10
|
+
const logger_1 = require("../core/logger");
|
|
11
|
+
const sync_1 = require("../core/sync");
|
|
12
|
+
const STATUS_LABEL = {
|
|
13
|
+
add: picocolors_1.default.green("追加 "),
|
|
14
|
+
update: picocolors_1.default.cyan("更新 "),
|
|
15
|
+
unchanged: picocolors_1.default.dim("最新 "),
|
|
16
|
+
"user-modified": picocolors_1.default.yellow("編集済み保護"),
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Workflow / Prompt / Rules を最新アセットへ同期する。
|
|
20
|
+
* 導入時に記録したハッシュと比較し、ユーザーが編集したファイルは --force なしでは上書きしない。
|
|
21
|
+
*/
|
|
22
|
+
function runUpdate(cwd, options) {
|
|
23
|
+
const config = (0, config_1.readConfig)(cwd);
|
|
24
|
+
if (!config?.workflow) {
|
|
25
|
+
logger_1.log.warn("このプロジェクトには Workflow が導入されていません。foundruu workflow install を実行してください。");
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const { root, source } = (0, fetcher_1.fetchWorkflowAssets)({ local: options.local });
|
|
30
|
+
logger_1.log.info(`アセット取得元: ${source === "remote" ? "GitHub (Ruu5LP/RuunFoundry)" : "CLI 同梱"} / 導入済みバージョン: ${config.workflow.version}`);
|
|
31
|
+
const recorded = config.workflow.files ?? {};
|
|
32
|
+
const { plan, hashes } = (0, sync_1.syncTree)(root, cwd, recorded, {
|
|
33
|
+
force: options.force,
|
|
34
|
+
dryRun: options.diff,
|
|
35
|
+
});
|
|
36
|
+
const changed = plan.filter((e) => e.status !== "unchanged");
|
|
37
|
+
if (changed.length === 0) {
|
|
38
|
+
logger_1.log.success("すべて最新です。");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
for (const entry of changed) {
|
|
42
|
+
const label = entry.status === "user-modified" && options.force && !options.diff
|
|
43
|
+
? picocolors_1.default.red("強制上書き ")
|
|
44
|
+
: STATUS_LABEL[entry.status];
|
|
45
|
+
logger_1.log.info(` ${label} ${entry.relPath}`);
|
|
46
|
+
}
|
|
47
|
+
const protectedCount = plan.filter((e) => e.status === "user-modified").length;
|
|
48
|
+
if (options.diff) {
|
|
49
|
+
logger_1.log.info("");
|
|
50
|
+
logger_1.log.info("--diff のため書き込みは行っていません。適用するには foundruu update を実行してください。");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (protectedCount > 0 && !options.force) {
|
|
54
|
+
logger_1.log.warn(`ユーザー編集済みのため保護したファイルが ${protectedCount}件あります(上書きは --force)。`);
|
|
55
|
+
}
|
|
56
|
+
config.workflow = {
|
|
57
|
+
version: (0, config_1.cliVersion)(),
|
|
58
|
+
installedAt: new Date().toISOString(),
|
|
59
|
+
files: hashes,
|
|
60
|
+
};
|
|
61
|
+
(0, config_1.writeConfig)(cwd, config);
|
|
62
|
+
logger_1.log.success("Workflow を更新しました。");
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
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.installWorkflow = installWorkflow;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const assets_1 = require("../core/assets");
|
|
10
|
+
const config_1 = require("../core/config");
|
|
11
|
+
const copier_1 = require("../core/copier");
|
|
12
|
+
const logger_1 = require("../core/logger");
|
|
13
|
+
const sync_1 = require("../core/sync");
|
|
14
|
+
const GITIGNORE_ENTRY = ".ai/sessions/";
|
|
15
|
+
function neutralContext(cwd) {
|
|
16
|
+
return {
|
|
17
|
+
projectName: path_1.default.basename(cwd),
|
|
18
|
+
description: "",
|
|
19
|
+
language: "",
|
|
20
|
+
languageLabel: "",
|
|
21
|
+
aiProviders: [],
|
|
22
|
+
aiProviderLabels: [],
|
|
23
|
+
features: [],
|
|
24
|
+
featureLabels: [],
|
|
25
|
+
year: new Date().getFullYear(),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function ensureGitignoreEntry(cwd) {
|
|
29
|
+
const file = path_1.default.join(cwd, ".gitignore");
|
|
30
|
+
const current = fs_1.default.existsSync(file) ? fs_1.default.readFileSync(file, "utf8") : "";
|
|
31
|
+
if (current.split(/\r?\n/).includes(GITIGNORE_ENTRY))
|
|
32
|
+
return;
|
|
33
|
+
const next = current.length && !current.endsWith("\n") ? current + "\n" : current;
|
|
34
|
+
fs_1.default.writeFileSync(file, `${next}${GITIGNORE_ENTRY}\n`);
|
|
35
|
+
logger_1.log.step(`.gitignore に ${GITIGNORE_ENTRY} を追加しました`);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Workflow / Prompt / Rules(.ai/) を導入する。
|
|
39
|
+
* @param overwrite true の場合、既存ファイルも最新アセットで上書きする(update用)
|
|
40
|
+
*/
|
|
41
|
+
function installWorkflow(cwd, options = {}) {
|
|
42
|
+
const result = (0, copier_1.copyTree)((0, assets_1.workflowRoot)(), cwd, neutralContext(cwd), {
|
|
43
|
+
overwrite: options.overwrite ?? false,
|
|
44
|
+
});
|
|
45
|
+
ensureGitignoreEntry(cwd);
|
|
46
|
+
for (const file of result.written) {
|
|
47
|
+
logger_1.log.step(`書き込み: ${path_1.default.relative(cwd, file)}`);
|
|
48
|
+
}
|
|
49
|
+
if (result.skipped.length > 0) {
|
|
50
|
+
logger_1.log.info(` 既存のためスキップ: ${result.skipped.length}件(上書きは foundruu update --force)`);
|
|
51
|
+
}
|
|
52
|
+
// 管理ファイルの導入時ハッシュを記録する(update 時のユーザー編集検出に使用)
|
|
53
|
+
const files = {};
|
|
54
|
+
for (const relPath of (0, sync_1.listFiles)((0, assets_1.workflowRoot)())) {
|
|
55
|
+
const destPath = path_1.default.join(cwd, relPath);
|
|
56
|
+
if (fs_1.default.existsSync(destPath))
|
|
57
|
+
files[relPath] = (0, sync_1.hashFile)(destPath);
|
|
58
|
+
}
|
|
59
|
+
const config = (0, config_1.readConfig)(cwd) ?? { version: (0, config_1.cliVersion)() };
|
|
60
|
+
config.workflow = { version: (0, config_1.cliVersion)(), installedAt: new Date().toISOString(), files };
|
|
61
|
+
(0, config_1.writeConfig)(cwd, config);
|
|
62
|
+
logger_1.log.success(`Workflow を導入しました(${result.written.length}ファイル)`);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 同梱アセット(assets/)のルートを解決する。
|
|
3
|
+
* ビルド後は dist/core/assets.js から見て ../../assets、
|
|
4
|
+
* ts-node 実行時は src/core/assets.ts から見ても同じ相対位置になる。
|
|
5
|
+
*/
|
|
6
|
+
export declare function assetsRoot(): string;
|
|
7
|
+
export declare function templatesRoot(): string;
|
|
8
|
+
export declare function workflowRoot(): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
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.assetsRoot = assetsRoot;
|
|
7
|
+
exports.templatesRoot = templatesRoot;
|
|
8
|
+
exports.workflowRoot = workflowRoot;
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
/**
|
|
12
|
+
* 同梱アセット(assets/)のルートを解決する。
|
|
13
|
+
* ビルド後は dist/core/assets.js から見て ../../assets、
|
|
14
|
+
* ts-node 実行時は src/core/assets.ts から見ても同じ相対位置になる。
|
|
15
|
+
*/
|
|
16
|
+
function assetsRoot() {
|
|
17
|
+
const root = path_1.default.resolve(__dirname, "..", "..", "assets");
|
|
18
|
+
if (!fs_1.default.existsSync(root)) {
|
|
19
|
+
throw new Error(`同梱アセットが見つかりません: ${root}`);
|
|
20
|
+
}
|
|
21
|
+
return root;
|
|
22
|
+
}
|
|
23
|
+
function templatesRoot() {
|
|
24
|
+
return path_1.default.join(assetsRoot(), "templates");
|
|
25
|
+
}
|
|
26
|
+
function workflowRoot() {
|
|
27
|
+
return path_1.default.join(assetsRoot(), "workflow");
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=assets.js.map
|