@launchsecure/launch-kit 0.0.31 → 0.0.33

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 (95) hide show
  1. package/dist/beacon/beacon.mjs +550 -521
  2. package/dist/beacon/beacon.mjs.map +1 -1
  3. package/dist/beacon/beacon.umd.js +9 -9
  4. package/dist/beacon/beacon.umd.js.map +1 -1
  5. package/dist/beacon/types/internal/pick-mode-overlay.d.ts.map +1 -1
  6. package/dist/beacon/types/internal/picker.d.ts.map +1 -1
  7. package/dist/beacon/types/internal/pin-popover.d.ts.map +1 -1
  8. package/dist/beacon/types/internal/selector.d.ts.map +1 -1
  9. package/dist/chart-client/assets/{index-B__ARB8k.js → index-DFu2xIrM.js} +2 -2
  10. package/dist/chart-client/assets/index-DpKO9p0s.css +1 -0
  11. package/dist/chart-client/index.html +2 -2
  12. package/dist/client/assets/{index-h8kMzVtG.js → index-Cbw6bVdx.js} +2 -2
  13. package/dist/client/assets/index-Dv6dD2zY.css +32 -0
  14. package/dist/client/index.html +2 -2
  15. package/dist/council-client/assets/index-AqQ9Sei6.css +1 -0
  16. package/dist/council-client/assets/{index-CWaDcsFR.js → index-CAsmGTzg.js} +2 -2
  17. package/dist/council-client/index.html +2 -2
  18. package/dist/deck-client/assets/{_baseUniq-DdHaBFYO.js → _baseUniq-BiVx0WO_.js} +1 -1
  19. package/dist/deck-client/assets/{arc-D98e_18X.js → arc-DGMkiEzS.js} +1 -1
  20. package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-DNFZzh-4.js → architectureDiagram-Q4EWVU46-Y2WRmHtk.js} +1 -1
  21. package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-DeQvGUdX.js → blockDiagram-DXYQGD6D-_Lbfu5BQ.js} +1 -1
  22. package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-B6ekZf1n.js → c4Diagram-AHTNJAMY-CTqpYTBX.js} +1 -1
  23. package/dist/deck-client/assets/channel-DB6LxW_l.js +1 -0
  24. package/dist/deck-client/assets/{chunk-4BX2VUAB-9aDWymq2.js → chunk-4BX2VUAB-liEIbPHs.js} +1 -1
  25. package/dist/deck-client/assets/{chunk-4TB4RGXK-DtKQqaI7.js → chunk-4TB4RGXK-CCc6lYvL.js} +1 -1
  26. package/dist/deck-client/assets/{chunk-55IACEB6-COy9hEae.js → chunk-55IACEB6-D02jJUR2.js} +1 -1
  27. package/dist/deck-client/assets/{chunk-EDXVE4YY-D_f861An.js → chunk-EDXVE4YY-BFmGMbLD.js} +1 -1
  28. package/dist/deck-client/assets/{chunk-FMBD7UC4-CmuA5UKn.js → chunk-FMBD7UC4-6wFLOVcJ.js} +1 -1
  29. package/dist/deck-client/assets/{chunk-OYMX7WX6-vT8z8D-0.js → chunk-OYMX7WX6-Bnr8RiBf.js} +1 -1
  30. package/dist/deck-client/assets/{chunk-QZHKN3VN-CTlwwg-R.js → chunk-QZHKN3VN-Ct82MksJ.js} +1 -1
  31. package/dist/deck-client/assets/{chunk-YZCP3GAM-C44yr620.js → chunk-YZCP3GAM-BXmN1diQ.js} +1 -1
  32. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-g944ZyG8.js +1 -0
  33. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-g944ZyG8.js +1 -0
  34. package/dist/deck-client/assets/clone-DiIRH1pI.js +1 -0
  35. package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-DBB2J2nL.js → cose-bilkent-S5V4N54A-CmQCT-mH.js} +1 -1
  36. package/dist/deck-client/assets/{dagre-KV5264BT-DxDTYbKl.js → dagre-KV5264BT-DDdSa9EX.js} +1 -1
  37. package/dist/deck-client/assets/{diagram-5BDNPKRD-DByWrWd1.js → diagram-5BDNPKRD-Bccks2xJ.js} +1 -1
  38. package/dist/deck-client/assets/{diagram-G4DWMVQ6-B8B6ddMq.js → diagram-G4DWMVQ6-CPPNgxmQ.js} +1 -1
  39. package/dist/deck-client/assets/{diagram-MMDJMWI5-BMUZ2PWK.js → diagram-MMDJMWI5-KrD300pS.js} +1 -1
  40. package/dist/deck-client/assets/{diagram-TYMM5635-Bk9e8BB-.js → diagram-TYMM5635-DefnLuQf.js} +1 -1
  41. package/dist/deck-client/assets/{erDiagram-SMLLAGMA-DcOSwSol.js → erDiagram-SMLLAGMA-DI9FfnFP.js} +1 -1
  42. package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-DI-4BR0F.js → flowDiagram-DWJPFMVM-twKyd3Fx.js} +1 -1
  43. package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-BeZuXBoU.js → ganttDiagram-T4ZO3ILL-Wau3jhBr.js} +1 -1
  44. package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-Bcki__f-.js → gitGraphDiagram-UUTBAWPF-D9GgYXwb.js} +1 -1
  45. package/dist/deck-client/assets/{graph-CifKx6G1.js → graph-BhNLzyXS.js} +1 -1
  46. package/dist/deck-client/assets/index-B-YQq5b5.css +1 -0
  47. package/dist/deck-client/assets/{index-CB-qlwRT.js → index-BtQBaQ7s.js} +76 -76
  48. package/dist/deck-client/assets/{infoDiagram-42DDH7IO-CReN1nFN.js → infoDiagram-42DDH7IO-TylGlSG-.js} +1 -1
  49. package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-CDF_VLN_.js → ishikawaDiagram-UXIWVN3A-DAT8icpg.js} +1 -1
  50. package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-DwgGrNVB.js → journeyDiagram-VCZTEJTY-D3v_XL72.js} +1 -1
  51. package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-DB_zohh5.js → kanban-definition-6JOO6SKY-DNUOBiNr.js} +1 -1
  52. package/dist/deck-client/assets/{layout-DFfX1O3z.js → layout-COfodgwF.js} +1 -1
  53. package/dist/deck-client/assets/{linear-CtKb4EXj.js → linear-DmTsuIvK.js} +1 -1
  54. package/dist/deck-client/assets/{min-DCRRwUZv.js → min-BW1F7i1D.js} +1 -1
  55. package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-D0QBOiFe.js → mindmap-definition-QFDTVHPH-CErFzKWl.js} +1 -1
  56. package/dist/deck-client/assets/{pieDiagram-DEJITSTG-CD-EV5WB.js → pieDiagram-DEJITSTG-DW5F757o.js} +1 -1
  57. package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-B-JXZ8xI.js → quadrantDiagram-34T5L4WZ-B1S2-TfI.js} +1 -1
  58. package/dist/deck-client/assets/{requirementDiagram-MS252O5E-D2_OK5Dp.js → requirementDiagram-MS252O5E-BY5BAR-5.js} +1 -1
  59. package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-BbBJqVSC.js → sankeyDiagram-XADWPNL6-CE1Cp9HS.js} +1 -1
  60. package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-Db8A-Rkk.js → sequenceDiagram-FGHM5R23-IaHnbKye.js} +1 -1
  61. package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-DGJnanjS.js → stateDiagram-FHFEXIEX-CwPJm9hU.js} +1 -1
  62. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-DQYa2M1q.js +1 -0
  63. package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-BRkr6T4w.js → timeline-definition-GMOUNBTQ-DVFGGSgN.js} +1 -1
  64. package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-d0rsTqFo.js → vennDiagram-DHZGUBPP-C1194MJi.js} +1 -1
  65. package/dist/deck-client/assets/{wardley-RL74JXVD-2t7cMqdS.js → wardley-RL74JXVD-CHZiUbBa.js} +1 -1
  66. package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-DzboAsHh.js → wardleyDiagram-NUSXRM2D-hpwdFfGj.js} +1 -1
  67. package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-CgTP9u2V.js → xychartDiagram-5P7HB3ND-DYkotwy8.js} +1 -1
  68. package/dist/deck-client/index.html +2 -2
  69. package/dist/server/cli.js +91 -13
  70. package/dist/server/council-entry.js +0 -0
  71. package/dist/server/deck-mcp-entry.js +83 -40
  72. package/dist/server/deck-serve.js +54 -20
  73. package/dist/server/fb-wizard.js +0 -0
  74. package/dist/server/init-entry.js +952 -290
  75. package/dist/server/radar-docker-init-entry.js +239 -0
  76. package/dist/server/radar-entrypoint-entry.js +99 -0
  77. package/dist/server/radar-teardown-entry.js +477 -0
  78. package/dist/server/recall-entry.js +4 -1
  79. package/package.json +22 -23
  80. package/scaffolds/ls-marketplace/plugins/kit/commands/activate-statusline.md +5 -5
  81. package/scaffolds/ls-marketplace/plugins/kit/skills/diagram/SKILL.md +27 -5
  82. package/scaffolds/ls-marketplace/plugins/kit/skills/ship/SKILL.md +274 -0
  83. package/scaffolds/migrate-safety/scripts/migrate-with-backup.sh +0 -0
  84. package/scaffolds/recall-hook/scripts/ensure-recall.sh +0 -0
  85. package/scaffolds/statusline/statusline-mcp.sh +82 -2
  86. package/scaffolds/statusline/statusline-wrapper.sh +8 -1
  87. package/dist/chart-client/assets/index-CDIhdgWg.css +0 -1
  88. package/dist/client/assets/index-CfW4n40I.css +0 -32
  89. package/dist/council-client/assets/index-CZim6x1u.css +0 -1
  90. package/dist/deck-client/assets/channel-DmR7Tyyt.js +0 -1
  91. package/dist/deck-client/assets/classDiagram-6PBFFD2Q-Bl4ozQWs.js +0 -1
  92. package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-Bl4ozQWs.js +0 -1
  93. package/dist/deck-client/assets/clone-BAy58j24.js +0 -1
  94. package/dist/deck-client/assets/index-BlTlhxFW.css +0 -1
  95. package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-CR7riiab.js +0 -1
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/server/radar-docker-init-entry.ts
5
+ var import_node_child_process = require("node:child_process");
6
+ var import_node_fs = require("node:fs");
7
+ var import_node_path = require("node:path");
8
+
9
+ // src/server/radar/mcp.ts
10
+ var import_node_https = require("node:https");
11
+ var import_node_http = require("node:http");
12
+ var ProjectMcpClient = class {
13
+ constructor(opts) {
14
+ this.initialized = false;
15
+ this.callId = 1;
16
+ this.mcpUrl = new URL("/api/mcp/project", opts.serverUrl);
17
+ this.headers = {
18
+ "Content-Type": "application/json",
19
+ "Accept": "application/json, text/event-stream",
20
+ "Authorization": `Bearer ${opts.pat}`
21
+ };
22
+ if (opts.orgSlug) this.headers["X-Org-Slug"] = opts.orgSlug;
23
+ if (opts.projectSlug) this.headers["X-Project-Slug"] = opts.projectSlug;
24
+ }
25
+ async call(toolName, args) {
26
+ await this.ensureInitialized();
27
+ const body = JSON.stringify({
28
+ jsonrpc: "2.0",
29
+ id: this.callId++,
30
+ method: "tools/call",
31
+ params: { name: toolName, arguments: args }
32
+ });
33
+ const resp = await this.send(body);
34
+ const parsed = parseBody(resp.body);
35
+ if (parsed.error) {
36
+ throw new Error(`MCP ${toolName} failed: ${parsed.error.message ?? JSON.stringify(parsed.error)}`);
37
+ }
38
+ const text = parsed.result?.content?.[0]?.text;
39
+ if (!text) return parsed.result;
40
+ if (text.startsWith("\u2500\u2500 Error")) {
41
+ const lines = text.split("\n").map((l) => l.trim()).filter(Boolean);
42
+ const reason = lines.find((l) => !l.startsWith("\u2500\u2500")) ?? text;
43
+ throw new Error(`MCP ${toolName} failed: ${reason}`);
44
+ }
45
+ try {
46
+ return JSON.parse(text);
47
+ } catch {
48
+ return text;
49
+ }
50
+ }
51
+ async ensureInitialized() {
52
+ if (this.initialized) return;
53
+ const initBody = JSON.stringify({
54
+ jsonrpc: "2.0",
55
+ id: this.callId++,
56
+ method: "initialize",
57
+ params: {
58
+ protocolVersion: "2025-03-26",
59
+ capabilities: {},
60
+ clientInfo: { name: "launchpod-feedback-agent", version: "0.0.1" }
61
+ }
62
+ });
63
+ const initResp = await this.send(initBody);
64
+ if (initResp.sessionId) this.sessionId = initResp.sessionId;
65
+ const notifBody = JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" });
66
+ await this.send(notifBody);
67
+ this.initialized = true;
68
+ }
69
+ send(body) {
70
+ return new Promise((resolve, reject) => {
71
+ const headers = {
72
+ ...this.headers,
73
+ "Content-Length": String(Buffer.byteLength(body))
74
+ };
75
+ if (this.sessionId) headers["Mcp-Session-Id"] = this.sessionId;
76
+ const requester = this.mcpUrl.protocol === "https:" ? import_node_https.request : import_node_http.request;
77
+ const req = requester(
78
+ {
79
+ host: this.mcpUrl.hostname,
80
+ port: this.mcpUrl.port || (this.mcpUrl.protocol === "https:" ? 443 : 80),
81
+ path: this.mcpUrl.pathname + this.mcpUrl.search,
82
+ method: "POST",
83
+ headers
84
+ },
85
+ (res) => {
86
+ const chunks = [];
87
+ res.on("data", (c) => chunks.push(c));
88
+ res.on("end", () => {
89
+ const text = Buffer.concat(chunks).toString("utf-8");
90
+ if (res.statusCode && res.statusCode >= 400) {
91
+ reject(new Error(`MCP HTTP ${res.statusCode}: ${text}`));
92
+ return;
93
+ }
94
+ const sid = res.headers["mcp-session-id"];
95
+ resolve({ body: text, sessionId: typeof sid === "string" ? sid : void 0 });
96
+ });
97
+ }
98
+ );
99
+ req.on("error", reject);
100
+ req.write(body);
101
+ req.end();
102
+ });
103
+ }
104
+ };
105
+ function parseBody(text) {
106
+ if (!text) return {};
107
+ if (text.startsWith("event:") || text.includes("\ndata: ")) {
108
+ for (const line of text.split("\n")) {
109
+ if (line.startsWith("data: ")) {
110
+ try {
111
+ return JSON.parse(line.slice(6));
112
+ } catch {
113
+ }
114
+ }
115
+ }
116
+ }
117
+ try {
118
+ return JSON.parse(text);
119
+ } catch {
120
+ return {};
121
+ }
122
+ }
123
+
124
+ // src/server/radar-docker-init-entry.ts
125
+ var REQUIRED_ENV = [
126
+ "CLAUDE_CREDENTIALS_B64",
127
+ "LS_PAT"
128
+ ];
129
+ function fail(message) {
130
+ console.error(message);
131
+ process.exit(1);
132
+ }
133
+ function requireEnv(name) {
134
+ const v = process.env[name];
135
+ if (!v) fail(`ERROR: ${name} is required but not set`);
136
+ return v;
137
+ }
138
+ function run(cmd, args, stdio = "inherit") {
139
+ const r = (0, import_node_child_process.spawnSync)(cmd, args, { stdio });
140
+ return r.status ?? 1;
141
+ }
142
+ async function setupFromCloud() {
143
+ const pat = requireEnv("LS_PAT");
144
+ const serverUrl = process.env.LS_SERVER_URL ?? "https://launchsecure-v2.vercel.app";
145
+ const orgSlug = process.env.LS_ORG_SLUG;
146
+ const projectSlug = process.env.LS_PROJECT_SLUG;
147
+ const mcp = new ProjectMcpClient({ serverUrl, pat, orgSlug, projectSlug });
148
+ let bundle;
149
+ try {
150
+ bundle = await mcp.call("radar_bootstrap_get", {});
151
+ } catch (err) {
152
+ fail(`[entrypoint] radar_bootstrap_get failed (${err instanceof Error ? err.message : String(err)}) \u2014 check LS_PAT has mcp:radar:bootstrap scope and is scoped to the right org/project.`);
153
+ }
154
+ if (!process.env.LS_ORG_SLUG) process.env.LS_ORG_SLUG = bundle.orgSlug;
155
+ if (!process.env.LS_PROJECT_SLUG) process.env.LS_PROJECT_SLUG = bundle.projectSlug;
156
+ if (!process.env.GIT_USER_NAME) process.env.GIT_USER_NAME = bundle.gitName;
157
+ if (!process.env.GIT_USER_EMAIL) process.env.GIT_USER_EMAIL = bundle.gitEmail;
158
+ if (!process.env.GH_TOKEN && bundle.githubToken) process.env.GH_TOKEN = bundle.githubToken;
159
+ if (!process.env.GH_TOKEN) {
160
+ fail(`[entrypoint] no GH_TOKEN available \u2014 user has not connected GitHub (githubTokenStatus=${bundle.githubTokenStatus}). Connect GitHub in LS or pre-set GH_TOKEN in the container env.`);
161
+ }
162
+ console.log(`[entrypoint] bundle from cloud: org=${process.env.LS_ORG_SLUG} project=${process.env.LS_PROJECT_SLUG} git=${process.env.GIT_USER_NAME} <${process.env.GIT_USER_EMAIL}> github=${bundle.githubTokenStatus.toLowerCase()}`);
163
+ }
164
+ function setupClaudeCredentials() {
165
+ const home = process.env.HOME ?? "/home/launchpod";
166
+ const claudeDir = (0, import_node_path.join)(home, ".claude");
167
+ (0, import_node_fs.mkdirSync)(claudeDir, { recursive: true });
168
+ const decoded = Buffer.from(requireEnv("CLAUDE_CREDENTIALS_B64"), "base64").toString("utf8");
169
+ const credsPath = (0, import_node_path.join)(claudeDir, ".credentials.json");
170
+ (0, import_node_fs.writeFileSync)(credsPath, decoded);
171
+ (0, import_node_fs.chmodSync)(credsPath, 384);
172
+ const configPath = (0, import_node_path.join)(home, ".claude.json");
173
+ let cfg = {};
174
+ if ((0, import_node_fs.existsSync)(configPath)) {
175
+ try {
176
+ cfg = JSON.parse((0, import_node_fs.readFileSync)(configPath, "utf8"));
177
+ } catch {
178
+ cfg = {};
179
+ }
180
+ }
181
+ cfg.hasCompletedOnboarding = true;
182
+ cfg.lastOnboardingVersion = cfg.lastOnboardingVersion ?? "2.1.159";
183
+ cfg.numStartups = (cfg.numStartups ?? 0) + 1;
184
+ cfg.installMethod = cfg.installMethod ?? "global";
185
+ (0, import_node_fs.writeFileSync)(configPath, JSON.stringify(cfg, null, 2));
186
+ (0, import_node_fs.chmodSync)(configPath, 384);
187
+ }
188
+ function setupGitAndGh() {
189
+ const name = process.env.GIT_USER_NAME ?? "Radar Bot";
190
+ const email = process.env.GIT_USER_EMAIL ?? "radar@launchpod.local";
191
+ const status = run("launch-kit", ["setup-git", `--identity=${name} <${email}>`]);
192
+ if (status !== 0) fail(`[entrypoint] launch-kit setup-git failed (status ${status})`);
193
+ }
194
+ function initWorkspaceIfEmpty() {
195
+ process.chdir("/workspace");
196
+ if ((0, import_node_fs.existsSync)(".git")) {
197
+ console.log("[entrypoint] /workspace already initialized \u2014 skipping init");
198
+ return;
199
+ }
200
+ console.log("[entrypoint] /workspace is empty \u2014 running launch-kit init");
201
+ const status = run("launch-kit", [
202
+ "init",
203
+ `--token=${requireEnv("LS_PAT")}`,
204
+ `--org=${requireEnv("LS_ORG_SLUG")}`,
205
+ `--project=${requireEnv("LS_PROJECT_SLUG")}`,
206
+ `--url=${process.env.LS_SERVER_URL ?? "https://launchsecure-v2.vercel.app"}`,
207
+ `--dir=/workspace`
208
+ ]);
209
+ if (status !== 0) fail(`[entrypoint] launch-kit init failed (status ${status})`);
210
+ }
211
+ function execLaunchPodRadar() {
212
+ console.log("[entrypoint] starting launch-pod radar");
213
+ const child = (0, import_node_child_process.spawn)("launch-pod", ["radar"], { stdio: "inherit" });
214
+ const forward = (sig) => () => {
215
+ try {
216
+ child.kill(sig);
217
+ } catch {
218
+ }
219
+ };
220
+ process.on("SIGTERM", forward("SIGTERM"));
221
+ process.on("SIGINT", forward("SIGINT"));
222
+ process.on("SIGHUP", forward("SIGHUP"));
223
+ child.on("exit", (code, signal) => {
224
+ if (signal) process.kill(process.pid, signal);
225
+ else process.exit(code ?? 0);
226
+ });
227
+ }
228
+ async function main() {
229
+ for (const k of REQUIRED_ENV) requireEnv(k);
230
+ await setupFromCloud();
231
+ setupClaudeCredentials();
232
+ setupGitAndGh();
233
+ initWorkspaceIfEmpty();
234
+ execLaunchPodRadar();
235
+ }
236
+ main().catch((err) => {
237
+ console.error(`[entrypoint] fatal: ${err instanceof Error ? err.message : String(err)}`);
238
+ process.exit(1);
239
+ });
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/server/radar-entrypoint-entry.ts
5
+ var import_node_child_process = require("node:child_process");
6
+ var import_node_fs = require("node:fs");
7
+ var import_node_path = require("node:path");
8
+ var REQUIRED_ENV = [
9
+ "CLAUDE_CREDENTIALS_B64",
10
+ "LS_PAT",
11
+ "LS_ORG_SLUG",
12
+ "LS_PROJECT_SLUG",
13
+ "GH_TOKEN"
14
+ ];
15
+ function fail(message) {
16
+ console.error(message);
17
+ process.exit(1);
18
+ }
19
+ function requireEnv(name) {
20
+ const v = process.env[name];
21
+ if (!v) fail(`ERROR: ${name} is required but not set`);
22
+ return v;
23
+ }
24
+ function run(cmd, args, stdio = "inherit") {
25
+ const r = (0, import_node_child_process.spawnSync)(cmd, args, { stdio });
26
+ return r.status ?? 1;
27
+ }
28
+ function setupClaudeCredentials() {
29
+ const home = process.env.HOME ?? "/home/launchpod";
30
+ const claudeDir = (0, import_node_path.join)(home, ".claude");
31
+ (0, import_node_fs.mkdirSync)(claudeDir, { recursive: true });
32
+ const decoded = Buffer.from(requireEnv("CLAUDE_CREDENTIALS_B64"), "base64").toString("utf8");
33
+ const credsPath = (0, import_node_path.join)(claudeDir, ".credentials.json");
34
+ (0, import_node_fs.writeFileSync)(credsPath, decoded);
35
+ (0, import_node_fs.chmodSync)(credsPath, 384);
36
+ const configPath = (0, import_node_path.join)(home, ".claude.json");
37
+ let cfg = {};
38
+ if ((0, import_node_fs.existsSync)(configPath)) {
39
+ try {
40
+ cfg = JSON.parse((0, import_node_fs.readFileSync)(configPath, "utf8"));
41
+ } catch {
42
+ cfg = {};
43
+ }
44
+ }
45
+ cfg.hasCompletedOnboarding = true;
46
+ cfg.lastOnboardingVersion = cfg.lastOnboardingVersion ?? "2.1.159";
47
+ cfg.numStartups = (cfg.numStartups ?? 0) + 1;
48
+ cfg.installMethod = cfg.installMethod ?? "global";
49
+ (0, import_node_fs.writeFileSync)(configPath, JSON.stringify(cfg, null, 2));
50
+ (0, import_node_fs.chmodSync)(configPath, 384);
51
+ }
52
+ function setupGitAndGh() {
53
+ const name = process.env.GIT_USER_NAME ?? "Radar Bot";
54
+ const email = process.env.GIT_USER_EMAIL ?? "radar@launchpod.local";
55
+ const status = run("launch-kit", ["setup-git", `--identity=${name} <${email}>`]);
56
+ if (status !== 0) fail(`[entrypoint] launch-kit setup-git failed (status ${status})`);
57
+ }
58
+ function initWorkspaceIfEmpty() {
59
+ process.chdir("/workspace");
60
+ if ((0, import_node_fs.existsSync)(".git")) {
61
+ console.log("[entrypoint] /workspace already initialized \u2014 skipping init");
62
+ return;
63
+ }
64
+ console.log("[entrypoint] /workspace is empty \u2014 running launch-kit init");
65
+ const status = run("launch-kit", [
66
+ "init",
67
+ `--token=${requireEnv("LS_PAT")}`,
68
+ `--org=${requireEnv("LS_ORG_SLUG")}`,
69
+ `--project=${requireEnv("LS_PROJECT_SLUG")}`,
70
+ `--url=${process.env.LS_SERVER_URL ?? "https://launchsecure-v2.vercel.app"}`,
71
+ `--dir=/workspace`
72
+ ]);
73
+ if (status !== 0) fail(`[entrypoint] launch-kit init failed (status ${status})`);
74
+ }
75
+ function execLaunchPodRadar() {
76
+ console.log("[entrypoint] starting launch-pod radar");
77
+ const child = (0, import_node_child_process.spawn)("launch-pod", ["radar"], { stdio: "inherit" });
78
+ const forward = (sig) => () => {
79
+ try {
80
+ child.kill(sig);
81
+ } catch {
82
+ }
83
+ };
84
+ process.on("SIGTERM", forward("SIGTERM"));
85
+ process.on("SIGINT", forward("SIGINT"));
86
+ process.on("SIGHUP", forward("SIGHUP"));
87
+ child.on("exit", (code, signal) => {
88
+ if (signal) process.kill(process.pid, signal);
89
+ else process.exit(code ?? 0);
90
+ });
91
+ }
92
+ function main() {
93
+ for (const k of REQUIRED_ENV) requireEnv(k);
94
+ setupClaudeCredentials();
95
+ setupGitAndGh();
96
+ initWorkspaceIfEmpty();
97
+ execLaunchPodRadar();
98
+ }
99
+ main();