@codyswann/lisa 4.57.3 → 4.57.4
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.
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +2 -1
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +44 -19
- package/plugins/lisa/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +44 -19
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +44 -19
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +44 -19
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +44 -19
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +44 -19
package/package.json
CHANGED
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
"zod-validation-error": "^4.0.0"
|
|
188
188
|
},
|
|
189
189
|
"name": "@codyswann/lisa",
|
|
190
|
-
"version": "4.57.
|
|
190
|
+
"version": "4.57.4",
|
|
191
191
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
192
192
|
"main": "dist/index.js",
|
|
193
193
|
"exports": {
|
|
@@ -336,7 +336,7 @@
|
|
|
336
336
|
"test": "tests"
|
|
337
337
|
},
|
|
338
338
|
"types": "./dist/index.d.ts",
|
|
339
|
-
"lisaReleaseCommit": "
|
|
340
|
-
"gitHead": "
|
|
341
|
-
"lisaReleaseTag": "v4.57.
|
|
339
|
+
"lisaReleaseCommit": "f6f450438d19c364ff02140f32058a0b8c27f764",
|
|
340
|
+
"gitHead": "f6f450438d19c364ff02140f32058a0b8c27f764",
|
|
341
|
+
"lisaReleaseTag": "v4.57.4"
|
|
342
342
|
}
|
|
@@ -232,8 +232,22 @@ export function preflightTools(
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Format a count with the appropriate noun phrase.
|
|
237
|
+
* @param {number} n How many.
|
|
238
|
+
* @param {string} one Singular noun phrase.
|
|
239
|
+
* @param {string} many Plural noun phrase.
|
|
240
|
+
* @returns {string} A counted phrase such as "1 tool" or "3 tools".
|
|
241
|
+
*/
|
|
242
|
+
function count(n, one, many) {
|
|
243
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
244
|
+
}
|
|
245
|
+
|
|
235
246
|
/**
|
|
236
247
|
* Render a verdict for whoever has to act on it.
|
|
248
|
+
*
|
|
249
|
+
* Put blockers first and scope the stop instruction to that section. The
|
|
250
|
+
* separate installable section must not send usable work to the blocked lane.
|
|
237
251
|
* @param {object} result A {@link preflightTools} result.
|
|
238
252
|
* @returns {string} Operator-readable report, empty when nothing needs saying.
|
|
239
253
|
*/
|
|
@@ -243,42 +257,53 @@ export function reportTools(result) {
|
|
|
243
257
|
// The header tracks the exit code. Only a blocked tool is a failure — one
|
|
244
258
|
// Lisa can install is an action with a command attached, and calling that
|
|
245
259
|
// "FAILED" while exiting zero teaches readers that the word means nothing.
|
|
260
|
+
const blocking = count(result.blocked.length, "tool blocks", "tools block");
|
|
261
|
+
const spare = result.installable.length
|
|
262
|
+
? ` ${result.installable.length} more Lisa can install for you.`
|
|
263
|
+
: ``;
|
|
246
264
|
const header = () => {
|
|
247
|
-
if (result.blocked.length)
|
|
265
|
+
if (result.blocked.length)
|
|
266
|
+
return `Tooling preflight FAILED — ${blocking}.${spare}`;
|
|
248
267
|
if (result.installable.length)
|
|
249
|
-
return
|
|
268
|
+
return (
|
|
269
|
+
`Tooling preflight — action available. Nothing blocks;` +
|
|
270
|
+
` ${count(result.installable.length, "tool", "tools")} Lisa can` +
|
|
271
|
+
` install for you.`
|
|
272
|
+
);
|
|
250
273
|
// Nothing to do and nothing to fix; the note below is the whole message.
|
|
251
|
-
return
|
|
274
|
+
return `Tooling preflight passed, with a note.`;
|
|
252
275
|
};
|
|
253
276
|
const lines = [header()];
|
|
254
|
-
if (result.installable.length) {
|
|
255
|
-
lines.push(
|
|
256
|
-
``,
|
|
257
|
-
`Lisa can install these itself — they are pinned and checksummed.`,
|
|
258
|
-
`Run /lisa:setup:local-env to place them:`,
|
|
259
|
-
``
|
|
260
|
-
);
|
|
261
|
-
for (const step of result.installable) {
|
|
262
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
277
|
if (result.blocked.length) {
|
|
266
278
|
lines.push(
|
|
267
279
|
``,
|
|
268
|
-
`
|
|
280
|
+
`STOP — these block the work. Lisa has no pinned artifact it can place,`,
|
|
281
|
+
`so it cannot fix them for you:`,
|
|
269
282
|
``
|
|
270
283
|
);
|
|
271
284
|
for (const step of result.blocked) {
|
|
272
285
|
const why = result.reasons[step.name];
|
|
273
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
274
|
-
if (why) lines.push(`
|
|
286
|
+
lines.push(` [BLOCKED] ${step.name} — ${step.reason}`);
|
|
287
|
+
if (why) lines.push(` required because ${why}`);
|
|
275
288
|
}
|
|
276
289
|
lines.push(
|
|
277
290
|
``,
|
|
278
|
-
`Work needing one of
|
|
279
|
-
`blocked
|
|
291
|
+
` Work needing one of the tools above cannot be completed. Route that`,
|
|
292
|
+
` item to blocked citing that tool, rather than claiming it and`,
|
|
293
|
+
` stopping partway. Nothing else in this report is a reason to stop.`
|
|
280
294
|
);
|
|
281
295
|
}
|
|
296
|
+
if (result.installable.length) {
|
|
297
|
+
lines.push(
|
|
298
|
+
``,
|
|
299
|
+
`NOT A BLOCKER — Lisa can install these itself; they are pinned and`,
|
|
300
|
+
`checksummed. Run /lisa:setup:local-env to place them:`,
|
|
301
|
+
``
|
|
302
|
+
);
|
|
303
|
+
for (const step of result.installable) {
|
|
304
|
+
lines.push(` [INSTALLABLE] ${step.name} — ${step.reason}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
282
307
|
if (result.unverified.length) {
|
|
283
308
|
lines.push(
|
|
284
309
|
``,
|
|
@@ -232,8 +232,22 @@ export function preflightTools(
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Format a count with the appropriate noun phrase.
|
|
237
|
+
* @param {number} n How many.
|
|
238
|
+
* @param {string} one Singular noun phrase.
|
|
239
|
+
* @param {string} many Plural noun phrase.
|
|
240
|
+
* @returns {string} A counted phrase such as "1 tool" or "3 tools".
|
|
241
|
+
*/
|
|
242
|
+
function count(n, one, many) {
|
|
243
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
244
|
+
}
|
|
245
|
+
|
|
235
246
|
/**
|
|
236
247
|
* Render a verdict for whoever has to act on it.
|
|
248
|
+
*
|
|
249
|
+
* Put blockers first and scope the stop instruction to that section. The
|
|
250
|
+
* separate installable section must not send usable work to the blocked lane.
|
|
237
251
|
* @param {object} result A {@link preflightTools} result.
|
|
238
252
|
* @returns {string} Operator-readable report, empty when nothing needs saying.
|
|
239
253
|
*/
|
|
@@ -243,42 +257,53 @@ export function reportTools(result) {
|
|
|
243
257
|
// The header tracks the exit code. Only a blocked tool is a failure — one
|
|
244
258
|
// Lisa can install is an action with a command attached, and calling that
|
|
245
259
|
// "FAILED" while exiting zero teaches readers that the word means nothing.
|
|
260
|
+
const blocking = count(result.blocked.length, "tool blocks", "tools block");
|
|
261
|
+
const spare = result.installable.length
|
|
262
|
+
? ` ${result.installable.length} more Lisa can install for you.`
|
|
263
|
+
: ``;
|
|
246
264
|
const header = () => {
|
|
247
|
-
if (result.blocked.length)
|
|
265
|
+
if (result.blocked.length)
|
|
266
|
+
return `Tooling preflight FAILED — ${blocking}.${spare}`;
|
|
248
267
|
if (result.installable.length)
|
|
249
|
-
return
|
|
268
|
+
return (
|
|
269
|
+
`Tooling preflight — action available. Nothing blocks;` +
|
|
270
|
+
` ${count(result.installable.length, "tool", "tools")} Lisa can` +
|
|
271
|
+
` install for you.`
|
|
272
|
+
);
|
|
250
273
|
// Nothing to do and nothing to fix; the note below is the whole message.
|
|
251
|
-
return
|
|
274
|
+
return `Tooling preflight passed, with a note.`;
|
|
252
275
|
};
|
|
253
276
|
const lines = [header()];
|
|
254
|
-
if (result.installable.length) {
|
|
255
|
-
lines.push(
|
|
256
|
-
``,
|
|
257
|
-
`Lisa can install these itself — they are pinned and checksummed.`,
|
|
258
|
-
`Run /lisa:setup:local-env to place them:`,
|
|
259
|
-
``
|
|
260
|
-
);
|
|
261
|
-
for (const step of result.installable) {
|
|
262
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
277
|
if (result.blocked.length) {
|
|
266
278
|
lines.push(
|
|
267
279
|
``,
|
|
268
|
-
`
|
|
280
|
+
`STOP — these block the work. Lisa has no pinned artifact it can place,`,
|
|
281
|
+
`so it cannot fix them for you:`,
|
|
269
282
|
``
|
|
270
283
|
);
|
|
271
284
|
for (const step of result.blocked) {
|
|
272
285
|
const why = result.reasons[step.name];
|
|
273
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
274
|
-
if (why) lines.push(`
|
|
286
|
+
lines.push(` [BLOCKED] ${step.name} — ${step.reason}`);
|
|
287
|
+
if (why) lines.push(` required because ${why}`);
|
|
275
288
|
}
|
|
276
289
|
lines.push(
|
|
277
290
|
``,
|
|
278
|
-
`Work needing one of
|
|
279
|
-
`blocked
|
|
291
|
+
` Work needing one of the tools above cannot be completed. Route that`,
|
|
292
|
+
` item to blocked citing that tool, rather than claiming it and`,
|
|
293
|
+
` stopping partway. Nothing else in this report is a reason to stop.`
|
|
280
294
|
);
|
|
281
295
|
}
|
|
296
|
+
if (result.installable.length) {
|
|
297
|
+
lines.push(
|
|
298
|
+
``,
|
|
299
|
+
`NOT A BLOCKER — Lisa can install these itself; they are pinned and`,
|
|
300
|
+
`checksummed. Run /lisa:setup:local-env to place them:`,
|
|
301
|
+
``
|
|
302
|
+
);
|
|
303
|
+
for (const step of result.installable) {
|
|
304
|
+
lines.push(` [INSTALLABLE] ${step.name} — ${step.reason}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
282
307
|
if (result.unverified.length) {
|
|
283
308
|
lines.push(
|
|
284
309
|
``,
|
|
@@ -232,8 +232,22 @@ export function preflightTools(
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Format a count with the appropriate noun phrase.
|
|
237
|
+
* @param {number} n How many.
|
|
238
|
+
* @param {string} one Singular noun phrase.
|
|
239
|
+
* @param {string} many Plural noun phrase.
|
|
240
|
+
* @returns {string} A counted phrase such as "1 tool" or "3 tools".
|
|
241
|
+
*/
|
|
242
|
+
function count(n, one, many) {
|
|
243
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
244
|
+
}
|
|
245
|
+
|
|
235
246
|
/**
|
|
236
247
|
* Render a verdict for whoever has to act on it.
|
|
248
|
+
*
|
|
249
|
+
* Put blockers first and scope the stop instruction to that section. The
|
|
250
|
+
* separate installable section must not send usable work to the blocked lane.
|
|
237
251
|
* @param {object} result A {@link preflightTools} result.
|
|
238
252
|
* @returns {string} Operator-readable report, empty when nothing needs saying.
|
|
239
253
|
*/
|
|
@@ -243,42 +257,53 @@ export function reportTools(result) {
|
|
|
243
257
|
// The header tracks the exit code. Only a blocked tool is a failure — one
|
|
244
258
|
// Lisa can install is an action with a command attached, and calling that
|
|
245
259
|
// "FAILED" while exiting zero teaches readers that the word means nothing.
|
|
260
|
+
const blocking = count(result.blocked.length, "tool blocks", "tools block");
|
|
261
|
+
const spare = result.installable.length
|
|
262
|
+
? ` ${result.installable.length} more Lisa can install for you.`
|
|
263
|
+
: ``;
|
|
246
264
|
const header = () => {
|
|
247
|
-
if (result.blocked.length)
|
|
265
|
+
if (result.blocked.length)
|
|
266
|
+
return `Tooling preflight FAILED — ${blocking}.${spare}`;
|
|
248
267
|
if (result.installable.length)
|
|
249
|
-
return
|
|
268
|
+
return (
|
|
269
|
+
`Tooling preflight — action available. Nothing blocks;` +
|
|
270
|
+
` ${count(result.installable.length, "tool", "tools")} Lisa can` +
|
|
271
|
+
` install for you.`
|
|
272
|
+
);
|
|
250
273
|
// Nothing to do and nothing to fix; the note below is the whole message.
|
|
251
|
-
return
|
|
274
|
+
return `Tooling preflight passed, with a note.`;
|
|
252
275
|
};
|
|
253
276
|
const lines = [header()];
|
|
254
|
-
if (result.installable.length) {
|
|
255
|
-
lines.push(
|
|
256
|
-
``,
|
|
257
|
-
`Lisa can install these itself — they are pinned and checksummed.`,
|
|
258
|
-
`Run /lisa:setup:local-env to place them:`,
|
|
259
|
-
``
|
|
260
|
-
);
|
|
261
|
-
for (const step of result.installable) {
|
|
262
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
277
|
if (result.blocked.length) {
|
|
266
278
|
lines.push(
|
|
267
279
|
``,
|
|
268
|
-
`
|
|
280
|
+
`STOP — these block the work. Lisa has no pinned artifact it can place,`,
|
|
281
|
+
`so it cannot fix them for you:`,
|
|
269
282
|
``
|
|
270
283
|
);
|
|
271
284
|
for (const step of result.blocked) {
|
|
272
285
|
const why = result.reasons[step.name];
|
|
273
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
274
|
-
if (why) lines.push(`
|
|
286
|
+
lines.push(` [BLOCKED] ${step.name} — ${step.reason}`);
|
|
287
|
+
if (why) lines.push(` required because ${why}`);
|
|
275
288
|
}
|
|
276
289
|
lines.push(
|
|
277
290
|
``,
|
|
278
|
-
`Work needing one of
|
|
279
|
-
`blocked
|
|
291
|
+
` Work needing one of the tools above cannot be completed. Route that`,
|
|
292
|
+
` item to blocked citing that tool, rather than claiming it and`,
|
|
293
|
+
` stopping partway. Nothing else in this report is a reason to stop.`
|
|
280
294
|
);
|
|
281
295
|
}
|
|
296
|
+
if (result.installable.length) {
|
|
297
|
+
lines.push(
|
|
298
|
+
``,
|
|
299
|
+
`NOT A BLOCKER — Lisa can install these itself; they are pinned and`,
|
|
300
|
+
`checksummed. Run /lisa:setup:local-env to place them:`,
|
|
301
|
+
``
|
|
302
|
+
);
|
|
303
|
+
for (const step of result.installable) {
|
|
304
|
+
lines.push(` [INSTALLABLE] ${step.name} — ${step.reason}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
282
307
|
if (result.unverified.length) {
|
|
283
308
|
lines.push(
|
|
284
309
|
``,
|
|
@@ -232,8 +232,22 @@ export function preflightTools(
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Format a count with the appropriate noun phrase.
|
|
237
|
+
* @param {number} n How many.
|
|
238
|
+
* @param {string} one Singular noun phrase.
|
|
239
|
+
* @param {string} many Plural noun phrase.
|
|
240
|
+
* @returns {string} A counted phrase such as "1 tool" or "3 tools".
|
|
241
|
+
*/
|
|
242
|
+
function count(n, one, many) {
|
|
243
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
244
|
+
}
|
|
245
|
+
|
|
235
246
|
/**
|
|
236
247
|
* Render a verdict for whoever has to act on it.
|
|
248
|
+
*
|
|
249
|
+
* Put blockers first and scope the stop instruction to that section. The
|
|
250
|
+
* separate installable section must not send usable work to the blocked lane.
|
|
237
251
|
* @param {object} result A {@link preflightTools} result.
|
|
238
252
|
* @returns {string} Operator-readable report, empty when nothing needs saying.
|
|
239
253
|
*/
|
|
@@ -243,42 +257,53 @@ export function reportTools(result) {
|
|
|
243
257
|
// The header tracks the exit code. Only a blocked tool is a failure — one
|
|
244
258
|
// Lisa can install is an action with a command attached, and calling that
|
|
245
259
|
// "FAILED" while exiting zero teaches readers that the word means nothing.
|
|
260
|
+
const blocking = count(result.blocked.length, "tool blocks", "tools block");
|
|
261
|
+
const spare = result.installable.length
|
|
262
|
+
? ` ${result.installable.length} more Lisa can install for you.`
|
|
263
|
+
: ``;
|
|
246
264
|
const header = () => {
|
|
247
|
-
if (result.blocked.length)
|
|
265
|
+
if (result.blocked.length)
|
|
266
|
+
return `Tooling preflight FAILED — ${blocking}.${spare}`;
|
|
248
267
|
if (result.installable.length)
|
|
249
|
-
return
|
|
268
|
+
return (
|
|
269
|
+
`Tooling preflight — action available. Nothing blocks;` +
|
|
270
|
+
` ${count(result.installable.length, "tool", "tools")} Lisa can` +
|
|
271
|
+
` install for you.`
|
|
272
|
+
);
|
|
250
273
|
// Nothing to do and nothing to fix; the note below is the whole message.
|
|
251
|
-
return
|
|
274
|
+
return `Tooling preflight passed, with a note.`;
|
|
252
275
|
};
|
|
253
276
|
const lines = [header()];
|
|
254
|
-
if (result.installable.length) {
|
|
255
|
-
lines.push(
|
|
256
|
-
``,
|
|
257
|
-
`Lisa can install these itself — they are pinned and checksummed.`,
|
|
258
|
-
`Run /lisa:setup:local-env to place them:`,
|
|
259
|
-
``
|
|
260
|
-
);
|
|
261
|
-
for (const step of result.installable) {
|
|
262
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
277
|
if (result.blocked.length) {
|
|
266
278
|
lines.push(
|
|
267
279
|
``,
|
|
268
|
-
`
|
|
280
|
+
`STOP — these block the work. Lisa has no pinned artifact it can place,`,
|
|
281
|
+
`so it cannot fix them for you:`,
|
|
269
282
|
``
|
|
270
283
|
);
|
|
271
284
|
for (const step of result.blocked) {
|
|
272
285
|
const why = result.reasons[step.name];
|
|
273
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
274
|
-
if (why) lines.push(`
|
|
286
|
+
lines.push(` [BLOCKED] ${step.name} — ${step.reason}`);
|
|
287
|
+
if (why) lines.push(` required because ${why}`);
|
|
275
288
|
}
|
|
276
289
|
lines.push(
|
|
277
290
|
``,
|
|
278
|
-
`Work needing one of
|
|
279
|
-
`blocked
|
|
291
|
+
` Work needing one of the tools above cannot be completed. Route that`,
|
|
292
|
+
` item to blocked citing that tool, rather than claiming it and`,
|
|
293
|
+
` stopping partway. Nothing else in this report is a reason to stop.`
|
|
280
294
|
);
|
|
281
295
|
}
|
|
296
|
+
if (result.installable.length) {
|
|
297
|
+
lines.push(
|
|
298
|
+
``,
|
|
299
|
+
`NOT A BLOCKER — Lisa can install these itself; they are pinned and`,
|
|
300
|
+
`checksummed. Run /lisa:setup:local-env to place them:`,
|
|
301
|
+
``
|
|
302
|
+
);
|
|
303
|
+
for (const step of result.installable) {
|
|
304
|
+
lines.push(` [INSTALLABLE] ${step.name} — ${step.reason}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
282
307
|
if (result.unverified.length) {
|
|
283
308
|
lines.push(
|
|
284
309
|
``,
|
|
@@ -232,8 +232,22 @@ export function preflightTools(
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Format a count with the appropriate noun phrase.
|
|
237
|
+
* @param {number} n How many.
|
|
238
|
+
* @param {string} one Singular noun phrase.
|
|
239
|
+
* @param {string} many Plural noun phrase.
|
|
240
|
+
* @returns {string} A counted phrase such as "1 tool" or "3 tools".
|
|
241
|
+
*/
|
|
242
|
+
function count(n, one, many) {
|
|
243
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
244
|
+
}
|
|
245
|
+
|
|
235
246
|
/**
|
|
236
247
|
* Render a verdict for whoever has to act on it.
|
|
248
|
+
*
|
|
249
|
+
* Put blockers first and scope the stop instruction to that section. The
|
|
250
|
+
* separate installable section must not send usable work to the blocked lane.
|
|
237
251
|
* @param {object} result A {@link preflightTools} result.
|
|
238
252
|
* @returns {string} Operator-readable report, empty when nothing needs saying.
|
|
239
253
|
*/
|
|
@@ -243,42 +257,53 @@ export function reportTools(result) {
|
|
|
243
257
|
// The header tracks the exit code. Only a blocked tool is a failure — one
|
|
244
258
|
// Lisa can install is an action with a command attached, and calling that
|
|
245
259
|
// "FAILED" while exiting zero teaches readers that the word means nothing.
|
|
260
|
+
const blocking = count(result.blocked.length, "tool blocks", "tools block");
|
|
261
|
+
const spare = result.installable.length
|
|
262
|
+
? ` ${result.installable.length} more Lisa can install for you.`
|
|
263
|
+
: ``;
|
|
246
264
|
const header = () => {
|
|
247
|
-
if (result.blocked.length)
|
|
265
|
+
if (result.blocked.length)
|
|
266
|
+
return `Tooling preflight FAILED — ${blocking}.${spare}`;
|
|
248
267
|
if (result.installable.length)
|
|
249
|
-
return
|
|
268
|
+
return (
|
|
269
|
+
`Tooling preflight — action available. Nothing blocks;` +
|
|
270
|
+
` ${count(result.installable.length, "tool", "tools")} Lisa can` +
|
|
271
|
+
` install for you.`
|
|
272
|
+
);
|
|
250
273
|
// Nothing to do and nothing to fix; the note below is the whole message.
|
|
251
|
-
return
|
|
274
|
+
return `Tooling preflight passed, with a note.`;
|
|
252
275
|
};
|
|
253
276
|
const lines = [header()];
|
|
254
|
-
if (result.installable.length) {
|
|
255
|
-
lines.push(
|
|
256
|
-
``,
|
|
257
|
-
`Lisa can install these itself — they are pinned and checksummed.`,
|
|
258
|
-
`Run /lisa:setup:local-env to place them:`,
|
|
259
|
-
``
|
|
260
|
-
);
|
|
261
|
-
for (const step of result.installable) {
|
|
262
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
277
|
if (result.blocked.length) {
|
|
266
278
|
lines.push(
|
|
267
279
|
``,
|
|
268
|
-
`
|
|
280
|
+
`STOP — these block the work. Lisa has no pinned artifact it can place,`,
|
|
281
|
+
`so it cannot fix them for you:`,
|
|
269
282
|
``
|
|
270
283
|
);
|
|
271
284
|
for (const step of result.blocked) {
|
|
272
285
|
const why = result.reasons[step.name];
|
|
273
|
-
lines.push(` ${step.name} — ${step.reason}`);
|
|
274
|
-
if (why) lines.push(`
|
|
286
|
+
lines.push(` [BLOCKED] ${step.name} — ${step.reason}`);
|
|
287
|
+
if (why) lines.push(` required because ${why}`);
|
|
275
288
|
}
|
|
276
289
|
lines.push(
|
|
277
290
|
``,
|
|
278
|
-
`Work needing one of
|
|
279
|
-
`blocked
|
|
291
|
+
` Work needing one of the tools above cannot be completed. Route that`,
|
|
292
|
+
` item to blocked citing that tool, rather than claiming it and`,
|
|
293
|
+
` stopping partway. Nothing else in this report is a reason to stop.`
|
|
280
294
|
);
|
|
281
295
|
}
|
|
296
|
+
if (result.installable.length) {
|
|
297
|
+
lines.push(
|
|
298
|
+
``,
|
|
299
|
+
`NOT A BLOCKER — Lisa can install these itself; they are pinned and`,
|
|
300
|
+
`checksummed. Run /lisa:setup:local-env to place them:`,
|
|
301
|
+
``
|
|
302
|
+
);
|
|
303
|
+
for (const step of result.installable) {
|
|
304
|
+
lines.push(` [INSTALLABLE] ${step.name} — ${step.reason}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
282
307
|
if (result.unverified.length) {
|
|
283
308
|
lines.push(
|
|
284
309
|
``,
|