plum-e2e 2.8.6 → 2.9.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/README.md +20 -19
- package/backend/_scaffold/utils/browser.ts +7 -63
- package/backend/_scaffold/utils/hooks.ts +5 -20
- package/backend/app.js +0 -5
- package/backend/config/scripts/generate-report.js +2 -2
- package/backend/config/scripts/run-tests.js +5 -1
- package/backend/constants/socketEvents.js +7 -4
- package/backend/lib/plumTestRuntime.js +262 -0
- package/backend/lib/reportFilename.js +1 -2
- package/backend/lib/{screenshotPoller.js → rrwebPoller.js} +7 -4
- package/backend/lib/serverBootstrap.js +14 -0
- package/backend/logs/runner-cmtbz5b1l0000mr0110b27w5k.log +8 -0
- package/backend/mcp/server.js +3 -47
- package/backend/package-lock.json +199 -1
- package/backend/package.json +3 -1
- package/backend/prisma/migrations/20260828120000_add_recording_and_split_runner_worker_count/migration.sql +39 -0
- package/backend/prisma/migrations/20260828140000_add_recording_started_ended_at/migration.sql +5 -0
- package/backend/prisma/migrations/20260828150000_strip_screenshot_refs_from_reports/migration.sql +34 -0
- package/backend/prisma/migrations/20260828160000_add_backup_include_reports/migration.sql +4 -0
- package/backend/prisma/schema.prisma +97 -70
- package/backend/routes/backup.routes.js +47 -1
- package/backend/routes/reports.routes.js +23 -0
- package/backend/server.js +1 -1
- package/backend/services/backupCronService.js +1 -1
- package/backend/services/backupService.js +134 -44
- package/backend/services/cronService.js +23 -15
- package/backend/services/nodeExecutionService.js +41 -15
- package/backend/services/nodeStreamRegistry.js +24 -0
- package/backend/services/reportService.js +167 -83
- package/backend/services/runnerService.js +19 -7
- package/backend/services/settingsService.js +6 -3
- package/backend/services/triggerService.js +20 -13
- package/backend/websockets/nodeSocketHandler.js +40 -0
- package/backend/websockets/socketHandler.js +9 -7
- package/bin/plum.js +58 -1
- package/frontend/.svelte-kit/ambient.d.ts +28 -28
- package/frontend/.svelte-kit/generated/server/internal.js +1 -1
- package/frontend/package-lock.json +121 -32
- package/frontend/package.json +1 -0
- package/frontend/src/lib/api/reports.js +13 -4
- package/frontend/src/lib/api/settings.js +16 -1
- package/frontend/src/lib/components/layout/RunnerPanel.svelte +9 -24
- package/frontend/src/lib/components/reports/ElementInspector.svelte +141 -0
- package/frontend/src/lib/components/reports/LiveReplayer.svelte +110 -0
- package/frontend/src/lib/components/reports/MultiTabTimeline.svelte +115 -0
- package/frontend/src/lib/components/reports/RecordingPlayer.svelte +786 -0
- package/frontend/src/lib/components/reports/StepsRail.svelte +109 -0
- package/frontend/src/lib/components/ui/CodeViewer.svelte +61 -0
- package/frontend/src/lib/constants.js +0 -1
- package/frontend/src/lib/copy/reports.js +18 -8
- package/frontend/src/lib/copy/settings.js +25 -4
- package/frontend/src/lib/socketEvents.js +7 -4
- package/frontend/src/lib/stores/runner.js +26 -3
- package/frontend/src/lib/styles/tokens.css +7 -0
- package/frontend/src/lib/utils/format.js +108 -2
- package/frontend/src/lib/utils/inspectElement.js +34 -0
- package/frontend/src/routes/reports/+page.svelte +79 -1
- package/frontend/src/routes/reports/[id]/+page.svelte +304 -495
- package/frontend/src/routes/reports/live/+page.svelte +236 -260
- package/frontend/src/routes/settings/+page.svelte +246 -8
- package/package.json +1 -1
- package/backend/playwright.config.js +0 -85
|
@@ -8,8 +8,8 @@ const fs = require('fs');
|
|
|
8
8
|
const os = require('os');
|
|
9
9
|
const { spawn } = require('child_process');
|
|
10
10
|
const { randomUUID } = require('crypto');
|
|
11
|
-
const {
|
|
12
|
-
const { TRIGGER_TYPE } = require('../constants/triggers');
|
|
11
|
+
const { startRRwebPoller } = require('../lib/rrwebPoller');
|
|
12
|
+
const { TRIGGER_TYPE, BUILT_IN_RUNNER_ID } = require('../constants/triggers');
|
|
13
13
|
const { DEFAULT_BROWSER } = require('../constants/defaults');
|
|
14
14
|
const { PLUM_MODE_NODE } = require('../constants/env');
|
|
15
15
|
const { SOCKET_EVENTS } = require('../constants/socketEvents');
|
|
@@ -52,7 +52,7 @@ function runAttempt({
|
|
|
52
52
|
baseUrl,
|
|
53
53
|
suppressSave,
|
|
54
54
|
onLog,
|
|
55
|
-
|
|
55
|
+
onRRwebBatch
|
|
56
56
|
}) {
|
|
57
57
|
return new Promise((resolve) => {
|
|
58
58
|
const ssDir = path.join(os.tmpdir(), `plum-trigger-ss-${jobId}-${Date.now()}`);
|
|
@@ -73,7 +73,7 @@ function runAttempt({
|
|
|
73
73
|
|
|
74
74
|
const proc = spawn('npm', ['run', 'test'], { env, shell: true, cwd: BACKEND_DIR });
|
|
75
75
|
|
|
76
|
-
const ssPoller =
|
|
76
|
+
const ssPoller = startRRwebPoller(ssDir, onRRwebBatch);
|
|
77
77
|
|
|
78
78
|
proc.stdout.on('data', (d) => onLog(d.toString()));
|
|
79
79
|
proc.stderr.on('data', (d) => onLog(`[ERROR] ${d.toString()}`));
|
|
@@ -96,7 +96,7 @@ function runNoRetry({
|
|
|
96
96
|
baseUrl,
|
|
97
97
|
startedAt,
|
|
98
98
|
onLog,
|
|
99
|
-
|
|
99
|
+
onRRwebBatch
|
|
100
100
|
}) {
|
|
101
101
|
runAttempt({
|
|
102
102
|
jobId,
|
|
@@ -108,7 +108,7 @@ function runNoRetry({
|
|
|
108
108
|
baseUrl,
|
|
109
109
|
suppressSave: false,
|
|
110
110
|
onLog,
|
|
111
|
-
|
|
111
|
+
onRRwebBatch
|
|
112
112
|
}).then(async ({ code }) => {
|
|
113
113
|
let reportId = null;
|
|
114
114
|
try {
|
|
@@ -142,7 +142,7 @@ function runWithRetriesAndSave({
|
|
|
142
142
|
maxRetries,
|
|
143
143
|
startedAt,
|
|
144
144
|
onLog,
|
|
145
|
-
|
|
145
|
+
onRRwebBatch
|
|
146
146
|
}) {
|
|
147
147
|
runWithRetries({
|
|
148
148
|
maxRetries,
|
|
@@ -157,7 +157,7 @@ function runWithRetriesAndSave({
|
|
|
157
157
|
baseUrl,
|
|
158
158
|
suppressSave: true,
|
|
159
159
|
onLog,
|
|
160
|
-
|
|
160
|
+
onRRwebBatch
|
|
161
161
|
});
|
|
162
162
|
return { code, rawJson: raw ? JSON.parse(raw) : [] };
|
|
163
163
|
},
|
|
@@ -169,6 +169,7 @@ function runWithRetriesAndSave({
|
|
|
169
169
|
rawCucumberJson: rawJson,
|
|
170
170
|
tags: tag,
|
|
171
171
|
triggerType: trigger,
|
|
172
|
+
workerCount: workers,
|
|
172
173
|
browser,
|
|
173
174
|
testRunId: testRunId ?? null,
|
|
174
175
|
duration: Date.now() - startedAt,
|
|
@@ -191,8 +192,8 @@ function runWithRetriesAndSave({
|
|
|
191
192
|
|
|
192
193
|
// Starts a background test run for the HTTP trigger API and returns the jobId
|
|
193
194
|
// immediately — the run continues asynchronously, reporting progress via
|
|
194
|
-
// socket.io events (bg-run-start/log/
|
|
195
|
-
//
|
|
195
|
+
// socket.io events (bg-run-start/log/done) and the job store (polled through
|
|
196
|
+
// getJob).
|
|
196
197
|
async function startRun({
|
|
197
198
|
tag = '',
|
|
198
199
|
browser = DEFAULT_BROWSER,
|
|
@@ -218,8 +219,14 @@ async function startRun({
|
|
|
218
219
|
const onLog = (text) => {
|
|
219
220
|
if (_io) _io.emit(SOCKET_EVENTS.BG_RUN_LOG, { runId: jobId, log: text });
|
|
220
221
|
};
|
|
221
|
-
const
|
|
222
|
-
if (_io)
|
|
222
|
+
const onRRwebBatch = (batch) => {
|
|
223
|
+
if (_io) {
|
|
224
|
+
_io.emit(SOCKET_EVENTS.BG_RUN_LANE_RRWEB_BATCH, {
|
|
225
|
+
runId: jobId,
|
|
226
|
+
id: BUILT_IN_RUNNER_ID,
|
|
227
|
+
...batch
|
|
228
|
+
});
|
|
229
|
+
}
|
|
223
230
|
};
|
|
224
231
|
|
|
225
232
|
const runParams = {
|
|
@@ -232,7 +239,7 @@ async function startRun({
|
|
|
232
239
|
baseUrl,
|
|
233
240
|
startedAt,
|
|
234
241
|
onLog,
|
|
235
|
-
|
|
242
|
+
onRRwebBatch
|
|
236
243
|
};
|
|
237
244
|
if (maxRetries === 0) {
|
|
238
245
|
runNoRetry(runParams);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of Plum.
|
|
3
|
+
* Licensed under the MIT License. See LICENSE file in the project root for details.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const runnerService = require('../services/runnerService');
|
|
7
|
+
const nodeStreamRegistry = require('../services/nodeStreamRegistry');
|
|
8
|
+
|
|
9
|
+
// A separate namespace from the browser-facing default one — a node connects
|
|
10
|
+
// with its own runner token (the same credential it already uses to call back
|
|
11
|
+
// into the primary's HTTP control routes, see runnerService.isValidToken) and
|
|
12
|
+
// announces the jobId it's streaming for, which nodeStreamRegistry maps back
|
|
13
|
+
// to whichever dispatch call is waiting on it.
|
|
14
|
+
function nodeSocketHandler(io) {
|
|
15
|
+
const nodeIo = io.of('/node-stream');
|
|
16
|
+
|
|
17
|
+
nodeIo.use(async (socket, next) => {
|
|
18
|
+
const token = socket.handshake.auth?.token;
|
|
19
|
+
if (await runnerService.isValidToken(token)) return next();
|
|
20
|
+
next(new Error('unauthorized'));
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
nodeIo.on('connection', (socket) => {
|
|
24
|
+
let jobId = null;
|
|
25
|
+
|
|
26
|
+
socket.on('join', (id) => {
|
|
27
|
+
jobId = id;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
socket.on('rrweb-batch', (batch) => {
|
|
31
|
+
if (jobId) nodeStreamRegistry.getRelay(jobId)?.onRRwebBatch?.(batch);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
socket.on('log', (text) => {
|
|
35
|
+
if (jobId) nodeStreamRegistry.getRelay(jobId)?.onLog?.(text);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = nodeSocketHandler;
|
|
@@ -13,7 +13,7 @@ const reportService = require('../services/reportService');
|
|
|
13
13
|
const settingsService = require('../services/settingsService');
|
|
14
14
|
const notificationService = require('../services/notificationService');
|
|
15
15
|
const activeRunsService = require('../services/activeRunsService');
|
|
16
|
-
const {
|
|
16
|
+
const { startRRwebPoller } = require('../lib/rrwebPoller');
|
|
17
17
|
const { runWithRetries } = require('../lib/retryRunner');
|
|
18
18
|
const { TRIGGER_TYPE, BUILT_IN_RUNNER_ID, TRIGGER_REMOTE } = require('../constants/triggers');
|
|
19
19
|
const { DEFAULT_BROWSER } = require('../constants/defaults');
|
|
@@ -243,8 +243,8 @@ function runBuiltInAttempt({
|
|
|
243
243
|
const proc = spawn('npm', ['run', 'test'], { env, shell: true });
|
|
244
244
|
activeProcs.add(proc);
|
|
245
245
|
|
|
246
|
-
const ssPoller =
|
|
247
|
-
socket.emit(SOCKET_EVENTS.
|
|
246
|
+
const ssPoller = startRRwebPoller(ssDir, (batch) => {
|
|
247
|
+
socket.emit(SOCKET_EVENTS.RUNNER_LANE_RRWEB_BATCH, { id: BUILT_IN_RUNNER_ID, ...batch });
|
|
248
248
|
});
|
|
249
249
|
|
|
250
250
|
proc.stdout.on('data', (d) => onLog(d.toString()));
|
|
@@ -362,6 +362,7 @@ async function runBuiltIn(
|
|
|
362
362
|
rawCucumberJson: rawJson,
|
|
363
363
|
tags: tag,
|
|
364
364
|
triggerType: TRIGGER_TYPE.MANUAL,
|
|
365
|
+
workerCount: workers,
|
|
365
366
|
browser,
|
|
366
367
|
testRunId: testRunId ?? null,
|
|
367
368
|
logs: logBuffer || null,
|
|
@@ -468,6 +469,7 @@ async function runDistributed(
|
|
|
468
469
|
.saveCombinedReport({
|
|
469
470
|
reports: collectedReports,
|
|
470
471
|
runners: laneInfos,
|
|
472
|
+
workers,
|
|
471
473
|
overallCode,
|
|
472
474
|
tag,
|
|
473
475
|
triggerType: TRIGGER_TYPE.MANUAL,
|
|
@@ -543,8 +545,8 @@ async function runDistributed(
|
|
|
543
545
|
const proc = spawn('npm', ['run', 'test'], { env, shell: true });
|
|
544
546
|
activeProcs.add(proc);
|
|
545
547
|
|
|
546
|
-
const ssPoller =
|
|
547
|
-
socket.emit(SOCKET_EVENTS.
|
|
548
|
+
const ssPoller = startRRwebPoller(ssDir, (batch) => {
|
|
549
|
+
socket.emit(SOCKET_EVENTS.RUNNER_LANE_RRWEB_BATCH, { id: laneId, ...batch });
|
|
548
550
|
});
|
|
549
551
|
|
|
550
552
|
proc.stdout.on('data', (d) => onLog(d.toString()));
|
|
@@ -588,8 +590,8 @@ async function runDistributed(
|
|
|
588
590
|
makeSyntheticFailReport(lane.name, chunkIds, 'could not fetch report from runner');
|
|
589
591
|
resolve({ code, rawJson: JSON.parse(raw) });
|
|
590
592
|
},
|
|
591
|
-
(
|
|
592
|
-
socket.emit(SOCKET_EVENTS.
|
|
593
|
+
(batch) => {
|
|
594
|
+
socket.emit(SOCKET_EVENTS.RUNNER_LANE_RRWEB_BATCH, { id: laneId, ...batch });
|
|
593
595
|
}
|
|
594
596
|
);
|
|
595
597
|
});
|
package/bin/plum.js
CHANGED
|
@@ -62,6 +62,48 @@ function scaffoldPluginsFile() {
|
|
|
62
62
|
clack.log.success('plum.plugins.json created.');
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
// Files under tests/ that are Plum's own wiring rather than customer content —
|
|
66
|
+
// `plum init` only writes these once, so a project scaffolded before a Plum
|
|
67
|
+
// upgrade keeps running whatever version shipped at init time (e.g. an old
|
|
68
|
+
// screenshot-based browser.ts after Plum has moved to rrweb recording) unless
|
|
69
|
+
// something explicitly re-syncs them. Never touches customer-owned files
|
|
70
|
+
// (features/, pages/, step_definitions/, utils/constants.ts, utils/utils.ts).
|
|
71
|
+
const INFRA_SCAFFOLD_FILES = ['utils/browser.ts', 'utils/hooks.ts'];
|
|
72
|
+
|
|
73
|
+
// Re-syncs INFRA_SCAFFOLD_FILES from the installed Plum version's scaffold
|
|
74
|
+
// into an existing tests/ directory, backing up anything it overwrites so a
|
|
75
|
+
// customer's own edits to these files (unsupported, but possible) aren't
|
|
76
|
+
// silently lost.
|
|
77
|
+
function syncScaffoldInfraFiles(testsDir) {
|
|
78
|
+
if (!fs.existsSync(testsDir)) {
|
|
79
|
+
clack.log.warn(`No \`tests/\` folder found at ${testsDir} — skipping scaffold sync.`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let updated = 0;
|
|
84
|
+
for (const relPath of INFRA_SCAFFOLD_FILES) {
|
|
85
|
+
const src = path.join(scaffoldTestsPath, relPath);
|
|
86
|
+
const dest = path.join(testsDir, relPath);
|
|
87
|
+
if (!fs.existsSync(src) || !fs.existsSync(dest)) continue;
|
|
88
|
+
|
|
89
|
+
const current = fs.readFileSync(dest, 'utf8');
|
|
90
|
+
const latest = fs.readFileSync(src, 'utf8');
|
|
91
|
+
if (current === latest) continue;
|
|
92
|
+
|
|
93
|
+
const backupPath = `${dest}.bak-${Date.now()}`;
|
|
94
|
+
fs.copyFileSync(dest, backupPath);
|
|
95
|
+
fs.copyFileSync(src, dest);
|
|
96
|
+
updated++;
|
|
97
|
+
clack.log.success(
|
|
98
|
+
`Updated ${relPath} (previous version backed up to ${path.basename(backupPath)})`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (updated === 0) {
|
|
103
|
+
clack.log.info('Test scaffold wiring is already up to date.');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
65
107
|
// Install user plugins listed in plum.plugins.json into the backend
|
|
66
108
|
function installPlugins() {
|
|
67
109
|
const pluginsPath = path.join(process.cwd(), 'plum.plugins.json');
|
|
@@ -511,6 +553,9 @@ async function serverUpdate() {
|
|
|
511
553
|
// logic no matter how new the just-installed files on disk actually are.
|
|
512
554
|
for (const dir of getInstalls('server')) {
|
|
513
555
|
if (!fs.existsSync(path.join(dir, '.plum-server.json'))) continue;
|
|
556
|
+
if (fs.existsSync(path.join(dir, 'tests'))) {
|
|
557
|
+
syncScaffoldInfraFiles(path.join(dir, 'tests'));
|
|
558
|
+
}
|
|
514
559
|
clack.log.step(`Rebuilding server at ${dir}…`);
|
|
515
560
|
try {
|
|
516
561
|
execSync('plum server restart', { stdio: 'inherit', cwd: dir });
|
|
@@ -523,6 +568,9 @@ async function serverUpdate() {
|
|
|
523
568
|
for (const dir of getInstalls('node')) {
|
|
524
569
|
const nodeCfg = loadNodeConfig(dir);
|
|
525
570
|
if (!nodeCfg.id) continue;
|
|
571
|
+
if (fs.existsSync(path.join(dir, 'tests'))) {
|
|
572
|
+
syncScaffoldInfraFiles(path.join(dir, 'tests'));
|
|
573
|
+
}
|
|
526
574
|
// Always attempt the restart rather than gating on the local PID
|
|
527
575
|
// registry: that registry goes stale (manager restarts, pre-existing
|
|
528
576
|
// installs from before this tracking existed, etc.), and skipping the
|
|
@@ -1093,6 +1141,12 @@ switch (command) {
|
|
|
1093
1141
|
await serverUpdate();
|
|
1094
1142
|
break;
|
|
1095
1143
|
|
|
1144
|
+
case 'sync-scaffold':
|
|
1145
|
+
clack.intro(pc.bgMagenta(pc.white(' 🟣 Plum — Sync Test Scaffold ')));
|
|
1146
|
+
syncScaffoldInfraFiles(userTestsPath);
|
|
1147
|
+
clack.outro(pc.green('Done.'));
|
|
1148
|
+
break;
|
|
1149
|
+
|
|
1096
1150
|
case 'run-test': {
|
|
1097
1151
|
const runHelpArgs = process.argv.slice(3);
|
|
1098
1152
|
if (anyFlags(runHelpArgs, ['--help', '-h'])) {
|
|
@@ -1299,7 +1353,10 @@ switch (command) {
|
|
|
1299
1353
|
console.log(' server stop Stop the server (data preserved)');
|
|
1300
1354
|
console.log(' server reconfig Re-enter server settings without starting');
|
|
1301
1355
|
console.log(
|
|
1302
|
-
' update Update Plum
|
|
1356
|
+
' update Update Plum, restart whichever is running (server/node), and re-sync tests/ wiring'
|
|
1357
|
+
);
|
|
1358
|
+
console.log(
|
|
1359
|
+
' sync-scaffold Re-sync browser.ts/hooks.ts in tests/ from the installed Plum version'
|
|
1303
1360
|
);
|
|
1304
1361
|
console.log(' node start Start a runner node (interactive), then open runner menu');
|
|
1305
1362
|
console.log(' --primary <url> Primary Plum server to auto-register with');
|
|
@@ -58,41 +58,42 @@ declare module '$env/static/private' {
|
|
|
58
58
|
export const VIKUNJA_API_KEY: string;
|
|
59
59
|
export const USER: string;
|
|
60
60
|
export const COMMAND_MODE: string;
|
|
61
|
-
export const npm_config_globalconfig: string;
|
|
62
61
|
export const OUTLINE_BASE_URL: string;
|
|
62
|
+
export const npm_config_globalconfig: string;
|
|
63
63
|
export const CLAUDE_CODE_SSE_PORT: string;
|
|
64
64
|
export const SSH_AUTH_SOCK: string;
|
|
65
65
|
export const VSCODE_PROFILE_INITIALIZED: string;
|
|
66
66
|
export const __CF_USER_TEXT_ENCODING: string;
|
|
67
67
|
export const npm_execpath: string;
|
|
68
68
|
export const PATH: string;
|
|
69
|
-
export const
|
|
69
|
+
export const npm_package_bin_plum: string;
|
|
70
70
|
export const npm_config_engine_strict: string;
|
|
71
71
|
export const _: string;
|
|
72
|
-
export const
|
|
73
|
-
export const npm_config_init_module: string;
|
|
72
|
+
export const npm_package_json: string;
|
|
74
73
|
export const USER_ZDOTDIR: string;
|
|
75
74
|
export const __CFBundleIdentifier: string;
|
|
76
|
-
export const
|
|
75
|
+
export const npm_config_init_module: string;
|
|
76
|
+
export const npm_config_userconfig: string;
|
|
77
77
|
export const PWD: string;
|
|
78
|
-
export const
|
|
79
|
-
export const EDITOR: string;
|
|
78
|
+
export const npm_command: string;
|
|
80
79
|
export const OUTLINE_API_KEY: string;
|
|
81
|
-
export const
|
|
80
|
+
export const EDITOR: string;
|
|
81
|
+
export const npm_lifecycle_event: string;
|
|
82
82
|
export const LANG: string;
|
|
83
|
-
export const
|
|
83
|
+
export const npm_package_name: string;
|
|
84
84
|
export const VSCODE_GIT_ASKPASS_EXTRA_ARGS: string;
|
|
85
85
|
export const XPC_FLAGS: string;
|
|
86
|
+
export const npm_config_npm_version: string;
|
|
86
87
|
export const npm_config_node_gyp: string;
|
|
87
|
-
export const npm_package_version: string;
|
|
88
88
|
export const XPC_SERVICE_NAME: string;
|
|
89
|
+
export const npm_package_version: string;
|
|
89
90
|
export const VSCODE_INJECTION: string;
|
|
90
91
|
export const SHLVL: string;
|
|
91
92
|
export const HOME: string;
|
|
92
93
|
export const VSCODE_GIT_ASKPASS_MAIN: string;
|
|
93
94
|
export const CLAUDE_CODE_EXECPATH: string;
|
|
94
|
-
export const npm_config_cache: string;
|
|
95
95
|
export const LOGNAME: string;
|
|
96
|
+
export const npm_config_cache: string;
|
|
96
97
|
export const npm_lifecycle_script: string;
|
|
97
98
|
export const VSCODE_GIT_IPC_HANDLE: string;
|
|
98
99
|
export const COREPACK_ENABLE_AUTO_PIN: string;
|
|
@@ -103,10 +104,9 @@ declare module '$env/static/private' {
|
|
|
103
104
|
export const OSLogRateLimit: string;
|
|
104
105
|
export const CLAUDECODE: string;
|
|
105
106
|
export const CLAUDE_CODE_MESSAGING_SOCKET: string;
|
|
106
|
-
export const npm_node_execpath: string;
|
|
107
|
-
export const npm_config_prefix: string;
|
|
108
107
|
export const COLORTERM: string;
|
|
109
|
-
export const
|
|
108
|
+
export const npm_config_prefix: string;
|
|
109
|
+
export const npm_node_execpath: string;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
/**
|
|
@@ -165,41 +165,42 @@ declare module '$env/dynamic/private' {
|
|
|
165
165
|
VIKUNJA_API_KEY: string;
|
|
166
166
|
USER: string;
|
|
167
167
|
COMMAND_MODE: string;
|
|
168
|
-
npm_config_globalconfig: string;
|
|
169
168
|
OUTLINE_BASE_URL: string;
|
|
169
|
+
npm_config_globalconfig: string;
|
|
170
170
|
CLAUDE_CODE_SSE_PORT: string;
|
|
171
171
|
SSH_AUTH_SOCK: string;
|
|
172
172
|
VSCODE_PROFILE_INITIALIZED: string;
|
|
173
173
|
__CF_USER_TEXT_ENCODING: string;
|
|
174
174
|
npm_execpath: string;
|
|
175
175
|
PATH: string;
|
|
176
|
-
|
|
176
|
+
npm_package_bin_plum: string;
|
|
177
177
|
npm_config_engine_strict: string;
|
|
178
178
|
_: string;
|
|
179
|
-
|
|
180
|
-
npm_config_init_module: string;
|
|
179
|
+
npm_package_json: string;
|
|
181
180
|
USER_ZDOTDIR: string;
|
|
182
181
|
__CFBundleIdentifier: string;
|
|
183
|
-
|
|
182
|
+
npm_config_init_module: string;
|
|
183
|
+
npm_config_userconfig: string;
|
|
184
184
|
PWD: string;
|
|
185
|
-
|
|
186
|
-
EDITOR: string;
|
|
185
|
+
npm_command: string;
|
|
187
186
|
OUTLINE_API_KEY: string;
|
|
188
|
-
|
|
187
|
+
EDITOR: string;
|
|
188
|
+
npm_lifecycle_event: string;
|
|
189
189
|
LANG: string;
|
|
190
|
-
|
|
190
|
+
npm_package_name: string;
|
|
191
191
|
VSCODE_GIT_ASKPASS_EXTRA_ARGS: string;
|
|
192
192
|
XPC_FLAGS: string;
|
|
193
|
+
npm_config_npm_version: string;
|
|
193
194
|
npm_config_node_gyp: string;
|
|
194
|
-
npm_package_version: string;
|
|
195
195
|
XPC_SERVICE_NAME: string;
|
|
196
|
+
npm_package_version: string;
|
|
196
197
|
VSCODE_INJECTION: string;
|
|
197
198
|
SHLVL: string;
|
|
198
199
|
HOME: string;
|
|
199
200
|
VSCODE_GIT_ASKPASS_MAIN: string;
|
|
200
201
|
CLAUDE_CODE_EXECPATH: string;
|
|
201
|
-
npm_config_cache: string;
|
|
202
202
|
LOGNAME: string;
|
|
203
|
+
npm_config_cache: string;
|
|
203
204
|
npm_lifecycle_script: string;
|
|
204
205
|
VSCODE_GIT_IPC_HANDLE: string;
|
|
205
206
|
COREPACK_ENABLE_AUTO_PIN: string;
|
|
@@ -210,10 +211,9 @@ declare module '$env/dynamic/private' {
|
|
|
210
211
|
OSLogRateLimit: string;
|
|
211
212
|
CLAUDECODE: string;
|
|
212
213
|
CLAUDE_CODE_MESSAGING_SOCKET: string;
|
|
213
|
-
npm_node_execpath: string;
|
|
214
|
-
npm_config_prefix: string;
|
|
215
214
|
COLORTERM: string;
|
|
216
|
-
|
|
215
|
+
npm_config_prefix: string;
|
|
216
|
+
npm_node_execpath: string;
|
|
217
217
|
[key: `PUBLIC_${string}`]: undefined;
|
|
218
218
|
[key: `${string}`]: string | undefined;
|
|
219
219
|
}
|
|
@@ -26,7 +26,7 @@ export const options = {
|
|
|
26
26
|
app: ({ head, body, assets, nonce, env }) => "<!--\nThis file is part of Plum.\nLicensed under the MIT License. See LICENSE file in the project root for details.\n-->\n<!doctype html>\n<html lang=\"en\" data-theme=\"light\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" href=\"" + assets + "/favicon.ico\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t\t<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n\t\t<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n\t\t<link\n\t\t\thref=\"https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500&family=DM+Sans:wght@300;400;500&display=swap\"\n\t\t\trel=\"stylesheet\"\n\t\t/>\n\t\t<!-- Prevent theme flash before Svelte hydrates -->\n\t\t<script>\n\t\t\ttry {\n\t\t\t\tconst t = localStorage.getItem('plum-theme');\n\t\t\t\tif (t) document.documentElement.setAttribute('data-theme', t);\n\t\t\t} catch (e) {}\n\t\t</script>\n\t\t" + head + "\n\t</head>\n\t<body data-sveltekit-preload-data=\"hover\">\n\t\t<div style=\"display: contents\">" + body + "</div>\n\t</body>\n</html>\n",
|
|
27
27
|
error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>" + message + "</title>\n\n\t\t<style>\n\t\t\tbody {\n\t\t\t\t--bg: white;\n\t\t\t\t--fg: #222;\n\t\t\t\t--divider: #ccc;\n\t\t\t\tbackground: var(--bg);\n\t\t\t\tcolor: var(--fg);\n\t\t\t\tfont-family:\n\t\t\t\t\tsystem-ui,\n\t\t\t\t\t-apple-system,\n\t\t\t\t\tBlinkMacSystemFont,\n\t\t\t\t\t'Segoe UI',\n\t\t\t\t\tRoboto,\n\t\t\t\t\tOxygen,\n\t\t\t\t\tUbuntu,\n\t\t\t\t\tCantarell,\n\t\t\t\t\t'Open Sans',\n\t\t\t\t\t'Helvetica Neue',\n\t\t\t\t\tsans-serif;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.error {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tmax-width: 32rem;\n\t\t\t\tmargin: 0 1rem;\n\t\t\t}\n\n\t\t\t.status {\n\t\t\t\tfont-weight: 200;\n\t\t\t\tfont-size: 3rem;\n\t\t\t\tline-height: 1;\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -0.05rem;\n\t\t\t}\n\n\t\t\t.message {\n\t\t\t\tborder-left: 1px solid var(--divider);\n\t\t\t\tpadding: 0 0 0 1rem;\n\t\t\t\tmargin: 0 0 0 1rem;\n\t\t\t\tmin-height: 2.5rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.message h1 {\n\t\t\t\tfont-weight: 400;\n\t\t\t\tfont-size: 1em;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\t--bg: #222;\n\t\t\t\t\t--fg: #ddd;\n\t\t\t\t\t--divider: #666;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"error\">\n\t\t\t<span class=\"status\">" + status + "</span>\n\t\t\t<div class=\"message\">\n\t\t\t\t<h1>" + message + "</h1>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>\n"
|
|
28
28
|
},
|
|
29
|
-
version_hash: "
|
|
29
|
+
version_hash: "19o4i41"
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
export async function get_hooks() {
|