@codyswann/lisa 2.324.0 → 2.325.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 (110) hide show
  1. package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +71 -0
  2. package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +102 -0
  3. package/all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh +220 -0
  4. package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +562 -0
  5. package/all/merge/.claude/settings.json +19 -4
  6. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  7. package/dist/core/upstream-evidence-manifest.js +42 -9
  8. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  9. package/dist/standards/git-state.d.ts.map +1 -1
  10. package/dist/standards/git-state.js +10 -1
  11. package/dist/standards/git-state.js.map +1 -1
  12. package/package.json +1 -1
  13. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  14. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  15. package/plugins/lisa/.codex-plugin/skills/lisa-detect-tooling/SKILL.md +60 -0
  16. package/plugins/lisa/.codex-plugin/skills/lisa-detect-tooling/agents/openai.yaml +4 -0
  17. package/plugins/lisa/.codex-plugin/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +311 -0
  18. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/SKILL.md +18 -2
  19. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +74 -3
  20. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/toolchain.mjs +50 -3
  21. package/plugins/lisa/commands/detect-tooling.md +7 -0
  22. package/plugins/lisa/rules/eager/tracked-work.md +1 -1
  23. package/plugins/lisa/rules/reference/tracked-work.md +1 -1
  24. package/plugins/lisa/skills/lisa-detect-tooling/SKILL.md +60 -0
  25. package/plugins/lisa/skills/lisa-detect-tooling/agents/openai.yaml +4 -0
  26. package/plugins/lisa/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +311 -0
  27. package/plugins/lisa/skills/lisa-setup-remote-env/SKILL.md +18 -2
  28. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +74 -3
  29. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/toolchain.mjs +50 -3
  30. package/plugins/lisa-agy/commands/lisa/detect-tooling.md +7 -0
  31. package/plugins/lisa-agy/plugin.json +1 -1
  32. package/plugins/lisa-agy/skills/lisa-detect-tooling/SKILL.md +60 -0
  33. package/plugins/lisa-agy/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +311 -0
  34. package/plugins/lisa-agy/skills/lisa-setup-remote-env/SKILL.md +18 -2
  35. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +74 -3
  36. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/toolchain.mjs +50 -3
  37. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  39. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  40. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-copilot/commands/lisa/detect-tooling.md +7 -0
  44. package/plugins/lisa-copilot/rules/eager/tracked-work.md +1 -1
  45. package/plugins/lisa-copilot/rules/reference/tracked-work.md +1 -1
  46. package/plugins/lisa-copilot/skills/lisa-detect-tooling/SKILL.md +60 -0
  47. package/plugins/lisa-copilot/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +311 -0
  48. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/SKILL.md +18 -2
  49. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +74 -3
  50. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/toolchain.mjs +50 -3
  51. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-cursor/commands/lisa/detect-tooling.md +7 -0
  53. package/plugins/lisa-cursor/rules/tracked-work-reference.mdc +1 -1
  54. package/plugins/lisa-cursor/rules/tracked-work.mdc +1 -1
  55. package/plugins/lisa-cursor/skills/lisa-detect-tooling/SKILL.md +60 -0
  56. package/plugins/lisa-cursor/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +311 -0
  57. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/SKILL.md +18 -2
  58. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +74 -3
  59. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/toolchain.mjs +50 -3
  60. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-expo-agy/plugin.json +1 -1
  63. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  67. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  68. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  72. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  73. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  77. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  78. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  82. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  83. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  87. package/plugins/lisa-rails-agy/plugin.json +1 -1
  88. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  92. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  93. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  97. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  98. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  100. package/plugins/src/base/commands/detect-tooling.md +7 -0
  101. package/plugins/src/base/rules/eager/tracked-work.md +1 -1
  102. package/plugins/src/base/rules/reference/tracked-work.md +1 -1
  103. package/plugins/src/base/skills/lisa-detect-tooling/SKILL.md +60 -0
  104. package/plugins/src/base/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +311 -0
  105. package/plugins/src/base/skills/lisa-setup-remote-env/SKILL.md +18 -2
  106. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +74 -3
  107. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/toolchain.mjs +50 -3
  108. package/scripts/build-plugins.sh +32 -0
  109. package/scripts/generate-upstream-evidence-manifest.mjs +50 -11
  110. package/scripts/lisa-enforcement-fallback.sh +16 -2
@@ -124,18 +124,65 @@ function planInstallable(tool, found) {
124
124
  };
125
125
  }
126
126
 
127
+ /** Surfaces a manifest entry may name. */
128
+ const KNOWN_SURFACES = new Set(["local", "remote"]);
129
+
130
+ /**
131
+ * Whether a manifest entry applies to the surface being provisioned.
132
+ *
133
+ * One declaration per tool, not one block per surface. Most tools a project
134
+ * needs are needed *everywhere* — a Maestro or Sonar CLI is as required on a
135
+ * laptop as in a container — and duplicated blocks drift, which this repository
136
+ * has paid for more than once. What actually differs between surfaces is the
137
+ * install method and, more importantly, consent: a disposable container may
138
+ * install silently, a developer's machine may not.
139
+ *
140
+ * Omitting `surfaces` means every surface, because that is true of most tools
141
+ * and the failure of forgetting it should be "checked somewhere unnecessary"
142
+ * rather than "silently absent where it was needed".
143
+ * @param {object} tool Manifest entry.
144
+ * @param {string} surface Surface being provisioned.
145
+ * @returns {boolean} Whether this entry applies.
146
+ */
147
+ export function appliesToSurface(tool, surface) {
148
+ const surfaces = tool.surfaces;
149
+ if (surfaces === undefined) return true;
150
+ // A typo must not silently widen scope. Treating any non-array as "omitted"
151
+ // meant `surfaces: "remote"` — an easy thing to write — quietly applied the
152
+ // entry to every surface, which for a platform-specific archive means
153
+ // offering a Linux binary to a laptop. Absent means everywhere; malformed
154
+ // means stop.
155
+ if (!Array.isArray(surfaces)) {
156
+ throw new Error(
157
+ `${tool.name}: surfaces must be an array, got ${typeof surfaces}.\n` +
158
+ `Omit it to mean every surface; write ["remote"] or ["local"] to narrow.`
159
+ );
160
+ }
161
+ if (surfaces.length === 0) return true;
162
+ const unknown = surfaces.filter(entry => !KNOWN_SURFACES.has(entry));
163
+ if (unknown.length > 0) {
164
+ throw new Error(
165
+ `${tool.name}: unknown surface(s) ${unknown.join(", ")}.\n` +
166
+ `Known: ${[...KNOWN_SURFACES].join(", ")}.`
167
+ );
168
+ }
169
+ return surfaces.includes(surface);
170
+ }
171
+
127
172
  /**
128
173
  * Produce the complete plan for a toolchain manifest.
129
174
  * @param {{require?: object[], install?: object[]}} tools Manifest.
130
175
  * @param {(name: string) => {version: string|null, present: boolean}} probe Version probe.
131
176
  * @returns {Array<{name: string, action: string, reason: string}>} Ordered decisions.
132
177
  */
133
- export function planToolchain(tools, probe) {
178
+ export function planToolchain(tools, probe, surface = "remote") {
134
179
  const plan = [];
135
180
  for (const tool of tools.require ?? [])
136
- plan.push(planRequired(tool, probe(tool.name)));
181
+ if (appliesToSurface(tool, surface))
182
+ plan.push(planRequired(tool, probe(tool.name)));
137
183
  for (const tool of tools.install ?? [])
138
- plan.push(planInstallable(tool, probe(tool.name)));
184
+ if (appliesToSurface(tool, surface))
185
+ plan.push(planInstallable(tool, probe(tool.name)));
139
186
  return plan;
140
187
  }
141
188
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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.324.0",
3
+ "version": "2.325.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"
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: "Find the command-line tools this project needs but never declares, and propose pinned manifest entries for them. Reads npm scripts, MCP servers, credential usage notes and quality configuration, subtracts what remoteEnv.tools already covers, and prints proposals with evidence. Writes nothing and installs nothing — a tool reaches a machine only once a human has reviewed a pinned, checksummed entry."
3
+ allowed-tools: ["Skill"]
4
+ argument-hint: "[--json]"
5
+ ---
6
+
7
+ Use the /lisa-detect-tooling skill to find undeclared command-line tooling and propose manifest entries for it. $ARGUMENTS
@@ -2,6 +2,6 @@
2
2
 
3
3
  Before the first durable project mutation (code, tests, config, docs, committed research/plans/findings, commits, or PRs), establish exactly one live tracker leaf through `lisa-track`. Read-only discussion and orientation are exempt only while they produce no durable artifact.
4
4
 
5
- The mandatory order is: live-validate an explicit ref, or conservatively search and create exactly one valid leaf through `lisa-tracker-write` when no unique match exists; idempotently claim it through `lisa-tracker-claim`; then persist and verify the worktree-local binding with `node scripts/lisa-work-item.mjs bind <ref>`. Any tracker, claim, or binding failure blocks durable work.
5
+ The mandatory order is: live-validate an explicit ref, or conservatively search and create exactly one valid leaf through `lisa-tracker-write` when no unique match exists; idempotently claim it through `lisa-tracker-claim`; then persist and verify the worktree-local binding with `node scripts/lisa-work-item.mjs bind <ref>`. A tracker that answers no, and any claim or binding failure, blocks durable work; a tracker that cannot be reached does not block a commit — the offline checks still run, the skip is loud on stderr, and the required `Work-Item Traceability` check re-runs the live checks with credentials before anything merges.
6
6
 
7
7
  Carry that canonical ref through the branch, every ordinary commit's `Work-Item:` trailer, the PR, usage/evidence, and `lisa-tracker-sync`. Hooks and CI never create tickets. Keep the binding through interruptions or blocked outcomes; run `node scripts/lisa-work-item.mjs clear` only after merge/deploy/verification, two-way linkage/evidence, and the tracker item have all reached true terminal completion.
@@ -11,7 +11,7 @@ Use `lisa-track` as the single entry point:
11
11
  3. Idempotently claim the resolved leaf through `lisa-tracker-claim`, which reuses the vendor build-intake claim semantics and post-read verifies the claimed-or-later state.
12
12
  4. Before any durable repository work, persist the canonical reference with `node scripts/lisa-work-item.mjs bind <ref>` and verify the worktree-local binding.
13
13
 
14
- The sequence is strict: **live validate/create -> claim -> bind -> durable work**. A failed tracker read/write, claim, or binding blocks the work. Tracker availability must be proven; tool presence or stale session text is not access.
14
+ The sequence is strict: **live validate/create -> claim -> bind -> durable work**. A tracker answer of no, and any claim or binding failure, blocks the work. A tracker that cannot be reached `gh` absent, or its credential refused — does not block a commit: the offline checks still run, the skip is loud on stderr, and the required `Work-Item Traceability` check re-runs the live checks with credentials before anything merges. Any other tracker failure still blocks. Tool presence or stale session text is not access.
15
15
 
16
16
  ## One canonical identity
17
17
 
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: lisa-detect-tooling
3
+ description: "Find the command-line tools a project needs but never declares, and propose pinned manifest entries for them. Reads npm scripts, MCP servers, credential usage notes and quality configuration, subtracts whatever remoteEnv.tools already covers, and prints proposals with evidence. Writes nothing and installs nothing — a tool reaches a machine only when a human has reviewed a pinned, checksummed entry. Invoked by lisa-setup-remote-env before provisioning, and runnable on its own."
4
+ allowed-tools: ["Bash", "Read", "AskUserQuestion"]
5
+ ---
6
+
7
+ # Detect Tooling
8
+
9
+ Lisa provisions tooling through four unrelated mechanisms, and only one of them puts a binary on `PATH`:
10
+
11
+ | tool | how it arrives | what puts it on PATH |
12
+ | --- | --- | --- |
13
+ | playwright, stryker | npm devDependency from a stack template | nothing — a local `node_modules` binary |
14
+ | maestro | npm **scripts** in the Expo template | **nothing** |
15
+ | sonar | `src/sonar/sonar-installer.ts` | nothing |
16
+ | linear | MCP server | nothing, and it needs browser OAuth |
17
+ | bws, gh | `remoteEnv.tools` — pinned and checksummed | this, and only this |
18
+
19
+ Nothing populates that last row. So a project can ship scripts that invoke `maestro`, wire an MCP server whose CLI it also shells out to, and configure Playwright thresholds, while the manifest that actually provisions binaries stays empty — and every one of those fails at the moment of use rather than at setup.
20
+
21
+ That is the same failure this repository has now paid for twice: `gh` was declared nowhere and a cloud session could not commit; `tar` was needed by an install method and asserted by nothing.
22
+
23
+ ## What it does
24
+
25
+ Reads four signals, subtracts what `remoteEnv.tools` already declares, and prints what is left with the evidence for each:
26
+
27
+ - **npm scripts** that invoke a binary. The strongest signal there is — a script running `maestro test` is the project stating a dependency in executable form. Matched on the script *body*, not its name, because the name is a label.
28
+ - **MCP servers with a CLI equivalent.** An MCP server is not a substitute for the binary: several authenticate by browser OAuth, which a container cannot do, so a project relying on one remotely has *no* integration rather than a degraded one.
29
+ - **Credential usage notes.** A note explaining what a token is for usually names the program that consumes it. `lisa-secrets-access` already exposes these without touching a value, which makes them a first-class input rather than a trick.
30
+ - **Quality configuration**, where a threshold implies the tool that produces it.
31
+
32
+ ## What it will not do
33
+
34
+ **It writes nothing and installs nothing.** Output is a proposal with `<pin>`, `<release url>` and `<sha256>` left for a human.
35
+
36
+ That boundary is the whole design. A tool should reach a machine because someone reviewed a pinned entry with a checksum, never because a detector was confident. Detection is evidence; the manifest is the decision. An auto-writing detector would quietly become a second, unreviewed install path — exactly what `assertPinned` exists to prevent.
37
+
38
+ ## Surfaces
39
+
40
+ One declaration per tool, with an optional `surfaces` list, rather than separate blocks per surface. Most tools are needed *everywhere* — a Maestro or Sonar CLI is as required on a laptop as in a container — and duplicated blocks drift.
41
+
42
+ What genuinely differs is **consent**, not the list:
43
+
44
+ - A remote container is disposable and nobody is watching, so it provisions silently.
45
+ - A developer machine belongs to a person, so `--phase=toolchain` reports what is missing and installs nothing unless `--install-tools` is passed.
46
+
47
+ Omitting `surfaces` means every surface, because that is true of most tools and the cost of forgetting should be a redundant check rather than a silent absence.
48
+
49
+ A platform-specific pin is the exception worth knowing: a Linux release archive must be `surfaces: ["remote"]`, with a matching `require` entry for `local`, so a laptop asserts the tool without being offered a binary it cannot run.
50
+
51
+ ## Usage
52
+
53
+ ```sh
54
+ node scripts/detect-tooling.mjs # human-readable proposals
55
+ node scripts/detect-tooling.mjs --json # machine-readable
56
+ ```
57
+
58
+ Confirm each proposal with the operator, then hand it to them to apply. **This skill does not hold `Edit`**, deliberately: a skill that both decides a tool is needed and writes the entry that installs it is the second unreviewed install path this design exists to avoid. Granting `Edit` while documenting "writes nothing" would have made the prose the only thing stopping it.
59
+
60
+ When a proposal is wrong — the tool is genuinely unused, or arrives another way — say so and move on. A rejected proposal is a normal outcome, not a failure.