Not in the top 1,000 by GitHub stars
tolimarchuk/goalbuddy
A better /goal for Codex and Claude Code
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
goalbuddy/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → e9823cc64cf1
No earlier version was observed for comparison.
plugins/goalbuddy/skills/goal-prep/SKILL.md
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → e9823cc64cf1
No earlier version was observed for comparison.
Verified commit e9823cc64cf1473c78e879831e955d53161ca5d1
git clone --filter=blob:none --no-checkout https://github.com/tolimarchuk/goalbuddy.git .hotskills/tolimarchuk-goalbuddy && git -C .hotskills/tolimarchuk-goalbuddy checkout --detach e9823cc64cf1473c78e879831e955d53161ca5d1
# Copy each selected skill directory from .hotskills/tolimarchuk-goalbuddy into .claude/skills/<skill-name>/git clone --filter=blob:none --no-checkout https://github.com/tolimarchuk/goalbuddy.git .hotskills/tolimarchuk-goalbuddy && git -C .hotskills/tolimarchuk-goalbuddy checkout --detach e9823cc64cf1473c78e879831e955d53161ca5d1
# Copy each selected skill directory from .hotskills/tolimarchuk-goalbuddy into .agents/skills/<skill-name>/Heat
0.1- Star growth, last 7 daysNot available
- Star growth, last 24 hoursNot available
- Rank movement, last 7 daysNot available
- Commits, last 30 daysNot available
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekNot available
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
Individual skills in this repository
How it works
goal-prep
When your agent uses it
Goal Prep for GoalBuddy. Use for broad, long-running, stalled, vague, detailed, planned, or unhealthy Codex or Claude Code work that needs a structured /goal intake, autonomous task discovery, role-tagged Scout/Judge/Worker delegation, one active task, durable receipts, and a PM-owned rolling board that maximizes the chance of a successful goal run.
What it loads into context
Frontmatter
83 tokensAlways available to the agent
SKILL.md
5,367 tokensWhen the skill is activated
Reference documents
8,195 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Invocation Boundary
- Update Check
- Intake Compiler
- Guided Intake Surface
- What `$goal-prep` Does
- Slice Sizing Policy
- When To Use
- The Four Primitives
- Control Files
- Charter
- Board
- Seed Boards
- Agents
- Default Execution Shape
Scripts executed separately
scripts/apply-receipt.mjsscripts/check-can-stop.mjsscripts/check-goal-state.mjsscripts/check-update.mjsscripts/dispatch-task.mjsscripts/install-agents.mjsscripts/parallel-plan.mjsscripts/render-task-prompt.mjssurfaces/local-goal-board/scripts/lib/goal-board.mjssurfaces/local-goal-board/scripts/local-goal-board.mjssurfaces/local-goal-board/test/local-goal-board.test.mjs
Files
../.claude-plugin/marketplace.jsonasset518 bytesSKILL.mdcore24,449 bytesSKILL.mdcore24,449 bytesagents/README.mddoc1,082 bytesagents/config-snippet.tomlasset131 bytesagents/goal_judge.tomlasset3,008 bytesagents/goal_scout.tomlasset1,776 bytesagents/goal_worker.tomlasset3,088 bytesagents/openai.yamlasset653 bytesreferences/goal-execution.mddoc24,233 bytesscripts/apply-receipt.mjsruns9,205 bytesscripts/check-can-stop.mjsruns2,676 bytesscripts/check-goal-state.mjsruns26,140 bytesscripts/check-update.mjsruns4,011 bytesscripts/dispatch-task.mjsruns11,257 bytesscripts/install-agents.mjsruns1,178 bytesscripts/parallel-plan.mjsruns6,432 bytesscripts/render-task-prompt.mjsruns14,194 bytessurfaces/local-goal-board/README.mddoc3,215 bytessurfaces/local-goal-board/assets/goalbuddy-mark.pngasset1,198,990 bytessurfaces/local-goal-board/examples/sample-goal/.gitignoreasset18 bytessurfaces/local-goal-board/examples/sample-goal/notes/T001-scout.mddoc94 bytessurfaces/local-goal-board/examples/sample-goal/state.yamlasset3,415 bytessurfaces/local-goal-board/examples/subgoal-parent/goal.mddoc95 bytessurfaces/local-goal-board/examples/subgoal-parent/notes/.gitkeepasset1 bytessurfaces/local-goal-board/examples/subgoal-parent/state.yamlasset1,488 bytessurfaces/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/goal.mddoc77 bytessurfaces/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/notes/.gitkeepasset1 bytessurfaces/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/state.yamlasset1,258 bytessurfaces/local-goal-board/scripts/lib/goal-board.mjsruns71,275 bytessurfaces/local-goal-board/scripts/local-goal-board.mjsruns21,375 bytessurfaces/local-goal-board/test/local-goal-board.test.mjsruns37,841 bytestemplates/agents.mddoc1,805 bytestemplates/goal-prompt.txtdoc105 bytestemplates/goal.mddoc6,386 bytestemplates/note.mddoc379 bytestemplates/state.yamlasset5,405 bytes../plugins/goalbuddy/.claude-plugin/plugin.jsonasset602 bytes
Read SKILL.md
# Goal Prep
`$goal-prep` (Codex) or `/goal-prep` (Claude Code) prepares a GoalBuddy board. It does not start execution automatically, but the board and harness-specific starter command must be shaped so the next run continues into safe execution by default.
GoalBuddy is for autonomous, long-running Codex or Claude Code work where the PM thread may need to discover the work, define tasks, sequence them, delegate them, execute them, verify them, and keep going without the human decomposing every step.
The loop is:
```text
raw user intent -> intake compiler -> goal oracle -> local work surface -> one active task -> receipt -> proof loop -> repeat
```
GoalBuddy's core invariant is:
View the complete source on GitHubgoal-prep
When your agent uses it
Goal Prep for GoalBuddy. Use for broad, long-running, stalled, vague, detailed, planned, or unhealthy Codex or Claude Code work that needs a structured /goal intake, autonomous task discovery, role-tagged Scout/Judge/Worker delegation, one active task, durable receipts, and a PM-owned rolling board that maximizes the chance of a successful goal run.
What it loads into context
Frontmatter
83 tokensAlways available to the agent
SKILL.md
5,367 tokensWhen the skill is activated
Reference documents
8,195 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Invocation Boundary
- Update Check
- Intake Compiler
- Guided Intake Surface
- What `$goal-prep` Does
- Slice Sizing Policy
- When To Use
- The Four Primitives
- Control Files
- Charter
- Board
- Seed Boards
- Agents
- Default Execution Shape
Scripts executed separately
scripts/apply-receipt.mjsscripts/check-can-stop.mjsscripts/check-goal-state.mjsscripts/check-update.mjsscripts/dispatch-task.mjsscripts/install-agents.mjsscripts/parallel-plan.mjsscripts/render-task-prompt.mjssurfaces/local-goal-board/scripts/lib/goal-board.mjssurfaces/local-goal-board/scripts/local-goal-board.mjssurfaces/local-goal-board/test/local-goal-board.test.mjs
Files
SKILL.mdcore24,449 bytesSKILL.mdcore24,449 bytesagents/README.mddoc1,082 bytesagents/config-snippet.tomlasset131 bytesagents/goal_judge.tomlasset3,008 bytesagents/goal_scout.tomlasset1,776 bytesagents/goal_worker.tomlasset3,088 bytesagents/openai.yamlasset653 bytesreferences/goal-execution.mddoc24,233 bytesscripts/apply-receipt.mjsruns9,205 bytesscripts/check-can-stop.mjsruns2,676 bytesscripts/check-goal-state.mjsruns26,140 bytesscripts/check-update.mjsruns4,011 bytesscripts/dispatch-task.mjsruns11,257 bytesscripts/install-agents.mjsruns1,178 bytesscripts/parallel-plan.mjsruns6,432 bytesscripts/render-task-prompt.mjsruns14,194 bytessurfaces/local-goal-board/README.mddoc3,215 bytessurfaces/local-goal-board/assets/goalbuddy-mark.pngasset1,198,990 bytessurfaces/local-goal-board/examples/sample-goal/.gitignoreasset18 bytessurfaces/local-goal-board/examples/sample-goal/notes/T001-scout.mddoc94 bytessurfaces/local-goal-board/examples/sample-goal/state.yamlasset3,415 bytessurfaces/local-goal-board/examples/subgoal-parent/goal.mddoc95 bytessurfaces/local-goal-board/examples/subgoal-parent/notes/.gitkeepasset1 bytessurfaces/local-goal-board/examples/subgoal-parent/state.yamlasset1,488 bytessurfaces/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/goal.mddoc77 bytessurfaces/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/notes/.gitkeepasset1 bytessurfaces/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/state.yamlasset1,258 bytessurfaces/local-goal-board/scripts/lib/goal-board.mjsruns71,275 bytessurfaces/local-goal-board/scripts/local-goal-board.mjsruns21,375 bytessurfaces/local-goal-board/test/local-goal-board.test.mjsruns37,841 bytestemplates/agents.mddoc1,805 bytestemplates/goal-prompt.txtdoc105 bytestemplates/goal.mddoc6,386 bytestemplates/note.mddoc379 bytestemplates/state.yamlasset5,405 bytes
Read SKILL.md
# Goal Prep
`$goal-prep` (Codex) or `/goal-prep` (Claude Code) prepares a GoalBuddy board. It does not start execution automatically, but the board and harness-specific starter command must be shaped so the next run continues into safe execution by default.
GoalBuddy is for autonomous, long-running Codex or Claude Code work where the PM thread may need to discover the work, define tasks, sequence them, delegate them, execute them, verify them, and keep going without the human decomposing every step.
The loop is:
```text
raw user intent -> intake compiler -> goal oracle -> local work surface -> one active task -> receipt -> proof loop -> repeat
```
GoalBuddy's core invariant is:
View the complete source on GitHubSkills included
- goal-prep
- goal-prep
Repository facts
- License
- MIT
- Created
- May 3, 2026
- Last pushed
- Oct 2, 2026
- Forks
- 66
- Open issues
- 4
- Project activity
- Active
Rank over the last 12 weeks
Now #999 · best #631 · down 262 in 30 days
- #841 on Oct 23
- #802 on Oct 24
- #984 on Oct 25
- #995 on Oct 28
- #998 on Oct 29
- #999 since Oct 30
26 earlier periods
- #630 on Aug 2
- #632 on Aug 5
- #631 on Aug 9
- #659 on Aug 10
- #666 on Aug 11
- #659 on Aug 14
- #662 on Aug 17
- #680 on Aug 18
- #668 on Aug 20
- #639 on Aug 22
- #690 on Aug 24
- #693 on Aug 25
- #663 on Aug 30
- #711 on Sep 1
- #700 on Sep 2
- #698 on Sep 6
- #712 on Sep 11
- #710 on Sep 12
- #738 on Sep 14
- #740 on Sep 16
- #756 on Sep 23
- #708 on Sep 26
- #737 on Sep 27
- #826 on Oct 14
- #819 on Oct 16
- #855 on Oct 21
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 4, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 2 notes
goalbuddy/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedplugins/goalbuddy/skills/goal-prep/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzed
- No broad tool permissions
- No dangerous shell commands
- No hidden or obfuscated text
- No instruction overrides
- 22 executable scriptsin 22 files: goalbuddy/scripts/apply-receipt.mjs:1 goalbuddy/scripts/check-can-stop.mjs:1 goalbuddy/scripts/check-goal-state.mjs:1 and 19 more
- No access to secrets
- No requests to vote in Hot
Show all 200 signals by file
.claude-plugin/marketplace.json
goalbuddy/SKILL.md
- Network accessline 98
If the user chooses the local live board, create the goal directory, `notes/`, and an initial minimal `state.yaml` as soon as the slug is known, then run `node <skill-path>/surfaces/local-goal-board/scripts/local-goal-board.mjs --goal docs/ - Network accessline 100
If `http://goalbuddy.localhost:41737/<slug>/` returns 404, do not assume the existing process is stale and do not stop it. First check `http://127.0.0.1:41737/api/boards`. If that endpoint returns board JSON, the port is the shared multi-bo
goalbuddy/references/goal-execution.md
- Network accessline 224
If a local board server is running, compare `state.yaml` with `http://127.0.0.1:41737/<slug>/api/board` or `http://127.0.0.1:41737/api/boards`. Repair only GoalBuddy control files: `goal.md`, `state.yaml`, `notes/`, depth-1 `subgoals/`, and
goalbuddy/scripts/apply-receipt.mjs
- Executable scriptline 1
#!/usr/bin/env node
goalbuddy/scripts/check-can-stop.mjs
- Executable scriptline 1
#!/usr/bin/env node
goalbuddy/scripts/check-goal-state.mjs
- Executable scriptline 1
#!/usr/bin/env node
goalbuddy/scripts/check-update.mjs
- Executable scriptline 1
#!/usr/bin/env node
goalbuddy/scripts/dispatch-task.mjs
- Executable scriptline 1
#!/usr/bin/env node
goalbuddy/scripts/install-agents.mjs
- Executable scriptline 1
#!/usr/bin/env node
goalbuddy/scripts/parallel-plan.mjs
- Executable scriptline 1
#!/usr/bin/env node
goalbuddy/scripts/render-task-prompt.mjs
- Executable scriptline 1
#!/usr/bin/env node
goalbuddy/surfaces/local-goal-board/README.md
- Network accessline 31
Then it starts or reuses the shared local board hub at `http://goalbuddy.localhost:41737/`. The server still binds to loopback, so no `/etc/hosts` setup is required. The printed board URL includes the goal slug, like `http://goalbuddy.local - Network accessline 73
- `state.yaml` remains the source of truth. - The server binds to `127.0.0.1:41737` by default, advertises `http://goalbuddy.localhost:41737/`, and reuses that URL as a multi-board hub with in-board header navigation. - Network accessline 74
- The server binds to `127.0.0.1:41737` by default, advertises `http://goalbuddy.localhost:41737/`, and reuses that URL as a multi-board hub with in-board header navigation.
goalbuddy/surfaces/local-goal-board/scripts/lib/goal-board.mjs
- Executable scriptline 1
Executable file - Network accessline 784
</div> <div class="header-tools"> <a class="github-stars" href="https://github.com/tolimarchuk/goalbuddy" target="_blank" rel="noreferrer" aria-label="Open GoalBuddy on GitHub"> - Network accessline 785
<div class="header-tools"> <a class="github-stars" href="https://github.com/tolimarchuk/goalbuddy" target="_blank" rel="noreferrer" aria-label="Open GoalBuddy on GitHub"> <svg viewBox="0 0 24 24" aria-hidden="true"><path d="m1 - Network accessline 786
<a class="github-stars" href="https://github.com/tolimarchuk/goalbuddy" target="_blank" rel="noreferrer" aria-label="Open GoalBuddy on GitHub"> - Network accessline 1961
async function loadBoard() { const response = await fetch("./api/board", { cache: "no-store" }); - Network accessline 1962
const response = await fetch("./api/board", { cache: "no-store" }); - Network accessline 1967
async function loadBoardSwitcher() { const response = await fetch("../api/boards", { cache: "no-store" }); - Network accessline 1968
const response = await fetch("../api/boards", { cache: "no-store" }); - Network accessline 1974
async function loadSettings() { try { const response = await fetch("../api/settings", { cache: "no-store" }); - Network accessline 1975
try { const response = await fetch("../api/settings", { cache: "no-store" }); if (!response.ok) throw new Error("Settings request failed"); - Network accessline 1976
const response = await fetch("../api/settings", { cache: "no-store" }); - Network accessline 1990
applySettings(currentSettings); try { const response = await fetch("../api/settings", { - Network accessline 1991
try { const response = await fetch("../api/settings", { method: "PUT", - Network accessline 1992
const response = await fetch("../api/settings", { - Network accessline 2044
currentSettings = nextSettings; window.localStorage?.setItem(settingsStorageKey, JSON.stringify(nextSettings)); fetch("../api/settings", { - Network accessline 2045
window.localStorage?.setItem(settingsStorageKey, JSON.stringify(nextSettings)); fetch("../api/settings", { method: "PUT", - Network accessline 2046
fetch("../api/settings", { - Network accessline 2070
if (!githubStarsEl) return; try { const response = await fetch("https://api.github.com/repos/tolimarchuk/goalbuddy", { - Network accessline 2071
try { const response = await fetch("https://api.github.com/repos/tolimarchuk/goalbuddy", { headers: { Accept: "application/vnd.github+json" }, - Network accessline 2072
const response = await fetch("https://api.github.com/repos/tolimarchuk/goalbuddy", {
goalbuddy/surfaces/local-goal-board/scripts/local-goal-board.mjs
- Executable scriptline 1
#!/usr/bin/env node - Network accessline 204
return; } const url = new URL(request.url || "/", `http://${request.headers.host || "127.0.0.1"}`); - Network accessline 205
} const url = new URL(request.url || "/", `http://${request.headers.host || "127.0.0.1"}`); if (request.method === "POST" && url.pathname === "/api/boards") { - Network accessline 206
const url = new URL(request.url || "/", `http://${request.headers.host || "127.0.0.1"}`); - Network accessline 278
const address = server.address(); const actualPort = typeof address === "object" && address ? address.port : port; baseUrl = `http://${publicHost || host}:${actualPort}`; - Network accessline 279
const actualPort = typeof address === "object" && address ? address.port : port; baseUrl = `http://${publicHost || host}:${actualPort}`; const initialSummary = addBoard(goalDir, appDir); - Network accessline 280
baseUrl = `http://${publicHost || host}:${actualPort}`; - Network accessline 296
async function registerWithBoardHub({ goalDir, host, port }) { const response = await fetch(`http://${host}:${port}/api/boards`, { - Network accessline 297
const response = await fetch(`http://${host}:${port}/api/boards`, { - Network accessline 540
if (!rawHost) return false; try { return allowedHostnames.has(new URL(`http://${rawHost}`).hostname.toLowerCase()); - Network accessline 541
try { return allowedHostnames.has(new URL(`http://${rawHost}`).hostname.toLowerCase()); } catch { - Network accessline 542
return allowedHostnames.has(new URL(`http://${rawHost}`).hostname.toLowerCase());
goalbuddy/surfaces/local-goal-board/test/local-goal-board.test.mjs
- Executable scriptline 1
Executable file - Network accessline 368
const server = await startBoardServer({ goalDir, host: "127.0.0.1", port: 0 }); try { const initialResponse = await fetch(`${server.hubUrl}api/settings`); - Network accessline 369
try { const initialResponse = await fetch(`${server.hubUrl}api/settings`); assert.equal(initialResponse.status, 200); - Network accessline 370
const initialResponse = await fetch(`${server.hubUrl}api/settings`); - Network accessline 381
const updateResponse = await fetch(`${server.hubUrl}api/settings`, { - Network accessline 407
const partialResponse = await fetch(`${server.hubUrl}api/settings`, { - Network accessline 422
const invalidResponse = await fetch(`${server.hubUrl}api/settings`, { - Network accessline 484
const loopbackResponse = await fetch(`http://127.0.0.1:${url.port}/api/boards`); - Network accessline 525
try { assert.match(server.url, /\/live-board\/$/); const boardResponse = await fetch(`${server.url}api/board`); - Network accessline 526
assert.match(server.url, /\/live-board\/$/); const boardResponse = await fetch(`${server.url}api/board`); assert.equal(boardResponse.status, 200); - Network accessline 527
const boardResponse = await fetch(`${server.url}api/board`); - Network accessline 532
const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 533
const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 564
try { const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 565
const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); assert.equal(events.status, 200); - Network accessline 566
const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 607
try { const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 608
const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); assert.equal(events.status, 200); - Network accessline 609
const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 640
const server = await startBoardServer({ goalDir: firstGoalDir, host: "127.0.0.1", port: 0 }); try { const registerResponse = await fetch(server.apiUrl, { - Network accessline 641
try { const registerResponse = await fetch(server.apiUrl, { method: "POST", - Network accessline 642
const registerResponse = await fetch(server.apiUrl, { - Network accessline 656
const hubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 660
const noSlashResponse = await fetch(`${secondUrl.origin}/second-goal`, { redirect: "manual" }); - Network accessline 664
const boardsResponse = await fetch(server.apiUrl); - Network accessline 669
const newestSettingsResponse = await fetch(`${firstUrl.origin}/api/settings`, { - Network accessline 673
}); assert.equal(newestSettingsResponse.status, 200); const newestHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 674
assert.equal(newestSettingsResponse.status, 200); const newestHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); assert.equal(newestHubResponse.status, 302); - Network accessline 675
const newestHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 679
const lastSettingsResponse = await fetch(`${firstUrl.origin}/api/settings`, { - Network accessline 683
}); assert.equal(lastSettingsResponse.status, 200); const lastHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 684
assert.equal(lastSettingsResponse.status, 200); const lastHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); assert.equal(lastHubResponse.status, 302); - Network accessline 685
const lastHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 689
const secondBoardResponse = await fetch(`${second.url}api/board`); - Network accessline 714
try { const baseUrl = new URL(server.url).origin; const missingResponse = await fetch(`${baseUrl}/unregistered-example-board/`); - Network accessline 715
const baseUrl = new URL(server.url).origin; const missingResponse = await fetch(`${baseUrl}/unregistered-example-board/`); assert.equal(missingResponse.status, 404); - Network accessline 716
const missingResponse = await fetch(`${baseUrl}/unregistered-example-board/`); - Network accessline 877
try { const port = new URL(server.apiUrl).port; const registration = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 878
const port = new URL(server.apiUrl).port; const registration = await fetch(`http://127.0.0.1:${port}/api/boards`, { method: "POST", - Network accessline 879
const registration = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 889
const boards = (await (await fetch(`http://127.0.0.1:${port}/api/boards`)).json()).boards; - Network accessline 956
const allowed = await fetch(`http://127.0.0.1:${port}/api/boards`); - Network accessline 974
try { const port = new URL(server.apiUrl).port; const crossSite = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 975
const port = new URL(server.apiUrl).port; const crossSite = await fetch(`http://127.0.0.1:${port}/api/boards`, { method: "POST", - Network accessline 976
const crossSite = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 977
method: "POST", headers: { "Content-Type": "application/json", Origin: "http://evil.example" }, body: JSON.stringify({ goalDir }), - Network accessline 978
headers: { "Content-Type": "application/json", Origin: "http://evil.example" }, - Network accessline 983
const sameOrigin = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 984
method: "POST", headers: { "Content-Type": "application/json", Origin: `http://127.0.0.1:${port}` }, body: JSON.stringify({ goalDir }), - Network accessline 985
headers: { "Content-Type": "application/json", Origin: `http://127.0.0.1:${port}` },
plugins/goalbuddy/.claude-plugin/plugin.json
- Network accessline 6
"name": "tolimarchuk", "email": "support@tolibear.com", "url": "https://github.com/tolimarchuk" - Network accessline 7
"email": "support@tolibear.com", "url": "https://github.com/tolimarchuk" }, - Network accessline 8
"url": "https://github.com/tolimarchuk" - Network accessline 9
}, "homepage": "https://goalbuddy.dev", "repository": "https://github.com/tolimarchuk/goalbuddy", - Network accessline 10
"homepage": "https://goalbuddy.dev", - Network accessline 11
"repository": "https://github.com/tolimarchuk/goalbuddy",
plugins/goalbuddy/skills/goal-prep/SKILL.md
- Network accessline 98
If the user chooses the local live board, create the goal directory, `notes/`, and an initial minimal `state.yaml` as soon as the slug is known, then run `node <skill-path>/surfaces/local-goal-board/scripts/local-goal-board.mjs --goal docs/ - Network accessline 100
If `http://goalbuddy.localhost:41737/<slug>/` returns 404, do not assume the existing process is stale and do not stop it. First check `http://127.0.0.1:41737/api/boards`. If that endpoint returns board JSON, the port is the shared multi-bo
plugins/goalbuddy/skills/goal-prep/references/goal-execution.md
- Network accessline 224
If a local board server is running, compare `state.yaml` with `http://127.0.0.1:41737/<slug>/api/board` or `http://127.0.0.1:41737/api/boards`. Repair only GoalBuddy control files: `goal.md`, `state.yaml`, `notes/`, depth-1 `subgoals/`, and
plugins/goalbuddy/skills/goal-prep/scripts/apply-receipt.mjs
- Executable scriptline 1
#!/usr/bin/env node
plugins/goalbuddy/skills/goal-prep/scripts/check-can-stop.mjs
- Executable scriptline 1
#!/usr/bin/env node
plugins/goalbuddy/skills/goal-prep/scripts/check-goal-state.mjs
- Executable scriptline 1
#!/usr/bin/env node
plugins/goalbuddy/skills/goal-prep/scripts/check-update.mjs
- Executable scriptline 1
#!/usr/bin/env node
plugins/goalbuddy/skills/goal-prep/scripts/dispatch-task.mjs
- Executable scriptline 1
#!/usr/bin/env node
plugins/goalbuddy/skills/goal-prep/scripts/install-agents.mjs
- Executable scriptline 1
#!/usr/bin/env node
plugins/goalbuddy/skills/goal-prep/scripts/parallel-plan.mjs
- Executable scriptline 1
#!/usr/bin/env node
plugins/goalbuddy/skills/goal-prep/scripts/render-task-prompt.mjs
- Executable scriptline 1
#!/usr/bin/env node
plugins/goalbuddy/skills/goal-prep/surfaces/local-goal-board/README.md
- Network accessline 31
Then it starts or reuses the shared local board hub at `http://goalbuddy.localhost:41737/`. The server still binds to loopback, so no `/etc/hosts` setup is required. The printed board URL includes the goal slug, like `http://goalbuddy.local - Network accessline 73
- `state.yaml` remains the source of truth. - The server binds to `127.0.0.1:41737` by default, advertises `http://goalbuddy.localhost:41737/`, and reuses that URL as a multi-board hub with in-board header navigation. - Network accessline 74
- The server binds to `127.0.0.1:41737` by default, advertises `http://goalbuddy.localhost:41737/`, and reuses that URL as a multi-board hub with in-board header navigation.
plugins/goalbuddy/skills/goal-prep/surfaces/local-goal-board/scripts/lib/goal-board.mjs
- Executable scriptline 1
Executable file - Network accessline 784
</div> <div class="header-tools"> <a class="github-stars" href="https://github.com/tolimarchuk/goalbuddy" target="_blank" rel="noreferrer" aria-label="Open GoalBuddy on GitHub"> - Network accessline 785
<div class="header-tools"> <a class="github-stars" href="https://github.com/tolimarchuk/goalbuddy" target="_blank" rel="noreferrer" aria-label="Open GoalBuddy on GitHub"> <svg viewBox="0 0 24 24" aria-hidden="true"><path d="m1 - Network accessline 786
<a class="github-stars" href="https://github.com/tolimarchuk/goalbuddy" target="_blank" rel="noreferrer" aria-label="Open GoalBuddy on GitHub"> - Network accessline 1961
async function loadBoard() { const response = await fetch("./api/board", { cache: "no-store" }); - Network accessline 1962
const response = await fetch("./api/board", { cache: "no-store" }); - Network accessline 1967
async function loadBoardSwitcher() { const response = await fetch("../api/boards", { cache: "no-store" }); - Network accessline 1968
const response = await fetch("../api/boards", { cache: "no-store" }); - Network accessline 1974
async function loadSettings() { try { const response = await fetch("../api/settings", { cache: "no-store" }); - Network accessline 1975
try { const response = await fetch("../api/settings", { cache: "no-store" }); if (!response.ok) throw new Error("Settings request failed"); - Network accessline 1976
const response = await fetch("../api/settings", { cache: "no-store" }); - Network accessline 1990
applySettings(currentSettings); try { const response = await fetch("../api/settings", { - Network accessline 1991
try { const response = await fetch("../api/settings", { method: "PUT", - Network accessline 1992
const response = await fetch("../api/settings", { - Network accessline 2044
currentSettings = nextSettings; window.localStorage?.setItem(settingsStorageKey, JSON.stringify(nextSettings)); fetch("../api/settings", { - Network accessline 2045
window.localStorage?.setItem(settingsStorageKey, JSON.stringify(nextSettings)); fetch("../api/settings", { method: "PUT", - Network accessline 2046
fetch("../api/settings", { - Network accessline 2070
if (!githubStarsEl) return; try { const response = await fetch("https://api.github.com/repos/tolimarchuk/goalbuddy", { - Network accessline 2071
try { const response = await fetch("https://api.github.com/repos/tolimarchuk/goalbuddy", { headers: { Accept: "application/vnd.github+json" }, - Network accessline 2072
const response = await fetch("https://api.github.com/repos/tolimarchuk/goalbuddy", {
plugins/goalbuddy/skills/goal-prep/surfaces/local-goal-board/scripts/local-goal-board.mjs
- Executable scriptline 1
#!/usr/bin/env node - Network accessline 204
return; } const url = new URL(request.url || "/", `http://${request.headers.host || "127.0.0.1"}`); - Network accessline 205
} const url = new URL(request.url || "/", `http://${request.headers.host || "127.0.0.1"}`); if (request.method === "POST" && url.pathname === "/api/boards") { - Network accessline 206
const url = new URL(request.url || "/", `http://${request.headers.host || "127.0.0.1"}`); - Network accessline 278
const address = server.address(); const actualPort = typeof address === "object" && address ? address.port : port; baseUrl = `http://${publicHost || host}:${actualPort}`; - Network accessline 279
const actualPort = typeof address === "object" && address ? address.port : port; baseUrl = `http://${publicHost || host}:${actualPort}`; const initialSummary = addBoard(goalDir, appDir); - Network accessline 280
baseUrl = `http://${publicHost || host}:${actualPort}`; - Network accessline 296
async function registerWithBoardHub({ goalDir, host, port }) { const response = await fetch(`http://${host}:${port}/api/boards`, { - Network accessline 297
const response = await fetch(`http://${host}:${port}/api/boards`, { - Network accessline 540
if (!rawHost) return false; try { return allowedHostnames.has(new URL(`http://${rawHost}`).hostname.toLowerCase()); - Network accessline 541
try { return allowedHostnames.has(new URL(`http://${rawHost}`).hostname.toLowerCase()); } catch { - Network accessline 542
return allowedHostnames.has(new URL(`http://${rawHost}`).hostname.toLowerCase());
plugins/goalbuddy/skills/goal-prep/surfaces/local-goal-board/test/local-goal-board.test.mjs
- Executable scriptline 1
Executable file - Network accessline 368
const server = await startBoardServer({ goalDir, host: "127.0.0.1", port: 0 }); try { const initialResponse = await fetch(`${server.hubUrl}api/settings`); - Network accessline 369
try { const initialResponse = await fetch(`${server.hubUrl}api/settings`); assert.equal(initialResponse.status, 200); - Network accessline 370
const initialResponse = await fetch(`${server.hubUrl}api/settings`); - Network accessline 381
const updateResponse = await fetch(`${server.hubUrl}api/settings`, { - Network accessline 407
const partialResponse = await fetch(`${server.hubUrl}api/settings`, { - Network accessline 422
const invalidResponse = await fetch(`${server.hubUrl}api/settings`, { - Network accessline 484
const loopbackResponse = await fetch(`http://127.0.0.1:${url.port}/api/boards`); - Network accessline 525
try { assert.match(server.url, /\/live-board\/$/); const boardResponse = await fetch(`${server.url}api/board`); - Network accessline 526
assert.match(server.url, /\/live-board\/$/); const boardResponse = await fetch(`${server.url}api/board`); assert.equal(boardResponse.status, 200); - Network accessline 527
const boardResponse = await fetch(`${server.url}api/board`); - Network accessline 532
const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 533
const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 564
try { const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 565
const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); assert.equal(events.status, 200); - Network accessline 566
const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 607
try { const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 608
const controller = new AbortController(); const events = await fetch(`${server.url}events`, { signal: controller.signal }); assert.equal(events.status, 200); - Network accessline 609
const events = await fetch(`${server.url}events`, { signal: controller.signal }); - Network accessline 640
const server = await startBoardServer({ goalDir: firstGoalDir, host: "127.0.0.1", port: 0 }); try { const registerResponse = await fetch(server.apiUrl, { - Network accessline 641
try { const registerResponse = await fetch(server.apiUrl, { method: "POST", - Network accessline 642
const registerResponse = await fetch(server.apiUrl, { - Network accessline 656
const hubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 660
const noSlashResponse = await fetch(`${secondUrl.origin}/second-goal`, { redirect: "manual" }); - Network accessline 664
const boardsResponse = await fetch(server.apiUrl); - Network accessline 669
const newestSettingsResponse = await fetch(`${firstUrl.origin}/api/settings`, { - Network accessline 673
}); assert.equal(newestSettingsResponse.status, 200); const newestHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 674
assert.equal(newestSettingsResponse.status, 200); const newestHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); assert.equal(newestHubResponse.status, 302); - Network accessline 675
const newestHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 679
const lastSettingsResponse = await fetch(`${firstUrl.origin}/api/settings`, { - Network accessline 683
}); assert.equal(lastSettingsResponse.status, 200); const lastHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 684
assert.equal(lastSettingsResponse.status, 200); const lastHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); assert.equal(lastHubResponse.status, 302); - Network accessline 685
const lastHubResponse = await fetch(server.hubUrl, { redirect: "manual" }); - Network accessline 689
const secondBoardResponse = await fetch(`${second.url}api/board`); - Network accessline 714
try { const baseUrl = new URL(server.url).origin; const missingResponse = await fetch(`${baseUrl}/unregistered-example-board/`); - Network accessline 715
const baseUrl = new URL(server.url).origin; const missingResponse = await fetch(`${baseUrl}/unregistered-example-board/`); assert.equal(missingResponse.status, 404); - Network accessline 716
const missingResponse = await fetch(`${baseUrl}/unregistered-example-board/`); - Network accessline 877
try { const port = new URL(server.apiUrl).port; const registration = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 878
const port = new URL(server.apiUrl).port; const registration = await fetch(`http://127.0.0.1:${port}/api/boards`, { method: "POST", - Network accessline 879
const registration = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 889
const boards = (await (await fetch(`http://127.0.0.1:${port}/api/boards`)).json()).boards; - Network accessline 956
const allowed = await fetch(`http://127.0.0.1:${port}/api/boards`); - Network accessline 974
try { const port = new URL(server.apiUrl).port; const crossSite = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 975
const port = new URL(server.apiUrl).port; const crossSite = await fetch(`http://127.0.0.1:${port}/api/boards`, { method: "POST", - Network accessline 976
const crossSite = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 977
method: "POST", headers: { "Content-Type": "application/json", Origin: "http://evil.example" }, body: JSON.stringify({ goalDir }), - Network accessline 978
headers: { "Content-Type": "application/json", Origin: "http://evil.example" }, - Network accessline 983
const sameOrigin = await fetch(`http://127.0.0.1:${port}/api/boards`, { - Network accessline 984
method: "POST", headers: { "Content-Type": "application/json", Origin: `http://127.0.0.1:${port}` }, body: JSON.stringify({ goalDir }), - Network accessline 985
headers: { "Content-Type": "application/json", Origin: `http://127.0.0.1:${port}` },
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Signal confidence: 2 facts
- Network access in prose of the SKILL.mdgoalbuddy/SKILL.md:98Low confidence
- Network access in prose of the SKILL.mdgoal-prep/SKILL.md:98Low confidence
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Native | Manifest .claude-plugin/marketplace.json | .claude/skills/<skill-name>/ |
| Codex | Native | Manifest AGENTS.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md goalbuddy/SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md goalbuddy/SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md goalbuddy/SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md goalbuddy/SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.