xwang 0.0.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/assets/skills/xwang/SKILL.md +112 -0
- package/assets/skills/xwang/scripts/xwang-env.sh +48 -0
- package/assets/skills/xwang/scripts/xwang-guard.sh +530 -0
- package/assets/skills/xwang/scripts/xwang-state.sh +374 -0
- package/assets/skills/xwang-archive/SKILL.md +86 -0
- package/assets/skills/xwang-build/REFERENCE.md +94 -0
- package/assets/skills/xwang-build/SKILL.md +113 -0
- package/assets/skills/xwang-design/SKILL.md +104 -0
- package/assets/skills/xwang-hotfix/SKILL.md +102 -0
- package/assets/skills/xwang-open/SKILL.md +108 -0
- package/assets/skills/xwang-open/scripts/xwang-open-check.sh +197 -0
- package/assets/skills/xwang-tweak/SKILL.md +99 -0
- package/assets/skills/xwang-verify/SKILL.md +112 -0
- package/bin/xwang.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 +30 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +238 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/core/detect.d.ts +6 -0
- package/dist/core/detect.d.ts.map +1 -0
- package/dist/core/detect.js +74 -0
- package/dist/core/detect.js.map +1 -0
- package/dist/core/mattpocock.d.ts +6 -0
- package/dist/core/mattpocock.d.ts.map +1 -0
- package/dist/core/mattpocock.js +82 -0
- package/dist/core/mattpocock.js.map +1 -0
- package/dist/core/openspec.d.ts +3 -0
- package/dist/core/openspec.d.ts.map +1 -0
- package/dist/core/openspec.js +178 -0
- package/dist/core/openspec.js.map +1 -0
- package/dist/core/package-manager.d.ts +8 -0
- package/dist/core/package-manager.d.ts.map +1 -0
- package/dist/core/package-manager.js +62 -0
- package/dist/core/package-manager.js.map +1 -0
- package/dist/core/platforms.d.ts +22 -0
- package/dist/core/platforms.d.ts.map +1 -0
- package/dist/core/platforms.js +23 -0
- package/dist/core/platforms.js.map +1 -0
- package/dist/core/superpowers.d.ts +5 -0
- package/dist/core/superpowers.d.ts.map +1 -0
- package/dist/core/superpowers.js +75 -0
- package/dist/core/superpowers.js.map +1 -0
- package/dist/core/types.d.ts +2 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/utils/file-system.d.ts +5 -0
- package/dist/utils/file-system.d.ts.map +1 -0
- package/dist/utils/file-system.js +41 -0
- package/dist/utils/file-system.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: xwang-verify
|
|
3
|
+
description: 启动 xwang 项目阶段4:验证与收尾。基于 PRD、OpenSpec 产物和实现 diff 进行验证,处理开发分支并归档 change。当用户触发 xwang 阶段4、开始验证、xwang-verify,或在 xwang-build 完成后要求验证时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# xwang-verify
|
|
7
|
+
|
|
8
|
+
## 前置条件
|
|
9
|
+
|
|
10
|
+
- 当前 change 的 `.xwang.yaml` 中 `phase` 为 `verify`
|
|
11
|
+
- `openspec/changes/<name>/tasks.md` 全部任务已勾选
|
|
12
|
+
- 代码已提交
|
|
13
|
+
|
|
14
|
+
## Quick start
|
|
15
|
+
|
|
16
|
+
当用户触发 xwang 阶段4时:
|
|
17
|
+
|
|
18
|
+
1. 确定 change 名称 `<name>`:优先使用用户提供的名称;若未提供,从 `openspec/changes/` 下选择 phase 为 `verify` 的 change。
|
|
19
|
+
2. 读取 `.xwang.yaml` 确认当前 phase 为 `verify`。
|
|
20
|
+
3. 评估改动规模,选择 `verify_mode: light` 或 `full`。
|
|
21
|
+
4. 执行验证:
|
|
22
|
+
- **light**:检查 tasks 完成、编译、测试、轻量代码审查
|
|
23
|
+
- **full**:额外对照 PRD、OpenSpec design/spec 验证实现一致性
|
|
24
|
+
5. 验证不通过时暂停并让用户决定修复或接受偏差;修复后回退到 `/xwang-build`。
|
|
25
|
+
6. 验证通过后,若 `branch_status` 已为 `handled`,默认保持分支不变(稍后处理),无需用户确认;否则处理分支(合并/PR/保留)并记录 `branch_status: handled`。
|
|
26
|
+
7. 生成验证报告并写入 `docs/superpowers/reports/YYYY-MM-DD-<name>-verify.md`。
|
|
27
|
+
8. 更新 `.xwang.yaml`:`verification_report` 指向报告,`branch_status: handled`,`phase` 推进到 `archive`,`archived` 保持 `false`;汇报完成。
|
|
28
|
+
|
|
29
|
+
## Workflows
|
|
30
|
+
|
|
31
|
+
开始前先定位 xwang 脚本:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
XWANG_ENV="${XWANG_ENV:-$(find . "$HOME"/.*/skills "$HOME/.config" -path '*/xwang/scripts/xwang-env.sh' -type f -print -quit 2>/dev/null)}"
|
|
35
|
+
if [ -z "$XWANG_ENV" ]; then
|
|
36
|
+
echo "ERROR: xwang-env.sh not found. Ensure the xwang skill is installed." >&2
|
|
37
|
+
return 1
|
|
38
|
+
fi
|
|
39
|
+
. "$XWANG_ENV"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Step 1:入口确认
|
|
43
|
+
|
|
44
|
+
- [ ] 获取 `<name>`:用户未提供时,选择 `.xwang.yaml` 中 `phase: verify` 的 change。
|
|
45
|
+
- [ ] 读取 `openspec/changes/<name>/.xwang.yaml`,确认 `phase` 为 `verify`。
|
|
46
|
+
- [ ] 确认 `plan`、`isolation`、`build_mode`、`tdd_mode` 已记录;`subagent_dispatch` 在 `build_mode: subagent-driven-development` 时必须为 `confirmed`。
|
|
47
|
+
- [ ] 确认 `openspec/changes/<name>/tasks.md` 中所有任务已勾选。
|
|
48
|
+
|
|
49
|
+
### Step 2:规模评估
|
|
50
|
+
|
|
51
|
+
- [ ] 统计任务数、spec 数和变更文件数。
|
|
52
|
+
- [ ] 满足任一条件则设为 `full`:任务数 > 3、spec 能力数 > 1、变更文件数 > 4。
|
|
53
|
+
- [ ] 否则设为 `light`。
|
|
54
|
+
- [ ] 调用 `"$XWANG_STATE" set <name> verify_mode <light|full>`。
|
|
55
|
+
|
|
56
|
+
### Step 3:执行验证
|
|
57
|
+
|
|
58
|
+
**light 模式**:
|
|
59
|
+
|
|
60
|
+
- [ ] tasks.md 全部完成。
|
|
61
|
+
- [ ] 改动文件与 tasks 描述一致(`git diff --stat` 或基于 plan 的 `base-ref` 区间)。
|
|
62
|
+
- [ ] 项目构建通过(执行项目对应构建命令,如 `npm run build`、`mvn compile`、`cargo build` 等)。
|
|
63
|
+
- [ ] 相关测试通过。
|
|
64
|
+
- [ ] 无明显安全问题(无硬编码密钥、无新增 unsafe 操作)。
|
|
65
|
+
- [ ] 使用 Skill 工具加载 Superpowers `requesting-code-review` 技能,请求轻量代码审查(只检查正确性、安全、边界条件)。
|
|
66
|
+
|
|
67
|
+
**full 模式**:
|
|
68
|
+
|
|
69
|
+
- [ ] 完成 light 模式全部检查。
|
|
70
|
+
- [ ] 对照 `docs/mattpocock/<name>-prd.md` 验证目标已满足。
|
|
71
|
+
- [ ] 对照 `openspec/changes/<name>/design.md` 验证实现符合高层设计。
|
|
72
|
+
- [ ] 对照 `openspec/changes/<name>/specs/*/spec.md` 验证能力场景全部通过。
|
|
73
|
+
- [ ] 检查 delta spec 与 PRD/design 是否存在矛盾,必要时让用户决策。
|
|
74
|
+
|
|
75
|
+
**验证失败处理**:
|
|
76
|
+
|
|
77
|
+
- [ ] 列出失败项及严重程度(CRITICAL / IMPORTANT / WARNING / SUGGESTION)。
|
|
78
|
+
- [ ] 使用当前平台的用户输入/确认机制暂停,等待用户选择:
|
|
79
|
+
- **全部修复**:回退到 `/xwang-build`
|
|
80
|
+
- **逐项处理**:CRITICAL / IMPORTANT 必须修复;WARNING / SUGGESTION 可接受偏差,但需记录原因
|
|
81
|
+
- [ ] 用户确认修复后,调用 `"$XWANG_STATE" set <name> phase build`,然后调用 `/xwang-build`。
|
|
82
|
+
|
|
83
|
+
### Step 4:分支处理
|
|
84
|
+
|
|
85
|
+
- [ ] 读取 `.xwang.yaml` 中 `branch_status`:
|
|
86
|
+
- 若 `branch_status` 为 `handled`(由 `/xwang-build` 默认设置为保持分支不变):
|
|
87
|
+
- 默认选择「保持分支(稍后处理)」,**无需用户确认**
|
|
88
|
+
- 在验证报告中记录分支处理方式为「保持分支(稍后处理)」
|
|
89
|
+
- 若 `branch_status` 为 `pending` 或其他:
|
|
90
|
+
- 使用 Skill 工具加载 Superpowers `finishing-a-development-branch` 技能
|
|
91
|
+
- 使用当前平台的用户输入/确认机制暂停,等待用户选择分支处理方式:
|
|
92
|
+
- 本地合并到主分支
|
|
93
|
+
- 推送并创建 PR
|
|
94
|
+
- 保持分支
|
|
95
|
+
- 丢弃工作
|
|
96
|
+
- 处理完成后,调用 `"$XWANG_STATE" set <name> branch_status handled`
|
|
97
|
+
|
|
98
|
+
### Step 5:生成验证报告并推进到 archive
|
|
99
|
+
|
|
100
|
+
- [ ] 创建 `docs/superpowers/reports/` 目录(如不存在)。
|
|
101
|
+
- [ ] 生成 `docs/superpowers/reports/YYYY-MM-DD-<name>-verify.md`,包含验证项结果、失败项与处理记录、分支处理方式。
|
|
102
|
+
- [ ] 调用 `"$XWANG_STATE" set <name> verification_report docs/superpowers/reports/YYYY-MM-DD-<name>-verify.md`。
|
|
103
|
+
- [ ] 若 Step 4 中 branch_status 仍不是 `handled`,调用 `"$XWANG_STATE" set <name> branch_status handled`。
|
|
104
|
+
- [ ] **阶段出口守护(verify → archive)**:调用 `"$XWANG_GUARD" <name> verify --apply` 校验 verify 阶段退出条件,通过后会自动将 `.xwang.yaml` 的 `phase` 推进到 `archive`。
|
|
105
|
+
- [ ] `archived` 保持为 `false`(verify 阶段不做归档处理,只推进 phase)。
|
|
106
|
+
- [ ] 向用户汇报验证报告路径、分支处理结果与当前 phase。
|
|
107
|
+
|
|
108
|
+
## Advanced features
|
|
109
|
+
|
|
110
|
+
- **覆盖 verify_mode**:agent 或用户可随时手动设置 `verify_mode` 为 `light` 或 `full`。
|
|
111
|
+
- **从验证失败恢复**:再次调用 `/xwang-verify` 时,先读取 `.xwang.yaml` 中 `verify_result` 与 `branch_status`,避免重复处理分支。
|
|
112
|
+
- **跳过分支处理**:仅在用户明确要求且记录显式 override 时允许。
|
package/bin/xwang.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command, Option } from 'commander';
|
|
2
|
+
import { initCommand } from '../commands/init.js';
|
|
3
|
+
const program = new Command();
|
|
4
|
+
program.name('xwang').description('xwang CLI').version('0.0.1');
|
|
5
|
+
program
|
|
6
|
+
.command('init [path]')
|
|
7
|
+
.description('初始化 XWANG 工作流')
|
|
8
|
+
.option('--auto', '自动安装缺失组件,跳过已存在组件')
|
|
9
|
+
.addOption(new Option('--scope <scope>', '安装范围').choices(['global', 'project']))
|
|
10
|
+
.action(async (targetPath = '.', options) => {
|
|
11
|
+
try {
|
|
12
|
+
await initCommand(targetPath, options);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (error instanceof Error && error.name === 'ExitPromptError') {
|
|
16
|
+
console.log('\n 已取消。\n');
|
|
17
|
+
process.exit(0);
|
|
18
|
+
}
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
program
|
|
23
|
+
.command('hello')
|
|
24
|
+
.description('Say hello')
|
|
25
|
+
.option('-n, --name <name>', 'Name to greet', 'world')
|
|
26
|
+
.action((options) => {
|
|
27
|
+
console.log('Hello, ' + options.name + '!');
|
|
28
|
+
});
|
|
29
|
+
program.parse();
|
|
30
|
+
//# 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,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhE,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,eAAe,CAAC;KAC5B,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC;KACpC,SAAS,CAAC,IAAI,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;KAC/E,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,EAAE,OAAO,EAAE,EAAE;IAC1C,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC/D,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,WAAW,CAAC;KACxB,MAAM,CAAC,mBAAmB,EAAE,eAAe,EAAE,OAAO,CAAC;KACrD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { InstallScope } from '../core/types.js';
|
|
2
|
+
export type InitOptions = {
|
|
3
|
+
scope?: InstallScope;
|
|
4
|
+
auto?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function selectScope(options?: InitOptions): Promise<InstallScope>;
|
|
7
|
+
export declare function selectPlatforms(detected: Set<string>, options?: InitOptions): Promise<string[]>;
|
|
8
|
+
export declare function initCommand(targetPath: string, options?: InitOptions): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAqBF,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAalF;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBnB;AAmGD,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyJ9F"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import { checkbox, select } from '@inquirer/prompts';
|
|
4
|
+
import { detectPlatforms, getBaseDir, hasSkills } from '../core/detect.js';
|
|
5
|
+
import { installMattpocock, listMattpocockSkills, resolveMattpocockSkillsDir, } from '../core/mattpocock.js';
|
|
6
|
+
import { installOpenSpec } from '../core/openspec.js';
|
|
7
|
+
import { installSuperpowers, listSuperpowersSkills, resolveSuperpowersSkillsDir, } from '../core/superpowers.js';
|
|
8
|
+
import { PLATFORMS, getPlatformSkillsDir } from '../core/platforms.js';
|
|
9
|
+
import { copySkill, ensureDir } from '../utils/file-system.js';
|
|
10
|
+
const XWANG_BANNER = [
|
|
11
|
+
'██╗ ██╗██╗ ██╗ █████╗ ███╗ ██╗ ██████╗ ',
|
|
12
|
+
'╚██╗██╔╝██║ ██║██╔══██╗████╗ ██║██╔════╝ ',
|
|
13
|
+
' ╚███╔╝ ██║ █╗ ██║███████║██╔██╗ ██║██║ ███╗',
|
|
14
|
+
' ██╔██╗ ██║███╗██║██╔══██║██║╚██╗██║██║ ██║',
|
|
15
|
+
'██╔╝ ██╗╚███╔███╔╝██║ ██║██║ ╚████║╚██████╔╝',
|
|
16
|
+
'╚═╝ ╚═╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ',
|
|
17
|
+
' XWANG WORKFLOW ',
|
|
18
|
+
].join('\n');
|
|
19
|
+
export async function selectScope(options = {}) {
|
|
20
|
+
if (options.scope)
|
|
21
|
+
return options.scope;
|
|
22
|
+
if (options.auto)
|
|
23
|
+
return 'project';
|
|
24
|
+
const scope = await select({
|
|
25
|
+
message: '请选择安装范围:',
|
|
26
|
+
choices: [
|
|
27
|
+
{ name: '项目(当前目录)', value: 'project' },
|
|
28
|
+
{ name: '全局(用户主目录)', value: 'global' },
|
|
29
|
+
],
|
|
30
|
+
});
|
|
31
|
+
return scope;
|
|
32
|
+
}
|
|
33
|
+
export async function selectPlatforms(detected, options = {}) {
|
|
34
|
+
const choices = PLATFORMS.map((platform) => ({
|
|
35
|
+
name: platform.name + (detected.has(platform.id) ? '(已检测到)' : ''),
|
|
36
|
+
value: platform.id,
|
|
37
|
+
checked: true,
|
|
38
|
+
}));
|
|
39
|
+
if (options.auto) {
|
|
40
|
+
const selected = [...detected];
|
|
41
|
+
return selected.length > 0 ? selected : PLATFORMS.map((platform) => platform.id);
|
|
42
|
+
}
|
|
43
|
+
const selectedIds = await checkbox({
|
|
44
|
+
message: '请选择要初始化的平台:',
|
|
45
|
+
choices,
|
|
46
|
+
required: true,
|
|
47
|
+
});
|
|
48
|
+
return selectedIds;
|
|
49
|
+
}
|
|
50
|
+
async function promptOverwriteChoice(componentName, platformName) {
|
|
51
|
+
const choice = await select({
|
|
52
|
+
message: `${componentName} 已在 ${platformName} 上安装。如何处理?`,
|
|
53
|
+
choices: [
|
|
54
|
+
{ name: '覆盖', value: 'overwrite' },
|
|
55
|
+
{ name: '跳过', value: 'skip' },
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
return choice;
|
|
59
|
+
}
|
|
60
|
+
function resolveAction(hasExisting, options) {
|
|
61
|
+
if (!hasExisting)
|
|
62
|
+
return 'install';
|
|
63
|
+
if (options.auto)
|
|
64
|
+
return 'skip';
|
|
65
|
+
return 'overwrite';
|
|
66
|
+
}
|
|
67
|
+
function computePlatformStatus(action, globalStatus) {
|
|
68
|
+
if (action === 'skip')
|
|
69
|
+
return 'skipped';
|
|
70
|
+
if (globalStatus === 'failed')
|
|
71
|
+
return 'failed';
|
|
72
|
+
if (action === 'overwrite')
|
|
73
|
+
return 'overwritten';
|
|
74
|
+
return 'installed';
|
|
75
|
+
}
|
|
76
|
+
function normalizeGlobalStatus(status, hasOverwrite) {
|
|
77
|
+
if (status === 'failed')
|
|
78
|
+
return 'failed';
|
|
79
|
+
if (hasOverwrite)
|
|
80
|
+
return 'overwritten';
|
|
81
|
+
return status;
|
|
82
|
+
}
|
|
83
|
+
function statusLabel(status) {
|
|
84
|
+
switch (status) {
|
|
85
|
+
case 'installed':
|
|
86
|
+
return '已安装';
|
|
87
|
+
case 'overwritten':
|
|
88
|
+
return '已覆盖';
|
|
89
|
+
case 'skipped':
|
|
90
|
+
return '已跳过';
|
|
91
|
+
case 'failed':
|
|
92
|
+
return '失败';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function displayComponentSummary(results, scope, componentKey, componentName) {
|
|
96
|
+
const grouped = new Map();
|
|
97
|
+
for (const result of results) {
|
|
98
|
+
const status = result[componentKey];
|
|
99
|
+
const group = grouped.get(status) ?? [];
|
|
100
|
+
group.push(result);
|
|
101
|
+
grouped.set(status, group);
|
|
102
|
+
}
|
|
103
|
+
const installedOrOverwritten = [
|
|
104
|
+
...(grouped.get('installed') ?? []),
|
|
105
|
+
...(grouped.get('overwritten') ?? []),
|
|
106
|
+
];
|
|
107
|
+
if (installedOrOverwritten.length > 0) {
|
|
108
|
+
console.log(` ${componentName} 已安装/覆盖:`);
|
|
109
|
+
for (const result of installedOrOverwritten) {
|
|
110
|
+
const skillsDir = getPlatformSkillsDir(result.platform, scope);
|
|
111
|
+
console.log(` ${result.platform.name} -> ${skillsDir}/skills/`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const [status, items] of grouped) {
|
|
115
|
+
if (status === 'installed' || status === 'overwritten')
|
|
116
|
+
continue;
|
|
117
|
+
const label = statusLabel(status);
|
|
118
|
+
console.log(` ${componentName} ${label}:` + items.map((r) => r.platform.name).join('、'));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function displaySummary(results, scope) {
|
|
122
|
+
const scopeLabel = scope === 'global' ? os.homedir() : 'project';
|
|
123
|
+
console.log('\n XWANG 初始化完成!(范围:' + scopeLabel + ')\n');
|
|
124
|
+
displayComponentSummary(results, scope, 'mattpocock', 'mattpocock');
|
|
125
|
+
displayComponentSummary(results, scope, 'openspec', 'OpenSpec');
|
|
126
|
+
displayComponentSummary(results, scope, 'superpowers', 'Superpowers');
|
|
127
|
+
console.log('');
|
|
128
|
+
}
|
|
129
|
+
export async function initCommand(targetPath, options = {}) {
|
|
130
|
+
const projectPath = path.resolve(targetPath);
|
|
131
|
+
console.log('\n' + XWANG_BANNER + '\n');
|
|
132
|
+
console.log(' 正在 ' + projectPath + ' 中设置 XWANG\n');
|
|
133
|
+
const detected = await detectPlatforms(projectPath);
|
|
134
|
+
const scope = await selectScope(options);
|
|
135
|
+
const selectedPlatformIds = await selectPlatforms(detected, options);
|
|
136
|
+
if (selectedPlatformIds.length === 0) {
|
|
137
|
+
console.log('\n 未选择任何平台,退出。\n');
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const selectedPlatforms = PLATFORMS.filter((platform) => selectedPlatformIds.includes(platform.id));
|
|
141
|
+
const baseDir = getBaseDir(scope, projectPath);
|
|
142
|
+
const plans = [];
|
|
143
|
+
for (const platform of selectedPlatforms) {
|
|
144
|
+
const hasMP = await hasSkills(baseDir, platform, 'mattpocock', scope);
|
|
145
|
+
let mpAction = resolveAction(hasMP, options);
|
|
146
|
+
if (hasMP && !options.auto) {
|
|
147
|
+
mpAction = await promptOverwriteChoice('mattpocock', platform.name);
|
|
148
|
+
}
|
|
149
|
+
const hasOS = await hasSkills(baseDir, platform, 'openspec', scope);
|
|
150
|
+
let osAction = resolveAction(hasOS, options);
|
|
151
|
+
if (hasOS && !options.auto) {
|
|
152
|
+
osAction = await promptOverwriteChoice('OpenSpec', platform.name);
|
|
153
|
+
}
|
|
154
|
+
const hasSP = await hasSkills(baseDir, platform, 'superpowers', scope);
|
|
155
|
+
let spAction = resolveAction(hasSP, options);
|
|
156
|
+
if (hasSP && !options.auto) {
|
|
157
|
+
spAction = await promptOverwriteChoice('Superpowers', platform.name);
|
|
158
|
+
}
|
|
159
|
+
plans.push({ platform, osAction, mpAction, spAction });
|
|
160
|
+
}
|
|
161
|
+
const osToolIds = plans
|
|
162
|
+
.filter((plan) => plan.osAction !== 'skip')
|
|
163
|
+
.map((plan) => plan.platform.openspecToolId);
|
|
164
|
+
const mpPlatformNames = plans
|
|
165
|
+
.filter((plan) => plan.mpAction !== 'skip')
|
|
166
|
+
.map((plan) => plan.platform.name);
|
|
167
|
+
let mattpocockStatus = 'skipped';
|
|
168
|
+
if (mpPlatformNames.length > 0) {
|
|
169
|
+
const hasMpOverwrite = plans.some((p) => p.mpAction === 'overwrite');
|
|
170
|
+
console.log('\n 正在为以下平台安装 mattpocock:' + mpPlatformNames.join('、'));
|
|
171
|
+
mattpocockStatus = normalizeGlobalStatus(await installMattpocock(projectPath, scope, hasMpOverwrite), hasMpOverwrite);
|
|
172
|
+
console.log(' mattpocock:' + statusLabel(mattpocockStatus));
|
|
173
|
+
if (mattpocockStatus !== 'failed') {
|
|
174
|
+
const skillsSourceDir = resolveMattpocockSkillsDir(projectPath, scope);
|
|
175
|
+
if (skillsSourceDir) {
|
|
176
|
+
const skillNames = listMattpocockSkills(skillsSourceDir);
|
|
177
|
+
for (const plan of plans.filter((p) => p.mpAction !== 'skip')) {
|
|
178
|
+
const skillsDir = path.join(baseDir, getPlatformSkillsDir(plan.platform, scope), 'skills');
|
|
179
|
+
await ensureDir(skillsDir);
|
|
180
|
+
for (const skillName of skillNames) {
|
|
181
|
+
const skillSource = path.join(skillsSourceDir, skillName);
|
|
182
|
+
const skillTarget = path.join(skillsDir, skillName);
|
|
183
|
+
await copySkill(skillSource, skillTarget);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
console.log('\n mattpocock:全部跳过');
|
|
191
|
+
}
|
|
192
|
+
let osGlobalStatus = 'skipped';
|
|
193
|
+
if (osToolIds.length > 0) {
|
|
194
|
+
const hasOsOverwrite = plans.some((p) => p.osAction === 'overwrite');
|
|
195
|
+
console.log('\n 正在为以下平台安装 OpenSpec:' + osToolIds.join('、'));
|
|
196
|
+
osGlobalStatus = normalizeGlobalStatus(await installOpenSpec(projectPath, osToolIds, scope), hasOsOverwrite);
|
|
197
|
+
console.log(' OpenSpec:' + statusLabel(osGlobalStatus));
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
console.log('\n OpenSpec:全部跳过');
|
|
201
|
+
}
|
|
202
|
+
const spPlatformNames = plans
|
|
203
|
+
.filter((plan) => plan.spAction !== 'skip')
|
|
204
|
+
.map((plan) => plan.platform.name);
|
|
205
|
+
let spGlobalStatus = 'skipped';
|
|
206
|
+
if (spPlatformNames.length > 0) {
|
|
207
|
+
const hasSpOverwrite = plans.some((p) => p.spAction === 'overwrite');
|
|
208
|
+
console.log('\n 正在为以下平台安装 Superpowers:' + spPlatformNames.join('、'));
|
|
209
|
+
spGlobalStatus = normalizeGlobalStatus(await installSuperpowers(projectPath, scope), hasSpOverwrite);
|
|
210
|
+
console.log(' Superpowers:' + statusLabel(spGlobalStatus));
|
|
211
|
+
if (spGlobalStatus !== 'failed') {
|
|
212
|
+
const skillsSourceDir = resolveSuperpowersSkillsDir(projectPath, scope);
|
|
213
|
+
if (skillsSourceDir) {
|
|
214
|
+
const skillNames = listSuperpowersSkills(skillsSourceDir);
|
|
215
|
+
for (const plan of plans.filter((p) => p.spAction !== 'skip')) {
|
|
216
|
+
const skillsDir = path.join(baseDir, getPlatformSkillsDir(plan.platform, scope), 'skills');
|
|
217
|
+
await ensureDir(skillsDir);
|
|
218
|
+
for (const skillName of skillNames) {
|
|
219
|
+
const skillSource = path.join(skillsSourceDir, skillName);
|
|
220
|
+
const skillTarget = path.join(skillsDir, skillName);
|
|
221
|
+
await copySkill(skillSource, skillTarget);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.log('\n Superpowers:全部跳过');
|
|
229
|
+
}
|
|
230
|
+
const results = plans.map((plan) => ({
|
|
231
|
+
platform: plan.platform,
|
|
232
|
+
mattpocock: computePlatformStatus(plan.mpAction, mattpocockStatus),
|
|
233
|
+
openspec: computePlatformStatus(plan.osAction, osGlobalStatus),
|
|
234
|
+
superpowers: computePlatformStatus(plan.spAction, spGlobalStatus),
|
|
235
|
+
}));
|
|
236
|
+
displaySummary(results, scope);
|
|
237
|
+
}
|
|
238
|
+
//# 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,6 @@
|
|
|
1
|
+
import { type Platform } from './platforms.js';
|
|
2
|
+
import type { InstallScope } from './types.js';
|
|
3
|
+
export declare function getBaseDir(scope: InstallScope, projectPath: string): string;
|
|
4
|
+
export declare function detectPlatforms(projectPath: string): Promise<Set<string>>;
|
|
5
|
+
export declare function hasSkills(baseDir: string, platform: Platform, component: 'openspec' | 'mattpocock' | 'superpowers', scope?: InstallScope): Promise<boolean>;
|
|
6
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/core/detect.ts"],"names":[],"mappings":"AAIA,OAAO,EAAoC,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAsB/E;AAuBD,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,UAAU,GAAG,YAAY,GAAG,aAAa,EACpD,KAAK,GAAE,YAAwB,GAC9B,OAAO,CAAC,OAAO,CAAC,CAkClB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import { fileExists, readDir } from '../utils/file-system.js';
|
|
4
|
+
import { PLATFORMS, getPlatformSkillsDirs } from './platforms.js';
|
|
5
|
+
export function getBaseDir(scope, projectPath) {
|
|
6
|
+
return scope === 'global' ? os.homedir() : projectPath;
|
|
7
|
+
}
|
|
8
|
+
export async function detectPlatforms(projectPath) {
|
|
9
|
+
const detected = new Set();
|
|
10
|
+
for (const platform of PLATFORMS) {
|
|
11
|
+
if (platform.detectionPaths && platform.detectionPaths.length > 0) {
|
|
12
|
+
for (const detectionPath of platform.detectionPaths) {
|
|
13
|
+
if (await fileExists(path.join(projectPath, detectionPath))) {
|
|
14
|
+
detected.add(platform.id);
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
for (const skillsDir of getPlatformSkillsDirs(platform, 'project')) {
|
|
21
|
+
if (await fileExists(path.join(projectPath, skillsDir))) {
|
|
22
|
+
detected.add(platform.id);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return detected;
|
|
29
|
+
}
|
|
30
|
+
const SUPERPOWERS_SKILLS = [
|
|
31
|
+
'brainstorming',
|
|
32
|
+
'using-superpowers',
|
|
33
|
+
'writing-plans',
|
|
34
|
+
'test-driven-development',
|
|
35
|
+
'subagent-driven-development',
|
|
36
|
+
];
|
|
37
|
+
function matchesSkill(entry, component) {
|
|
38
|
+
if (component === 'openspec') {
|
|
39
|
+
return entry.startsWith('openspec-');
|
|
40
|
+
}
|
|
41
|
+
if (component === 'superpowers') {
|
|
42
|
+
return SUPERPOWERS_SKILLS.includes(entry);
|
|
43
|
+
}
|
|
44
|
+
return entry === 'grill-me' || entry === 'to-prd';
|
|
45
|
+
}
|
|
46
|
+
export async function hasSkills(baseDir, platform, component, scope = 'project') {
|
|
47
|
+
const skillDirEntries = await Promise.all(getPlatformSkillsDirs(platform, scope).map(async (skillsDir) => {
|
|
48
|
+
const fullPath = path.join(baseDir, skillsDir, 'skills');
|
|
49
|
+
return {
|
|
50
|
+
skillsDir,
|
|
51
|
+
entries: (await fileExists(fullPath)) ? await readDir(fullPath) : [],
|
|
52
|
+
};
|
|
53
|
+
}));
|
|
54
|
+
const entries = skillDirEntries.flatMap((dir) => dir.entries);
|
|
55
|
+
if (entries.some((entry) => matchesSkill(entry, component))) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
// For project scope, also check global installation as a fallback.
|
|
59
|
+
if (scope === 'project' && baseDir !== os.homedir()) {
|
|
60
|
+
const globalSkillDirEntries = await Promise.all(getPlatformSkillsDirs(platform, 'global').map(async (skillsDir) => {
|
|
61
|
+
const fullPath = path.join(os.homedir(), skillsDir, 'skills');
|
|
62
|
+
return {
|
|
63
|
+
skillsDir,
|
|
64
|
+
entries: (await fileExists(fullPath)) ? await readDir(fullPath) : [],
|
|
65
|
+
};
|
|
66
|
+
}));
|
|
67
|
+
const globalEntries = globalSkillDirEntries.flatMap((dir) => dir.entries);
|
|
68
|
+
if (globalEntries.some((entry) => matchesSkill(entry, component))) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/core/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { InstallScope } from './types.js';
|
|
2
|
+
export declare function resolveMattpocockSkillsDir(projectPath: string, scope: InstallScope): string | null;
|
|
3
|
+
export declare function resolveMattpocockSkillSource(projectPath: string, scope: InstallScope, skillName: string): string | null;
|
|
4
|
+
export declare function listMattpocockSkills(skillsDir: string): string[];
|
|
5
|
+
export declare function installMattpocock(projectPath: string, scope: InstallScope, force?: boolean): Promise<'installed' | 'failed' | 'skipped'>;
|
|
6
|
+
//# sourceMappingURL=mattpocock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mattpocock.d.ts","sourceRoot":"","sources":["../../src/core/mattpocock.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoC/C,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,GAClB,MAAM,GAAG,IAAI,CAQf;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAQf;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAQhE;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,EACnB,KAAK,UAAQ,GACZ,OAAO,CAAC,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC,CAwB7C"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { detectPackageManager, getExecutableName, getPackageManagerInstallArgs, } from './package-manager.js';
|
|
5
|
+
function resolveGlobalNodeModules() {
|
|
6
|
+
try {
|
|
7
|
+
return execFileSync(getExecutableName('npm'), ['root', '-g'], {
|
|
8
|
+
encoding: 'utf-8',
|
|
9
|
+
stdio: 'ignore',
|
|
10
|
+
timeout: 10_000,
|
|
11
|
+
shell: process.platform === 'win32',
|
|
12
|
+
}).trim();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function resolvePackageRoot(projectPath, scope) {
|
|
19
|
+
if (scope === 'project') {
|
|
20
|
+
const projectPackage = path.join(projectPath, 'node_modules', 'xwang-mattpocock');
|
|
21
|
+
if (fs.existsSync(path.join(projectPackage, 'package.json'))) {
|
|
22
|
+
return projectPackage;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (scope === 'global') {
|
|
26
|
+
const globalModules = resolveGlobalNodeModules();
|
|
27
|
+
if (globalModules) {
|
|
28
|
+
const globalPackage = path.join(globalModules, 'xwang-mattpocock');
|
|
29
|
+
if (fs.existsSync(path.join(globalPackage, 'package.json'))) {
|
|
30
|
+
return globalPackage;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
export function resolveMattpocockSkillsDir(projectPath, scope) {
|
|
37
|
+
const packageRoot = resolvePackageRoot(projectPath, scope);
|
|
38
|
+
if (!packageRoot) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const skillsDir = path.join(packageRoot, 'skills');
|
|
42
|
+
return fs.existsSync(skillsDir) ? skillsDir : null;
|
|
43
|
+
}
|
|
44
|
+
export function resolveMattpocockSkillSource(projectPath, scope, skillName) {
|
|
45
|
+
const skillsDir = resolveMattpocockSkillsDir(projectPath, scope);
|
|
46
|
+
if (!skillsDir) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const skillPath = path.join(skillsDir, skillName);
|
|
50
|
+
return fs.existsSync(skillPath) ? skillPath : null;
|
|
51
|
+
}
|
|
52
|
+
export function listMattpocockSkills(skillsDir) {
|
|
53
|
+
try {
|
|
54
|
+
return fs
|
|
55
|
+
.readdirSync(skillsDir)
|
|
56
|
+
.filter((entry) => fs.statSync(path.join(skillsDir, entry)).isDirectory());
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function installMattpocock(projectPath, scope, force = false) {
|
|
63
|
+
if (!force && resolvePackageRoot(projectPath, scope)) {
|
|
64
|
+
return 'skipped';
|
|
65
|
+
}
|
|
66
|
+
const packageManager = detectPackageManager(projectPath);
|
|
67
|
+
const { executable, args } = getPackageManagerInstallArgs(packageManager, 'xwang-mattpocock@latest', scope === 'global');
|
|
68
|
+
try {
|
|
69
|
+
execFileSync(executable, args, {
|
|
70
|
+
cwd: projectPath,
|
|
71
|
+
stdio: 'inherit',
|
|
72
|
+
timeout: 120_000,
|
|
73
|
+
shell: process.platform === 'win32',
|
|
74
|
+
});
|
|
75
|
+
return resolvePackageRoot(projectPath, scope) ? 'installed' : 'failed';
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error(' 安装 mattpocock 失败:' + error.message);
|
|
79
|
+
return 'failed';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=mattpocock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mattpocock.js","sourceRoot":"","sources":["../../src/core/mattpocock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openspec.d.ts","sourceRoot":"","sources":["../../src/core/openspec.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA8J/C,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC,CA8C7C"}
|