@codyswann/lisa 2.235.0 → 2.237.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/dist/cli/check-learnings-budget-cmd.d.ts +20 -0
- package/dist/cli/check-learnings-budget-cmd.d.ts.map +1 -0
- package/dist/cli/check-learnings-budget-cmd.js +59 -0
- package/dist/cli/check-learnings-budget-cmd.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +29 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ui-automations-adapters.d.ts +50 -0
- package/dist/cli/ui-automations-adapters.d.ts.map +1 -0
- package/dist/cli/ui-automations-adapters.js +162 -0
- package/dist/cli/ui-automations-adapters.js.map +1 -0
- package/dist/cli/ui-automations.d.ts +89 -0
- package/dist/cli/ui-automations.d.ts.map +1 -0
- package/dist/cli/ui-automations.js +148 -0
- package/dist/cli/ui-automations.js.map +1 -0
- package/dist/cli/ui-cmd.d.ts +5 -0
- package/dist/cli/ui-cmd.d.ts.map +1 -1
- package/dist/cli/ui-cmd.js +17 -0
- package/dist/cli/ui-cmd.js.map +1 -1
- package/dist/cli/ui-deploy-pipeline-model.d.ts +70 -0
- package/dist/cli/ui-deploy-pipeline-model.d.ts.map +1 -0
- package/dist/cli/ui-deploy-pipeline-model.js +127 -0
- package/dist/cli/ui-deploy-pipeline-model.js.map +1 -0
- package/dist/cli/ui-deploy-pipeline.d.ts +25 -0
- package/dist/cli/ui-deploy-pipeline.d.ts.map +1 -0
- package/dist/cli/ui-deploy-pipeline.js +192 -0
- package/dist/cli/ui-deploy-pipeline.js.map +1 -0
- package/dist/cli/ui-detected-stacks.d.ts +20 -0
- package/dist/cli/ui-detected-stacks.d.ts.map +1 -0
- package/dist/cli/ui-detected-stacks.js +28 -0
- package/dist/cli/ui-detected-stacks.js.map +1 -0
- package/dist/cli/ui-enabled-plugins.d.ts +52 -0
- package/dist/cli/ui-enabled-plugins.d.ts.map +1 -0
- package/dist/cli/ui-enabled-plugins.js +253 -0
- package/dist/cli/ui-enabled-plugins.js.map +1 -0
- package/dist/cli/ui-github-repo-expected.d.ts +36 -0
- package/dist/cli/ui-github-repo-expected.d.ts.map +1 -0
- package/dist/cli/ui-github-repo-expected.js +118 -0
- package/dist/cli/ui-github-repo-expected.js.map +1 -0
- package/dist/cli/ui-github-repo-gh.d.ts +36 -0
- package/dist/cli/ui-github-repo-gh.d.ts.map +1 -0
- package/dist/cli/ui-github-repo-gh.js +112 -0
- package/dist/cli/ui-github-repo-gh.js.map +1 -0
- package/dist/cli/ui-github-repo-map.d.ts +25 -0
- package/dist/cli/ui-github-repo-map.d.ts.map +1 -0
- package/dist/cli/ui-github-repo-map.js +150 -0
- package/dist/cli/ui-github-repo-map.js.map +1 -0
- package/dist/cli/ui-github-repo.d.ts +51 -0
- package/dist/cli/ui-github-repo.d.ts.map +1 -0
- package/dist/cli/ui-github-repo.js +117 -0
- package/dist/cli/ui-github-repo.js.map +1 -0
- package/dist/cli/ui-observability-checks.d.ts +23 -0
- package/dist/cli/ui-observability-checks.d.ts.map +1 -0
- package/dist/cli/ui-observability-checks.js +156 -0
- package/dist/cli/ui-observability-checks.js.map +1 -0
- package/dist/cli/ui-observability-providers.d.ts +69 -0
- package/dist/cli/ui-observability-providers.d.ts.map +1 -0
- package/dist/cli/ui-observability-providers.js +99 -0
- package/dist/cli/ui-observability-providers.js.map +1 -0
- package/dist/core/learnings-budget-check.d.ts +42 -0
- package/dist/core/learnings-budget-check.d.ts.map +1 -0
- package/dist/core/learnings-budget-check.js +210 -0
- package/dist/core/learnings-budget-check.js.map +1 -0
- package/dist/core/learnings-document.js +6 -1
- package/dist/core/learnings-document.js.map +1 -1
- 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-agy/plugin.json +1 -1
- 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-cursor/.claude-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-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/scripts/check-learnings-budget.ts +29 -163
- package/ui/README.md +5 -3
- package/ui/index.html +1097 -432
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live-status probe for Deploy pipeline stages in `lisa ui`.
|
|
3
|
+
*
|
|
4
|
+
* Combines the project's `.github/workflows/deploy.yml` job sequence with
|
|
5
|
+
* live GitHub environment protection rules for each `github.environments`
|
|
6
|
+
* entry. READ-ONLY — never fabricates a hold/no-hold claim.
|
|
7
|
+
* @module cli/ui-deploy-pipeline
|
|
8
|
+
*/
|
|
9
|
+
import { execFile } from "node:child_process";
|
|
10
|
+
import { access, readFile } from "node:fs/promises";
|
|
11
|
+
import * as path from "node:path";
|
|
12
|
+
import { isJsonObject } from "../sync/json-path.js";
|
|
13
|
+
import { deepMerge, readJsonOrNull } from "../utils/index.js";
|
|
14
|
+
import { buildDeployPipelineResult, DEPLOY_PIPELINE_PROBE_ID, } from "./ui-deploy-pipeline-model.js";
|
|
15
|
+
export { assembleDeployPipelineStages, buildDeployPipelineResult, DEPLOY_PIPELINE_PROBE_ID, mapEnvironmentHoldStage, parseDeployWorkflowStages, } from "./ui-deploy-pipeline-model.js";
|
|
16
|
+
const DEPLOY_YML_RELATIVE = path.join(".github", "workflows", "deploy.yml");
|
|
17
|
+
const DEFAULT_TIMEOUT_MS = 8_000;
|
|
18
|
+
/**
|
|
19
|
+
* Read deploy.yml when present; null when the project has no deploy workflow.
|
|
20
|
+
* @param cwd - Project root
|
|
21
|
+
* @returns File contents or null
|
|
22
|
+
*/
|
|
23
|
+
async function readDeployWorkflowDefault(cwd) {
|
|
24
|
+
const filePath = path.join(cwd, DEPLOY_YML_RELATIVE);
|
|
25
|
+
try {
|
|
26
|
+
await access(filePath);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return await readFile(filePath, "utf8");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Read configured environment names from merged Lisa config.
|
|
35
|
+
* @param cwd - Project root
|
|
36
|
+
* @returns Stable key order from the merged `github.environments` map
|
|
37
|
+
*/
|
|
38
|
+
async function readConfiguredEnvironmentsDefault(cwd) {
|
|
39
|
+
const committed = await readJsonOrNull(path.join(cwd, ".lisa.config.json"));
|
|
40
|
+
const local = await readJsonOrNull(path.join(cwd, ".lisa.config.local.json"));
|
|
41
|
+
const merged = deepMerge(isJsonObject(committed) ? committed : {}, isJsonObject(local) ? local : {});
|
|
42
|
+
const github = merged.github;
|
|
43
|
+
if (!isJsonObject(github)) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
const environments = github.environments;
|
|
47
|
+
if (!isJsonObject(environments)) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
return Object.keys(environments);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Detect whether a gh failure means the CLI is not authenticated.
|
|
54
|
+
* @param stderr - Combined stderr/stdout from the failed command
|
|
55
|
+
* @returns Whether the failure is an authentication problem
|
|
56
|
+
*/
|
|
57
|
+
function isNotAuthenticatedFailure(stderr) {
|
|
58
|
+
const text = stderr.toLowerCase();
|
|
59
|
+
return (text.includes("not logged into") ||
|
|
60
|
+
text.includes("not authenticated") ||
|
|
61
|
+
text.includes("gh auth login") ||
|
|
62
|
+
text.includes("http 401") ||
|
|
63
|
+
text.includes("401 unauthorized") ||
|
|
64
|
+
text.includes("to re-authenticate") ||
|
|
65
|
+
text.includes("authentication required"));
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse a required-reviewers protection rule into a boolean hold signal.
|
|
69
|
+
* @param rules - Protection rules from one environment payload
|
|
70
|
+
* @returns True when at least one required reviewer is configured
|
|
71
|
+
*/
|
|
72
|
+
function protectionHasRequiredReviewers(rules) {
|
|
73
|
+
if (!Array.isArray(rules)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return rules.some(rule => {
|
|
77
|
+
if (!isJsonObject(rule) || rule.type !== "required_reviewers") {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const reviewers = rule.reviewers;
|
|
81
|
+
return Array.isArray(reviewers) && reviewers.length > 0;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Classify a failed `gh api` invocation without fabricating hold state.
|
|
86
|
+
* @param stderr - Command stderr
|
|
87
|
+
* @param errorMessage - Error message from execFile
|
|
88
|
+
* @returns not-authenticated or generic error lookup
|
|
89
|
+
*/
|
|
90
|
+
function classifyGithubEnvironmentsFailure(stderr, errorMessage) {
|
|
91
|
+
const detail = `${stderr}\n${errorMessage}`.trim();
|
|
92
|
+
if (isNotAuthenticatedFailure(detail)) {
|
|
93
|
+
return {
|
|
94
|
+
status: "not-authenticated",
|
|
95
|
+
message: detail.length > 0 ? detail : "GitHub CLI is not authenticated",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
status: "error",
|
|
100
|
+
message: detail.length > 0 ? detail : "Failed to list GitHub environments",
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Parse the jq-shaped environments array from `gh api`.
|
|
105
|
+
* @param stdout - Command stdout
|
|
106
|
+
* @returns ok lookup or parse error
|
|
107
|
+
*/
|
|
108
|
+
function parseGithubEnvironmentsStdout(stdout) {
|
|
109
|
+
try {
|
|
110
|
+
const parsed = JSON.parse(stdout);
|
|
111
|
+
if (!Array.isArray(parsed)) {
|
|
112
|
+
return {
|
|
113
|
+
status: "error",
|
|
114
|
+
message: "GitHub environments response was not an array",
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const environments = parsed.flatMap((entry) => {
|
|
118
|
+
if (!isJsonObject(entry) || typeof entry.name !== "string") {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
return [
|
|
122
|
+
{
|
|
123
|
+
name: entry.name,
|
|
124
|
+
hasRequiredReviewers: protectionHasRequiredReviewers(entry.protection_rules),
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
});
|
|
128
|
+
return { status: "ok", environments };
|
|
129
|
+
}
|
|
130
|
+
catch (parseError) {
|
|
131
|
+
return {
|
|
132
|
+
status: "error",
|
|
133
|
+
message: parseError instanceof Error
|
|
134
|
+
? parseError.message
|
|
135
|
+
: "Failed to parse GitHub environments response",
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* List GitHub Environments for the project's origin repo via `gh api`.
|
|
141
|
+
* @param cwd - Project root
|
|
142
|
+
* @param signal - Probe cancellation signal
|
|
143
|
+
* @param timeoutMs - Child-process timeout
|
|
144
|
+
* @returns Authenticated list, not-authenticated, or error
|
|
145
|
+
*/
|
|
146
|
+
export async function listGithubEnvironmentsViaGh(cwd, signal, timeoutMs) {
|
|
147
|
+
return await new Promise(resolve => {
|
|
148
|
+
const ghExecutable = "gh";
|
|
149
|
+
execFile(
|
|
150
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path -- fixed user-installed gh executable
|
|
151
|
+
ghExecutable, [
|
|
152
|
+
"api",
|
|
153
|
+
"repos/{owner}/{repo}/environments",
|
|
154
|
+
"--paginate",
|
|
155
|
+
"--jq",
|
|
156
|
+
"[.environments[]? | {name, protection_rules}]",
|
|
157
|
+
], { cwd, signal, timeout: timeoutMs, encoding: "utf8" }, (error, stdout, stderr) => {
|
|
158
|
+
if (error !== null) {
|
|
159
|
+
resolve(classifyGithubEnvironmentsFailure(stderr, error.message));
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
resolve(parseGithubEnvironmentsStdout(stdout));
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Create the probe that reports Deploy pipeline stages for `lisa ui`.
|
|
168
|
+
* @param cwd - Project root the console is serving
|
|
169
|
+
* @param dependencies - Injectable IO for focused tests
|
|
170
|
+
* @returns Status probe registered as `deploy-pipeline-stages`
|
|
171
|
+
*/
|
|
172
|
+
export function createDeployPipelineProbe(cwd, dependencies = {}) {
|
|
173
|
+
const readDeployWorkflow = dependencies.readDeployWorkflow ?? readDeployWorkflowDefault;
|
|
174
|
+
const readConfiguredEnvironments = dependencies.readConfiguredEnvironments ??
|
|
175
|
+
readConfiguredEnvironmentsDefault;
|
|
176
|
+
const listGithubEnvironments = dependencies.listGithubEnvironments ?? listGithubEnvironmentsViaGh;
|
|
177
|
+
return {
|
|
178
|
+
id: DEPLOY_PIPELINE_PROBE_ID,
|
|
179
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
180
|
+
run: async (signal) => {
|
|
181
|
+
const [workflow, configuredEnvironments] = await Promise.all([
|
|
182
|
+
readDeployWorkflow(cwd),
|
|
183
|
+
readConfiguredEnvironments(cwd),
|
|
184
|
+
]);
|
|
185
|
+
const lookup = configuredEnvironments.length === 0
|
|
186
|
+
? { status: "ok", environments: [] }
|
|
187
|
+
: await listGithubEnvironments(cwd, signal, DEFAULT_TIMEOUT_MS + 250);
|
|
188
|
+
return buildDeployPipelineResult(workflow, configuredEnvironments, lookup);
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=ui-deploy-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-deploy-pipeline.js","sourceRoot":"","sources":["../../src/cli/ui-deploy-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live-status probe for the console Stacks section.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors doctor's detection chain exactly so the console and `lisa doctor`
|
|
5
|
+
* can never disagree. An empty match is the honest empty value (`[]`), never
|
|
6
|
+
* unknown; the runner maps a thrown detector error to unknown.
|
|
7
|
+
* @module cli/ui-detected-stacks
|
|
8
|
+
*/
|
|
9
|
+
import { type DetectorRegistry } from "../detection/index.js";
|
|
10
|
+
import type { StatusProbe } from "./ui-status.js";
|
|
11
|
+
/** Probe id for the detected-stacks live-status entry. */
|
|
12
|
+
export declare const DETECTED_STACKS_PROBE_ID = "detected-stacks";
|
|
13
|
+
/**
|
|
14
|
+
* Create the probe that reports the project's detected stacks.
|
|
15
|
+
* @param destDir - Project root scanned by the detector registry
|
|
16
|
+
* @param registry - Injectable detector registry used by focused tests
|
|
17
|
+
* @returns Probe emitting the expanded, ordered project types
|
|
18
|
+
*/
|
|
19
|
+
export declare function createDetectedStacksProbe(destDir: string, registry?: DetectorRegistry): StatusProbe<string[]>;
|
|
20
|
+
//# sourceMappingURL=ui-detected-stacks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-detected-stacks.d.ts","sourceRoot":"","sources":["../../src/cli/ui-detected-stacks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,0DAA0D;AAC1D,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAE1D;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,gBAA2C,GACpD,WAAW,CAAC,MAAM,EAAE,CAAC,CAWvB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live-status probe for the console Stacks section.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors doctor's detection chain exactly so the console and `lisa doctor`
|
|
5
|
+
* can never disagree. An empty match is the honest empty value (`[]`), never
|
|
6
|
+
* unknown; the runner maps a thrown detector error to unknown.
|
|
7
|
+
* @module cli/ui-detected-stacks
|
|
8
|
+
*/
|
|
9
|
+
import { createDetectorRegistry, } from "../detection/index.js";
|
|
10
|
+
/** Probe id for the detected-stacks live-status entry. */
|
|
11
|
+
export const DETECTED_STACKS_PROBE_ID = "detected-stacks";
|
|
12
|
+
/**
|
|
13
|
+
* Create the probe that reports the project's detected stacks.
|
|
14
|
+
* @param destDir - Project root scanned by the detector registry
|
|
15
|
+
* @param registry - Injectable detector registry used by focused tests
|
|
16
|
+
* @returns Probe emitting the expanded, ordered project types
|
|
17
|
+
*/
|
|
18
|
+
export function createDetectedStacksProbe(destDir, registry = createDetectorRegistry()) {
|
|
19
|
+
return {
|
|
20
|
+
id: DETECTED_STACKS_PROBE_ID,
|
|
21
|
+
timeoutMs: 5_000,
|
|
22
|
+
run: async () => {
|
|
23
|
+
const types = registry.expandAndOrderTypes(await registry.detectAll(destDir));
|
|
24
|
+
return { state: "value", value: [...types] };
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=ui-detected-stacks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-detected-stacks.js","sourceRoot":"","sources":["../../src/cli/ui-detected-stacks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,sBAAsB,GAEvB,MAAM,uBAAuB,CAAC;AAG/B,0DAA0D;AAC1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,iBAAiB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAe,EACf,WAA6B,sBAAsB,EAAE;IAErD,OAAO;QACL,EAAE,EAAE,wBAAwB;QAC5B,SAAS,EAAE,KAAK;QAChB,GAAG,EAAE,KAAK,IAAI,EAAE;YACd,MAAM,KAAK,GAAG,QAAQ,CAAC,mBAAmB,CACxC,MAAM,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAClC,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { JsonValue } from "../sync/json-path.js";
|
|
2
|
+
import type { StatusProbe } from "./ui-status.js";
|
|
3
|
+
/** One plugin entry from a marketplace.json catalog. */
|
|
4
|
+
export type MarketplacePlugin = {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly description?: string;
|
|
7
|
+
};
|
|
8
|
+
/** One plugin row emitted by the enabled-plugins probe. */
|
|
9
|
+
export type EnabledPluginRow = {
|
|
10
|
+
readonly [key: string]: JsonValue;
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly status: "enabled" | "available";
|
|
13
|
+
readonly description: string;
|
|
14
|
+
};
|
|
15
|
+
/** Structured value emitted by the enabled-plugins live-status probe. */
|
|
16
|
+
export type EnabledPluginsValue = {
|
|
17
|
+
readonly [key: string]: JsonValue;
|
|
18
|
+
/** False when `.claude/settings.json` is absent (empty-state trigger). */
|
|
19
|
+
readonly settingsPresent: boolean;
|
|
20
|
+
/** Enabled and available-not-enabled plugins; never demo data. */
|
|
21
|
+
readonly plugins: EnabledPluginRow[];
|
|
22
|
+
};
|
|
23
|
+
/** Injectable collaborators for focused tests. */
|
|
24
|
+
export type EnabledPluginsProbeDependencies = {
|
|
25
|
+
/** Home directory used to locate `~/.claude/plugins/known_marketplaces.json`. */
|
|
26
|
+
readonly homedir?: () => string;
|
|
27
|
+
/** Override marketplace discovery for unit tests. */
|
|
28
|
+
readonly listMarketplacePlugins?: (cwd: string, home: string) => Promise<ReadonlyMap<string, string>>;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Collect plugin id → description from known Claude marketplaces on disk.
|
|
32
|
+
* @param cwd - Project root (checked for a local `.claude-plugin/marketplace.json`)
|
|
33
|
+
* @param home - Home directory containing `~/.claude/plugins`
|
|
34
|
+
* @returns Map of `plugin@marketplace` ids to descriptions
|
|
35
|
+
*/
|
|
36
|
+
export declare function listMarketplacePluginsFromDisk(cwd: string, home: string): Promise<ReadonlyMap<string, string>>;
|
|
37
|
+
/**
|
|
38
|
+
* Build the probe value from settings + marketplace catalog.
|
|
39
|
+
* @param settingsPresent - Whether settings.json existed
|
|
40
|
+
* @param enabledPlugins - Parsed enabledPlugins map (true = enabled)
|
|
41
|
+
* @param marketplace - Plugin id → description catalog
|
|
42
|
+
* @returns Structured probe value
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildEnabledPluginsValue(settingsPresent: boolean, enabledPlugins: Readonly<Record<string, boolean>>, marketplace: ReadonlyMap<string, string>): EnabledPluginsValue;
|
|
45
|
+
/**
|
|
46
|
+
* Create the probe that reports project plugin enablement vs marketplace availability.
|
|
47
|
+
* @param cwd - Project root containing `.claude/settings.json`
|
|
48
|
+
* @param dependencies - Injectable collaborators for focused tests
|
|
49
|
+
* @returns Probe emitting enabled / available-not-enabled rows, or unknown
|
|
50
|
+
*/
|
|
51
|
+
export declare function createEnabledPluginsProbe(cwd: string, dependencies?: EnabledPluginsProbeDependencies): StatusProbe<EnabledPluginsValue>;
|
|
52
|
+
//# sourceMappingURL=ui-enabled-plugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-enabled-plugins.d.ts","sourceRoot":"","sources":["../../src/cli/ui-enabled-plugins.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE/D,wDAAwD;AACxD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,2DAA2D;AAC3D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,WAAW,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,yEAAyE;AACzE,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAEF,kDAAkD;AAClD,MAAM,MAAM,+BAA+B,GAAG;IAC5C,iFAAiF;IACjF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;IAChC,qDAAqD;IACrD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAChC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C,CAAC;AA8FF;;;;;GAKG;AACH,wBAAsB,8BAA8B,CAClD,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBtC;AAkBD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,OAAO,EACxB,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACjD,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC,mBAAmB,CA+BrB;AAsFD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,EACX,YAAY,GAAE,+BAAoC,GACjD,WAAW,CAAC,mBAAmB,CAAC,CA2ClC"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live-status probe for the console Plugins & MCP section.
|
|
3
|
+
*
|
|
4
|
+
* Reads project `.claude/settings.json` `enabledPlugins` and joins against
|
|
5
|
+
* marketplace catalogs on disk. READ-ONLY — never fabricates enablement.
|
|
6
|
+
* @module cli/ui-enabled-plugins
|
|
7
|
+
*/
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
import { homedir as defaultHomedir } from "node:os";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
const ENABLED_PLUGINS_PROBE_ID = "enabled-plugins";
|
|
12
|
+
const SETTINGS_RELATIVE = path.join(".claude", "settings.json");
|
|
13
|
+
const MARKETPLACE_JSON = path.join(".claude-plugin", "marketplace.json");
|
|
14
|
+
/**
|
|
15
|
+
* Read and parse JSON with a real parser; never hand-roll.
|
|
16
|
+
* @param filePath - Absolute path to a JSON file
|
|
17
|
+
* @returns Parsed value
|
|
18
|
+
*/
|
|
19
|
+
async function readJsonFile(filePath) {
|
|
20
|
+
const content = await readFile(filePath, "utf8");
|
|
21
|
+
return JSON.parse(content);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extract `plugin@marketplace` → description pairs from one marketplace.json.
|
|
25
|
+
* @param marketplacePath - Absolute path to marketplace.json
|
|
26
|
+
* @param fallbackName - Name used when the file omits `name`
|
|
27
|
+
* @returns Catalog entries (may be empty on read/parse failure)
|
|
28
|
+
*/
|
|
29
|
+
async function readMarketplaceEntries(marketplacePath, fallbackName) {
|
|
30
|
+
try {
|
|
31
|
+
const parsed = await readJsonFile(marketplacePath);
|
|
32
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
const nameRaw = Reflect.get(parsed, "name");
|
|
36
|
+
const marketplaceName = typeof nameRaw === "string" && nameRaw.trim().length > 0
|
|
37
|
+
? nameRaw.trim()
|
|
38
|
+
: fallbackName;
|
|
39
|
+
const plugins = Reflect.get(parsed, "plugins");
|
|
40
|
+
if (!Array.isArray(plugins)) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
return plugins.flatMap(entry => {
|
|
44
|
+
if (typeof entry !== "object" || entry === null) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
const pluginName = Reflect.get(entry, "name");
|
|
48
|
+
if (typeof pluginName !== "string" || pluginName.trim().length === 0) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
const descriptionRaw = Reflect.get(entry, "description");
|
|
52
|
+
const description = typeof descriptionRaw === "string" ? descriptionRaw : "";
|
|
53
|
+
return [
|
|
54
|
+
[`${pluginName.trim()}@${marketplaceName}`, description],
|
|
55
|
+
];
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read install locations from `~/.claude/plugins/known_marketplaces.json`.
|
|
64
|
+
* @param home - Home directory
|
|
65
|
+
* @returns Marketplace name → installLocation pairs
|
|
66
|
+
*/
|
|
67
|
+
async function readKnownMarketplaceInstalls(home) {
|
|
68
|
+
const knownPath = path.join(home, ".claude", "plugins", "known_marketplaces.json");
|
|
69
|
+
try {
|
|
70
|
+
const known = await readJsonFile(knownPath);
|
|
71
|
+
if (typeof known !== "object" || known === null || Array.isArray(known)) {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
return Object.entries(known).flatMap(([marketplaceName, entry]) => {
|
|
75
|
+
if (typeof entry !== "object" || entry === null) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
const installLocation = Reflect.get(entry, "installLocation");
|
|
79
|
+
if (typeof installLocation !== "string" || installLocation.length === 0) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
return [[marketplaceName, installLocation]];
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Collect plugin id → description from known Claude marketplaces on disk.
|
|
91
|
+
* @param cwd - Project root (checked for a local `.claude-plugin/marketplace.json`)
|
|
92
|
+
* @param home - Home directory containing `~/.claude/plugins`
|
|
93
|
+
* @returns Map of `plugin@marketplace` ids to descriptions
|
|
94
|
+
*/
|
|
95
|
+
export async function listMarketplacePluginsFromDisk(cwd, home) {
|
|
96
|
+
const localEntries = await readMarketplaceEntries(path.join(cwd, MARKETPLACE_JSON), "lisa");
|
|
97
|
+
const installs = await readKnownMarketplaceInstalls(home);
|
|
98
|
+
const knownEntries = (await Promise.all(installs.map(async ([marketplaceName, installLocation]) => readMarketplaceEntries(path.join(installLocation, MARKETPLACE_JSON), marketplaceName)))).flat();
|
|
99
|
+
// Later entries win so the project's local marketplace takes precedence.
|
|
100
|
+
return new Map([...knownEntries, ...localEntries]);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Sort enabled rows before available, then by id.
|
|
104
|
+
* @param left - First row
|
|
105
|
+
* @param right - Second row
|
|
106
|
+
* @returns Comparator result
|
|
107
|
+
*/
|
|
108
|
+
function comparePluginRows(left, right) {
|
|
109
|
+
if (left.status !== right.status) {
|
|
110
|
+
return left.status === "enabled" ? -1 : 1;
|
|
111
|
+
}
|
|
112
|
+
return left.id.localeCompare(right.id);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Build the probe value from settings + marketplace catalog.
|
|
116
|
+
* @param settingsPresent - Whether settings.json existed
|
|
117
|
+
* @param enabledPlugins - Parsed enabledPlugins map (true = enabled)
|
|
118
|
+
* @param marketplace - Plugin id → description catalog
|
|
119
|
+
* @returns Structured probe value
|
|
120
|
+
*/
|
|
121
|
+
export function buildEnabledPluginsValue(settingsPresent, enabledPlugins, marketplace) {
|
|
122
|
+
if (!settingsPresent) {
|
|
123
|
+
return { settingsPresent: false, plugins: [] };
|
|
124
|
+
}
|
|
125
|
+
const enabledRows = Object.entries(enabledPlugins)
|
|
126
|
+
.filter((entry) => typeof entry[0] === "string" &&
|
|
127
|
+
entry[0].trim().length > 0 &&
|
|
128
|
+
entry[1] === true)
|
|
129
|
+
.map(([id]) => ({
|
|
130
|
+
id,
|
|
131
|
+
status: "enabled",
|
|
132
|
+
description: marketplace.get(id) ?? "",
|
|
133
|
+
}));
|
|
134
|
+
const enabledIds = new Set(enabledRows.map(row => row.id));
|
|
135
|
+
const availableRows = [...marketplace.entries()]
|
|
136
|
+
.filter(([id]) => !enabledIds.has(id))
|
|
137
|
+
.map(([id, description]) => ({
|
|
138
|
+
id,
|
|
139
|
+
status: "available",
|
|
140
|
+
description,
|
|
141
|
+
}));
|
|
142
|
+
return {
|
|
143
|
+
settingsPresent: true,
|
|
144
|
+
plugins: [...enabledRows, ...availableRows].sort(comparePluginRows),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Parse `enabledPlugins` from a settings document.
|
|
149
|
+
* @param settings - Parsed settings.json root
|
|
150
|
+
* @returns Map of plugin id → enabled, or an error reason
|
|
151
|
+
*/
|
|
152
|
+
function parseEnabledPluginsMap(settings) {
|
|
153
|
+
if (typeof settings !== "object" ||
|
|
154
|
+
settings === null ||
|
|
155
|
+
Array.isArray(settings)) {
|
|
156
|
+
return {
|
|
157
|
+
ok: false,
|
|
158
|
+
reason: "invalid-settings",
|
|
159
|
+
message: ".claude/settings.json did not contain a JSON object",
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (!Object.hasOwn(settings, "enabledPlugins")) {
|
|
163
|
+
return { ok: true, map: {} };
|
|
164
|
+
}
|
|
165
|
+
const enabledPlugins = Reflect.get(settings, "enabledPlugins");
|
|
166
|
+
if (typeof enabledPlugins !== "object" ||
|
|
167
|
+
enabledPlugins === null ||
|
|
168
|
+
Array.isArray(enabledPlugins)) {
|
|
169
|
+
return {
|
|
170
|
+
ok: false,
|
|
171
|
+
reason: "invalid-enabled-plugins",
|
|
172
|
+
message: "enabledPlugins must be a JSON object map of plugin id → boolean",
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const map = Object.fromEntries(Object.entries(enabledPlugins).filter((entry) => typeof entry[1] === "boolean"));
|
|
176
|
+
return { ok: true, map };
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Classify a settings.json read failure into empty vs unknown.
|
|
180
|
+
* @param error - Thrown value from read/parse
|
|
181
|
+
* @returns Probe outcome when the file cannot be used
|
|
182
|
+
*/
|
|
183
|
+
function classifySettingsReadError(error) {
|
|
184
|
+
const code = typeof error === "object" &&
|
|
185
|
+
error !== null &&
|
|
186
|
+
"code" in error &&
|
|
187
|
+
typeof Reflect.get(error, "code") === "string"
|
|
188
|
+
? Reflect.get(error, "code")
|
|
189
|
+
: undefined;
|
|
190
|
+
if (code === "ENOENT") {
|
|
191
|
+
return { missing: true };
|
|
192
|
+
}
|
|
193
|
+
if (error instanceof SyntaxError) {
|
|
194
|
+
return {
|
|
195
|
+
state: "unknown",
|
|
196
|
+
reason: "unparseable-settings",
|
|
197
|
+
message: error.message.trim().length > 0
|
|
198
|
+
? error.message
|
|
199
|
+
: ".claude/settings.json could not be parsed as JSON",
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const message = error instanceof Error && error.message.trim().length > 0
|
|
203
|
+
? error.message
|
|
204
|
+
: "Failed to read .claude/settings.json";
|
|
205
|
+
return {
|
|
206
|
+
state: "unknown",
|
|
207
|
+
reason: "settings-read-failed",
|
|
208
|
+
message,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Create the probe that reports project plugin enablement vs marketplace availability.
|
|
213
|
+
* @param cwd - Project root containing `.claude/settings.json`
|
|
214
|
+
* @param dependencies - Injectable collaborators for focused tests
|
|
215
|
+
* @returns Probe emitting enabled / available-not-enabled rows, or unknown
|
|
216
|
+
*/
|
|
217
|
+
export function createEnabledPluginsProbe(cwd, dependencies = {}) {
|
|
218
|
+
const resolveHome = dependencies.homedir ?? defaultHomedir;
|
|
219
|
+
const listMarketplace = dependencies.listMarketplacePlugins ?? listMarketplacePluginsFromDisk;
|
|
220
|
+
return {
|
|
221
|
+
id: ENABLED_PLUGINS_PROBE_ID,
|
|
222
|
+
timeoutMs: 5_000,
|
|
223
|
+
run: async () => {
|
|
224
|
+
const settingsPath = path.join(cwd, SETTINGS_RELATIVE);
|
|
225
|
+
const loaded = await readJsonFile(settingsPath).then(settings => ({ ok: true, settings }), (error) => ({ ok: false, error }));
|
|
226
|
+
if (!loaded.ok) {
|
|
227
|
+
const classified = classifySettingsReadError(loaded.error);
|
|
228
|
+
if (!("missing" in classified)) {
|
|
229
|
+
return classified;
|
|
230
|
+
}
|
|
231
|
+
const marketplace = await listMarketplace(cwd, resolveHome());
|
|
232
|
+
return {
|
|
233
|
+
state: "value",
|
|
234
|
+
value: buildEnabledPluginsValue(false, {}, marketplace),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const parsed = parseEnabledPluginsMap(loaded.settings);
|
|
238
|
+
if (!parsed.ok) {
|
|
239
|
+
return {
|
|
240
|
+
state: "unknown",
|
|
241
|
+
reason: parsed.reason,
|
|
242
|
+
message: parsed.message,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
const marketplace = await listMarketplace(cwd, resolveHome());
|
|
246
|
+
return {
|
|
247
|
+
state: "value",
|
|
248
|
+
value: buildEnabledPluginsValue(true, parsed.map, marketplace),
|
|
249
|
+
};
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=ui-enabled-plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-enabled-plugins.js","sourceRoot":"","sources":["../../src/cli/ui-enabled-plugins.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAsClC,MAAM,wBAAwB,GAAG,iBAAiB,CAAC;AACnD,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;AAEzE;;;;GAIG;AACH,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC1C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,sBAAsB,CACnC,eAAuB,EACvB,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,CAAC;QACnD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,eAAe,GACnB,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YACtD,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE;YAChB,CAAC,CAAC,YAAY,CAAC;QACnB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBAChD,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC9C,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrE,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;YACzD,MAAM,WAAW,GACf,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,OAAO;gBACL,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,eAAe,EAAE,EAAE,WAAW,CAAC;aAChD,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,4BAA4B,CACzC,IAAY;IAEZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CACzB,IAAI,EACJ,SAAS,EACT,SAAS,EACT,yBAAyB,CAC1B,CAAC;IACF,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxE,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,EAAE;YAChE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBAChD,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;YAC9D,IAAI,OAAO,eAAe,KAAK,QAAQ,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxE,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,CAAC,CAAC,eAAe,EAAE,eAAe,CAAC,CAAU,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,GAAW,EACX,IAAY;IAEZ,MAAM,YAAY,GAAG,MAAM,sBAAsB,CAC/C,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAChC,MAAM,CACP,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,4BAA4B,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,CACnB,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC,EAAE,EAAE,CACxD,sBAAsB,CACpB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAC5C,eAAe,CAChB,CACF,CACF,CACF,CAAC,IAAI,EAAE,CAAC;IACT,yEAAyE;IACzE,OAAO,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CACxB,IAAsB,EACtB,KAAuB;IAEvB,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,eAAwB,EACxB,cAAiD,EACjD,WAAwC;IAExC,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,WAAW,GAAuB,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;SACnE,MAAM,CACL,CAAC,KAAK,EAA2B,EAAE,CACjC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ;QAC5B,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QAC1B,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CACpB;SACA,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACd,EAAE;QACF,MAAM,EAAE,SAAkB;QAC1B,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;KACvC,CAAC,CAAC,CAAC;IAEN,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAuB,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;SACjE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SACrC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3B,EAAE;QACF,MAAM,EAAE,WAAoB;QAC5B,WAAW;KACZ,CAAC,CAAC,CAAC;IAEN,OAAO;QACL,eAAe,EAAE,IAAI;QACrB,OAAO,EAAE,CAAC,GAAG,WAAW,EAAE,GAAG,aAAa,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;KACpE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAC7B,QAAiB;IAIjB,IACE,OAAO,QAAQ,KAAK,QAAQ;QAC5B,QAAQ,KAAK,IAAI;QACjB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EACvB,CAAC;QACD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,kBAAkB;YAC1B,OAAO,EAAE,qDAAqD;SAC/D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,CAAC;QAC/C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;IAC/B,CAAC;IACD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IAC/D,IACE,OAAO,cAAc,KAAK,QAAQ;QAClC,cAAc,KAAK,IAAI;QACvB,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAC7B,CAAC;QACD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,yBAAyB;YACjC,OAAO,EACL,iEAAiE;SACpE,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAC5B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,MAAM,CACnC,CAAC,KAAK,EAA8B,EAAE,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CACrE,CACF,CAAC;IACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,SAAS,yBAAyB,CAChC,KAAc;IAEd,MAAM,IAAI,GACR,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,QAAQ;QAC5C,CAAC,CAAE,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAY;QACxC,CAAC,CAAC,SAAS,CAAC;IAChB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IACD,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,sBAAsB;YAC9B,OAAO,EACL,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;gBAC7B,CAAC,CAAC,KAAK,CAAC,OAAO;gBACf,CAAC,CAAC,mDAAmD;SAC1D,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QACvD,CAAC,CAAC,KAAK,CAAC,OAAO;QACf,CAAC,CAAC,sCAAsC,CAAC;IAC7C,OAAO;QACL,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,sBAAsB;QAC9B,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,GAAW,EACX,eAAgD,EAAE;IAElD,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,IAAI,cAAc,CAAC;IAC3D,MAAM,eAAe,GACnB,YAAY,CAAC,sBAAsB,IAAI,8BAA8B,CAAC;IAExE,OAAO;QACL,EAAE,EAAE,wBAAwB;QAC5B,SAAS,EAAE,KAAK;QAChB,GAAG,EAAE,KAAK,IAA+C,EAAE;YACzD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC,IAAI,CAClD,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAa,EAAE,QAAQ,EAAE,CAAC,EAC7C,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAc,EAAE,KAAK,EAAE,CAAC,CACpD,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,UAAU,GAAG,yBAAyB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC3D,IAAI,CAAC,CAAC,SAAS,IAAI,UAAU,CAAC,EAAE,CAAC;oBAC/B,OAAO,UAAU,CAAC;gBACpB,CAAC;gBACD,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC9D,OAAO;oBACL,KAAK,EAAE,OAAO;oBACd,KAAK,EAAE,wBAAwB,CAAC,KAAK,EAAE,EAAE,EAAE,WAAW,CAAC;iBACxD,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO;oBACL,KAAK,EAAE,SAAS;oBAChB,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB,CAAC;YACJ,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;YAC9D,OAAO;gBACL,KAAK,EAAE,OAAO;gBACd,KAAK,EAAE,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC;aAC/D,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expected labels and secrets for the GitHub repository live-status panel.
|
|
3
|
+
* @module cli/ui-github-repo-expected
|
|
4
|
+
*/
|
|
5
|
+
import type { JsonObject } from "../sync/json-path.js";
|
|
6
|
+
/** One config-expected lifecycle label. */
|
|
7
|
+
export interface ExpectedLabel {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly role: string;
|
|
10
|
+
}
|
|
11
|
+
/** One workflow-expected repository secret (presence only). */
|
|
12
|
+
export interface ExpectedSecret {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly purpose: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Secrets Lisa creates or expects workflows to consume.
|
|
18
|
+
* Presence is checked via `gh secret list`; values are never read.
|
|
19
|
+
*/
|
|
20
|
+
export declare const EXPECTED_GITHUB_SECRETS: readonly ExpectedSecret[];
|
|
21
|
+
/**
|
|
22
|
+
* Flatten `github.labels` from merged config into expected label rows.
|
|
23
|
+
* @param config - Merged Lisa project config
|
|
24
|
+
* @returns Expected labels with human-readable role paths
|
|
25
|
+
*/
|
|
26
|
+
export declare function expectedLabelsFromConfig(config: JsonObject): readonly ExpectedLabel[];
|
|
27
|
+
/**
|
|
28
|
+
* Read configured github.org / github.repo when both are non-empty strings.
|
|
29
|
+
* @param config - Merged Lisa project config
|
|
30
|
+
* @returns Owner and repo, or undefined when either is missing
|
|
31
|
+
*/
|
|
32
|
+
export declare function configuredGithubRepo(config: JsonObject): {
|
|
33
|
+
readonly owner: string;
|
|
34
|
+
readonly repo: string;
|
|
35
|
+
} | undefined;
|
|
36
|
+
//# sourceMappingURL=ui-github-repo-expected.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-github-repo-expected.d.ts","sourceRoot":"","sources":["../../src/cli/ui-github-repo-expected.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,sBAAsB,CAAC;AAElE,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,cAAc,EAgE5D,CAAC;AAuBF;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,UAAU,GACjB,SAAS,aAAa,EAAE,CAU1B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,GACjB;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAgB/D"}
|