@codyswann/lisa 2.85.2 → 2.88.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.
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/commands/automation-status.md +5 -0
- package/plugins/lisa/scripts/automation-status-expected-fleet.mjs +444 -0
- package/plugins/lisa/scripts/automation-status-report.mjs +170 -0
- package/plugins/lisa/skills/automation-status/SKILL.md +75 -0
- package/plugins/lisa/skills/automation-status/agents/openai.yaml +4 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-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-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-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-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-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-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/src/base/commands/automation-status.md +5 -0
- package/plugins/src/base/scripts/automation-status-expected-fleet.mjs +444 -0
- package/plugins/src/base/scripts/automation-status-report.mjs +170 -0
- package/plugins/src/base/skills/automation-status/SKILL.md +75 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Shared automation-status report helpers for the base Lisa operator surface.
|
|
4
|
+
*
|
|
5
|
+
* Keep this dependency-free so the grouped fleet rendering contract can ship in
|
|
6
|
+
* plugin distributions and downstream repos before the runtime adapters land.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const AUTOMATION_HEALTH_STATUSES = [
|
|
10
|
+
"HEALTHY",
|
|
11
|
+
"MISSING",
|
|
12
|
+
"UNSUPPORTED",
|
|
13
|
+
"DRIFTED",
|
|
14
|
+
"STALE",
|
|
15
|
+
"FAILING",
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export const AUTOMATION_FLEET_VERDICTS = [
|
|
19
|
+
"HEALTHY",
|
|
20
|
+
"PARTIAL_SUPPORT",
|
|
21
|
+
"ATTENTION_NEEDED",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {"HEALTHY" | "MISSING" | "UNSUPPORTED" | "DRIFTED" | "STALE" | "FAILING"} AutomationHealthStatus
|
|
26
|
+
* @typedef {"HEALTHY" | "PARTIAL_SUPPORT" | "ATTENTION_NEEDED"} AutomationFleetVerdict
|
|
27
|
+
*
|
|
28
|
+
* @typedef {{
|
|
29
|
+
* readonly id: string
|
|
30
|
+
* readonly status: AutomationHealthStatus
|
|
31
|
+
* readonly summary: string
|
|
32
|
+
* readonly expectedCadence?: string
|
|
33
|
+
* readonly expectedCommand?: string
|
|
34
|
+
* readonly observed?: string
|
|
35
|
+
* readonly remediation?: string
|
|
36
|
+
* }} AutomationStatusItem
|
|
37
|
+
*
|
|
38
|
+
* @typedef {{
|
|
39
|
+
* readonly id: string
|
|
40
|
+
* readonly title: string
|
|
41
|
+
* readonly items: readonly AutomationStatusItem[]
|
|
42
|
+
* }} AutomationStatusGroup
|
|
43
|
+
*
|
|
44
|
+
* @typedef {{
|
|
45
|
+
* readonly runtime?: string
|
|
46
|
+
* readonly generatedAt?: string
|
|
47
|
+
* readonly groups: readonly AutomationStatusGroup[]
|
|
48
|
+
* }} AutomationStatusReportInput
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {readonly AutomationStatusGroup[]} groups
|
|
53
|
+
* @returns {AutomationFleetVerdict}
|
|
54
|
+
*/
|
|
55
|
+
export function computeAutomationFleetVerdict(groups) {
|
|
56
|
+
const items = groups.flatMap(group => group.items);
|
|
57
|
+
if (
|
|
58
|
+
items.some(item =>
|
|
59
|
+
["MISSING", "DRIFTED", "STALE", "FAILING"].includes(item.status)
|
|
60
|
+
)
|
|
61
|
+
) {
|
|
62
|
+
return "ATTENTION_NEEDED";
|
|
63
|
+
}
|
|
64
|
+
if (items.some(item => item.status === "UNSUPPORTED")) {
|
|
65
|
+
return "PARTIAL_SUPPORT";
|
|
66
|
+
}
|
|
67
|
+
return "HEALTHY";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param {readonly AutomationStatusGroup[]} groups
|
|
72
|
+
* @returns {Record<AutomationHealthStatus, number>}
|
|
73
|
+
*/
|
|
74
|
+
export function countAutomationHealthStatuses(groups) {
|
|
75
|
+
return groups
|
|
76
|
+
.flatMap(group => group.items)
|
|
77
|
+
.reduce(
|
|
78
|
+
(counts, item) => ({
|
|
79
|
+
...counts,
|
|
80
|
+
[item.status]: counts[item.status] + 1,
|
|
81
|
+
}),
|
|
82
|
+
{
|
|
83
|
+
HEALTHY: 0,
|
|
84
|
+
MISSING: 0,
|
|
85
|
+
UNSUPPORTED: 0,
|
|
86
|
+
DRIFTED: 0,
|
|
87
|
+
STALE: 0,
|
|
88
|
+
FAILING: 0,
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @param {AutomationStatusReportInput} input
|
|
95
|
+
* @returns {{ readonly verdict: AutomationFleetVerdict, readonly counts: Record<AutomationHealthStatus, number>, readonly text: string }}
|
|
96
|
+
*/
|
|
97
|
+
export function renderAutomationStatusReport(input) {
|
|
98
|
+
const groups = input.groups.map(normalizeGroup);
|
|
99
|
+
const verdict = computeAutomationFleetVerdict(groups);
|
|
100
|
+
const counts = countAutomationHealthStatuses(groups);
|
|
101
|
+
const lines = [
|
|
102
|
+
`Overall verdict: ${verdict}`,
|
|
103
|
+
`Counts: ${AUTOMATION_HEALTH_STATUSES.map(status => `${counts[status]} ${status}`).join(", ")}`,
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
if (input.runtime) {
|
|
107
|
+
lines.push(`Runtime inspected: ${input.runtime}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (input.generatedAt) {
|
|
111
|
+
lines.push(`Generated at: ${input.generatedAt}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
for (const group of groups) {
|
|
115
|
+
lines.push("", `${group.id}. ${group.title}`);
|
|
116
|
+
if (group.items.length === 0) {
|
|
117
|
+
lines.push(
|
|
118
|
+
"- UNSUPPORTED empty-group: no automations expected in this group"
|
|
119
|
+
);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (const item of group.items) {
|
|
124
|
+
lines.push(`- ${item.status} ${item.id}: ${item.summary}`);
|
|
125
|
+
if (item.expectedCadence || item.expectedCommand) {
|
|
126
|
+
const cadence = item.expectedCadence ?? "cadence unavailable";
|
|
127
|
+
const command = item.expectedCommand ?? "command unavailable";
|
|
128
|
+
lines.push(` Expected: ${cadence} -> ${command}`);
|
|
129
|
+
}
|
|
130
|
+
if (item.observed) {
|
|
131
|
+
lines.push(` Observed: ${item.observed}`);
|
|
132
|
+
}
|
|
133
|
+
if (item.remediation) {
|
|
134
|
+
lines.push(` Remediation: ${item.remediation}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
verdict,
|
|
141
|
+
counts,
|
|
142
|
+
text: `${lines.join("\n")}\n`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @param {AutomationStatusGroup} group
|
|
148
|
+
* @returns {AutomationStatusGroup}
|
|
149
|
+
*/
|
|
150
|
+
function normalizeGroup(group) {
|
|
151
|
+
return {
|
|
152
|
+
...group,
|
|
153
|
+
items: group.items.map(normalizeItem),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @param {AutomationStatusItem} item
|
|
159
|
+
* @returns {AutomationStatusItem}
|
|
160
|
+
*/
|
|
161
|
+
function normalizeItem(item) {
|
|
162
|
+
const normalizedStatus = AUTOMATION_HEALTH_STATUSES.includes(item.status)
|
|
163
|
+
? item.status
|
|
164
|
+
: "FAILING";
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
...item,
|
|
168
|
+
status: normalizedStatus,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: automation-status
|
|
3
|
+
description: "Read-only operator surface for the current project's Lisa automation fleet. Resolves the expected recurring jobs from the same setup-automations contract Lisa uses to create them, inspects the active runtime scheduler (Codex automations or Claude /schedule), compares live command/cadence/queue arguments against the expected contract, and reports grouped fleet health such as healthy, missing, unsupported, drifted, stale, or failing with remediation guidance."
|
|
4
|
+
allowed-tools: ["Skill", "Bash", "Read"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Automation Status: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
`/lisa:automation-status` is the operator-facing inspection surface for Lisa's unattended job fleet. It answers, for the **current repo only**, whether the recurring Lisa automations that should exist actually exist, still match Lisa's setup contract, and appear healthy based on the runtime metadata available.
|
|
10
|
+
|
|
11
|
+
This command is **read-only** in v1. It does not create, update, resume, rerun, pause, or delete automations. It complements `/lisa:setup-automations`, `/lisa:tear-down-automations`, `/lisa:intake`, `/lisa:repair-intake`, `doctor`, and `monitor`; it does not replace them.
|
|
12
|
+
|
|
13
|
+
## Confirmation policy
|
|
14
|
+
|
|
15
|
+
Do **not** ask for confirmation once invoked. This skill inspects scheduler state and reports what it finds. There are no write-side effects in the v1 surface.
|
|
16
|
+
|
|
17
|
+
## Scope
|
|
18
|
+
|
|
19
|
+
Inspect only the Lisa automation fleet for the current project:
|
|
20
|
+
|
|
21
|
+
- `intake-repair`
|
|
22
|
+
- `intake-prd`
|
|
23
|
+
- `intake-tickets`
|
|
24
|
+
- `exploratory-bugs` when the current stack supports `exploratory-qa`
|
|
25
|
+
- `exploratory-prds`
|
|
26
|
+
|
|
27
|
+
Resolve the expected project identifier, fleet naming prefix, queue arguments, cadence, and stack-support rules from the same contract used by `setup-automations` and `tear-down-automations`. Do **not** invent a second source of truth for fleet naming or queue resolution.
|
|
28
|
+
|
|
29
|
+
## Runtime inspection
|
|
30
|
+
|
|
31
|
+
Branch on the active runtime and prefer the runtime's native automation listing surface:
|
|
32
|
+
|
|
33
|
+
- **Codex**: inspect Codex automations metadata first. Use backing-store files only as a fallback or to enrich timestamps when the runtime surface cannot provide enough status detail directly.
|
|
34
|
+
- **Claude**: inspect the `/schedule` listing surface and any exposed recency or failure metadata available there.
|
|
35
|
+
- **Other runtimes**: if no native recurring-task inspection exists, report that automation-status is unsupported in this runtime rather than guessing.
|
|
36
|
+
|
|
37
|
+
The report must stay repo-scoped: inspect only automations whose names belong to the current repo's Lisa fleet prefix, and do not absorb unrelated automations into the result.
|
|
38
|
+
|
|
39
|
+
## What to report
|
|
40
|
+
|
|
41
|
+
For each expected automation, report:
|
|
42
|
+
|
|
43
|
+
1. Whether it exists.
|
|
44
|
+
2. Whether it is expected or intentionally unsupported.
|
|
45
|
+
3. The configured command and cadence Lisa expects.
|
|
46
|
+
4. Any detected drift in name, cadence, command shape, or queue arguments.
|
|
47
|
+
5. Any available recent-run health signal such as stale last-run timing or repeated failure status.
|
|
48
|
+
6. A concise remediation hint when attention is needed.
|
|
49
|
+
|
|
50
|
+
Emit an overall grouped fleet verdict such as `HEALTHY`, `ATTENTION_NEEDED`, or `PARTIAL_SUPPORT`, plus the runtime surface inspected.
|
|
51
|
+
|
|
52
|
+
Render the report in grouped sections using the shared `scripts/automation-status-report.mjs` contract:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
Overall verdict: <VERDICT>
|
|
56
|
+
Counts: <n HEALTHY>, <n MISSING>, <n UNSUPPORTED>, <n DRIFTED>, <n STALE>, <n FAILING>
|
|
57
|
+
Runtime inspected: <runtime surface>
|
|
58
|
+
Generated at: <ISO timestamp>
|
|
59
|
+
|
|
60
|
+
1. <group title>
|
|
61
|
+
- <STATUS> <automation-id>: <summary>
|
|
62
|
+
Expected: <cadence> -> <command>
|
|
63
|
+
Observed: <what the runtime exposed>
|
|
64
|
+
Remediation: <next step when attention is needed>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Keep observable runtime facts separate from remediation guidance so operators can distinguish drift, unsupported jobs, and actual failures quickly.
|
|
68
|
+
|
|
69
|
+
## Rules
|
|
70
|
+
|
|
71
|
+
- Stay **read-only**. Never create, update, delete, enable, disable, or rerun automations from this skill.
|
|
72
|
+
- Reuse `setup-automations` contract logic for expected fleet resolution, cadence, queue arguments, naming, and stack-specific support checks.
|
|
73
|
+
- Distinguish **unsupported** from **missing**. An exploratory job omitted because the current stack lacks `exploratory-qa` is not a failure.
|
|
74
|
+
- If the runtime cannot expose a field such as last-run timestamp or failure state, say that explicitly instead of implying health.
|
|
75
|
+
- Keep the output operational and repo-scoped so operators can tell whether Lisa's unattended surfaces are present, current, and healthy right now.
|