@flyin-ai/alloy 0.1.1 → 0.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -90
- package/commands/alloy/apply.md +274 -119
- package/commands/alloy/archive.md +116 -60
- package/commands/alloy/discard.md +57 -15
- package/commands/alloy/finish.md +92 -70
- package/commands/alloy/fix.md +282 -53
- package/commands/alloy/plan.md +125 -63
- package/commands/alloy/references/interaction-style.md +82 -0
- package/commands/alloy/references/main-branch-detection.md +32 -0
- package/commands/alloy/references/phase-routing.md +21 -0
- package/commands/alloy/references/skill-precheck.md +46 -0
- package/commands/alloy/start.md +167 -64
- package/commands/alloy/status.md +1 -1
- package/dist/cli/commands/doctor.d.ts +1 -0
- package/dist/cli/commands/doctor.js +28 -6
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/init.js +40 -37
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/internal/config.d.ts +1 -0
- package/dist/cli/commands/internal/config.js +45 -0
- package/dist/cli/commands/internal/config.js.map +1 -0
- package/dist/cli/commands/internal/guard.js +2 -41
- package/dist/cli/commands/internal/guard.js.map +1 -1
- package/dist/cli/commands/internal/record.js +10 -47
- package/dist/cli/commands/internal/record.js.map +1 -1
- package/dist/cli/commands/internal/skill-usage.d.ts +1 -0
- package/dist/cli/commands/internal/skill-usage.js +78 -0
- package/dist/cli/commands/internal/skill-usage.js.map +1 -0
- package/dist/cli/commands/internal/state.js +105 -6
- package/dist/cli/commands/internal/state.js.map +1 -1
- package/dist/cli/commands/status.d.ts +1 -0
- package/dist/cli/commands/status.js +50 -11
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/update.js +20 -17
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +73 -31
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/hash.d.ts +3 -0
- package/dist/cli/utils/hash.js +42 -0
- package/dist/cli/utils/hash.js.map +1 -0
- package/dist/cli/utils/state.d.ts +4 -2
- package/dist/cli/utils/state.js +34 -2
- package/dist/cli/utils/state.js.map +1 -1
- package/dist/core/artifacts.d.ts +3 -0
- package/dist/core/artifacts.js +45 -0
- package/dist/core/artifacts.js.map +1 -0
- package/dist/core/detect-installations.d.ts +19 -0
- package/dist/core/detect-installations.js +65 -0
- package/dist/core/detect-installations.js.map +1 -0
- package/dist/core/openspec.d.ts +2 -1
- package/dist/core/openspec.js +30 -12
- package/dist/core/openspec.js.map +1 -1
- package/dist/core/skills.js +16 -0
- package/dist/core/skills.js.map +1 -1
- package/dist/core/superpowers.d.ts +8 -1
- package/dist/core/superpowers.js +41 -20
- package/dist/core/superpowers.js.map +1 -1
- package/dist/core/types.d.ts +20 -0
- package/dist/utils/format.d.ts +31 -0
- package/dist/utils/format.js +101 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/output.d.ts +16 -0
- package/dist/utils/output.js +38 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/prompt.d.ts +0 -1
- package/dist/utils/prompt.js +11 -83
- package/dist/utils/prompt.js.map +1 -1
- package/openspec/schemas/alloy/instructions/retrospective.md +17 -35
- package/openspec/schemas/alloy/templates/design.md +2 -0
- package/openspec/schemas/alloy/templates/draft.md +2 -0
- package/openspec/schemas/alloy/templates/plans.md +2 -0
- package/openspec/schemas/alloy/templates/proposal.md +2 -0
- package/openspec/schemas/alloy/templates/retrospective.md +39 -19
- package/openspec/schemas/alloy/templates/specs.md +2 -0
- package/openspec/schemas/alloy/templates/tasks.md +2 -0
- package/package.json +8 -2
package/dist/cli/utils/state.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { readFile, writeFile, readdir } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
1
|
+
import { readFile, writeFile, readdir, mkdir } from "node:fs/promises";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
3
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
4
4
|
function formatTimestamp() {
|
|
5
5
|
const d = new Date();
|
|
@@ -12,10 +12,15 @@ export function createInitialState() {
|
|
|
12
12
|
return {
|
|
13
13
|
phase: "started",
|
|
14
14
|
worktree: null,
|
|
15
|
+
feature_branch: null,
|
|
16
|
+
worktree_branch: null,
|
|
17
|
+
worktree_created_at: null,
|
|
18
|
+
worktree_merged_at: null,
|
|
15
19
|
schema_version: 1,
|
|
16
20
|
created_at: now,
|
|
17
21
|
updated_at: now,
|
|
18
22
|
records: [],
|
|
23
|
+
skill_usage: [],
|
|
19
24
|
};
|
|
20
25
|
}
|
|
21
26
|
export async function readState(changePath) {
|
|
@@ -36,6 +41,7 @@ export async function writeState(changePath, state) {
|
|
|
36
41
|
const yamlPath = join(changePath, ".alloy.yaml");
|
|
37
42
|
state.updated_at = formatTimestamp();
|
|
38
43
|
const content = stringifyYaml(state);
|
|
44
|
+
await mkdir(dirname(yamlPath), { recursive: true });
|
|
39
45
|
await writeFile(yamlPath, content, "utf-8");
|
|
40
46
|
}
|
|
41
47
|
export async function findActiveChanges(changesDir) {
|
|
@@ -61,4 +67,30 @@ export async function findActiveChanges(changesDir) {
|
|
|
61
67
|
}
|
|
62
68
|
return changes;
|
|
63
69
|
}
|
|
70
|
+
// --- 项目级配置(openspec/config.yaml)---
|
|
71
|
+
function createDefaultProjectConfig() {
|
|
72
|
+
return { schema: "alloy", alloy: {} };
|
|
73
|
+
}
|
|
74
|
+
export async function readProjectConfig(projectRoot) {
|
|
75
|
+
const configPath = join(projectRoot, "openspec", "config.yaml");
|
|
76
|
+
try {
|
|
77
|
+
const content = await readFile(configPath, "utf-8");
|
|
78
|
+
const parsed = parseYaml(content);
|
|
79
|
+
if (!parsed.alloy)
|
|
80
|
+
parsed.alloy = {};
|
|
81
|
+
return parsed;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (err.code === "ENOENT") {
|
|
85
|
+
return createDefaultProjectConfig();
|
|
86
|
+
}
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export async function writeProjectConfig(projectRoot, config) {
|
|
91
|
+
const configPath = join(projectRoot, "openspec", "config.yaml");
|
|
92
|
+
await mkdir(dirname(configPath), { recursive: true });
|
|
93
|
+
const content = stringifyYaml(config);
|
|
94
|
+
await writeFile(configPath, content, "utf-8");
|
|
95
|
+
}
|
|
64
96
|
//# sourceMappingURL=state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/cli/utils/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/cli/utils/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFile, stat, readdir } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
export const ARTIFACT_FILES = {
|
|
5
|
+
draft: "draft.md",
|
|
6
|
+
proposal: "proposal.md",
|
|
7
|
+
design: "design.md",
|
|
8
|
+
specs: "specs",
|
|
9
|
+
tasks: "tasks.md",
|
|
10
|
+
plans: "plans.md",
|
|
11
|
+
verify: "verify.md",
|
|
12
|
+
retrospective: "retrospective.md",
|
|
13
|
+
};
|
|
14
|
+
export function computeHash(content) {
|
|
15
|
+
return createHash("sha256").update(content).digest("hex").substring(0, 12);
|
|
16
|
+
}
|
|
17
|
+
export async function computeArtifactHash(changeDir, artifactId) {
|
|
18
|
+
const fileName = ARTIFACT_FILES[artifactId];
|
|
19
|
+
if (!fileName)
|
|
20
|
+
return null;
|
|
21
|
+
const fullPath = join(changeDir, fileName);
|
|
22
|
+
try {
|
|
23
|
+
const st = await stat(fullPath);
|
|
24
|
+
if (st.isDirectory()) {
|
|
25
|
+
const entries = await readdir(fullPath, { withFileTypes: true });
|
|
26
|
+
const files = entries
|
|
27
|
+
.filter((e) => e.isFile())
|
|
28
|
+
.map((e) => e.name)
|
|
29
|
+
.sort();
|
|
30
|
+
const contents = [];
|
|
31
|
+
for (const f of files) {
|
|
32
|
+
contents.push(await readFile(join(fullPath, f)));
|
|
33
|
+
}
|
|
34
|
+
return computeHash(Buffer.concat(contents));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
const content = await readFile(fullPath);
|
|
38
|
+
return computeHash(content);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/core/artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,cAAc,GAA2B;IACpD,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE,aAAa;IACvB,MAAM,EAAE,WAAW;IACnB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,WAAW;IACnB,aAAa,EAAE,kBAAkB;CAClC,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,OAAwB;IAClD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,UAAkB;IAElB,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,KAAK,GAAG,OAAO;iBAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAClB,IAAI,EAAE,CAAC;YACV,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzC,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AgentInfo } from "./types.js";
|
|
2
|
+
export type InstallLocation = "project-command" | "project-skill" | "user-command" | "user-skill" | "user-plugin";
|
|
3
|
+
export interface InstallationInfo {
|
|
4
|
+
found: boolean;
|
|
5
|
+
location: InstallLocation | null;
|
|
6
|
+
path: string | null;
|
|
7
|
+
version: string | null;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 检测某 agent 的命令是否存在。
|
|
11
|
+
* 优先级:项目级 command → 用户级 command
|
|
12
|
+
*/
|
|
13
|
+
export declare function detectCommand(name: string, agent: AgentInfo, projectPath: string): InstallationInfo;
|
|
14
|
+
/**
|
|
15
|
+
* 检测某 agent 的技能是否存在。
|
|
16
|
+
* 优先级:项目级 skill → 用户级 skill → 用户级 plugin
|
|
17
|
+
* 注意:只有 Claude Code 有 skills/plugins,其他 agent 直接返回 NOT_FOUND。
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectSkill(name: string, agent: AgentInfo, projectPath: string): InstallationInfo;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const NOT_FOUND = { found: false, location: null, path: null, version: null };
|
|
5
|
+
/**
|
|
6
|
+
* 检测某 agent 的命令是否存在。
|
|
7
|
+
* 优先级:项目级 command → 用户级 command
|
|
8
|
+
*/
|
|
9
|
+
export function detectCommand(name, agent, projectPath) {
|
|
10
|
+
const cmdFile = `${name}.md`;
|
|
11
|
+
// 项目级 command
|
|
12
|
+
const projectCmd = join(projectPath, agent.commandsDir, cmdFile);
|
|
13
|
+
if (existsSync(projectCmd)) {
|
|
14
|
+
return { found: true, location: "project-command", path: projectCmd, version: null };
|
|
15
|
+
}
|
|
16
|
+
// 用户级 command
|
|
17
|
+
const home = homedir();
|
|
18
|
+
const userCmd = join(home, agent.commandsDir, cmdFile);
|
|
19
|
+
if (existsSync(userCmd)) {
|
|
20
|
+
return { found: true, location: "user-command", path: userCmd, version: null };
|
|
21
|
+
}
|
|
22
|
+
return NOT_FOUND;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 检测某 agent 的技能是否存在。
|
|
26
|
+
* 优先级:项目级 skill → 用户级 skill → 用户级 plugin
|
|
27
|
+
* 注意:只有 Claude Code 有 skills/plugins,其他 agent 直接返回 NOT_FOUND。
|
|
28
|
+
*/
|
|
29
|
+
export function detectSkill(name, agent, projectPath) {
|
|
30
|
+
// skills 只对 Claude Code 有意义(.claude/skills/)
|
|
31
|
+
if (!agent.commandsDir.startsWith(".claude/")) {
|
|
32
|
+
return NOT_FOUND;
|
|
33
|
+
}
|
|
34
|
+
const home = homedir();
|
|
35
|
+
// 项目级 skill
|
|
36
|
+
const projectSkill = join(projectPath, ".claude", "skills", name);
|
|
37
|
+
if (existsSync(projectSkill)) {
|
|
38
|
+
return { found: true, location: "project-skill", path: projectSkill, version: null };
|
|
39
|
+
}
|
|
40
|
+
// 用户级 skill
|
|
41
|
+
const userSkill = join(home, ".claude", "skills", name);
|
|
42
|
+
if (existsSync(userSkill)) {
|
|
43
|
+
return { found: true, location: "user-skill", path: userSkill, version: null };
|
|
44
|
+
}
|
|
45
|
+
// 用户级 plugin(superpowers 插件)
|
|
46
|
+
const pluginBase = join(home, ".claude", "plugins", "cache", "superpowers-marketplace", "superpowers");
|
|
47
|
+
if (existsSync(pluginBase)) {
|
|
48
|
+
try {
|
|
49
|
+
const versions = readdirSync(pluginBase, { withFileTypes: true });
|
|
50
|
+
for (const v of versions) {
|
|
51
|
+
if (!v.isDirectory())
|
|
52
|
+
continue;
|
|
53
|
+
const skillPath = join(pluginBase, v.name, "skills", name);
|
|
54
|
+
if (existsSync(skillPath)) {
|
|
55
|
+
return { found: true, location: "user-plugin", path: skillPath, version: v.name };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// 目录不存在或无法读取
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return NOT_FOUND;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=detect-installations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-installations.js","sourceRoot":"","sources":["../../src/core/detect-installations.ts"],"names":[],"mappings":"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"}
|
package/dist/core/openspec.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
+
import type { AgentInfo } from "./types.js";
|
|
1
2
|
export declare function installOpenSpecCli(): Promise<"installed" | "skipped" | "failed">;
|
|
2
|
-
export declare function initOpenSpecProject(projectPath: string, scope: "global" | "project"): Promise<"initialized" | "skipped" | "failed">;
|
|
3
|
+
export declare function initOpenSpecProject(projectPath: string, scope: "global" | "project", agents?: AgentInfo[]): Promise<"initialized" | "skipped" | "failed">;
|
package/dist/core/openspec.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { mkdirSync, mkdtempSync, writeFileSync, rmSync } from "node:fs";
|
|
2
|
-
import { readFile } from "node:fs/promises";
|
|
3
2
|
import { tmpdir } from "node:os";
|
|
4
3
|
import { join } from "node:path";
|
|
5
4
|
import { execSync } from "node:child_process";
|
|
6
5
|
import { checkOpenSpec } from "./health.js";
|
|
7
6
|
import { loadCompat } from "./compat.js";
|
|
8
7
|
import { getPackageRoot } from "../utils/fs.js";
|
|
8
|
+
import { detectCommand, detectSkill } from "./detect-installations.js";
|
|
9
|
+
import { promptConfirm } from "../utils/prompt.js";
|
|
9
10
|
function createCustomProfile() {
|
|
10
11
|
const configHome = mkdtempSync(join(tmpdir(), "alloy-openspec-profile-"));
|
|
11
12
|
const openspecConfigDir = join(configHome, "openspec");
|
|
@@ -30,8 +31,12 @@ export async function installOpenSpecCli() {
|
|
|
30
31
|
const config = await loadCompat(packageDir);
|
|
31
32
|
const dep = checkOpenSpec(config.compatible.openspec);
|
|
32
33
|
if (dep.installed && dep.compatible) {
|
|
33
|
-
console.log(`
|
|
34
|
-
|
|
34
|
+
console.log(` ℹ OpenSpec CLI ${dep.version} 已安装`);
|
|
35
|
+
const overwrite = await promptConfirm(" 是否覆盖安装?", false);
|
|
36
|
+
if (!overwrite) {
|
|
37
|
+
console.log(` ✓ OpenSpec CLI ${dep.version} 已安装,跳过`);
|
|
38
|
+
return "skipped";
|
|
39
|
+
}
|
|
35
40
|
}
|
|
36
41
|
if (dep.installed && !dep.compatible) {
|
|
37
42
|
console.log(` ⚠ OpenSpec ${dep.version} 不满足要求 ${config.compatible.openspec},重新安装...`);
|
|
@@ -47,19 +52,32 @@ export async function installOpenSpecCli() {
|
|
|
47
52
|
return "failed";
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
|
-
export async function initOpenSpecProject(projectPath, scope) {
|
|
55
|
+
export async function initOpenSpecProject(projectPath, scope, agents) {
|
|
51
56
|
const home = process.env.HOME || process.env.USERPROFILE || "~";
|
|
52
57
|
const targetPath = scope === "global" ? home : projectPath;
|
|
53
58
|
const label = scope === "global" ? "全局" : "项目";
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
// 检测已有 OpenSpec 安装(按每个 agent 独立检测)
|
|
60
|
+
if (agents && agents.length > 0) {
|
|
61
|
+
let hasExisting = false;
|
|
62
|
+
for (const agent of agents) {
|
|
63
|
+
const cmdDetected = detectCommand("opsx/continue", agent, projectPath);
|
|
64
|
+
const skillDetected = detectSkill("openspec-explore", agent, projectPath);
|
|
65
|
+
if (cmdDetected.found || skillDetected.found) {
|
|
66
|
+
hasExisting = true;
|
|
67
|
+
const parts = [];
|
|
68
|
+
if (cmdDetected.found)
|
|
69
|
+
parts.push(`commands: ✓(${cmdDetected.path})`);
|
|
70
|
+
if (skillDetected.found)
|
|
71
|
+
parts.push(`skills: ✓(${skillDetected.path})`);
|
|
72
|
+
console.log(` ℹ OpenSpec 已安装(${agent.label}:${parts.join(", ")})`);
|
|
73
|
+
}
|
|
60
74
|
}
|
|
61
|
-
|
|
62
|
-
|
|
75
|
+
if (hasExisting) {
|
|
76
|
+
const overwrite = await promptConfirm(" openspec init 可能覆盖现有文件,继续?", false);
|
|
77
|
+
if (!overwrite) {
|
|
78
|
+
console.log(" ✓ 跳过 OpenSpec 项目初始化");
|
|
79
|
+
return "skipped";
|
|
80
|
+
}
|
|
63
81
|
}
|
|
64
82
|
}
|
|
65
83
|
const profile = createCustomProfile();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openspec.js","sourceRoot":"","sources":["../../src/core/openspec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"openspec.js","sourceRoot":"","sources":["../../src/core/openspec.ts"],"names":[],"mappings":"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"}
|
package/dist/core/skills.js
CHANGED
|
@@ -2,6 +2,8 @@ import { mkdir, cp, readFile, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { getPackageRoot } from "../utils/fs.js";
|
|
4
4
|
import { getCommandTargetDir } from "./agents.js";
|
|
5
|
+
import { detectCommand } from "./detect-installations.js";
|
|
6
|
+
import { promptConfirm } from "../utils/prompt.js";
|
|
5
7
|
export async function deployCommands(opts) {
|
|
6
8
|
const deployed = [];
|
|
7
9
|
const packageRoot = getPackageRoot();
|
|
@@ -10,6 +12,20 @@ export async function deployCommands(opts) {
|
|
|
10
12
|
const { readdir } = await import("node:fs/promises");
|
|
11
13
|
const entries = await readdir(colonSourceDir, { withFileTypes: true });
|
|
12
14
|
for (const agent of opts.targetAgents) {
|
|
15
|
+
// 检测已有 Alloy commands
|
|
16
|
+
const detected = detectCommand("alloy/start", agent, opts.projectPath);
|
|
17
|
+
if (detected.found) {
|
|
18
|
+
const locationLabel = {
|
|
19
|
+
"project-command": "项目级",
|
|
20
|
+
"user-command": "用户级",
|
|
21
|
+
}[detected.location] || detected.location;
|
|
22
|
+
console.log(` ℹ Alloy commands 已部署(${locationLabel}:${detected.path})`);
|
|
23
|
+
const overwrite = await promptConfirm(` 是否覆盖 ${agent.label} 的 Alloy commands?`, false);
|
|
24
|
+
if (!overwrite) {
|
|
25
|
+
console.log(` ✓ 跳过 ${agent.label} 的 Alloy commands 部署`);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
13
29
|
// Codex: project 模式跳过
|
|
14
30
|
if (agent.globalOnly && opts.scope === "project") {
|
|
15
31
|
console.log(` ⚠ Codex commands 仅全局安装有效,跳过`);
|
package/dist/core/skills.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import type { AgentInfo } from "./types.js";
|
|
2
|
+
export interface SuperpowersInstallResult {
|
|
3
|
+
status: "installed" | "skipped" | "failed";
|
|
4
|
+
version?: string | null;
|
|
5
|
+
location?: string | null;
|
|
6
|
+
requiresUpgrade?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function installSuperpowers(scope: "global" | "project", agent?: AgentInfo, projectPath?: string): Promise<SuperpowersInstallResult>;
|
package/dist/core/superpowers.js
CHANGED
|
@@ -2,21 +2,47 @@ import { execSync } from "node:child_process";
|
|
|
2
2
|
import { cpSync, existsSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import { checkSuperpowers } from "./health.js";
|
|
6
5
|
import { loadCompat } from "./compat.js";
|
|
7
6
|
import { getPackageRoot } from "../utils/fs.js";
|
|
8
|
-
|
|
7
|
+
import { detectSkill } from "./detect-installations.js";
|
|
8
|
+
import { promptConfirm } from "../utils/prompt.js";
|
|
9
|
+
export async function installSuperpowers(scope, agent, projectPath) {
|
|
9
10
|
const packageDir = getPackageRoot();
|
|
10
11
|
const config = await loadCompat(packageDir);
|
|
11
|
-
|
|
12
|
-
if (
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
// 检测已有安装(含版本比较)
|
|
13
|
+
if (agent && projectPath) {
|
|
14
|
+
const detected = detectSkill("brainstorming", agent, projectPath);
|
|
15
|
+
if (detected.found) {
|
|
16
|
+
const locationLabel = {
|
|
17
|
+
"project-skill": "项目级 skill",
|
|
18
|
+
"user-skill": "用户级 skill",
|
|
19
|
+
"user-plugin": "用户级 plugin",
|
|
20
|
+
}[detected.location] || detected.location;
|
|
21
|
+
// 版本比较(如果有版本信息)
|
|
22
|
+
if (detected.version) {
|
|
23
|
+
const semver = (await import("semver")).default;
|
|
24
|
+
const required = config.compatible.superpowers;
|
|
25
|
+
const satisfies = semver.satisfies(detected.version, required);
|
|
26
|
+
if (!satisfies) {
|
|
27
|
+
// 版本不满足要求,需要升级,不提示直接继续安装
|
|
28
|
+
// 继续执行后面的安装逻辑
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// 版本满足要求,提示用户是否覆盖安装
|
|
32
|
+
const overwrite = await promptConfirm(" 是否覆盖安装?", false);
|
|
33
|
+
if (!overwrite) {
|
|
34
|
+
return { status: "skipped", version: detected.version, location: locationLabel };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// 无版本信息,只做存在性提示
|
|
40
|
+
const overwrite = await promptConfirm(" 是否覆盖安装?", false);
|
|
41
|
+
if (!overwrite) {
|
|
42
|
+
return { status: "skipped", location: locationLabel };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
20
46
|
}
|
|
21
47
|
// 尝试网络安装
|
|
22
48
|
const scopeFlag = scope === "global" ? "-g" : "";
|
|
@@ -26,10 +52,9 @@ export async function installSuperpowers(scope) {
|
|
|
26
52
|
stdio: "pipe",
|
|
27
53
|
cwd: process.cwd(),
|
|
28
54
|
});
|
|
29
|
-
return "installed";
|
|
55
|
+
return { status: "installed" };
|
|
30
56
|
}
|
|
31
57
|
catch {
|
|
32
|
-
console.log(" ⚠ 网络安装失败,从本地 vendor 副本部署...");
|
|
33
58
|
return fallbackInstall(scope);
|
|
34
59
|
}
|
|
35
60
|
}
|
|
@@ -38,20 +63,16 @@ function fallbackInstall(scope) {
|
|
|
38
63
|
const packageDir = getPackageRoot();
|
|
39
64
|
const vendorSkills = join(packageDir, "vendor", "superpowers", "skills");
|
|
40
65
|
if (!existsSync(vendorSkills)) {
|
|
41
|
-
|
|
42
|
-
return "failed";
|
|
66
|
+
return { status: "failed" };
|
|
43
67
|
}
|
|
44
68
|
const targetDir = scope === "global"
|
|
45
69
|
? join(homedir(), ".claude", "skills")
|
|
46
70
|
: join(process.cwd(), ".claude", "skills");
|
|
47
|
-
console.log(` → 从 vendor 复制到 ${targetDir}`);
|
|
48
71
|
cpSync(vendorSkills, targetDir, { recursive: true });
|
|
49
|
-
|
|
50
|
-
return "installed";
|
|
72
|
+
return { status: "installed" };
|
|
51
73
|
}
|
|
52
74
|
catch (err) {
|
|
53
|
-
|
|
54
|
-
return "failed";
|
|
75
|
+
return { status: "failed" };
|
|
55
76
|
}
|
|
56
77
|
}
|
|
57
78
|
//# sourceMappingURL=superpowers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"superpowers.js","sourceRoot":"","sources":["../../src/core/superpowers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"superpowers.js","sourceRoot":"","sources":["../../src/core/superpowers.ts"],"names":[],"mappings":"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"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -54,6 +54,15 @@ export interface ArtifactRecord {
|
|
|
54
54
|
committed_at: string;
|
|
55
55
|
approver: string;
|
|
56
56
|
}
|
|
57
|
+
export interface SkillUsageEntry {
|
|
58
|
+
skill: string;
|
|
59
|
+
stage: string;
|
|
60
|
+
used: boolean;
|
|
61
|
+
count?: number;
|
|
62
|
+
via?: string;
|
|
63
|
+
reason?: string;
|
|
64
|
+
recorded_at: string;
|
|
65
|
+
}
|
|
57
66
|
export interface PhaseTiming {
|
|
58
67
|
started_at: string;
|
|
59
68
|
completed_at: string | null;
|
|
@@ -68,9 +77,20 @@ export interface PhaseTimings {
|
|
|
68
77
|
export interface AlloyState {
|
|
69
78
|
phase: "started" | "planned" | "applied" | "archived" | "finished";
|
|
70
79
|
worktree: string | null;
|
|
80
|
+
worktree_branch?: string | null;
|
|
81
|
+
worktree_created_at?: string | null;
|
|
82
|
+
worktree_merged_at?: string | null;
|
|
71
83
|
schema_version: number;
|
|
72
84
|
created_at: string;
|
|
73
85
|
updated_at: string;
|
|
74
86
|
phase_timings?: PhaseTimings;
|
|
75
87
|
records: ArtifactRecord[];
|
|
88
|
+
skill_usage: SkillUsageEntry[];
|
|
89
|
+
feature_branch?: string | null;
|
|
90
|
+
}
|
|
91
|
+
export interface ProjectConfig {
|
|
92
|
+
schema: "alloy";
|
|
93
|
+
alloy: {
|
|
94
|
+
main_branch?: string;
|
|
95
|
+
};
|
|
76
96
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Options as BoxenOptions } from "boxen";
|
|
2
|
+
import { type Ora } from "ora";
|
|
3
|
+
export declare const color: import("picocolors/types.js").Colors & {
|
|
4
|
+
createColors: (enabled?: boolean) => import("picocolors/types.js").Colors;
|
|
5
|
+
};
|
|
6
|
+
export { default as stringWidth } from "string-width";
|
|
7
|
+
export declare function box(text: string, opts?: BoxenOptions): string;
|
|
8
|
+
interface BoxOptions {
|
|
9
|
+
padding?: number;
|
|
10
|
+
margin?: number;
|
|
11
|
+
width?: number;
|
|
12
|
+
title?: string;
|
|
13
|
+
titleAlignment?: "left" | "center" | "right";
|
|
14
|
+
}
|
|
15
|
+
export declare function boxPanel(content: string, opts?: BoxOptions): string;
|
|
16
|
+
export declare function table(headers: string[], rows: string[][]): string;
|
|
17
|
+
export declare function borderedTable(headers: string[], rows: string[][]): string;
|
|
18
|
+
interface TableOptions {
|
|
19
|
+
width?: number;
|
|
20
|
+
headerStyle?: string;
|
|
21
|
+
borderStyle?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function tableWithBorder(headers: string[], rows: string[][], opts?: TableOptions): string;
|
|
24
|
+
export declare function spinner(text: string): Ora;
|
|
25
|
+
interface StatusOptions {
|
|
26
|
+
icon?: string;
|
|
27
|
+
width?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function statusLine(label: string, value: string, status: "success" | "warning" | "error", opts?: StatusOptions): string;
|
|
30
|
+
export declare function progressBar(value: number, total: number, width?: number): string;
|
|
31
|
+
export { default as stripAnsi } from "strip-ansi";
|