vibetree 1.0.1
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/README.md +97 -0
- package/bin/vibe-flow.js +119 -0
- package/client/.eslintrc.cjs +21 -0
- package/client/dist/assets/index-BHwz5D0S.js +221 -0
- package/client/dist/assets/index-h-ov2iq3.css +32 -0
- package/client/dist/index.html +14 -0
- package/client/dist/vite.svg +1 -0
- package/client/index.html +13 -0
- package/client/package.json +35 -0
- package/client/postcss.config.js +6 -0
- package/client/public/vite.svg +1 -0
- package/client/src/App.tsx +20 -0
- package/client/src/api.ts +85 -0
- package/client/src/assets/react.svg +1 -0
- package/client/src/components/CreateTaskModal.tsx +60 -0
- package/client/src/components/KanbanBoard.tsx +159 -0
- package/client/src/components/RepoModal.tsx +155 -0
- package/client/src/components/TaskDetail.tsx +119 -0
- package/client/src/components/TerminalView.tsx +120 -0
- package/client/src/context/TaskContext.tsx +120 -0
- package/client/src/index.css +31 -0
- package/client/src/main.tsx +10 -0
- package/client/src/types.ts +33 -0
- package/client/tailwind.config.js +22 -0
- package/client/tsconfig.json +25 -0
- package/client/tsconfig.node.json +11 -0
- package/client/vite.config.ts +16 -0
- package/package.json +69 -0
- package/server/ai_tools_config.json +7 -0
- package/server/db.ts +32 -0
- package/server/dist/db.js +31 -0
- package/server/dist/git.js +127 -0
- package/server/dist/index.js +73 -0
- package/server/dist/system.js +102 -0
- package/server/dist/tasks.js +82 -0
- package/server/dist/terminal.js +195 -0
- package/server/dist/types.js +2 -0
- package/server/git.ts +140 -0
- package/server/index.ts +112 -0
- package/server/package.json +34 -0
- package/server/system.ts +109 -0
- package/server/tasks.ts +100 -0
- package/server/terminal.ts +173 -0
- package/server/tsconfig.json +19 -0
- package/server/types.ts +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Vibe-Flow
|
|
2
|
+
|
|
3
|
+
Vibe-Flow is a local AI-enhanced Kanban board designed for seamless task management and code integration. It combines a modern React frontend with a robust Node.js backend, built with TypeScript for enhanced type safety and developer experience.
|
|
4
|
+
|
|
5
|
+
## Quick Start with npx
|
|
6
|
+
|
|
7
|
+
You can launch Vibe-Flow directly using `npx` without installation:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx github:takecian/vibe-flow
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The app will start and automatically open in your default browser at `http://localhost:3000`.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- **Kanban Board**: Manage tasks with Todo, In Progress, In Review, Done, and Cancelled statuses.
|
|
18
|
+
- **Git Integration**:
|
|
19
|
+
- Select and manage local Git repositories.
|
|
20
|
+
- Create Git worktrees for each task automatically.
|
|
21
|
+
- View git status, diffs, and create commits/PRs directly from the UI.
|
|
22
|
+
- **AI Assistant Integration**:
|
|
23
|
+
- Configure and use local CLI AI tools like **Claude**, **Codex**, and **Gemini**.
|
|
24
|
+
- Robust tool detection (checks PATH and configuration files).
|
|
25
|
+
- Integrated terminal for executing AI commands and scripts.
|
|
26
|
+
- **Task Management**:
|
|
27
|
+
- Create tasks with titles and detailed descriptions.
|
|
28
|
+
- Track task progress and history.
|
|
29
|
+
- **Native System Integration**:
|
|
30
|
+
- Native directory picker for selecting repositories.
|
|
31
|
+
- Terminal emulator (xterm.js) embedded in task details.
|
|
32
|
+
- **Modern UI**:
|
|
33
|
+
- Built with React and Vite.
|
|
34
|
+
- Drag-and-drop interface (hello-pangea/dnd).
|
|
35
|
+
- Dark mode optimized.
|
|
36
|
+
- **TypeScript**:
|
|
37
|
+
- Fully typed codebase for both client and server.
|
|
38
|
+
- Strict mode enabled for maximum type safety.
|
|
39
|
+
|
|
40
|
+
## Prerequisites
|
|
41
|
+
|
|
42
|
+
- **Node.js**: (v16+ recommended)
|
|
43
|
+
- **Git**: Installed and configured.
|
|
44
|
+
- **AI Tools** (Optional but recommended):
|
|
45
|
+
- `claude` (Claude CLI)
|
|
46
|
+
- `gemini` (Gemini CLI)
|
|
47
|
+
- `codex`
|
|
48
|
+
- Ensure these are installed and available in your PATH or configured in their default home directories (e.g., `~/.gemini`).
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
1. Clone the repository:
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/takecian/vibe-flow.git
|
|
55
|
+
cd vibe-flow
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
2. Install dependencies:
|
|
59
|
+
```bash
|
|
60
|
+
npm install
|
|
61
|
+
# This will install dependencies for both root, client, and server workspaces.
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
3. Build the project (compiles TypeScript):
|
|
65
|
+
```bash
|
|
66
|
+
npm run build
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Usage
|
|
70
|
+
|
|
71
|
+
1. Start the development server (runs both client and server concurrently):
|
|
72
|
+
```bash
|
|
73
|
+
npm run dev
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
2. Open your browser and navigate to `http://localhost:5173`.
|
|
77
|
+
|
|
78
|
+
3. **Setup**:
|
|
79
|
+
- Click the **Settings** (gear icon) in the top right.
|
|
80
|
+
- Select your target Git **Repository Path**.
|
|
81
|
+
- Select your preferred **AI Assistant**.
|
|
82
|
+
|
|
83
|
+
4. **Workflow**:
|
|
84
|
+
- Create a new task.
|
|
85
|
+
- Click "Setup Worktree" in the task detail view to create an isolated environment.
|
|
86
|
+
- Use the embedded terminal to run commands or interact with the AI assistant.
|
|
87
|
+
- Drag tasks across columns to update status.
|
|
88
|
+
|
|
89
|
+
## Project Structure
|
|
90
|
+
|
|
91
|
+
- `client/`: React frontend (Vite) - TypeScript with `.tsx` components.
|
|
92
|
+
- `server/`: Express.js backend - TypeScript compiled to `dist/`.
|
|
93
|
+
- `bin/`: CLI entry point.
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
ISC
|
package/bin/vibe-flow.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { spawn, spawnSync } = require('child_process');
|
|
5
|
+
const yargs = require('yargs/yargs');
|
|
6
|
+
const { hideBin } = require('yargs/helpers');
|
|
7
|
+
const prompts = require('prompts');
|
|
8
|
+
// const open = require('open'); // Moved to dynamic import
|
|
9
|
+
|
|
10
|
+
const argv = yargs(hideBin(process.argv))
|
|
11
|
+
.option('repo', {
|
|
12
|
+
alias: 'r',
|
|
13
|
+
type: 'string',
|
|
14
|
+
description: 'Path to target repository',
|
|
15
|
+
})
|
|
16
|
+
.option('ai', {
|
|
17
|
+
alias: 'a',
|
|
18
|
+
type: 'string',
|
|
19
|
+
choices: ['claude', 'codex', 'gemini'],
|
|
20
|
+
description: 'AI tool to use',
|
|
21
|
+
})
|
|
22
|
+
.argv;
|
|
23
|
+
|
|
24
|
+
(async () => {
|
|
25
|
+
// 1. Resolve Repo Path
|
|
26
|
+
let repoPath = argv.repo ? path.resolve(argv.repo) : process.cwd();
|
|
27
|
+
|
|
28
|
+
if (!fs.existsSync(repoPath) || !fs.statSync(repoPath).isDirectory()) {
|
|
29
|
+
console.error(`Error: Repository path does not exist: ${repoPath}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 2. Resolve AI Tool
|
|
34
|
+
const configPath = path.join(repoPath, '.vibe-flow', 'config.json');
|
|
35
|
+
let config = {};
|
|
36
|
+
if (fs.existsSync(configPath)) {
|
|
37
|
+
try {
|
|
38
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
39
|
+
} catch (e) { }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let aiTool = argv.ai || config.aiTool;
|
|
43
|
+
|
|
44
|
+
if (!aiTool) {
|
|
45
|
+
const response = await prompts({
|
|
46
|
+
type: 'select',
|
|
47
|
+
name: 'aiTool',
|
|
48
|
+
message: 'Select AI tool to use:',
|
|
49
|
+
choices: [
|
|
50
|
+
{ title: 'Claude', value: 'claude' },
|
|
51
|
+
{ title: 'Codex (OpenAI)', value: 'codex' },
|
|
52
|
+
{ title: 'Gemini', value: 'gemini' },
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
aiTool = response.aiTool;
|
|
56
|
+
|
|
57
|
+
// Save preference
|
|
58
|
+
const vibeDir = path.join(repoPath, '.vibe-flow');
|
|
59
|
+
if (!fs.existsSync(vibeDir)) fs.mkdirSync(vibeDir, { recursive: true });
|
|
60
|
+
fs.writeFileSync(path.join(vibeDir, 'config.json'), JSON.stringify({ aiTool }, null, 2));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log(`Starting Vibe-Flow...`);
|
|
64
|
+
console.log(`Repository: ${repoPath}`);
|
|
65
|
+
console.log(`AI Tool: ${aiTool}`);
|
|
66
|
+
|
|
67
|
+
// 3. Start Server
|
|
68
|
+
const pkgRoot = path.join(__dirname, '..');
|
|
69
|
+
const serverPath = path.join(pkgRoot, 'server', 'dist', 'index.js');
|
|
70
|
+
const clientPath = path.join(pkgRoot, 'client', 'dist');
|
|
71
|
+
const env = {
|
|
72
|
+
...process.env,
|
|
73
|
+
REPO_PATH: repoPath,
|
|
74
|
+
AI_TOOL: aiTool,
|
|
75
|
+
VIBE_FLOW_PORT: process.env.VIBE_FLOW_PORT || 3000,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
if (!fs.existsSync(serverPath)) {
|
|
79
|
+
console.log('Building server (first run or npx)...');
|
|
80
|
+
const build = spawnSync('npm', ['run', 'build', '-w', 'server'], {
|
|
81
|
+
cwd: pkgRoot,
|
|
82
|
+
stdio: 'inherit',
|
|
83
|
+
shell: true,
|
|
84
|
+
});
|
|
85
|
+
if (build.status !== 0) {
|
|
86
|
+
console.error('Server build failed.');
|
|
87
|
+
process.exit(build.status || 1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!fs.existsSync(clientPath)) {
|
|
92
|
+
console.log('Building client dashboard (first run or npx)...');
|
|
93
|
+
const build = spawnSync('npm', ['run', 'build', '-w', 'client'], {
|
|
94
|
+
cwd: pkgRoot,
|
|
95
|
+
stdio: 'inherit',
|
|
96
|
+
shell: true,
|
|
97
|
+
});
|
|
98
|
+
if (build.status !== 0) {
|
|
99
|
+
console.error('Client build failed.');
|
|
100
|
+
process.exit(build.status || 1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
console.log('Launching server...');
|
|
105
|
+
const serverProcess = spawn('node', [serverPath], { env, stdio: 'inherit', cwd: pkgRoot });
|
|
106
|
+
|
|
107
|
+
serverProcess.on('error', (err) => {
|
|
108
|
+
console.error('Failed to start server:', err);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Open Browser
|
|
112
|
+
const { default: open } = await import('open');
|
|
113
|
+
const port = process.env.VIBE_FLOW_PORT || 3000;
|
|
114
|
+
setTimeout(() => {
|
|
115
|
+
console.log(`Opening dashboard at http://localhost:${port}...`);
|
|
116
|
+
open(`http://localhost:${port}`);
|
|
117
|
+
}, 2000);
|
|
118
|
+
|
|
119
|
+
})();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
env: { browser: true, es2020: true },
|
|
4
|
+
extends: [
|
|
5
|
+
'eslint:recommended',
|
|
6
|
+
'plugin:react/recommended',
|
|
7
|
+
'plugin:react/jsx-runtime',
|
|
8
|
+
'plugin:react-hooks/recommended',
|
|
9
|
+
],
|
|
10
|
+
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
|
11
|
+
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
|
12
|
+
settings: { react: { version: '18.2' } },
|
|
13
|
+
plugins: ['react-refresh'],
|
|
14
|
+
rules: {
|
|
15
|
+
'react/jsx-no-target-blank': 'off',
|
|
16
|
+
'react-refresh/only-export-components': [
|
|
17
|
+
'warn',
|
|
18
|
+
{ allowConstantExport: true },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
}
|