@codyswann/lisa 2.235.0 → 2.236.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 (105) hide show
  1. package/dist/cli/ui-automations-adapters.d.ts +50 -0
  2. package/dist/cli/ui-automations-adapters.d.ts.map +1 -0
  3. package/dist/cli/ui-automations-adapters.js +162 -0
  4. package/dist/cli/ui-automations-adapters.js.map +1 -0
  5. package/dist/cli/ui-automations.d.ts +89 -0
  6. package/dist/cli/ui-automations.d.ts.map +1 -0
  7. package/dist/cli/ui-automations.js +148 -0
  8. package/dist/cli/ui-automations.js.map +1 -0
  9. package/dist/cli/ui-cmd.d.ts +5 -0
  10. package/dist/cli/ui-cmd.d.ts.map +1 -1
  11. package/dist/cli/ui-cmd.js +17 -0
  12. package/dist/cli/ui-cmd.js.map +1 -1
  13. package/dist/cli/ui-deploy-pipeline-model.d.ts +70 -0
  14. package/dist/cli/ui-deploy-pipeline-model.d.ts.map +1 -0
  15. package/dist/cli/ui-deploy-pipeline-model.js +127 -0
  16. package/dist/cli/ui-deploy-pipeline-model.js.map +1 -0
  17. package/dist/cli/ui-deploy-pipeline.d.ts +25 -0
  18. package/dist/cli/ui-deploy-pipeline.d.ts.map +1 -0
  19. package/dist/cli/ui-deploy-pipeline.js +192 -0
  20. package/dist/cli/ui-deploy-pipeline.js.map +1 -0
  21. package/dist/cli/ui-detected-stacks.d.ts +20 -0
  22. package/dist/cli/ui-detected-stacks.d.ts.map +1 -0
  23. package/dist/cli/ui-detected-stacks.js +28 -0
  24. package/dist/cli/ui-detected-stacks.js.map +1 -0
  25. package/dist/cli/ui-enabled-plugins.d.ts +52 -0
  26. package/dist/cli/ui-enabled-plugins.d.ts.map +1 -0
  27. package/dist/cli/ui-enabled-plugins.js +253 -0
  28. package/dist/cli/ui-enabled-plugins.js.map +1 -0
  29. package/dist/cli/ui-github-repo-expected.d.ts +36 -0
  30. package/dist/cli/ui-github-repo-expected.d.ts.map +1 -0
  31. package/dist/cli/ui-github-repo-expected.js +118 -0
  32. package/dist/cli/ui-github-repo-expected.js.map +1 -0
  33. package/dist/cli/ui-github-repo-gh.d.ts +36 -0
  34. package/dist/cli/ui-github-repo-gh.d.ts.map +1 -0
  35. package/dist/cli/ui-github-repo-gh.js +112 -0
  36. package/dist/cli/ui-github-repo-gh.js.map +1 -0
  37. package/dist/cli/ui-github-repo-map.d.ts +25 -0
  38. package/dist/cli/ui-github-repo-map.d.ts.map +1 -0
  39. package/dist/cli/ui-github-repo-map.js +150 -0
  40. package/dist/cli/ui-github-repo-map.js.map +1 -0
  41. package/dist/cli/ui-github-repo.d.ts +51 -0
  42. package/dist/cli/ui-github-repo.d.ts.map +1 -0
  43. package/dist/cli/ui-github-repo.js +117 -0
  44. package/dist/cli/ui-github-repo.js.map +1 -0
  45. package/dist/cli/ui-observability-checks.d.ts +23 -0
  46. package/dist/cli/ui-observability-checks.d.ts.map +1 -0
  47. package/dist/cli/ui-observability-checks.js +156 -0
  48. package/dist/cli/ui-observability-checks.js.map +1 -0
  49. package/dist/cli/ui-observability-providers.d.ts +69 -0
  50. package/dist/cli/ui-observability-providers.d.ts.map +1 -0
  51. package/dist/cli/ui-observability-providers.js +99 -0
  52. package/dist/cli/ui-observability-providers.js.map +1 -0
  53. package/package.json +1 -1
  54. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  56. package/plugins/lisa-agy/plugin.json +1 -1
  57. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  59. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  60. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  66. package/plugins/lisa-expo-agy/plugin.json +1 -1
  67. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  71. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  72. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  76. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  77. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  81. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  82. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  86. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  87. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  91. package/plugins/lisa-rails-agy/plugin.json +1 -1
  92. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  96. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  97. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  100. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  101. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  102. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  104. package/ui/README.md +5 -3
  105. package/ui/index.html +1097 -432
@@ -0,0 +1,70 @@
1
+ import { type JsonValue } from "../sync/json-path.js";
2
+ import type { ProbeResult } from "./ui-status.js";
3
+ /** Stable probe id consumed by the Deploy section hydration. */
4
+ export declare const DEPLOY_PIPELINE_PROBE_ID = "deploy-pipeline-stages";
5
+ /** One row in the Deploy pipeline stages table. */
6
+ export type DeployPipelineStage = {
7
+ readonly [key: string]: JsonValue;
8
+ readonly id: string;
9
+ readonly name: string;
10
+ readonly description: string;
11
+ /** Configured GitHub environment name, or empty for workflow jobs. */
12
+ readonly environment: string;
13
+ /**
14
+ * Active column: `true` = hold/job present, `false` = no hold,
15
+ * `"unknown"` = cannot claim hold/no-hold without lying.
16
+ */
17
+ readonly active: boolean | "unknown";
18
+ /** Required when `active` is false or unknown; empty otherwise. */
19
+ readonly reason: string;
20
+ };
21
+ /** Structured value emitted by the deploy-pipeline-stages probe. */
22
+ export type DeployPipelineValue = {
23
+ readonly [key: string]: JsonValue;
24
+ readonly stages: DeployPipelineStage[];
25
+ };
26
+ /** One GitHub environment as returned by the Environments API. */
27
+ export type GithubEnvironmentInfo = {
28
+ readonly name: string;
29
+ readonly hasRequiredReviewers: boolean;
30
+ };
31
+ /** Result of listing GitHub environments — never invents a concrete hold. */
32
+ export type GithubEnvironmentsLookup = {
33
+ readonly status: "ok";
34
+ readonly environments: readonly GithubEnvironmentInfo[];
35
+ } | {
36
+ readonly status: "not-authenticated";
37
+ readonly message: string;
38
+ } | {
39
+ readonly status: "error";
40
+ readonly message: string;
41
+ };
42
+ /**
43
+ * Extract ordered job stages from a deploy.yml document.
44
+ * @param contents - Raw YAML text
45
+ * @returns Workflow job stages in document order
46
+ */
47
+ export declare function parseDeployWorkflowStages(contents: string): readonly DeployPipelineStage[];
48
+ /**
49
+ * Map one configured environment onto a hold stage using live GH evidence.
50
+ * @param environment - Configured environment name
51
+ * @param lookup - Live environments API result
52
+ * @returns Approval-hold stage that never false-greens
53
+ */
54
+ export declare function mapEnvironmentHoldStage(environment: string, lookup: GithubEnvironmentsLookup): DeployPipelineStage;
55
+ /**
56
+ * Interleave approval holds before the first release job (or append).
57
+ * @param jobStages - Stages parsed from deploy.yml
58
+ * @param holdStages - Per-environment approval hold stages
59
+ * @returns Ordered pipeline stages for the console table
60
+ */
61
+ export declare function assembleDeployPipelineStages(jobStages: readonly DeployPipelineStage[], holdStages: readonly DeployPipelineStage[]): readonly DeployPipelineStage[];
62
+ /**
63
+ * Build the tri-state probe result from filesystem + live environment inputs.
64
+ * @param workflow - deploy.yml contents, or null when absent
65
+ * @param configuredEnvironments - Keys from github.environments
66
+ * @param lookup - Live GitHub environments lookup
67
+ * @returns Probe result — value, not-applicable, or unknown
68
+ */
69
+ export declare function buildDeployPipelineResult(workflow: string | null, configuredEnvironments: readonly string[], lookup: GithubEnvironmentsLookup): ProbeResult<DeployPipelineValue>;
70
+ //# sourceMappingURL=ui-deploy-pipeline-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-deploy-pipeline-model.d.ts","sourceRoot":"","sources":["../../src/cli/ui-deploy-pipeline-model.ts"],"names":[],"mappings":"AAKA,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,gEAAgE;AAChE,eAAO,MAAM,wBAAwB,2BAA2B,CAAC;AAKjE,mDAAmD;AACnD,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC;CACxC,CAAC;AAEF,kEAAkE;AAClE,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;CACxC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,MAAM,wBAAwB,GAChC;IACE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACzD,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GACf,SAAS,mBAAmB,EAAE,CA2BhC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,wBAAwB,GAC/B,mBAAmB,CAqCrB;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,SAAS,mBAAmB,EAAE,EACzC,UAAU,EAAE,SAAS,mBAAmB,EAAE,GACzC,SAAS,mBAAmB,EAAE,CAkBhC;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,sBAAsB,EAAE,SAAS,MAAM,EAAE,EACzC,MAAM,EAAE,wBAAwB,GAC/B,WAAW,CAAC,mBAAmB,CAAC,CAWlC"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Pure model for Deploy pipeline stages — parse deploy.yml, map holds, assemble.
3
+ * @module cli/ui-deploy-pipeline-model
4
+ */
5
+ import yaml from "js-yaml";
6
+ import { isJsonObject } from "../sync/json-path.js";
7
+ /** Stable probe id consumed by the Deploy section hydration. */
8
+ export const DEPLOY_PIPELINE_PROBE_ID = "deploy-pipeline-stages";
9
+ const NOT_AUTHENTICATED_REASON = "not-authenticated";
10
+ const ENVIRONMENT_NOT_FOUND_REASON = "environment-not-found";
11
+ /**
12
+ * Extract ordered job stages from a deploy.yml document.
13
+ * @param contents - Raw YAML text
14
+ * @returns Workflow job stages in document order
15
+ */
16
+ export function parseDeployWorkflowStages(contents) {
17
+ try {
18
+ const loaded = yaml.load(contents);
19
+ if (!isJsonObject(loaded)) {
20
+ return [];
21
+ }
22
+ const jobs = loaded.jobs;
23
+ if (!isJsonObject(jobs)) {
24
+ return [];
25
+ }
26
+ return Object.entries(jobs).map(([id, job]) => {
27
+ const name = isJsonObject(job) && typeof job.name === "string" && job.name.length > 0
28
+ ? job.name
29
+ : id;
30
+ return {
31
+ id: `job:${id}`,
32
+ name,
33
+ description: `Workflow job \`${id}\` from deploy.yml`,
34
+ environment: "",
35
+ active: true,
36
+ reason: "",
37
+ };
38
+ });
39
+ }
40
+ catch {
41
+ return [];
42
+ }
43
+ }
44
+ /**
45
+ * Map one configured environment onto a hold stage using live GH evidence.
46
+ * @param environment - Configured environment name
47
+ * @param lookup - Live environments API result
48
+ * @returns Approval-hold stage that never false-greens
49
+ */
50
+ export function mapEnvironmentHoldStage(environment, lookup) {
51
+ const base = {
52
+ id: `hold:${environment}`,
53
+ name: `Release approval — ${environment}`,
54
+ description: `Pauses at the release_approval job until a configured reviewer approves the GitHub environment \`${environment}\``,
55
+ environment,
56
+ };
57
+ if (lookup.status === "not-authenticated") {
58
+ return {
59
+ ...base,
60
+ active: "unknown",
61
+ reason: `${NOT_AUTHENTICATED_REASON}: ${lookup.message}`,
62
+ };
63
+ }
64
+ if (lookup.status === "error") {
65
+ return {
66
+ ...base,
67
+ active: "unknown",
68
+ reason: `environments-api-error: ${lookup.message}`,
69
+ };
70
+ }
71
+ const match = lookup.environments.find(entry => entry.name === environment);
72
+ if (match === undefined) {
73
+ return {
74
+ ...base,
75
+ active: "unknown",
76
+ reason: `${ENVIRONMENT_NOT_FOUND_REASON}: GitHub environment '${environment}' is named in github.environments but was not found on the repository`,
77
+ };
78
+ }
79
+ if (match.hasRequiredReviewers) {
80
+ return { ...base, active: true, reason: "" };
81
+ }
82
+ return {
83
+ ...base,
84
+ active: false,
85
+ reason: `No required reviewers on GitHub environment '${environment}'`,
86
+ };
87
+ }
88
+ /**
89
+ * Interleave approval holds before the first release job (or append).
90
+ * @param jobStages - Stages parsed from deploy.yml
91
+ * @param holdStages - Per-environment approval hold stages
92
+ * @returns Ordered pipeline stages for the console table
93
+ */
94
+ export function assembleDeployPipelineStages(jobStages, holdStages) {
95
+ if (holdStages.length === 0) {
96
+ return jobStages;
97
+ }
98
+ if (jobStages.length === 0) {
99
+ return holdStages;
100
+ }
101
+ const releaseIndex = jobStages.findIndex(stage => /release/iu.test(stage.id) || /release/iu.test(stage.name));
102
+ if (releaseIndex === -1) {
103
+ return [...jobStages, ...holdStages];
104
+ }
105
+ return [
106
+ ...jobStages.slice(0, releaseIndex),
107
+ ...holdStages,
108
+ ...jobStages.slice(releaseIndex),
109
+ ];
110
+ }
111
+ /**
112
+ * Build the tri-state probe result from filesystem + live environment inputs.
113
+ * @param workflow - deploy.yml contents, or null when absent
114
+ * @param configuredEnvironments - Keys from github.environments
115
+ * @param lookup - Live GitHub environments lookup
116
+ * @returns Probe result — value, not-applicable, or unknown
117
+ */
118
+ export function buildDeployPipelineResult(workflow, configuredEnvironments, lookup) {
119
+ const jobStages = workflow === null ? [] : parseDeployWorkflowStages(workflow);
120
+ const holdStages = configuredEnvironments.map(name => mapEnvironmentHoldStage(name, lookup));
121
+ const stages = assembleDeployPipelineStages(jobStages, holdStages);
122
+ if (stages.length === 0) {
123
+ return { state: "not-applicable" };
124
+ }
125
+ return { state: "value", value: { stages: [...stages] } };
126
+ }
127
+ //# sourceMappingURL=ui-deploy-pipeline-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-deploy-pipeline-model.js","sourceRoot":"","sources":["../../src/cli/ui-deploy-pipeline-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { StatusProbe } from "./ui-status.js";
2
+ import { type DeployPipelineValue, type GithubEnvironmentsLookup } from "./ui-deploy-pipeline-model.js";
3
+ export { assembleDeployPipelineStages, buildDeployPipelineResult, DEPLOY_PIPELINE_PROBE_ID, mapEnvironmentHoldStage, parseDeployWorkflowStages, type DeployPipelineStage, type DeployPipelineValue, type GithubEnvironmentInfo, type GithubEnvironmentsLookup, } from "./ui-deploy-pipeline-model.js";
4
+ /** Injectable collaborators for focused unit tests. */
5
+ export type DeployPipelineDependencies = {
6
+ readonly readDeployWorkflow?: (cwd: string) => Promise<string | null>;
7
+ readonly readConfiguredEnvironments?: (cwd: string) => Promise<readonly string[]>;
8
+ readonly listGithubEnvironments?: (cwd: string, signal: AbortSignal, timeoutMs: number) => Promise<GithubEnvironmentsLookup>;
9
+ };
10
+ /**
11
+ * List GitHub Environments for the project's origin repo via `gh api`.
12
+ * @param cwd - Project root
13
+ * @param signal - Probe cancellation signal
14
+ * @param timeoutMs - Child-process timeout
15
+ * @returns Authenticated list, not-authenticated, or error
16
+ */
17
+ export declare function listGithubEnvironmentsViaGh(cwd: string, signal: AbortSignal, timeoutMs: number): Promise<GithubEnvironmentsLookup>;
18
+ /**
19
+ * Create the probe that reports Deploy pipeline stages for `lisa ui`.
20
+ * @param cwd - Project root the console is serving
21
+ * @param dependencies - Injectable IO for focused tests
22
+ * @returns Status probe registered as `deploy-pipeline-stages`
23
+ */
24
+ export declare function createDeployPipelineProbe(cwd: string, dependencies?: DeployPipelineDependencies): StatusProbe<DeployPipelineValue>;
25
+ //# sourceMappingURL=ui-deploy-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-deploy-pipeline.d.ts","sourceRoot":"","sources":["../../src/cli/ui-deploy-pipeline.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAGL,KAAK,mBAAmB,EAExB,KAAK,wBAAwB,EAC9B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,GAC9B,MAAM,+BAA+B,CAAC;AAKvC,uDAAuD;AACvD,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtE,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CACpC,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAChC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACxC,CAAC;AAkJF;;;;;;GAMG;AACH,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,wBAAwB,CAAC,CAuBnC;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,EACX,YAAY,GAAE,0BAA+B,GAC5C,WAAW,CAAC,mBAAmB,CAAC,CA2BlC"}
@@ -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"}