@codyswann/lisa 2.75.1 → 2.77.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 (26) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa/commands/doctor.md +6 -0
  5. package/plugins/lisa/scripts/doctor-report.mjs +132 -0
  6. package/plugins/lisa/skills/doctor/SKILL.md +114 -0
  7. package/plugins/lisa/skills/doctor/agents/openai.yaml +4 -0
  8. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  9. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  10. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  11. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  12. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  14. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  16. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  18. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  20. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  22. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  24. package/plugins/src/base/commands/doctor.md +6 -0
  25. package/plugins/src/base/scripts/doctor-report.mjs +132 -0
  26. package/plugins/src/base/skills/doctor/SKILL.md +114 -0
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  "lodash": ">=4.18.1"
83
83
  },
84
84
  "name": "@codyswann/lisa",
85
- "version": "2.75.1",
85
+ "version": "2.77.0",
86
86
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
87
87
  "main": "dist/index.js",
88
88
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.75.1",
3
+ "version": "2.77.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.75.1",
3
+ "version": "2.77.0",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Audit whether the current repository is ready to use Lisa. Runs grouped read-only readiness checks for config, runtime surfaces, tracker/source access, automation prerequisites, and optional project/wiki coordination, then reports PASS/WARN/FAIL/SKIP results plus an overall verdict."
3
+ argument-hint: "[--fix=false]"
4
+ ---
5
+
6
+ Use the /lisa:doctor skill to audit whether the current repository is ready to use Lisa, report grouped PASS/WARN/FAIL/SKIP checks, and emit an overall readiness verdict. $ARGUMENTS
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Shared doctor report helpers for the base Lisa doctor surface.
4
+ *
5
+ * The first doctor milestone needs a stable grouped output contract before the
6
+ * repo adds real readiness probes. Keep this file dependency-free so future
7
+ * doctor scripts can reuse it from plugin distributions and downstream repos.
8
+ */
9
+
10
+ export const DOCTOR_STATUSES = ["PASS", "WARN", "FAIL", "SKIP"];
11
+ export const DOCTOR_VERDICTS = ["READY", "READY_WITH_WARNINGS", "NOT_READY"];
12
+
13
+ /**
14
+ * @typedef {"PASS" | "WARN" | "FAIL" | "SKIP"} DoctorStatus
15
+ * @typedef {"READY" | "READY_WITH_WARNINGS" | "NOT_READY"} DoctorVerdict
16
+ *
17
+ * @typedef {{
18
+ * readonly id: string
19
+ * readonly status: DoctorStatus
20
+ * readonly summary: string
21
+ * readonly observed?: string
22
+ * readonly remediation?: string
23
+ * }} DoctorCheck
24
+ *
25
+ * @typedef {{
26
+ * readonly id: string
27
+ * readonly title: string
28
+ * readonly checks: readonly DoctorCheck[]
29
+ * }} DoctorGroup
30
+ *
31
+ * @typedef {{
32
+ * readonly generatedAt?: string
33
+ * readonly groups: readonly DoctorGroup[]
34
+ * }} DoctorReportInput
35
+ */
36
+
37
+ /**
38
+ * @param {readonly DoctorGroup[]} groups
39
+ * @returns {DoctorVerdict}
40
+ */
41
+ export function computeDoctorVerdict(groups) {
42
+ const checks = groups.flatMap(group => group.checks);
43
+ if (checks.some(check => check.status === "FAIL")) {
44
+ return "NOT_READY";
45
+ }
46
+ if (checks.some(check => check.status === "WARN")) {
47
+ return "READY_WITH_WARNINGS";
48
+ }
49
+ return "READY";
50
+ }
51
+
52
+ /**
53
+ * @param {readonly DoctorGroup[]} groups
54
+ * @returns {Record<DoctorStatus, number>}
55
+ */
56
+ export function countDoctorStatuses(groups) {
57
+ return groups
58
+ .flatMap(group => group.checks)
59
+ .reduce(
60
+ (counts, check) => ({
61
+ ...counts,
62
+ [check.status]: counts[check.status] + 1,
63
+ }),
64
+ { PASS: 0, WARN: 0, FAIL: 0, SKIP: 0 }
65
+ );
66
+ }
67
+
68
+ /**
69
+ * @param {DoctorReportInput} input
70
+ * @returns {{ readonly verdict: DoctorVerdict, readonly counts: Record<DoctorStatus, number>, readonly text: string }}
71
+ */
72
+ export function renderDoctorReport(input) {
73
+ const groups = input.groups.map(normalizeGroup);
74
+ const verdict = computeDoctorVerdict(groups);
75
+ const counts = countDoctorStatuses(groups);
76
+ const lines = [
77
+ `Overall verdict: ${verdict}`,
78
+ `Counts: ${DOCTOR_STATUSES.map(status => `${counts[status]} ${status}`).join(", ")}`,
79
+ ];
80
+
81
+ if (input.generatedAt) {
82
+ lines.push(`Generated at: ${input.generatedAt}`);
83
+ }
84
+
85
+ for (const group of groups) {
86
+ lines.push("", `${group.id}. ${group.title}`);
87
+ if (group.checks.length === 0) {
88
+ lines.push("- SKIP empty-group: no checks registered yet");
89
+ continue;
90
+ }
91
+ for (const check of group.checks) {
92
+ lines.push(`- ${check.status} ${check.id}: ${check.summary}`);
93
+ if (check.observed) {
94
+ lines.push(` Observed: ${check.observed}`);
95
+ }
96
+ if (check.remediation) {
97
+ lines.push(` Remediation: ${check.remediation}`);
98
+ }
99
+ }
100
+ }
101
+
102
+ return {
103
+ verdict,
104
+ counts,
105
+ text: `${lines.join("\n")}\n`,
106
+ };
107
+ }
108
+
109
+ /**
110
+ * @param {DoctorGroup} group
111
+ * @returns {DoctorGroup}
112
+ */
113
+ function normalizeGroup(group) {
114
+ return {
115
+ ...group,
116
+ checks: group.checks.map(normalizeCheck),
117
+ };
118
+ }
119
+
120
+ /**
121
+ * @param {DoctorCheck} check
122
+ * @returns {DoctorCheck}
123
+ */
124
+ function normalizeCheck(check) {
125
+ const normalizedStatus = DOCTOR_STATUSES.includes(check.status)
126
+ ? check.status
127
+ : "FAIL";
128
+ return {
129
+ ...check,
130
+ status: normalizedStatus,
131
+ };
132
+ }
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: doctor
3
+ description: "Audit whether the current repository is ready to use Lisa. Runs grouped read-only checks across project detection, Lisa config, runtime distribution surfaces, tracker/source preflight access, automation prerequisites, optional GitHub Project coordination, and optional wiki delegation, then reports PASS/WARN/FAIL/SKIP results plus an overall readiness verdict (`READY`, `READY_WITH_WARNINGS`, or `NOT_READY`)."
4
+ allowed-tools: ["Skill", "Bash", "Read", "Glob", "Grep"]
5
+ ---
6
+
7
+ # Doctor: $ARGUMENTS
8
+
9
+ Run a read-only Lisa readiness audit for the current repository.
10
+
11
+ ## Purpose
12
+
13
+ `/lisa:doctor` is the deterministic answer to "is this repo actually ready to use Lisa?" It audits
14
+ the repository in grouped sections, reports each check as `PASS`, `WARN`, `FAIL`, or `SKIP`, and
15
+ emits one overall verdict: `READY`, `READY_WITH_WARNINGS`, or `NOT_READY`.
16
+
17
+ The command is repository-scoped. It validates only what can be observed from the current repo,
18
+ current machine, and current runtime. It does **not** create automations, labels, tracker items, or
19
+ other external state as part of the default audit path.
20
+
21
+ ## Inputs
22
+
23
+ - Optional flags in `$ARGUMENTS` that narrow or tune read-only validation.
24
+ - The current repository root and its Lisa config files (`.lisa.config.json`,
25
+ `.lisa.config.local.json`) when present.
26
+
27
+ ## Confirmation policy
28
+
29
+ Do **not** ask whether to proceed. Once invoked, run the read-only audit, print the grouped
30
+ results, emit the overall verdict, and stop.
31
+
32
+ Specifically forbidden:
33
+
34
+ - Previewing the number of checks and asking whether to continue.
35
+ - Offering "run a few checks first" or "dry-run vs real run" choices. This skill is already the
36
+ read-only path.
37
+ - Performing setup mutations just because a failing check discovered something missing.
38
+
39
+ The only legitimate reasons to stop early are:
40
+
41
+ - The current working directory cannot be resolved to a repository/root the audit can inspect.
42
+ - The runtime blocks all required local reads needed to even classify the repo.
43
+
44
+ ## Audit contract
45
+
46
+ Doctor reports grouped checks in a stable, human-readable structure. The grouped sections include,
47
+ as applicable to the current repo:
48
+
49
+ 1. **Project detection and runtime basics** — detect the project root, package/runtime surface, and
50
+ whether Lisa is installed where the repo expects it.
51
+ 2. **Lisa config readiness** — read `.lisa.config.json` and `.lisa.config.local.json` using the
52
+ same local-overrides-global semantics defined by `config-resolution`; report missing required
53
+ keys, incompatible combinations, and committed-vs-local locality problems as findings rather
54
+ than mutating config.
55
+ 3. **Tracker/source preflight** — perform read-only readiness checks for the configured `tracker`
56
+ and `source` only. If a required CLI, MCP surface, or auth context is unavailable in the current
57
+ runtime, report that explicitly instead of pretending the repo is ready.
58
+ 4. **Runtime distribution surfaces** — confirm the command, skill, hook, and related distribution
59
+ surfaces relevant to this repo are present where Lisa expects them on the active runtime.
60
+ 5. **Automation readiness** — inspect whether the configured queue source/tracker and scheduling
61
+ prerequisites are observable, but do **not** create, edit, or delete automations during doctor.
62
+ 6. **Optional GitHub Project coordination** — when `github.projects.v2` is configured, delegate
63
+ the shared validation read to `github-project-v2` instead of reimplementing ad-hoc GraphQL
64
+ checks. Honor the `required=false` vs `required=true` semantics documented by
65
+ `config-resolution`: best-effort failures are `WARN`, required-mode failures are `FAIL`.
66
+ 7. **Optional wiki delegation** — when a repo-local `wiki/` exists, either summarize the
67
+ specialized `lisa-wiki-doctor` verdict or explicitly report that deeper wiki checks are
68
+ available there. The base doctor stays narrower than full wiki migration enforcement.
69
+
70
+ If a check family is not applicable to the current repo, report `SKIP` with the reason.
71
+
72
+ ## Output contract
73
+
74
+ The final report must:
75
+
76
+ - Separate observed facts from remediation advice.
77
+ - Print every check with one of `PASS`, `WARN`, `FAIL`, or `SKIP`.
78
+ - Emit exactly one overall verdict: `READY`, `READY_WITH_WARNINGS`, or `NOT_READY`.
79
+ - Stay read-only by default.
80
+
81
+ Render the report in grouped sections using the shared `scripts/doctor-report.mjs` contract:
82
+
83
+ - Start with `Overall verdict: <VERDICT>` and one `Counts:` line covering `PASS`, `WARN`, `FAIL`,
84
+ and `SKIP`.
85
+ - Then print each group as `<group-id>. <group-title>`.
86
+ - Under each group, print one line per check as `- <STATUS> <check-id>: <summary>`.
87
+ - When available, print `Observed:` and `Remediation:` lines beneath the check so the report keeps
88
+ facts separate from advice.
89
+ - If a group has no applicable checks yet, render it as a grouped `SKIP` with the reason instead of
90
+ silently omitting the section.
91
+
92
+ The verdict ladder is:
93
+
94
+ - `READY` — no `FAIL` and no `WARN`.
95
+ - `READY_WITH_WARNINGS` — no `FAIL`, but one or more `WARN`.
96
+ - `NOT_READY` — one or more `FAIL`.
97
+
98
+ ## Delegation and reuse
99
+
100
+ - Reuse `config-resolution` for config and lifecycle role defaults instead of inventing a second
101
+ schema.
102
+ - Reuse the existing `github-project-v2` chokepoint for GitHub Project coordination checks instead
103
+ of inlining bespoke access logic.
104
+ - Reuse ideas from `lisa-wiki-doctor` for grouped verdict rendering where they fit, while keeping
105
+ the Lisa-wide doctor narrower than the wiki-specific migration/readiness workflow.
106
+
107
+ ## Rules
108
+
109
+ - Never mutate repository, tracker, or automation state on the default doctor path.
110
+ - Never hardcode tracker/source label names outside the documented defaults plus configured
111
+ overrides from `config-resolution`.
112
+ - Never silently treat an unavailable check surface as success; report `WARN`, `FAIL`, or `SKIP`
113
+ with the explicit missing dependency.
114
+ - Never turn wiki-specific checks into a requirement for non-wiki repos.
@@ -0,0 +1,4 @@
1
+ display_name: "Doctor"
2
+ short_description: "Audit whether the current repository is ready to use Lisa"
3
+ default_prompt:
4
+ - "Use $doctor: Audit whether the current repository is ready to use Lisa."
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.75.1",
3
+ "version": "2.77.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.75.1",
3
+ "version": "2.77.0",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.75.1",
3
+ "version": "2.77.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.75.1",
3
+ "version": "2.77.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-harper-fabric",
3
- "version": "2.75.1",
3
+ "version": "2.77.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.75.1",
3
+ "version": "2.77.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-nestjs",
3
- "version": "2.75.1",
3
+ "version": "2.77.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.75.1",
3
+ "version": "2.77.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-openclaw",
3
- "version": "2.75.1",
3
+ "version": "2.77.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.75.1",
3
+ "version": "2.77.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-rails",
3
- "version": "2.75.1",
3
+ "version": "2.77.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.75.1",
3
+ "version": "2.77.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-typescript",
3
- "version": "2.75.1",
3
+ "version": "2.77.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint 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.75.1",
3
+ "version": "2.77.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-wiki",
3
- "version": "2.75.1",
3
+ "version": "2.77.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.75.1",
3
+ "version": "2.77.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"
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Audit whether the current repository is ready to use Lisa. Runs grouped read-only readiness checks for config, runtime surfaces, tracker/source access, automation prerequisites, and optional project/wiki coordination, then reports PASS/WARN/FAIL/SKIP results plus an overall verdict."
3
+ argument-hint: "[--fix=false]"
4
+ ---
5
+
6
+ Use the /lisa:doctor skill to audit whether the current repository is ready to use Lisa, report grouped PASS/WARN/FAIL/SKIP checks, and emit an overall readiness verdict. $ARGUMENTS
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Shared doctor report helpers for the base Lisa doctor surface.
4
+ *
5
+ * The first doctor milestone needs a stable grouped output contract before the
6
+ * repo adds real readiness probes. Keep this file dependency-free so future
7
+ * doctor scripts can reuse it from plugin distributions and downstream repos.
8
+ */
9
+
10
+ export const DOCTOR_STATUSES = ["PASS", "WARN", "FAIL", "SKIP"];
11
+ export const DOCTOR_VERDICTS = ["READY", "READY_WITH_WARNINGS", "NOT_READY"];
12
+
13
+ /**
14
+ * @typedef {"PASS" | "WARN" | "FAIL" | "SKIP"} DoctorStatus
15
+ * @typedef {"READY" | "READY_WITH_WARNINGS" | "NOT_READY"} DoctorVerdict
16
+ *
17
+ * @typedef {{
18
+ * readonly id: string
19
+ * readonly status: DoctorStatus
20
+ * readonly summary: string
21
+ * readonly observed?: string
22
+ * readonly remediation?: string
23
+ * }} DoctorCheck
24
+ *
25
+ * @typedef {{
26
+ * readonly id: string
27
+ * readonly title: string
28
+ * readonly checks: readonly DoctorCheck[]
29
+ * }} DoctorGroup
30
+ *
31
+ * @typedef {{
32
+ * readonly generatedAt?: string
33
+ * readonly groups: readonly DoctorGroup[]
34
+ * }} DoctorReportInput
35
+ */
36
+
37
+ /**
38
+ * @param {readonly DoctorGroup[]} groups
39
+ * @returns {DoctorVerdict}
40
+ */
41
+ export function computeDoctorVerdict(groups) {
42
+ const checks = groups.flatMap(group => group.checks);
43
+ if (checks.some(check => check.status === "FAIL")) {
44
+ return "NOT_READY";
45
+ }
46
+ if (checks.some(check => check.status === "WARN")) {
47
+ return "READY_WITH_WARNINGS";
48
+ }
49
+ return "READY";
50
+ }
51
+
52
+ /**
53
+ * @param {readonly DoctorGroup[]} groups
54
+ * @returns {Record<DoctorStatus, number>}
55
+ */
56
+ export function countDoctorStatuses(groups) {
57
+ return groups
58
+ .flatMap(group => group.checks)
59
+ .reduce(
60
+ (counts, check) => ({
61
+ ...counts,
62
+ [check.status]: counts[check.status] + 1,
63
+ }),
64
+ { PASS: 0, WARN: 0, FAIL: 0, SKIP: 0 }
65
+ );
66
+ }
67
+
68
+ /**
69
+ * @param {DoctorReportInput} input
70
+ * @returns {{ readonly verdict: DoctorVerdict, readonly counts: Record<DoctorStatus, number>, readonly text: string }}
71
+ */
72
+ export function renderDoctorReport(input) {
73
+ const groups = input.groups.map(normalizeGroup);
74
+ const verdict = computeDoctorVerdict(groups);
75
+ const counts = countDoctorStatuses(groups);
76
+ const lines = [
77
+ `Overall verdict: ${verdict}`,
78
+ `Counts: ${DOCTOR_STATUSES.map(status => `${counts[status]} ${status}`).join(", ")}`,
79
+ ];
80
+
81
+ if (input.generatedAt) {
82
+ lines.push(`Generated at: ${input.generatedAt}`);
83
+ }
84
+
85
+ for (const group of groups) {
86
+ lines.push("", `${group.id}. ${group.title}`);
87
+ if (group.checks.length === 0) {
88
+ lines.push("- SKIP empty-group: no checks registered yet");
89
+ continue;
90
+ }
91
+ for (const check of group.checks) {
92
+ lines.push(`- ${check.status} ${check.id}: ${check.summary}`);
93
+ if (check.observed) {
94
+ lines.push(` Observed: ${check.observed}`);
95
+ }
96
+ if (check.remediation) {
97
+ lines.push(` Remediation: ${check.remediation}`);
98
+ }
99
+ }
100
+ }
101
+
102
+ return {
103
+ verdict,
104
+ counts,
105
+ text: `${lines.join("\n")}\n`,
106
+ };
107
+ }
108
+
109
+ /**
110
+ * @param {DoctorGroup} group
111
+ * @returns {DoctorGroup}
112
+ */
113
+ function normalizeGroup(group) {
114
+ return {
115
+ ...group,
116
+ checks: group.checks.map(normalizeCheck),
117
+ };
118
+ }
119
+
120
+ /**
121
+ * @param {DoctorCheck} check
122
+ * @returns {DoctorCheck}
123
+ */
124
+ function normalizeCheck(check) {
125
+ const normalizedStatus = DOCTOR_STATUSES.includes(check.status)
126
+ ? check.status
127
+ : "FAIL";
128
+ return {
129
+ ...check,
130
+ status: normalizedStatus,
131
+ };
132
+ }
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: doctor
3
+ description: "Audit whether the current repository is ready to use Lisa. Runs grouped read-only checks across project detection, Lisa config, runtime distribution surfaces, tracker/source preflight access, automation prerequisites, optional GitHub Project coordination, and optional wiki delegation, then reports PASS/WARN/FAIL/SKIP results plus an overall readiness verdict (`READY`, `READY_WITH_WARNINGS`, or `NOT_READY`)."
4
+ allowed-tools: ["Skill", "Bash", "Read", "Glob", "Grep"]
5
+ ---
6
+
7
+ # Doctor: $ARGUMENTS
8
+
9
+ Run a read-only Lisa readiness audit for the current repository.
10
+
11
+ ## Purpose
12
+
13
+ `/lisa:doctor` is the deterministic answer to "is this repo actually ready to use Lisa?" It audits
14
+ the repository in grouped sections, reports each check as `PASS`, `WARN`, `FAIL`, or `SKIP`, and
15
+ emits one overall verdict: `READY`, `READY_WITH_WARNINGS`, or `NOT_READY`.
16
+
17
+ The command is repository-scoped. It validates only what can be observed from the current repo,
18
+ current machine, and current runtime. It does **not** create automations, labels, tracker items, or
19
+ other external state as part of the default audit path.
20
+
21
+ ## Inputs
22
+
23
+ - Optional flags in `$ARGUMENTS` that narrow or tune read-only validation.
24
+ - The current repository root and its Lisa config files (`.lisa.config.json`,
25
+ `.lisa.config.local.json`) when present.
26
+
27
+ ## Confirmation policy
28
+
29
+ Do **not** ask whether to proceed. Once invoked, run the read-only audit, print the grouped
30
+ results, emit the overall verdict, and stop.
31
+
32
+ Specifically forbidden:
33
+
34
+ - Previewing the number of checks and asking whether to continue.
35
+ - Offering "run a few checks first" or "dry-run vs real run" choices. This skill is already the
36
+ read-only path.
37
+ - Performing setup mutations just because a failing check discovered something missing.
38
+
39
+ The only legitimate reasons to stop early are:
40
+
41
+ - The current working directory cannot be resolved to a repository/root the audit can inspect.
42
+ - The runtime blocks all required local reads needed to even classify the repo.
43
+
44
+ ## Audit contract
45
+
46
+ Doctor reports grouped checks in a stable, human-readable structure. The grouped sections include,
47
+ as applicable to the current repo:
48
+
49
+ 1. **Project detection and runtime basics** — detect the project root, package/runtime surface, and
50
+ whether Lisa is installed where the repo expects it.
51
+ 2. **Lisa config readiness** — read `.lisa.config.json` and `.lisa.config.local.json` using the
52
+ same local-overrides-global semantics defined by `config-resolution`; report missing required
53
+ keys, incompatible combinations, and committed-vs-local locality problems as findings rather
54
+ than mutating config.
55
+ 3. **Tracker/source preflight** — perform read-only readiness checks for the configured `tracker`
56
+ and `source` only. If a required CLI, MCP surface, or auth context is unavailable in the current
57
+ runtime, report that explicitly instead of pretending the repo is ready.
58
+ 4. **Runtime distribution surfaces** — confirm the command, skill, hook, and related distribution
59
+ surfaces relevant to this repo are present where Lisa expects them on the active runtime.
60
+ 5. **Automation readiness** — inspect whether the configured queue source/tracker and scheduling
61
+ prerequisites are observable, but do **not** create, edit, or delete automations during doctor.
62
+ 6. **Optional GitHub Project coordination** — when `github.projects.v2` is configured, delegate
63
+ the shared validation read to `github-project-v2` instead of reimplementing ad-hoc GraphQL
64
+ checks. Honor the `required=false` vs `required=true` semantics documented by
65
+ `config-resolution`: best-effort failures are `WARN`, required-mode failures are `FAIL`.
66
+ 7. **Optional wiki delegation** — when a repo-local `wiki/` exists, either summarize the
67
+ specialized `lisa-wiki-doctor` verdict or explicitly report that deeper wiki checks are
68
+ available there. The base doctor stays narrower than full wiki migration enforcement.
69
+
70
+ If a check family is not applicable to the current repo, report `SKIP` with the reason.
71
+
72
+ ## Output contract
73
+
74
+ The final report must:
75
+
76
+ - Separate observed facts from remediation advice.
77
+ - Print every check with one of `PASS`, `WARN`, `FAIL`, or `SKIP`.
78
+ - Emit exactly one overall verdict: `READY`, `READY_WITH_WARNINGS`, or `NOT_READY`.
79
+ - Stay read-only by default.
80
+
81
+ Render the report in grouped sections using the shared `scripts/doctor-report.mjs` contract:
82
+
83
+ - Start with `Overall verdict: <VERDICT>` and one `Counts:` line covering `PASS`, `WARN`, `FAIL`,
84
+ and `SKIP`.
85
+ - Then print each group as `<group-id>. <group-title>`.
86
+ - Under each group, print one line per check as `- <STATUS> <check-id>: <summary>`.
87
+ - When available, print `Observed:` and `Remediation:` lines beneath the check so the report keeps
88
+ facts separate from advice.
89
+ - If a group has no applicable checks yet, render it as a grouped `SKIP` with the reason instead of
90
+ silently omitting the section.
91
+
92
+ The verdict ladder is:
93
+
94
+ - `READY` — no `FAIL` and no `WARN`.
95
+ - `READY_WITH_WARNINGS` — no `FAIL`, but one or more `WARN`.
96
+ - `NOT_READY` — one or more `FAIL`.
97
+
98
+ ## Delegation and reuse
99
+
100
+ - Reuse `config-resolution` for config and lifecycle role defaults instead of inventing a second
101
+ schema.
102
+ - Reuse the existing `github-project-v2` chokepoint for GitHub Project coordination checks instead
103
+ of inlining bespoke access logic.
104
+ - Reuse ideas from `lisa-wiki-doctor` for grouped verdict rendering where they fit, while keeping
105
+ the Lisa-wide doctor narrower than the wiki-specific migration/readiness workflow.
106
+
107
+ ## Rules
108
+
109
+ - Never mutate repository, tracker, or automation state on the default doctor path.
110
+ - Never hardcode tracker/source label names outside the documented defaults plus configured
111
+ overrides from `config-resolution`.
112
+ - Never silently treat an unavailable check surface as success; report `WARN`, `FAIL`, or `SKIP`
113
+ with the explicit missing dependency.
114
+ - Never turn wiki-specific checks into a requirement for non-wiki repos.