@codyswann/lisa 2.30.0 → 2.32.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 (52) hide show
  1. package/.agents/plugins/marketplace.json +24 -0
  2. package/.claude-plugin/marketplace.json +6 -0
  3. package/package.json +1 -1
  4. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  5. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  6. package/plugins/lisa/skills/github-sync/SKILL.md +48 -2
  7. package/plugins/lisa/skills/jira-sync/SKILL.md +27 -1
  8. package/plugins/lisa/skills/linear-sync/SKILL.md +27 -2
  9. package/plugins/lisa/skills/tracker-sync/SKILL.md +23 -0
  10. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  11. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  12. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  14. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  16. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  18. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +8 -0
  19. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +32 -0
  20. package/plugins/lisa-openclaw/commands/connect-repo-topic.md +7 -0
  21. package/plugins/lisa-openclaw/commands/connect-staff-slack.md +7 -0
  22. package/plugins/lisa-openclaw/commands/connect-staff-telegram.md +7 -0
  23. package/plugins/lisa-openclaw/commands/setup-openclaw.md +7 -0
  24. package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-repo-topic/SKILL.md +137 -0
  25. package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-repo-topic/references/repo-topic-config.md +109 -0
  26. package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-staff/SKILL.md +175 -0
  27. package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-staff/references/platform-routing.md +83 -0
  28. package/plugins/lisa-openclaw/skills/lisa-openclaw-connect-staff/references/prompts.md +78 -0
  29. package/plugins/lisa-openclaw/skills/lisa-openclaw-setup/SKILL.md +138 -0
  30. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  34. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  36. package/plugins/src/base/skills/github-sync/SKILL.md +48 -2
  37. package/plugins/src/base/skills/jira-sync/SKILL.md +27 -1
  38. package/plugins/src/base/skills/linear-sync/SKILL.md +27 -2
  39. package/plugins/src/base/skills/tracker-sync/SKILL.md +23 -0
  40. package/plugins/src/openclaw/.claude-plugin/plugin.json +6 -0
  41. package/plugins/src/openclaw/commands/connect-repo-topic.md +7 -0
  42. package/plugins/src/openclaw/commands/connect-staff-slack.md +7 -0
  43. package/plugins/src/openclaw/commands/connect-staff-telegram.md +7 -0
  44. package/plugins/src/openclaw/commands/setup-openclaw.md +7 -0
  45. package/plugins/src/openclaw/skills/lisa-openclaw-connect-repo-topic/SKILL.md +137 -0
  46. package/plugins/src/openclaw/skills/lisa-openclaw-connect-repo-topic/references/repo-topic-config.md +109 -0
  47. package/plugins/src/openclaw/skills/lisa-openclaw-connect-staff/SKILL.md +175 -0
  48. package/plugins/src/openclaw/skills/lisa-openclaw-connect-staff/references/platform-routing.md +83 -0
  49. package/plugins/src/openclaw/skills/lisa-openclaw-connect-staff/references/prompts.md +78 -0
  50. package/plugins/src/openclaw/skills/lisa-openclaw-setup/SKILL.md +138 -0
  51. package/scripts/build-plugins.sh +1 -1
  52. 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.30.0",
85
+ "version": "2.32.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": "lisa",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -62,11 +62,57 @@ Based on the milestone, suggest (but do NOT automatically perform) a label trans
62
62
 
63
63
  The actual `status:in-progress` flip is owned by `lisa:github-build-intake` (claim) and `lisa:github-agent`. The `status:code-review` flip is owned by `lisa:github-evidence`. The `status:done` flip is typically owned by merge automation or PM. This skill never relabels.
64
64
 
65
+ ### Step 5: Parent Status Rollup (`--rollup`)
66
+
67
+ When invoked with `--rollup`, this skill **derives a parent/container issue's `status:*` label from the roll-up of its child sub-issues** instead of posting a milestone update on a leaf. This implements the GitHub sub-issue-completion arm of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy. It is the sync-side complement to the write-time labeling (`lisa:github-write-issue`), the validate-time S15 gate (`lisa:github-validate-issue`), and the claim-time gate (`lisa:github-build-intake`); all four cite the same rule so the classification never drifts.
68
+
69
+ **Resolve the child set the same way `lisa:github-read-issue` does** — native sub-issues via GraphQL, each with its `status:*` label and open/closed state:
70
+
71
+ ```bash
72
+ gh api graphql -f query='
73
+ query($owner:String!,$repo:String!,$number:Int!){
74
+ repository(owner:$owner,name:$repo){
75
+ issue(number:$number){
76
+ number title state
77
+ subIssues(first:100){ nodes { number state labels(first:20){ nodes { name } } } }
78
+ }
79
+ }
80
+ }' -F owner=<org> -F repo=<repo> -F number=<parent-number>
81
+ ```
82
+
83
+ If the `subIssues` field is unavailable (older GHES), fall back to body parentage exactly as `lisa:github-read-issue` does. If the issue has **no** children it is a leaf, not a parent — rollup is N/A; behave as a normal milestone sync.
84
+
85
+ **Evaluate the required children in priority order and take the first match** (canonical roles from `config-resolution`; the GitHub label map is `status:blocked`, `status:in-progress`, `status:code-review`, `status:done`):
86
+
87
+ | If among the required child leaves… | Derived parent role | GitHub label |
88
+ |---|---|---|
89
+ | any child carries `status:blocked` (or is otherwise blocked) | `blocked` | `status:blocked` |
90
+ | else any child carries `status:in-progress` **or** `status:code-review` | `claimed` | `status:in-progress` |
91
+ | else **all** required children are terminal (closed / `status:done`) | `done` | the configured terminal `done` label |
92
+ | else (children exist, none started) | — | unchanged — parent keeps its non-ready container label |
93
+
94
+ - **Blocked dominates** — a single blocked child surfaces `status:blocked` on the parent even while siblings progress, so a human sees the parent needs attention.
95
+ - **"Required" children only** — a child labelled won't-do / optional does not hold the parent open; only leaves that must ship count toward the all-terminal check.
96
+ - **Recursive** — a parent reaches `done` only when its children are all terminal; an Epic reaches `done` only when its Stories have themselves rolled up to `done`. Evaluate bottom-up.
97
+ - **Never set the parent to `status:ready`** — `ready` is leaf-only (the human "claim this" signal). Rollup only moves the parent between non-ready container labels.
98
+
99
+ **Single-environment collapse (this repo).** `.lisa.config.json` `deploy.branches` declares only `production: main`, so the terminal `done` resolves to the single label `status:done` — there is no `status:on-dev` / `status:on-stg` and **no dev → staging → prod promotion chain**. Resolve the terminal via the env-keyed `done` logic in `config-resolution`, but in the single-environment case it collapses to the one `status:done` value; the rollup never attempts to resolve a dev or staging `done`. Projects that DO have multiple environments keep the env-keyed map and roll the parent up to whichever `done` matches the environment its leaves shipped to.
100
+
101
+ **Apply the derived label** (only when it differs from the parent's current `status:*`): remove the parent's existing `status:*` label and add the derived one, keeping exactly one `status:*` label so the build-queue invariant holds. Post an idempotent `[claude-sync] rollup` comment naming the derived state and the child tally (e.g. `3/4 leaves terminal, 1 blocked → status:blocked`); skip the comment if an identical one is already the most recent rollup comment.
102
+
103
+ ```bash
104
+ gh issue edit <parent-number> --repo <org>/<repo> \
105
+ --remove-label "<current status:*>" --add-label "<derived status:*>"
106
+ ```
107
+
108
+ **Safe default.** If rollup cannot be applied automatically (e.g. ambiguous required-set, GraphQL hierarchy unavailable, or a derived terminal that the env logic cannot resolve), this skill does **not** guess — it posts the derived suggestion as a comment and leaves the parent's label untouched. No unsafe transition is ever made.
109
+
65
110
  ## Important Notes
66
111
 
67
- - **Never auto-transition labels** — always suggest and let the user / pipeline confirm.
68
- - **Idempotent updates** — the `[claude-sync] <milestone>` prefix on the most-recent comment is the dedupe key.
112
+ - **Never auto-transition labels** — always suggest and let the user / pipeline confirm. The one exception is the explicit `--rollup` parent derivation (Step 5), which moves a *parent's* `status:*` label as the `leaf-only-lifecycle` rule mandates — never a leaf's, and never to `status:ready`.
113
+ - **Idempotent updates** — the `[claude-sync] <milestone>` prefix on the most-recent comment is the dedupe key; the rollup path uses `[claude-sync] rollup`.
69
114
  - **Comment format** — use GitHub-flavored markdown (`##` headings, fenced code blocks). The same template is used for the JIRA path (rendered as wiki markup there); keep the markdown source canonical.
115
+ - **Rollup cites the rule by slug** — parent state derivation follows the `leaf-only-lifecycle` rule's state machine; this skill does not restate the policy.
70
116
 
71
117
  ## Execution
72
118
 
@@ -58,11 +58,37 @@ Based on the milestone, suggest (but don't automatically perform) a status trans
58
58
  | PR ready | "In Review" |
59
59
  | PR merged | "Done" |
60
60
 
61
+ ### Step 5: Parent Status Rollup (`--rollup`)
62
+
63
+ When invoked with `--rollup`, this skill **derives a parent/container ticket's status from the roll-up of its children** (Stories under an Epic; Sub-tasks under a Story/Task) instead of posting a milestone update on a leaf. This implements the JIRA child/subtask-status arm of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy.
64
+
65
+ **Resolve the child set the same way `lisa:jira-read-ticket` does** — the native Epic → Story → Sub-task hierarchy (Epic link / parent field for Stories, the subtask relationship for Sub-tasks), each with its current status. Fetch via `lisa:atlassian-access` (`operation: read-ticket` / `search-issues` with the parent's `"Epic Link" = <KEY>` or `parent = <KEY>` JQL). If the ticket has **no** children it is a leaf — rollup is N/A; behave as a normal milestone sync.
66
+
67
+ **Evaluate the required children in priority order and take the first match** (canonical roles from `config-resolution`; the JIRA status map defaults to `Blocked`, `In Progress`, `Code Review`, env-keyed `done`):
68
+
69
+ | If among the required child leaves… | Derived parent role | JIRA status |
70
+ |---|---|---|
71
+ | any child is **blocked** | `blocked` | `Blocked` |
72
+ | else any child is **in progress** (`In Progress` or `Code Review`) | `claimed` | `In Progress` |
73
+ | else **all** required children are terminal (`Done`) | `done` | the configured terminal `done` status |
74
+ | else (children exist, none started) | — | unchanged — parent keeps its non-ready container status |
75
+
76
+ - **Blocked dominates** — a single blocked child surfaces `Blocked` on the parent even while siblings progress.
77
+ - **"Required" children only** — won't-do / optional children do not hold the parent open.
78
+ - **Recursive** — an Epic reaches `Done` only when its Stories have themselves rolled up to `Done`; a Story reaches `Done` only when its Sub-tasks are all terminal. Evaluate bottom-up.
79
+ - **Never set the parent to the build-ready status** — `ready` is leaf-only. Rollup only moves the parent between non-ready container statuses.
80
+ - **`review` is optional for JIRA** (`config-resolution`) — a project that omits `Code Review` keeps the parent in `In Progress` until terminal; skip the intermediate rollup hop rather than forcing a non-existent status (a `leaf-only-lifecycle` "vendor support varies" note).
81
+
82
+ **Single-environment collapse (this repo).** The terminal `done` resolves via the env-keyed `done` logic in `config-resolution`. In this repo `deploy.branches` declares only `production: main`, so `done` collapses to a single status and the lifecycle is `Ready → In Progress → Code Review → Done` with **no** dev/staging promotion hops; the rollup never resolves a dev or staging `done`. Multi-environment projects keep the env-keyed map.
83
+
84
+ **Apply the derived status** (only when it differs from the parent's current status) via `lisa:atlassian-access` `operation: transition`, and post an idempotent rollup comment naming the derived state and the child tally. **Safe default:** if the derived terminal cannot be resolved (ambiguous required-set or unresolvable env `done`), do not guess — post the derived suggestion as a comment and leave the parent's status untouched.
85
+
61
86
  ## Important Notes
62
87
 
63
- - **Never auto-transition ticket status** — always suggest and let the user confirm
88
+ - **Never auto-transition ticket status** — always suggest and let the user confirm. The one exception is the explicit `--rollup` parent derivation (Step 5), which transitions a *parent's* status per the `leaf-only-lifecycle` rule — never a leaf's, and never to the build-ready status.
64
89
  - **Idempotent updates** — running sync multiple times at the same milestone should not create duplicate comments
65
90
  - **Comment format** — use JIRA markdown with clear headers and bullet points
91
+ - **Rollup cites the rule by slug** — parent state derivation follows the `leaf-only-lifecycle` rule's state machine; this skill does not restate the policy.
66
92
 
67
93
  ## Execution
68
94
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: linear-sync
3
3
  description: "Syncs plan progress to a linked Linear Issue. Posts plan contents, progress updates, branch links, and PR links at key milestones. Use this skill throughout the plan lifecycle to keep Linear Issues in sync. The Linear counterpart of lisa:jira-sync and lisa:github-sync."
4
- allowed-tools: ["Bash", "Skill", "mcp__linear-server__list_teams", "mcp__linear-server__get_issue", "mcp__linear-server__save_comment", "mcp__linear-server__list_issue_labels", "mcp__linear-server__create_issue_label", "mcp__linear-server__save_issue"]
4
+ allowed-tools: ["Bash", "Skill", "mcp__linear-server__list_teams", "mcp__linear-server__get_issue", "mcp__linear-server__list_issues", "mcp__linear-server__save_comment", "mcp__linear-server__list_issue_labels", "mcp__linear-server__create_issue_label", "mcp__linear-server__save_issue"]
5
5
  ---
6
6
 
7
7
  # Sync Plan to Linear: $ARGUMENTS
@@ -81,9 +81,34 @@ Verify exactly one `status:*` label remains after the update — having two simu
81
81
 
82
82
  Without `--update-label`, this skill posts the comment only and does NOT touch labels.
83
83
 
84
+ ## Phase 5 — Parent Status Rollup (`--rollup`)
85
+
86
+ When the caller passes `--rollup`, this skill **derives a parent/container's `status:*` label from the roll-up of its children** instead of acting on a leaf. A **Project** (the Epic equivalent) rolls up from its Issues; an **Issue** rolls up from its sub-Issues. This implements the Linear child-issue-status arm of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy.
87
+
88
+ **Resolve the child set the same way `lisa:linear-read-issue` does** — `mcp__linear-server__list_issues({project: <id>})` for a Project's Issues, or `mcp__linear-server__get_issue` per child for an Issue's sub-Issues (via `parentId`). Capture each child's `status:*` label. If the item has **no** children it is a leaf — rollup is N/A; behave as a normal milestone sync.
89
+
90
+ **Evaluate the required children in priority order and take the first match** (canonical roles from `config-resolution`; Linear label map is `status:blocked`, `status:in-progress`, `status:code-review`, `status:done`):
91
+
92
+ | If among the required child leaves… | Derived parent role | Linear label |
93
+ |---|---|---|
94
+ | any child carries `status:blocked` | `blocked` | `status:blocked` |
95
+ | else any child carries `status:in-progress` **or** `status:code-review` | `claimed` | `status:in-progress` |
96
+ | else **all** required children carry `status:done` | `done` | the configured terminal `done` label |
97
+ | else (children exist, none started) | — | unchanged — parent keeps its non-ready container label |
98
+
99
+ - **Blocked dominates** — one blocked child surfaces `status:blocked` on the parent even while siblings progress.
100
+ - **"Required" children only** — won't-do / optional (e.g. `Canceled`) children do not hold the parent open.
101
+ - **Recursive** — a Project reaches `status:done` only when its Issues have themselves rolled up to `status:done`. Evaluate bottom-up.
102
+ - **Never set the parent to `status:ready`** — `ready` is leaf-only. Rollup only moves the parent between non-ready container labels.
103
+
104
+ **Single-environment collapse (this repo).** The terminal `done` resolves via the env-keyed `done` logic in `config-resolution`. In this repo `deploy.branches` declares only `production: main`, so `done` collapses to the single `status:done` label and the lifecycle is `status:ready → status:in-progress → status:code-review → status:done` with **no** dev/staging promotion hops; the rollup never resolves a dev or staging `done`. Multi-environment projects keep the env-keyed map.
105
+
106
+ **Apply the derived label** via `mcp__linear-server__save_issue` (Project or Issue), removing the parent's existing `status:*` and adding the derived one so exactly one `status:*` label remains. Post an idempotent rollup comment naming the derived state and the child tally. The native Linear `state` is **not** auto-transitioned — only the `status:*` label, mirroring the `--update-label` rule. **Safe default:** if the derived terminal cannot be resolved (ambiguous required-set or unresolvable env `done`), do not guess — post the derived suggestion as a comment and leave the parent's label untouched.
107
+
84
108
  ## Rules
85
109
 
86
- - Never auto-transition the native Linear `state` — only the label, and only when the caller explicitly asks.
110
+ - Never auto-transition the native Linear `state` — only the label, and only when the caller explicitly asks (`--update-label`, or `--rollup` for parent derivation per the `leaf-only-lifecycle` rule).
111
+ - Rollup derives a *parent's* `status:*` label from its children and never sets a parent to `status:ready`. It cites the `leaf-only-lifecycle` rule by slug rather than restating the state machine.
87
112
  - Never post empty or minimal comments — if a milestone has no meaningful content, skip the post.
88
113
  - Do not delete prior milestone comments. They are the audit trail.
89
114
  - If `save_comment` fails, retry once. If it fails again, surface the error.
@@ -20,9 +20,32 @@ See the `config-resolution` rule for configuration and dispatch table.
20
20
  - Anything else → stop and report `"Unknown tracker '<value>' in .lisa.config.json. Expected 'jira', 'github', or 'linear'."`
21
21
  3. Pass through the output.
22
22
 
23
+ `$ARGUMENTS` is forwarded verbatim, including the optional `--rollup` flag (see "Parent status rollup" below) and `--update-label`. The shim never interprets these — the vendor skill does.
24
+
23
25
  If `$ARGUMENTS` is empty, all vendor skills auto-detect a ticket reference from the active plan file (most recently modified `.md` in `plans/`).
24
26
 
27
+ ## Parent status rollup (`--rollup`)
28
+
29
+ When the caller passes `--rollup` after the milestone, the dispatch target additionally **derives the parent/container's lifecycle state from its children** instead of acting on the work item directly. This is the vendor-neutral implementation of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy here. The shim is dispatch only; the rollup mechanics live in the vendor sync skill (`lisa:github-sync`, `lisa:jira-sync`, `lisa:linear-sync`), which resolves child membership via its `*-read-*` skill and evaluates the state machine below.
30
+
31
+ The state machine (first match wins, evaluated over the **required** leaves only):
32
+
33
+ | If among the required leaves… | …the parent rolls up to | Role |
34
+ |---|---|---|
35
+ | any leaf is **blocked** | blocked / attention-needed | `blocked` |
36
+ | else any leaf is **in progress** (claimed or in review) | active / in-progress | `claimed` |
37
+ | else **all** required leaves are **terminal** | the configured rollup terminal | `done` (or `review` where supported) |
38
+ | else (leaves exist, none started) | unchanged | — |
39
+
40
+ - **Blocked dominates** — one blocked leaf surfaces blocked on the parent even while others progress.
41
+ - **The parent never carries `ready`** — `ready` is a human "claim this leaf" signal; rollup only moves a parent between non-ready container states.
42
+ - **Rollup is recursive** — an Epic rolls up from its Stories, each of which rolls up from its own leaves. Evaluate bottom-up.
43
+ - **The terminal is the configured env-keyed `done`** — multi-env projects roll up to whichever `done` value matches the env their leaves shipped to (see `config-resolution` "Env-keyed `done`"). **Single-environment collapse (this repo):** `deploy.branches` declares only `production: main`, so `done` is a single value and the lifecycle collapses to `ready → claimed (in-progress) → review (code-review) → done`; the rollup terminal is simply `done` (or the PRD-side `ticketed` for PRD containers), with **no** dev/staging promotion hops and **no** env-keyed multi-entry chain to resolve.
44
+
45
+ **Safe-by-default when not yet supported.** A vendor sync path that has not implemented native rollup MUST be a documented no-op that surfaces the derived state as a suggestion/comment rather than guessing a transition — never an unsafe default. Without `--rollup`, the sync skills behave exactly as before (milestone comment on the work item; no parent derivation).
46
+
25
47
  ## Rules
26
48
 
27
49
  - Idempotent updates — running sync at the same milestone twice should not produce duplicate comments. Vendor skills enforce this.
28
50
  - Never auto-transition the underlying state. Linear's label-based transition (`status:*`) is the canonical signal and is updated only when the caller passes `--update-label`. Native states stay as suggestions.
51
+ - Parent rollup derives state from children per the `leaf-only-lifecycle` rule; it never sets a parent to `ready` and never resolves a dev/staging `done` in this single-environment repo.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.30.0",
3
+ "version": "2.32.0",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "lisa-openclaw",
3
+ "version": "2.32.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.32.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).