@codyswann/lisa 2.348.0 → 2.349.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 (63) hide show
  1. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  2. package/dist/core/upstream-evidence-manifest.js +26 -3
  3. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  4. package/expo/create-only/.github/required-checks.json +52 -0
  5. package/expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml +83 -0
  6. package/expo/create-only/.github/workflows/nightly-e2e-health.yml +140 -0
  7. package/expo/github-rulesets/{playwright.json → nightly-e2e-health.json} +3 -8
  8. package/package.json +1 -1
  9. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  10. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  11. package/plugins/lisa-agy/plugin.json +1 -1
  12. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  14. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  15. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  21. package/plugins/lisa-expo-agy/plugin.json +1 -1
  22. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  26. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  27. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  31. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  32. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  36. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  37. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  41. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  42. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  46. package/plugins/lisa-rails-agy/plugin.json +1 -1
  47. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  51. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  52. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  56. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  57. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  59. package/typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs +1516 -0
  60. package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +580 -0
  61. package/typescript/copy-overwrite/scripts/nightly-e2e-suites.schema.json +85 -0
  62. package/typescript/create-only/.github/required-checks.json +28 -0
  63. package/typescript/package-lisa/package.lisa.json +4 -1
@@ -0,0 +1,52 @@
1
+ {
2
+ "_readme": [
3
+ "See typescript/create-only/.github/required-checks.json in Lisa for the full rationale. In short: GitHub counts a SKIPPED required status check as SATISFIED, so a `skip_jobs` token that silences a required context makes the merge gate decorative.",
4
+ "This expo seed declares the three tokens the shipped ci.yml skips. Every one of them is currently NOT ruleset-required, so nothing here is a false green — but the declaration exists so that the day one of them BECOMES required, the guard says so instead of the gate quietly going hollow.",
5
+ "Transcribe `required_contexts` byte for byte from your ruleset and keep it current with `--remote`.",
6
+ "The nightly-gate context is listed because Lisa ships expo/github-rulesets/nightly-e2e-health.json requiring it on dev. No skip_jobs token silences it today, so nothing is a false green — it is here so that the day one does, the guard says so instead of staying quiet."
7
+ ],
8
+ "ruleset": {
9
+ "repo": "",
10
+ "ids": [],
11
+ "baseline_fetched_at": ""
12
+ },
13
+ "workflows": [
14
+ ".github/workflows/ci.yml"
15
+ ],
16
+ "exemption_ticket_pattern": "^[A-Z][A-Z0-9]+-\\d+$",
17
+ "required_contexts": [
18
+ "🔍 Quality Checks / 🧹 Lint",
19
+ "🔍 Quality Checks / 🔍 Type Check",
20
+ "🔍 Quality Checks / 🏗️ Build",
21
+ "🔍 Quality Checks / 📐 Check Formatting",
22
+ "🔍 Quality Checks / 🔒 Security Scan",
23
+ "🔍 Quality Checks / 🧪 Run Unit Tests",
24
+ "🔍 Quality Checks / 🧪 Run Integration Tests",
25
+ "🔍 Quality Checks / 🔗 Work-Item Traceability",
26
+ "🌙 Nightly E2E Health / 🌙 Gate"
27
+ ],
28
+ "skip_job_declarations": {
29
+ "test:e2e": {
30
+ "suppressed_contexts": [
31
+ "🔍 Quality Checks / 🧪 Run E2E Tests"
32
+ ],
33
+ "ruleset_required": false,
34
+ "reason": "A fresh Expo project has no `test:e2e` script. Lisa's quality callee guards each job on script existence, so un-skipping it would produce a real run that succeeds having tested nothing — a worse false green than the skip. Not a required context, so skipping removes a check rather than faking one."
35
+ },
36
+ "playwright_e2e": {
37
+ "suppressed_contexts": [
38
+ "🔍 Quality Checks / 🎭 Playwright Shard Setup",
39
+ "🔍 Quality Checks / 🎭 Playwright E2E Tests"
40
+ ],
41
+ "ruleset_required": false,
42
+ "reason": "Note this ONE token silences TWO jobs. Neither is a required context. Browser e2e is gated by the nightly suite plus `🌙 Nightly E2E Health`, not by a PR-time Playwright run — which is exactly why the old `playwright` ruleset template was deleted: it required a context PRs skip, and GitHub counts skipped as satisfied."
43
+ },
44
+ "zap_baseline": {
45
+ "suppressed_contexts": [
46
+ "🔍 Quality Checks / 🕷️ OWASP ZAP Baseline"
47
+ ],
48
+ "ruleset_required": false,
49
+ "reason": "DAST needs a deployed target and is run against staging, not on every PR. Not a required context."
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,83 @@
1
+ name: 🧹 Nightly E2E Bypass Reaper
2
+
3
+ # Removes a used `nightly-e2e-bypass` label when its pull request closes.
4
+ #
5
+ # ## Why removal happens on CLOSE and not on USE
6
+ #
7
+ # The obvious implementation — have the gate strip the label as soon as it
8
+ # honours it — is wrong, and wrong in a way that is easy to ship and hard to
9
+ # diagnose. Removing the label fires `unlabeled`, which re-runs the gate, which
10
+ # now sees no bypass and goes RED. The PR is blocked again by the very mechanism
11
+ # meant to unblock it, and the only way out is to re-apply the label, which the
12
+ # gate then strips again. So the gate itself never writes; this single-purpose
13
+ # workflow does the cleanup once the PR can no longer be affected by it.
14
+ #
15
+ # Expiry is the belt to this suspenders. Even where this reaper is not
16
+ # installed, a bypass stops working `bypass_max_hours` after the label was
17
+ # applied (default 24, hard ceiling 72). The reaper keeps the label list honest;
18
+ # it is not what bounds the waiver's lifetime.
19
+ #
20
+ # ## Why the audit survives removal
21
+ #
22
+ # The audit record lives in the gate's job summary, its `::notice::` annotation
23
+ # and its `audit_json` output on the run that honoured the bypass — none of which
24
+ # this workflow touches. Removing the label removes the REQUEST, never the
25
+ # RECORD.
26
+
27
+ on:
28
+ pull_request_target:
29
+ types: [closed]
30
+
31
+ permissions:
32
+ contents: read
33
+ # The one write in the whole nightly-gate standard, scoped to removing one
34
+ # label from an already-closed PR.
35
+ pull-requests: write
36
+
37
+ concurrency:
38
+ group: nightly-e2e-bypass-reaper-${{ github.event.pull_request.number }}
39
+ cancel-in-progress: false
40
+
41
+ jobs:
42
+ reap:
43
+ name: 🧹 Remove used bypass label
44
+ # `pull_request_target` runs with a writable token against the BASE repo, so
45
+ # this job must never check out or execute pull-request code. It does not:
46
+ # there is no checkout step and the only command is a `gh` API call.
47
+ if: contains(github.event.pull_request.labels.*.name, 'nightly-e2e-bypass')
48
+ runs-on: ubuntu-latest
49
+ timeout-minutes: 5
50
+ steps:
51
+ - name: 🧹 Strip the bypass label
52
+ env:
53
+ GH_TOKEN: ${{ github.token }}
54
+ REPO: ${{ github.repository }}
55
+ PR: ${{ github.event.pull_request.number }}
56
+ LABEL: nightly-e2e-bypass
57
+ run: |
58
+ set -euo pipefail
59
+ echo "Removing '$LABEL' from $REPO#$PR (state: ${{ github.event.pull_request.merged && 'merged' || 'closed' }})."
60
+ # ONE delete. Someone removing the label between the event and this
61
+ # run is the desired end state, not a failure — but a permission or
62
+ # API problem must NEVER look like a successful reap, or the label
63
+ # list quietly stops being trustworthy.
64
+ #
65
+ # `set -e` is disabled around the call so a non-zero exit is inspected
66
+ # rather than killing the step, and the outcome is then decided by
67
+ # asking whether the label is actually gone. Reading the status out of
68
+ # `--include` does not work: `--silent` suppresses the output that
69
+ # would carry it.
70
+ set +e
71
+ gh api -X DELETE "repos/$REPO/issues/$PR/labels/$LABEL" --silent 2>/dev/null
72
+ deleted=$?
73
+ set -e
74
+ if [[ $deleted -eq 0 ]]; then
75
+ echo "::notice title=Nightly E2E bypass label removed::'$LABEL' cleared from #$PR after close. The audit record on the gate run that honoured it is unaffected."
76
+ exit 0
77
+ fi
78
+ if gh api "repos/$REPO/issues/$PR/labels" --jq '.[].name' 2>/dev/null \
79
+ | grep -qxF "$LABEL"; then
80
+ echo "::error title=Nightly E2E bypass label NOT removed::'$LABEL' is still on #$PR and the delete failed. Check that this workflow's token carries \`pull-requests: write\`."
81
+ exit 1
82
+ fi
83
+ echo "::notice title=Nightly E2E bypass label already gone::'$LABEL' was not on #$PR by the time the reaper ran. Nothing to do."
@@ -0,0 +1,140 @@
1
+ name: 🌙 Nightly E2E Health
2
+
3
+ # The blocking half of the nightly e2e standard.
4
+ #
5
+ # The e2e suites are too slow to gate a pull request, so they run on a schedule
6
+ # against the integration branch. That trade buys fast PRs and pays for them
7
+ # with a signal nobody is obliged to read: a nightly can go red and merges
8
+ # continue on top of it for days, so the suite ends up measuring accumulated
9
+ # damage rather than the change that caused it. This workflow closes the loop —
10
+ # it runs no e2e itself, it reads the verdict the nightlies already produced, so
11
+ # it costs seconds and adds nothing to PR latency.
12
+ #
13
+ # All the logic lives in Lisa's reusable `nightly-e2e-health.yml` plus the
14
+ # Lisa-shipped guard `scripts/check-nightly-e2e-health.mjs`. The contract —
15
+ # including the 25-row fail-closed truth table and the bypass rules — is
16
+ # `docs/nightly-e2e-gate.md` in Lisa. This caller owns only the project-specific
17
+ # values: which suites, which branch, and where the gate is required.
18
+ #
19
+ # ## Wiring this up, in order
20
+ #
21
+ # 1. Fill in `suites` below with YOUR workflow file names and job names. The
22
+ # job name for a suite reached through a nested reusable workflow is
23
+ # reported by the API as `<caller job name> / <called job name>` — copy it
24
+ # from a real run, do not guess it.
25
+ # 2. Leave `bootstrap_until` set to a date ~2 weeks out while you burn the
26
+ # suite down. Missing evidence will report but not block, with the expiry
27
+ # visible on every PR. A red suite still blocks. When the date passes the
28
+ # gate arms itself with no further action.
29
+ # 3. Add the required status check to the ruleset for the branch below. The
30
+ # context is `🌙 Nightly E2E Health / 🌙 Gate` — the composite of THIS
31
+ # job's name and the reusable's job name, byte for byte, emoji included.
32
+ # `expo/github-rulesets/nightly-e2e-health.json` in Lisa is the template.
33
+ # 4. Add the context-pinning test (see the ruleset template's header) so a
34
+ # rename of either half cannot silently disarm the gate.
35
+ # 5. Install `nightly-e2e-bypass-reaper.yml` so a used bypass label is removed
36
+ # when the PR closes.
37
+ #
38
+ # ## Scoped to PRs targeting the integration branch, on purpose
39
+ #
40
+ # `branches:` filters by BASE branch, and it must pair with where the context is
41
+ # required. Two reasons, each load-bearing:
42
+ #
43
+ # 1. A required context whose workflow never runs on that branch is a DEADLOCK,
44
+ # not a gate — the check is never reported, so the PR can never go green.
45
+ # 2. Release and hotfix branches receive promotion PRs. Blocking a hotfix to
46
+ # production because last night's dev suite was red blocks the fix for the
47
+ # failure, which inverts the point of the gate.
48
+ #
49
+ # So: required where the work lands, absent where the releases go.
50
+
51
+ on:
52
+ pull_request:
53
+ # Set this to your integration branch (the one the nightlies run against).
54
+ branches: [dev]
55
+ # No `paths:` filter, deliberately. A required context that a path filter
56
+ # can suppress never reports on a docs-only PR, which blocks that PR
57
+ # forever. This job takes seconds; it always runs.
58
+ #
59
+ # `labeled` / `unlabeled` ride on top of the defaults so applying (or
60
+ # removing) the bypass label re-evaluates the gate immediately instead of
61
+ # requiring an empty push to re-trigger `synchronize`.
62
+ types: [opened, synchronize, reopened, labeled, unlabeled]
63
+ workflow_dispatch:
64
+
65
+ permissions:
66
+ contents: read
67
+ # The whole job is Actions-API reads. Nothing here writes.
68
+ actions: read
69
+ # Only needed on a PRIVATE repository, and only for the bypass path (reading
70
+ # the PR timeline to attribute the label). Harmless to keep on a public repo.
71
+ pull-requests: read
72
+
73
+ concurrency:
74
+ # Per-PR and CANCELLING: this job holds no external state and writes to
75
+ # nothing, so a superseded run is pure waste. Note the fail-closed
76
+ # interaction: a cancelled gate run reports NO check, which leaves the
77
+ # required context unreported and the PR blocked until the newer run reports.
78
+ group: nightly-e2e-health-${{ github.event.pull_request.number || github.ref }}
79
+ cancel-in-progress: true
80
+
81
+ jobs:
82
+ # This job's `name:` is HALF of the required status-check context; the other
83
+ # half is the reusable's job name (`🌙 Gate`). GitHub composes them as
84
+ # `🌙 Nightly E2E Health / 🌙 Gate`. Renaming either half silently stops the
85
+ # gate reporting, which DEADLOCKS every PR into the protected branch until
86
+ # someone edits the ruleset. Pin both strings in a test.
87
+ health:
88
+ name: 🌙 Nightly E2E Health
89
+ # PIN AN IMMUTABLE REF. `@main` is not a supported pin for a merge gate: the
90
+ # thing that decides whether code may merge must not change under you
91
+ # between two runs of the same PR. Better still, pin the tag's commit SHA
92
+ # and keep the tag in a trailing comment.
93
+ uses: CodySwannGT/lisa/.github/workflows/nightly-e2e-health.yml@v2.345.1
94
+ with:
95
+ branch: dev
96
+ # Structured JSON, schema-validated before any API call. Duplicated
97
+ # labels, unanchored regexes, unknown keys and zero-match patterns are all
98
+ # rejected rather than silently gating less than you wrote.
99
+ #
100
+ # Prefer `{"mode":"run"}` (the whole workflow IS the suite) or
101
+ # `{"mode":"job","name":"…"}` (an exact, published job name). Use
102
+ # `{"mode":"job_pattern","pattern":"^…$"}` only for matrix job names that
103
+ # no single string can cover.
104
+ #
105
+ # ONLY `maestro-e2e.yml` by default, because that is the only nightly
106
+ # suite this template actually ships. Naming a workflow file that does not
107
+ # exist is truth-table row 11 — a HARD failure, not missing evidence —
108
+ # since the API cannot tell "renamed out from under the gate" apart from
109
+ # "never existed". A default that red-walls a fresh fork would teach the
110
+ # first adopter to delete the gate.
111
+ #
112
+ # Add your browser suite here once you have one. If Playwright runs inside
113
+ # `ci.yml`'s scheduled arm rather than its own workflow, use `mode: "job"`
114
+ # with the job name copied from a REAL run — for a job inside a nested
115
+ # reusable workflow the API reports `<caller job> / <called job>`:
116
+ #
117
+ # {
118
+ # "label": "Playwright browser e2e",
119
+ # "workflow": "ci.yml",
120
+ # "match": {
121
+ # "mode": "job",
122
+ # "name": "🔍 Quality Checks / 🎭 Playwright E2E Tests"
123
+ # }
124
+ # }
125
+ #
126
+ # Do NOT add a suite whose job `ci.yml` skips — a skipped job never
127
+ # reports, and the gate would read it as missing evidence forever.
128
+ suites: |
129
+ [
130
+ {
131
+ "label": "Maestro native e2e",
132
+ "workflow": "maestro-e2e.yml",
133
+ "match": { "mode": "run" }
134
+ }
135
+ ]
136
+ # A TIME-BOXED grace period. While this is in the future, MISSING evidence
137
+ # reports but does not block, and every PR shows the expiry. A red suite
138
+ # blocks inside the window too. Set it, do not remove it — and do not push
139
+ # it out repeatedly, which is how a bootstrap becomes permanent.
140
+ bootstrap_until: ''
@@ -1,11 +1,11 @@
1
1
  {
2
- "name": "playwright",
2
+ "name": "nightly e2e health",
3
3
  "target": "branch",
4
4
  "enforcement": "active",
5
5
  "conditions": {
6
6
  "ref_name": {
7
7
  "exclude": [],
8
- "include": ["refs/heads/staging"]
8
+ "include": ["refs/heads/dev"]
9
9
  }
10
10
  },
11
11
  "bypass_actors": [
@@ -13,11 +13,6 @@
13
13
  "actor_id": null,
14
14
  "actor_type": "DeployKey",
15
15
  "bypass_mode": "always"
16
- },
17
- {
18
- "actor_id": 5,
19
- "actor_type": "RepositoryRole",
20
- "bypass_mode": "always"
21
16
  }
22
17
  ],
23
18
  "rules": [
@@ -28,7 +23,7 @@
28
23
  "do_not_enforce_on_create": true,
29
24
  "required_status_checks": [
30
25
  {
31
- "context": "🔍 Quality Checks / 🎭 Playwright E2E Tests",
26
+ "context": "🌙 Nightly E2E Health / 🌙 Gate",
32
27
  "integration_id": 15368
33
28
  }
34
29
  ]
package/package.json CHANGED
@@ -120,7 +120,7 @@
120
120
  }
121
121
  },
122
122
  "name": "@codyswann/lisa",
123
- "version": "2.348.0",
123
+ "version": "2.349.0",
124
124
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
125
125
  "main": "dist/index.js",
126
126
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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-cdk",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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-cdk",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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-expo",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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-expo",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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-harper-fabric",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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-harper-fabric",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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-nestjs",
3
- "version": "2.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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.348.0",
3
+ "version": "2.349.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-openclaw",
3
- "version": "2.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
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.348.0",
3
+ "version": "2.349.0",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"