@dbx-tools/appkit-lakebox 0.0.0-stage → 0.9.131
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 +202 -0
- package/README.md +104 -2
- package/index.ts +32 -0
- package/lib/index.d.ts +28 -0
- package/lib/index.js +26 -0
- package/lib/src/_package.d.ts +2 -0
- package/lib/src/_package.js +11 -0
- package/lib/src/_resource-registry.d.ts +41 -0
- package/lib/src/_resource-registry.js +128 -0
- package/lib/src/_service-snapshots.d.ts +55 -0
- package/lib/src/_service-snapshots.js +65 -0
- package/lib/src/config.d.ts +40 -0
- package/lib/src/config.js +86 -0
- package/lib/src/desktop.d.ts +6 -0
- package/lib/src/desktop.js +88 -0
- package/lib/src/metrics.d.ts +59 -0
- package/lib/src/metrics.js +151 -0
- package/lib/src/plugin.d.ts +259 -0
- package/lib/src/plugin.js +329 -0
- package/lib/src/routes.d.ts +75 -0
- package/lib/src/routes.js +441 -0
- package/lib/src/runtime.d.ts +154 -0
- package/lib/src/runtime.js +760 -0
- package/lib/src/services.d.ts +101 -0
- package/lib/src/services.js +188 -0
- package/lib/src/skills.d.ts +5 -0
- package/lib/src/skills.js +21 -0
- package/lib/src/user.d.ts +46 -0
- package/lib/src/user.js +76 -0
- package/lib/src/workspace.d.ts +43 -0
- package/lib/src/workspace.js +138 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +167 -4
- package/scripts/desktop-prerequisites.sh +66 -0
- package/scripts/desktop-session.sh +307 -0
- package/scripts/lakebox-admin.sh +234 -0
- package/scripts/lakebox-service.py +449 -0
- package/skills/html-page/SKILL.md +40 -0
- package/skills/jupyter-lab/SKILL.md +32 -0
- package/skills/lakebox-showcase/SKILL.md +66 -0
- package/skills/network-speed-test/SKILL.md +29 -0
- package/skills/realtime-whiteboard/SKILL.md +28 -0
- package/src/_package.ts +11 -0
- package/src/_resource-registry.ts +160 -0
- package/src/_service-snapshots.ts +84 -0
- package/src/config.ts +128 -0
- package/src/desktop.ts +97 -0
- package/src/metrics.ts +178 -0
- package/src/plugin.ts +446 -0
- package/src/routes.ts +524 -0
- package/src/runtime.ts +952 -0
- package/src/services.ts +239 -0
- package/src/skills.ts +23 -0
- package/src/user.ts +88 -0
- package/src/workspace.ts +185 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { ConfigurationError } from "@databricks/appkit";
|
|
2
|
+
import { MASTRA_USER_KEY } from "@dbx-tools/appkit-mastra";
|
|
3
|
+
import { MastraSandbox, } from "@mastra/core/workspace";
|
|
4
|
+
const INSTRUCTIONS = `Commands run on the app's shared Databricks Lakebox as your own locked, non-sudo Linux account with a persistent home. Other users have separate accounts and cannot reach your files or service ports. The Lakebox is created and started on first use and stops after its idle timeout; files and saved services persist.
|
|
5
|
+
|
|
6
|
+
Run long-lived servers as services, not background commands. Call create_lakebox_service with an OCI image; it starts the service detached, waits until it is ready, and returns openUrl. The runtime injects SERVICE_NAME, SERVICE_PATH, SERVICE_PORT, and PORT. Routed services must listen on 127.0.0.1:$SERVICE_PORT. There is no Docker CLI, daemon, port publishing, privileged mode, or device access. Bind mounts come from your home through the mounts field. Services restart from their saved definition when the Lakebox starts; process memory does not resume.
|
|
7
|
+
|
|
8
|
+
For a minimal routed Python service:
|
|
9
|
+
|
|
10
|
+
{
|
|
11
|
+
"name": "hello",
|
|
12
|
+
"image": "docker.io/library/python:3.12-alpine",
|
|
13
|
+
"command": ["python", "-c", "import http.server, os; name=os.environ['SERVICE_NAME']; H=type('H',(http.server.BaseHTTPRequestHandler,),{'do_GET':lambda s:(s.send_response(200),s.send_header('Content-Type','text/plain'),s.end_headers(),s.wfile.write(f'hello from {name}\\\\n'.encode())),'log_message':lambda *a:None}); http.server.ThreadingHTTPServer(('127.0.0.1',int(os.environ['SERVICE_PORT'])),H).serve_forever()"]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
Terminal and desktop are built-in services: call start_lakebox_service with name "terminal" or "desktop" and return the openUrl. Graphical applications belong on the desktop; never start, stop, or reconfigure the desktop display yourself.
|
|
17
|
+
|
|
18
|
+
With execute_lakebox_command, pass command "sh" and put the script in args ["-lc", "..."]; never pass an executable and its arguments together as command. Commands never receive Databricks credentials. Never return localhost, a loopback port, or a direct Lakebox URL; use the returned openUrl. Services must use relative asset and API URLs beneath their route. Derive ws:// or wss:// from the browser origin.`;
|
|
19
|
+
/**
|
|
20
|
+
* Mastra workspace sandbox backed by the app Lakebox.
|
|
21
|
+
*
|
|
22
|
+
* Commands run as the requesting user's Lakebox account through the shared
|
|
23
|
+
* {@link LakeboxRuntime}, so identity, credential scrubbing, and transport
|
|
24
|
+
* policy match the AppKit plugin tools and routes.
|
|
25
|
+
*/
|
|
26
|
+
export class LakeboxWorkspaceSandbox extends MastraSandbox {
|
|
27
|
+
id;
|
|
28
|
+
name;
|
|
29
|
+
runtime;
|
|
30
|
+
identity;
|
|
31
|
+
provider = "appkit-lakebox";
|
|
32
|
+
status = "pending";
|
|
33
|
+
constructor(id, name, runtime, identity) {
|
|
34
|
+
super({ name });
|
|
35
|
+
this.id = id;
|
|
36
|
+
this.name = name;
|
|
37
|
+
this.runtime = runtime;
|
|
38
|
+
this.identity = identity;
|
|
39
|
+
}
|
|
40
|
+
/** Creates or starts the app Lakebox. */
|
|
41
|
+
async start(options) {
|
|
42
|
+
await this.runtime.start(options?.abortSignal);
|
|
43
|
+
this.status = "running";
|
|
44
|
+
return { outcome: "connected" };
|
|
45
|
+
}
|
|
46
|
+
/** Leaves the shared Lakebox running; its platform idle timeout stops it. */
|
|
47
|
+
async stop() {
|
|
48
|
+
this.status = "stopped";
|
|
49
|
+
}
|
|
50
|
+
/** Releases this handle without changing the shared Lakebox. */
|
|
51
|
+
async destroy() {
|
|
52
|
+
this.status = "destroyed";
|
|
53
|
+
}
|
|
54
|
+
/** Mastra snapshot hook. Lakeboxes do not expose snapshot operations. */
|
|
55
|
+
async snapshot() { }
|
|
56
|
+
/** Runs a command as the current user's Lakebox account. */
|
|
57
|
+
async executeCommand(command, args = [], options = {}) {
|
|
58
|
+
const execution = this.runtime.execute(this.identity, {
|
|
59
|
+
command,
|
|
60
|
+
args,
|
|
61
|
+
...(options.cwd ? { cwd: options.cwd } : {}),
|
|
62
|
+
...(options.env
|
|
63
|
+
? {
|
|
64
|
+
env: Object.fromEntries(Object.entries(options.env).filter((entry) => typeof entry[1] === "string")),
|
|
65
|
+
}
|
|
66
|
+
: {}),
|
|
67
|
+
...(options.timeout ? { timeoutMs: options.timeout } : {}),
|
|
68
|
+
}, options.abortSignal);
|
|
69
|
+
if (options.onStdout)
|
|
70
|
+
execution.stdout.on("data", (chunk) => options.onStdout?.(chunk));
|
|
71
|
+
if (options.onStderr)
|
|
72
|
+
execution.stderr.on("data", (chunk) => options.onStderr?.(chunk));
|
|
73
|
+
const result = await execution.result;
|
|
74
|
+
const stdout = retainCommandOutput(result.stdout, options.maxRetainedBytes);
|
|
75
|
+
const stderr = retainCommandOutput(result.stderr, options.maxRetainedBytes);
|
|
76
|
+
return {
|
|
77
|
+
...result,
|
|
78
|
+
stdout: stdout.value,
|
|
79
|
+
stderr: stderr.value,
|
|
80
|
+
...(stdout.droppedBytes > 0
|
|
81
|
+
? { stdoutTruncated: true, stdoutDroppedBytes: stdout.droppedBytes }
|
|
82
|
+
: {}),
|
|
83
|
+
...(stderr.droppedBytes > 0
|
|
84
|
+
? { stderrTruncated: true, stderrDroppedBytes: stderr.droppedBytes }
|
|
85
|
+
: {}),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Returns the current Lakebox status in Mastra's sandbox shape. */
|
|
89
|
+
async getInfo() {
|
|
90
|
+
const summary = await this.runtime.summary(this.identity);
|
|
91
|
+
this.status =
|
|
92
|
+
summary.status === "missing" || summary.status === "unknown" ? "pending" : summary.status;
|
|
93
|
+
return {
|
|
94
|
+
id: this.id,
|
|
95
|
+
name: this.name,
|
|
96
|
+
provider: this.provider,
|
|
97
|
+
status: this.status,
|
|
98
|
+
createdAt: new Date(0),
|
|
99
|
+
metadata: { lakeboxId: summary.id, user: summary.user.name, services: summary.services },
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** Returns agent instructions for services, routes, and command execution. */
|
|
103
|
+
getInstructions() {
|
|
104
|
+
return INSTRUCTIONS;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Creates a request-scoped Mastra workspace resolver for the app Lakebox.
|
|
109
|
+
*
|
|
110
|
+
* Resolution never creates compute; the first command or service does.
|
|
111
|
+
*/
|
|
112
|
+
export function lakeboxWorkspaceSandbox(runtime, options = {}) {
|
|
113
|
+
return async ({ requestContext }) => {
|
|
114
|
+
const user = requestContext.get(MASTRA_USER_KEY);
|
|
115
|
+
if (!user) {
|
|
116
|
+
throw ConfigurationError.resourceNotFound("Lakebox user context", "Invoke Code Mode from an agent turn served by the Mastra plugin.");
|
|
117
|
+
}
|
|
118
|
+
return new LakeboxWorkspaceSandbox(runtime.config.application, options.displayName ?? "Lakebox", runtime, user.id);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function retainCommandOutput(output, maxRetainedBytes) {
|
|
122
|
+
if (maxRetainedBytes === undefined || maxRetainedBytes === Infinity) {
|
|
123
|
+
return { value: output, droppedBytes: 0 };
|
|
124
|
+
}
|
|
125
|
+
const limit = Number.isFinite(maxRetainedBytes) ? Math.max(0, Math.floor(maxRetainedBytes)) : 0;
|
|
126
|
+
const bytes = Buffer.from(output);
|
|
127
|
+
if (bytes.length <= limit)
|
|
128
|
+
return { value: output, droppedBytes: 0 };
|
|
129
|
+
let retainedStart = bytes.length - limit;
|
|
130
|
+
while (retainedStart < bytes.length && (bytes[retainedStart] & 0xc0) === 0x80) {
|
|
131
|
+
retainedStart++;
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
value: bytes.subarray(retainedStart).toString("utf8"),
|
|
135
|
+
droppedBytes: retainedStart,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya3NwYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3dvcmtzcGFjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsZUFBZSxFQUFhLE1BQU0sMEJBQTBCLENBQUM7QUFDdEUsT0FBTyxFQUNMLGFBQWEsR0FRZCxNQUFNLHdCQUF3QixDQUFDO0FBR2hDLE1BQU0sWUFBWSxHQUFHOzs7Ozs7Ozs7Ozs7Ozt5WkFjb1ksQ0FBQztBQVExWjs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sdUJBQXdCLFNBQVEsYUFBYTtJQUs3QztJQUNBO0lBQ1E7SUFDQTtJQVBWLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQztJQUNyQyxNQUFNLEdBQStCLFNBQVMsQ0FBQztJQUUvQyxZQUNXLEVBQVUsRUFDVixJQUFZLEVBQ0osT0FBdUIsRUFDdkIsUUFBZ0I7UUFFakMsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUxQLE9BQUUsR0FBRixFQUFFLENBQVE7UUFDVixTQUFJLEdBQUosSUFBSSxDQUFRO1FBQ0osWUFBTyxHQUFQLE9BQU8sQ0FBZ0I7UUFDdkIsYUFBUSxHQUFSLFFBQVEsQ0FBUTtJQUduQyxDQUFDO0lBRUQseUNBQXlDO0lBQ3pDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBNkI7UUFDdkMsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7UUFDeEIsT0FBTyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsNkVBQTZFO0lBQzdFLEtBQUssQ0FBQyxJQUFJO1FBQ1IsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7SUFDMUIsQ0FBQztJQUVELGdFQUFn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RUQsU0FBUyxtQkFBbUIsQ0FDMUIsTUFBYyxFQUNkLGdCQUFvQztJQUVwQyxJQUFJLGdCQUFnQixLQUFLLFNBQVMsSUFBSSxnQkFBZ0IsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNwRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDNUMsQ0FBQztJQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2xDLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLO1FBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQ3JFLElBQUksYUFBYSxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ3pDLE9BQU8sYUFBYSxHQUFHLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDL0UsYUFBYSxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUNELE9BQU87UUFDTCxLQUFLLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQ3JELFlBQVksRUFBRSxhQUFhO0tBQzVCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uZmlndXJhdGlvbkVycm9yIH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHsgTUFTVFJBX1VTRVJfS0VZLCB0eXBlIFVzZXIgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXQtbWFzdHJhXCI7XG5pbXBvcnQge1xuICBNYXN0cmFTYW5kYm94LFxuICB0eXBlIENvbW1hbmRSZXN1bHQsXG4gIHR5cGUgRXhlY3V0ZUNvbW1hbmRPcHRpb25zLFxuICB0eXBlIFNhbmRib3hJbmZvLFxuICB0eXBlIFNhbmRib3hTdGFydE9wdGlvbnMsXG4gIHR5cGUgU2FuZGJveFN0YXJ0UmVzdWx0LFxuICB0eXBlIFdvcmtzcGFjZVNhbmRib3gsXG4gIHR5cGUgV29ya3NwYWNlU2FuZGJveFJlc29sdmVyLFxufSBmcm9tIFwiQG1hc3RyYS9jb3JlL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHR5cGUgeyBMYWtlYm94UnVudGltZSB9IGZyb20gXCIuL3J1bnRpbWUudHNcIjtcblxuY29uc3QgSU5TVFJVQ1RJT05TID0gYENvbW1hbmRzIHJ1biBvbiB0aGUgYXBwJ3Mgc2hhcmVkIERhdGFicmlja3MgTGFrZWJveCBhcyB5b3VyIG93biBsb2NrZWQsIG5vbi1zdWRvIExpbnV4IGFjY291bnQgd2l0aCBhIHBlcnNpc3RlbnQgaG9tZS4gT3RoZXIgdXNlcnMgaGF2ZSBzZXBhcmF0ZSBhY2NvdW50cyBhbmQgY2Fubm90IHJlYWNoIHlvdXIgZmlsZXMgb3Igc2VydmljZSBwb3J0cy4gVGhlIExha2Vib3ggaXMgY3JlYXRlZCBhbmQgc3RhcnRlZCBvbiBmaXJzdCB1c2UgYW5kIHN0b3BzIGFmdGVyIGl0cyBpZGxlIHRpbWVvdXQ7IGZpbGVzIGFuZCBzYXZlZCBzZXJ2aWNlcyBwZXJzaXN0LlxuXG5SdW4gbG9uZy1saXZlZCBzZXJ2ZXJzIGFzIHNlcnZpY2VzLCBub3QgYmFja2dyb3VuZCBjb21tYW5kcy4gQ2FsbCBjcmVhdGVfbGFrZWJveF9zZXJ2aWNlIHdpdGggYW4gT0NJIGltYWdlOyBpdCBzdGFydHMgdGhlIHNlcnZpY2UgZGV0YWNoZWQsIHdhaXRzIHVudGlsIGl0IGlzIHJlYWR5LCBhbmQgcmV0dXJucyBvcGVuVXJsLiBUaGUgcnVudGltZSBpbmplY3RzIFNFUlZJQ0VfTkFNRSwgU0VSVklDRV9QQVRILCBTRVJWSUNFX1BPUlQsIGFuZCBQT1JULiBSb3V0ZWQgc2VydmljZXMgbXVzdCBsaXN0ZW4gb24gMTI3LjAuMC4xOiRTRVJWSUNFX1BPUlQuIFRoZXJlIGlzIG5vIERvY2tlciBDTEksIGRhZW1vbiwgcG9ydCBwdWJsaXNoaW5nLCBwcml2aWxlZ2VkIG1vZGUsIG9yIGRldmljZSBhY2Nlc3MuIEJpbmQgbW91bnRzIGNvbWUgZnJvbSB5b3VyIGhvbWUgdGhyb3VnaCB0aGUgbW91bnRzIGZpZWxkLiBTZXJ2aWNlcyByZXN0YXJ0IGZyb20gdGhlaXIgc2F2ZWQgZGVmaW5pdGlvbiB3aGVuIHRoZSBMYWtlYm94IHN0YXJ0czsgcHJvY2VzcyBtZW1vcnkgZG9lcyBub3QgcmVzdW1lLlxuXG5Gb3IgYSBtaW5pbWFsIHJvdXRlZCBQeXRob24gc2VydmljZTpcblxue1xuICBcIm5hbWVcIjogXCJoZWxsb1wiLFxuICBcImltYWdlXCI6IFwiZG9ja2VyLmlvL2xpYnJhcnkvcHl0aG9uOjMuMTItYWxwaW5lXCIsXG4gIFwiY29tbWFuZFwiOiBbXCJweXRob25cIiwgXCItY1wiLCBcImltcG9ydCBodHRwLnNlcnZlciwgb3M7IG5hbWU9b3MuZW52aXJvblsnU0VSVklDRV9OQU1FJ107IEg9dHlwZSgnSCcsKGh0dHAuc2VydmVyLkJhc2VIVFRQUmVxdWVzdEhhbmRsZXIsKSx7J2RvX0dFVCc6bGFtYmRhIHM6KHMuc2VuZF9yZXNwb25zZSgyMDApLHMuc2VuZF9oZWFkZXIoJ0NvbnRlbnQtVHlwZScsJ3RleHQvcGxhaW4nKSxzLmVuZF9oZWFkZXJzKCkscy53ZmlsZS53cml0ZShmJ2hlbGxvIGZyb20ge25hbWV9XFxcXFxcXFxuJy5lbmNvZGUoKSkpLCdsb2dfbWVzc2FnZSc6bGFtYmRhICphOk5vbmV9KTsgaHR0cC5zZXJ2ZXIuVGhyZWFkaW5nSFRUUFNlcnZlcigoJzEyNy4wLjAuMScsaW50KG9zLmVudmlyb25bJ1NFUlZJQ0VfUE9SVCddKSksSCkuc2VydmVfZm9yZXZlcigpXCJdXG59XG5cblRlcm1pbmFsIGFuZCBkZXNrdG9wIGFyZSBidWlsdC1pbiBzZXJ2aWNlczogY2FsbCBzdGFydF9sYWtlYm94X3NlcnZpY2Ugd2l0aCBuYW1lIFwidGVybWluYWxcIiBvciBcImRlc2t0b3BcIiBhbmQgcmV0dXJuIHRoZSBvcGVuVXJsLiBHcmFwaGljYWwgYXBwbGljYXRpb25zIGJlbG9uZyBvbiB0aGUgZGVza3RvcDsgbmV2ZXIgc3RhcnQsIHN0b3AsIG9yIHJlY29uZmlndXJlIHRoZSBkZXNrdG9wIGRpc3BsYXkgeW91cnNlbGYuXG5cbldpdGggZXhlY3V0ZV9sYWtlYm94X2NvbW1hbmQsIHBhc3MgY29tbWFuZCBcInNoXCIgYW5kIHB1dCB0aGUgc2NyaXB0IGluIGFyZ3MgW1wiLWxjXCIsIFwiLi4uXCJdOyBuZXZlciBwYXNzIGFuIGV4ZWN1dGFibGUgYW5kIGl0cyBhcmd1bWVudHMgdG9nZXRoZXIgYXMgY29tbWFuZC4gQ29tbWFuZHMgbmV2ZXIgcmVjZWl2ZSBEYXRhYnJpY2tzIGNyZWRlbnRpYWxzLiBOZXZlciByZXR1cm4gbG9jYWxob3N0LCBhIGxvb3BiYWNrIHBvcnQsIG9yIGEgZGlyZWN0IExha2Vib3ggVVJMOyB1c2UgdGhlIHJldHVybmVkIG9wZW5VcmwuIFNlcnZpY2VzIG11c3QgdXNlIHJlbGF0aXZlIGFzc2V0IGFuZCBBUEkgVVJMcyBiZW5lYXRoIHRoZWlyIHJvdXRlLiBEZXJpdmUgd3M6Ly8gb3Igd3NzOi8vIGZyb20gdGhlIGJyb3dzZXIgb3JpZ2luLmA7XG5cbi8qKiBPcHRpb25zIGZvciB0aGUgTGFrZWJveC1iYWNrZWQgTWFzdHJhIHdvcmtzcGFjZSBzYW5kYm94LiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYWtlYm94V29ya3NwYWNlU2FuZGJveE9wdGlvbnMge1xuICAvKiogT3B0aW9uYWwgZGlzcGxheSBuYW1lIHByZXNlbnRlZCBieSBNYXN0cmEgaW5zdGVhZCBvZiBMYWtlYm94LiAqL1xuICBkaXNwbGF5TmFtZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBNYXN0cmEgd29ya3NwYWNlIHNhbmRib3ggYmFja2VkIGJ5IHRoZSBhcHAgTGFrZWJveC5cbiAqXG4gKiBDb21tYW5kcyBydW4gYXMgdGhlIHJlcXVlc3RpbmcgdXNlcidzIExha2Vib3ggYWNjb3VudCB0aHJvdWdoIHRoZSBzaGFyZWRcbiAqIHtAbGluayBMYWtlYm94UnVudGltZX0sIHNvIGlkZW50aXR5LCBjcmVkZW50aWFsIHNjcnViYmluZywgYW5kIHRyYW5zcG9ydFxuICogcG9saWN5IG1hdGNoIHRoZSBBcHBLaXQgcGx1Z2luIHRvb2xzIGFuZCByb3V0ZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYWtlYm94V29ya3NwYWNlU2FuZGJveCBleHRlbmRzIE1hc3RyYVNhbmRib3gge1xuICByZWFkb25seSBwcm92aWRlciA9IFwiYXBwa2l0LWxha2Vib3hcIjtcbiAgc3RhdHVzOiBXb3Jrc3BhY2VTYW5kYm94W1wic3RhdHVzXCJdID0gXCJwZW5kaW5nXCI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkgaWQ6IHN0cmluZyxcbiAgICByZWFkb25seSBuYW1lOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBydW50aW1lOiBMYWtlYm94UnVudGltZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGlkZW50aXR5OiBzdHJpbmcsXG4gICkge1xuICAgIHN1cGVyKHsgbmFtZSB9KTtcbiAgfVxuXG4gIC8qKiBDcmVhdGVzIG9yIHN0YXJ0cyB0aGUgYXBwIExha2Vib3guICovXG4gIGFzeW5jIHN0YXJ0KG9wdGlvbnM/OiBTYW5kYm94U3RhcnRPcHRpb25zKTogUHJvbWlzZTxTYW5kYm94U3RhcnRSZXN1bHQ+IHtcbiAgICBhd2FpdCB0aGlzLnJ1bnRpbWUuc3RhcnQob3B0aW9ucz8uYWJvcnRTaWduYWwpO1xuICAgIHRoaXMuc3RhdHVzID0gXCJydW5uaW5nXCI7XG4gICAgcmV0dXJuIHsgb3V0Y29tZTogXCJjb25uZWN0ZWRcIiB9O1xuICB9XG5cbiAgLyoqIExlYXZlcyB0aGUgc2hhcmVkIExha2Vib3ggcnVubmluZzsgaXRzIHBsYXRmb3JtIGlkbGUgdGltZW91dCBzdG9wcyBpdC4gKi9cbiAgYXN5bmMgc3RvcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnN0YXR1cyA9IFwic3RvcHBlZFwiO1xuICB9XG5cbiAgLyoqIFJlbGVhc2VzIHRoaXMgaGFuZGxlIHdpdGhvdXQgY2hhbmdpbmcgdGhlIHNoYXJlZCBMYWtlYm94LiAqL1xuICBhc3luYyBkZXN0cm95KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RhdHVzID0gXCJkZXN0cm95ZWRcIjtcbiAgfVxuXG4gIC8qKiBNYXN0cmEgc25hcHNob3QgaG9vay4gTGFrZWJveGVzIGRvIG5vdCBleHBvc2Ugc25hcHNob3Qgb3BlcmF0aW9ucy4gKi9cbiAgYXN5bmMgc25hcHNob3QoKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIC8qKiBSdW5zIGEgY29tbWFuZCBhcyB0aGUgY3VycmVudCB1c2VyJ3MgTGFrZWJveCBhY2NvdW50LiAqL1xuICBvdmVycmlkZSBhc3luYyBleGVjdXRlQ29tbWFuZChcbiAgICBjb21tYW5kOiBzdHJpbmcsXG4gICAgYXJnczogc3RyaW5nW10gPSBbXSxcbiAgICBvcHRpb25zOiBFeGVjdXRlQ29tbWFuZE9wdGlvbnMgPSB7fSxcbiAgKTogUHJvbWlzZTxDb21tYW5kUmVzdWx0PiB7XG4gICAgY29uc3QgZXhlY3V0aW9uID0gdGhpcy5ydW50aW1lLmV4ZWN1dGUoXG4gICAgICB0aGlzLmlkZW50aXR5LFxuICAgICAge1xuICAgICAgICBjb21tYW5kLFxuICAgICAgICBhcmdzLFxuICAgICAgICAuLi4ob3B0aW9ucy5jd2QgPyB7IGN3ZDogb3B0aW9ucy5jd2QgfSA6IHt9KSxcbiAgICAgICAgLi4uKG9wdGlvbnMuZW52XG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIGVudjogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKG9wdGlvbnMuZW52KS5maWx0ZXIoXG4gICAgICAgICAgICAgICAgICAoZW50cnkpOiBlbnRyeSBpcyBbc3RyaW5nLCBzdHJpbmddID0+IHR5cGVvZiBlbnRyeVsxXSA9PT0gXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDoge30pLFxuICAgICAgICAuLi4ob3B0aW9ucy50aW1lb3V0ID8geyB0aW1lb3V0TXM6IG9wdGlvbnMudGltZW91dCB9IDoge30pLFxuICAgICAgfSxcbiAgICAgIG9wdGlvbnMuYWJvcnRTaWduYWwsXG4gICAgKTtcbiAgICBpZiAob3B0aW9ucy5vblN0ZG91dCkgZXhlY3V0aW9uLnN0ZG91dC5vbihcImRhdGFcIiwgKGNodW5rOiBzdHJpbmcpID0+IG9wdGlvbnMub25TdGRvdXQ/LihjaHVuaykpO1xuICAgIGlmIChvcHRpb25zLm9uU3RkZXJyKSBleGVjdXRpb24uc3RkZXJyLm9uKFwiZGF0YVwiLCAoY2h1bms6IHN0cmluZykgPT4gb3B0aW9ucy5vblN0ZGVycj8uKGNodW5rKSk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhlY3V0aW9uLnJlc3VsdDtcbiAgICBjb25zdCBzdGRvdXQgPSByZXRhaW5Db21tYW5kT3V0cHV0KHJlc3VsdC5zdGRvdXQsIG9wdGlvbnMubWF4UmV0YWluZWRCeXRlcyk7XG4gICAgY29uc3Qgc3RkZXJyID0gcmV0YWluQ29tbWFuZE91dHB1dChyZXN1bHQuc3RkZXJyLCBvcHRpb25zLm1heFJldGFpbmVkQnl0ZXMpO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5yZXN1bHQsXG4gICAgICBzdGRvdXQ6IHN0ZG91dC52YWx1ZSxcbiAgICAgIHN0ZGVycjogc3RkZXJyLnZhbHVlLFxuICAgICAgLi4uKHN0ZG91dC5kcm9wcGVkQnl0ZXMgPiAwXG4gICAgICAgID8geyBzdGRvdXRUcnVuY2F0ZWQ6IHRydWUsIHN0ZG91dERyb3BwZWRCeXRlczogc3Rkb3V0LmRyb3BwZWRCeXRlcyB9XG4gICAgICAgIDoge30pLFxuICAgICAgLi4uKHN0ZGVyci5kcm9wcGVkQnl0ZXMgPiAwXG4gICAgICAgID8geyBzdGRlcnJUcnVuY2F0ZWQ6IHRydWUsIHN0ZGVyckRyb3BwZWRCeXRlczogc3RkZXJyLmRyb3BwZWRCeXRlcyB9XG4gICAgICAgIDoge30pLFxuICAgIH07XG4gIH1cblxuICAvKiogUmV0dXJucyB0aGUgY3VycmVudCBMYWtlYm94IHN0YXR1cyBpbiBNYXN0cmEncyBzYW5kYm94IHNoYXBlLiAqL1xuICBhc3luYyBnZXRJbmZvKCk6IFByb21pc2U8U2FuZGJveEluZm8+IHtcbiAgICBjb25zdCBzdW1tYXJ5ID0gYXdhaXQgdGhpcy5ydW50aW1lLnN1bW1hcnkodGhpcy5pZGVudGl0eSk7XG4gICAgdGhpcy5zdGF0dXMgPVxuICAgICAgc3VtbWFyeS5zdGF0dXMgPT09IFwibWlzc2luZ1wiIHx8IHN1bW1hcnkuc3RhdHVzID09PSBcInVua25vd25cIiA/IFwicGVuZGluZ1wiIDogc3VtbWFyeS5zdGF0dXM7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgcHJvdmlkZXI6IHRoaXMucHJvdmlkZXIsXG4gICAgICBzdGF0dXM6IHRoaXMuc3RhdHVzLFxuICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgwKSxcbiAgICAgIG1ldGFkYXRhOiB7IGxha2Vib3hJZDogc3VtbWFyeS5pZCwgdXNlcjogc3VtbWFyeS51c2VyLm5hbWUsIHNlcnZpY2VzOiBzdW1tYXJ5LnNlcnZpY2VzIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIGFnZW50IGluc3RydWN0aW9ucyBmb3Igc2VydmljZXMsIHJvdXRlcywgYW5kIGNvbW1hbmQgZXhlY3V0aW9uLiAqL1xuICBnZXRJbnN0cnVjdGlvbnMoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gSU5TVFJVQ1RJT05TO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJlcXVlc3Qtc2NvcGVkIE1hc3RyYSB3b3Jrc3BhY2UgcmVzb2x2ZXIgZm9yIHRoZSBhcHAgTGFrZWJveC5cbiAqXG4gKiBSZXNvbHV0aW9uIG5ldmVyIGNyZWF0ZXMgY29tcHV0ZTsgdGhlIGZpcnN0IGNvbW1hbmQgb3Igc2VydmljZSBkb2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGFrZWJveFdvcmtzcGFjZVNhbmRib3goXG4gIHJ1bnRpbWU6IExha2Vib3hSdW50aW1lLFxuICBvcHRpb25zOiBMYWtlYm94V29ya3NwYWNlU2FuZGJveE9wdGlvbnMgPSB7fSxcbik6IFdvcmtzcGFjZVNhbmRib3hSZXNvbHZlciB7XG4gIHJldHVybiBhc3luYyAoeyByZXF1ZXN0Q29udGV4dCB9KSA9PiB7XG4gICAgY29uc3QgdXNlciA9IHJlcXVlc3RDb250ZXh0LmdldChNQVNUUkFfVVNFUl9LRVkpIGFzIFVzZXIgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB0aHJvdyBDb25maWd1cmF0aW9uRXJyb3IucmVzb3VyY2VOb3RGb3VuZChcbiAgICAgICAgXCJMYWtlYm94IHVzZXIgY29udGV4dFwiLFxuICAgICAgICBcIkludm9rZSBDb2RlIE1vZGUgZnJvbSBhbiBhZ2VudCB0dXJuIHNlcnZlZCBieSB0aGUgTWFzdHJhIHBsdWdpbi5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgTGFrZWJveFdvcmtzcGFjZVNhbmRib3goXG4gICAgICBydW50aW1lLmNvbmZpZy5hcHBsaWNhdGlvbixcbiAgICAgIG9wdGlvbnMuZGlzcGxheU5hbWUgPz8gXCJMYWtlYm94XCIsXG4gICAgICBydW50aW1lLFxuICAgICAgdXNlci5pZCxcbiAgICApO1xuICB9O1xufVxuXG5mdW5jdGlvbiByZXRhaW5Db21tYW5kT3V0cHV0KFxuICBvdXRwdXQ6IHN0cmluZyxcbiAgbWF4UmV0YWluZWRCeXRlczogbnVtYmVyIHwgdW5kZWZpbmVkLFxuKTogeyB2YWx1ZTogc3RyaW5nOyBkcm9wcGVkQnl0ZXM6IG51bWJlciB9IHtcbiAgaWYgKG1heFJldGFpbmVkQnl0ZXMgPT09IHVuZGVmaW5lZCB8fCBtYXhSZXRhaW5lZEJ5dGVzID09PSBJbmZpbml0eSkge1xuICAgIHJldHVybiB7IHZhbHVlOiBvdXRwdXQsIGRyb3BwZWRCeXRlczogMCB9O1xuICB9XG4gIGNvbnN0IGxpbWl0ID0gTnVtYmVyLmlzRmluaXRlKG1heFJldGFpbmVkQnl0ZXMpID8gTWF0aC5tYXgoMCwgTWF0aC5mbG9vcihtYXhSZXRhaW5lZEJ5dGVzKSkgOiAwO1xuICBjb25zdCBieXRlcyA9IEJ1ZmZlci5mcm9tKG91dHB1dCk7XG4gIGlmIChieXRlcy5sZW5ndGggPD0gbGltaXQpIHJldHVybiB7IHZhbHVlOiBvdXRwdXQsIGRyb3BwZWRCeXRlczogMCB9O1xuICBsZXQgcmV0YWluZWRTdGFydCA9IGJ5dGVzLmxlbmd0aCAtIGxpbWl0O1xuICB3aGlsZSAocmV0YWluZWRTdGFydCA8IGJ5dGVzLmxlbmd0aCAmJiAoYnl0ZXNbcmV0YWluZWRTdGFydF0hICYgMHhjMCkgPT09IDB4ODApIHtcbiAgICByZXRhaW5lZFN0YXJ0Kys7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICB2YWx1ZTogYnl0ZXMuc3ViYXJyYXkocmV0YWluZWRTdGFydCkudG9TdHJpbmcoXCJ1dGY4XCIpLFxuICAgIGRyb3BwZWRCeXRlczogcmV0YWluZWRTdGFydCxcbiAgfTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/_package.ts","../src/_resource-registry.ts","../src/_service-snapshots.ts","../src/config.ts","../src/desktop.ts","../src/metrics.ts","../src/plugin.ts","../src/routes.ts","../src/runtime.ts","../src/services.ts","../src/skills.ts","../src/user.ts","../src/workspace.ts","../index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,169 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbx-tools/appkit-lakebox",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"description": "AppKit plugin, user services, routes, metrics, and Mastra tools for one app Lakebox",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/reggie-db/dbx-tools.git",
|
|
7
|
+
"directory": "packages/js/node/appkit-lakebox"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "projen build",
|
|
11
|
+
"compile": "projen compile",
|
|
12
|
+
"default": "projen default",
|
|
13
|
+
"package": "projen package",
|
|
14
|
+
"post-compile": "projen post-compile",
|
|
15
|
+
"pre-compile": "projen pre-compile",
|
|
16
|
+
"prepack": "projen prepack",
|
|
17
|
+
"test": "projen test",
|
|
18
|
+
"watch": "projen watch",
|
|
19
|
+
"projen": "projen"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@dbx-tools/auth": "^0.9.131",
|
|
23
|
+
"@types/express": "^5.0.5",
|
|
24
|
+
"@types/json-schema": "^7",
|
|
25
|
+
"@types/node": "^24.6.0",
|
|
26
|
+
"express": "^5.1.0",
|
|
27
|
+
"typescript": "^5.9.3",
|
|
28
|
+
"vitest": "3.2.4"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@databricks/appkit": "0.81.0",
|
|
32
|
+
"@dbx-tools/appkit": "^0.9.131",
|
|
33
|
+
"@dbx-tools/appkit-mastra": "^0.9.131",
|
|
34
|
+
"@dbx-tools/core": "^0.9.131",
|
|
35
|
+
"@dbx-tools/lakebox": "^0.9.131",
|
|
36
|
+
"@dbx-tools/postgres": "^0.9.131",
|
|
37
|
+
"@dbx-tools/shared-core": "^0.9.131",
|
|
38
|
+
"@dbx-tools/shared-lakebox": "^0.9.131",
|
|
39
|
+
"@dbx-tools/ui": "^0.9.131",
|
|
40
|
+
"@mastra/core": "1.71.0",
|
|
41
|
+
"http-proxy-3": "^1.23.1",
|
|
42
|
+
"zod": "4.3.6"
|
|
43
|
+
},
|
|
44
|
+
"main": "./lib/index.js",
|
|
45
|
+
"license": "Apache-2.0",
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public",
|
|
48
|
+
"main": "./lib/index.js",
|
|
49
|
+
"types": "./lib/index.d.ts",
|
|
50
|
+
"exports": {
|
|
51
|
+
".": {
|
|
52
|
+
"types": "./lib/index.d.ts",
|
|
53
|
+
"default": "./lib/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./config": {
|
|
56
|
+
"types": "./lib/src/config.d.ts",
|
|
57
|
+
"default": "./lib/src/config.js"
|
|
58
|
+
},
|
|
59
|
+
"./desktop": {
|
|
60
|
+
"types": "./lib/src/desktop.d.ts",
|
|
61
|
+
"default": "./lib/src/desktop.js"
|
|
62
|
+
},
|
|
63
|
+
"./metrics": {
|
|
64
|
+
"types": "./lib/src/metrics.d.ts",
|
|
65
|
+
"default": "./lib/src/metrics.js"
|
|
66
|
+
},
|
|
67
|
+
"./plugin": {
|
|
68
|
+
"types": "./lib/src/plugin.d.ts",
|
|
69
|
+
"default": "./lib/src/plugin.js"
|
|
70
|
+
},
|
|
71
|
+
"./routes": {
|
|
72
|
+
"types": "./lib/src/routes.d.ts",
|
|
73
|
+
"default": "./lib/src/routes.js"
|
|
74
|
+
},
|
|
75
|
+
"./runtime": {
|
|
76
|
+
"types": "./lib/src/runtime.d.ts",
|
|
77
|
+
"default": "./lib/src/runtime.js"
|
|
78
|
+
},
|
|
79
|
+
"./services": {
|
|
80
|
+
"types": "./lib/src/services.d.ts",
|
|
81
|
+
"default": "./lib/src/services.js"
|
|
82
|
+
},
|
|
83
|
+
"./skills": {
|
|
84
|
+
"types": "./lib/src/skills.d.ts",
|
|
85
|
+
"default": "./lib/src/skills.js"
|
|
86
|
+
},
|
|
87
|
+
"./user": {
|
|
88
|
+
"types": "./lib/src/user.d.ts",
|
|
89
|
+
"default": "./lib/src/user.js"
|
|
90
|
+
},
|
|
91
|
+
"./workspace": {
|
|
92
|
+
"types": "./lib/src/workspace.d.ts",
|
|
93
|
+
"default": "./lib/src/workspace.js"
|
|
94
|
+
},
|
|
95
|
+
"./*": {
|
|
96
|
+
"types": "./lib/src/*/index.d.ts",
|
|
97
|
+
"default": "./lib/src/*/index.js"
|
|
98
|
+
},
|
|
99
|
+
"./package.json": "./package.json"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"version": "0.9.131",
|
|
103
|
+
"types": "./lib/index.d.ts",
|
|
104
|
+
"dbxToolsConfig": {
|
|
105
|
+
"tags": [
|
|
106
|
+
"node"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
"type": "module",
|
|
110
|
+
"exports": {
|
|
111
|
+
".": {
|
|
112
|
+
"types": "./lib/index.d.ts",
|
|
113
|
+
"default": "./lib/index.js"
|
|
114
|
+
},
|
|
115
|
+
"./config": {
|
|
116
|
+
"types": "./lib/src/config.d.ts",
|
|
117
|
+
"default": "./lib/src/config.js"
|
|
118
|
+
},
|
|
119
|
+
"./desktop": {
|
|
120
|
+
"types": "./lib/src/desktop.d.ts",
|
|
121
|
+
"default": "./lib/src/desktop.js"
|
|
122
|
+
},
|
|
123
|
+
"./metrics": {
|
|
124
|
+
"types": "./lib/src/metrics.d.ts",
|
|
125
|
+
"default": "./lib/src/metrics.js"
|
|
126
|
+
},
|
|
127
|
+
"./plugin": {
|
|
128
|
+
"types": "./lib/src/plugin.d.ts",
|
|
129
|
+
"default": "./lib/src/plugin.js"
|
|
130
|
+
},
|
|
131
|
+
"./routes": {
|
|
132
|
+
"types": "./lib/src/routes.d.ts",
|
|
133
|
+
"default": "./lib/src/routes.js"
|
|
134
|
+
},
|
|
135
|
+
"./runtime": {
|
|
136
|
+
"types": "./lib/src/runtime.d.ts",
|
|
137
|
+
"default": "./lib/src/runtime.js"
|
|
138
|
+
},
|
|
139
|
+
"./services": {
|
|
140
|
+
"types": "./lib/src/services.d.ts",
|
|
141
|
+
"default": "./lib/src/services.js"
|
|
142
|
+
},
|
|
143
|
+
"./skills": {
|
|
144
|
+
"types": "./lib/src/skills.d.ts",
|
|
145
|
+
"default": "./lib/src/skills.js"
|
|
146
|
+
},
|
|
147
|
+
"./user": {
|
|
148
|
+
"types": "./lib/src/user.d.ts",
|
|
149
|
+
"default": "./lib/src/user.js"
|
|
150
|
+
},
|
|
151
|
+
"./workspace": {
|
|
152
|
+
"types": "./lib/src/workspace.d.ts",
|
|
153
|
+
"default": "./lib/src/workspace.js"
|
|
154
|
+
},
|
|
155
|
+
"./*": {
|
|
156
|
+
"types": "./lib/src/*/index.d.ts",
|
|
157
|
+
"default": "./lib/src/*/index.js"
|
|
158
|
+
},
|
|
159
|
+
"./package.json": "./package.json"
|
|
160
|
+
},
|
|
161
|
+
"files": [
|
|
162
|
+
"index.ts",
|
|
163
|
+
"src",
|
|
164
|
+
"skills",
|
|
165
|
+
"scripts",
|
|
166
|
+
"lib"
|
|
167
|
+
],
|
|
168
|
+
"//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"bunx projen\"."
|
|
169
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
kasmvnc_version=1.5.0
|
|
5
|
+
kasmvnc_package_version="$kasmvnc_version-1"
|
|
6
|
+
installed_kasmvnc=$(dpkg-query -W -f='${Version}' kasmvncserver 2>/dev/null || true)
|
|
7
|
+
missing=false
|
|
8
|
+
for command in startxfce4 xfce4-panel xfdesktop xfwm4 xfce4-terminal \
|
|
9
|
+
rsvg-convert dbus-run-session epiphany exo-open; do
|
|
10
|
+
command -v "$command" >/dev/null 2>&1 || missing=true
|
|
11
|
+
done
|
|
12
|
+
for package in arc-theme hicolor-icon-theme xfce4-whiskermenu-plugin; do
|
|
13
|
+
dpkg-query -W -f='${Status}' "$package" 2>/dev/null |
|
|
14
|
+
grep -q 'install ok installed' || missing=true
|
|
15
|
+
done
|
|
16
|
+
if [ "$missing" = false ] && [ "$installed_kasmvnc" = "$kasmvnc_package_version" ]; then
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
command -v apt-get >/dev/null 2>&1
|
|
21
|
+
test -r /etc/os-release
|
|
22
|
+
. /etc/os-release
|
|
23
|
+
codename="$VERSION_CODENAME"
|
|
24
|
+
architecture=$(dpkg --print-architecture)
|
|
25
|
+
package_target="$codename-$architecture"
|
|
26
|
+
case "$package_target" in
|
|
27
|
+
focal-amd64) package_checksum="a2951daaa48aa52d09c04a0c6438ab43fe2e7d420485b1bfc36253772799c83c" ;;
|
|
28
|
+
focal-arm64) package_checksum="d0188b4e65706f5143fcb000bb29e97d90a3848e7290c9155f7df20585957558" ;;
|
|
29
|
+
jammy-amd64) package_checksum="485c190b1d9269fc40fc7205f850ecf71292d737cdb5482e778f2e52f128cd8a" ;;
|
|
30
|
+
jammy-arm64) package_checksum="9b21779ee16e514bccd2971dcb3983cd8019a94c8614149dbd717d3702c8dbb5" ;;
|
|
31
|
+
noble-amd64) package_checksum="f599fe02e2175b9817b6165f74a5d2bebdc73118dde9181ba3410963bed7ae1e" ;;
|
|
32
|
+
noble-arm64) package_checksum="c9199cf4753208bfb69fd016a9780242bebfc43370cc38c97d61e90a3c783e04" ;;
|
|
33
|
+
*) exit 2 ;;
|
|
34
|
+
esac
|
|
35
|
+
|
|
36
|
+
package_name="kasmvncserver_${codename}_${kasmvnc_version}_$architecture.deb"
|
|
37
|
+
cache=/home/sandbox-agent/.dbx-tools/runtime/cache
|
|
38
|
+
package_file="$cache/$package_name"
|
|
39
|
+
temporary="$package_file.tmp.$$"
|
|
40
|
+
install -d -m 0700 "$cache"
|
|
41
|
+
if ! printf '%s %s\n' "$package_checksum" "$package_file" |
|
|
42
|
+
sha256sum --check --status 2>/dev/null; then
|
|
43
|
+
PACKAGE_URL="https://github.com/kasmtech/KasmVNC/releases/download/v${kasmvnc_version}/$package_name" \
|
|
44
|
+
PACKAGE_DESTINATION="$temporary" python3 - <<'PY'
|
|
45
|
+
import os
|
|
46
|
+
import urllib.request
|
|
47
|
+
|
|
48
|
+
request = urllib.request.Request(
|
|
49
|
+
os.environ["PACKAGE_URL"],
|
|
50
|
+
headers={"User-Agent": "dbx-tools-appkit-lakebox"},
|
|
51
|
+
)
|
|
52
|
+
with urllib.request.urlopen(request) as response:
|
|
53
|
+
with open(os.environ["PACKAGE_DESTINATION"], "wb") as destination:
|
|
54
|
+
while chunk := response.read(1024 * 1024):
|
|
55
|
+
destination.write(chunk)
|
|
56
|
+
PY
|
|
57
|
+
printf '%s %s\n' "$package_checksum" "$temporary" | sha256sum --check --status
|
|
58
|
+
mv -f -- "$temporary" "$package_file"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
apt-get update
|
|
62
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
|
63
|
+
arc-theme ca-certificates dbus-daemon dbus-x11 epiphany-browser exo-utils \
|
|
64
|
+
fonts-dejavu-core hicolor-icon-theme librsvg2-bin thunar \
|
|
65
|
+
xfce4-whiskermenu-plugin x11-utils x11-xserver-utils xdg-utils xfce4-panel \
|
|
66
|
+
xfce4-session xfce4-settings xfce4-terminal xfdesktop4 xfwm4 "$package_file"
|