@codyswann/lisa 2.229.1 → 2.230.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/remote-environment-catalog.d.ts +17 -0
- package/dist/cli/remote-environment-catalog.d.ts.map +1 -0
- package/dist/cli/remote-environment-catalog.js +175 -0
- package/dist/cli/remote-environment-catalog.js.map +1 -0
- package/dist/cli/remote-environment-contract.d.ts +94 -0
- package/dist/cli/remote-environment-contract.d.ts.map +1 -0
- package/dist/cli/remote-environment-contract.js +58 -0
- package/dist/cli/remote-environment-contract.js.map +1 -0
- package/dist/cli/remote-environment-detection.d.ts +23 -0
- package/dist/cli/remote-environment-detection.d.ts.map +1 -0
- package/dist/cli/remote-environment-detection.js +120 -0
- package/dist/cli/remote-environment-detection.js.map +1 -0
- package/dist/cli/remote-environment.d.ts +12 -0
- package/dist/cli/remote-environment.d.ts.map +1 -0
- package/dist/cli/remote-environment.js +73 -0
- package/dist/cli/remote-environment.js.map +1 -0
- package/dist/cli/ui-cmd.d.ts +2 -19
- package/dist/cli/ui-cmd.d.ts.map +1 -1
- package/dist/cli/ui-cmd.js +6 -34
- package/dist/cli/ui-cmd.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/.codex-plugin/skills/lisa-generate-claude-remote-build-script/SKILL.md +23 -8
- package/plugins/lisa/skills/lisa-generate-claude-remote-build-script/SKILL.md +23 -8
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-generate-claude-remote-build-script/SKILL.md +23 -8
- 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-copilot/skills/lisa-generate-claude-remote-build-script/SKILL.md +23 -8
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-generate-claude-remote-build-script/SKILL.md +23 -8
- 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/plugins/src/base/skills/lisa-generate-claude-remote-build-script/SKILL.md +23 -8
- package/ui/README.md +28 -1
- package/ui/index.html +39 -80
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ProjectType } from "../core/config.js";
|
|
2
|
+
import type { JsonObject } from "../sync/json-path.js";
|
|
3
|
+
import type { IntegrationFlags, VariableRequirement } from "./remote-environment-contract.js";
|
|
4
|
+
/**
|
|
5
|
+
* Build requirements implied by the active Lisa tracker and PRD source.
|
|
6
|
+
* @param config - Merged Lisa project config
|
|
7
|
+
* @returns Active integration requirements
|
|
8
|
+
*/
|
|
9
|
+
export declare function configuredIntegrationRequirements(config: JsonObject): readonly VariableRequirement[];
|
|
10
|
+
/**
|
|
11
|
+
* Convert active flags to names-only variable requirements.
|
|
12
|
+
* @param flags - Detected integrations
|
|
13
|
+
* @param projectTypes - Detected Lisa project types
|
|
14
|
+
* @returns Active project requirements
|
|
15
|
+
*/
|
|
16
|
+
export declare function requirementsForFlags(flags: IntegrationFlags, projectTypes: readonly ProjectType[]): readonly VariableRequirement[];
|
|
17
|
+
//# sourceMappingURL=remote-environment-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-environment-catalog.d.ts","sourceRoot":"","sources":["../../src/cli/remote-environment-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAgD1C;;;;GAIG;AACH,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,UAAU,GACjB,SAAS,mBAAmB,EAAE,CAmDhC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,gBAAgB,EACvB,YAAY,EAAE,SAAS,WAAW,EAAE,GACnC,SAAS,mBAAmB,EAAE,CAsEhC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
const JIRA_SOURCE = "Lisa config: Jira tracker";
|
|
2
|
+
/**
|
|
3
|
+
* Build the active Jira tracker requirements.
|
|
4
|
+
* @returns Required jira-cli variables
|
|
5
|
+
*/
|
|
6
|
+
function jiraRequirements() {
|
|
7
|
+
return [
|
|
8
|
+
{
|
|
9
|
+
name: "JIRA_API_TOKEN",
|
|
10
|
+
reason: "Jira API authentication for the active tracker",
|
|
11
|
+
source: JIRA_SOURCE,
|
|
12
|
+
secret: true,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: "JIRA_SERVER",
|
|
16
|
+
reason: "Jira Cloud site used by jira-cli",
|
|
17
|
+
source: JIRA_SOURCE,
|
|
18
|
+
secret: false,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "JIRA_LOGIN",
|
|
22
|
+
reason: "Jira account used by jira-cli",
|
|
23
|
+
source: JIRA_SOURCE,
|
|
24
|
+
secret: false,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "JIRA_PROJECT",
|
|
28
|
+
reason: "Jira project key used by the factory",
|
|
29
|
+
source: JIRA_SOURCE,
|
|
30
|
+
secret: false,
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Resolve the most specific AWS detection source.
|
|
36
|
+
* @param projectTypes - Detected Lisa project types
|
|
37
|
+
* @returns Human-readable detection source
|
|
38
|
+
*/
|
|
39
|
+
function awsRequirementSource(projectTypes) {
|
|
40
|
+
return projectTypes.includes("cdk")
|
|
41
|
+
? "Project type: CDK"
|
|
42
|
+
: "Integration: AWS";
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build requirements implied by the active Lisa tracker and PRD source.
|
|
46
|
+
* @param config - Merged Lisa project config
|
|
47
|
+
* @returns Active integration requirements
|
|
48
|
+
*/
|
|
49
|
+
export function configuredIntegrationRequirements(config) {
|
|
50
|
+
const tracker = typeof config.tracker === "string" ? config.tracker : "";
|
|
51
|
+
const source = typeof config.source === "string" ? config.source : "";
|
|
52
|
+
const catalog = [
|
|
53
|
+
{
|
|
54
|
+
active: tracker === "github" || source === "github",
|
|
55
|
+
requirements: [
|
|
56
|
+
{
|
|
57
|
+
name: "GH_TOKEN",
|
|
58
|
+
reason: "GitHub CLI access for the active tracker or PRD source",
|
|
59
|
+
source: "Lisa config: GitHub",
|
|
60
|
+
secret: true,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{ active: tracker === "jira", requirements: jiraRequirements() },
|
|
65
|
+
{
|
|
66
|
+
active: tracker === "linear" || source === "linear",
|
|
67
|
+
requirements: [
|
|
68
|
+
{
|
|
69
|
+
name: "LINEAR_API_KEY",
|
|
70
|
+
reason: "Headless Linear access for the active tracker or source",
|
|
71
|
+
source: "Lisa config: Linear",
|
|
72
|
+
secret: true,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
active: source === "notion",
|
|
78
|
+
requirements: [
|
|
79
|
+
{
|
|
80
|
+
name: "NOTION_API_TOKEN",
|
|
81
|
+
reason: "Notion integration access for the active PRD source",
|
|
82
|
+
source: "Lisa config: Notion source",
|
|
83
|
+
secret: true,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
active: source === "confluence",
|
|
89
|
+
requirements: [
|
|
90
|
+
{
|
|
91
|
+
name: "ATLASSIAN_API_TOKEN",
|
|
92
|
+
reason: "Confluence API access for the active PRD source",
|
|
93
|
+
source: "Lisa config: Confluence source",
|
|
94
|
+
secret: true,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
return catalog.flatMap(entry => (entry.active ? entry.requirements : []));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Convert active flags to names-only variable requirements.
|
|
103
|
+
* @param flags - Detected integrations
|
|
104
|
+
* @param projectTypes - Detected Lisa project types
|
|
105
|
+
* @returns Active project requirements
|
|
106
|
+
*/
|
|
107
|
+
export function requirementsForFlags(flags, projectTypes) {
|
|
108
|
+
const catalog = [
|
|
109
|
+
{
|
|
110
|
+
active: flags.jam,
|
|
111
|
+
requirement: {
|
|
112
|
+
name: "JAM_PAT",
|
|
113
|
+
reason: "Jam CLI access for the detected Jam integration",
|
|
114
|
+
source: "Integration: @jam.dev",
|
|
115
|
+
secret: true,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
active: flags.aws,
|
|
120
|
+
requirement: {
|
|
121
|
+
name: "LISA_AWS_BOOTSTRAP_JSON",
|
|
122
|
+
reason: "Renewable AWS CLI profiles for this AWS-enabled project",
|
|
123
|
+
source: awsRequirementSource(projectTypes),
|
|
124
|
+
secret: true,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
active: flags.sonar,
|
|
129
|
+
requirement: {
|
|
130
|
+
name: "SONAR_TOKEN",
|
|
131
|
+
reason: "SonarCloud diagnostics for the configured project",
|
|
132
|
+
source: "Integration: SonarCloud",
|
|
133
|
+
secret: true,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
active: flags.sentry,
|
|
138
|
+
requirement: {
|
|
139
|
+
name: "SENTRY_AUTH_TOKEN",
|
|
140
|
+
reason: "Sentry diagnostics and release tooling",
|
|
141
|
+
source: "Integration: Sentry",
|
|
142
|
+
secret: true,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
active: flags.figma,
|
|
147
|
+
requirement: {
|
|
148
|
+
name: "FIGMA_ACCESS_TOKEN",
|
|
149
|
+
reason: "Figma tooling referenced by the project setup",
|
|
150
|
+
source: "Integration: Figma",
|
|
151
|
+
secret: true,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
active: flags.eas,
|
|
156
|
+
requirement: {
|
|
157
|
+
name: "EXPO_TOKEN",
|
|
158
|
+
reason: "EAS operations for this Expo project",
|
|
159
|
+
source: "Project type: Expo with EAS",
|
|
160
|
+
secret: true,
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
active: flags.maestro,
|
|
165
|
+
requirement: {
|
|
166
|
+
name: "MAESTRO_API_KEY",
|
|
167
|
+
reason: "Maestro Cloud verification for this project",
|
|
168
|
+
source: "Integration: Maestro Cloud",
|
|
169
|
+
secret: true,
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
return catalog.filter(entry => entry.active).map(entry => entry.requirement);
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=remote-environment-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-environment-catalog.js","sourceRoot":"","sources":["../../src/cli/remote-environment-catalog.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAEhD;;;GAGG;AACH,SAAS,gBAAgB;IACvB,OAAO;QACL;YACE,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,gDAAgD;YACxD,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,IAAI;SACb;QACD;YACE,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,kCAAkC;YAC1C,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,KAAK;SACd;QACD;YACE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,+BAA+B;YACvC,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,KAAK;SACd;QACD;YACE,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,sCAAsC;YAC9C,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,KAAK;SACd;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,YAAoC;IAChE,OAAO,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC;QACjC,CAAC,CAAC,mBAAmB;QACrB,CAAC,CAAC,kBAAkB,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAC/C,MAAkB;IAElB,MAAM,OAAO,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,MAAM,OAAO,GAAG;QACd;YACE,MAAM,EAAE,OAAO,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ;YACnD,YAAY,EAAE;gBACZ;oBACE,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,wDAAwD;oBAChE,MAAM,EAAE,qBAAqB;oBAC7B,MAAM,EAAE,IAAI;iBACb;aACF;SACF;QACD,EAAE,MAAM,EAAE,OAAO,KAAK,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,EAAE;QAChE;YACE,MAAM,EAAE,OAAO,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ;YACnD,YAAY,EAAE;gBACZ;oBACE,IAAI,EAAE,gBAAgB;oBACtB,MAAM,EAAE,yDAAyD;oBACjE,MAAM,EAAE,qBAAqB;oBAC7B,MAAM,EAAE,IAAI;iBACb;aACF;SACF;QACD;YACE,MAAM,EAAE,MAAM,KAAK,QAAQ;YAC3B,YAAY,EAAE;gBACZ;oBACE,IAAI,EAAE,kBAAkB;oBACxB,MAAM,EAAE,qDAAqD;oBAC7D,MAAM,EAAE,4BAA4B;oBACpC,MAAM,EAAE,IAAI;iBACb;aACF;SACF;QACD;YACE,MAAM,EAAE,MAAM,KAAK,YAAY;YAC/B,YAAY,EAAE;gBACZ;oBACE,IAAI,EAAE,qBAAqB;oBAC3B,MAAM,EAAE,iDAAiD;oBACzD,MAAM,EAAE,gCAAgC;oBACxC,MAAM,EAAE,IAAI;iBACb;aACF;SACF;KACF,CAAC;IACF,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAuB,EACvB,YAAoC;IAEpC,MAAM,OAAO,GAGP;QACJ;YACE,MAAM,EAAE,KAAK,CAAC,GAAG;YACjB,WAAW,EAAE;gBACX,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,iDAAiD;gBACzD,MAAM,EAAE,uBAAuB;gBAC/B,MAAM,EAAE,IAAI;aACb;SACF;QACD;YACE,MAAM,EAAE,KAAK,CAAC,GAAG;YACjB,WAAW,EAAE;gBACX,IAAI,EAAE,yBAAyB;gBAC/B,MAAM,EAAE,yDAAyD;gBACjE,MAAM,EAAE,oBAAoB,CAAC,YAAY,CAAC;gBAC1C,MAAM,EAAE,IAAI;aACb;SACF;QACD;YACE,MAAM,EAAE,KAAK,CAAC,KAAK;YACnB,WAAW,EAAE;gBACX,IAAI,EAAE,aAAa;gBACnB,MAAM,EAAE,mDAAmD;gBAC3D,MAAM,EAAE,yBAAyB;gBACjC,MAAM,EAAE,IAAI;aACb;SACF;QACD;YACE,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,WAAW,EAAE;gBACX,IAAI,EAAE,mBAAmB;gBACzB,MAAM,EAAE,wCAAwC;gBAChD,MAAM,EAAE,qBAAqB;gBAC7B,MAAM,EAAE,IAAI;aACb;SACF;QACD;YACE,MAAM,EAAE,KAAK,CAAC,KAAK;YACnB,WAAW,EAAE;gBACX,IAAI,EAAE,oBAAoB;gBAC1B,MAAM,EAAE,+CAA+C;gBACvD,MAAM,EAAE,oBAAoB;gBAC5B,MAAM,EAAE,IAAI;aACb;SACF;QACD;YACE,MAAM,EAAE,KAAK,CAAC,GAAG;YACjB,WAAW,EAAE;gBACX,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,sCAAsC;gBAC9C,MAAM,EAAE,6BAA6B;gBACrC,MAAM,EAAE,IAAI;aACb;SACF;QACD;YACE,MAAM,EAAE,KAAK,CAAC,OAAO;YACrB,WAAW,EAAE;gBACX,IAAI,EAAE,iBAAiB;gBACvB,MAAM,EAAE,6CAA6C;gBACrD,MAAM,EAAE,4BAA4B;gBACpC,MAAM,EAAE,IAAI;aACb;SACF;KACF,CAAC;IACF,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Harness, ProjectType } from "../core/config.js";
|
|
2
|
+
/** Project-owned extension point for remote-environment requirements. */
|
|
3
|
+
export declare const REMOTE_ENVIRONMENT_MANIFEST: ".lisa/remote-environment.json";
|
|
4
|
+
/** One concrete coding agent, excluding the fleet aggregate. */
|
|
5
|
+
export type RemoteAgent = Exclude<Harness, "fleet">;
|
|
6
|
+
/** A variable the current project requires in a remote coding environment. */
|
|
7
|
+
export interface RemoteEnvironmentVariableStatus {
|
|
8
|
+
/** Environment-variable name. Values are never exposed. */
|
|
9
|
+
readonly name: string;
|
|
10
|
+
/** Why this project requires the variable. */
|
|
11
|
+
readonly reason: string;
|
|
12
|
+
/** Project signal that activated the requirement. */
|
|
13
|
+
readonly source: string;
|
|
14
|
+
/** Whether the variable contains a credential. */
|
|
15
|
+
readonly secret: boolean;
|
|
16
|
+
/** Whether the variable is visible to the `lisa ui` process. */
|
|
17
|
+
readonly set: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** Startup artifact expected by one supported remote coding agent. */
|
|
20
|
+
export interface RemoteEnvironmentStartupStatus {
|
|
21
|
+
/** Agent whose remote environment consumes the artifact. */
|
|
22
|
+
readonly agent: RemoteAgent;
|
|
23
|
+
/** Project-relative setup artifact, when one is configured. */
|
|
24
|
+
readonly artifact?: string;
|
|
25
|
+
/** Whether the configured artifact exists. */
|
|
26
|
+
readonly installed: boolean;
|
|
27
|
+
}
|
|
28
|
+
/** Project-aware remote-environment readiness exposed to the console. */
|
|
29
|
+
export interface RemoteEnvironmentStatus {
|
|
30
|
+
/** Lisa project types detected for the current project. */
|
|
31
|
+
readonly projectTypes: readonly ProjectType[];
|
|
32
|
+
/** Required variables only; optional/dormant integrations are omitted. */
|
|
33
|
+
readonly variables: readonly RemoteEnvironmentVariableStatus[];
|
|
34
|
+
/** Startup artifact status for every supported agent. */
|
|
35
|
+
readonly startupScripts: readonly RemoteEnvironmentStartupStatus[];
|
|
36
|
+
}
|
|
37
|
+
/** Internal names-only variable requirement. */
|
|
38
|
+
export interface VariableRequirement {
|
|
39
|
+
/** Environment-variable name. */
|
|
40
|
+
readonly name: string;
|
|
41
|
+
/** Human-readable reason the project requires it. */
|
|
42
|
+
readonly reason: string;
|
|
43
|
+
/** Project signal that activated it. */
|
|
44
|
+
readonly source: string;
|
|
45
|
+
/** Whether it contains a credential. */
|
|
46
|
+
readonly secret: boolean;
|
|
47
|
+
}
|
|
48
|
+
/** Active remote-tool integrations detected from the host project. */
|
|
49
|
+
export interface IntegrationFlags {
|
|
50
|
+
/** AWS SDK/infrastructure/operational integration. */
|
|
51
|
+
readonly aws: boolean;
|
|
52
|
+
/** Expo Application Services integration. */
|
|
53
|
+
readonly eas: boolean;
|
|
54
|
+
/** Figma tooling integration. */
|
|
55
|
+
readonly figma: boolean;
|
|
56
|
+
/** Jam debugging integration. */
|
|
57
|
+
readonly jam: boolean;
|
|
58
|
+
/** Maestro Cloud integration. */
|
|
59
|
+
readonly maestro: boolean;
|
|
60
|
+
/** Sentry tooling integration. */
|
|
61
|
+
readonly sentry: boolean;
|
|
62
|
+
/** SonarCloud integration. */
|
|
63
|
+
readonly sonar: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** Raw project-owned manifest shape; every field is validated before use. */
|
|
66
|
+
export interface RemoteEnvironmentManifest {
|
|
67
|
+
/** Names-only variable declarations. */
|
|
68
|
+
readonly variables?: readonly {
|
|
69
|
+
readonly name?: unknown;
|
|
70
|
+
readonly reason?: unknown;
|
|
71
|
+
readonly source?: unknown;
|
|
72
|
+
readonly secret?: unknown;
|
|
73
|
+
readonly required?: unknown;
|
|
74
|
+
}[];
|
|
75
|
+
/** Per-agent project-relative startup artifacts. */
|
|
76
|
+
readonly startupScripts?: Readonly<Record<string, unknown>>;
|
|
77
|
+
}
|
|
78
|
+
/** Supported concrete agents in canonical order. */
|
|
79
|
+
export declare const REMOTE_AGENTS: readonly RemoteAgent[];
|
|
80
|
+
/** Default project artifacts recognized for each remote agent. */
|
|
81
|
+
export declare const DEFAULT_STARTUP_ARTIFACTS: Readonly<Record<RemoteAgent, readonly string[]>>;
|
|
82
|
+
/**
|
|
83
|
+
* Validate project-owned manifest variable declarations.
|
|
84
|
+
* @param manifest - Parsed manifest
|
|
85
|
+
* @returns Required variable declarations only
|
|
86
|
+
*/
|
|
87
|
+
export declare function manifestRequirements(manifest: RemoteEnvironmentManifest | null): readonly VariableRequirement[];
|
|
88
|
+
/**
|
|
89
|
+
* Deduplicate requirements by variable name while preserving first-source order.
|
|
90
|
+
* @param requirements - Requirements from config, detection, and manifest
|
|
91
|
+
* @returns Deduplicated requirements
|
|
92
|
+
*/
|
|
93
|
+
export declare function uniqueRequirements(requirements: readonly VariableRequirement[]): readonly VariableRequirement[];
|
|
94
|
+
//# sourceMappingURL=remote-environment-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-environment-contract.d.ts","sourceRoot":"","sources":["../../src/cli/remote-environment-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAG9D,yEAAyE;AACzE,eAAO,MAAM,2BAA2B,EACtC,+BAAwC,CAAC;AAE3C,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEpD,8EAA8E;AAC9E,MAAM,WAAW,+BAA+B;IAC9C,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,gEAAgE;IAChE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACvB;AAED,sEAAsE;AACtE,MAAM,WAAW,8BAA8B;IAC7C,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,yEAAyE;AACzE,MAAM,WAAW,uBAAuB;IACtC,2DAA2D;IAC3D,QAAQ,CAAC,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IAC9C,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,SAAS,+BAA+B,EAAE,CAAC;IAC/D,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,SAAS,8BAA8B,EAAE,CAAC;CACpE;AAED,gDAAgD;AAChD,MAAM,WAAW,mBAAmB;IAClC,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,6EAA6E;AAC7E,MAAM,WAAW,yBAAyB;IACxC,wCAAwC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS;QAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;KAC7B,EAAE,CAAC;IACJ,oDAAoD;IACpD,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC7D;AAED,oDAAoD;AACpD,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAE/C,CAAC;AAIF,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAC9C,MAAM,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC,CAgBvC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,yBAAyB,GAAG,IAAI,GACzC,SAAS,mBAAmB,EAAE,CAwBhC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,SAAS,mBAAmB,EAAE,GAC3C,SAAS,mBAAmB,EAAE,CAOhC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { HARNESS_VALUES } from "../core/config.js";
|
|
2
|
+
/** Project-owned extension point for remote-environment requirements. */
|
|
3
|
+
export const REMOTE_ENVIRONMENT_MANIFEST = ".lisa/remote-environment.json";
|
|
4
|
+
/** Supported concrete agents in canonical order. */
|
|
5
|
+
export const REMOTE_AGENTS = HARNESS_VALUES.filter((harness) => harness !== "fleet");
|
|
6
|
+
const GENERIC_STARTUP_ARTIFACT = "scripts/remote-agent-setup.sh";
|
|
7
|
+
/** Default project artifacts recognized for each remote agent. */
|
|
8
|
+
export const DEFAULT_STARTUP_ARTIFACTS = {
|
|
9
|
+
claude: ["scripts/claude-remote-setup.sh", GENERIC_STARTUP_ARTIFACT],
|
|
10
|
+
codex: ["scripts/codex-remote-setup.sh", GENERIC_STARTUP_ARTIFACT],
|
|
11
|
+
cursor: [
|
|
12
|
+
".cursor/environment.json",
|
|
13
|
+
"scripts/cursor-remote-setup.sh",
|
|
14
|
+
GENERIC_STARTUP_ARTIFACT,
|
|
15
|
+
],
|
|
16
|
+
agy: ["scripts/agy-remote-setup.sh", GENERIC_STARTUP_ARTIFACT],
|
|
17
|
+
copilot: [
|
|
18
|
+
".github/workflows/copilot-setup-steps.yml",
|
|
19
|
+
"scripts/copilot-remote-setup.sh",
|
|
20
|
+
GENERIC_STARTUP_ARTIFACT,
|
|
21
|
+
],
|
|
22
|
+
opencode: ["scripts/opencode-remote-setup.sh", GENERIC_STARTUP_ARTIFACT],
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Validate project-owned manifest variable declarations.
|
|
26
|
+
* @param manifest - Parsed manifest
|
|
27
|
+
* @returns Required variable declarations only
|
|
28
|
+
*/
|
|
29
|
+
export function manifestRequirements(manifest) {
|
|
30
|
+
return (manifest?.variables ?? []).flatMap(entry => {
|
|
31
|
+
if (entry.required === false ||
|
|
32
|
+
typeof entry.name !== "string" ||
|
|
33
|
+
!/^[A-Z][A-Z0-9_]*$/u.test(entry.name)) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
return [
|
|
37
|
+
{
|
|
38
|
+
name: entry.name,
|
|
39
|
+
reason: typeof entry.reason === "string"
|
|
40
|
+
? entry.reason
|
|
41
|
+
: "Required by the project remote-environment manifest",
|
|
42
|
+
source: typeof entry.source === "string"
|
|
43
|
+
? entry.source
|
|
44
|
+
: REMOTE_ENVIRONMENT_MANIFEST,
|
|
45
|
+
secret: entry.secret !== false,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Deduplicate requirements by variable name while preserving first-source order.
|
|
52
|
+
* @param requirements - Requirements from config, detection, and manifest
|
|
53
|
+
* @returns Deduplicated requirements
|
|
54
|
+
*/
|
|
55
|
+
export function uniqueRequirements(requirements) {
|
|
56
|
+
return requirements.filter((requirement, index) => requirements.findIndex(candidate => candidate.name === requirement.name) === index);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=remote-environment-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-environment-contract.js","sourceRoot":"","sources":["../../src/cli/remote-environment-contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,yEAAyE;AACzE,MAAM,CAAC,MAAM,2BAA2B,GACtC,+BAAwC,CAAC;AAmF3C,oDAAoD;AACpD,MAAM,CAAC,MAAM,aAAa,GAA2B,cAAc,CAAC,MAAM,CACxE,CAAC,OAAO,EAA0B,EAAE,CAAC,OAAO,KAAK,OAAO,CACzD,CAAC;AAEF,MAAM,wBAAwB,GAAG,+BAA+B,CAAC;AAEjE,kEAAkE;AAClE,MAAM,CAAC,MAAM,yBAAyB,GAElC;IACF,MAAM,EAAE,CAAC,gCAAgC,EAAE,wBAAwB,CAAC;IACpE,KAAK,EAAE,CAAC,+BAA+B,EAAE,wBAAwB,CAAC;IAClE,MAAM,EAAE;QACN,0BAA0B;QAC1B,gCAAgC;QAChC,wBAAwB;KACzB;IACD,GAAG,EAAE,CAAC,6BAA6B,EAAE,wBAAwB,CAAC;IAC9D,OAAO,EAAE;QACP,2CAA2C;QAC3C,iCAAiC;QACjC,wBAAwB;KACzB;IACD,QAAQ,EAAE,CAAC,kCAAkC,EAAE,wBAAwB,CAAC;CACzE,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA0C;IAE1C,OAAO,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACjD,IACE,KAAK,CAAC,QAAQ,KAAK,KAAK;YACxB,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;YAC9B,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EACtC,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO;YACL;gBACE,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EACJ,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;oBAC9B,CAAC,CAAC,KAAK,CAAC,MAAM;oBACd,CAAC,CAAC,qDAAqD;gBAC3D,MAAM,EACJ,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;oBAC9B,CAAC,CAAC,KAAK,CAAC,MAAM;oBACd,CAAC,CAAC,2BAA2B;gBACjC,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,KAAK;aAC/B;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAA4C;IAE5C,OAAO,YAAY,CAAC,MAAM,CACxB,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CACrB,YAAY,CAAC,SAAS,CACpB,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CACjD,KAAK,KAAK,CACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ProjectType } from "../core/config.js";
|
|
2
|
+
import type { VariableRequirement } from "./remote-environment-contract.js";
|
|
3
|
+
/**
|
|
4
|
+
* Read a UTF-8 file, returning an empty string when it is absent.
|
|
5
|
+
* @param filePath - Absolute path
|
|
6
|
+
* @returns File contents or an empty string
|
|
7
|
+
*/
|
|
8
|
+
export declare function readTextOrEmpty(filePath: string): Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Return whether a project-relative file exists.
|
|
11
|
+
* @param destDir - Project root
|
|
12
|
+
* @param relativePath - Project-relative path
|
|
13
|
+
* @returns True when the file can be read and is non-empty
|
|
14
|
+
*/
|
|
15
|
+
export declare function projectFileExists(destDir: string, relativePath: string): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Build requirements activated by detected project type and integrations.
|
|
18
|
+
* @param destDir - Project root
|
|
19
|
+
* @param projectTypes - Detected Lisa project types
|
|
20
|
+
* @returns Project-specific requirements
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectedProjectRequirements(destDir: string, projectTypes: readonly ProjectType[]): Promise<readonly VariableRequirement[]>;
|
|
23
|
+
//# sourceMappingURL=remote-environment-detection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-environment-detection.d.ts","sourceRoot":"","sources":["../../src/cli/remote-environment-detection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAU1C;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWvE;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAElB;AA2GD;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,SAAS,WAAW,EAAE,GACnC,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAIzC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { readJsonOrNull } from "../utils/index.js";
|
|
4
|
+
import { requirementsForFlags } from "./remote-environment-catalog.js";
|
|
5
|
+
/**
|
|
6
|
+
* Read a UTF-8 file, returning an empty string when it is absent.
|
|
7
|
+
* @param filePath - Absolute path
|
|
8
|
+
* @returns File contents or an empty string
|
|
9
|
+
*/
|
|
10
|
+
export async function readTextOrEmpty(filePath) {
|
|
11
|
+
try {
|
|
12
|
+
return await readFile(filePath, "utf8");
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
const code = typeof error === "object" && error !== null && "code" in error
|
|
16
|
+
? error.code
|
|
17
|
+
: undefined;
|
|
18
|
+
if (code === "ENOENT")
|
|
19
|
+
return "";
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Return whether a project-relative file exists.
|
|
25
|
+
* @param destDir - Project root
|
|
26
|
+
* @param relativePath - Project-relative path
|
|
27
|
+
* @returns True when the file can be read and is non-empty
|
|
28
|
+
*/
|
|
29
|
+
export async function projectFileExists(destDir, relativePath) {
|
|
30
|
+
return (await readTextOrEmpty(path.join(destDir, relativePath))) !== "";
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Read dependency names and selected project-owned integration surfaces.
|
|
34
|
+
* @param destDir - Project root
|
|
35
|
+
* @returns Signals used by the requirement detectors
|
|
36
|
+
*/
|
|
37
|
+
async function readProjectSignals(destDir) {
|
|
38
|
+
const packageJson = await readJsonOrNull(path.join(destDir, "package.json"));
|
|
39
|
+
const dependencies = new Set([
|
|
40
|
+
...Object.keys(packageJson?.dependencies ?? {}),
|
|
41
|
+
...Object.keys(packageJson?.devDependencies ?? {}),
|
|
42
|
+
]);
|
|
43
|
+
const workflows = ["ci", "deploy", "quality"].flatMap(name => [
|
|
44
|
+
`.github/workflows/${name}.yml`,
|
|
45
|
+
`.github/workflows/${name}.yaml`,
|
|
46
|
+
]);
|
|
47
|
+
const [envExample, remoteSetup, ...workflowContents] = await Promise.all([
|
|
48
|
+
readTextOrEmpty(path.join(destDir, ".env.example")),
|
|
49
|
+
readTextOrEmpty(path.join(destDir, "scripts/claude-remote-setup.sh")),
|
|
50
|
+
...workflows.map(relativePath => readTextOrEmpty(path.join(destDir, relativePath))),
|
|
51
|
+
]);
|
|
52
|
+
return {
|
|
53
|
+
dependencies,
|
|
54
|
+
envExample,
|
|
55
|
+
remoteSetup,
|
|
56
|
+
workflows: workflowContents.join("\n"),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Test dependency presence by exact name or namespace prefix.
|
|
61
|
+
* @param dependencies - Project dependency names
|
|
62
|
+
* @param names - Exact names or prefixes ending in `/`
|
|
63
|
+
* @returns Whether any dependency matches
|
|
64
|
+
*/
|
|
65
|
+
function hasDependency(dependencies, names) {
|
|
66
|
+
return Array.from(dependencies).some(dependency => names.some(name => name.endsWith("/") ? dependency.startsWith(name) : dependency === name));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Detect active project integrations from dependencies and committed surfaces.
|
|
70
|
+
* @param destDir - Project root
|
|
71
|
+
* @param projectTypes - Detected Lisa project types
|
|
72
|
+
* @param signals - Project signals
|
|
73
|
+
* @returns Boolean integration flags
|
|
74
|
+
*/
|
|
75
|
+
async function detectIntegrationFlags(destDir, projectTypes, signals) {
|
|
76
|
+
const { dependencies, envExample, remoteSetup, workflows } = signals;
|
|
77
|
+
const [serverlessYml, serverlessYaml, sstTs, sstJs, sonar, eas, maestro] = await Promise.all([
|
|
78
|
+
"serverless.yml",
|
|
79
|
+
"serverless.yaml",
|
|
80
|
+
"sst.config.ts",
|
|
81
|
+
"sst.config.js",
|
|
82
|
+
"sonar-project.properties",
|
|
83
|
+
"eas.json",
|
|
84
|
+
".maestro/config.yaml",
|
|
85
|
+
].map(relativePath => projectFileExists(destDir, relativePath)));
|
|
86
|
+
return {
|
|
87
|
+
aws: projectTypes.includes("cdk") ||
|
|
88
|
+
hasDependency(dependencies, [
|
|
89
|
+
"@aws-sdk/",
|
|
90
|
+
"aws-cdk-lib",
|
|
91
|
+
"serverless",
|
|
92
|
+
"sst",
|
|
93
|
+
]) ||
|
|
94
|
+
/^(AWS_PROFILE|CDK_CONTEXT_ACCOUNT|CDK_CONTEXT_ENV)=/mu.test(envExample) ||
|
|
95
|
+
[serverlessYml, serverlessYaml, sstTs, sstJs].some(Boolean),
|
|
96
|
+
eas: projectTypes.includes("expo") &&
|
|
97
|
+
(eas || workflows.includes("EXPO_TOKEN")),
|
|
98
|
+
figma: remoteSetup.includes("FIGMA_ACCESS_TOKEN"),
|
|
99
|
+
jam: hasDependency(dependencies, ["@jam.dev/"]),
|
|
100
|
+
maestro: maestro === true && workflows.includes("MAESTRO_API_KEY"),
|
|
101
|
+
sentry: hasDependency(dependencies, ["@sentry/"]) &&
|
|
102
|
+
(remoteSetup.includes("SENTRY_AUTH_TOKEN") ||
|
|
103
|
+
workflows.includes("SENTRY_AUTH_TOKEN")),
|
|
104
|
+
sonar: sonar === true &&
|
|
105
|
+
(remoteSetup.includes("SONAR_TOKEN") ||
|
|
106
|
+
workflows.includes("SONAR_TOKEN")),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Build requirements activated by detected project type and integrations.
|
|
111
|
+
* @param destDir - Project root
|
|
112
|
+
* @param projectTypes - Detected Lisa project types
|
|
113
|
+
* @returns Project-specific requirements
|
|
114
|
+
*/
|
|
115
|
+
export async function detectedProjectRequirements(destDir, projectTypes) {
|
|
116
|
+
const signals = await readProjectSignals(destDir);
|
|
117
|
+
const flags = await detectIntegrationFlags(destDir, projectTypes, signals);
|
|
118
|
+
return requirementsForFlags(flags, projectTypes);
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=remote-environment-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-environment-detection.js","sourceRoot":"","sources":["../../src/cli/remote-environment-detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { JsonObject } from "../sync/json-path.js";
|
|
2
|
+
import { type RemoteEnvironmentStatus } from "./remote-environment-contract.js";
|
|
3
|
+
export type { RemoteEnvironmentStartupStatus, RemoteEnvironmentStatus, RemoteEnvironmentVariableStatus, } from "./remote-environment-contract.js";
|
|
4
|
+
/**
|
|
5
|
+
* Inspect requirements for this particular project without exposing values.
|
|
6
|
+
* @param destDir - Project root
|
|
7
|
+
* @param config - Merged Lisa project config
|
|
8
|
+
* @param environment - Environment visible to the Lisa process
|
|
9
|
+
* @returns Project-aware variable and startup-artifact status
|
|
10
|
+
*/
|
|
11
|
+
export declare function inspectRemoteEnvironment(destDir: string, config: JsonObject, environment: NodeJS.ProcessEnv): Promise<RemoteEnvironmentStatus>;
|
|
12
|
+
//# sourceMappingURL=remote-environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-environment.d.ts","sourceRoot":"","sources":["../../src/cli/remote-environment.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAQL,KAAK,uBAAuB,EAE7B,MAAM,kCAAkC,CAAC;AAO1C,YAAY,EACV,8BAA8B,EAC9B,uBAAuB,EACvB,+BAA+B,GAChC,MAAM,kCAAkC,CAAC;AAkD1C;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,MAAM,CAAC,UAAU,GAC7B,OAAO,CAAC,uBAAuB,CAAC,CA2BlC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { createDetectorRegistry } from "../detection/index.js";
|
|
3
|
+
import { readJsonOrNull } from "../utils/index.js";
|
|
4
|
+
import { DEFAULT_STARTUP_ARTIFACTS, manifestRequirements, REMOTE_AGENTS, REMOTE_ENVIRONMENT_MANIFEST, uniqueRequirements, } from "./remote-environment-contract.js";
|
|
5
|
+
import { configuredIntegrationRequirements } from "./remote-environment-catalog.js";
|
|
6
|
+
import { detectedProjectRequirements, projectFileExists, } from "./remote-environment-detection.js";
|
|
7
|
+
/**
|
|
8
|
+
* Restrict manifest artifacts to files beneath the host project.
|
|
9
|
+
* @param candidate - Project-owned manifest value
|
|
10
|
+
* @returns Whether the value is a safe project-relative path
|
|
11
|
+
*/
|
|
12
|
+
function isSafeProjectArtifact(candidate) {
|
|
13
|
+
return (candidate.length > 0 &&
|
|
14
|
+
!path.isAbsolute(candidate) &&
|
|
15
|
+
!candidate.split(/[\\/]/u).includes(".."));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve an explicitly configured or discovered startup artifact for one agent.
|
|
19
|
+
* @param destDir - Project root
|
|
20
|
+
* @param agent - Supported coding agent
|
|
21
|
+
* @param manifest - Project-owned manifest
|
|
22
|
+
* @returns Startup artifact status
|
|
23
|
+
*/
|
|
24
|
+
async function resolveStartupScript(destDir, agent, manifest) {
|
|
25
|
+
const configured = manifest?.startupScripts?.[agent];
|
|
26
|
+
const explicit = typeof configured === "string" && isSafeProjectArtifact(configured)
|
|
27
|
+
? configured
|
|
28
|
+
: undefined;
|
|
29
|
+
const candidates = explicit === undefined ? DEFAULT_STARTUP_ARTIFACTS[agent] : [explicit];
|
|
30
|
+
const existence = await Promise.all(candidates.map(async (artifact) => ({
|
|
31
|
+
artifact,
|
|
32
|
+
exists: await projectFileExists(destDir, artifact),
|
|
33
|
+
})));
|
|
34
|
+
const installed = existence.find(candidate => candidate.exists);
|
|
35
|
+
return installed === undefined
|
|
36
|
+
? {
|
|
37
|
+
agent,
|
|
38
|
+
...(explicit === undefined ? {} : { artifact: explicit }),
|
|
39
|
+
installed: false,
|
|
40
|
+
}
|
|
41
|
+
: { agent, artifact: installed.artifact, installed: true };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Inspect requirements for this particular project without exposing values.
|
|
45
|
+
* @param destDir - Project root
|
|
46
|
+
* @param config - Merged Lisa project config
|
|
47
|
+
* @param environment - Environment visible to the Lisa process
|
|
48
|
+
* @returns Project-aware variable and startup-artifact status
|
|
49
|
+
*/
|
|
50
|
+
export async function inspectRemoteEnvironment(destDir, config, environment) {
|
|
51
|
+
const detectorRegistry = createDetectorRegistry();
|
|
52
|
+
const [detectedTypes, manifest] = await Promise.all([
|
|
53
|
+
detectorRegistry.detectAll(destDir),
|
|
54
|
+
readJsonOrNull(path.join(destDir, REMOTE_ENVIRONMENT_MANIFEST)),
|
|
55
|
+
]);
|
|
56
|
+
const projectTypes = detectorRegistry.expandAndOrderTypes(detectedTypes);
|
|
57
|
+
const requirements = uniqueRequirements([
|
|
58
|
+
...configuredIntegrationRequirements(config),
|
|
59
|
+
...(await detectedProjectRequirements(destDir, projectTypes)),
|
|
60
|
+
...manifestRequirements(manifest),
|
|
61
|
+
]);
|
|
62
|
+
const startupScripts = await Promise.all(REMOTE_AGENTS.map(agent => resolveStartupScript(destDir, agent, manifest)));
|
|
63
|
+
return {
|
|
64
|
+
projectTypes,
|
|
65
|
+
variables: requirements.map(requirement => ({
|
|
66
|
+
...requirement,
|
|
67
|
+
set: typeof environment[requirement.name] === "string" &&
|
|
68
|
+
environment[requirement.name].length > 0,
|
|
69
|
+
})),
|
|
70
|
+
startupScripts,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=remote-environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-environment.js","sourceRoot":"","sources":["../../src/cli/remote-environment.ts"],"names":[],"mappings":"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"}
|