@nick848/sf-cli 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,6 +1,8 @@
1
+ import * as path5 from 'path';
2
+ import path5__default from 'path';
3
+ import { fileURLToPath } from 'url';
1
4
  import * as fs4 from 'fs/promises';
2
5
  import * as fsSync from 'fs';
3
- import * as path4 from 'path';
4
6
  import * as crypto from 'crypto';
5
7
  import * as os from 'os';
6
8
  import { encoding_for_model } from 'tiktoken';
@@ -11,7 +13,10 @@ import { v4 } from 'uuid';
11
13
  import { prompt } from 'enquirer';
12
14
  import { spawn } from 'child_process';
13
15
 
14
- // src/services/config.ts
16
+ // node_modules/tsup/assets/esm_shims.js
17
+ var getFilename = () => fileURLToPath(import.meta.url);
18
+ var getDirname = () => path5__default.dirname(getFilename());
19
+ var __dirname$1 = /* @__PURE__ */ getDirname();
15
20
  var DEFAULT_CONFIG = {
16
21
  model: "GLM-5",
17
22
  apiKey: "",
@@ -24,7 +29,7 @@ var IV_LENGTH = 16;
24
29
  var KEY_DIR = ".sf-cli";
25
30
  var KEY_FILE = ".key";
26
31
  function getOrCreateEncryptionKey() {
27
- const keyPath = path4.join(os.homedir(), KEY_DIR, KEY_FILE);
32
+ const keyPath = path5.join(os.homedir(), KEY_DIR, KEY_FILE);
28
33
  try {
29
34
  if (fsSync.existsSync(keyPath)) {
30
35
  const keyBase64 = fsSync.readFileSync(keyPath, "utf-8").trim();
@@ -34,7 +39,7 @@ function getOrCreateEncryptionKey() {
34
39
  }
35
40
  const key = crypto.randomBytes(32);
36
41
  try {
37
- const keyDir = path4.dirname(keyPath);
42
+ const keyDir = path5.dirname(keyPath);
38
43
  if (!fsSync.existsSync(keyDir)) {
39
44
  fsSync.mkdirSync(keyDir, { recursive: true, mode: 448 });
40
45
  }
@@ -65,7 +70,7 @@ var ConfigManager = class {
65
70
  }
66
71
  async load(projectPath) {
67
72
  this.projectPath = projectPath;
68
- this.configPath = path4.join(projectPath, ".sf-cli", "config.json");
73
+ this.configPath = path5.join(projectPath, ".sf-cli", "config.json");
69
74
  try {
70
75
  const content = await fs4.readFile(this.configPath, "utf-8");
71
76
  const loaded = JSON.parse(content);
@@ -86,7 +91,7 @@ var ConfigManager = class {
86
91
  configToSave.apiKey = encrypted;
87
92
  configToSave.apiKeyEncrypted = true;
88
93
  }
89
- await fs4.mkdir(path4.dirname(this.configPath), { recursive: true });
94
+ await fs4.mkdir(path5.dirname(this.configPath), { recursive: true });
90
95
  await fs4.writeFile(
91
96
  this.configPath,
92
97
  JSON.stringify(configToSave, null, 2),
@@ -345,7 +350,7 @@ var BaseAdapter = class {
345
350
  * 延迟工具函数
346
351
  */
347
352
  delay(ms) {
348
- return new Promise((resolve2) => setTimeout(resolve2, ms));
353
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
349
354
  }
350
355
  };
351
356
 
@@ -966,7 +971,7 @@ var ModelService = class {
966
971
  * 初始化服务
967
972
  */
968
973
  async initialize(statsDir) {
969
- this.statsPath = path4.join(statsDir, "tokens");
974
+ this.statsPath = path5.join(statsDir, "tokens");
970
975
  await this.loadStats();
971
976
  const model = this.configManager.get("model");
972
977
  const apiKey = this.configManager.get("apiKey");
@@ -1139,8 +1144,8 @@ var ModelService = class {
1139
1144
  async loadStats() {
1140
1145
  if (!this.statsPath) return;
1141
1146
  try {
1142
- const dailyPath = path4.join(this.statsPath, "daily.json");
1143
- const totalPath = path4.join(this.statsPath, "total.json");
1147
+ const dailyPath = path5.join(this.statsPath, "daily.json");
1148
+ const totalPath = path5.join(this.statsPath, "total.json");
1144
1149
  const [daily, total] = await Promise.all([
1145
1150
  fs4.readFile(dailyPath, "utf-8").catch(() => "{}"),
1146
1151
  fs4.readFile(totalPath, "utf-8").catch(() => '{"totalInput":0,"totalOutput":0}')
@@ -1157,8 +1162,8 @@ var ModelService = class {
1157
1162
  if (!this.statsPath) return;
1158
1163
  try {
1159
1164
  await fs4.mkdir(this.statsPath, { recursive: true });
1160
- const dailyPath = path4.join(this.statsPath, "daily.json");
1161
- const totalPath = path4.join(this.statsPath, "total.json");
1165
+ const dailyPath = path5.join(this.statsPath, "daily.json");
1166
+ const totalPath = path5.join(this.statsPath, "total.json");
1162
1167
  await Promise.all([
1163
1168
  fs4.writeFile(dailyPath, JSON.stringify(this.stats.byDate, null, 2)),
1164
1169
  fs4.writeFile(totalPath, JSON.stringify({
@@ -2832,15 +2837,15 @@ async function loadProjectContext(workingDirectory) {
2832
2837
  devStandards: ""
2833
2838
  };
2834
2839
  try {
2835
- context.agentsMd = await fs4.readFile(path4.join(workingDirectory, "AGENTS.md"), "utf-8");
2840
+ context.agentsMd = await fs4.readFile(path5.join(workingDirectory, "AGENTS.md"), "utf-8");
2836
2841
  } catch {
2837
2842
  }
2838
2843
  try {
2839
- context.configYaml = await fs4.readFile(path4.join(workingDirectory, "openspec", "config.yaml"), "utf-8");
2844
+ context.configYaml = await fs4.readFile(path5.join(workingDirectory, "openspec", "config.yaml"), "utf-8");
2840
2845
  } catch {
2841
2846
  }
2842
2847
  try {
2843
- context.devStandards = await fs4.readFile(path4.join(workingDirectory, ".sf-cli", "norms", "devstanded.md"), "utf-8");
2848
+ context.devStandards = await fs4.readFile(path5.join(workingDirectory, ".sf-cli", "norms", "devstanded.md"), "utf-8");
2844
2849
  } catch {
2845
2850
  }
2846
2851
  return context;
@@ -3776,7 +3781,7 @@ var WorkflowEngine = class {
3776
3781
  */
3777
3782
  async initialize(projectPath) {
3778
3783
  this.projectPath = projectPath;
3779
- this.openspecPath = path4.join(projectPath, "openspec");
3784
+ this.openspecPath = path5.join(projectPath, "openspec");
3780
3785
  await this.ensureDirectories();
3781
3786
  await this.loadProjectContext();
3782
3787
  await this.restoreState();
@@ -3786,19 +3791,19 @@ var WorkflowEngine = class {
3786
3791
  * 加载项目上下文(AGENTS.md 和 config.yaml)
3787
3792
  */
3788
3793
  async loadProjectContext() {
3789
- const agentsMdPath = path4.join(this.projectPath, "AGENTS.md");
3794
+ const agentsMdPath = path5.join(this.projectPath, "AGENTS.md");
3790
3795
  try {
3791
3796
  this.projectContext = await fs4.readFile(agentsMdPath, "utf-8");
3792
3797
  } catch {
3793
3798
  this.projectContext = "";
3794
3799
  }
3795
- const configPath = path4.join(this.openspecPath, "config.yaml");
3800
+ const configPath = path5.join(this.openspecPath, "config.yaml");
3796
3801
  try {
3797
3802
  this.projectConfig = await fs4.readFile(configPath, "utf-8");
3798
3803
  } catch {
3799
3804
  this.projectConfig = "";
3800
3805
  }
3801
- const devstandedPath = path4.join(this.projectPath, ".sf-cli", "norms", "devstanded.md");
3806
+ const devstandedPath = path5.join(this.projectPath, ".sf-cli", "norms", "devstanded.md");
3802
3807
  try {
3803
3808
  this.devStandards = await fs4.readFile(devstandedPath, "utf-8");
3804
3809
  } catch {
@@ -4086,10 +4091,10 @@ var WorkflowEngine = class {
4086
4091
  await this.createSpecDocument(summary);
4087
4092
  await this.updateChangeRecord("archived");
4088
4093
  await this.saveState();
4089
- const changesDir = path4.join(this.openspecPath, "changes");
4090
- const archiveDir = path4.join(changesDir, "archive");
4091
- const changeFile = path4.join(changesDir, `${changeId}.md`);
4092
- const archiveFile = path4.join(archiveDir, `${changeId}.md`);
4094
+ const changesDir = path5.join(this.openspecPath, "changes");
4095
+ const archiveDir = path5.join(changesDir, "archive");
4096
+ const changeFile = path5.join(changesDir, `${changeId}.md`);
4097
+ const archiveFile = path5.join(archiveDir, `${changeId}.md`);
4093
4098
  await fs4.mkdir(archiveDir, { recursive: true });
4094
4099
  await fs4.rename(changeFile, archiveFile).catch(() => {
4095
4100
  });
@@ -4113,14 +4118,14 @@ var WorkflowEngine = class {
4113
4118
  }
4114
4119
  // ==================== 私有方法 ====================
4115
4120
  async ensureDirectories() {
4116
- const changesDir = path4.join(this.openspecPath, "changes");
4117
- const archiveDir = path4.join(changesDir, "archive");
4118
- const specDir = path4.join(this.openspecPath, "spec");
4121
+ const changesDir = path5.join(this.openspecPath, "changes");
4122
+ const archiveDir = path5.join(changesDir, "archive");
4123
+ const specDir = path5.join(this.openspecPath, "spec");
4119
4124
  await fs4.mkdir(archiveDir, { recursive: true });
4120
4125
  await fs4.mkdir(specDir, { recursive: true });
4121
4126
  }
4122
4127
  async restoreState() {
4123
- const statePath = path4.join(this.openspecPath, ".workflow-state.json");
4128
+ const statePath = path5.join(this.openspecPath, ".workflow-state.json");
4124
4129
  try {
4125
4130
  const content = await fs4.readFile(statePath, "utf-8");
4126
4131
  this.state = JSON.parse(content, (key, value) => {
@@ -4140,11 +4145,11 @@ var WorkflowEngine = class {
4140
4145
  }
4141
4146
  }
4142
4147
  async saveState() {
4143
- const statePath = path4.join(this.openspecPath, ".workflow-state.json");
4148
+ const statePath = path5.join(this.openspecPath, ".workflow-state.json");
4144
4149
  await fs4.writeFile(statePath, JSON.stringify(this.state, null, 2));
4145
4150
  }
4146
4151
  async restoreSnapshots() {
4147
- const snapshotsPath = path4.join(this.openspecPath, ".workflow-snapshots.json");
4152
+ const snapshotsPath = path5.join(this.openspecPath, ".workflow-snapshots.json");
4148
4153
  try {
4149
4154
  const content = await fs4.readFile(snapshotsPath, "utf-8");
4150
4155
  const data = JSON.parse(content, (key, value) => {
@@ -4161,7 +4166,7 @@ var WorkflowEngine = class {
4161
4166
  }
4162
4167
  }
4163
4168
  async saveSnapshots() {
4164
- const snapshotsPath = path4.join(this.openspecPath, ".workflow-snapshots.json");
4169
+ const snapshotsPath = path5.join(this.openspecPath, ".workflow-snapshots.json");
4165
4170
  const data = Array.from(this.snapshots.values());
4166
4171
  await fs4.writeFile(snapshotsPath, JSON.stringify(data, null, 2));
4167
4172
  }
@@ -4183,7 +4188,7 @@ var WorkflowEngine = class {
4183
4188
  }
4184
4189
  async createChangeRecord() {
4185
4190
  if (!this.state) return;
4186
- const changePath = path4.join(this.openspecPath, "changes", `${this.state.id}.md`);
4191
+ const changePath = path5.join(this.openspecPath, "changes", `${this.state.id}.md`);
4187
4192
  await fs4.writeFile(changePath, this.formatChangeRecord());
4188
4193
  }
4189
4194
  async updateChangeRecord(status) {
@@ -4191,7 +4196,7 @@ var WorkflowEngine = class {
4191
4196
  if (status) {
4192
4197
  this.state.status = status;
4193
4198
  }
4194
- const changePath = path4.join(this.openspecPath, "changes", `${this.state.id}.md`);
4199
+ const changePath = path5.join(this.openspecPath, "changes", `${this.state.id}.md`);
4195
4200
  await fs4.writeFile(changePath, this.formatChangeRecord());
4196
4201
  }
4197
4202
  formatChangeRecord() {
@@ -4231,7 +4236,7 @@ ${this.state.artifacts.map((a) => `- ${a}`).join("\n") || "\u6682\u65E0"}
4231
4236
  }
4232
4237
  async createSpecDocument(summary) {
4233
4238
  if (!this.state) return;
4234
- const specPath = path4.join(this.openspecPath, "spec", `${this.state.id}.md`);
4239
+ const specPath = path5.join(this.openspecPath, "spec", `${this.state.id}.md`);
4235
4240
  const content = `# Spec: ${this.state.title}
4236
4241
 
4237
4242
  > \u53D8\u66F4ID: ${this.state.id}
@@ -4329,7 +4334,7 @@ var NormsManager = class {
4329
4334
  * 从单个文件学习规范
4330
4335
  */
4331
4336
  async learnFromFile(filePath, content) {
4332
- const ext = path4.extname(filePath);
4337
+ const ext = path5.extname(filePath);
4333
4338
  const patterns = this.extractPatterns(filePath, content, ext);
4334
4339
  for (const pattern of patterns) {
4335
4340
  await this.recordOccurrence({
@@ -4936,12 +4941,12 @@ ${response}`;
4936
4941
  for (const entry of entries) {
4937
4942
  if (entry.isDirectory()) {
4938
4943
  if (!IGNORED_DIRS.includes(entry.name)) {
4939
- await scan(path4.join(dir, entry.name));
4944
+ await scan(path5.join(dir, entry.name));
4940
4945
  }
4941
4946
  } else if (entry.isFile()) {
4942
- const ext = path4.extname(entry.name);
4947
+ const ext = path5.extname(entry.name);
4943
4948
  if (SCAN_EXTENSIONS.includes(ext)) {
4944
- files.push(path4.join(dir, entry.name));
4949
+ files.push(path5.join(dir, entry.name));
4945
4950
  }
4946
4951
  }
4947
4952
  }
@@ -4976,13 +4981,13 @@ ${response}`;
4976
4981
  */
4977
4982
  async ensureNormsDir() {
4978
4983
  await fs4.mkdir(this.config.normsDir, { recursive: true });
4979
- await fs4.mkdir(path4.join(this.config.normsDir, "weekly"), { recursive: true });
4984
+ await fs4.mkdir(path5.join(this.config.normsDir, "weekly"), { recursive: true });
4980
4985
  }
4981
4986
  /**
4982
4987
  * 加载已有规范
4983
4988
  */
4984
4989
  async loadStandards() {
4985
- const standardsPath = path4.join(this.config.normsDir, "patterns.json");
4990
+ const standardsPath = path5.join(this.config.normsDir, "patterns.json");
4986
4991
  try {
4987
4992
  const content = await fs4.readFile(standardsPath, "utf-8");
4988
4993
  const data = JSON.parse(content);
@@ -5000,7 +5005,7 @@ ${response}`;
5000
5005
  * 加载权重数据
5001
5006
  */
5002
5007
  async loadWeights() {
5003
- const weightsPath = path4.join(this.config.normsDir, "weights.json");
5008
+ const weightsPath = path5.join(this.config.normsDir, "weights.json");
5004
5009
  try {
5005
5010
  const content = await fs4.readFile(weightsPath, "utf-8");
5006
5011
  const data = JSON.parse(content);
@@ -5017,7 +5022,7 @@ ${response}`;
5017
5022
  * 保存规范
5018
5023
  */
5019
5024
  async saveStandards() {
5020
- const standardsPath = path4.join(this.config.normsDir, "patterns.json");
5025
+ const standardsPath = path5.join(this.config.normsDir, "patterns.json");
5021
5026
  await fs4.writeFile(
5022
5027
  standardsPath,
5023
5028
  JSON.stringify(Array.from(this.standards.values()), null, 2),
@@ -5028,7 +5033,7 @@ ${response}`;
5028
5033
  * 保存权重
5029
5034
  */
5030
5035
  async saveWeights() {
5031
- const weightsPath = path4.join(this.config.normsDir, "weights.json");
5036
+ const weightsPath = path5.join(this.config.normsDir, "weights.json");
5032
5037
  await fs4.writeFile(
5033
5038
  weightsPath,
5034
5039
  JSON.stringify(Array.from(this.weights.values()), null, 2),
@@ -5056,7 +5061,7 @@ ${response}`;
5056
5061
  * 保存周报
5057
5062
  */
5058
5063
  async saveWeeklyReport(weekId, report) {
5059
- const reportPath = path4.join(this.config.normsDir, "weekly", `${weekId}.json`);
5064
+ const reportPath = path5.join(this.config.normsDir, "weekly", `${weekId}.json`);
5060
5065
  await fs4.writeFile(reportPath, JSON.stringify(report, null, 2), "utf-8");
5061
5066
  }
5062
5067
  /**
@@ -5065,7 +5070,7 @@ ${response}`;
5065
5070
  async updateDevStandedMd() {
5066
5071
  const standards = this.getEffectiveStandards();
5067
5072
  const content = this.generateDevStandedMd(standards);
5068
- const mdPath = path4.join(this.config.normsDir, "devstanded.md");
5073
+ const mdPath = path5.join(this.config.normsDir, "devstanded.md");
5069
5074
  await fs4.writeFile(mdPath, content, "utf-8");
5070
5075
  }
5071
5076
  /**
@@ -5213,7 +5218,7 @@ var ContextManager = class {
5213
5218
  }
5214
5219
  async initialize(projectPath) {
5215
5220
  this.projectPath = projectPath;
5216
- this.persistPath = path4.join(projectPath, ".sf-cli", "cache", "context", "context.json");
5221
+ this.persistPath = path5.join(projectPath, ".sf-cli", "cache", "context", "context.json");
5217
5222
  await this.loadPersistedContext();
5218
5223
  }
5219
5224
  /**
@@ -5454,7 +5459,7 @@ ${summary}`,
5454
5459
  */
5455
5460
  async persist() {
5456
5461
  if (!this.persistPath) return;
5457
- const dir = path4.dirname(this.persistPath);
5462
+ const dir = path5.dirname(this.persistPath);
5458
5463
  await fs4.mkdir(dir, { recursive: true });
5459
5464
  const data = {
5460
5465
  messages: this.state.messages,
@@ -5589,8 +5594,8 @@ var CommandParser = class {
5589
5594
  };
5590
5595
  }
5591
5596
  parseAtPath(input) {
5592
- const path11 = input.slice(1).trim();
5593
- if (!path11) {
5597
+ const path14 = input.slice(1).trim();
5598
+ if (!path14) {
5594
5599
  return { success: false, error: "\u7F3A\u5C11\u6587\u4EF6\u8DEF\u5F84" };
5595
5600
  }
5596
5601
  return {
@@ -5598,7 +5603,7 @@ var CommandParser = class {
5598
5603
  command: {
5599
5604
  type: "at" /* AT */,
5600
5605
  raw: input,
5601
- path: path11
5606
+ path: path14
5602
5607
  }
5603
5608
  };
5604
5609
  }
@@ -5654,9 +5659,9 @@ async function initProject(options = {}, workingDir) {
5654
5659
  output: chalk9.red(`\u9519\u8BEF: \u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6743\u9650\u8BBF\u95EE ${cwd}`)
5655
5660
  };
5656
5661
  }
5657
- const sfCliDir = path4.join(cwd, ".sf-cli");
5658
- const openspecDir = path4.join(cwd, "openspec");
5659
- const agentsMdPath = path4.join(cwd, "AGENTS.md");
5662
+ const sfCliDir = path5.join(cwd, ".sf-cli");
5663
+ const openspecDir = path5.join(cwd, "openspec");
5664
+ const agentsMdPath = path5.join(cwd, "AGENTS.md");
5660
5665
  try {
5661
5666
  const agentsExists = await fileExists(agentsMdPath);
5662
5667
  if (agentsExists && !options.force) {
@@ -5716,7 +5721,7 @@ async function createSfCliDirectory(basePath) {
5716
5721
  "logs"
5717
5722
  ];
5718
5723
  for (const dir of dirs) {
5719
- await fs4.mkdir(path4.join(basePath, dir), { recursive: true });
5724
+ await fs4.mkdir(path5.join(basePath, dir), { recursive: true });
5720
5725
  }
5721
5726
  const config = {
5722
5727
  version: "1.0.0",
@@ -5725,36 +5730,36 @@ async function createSfCliDirectory(basePath) {
5725
5730
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
5726
5731
  };
5727
5732
  await fs4.writeFile(
5728
- path4.join(basePath, "config.json"),
5733
+ path5.join(basePath, "config.json"),
5729
5734
  JSON.stringify(config, null, 2),
5730
5735
  "utf-8"
5731
5736
  );
5732
5737
  await fs4.writeFile(
5733
- path4.join(basePath, "agents", "registry.json"),
5738
+ path5.join(basePath, "agents", "registry.json"),
5734
5739
  JSON.stringify({ version: "1.0.0", agents: {} }, null, 2),
5735
5740
  "utf-8"
5736
5741
  );
5737
5742
  await fs4.writeFile(
5738
- path4.join(basePath, "skills", "registry.json"),
5743
+ path5.join(basePath, "skills", "registry.json"),
5739
5744
  JSON.stringify({ version: "1.0.0", skills: {} }, null, 2),
5740
5745
  "utf-8"
5741
5746
  );
5742
5747
  await fs4.writeFile(
5743
- path4.join(basePath, "health", "health.md"),
5748
+ path5.join(basePath, "health", "health.md"),
5744
5749
  generateHealthTemplate(),
5745
5750
  "utf-8"
5746
5751
  );
5747
5752
  }
5748
5753
  async function createOpenSpecDirectory(basePath) {
5749
- const changesDir = path4.join(basePath, "changes");
5750
- const archiveDir = path4.join(changesDir, "archive");
5751
- const specDir = path4.join(basePath, "spec");
5754
+ const changesDir = path5.join(basePath, "changes");
5755
+ const archiveDir = path5.join(changesDir, "archive");
5756
+ const specDir = path5.join(basePath, "spec");
5752
5757
  await fs4.mkdir(archiveDir, { recursive: true });
5753
5758
  await fs4.mkdir(specDir, { recursive: true });
5754
5759
  }
5755
5760
  async function analyzeProject(cwd) {
5756
5761
  const result = {
5757
- name: path4.basename(cwd),
5762
+ name: path5.basename(cwd),
5758
5763
  type: "unknown",
5759
5764
  framework: null,
5760
5765
  techStack: [],
@@ -5773,7 +5778,7 @@ async function analyzeProject(cwd) {
5773
5778
  hasEslint: false,
5774
5779
  hasPrettier: false
5775
5780
  };
5776
- const pkgPath = path4.join(cwd, "package.json");
5781
+ const pkgPath = path5.join(cwd, "package.json");
5777
5782
  try {
5778
5783
  const pkgContent = await fs4.readFile(pkgPath, "utf-8");
5779
5784
  const pkg = JSON.parse(pkgContent);
@@ -5894,7 +5899,7 @@ async function findEntryPoints(cwd) {
5894
5899
  "index.js"
5895
5900
  ];
5896
5901
  for (const entry of possibleEntries) {
5897
- const fullPath = path4.join(cwd, entry);
5902
+ const fullPath = path5.join(cwd, entry);
5898
5903
  if (await fileExists(fullPath)) {
5899
5904
  entryPoints.push(entry);
5900
5905
  }
@@ -5902,7 +5907,7 @@ async function findEntryPoints(cwd) {
5902
5907
  return entryPoints;
5903
5908
  }
5904
5909
  async function saveProjectAnalysis(sfCliDir, analysis) {
5905
- const analysisPath = path4.join(sfCliDir, "cache", "analysis", "project-analysis.json");
5910
+ const analysisPath = path5.join(sfCliDir, "cache", "analysis", "project-analysis.json");
5906
5911
  await fs4.writeFile(
5907
5912
  analysisPath,
5908
5913
  JSON.stringify(analysis, null, 2),
@@ -5910,7 +5915,7 @@ async function saveProjectAnalysis(sfCliDir, analysis) {
5910
5915
  );
5911
5916
  }
5912
5917
  async function generateOpenSpecConfig(openspecDir, analysis) {
5913
- const configPath = path4.join(openspecDir, "config.yaml");
5918
+ const configPath = path5.join(openspecDir, "config.yaml");
5914
5919
  const content = `# OpenSpec \u9879\u76EE\u914D\u7F6E
5915
5920
  # \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
5916
5921
 
@@ -6442,8 +6447,10 @@ function createSpinner(message) {
6442
6447
  stop: () => process.stdout.write(" ".repeat(message.length + 10) + "\r")
6443
6448
  };
6444
6449
  }
6445
- var CURRENT_VERSION = "1.0.0";
6446
- var PACKAGE_NAME = "sf-cli";
6450
+ var packageJsonPath = path5.resolve(__dirname$1, "../../package.json");
6451
+ var packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, "utf-8"));
6452
+ var CURRENT_VERSION = packageJson.version;
6453
+ var PACKAGE_NAME = packageJson.name;
6447
6454
  async function handleUpdate(args, ctx) {
6448
6455
  const options = {
6449
6456
  check: args.includes("--check") || args.includes("-c"),
@@ -6470,6 +6477,9 @@ async function checkForUpdates() {
6470
6477
  const latestVersion = await getLatestVersion();
6471
6478
  if (!latestVersion) {
6472
6479
  lines.push(chalk9.yellow("\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\u4FE1\u606F"));
6480
+ lines.push(chalk9.gray("\u53EF\u80FD\u539F\u56E0:"));
6481
+ lines.push(chalk9.gray(" 1. \u5305\u5C1A\u672A\u53D1\u5E03\u5230 npm"));
6482
+ lines.push(chalk9.gray(" 2. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898"));
6473
6483
  return { output: lines.join("\n") };
6474
6484
  }
6475
6485
  lines.push(chalk9.gray(` \u5F53\u524D\u7248\u672C: v${CURRENT_VERSION}`));
@@ -6488,43 +6498,70 @@ async function checkForUpdates() {
6488
6498
  async function performUpdate(targetVersion) {
6489
6499
  const lines = [];
6490
6500
  lines.push(chalk9.cyan("\u6B63\u5728\u66F4\u65B0 sf-cli..."));
6501
+ lines.push(chalk9.gray(` \u5305\u540D: ${PACKAGE_NAME}`));
6502
+ lines.push(chalk9.gray(` \u5F53\u524D\u7248\u672C: v${CURRENT_VERSION}`));
6491
6503
  try {
6492
6504
  const latestVersion = await getLatestVersion();
6505
+ if (!latestVersion && !targetVersion) {
6506
+ lines.push(chalk9.yellow("\n\u26A0 \u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\u4FE1\u606F"));
6507
+ lines.push(chalk9.gray("\n\u53EF\u80FD\u539F\u56E0:"));
6508
+ lines.push(chalk9.gray(" 1. \u5305\u5C1A\u672A\u53D1\u5E03\u5230 npm"));
6509
+ lines.push(chalk9.gray(" 2. \u7F51\u7EDC\u8FDE\u63A5\u95EE\u9898"));
6510
+ lines.push(chalk9.gray("\n\u60A8\u53EF\u4EE5\u5C1D\u8BD5\u624B\u52A8\u66F4\u65B0:"));
6511
+ lines.push(chalk9.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
6512
+ return { output: lines.join("\n") };
6513
+ }
6493
6514
  if (latestVersion === CURRENT_VERSION && !targetVersion) {
6494
- lines.push(chalk9.green("\u2713 \u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0"));
6515
+ lines.push(chalk9.green("\n\u2713 \u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0"));
6495
6516
  return { output: lines.join("\n") };
6496
6517
  }
6497
6518
  const packageSpec = targetVersion ? `${PACKAGE_NAME}@${targetVersion}` : `${PACKAGE_NAME}@latest`;
6498
6519
  lines.push(chalk9.gray(` \u5B89\u88C5: ${packageSpec}`));
6499
- await new Promise((resolve2, reject) => {
6520
+ const installResult = await new Promise((resolve4) => {
6500
6521
  const proc = spawn("npm", ["install", "-g", packageSpec], {
6501
6522
  stdio: "pipe",
6502
6523
  shell: true
6503
6524
  });
6525
+ let output = "";
6526
+ proc.stdout?.on("data", (data) => {
6527
+ output += data.toString();
6528
+ });
6529
+ proc.stderr?.on("data", (data) => {
6530
+ output += data.toString();
6531
+ });
6504
6532
  proc.on("close", (code) => {
6505
- if (code === 0) {
6506
- resolve2();
6507
- } else {
6508
- reject(new Error(`npm install exited with code ${code}`));
6509
- }
6533
+ resolve4({
6534
+ success: code === 0,
6535
+ output
6536
+ });
6510
6537
  });
6511
6538
  proc.on("error", (err) => {
6512
- reject(err);
6539
+ resolve4({
6540
+ success: false,
6541
+ output: err.message
6542
+ });
6513
6543
  });
6514
6544
  });
6515
- lines.push(chalk9.green("\u2713 \u66F4\u65B0\u5B8C\u6210!"));
6545
+ if (!installResult.success) {
6546
+ lines.push(chalk9.red("\n\u2717 \u66F4\u65B0\u5931\u8D25"));
6547
+ lines.push(chalk9.gray(installResult.output));
6548
+ lines.push(chalk9.gray("\n\u60A8\u53EF\u4EE5\u5C1D\u8BD5\u624B\u52A8\u66F4\u65B0:"));
6549
+ lines.push(chalk9.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
6550
+ return { output: lines.join("\n") };
6551
+ }
6552
+ lines.push(chalk9.green("\n\u2713 \u66F4\u65B0\u5B8C\u6210!"));
6516
6553
  lines.push(chalk9.gray(` \u65B0\u7248\u672C: v${targetVersion || latestVersion}`));
6517
6554
  lines.push(chalk9.gray("\n\u8BF7\u91CD\u542F CLI \u4EE5\u4F7F\u7528\u65B0\u7248\u672C"));
6518
6555
  } catch (error) {
6519
6556
  lines.push(chalk9.red("\u66F4\u65B0\u5931\u8D25: " + error.message));
6520
6557
  lines.push(chalk9.gray("\n\u60A8\u53EF\u4EE5\u5C1D\u8BD5\u624B\u52A8\u66F4\u65B0:"));
6521
- lines.push(chalk9.gray(" npm install -g sf-cli@latest"));
6558
+ lines.push(chalk9.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
6522
6559
  }
6523
6560
  return { output: lines.join("\n") };
6524
6561
  }
6525
6562
  async function getLatestVersion() {
6526
6563
  try {
6527
- const result = await new Promise((resolve2, reject) => {
6564
+ const result = await new Promise((resolve4, reject) => {
6528
6565
  const proc = spawn("npm", ["view", PACKAGE_NAME, "version"], {
6529
6566
  stdio: "pipe",
6530
6567
  shell: true
@@ -6534,13 +6571,17 @@ async function getLatestVersion() {
6534
6571
  output += data.toString();
6535
6572
  });
6536
6573
  proc.on("close", (code) => {
6537
- if (code === 0) {
6538
- resolve2(output.trim());
6574
+ if (code === 0 && output.trim()) {
6575
+ resolve4(output.trim());
6539
6576
  } else {
6540
6577
  reject(new Error("Failed to get version"));
6541
6578
  }
6542
6579
  });
6543
6580
  proc.on("error", reject);
6581
+ setTimeout(() => {
6582
+ proc.kill();
6583
+ reject(new Error("Timeout"));
6584
+ }, 1e4);
6544
6585
  });
6545
6586
  return result || null;
6546
6587
  } catch {
@@ -6622,15 +6663,32 @@ var MAX_FILE_SIZE2 = 1024 * 1024;
6622
6663
  var COMPLEXITY_THRESHOLD = 6;
6623
6664
  async function handleNew(args, ctx) {
6624
6665
  const workingDir = ctx.options.workingDirectory;
6666
+ const workflowEngine = ctx.workflowEngine;
6667
+ if (workflowEngine) {
6668
+ const existingState = workflowEngine.getState();
6669
+ if (existingState && existingState.status === "running") {
6670
+ return {
6671
+ output: chalk9.yellow("\u5F53\u524D\u5DF2\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9.gray(`
6672
+
6673
+ \u5DE5\u4F5C\u6D41: ${existingState.title}`) + chalk9.gray(`
6674
+ \u5F53\u524D\u9636\u6BB5: ${existingState.currentStep}`) + chalk9.gray(`
6675
+
6676
+ \u9009\u9879:`) + chalk9.gray(`
6677
+ 1. \u7EE7\u7EED\u5F53\u524D\u5DE5\u4F5C\u6D41: /opsx:${existingState.currentStep}`) + chalk9.gray(`
6678
+ 2. \u53D6\u6D88\u5F53\u524D\u5DE5\u4F5C\u6D41: /opsx:cancel`) + chalk9.gray(`
6679
+ 3. \u67E5\u770B\u5DE5\u4F5C\u6D41\u72B6\u6001: /opsx:status`)
6680
+ };
6681
+ }
6682
+ }
6625
6683
  const { requirement, forceComplexity } = parseArgs(args);
6626
6684
  if (!requirement) {
6627
6685
  return {
6628
6686
  output: chalk9.red("\u8BF7\u8F93\u5165\u9700\u6C42\u63CF\u8FF0") + chalk9.gray("\n\u7528\u6CD5: /new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray("\n\u9009\u9879:") + chalk9.gray("\n --simple \u5F3A\u5236\u4F7F\u7528\u7B80\u5355\u6D41\u7A0B") + chalk9.gray("\n --complex \u5F3A\u5236\u4F7F\u7528\u590D\u6742\u6D41\u7A0B")
6629
6687
  };
6630
6688
  }
6631
- return newFeature({ requirement, forceComplexity }, workingDir);
6689
+ return newFeature({ requirement, forceComplexity }, workingDir, workflowEngine);
6632
6690
  }
6633
- async function newFeature(options, workingDir) {
6691
+ async function newFeature(options, workingDir, workflowEngine) {
6634
6692
  const cwd = workingDir || process.cwd();
6635
6693
  const { requirement, forceComplexity } = options;
6636
6694
  try {
@@ -6648,8 +6706,10 @@ async function newFeature(options, workingDir) {
6648
6706
  try {
6649
6707
  const context = await readProjectContext(cwd);
6650
6708
  const analysis = forceComplexity ? createForcedAnalysis(forceComplexity) : analyzeComplexity(requirement, context);
6651
- const workflow = new WorkflowEngine();
6652
- await workflow.initialize(cwd);
6709
+ const workflow = workflowEngine || new WorkflowEngine();
6710
+ if (!workflowEngine) {
6711
+ await workflow.initialize(cwd);
6712
+ }
6653
6713
  const state = await workflow.start(requirement, analysis.score, {
6654
6714
  title: extractTitle(requirement)
6655
6715
  });
@@ -6703,13 +6763,13 @@ function parseArgs(args) {
6703
6763
  }
6704
6764
  async function readProjectContext(cwd) {
6705
6765
  const defaultContext = {
6706
- name: path4.basename(cwd),
6766
+ name: path5.basename(cwd),
6707
6767
  type: "unknown",
6708
6768
  framework: null,
6709
6769
  techStack: [],
6710
6770
  description: ""
6711
6771
  };
6712
- const agentsPath = path4.join(cwd, "AGENTS.md");
6772
+ const agentsPath = path5.join(cwd, "AGENTS.md");
6713
6773
  try {
6714
6774
  const stats = await fs4.stat(agentsPath);
6715
6775
  if (stats.size > MAX_FILE_SIZE2) {
@@ -6724,7 +6784,7 @@ async function readProjectContext(cwd) {
6724
6784
  console.warn(`\u8B66\u544A: \u65E0\u6CD5\u8BFB\u53D6 AGENTS.md - ${err.message}`);
6725
6785
  }
6726
6786
  }
6727
- const configPath = path4.join(cwd, "openspec", "config.yaml");
6787
+ const configPath = path5.join(cwd, "openspec", "config.yaml");
6728
6788
  try {
6729
6789
  const stats = await fs4.stat(configPath);
6730
6790
  if (stats.size > MAX_FILE_SIZE2) {
@@ -7205,6 +7265,9 @@ ${generateConfirmationPrompt(e.point)}`) + chalk9.cyan(`
7205
7265
  }
7206
7266
 
7207
7267
  // src/commands/runner.ts
7268
+ var packageJsonPath2 = path5.resolve(__dirname$1, "../../package.json");
7269
+ var packageJson2 = JSON.parse(fsSync.readFileSync(packageJsonPath2, "utf-8"));
7270
+ var VERSION2 = packageJson2.version;
7208
7271
  async function runSlashCommand(command, args, ctx) {
7209
7272
  const normalizedCommand = normalizeCommand(command);
7210
7273
  switch (normalizedCommand) {
@@ -7232,6 +7295,11 @@ async function runSlashCommand(command, args, ctx) {
7232
7295
  case "new":
7233
7296
  case "n":
7234
7297
  return handleNew(args, ctx);
7298
+ case "version":
7299
+ case "v":
7300
+ return {
7301
+ output: chalk9.cyan(`sf-cli v${VERSION2}`)
7302
+ };
7235
7303
  default:
7236
7304
  if (normalizedCommand.startsWith("opsx:")) {
7237
7305
  return handleOpsx(normalizedCommand, args, ctx);
@@ -7246,7 +7314,7 @@ function normalizeCommand(command) {
7246
7314
  }
7247
7315
  async function handleFileReference(filePath, ctx) {
7248
7316
  const cwd = ctx.options.workingDirectory;
7249
- const absolutePath = path4.isAbsolute(filePath) ? filePath : path4.join(cwd, filePath);
7317
+ const absolutePath = path5.isAbsolute(filePath) ? filePath : path5.join(cwd, filePath);
7250
7318
  try {
7251
7319
  const stats = await fs4.stat(absolutePath);
7252
7320
  if (stats.isDirectory()) {
@@ -7294,7 +7362,7 @@ async function executeShell(command, ctx) {
7294
7362
  \u547D\u4EE4 "${command}" \u53EF\u80FD\u4F1A\u5220\u9664\u91CD\u8981\u6587\u4EF6`) + chalk9.gray("\n\u4F7F\u7528 yolo \u6A21\u5F0F\u5F3A\u5236\u6267\u884C")
7295
7363
  };
7296
7364
  }
7297
- return new Promise((resolve2) => {
7365
+ return new Promise((resolve4) => {
7298
7366
  const shell = spawn(command, [], {
7299
7367
  shell: true,
7300
7368
  cwd: ctx.options.workingDirectory
@@ -7319,11 +7387,11 @@ async function executeShell(command, ctx) {
7319
7387
  output += chalk9.red(`
7320
7388
  \u9000\u51FA\u7801: ${code}`);
7321
7389
  }
7322
- resolve2({ output: output || chalk9.gray("(\u65E0\u8F93\u51FA)") });
7390
+ resolve4({ output: output || chalk9.gray("(\u65E0\u8F93\u51FA)") });
7323
7391
  });
7324
7392
  setTimeout(() => {
7325
7393
  shell.kill();
7326
- resolve2({
7394
+ resolve4({
7327
7395
  output: chalk9.yellow("\u547D\u4EE4\u6267\u884C\u8D85\u65F6\uFF0C\u5DF2\u7EC8\u6B62")
7328
7396
  });
7329
7397
  }, 6e4);
@@ -7342,12 +7410,75 @@ async function handleNaturalLanguage(input, ctx) {
7342
7410
  }
7343
7411
 
7344
7412
  // src/cli/executor.ts
7413
+ var ALLOWED_COMMANDS_WITHOUT_WORKFLOW = [
7414
+ "help",
7415
+ "h",
7416
+ "?",
7417
+ "init",
7418
+ "i",
7419
+ "model",
7420
+ "m",
7421
+ "new",
7422
+ "n",
7423
+ "exit",
7424
+ "e",
7425
+ "q",
7426
+ "quit",
7427
+ "clear",
7428
+ "c",
7429
+ "update",
7430
+ "u",
7431
+ "version",
7432
+ "v"
7433
+ ];
7434
+ var STAGE_PERMISSIONS = {
7435
+ "explore": {
7436
+ canRead: true,
7437
+ canWrite: false,
7438
+ canRunShell: false,
7439
+ allowedAgents: ["architect"]
7440
+ },
7441
+ "new": {
7442
+ canRead: true,
7443
+ canWrite: true,
7444
+ canRunShell: false,
7445
+ allowedAgents: ["frontend-dev", "architect"]
7446
+ },
7447
+ "continue": {
7448
+ canRead: true,
7449
+ canWrite: true,
7450
+ canRunShell: true,
7451
+ allowedAgents: ["frontend-dev", "tester"]
7452
+ },
7453
+ "propose": {
7454
+ canRead: true,
7455
+ canWrite: true,
7456
+ canRunShell: true,
7457
+ allowedAgents: ["frontend-dev"]
7458
+ },
7459
+ "apply": {
7460
+ canRead: true,
7461
+ canWrite: true,
7462
+ canRunShell: true,
7463
+ allowedAgents: ["code-reviewer"]
7464
+ },
7465
+ "archive": {
7466
+ canRead: true,
7467
+ canWrite: false,
7468
+ canRunShell: false,
7469
+ allowedAgents: []
7470
+ }
7471
+ };
7345
7472
  var CommandExecutor = class {
7346
7473
  async execute(parseResult, ctx) {
7347
7474
  if (!parseResult.success || !parseResult.command) {
7348
7475
  return { output: chalk9.red(`\u9519\u8BEF: ${parseResult.error}`) };
7349
7476
  }
7350
7477
  const { command } = parseResult;
7478
+ const workflowCheck = this.checkWorkflowPermission(command, ctx);
7479
+ if (!workflowCheck.allowed) {
7480
+ return { output: workflowCheck.message };
7481
+ }
7351
7482
  switch (command.type) {
7352
7483
  case "slash" /* SLASH */:
7353
7484
  return this.executeSlashCommand(command, ctx);
@@ -7365,13 +7496,75 @@ var CommandExecutor = class {
7365
7496
  return { output: chalk9.red("\u672A\u77E5\u7684\u547D\u4EE4\u7C7B\u578B") };
7366
7497
  }
7367
7498
  }
7499
+ /**
7500
+ * 检查工作流权限
7501
+ */
7502
+ checkWorkflowPermission(command, ctx) {
7503
+ const workflowEngine = ctx.workflowEngine;
7504
+ const workflowState = workflowEngine?.getState();
7505
+ if (!workflowState) {
7506
+ if (command.type === "slash" /* SLASH */) {
7507
+ const cmd = command.command?.toLowerCase();
7508
+ if (!ALLOWED_COMMANDS_WITHOUT_WORKFLOW.includes(cmd)) {
7509
+ return {
7510
+ allowed: false,
7511
+ message: chalk9.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
7512
+ };
7513
+ }
7514
+ }
7515
+ if (command.type === "natural" /* NATURAL */) {
7516
+ return {
7517
+ allowed: false,
7518
+ message: chalk9.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41") + chalk9.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
7519
+ };
7520
+ }
7521
+ if (command.type === "dollar" /* DOLLAR */) {
7522
+ return {
7523
+ allowed: false,
7524
+ message: chalk9.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41\uFF0C\u65E0\u6CD5\u8C03\u7528 Agent") + chalk9.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
7525
+ };
7526
+ }
7527
+ if (command.type === "shell" /* SHELL */) {
7528
+ return {
7529
+ allowed: false,
7530
+ message: chalk9.yellow("\u5F53\u524D\u6CA1\u6709\u6D3B\u8DC3\u7684\u5DE5\u4F5C\u6D41\uFF0C\u65E0\u6CD5\u6267\u884C Shell \u547D\u4EE4") + chalk9.gray("\n\u8BF7\u5148\u4F7F\u7528 ") + chalk9.cyan("/new <\u9700\u6C42\u63CF\u8FF0>") + chalk9.gray(" \u542F\u52A8\u65B0\u5DE5\u4F5C\u6D41")
7531
+ };
7532
+ }
7533
+ return { allowed: true };
7534
+ }
7535
+ const currentStep = workflowState.currentStep;
7536
+ const permissions = STAGE_PERMISSIONS[currentStep];
7537
+ if (command.type === "at" /* AT */ && !permissions.canRead) {
7538
+ return {
7539
+ allowed: false,
7540
+ message: chalk9.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u8BFB\u53D6\u6587\u4EF6`)
7541
+ };
7542
+ }
7543
+ if (command.type === "dollar" /* DOLLAR */) {
7544
+ const agentId = command.agent?.toLowerCase().replace("$", "");
7545
+ if (!permissions.allowedAgents.includes(agentId)) {
7546
+ return {
7547
+ allowed: false,
7548
+ message: chalk9.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u8C03\u7528 $${agentId} Agent`) + chalk9.gray(`
7549
+ \u5F53\u524D\u9636\u6BB5\u5141\u8BB8\u7684 Agent: ${permissions.allowedAgents.map((a) => `$${a}`).join(", ") || "\u65E0"}`)
7550
+ };
7551
+ }
7552
+ }
7553
+ if (command.type === "shell" /* SHELL */ && !permissions.canRunShell) {
7554
+ return {
7555
+ allowed: false,
7556
+ message: chalk9.yellow(`\u5F53\u524D\u9636\u6BB5 [${currentStep}] \u4E0D\u5141\u8BB8\u6267\u884C Shell \u547D\u4EE4`)
7557
+ };
7558
+ }
7559
+ return { allowed: true };
7560
+ }
7368
7561
  async executeSlashCommand(command, ctx) {
7369
7562
  const result = await runSlashCommand(
7370
7563
  command.command,
7371
7564
  command.args || [],
7372
7565
  ctx
7373
7566
  );
7374
- return { output: result.output };
7567
+ return { output: result.output, exit: result.exit };
7375
7568
  }
7376
7569
  async executeFileReference(command, ctx) {
7377
7570
  const result = await handleFileReference(command.path, ctx);
@@ -7505,7 +7698,7 @@ var Completer = class {
7505
7698
  prefix = filePath;
7506
7699
  } else {
7507
7700
  const dir = filePath.slice(0, lastSlash);
7508
- dirPath = path4.resolve(this.workingDirectory, dir);
7701
+ dirPath = path5.resolve(this.workingDirectory, dir);
7509
7702
  prefix = filePath.slice(lastSlash + 1);
7510
7703
  }
7511
7704
  try {
@@ -7515,7 +7708,7 @@ var Completer = class {
7515
7708
  if (entry.name.startsWith(prefix)) {
7516
7709
  const isDir = entry.isDirectory();
7517
7710
  matches.push({
7518
- text: "@" + path4.relative(this.workingDirectory, path4.join(dirPath, entry.name)).replace(/\\/g, "/") + (isDir ? "/" : ""),
7711
+ text: "@" + path5.relative(this.workingDirectory, path5.join(dirPath, entry.name)).replace(/\\/g, "/") + (isDir ? "/" : ""),
7519
7712
  displayText: entry.name + (isDir ? "/" : ""),
7520
7713
  description: isDir ? "\u76EE\u5F55" : "\u6587\u4EF6",
7521
7714
  type: isDir ? "directory" : "file"