@codyswann/lisa 2.336.3 → 2.337.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 (78) hide show
  1. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  2. package/dist/core/upstream-evidence-manifest.js +6 -4
  3. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  4. package/package.json +1 -1
  5. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  6. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  7. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +6 -0
  8. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -3
  9. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/SKILL.md +1 -1
  10. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +54 -6
  11. package/plugins/lisa/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +6 -0
  12. package/plugins/lisa/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -3
  13. package/plugins/lisa/skills/lisa-setup-remote-env/SKILL.md +1 -1
  14. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +54 -6
  15. package/plugins/lisa-agy/plugin.json +1 -1
  16. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +6 -0
  17. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -3
  18. package/plugins/lisa-agy/skills/lisa-setup-remote-env/SKILL.md +1 -1
  19. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +54 -6
  20. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  22. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  23. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +6 -0
  27. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -3
  28. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/SKILL.md +1 -1
  29. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +54 -6
  30. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +6 -0
  32. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -3
  33. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/SKILL.md +1 -1
  34. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +54 -6
  35. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-expo-agy/plugin.json +1 -1
  38. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  42. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  43. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  48. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  53. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  58. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-rails-agy/plugin.json +1 -1
  63. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  67. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  68. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  72. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  73. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/src/base/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +6 -0
  76. package/plugins/src/base/skills/lisa-secrets-access/scripts/surfaces.mjs +22 -3
  77. package/plugins/src/base/skills/lisa-setup-remote-env/SKILL.md +1 -1
  78. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +54 -6
@@ -13,7 +13,7 @@ Prepare a remote surface so a host project can execute there. Today that means *
13
13
  The remote environment's own configuration fields stay **one line into the repository**. Nothing else is pasted into a vendor UI.
14
14
 
15
15
  ```text
16
- setup: n=0; rc=0; seen=""; for f in scripts/lisa-remote-env/setup.sh */scripts/lisa-remote-env/setup.sh "$HOME"/scripts/lisa-remote-env/setup.sh "$HOME"/*/scripts/lisa-remote-env/setup.sh /workspace/scripts/lisa-remote-env/setup.sh /workspace/*/scripts/lisa-remote-env/setup.sh; do [ -f "$f" ] || continue; d=$(cd "$(dirname "$f")" && pwd -P); case " $seen " in *" $d "*) continue;; esac; seen="$seen $d"; n=$((n+1)); bash "$f" || rc=$?; done; [ "$n" -gt 0 ] && exit "$rc"; g=0; for c in ./.git ./*/.git "$HOME"/*/.git /workspace/*/.git; do [ -e "$c" ] && g=1; done; if [ "$g" -eq 1 ]; then echo "lisa-remote-env entrypoint not found, but a checkout is present. PWD=$PWD HOME=$HOME" >&2; ls -1 . "$HOME" /workspace 2>&1 | head -40 >&2; exit 1; fi; if [ -n "${LISA_SECRETS_NAMESPACE:-}" ]; then echo "No checkout; preparing tools and credentials for $LISA_SECRETS_NAMESPACE."; npx -y @codyswann/lisa@latest workstation --provider "${LISA_SECRETS_PROVIDER:-bitwarden}" --yes || true; npx -y @codyswann/lisa@latest remote-env --phase=secrets || true; else echo "No checkout and no LISA_SECRETS_NAMESPACE; nothing to prepare."; fi; exit 0
16
+ setup: n=0; rc=0; seen=""; for f in scripts/lisa-remote-env/setup.sh */scripts/lisa-remote-env/setup.sh "$HOME"/scripts/lisa-remote-env/setup.sh "$HOME"/*/scripts/lisa-remote-env/setup.sh /workspace/scripts/lisa-remote-env/setup.sh /workspace/*/scripts/lisa-remote-env/setup.sh; do [ -f "$f" ] || continue; d=$(cd "$(dirname "$f")" && pwd -P); case " $seen " in *" $d "*) continue;; esac; seen="$seen $d"; n=$((n+1)); bash "$f" || rc=$?; done; [ "$n" -gt 0 ] && exit "$rc"; g=0; for c in ./.git ./*/.git "$HOME"/*/.git /workspace/*/.git; do [ -e "$c" ] && g=1; done; if [ "$g" -eq 1 ]; then echo "lisa-remote-env entrypoint not found, but a checkout is present. PWD=$PWD HOME=$HOME" >&2; ls -1 . "$HOME" /workspace 2>&1 | head -40 >&2; exit 1; fi; ten="${LISA_TENANT:-${LISA_SECRETS_NAMESPACE:-}}"; if [ -n "$ten" ]; then echo "No checkout; preparing tools and credentials for $ten."; tw=0; ts=0; npx -y @codyswann/lisa@2.336.4 workstation --install --provider="${LISA_PROVIDER:-${LISA_SECRETS_PROVIDER:-bitwarden}}" || tw=$?; export PATH="$HOME/.local/bin:$PATH"; npx -y @codyswann/lisa@2.336.4 remote-env --phase=secrets || ts=$?; [ "$tw" -eq 0 ] || echo "SETUP INCOMPLETE: tool install failed (exit $tw). The session will start WITHOUT the pinned tools." >&2; [ "$ts" -eq 0 ] || echo "SETUP INCOMPLETE: secrets did not materialize (exit $ts). The session will start WITHOUT credentials." >&2; else echo "No checkout and no tenant configured; nothing to prepare."; fi; exit 0
17
17
  maintenance: n=0; rc=0; seen=""; for f in scripts/lisa-remote-env/setup.sh */scripts/lisa-remote-env/setup.sh "$HOME"/scripts/lisa-remote-env/setup.sh "$HOME"/*/scripts/lisa-remote-env/setup.sh /workspace/scripts/lisa-remote-env/setup.sh /workspace/*/scripts/lisa-remote-env/setup.sh; do [ -f "$f" ] || continue; d=$(cd "$(dirname "$f")" && pwd -P); case " $seen " in *" $d "*) continue;; esac; seen="$seen $d"; n=$((n+1)); bash "$f" || rc=$?; done; [ "$n" -gt 0 ] || { echo "lisa-remote-env entrypoint not found. PWD=$PWD HOME=$HOME" >&2; ls -1 . "$HOME" /workspace 2>&1 | head -40 >&2; exit 1; }; exit "$rc"
18
18
  ```
19
19
 
@@ -580,6 +580,17 @@ export function installAssets(cwd = process.cwd()) {
580
580
  * Given it, the machine itself is prepared — tools and credentials, no repo
581
581
  * required. Without it there is nothing to prepare and nothing to fail about.
582
582
  *
583
+ * Those two preparation steps report their failures and do not propagate them,
584
+ * which is deliberate and is NOT the same as hiding them. A setup script that
585
+ * exits non-zero stops the session from starting at all, so propagating turns
586
+ * "no credentials this session" into "no session" — strictly worse, and the
587
+ * exact regression that killed every repo-less channel session once already.
588
+ * What was wrong before was the silence: a bare `|| true` let a container come
589
+ * up with a bootstrap token and nothing able to use it, looking identical to
590
+ * success. Each phase's status is now captured and named on stderr, which the
591
+ * vendor surfaces, so the session still starts and the operator can see which
592
+ * half is missing.
593
+ *
583
594
  * Failure prints the layout it found rather than only the path it wanted. This
584
595
  * field lives in a vendor settings box with a slow edit-and-retry loop, and a
585
596
  * miss that reports nothing costs a whole round trip to learn one fact; the
@@ -589,6 +600,33 @@ export function installAssets(cwd = process.cwd()) {
589
600
  * had to get right, in a settings box with no review, no version history and no
590
601
  * test — and the logic it encoded belongs in a file that has all three.
591
602
  */
603
+ /**
604
+ * The exact Lisa the emitted field runs, pinned to the version that emitted it.
605
+ *
606
+ * `@latest` in a field that executes with `npx -y` is remote code execution
607
+ * against a moving target: whatever is newest when the session starts, run as
608
+ * root before Claude launches. That contradicts the rule this project applies
609
+ * to everything else — `assertPinned` refuses a tool whose version is not fixed
610
+ * and checksummed, and it would be strange to hold third-party binaries to a
611
+ * standard Lisa exempts itself from.
612
+ *
613
+ * Pinning to the emitting version keeps the field honest without freezing it:
614
+ * regenerating the field after an upgrade produces a new pin, which is the same
615
+ * "a version bump moves in one reviewed commit" contract as the toolchain.
616
+ * Falling back to `latest` only when the version cannot be read keeps a broken
617
+ * install from turning into an unrunnable field.
618
+ */
619
+ const SELF_SPEC = (() => {
620
+ try {
621
+ const pkg = JSON.parse(
622
+ readFileSync(resolve(HERE, "../../../../../../package.json"), "utf8")
623
+ );
624
+ return pkg.version ? `@codyswann/lisa@${pkg.version}` : "@codyswann/lisa";
625
+ } catch {
626
+ return "@codyswann/lisa";
627
+ }
628
+ })();
629
+
592
630
  export const SETUP_FIELD =
593
631
  'n=0; rc=0; seen=""; ' +
594
632
  "for f in scripts/lisa-remote-env/setup.sh */scripts/lisa-remote-env/setup.sh " +
@@ -603,12 +641,22 @@ export const SETUP_FIELD =
603
641
  'if [ "$g" -eq 1 ]; then ' +
604
642
  'echo "lisa-remote-env entrypoint not found, but a checkout is present. ' +
605
643
  'PWD=$PWD HOME=$HOME" >&2; ls -1 . "$HOME" /workspace 2>&1 | head -40 >&2; exit 1; fi; ' +
606
- 'if [ -n "${LISA_SECRETS_NAMESPACE:-}" ]; then ' +
607
- 'echo "No checkout; preparing tools and credentials for $LISA_SECRETS_NAMESPACE."; ' +
608
- "npx -y @codyswann/lisa@latest workstation " +
609
- '--provider "${LISA_SECRETS_PROVIDER:-bitwarden}" --yes || true; ' +
610
- "npx -y @codyswann/lisa@latest remote-env --phase=secrets || true; " +
611
- 'else echo "No checkout and no LISA_SECRETS_NAMESPACE; nothing to prepare."; fi; ' +
644
+ 'ten="${LISA_TENANT:-${LISA_SECRETS_NAMESPACE:-}}"; ' +
645
+ 'if [ -n "$ten" ]; then ' +
646
+ 'echo "No checkout; preparing tools and credentials for $ten."; ' +
647
+ "tw=0; ts=0; " +
648
+ `npx -y ${SELF_SPEC} workstation --install ` +
649
+ '--provider="${LISA_PROVIDER:-${LISA_SECRETS_PROVIDER:-bitwarden}}" || tw=$?; ' +
650
+ // Exported BEFORE the secrets phase, not after: the toolchain installs into
651
+ // ~/.local/bin, and materialization spawns the provider CLI by name. Ordered
652
+ // the other way it gets ENOENT on a binary that is sitting right there.
653
+ 'export PATH="$HOME/.local/bin:$PATH"; ' +
654
+ `npx -y ${SELF_SPEC} remote-env --phase=secrets || ts=$?; ` +
655
+ '[ "$tw" -eq 0 ] || echo "SETUP INCOMPLETE: tool install failed ' +
656
+ '(exit $tw). The session will start WITHOUT the pinned tools." >&2; ' +
657
+ '[ "$ts" -eq 0 ] || echo "SETUP INCOMPLETE: secrets did not materialize ' +
658
+ '(exit $ts). The session will start WITHOUT credentials." >&2; ' +
659
+ 'else echo "No checkout and no tenant configured; nothing to prepare."; fi; ' +
612
660
  "exit 0";
613
661
 
614
662
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.336.3",
3
+ "version": "2.337.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -151,6 +151,12 @@ export function installProfileSourcing(valuesFile, options = {}) {
151
151
  // poison beats out-shouting it, and it is what lets `--profile agent-dev`
152
152
  // behave here exactly as it does on a developer's machine.
153
153
  `unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN`,
154
+ // The pinned toolchain installs into ~/.local/bin, which is not on PATH in
155
+ // every base image. Without this the tools are present and unfindable:
156
+ // `command -v bws` fails and anything spawning it gets ENOENT, which reads
157
+ // as "nothing was installed" when everything was.
158
+ `case ":$PATH:" in *":$HOME/.local/bin:"*) ;; ` +
159
+ `*) PATH="$HOME/.local/bin:$PATH"; export PATH;; esac`,
154
160
  `if [ -f "${valuesFile}" ]; then`,
155
161
  ` set -a`,
156
162
  ` . "${valuesFile}"`,
@@ -211,17 +211,36 @@ export function readConfig(cwd = process.cwd(), env = process.env) {
211
211
  * @returns {object} A configuration, defaulted where the environment is silent.
212
212
  */
213
213
  function fromEnvironment(env) {
214
- const namespace = (env.LISA_SECRETS_NAMESPACE ?? "").trim();
214
+ // `LISA_TENANT` is the name to prefer, and the reason is not cosmetic.
215
+ //
216
+ // A Claude Tag session's safety classifier refuses a request that so much as
217
+ // NAMES a secret-shaped variable — and it refuses the whole request, so one
218
+ // such name poisons every check bundled with it. `LISA_SECRETS_NAMESPACE`
219
+ // holds a tenant name, not a secret, but it reads like one and an operator
220
+ // cannot ask about it, print it, or debug around it on that surface.
221
+ //
222
+ // The older name keeps working: it is configured in live environments, and
223
+ // breaking those to improve a spelling would be a poor trade.
224
+ const namespace = (
225
+ env.LISA_TENANT ??
226
+ env.LISA_SECRETS_NAMESPACE ??
227
+ ""
228
+ ).trim();
215
229
  if (!namespace) return DEFAULTS;
216
230
 
217
- const provider = (env.LISA_SECRETS_PROVIDER ?? "").trim() || "bitwarden";
231
+ const provider =
232
+ (env.LISA_PROVIDER ?? env.LISA_SECRETS_PROVIDER ?? "").trim() ||
233
+ "bitwarden";
218
234
  return {
219
235
  ...DEFAULTS,
220
236
  provider,
221
237
  namespace: assertNamespace(namespace),
222
238
  bootstrap: {
223
239
  ...DEFAULTS.bootstrap,
224
- key: env.LISA_SECRETS_BOOTSTRAP_KEY ?? `BWS_ACCESS_TOKEN_${namespace}`,
240
+ key:
241
+ env.LISA_BOOTSTRAP_KEY ??
242
+ env.LISA_SECRETS_BOOTSTRAP_KEY ??
243
+ `BWS_ACCESS_TOKEN_${namespace}`,
225
244
  },
226
245
  };
227
246
  }
@@ -13,7 +13,7 @@ Prepare a remote surface so a host project can execute there. Today that means *
13
13
  The remote environment's own configuration fields stay **one line into the repository**. Nothing else is pasted into a vendor UI.
14
14
 
15
15
  ```text
16
- setup: n=0; rc=0; seen=""; for f in scripts/lisa-remote-env/setup.sh */scripts/lisa-remote-env/setup.sh "$HOME"/scripts/lisa-remote-env/setup.sh "$HOME"/*/scripts/lisa-remote-env/setup.sh /workspace/scripts/lisa-remote-env/setup.sh /workspace/*/scripts/lisa-remote-env/setup.sh; do [ -f "$f" ] || continue; d=$(cd "$(dirname "$f")" && pwd -P); case " $seen " in *" $d "*) continue;; esac; seen="$seen $d"; n=$((n+1)); bash "$f" || rc=$?; done; [ "$n" -gt 0 ] && exit "$rc"; g=0; for c in ./.git ./*/.git "$HOME"/*/.git /workspace/*/.git; do [ -e "$c" ] && g=1; done; if [ "$g" -eq 1 ]; then echo "lisa-remote-env entrypoint not found, but a checkout is present. PWD=$PWD HOME=$HOME" >&2; ls -1 . "$HOME" /workspace 2>&1 | head -40 >&2; exit 1; fi; if [ -n "${LISA_SECRETS_NAMESPACE:-}" ]; then echo "No checkout; preparing tools and credentials for $LISA_SECRETS_NAMESPACE."; npx -y @codyswann/lisa@latest workstation --provider "${LISA_SECRETS_PROVIDER:-bitwarden}" --yes || true; npx -y @codyswann/lisa@latest remote-env --phase=secrets || true; else echo "No checkout and no LISA_SECRETS_NAMESPACE; nothing to prepare."; fi; exit 0
16
+ setup: n=0; rc=0; seen=""; for f in scripts/lisa-remote-env/setup.sh */scripts/lisa-remote-env/setup.sh "$HOME"/scripts/lisa-remote-env/setup.sh "$HOME"/*/scripts/lisa-remote-env/setup.sh /workspace/scripts/lisa-remote-env/setup.sh /workspace/*/scripts/lisa-remote-env/setup.sh; do [ -f "$f" ] || continue; d=$(cd "$(dirname "$f")" && pwd -P); case " $seen " in *" $d "*) continue;; esac; seen="$seen $d"; n=$((n+1)); bash "$f" || rc=$?; done; [ "$n" -gt 0 ] && exit "$rc"; g=0; for c in ./.git ./*/.git "$HOME"/*/.git /workspace/*/.git; do [ -e "$c" ] && g=1; done; if [ "$g" -eq 1 ]; then echo "lisa-remote-env entrypoint not found, but a checkout is present. PWD=$PWD HOME=$HOME" >&2; ls -1 . "$HOME" /workspace 2>&1 | head -40 >&2; exit 1; fi; ten="${LISA_TENANT:-${LISA_SECRETS_NAMESPACE:-}}"; if [ -n "$ten" ]; then echo "No checkout; preparing tools and credentials for $ten."; tw=0; ts=0; npx -y @codyswann/lisa@2.336.4 workstation --install --provider="${LISA_PROVIDER:-${LISA_SECRETS_PROVIDER:-bitwarden}}" || tw=$?; export PATH="$HOME/.local/bin:$PATH"; npx -y @codyswann/lisa@2.336.4 remote-env --phase=secrets || ts=$?; [ "$tw" -eq 0 ] || echo "SETUP INCOMPLETE: tool install failed (exit $tw). The session will start WITHOUT the pinned tools." >&2; [ "$ts" -eq 0 ] || echo "SETUP INCOMPLETE: secrets did not materialize (exit $ts). The session will start WITHOUT credentials." >&2; else echo "No checkout and no tenant configured; nothing to prepare."; fi; exit 0
17
17
  maintenance: n=0; rc=0; seen=""; for f in scripts/lisa-remote-env/setup.sh */scripts/lisa-remote-env/setup.sh "$HOME"/scripts/lisa-remote-env/setup.sh "$HOME"/*/scripts/lisa-remote-env/setup.sh /workspace/scripts/lisa-remote-env/setup.sh /workspace/*/scripts/lisa-remote-env/setup.sh; do [ -f "$f" ] || continue; d=$(cd "$(dirname "$f")" && pwd -P); case " $seen " in *" $d "*) continue;; esac; seen="$seen $d"; n=$((n+1)); bash "$f" || rc=$?; done; [ "$n" -gt 0 ] || { echo "lisa-remote-env entrypoint not found. PWD=$PWD HOME=$HOME" >&2; ls -1 . "$HOME" /workspace 2>&1 | head -40 >&2; exit 1; }; exit "$rc"
18
18
  ```
19
19
 
@@ -580,6 +580,17 @@ export function installAssets(cwd = process.cwd()) {
580
580
  * Given it, the machine itself is prepared — tools and credentials, no repo
581
581
  * required. Without it there is nothing to prepare and nothing to fail about.
582
582
  *
583
+ * Those two preparation steps report their failures and do not propagate them,
584
+ * which is deliberate and is NOT the same as hiding them. A setup script that
585
+ * exits non-zero stops the session from starting at all, so propagating turns
586
+ * "no credentials this session" into "no session" — strictly worse, and the
587
+ * exact regression that killed every repo-less channel session once already.
588
+ * What was wrong before was the silence: a bare `|| true` let a container come
589
+ * up with a bootstrap token and nothing able to use it, looking identical to
590
+ * success. Each phase's status is now captured and named on stderr, which the
591
+ * vendor surfaces, so the session still starts and the operator can see which
592
+ * half is missing.
593
+ *
583
594
  * Failure prints the layout it found rather than only the path it wanted. This
584
595
  * field lives in a vendor settings box with a slow edit-and-retry loop, and a
585
596
  * miss that reports nothing costs a whole round trip to learn one fact; the
@@ -589,6 +600,33 @@ export function installAssets(cwd = process.cwd()) {
589
600
  * had to get right, in a settings box with no review, no version history and no
590
601
  * test — and the logic it encoded belongs in a file that has all three.
591
602
  */
603
+ /**
604
+ * The exact Lisa the emitted field runs, pinned to the version that emitted it.
605
+ *
606
+ * `@latest` in a field that executes with `npx -y` is remote code execution
607
+ * against a moving target: whatever is newest when the session starts, run as
608
+ * root before Claude launches. That contradicts the rule this project applies
609
+ * to everything else — `assertPinned` refuses a tool whose version is not fixed
610
+ * and checksummed, and it would be strange to hold third-party binaries to a
611
+ * standard Lisa exempts itself from.
612
+ *
613
+ * Pinning to the emitting version keeps the field honest without freezing it:
614
+ * regenerating the field after an upgrade produces a new pin, which is the same
615
+ * "a version bump moves in one reviewed commit" contract as the toolchain.
616
+ * Falling back to `latest` only when the version cannot be read keeps a broken
617
+ * install from turning into an unrunnable field.
618
+ */
619
+ const SELF_SPEC = (() => {
620
+ try {
621
+ const pkg = JSON.parse(
622
+ readFileSync(resolve(HERE, "../../../../../../package.json"), "utf8")
623
+ );
624
+ return pkg.version ? `@codyswann/lisa@${pkg.version}` : "@codyswann/lisa";
625
+ } catch {
626
+ return "@codyswann/lisa";
627
+ }
628
+ })();
629
+
592
630
  export const SETUP_FIELD =
593
631
  'n=0; rc=0; seen=""; ' +
594
632
  "for f in scripts/lisa-remote-env/setup.sh */scripts/lisa-remote-env/setup.sh " +
@@ -603,12 +641,22 @@ export const SETUP_FIELD =
603
641
  'if [ "$g" -eq 1 ]; then ' +
604
642
  'echo "lisa-remote-env entrypoint not found, but a checkout is present. ' +
605
643
  'PWD=$PWD HOME=$HOME" >&2; ls -1 . "$HOME" /workspace 2>&1 | head -40 >&2; exit 1; fi; ' +
606
- 'if [ -n "${LISA_SECRETS_NAMESPACE:-}" ]; then ' +
607
- 'echo "No checkout; preparing tools and credentials for $LISA_SECRETS_NAMESPACE."; ' +
608
- "npx -y @codyswann/lisa@latest workstation " +
609
- '--provider "${LISA_SECRETS_PROVIDER:-bitwarden}" --yes || true; ' +
610
- "npx -y @codyswann/lisa@latest remote-env --phase=secrets || true; " +
611
- 'else echo "No checkout and no LISA_SECRETS_NAMESPACE; nothing to prepare."; fi; ' +
644
+ 'ten="${LISA_TENANT:-${LISA_SECRETS_NAMESPACE:-}}"; ' +
645
+ 'if [ -n "$ten" ]; then ' +
646
+ 'echo "No checkout; preparing tools and credentials for $ten."; ' +
647
+ "tw=0; ts=0; " +
648
+ `npx -y ${SELF_SPEC} workstation --install ` +
649
+ '--provider="${LISA_PROVIDER:-${LISA_SECRETS_PROVIDER:-bitwarden}}" || tw=$?; ' +
650
+ // Exported BEFORE the secrets phase, not after: the toolchain installs into
651
+ // ~/.local/bin, and materialization spawns the provider CLI by name. Ordered
652
+ // the other way it gets ENOENT on a binary that is sitting right there.
653
+ 'export PATH="$HOME/.local/bin:$PATH"; ' +
654
+ `npx -y ${SELF_SPEC} remote-env --phase=secrets || ts=$?; ` +
655
+ '[ "$tw" -eq 0 ] || echo "SETUP INCOMPLETE: tool install failed ' +
656
+ '(exit $tw). The session will start WITHOUT the pinned tools." >&2; ' +
657
+ '[ "$ts" -eq 0 ] || echo "SETUP INCOMPLETE: secrets did not materialize ' +
658
+ '(exit $ts). The session will start WITHOUT credentials." >&2; ' +
659
+ 'else echo "No checkout and no tenant configured; nothing to prepare."; fi; ' +
612
660
  "exit 0";
613
661
 
614
662
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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.336.3",
3
+ "version": "2.337.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-rails",
3
- "version": "2.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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.336.3",
3
+ "version": "2.337.0",
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"