rrce-workflow 0.3.37 → 0.3.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +5 -0
  2. package/dist/index.js +223 -73
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -29,6 +29,11 @@ cd your-project
29
29
  npx rrce-workflow
30
30
  ```
31
31
 
32
+ Alias:
33
+ ```bash
34
+ npx rrce-workflow install
35
+ ```
36
+
32
37
  This launches the setup wizard and can:
33
38
  - Create the `.rrce-workflow/` structure (workspace mode) or initialize global storage (global mode)
34
39
  - Install IDE integrations (VSCode / Claude Desktop / OpenCode / Antigravity)
package/dist/index.js CHANGED
@@ -1728,6 +1728,8 @@ var init_logger = __esm({
1728
1728
  init_paths();
1729
1729
  Logger = class {
1730
1730
  logPath;
1731
+ maxBytes = 2 * 1024 * 1024;
1732
+ trimToBytes = 512 * 1024;
1731
1733
  constructor() {
1732
1734
  this.logPath = getLogFilePath();
1733
1735
  }
@@ -1754,12 +1756,30 @@ ${JSON.stringify(data, null, 2)}`;
1754
1756
  if (!fs13.existsSync(dir)) {
1755
1757
  fs13.mkdirSync(dir, { recursive: true });
1756
1758
  }
1759
+ this.trimIfNeeded();
1757
1760
  fs13.appendFileSync(this.logPath, logMessage);
1758
1761
  } catch (e) {
1759
1762
  console.error(`[Logger Failure] Could not write to ${this.logPath}`, e);
1760
1763
  console.error(logMessage);
1761
1764
  }
1762
1765
  }
1766
+ trimIfNeeded() {
1767
+ try {
1768
+ if (!fs13.existsSync(this.logPath)) return;
1769
+ const stats = fs13.statSync(this.logPath);
1770
+ if (stats.size <= this.maxBytes) return;
1771
+ const start = Math.max(0, stats.size - this.trimToBytes);
1772
+ const fd = fs13.openSync(this.logPath, "r");
1773
+ const buffer = Buffer.alloc(stats.size - start);
1774
+ fs13.readSync(fd, buffer, 0, buffer.length, start);
1775
+ fs13.closeSync(fd);
1776
+ const header = `[${(/* @__PURE__ */ new Date()).toISOString()}] [INFO] Log truncated to last ${this.trimToBytes} bytes
1777
+ `;
1778
+ fs13.writeFileSync(this.logPath, header + buffer.toString("utf-8"));
1779
+ } catch (e) {
1780
+ console.error(`[Logger Failure] Could not trim ${this.logPath}`, e);
1781
+ }
1782
+ }
1763
1783
  info(message, data) {
1764
1784
  this.write("INFO", message, data);
1765
1785
  }
@@ -1924,6 +1944,13 @@ function resolveProjectPaths(project, pathInput) {
1924
1944
  const projConfig = findProjectConfig(config, { name: project });
1925
1945
  if (projConfig?.path) {
1926
1946
  workspaceRoot = projConfig.path;
1947
+ } else {
1948
+ const knownProjects = config.projects.filter((p) => !!p.path).map((p) => ({ name: p.name, path: p.path }));
1949
+ const projects = projectService.scan({ knownProjects });
1950
+ const match = projects.find((p) => p.name === project);
1951
+ if (match) {
1952
+ workspaceRoot = match.sourcePath || match.path;
1953
+ }
1927
1954
  }
1928
1955
  }
1929
1956
  if (workspaceRoot && workspaceRoot.includes("/workspaces/")) {
@@ -1941,7 +1968,14 @@ function resolveProjectPaths(project, pathInput) {
1941
1968
  }
1942
1969
  if (!workspaceName && workspaceRoot) {
1943
1970
  const projConfig = findProjectConfig(config, { path: workspaceRoot });
1944
- workspaceName = projConfig?.name || getWorkspaceName(workspaceRoot);
1971
+ if (projConfig?.name) {
1972
+ workspaceName = projConfig.name;
1973
+ } else {
1974
+ const knownProjects = config.projects.filter((p) => !!p.path).map((p) => ({ name: p.name, path: p.path }));
1975
+ const projects = projectService.scan({ knownProjects });
1976
+ const closest = findClosestProject(projects, workspaceRoot);
1977
+ workspaceName = closest?.name || getWorkspaceName(workspaceRoot);
1978
+ }
1945
1979
  }
1946
1980
  if (!workspaceName) {
1947
1981
  workspaceName = "unknown";
@@ -1980,6 +2014,8 @@ var init_paths2 = __esm({
1980
2014
  "use strict";
1981
2015
  init_config();
1982
2016
  init_config_utils();
2017
+ init_detection_service();
2018
+ init_detection();
1983
2019
  init_paths();
1984
2020
  }
1985
2021
  });
@@ -5448,6 +5484,7 @@ import {
5448
5484
  ListToolsRequestSchema,
5449
5485
  CallToolRequestSchema
5450
5486
  } from "@modelcontextprotocol/sdk/types.js";
5487
+ import * as path29 from "path";
5451
5488
  function registerToolHandlers(server) {
5452
5489
  server.setRequestHandler(ListToolsRequestSchema, async () => {
5453
5490
  const tools = [
@@ -5470,19 +5507,20 @@ function registerToolHandlers(server) {
5470
5507
  });
5471
5508
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
5472
5509
  const { name, arguments: args } = request.params;
5473
- logger.info(`Calling tool: ${name}`, args);
5510
+ const argsWithCaller = applyCallerContext(name, args, request);
5511
+ logger.info(`Calling tool: ${name}`, argsWithCaller);
5474
5512
  try {
5475
- const projectResult = await handleProjectTool(name, args);
5513
+ const projectResult = await handleProjectTool(name, argsWithCaller);
5476
5514
  if (projectResult) return projectResult;
5477
- const searchResult = await handleSearchTool(name, args);
5515
+ const searchResult = await handleSearchTool(name, argsWithCaller);
5478
5516
  if (searchResult) return searchResult;
5479
- const taskResult = await handleTaskTool(name, args);
5517
+ const taskResult = await handleTaskTool(name, argsWithCaller);
5480
5518
  if (taskResult) return taskResult;
5481
- const sessionResult = await handleSessionTool(name, args);
5519
+ const sessionResult = await handleSessionTool(name, argsWithCaller);
5482
5520
  if (sessionResult) return sessionResult;
5483
- const agentResult = await handleAgentTool(name, args);
5521
+ const agentResult = await handleAgentTool(name, argsWithCaller);
5484
5522
  if (agentResult) return agentResult;
5485
- const cleanupResult = await handleCleanupTool(name, args);
5523
+ const cleanupResult = await handleCleanupTool(name, argsWithCaller);
5486
5524
  if (cleanupResult) return cleanupResult;
5487
5525
  throw new Error(`Unknown tool: ${name}`);
5488
5526
  } catch (error) {
@@ -5491,11 +5529,72 @@ function registerToolHandlers(server) {
5491
5529
  }
5492
5530
  });
5493
5531
  }
5532
+ function applyCallerContext(toolName, args, request) {
5533
+ const callerPath = getCallerPath(request);
5534
+ if (!callerPath) return args;
5535
+ const callerProject = resolveCallerProject(callerPath);
5536
+ if (!callerProject) return args;
5537
+ const nextArgs = { ...args || {} };
5538
+ if (!nextArgs.project && callerProject.project) {
5539
+ nextArgs.project = callerProject.project;
5540
+ }
5541
+ if (!nextArgs.path && toolName === "resolve_path" && callerProject.path) {
5542
+ nextArgs.path = callerProject.path;
5543
+ }
5544
+ return nextArgs;
5545
+ }
5546
+ function getCallerPath(request) {
5547
+ const params = request.params;
5548
+ const meta = params?._meta || request._meta || request.meta;
5549
+ const caller = meta?.caller || meta?.client || meta?.source || meta?.requester || meta;
5550
+ const candidates = [
5551
+ caller?.workspaceRoot,
5552
+ caller?.workspace_root,
5553
+ caller?.projectPath,
5554
+ caller?.project_path,
5555
+ caller?.cwd,
5556
+ caller?.root,
5557
+ caller?.path,
5558
+ meta?.workspaceRoot,
5559
+ meta?.workspace_root,
5560
+ meta?.projectPath,
5561
+ meta?.project_path,
5562
+ meta?.cwd,
5563
+ meta?.root,
5564
+ meta?.path
5565
+ ];
5566
+ for (const value of candidates) {
5567
+ if (typeof value === "string" && value.trim().length > 0) {
5568
+ return value.trim();
5569
+ }
5570
+ }
5571
+ return void 0;
5572
+ }
5573
+ function resolveCallerProject(callerPath) {
5574
+ const config = configService.load();
5575
+ const knownProjects = config.projects.filter((p) => !!p.path).map((p) => ({ name: p.name, path: p.path }));
5576
+ const projects = projectService.scan({ knownProjects });
5577
+ const exposed = projects.filter((p) => isProjectExposed(config, p.name, p.sourcePath || p.path));
5578
+ const closest = findClosestProject(exposed, callerPath);
5579
+ if (closest) {
5580
+ return { project: closest.name, path: closest.sourcePath || closest.path };
5581
+ }
5582
+ if (callerPath) {
5583
+ const fallbackName = path29.basename(callerPath);
5584
+ if (fallbackName) {
5585
+ return { project: fallbackName, path: callerPath };
5586
+ }
5587
+ }
5588
+ return void 0;
5589
+ }
5494
5590
  var init_tools = __esm({
5495
5591
  "src/mcp/handlers/tools.ts"() {
5496
5592
  "use strict";
5497
5593
  init_logger();
5498
5594
  init_resources2();
5595
+ init_config();
5596
+ init_detection_service();
5597
+ init_detection();
5499
5598
  init_project();
5500
5599
  init_search2();
5501
5600
  init_task();
@@ -5748,7 +5847,7 @@ Hidden projects: ${projects.length - exposedCount}`,
5748
5847
  async function handleConfigureGlobalPath() {
5749
5848
  const { resolveGlobalPath: resolveGlobalPath2 } = await Promise.resolve().then(() => (init_tui_utils(), tui_utils_exports));
5750
5849
  const fs36 = await import("fs");
5751
- const path35 = await import("path");
5850
+ const path36 = await import("path");
5752
5851
  note3(
5753
5852
  `MCP Hub requires a ${pc5.bold("global storage path")} to store its configuration
5754
5853
  and coordinate across projects.
@@ -5771,7 +5870,7 @@ locally in each project. MCP needs a central location.`,
5771
5870
  `${pc5.green("\u2713")} Global path configured: ${pc5.cyan(resolvedPath)}
5772
5871
 
5773
5872
  MCP config will be stored at:
5774
- ${path35.join(resolvedPath, "mcp.yaml")}`,
5873
+ ${path36.join(resolvedPath, "mcp.yaml")}`,
5775
5874
  "Configuration Saved"
5776
5875
  );
5777
5876
  return true;
@@ -5876,12 +5975,12 @@ __export(ConfigContext_exports, {
5876
5975
  });
5877
5976
  import { createContext, useContext, useState, useCallback, useMemo, useEffect } from "react";
5878
5977
  import * as fs27 from "fs";
5879
- import * as path29 from "path";
5978
+ import * as path30 from "path";
5880
5979
  import { jsx as jsx2 } from "react/jsx-runtime";
5881
5980
  function getPackageVersion() {
5882
5981
  try {
5883
5982
  const agentCoreDir = getAgentCoreDir();
5884
- const packageJsonPath = path29.join(path29.dirname(agentCoreDir), "package.json");
5983
+ const packageJsonPath = path30.join(path30.dirname(agentCoreDir), "package.json");
5885
5984
  if (fs27.existsSync(packageJsonPath)) {
5886
5985
  return JSON.parse(fs27.readFileSync(packageJsonPath, "utf8")).version;
5887
5986
  }
@@ -5951,10 +6050,10 @@ var init_ConfigContext = __esm({
5951
6050
 
5952
6051
  // src/mcp/ui/lib/tasks-fs.ts
5953
6052
  import * as fs28 from "fs";
5954
- import * as path30 from "path";
6053
+ import * as path31 from "path";
5955
6054
  function readSession(project, taskSlug) {
5956
6055
  const rrceData = getProjectRRCEData(project);
5957
- const sessionPath = path30.join(rrceData, "tasks", taskSlug, "session.json");
6056
+ const sessionPath = path31.join(rrceData, "tasks", taskSlug, "session.json");
5958
6057
  if (!fs28.existsSync(sessionPath)) {
5959
6058
  return null;
5960
6059
  }
@@ -5972,7 +6071,7 @@ function isSessionStale(session, thresholdMs = SESSION_STALE_THRESHOLD_MS) {
5972
6071
  }
5973
6072
  function readAgentTodos(project, taskSlug) {
5974
6073
  const rrceData = getProjectRRCEData(project);
5975
- const todosPath = path30.join(rrceData, "tasks", taskSlug, "agent-todos.json");
6074
+ const todosPath = path31.join(rrceData, "tasks", taskSlug, "agent-todos.json");
5976
6075
  if (!fs28.existsSync(todosPath)) {
5977
6076
  return null;
5978
6077
  }
@@ -6001,7 +6100,7 @@ function detectStorageModeFromConfig(workspaceRoot) {
6001
6100
  }
6002
6101
  function getEffectiveGlobalBase() {
6003
6102
  const dummy = resolveDataPath("global", "__rrce_dummy__", "");
6004
- return path30.dirname(path30.dirname(dummy));
6103
+ return path31.dirname(path31.dirname(dummy));
6005
6104
  }
6006
6105
  function getProjectRRCEData(project) {
6007
6106
  const workspaceRoot = project.sourcePath || project.path;
@@ -6010,7 +6109,7 @@ function getProjectRRCEData(project) {
6010
6109
  }
6011
6110
  function listProjectTasks(project) {
6012
6111
  const rrceData = getProjectRRCEData(project);
6013
- const tasksPath = path30.join(rrceData, "tasks");
6112
+ const tasksPath = path31.join(rrceData, "tasks");
6014
6113
  if (!fs28.existsSync(tasksPath)) {
6015
6114
  return { projectName: project.name, tasksPath, tasks: [] };
6016
6115
  }
@@ -6019,7 +6118,7 @@ function listProjectTasks(project) {
6019
6118
  const entries = fs28.readdirSync(tasksPath, { withFileTypes: true });
6020
6119
  for (const entry of entries) {
6021
6120
  if (!entry.isDirectory()) continue;
6022
- const metaPath = path30.join(tasksPath, entry.name, "meta.json");
6121
+ const metaPath = path31.join(tasksPath, entry.name, "meta.json");
6023
6122
  if (!fs28.existsSync(metaPath)) continue;
6024
6123
  try {
6025
6124
  const raw = fs28.readFileSync(metaPath, "utf-8");
@@ -6041,7 +6140,7 @@ function listProjectTasks(project) {
6041
6140
  }
6042
6141
  function updateTaskStatus(project, taskSlug, status) {
6043
6142
  const rrceData = getProjectRRCEData(project);
6044
- const metaPath = path30.join(rrceData, "tasks", taskSlug, "meta.json");
6143
+ const metaPath = path31.join(rrceData, "tasks", taskSlug, "meta.json");
6045
6144
  if (!fs28.existsSync(metaPath)) {
6046
6145
  return { ok: false, error: `meta.json not found for task '${taskSlug}'` };
6047
6146
  }
@@ -6438,14 +6537,14 @@ var init_ProjectViews = __esm({
6438
6537
 
6439
6538
  // src/mcp/ui/lib/projects.ts
6440
6539
  import * as fs29 from "fs";
6441
- import * as path31 from "path";
6540
+ import * as path32 from "path";
6442
6541
  function getIndexStats(project) {
6443
6542
  const stats = { knowledgeCount: 0, codeCount: 0, lastIndexed: null };
6444
6543
  try {
6445
6544
  const knowledgePath = project.knowledgePath;
6446
6545
  if (knowledgePath) {
6447
- const embPath = path31.join(knowledgePath, "embeddings.json");
6448
- const codeEmbPath = path31.join(knowledgePath, "code-embeddings.json");
6546
+ const embPath = path32.join(knowledgePath, "embeddings.json");
6547
+ const codeEmbPath = path32.join(knowledgePath, "code-embeddings.json");
6449
6548
  if (fs29.existsSync(embPath)) {
6450
6549
  const stat = fs29.statSync(embPath);
6451
6550
  stats.lastIndexed = stat.mtime.toISOString();
@@ -7274,27 +7373,46 @@ var init_App = __esm({
7274
7373
  }, []);
7275
7374
  useEffect6(() => {
7276
7375
  const logPath = getLogFilePath();
7376
+ const maxLines = 100;
7377
+ const tailBytes = 64 * 1024;
7277
7378
  let lastSize = 0;
7278
- if (fs30.existsSync(logPath)) {
7379
+ const loadTail = () => {
7380
+ if (!fs30.existsSync(logPath)) {
7381
+ setLogs([]);
7382
+ lastSize = 0;
7383
+ return;
7384
+ }
7279
7385
  const stats = fs30.statSync(logPath);
7386
+ const start = Math.max(0, stats.size - tailBytes);
7387
+ const buffer = Buffer.alloc(stats.size - start);
7388
+ const fd = fs30.openSync(logPath, "r");
7389
+ fs30.readSync(fd, buffer, 0, buffer.length, start);
7390
+ fs30.closeSync(fd);
7391
+ const content = buffer.toString("utf-8");
7392
+ const lines = content.split("\n").filter((l) => l.trim());
7393
+ setLogs(lines.slice(-maxLines));
7280
7394
  lastSize = stats.size;
7281
- }
7395
+ };
7396
+ loadTail();
7282
7397
  const interval = setInterval(() => {
7283
- if (fs30.existsSync(logPath)) {
7284
- const stats = fs30.statSync(logPath);
7285
- if (stats.size > lastSize) {
7286
- const buffer = Buffer.alloc(stats.size - lastSize);
7287
- const fd = fs30.openSync(logPath, "r");
7288
- fs30.readSync(fd, buffer, 0, buffer.length, lastSize);
7289
- fs30.closeSync(fd);
7290
- const newContent = buffer.toString("utf-8");
7291
- const newLines = newContent.split("\n").filter((l) => l.trim());
7292
- setLogs((prev) => {
7293
- const next = [...prev, ...newLines];
7294
- return next.slice(-100);
7295
- });
7296
- lastSize = stats.size;
7297
- }
7398
+ if (!fs30.existsSync(logPath)) return;
7399
+ const stats = fs30.statSync(logPath);
7400
+ if (stats.size < lastSize) {
7401
+ loadTail();
7402
+ return;
7403
+ }
7404
+ if (stats.size > lastSize) {
7405
+ const buffer = Buffer.alloc(stats.size - lastSize);
7406
+ const fd = fs30.openSync(logPath, "r");
7407
+ fs30.readSync(fd, buffer, 0, buffer.length, lastSize);
7408
+ fs30.closeSync(fd);
7409
+ const newContent = buffer.toString("utf-8");
7410
+ const newLines = newContent.split("\n").filter((l) => l.trim());
7411
+ setLogs((prev) => {
7412
+ const next = [...prev, ...newLines];
7413
+ return next.slice(-maxLines);
7414
+ });
7415
+ lastSize = stats.size;
7298
7416
  }
7299
7417
  }, 500);
7300
7418
  return () => clearInterval(interval);
@@ -7512,8 +7630,38 @@ __export(update_flow_exports, {
7512
7630
  import { confirm as confirm5, spinner as spinner2, note as note6, outro as outro2, cancel as cancel2, isCancel as isCancel7 } from "@clack/prompts";
7513
7631
  import pc8 from "picocolors";
7514
7632
  import * as fs31 from "fs";
7515
- import * as path32 from "path";
7633
+ import * as path33 from "path";
7516
7634
  import { stringify as stringify2, parse } from "yaml";
7635
+ async function ensureWorkspaceRootRegistration(workspacePath, workspaceName, configFilePath) {
7636
+ if (!fs31.existsSync(configFilePath)) {
7637
+ return;
7638
+ }
7639
+ let updatedConfig = false;
7640
+ try {
7641
+ const content = fs31.readFileSync(configFilePath, "utf-8");
7642
+ const yaml = parse(content);
7643
+ if (!yaml.project) {
7644
+ yaml.project = { name: workspaceName, sourcePath: workspacePath };
7645
+ updatedConfig = true;
7646
+ } else if (!yaml.project.sourcePath) {
7647
+ yaml.project.sourcePath = workspacePath;
7648
+ updatedConfig = true;
7649
+ }
7650
+ if (updatedConfig) {
7651
+ fs31.writeFileSync(configFilePath, stringify2(yaml));
7652
+ }
7653
+ } catch (e) {
7654
+ console.error("Failed to update config.yaml sourcePath:", e);
7655
+ }
7656
+ try {
7657
+ const { loadMCPConfig: loadMCPConfig2, saveMCPConfig: saveMCPConfig2, setProjectConfig: setProjectConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
7658
+ const mcpConfig = loadMCPConfig2();
7659
+ setProjectConfig2(mcpConfig, workspaceName, true, void 0, workspacePath);
7660
+ saveMCPConfig2(mcpConfig);
7661
+ } catch (e) {
7662
+ console.error("Failed to update MCP config project path:", e);
7663
+ }
7664
+ }
7517
7665
  function backupFile(filePath) {
7518
7666
  if (!fs31.existsSync(filePath)) return null;
7519
7667
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T")[0] + "-" + Date.now();
@@ -7529,7 +7677,7 @@ function backupFile(filePath) {
7529
7677
  function getPackageVersion2() {
7530
7678
  try {
7531
7679
  const agentCoreDir = getAgentCoreDir();
7532
- const packageJsonPath = path32.join(path32.dirname(agentCoreDir), "package.json");
7680
+ const packageJsonPath = path33.join(path33.dirname(agentCoreDir), "package.json");
7533
7681
  if (fs31.existsSync(packageJsonPath)) {
7534
7682
  return JSON.parse(fs31.readFileSync(packageJsonPath, "utf8")).version;
7535
7683
  }
@@ -7566,14 +7714,14 @@ async function performUpdate(workspacePath, workspaceName, currentStorageMode, o
7566
7714
  const dirs = ["templates", "prompts", "docs"];
7567
7715
  const updatedFiles = [];
7568
7716
  for (const dir of dirs) {
7569
- const srcDir = path32.join(agentCoreDir, dir);
7717
+ const srcDir = path33.join(agentCoreDir, dir);
7570
7718
  if (!fs31.existsSync(srcDir)) continue;
7571
7719
  const syncFiles = (src, rel) => {
7572
7720
  const entries = fs31.readdirSync(src, { withFileTypes: true });
7573
7721
  for (const entry of entries) {
7574
- const entrySrc = path32.join(src, entry.name);
7575
- const entryRel = path32.join(rel, entry.name);
7576
- const entryDest = path32.join(dataPath, entryRel);
7722
+ const entrySrc = path33.join(src, entry.name);
7723
+ const entryRel = path33.join(rel, entry.name);
7724
+ const entryDest = path33.join(dataPath, entryRel);
7577
7725
  if (entry.isDirectory()) {
7578
7726
  ensureDir(entryDest);
7579
7727
  syncFiles(entrySrc, entryRel);
@@ -7581,7 +7729,7 @@ async function performUpdate(workspacePath, workspaceName, currentStorageMode, o
7581
7729
  if (driftReport.modifiedFiles.includes(entryRel)) {
7582
7730
  backupFile(entryDest);
7583
7731
  }
7584
- ensureDir(path32.dirname(entryDest));
7732
+ ensureDir(path33.dirname(entryDest));
7585
7733
  fs31.copyFileSync(entrySrc, entryDest);
7586
7734
  updatedFiles.push(entryRel);
7587
7735
  }
@@ -7593,10 +7741,10 @@ async function performUpdate(workspacePath, workspaceName, currentStorageMode, o
7593
7741
  DriftService.saveManifest(dataPath, manifest);
7594
7742
  }
7595
7743
  const rrceHome = customGlobalPath || getDefaultRRCEHome2();
7596
- ensureDir(path32.join(rrceHome, "templates"));
7597
- ensureDir(path32.join(rrceHome, "docs"));
7598
- copyDirRecursive(path32.join(agentCoreDir, "templates"), path32.join(rrceHome, "templates"));
7599
- copyDirRecursive(path32.join(agentCoreDir, "docs"), path32.join(rrceHome, "docs"));
7744
+ ensureDir(path33.join(rrceHome, "templates"));
7745
+ ensureDir(path33.join(rrceHome, "docs"));
7746
+ copyDirRecursive(path33.join(agentCoreDir, "templates"), path33.join(rrceHome, "templates"));
7747
+ copyDirRecursive(path33.join(agentCoreDir, "docs"), path33.join(rrceHome, "docs"));
7600
7748
  if (fs31.existsSync(configFilePath)) {
7601
7749
  const configContent = fs31.readFileSync(configFilePath, "utf-8");
7602
7750
  if (configContent.includes("copilot: true")) {
@@ -7625,7 +7773,8 @@ async function performUpdate(workspacePath, workspaceName, currentStorageMode, o
7625
7773
  console.error("Failed to update config.yaml version:", e);
7626
7774
  }
7627
7775
  }
7628
- const mcpPath = path32.join(rrceHome, "mcp.yaml");
7776
+ await ensureWorkspaceRootRegistration(workspacePath, workspaceName, configFilePath);
7777
+ const mcpPath = path33.join(rrceHome, "mcp.yaml");
7629
7778
  if (fs31.existsSync(mcpPath)) {
7630
7779
  try {
7631
7780
  const content = fs31.readFileSync(mcpPath, "utf-8");
@@ -7726,14 +7875,14 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
7726
7875
  const dirs = ["templates", "prompts", "docs"];
7727
7876
  const updatedFiles = [];
7728
7877
  for (const dir of dirs) {
7729
- const srcDir = path32.join(agentCoreDir, dir);
7878
+ const srcDir = path33.join(agentCoreDir, dir);
7730
7879
  if (!fs31.existsSync(srcDir)) continue;
7731
7880
  const syncFiles = (src, rel) => {
7732
7881
  const entries = fs31.readdirSync(src, { withFileTypes: true });
7733
7882
  for (const entry of entries) {
7734
- const entrySrc = path32.join(src, entry.name);
7735
- const entryRel = path32.join(rel, entry.name);
7736
- const entryDest = path32.join(dataPath, entryRel);
7883
+ const entrySrc = path33.join(src, entry.name);
7884
+ const entryRel = path33.join(rel, entry.name);
7885
+ const entryDest = path33.join(dataPath, entryRel);
7737
7886
  if (entry.isDirectory()) {
7738
7887
  ensureDir(entryDest);
7739
7888
  syncFiles(entrySrc, entryRel);
@@ -7741,7 +7890,7 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
7741
7890
  if (driftReport.modifiedFiles.includes(entryRel)) {
7742
7891
  backupFile(entryDest);
7743
7892
  }
7744
- ensureDir(path32.dirname(entryDest));
7893
+ ensureDir(path33.dirname(entryDest));
7745
7894
  fs31.copyFileSync(entrySrc, entryDest);
7746
7895
  updatedFiles.push(entryRel);
7747
7896
  }
@@ -7753,10 +7902,10 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
7753
7902
  DriftService.saveManifest(dataPath, manifest);
7754
7903
  }
7755
7904
  const rrceHome = customGlobalPath || getDefaultRRCEHome2();
7756
- ensureDir(path32.join(rrceHome, "templates"));
7757
- ensureDir(path32.join(rrceHome, "docs"));
7758
- copyDirRecursive(path32.join(agentCoreDir, "templates"), path32.join(rrceHome, "templates"));
7759
- copyDirRecursive(path32.join(agentCoreDir, "docs"), path32.join(rrceHome, "docs"));
7905
+ ensureDir(path33.join(rrceHome, "templates"));
7906
+ ensureDir(path33.join(rrceHome, "docs"));
7907
+ copyDirRecursive(path33.join(agentCoreDir, "templates"), path33.join(rrceHome, "templates"));
7908
+ copyDirRecursive(path33.join(agentCoreDir, "docs"), path33.join(rrceHome, "docs"));
7760
7909
  if (fs31.existsSync(configFilePath)) {
7761
7910
  const configContent = fs31.readFileSync(configFilePath, "utf-8");
7762
7911
  if (configContent.includes("copilot: true")) {
@@ -7785,7 +7934,8 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
7785
7934
  console.error("Failed to update config.yaml version:", e);
7786
7935
  }
7787
7936
  }
7788
- const mcpPath = path32.join(rrceHome, "mcp.yaml");
7937
+ await ensureWorkspaceRootRegistration(workspacePath, workspaceName, configFilePath);
7938
+ const mcpPath = path33.join(rrceHome, "mcp.yaml");
7789
7939
  if (fs31.existsSync(mcpPath)) {
7790
7940
  try {
7791
7941
  const content = fs31.readFileSync(mcpPath, "utf-8");
@@ -7829,8 +7979,8 @@ ${dataPaths.map((p) => ` \u2022 ${p}`).join("\n")}`,
7829
7979
  }
7830
7980
  }
7831
7981
  function resolveAllDataPathsWithCustomGlobal(mode, workspaceName, workspaceRoot, customGlobalPath) {
7832
- const globalPath = path32.join(customGlobalPath, "workspaces", workspaceName);
7833
- const workspacePath = path32.join(workspaceRoot, ".rrce-workflow");
7982
+ const globalPath = path33.join(customGlobalPath, "workspaces", workspaceName);
7983
+ const workspacePath = path33.join(workspaceRoot, ".rrce-workflow");
7834
7984
  switch (mode) {
7835
7985
  case "global":
7836
7986
  return [globalPath];
@@ -7854,7 +8004,7 @@ var init_update_flow = __esm({
7854
8004
  import { intro as intro2, select as select5, spinner as spinner7, note as note11, outro as outro7, isCancel as isCancel12, confirm as confirm10 } from "@clack/prompts";
7855
8005
  import pc13 from "picocolors";
7856
8006
  import * as fs35 from "fs";
7857
- import * as path34 from "path";
8007
+ import * as path35 from "path";
7858
8008
  import { parse as parse2 } from "yaml";
7859
8009
 
7860
8010
  // src/lib/git.ts
@@ -8632,14 +8782,14 @@ init_utils();
8632
8782
  import { confirm as confirm8, spinner as spinner5, note as note9, outro as outro5, cancel as cancel5, isCancel as isCancel10 } from "@clack/prompts";
8633
8783
  import pc11 from "picocolors";
8634
8784
  import * as fs33 from "fs";
8635
- import * as path33 from "path";
8785
+ import * as path34 from "path";
8636
8786
  async function runSyncToGlobalFlow(workspacePath, workspaceName) {
8637
8787
  const localPath = getLocalWorkspacePath(workspacePath);
8638
8788
  const customGlobalPath = getEffectiveRRCEHome(workspacePath);
8639
- const globalPath = path33.join(customGlobalPath, "workspaces", workspaceName);
8789
+ const globalPath = path34.join(customGlobalPath, "workspaces", workspaceName);
8640
8790
  const subdirs = ["knowledge", "prompts", "templates", "tasks", "refs"];
8641
8791
  const existingDirs = subdirs.filter(
8642
- (dir) => fs33.existsSync(path33.join(localPath, dir))
8792
+ (dir) => fs33.existsSync(path34.join(localPath, dir))
8643
8793
  );
8644
8794
  if (existingDirs.length === 0) {
8645
8795
  outro5(pc11.yellow("No data found in workspace storage to sync."));
@@ -8665,8 +8815,8 @@ Destination: ${pc11.cyan(globalPath)}`,
8665
8815
  try {
8666
8816
  ensureDir(globalPath);
8667
8817
  for (const dir of existingDirs) {
8668
- const srcDir = path33.join(localPath, dir);
8669
- const destDir = path33.join(globalPath, dir);
8818
+ const srcDir = path34.join(localPath, dir);
8819
+ const destDir = path34.join(globalPath, dir);
8670
8820
  ensureDir(destDir);
8671
8821
  copyDirRecursive(srcDir, destDir);
8672
8822
  }
@@ -8761,7 +8911,7 @@ init_config();
8761
8911
  function getPackageVersion3() {
8762
8912
  try {
8763
8913
  const agentCoreDir = getAgentCoreDir();
8764
- const packageJsonPath = path34.join(path34.dirname(agentCoreDir), "package.json");
8914
+ const packageJsonPath = path35.join(path35.dirname(agentCoreDir), "package.json");
8765
8915
  if (fs35.existsSync(packageJsonPath)) {
8766
8916
  return JSON.parse(fs35.readFileSync(packageJsonPath, "utf8")).version;
8767
8917
  }
@@ -8782,7 +8932,7 @@ function getLastSyncedVersion(workspacePath, workspaceName) {
8782
8932
  }
8783
8933
  }
8784
8934
  const rrceHome = getEffectiveRRCEHome(workspacePath) || getDefaultRRCEHome2();
8785
- const mcpPath = path34.join(rrceHome, "mcp.yaml");
8935
+ const mcpPath = path35.join(rrceHome, "mcp.yaml");
8786
8936
  if (fs35.existsSync(mcpPath)) {
8787
8937
  try {
8788
8938
  const content = fs35.readFileSync(mcpPath, "utf-8");
@@ -8982,12 +9132,12 @@ Workspace: ${pc13.bold(workspaceName)}`,
8982
9132
  init_mcp();
8983
9133
  var command = process.argv[2];
8984
9134
  var subcommand = process.argv[3];
8985
- if (!command || command === "wizard") {
9135
+ if (!command || command === "wizard" || command === "install") {
8986
9136
  runWizard();
8987
9137
  } else if (command === "mcp") {
8988
9138
  runMCP(subcommand);
8989
9139
  } else {
8990
9140
  console.error(`Unknown command: ${command}`);
8991
- console.error("Usage: rrce-workflow [wizard|mcp]");
9141
+ console.error("Usage: rrce-workflow [wizard|install|mcp]");
8992
9142
  process.exit(1);
8993
9143
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.3.37",
3
+ "version": "0.3.38",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",