@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.
Files changed (120) hide show
  1. package/dist/cli/check-learnings-budget-cmd.d.ts +20 -0
  2. package/dist/cli/check-learnings-budget-cmd.d.ts.map +1 -0
  3. package/dist/cli/check-learnings-budget-cmd.js +59 -0
  4. package/dist/cli/check-learnings-budget-cmd.js.map +1 -0
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -1
  7. package/dist/cli/index.js +29 -1
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/cli/ui-automations-adapters.d.ts +50 -0
  10. package/dist/cli/ui-automations-adapters.d.ts.map +1 -0
  11. package/dist/cli/ui-automations-adapters.js +162 -0
  12. package/dist/cli/ui-automations-adapters.js.map +1 -0
  13. package/dist/cli/ui-automations.d.ts +89 -0
  14. package/dist/cli/ui-automations.d.ts.map +1 -0
  15. package/dist/cli/ui-automations.js +148 -0
  16. package/dist/cli/ui-automations.js.map +1 -0
  17. package/dist/cli/ui-cmd.d.ts +5 -0
  18. package/dist/cli/ui-cmd.d.ts.map +1 -1
  19. package/dist/cli/ui-cmd.js +17 -0
  20. package/dist/cli/ui-cmd.js.map +1 -1
  21. package/dist/cli/ui-deploy-pipeline-model.d.ts +70 -0
  22. package/dist/cli/ui-deploy-pipeline-model.d.ts.map +1 -0
  23. package/dist/cli/ui-deploy-pipeline-model.js +127 -0
  24. package/dist/cli/ui-deploy-pipeline-model.js.map +1 -0
  25. package/dist/cli/ui-deploy-pipeline.d.ts +25 -0
  26. package/dist/cli/ui-deploy-pipeline.d.ts.map +1 -0
  27. package/dist/cli/ui-deploy-pipeline.js +192 -0
  28. package/dist/cli/ui-deploy-pipeline.js.map +1 -0
  29. package/dist/cli/ui-detected-stacks.d.ts +20 -0
  30. package/dist/cli/ui-detected-stacks.d.ts.map +1 -0
  31. package/dist/cli/ui-detected-stacks.js +28 -0
  32. package/dist/cli/ui-detected-stacks.js.map +1 -0
  33. package/dist/cli/ui-enabled-plugins.d.ts +52 -0
  34. package/dist/cli/ui-enabled-plugins.d.ts.map +1 -0
  35. package/dist/cli/ui-enabled-plugins.js +253 -0
  36. package/dist/cli/ui-enabled-plugins.js.map +1 -0
  37. package/dist/cli/ui-github-repo-expected.d.ts +36 -0
  38. package/dist/cli/ui-github-repo-expected.d.ts.map +1 -0
  39. package/dist/cli/ui-github-repo-expected.js +118 -0
  40. package/dist/cli/ui-github-repo-expected.js.map +1 -0
  41. package/dist/cli/ui-github-repo-gh.d.ts +36 -0
  42. package/dist/cli/ui-github-repo-gh.d.ts.map +1 -0
  43. package/dist/cli/ui-github-repo-gh.js +112 -0
  44. package/dist/cli/ui-github-repo-gh.js.map +1 -0
  45. package/dist/cli/ui-github-repo-map.d.ts +25 -0
  46. package/dist/cli/ui-github-repo-map.d.ts.map +1 -0
  47. package/dist/cli/ui-github-repo-map.js +150 -0
  48. package/dist/cli/ui-github-repo-map.js.map +1 -0
  49. package/dist/cli/ui-github-repo.d.ts +51 -0
  50. package/dist/cli/ui-github-repo.d.ts.map +1 -0
  51. package/dist/cli/ui-github-repo.js +117 -0
  52. package/dist/cli/ui-github-repo.js.map +1 -0
  53. package/dist/cli/ui-observability-checks.d.ts +23 -0
  54. package/dist/cli/ui-observability-checks.d.ts.map +1 -0
  55. package/dist/cli/ui-observability-checks.js +156 -0
  56. package/dist/cli/ui-observability-checks.js.map +1 -0
  57. package/dist/cli/ui-observability-providers.d.ts +69 -0
  58. package/dist/cli/ui-observability-providers.d.ts.map +1 -0
  59. package/dist/cli/ui-observability-providers.js +99 -0
  60. package/dist/cli/ui-observability-providers.js.map +1 -0
  61. package/dist/core/learnings-budget-check.d.ts +42 -0
  62. package/dist/core/learnings-budget-check.d.ts.map +1 -0
  63. package/dist/core/learnings-budget-check.js +210 -0
  64. package/dist/core/learnings-budget-check.js.map +1 -0
  65. package/dist/core/learnings-document.js +6 -1
  66. package/dist/core/learnings-document.js.map +1 -1
  67. package/package.json +1 -1
  68. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  70. package/plugins/lisa-agy/plugin.json +1 -1
  71. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  73. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  74. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa-expo-agy/plugin.json +1 -1
  81. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  86. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  91. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  96. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  100. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  101. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  105. package/plugins/lisa-rails-agy/plugin.json +1 -1
  106. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  110. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  111. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  114. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  115. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  116. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  117. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  118. package/scripts/check-learnings-budget.ts +29 -163
  119. package/ui/README.md +5 -3
  120. package/ui/index.html +1097 -432
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Secrets Lisa creates or expects workflows to consume.
3
+ * Presence is checked via `gh secret list`; values are never read.
4
+ */
5
+ export const EXPECTED_GITHUB_SECRETS = [
6
+ {
7
+ name: "DEPLOY_KEY",
8
+ purpose: "Write deploy key so CI can push version bumps through ruleset bypass",
9
+ },
10
+ {
11
+ name: "CLAUDE_CODE_OAUTH_TOKEN",
12
+ purpose: "Claude Code Action workflows (nightly, review response, auto-fix)",
13
+ },
14
+ {
15
+ name: "AWS_ACCOUNT_ID_DEV",
16
+ purpose: "Per-environment AWS account for dev deploys",
17
+ },
18
+ {
19
+ name: "AWS_ACCOUNT_ID_STAGING",
20
+ purpose: "Per-environment AWS account for staging deploys",
21
+ },
22
+ {
23
+ name: "AWS_ACCOUNT_ID_PRODUCTION",
24
+ purpose: "Per-environment AWS account for production deploys",
25
+ },
26
+ {
27
+ name: "GITGUARDIAN_API_KEY",
28
+ purpose: "Secret scanning check",
29
+ },
30
+ {
31
+ name: "SONAR_TOKEN",
32
+ purpose: "SonarCloud SAST",
33
+ },
34
+ {
35
+ name: "SNYK_TOKEN",
36
+ purpose: "Snyk dependency scan",
37
+ },
38
+ {
39
+ name: "FOSSA_API_KEY",
40
+ purpose: "License compliance",
41
+ },
42
+ {
43
+ name: "SENTRY_AUTH_TOKEN",
44
+ purpose: "Sentry releases and sourcemaps",
45
+ },
46
+ {
47
+ name: "SENTRY_ORG",
48
+ purpose: "Sentry organization slug",
49
+ },
50
+ {
51
+ name: "SENTRY_PROJECT",
52
+ purpose: "Sentry project slug",
53
+ },
54
+ {
55
+ name: "EXPO_TOKEN",
56
+ purpose: "EAS builds",
57
+ },
58
+ {
59
+ name: "MAESTRO_API_KEY",
60
+ purpose: "Maestro Cloud mobile E2E",
61
+ },
62
+ {
63
+ name: "MAESTRO_SECRET_ENV",
64
+ purpose: "Native Maestro e2e — newline-separated KEY=VALUE secrets forwarded to flows",
65
+ },
66
+ ];
67
+ /**
68
+ * Walk a nested labels object into role-path entries.
69
+ * @param value - Nested label map or leaf string
70
+ * @param pathParts - Role segments accumulated so far
71
+ * @returns Flattened labels under this node
72
+ */
73
+ function walkLabels(value, pathParts) {
74
+ if (typeof value === "string" && value.trim().length > 0) {
75
+ return [{ name: value, role: pathParts.join(" · ") }];
76
+ }
77
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
78
+ return [];
79
+ }
80
+ return Object.entries(value).flatMap(([key, child]) => walkLabels(child, [...pathParts, key]));
81
+ }
82
+ /**
83
+ * Flatten `github.labels` from merged config into expected label rows.
84
+ * @param config - Merged Lisa project config
85
+ * @returns Expected labels with human-readable role paths
86
+ */
87
+ export function expectedLabelsFromConfig(config) {
88
+ const github = config.github;
89
+ if (github === null || typeof github !== "object" || Array.isArray(github)) {
90
+ return [];
91
+ }
92
+ const labels = Reflect.get(github, "labels");
93
+ if (labels === null || typeof labels !== "object" || Array.isArray(labels)) {
94
+ return [];
95
+ }
96
+ return walkLabels(labels, []);
97
+ }
98
+ /**
99
+ * Read configured github.org / github.repo when both are non-empty strings.
100
+ * @param config - Merged Lisa project config
101
+ * @returns Owner and repo, or undefined when either is missing
102
+ */
103
+ export function configuredGithubRepo(config) {
104
+ const github = config.github;
105
+ if (github === null || typeof github !== "object" || Array.isArray(github)) {
106
+ return undefined;
107
+ }
108
+ const owner = Reflect.get(github, "org");
109
+ const repo = Reflect.get(github, "repo");
110
+ if (typeof owner !== "string" ||
111
+ owner.trim().length === 0 ||
112
+ typeof repo !== "string" ||
113
+ repo.trim().length === 0) {
114
+ return undefined;
115
+ }
116
+ return { owner: owner.trim(), repo: repo.trim() };
117
+ }
118
+ //# sourceMappingURL=ui-github-repo-expected.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-github-repo-expected.js","sourceRoot":"","sources":["../../src/cli/ui-github-repo-expected.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /** Live repository settings surfaced in the console panel. */
2
+ export interface GithubRepoSettings {
3
+ readonly allow_merge_commit: boolean;
4
+ readonly allow_squash_merge: boolean;
5
+ readonly allow_rebase_merge: boolean;
6
+ readonly allow_auto_merge: boolean;
7
+ readonly allow_update_branch: boolean;
8
+ readonly delete_branch_on_merge: boolean;
9
+ readonly merge_commit_title: string;
10
+ readonly has_issues: boolean;
11
+ readonly has_wiki: boolean;
12
+ readonly secret_scanning: boolean;
13
+ readonly default_branch: string;
14
+ }
15
+ /** One ruleset row for the panel. */
16
+ export interface GithubRulesetRow {
17
+ readonly name: string;
18
+ readonly appliesTo: string;
19
+ readonly enforces: string;
20
+ readonly active: boolean;
21
+ }
22
+ /** One label present on the remote repository. */
23
+ export interface GithubRemoteLabel {
24
+ readonly name: string;
25
+ readonly color: string;
26
+ }
27
+ /** Injectable collaborators used by the github-repo probe. */
28
+ export interface GithubRepoGhReads {
29
+ readonly readSettings: (owner: string, repo: string, cwd: string, timeoutMs: number, signal: AbortSignal) => Promise<GithubRepoSettings>;
30
+ readonly listRulesets: (owner: string, repo: string, cwd: string, timeoutMs: number, signal: AbortSignal) => Promise<readonly GithubRulesetRow[]>;
31
+ readonly listLabels: (owner: string, repo: string, cwd: string, timeoutMs: number, signal: AbortSignal) => Promise<readonly GithubRemoteLabel[]>;
32
+ readonly listSecretNames: (owner: string, repo: string, cwd: string, timeoutMs: number, signal: AbortSignal) => Promise<readonly string[]>;
33
+ }
34
+ /** Default `gh` implementations used by `lisa ui`. */
35
+ export declare const defaultGithubRepoGhReads: GithubRepoGhReads;
36
+ //# sourceMappingURL=ui-github-repo-gh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-github-repo-gh.d.ts","sourceRoot":"","sources":["../../src/cli/ui-github-repo-gh.ts"],"names":[],"mappings":"AAWA,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,kDAAkD;AAClD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,8DAA8D;AAC9D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,EAAE,CACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,CACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAAC;IAC1C,QAAQ,CAAC,UAAU,EAAE,CACnB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,eAAe,EAAE,CACxB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;CACjC;AAoFD,sDAAsD;AACtD,eAAO,MAAM,wBAAwB,EAAE,iBA0EtC,CAAC"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Injectable `gh` reads for the GitHub repository live-status panel.
3
+ * @module cli/ui-github-repo-gh
4
+ */
5
+ import { execFile } from "node:child_process";
6
+ import { mapRepoSettings, mapRulesetRow, requireNamedString, } from "./ui-github-repo-map.js";
7
+ /**
8
+ * Run `gh` without a shell and return stdout.
9
+ * @param args - gh argv after the executable
10
+ * @param cwd - Working directory
11
+ * @param timeoutMs - Child-process timeout
12
+ * @param signal - Probe cancellation signal
13
+ * @returns Trimmed stdout
14
+ */
15
+ function runGh(args, cwd, timeoutMs, signal) {
16
+ return new Promise((resolve, reject) => {
17
+ const ghExecutable = "gh";
18
+ execFile(
19
+ // eslint-disable-next-line sonarjs/no-os-command-from-path -- fixed user-installed gh executable
20
+ ghExecutable, [...args], { cwd, signal, timeout: timeoutMs, encoding: "utf8" }, (error, stdout) => {
21
+ if (error !== null) {
22
+ reject(error);
23
+ return;
24
+ }
25
+ resolve(stdout.trim());
26
+ });
27
+ });
28
+ }
29
+ /**
30
+ * Parse JSON from a gh command, rejecting non-JSON payloads.
31
+ * @param stdout - Command stdout
32
+ * @returns Parsed JSON value
33
+ */
34
+ function parseJson(stdout) {
35
+ return JSON.parse(stdout);
36
+ }
37
+ /**
38
+ * Load detailed ruleset rows for every ruleset id in the list response.
39
+ * @param owner - Repository owner
40
+ * @param repo - Repository name
41
+ * @param listed - Parsed rulesets list payload
42
+ * @param cwd - Working directory
43
+ * @param timeoutMs - Child-process timeout
44
+ * @param signal - Probe cancellation signal
45
+ * @returns Panel ruleset rows
46
+ */
47
+ async function loadRulesetDetails(owner, repo, listed, cwd, timeoutMs, signal) {
48
+ if (!Array.isArray(listed)) {
49
+ throw new TypeError("Rulesets list was not an array");
50
+ }
51
+ return await Promise.all(listed.map(async (entry) => {
52
+ if (entry === null || typeof entry !== "object") {
53
+ throw new TypeError("Ruleset list entry was not an object");
54
+ }
55
+ const id = Reflect.get(entry, "id");
56
+ if (typeof id !== "number") {
57
+ throw new TypeError("Ruleset list entry omitted numeric id");
58
+ }
59
+ const detailStdout = await runGh(["api", `repos/${owner}/${repo}/rulesets/${String(id)}`], cwd, timeoutMs, signal);
60
+ return mapRulesetRow(parseJson(detailStdout));
61
+ }));
62
+ }
63
+ /** Default `gh` implementations used by `lisa ui`. */
64
+ export const defaultGithubRepoGhReads = {
65
+ readSettings: async (owner, repo, cwd, timeoutMs, signal) => {
66
+ const stdout = await runGh(["api", `repos/${owner}/${repo}`], cwd, timeoutMs, signal);
67
+ return mapRepoSettings(parseJson(stdout));
68
+ },
69
+ listRulesets: async (owner, repo, cwd, timeoutMs, signal) => {
70
+ const listStdout = await runGh(["api", `repos/${owner}/${repo}/rulesets`], cwd, timeoutMs, signal);
71
+ return loadRulesetDetails(owner, repo, parseJson(listStdout), cwd, timeoutMs, signal);
72
+ },
73
+ listLabels: async (owner, repo, cwd, timeoutMs, signal) => {
74
+ const stdout = await runGh([
75
+ "label",
76
+ "list",
77
+ "--repo",
78
+ `${owner}/${repo}`,
79
+ "--limit",
80
+ "200",
81
+ "--json",
82
+ "name,color",
83
+ ], cwd, timeoutMs, signal);
84
+ const parsed = parseJson(stdout);
85
+ if (!Array.isArray(parsed)) {
86
+ throw new TypeError("Label list was not an array");
87
+ }
88
+ return parsed.map(entry => {
89
+ if (entry === null || typeof entry !== "object") {
90
+ throw new TypeError("Label entry was not an object");
91
+ }
92
+ return {
93
+ name: requireNamedString(entry, "name"),
94
+ color: requireNamedString(entry, "color"),
95
+ };
96
+ });
97
+ },
98
+ listSecretNames: async (owner, repo, cwd, timeoutMs, signal) => {
99
+ const stdout = await runGh(["secret", "list", "--repo", `${owner}/${repo}`, "--json", "name"], cwd, timeoutMs, signal);
100
+ const parsed = parseJson(stdout);
101
+ if (!Array.isArray(parsed)) {
102
+ throw new TypeError("Secret list was not an array");
103
+ }
104
+ return parsed.map(entry => {
105
+ if (entry === null || typeof entry !== "object") {
106
+ throw new TypeError("Secret entry was not an object");
107
+ }
108
+ return requireNamedString(entry, "name");
109
+ });
110
+ },
111
+ };
112
+ //# sourceMappingURL=ui-github-repo-gh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-github-repo-gh.js","sourceRoot":"","sources":["../../src/cli/ui-github-repo-gh.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,aAAa,EACb,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AA+DjC;;;;;;;GAOG;AACH,SAAS,KAAK,CACZ,IAAuB,EACvB,GAAW,EACX,SAAiB,EACjB,MAAmB;IAEnB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,YAAY,GAAG,IAAI,CAAC;QAC1B,QAAQ;QACN,iGAAiG;QACjG,YAAY,EACZ,CAAC,GAAG,IAAI,CAAC,EACT,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EACrD,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAChB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,OAAO;YACT,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAAC,MAAc;IAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;AACvC,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,kBAAkB,CAC/B,KAAa,EACb,IAAY,EACZ,MAAe,EACf,GAAW,EACX,SAAiB,EACjB,MAAmB;IAEnB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;QACvB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,KAAK,CAC9B,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,IAAI,aAAa,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EACxD,GAAG,EACH,SAAS,EACT,MAAM,CACP,CAAC;QACF,OAAO,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,MAAM,wBAAwB,GAAsB;IACzD,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;QAC1D,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,IAAI,EAAE,CAAC,EACjC,GAAG,EACH,SAAS,EACT,MAAM,CACP,CAAC;QACF,OAAO,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;QAC1D,MAAM,UAAU,GAAG,MAAM,KAAK,CAC5B,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,IAAI,WAAW,CAAC,EAC1C,GAAG,EACH,SAAS,EACT,MAAM,CACP,CAAC;QACF,OAAO,kBAAkB,CACvB,KAAK,EACL,IAAI,EACJ,SAAS,CAAC,UAAU,CAAC,EACrB,GAAG,EACH,SAAS,EACT,MAAM,CACP,CAAC;IACJ,CAAC;IACD,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;QACxD,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB;YACE,OAAO;YACP,MAAM;YACN,QAAQ;YACR,GAAG,KAAK,IAAI,IAAI,EAAE;YAClB,SAAS;YACT,KAAK;YACL,QAAQ;YACR,YAAY;SACb,EACD,GAAG,EACH,SAAS,EACT,MAAM,CACP,CAAC;QACF,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACxB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAChD,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAC;YACvD,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC;gBACvC,KAAK,EAAE,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC;aAC1C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IACD,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;QAC7D,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,IAAI,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAClE,GAAG,EACH,SAAS,EACT,MAAM,CACP,CAAC;QACF,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACxB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAChD,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Pure mappers from GitHub API JSON onto repository panel rows.
3
+ * @module cli/ui-github-repo-map
4
+ */
5
+ import type { GithubRepoSettings, GithubRulesetRow } from "./ui-github-repo-gh.js";
6
+ /**
7
+ * Map repository JSON into the panel settings shape.
8
+ * @param raw - Parsed `gh api repos/{owner}/{repo}` payload
9
+ * @returns Settings for the console
10
+ */
11
+ export declare function mapRepoSettings(raw: unknown): GithubRepoSettings;
12
+ /**
13
+ * Map a detailed ruleset payload into a panel row.
14
+ * @param raw - One ruleset object from gh api
15
+ * @returns Panel row
16
+ */
17
+ export declare function mapRulesetRow(raw: unknown): GithubRulesetRow;
18
+ /**
19
+ * Require a non-empty string field (shared by label/secret list parsers).
20
+ * @param record - Source object
21
+ * @param key - Property name
22
+ * @returns String value
23
+ */
24
+ export declare function requireNamedString(record: object, key: string): string;
25
+ //# sourceMappingURL=ui-github-repo-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-github-repo-map.d.ts","sourceRoot":"","sources":["../../src/cli/ui-github-repo-map.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AA+ChC;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,CAiBhE;AAqED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAW5D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtE"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Require a boolean field from a plain object.
3
+ * @param record - Source object
4
+ * @param key - Property name
5
+ * @returns Boolean value
6
+ */
7
+ function requireBoolean(record, key) {
8
+ const value = Reflect.get(record, key);
9
+ if (typeof value !== "boolean") {
10
+ throw new TypeError(`Repository settings omitted boolean ${key}`);
11
+ }
12
+ return value;
13
+ }
14
+ /**
15
+ * Require a string field from a plain object.
16
+ * @param record - Source object
17
+ * @param key - Property name
18
+ * @returns String value
19
+ */
20
+ function requireString(record, key) {
21
+ const value = Reflect.get(record, key);
22
+ if (typeof value !== "string" || value.trim().length === 0) {
23
+ throw new TypeError(`Repository settings omitted string ${key}`);
24
+ }
25
+ return value;
26
+ }
27
+ /**
28
+ * Derive secret-scanning enabled from the security_and_analysis payload.
29
+ * @param record - Repository API object
30
+ * @returns Whether secret scanning is enabled
31
+ */
32
+ function secretScanningEnabled(record) {
33
+ const security = Reflect.get(record, "security_and_analysis");
34
+ if (security === null || typeof security !== "object") {
35
+ return false;
36
+ }
37
+ const scanning = Reflect.get(security, "secret_scanning");
38
+ if (scanning === null || typeof scanning !== "object") {
39
+ return false;
40
+ }
41
+ return Reflect.get(scanning, "status") === "enabled";
42
+ }
43
+ /**
44
+ * Map repository JSON into the panel settings shape.
45
+ * @param raw - Parsed `gh api repos/{owner}/{repo}` payload
46
+ * @returns Settings for the console
47
+ */
48
+ export function mapRepoSettings(raw) {
49
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
50
+ throw new TypeError("Repository settings response was not an object");
51
+ }
52
+ return {
53
+ allow_merge_commit: requireBoolean(raw, "allow_merge_commit"),
54
+ allow_squash_merge: requireBoolean(raw, "allow_squash_merge"),
55
+ allow_rebase_merge: requireBoolean(raw, "allow_rebase_merge"),
56
+ allow_auto_merge: requireBoolean(raw, "allow_auto_merge"),
57
+ allow_update_branch: requireBoolean(raw, "allow_update_branch"),
58
+ delete_branch_on_merge: requireBoolean(raw, "delete_branch_on_merge"),
59
+ merge_commit_title: requireString(raw, "merge_commit_title"),
60
+ has_issues: requireBoolean(raw, "has_issues"),
61
+ has_wiki: requireBoolean(raw, "has_wiki"),
62
+ secret_scanning: secretScanningEnabled(raw),
63
+ default_branch: requireString(raw, "default_branch"),
64
+ };
65
+ }
66
+ /**
67
+ * Humanize ruleset ref includes for the Applies-to column.
68
+ * @param includes - Ruleset condition include list
69
+ * @returns Display string
70
+ */
71
+ function formatAppliesTo(includes) {
72
+ if (includes.length === 0) {
73
+ return "—";
74
+ }
75
+ return includes
76
+ .map(entry => entry
77
+ .replace(/^refs\/heads\//u, "")
78
+ .replace(/^refs\/tags\//u, "")
79
+ .replace(/^~DEFAULT_BRANCH$/u, "default"))
80
+ .join(" · ");
81
+ }
82
+ /**
83
+ * Extract ref_name.include strings from a ruleset conditions object.
84
+ * @param conditions - Ruleset conditions payload
85
+ * @returns Include list, or empty when absent
86
+ */
87
+ function rulesetIncludes(conditions) {
88
+ if (conditions === null ||
89
+ typeof conditions !== "object" ||
90
+ Array.isArray(conditions)) {
91
+ return [];
92
+ }
93
+ const refName = Reflect.get(conditions, "ref_name");
94
+ if (refName === null ||
95
+ typeof refName !== "object" ||
96
+ Array.isArray(refName)) {
97
+ return [];
98
+ }
99
+ const include = Reflect.get(refName, "include");
100
+ if (!Array.isArray(include)) {
101
+ return [];
102
+ }
103
+ return include.filter((entry) => typeof entry === "string");
104
+ }
105
+ /**
106
+ * Extract rule type names from a ruleset rules array.
107
+ * @param rules - Ruleset rules payload
108
+ * @returns Rule type strings
109
+ */
110
+ function rulesetRuleTypes(rules) {
111
+ if (!Array.isArray(rules)) {
112
+ return [];
113
+ }
114
+ return rules
115
+ .map(rule => {
116
+ if (rule === null || typeof rule !== "object") {
117
+ return undefined;
118
+ }
119
+ const type = Reflect.get(rule, "type");
120
+ return typeof type === "string" ? type : undefined;
121
+ })
122
+ .filter((type) => type !== undefined);
123
+ }
124
+ /**
125
+ * Map a detailed ruleset payload into a panel row.
126
+ * @param raw - One ruleset object from gh api
127
+ * @returns Panel row
128
+ */
129
+ export function mapRulesetRow(raw) {
130
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
131
+ throw new TypeError("Ruleset entry was not an object");
132
+ }
133
+ const ruleTypes = rulesetRuleTypes(Reflect.get(raw, "rules"));
134
+ return {
135
+ name: requireString(raw, "name"),
136
+ appliesTo: formatAppliesTo(rulesetIncludes(Reflect.get(raw, "conditions"))),
137
+ enforces: ruleTypes.length > 0 ? ruleTypes.join(", ") : "—",
138
+ active: Reflect.get(raw, "enforcement") === "active",
139
+ };
140
+ }
141
+ /**
142
+ * Require a non-empty string field (shared by label/secret list parsers).
143
+ * @param record - Source object
144
+ * @param key - Property name
145
+ * @returns String value
146
+ */
147
+ export function requireNamedString(record, key) {
148
+ return requireString(record, key);
149
+ }
150
+ //# sourceMappingURL=ui-github-repo-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-github-repo-map.js","sourceRoot":"","sources":["../../src/cli/ui-github-repo-map.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Live-status probe for the console GitHub repository panel.
3
+ *
4
+ * Every input is `gh`-derived. Unauthenticated `gh` takes the whole panel to
5
+ * unknown — never a partial concrete value. Secret values are never read.
6
+ * @module cli/ui-github-repo
7
+ */
8
+ import type { JsonObject } from "../sync/json-path.js";
9
+ import { type GithubRepoGhReads, type GithubRepoSettings, type GithubRulesetRow } from "./ui-github-repo-gh.js";
10
+ import { type StatusProbe } from "./ui-status.js";
11
+ export type { GithubRepoGhReads } from "./ui-github-repo-gh.js";
12
+ export { expectedLabelsFromConfig } from "./ui-github-repo-expected.js";
13
+ /** Label row for the panel (presence vs config expectation). */
14
+ export interface GithubRepoLabelRow {
15
+ readonly name: string;
16
+ readonly role: string;
17
+ readonly color: string;
18
+ readonly present: boolean;
19
+ }
20
+ /** Secret row — presence only; never a value. */
21
+ export interface GithubRepoSecretRow {
22
+ readonly name: string;
23
+ readonly purpose: string;
24
+ readonly set: boolean;
25
+ }
26
+ /**
27
+ * Structured value emitted by the github-repo live-status probe.
28
+ * Stored as JsonObject for the probe transport; shape is validated in tests.
29
+ */
30
+ export type GithubRepoPanelValue = JsonObject & {
31
+ readonly owner: string;
32
+ readonly repo: string;
33
+ readonly settings: GithubRepoSettings;
34
+ readonly rulesets: readonly GithubRulesetRow[];
35
+ readonly labels: readonly GithubRepoLabelRow[];
36
+ readonly secrets: readonly GithubRepoSecretRow[];
37
+ };
38
+ /** Optional overrides for focused unit tests. */
39
+ export interface GithubRepoProbeDependencies {
40
+ readonly authenticate?: (signal: AbortSignal) => Promise<"authenticated" | "not-authenticated">;
41
+ readonly reads?: Partial<GithubRepoGhReads>;
42
+ }
43
+ /**
44
+ * Create the probe that populates the GitHub repository panel.
45
+ * @param cwd - Project root used as the command working directory
46
+ * @param config - Merged Lisa project config
47
+ * @param dependencies - Injectable auth and gh reads for focused tests
48
+ * @returns Live-status probe for GET /api/status
49
+ */
50
+ export declare function createGithubRepoProbe(cwd: string, config: JsonObject, dependencies?: GithubRepoProbeDependencies): StatusProbe<GithubRepoPanelValue>;
51
+ //# sourceMappingURL=ui-github-repo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-github-repo.d.ts","sourceRoot":"","sources":["../../src/cli/ui-github-repo.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAMvD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAOxE,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,iDAAiD;AACjD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAClD,CAAC;AAEF,iDAAiD;AACjD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,CACtB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,eAAe,GAAG,mBAAmB,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC7C;AAsED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,UAAU,EAClB,YAAY,GAAE,2BAAgC,GAC7C,WAAW,CAAC,oBAAoB,CAAC,CAgEnC"}
@@ -0,0 +1,117 @@
1
+ import { configuredGithubRepo, EXPECTED_GITHUB_SECRETS, expectedLabelsFromConfig, } from "./ui-github-repo-expected.js";
2
+ import { defaultGithubRepoGhReads, } from "./ui-github-repo-gh.js";
3
+ import { createGithubAuthProbe, } from "./ui-status.js";
4
+ export { expectedLabelsFromConfig } from "./ui-github-repo-expected.js";
5
+ const GITHUB_REPO_PROBE_ID = "github-repo";
6
+ const PROBE_TIMEOUT_MS = 15_000;
7
+ const NOT_AUTHENTICATED = "not-authenticated";
8
+ const GITHUB_NOT_AUTHENTICATED = "GitHub CLI is not authenticated";
9
+ /**
10
+ * Compare expected labels against the remote label set.
11
+ * @param expected - Labels from config
12
+ * @param remote - Labels returned by gh
13
+ * @returns Panel rows with present/missing
14
+ */
15
+ function compareLabels(expected, remote) {
16
+ const byName = new Map(remote.map(label => [label.name, label]));
17
+ return expected.map(label => {
18
+ const found = byName.get(label.name);
19
+ return found === undefined
20
+ ? { name: label.name, role: label.role, color: "", present: false }
21
+ : {
22
+ name: label.name,
23
+ role: label.role,
24
+ color: found.color,
25
+ present: true,
26
+ };
27
+ });
28
+ }
29
+ /**
30
+ * Compare expected secrets against names from `gh secret list`.
31
+ * @param presentNames - Secret names that exist on the repo
32
+ * @returns Presence-only rows (no values)
33
+ */
34
+ function compareSecrets(presentNames) {
35
+ const present = new Set(presentNames);
36
+ return EXPECTED_GITHUB_SECRETS.map(secret => ({
37
+ name: secret.name,
38
+ purpose: secret.purpose,
39
+ set: present.has(secret.name),
40
+ }));
41
+ }
42
+ /**
43
+ * Build the panel value after all gh reads succeed.
44
+ * @param owner - github.org
45
+ * @param repo - github.repo
46
+ * @param settings - Live repository settings
47
+ * @param rulesets - Live rulesets
48
+ * @param labels - Compared label rows
49
+ * @param secrets - Presence-only secret rows
50
+ * @returns Probe value payload
51
+ */
52
+ function panelValue(owner, repo, settings, rulesets, labels, secrets) {
53
+ return {
54
+ owner,
55
+ repo,
56
+ settings: { ...settings },
57
+ rulesets: rulesets.map(row => ({ ...row })),
58
+ labels: labels.map(row => ({ ...row })),
59
+ secrets: secrets.map(row => ({ ...row })),
60
+ };
61
+ }
62
+ /**
63
+ * Create the probe that populates the GitHub repository panel.
64
+ * @param cwd - Project root used as the command working directory
65
+ * @param config - Merged Lisa project config
66
+ * @param dependencies - Injectable auth and gh reads for focused tests
67
+ * @returns Live-status probe for GET /api/status
68
+ */
69
+ export function createGithubRepoProbe(cwd, config, dependencies = {}) {
70
+ const reads = {
71
+ ...defaultGithubRepoGhReads,
72
+ ...dependencies.reads,
73
+ };
74
+ const authenticate = dependencies.authenticate ??
75
+ (async (signal) => {
76
+ const auth = await createGithubAuthProbe(cwd).run(signal);
77
+ return auth.state === "value" && auth.value === true
78
+ ? "authenticated"
79
+ : "not-authenticated";
80
+ });
81
+ return {
82
+ id: GITHUB_REPO_PROBE_ID,
83
+ timeoutMs: PROBE_TIMEOUT_MS,
84
+ run: async (signal) => {
85
+ const authState = await authenticate(signal);
86
+ if (authState !== "authenticated") {
87
+ return {
88
+ state: "unknown",
89
+ reason: NOT_AUTHENTICATED,
90
+ message: GITHUB_NOT_AUTHENTICATED,
91
+ };
92
+ }
93
+ const target = configuredGithubRepo(config);
94
+ if (target === undefined) {
95
+ return {
96
+ state: "unknown",
97
+ reason: "repo-not-configured",
98
+ message: "github.org and github.repo must be set in Lisa config",
99
+ };
100
+ }
101
+ const timeoutMs = PROBE_TIMEOUT_MS + 250;
102
+ const [settings, rulesets, remoteLabels, secretNames] = await Promise.all([
103
+ reads.readSettings(target.owner, target.repo, cwd, timeoutMs, signal),
104
+ reads.listRulesets(target.owner, target.repo, cwd, timeoutMs, signal),
105
+ reads.listLabels(target.owner, target.repo, cwd, timeoutMs, signal),
106
+ reads.listSecretNames(target.owner, target.repo, cwd, timeoutMs, signal),
107
+ ]);
108
+ const value = panelValue(target.owner, target.repo, settings, rulesets, compareLabels(expectedLabelsFromConfig(config), remoteLabels), compareSecrets(secretNames));
109
+ const result = {
110
+ state: "value",
111
+ value,
112
+ };
113
+ return result;
114
+ },
115
+ };
116
+ }
117
+ //# sourceMappingURL=ui-github-repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-github-repo.js","sourceRoot":"","sources":["../../src/cli/ui-github-repo.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,wBAAwB,GAKzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,qBAAqB,GAGtB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAExE,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAC3C,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,iBAAiB,GAAG,mBAA4B,CAAC;AACvD,MAAM,wBAAwB,GAAG,iCAAiC,CAAC;AAsCnE;;;;;GAKG;AACH,SAAS,aAAa,CACpB,QAAqD,EACrD,MAAoC;IAEpC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO,KAAK,KAAK,SAAS;YACxB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;YACnE,CAAC,CAAC;gBACE,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,OAAO,EAAE,IAAI;aACd,CAAC;IACR,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CACrB,YAA+B;IAE/B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;KAC9B,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,UAAU,CACjB,KAAa,EACb,IAAY,EACZ,QAA4B,EAC5B,QAAqC,EACrC,MAAqC,EACrC,OAAuC;IAEvC,OAAO;QACL,KAAK;QACL,IAAI;QACJ,QAAQ,EAAE,EAAE,GAAG,QAAQ,EAAE;QACzB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;QAC3C,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;QACvC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;KAClB,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAAW,EACX,MAAkB,EAClB,eAA4C,EAAE;IAE9C,MAAM,KAAK,GAAsB;QAC/B,GAAG,wBAAwB;QAC3B,GAAG,YAAY,CAAC,KAAK;KACtB,CAAC;IACF,MAAM,YAAY,GAChB,YAAY,CAAC,YAAY;QACzB,CAAC,KAAK,EAAE,MAAmB,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,KAAK,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;gBAClD,CAAC,CAAC,eAAe;gBACjB,CAAC,CAAC,mBAAmB,CAAC;QAC1B,CAAC,CAAC,CAAC;IAEL,OAAO;QACL,EAAE,EAAE,oBAAoB;QACxB,SAAS,EAAE,gBAAgB;QAC3B,GAAG,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;YAClB,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,SAAS,KAAK,eAAe,EAAE,CAAC;gBAClC,OAAO;oBACL,KAAK,EAAE,SAAS;oBAChB,MAAM,EAAE,iBAAiB;oBACzB,OAAO,EAAE,wBAAwB;iBAClC,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO;oBACL,KAAK,EAAE,SAAS;oBAChB,MAAM,EAAE,qBAAqB;oBAC7B,OAAO,EAAE,uDAAuD;iBACjE,CAAC;YACJ,CAAC;YACD,MAAM,SAAS,GAAG,gBAAgB,GAAG,GAAG,CAAC;YACzC,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CACvE;gBACE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC;gBACrE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC;gBACrE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC;gBACnE,KAAK,CAAC,eAAe,CACnB,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,IAAI,EACX,GAAG,EACH,SAAS,EACT,MAAM,CACP;aACF,CACF,CAAC;YACF,MAAM,KAAK,GAAG,UAAU,CACtB,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,IAAI,EACX,QAAQ,EACR,QAAQ,EACR,aAAa,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,EAC7D,cAAc,CAAC,WAAW,CAAC,CAC5B,CAAC;YACF,MAAM,MAAM,GAAsC;gBAChD,KAAK,EAAE,OAAO;gBACd,KAAK;aACN,CAAC;YACF,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}