rrce-workflow 0.1.5 → 0.2.6

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.
@@ -48,7 +48,7 @@ Non-Negotiables
48
48
  6. Close the loop in `meta.json` when working within a task by setting `agents.documentation.status`, refreshing `checklist`, and updating overall `status`.
49
49
 
50
50
  Path Resolution
51
- - Storage mode: Determined by `.rrce-workflow.yaml` → global config → default (`global`)
51
+ - Storage mode: Determined by `config.yaml`storage.mode`` → global config → default (`global`)
52
52
  - `global`: Data in `~/.rrce-workflow/workspaces/<workspace-name>/`
53
53
  - `workspace`: Data in `<workspace>/.rrce-workflow/`
54
54
  - `both`: **Dual storage** - data stored in BOTH locations simultaneously
@@ -56,7 +56,7 @@ Path Resolution
56
56
  - Secondary (auto-synced): `~/.rrce-workflow/workspaces/<workspace-name>/`
57
57
  - When writing, always write to `{{RRCE_DATA}}` - the system ensures both locations stay in sync
58
58
  - Data path: `{{RRCE_DATA}}` (resolves to primary storage based on mode)
59
- - Global home: `{{RRCE_HOME}}` (always `~/.rrce-workflow`)
59
+ - Global home: `{{RRCE_HOME}}` - **To resolve:** read `.rrce-workflow/config.yaml` → `storage.globalPath`, or default `~/.rrce-workflow`
60
60
  - Workspace root: `{{WORKSPACE_ROOT}}` (auto-detected or via `$RRCE_WORKSPACE`)
61
61
  - Workspace name: `{{WORKSPACE_NAME}}` (from config or directory name)
62
62
 
@@ -52,17 +52,14 @@ Non-Negotiables
52
52
  6. Update `meta.json` as you proceed so statuses stay accurate.
53
53
 
54
54
  Path Resolution
55
- - Storage mode: Determined by `.rrce-workflow.yaml` global config default (`global`)
56
- - `global`: Data in `~/.rrce-workflow/workspaces/<workspace-name>/`
55
+ - **Config file**: `.rrce-workflow/config.yaml` (read this first to resolve paths)
56
+ - Storage mode: Determined by `config.yaml` `storage.mode` (default: `global`)
57
+ - `global`: Data in `{{RRCE_HOME}}/workspaces/<workspace-name>/`
57
58
  - `workspace`: Data in `<workspace>/.rrce-workflow/`
58
- - `both`: **Dual storage** - data stored in BOTH locations simultaneously
59
- - Primary (for reads): `<workspace>/.rrce-workflow/`
60
- - Secondary (auto-synced): `~/.rrce-workflow/workspaces/<workspace-name>/`
61
- - When writing, always write to `{{RRCE_DATA}}` - the system ensures both locations stay in sync
59
+ - `both`: Dual storage - data in BOTH locations
62
60
  - Data path: `{{RRCE_DATA}}` (resolves to primary storage based on mode)
63
- - Global home: `{{RRCE_HOME}}` (always `~/.rrce-workflow`)
64
- - Workspace root: `{{WORKSPACE_ROOT}}` (auto-detected or via `$RRCE_WORKSPACE`)
65
- - Workspace name: `{{WORKSPACE_NAME}}` (from config or directory name)
61
+ - Global home: `{{RRCE_HOME}}` - **To resolve:** read `config.yaml` → `storage.globalPath`, or default `~/.rrce-workflow`
62
+ - Workspace name: `{{WORKSPACE_NAME}}` (from `config.yaml` `project.name`)
66
63
 
67
64
  Cross-Project References
68
65
  - Reference another project's context: `{{RRCE_HOME}}/workspaces/<other-project>/knowledge/`
@@ -34,17 +34,18 @@ Non-Negotiables
34
34
  6. Keep output actionable and scannable; use structured sections.
35
35
 
36
36
  Path Resolution
37
- - Storage mode: Determined by `.rrce-workflow.yaml` global config default (`global`)
38
- - `global`: Data stored in `~/.rrce-workflow/workspaces/<workspace-name>/`
37
+ - **Config file**: `.rrce-workflow/config.yaml` (read this first to resolve paths)
38
+ - Storage mode: Determined by `config.yaml` `storage.mode` (default: `global`)
39
+ - `global`: Data stored in `{{RRCE_HOME}}/workspaces/<workspace-name>/`
39
40
  - `workspace`: Data stored in `<workspace>/.rrce-workflow/`
40
- - `both`: **Dual storage** - data stored in BOTH locations simultaneously
41
- - Primary (for reads): `<workspace>/.rrce-workflow/`
42
- - Secondary (auto-synced): `~/.rrce-workflow/workspaces/<workspace-name>/`
43
- - When writing, always write to `{{RRCE_DATA}}` - the system ensures both locations stay in sync
41
+ - `both`: **Dual storage** - data in BOTH locations
44
42
  - Data path: `{{RRCE_DATA}}` (resolves to primary storage based on mode)
45
- - Global home: `{{RRCE_HOME}}` (always `~/.rrce-workflow`)
43
+ - Global home: `{{RRCE_HOME}}` - **To resolve:**
44
+ 1. Read `.rrce-workflow/config.yaml`
45
+ 2. If `storage.globalPath` exists, use that value
46
+ 3. Otherwise, default to `~/.rrce-workflow`
46
47
  - Workspace root: `{{WORKSPACE_ROOT}}` (auto-detected or via `$RRCE_WORKSPACE`)
47
- - Workspace name: `{{WORKSPACE_NAME}}` (from config or directory name)
48
+ - Workspace name: `{{WORKSPACE_NAME}}` (from `config.yaml` → `project.name` or directory name)
48
49
 
49
50
  Cross-Project References
50
51
  - To reference another project's context: `{{RRCE_HOME}}/workspaces/<other-project-name>/knowledge/`
@@ -44,7 +44,7 @@ Non-Negotiables
44
44
  6. Keep the written plan under 500 lines and reference supporting materials explicitly.
45
45
 
46
46
  Path Resolution
47
- - Storage mode: Determined by `.rrce-workflow.yaml` → global config → default (`global`)
47
+ - Storage mode: Determined by `config.yaml`storage.mode`` → global config → default (`global`)
48
48
  - `global`: Data in `~/.rrce-workflow/workspaces/<workspace-name>/`
49
49
  - `workspace`: Data in `<workspace>/.rrce-workflow/`
50
50
  - `both`: **Dual storage** - data stored in BOTH locations simultaneously
@@ -52,7 +52,7 @@ Path Resolution
52
52
  - Secondary (auto-synced): `~/.rrce-workflow/workspaces/<workspace-name>/`
53
53
  - When writing, always write to `{{RRCE_DATA}}` - the system ensures both locations stay in sync
54
54
  - Data path: `{{RRCE_DATA}}` (resolves to primary storage based on mode)
55
- - Global home: `{{RRCE_HOME}}` (always `~/.rrce-workflow`)
55
+ - Global home: `{{RRCE_HOME}}` - **To resolve:** read `.rrce-workflow/config.yaml` → `storage.globalPath`, or default `~/.rrce-workflow`
56
56
  - Workspace root: `{{WORKSPACE_ROOT}}` (auto-detected or via `$RRCE_WORKSPACE`)
57
57
  - Workspace name: `{{WORKSPACE_NAME}}` (from config or directory name)
58
58
 
@@ -38,7 +38,7 @@ Non-Negotiables
38
38
  6. Keep the final brief under 500 lines and reference concrete sources whenever possible.
39
39
 
40
40
  Path Resolution
41
- - Storage mode: Determined by `.rrce-workflow.yaml` → global config → default (`global`)
41
+ - Storage mode: Determined by `config.yaml`storage.mode`` → global config → default (`global`)
42
42
  - `global`: Data in `~/.rrce-workflow/workspaces/<workspace-name>/`
43
43
  - `workspace`: Data in `<workspace>/.rrce-workflow/`
44
44
  - `both`: **Dual storage** - data stored in BOTH locations simultaneously
@@ -46,7 +46,7 @@ Path Resolution
46
46
  - Secondary (auto-synced): `~/.rrce-workflow/workspaces/<workspace-name>/`
47
47
  - When writing, always write to `{{RRCE_DATA}}` - the system ensures both locations stay in sync
48
48
  - Data path: `{{RRCE_DATA}}` (resolves to primary storage based on mode)
49
- - Global home: `{{RRCE_HOME}}` (always `~/.rrce-workflow`)
49
+ - Global home: `{{RRCE_HOME}}` - **To resolve:** read `.rrce-workflow/config.yaml` → `storage.globalPath`, or default `~/.rrce-workflow`
50
50
  - Workspace root: `{{WORKSPACE_ROOT}}` (auto-detected or via `$RRCE_WORKSPACE`)
51
51
  - Workspace name: `{{WORKSPACE_NAME}}` (from config or directory name)
52
52
 
@@ -38,7 +38,7 @@ Non-Negotiables
38
38
  5. Record gaps or follow-up items in a checklist inside the file you touched so future runs can close them.
39
39
 
40
40
  Path Resolution
41
- - Storage mode: Determined by `.rrce-workflow.yaml` → global config → default (`global`)
41
+ - Storage mode: Determined by `config.yaml`storage.mode`` → global config → default (`global`)
42
42
  - `global`: Data in `~/.rrce-workflow/workspaces/<workspace-name>/`
43
43
  - `workspace`: Data in `<workspace>/.rrce-workflow/`
44
44
  - `both`: **Dual storage** - data stored in BOTH locations simultaneously
@@ -46,7 +46,7 @@ Path Resolution
46
46
  - Secondary (auto-synced): `~/.rrce-workflow/workspaces/<workspace-name>/`
47
47
  - When writing, always write to `{{RRCE_DATA}}` - the system ensures both locations stay in sync
48
48
  - Data path: `{{RRCE_DATA}}` (resolves to primary storage based on mode)
49
- - Global home: `{{RRCE_HOME}}` (always `~/.rrce-workflow`)
49
+ - Global home: `{{RRCE_HOME}}` - **To resolve:** read `.rrce-workflow/config.yaml` → `storage.globalPath`, or default `~/.rrce-workflow`
50
50
  - Workspace root: `{{WORKSPACE_ROOT}}` (auto-detected or via `$RRCE_WORKSPACE`)
51
51
  - Workspace name: `{{WORKSPACE_NAME}}` (from config or directory name)
52
52
 
@@ -1,10 +1,10 @@
1
1
  <!--
2
2
  RRCE Template Variables:
3
3
  - {{RRCE_DATA}}: Primary storage path (resolves based on storage mode in .rrce-workflow.yaml)
4
- - global: ~/.rrce-workflow/workspaces/<workspace-name>/
4
+ - global: {{RRCE_HOME}}/workspaces/<workspace-name>/
5
5
  - workspace: <workspace>/.rrce-workflow/
6
6
  - both: <workspace>/.rrce-workflow/ (primary, auto-synced to global)
7
- - {{RRCE_HOME}}: Always ~/.rrce-workflow
7
+ - {{RRCE_HOME}}: Global home (default: ~/.rrce-workflow, customizable via storage.globalPath in config)
8
8
  - {{WORKSPACE_ROOT}}: Workspace root directory
9
9
  - {{WORKSPACE_NAME}}: Workspace name from config or directory name
10
10
  -->
@@ -1,10 +1,10 @@
1
1
  <!--
2
2
  RRCE Template Variables:
3
3
  - {{RRCE_DATA}}: Primary storage path (resolves based on storage mode in .rrce-workflow.yaml)
4
- - global: ~/.rrce-workflow/workspaces/<workspace-name>/
4
+ - global: {{RRCE_HOME}}/workspaces/<workspace-name>/
5
5
  - workspace: <workspace>/.rrce-workflow/
6
6
  - both: <workspace>/.rrce-workflow/ (primary, auto-synced to global)
7
- - {{RRCE_HOME}}: Always ~/.rrce-workflow
7
+ - {{RRCE_HOME}}: Global home (default: ~/.rrce-workflow, customizable via storage.globalPath in config)
8
8
  - {{WORKSPACE_ROOT}}: Workspace root directory
9
9
  - {{WORKSPACE_NAME}}: Workspace name from config or directory name
10
10
  -->
@@ -1,10 +1,10 @@
1
1
  <!--
2
2
  RRCE Template Variables:
3
3
  - {{RRCE_DATA}}: Primary storage path (resolves based on storage mode in .rrce-workflow.yaml)
4
- - global: ~/.rrce-workflow/workspaces/<workspace-name>/
4
+ - global: {{RRCE_HOME}}/workspaces/<workspace-name>/
5
5
  - workspace: <workspace>/.rrce-workflow/
6
6
  - both: <workspace>/.rrce-workflow/ (primary, auto-synced to global)
7
- - {{RRCE_HOME}}: Always ~/.rrce-workflow
7
+ - {{RRCE_HOME}}: Global home (default: ~/.rrce-workflow, customizable via storage.globalPath in config)
8
8
  - {{WORKSPACE_ROOT}}: Workspace root directory
9
9
  - {{WORKSPACE_NAME}}: Workspace name from config or directory name
10
10
  -->
@@ -1,10 +1,10 @@
1
1
  <!--
2
2
  RRCE Template Variables:
3
3
  - {{RRCE_DATA}}: Primary storage path (resolves based on storage mode in .rrce-workflow.yaml)
4
- - global: ~/.rrce-workflow/workspaces/<workspace-name>/
4
+ - global: {{RRCE_HOME}}/workspaces/<workspace-name>/
5
5
  - workspace: <workspace>/.rrce-workflow/
6
6
  - both: <workspace>/.rrce-workflow/ (primary, auto-synced to global)
7
- - {{RRCE_HOME}}: Always ~/.rrce-workflow
7
+ - {{RRCE_HOME}}: Global home (default: ~/.rrce-workflow, customizable via storage.globalPath in config)
8
8
  - {{WORKSPACE_ROOT}}: Workspace root directory
9
9
  - {{WORKSPACE_NAME}}: Workspace name from config or directory name
10
10
  -->
@@ -1,10 +1,10 @@
1
1
  <!--
2
2
  RRCE Template Variables:
3
3
  - {{RRCE_DATA}}: Primary storage path (resolves based on storage mode in .rrce-workflow.yaml)
4
- - global: ~/.rrce-workflow/workspaces/<workspace-name>/
4
+ - global: {{RRCE_HOME}}/workspaces/<workspace-name>/
5
5
  - workspace: <workspace>/.rrce-workflow/
6
6
  - both: <workspace>/.rrce-workflow/ (primary, auto-synced to global)
7
- - {{RRCE_HOME}}: Always ~/.rrce-workflow
7
+ - {{RRCE_HOME}}: Global home (default: ~/.rrce-workflow, customizable via storage.globalPath in config)
8
8
  - {{WORKSPACE_ROOT}}: Workspace root directory
9
9
  - {{WORKSPACE_NAME}}: Workspace name from config or directory name
10
10
  -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.1.5",
3
+ "version": "0.2.6",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",
@@ -0,0 +1,114 @@
1
+ import { intro, select, spinner, note, outro, cancel, isCancel } from '@clack/prompts';
2
+ import pc from 'picocolors';
3
+ import * as fs from 'fs';
4
+ import { getGitUser } from '../../lib/git';
5
+ import {
6
+ detectWorkspaceRoot,
7
+ getWorkspaceName,
8
+ listGlobalProjects,
9
+ getLocalWorkspacePath,
10
+ getConfigPath
11
+ } from '../../lib/paths';
12
+
13
+ // Import flows
14
+ import { runSetupFlow } from './setup-flow';
15
+ import { runLinkProjectsFlow } from './link-flow';
16
+ import { runSyncToGlobalFlow } from './sync-flow';
17
+ import { runUpdateFlow } from './update-flow';
18
+
19
+ export async function runWizard() {
20
+ intro(pc.cyan(pc.inverse(' RRCE-Workflow Setup ')));
21
+
22
+ const s = spinner();
23
+ s.start('Detecting environment');
24
+
25
+ const workspacePath = detectWorkspaceRoot();
26
+ const workspaceName = getWorkspaceName(workspacePath);
27
+ const gitUser = getGitUser();
28
+
29
+ await new Promise(r => setTimeout(r, 800)); // Dramatic pause
30
+ s.stop('Environment detected');
31
+
32
+ note(
33
+ `Git User: ${pc.bold(gitUser || '(not found)')}
34
+ Workspace: ${pc.bold(workspaceName)}`,
35
+ 'Context'
36
+ );
37
+
38
+ // Check for existing projects in global storage
39
+ const existingProjects = listGlobalProjects(workspaceName);
40
+
41
+ // Check if already configured (using getConfigPath for new/legacy support)
42
+ const configFilePath = getConfigPath(workspacePath);
43
+ const isAlreadyConfigured = fs.existsSync(configFilePath);
44
+
45
+ // Check current storage mode from config
46
+ let currentStorageMode: string | null = null;
47
+ if (isAlreadyConfigured) {
48
+ try {
49
+ const configContent = fs.readFileSync(configFilePath, 'utf-8');
50
+ const modeMatch = configContent.match(/mode:\s*(global|workspace|both)/);
51
+ currentStorageMode = modeMatch?.[1] ?? null;
52
+ } catch {
53
+ // Ignore parse errors
54
+ }
55
+ }
56
+
57
+ // Check if workspace has local data that could be synced
58
+ const localDataPath = getLocalWorkspacePath(workspacePath);
59
+ const hasLocalData = fs.existsSync(localDataPath);
60
+
61
+ // If already configured, show menu
62
+ if (isAlreadyConfigured) {
63
+ const menuOptions: { value: string; label: string; hint?: string }[] = [];
64
+
65
+ // Add link option if other projects exist
66
+ if (existingProjects.length > 0) {
67
+ menuOptions.push({
68
+ value: 'link',
69
+ label: 'Link other project knowledge',
70
+ hint: `${existingProjects.length} projects available`
71
+ });
72
+ }
73
+
74
+ // Add sync to global option if using workspace-only mode
75
+ if (currentStorageMode === 'workspace' && hasLocalData) {
76
+ menuOptions.push({
77
+ value: 'sync-global',
78
+ label: 'Sync to global storage',
79
+ hint: 'Share knowledge with other projects'
80
+ });
81
+ }
82
+
83
+ menuOptions.push({ value: 'update', label: 'Update from package', hint: 'Get latest prompts & templates' });
84
+ menuOptions.push({ value: 'exit', label: 'Exit' });
85
+
86
+ const action = await select({
87
+ message: 'This workspace is already configured. What would you like to do?',
88
+ options: menuOptions,
89
+ });
90
+
91
+ if (isCancel(action) || action === 'exit') {
92
+ outro('Exited.');
93
+ process.exit(0);
94
+ }
95
+
96
+ if (action === 'link') {
97
+ await runLinkProjectsFlow(workspacePath, workspaceName, existingProjects);
98
+ return;
99
+ }
100
+
101
+ if (action === 'sync-global') {
102
+ await runSyncToGlobalFlow(workspacePath, workspaceName);
103
+ return;
104
+ }
105
+
106
+ if (action === 'update') {
107
+ await runUpdateFlow(workspacePath, workspaceName, currentStorageMode);
108
+ return;
109
+ }
110
+ }
111
+
112
+ // Run full setup flow for new workspaces
113
+ await runSetupFlow(workspacePath, workspaceName, existingProjects);
114
+ }
@@ -0,0 +1,101 @@
1
+ import { multiselect, spinner, note, outro, cancel, isCancel } from '@clack/prompts';
2
+ import pc from 'picocolors';
3
+ import * as fs from 'fs';
4
+ import { listGlobalProjects, getEffectiveRRCEHome, getConfigPath } from '../../lib/paths';
5
+ import { generateVSCodeWorkspace } from './vscode';
6
+
7
+ /**
8
+ * Run the link-only flow for adding other project knowledge to an existing workspace
9
+ */
10
+ export async function runLinkProjectsFlow(
11
+ workspacePath: string,
12
+ workspaceName: string,
13
+ existingProjects?: string[]
14
+ ) {
15
+ // Get projects if not provided
16
+ const projects = existingProjects ?? listGlobalProjects(workspaceName);
17
+
18
+ if (projects.length === 0) {
19
+ outro(pc.yellow('No other projects found in global storage.'));
20
+ return;
21
+ }
22
+
23
+ const customGlobalPath = getEffectiveRRCEHome(workspacePath);
24
+
25
+ const linkedProjects = await multiselect({
26
+ message: 'Select projects to link:',
27
+ options: projects.map(name => ({
28
+ value: name,
29
+ label: name,
30
+ hint: `${customGlobalPath}/workspaces/${name}/knowledge`
31
+ })),
32
+ required: true,
33
+ });
34
+
35
+ if (isCancel(linkedProjects)) {
36
+ cancel('Cancelled.');
37
+ process.exit(0);
38
+ }
39
+
40
+ const selectedProjects = linkedProjects as string[];
41
+
42
+ if (selectedProjects.length === 0) {
43
+ outro('No projects selected.');
44
+ return;
45
+ }
46
+
47
+ const s = spinner();
48
+ s.start('Linking projects');
49
+
50
+ // Update config.yaml with linked projects
51
+ const configFilePath = getConfigPath(workspacePath);
52
+ let configContent = fs.readFileSync(configFilePath, 'utf-8');
53
+
54
+ // Check if linked_projects section exists
55
+ if (configContent.includes('linked_projects:')) {
56
+ // Append to existing section - find and update
57
+ const lines = configContent.split('\n');
58
+ const linkedIndex = lines.findIndex(l => l.trim() === 'linked_projects:');
59
+ if (linkedIndex !== -1) {
60
+ // Find where to insert new projects (after existing ones)
61
+ let insertIndex = linkedIndex + 1;
62
+ while (insertIndex < lines.length && lines[insertIndex]?.startsWith(' - ')) {
63
+ insertIndex++;
64
+ }
65
+ // Add new projects that aren't already there
66
+ for (const name of selectedProjects) {
67
+ if (!configContent.includes(` - ${name}`)) {
68
+ lines.splice(insertIndex, 0, ` - ${name}`);
69
+ insertIndex++;
70
+ }
71
+ }
72
+ configContent = lines.join('\n');
73
+ }
74
+ } else {
75
+ // Add new linked_projects section
76
+ configContent += `\nlinked_projects:\n`;
77
+ selectedProjects.forEach(name => {
78
+ configContent += ` - ${name}\n`;
79
+ });
80
+ }
81
+
82
+ fs.writeFileSync(configFilePath, configContent);
83
+
84
+ // Update VSCode workspace file
85
+ generateVSCodeWorkspace(workspacePath, workspaceName, selectedProjects, customGlobalPath);
86
+
87
+ s.stop('Projects linked');
88
+
89
+ // Show summary
90
+ const workspaceFile = `${workspaceName}.code-workspace`;
91
+ const summary = [
92
+ `Linked projects:`,
93
+ ...selectedProjects.map(p => ` ✓ ${p}`),
94
+ ``,
95
+ `Workspace file: ${pc.cyan(workspaceFile)}`,
96
+ ];
97
+
98
+ note(summary.join('\n'), 'Link Summary');
99
+
100
+ outro(pc.green(`✓ Projects linked! Open ${pc.bold(workspaceFile)} in VSCode to access linked knowledge.`));
101
+ }