rrce-workflow 0.2.15 → 0.2.16
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.js +148 -158
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -49,18 +49,6 @@ function getWorkspaceName(workspaceRoot) {
|
|
|
49
49
|
function getRRCEHome() {
|
|
50
50
|
return RRCE_HOME;
|
|
51
51
|
}
|
|
52
|
-
function listGlobalProjects(excludeWorkspace) {
|
|
53
|
-
const workspacesDir = path.join(RRCE_HOME, "workspaces");
|
|
54
|
-
if (!fs.existsSync(workspacesDir)) {
|
|
55
|
-
return [];
|
|
56
|
-
}
|
|
57
|
-
try {
|
|
58
|
-
const entries = fs.readdirSync(workspacesDir, { withFileTypes: true });
|
|
59
|
-
return entries.filter((entry) => entry.isDirectory() && entry.name !== excludeWorkspace).map((entry) => entry.name);
|
|
60
|
-
} catch {
|
|
61
|
-
return [];
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
52
|
function getLocalWorkspacePath(workspaceRoot) {
|
|
65
53
|
return path.join(workspaceRoot, ".rrce-workflow");
|
|
66
54
|
}
|
|
@@ -145,115 +133,9 @@ function getEffectiveRRCEHome(workspaceRoot) {
|
|
|
145
133
|
return getDefaultRRCEHome();
|
|
146
134
|
}
|
|
147
135
|
|
|
148
|
-
// src/
|
|
149
|
-
import { group, select, multiselect, confirm, spinner, note, outro, cancel, isCancel as isCancel2 } from "@clack/prompts";
|
|
150
|
-
import pc2 from "picocolors";
|
|
151
|
-
import * as fs7 from "fs";
|
|
152
|
-
import * as path7 from "path";
|
|
153
|
-
|
|
154
|
-
// src/lib/prompts.ts
|
|
136
|
+
// src/lib/detection.ts
|
|
155
137
|
import * as fs2 from "fs";
|
|
156
138
|
import * as path2 from "path";
|
|
157
|
-
import { fileURLToPath } from "url";
|
|
158
|
-
import matter from "gray-matter";
|
|
159
|
-
|
|
160
|
-
// src/types/prompt.ts
|
|
161
|
-
import { z } from "zod";
|
|
162
|
-
var PromptArgSchema = z.object({
|
|
163
|
-
name: z.string(),
|
|
164
|
-
default: z.string().optional(),
|
|
165
|
-
prompt: z.string().optional()
|
|
166
|
-
});
|
|
167
|
-
var AutoIdentitySchema = z.object({
|
|
168
|
-
user: z.string(),
|
|
169
|
-
model: z.string()
|
|
170
|
-
});
|
|
171
|
-
var PromptFrontmatterSchema = z.object({
|
|
172
|
-
name: z.string(),
|
|
173
|
-
description: z.string(),
|
|
174
|
-
"argument-hint": z.union([z.string(), z.array(z.string())]).optional(),
|
|
175
|
-
tools: z.array(z.string()).optional(),
|
|
176
|
-
"required-args": z.array(PromptArgSchema).optional(),
|
|
177
|
-
"optional-args": z.array(PromptArgSchema).optional(),
|
|
178
|
-
"auto-identity": AutoIdentitySchema.optional()
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// src/lib/prompts.ts
|
|
182
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
183
|
-
var __dirname = path2.dirname(__filename);
|
|
184
|
-
function parsePromptFile(filePath) {
|
|
185
|
-
try {
|
|
186
|
-
const fileContent = fs2.readFileSync(filePath, "utf-8");
|
|
187
|
-
const { data, content } = matter(fileContent);
|
|
188
|
-
const parsed = PromptFrontmatterSchema.safeParse(data);
|
|
189
|
-
if (!parsed.success) {
|
|
190
|
-
console.error(`Failed to parse frontmatter in ${filePath}:`, parsed.error);
|
|
191
|
-
return null;
|
|
192
|
-
}
|
|
193
|
-
return {
|
|
194
|
-
frontmatter: parsed.data,
|
|
195
|
-
content: content.trim(),
|
|
196
|
-
filePath
|
|
197
|
-
};
|
|
198
|
-
} catch (error) {
|
|
199
|
-
console.error(`Error reading prompt file ${filePath}:`, error);
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
function loadPromptsFromDir(dirPath) {
|
|
204
|
-
if (!fs2.existsSync(dirPath)) {
|
|
205
|
-
return [];
|
|
206
|
-
}
|
|
207
|
-
const files = fs2.readdirSync(dirPath).filter((f) => f.endsWith(".md"));
|
|
208
|
-
const prompts = [];
|
|
209
|
-
for (const file of files) {
|
|
210
|
-
const prompt = parsePromptFile(path2.join(dirPath, file));
|
|
211
|
-
if (prompt) {
|
|
212
|
-
prompts.push(prompt);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return prompts;
|
|
216
|
-
}
|
|
217
|
-
function getAgentCoreDir() {
|
|
218
|
-
return path2.join(__dirname, "..", "..", "agent-core");
|
|
219
|
-
}
|
|
220
|
-
function getAgentCorePromptsDir() {
|
|
221
|
-
return path2.join(getAgentCoreDir(), "prompts");
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// src/commands/wizard/utils.ts
|
|
225
|
-
import * as fs3 from "fs";
|
|
226
|
-
import * as path3 from "path";
|
|
227
|
-
function copyPromptsToDir(prompts, targetDir, extension) {
|
|
228
|
-
for (const prompt of prompts) {
|
|
229
|
-
const baseName = path3.basename(prompt.filePath, ".md");
|
|
230
|
-
const targetName = baseName + extension;
|
|
231
|
-
const targetPath = path3.join(targetDir, targetName);
|
|
232
|
-
const content = fs3.readFileSync(prompt.filePath, "utf-8");
|
|
233
|
-
fs3.writeFileSync(targetPath, content);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
function copyDirRecursive(src, dest) {
|
|
237
|
-
const entries = fs3.readdirSync(src, { withFileTypes: true });
|
|
238
|
-
for (const entry of entries) {
|
|
239
|
-
const srcPath = path3.join(src, entry.name);
|
|
240
|
-
const destPath = path3.join(dest, entry.name);
|
|
241
|
-
if (entry.isDirectory()) {
|
|
242
|
-
ensureDir(destPath);
|
|
243
|
-
copyDirRecursive(srcPath, destPath);
|
|
244
|
-
} else {
|
|
245
|
-
fs3.copyFileSync(srcPath, destPath);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// src/commands/wizard/vscode.ts
|
|
251
|
-
import * as fs5 from "fs";
|
|
252
|
-
import * as path5 from "path";
|
|
253
|
-
|
|
254
|
-
// src/lib/detection.ts
|
|
255
|
-
import * as fs4 from "fs";
|
|
256
|
-
import * as path4 from "path";
|
|
257
139
|
function scanForProjects(options = {}) {
|
|
258
140
|
const { excludeWorkspace, workspacePath, scanSiblings = true } = options;
|
|
259
141
|
const projects = [];
|
|
@@ -278,29 +160,29 @@ function scanForProjects(options = {}) {
|
|
|
278
160
|
}
|
|
279
161
|
function scanGlobalStorage(excludeWorkspace) {
|
|
280
162
|
const rrceHome = getDefaultRRCEHome();
|
|
281
|
-
const workspacesDir =
|
|
163
|
+
const workspacesDir = path2.join(rrceHome, "workspaces");
|
|
282
164
|
const projects = [];
|
|
283
|
-
if (!
|
|
165
|
+
if (!fs2.existsSync(workspacesDir)) {
|
|
284
166
|
return projects;
|
|
285
167
|
}
|
|
286
168
|
try {
|
|
287
|
-
const entries =
|
|
169
|
+
const entries = fs2.readdirSync(workspacesDir, { withFileTypes: true });
|
|
288
170
|
for (const entry of entries) {
|
|
289
171
|
if (!entry.isDirectory()) continue;
|
|
290
172
|
if (entry.name === excludeWorkspace) continue;
|
|
291
|
-
const projectDataPath =
|
|
292
|
-
const knowledgePath =
|
|
293
|
-
const refsPath =
|
|
294
|
-
const tasksPath =
|
|
173
|
+
const projectDataPath = path2.join(workspacesDir, entry.name);
|
|
174
|
+
const knowledgePath = path2.join(projectDataPath, "knowledge");
|
|
175
|
+
const refsPath = path2.join(projectDataPath, "refs");
|
|
176
|
+
const tasksPath = path2.join(projectDataPath, "tasks");
|
|
295
177
|
projects.push({
|
|
296
178
|
name: entry.name,
|
|
297
179
|
path: projectDataPath,
|
|
298
180
|
// For global projects, path is the data path
|
|
299
181
|
dataPath: projectDataPath,
|
|
300
182
|
source: "global",
|
|
301
|
-
knowledgePath:
|
|
302
|
-
refsPath:
|
|
303
|
-
tasksPath:
|
|
183
|
+
knowledgePath: fs2.existsSync(knowledgePath) ? knowledgePath : void 0,
|
|
184
|
+
refsPath: fs2.existsSync(refsPath) ? refsPath : void 0,
|
|
185
|
+
tasksPath: fs2.existsSync(tasksPath) ? tasksPath : void 0
|
|
304
186
|
});
|
|
305
187
|
}
|
|
306
188
|
} catch {
|
|
@@ -308,32 +190,32 @@ function scanGlobalStorage(excludeWorkspace) {
|
|
|
308
190
|
return projects;
|
|
309
191
|
}
|
|
310
192
|
function scanSiblingDirectories(workspacePath, excludeWorkspace) {
|
|
311
|
-
const parentDir =
|
|
193
|
+
const parentDir = path2.dirname(workspacePath);
|
|
312
194
|
const projects = [];
|
|
313
195
|
try {
|
|
314
|
-
const entries =
|
|
196
|
+
const entries = fs2.readdirSync(parentDir, { withFileTypes: true });
|
|
315
197
|
for (const entry of entries) {
|
|
316
198
|
if (!entry.isDirectory()) continue;
|
|
317
|
-
const projectPath =
|
|
199
|
+
const projectPath = path2.join(parentDir, entry.name);
|
|
318
200
|
if (projectPath === workspacePath) continue;
|
|
319
201
|
if (entry.name === excludeWorkspace) continue;
|
|
320
|
-
const configPath =
|
|
321
|
-
if (!
|
|
202
|
+
const configPath = path2.join(projectPath, ".rrce-workflow", "config.yaml");
|
|
203
|
+
if (!fs2.existsSync(configPath)) continue;
|
|
322
204
|
const config = parseWorkspaceConfig(configPath);
|
|
323
205
|
if (!config) continue;
|
|
324
|
-
const dataPath =
|
|
325
|
-
const knowledgePath =
|
|
326
|
-
const refsPath =
|
|
327
|
-
const tasksPath =
|
|
206
|
+
const dataPath = path2.join(projectPath, ".rrce-workflow");
|
|
207
|
+
const knowledgePath = path2.join(dataPath, "knowledge");
|
|
208
|
+
const refsPath = path2.join(dataPath, "refs");
|
|
209
|
+
const tasksPath = path2.join(dataPath, "tasks");
|
|
328
210
|
projects.push({
|
|
329
211
|
name: config.name || entry.name,
|
|
330
212
|
path: projectPath,
|
|
331
213
|
dataPath,
|
|
332
214
|
source: "sibling",
|
|
333
215
|
storageMode: config.storageMode,
|
|
334
|
-
knowledgePath:
|
|
335
|
-
refsPath:
|
|
336
|
-
tasksPath:
|
|
216
|
+
knowledgePath: fs2.existsSync(knowledgePath) ? knowledgePath : void 0,
|
|
217
|
+
refsPath: fs2.existsSync(refsPath) ? refsPath : void 0,
|
|
218
|
+
tasksPath: fs2.existsSync(tasksPath) ? tasksPath : void 0
|
|
337
219
|
});
|
|
338
220
|
}
|
|
339
221
|
} catch {
|
|
@@ -342,7 +224,7 @@ function scanSiblingDirectories(workspacePath, excludeWorkspace) {
|
|
|
342
224
|
}
|
|
343
225
|
function parseWorkspaceConfig(configPath) {
|
|
344
226
|
try {
|
|
345
|
-
const content =
|
|
227
|
+
const content = fs2.readFileSync(configPath, "utf-8");
|
|
346
228
|
const nameMatch = content.match(/name:\s*["']?([^"'\n]+)["']?/);
|
|
347
229
|
const modeMatch = content.match(/mode:\s*(global|workspace|both)/);
|
|
348
230
|
const linkedProjects = [];
|
|
@@ -357,7 +239,7 @@ function parseWorkspaceConfig(configPath) {
|
|
|
357
239
|
}
|
|
358
240
|
}
|
|
359
241
|
return {
|
|
360
|
-
name: nameMatch?.[1]?.trim() ||
|
|
242
|
+
name: nameMatch?.[1]?.trim() || path2.basename(path2.dirname(path2.dirname(configPath))),
|
|
361
243
|
storageMode: modeMatch?.[1] || "global",
|
|
362
244
|
linkedProjects: linkedProjects.length > 0 ? linkedProjects : void 0
|
|
363
245
|
};
|
|
@@ -401,7 +283,111 @@ function getProjectFolders(project) {
|
|
|
401
283
|
return folders;
|
|
402
284
|
}
|
|
403
285
|
|
|
286
|
+
// src/commands/wizard/setup-flow.ts
|
|
287
|
+
import { group, select, multiselect, confirm, spinner, note, outro, cancel, isCancel as isCancel2 } from "@clack/prompts";
|
|
288
|
+
import pc2 from "picocolors";
|
|
289
|
+
import * as fs7 from "fs";
|
|
290
|
+
import * as path7 from "path";
|
|
291
|
+
|
|
292
|
+
// src/lib/prompts.ts
|
|
293
|
+
import * as fs3 from "fs";
|
|
294
|
+
import * as path3 from "path";
|
|
295
|
+
import { fileURLToPath } from "url";
|
|
296
|
+
import matter from "gray-matter";
|
|
297
|
+
|
|
298
|
+
// src/types/prompt.ts
|
|
299
|
+
import { z } from "zod";
|
|
300
|
+
var PromptArgSchema = z.object({
|
|
301
|
+
name: z.string(),
|
|
302
|
+
default: z.string().optional(),
|
|
303
|
+
prompt: z.string().optional()
|
|
304
|
+
});
|
|
305
|
+
var AutoIdentitySchema = z.object({
|
|
306
|
+
user: z.string(),
|
|
307
|
+
model: z.string()
|
|
308
|
+
});
|
|
309
|
+
var PromptFrontmatterSchema = z.object({
|
|
310
|
+
name: z.string(),
|
|
311
|
+
description: z.string(),
|
|
312
|
+
"argument-hint": z.union([z.string(), z.array(z.string())]).optional(),
|
|
313
|
+
tools: z.array(z.string()).optional(),
|
|
314
|
+
"required-args": z.array(PromptArgSchema).optional(),
|
|
315
|
+
"optional-args": z.array(PromptArgSchema).optional(),
|
|
316
|
+
"auto-identity": AutoIdentitySchema.optional()
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// src/lib/prompts.ts
|
|
320
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
321
|
+
var __dirname = path3.dirname(__filename);
|
|
322
|
+
function parsePromptFile(filePath) {
|
|
323
|
+
try {
|
|
324
|
+
const fileContent = fs3.readFileSync(filePath, "utf-8");
|
|
325
|
+
const { data, content } = matter(fileContent);
|
|
326
|
+
const parsed = PromptFrontmatterSchema.safeParse(data);
|
|
327
|
+
if (!parsed.success) {
|
|
328
|
+
console.error(`Failed to parse frontmatter in ${filePath}:`, parsed.error);
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
frontmatter: parsed.data,
|
|
333
|
+
content: content.trim(),
|
|
334
|
+
filePath
|
|
335
|
+
};
|
|
336
|
+
} catch (error) {
|
|
337
|
+
console.error(`Error reading prompt file ${filePath}:`, error);
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function loadPromptsFromDir(dirPath) {
|
|
342
|
+
if (!fs3.existsSync(dirPath)) {
|
|
343
|
+
return [];
|
|
344
|
+
}
|
|
345
|
+
const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".md"));
|
|
346
|
+
const prompts = [];
|
|
347
|
+
for (const file of files) {
|
|
348
|
+
const prompt = parsePromptFile(path3.join(dirPath, file));
|
|
349
|
+
if (prompt) {
|
|
350
|
+
prompts.push(prompt);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return prompts;
|
|
354
|
+
}
|
|
355
|
+
function getAgentCoreDir() {
|
|
356
|
+
return path3.join(__dirname, "..", "..", "agent-core");
|
|
357
|
+
}
|
|
358
|
+
function getAgentCorePromptsDir() {
|
|
359
|
+
return path3.join(getAgentCoreDir(), "prompts");
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/commands/wizard/utils.ts
|
|
363
|
+
import * as fs4 from "fs";
|
|
364
|
+
import * as path4 from "path";
|
|
365
|
+
function copyPromptsToDir(prompts, targetDir, extension) {
|
|
366
|
+
for (const prompt of prompts) {
|
|
367
|
+
const baseName = path4.basename(prompt.filePath, ".md");
|
|
368
|
+
const targetName = baseName + extension;
|
|
369
|
+
const targetPath = path4.join(targetDir, targetName);
|
|
370
|
+
const content = fs4.readFileSync(prompt.filePath, "utf-8");
|
|
371
|
+
fs4.writeFileSync(targetPath, content);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function copyDirRecursive(src, dest) {
|
|
375
|
+
const entries = fs4.readdirSync(src, { withFileTypes: true });
|
|
376
|
+
for (const entry of entries) {
|
|
377
|
+
const srcPath = path4.join(src, entry.name);
|
|
378
|
+
const destPath = path4.join(dest, entry.name);
|
|
379
|
+
if (entry.isDirectory()) {
|
|
380
|
+
ensureDir(destPath);
|
|
381
|
+
copyDirRecursive(srcPath, destPath);
|
|
382
|
+
} else {
|
|
383
|
+
fs4.copyFileSync(srcPath, destPath);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
404
388
|
// src/commands/wizard/vscode.ts
|
|
389
|
+
import * as fs5 from "fs";
|
|
390
|
+
import * as path5 from "path";
|
|
405
391
|
var REFERENCE_GROUP_PREFIX = "\u{1F4C1} References";
|
|
406
392
|
function generateVSCodeWorkspace(workspacePath, workspaceName, linkedProjects, customGlobalPath) {
|
|
407
393
|
const workspaceFilePath = path5.join(workspacePath, `${workspaceName}.code-workspace`);
|
|
@@ -647,10 +633,10 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
647
633
|
}
|
|
648
634
|
return multiselect({
|
|
649
635
|
message: "Link knowledge from other projects?",
|
|
650
|
-
options: existingProjects.map((
|
|
651
|
-
value: name,
|
|
652
|
-
label: name,
|
|
653
|
-
hint:
|
|
636
|
+
options: existingProjects.map((project) => ({
|
|
637
|
+
value: project.name,
|
|
638
|
+
label: project.name,
|
|
639
|
+
hint: pc2.dim(getProjectDisplayLabel(project))
|
|
654
640
|
})),
|
|
655
641
|
required: false
|
|
656
642
|
});
|
|
@@ -686,7 +672,7 @@ async function runSetupFlow(workspacePath, workspaceName, existingProjects) {
|
|
|
686
672
|
globalPath: customGlobalPath,
|
|
687
673
|
tools: config.tools,
|
|
688
674
|
linkedProjects: config.linkedProjects
|
|
689
|
-
}, workspacePath, workspaceName);
|
|
675
|
+
}, workspacePath, workspaceName, existingProjects);
|
|
690
676
|
s.stop("Configuration generated");
|
|
691
677
|
const dataPaths = getDataPaths(
|
|
692
678
|
config.storageMode,
|
|
@@ -782,7 +768,7 @@ Please choose a custom path instead.`,
|
|
|
782
768
|
}
|
|
783
769
|
return customPath;
|
|
784
770
|
}
|
|
785
|
-
async function generateConfiguration(config, workspacePath, workspaceName) {
|
|
771
|
+
async function generateConfiguration(config, workspacePath, workspaceName, allProjects = []) {
|
|
786
772
|
const dataPaths = getDataPaths(config.storageMode, workspaceName, workspacePath, config.globalPath);
|
|
787
773
|
for (const dataPath of dataPaths) {
|
|
788
774
|
ensureDir(dataPath);
|
|
@@ -836,7 +822,8 @@ linked_projects:
|
|
|
836
822
|
}
|
|
837
823
|
fs7.writeFileSync(workspaceConfigPath, configContent);
|
|
838
824
|
if (config.tools.includes("copilot") || config.linkedProjects.length > 0) {
|
|
839
|
-
|
|
825
|
+
const selectedProjects = allProjects.filter((p) => config.linkedProjects.includes(p.name));
|
|
826
|
+
generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, config.globalPath);
|
|
840
827
|
}
|
|
841
828
|
}
|
|
842
829
|
function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
@@ -858,13 +845,12 @@ function getDataPaths(mode, workspaceName, workspaceRoot, customGlobalPath) {
|
|
|
858
845
|
import { multiselect as multiselect2, spinner as spinner2, note as note2, outro as outro2, cancel as cancel2, isCancel as isCancel3 } from "@clack/prompts";
|
|
859
846
|
import pc3 from "picocolors";
|
|
860
847
|
import * as fs8 from "fs";
|
|
861
|
-
async function runLinkProjectsFlow(workspacePath, workspaceName
|
|
862
|
-
const
|
|
848
|
+
async function runLinkProjectsFlow(workspacePath, workspaceName) {
|
|
849
|
+
const projects = scanForProjects({
|
|
863
850
|
excludeWorkspace: workspaceName,
|
|
864
851
|
workspacePath,
|
|
865
852
|
scanSiblings: true
|
|
866
853
|
});
|
|
867
|
-
const projects = existingProjects ? existingProjects.map((name) => ({ name, source: "global" })) : detectedProjects;
|
|
868
854
|
if (projects.length === 0) {
|
|
869
855
|
outro2(pc3.yellow("No other projects found. Try setting up another project first."));
|
|
870
856
|
return;
|
|
@@ -1093,7 +1079,11 @@ async function runWizard() {
|
|
|
1093
1079
|
Workspace: ${pc6.bold(workspaceName)}`,
|
|
1094
1080
|
"Context"
|
|
1095
1081
|
);
|
|
1096
|
-
const
|
|
1082
|
+
const detectedProjects = scanForProjects({
|
|
1083
|
+
excludeWorkspace: workspaceName,
|
|
1084
|
+
workspacePath,
|
|
1085
|
+
scanSiblings: true
|
|
1086
|
+
});
|
|
1097
1087
|
const configFilePath = getConfigPath(workspacePath);
|
|
1098
1088
|
const isAlreadyConfigured = fs11.existsSync(configFilePath);
|
|
1099
1089
|
let currentStorageMode = null;
|
|
@@ -1109,11 +1099,11 @@ Workspace: ${pc6.bold(workspaceName)}`,
|
|
|
1109
1099
|
const hasLocalData = fs11.existsSync(localDataPath);
|
|
1110
1100
|
if (isAlreadyConfigured) {
|
|
1111
1101
|
const menuOptions = [];
|
|
1112
|
-
if (
|
|
1102
|
+
if (detectedProjects.length > 0) {
|
|
1113
1103
|
menuOptions.push({
|
|
1114
1104
|
value: "link",
|
|
1115
1105
|
label: "Link other project knowledge",
|
|
1116
|
-
hint: `${
|
|
1106
|
+
hint: `${detectedProjects.length} projects detected (global + sibling)`
|
|
1117
1107
|
});
|
|
1118
1108
|
}
|
|
1119
1109
|
if (currentStorageMode === "workspace" && hasLocalData) {
|
|
@@ -1134,7 +1124,7 @@ Workspace: ${pc6.bold(workspaceName)}`,
|
|
|
1134
1124
|
process.exit(0);
|
|
1135
1125
|
}
|
|
1136
1126
|
if (action === "link") {
|
|
1137
|
-
await runLinkProjectsFlow(workspacePath, workspaceName
|
|
1127
|
+
await runLinkProjectsFlow(workspacePath, workspaceName);
|
|
1138
1128
|
return;
|
|
1139
1129
|
}
|
|
1140
1130
|
if (action === "sync-global") {
|
|
@@ -1146,7 +1136,7 @@ Workspace: ${pc6.bold(workspaceName)}`,
|
|
|
1146
1136
|
return;
|
|
1147
1137
|
}
|
|
1148
1138
|
}
|
|
1149
|
-
await runSetupFlow(workspacePath, workspaceName,
|
|
1139
|
+
await runSetupFlow(workspacePath, workspaceName, detectedProjects);
|
|
1150
1140
|
}
|
|
1151
1141
|
|
|
1152
1142
|
// src/commands/selector.ts
|