rrce-workflow 0.1.4 → 0.1.5

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.
@@ -20,8 +20,20 @@ auto-identity:
20
20
 
21
21
  You are the Documentation Lead for the project. Operate like a senior engineering manager responsible for synthesizing knowledge and preparing smooth handovers.
22
22
 
23
- Prerequisite
24
- **IMPORTANT**: Before proceeding, verify that `{{RRCE_DATA}}/knowledge/project-context.md` exists. If it does not exist, stop and instruct the user to run `/init` first to establish project context. Do not continue with documentation until initialization is complete.
23
+ Pipeline Position
24
+ - **Optional**: Documentation can be run at any point, but is most valuable after Execution.
25
+ - **Best After**: Executor phase complete (if documenting a specific task).
26
+ - **Standalone**: Can also run independently to document general knowledge, architecture, or runbooks.
27
+
28
+ Prerequisites (RECOMMENDED)
29
+ If a `TASK_SLUG` is provided:
30
+ 1. **Execution Complete** (recommended): Check `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json` for `agents.executor.status === 'complete'`.
31
+ - If not complete, inform user: "Execution is not complete for this task. You may proceed with partial documentation, or run `/execute TASK_SLUG={{TASK_SLUG}}` first for complete coverage."
32
+
33
+ 2. **Project Context Exists**: Check `{{RRCE_DATA}}/knowledge/project-context.md` exists.
34
+ - If missing, recommend: "Consider running `/init` first to establish project context for better documentation."
35
+
36
+ Documentation can proceed even if prerequisites are not fully met, but output quality may be limited.
25
37
 
26
38
  Mission
27
39
  - Translate the implemented work and accumulated context into durable documentation.
@@ -16,8 +16,28 @@ auto-identity:
16
16
 
17
17
  You are the Executor for the project. Operate like a senior individual contributor who ships clean, well-tested code aligned with the orchestrated plan.
18
18
 
19
- Prerequisite
20
- **IMPORTANT**: Before proceeding, verify that `{{RRCE_DATA}}/knowledge/project-context.md` exists. If it does not exist, stop and instruct the user to run `/init` first to establish project context. Do not continue with execution until initialization is complete.
19
+ Pipeline Position
20
+ - **Requires**: Planning phase must be complete before execution can begin.
21
+ - **Next Step**: After execution is complete, optionally hand off to `/docs` (Documentation agent).
22
+
23
+ Prerequisites (STRICT)
24
+ Before proceeding, verify ALL of the following:
25
+
26
+ 1. **Planning Complete**: Check `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json` exists and `agents.planning.status` is `complete`.
27
+ - If meta.json doesn't exist, **STOP** and prompt user:
28
+ > "Task not found. Please run `/research TASK_SLUG={{TASK_SLUG}}` to start a new task."
29
+ - If planning status is not `complete`, **STOP** and prompt user:
30
+ > "Planning phase is not complete for this task. Please run `/plan TASK_SLUG={{TASK_SLUG}}` first."
31
+
32
+ 2. **Plan Artifact Exists**: Check that the plan file at `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/planning/{{TASK_SLUG}}-plan.md` exists.
33
+ - If missing, **STOP** and prompt user:
34
+ > "Plan artifact not found. Please run `/plan TASK_SLUG={{TASK_SLUG}}` first."
35
+
36
+ 3. **Project Context Exists**: Check `{{RRCE_DATA}}/knowledge/project-context.md` exists.
37
+ - If missing, **STOP** and prompt user:
38
+ > "Project context not found. Please run `/init` first to establish project context."
39
+
40
+ Do not proceed with execution until all prerequisites are satisfied.
21
41
 
22
42
  Mission
23
43
  - Implement the scoped work, keeping quality high and feedback loops short.
@@ -15,6 +15,11 @@ auto-identity:
15
15
 
16
16
  You are the Project Initializer for RRCE-Workflow. Operate like a senior architect performing a comprehensive codebase audit to establish foundational context for all downstream agents.
17
17
 
18
+ Pipeline Position
19
+ - **Entry Point**: Init can be run at any time to establish or update project context.
20
+ - **Correlation**: Init and Planning work together to maintain project context. Planning may trigger Init updates when significant changes are planned.
21
+ - **Foundation**: All other agents (Research, Executor, Documentation, Sync) rely on the `project-context.md` created by Init.
22
+
18
23
  Mission
19
24
  - Analyze the workspace to extract tech stack, architecture patterns, coding conventions, and project structure.
20
25
  - Produce a durable project context file that informs all future agent interactions.
@@ -13,8 +13,23 @@ auto-identity:
13
13
 
14
14
  You are the Planning & Task Orchestrator for the project. Operate like an engineering manager with deep scoped knowledge of this codebase.
15
15
 
16
- Prerequisite
17
- **IMPORTANT**: Before proceeding, verify that `{{RRCE_DATA}}/knowledge/project-context.md` exists. If it does not exist, stop and instruct the user to run `/init` first to establish project context. Do not continue with planning until initialization is complete.
16
+ Pipeline Position
17
+ - **Requires**: Research phase must be complete before planning can begin.
18
+ - **Correlation**: Planning works with Init to maintain project context. If planning reveals significant architectural changes, recommend running `/init` to update project context.
19
+ - **Next Step**: After planning is complete, hand off to `/execute` (Executor agent).
20
+
21
+ Prerequisites (STRICT)
22
+ Before proceeding, verify ALL of the following:
23
+
24
+ 1. **Research Complete**: Check `{{RRCE_DATA}}/tasks/{{TASK_SLUG}}/meta.json` exists and `agents.research.status` is `complete`.
25
+ - If meta.json doesn't exist or research status is not `complete`, **STOP** and prompt user:
26
+ > "Research phase is not complete for this task. Please run `/research TASK_SLUG={{TASK_SLUG}}` first."
27
+
28
+ 2. **Project Context Exists**: Check `{{RRCE_DATA}}/knowledge/project-context.md` exists.
29
+ - If missing, **STOP** and prompt user:
30
+ > "Project context not found. Please run `/init` first to establish project context."
31
+
32
+ Do not proceed with planning until both prerequisites are satisfied.
18
33
 
19
34
  Mission
20
35
  - Convert the Research brief into a concrete, prioritized plan that the Executor can follow with minimal ambiguity.
@@ -20,8 +20,10 @@ auto-identity:
20
20
 
21
21
  You are the Research & Discussion Lead for the project. Operate like a staff-level tech lead who owns broad project awareness.
22
22
 
23
- Prerequisite
24
- **IMPORTANT**: Before proceeding, verify that `{{RRCE_DATA}}/knowledge/project-context.md` exists. If it does not exist, stop and instruct the user to run `/init` first to establish project context. Do not continue with research until initialization is complete.
23
+ Pipeline Position
24
+ - **Entry Point**: Research can be the first agent invoked for a new task.
25
+ - **Recommendation**: If `{{RRCE_DATA}}/knowledge/project-context.md` does not exist, recommend running `/init` first for best results, but you may proceed with research if the user prefers.
26
+ - **Next Step**: After research is complete, hand off to `/plan` (Planning agent).
25
27
 
26
28
  Mission
27
29
  - Challenge and refine the incoming request until intent, constraints, and success criteria are explicit.
@@ -14,8 +14,17 @@ auto-identity:
14
14
 
15
15
  You are the Knowledge Sync Lead. Act like a senior architect charged with keeping the RRCE knowledge cache authoritative and current.
16
16
 
17
- Prerequisite
18
- **IMPORTANT**: Before proceeding, verify that `{{RRCE_DATA}}/knowledge/project-context.md` exists. If it does not exist, stop and instruct the user to run `/init` first to establish project context. Do not continue with sync until initialization is complete.
17
+ Pipeline Position
18
+ - **Maintenance Agent**: Sync runs periodically or after significant codebase changes to keep knowledge current.
19
+ - **Requires**: Init must have been run at least once (project-context.md must exist).
20
+ - **Triggers Init**: If sync detects major structural changes, recommend running `/init` to update project context.
21
+
22
+ Prerequisites (STRICT)
23
+ 1. **Project Context Exists**: Check `{{RRCE_DATA}}/knowledge/project-context.md` exists.
24
+ - If missing, **STOP** and prompt user:
25
+ > "Project context not found. Please run `/init` first to establish project context before syncing."
26
+
27
+ Do not proceed with sync until the prerequisite is satisfied.
19
28
 
20
29
  Mission
21
30
  - Inspect the live codebase to understand the present implementation and its recent changes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",
@@ -3,7 +3,7 @@ import pc from 'picocolors';
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
5
5
  import { getGitUser } from '../lib/git';
6
- import { detectWorkspaceRoot, getWorkspaceName, resolveAllDataPaths, ensureDir, getAgentPromptPath, syncMetadataToAll, copyDirToAllStoragePaths, listGlobalProjects, getGlobalProjectKnowledgePath, getRRCEHome } from '../lib/paths';
6
+ import { detectWorkspaceRoot, getWorkspaceName, resolveAllDataPaths, ensureDir, getAgentPromptPath, syncMetadataToAll, copyDirToAllStoragePaths, listGlobalProjects, getGlobalProjectKnowledgePath, getRRCEHome, getGlobalWorkspacePath, getLocalWorkspacePath } from '../lib/paths';
7
7
  import type { StorageMode } from '../types/prompt';
8
8
  import { loadPromptsFromDir, getAgentCorePromptsDir, getAgentCoreDir } from '../lib/prompts';
9
9
 
@@ -34,16 +34,51 @@ Workspace: ${pc.bold(workspaceName)}`,
34
34
  // Check if already configured
35
35
  const configFilePath = path.join(workspacePath, '.rrce-workflow.yaml');
36
36
  const isAlreadyConfigured = fs.existsSync(configFilePath);
37
+
38
+ // Check current storage mode from config
39
+ let currentStorageMode: string | null = null;
40
+ if (isAlreadyConfigured) {
41
+ try {
42
+ const configContent = fs.readFileSync(configFilePath, 'utf-8');
43
+ const modeMatch = configContent.match(/mode:\s*(global|workspace|both)/);
44
+ currentStorageMode = modeMatch?.[1] ?? null;
45
+ } catch {
46
+ // Ignore parse errors
47
+ }
48
+ }
49
+
50
+ // Check if workspace has local data that could be synced
51
+ const localDataPath = path.join(workspacePath, '.rrce-workflow');
52
+ const hasLocalData = fs.existsSync(localDataPath);
53
+
54
+ // If already configured, show menu
55
+ if (isAlreadyConfigured) {
56
+ const menuOptions: { value: string; label: string; hint?: string }[] = [];
57
+
58
+ // Add link option if other projects exist
59
+ if (existingProjects.length > 0) {
60
+ menuOptions.push({
61
+ value: 'link',
62
+ label: 'Link other project knowledge',
63
+ hint: `${existingProjects.length} projects available`
64
+ });
65
+ }
66
+
67
+ // Add sync to global option if using workspace-only mode
68
+ if (currentStorageMode === 'workspace' && hasLocalData) {
69
+ menuOptions.push({
70
+ value: 'sync-global',
71
+ label: 'Sync to global storage',
72
+ hint: 'Share knowledge with other projects'
73
+ });
74
+ }
75
+
76
+ menuOptions.push({ value: 'update', label: 'Update from package', hint: 'Get latest prompts & templates' });
77
+ menuOptions.push({ value: 'exit', label: 'Exit' });
37
78
 
38
- // If already configured and there are other projects, show menu
39
- if (isAlreadyConfigured && existingProjects.length > 0) {
40
79
  const action = await select({
41
80
  message: 'This workspace is already configured. What would you like to do?',
42
- options: [
43
- { value: 'link', label: 'Link other project knowledge', hint: `${existingProjects.length} projects available` },
44
- { value: 'reconfigure', label: 'Reconfigure from scratch' },
45
- { value: 'exit', label: 'Exit' },
46
- ],
81
+ options: menuOptions,
47
82
  });
48
83
 
49
84
  if (isCancel(action) || action === 'exit') {
@@ -52,11 +87,19 @@ Workspace: ${pc.bold(workspaceName)}`,
52
87
  }
53
88
 
54
89
  if (action === 'link') {
55
- // Link-only flow
56
90
  await runLinkProjectsFlow(workspacePath, workspaceName, existingProjects);
57
91
  return;
58
92
  }
59
- // Otherwise continue to full reconfigure flow
93
+
94
+ if (action === 'sync-global') {
95
+ await runSyncToGlobalFlow(workspacePath, workspaceName);
96
+ return;
97
+ }
98
+
99
+ if (action === 'update') {
100
+ await runUpdateFlow(workspacePath, workspaceName, currentStorageMode);
101
+ return;
102
+ }
60
103
  }
61
104
 
62
105
  // Full setup flow
@@ -215,11 +258,17 @@ tools:
215
258
 
216
259
  if (linkedProjects.length > 0) {
217
260
  summary.push(`Linked projects: ${linkedProjects.join(', ')}`);
261
+ summary.push(`Workspace file: ${pc.cyan(`${workspaceName}.code-workspace`)}`);
218
262
  }
219
263
 
220
264
  note(summary.join('\n'), 'Setup Summary');
221
265
 
222
- outro(pc.green(`✓ Setup complete! Your agents are ready to use.`));
266
+ // Show appropriate outro message
267
+ if (linkedProjects.length > 0) {
268
+ outro(pc.green(`✓ Setup complete! Open ${pc.bold(`${workspaceName}.code-workspace`)} in VSCode to access linked knowledge.`));
269
+ } else {
270
+ outro(pc.green(`✓ Setup complete! Your agents are ready to use.`));
271
+ }
223
272
 
224
273
  } catch (error) {
225
274
  s.stop('Error occurred');
@@ -367,14 +416,197 @@ async function runLinkProjectsFlow(workspacePath: string, workspaceName: string,
367
416
  s.stop('Projects linked');
368
417
 
369
418
  // Show summary
419
+ const workspaceFile = `${workspaceName}.code-workspace`;
370
420
  const summary = [
371
421
  `Linked projects:`,
372
422
  ...selectedProjects.map(p => ` ✓ ${p}`),
373
423
  ``,
374
- `VSCode workspace file updated: ${workspaceName}.code-workspace`,
424
+ `Workspace file: ${pc.cyan(workspaceFile)}`,
375
425
  ];
376
426
 
377
427
  note(summary.join('\n'), 'Link Summary');
378
428
 
379
- outro(pc.green('✓ Projects linked successfully!'));
429
+ outro(pc.green(`✓ Projects linked! Open ${pc.bold(workspaceFile)} in VSCode to access linked knowledge.`));
430
+ }
431
+
432
+ /**
433
+ * Sync workspace knowledge to global storage so other projects can reference it
434
+ */
435
+ async function runSyncToGlobalFlow(workspacePath: string, workspaceName: string) {
436
+ const localPath = getLocalWorkspacePath(workspacePath);
437
+ const globalPath = getGlobalWorkspacePath(workspaceName);
438
+
439
+ // Check what exists locally
440
+ const subdirs = ['knowledge', 'prompts', 'templates', 'tasks', 'refs'];
441
+ const existingDirs = subdirs.filter(dir =>
442
+ fs.existsSync(path.join(localPath, dir))
443
+ );
444
+
445
+ if (existingDirs.length === 0) {
446
+ outro(pc.yellow('No data found in workspace storage to sync.'));
447
+ return;
448
+ }
449
+
450
+ // Show what will be synced
451
+ note(
452
+ `The following will be copied to global storage:\n${existingDirs.map(d => ` • ${d}/`).join('\n')}\n\nDestination: ${pc.cyan(globalPath)}`,
453
+ 'Sync Preview'
454
+ );
455
+
456
+ const shouldSync = await confirm({
457
+ message: 'Proceed with sync to global storage?',
458
+ initialValue: true,
459
+ });
460
+
461
+ if (isCancel(shouldSync) || !shouldSync) {
462
+ outro('Sync cancelled.');
463
+ return;
464
+ }
465
+
466
+ const s = spinner();
467
+ s.start('Syncing to global storage');
468
+
469
+ try {
470
+ // Ensure global directory exists
471
+ ensureDir(globalPath);
472
+
473
+ // Copy each directory
474
+ for (const dir of existingDirs) {
475
+ const srcDir = path.join(localPath, dir);
476
+ const destDir = path.join(globalPath, dir);
477
+ ensureDir(destDir);
478
+
479
+ // Copy files recursively
480
+ copyDirRecursive(srcDir, destDir);
481
+ }
482
+
483
+ // Update the config to reflect 'both' mode
484
+ const configFilePath = path.join(workspacePath, '.rrce-workflow.yaml');
485
+ let configContent = fs.readFileSync(configFilePath, 'utf-8');
486
+ configContent = configContent.replace(/mode:\s*workspace/, 'mode: both');
487
+ fs.writeFileSync(configFilePath, configContent);
488
+
489
+ s.stop('Sync complete');
490
+
491
+ const summary = [
492
+ `Synced directories:`,
493
+ ...existingDirs.map(d => ` ✓ ${d}/`),
494
+ ``,
495
+ `Global path: ${pc.cyan(globalPath)}`,
496
+ `Storage mode updated to: ${pc.bold('both')}`,
497
+ ``,
498
+ `Other projects can now link this knowledge!`,
499
+ ];
500
+
501
+ note(summary.join('\n'), 'Sync Summary');
502
+
503
+ outro(pc.green('✓ Workspace knowledge synced to global storage!'));
504
+
505
+ } catch (error) {
506
+ s.stop('Error occurred');
507
+ cancel(`Failed to sync: ${error instanceof Error ? error.message : String(error)}`);
508
+ process.exit(1);
509
+ }
510
+ }
511
+
512
+ /**
513
+ * Recursively copy a directory
514
+ */
515
+ function copyDirRecursive(src: string, dest: string) {
516
+ const entries = fs.readdirSync(src, { withFileTypes: true });
517
+
518
+ for (const entry of entries) {
519
+ const srcPath = path.join(src, entry.name);
520
+ const destPath = path.join(dest, entry.name);
521
+
522
+ if (entry.isDirectory()) {
523
+ ensureDir(destPath);
524
+ copyDirRecursive(srcPath, destPath);
525
+ } else {
526
+ fs.copyFileSync(srcPath, destPath);
527
+ }
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Update prompts and templates from the package without resetting config
533
+ */
534
+ async function runUpdateFlow(workspacePath: string, workspaceName: string, currentStorageMode: string | null) {
535
+ const s = spinner();
536
+ s.start('Checking for updates');
537
+
538
+ try {
539
+ const agentCoreDir = getAgentCoreDir();
540
+ const prompts = loadPromptsFromDir(getAgentCorePromptsDir());
541
+
542
+ // Determine storage paths based on current mode
543
+ const mode = (currentStorageMode as StorageMode) || 'global';
544
+ const dataPaths = resolveAllDataPaths(mode, workspaceName, workspacePath);
545
+
546
+ s.stop('Updates found');
547
+
548
+ // Show what will be updated
549
+ note(
550
+ `The following will be updated from the package:\n • prompts/ (${prompts.length} agent prompts)\n • templates/ (output templates)\n\nTarget locations:\n${dataPaths.map(p => ` • ${p}`).join('\n')}`,
551
+ 'Update Preview'
552
+ );
553
+
554
+ const shouldUpdate = await confirm({
555
+ message: 'Proceed with update?',
556
+ initialValue: true,
557
+ });
558
+
559
+ if (isCancel(shouldUpdate) || !shouldUpdate) {
560
+ outro('Update cancelled.');
561
+ return;
562
+ }
563
+
564
+ s.start('Updating from package');
565
+
566
+ // Update prompts and templates in all storage locations
567
+ for (const dataPath of dataPaths) {
568
+ // Update prompts
569
+ const promptsDir = path.join(dataPath, 'prompts');
570
+ ensureDir(promptsDir);
571
+ copyPromptsToDir(prompts, promptsDir, '.md');
572
+
573
+ // Update templates
574
+ copyDirToAllStoragePaths(path.join(agentCoreDir, 'templates'), 'templates', [dataPath]);
575
+ }
576
+
577
+ // Also update tool-specific locations if configured
578
+ const configFilePath = path.join(workspacePath, '.rrce-workflow.yaml');
579
+ const configContent = fs.readFileSync(configFilePath, 'utf-8');
580
+
581
+ if (configContent.includes('copilot: true')) {
582
+ const copilotPath = getAgentPromptPath(workspacePath, 'copilot');
583
+ ensureDir(copilotPath);
584
+ copyPromptsToDir(prompts, copilotPath, '.agent.md');
585
+ }
586
+
587
+ if (configContent.includes('antigravity: true')) {
588
+ const antigravityPath = getAgentPromptPath(workspacePath, 'antigravity');
589
+ ensureDir(antigravityPath);
590
+ copyPromptsToDir(prompts, antigravityPath, '.md');
591
+ }
592
+
593
+ s.stop('Update complete');
594
+
595
+ const summary = [
596
+ `Updated:`,
597
+ ` ✓ ${prompts.length} agent prompts`,
598
+ ` ✓ Output templates`,
599
+ ``,
600
+ `Your configuration and knowledge files were preserved.`,
601
+ ];
602
+
603
+ note(summary.join('\n'), 'Update Summary');
604
+
605
+ outro(pc.green('✓ Successfully updated from package!'));
606
+
607
+ } catch (error) {
608
+ s.stop('Error occurred');
609
+ cancel(`Failed to update: ${error instanceof Error ? error.message : String(error)}`);
610
+ process.exit(1);
611
+ }
380
612
  }
package/src/lib/paths.ts CHANGED
@@ -114,6 +114,20 @@ export function getGlobalProjectKnowledgePath(projectName: string): string {
114
114
  return path.join(RRCE_HOME, 'workspaces', projectName, 'knowledge');
115
115
  }
116
116
 
117
+ /**
118
+ * Get the global workspace data path for a project
119
+ */
120
+ export function getGlobalWorkspacePath(workspaceName: string): string {
121
+ return path.join(RRCE_HOME, 'workspaces', workspaceName);
122
+ }
123
+
124
+ /**
125
+ * Get the local workspace data path
126
+ */
127
+ export function getLocalWorkspacePath(workspaceRoot: string): string {
128
+ return path.join(workspaceRoot, '.rrce-workflow');
129
+ }
130
+
117
131
  /**
118
132
  * Ensure directory exists
119
133
  */