@chenmk/superflow 0.1.3 → 0.2.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.
Files changed (113) hide show
  1. package/dist/app/cli.js +218 -0
  2. package/dist/app/cli.js.map +1 -0
  3. package/dist/app/commands/archive.js +6 -0
  4. package/dist/app/commands/archive.js.map +1 -0
  5. package/dist/app/commands/check.js +132 -0
  6. package/dist/app/commands/check.js.map +1 -0
  7. package/dist/app/commands/clarify.js +6 -0
  8. package/dist/app/commands/clarify.js.map +1 -0
  9. package/dist/app/commands/config.js +103 -0
  10. package/dist/app/commands/config.js.map +1 -0
  11. package/dist/app/commands/design.js +28 -0
  12. package/dist/app/commands/design.js.map +1 -0
  13. package/dist/app/commands/docs.js +6 -0
  14. package/dist/app/commands/docs.js.map +1 -0
  15. package/dist/app/commands/doctor.js +494 -0
  16. package/dist/app/commands/doctor.js.map +1 -0
  17. package/dist/app/commands/implement.js +6 -0
  18. package/dist/app/commands/implement.js.map +1 -0
  19. package/dist/app/commands/init.js +520 -0
  20. package/dist/app/commands/init.js.map +1 -0
  21. package/dist/app/commands/pipeline.js +6 -0
  22. package/dist/app/commands/pipeline.js.map +1 -0
  23. package/dist/app/commands/scan.js +63 -0
  24. package/dist/app/commands/scan.js.map +1 -0
  25. package/dist/app/commands/status.js +192 -0
  26. package/dist/app/commands/status.js.map +1 -0
  27. package/dist/app/commands/uninstall.js +214 -0
  28. package/dist/app/commands/uninstall.js.map +1 -0
  29. package/dist/app/commands/update.js +193 -0
  30. package/dist/app/commands/update.js.map +1 -0
  31. package/dist/app/commands/verify.js +6 -0
  32. package/dist/app/commands/verify.js.map +1 -0
  33. package/dist/cli/index.js +1 -1
  34. package/dist/cli/index.js.map +1 -1
  35. package/dist/commands/archive.js +1 -1
  36. package/dist/commands/archive.js.map +1 -1
  37. package/dist/commands/clarify.js +1 -1
  38. package/dist/commands/clarify.js.map +1 -1
  39. package/dist/commands/design.js +1 -1
  40. package/dist/commands/design.js.map +1 -1
  41. package/dist/commands/docs.js +1 -1
  42. package/dist/commands/docs.js.map +1 -1
  43. package/dist/commands/doctor.js +4 -3
  44. package/dist/commands/doctor.js.map +1 -1
  45. package/dist/commands/implement.js +1 -1
  46. package/dist/commands/implement.js.map +1 -1
  47. package/dist/commands/init.js +13 -12
  48. package/dist/commands/init.js.map +1 -1
  49. package/dist/commands/pipeline.js +1 -1
  50. package/dist/commands/pipeline.js.map +1 -1
  51. package/dist/commands/scan.js +2 -2
  52. package/dist/commands/scan.js.map +1 -1
  53. package/dist/commands/status.js +1 -1
  54. package/dist/commands/status.js.map +1 -1
  55. package/dist/commands/uninstall.js +6 -5
  56. package/dist/commands/uninstall.js.map +1 -1
  57. package/dist/commands/update.js +10 -9
  58. package/dist/commands/update.js.map +1 -1
  59. package/dist/commands/verify.js +1 -1
  60. package/dist/commands/verify.js.map +1 -1
  61. package/dist/core/dependencies.js +1 -1
  62. package/dist/core/dependencies.js.map +1 -1
  63. package/dist/core/detect.js +0 -60
  64. package/dist/core/detect.js.map +1 -1
  65. package/dist/core/skill-check.js +3 -2
  66. package/dist/core/skill-check.js.map +1 -1
  67. package/dist/domains/agent.js +64 -0
  68. package/dist/domains/agent.js.map +1 -0
  69. package/dist/domains/config/cli-help.js +98 -0
  70. package/dist/domains/config/cli-help.js.map +1 -0
  71. package/dist/domains/config/context.js +126 -0
  72. package/dist/domains/config/context.js.map +1 -0
  73. package/dist/domains/config/i18n.js +105 -0
  74. package/dist/domains/config/i18n.js.map +1 -0
  75. package/dist/domains/config/manifest.js +21 -0
  76. package/dist/domains/config/manifest.js.map +1 -0
  77. package/dist/domains/deps.js +146 -0
  78. package/dist/domains/deps.js.map +1 -0
  79. package/dist/domains/hook.js +134 -0
  80. package/dist/domains/hook.js.map +1 -0
  81. package/dist/domains/intent.js +69 -0
  82. package/dist/domains/intent.js.map +1 -0
  83. package/dist/domains/run-state.js +47 -0
  84. package/dist/domains/run-state.js.map +1 -0
  85. package/dist/domains/skill/assets.js +27 -0
  86. package/dist/domains/skill/assets.js.map +1 -0
  87. package/dist/domains/skill/check.js +32 -0
  88. package/dist/domains/skill/check.js.map +1 -0
  89. package/dist/domains/skill/deploy.js +62 -0
  90. package/dist/domains/skill/deploy.js.map +1 -0
  91. package/dist/domains/skill/prompts.js +20 -0
  92. package/dist/domains/skill/prompts.js.map +1 -0
  93. package/dist/domains/skill/rules.js +17 -0
  94. package/dist/domains/skill/rules.js.map +1 -0
  95. package/dist/domains/skill/scripts.js +48 -0
  96. package/dist/domains/skill/scripts.js.map +1 -0
  97. package/dist/domains/state-events.js +32 -0
  98. package/dist/domains/state-events.js.map +1 -0
  99. package/dist/domains/state.js +54 -0
  100. package/dist/domains/state.js.map +1 -0
  101. package/dist/domains/workflow-state.js +47 -0
  102. package/dist/domains/workflow-state.js.map +1 -0
  103. package/dist/platform/fs.js +45 -0
  104. package/dist/platform/fs.js.map +1 -0
  105. package/dist/platform/os.js +14 -0
  106. package/dist/platform/os.js.map +1 -0
  107. package/dist/platform/paths.js +55 -0
  108. package/dist/platform/paths.js.map +1 -0
  109. package/dist/platform/process.js +29 -0
  110. package/dist/platform/process.js.map +1 -0
  111. package/dist/platform/version-check.js +45 -0
  112. package/dist/platform/version-check.js.map +1 -0
  113. package/package.json +2 -2
@@ -0,0 +1,21 @@
1
+ import manifestJson from '../../../assets/manifest.json' with { type: 'json' };
2
+ const manifest = manifestJson;
3
+ export function getManifest() {
4
+ return manifest;
5
+ }
6
+ export function getManifestSkillNames() {
7
+ return [...manifest.skills];
8
+ }
9
+ export function getManifestRules() {
10
+ return [...(manifest.rules ?? [])];
11
+ }
12
+ export function getManifestScripts(agent) {
13
+ return [...manifest.scripts, ...(manifest.agentScripts[agent] ?? [])];
14
+ }
15
+ export function getManifestHooks(agent) {
16
+ if (agent === 'opencode') {
17
+ return [...(manifest.agentHooks[agent] ?? [])];
18
+ }
19
+ return [...(manifest.agentHooks[agent] ?? []), ...manifest.hooks];
20
+ }
21
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/domains/config/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,+BAA+B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAc/E,MAAM,QAAQ,GAAG,YAA2B,CAAC;AAE7C,MAAM,UAAU,WAAW;IACzB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAY;IAC7C,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAY;IAC3C,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,146 @@
1
+ import { promises as fs } from 'fs';
2
+ import { homedir } from 'os';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { runCommand } from '../platform/process.js';
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ // dist/domains/deps.js → ../../../assets
9
+ const ASSETS_DIR = path.resolve(__dirname, '..', '..', '..', 'assets');
10
+ function alreadyInstalled(output) {
11
+ return /already\s+(installed|exists)|is\s+already\s+installed|already\s+added/i.test(output);
12
+ }
13
+ /**
14
+ * 安装 openspec CLI(npm 全局)
15
+ * 失败阻塞 init(核心依赖)
16
+ */
17
+ export async function installOpenspec() {
18
+ const result = await runCommand('npm', ['install', '-g', '@fission-ai/openspec@latest']);
19
+ if (result.code !== 0) {
20
+ return { ok: false, error: `npm install failed: ${result.stderr}` };
21
+ }
22
+ return { ok: true };
23
+ }
24
+ export function openspecInitArgs(projectPath, agents, _scope, includeProfile = true) {
25
+ const args = ['init', projectPath, '--tools', agents.join(',')];
26
+ if (includeProfile) {
27
+ args.push('--profile', 'custom');
28
+ }
29
+ return args;
30
+ }
31
+ export async function initializeOpenspec(projectPath, agents, scope) {
32
+ const args = openspecInitArgs(projectPath, agents, scope);
33
+ const result = await runCommand('openspec', args, {
34
+ cwd: projectPath,
35
+ timeout: 120_000,
36
+ });
37
+ if (result.code === 0)
38
+ return { ok: true };
39
+ const stderr = result.stderr || result.stdout;
40
+ if (stderr.includes('unknown option') && stderr.includes('--profile')) {
41
+ const fallback = await runCommand('openspec', openspecInitArgs(projectPath, agents, scope, false), { cwd: projectPath, timeout: 120_000 });
42
+ if (fallback.code === 0)
43
+ return { ok: true };
44
+ return { ok: false, error: fallback.stderr || fallback.stdout };
45
+ }
46
+ return { ok: false, error: stderr };
47
+ }
48
+ /**
49
+ * 安装 superpowers(claude 插件)
50
+ * 失败阻塞 init(核心 HOW/TDD 依赖;已装视为成功)
51
+ */
52
+ export async function installSuperpowers() {
53
+ const result = await runCommand('claude', [
54
+ 'plugin',
55
+ 'install',
56
+ 'superpowers@superpowers-marketplace',
57
+ ]);
58
+ if (result.code !== 0) {
59
+ const output = `${result.stderr}\n${result.stdout}`;
60
+ if (alreadyInstalled(output))
61
+ return { ok: true };
62
+ return { ok: false, error: result.stderr };
63
+ }
64
+ return { ok: true };
65
+ }
66
+ /**
67
+ * 安装 superpowers(Codex 插件)
68
+ * 失败阻塞 init(核心 HOW/TDD 依赖;已装视为成功)
69
+ */
70
+ export async function installCodexSuperpowers() {
71
+ const result = await runCommand('codex', [
72
+ 'plugin',
73
+ 'add',
74
+ 'superpowers@openai-curated',
75
+ ]);
76
+ if (result.code !== 0) {
77
+ const output = `${result.stderr}\n${result.stdout}`;
78
+ if (alreadyInstalled(output))
79
+ return { ok: true };
80
+ return { ok: false, error: result.stderr || result.stdout };
81
+ }
82
+ return { ok: true };
83
+ }
84
+ /**
85
+ * 安装 understand-anything(claude 插件)
86
+ */
87
+ export async function installUnderstand() {
88
+ const result = await runCommand('claude', [
89
+ 'plugin',
90
+ 'install',
91
+ 'understand-anything@understand-anything',
92
+ ]);
93
+ if (result.code !== 0) {
94
+ return { ok: false, error: result.stderr };
95
+ }
96
+ return { ok: true };
97
+ }
98
+ /**
99
+ * 安装 understand-anything(Codex / agents 技能链接)
100
+ */
101
+ export async function installCodexUnderstand() {
102
+ const script = path.join(homedir(), '.understand-anything', 'repo', 'install.sh');
103
+ const result = await runCommand('bash', [script, 'codex']);
104
+ if (result.code !== 0) {
105
+ const fallback = await linkCodexUnderstandSkills();
106
+ if (fallback.ok)
107
+ return fallback;
108
+ return { ok: false, error: `${result.stderr || result.stdout}\n${fallback.error}` };
109
+ }
110
+ return { ok: true };
111
+ }
112
+ async function linkCodexUnderstandSkills() {
113
+ const sourceRoot = path.join(homedir(), '.understand-anything', 'repo', 'understand-anything-plugin', 'skills');
114
+ const targetRoot = path.join(homedir(), '.agents', 'skills');
115
+ try {
116
+ const entries = await fs.readdir(sourceRoot, { withFileTypes: true });
117
+ await fs.mkdir(targetRoot, { recursive: true });
118
+ for (const entry of entries) {
119
+ if (!entry.isDirectory())
120
+ continue;
121
+ const source = path.join(sourceRoot, entry.name);
122
+ const target = path.join(targetRoot, entry.name);
123
+ await fs.rm(target, { recursive: true, force: true });
124
+ await fs.symlink(source, target, process.platform === 'win32' ? 'junction' : 'dir');
125
+ }
126
+ return { ok: true };
127
+ }
128
+ catch (err) {
129
+ return { ok: false, error: `understand-anything fallback failed: ${err.message}` };
130
+ }
131
+ }
132
+ /**
133
+ * 安装 api-doc-changelog(直接复制)
134
+ */
135
+ export async function installApiDocChangelog(skillsDir = path.join(homedir(), '.claude', 'skills')) {
136
+ const source = path.join(ASSETS_DIR, 'skills', 'api-doc-changelog');
137
+ const dest = path.join(skillsDir, 'api-doc-changelog');
138
+ try {
139
+ await fs.cp(source, dest, { recursive: true, force: true });
140
+ return { ok: true };
141
+ }
142
+ catch (err) {
143
+ return { ok: false, error: err.message };
144
+ }
145
+ }
146
+ //# sourceMappingURL=deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/domains/deps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,134 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+ import path from 'path';
3
+ export const HOOK_MAP = {
4
+ 'claude-auto-backup-hook.sh': { event: 'PostToolUse', matcher: 'Edit|Write|Bash' },
5
+ 'codex-auto-backup-hook.sh': { event: 'PostToolUse', matcher: 'Edit|Write|Bash' },
6
+ 'superflow-hook-guard.sh': { event: 'PreToolUse', matcher: 'Edit|Write|NotebookEdit' },
7
+ 'superflow-enforce-hook.sh': { event: 'PreToolUse', matcher: 'Edit|Write|NotebookEdit' },
8
+ 'superflow-contract-hooks.sh': { event: 'PreToolUse', matcher: 'Edit|Write|NotebookEdit' },
9
+ 'superflow-dependency-update-hook.sh': { event: 'UserPromptSubmit' },
10
+ 'superflow-sql-sync-hook.py': { event: 'PreToolUse', matcher: 'Edit|Write|NotebookEdit' },
11
+ 'superflow-delivery-check.sh': { event: 'PreToolUse', matcher: 'Bash' },
12
+ 'superflow-integration-evidence-hook.sh': { event: 'PreToolUse', matcher: 'Bash' },
13
+ };
14
+ /**
15
+ * 判定一个 command path 是否是 SuperBridge Flow 体系管理的 hook。
16
+ * - superflow-* 脚本:路径含 /scripts/superflow- 或 /hooks/superflow-
17
+ * - legacy sdd-* 脚本:用于清理旧版本安装残留
18
+ * - auto-backup-hook.sh:路径含 /scripts/ 或 /hooks/ 下的备份 hook
19
+ * 覆盖 `~` 路径和绝对路径两种写法。
20
+ */
21
+ function isSuperflowManagedHook(command) {
22
+ if (!command)
23
+ return false;
24
+ return (command.includes('/scripts/superflow-') ||
25
+ command.includes('/hooks/superflow-') ||
26
+ command.includes('/scripts/sdd-') ||
27
+ command.includes('/hooks/sdd-') ||
28
+ command.includes('/scripts/claude-auto-backup-hook.sh') ||
29
+ command.includes('/scripts/claude-auto-backup-hook') ||
30
+ command.includes('/hooks/claude-auto-backup-hook.sh') ||
31
+ command.includes('/hooks/claude-auto-backup-hook') ||
32
+ command.includes('/scripts/codex-auto-backup-hook.sh') ||
33
+ command.includes('/scripts/codex-auto-backup-hook') ||
34
+ command.includes('/hooks/codex-auto-backup-hook.sh') ||
35
+ command.includes('/hooks/codex-auto-backup-hook'));
36
+ }
37
+ /**
38
+ * 清理 settings.json 中所有 SuperBridge Flow 体系管理的 hook。
39
+ * - 保留非 superflow hook(用户手写、UserPromptSubmit system 提示等)
40
+ * - 保留所有其他顶层 key(env / enabledPlugins / extraKnownMarketplaces / statusLine / model / skipDangerousModePermissionPrompt)
41
+ * - 修改前自动备份到 .sdd-backup-<ts>
42
+ * - 返回清理掉的 hook command 数(用于日志)
43
+ *
44
+ * 修法理由:init 之前可能用 `~` 路径注册过,本 CLI 用绝对路径;
45
+ * registerHook 跳过逻辑只比较 command 字符串严格相等,会导致新旧并存。
46
+ * 用"全量覆盖"策略:先清所有 superflow/legacy sdd hook,再注册新 hook。
47
+ */
48
+ export function clearSddHooks(settingsFile) {
49
+ if (!existsSync(settingsFile)) {
50
+ mkdirSync(path.dirname(settingsFile), { recursive: true });
51
+ writeFileSync(settingsFile, JSON.stringify({}, null, 2), 'utf-8');
52
+ return 0;
53
+ }
54
+ const settings = JSON.parse(readFileSync(settingsFile, 'utf-8'));
55
+ if (!settings.hooks)
56
+ return 0;
57
+ // 1. 备份
58
+ const backupPath = settingsFile + '.sdd-backup-' + Date.now();
59
+ writeFileSync(backupPath, JSON.stringify(settings, null, 2), 'utf-8');
60
+ // 2. 清理所有 SuperBridge Flow 体系管理的 hook
61
+ let removed = 0;
62
+ for (const event of Object.keys(settings.hooks)) {
63
+ const entries = settings.hooks[event];
64
+ if (!Array.isArray(entries))
65
+ continue;
66
+ const filtered = entries.filter((entry) => {
67
+ const cmds = (entry?.hooks ?? []).map((h) => h.command).filter(Boolean);
68
+ const allSuperflow = cmds.length > 0 && cmds.every((c) => isSuperflowManagedHook(c));
69
+ if (allSuperflow) {
70
+ removed += cmds.length;
71
+ return false; // 整条 entry 全删
72
+ }
73
+ return true;
74
+ });
75
+ if (filtered.length === 0) {
76
+ delete settings.hooks[event];
77
+ }
78
+ else {
79
+ settings.hooks[event] = filtered;
80
+ }
81
+ }
82
+ // 3. 保留所有其他顶层 key
83
+ writeFileSync(settingsFile, JSON.stringify(settings, null, 2), 'utf-8');
84
+ return removed;
85
+ }
86
+ /**
87
+ * 注册一个 hook 到 settings.json(read-merge-write)
88
+ * - 备份 settings.json 到 .sdd-backup-<ts>
89
+ * - 保留所有现有 key
90
+ * - 跳过已存在的 hook
91
+ * - 支持 matcherOverride 用于同脚本注册到多 matcher(superflow-sql-sync-hook.py)
92
+ *
93
+ * 注意:本函数只检查精确字符串相等,不会清理 `~` 路径的旧 hook。
94
+ * 配合 clearSddHooks() 使用(init 阶段先 clear 后 register)可避免重复。
95
+ */
96
+ export function registerHook(settingsFile, scriptName, commandPath, options = {}) {
97
+ if (!existsSync(settingsFile)) {
98
+ mkdirSync(path.dirname(settingsFile), { recursive: true });
99
+ writeFileSync(settingsFile, JSON.stringify({}, null, 2), 'utf-8');
100
+ }
101
+ const settings = JSON.parse(readFileSync(settingsFile, 'utf-8'));
102
+ const map = HOOK_MAP[scriptName];
103
+ if (!map) {
104
+ throw new Error(`Unknown hook script: ${scriptName}. Expected one of: ${Object.keys(HOOK_MAP).join(', ')}`);
105
+ }
106
+ const finalMatcher = options.matcherOverride ?? map.matcher;
107
+ const finalEvent = map.event; // event 不可 override(同一脚本绑定同一 event 不同 matcher)
108
+ // 1. 备份
109
+ const backupPath = settingsFile + '.sdd-backup-' + Date.now();
110
+ writeFileSync(backupPath, JSON.stringify(settings, null, 2), 'utf-8');
111
+ // 2. 合并 hooks
112
+ if (!settings.hooks)
113
+ settings.hooks = {};
114
+ if (!settings.hooks[finalEvent])
115
+ settings.hooks[finalEvent] = [];
116
+ // 3. 跳过已存在(同 command + 同 matcher)
117
+ const exists = settings.hooks[finalEvent].some((entry) => {
118
+ const matcherMatches = finalMatcher === undefined
119
+ ? entry.matcher === undefined
120
+ : entry.matcher === finalMatcher;
121
+ return entry.hooks?.some((h) => h.command === commandPath) && matcherMatches;
122
+ });
123
+ if (!exists) {
124
+ const entry = {
125
+ hooks: [{ type: 'command', command: commandPath, timeout: options.timeout ?? 120 }],
126
+ };
127
+ if (finalMatcher !== undefined)
128
+ entry.matcher = finalMatcher;
129
+ settings.hooks[finalEvent].push(entry);
130
+ }
131
+ // 4. 保留所有现有 key
132
+ writeFileSync(settingsFile, JSON.stringify(settings, null, 2), 'utf-8');
133
+ }
134
+ //# sourceMappingURL=hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/domains/hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /** 触发 hotfix 的关键词(中文 + 英文) */
2
+ const HOTFIX_SIGNALS = [
3
+ '修复', '修', 'fix', 'hotfix', 'bug', '缺陷', '补丁', 'patch',
4
+ '紧急', 'urgent', '崩溃', 'crash', '报错', 'error',
5
+ ];
6
+ /** 触发 tweak 的关键词(纯文档/配置类改动) */
7
+ const TWEAK_SIGNALS = [
8
+ '文档', 'doc', 'readme', '注释', 'comment', '文案', 'copy',
9
+ '配置', 'config', '格式', 'format', 'lint', '排版',
10
+ 'changelog', 'news',
11
+ ];
12
+ /** 触发 resume 的关键词 */
13
+ const RESUME_SIGNALS = [
14
+ '继续', '恢复', 'resume', '接着', '往下', '下一步', 'next',
15
+ ];
16
+ /**
17
+ * 基于用户输入文本检测意图。
18
+ * 规则优先级:hotfix > tweak > resume > full
19
+ */
20
+ export function detectIntent(input) {
21
+ const lower = input.toLowerCase();
22
+ // 1. hotfix 信号
23
+ const hotfixHit = HOTFIX_SIGNALS.filter((s) => lower.includes(s.toLowerCase()));
24
+ if (hotfixHit.length >= 2 || (hotfixHit.length >= 1 && lower.length < 40)) {
25
+ return { intent: 'hotfix', profile: 'hotfix', reason: `检测到修复信号: ${hotfixHit.join(', ')}` };
26
+ }
27
+ // 2. tweak 信号
28
+ const tweakHit = TWEAK_SIGNALS.filter((s) => lower.includes(s.toLowerCase()));
29
+ if (tweakHit.length >= 2 && !containsCodeSignals(lower)) {
30
+ return { intent: 'tweak', profile: 'tweak', reason: `检测到轻量改动信号: ${tweakHit.join(', ')}` };
31
+ }
32
+ // 3. resume 信号
33
+ const resumeHit = RESUME_SIGNALS.filter((s) => lower.includes(s.toLowerCase()));
34
+ if (resumeHit.length >= 1 && lower.length < 60) {
35
+ return { intent: 'resume', profile: 'full', reason: '检测到恢复信号,尝试继续上次中断的任务' };
36
+ }
37
+ // 4. ambiguous:太短无法判断
38
+ if (lower.length < 10) {
39
+ return { intent: 'ambiguous', profile: 'full', reason: '输入过短,无法自动判断意图' };
40
+ }
41
+ // 5. 默认 full
42
+ return { intent: 'full', profile: 'full', reason: '默认为完整工作流' };
43
+ }
44
+ /** 检查是否包含代码改动信号 */
45
+ function containsCodeSignals(input) {
46
+ const codeWords = [
47
+ '函数', 'function', '类', 'class', '接口', 'interface',
48
+ '模块', 'module', '组件', 'component', 'api', 'sql',
49
+ '数据库', 'database', '实现', 'implement', '开发',
50
+ '添加', '新增', 'add', 'feature', 'feat',
51
+ ];
52
+ return codeWords.some((w) => input.includes(w));
53
+ }
54
+ /** 获取意图对应的工作流阶段列表 */
55
+ export function phasesForIntent(intent) {
56
+ switch (intent) {
57
+ case 'full':
58
+ return ['docs', 'design', 'implement', 'verify', 'archive'];
59
+ case 'hotfix':
60
+ return ['implement', 'verify', 'archive'];
61
+ case 'tweak':
62
+ return ['implement', 'verify'];
63
+ case 'resume':
64
+ return []; // 从 run-state 恢复,不预设阶段
65
+ case 'ambiguous':
66
+ return [];
67
+ }
68
+ }
69
+ //# sourceMappingURL=intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent.js","sourceRoot":"","sources":["../../src/domains/intent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
2
+ import path from 'path';
3
+ const RUN_STATE_FILE = '.sdd/run-state.json';
4
+ export function loadRunState(changeDir) {
5
+ const file = path.join(changeDir, RUN_STATE_FILE);
6
+ if (!existsSync(file))
7
+ return null;
8
+ try {
9
+ return JSON.parse(readFileSync(file, 'utf-8'));
10
+ }
11
+ catch {
12
+ return null;
13
+ }
14
+ }
15
+ export function saveRunState(changeDir, state) {
16
+ const file = path.join(changeDir, RUN_STATE_FILE);
17
+ const dir = path.dirname(file);
18
+ if (!existsSync(dir))
19
+ mkdirSync(dir, { recursive: true });
20
+ writeFileSync(file, JSON.stringify({ ...state, updatedAt: new Date().toISOString() }, null, 2), 'utf-8');
21
+ }
22
+ export function initRunState(skill) {
23
+ return {
24
+ runId: `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
25
+ skill,
26
+ currentStep: null,
27
+ iteration: 0,
28
+ retries: {},
29
+ status: 'running',
30
+ updatedAt: new Date().toISOString(),
31
+ };
32
+ }
33
+ /** 增加指定步骤的重试计数 */
34
+ export function recordRetry(state, stepId) {
35
+ const retries = { ...state.retries };
36
+ retries[stepId] = (retries[stepId] ?? 0) + 1;
37
+ return { ...state, retries };
38
+ }
39
+ /** 更新当前步骤并增加迭代计数 */
40
+ export function advanceStep(state, step) {
41
+ return {
42
+ ...state,
43
+ currentStep: step,
44
+ iteration: state.iteration + 1,
45
+ };
46
+ }
47
+ //# sourceMappingURL=run-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-state.js","sourceRoot":"","sources":["../../src/domains/run-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,IAAI,MAAM,MAAM,CAAC;AAuBxB,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAE7C,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAClD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAa,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,SAAiB,EAAE,KAAe;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3G,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO;QACL,KAAK,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACpE,KAAK;QACL,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,CAAC;QACZ,OAAO,EAAE,EAAE;QACX,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC;AAED,kBAAkB;AAClB,MAAM,UAAU,WAAW,CAAC,KAAe,EAAE,MAAc;IACzD,MAAM,OAAO,GAAG,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,OAAO,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC;AAED,oBAAoB;AACpB,MAAM,UAAU,WAAW,CAAC,KAAe,EAAE,IAAY;IACvD,OAAO;QACL,GAAG,KAAK;QACR,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { getManifestHooks, getManifestRules, getManifestScripts, getManifestSkillNames, } from '../config/manifest.js';
2
+ export const ALL_SKILLS = getManifestSkillNames();
3
+ export const ALL_RULES = getManifestRules();
4
+ export const CODEX_PROMPTS = [
5
+ 'superflow-pipeline.md',
6
+ 'superflow-clarify.md',
7
+ 'superflow-docs.md',
8
+ 'superflow-design.md',
9
+ 'superflow-implement.md',
10
+ 'superflow-verify.md',
11
+ 'superflow-archive.md',
12
+ ];
13
+ export const LEGACY_CODEX_PROMPTS = [
14
+ 'sdd.md',
15
+ 'sdd-spec-pipeline.md',
16
+ ];
17
+ export const COMMON_SCRIPTS = getManifestScripts('codex')
18
+ .filter((script) => script !== 'codex-auto-backup-hook.sh');
19
+ export const COMMON_HOOK_SCRIPTS = getManifestHooks('codex')
20
+ .filter((script) => script !== 'codex-auto-backup-hook.sh');
21
+ export function scriptsForAgent(agent) {
22
+ return getManifestScripts(agent);
23
+ }
24
+ export function hookScriptsForAgent(agent) {
25
+ return getManifestHooks(agent);
26
+ }
27
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../../../src/domains/skill/assets.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,CAAC,MAAM,UAAU,GAAG,qBAAqB,EAAE,CAAC;AAClD,MAAM,CAAC,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,uBAAuB;IACvB,sBAAsB;IACtB,mBAAmB;IACnB,qBAAqB;IACrB,wBAAwB;IACxB,qBAAqB;IACrB,sBAAsB;CACvB,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,QAAQ;IACR,sBAAsB;CACvB,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC;KACtD,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,2BAA2B,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,OAAO,CAAC;KACzD,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,2BAA2B,CAAC,CAAC;AAE9D,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAY;IAC9C,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { existsSync } from 'fs';
2
+ import path from 'path';
3
+ import { computeDirHash } from '../../platform/fs.js';
4
+ import { getPlatformPaths } from '../../platform/paths.js';
5
+ import { parseAgentSelection, resolveAgents } from '../agent.js';
6
+ export function checkSkillDeployment(skillName, options = {}) {
7
+ const agents = resolveAgents(parseAgentSelection(options.agent));
8
+ const readyPaths = [];
9
+ for (const agent of agents) {
10
+ const platform = getPlatformPaths(agent);
11
+ const skillPath = path.join(platform.skillsDir, skillName);
12
+ const skillFile = path.join(skillPath, 'SKILL.md');
13
+ if (!existsSync(skillFile)) {
14
+ console.error(`Error: ${skillName} not deployed for ${platform.name}. Run: superflow init --agent ${agent}`);
15
+ process.exit(1);
16
+ }
17
+ try {
18
+ computeDirHash(skillPath);
19
+ }
20
+ catch (err) {
21
+ console.error(`[FAIL] ${platform.name} integrity check failed: ${err.message}`);
22
+ process.exit(2);
23
+ }
24
+ readyPaths.push(` ${platform.name}: ${skillFile}`);
25
+ }
26
+ console.log(`✓ ${skillName} ready at:`);
27
+ for (const readyPath of readyPaths) {
28
+ console.log(readyPath);
29
+ }
30
+ console.log(`\n→ Agent should load this skill via description matching.`);
31
+ }
32
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/domains/skill/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjE,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,UAA6B,EAAE;IAE/B,MAAM,MAAM,GAAG,aAAa,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,SAAS,qBAAqB,QAAQ,CAAC,IAAI,iCAAiC,KAAK,EAAE,CAAC,CAAC;YAC7G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC;YACH,cAAc,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,QAAQ,CAAC,IAAI,4BAA6B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,UAAU,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,YAAY,CAAC,CAAC;IACxC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,62 @@
1
+ import { promises as fs } from 'fs';
2
+ import { existsSync } from 'fs';
3
+ import path from 'path';
4
+ export async function deploySkill(name, assetsDir, skillsDir, options = {}) {
5
+ const source = path.join(assetsDir, name);
6
+ const dest = path.join(skillsDir, name);
7
+ if (existsSync(dest)) {
8
+ if (options.skipExisting)
9
+ return;
10
+ if (options.overwrite !== true) {
11
+ const ts = Date.now();
12
+ const backup = path.join(skillsDir, `${name}.backup-${ts}`);
13
+ await fs.cp(dest, backup, { recursive: true });
14
+ }
15
+ }
16
+ await fs.rm(dest, { recursive: true, force: true });
17
+ await copySkillTree(source, dest, options.agent ?? 'codex');
18
+ }
19
+ export async function listDeployedSkills(skillsDir) {
20
+ if (!existsSync(skillsDir))
21
+ return [];
22
+ const entries = await fs.readdir(skillsDir, { withFileTypes: true });
23
+ return entries
24
+ .filter((e) => e.isDirectory() && !e.name.startsWith('.'))
25
+ .map((e) => e.name);
26
+ }
27
+ async function copySkillTree(source, dest, agent) {
28
+ const stat = await fs.stat(source);
29
+ if (stat.isDirectory()) {
30
+ await fs.mkdir(dest, { recursive: true });
31
+ const entries = await fs.readdir(source, { withFileTypes: true });
32
+ for (const entry of entries) {
33
+ await copySkillTree(path.join(source, entry.name), path.join(dest, entry.name), agent);
34
+ }
35
+ return;
36
+ }
37
+ await fs.mkdir(path.dirname(dest), { recursive: true });
38
+ if (shouldRewriteSkillFile(source)) {
39
+ const content = await fs.readFile(source, 'utf-8');
40
+ await fs.writeFile(dest, rewriteSkillContent(content, agent), 'utf-8');
41
+ return;
42
+ }
43
+ await fs.copyFile(source, dest);
44
+ }
45
+ function shouldRewriteSkillFile(file) {
46
+ return /\.(md|yaml|yml|json)$/i.test(file);
47
+ }
48
+ function rewriteSkillContent(content, agent) {
49
+ if (agent === 'codex')
50
+ return content;
51
+ if (agent === 'opencode') {
52
+ return content
53
+ .replaceAll('~/.codex/hooks', '~/.opencode/scripts')
54
+ .replaceAll('~/.codex/skills', '~/.opencode/skills')
55
+ .replaceAll('Codex Hooks', 'OpenCode Commands');
56
+ }
57
+ return content
58
+ .replaceAll('~/.codex/hooks', '~/.claude/scripts')
59
+ .replaceAll('~/.codex/skills', '~/.claude/skills')
60
+ .replaceAll('Codex Hooks', 'Claude Code Hooks');
61
+ }
62
+ //# sourceMappingURL=deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../src/domains/skill/deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ export async function deployPrompts(promptNames, assetsDir, promptsDir, options = {}) {
4
+ await fs.mkdir(promptsDir, { recursive: true });
5
+ for (const name of promptNames) {
6
+ const source = path.join(assetsDir, name);
7
+ const dest = path.join(promptsDir, name);
8
+ if (options.skipExisting) {
9
+ try {
10
+ await fs.access(dest);
11
+ continue;
12
+ }
13
+ catch {
14
+ // prompt does not exist; deploy it below.
15
+ }
16
+ }
17
+ await fs.cp(source, dest, { recursive: false, force: true });
18
+ }
19
+ }
20
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/domains/skill/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAqB,EACrB,SAAiB,EACjB,UAAkB,EAClB,UAAsC,EAAE;IAExC,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACtB,SAAS;YACX,CAAC;YAAC,MAAM,CAAC;gBACP,0CAA0C;YAC5C,CAAC;QACH,CAAC;QACD,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { promises as fs } from 'fs';
2
+ import { existsSync } from 'fs';
3
+ import path from 'path';
4
+ export async function deployRules(ruleNames, assetsDir, rulesDir, options = {}) {
5
+ await fs.mkdir(rulesDir, { recursive: true });
6
+ for (const name of ruleNames) {
7
+ const source = path.join(assetsDir, name);
8
+ const dest = path.join(rulesDir, name);
9
+ if (options.skipExisting && existsSync(dest))
10
+ continue;
11
+ await fs.cp(source, dest, { recursive: false, force: true });
12
+ }
13
+ }
14
+ export function rulePath(rulesDir, ruleName) {
15
+ return path.join(rulesDir, ruleName);
16
+ }
17
+ //# sourceMappingURL=rules.js.map