@codyswann/lisa 2.29.0 → 2.31.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.
- package/.agents/plugins/marketplace.json +24 -0
- package/.claude-plugin/marketplace.json +6 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/skills/github-build-intake/SKILL.md +56 -5
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +8 -0
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +32 -0
- package/plugins/lisa-openclaw/commands/connect-repo-topic.md +7 -0
- package/plugins/lisa-openclaw/commands/connect-staff-slack.md +7 -0
- package/plugins/lisa-openclaw/commands/connect-staff-telegram.md +7 -0
- package/plugins/lisa-openclaw/commands/setup-openclaw.md +7 -0
- package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-repo-topic/SKILL.md +137 -0
- package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-repo-topic/references/repo-topic-config.md +109 -0
- package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-staff/SKILL.md +175 -0
- package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-staff/references/platform-routing.md +83 -0
- package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-staff/references/prompts.md +78 -0
- package/plugins/lisa-openclaw/skills/lisa-openclaw-setup/SKILL.md +138 -0
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/src/base/skills/github-build-intake/SKILL.md +56 -5
- package/plugins/src/openclaw/.claude-plugin/plugin.json +6 -0
- package/plugins/src/openclaw/commands/connect-repo-topic.md +7 -0
- package/plugins/src/openclaw/commands/connect-staff-slack.md +7 -0
- package/plugins/src/openclaw/commands/connect-staff-telegram.md +7 -0
- package/plugins/src/openclaw/commands/setup-openclaw.md +7 -0
- package/plugins/src/openclaw/skills/lisa-openclaw-connect-repo-topic/SKILL.md +137 -0
- package/plugins/src/openclaw/skills/lisa-openclaw-connect-repo-topic/references/repo-topic-config.md +109 -0
- package/plugins/src/openclaw/skills/lisa-openclaw-connect-staff/SKILL.md +175 -0
- package/plugins/src/openclaw/skills/lisa-openclaw-connect-staff/references/platform-routing.md +83 -0
- package/plugins/src/openclaw/skills/lisa-openclaw-connect-staff/references/prompts.md +78 -0
- package/plugins/src/openclaw/skills/lisa-openclaw-setup/SKILL.md +138 -0
- package/scripts/build-plugins.sh +1 -1
- package/scripts/generate-codex-plugin-artifacts.mjs +16 -0
|
@@ -87,6 +87,30 @@
|
|
|
87
87
|
"authentication": "ON_INSTALL"
|
|
88
88
|
},
|
|
89
89
|
"category": "Coding"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "lisa-wiki",
|
|
93
|
+
"source": {
|
|
94
|
+
"source": "local",
|
|
95
|
+
"path": "./plugins/lisa-wiki"
|
|
96
|
+
},
|
|
97
|
+
"policy": {
|
|
98
|
+
"installation": "AVAILABLE",
|
|
99
|
+
"authentication": "ON_INSTALL"
|
|
100
|
+
},
|
|
101
|
+
"category": "Productivity"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "lisa-openclaw",
|
|
105
|
+
"source": {
|
|
106
|
+
"source": "local",
|
|
107
|
+
"path": "./plugins/lisa-openclaw"
|
|
108
|
+
},
|
|
109
|
+
"policy": {
|
|
110
|
+
"installation": "AVAILABLE",
|
|
111
|
+
"authentication": "ON_INSTALL"
|
|
112
|
+
},
|
|
113
|
+
"category": "Productivity"
|
|
90
114
|
}
|
|
91
115
|
]
|
|
92
116
|
}
|
|
@@ -55,6 +55,12 @@
|
|
|
55
55
|
"source": "./plugins/lisa-wiki",
|
|
56
56
|
"description": "LLM Wiki — git-native markdown knowledge base: ingest, query, lint, onboard (Claude + Codex)",
|
|
57
57
|
"category": "productivity"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "lisa-openclaw",
|
|
61
|
+
"source": "./plugins/lisa-openclaw",
|
|
62
|
+
"description": "Connect staff to Telegram or Slack via OpenClaw — facilitator/specialist routing and repo-coding topics (Claude + Codex)",
|
|
63
|
+
"category": "productivity"
|
|
58
64
|
}
|
|
59
65
|
]
|
|
60
66
|
}
|
package/package.json
CHANGED
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"lodash": ">=4.18.1"
|
|
83
83
|
},
|
|
84
84
|
"name": "@codyswann/lisa",
|
|
85
|
-
"version": "2.
|
|
85
|
+
"version": "2.31.0",
|
|
86
86
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
87
87
|
"main": "dist/index.js",
|
|
88
88
|
"exports": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github-build-intake
|
|
3
|
-
description: "GitHub counterpart to lisa:jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label, claims each by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:github-agent, and relabels to the configured `done` label on completion. The `ready` label is the human-flipped signal that an issue is truly ready for development — mirroring how Notion PRDs work product Draft → Ready → (us) In Review → Blocked|Ticketed."
|
|
3
|
+
description: "GitHub counterpart to lisa:jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label, claims each leaf work unit by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:github-agent, and relabels to the configured `done` label on completion. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic/Story/Spike) that still carries a stale build-ready label is skipped or safe-blocked with a lifecycle-repair comment, never claimed. The `ready` label is the human-flipped signal that an issue is truly ready for development — mirroring how Notion PRDs work product Draft → Ready → (us) In Review → Blocked|Ticketed."
|
|
4
4
|
allowed-tools: ["Skill", "Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -135,7 +135,54 @@ If none of the configured role labels exist on the repo → label convention not
|
|
|
135
135
|
|
|
136
136
|
### Phase 3 — Process each ready issue (serial)
|
|
137
137
|
|
|
138
|
-
#### 3a.
|
|
138
|
+
#### 3a. Leaf-only claim gate (skip / safe-block containers)
|
|
139
|
+
|
|
140
|
+
Build intake claims **only independently implementable leaf work units**. This enforces the claim-time arm of the vendor-neutral `leaf-only-lifecycle` rule: a parent/container that still carries a stale build-ready role (e.g. `status:ready` applied before this rule existed, or hand-applied to an Epic/Story) is **never claimed** — intake skips it or safe-blocks it with a clear lifecycle-repair message. It is the claim-time complement to the write-time labeling in `lisa:github-write-issue` and the validate-time S15 gate in `lisa:github-validate-issue`; all three cite the same rule so the classification never drifts. **Never silently implement a container.**
|
|
141
|
+
|
|
142
|
+
Run this gate **before** the claim relabel, for every candidate issue. Do NOT relabel, comment "Claimed", or invoke `lisa:github-agent` for an issue that fails the gate.
|
|
143
|
+
|
|
144
|
+
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an issue is a **container** if it has **open** child work, whatever its declared type; otherwise the **type label** decides. Resolve child work using the same hierarchy `lisa:github-read-issue` uses — native sub-issues first, then body parentage (task-list checkboxes referencing other issues, `Blocked by #<n>` / `Parent: #<n>` references):
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Native sub-issues via GraphQL (same query lisa:github-read-issue uses).
|
|
148
|
+
SUBS=$(gh api graphql -f query='
|
|
149
|
+
query($org:String!,$repo:String!,$number:Int!){
|
|
150
|
+
repository(owner:$org,name:$repo){
|
|
151
|
+
issue(number:$number){
|
|
152
|
+
subIssues(first: 100) {
|
|
153
|
+
nodes { number state }
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}' -F org=<org> -F repo=<repo> -F number=<number> 2>/dev/null)
|
|
158
|
+
|
|
159
|
+
# Count children still OPEN — a parent whose children are all closed is no longer
|
|
160
|
+
# holding open work and rolls up via lisa:github-read-issue's rollup, not here.
|
|
161
|
+
OPEN_CHILDREN=$(echo "$SUBS" | jq -r '[.data.repository.issue.subIssues.nodes[]? | select(.state == "OPEN")] | length' 2>/dev/null)
|
|
162
|
+
OPEN_CHILDREN=${OPEN_CHILDREN:-0}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
If the GraphQL `subIssues` field is unavailable (older GHES), fall back to parsing the body for child references exactly as `lisa:github-read-issue` does, and treat the issue as a container if any referenced child issue is open. Note "GraphQL sub-issues unavailable" so the operator knows parentage was text-derived.
|
|
166
|
+
|
|
167
|
+
Classify and act (first match wins). `type:` is read from the issue's labels (`type:Epic`, `type:Story`, `type:Spike`, `type:Bug`, `type:Task`, `type:Sub-task`, `type:Improvement`):
|
|
168
|
+
|
|
169
|
+
| Condition | Class | Action |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **Skip / safe-block — do NOT claim** |
|
|
172
|
+
| no open children AND `type ∈ {Epic, Story, Spike}` | **Childless container-type** | **Skip / safe-block — do NOT claim** |
|
|
173
|
+
| no open children AND `type ∈ {Bug, Task, Sub-task, Improvement}` (or no `type:` label) | **Leaf work unit** | **Proceed to 3b claim** |
|
|
174
|
+
|
|
175
|
+
The childless-parent exception is narrow: childlessness enables a claim **only** for types that are leaf work units to begin with. A childless Epic/Story/Spike is an incomplete decomposition, not an implementable unit — it is never claimed.
|
|
176
|
+
|
|
177
|
+
**Safe-block (default action for a flagged container).** Leave the build-ready role in place (don't silently strip it — that hides the lifecycle error), post a single lifecycle-repair comment, and record the issue under "Skipped (container)" in the summary. Do NOT relabel to `$CLAIMED`. Keep the comment idempotent — skip posting if an identical `[claude-build-intake]` lifecycle-repair comment already exists on the issue, so a re-entrant cycle doesn't spam it.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Not claimed: this issue carries the build-ready role ($READY) but is a container with open child work (or a childless Epic/Story/Spike), which violates the leaf-only-lifecycle rule. Build-ready is leaf-only — an agent claims and implements leaves, never a container. Repair: move $READY off this parent onto its leaf children (or, for a childless Epic/Story/Spike, decompose it into leaf children or reclassify it to a leaf type). A parent's lifecycle state rolls up from its children and is never set to ready directly."
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
This gate never blocks a legitimate flat Task/Bug: those have no open children and a leaf `type:`, so they fall straight through to the claim in 3b.
|
|
184
|
+
|
|
185
|
+
#### 3b. Claim
|
|
139
186
|
|
|
140
187
|
```bash
|
|
141
188
|
gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$CLAIMED"
|
|
@@ -146,7 +193,7 @@ This is the idempotency lock — a re-entrant cycle's `--label $READY` filter wi
|
|
|
146
193
|
|
|
147
194
|
If the relabel fails (permission, race), log under "Errors" in the cycle summary and skip this issue. **Do not invoke the build flow on an issue you didn't successfully claim.**
|
|
148
195
|
|
|
149
|
-
####
|
|
196
|
+
#### 3c. Run the build flow
|
|
150
197
|
|
|
151
198
|
Invoke `lisa:github-agent` (the per-issue lifecycle agent) with the issue ref. `lisa:github-agent` owns:
|
|
152
199
|
- Reading the full issue graph (`lisa:github-read-issue`)
|
|
@@ -163,7 +210,7 @@ Wait for `lisa:github-agent` to return. Capture its outcome:
|
|
|
163
210
|
- **Blocked by ticket-triage ambiguities** — `lisa:github-agent` posts findings and stops. The issue stays in `$CLAIMED`. Surface to human; do not auto-relabel. Record under "Errors".
|
|
164
211
|
- **Errored** — exception, missing config, etc. Leave the issue in `$CLAIMED` for human investigation. Record under "Errors".
|
|
165
212
|
|
|
166
|
-
####
|
|
213
|
+
#### 3d. Transition to $DONE (only on Success)
|
|
167
214
|
|
|
168
215
|
If `lisa:github-agent` returned Success:
|
|
169
216
|
|
|
@@ -176,7 +223,7 @@ gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Buil
|
|
|
176
223
|
|
|
177
224
|
For any non-Success outcome, do NOT transition. The issue sits in `$CLAIMED` (or wherever `lisa:github-agent` left it) — humans take it from there.
|
|
178
225
|
|
|
179
|
-
####
|
|
226
|
+
#### 3e. Continue
|
|
180
227
|
|
|
181
228
|
Move to the next ready issue. One issue failing does not stop others.
|
|
182
229
|
|
|
@@ -192,6 +239,8 @@ Cycle completed: <ISO timestamp>
|
|
|
192
239
|
Issues processed: <n>
|
|
193
240
|
- $DONE (build complete, PR ready): <n>
|
|
194
241
|
- <org>/<repo>#<number> <title> → PR <URL>
|
|
242
|
+
- Skipped (container — leaf-only-lifecycle): <n>
|
|
243
|
+
- <org>/<repo>#<number> <title> — build-ready on a parent with open child work; lifecycle-repair comment posted
|
|
195
244
|
- Blocked (pre-flight verify failed): <n>
|
|
196
245
|
- <org>/<repo>#<number> <title> — see issue comments
|
|
197
246
|
- Held (triage found ambiguities): <n>
|
|
@@ -204,6 +253,7 @@ Total PRs opened: <n>
|
|
|
204
253
|
|
|
205
254
|
## Idempotency & safety
|
|
206
255
|
|
|
256
|
+
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic/Story/Spike) is skipped/safe-blocked, never claimed. The safe-block comment is idempotent — a re-entrant cycle does not re-post it.
|
|
207
257
|
- **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:github-agent` invocation — no double-pickup.
|
|
208
258
|
- **No writes outside the lifecycle**: this skill only relabels `$READY → $CLAIMED` and `$CLAIMED → $DONE`. Every other label change is owned by `lisa:github-agent`.
|
|
209
259
|
- **Failure isolation**: per-issue exceptions caught and recorded; the cycle continues.
|
|
@@ -227,6 +277,7 @@ If the repo has not adopted the `status:*` label namespace, this skill cannot ru
|
|
|
227
277
|
|
|
228
278
|
## Rules
|
|
229
279
|
|
|
280
|
+
- **Claim leaves only.** Per the `leaf-only-lifecycle` rule, never claim a container — an issue with open child work, or a childless Epic/Story/Spike — even if it carries the build-ready role. Skip or safe-block it (Phase 3a); never silently implement a container.
|
|
230
281
|
- Never relabel an issue the cycle didn't claim. The `$CLAIMED` label is the signature of cycle ownership.
|
|
231
282
|
- Never bypass `lisa:github-agent` to do build work directly. `lisa:github-agent` owns the per-issue lifecycle.
|
|
232
283
|
- Never auto-transition past `$DONE`. Downstream labels (terminal `status:done`, etc.) are owned by QA / PM / merge automation.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lisa-openclaw",
|
|
3
|
+
"version": "2.31.0",
|
|
4
|
+
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Cody Swann"
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lisa-openclaw",
|
|
3
|
+
"version": "2.31.0",
|
|
4
|
+
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Cody Swann"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"openclaw",
|
|
10
|
+
"telegram",
|
|
11
|
+
"slack",
|
|
12
|
+
"agents",
|
|
13
|
+
"chat-ops"
|
|
14
|
+
],
|
|
15
|
+
"skills": "./skills/",
|
|
16
|
+
"interface": {
|
|
17
|
+
"displayName": "Lisa OpenClaw",
|
|
18
|
+
"shortDescription": "Staff on Telegram/Slack via OpenClaw",
|
|
19
|
+
"longDescription": "Wire staff roles to human chat surfaces through OpenClaw: set up the gateway prerequisites, connect a facilitator (chief of staff) and its specialists on Telegram or Slack with hub-and-spoke routing, and bind Telegram forum topics to dispatcher+worker pairs for repo-coding work. Distributed for both Claude Code and Codex.",
|
|
20
|
+
"developerName": "Cody Swann",
|
|
21
|
+
"category": "Productivity",
|
|
22
|
+
"capabilities": [
|
|
23
|
+
"Interactive",
|
|
24
|
+
"Write"
|
|
25
|
+
],
|
|
26
|
+
"defaultPrompt": [
|
|
27
|
+
"Set up OpenClaw for this project",
|
|
28
|
+
"Connect my chief of staff to Telegram",
|
|
29
|
+
"Connect staff to Slack via OpenClaw"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Bind a Telegram forum topic to an OpenClaw dispatcher+worker pair that runs a coding CLI against a repo (single-repo or folder-scoped), so you can drive code work from chat. Requires /lisa:setup-openclaw first."
|
|
3
|
+
argument-hint: "<admin|developer> <single-repo|folder-scoped> <topic name> <workspace path>"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use the lisa-openclaw-connect-repo-topic skill to provision or update a Telegram repo-coding topic
|
|
7
|
+
(dispatcher + worker pair) and wire it in OpenClaw. $ARGUMENTS
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Connect staff roles to Slack via OpenClaw using a facilitator/specialist hub-and-spoke model — register the app, create/reuse the facilitator channel, wire routes, validate, and run an end-to-end route test. Requires /lisa:setup-openclaw first."
|
|
3
|
+
argument-hint: "<facilitator role + specialists, e.g. Chief of Staff with Legal, Finance, Sales>"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use the lisa-openclaw-connect-staff skill with platform `slack`. Connect the named facilitator and
|
|
7
|
+
specialists to a Slack facilitator channel via OpenClaw. $ARGUMENTS
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Connect staff roles to Telegram via OpenClaw using a facilitator/specialist hub-and-spoke model — register bots, create/reuse the facilitator topic, wire routes, validate, and run an end-to-end route test. Requires /lisa:setup-openclaw first."
|
|
3
|
+
argument-hint: "<facilitator role + specialists, e.g. Chief of Staff with Legal, Finance, Sales>"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use the lisa-openclaw-connect-staff skill with platform `telegram`. Connect the named facilitator and
|
|
7
|
+
specialists to a Telegram facilitator topic via OpenClaw. $ARGUMENTS
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up OpenClaw as the chat-surface runtime for this project's staff. Verifies the openclaw CLI, ~/.openclaw/openclaw.json, a secret provider, and required gateway capabilities, then writes a lean `openclaw` section to .lisa.config.json. Run before connect-staff / connect-repo-topic."
|
|
3
|
+
argument-hint: "[telegram|slack]"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Use the lisa-openclaw-setup skill to verify OpenClaw prerequisites and write the lean `openclaw`
|
|
7
|
+
section to .lisa.config.json. If a platform is given, use it as the defaultPlatform. $ARGUMENTS
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lisa-openclaw-connect-repo-topic
|
|
3
|
+
description: Bind a Telegram forum topic to an OpenClaw dispatcher+worker agent pair that runs a coding CLI against a repo, so you can drive code work from chat. Supports single-repo topics and folder-scoped topics (multiple repos with repo-confirmation). Creates/validates the agent pair, ensures the bot is a group admin, captures real group/topic ids, wires the route in ~/.openclaw/openclaw.json, validates the gateway, and runs a no-change self-test. Requires lisa-openclaw-setup first.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# lisa-openclaw-connect-repo-topic
|
|
7
|
+
|
|
8
|
+
Turn a Telegram forum topic into a repeatable OpenClaw entrypoint for code work. A **dispatcher**
|
|
9
|
+
agent receives the request and delegates; a **worker** agent runs the local coding CLI in a safe
|
|
10
|
+
target directory and relays the result.
|
|
11
|
+
|
|
12
|
+
This SKILL.md is complete and runnable under both Claude Code and Codex (no command/`$ARGUMENTS`
|
|
13
|
+
layer in Codex). Keep real ids/handles/paths out of committed files — they go only in
|
|
14
|
+
`~/.openclaw/openclaw.json`. For exact config shapes read
|
|
15
|
+
[references/repo-topic-config.md](references/repo-topic-config.md).
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- `lisa-openclaw-setup` has run and its capability probes passed.
|
|
20
|
+
- A Telegram supergroup with forum topics, and a bot that is (or can be promoted to) a **group
|
|
21
|
+
admin** — bot presence alone is not enough for topic routing.
|
|
22
|
+
|
|
23
|
+
## Boundaries (apply every time)
|
|
24
|
+
|
|
25
|
+
- groups = the human trust boundary
|
|
26
|
+
- topics = the project-routing boundary
|
|
27
|
+
- native-reply roots = the short-term session boundary inside a topic
|
|
28
|
+
- agents = the capability boundary
|
|
29
|
+
- Do not mix admin-only repos with broader-collaboration repos in one group. If two repos need
|
|
30
|
+
different member lists, use separate groups, not topic-only separation.
|
|
31
|
+
|
|
32
|
+
## Scope modes (pick exactly one per topic)
|
|
33
|
+
|
|
34
|
+
- **`single-repo`** — the topic is pinned to one repo directory; the dispatcher never asks which repo.
|
|
35
|
+
- **`folder-scoped`** — the topic is pinned to a parent folder containing multiple repos; the
|
|
36
|
+
dispatcher must confirm the inferred repo(s) unless the user named them explicitly.
|
|
37
|
+
|
|
38
|
+
Do not mix both behaviors in one topic.
|
|
39
|
+
|
|
40
|
+
## Required inputs
|
|
41
|
+
|
|
42
|
+
- trust boundary: `admin` or `developer`
|
|
43
|
+
- scope mode: `single-repo` or `folder-scoped`
|
|
44
|
+
- access surface: Telegram group + topic (by name; ids captured during the run)
|
|
45
|
+
- the bot handle to bind
|
|
46
|
+
- workspace root on disk (repo dir for single-repo; parent folder for folder-scoped)
|
|
47
|
+
- allowed Telegram user ids
|
|
48
|
+
- completion policy:
|
|
49
|
+
- `admin` topics may request change + docs + commit + PR + merge
|
|
50
|
+
- `developer` topics default to change + docs + commit + PR only
|
|
51
|
+
- for `folder-scoped`: a repo catalog (label, absolute path, a few matching keyword hints)
|
|
52
|
+
|
|
53
|
+
## Workflow
|
|
54
|
+
|
|
55
|
+
### 1. Resolve the contract
|
|
56
|
+
|
|
57
|
+
Confirm the trust boundary, scope mode, workspace root, bot handle, and (for folder-scoped) the repo
|
|
58
|
+
catalog. If a needed agent doesn't exist yet, create it in step 3.
|
|
59
|
+
|
|
60
|
+
### 2. Provision / reuse the Telegram surface
|
|
61
|
+
|
|
62
|
+
Reuse the trust-matched group and the exact topic if they already exist; otherwise create them (enable
|
|
63
|
+
forum/topics mode first). Ensure the bot is in the group and **promoted to admin**. Telegram Bot API
|
|
64
|
+
cannot list groups by name — discover ids from a logged-in Telegram client, an existing route in
|
|
65
|
+
`~/.openclaw/openclaw.json`, or a received Bot API update. If browser/UI automation blocks on a human
|
|
66
|
+
confirmation step, give the user only the blocked step, wait, then resume.
|
|
67
|
+
|
|
68
|
+
### 3. Implement the dispatcher + worker pair
|
|
69
|
+
|
|
70
|
+
Create or update two agents (exact tool-deny shapes in
|
|
71
|
+
[references/repo-topic-config.md](references/repo-topic-config.md)):
|
|
72
|
+
|
|
73
|
+
- **`<topic-slug>-dispatch`** — skill-aware entrypoint; tools restricted to delegation/session tools
|
|
74
|
+
(+ optional `read`); denies file writes, shell/exec, browser, gateway, automation; may delegate
|
|
75
|
+
only to `<topic-slug>-codex`.
|
|
76
|
+
- **`<topic-slug>-codex`** — restricted worker; keeps `read` + `exec`; denies session spawning,
|
|
77
|
+
browser, gateway, and direct file-write tools; runs the local coding CLI for the actual work.
|
|
78
|
+
|
|
79
|
+
### 4. Repo-selection behavior
|
|
80
|
+
|
|
81
|
+
- `single-repo`: treat the repo as decided; pass the fixed repo path to the worker; never ask.
|
|
82
|
+
- `folder-scoped`: infer candidates from the catalog. If the user named repo(s) explicitly, skip
|
|
83
|
+
confirmation; otherwise ask before spawning:
|
|
84
|
+
- one likely repo: `This looks like <repo>. Is that correct?`
|
|
85
|
+
- multiple: `This may belong to <repo-1> or <repo-2>. Is that correct, or which repo(s)?`
|
|
86
|
+
On confirmation of multiple repos, spawn one worker run per repo (or ask the user to split a
|
|
87
|
+
too-coupled change). Never skip confirmation in folder-scoped mode unless selection was explicit.
|
|
88
|
+
|
|
89
|
+
### 5. Worker safety contract
|
|
90
|
+
|
|
91
|
+
Every worker task receives an explicit repo path and:
|
|
92
|
+
|
|
93
|
+
1. inspects `git status --short --branch` in the selected repo
|
|
94
|
+
2. if the primary checkout is dirty or already on a feature branch, creates a temporary worktree from
|
|
95
|
+
`main` under `/tmp`
|
|
96
|
+
3. trusts local tool config in a fresh worktree if required (e.g. `mise trust <target_dir>`)
|
|
97
|
+
4. runs the coding CLI in the foreground in the target directory
|
|
98
|
+
5. cleans up the temporary worktree after success when safe
|
|
99
|
+
|
|
100
|
+
The worker prepares the safe target and launches the CLI; it does not edit files directly.
|
|
101
|
+
|
|
102
|
+
### 6. Bind the topic
|
|
103
|
+
|
|
104
|
+
Route the topic to the dispatcher: set
|
|
105
|
+
`channels.telegram.groups.<group-id>.topics.<topic-id>.agentId = <topic-slug>-dispatch`, keep
|
|
106
|
+
`requireMention = true` and allowlist policy, and add `allowFrom` only when membership must be
|
|
107
|
+
narrower than the group. The topic `systemPrompt` must state the scope mode, treat each native-reply
|
|
108
|
+
root as an independent request context, confirm repo selection only in folder-scoped mode, spawn the
|
|
109
|
+
worker with an explicit repo path, and return the worker result to the topic. Back up
|
|
110
|
+
`~/.openclaw/openclaw.json` before editing and preserve unrelated routes.
|
|
111
|
+
|
|
112
|
+
### 7. Validate + self-test
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
openclaw config validate
|
|
116
|
+
openclaw gateway restart
|
|
117
|
+
openclaw gateway status
|
|
118
|
+
openclaw channels status --probe
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Then from the target topic: mention the bot and ask for an exact-token reply with **no** file
|
|
122
|
+
changes, commits, PRs, or merges, e.g. `<bot-handle> reply with exactly TELEGRAM-ROUTE-OK`. Confirm
|
|
123
|
+
the visible reply, that the dispatcher spawned the worker, and that the worker ran in the intended
|
|
124
|
+
repo. For folder-scoped topics, also send a request that implies but doesn't name a repo and confirm
|
|
125
|
+
the dispatcher asks for confirmation before proceeding. Do **not** treat `openclaw agent --agent
|
|
126
|
+
<id> ...` as proof a topic route works — use the visible topic reply.
|
|
127
|
+
|
|
128
|
+
## Output standard
|
|
129
|
+
|
|
130
|
+
Finish with: group id + topic id used; scope mode; workspace root and repo path or catalog;
|
|
131
|
+
dispatcher + worker agent ids; whether the bot is confirmed group admin; validation results; whether
|
|
132
|
+
the self-test passed; and any remaining manual follow-up or trust caveat.
|
|
133
|
+
|
|
134
|
+
## Related
|
|
135
|
+
|
|
136
|
+
`lisa-openclaw-setup` (run first), `lisa-openclaw-connect-staff` (facilitator/specialist staff on
|
|
137
|
+
Telegram or Slack).
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Repo-coding topic config shapes
|
|
2
|
+
|
|
3
|
+
Placeholder-only. Real ids/paths/handles go only into `~/.openclaw/openclaw.json` (machine-local,
|
|
4
|
+
never committed). Back up that file before editing; change only the intended keys.
|
|
5
|
+
|
|
6
|
+
## Trust model
|
|
7
|
+
|
|
8
|
+
- `admin` group: highly trusted people; machine-config/infra repos allowed; topics may request merge
|
|
9
|
+
after PR.
|
|
10
|
+
- `developer` group: broader collaborators; topics stop at change + docs + commit + PR unless
|
|
11
|
+
explicitly raised.
|
|
12
|
+
|
|
13
|
+
If two repos need different member lists, use different groups even if both are `developer`.
|
|
14
|
+
|
|
15
|
+
## Folder-scoped repo catalog
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
repos:
|
|
19
|
+
- name: repo-1
|
|
20
|
+
path: /absolute/path/to/repo-1
|
|
21
|
+
hints: [billing, invoices]
|
|
22
|
+
- name: repo-2
|
|
23
|
+
path: /absolute/path/to/repo-2
|
|
24
|
+
hints: [login, mobile-app]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Naming
|
|
28
|
+
|
|
29
|
+
- topic slug: derived from the topic purpose or workspace name
|
|
30
|
+
- dispatcher agent id: `<topic-slug>-dispatch`
|
|
31
|
+
- worker agent id: `<topic-slug>-codex`
|
|
32
|
+
|
|
33
|
+
## Dispatcher agent
|
|
34
|
+
|
|
35
|
+
```json5
|
|
36
|
+
{
|
|
37
|
+
"id": "<topic-slug>-dispatch",
|
|
38
|
+
"workspace": "/absolute/path/to/repo-or-parent",
|
|
39
|
+
"skills": ["acp-router"],
|
|
40
|
+
"subagents": { "allowAgents": ["<topic-slug>-codex"] },
|
|
41
|
+
"tools": {
|
|
42
|
+
"profile": "coding",
|
|
43
|
+
"deny": [
|
|
44
|
+
"group:ui", "group:automation", "group:nodes",
|
|
45
|
+
"bash", "exec", "process", "browser", "canvas", "cron",
|
|
46
|
+
"gateway", "write", "edit", "apply_patch"
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"elevated": { "enabled": false }
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Worker agent
|
|
54
|
+
|
|
55
|
+
```json5
|
|
56
|
+
{
|
|
57
|
+
"id": "<topic-slug>-codex",
|
|
58
|
+
"workspace": "/absolute/path/to/repo-or-parent",
|
|
59
|
+
"tools": {
|
|
60
|
+
"profile": "coding",
|
|
61
|
+
"deny": [
|
|
62
|
+
"group:ui", "group:automation", "group:nodes", "group:sessions",
|
|
63
|
+
"subagents", "process", "browser", "canvas", "cron",
|
|
64
|
+
"gateway", "write", "edit", "apply_patch"
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
"elevated": { "enabled": false }
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Topic route
|
|
72
|
+
|
|
73
|
+
```json5
|
|
74
|
+
{
|
|
75
|
+
"channels": {
|
|
76
|
+
"telegram": {
|
|
77
|
+
"groups": {
|
|
78
|
+
"<group-id>": {
|
|
79
|
+
"groupPolicy": "allowlist",
|
|
80
|
+
"requireMention": true,
|
|
81
|
+
"allowFrom": ["<telegram-user-id>"],
|
|
82
|
+
"topics": {
|
|
83
|
+
"<topic-id>": {
|
|
84
|
+
"agentId": "<topic-slug>-dispatch",
|
|
85
|
+
"requireMention": true,
|
|
86
|
+
"systemPrompt": "Use the topic's configured scope mode. For single-repo, pass the fixed repo path to <topic-slug>-codex. For folder-scoped, confirm the inferred repo or repo set unless the user already named it explicitly, then pass the explicit repo path(s) to <topic-slug>-codex. Treat each native reply root as an independent request context."
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Worker launcher form
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
PATH="$HOME/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin" \
|
|
100
|
+
"$HOME/bin/<coding-cli>" exec -C <target_dir> "<prompt>"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Id rules
|
|
104
|
+
|
|
105
|
+
- Telegram Bot API `chat_id` for a supergroup is the full signed id (usually starts `-100`); the short
|
|
106
|
+
positive number is not a valid substitute.
|
|
107
|
+
- Topic id is the Telegram `message_thread_id`.
|
|
108
|
+
- Discover ids from a logged-in Telegram client, an existing route in `~/.openclaw/openclaw.json`, or a
|
|
109
|
+
received Bot API update — the Bot API cannot list groups by name.
|