@nick848/sf-cli 1.0.15 → 1.0.17

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
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- var fs7 = require('fs/promises');
5
- var fs9 = require('fs');
6
- var path7 = require('path');
7
- var crypto = require('crypto');
8
- var os = require('os');
9
4
  var tiktoken = require('tiktoken');
10
- require('@modelcontextprotocol/sdk/client/index.js');
11
- require('@modelcontextprotocol/sdk/client/stdio.js');
12
5
  var chalk9 = require('chalk');
13
6
  var enquirer = require('enquirer');
14
7
  var child_process = require('child_process');
8
+ var fs7 = require('fs');
9
+ var path5 = require('path');
10
+ var fs5 = require('fs/promises');
15
11
  var commander = require('commander');
16
12
  var readline = require('readline');
17
13
  require('uuid');
14
+ var crypto = require('crypto');
15
+ var os = require('os');
16
+ require('@modelcontextprotocol/sdk/client/index.js');
17
+ require('@modelcontextprotocol/sdk/client/stdio.js');
18
18
 
19
19
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
20
20
 
@@ -36,13 +36,13 @@ function _interopNamespace(e) {
36
36
  return Object.freeze(n);
37
37
  }
38
38
 
39
+ var chalk9__default = /*#__PURE__*/_interopDefault(chalk9);
39
40
  var fs7__namespace = /*#__PURE__*/_interopNamespace(fs7);
40
- var fs9__namespace = /*#__PURE__*/_interopNamespace(fs9);
41
- var path7__namespace = /*#__PURE__*/_interopNamespace(path7);
41
+ var path5__namespace = /*#__PURE__*/_interopNamespace(path5);
42
+ var fs5__namespace = /*#__PURE__*/_interopNamespace(fs5);
43
+ var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
42
44
  var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
43
45
  var os__namespace = /*#__PURE__*/_interopNamespace(os);
44
- var chalk9__default = /*#__PURE__*/_interopDefault(chalk9);
45
- var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
46
46
 
47
47
  var __defProp = Object.defineProperty;
48
48
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -59,138 +59,6 @@ var init_cjs_shims = __esm({
59
59
  "node_modules/tsup/assets/cjs_shims.js"() {
60
60
  }
61
61
  });
62
- function getOrCreateEncryptionKey() {
63
- const keyPath = path7__namespace.join(os__namespace.homedir(), KEY_DIR, KEY_FILE);
64
- try {
65
- if (fs9__namespace.existsSync(keyPath)) {
66
- const keyBase64 = fs9__namespace.readFileSync(keyPath, "utf-8").trim();
67
- return Buffer.from(keyBase64, "base64");
68
- }
69
- } catch {
70
- }
71
- const key = crypto__namespace.randomBytes(32);
72
- try {
73
- const keyDir = path7__namespace.dirname(keyPath);
74
- if (!fs9__namespace.existsSync(keyDir)) {
75
- fs9__namespace.mkdirSync(keyDir, { recursive: true, mode: 448 });
76
- }
77
- fs9__namespace.writeFileSync(keyPath, key.toString("base64"), {
78
- mode: 384,
79
- // 仅所有者可读写
80
- encoding: "utf-8"
81
- });
82
- return key;
83
- } catch {
84
- const machineId = [
85
- os__namespace.hostname(),
86
- os__namespace.platform(),
87
- os__namespace.arch(),
88
- process.env.USERNAME || process.env.USER || "default"
89
- ].join("-");
90
- return crypto__namespace.createHash("sha256").update(machineId).digest();
91
- }
92
- }
93
- var DEFAULT_CONFIG, ALGORITHM, IV_LENGTH, KEY_DIR, KEY_FILE, ConfigManager;
94
- var init_config = __esm({
95
- "src/services/config.ts"() {
96
- init_cjs_shims();
97
- DEFAULT_CONFIG = {
98
- model: "GLM-5",
99
- apiKey: "",
100
- yolo: false,
101
- locale: "zh-CN",
102
- theme: "auto"
103
- };
104
- ALGORITHM = "aes-256-gcm";
105
- IV_LENGTH = 16;
106
- KEY_DIR = ".sf-cli";
107
- KEY_FILE = ".key";
108
- ConfigManager = class {
109
- config;
110
- configPath = "";
111
- projectPath = "";
112
- encryptionKey;
113
- constructor() {
114
- this.config = { ...DEFAULT_CONFIG };
115
- this.encryptionKey = getOrCreateEncryptionKey();
116
- }
117
- async load(projectPath) {
118
- this.projectPath = projectPath;
119
- this.configPath = path7__namespace.join(projectPath, ".sf-cli", "config.json");
120
- try {
121
- const content = await fs7__namespace.readFile(this.configPath, "utf-8");
122
- const loaded = JSON.parse(content);
123
- if (loaded.apiKey && loaded.apiKeyEncrypted) {
124
- loaded.apiKey = this.decrypt(loaded.apiKey);
125
- delete loaded.apiKeyEncrypted;
126
- }
127
- this.config = { ...DEFAULT_CONFIG, ...loaded };
128
- } catch {
129
- this.config = { ...DEFAULT_CONFIG };
130
- }
131
- }
132
- async save() {
133
- if (!this.configPath) return;
134
- const configToSave = { ...this.config };
135
- if (configToSave.apiKey) {
136
- const encrypted = this.encrypt(configToSave.apiKey);
137
- configToSave.apiKey = encrypted;
138
- configToSave.apiKeyEncrypted = true;
139
- }
140
- await fs7__namespace.mkdir(path7__namespace.dirname(this.configPath), { recursive: true });
141
- await fs7__namespace.writeFile(
142
- this.configPath,
143
- JSON.stringify(configToSave, null, 2),
144
- "utf-8"
145
- );
146
- }
147
- get(key) {
148
- return this.config[key];
149
- }
150
- set(key, value) {
151
- this.config[key] = value;
152
- }
153
- getAll() {
154
- return { ...this.config };
155
- }
156
- update(updates) {
157
- this.config = { ...this.config, ...updates };
158
- }
159
- /**
160
- * 加密敏感数据
161
- */
162
- encrypt(text) {
163
- const iv = crypto__namespace.randomBytes(IV_LENGTH);
164
- const cipher = crypto__namespace.createCipheriv(ALGORITHM, this.encryptionKey, iv);
165
- let encrypted = cipher.update(text, "utf8", "base64");
166
- encrypted += cipher.final("base64");
167
- const authTag = cipher.getAuthTag();
168
- return `${iv.toString("base64")}:${authTag.toString("base64")}:${encrypted}`;
169
- }
170
- /**
171
- * 解密敏感数据
172
- */
173
- decrypt(encryptedData) {
174
- try {
175
- const parts = encryptedData.split(":");
176
- if (parts.length !== 3) {
177
- return encryptedData;
178
- }
179
- const [ivBase64, authTagBase64, encrypted] = parts;
180
- const iv = Buffer.from(ivBase64, "base64");
181
- const authTag = Buffer.from(authTagBase64, "base64");
182
- const decipher = crypto__namespace.createDecipheriv(ALGORITHM, this.encryptionKey, iv);
183
- decipher.setAuthTag(authTag);
184
- let decrypted = decipher.update(encrypted, "base64", "utf8");
185
- decrypted += decipher.final("utf8");
186
- return decrypted;
187
- } catch {
188
- return "";
189
- }
190
- }
191
- };
192
- }
193
- });
194
62
 
195
63
  // src/types/model.ts
196
64
  function getModelInfo(modelId) {
@@ -1078,312 +946,6 @@ var init_adapters = __esm({
1078
946
  DEEPSEEK_API_ENDPOINT = "https://api.deepseek.com/v1";
1079
947
  }
1080
948
  });
1081
- var ModelService;
1082
- var init_model2 = __esm({
1083
- "src/services/model.ts"() {
1084
- init_cjs_shims();
1085
- init_model();
1086
- init_adapters();
1087
- ModelService = class {
1088
- adapters = /* @__PURE__ */ new Map();
1089
- currentConfig = null;
1090
- stats;
1091
- configManager;
1092
- statsPath = "";
1093
- constructor(configManager) {
1094
- this.configManager = configManager;
1095
- this.stats = {
1096
- totalInput: 0,
1097
- totalOutput: 0,
1098
- byModel: {},
1099
- byAgent: {},
1100
- byDate: {}
1101
- };
1102
- }
1103
- /**
1104
- * 初始化服务
1105
- */
1106
- async initialize(statsDir) {
1107
- this.statsPath = path7__namespace.join(statsDir, "tokens");
1108
- await this.loadStats();
1109
- const model = this.configManager.get("model");
1110
- const apiKey = this.configManager.get("apiKey");
1111
- if (model && apiKey) {
1112
- await this.configureModel({
1113
- provider: this.getProviderFromModel(model),
1114
- model,
1115
- apiKey
1116
- });
1117
- }
1118
- }
1119
- /**
1120
- * 配置模型
1121
- */
1122
- async configureModel(config) {
1123
- let adapter = this.adapters.get(config.provider);
1124
- if (!adapter) {
1125
- adapter = createAdapter(config.provider);
1126
- this.adapters.set(config.provider, adapter);
1127
- }
1128
- await adapter.initialize(config);
1129
- this.currentConfig = config;
1130
- this.configManager.set("model", config.model);
1131
- this.configManager.set("apiKey", config.apiKey);
1132
- await this.configManager.save();
1133
- }
1134
- /**
1135
- * 发送消息
1136
- */
1137
- async sendMessage(messages, options) {
1138
- if (!this.currentConfig) {
1139
- throw new Error("\u6A21\u578B\u672A\u914D\u7F6E\uFF0C\u8BF7\u5148\u6267\u884C /model \u547D\u4EE4");
1140
- }
1141
- const adapter = this.adapters.get(this.currentConfig.provider);
1142
- if (!adapter || !adapter.isInitialized()) {
1143
- throw new Error("\u6A21\u578B\u9002\u914D\u5668\u672A\u521D\u59CB\u5316");
1144
- }
1145
- try {
1146
- const response = await adapter.sendMessage(messages, options);
1147
- this.updateStats(response.usage, {
1148
- model: this.currentConfig.model,
1149
- agent: options?.agent
1150
- });
1151
- this.saveStats().catch(() => {
1152
- });
1153
- return response;
1154
- } catch (error) {
1155
- throw this.wrapError(error);
1156
- }
1157
- }
1158
- /**
1159
- * 流式发送消息
1160
- */
1161
- async *streamMessage(messages, options) {
1162
- if (!this.currentConfig) {
1163
- throw new Error("\u6A21\u578B\u672A\u914D\u7F6E\uFF0C\u8BF7\u5148\u6267\u884C /model \u547D\u4EE4");
1164
- }
1165
- const adapter = this.adapters.get(this.currentConfig.provider);
1166
- if (!adapter || !adapter.isInitialized()) {
1167
- throw new Error("\u6A21\u578B\u9002\u914D\u5668\u672A\u521D\u59CB\u5316");
1168
- }
1169
- let totalTokens = 0;
1170
- try {
1171
- for await (const chunk of adapter.streamMessage(messages, options)) {
1172
- totalTokens += chunk.delta.length;
1173
- yield chunk;
1174
- }
1175
- const inputTokens = adapter.countTokens(
1176
- messages.map((m) => m.content).join("\n")
1177
- );
1178
- this.updateStats(
1179
- { inputTokens, outputTokens: Math.ceil(totalTokens / 4), totalTokens: 0 },
1180
- { model: this.currentConfig.model, agent: options?.agent }
1181
- );
1182
- this.saveStats().catch(() => {
1183
- });
1184
- } catch (error) {
1185
- throw this.wrapError(error);
1186
- }
1187
- }
1188
- /**
1189
- * 计算Token数量
1190
- */
1191
- countTokens(text) {
1192
- if (!this.currentConfig) {
1193
- return Math.ceil(text.length / 4);
1194
- }
1195
- const adapter = this.adapters.get(this.currentConfig.provider);
1196
- return adapter?.countTokens(text) || Math.ceil(text.length / 4);
1197
- }
1198
- /**
1199
- * 获取当前模型
1200
- */
1201
- getCurrentModel() {
1202
- return this.currentConfig?.model || null;
1203
- }
1204
- /**
1205
- * 获取当前提供商
1206
- */
1207
- getCurrentProvider() {
1208
- return this.currentConfig?.provider || null;
1209
- }
1210
- /**
1211
- * 获取Token统计
1212
- */
1213
- getStats() {
1214
- return { ...this.stats };
1215
- }
1216
- /**
1217
- * 获取今日统计
1218
- */
1219
- getTodayStats() {
1220
- const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1221
- return this.stats.byDate[today] || { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1222
- }
1223
- /**
1224
- * 重置统计
1225
- */
1226
- resetStats() {
1227
- this.stats = {
1228
- totalInput: 0,
1229
- totalOutput: 0,
1230
- byModel: {},
1231
- byAgent: {},
1232
- byDate: {}
1233
- };
1234
- this.saveStats().catch(() => {
1235
- });
1236
- }
1237
- /**
1238
- * 验证API Key
1239
- */
1240
- async validateApiKey(provider, apiKey) {
1241
- let adapter = this.adapters.get(provider);
1242
- if (!adapter) {
1243
- adapter = createAdapter(provider);
1244
- }
1245
- return adapter.validateApiKey(apiKey);
1246
- }
1247
- // ==================== 私有方法 ====================
1248
- getProviderFromModel(modelId) {
1249
- const info = getModelInfo(modelId);
1250
- return info?.provider || "openai";
1251
- }
1252
- updateStats(usage, context) {
1253
- this.stats.totalInput += usage.inputTokens;
1254
- this.stats.totalOutput += usage.outputTokens;
1255
- if (!this.stats.byModel[context.model]) {
1256
- this.stats.byModel[context.model] = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1257
- }
1258
- this.stats.byModel[context.model].inputTokens += usage.inputTokens;
1259
- this.stats.byModel[context.model].outputTokens += usage.outputTokens;
1260
- this.stats.byModel[context.model].totalTokens += usage.totalTokens;
1261
- if (context.agent) {
1262
- if (!this.stats.byAgent[context.agent]) {
1263
- this.stats.byAgent[context.agent] = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1264
- }
1265
- this.stats.byAgent[context.agent].inputTokens += usage.inputTokens;
1266
- this.stats.byAgent[context.agent].outputTokens += usage.outputTokens;
1267
- this.stats.byAgent[context.agent].totalTokens += usage.totalTokens;
1268
- }
1269
- const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1270
- if (!this.stats.byDate[today]) {
1271
- this.stats.byDate[today] = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1272
- }
1273
- this.stats.byDate[today].inputTokens += usage.inputTokens;
1274
- this.stats.byDate[today].outputTokens += usage.outputTokens;
1275
- this.stats.byDate[today].totalTokens += usage.totalTokens;
1276
- }
1277
- async loadStats() {
1278
- if (!this.statsPath) return;
1279
- try {
1280
- const dailyPath = path7__namespace.join(this.statsPath, "daily.json");
1281
- const totalPath = path7__namespace.join(this.statsPath, "total.json");
1282
- const [daily, total] = await Promise.all([
1283
- fs7__namespace.readFile(dailyPath, "utf-8").catch(() => "{}"),
1284
- fs7__namespace.readFile(totalPath, "utf-8").catch(() => '{"totalInput":0,"totalOutput":0}')
1285
- ]);
1286
- const dailyData = JSON.parse(daily);
1287
- const totalData = JSON.parse(total);
1288
- this.stats.byDate = dailyData;
1289
- this.stats.totalInput = totalData.totalInput || 0;
1290
- this.stats.totalOutput = totalData.totalOutput || 0;
1291
- } catch {
1292
- }
1293
- }
1294
- async saveStats() {
1295
- if (!this.statsPath) return;
1296
- try {
1297
- await fs7__namespace.mkdir(this.statsPath, { recursive: true });
1298
- const dailyPath = path7__namespace.join(this.statsPath, "daily.json");
1299
- const totalPath = path7__namespace.join(this.statsPath, "total.json");
1300
- await Promise.all([
1301
- fs7__namespace.writeFile(dailyPath, JSON.stringify(this.stats.byDate, null, 2)),
1302
- fs7__namespace.writeFile(totalPath, JSON.stringify({
1303
- totalInput: this.stats.totalInput,
1304
- totalOutput: this.stats.totalOutput
1305
- }))
1306
- ]);
1307
- } catch {
1308
- }
1309
- }
1310
- wrapError(error) {
1311
- if (error instanceof ModelError) {
1312
- return error;
1313
- }
1314
- const err = error;
1315
- if (err.message.includes("timeout")) {
1316
- return new ModelError("TIMEOUT", err.message, { retryable: true });
1317
- }
1318
- if (err.message.includes("network") || err.message.includes("ECONNREFUSED")) {
1319
- return new ModelError("NETWORK_ERROR", err.message, { retryable: true });
1320
- }
1321
- return new ModelError("UNKNOWN_ERROR", err.message, { retryable: false });
1322
- }
1323
- };
1324
- }
1325
- });
1326
-
1327
- // src/types/mcp.ts
1328
- var init_mcp = __esm({
1329
- "src/types/mcp.ts"() {
1330
- init_cjs_shims();
1331
- }
1332
- });
1333
- var init_base2 = __esm({
1334
- "src/services/mcp/base.ts"() {
1335
- init_cjs_shims();
1336
- }
1337
- });
1338
-
1339
- // src/services/mcp/lanhu.ts
1340
- var init_lanhu = __esm({
1341
- "src/services/mcp/lanhu.ts"() {
1342
- init_cjs_shims();
1343
- init_base2();
1344
- }
1345
- });
1346
-
1347
- // src/services/mcp/figma.ts
1348
- var init_figma = __esm({
1349
- "src/services/mcp/figma.ts"() {
1350
- init_cjs_shims();
1351
- init_base2();
1352
- }
1353
- });
1354
-
1355
- // src/services/mcp/manager.ts
1356
- var init_manager = __esm({
1357
- "src/services/mcp/manager.ts"() {
1358
- init_cjs_shims();
1359
- init_base2();
1360
- init_lanhu();
1361
- init_figma();
1362
- }
1363
- });
1364
-
1365
- // src/services/mcp/index.ts
1366
- var init_mcp2 = __esm({
1367
- "src/services/mcp/index.ts"() {
1368
- init_cjs_shims();
1369
- init_mcp();
1370
- init_base2();
1371
- init_lanhu();
1372
- init_figma();
1373
- init_manager();
1374
- }
1375
- });
1376
-
1377
- // src/services/index.ts
1378
- var init_services = __esm({
1379
- "src/services/index.ts"() {
1380
- init_cjs_shims();
1381
- init_config();
1382
- init_model2();
1383
- init_adapters();
1384
- init_mcp2();
1385
- }
1386
- });
1387
949
 
1388
950
  // src/commands/model.ts
1389
951
  var model_exports = {};
@@ -1399,17 +961,18 @@ __export(model_exports, {
1399
961
  async function handleModel(args, ctx) {
1400
962
  const subCommand = args[0];
1401
963
  const configManager = ctx.configManager;
964
+ const modelService = ctx.modelService;
1402
965
  switch (subCommand) {
1403
966
  case "list":
1404
967
  return listModels();
1405
968
  case "current":
1406
969
  return showCurrentModel(configManager);
1407
970
  case "set":
1408
- return setModelDirectly(args[1], configManager);
971
+ return setModelDirectly(args[1], configManager, modelService);
1409
972
  case "verify":
1410
973
  return verifyCurrentModel(configManager);
1411
974
  default:
1412
- return selectModel(configManager);
975
+ return selectModel(configManager, modelService);
1413
976
  }
1414
977
  }
1415
978
  async function listModels() {
@@ -1450,7 +1013,7 @@ async function showCurrentModel(configManager) {
1450
1013
  ];
1451
1014
  return { output: lines.join("\n") };
1452
1015
  }
1453
- async function setModelDirectly(modelId, configManager) {
1016
+ async function setModelDirectly(modelId, configManager, modelService) {
1454
1017
  if (!modelId) {
1455
1018
  return {
1456
1019
  output: chalk9__default.default.red("\u8BF7\u6307\u5B9A\u6A21\u578BID\uFF0C\u4F8B\u5982: /model set gpt-4o")
@@ -1465,11 +1028,22 @@ async function setModelDirectly(modelId, configManager) {
1465
1028
  }
1466
1029
  configManager.set("model", modelId);
1467
1030
  await configManager.save();
1031
+ const apiKey = configManager.get("apiKey");
1032
+ if (apiKey) {
1033
+ try {
1034
+ await modelService.configureModel({
1035
+ provider: modelInfo.provider,
1036
+ model: modelId,
1037
+ apiKey
1038
+ });
1039
+ } catch {
1040
+ }
1041
+ }
1468
1042
  return {
1469
1043
  output: chalk9__default.default.green(`\u2713 \u5DF2\u5207\u6362\u5230\u6A21\u578B: ${modelInfo.name} (${modelInfo.provider})`)
1470
1044
  };
1471
1045
  }
1472
- async function verifyCurrentModel(configManager) {
1046
+ async function verifyCurrentModel(configManager, modelService) {
1473
1047
  const currentModel = configManager.get("model");
1474
1048
  const apiKey = configManager.get("apiKey");
1475
1049
  if (!apiKey) {
@@ -1502,7 +1076,7 @@ async function verifyCurrentModel(configManager) {
1502
1076
  };
1503
1077
  }
1504
1078
  }
1505
- async function selectModel(configManager) {
1079
+ async function selectModel(configManager, modelService) {
1506
1080
  try {
1507
1081
  const currentModel = configManager.get("model");
1508
1082
  const currentApiKey = configManager.get("apiKey");
@@ -1566,6 +1140,11 @@ async function selectModel(configManager) {
1566
1140
  configManager.set("model", modelResponse.model);
1567
1141
  configManager.set("apiKey", apiKeyResponse.apiKey);
1568
1142
  await configManager.save();
1143
+ await modelService.configureModel({
1144
+ provider: selectedModel.provider,
1145
+ model: modelResponse.model,
1146
+ apiKey: apiKeyResponse.apiKey
1147
+ });
1569
1148
  return {
1570
1149
  output: chalk9__default.default.green(`
1571
1150
  \u2713 \u6A21\u578B\u914D\u7F6E\u5B8C\u6210
@@ -1614,10 +1193,10 @@ function createSpinner(message) {
1614
1193
  };
1615
1194
  }
1616
1195
  var model_default;
1617
- var init_model3 = __esm({
1196
+ var init_model2 = __esm({
1618
1197
  "src/commands/model.ts"() {
1619
1198
  init_cjs_shims();
1620
- init_services();
1199
+ init_adapters();
1621
1200
  init_model();
1622
1201
  model_default = selectModel;
1623
1202
  }
@@ -1633,13 +1212,13 @@ __export(update_exports, {
1633
1212
  });
1634
1213
  function getPackageInfo() {
1635
1214
  const possiblePaths = [
1636
- path7__namespace.resolve(__dirname, "..", "..", "package.json"),
1637
- path7__namespace.resolve(__dirname, "..", "..", "..", "package.json")
1215
+ path5__namespace.resolve(__dirname, "..", "..", "package.json"),
1216
+ path5__namespace.resolve(__dirname, "..", "..", "..", "package.json")
1638
1217
  ];
1639
1218
  for (const pkgPath of possiblePaths) {
1640
1219
  try {
1641
- if (fs9__namespace.existsSync(pkgPath)) {
1642
- const content = fs9__namespace.readFileSync(pkgPath, "utf-8");
1220
+ if (fs7__namespace.existsSync(pkgPath)) {
1221
+ const content = fs7__namespace.readFileSync(pkgPath, "utf-8");
1643
1222
  return JSON.parse(content);
1644
1223
  }
1645
1224
  } catch {
@@ -1835,6 +1414,7 @@ async function handleNew(args, ctx) {
1835
1414
  context: null,
1836
1415
  clarityScore: 0,
1837
1416
  clarificationQuestions: [],
1417
+ referenceResources: [],
1838
1418
  complexity: 0,
1839
1419
  bddScenarios: [],
1840
1420
  specItems: [],
@@ -1877,7 +1457,7 @@ async function executeWorkflow(ctx) {
1877
1457
  const lines = [];
1878
1458
  try {
1879
1459
  if (activeSession.phase === "context") {
1880
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/8: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
1460
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 1/9: \u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6 \u2501\u2501\u2501"));
1881
1461
  lines.push("");
1882
1462
  activeSession.context = await readProjectContext(ctx.options.workingDirectory);
1883
1463
  lines.push(chalk9__default.default.gray(` \u9879\u76EE: ${activeSession.context.name}`));
@@ -1891,7 +1471,7 @@ async function executeWorkflow(ctx) {
1891
1471
  }
1892
1472
  if (activeSession.phase === "clarify") {
1893
1473
  lines.push("");
1894
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/8: \u9700\u6C42\u6F84\u6E05 \u2501\u2501\u2501"));
1474
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 2/9: \u9700\u6C42\u6F84\u6E05 \u2501\u2501\u2501"));
1895
1475
  lines.push("");
1896
1476
  const clarityResult = analyzeRequirementClarity(
1897
1477
  activeSession.requirement,
@@ -1917,11 +1497,40 @@ async function executeWorkflow(ctx) {
1917
1497
  return { output: lines.join("\n") };
1918
1498
  }
1919
1499
  lines.push(chalk9__default.default.green(" \u2713 \u9700\u6C42\u6E05\u6670\uFF0C\u7EE7\u7EED\u4E0B\u4E00\u6B65"));
1500
+ activeSession.phase = "reference";
1501
+ }
1502
+ if (activeSession.phase === "reference") {
1503
+ lines.push("");
1504
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 3/9: \u53C2\u8003\u8D44\u6E90\u5206\u6790 \u2501\u2501\u2501"));
1505
+ lines.push("");
1506
+ const urls = extractUrls(activeSession.refinedRequirement);
1507
+ if (urls.length > 0) {
1508
+ lines.push(chalk9__default.default.gray(` \u53D1\u73B0 ${urls.length} \u4E2A\u53C2\u8003\u94FE\u63A5`));
1509
+ lines.push("");
1510
+ for (const url of urls) {
1511
+ lines.push(chalk9__default.default.gray(` \u{1F4CE} ${url}`));
1512
+ try {
1513
+ const resource = await fetchAndAnalyzeReference(url, ctx);
1514
+ activeSession.referenceResources.push(resource);
1515
+ lines.push(chalk9__default.default.green(` \u2713 \u5DF2\u5206\u6790`));
1516
+ activeSession.refinedRequirement += `
1517
+
1518
+ \u3010\u53C2\u8003\u8D44\u6E90\u5206\u6790 - ${url}\u3011
1519
+ ${resource.analysis}`;
1520
+ } catch (error) {
1521
+ lines.push(chalk9__default.default.yellow(` \u26A0 \u83B7\u53D6\u5931\u8D25: ${error.message}`));
1522
+ }
1523
+ }
1524
+ lines.push("");
1525
+ lines.push(chalk9__default.default.green(" \u2713 \u53C2\u8003\u8D44\u6E90\u5206\u6790\u5B8C\u6210"));
1526
+ } else {
1527
+ lines.push(chalk9__default.default.gray(" \u65E0\u5916\u90E8\u53C2\u8003\u94FE\u63A5"));
1528
+ }
1920
1529
  activeSession.phase = "analysis";
1921
1530
  }
1922
1531
  if (activeSession.phase === "analysis") {
1923
1532
  lines.push("");
1924
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 3/8: \u590D\u6742\u5EA6\u8BC4\u4F30 \u2501\u2501\u2501"));
1533
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 4/9: \u590D\u6742\u5EA6\u8BC4\u4F30 \u2501\u2501\u2501"));
1925
1534
  lines.push("");
1926
1535
  activeSession.complexity = analyzeComplexity(
1927
1536
  activeSession.refinedRequirement,
@@ -1938,12 +1547,13 @@ async function executeWorkflow(ctx) {
1938
1547
  }
1939
1548
  if (activeSession.phase === "bdd") {
1940
1549
  lines.push("");
1941
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 4/8: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
1550
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/9: BDD \u573A\u666F\u62C6\u89E3 \u2501\u2501\u2501"));
1942
1551
  lines.push("");
1943
1552
  activeSession.bddScenarios = generateBDDScenarios(
1944
1553
  activeSession.refinedRequirement,
1945
1554
  activeSession.context,
1946
- activeSession.clarificationQuestions
1555
+ activeSession.clarificationQuestions,
1556
+ activeSession.referenceResources
1947
1557
  );
1948
1558
  for (const scenario of activeSession.bddScenarios) {
1949
1559
  lines.push(chalk9__default.default.white(` Feature: ${scenario.feature}`));
@@ -1958,13 +1568,14 @@ async function executeWorkflow(ctx) {
1958
1568
  }
1959
1569
  if (activeSession.phase === "spec") {
1960
1570
  lines.push("");
1961
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 5/8: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
1571
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/9: OpenSpec \u89C4\u683C \u2501\u2501\u2501"));
1962
1572
  lines.push("");
1963
1573
  activeSession.specItems = generateSpecItems(
1964
1574
  activeSession.refinedRequirement,
1965
1575
  activeSession.context,
1966
1576
  activeSession.bddScenarios,
1967
- activeSession.clarificationQuestions
1577
+ activeSession.clarificationQuestions,
1578
+ activeSession.referenceResources
1968
1579
  );
1969
1580
  const specPath = await saveSpecFile(ctx.options.workingDirectory, activeSession);
1970
1581
  lines.push(chalk9__default.default.green(" \u2713 \u89C4\u683C\u6587\u4EF6\u5DF2\u751F\u6210"));
@@ -1988,7 +1599,7 @@ async function executeWorkflow(ctx) {
1988
1599
  }
1989
1600
  if (activeSession.phase === "tdd") {
1990
1601
  lines.push("");
1991
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 6/8: TDD \u6D4B\u8BD5\u751F\u6210 \u2501\u2501\u2501"));
1602
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 7/9: TDD \u6D4B\u8BD5\u751F\u6210 \u2501\u2501\u2501"));
1992
1603
  lines.push("");
1993
1604
  activeSession.testFiles = await generateTests(ctx.options.workingDirectory, activeSession);
1994
1605
  lines.push(chalk9__default.default.green(" \u2713 \u6D4B\u8BD5\u6587\u4EF6\u5DF2\u751F\u6210"));
@@ -1999,7 +1610,7 @@ async function executeWorkflow(ctx) {
1999
1610
  }
2000
1611
  if (activeSession.phase === "develop") {
2001
1612
  lines.push("");
2002
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 7/8: \u5F00\u53D1\u5B9E\u73B0 \u2501\u2501\u2501"));
1613
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 8/9: \u5F00\u53D1\u5B9E\u73B0 \u2501\u2501\u2501"));
2003
1614
  lines.push("");
2004
1615
  lines.push(chalk9__default.default.yellow(" \u{1F680} \u6B63\u5728\u8C03\u7528 AI \u751F\u6210\u4EE3\u7801..."));
2005
1616
  try {
@@ -2024,7 +1635,7 @@ async function executeWorkflow(ctx) {
2024
1635
  }
2025
1636
  if (activeSession.phase === "review") {
2026
1637
  lines.push("");
2027
- lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 8/8: \u4EE3\u7801\u5BA1\u6838 \u2501\u2501\u2501"));
1638
+ lines.push(chalk9__default.default.cyan("\u2501\u2501\u2501 \u9636\u6BB5 9/9: \u4EE3\u7801\u5BA1\u6838 \u2501\u2501\u2501"));
2028
1639
  lines.push("");
2029
1640
  lines.push(chalk9__default.default.yellow(" \u{1F50D} \u6B63\u5728\u8FDB\u884C\u4EE3\u7801\u5BA1\u6838..."));
2030
1641
  try {
@@ -2321,18 +1932,18 @@ ${session.context.devStandards.slice(0, 2e3)}` : ""}`
2321
1932
  });
2322
1933
  const codeBlocks = parseCodeBlocks(response.content);
2323
1934
  for (const block of codeBlocks) {
2324
- const filePath = path7__namespace.join(workingDir, block.filename);
2325
- const dir = path7__namespace.dirname(filePath);
2326
- await fs7__namespace.mkdir(dir, { recursive: true });
2327
- await fs7__namespace.writeFile(filePath, block.code, "utf-8");
1935
+ const filePath = path5__namespace.join(workingDir, block.filename);
1936
+ const dir = path5__namespace.dirname(filePath);
1937
+ await fs5__namespace.mkdir(dir, { recursive: true });
1938
+ await fs5__namespace.writeFile(filePath, block.code, "utf-8");
2328
1939
  files.push(block.filename);
2329
1940
  }
2330
1941
  if (files.length === 0) {
2331
- const implDir = path7__namespace.join(workingDir, "src", "features");
2332
- await fs7__namespace.mkdir(implDir, { recursive: true });
1942
+ const implDir = path5__namespace.join(workingDir, "src", "features");
1943
+ await fs5__namespace.mkdir(implDir, { recursive: true });
2333
1944
  const featureName = session.specItems[0]?.title || "feature";
2334
1945
  const fileName = `${featureName.replace(/[^a-zA-Z0-9]/g, "_")}.ts`;
2335
- const filePath = path7__namespace.join(implDir, fileName);
1946
+ const filePath = path5__namespace.join(implDir, fileName);
2336
1947
  const stubCode = `/**
2337
1948
  * ${session.requirement}
2338
1949
  *
@@ -2344,7 +1955,7 @@ export function ${featureName.replace(/[^a-zA-Z0-9]/g, "")}() {
2344
1955
  console.log('${featureName} - \u5F85\u5B9E\u73B0');
2345
1956
  }
2346
1957
  `;
2347
- await fs7__namespace.writeFile(filePath, stubCode, "utf-8");
1958
+ await fs5__namespace.writeFile(filePath, stubCode, "utf-8");
2348
1959
  files.push(`src/features/${fileName}`);
2349
1960
  }
2350
1961
  return { success: true, files };
@@ -2399,7 +2010,7 @@ async function executeReview(ctx, session) {
2399
2010
  const codeContents = [];
2400
2011
  for (const file of session.implFiles) {
2401
2012
  try {
2402
- const content = await fs7__namespace.readFile(path7__namespace.join(workingDir, file), "utf-8");
2013
+ const content = await fs5__namespace.readFile(path5__namespace.join(workingDir, file), "utf-8");
2403
2014
  codeContents.push(`// ${file}
2404
2015
  ${content}`);
2405
2016
  } catch {
@@ -2408,7 +2019,7 @@ ${content}`);
2408
2019
  const testContents = [];
2409
2020
  for (const file of session.testFiles) {
2410
2021
  try {
2411
- const content = await fs7__namespace.readFile(path7__namespace.join(workingDir, file), "utf-8");
2022
+ const content = await fs5__namespace.readFile(path5__namespace.join(workingDir, file), "utf-8");
2412
2023
  testContents.push(`// ${file}
2413
2024
  ${content}`);
2414
2025
  } catch {
@@ -2487,7 +2098,7 @@ ${testContents.join("\n\n") || "\uFF08\u65E0\u6D4B\u8BD5\u6587\u4EF6\uFF09"}
2487
2098
  }
2488
2099
  async function readProjectContext(workingDir) {
2489
2100
  const context = {
2490
- name: path7__namespace.basename(workingDir),
2101
+ name: path5__namespace.basename(workingDir),
2491
2102
  type: "unknown",
2492
2103
  framework: null,
2493
2104
  techStack: [],
@@ -2496,11 +2107,11 @@ async function readProjectContext(workingDir) {
2496
2107
  agentsMd: "",
2497
2108
  configYaml: ""
2498
2109
  };
2499
- const agentsPath = path7__namespace.join(workingDir, "AGENTS.md");
2110
+ const agentsPath = path5__namespace.join(workingDir, "AGENTS.md");
2500
2111
  try {
2501
- const stats = await fs7__namespace.stat(agentsPath);
2112
+ const stats = await fs5__namespace.stat(agentsPath);
2502
2113
  if (stats.size <= MAX_FILE_SIZE2) {
2503
- context.agentsMd = await fs7__namespace.readFile(agentsPath, "utf-8");
2114
+ context.agentsMd = await fs5__namespace.readFile(agentsPath, "utf-8");
2504
2115
  const nameMatch = context.agentsMd.match(/\|\s*项目名称\s*\|\s*([^\s|]+)/);
2505
2116
  if (nameMatch) context.name = nameMatch[1];
2506
2117
  const typeMatch = context.agentsMd.match(/\|\s*项目类型\s*\|\s*([^\s|]+)/);
@@ -2512,11 +2123,11 @@ async function readProjectContext(workingDir) {
2512
2123
  }
2513
2124
  } catch {
2514
2125
  }
2515
- const configPath = path7__namespace.join(workingDir, "openspec", "config.yaml");
2126
+ const configPath = path5__namespace.join(workingDir, "openspec", "config.yaml");
2516
2127
  try {
2517
- const stats = await fs7__namespace.stat(configPath);
2128
+ const stats = await fs5__namespace.stat(configPath);
2518
2129
  if (stats.size <= MAX_FILE_SIZE2) {
2519
- context.configYaml = await fs7__namespace.readFile(configPath, "utf-8");
2130
+ context.configYaml = await fs5__namespace.readFile(configPath, "utf-8");
2520
2131
  const nameMatch = context.configYaml.match(/name:\s*(.+)/);
2521
2132
  if (nameMatch) context.name = nameMatch[1].trim();
2522
2133
  const typeMatch = context.configYaml.match(/type:\s*(.+)/);
@@ -2535,11 +2146,11 @@ async function readProjectContext(workingDir) {
2535
2146
  }
2536
2147
  } catch {
2537
2148
  }
2538
- const devStandardsPath = path7__namespace.join(workingDir, ".sf-cli", "norms", "devstanded.md");
2149
+ const devStandardsPath = path5__namespace.join(workingDir, ".sf-cli", "norms", "devstanded.md");
2539
2150
  try {
2540
- const stats = await fs7__namespace.stat(devStandardsPath);
2151
+ const stats = await fs5__namespace.stat(devStandardsPath);
2541
2152
  if (stats.size <= MAX_FILE_SIZE2) {
2542
- context.devStandards = await fs7__namespace.readFile(devStandardsPath, "utf-8");
2153
+ context.devStandards = await fs5__namespace.readFile(devStandardsPath, "utf-8");
2543
2154
  }
2544
2155
  } catch {
2545
2156
  }
@@ -2566,13 +2177,41 @@ function analyzeComplexity(requirement, context) {
2566
2177
  if (!context.framework) score += 0.5;
2567
2178
  return Math.max(1, Math.min(10, Math.round(score)));
2568
2179
  }
2569
- function generateBDDScenarios(requirement, context, questions) {
2180
+ function generateBDDScenarios(requirement, context, questions, references = []) {
2570
2181
  const scenarios = [];
2571
2182
  questions.find((q) => q.category === "ui" && q.answered)?.answer;
2572
2183
  const interactionAnswer = questions.find((q) => q.category === "interaction" && q.answered)?.answer;
2573
2184
  const edgeAnswer = questions.find((q) => q.category === "edge" && q.answered)?.answer;
2185
+ if (references.length > 0) {
2186
+ for (const ref of references) {
2187
+ const refFeatures = extractFeaturesFromReference(ref);
2188
+ for (const feature of refFeatures) {
2189
+ const scenario = {
2190
+ feature: feature.title,
2191
+ description: feature.description,
2192
+ scenarios: []
2193
+ };
2194
+ scenario.scenarios.push({
2195
+ name: `\u6B63\u5E38\u6D41\u7A0B: ${feature.title}`,
2196
+ given: [`\u7528\u6237\u8FDB\u5165\u76F8\u5173\u9875\u9762`],
2197
+ when: [`\u7528\u6237\u6267\u884C "${feature.title}" \u64CD\u4F5C`],
2198
+ then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u5E76\u8FD4\u56DE\u9884\u671F\u7ED3\u679C`]
2199
+ });
2200
+ if (feature.hasInput) {
2201
+ scenario.scenarios.push({
2202
+ name: `\u8FB9\u754C\u60C5\u51B5: \u8F93\u5165\u9A8C\u8BC1`,
2203
+ given: [`\u7528\u6237\u8FDB\u5165\u8F93\u5165\u754C\u9762`],
2204
+ when: [`\u7528\u6237\u8F93\u5165\u8FB9\u754C\u503C\u6216\u7A7A\u503C`],
2205
+ then: [`\u7CFB\u7EDF\u5E94\u6B63\u786E\u5904\u7406\u8FB9\u754C\u60C5\u51B5`]
2206
+ });
2207
+ }
2208
+ scenarios.push(scenario);
2209
+ }
2210
+ }
2211
+ }
2574
2212
  const features = extractFeatures(requirement);
2575
2213
  for (const feature of features) {
2214
+ if (scenarios.some((s) => s.feature === feature.title)) continue;
2576
2215
  const scenario = {
2577
2216
  feature: feature.title,
2578
2217
  description: feature.description,
@@ -2604,6 +2243,46 @@ function generateBDDScenarios(requirement, context, questions) {
2604
2243
  }
2605
2244
  return scenarios;
2606
2245
  }
2246
+ function extractFeaturesFromReference(ref) {
2247
+ const features = [];
2248
+ const analysis = ref.analysis.toLowerCase();
2249
+ if (analysis.includes("\u8F93\u5165") || analysis.includes("\u8868\u5355")) {
2250
+ features.push({
2251
+ title: "\u8F93\u5165\u8868\u5355",
2252
+ description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u8F93\u5165\u8868\u5355\u529F\u80FD",
2253
+ hasInput: true
2254
+ });
2255
+ }
2256
+ if (analysis.includes("\u6309\u94AE") || analysis.includes("\u64CD\u4F5C")) {
2257
+ features.push({
2258
+ title: "\u4EA4\u4E92\u6309\u94AE",
2259
+ description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u6309\u94AE\u4EA4\u4E92",
2260
+ hasInput: false
2261
+ });
2262
+ }
2263
+ if (analysis.includes("\u8868\u683C") || analysis.includes("\u5217\u8868")) {
2264
+ features.push({
2265
+ title: "\u6570\u636E\u5217\u8868",
2266
+ description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u6570\u636E\u5C55\u793A",
2267
+ hasInput: false
2268
+ });
2269
+ }
2270
+ if (analysis.includes("\u56FE\u8868") || analysis.includes("\u53EF\u89C6\u5316")) {
2271
+ features.push({
2272
+ title: "\u56FE\u8868\u5C55\u793A",
2273
+ description: "\u53C2\u8003\u754C\u9762\u4E2D\u7684\u56FE\u8868\u53EF\u89C6\u5316",
2274
+ hasInput: false
2275
+ });
2276
+ }
2277
+ if (features.length === 0) {
2278
+ features.push({
2279
+ title: "\u53C2\u8003\u529F\u80FD\u5B9E\u73B0",
2280
+ description: `\u57FA\u4E8E\u53C2\u8003\u8D44\u6E90 ${ref.url} \u5B9E\u73B0\u7684\u529F\u80FD`,
2281
+ hasInput: true
2282
+ });
2283
+ }
2284
+ return features;
2285
+ }
2607
2286
  function extractFeatures(requirement) {
2608
2287
  const features = [];
2609
2288
  const urlMatch = requirement.match(/https?:\/\/[^\s]+/);
@@ -2644,15 +2323,26 @@ function extractFeatures(requirement) {
2644
2323
  }
2645
2324
  return features;
2646
2325
  }
2647
- function generateSpecItems(requirement, context, bddScenarios, questions) {
2326
+ function generateSpecItems(requirement, context, bddScenarios, questions, references = []) {
2648
2327
  const items = [];
2649
2328
  let id = 1;
2329
+ for (const ref of references) {
2330
+ items.push({
2331
+ id: `T${id.toString().padStart(3, "0")}`,
2332
+ title: `\u53C2\u8003\u5206\u6790: ${ref.type}`,
2333
+ description: `\u5206\u6790\u53C2\u8003\u8D44\u6E90 ${ref.url}`,
2334
+ priority: "high",
2335
+ files: [],
2336
+ tests: []
2337
+ });
2338
+ id++;
2339
+ }
2650
2340
  for (const scenario of bddScenarios) {
2651
2341
  items.push({
2652
2342
  id: `T${id.toString().padStart(3, "0")}`,
2653
2343
  title: scenario.feature,
2654
2344
  description: scenario.description,
2655
- priority: id <= 2 ? "high" : "medium",
2345
+ priority: id <= 3 ? "high" : "medium",
2656
2346
  files: [],
2657
2347
  tests: []
2658
2348
  });
@@ -2669,11 +2359,11 @@ function generateSpecItems(requirement, context, bddScenarios, questions) {
2669
2359
  return items;
2670
2360
  }
2671
2361
  async function saveSpecFile(workingDir, session) {
2672
- const specDir = path7__namespace.join(workingDir, "openspec", "changes");
2673
- await fs7__namespace.mkdir(specDir, { recursive: true });
2674
- const specPath = path7__namespace.join(specDir, `${session.id}-spec.md`);
2362
+ const specDir = path5__namespace.join(workingDir, "openspec", "changes");
2363
+ await fs5__namespace.mkdir(specDir, { recursive: true });
2364
+ const specPath = path5__namespace.join(specDir, `${session.id}-spec.md`);
2675
2365
  const content = formatSpecFile(session);
2676
- await fs7__namespace.writeFile(specPath, content, "utf-8");
2366
+ await fs5__namespace.writeFile(specPath, content, "utf-8");
2677
2367
  return specPath;
2678
2368
  }
2679
2369
  function formatSpecFile(session) {
@@ -2695,6 +2385,19 @@ function formatSpecFile(session) {
2695
2385
  lines.push("---");
2696
2386
  lines.push("");
2697
2387
  }
2388
+ if (session.referenceResources.length > 0) {
2389
+ lines.push("## \u53C2\u8003\u8D44\u6E90");
2390
+ lines.push("");
2391
+ for (const ref of session.referenceResources) {
2392
+ lines.push(`### ${ref.url}`);
2393
+ lines.push(`> \u7C7B\u578B: ${ref.type}`);
2394
+ lines.push("");
2395
+ lines.push(ref.analysis);
2396
+ lines.push("");
2397
+ }
2398
+ lines.push("---");
2399
+ lines.push("");
2400
+ }
2698
2401
  if (session.clarificationQuestions.some((q) => q.answered)) {
2699
2402
  lines.push("## \u9700\u6C42\u6F84\u6E05");
2700
2403
  lines.push("");
@@ -2734,14 +2437,14 @@ function formatSpecFile(session) {
2734
2437
  return lines.join("\n");
2735
2438
  }
2736
2439
  async function generateTests(workingDir, session) {
2737
- const testDir = path7__namespace.join(workingDir, "tests");
2738
- await fs7__namespace.mkdir(testDir, { recursive: true });
2440
+ const testDir = path5__namespace.join(workingDir, "tests");
2441
+ await fs5__namespace.mkdir(testDir, { recursive: true });
2739
2442
  const testFiles = [];
2740
2443
  for (const scenario of session.bddScenarios) {
2741
2444
  const testName = scenario.feature.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, "_");
2742
- const testPath = path7__namespace.join(testDir, `${testName}.test.ts`);
2445
+ const testPath = path5__namespace.join(testDir, `${testName}.test.ts`);
2743
2446
  const content = generateTestFile(scenario);
2744
- await fs7__namespace.writeFile(testPath, content, "utf-8");
2447
+ await fs5__namespace.writeFile(testPath, content, "utf-8");
2745
2448
  testFiles.push(`tests/${testName}.test.ts`);
2746
2449
  }
2747
2450
  return testFiles;
@@ -2765,9 +2468,9 @@ function generateTestFile(scenario) {
2765
2468
  }
2766
2469
  async function archiveWorkflow(workingDir) {
2767
2470
  if (!activeSession) return;
2768
- const archiveDir = path7__namespace.join(workingDir, "openspec", "spec");
2769
- await fs7__namespace.mkdir(archiveDir, { recursive: true });
2770
- const archivePath = path7__namespace.join(archiveDir, `${activeSession.id}.md`);
2471
+ const archiveDir = path5__namespace.join(workingDir, "openspec", "spec");
2472
+ await fs5__namespace.mkdir(archiveDir, { recursive: true });
2473
+ const archivePath = path5__namespace.join(archiveDir, `${activeSession.id}.md`);
2771
2474
  const content = `# \u5F52\u6863: ${activeSession.requirement.slice(0, 50)}
2772
2475
 
2773
2476
  > \u5F52\u6863\u65F6\u95F4: ${(/* @__PURE__ */ new Date()).toISOString()}
@@ -2793,13 +2496,103 @@ ${activeSession.refinedRequirement}
2793
2496
 
2794
2497
  ${activeSession.testFiles.map((f) => `- ${f}`).join("\n") || "\u65E0"}
2795
2498
  `;
2796
- await fs7__namespace.writeFile(archivePath, content, "utf-8");
2499
+ await fs5__namespace.writeFile(archivePath, content, "utf-8");
2797
2500
  }
2798
2501
  function generateSessionId() {
2799
2502
  const timestamp = Date.now().toString(36);
2800
2503
  const random = Math.random().toString(36).slice(2, 6);
2801
2504
  return `WF-${timestamp}-${random}`.toUpperCase();
2802
2505
  }
2506
+ function extractUrls(text) {
2507
+ const urlRegex = /https?:\/\/[^\s<>"{}|\\^`\[\]]+/gi;
2508
+ const matches = text.match(urlRegex);
2509
+ return matches ? [...new Set(matches)] : [];
2510
+ }
2511
+ async function fetchAndAnalyzeReference(url, ctx) {
2512
+ const type = detectResourceType(url);
2513
+ let content = "";
2514
+ let analysis = "";
2515
+ try {
2516
+ const response = await fetch(url, {
2517
+ headers: {
2518
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
2519
+ }
2520
+ });
2521
+ if (!response.ok) {
2522
+ throw new Error(`HTTP ${response.status}`);
2523
+ }
2524
+ content = await response.text();
2525
+ if (ctx.modelService.getCurrentModel()) {
2526
+ analysis = await analyzeReferenceContent(url, content, type, ctx);
2527
+ } else {
2528
+ analysis = extractBasicInfo(content, type);
2529
+ }
2530
+ } catch (error) {
2531
+ throw new Error(`\u65E0\u6CD5\u83B7\u53D6\u53C2\u8003\u8D44\u6E90: ${error.message}`);
2532
+ }
2533
+ return { url, type, content: content.slice(0, 1e4), analysis };
2534
+ }
2535
+ function detectResourceType(url) {
2536
+ if (url.includes("figma.com") || url.includes("lanhuapp.com")) {
2537
+ return "design";
2538
+ }
2539
+ if (/\.(png|jpg|jpeg|gif|webp|svg)$/i.test(url)) {
2540
+ return "image";
2541
+ }
2542
+ if (/api\//i.test(url)) {
2543
+ return "api";
2544
+ }
2545
+ return "webpage";
2546
+ }
2547
+ async function analyzeReferenceContent(url, content, type, ctx) {
2548
+ const typePrompts = {
2549
+ webpage: "\u5206\u6790\u8FD9\u4E2A\u7F51\u9875\u7684\u529F\u80FD\u3001UI\u7EC4\u4EF6\u548C\u4EA4\u4E92\u65B9\u5F0F",
2550
+ design: "\u5206\u6790\u8FD9\u4E2A\u8BBE\u8BA1\u7A3F\u7684\u5E03\u5C40\u3001\u7EC4\u4EF6\u548C\u6837\u5F0F",
2551
+ image: "\u63CF\u8FF0\u8FD9\u4E2A\u56FE\u7247\u7684\u5185\u5BB9\u548C\u8BBE\u8BA1\u5143\u7D20",
2552
+ api: "\u5206\u6790\u8FD9\u4E2AAPI\u7684\u7ED3\u6784\u548C\u53C2\u6570"
2553
+ };
2554
+ const prompt2 = `
2555
+ \u8BF7\u5206\u6790\u4EE5\u4E0B\u53C2\u8003\u8D44\u6E90\u7684 URL\uFF0C\u63D0\u53D6\u5BF9\u5F00\u53D1\u6709\u7528\u7684\u4FE1\u606F\uFF1A
2556
+
2557
+ URL: ${url}
2558
+ \u7C7B\u578B: ${type}
2559
+
2560
+ \u5185\u5BB9\u6458\u8981:
2561
+ ${content.slice(0, 5e3)}
2562
+
2563
+ ${typePrompts[type]}
2564
+
2565
+ \u8BF7\u63D0\u53D6\uFF1A
2566
+ 1. \u4E3B\u8981\u529F\u80FD\u70B9
2567
+ 2. UI\u7EC4\u4EF6\u7ED3\u6784
2568
+ 3. \u4EA4\u4E92\u65B9\u5F0F
2569
+ 4. \u6570\u636E\u7ED3\u6784\uFF08\u5982\u679C\u6709\uFF09
2570
+ 5. \u6280\u672F\u5B9E\u73B0\u5EFA\u8BAE
2571
+
2572
+ \u4EE5\u7B80\u6D01\u7684\u8981\u70B9\u5F62\u5F0F\u8F93\u51FA\u3002
2573
+ `;
2574
+ try {
2575
+ const response = await ctx.modelService.sendMessage([
2576
+ { role: "user", content: prompt2 }
2577
+ ], { temperature: 0.3, maxTokens: 2e3 });
2578
+ return response.content;
2579
+ } catch {
2580
+ return extractBasicInfo(content, type);
2581
+ }
2582
+ }
2583
+ function extractBasicInfo(content, type) {
2584
+ const titleMatch = content.match(/<title[^>]*>([^<]+)<\/title>/i);
2585
+ const descMatch = content.match(/<meta[^>]*name=["']description["'][^>]*content=["']([^"']+)["']/i);
2586
+ const parts = [];
2587
+ if (titleMatch) {
2588
+ parts.push(`\u6807\u9898: ${titleMatch[1]}`);
2589
+ }
2590
+ if (descMatch) {
2591
+ parts.push(`\u63CF\u8FF0: ${descMatch[1]}`);
2592
+ }
2593
+ parts.push(`\u8D44\u6E90\u7C7B\u578B: ${type}`);
2594
+ return parts.join("\n");
2595
+ }
2803
2596
  function generateComplexityBar(score) {
2804
2597
  const filled = Math.round(score / 2);
2805
2598
  const empty = 5 - filled;
@@ -2809,6 +2602,7 @@ function getPhaseLabel(phase) {
2809
2602
  const labels = {
2810
2603
  context: "\u9879\u76EE\u4E0A\u4E0B\u6587\u83B7\u53D6",
2811
2604
  clarify: "\u9700\u6C42\u6F84\u6E05",
2605
+ reference: "\u53C2\u8003\u8D44\u6E90\u5206\u6790",
2812
2606
  analysis: "\u590D\u6742\u5EA6\u8BC4\u4F30",
2813
2607
  bdd: "BDD \u573A\u666F\u62C6\u89E3",
2814
2608
  spec: "OpenSpec \u89C4\u683C",
@@ -3051,11 +2845,11 @@ var NormsManager = class {
3051
2845
  const files = await this.collectProjectFiles(projectPath);
3052
2846
  for (const filePath of files.slice(0, MAX_FILES_TO_SCAN)) {
3053
2847
  try {
3054
- const stats = await fs7__namespace.stat(filePath);
2848
+ const stats = await fs5__namespace.stat(filePath);
3055
2849
  if (stats.size > MAX_FILE_SIZE) {
3056
2850
  continue;
3057
2851
  }
3058
- const content = await fs7__namespace.readFile(filePath, "utf-8");
2852
+ const content = await fs5__namespace.readFile(filePath, "utf-8");
3059
2853
  const patterns = await this.learnFromFile(filePath, content);
3060
2854
  result.patternsFound += patterns.length;
3061
2855
  result.filesScanned++;
@@ -3078,7 +2872,7 @@ var NormsManager = class {
3078
2872
  * 从单个文件学习规范
3079
2873
  */
3080
2874
  async learnFromFile(filePath, content) {
3081
- const ext = path7__namespace.extname(filePath);
2875
+ const ext = path5__namespace.extname(filePath);
3082
2876
  const patterns = this.extractPatterns(filePath, content, ext);
3083
2877
  for (const pattern of patterns) {
3084
2878
  await this.recordOccurrence({
@@ -3681,16 +3475,16 @@ ${response}`;
3681
3475
  const files = [];
3682
3476
  async function scan(dir) {
3683
3477
  try {
3684
- const entries = await fs7__namespace.readdir(dir, { withFileTypes: true });
3478
+ const entries = await fs5__namespace.readdir(dir, { withFileTypes: true });
3685
3479
  for (const entry of entries) {
3686
3480
  if (entry.isDirectory()) {
3687
3481
  if (!IGNORED_DIRS.includes(entry.name)) {
3688
- await scan(path7__namespace.join(dir, entry.name));
3482
+ await scan(path5__namespace.join(dir, entry.name));
3689
3483
  }
3690
3484
  } else if (entry.isFile()) {
3691
- const ext = path7__namespace.extname(entry.name);
3485
+ const ext = path5__namespace.extname(entry.name);
3692
3486
  if (SCAN_EXTENSIONS.includes(ext)) {
3693
- files.push(path7__namespace.join(dir, entry.name));
3487
+ files.push(path5__namespace.join(dir, entry.name));
3694
3488
  }
3695
3489
  }
3696
3490
  }
@@ -3724,16 +3518,16 @@ ${response}`;
3724
3518
  * 确保规范目录存在
3725
3519
  */
3726
3520
  async ensureNormsDir() {
3727
- await fs7__namespace.mkdir(this.config.normsDir, { recursive: true });
3728
- await fs7__namespace.mkdir(path7__namespace.join(this.config.normsDir, "weekly"), { recursive: true });
3521
+ await fs5__namespace.mkdir(this.config.normsDir, { recursive: true });
3522
+ await fs5__namespace.mkdir(path5__namespace.join(this.config.normsDir, "weekly"), { recursive: true });
3729
3523
  }
3730
3524
  /**
3731
3525
  * 加载已有规范
3732
3526
  */
3733
3527
  async loadStandards() {
3734
- const standardsPath = path7__namespace.join(this.config.normsDir, "patterns.json");
3528
+ const standardsPath = path5__namespace.join(this.config.normsDir, "patterns.json");
3735
3529
  try {
3736
- const content = await fs7__namespace.readFile(standardsPath, "utf-8");
3530
+ const content = await fs5__namespace.readFile(standardsPath, "utf-8");
3737
3531
  const data = JSON.parse(content);
3738
3532
  for (const standard of data) {
3739
3533
  this.standards.set(standard.id, {
@@ -3749,9 +3543,9 @@ ${response}`;
3749
3543
  * 加载权重数据
3750
3544
  */
3751
3545
  async loadWeights() {
3752
- const weightsPath = path7__namespace.join(this.config.normsDir, "weights.json");
3546
+ const weightsPath = path5__namespace.join(this.config.normsDir, "weights.json");
3753
3547
  try {
3754
- const content = await fs7__namespace.readFile(weightsPath, "utf-8");
3548
+ const content = await fs5__namespace.readFile(weightsPath, "utf-8");
3755
3549
  const data = JSON.parse(content);
3756
3550
  for (const weight of data) {
3757
3551
  this.weights.set(weight.standardId, {
@@ -3766,8 +3560,8 @@ ${response}`;
3766
3560
  * 保存规范
3767
3561
  */
3768
3562
  async saveStandards() {
3769
- const standardsPath = path7__namespace.join(this.config.normsDir, "patterns.json");
3770
- await fs7__namespace.writeFile(
3563
+ const standardsPath = path5__namespace.join(this.config.normsDir, "patterns.json");
3564
+ await fs5__namespace.writeFile(
3771
3565
  standardsPath,
3772
3566
  JSON.stringify(Array.from(this.standards.values()), null, 2),
3773
3567
  "utf-8"
@@ -3777,8 +3571,8 @@ ${response}`;
3777
3571
  * 保存权重
3778
3572
  */
3779
3573
  async saveWeights() {
3780
- const weightsPath = path7__namespace.join(this.config.normsDir, "weights.json");
3781
- await fs7__namespace.writeFile(
3574
+ const weightsPath = path5__namespace.join(this.config.normsDir, "weights.json");
3575
+ await fs5__namespace.writeFile(
3782
3576
  weightsPath,
3783
3577
  JSON.stringify(Array.from(this.weights.values()), null, 2),
3784
3578
  "utf-8"
@@ -3805,8 +3599,8 @@ ${response}`;
3805
3599
  * 保存周报
3806
3600
  */
3807
3601
  async saveWeeklyReport(weekId, report) {
3808
- const reportPath = path7__namespace.join(this.config.normsDir, "weekly", `${weekId}.json`);
3809
- await fs7__namespace.writeFile(reportPath, JSON.stringify(report, null, 2), "utf-8");
3602
+ const reportPath = path5__namespace.join(this.config.normsDir, "weekly", `${weekId}.json`);
3603
+ await fs5__namespace.writeFile(reportPath, JSON.stringify(report, null, 2), "utf-8");
3810
3604
  }
3811
3605
  /**
3812
3606
  * 更新 devstanded.md
@@ -3814,8 +3608,8 @@ ${response}`;
3814
3608
  async updateDevStandedMd() {
3815
3609
  const standards = this.getEffectiveStandards();
3816
3610
  const content = this.generateDevStandedMd(standards);
3817
- const mdPath = path7__namespace.join(this.config.normsDir, "devstanded.md");
3818
- await fs7__namespace.writeFile(mdPath, content, "utf-8");
3611
+ const mdPath = path5__namespace.join(this.config.normsDir, "devstanded.md");
3612
+ await fs5__namespace.writeFile(mdPath, content, "utf-8");
3819
3613
  }
3820
3614
  /**
3821
3615
  * 生成 devstanded.md 内容
@@ -3954,7 +3748,7 @@ async function handleInit(args, ctx) {
3954
3748
  async function initProject(options = {}, workingDir) {
3955
3749
  const cwd = workingDir || process.cwd();
3956
3750
  try {
3957
- const stats = await fs7__namespace.stat(cwd);
3751
+ const stats = await fs5__namespace.stat(cwd);
3958
3752
  if (!stats.isDirectory()) {
3959
3753
  return {
3960
3754
  output: chalk9__default.default.red(`\u9519\u8BEF: ${cwd} \u4E0D\u662F\u6709\u6548\u76EE\u5F55`)
@@ -3965,9 +3759,9 @@ async function initProject(options = {}, workingDir) {
3965
3759
  output: chalk9__default.default.red(`\u9519\u8BEF: \u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u9650\u8BBF\u95EE ${cwd}`)
3966
3760
  };
3967
3761
  }
3968
- const sfCliDir = path7__namespace.join(cwd, ".sf-cli");
3969
- const openspecDir = path7__namespace.join(cwd, "openspec");
3970
- const agentsMdPath = path7__namespace.join(cwd, "AGENTS.md");
3762
+ const sfCliDir = path5__namespace.join(cwd, ".sf-cli");
3763
+ const openspecDir = path5__namespace.join(cwd, "openspec");
3764
+ const agentsMdPath = path5__namespace.join(cwd, "AGENTS.md");
3971
3765
  try {
3972
3766
  const agentsExists = await fileExists(agentsMdPath);
3973
3767
  if (agentsExists && !options.force) {
@@ -3986,7 +3780,7 @@ async function initProject(options = {}, workingDir) {
3986
3780
  await normsManager.initialize();
3987
3781
  const scanResult = await normsManager.scanProject(cwd);
3988
3782
  const agentsContent = generateAgentsMd(projectInfo, scanResult);
3989
- await fs7__namespace.writeFile(agentsMdPath, agentsContent, "utf-8");
3783
+ await fs5__namespace.writeFile(agentsMdPath, agentsContent, "utf-8");
3990
3784
  await generateOpenSpecConfig(openspecDir, projectInfo);
3991
3785
  return {
3992
3786
  output: chalk9__default.default.green("\u2713 \u9879\u76EE\u521D\u59CB\u5316\u5B8C\u6210\n") + chalk9__default.default.gray(` \u9879\u76EE\u7C7B\u578B: ${projectInfo.type}
@@ -4027,7 +3821,7 @@ async function createSfCliDirectory(basePath) {
4027
3821
  "logs"
4028
3822
  ];
4029
3823
  for (const dir of dirs) {
4030
- await fs7__namespace.mkdir(path7__namespace.join(basePath, dir), { recursive: true });
3824
+ await fs5__namespace.mkdir(path5__namespace.join(basePath, dir), { recursive: true });
4031
3825
  }
4032
3826
  const config = {
4033
3827
  version: "1.0.0",
@@ -4035,37 +3829,37 @@ async function createSfCliDirectory(basePath) {
4035
3829
  yolo: false,
4036
3830
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
4037
3831
  };
4038
- await fs7__namespace.writeFile(
4039
- path7__namespace.join(basePath, "config.json"),
3832
+ await fs5__namespace.writeFile(
3833
+ path5__namespace.join(basePath, "config.json"),
4040
3834
  JSON.stringify(config, null, 2),
4041
3835
  "utf-8"
4042
3836
  );
4043
- await fs7__namespace.writeFile(
4044
- path7__namespace.join(basePath, "agents", "registry.json"),
3837
+ await fs5__namespace.writeFile(
3838
+ path5__namespace.join(basePath, "agents", "registry.json"),
4045
3839
  JSON.stringify({ version: "1.0.0", agents: {} }, null, 2),
4046
3840
  "utf-8"
4047
3841
  );
4048
- await fs7__namespace.writeFile(
4049
- path7__namespace.join(basePath, "skills", "registry.json"),
3842
+ await fs5__namespace.writeFile(
3843
+ path5__namespace.join(basePath, "skills", "registry.json"),
4050
3844
  JSON.stringify({ version: "1.0.0", skills: {} }, null, 2),
4051
3845
  "utf-8"
4052
3846
  );
4053
- await fs7__namespace.writeFile(
4054
- path7__namespace.join(basePath, "health", "health.md"),
3847
+ await fs5__namespace.writeFile(
3848
+ path5__namespace.join(basePath, "health", "health.md"),
4055
3849
  generateHealthTemplate(),
4056
3850
  "utf-8"
4057
3851
  );
4058
3852
  }
4059
3853
  async function createOpenSpecDirectory(basePath) {
4060
- const changesDir = path7__namespace.join(basePath, "changes");
4061
- const archiveDir = path7__namespace.join(changesDir, "archive");
4062
- const specDir = path7__namespace.join(basePath, "spec");
4063
- await fs7__namespace.mkdir(archiveDir, { recursive: true });
4064
- await fs7__namespace.mkdir(specDir, { recursive: true });
3854
+ const changesDir = path5__namespace.join(basePath, "changes");
3855
+ const archiveDir = path5__namespace.join(changesDir, "archive");
3856
+ const specDir = path5__namespace.join(basePath, "spec");
3857
+ await fs5__namespace.mkdir(archiveDir, { recursive: true });
3858
+ await fs5__namespace.mkdir(specDir, { recursive: true });
4065
3859
  }
4066
3860
  async function analyzeProject(cwd) {
4067
3861
  const result = {
4068
- name: path7__namespace.basename(cwd),
3862
+ name: path5__namespace.basename(cwd),
4069
3863
  type: "unknown",
4070
3864
  framework: null,
4071
3865
  techStack: [],
@@ -4084,9 +3878,9 @@ async function analyzeProject(cwd) {
4084
3878
  hasEslint: false,
4085
3879
  hasPrettier: false
4086
3880
  };
4087
- const pkgPath = path7__namespace.join(cwd, "package.json");
3881
+ const pkgPath = path5__namespace.join(cwd, "package.json");
4088
3882
  try {
4089
- const pkgContent = await fs7__namespace.readFile(pkgPath, "utf-8");
3883
+ const pkgContent = await fs5__namespace.readFile(pkgPath, "utf-8");
4090
3884
  const pkg = JSON.parse(pkgContent);
4091
3885
  result.name = pkg.name || result.name;
4092
3886
  result.dependencies = pkg.dependencies || {};
@@ -4169,7 +3963,7 @@ async function analyzeDirectoryStructure(cwd) {
4169
3963
  others: []
4170
3964
  };
4171
3965
  try {
4172
- const entries = await fs7__namespace.readdir(cwd, { withFileTypes: true });
3966
+ const entries = await fs5__namespace.readdir(cwd, { withFileTypes: true });
4173
3967
  for (const entry of entries) {
4174
3968
  if (!entry.isDirectory()) continue;
4175
3969
  const name = entry.name;
@@ -4205,7 +3999,7 @@ async function findEntryPoints(cwd) {
4205
3999
  "index.js"
4206
4000
  ];
4207
4001
  for (const entry of possibleEntries) {
4208
- const fullPath = path7__namespace.join(cwd, entry);
4002
+ const fullPath = path5__namespace.join(cwd, entry);
4209
4003
  if (await fileExists(fullPath)) {
4210
4004
  entryPoints.push(entry);
4211
4005
  }
@@ -4213,15 +4007,15 @@ async function findEntryPoints(cwd) {
4213
4007
  return entryPoints;
4214
4008
  }
4215
4009
  async function saveProjectAnalysis(sfCliDir, analysis) {
4216
- const analysisPath = path7__namespace.join(sfCliDir, "cache", "analysis", "project-analysis.json");
4217
- await fs7__namespace.writeFile(
4010
+ const analysisPath = path5__namespace.join(sfCliDir, "cache", "analysis", "project-analysis.json");
4011
+ await fs5__namespace.writeFile(
4218
4012
  analysisPath,
4219
4013
  JSON.stringify(analysis, null, 2),
4220
4014
  "utf-8"
4221
4015
  );
4222
4016
  }
4223
4017
  async function generateOpenSpecConfig(openspecDir, analysis) {
4224
- const configPath = path7__namespace.join(openspecDir, "config.yaml");
4018
+ const configPath = path5__namespace.join(openspecDir, "config.yaml");
4225
4019
  const content = `# OpenSpec \u9879\u76EE\u914D\u7F6E
4226
4020
  # \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
4227
4021
 
@@ -4255,7 +4049,7 @@ architecture:
4255
4049
  # \u5F00\u53D1\u89C4\u8303 (\u4ECE\u4EE3\u7801\u4E2D\u5B66\u4E60)
4256
4050
  standards: []
4257
4051
  `;
4258
- await fs7__namespace.writeFile(configPath, content, "utf-8");
4052
+ await fs5__namespace.writeFile(configPath, content, "utf-8");
4259
4053
  }
4260
4054
  function generateAgentsMd(info, scanResult) {
4261
4055
  const techStackList = info.techStack.length > 0 ? info.techStack.map((t) => `| ${t} | \u2713 |`).join("\n") : "| \u5F85\u8BC6\u522B | - |";
@@ -4377,7 +4171,7 @@ function generateHealthTemplate() {
4377
4171
  }
4378
4172
  async function fileExists(filePath) {
4379
4173
  try {
4380
- await fs7__namespace.access(filePath);
4174
+ await fs5__namespace.access(filePath);
4381
4175
  return true;
4382
4176
  } catch {
4383
4177
  return false;
@@ -4541,7 +4335,7 @@ ${chalk9__default.default.yellow("\u793A\u4F8B:")}
4541
4335
  }
4542
4336
 
4543
4337
  // src/commands/runner.ts
4544
- init_model3();
4338
+ init_model2();
4545
4339
  init_update();
4546
4340
 
4547
4341
  // src/commands/clear.ts
@@ -4832,7 +4626,7 @@ var WorkflowEngine = class {
4832
4626
  */
4833
4627
  async initialize(projectPath) {
4834
4628
  this.projectPath = projectPath;
4835
- this.openspecPath = path7__namespace.join(projectPath, "openspec");
4629
+ this.openspecPath = path5__namespace.join(projectPath, "openspec");
4836
4630
  await this.ensureDirectories();
4837
4631
  await this.loadProjectContext();
4838
4632
  await this.restoreState();
@@ -4842,21 +4636,21 @@ var WorkflowEngine = class {
4842
4636
  * 加载项目上下文(AGENTS.md 和 config.yaml)
4843
4637
  */
4844
4638
  async loadProjectContext() {
4845
- const agentsMdPath = path7__namespace.join(this.projectPath, "AGENTS.md");
4639
+ const agentsMdPath = path5__namespace.join(this.projectPath, "AGENTS.md");
4846
4640
  try {
4847
- this.projectContext = await fs7__namespace.readFile(agentsMdPath, "utf-8");
4641
+ this.projectContext = await fs5__namespace.readFile(agentsMdPath, "utf-8");
4848
4642
  } catch {
4849
4643
  this.projectContext = "";
4850
4644
  }
4851
- const configPath = path7__namespace.join(this.openspecPath, "config.yaml");
4645
+ const configPath = path5__namespace.join(this.openspecPath, "config.yaml");
4852
4646
  try {
4853
- this.projectConfig = await fs7__namespace.readFile(configPath, "utf-8");
4647
+ this.projectConfig = await fs5__namespace.readFile(configPath, "utf-8");
4854
4648
  } catch {
4855
4649
  this.projectConfig = "";
4856
4650
  }
4857
- const devstandedPath = path7__namespace.join(this.projectPath, ".sf-cli", "norms", "devstanded.md");
4651
+ const devstandedPath = path5__namespace.join(this.projectPath, ".sf-cli", "norms", "devstanded.md");
4858
4652
  try {
4859
- this.devStandards = await fs7__namespace.readFile(devstandedPath, "utf-8");
4653
+ this.devStandards = await fs5__namespace.readFile(devstandedPath, "utf-8");
4860
4654
  } catch {
4861
4655
  this.devStandards = "";
4862
4656
  }
@@ -4876,7 +4670,7 @@ var WorkflowEngine = class {
4876
4670
  */
4877
4671
  getSpecFilePath() {
4878
4672
  if (!this.state) return null;
4879
- return path7__namespace.join(this.openspecPath, "changes", `${this.state.id}-spec.md`);
4673
+ return path5__namespace.join(this.openspecPath, "changes", `${this.state.id}-spec.md`);
4880
4674
  }
4881
4675
  /**
4882
4676
  * 检查规格文件是否存在
@@ -4885,7 +4679,7 @@ var WorkflowEngine = class {
4885
4679
  const specPath = this.getSpecFilePath();
4886
4680
  if (!specPath) return false;
4887
4681
  try {
4888
- await fs7__namespace.access(specPath);
4682
+ await fs5__namespace.access(specPath);
4889
4683
  return true;
4890
4684
  } catch {
4891
4685
  return false;
@@ -5117,13 +4911,13 @@ var WorkflowEngine = class {
5117
4911
  */
5118
4912
  async getAllActiveWorkflows() {
5119
4913
  const workflows = [];
5120
- const changesDir = path7__namespace.join(this.openspecPath, "changes");
4914
+ const changesDir = path5__namespace.join(this.openspecPath, "changes");
5121
4915
  try {
5122
- const files = await fs7__namespace.readdir(changesDir);
4916
+ const files = await fs5__namespace.readdir(changesDir);
5123
4917
  for (const file of files) {
5124
4918
  if (!file.endsWith(".md") || file.includes("-spec.md")) continue;
5125
- const filePath = path7__namespace.join(changesDir, file);
5126
- const content = await fs7__namespace.readFile(filePath, "utf-8");
4919
+ const filePath = path5__namespace.join(changesDir, file);
4920
+ const content = await fs5__namespace.readFile(filePath, "utf-8");
5127
4921
  const state = this.parseChangeRecord(content);
5128
4922
  if (state && state.status === "running") {
5129
4923
  workflows.push(state);
@@ -5172,9 +4966,9 @@ var WorkflowEngine = class {
5172
4966
  if (this.state) {
5173
4967
  await this.saveState();
5174
4968
  }
5175
- const statePath = path7__namespace.join(this.openspecPath, ".workflow-states", `${changeId}.json`);
4969
+ const statePath = path5__namespace.join(this.openspecPath, ".workflow-states", `${changeId}.json`);
5176
4970
  try {
5177
- const content = await fs7__namespace.readFile(statePath, "utf-8");
4971
+ const content = await fs5__namespace.readFile(statePath, "utf-8");
5178
4972
  this.state = JSON.parse(content, (key, value) => {
5179
4973
  if (key.endsWith("At") && typeof value === "string") {
5180
4974
  return new Date(value);
@@ -5184,10 +4978,10 @@ var WorkflowEngine = class {
5184
4978
  await this.restoreSnapshots();
5185
4979
  return true;
5186
4980
  } catch {
5187
- const changesDir = path7__namespace.join(this.openspecPath, "changes");
5188
- const changeFile = path7__namespace.join(changesDir, `${changeId}.md`);
4981
+ const changesDir = path5__namespace.join(this.openspecPath, "changes");
4982
+ const changeFile = path5__namespace.join(changesDir, `${changeId}.md`);
5189
4983
  try {
5190
- const content = await fs7__namespace.readFile(changeFile, "utf-8");
4984
+ const content = await fs5__namespace.readFile(changeFile, "utf-8");
5191
4985
  const parsed = this.parseChangeRecord(content);
5192
4986
  if (parsed && parsed.status === "running") {
5193
4987
  this.state = parsed;
@@ -5248,12 +5042,12 @@ var WorkflowEngine = class {
5248
5042
  await this.createSpecDocument(summary);
5249
5043
  await this.updateChangeRecord("archived");
5250
5044
  await this.saveState();
5251
- const changesDir = path7__namespace.join(this.openspecPath, "changes");
5252
- const archiveDir = path7__namespace.join(changesDir, "archive");
5253
- const changeFile = path7__namespace.join(changesDir, `${changeId}.md`);
5254
- const archiveFile = path7__namespace.join(archiveDir, `${changeId}.md`);
5255
- await fs7__namespace.mkdir(archiveDir, { recursive: true });
5256
- await fs7__namespace.rename(changeFile, archiveFile).catch(() => {
5045
+ const changesDir = path5__namespace.join(this.openspecPath, "changes");
5046
+ const archiveDir = path5__namespace.join(changesDir, "archive");
5047
+ const changeFile = path5__namespace.join(changesDir, `${changeId}.md`);
5048
+ const archiveFile = path5__namespace.join(archiveDir, `${changeId}.md`);
5049
+ await fs5__namespace.mkdir(archiveDir, { recursive: true });
5050
+ await fs5__namespace.rename(changeFile, archiveFile).catch(() => {
5257
5051
  });
5258
5052
  this.state = null;
5259
5053
  this.snapshots.clear();
@@ -5275,27 +5069,27 @@ var WorkflowEngine = class {
5275
5069
  }
5276
5070
  // ==================== 私有方法 ====================
5277
5071
  async ensureDirectories() {
5278
- const changesDir = path7__namespace.join(this.openspecPath, "changes");
5279
- const archiveDir = path7__namespace.join(changesDir, "archive");
5280
- const specDir = path7__namespace.join(this.openspecPath, "spec");
5281
- const statesDir = path7__namespace.join(this.openspecPath, ".workflow-states");
5282
- await fs7__namespace.mkdir(archiveDir, { recursive: true });
5283
- await fs7__namespace.mkdir(specDir, { recursive: true });
5284
- await fs7__namespace.mkdir(statesDir, { recursive: true });
5072
+ const changesDir = path5__namespace.join(this.openspecPath, "changes");
5073
+ const archiveDir = path5__namespace.join(changesDir, "archive");
5074
+ const specDir = path5__namespace.join(this.openspecPath, "spec");
5075
+ const statesDir = path5__namespace.join(this.openspecPath, ".workflow-states");
5076
+ await fs5__namespace.mkdir(archiveDir, { recursive: true });
5077
+ await fs5__namespace.mkdir(specDir, { recursive: true });
5078
+ await fs5__namespace.mkdir(statesDir, { recursive: true });
5285
5079
  }
5286
5080
  async restoreState() {
5287
- const activePath = path7__namespace.join(this.openspecPath, ".workflow-active.json");
5081
+ const activePath = path5__namespace.join(this.openspecPath, ".workflow-active.json");
5288
5082
  let activeId = null;
5289
5083
  try {
5290
- const activeContent = await fs7__namespace.readFile(activePath, "utf-8");
5084
+ const activeContent = await fs5__namespace.readFile(activePath, "utf-8");
5291
5085
  const activeData = JSON.parse(activeContent);
5292
5086
  activeId = activeData.activeId;
5293
5087
  } catch {
5294
5088
  }
5295
5089
  if (activeId) {
5296
- const statePath = path7__namespace.join(this.openspecPath, ".workflow-states", `${activeId}.json`);
5090
+ const statePath = path5__namespace.join(this.openspecPath, ".workflow-states", `${activeId}.json`);
5297
5091
  try {
5298
- const content = await fs7__namespace.readFile(statePath, "utf-8");
5092
+ const content = await fs5__namespace.readFile(statePath, "utf-8");
5299
5093
  this.state = JSON.parse(content, (key, value) => {
5300
5094
  if (key.endsWith("At") && typeof value === "string") {
5301
5095
  return new Date(value);
@@ -5306,9 +5100,9 @@ var WorkflowEngine = class {
5306
5100
  } catch {
5307
5101
  }
5308
5102
  }
5309
- const oldStatePath = path7__namespace.join(this.openspecPath, ".workflow-state.json");
5103
+ const oldStatePath = path5__namespace.join(this.openspecPath, ".workflow-state.json");
5310
5104
  try {
5311
- const content = await fs7__namespace.readFile(oldStatePath, "utf-8");
5105
+ const content = await fs5__namespace.readFile(oldStatePath, "utf-8");
5312
5106
  this.state = JSON.parse(content, (key, value) => {
5313
5107
  if (key.endsWith("At") && typeof value === "string") {
5314
5108
  return new Date(value);
@@ -5317,7 +5111,7 @@ var WorkflowEngine = class {
5317
5111
  });
5318
5112
  if (this.state) {
5319
5113
  await this.saveState();
5320
- await fs7__namespace.unlink(oldStatePath).catch(() => {
5114
+ await fs5__namespace.unlink(oldStatePath).catch(() => {
5321
5115
  });
5322
5116
  }
5323
5117
  } catch (e) {
@@ -5330,17 +5124,17 @@ var WorkflowEngine = class {
5330
5124
  }
5331
5125
  async saveState() {
5332
5126
  if (!this.state) return;
5333
- const statesDir = path7__namespace.join(this.openspecPath, ".workflow-states");
5334
- await fs7__namespace.mkdir(statesDir, { recursive: true });
5335
- const statePath = path7__namespace.join(statesDir, `${this.state.id}.json`);
5336
- await fs7__namespace.writeFile(statePath, JSON.stringify(this.state, null, 2));
5337
- const activePath = path7__namespace.join(this.openspecPath, ".workflow-active.json");
5338
- await fs7__namespace.writeFile(activePath, JSON.stringify({ activeId: this.state.id }, null, 2));
5127
+ const statesDir = path5__namespace.join(this.openspecPath, ".workflow-states");
5128
+ await fs5__namespace.mkdir(statesDir, { recursive: true });
5129
+ const statePath = path5__namespace.join(statesDir, `${this.state.id}.json`);
5130
+ await fs5__namespace.writeFile(statePath, JSON.stringify(this.state, null, 2));
5131
+ const activePath = path5__namespace.join(this.openspecPath, ".workflow-active.json");
5132
+ await fs5__namespace.writeFile(activePath, JSON.stringify({ activeId: this.state.id }, null, 2));
5339
5133
  }
5340
5134
  async restoreSnapshots() {
5341
- const snapshotsPath = path7__namespace.join(this.openspecPath, ".workflow-snapshots.json");
5135
+ const snapshotsPath = path5__namespace.join(this.openspecPath, ".workflow-snapshots.json");
5342
5136
  try {
5343
- const content = await fs7__namespace.readFile(snapshotsPath, "utf-8");
5137
+ const content = await fs5__namespace.readFile(snapshotsPath, "utf-8");
5344
5138
  const data = JSON.parse(content, (key, value) => {
5345
5139
  if (key === "timestamp" && typeof value === "string") {
5346
5140
  return new Date(value);
@@ -5355,9 +5149,9 @@ var WorkflowEngine = class {
5355
5149
  }
5356
5150
  }
5357
5151
  async saveSnapshots() {
5358
- const snapshotsPath = path7__namespace.join(this.openspecPath, ".workflow-snapshots.json");
5152
+ const snapshotsPath = path5__namespace.join(this.openspecPath, ".workflow-snapshots.json");
5359
5153
  const data = Array.from(this.snapshots.values());
5360
- await fs7__namespace.writeFile(snapshotsPath, JSON.stringify(data, null, 2));
5154
+ await fs5__namespace.writeFile(snapshotsPath, JSON.stringify(data, null, 2));
5361
5155
  }
5362
5156
  async createSnapshot() {
5363
5157
  if (!this.state) return;
@@ -5377,16 +5171,16 @@ var WorkflowEngine = class {
5377
5171
  }
5378
5172
  async createChangeRecord() {
5379
5173
  if (!this.state) return;
5380
- const changePath = path7__namespace.join(this.openspecPath, "changes", `${this.state.id}.md`);
5381
- await fs7__namespace.writeFile(changePath, this.formatChangeRecord());
5174
+ const changePath = path5__namespace.join(this.openspecPath, "changes", `${this.state.id}.md`);
5175
+ await fs5__namespace.writeFile(changePath, this.formatChangeRecord());
5382
5176
  }
5383
5177
  async updateChangeRecord(status) {
5384
5178
  if (!this.state) return;
5385
5179
  if (status) {
5386
5180
  this.state.status = status;
5387
5181
  }
5388
- const changePath = path7__namespace.join(this.openspecPath, "changes", `${this.state.id}.md`);
5389
- await fs7__namespace.writeFile(changePath, this.formatChangeRecord());
5182
+ const changePath = path5__namespace.join(this.openspecPath, "changes", `${this.state.id}.md`);
5183
+ await fs5__namespace.writeFile(changePath, this.formatChangeRecord());
5390
5184
  }
5391
5185
  formatChangeRecord() {
5392
5186
  if (!this.state) return "";
@@ -5425,7 +5219,7 @@ ${this.state.artifacts.map((a) => `- ${a}`).join("\n") || "\u6682\u65E0"}
5425
5219
  }
5426
5220
  async createSpecDocument(summary) {
5427
5221
  if (!this.state) return;
5428
- const specPath = path7__namespace.join(this.openspecPath, "spec", `${this.state.id}.md`);
5222
+ const specPath = path5__namespace.join(this.openspecPath, "spec", `${this.state.id}.md`);
5429
5223
  const content = `# Spec: ${this.state.title}
5430
5224
 
5431
5225
  > \u53D8\u66F4ID: ${this.state.id}
@@ -5450,7 +5244,7 @@ ${this.state.steps.map((s) => `- [${s.status === "completed" ? "x" : " "}] ${s.s
5450
5244
 
5451
5245
  ${this.state.artifacts.map((a) => `- ${a}`).join("\n") || "\u6682\u65E0"}
5452
5246
  `;
5453
- await fs7__namespace.writeFile(specPath, content);
5247
+ await fs5__namespace.writeFile(specPath, content);
5454
5248
  }
5455
5249
  };
5456
5250
  var ConfirmationRequiredError = class extends Error {
@@ -5947,15 +5741,15 @@ async function loadProjectContext(workingDirectory) {
5947
5741
  devStandards: ""
5948
5742
  };
5949
5743
  try {
5950
- context.agentsMd = await fs7__namespace.readFile(path7__namespace.join(workingDirectory, "AGENTS.md"), "utf-8");
5744
+ context.agentsMd = await fs5__namespace.readFile(path5__namespace.join(workingDirectory, "AGENTS.md"), "utf-8");
5951
5745
  } catch {
5952
5746
  }
5953
5747
  try {
5954
- context.configYaml = await fs7__namespace.readFile(path7__namespace.join(workingDirectory, "openspec", "config.yaml"), "utf-8");
5748
+ context.configYaml = await fs5__namespace.readFile(path5__namespace.join(workingDirectory, "openspec", "config.yaml"), "utf-8");
5955
5749
  } catch {
5956
5750
  }
5957
5751
  try {
5958
- context.devStandards = await fs7__namespace.readFile(path7__namespace.join(workingDirectory, ".sf-cli", "norms", "devstanded.md"), "utf-8");
5752
+ context.devStandards = await fs5__namespace.readFile(path5__namespace.join(workingDirectory, ".sf-cli", "norms", "devstanded.md"), "utf-8");
5959
5753
  } catch {
5960
5754
  }
5961
5755
  return context;
@@ -6422,11 +6216,11 @@ ${generateConfirmationPrompt(confirmation.point)}`) + chalk9__default.default.cy
6422
6216
  }
6423
6217
  async function updateChangelog(workingDirectory, summary, changeId) {
6424
6218
  try {
6425
- const changelogPath = path7__namespace.join(workingDirectory, "CHANGELOG.md");
6426
- const pkgPath = path7__namespace.join(workingDirectory, "package.json");
6219
+ const changelogPath = path5__namespace.join(workingDirectory, "CHANGELOG.md");
6220
+ const pkgPath = path5__namespace.join(workingDirectory, "package.json");
6427
6221
  let version = "1.0.0";
6428
6222
  try {
6429
- const pkgContent = fs9__namespace.readFileSync(pkgPath, "utf-8");
6223
+ const pkgContent = fs7__namespace.readFileSync(pkgPath, "utf-8");
6430
6224
  const pkg = JSON.parse(pkgContent);
6431
6225
  version = pkg.version || "1.0.0";
6432
6226
  } catch {
@@ -6440,22 +6234,22 @@ async function updateChangelog(workingDirectory, summary, changeId) {
6440
6234
 
6441
6235
  - ${summary} (${changeId})
6442
6236
  `;
6443
- if (fs9__namespace.existsSync(changelogPath)) {
6444
- const content = fs9__namespace.readFileSync(changelogPath, "utf-8");
6237
+ if (fs7__namespace.existsSync(changelogPath)) {
6238
+ const content = fs7__namespace.readFileSync(changelogPath, "utf-8");
6445
6239
  const versionPattern = /^## v\d+\.\d+\.\d+/m;
6446
6240
  const match = content.match(versionPattern);
6447
6241
  if (match && match.index !== void 0) {
6448
6242
  const newContent = content.slice(0, match.index) + entry + content.slice(match.index);
6449
- fs9__namespace.writeFileSync(changelogPath, newContent, "utf-8");
6243
+ fs7__namespace.writeFileSync(changelogPath, newContent, "utf-8");
6450
6244
  } else {
6451
- fs9__namespace.appendFileSync(changelogPath, entry, "utf-8");
6245
+ fs7__namespace.appendFileSync(changelogPath, entry, "utf-8");
6452
6246
  }
6453
6247
  } else {
6454
6248
  const header = `# Changelog
6455
6249
 
6456
6250
  All notable changes to this project will be documented in this file.
6457
6251
  `;
6458
- fs9__namespace.writeFileSync(changelogPath, header + entry, "utf-8");
6252
+ fs7__namespace.writeFileSync(changelogPath, header + entry, "utf-8");
6459
6253
  }
6460
6254
  } catch (error) {
6461
6255
  }
@@ -6585,7 +6379,7 @@ async function handleRegenerateSpec(workflow, ctx) {
6585
6379
  return { output: chalk9__default.default.red("\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") };
6586
6380
  }
6587
6381
  const workingDir = ctx.options.workingDirectory;
6588
- const specPath = path7__namespace.join(workingDir, "openspec", "changes", `${state.id}-spec.md`);
6382
+ const specPath = path5__namespace.join(workingDir, "openspec", "changes", `${state.id}-spec.md`);
6589
6383
  workflow.confirm("spec-review", "regenerate");
6590
6384
  const lines = [];
6591
6385
  lines.push(chalk9__default.default.cyan("\u{1F504} \u91CD\u65B0\u751F\u6210\u89C4\u683C..."));
@@ -6594,7 +6388,7 @@ async function handleRegenerateSpec(workflow, ctx) {
6594
6388
  const context = await readProjectContext2(workingDir);
6595
6389
  const analysis = analyzeComplexity2(state.requirement, context);
6596
6390
  const specContent = await generateSpecContent(state.id, state.requirement, analysis, context);
6597
- await fs9__namespace.promises.writeFile(specPath, specContent, "utf-8");
6391
+ await fs7__namespace.promises.writeFile(specPath, specContent, "utf-8");
6598
6392
  lines.push(chalk9__default.default.green("\u2713 \u89C4\u683C\u5DF2\u91CD\u65B0\u751F\u6210"));
6599
6393
  lines.push(chalk9__default.default.gray(`\u8DEF\u5F84: ${specPath}`));
6600
6394
  lines.push("");
@@ -6688,9 +6482,9 @@ ${generateConfirmationPrompt(e.point)}`) + chalk9__default.default.cyan(`
6688
6482
  return { output: lines.join("\n") };
6689
6483
  }
6690
6484
  async function checkPendingSpec(workingDirectory, changeId) {
6691
- const specPath = path7__namespace.join(workingDirectory, "openspec", "changes", `${changeId}-spec.md`);
6485
+ const specPath = path5__namespace.join(workingDirectory, "openspec", "changes", `${changeId}-spec.md`);
6692
6486
  try {
6693
- await fs9__namespace.promises.access(specPath);
6487
+ await fs7__namespace.promises.access(specPath);
6694
6488
  return specPath;
6695
6489
  } catch {
6696
6490
  return null;
@@ -6804,13 +6598,13 @@ async function handleSwitch(workflow, args, ctx) {
6804
6598
  // src/commands/runner.ts
6805
6599
  function getVersion2() {
6806
6600
  const possiblePaths = [
6807
- path7__namespace.resolve(__dirname, "..", "..", "package.json"),
6808
- path7__namespace.resolve(__dirname, "..", "..", "..", "package.json")
6601
+ path5__namespace.resolve(__dirname, "..", "..", "package.json"),
6602
+ path5__namespace.resolve(__dirname, "..", "..", "..", "package.json")
6809
6603
  ];
6810
6604
  for (const pkgPath of possiblePaths) {
6811
6605
  try {
6812
- if (fs9__namespace.existsSync(pkgPath)) {
6813
- const content = fs9__namespace.readFileSync(pkgPath, "utf-8");
6606
+ if (fs7__namespace.existsSync(pkgPath)) {
6607
+ const content = fs7__namespace.readFileSync(pkgPath, "utf-8");
6814
6608
  const pkg = JSON.parse(content);
6815
6609
  return pkg.version;
6816
6610
  }
@@ -6867,7 +6661,7 @@ function normalizeCommand(command) {
6867
6661
  }
6868
6662
 
6869
6663
  // src/commands/index.ts
6870
- init_model3();
6664
+ init_model2();
6871
6665
  init_update();
6872
6666
  init_new();
6873
6667
 
@@ -6875,11 +6669,11 @@ init_new();
6875
6669
  init_cjs_shims();
6876
6670
  async function handleFileReference(filePath, ctx) {
6877
6671
  const cwd = ctx.options.workingDirectory;
6878
- const absolutePath = path7__namespace.isAbsolute(filePath) ? filePath : path7__namespace.join(cwd, filePath);
6672
+ const absolutePath = path5__namespace.isAbsolute(filePath) ? filePath : path5__namespace.join(cwd, filePath);
6879
6673
  try {
6880
- const stats = await fs7__namespace.stat(absolutePath);
6674
+ const stats = await fs5__namespace.stat(absolutePath);
6881
6675
  if (stats.isDirectory()) {
6882
- const files = await fs7__namespace.readdir(absolutePath);
6676
+ const files = await fs5__namespace.readdir(absolutePath);
6883
6677
  return {
6884
6678
  output: chalk9__default.default.cyan(`\u{1F4C1} ${filePath}/`) + chalk9__default.default.gray(`
6885
6679
  ${files.slice(0, 20).join("\n")}`) + (files.length > 20 ? chalk9__default.default.gray(`
@@ -6887,7 +6681,7 @@ ${files.slice(0, 20).join("\n")}`) + (files.length > 20 ? chalk9__default.defaul
6887
6681
  contextUsed: 0
6888
6682
  };
6889
6683
  }
6890
- const content = await fs7__namespace.readFile(absolutePath, "utf-8");
6684
+ const content = await fs5__namespace.readFile(absolutePath, "utf-8");
6891
6685
  const lines = content.split("\n");
6892
6686
  ctx.contextManager.addMessage({
6893
6687
  role: "user",
@@ -7197,7 +6991,7 @@ var ContextManager = class {
7197
6991
  }
7198
6992
  async initialize(projectPath) {
7199
6993
  this.projectPath = projectPath;
7200
- this.persistPath = path7__namespace.join(projectPath, ".sf-cli", "cache", "context", "context.json");
6994
+ this.persistPath = path5__namespace.join(projectPath, ".sf-cli", "cache", "context", "context.json");
7201
6995
  await this.loadPersistedContext();
7202
6996
  }
7203
6997
  /**
@@ -7438,15 +7232,15 @@ ${summary}`,
7438
7232
  */
7439
7233
  async persist() {
7440
7234
  if (!this.persistPath) return;
7441
- const dir = path7__namespace.dirname(this.persistPath);
7442
- await fs7__namespace.mkdir(dir, { recursive: true });
7235
+ const dir = path5__namespace.dirname(this.persistPath);
7236
+ await fs5__namespace.mkdir(dir, { recursive: true });
7443
7237
  const data = {
7444
7238
  messages: this.state.messages,
7445
7239
  totalTokens: this.state.totalTokens,
7446
7240
  limit: this.state.limit,
7447
7241
  savedAt: (/* @__PURE__ */ new Date()).toISOString()
7448
7242
  };
7449
- await fs7__namespace.writeFile(this.persistPath, JSON.stringify(data, null, 2), "utf-8");
7243
+ await fs5__namespace.writeFile(this.persistPath, JSON.stringify(data, null, 2), "utf-8");
7450
7244
  }
7451
7245
  /**
7452
7246
  * 加载持久化的上下文
@@ -7454,7 +7248,7 @@ ${summary}`,
7454
7248
  async loadPersistedContext() {
7455
7249
  if (!this.persistPath) return;
7456
7250
  try {
7457
- const content = await fs7__namespace.readFile(this.persistPath, "utf-8");
7251
+ const content = await fs5__namespace.readFile(this.persistPath, "utf-8");
7458
7252
  const data = JSON.parse(content);
7459
7253
  this.state.messages = data.messages || [];
7460
7254
  this.state.totalTokens = data.totalTokens || 0;
@@ -7483,8 +7277,400 @@ ${summary}`,
7483
7277
  }
7484
7278
  };
7485
7279
 
7486
- // src/cli/repl.ts
7487
- init_services();
7280
+ // src/services/index.ts
7281
+ init_cjs_shims();
7282
+
7283
+ // src/services/config.ts
7284
+ init_cjs_shims();
7285
+ var DEFAULT_CONFIG = {
7286
+ model: "GLM-5",
7287
+ apiKey: "",
7288
+ yolo: false,
7289
+ locale: "zh-CN",
7290
+ theme: "auto"
7291
+ };
7292
+ var ALGORITHM = "aes-256-gcm";
7293
+ var IV_LENGTH = 16;
7294
+ var KEY_DIR = ".sf-cli";
7295
+ var KEY_FILE = ".key";
7296
+ function getOrCreateEncryptionKey() {
7297
+ const keyPath = path5__namespace.join(os__namespace.homedir(), KEY_DIR, KEY_FILE);
7298
+ try {
7299
+ if (fs7__namespace.existsSync(keyPath)) {
7300
+ const keyBase64 = fs7__namespace.readFileSync(keyPath, "utf-8").trim();
7301
+ return Buffer.from(keyBase64, "base64");
7302
+ }
7303
+ } catch {
7304
+ }
7305
+ const key = crypto__namespace.randomBytes(32);
7306
+ try {
7307
+ const keyDir = path5__namespace.dirname(keyPath);
7308
+ if (!fs7__namespace.existsSync(keyDir)) {
7309
+ fs7__namespace.mkdirSync(keyDir, { recursive: true, mode: 448 });
7310
+ }
7311
+ fs7__namespace.writeFileSync(keyPath, key.toString("base64"), {
7312
+ mode: 384,
7313
+ // 仅所有者可读写
7314
+ encoding: "utf-8"
7315
+ });
7316
+ return key;
7317
+ } catch {
7318
+ const machineId = [
7319
+ os__namespace.hostname(),
7320
+ os__namespace.platform(),
7321
+ os__namespace.arch(),
7322
+ process.env.USERNAME || process.env.USER || "default"
7323
+ ].join("-");
7324
+ return crypto__namespace.createHash("sha256").update(machineId).digest();
7325
+ }
7326
+ }
7327
+ var ConfigManager = class {
7328
+ config;
7329
+ configPath = "";
7330
+ projectPath = "";
7331
+ encryptionKey;
7332
+ constructor() {
7333
+ this.config = { ...DEFAULT_CONFIG };
7334
+ this.encryptionKey = getOrCreateEncryptionKey();
7335
+ }
7336
+ async load(projectPath) {
7337
+ this.projectPath = projectPath;
7338
+ this.configPath = path5__namespace.join(projectPath, ".sf-cli", "config.json");
7339
+ try {
7340
+ const content = await fs5__namespace.readFile(this.configPath, "utf-8");
7341
+ const loaded = JSON.parse(content);
7342
+ if (loaded.apiKey && loaded.apiKeyEncrypted) {
7343
+ loaded.apiKey = this.decrypt(loaded.apiKey);
7344
+ delete loaded.apiKeyEncrypted;
7345
+ }
7346
+ this.config = { ...DEFAULT_CONFIG, ...loaded };
7347
+ } catch {
7348
+ this.config = { ...DEFAULT_CONFIG };
7349
+ }
7350
+ }
7351
+ async save() {
7352
+ if (!this.configPath) return;
7353
+ const configToSave = { ...this.config };
7354
+ if (configToSave.apiKey) {
7355
+ const encrypted = this.encrypt(configToSave.apiKey);
7356
+ configToSave.apiKey = encrypted;
7357
+ configToSave.apiKeyEncrypted = true;
7358
+ }
7359
+ await fs5__namespace.mkdir(path5__namespace.dirname(this.configPath), { recursive: true });
7360
+ await fs5__namespace.writeFile(
7361
+ this.configPath,
7362
+ JSON.stringify(configToSave, null, 2),
7363
+ "utf-8"
7364
+ );
7365
+ }
7366
+ get(key) {
7367
+ return this.config[key];
7368
+ }
7369
+ set(key, value) {
7370
+ this.config[key] = value;
7371
+ }
7372
+ getAll() {
7373
+ return { ...this.config };
7374
+ }
7375
+ update(updates) {
7376
+ this.config = { ...this.config, ...updates };
7377
+ }
7378
+ /**
7379
+ * 加密敏感数据
7380
+ */
7381
+ encrypt(text) {
7382
+ const iv = crypto__namespace.randomBytes(IV_LENGTH);
7383
+ const cipher = crypto__namespace.createCipheriv(ALGORITHM, this.encryptionKey, iv);
7384
+ let encrypted = cipher.update(text, "utf8", "base64");
7385
+ encrypted += cipher.final("base64");
7386
+ const authTag = cipher.getAuthTag();
7387
+ return `${iv.toString("base64")}:${authTag.toString("base64")}:${encrypted}`;
7388
+ }
7389
+ /**
7390
+ * 解密敏感数据
7391
+ */
7392
+ decrypt(encryptedData) {
7393
+ try {
7394
+ const parts = encryptedData.split(":");
7395
+ if (parts.length !== 3) {
7396
+ return encryptedData;
7397
+ }
7398
+ const [ivBase64, authTagBase64, encrypted] = parts;
7399
+ const iv = Buffer.from(ivBase64, "base64");
7400
+ const authTag = Buffer.from(authTagBase64, "base64");
7401
+ const decipher = crypto__namespace.createDecipheriv(ALGORITHM, this.encryptionKey, iv);
7402
+ decipher.setAuthTag(authTag);
7403
+ let decrypted = decipher.update(encrypted, "base64", "utf8");
7404
+ decrypted += decipher.final("utf8");
7405
+ return decrypted;
7406
+ } catch {
7407
+ return "";
7408
+ }
7409
+ }
7410
+ };
7411
+
7412
+ // src/services/model.ts
7413
+ init_cjs_shims();
7414
+ init_model();
7415
+ init_adapters();
7416
+ var ModelService = class {
7417
+ adapters = /* @__PURE__ */ new Map();
7418
+ currentConfig = null;
7419
+ stats;
7420
+ configManager;
7421
+ statsPath = "";
7422
+ constructor(configManager) {
7423
+ this.configManager = configManager;
7424
+ this.stats = {
7425
+ totalInput: 0,
7426
+ totalOutput: 0,
7427
+ byModel: {},
7428
+ byAgent: {},
7429
+ byDate: {}
7430
+ };
7431
+ }
7432
+ /**
7433
+ * 初始化服务
7434
+ */
7435
+ async initialize(statsDir) {
7436
+ this.statsPath = path5__namespace.join(statsDir, "tokens");
7437
+ await this.loadStats();
7438
+ const model = this.configManager.get("model");
7439
+ const apiKey = this.configManager.get("apiKey");
7440
+ if (model && apiKey) {
7441
+ await this.configureModel({
7442
+ provider: this.getProviderFromModel(model),
7443
+ model,
7444
+ apiKey
7445
+ });
7446
+ }
7447
+ }
7448
+ /**
7449
+ * 配置模型
7450
+ */
7451
+ async configureModel(config) {
7452
+ let adapter = this.adapters.get(config.provider);
7453
+ if (!adapter) {
7454
+ adapter = createAdapter(config.provider);
7455
+ this.adapters.set(config.provider, adapter);
7456
+ }
7457
+ await adapter.initialize(config);
7458
+ this.currentConfig = config;
7459
+ this.configManager.set("model", config.model);
7460
+ this.configManager.set("apiKey", config.apiKey);
7461
+ await this.configManager.save();
7462
+ }
7463
+ /**
7464
+ * 发送消息
7465
+ */
7466
+ async sendMessage(messages, options) {
7467
+ if (!this.currentConfig) {
7468
+ throw new Error("\u6A21\u578B\u672A\u914D\u7F6E\uFF0C\u8BF7\u5148\u6267\u884C /model \u547D\u4EE4");
7469
+ }
7470
+ const adapter = this.adapters.get(this.currentConfig.provider);
7471
+ if (!adapter || !adapter.isInitialized()) {
7472
+ throw new Error("\u6A21\u578B\u9002\u914D\u5668\u672A\u521D\u59CB\u5316");
7473
+ }
7474
+ try {
7475
+ const response = await adapter.sendMessage(messages, options);
7476
+ this.updateStats(response.usage, {
7477
+ model: this.currentConfig.model,
7478
+ agent: options?.agent
7479
+ });
7480
+ this.saveStats().catch(() => {
7481
+ });
7482
+ return response;
7483
+ } catch (error) {
7484
+ throw this.wrapError(error);
7485
+ }
7486
+ }
7487
+ /**
7488
+ * 流式发送消息
7489
+ */
7490
+ async *streamMessage(messages, options) {
7491
+ if (!this.currentConfig) {
7492
+ throw new Error("\u6A21\u578B\u672A\u914D\u7F6E\uFF0C\u8BF7\u5148\u6267\u884C /model \u547D\u4EE4");
7493
+ }
7494
+ const adapter = this.adapters.get(this.currentConfig.provider);
7495
+ if (!adapter || !adapter.isInitialized()) {
7496
+ throw new Error("\u6A21\u578B\u9002\u914D\u5668\u672A\u521D\u59CB\u5316");
7497
+ }
7498
+ let totalTokens = 0;
7499
+ try {
7500
+ for await (const chunk of adapter.streamMessage(messages, options)) {
7501
+ totalTokens += chunk.delta.length;
7502
+ yield chunk;
7503
+ }
7504
+ const inputTokens = adapter.countTokens(
7505
+ messages.map((m) => m.content).join("\n")
7506
+ );
7507
+ this.updateStats(
7508
+ { inputTokens, outputTokens: Math.ceil(totalTokens / 4), totalTokens: 0 },
7509
+ { model: this.currentConfig.model, agent: options?.agent }
7510
+ );
7511
+ this.saveStats().catch(() => {
7512
+ });
7513
+ } catch (error) {
7514
+ throw this.wrapError(error);
7515
+ }
7516
+ }
7517
+ /**
7518
+ * 计算Token数量
7519
+ */
7520
+ countTokens(text) {
7521
+ if (!this.currentConfig) {
7522
+ return Math.ceil(text.length / 4);
7523
+ }
7524
+ const adapter = this.adapters.get(this.currentConfig.provider);
7525
+ return adapter?.countTokens(text) || Math.ceil(text.length / 4);
7526
+ }
7527
+ /**
7528
+ * 获取当前模型
7529
+ */
7530
+ getCurrentModel() {
7531
+ return this.currentConfig?.model || null;
7532
+ }
7533
+ /**
7534
+ * 获取当前提供商
7535
+ */
7536
+ getCurrentProvider() {
7537
+ return this.currentConfig?.provider || null;
7538
+ }
7539
+ /**
7540
+ * 获取Token统计
7541
+ */
7542
+ getStats() {
7543
+ return { ...this.stats };
7544
+ }
7545
+ /**
7546
+ * 获取今日统计
7547
+ */
7548
+ getTodayStats() {
7549
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
7550
+ return this.stats.byDate[today] || { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
7551
+ }
7552
+ /**
7553
+ * 重置统计
7554
+ */
7555
+ resetStats() {
7556
+ this.stats = {
7557
+ totalInput: 0,
7558
+ totalOutput: 0,
7559
+ byModel: {},
7560
+ byAgent: {},
7561
+ byDate: {}
7562
+ };
7563
+ this.saveStats().catch(() => {
7564
+ });
7565
+ }
7566
+ /**
7567
+ * 验证API Key
7568
+ */
7569
+ async validateApiKey(provider, apiKey) {
7570
+ let adapter = this.adapters.get(provider);
7571
+ if (!adapter) {
7572
+ adapter = createAdapter(provider);
7573
+ }
7574
+ return adapter.validateApiKey(apiKey);
7575
+ }
7576
+ // ==================== 私有方法 ====================
7577
+ getProviderFromModel(modelId) {
7578
+ const info = getModelInfo(modelId);
7579
+ return info?.provider || "openai";
7580
+ }
7581
+ updateStats(usage, context) {
7582
+ this.stats.totalInput += usage.inputTokens;
7583
+ this.stats.totalOutput += usage.outputTokens;
7584
+ if (!this.stats.byModel[context.model]) {
7585
+ this.stats.byModel[context.model] = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
7586
+ }
7587
+ this.stats.byModel[context.model].inputTokens += usage.inputTokens;
7588
+ this.stats.byModel[context.model].outputTokens += usage.outputTokens;
7589
+ this.stats.byModel[context.model].totalTokens += usage.totalTokens;
7590
+ if (context.agent) {
7591
+ if (!this.stats.byAgent[context.agent]) {
7592
+ this.stats.byAgent[context.agent] = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
7593
+ }
7594
+ this.stats.byAgent[context.agent].inputTokens += usage.inputTokens;
7595
+ this.stats.byAgent[context.agent].outputTokens += usage.outputTokens;
7596
+ this.stats.byAgent[context.agent].totalTokens += usage.totalTokens;
7597
+ }
7598
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
7599
+ if (!this.stats.byDate[today]) {
7600
+ this.stats.byDate[today] = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
7601
+ }
7602
+ this.stats.byDate[today].inputTokens += usage.inputTokens;
7603
+ this.stats.byDate[today].outputTokens += usage.outputTokens;
7604
+ this.stats.byDate[today].totalTokens += usage.totalTokens;
7605
+ }
7606
+ async loadStats() {
7607
+ if (!this.statsPath) return;
7608
+ try {
7609
+ const dailyPath = path5__namespace.join(this.statsPath, "daily.json");
7610
+ const totalPath = path5__namespace.join(this.statsPath, "total.json");
7611
+ const [daily, total] = await Promise.all([
7612
+ fs5__namespace.readFile(dailyPath, "utf-8").catch(() => "{}"),
7613
+ fs5__namespace.readFile(totalPath, "utf-8").catch(() => '{"totalInput":0,"totalOutput":0}')
7614
+ ]);
7615
+ const dailyData = JSON.parse(daily);
7616
+ const totalData = JSON.parse(total);
7617
+ this.stats.byDate = dailyData;
7618
+ this.stats.totalInput = totalData.totalInput || 0;
7619
+ this.stats.totalOutput = totalData.totalOutput || 0;
7620
+ } catch {
7621
+ }
7622
+ }
7623
+ async saveStats() {
7624
+ if (!this.statsPath) return;
7625
+ try {
7626
+ await fs5__namespace.mkdir(this.statsPath, { recursive: true });
7627
+ const dailyPath = path5__namespace.join(this.statsPath, "daily.json");
7628
+ const totalPath = path5__namespace.join(this.statsPath, "total.json");
7629
+ await Promise.all([
7630
+ fs5__namespace.writeFile(dailyPath, JSON.stringify(this.stats.byDate, null, 2)),
7631
+ fs5__namespace.writeFile(totalPath, JSON.stringify({
7632
+ totalInput: this.stats.totalInput,
7633
+ totalOutput: this.stats.totalOutput
7634
+ }))
7635
+ ]);
7636
+ } catch {
7637
+ }
7638
+ }
7639
+ wrapError(error) {
7640
+ if (error instanceof ModelError) {
7641
+ return error;
7642
+ }
7643
+ const err = error;
7644
+ if (err.message.includes("timeout")) {
7645
+ return new ModelError("TIMEOUT", err.message, { retryable: true });
7646
+ }
7647
+ if (err.message.includes("network") || err.message.includes("ECONNREFUSED")) {
7648
+ return new ModelError("NETWORK_ERROR", err.message, { retryable: true });
7649
+ }
7650
+ return new ModelError("UNKNOWN_ERROR", err.message, { retryable: false });
7651
+ }
7652
+ };
7653
+
7654
+ // src/services/index.ts
7655
+ init_adapters();
7656
+
7657
+ // src/services/mcp/index.ts
7658
+ init_cjs_shims();
7659
+
7660
+ // src/types/mcp.ts
7661
+ init_cjs_shims();
7662
+
7663
+ // src/services/mcp/base.ts
7664
+ init_cjs_shims();
7665
+
7666
+ // src/services/mcp/lanhu.ts
7667
+ init_cjs_shims();
7668
+
7669
+ // src/services/mcp/figma.ts
7670
+ init_cjs_shims();
7671
+
7672
+ // src/services/mcp/manager.ts
7673
+ init_cjs_shims();
7488
7674
 
7489
7675
  // src/cli/status.ts
7490
7676
  init_cjs_shims();
@@ -7497,6 +7683,7 @@ var STEP_DISPLAY_NAMES = {
7497
7683
  "archive": "\u5F52\u6863",
7498
7684
  "context": "\u4E0A\u4E0B\u6587",
7499
7685
  "clarify": "\u6F84\u6E05",
7686
+ "reference": "\u53C2\u8003\u5206\u6790",
7500
7687
  "analysis": "\u5206\u6790",
7501
7688
  "bdd": "BDD",
7502
7689
  "spec": "\u89C4\u683C",
@@ -7513,6 +7700,7 @@ var STEP_COLORS = {
7513
7700
  "archive": chalk9__default.default.gray,
7514
7701
  "context": chalk9__default.default.magenta,
7515
7702
  "clarify": chalk9__default.default.yellow,
7703
+ "reference": chalk9__default.default.blue,
7516
7704
  "analysis": chalk9__default.default.blue,
7517
7705
  "bdd": chalk9__default.default.cyan,
7518
7706
  "spec": chalk9__default.default.green,
@@ -7649,17 +7837,17 @@ var Completer = class {
7649
7837
  prefix = filePath;
7650
7838
  } else {
7651
7839
  const dir = filePath.slice(0, lastSlash);
7652
- dirPath = path7__namespace.resolve(this.workingDirectory, dir);
7840
+ dirPath = path5__namespace.resolve(this.workingDirectory, dir);
7653
7841
  prefix = filePath.slice(lastSlash + 1);
7654
7842
  }
7655
7843
  try {
7656
- const entries = await fs7__namespace.readdir(dirPath, { withFileTypes: true });
7844
+ const entries = await fs5__namespace.readdir(dirPath, { withFileTypes: true });
7657
7845
  const matches = [];
7658
7846
  for (const entry of entries) {
7659
7847
  if (entry.name.startsWith(prefix)) {
7660
7848
  const isDir = entry.isDirectory();
7661
7849
  matches.push({
7662
- text: "@" + path7__namespace.relative(this.workingDirectory, path7__namespace.join(dirPath, entry.name)).replace(/\\/g, "/") + (isDir ? "/" : ""),
7850
+ text: "@" + path5__namespace.relative(this.workingDirectory, path5__namespace.join(dirPath, entry.name)).replace(/\\/g, "/") + (isDir ? "/" : ""),
7663
7851
  displayText: entry.name + (isDir ? "/" : ""),
7664
7852
  description: isDir ? "\u76EE\u5F55" : "\u6587\u4EF6",
7665
7853
  type: isDir ? "directory" : "file"
@@ -7732,10 +7920,10 @@ var Completer = class {
7732
7920
  // src/cli/repl.ts
7733
7921
  init_new();
7734
7922
  async function startInteractiveMode(options) {
7735
- const historyFile = path7__namespace.join(options.workingDirectory, ".sf-cli", "history.json");
7923
+ const historyFile = path5__namespace.join(options.workingDirectory, ".sf-cli", "history.json");
7736
7924
  let history = [];
7737
7925
  try {
7738
- const historyData = await fs7__namespace.readFile(historyFile, "utf-8");
7926
+ const historyData = await fs5__namespace.readFile(historyFile, "utf-8");
7739
7927
  history = JSON.parse(historyData);
7740
7928
  } catch {
7741
7929
  }
@@ -7768,11 +7956,11 @@ async function startInteractiveMode(options) {
7768
7956
  const modelService = new ModelService(configManager);
7769
7957
  const normsManager = new NormsManager({
7770
7958
  projectPath: options.workingDirectory,
7771
- normsDir: path7__namespace.join(options.workingDirectory, ".sf-cli", "norms")
7959
+ normsDir: path5__namespace.join(options.workingDirectory, ".sf-cli", "norms")
7772
7960
  });
7773
7961
  await configManager.load(options.workingDirectory);
7774
7962
  await contextManager.initialize(options.workingDirectory);
7775
- const statsDir = path7__namespace.join(options.workingDirectory, ".sf-cli");
7963
+ const statsDir = path5__namespace.join(options.workingDirectory, ".sf-cli");
7776
7964
  await modelService.initialize(statsDir);
7777
7965
  await normsManager.initialize();
7778
7966
  const state = {
@@ -7822,8 +8010,8 @@ async function startInteractiveMode(options) {
7822
8010
  }
7823
8011
  const saveHistory = async () => {
7824
8012
  try {
7825
- await fs7__namespace.mkdir(path7__namespace.dirname(historyFile), { recursive: true });
7826
- await fs7__namespace.writeFile(historyFile, JSON.stringify(history.slice(-500)));
8013
+ await fs5__namespace.mkdir(path5__namespace.dirname(historyFile), { recursive: true });
8014
+ await fs5__namespace.writeFile(historyFile, JSON.stringify(history.slice(-500)));
7827
8015
  } catch {
7828
8016
  }
7829
8017
  };
@@ -7894,16 +8082,15 @@ async function startInteractiveMode(options) {
7894
8082
  }
7895
8083
 
7896
8084
  // src/cli/index.ts
7897
- init_config();
7898
8085
  function getPackageJson() {
7899
8086
  const possiblePaths = [
7900
- path7__namespace.resolve(__dirname, "..", "..", "package.json"),
7901
- path7__namespace.resolve(__dirname, "..", "..", "..", "package.json")
8087
+ path5__namespace.resolve(__dirname, "..", "..", "package.json"),
8088
+ path5__namespace.resolve(__dirname, "..", "..", "..", "package.json")
7902
8089
  ];
7903
8090
  for (const pkgPath of possiblePaths) {
7904
8091
  try {
7905
- if (fs9__namespace.existsSync(pkgPath)) {
7906
- const content = fs9__namespace.readFileSync(pkgPath, "utf-8");
8092
+ if (fs7__namespace.existsSync(pkgPath)) {
8093
+ const content = fs7__namespace.readFileSync(pkgPath, "utf-8");
7907
8094
  return JSON.parse(content);
7908
8095
  }
7909
8096
  } catch {
@@ -7932,7 +8119,7 @@ commander.program.command("init").description("\u521D\u59CB\u5316\u63A5\u7BA1\u9
7932
8119
  commander.program.command("model").description("\u9009\u62E9AI\u6A21\u578B").action(async () => {
7933
8120
  const configManager = new ConfigManager();
7934
8121
  await configManager.load(process.cwd());
7935
- const { selectModel: selectModel2 } = await Promise.resolve().then(() => (init_model3(), model_exports));
8122
+ const { selectModel: selectModel2 } = await Promise.resolve().then(() => (init_model2(), model_exports));
7936
8123
  await selectModel2(configManager);
7937
8124
  });
7938
8125
  commander.program.command("update").description("\u66F4\u65B0CLI\u5230\u6700\u65B0\u7248\u672C").action(async () => {