goalbuddy 0.3.6 → 0.3.8
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/CHANGELOG.md +61 -0
- package/CONTRIBUTING.md +2 -2
- package/README.md +27 -10
- package/{RELEASE-0.3.5.md → docs/releases/0.3.5.md} +4 -4
- package/docs/releases/0.3.7.md +129 -0
- package/docs/releases/0.3.8.md +40 -0
- package/docs/releases/README.md +83 -0
- package/goalbuddy/SKILL.md +21 -10
- package/goalbuddy/scripts/check-goal-state.mjs +53 -0
- package/goalbuddy/scripts/render-task-prompt.mjs +39 -4
- package/{plugins/goalbuddy/skills/goalbuddy/extend → goalbuddy/surfaces}/local-goal-board/README.md +7 -9
- package/goalbuddy/{extend → surfaces}/local-goal-board/examples/sample-goal/state.yaml +5 -5
- package/{plugins/goalbuddy/skills/goalbuddy/extend → goalbuddy/surfaces}/local-goal-board/examples/subgoal-parent/state.yaml +3 -3
- package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/state.yaml +3 -3
- package/{plugins/goalbuddy/skills/goalbuddy/extend → goalbuddy/surfaces}/local-goal-board/scripts/lib/goal-board.mjs +17 -13
- package/goalbuddy/{extend → surfaces}/local-goal-board/scripts/local-goal-board.mjs +27 -6
- package/{plugins/goalbuddy/skills/goalbuddy/extend → goalbuddy/surfaces}/local-goal-board/test/local-goal-board.test.mjs +63 -12
- package/goalbuddy/templates/goal.md +9 -0
- package/goalbuddy/templates/state.yaml +7 -6
- package/internal/assets/goalbuddy-v0.3.7-release.png +0 -0
- package/internal/cli/goal-maker.mjs +177 -717
- package/package.json +7 -8
- package/plugins/goalbuddy/.claude-plugin/plugin.json +3 -4
- package/plugins/goalbuddy/.codex-plugin/plugin.json +5 -6
- package/plugins/goalbuddy/README.md +4 -3
- package/plugins/goalbuddy/skills/goalbuddy/SKILL.md +21 -10
- package/plugins/goalbuddy/skills/goalbuddy/scripts/check-goal-state.mjs +53 -0
- package/plugins/goalbuddy/skills/goalbuddy/scripts/render-task-prompt.mjs +39 -4
- package/{goalbuddy/extend → plugins/goalbuddy/skills/goalbuddy/surfaces}/local-goal-board/README.md +7 -9
- package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/sample-goal/state.yaml +5 -5
- package/{goalbuddy/extend → plugins/goalbuddy/skills/goalbuddy/surfaces}/local-goal-board/examples/subgoal-parent/state.yaml +3 -3
- package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/state.yaml +3 -3
- package/{goalbuddy/extend → plugins/goalbuddy/skills/goalbuddy/surfaces}/local-goal-board/scripts/lib/goal-board.mjs +2 -2
- package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/scripts/local-goal-board.mjs +27 -6
- package/{goalbuddy/extend → plugins/goalbuddy/skills/goalbuddy/surfaces}/local-goal-board/test/local-goal-board.test.mjs +35 -8
- package/plugins/goalbuddy/skills/goalbuddy/templates/goal.md +9 -0
- package/plugins/goalbuddy/skills/goalbuddy/templates/state.yaml +7 -6
- package/examples/extend-catalog-workflow/goal.md +0 -53
- package/examples/extend-catalog-workflow/notes/T001-extension-model-map.md +0 -47
- package/examples/extend-catalog-workflow/notes/T002-architecture-decision.md +0 -48
- package/examples/extend-catalog-workflow/notes/T003-implementation-summary.md +0 -43
- package/examples/extend-catalog-workflow/notes/T004-root-extend-folder.md +0 -24
- package/examples/extend-catalog-workflow/notes/T005-layout-cleanup.md +0 -46
- package/examples/extend-catalog-workflow/notes/T006-catalog-location.md +0 -50
- package/examples/extend-catalog-workflow/notes/T999-completion-audit.md +0 -36
- package/examples/extend-catalog-workflow/state.yaml +0 -327
- package/examples/github-pr-workflow-extension/pr-handoff.md +0 -46
- package/examples/improve-goal-maker/goal.md +0 -51
- package/examples/improve-goal-maker/notes/T001-repo-map.md +0 -59
- package/examples/improve-goal-maker/notes/T002-risk-map.md +0 -37
- package/examples/improve-goal-maker/state.yaml +0 -224
- package/goalbuddy/extend/github-projects/README.md +0 -105
- package/goalbuddy/extend/github-projects/examples/goal-board-sync/state.yaml +0 -63
- package/goalbuddy/extend/github-projects/extension.yaml +0 -43
- package/goalbuddy/extend/github-projects/scripts/lib/github-projects.mjs +0 -728
- package/goalbuddy/extend/github-projects/scripts/lib/goal-state.mjs +0 -362
- package/goalbuddy/extend/github-projects/scripts/sync-github-project.mjs +0 -193
- package/goalbuddy/extend/github-projects/test/github-projects.test.mjs +0 -267
- package/goalbuddy/extend/local-goal-board/extension.yaml +0 -39
- package/internal/assets/extend-release.png +0 -0
- package/internal/assets/extend-release.svg +0 -83
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/README.md +0 -105
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/examples/goal-board-sync/state.yaml +0 -63
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/extension.yaml +0 -43
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/scripts/lib/github-projects.mjs +0 -728
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/scripts/lib/goal-state.mjs +0 -362
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/scripts/sync-github-project.mjs +0 -193
- package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/test/github-projects.test.mjs +0 -267
- package/plugins/goalbuddy/skills/goalbuddy/extend/local-goal-board/extension.yaml +0 -39
- /package/goalbuddy/{extend → surfaces}/local-goal-board/assets/goalbuddy-mark.png +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/sample-goal/notes/T001-scout.md +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/goal.md +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/notes/.gitkeep +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/goal.md +0 -0
- /package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/notes/.gitkeep +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/assets/goalbuddy-mark.png +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/sample-goal/notes/T001-scout.md +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/goal.md +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/notes/.gitkeep +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/goal.md +0 -0
- /package/plugins/goalbuddy/skills/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/subgoals/T004-board-view/notes/.gitkeep +0 -0
package/plugins/goalbuddy/skills/goalbuddy/extend/github-projects/test/github-projects.test.mjs
DELETED
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
import { readFile } from "node:fs/promises";
|
|
4
|
-
import { resolve } from "node:path";
|
|
5
|
-
import { GoalStateError, normalizeGoalBoard, parseGoalStateText } from "../scripts/lib/goal-state.mjs";
|
|
6
|
-
import {
|
|
7
|
-
GITHUB_PROJECT_FIELDS,
|
|
8
|
-
GITHUB_PROJECT_VIEWS,
|
|
9
|
-
agentLaneForTask,
|
|
10
|
-
buildDraftIssueBody,
|
|
11
|
-
buildFieldUpdates,
|
|
12
|
-
ensureGoalProjectViews,
|
|
13
|
-
planGitHubProjectSync,
|
|
14
|
-
priorityForTask,
|
|
15
|
-
projectStatusForTask,
|
|
16
|
-
workTypeForTask,
|
|
17
|
-
} from "../scripts/lib/github-projects.mjs";
|
|
18
|
-
|
|
19
|
-
describe("goal state parsing", () => {
|
|
20
|
-
it("normalizes a GoalBuddy v2 board", async () => {
|
|
21
|
-
const text = await readFile(resolve("extend/github-projects/examples/goal-board-sync/state.yaml"), "utf8");
|
|
22
|
-
const board = normalizeGoalBoard(parseGoalStateText(text));
|
|
23
|
-
|
|
24
|
-
assert.equal(board.title, "Goal board sync MVP");
|
|
25
|
-
assert.equal(board.activeTask, "T002");
|
|
26
|
-
assert.equal(board.tasks.length, 3);
|
|
27
|
-
assert.equal(board.tasks[0].title, "Map external board API requirements");
|
|
28
|
-
assert.equal(board.tasks[1].priority, "P1");
|
|
29
|
-
assert.equal(board.tasks[0].receiptSummary, "The board sync can read GoalBuddy state.yaml and mirror tasks into an external board.");
|
|
30
|
-
assert.equal(board.tasks[0].goalRole, "Scout");
|
|
31
|
-
assert.equal(board.tasks[1].agentResponsible, "Worker");
|
|
32
|
-
assert.equal(board.tasks[1].credentialGate, "Credentials");
|
|
33
|
-
assert.equal(board.tasks[1].parentId, "T001");
|
|
34
|
-
assert.deepEqual(board.tasks[1].dependsOn, ["T001"]);
|
|
35
|
-
assert.deepEqual(board.tasks[1].verify, [
|
|
36
|
-
"node --test extend/github-projects/test/*.test.mjs",
|
|
37
|
-
"node extend/github-projects/scripts/sync-github-project.mjs --state extend/github-projects/examples/goal-board-sync/state.yaml --dry-run",
|
|
38
|
-
]);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("rejects malformed task status", () => {
|
|
42
|
-
const parsed = parseGoalStateText(`
|
|
43
|
-
version: 2
|
|
44
|
-
goal:
|
|
45
|
-
title: "Bad board"
|
|
46
|
-
slug: "bad-board"
|
|
47
|
-
tasks:
|
|
48
|
-
- id: T001
|
|
49
|
-
status: moving
|
|
50
|
-
objective: "Bad status"
|
|
51
|
-
`);
|
|
52
|
-
|
|
53
|
-
assert.throws(() => normalizeGoalBoard(parsed), GoalStateError);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe("GitHub Projects mapping", () => {
|
|
58
|
-
it("plans GitHub draft issue creates and updates by task id", () => {
|
|
59
|
-
const tasks = [
|
|
60
|
-
{
|
|
61
|
-
id: "T001",
|
|
62
|
-
title: "T001: Existing",
|
|
63
|
-
objective: "Existing",
|
|
64
|
-
status: "done",
|
|
65
|
-
type: "scout",
|
|
66
|
-
assignee: "Scout",
|
|
67
|
-
receiptSummary: "Done",
|
|
68
|
-
verify: [],
|
|
69
|
-
allowedFiles: [],
|
|
70
|
-
updatedLabel: "receipt:done",
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
id: "T002",
|
|
74
|
-
title: "T002: New",
|
|
75
|
-
objective: "New",
|
|
76
|
-
status: "queued",
|
|
77
|
-
type: "worker",
|
|
78
|
-
assignee: "Worker",
|
|
79
|
-
receiptSummary: "",
|
|
80
|
-
verify: [],
|
|
81
|
-
allowedFiles: [],
|
|
82
|
-
updatedLabel: "receipt:none",
|
|
83
|
-
},
|
|
84
|
-
];
|
|
85
|
-
|
|
86
|
-
const operations = planGitHubProjectSync(tasks, [
|
|
87
|
-
{
|
|
88
|
-
id: "PVTI_existing",
|
|
89
|
-
taskId: { text: "T001" },
|
|
90
|
-
content: { __typename: "DraftIssue", id: "DI_existing" },
|
|
91
|
-
},
|
|
92
|
-
]);
|
|
93
|
-
|
|
94
|
-
assert.equal(operations[0].type, "update");
|
|
95
|
-
assert.equal(operations[0].itemId, "PVTI_existing");
|
|
96
|
-
assert.equal(operations[0].draftIssueId, "DI_existing");
|
|
97
|
-
assert.equal(operations[1].type, "create");
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("builds GitHub field updates for text and single-select fields", () => {
|
|
101
|
-
const fields = {
|
|
102
|
-
taskId: { id: "F_task" },
|
|
103
|
-
status: { id: "F_status", name: GITHUB_PROJECT_FIELDS.status, options: [{ id: "O_progress", name: "In Progress" }] },
|
|
104
|
-
priority: { id: "F_priority", name: GITHUB_PROJECT_FIELDS.priority, options: [{ id: "O_p1", name: "P1" }] },
|
|
105
|
-
workType: { id: "F_type", name: GITHUB_PROJECT_FIELDS.workType, options: [{ id: "O_execution", name: "Execution" }] },
|
|
106
|
-
agentLane: { id: "F_lane", name: GITHUB_PROJECT_FIELDS.agentLane, options: [{ id: "O_worker", name: "Worker" }] },
|
|
107
|
-
owner: { id: "F_owner" },
|
|
108
|
-
goalRole: { id: "F_goal_role" },
|
|
109
|
-
agentResponsible: { id: "F_agent" },
|
|
110
|
-
credentialGate: { id: "F_gate" },
|
|
111
|
-
parentId: { id: "F_parent" },
|
|
112
|
-
dependsOn: { id: "F_depends" },
|
|
113
|
-
receiptSummary: { id: "F_receipt" },
|
|
114
|
-
verify: { id: "F_verify" },
|
|
115
|
-
allowedFiles: { id: "F_allowed" },
|
|
116
|
-
updated: { id: "F_updated" },
|
|
117
|
-
};
|
|
118
|
-
const task = {
|
|
119
|
-
id: "T002",
|
|
120
|
-
status: "active",
|
|
121
|
-
type: "worker",
|
|
122
|
-
assignee: "Worker",
|
|
123
|
-
goalRole: "Worker",
|
|
124
|
-
agentResponsible: "Worker",
|
|
125
|
-
credentialGate: "None",
|
|
126
|
-
receiptSummary: "",
|
|
127
|
-
verify: ["npm test"],
|
|
128
|
-
allowedFiles: ["scripts/**"],
|
|
129
|
-
parentId: "T001",
|
|
130
|
-
dependsOn: ["T001"],
|
|
131
|
-
updatedLabel: "receipt:none",
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const updates = buildFieldUpdates(task, fields);
|
|
135
|
-
assert.equal(updates.length, 15);
|
|
136
|
-
assert.deepEqual(updates.find((update) => update.fieldId === "F_status").value, {
|
|
137
|
-
singleSelectOptionId: "O_progress",
|
|
138
|
-
});
|
|
139
|
-
assert.deepEqual(updates.find((update) => update.fieldId === "F_task").value, {
|
|
140
|
-
text: "T002",
|
|
141
|
-
});
|
|
142
|
-
assert.deepEqual(updates.find((update) => update.fieldId === "F_lane").value, {
|
|
143
|
-
singleSelectOptionId: "O_worker",
|
|
144
|
-
});
|
|
145
|
-
assert.deepEqual(updates.find((update) => update.fieldId === "F_goal_role").value, { text: "Worker" });
|
|
146
|
-
assert.deepEqual(updates.find((update) => update.fieldId === "F_agent").value, { text: "Worker" });
|
|
147
|
-
assert.deepEqual(updates.find((update) => update.fieldId === "F_gate").value, { text: "None" });
|
|
148
|
-
assert.deepEqual(updates.find((update) => update.fieldId === "F_parent").value, { text: "T001" });
|
|
149
|
-
assert.deepEqual(updates.find((update) => update.fieldId === "F_depends").value, { text: "T001" });
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("builds a draft issue body that points back to the state file", () => {
|
|
153
|
-
const body = buildDraftIssueBody(
|
|
154
|
-
{
|
|
155
|
-
id: "T002",
|
|
156
|
-
objective: "Run sync.",
|
|
157
|
-
status: "active",
|
|
158
|
-
type: "worker",
|
|
159
|
-
assignee: "Worker",
|
|
160
|
-
receiptSummary: "",
|
|
161
|
-
verify: ["npm test"],
|
|
162
|
-
allowedFiles: ["scripts/**"],
|
|
163
|
-
parentId: "T001",
|
|
164
|
-
dependsOn: ["T001"],
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
sourcePath: "extend/github-projects/examples/goal-board-sync/state.yaml",
|
|
168
|
-
}
|
|
169
|
-
);
|
|
170
|
-
|
|
171
|
-
assert.match(body, /YAML remains the source of truth/);
|
|
172
|
-
assert.match(body, /Task ID: T002/);
|
|
173
|
-
assert.match(body, /Parent: T001/);
|
|
174
|
-
assert.match(body, /Depends on:/);
|
|
175
|
-
assert.match(body, /extend\/github-projects\/examples\/goal-board-sync\/state\.yaml/);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it("creates only the Goal Board GitHub Project view with visible fields when missing", async () => {
|
|
179
|
-
const restCalls = [];
|
|
180
|
-
const views = await ensureGoalProjectViews({
|
|
181
|
-
client: {
|
|
182
|
-
rest: async (path, options) => {
|
|
183
|
-
restCalls.push({ path, options });
|
|
184
|
-
return {
|
|
185
|
-
html_url: "https://github.com/users/example/projects/1/views/2",
|
|
186
|
-
};
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
project: {
|
|
190
|
-
number: 1,
|
|
191
|
-
owner: { __typename: "User", login: "example" },
|
|
192
|
-
views: { nodes: [] },
|
|
193
|
-
},
|
|
194
|
-
fields: {
|
|
195
|
-
taskId: { databaseId: 1 },
|
|
196
|
-
status: { databaseId: 2 },
|
|
197
|
-
priority: { databaseId: 3 },
|
|
198
|
-
workType: { databaseId: 4 },
|
|
199
|
-
owner: { databaseId: 5 },
|
|
200
|
-
agentLane: { databaseId: 13 },
|
|
201
|
-
goalRole: { databaseId: 10 },
|
|
202
|
-
agentResponsible: { databaseId: 11 },
|
|
203
|
-
credentialGate: { databaseId: 12 },
|
|
204
|
-
receiptSummary: { databaseId: 6 },
|
|
205
|
-
verify: { databaseId: 7 },
|
|
206
|
-
allowedFiles: { databaseId: 8 },
|
|
207
|
-
updated: { databaseId: 9 },
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
assert.equal(views.board.html_url, "https://github.com/users/example/projects/1/views/2");
|
|
212
|
-
assert.equal(views.agentWorkboard, undefined);
|
|
213
|
-
assert.equal(restCalls.length, 1);
|
|
214
|
-
assert.equal(restCalls[0].path, "users/example/projectsV2/1/views");
|
|
215
|
-
assert.equal(restCalls[0].options.body.layout, "board");
|
|
216
|
-
assert.equal(restCalls[0].options.body.name, GITHUB_PROJECT_VIEWS.board.name);
|
|
217
|
-
assert.deepEqual(restCalls[0].options.body.visible_fields, [3, 2, 4, 5, 10, 11, 13, 12]);
|
|
218
|
-
assert.equal(restCalls[0].options.body.group_by, undefined);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it("reuses an existing Goal Board view without creating extra views", async () => {
|
|
222
|
-
const views = await ensureGoalProjectViews({
|
|
223
|
-
client: {
|
|
224
|
-
rest: async () => {
|
|
225
|
-
throw new Error("REST should not be called for existing views.");
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
project: {
|
|
229
|
-
number: 1,
|
|
230
|
-
owner: { __typename: "User", login: "example" },
|
|
231
|
-
views: {
|
|
232
|
-
nodes: [
|
|
233
|
-
{ id: "PVTV_board", name: "Goal Board", layout: "BOARD_LAYOUT" },
|
|
234
|
-
{ id: "PVTV_agent", name: "Agent Workboard", layout: "BOARD_LAYOUT" },
|
|
235
|
-
],
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
fields: {},
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
assert.equal(views.board.id, "PVTV_board");
|
|
242
|
-
assert.equal(views.agentWorkboard, undefined);
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
it("maps GoalBuddy task statuses to native GitHub board statuses", () => {
|
|
246
|
-
assert.equal(projectStatusForTask("queued"), "Todo");
|
|
247
|
-
assert.equal(projectStatusForTask("active"), "In Progress");
|
|
248
|
-
assert.equal(projectStatusForTask("blocked"), "Blocked");
|
|
249
|
-
assert.equal(projectStatusForTask("done"), "Done");
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
it("maps GoalBuddy task types and priorities to lean PM fields", () => {
|
|
253
|
-
assert.equal(workTypeForTask("scout"), "Discovery");
|
|
254
|
-
assert.equal(workTypeForTask("judge"), "Decision");
|
|
255
|
-
assert.equal(workTypeForTask("worker"), "Execution");
|
|
256
|
-
assert.equal(priorityForTask({ status: "blocked", type: "worker" }), "P0");
|
|
257
|
-
assert.equal(priorityForTask({ status: "active", type: "worker" }), "P1");
|
|
258
|
-
assert.equal(priorityForTask({ status: "queued", type: "scout" }), "P2");
|
|
259
|
-
assert.equal(priorityForTask({ status: "done", type: "worker" }), "P3");
|
|
260
|
-
assert.equal(priorityForTask({ status: "queued", type: "scout", priority: "P0" }), "P0");
|
|
261
|
-
assert.equal(agentLaneForTask({ assignee: "PM" }), "PM");
|
|
262
|
-
assert.equal(agentLaneForTask({ agentResponsible: "Scout" }), "Scout");
|
|
263
|
-
assert.equal(agentLaneForTask({ goalRole: "Judge" }), "Judge");
|
|
264
|
-
assert.equal(agentLaneForTask({ agentResponsible: "Worker" }), "Worker");
|
|
265
|
-
assert.equal(agentLaneForTask({ agentResponsible: "User" }), "User");
|
|
266
|
-
});
|
|
267
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
id: local-goal-board
|
|
2
|
-
name: Local Goal Board
|
|
3
|
-
kind: visualization
|
|
4
|
-
version: 0.2.0
|
|
5
|
-
source_of_truth: local
|
|
6
|
-
description: Generate and serve a GoalBuddy-branded local Kanban board that updates live from a goal directory's state.yaml, notes, and linked depth-1 sub-goals.
|
|
7
|
-
local_use_prompt: Run the bundled local board script for docs/goals/<slug>. It writes a tiny web app into docs/goals/<slug>/.goalbuddy-board and serves it through the shared goalbuddy.localhost:41737 local board hub with live SSE updates from state.yaml, notes, and linked depth-1 sub-goals. Multiple active boards are available from the board header switcher. Use --once --json for generation checks and no long-running server.
|
|
8
|
-
use_when:
|
|
9
|
-
- A human wants to watch a GoalBuddy run in a local board UI.
|
|
10
|
-
- The goal needs GitHub-Projects-like visibility without GitHub credentials.
|
|
11
|
-
- state.yaml and notes should remain the source of truth while the browser updates live.
|
|
12
|
-
- A parent task links a depth-1 child board under subgoals/.
|
|
13
|
-
activation: user_requested
|
|
14
|
-
outputs:
|
|
15
|
-
- Local GoalBuddy board web app
|
|
16
|
-
- Live state.yaml and notes viewer
|
|
17
|
-
requires_approval: false
|
|
18
|
-
safe_by_default: true
|
|
19
|
-
reads:
|
|
20
|
-
- docs/goals/<slug>/state.yaml
|
|
21
|
-
- docs/goals/<slug>/notes
|
|
22
|
-
- docs/goals/<slug>/subgoals
|
|
23
|
-
writes:
|
|
24
|
-
- docs/goals/<slug>/.goalbuddy-board
|
|
25
|
-
side_effects:
|
|
26
|
-
- Starts or reuses the shared local-only HTTP board hub when not run with --once.
|
|
27
|
-
agent_instructions:
|
|
28
|
-
- Use the bundled local-goal-board script; do not build a static-only mockup.
|
|
29
|
-
- Keep state.yaml authoritative; the app is only a viewer.
|
|
30
|
-
- Require live no-manual-reload updates through the local server event stream.
|
|
31
|
-
- Keep the generated UI simple, clean, minimal, and GoalBuddy branded.
|
|
32
|
-
auth:
|
|
33
|
-
env: []
|
|
34
|
-
supports:
|
|
35
|
-
dry_run: true
|
|
36
|
-
live_local_board: true
|
|
37
|
-
live_updates: true
|
|
38
|
-
credentials_required: false
|
|
39
|
-
generated_goal_artifact: true
|
|
File without changes
|
/package/goalbuddy/{extend → surfaces}/local-goal-board/examples/sample-goal/notes/T001-scout.md
RENAMED
|
File without changes
|
|
File without changes
|
/package/goalbuddy/{extend → surfaces}/local-goal-board/examples/subgoal-parent/notes/.gitkeep
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|