@sugar-crash-studios/vibe-forge 0.4.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/.claude/commands/clear-attention.md +63 -0
- package/.claude/commands/compact-context.md +52 -0
- package/.claude/commands/configure-vcs.md +102 -0
- package/.claude/commands/forge.md +171 -0
- package/.claude/commands/need-help.md +77 -0
- package/.claude/commands/update-status.md +64 -0
- package/.claude/commands/worker-loop.md +106 -0
- package/.claude/hooks/worker-loop.js +198 -0
- package/.claude/scripts/setup-worker-loop.sh +45 -0
- package/.claude/settings.local.json +46 -0
- package/LICENSE +21 -0
- package/README.md +238 -0
- package/agents/aegis/personality.md +294 -0
- package/agents/anvil/personality.md +276 -0
- package/agents/architect/personality.md +258 -0
- package/agents/crucible/personality.md +360 -0
- package/agents/ember/personality.md +291 -0
- package/agents/forge-master/capabilities.md +144 -0
- package/agents/forge-master/context-template.md +128 -0
- package/agents/forge-master/personality.md +138 -0
- package/agents/furnace/personality.md +340 -0
- package/agents/herald/personality.md +247 -0
- package/agents/loki/personality.md +108 -0
- package/agents/oracle/personality.md +283 -0
- package/agents/pixel/personality.md +113 -0
- package/agents/planning-hub/personality.md +320 -0
- package/agents/scribe/personality.md +251 -0
- package/agents/temper/personality.md +218 -0
- package/bin/cli.js +375 -0
- package/bin/dashboard/api/agents.js +333 -0
- package/bin/dashboard/api/dispatch.js +483 -0
- package/bin/dashboard/api/tasks.js +416 -0
- package/bin/dashboard/frontend/index.html +13 -0
- package/bin/dashboard/frontend/package.json +16 -0
- package/bin/dashboard/frontend/src/App.svelte +222 -0
- package/bin/dashboard/frontend/src/app.css +1777 -0
- package/bin/dashboard/frontend/src/lib/components/AgentCard.svelte +60 -0
- package/bin/dashboard/frontend/src/lib/components/AgentsPanel.svelte +57 -0
- package/bin/dashboard/frontend/src/lib/components/DispatchModal.svelte +180 -0
- package/bin/dashboard/frontend/src/lib/components/Footer.svelte +33 -0
- package/bin/dashboard/frontend/src/lib/components/Header.svelte +84 -0
- package/bin/dashboard/frontend/src/lib/components/IssueCard.svelte +33 -0
- package/bin/dashboard/frontend/src/lib/components/IssuesPanel.svelte +73 -0
- package/bin/dashboard/frontend/src/lib/components/KeyboardShortcutsModal.svelte +108 -0
- package/bin/dashboard/frontend/src/lib/components/MobileTabs.svelte +52 -0
- package/bin/dashboard/frontend/src/lib/components/NotificationCard.svelte +60 -0
- package/bin/dashboard/frontend/src/lib/components/NotificationsPanel.svelte +44 -0
- package/bin/dashboard/frontend/src/lib/components/TaskCard.svelte +63 -0
- package/bin/dashboard/frontend/src/lib/components/TasksPanel.svelte +82 -0
- package/bin/dashboard/frontend/src/lib/components/Toast.svelte +45 -0
- package/bin/dashboard/frontend/src/lib/stores/agents.js +34 -0
- package/bin/dashboard/frontend/src/lib/stores/issues.js +54 -0
- package/bin/dashboard/frontend/src/lib/stores/notifications.js +48 -0
- package/bin/dashboard/frontend/src/lib/stores/tasks.js +63 -0
- package/bin/dashboard/frontend/src/lib/stores/theme.js +33 -0
- package/bin/dashboard/frontend/src/lib/stores/toast.js +35 -0
- package/bin/dashboard/frontend/src/lib/stores/ui.js +25 -0
- package/bin/dashboard/frontend/src/lib/stores/voice.js +275 -0
- package/bin/dashboard/frontend/src/lib/stores/websocket.js +295 -0
- package/bin/dashboard/frontend/src/lib/utils/api.js +101 -0
- package/bin/dashboard/frontend/src/lib/utils/formatters.js +54 -0
- package/bin/dashboard/frontend/src/main.js +9 -0
- package/bin/dashboard/frontend/svelte.config.js +5 -0
- package/bin/dashboard/frontend/vite.config.js +20 -0
- package/bin/dashboard/public/assets/index-DnfVj9Ce.css +1 -0
- package/bin/dashboard/public/assets/index-Ze5h0kXQ.js +2 -0
- package/bin/dashboard/public/index.html +14 -0
- package/bin/dashboard/server.js +566 -0
- package/bin/forge-daemon.sh +463 -0
- package/bin/forge-setup.sh +645 -0
- package/bin/forge-spawn.sh +164 -0
- package/bin/forge.cmd +83 -0
- package/bin/forge.sh +533 -0
- package/bin/lib/agents.sh +177 -0
- package/bin/lib/colors.sh +44 -0
- package/bin/lib/config.sh +347 -0
- package/bin/lib/constants.sh +241 -0
- package/bin/lib/daemon/display.sh +128 -0
- package/bin/lib/daemon/notifications.sh +263 -0
- package/bin/lib/daemon/routing.sh +77 -0
- package/bin/lib/daemon/state.sh +115 -0
- package/bin/lib/daemon/sync.sh +95 -0
- package/bin/lib/database.sh +310 -0
- package/bin/lib/heimdall-setup.js +113 -0
- package/bin/lib/heimdall.js +265 -0
- package/bin/lib/json.sh +264 -0
- package/bin/lib/terminal.js +451 -0
- package/bin/lib/util.sh +126 -0
- package/bin/lib/vcs.js +349 -0
- package/config/agent-manifest.yaml +203 -0
- package/config/agents.json +168 -0
- package/config/task-template.md +159 -0
- package/config/task-types.yaml +106 -0
- package/context/agent-status/aegis.json +7 -0
- package/context/agent-status/anvil.json +7 -0
- package/context/agent-status/architect.json +7 -0
- package/context/agent-status/crucible.json +7 -0
- package/context/agent-status/ember.json +7 -0
- package/context/agent-status/furnace.json +7 -0
- package/context/agent-status/loki.json +7 -0
- package/context/agent-status/oracle.json +7 -0
- package/context/agent-status/pixel.json +7 -0
- package/context/agent-status/planning-hub.json +7 -0
- package/context/agent-status/scribe.json +7 -0
- package/context/agent-status/temper.json +7 -0
- package/context/feature-brainstorm.md +426 -0
- package/context/forge-state.yaml +19 -0
- package/context/modern-conventions.md +129 -0
- package/context/project-context-template.md +122 -0
- package/context/project-context.md +122 -0
- package/docs/TODO.md +150 -0
- package/docs/agents.md +409 -0
- package/docs/architecture/decisions/ADR-001-daemon-modularization.md +122 -0
- package/docs/architecture/vibe-lab-integration.md +684 -0
- package/docs/architecture.md +194 -0
- package/docs/bmad-gap-analysis-2026-03-31.md +444 -0
- package/docs/cleanup-workflow.md +329 -0
- package/docs/commands.md +451 -0
- package/docs/dashboard-mockup.html +989 -0
- package/docs/getting-started.md +261 -0
- package/docs/integration/forge-ownership-policy.md +112 -0
- package/docs/npm-publishing.md +132 -0
- package/docs/roadmap-2026.md +519 -0
- package/docs/security.md +144 -0
- package/docs/wireframes/dashboard-mvp.md +1164 -0
- package/docs/workflows/README.md +32 -0
- package/docs/workflows/azure-devops.md +108 -0
- package/docs/workflows/bitbucket.md +104 -0
- package/docs/workflows/git-only.md +130 -0
- package/docs/workflows/gitea.md +168 -0
- package/docs/workflows/github.md +103 -0
- package/docs/workflows/gitlab.md +105 -0
- package/docs/workflows.md +454 -0
- package/package.json +73 -0
- package/tasks/completed/ARCH-001-duplicate-agent-config.md +121 -0
- package/tasks/completed/ARCH-002-mixed-bash-node-implementation.md +88 -0
- package/tasks/completed/ARCH-003-worker-loop-hook-duplication.md +77 -0
- package/tasks/completed/ARCH-009-test-organization.md +78 -0
- package/tasks/completed/ARCH-011-jq-vs-nodejs-json.md +94 -0
- package/tasks/completed/ARCH-012-tmp-files-in-root.md +71 -0
- package/tasks/completed/ARCH-013-exit-code-constants.md +65 -0
- package/tasks/completed/ARCH-014-sed-incompatibility.md +96 -0
- package/tasks/completed/ARCH-015-docs-todo-tracking.md +83 -0
- package/tasks/completed/BUG-dash-001-tasks-filter-error.md +31 -0
- package/tasks/completed/BUG-dash-002-agents-unknown.md +41 -0
- package/tasks/completed/CLEAN-001.md +38 -0
- package/tasks/completed/CLEAN-002.md +43 -0
- package/tasks/completed/CLEAN-003.md +47 -0
- package/tasks/completed/CLEAN-004.md +56 -0
- package/tasks/completed/CLEAN-005.md +75 -0
- package/tasks/completed/CLEAN-006.md +47 -0
- package/tasks/completed/CLEAN-007.md +34 -0
- package/tasks/completed/CLEAN-008.md +49 -0
- package/tasks/completed/CLEAN-012.md +58 -0
- package/tasks/completed/CLEAN-013.md +45 -0
- package/tasks/completed/FEATURE-001a-dashboard-wireframes.md +162 -0
- package/tasks/completed/IMPL-007a-daemon-notifications-module.md +82 -0
- package/tasks/completed/IMPL-007b-daemon-sync-module.md +71 -0
- package/tasks/completed/IMPL-007c-daemon-state-module.md +80 -0
- package/tasks/completed/IMPL-007d-daemon-routing-module.md +77 -0
- package/tasks/completed/IMPL-007e-daemon-display-module.md +77 -0
- package/tasks/completed/IMPL-007f-daemon-integration.md +124 -0
- package/tasks/completed/PLAT-1-heimdall.md +420 -0
- package/tasks/completed/SEC-001-sql-injection-fix.md +58 -0
- package/tasks/completed/SEC-002-notification-injection-fix.md +45 -0
- package/tasks/completed/SEC-003-eval-injection-fix.md +54 -0
- package/tasks/completed/SEC-004-pid-race-condition-fix.md +49 -0
- package/tasks/completed/SEC-005-worker-loop-path-fix.md +51 -0
- package/tasks/completed/SEC-006-eval-agent-names.md +55 -0
- package/tasks/completed/SEC-007-spawn-escaping.md +67 -0
- package/tasks/completed/TASK-DASH-001-server-infrastructure.md +185 -0
- package/tasks/completed/TASK-anvil-001-dashboard-frontend.md +133 -0
- package/tasks/completed/review-bmad-aegis.md +89 -0
- package/tasks/completed/review-bmad-anvil.md +80 -0
- package/tasks/completed/review-bmad-crucible.md +81 -0
- package/tasks/completed/review-bmad-ember.md +90 -0
- package/tasks/completed/review-bmad-furnace.md +79 -0
- package/tasks/completed/review-bmad-pixel.md +82 -0
- package/tasks/completed/review-bmad-scribe.md +92 -0
- package/tasks/completed/review-bmad-sentinel.md +83 -0
- package/tasks/pending/ARCH-004-git-bash-detection-duplication.md +72 -0
- package/tasks/pending/ARCH-005-missing-src-directory.md +95 -0
- package/tasks/pending/ARCH-006-task-template-location.md +64 -0
- package/tasks/pending/ARCH-008-forge-master-vs-hub.md +81 -0
- package/tasks/pending/ARCH-010-missing-index-files.md +84 -0
- package/tasks/pending/CLEAN-009.md +31 -0
- package/tasks/pending/CLEAN-010.md +30 -0
- package/tasks/pending/CLEAN-011.md +30 -0
- package/tasks/pending/CLEAN-014.md +32 -0
- package/tasks/pending/DESIGN-dash-001-layout-review.md +45 -0
- package/tasks/pending/FEATURE-001-dashboard-mvp.md +268 -0
- package/tasks/review/ARCH-007-daemon-monolith.md +162 -0
- package/tasks/review/bmad-review-aegis.md +349 -0
- package/tasks/review/bmad-review-anvil.md +259 -0
- package/tasks/review/bmad-review-crucible.md +277 -0
- package/tasks/review/bmad-review-ember.md +307 -0
- package/tasks/review/bmad-review-furnace.md +285 -0
- package/tasks/review/bmad-review-pixel.md +329 -0
- package/tasks/review/bmad-review-scribe.md +361 -0
- package/tasks/review/bmad-review-sentinel.md +242 -0
- package/tasks/review/task-001.md +78 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Vibe Forge Worker Loop - Stop Hook (Cross-Platform)
|
|
4
|
+
*
|
|
5
|
+
* Implements the Ralph Loop technique for Vibe Forge workers.
|
|
6
|
+
* When a worker tries to exit, this hook checks if there are pending tasks
|
|
7
|
+
* and feeds the worker prompt back to continue working.
|
|
8
|
+
*
|
|
9
|
+
* Based on the Ralph Loop plugin by Anthropic.
|
|
10
|
+
*
|
|
11
|
+
* Activation modes:
|
|
12
|
+
* 1. Config-based: worker_loop_enabled=true in .forge/config.json
|
|
13
|
+
* 2. Runtime: State file created by /worker-loop command
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const os = require('os');
|
|
19
|
+
|
|
20
|
+
// State file location (runtime toggle)
|
|
21
|
+
const claudeLocalDir = process.env.CLAUDE_LOCAL_DIR || path.join(os.homedir(), '.claude');
|
|
22
|
+
const stateFile = path.join(claudeLocalDir, 'forge-worker-loop.json');
|
|
23
|
+
const forgeRoot = process.env.FORGE_ROOT || process.cwd();
|
|
24
|
+
|
|
25
|
+
// Helper to safely parse JSON
|
|
26
|
+
function safeJsonParse(filePath, defaultValue = {}) {
|
|
27
|
+
try {
|
|
28
|
+
if (fs.existsSync(filePath)) {
|
|
29
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
30
|
+
}
|
|
31
|
+
} catch (e) {
|
|
32
|
+
// Ignore parse errors
|
|
33
|
+
}
|
|
34
|
+
return defaultValue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Helper to count matching files
|
|
38
|
+
function countFiles(dir, pattern = '*.md') {
|
|
39
|
+
try {
|
|
40
|
+
if (!fs.existsSync(dir)) return 0;
|
|
41
|
+
const files = fs.readdirSync(dir);
|
|
42
|
+
return files.filter(f => f.endsWith('.md')).length;
|
|
43
|
+
} catch (e) {
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Helper to count files with specific content
|
|
49
|
+
function countFilesWithContent(dir, searchPattern) {
|
|
50
|
+
try {
|
|
51
|
+
if (!fs.existsSync(dir)) return 0;
|
|
52
|
+
const files = fs.readdirSync(dir).filter(f => f.endsWith('.md'));
|
|
53
|
+
let count = 0;
|
|
54
|
+
for (const file of files) {
|
|
55
|
+
try {
|
|
56
|
+
const content = fs.readFileSync(path.join(dir, file), 'utf8');
|
|
57
|
+
if (content.includes(searchPattern)) {
|
|
58
|
+
count++;
|
|
59
|
+
}
|
|
60
|
+
} catch (e) {
|
|
61
|
+
// Skip files we can't read
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return count;
|
|
65
|
+
} catch (e) {
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Output result and exit
|
|
71
|
+
function output(result) {
|
|
72
|
+
console.log(JSON.stringify(result));
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Main logic
|
|
77
|
+
function main() {
|
|
78
|
+
let loopActive = false;
|
|
79
|
+
let workerAgent = '';
|
|
80
|
+
let maxIdleChecks = 10;
|
|
81
|
+
let idleCount = 0;
|
|
82
|
+
let pollInterval = 5;
|
|
83
|
+
|
|
84
|
+
// Check for runtime state file first (takes precedence)
|
|
85
|
+
if (fs.existsSync(stateFile)) {
|
|
86
|
+
const state = safeJsonParse(stateFile);
|
|
87
|
+
loopActive = true;
|
|
88
|
+
workerAgent = state.agent || '';
|
|
89
|
+
maxIdleChecks = state.max_idle_checks || 10;
|
|
90
|
+
idleCount = state.idle_count || 0;
|
|
91
|
+
pollInterval = state.poll_interval || 5;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// If no runtime state, check config-based setting
|
|
95
|
+
if (!loopActive) {
|
|
96
|
+
const configFile = path.join(forgeRoot, '.forge', 'config.json');
|
|
97
|
+
const config = safeJsonParse(configFile);
|
|
98
|
+
if (config.worker_loop_enabled === true) {
|
|
99
|
+
loopActive = true;
|
|
100
|
+
workerAgent = 'any';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Check if worker loop is active
|
|
105
|
+
if (!loopActive) {
|
|
106
|
+
return output({ decision: 'approve' });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!workerAgent) {
|
|
110
|
+
// Invalid state, clean up and allow exit
|
|
111
|
+
try { fs.unlinkSync(stateFile); } catch (e) {}
|
|
112
|
+
return output({ decision: 'approve' });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Determine tasks directory location
|
|
116
|
+
// When running from vibe-forge repo: tasks are at ./tasks/
|
|
117
|
+
// When running from a project using vibe-forge as submodule: tasks are at ./_vibe-forge/tasks/
|
|
118
|
+
let tasksDir = path.join(forgeRoot, 'tasks');
|
|
119
|
+
if (!fs.existsSync(tasksDir)) {
|
|
120
|
+
// Fall back to submodule location
|
|
121
|
+
tasksDir = path.join(forgeRoot, '_vibe-forge', 'tasks');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Check for pending tasks
|
|
125
|
+
let pendingCount = 0;
|
|
126
|
+
let needsChangesCount = 0;
|
|
127
|
+
|
|
128
|
+
const pendingDir = path.join(tasksDir, 'pending');
|
|
129
|
+
const needsChangesDir = path.join(tasksDir, 'needs-changes');
|
|
130
|
+
|
|
131
|
+
if (workerAgent === 'any') {
|
|
132
|
+
// Config mode: count all tasks
|
|
133
|
+
pendingCount = countFiles(pendingDir);
|
|
134
|
+
needsChangesCount = countFiles(needsChangesDir);
|
|
135
|
+
} else {
|
|
136
|
+
// Runtime mode: count only tasks assigned to specific worker
|
|
137
|
+
const searchPattern = `assigned_to: ${workerAgent}`;
|
|
138
|
+
pendingCount = countFilesWithContent(pendingDir, searchPattern);
|
|
139
|
+
needsChangesCount = countFilesWithContent(needsChangesDir, searchPattern);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const totalTasks = pendingCount + needsChangesCount;
|
|
143
|
+
|
|
144
|
+
// Get relative task path for prompts (relative to forgeRoot)
|
|
145
|
+
const relativeTasksPath = path.relative(forgeRoot, tasksDir);
|
|
146
|
+
|
|
147
|
+
if (totalTasks > 0) {
|
|
148
|
+
// Tasks found! Reset idle counter and continue
|
|
149
|
+
if (fs.existsSync(stateFile)) {
|
|
150
|
+
try {
|
|
151
|
+
const state = safeJsonParse(stateFile);
|
|
152
|
+
state.idle_count = 0;
|
|
153
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2));
|
|
154
|
+
} catch (e) {}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return output({
|
|
158
|
+
decision: 'block',
|
|
159
|
+
message: `[Forge Loop] Found ${totalTasks} pending task(s). Continuing work...`,
|
|
160
|
+
prompt: `Check ${relativeTasksPath}/pending/ and ${relativeTasksPath}/needs-changes/ for tasks assigned to you and begin working on them immediately.`
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// No tasks - handle idle state
|
|
165
|
+
if (fs.existsSync(stateFile)) {
|
|
166
|
+
idleCount++;
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
const state = safeJsonParse(stateFile);
|
|
170
|
+
state.idle_count = idleCount;
|
|
171
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2));
|
|
172
|
+
} catch (e) {}
|
|
173
|
+
|
|
174
|
+
if (idleCount >= maxIdleChecks) {
|
|
175
|
+
// Max idle checks reached, clean up and allow exit
|
|
176
|
+
try { fs.unlinkSync(stateFile); } catch (e) {}
|
|
177
|
+
return output({
|
|
178
|
+
decision: 'approve',
|
|
179
|
+
message: `[Forge Loop] No tasks found after ${maxIdleChecks} checks. Exiting.`
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Still within idle limit - wait and check again
|
|
184
|
+
return output({
|
|
185
|
+
decision: 'block',
|
|
186
|
+
message: `[Forge Loop] No tasks available. Idle check ${idleCount}/${maxIdleChecks}. Waiting...`,
|
|
187
|
+
prompt: `No tasks currently assigned to you. Wait briefly, then check ${relativeTasksPath}/pending/ and ${relativeTasksPath}/needs-changes/ again for new work. If still no tasks, announce you are idle and ready.`
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Config-based mode - no idle tracking, just allow exit when no tasks
|
|
192
|
+
return output({
|
|
193
|
+
decision: 'approve',
|
|
194
|
+
message: '[Forge Loop] No pending tasks. Worker exiting.'
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
main();
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Setup Worker Loop
|
|
4
|
+
# Creates state file to enable the worker loop stop hook
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
AGENT="${1:-}"
|
|
10
|
+
MAX_IDLE="${2:-10}"
|
|
11
|
+
STATE_DIR="${CLAUDE_LOCAL_DIR:-$HOME/.claude}"
|
|
12
|
+
STATE_FILE="$STATE_DIR/forge-worker-loop.json"
|
|
13
|
+
|
|
14
|
+
if [[ "$AGENT" == "stop" ]]; then
|
|
15
|
+
if [[ -f "$STATE_FILE" ]]; then
|
|
16
|
+
rm -f "$STATE_FILE"
|
|
17
|
+
echo "Worker loop stopped."
|
|
18
|
+
else
|
|
19
|
+
echo "No active worker loop."
|
|
20
|
+
fi
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
if [[ -z "$AGENT" ]]; then
|
|
25
|
+
echo "Usage: setup-worker-loop.sh <agent> [max-idle-checks]"
|
|
26
|
+
echo " setup-worker-loop.sh stop"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Ensure state directory exists
|
|
31
|
+
mkdir -p "$STATE_DIR"
|
|
32
|
+
|
|
33
|
+
# Create state file
|
|
34
|
+
cat > "$STATE_FILE" << EOF
|
|
35
|
+
{
|
|
36
|
+
"agent": "$AGENT",
|
|
37
|
+
"max_idle_checks": $MAX_IDLE,
|
|
38
|
+
"idle_count": 0,
|
|
39
|
+
"poll_interval": 5,
|
|
40
|
+
"started_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
41
|
+
}
|
|
42
|
+
EOF
|
|
43
|
+
|
|
44
|
+
echo "Worker loop started for $AGENT (max idle: $MAX_IDLE checks)"
|
|
45
|
+
echo "State file: $STATE_FILE"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(ls:*)",
|
|
5
|
+
"Bash(git pull:*)",
|
|
6
|
+
"Bash(npm view:*)",
|
|
7
|
+
"Bash(gh run list:*)",
|
|
8
|
+
"Bash(gh run view:*)",
|
|
9
|
+
"Bash(gh secret list:*)",
|
|
10
|
+
"Bash(git add:*)",
|
|
11
|
+
"Bash(git commit:*)",
|
|
12
|
+
"Bash(gh workflow run:*)",
|
|
13
|
+
"Bash(gh repo view:*)",
|
|
14
|
+
"Bash(git push:*)",
|
|
15
|
+
"Bash(sqlite3:*)",
|
|
16
|
+
"Bash(npm test)",
|
|
17
|
+
"Bash(git rm:*)",
|
|
18
|
+
"Bash(git checkout:*)",
|
|
19
|
+
"Bash(git switch:*)"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"hooks": {
|
|
23
|
+
"PreToolUse": [
|
|
24
|
+
{
|
|
25
|
+
"matcher": "Bash",
|
|
26
|
+
"hooks": [
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "node G:/dev/vibe-forge/bin/lib/heimdall.js"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"Stop": [
|
|
35
|
+
{
|
|
36
|
+
"matcher": "",
|
|
37
|
+
"hooks": [
|
|
38
|
+
{
|
|
39
|
+
"type": "command",
|
|
40
|
+
"command": "node G:/dev/vibe-forge/.claude/hooks/worker-loop.js"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SpasticPalate
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Vibe Forge ⚒️
|
|
2
|
+
|
|
3
|
+
A multi-agent development orchestration system for terminal-native vibe coding.
|
|
4
|
+
|
|
5
|
+
## Vision
|
|
6
|
+
|
|
7
|
+
Vibe Forge transforms your terminal into a collaborative AI development environment. Multiple Claude agents - each with distinct personalities and specializations - work together to build software, coordinated through a file-based task system.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
11
|
+
│ PLANNING HUB │
|
|
12
|
+
│ (Your main terminal session) │
|
|
13
|
+
│ │
|
|
14
|
+
│ You + Architect · Aegis · Ember · Pixel · Oracle │
|
|
15
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
16
|
+
│
|
|
17
|
+
▼
|
|
18
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
19
|
+
│ FORGE MASTER ⚒️ │
|
|
20
|
+
│ Task Distribution & Orchestration │
|
|
21
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
22
|
+
│
|
|
23
|
+
┌────────────┬───────┴───────┬────────────┐
|
|
24
|
+
▼ ▼ ▼ ▼
|
|
25
|
+
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
26
|
+
│ Anvil │ │ Furnace │ │Crucible │ │Sentinel │
|
|
27
|
+
│ 🔨 │ │ 🔥 │ │ 🧪 │ │ 🛡️ │
|
|
28
|
+
│Frontend │ │ Backend │ │ Testing │ │ Review │
|
|
29
|
+
└─────────┘ └─────────┘ └─────────┘ └─────────┘
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Key Features
|
|
33
|
+
|
|
34
|
+
- **Personality-driven agents** - Each agent has a distinct voice, expertise, and decision-making style
|
|
35
|
+
- **File-based task coordination** - Reliable, debuggable, no WebSocket complexity
|
|
36
|
+
- **Token-efficient design** - Context stored locally, minimal wire traffic
|
|
37
|
+
- **Terminal-native** - Built for Windows Terminal, works with any terminal supporting tabs
|
|
38
|
+
|
|
39
|
+
## Agents
|
|
40
|
+
|
|
41
|
+
### Core Agents (Always Running)
|
|
42
|
+
|
|
43
|
+
| Agent | Icon | Role |
|
|
44
|
+
|-------|------|------|
|
|
45
|
+
| Forge Master | ⚒️ | Chief Orchestrator - distributes tasks, tracks progress |
|
|
46
|
+
| Sentinel | 🛡️ | Code Reviewer - quality gates, adversarial review |
|
|
47
|
+
|
|
48
|
+
### Worker Agents (Per-Task)
|
|
49
|
+
|
|
50
|
+
| Agent | Icon | Role |
|
|
51
|
+
|-------|------|------|
|
|
52
|
+
| Anvil | 🔨 | Frontend Dev - components, UI, styling |
|
|
53
|
+
| Furnace | 🔥 | Backend Dev - APIs, database, services |
|
|
54
|
+
| Crucible | 🧪 | Tester/QA - tests, bug hunting |
|
|
55
|
+
| Scribe | 📜 | Documentation - docs, README, API specs |
|
|
56
|
+
| Herald | 📯 | Release Manager - versioning, deployment |
|
|
57
|
+
|
|
58
|
+
### Planning Hub Voices (Your Terminal)
|
|
59
|
+
|
|
60
|
+
The Planning Hub is a **multi-voice planning session** — not separate agents. When you run `forge hub`, these expert voices collaborate in a single session:
|
|
61
|
+
|
|
62
|
+
| Voice | Icon | Expertise |
|
|
63
|
+
|-------|------|-----------|
|
|
64
|
+
| Forge Master | 🔥 | Orchestration & task coordination |
|
|
65
|
+
| Architect | 🏛️ | Technical design & architecture |
|
|
66
|
+
| Aegis | 🔒 | Security & risk |
|
|
67
|
+
| Ember | ⚙️ | DevOps & infrastructure |
|
|
68
|
+
| Pixel | 🎨 | User experience & design |
|
|
69
|
+
| Oracle | 📊 | Requirements & scope |
|
|
70
|
+
| Crucible | 🧪 | Quality & edge cases |
|
|
71
|
+
|
|
72
|
+
### Specialists (On-Demand)
|
|
73
|
+
|
|
74
|
+
| Agent | Icon | Role |
|
|
75
|
+
|-------|------|------|
|
|
76
|
+
| Architect | 🏛️ | System Architect |
|
|
77
|
+
| Ember | ⚙️ | DevOps/Infrastructure |
|
|
78
|
+
| Aegis | 🔒 | Security Specialist |
|
|
79
|
+
|
|
80
|
+
## Project Structure
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
vibe-forge/
|
|
84
|
+
├── agents/ # Agent definitions
|
|
85
|
+
│ ├── forge-master/
|
|
86
|
+
│ │ ├── personality.md # Identity, voice, principles
|
|
87
|
+
│ │ ├── capabilities.md # Commands, tools, decisions
|
|
88
|
+
│ │ └── context-template.md # Session startup context
|
|
89
|
+
│ ├── sentinel/
|
|
90
|
+
│ ├── anvil/
|
|
91
|
+
│ ├── furnace/
|
|
92
|
+
│ ├── crucible/
|
|
93
|
+
│ └── ...
|
|
94
|
+
├── tasks/ # Task lifecycle folders
|
|
95
|
+
│ ├── pending/ # New tasks waiting for pickup
|
|
96
|
+
│ ├── in-progress/ # Currently being worked on
|
|
97
|
+
│ ├── completed/ # Done, ready for review
|
|
98
|
+
│ ├── review/ # Under Sentinel review
|
|
99
|
+
│ ├── approved/ # Passed review
|
|
100
|
+
│ ├── needs-changes/ # Review feedback to address
|
|
101
|
+
│ └── merged/ # Archive
|
|
102
|
+
├── specs/ # Planning documents
|
|
103
|
+
│ ├── epics/
|
|
104
|
+
│ └── stories/
|
|
105
|
+
├── context/ # Shared context files
|
|
106
|
+
│ ├── project-context.md # Tech stack, patterns, rules
|
|
107
|
+
│ └── forge-state.yaml # Current forge status
|
|
108
|
+
└── config/ # Configuration
|
|
109
|
+
├── agents.json # Agent roster (source of truth)
|
|
110
|
+
├── agent-manifest.yaml # Agent documentation (non-normative)
|
|
111
|
+
├── task-template.md # Task file template
|
|
112
|
+
└── task-types.yaml # Task routing rules
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Task Lifecycle
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
┌─────────┐ ┌─────────────┐ ┌───────────┐ ┌────────┐
|
|
119
|
+
│ pending │ -> │ in-progress │ -> │ completed │ -> │ review │
|
|
120
|
+
└─────────┘ └─────────────┘ └───────────┘ └────────┘
|
|
121
|
+
│
|
|
122
|
+
┌──────────────┐ │
|
|
123
|
+
│ needs-changes│ <────────────────┤
|
|
124
|
+
└──────────────┘ │
|
|
125
|
+
│ │
|
|
126
|
+
▼ ▼
|
|
127
|
+
┌─────────────┐ ┌──────────┐
|
|
128
|
+
│ in-progress │ │ approved │
|
|
129
|
+
└─────────────┘ └──────────┘
|
|
130
|
+
│
|
|
131
|
+
▼
|
|
132
|
+
┌─────────┐
|
|
133
|
+
│ merged │
|
|
134
|
+
└─────────┘
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Getting Started
|
|
138
|
+
|
|
139
|
+
### Prerequisites
|
|
140
|
+
|
|
141
|
+
- Claude Code CLI ([install](https://claude.ai/download))
|
|
142
|
+
- Windows Terminal (recommended) or any terminal with tabs
|
|
143
|
+
- Node.js 16+ (for npx installer)
|
|
144
|
+
- Git
|
|
145
|
+
|
|
146
|
+
### Quick Start
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# In your project directory
|
|
150
|
+
npx vibe-forge init
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
This will:
|
|
154
|
+
|
|
155
|
+
1. Clone Vibe Forge into `_vibe-forge/`
|
|
156
|
+
2. Detect your platform and terminal
|
|
157
|
+
3. Set up the daemon and configuration
|
|
158
|
+
4. Create a project context file
|
|
159
|
+
|
|
160
|
+
Then start the Planning Hub:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cd _vibe-forge
|
|
164
|
+
./bin/forge.sh
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Manual Setup
|
|
168
|
+
|
|
169
|
+
If you prefer not to use npx:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Clone into your project
|
|
173
|
+
git clone https://github.com/SpasticPalate/vibe-forge.git _vibe-forge
|
|
174
|
+
|
|
175
|
+
# Run setup
|
|
176
|
+
cd _vibe-forge
|
|
177
|
+
./bin/forge-setup.sh
|
|
178
|
+
|
|
179
|
+
# Start the Planning Hub
|
|
180
|
+
./bin/forge.sh
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Updating
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
npx vibe-forge update
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Slash Commands
|
|
190
|
+
|
|
191
|
+
When using Claude Code inside your project, use the `/forge` command:
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
/forge - Start the Planning Hub (default)
|
|
195
|
+
/forge status - Show status dashboard
|
|
196
|
+
/forge spawn <agent> - Spawn worker in new terminal
|
|
197
|
+
/forge task [desc] - Create a new task
|
|
198
|
+
/forge help - Show available commands
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Agents (with aliases):
|
|
202
|
+
|
|
203
|
+
| Agent | Aliases | Role |
|
|
204
|
+
|-------|---------|------|
|
|
205
|
+
| anvil | frontend, ui, fe | Frontend Developer |
|
|
206
|
+
| furnace | backend, api, be | Backend Developer |
|
|
207
|
+
| crucible | test, testing, qa | Tester / QA |
|
|
208
|
+
| sentinel | review, reviewer, cr | Code Reviewer |
|
|
209
|
+
| scribe | docs, documentation | Documentation |
|
|
210
|
+
| herald | release, deploy | Release Manager |
|
|
211
|
+
| ember | devops, ops, infra | DevOps |
|
|
212
|
+
| aegis | security, sec, appsec | Security |
|
|
213
|
+
|
|
214
|
+
Use either the forge name or any alias: `/forge spawn frontend` or `/forge spawn anvil`
|
|
215
|
+
|
|
216
|
+
## Token Efficiency
|
|
217
|
+
|
|
218
|
+
Vibe Forge is designed for minimal token usage:
|
|
219
|
+
|
|
220
|
+
1. **Local context** - Agents read from files, not conversation history
|
|
221
|
+
2. **Task files as truth** - Instructions in files, not repeated in chat
|
|
222
|
+
3. **Reference, don't duplicate** - Point to paths, don't paste contents
|
|
223
|
+
4. **Batch updates** - One status report per cycle, not per task
|
|
224
|
+
5. **Exception-based** - Report problems, not smooth operations
|
|
225
|
+
|
|
226
|
+
## Philosophy
|
|
227
|
+
|
|
228
|
+
> "A forge is not a factory. Each piece is crafted with intention."
|
|
229
|
+
|
|
230
|
+
Vibe Forge embraces the craft of software development. Each agent brings expertise and personality to their work. The goal isn't maximum automation - it's maximum collaboration between human and AI.
|
|
231
|
+
|
|
232
|
+
## Acknowledgments
|
|
233
|
+
|
|
234
|
+
Inspired by BMAD (Business Model-Agnostic Development) methodology and its multi-agent workflow system.
|
|
235
|
+
|
|
236
|
+
## License
|
|
237
|
+
|
|
238
|
+
MIT
|