rrce-workflow 0.1.0
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/LICENSE +21 -0
- package/README.md +80 -0
- package/agent-core/prompts/documentation.md +66 -0
- package/agent-core/prompts/executor.md +58 -0
- package/agent-core/prompts/init.md +164 -0
- package/agent-core/prompts/planning_orchestrator.md +57 -0
- package/agent-core/prompts/research_discussion.md +69 -0
- package/agent-core/prompts/sync.md +56 -0
- package/agent-core/templates/docs/.gitkeep +1 -0
- package/agent-core/templates/documentation_output.md +46 -0
- package/agent-core/templates/executor_output.md +41 -0
- package/agent-core/templates/init_output.md +263 -0
- package/agent-core/templates/meta.template.json +54 -0
- package/agent-core/templates/planning_output.md +44 -0
- package/agent-core/templates/research_output.md +44 -0
- package/bin/rrce-workflow.js +2 -0
- package/docs/architecture.md +346 -0
- package/package.json +57 -0
- package/src/App.tsx +110 -0
- package/src/components/AgentSelector.tsx +43 -0
- package/src/components/Wizard.tsx +135 -0
- package/src/index.tsx +9 -0
- package/src/lib/git.ts +37 -0
- package/src/lib/paths.ts +82 -0
- package/src/lib/prompts.ts +59 -0
- package/src/types/prompt.ts +53 -0
package/src/index.tsx
ADDED
package/src/lib/git.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get git user name from config
|
|
5
|
+
*/
|
|
6
|
+
export function getGitUser(): string | null {
|
|
7
|
+
try {
|
|
8
|
+
const result = execSync('git config user.name', { encoding: 'utf-8' });
|
|
9
|
+
return result.trim() || null;
|
|
10
|
+
} catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Get git user email from config
|
|
17
|
+
*/
|
|
18
|
+
export function getGitEmail(): string | null {
|
|
19
|
+
try {
|
|
20
|
+
const result = execSync('git config user.email', { encoding: 'utf-8' });
|
|
21
|
+
return result.trim() || null;
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Check if current directory is a git repository
|
|
29
|
+
*/
|
|
30
|
+
export function isGitRepo(): boolean {
|
|
31
|
+
try {
|
|
32
|
+
execSync('git rev-parse --git-dir', { encoding: 'utf-8', stdio: 'pipe' });
|
|
33
|
+
return true;
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/lib/paths.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import type { StorageMode } from '../types/prompt';
|
|
5
|
+
|
|
6
|
+
// Environment variables
|
|
7
|
+
const RRCE_HOME = process.env.RRCE_HOME || path.join(process.env.HOME || '~', '.rrce-workflow');
|
|
8
|
+
const RRCE_WORKSPACE = process.env.RRCE_WORKSPACE;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Detect workspace root by walking up from CWD
|
|
12
|
+
*/
|
|
13
|
+
export function detectWorkspaceRoot(): string {
|
|
14
|
+
if (RRCE_WORKSPACE) {
|
|
15
|
+
return RRCE_WORKSPACE;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let current = process.cwd();
|
|
19
|
+
|
|
20
|
+
while (current !== '/') {
|
|
21
|
+
// Check for .git or .rrce-workflow.yaml
|
|
22
|
+
if (fs.existsSync(path.join(current, '.git')) ||
|
|
23
|
+
fs.existsSync(path.join(current, '.rrce-workflow.yaml'))) {
|
|
24
|
+
return current;
|
|
25
|
+
}
|
|
26
|
+
current = path.dirname(current);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return process.cwd();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get workspace name from directory or config
|
|
34
|
+
*/
|
|
35
|
+
export function getWorkspaceName(workspaceRoot: string): string {
|
|
36
|
+
// TODO: Check .rrce-workflow.yaml for project.name
|
|
37
|
+
return path.basename(workspaceRoot);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Resolve data path based on storage mode
|
|
42
|
+
*/
|
|
43
|
+
export function resolveDataPath(mode: StorageMode, workspaceName: string, workspaceRoot: string): string {
|
|
44
|
+
switch (mode) {
|
|
45
|
+
case 'global':
|
|
46
|
+
return path.join(RRCE_HOME, 'workspaces', workspaceName);
|
|
47
|
+
case 'workspace':
|
|
48
|
+
return path.join(workspaceRoot, '.rrce-workflow');
|
|
49
|
+
case 'both':
|
|
50
|
+
// Primary is workspace for 'both' mode
|
|
51
|
+
return path.join(workspaceRoot, '.rrce-workflow');
|
|
52
|
+
default:
|
|
53
|
+
return path.join(RRCE_HOME, 'workspaces', workspaceName);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get RRCE home directory
|
|
59
|
+
*/
|
|
60
|
+
export function getRRCEHome(): string {
|
|
61
|
+
return RRCE_HOME;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Ensure directory exists
|
|
66
|
+
*/
|
|
67
|
+
export function ensureDir(dirPath: string): void {
|
|
68
|
+
if (!fs.existsSync(dirPath)) {
|
|
69
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get path for agent prompts based on tool
|
|
75
|
+
*/
|
|
76
|
+
export function getAgentPromptPath(workspaceRoot: string, tool: 'copilot' | 'antigravity'): string {
|
|
77
|
+
if (tool === 'copilot') {
|
|
78
|
+
return path.join(workspaceRoot, '.github', 'agents');
|
|
79
|
+
} else {
|
|
80
|
+
return path.join(workspaceRoot, '.agent', 'workflows');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import matter from 'gray-matter';
|
|
4
|
+
import { PromptFrontmatterSchema, type ParsedPrompt } from '../types/prompt';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Parse a prompt file and extract frontmatter + content
|
|
8
|
+
*/
|
|
9
|
+
export function parsePromptFile(filePath: string): ParsedPrompt | null {
|
|
10
|
+
try {
|
|
11
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
12
|
+
const { data, content } = matter(fileContent);
|
|
13
|
+
|
|
14
|
+
const parsed = PromptFrontmatterSchema.safeParse(data);
|
|
15
|
+
|
|
16
|
+
if (!parsed.success) {
|
|
17
|
+
console.error(`Failed to parse frontmatter in ${filePath}:`, parsed.error);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
frontmatter: parsed.data,
|
|
23
|
+
content: content.trim(),
|
|
24
|
+
filePath,
|
|
25
|
+
};
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error(`Error reading prompt file ${filePath}:`, error);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Load all prompts from a directory
|
|
34
|
+
*/
|
|
35
|
+
export function loadPromptsFromDir(dirPath: string): ParsedPrompt[] {
|
|
36
|
+
if (!fs.existsSync(dirPath)) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const files = fs.readdirSync(dirPath).filter(f => f.endsWith('.md'));
|
|
41
|
+
const prompts: ParsedPrompt[] = [];
|
|
42
|
+
|
|
43
|
+
for (const file of files) {
|
|
44
|
+
const prompt = parsePromptFile(path.join(dirPath, file));
|
|
45
|
+
if (prompt) {
|
|
46
|
+
prompts.push(prompt);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return prompts;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get the agent-core prompts directory
|
|
55
|
+
*/
|
|
56
|
+
export function getAgentCorePromptsDir(): string {
|
|
57
|
+
// Relative to the package root
|
|
58
|
+
return path.join(import.meta.dir, '..', '..', 'agent-core', 'prompts');
|
|
59
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// Prompt frontmatter schema
|
|
4
|
+
export const PromptArgSchema = z.object({
|
|
5
|
+
name: z.string(),
|
|
6
|
+
default: z.string().optional(),
|
|
7
|
+
prompt: z.string().optional(),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export const AutoIdentitySchema = z.object({
|
|
11
|
+
user: z.string(),
|
|
12
|
+
model: z.string(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const PromptFrontmatterSchema = z.object({
|
|
16
|
+
name: z.string(),
|
|
17
|
+
description: z.string(),
|
|
18
|
+
'argument-hint': z.union([z.string(), z.array(z.string())]).optional(),
|
|
19
|
+
tools: z.array(z.string()).optional(),
|
|
20
|
+
'required-args': z.array(PromptArgSchema).optional(),
|
|
21
|
+
'optional-args': z.array(PromptArgSchema).optional(),
|
|
22
|
+
'auto-identity': AutoIdentitySchema.optional(),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export type PromptArg = z.infer<typeof PromptArgSchema>;
|
|
26
|
+
export type AutoIdentity = z.infer<typeof AutoIdentitySchema>;
|
|
27
|
+
export type PromptFrontmatter = z.infer<typeof PromptFrontmatterSchema>;
|
|
28
|
+
|
|
29
|
+
// Parsed prompt with content
|
|
30
|
+
export interface ParsedPrompt {
|
|
31
|
+
frontmatter: PromptFrontmatter;
|
|
32
|
+
content: string;
|
|
33
|
+
filePath: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Storage mode options
|
|
37
|
+
export type StorageMode = 'global' | 'workspace' | 'both';
|
|
38
|
+
|
|
39
|
+
// Config schema
|
|
40
|
+
export interface RRCEConfig {
|
|
41
|
+
version: number;
|
|
42
|
+
storage: {
|
|
43
|
+
mode: StorageMode;
|
|
44
|
+
};
|
|
45
|
+
workspace: {
|
|
46
|
+
name: string;
|
|
47
|
+
path: string;
|
|
48
|
+
};
|
|
49
|
+
tools: {
|
|
50
|
+
copilot: boolean;
|
|
51
|
+
antigravity: boolean;
|
|
52
|
+
};
|
|
53
|
+
}
|