@codyswann/lisa 2.286.12 → 2.287.1

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 (106) hide show
  1. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  2. package/dist/core/upstream-evidence-manifest.js +29 -5
  3. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  4. package/dist/strategies/package-lisa.d.ts.map +1 -1
  5. package/dist/strategies/package-lisa.js +51 -1
  6. package/dist/strategies/package-lisa.js.map +1 -1
  7. package/package.json +1 -1
  8. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  9. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  10. package/plugins/lisa/.codex-plugin/skills/lisa-exploratory-qa/SKILL.md +1 -1
  11. package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +6 -4
  12. package/plugins/lisa/.codex-plugin/skills/lisa-verify-prd/SKILL.md +1 -1
  13. package/plugins/lisa/rules/reference/prd-lifecycle-rollup.md +2 -2
  14. package/plugins/lisa/skills/lisa-exploratory-qa/SKILL.md +1 -1
  15. package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +6 -4
  16. package/plugins/lisa/skills/lisa-verify-prd/SKILL.md +1 -1
  17. package/plugins/lisa-agy/plugin.json +1 -1
  18. package/plugins/lisa-agy/skills/lisa-exploratory-qa/SKILL.md +1 -1
  19. package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +6 -4
  20. package/plugins/lisa-agy/skills/lisa-verify-prd/SKILL.md +1 -1
  21. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  23. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  24. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-copilot/rules/reference/prd-lifecycle-rollup.md +2 -2
  28. package/plugins/lisa-copilot/skills/lisa-exploratory-qa/SKILL.md +1 -1
  29. package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +6 -4
  30. package/plugins/lisa-copilot/skills/lisa-verify-prd/SKILL.md +1 -1
  31. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-cursor/rules/prd-lifecycle-rollup-reference.mdc +2 -2
  33. package/plugins/lisa-cursor/skills/lisa-exploratory-qa/SKILL.md +1 -1
  34. package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +6 -4
  35. package/plugins/lisa-cursor/skills/lisa-verify-prd/SKILL.md +1 -1
  36. package/plugins/lisa-expo/.claude-plugin/plugin.json +14 -2
  37. package/plugins/lisa-expo/.codex-plugin/hooks.json +15 -0
  38. package/plugins/lisa-expo/.codex-plugin/plugin.json +2 -1
  39. package/plugins/lisa-expo/.codex-plugin/skills/lisa-maestro-mcp-setup/SKILL.md +12 -0
  40. package/plugins/lisa-expo/.codex-plugin/skills/lisa-maestro-mcp-setup/agents/openai.yaml +4 -0
  41. package/plugins/lisa-expo/.codex-plugin/skills/maestro-mcp-setup/SKILL.md +144 -0
  42. package/plugins/lisa-expo/.codex-plugin/skills/maestro-mcp-setup/agents/openai.yaml +4 -0
  43. package/plugins/lisa-expo/THIRD-PARTY-NOTICES.md +17 -5
  44. package/plugins/lisa-expo/commands/maestro-mcp-setup.md +7 -0
  45. package/plugins/lisa-expo/hooks/register-maestro-mcp.sh +84 -0
  46. package/plugins/lisa-expo/skills/maestro-mcp-setup/SKILL.md +144 -0
  47. package/plugins/lisa-expo/skills/maestro-mcp-setup/agents/openai.yaml +4 -0
  48. package/plugins/lisa-expo-agy/THIRD-PARTY-NOTICES.md +17 -5
  49. package/plugins/lisa-expo-agy/commands/lisa/maestro-mcp-setup.md +7 -0
  50. package/plugins/lisa-expo-agy/plugin.json +1 -1
  51. package/plugins/lisa-expo-agy/skills/maestro-mcp-setup/SKILL.md +144 -0
  52. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +14 -1
  53. package/plugins/lisa-expo-copilot/THIRD-PARTY-NOTICES.md +17 -5
  54. package/plugins/lisa-expo-copilot/commands/lisa/maestro-mcp-setup.md +7 -0
  55. package/plugins/lisa-expo-copilot/hooks/register-maestro-mcp.sh +84 -0
  56. package/plugins/lisa-expo-copilot/skills/maestro-mcp-setup/SKILL.md +144 -0
  57. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-expo-cursor/THIRD-PARTY-NOTICES.md +17 -5
  59. package/plugins/lisa-expo-cursor/commands/lisa/maestro-mcp-setup.md +7 -0
  60. package/plugins/lisa-expo-cursor/hooks/hooks.json +10 -0
  61. package/plugins/lisa-expo-cursor/hooks/register-maestro-mcp.sh +84 -0
  62. package/plugins/lisa-expo-cursor/skills/maestro-mcp-setup/SKILL.md +144 -0
  63. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  65. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  66. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  70. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  71. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  75. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  76. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  81. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-rails-agy/plugin.json +1 -1
  86. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  91. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  96. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/src/base/rules/reference/prd-lifecycle-rollup.md +2 -2
  99. package/plugins/src/base/skills/lisa-exploratory-qa/SKILL.md +1 -1
  100. package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +6 -4
  101. package/plugins/src/base/skills/lisa-verify-prd/SKILL.md +1 -1
  102. package/plugins/src/expo/.claude-plugin/plugin.json +13 -2
  103. package/plugins/src/expo/THIRD-PARTY-NOTICES.md +17 -5
  104. package/plugins/src/expo/commands/maestro-mcp-setup.md +7 -0
  105. package/plugins/src/expo/hooks/register-maestro-mcp.sh +84 -0
  106. package/plugins/src/expo/skills/maestro-mcp-setup/SKILL.md +144 -0
@@ -0,0 +1,144 @@
1
+ ---
2
+ name: maestro-mcp-setup
3
+ description: Enable the Maestro CLI's built-in MCP server (`maestro mcp`, STDIO) for this machine, robustly. Detects the Maestro CLI and a usable Java runtime, installs/guides what is missing, and registers the MCP server at LOCAL (per-machine, uncommitted) scope with an absolute command path and injected JAVA_HOME/PATH so the spawn never dies on a non-login PATH. Use when an Expo project needs Maestro device-automation tools (list_devices, inspect_screen, take_screenshot, run flows). Never registers at project/committed scope — that reintroduces the fleet-wide "-32000" failure.
4
+ allowed-tools:
5
+ - Bash
6
+ - Read
7
+ ---
8
+
9
+ # Maestro MCP Setup
10
+
11
+ Wire the Maestro CLI's built-in MCP server (`maestro mcp`, STDIO) into the
12
+ current coding agent for **this machine only**, in a way that actually works.
13
+
14
+ ## Why this skill exists (read before changing it)
15
+
16
+ The Maestro MCP server is intentionally **NOT** in the distributed plugin
17
+ `.mcp.json`. A static, committed entry always attempts to spawn, and coding
18
+ agents spawn stdio servers with a **non-login PATH**. So an always-on entry
19
+ fails visibly — Claude Code shows `Failed to reconnect … -32000` **every
20
+ session** — on any machine missing the Maestro CLI *or* a resolvable Java
21
+ runtime, which is most of a typical fleet (CI runners, unattended QA/intake
22
+ agent boxes). That exact regression shipped once (expo plugin commit b12d5d3)
23
+ and was reverted (b1f3efd).
24
+
25
+ This skill fixes both failure modes without poisoning the fleet:
26
+
27
+ 1. **Missing CLI / Java** → detect, and install or guide install.
28
+ 2. **Installed but PATH-less spawn** → register with an **absolute `command`
29
+ path** plus injected **`JAVA_HOME` / `PATH`** env, so the server finds Java
30
+ regardless of the spawn's inherited PATH.
31
+
32
+ Registration is always **`--scope local`** (per-machine, uncommitted). Never use
33
+ `--scope project` / a committed `.mcp.json` entry — that is the always-on form
34
+ that reds out every other machine.
35
+
36
+ ## Steps
37
+
38
+ ### 1. Locate the Maestro CLI
39
+
40
+ ```bash
41
+ MAESTRO_BIN="$(command -v maestro || true)"
42
+ [ -z "$MAESTRO_BIN" ] && [ -x "$HOME/.maestro/bin/maestro" ] && MAESTRO_BIN="$HOME/.maestro/bin/maestro"
43
+ echo "maestro: ${MAESTRO_BIN:-NOT FOUND}"
44
+ ```
45
+
46
+ If not found, install it (official installer — confirm with the user first,
47
+ since it writes to `~/.maestro`):
48
+
49
+ ```bash
50
+ curl -fsSL "https://get.maestro.mobile.dev" | bash
51
+ MAESTRO_BIN="$HOME/.maestro/bin/maestro"
52
+ ```
53
+
54
+ Resolve to an **absolute** path — a bare `maestro` in the registration relies on
55
+ the very PATH that is missing at spawn time.
56
+
57
+ ### 2. Locate a usable Java runtime
58
+
59
+ Maestro needs a JDK (8+). Resolve `JAVA_HOME` **honoring the project's version
60
+ manager** — do not install a parallel global JDK when one is already managed:
61
+
62
+ ```bash
63
+ # Prefer an already-active/managed Java before installing anything. Covers the
64
+ # common version managers (mise, asdf, SDKMAN) plus an ambient install.
65
+ if command -v mise >/dev/null 2>&1 && mise which java >/dev/null 2>&1; then
66
+ JAVA_BIN="$(mise which java)"
67
+ elif command -v asdf >/dev/null 2>&1 && asdf which java >/dev/null 2>&1; then
68
+ JAVA_BIN="$(asdf which java)"
69
+ elif [ -x "${SDKMAN_DIR:-$HOME/.sdkman}/candidates/java/current/bin/java" ]; then
70
+ # SDKMAN's `sdk` is a shell function absent in non-login shells; use its stable
71
+ # `candidates/java/current` symlink directly instead.
72
+ JAVA_BIN="${SDKMAN_DIR:-$HOME/.sdkman}/candidates/java/current/bin/java"
73
+ elif command -v java >/dev/null 2>&1; then
74
+ JAVA_BIN="$(command -v java)"
75
+ fi
76
+ echo "java: ${JAVA_BIN:-NOT FOUND}"
77
+
78
+ # Derive JAVA_HOME by asking the JVM itself — NOT `dirname "$JAVA_BIN"/..`, which
79
+ # is wrong when `java` is a mise/asdf shim or a symlink whose parent is not a JDK
80
+ # root. Fall back to the bin/.. parent only if the JVM query yields nothing usable.
81
+ if [ -n "$JAVA_BIN" ]; then
82
+ JAVA_HOME="$("$JAVA_BIN" -XshowSettings:properties -version 2>&1 \
83
+ | sed -n 's/^[[:space:]]*java\.home = //p' | head -n 1)"
84
+ { [ -z "$JAVA_HOME" ] || [ ! -x "$JAVA_HOME/bin/java" ]; } &&
85
+ JAVA_HOME="$(cd "$(dirname "$JAVA_BIN")/.." && pwd)"
86
+ fi
87
+ ```
88
+
89
+ If no Java is found: install through the project's version manager when present
90
+ (`mise use -g java@21`, `asdf install java …`, or `sdk install java`), or guide
91
+ the user to install a JDK. Prefer the managed path; only fall back to a global
92
+ install with explicit consent. Re-resolve `JAVA_HOME` afterward.
93
+
94
+ ### 3. Register at local scope with injected env
95
+
96
+ Build a `PATH` that puts the Maestro and Java `bin` dirs first, then register for
97
+ the **current** coding agent. `$JAVA_BIN`/`$MAESTRO_BIN` are absolute.
98
+
99
+ Claude Code:
100
+
101
+ ```bash
102
+ # Refuse to register a broken server — both toolchain paths must resolve and be
103
+ # executable, or `claude mcp add` would create the exact -32000 entry this skill
104
+ # exists to avoid.
105
+ [ -n "$MAESTRO_BIN" ] && [ -x "$MAESTRO_BIN" ] || { echo "Maestro CLI unresolved — abort"; exit 1; }
106
+ [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ] || { echo "Java runtime unresolved — abort"; exit 1; }
107
+
108
+ # Use the real JDK bin (from JAVA_HOME), not the shim dir, on PATH.
109
+ JBIN_DIR="$JAVA_HOME/bin"; MBIN_DIR="$(dirname "$MAESTRO_BIN")"
110
+ claude mcp add --scope local maestro \
111
+ --env "JAVA_HOME=$JAVA_HOME" \
112
+ --env "PATH=$JBIN_DIR:$MBIN_DIR:$PATH" \
113
+ -- "$MAESTRO_BIN" mcp
114
+ ```
115
+
116
+ Parity — same intent on other harnesses (local/per-machine scope, absolute
117
+ command, injected `JAVA_HOME`/`PATH`); translate the registration verb only:
118
+
119
+ - **Codex** — `codex mcp add maestro --env JAVA_HOME=… --env PATH=… -- "$MAESTRO_BIN" mcp` (writes `~/.codex/config.toml`; keep it out of the committed project config).
120
+ - **Cursor** — add the server to the user-scope `~/.cursor/mcp.json` (not the project `.cursor/mcp.json`) with `command`, `args: ["mcp"]`, and `env: { JAVA_HOME, PATH }`.
121
+ - **OpenCode** — add to the user config (`~/.config/opencode/opencode.json`) `mcp` block with the absolute command and `environment`.
122
+ - **Antigravity (agy) / Copilot** — add to the per-user MCP config with the absolute command + `env`; Copilot uses `type: "local"` for stdio servers.
123
+
124
+ In every case: **local/user scope, never the committed project file.**
125
+
126
+ ### 4. Verify
127
+
128
+ ```bash
129
+ claude mcp list # or the harness equivalent
130
+ ```
131
+
132
+ Confirm `maestro` shows connected. If it still fails, the usual cause is
133
+ `JAVA_HOME` pointing at a JRE without `bin/java`, or a Maestro path that moved —
134
+ re-resolve both and re-register. Do not "fix" it by dropping to a bare
135
+ `maestro mcp` command; that reintroduces the PATH-less failure.
136
+
137
+ ## Guardrails
138
+
139
+ - **Local scope only.** If you catch yourself typing `--scope project` or editing
140
+ a committed `.mcp.json`, stop — that is the reverted fleet-wide regression.
141
+ - **Absolute paths + injected env are mandatory**, not optional — they are the
142
+ whole reason this is a skill and not a one-line doc.
143
+ - Installing the CLI or a JDK mutates the machine — confirm before installing,
144
+ and prefer the project's version manager over a parallel global install.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
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.286.12",
3
+ "version": "2.287.1",
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-harper-fabric",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
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.286.12",
3
+ "version": "2.287.1",
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.286.12",
3
+ "version": "2.287.1",
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-nestjs",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
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.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
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.286.12",
3
+ "version": "2.287.1",
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.286.12",
3
+ "version": "2.287.1",
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-openclaw",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
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
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
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
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
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
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
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
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
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
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.286.12",
3
+ "version": "2.287.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -66,13 +66,13 @@ A generated top-level child is **terminal** (counts as done for rollup) when it
66
66
  | Vendor | A generated top-level child is terminal when… |
67
67
  |---|---|
68
68
  | **GitHub Issues** | the issue is **closed** *and* (where the build-status label is used) carries the resolved `done` role label (`status:done` by default — env-keyed; see below). A closed-as-not-planned issue is terminal-but-dropped: it does not hold the PRD open but is excluded from "shipped" (treated like a won't-do leaf). |
69
- | **Linear** | the Issue/Project is in a **completed** workflow state (`done`-category), **or** a **canceled** state (terminal-but-dropped, like not-planned — does not hold the PRD open, excluded from shipped). |
69
+ | **Linear** | the Issue/Project is in a **completed** workflow state (`done`-category), **or** a **canceled** or **duplicate** state (both terminal-but-dropped, like not-planned — do not hold the PRD open, excluded from shipped). Linear exposes `duplicate` as its own first-class `state.type`, distinct from `canceled`; an Issue marked as a duplicate (via Linear's native action or a team's Duplicate workflow state) is terminal and must be treated like canceled, never as still-open. |
70
70
  | **JIRA** | the issue's status is in the **Done status category** (`statusCategory.key == "done"`). |
71
71
  | **Confluence / Notion** | the documented generated-work entry is marked **done** in the PRD's machine-readable section (the durable equivalent of a closed ticket, since these sources have no native ticket state). |
72
72
 
73
73
  Notes:
74
74
 
75
- - **Required vs. optional children.** Only the generated top-level children that must ship for the PRD to be complete are counted toward the all-terminal check. Won't-do / canceled / not-planned children are terminal-but-dropped: they do not hold the PRD open and are excluded from the shipped set. This mirrors `leaf-only-lifecycle`'s "required leaves" qualifier.
75
+ - **Required vs. optional children.** Only the generated top-level children that must ship for the PRD to be complete are counted toward the all-terminal check. Won't-do / canceled / duplicate / not-planned children are terminal-but-dropped: they do not hold the PRD open and are excluded from the shipped set. This mirrors `leaf-only-lifecycle`'s "required leaves" qualifier.
76
76
  - **Recursion is delegated, not duplicated.** A generated Epic is terminal only when *it* has rolled up to its own terminal state per `leaf-only-lifecycle`'s parent-status-rollup (all its required Stories/Sub-tasks terminal). This rule does not re-derive an Epic's state from its leaves — it reads the top-level child's own resolved state and trusts `leaf-only-lifecycle` to have rolled that up bottom-up.
77
77
  - **Blocked dominates at the report level.** If any required generated top-level child is blocked or incomplete, rollup leaves the PRD open and reports the incomplete child set (PRD #525: "rollup leaving a PRD open when at least one generated top-level child is incomplete"). The PRD is only advanced when **all** required top-level children are terminal.
78
78
 
@@ -78,7 +78,7 @@ Re-running a pass must not refile the same finding. Before creating a ticket, se
78
78
 
79
79
  - **Open** ticket carrying the marker → reference/update it instead; do not create a second.
80
80
  - **Closed as _completed_** → does **not** suppress. A recurrence after a fix is a genuine **regression**, so file the finding.
81
- - **Closed as _not planned_** (GitHub `stateReason == "not_planned"`; the config-resolved won't-do/canceled equivalent on JIRA/Linear) → a human **declined** this finding, so **suppress it**. Re-file only with evidence that **postdates the decline**, carrying BOTH the machine token (`declined <date>; recurred <date> in <ref>`) and a human acknowledgment sentence (`You declined this on <date>. It has recurred (<date>, <ref>), so we're raising it once more for your review.`).
81
+ - **Closed as _not planned_** (GitHub `stateReason == "not_planned"`; the config-resolved won't-do/canceled equivalent on JIRA/Linear, including a Linear `duplicate` state) → a human **declined** this finding, so **suppress it**. Re-file only with evidence that **postdates the decline**, carrying BOTH the machine token (`declined <date>; recurred <date> in <ref>`) and a human acknowledgment sentence (`You declined this on <date>. It has recurred (<date>, <ref>), so we're raising it once more for your review.`).
82
82
 
83
83
  Every filed finding ticket MUST end with the `rejection-detection` **operator footer** as a visible prose line so the operator knows which close-reason silences it:
84
84
 
@@ -151,15 +151,17 @@ Run this gate **before** the claim relabel, starting with the oldest/highest-pri
151
151
 
152
152
  **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-linear-read-issue` uses — Linear's native parentage: an Issue groups **sub-issues** via `parentId`, and a **Project** (the Epic equivalent) groups Issues via `projectId`. Relations (`save_issue_relation` — `blocks` / `is blocked by`) express dependencies and are **not** parentage — do not count them as children.
153
153
 
154
- Fetch the Issue's sub-issues via `lisa-linear-access operation: get-issue` (which returns the children) or `lisa-linear-access operation: list-issues({parentId: <issueId>})`, then count those still open (Linear `state.type` not in the completed/canceled set):
154
+ Fetch the Issue's sub-issues via `lisa-linear-access operation: get-issue` (which returns the children) or `lisa-linear-access operation: list-issues({parentId: <issueId>})`, then count those still open (Linear `state.type` not in the completed/canceled/duplicate set):
155
155
 
156
156
  ```text
157
157
  # Children of <issueId>: native sub-issues via parentId.
158
- # Count children whose Linear state.type is NOT terminal ("completed" / "canceled").
159
- # A parent whose children are all completed is no longer holding open work and
158
+ # Count children whose Linear state.type is NOT terminal ("completed" / "canceled" / "duplicate").
159
+ # "duplicate" is a first-class Linear state.type (distinct from "canceled"): an Issue marked
160
+ # as a duplicate is closed and must NOT be counted as open, or the parent never rolls up.
161
+ # A parent whose children are all terminal is no longer holding open work and
160
162
  # rolls up via leaf-only-lifecycle's rollup, not here.
161
163
  OPEN_CHILDREN = count(list_issues({parentId: <issueId>})
162
- where state.type not in {"completed", "canceled"})
164
+ where state.type not in {"completed", "canceled", "duplicate"})
163
165
  ```
164
166
 
165
167
  For a Project-level parent (an Issue that itself anchors a `projectId` grouping rather than a `parentId` tree), resolve membership the same way `lisa-linear-read-issue` does and treat the parent as a container if any grouped Issue is still open. If sub-issue resolution is unavailable, fall back to the parentage `lisa-linear-read-issue` derives and treat the Issue as a container if any derived child is open. Note "sub-issues unavailable — parentage derived" so the operator knows how children were resolved.
@@ -70,7 +70,7 @@ If neither source yields any generated top-level child (the PRD generated nothin
70
70
  Apply the **per-vendor terminal-state predicate from the `prd-lifecycle-rollup` rule** to every generated **top-level** work item (cite the rule by slug — do not restate its predicate table here). In summary, a top-level child is:
71
71
 
72
72
  - **Terminal** — it has reached its source/tracker's done/shipped state (GitHub: closed + the resolved build `done` role label where used; Linear: a `done`-category completed state; JIRA: `statusCategory.key == "done"`; Notion/Confluence: the documented generated-work entry marked done). A generated Epic is terminal only when *it* has rolled up to its own terminal state per `leaf-only-lifecycle` — read the child's own resolved state; do not re-derive it from its leaves.
73
- - **Terminal-but-dropped** — closed-as-not-planned (GitHub `stateReason == "not_planned"`) / canceled (Linear) / won't-do. It does **not** hold the PRD open and is excluded from the required set.
73
+ - **Terminal-but-dropped** — closed-as-not-planned (GitHub `stateReason == "not_planned"`) / canceled or duplicate (Linear — both are terminal `state.type`s; `duplicate` is distinct from `canceled`) / won't-do. It does **not** hold the PRD open and is excluded from the required set.
74
74
  - **Incomplete / blocked** — anything else (still open, or closed without the `done` role). It holds the PRD open.
75
75
 
76
76
  The **required** set is the top-level children minus the terminal-but-dropped ones. Branch:
@@ -4,6 +4,17 @@
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": { "name": "Cody Swann" },
6
6
  "dependencies": ["lisa-typescript"],
7
- "hooks": {}
8
-
7
+ "hooks": {
8
+ "SessionStart": [
9
+ {
10
+ "matcher": "",
11
+ "hooks": [
12
+ {
13
+ "type": "command",
14
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/register-maestro-mcp.sh"
15
+ }
16
+ ]
17
+ }
18
+ ]
19
+ }
9
20
  }
@@ -35,15 +35,27 @@ NOT registered in `.mcp.json`. Coding agents spawn stdio servers with a
35
35
  non-login PATH, so an always-on entry fails visibly (Claude Code shows a
36
36
  "Failed to reconnect … -32000" error every session) on any machine missing the
37
37
  Maestro CLI or a resolvable Java runtime — which is most of the fleet. Opt in
38
- per machine instead, e.g.:
38
+ per machine instead.
39
+
40
+ The supported path is the **`/lisa-expo:maestro-mcp-setup`** skill (Codex:
41
+ `$maestro-mcp-setup`), which detects the Maestro CLI and a usable Java runtime,
42
+ installs or guides whatever is missing, and registers `maestro mcp` at
43
+ **local/per-machine scope** with an absolute command path and injected
44
+ `JAVA_HOME`/`PATH` — so the spawn works even under a non-login PATH.
45
+
46
+ To register by hand instead, keep it at local scope and inject the toolchain,
47
+ e.g.:
39
48
 
40
49
  ```
41
- claude mcp add --scope local maestro -- maestro mcp
50
+ # Resolve a real JAVA_HOME from the JVM (robust when `java` is a shim/symlink):
51
+ JAVA_HOME="$(java -XshowSettings:properties -version 2>&1 | sed -n 's/^[[:space:]]*java\.home = //p' | head -n1)"
52
+ claude mcp add --scope local maestro \
53
+ --env "JAVA_HOME=$JAVA_HOME" --env "PATH=$JAVA_HOME/bin:$HOME/.maestro/bin:$PATH" \
54
+ -- "$HOME/.maestro/bin/maestro" mcp
42
55
  ```
43
56
 
44
- ensuring `maestro` and a Java runtime are on the non-interactive PATH (mise
45
- users: `claude mcp add --scope local maestro -- mise exec java -- maestro mcp`
46
- from a directory where Java is active).
57
+ Never register at `--scope project` / a committed `.mcp.json` that is the
58
+ always-on form that reds out every other machine in the fleet.
47
59
 
48
60
  ### MIT License
49
61
 
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: "Enable the Maestro CLI's MCP server (maestro mcp, STDIO) for this machine, robustly. Detects the Maestro CLI + a usable Java runtime (honoring mise/asdf/sdkman), installs or guides what is missing, and registers the server at LOCAL/per-machine scope with an absolute command path and injected JAVA_HOME/PATH so the spawn never dies on a non-login PATH. Never registers at committed/project scope, which would reintroduce the fleet-wide -32000 failure."
3
+ allowed-tools: ["Skill"]
4
+ argument-hint: ""
5
+ ---
6
+
7
+ Use the /lisa-expo:maestro-mcp-setup skill to enable the Maestro MCP server for this machine: detect the Maestro CLI and a usable Java runtime, install or guide whatever is missing (preferring the project's version manager), and register `maestro mcp` at local/per-machine scope with an absolute command path plus injected JAVA_HOME/PATH env. Local scope only — never a committed project `.mcp.json`. $ARGUMENTS