@nick848/sf-cli 1.0.1 → 1.0.2

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/dist/cli/index.js CHANGED
@@ -3,11 +3,11 @@
3
3
 
4
4
  var commander = require('commander');
5
5
  var chalk9 = require('chalk');
6
+ var fsSync = require('fs');
7
+ var path6 = require('path');
6
8
  var readline = require('readline');
7
- var path5 = require('path');
8
- var fs5 = require('fs/promises');
9
+ var fs6 = require('fs/promises');
9
10
  var enquirer = require('enquirer');
10
- var fsSync = require('fs');
11
11
  var crypto = require('crypto');
12
12
  var os = require('os');
13
13
  var tiktoken = require('tiktoken');
@@ -15,7 +15,6 @@ require('@modelcontextprotocol/sdk/client/index.js');
15
15
  require('@modelcontextprotocol/sdk/client/stdio.js');
16
16
  var child_process = require('child_process');
17
17
  require('uuid');
18
- var module$1 = require('module');
19
18
 
20
19
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
20
 
@@ -38,17 +37,13 @@ function _interopNamespace(e) {
38
37
  }
39
38
 
40
39
  var chalk9__default = /*#__PURE__*/_interopDefault(chalk9);
41
- var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
42
- var path5__namespace = /*#__PURE__*/_interopNamespace(path5);
43
- var fs5__namespace = /*#__PURE__*/_interopNamespace(fs5);
44
40
  var fsSync__namespace = /*#__PURE__*/_interopNamespace(fsSync);
41
+ var path6__namespace = /*#__PURE__*/_interopNamespace(path6);
42
+ var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
43
+ var fs6__namespace = /*#__PURE__*/_interopNamespace(fs6);
45
44
  var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
46
45
  var os__namespace = /*#__PURE__*/_interopNamespace(os);
47
46
 
48
- // node_modules/tsup/assets/cjs_shims.js
49
- var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
50
- var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
51
-
52
47
  // src/cli/parser.ts
53
48
  var CommandParser = class {
54
49
  slashCommands = [
@@ -130,8 +125,8 @@ var CommandParser = class {
130
125
  };
131
126
  }
132
127
  parseAtPath(input) {
133
- const path12 = input.slice(1).trim();
134
- if (!path12) {
128
+ const path15 = input.slice(1).trim();
129
+ if (!path15) {
135
130
  return { success: false, error: "\u7F3A\u5C11\u6587\u4EF6\u8DEF\u5F84" };
136
131
  }
137
132
  return {
@@ -139,7 +134,7 @@ var CommandParser = class {
139
134
  command: {
140
135
  type: "at" /* AT */,
141
136
  raw: input,
142
- path: path12
137
+ path: path15
143
138
  }
144
139
  };
145
140
  }
@@ -211,11 +206,11 @@ var NormsManager = class {
211
206
  const files = await this.collectProjectFiles(projectPath);
212
207
  for (const filePath of files.slice(0, MAX_FILES_TO_SCAN)) {
213
208
  try {
214
- const stats = await fs5__namespace.stat(filePath);
209
+ const stats = await fs6__namespace.stat(filePath);
215
210
  if (stats.size > MAX_FILE_SIZE) {
216
211
  continue;
217
212
  }
218
- const content = await fs5__namespace.readFile(filePath, "utf-8");
213
+ const content = await fs6__namespace.readFile(filePath, "utf-8");
219
214
  const patterns = await this.learnFromFile(filePath, content);
220
215
  result.patternsFound += patterns.length;
221
216
  result.filesScanned++;
@@ -238,7 +233,7 @@ var NormsManager = class {
238
233
  * 从单个文件学习规范
239
234
  */
240
235
  async learnFromFile(filePath, content) {
241
- const ext = path5__namespace.extname(filePath);
236
+ const ext = path6__namespace.extname(filePath);
242
237
  const patterns = this.extractPatterns(filePath, content, ext);
243
238
  for (const pattern of patterns) {
244
239
  await this.recordOccurrence({
@@ -841,16 +836,16 @@ ${response}`;
841
836
  const files = [];
842
837
  async function scan(dir) {
843
838
  try {
844
- const entries = await fs5__namespace.readdir(dir, { withFileTypes: true });
839
+ const entries = await fs6__namespace.readdir(dir, { withFileTypes: true });
845
840
  for (const entry of entries) {
846
841
  if (entry.isDirectory()) {
847
842
  if (!IGNORED_DIRS.includes(entry.name)) {
848
- await scan(path5__namespace.join(dir, entry.name));
843
+ await scan(path6__namespace.join(dir, entry.name));
849
844
  }
850
845
  } else if (entry.isFile()) {
851
- const ext = path5__namespace.extname(entry.name);
846
+ const ext = path6__namespace.extname(entry.name);
852
847
  if (SCAN_EXTENSIONS.includes(ext)) {
853
- files.push(path5__namespace.join(dir, entry.name));
848
+ files.push(path6__namespace.join(dir, entry.name));
854
849
  }
855
850
  }
856
851
  }
@@ -884,16 +879,16 @@ ${response}`;
884
879
  * 确保规范目录存在
885
880
  */
886
881
  async ensureNormsDir() {
887
- await fs5__namespace.mkdir(this.config.normsDir, { recursive: true });
888
- await fs5__namespace.mkdir(path5__namespace.join(this.config.normsDir, "weekly"), { recursive: true });
882
+ await fs6__namespace.mkdir(this.config.normsDir, { recursive: true });
883
+ await fs6__namespace.mkdir(path6__namespace.join(this.config.normsDir, "weekly"), { recursive: true });
889
884
  }
890
885
  /**
891
886
  * 加载已有规范
892
887
  */
893
888
  async loadStandards() {
894
- const standardsPath = path5__namespace.join(this.config.normsDir, "patterns.json");
889
+ const standardsPath = path6__namespace.join(this.config.normsDir, "patterns.json");
895
890
  try {
896
- const content = await fs5__namespace.readFile(standardsPath, "utf-8");
891
+ const content = await fs6__namespace.readFile(standardsPath, "utf-8");
897
892
  const data = JSON.parse(content);
898
893
  for (const standard of data) {
899
894
  this.standards.set(standard.id, {
@@ -909,9 +904,9 @@ ${response}`;
909
904
  * 加载权重数据
910
905
  */
911
906
  async loadWeights() {
912
- const weightsPath = path5__namespace.join(this.config.normsDir, "weights.json");
907
+ const weightsPath = path6__namespace.join(this.config.normsDir, "weights.json");
913
908
  try {
914
- const content = await fs5__namespace.readFile(weightsPath, "utf-8");
909
+ const content = await fs6__namespace.readFile(weightsPath, "utf-8");
915
910
  const data = JSON.parse(content);
916
911
  for (const weight of data) {
917
912
  this.weights.set(weight.standardId, {
@@ -926,8 +921,8 @@ ${response}`;
926
921
  * 保存规范
927
922
  */
928
923
  async saveStandards() {
929
- const standardsPath = path5__namespace.join(this.config.normsDir, "patterns.json");
930
- await fs5__namespace.writeFile(
924
+ const standardsPath = path6__namespace.join(this.config.normsDir, "patterns.json");
925
+ await fs6__namespace.writeFile(
931
926
  standardsPath,
932
927
  JSON.stringify(Array.from(this.standards.values()), null, 2),
933
928
  "utf-8"
@@ -937,8 +932,8 @@ ${response}`;
937
932
  * 保存权重
938
933
  */
939
934
  async saveWeights() {
940
- const weightsPath = path5__namespace.join(this.config.normsDir, "weights.json");
941
- await fs5__namespace.writeFile(
935
+ const weightsPath = path6__namespace.join(this.config.normsDir, "weights.json");
936
+ await fs6__namespace.writeFile(
942
937
  weightsPath,
943
938
  JSON.stringify(Array.from(this.weights.values()), null, 2),
944
939
  "utf-8"
@@ -965,8 +960,8 @@ ${response}`;
965
960
  * 保存周报
966
961
  */
967
962
  async saveWeeklyReport(weekId, report) {
968
- const reportPath = path5__namespace.join(this.config.normsDir, "weekly", `${weekId}.json`);
969
- await fs5__namespace.writeFile(reportPath, JSON.stringify(report, null, 2), "utf-8");
963
+ const reportPath = path6__namespace.join(this.config.normsDir, "weekly", `${weekId}.json`);
964
+ await fs6__namespace.writeFile(reportPath, JSON.stringify(report, null, 2), "utf-8");
970
965
  }
971
966
  /**
972
967
  * 更新 devstanded.md
@@ -974,8 +969,8 @@ ${response}`;
974
969
  async updateDevStandedMd() {
975
970
  const standards = this.getEffectiveStandards();
976
971
  const content = this.generateDevStandedMd(standards);
977
- const mdPath = path5__namespace.join(this.config.normsDir, "devstanded.md");
978
- await fs5__namespace.writeFile(mdPath, content, "utf-8");
972
+ const mdPath = path6__namespace.join(this.config.normsDir, "devstanded.md");
973
+ await fs6__namespace.writeFile(mdPath, content, "utf-8");
979
974
  }
980
975
  /**
981
976
  * 生成 devstanded.md 内容
@@ -1114,7 +1109,7 @@ async function handleInit(args, ctx) {
1114
1109
  async function initProject(options = {}, workingDir) {
1115
1110
  const cwd = workingDir || process.cwd();
1116
1111
  try {
1117
- const stats = await fs5__namespace.stat(cwd);
1112
+ const stats = await fs6__namespace.stat(cwd);
1118
1113
  if (!stats.isDirectory()) {
1119
1114
  return {
1120
1115
  output: chalk9__default.default.red(`\u9519\u8BEF: ${cwd} \u4E0D\u662F\u6709\u6548\u76EE\u5F55`)
@@ -1125,9 +1120,9 @@ async function initProject(options = {}, workingDir) {
1125
1120
  output: chalk9__default.default.red(`\u9519\u8BEF: \u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u9650\u8BBF\u95EE ${cwd}`)
1126
1121
  };
1127
1122
  }
1128
- const sfCliDir = path5__namespace.join(cwd, ".sf-cli");
1129
- const openspecDir = path5__namespace.join(cwd, "openspec");
1130
- const agentsMdPath = path5__namespace.join(cwd, "AGENTS.md");
1123
+ const sfCliDir = path6__namespace.join(cwd, ".sf-cli");
1124
+ const openspecDir = path6__namespace.join(cwd, "openspec");
1125
+ const agentsMdPath = path6__namespace.join(cwd, "AGENTS.md");
1131
1126
  try {
1132
1127
  const agentsExists = await fileExists(agentsMdPath);
1133
1128
  if (agentsExists && !options.force) {
@@ -1146,7 +1141,7 @@ async function initProject(options = {}, workingDir) {
1146
1141
  await normsManager.initialize();
1147
1142
  const scanResult = await normsManager.scanProject(cwd);
1148
1143
  const agentsContent = generateAgentsMd(projectInfo, scanResult);
1149
- await fs5__namespace.writeFile(agentsMdPath, agentsContent, "utf-8");
1144
+ await fs6__namespace.writeFile(agentsMdPath, agentsContent, "utf-8");
1150
1145
  await generateOpenSpecConfig(openspecDir, projectInfo);
1151
1146
  return {
1152
1147
  output: chalk9__default.default.green("\u2713 \u9879\u76EE\u521D\u59CB\u5316\u5B8C\u6210\n") + chalk9__default.default.gray(` \u9879\u76EE\u7C7B\u578B: ${projectInfo.type}
@@ -1187,7 +1182,7 @@ async function createSfCliDirectory(basePath) {
1187
1182
  "logs"
1188
1183
  ];
1189
1184
  for (const dir of dirs) {
1190
- await fs5__namespace.mkdir(path5__namespace.join(basePath, dir), { recursive: true });
1185
+ await fs6__namespace.mkdir(path6__namespace.join(basePath, dir), { recursive: true });
1191
1186
  }
1192
1187
  const config = {
1193
1188
  version: "1.0.0",
@@ -1195,37 +1190,37 @@ async function createSfCliDirectory(basePath) {
1195
1190
  yolo: false,
1196
1191
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
1197
1192
  };
1198
- await fs5__namespace.writeFile(
1199
- path5__namespace.join(basePath, "config.json"),
1193
+ await fs6__namespace.writeFile(
1194
+ path6__namespace.join(basePath, "config.json"),
1200
1195
  JSON.stringify(config, null, 2),
1201
1196
  "utf-8"
1202
1197
  );
1203
- await fs5__namespace.writeFile(
1204
- path5__namespace.join(basePath, "agents", "registry.json"),
1198
+ await fs6__namespace.writeFile(
1199
+ path6__namespace.join(basePath, "agents", "registry.json"),
1205
1200
  JSON.stringify({ version: "1.0.0", agents: {} }, null, 2),
1206
1201
  "utf-8"
1207
1202
  );
1208
- await fs5__namespace.writeFile(
1209
- path5__namespace.join(basePath, "skills", "registry.json"),
1203
+ await fs6__namespace.writeFile(
1204
+ path6__namespace.join(basePath, "skills", "registry.json"),
1210
1205
  JSON.stringify({ version: "1.0.0", skills: {} }, null, 2),
1211
1206
  "utf-8"
1212
1207
  );
1213
- await fs5__namespace.writeFile(
1214
- path5__namespace.join(basePath, "health", "health.md"),
1208
+ await fs6__namespace.writeFile(
1209
+ path6__namespace.join(basePath, "health", "health.md"),
1215
1210
  generateHealthTemplate(),
1216
1211
  "utf-8"
1217
1212
  );
1218
1213
  }
1219
1214
  async function createOpenSpecDirectory(basePath) {
1220
- const changesDir = path5__namespace.join(basePath, "changes");
1221
- const archiveDir = path5__namespace.join(changesDir, "archive");
1222
- const specDir = path5__namespace.join(basePath, "spec");
1223
- await fs5__namespace.mkdir(archiveDir, { recursive: true });
1224
- await fs5__namespace.mkdir(specDir, { recursive: true });
1215
+ const changesDir = path6__namespace.join(basePath, "changes");
1216
+ const archiveDir = path6__namespace.join(changesDir, "archive");
1217
+ const specDir = path6__namespace.join(basePath, "spec");
1218
+ await fs6__namespace.mkdir(archiveDir, { recursive: true });
1219
+ await fs6__namespace.mkdir(specDir, { recursive: true });
1225
1220
  }
1226
1221
  async function analyzeProject(cwd) {
1227
1222
  const result = {
1228
- name: path5__namespace.basename(cwd),
1223
+ name: path6__namespace.basename(cwd),
1229
1224
  type: "unknown",
1230
1225
  framework: null,
1231
1226
  techStack: [],
@@ -1244,9 +1239,9 @@ async function analyzeProject(cwd) {
1244
1239
  hasEslint: false,
1245
1240
  hasPrettier: false
1246
1241
  };
1247
- const pkgPath = path5__namespace.join(cwd, "package.json");
1242
+ const pkgPath = path6__namespace.join(cwd, "package.json");
1248
1243
  try {
1249
- const pkgContent = await fs5__namespace.readFile(pkgPath, "utf-8");
1244
+ const pkgContent = await fs6__namespace.readFile(pkgPath, "utf-8");
1250
1245
  const pkg = JSON.parse(pkgContent);
1251
1246
  result.name = pkg.name || result.name;
1252
1247
  result.dependencies = pkg.dependencies || {};
@@ -1329,7 +1324,7 @@ async function analyzeDirectoryStructure(cwd) {
1329
1324
  others: []
1330
1325
  };
1331
1326
  try {
1332
- const entries = await fs5__namespace.readdir(cwd, { withFileTypes: true });
1327
+ const entries = await fs6__namespace.readdir(cwd, { withFileTypes: true });
1333
1328
  for (const entry of entries) {
1334
1329
  if (!entry.isDirectory()) continue;
1335
1330
  const name = entry.name;
@@ -1365,7 +1360,7 @@ async function findEntryPoints(cwd) {
1365
1360
  "index.js"
1366
1361
  ];
1367
1362
  for (const entry of possibleEntries) {
1368
- const fullPath = path5__namespace.join(cwd, entry);
1363
+ const fullPath = path6__namespace.join(cwd, entry);
1369
1364
  if (await fileExists(fullPath)) {
1370
1365
  entryPoints.push(entry);
1371
1366
  }
@@ -1373,15 +1368,15 @@ async function findEntryPoints(cwd) {
1373
1368
  return entryPoints;
1374
1369
  }
1375
1370
  async function saveProjectAnalysis(sfCliDir, analysis) {
1376
- const analysisPath = path5__namespace.join(sfCliDir, "cache", "analysis", "project-analysis.json");
1377
- await fs5__namespace.writeFile(
1371
+ const analysisPath = path6__namespace.join(sfCliDir, "cache", "analysis", "project-analysis.json");
1372
+ await fs6__namespace.writeFile(
1378
1373
  analysisPath,
1379
1374
  JSON.stringify(analysis, null, 2),
1380
1375
  "utf-8"
1381
1376
  );
1382
1377
  }
1383
1378
  async function generateOpenSpecConfig(openspecDir, analysis) {
1384
- const configPath = path5__namespace.join(openspecDir, "config.yaml");
1379
+ const configPath = path6__namespace.join(openspecDir, "config.yaml");
1385
1380
  const content = `# OpenSpec \u9879\u76EE\u914D\u7F6E
1386
1381
  # \u6B64\u6587\u4EF6\u5B9A\u4E49\u9879\u76EE\u7684\u57FA\u672C\u4FE1\u606F\uFF0C\u7528\u4E8E\u6307\u5BFC AI \u7406\u89E3\u9879\u76EE\u4E0A\u4E0B\u6587
1387
1382
 
@@ -1415,7 +1410,7 @@ architecture:
1415
1410
  # \u5F00\u53D1\u89C4\u8303 (\u4ECE\u4EE3\u7801\u4E2D\u5B66\u4E60)
1416
1411
  standards: []
1417
1412
  `;
1418
- await fs5__namespace.writeFile(configPath, content, "utf-8");
1413
+ await fs6__namespace.writeFile(configPath, content, "utf-8");
1419
1414
  }
1420
1415
  function generateAgentsMd(info, scanResult) {
1421
1416
  const techStackList = info.techStack.length > 0 ? info.techStack.map((t) => `| ${t} | \u2713 |`).join("\n") : "| \u5F85\u8BC6\u522B | - |";
@@ -1537,7 +1532,7 @@ function generateHealthTemplate() {
1537
1532
  }
1538
1533
  async function fileExists(filePath) {
1539
1534
  try {
1540
- await fs5__namespace.access(filePath);
1535
+ await fs6__namespace.access(filePath);
1541
1536
  return true;
1542
1537
  } catch {
1543
1538
  return false;
@@ -1708,7 +1703,7 @@ var IV_LENGTH = 16;
1708
1703
  var KEY_DIR = ".sf-cli";
1709
1704
  var KEY_FILE = ".key";
1710
1705
  function getOrCreateEncryptionKey() {
1711
- const keyPath = path5__namespace.join(os__namespace.homedir(), KEY_DIR, KEY_FILE);
1706
+ const keyPath = path6__namespace.join(os__namespace.homedir(), KEY_DIR, KEY_FILE);
1712
1707
  try {
1713
1708
  if (fsSync__namespace.existsSync(keyPath)) {
1714
1709
  const keyBase64 = fsSync__namespace.readFileSync(keyPath, "utf-8").trim();
@@ -1718,7 +1713,7 @@ function getOrCreateEncryptionKey() {
1718
1713
  }
1719
1714
  const key = crypto__namespace.randomBytes(32);
1720
1715
  try {
1721
- const keyDir = path5__namespace.dirname(keyPath);
1716
+ const keyDir = path6__namespace.dirname(keyPath);
1722
1717
  if (!fsSync__namespace.existsSync(keyDir)) {
1723
1718
  fsSync__namespace.mkdirSync(keyDir, { recursive: true, mode: 448 });
1724
1719
  }
@@ -1749,9 +1744,9 @@ var ConfigManager = class {
1749
1744
  }
1750
1745
  async load(projectPath) {
1751
1746
  this.projectPath = projectPath;
1752
- this.configPath = path5__namespace.join(projectPath, ".sf-cli", "config.json");
1747
+ this.configPath = path6__namespace.join(projectPath, ".sf-cli", "config.json");
1753
1748
  try {
1754
- const content = await fs5__namespace.readFile(this.configPath, "utf-8");
1749
+ const content = await fs6__namespace.readFile(this.configPath, "utf-8");
1755
1750
  const loaded = JSON.parse(content);
1756
1751
  if (loaded.apiKey && loaded.apiKeyEncrypted) {
1757
1752
  loaded.apiKey = this.decrypt(loaded.apiKey);
@@ -1770,8 +1765,8 @@ var ConfigManager = class {
1770
1765
  configToSave.apiKey = encrypted;
1771
1766
  configToSave.apiKeyEncrypted = true;
1772
1767
  }
1773
- await fs5__namespace.mkdir(path5__namespace.dirname(this.configPath), { recursive: true });
1774
- await fs5__namespace.writeFile(
1768
+ await fs6__namespace.mkdir(path6__namespace.dirname(this.configPath), { recursive: true });
1769
+ await fs6__namespace.writeFile(
1775
1770
  this.configPath,
1776
1771
  JSON.stringify(configToSave, null, 2),
1777
1772
  "utf-8"
@@ -2029,7 +2024,7 @@ var BaseAdapter = class {
2029
2024
  * 延迟工具函数
2030
2025
  */
2031
2026
  delay(ms) {
2032
- return new Promise((resolve2) => setTimeout(resolve2, ms));
2027
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
2033
2028
  }
2034
2029
  };
2035
2030
 
@@ -2650,7 +2645,7 @@ var ModelService = class {
2650
2645
  * 初始化服务
2651
2646
  */
2652
2647
  async initialize(statsDir) {
2653
- this.statsPath = path5__namespace.join(statsDir, "tokens");
2648
+ this.statsPath = path6__namespace.join(statsDir, "tokens");
2654
2649
  await this.loadStats();
2655
2650
  const model = this.configManager.get("model");
2656
2651
  const apiKey = this.configManager.get("apiKey");
@@ -2823,11 +2818,11 @@ var ModelService = class {
2823
2818
  async loadStats() {
2824
2819
  if (!this.statsPath) return;
2825
2820
  try {
2826
- const dailyPath = path5__namespace.join(this.statsPath, "daily.json");
2827
- const totalPath = path5__namespace.join(this.statsPath, "total.json");
2821
+ const dailyPath = path6__namespace.join(this.statsPath, "daily.json");
2822
+ const totalPath = path6__namespace.join(this.statsPath, "total.json");
2828
2823
  const [daily, total] = await Promise.all([
2829
- fs5__namespace.readFile(dailyPath, "utf-8").catch(() => "{}"),
2830
- fs5__namespace.readFile(totalPath, "utf-8").catch(() => '{"totalInput":0,"totalOutput":0}')
2824
+ fs6__namespace.readFile(dailyPath, "utf-8").catch(() => "{}"),
2825
+ fs6__namespace.readFile(totalPath, "utf-8").catch(() => '{"totalInput":0,"totalOutput":0}')
2831
2826
  ]);
2832
2827
  const dailyData = JSON.parse(daily);
2833
2828
  const totalData = JSON.parse(total);
@@ -2840,12 +2835,12 @@ var ModelService = class {
2840
2835
  async saveStats() {
2841
2836
  if (!this.statsPath) return;
2842
2837
  try {
2843
- await fs5__namespace.mkdir(this.statsPath, { recursive: true });
2844
- const dailyPath = path5__namespace.join(this.statsPath, "daily.json");
2845
- const totalPath = path5__namespace.join(this.statsPath, "total.json");
2838
+ await fs6__namespace.mkdir(this.statsPath, { recursive: true });
2839
+ const dailyPath = path6__namespace.join(this.statsPath, "daily.json");
2840
+ const totalPath = path6__namespace.join(this.statsPath, "total.json");
2846
2841
  await Promise.all([
2847
- fs5__namespace.writeFile(dailyPath, JSON.stringify(this.stats.byDate, null, 2)),
2848
- fs5__namespace.writeFile(totalPath, JSON.stringify({
2842
+ fs6__namespace.writeFile(dailyPath, JSON.stringify(this.stats.byDate, null, 2)),
2843
+ fs6__namespace.writeFile(totalPath, JSON.stringify({
2849
2844
  totalInput: this.stats.totalInput,
2850
2845
  totalOutput: this.stats.totalOutput
2851
2846
  }))
@@ -3086,8 +3081,10 @@ function createSpinner(message) {
3086
3081
  stop: () => process.stdout.write(" ".repeat(message.length + 10) + "\r")
3087
3082
  };
3088
3083
  }
3089
- var CURRENT_VERSION = "1.0.0";
3090
- var PACKAGE_NAME = "sf-cli";
3084
+ var packageJsonPath = path6__namespace.resolve(__dirname, "../../package.json");
3085
+ var packageJson = JSON.parse(fsSync__namespace.readFileSync(packageJsonPath, "utf-8"));
3086
+ var CURRENT_VERSION = packageJson.version;
3087
+ var PACKAGE_NAME = packageJson.name;
3091
3088
  async function handleUpdate(args, ctx) {
3092
3089
  const options = {
3093
3090
  check: args.includes("--check") || args.includes("-c"),
@@ -3114,6 +3111,9 @@ async function checkForUpdates() {
3114
3111
  const latestVersion = await getLatestVersion();
3115
3112
  if (!latestVersion) {
3116
3113
  lines.push(chalk9__default.default.yellow("\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\u4FE1\u606F"));
3114
+ lines.push(chalk9__default.default.gray("\u53EF\u80FD\u539F\u56E0:"));
3115
+ lines.push(chalk9__default.default.gray(" 1. \u5305\u5C1A\u672A\u53D1\u5E03\u5230 npm"));
3116
+ lines.push(chalk9__default.default.gray(" 2. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898"));
3117
3117
  return { output: lines.join("\n") };
3118
3118
  }
3119
3119
  lines.push(chalk9__default.default.gray(` \u5F53\u524D\u7248\u672C: v${CURRENT_VERSION}`));
@@ -3132,43 +3132,70 @@ async function checkForUpdates() {
3132
3132
  async function performUpdate(targetVersion) {
3133
3133
  const lines = [];
3134
3134
  lines.push(chalk9__default.default.cyan("\u6B63\u5728\u66F4\u65B0 sf-cli..."));
3135
+ lines.push(chalk9__default.default.gray(` \u5305\u540D: ${PACKAGE_NAME}`));
3136
+ lines.push(chalk9__default.default.gray(` \u5F53\u524D\u7248\u672C: v${CURRENT_VERSION}`));
3135
3137
  try {
3136
3138
  const latestVersion = await getLatestVersion();
3139
+ if (!latestVersion && !targetVersion) {
3140
+ lines.push(chalk9__default.default.yellow("\n\u26A0 \u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\u4FE1\u606F"));
3141
+ lines.push(chalk9__default.default.gray("\n\u53EF\u80FD\u539F\u56E0:"));
3142
+ lines.push(chalk9__default.default.gray(" 1. \u5305\u5C1A\u672A\u53D1\u5E03\u5230 npm"));
3143
+ lines.push(chalk9__default.default.gray(" 2. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898"));
3144
+ lines.push(chalk9__default.default.gray("\n\u60A8\u53EF\u4EE5\u5C1D\u8BD5\u624B\u52A8\u66F4\u65B0:"));
3145
+ lines.push(chalk9__default.default.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
3146
+ return { output: lines.join("\n") };
3147
+ }
3137
3148
  if (latestVersion === CURRENT_VERSION && !targetVersion) {
3138
- lines.push(chalk9__default.default.green("\u2713 \u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0"));
3149
+ lines.push(chalk9__default.default.green("\n\u2713 \u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0"));
3139
3150
  return { output: lines.join("\n") };
3140
3151
  }
3141
3152
  const packageSpec = targetVersion ? `${PACKAGE_NAME}@${targetVersion}` : `${PACKAGE_NAME}@latest`;
3142
3153
  lines.push(chalk9__default.default.gray(` \u5B89\u88C5: ${packageSpec}`));
3143
- await new Promise((resolve2, reject) => {
3154
+ const installResult = await new Promise((resolve5) => {
3144
3155
  const proc = child_process.spawn("npm", ["install", "-g", packageSpec], {
3145
3156
  stdio: "pipe",
3146
3157
  shell: true
3147
3158
  });
3159
+ let output = "";
3160
+ proc.stdout?.on("data", (data) => {
3161
+ output += data.toString();
3162
+ });
3163
+ proc.stderr?.on("data", (data) => {
3164
+ output += data.toString();
3165
+ });
3148
3166
  proc.on("close", (code) => {
3149
- if (code === 0) {
3150
- resolve2();
3151
- } else {
3152
- reject(new Error(`npm install exited with code ${code}`));
3153
- }
3167
+ resolve5({
3168
+ success: code === 0,
3169
+ output
3170
+ });
3154
3171
  });
3155
3172
  proc.on("error", (err) => {
3156
- reject(err);
3173
+ resolve5({
3174
+ success: false,
3175
+ output: err.message
3176
+ });
3157
3177
  });
3158
3178
  });
3159
- lines.push(chalk9__default.default.green("\u2713 \u66F4\u65B0\u5B8C\u6210!"));
3179
+ if (!installResult.success) {
3180
+ lines.push(chalk9__default.default.red("\n\u2717 \u66F4\u65B0\u5931\u8D25"));
3181
+ lines.push(chalk9__default.default.gray(installResult.output));
3182
+ lines.push(chalk9__default.default.gray("\n\u60A8\u53EF\u4EE5\u5C1D\u8BD5\u624B\u52A8\u66F4\u65B0:"));
3183
+ lines.push(chalk9__default.default.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
3184
+ return { output: lines.join("\n") };
3185
+ }
3186
+ lines.push(chalk9__default.default.green("\n\u2713 \u66F4\u65B0\u5B8C\u6210!"));
3160
3187
  lines.push(chalk9__default.default.gray(` \u65B0\u7248\u672C: v${targetVersion || latestVersion}`));
3161
3188
  lines.push(chalk9__default.default.gray("\n\u8BF7\u91CD\u542F CLI \u4EE5\u4F7F\u7528\u65B0\u7248\u672C"));
3162
3189
  } catch (error) {
3163
3190
  lines.push(chalk9__default.default.red("\u66F4\u65B0\u5931\u8D25: " + error.message));
3164
3191
  lines.push(chalk9__default.default.gray("\n\u60A8\u53EF\u4EE5\u5C1D\u8BD5\u624B\u52A8\u66F4\u65B0:"));
3165
- lines.push(chalk9__default.default.gray(" npm install -g sf-cli@latest"));
3192
+ lines.push(chalk9__default.default.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
3166
3193
  }
3167
3194
  return { output: lines.join("\n") };
3168
3195
  }
3169
3196
  async function getLatestVersion() {
3170
3197
  try {
3171
- const result = await new Promise((resolve2, reject) => {
3198
+ const result = await new Promise((resolve5, reject) => {
3172
3199
  const proc = child_process.spawn("npm", ["view", PACKAGE_NAME, "version"], {
3173
3200
  stdio: "pipe",
3174
3201
  shell: true
@@ -3178,13 +3205,17 @@ async function getLatestVersion() {
3178
3205
  output += data.toString();
3179
3206
  });
3180
3207
  proc.on("close", (code) => {
3181
- if (code === 0) {
3182
- resolve2(output.trim());
3208
+ if (code === 0 && output.trim()) {
3209
+ resolve5(output.trim());
3183
3210
  } else {
3184
3211
  reject(new Error("Failed to get version"));
3185
3212
  }
3186
3213
  });
3187
3214
  proc.on("error", reject);
3215
+ setTimeout(() => {
3216
+ proc.kill();
3217
+ reject(new Error("Timeout"));
3218
+ }, 1e4);
3188
3219
  });
3189
3220
  return result || null;
3190
3221
  } catch {
@@ -3468,7 +3499,7 @@ var WorkflowEngine = class {
3468
3499
  */
3469
3500
  async initialize(projectPath) {
3470
3501
  this.projectPath = projectPath;
3471
- this.openspecPath = path5__namespace.join(projectPath, "openspec");
3502
+ this.openspecPath = path6__namespace.join(projectPath, "openspec");
3472
3503
  await this.ensureDirectories();
3473
3504
  await this.loadProjectContext();
3474
3505
  await this.restoreState();
@@ -3478,21 +3509,21 @@ var WorkflowEngine = class {
3478
3509
  * 加载项目上下文(AGENTS.md 和 config.yaml)
3479
3510
  */
3480
3511
  async loadProjectContext() {
3481
- const agentsMdPath = path5__namespace.join(this.projectPath, "AGENTS.md");
3512
+ const agentsMdPath = path6__namespace.join(this.projectPath, "AGENTS.md");
3482
3513
  try {
3483
- this.projectContext = await fs5__namespace.readFile(agentsMdPath, "utf-8");
3514
+ this.projectContext = await fs6__namespace.readFile(agentsMdPath, "utf-8");
3484
3515
  } catch {
3485
3516
  this.projectContext = "";
3486
3517
  }
3487
- const configPath = path5__namespace.join(this.openspecPath, "config.yaml");
3518
+ const configPath = path6__namespace.join(this.openspecPath, "config.yaml");
3488
3519
  try {
3489
- this.projectConfig = await fs5__namespace.readFile(configPath, "utf-8");
3520
+ this.projectConfig = await fs6__namespace.readFile(configPath, "utf-8");
3490
3521
  } catch {
3491
3522
  this.projectConfig = "";
3492
3523
  }
3493
- const devstandedPath = path5__namespace.join(this.projectPath, ".sf-cli", "norms", "devstanded.md");
3524
+ const devstandedPath = path6__namespace.join(this.projectPath, ".sf-cli", "norms", "devstanded.md");
3494
3525
  try {
3495
- this.devStandards = await fs5__namespace.readFile(devstandedPath, "utf-8");
3526
+ this.devStandards = await fs6__namespace.readFile(devstandedPath, "utf-8");
3496
3527
  } catch {
3497
3528
  this.devStandards = "";
3498
3529
  }
@@ -3778,12 +3809,12 @@ var WorkflowEngine = class {
3778
3809
  await this.createSpecDocument(summary);
3779
3810
  await this.updateChangeRecord("archived");
3780
3811
  await this.saveState();
3781
- const changesDir = path5__namespace.join(this.openspecPath, "changes");
3782
- const archiveDir = path5__namespace.join(changesDir, "archive");
3783
- const changeFile = path5__namespace.join(changesDir, `${changeId}.md`);
3784
- const archiveFile = path5__namespace.join(archiveDir, `${changeId}.md`);
3785
- await fs5__namespace.mkdir(archiveDir, { recursive: true });
3786
- await fs5__namespace.rename(changeFile, archiveFile).catch(() => {
3812
+ const changesDir = path6__namespace.join(this.openspecPath, "changes");
3813
+ const archiveDir = path6__namespace.join(changesDir, "archive");
3814
+ const changeFile = path6__namespace.join(changesDir, `${changeId}.md`);
3815
+ const archiveFile = path6__namespace.join(archiveDir, `${changeId}.md`);
3816
+ await fs6__namespace.mkdir(archiveDir, { recursive: true });
3817
+ await fs6__namespace.rename(changeFile, archiveFile).catch(() => {
3787
3818
  });
3788
3819
  this.state = null;
3789
3820
  this.snapshots.clear();
@@ -3805,16 +3836,16 @@ var WorkflowEngine = class {
3805
3836
  }
3806
3837
  // ==================== 私有方法 ====================
3807
3838
  async ensureDirectories() {
3808
- const changesDir = path5__namespace.join(this.openspecPath, "changes");
3809
- const archiveDir = path5__namespace.join(changesDir, "archive");
3810
- const specDir = path5__namespace.join(this.openspecPath, "spec");
3811
- await fs5__namespace.mkdir(archiveDir, { recursive: true });
3812
- await fs5__namespace.mkdir(specDir, { recursive: true });
3839
+ const changesDir = path6__namespace.join(this.openspecPath, "changes");
3840
+ const archiveDir = path6__namespace.join(changesDir, "archive");
3841
+ const specDir = path6__namespace.join(this.openspecPath, "spec");
3842
+ await fs6__namespace.mkdir(archiveDir, { recursive: true });
3843
+ await fs6__namespace.mkdir(specDir, { recursive: true });
3813
3844
  }
3814
3845
  async restoreState() {
3815
- const statePath = path5__namespace.join(this.openspecPath, ".workflow-state.json");
3846
+ const statePath = path6__namespace.join(this.openspecPath, ".workflow-state.json");
3816
3847
  try {
3817
- const content = await fs5__namespace.readFile(statePath, "utf-8");
3848
+ const content = await fs6__namespace.readFile(statePath, "utf-8");
3818
3849
  this.state = JSON.parse(content, (key, value) => {
3819
3850
  if (key.endsWith("At") && typeof value === "string") {
3820
3851
  return new Date(value);
@@ -3825,20 +3856,20 @@ var WorkflowEngine = class {
3825
3856
  const err = e;
3826
3857
  if (err.code !== "ENOENT") {
3827
3858
  console.warn("\u8B66\u544A: \u5DE5\u4F5C\u6D41\u72B6\u6001\u6587\u4EF6\u5DF2\u635F\u574F\uFF0C\u5C06\u91CD\u65B0\u5F00\u59CB");
3828
- await fs5__namespace.unlink(statePath).catch(() => {
3859
+ await fs6__namespace.unlink(statePath).catch(() => {
3829
3860
  });
3830
3861
  }
3831
3862
  this.state = null;
3832
3863
  }
3833
3864
  }
3834
3865
  async saveState() {
3835
- const statePath = path5__namespace.join(this.openspecPath, ".workflow-state.json");
3836
- await fs5__namespace.writeFile(statePath, JSON.stringify(this.state, null, 2));
3866
+ const statePath = path6__namespace.join(this.openspecPath, ".workflow-state.json");
3867
+ await fs6__namespace.writeFile(statePath, JSON.stringify(this.state, null, 2));
3837
3868
  }
3838
3869
  async restoreSnapshots() {
3839
- const snapshotsPath = path5__namespace.join(this.openspecPath, ".workflow-snapshots.json");
3870
+ const snapshotsPath = path6__namespace.join(this.openspecPath, ".workflow-snapshots.json");
3840
3871
  try {
3841
- const content = await fs5__namespace.readFile(snapshotsPath, "utf-8");
3872
+ const content = await fs6__namespace.readFile(snapshotsPath, "utf-8");
3842
3873
  const data = JSON.parse(content, (key, value) => {
3843
3874
  if (key === "timestamp" && typeof value === "string") {
3844
3875
  return new Date(value);
@@ -3853,9 +3884,9 @@ var WorkflowEngine = class {
3853
3884
  }
3854
3885
  }
3855
3886
  async saveSnapshots() {
3856
- const snapshotsPath = path5__namespace.join(this.openspecPath, ".workflow-snapshots.json");
3887
+ const snapshotsPath = path6__namespace.join(this.openspecPath, ".workflow-snapshots.json");
3857
3888
  const data = Array.from(this.snapshots.values());
3858
- await fs5__namespace.writeFile(snapshotsPath, JSON.stringify(data, null, 2));
3889
+ await fs6__namespace.writeFile(snapshotsPath, JSON.stringify(data, null, 2));
3859
3890
  }
3860
3891
  async createSnapshot() {
3861
3892
  if (!this.state) return;
@@ -3875,16 +3906,16 @@ var WorkflowEngine = class {
3875
3906
  }
3876
3907
  async createChangeRecord() {
3877
3908
  if (!this.state) return;
3878
- const changePath = path5__namespace.join(this.openspecPath, "changes", `${this.state.id}.md`);
3879
- await fs5__namespace.writeFile(changePath, this.formatChangeRecord());
3909
+ const changePath = path6__namespace.join(this.openspecPath, "changes", `${this.state.id}.md`);
3910
+ await fs6__namespace.writeFile(changePath, this.formatChangeRecord());
3880
3911
  }
3881
3912
  async updateChangeRecord(status) {
3882
3913
  if (!this.state) return;
3883
3914
  if (status) {
3884
3915
  this.state.status = status;
3885
3916
  }
3886
- const changePath = path5__namespace.join(this.openspecPath, "changes", `${this.state.id}.md`);
3887
- await fs5__namespace.writeFile(changePath, this.formatChangeRecord());
3917
+ const changePath = path6__namespace.join(this.openspecPath, "changes", `${this.state.id}.md`);
3918
+ await fs6__namespace.writeFile(changePath, this.formatChangeRecord());
3888
3919
  }
3889
3920
  formatChangeRecord() {
3890
3921
  if (!this.state) return "";
@@ -3923,7 +3954,7 @@ ${this.state.artifacts.map((a) => `- ${a}`).join("\n") || "\u6682\u65E0"}
3923
3954
  }
3924
3955
  async createSpecDocument(summary) {
3925
3956
  if (!this.state) return;
3926
- const specPath = path5__namespace.join(this.openspecPath, "spec", `${this.state.id}.md`);
3957
+ const specPath = path6__namespace.join(this.openspecPath, "spec", `${this.state.id}.md`);
3927
3958
  const content = `# Spec: ${this.state.title}
3928
3959
 
3929
3960
  > \u53D8\u66F4ID: ${this.state.id}
@@ -3948,7 +3979,7 @@ ${this.state.steps.map((s) => `- [${s.status === "completed" ? "x" : " "}] ${s.s
3948
3979
 
3949
3980
  ${this.state.artifacts.map((a) => `- ${a}`).join("\n") || "\u6682\u65E0"}
3950
3981
  `;
3951
- await fs5__namespace.writeFile(specPath, content);
3982
+ await fs6__namespace.writeFile(specPath, content);
3952
3983
  }
3953
3984
  };
3954
3985
  var ConfirmationRequiredError = class extends Error {
@@ -3993,7 +4024,7 @@ async function newFeature(options, workingDir, workflowEngine) {
3993
4024
  const cwd = workingDir || process.cwd();
3994
4025
  const { requirement, forceComplexity } = options;
3995
4026
  try {
3996
- const stats = await fs5__namespace.stat(cwd);
4027
+ const stats = await fs6__namespace.stat(cwd);
3997
4028
  if (!stats.isDirectory()) {
3998
4029
  return {
3999
4030
  output: chalk9__default.default.red(`\u9519\u8BEF: ${cwd} \u4E0D\u662F\u6709\u6548\u76EE\u5F55`)
@@ -4064,20 +4095,20 @@ function parseArgs(args) {
4064
4095
  }
4065
4096
  async function readProjectContext(cwd) {
4066
4097
  const defaultContext = {
4067
- name: path5__namespace.basename(cwd),
4098
+ name: path6__namespace.basename(cwd),
4068
4099
  type: "unknown",
4069
4100
  framework: null,
4070
4101
  techStack: [],
4071
4102
  description: ""
4072
4103
  };
4073
- const agentsPath = path5__namespace.join(cwd, "AGENTS.md");
4104
+ const agentsPath = path6__namespace.join(cwd, "AGENTS.md");
4074
4105
  try {
4075
- const stats = await fs5__namespace.stat(agentsPath);
4106
+ const stats = await fs6__namespace.stat(agentsPath);
4076
4107
  if (stats.size > MAX_FILE_SIZE2) {
4077
4108
  console.warn(`\u8B66\u544A: AGENTS.md \u6587\u4EF6\u8FC7\u5927 (${stats.size} bytes)\uFF0C\u8DF3\u8FC7\u8BFB\u53D6`);
4078
4109
  return defaultContext;
4079
4110
  }
4080
- const content = await fs5__namespace.readFile(agentsPath, "utf-8");
4111
+ const content = await fs6__namespace.readFile(agentsPath, "utf-8");
4081
4112
  return parseAgentsMd(content, defaultContext);
4082
4113
  } catch (e) {
4083
4114
  const err = e;
@@ -4085,14 +4116,14 @@ async function readProjectContext(cwd) {
4085
4116
  console.warn(`\u8B66\u544A: \u65E0\u6CD5\u8BFB\u53D6 AGENTS.md - ${err.message}`);
4086
4117
  }
4087
4118
  }
4088
- const configPath = path5__namespace.join(cwd, "openspec", "config.yaml");
4119
+ const configPath = path6__namespace.join(cwd, "openspec", "config.yaml");
4089
4120
  try {
4090
- const stats = await fs5__namespace.stat(configPath);
4121
+ const stats = await fs6__namespace.stat(configPath);
4091
4122
  if (stats.size > MAX_FILE_SIZE2) {
4092
4123
  console.warn(`\u8B66\u544A: config.yaml \u6587\u4EF6\u8FC7\u5927\uFF0C\u8DF3\u8FC7\u8BFB\u53D6`);
4093
4124
  return defaultContext;
4094
4125
  }
4095
- const content = await fs5__namespace.readFile(configPath, "utf-8");
4126
+ const content = await fs6__namespace.readFile(configPath, "utf-8");
4096
4127
  return parseConfigYaml(content, defaultContext);
4097
4128
  } catch (e) {
4098
4129
  const err = e;
@@ -4652,15 +4683,15 @@ async function loadProjectContext(workingDirectory) {
4652
4683
  devStandards: ""
4653
4684
  };
4654
4685
  try {
4655
- context.agentsMd = await fs5__namespace.readFile(path5__namespace.join(workingDirectory, "AGENTS.md"), "utf-8");
4686
+ context.agentsMd = await fs6__namespace.readFile(path6__namespace.join(workingDirectory, "AGENTS.md"), "utf-8");
4656
4687
  } catch {
4657
4688
  }
4658
4689
  try {
4659
- context.configYaml = await fs5__namespace.readFile(path5__namespace.join(workingDirectory, "openspec", "config.yaml"), "utf-8");
4690
+ context.configYaml = await fs6__namespace.readFile(path6__namespace.join(workingDirectory, "openspec", "config.yaml"), "utf-8");
4660
4691
  } catch {
4661
4692
  }
4662
4693
  try {
4663
- context.devStandards = await fs5__namespace.readFile(path5__namespace.join(workingDirectory, ".sf-cli", "norms", "devstanded.md"), "utf-8");
4694
+ context.devStandards = await fs6__namespace.readFile(path6__namespace.join(workingDirectory, ".sf-cli", "norms", "devstanded.md"), "utf-8");
4664
4695
  } catch {
4665
4696
  }
4666
4697
  return context;
@@ -5181,9 +5212,11 @@ ${generateConfirmationPrompt(e.point)}`) + chalk9__default.default.cyan(`
5181
5212
  throw e;
5182
5213
  }
5183
5214
  }
5184
- var require2 = module$1.createRequire(importMetaUrl);
5185
- var packageJson = require2("../../package.json");
5186
- var VERSION2 = packageJson.version;
5215
+
5216
+ // src/commands/runner.ts
5217
+ var packageJsonPath2 = path6__namespace.resolve(__dirname, "../../package.json");
5218
+ var packageJson2 = JSON.parse(fsSync__namespace.readFileSync(packageJsonPath2, "utf-8"));
5219
+ var VERSION2 = packageJson2.version;
5187
5220
  async function runSlashCommand(command, args, ctx) {
5188
5221
  const normalizedCommand = normalizeCommand(command);
5189
5222
  switch (normalizedCommand) {
@@ -5230,11 +5263,11 @@ function normalizeCommand(command) {
5230
5263
  }
5231
5264
  async function handleFileReference(filePath, ctx) {
5232
5265
  const cwd = ctx.options.workingDirectory;
5233
- const absolutePath = path5__namespace.isAbsolute(filePath) ? filePath : path5__namespace.join(cwd, filePath);
5266
+ const absolutePath = path6__namespace.isAbsolute(filePath) ? filePath : path6__namespace.join(cwd, filePath);
5234
5267
  try {
5235
- const stats = await fs5__namespace.stat(absolutePath);
5268
+ const stats = await fs6__namespace.stat(absolutePath);
5236
5269
  if (stats.isDirectory()) {
5237
- const files = await fs5__namespace.readdir(absolutePath);
5270
+ const files = await fs6__namespace.readdir(absolutePath);
5238
5271
  return {
5239
5272
  output: chalk9__default.default.cyan(`\u{1F4C1} ${filePath}/`) + chalk9__default.default.gray(`
5240
5273
  ${files.slice(0, 20).join("\n")}`) + (files.length > 20 ? chalk9__default.default.gray(`
@@ -5242,7 +5275,7 @@ ${files.slice(0, 20).join("\n")}`) + (files.length > 20 ? chalk9__default.defaul
5242
5275
  contextUsed: 0
5243
5276
  };
5244
5277
  }
5245
- const content = await fs5__namespace.readFile(absolutePath, "utf-8");
5278
+ const content = await fs6__namespace.readFile(absolutePath, "utf-8");
5246
5279
  const lines = content.split("\n");
5247
5280
  ctx.contextManager.addMessage({
5248
5281
  role: "user",
@@ -5278,7 +5311,7 @@ async function executeShell(command, ctx) {
5278
5311
  \u547D\u4EE4 "${command}" \u53EF\u80FD\u4F1A\u5220\u9664\u91CD\u8981\u6587\u4EF6`) + chalk9__default.default.gray("\n\u4F7F\u7528 yolo \u6A21\u5F0F\u5F3A\u5236\u6267\u884C")
5279
5312
  };
5280
5313
  }
5281
- return new Promise((resolve2) => {
5314
+ return new Promise((resolve5) => {
5282
5315
  const shell = child_process.spawn(command, [], {
5283
5316
  shell: true,
5284
5317
  cwd: ctx.options.workingDirectory
@@ -5303,11 +5336,11 @@ async function executeShell(command, ctx) {
5303
5336
  output += chalk9__default.default.red(`
5304
5337
  \u9000\u51FA\u7801: ${code}`);
5305
5338
  }
5306
- resolve2({ output: output || chalk9__default.default.gray("(\u65E0\u8F93\u51FA)") });
5339
+ resolve5({ output: output || chalk9__default.default.gray("(\u65E0\u8F93\u51FA)") });
5307
5340
  });
5308
5341
  setTimeout(() => {
5309
5342
  shell.kill();
5310
- resolve2({
5343
+ resolve5({
5311
5344
  output: chalk9__default.default.yellow("\u547D\u4EE4\u6267\u884C\u8D85\u65F6\uFF0C\u5DF2\u7EC8\u6B62")
5312
5345
  });
5313
5346
  }, 6e4);
@@ -5533,7 +5566,7 @@ var ContextManager = class {
5533
5566
  }
5534
5567
  async initialize(projectPath) {
5535
5568
  this.projectPath = projectPath;
5536
- this.persistPath = path5__namespace.join(projectPath, ".sf-cli", "cache", "context", "context.json");
5569
+ this.persistPath = path6__namespace.join(projectPath, ".sf-cli", "cache", "context", "context.json");
5537
5570
  await this.loadPersistedContext();
5538
5571
  }
5539
5572
  /**
@@ -5774,15 +5807,15 @@ ${summary}`,
5774
5807
  */
5775
5808
  async persist() {
5776
5809
  if (!this.persistPath) return;
5777
- const dir = path5__namespace.dirname(this.persistPath);
5778
- await fs5__namespace.mkdir(dir, { recursive: true });
5810
+ const dir = path6__namespace.dirname(this.persistPath);
5811
+ await fs6__namespace.mkdir(dir, { recursive: true });
5779
5812
  const data = {
5780
5813
  messages: this.state.messages,
5781
5814
  totalTokens: this.state.totalTokens,
5782
5815
  limit: this.state.limit,
5783
5816
  savedAt: (/* @__PURE__ */ new Date()).toISOString()
5784
5817
  };
5785
- await fs5__namespace.writeFile(this.persistPath, JSON.stringify(data, null, 2), "utf-8");
5818
+ await fs6__namespace.writeFile(this.persistPath, JSON.stringify(data, null, 2), "utf-8");
5786
5819
  }
5787
5820
  /**
5788
5821
  * 加载持久化的上下文
@@ -5790,7 +5823,7 @@ ${summary}`,
5790
5823
  async loadPersistedContext() {
5791
5824
  if (!this.persistPath) return;
5792
5825
  try {
5793
- const content = await fs5__namespace.readFile(this.persistPath, "utf-8");
5826
+ const content = await fs6__namespace.readFile(this.persistPath, "utf-8");
5794
5827
  const data = JSON.parse(content);
5795
5828
  this.state.messages = data.messages || [];
5796
5829
  this.state.totalTokens = data.totalTokens || 0;
@@ -5960,17 +5993,17 @@ var Completer = class {
5960
5993
  prefix = filePath;
5961
5994
  } else {
5962
5995
  const dir = filePath.slice(0, lastSlash);
5963
- dirPath = path5__namespace.resolve(this.workingDirectory, dir);
5996
+ dirPath = path6__namespace.resolve(this.workingDirectory, dir);
5964
5997
  prefix = filePath.slice(lastSlash + 1);
5965
5998
  }
5966
5999
  try {
5967
- const entries = await fs5__namespace.readdir(dirPath, { withFileTypes: true });
6000
+ const entries = await fs6__namespace.readdir(dirPath, { withFileTypes: true });
5968
6001
  const matches = [];
5969
6002
  for (const entry of entries) {
5970
6003
  if (entry.name.startsWith(prefix)) {
5971
6004
  const isDir = entry.isDirectory();
5972
6005
  matches.push({
5973
- text: "@" + path5__namespace.relative(this.workingDirectory, path5__namespace.join(dirPath, entry.name)).replace(/\\/g, "/") + (isDir ? "/" : ""),
6006
+ text: "@" + path6__namespace.relative(this.workingDirectory, path6__namespace.join(dirPath, entry.name)).replace(/\\/g, "/") + (isDir ? "/" : ""),
5974
6007
  displayText: entry.name + (isDir ? "/" : ""),
5975
6008
  description: isDir ? "\u76EE\u5F55" : "\u6587\u4EF6",
5976
6009
  type: isDir ? "directory" : "file"
@@ -6042,10 +6075,10 @@ var Completer = class {
6042
6075
 
6043
6076
  // src/cli/repl.ts
6044
6077
  async function startInteractiveMode(options) {
6045
- const historyFile = path5__namespace.join(options.workingDirectory, ".sf-cli", "history.json");
6078
+ const historyFile = path6__namespace.join(options.workingDirectory, ".sf-cli", "history.json");
6046
6079
  let history = [];
6047
6080
  try {
6048
- const historyData = await fs5__namespace.readFile(historyFile, "utf-8");
6081
+ const historyData = await fs6__namespace.readFile(historyFile, "utf-8");
6049
6082
  history = JSON.parse(historyData);
6050
6083
  } catch {
6051
6084
  }
@@ -6079,11 +6112,11 @@ async function startInteractiveMode(options) {
6079
6112
  const workflowEngine = new WorkflowEngine();
6080
6113
  const normsManager = new NormsManager({
6081
6114
  projectPath: options.workingDirectory,
6082
- normsDir: path5__namespace.join(options.workingDirectory, ".sf-cli", "norms")
6115
+ normsDir: path6__namespace.join(options.workingDirectory, ".sf-cli", "norms")
6083
6116
  });
6084
6117
  await configManager.load(options.workingDirectory);
6085
6118
  await contextManager.initialize(options.workingDirectory);
6086
- const statsDir = path5__namespace.join(options.workingDirectory, ".sf-cli");
6119
+ const statsDir = path6__namespace.join(options.workingDirectory, ".sf-cli");
6087
6120
  await modelService.initialize(statsDir);
6088
6121
  await workflowEngine.initialize(options.workingDirectory);
6089
6122
  await normsManager.initialize();
@@ -6114,8 +6147,8 @@ async function startInteractiveMode(options) {
6114
6147
  }
6115
6148
  const saveHistory = async () => {
6116
6149
  try {
6117
- await fs5__namespace.mkdir(path5__namespace.dirname(historyFile), { recursive: true });
6118
- await fs5__namespace.writeFile(historyFile, JSON.stringify(history.slice(-500)));
6150
+ await fs6__namespace.mkdir(path6__namespace.dirname(historyFile), { recursive: true });
6151
+ await fs6__namespace.writeFile(historyFile, JSON.stringify(history.slice(-500)));
6119
6152
  } catch {
6120
6153
  }
6121
6154
  };
@@ -6187,9 +6220,11 @@ async function startInteractiveMode(options) {
6187
6220
  rl.prompt();
6188
6221
  }
6189
6222
  }
6190
- var require3 = module$1.createRequire(importMetaUrl);
6191
- var packageJson2 = require3("../../package.json");
6192
- var VERSION3 = packageJson2.version;
6223
+
6224
+ // src/cli/index.ts
6225
+ var packageJsonPath3 = path6__namespace.resolve(__dirname, "../package.json");
6226
+ var packageJson3 = JSON.parse(fsSync__namespace.readFileSync(packageJsonPath3, "utf-8"));
6227
+ var VERSION3 = packageJson3.version;
6193
6228
  var NAME = "sf-cli";
6194
6229
  commander.program.name(NAME).description("\u4E13\u4E3A\u524D\u7AEF\u5F00\u53D1\u8BBE\u8BA1\u7684AI\u9A71\u52A8CLI\u5DE5\u5177").version(VERSION3, "-v, --version", "\u663E\u793A\u7248\u672C\u53F7");
6195
6230
  commander.program.argument("[directory]", "\u5DE5\u4F5C\u76EE\u5F55", process.cwd()).option("-m, --model <model>", "\u6307\u5B9AAI\u6A21\u578B").option("-y, --yolo", "\u81EA\u52A8\u786E\u8BA4\u6240\u6709\u64CD\u4F5C").action(async (directory, options) => {