@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,133 @@
1
+ ---
2
+ name: orchestrator
3
+ description: EXAMPLE skill — workflow, pre-flight audits, agent synchronization, and human-in-the-loop signoff protocols for the orchestrating agent
4
+ ---
5
+
6
+ > [!WARNING]
7
+ > **This is an example, not a drop-in.** It encodes one team's board
8
+ > conventions (labels, slash commands, issue-link format) built on the
9
+ > scoped label seed in `../../labels/label-base.yaml`. This variant operates
10
+ > through the `forges` plugin's own surfaces and embedded `/api/v1` client and
11
+ > needs no forge CLI; the richer CLI twin is
12
+ > [`../orchestrator-fgjx/SKILL.md`](../orchestrator-fgjx/SKILL.md). Adapt the
13
+ > labels, commands, and escalation rules to your own workflow before use. See
14
+ > `../../README.md` and `../../docs/workflow.md`.
15
+
16
+ # Orchestrator Skill
17
+
18
+ You coordinate the fleet. Default: **delegate unless stopped**. Labels describe state; they never gate action.
19
+
20
+ > [!WARNING]
21
+ > **Reads are paged — page 1 is not the board.** Issue lists, search results,
22
+ > label lists, and comment lists each return a single page, and the default page
23
+ > size is **server-defined and can change**, so an unpaged read silently
24
+ > truncates. Page every list read before you reason about it (`limit`/`page`, or
25
+ > follow `Link` / `X-Total-Count`): never rank, dispatch, or conclude "no
26
+ > results" from one unpaged call. The board overview and label chips are
27
+ > collections too — a surface that lists results must page internally rather
28
+ > than render a truncated set (#189). Worked example: an unpaged `fgj label
29
+ > list` returned **30 of 59** labels, producing false "labels not found" errors
30
+ > (#197).
31
+
32
+ ## 1. Binding stops (only two)
33
+
34
+ - `priority/0-SOS` — preempt everything, handle first.
35
+ - `flag/stop-work` — do not touch, full stop.
36
+
37
+ Everything else (`spec/*`, `attention/*`, `state/*`, missing labels, one-word tickets) is advisory.
38
+
39
+ ## 2. Delegate by default
40
+
41
+ - `attention/0-orchestrator`, bare text, or no labels at all still means: infer scope, shape it, dispatch if tree-safe.
42
+ - Typical operator input like "build's failing, fix" is sufficient. Pull context yourself (`git status/log`, failing command output, recent comments), form the checklist, set labels yourself, dispatch.
43
+ - Only stop-and-ask when: tree-unsafe (operator hands-on in checkout), scope truly uninterpretable, or you need device/credential/2FA input. Ask one question via `attention/2-user`.
44
+ - `spec/2-approved` is a hint you've pre-shaped it, not a gate. Never wait for it.
45
+ - Slash-commands (`/hold`, `/rework`, `/approve`, etc.): obey when present, never go looking for them. Static labels + ticket text are the primary signal. Full vocabulary in §6.
46
+
47
+ ## 3. Dispatch
48
+
49
+ - One ticket = one worker. Isolate by package dir. Instruct worker: envelope claim comment, `state/1-wip` on start, `state/3-verify` + envelope report on done. Never `git add -A` (stage explicit paths only).
50
+ - Tree conflicts gate dispatch: queue, don't collide. Single shared checkout means one worker in the tree at a time until worktree isolation (#52) exists.
51
+ - Workers run via subagents; provider/model copied from a known-good session record, never guessed.
52
+
53
+ ## 4. Pre-flight before human testing (only real gate)
54
+
55
+ Before `state/3-verify` + `attention/2-user` ("real-use test this"):
56
+ - Tree clean, committed, pushed, tests + typecheck green.- Runtime sync via `make doctor` (or `reload` to auto-synchronize): helper `dist` fresh, plugin `shared/version.ts` matches HEAD, live daemon executing latest commit.
57
+ - **Source-pinning gate:** `paseo plugin ls` — a `git`-sourced plugin must have checkout COMMIT ≥ expected HEAD or do not present; fix delivery first. State source + commit in every presentation.
58
+ - Client refresh flag: note whether the operator needs `Ctrl+R` / re-open.
59
+ - Never present unverified work.
60
+ - The presentation lives on the board: post the pre-flight summary + operator checklist as an issue comment (lasting record). Chat gets a one-line pointer, never the substance.
61
+ ## 5. Verify is non-binding
62
+
63
+ `state/3-verify` never means "blocked on human forever." If the operator doesn't test: close as superseded/done with rationale, requeue, or verify by proxy — and say so on the ticket. No mutual-wait deadlocks.
64
+
65
+ ## 6. Operator Slash-Command Protocol (Issue Comments)
66
+
67
+ The operator signals with line-anchored `/`-commands in issue comments. Obey when present; never go looking.
68
+
69
+ ### Recognition rules
70
+ - A command is a line whose first non-space character is `/`: `^/\w+` plus optional same-line args. Trailing punctuation (e.g. `/orchestrator.`) tolerated.
71
+ - Only commands authored by the operator handle apply; identical text from agents or others is ignored.
72
+ - Inline `/words` mid-sentence never trigger.
73
+ - Unknown `/words` are ignored (forward-compatible; Paseo-side slash commands never collide — those live in Paseo, not in Forgejo comments).
74
+ - Free-text bodies continue on following non-blank, non-command lines until a blank line or the next command.
75
+
76
+ ### Deterministic lifecycle commands
77
+ - `/approve` — spec/checklist accepted (`spec/2-approved` or equivalent state advance).
78
+ - `/verify` or `/done` — work accepted pending check: run pre-flight, present for operator testing (`state/3-verify`).
79
+ - `/close` — operator confirms the deliverable (`confirmed-done`).
80
+ - `/hold` — stop and hand back to orchestrator (`attention/0-orchestrator`).
81
+ - `/rework <note>` — return to `state/1-wip` with the note as the steering directive.
82
+
83
+ ### Free-text routing commands (orchestrator interprets, may route)
84
+ - `/instruction <text>` — free-text directive to the orchestrator; it executes or routes to the worker itself.
85
+ - `/orchestrator <text>` — explicit override: orchestrator handles directly, never forwards.
86
+ - `/agent <text>` — explicit override: forward verbatim as steering to the active worker on that issue.
87
+
88
+ An explicit `/orchestrator` directive is actionable even when its free-text is
89
+ informal or terse. Treat phrases such as `/orchestrator holler` as a request
90
+ to immediately inspect the complete ticket and latest workspace/agent state,
91
+ then report the relevant finding or blocker; do not classify the message as a
92
+ routine webhook or dismiss it because it lacks a conventional command verb.
93
+
94
+ ## 7. Attention Contract (Agreed Operating Rules)
95
+
96
+ - The operator only touches `attention/*`. Nothing else is a signal.
97
+ - `attention/0-orchestrator` means "you own it, don't let it sit": handle the deliverable, delegate, or — if the next step is unclear — flip to `attention/2-user` with a one-line question. An issue must never rest on `0-orchestrator`.
98
+ - Anything needing operator eyes (approval, verify, decision, question) MUST carry `attention/2-user` — otherwise it is invisible.
99
+ - Tree conflicts keep gating dispatch: no worker enters a checkout the operator is hands-on in. Queue, don't collide.
100
+ - Pre-flight stands: never present unverified work for operator testing.
101
+ - Verify is non-binding: resolve unilaterally with narration rather than park in mutual wait.
102
+
103
+ ## 8. Presentation: clickable issue references
104
+
105
+ - Every issue number in chat responses and issue comments MUST be a clickable Markdown link to `https://forge.example.com/your-org/your-repo/issues/<n>` (e.g. [#98](https://forge.example.com/your-org/your-repo/issues/98)). Never emit a bare `#nnn`.
106
+
107
+ ## 9. Forgejo labels: one scoped label at a time
108
+
109
+ - Label writes go through the plugin (`forge.set-label` via the Labels tab /
110
+ label chips). It adds the new label **and** explicitly removes any same-scope
111
+ mate, so the result is correct even on boards whose scope names differ from
112
+ the canonical set — never rely on DB-level exclusivity alone.
113
+ - Verify the set changed by re-reading the issue (plugin detail view or
114
+ `GET /repos/{owner}/{repo}/issues/{n}`).
115
+ - Unknown scopes are rejected before any API call. No label CLI is required.
116
+
117
+ ## 10. Comment & chat budget (keep the board readable)
118
+
119
+ - Issue comments and pre-flight/presentation posts: **one screen (~15 lines)**.
120
+ Summary first — what changed, commit SHA, test result, what is left.
121
+ - Analysis, checklists, and design detail go in the issue **body** or a linked
122
+ child issue, not a comment.
123
+ - Never paste diffs, full test logs, or restate code already in the body.
124
+ - One comment per handoff; no per-step narration.
125
+ - Chat: one line pointing at the ticket; never duplicate the substance.
126
+ - Comment length is not a status signal. A short, complete comment beats a long
127
+ one.
128
+
129
+ ## 11. Cold start (no labels yet)
130
+
131
+ The operator may never set labels; a ticket can arrive bare. Never treat an
132
+ unlabeled ticket as out of scope or blocked: infer the state, apply the labels
133
+ yourself, and dispatch. The board is bootstrapped by agents, not by the operator.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: orchestrator-fgjx
3
+ description: EXAMPLE skill — CLI variant of the orchestrator workflow, dispatching and verifying 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
+ > `orchestrator` skill: board operations go through a `fgjx` wrapper, which
9
+ > needs the `fgj` CLI. Neither is part of the plugin. It encodes one team's
10
+ > board conventions (labels, slash commands, issue-link format) built on the
11
+ > scoped label seed in `../../labels/label-base.yaml`. If you have no forge CLI,
12
+ > use the zero-dependency [`../orchestrator/SKILL.md`](../orchestrator/SKILL.md)
13
+ > variant instead. See `../../README.md`, `../../tools/README.md`, and
14
+ > `../../docs/workflow.md`.
15
+
16
+ # Orchestrator Skill (fgjx CLI)
17
+
18
+ You coordinate the fleet. Default: **delegate unless stopped**. Labels describe state; they never gate action.
19
+
20
+ > [!NOTE]
21
+ > **Prerequisite — `fgjx` needs `fgj`.** `fgj` is the authenticated transport
22
+ > (host URL + token; performs the raw `/api/v1` calls). `fgjx` only adds
23
+ > board-shaped verbs (label resolution, table/view niceties, optional envelope
24
+ > stamping), so it fails loudly (exit 127) without `fgj`. Adopters supply `fgj`,
25
+ > pointed at their own forge; the envelope tool is optional. See
26
+ > [`../../tools/README.md`](../../tools/README.md).
27
+
28
+ > [!WARNING]
29
+ > **Reads are paged — page 1 is not the board.** Issue lists, search results,
30
+ > label lists, and comment lists each return a single page, and the default page
31
+ > size is **server-defined and can change**, so an unpaged read silently
32
+ > truncates. Page every list read before you reason about it — increment
33
+ > `limit`/`page` and follow `Link` / `X-Total-Count`, or use
34
+ > `fgjx api '<path>?limit=50&page=N'` when a verb exposes no paging flags.
35
+ > Never rank, dispatch, or conclude "no results" from one unpaged call. A
36
+ > surface that lists results must page internally rather than render a truncated
37
+ > set (#189). Worked example: an unpaged `fgj label list` returned **30 of 59**
38
+ > labels, producing false "labels not found" errors (#197).
39
+
40
+ ## 1. Binding stops (only two)
41
+
42
+ - `priority/0-SOS` — preempt everything, handle first.
43
+ - `flag/stop-work` — do not touch, full stop.
44
+
45
+ Everything else (`spec/*`, `attention/*`, `state/*`, missing labels, one-word tickets) is advisory.
46
+
47
+ ## 2. Delegate by default
48
+
49
+ - `attention/0-orchestrator`, bare text, or no labels at all still means: infer scope, shape it, dispatch if tree-safe.
50
+ - Typical operator input like "build's failing, fix" is sufficient. Pull context yourself (`git status/log`, failing command output, recent comments), form the checklist, set labels yourself, dispatch.
51
+ - Only stop-and-ask when: tree-unsafe (operator hands-on in checkout), scope truly uninterpretable, or you need device/credential/2FA input. Ask one question via `attention/2-user`.
52
+ - `spec/2-approved` is a hint you've pre-shaped it, not a gate. Never wait for it.
53
+ - Slash-commands (`/hold`, `/rework`, `/approve`, etc.): obey when present, never go looking for them. Static labels + ticket text are the primary signal. Full vocabulary in §6.
54
+
55
+ ## 3. Dispatch
56
+
57
+ - One ticket = one worker. Isolate by package dir. Instruct worker: envelope claim comment, `state/1-wip` on start, `state/3-verify` + envelope report on done. Never `git add -A` (stage explicit paths only).
58
+ - Tree conflicts gate dispatch: queue, don't collide. Single shared checkout means one worker in the tree at a time until worktree isolation (#52) exists.
59
+ - Workers run via subagents; provider/model copied from a known-good session record, never guessed.
60
+
61
+ ## 4. Pre-flight before human testing (only real gate)
62
+
63
+ Before `state/3-verify` + `attention/2-user` ("real-use test this"):
64
+ - Tree clean, committed, pushed, tests + typecheck green.- Runtime sync via `make doctor` (or `reload` to auto-synchronize): helper `dist` fresh, plugin `shared/version.ts` matches HEAD, live daemon executing latest commit.
65
+ - **Source-pinning gate:** `paseo plugin ls` — a `git`-sourced plugin must have checkout COMMIT ≥ expected HEAD or do not present; fix delivery first. State source + commit in every presentation.
66
+ - Client refresh flag: note whether the operator needs `Ctrl+R` / re-open.
67
+ - Never present unverified work.
68
+ - The presentation lives on the board: post the pre-flight summary + operator checklist as an issue comment (lasting record). Chat gets a one-line pointer, never the substance.
69
+ ## 5. Verify is non-binding
70
+
71
+ `state/3-verify` never means "blocked on human forever." If the operator doesn't test: close as superseded/done with rationale, requeue, or verify by proxy — and say so on the ticket. No mutual-wait deadlocks.
72
+
73
+ ## 6. Operator Slash-Command Protocol (Issue Comments)
74
+
75
+ The operator signals with line-anchored `/`-commands in issue comments. Obey when present; never go looking.
76
+
77
+ ### Recognition rules
78
+ - A command is a line whose first non-space character is `/`: `^/\w+` plus optional same-line args. Trailing punctuation (e.g. `/orchestrator.`) tolerated.
79
+ - Only commands authored by the operator handle apply; identical text from agents or others is ignored.
80
+ - Inline `/words` mid-sentence never trigger.
81
+ - Unknown `/words` are ignored (forward-compatible; Paseo-side slash commands never collide — those live in Paseo, not in Forgejo comments).
82
+ - Free-text bodies continue on following non-blank, non-command lines until a blank line or the next command.
83
+
84
+ ### Deterministic lifecycle commands
85
+ - `/approve` — spec/checklist accepted (`spec/2-approved` or equivalent state advance).
86
+ - `/verify` or `/done` — work accepted pending check: run pre-flight, present for operator testing (`state/3-verify`).
87
+ - `/close` — operator confirms the deliverable (`confirmed-done`).
88
+ - `/hold` — stop and hand back to orchestrator (`attention/0-orchestrator`).
89
+ - `/rework <note>` — return to `state/1-wip` with the note as the steering directive.
90
+
91
+ ### Free-text routing commands (orchestrator interprets, may route)
92
+ - `/instruction <text>` — free-text directive to the orchestrator; it executes or routes to the worker itself.
93
+ - `/orchestrator <text>` — explicit override: orchestrator handles directly, never forwards.
94
+ - `/agent <text>` — explicit override: forward verbatim as steering to the active worker on that issue.
95
+
96
+ An explicit `/orchestrator` directive is actionable even when its free-text is
97
+ informal or terse. Treat phrases such as `/orchestrator holler` as a request
98
+ to immediately inspect the complete ticket and latest workspace/agent state,
99
+ then report the relevant finding or blocker; do not classify the message as a
100
+ routine webhook or dismiss it because it lacks a conventional command verb.
101
+
102
+ ## 7. Attention Contract (Agreed Operating Rules)
103
+
104
+ - The operator only touches `attention/*`. Nothing else is a signal.
105
+ - `attention/0-orchestrator` means "you own it, don't let it sit": handle the deliverable, delegate, or — if the next step is unclear — flip to `attention/2-user` with a one-line question. An issue must never rest on `0-orchestrator`.
106
+ - Anything needing operator eyes (approval, verify, decision, question) MUST carry `attention/2-user` — otherwise it is invisible.
107
+ - Tree conflicts keep gating dispatch: no worker enters a checkout the operator is hands-on in. Queue, don't collide.
108
+ - Pre-flight stands: never present unverified work for operator testing.
109
+ - Verify is non-binding: resolve unilaterally with narration rather than park in mutual wait.
110
+
111
+ ## 8. Presentation: clickable issue references
112
+
113
+ - Every issue number in chat responses and issue comments MUST be a clickable Markdown link to `https://forge.example.com/your-org/your-repo/issues/<n>` (e.g. [#98](https://forge.example.com/your-org/your-repo/issues/98)). Never emit a bare `#nnn`.
114
+
115
+ ## 9. Forgejo labels via `fgjx`
116
+
117
+ - `fgjx issue edit --add-label` resolves each name to an id and writes it.
118
+ Comma-joined values are split, and an **unknown name fails non-zero** with
119
+ nothing written. Repeating the flag is the most portable form:
120
+ `--add-label 'a' --add-label 'b'` (same for `--remove-label`).
121
+ - Always read back with `fgjx issue view` and confirm the label set changed.
122
+
123
+ ## 10. Comment & chat budget (keep the board readable)
124
+
125
+ - Issue comments and pre-flight/presentation posts: **one screen (~15 lines)**.
126
+ Summary first — what changed, commit SHA, test result, what is left.
127
+ - Analysis, checklists, and design detail go in the issue **body** or a linked
128
+ child issue, not a comment.
129
+ - Never paste diffs, full test logs, or restate code already in the body.
130
+ - One comment per handoff; no per-step narration.
131
+ - Chat: one line pointing at the ticket; never duplicate the substance.
132
+ - Comment length is not a status signal. A short, complete comment beats a long
133
+ one.
134
+
135
+ ## 11. Cold start (no labels yet)
136
+
137
+ The operator may never set labels; a ticket can arrive bare. Never treat an
138
+ unlabeled ticket as out of scope or blocked: infer the state, apply the labels
139
+ yourself, and dispatch. The board is bootstrapped by agents, not by the operator.
@@ -0,0 +1,68 @@
1
+ # `fgjx` (vendored example)
2
+
3
+ `fgjx` is the Forgejo CLI wrapper the example Skills use for their "rich CLI"
4
+ variant. It is a **sanitized copy of the `fgjx` wrapper** — the
5
+ platform stays the source of truth, and this copy is synced by hand. Edit
6
+ upstream first, then re-copy.
7
+
8
+ It is an example, not a supported tool. Adapt it or ignore it: the plugin itself
9
+ needs neither `fgjx` nor `fgj` (see [`../skills/coding-agent/SKILL.md`](../skills/coding-agent/SKILL.md)
10
+ for the zero-dependency, embedded-`/api/v1` path).
11
+
12
+ ## Why `fgjx` needs `fgj` (the split)
13
+
14
+ `fgj` is the **authenticated transport and config provider**. It owns the host
15
+ URL and the token (its `config.yaml`, or `--hostname` / `--config` on the
16
+ command line) and performs the raw Gitea-family `/api/v1` HTTP calls. Anything
17
+ `fgj` can do — including `fgj api ...` — works directly.
18
+
19
+ `fgjx` is a thin **passthrough shim** on top of `fgj`. It adds only
20
+ board-shaped conveniences that the raw CLI lacks:
21
+
22
+ - a `LABELS` column and sorting filters for `issue list`, a labels header +
23
+ formatted comment history for `issue view`;
24
+ - **label resolution** — `issue edit --add-label/--remove-label` looks label
25
+ *names* up to ids and writes them via the API;
26
+ - **envelope stamping** — `--envelope` appends an agent attribution footer;
27
+ - `--format` body wrapping for comments.
28
+
29
+ None of that can work without `fgj`, because every call it makes is ultimately
30
+ `fgj api ...` against a host and token only `fgj` knows. That is the whole
31
+ reason this is a wrapper and not a standalone tool: **the adopter supplies
32
+ `fgj`, pointed at their own forge, and `fgjx` decorates it.** `fgjx` fails
33
+ loudly (exit 127) if `fgj` is not on `PATH`.
34
+
35
+ Point it at your forge with `fgj`'s own `config.yaml`, or per-invocation:
36
+
37
+ ```sh
38
+ fgjx --hostname forge.example.com -R your-org/your-repo issue list
39
+ fgjx issue view 42 --hostname forge.example.com -R your-org/your-repo
40
+ fgjx issue edit 42 --hostname forge.example.com -R your-org/your-repo \
41
+ --add-label state/1-wip
42
+ ```
43
+
44
+ ## Requirements
45
+
46
+ - `fgj` on `PATH` (or in `$HOME/bin/.lib`, which the wrapper prepends). Required.
47
+ - `bash` and `python3` (the wrapper shells python for JSON rendering/label id
48
+ resolution). Required.
49
+ - An **envelope tool** — optional, only for `--envelope`. Resolution order:
50
+ `$ENVELOPE_TOOL`, then `envelope-tool` on `PATH`, then `$HOME/bin/envelope-tool`,
51
+ else a generic `<sub>🤖 agent · <timestamp></sub>` fallback. The plugin does
52
+ not ship one; the core wrapper never needs it.
53
+
54
+ ## Sanitized for publication
55
+
56
+ Relative to the platform source, this copy:
57
+
58
+ - drops every absolute `/home/...` fallback (only `command -v` and
59
+ `$HOME`-relative paths remain) and names the optional envelope tool
60
+ generically;
61
+ - **fails loudly when `fgj` is missing** instead of half-running;
62
+ - carries the label-resolver fix from upstream #197: the label fetch **pages**
63
+ (`?limit=50&page=N`), comma-joined `--add-label`/`--remove-label` values are
64
+ **split**, and an **unknown label name fails non-zero** rather than being
65
+ silently skipped (and nothing is written unless every name resolves).
66
+
67
+ Anything host-specific that remains is a placeholder — replace it with your own
68
+ forge, repo, and tooling.