@plot-ai/linux-x64-musl 0.0.3 → 0.0.4

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/bin/CHANGELOG.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # changelog
2
2
 
3
- ## 0.0.3
3
+ ## 0.0.4
4
4
 
5
5
  - packaged plot-ai release
package/bin/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plot-ai/linux-x64-musl",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "piConfig": {
5
5
  "name": "plot",
6
6
  "configDir": ".plot"
package/bin/plot-ai CHANGED
Binary file
@@ -0,0 +1,241 @@
1
+ ---
2
+ name: plot-beads-tracker
3
+ description: "beads issue state management for plot orchestration. hybrid model: native beads status for primary lifecycle, labels for orchestrator sub-states (rework, merging). workpad comment lifecycle and bd queries. use when moving issues between states, creating/updating workpad comments, or querying issue status."
4
+ ---
5
+
6
+ # plot-beads-tracker
7
+
8
+ manages issue state and progress tracking for the plot orchestrator via beads status, labels, and comments.
9
+
10
+ use `bd` for all tracker operations. the git/PR lifecycle uses `gh` separately.
11
+
12
+ ## state model
13
+
14
+ beads uses a hybrid state model with two layers:
15
+
16
+ - **status** (native beads lifecycle): `open`, `in_progress`, `blocked`, `deferred`, `closed`
17
+ - **labels** (orchestrator sub-states): `plot:rework`, `plot:merging`
18
+
19
+ the orchestrator checks labels first. if a configured label exists on the issue, it becomes the routing state. otherwise the native beads status is the state.
20
+
21
+ ```
22
+ ┌─────────┐
23
+ │ open │ agent picks up, starts work
24
+ └────┬────┘
25
+ │ bd update <id> --status in_progress
26
+
27
+ ┌─────────────┐
28
+ │ in_progress │ agent implements, pushes PR
29
+ └──────┬──────┘
30
+ │ bd update <id> --status blocked
31
+
32
+ ┌─────────┐
33
+ │ blocked │ human reviews PR
34
+ └────┬────┘
35
+
36
+ ┌──────────┼──────────┐
37
+ ▼ ▼ ▼
38
+ ┌────────────┐ ┌─────────────────┐ ┌────────┐
39
+ │plot:rework │ │ plot:merging │ │closed │
40
+ │(label) │ │ (label) │ │(reject)│
41
+ └─────┬──────┘ └───────┬─────────┘ └────────┘
42
+ │ │
43
+ │ agent fixes, │ agent merges PR,
44
+ │ removes label, │ removes label,
45
+ │ → blocked │ closes issue
46
+ │ │
47
+ ▼ ▼
48
+ ┌─────────┐ ┌────────┐
49
+ │ blocked │ │ closed │
50
+ └─────────┘ └────────┘
51
+ ```
52
+
53
+ ## state transitions
54
+
55
+ ```bash
56
+ # open → in_progress (starting work)
57
+ bd update <id> --status in_progress
58
+
59
+ # in_progress → blocked (PR ready for review)
60
+ bd update <id> --status blocked
61
+
62
+ # human approves → add merging label (human does this)
63
+ bd label add <id> plot:merging
64
+
65
+ # human requests changes → add rework label (human does this)
66
+ bd label add <id> plot:rework
67
+
68
+ # plot:rework → blocked (rework complete, remove label first)
69
+ bd label remove <id> plot:rework
70
+ bd update <id> --status blocked
71
+
72
+ # plot:merging → closed (PR merged, remove label first)
73
+ bd label remove <id> plot:merging
74
+ bd close <id> -r "completed"
75
+
76
+ # reopen closed → in_progress
77
+ bd reopen <id> -r "needs rework"
78
+ ```
79
+
80
+ ## available states
81
+
82
+ | source | state | meaning | agent action |
83
+ | ------ | -------------- | --------------------------- | ----------------------------------------------------- |
84
+ | status | `open` | queued for work | move to `in_progress`, start implementation |
85
+ | status | `in_progress` | implementation underway | continue implementation, push PR, move to `blocked` |
86
+ | status | `blocked` | waiting on human review | do nothing, wait |
87
+ | status | `deferred` | intentionally postponed | do nothing, wait |
88
+ | label | `plot:rework` | reviewer requested changes | address feedback, remove label, move to `blocked` |
89
+ | label | `plot:merging` | human approved PR | merge PR, remove label, close issue |
90
+ | status | `closed` | terminal | stop |
91
+
92
+ workflow routing:
93
+
94
+ - dispatch_states: `open`, `in_progress`, `plot:rework`, `plot:merging`
95
+ - parked_states: `blocked`, `deferred`
96
+ - terminal_states: `closed`
97
+
98
+ ## workpad comment
99
+
100
+ a persistent beads comment used as a living scratchpad across agent sessions.
101
+
102
+ ### find current workpad
103
+
104
+ comments are append-only. there is no edit-in-place. the current workpad is the latest comment whose body starts with `## Plot Workpad`.
105
+
106
+ ```bash
107
+ bd comments <id> --json
108
+ ```
109
+
110
+ scan the returned comments and pick the latest one starting with `## Plot Workpad`.
111
+
112
+ if none exists, create one.
113
+
114
+ ### create workpad
115
+
116
+ write the full workpad body to a temp file, then add it as a comment:
117
+
118
+ ````bash
119
+ cat > /tmp/workpad.md <<'WORKPAD'
120
+ ## Plot Workpad
121
+
122
+ ```text
123
+ <workspace-id>@<short-sha>
124
+ ```
125
+
126
+ ### Plan
127
+ - [ ] 1. <task>
128
+
129
+ ### Acceptance Criteria
130
+ - [ ] <criterion>
131
+
132
+ ### Validation
133
+ - [ ] targeted tests: `<command>`
134
+
135
+ ### Latest Attempt Summary
136
+ - changed: <files or none>
137
+ - validated: <commands + outcome>
138
+ - failed: <remaining failure or none>
139
+ - blocked: <blocker or none>
140
+
141
+ ### Notes
142
+ - <durable context>
143
+ WORKPAD
144
+
145
+ bd comments add <id> -f /tmp/workpad.md
146
+ ````
147
+
148
+ ### update workpad
149
+
150
+ do not try to edit an old comment. add a new full workpad comment with the complete updated body.
151
+
152
+ ````bash
153
+ cat > /tmp/workpad.md <<'WORKPAD'
154
+ ...full updated workpad body...
155
+ WORKPAD
156
+
157
+ bd comments add <id> -f /tmp/workpad.md
158
+ ````
159
+
160
+ ### rules
161
+
162
+ - treat the latest `## Plot Workpad` comment as canonical
163
+ - never rely on older workpad comments once a newer one exists
164
+ - update the workpad after every meaningful milestone
165
+ - never leave completed items unchecked
166
+ - include workspace id and short sha at top: `<workspace-id>@<short-sha>`
167
+ - keep the full workpad body in each update so the latest comment is self-contained
168
+
169
+ ## workpad template
170
+
171
+ ````markdown
172
+ ## Plot Workpad
173
+
174
+ ```text
175
+ <workspace-id>@<short-sha>
176
+ ```
177
+
178
+ ### Plan
179
+ - [ ] 1. Parent task
180
+ - [ ] 1.1 Child task
181
+ - [ ] 2. Parent task
182
+
183
+ ### Acceptance Criteria
184
+ - [ ] Criterion 1
185
+ - [ ] Criterion 2
186
+
187
+ ### Validation
188
+ - [ ] targeted tests: `<command>`
189
+
190
+ ### Latest Attempt Summary
191
+ - changed: <files or none>
192
+ - validated: <commands + outcome>
193
+ - failed: <remaining failure or none>
194
+ - blocked: <blocker or none>
195
+
196
+ ### Notes
197
+ - <short durable context>
198
+
199
+ ````
200
+
201
+ ## issue queries
202
+
203
+ ```bash
204
+ # full issue details
205
+ bd show <id> --json
206
+
207
+ # all comments (for workpad lookup)
208
+ bd comments <id> --json
209
+
210
+ # list by status
211
+ bd list --status open --json
212
+ bd list --status in_progress --json
213
+ bd list --status blocked --json
214
+
215
+ # list by label
216
+ bd list --label plot:rework --json
217
+ bd list --label plot:merging --json
218
+
219
+ # ready work: open + no blockers
220
+ bd ready --json
221
+
222
+ # complex filters
223
+ bd query "status=open AND priority<=1" --json
224
+ bd query "label=plot:rework" --json
225
+
226
+ # text search
227
+ bd search "keyword" --json
228
+
229
+ # dependencies
230
+ bd dep list <id>
231
+ ```
232
+
233
+ ## out-of-scope issue creation
234
+
235
+ if you discover unrelated work, file a separate beads issue instead of expanding scope:
236
+
237
+ ```bash
238
+ bd create "discovered: <title>" -t task -p 2 -d "<description>"
239
+ ```
240
+
241
+ keep the new issue narrow and factual. reference the triggering issue in the description when useful.
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: plot-github-tracker
3
+ description: "github issue state management for plot orchestration. state transitions via labels, workpad comment lifecycle, and issue/PR linkage. use when moving issues between states, creating/updating workpad comments, or linking PRs to issues."
4
+ ---
5
+
6
+ # plot-github-tracker
7
+
8
+ manages issue state and progress tracking for the plot orchestrator via GitHub labels and comments.
9
+
10
+ use `gh` CLI for all GitHub operations. `$GITHUB_REPO` must be set to `owner/repo`.
11
+
12
+ ## state transitions
13
+
14
+ issue state is determined by labels. plot only routes issues that have an explicit `plot:*` state label. unlabeled issues are ignored.
15
+
16
+ transition by removing the previous `plot:*` label and adding the new one:
17
+
18
+ ```bash
19
+ # todo -> in-progress
20
+ gh issue edit <number> --repo "$GITHUB_REPO" --remove-label "plot:todo" --add-label "plot:in-progress"
21
+
22
+ # in-progress -> human-review
23
+ gh issue edit <number> --repo "$GITHUB_REPO" --remove-label "plot:in-progress" --add-label "plot:human-review"
24
+
25
+ # rework -> human-review
26
+ gh issue edit <number> --repo "$GITHUB_REPO" --remove-label "plot:rework" --add-label "plot:human-review"
27
+
28
+ # merging -> done, then close
29
+ gh issue edit <number> --repo "$GITHUB_REPO" --remove-label "plot:merging" --add-label "plot:done"
30
+ gh issue close <number> --repo "$GITHUB_REPO"
31
+ ```
32
+
33
+ if you need to move a terminal issue back into active work, reopen first, then swap labels:
34
+
35
+ ```bash
36
+ gh issue reopen <number> --repo "$GITHUB_REPO"
37
+ gh issue edit <number> --repo "$GITHUB_REPO" --remove-label "plot:done" --add-label "plot:rework"
38
+ ```
39
+
40
+ ## available states
41
+
42
+ | label | meaning | agent action |
43
+ | ----------------- | -------------------------- | ------------------------------------------------------ |
44
+ | plot:todo | queued for work | move to plot:in-progress, start execution |
45
+ | plot:in-progress | implementation underway | implement, verify, open PR, move to plot:human-review |
46
+ | plot:human-review | PR open, waiting on human | do nothing, wait |
47
+ | plot:rework | reviewer requested changes | read feedback, fix, move to plot:human-review |
48
+ | plot:merging | human approved | merge PR, move to plot:done |
49
+ | plot:done | terminal | stop |
50
+
51
+ ## workpad comment
52
+
53
+ a single persistent GitHub issue comment used as a living scratchpad across agent sessions.
54
+
55
+ ### find or create
56
+
57
+ ```bash
58
+ # search for existing workpad
59
+ gh api repos/$GITHUB_REPO/issues/<number>/comments --jq '.[] | select(.body | startswith("## Plot Workpad")) | .id' | head -1
60
+ ```
61
+
62
+ if not found, create it:
63
+
64
+ ```bash
65
+ gh api repos/$GITHUB_REPO/issues/<number>/comments -X POST -f body='## Plot Workpad
66
+
67
+ ### Plan
68
+
69
+ - [ ] 1. <task>
70
+
71
+ ### Acceptance Criteria
72
+
73
+ - [ ] <criterion>
74
+
75
+ ### Validation
76
+
77
+ - [ ] <test command>
78
+
79
+ ### Latest Attempt Summary
80
+
81
+ - changed: <files or none>
82
+ - validated: <commands + outcome>
83
+ - failed: <remaining failure or none>
84
+ - blocked: <blocker or none>
85
+
86
+ ### Notes
87
+
88
+ - <durable context>'
89
+ ```
90
+
91
+ ### update existing
92
+
93
+ replace the full workpad body in place:
94
+
95
+ ```bash
96
+ gh api repos/$GITHUB_REPO/issues/comments/<id> -X PATCH -f body='...full updated workpad body...'
97
+ ```
98
+
99
+ ### rules
100
+
101
+ - exactly one workpad comment per issue, identified by `## Plot Workpad` header
102
+ - reuse existing comment on continuation runs — do not create duplicates
103
+ - update the workpad after every meaningful milestone
104
+ - never leave completed items unchecked
105
+ - include workspace id and short sha at top: `<workspace-id>@<short-sha>`
106
+
107
+ ## workpad template
108
+
109
+ ````markdown
110
+ ## Plot Workpad
111
+
112
+ ```text
113
+ <workspace-id>@<short-sha>
114
+ ```
115
+
116
+ ### Plan
117
+
118
+ - [ ] 1. Parent task
119
+ - [ ] 1.1 Child task
120
+ - [ ] 2. Parent task
121
+
122
+ ### Acceptance Criteria
123
+
124
+ - [ ] Criterion 1
125
+ - [ ] Criterion 2
126
+
127
+ ### Validation
128
+
129
+ - [ ] targeted tests: `<command>`
130
+
131
+ ### Latest Attempt Summary
132
+
133
+ - changed: <files or none>
134
+ - validated: <commands + outcome>
135
+ - failed: <remaining failure or none>
136
+ - blocked: <blocker or none>
137
+
138
+ ### Notes
139
+
140
+ - <short durable context>
141
+
142
+ ````
143
+
144
+ ## issue queries
145
+
146
+ ```bash
147
+ # view issue details
148
+ gh issue view <number> --repo "$GITHUB_REPO" --json title,body,state,labels,comments
149
+
150
+ # list open issues by label
151
+ gh issue list --repo "$GITHUB_REPO" --label "plot:in-progress" --state open
152
+ ```
153
+
154
+ ## PR linkage
155
+
156
+ after creating or updating a PR, ensure the PR body includes `Resolves #<number>`. that is the durable issue/PR link.
157
+
158
+ if you need to post the PR URL back to the issue, add a normal issue comment:
159
+
160
+ ```bash
161
+ gh api repos/$GITHUB_REPO/issues/<number>/comments -X POST -f body='linked PR: <pr-url>'
162
+ ```
package/bin/tui-worker.js CHANGED
@@ -290968,7 +290968,64 @@ async function createBeadsOps(config2) {
290968
290968
  createdAt: bd.created_at || null,
290969
290969
  updatedAt: bd.updated_at || null
290970
290970
  });
290971
- const fetchRunContext = async (issueId, _state) => {
290971
+ const runGh = async (args2) => {
290972
+ return await execFileAsync2("gh", args2, {
290973
+ maxBuffer: 50 * 1024 * 1024,
290974
+ cwd: workspaceRoot
290975
+ });
290976
+ };
290977
+ const fetchPrReviews = async (issueId) => {
290978
+ const repoArgs = config2.githubRepo ? ["--repo", config2.githubRepo] : [];
290979
+ try {
290980
+ const prSearchResult = await runGh([
290981
+ "pr",
290982
+ "list",
290983
+ ...repoArgs,
290984
+ "--state",
290985
+ "open",
290986
+ "--json",
290987
+ "number,headRefName,body",
290988
+ "--limit",
290989
+ "50"
290990
+ ]);
290991
+ const prs = JSON.parse(prSearchResult.stdout);
290992
+ const linkedPr = prs.find((pr) => pr.body?.includes(issueId));
290993
+ if (!linkedPr)
290994
+ return null;
290995
+ const reviewResult = await runGh([
290996
+ "pr",
290997
+ "view",
290998
+ String(linkedPr.number),
290999
+ ...repoArgs,
291000
+ "--json",
291001
+ "reviews,comments"
291002
+ ]);
291003
+ const prData = JSON.parse(reviewResult.stdout);
291004
+ const parts2 = [];
291005
+ if (prData.reviews?.length) {
291006
+ for (const r of prData.reviews) {
291007
+ if (r.body)
291008
+ parts2.push(`**${r.author.login}** (${r.state}):
291009
+ ${r.body}`);
291010
+ }
291011
+ }
291012
+ if (prData.comments?.length) {
291013
+ for (const c of prData.comments) {
291014
+ if (c.body)
291015
+ parts2.push(`**${c.author.login}**:
291016
+ ${c.body}`);
291017
+ }
291018
+ }
291019
+ return parts2.length > 0 ? parts2.join(`
291020
+
291021
+ ---
291022
+
291023
+ `) : null;
291024
+ } catch {
291025
+ return null;
291026
+ }
291027
+ };
291028
+ const fetchRunContext = async (issueId, state) => {
290972
291029
  let comments = [];
290973
291030
  try {
290974
291031
  const issue2 = await viewIssue(issueId);
@@ -290980,7 +291037,12 @@ async function createBeadsOps(config2) {
290980
291037
  const workpadComment = comments.find((c) => c.text.startsWith("## Plot Workpad"));
290981
291038
  if (workpadComment)
290982
291039
  workpad = workpadComment.text;
290983
- return buildRunContext({ workpad, reviewFeedback: null });
291040
+ let reviews = null;
291041
+ const normalizedDispatch = config2.dispatchStates.map(normalizeState2);
291042
+ if (normalizedDispatch.includes(normalizeState2(state))) {
291043
+ reviews = await fetchPrReviews(issueId);
291044
+ }
291045
+ return buildRunContext({ workpad, reviewFeedback: reviews });
290984
291046
  };
290985
291047
  return {
290986
291048
  runBd,
@@ -290999,6 +291061,7 @@ var plugin2 = {
290999
291061
  return {
291000
291062
  kind: String(raw2.kind),
291001
291063
  beadsDir: typeof raw2["beadsDir"] === "string" ? raw2["beadsDir"] : undefined,
291064
+ githubRepo: typeof raw2["githubRepo"] === "string" ? raw2["githubRepo"] : undefined,
291002
291065
  dispatchStates: Array.isArray(raw2["dispatchStates"]) ? raw2["dispatchStates"] : undefined,
291003
291066
  parkedStates: Array.isArray(raw2["parkedStates"]) ? raw2["parkedStates"] : undefined,
291004
291067
  terminalStates: Array.isArray(raw2["terminalStates"]) ? raw2["terminalStates"] : undefined
@@ -291012,11 +291075,13 @@ var plugin2 = {
291012
291075
  ].filter((s, i, arr) => arr.indexOf(s) === i);
291013
291076
  const ops = await createBeadsOps({
291014
291077
  beadsDir: config2.beadsDir,
291078
+ githubRepo: config2.githubRepo,
291079
+ dispatchStates: config2.dispatchStates ?? [],
291015
291080
  allStates
291016
291081
  });
291017
291082
  return {
291018
291083
  async fetchCandidateIssues(dispatchStates) {
291019
- const bdIssues = await ops.listOpenIssues();
291084
+ const bdIssues = await ops.listAllIssues();
291020
291085
  const issues = bdIssues.map(ops.mapIssue);
291021
291086
  const normalized = new Set(dispatchStates.map(normalizeState2));
291022
291087
  return issues.filter((i) => normalized.has(normalizeState2(i.state)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plot-ai/linux-x64-musl",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "orchestrate coding agents against an issue tracker",