@usepowerplant/cli 0.4.19 → 0.4.21
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 +1 -1
- package/dist/cli.js +450 -120
- package/dist/hooks/powerplant-cloud-capture.mjs +747 -0
- package/dist/menubar/Powerplant.app.zip +0 -0
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9ee35b05-7453-5338-85ff-5dc1b6010221")}catch(e){}}();
|
|
4
4
|
const __cliNodeMajor = Number(process.versions.node.split('.')[0]);
|
|
5
5
|
if (__cliNodeMajor < 20) {
|
|
6
6
|
console.error(`powerplant needs Node 20 or newer — this is Node ${process.versions.node}.`);
|
|
@@ -23886,7 +23886,7 @@ var require_mock_interceptor = __commonJS({
|
|
|
23886
23886
|
var require_mock_client = __commonJS({
|
|
23887
23887
|
"../../node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/mock/mock-client.js"(exports, module2) {
|
|
23888
23888
|
"use strict";
|
|
23889
|
-
var { promisify:
|
|
23889
|
+
var { promisify: promisify3 } = __require("node:util");
|
|
23890
23890
|
var Client2 = require_client();
|
|
23891
23891
|
var { buildMockDispatch } = require_mock_utils();
|
|
23892
23892
|
var {
|
|
@@ -23934,7 +23934,7 @@ var require_mock_client = __commonJS({
|
|
|
23934
23934
|
this[kDispatches] = [];
|
|
23935
23935
|
}
|
|
23936
23936
|
async [kClose]() {
|
|
23937
|
-
await
|
|
23937
|
+
await promisify3(this[kOriginalClose])();
|
|
23938
23938
|
this[kConnected] = 0;
|
|
23939
23939
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
23940
23940
|
}
|
|
@@ -24147,7 +24147,7 @@ var require_mock_call_history = __commonJS({
|
|
|
24147
24147
|
var require_mock_pool = __commonJS({
|
|
24148
24148
|
"../../node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/mock/mock-pool.js"(exports, module2) {
|
|
24149
24149
|
"use strict";
|
|
24150
|
-
var { promisify:
|
|
24150
|
+
var { promisify: promisify3 } = __require("node:util");
|
|
24151
24151
|
var Pool = require_pool();
|
|
24152
24152
|
var { buildMockDispatch } = require_mock_utils();
|
|
24153
24153
|
var {
|
|
@@ -24195,7 +24195,7 @@ var require_mock_pool = __commonJS({
|
|
|
24195
24195
|
this[kDispatches] = [];
|
|
24196
24196
|
}
|
|
24197
24197
|
async [kClose]() {
|
|
24198
|
-
await
|
|
24198
|
+
await promisify3(this[kOriginalClose])();
|
|
24199
24199
|
this[kConnected] = 0;
|
|
24200
24200
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
24201
24201
|
}
|
|
@@ -59131,30 +59131,99 @@ var SECRET_QUERY_PARAM_PATTERN = /^(?:token|access_token|refresh_token|id_token|
|
|
|
59131
59131
|
var BEARER_TOKEN_PATTERN = /\bBearer\s+[\w\-._~+/=]+/gi;
|
|
59132
59132
|
var JWT_PATTERN = /\b[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g;
|
|
59133
59133
|
var EMBEDDED_QUERY_SECRET_PATTERN = /([?&](?:token|access_token|refresh_token|id_token|api_key|apikey|key|code|signature|password|secret|client_secret|state)=)[^&\s#]+/gi;
|
|
59134
|
-
var URL_FIELD_NAMES = /* @__PURE__ */ new Set([
|
|
59134
|
+
var URL_FIELD_NAMES = /* @__PURE__ */ new Set([
|
|
59135
|
+
"url",
|
|
59136
|
+
"to",
|
|
59137
|
+
"from",
|
|
59138
|
+
"href",
|
|
59139
|
+
"request_url",
|
|
59140
|
+
"referer",
|
|
59141
|
+
"url.full",
|
|
59142
|
+
"http.url",
|
|
59143
|
+
"http.target",
|
|
59144
|
+
"url.path"
|
|
59145
|
+
]);
|
|
59146
|
+
var KEPT_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
59147
|
+
"accept",
|
|
59148
|
+
"content-encoding",
|
|
59149
|
+
"content-length",
|
|
59150
|
+
"content-type",
|
|
59151
|
+
"host",
|
|
59152
|
+
"mcp-protocol-version",
|
|
59153
|
+
"referer",
|
|
59154
|
+
"user-agent",
|
|
59155
|
+
"x-github-event",
|
|
59156
|
+
"x-powerplant-cli-version"
|
|
59157
|
+
]);
|
|
59158
|
+
var KEPT_HTTP_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
59159
|
+
"http.method",
|
|
59160
|
+
"http.request.method",
|
|
59161
|
+
"http.request.method_original",
|
|
59162
|
+
"http.route",
|
|
59163
|
+
"http.status_code",
|
|
59164
|
+
"http.status_text",
|
|
59165
|
+
"http.response.status_code",
|
|
59166
|
+
"http.scheme",
|
|
59167
|
+
"http.host",
|
|
59168
|
+
"http.flavor",
|
|
59169
|
+
"http.request_content_length_uncompressed",
|
|
59170
|
+
"url.scheme",
|
|
59171
|
+
"url.full",
|
|
59172
|
+
"http.url",
|
|
59173
|
+
"http.target",
|
|
59174
|
+
"url.path"
|
|
59175
|
+
]);
|
|
59176
|
+
var HTTP_ATTRIBUTE_PREFIX = /^(?:http|url)\./;
|
|
59177
|
+
var URL_PARTS = /^([a-z][a-z\d+.-]*:\/\/)([^/?#]*)([^?#]*)/i;
|
|
59178
|
+
var PATH_KEPT_HOSTS = /(?:^|\.)(?:supabase\.co|usepowerplant\.com)$/i;
|
|
59179
|
+
var OUTGOING_ROUTES = [
|
|
59180
|
+
// GitHub REST API
|
|
59181
|
+
"/app/installations/{installation_id}/access_tokens",
|
|
59182
|
+
"/app/installations/{installation_id}",
|
|
59183
|
+
"/installation/repositories",
|
|
59184
|
+
"/orgs/{org}/memberships/{username}",
|
|
59185
|
+
"/repos/{owner}/{repo}/contents/{path}",
|
|
59186
|
+
"/user/installations",
|
|
59187
|
+
"/user/{account_id}",
|
|
59188
|
+
// GitHub sign-in
|
|
59189
|
+
"/login/oauth/access_token",
|
|
59190
|
+
// Cursor API
|
|
59191
|
+
"/v1/agents",
|
|
59192
|
+
"/v1/agents/{agent_id}",
|
|
59193
|
+
"/v1/agents/{agent_id}/runs",
|
|
59194
|
+
"/v1/agents/{agent_id}/runs/{run_id}",
|
|
59195
|
+
"/v1/agents/{agent_id}/runs/{run_id}/stream",
|
|
59196
|
+
"/teams/filtered-usage-events"
|
|
59197
|
+
];
|
|
59198
|
+
var OUTGOING_URL_FIELD_NAMES = ["url", "url.full", "http.url"];
|
|
59199
|
+
var OUTGOING_PATH_FIELD_NAMES = ["url.path", "http.target"];
|
|
59135
59200
|
var MAX_DEPTH = 10;
|
|
59136
59201
|
function scrubString(value) {
|
|
59137
59202
|
return value.replace(POWERPLANT_TOKEN_PATTERN, REDACTED3).replace(BEARER_TOKEN_PATTERN, `Bearer ${REDACTED3}`).replace(JWT_PATTERN, REDACTED3).replace(EMBEDDED_QUERY_SECRET_PATTERN, `$1${REDACTED3}`);
|
|
59138
59203
|
}
|
|
59139
59204
|
function scrubUrl(url2) {
|
|
59140
|
-
|
|
59141
|
-
|
|
59142
|
-
|
|
59143
|
-
|
|
59144
|
-
|
|
59145
|
-
|
|
59146
|
-
|
|
59147
|
-
|
|
59148
|
-
|
|
59149
|
-
|
|
59150
|
-
|
|
59151
|
-
|
|
59152
|
-
|
|
59153
|
-
|
|
59154
|
-
|
|
59155
|
-
|
|
59156
|
-
const
|
|
59157
|
-
|
|
59205
|
+
const queryStart = url2.search(/[?#]/);
|
|
59206
|
+
return queryStart === -1 ? url2 : url2.slice(0, queryStart);
|
|
59207
|
+
}
|
|
59208
|
+
function scrubOutgoingUrl(url2) {
|
|
59209
|
+
const parts = URL_PARTS.exec(url2);
|
|
59210
|
+
if (!parts) return REDACTED3;
|
|
59211
|
+
const [, scheme = "", authority = "", path38 = ""] = parts;
|
|
59212
|
+
const host = authority.slice(authority.lastIndexOf("@") + 1);
|
|
59213
|
+
const origin = `${scheme}${host}`;
|
|
59214
|
+
if (PATH_KEPT_HOSTS.test(host.replace(/:\d*$/, ""))) return `${origin}${path38}`;
|
|
59215
|
+
const route = OUTGOING_ROUTES.find((template) => fitsRoute(path38, template));
|
|
59216
|
+
return `${origin}${route ?? ""}`;
|
|
59217
|
+
}
|
|
59218
|
+
function fitsRoute(path38, template) {
|
|
59219
|
+
const segments = path38.replace(/(.)\/$/, "$1").split("/");
|
|
59220
|
+
const route = template.split("/");
|
|
59221
|
+
const hasRest = route.at(-1) === "{path}";
|
|
59222
|
+
const fixed = hasRest ? route.slice(0, -1) : route;
|
|
59223
|
+
if (hasRest ? segments.length < fixed.length : segments.length !== fixed.length) return false;
|
|
59224
|
+
return fixed.every(
|
|
59225
|
+
(part, index) => part.startsWith("{") ? segments[index] !== "" : part === segments[index]
|
|
59226
|
+
);
|
|
59158
59227
|
}
|
|
59159
59228
|
function scrubValue(value, depth = 0) {
|
|
59160
59229
|
if (depth > MAX_DEPTH || value == null) return value;
|
|
@@ -59163,9 +59232,10 @@ function scrubValue(value, depth = 0) {
|
|
|
59163
59232
|
if (typeof value !== "object") return value;
|
|
59164
59233
|
const out = {};
|
|
59165
59234
|
for (const [key, child] of Object.entries(value)) {
|
|
59166
|
-
|
|
59235
|
+
const name = key.toLowerCase();
|
|
59236
|
+
if (SECRET_KEY_PATTERN.test(key) || SECRET_QUERY_PARAM_PATTERN.test(key) || HTTP_ATTRIBUTE_PREFIX.test(name) && !KEPT_HTTP_ATTRIBUTES.has(name)) {
|
|
59167
59237
|
out[key] = REDACTED3;
|
|
59168
|
-
} else if (URL_FIELD_NAMES.has(
|
|
59238
|
+
} else if (URL_FIELD_NAMES.has(name) && typeof child === "string") {
|
|
59169
59239
|
out[key] = scrubUrl(child);
|
|
59170
59240
|
} else {
|
|
59171
59241
|
out[key] = scrubValue(child, depth + 1);
|
|
@@ -59178,17 +59248,21 @@ function scrubSentryEvent(event) {
|
|
|
59178
59248
|
if (typeof event.request.url === "string") {
|
|
59179
59249
|
event.request.url = scrubUrl(event.request.url);
|
|
59180
59250
|
}
|
|
59181
|
-
if (
|
|
59182
|
-
event.request.query_string =
|
|
59251
|
+
if (event.request.query_string !== void 0) {
|
|
59252
|
+
event.request.query_string = REDACTED3;
|
|
59183
59253
|
}
|
|
59184
59254
|
if (event.request.headers) {
|
|
59185
|
-
|
|
59255
|
+
const headers = Object.entries(event.request.headers).map(([name, value]) => [
|
|
59256
|
+
name,
|
|
59257
|
+
KEPT_HEADER_NAMES.has(name.toLowerCase()) ? value : REDACTED3
|
|
59258
|
+
]);
|
|
59259
|
+
event.request.headers = scrubValue(Object.fromEntries(headers));
|
|
59186
59260
|
}
|
|
59187
59261
|
if (event.request.cookies !== void 0) {
|
|
59188
59262
|
event.request.cookies = REDACTED3;
|
|
59189
59263
|
}
|
|
59190
59264
|
if (event.request.data !== void 0) {
|
|
59191
|
-
event.request.data =
|
|
59265
|
+
event.request.data = REDACTED3;
|
|
59192
59266
|
}
|
|
59193
59267
|
}
|
|
59194
59268
|
if (event.exception?.values) {
|
|
@@ -59210,14 +59284,45 @@ function scrubSentryEvent(event) {
|
|
|
59210
59284
|
if (Array.isArray(event.breadcrumbs)) {
|
|
59211
59285
|
event.breadcrumbs = event.breadcrumbs.map(scrubBreadcrumb);
|
|
59212
59286
|
}
|
|
59287
|
+
for (const span of event.spans ?? []) {
|
|
59288
|
+
if (typeof span.description === "string") {
|
|
59289
|
+
span.description = scrubString(span.description);
|
|
59290
|
+
}
|
|
59291
|
+
if (span.data) {
|
|
59292
|
+
span.data = scrubValue(span.data);
|
|
59293
|
+
}
|
|
59294
|
+
if (span.op === "http.client") {
|
|
59295
|
+
scrubOutgoingRequestSpan(span);
|
|
59296
|
+
}
|
|
59297
|
+
}
|
|
59213
59298
|
return event;
|
|
59214
59299
|
}
|
|
59300
|
+
function scrubOutgoingRequestSpan(span) {
|
|
59301
|
+
if (typeof span.description === "string") {
|
|
59302
|
+
const [method, ...target] = span.description.split(" ");
|
|
59303
|
+
if (target.length > 0) {
|
|
59304
|
+
span.description = `${method} ${scrubOutgoingUrl(target.join(" "))}`;
|
|
59305
|
+
}
|
|
59306
|
+
}
|
|
59307
|
+
const data = span.data;
|
|
59308
|
+
if (!data) return;
|
|
59309
|
+
for (const name of OUTGOING_URL_FIELD_NAMES) {
|
|
59310
|
+
const value = data[name];
|
|
59311
|
+
if (typeof value === "string") data[name] = scrubOutgoingUrl(value);
|
|
59312
|
+
}
|
|
59313
|
+
for (const name of OUTGOING_PATH_FIELD_NAMES) {
|
|
59314
|
+
if (name in data) data[name] = REDACTED3;
|
|
59315
|
+
}
|
|
59316
|
+
}
|
|
59215
59317
|
function scrubBreadcrumb(breadcrumb) {
|
|
59216
59318
|
if (typeof breadcrumb.message === "string") {
|
|
59217
59319
|
breadcrumb.message = scrubString(breadcrumb.message);
|
|
59218
59320
|
}
|
|
59219
59321
|
if (breadcrumb.data) {
|
|
59220
59322
|
breadcrumb.data = scrubValue(breadcrumb.data);
|
|
59323
|
+
if (breadcrumb.category === "http" && typeof breadcrumb.data.url === "string") {
|
|
59324
|
+
breadcrumb.data.url = scrubOutgoingUrl(breadcrumb.data.url);
|
|
59325
|
+
}
|
|
59221
59326
|
}
|
|
59222
59327
|
return breadcrumb;
|
|
59223
59328
|
}
|
|
@@ -59416,9 +59521,10 @@ function parseCodexChildThread(sessionMeta) {
|
|
|
59416
59521
|
// ../core/src/recentSessionPage.ts
|
|
59417
59522
|
var RECENT_SESSION_WINDOW_MS = 72 * 60 * 60 * 1e3;
|
|
59418
59523
|
var RECENT_SESSION_VISIBLE_LIMIT = 12;
|
|
59524
|
+
var RECENT_SESSION_PAGE_MAX = 40;
|
|
59419
59525
|
var recentSessionOptionsSchema = external_exports.object({
|
|
59420
59526
|
windowHours: external_exports.coerce.number().int().min(1).max(120).default(72),
|
|
59421
|
-
limit: external_exports.coerce.number().int().min(1).max(
|
|
59527
|
+
limit: external_exports.coerce.number().int().min(1).max(RECENT_SESSION_PAGE_MAX).default(12)
|
|
59422
59528
|
});
|
|
59423
59529
|
var recentSessionCursorSchema = external_exports.object({
|
|
59424
59530
|
at: external_exports.iso.datetime({ offset: true }),
|
|
@@ -86582,40 +86688,45 @@ function readCodexTranscriptDiscoveryRecords(home, roots) {
|
|
|
86582
86688
|
} catch {
|
|
86583
86689
|
return [];
|
|
86584
86690
|
}
|
|
86585
|
-
|
|
86586
|
-
|
|
86587
|
-
|
|
86691
|
+
return files.flatMap((file2) => {
|
|
86692
|
+
if (!/^[a-f0-9]{64}\.json$/.test(file2)) return [];
|
|
86693
|
+
const record2 = readRecord(path2.join(dir, file2), roots);
|
|
86694
|
+
return record2 === null ? [] : [record2];
|
|
86695
|
+
});
|
|
86696
|
+
}
|
|
86697
|
+
function readCodexTranscriptDiscoveryRecord(home, sessionId, roots) {
|
|
86698
|
+
return readRecord(codexTranscriptRecordPath(home, sessionId), roots);
|
|
86699
|
+
}
|
|
86700
|
+
function readRecord(recordPath, roots) {
|
|
86701
|
+
try {
|
|
86702
|
+
if (!lstatSync(recordPath).isFile()) return null;
|
|
86703
|
+
const fd = openSync(recordPath, "r");
|
|
86704
|
+
let text;
|
|
86588
86705
|
try {
|
|
86589
|
-
const
|
|
86590
|
-
|
|
86591
|
-
|
|
86592
|
-
|
|
86593
|
-
|
|
86594
|
-
|
|
86595
|
-
|
|
86596
|
-
|
|
86597
|
-
|
|
86598
|
-
|
|
86599
|
-
|
|
86600
|
-
|
|
86601
|
-
|
|
86602
|
-
|
|
86603
|
-
|
|
86604
|
-
|
|
86605
|
-
|
|
86606
|
-
|
|
86607
|
-
|
|
86608
|
-
|
|
86609
|
-
|
|
86610
|
-
|
|
86611
|
-
|
|
86612
|
-
if (realpathSync(rolloutPath) !== path2.join(realpathSync(root), path2.relative(root, rolloutPath)))
|
|
86613
|
-
continue;
|
|
86614
|
-
result.push({ rolloutPath, sessionId: record2.sessionId, archived: rootIndex === 1 });
|
|
86615
|
-
} catch {
|
|
86616
|
-
}
|
|
86706
|
+
const buffer = Buffer.alloc(32 * 1024 + 1);
|
|
86707
|
+
const read = readSync(fd, buffer, 0, buffer.length, null);
|
|
86708
|
+
if (read === buffer.length) return null;
|
|
86709
|
+
text = buffer.subarray(0, read).toString("utf8");
|
|
86710
|
+
} finally {
|
|
86711
|
+
closeSync(fd);
|
|
86712
|
+
}
|
|
86713
|
+
const record2 = transcriptDiscoveryRecordSchema.parse(JSON.parse(text));
|
|
86714
|
+
if (path2.basename(recordPath) !== `${createHash("sha256").update(record2.sessionId).digest("hex")}.json`) return null;
|
|
86715
|
+
if (record2.transcriptPath === null || !path2.isAbsolute(record2.transcriptPath)) return null;
|
|
86716
|
+
const rolloutPath = path2.normalize(record2.transcriptPath);
|
|
86717
|
+
if (path2.extname(rolloutPath) !== ".jsonl") return null;
|
|
86718
|
+
const rootIndex = roots.findIndex((root2) => {
|
|
86719
|
+
const relative2 = path2.relative(root2, rolloutPath);
|
|
86720
|
+
return relative2 !== "" && relative2 !== ".." && !relative2.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative2);
|
|
86721
|
+
});
|
|
86722
|
+
if (rootIndex < 0 || !lstatSync(rolloutPath).isFile()) return null;
|
|
86723
|
+
const root = roots[rootIndex];
|
|
86724
|
+
if (realpathSync(rolloutPath) !== path2.join(realpathSync(root), path2.relative(root, rolloutPath)))
|
|
86725
|
+
return null;
|
|
86726
|
+
return { rolloutPath, sessionId: record2.sessionId, archived: rootIndex === 1 };
|
|
86727
|
+
} catch {
|
|
86728
|
+
return null;
|
|
86617
86729
|
}
|
|
86618
|
-
return result;
|
|
86619
86730
|
}
|
|
86620
86731
|
|
|
86621
86732
|
// ../../apps/syncservice/src/diagnostics.ts
|
|
@@ -86624,7 +86735,7 @@ import { createHmac } from "node:crypto";
|
|
|
86624
86735
|
// ../../apps/syncservice/src/http.ts
|
|
86625
86736
|
var import_undici = __toESM(require_undici(), 1);
|
|
86626
86737
|
var CLI_VERSION_HEADER = "x-powerplant-cli-version";
|
|
86627
|
-
var cliVersion = true ? "0.4.
|
|
86738
|
+
var cliVersion = true ? "0.4.21" : "0.0.0-checkout";
|
|
86628
86739
|
function cliVersionHeaders() {
|
|
86629
86740
|
return { [CLI_VERSION_HEADER]: cliVersion, "user-agent": `powerplant-cli/${cliVersion}` };
|
|
86630
86741
|
}
|
|
@@ -87717,7 +87828,7 @@ function mayBeParentOf(parent, childMadeMs) {
|
|
|
87717
87828
|
function mayBeChildOf(threadTimeMs, parentTimeMs) {
|
|
87718
87829
|
return threadTimeMs === void 0 || parentTimeMs === void 0 || threadTimeMs + THREAD_ID_TIME_MARGIN_MS >= parentTimeMs;
|
|
87719
87830
|
}
|
|
87720
|
-
var CodexThreadLinks = class {
|
|
87831
|
+
var CodexThreadLinks = class _CodexThreadLinks {
|
|
87721
87832
|
/** `readLink` is a test seam for the first-record read. */
|
|
87722
87833
|
constructor(readLink = readThreadLink) {
|
|
87723
87834
|
this.readLink = readLink;
|
|
@@ -87743,6 +87854,19 @@ var CodexThreadLinks = class {
|
|
|
87743
87854
|
* (settleRecoveries), with the session the last pass made of it and how
|
|
87744
87855
|
* many uploads of it failed. */
|
|
87745
87856
|
recovering = /* @__PURE__ */ new Map();
|
|
87857
|
+
/** A copy for a pass that runs beside the watcher's own passes (the
|
|
87858
|
+
* new-session pass), so neither changes what the other knows. It keeps
|
|
87859
|
+
* what each rollout's first record showed, and leaves out the rollouts
|
|
87860
|
+
* and threads owed another read or a corrected capture, which only the
|
|
87861
|
+
* watcher's own passes settle. */
|
|
87862
|
+
copyForSidePass() {
|
|
87863
|
+
const copy = new _CodexThreadLinks(this.readLink);
|
|
87864
|
+
for (const [rolloutPath, link] of this.byPath) copy.byPath.set(rolloutPath, link);
|
|
87865
|
+
for (const [rolloutPath, changedMs] of this.failedAt) copy.failedAt.set(rolloutPath, changedMs);
|
|
87866
|
+
for (const [rolloutPath, state] of this.incomplete) copy.incomplete.set(rolloutPath, { ...state });
|
|
87867
|
+
for (const rolloutPath of this.faulted) copy.faulted.add(rolloutPath);
|
|
87868
|
+
return copy;
|
|
87869
|
+
}
|
|
87746
87870
|
/** Keeps what another read of the same first record found. */
|
|
87747
87871
|
remember(rolloutPath, link) {
|
|
87748
87872
|
this.byPath.set(rolloutPath, link);
|
|
@@ -87980,7 +88104,7 @@ var CodexThreadLinks = class {
|
|
|
87980
88104
|
return true;
|
|
87981
88105
|
}
|
|
87982
88106
|
};
|
|
87983
|
-
var CodexThreadReads = class {
|
|
88107
|
+
var CodexThreadReads = class _CodexThreadReads {
|
|
87984
88108
|
byThread = /* @__PURE__ */ new Map();
|
|
87985
88109
|
/** What a full read found when the thread's files were `files`
|
|
87986
88110
|
* (threadFilesKey): its summary and prefix, null for a thread holding no
|
|
@@ -87992,6 +88116,14 @@ var CodexThreadReads = class {
|
|
|
87992
88116
|
set(threadId2, files, read) {
|
|
87993
88117
|
this.byThread.set(threadId2, { files, read });
|
|
87994
88118
|
}
|
|
88119
|
+
/** A copy for a pass that runs beside the watcher's own passes. Each read
|
|
88120
|
+
* is kept for exactly the files it was made from, so a copy never serves
|
|
88121
|
+
* a read of files that have since changed. */
|
|
88122
|
+
copyForSidePass() {
|
|
88123
|
+
const copy = new _CodexThreadReads();
|
|
88124
|
+
for (const [threadId2, kept] of this.byThread) copy.byThread.set(threadId2, kept);
|
|
88125
|
+
return copy;
|
|
88126
|
+
}
|
|
87995
88127
|
/** Forgets the threads no longer on this machine. */
|
|
87996
88128
|
keepOnly(threadIds) {
|
|
87997
88129
|
for (const threadId2 of this.byThread.keys()) if (!threadIds.has(threadId2)) this.byThread.delete(threadId2);
|
|
@@ -90295,8 +90427,10 @@ var collectorStatusSchema = external_exports.object({
|
|
|
90295
90427
|
/** Last pass that completed without error — everything eligible had been
|
|
90296
90428
|
* uploaded as of this time. */
|
|
90297
90429
|
lastSyncAt: external_exports.string().optional(),
|
|
90298
|
-
/**
|
|
90299
|
-
*
|
|
90430
|
+
/** When the server last stored a changed session record, from any pass,
|
|
90431
|
+
* a recent catch-up inside one included. The next run of the same
|
|
90432
|
+
* enrollment carries it (carriedUploadClock). Missing: no upload in this
|
|
90433
|
+
* run or the one before it, not "never". */
|
|
90300
90434
|
lastUploadAt: external_exports.string().optional(),
|
|
90301
90435
|
consecutiveFailures: external_exports.number().int().nonnegative(),
|
|
90302
90436
|
/** Whether the hooks this daemon installed are firing, per harness
|
|
@@ -90867,7 +91001,7 @@ function saveCredentials(appEnv, credentials) {
|
|
|
90867
91001
|
function loadCredentials(appEnv) {
|
|
90868
91002
|
if (process.platform === "darwin") {
|
|
90869
91003
|
const raw2 = new MacosCredentialStore(appEnv).load();
|
|
90870
|
-
return raw2 === null ? null : parseStoredCredentials(raw2, appEnv);
|
|
91004
|
+
return raw2 === null ? null : withCurrentApiUrl(appEnv, parseStoredCredentials(raw2, appEnv));
|
|
90871
91005
|
}
|
|
90872
91006
|
let raw;
|
|
90873
91007
|
try {
|
|
@@ -90879,7 +91013,19 @@ function loadCredentials(appEnv) {
|
|
|
90879
91013
|
{ cause }
|
|
90880
91014
|
);
|
|
90881
91015
|
}
|
|
90882
|
-
return parseStoredCredentials(raw, appEnv);
|
|
91016
|
+
return withCurrentApiUrl(appEnv, parseStoredCredentials(raw, appEnv));
|
|
91017
|
+
}
|
|
91018
|
+
var RETIRED_API_URLS = {
|
|
91019
|
+
production: { retired: "https://api.powerplant.sh", replacement: "https://api.usepowerplant.com" },
|
|
91020
|
+
staging: {
|
|
91021
|
+
retired: "https://staging.api.powerplant.sh",
|
|
91022
|
+
replacement: "https://staging.api.usepowerplant.com"
|
|
91023
|
+
}
|
|
91024
|
+
};
|
|
91025
|
+
function withCurrentApiUrl(appEnv, credentials) {
|
|
91026
|
+
const moved = RETIRED_API_URLS[appEnv];
|
|
91027
|
+
if (moved === void 0 || credentials.apiUrl !== moved.retired) return credentials;
|
|
91028
|
+
return { ...credentials, apiUrl: moved.replacement };
|
|
90883
91029
|
}
|
|
90884
91030
|
function isCredentialStoreAbsent(cause) {
|
|
90885
91031
|
return cause instanceof Error && "code" in cause && cause.code === "ENOENT";
|
|
@@ -90912,7 +91058,9 @@ import os14 from "node:os";
|
|
|
90912
91058
|
|
|
90913
91059
|
// ../../apps/syncservice/src/upload.ts
|
|
90914
91060
|
import { readFileSync as readFileSync10 } from "node:fs";
|
|
90915
|
-
import {
|
|
91061
|
+
import { setImmediate as yieldToEventLoop3 } from "node:timers/promises";
|
|
91062
|
+
import { promisify as promisify2 } from "node:util";
|
|
91063
|
+
import { gzip } from "node:zlib";
|
|
90916
91064
|
|
|
90917
91065
|
// ../../apps/syncservice/src/claudeCode.ts
|
|
90918
91066
|
import { readdirSync as readdirSync6 } from "node:fs";
|
|
@@ -91490,8 +91638,20 @@ async function uploadPreviewRegistration(apiUrl, machineToken, registration) {
|
|
|
91490
91638
|
}
|
|
91491
91639
|
return "registered";
|
|
91492
91640
|
}
|
|
91493
|
-
|
|
91494
|
-
|
|
91641
|
+
var gzipAsync = promisify2(gzip);
|
|
91642
|
+
var REDACT_SLICE_CHARS = 64 * 1024;
|
|
91643
|
+
async function encodeRawTranscript(text) {
|
|
91644
|
+
const lines = text.split("\n");
|
|
91645
|
+
let sliceChars = 0;
|
|
91646
|
+
for (const [index, line] of lines.entries()) {
|
|
91647
|
+
lines[index] = redactJsonl(line);
|
|
91648
|
+
sliceChars += line.length;
|
|
91649
|
+
if (sliceChars >= REDACT_SLICE_CHARS) {
|
|
91650
|
+
await yieldToEventLoop3();
|
|
91651
|
+
sliceChars = 0;
|
|
91652
|
+
}
|
|
91653
|
+
}
|
|
91654
|
+
return gzipAsync(lines.join("\n"));
|
|
91495
91655
|
}
|
|
91496
91656
|
function readCollectedTranscript(file2, prefix) {
|
|
91497
91657
|
return prefix === void 0 ? readFileSync10(file2, "utf8") : readTranscriptPrefix(file2, prefix, false);
|
|
@@ -91501,8 +91661,8 @@ function readUnchangedTranscript(file2, prefix) {
|
|
|
91501
91661
|
}
|
|
91502
91662
|
var BUNDLE_HEADER_BYTES = 256;
|
|
91503
91663
|
var BUNDLE_HEADER_BYTES_PER_PART = 256;
|
|
91504
|
-
function rawUploadBody(session, readTranscript, maxBytes = MAX_RAW_UPLOAD_BYTES) {
|
|
91505
|
-
const main2 = encodeRawTranscript(readTranscript(session.transcriptPath, session.transcriptPrefix));
|
|
91664
|
+
async function rawUploadBody(session, readTranscript, maxBytes = MAX_RAW_UPLOAD_BYTES) {
|
|
91665
|
+
const main2 = await encodeRawTranscript(readTranscript(session.transcriptPath, session.transcriptPrefix));
|
|
91506
91666
|
if (session.subagents === void 0) {
|
|
91507
91667
|
return main2.byteLength > maxBytes ? "too-large" : { body: main2, main: main2, contentType: "application/gzip", skippedSubagentFiles: 0, unreadableSubagentFiles: 0 };
|
|
91508
91668
|
}
|
|
@@ -91514,7 +91674,7 @@ function rawUploadBody(session, readTranscript, maxBytes = MAX_RAW_UPLOAD_BYTES)
|
|
|
91514
91674
|
for (const file2 of session.subagents.files) {
|
|
91515
91675
|
let body;
|
|
91516
91676
|
try {
|
|
91517
|
-
body = encodeRawTranscript(readTranscript(file2.path, file2.prefix));
|
|
91677
|
+
body = await encodeRawTranscript(readTranscript(file2.path, file2.prefix));
|
|
91518
91678
|
} catch (error63) {
|
|
91519
91679
|
if (error63 instanceof TranscriptChangedError) throw error63;
|
|
91520
91680
|
skipped += 1;
|
|
@@ -91588,7 +91748,7 @@ async function uploadRawSessions(apiUrl, machineToken, transcriptUploadSources,
|
|
|
91588
91748
|
continue;
|
|
91589
91749
|
}
|
|
91590
91750
|
try {
|
|
91591
|
-
const encoded = rawUploadBody(session, readTranscript);
|
|
91751
|
+
const encoded = await rawUploadBody(session, readTranscript);
|
|
91592
91752
|
if (encoded === "too-large") {
|
|
91593
91753
|
summary.skippedTooLarge += 1;
|
|
91594
91754
|
summary.outcomes.set(key, "too-large");
|
|
@@ -92523,7 +92683,16 @@ var codexLocal = {
|
|
|
92523
92683
|
transcriptSession(transcriptPath) {
|
|
92524
92684
|
const identity = rolloutIdentity(transcriptPath);
|
|
92525
92685
|
return identity.page ? { hookId: identity.threadId } : { externalId: path18.basename(transcriptPath, ".jsonl") };
|
|
92526
|
-
}
|
|
92686
|
+
},
|
|
92687
|
+
// The hook records the rollout of each thread before it appends the
|
|
92688
|
+
// journal line (.claude/hooks/powerplant-codex-transcript.mjs).
|
|
92689
|
+
hookTranscriptPath(threadId2, homeDir) {
|
|
92690
|
+
const sessionsDir = path18.join(homeDir, ".codex", "sessions");
|
|
92691
|
+
return readCodexTranscriptDiscoveryRecord(homeDir, threadId2, [sessionsDir, codexArchivedSessionsDir(sessionsDir)])?.rolloutPath;
|
|
92692
|
+
},
|
|
92693
|
+
// The Codex app holds the rollout of each open thread for writing
|
|
92694
|
+
// (lsof, 2026-09-27), and macOS reports a write to it only on close.
|
|
92695
|
+
holdsTranscriptOpen: true
|
|
92527
92696
|
};
|
|
92528
92697
|
var cursorLocal = {
|
|
92529
92698
|
harness: "cursor-local",
|
|
@@ -93429,6 +93598,7 @@ function readIfExists2(p) {
|
|
|
93429
93598
|
}
|
|
93430
93599
|
|
|
93431
93600
|
// ../../apps/syncservice/src/previewRegistration.ts
|
|
93601
|
+
import { setImmediate as yieldToEventLoop4 } from "node:timers/promises";
|
|
93432
93602
|
async function registerAnnouncedPreviews(apiUrl, machineToken, collected, memo2, deps = {}) {
|
|
93433
93603
|
const readTranscript = deps.readTranscript ?? readIfExists;
|
|
93434
93604
|
const upload = deps.upload ?? uploadPreviewRegistration;
|
|
@@ -93444,6 +93614,7 @@ async function registerAnnouncedPreviews(apiUrl, machineToken, collected, memo2,
|
|
|
93444
93614
|
const state = memo2.get(key);
|
|
93445
93615
|
if (state?.foreignOwner || state?.previewsOff) continue;
|
|
93446
93616
|
if (state?.examinedMtimeMs === session.mtimeMs) continue;
|
|
93617
|
+
await yieldToEventLoop4();
|
|
93447
93618
|
try {
|
|
93448
93619
|
const text = readTranscript(session.transcriptPath);
|
|
93449
93620
|
if (text === null) continue;
|
|
@@ -93489,6 +93660,22 @@ async function registerAnnouncedPreviews(apiUrl, machineToken, collected, memo2,
|
|
|
93489
93660
|
}
|
|
93490
93661
|
|
|
93491
93662
|
// ../../apps/syncservice/src/sync.ts
|
|
93663
|
+
var RecordTurns = class {
|
|
93664
|
+
last = Promise.resolve();
|
|
93665
|
+
/** Waits for the passes ahead, then returns `end`, which lets the next
|
|
93666
|
+
* pass take its turn. Calling `end` again does nothing. */
|
|
93667
|
+
async take() {
|
|
93668
|
+
let end = () => {
|
|
93669
|
+
};
|
|
93670
|
+
const ended = new Promise((resolve2) => {
|
|
93671
|
+
end = resolve2;
|
|
93672
|
+
});
|
|
93673
|
+
const ahead = this.last;
|
|
93674
|
+
this.last = ahead.then(() => ended);
|
|
93675
|
+
await ahead;
|
|
93676
|
+
return end;
|
|
93677
|
+
}
|
|
93678
|
+
};
|
|
93492
93679
|
var defaultPolicyDeps = {
|
|
93493
93680
|
fetchPolicy: fetchCapturePolicy,
|
|
93494
93681
|
load: loadCredentials,
|
|
@@ -93590,7 +93777,17 @@ async function resolveCapturePolicy(config2, credentials, log3, deps = defaultPo
|
|
|
93590
93777
|
environment
|
|
93591
93778
|
};
|
|
93592
93779
|
}
|
|
93593
|
-
|
|
93780
|
+
function recordTurn(turns) {
|
|
93781
|
+
let end = () => {
|
|
93782
|
+
};
|
|
93783
|
+
return {
|
|
93784
|
+
start: async () => {
|
|
93785
|
+
if (turns) end = await turns.take();
|
|
93786
|
+
},
|
|
93787
|
+
end: () => end()
|
|
93788
|
+
};
|
|
93789
|
+
}
|
|
93790
|
+
async function runSyncPassInternal(config2, options, diagnostic, turn) {
|
|
93594
93791
|
const log3 = options.log ?? console.log;
|
|
93595
93792
|
const credentials = loadCredentials(config2.appEnv);
|
|
93596
93793
|
if (!credentials) {
|
|
@@ -93616,6 +93813,7 @@ async function runSyncPassInternal(config2, options, diagnostic) {
|
|
|
93616
93813
|
diagnostic.sinceMs = sinceMs;
|
|
93617
93814
|
diagnostic.deepSweep = window2.deepSweep;
|
|
93618
93815
|
const maxSessions = window2.deepSweep ? DEEP_FIRST_SYNC_MAX_SESSIONS : void 0;
|
|
93816
|
+
await turn.start();
|
|
93619
93817
|
diagnostic.stage = "claude";
|
|
93620
93818
|
const claude = await collectClaudeCodeSessions({
|
|
93621
93819
|
sinceMs,
|
|
@@ -93726,12 +93924,14 @@ async function runSyncPassInternal(config2, options, diagnostic) {
|
|
|
93726
93924
|
credentials.token,
|
|
93727
93925
|
items
|
|
93728
93926
|
);
|
|
93927
|
+
turn.end();
|
|
93729
93928
|
const foreignKeys = new Set(foreignOwned.map(sessionKey));
|
|
93730
93929
|
const writable = collected.filter(({ item }) => !foreignKeys.has(sessionKey(item)));
|
|
93731
93930
|
for (const { harness, harnessSessionId } of foreignOwned) {
|
|
93732
93931
|
log3(`Skipped ${harness} session ${harnessSessionId}: already synced from another machine.`);
|
|
93733
93932
|
}
|
|
93734
93933
|
Object.assign(diagnostic, { upserted, unchanged, outOfPolicy, deferred });
|
|
93934
|
+
if (upserted > 0) options.onRecordsUpserted?.();
|
|
93735
93935
|
log3(
|
|
93736
93936
|
`Uploaded: ${upserted} session(s) upserted` + (unchanged > 0 ? `, ${unchanged} unchanged (no writes issued)` : "") + "."
|
|
93737
93937
|
);
|
|
@@ -93863,8 +94063,9 @@ async function runSyncPass(config2, options = {}) {
|
|
|
93863
94063
|
}
|
|
93864
94064
|
};
|
|
93865
94065
|
notify();
|
|
94066
|
+
const turn = recordTurn(options.recordTurns);
|
|
93866
94067
|
try {
|
|
93867
|
-
const result = await runSyncPassInternal(config2, options, diagnostic);
|
|
94068
|
+
const result = await runSyncPassInternal(config2, options, diagnostic, turn);
|
|
93868
94069
|
diagnostic.outcome = "complete";
|
|
93869
94070
|
diagnostic.stage = "complete";
|
|
93870
94071
|
diagnostic.upserted = result.upserted;
|
|
@@ -93877,6 +94078,7 @@ async function runSyncPass(config2, options = {}) {
|
|
|
93877
94078
|
if (error63 instanceof Error) failedPasses.set(error63, diagnostic);
|
|
93878
94079
|
throw error63;
|
|
93879
94080
|
} finally {
|
|
94081
|
+
turn.end();
|
|
93880
94082
|
diagnostic.durationMs = Math.max(0, Date.now() - start);
|
|
93881
94083
|
notify();
|
|
93882
94084
|
}
|
|
@@ -93939,7 +94141,7 @@ function unsupportedVersionNotice(cliVersion2, oldestSupportedVersion) {
|
|
|
93939
94141
|
}
|
|
93940
94142
|
|
|
93941
94143
|
// ../../apps/syncservice/src/watch.ts
|
|
93942
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync11, watch as
|
|
94144
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync11, watch as fsWatch3 } from "node:fs";
|
|
93943
94145
|
import os19 from "node:os";
|
|
93944
94146
|
import path21 from "node:path";
|
|
93945
94147
|
|
|
@@ -93973,7 +94175,7 @@ function defaultStat(file2) {
|
|
|
93973
94175
|
}
|
|
93974
94176
|
|
|
93975
94177
|
// ../../apps/syncservice/src/sessionStatusFeed.ts
|
|
93976
|
-
import { statSync as statSync5 } from "node:fs";
|
|
94178
|
+
import { statSync as statSync5, watch as fsWatch2 } from "node:fs";
|
|
93977
94179
|
|
|
93978
94180
|
// ../../apps/syncservice/src/sessionStatusModel.ts
|
|
93979
94181
|
function createSessionStatusModel(now = Date.now) {
|
|
@@ -94024,11 +94226,13 @@ function createSessionStatusModel(now = Date.now) {
|
|
|
94024
94226
|
// ../../apps/syncservice/src/sessionStatusFeed.ts
|
|
94025
94227
|
var TRANSCRIPT_WRITE_DELAY_MS = 500;
|
|
94026
94228
|
var HELD_HOOK_ENTRIES_MAX = 500;
|
|
94229
|
+
var TRANSCRIPT_FILE_WATCHES_MAX = 32;
|
|
94027
94230
|
var HOOK_ID_PAIRS_MAX = 1e4;
|
|
94028
94231
|
var MAX_TIMER_MS = 2 ** 31 - 1;
|
|
94029
94232
|
function createSessionStatusFeed(deps) {
|
|
94030
94233
|
const now = deps.now ?? Date.now;
|
|
94031
94234
|
const adapters = deps.adapters ?? HARNESS_ADAPTERS;
|
|
94235
|
+
const watchFile = deps.watchFile ?? watchFileWrites;
|
|
94032
94236
|
const model = createSessionStatusModel(now);
|
|
94033
94237
|
const adapterOf = (harness) => adapters.find((adapter) => adapter.harness === harness);
|
|
94034
94238
|
const hookIdOf = (harness) => adapterOf(harness)?.hookSessionId;
|
|
@@ -94040,8 +94244,34 @@ function createSessionStatusFeed(deps) {
|
|
|
94040
94244
|
let readQueued = false;
|
|
94041
94245
|
let readFailing = false;
|
|
94042
94246
|
let statFailing = false;
|
|
94247
|
+
let watchFailing = false;
|
|
94043
94248
|
const writeTimers = /* @__PURE__ */ new Map();
|
|
94249
|
+
const hookFilesRead = /* @__PURE__ */ new Set();
|
|
94250
|
+
const reportedFiles = /* @__PURE__ */ new Map();
|
|
94251
|
+
const fileWatches = /* @__PURE__ */ new Map();
|
|
94044
94252
|
let stopped = false;
|
|
94253
|
+
function applyJournalEntry(entry) {
|
|
94254
|
+
if (learnFromHookFile(entry.harness, entry.sessionId)) releaseHeld();
|
|
94255
|
+
apply(entry);
|
|
94256
|
+
}
|
|
94257
|
+
function learnFromHookFile(harness, hookId) {
|
|
94258
|
+
const adapter = adapterOf(harness);
|
|
94259
|
+
const hookIdOfStored = adapter?.hookSessionId;
|
|
94260
|
+
const key = pairKey(harness, hookId);
|
|
94261
|
+
if (adapter?.hookTranscriptPath === void 0 || hookIdOfStored === void 0 || hookFilesRead.has(key)) {
|
|
94262
|
+
return false;
|
|
94263
|
+
}
|
|
94264
|
+
hookFilesRead.add(key);
|
|
94265
|
+
const file2 = adapter.hookTranscriptPath(hookId, deps.home);
|
|
94266
|
+
const session = file2 === void 0 ? void 0 : adapter.transcriptSession?.(file2);
|
|
94267
|
+
if (file2 === void 0 || session === void 0) return false;
|
|
94268
|
+
const fileHookId = "externalId" in session ? hookIdOfStored(session.externalId) : session.hookId;
|
|
94269
|
+
if (pairKey(harness, fileHookId) !== key) return false;
|
|
94270
|
+
const externalId = "externalId" in session ? session.externalId : storedIds.get(key);
|
|
94271
|
+
if (externalId === void 0) return false;
|
|
94272
|
+
reportFile(file2, { harness, externalId });
|
|
94273
|
+
return "externalId" in session && learnPair(harness, externalId);
|
|
94274
|
+
}
|
|
94045
94275
|
function stored(entry) {
|
|
94046
94276
|
if (hookIdOf(entry.harness) === void 0) return entry;
|
|
94047
94277
|
const storedId = storedIds.get(pairKey(entry.harness, entry.sessionId));
|
|
@@ -94083,8 +94313,66 @@ function createSessionStatusFeed(deps) {
|
|
|
94083
94313
|
if (mtimeMs === null) return;
|
|
94084
94314
|
const learned = "externalId" in session && learnPair(harness, externalId);
|
|
94085
94315
|
applyWrite(harness, externalId, mtimeMs);
|
|
94316
|
+
reportFile(transcriptPath, { harness, externalId });
|
|
94086
94317
|
if (learned) releaseHeld();
|
|
94087
94318
|
}
|
|
94319
|
+
function reportFile(file2, session) {
|
|
94320
|
+
if (adapterOf(session.harness)?.holdsTranscriptOpen !== true) return;
|
|
94321
|
+
reportedFiles.delete(file2);
|
|
94322
|
+
reportedFiles.set(file2, session);
|
|
94323
|
+
}
|
|
94324
|
+
function needsFileWatch(session) {
|
|
94325
|
+
const status = model.status(session.harness, session.externalId);
|
|
94326
|
+
return status !== void 0 && status !== "ended";
|
|
94327
|
+
}
|
|
94328
|
+
function watchReportedFiles() {
|
|
94329
|
+
for (const [file2, watched] of fileWatches) {
|
|
94330
|
+
if (!needsFileWatch(watched)) closeFileWatch(file2);
|
|
94331
|
+
}
|
|
94332
|
+
const newest = [...reportedFiles].filter(([, session]) => needsFileWatch(session)).slice(-TRANSCRIPT_FILE_WATCHES_MAX);
|
|
94333
|
+
reportedFiles.clear();
|
|
94334
|
+
for (const [file2, session] of newest) {
|
|
94335
|
+
const watched = fileWatches.get(file2);
|
|
94336
|
+
if (watched === void 0) {
|
|
94337
|
+
openFileWatch(file2, session);
|
|
94338
|
+
} else {
|
|
94339
|
+
fileWatches.delete(file2);
|
|
94340
|
+
fileWatches.set(file2, watched);
|
|
94341
|
+
}
|
|
94342
|
+
}
|
|
94343
|
+
while (fileWatches.size > TRANSCRIPT_FILE_WATCHES_MAX) closeFileWatch(fileWatches.keys().next().value);
|
|
94344
|
+
}
|
|
94345
|
+
function openFileWatch(file2, session) {
|
|
94346
|
+
let close2;
|
|
94347
|
+
try {
|
|
94348
|
+
close2 = watchFile(
|
|
94349
|
+
file2,
|
|
94350
|
+
() => noteWrite(session.harness, file2),
|
|
94351
|
+
(error63) => {
|
|
94352
|
+
closeFileWatch(file2);
|
|
94353
|
+
noteWatchFailure(error63);
|
|
94354
|
+
}
|
|
94355
|
+
);
|
|
94356
|
+
} catch (error63) {
|
|
94357
|
+
if (errorCode(error63) !== "ENOENT") noteWatchFailure(error63);
|
|
94358
|
+
return;
|
|
94359
|
+
}
|
|
94360
|
+
if (watchFailing) deps.log("transcript files watched again");
|
|
94361
|
+
watchFailing = false;
|
|
94362
|
+
fileWatches.set(file2, { ...session, close: close2 });
|
|
94363
|
+
const mtimeMs = modifiedMs(file2);
|
|
94364
|
+
if (mtimeMs !== null) applyWrite(session.harness, session.externalId, mtimeMs);
|
|
94365
|
+
}
|
|
94366
|
+
function closeFileWatch(file2) {
|
|
94367
|
+
fileWatches.get(file2)?.close();
|
|
94368
|
+
fileWatches.delete(file2);
|
|
94369
|
+
}
|
|
94370
|
+
function noteWatchFailure(error63) {
|
|
94371
|
+
if (!watchFailing) {
|
|
94372
|
+
deps.log(`\u26A0 transcript file not watched (${errorCode(error63)}), its status waits for hook events and sync passes`);
|
|
94373
|
+
}
|
|
94374
|
+
watchFailing = true;
|
|
94375
|
+
}
|
|
94088
94376
|
function modifiedMs(transcriptPath) {
|
|
94089
94377
|
try {
|
|
94090
94378
|
const mtimeMs = statSync5(transcriptPath).mtimeMs;
|
|
@@ -94092,7 +94380,10 @@ function createSessionStatusFeed(deps) {
|
|
|
94092
94380
|
statFailing = false;
|
|
94093
94381
|
return mtimeMs;
|
|
94094
94382
|
} catch (error63) {
|
|
94095
|
-
if (errorCode(error63) === "ENOENT")
|
|
94383
|
+
if (errorCode(error63) === "ENOENT") {
|
|
94384
|
+
closeFileWatch(transcriptPath);
|
|
94385
|
+
return null;
|
|
94386
|
+
}
|
|
94096
94387
|
if (!statFailing) {
|
|
94097
94388
|
deps.log(`\u26A0 transcript file not read (${errorCode(error63)}), its status waits for the next sync pass`);
|
|
94098
94389
|
}
|
|
@@ -94111,8 +94402,10 @@ function createSessionStatusFeed(deps) {
|
|
|
94111
94402
|
timer.unref?.();
|
|
94112
94403
|
writeTimers.set(transcriptPath, timer);
|
|
94113
94404
|
}
|
|
94114
|
-
const journal = createLifecycleJournalReader(deps.home, void 0,
|
|
94405
|
+
const journal = createLifecycleJournalReader(deps.home, void 0, applyJournalEntry);
|
|
94115
94406
|
function settle2() {
|
|
94407
|
+
watchReportedFiles();
|
|
94408
|
+
hookFilesRead.clear();
|
|
94116
94409
|
armDeadline();
|
|
94117
94410
|
if (!changedInBatch) return;
|
|
94118
94411
|
changedInBatch = false;
|
|
@@ -94169,6 +94462,7 @@ function createSessionStatusFeed(deps) {
|
|
|
94169
94462
|
const floorMs = lifecycleJournalRetentionFloorMs(now());
|
|
94170
94463
|
model.forgetBefore(floorMs);
|
|
94171
94464
|
held = held.filter((entry) => Date.parse(entry.at) >= floorMs);
|
|
94465
|
+
settle2();
|
|
94172
94466
|
journal.deleteExpired(now());
|
|
94173
94467
|
},
|
|
94174
94468
|
status: (harness, externalId) => model.status(harness, externalId),
|
|
@@ -94177,9 +94471,17 @@ function createSessionStatusFeed(deps) {
|
|
|
94177
94471
|
if (deadlineTimer) clearTimeout(deadlineTimer);
|
|
94178
94472
|
for (const timer of writeTimers.values()) clearTimeout(timer);
|
|
94179
94473
|
writeTimers.clear();
|
|
94474
|
+
for (const watched of fileWatches.values()) watched.close();
|
|
94475
|
+
fileWatches.clear();
|
|
94180
94476
|
}
|
|
94181
94477
|
};
|
|
94182
94478
|
}
|
|
94479
|
+
function watchFileWrites(file2, onWrite, onError2) {
|
|
94480
|
+
const watcher = fsWatch2(file2, onWrite);
|
|
94481
|
+
watcher.on("error", onError2);
|
|
94482
|
+
watcher.unref();
|
|
94483
|
+
return () => watcher.close();
|
|
94484
|
+
}
|
|
94183
94485
|
function errorCode(error63) {
|
|
94184
94486
|
return error63 instanceof Error && "code" in error63 && typeof error63.code === "string" ? error63.code : "unknown";
|
|
94185
94487
|
}
|
|
@@ -94238,6 +94540,8 @@ function createWatchLoop(deps) {
|
|
|
94238
94540
|
const newTranscripts = /* @__PURE__ */ new Map();
|
|
94239
94541
|
let newSessionTimer = null;
|
|
94240
94542
|
let newSessionPassDue = false;
|
|
94543
|
+
let newSessionRunning = false;
|
|
94544
|
+
let failedBesidePass = null;
|
|
94241
94545
|
function onEvent(change) {
|
|
94242
94546
|
if (stopped) return;
|
|
94243
94547
|
if (change === "lifecycle") lifecycleChanged = true;
|
|
@@ -94269,12 +94573,19 @@ function createWatchLoop(deps) {
|
|
|
94269
94573
|
newSessionPassDue = false;
|
|
94270
94574
|
return;
|
|
94271
94575
|
}
|
|
94272
|
-
if (
|
|
94576
|
+
if (newSessionRunning) return;
|
|
94577
|
+
if (now() < retryNotBefore) {
|
|
94578
|
+
newSessionTimer ??= setTimeout(() => {
|
|
94579
|
+
newSessionTimer = null;
|
|
94580
|
+
void newSessionPass();
|
|
94581
|
+
}, retryNotBefore - now());
|
|
94582
|
+
return;
|
|
94583
|
+
}
|
|
94273
94584
|
newSessionPassDue = false;
|
|
94274
94585
|
const transcripts = [...newTranscripts];
|
|
94275
94586
|
newTranscripts.clear();
|
|
94276
94587
|
if (transcripts.length === 0) return;
|
|
94277
|
-
|
|
94588
|
+
newSessionRunning = true;
|
|
94278
94589
|
deps.log(`${transcripts.length} new transcript file(s), uploading new session records now`);
|
|
94279
94590
|
const startedAt = now();
|
|
94280
94591
|
const known = new Set(knownSessions);
|
|
@@ -94284,21 +94595,22 @@ function createWatchLoop(deps) {
|
|
|
94284
94595
|
isNew: (session) => !known.has(sessionKey(session.item))
|
|
94285
94596
|
});
|
|
94286
94597
|
for (const session of summary.sessions) rememberSession(session);
|
|
94287
|
-
if (summary.upserted > 0) deps.onNewSessionsUploaded?.(now());
|
|
94288
94598
|
} catch (error63) {
|
|
94289
94599
|
const holdMs = Math.max(FAILED_PASS_RETRY_MS, retryAfterMs(error63) ?? 0);
|
|
94290
94600
|
retryNotBefore = Math.max(retryNotBefore, now() + holdMs);
|
|
94291
|
-
|
|
94601
|
+
const result = failedPassResult("new-session", startedAt, error63);
|
|
94602
|
+
if (running) failedBesidePass = result;
|
|
94603
|
+
else deps.onPassResult?.(result);
|
|
94292
94604
|
deps.log(
|
|
94293
94605
|
`new session records not uploaded (${describeError(error63)}), the next pass uploads them in ${describeDelay(holdMs)}`
|
|
94294
94606
|
);
|
|
94295
94607
|
}
|
|
94296
94608
|
for (const [transcript] of transcripts) rememberTranscript(transcript);
|
|
94297
|
-
|
|
94298
|
-
|
|
94609
|
+
newSessionRunning = false;
|
|
94610
|
+
void newSessionPass();
|
|
94299
94611
|
}
|
|
94300
|
-
function runNext(
|
|
94301
|
-
|
|
94612
|
+
function runNext() {
|
|
94613
|
+
void newSessionPass();
|
|
94302
94614
|
if (queued === null || running) return;
|
|
94303
94615
|
const next = queued === "steady" ? "net" : "change";
|
|
94304
94616
|
queued = null;
|
|
@@ -94385,6 +94697,7 @@ function createWatchLoop(deps) {
|
|
|
94385
94697
|
upserted: summary.upserted,
|
|
94386
94698
|
...summary.diagnostic && { diagnostic: summary.diagnostic }
|
|
94387
94699
|
});
|
|
94700
|
+
if (failedBesidePass !== null && now() < retryNotBefore) deps.onPassResult?.(failedBesidePass);
|
|
94388
94701
|
} catch (error63) {
|
|
94389
94702
|
consecutiveFailures += 1;
|
|
94390
94703
|
const signature = errorSignature(error63);
|
|
@@ -94400,7 +94713,7 @@ function createWatchLoop(deps) {
|
|
|
94400
94713
|
Math.min(FAILED_PASS_RETRY_MS * 2 ** (streakCount - 1), FAILED_PASS_BACKOFF_CAP_MS),
|
|
94401
94714
|
retryAfterMs(error63) ?? 0
|
|
94402
94715
|
);
|
|
94403
|
-
retryNotBefore = now() + holdMs;
|
|
94716
|
+
retryNotBefore = Math.max(retryNotBefore, now() + holdMs);
|
|
94404
94717
|
lifecycleChanged ||= consultLifecycle;
|
|
94405
94718
|
deps.onPassResult?.(failedPassResult(kind, startedAt, error63));
|
|
94406
94719
|
const failLine = `${kind} pass failed (${describeError(error63)})`;
|
|
@@ -94429,8 +94742,9 @@ function createWatchLoop(deps) {
|
|
|
94429
94742
|
}
|
|
94430
94743
|
}
|
|
94431
94744
|
running = false;
|
|
94745
|
+
failedBesidePass = null;
|
|
94432
94746
|
scheduleCompletionCheck();
|
|
94433
|
-
runNext(
|
|
94747
|
+
runNext();
|
|
94434
94748
|
}
|
|
94435
94749
|
function scheduleCompletionCheck() {
|
|
94436
94750
|
if (completionTimer) {
|
|
@@ -94517,7 +94831,7 @@ function watchEventChange(root, filename) {
|
|
|
94517
94831
|
}
|
|
94518
94832
|
function watchSessionStores(roots, onEvent, onLost) {
|
|
94519
94833
|
const watchers = roots.map((root) => {
|
|
94520
|
-
const watcher =
|
|
94834
|
+
const watcher = fsWatch3(root.dir, { recursive: root.recursive }, (_type, filename) => {
|
|
94521
94835
|
const change = watchEventChange(root, filename);
|
|
94522
94836
|
if (change !== "ignore") onEvent(change);
|
|
94523
94837
|
});
|
|
@@ -94531,10 +94845,12 @@ function watchSessionStores(roots, onEvent, onLost) {
|
|
|
94531
94845
|
function newSessionSyncOptions(shared, sinceMs, isNew) {
|
|
94532
94846
|
return {
|
|
94533
94847
|
lifecycleJournal: shared.lifecycleJournal,
|
|
94534
|
-
codexThreadLinks: shared.codexThreadLinks,
|
|
94535
|
-
codexThreadReads: shared.codexThreadReads,
|
|
94536
94848
|
log: shared.log,
|
|
94537
94849
|
enrollCommand: shared.enrollCommand,
|
|
94850
|
+
onRecordsUpserted: shared.onRecordsUpserted,
|
|
94851
|
+
recordTurns: shared.recordTurns,
|
|
94852
|
+
codexThreadLinks: shared.codexThreadLinks?.copyForSidePass(),
|
|
94853
|
+
codexThreadReads: shared.codexThreadReads?.copyForSidePass(),
|
|
94538
94854
|
explicitSince: String(STEADY_SYNC_WINDOW_DAYS),
|
|
94539
94855
|
narrowSinceMs: sinceMs,
|
|
94540
94856
|
isNewSession: isNew
|
|
@@ -94653,6 +94969,7 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
|
|
|
94653
94969
|
});
|
|
94654
94970
|
const writeStatus = (patch) => statusWriter.write(patch);
|
|
94655
94971
|
writeStatus({});
|
|
94972
|
+
const recordUpload = () => writeStatus({ lastUploadAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
94656
94973
|
const diagnostics = createDiagnosticsReporter(() => loadCredentials(config2.appEnv));
|
|
94657
94974
|
const checkIn = () => {
|
|
94658
94975
|
let current;
|
|
@@ -94734,6 +95051,7 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
|
|
|
94734
95051
|
const previewRegistrations = /* @__PURE__ */ new Map();
|
|
94735
95052
|
const codexThreadLinks = new CodexThreadLinks();
|
|
94736
95053
|
const codexThreadReads = new CodexThreadReads();
|
|
95054
|
+
const recordTurns = new RecordTurns();
|
|
94737
95055
|
const loop = createWatchLoop({
|
|
94738
95056
|
runPass: async (options) => {
|
|
94739
95057
|
let uploaded = 0;
|
|
@@ -94753,7 +95071,9 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
|
|
|
94753
95071
|
uploaded += 1;
|
|
94754
95072
|
if (uploaded === 1 || uploaded % 10 === 0)
|
|
94755
95073
|
log3(`Transcript progress: ${uploaded} uploaded this pass.`);
|
|
94756
|
-
}
|
|
95074
|
+
},
|
|
95075
|
+
onRecordsUpserted: recordUpload,
|
|
95076
|
+
recordTurns
|
|
94757
95077
|
};
|
|
94758
95078
|
const catchUp = createRecentCatchup(async (narrowSinceMs) => {
|
|
94759
95079
|
if (readCollectorControl(config2.appEnv, home).paused) return false;
|
|
@@ -94798,10 +95118,15 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
|
|
|
94798
95118
|
}
|
|
94799
95119
|
return summary;
|
|
94800
95120
|
},
|
|
94801
|
-
runNewSessionPass: ({ sinceMs, isNew }) => runSyncPass(config2, newSessionSyncOptions({
|
|
94802
|
-
|
|
94803
|
-
|
|
94804
|
-
|
|
95121
|
+
runNewSessionPass: ({ sinceMs, isNew }) => runSyncPass(config2, newSessionSyncOptions({
|
|
95122
|
+
lifecycleJournal: journal,
|
|
95123
|
+
log: log3,
|
|
95124
|
+
enrollCommand: runtime.enrollCommand,
|
|
95125
|
+
onRecordsUpserted: recordUpload,
|
|
95126
|
+
recordTurns,
|
|
95127
|
+
codexThreadLinks,
|
|
95128
|
+
codexThreadReads
|
|
95129
|
+
}, sinceMs, isNew)),
|
|
94805
95130
|
paused: () => readCollectorControl(config2.appEnv, home).paused,
|
|
94806
95131
|
onPassResult: (result) => writeStatus({
|
|
94807
95132
|
lastPass: {
|
|
@@ -94814,7 +95139,6 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
|
|
|
94814
95139
|
...result.diagnostic && { diagnostic: result.diagnostic }
|
|
94815
95140
|
},
|
|
94816
95141
|
...result.ok && { lastSyncAt: new Date(result.at).toISOString() },
|
|
94817
|
-
...result.ok && result.upserted > 0 && { lastUploadAt: new Date(result.at).toISOString() },
|
|
94818
95142
|
consecutiveFailures: result.ok ? 0 : statusWriter.current.consecutiveFailures + 1
|
|
94819
95143
|
}),
|
|
94820
95144
|
reportError: reportCollectorError,
|
|
@@ -95231,7 +95555,7 @@ function applyLocalSessionFlags(sessions, machineId, localFlags, localKey, claud
|
|
|
95231
95555
|
};
|
|
95232
95556
|
});
|
|
95233
95557
|
}
|
|
95234
|
-
async function fetchMemberSessions(credentials, fetchImpl = fetch, options = { windowHours: RECENT_SESSION_WINDOW_MS / 36e5, limit:
|
|
95558
|
+
async function fetchMemberSessions(credentials, fetchImpl = fetch, options = { windowHours: RECENT_SESSION_WINDOW_MS / 36e5, limit: RECENT_SESSION_PAGE_MAX }) {
|
|
95235
95559
|
const { windowHours, limit } = recentSessionOptionsSchema.parse(options);
|
|
95236
95560
|
try {
|
|
95237
95561
|
const query = new URLSearchParams({ view: "recent", windowHours: String(windowHours), limit: String(limit) });
|
|
@@ -95457,7 +95781,7 @@ async function probeClaudeDesktopSessions(wanted, installed, reportFault, root =
|
|
|
95457
95781
|
|
|
95458
95782
|
// src/menuModel.ts
|
|
95459
95783
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
95460
|
-
import { mkdirSync as mkdirSync17, rmSync as rmSync10, watch as
|
|
95784
|
+
import { mkdirSync as mkdirSync17, rmSync as rmSync10, watch as fsWatch4 } from "node:fs";
|
|
95461
95785
|
import path34 from "node:path";
|
|
95462
95786
|
|
|
95463
95787
|
// src/menu.ts
|
|
@@ -95487,7 +95811,7 @@ import { accessSync, constants as constants2, readFileSync as readFileSync15 } f
|
|
|
95487
95811
|
import path28 from "node:path";
|
|
95488
95812
|
|
|
95489
95813
|
// src/version.ts
|
|
95490
|
-
var CLI_VERSION = true ? "0.4.
|
|
95814
|
+
var CLI_VERSION = true ? "0.4.21" : "0.0.0-checkout";
|
|
95491
95815
|
var CLI_RELEASE_BUILD = true ? true : false;
|
|
95492
95816
|
var CLI_PACKAGE_NAME = "@usepowerplant/cli";
|
|
95493
95817
|
|
|
@@ -96177,8 +96501,8 @@ function syncHeader(i) {
|
|
|
96177
96501
|
if (i.credentials && (i.credentials.captureMode === "scope" || i.credentials.allowedRepos !== void 0 || i.credentials.scopePaths?.length || (i.credentials.workspacePolicies?.length ?? 0) > 1 || !i.credentials.allowedOwners?.length)) {
|
|
96178
96502
|
details.push(describeStoredCaptureSummary(i.credentials));
|
|
96179
96503
|
}
|
|
96180
|
-
const
|
|
96181
|
-
if (!i.control.paused && (
|
|
96504
|
+
const uploadedAt = lastUploadTime(i);
|
|
96505
|
+
if (!i.control.paused && (uploadedAt === void 0 || i.now - uploadedAt > 36e5)) {
|
|
96182
96506
|
details.push(lastUploadLine(i));
|
|
96183
96507
|
}
|
|
96184
96508
|
return { type: "header", title, ...details.length > 0 && { subtitle: details.join(" \xB7 ") } };
|
|
@@ -96186,7 +96510,7 @@ function syncHeader(i) {
|
|
|
96186
96510
|
var AGENT_TITLE_MAX = 48;
|
|
96187
96511
|
function recentAgentItems(i) {
|
|
96188
96512
|
if (i.memberSessions === null) return null;
|
|
96189
|
-
const recent = i.memberSessions.filter((session) => i.now - Date.parse(session.lastActivityAt) < RECENT_SESSION_WINDOW_MS).filter((session) => session.archived !== true && session.subagent !== true && session.standaloneReview !== true).sort((a, b2) => Date.parse(b2.lastActivityAt) - Date.parse(a.lastActivityAt)).map((session) => agentRow(session, i));
|
|
96513
|
+
const recent = i.memberSessions.filter((session) => i.now - Date.parse(session.lastActivityAt) < RECENT_SESSION_WINDOW_MS).filter((session) => session.archived !== true && session.subagent !== true && session.standaloneReview !== true).sort((a, b2) => Date.parse(b2.lastActivityAt) - Date.parse(a.lastActivityAt)).map((session) => agentRow(session, i)).filter((row) => row.agent?.status !== "ended");
|
|
96190
96514
|
const rows = recent.length === 0 ? [{ type: "status", mark: "muted", title: i.memberSessionsIncomplete ? "No sessions found in the partial list" : "No eligible sessions in the latest results" }] : groupedAgentRows(recent.slice(0, RECENT_SESSION_VISIBLE_LIMIT));
|
|
96191
96515
|
if (i.memberSessionsIncomplete) rows.push({
|
|
96192
96516
|
type: "status",
|
|
@@ -96214,7 +96538,7 @@ function agentRow(session, i) {
|
|
|
96214
96538
|
const harness = isLegacySessionSource(session.source) ? harnessFromLegacySessionSource(session.source) : null;
|
|
96215
96539
|
const harnessName = harness?.kind === "harness" ? harness.harness : session.source;
|
|
96216
96540
|
const status = localMachine && harness?.kind === "harness" && i.sessionStatus !== void 0 ? i.sessionStatus(harness.harness, session.externalId) ?? "unknown" : void 0;
|
|
96217
|
-
const statusLabel = status ===
|
|
96541
|
+
const statusLabel = status === "waiting" ? LOCAL_SESSION_STATUS_LABELS.waiting : null;
|
|
96218
96542
|
const desktopSessionId = localMachine && session.source === "claude-code" ? i.claudeDesktopSessions?.get(session.externalId)?.sessionId : void 0;
|
|
96219
96543
|
const app = desktopSessionId !== void 0 ? "Claude desktop" : isLegacySessionSource(session.source) ? describeSessionSource(session.source) : session.source;
|
|
96220
96544
|
const links = sessionLinks(session, i.config.webUrl, {
|
|
@@ -96298,10 +96622,16 @@ function menuContentKey(payload) {
|
|
|
96298
96622
|
});
|
|
96299
96623
|
return JSON.stringify({ ...shown, desktopDiagnostic: void 0 });
|
|
96300
96624
|
}
|
|
96625
|
+
function lastUploadTime(i) {
|
|
96626
|
+
if (!("status" in i.daemon)) return void 0;
|
|
96627
|
+
const { lastSyncAt, lastUploadAt } = i.daemon.status;
|
|
96628
|
+
const times = [lastSyncAt, lastUploadAt].map((at) => Date.parse(at ?? "")).filter((at) => !Number.isNaN(at));
|
|
96629
|
+
return times.length === 0 ? void 0 : Math.max(...times);
|
|
96630
|
+
}
|
|
96301
96631
|
function lastUploadLine(i) {
|
|
96302
|
-
const
|
|
96303
|
-
if (
|
|
96304
|
-
return `Last upload ${ago(i.now -
|
|
96632
|
+
const uploadedAt = lastUploadTime(i);
|
|
96633
|
+
if (uploadedAt === void 0) return "No successful upload yet";
|
|
96634
|
+
return `Last upload ${ago(i.now - uploadedAt)}`;
|
|
96305
96635
|
}
|
|
96306
96636
|
function connectionRow(connection, envArgs, now) {
|
|
96307
96637
|
const name = CLIENT_NAMES[connection.client];
|
|
@@ -97894,7 +98224,7 @@ function startMenuModel(sources) {
|
|
|
97894
98224
|
const dir = path34.dirname(menuRefreshRequestPath(appEnv, host.home));
|
|
97895
98225
|
mkdirSync17(dir, { recursive: true, mode: 448 });
|
|
97896
98226
|
const openFile = path34.basename(menuOpenRequestPath(appEnv, host.home));
|
|
97897
|
-
const watcher =
|
|
98227
|
+
const watcher = fsWatch4(dir, (_event, filename) => onRequest(filename === openFile ? "menu-open" : "command"));
|
|
97898
98228
|
watcher.on("error", onLost);
|
|
97899
98229
|
return () => watcher.close();
|
|
97900
98230
|
},
|
|
@@ -97960,7 +98290,7 @@ function renderDoctorReport(i) {
|
|
|
97960
98290
|
);
|
|
97961
98291
|
const unsupported = unsupportedVersionNotice(i.cliVersion, i.oldestSupportedVersion);
|
|
97962
98292
|
if (unsupported !== null) lines.push(unsupported);
|
|
97963
|
-
lines.push(`Environment: ${i.config.appEnv} (API ${i.config.apiUrl})`);
|
|
98293
|
+
lines.push(`Environment: ${i.config.appEnv} (API ${i.credentials?.apiUrl ?? i.config.apiUrl})`);
|
|
97964
98294
|
lines.push(`Node: ${i.nodeVersion} (${i.platform})`);
|
|
97965
98295
|
lines.push(installLine(i.install));
|
|
97966
98296
|
lines.push(enrollmentLine(i));
|
|
@@ -98070,16 +98400,16 @@ var CLI_ENVIRONMENTS = {
|
|
|
98070
98400
|
appEnv: "production",
|
|
98071
98401
|
supabaseUrl: "https://jcwzvorqlsquudjoqbza.supabase.co",
|
|
98072
98402
|
supabasePublishableKey: "sb_publishable_vcGj0Spjl7oyXzrgLHUfBA_8fbpMuWb",
|
|
98073
|
-
apiUrl: "https://api.
|
|
98074
|
-
webUrl: "https://app.
|
|
98403
|
+
apiUrl: "https://api.usepowerplant.com",
|
|
98404
|
+
webUrl: "https://app.usepowerplant.com",
|
|
98075
98405
|
sentryDsn: SHARED_SENTRY_DSN
|
|
98076
98406
|
},
|
|
98077
98407
|
staging: {
|
|
98078
98408
|
appEnv: "staging",
|
|
98079
98409
|
supabaseUrl: "https://zadwpjlzfwqbrvegurfz.supabase.co",
|
|
98080
98410
|
supabasePublishableKey: "sb_publishable_z6Ey6GkxmpPHaNbsu3tZtA_TQoNXZJF",
|
|
98081
|
-
apiUrl: "https://staging.api.
|
|
98082
|
-
webUrl: "https://staging.app.
|
|
98411
|
+
apiUrl: "https://staging.api.usepowerplant.com",
|
|
98412
|
+
webUrl: "https://staging.app.usepowerplant.com",
|
|
98083
98413
|
sentryDsn: SHARED_SENTRY_DSN
|
|
98084
98414
|
},
|
|
98085
98415
|
agent: {
|
|
@@ -100093,4 +100423,4 @@ undici/lib/web/websocket/frame.js:
|
|
|
100093
100423
|
(*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
|
|
100094
100424
|
*/
|
|
100095
100425
|
|
|
100096
|
-
//# debugId=
|
|
100426
|
+
//# debugId=9ee35b05-7453-5338-85ff-5dc1b6010221
|