@shendu-sdt/sdt-dev-agent 0.1.1
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 +108 -0
- package/bin/sdt-dev-agent.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +26 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +34 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/core/init-options.d.ts +9 -0
- package/dist/core/init-options.d.ts.map +1 -0
- package/dist/core/init-options.js +151 -0
- package/dist/core/init-options.js.map +1 -0
- package/dist/core/init-plan.d.ts +3 -0
- package/dist/core/init-plan.d.ts.map +1 -0
- package/dist/core/init-plan.js +108 -0
- package/dist/core/init-plan.js.map +1 -0
- package/dist/core/init-writer.d.ts +6 -0
- package/dist/core/init-writer.d.ts.map +1 -0
- package/dist/core/init-writer.js +28 -0
- package/dist/core/init-writer.js.map +1 -0
- package/dist/core/project-inspector.d.ts +3 -0
- package/dist/core/project-inspector.d.ts.map +1 -0
- package/dist/core/project-inspector.js +53 -0
- package/dist/core/project-inspector.js.map +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/fs.d.ts +6 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +25 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/init-welcome.d.ts +5 -0
- package/dist/utils/init-welcome.d.ts.map +1 -0
- package/dist/utils/init-welcome.js +285 -0
- package/dist/utils/init-welcome.js.map +1 -0
- package/dist/utils/interactive.d.ts +2 -0
- package/dist/utils/interactive.d.ts.map +1 -0
- package/dist/utils/interactive.js +4 -0
- package/dist/utils/interactive.js.map +1 -0
- package/dist/utils/prompt-flow.d.ts +3 -0
- package/dist/utils/prompt-flow.d.ts.map +1 -0
- package/dist/utils/prompt-flow.js +2 -0
- package/dist/utils/prompt-flow.js.map +1 -0
- package/dist/utils/render-template.d.ts +2 -0
- package/dist/utils/render-template.d.ts.map +1 -0
- package/dist/utils/render-template.js +4 -0
- package/dist/utils/render-template.js.map +1 -0
- package/dist/utils/searchable-multi-select.d.ts +15 -0
- package/dist/utils/searchable-multi-select.d.ts.map +1 -0
- package/dist/utils/searchable-multi-select.js +144 -0
- package/dist/utils/searchable-multi-select.js.map +1 -0
- package/dist/utils/styled-select.d.ts +13 -0
- package/dist/utils/styled-select.d.ts.map +1 -0
- package/dist/utils/styled-select.js +74 -0
- package/dist/utils/styled-select.js.map +1 -0
- package/package.json +63 -0
- package/templates/AGENTS.md +24 -0
- package/templates/ARCHITECTURE.md +26 -0
- package/templates/capabilities/mcp/README.md +8 -0
- package/templates/capabilities/skills/README.md +8 -0
- package/templates/docs/ai-collaboration/README.md +16 -0
- package/templates/tools/claude-code/README.md +8 -0
- package/templates/tools/codex/README.md +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# SDT DevAgent
|
|
2
|
+
|
|
3
|
+
面向研发项目落地的 AI 协作底座。
|
|
4
|
+
|
|
5
|
+
当前版本提供一个初始化命令:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
sdt-dev-agent init [targetPath]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
它会把项目级 AI 协作文档骨架、工具占位目录、能力包占位目录,以及安装清单 `.sdt-devagent/manifest.json` 安装到现有仓库中。
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
**Requires Node.js 20.19.0 or higher.**
|
|
16
|
+
|
|
17
|
+
在目标项目中安装:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add -D @shendu-sdt/sdt-dev-agent
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
然后执行初始化:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm exec sdt-dev-agent init .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
直接使用默认选择:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pnpm exec sdt-dev-agent init . --yes
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
常见用法:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm exec sdt-dev-agent init . --tools codex --install-mode recommended
|
|
39
|
+
pnpm exec sdt-dev-agent init . --tools codex,claude-code --install-mode minimal
|
|
40
|
+
pnpm exec sdt-dev-agent init . --tools codex --install-mode custom --capabilities base-assets,skills
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
当前支持:
|
|
44
|
+
|
|
45
|
+
- tools: `codex`, `claude-code`
|
|
46
|
+
- install mode: `recommended`, `minimal`, `custom`
|
|
47
|
+
- capabilities: `base-assets`, `skills`, `mcp`
|
|
48
|
+
|
|
49
|
+
初始化输出包括:
|
|
50
|
+
|
|
51
|
+
- `AGENTS.md`
|
|
52
|
+
- `ARCHITECTURE.md`
|
|
53
|
+
- `docs/ai-collaboration/README.md`
|
|
54
|
+
- `.codex/` / `.claude/` 占位文件
|
|
55
|
+
- `.sdt-devagent/manifest.json`
|
|
56
|
+
|
|
57
|
+
> [!NOTE]
|
|
58
|
+
> 当前只支持初始化基座,不包含真实 MCP 接线、真实 Skills 内容或业务闭环。
|
|
59
|
+
>
|
|
60
|
+
> 当前写入策略是严格防覆盖;目标文件已存在时会整体中止,不会自动合并。
|
|
61
|
+
|
|
62
|
+
## Development
|
|
63
|
+
|
|
64
|
+
安装依赖并构建:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pnpm install
|
|
68
|
+
pnpm run build
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
推荐用 `file:` 依赖联调。先在当前仓库执行 `pnpm run build`,再到目标项目中安装:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pnpm add -D file:/Users/your-name/workspace/SDT-DevAgent
|
|
75
|
+
pnpm exec sdt-dev-agent init .
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
把示例路径替换成你本机 `SDT-DevAgent` 仓库的绝对路径。由于 CLI 入口指向 `dist/cli/index.js`,修改 `src/` 或 `templates/` 后需要重新执行 `pnpm run build`。
|
|
79
|
+
|
|
80
|
+
常用命令:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pnpm run dev
|
|
84
|
+
pnpm run build
|
|
85
|
+
pnpm run typecheck
|
|
86
|
+
pnpm run test
|
|
87
|
+
pnpm run lint
|
|
88
|
+
pnpm run verify
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Release
|
|
92
|
+
|
|
93
|
+
发布前先执行:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pnpm run verify
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
然后按版本类型发布:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pnpm run release
|
|
103
|
+
pnpm run release:patch
|
|
104
|
+
pnpm run release:minor
|
|
105
|
+
pnpm run release:major
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
发布脚本会依次执行 `build`、`npm publish --dry-run --access public`、`version --no-git-tag-version`、`npm publish --access public`,并发布到 npm 官方 registry。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { runInitCommand } from '../commands/init.js';
|
|
3
|
+
const program = new Command();
|
|
4
|
+
program
|
|
5
|
+
.name('sdt-dev-agent')
|
|
6
|
+
.description('Bootstrap project-level AI collaboration assets')
|
|
7
|
+
.version('0.1.0');
|
|
8
|
+
program
|
|
9
|
+
.command('init [targetPath]')
|
|
10
|
+
.description('Initialize SDT DevAgent assets in an existing project')
|
|
11
|
+
.option('--tools <tools>', 'Comma-separated tools: codex,claude-code')
|
|
12
|
+
.option('--install-mode <mode>', 'Install mode: recommended|minimal|custom')
|
|
13
|
+
.option('--capabilities <capabilities>', 'Comma-separated capabilities: base-assets,skills,mcp')
|
|
14
|
+
.option('--yes', 'Use default selections without prompting')
|
|
15
|
+
.action(async (targetPath = '.', options) => {
|
|
16
|
+
try {
|
|
17
|
+
await runInitCommand(targetPath, options);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
21
|
+
console.error(message);
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
await program.parseAsync(process.argv);
|
|
26
|
+
//# 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,CAAA;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,iBAAiB,EAAE,0CAA0C,CAAC;KACrE,MAAM,CAAC,uBAAuB,EAAE,0CAA0C,CAAC;KAC3E,MAAM,CAAC,+BAA+B,EAAE,sDAAsD,CAAC;KAC/F,MAAM,CAAC,OAAO,EAAE,0CAA0C,CAAC;KAC3D,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,EAAE,OAAO,EAAE,EAAE;IAC1C,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAA;QACxE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACtB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC;AACH,CAAC,CAAC,CAAA;AAEJ,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAc7D,wBAAsB,cAAc,CAClC,UAAU,SAAM,EAChB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAsBf"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import { inspectProject } from '../core/project-inspector.js';
|
|
4
|
+
import { resolveInitSelections } from '../core/init-options.js';
|
|
5
|
+
import { createInitPlan } from '../core/init-plan.js';
|
|
6
|
+
import { applyInitPlan } from '../core/init-writer.js';
|
|
7
|
+
import { showInitWelcome } from '../utils/init-welcome.js';
|
|
8
|
+
function printSummary(targetPath, writtenFiles) {
|
|
9
|
+
console.log(`Initialized SDT DevAgent in ${targetPath}`);
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log('Generated files:');
|
|
12
|
+
for (const file of writtenFiles) {
|
|
13
|
+
console.log(`- ${file}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export async function runInitCommand(targetPath = '.', options = {}) {
|
|
17
|
+
const resolvedTarget = path.resolve(targetPath);
|
|
18
|
+
const stats = await fs.stat(resolvedTarget).catch((error) => {
|
|
19
|
+
if (error.code === 'ENOENT') {
|
|
20
|
+
throw new Error(`Target directory does not exist: ${resolvedTarget}`);
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
});
|
|
24
|
+
if (!stats.isDirectory()) {
|
|
25
|
+
throw new Error(`Target path is not a directory: ${resolvedTarget}`);
|
|
26
|
+
}
|
|
27
|
+
await showInitWelcome();
|
|
28
|
+
const selections = await resolveInitSelections(options);
|
|
29
|
+
const facts = await inspectProject(resolvedTarget);
|
|
30
|
+
const plan = createInitPlan(facts, selections);
|
|
31
|
+
const result = await applyInitPlan(resolvedTarget, plan);
|
|
32
|
+
printSummary(resolvedTarget, result.writtenFiles);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAA;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,SAAS,YAAY,CAAC,UAAkB,EAAE,YAAsB;IAC9D,OAAO,CAAC,GAAG,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAA;IACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IAC/B,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAAU,GAAG,GAAG,EAChB,UAA0B,EAAE;IAE5B,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAE/C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,KAA4B,EAAE,EAAE;QACjF,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,oCAAoC,cAAc,EAAE,CAAC,CAAA;QACvE,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,mCAAmC,cAAc,EAAE,CAAC,CAAA;IACtE,CAAC;IAED,MAAM,eAAe,EAAE,CAAA;IAEvB,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAA;IACvD,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,cAAc,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IAC9C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA;IAExD,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;AACnD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { InitSelections } from '../types.js';
|
|
2
|
+
export interface RawInitOptions {
|
|
3
|
+
tools?: string;
|
|
4
|
+
installMode?: string;
|
|
5
|
+
capabilities?: string;
|
|
6
|
+
yes?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveInitSelections(options: RawInitOptions): Promise<InitSelections>;
|
|
9
|
+
//# sourceMappingURL=init-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-options.d.ts","sourceRoot":"","sources":["../../src/core/init-options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,cAAc,EAAuB,MAAM,aAAa,CAAA;AAOpF,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAmFD,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CA4F5F"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { CAPABILITIES, INSTALL_MODES, SUPPORTED_TOOLS } from '../types.js';
|
|
2
|
+
import { canPrompt } from '../utils/interactive.js';
|
|
3
|
+
import { GO_BACK } from '../utils/prompt-flow.js';
|
|
4
|
+
import { searchableMultiSelect } from '../utils/searchable-multi-select.js';
|
|
5
|
+
import { styledSelect } from '../utils/styled-select.js';
|
|
6
|
+
function parseList(input, allowed) {
|
|
7
|
+
if (!input) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
const values = input
|
|
11
|
+
.split(',')
|
|
12
|
+
.map((item) => item.trim())
|
|
13
|
+
.filter(Boolean);
|
|
14
|
+
const invalid = values.filter((value) => !allowed.includes(value));
|
|
15
|
+
if (invalid.length > 0) {
|
|
16
|
+
throw new Error(`Invalid values: ${invalid.join(', ')}`);
|
|
17
|
+
}
|
|
18
|
+
return values;
|
|
19
|
+
}
|
|
20
|
+
function normalizeCapabilities(installMode, capabilities) {
|
|
21
|
+
if (installMode === 'recommended') {
|
|
22
|
+
return [...CAPABILITIES];
|
|
23
|
+
}
|
|
24
|
+
if (installMode === 'minimal') {
|
|
25
|
+
return ['base-assets'];
|
|
26
|
+
}
|
|
27
|
+
return capabilities;
|
|
28
|
+
}
|
|
29
|
+
async function promptTools() {
|
|
30
|
+
return searchableMultiSelect({
|
|
31
|
+
message: 'Select tools to set up (2 available)',
|
|
32
|
+
choices: [
|
|
33
|
+
{ name: 'Codex', value: 'codex' },
|
|
34
|
+
{ name: 'Claude Code', value: 'claude-code' },
|
|
35
|
+
],
|
|
36
|
+
validate: (selected) => (selected.length > 0 ? true : 'Select at least one tool'),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async function promptInstallMode(allowBack = false) {
|
|
40
|
+
return styledSelect({
|
|
41
|
+
message: '选择安装方式',
|
|
42
|
+
allowBack,
|
|
43
|
+
choices: [
|
|
44
|
+
{
|
|
45
|
+
name: '推荐安装(默认)',
|
|
46
|
+
value: 'recommended',
|
|
47
|
+
description: '安装基础协作资产、内置 Skills、内置 MCP',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: '最小安装',
|
|
51
|
+
value: 'minimal',
|
|
52
|
+
description: '只安装基础协作资产和目标工具接入文件',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: '自定义安装',
|
|
56
|
+
value: 'custom',
|
|
57
|
+
description: '按能力包选择安装内容',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async function promptCapabilities(allowBack = false) {
|
|
63
|
+
return searchableMultiSelect({
|
|
64
|
+
message: 'Select capability packs to install (3 available)',
|
|
65
|
+
allowBack,
|
|
66
|
+
choices: [
|
|
67
|
+
{ name: '基础协作资产', value: 'base-assets' },
|
|
68
|
+
{ name: '内置 Skills', value: 'skills' },
|
|
69
|
+
{ name: '内置 MCP', value: 'mcp' },
|
|
70
|
+
],
|
|
71
|
+
validate: (selected) => (selected.length > 0 ? true : 'Select at least one capability pack'),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
export async function resolveInitSelections(options) {
|
|
75
|
+
const tools = parseList(options.tools, SUPPORTED_TOOLS);
|
|
76
|
+
const installMode = options.installMode
|
|
77
|
+
? (() => {
|
|
78
|
+
if (!INSTALL_MODES.includes(options.installMode)) {
|
|
79
|
+
throw new Error(`Invalid install mode: ${options.installMode}`);
|
|
80
|
+
}
|
|
81
|
+
return options.installMode;
|
|
82
|
+
})()
|
|
83
|
+
: undefined;
|
|
84
|
+
const capabilities = parseList(options.capabilities, CAPABILITIES);
|
|
85
|
+
if (options.yes) {
|
|
86
|
+
return {
|
|
87
|
+
tools: tools.length > 0 ? tools : [...SUPPORTED_TOOLS],
|
|
88
|
+
installMode: installMode ?? 'recommended',
|
|
89
|
+
capabilities: normalizeCapabilities(installMode ?? 'recommended', capabilities),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (tools.length > 0 && installMode) {
|
|
93
|
+
return {
|
|
94
|
+
tools,
|
|
95
|
+
installMode,
|
|
96
|
+
capabilities: normalizeCapabilities(installMode, capabilities),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (!canPrompt()) {
|
|
100
|
+
throw new Error('Interactive prompts are unavailable. Pass --tools, --install-mode, and optionally --capabilities or use --yes.');
|
|
101
|
+
}
|
|
102
|
+
let selectedTools = tools.length > 0 ? tools : undefined;
|
|
103
|
+
let selectedInstallMode = installMode;
|
|
104
|
+
let selectedCapabilities = capabilities.length > 0 ? capabilities : undefined;
|
|
105
|
+
const history = [];
|
|
106
|
+
while (true) {
|
|
107
|
+
if (!selectedTools) {
|
|
108
|
+
selectedTools = await promptTools();
|
|
109
|
+
history.push('tools');
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (!selectedInstallMode) {
|
|
113
|
+
const installModeResult = await promptInstallMode(history.length > 0);
|
|
114
|
+
if (installModeResult === GO_BACK) {
|
|
115
|
+
const previousStep = history.pop();
|
|
116
|
+
if (previousStep === 'tools') {
|
|
117
|
+
selectedTools = undefined;
|
|
118
|
+
}
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
selectedInstallMode = installModeResult;
|
|
122
|
+
history.push('install-mode');
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (selectedInstallMode === 'custom' && !selectedCapabilities) {
|
|
126
|
+
const capabilitiesResult = await promptCapabilities(history.length > 0);
|
|
127
|
+
if (capabilitiesResult === GO_BACK) {
|
|
128
|
+
const previousStep = history.pop();
|
|
129
|
+
if (previousStep === 'install-mode') {
|
|
130
|
+
selectedInstallMode = undefined;
|
|
131
|
+
}
|
|
132
|
+
else if (previousStep === 'tools') {
|
|
133
|
+
selectedTools = undefined;
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
selectedCapabilities = capabilitiesResult;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
if (selectedInstallMode === 'custom' && (!selectedCapabilities || selectedCapabilities.length === 0)) {
|
|
143
|
+
throw new Error('Custom install mode requires at least one capability.');
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
tools: selectedTools,
|
|
147
|
+
installMode: selectedInstallMode,
|
|
148
|
+
capabilities: normalizeCapabilities(selectedInstallMode, selectedCapabilities ?? []),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=init-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-options.js","sourceRoot":"","sources":["../../src/core/init-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE1E,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AASxD,SAAS,SAAS,CAAmB,KAAyB,EAAE,OAAqB;IACnF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,MAAM,GAAG,KAAK;SACjB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAA;IAElB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAU,CAAC,CAAC,CAAA;IACvE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC1D,CAAC;IAED,OAAO,MAAa,CAAA;AACtB,CAAC;AAED,SAAS,qBAAqB,CAC5B,WAAwB,EACxB,YAA4B;IAE5B,IAAI,WAAW,KAAK,aAAa,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,YAAY,CAAC,CAAA;IAC1B,CAAC;IAED,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,aAAa,CAAC,CAAA;IACxB,CAAC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,OAAO,qBAAqB,CAAC;QAC3B,OAAO,EAAE,sCAAsC;QAC/C,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;YACjC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE;SAC9C;QACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC;KAClF,CAAsB,CAAA;AACzB,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,SAAS,GAAG,KAAK;IAChD,OAAO,YAAY,CAAC;QAClB,OAAO,EAAE,QAAQ;QACjB,SAAS;QACT,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,aAAa;gBACpB,WAAW,EAAE,2BAA2B;aACzC;YACD;gBACE,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,SAAS;gBAChB,WAAW,EAAE,oBAAoB;aAClC;YACD;gBACE,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE,YAAY;aAC1B;SACF;KACF,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,SAAS,GAAG,KAAK;IACjD,OAAO,qBAAqB,CAAC;QAC3B,OAAO,EAAE,kDAAkD;QAC3D,SAAS;QACT,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE;YACxC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE;YACtC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE;SACjC;QACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,qCAAqC,CAAC;KAC7F,CAA4B,CAAA;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAuB;IACjE,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,CAAA;IACvD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW;QACrC,CAAC,CAAC,CAAC,GAAG,EAAE;YACJ,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,WAA0B,CAAC,EAAE,CAAC;gBAChE,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;YACjE,CAAC;YACD,OAAO,OAAO,CAAC,WAA0B,CAAA;QAC3C,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,SAAS,CAAA;IACb,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;IAElE,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC;YACtD,WAAW,EAAE,WAAW,IAAI,aAAa;YACzC,YAAY,EAAE,qBAAqB,CAAC,WAAW,IAAI,aAAa,EAAE,YAAY,CAAC;SAChF,CAAA;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,EAAE,CAAC;QACpC,OAAO;YACL,KAAK;YACL,WAAW;YACX,YAAY,EAAE,qBAAqB,CAAC,WAAW,EAAE,YAAY,CAAC;SAC/D,CAAA;IACH,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAA;IACH,CAAC;IAED,IAAI,aAAa,GAAyB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9E,IAAI,mBAAmB,GAA4B,WAAW,CAAA;IAC9D,IAAI,oBAAoB,GAA+B,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAA;IACzG,MAAM,OAAO,GAAoC,EAAE,CAAA;IAEnD,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,aAAa,GAAG,MAAM,WAAW,EAAE,CAAA;YACnC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACrB,SAAQ;QACV,CAAC;QAED,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,MAAM,iBAAiB,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YAErE,IAAI,iBAAiB,KAAK,OAAO,EAAE,CAAC;gBAClC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;gBAClC,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;oBAC7B,aAAa,GAAG,SAAS,CAAA;gBAC3B,CAAC;gBACD,SAAQ;YACV,CAAC;YAED,mBAAmB,GAAG,iBAAiB,CAAA;YACvC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YAC5B,SAAQ;QACV,CAAC;QAED,IAAI,mBAAmB,KAAK,QAAQ,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9D,MAAM,kBAAkB,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YAEvE,IAAI,kBAAkB,KAAK,OAAO,EAAE,CAAC;gBACnC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;gBAElC,IAAI,YAAY,KAAK,cAAc,EAAE,CAAC;oBACpC,mBAAmB,GAAG,SAAS,CAAA;gBACjC,CAAC;qBAAM,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;oBACpC,aAAa,GAAG,SAAS,CAAA;gBAC3B,CAAC;gBACD,SAAQ;YACV,CAAC;YAED,oBAAoB,GAAG,kBAAkB,CAAA;YACzC,SAAQ;QACV,CAAC;QAED,MAAK;IACP,CAAC;IAED,IAAI,mBAAmB,KAAK,QAAQ,IAAI,CAAC,CAAC,oBAAoB,IAAI,oBAAoB,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QACrG,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;IAC1E,CAAC;IAED,OAAO;QACL,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,mBAAmB;QAChC,YAAY,EAAE,qBAAqB,CAAC,mBAAmB,EAAE,oBAAoB,IAAI,EAAE,CAAC;KACrF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-plan.d.ts","sourceRoot":"","sources":["../../src/core/init-plan.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,QAAQ,EACR,cAAc,EAGd,YAAY,EAEb,MAAM,aAAa,CAAA;AAwHpB,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,GAAG,QAAQ,CAqBxF"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { renderTemplate } from '../utils/render-template.js';
|
|
5
|
+
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const projectRoot = path.resolve(currentDir, '..', '..');
|
|
7
|
+
function loadTemplate(relativePath) {
|
|
8
|
+
return readFileSync(path.join(projectRoot, 'templates', relativePath), 'utf8');
|
|
9
|
+
}
|
|
10
|
+
function toolDir(tool) {
|
|
11
|
+
return tool === 'codex' ? '.codex' : '.claude';
|
|
12
|
+
}
|
|
13
|
+
function baseTemplateValues(facts, selections) {
|
|
14
|
+
return {
|
|
15
|
+
projectName: facts.projectName,
|
|
16
|
+
packageManager: facts.packageManager,
|
|
17
|
+
sourceRoot: facts.sourceRoot,
|
|
18
|
+
testRoot: facts.testRoot,
|
|
19
|
+
selectedTools: selections.tools.join(', '),
|
|
20
|
+
installMode: selections.installMode,
|
|
21
|
+
capabilities: selections.capabilities.join(', '),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function addBaseAssets(files, facts, selections) {
|
|
25
|
+
const values = baseTemplateValues(facts, selections);
|
|
26
|
+
files.push({
|
|
27
|
+
path: 'AGENTS.md',
|
|
28
|
+
content: renderTemplate(loadTemplate('AGENTS.md'), values),
|
|
29
|
+
kind: 'project-asset',
|
|
30
|
+
}, {
|
|
31
|
+
path: 'ARCHITECTURE.md',
|
|
32
|
+
content: renderTemplate(loadTemplate('ARCHITECTURE.md'), values),
|
|
33
|
+
kind: 'project-asset',
|
|
34
|
+
}, {
|
|
35
|
+
path: path.join('docs', 'ai-collaboration', 'README.md'),
|
|
36
|
+
content: renderTemplate(loadTemplate(path.join('docs', 'ai-collaboration', 'README.md')), values),
|
|
37
|
+
kind: 'project-asset',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function addToolFiles(files, tools) {
|
|
41
|
+
for (const tool of tools) {
|
|
42
|
+
files.push({
|
|
43
|
+
path: path.join(toolDir(tool), 'README.md'),
|
|
44
|
+
content: loadTemplate(path.join('tools', tool, 'README.md')),
|
|
45
|
+
kind: 'tool-integration',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function addCapabilityFiles(files, tools, capabilities) {
|
|
50
|
+
for (const capability of capabilities) {
|
|
51
|
+
if (capability === 'base-assets') {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
for (const tool of tools) {
|
|
55
|
+
files.push({
|
|
56
|
+
path: path.join(toolDir(tool), capability, 'README.md'),
|
|
57
|
+
content: loadTemplate(path.join('capabilities', capability, 'README.md')),
|
|
58
|
+
kind: 'tool-integration',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function buildManifest(facts, selections, files) {
|
|
64
|
+
const generatedFiles = [
|
|
65
|
+
...files.map((file) => ({
|
|
66
|
+
path: file.path,
|
|
67
|
+
kind: file.kind,
|
|
68
|
+
})),
|
|
69
|
+
{
|
|
70
|
+
path: path.join('.sdt-devagent', 'manifest.json'),
|
|
71
|
+
kind: 'manifest',
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
return {
|
|
75
|
+
version: '0.1.0',
|
|
76
|
+
generatedAt: new Date().toISOString(),
|
|
77
|
+
installMode: selections.installMode,
|
|
78
|
+
tools: selections.tools,
|
|
79
|
+
capabilities: selections.capabilities,
|
|
80
|
+
project: {
|
|
81
|
+
path: facts.targetPath,
|
|
82
|
+
name: facts.projectName,
|
|
83
|
+
packageManager: facts.packageManager,
|
|
84
|
+
sourceRoot: facts.sourceRoot,
|
|
85
|
+
testRoot: facts.testRoot,
|
|
86
|
+
},
|
|
87
|
+
generatedFiles,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export function createInitPlan(facts, selections) {
|
|
91
|
+
const files = [];
|
|
92
|
+
if (selections.capabilities.includes('base-assets')) {
|
|
93
|
+
addBaseAssets(files, facts, selections);
|
|
94
|
+
}
|
|
95
|
+
addToolFiles(files, selections.tools);
|
|
96
|
+
addCapabilityFiles(files, selections.tools, selections.capabilities);
|
|
97
|
+
const manifest = buildManifest(facts, selections, files);
|
|
98
|
+
files.push({
|
|
99
|
+
path: path.join('.sdt-devagent', 'manifest.json'),
|
|
100
|
+
content: `${JSON.stringify(manifest, null, 2)}\n`,
|
|
101
|
+
kind: 'manifest',
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
files,
|
|
105
|
+
manifest,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=init-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-plan.js","sourceRoot":"","sources":["../../src/core/init-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-writer.d.ts","sourceRoot":"","sources":["../../src/core/init-writer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAeD,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAmB5F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { exists, toPosixPath, writeText } from '../utils/fs.js';
|
|
3
|
+
async function collectConflicts(targetPath, plan) {
|
|
4
|
+
const conflicts = [];
|
|
5
|
+
for (const file of plan.files) {
|
|
6
|
+
const absolutePath = path.join(targetPath, file.path);
|
|
7
|
+
if (await exists(absolutePath)) {
|
|
8
|
+
conflicts.push(file.path);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return conflicts;
|
|
12
|
+
}
|
|
13
|
+
export async function applyInitPlan(targetPath, plan) {
|
|
14
|
+
const conflicts = await collectConflicts(targetPath, plan);
|
|
15
|
+
if (conflicts.length > 0) {
|
|
16
|
+
throw new Error(`Initialization aborted. Existing files would be overwritten:\n${conflicts
|
|
17
|
+
.map((item) => `- ${item}`)
|
|
18
|
+
.join('\n')}`);
|
|
19
|
+
}
|
|
20
|
+
const writtenFiles = [];
|
|
21
|
+
for (const file of plan.files) {
|
|
22
|
+
const absolutePath = path.join(targetPath, file.path);
|
|
23
|
+
await writeText(absolutePath, file.content);
|
|
24
|
+
writtenFiles.push(toPosixPath(file.path));
|
|
25
|
+
}
|
|
26
|
+
return { writtenFiles };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=init-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-writer.js","sourceRoot":"","sources":["../../src/core/init-writer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAO/D,KAAK,UAAU,gBAAgB,CAAC,UAAkB,EAAE,IAAc;IAChE,MAAM,SAAS,GAAa,EAAE,CAAA;IAE9B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QACrD,IAAI,MAAM,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAkB,EAAE,IAAc;IACpE,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;IAC1D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,iEAAiE,SAAS;aACvE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;aAC1B,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAA;IACH,CAAC;IAED,MAAM,YAAY,GAAa,EAAE,CAAA;IAEjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QACrD,MAAM,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QAC3C,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3C,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-inspector.d.ts","sourceRoot":"","sources":["../../src/core/project-inspector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAkD/C,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAa9E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { exists, readText } from '../utils/fs.js';
|
|
3
|
+
async function detectPackageManager(targetPath) {
|
|
4
|
+
const checks = [
|
|
5
|
+
['pnpm-lock.yaml', 'pnpm'],
|
|
6
|
+
['package-lock.json', 'npm'],
|
|
7
|
+
['yarn.lock', 'yarn'],
|
|
8
|
+
['bun.lockb', 'bun'],
|
|
9
|
+
];
|
|
10
|
+
for (const [filename, packageManager] of checks) {
|
|
11
|
+
if (await exists(path.join(targetPath, filename))) {
|
|
12
|
+
return packageManager;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return 'unknown';
|
|
16
|
+
}
|
|
17
|
+
async function detectProjectName(targetPath) {
|
|
18
|
+
const packageJsonPath = path.join(targetPath, 'package.json');
|
|
19
|
+
if (!(await exists(packageJsonPath))) {
|
|
20
|
+
return {
|
|
21
|
+
projectName: path.basename(targetPath),
|
|
22
|
+
hasPackageJson: false,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const raw = await readText(packageJsonPath);
|
|
26
|
+
const packageJson = JSON.parse(raw);
|
|
27
|
+
return {
|
|
28
|
+
projectName: packageJson.name ?? path.basename(targetPath),
|
|
29
|
+
hasPackageJson: true,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async function detectDirectory(targetPath, candidates) {
|
|
33
|
+
for (const candidate of candidates) {
|
|
34
|
+
if (await exists(path.join(targetPath, candidate))) {
|
|
35
|
+
return candidate;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return 'N/A';
|
|
39
|
+
}
|
|
40
|
+
export async function inspectProject(targetPath) {
|
|
41
|
+
const project = await detectProjectName(targetPath);
|
|
42
|
+
return {
|
|
43
|
+
targetPath,
|
|
44
|
+
projectName: project.projectName,
|
|
45
|
+
packageManager: await detectPackageManager(targetPath),
|
|
46
|
+
sourceRoot: await detectDirectory(targetPath, ['src', 'app', 'packages']),
|
|
47
|
+
testRoot: await detectDirectory(targetPath, ['test', 'tests', '__tests__']),
|
|
48
|
+
hasPackageJson: project.hasPackageJson,
|
|
49
|
+
hasReadme: await exists(path.join(targetPath, 'README.md')),
|
|
50
|
+
hasDocsDir: await exists(path.join(targetPath, 'docs')),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=project-inspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-inspector.js","sourceRoot":"","sources":["../../src/core/project-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGjD,KAAK,UAAU,oBAAoB,CAAC,UAAkB;IACpD,MAAM,MAAM,GAA4B;QACtC,CAAC,gBAAgB,EAAE,MAAM,CAAC;QAC1B,CAAC,mBAAmB,EAAE,KAAK,CAAC;QAC5B,CAAC,WAAW,EAAE,MAAM,CAAC;QACrB,CAAC,WAAW,EAAE,KAAK,CAAC;KACrB,CAAA;IAED,KAAK,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,IAAI,MAAM,EAAE,CAAC;QAChD,IAAI,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO,cAAc,CAAA;QACvB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,UAAkB;IAIjD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;IAC7D,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;QACrC,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YACtC,cAAc,EAAE,KAAK;SACtB,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,CAAA;IAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAA;IAExD,OAAO;QACL,WAAW,EAAE,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC1D,cAAc,EAAE,IAAI;KACrB,CAAA;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,UAAkB,EAAE,UAAoB;IACrE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;YACnD,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB;IACrD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAA;IAEnD,OAAO;QACL,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,cAAc,EAAE,MAAM,oBAAoB,CAAC,UAAU,CAAC;QACtD,UAAU,EAAE,MAAM,eAAe,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QACzE,QAAQ,EAAE,MAAM,eAAe,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAC3E,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,SAAS,EAAE,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC3D,UAAU,EAAE,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;KACxD,CAAA;AACH,CAAC"}
|