@flyin-ai/alloy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +151 -0
  2. package/commands/alloy/apply.md +485 -0
  3. package/commands/alloy/archive.md +170 -0
  4. package/commands/alloy/discard.md +80 -0
  5. package/commands/alloy/finish.md +204 -0
  6. package/commands/alloy/fix.md +149 -0
  7. package/commands/alloy/plan.md +360 -0
  8. package/commands/alloy/start.md +314 -0
  9. package/commands/alloy/status.md +79 -0
  10. package/compat.yaml +10 -0
  11. package/dist/cli/commands/completion.d.ts +1 -0
  12. package/dist/cli/commands/completion.js +155 -0
  13. package/dist/cli/commands/completion.js.map +1 -0
  14. package/dist/cli/commands/doctor.d.ts +7 -0
  15. package/dist/cli/commands/doctor.js +93 -0
  16. package/dist/cli/commands/doctor.js.map +1 -0
  17. package/dist/cli/commands/init.d.ts +6 -0
  18. package/dist/cli/commands/init.js +168 -0
  19. package/dist/cli/commands/init.js.map +1 -0
  20. package/dist/cli/commands/internal/archive.d.ts +1 -0
  21. package/dist/cli/commands/internal/archive.js +91 -0
  22. package/dist/cli/commands/internal/archive.js.map +1 -0
  23. package/dist/cli/commands/internal/guard.d.ts +1 -0
  24. package/dist/cli/commands/internal/guard.js +135 -0
  25. package/dist/cli/commands/internal/guard.js.map +1 -0
  26. package/dist/cli/commands/internal/record.d.ts +1 -0
  27. package/dist/cli/commands/internal/record.js +144 -0
  28. package/dist/cli/commands/internal/record.js.map +1 -0
  29. package/dist/cli/commands/internal/state.d.ts +1 -0
  30. package/dist/cli/commands/internal/state.js +99 -0
  31. package/dist/cli/commands/internal/state.js.map +1 -0
  32. package/dist/cli/commands/status.d.ts +1 -0
  33. package/dist/cli/commands/status.js +112 -0
  34. package/dist/cli/commands/status.js.map +1 -0
  35. package/dist/cli/commands/update.d.ts +1 -0
  36. package/dist/cli/commands/update.js +162 -0
  37. package/dist/cli/commands/update.js.map +1 -0
  38. package/dist/cli/index.d.ts +2 -0
  39. package/dist/cli/index.js +291 -0
  40. package/dist/cli/index.js.map +1 -0
  41. package/dist/cli/utils/state.d.ts +6 -0
  42. package/dist/cli/utils/state.js +64 -0
  43. package/dist/cli/utils/state.js.map +1 -0
  44. package/dist/core/agents.d.ts +8 -0
  45. package/dist/core/agents.js +85 -0
  46. package/dist/core/agents.js.map +1 -0
  47. package/dist/core/claude-md.d.ts +4 -0
  48. package/dist/core/claude-md.js +47 -0
  49. package/dist/core/claude-md.js.map +1 -0
  50. package/dist/core/compat.d.ts +2 -0
  51. package/dist/core/compat.js +8 -0
  52. package/dist/core/compat.js.map +1 -0
  53. package/dist/core/detect.d.ts +2 -0
  54. package/dist/core/detect.js +22 -0
  55. package/dist/core/detect.js.map +1 -0
  56. package/dist/core/health.d.ts +22 -0
  57. package/dist/core/health.js +283 -0
  58. package/dist/core/health.js.map +1 -0
  59. package/dist/core/openspec.d.ts +2 -0
  60. package/dist/core/openspec.js +79 -0
  61. package/dist/core/openspec.js.map +1 -0
  62. package/dist/core/skills.d.ts +3 -0
  63. package/dist/core/skills.js +68 -0
  64. package/dist/core/skills.js.map +1 -0
  65. package/dist/core/superpowers.d.ts +1 -0
  66. package/dist/core/superpowers.js +31 -0
  67. package/dist/core/superpowers.js.map +1 -0
  68. package/dist/core/types.d.ts +76 -0
  69. package/dist/core/types.js +2 -0
  70. package/dist/core/types.js.map +1 -0
  71. package/dist/utils/fs.d.ts +1 -0
  72. package/dist/utils/fs.js +7 -0
  73. package/dist/utils/fs.js.map +1 -0
  74. package/dist/utils/prompt.d.ts +10 -0
  75. package/dist/utils/prompt.js +90 -0
  76. package/dist/utils/prompt.js.map +1 -0
  77. package/openspec/schemas/alloy/instructions/design.md +46 -0
  78. package/openspec/schemas/alloy/instructions/draft.md +39 -0
  79. package/openspec/schemas/alloy/instructions/plans.md +59 -0
  80. package/openspec/schemas/alloy/instructions/proposal.md +34 -0
  81. package/openspec/schemas/alloy/instructions/retrospective.md +157 -0
  82. package/openspec/schemas/alloy/instructions/specs.md +53 -0
  83. package/openspec/schemas/alloy/instructions/tasks.md +40 -0
  84. package/openspec/schemas/alloy/instructions/verify.md +90 -0
  85. package/openspec/schemas/alloy/schema.yaml +100 -0
  86. package/openspec/schemas/alloy/templates/design.md +15 -0
  87. package/openspec/schemas/alloy/templates/draft.md +17 -0
  88. package/openspec/schemas/alloy/templates/plans.md +28 -0
  89. package/openspec/schemas/alloy/templates/proposal.md +22 -0
  90. package/openspec/schemas/alloy/templates/retrospective.md +163 -0
  91. package/openspec/schemas/alloy/templates/specs.md +54 -0
  92. package/openspec/schemas/alloy/templates/tasks.md +8 -0
  93. package/openspec/schemas/alloy/templates/verify.md +55 -0
  94. package/package.json +43 -0
@@ -0,0 +1,162 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { readFileSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { execSync } from "node:child_process";
5
+ import { deployCommands, deploySchema } from "../../core/skills.js";
6
+ import { detectDeployedAgents } from "../../core/agents.js";
7
+ import { runHealthCheck } from "../../core/health.js";
8
+ import { getPackageRoot } from "../../utils/fs.js";
9
+ import { promptConfirm } from "../../utils/prompt.js";
10
+ const CLAUDE_MD_MARKER_START = "<!-- ALLOY-WORKFLOW:START -->";
11
+ const CLAUDE_MD_MARKER_END = "<!-- ALLOY-WORKFLOW:END -->";
12
+ function isDevMode() {
13
+ // npm link 下包根目录不是 symlink,但 .git 存在标记了开发环境
14
+ return existsSync(join(getPackageRoot(), ".git"));
15
+ }
16
+ function detectScope(projectPath) {
17
+ const probe = (dir) => existsSync(join(dir, "commands", "alloy"));
18
+ // 先检测项目级别
19
+ if (probe(join(projectPath, ".claude")))
20
+ return "project";
21
+ // 再检测全局
22
+ const home = process.env.HOME || process.env.USERPROFILE || "~";
23
+ if (probe(join(home, ".claude")))
24
+ return "global";
25
+ return null;
26
+ }
27
+ async function checkLatestVersion() {
28
+ try {
29
+ return execSync("npm view @flyin-ai/alloy version", { stdio: "pipe" })
30
+ .toString()
31
+ .trim();
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ export async function updateCommand(projectPath) {
38
+ const results = [];
39
+ // 1. 自动检测 scope
40
+ const scope = detectScope(projectPath);
41
+ if (!scope) {
42
+ results.push("⚠️ Alloy 未初始化,请先运行 alloy init");
43
+ return results;
44
+ }
45
+ // 2. 开发模式 vs 用户模式
46
+ const dev = isDevMode();
47
+ if (dev) {
48
+ console.log(" 🔧 开发模式,从本地构建重新部署…");
49
+ }
50
+ else {
51
+ const pkg = JSON.parse(readFileSync(join(getPackageRoot(), "package.json"), "utf-8"));
52
+ const currentVersion = pkg.version;
53
+ const latest = await checkLatestVersion();
54
+ if (latest && latest !== currentVersion) {
55
+ console.log(`\n 发现新版本: v${latest}(当前 v${currentVersion})`);
56
+ // 兼容性检查
57
+ console.log(" 🩺 兼容性检查…");
58
+ const health = await runHealthCheck(getPackageRoot(), projectPath);
59
+ const warnings = health.filter((h) => h.status !== "pass");
60
+ if (warnings.length > 0) {
61
+ for (const w of warnings) {
62
+ console.log(` ⚠ ${w.name}: ${w.current}`);
63
+ }
64
+ }
65
+ else {
66
+ console.log(" ✓ 兼容性检查通过");
67
+ }
68
+ // 询问确认
69
+ const doUpdate = await promptConfirm("是否升级 alloy?", false);
70
+ if (doUpdate) {
71
+ try {
72
+ execSync("npm update -g @flyin-ai/alloy", { stdio: "pipe" });
73
+ results.push("✓ alloy CLI 已升级");
74
+ }
75
+ catch {
76
+ results.push("⚠️ CLI 升级失败");
77
+ }
78
+ }
79
+ else {
80
+ results.push(" 已跳过 CLI 升级");
81
+ }
82
+ }
83
+ else if (latest) {
84
+ results.push(`✓ Alloy v${currentVersion} 已是最新`);
85
+ }
86
+ else {
87
+ results.push(`⚠️ 无法检查更新(npm registry 不可达)`);
88
+ }
89
+ }
90
+ // 3. 部署 commands
91
+ const deployedAgents = detectDeployedAgents(scope, projectPath);
92
+ if (deployedAgents.length === 0) {
93
+ results.push("⚠️ 未检测到已部署的 Alloy commands,请先运行 alloy init");
94
+ return results;
95
+ }
96
+ const deployOpts = {
97
+ scope,
98
+ injectClaudeMd: false,
99
+ projectPath,
100
+ targetAgents: deployedAgents,
101
+ };
102
+ try {
103
+ const paths = await deployCommands(deployOpts);
104
+ results.push(`✓ commands/ → 部署 ${paths.length} 个文件到 ${deployedAgents.length} 个 agent`);
105
+ }
106
+ catch {
107
+ results.push("⚠️ command 部署失败");
108
+ }
109
+ try {
110
+ await deploySchema(deployOpts);
111
+ results.push("✓ schema/ → 已部署");
112
+ }
113
+ catch {
114
+ results.push(`⚠️ schema 部署失败`);
115
+ }
116
+ // 4. 更新 CLAUDE.md 标记区域
117
+ const claudeMdPath = join(projectPath, "CLAUDE.md");
118
+ if (existsSync(claudeMdPath)) {
119
+ try {
120
+ let content = await readFile(claudeMdPath, "utf-8");
121
+ if (content.includes(CLAUDE_MD_MARKER_START)) {
122
+ const latestFragment = getLatestClaudeMdFragment();
123
+ const startIdx = content.indexOf(CLAUDE_MD_MARKER_START);
124
+ const endIdx = content.indexOf(CLAUDE_MD_MARKER_END);
125
+ if (endIdx > startIdx) {
126
+ content =
127
+ content.slice(0, startIdx) +
128
+ latestFragment +
129
+ content.slice(endIdx + CLAUDE_MD_MARKER_END.length);
130
+ await writeFile(claudeMdPath, content, "utf-8");
131
+ results.push("✓ CLAUDE.md → Alloy 标记区域已更新");
132
+ }
133
+ }
134
+ }
135
+ catch {
136
+ results.push("⚠️ CLAUDE.md 更新失败");
137
+ }
138
+ }
139
+ return results;
140
+ }
141
+ function getLatestClaudeMdFragment() {
142
+ return [
143
+ "",
144
+ CLAUDE_MD_MARKER_START,
145
+ "## Alloy 工作流",
146
+ "",
147
+ "本项目使用 [Alloy](https://github.com/Rushing0711/alloy) 管理开发工作流。",
148
+ "",
149
+ "常用命令:",
150
+ "- `/alloy-start [topic]` - 智能入口",
151
+ "- `/alloy-plan [name]` - 制品规划",
152
+ "- `/alloy-apply [name]` - 执行实现",
153
+ "- `/alloy-archive [name]` - 归档与收尾",
154
+ "- `/alloy-finish [name]` - 独立收尾",
155
+ "- `/alloy-fix` - Bug 修复",
156
+ "- `/alloy-status [name]` - 查看状态",
157
+ "",
158
+ CLAUDE_MD_MARKER_END,
159
+ "",
160
+ ].join("\n");
161
+ }
162
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from "node:util";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { readFile, writeFile } from "node:fs/promises";
5
+ import { join, dirname } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { statusCommand } from "./commands/status.js";
8
+ import { doctorCommand, formatDoctorResult } from "./commands/doctor.js";
9
+ import { updateCommand } from "./commands/update.js";
10
+ import { generateCompletion } from "./commands/completion.js";
11
+ import { stateCommand } from "./commands/internal/state.js";
12
+ import { guardCommand } from "./commands/internal/guard.js";
13
+ import { recordCommand } from "./commands/internal/record.js";
14
+ const USAGE = `
15
+ alloy <command> [options]
16
+
17
+ Commands:
18
+ init [path] [--scope <project|global>] [--inject-claude-md]
19
+ 项目初始化:检测环境 → 安装依赖 → 部署 schema + skill
20
+ status [path|name] [--json]
21
+ 查看活跃 change 总览,指定 name 查看详情
22
+ doctor [path] [--json]
23
+ 诊断:版本兼容性、文件一致性
24
+ update [path]
25
+ 从 alloy 包重新部署 skill + schema
26
+ completion [bash|zsh|pwsh|powershell] [--install]
27
+ 生成 shell 补全脚本,--install 自动注册
28
+
29
+ Options:
30
+ --version, -v, -V 版本号
31
+ --help, -h 帮助(alloy -h 或 alloy <command> -h)
32
+ `;
33
+ function commandHelp(cmd) {
34
+ switch (cmd) {
35
+ case "init":
36
+ return `
37
+ alloy init [path] [options]
38
+
39
+ 选项:
40
+ --scope <project|global> 安装范围,默认 project
41
+ --inject-claude-md 注入 CLAUDE.md 工作流标记(默认关闭)
42
+ --help, -h 显示本帮助
43
+ `;
44
+ case "status":
45
+ return `
46
+ alloy status [path|name] [options]
47
+
48
+ 参数:
49
+ path 项目路径(默认当前目录)
50
+ name change 名称(查看详情)
51
+
52
+ 选项:
53
+ --json JSON 格式输出
54
+ --help, -h 显示本帮助
55
+ `;
56
+ case "doctor":
57
+ return `
58
+ alloy doctor [path] [options]
59
+
60
+ 选项:
61
+ --json JSON 格式输出
62
+ --help, -h 显示本帮助
63
+ `;
64
+ case "update":
65
+ return `
66
+ alloy update [path] [options]
67
+
68
+ 自动检测 scope(project/global),从 alloy 包重新部署 skill + schema。
69
+ 用户模式下会检查 npm registry 是否有新版本。
70
+
71
+ 选项:
72
+ --help, -h 显示本帮助
73
+ `;
74
+ case "completion":
75
+ return `
76
+ alloy completion [shell] [options]
77
+
78
+ 参数:
79
+ shell 目标 shell(bash / zsh / pwsh / powershell,默认从 $SHELL 检测)
80
+
81
+ 选项:
82
+ --install 自动注册到 shell 配置文件(~/.zshrc / ~/.bashrc / PowerShell profile)
83
+ --help, -h 显示本帮助
84
+
85
+ 示例:
86
+ source <(alloy completion) # 当前 session 生效
87
+ alloy completion --install # 自动注册并立即生效
88
+ alloy completion pwsh | Out-File -FilePath $PROFILE -Append # PowerShell(需先确保目录存在,完成后 . $PROFILE)
89
+ `;
90
+ default:
91
+ return `未知命令: ${cmd}\n使用 alloy --help 查看可用命令。`;
92
+ }
93
+ }
94
+ async function installCompletion(shell) {
95
+ const home = process.env.HOME || process.env.USERPROFILE || "~";
96
+ let rcFile = null;
97
+ let completionLine = "";
98
+ if (shell.includes("zsh")) {
99
+ rcFile = join(home, ".zshrc");
100
+ completionLine = "source <(alloy completion zsh)";
101
+ }
102
+ else if (shell.includes("bash")) {
103
+ rcFile = join(home, ".bashrc");
104
+ completionLine = "source <(alloy completion bash)";
105
+ }
106
+ else if (shell.includes("pwsh") || shell.includes("powershell")) {
107
+ console.log("PowerShell 用户请依次运行:");
108
+ console.log(" New-Item -ItemType Directory -Force -Path (Split-Path $PROFILE)");
109
+ console.log(" alloy completion pwsh | Out-File -FilePath $PROFILE -Append");
110
+ console.log(" . $PROFILE # 重新加载 profile,或重启 PowerShell");
111
+ return;
112
+ }
113
+ if (!rcFile) {
114
+ console.error("无法确定 shell 配置文件路径");
115
+ process.exit(1);
116
+ }
117
+ let content = "";
118
+ try {
119
+ content = await readFile(rcFile, "utf-8");
120
+ }
121
+ catch {
122
+ // 文件不存在
123
+ }
124
+ if (content.includes("alloy completion")) {
125
+ console.log(`✓ shell 补全已存在 → ${rcFile}`);
126
+ return;
127
+ }
128
+ const block = [
129
+ "",
130
+ "# Alloy shell 补全 — Tab 自动补全 alloy 命令",
131
+ completionLine,
132
+ "",
133
+ ].join("\n");
134
+ await writeFile(rcFile, content.trimEnd() + block, "utf-8");
135
+ console.log(`✓ shell 补全已注册 → ${rcFile}`);
136
+ console.log(` 运行 'source ${rcFile}' 或重新打开终端使其生效`);
137
+ }
138
+ async function main() {
139
+ const args = process.argv.slice(2);
140
+ const isHelp = (a) => a.includes("--help") || a.includes("-h");
141
+ const isVersion = (a) => a.includes("--version") || a.includes("-v") || a.includes("-V");
142
+ if (args.length === 0 || (args.length === 1 && isHelp(args))) {
143
+ console.log(USAGE);
144
+ process.exit(0);
145
+ }
146
+ if (args.length === 1 && isVersion(args)) {
147
+ try {
148
+ const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "..", "package.json"), "utf-8"));
149
+ console.log(`alloy v${pkg.version}`);
150
+ }
151
+ catch {
152
+ console.log("alloy v0.1.0");
153
+ }
154
+ process.exit(0);
155
+ }
156
+ const command = args[0];
157
+ const restArgs = args.slice(1);
158
+ if (isHelp(restArgs)) {
159
+ console.log(commandHelp(command));
160
+ process.exit(0);
161
+ }
162
+ switch (command) {
163
+ case "init": {
164
+ const { values, positionals } = parseArgs({
165
+ args: restArgs,
166
+ options: {
167
+ scope: { type: "string" },
168
+ "inject-claude-md": { type: "boolean", default: false },
169
+ },
170
+ strict: true,
171
+ allowPositionals: true,
172
+ });
173
+ const projectPath = positionals[0] ?? process.cwd();
174
+ const { initCommand, selectScope, selectTargetAgents } = await import("./commands/init.js");
175
+ const scope = await selectScope(values.scope);
176
+ const targetAgents = await selectTargetAgents();
177
+ await initCommand({
178
+ scope,
179
+ injectClaudeMd: values["inject-claude-md"] || false,
180
+ projectPath,
181
+ targetAgents,
182
+ });
183
+ break;
184
+ }
185
+ case "status": {
186
+ const { positionals } = parseArgs({
187
+ args: restArgs,
188
+ options: { json: { type: "boolean", default: false } },
189
+ strict: true,
190
+ allowPositionals: true,
191
+ });
192
+ const useJson = restArgs.includes("--json");
193
+ let projectPath;
194
+ let changeName;
195
+ if (positionals.length === 1 && !existsSync(positionals[0])) {
196
+ // 单个参数且非路径 → 视为 change name
197
+ projectPath = process.cwd();
198
+ changeName = positionals[0];
199
+ }
200
+ else {
201
+ projectPath = positionals[0] ?? process.cwd();
202
+ changeName = positionals[1];
203
+ }
204
+ const result = await statusCommand(projectPath, changeName);
205
+ if (useJson) {
206
+ console.log(JSON.stringify({ output: result }, null, 2));
207
+ }
208
+ else {
209
+ console.log(result);
210
+ }
211
+ break;
212
+ }
213
+ case "doctor": {
214
+ const { positionals } = parseArgs({
215
+ args: restArgs,
216
+ options: { json: { type: "boolean", default: false } },
217
+ strict: true,
218
+ allowPositionals: true,
219
+ });
220
+ const useJson = restArgs.includes("--json");
221
+ const result = await doctorCommand(positionals[0] ?? process.cwd());
222
+ console.log(formatDoctorResult(result, useJson));
223
+ break;
224
+ }
225
+ case "update": {
226
+ const { positionals } = parseArgs({
227
+ args: restArgs,
228
+ options: {},
229
+ strict: true,
230
+ allowPositionals: true,
231
+ });
232
+ const results = await updateCommand(positionals[0] ?? process.cwd());
233
+ for (const r of results)
234
+ console.log(` ${r}`);
235
+ break;
236
+ }
237
+ case "completion": {
238
+ const { values, positionals } = parseArgs({
239
+ args: restArgs,
240
+ options: {
241
+ install: { type: "boolean", default: false },
242
+ },
243
+ strict: true,
244
+ allowPositionals: true,
245
+ });
246
+ if (values.install) {
247
+ const shell = positionals[0] ?? process.env.SHELL ?? "bash";
248
+ await installCompletion(shell);
249
+ break;
250
+ }
251
+ // 指定了 shell → 输出补全脚本(用于管道/重定向)
252
+ if (positionals[0]) {
253
+ console.log(generateCompletion(positionals[0]));
254
+ break;
255
+ }
256
+ // 无参数 → 显示友好使用说明
257
+ console.log("生成 shell 补全脚本,获取 Tab 自动补全能力。\n");
258
+ console.log("用法:");
259
+ console.log(" source <(alloy completion zsh) # zsh 当前 session 生效");
260
+ console.log(" source <(alloy completion bash) # bash 当前 session 生效");
261
+ console.log(" alloy completion --install # 自动注册到 rc 文件,永久生效");
262
+ console.log("");
263
+ console.log(" # PowerShell(需先创建目录,再写入 profile,最后 . $PROFILE 或重启)");
264
+ console.log(" New-Item -ItemType Directory -Force -Path (Split-Path $PROFILE)");
265
+ console.log(" alloy completion pwsh | Out-File $PROFILE");
266
+ console.log(" . $PROFILE");
267
+ break;
268
+ }
269
+ case "_state": {
270
+ await stateCommand(restArgs);
271
+ break;
272
+ }
273
+ case "_guard": {
274
+ await guardCommand(restArgs);
275
+ break;
276
+ }
277
+ case "_record": {
278
+ await recordCommand(restArgs);
279
+ break;
280
+ }
281
+ default:
282
+ console.error(`未知命令: ${command}`);
283
+ console.log(USAGE);
284
+ process.exit(1);
285
+ }
286
+ }
287
+ main().catch((err) => {
288
+ console.error(err);
289
+ process.exit(1);
290
+ });
291
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { AlloyState } from "../../core/types.js";
2
+ export type { AlloyState };
3
+ export declare function createInitialState(): AlloyState;
4
+ export declare function readState(changePath: string): Promise<AlloyState>;
5
+ export declare function writeState(changePath: string, state: AlloyState): Promise<void>;
6
+ export declare function findActiveChanges(changesDir: string): Promise<Map<string, AlloyState>>;
@@ -0,0 +1,64 @@
1
+ import { readFile, writeFile, readdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
4
+ function formatTimestamp() {
5
+ const d = new Date();
6
+ const pad = (n) => n.toString().padStart(2, "0");
7
+ // 本地时间,人类可读格式:YYYY-MM-DD HH:MM:SS
8
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
9
+ }
10
+ export function createInitialState() {
11
+ const now = formatTimestamp();
12
+ return {
13
+ phase: "started",
14
+ worktree: null,
15
+ schema_version: 1,
16
+ created_at: now,
17
+ updated_at: now,
18
+ records: [],
19
+ };
20
+ }
21
+ export async function readState(changePath) {
22
+ const yamlPath = join(changePath, ".alloy.yaml");
23
+ let content;
24
+ try {
25
+ content = await readFile(yamlPath, "utf-8");
26
+ }
27
+ catch (err) {
28
+ if (err.code === "ENOENT") {
29
+ throw new Error(`缺少 .alloy.yaml: ${changePath}`);
30
+ }
31
+ throw err;
32
+ }
33
+ return parseYaml(content);
34
+ }
35
+ export async function writeState(changePath, state) {
36
+ const yamlPath = join(changePath, ".alloy.yaml");
37
+ state.updated_at = formatTimestamp();
38
+ const content = stringifyYaml(state);
39
+ await writeFile(yamlPath, content, "utf-8");
40
+ }
41
+ export async function findActiveChanges(changesDir) {
42
+ const changes = new Map();
43
+ try {
44
+ const entries = await readdir(changesDir, { withFileTypes: true });
45
+ for (const entry of entries) {
46
+ if (!entry.isDirectory())
47
+ continue;
48
+ try {
49
+ const state = await readState(join(changesDir, entry.name));
50
+ if (state.phase !== "finished") {
51
+ changes.set(entry.name, state);
52
+ }
53
+ }
54
+ catch {
55
+ // 目录存在但无 .alloy.yaml,跳过
56
+ }
57
+ }
58
+ }
59
+ catch {
60
+ // changes 目录可能不存在
61
+ }
62
+ return changes;
63
+ }
64
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/cli/utils/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { AgentInfo } from "./types.js";
2
+ export declare const KNOWN_AGENTS: AgentInfo[];
3
+ declare const COMMAND_IDS: string[];
4
+ /** 反向推导:检查哪些 agent 已有 alloy command 部署 */
5
+ export declare function detectDeployedAgents(scope: "global" | "project", projectPath: string): AgentInfo[];
6
+ /** 获取 agent command 部署的目标路径 */
7
+ export declare function getCommandTargetDir(agent: AgentInfo, scope: "global" | "project", projectPath: string): string;
8
+ export { COMMAND_IDS };
@@ -0,0 +1,85 @@
1
+ import { join } from "node:path";
2
+ import { existsSync } from "node:fs";
3
+ export const KNOWN_AGENTS = [
4
+ {
5
+ id: "claude-code",
6
+ label: "Claude Code",
7
+ supportsColonCommands: true,
8
+ commandsDir: ".claude/commands/",
9
+ },
10
+ {
11
+ id: "codebuddy",
12
+ label: "CodeBuddy",
13
+ supportsColonCommands: true,
14
+ commandsDir: ".codebuddy/commands/",
15
+ },
16
+ {
17
+ id: "qoder",
18
+ label: "Qoder",
19
+ supportsColonCommands: true,
20
+ commandsDir: ".qoder/commands/",
21
+ },
22
+ {
23
+ id: "cursor",
24
+ label: "Cursor",
25
+ supportsColonCommands: false,
26
+ commandsDir: ".cursor/commands/",
27
+ },
28
+ {
29
+ id: "opencode",
30
+ label: "OpenCode",
31
+ supportsColonCommands: false,
32
+ commandsDir: ".opencode/commands/",
33
+ },
34
+ {
35
+ id: "codex",
36
+ label: "Codex",
37
+ supportsColonCommands: false,
38
+ commandsDir: ".codex/prompts/",
39
+ globalOnly: true,
40
+ },
41
+ {
42
+ id: "trae",
43
+ label: "Trae",
44
+ supportsColonCommands: false,
45
+ commandsDir: ".trae/commands/",
46
+ },
47
+ {
48
+ id: "pi",
49
+ label: "Pi",
50
+ supportsColonCommands: false,
51
+ commandsDir: ".pi/prompts/",
52
+ },
53
+ ];
54
+ const COMMAND_IDS = [
55
+ "start", "plan", "apply", "archive",
56
+ "finish", "fix", "discard", "status",
57
+ ];
58
+ function basePath(scope, projectPath) {
59
+ if (scope === "global") {
60
+ return process.env.HOME || process.env.USERPROFILE || "~";
61
+ }
62
+ return projectPath;
63
+ }
64
+ /** 反向推导:检查哪些 agent 已有 alloy command 部署 */
65
+ export function detectDeployedAgents(scope, projectPath) {
66
+ const base = basePath(scope, projectPath);
67
+ return KNOWN_AGENTS.filter((agent) => {
68
+ const dir = join(base, agent.commandsDir);
69
+ if (agent.supportsColonCommands) {
70
+ const alloyDir = join(dir, "alloy");
71
+ return existsSync(alloyDir) && existsSync(join(alloyDir, "start.md"));
72
+ }
73
+ return existsSync(join(dir, "alloy-start.md"));
74
+ });
75
+ }
76
+ /** 获取 agent command 部署的目标路径 */
77
+ export function getCommandTargetDir(agent, scope, projectPath) {
78
+ const base = basePath(scope, projectPath);
79
+ if (agent.supportsColonCommands) {
80
+ return join(base, agent.commandsDir, "alloy");
81
+ }
82
+ return join(base, agent.commandsDir);
83
+ }
84
+ export { COMMAND_IDS };
85
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/core/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { DeployOptions } from "./types.js";
2
+ export declare const CLAUDE_MD_MARKER_START = "<!-- ALLOY-WORKFLOW:START -->";
3
+ export declare const CLAUDE_MD_MARKER_END = "<!-- ALLOY-WORKFLOW:END -->";
4
+ export declare function injectClaudeMd(opts: DeployOptions): Promise<boolean>;