koppler 0.0.0-stage → 0.0.1
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/LICENSE +21 -0
- package/README.md +101 -2
- package/bin/run-logged +16 -0
- package/bin/secret-list +7 -0
- package/bin/secret-psql +41 -0
- package/bin/secret-set +17 -0
- package/bin/secret-store +82 -0
- package/bin/secret-test +10 -0
- package/bin/with-secrets +25 -0
- package/dist/.built +1 -0
- package/dist/cli/agent.js +144 -0
- package/dist/cli/agent.js.map +1 -0
- package/dist/cli/doctor.js +173 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/mcp.js +204 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/output.js +37 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/records.js +121 -0
- package/dist/cli/records.js.map +1 -0
- package/dist/cli/running.js +270 -0
- package/dist/cli/running.js.map +1 -0
- package/dist/cli/shell.js +43 -0
- package/dist/cli/shell.js.map +1 -0
- package/dist/cli/wait.js +59 -0
- package/dist/cli/wait.js.map +1 -0
- package/dist/core/addresses.js +55 -0
- package/dist/core/addresses.js.map +1 -0
- package/dist/core/arrange.js +329 -0
- package/dist/core/arrange.js.map +1 -0
- package/dist/core/cables.js +158 -0
- package/dist/core/cables.js.map +1 -0
- package/dist/core/expressions.js +72 -0
- package/dist/core/expressions.js.map +1 -0
- package/dist/core/frameworks.js +13 -0
- package/dist/core/frameworks.js.map +1 -0
- package/dist/core/kinds.js +244 -0
- package/dist/core/kinds.js.map +1 -0
- package/dist/core/launch.js +181 -0
- package/dist/core/launch.js.map +1 -0
- package/dist/core/logfmt.js +144 -0
- package/dist/core/logfmt.js.map +1 -0
- package/dist/core/mock.js +27 -0
- package/dist/core/mock.js.map +1 -0
- package/dist/core/plan.js +147 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/core/ports.js +155 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/presets.js +186 -0
- package/dist/core/presets.js.map +1 -0
- package/dist/core/secret-types.js +3 -0
- package/dist/core/secret-types.js.map +1 -0
- package/dist/core/sign-in.js +30 -0
- package/dist/core/sign-in.js.map +1 -0
- package/dist/core/stack-path.js +64 -0
- package/dist/core/stack-path.js.map +1 -0
- package/dist/core/stack.js +509 -0
- package/dist/core/stack.js.map +1 -0
- package/dist/core/terraform.js +393 -0
- package/dist/core/terraform.js.map +1 -0
- package/dist/data.js +37 -0
- package/dist/data.js.map +1 -0
- package/dist/engine/actions.js +99 -0
- package/dist/engine/actions.js.map +1 -0
- package/dist/engine/app-commands.js +106 -0
- package/dist/engine/app-commands.js.map +1 -0
- package/dist/engine/app-start.js +167 -0
- package/dist/engine/app-start.js.map +1 -0
- package/dist/engine/app-state.js +43 -0
- package/dist/engine/app-state.js.map +1 -0
- package/dist/engine/boards.js +219 -0
- package/dist/engine/boards.js.map +1 -0
- package/dist/engine/branch.js +194 -0
- package/dist/engine/branch.js.map +1 -0
- package/dist/engine/browser-console.js +45 -0
- package/dist/engine/browser-console.js.map +1 -0
- package/dist/engine/calls.js +97 -0
- package/dist/engine/calls.js.map +1 -0
- package/dist/engine/checks.js +270 -0
- package/dist/engine/checks.js.map +1 -0
- package/dist/engine/clones.js +67 -0
- package/dist/engine/clones.js.map +1 -0
- package/dist/engine/config.js +26 -0
- package/dist/engine/config.js.map +1 -0
- package/dist/engine/deployed.js +488 -0
- package/dist/engine/deployed.js.map +1 -0
- package/dist/engine/devices.js +81 -0
- package/dist/engine/devices.js.map +1 -0
- package/dist/engine/discover.js +236 -0
- package/dist/engine/discover.js.map +1 -0
- package/dist/engine/down.js +253 -0
- package/dist/engine/down.js.map +1 -0
- package/dist/engine/history.js +215 -0
- package/dist/engine/history.js.map +1 -0
- package/dist/engine/investigate.js +278 -0
- package/dist/engine/investigate.js.map +1 -0
- package/dist/engine/libraries.js +129 -0
- package/dist/engine/libraries.js.map +1 -0
- package/dist/engine/linked.js +146 -0
- package/dist/engine/linked.js.map +1 -0
- package/dist/engine/listen.js +223 -0
- package/dist/engine/listen.js.map +1 -0
- package/dist/engine/locks.js +38 -0
- package/dist/engine/locks.js.map +1 -0
- package/dist/engine/messages.js +177 -0
- package/dist/engine/messages.js.map +1 -0
- package/dist/engine/needs.js +363 -0
- package/dist/engine/needs.js.map +1 -0
- package/dist/engine/processes.js +350 -0
- package/dist/engine/processes.js.map +1 -0
- package/dist/engine/query.js +241 -0
- package/dist/engine/query.js.map +1 -0
- package/dist/engine/queues.js +100 -0
- package/dist/engine/queues.js.map +1 -0
- package/dist/engine/recipes.js +248 -0
- package/dist/engine/recipes.js.map +1 -0
- package/dist/engine/reload.js +32 -0
- package/dist/engine/reload.js.map +1 -0
- package/dist/engine/repos.js +214 -0
- package/dist/engine/repos.js.map +1 -0
- package/dist/engine/research.js +134 -0
- package/dist/engine/research.js.map +1 -0
- package/dist/engine/run-logs.js +79 -0
- package/dist/engine/run-logs.js.map +1 -0
- package/dist/engine/run.js +54 -0
- package/dist/engine/run.js.map +1 -0
- package/dist/engine/runs.js +223 -0
- package/dist/engine/runs.js.map +1 -0
- package/dist/engine/session.js +130 -0
- package/dist/engine/session.js.map +1 -0
- package/dist/engine/share.js +124 -0
- package/dist/engine/share.js.map +1 -0
- package/dist/engine/stack-file.js +206 -0
- package/dist/engine/stack-file.js.map +1 -0
- package/dist/engine/stack-share.js +86 -0
- package/dist/engine/stack-share.js.map +1 -0
- package/dist/engine/stacks.js +143 -0
- package/dist/engine/stacks.js.map +1 -0
- package/dist/engine/sync.js +214 -0
- package/dist/engine/sync.js.map +1 -0
- package/dist/engine/traces.js +65 -0
- package/dist/engine/traces.js.map +1 -0
- package/dist/engine/up.js +621 -0
- package/dist/engine/up.js.map +1 -0
- package/dist/engine/watch.js +71 -0
- package/dist/engine/watch.js.map +1 -0
- package/dist/engine/wire.js +120 -0
- package/dist/engine/wire.js.map +1 -0
- package/dist/failure.js +16 -0
- package/dist/failure.js.map +1 -0
- package/dist/github.js +95 -0
- package/dist/github.js.map +1 -0
- package/dist/ids.js +6 -0
- package/dist/ids.js.map +1 -0
- package/dist/json-files.js +36 -0
- package/dist/json-files.js.map +1 -0
- package/dist/koppler.mjs +840 -0
- package/dist/koppler.mjs.map +1 -0
- package/dist/lambda-local.mjs +250 -0
- package/dist/lambda-local.mjs.map +1 -0
- package/dist/lambda-secrets-proxy.go +31 -0
- package/dist/mock-server.mjs +23 -0
- package/dist/mock-server.mjs.map +1 -0
- package/dist/page/assets/JetBrainsMono-cyrillic-D2jMJ_bk.woff2 +0 -0
- package/dist/page/assets/JetBrainsMono-greek-D2nYnAec.woff2 +0 -0
- package/dist/page/assets/JetBrainsMono-latin-Db4Uuiha.woff2 +0 -0
- package/dist/page/assets/JetBrainsMono-latin-ext-Bnd2h4Br.woff2 +0 -0
- package/dist/page/assets/JetBrainsMono-vietnamese-CNlsqbWb.woff2 +0 -0
- package/dist/page/assets/SchibstedGrotesk-latin-DxefFeRw.woff2 +0 -0
- package/dist/page/assets/SchibstedGrotesk-latin-ext-CnpJE18X.woff2 +0 -0
- package/dist/page/assets/index-Bkj_pX35.js +42 -0
- package/dist/page/assets/index-Dq45jswH.css +1 -0
- package/dist/page/index.html +14 -0
- package/dist/page/theme.js +8 -0
- package/dist/paths.js +19 -0
- package/dist/paths.js.map +1 -0
- package/dist/safe-env.js +73 -0
- package/dist/safe-env.js.map +1 -0
- package/dist/sam-local.mjs +135 -0
- package/dist/sam-local.mjs.map +1 -0
- package/dist/scrub.js +87 -0
- package/dist/scrub.js.map +1 -0
- package/dist/secret-check.mjs +262 -0
- package/dist/secret-check.mjs.map +1 -0
- package/dist/server/browser-console.js +117 -0
- package/dist/server/browser-console.js.map +1 -0
- package/dist/server/cable-test.js +365 -0
- package/dist/server/cable-test.js.map +1 -0
- package/dist/server/choices.js +51 -0
- package/dist/server/choices.js.map +1 -0
- package/dist/server/files.js +107 -0
- package/dist/server/files.js.map +1 -0
- package/dist/server/gate.js +128 -0
- package/dist/server/gate.js.map +1 -0
- package/dist/server/logs.js +76 -0
- package/dist/server/logs.js.map +1 -0
- package/dist/server/mobile.js +113 -0
- package/dist/server/mobile.js.map +1 -0
- package/dist/server/routes.js +326 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/server/runs.js +111 -0
- package/dist/server/runs.js.map +1 -0
- package/dist/server/sanitize.js +242 -0
- package/dist/server/sanitize.js.map +1 -0
- package/dist/server/secrets.js +111 -0
- package/dist/server/secrets.js.map +1 -0
- package/dist/server/status.js +321 -0
- package/dist/server/status.js.map +1 -0
- package/dist/server/token.js +38 -0
- package/dist/server/token.js.map +1 -0
- package/dist/server/waiting.js +79 -0
- package/dist/server/waiting.js.map +1 -0
- package/dist/status-watch.mjs +63 -0
- package/dist/status-watch.mjs.map +1 -0
- package/package.json +73 -4
- package/skills/koppler-run/SKILL.md +169 -0
- package/skills/koppler-run/VERSION +1 -0
- package/skills/koppler-run/references/action-log.md +50 -0
- package/skills/koppler-run/references/permissions.md +25 -0
- package/skills/koppler-run/references/preparing-nodes.md +62 -0
- package/skills/koppler-run/references/reporting-bugs.md +76 -0
- package/skills/koppler-run/references/research.md +40 -0
- package/skills/koppler-run/references/secrets.md +56 -0
- package/skills/koppler-run/references/stack.md +197 -0
- package/skills/koppler-run/references/status.md +92 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// The commands about what Koppler runs: stop, the canvas, logs and status.
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { readClones, readData, readStack } from "../data.js";
|
|
7
|
+
import { alive, listener, NAME, readRecord, records, sh, sleep, stopOne, uptime } from "../engine/processes.js";
|
|
8
|
+
import { run } from "../engine/run.js";
|
|
9
|
+
import { appendNote, live } from "../engine/history.js";
|
|
10
|
+
import { runLog } from "../engine/run-logs.js";
|
|
11
|
+
import { CODE, logsDir, tempDir } from "../paths.js";
|
|
12
|
+
import { redact, scrub } from "../scrub.js";
|
|
13
|
+
import { confirm, flagValue, positional, table } from "./output.js";
|
|
14
|
+
import { fail } from "../failure.js";
|
|
15
|
+
import { newToken } from "../server/token.js";
|
|
16
|
+
const notAName = (name) => `${name} is not a name Koppler gives its processes`;
|
|
17
|
+
export async function stop(args) {
|
|
18
|
+
// --all: every app, API and tunnel Koppler runs, but not the canvas; code changes and branches stay as they are.
|
|
19
|
+
const all = args.includes('--all');
|
|
20
|
+
const names = args.filter(arg => !arg.startsWith('-'));
|
|
21
|
+
if (!all && !names.length)
|
|
22
|
+
fail('usage: koppler stop <name...> | --all [--yes]');
|
|
23
|
+
for (const name of names)
|
|
24
|
+
if (!NAME.test(name))
|
|
25
|
+
fail(notAName(name));
|
|
26
|
+
const targets = all
|
|
27
|
+
? records().filter(record => record.name !== 'canvas')
|
|
28
|
+
: names.map(name => readRecord(name) ?? fail(`${name} is not started by koppler`));
|
|
29
|
+
if (!targets.length) {
|
|
30
|
+
console.log('nothing to stop');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const asked = `Stop ${targets.map(record => record.name).join(', ')}?`;
|
|
34
|
+
if (all && !(await confirm(asked, args)))
|
|
35
|
+
fail('nothing stopped (in a script, add --yes)');
|
|
36
|
+
for (const line of await Promise.all(targets.map(stopOne)))
|
|
37
|
+
console.log(line);
|
|
38
|
+
// Stopping in bulk is not a run, so the history gets a note of it: later it says why nothing runs any more.
|
|
39
|
+
const stopped = targets.map(record => record.name);
|
|
40
|
+
if (all)
|
|
41
|
+
appendNote('stop-apps', stopped);
|
|
42
|
+
}
|
|
43
|
+
/** The canvas: started when it is not running, then opened in the browser. */
|
|
44
|
+
export async function canvas(args) {
|
|
45
|
+
if (args[0] === 'stop') {
|
|
46
|
+
await stop(['canvas']);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const record = readRecord('canvas');
|
|
50
|
+
const urlFile = path.join(tempDir(), 'canvas-url');
|
|
51
|
+
// A new address: a running canvas switches to it, so every address given out before stops working.
|
|
52
|
+
if (args.includes('--new-address')) {
|
|
53
|
+
if (record && alive(record)) {
|
|
54
|
+
const old = new URL(fs.readFileSync(urlFile, 'utf8').trim());
|
|
55
|
+
const token = old.pathname.split('/')[2] ?? '';
|
|
56
|
+
const answer = await fetch(`${old.origin}/new-address?token=${encodeURIComponent(token)}`, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: { 'content-type': 'application/json' },
|
|
59
|
+
body: JSON.stringify({ port: old.port }),
|
|
60
|
+
}).catch(() => null);
|
|
61
|
+
if (!answer?.ok)
|
|
62
|
+
fail('the canvas did not take a new address; koppler canvas stop, then koppler canvas --new-address');
|
|
63
|
+
}
|
|
64
|
+
else
|
|
65
|
+
newToken();
|
|
66
|
+
console.log('The canvas has a new address; every address given out before no longer works.');
|
|
67
|
+
}
|
|
68
|
+
if (!record || !alive(record)) {
|
|
69
|
+
const port = String(Number(process.env['KOPPLER_PORT']) || 4747);
|
|
70
|
+
await run(['canvas', '--port', port, '--', process.execPath, path.join(CODE, 'status-watch.mjs')]);
|
|
71
|
+
}
|
|
72
|
+
for (let tries = 0; tries < 40 && !fs.existsSync(urlFile); tries++)
|
|
73
|
+
await sleep(250);
|
|
74
|
+
if (!fs.existsSync(urlFile))
|
|
75
|
+
fail('the canvas did not start; see koppler logs canvas');
|
|
76
|
+
// The address carries the page's access token, so it goes to the browser and is not printed.
|
|
77
|
+
const board = flagValue(args, '--board');
|
|
78
|
+
const hash = args.includes('--pick') ? '#pick' : board ? `#board=${encodeURIComponent(board)}` : '';
|
|
79
|
+
const url = fs.readFileSync(urlFile, 'utf8').trim() + hash;
|
|
80
|
+
if (args.includes('--no-open') || process.platform !== 'darwin') {
|
|
81
|
+
console.log(`The canvas runs on port ${new URL(url).port}; its address is in ${urlFile}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
sh('open', [url]);
|
|
85
|
+
console.log('The canvas is open in your browser.');
|
|
86
|
+
}
|
|
87
|
+
/** A log, with secrets masked as on the card; `-f` follows it. */
|
|
88
|
+
export function logs(args) {
|
|
89
|
+
const [want] = positional(args, ['-n', '--run']);
|
|
90
|
+
const lines = Number(flagValue(args, '-n')) || 50;
|
|
91
|
+
if (!want)
|
|
92
|
+
fail('usage: koppler logs <name> [-f] [-n <lines>] [--run <id>]');
|
|
93
|
+
if (!NAME.test(want))
|
|
94
|
+
fail(notAName(want));
|
|
95
|
+
const run = flagValue(args, '--run');
|
|
96
|
+
const kept = run ? runLog(run, want) : null;
|
|
97
|
+
if (run && !kept)
|
|
98
|
+
fail(`${run} is not a run id; koppler history lists them`);
|
|
99
|
+
const file = kept ?? path.join(logsDir(), `${want}.log`);
|
|
100
|
+
if (!fs.existsSync(file))
|
|
101
|
+
fail(run ? `run ${run} kept no log of ${want}` : `no log for ${want}; koppler status lists what runs`);
|
|
102
|
+
const last = fs.readFileSync(file, 'utf8').trimEnd().split('\n').slice(-lines);
|
|
103
|
+
process.stdout.write(redact(last.join('\n')) + '\n');
|
|
104
|
+
if (!args.includes('-f') && !args.includes('--follow'))
|
|
105
|
+
return;
|
|
106
|
+
let at = fs.statSync(file).size;
|
|
107
|
+
// Shown a whole line at a time: a secret is masked by the name before it, which may come in an earlier read.
|
|
108
|
+
let held = Buffer.alloc(0);
|
|
109
|
+
fs.watchFile(file, { interval: 500 }, now => {
|
|
110
|
+
if (now.size < at)
|
|
111
|
+
at = 0;
|
|
112
|
+
if (now.size === at)
|
|
113
|
+
return;
|
|
114
|
+
const fd = fs.openSync(file, 'r');
|
|
115
|
+
const added = Buffer.alloc(now.size - at);
|
|
116
|
+
fs.readSync(fd, added, 0, added.length, at);
|
|
117
|
+
fs.closeSync(fd);
|
|
118
|
+
at = now.size;
|
|
119
|
+
const all = Buffer.concat([held, added]);
|
|
120
|
+
const end = all.lastIndexOf(10) + 1;
|
|
121
|
+
held = all.subarray(end);
|
|
122
|
+
if (end)
|
|
123
|
+
process.stdout.write(redact(all.subarray(0, end).toString('utf8')));
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const tail = (file, lines) => {
|
|
127
|
+
try {
|
|
128
|
+
return fs.readFileSync(file, 'utf8').trimEnd().split('\n').slice(-lines).join('\n');
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const read = (file) => {
|
|
135
|
+
try {
|
|
136
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const newestRunLog = () => {
|
|
143
|
+
try {
|
|
144
|
+
const logs = fs.readdirSync(tempDir()).filter(file => /^up-.*\.log$/.test(file));
|
|
145
|
+
const age = (file) => fs.statSync(path.join(tempDir(), file)).mtimeMs;
|
|
146
|
+
const [newest] = logs.sort((a, b) => age(b) - age(a));
|
|
147
|
+
return newest ? path.join(tempDir(), newest) : null;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
/** A board's name says nothing about a bug and may name a project, even one no stack lists any more. */
|
|
154
|
+
const unnamed = (line) => {
|
|
155
|
+
try {
|
|
156
|
+
const entry = JSON.parse(line);
|
|
157
|
+
if (entry.board?.name)
|
|
158
|
+
entry.board.name = 'board';
|
|
159
|
+
return JSON.stringify(entry);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return line;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* What a bug report needs, ready to paste into a public issue: versions, then the tails of the canvas debug log, the
|
|
167
|
+
* latest run log and each named log, all scrubbed of secrets and of everything that names the user or their stack.
|
|
168
|
+
*/
|
|
169
|
+
async function debugReport(names) {
|
|
170
|
+
const { stacksHere } = await import("../engine/stacks.js");
|
|
171
|
+
const stacks = stacksHere().map(stack => read(path.join(stack.dir, 'stack.json')));
|
|
172
|
+
let commit = null;
|
|
173
|
+
try {
|
|
174
|
+
const git = ['-C', CODE, 'rev-parse', '--short', 'HEAD'];
|
|
175
|
+
commit = execFileSync('git', git, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// An installed copy is not a clone.
|
|
179
|
+
}
|
|
180
|
+
const parts = [`Koppler ${commit ?? 'installed copy'}, Node ${process.version}, ${os.type()} ${os.release()}`];
|
|
181
|
+
const add = (title, text) => {
|
|
182
|
+
if (text)
|
|
183
|
+
parts.push(`## ${title}\n\n\`\`\`text\n${text}\n\`\`\``);
|
|
184
|
+
};
|
|
185
|
+
add('Canvas debug log', tail(path.join(tempDir(), 'debug.jsonl'), 40)?.split('\n').map(unnamed).join('\n'));
|
|
186
|
+
const runLog = newestRunLog();
|
|
187
|
+
add(`Latest run (${runLog ? path.basename(runLog) : ''})`, runLog && tail(runLog, 60));
|
|
188
|
+
for (const name of names)
|
|
189
|
+
add(`${name} log`, NAME.test(name) ? (tail(path.join(logsDir(), `${name}.log`), 80) ?? 'no log') : 'not a log name');
|
|
190
|
+
console.log(scrub(parts.join('\n\n'), [readData('registry'), readData('state'), ...stacks]));
|
|
191
|
+
}
|
|
192
|
+
/** What runs; --apps adds every app in the stack with its clone; --debug is for a bug report. */
|
|
193
|
+
export async function status(args = []) {
|
|
194
|
+
if (args.includes('--debug')) {
|
|
195
|
+
await debugReport(positional(args));
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const { processState, stateOf } = await import("../engine/app-state.js");
|
|
199
|
+
const processes = records().map(record => {
|
|
200
|
+
const up = alive(record);
|
|
201
|
+
return {
|
|
202
|
+
name: record.name,
|
|
203
|
+
state: up ? 'running' : 'exited',
|
|
204
|
+
pid: record.pid,
|
|
205
|
+
up: up ? uptime(record.startedAt) : null,
|
|
206
|
+
port: record.port ?? null,
|
|
207
|
+
open: !!(record.port && up && listener(record.port, record.bind)),
|
|
208
|
+
command: record.command,
|
|
209
|
+
};
|
|
210
|
+
});
|
|
211
|
+
const stack = args.includes('--apps') ? (readStack() ?? fail('no stack loaded (koppler init)')) : null;
|
|
212
|
+
const clones = readClones();
|
|
213
|
+
const apps = stack &&
|
|
214
|
+
Object.entries(stack.apps).map(([id, app]) => {
|
|
215
|
+
const clone = clones[id];
|
|
216
|
+
return {
|
|
217
|
+
id,
|
|
218
|
+
name: app.name,
|
|
219
|
+
kind: app.kind,
|
|
220
|
+
clone: clone ? { branch: clone.branch ?? null, changed: clone.dirty ?? 0 } : null,
|
|
221
|
+
state: processes.find(one => one.name === id)?.state ?? null,
|
|
222
|
+
};
|
|
223
|
+
});
|
|
224
|
+
if (args.includes('--json')) {
|
|
225
|
+
const steps = read(path.join(tempDir(), 'progress.json'))?.apps ?? {};
|
|
226
|
+
const detailed = await Promise.all(processes.map(async (one) => ({ ...one, status: stateOf(await processState(one.name), steps[one.name]) })));
|
|
227
|
+
let missing = {};
|
|
228
|
+
if (stack) {
|
|
229
|
+
const { secretsStatus } = await import("../server/secrets.js");
|
|
230
|
+
const env = live()?.env ?? stack.envs[0] ?? '';
|
|
231
|
+
const declared = await secretsStatus().catch(() => ({}));
|
|
232
|
+
missing = Object.fromEntries(Object.entries(declared).map(([id, envs]) => [
|
|
233
|
+
id,
|
|
234
|
+
(envs[env] ?? []).filter(secret => !secret.stored).map(secret => secret.name),
|
|
235
|
+
]));
|
|
236
|
+
}
|
|
237
|
+
const withState = await Promise.all((apps ?? []).map(async (app) => ({
|
|
238
|
+
...app,
|
|
239
|
+
status: stateOf(await processState(app.id), steps[app.id], missing[app.id]),
|
|
240
|
+
})));
|
|
241
|
+
console.log(JSON.stringify({ processes: detailed, ...(apps && { stack: stack.name ?? null, apps: withState }) }, null, 2));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (stack && apps) {
|
|
245
|
+
console.log(`${stack.name ?? 'stack'}: ${stack.source ?? ''}`);
|
|
246
|
+
const cloneOf = ({ clone }) => clone ? `${clone.branch ?? 'detached'}${clone.changed ? ` (${String(clone.changed)} changed)` : ''}` : 'missing';
|
|
247
|
+
table([
|
|
248
|
+
['APP', 'NAME', 'KIND', 'CLONE', 'KOPPLER'],
|
|
249
|
+
...apps.map(app => [app.id, app.name, app.kind, cloneOf(app), app.state ?? '-']),
|
|
250
|
+
]);
|
|
251
|
+
console.log('');
|
|
252
|
+
}
|
|
253
|
+
if (!processes.length) {
|
|
254
|
+
console.log('nothing started by koppler');
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const short = (command) => (command.length > 70 ? command.slice(0, 67) + '...' : command);
|
|
258
|
+
table([
|
|
259
|
+
['NAME', 'STATE', 'PID', 'UP', 'PORT', 'COMMAND'],
|
|
260
|
+
...processes.map(one => [
|
|
261
|
+
one.name,
|
|
262
|
+
one.state,
|
|
263
|
+
one.pid,
|
|
264
|
+
one.up ?? '-',
|
|
265
|
+
one.port ? `${String(one.port)} ${one.open ? 'open' : 'closed'}` : '-',
|
|
266
|
+
short(one.command),
|
|
267
|
+
]),
|
|
268
|
+
]);
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=running.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"running.js","sourceRoot":"","sources":["../../src/cli/running.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// `koppler shell <app>`: a shell in the app's clone with the settings its run starts it with (where the apps it calls
|
|
2
|
+
// answer), never its secrets. `--query` opens psql on its database instead, through the stored connection.
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { appOn, storeOf } from "../core/stack.js";
|
|
6
|
+
import { readClones, readStack } from "../data.js";
|
|
7
|
+
import { live } from "../engine/history.js";
|
|
8
|
+
import { readRecord } from "../engine/processes.js";
|
|
9
|
+
import { fail } from "../failure.js";
|
|
10
|
+
import { CODE } from "../paths.js";
|
|
11
|
+
import { flagValue, positional } from "./output.js";
|
|
12
|
+
const USAGE = 'usage: koppler shell <app> [--env <env>] [--query]';
|
|
13
|
+
export function shellCommand(args) {
|
|
14
|
+
const [id = ''] = positional(args, ['--env']);
|
|
15
|
+
const stack = readStack() ?? fail('no stack loaded (koppler init)');
|
|
16
|
+
const app = (Object.hasOwn(stack.apps, id) ? stack.apps[id] : undefined) ?? fail(USAGE);
|
|
17
|
+
const env = flagValue(args, '--env') ?? live()?.env ?? stack.envs[0] ?? '';
|
|
18
|
+
if (!stack.envs.includes(env))
|
|
19
|
+
fail(`unknown env ${env}; the stack has ${stack.envs.join(', ')}`);
|
|
20
|
+
if (args.includes('--query')) {
|
|
21
|
+
const secret = (appOn(stack, id, env)?.secrets ?? []).find(one => one.env && one.type === 'postgres');
|
|
22
|
+
if (!secret?.env)
|
|
23
|
+
fail(`${app.name} has no Postgres connection among its secrets on ${env.toUpperCase()}; for one query: koppler query ${id} --env ${env} "<sql>"`);
|
|
24
|
+
const store = storeOf(stack, id, env);
|
|
25
|
+
const ran = spawnSync(process.execPath, [path.join(CODE, 'koppler.mjs'), 'secret', 'psql', store, secret.env], {
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
});
|
|
28
|
+
process.exit(ran.status ?? 1);
|
|
29
|
+
}
|
|
30
|
+
const repo = readClones()[id]?.path ?? fail(`${id} is not cloned (koppler sync --rescan after cloning)`);
|
|
31
|
+
// Only what the run gave it beside its own environment: the addresses of what it calls, never a stored value.
|
|
32
|
+
const given = readRecord(id)?.start?.setEnv ?? {};
|
|
33
|
+
const names = Object.keys(given);
|
|
34
|
+
console.log(`${app.name}, in ${repo}${names.length ? `, with ${names.join(', ')} as its run sets them` : ''}. Its secrets are not here. Type exit to leave.`);
|
|
35
|
+
const shell = process.env['SHELL'] || '/bin/sh';
|
|
36
|
+
const ran = spawnSync(shell, ['-i'], {
|
|
37
|
+
cwd: repo,
|
|
38
|
+
stdio: 'inherit',
|
|
39
|
+
env: { ...process.env, ...given, KOPPLER_APP: id, KOPPLER_ENV: env },
|
|
40
|
+
});
|
|
41
|
+
process.exit(ran.status ?? 0);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/cli/shell.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/wait.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// `koppler wait`: blocks until apps Koppler runs are up, healthy or down, for agents and scripts.
|
|
2
|
+
import { processState } from "../engine/app-state.js";
|
|
3
|
+
import { NAME, readRecord, sleep, tailOf } from "../engine/processes.js";
|
|
4
|
+
import { fail } from "../failure.js";
|
|
5
|
+
import { flagValue, positional } from "./output.js";
|
|
6
|
+
const USAGE = 'usage: koppler wait <app...> --healthy|--up|--down [--timeout <seconds>] [--json]';
|
|
7
|
+
const GOALS = ['healthy', 'up', 'down'];
|
|
8
|
+
const waitState = async (name) => {
|
|
9
|
+
const now = await processState(name);
|
|
10
|
+
return now?.state ?? 'not started';
|
|
11
|
+
};
|
|
12
|
+
const met = (goal, state) => goal === 'down'
|
|
13
|
+
? state === 'not started' || state === 'exited'
|
|
14
|
+
: goal === 'up'
|
|
15
|
+
? state !== 'not started' && state !== 'exited'
|
|
16
|
+
: state === 'running';
|
|
17
|
+
/** Waits for every named app to reach the goal; exits 1 on a timeout or an app that exits, naming each app's state. */
|
|
18
|
+
export async function wait(args) {
|
|
19
|
+
const goals = GOALS.filter(goal => args.includes(`--${goal}`));
|
|
20
|
+
const [goal] = goals;
|
|
21
|
+
const names = positional(args, ['--timeout']);
|
|
22
|
+
if (!goal || goals.length > 1 || !names.length)
|
|
23
|
+
fail(USAGE);
|
|
24
|
+
for (const name of names)
|
|
25
|
+
if (!NAME.test(name))
|
|
26
|
+
fail(`${name} is not an app or process name`);
|
|
27
|
+
const seconds = Number(flagValue(args, '--timeout') ?? 120);
|
|
28
|
+
if (!Number.isFinite(seconds) || seconds <= 0)
|
|
29
|
+
fail(`--timeout takes seconds, more than 0 (${USAGE})`);
|
|
30
|
+
const until = Date.now() + seconds * 1000;
|
|
31
|
+
let states = [];
|
|
32
|
+
let why = '';
|
|
33
|
+
for (;;) {
|
|
34
|
+
states = await Promise.all(names.map(async (name) => [name, await waitState(name)]));
|
|
35
|
+
if (states.every(([, state]) => met(goal, state)))
|
|
36
|
+
break;
|
|
37
|
+
const gone = goal !== 'down' && states.find(([, state]) => state === 'exited');
|
|
38
|
+
if (gone) {
|
|
39
|
+
why = `${gone[0]} exited`;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
if (Date.now() >= until) {
|
|
43
|
+
why = `timed out after ${String(seconds)}s`;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
await sleep(500);
|
|
47
|
+
}
|
|
48
|
+
if (args.includes('--json'))
|
|
49
|
+
console.log(JSON.stringify({ goal, met: !why, why: why || null, apps: Object.fromEntries(states) }));
|
|
50
|
+
else
|
|
51
|
+
for (const [name, state] of states)
|
|
52
|
+
console.log(`${name}: ${state}`);
|
|
53
|
+
if (!why)
|
|
54
|
+
return;
|
|
55
|
+
const exited = states.find(([, state]) => state === 'exited' && goal !== 'down');
|
|
56
|
+
const record = exited && readRecord(exited[0]);
|
|
57
|
+
fail(`not ${goal}: ${why}${record ? `; last lines of ${record.log}:\n${tailOf(record.log, 15)}` : ''}`);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=wait.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../../src/cli/wait.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host a device uses to reach this machine: the iOS simulator shares its network, the Android emulator sees it as
|
|
3
|
+
* 10.0.2.2, and a real phone reaches it over Wi-Fi at the machine's network address (null when it has none).
|
|
4
|
+
*/
|
|
5
|
+
export function deviceHost(device, lanIp) {
|
|
6
|
+
if (!device || (device.platform === 'ios' && !device.physical))
|
|
7
|
+
return 'localhost';
|
|
8
|
+
if (device.platform === 'android' && !device.physical)
|
|
9
|
+
return '10.0.2.2';
|
|
10
|
+
return lanIp ?? null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The address a caller on `device` uses for a local callee. A phone cannot trust this machine's development
|
|
14
|
+
* certificate, so it gets the callee's plain http address, and the callee has to listen on the network.
|
|
15
|
+
*/
|
|
16
|
+
export function localAddress(callee, device, options = {}) {
|
|
17
|
+
const phone = !!device?.physical;
|
|
18
|
+
const base = phone && options.httpUrl ? options.httpUrl : callee.url;
|
|
19
|
+
if (!base)
|
|
20
|
+
return { error: 'the callee has no url in stack.json' };
|
|
21
|
+
const host = deviceHost(device, options.lanIp);
|
|
22
|
+
if (!host)
|
|
23
|
+
return { error: "no network address for this Mac; connect to Wi-Fi, or pass the phone's reachable host" };
|
|
24
|
+
const address = new URL(base);
|
|
25
|
+
address.hostname = host;
|
|
26
|
+
const slash = (options.like ?? callee.url ?? '').endsWith('/');
|
|
27
|
+
const url = slash ? address.toString() : address.toString().replace(/\/$/, '');
|
|
28
|
+
const untrusted = phone && !options.httpUrl && address.protocol === 'https:';
|
|
29
|
+
const note = untrusted
|
|
30
|
+
? 'the callee has no http address; a phone will reject its development certificate'
|
|
31
|
+
: undefined;
|
|
32
|
+
return { url, needsLan: phone, note };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* What a browser front end needs from an API it calls locally: its own origin allowed (CORS), and no https page
|
|
36
|
+
* calling http. `slot` numbers each browser caller of the same API, for settings written as `Origins__{n}`.
|
|
37
|
+
*/
|
|
38
|
+
export function browserChecks(callee, callerUrl, slot = 0) {
|
|
39
|
+
const origin = callerUrl && URL.canParse(callerUrl) ? new URL(callerUrl).origin : null;
|
|
40
|
+
const out = { settings: [], warnings: [] };
|
|
41
|
+
const allow = callee.cors?.env;
|
|
42
|
+
if (allow && origin)
|
|
43
|
+
for (const env of [allow].flat())
|
|
44
|
+
out.settings.push({ app: 'callee', env: env.replace('{n}', String(slot)), value: origin });
|
|
45
|
+
else if (origin)
|
|
46
|
+
out.warnings.push(`${callee.name ?? 'the API'} has no recorded CORS setting; the browser may block calls from ${origin}. Record it with: koppler stack set apps.<app>.cors.env <setting>`);
|
|
47
|
+
if (callerUrl?.startsWith('https:') && callee.url?.startsWith('http:'))
|
|
48
|
+
out.warnings.push("an https page cannot call an http API; use the API's https address or serve the page over http");
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
/** The lines to put in a git-ignored local env file, which the framework reads on top of its .env. */
|
|
52
|
+
export function envFileChange(call, value) {
|
|
53
|
+
return { file: call.file ?? '.env.local', lines: [call.env ?? []].flat().map(name => `${name}=${value}`) };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=addresses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addresses.js","sourceRoot":"","sources":["../../src/core/addresses.ts"],"names":[],"mappings":"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"}
|