@xpufx/paseo-forges 0.1.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.
Files changed (128) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/client/active-forge.ts +47 -0
  4. package/client/board-alert.tsx +236 -0
  5. package/client/foreign-link.tsx +33 -0
  6. package/client/hook-queue-panel.tsx +412 -0
  7. package/client/issues-pill.tsx +1976 -0
  8. package/client/label-chip.tsx +116 -0
  9. package/client/linkifier.tsx +280 -0
  10. package/client/pill-label.ts +183 -0
  11. package/client/vendor/paseo-plugin-helper/command-center.ts +43 -0
  12. package/client/vendor/paseo-plugin-helper/components/AboutSection.tsx +493 -0
  13. package/client/vendor/paseo-plugin-helper/components/AttentionBeacon.tsx +250 -0
  14. package/client/vendor/paseo-plugin-helper/components/Badge.tsx +156 -0
  15. package/client/vendor/paseo-plugin-helper/components/Button.tsx +178 -0
  16. package/client/vendor/paseo-plugin-helper/components/Card.tsx +225 -0
  17. package/client/vendor/paseo-plugin-helper/components/CodeBlock.tsx +196 -0
  18. package/client/vendor/paseo-plugin-helper/components/Collapsible.tsx +277 -0
  19. package/client/vendor/paseo-plugin-helper/components/CommandBox.tsx +172 -0
  20. package/client/vendor/paseo-plugin-helper/components/CopyButton.tsx +180 -0
  21. package/client/vendor/paseo-plugin-helper/components/DataTable.tsx +200 -0
  22. package/client/vendor/paseo-plugin-helper/components/EmptyState.tsx +97 -0
  23. package/client/vendor/paseo-plugin-helper/components/HighlightedText.tsx +70 -0
  24. package/client/vendor/paseo-plugin-helper/components/InlineButton.tsx +73 -0
  25. package/client/vendor/paseo-plugin-helper/components/KeyValue.tsx +446 -0
  26. package/client/vendor/paseo-plugin-helper/components/MetricGauge.tsx +247 -0
  27. package/client/vendor/paseo-plugin-helper/components/ProgressBar.tsx +117 -0
  28. package/client/vendor/paseo-plugin-helper/components/Responsive.tsx +53 -0
  29. package/client/vendor/paseo-plugin-helper/components/SearchInput.tsx +118 -0
  30. package/client/vendor/paseo-plugin-helper/components/SectionHeader.tsx +80 -0
  31. package/client/vendor/paseo-plugin-helper/components/Select.tsx +215 -0
  32. package/client/vendor/paseo-plugin-helper/components/StatusDot.tsx +80 -0
  33. package/client/vendor/paseo-plugin-helper/components/Tabs.tsx +319 -0
  34. package/client/vendor/paseo-plugin-helper/components/TextInput.tsx +150 -0
  35. package/client/vendor/paseo-plugin-helper/components/Toggle.tsx +163 -0
  36. package/client/vendor/paseo-plugin-helper/components/TruncatedText.tsx +157 -0
  37. package/client/vendor/paseo-plugin-helper/components/index.ts +25 -0
  38. package/client/vendor/paseo-plugin-helper/custom-pills.tsx +224 -0
  39. package/client/vendor/paseo-plugin-helper/forge-icon.tsx +79 -0
  40. package/client/vendor/paseo-plugin-helper/host.ts +277 -0
  41. package/client/vendor/paseo-plugin-helper/icon.tsx +39 -0
  42. package/client/vendor/paseo-plugin-helper/index.ts +28 -0
  43. package/client/vendor/paseo-plugin-helper/layout/ActionBar.tsx +49 -0
  44. package/client/vendor/paseo-plugin-helper/layout/FormRow.tsx +103 -0
  45. package/client/vendor/paseo-plugin-helper/layout/Grid.tsx +65 -0
  46. package/client/vendor/paseo-plugin-helper/layout/ModalBody.tsx +378 -0
  47. package/client/vendor/paseo-plugin-helper/layout/ModalContent.tsx +49 -0
  48. package/client/vendor/paseo-plugin-helper/layout/Row.tsx +39 -0
  49. package/client/vendor/paseo-plugin-helper/layout/Stack.tsx +39 -0
  50. package/client/vendor/paseo-plugin-helper/layout/index.ts +7 -0
  51. package/client/vendor/paseo-plugin-helper/panel.tsx +81 -0
  52. package/client/vendor/paseo-plugin-helper/pill.tsx +884 -0
  53. package/client/vendor/paseo-plugin-helper/query-refresh.ts +79 -0
  54. package/client/vendor/paseo-plugin-helper/query.ts +66 -0
  55. package/client/vendor/paseo-plugin-helper/settings-screen.tsx +372 -0
  56. package/client/vendor/paseo-plugin-helper/settings.ts +181 -0
  57. package/client/vendor/paseo-plugin-helper/shared-settings.ts +46 -0
  58. package/client/vendor/paseo-plugin-helper/snapshot.ts +68 -0
  59. package/client/vendor/paseo-plugin-helper/surface.tsx +80 -0
  60. package/client/vendor/paseo-plugin-helper/theme/color-utils.ts +118 -0
  61. package/client/vendor/paseo-plugin-helper/theme/flair.ts +76 -0
  62. package/client/vendor/paseo-plugin-helper/theme/host-variables.ts +121 -0
  63. package/client/vendor/paseo-plugin-helper/theme/index.ts +7 -0
  64. package/client/vendor/paseo-plugin-helper/theme/provider.tsx +214 -0
  65. package/client/vendor/paseo-plugin-helper/theme/responsive.ts +213 -0
  66. package/client/vendor/paseo-plugin-helper/theme/tokens.ts +161 -0
  67. package/client/vendor/paseo-plugin-helper/theme/useResponsive.ts +57 -0
  68. package/client/vendor/paseo-plugin-helper/utils/clipboard.ts +149 -0
  69. package/client/vendor/paseo-plugin-helper/utils/haptics.ts +34 -0
  70. package/client/webhook-card.tsx +198 -0
  71. package/docs/specs/forge-workflow-gui.md +820 -0
  72. package/docs/workflow.md +339 -0
  73. package/examples/README.md +108 -0
  74. package/examples/hook-service/README.md +66 -0
  75. package/examples/hook-service/forge-hook.service +28 -0
  76. package/examples/hook-service/hook-server.mjs +265 -0
  77. package/examples/hook-service/hook.env.example +21 -0
  78. package/examples/labels/README.md +64 -0
  79. package/examples/labels/label-base.yaml +117 -0
  80. package/examples/skills/coding-agent/SKILL.md +262 -0
  81. package/examples/skills/coding-agent-fgjx/SKILL.md +271 -0
  82. package/examples/skills/orchestrator/SKILL.md +133 -0
  83. package/examples/skills/orchestrator-fgjx/SKILL.md +139 -0
  84. package/examples/tools/README.md +68 -0
  85. package/examples/tools/fgjx +464 -0
  86. package/package.json +38 -0
  87. package/paseo-plugin.json +4 -0
  88. package/server/forge-client.ts +484 -0
  89. package/server/forge-guard.ts +70 -0
  90. package/server/git-origin.ts +70 -0
  91. package/server/hook-queue.ts +127 -0
  92. package/server/issues.ts +542 -0
  93. package/server/settings.ts +52 -0
  94. package/server/vendor/paseo-plugin-helper/agent.ts +85 -0
  95. package/server/vendor/paseo-plugin-helper/custom-pills.ts +344 -0
  96. package/server/vendor/paseo-plugin-helper/index.ts +18 -0
  97. package/server/vendor/paseo-plugin-helper/jsonc.ts +78 -0
  98. package/server/vendor/paseo-plugin-helper/logger.ts +210 -0
  99. package/server/vendor/paseo-plugin-helper/mcp-config.ts +367 -0
  100. package/server/vendor/paseo-plugin-helper/mcp-injection.ts +85 -0
  101. package/server/vendor/paseo-plugin-helper/network.ts +91 -0
  102. package/server/vendor/paseo-plugin-helper/plugins.ts +160 -0
  103. package/server/vendor/paseo-plugin-helper/process.ts +186 -0
  104. package/server/vendor/paseo-plugin-helper/redact.ts +86 -0
  105. package/server/vendor/paseo-plugin-helper/rpc-guard.ts +77 -0
  106. package/server/vendor/paseo-plugin-helper/settings.ts +97 -0
  107. package/server/vendor/paseo-plugin-helper/shared-settings.ts +243 -0
  108. package/server/vendor/paseo-plugin-helper/storage.ts +244 -0
  109. package/server/vendor/paseo-plugin-helper/system.ts +128 -0
  110. package/server/vendor/paseo-plugin-helper/task.ts +116 -0
  111. package/server/vendor/paseo-plugin-helper/version.ts +153 -0
  112. package/server/vendor/paseo-plugin-helper/workspace-beacon.ts +418 -0
  113. package/shared/hook-queue.ts +140 -0
  114. package/shared/issues.ts +1750 -0
  115. package/shared/vendor/paseo-plugin-helper/README.md +11 -0
  116. package/shared/vendor/paseo-plugin-helper/async.ts +35 -0
  117. package/shared/vendor/paseo-plugin-helper/custom-pills.ts +169 -0
  118. package/shared/vendor/paseo-plugin-helper/forge.ts +110 -0
  119. package/shared/vendor/paseo-plugin-helper/formatters.ts +271 -0
  120. package/shared/vendor/paseo-plugin-helper/highlight.ts +184 -0
  121. package/shared/vendor/paseo-plugin-helper/index.ts +10 -0
  122. package/shared/vendor/paseo-plugin-helper/rpc.ts +72 -0
  123. package/shared/vendor/paseo-plugin-helper/settings.ts +138 -0
  124. package/shared/vendor/paseo-plugin-helper/suite-settings.ts +17 -0
  125. package/shared/vendor/paseo-plugin-helper/suppressed.ts +31 -0
  126. package/shared/vendor/paseo-plugin-helper/types.ts +36 -0
  127. package/shared/version.ts +2 -0
  128. package/shared/webhook.ts +223 -0
@@ -0,0 +1,262 @@
1
+ ---
2
+ name: coding-agent
3
+ description: EXAMPLE skill โ€” workflow, board conventions, and task lifecycle for coding agents using the forges plugin's embedded /api/v1 client (no CLI dependency)
4
+ ---
5
+
6
+ > [!WARNING]
7
+ > **This is an example, not a drop-in.** It describes one team's Forgejo +
8
+ > Paseo workflow, label taxonomy, and board conventions, adapted for
9
+ > publication. This variant is **zero-dependency**: it drives the board through
10
+ > the `forges` plugin's own surfaces and embedded Gitea-family `/api/v1` client
11
+ > and needs no forge CLI on the host. If you already run a CLI wrapper, the
12
+ > richer [`../coding-agent-fgjx/SKILL.md`](../coding-agent-fgjx/SKILL.md)
13
+ > variant may fit better. Adapt hosts, repo, labels, and conventions to your own
14
+ > workflow. See [`../../README.md`](../../README.md) and
15
+ > [`../../docs/workflow.md`](../../docs/workflow.md).
16
+
17
+ # Coding Agent Skill (embedded API)
18
+
19
+ This skill defines the operational workflow, board operations, issue
20
+ conventions, and reporting standards for **coding agents** operating behind a
21
+ shared forge user identity, using only what the `forges` plugin ships.
22
+
23
+ > [!IMPORTANT]
24
+ > **Token Economy Rule**: If you explained or documented something in a Forgejo issue comment, **keep conversation responses in the agent/user harness strictly brief and low-token**. Point directly to the issue number/link; do not duplicate long explanations into chat.
25
+
26
+ ---
27
+
28
+ ## 1. Primary Surfaces: the plugin + embedded `/api/v1`
29
+
30
+ The `forges` plugin embeds a Gitea-family `/api/v1` `fetch` client on the
31
+ daemon side (`plugins/forges/server/forge-client.ts`). The daemon holds a
32
+ per-host token from Settings, so **no forge CLI is required on the machine**.
33
+ Two ways to operate the board:
34
+
35
+ **Interactive โ€” the plugin's surfaces.** Use these when a human or the Paseo
36
+ client is driving:
37
+ - the issues pill + modal for listing, filtering, and issue detail;
38
+ - the Labels tab / label chips for scoped label changes (they add the new label
39
+ and remove any same-scope mate);
40
+ - the quick-comment composer for steering notes.
41
+
42
+ **Programmatic โ€” the plugin's write/read RPCs** (same operations, from a Paseo
43
+ client): `forge.board-overview`, `forge.issue-detail`, `forge.set-label`,
44
+ `forge.add-comment`. The plugin never appends an agent envelope; it stamps the
45
+ comment with the shared account identity only.
46
+
47
+ **Scripted โ€” direct `/api/v1`** when an agent needs a shell call and has no
48
+ CLI. Point at your forge with a personal access token (adopter-supplied; keep it
49
+ out of the repo):
50
+
51
+ ```bash
52
+ FORGE=https://forge.example.com
53
+ REPO=your-org/your-repo
54
+ TOKEN="$FORGE_TOKEN" # read:repository, write:issue
55
+
56
+ # List / filter issues โ€” page explicitly, never assume one call is complete
57
+ curl -s -H "Authorization: token $TOKEN" \
58
+ "$FORGE/api/v1/repos/$REPO/issues?state=open&type=issues&limit=50&page=1"
59
+
60
+ # Issue detail + comments (comments are a collection too: pass limit/page)
61
+ curl -s -H "Authorization: token $TOKEN" "$FORGE/api/v1/repos/$REPO/issues/<NUMBER>"
62
+ curl -s -H "Authorization: token $TOKEN" \
63
+ "$FORGE/api/v1/repos/$REPO/issues/<NUMBER>/comments?limit=50&page=1"
64
+
65
+ # Labels are a collection as well
66
+ curl -s -H "Authorization: token $TOKEN" "$FORGE/api/v1/repos/$REPO/labels?limit=50&page=1"
67
+
68
+ # Post a comment
69
+ curl -s -X POST -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
70
+ -d '{"body":"..."}' "$FORGE/api/v1/repos/$REPO/issues/<NUMBER>/comments"
71
+ ```
72
+
73
+ > [!WARNING]
74
+ > **List and search calls are paged โ€” one call is never the whole set.** Every
75
+ > Gitea-family collection endpoint returns a single page, and the default page
76
+ > size is **server-defined and can change**, so an unpaged call silently
77
+ > truncates. This binds the **issue list, search results, label list, and
78
+ > comment list** โ€” `GET .../issues`, `.../issues?q=`, `.../labels`, and
79
+ > `.../issues/<n>/comments`. Always page: pass `limit` and increment `page`
80
+ > until a short page comes back, or follow the `Link` header / `X-Total-Count`
81
+ > when the server sends them. Never treat page 1 as complete, and never
82
+ > conclude "no results" (or "labels not found") from one unpaged call. Worked
83
+ > example: an unpaged `fgj label list` returned **30 of 59** labels and produced
84
+ > false "labels not found" errors (#197). The same rule binds the plugin's own
85
+ > surfaces: a list UI must page internally rather than render a truncated set
86
+ > (see #189).
87
+
88
+ > [!NOTE]
89
+ > Forgejo (`forge.example.com`) is the **primary git remote (`origin`) and
90
+ > issues tracker**. All agent code pushes go to `origin` on Forgejo. Pushes to
91
+ > public GitHub are strictly manual and gated by human review.
92
+
93
+ > [!IMPORTANT]
94
+ > **Clean Markdown & Backticks**: When posting comments via shell or heredocs, do NOT double-escape backticks with backslashes (e.g. avoid `\`\`\`` or `\`code\``). Backslashes display literally on the Forgejo web UI. Use unescaped single quotes, heredocs (`cat << 'EOF'`), or raw file input (`-F file` or python) to preserve clean triple backticks (` ``` `).
95
+
96
+ ---
97
+
98
+ ## 2. Issue Referencing & Linking Conventions
99
+
100
+ When referencing issues in comments, commit messages, or chat harness:
101
+ 1. **Instance-Qualified Links**: We may have multiple Forgejo/Git instances. Always format issue references with clickable markdown URLs including the instance descriptor, for example:
102
+ `[Issue #47 (forge.example.com)](https://forge.example.com/your-org/your-repo/issues/47)`
103
+ 2. **Never echo redundant issue numbers**: Do not post naked `#47` inside comments on issue #47 itself without additional context. Reference external/cross-issue links with their full URL and repo/forge context.
104
+
105
+ ---
106
+
107
+ ## 3. Commit Tracking: Explicit Code Host & Commit SHAs
108
+
109
+ If an issue fix includes a code commit:
110
+ 1. **Always record the exact commit SHA and branch**:
111
+ `commit: abc1234 on branch main in forge.example.com/your-org/your-repo`
112
+ 2. **Public Mirroring**: Never push directly to GitHub without human instruction; code stays on Forgejo `origin`. For external repositories, state the repository origin remote + branch + SHA explicitly.
113
+ 3. **Anchored resolution explanations**: post the why + commit ref on the resolved issue itself, never as a loose top-level thread elsewhere.
114
+
115
+ ---
116
+
117
+ ## 4. Comment Attribution (optional self-stamp)
118
+
119
+ When several agents share one forge account, a plain comment carries no
120
+ provenance. The plugin does **not** append one โ€” quick comments are operator
121
+ steering, stamped with the shared identity by the API.
122
+
123
+ If you want attribution, append a footer to your own comment body. This is a
124
+ convention, not a plugin feature, and needs no tooling:
125
+
126
+ ```markdown
127
+ <Your actual comment / progress report / deliverable here>
128
+
129
+ ---
130
+ <sub>๐Ÿค– **<AgentName/SessionTitle>** (`<ShortId>`) ยท `<Model>` ยท `<Repo>:<Branch>` ยท _<UTC Timestamp>_</sub>
131
+ ```
132
+
133
+ > [!CAUTION]
134
+ > **Stamps are convention-only, unverified**: a display name resolved
135
+ > best-effort from a daemon/provider lookup, an environment variable, or a
136
+ > session DB can disagree with what the Paseo UI shows, and nothing records who
137
+ > set a title. Never treat a stamp as proof of which agent acted. If a stamp
138
+ > looks wrong, check your agent inventory (`paseo ls` / `paseo inspect <id>` in
139
+ > Paseo) before assuming attribution.
140
+
141
+ The example [`../coding-agent-fgjx/SKILL.md`](../coding-agent-fgjx/SKILL.md)
142
+ shows how a CLI wrapper can generate this footer for you.
143
+
144
+ ---
145
+
146
+ ## 5. Steering Labels & Operational Directives
147
+
148
+ Understand the intent of board labels:
149
+
150
+ - **`attention/1-agent`**: Dispatch signal โ€” this task is available and open
151
+ for an agent to inspect, claim, or act upon.
152
+ - **Precedence Rule (Recent Updates Over Labels)**: If an issue has a recent update (`updated_at` delta), **recent comments and feedback ALWAYS take precedence over static labels**. Never rely on an existing label and move on without inspecting recent activity. **Read the 3 latest comments first** to understand the current state; if that context is inconclusive or references earlier requirements, read a few more comments backwards. If a human or peer agent posted new feedback or instructions after the last agent completion, that issue is active work: strip the finished marker, claim it, and execute.
153
+ - **Aging Attention Heuristic**: If an issue has an attention signal, has no work-blocking labels (`state/1-wip`, `flag/stop-work`, `blockee`, `upstream`), and has had no action for a reasonable window (> 15-30m or oldest updated), the Orchestrator hands it out or an idle agent claims it.
154
+ - **`state/` lifecycle**: `0-triage` โ†’ `1-wip` โ†’ `2-review` โ†’ `3-verify` โ†’ `4-done`.
155
+ - **`attention/2-user`**: Escalation signal for blocked or ambiguous issues.
156
+ - **Strict Guardrail**: Agents may **never** use this label as an excuse to avoid work or offload solvable technical decisions.
157
+ - **Mandatory Requirement**: Whenever applying it, the agent **MUST** post a clear, precise comment directly addressing the human operator stating what options exist and what exact clarification or decision is required.
158
+ - **`spec/` (pre-code shaping)**: When `spec/0-needed` is present, the job is **strictly pre-code shaping** โ€” update the ticket body with specifications, constraints, and a `- [ ]` checklist. **No code or file modifications.** Advance to `spec/1-checklist`, then wait; implementation begins only after the operator approves (`spec/2-approved`).
159
+ - **`flag/stop-work`**: Circuit breaker scoped strictly to this issue. If working on it, stop immediately โ€” do not commit or push further changes for it.
160
+ - **`flag/agent-ignore`**: Hard silence directive. Ignore the issue entirely unless `SOS`/`priority/0-SOS` is explicitly set.
161
+ - **`priority/4-backburner`**: Lowest priority. Never prioritize over standard or high priority work.
162
+ - **`blockee` / `blocker`**: Dependency indicators. Check linked blocking issues before proceeding.
163
+ - **`upstream`**: Blocked on an upstream capability or bug fix; **`upstream-check`**: steering instruction to investigate upstream before implementing a workaround.
164
+
165
+ ### Scoped & Exclusive Labels
166
+
167
+ Seed these labels from [`../../labels/label-base.yaml`](../../labels/label-base.yaml).
168
+ When scoped labels (`scope/name`) with `exclusive: true` are present, applying a
169
+ new label in a scope automatically evicts any existing label sharing that scope
170
+ at the Forgejo DB level:
171
+
172
+ - **`format/`**: `format/0-needed` โ†” `format/1-ok`.
173
+ - **`spec/`**: `spec/0-needed` โ†’ `spec/1-checklist` โ†’ `spec/2-approved`.
174
+ - **`state/`**: `state/0-triage` โ†’ `state/1-wip` โ†’ `state/2-review` โ†’ `state/3-verify` โ†’ `state/4-done`.
175
+ - **`attention/`**: `attention/0-orchestrator` โ†” `attention/1-agent` โ†” `attention/2-user` โ†” `attention/3-ignore`.
176
+ - **`priority/`**: `priority/0-SOS` โ†” `priority/1-high` โ†” `priority/2-normal` โ†” `priority/3-low` โ†” `priority/4-backburner`.
177
+
178
+ The plugin's own label write (Labels tab / `forge.set-label`) adds the new
179
+ label **and** explicitly removes any same-scope mate, so it stays correct on
180
+ boards whose scope names differ from the canonical set.
181
+
182
+ ### Missing labels are advisory (cold start)
183
+
184
+ The operator may apply **no labels at all** โ€” a ticket can reach you with an
185
+ empty label set, and that is normal, not a signal that it is out of scope. Read
186
+ the ticket and comment thread, infer the state/priority yourself, and set the
187
+ labels on first touch. Never skip or park work solely because `state/`, `spec/`,
188
+ or `priority/` is absent.
189
+
190
+ ### Board Prioritization & Intelligence Model
191
+
192
+ Rank the board yourself from the plugin's board overview / issues list:
193
+
194
+ 1. **Deterministic baseline**: order by the sort tuple the plugin uses โ€”
195
+ `priorityRank`, then `stateRank`, then recency. Surface unlabeled issues as
196
+ normal priority with no state rank; never hide them.
197
+ 2. **Agent reasoning**: labels and comment deltas cannot express unstated
198
+ context. Check discussions for operator guidance (`spec/0-needed` โ†’
199
+ `spec/1-checklist`), tickets unblocked by recent commits or sibling issues,
200
+ and tickets parked on a clarifying question. A comment containing
201
+ `/orchestrator <text>` is a direct routing signal to the Orchestrator โ€” even
202
+ terse free text must be surfaced as an instruction, not dismissed as webhook
203
+ noise.
204
+
205
+ ---
206
+
207
+ ## 6. Task Execution Lifecycle
208
+
209
+ ### Step 1: Discover & Claim Work
210
+ 1. Look for unblocked issues tagged **`attention/1-agent`** (available task) or urgent **`priority/0-SOS`**.
211
+ 2. **Mandatory Full Ticket & History Audit**:
212
+ - **Read the entire ticket**: Never assume you know the scope from the title or prior memory. The issue body may have been rewritten, amended, or contain crucial boundary constraints.
213
+ - **Read the ENTIRE comment thread**: Human operators frequently modify scope (e.g. *"SKIP step 2"*, *"Do not touch X"*, *"Focus only on Y"*), or another agent might have added crucial context or warnings. Blindly executing a plan without verifying the latest comment thread is a critical protocol violation.
214
+ 3. Check issue comments to verify no other agent has already claimed it.
215
+ 4. Post a claim comment (plugin composer / `forge.add-comment` / `POST .../comments`).
216
+ 5. **Attach `state/1-wip` immediately** โ€” via the Labels tab / `forge.set-label`,
217
+ or `PATCH .../issues/<n>` with the label set. Because `state/` is an
218
+ exclusive scope, applying `state/1-wip` clears any prior state.
219
+
220
+ ### Step 2: Implementation Guidelines
221
+ - **Autonomous Execution**: Work quietly in your designated worktree/checkout without spamming chat.
222
+ - **Stage explicit paths only; never `git add -A`** in a shared tree.
223
+
224
+ #### Mandatory: Paseo Plugin Helper UI Standards (Never Bespoke Raw React Native)
225
+ When building or modifying client UI in Paseo plugins:
226
+ 1. **Reference Gold Standard**: Inspect `plugins/mcp-tools` as the canonical reference implementation.
227
+ 2. **Never Handroll Bespoke UI Primitives**:
228
+ - **Do NOT hardcode modal dimensions**: Never set `minWidth`, `minHeight`, or fixed widths on `<ModalBody>` or modal containers. Modals must be 100% fluid.
229
+ - **Do NOT roll custom buttons or selectors using `<Pressable>`**: Use `Button`, `Tabs`, or `FormRow` containing `Button` variants (`variant="primary" | "ghost" | "secondary"`).
230
+ - **Do NOT roll custom form rows or setting switches**: Use `<FormRow label="..." description="...">` wrapping `<Toggle>` or `<TextInput>`.
231
+ - **Do NOT roll custom card borders or headers**: Use `<Card variant="elevated">`, `<Card.Header title="..." subtitle="..." />`, or `<SectionHeader>`.
232
+ - **Do NOT roll custom key/value displays**: Use `<KeyValueGroup>` and `<KeyValue>` (or `CompactKeyValue`).
233
+ - **Do NOT roll custom empty or status indicators**: Use `<EmptyState>` and `<StatusDot>`.
234
+ 3. **Available Helper Client Palette**: Exported from `paseo-plugin-helper/client`:
235
+ - **Layout**: `ModalBody`, `ActionBar`, `FormRow`
236
+ - **Components**: `Card`, `Tabs`, `Button`, `Toggle`, `TextInput`, `Badge`, `StatusDot`, `KeyValue`, `KeyValueGroup`, `Collapsible`, `SectionHeader`, `CommandBox`, `AttentionBeacon`, `CodeBlock`, `SearchInput`, `EmptyState`, `ProgressBar`, `MetricGauge`, `DataTable`, `TruncatedText`, `AboutSection`, `Icon`
237
+ 4. **Audit Before Delivery**:
238
+ - Run `./packages/paseo-plugin-helper/bin/paseo-plugin-helper.js audit <plugin-path>` to catch anti-patterns.
239
+
240
+ - **Verification:** Run typechecks (`npm run typecheck`), linters, and test suites locally before claiming completion.
241
+
242
+ ### Step 3: Handoff (`state/2-review` or `state/3-verify`)
243
+ When code is implemented and verified locally:
244
+ 1. Commit and push your branch/commits to `origin`.
245
+ 2. **Live freshness** (if you ship a running artifact): build/sync it and reload
246
+ the consumer per your deployment so the process actually runs HEAD. Never
247
+ present unverified work for testing.
248
+ 3. Post a completion comment with a clean footer if you use one (ยง4).
249
+ - **Strict Formatting Standard**: Never dump an unformatted, narrative wall of text. Use structured markdown with headers, bulleted deliverables, explicit code host/repo/branch/SHA, and test results.
250
+ - **Deployment & Verification Status block**:
251
+ ```markdown
252
+ ### Deployment & Verification Status
253
+ - **Commit**: `<sha>` on `origin/<branch>`
254
+ - **Tests**: `<command>` โ€” passed
255
+ - **Client Action**: Re-open the surface (or Ctrl+R / Cmd+R in the client).
256
+ ```
257
+ 4. **Transition the state** to `state/2-review` (internal review) or
258
+ `state/3-verify` (operator testing) via the Labels tab / `forge.set-label` /
259
+ `PATCH .../issues/<n>`.
260
+ - Because `state/` is an exclusive scope, this clears the prior state.
261
+ 5. **Do NOT close the issue**: Agents and the Orchestrator do not close issues upon completion. The issue must remain `open` so the human operator can verify and close it.
262
+ 6. Stand by for fast review from the `Orchestrator` or testing by the human operator.
@@ -0,0 +1,271 @@
1
+ ---
2
+ name: coding-agent-fgjx
3
+ description: EXAMPLE skill โ€” richer CLI variant: board workflow and task lifecycle for coding agents driving Forgejo through the fgjx wrapper over fgj
4
+ ---
5
+
6
+ > [!WARNING]
7
+ > **This is an example, not a drop-in.** It is the CLI variant of the
8
+ > `coding-agent` skill: it drives the board through a `fgjx` wrapper, which in
9
+ > turn needs the `fgj` CLI. Neither tool is part of the plugin. Adapt the host,
10
+ > repo, tooling, labels, and envelope format to your own workflow before use.
11
+ > If you have no forge CLI, use the zero-dependency
12
+ > [`../coding-agent/SKILL.md`](../coding-agent/SKILL.md) variant instead. See
13
+ > [`../../README.md`](../../README.md), [`../../tools/README.md`](../../tools/README.md),
14
+ > and [`../../docs/workflow.md`](../../docs/workflow.md).
15
+
16
+ # Coding Agent Skill (fgjx CLI)
17
+
18
+ This skill defines the operational workflow, CLI usage, issue conventions, and
19
+ reporting standards for **coding agents** operating behind a shared forge user
20
+ identity, using the `fgjx` wrapper.
21
+
22
+ > [!IMPORTANT]
23
+ > **Token Economy Rule**: If you explained or documented something in a Forgejo issue comment, **keep conversation responses in the agent/user harness strictly brief and low-token**. Point directly to the issue number/link; do not duplicate long explanations into chat.
24
+
25
+ ---
26
+
27
+ ## 0. Prerequisites: `fgjx` needs `fgj`
28
+
29
+ `fgjx` is a display/label shim, **not** a standalone client. It only wraps
30
+ `fgj`:
31
+
32
+ - **`fgj` is the authenticated transport.** It owns the host URL and the token
33
+ (its `config.yaml`, or `--hostname` / `--config` flags) and performs the raw
34
+ Gitea-family `/api/v1` HTTP calls. Every `fgjx` action bottom out in
35
+ `fgj api ...`.
36
+ - **`fgjx` adds board-shaped verbs** on top: a `LABELS` column and sort filters
37
+ for `issue list`, a labels header + formatted comments for `issue view`,
38
+ label-name โ†’ id resolution for `issue edit`, `--format` body wrapping, and
39
+ `--envelope` attribution stamping.
40
+
41
+ So **you must supply `fgj`**, pointed at *your* forge, or `fgjx` cannot run โ€” it
42
+ fails loudly (exit 127) when `fgj` is missing. The wrapper is vendored at
43
+ [`../../tools/fgjx`](../../tools/fgjx); copy it onto `PATH` and read
44
+ [`../../tools/README.md`](../../tools/README.md) for the split and the optional
45
+ envelope tool. The envelope generator is **optional** โ€” the core workflow does
46
+ not need it.
47
+
48
+ ---
49
+
50
+ ## 1. Primary Tool: `fgjx` (Always use `fgjx`, NEVER `fgj` directly)
51
+
52
+ Interact with the Forgejo task board using `fgjx` (available in `$PATH`).
53
+ **Rule**: Always invoke `fgjx`, never bare `fgj`. `fgjx` is a complete passthrough wrapper over `fgj` (including `fgjx api ...`) while adding display enhancements (labels, formatting, envelope stamping).
54
+
55
+ - **Host**: `forge.example.com` (via `--hostname`, or your `fgj` config)
56
+ - **Repo**: `your-org/your-repo` (or target repo in `owner/repo` format)
57
+
58
+ ### Essential Commands
59
+
60
+ ```bash
61
+ # List open issues with labels
62
+ fgjx --hostname forge.example.com -R your-org/your-repo issue list
63
+
64
+ # View issue details, labels, and formatted comment history
65
+ fgjx --hostname forge.example.com -R your-org/your-repo issue view <NUMBER>
66
+
67
+ # Post a comment with auto agent-envelope self-stamp (optional envelope tool)
68
+ fgjx issue comment <NUMBER> --hostname forge.example.com -R your-org/your-repo --envelope -b "Comment text"
69
+
70
+ # Call raw API via fgjx (never use bare fgj api)
71
+ fgjx api repos/your-org/your-repo/issues/<NUMBER> --hostname forge.example.com
72
+
73
+ # Page a collection explicitly โ€” `fgj api` is the raw transport, so limit/page
74
+ # are always available even when a CLI verb does not expose them
75
+ fgjx api 'repos/your-org/your-repo/issues?state=open&type=issues&limit=50&page=2' \
76
+ --hostname forge.example.com
77
+ fgjx api 'repos/your-org/your-repo/labels?limit=50&page=2' \
78
+ --hostname forge.example.com
79
+ ```
80
+
81
+ > [!WARNING]
82
+ > **List and search calls are paged โ€” one call is never the whole set.** Every
83
+ > Gitea-family collection endpoint returns a single page, and the default page
84
+ > size is **server-defined and can change**, so an unpaged call silently
85
+ > truncates. This binds the **issue list, search results, label list, and
86
+ > comment list** โ€” `fgjx issue list`, `issue view`'s comment history, label
87
+ > lookups, and anything backed by `.../issues`, `.../issues?q=`, `.../labels`,
88
+ > or `.../issues/<n>/comments`. Always page: pass `limit` and increment `page`
89
+ > until a short page comes back, or follow the `Link` header / `X-Total-Count`
90
+ > when the server sends them โ€” `fgjx api '<path>?limit=50&page=N'` always
91
+ > works whether or not the verb exposes paging flags. Never treat page 1 as
92
+ > complete, and never conclude "no results" (or "labels not found") from one
93
+ > unpaged call. Worked example: an unpaged `fgj label list` returned **30 of
94
+ > 59** labels and produced false "labels not found" errors (#197).
95
+
96
+ > [!NOTE]
97
+ > `fgjx issue edit --add-label` splits comma-joined names (`--add-label 'a,b'`)
98
+ > and resolves each name to an id before writing. An **unknown label name fails
99
+ > non-zero** and nothing is written. Repeating the flag (`--add-label a
100
+ > --add-label b`) remains the most portable form.
101
+
102
+ > [!IMPORTANT]
103
+ > **Clean Markdown & Backticks**: When posting comments via shell or heredocs, do NOT double-escape backticks with backslashes (e.g. avoid `\`\`\`` or `\`code\``). Backslashes display literally on the Forgejo web UI. Use unescaped single quotes, heredocs (`cat << 'EOF'`), or raw file input (`-F file` or python) to preserve clean triple backticks (` ``` `).
104
+
105
+ > [!NOTE]
106
+ > Forgejo (`forge.example.com`) is the **primary git remote (`origin`) and issues tracker**. All agent code pushes go to `origin` on Forgejo. Pushes to public GitHub are strictly manual and gated by human review.
107
+
108
+ ---
109
+
110
+ ## 2. Issue Referencing & Linking Conventions
111
+
112
+ When referencing issues in comments, commit messages, or chat harness:
113
+ 1. **Instance-Qualified Links**: We may have multiple Forgejo/Git instances. Always format issue references with clickable markdown URLs including the instance descriptor, for example:
114
+ `[Issue #47 (forge.example.com)](https://forge.example.com/your-org/your-repo/issues/47)`
115
+ 2. **Never echo redundant issue numbers**: Do not post naked `#47` inside comments on issue #47 itself without additional context. Reference external/cross-issue links with their full URL and repo/forge context.
116
+
117
+ ---
118
+
119
+ ## 3. Commit Tracking: Explicit Code Host & Commit SHAs
120
+
121
+ If an issue fix includes a code commit:
122
+ 1. **Always record the exact commit SHA and branch**:
123
+ `commit: abc1234 on branch main in forge.example.com/your-org/your-repo`
124
+ 2. **Public Mirroring**: Never push directly to GitHub without human instruction; code stays on Forgejo `origin`. For external repositories, state the repository origin remote + branch + SHA explicitly.
125
+ 3. **Anchored resolution explanations**: post the why + commit ref on the resolved issue itself, never as a loose top-level thread elsewhere.
126
+
127
+ ---
128
+
129
+ ## 4. Mandatory: Self-Stamping with Agent Envelope
130
+
131
+ When several agents share one forge account, stamp every issue comment and
132
+ status update so attribution survives (`fgjx issue comment <id> --envelope -b ...`).
133
+
134
+ The envelope generator is **optional** and resolved by `fgjx` in this order:
135
+ `$ENVELOPE_TOOL`, then `envelope-tool` on `$PATH`, then `$HOME/bin/envelope-tool`,
136
+ else a generic `<sub>๐Ÿค– agent ยท <timestamp></sub>` fallback. If you have no such
137
+ tool, the fallback still marks the comment as machine-authored; the core
138
+ workflow does not depend on it.
139
+
140
+ ### Envelope Template
141
+
142
+ Actual comment text comes first. The footer is appended as a clean, single-line
143
+ markdown badge:
144
+
145
+ ```markdown
146
+ <Your actual comment / progress report / deliverable here>
147
+
148
+ ---
149
+ <sub>๐Ÿค– **<AgentName/SessionTitle>** (`<ShortId>`) ยท `<Model>` ยท `<Repo>:<Branch>` ยท _<UTC Timestamp>_</sub>
150
+ ```
151
+
152
+ > [!CAUTION]
153
+ > **Stamps are convention-only, unverified**: the envelope name is resolved best-effort (daemon snapshot title when reachable, else env / provider session DB). The daemon title, the provider session title, and transient retitles can disagree, and nothing records who set a title โ€” so a stamp may disagree with what the Paseo UI shows. Never treat a stamp as proof of which agent acted. If a stamp looks wrong, check `paseo ls` / `paseo inspect <id>` before assuming attribution.
154
+
155
+ ---
156
+
157
+ ## 5. Steering Labels & Operational Directives
158
+
159
+ Understand the intent of board labels:
160
+
161
+ - **`attention/1-agent`**: Dispatch signal โ€” this task is available and open for an agent to inspect, claim, or act upon.
162
+ - **Precedence Rule (Recent Updates Over Labels)**: If an issue has a recent update (`updated_at` delta), **recent comments and feedback ALWAYS take precedence over static labels**. Never rely on an existing label and move on without inspecting recent activity. **Read the 3 latest comments first** to understand the current state; if that context is inconclusive or references earlier requirements, read a few more comments backwards. If a human or peer agent posted new feedback or instructions after the last agent completion, that issue is active work: strip the finished marker, claim it, and execute.
163
+ - **Aging Attention Heuristic**: If an issue has an attention signal, has no work-blocking labels (`state/1-wip`, `flag/stop-work`, `blockee`, `upstream`), and has had no action for a reasonable window (> 15-30m or oldest updated), the Orchestrator hands it out or an idle agent claims it.
164
+ - **`state/` lifecycle**: `0-triage` โ†’ `1-wip` โ†’ `2-review` โ†’ `3-verify` โ†’ `4-done`.
165
+ - **`attention/2-user`**: Escalation signal for blocked or ambiguous issues.
166
+ - **Strict Guardrail**: Agents may **never** use this label as an excuse to avoid work or offload solvable technical decisions.
167
+ - **Mandatory Requirement**: Whenever applying it, the agent **MUST** post a clear, precise comment directly addressing the human operator stating what options exist and what exact clarification or decision is required.
168
+ - **`spec/` (pre-code shaping)**: When `spec/0-needed` is present, the job is **strictly pre-code shaping** โ€” update the ticket body with specifications, constraints, and a `- [ ]` checklist. **No code or file modifications.** Advance to `spec/1-checklist`, then wait; implementation begins only after the operator approves (`spec/2-approved`).
169
+ - **`flag/stop-work`**: Circuit breaker scoped strictly to this issue. If working on it, stop immediately โ€” do not commit or push further changes for it.
170
+ - **`flag/agent-ignore`**: Hard silence directive. Ignore the issue entirely unless `SOS`/`priority/0-SOS` is explicitly set.
171
+ - **`priority/4-backburner`**: Lowest priority. Never prioritize over standard or high priority work.
172
+ - **`blockee` / `blocker`**: Dependency indicators. Check linked blocking issues before proceeding.
173
+ - **`upstream`**: Blocked on an upstream capability or bug fix; **`upstream-check`**: steering instruction to investigate upstream before implementing a workaround.
174
+
175
+ ### Scoped & Exclusive Labels
176
+
177
+ Seed these labels from [`../../labels/label-base.yaml`](../../labels/label-base.yaml).
178
+ When scoped labels (`scope/name`) with `exclusive: true` are present, applying a
179
+ new label in a scope automatically evicts any existing label sharing that scope
180
+ at the Forgejo DB level, so no `--remove-label` is needed for the happy path:
181
+
182
+ - **`format/`**: `format/0-needed` โ†” `format/1-ok`.
183
+ - **`spec/`**: `spec/0-needed` โ†’ `spec/1-checklist` โ†’ `spec/2-approved`.
184
+ - **`state/`**: `state/0-triage` โ†’ `state/1-wip` โ†’ `state/2-review` โ†’ `state/3-verify` โ†’ `state/4-done`.
185
+ - **`attention/`**: `attention/0-orchestrator` โ†” `attention/1-agent` โ†” `attention/2-user` โ†” `attention/3-ignore`.
186
+ - **`priority/`**: `priority/0-SOS` โ†” `priority/1-high` โ†” `priority/2-normal` โ†” `priority/3-low` โ†” `priority/4-backburner`.
187
+
188
+ ### Missing labels are advisory (cold start)
189
+
190
+ The operator may apply **no labels at all** โ€” a ticket can reach you with an
191
+ empty label set, and that is normal, not a signal that it is out of scope. Read
192
+ the ticket and comment thread, infer the state/priority yourself, and set the
193
+ labels on first touch. Never skip or park work solely because `state/`, `spec/`,
194
+ or `priority/` is absent.
195
+
196
+ ### Board Prioritization & Intelligence Model
197
+
198
+ 1. **Deterministic baseline**: order by the plugin's sort tuple โ€”
199
+ `priorityRank`, then `stateRank`, then recency.
200
+ 2. **Agent reasoning**: labels cannot express unstated context. Check
201
+ discussions (`spec/0-needed` โ†’ `spec/1-checklist`), tickets unblocked by
202
+ recent commits or siblings, and tickets parked on a question. A comment with
203
+ `/orchestrator <text>` is a direct routing signal โ€” even terse free text must
204
+ be surfaced as an instruction, not dismissed as webhook noise.
205
+
206
+ ---
207
+
208
+ ## 6. Task Execution Lifecycle
209
+
210
+ ### Step 1: Discover & Claim Work
211
+ 1. Look for unblocked issues tagged **`attention/1-agent`** (available task) or urgent **`priority/0-SOS`**.
212
+ 2. **Mandatory Full Ticket & History Audit**:
213
+ - **Read the entire ticket**: Never assume you know the scope from the title or prior memory. The issue body may have been rewritten, amended, or contain crucial boundary constraints.
214
+ - **Read the ENTIRE comment thread**: Human operators frequently modify scope (e.g. *"SKIP step 2"*, *"Do not touch X"*, *"Focus only on Y"*), or another agent might have added crucial context or warnings. Blindly executing a plan without verifying the latest comment thread is a critical protocol violation.
215
+ 3. If the issue has **`upstream-check`**, first audit upstream repositories/docs to inform your approach.
216
+ 4. Check issue comments to verify no other agent has already claimed it.
217
+ 5. Post a claim comment (`fgjx issue comment <n> --envelope -b ...`).
218
+ 6. **Attach `state/1-wip` immediately**:
219
+ `fgjx issue edit <number> --add-label state/1-wip`.
220
+ Because `state/` is an exclusive scope, this clears any prior state without
221
+ needing removal flags.
222
+
223
+ ### Step 2: Implementation Guidelines
224
+ - **Autonomous Execution**: Work quietly in your designated worktree/checkout without spamming chat.
225
+ - **Stage explicit paths only; never `git add -A`** in a shared tree.
226
+
227
+ #### Mandatory: Paseo Plugin Helper UI Standards (Never Bespoke Raw React Native)
228
+ When building or modifying client UI in Paseo plugins:
229
+ 1. **Reference Gold Standard**: Inspect `plugins/mcp-tools` as the canonical reference implementation.
230
+ 2. **Never Handroll Bespoke UI Primitives**:
231
+ - **Do NOT hardcode modal dimensions**: Never set `minWidth`, `minHeight`, or fixed widths on `<ModalBody>` or modal containers. Modals must be 100% fluid.
232
+ - **Do NOT roll custom buttons or selectors using `<Pressable>`**: Use `Button`, `Tabs`, or `FormRow` containing `Button` variants (`variant="primary" | "ghost" | "secondary"`).
233
+ - **Do NOT roll custom form rows or setting switches**: Use `<FormRow label="..." description="...">` wrapping `<Toggle>` or `<TextInput>`.
234
+ - **Do NOT roll custom card borders or headers**: Use `<Card variant="elevated">`, `<Card.Header title="..." subtitle="..." />`, or `<SectionHeader>`.
235
+ - **Do NOT roll custom key/value displays**: Use `<KeyValueGroup>` and `<KeyValue>` (or `CompactKeyValue`).
236
+ - **Do NOT roll custom empty or status indicators**: Use `<EmptyState>` and `<StatusDot>`.
237
+ 3. **Available Helper Client Palette**: Exported from `paseo-plugin-helper/client`:
238
+ - **Layout**: `ModalBody`, `ActionBar`, `FormRow`
239
+ - **Components**: `Card`, `Tabs`, `Button`, `Toggle`, `TextInput`, `Badge`, `StatusDot`, `KeyValue`, `KeyValueGroup`, `Collapsible`, `SectionHeader`, `CommandBox`, `AttentionBeacon`, `CodeBlock`, `SearchInput`, `EmptyState`, `ProgressBar`, `MetricGauge`, `DataTable`, `TruncatedText`, `AboutSection`, `Icon`
240
+ 4. **Audit Before Delivery**:
241
+ - Run `./packages/paseo-plugin-helper/bin/paseo-plugin-helper.js audit <plugin-path>` to catch anti-patterns.
242
+
243
+ - **Verification:** Run typechecks (`npm run typecheck`), linters, and test suites locally before claiming completion.
244
+
245
+ ### Step 3: Handoff (`state/2-review` or `state/3-verify`)
246
+ When code is implemented and verified locally:
247
+ 1. Commit and push your branch/commits to `origin`.
248
+ 2. **Live freshness** (if you ship a running artifact): build/sync it and reload
249
+ the consumer per your deployment so the process actually runs HEAD. Never
250
+ present unverified work for testing.
251
+ 3. Post a completion comment with your envelope
252
+ (`fgjx issue comment <n> --envelope -b ...`).
253
+ - **Strict Formatting Standard**: Never dump an unformatted, narrative wall of text. Use structured markdown with headers, bulleted deliverables, explicit code host/repo/branch/SHA, and test results.
254
+ - **Deployment & Verification Status block**:
255
+ ```markdown
256
+ ### Deployment & Verification Status
257
+ - **Commit**: `<sha>` on `origin/<branch>`
258
+ - **Tests**: `<command>` โ€” passed
259
+ - **Client Action**: Re-open the surface (or Ctrl+R / Cmd+R in the client).
260
+ ```
261
+ 4. **Transition the state**:
262
+ - `fgjx issue edit <number> --add-label state/2-review` (internal review), or
263
+ - `fgjx issue edit <number> --add-label state/3-verify` (operator testing).
264
+ - Because `state/` is an exclusive scope, this clears the prior state
265
+ automatically.
266
+
267
+ > [!CAUTION]
268
+ > **MANDATORY LABEL UPDATE**: You MUST run the `fgjx issue edit ... --add-label ...`. Merely posting a comment without executing the label update leaves the issue stranded in its old state on the board.
269
+
270
+ 5. **Do NOT close the issue**: Agents and the Orchestrator do not close issues upon completion. The issue must remain `open` so the human operator can verify and close it.
271
+ 6. Stand by for fast review from the `Orchestrator` or testing by the human operator.