koppler 0.0.0-stage → 0.0.2
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 +74 -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 @@
|
|
|
1
|
+
{"version":3,"file":"repos.js","sourceRoot":"","sources":["../../src/engine/repos.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Finding the repos behind the names in a description ("the wallet API", "push notification service"): the stack first,
|
|
2
|
+
// then the clones on this Mac (koppler init's index), then GitHub in the user's own organisations through their gh login.
|
|
3
|
+
// Several candidates or none is a question for the user, never a guess; nothing is cloned here.
|
|
4
|
+
// Usage: koppler discover --find "<name> [<name>...]" [--json] [--no-github]
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import os from 'node:os';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { readStack } from "../data.js";
|
|
9
|
+
import { Failure } from "../failure.js";
|
|
10
|
+
import { gh } from "../github.js";
|
|
11
|
+
import { configDir } from "../paths.js";
|
|
12
|
+
const readIndex = () => {
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(fs.readFileSync(path.join(configDir(), 'repos.json'), 'utf8'));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const FILLER = ['the', 'a', 'an', 'api', 'app', 'service', 'svc'];
|
|
21
|
+
/**
|
|
22
|
+
* "PushNotification-Service" and "push notification service" both become push / notification / service.
|
|
23
|
+
* Plurals count as the word ("notifications" finds "notification").
|
|
24
|
+
*/
|
|
25
|
+
export const words = (text) => text
|
|
26
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
27
|
+
.toLowerCase()
|
|
28
|
+
.split(/[^a-z0-9]+/)
|
|
29
|
+
.filter(word => word && !FILLER.includes(word))
|
|
30
|
+
.map(word => (word.length > 3 ? word.replace(/(?<!s)s$/, '') : word));
|
|
31
|
+
/**
|
|
32
|
+
* How well a repo name or app name matches: the share of the asked words it contains ("pushnotifications" has both
|
|
33
|
+
* push and notification), with a small bonus for words standing on their own.
|
|
34
|
+
*/
|
|
35
|
+
export function score(asked, candidate) {
|
|
36
|
+
const want = words(asked);
|
|
37
|
+
const have = words(candidate);
|
|
38
|
+
const joined = have.join('');
|
|
39
|
+
if (!want.length)
|
|
40
|
+
return 0;
|
|
41
|
+
const hits = want.filter(word => have.includes(word) || joined.includes(word)).length;
|
|
42
|
+
const whole = want.filter(word => have.includes(word)).length;
|
|
43
|
+
return Math.min(1, hits / want.length + (0.1 * whole) / want.length);
|
|
44
|
+
}
|
|
45
|
+
const slugOf = (key) => key
|
|
46
|
+
.replace(/^[^/]+\//, '')
|
|
47
|
+
.replace(/\.git$/, '')
|
|
48
|
+
.toLowerCase();
|
|
49
|
+
export async function find(names, { registry: stack, index = readIndex(), github = true, } = {}) {
|
|
50
|
+
const apps = Object.entries(stack?.apps ?? {});
|
|
51
|
+
const clones = (index?.repos ?? []).flatMap(repo => {
|
|
52
|
+
const [key] = repo.keys ?? [];
|
|
53
|
+
return key && fs.existsSync(repo.path) ? [{ path: repo.path, slug: slugOf(key) }] : [];
|
|
54
|
+
});
|
|
55
|
+
const orgs = [...new Set(clones.map(clone => clone.slug.split('/')[0] ?? ''))].slice(0, 5);
|
|
56
|
+
const out = [];
|
|
57
|
+
for (const name of names) {
|
|
58
|
+
// One entry per repo, whatever the case of its owner's name; the stack and a clone win over the same repo on GitHub.
|
|
59
|
+
const found = new Map();
|
|
60
|
+
const add = (slug, candidate) => {
|
|
61
|
+
const key = slug.toLowerCase();
|
|
62
|
+
const known = found.get(key);
|
|
63
|
+
if (!known || candidate.score > known.score)
|
|
64
|
+
found.set(key, { slug, ...known, ...candidate });
|
|
65
|
+
};
|
|
66
|
+
for (const [id, app] of apps) {
|
|
67
|
+
const match = Math.max(score(name, app.name ?? id), score(name, app.slug ?? ''));
|
|
68
|
+
if (match >= 0.5)
|
|
69
|
+
add(app.slug ?? id, { where: 'stack', app: id, name: app.name, score: match + 0.01 });
|
|
70
|
+
}
|
|
71
|
+
for (const clone of clones) {
|
|
72
|
+
const match = score(name, clone.slug.split('/').pop() ?? '');
|
|
73
|
+
if (match >= 0.5 && !found.has(clone.slug))
|
|
74
|
+
add(clone.slug, { where: 'clone', path: clone.path, score: match });
|
|
75
|
+
}
|
|
76
|
+
if (github && orgs.length) {
|
|
77
|
+
// Any of the words, in the name: the scoring above keeps only the repos that really match.
|
|
78
|
+
const inOrgs = orgs.map(org => `org:${org}`).join(' ');
|
|
79
|
+
const query = encodeURIComponent(`${words(name).join(' OR ')} in:name ${inOrgs} fork:true`);
|
|
80
|
+
const searched = await gh([`search/repositories?q=${query}&per_page=8`]);
|
|
81
|
+
if (!searched.ok)
|
|
82
|
+
out.githubError = searched.err.split('\n')[0] ?? '';
|
|
83
|
+
else
|
|
84
|
+
for (const repo of JSON.parse(searched.out).items ?? []) {
|
|
85
|
+
const match = score(name, repo.name);
|
|
86
|
+
if (match < 0.5 || found.has(repo.full_name.toLowerCase()))
|
|
87
|
+
continue;
|
|
88
|
+
add(repo.full_name, {
|
|
89
|
+
where: 'github',
|
|
90
|
+
description: (repo.description ?? '').slice(0, 140),
|
|
91
|
+
pushed: repo.pushed_at?.slice(0, 10),
|
|
92
|
+
archived: repo.archived,
|
|
93
|
+
score: match,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Best match first; an archived repo is rarely the one meant, and of equals the more recently changed wins.
|
|
98
|
+
const rank = (candidate) => candidate.score - (candidate.archived ? 0.3 : 0);
|
|
99
|
+
const best = [...found.values()].sort((a, b) => rank(b) - rank(a) || (b.pushed ?? '').localeCompare(a.pushed ?? ''));
|
|
100
|
+
out.push({ name, candidates: best.slice(0, 6) });
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
const whereOf = (candidate) => {
|
|
105
|
+
if (candidate.where === 'stack')
|
|
106
|
+
return `in the stack as ${String(candidate.app)}`;
|
|
107
|
+
if (candidate.where === 'clone')
|
|
108
|
+
return `cloned at ${(candidate.path ?? '').replace(os.homedir(), '~')}`;
|
|
109
|
+
const changed = candidate.pushed ? `, last change ${candidate.pushed}` : '';
|
|
110
|
+
const about = candidate.description ? `: ${candidate.description}` : '';
|
|
111
|
+
return `on GitHub${changed}${candidate.archived ? ', archived' : ''}${about}; clone it only after the user says yes`;
|
|
112
|
+
};
|
|
113
|
+
export async function findCommand(args) {
|
|
114
|
+
const names = args.filter(arg => !arg.startsWith('--'));
|
|
115
|
+
if (!names.length) {
|
|
116
|
+
console.error('usage: koppler discover --find "<name> [<name>...]" [--json] [--no-github]');
|
|
117
|
+
throw new Failure('', 1);
|
|
118
|
+
}
|
|
119
|
+
const found = await find(names, { registry: readStack(), github: !args.includes('--no-github') });
|
|
120
|
+
if (args.includes('--json')) {
|
|
121
|
+
console.log(JSON.stringify(found, null, 2));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
for (const { name, candidates } of found) {
|
|
125
|
+
const count = candidates.length;
|
|
126
|
+
const said = count === 1 ? 'one match' : count ? `${String(count)} candidates, ask which` : 'nothing found, ask the user';
|
|
127
|
+
console.log(`\n${name}: ${said}`);
|
|
128
|
+
for (const candidate of candidates)
|
|
129
|
+
console.log(` ${candidate.slug} ${whereOf(candidate)}`);
|
|
130
|
+
}
|
|
131
|
+
if (found.githubError)
|
|
132
|
+
console.log(`\n(GitHub was not searched: ${found.githubError})`);
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=research.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/engine/research.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Each run keeps its apps' logs: a log is copied into the run's folder when the run it belongs to is over (another run
|
|
2
|
+
// took its place, or the app restarts for another one). The newest runs are kept, and pinned ones too.
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { APP_ID, RUN_ID } from "../ids.js";
|
|
6
|
+
import { writeJson } from "../json-files.js";
|
|
7
|
+
import { logsDir, tempDir } from "../paths.js";
|
|
8
|
+
import { live } from "./history.js";
|
|
9
|
+
const KEPT = 20;
|
|
10
|
+
const runsDir = () => path.join(tempDir(), 'runs');
|
|
11
|
+
const pinsFile = () => path.join(tempDir(), 'pinned.json');
|
|
12
|
+
export function pinned() {
|
|
13
|
+
try {
|
|
14
|
+
const ids = JSON.parse(fs.readFileSync(pinsFile(), 'utf8'));
|
|
15
|
+
return Array.isArray(ids) ? ids.filter((id) => typeof id === 'string' && RUN_ID.test(id)) : [];
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Keeps a run's logs whatever happens, or lets them go with the oldest again. */
|
|
22
|
+
export function pin(id, on) {
|
|
23
|
+
const now = pinned().filter(one => one !== id);
|
|
24
|
+
writeJson(pinsFile(), on ? [...now, id] : now);
|
|
25
|
+
if (!on)
|
|
26
|
+
prune();
|
|
27
|
+
}
|
|
28
|
+
/** The apps a run kept logs of. */
|
|
29
|
+
export function runLogs(id) {
|
|
30
|
+
if (!RUN_ID.test(id))
|
|
31
|
+
return [];
|
|
32
|
+
try {
|
|
33
|
+
return fs
|
|
34
|
+
.readdirSync(path.join(runsDir(), id))
|
|
35
|
+
.filter(file => file.endsWith('.log'))
|
|
36
|
+
.map(file => file.slice(0, -4))
|
|
37
|
+
.filter(name => APP_ID.test(name));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Where a run's log of an app is, when it kept one. */
|
|
44
|
+
export const runLog = (id, name) => RUN_ID.test(id) && APP_ID.test(name) ? path.join(runsDir(), id, `${name}.log`) : null;
|
|
45
|
+
/** Copies an app's log into the folder of the run it belongs to, the live one, once. */
|
|
46
|
+
export function keepRunLog(name) {
|
|
47
|
+
const run = live();
|
|
48
|
+
const to = run?.id && run.nodes[name] ? runLog(run.id, name) : null;
|
|
49
|
+
const from = path.join(logsDir(), `${name}.log`);
|
|
50
|
+
if (!to || fs.existsSync(to) || !fs.existsSync(from))
|
|
51
|
+
return;
|
|
52
|
+
fs.mkdirSync(path.dirname(to), { recursive: true, mode: 0o700 });
|
|
53
|
+
fs.copyFileSync(from, to);
|
|
54
|
+
fs.chmodSync(to, 0o600);
|
|
55
|
+
prune();
|
|
56
|
+
}
|
|
57
|
+
/** Every app of the live run, as another run takes its place: not the one starting now. */
|
|
58
|
+
export function keepRunLogs(starting) {
|
|
59
|
+
const run = live();
|
|
60
|
+
if (run && run.id !== starting)
|
|
61
|
+
for (const name of Object.keys(run.nodes))
|
|
62
|
+
keepRunLog(name);
|
|
63
|
+
}
|
|
64
|
+
/** Drops the logs of all but the newest runs, unless a run is pinned. */
|
|
65
|
+
function prune() {
|
|
66
|
+
let ids;
|
|
67
|
+
try {
|
|
68
|
+
ids = fs.readdirSync(runsDir()).filter(id => RUN_ID.test(id));
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const age = (id) => fs.statSync(path.join(runsDir(), id)).mtimeMs;
|
|
74
|
+
const keep = new Set([...pinned(), ...ids.sort((a, b) => age(b) - age(a)).slice(0, KEPT)]);
|
|
75
|
+
for (const id of ids)
|
|
76
|
+
if (!keep.has(id))
|
|
77
|
+
fs.rmSync(path.join(runsDir(), id), { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=run-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-logs.js","sourceRoot":"","sources":["../../src/engine/run-logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// `koppler run`: one process, started detached and kept track of. A stack app is started by its id, with its stored
|
|
2
|
+
// secrets; anything else is a command of the caller's own, which never gets them.
|
|
3
|
+
import { fail } from "../failure.js";
|
|
4
|
+
import { appStart } from "./app-start.js";
|
|
5
|
+
import { parseRun, startProcess } from "./processes.js";
|
|
6
|
+
import { traceEnv, tracing } from "./traces.js";
|
|
7
|
+
import { showBrowserConsole } from "./browser-console.js";
|
|
8
|
+
import { readClones, readStack } from "../data.js";
|
|
9
|
+
const USAGE = 'usage: koppler run <app> | koppler run <name> [--cwd <dir>] [--port <n>] [--bind <address>] [--restart] -- <command...>';
|
|
10
|
+
const shown = (word) => (/\s/.test(word) ? JSON.stringify(word) : word);
|
|
11
|
+
export async function run(args, extra = {}) {
|
|
12
|
+
let options;
|
|
13
|
+
try {
|
|
14
|
+
options = { ...parseRun(args), ...extra };
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
fail(`${error.message}\n${USAGE}`);
|
|
18
|
+
}
|
|
19
|
+
if (!options.command.length) {
|
|
20
|
+
const { name } = options;
|
|
21
|
+
const app = appStart(name, options) ??
|
|
22
|
+
fail(`${name} is not an app in the stack; to run a command: koppler run ${name} -- <command>`);
|
|
23
|
+
const port = options.port ?? app.port;
|
|
24
|
+
Object.assign(options, { command: app.command, onStop: app.onStop ?? [], env: app.env, holdsSecrets: true });
|
|
25
|
+
if (app.cwd !== undefined)
|
|
26
|
+
options.cwd = app.cwd;
|
|
27
|
+
else
|
|
28
|
+
delete options.cwd;
|
|
29
|
+
if (port !== undefined)
|
|
30
|
+
options.port = port;
|
|
31
|
+
if (app.ready)
|
|
32
|
+
options.ready = app.ready;
|
|
33
|
+
if (app.once)
|
|
34
|
+
options.once = app.once;
|
|
35
|
+
const shown = readStack()?.apps[name]?.browserConsole;
|
|
36
|
+
const repo = readClones()[name]?.path;
|
|
37
|
+
if (shown && repo)
|
|
38
|
+
console.log(`${name}: ${showBrowserConsole(name, repo, shown.file)}`);
|
|
39
|
+
// While traces are collected, the app sends its own there, under its id; what the run sets for it comes on top.
|
|
40
|
+
if (tracing())
|
|
41
|
+
options.setEnv = { ...traceEnv(name), ...options.setEnv };
|
|
42
|
+
if (app.device)
|
|
43
|
+
console.log(`device: ${app.device.name} (${app.device.platform})`);
|
|
44
|
+
}
|
|
45
|
+
if (options.dryRun) {
|
|
46
|
+
const port = options.port ? `, port ${String(options.port)}` : '';
|
|
47
|
+
console.log(`would run in ${options.cwd ?? process.cwd()}${port}:\n ${options.command.map(shown).join(' ')}`);
|
|
48
|
+
for (const command of options.onStop ?? [])
|
|
49
|
+
console.log(`on stop: ${command.join(' ')}`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
await startProcess(options);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/engine/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// Runs: every Send and Stop from the canvas is kept as a record (what was asked, the plan the user confirmed, how it ended),
|
|
2
|
+
// and the board last applied is kept as the live state the next plan is compared with. Names only, never secret values.
|
|
3
|
+
// Usage: koppler plan [--json] what the newest unapplied Send will do, checked against what is running
|
|
4
|
+
// koppler history done [<id>] [--failed <why>] the agent finished (or gave up on) a run
|
|
5
|
+
// koppler history recent runs and how they ended
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { fail } from "../failure.js";
|
|
9
|
+
import * as kp from "../core/plan.js";
|
|
10
|
+
import { readClones, readData, readStack } from "../data.js";
|
|
11
|
+
import { stateDir, tempDir } from "../paths.js";
|
|
12
|
+
import { redact } from "../scrub.js";
|
|
13
|
+
import { alive, records } from "./processes.js";
|
|
14
|
+
import { writeJson } from "../json-files.js";
|
|
15
|
+
import { actionsFile, append, codeChanges, live, liveFile, NOTE_WORDS, notes, runs, } from "./history.js";
|
|
16
|
+
import { finishTaken } from "./listen.js";
|
|
17
|
+
import { pinned, runLogs } from "./run-logs.js";
|
|
18
|
+
import { markRuns } from "./recipes.js";
|
|
19
|
+
const text = (value, max = 200) => (typeof value === 'string' ? value.slice(0, max) : '');
|
|
20
|
+
const stamp = () => new Date().toISOString();
|
|
21
|
+
/** What Koppler is running right now (apps, tunnels, the canvas): its own records, each checked to still be that process. */
|
|
22
|
+
const runningRecords = () => records().filter(alive);
|
|
23
|
+
export const runningNames = () => runningRecords().map(record => record.name);
|
|
24
|
+
export const runningEnvs = () => Object.fromEntries(runningRecords().flatMap(record => (record.env ? [[record.name, record.env]] : [])));
|
|
25
|
+
/** The part of a board that really runs: apps Koppler runs now, and apps the user starts in an IDE; `off` lists the rest. */
|
|
26
|
+
export function runningPart(board, names = runningNames()) {
|
|
27
|
+
const all = board.nodes ?? {};
|
|
28
|
+
const on = (id) => names.includes(id) || all[id]?.run === 'ide';
|
|
29
|
+
const nodes = Object.fromEntries(Object.entries(all).filter(([id]) => on(id)));
|
|
30
|
+
const edges = (board.edges ?? []).filter(edge => nodes[edge.from] && nodes[edge.to]);
|
|
31
|
+
return { nodes, edges, off: Object.keys(all).filter(id => !on(id)) };
|
|
32
|
+
}
|
|
33
|
+
/** Apps Koppler runs that the applied board does not explain. */
|
|
34
|
+
export const strays = (liveBoard, names, appIds) => names.filter(name => appIds.includes(name) && !liveBoard?.nodes?.[name]);
|
|
35
|
+
const nameIn = (stack) => (id) => stack?.apps[id]?.name ?? id;
|
|
36
|
+
/** What running a board would start, restart, stop and keep, against what runs now. */
|
|
37
|
+
export function planFor(board) {
|
|
38
|
+
const stack = readStack();
|
|
39
|
+
const names = runningNames();
|
|
40
|
+
const envs = runningEnvs();
|
|
41
|
+
const liveBoard = live();
|
|
42
|
+
return kp.plan(liveBoard, board, {
|
|
43
|
+
name: nameIn(stack),
|
|
44
|
+
running: id => names.includes(id),
|
|
45
|
+
strays: strays(liveBoard, names, Object.keys(stack?.apps ?? {})),
|
|
46
|
+
startedOn: id => envs[id],
|
|
47
|
+
queuesOf: id => kp.queuesOf(stack, id),
|
|
48
|
+
current: id => readClones()[id]?.branch ?? undefined,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** The plan for the newest Send that has not been applied, worked out again now, and whether it is still what the user confirmed. */
|
|
52
|
+
export function currentPlan() {
|
|
53
|
+
const run = runs().findLast(one => one.kind === 'run' && (one.state === 'waiting' || one.state === 'applying'));
|
|
54
|
+
if (!run)
|
|
55
|
+
return null;
|
|
56
|
+
const plan = planFor(run);
|
|
57
|
+
return { run, plan, confirmed: kp.same(plan, run.plan), name: nameIn(readStack()) };
|
|
58
|
+
}
|
|
59
|
+
export function planCommand(args) {
|
|
60
|
+
const current = currentPlan();
|
|
61
|
+
if (!current) {
|
|
62
|
+
console.log('No Send is waiting to be applied.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const { run, plan, confirmed, name } = current;
|
|
66
|
+
if (args.includes('--json')) {
|
|
67
|
+
const shown = { id: run.id, env: run.env, mode: run.mode, confirmed, plan, asConfirmed: run.plan };
|
|
68
|
+
console.log(JSON.stringify(shown, null, 2));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
console.log(`Run ${run.id} on ${String(run.env).toUpperCase()} (${String(run.mode)}), sent ${run.at}`);
|
|
72
|
+
for (const line of kp.describe(plan, { name }))
|
|
73
|
+
console.log(` ${line}`);
|
|
74
|
+
const asConfirmed = kp.describe(run.plan, { name }).join(' | ');
|
|
75
|
+
console.log(confirmed
|
|
76
|
+
? ' This is what the user confirmed on the canvas.'
|
|
77
|
+
: ` DIFFERS from what the user confirmed (${asConfirmed}): things changed since. Tell the user and ask before doing anything.`);
|
|
78
|
+
}
|
|
79
|
+
/** The environment variables a launch profile has right now, read from the app's clone. */
|
|
80
|
+
function profileEnvNow(action) {
|
|
81
|
+
try {
|
|
82
|
+
const clones = (readData('local')?.['apps'] ?? {});
|
|
83
|
+
const { app, file, name } = action;
|
|
84
|
+
const repo = clones[app]?.path;
|
|
85
|
+
const settings = JSON.parse(fs.readFileSync(path.isAbsolute(file) ? file : path.join(repo, file), 'utf8').replace(/^\uFEFF/, ''));
|
|
86
|
+
return settings.profiles?.[name]?.environmentVariables ?? null;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** The code changes in effect after a run; ones an earlier run already showed are not marked new. */
|
|
93
|
+
function changesAfter(run, all) {
|
|
94
|
+
try {
|
|
95
|
+
const shown = all.filter(other => other.id !== run.id).flatMap(other => other.changes ?? []);
|
|
96
|
+
const seen = new Set(shown.map(change => JSON.stringify({ ...change, fresh: undefined })));
|
|
97
|
+
const actions = JSON.parse(fs.readFileSync(actionsFile(), 'utf8'));
|
|
98
|
+
return codeChanges(actions, { clean: redact, profileEnv: profileEnvNow }).map(change => ({
|
|
99
|
+
...change,
|
|
100
|
+
...(!seen.has(JSON.stringify(change)) && { fresh: true }),
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// No action log yet: nothing was changed.
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** While Koppler itself is worked on, a finished Stop ends a session: it is gathered, and the agent is asked to review it. */
|
|
109
|
+
async function gatherSession(stop) {
|
|
110
|
+
try {
|
|
111
|
+
const { isDev, collectSession } = await import("./session.js");
|
|
112
|
+
if (!isDev())
|
|
113
|
+
return;
|
|
114
|
+
const { dir, quiet } = collectSession({
|
|
115
|
+
temp: tempDir(),
|
|
116
|
+
logsDir: path.join(stateDir(), 'logs'),
|
|
117
|
+
stop,
|
|
118
|
+
runs: runs(),
|
|
119
|
+
});
|
|
120
|
+
if (quiet) {
|
|
121
|
+
console.log(`Session gathered in ${dir}; nothing went wrong, so no review is queued.`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const review = `The session ended with a full Stop. Review it using the koppler-run skill: read ${dir}/summary.md and the files next to it, find every problem the user ran into, fix them in Koppler, verify each fix, and report.`;
|
|
125
|
+
const prompt = { tag: 'koppler-review', at: stamp(), text: review, data: { dir } };
|
|
126
|
+
fs.appendFileSync(path.join(tempDir(), 'prompts.jsonl'), JSON.stringify(prompt) + '\n', { mode: 0o600 });
|
|
127
|
+
console.log(`Session gathered in ${dir}; a review request is queued for the agent.`);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error(`koppler: could not gather the session (${error.message})`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** `koppler history session`: what happened since the last finished Stop, gathered for the agent to read. */
|
|
134
|
+
export async function sessionCommand() {
|
|
135
|
+
const { collectSession } = await import("./session.js");
|
|
136
|
+
const { dir } = collectSession({ temp: tempDir(), logsDir: path.join(stateDir(), 'logs'), runs: runs() });
|
|
137
|
+
console.log(fs.readFileSync(path.join(dir, 'summary.md'), 'utf8').trimEnd());
|
|
138
|
+
console.log(`\nThe files are in ${dir}; they stay on this Mac.`);
|
|
139
|
+
}
|
|
140
|
+
/** `koppler history done [<id>] [--failed <why>]`: the run ended, and the live state becomes what really runs from it. */
|
|
141
|
+
export async function appliedCommand(args) {
|
|
142
|
+
const failAt = args.indexOf('--failed');
|
|
143
|
+
const failed = failAt >= 0;
|
|
144
|
+
const reason = failed ? args[failAt + 1] : undefined;
|
|
145
|
+
const given = args.find((arg, at) => !arg.startsWith('--') && (!failed || at !== failAt + 1));
|
|
146
|
+
const all = runs();
|
|
147
|
+
const run = given
|
|
148
|
+
? all.find(one => one.id === given)
|
|
149
|
+
: all.findLast(one => one.state === 'waiting' || one.state === 'applying');
|
|
150
|
+
if (!run && !given && !failed) {
|
|
151
|
+
// A request that was no run (filling in settings, answering a question): done means the agent is no longer at it.
|
|
152
|
+
if (finishTaken()) {
|
|
153
|
+
console.log('The request is finished: the canvas no longer shows the agent as working.');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (!run)
|
|
158
|
+
fail(given ? `no run ${given} in the history` : 'no run is waiting to be applied');
|
|
159
|
+
if (failed && !reason)
|
|
160
|
+
fail('say why: koppler history done --failed "<what went wrong>"');
|
|
161
|
+
const changes = changesAfter(run, all);
|
|
162
|
+
// How each remembered change did on this Mac, and when; private, never in the shared stack.
|
|
163
|
+
try {
|
|
164
|
+
markRuns(actionsFile(), !failed);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Remembered changes are a convenience: a run still ends without them.
|
|
168
|
+
}
|
|
169
|
+
append({
|
|
170
|
+
id: run.id,
|
|
171
|
+
event: failed ? 'failed' : 'done',
|
|
172
|
+
at: stamp(),
|
|
173
|
+
...(reason && { reason: text(reason, 500) }),
|
|
174
|
+
...(changes.length && { changes }),
|
|
175
|
+
});
|
|
176
|
+
// The live state is what really runs from this board, done or failed: what Koppler runs, and what the user starts in
|
|
177
|
+
// an IDE. An app that did not start is left out and named, so the next Send starts it instead of keeping a ghost.
|
|
178
|
+
const { nodes, edges, off } = runningPart(run);
|
|
179
|
+
const now = {
|
|
180
|
+
id: run.id,
|
|
181
|
+
at: stamp(),
|
|
182
|
+
env: run.env,
|
|
183
|
+
nodes,
|
|
184
|
+
edges,
|
|
185
|
+
...(run.queues && { queues: run.queues }),
|
|
186
|
+
};
|
|
187
|
+
writeJson(liveFile(), now);
|
|
188
|
+
if (run.kind === 'stop' && !failed)
|
|
189
|
+
await gatherSession(run);
|
|
190
|
+
const ended = failed ? `failed (${reason ?? ''})` : 'done';
|
|
191
|
+
const running = Object.keys(nodes).join(', ') || 'empty';
|
|
192
|
+
console.log(`${run.kind === 'stop' ? 'Stop' : 'Run'} ${run.id}: ${ended}; live state is now ${running}`);
|
|
193
|
+
if (off.length) {
|
|
194
|
+
const names = off.map(nameIn(readStack())).join(', ');
|
|
195
|
+
console.log(`Not running: ${names}. The next Send starts ${off.length === 1 ? 'it' : 'them'} again.`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/** `koppler history [--json]`: recent runs and how they ended. */
|
|
199
|
+
export function historyCommand(args = []) {
|
|
200
|
+
const all = runs().slice(-15);
|
|
201
|
+
if (args.includes('--json')) {
|
|
202
|
+
const pins = pinned();
|
|
203
|
+
const told = all.map(run => ({ ...run, logs: runLogs(run.id), pinned: pins.includes(run.id) }));
|
|
204
|
+
console.log(JSON.stringify(told, null, 2));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const lines = all.map((run) => {
|
|
208
|
+
const what = run.kind === 'stop'
|
|
209
|
+
? 'stop and revert'
|
|
210
|
+
: `${String(run.env).toUpperCase()} ${String(run.mode)}: ${Object.keys(run.nodes).join(', ')}`;
|
|
211
|
+
return [run.at, `${run.at} ${run.id} ${what} [${run.state}${run.reason ? `: ${run.reason}` : ''}]`];
|
|
212
|
+
});
|
|
213
|
+
// What stopped outside a run is told among the runs, in the order it happened.
|
|
214
|
+
const [oldest] = lines;
|
|
215
|
+
for (const { note, at, stopped } of notes())
|
|
216
|
+
if (!oldest || at >= oldest[0])
|
|
217
|
+
lines.push([at, `${at} ${NOTE_WORDS[note]}${stopped.length ? `: ${stopped.join(', ')}` : ''}`]);
|
|
218
|
+
if (!lines.length)
|
|
219
|
+
console.log('No runs yet.');
|
|
220
|
+
for (const [, line] of lines.sort((a, b) => a[0].localeCompare(b[0])))
|
|
221
|
+
console.log(line);
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/engine/runs.ts"],"names":[],"mappings":"AAAA,6HAA6H;AAC7H,wHAAwH;AACxH,4HAA4H;AAC5H,kGAAkG;AAClG,mFAAmF;AACnF,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,MAAM,EACN,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,KAAK,EACL,IAAI,GAIL,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACnG,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAE7C,6HAA6H;AAC7H,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,YAAY,GAAG,GAAa,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACxF,MAAM,CAAC,MAAM,WAAW,GAAG,GAA2B,EAAE,CACtD,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAG1G,6HAA6H;AAC7H,MAAM,UAAU,WAAW,CAAC,KAAgB,EAAE,KAAK,GAAG,YAAY,EAAE;IAClE,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,KAAK,CAAC;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACrF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACvE,CAAC;AACD,iEAAiE;AACjE,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,SAAiE,EACjE,KAAe,EACf,MAAgB,EACN,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAExF,MAAM,MAAM,GAAG,CAAC,KAAmC,EAAE,EAAE,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;AAEpG,uFAAuF;AACvF,MAAM,UAAU,OAAO,CAAC,KAAoB;IAC1C,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,MAAM,SAAS,GAAG,IAAI,EAAE,CAAC;IACzB,OAAO,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE;QAC/B,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC;QACnB,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QAChE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;QACtC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,IAAI,SAAS;KACrD,CAAC,CAAC;AACL,CAAC;AACD,qIAAqI;AACrI,MAAM,UAAU,WAAW;IACzB,MAAM,GAAG,GAAG,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC;IAChH,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IACD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;QACnG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACvG,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAe,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CACT,SAAS;QACP,CAAC,CAAC,kDAAkD;QACpD,CAAC,CAAC,2CAA2C,WAAW,uEAAuE,CAClI,CAAC;AACJ,CAAC;AAED,2FAA2F;AAC3F,SAAS,aAAa,CAAC,MAAa;IAClC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAA6C,CAAC;QAC/F,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAqD,CAAC;QAClF,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAc,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAC9B,CAAC;QACnF,OAAO,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,oBAAoB,IAAI,IAAI,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,qGAAqG;AACrG,SAAS,YAAY,CAAC,GAAQ,EAAE,GAAU;IACxC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAC7F,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3F,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QAC5E,OAAO,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvF,GAAG,MAAM;YACT,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,IAAa,EAAE,CAAC;SACnE,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,8HAA8H;AAC9H,KAAK,UAAU,aAAa,CAAC,IAAS;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,KAAK,EAAE;YAAE,OAAO;QACrB,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC;YACpC,IAAI,EAAE,OAAO,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC;YACtC,IAAI;YACJ,IAAI,EAAE,IAAI,EAAE;SACb,CAAC,CAAC;QACH,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,+CAA+C,CAAC,CAAC;YACvF,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,mFAAmF,GAAG,+HAA+H,CAAC;QACrO,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;QACnF,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzG,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,6CAA6C,CAAC,CAAC;IACvF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0CAA2C,KAAe,CAAC,OAAO,GAAG,CAAC,CAAC;IACvF,CAAC;AACH,CAAC;AAED,6GAA6G;AAC7G,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC1G,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,0BAA0B,CAAC,CAAC;AACnE,CAAC;AAED,0HAA0H;AAC1H,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAc;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,GAAG,GAAG,IAAI,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,KAAK;QACf,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC;QACnC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9B,kHAAkH;QAClH,IAAI,WAAW,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;YACzF,OAAO;QACT,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAG;QAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,iBAAiB,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC;IAC7F,IAAI,MAAM,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,4DAA4D,CAAC,CAAC;IAC1F,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACvC,4FAA4F;IAC5F,IAAI,CAAC;QACH,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;IACD,MAAM,CAAC;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM;QACjC,EAAE,EAAE,KAAK,EAAE;QACX,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;QAC5C,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,OAAO,EAAE,CAAC;KACnC,CAAC,CAAC;IACH,qHAAqH;IACrH,kHAAkH;IAClH,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAc;QACrB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,EAAE,EAAE,KAAK,EAAE;QACX,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,KAAK;QACL,KAAK;QACL,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;KAC1C,CAAC;IACF,SAAS,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,MAAM;QAAE,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,EAAE,KAAK,KAAK,uBAAuB,OAAO,EAAE,CAAC,CAAC;IACzG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,0BAA0B,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC;IACxG,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,cAAc,CAAC,OAAiB,EAAE;IAChD,MAAM,GAAG,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9B,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAChG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAoB,EAAE;QAC9C,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,MAAM;YACjB,CAAC,CAAC,iBAAiB;YACnB,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnG,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,MAAM,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACzG,CAAC,CAAC,CAAC;IACH,+EAA+E;IAC/E,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IACvB,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,KAAK,EAAE;QACzC,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACrG,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC/C,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC3F,CAAC"}
|