appostle-installer 0.0.13 → 0.0.14
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/dist/appostle.js +428 -181
- package/dist/appostle.js.map +4 -4
- package/dist/worker.js +486 -222
- package/dist/worker.js.map +4 -4
- package/package.json +1 -1
package/dist/worker.js
CHANGED
|
@@ -16,10 +16,10 @@ __export(rightfont_service_exports, {
|
|
|
16
16
|
isRightFontLibrary: () => isRightFontLibrary,
|
|
17
17
|
readRightFontLibrary: () => readRightFontLibrary
|
|
18
18
|
});
|
|
19
|
-
import { existsSync as
|
|
19
|
+
import { existsSync as existsSync11, readdirSync, readFileSync as readFileSync6 } from "node:fs";
|
|
20
20
|
import { join as join12 } from "node:path";
|
|
21
21
|
function isRightFontLibrary(libraryPath) {
|
|
22
|
-
return libraryPath.endsWith(".rightfontlibrary") &&
|
|
22
|
+
return libraryPath.endsWith(".rightfontlibrary") && existsSync11(join12(libraryPath, "fonts")) && existsSync11(join12(libraryPath, "metadata"));
|
|
23
23
|
}
|
|
24
24
|
function readRightFontLibrary(libraryPath) {
|
|
25
25
|
if (!isRightFontLibrary(libraryPath)) {
|
|
@@ -30,7 +30,7 @@ function readRightFontLibrary(libraryPath) {
|
|
|
30
30
|
const metadataListsDir = join12(libraryPath, "metadata", "fontlists");
|
|
31
31
|
const familyMap = /* @__PURE__ */ new Map();
|
|
32
32
|
let totalFonts = 0;
|
|
33
|
-
if (
|
|
33
|
+
if (existsSync11(metadataFontsDir)) {
|
|
34
34
|
const files = readdirSync(metadataFontsDir).filter((f) => f.endsWith(".rightfontmetadata"));
|
|
35
35
|
for (const file of files) {
|
|
36
36
|
try {
|
|
@@ -70,7 +70,7 @@ function readRightFontLibrary(libraryPath) {
|
|
|
70
70
|
fam.fonts.sort((a, b) => a.weight - b.weight || a.style.localeCompare(b.style));
|
|
71
71
|
}
|
|
72
72
|
const collections = [];
|
|
73
|
-
if (
|
|
73
|
+
if (existsSync11(metadataListsDir)) {
|
|
74
74
|
const files = readdirSync(metadataListsDir).filter((f) => f.endsWith(".rightfontmetadata"));
|
|
75
75
|
for (const file of files) {
|
|
76
76
|
try {
|
|
@@ -255,11 +255,11 @@ import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
|
255
255
|
// ../server/src/server/bootstrap.ts
|
|
256
256
|
import express from "express";
|
|
257
257
|
import { createServer as createHTTPServer } from "http";
|
|
258
|
-
import { createReadStream, unlinkSync, existsSync as
|
|
258
|
+
import { createReadStream, unlinkSync, existsSync as existsSync20 } from "fs";
|
|
259
259
|
import { stat as stat9 } from "fs/promises";
|
|
260
260
|
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
261
261
|
import { hostname as getHostname2 } from "node:os";
|
|
262
|
-
import
|
|
262
|
+
import path34 from "node:path";
|
|
263
263
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
264
264
|
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
265
265
|
|
|
@@ -712,18 +712,18 @@ function resolveNodePtyPackageRoot() {
|
|
|
712
712
|
return null;
|
|
713
713
|
}
|
|
714
714
|
}
|
|
715
|
-
function ensureExecutableBit(
|
|
716
|
-
if (!existsSync2(
|
|
715
|
+
function ensureExecutableBit(path38) {
|
|
716
|
+
if (!existsSync2(path38)) {
|
|
717
717
|
return;
|
|
718
718
|
}
|
|
719
|
-
const stat10 = statSync(
|
|
719
|
+
const stat10 = statSync(path38);
|
|
720
720
|
if (!stat10.isFile()) {
|
|
721
721
|
return;
|
|
722
722
|
}
|
|
723
723
|
if ((stat10.mode & 73) === 73) {
|
|
724
724
|
return;
|
|
725
725
|
}
|
|
726
|
-
chmodSync(
|
|
726
|
+
chmodSync(path38, stat10.mode | 73);
|
|
727
727
|
}
|
|
728
728
|
function ensureNodePtySpawnHelperExecutableForCurrentPlatform(options = {}) {
|
|
729
729
|
const platform = options.platform ?? process.platform;
|
|
@@ -1341,11 +1341,11 @@ function parseGitRevParsePath(stdout) {
|
|
|
1341
1341
|
if (lines.length !== 1) {
|
|
1342
1342
|
return null;
|
|
1343
1343
|
}
|
|
1344
|
-
const
|
|
1345
|
-
if (!
|
|
1344
|
+
const path38 = lines[0]?.trim() ?? "";
|
|
1345
|
+
if (!path38 || path38.startsWith("--")) {
|
|
1346
1346
|
return null;
|
|
1347
1347
|
}
|
|
1348
|
-
return
|
|
1348
|
+
return path38;
|
|
1349
1349
|
}
|
|
1350
1350
|
function resolveGitRevParsePath(cwd, stdout) {
|
|
1351
1351
|
const parsed = parseGitRevParsePath(stdout);
|
|
@@ -2118,9 +2118,9 @@ async function deleteAppostleWorktree({
|
|
|
2118
2118
|
}
|
|
2119
2119
|
}
|
|
2120
2120
|
}
|
|
2121
|
-
async function pathExists(
|
|
2121
|
+
async function pathExists(path38) {
|
|
2122
2122
|
try {
|
|
2123
|
-
await stat(
|
|
2123
|
+
await stat(path38);
|
|
2124
2124
|
return true;
|
|
2125
2125
|
} catch (error) {
|
|
2126
2126
|
if (error.code === "ENOENT") {
|
|
@@ -2129,8 +2129,8 @@ async function pathExists(path37) {
|
|
|
2129
2129
|
throw error;
|
|
2130
2130
|
}
|
|
2131
2131
|
}
|
|
2132
|
-
async function removeDirectoryWithRetries(
|
|
2133
|
-
if (!await pathExists(
|
|
2132
|
+
async function removeDirectoryWithRetries(path38) {
|
|
2133
|
+
if (!await pathExists(path38)) {
|
|
2134
2134
|
return;
|
|
2135
2135
|
}
|
|
2136
2136
|
const delaysMs = [0, 100, 300, 700, 1500];
|
|
@@ -2140,17 +2140,17 @@ async function removeDirectoryWithRetries(path37) {
|
|
|
2140
2140
|
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
2141
2141
|
}
|
|
2142
2142
|
try {
|
|
2143
|
-
await rm(
|
|
2144
|
-
if (!await pathExists(
|
|
2143
|
+
await rm(path38, { recursive: true, force: true });
|
|
2144
|
+
if (!await pathExists(path38)) {
|
|
2145
2145
|
return;
|
|
2146
2146
|
}
|
|
2147
|
-
lastError = new Error(`Directory still present after rm: ${
|
|
2147
|
+
lastError = new Error(`Directory still present after rm: ${path38}`);
|
|
2148
2148
|
} catch (error) {
|
|
2149
2149
|
lastError = error;
|
|
2150
2150
|
}
|
|
2151
2151
|
}
|
|
2152
|
-
if (await pathExists(
|
|
2153
|
-
throw lastError instanceof Error ? lastError : new Error(`Failed to remove worktree directory: ${
|
|
2152
|
+
if (await pathExists(path38)) {
|
|
2153
|
+
throw lastError instanceof Error ? lastError : new Error(`Failed to remove worktree directory: ${path38}`);
|
|
2154
2154
|
}
|
|
2155
2155
|
}
|
|
2156
2156
|
var createWorktree = async ({
|
|
@@ -5836,6 +5836,50 @@ var LinkAccountResponseMessageSchema = z11.object({
|
|
|
5836
5836
|
})
|
|
5837
5837
|
])
|
|
5838
5838
|
});
|
|
5839
|
+
var ClaudeProfileLoginRequestMessageSchema = z11.object({
|
|
5840
|
+
type: z11.literal("claude_profile_login_request"),
|
|
5841
|
+
requestId: z11.string(),
|
|
5842
|
+
/** Username for the profile dir (~/.claude-{username}/). */
|
|
5843
|
+
username: z11.string().min(1)
|
|
5844
|
+
});
|
|
5845
|
+
var ClaudeProfileLoginUrlMessageSchema = z11.object({
|
|
5846
|
+
type: z11.literal("claude_profile_login_url"),
|
|
5847
|
+
requestId: z11.string(),
|
|
5848
|
+
url: z11.string().min(1)
|
|
5849
|
+
});
|
|
5850
|
+
var ClaudeProfileLoginCallbackMessageSchema = z11.object({
|
|
5851
|
+
type: z11.literal("claude_profile_login_callback"),
|
|
5852
|
+
requestId: z11.string(),
|
|
5853
|
+
callbackToken: z11.string().min(1)
|
|
5854
|
+
});
|
|
5855
|
+
var ClaudeProfileLoginResultMessageSchema = z11.object({
|
|
5856
|
+
type: z11.literal("claude_profile_login_result"),
|
|
5857
|
+
requestId: z11.string(),
|
|
5858
|
+
ok: z11.boolean(),
|
|
5859
|
+
error: z11.string().optional()
|
|
5860
|
+
});
|
|
5861
|
+
var ClaudeProfileRemoveRequestMessageSchema = z11.object({
|
|
5862
|
+
type: z11.literal("claude_profile_remove_request"),
|
|
5863
|
+
requestId: z11.string(),
|
|
5864
|
+
username: z11.string().min(1)
|
|
5865
|
+
});
|
|
5866
|
+
var ClaudeProfileRemoveResponseMessageSchema = z11.object({
|
|
5867
|
+
type: z11.literal("claude_profile_remove_response"),
|
|
5868
|
+
requestId: z11.string(),
|
|
5869
|
+
ok: z11.boolean(),
|
|
5870
|
+
error: z11.string().optional()
|
|
5871
|
+
});
|
|
5872
|
+
var ClaudeProfileStatusRequestMessageSchema = z11.object({
|
|
5873
|
+
type: z11.literal("claude_profile_status_request"),
|
|
5874
|
+
requestId: z11.string(),
|
|
5875
|
+
username: z11.string().min(1)
|
|
5876
|
+
});
|
|
5877
|
+
var ClaudeProfileStatusResponseMessageSchema = z11.object({
|
|
5878
|
+
type: z11.literal("claude_profile_status_response"),
|
|
5879
|
+
requestId: z11.string(),
|
|
5880
|
+
hasProfile: z11.boolean(),
|
|
5881
|
+
isAuthenticated: z11.boolean()
|
|
5882
|
+
});
|
|
5839
5883
|
var ListSessionUploadsRequestSchema = z11.object({
|
|
5840
5884
|
type: z11.literal("list_session_uploads_request"),
|
|
5841
5885
|
requestId: z11.string(),
|
|
@@ -5966,6 +6010,10 @@ var SessionInboundMessageSchema = z11.discriminatedUnion("type", [
|
|
|
5966
6010
|
AbortRequestMessageSchema,
|
|
5967
6011
|
AudioPlayedMessageSchema,
|
|
5968
6012
|
LinkAccountRequestMessageSchema,
|
|
6013
|
+
ClaudeProfileLoginRequestMessageSchema,
|
|
6014
|
+
ClaudeProfileLoginCallbackMessageSchema,
|
|
6015
|
+
ClaudeProfileStatusRequestMessageSchema,
|
|
6016
|
+
ClaudeProfileRemoveRequestMessageSchema,
|
|
5969
6017
|
FetchAgentsRequestMessageSchema,
|
|
5970
6018
|
FetchWorkspacesRequestMessageSchema,
|
|
5971
6019
|
FetchAgentRequestMessageSchema,
|
|
@@ -7691,6 +7739,10 @@ var SessionOutboundMessageSchema = z11.discriminatedUnion("type", [
|
|
|
7691
7739
|
GoogleFontsDownloadResponseSchema,
|
|
7692
7740
|
GetVapidPublicKeyResponseSchema,
|
|
7693
7741
|
LinkAccountResponseMessageSchema,
|
|
7742
|
+
ClaudeProfileLoginUrlMessageSchema,
|
|
7743
|
+
ClaudeProfileLoginResultMessageSchema,
|
|
7744
|
+
ClaudeProfileStatusResponseMessageSchema,
|
|
7745
|
+
ClaudeProfileRemoveResponseMessageSchema,
|
|
7694
7746
|
ListSessionUploadsResponseSchema,
|
|
7695
7747
|
DeleteSessionUploadResponseSchema,
|
|
7696
7748
|
ListSessionImagesResponseSchema,
|
|
@@ -7712,7 +7764,11 @@ var WSHelloMessageSchema = z11.object({
|
|
|
7712
7764
|
capabilities: z11.object({
|
|
7713
7765
|
voice: z11.boolean().optional(),
|
|
7714
7766
|
pushNotifications: z11.boolean().optional()
|
|
7715
|
-
}).passthrough().optional()
|
|
7767
|
+
}).passthrough().optional(),
|
|
7768
|
+
/** Auth-server userId of the connecting user. Used for per-user Claude profile selection. */
|
|
7769
|
+
userId: z11.string().optional(),
|
|
7770
|
+
/** Display name of the connecting user (for profile dir naming). */
|
|
7771
|
+
username: z11.string().optional()
|
|
7716
7772
|
});
|
|
7717
7773
|
var WSRecordingStateMessageSchema = z11.object({
|
|
7718
7774
|
type: z11.literal("recording_state"),
|
|
@@ -10229,14 +10285,14 @@ var DictationStreamManager = class {
|
|
|
10229
10285
|
PCM_CHANNELS,
|
|
10230
10286
|
PCM_BITS_PER_SAMPLE
|
|
10231
10287
|
);
|
|
10232
|
-
const
|
|
10288
|
+
const path38 = await maybePersistDictationDebugAudio(
|
|
10233
10289
|
wavBuffer,
|
|
10234
10290
|
{ sessionId: state.sessionId, dictationId: state.dictationId, format: "audio/wav" },
|
|
10235
10291
|
this.logger,
|
|
10236
10292
|
state.debugChunkWriter?.folder
|
|
10237
10293
|
);
|
|
10238
|
-
state.debugRecordingPath =
|
|
10239
|
-
return
|
|
10294
|
+
state.debugRecordingPath = path38;
|
|
10295
|
+
return path38;
|
|
10240
10296
|
}
|
|
10241
10297
|
failDictationStream(dictationId, error, retryable) {
|
|
10242
10298
|
this.emit({
|
|
@@ -12247,14 +12303,14 @@ function parseDiff(diffText) {
|
|
|
12247
12303
|
const firstLine = lines[0];
|
|
12248
12304
|
const isNew = section.includes("new file mode") || section.includes("--- /dev/null");
|
|
12249
12305
|
const isDeleted = section.includes("deleted file mode") || section.includes("+++ /dev/null");
|
|
12250
|
-
let
|
|
12306
|
+
let path38 = "unknown";
|
|
12251
12307
|
const pathMatch = firstLine.match(/a\/(.*?) b\//);
|
|
12252
12308
|
if (pathMatch) {
|
|
12253
|
-
|
|
12309
|
+
path38 = pathMatch[1];
|
|
12254
12310
|
} else {
|
|
12255
12311
|
const newFileMatch = firstLine.match(/b\/(.+)$/);
|
|
12256
12312
|
if (newFileMatch) {
|
|
12257
|
-
|
|
12313
|
+
path38 = newFileMatch[1];
|
|
12258
12314
|
}
|
|
12259
12315
|
}
|
|
12260
12316
|
const hunks = [];
|
|
@@ -12298,7 +12354,7 @@ function parseDiff(diffText) {
|
|
|
12298
12354
|
if (currentHunk) {
|
|
12299
12355
|
hunks.push(currentHunk);
|
|
12300
12356
|
}
|
|
12301
|
-
files.push({ path:
|
|
12357
|
+
files.push({ path: path38, isNew, isDeleted, additions, deletions, hunks });
|
|
12302
12358
|
}
|
|
12303
12359
|
return files;
|
|
12304
12360
|
}
|
|
@@ -12354,9 +12410,9 @@ function buildTokenLookup(lineMap, highlighted) {
|
|
|
12354
12410
|
}
|
|
12355
12411
|
return lookup;
|
|
12356
12412
|
}
|
|
12357
|
-
function buildFullFileTokenLookup(fileContent,
|
|
12413
|
+
function buildFullFileTokenLookup(fileContent, path38) {
|
|
12358
12414
|
const lookup = /* @__PURE__ */ new Map();
|
|
12359
|
-
const highlighted = highlightCode(fileContent,
|
|
12415
|
+
const highlighted = highlightCode(fileContent, path38);
|
|
12360
12416
|
for (let i = 0; i < highlighted.length; i++) {
|
|
12361
12417
|
lookup.set(i + 1, highlighted[i]);
|
|
12362
12418
|
}
|
|
@@ -14061,11 +14117,11 @@ async function listCheckoutFileChanges(cwd, ref, ignoreWhitespace = false) {
|
|
|
14061
14117
|
}
|
|
14062
14118
|
continue;
|
|
14063
14119
|
}
|
|
14064
|
-
const
|
|
14065
|
-
if (!
|
|
14120
|
+
const path38 = tabParts[1];
|
|
14121
|
+
if (!path38) continue;
|
|
14066
14122
|
const code = rawStatus[0];
|
|
14067
14123
|
changes.push({
|
|
14068
|
-
path:
|
|
14124
|
+
path: path38,
|
|
14069
14125
|
status: rawStatus,
|
|
14070
14126
|
isNew: code === "A",
|
|
14071
14127
|
isDeleted: code === "D"
|
|
@@ -14100,9 +14156,9 @@ async function listCheckoutFileChanges(cwd, ref, ignoreWhitespace = false) {
|
|
|
14100
14156
|
}
|
|
14101
14157
|
return Array.from(byPath.values());
|
|
14102
14158
|
}
|
|
14103
|
-
async function readGitFileContentAtRef(cwd, ref,
|
|
14159
|
+
async function readGitFileContentAtRef(cwd, ref, path38) {
|
|
14104
14160
|
try {
|
|
14105
|
-
const { stdout } = await runGitCommand(["show", `${ref}:${
|
|
14161
|
+
const { stdout } = await runGitCommand(["show", `${ref}:${path38}`], {
|
|
14106
14162
|
cwd,
|
|
14107
14163
|
env: READ_ONLY_GIT_ENV2
|
|
14108
14164
|
});
|
|
@@ -14163,21 +14219,21 @@ async function getTrackedNumstatByPath(cwd, ref, ignoreWhitespace = false) {
|
|
|
14163
14219
|
const additionsField = parts[0] ?? "";
|
|
14164
14220
|
const deletionsField = parts[1] ?? "";
|
|
14165
14221
|
const rawPath = parts.slice(2).join(" ");
|
|
14166
|
-
const
|
|
14167
|
-
if (!
|
|
14222
|
+
const path38 = normalizeNumstatPath(rawPath);
|
|
14223
|
+
if (!path38) {
|
|
14168
14224
|
continue;
|
|
14169
14225
|
}
|
|
14170
14226
|
if (additionsField === "-" || deletionsField === "-") {
|
|
14171
|
-
stats.set(
|
|
14227
|
+
stats.set(path38, { additions: 0, deletions: 0, isBinary: true });
|
|
14172
14228
|
continue;
|
|
14173
14229
|
}
|
|
14174
14230
|
const additions = Number.parseInt(additionsField, 10);
|
|
14175
14231
|
const deletions = Number.parseInt(deletionsField, 10);
|
|
14176
14232
|
if (Number.isNaN(additions) || Number.isNaN(deletions)) {
|
|
14177
|
-
stats.set(
|
|
14233
|
+
stats.set(path38, null);
|
|
14178
14234
|
continue;
|
|
14179
14235
|
}
|
|
14180
|
-
stats.set(
|
|
14236
|
+
stats.set(path38, { additions, deletions, isBinary: false });
|
|
14181
14237
|
}
|
|
14182
14238
|
return stats;
|
|
14183
14239
|
}
|
|
@@ -14869,10 +14925,10 @@ async function listUncommittedFiles(cwd) {
|
|
|
14869
14925
|
if (dest) results.push({ path: dest, changeType: code });
|
|
14870
14926
|
continue;
|
|
14871
14927
|
}
|
|
14872
|
-
const
|
|
14873
|
-
if (!
|
|
14928
|
+
const path38 = parts[1];
|
|
14929
|
+
if (!path38) continue;
|
|
14874
14930
|
if (code === "A" || code === "M" || code === "D") {
|
|
14875
|
-
results.push({ path:
|
|
14931
|
+
results.push({ path: path38, changeType: code });
|
|
14876
14932
|
}
|
|
14877
14933
|
}
|
|
14878
14934
|
} catch {
|
|
@@ -18915,12 +18971,12 @@ function extractPlanNameFromFrontmatter(content) {
|
|
|
18915
18971
|
return null;
|
|
18916
18972
|
}
|
|
18917
18973
|
function resolvePlanFilename(options) {
|
|
18918
|
-
const { originalPath, newSlug, existsSync:
|
|
18974
|
+
const { originalPath, newSlug, existsSync: existsSync23 } = options;
|
|
18919
18975
|
const dir = path8.dirname(originalPath);
|
|
18920
18976
|
const base = `${newSlug}.md`;
|
|
18921
18977
|
let candidate = path8.join(dir, base);
|
|
18922
18978
|
let counter = 2;
|
|
18923
|
-
while (candidate !== originalPath &&
|
|
18979
|
+
while (candidate !== originalPath && existsSync23(candidate)) {
|
|
18924
18980
|
candidate = path8.join(dir, `${newSlug}-${counter}.md`);
|
|
18925
18981
|
counter += 1;
|
|
18926
18982
|
}
|
|
@@ -23157,14 +23213,14 @@ function codexApplyPatchToUnifiedDiff(text) {
|
|
|
23157
23213
|
for (const line of lines) {
|
|
23158
23214
|
const directive = parseCodexApplyPatchDirective(line);
|
|
23159
23215
|
if (directive) {
|
|
23160
|
-
const
|
|
23161
|
-
if (
|
|
23216
|
+
const path38 = normalizeDiffHeaderPath(directive.path);
|
|
23217
|
+
if (path38.length > 0) {
|
|
23162
23218
|
if (output.length > 0 && output[output.length - 1] !== "") {
|
|
23163
23219
|
output.push("");
|
|
23164
23220
|
}
|
|
23165
|
-
const left = directive.kind === "add" ? "/dev/null" : `a/${
|
|
23166
|
-
const right = directive.kind === "delete" ? "/dev/null" : `b/${
|
|
23167
|
-
output.push(`diff --git a/${
|
|
23221
|
+
const left = directive.kind === "add" ? "/dev/null" : `a/${path38}`;
|
|
23222
|
+
const right = directive.kind === "delete" ? "/dev/null" : `b/${path38}`;
|
|
23223
|
+
output.push(`diff --git a/${path38} b/${path38}`);
|
|
23168
23224
|
output.push(`--- ${left}`);
|
|
23169
23225
|
output.push(`+++ ${right}`);
|
|
23170
23226
|
sawDiffContent = true;
|
|
@@ -23234,9 +23290,9 @@ function asEditTextFields(text) {
|
|
|
23234
23290
|
function normalizeRolloutEditInput(input) {
|
|
23235
23291
|
if (typeof input === "string") {
|
|
23236
23292
|
const textFields2 = asEditTextFields(input);
|
|
23237
|
-
const
|
|
23293
|
+
const path38 = extractPatchPrimaryFilePath(input);
|
|
23238
23294
|
return {
|
|
23239
|
-
...
|
|
23295
|
+
...path38 ? { path: path38 } : {},
|
|
23240
23296
|
...textFields2.unifiedDiff ? { patch: textFields2.unifiedDiff } : {},
|
|
23241
23297
|
...textFields2.newString ? { content: textFields2.newString } : {}
|
|
23242
23298
|
};
|
|
@@ -23384,12 +23440,12 @@ function parseFileChangeDiff(entry) {
|
|
|
23384
23440
|
]);
|
|
23385
23441
|
}
|
|
23386
23442
|
function toFileChangeEntry(entry, options, fallbackPath) {
|
|
23387
|
-
const
|
|
23388
|
-
if (!
|
|
23443
|
+
const path38 = parseFileChangePath(entry, options, fallbackPath);
|
|
23444
|
+
if (!path38) {
|
|
23389
23445
|
return null;
|
|
23390
23446
|
}
|
|
23391
23447
|
return {
|
|
23392
|
-
path:
|
|
23448
|
+
path: path38,
|
|
23393
23449
|
kind: parseFileChangeKind(entry),
|
|
23394
23450
|
diff: parseFileChangeDiff(entry)
|
|
23395
23451
|
};
|
|
@@ -23411,12 +23467,12 @@ function parseFileChangeEntries(changes, options) {
|
|
|
23411
23467
|
if (singleEntry) {
|
|
23412
23468
|
return [singleEntry];
|
|
23413
23469
|
}
|
|
23414
|
-
return Object.entries(changes).map(([
|
|
23470
|
+
return Object.entries(changes).map(([path38, value]) => {
|
|
23415
23471
|
if (isRecord2(value)) {
|
|
23416
|
-
return toFileChangeEntry(value, options,
|
|
23472
|
+
return toFileChangeEntry(value, options, path38);
|
|
23417
23473
|
}
|
|
23418
23474
|
if (typeof value === "string") {
|
|
23419
|
-
const normalizedPath = normalizeCodexFilePath(
|
|
23475
|
+
const normalizedPath = normalizeCodexFilePath(path38.trim(), options?.cwd);
|
|
23420
23476
|
if (!normalizedPath) {
|
|
23421
23477
|
return null;
|
|
23422
23478
|
}
|
|
@@ -24161,16 +24217,16 @@ function isObjectSchemaNode(schema) {
|
|
|
24161
24217
|
const type = schema.type;
|
|
24162
24218
|
return isSchemaRecord(schema.properties) || type === "object" || Array.isArray(type) && type.includes("object");
|
|
24163
24219
|
}
|
|
24164
|
-
function normalizeCodexOutputSchemaNode(schema,
|
|
24220
|
+
function normalizeCodexOutputSchemaNode(schema, path38) {
|
|
24165
24221
|
if (Array.isArray(schema)) {
|
|
24166
|
-
return schema.map((entry, index) => normalizeCodexOutputSchemaNode(entry, `${
|
|
24222
|
+
return schema.map((entry, index) => normalizeCodexOutputSchemaNode(entry, `${path38}[${index}]`));
|
|
24167
24223
|
}
|
|
24168
24224
|
if (!isSchemaRecord(schema)) {
|
|
24169
24225
|
return schema;
|
|
24170
24226
|
}
|
|
24171
24227
|
const normalized = {};
|
|
24172
24228
|
for (const [key, value] of Object.entries(schema)) {
|
|
24173
|
-
normalized[key] = normalizeCodexOutputSchemaNode(value, `${
|
|
24229
|
+
normalized[key] = normalizeCodexOutputSchemaNode(value, `${path38}.${key}`);
|
|
24174
24230
|
}
|
|
24175
24231
|
if (!isObjectSchemaNode(normalized)) {
|
|
24176
24232
|
return normalized;
|
|
@@ -24179,7 +24235,7 @@ function normalizeCodexOutputSchemaNode(schema, path37) {
|
|
|
24179
24235
|
normalized.additionalProperties = false;
|
|
24180
24236
|
} else if (normalized.additionalProperties !== false) {
|
|
24181
24237
|
throw new Error(
|
|
24182
|
-
`Codex structured outputs require ${
|
|
24238
|
+
`Codex structured outputs require ${path38} to set additionalProperties to false for object schemas.`
|
|
24183
24239
|
);
|
|
24184
24240
|
}
|
|
24185
24241
|
const properties = isSchemaRecord(normalized.properties) ? normalized.properties : null;
|
|
@@ -24943,8 +24999,8 @@ function parseCodexPatchChanges(changes) {
|
|
|
24943
24999
|
}
|
|
24944
25000
|
];
|
|
24945
25001
|
}
|
|
24946
|
-
return Object.entries(recordChanges).map(([
|
|
24947
|
-
const normalizedPath =
|
|
25002
|
+
return Object.entries(recordChanges).map(([path38, value]) => {
|
|
25003
|
+
const normalizedPath = path38.trim();
|
|
24948
25004
|
if (!normalizedPath) {
|
|
24949
25005
|
return null;
|
|
24950
25006
|
}
|
|
@@ -32717,8 +32773,8 @@ function buildZodValidator(schema, schemaName) {
|
|
|
32717
32773
|
return { ok: true, value: result.data };
|
|
32718
32774
|
}
|
|
32719
32775
|
const errors = result.error.issues.map((issue) => {
|
|
32720
|
-
const
|
|
32721
|
-
return `${
|
|
32776
|
+
const path38 = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
32777
|
+
return `${path38}: ${issue.message}`;
|
|
32722
32778
|
});
|
|
32723
32779
|
return { ok: false, errors };
|
|
32724
32780
|
}
|
|
@@ -32736,9 +32792,9 @@ function buildJsonSchemaValidator(schema) {
|
|
|
32736
32792
|
return { ok: true, value };
|
|
32737
32793
|
}
|
|
32738
32794
|
const errors = (validate.errors ?? []).map((error) => {
|
|
32739
|
-
const
|
|
32795
|
+
const path38 = error.instancePath && error.instancePath.length > 0 ? error.instancePath : "(root)";
|
|
32740
32796
|
const message = error.message ?? "is invalid";
|
|
32741
|
-
return `${
|
|
32797
|
+
return `${path38}: ${message}`;
|
|
32742
32798
|
});
|
|
32743
32799
|
return { ok: false, errors };
|
|
32744
32800
|
}
|
|
@@ -34342,15 +34398,15 @@ async function getProjectIcon(projectDir) {
|
|
|
34342
34398
|
|
|
34343
34399
|
// ../server/src/utils/path.ts
|
|
34344
34400
|
import os5 from "os";
|
|
34345
|
-
function expandTilde(
|
|
34346
|
-
if (
|
|
34401
|
+
function expandTilde(path38) {
|
|
34402
|
+
if (path38.startsWith("~/")) {
|
|
34347
34403
|
const homeDir3 = process.env.HOME || os5.homedir();
|
|
34348
|
-
return
|
|
34404
|
+
return path38.replace("~", homeDir3);
|
|
34349
34405
|
}
|
|
34350
|
-
if (
|
|
34406
|
+
if (path38 === "~") {
|
|
34351
34407
|
return process.env.HOME || os5.homedir();
|
|
34352
34408
|
}
|
|
34353
|
-
return
|
|
34409
|
+
return path38;
|
|
34354
34410
|
}
|
|
34355
34411
|
|
|
34356
34412
|
// ../server/src/server/skills/scanner.ts
|
|
@@ -37280,6 +37336,45 @@ async function generateAndApplyArtDirection(options) {
|
|
|
37280
37336
|
return { generatedCount: acceptedUpdates.size };
|
|
37281
37337
|
}
|
|
37282
37338
|
|
|
37339
|
+
// ../server/src/server/claude-profile.ts
|
|
37340
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync5, symlinkSync, rmSync as rmSync2 } from "node:fs";
|
|
37341
|
+
import path22 from "node:path";
|
|
37342
|
+
import os8 from "node:os";
|
|
37343
|
+
var SHARED_ITEMS = ["settings.json", "hooks", "agents", "skills", "plugins", "keybindings.json"];
|
|
37344
|
+
function getClaudeProfileDir(username) {
|
|
37345
|
+
return path22.join(os8.homedir(), `.claude-${username}`);
|
|
37346
|
+
}
|
|
37347
|
+
function ensureClaudeProfile(username, logger) {
|
|
37348
|
+
const profileDir = getClaudeProfileDir(username);
|
|
37349
|
+
const ownerDir = path22.join(os8.homedir(), ".claude");
|
|
37350
|
+
if (!existsSync10(ownerDir)) {
|
|
37351
|
+
throw new Error(`Owner claude config dir not found: ${ownerDir}`);
|
|
37352
|
+
}
|
|
37353
|
+
if (!existsSync10(profileDir)) {
|
|
37354
|
+
mkdirSync5(profileDir, { recursive: true });
|
|
37355
|
+
logger?.info({ profileDir, username }, "created claude profile directory");
|
|
37356
|
+
}
|
|
37357
|
+
for (const item of SHARED_ITEMS) {
|
|
37358
|
+
const target = path22.join(ownerDir, item);
|
|
37359
|
+
const link = path22.join(profileDir, item);
|
|
37360
|
+
if (!existsSync10(target)) continue;
|
|
37361
|
+
if (existsSync10(link)) continue;
|
|
37362
|
+
symlinkSync(target, link);
|
|
37363
|
+
logger?.info({ item, profileDir }, "symlinked shared config item");
|
|
37364
|
+
}
|
|
37365
|
+
return profileDir;
|
|
37366
|
+
}
|
|
37367
|
+
function hasClaudeAuth(username) {
|
|
37368
|
+
const profileDir = getClaudeProfileDir(username);
|
|
37369
|
+
return existsSync10(profileDir);
|
|
37370
|
+
}
|
|
37371
|
+
function removeClaudeProfile(username, logger) {
|
|
37372
|
+
const profileDir = getClaudeProfileDir(username);
|
|
37373
|
+
if (!existsSync10(profileDir)) return;
|
|
37374
|
+
rmSync2(profileDir, { recursive: true, force: true });
|
|
37375
|
+
logger?.info({ profileDir, username }, "removed claude profile directory");
|
|
37376
|
+
}
|
|
37377
|
+
|
|
37283
37378
|
// ../server/src/services/oauth-service.ts
|
|
37284
37379
|
import { createHash as createHash4, randomBytes as randomBytes2 } from "node:crypto";
|
|
37285
37380
|
import { mkdir as mkdir4, readFile as readFile3, rename, unlink, writeFile as writeFile4 } from "node:fs/promises";
|
|
@@ -37525,57 +37620,57 @@ async function fetchGitLabUsername(fetchImpl, accessToken) {
|
|
|
37525
37620
|
return null;
|
|
37526
37621
|
}
|
|
37527
37622
|
}
|
|
37528
|
-
async function readCredential(
|
|
37623
|
+
async function readCredential(path38, log) {
|
|
37529
37624
|
try {
|
|
37530
|
-
const raw = await readFile3(
|
|
37625
|
+
const raw = await readFile3(path38, "utf8");
|
|
37531
37626
|
const parsed = JSON.parse(raw);
|
|
37532
37627
|
return parsed.gitlab ?? null;
|
|
37533
37628
|
} catch (error) {
|
|
37534
37629
|
if (isNotFound(error)) return null;
|
|
37535
|
-
log.warn({ err: error, path:
|
|
37630
|
+
log.warn({ err: error, path: path38 }, "oauth.credentials.read_failed");
|
|
37536
37631
|
return null;
|
|
37537
37632
|
}
|
|
37538
37633
|
}
|
|
37539
|
-
async function persistCredential(
|
|
37540
|
-
await mkdir4(dirname4(
|
|
37634
|
+
async function persistCredential(path38, credential, log) {
|
|
37635
|
+
await mkdir4(dirname4(path38), { recursive: true });
|
|
37541
37636
|
let current = {};
|
|
37542
37637
|
try {
|
|
37543
|
-
const raw = await readFile3(
|
|
37638
|
+
const raw = await readFile3(path38, "utf8");
|
|
37544
37639
|
current = JSON.parse(raw);
|
|
37545
37640
|
} catch (error) {
|
|
37546
37641
|
if (!isNotFound(error)) {
|
|
37547
|
-
log.warn({ err: error, path:
|
|
37642
|
+
log.warn({ err: error, path: path38 }, "oauth.credentials.read_failed_overwriting");
|
|
37548
37643
|
}
|
|
37549
37644
|
}
|
|
37550
37645
|
const next = { ...current, gitlab: credential };
|
|
37551
|
-
const tmpPath = `${
|
|
37646
|
+
const tmpPath = `${path38}.tmp-${process.pid}-${Date.now()}`;
|
|
37552
37647
|
await writeFile4(tmpPath, JSON.stringify(next, null, 2), { mode: 384 });
|
|
37553
|
-
await rename(tmpPath,
|
|
37648
|
+
await rename(tmpPath, path38);
|
|
37554
37649
|
}
|
|
37555
|
-
async function deleteCredential(
|
|
37650
|
+
async function deleteCredential(path38, log) {
|
|
37556
37651
|
let current = {};
|
|
37557
37652
|
try {
|
|
37558
|
-
const raw = await readFile3(
|
|
37653
|
+
const raw = await readFile3(path38, "utf8");
|
|
37559
37654
|
current = JSON.parse(raw);
|
|
37560
37655
|
} catch (error) {
|
|
37561
37656
|
if (isNotFound(error)) return;
|
|
37562
|
-
log.warn({ err: error, path:
|
|
37657
|
+
log.warn({ err: error, path: path38 }, "oauth.credentials.delete_read_failed");
|
|
37563
37658
|
return;
|
|
37564
37659
|
}
|
|
37565
37660
|
delete current.gitlab;
|
|
37566
37661
|
if (Object.keys(current).length === 0) {
|
|
37567
37662
|
try {
|
|
37568
|
-
await unlink(
|
|
37663
|
+
await unlink(path38);
|
|
37569
37664
|
} catch (error) {
|
|
37570
37665
|
if (!isNotFound(error)) {
|
|
37571
|
-
log.warn({ err: error, path:
|
|
37666
|
+
log.warn({ err: error, path: path38 }, "oauth.credentials.unlink_failed");
|
|
37572
37667
|
}
|
|
37573
37668
|
}
|
|
37574
37669
|
return;
|
|
37575
37670
|
}
|
|
37576
|
-
const tmpPath = `${
|
|
37671
|
+
const tmpPath = `${path38}.tmp-${process.pid}-${Date.now()}`;
|
|
37577
37672
|
await writeFile4(tmpPath, JSON.stringify(current, null, 2), { mode: 384 });
|
|
37578
|
-
await rename(tmpPath,
|
|
37673
|
+
await rename(tmpPath, path38);
|
|
37579
37674
|
}
|
|
37580
37675
|
function defaultGlabConfigPath() {
|
|
37581
37676
|
const home = homedir4();
|
|
@@ -37590,15 +37685,15 @@ function defaultGlabConfigPath() {
|
|
|
37590
37685
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
37591
37686
|
return join11(xdg && xdg.length > 0 ? xdg : join11(home, ".config"), "glab-cli", "config.yml");
|
|
37592
37687
|
}
|
|
37593
|
-
async function writeGlabConfig(
|
|
37594
|
-
await mkdir4(dirname4(
|
|
37688
|
+
async function writeGlabConfig(path38, credential, log) {
|
|
37689
|
+
await mkdir4(dirname4(path38), { recursive: true });
|
|
37595
37690
|
let doc;
|
|
37596
37691
|
try {
|
|
37597
|
-
const raw = await readFile3(
|
|
37692
|
+
const raw = await readFile3(path38, "utf8");
|
|
37598
37693
|
doc = YAML.parseDocument(raw);
|
|
37599
37694
|
if (doc.errors.length > 0) {
|
|
37600
37695
|
log.warn(
|
|
37601
|
-
{ errors: doc.errors.map((e) => e.message), path:
|
|
37696
|
+
{ errors: doc.errors.map((e) => e.message), path: path38 },
|
|
37602
37697
|
"oauth.glab.parse_errors_replacing"
|
|
37603
37698
|
);
|
|
37604
37699
|
doc = YAML.parseDocument("{}");
|
|
@@ -37607,7 +37702,7 @@ async function writeGlabConfig(path37, credential, log) {
|
|
|
37607
37702
|
if (isNotFound(error)) {
|
|
37608
37703
|
doc = YAML.parseDocument("{}");
|
|
37609
37704
|
} else {
|
|
37610
|
-
log.warn({ err: error, path:
|
|
37705
|
+
log.warn({ err: error, path: path38 }, "oauth.glab.read_failed_replacing");
|
|
37611
37706
|
doc = YAML.parseDocument("{}");
|
|
37612
37707
|
}
|
|
37613
37708
|
}
|
|
@@ -37620,18 +37715,18 @@ async function writeGlabConfig(path37, credential, log) {
|
|
|
37620
37715
|
if (credential.username) {
|
|
37621
37716
|
hostEntry.set("user", credential.username);
|
|
37622
37717
|
}
|
|
37623
|
-
const tmpPath = `${
|
|
37718
|
+
const tmpPath = `${path38}.tmp-${process.pid}-${Date.now()}`;
|
|
37624
37719
|
await writeFile4(tmpPath, doc.toString(), { mode: 384 });
|
|
37625
|
-
await rename(tmpPath,
|
|
37720
|
+
await rename(tmpPath, path38);
|
|
37626
37721
|
}
|
|
37627
|
-
async function removeGlabHost(
|
|
37722
|
+
async function removeGlabHost(path38, log) {
|
|
37628
37723
|
let doc;
|
|
37629
37724
|
try {
|
|
37630
|
-
const raw = await readFile3(
|
|
37725
|
+
const raw = await readFile3(path38, "utf8");
|
|
37631
37726
|
doc = YAML.parseDocument(raw);
|
|
37632
37727
|
} catch (error) {
|
|
37633
37728
|
if (isNotFound(error)) return;
|
|
37634
|
-
log.warn({ err: error, path:
|
|
37729
|
+
log.warn({ err: error, path: path38 }, "oauth.glab.remove_read_failed");
|
|
37635
37730
|
return;
|
|
37636
37731
|
}
|
|
37637
37732
|
const hosts = doc.get("hosts");
|
|
@@ -37640,9 +37735,9 @@ async function removeGlabHost(path37, log) {
|
|
|
37640
37735
|
if (hosts.items.length === 0) {
|
|
37641
37736
|
doc.delete("hosts");
|
|
37642
37737
|
}
|
|
37643
|
-
const tmpPath = `${
|
|
37738
|
+
const tmpPath = `${path38}.tmp-${process.pid}-${Date.now()}`;
|
|
37644
37739
|
await writeFile4(tmpPath, doc.toString(), { mode: 384 });
|
|
37645
|
-
await rename(tmpPath,
|
|
37740
|
+
await rename(tmpPath, path38);
|
|
37646
37741
|
}
|
|
37647
37742
|
function ensureMap(doc, key) {
|
|
37648
37743
|
const existing = doc.get(key);
|
|
@@ -38768,6 +38863,8 @@ var Session = class _Session {
|
|
|
38768
38863
|
this.nextTerminalSlot = 0;
|
|
38769
38864
|
this.inflightRequests = 0;
|
|
38770
38865
|
this.peakInflightRequests = 0;
|
|
38866
|
+
/** In-progress `claude login` processes, keyed by requestId. */
|
|
38867
|
+
this.pendingClaudeLogins = /* @__PURE__ */ new Map();
|
|
38771
38868
|
this.checkoutDiffSubscriptions = /* @__PURE__ */ new Map();
|
|
38772
38869
|
this.workspaceGitWatchTargets = /* @__PURE__ */ new Map();
|
|
38773
38870
|
this.workspaceSetupSnapshots = /* @__PURE__ */ new Map();
|
|
@@ -38829,6 +38926,8 @@ var Session = class _Session {
|
|
|
38829
38926
|
this.clientId = clientId;
|
|
38830
38927
|
this.appVersion = appVersion ?? null;
|
|
38831
38928
|
this.sessionId = uuidv47();
|
|
38929
|
+
this.userId = options.userId ?? null;
|
|
38930
|
+
this.username = options.username ?? null;
|
|
38832
38931
|
this.onMessage = onMessage;
|
|
38833
38932
|
this.onBinaryMessage = onBinaryMessage ?? null;
|
|
38834
38933
|
this.onLifecycleIntent = onLifecycleIntent ?? null;
|
|
@@ -39448,6 +39547,18 @@ var Session = class _Session {
|
|
|
39448
39547
|
case "link_account_request":
|
|
39449
39548
|
await this.handleLinkAccountRequest(msg);
|
|
39450
39549
|
break;
|
|
39550
|
+
case "claude_profile_login_request":
|
|
39551
|
+
await this.handleClaudeProfileLoginRequest(msg);
|
|
39552
|
+
break;
|
|
39553
|
+
case "claude_profile_login_callback":
|
|
39554
|
+
await this.handleClaudeProfileLoginCallback(msg);
|
|
39555
|
+
break;
|
|
39556
|
+
case "claude_profile_status_request":
|
|
39557
|
+
await this.handleClaudeProfileStatusRequest(msg);
|
|
39558
|
+
break;
|
|
39559
|
+
case "claude_profile_remove_request":
|
|
39560
|
+
await this.handleClaudeProfileRemoveRequest(msg);
|
|
39561
|
+
break;
|
|
39451
39562
|
case "fetch_agents_request":
|
|
39452
39563
|
await this.handleFetchAgents(msg);
|
|
39453
39564
|
break;
|
|
@@ -40154,6 +40265,138 @@ var Session = class _Session {
|
|
|
40154
40265
|
respond({ ok: false, error: message });
|
|
40155
40266
|
}
|
|
40156
40267
|
}
|
|
40268
|
+
// ---------------------------------------------------------------------------
|
|
40269
|
+
// Claude profile login — per-user subscription on shared hosts
|
|
40270
|
+
// ---------------------------------------------------------------------------
|
|
40271
|
+
async handleClaudeProfileLoginRequest(msg) {
|
|
40272
|
+
const { requestId, username } = msg;
|
|
40273
|
+
const log = this.sessionLogger.child({ handler: "claude_profile_login" });
|
|
40274
|
+
try {
|
|
40275
|
+
const profileDir = ensureClaudeProfile(username, log);
|
|
40276
|
+
const child = spawnProcess("claude", ["auth", "login"], {
|
|
40277
|
+
env: {
|
|
40278
|
+
...process.env,
|
|
40279
|
+
CLAUDE_CONFIG_DIR: profileDir
|
|
40280
|
+
},
|
|
40281
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
40282
|
+
});
|
|
40283
|
+
this.pendingClaudeLogins.set(requestId, { process: child, username });
|
|
40284
|
+
let stdoutBuffer = "";
|
|
40285
|
+
child.stdout?.on("data", (chunk) => {
|
|
40286
|
+
stdoutBuffer += chunk.toString();
|
|
40287
|
+
const urlMatch = stdoutBuffer.match(/(https?:\/\/[^\s]+)/);
|
|
40288
|
+
if (urlMatch) {
|
|
40289
|
+
this.emit({
|
|
40290
|
+
type: "claude_profile_login_url",
|
|
40291
|
+
requestId,
|
|
40292
|
+
url: urlMatch[1]
|
|
40293
|
+
});
|
|
40294
|
+
}
|
|
40295
|
+
});
|
|
40296
|
+
child.stderr?.on("data", (chunk) => {
|
|
40297
|
+
log.debug({ stderr: chunk.toString() }, "claude login stderr");
|
|
40298
|
+
});
|
|
40299
|
+
child.on("close", (code) => {
|
|
40300
|
+
this.pendingClaudeLogins.delete(requestId);
|
|
40301
|
+
if (code === 0) {
|
|
40302
|
+
log.info({ username }, "claude profile login succeeded");
|
|
40303
|
+
this.emit({
|
|
40304
|
+
type: "claude_profile_login_result",
|
|
40305
|
+
requestId,
|
|
40306
|
+
ok: true
|
|
40307
|
+
});
|
|
40308
|
+
} else {
|
|
40309
|
+
log.warn({ username, code }, "claude profile login failed");
|
|
40310
|
+
this.emit({
|
|
40311
|
+
type: "claude_profile_login_result",
|
|
40312
|
+
requestId,
|
|
40313
|
+
ok: false,
|
|
40314
|
+
error: `claude login exited with code ${code}`
|
|
40315
|
+
});
|
|
40316
|
+
}
|
|
40317
|
+
});
|
|
40318
|
+
child.on("error", (err) => {
|
|
40319
|
+
this.pendingClaudeLogins.delete(requestId);
|
|
40320
|
+
log.error({ err }, "claude login process error");
|
|
40321
|
+
this.emit({
|
|
40322
|
+
type: "claude_profile_login_result",
|
|
40323
|
+
requestId,
|
|
40324
|
+
ok: false,
|
|
40325
|
+
error: err.message
|
|
40326
|
+
});
|
|
40327
|
+
});
|
|
40328
|
+
} catch (err) {
|
|
40329
|
+
const message = err instanceof Error ? err.message : "unknown_error";
|
|
40330
|
+
log.error({ err }, "claude profile login request failed");
|
|
40331
|
+
this.emit({
|
|
40332
|
+
type: "claude_profile_login_result",
|
|
40333
|
+
requestId,
|
|
40334
|
+
ok: false,
|
|
40335
|
+
error: message
|
|
40336
|
+
});
|
|
40337
|
+
}
|
|
40338
|
+
}
|
|
40339
|
+
async handleClaudeProfileLoginCallback(msg) {
|
|
40340
|
+
const { requestId, callbackToken } = msg;
|
|
40341
|
+
const pending = this.pendingClaudeLogins.get(requestId);
|
|
40342
|
+
if (!pending) {
|
|
40343
|
+
this.sessionLogger.warn({ requestId }, "claude_profile_login_callback: no pending login");
|
|
40344
|
+
this.emit({
|
|
40345
|
+
type: "claude_profile_login_result",
|
|
40346
|
+
requestId,
|
|
40347
|
+
ok: false,
|
|
40348
|
+
error: "no_pending_login"
|
|
40349
|
+
});
|
|
40350
|
+
return;
|
|
40351
|
+
}
|
|
40352
|
+
try {
|
|
40353
|
+
pending.process.stdin?.write(callbackToken + "\n");
|
|
40354
|
+
} catch (err) {
|
|
40355
|
+
this.sessionLogger.error({ err }, "failed to write callback token to claude login stdin");
|
|
40356
|
+
}
|
|
40357
|
+
}
|
|
40358
|
+
async handleClaudeProfileStatusRequest(msg) {
|
|
40359
|
+
const { requestId, username } = msg;
|
|
40360
|
+
const profileExists = hasClaudeAuth(username);
|
|
40361
|
+
let isAuthenticated = false;
|
|
40362
|
+
if (profileExists) {
|
|
40363
|
+
try {
|
|
40364
|
+
const profileDir = ensureClaudeProfile(username);
|
|
40365
|
+
const result = await execCommand("claude", ["auth", "status"], {
|
|
40366
|
+
env: { ...process.env, CLAUDE_CONFIG_DIR: profileDir },
|
|
40367
|
+
timeout: 5e3
|
|
40368
|
+
});
|
|
40369
|
+
isAuthenticated = !result.stdout.toLowerCase().includes("not logged in");
|
|
40370
|
+
} catch {
|
|
40371
|
+
}
|
|
40372
|
+
}
|
|
40373
|
+
this.emit({
|
|
40374
|
+
type: "claude_profile_status_response",
|
|
40375
|
+
requestId,
|
|
40376
|
+
hasProfile: profileExists,
|
|
40377
|
+
isAuthenticated
|
|
40378
|
+
});
|
|
40379
|
+
}
|
|
40380
|
+
async handleClaudeProfileRemoveRequest(msg) {
|
|
40381
|
+
const { requestId, username } = msg;
|
|
40382
|
+
try {
|
|
40383
|
+
removeClaudeProfile(username, this.sessionLogger);
|
|
40384
|
+
this.emit({
|
|
40385
|
+
type: "claude_profile_remove_response",
|
|
40386
|
+
requestId,
|
|
40387
|
+
ok: true
|
|
40388
|
+
});
|
|
40389
|
+
} catch (err) {
|
|
40390
|
+
const message = err instanceof Error ? err.message : "unknown_error";
|
|
40391
|
+
this.sessionLogger.error({ err, username }, "claude profile remove failed");
|
|
40392
|
+
this.emit({
|
|
40393
|
+
type: "claude_profile_remove_response",
|
|
40394
|
+
requestId,
|
|
40395
|
+
ok: false,
|
|
40396
|
+
error: message
|
|
40397
|
+
});
|
|
40398
|
+
}
|
|
40399
|
+
}
|
|
40157
40400
|
async handleRestartServerRequest(requestId, reason) {
|
|
40158
40401
|
const payload = {
|
|
40159
40402
|
status: "restart_requested",
|
|
@@ -40987,7 +41230,9 @@ var Session = class _Session {
|
|
|
40987
41230
|
{
|
|
40988
41231
|
labels,
|
|
40989
41232
|
workspaceId: resolvedWorkspace.workspaceId,
|
|
40990
|
-
initialPrompt: trimmedPrompt
|
|
41233
|
+
initialPrompt: trimmedPrompt,
|
|
41234
|
+
userId: this.userId ?? void 0,
|
|
41235
|
+
username: this.username ?? void 0
|
|
40991
41236
|
}
|
|
40992
41237
|
);
|
|
40993
41238
|
await this.forwardAgentUpdate(snapshot);
|
|
@@ -42455,7 +42700,7 @@ var Session = class _Session {
|
|
|
42455
42700
|
homeDir: process.env.HOME ?? homedir5(),
|
|
42456
42701
|
query: query2,
|
|
42457
42702
|
limit
|
|
42458
|
-
})).map((
|
|
42703
|
+
})).map((path38) => ({ path: path38, kind: "directory" }));
|
|
42459
42704
|
const directories = entries.filter((entry) => entry.kind === "directory").map((entry) => entry.path);
|
|
42460
42705
|
this.emit({
|
|
42461
42706
|
type: "directory_suggestions_response",
|
|
@@ -47590,7 +47835,7 @@ function toErrorMessage(error) {
|
|
|
47590
47835
|
}
|
|
47591
47836
|
|
|
47592
47837
|
// ../server/src/server/push/token-store.ts
|
|
47593
|
-
import { existsSync as
|
|
47838
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
47594
47839
|
import { dirname as dirname5 } from "node:path";
|
|
47595
47840
|
var PushTokenStore = class {
|
|
47596
47841
|
constructor(logger, filePath) {
|
|
@@ -47684,7 +47929,7 @@ var PushTokenStore = class {
|
|
|
47684
47929
|
}
|
|
47685
47930
|
loadFromDisk() {
|
|
47686
47931
|
try {
|
|
47687
|
-
if (!
|
|
47932
|
+
if (!existsSync12(this.filePath)) {
|
|
47688
47933
|
return;
|
|
47689
47934
|
}
|
|
47690
47935
|
const raw = readFileSync7(this.filePath, "utf-8");
|
|
@@ -47720,7 +47965,7 @@ var PushTokenStore = class {
|
|
|
47720
47965
|
}
|
|
47721
47966
|
persist() {
|
|
47722
47967
|
try {
|
|
47723
|
-
|
|
47968
|
+
mkdirSync6(dirname5(this.filePath), { recursive: true });
|
|
47724
47969
|
const tmpPath = `${this.filePath}.tmp`;
|
|
47725
47970
|
const payload = { entries: Array.from(this.entries.values()) };
|
|
47726
47971
|
writeFileSync5(tmpPath, JSON.stringify(payload, null, 2) + "\n");
|
|
@@ -47800,7 +48045,7 @@ var PushService = class {
|
|
|
47800
48045
|
};
|
|
47801
48046
|
|
|
47802
48047
|
// ../server/src/server/push/web-push-store.ts
|
|
47803
|
-
import { existsSync as
|
|
48048
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync6, chmodSync as chmodSync2 } from "node:fs";
|
|
47804
48049
|
import { dirname as dirname6 } from "node:path";
|
|
47805
48050
|
import webpush from "web-push";
|
|
47806
48051
|
var WebPushStore = class {
|
|
@@ -47906,7 +48151,7 @@ var WebPushStore = class {
|
|
|
47906
48151
|
}
|
|
47907
48152
|
loadOrCreateVapidKeys() {
|
|
47908
48153
|
try {
|
|
47909
|
-
if (
|
|
48154
|
+
if (existsSync13(this.vapidPath)) {
|
|
47910
48155
|
const raw = readFileSync8(this.vapidPath, "utf-8");
|
|
47911
48156
|
const parsed = JSON.parse(raw);
|
|
47912
48157
|
if (parsed.publicKey && parsed.privateKey) {
|
|
@@ -47918,7 +48163,7 @@ var WebPushStore = class {
|
|
|
47918
48163
|
}
|
|
47919
48164
|
const generated = webpush.generateVAPIDKeys();
|
|
47920
48165
|
try {
|
|
47921
|
-
|
|
48166
|
+
mkdirSync7(dirname6(this.vapidPath), { recursive: true });
|
|
47922
48167
|
writeFileSync6(this.vapidPath, JSON.stringify(generated, null, 2) + "\n");
|
|
47923
48168
|
if (process.platform !== "win32") {
|
|
47924
48169
|
try {
|
|
@@ -47934,7 +48179,7 @@ var WebPushStore = class {
|
|
|
47934
48179
|
}
|
|
47935
48180
|
loadSubscriptions() {
|
|
47936
48181
|
try {
|
|
47937
|
-
if (!
|
|
48182
|
+
if (!existsSync13(this.subsPath)) return;
|
|
47938
48183
|
const raw = readFileSync8(this.subsPath, "utf-8");
|
|
47939
48184
|
const parsed = JSON.parse(raw);
|
|
47940
48185
|
if (parsed.vapidKey && parsed.vapidKey !== this.vapid.publicKey) {
|
|
@@ -47975,7 +48220,7 @@ var WebPushStore = class {
|
|
|
47975
48220
|
}
|
|
47976
48221
|
persist() {
|
|
47977
48222
|
try {
|
|
47978
|
-
|
|
48223
|
+
mkdirSync7(dirname6(this.subsPath), { recursive: true });
|
|
47979
48224
|
const tmpPath = `${this.subsPath}.tmp`;
|
|
47980
48225
|
const payload = {
|
|
47981
48226
|
vapidKey: this.vapid.publicKey,
|
|
@@ -48705,6 +48950,8 @@ var VoiceAssistantWebSocketServer = class {
|
|
|
48705
48950
|
const session = new Session({
|
|
48706
48951
|
clientId,
|
|
48707
48952
|
appVersion,
|
|
48953
|
+
userId: params.userId,
|
|
48954
|
+
username: params.username,
|
|
48708
48955
|
onMessage: (msg) => {
|
|
48709
48956
|
if (!connection) {
|
|
48710
48957
|
return;
|
|
@@ -48782,7 +49029,9 @@ var VoiceAssistantWebSocketServer = class {
|
|
|
48782
49029
|
appVersion,
|
|
48783
49030
|
connectionLogger,
|
|
48784
49031
|
sockets: /* @__PURE__ */ new Set([ws]),
|
|
48785
|
-
externalDisconnectCleanupTimeout: null
|
|
49032
|
+
externalDisconnectCleanupTimeout: null,
|
|
49033
|
+
userId: params.userId ?? null,
|
|
49034
|
+
username: params.username ?? null
|
|
48786
49035
|
};
|
|
48787
49036
|
return connection;
|
|
48788
49037
|
}
|
|
@@ -48857,7 +49106,9 @@ var VoiceAssistantWebSocketServer = class {
|
|
|
48857
49106
|
ws,
|
|
48858
49107
|
clientId,
|
|
48859
49108
|
appVersion: message.appVersion ?? null,
|
|
48860
|
-
connectionLogger
|
|
49109
|
+
connectionLogger,
|
|
49110
|
+
userId: message.userId,
|
|
49111
|
+
username: message.username
|
|
48861
49112
|
});
|
|
48862
49113
|
this.sessions.set(ws, connection);
|
|
48863
49114
|
this.externalSessionsByKey.set(clientId, connection);
|
|
@@ -49560,7 +49811,7 @@ import { join as join17 } from "node:path";
|
|
|
49560
49811
|
// ../server/src/server/speech/providers/local/sherpa/model-downloader.ts
|
|
49561
49812
|
import { createWriteStream } from "node:fs";
|
|
49562
49813
|
import { mkdir as mkdir6, rename as rename2, rm as rm2, stat as stat5 } from "node:fs/promises";
|
|
49563
|
-
import
|
|
49814
|
+
import path23 from "node:path";
|
|
49564
49815
|
import { Readable as Readable2 } from "node:stream";
|
|
49565
49816
|
import { pipeline } from "node:stream/promises";
|
|
49566
49817
|
import { spawn as spawn7 } from "node:child_process";
|
|
@@ -49696,11 +49947,11 @@ function getSherpaOnnxModelSpec(id) {
|
|
|
49696
49947
|
// ../server/src/server/speech/providers/local/sherpa/model-downloader.ts
|
|
49697
49948
|
function getSherpaOnnxModelDir(modelsDir, modelId) {
|
|
49698
49949
|
const spec = getSherpaOnnxModelSpec(modelId);
|
|
49699
|
-
return
|
|
49950
|
+
return path23.join(modelsDir, spec.extractedDir);
|
|
49700
49951
|
}
|
|
49701
49952
|
async function hasRequiredFiles(modelDir, requiredFiles) {
|
|
49702
49953
|
for (const rel of requiredFiles) {
|
|
49703
|
-
const abs =
|
|
49954
|
+
const abs = path23.join(modelDir, rel);
|
|
49704
49955
|
try {
|
|
49705
49956
|
const s = await stat5(abs);
|
|
49706
49957
|
if (s.isDirectory()) {
|
|
@@ -49726,7 +49977,7 @@ async function downloadToFile(options) {
|
|
|
49726
49977
|
throw new Error(`Failed to download ${url}: missing response body`);
|
|
49727
49978
|
}
|
|
49728
49979
|
const tmpPath = `${outputPath}.tmp-${Date.now()}`;
|
|
49729
|
-
await mkdir6(
|
|
49980
|
+
await mkdir6(path23.dirname(outputPath), { recursive: true });
|
|
49730
49981
|
const nodeStream = Readable2.fromWeb(res.body);
|
|
49731
49982
|
try {
|
|
49732
49983
|
await pipeline(nodeStream, createWriteStream(tmpPath));
|
|
@@ -49763,16 +50014,16 @@ async function ensureSherpaOnnxModel(options) {
|
|
|
49763
50014
|
modelId: options.modelId
|
|
49764
50015
|
});
|
|
49765
50016
|
const spec = getSherpaOnnxModelSpec(options.modelId);
|
|
49766
|
-
const modelDir =
|
|
50017
|
+
const modelDir = path23.join(options.modelsDir, spec.extractedDir);
|
|
49767
50018
|
if (await hasRequiredFiles(modelDir, spec.requiredFiles)) {
|
|
49768
50019
|
return modelDir;
|
|
49769
50020
|
}
|
|
49770
50021
|
logger.info({ modelsDir: options.modelsDir }, "Starting model download");
|
|
49771
50022
|
try {
|
|
49772
50023
|
if (spec.archiveUrl) {
|
|
49773
|
-
const downloadsDir =
|
|
49774
|
-
const archiveFilename =
|
|
49775
|
-
const archivePath =
|
|
50024
|
+
const downloadsDir = path23.join(options.modelsDir, ".downloads");
|
|
50025
|
+
const archiveFilename = path23.basename(new URL(spec.archiveUrl).pathname);
|
|
50026
|
+
const archivePath = path23.join(downloadsDir, archiveFilename);
|
|
49776
50027
|
if (!await isNonEmptyFile(archivePath)) {
|
|
49777
50028
|
await downloadToFile({
|
|
49778
50029
|
url: spec.archiveUrl,
|
|
@@ -49817,7 +50068,7 @@ async function ensureSherpaOnnxModel(options) {
|
|
|
49817
50068
|
if (spec.downloadFiles && spec.downloadFiles.length > 0) {
|
|
49818
50069
|
await mkdir6(modelDir, { recursive: true });
|
|
49819
50070
|
for (const file of spec.downloadFiles) {
|
|
49820
|
-
const dst =
|
|
50071
|
+
const dst = path23.join(modelDir, file.relPath);
|
|
49821
50072
|
if (await isNonEmptyFile(dst)) {
|
|
49822
50073
|
continue;
|
|
49823
50074
|
}
|
|
@@ -49876,17 +50127,17 @@ async function ensureLocalSpeechModels(options) {
|
|
|
49876
50127
|
}
|
|
49877
50128
|
|
|
49878
50129
|
// ../server/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.ts
|
|
49879
|
-
import { existsSync as
|
|
50130
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
49880
50131
|
|
|
49881
50132
|
// ../server/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.ts
|
|
49882
50133
|
import { createRequire as createRequire4 } from "node:module";
|
|
49883
|
-
import
|
|
49884
|
-
import { existsSync as
|
|
50134
|
+
import path25 from "node:path";
|
|
50135
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
49885
50136
|
import { spawnSync } from "node:child_process";
|
|
49886
50137
|
|
|
49887
50138
|
// ../server/src/server/speech/providers/local/sherpa/sherpa-runtime-env.ts
|
|
49888
50139
|
import { createRequire as createRequire3 } from "node:module";
|
|
49889
|
-
import
|
|
50140
|
+
import path24 from "node:path";
|
|
49890
50141
|
function sherpaPlatformArch(platform = process.platform, arch = process.arch) {
|
|
49891
50142
|
const normalizedPlatform = platform === "win32" ? "win" : platform;
|
|
49892
50143
|
return `${normalizedPlatform}-${arch}`;
|
|
@@ -49907,11 +50158,11 @@ function sherpaLoaderEnvKey(platform = process.platform) {
|
|
|
49907
50158
|
return null;
|
|
49908
50159
|
}
|
|
49909
50160
|
function prependEnvPath(existing, value) {
|
|
49910
|
-
const parts = (existing ?? "").split(
|
|
50161
|
+
const parts = (existing ?? "").split(path24.delimiter).filter(Boolean);
|
|
49911
50162
|
if (parts.includes(value)) {
|
|
49912
|
-
return parts.join(
|
|
50163
|
+
return parts.join(path24.delimiter);
|
|
49913
50164
|
}
|
|
49914
|
-
return [value, ...parts].join(
|
|
50165
|
+
return [value, ...parts].join(path24.delimiter);
|
|
49915
50166
|
}
|
|
49916
50167
|
function resolveSherpaLoaderEnv(platform = process.platform, arch = process.arch) {
|
|
49917
50168
|
const key = sherpaLoaderEnvKey(platform);
|
|
@@ -49924,7 +50175,7 @@ function resolveSherpaLoaderEnv(platform = process.platform, arch = process.arch
|
|
|
49924
50175
|
const pkgJson = require4.resolve(`${packageName}/package.json`);
|
|
49925
50176
|
return {
|
|
49926
50177
|
key,
|
|
49927
|
-
libDir:
|
|
50178
|
+
libDir: path24.dirname(pkgJson),
|
|
49928
50179
|
packageName
|
|
49929
50180
|
};
|
|
49930
50181
|
} catch {
|
|
@@ -50033,8 +50284,8 @@ function loadSherpaOnnxNode() {
|
|
|
50033
50284
|
const platformPkgDir = resolvedEnv?.libDir ?? null;
|
|
50034
50285
|
if (platformPkgDir) {
|
|
50035
50286
|
applySherpaLoaderEnv(process.env);
|
|
50036
|
-
const addonPath =
|
|
50037
|
-
if (
|
|
50287
|
+
const addonPath = path25.join(platformPkgDir, "sherpa-onnx.node");
|
|
50288
|
+
if (existsSync14(addonPath)) {
|
|
50038
50289
|
const byPath = loadWithRequire(require4, addonPath, attempts);
|
|
50039
50290
|
if (byPath) {
|
|
50040
50291
|
cached = byPath;
|
|
@@ -50053,7 +50304,7 @@ function loadSherpaOnnxNode() {
|
|
|
50053
50304
|
|
|
50054
50305
|
// ../server/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.ts
|
|
50055
50306
|
function assertFileExists(filePath, label) {
|
|
50056
|
-
if (!
|
|
50307
|
+
if (!existsSync15(filePath)) {
|
|
50057
50308
|
throw new Error(`Missing ${label}: ${filePath}`);
|
|
50058
50309
|
}
|
|
50059
50310
|
}
|
|
@@ -50120,7 +50371,7 @@ var SherpaOfflineRecognizerEngine = class {
|
|
|
50120
50371
|
};
|
|
50121
50372
|
|
|
50122
50373
|
// ../server/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.ts
|
|
50123
|
-
import { existsSync as
|
|
50374
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
50124
50375
|
|
|
50125
50376
|
// ../server/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.ts
|
|
50126
50377
|
import { createRequire as createRequire5 } from "node:module";
|
|
@@ -50136,7 +50387,7 @@ function loadSherpaOnnx() {
|
|
|
50136
50387
|
|
|
50137
50388
|
// ../server/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.ts
|
|
50138
50389
|
function assertFileExists2(filePath, label) {
|
|
50139
|
-
if (!
|
|
50390
|
+
if (!existsSync16(filePath)) {
|
|
50140
50391
|
throw new Error(`Missing ${label}: ${filePath}`);
|
|
50141
50392
|
}
|
|
50142
50393
|
}
|
|
@@ -50712,9 +50963,9 @@ var SherpaOnnxSTT = class {
|
|
|
50712
50963
|
|
|
50713
50964
|
// ../server/src/server/speech/providers/local/sherpa/sherpa-tts.ts
|
|
50714
50965
|
import { Readable as Readable3 } from "node:stream";
|
|
50715
|
-
import { existsSync as
|
|
50966
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
50716
50967
|
function assertFileExists3(filePath, label) {
|
|
50717
|
-
if (!
|
|
50968
|
+
if (!existsSync17(filePath)) {
|
|
50718
50969
|
throw new Error(`Missing ${label}: ${filePath}`);
|
|
50719
50970
|
}
|
|
50720
50971
|
}
|
|
@@ -50805,7 +51056,7 @@ var SherpaOnnxTTS = class {
|
|
|
50805
51056
|
|
|
50806
51057
|
// ../server/src/server/speech/providers/local/sherpa/silero-vad-provider.ts
|
|
50807
51058
|
import { copyFile, mkdir as mkdir7, stat as stat6 } from "node:fs/promises";
|
|
50808
|
-
import
|
|
51059
|
+
import path26 from "node:path";
|
|
50809
51060
|
|
|
50810
51061
|
// ../server/src/server/speech/providers/local/sherpa/silero-vad-session.ts
|
|
50811
51062
|
import { EventEmitter as EventEmitter6 } from "node:events";
|
|
@@ -50997,8 +51248,8 @@ var SherpaSileroVadSession = class extends EventEmitter6 {
|
|
|
50997
51248
|
var SILERO_VAD_DIR = "silero-vad";
|
|
50998
51249
|
var SILERO_VAD_FILE = "silero_vad.onnx";
|
|
50999
51250
|
async function ensureSileroVadModel(modelsDir, logger) {
|
|
51000
|
-
const destDir =
|
|
51001
|
-
const destPath =
|
|
51251
|
+
const destDir = path26.join(modelsDir, SILERO_VAD_DIR);
|
|
51252
|
+
const destPath = path26.join(destDir, SILERO_VAD_FILE);
|
|
51002
51253
|
try {
|
|
51003
51254
|
const s = await stat6(destPath);
|
|
51004
51255
|
if (s.isFile() && s.size > 0) return destPath;
|
|
@@ -52422,7 +52673,7 @@ import { z as z40 } from "zod";
|
|
|
52422
52673
|
import { getSessionMessages } from "@anthropic-ai/claude-agent-sdk";
|
|
52423
52674
|
|
|
52424
52675
|
// ../server/src/server/agent/session-fork.ts
|
|
52425
|
-
import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, readdirSync as readdirSync2, existsSync as
|
|
52676
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, readdirSync as readdirSync2, existsSync as existsSync18 } from "node:fs";
|
|
52426
52677
|
import { dirname as dirname7, join as join18 } from "node:path";
|
|
52427
52678
|
import { homedir as homedir6 } from "node:os";
|
|
52428
52679
|
var ForkPointInvalidError = class extends Error {
|
|
@@ -52457,11 +52708,11 @@ function extractUserMessageText2(message) {
|
|
|
52457
52708
|
function findClaudeSessionFile(params) {
|
|
52458
52709
|
const home = params.claudeHomeDir ?? join18(homedir6(), ".claude");
|
|
52459
52710
|
const projectsDir = join18(home, "projects");
|
|
52460
|
-
if (!
|
|
52711
|
+
if (!existsSync18(projectsDir)) return null;
|
|
52461
52712
|
for (const entry of readdirSync2(projectsDir, { withFileTypes: true })) {
|
|
52462
52713
|
if (!entry.isDirectory()) continue;
|
|
52463
52714
|
const candidate = join18(projectsDir, entry.name, `${params.sessionId}.jsonl`);
|
|
52464
|
-
if (
|
|
52715
|
+
if (existsSync18(candidate)) return candidate;
|
|
52465
52716
|
}
|
|
52466
52717
|
return null;
|
|
52467
52718
|
}
|
|
@@ -52514,7 +52765,7 @@ function forkSession(input) {
|
|
|
52514
52765
|
}
|
|
52515
52766
|
const copied = lines.slice(0, forkLineIndex).filter((l) => l.length > 0);
|
|
52516
52767
|
const targetDir = dirname7(input.targetSessionPath);
|
|
52517
|
-
if (!
|
|
52768
|
+
if (!existsSync18(targetDir)) {
|
|
52518
52769
|
throw new Error(`Target directory does not exist: ${targetDir}`);
|
|
52519
52770
|
}
|
|
52520
52771
|
const payload = copied.length > 0 ? copied.join("\n") + "\n" : "";
|
|
@@ -53124,6 +53375,7 @@ var AgentManager = class {
|
|
|
53124
53375
|
this.mcpBaseUrl = options?.mcpBaseUrl ?? null;
|
|
53125
53376
|
this.appostleHome = options?.appostleHome ?? null;
|
|
53126
53377
|
this.chromeEnabled = options?.chromeEnabled ?? true;
|
|
53378
|
+
this.ownerUserId = options?.ownerUserId ?? null;
|
|
53127
53379
|
this.logger = options.logger.child({ module: "agent", component: "agent-manager" });
|
|
53128
53380
|
this.agentStreamCoalescer = new AgentStreamCoalescer({
|
|
53129
53381
|
windowMs: options.agentStreamCoalesceWindowMs ?? AGENT_STREAM_COALESCE_DEFAULT_WINDOW_MS,
|
|
@@ -53381,7 +53633,10 @@ var AgentManager = class {
|
|
|
53381
53633
|
mcpServers
|
|
53382
53634
|
};
|
|
53383
53635
|
const normalizedConfig = await this.normalizeConfig(injectedConfig);
|
|
53384
|
-
const launchContext = this.buildLaunchContext(resolvedAgentId
|
|
53636
|
+
const launchContext = this.buildLaunchContext(resolvedAgentId, {
|
|
53637
|
+
userId: options?.userId,
|
|
53638
|
+
username: options?.username
|
|
53639
|
+
});
|
|
53385
53640
|
const client = this.requireClient(normalizedConfig.provider);
|
|
53386
53641
|
const available = await client.isAvailable();
|
|
53387
53642
|
if (!available) {
|
|
@@ -55266,13 +55521,19 @@ var AgentManager = class {
|
|
|
55266
55521
|
}
|
|
55267
55522
|
return normalized;
|
|
55268
55523
|
}
|
|
55269
|
-
buildLaunchContext(agentId) {
|
|
55270
|
-
|
|
55271
|
-
|
|
55272
|
-
APPOSTLE_AGENT_ID: agentId
|
|
55273
|
-
},
|
|
55274
|
-
chromeEnabled: this.chromeEnabled
|
|
55524
|
+
buildLaunchContext(agentId, user) {
|
|
55525
|
+
const env = {
|
|
55526
|
+
APPOSTLE_AGENT_ID: agentId
|
|
55275
55527
|
};
|
|
55528
|
+
if (user?.username && user?.userId && this.ownerUserId && user.userId !== this.ownerUserId) {
|
|
55529
|
+
const profileDir = ensureClaudeProfile(user.username, this.logger);
|
|
55530
|
+
env.CLAUDE_CONFIG_DIR = profileDir;
|
|
55531
|
+
this.logger.info(
|
|
55532
|
+
{ username: user.username, userId: user.userId, profileDir },
|
|
55533
|
+
"using shared user claude profile"
|
|
55534
|
+
);
|
|
55535
|
+
}
|
|
55536
|
+
return { env, chromeEnabled: this.chromeEnabled };
|
|
55276
55537
|
}
|
|
55277
55538
|
requireClient(provider) {
|
|
55278
55539
|
const client = this.clients.get(provider);
|
|
@@ -55301,7 +55562,7 @@ var AgentManager = class {
|
|
|
55301
55562
|
// ../server/src/server/agent/agent-storage.ts
|
|
55302
55563
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
55303
55564
|
import { promises as fs15 } from "node:fs";
|
|
55304
|
-
import
|
|
55565
|
+
import path27 from "node:path";
|
|
55305
55566
|
import { z as z41 } from "zod";
|
|
55306
55567
|
var SERIALIZABLE_CONFIG_SCHEMA = z41.object({
|
|
55307
55568
|
title: z41.string().nullable().optional(),
|
|
@@ -55388,7 +55649,7 @@ var AgentStorage = class {
|
|
|
55388
55649
|
}
|
|
55389
55650
|
const nextPath = this.buildRecordPath(record);
|
|
55390
55651
|
const previousPath = this.pathById.get(agentId);
|
|
55391
|
-
await fs15.mkdir(
|
|
55652
|
+
await fs15.mkdir(path27.dirname(nextPath), { recursive: true });
|
|
55392
55653
|
await writeFileAtomically(nextPath, JSON.stringify(record, null, 2));
|
|
55393
55654
|
this.addIndexedPath(agentId, nextPath);
|
|
55394
55655
|
if (previousPath && previousPath !== nextPath) {
|
|
@@ -55504,7 +55765,7 @@ var AgentStorage = class {
|
|
|
55504
55765
|
}
|
|
55505
55766
|
for (const entry of entries) {
|
|
55506
55767
|
if (entry.isFile() && entry.name.endsWith(".json")) {
|
|
55507
|
-
const rootPath =
|
|
55768
|
+
const rootPath = path27.join(this.baseDir, entry.name);
|
|
55508
55769
|
const rootRecord = await this.readRecordFile(rootPath);
|
|
55509
55770
|
if (!rootRecord) {
|
|
55510
55771
|
continue;
|
|
@@ -55518,7 +55779,7 @@ var AgentStorage = class {
|
|
|
55518
55779
|
if (!entry.isDirectory()) {
|
|
55519
55780
|
continue;
|
|
55520
55781
|
}
|
|
55521
|
-
const projectDir =
|
|
55782
|
+
const projectDir = path27.join(this.baseDir, entry.name);
|
|
55522
55783
|
let files = [];
|
|
55523
55784
|
try {
|
|
55524
55785
|
files = await fs15.readdir(projectDir, { withFileTypes: true });
|
|
@@ -55529,7 +55790,7 @@ var AgentStorage = class {
|
|
|
55529
55790
|
if (!file.isFile() || !file.name.endsWith(".json")) {
|
|
55530
55791
|
continue;
|
|
55531
55792
|
}
|
|
55532
|
-
const filePath =
|
|
55793
|
+
const filePath = path27.join(projectDir, file.name);
|
|
55533
55794
|
const record = await this.readRecordFile(filePath);
|
|
55534
55795
|
if (!record) {
|
|
55535
55796
|
continue;
|
|
@@ -55554,7 +55815,7 @@ var AgentStorage = class {
|
|
|
55554
55815
|
}
|
|
55555
55816
|
buildRecordPath(record) {
|
|
55556
55817
|
const projectDir = projectDirNameFromCwd(record.cwd);
|
|
55557
|
-
return
|
|
55818
|
+
return path27.join(this.baseDir, projectDir, `${record.id}.json`);
|
|
55558
55819
|
}
|
|
55559
55820
|
addIndexedPath(agentId, filePath) {
|
|
55560
55821
|
const paths = this.pathsById.get(agentId) ?? /* @__PURE__ */ new Set();
|
|
@@ -55576,7 +55837,7 @@ var AgentStorage = class {
|
|
|
55576
55837
|
}
|
|
55577
55838
|
};
|
|
55578
55839
|
function projectDirNameFromCwd(cwd) {
|
|
55579
|
-
const { root } =
|
|
55840
|
+
const { root } = path27.win32.parse(cwd);
|
|
55580
55841
|
const withoutRoot = cwd.slice(root.length).replace(/[\\/]+$/, "");
|
|
55581
55842
|
const sanitizedRoot = root.replace(/[:\\/]+/g, "-").replace(/^-+|-+$/g, "");
|
|
55582
55843
|
const prefix = sanitizedRoot ? sanitizedRoot + "-" : "";
|
|
@@ -55586,8 +55847,8 @@ function projectDirNameFromCwd(cwd) {
|
|
|
55586
55847
|
return prefix + withoutRoot.replace(/[\\/]+/g, "-");
|
|
55587
55848
|
}
|
|
55588
55849
|
async function writeFileAtomically(targetPath, payload) {
|
|
55589
|
-
const directory =
|
|
55590
|
-
const tempPath =
|
|
55850
|
+
const directory = path27.dirname(targetPath);
|
|
55851
|
+
const tempPath = path27.join(directory, `.agent.tmp-${process.pid}-${Date.now()}-${randomUUID12()}`);
|
|
55591
55852
|
await fs15.writeFile(tempPath, payload, "utf8");
|
|
55592
55853
|
await fs15.rename(tempPath, targetPath);
|
|
55593
55854
|
}
|
|
@@ -57095,7 +57356,7 @@ async function createMcpWorktree(options) {
|
|
|
57095
57356
|
}
|
|
57096
57357
|
|
|
57097
57358
|
// ../server/src/server/workspace-registry-bootstrap.ts
|
|
57098
|
-
import
|
|
57359
|
+
import path28 from "node:path";
|
|
57099
57360
|
function minIsoDate(left, right) {
|
|
57100
57361
|
if (!left) {
|
|
57101
57362
|
return right;
|
|
@@ -57192,8 +57453,8 @@ async function bootstrapWorkspaceRegistries(options) {
|
|
|
57192
57453
|
}
|
|
57193
57454
|
options.logger.info(
|
|
57194
57455
|
{
|
|
57195
|
-
projectsFile:
|
|
57196
|
-
workspacesFile:
|
|
57456
|
+
projectsFile: path28.join(options.appostleHome, "projects", "projects.json"),
|
|
57457
|
+
workspacesFile: path28.join(options.appostleHome, "projects", "workspaces.json"),
|
|
57197
57458
|
materializedProjects: projectRanges.size,
|
|
57198
57459
|
materializedWorkspaces: recordsByWorkspaceId.size
|
|
57199
57460
|
},
|
|
@@ -57390,7 +57651,7 @@ var CheckoutDiffManager = class {
|
|
|
57390
57651
|
// ../server/src/server/loop-service.ts
|
|
57391
57652
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
57392
57653
|
import { promises as fs16 } from "node:fs";
|
|
57393
|
-
import
|
|
57654
|
+
import path29 from "node:path";
|
|
57394
57655
|
import { z as z43 } from "zod";
|
|
57395
57656
|
var LOOP_ID_LENGTH = 8;
|
|
57396
57657
|
var DEFAULT_LOOP_PROVIDER = "claude";
|
|
@@ -57596,7 +57857,7 @@ var LoopService = class {
|
|
|
57596
57857
|
this.loops = /* @__PURE__ */ new Map();
|
|
57597
57858
|
this.persistQueue = Promise.resolve();
|
|
57598
57859
|
this.running = /* @__PURE__ */ new Map();
|
|
57599
|
-
this.storePath =
|
|
57860
|
+
this.storePath = path29.join(options.appostleHome, "loops", "loops.json");
|
|
57600
57861
|
this.logger = options.logger.child({ module: "loop-service" });
|
|
57601
57862
|
}
|
|
57602
57863
|
async initialize() {
|
|
@@ -57665,7 +57926,7 @@ var LoopService = class {
|
|
|
57665
57926
|
id: createLoopId(),
|
|
57666
57927
|
name: normalizeName(input.name),
|
|
57667
57928
|
prompt,
|
|
57668
|
-
cwd:
|
|
57929
|
+
cwd: path29.resolve(input.cwd),
|
|
57669
57930
|
provider: input.provider ?? DEFAULT_LOOP_PROVIDER,
|
|
57670
57931
|
model: normalizePrompt(input.model, "model"),
|
|
57671
57932
|
workerProvider: input.workerProvider ?? null,
|
|
@@ -58113,7 +58374,7 @@ ${output}` : `exit ${result.exitCode}`
|
|
|
58113
58374
|
}
|
|
58114
58375
|
async persist() {
|
|
58115
58376
|
const nextPersist = this.persistQueue.then(async () => {
|
|
58116
|
-
await fs16.mkdir(
|
|
58377
|
+
await fs16.mkdir(path29.dirname(this.storePath), { recursive: true });
|
|
58117
58378
|
const records = Array.from(this.loops.values()).sort(
|
|
58118
58379
|
(left, right) => left.createdAt.localeCompare(right.createdAt)
|
|
58119
58380
|
);
|
|
@@ -58659,12 +58920,12 @@ import { randomUUID as randomUUID15 } from "node:crypto";
|
|
|
58659
58920
|
|
|
58660
58921
|
// ../server/src/server/quest/store.ts
|
|
58661
58922
|
import { promises as fs17 } from "node:fs";
|
|
58662
|
-
import
|
|
58923
|
+
import path30 from "node:path";
|
|
58663
58924
|
import { z as z44 } from "zod";
|
|
58664
58925
|
var StoredQuestsSchema = z44.array(QuestRecordSchema);
|
|
58665
58926
|
var QuestStore = class {
|
|
58666
58927
|
constructor(options) {
|
|
58667
|
-
this.filePath =
|
|
58928
|
+
this.filePath = path30.join(options.appostleHome, "quests", "quests.json");
|
|
58668
58929
|
this.logger = options.logger;
|
|
58669
58930
|
this.records = /* @__PURE__ */ new Map();
|
|
58670
58931
|
this.persistQueue = Promise.resolve();
|
|
@@ -58705,7 +58966,7 @@ var QuestStore = class {
|
|
|
58705
58966
|
}
|
|
58706
58967
|
async persist() {
|
|
58707
58968
|
this.persistQueue = this.persistQueue.then(async () => {
|
|
58708
|
-
await fs17.mkdir(
|
|
58969
|
+
await fs17.mkdir(path30.dirname(this.filePath), { recursive: true });
|
|
58709
58970
|
const payload = JSON.stringify([...this.records.values()], null, 2);
|
|
58710
58971
|
await fs17.writeFile(this.filePath, payload, "utf8");
|
|
58711
58972
|
}).catch((err) => {
|
|
@@ -59471,7 +59732,7 @@ ${text || "(no output)"}`).join("\n\n");
|
|
|
59471
59732
|
|
|
59472
59733
|
// ../server/src/server/quest/runner-orchestrator.ts
|
|
59473
59734
|
import { access, readFile as readFile5 } from "node:fs/promises";
|
|
59474
|
-
import
|
|
59735
|
+
import path31 from "node:path";
|
|
59475
59736
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
59476
59737
|
|
|
59477
59738
|
// ../server/src/server/quest/orchestrator-mcp.ts
|
|
@@ -59702,16 +59963,16 @@ var FALLBACK_QUEEN_PROMPT_TEMPLATE = [
|
|
|
59702
59963
|
var QUEEN_PROMPT_FILENAME = "queen-prompt.md";
|
|
59703
59964
|
var QUEEN_PROMPT_MAX_LOOKUP_LEVELS = 10;
|
|
59704
59965
|
async function findQueenPromptOnDisk() {
|
|
59705
|
-
const start =
|
|
59966
|
+
const start = path31.dirname(fileURLToPath5(import.meta.url));
|
|
59706
59967
|
let cursor = start;
|
|
59707
59968
|
for (let i = 0; i < QUEEN_PROMPT_MAX_LOOKUP_LEVELS; i += 1) {
|
|
59708
|
-
const candidate =
|
|
59969
|
+
const candidate = path31.join(cursor, QUEEN_PROMPT_FILENAME);
|
|
59709
59970
|
try {
|
|
59710
59971
|
await access(candidate);
|
|
59711
59972
|
return candidate;
|
|
59712
59973
|
} catch {
|
|
59713
59974
|
}
|
|
59714
|
-
const parent =
|
|
59975
|
+
const parent = path31.dirname(cursor);
|
|
59715
59976
|
if (parent === cursor) break;
|
|
59716
59977
|
cursor = parent;
|
|
59717
59978
|
}
|
|
@@ -59757,7 +60018,7 @@ async function resolveWorkerConfigForHandoff(args) {
|
|
|
59757
60018
|
title: `quest ${record.id} handoff: ${taskTitle}`,
|
|
59758
60019
|
internal: true
|
|
59759
60020
|
};
|
|
59760
|
-
const roleName =
|
|
60021
|
+
const roleName = path31.basename(rolePath, path31.extname(rolePath));
|
|
59761
60022
|
try {
|
|
59762
60023
|
const resolved = await resolveRole({
|
|
59763
60024
|
roleName,
|
|
@@ -59936,7 +60197,7 @@ var OrchestratorRunner = class {
|
|
|
59936
60197
|
import { promisify as promisify4 } from "node:util";
|
|
59937
60198
|
import { execFile as execFile3 } from "node:child_process";
|
|
59938
60199
|
import { appendFile, mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
|
|
59939
|
-
import
|
|
60200
|
+
import path32 from "node:path";
|
|
59940
60201
|
var execFileAsync3 = promisify4(execFile3);
|
|
59941
60202
|
var MAX_VERIFY_OUTPUT_BYTES2 = 64 * 1024;
|
|
59942
60203
|
function nowIso5() {
|
|
@@ -60011,7 +60272,7 @@ function runContainsPromise(run, completionPromise) {
|
|
|
60011
60272
|
return finalText.includes(completionPromise);
|
|
60012
60273
|
}
|
|
60013
60274
|
function resolveRalphStatePaths(cwd) {
|
|
60014
|
-
const dir =
|
|
60275
|
+
const dir = path32.join(cwd, ".hiveminds", "ralph loop");
|
|
60015
60276
|
return {
|
|
60016
60277
|
dir,
|
|
60017
60278
|
logPath: ""
|
|
@@ -60021,7 +60282,7 @@ async function initializeRalphState(args) {
|
|
|
60021
60282
|
const base = resolveRalphStatePaths(args.record.cwd);
|
|
60022
60283
|
const paths = {
|
|
60023
60284
|
dir: base.dir,
|
|
60024
|
-
logPath:
|
|
60285
|
+
logPath: path32.join(base.dir, `ralphloop_${args.record.id}.md`)
|
|
60025
60286
|
};
|
|
60026
60287
|
await mkdir9(paths.dir, { recursive: true });
|
|
60027
60288
|
await writeFile8(
|
|
@@ -60256,8 +60517,8 @@ function deepMerge(current, patch) {
|
|
|
60256
60517
|
}
|
|
60257
60518
|
return next;
|
|
60258
60519
|
}
|
|
60259
|
-
function getValueAtPath(config,
|
|
60260
|
-
return
|
|
60520
|
+
function getValueAtPath(config, path38) {
|
|
60521
|
+
return path38.split(".").reduce((value, segment) => isRecord3(value) ? value[segment] : void 0, config);
|
|
60261
60522
|
}
|
|
60262
60523
|
function isEqualValue(a, b) {
|
|
60263
60524
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
@@ -60276,20 +60537,20 @@ var DaemonConfigStore = class {
|
|
|
60276
60537
|
patch(partial) {
|
|
60277
60538
|
const parsedPatch = MutableDaemonConfigPatchSchema.parse(partial);
|
|
60278
60539
|
const next = MutableDaemonConfigSchema.parse(deepMerge(this.current, parsedPatch));
|
|
60279
|
-
const changedFieldPaths = Array.from(this.fieldChangeHandlers.keys()).filter((
|
|
60280
|
-
return !isEqualValue(getValueAtPath(this.current,
|
|
60540
|
+
const changedFieldPaths = Array.from(this.fieldChangeHandlers.keys()).filter((path38) => {
|
|
60541
|
+
return !isEqualValue(getValueAtPath(this.current, path38), getValueAtPath(next, path38));
|
|
60281
60542
|
});
|
|
60282
60543
|
if (changedFieldPaths.length === 0 && isEqualValue(this.current, next)) {
|
|
60283
60544
|
return this.current;
|
|
60284
60545
|
}
|
|
60285
60546
|
this.persistConfig(next);
|
|
60286
60547
|
this.current = next;
|
|
60287
|
-
for (const
|
|
60288
|
-
const handlers = this.fieldChangeHandlers.get(
|
|
60548
|
+
for (const path38 of changedFieldPaths) {
|
|
60549
|
+
const handlers = this.fieldChangeHandlers.get(path38);
|
|
60289
60550
|
if (!handlers) {
|
|
60290
60551
|
continue;
|
|
60291
60552
|
}
|
|
60292
|
-
const value = getValueAtPath(next,
|
|
60553
|
+
const value = getValueAtPath(next, path38);
|
|
60293
60554
|
for (const handler of handlers) {
|
|
60294
60555
|
handler(value);
|
|
60295
60556
|
}
|
|
@@ -60299,18 +60560,18 @@ var DaemonConfigStore = class {
|
|
|
60299
60560
|
}
|
|
60300
60561
|
return next;
|
|
60301
60562
|
}
|
|
60302
|
-
onFieldChange(
|
|
60303
|
-
const handlers = this.fieldChangeHandlers.get(
|
|
60563
|
+
onFieldChange(path38, handler) {
|
|
60564
|
+
const handlers = this.fieldChangeHandlers.get(path38) ?? /* @__PURE__ */ new Set();
|
|
60304
60565
|
handlers.add(handler);
|
|
60305
|
-
this.fieldChangeHandlers.set(
|
|
60566
|
+
this.fieldChangeHandlers.set(path38, handlers);
|
|
60306
60567
|
return () => {
|
|
60307
|
-
const currentHandlers = this.fieldChangeHandlers.get(
|
|
60568
|
+
const currentHandlers = this.fieldChangeHandlers.get(path38);
|
|
60308
60569
|
if (!currentHandlers) {
|
|
60309
60570
|
return;
|
|
60310
60571
|
}
|
|
60311
60572
|
currentHandlers.delete(handler);
|
|
60312
60573
|
if (currentHandlers.size === 0) {
|
|
60313
|
-
this.fieldChangeHandlers.delete(
|
|
60574
|
+
this.fieldChangeHandlers.delete(path38);
|
|
60314
60575
|
}
|
|
60315
60576
|
};
|
|
60316
60577
|
}
|
|
@@ -61806,8 +62067,8 @@ function createAuthServerClient(options) {
|
|
|
61806
62067
|
}
|
|
61807
62068
|
|
|
61808
62069
|
// ../server/src/server/package-version.ts
|
|
61809
|
-
import { existsSync as
|
|
61810
|
-
import
|
|
62070
|
+
import { existsSync as existsSync19, readFileSync as readFileSync10 } from "node:fs";
|
|
62071
|
+
import path33 from "node:path";
|
|
61811
62072
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
61812
62073
|
var PackageVersionResolutionError = class extends Error {
|
|
61813
62074
|
constructor(params) {
|
|
@@ -61817,10 +62078,10 @@ var PackageVersionResolutionError = class extends Error {
|
|
|
61817
62078
|
};
|
|
61818
62079
|
function resolvePackageVersion(params) {
|
|
61819
62080
|
const moduleUrl = params.moduleUrl ?? import.meta.url;
|
|
61820
|
-
let currentDir =
|
|
62081
|
+
let currentDir = path33.dirname(fileURLToPath6(moduleUrl));
|
|
61821
62082
|
while (true) {
|
|
61822
|
-
const packageJsonPath =
|
|
61823
|
-
if (
|
|
62083
|
+
const packageJsonPath = path33.join(currentDir, "package.json");
|
|
62084
|
+
if (existsSync19(packageJsonPath)) {
|
|
61824
62085
|
try {
|
|
61825
62086
|
const packageJson = JSON.parse(readFileSync10(packageJsonPath, "utf8"));
|
|
61826
62087
|
if (packageJson.name === params.packageName) {
|
|
@@ -61838,7 +62099,7 @@ function resolvePackageVersion(params) {
|
|
|
61838
62099
|
}
|
|
61839
62100
|
}
|
|
61840
62101
|
}
|
|
61841
|
-
const parentDir =
|
|
62102
|
+
const parentDir = path33.dirname(currentDir);
|
|
61842
62103
|
if (parentDir === currentDir) {
|
|
61843
62104
|
break;
|
|
61844
62105
|
}
|
|
@@ -62203,8 +62464,10 @@ async function createAppostleDaemon(config, rootLogger) {
|
|
|
62203
62464
|
const daemonKeyPair = await loadOrCreateDaemonKeyPair(config.appostleHome, logger);
|
|
62204
62465
|
let relayTransport = null;
|
|
62205
62466
|
let authServerClient = null;
|
|
62467
|
+
let ownerUserId = null;
|
|
62206
62468
|
{
|
|
62207
62469
|
const persisted = loadPersistedConfig(config.appostleHome, logger);
|
|
62470
|
+
ownerUserId = persisted.account?.userId ?? null;
|
|
62208
62471
|
if (persisted.account) {
|
|
62209
62472
|
authServerClient = createAuthServerClient({
|
|
62210
62473
|
logger,
|
|
@@ -62341,11 +62604,11 @@ async function createAppostleDaemon(config, rootLogger) {
|
|
|
62341
62604
|
httpServer.on("upgrade", scriptProxyUpgradeHandler);
|
|
62342
62605
|
const agentStorage = new AgentStorage(config.agentStoragePath, logger);
|
|
62343
62606
|
const projectRegistry = new FileBackedProjectRegistry(
|
|
62344
|
-
|
|
62607
|
+
path34.join(config.appostleHome, "projects", "projects.json"),
|
|
62345
62608
|
logger
|
|
62346
62609
|
);
|
|
62347
62610
|
workspaceRegistry = new FileBackedWorkspaceRegistry(
|
|
62348
|
-
|
|
62611
|
+
path34.join(config.appostleHome, "projects", "workspaces.json"),
|
|
62349
62612
|
logger
|
|
62350
62613
|
);
|
|
62351
62614
|
const chatService = new FileBackedChatService({
|
|
@@ -62363,6 +62626,7 @@ async function createAppostleDaemon(config, rootLogger) {
|
|
|
62363
62626
|
registry: agentStorage,
|
|
62364
62627
|
appostleHome: config.appostleHome,
|
|
62365
62628
|
chromeEnabled: config.chromeEnabled ?? true,
|
|
62629
|
+
ownerUserId: ownerUserId ?? void 0,
|
|
62366
62630
|
logger
|
|
62367
62631
|
});
|
|
62368
62632
|
const providerRegistry = buildProviderRegistry(logger, {
|
|
@@ -62691,7 +62955,7 @@ async function createAppostleDaemon(config, rootLogger) {
|
|
|
62691
62955
|
if (listenTarget.type === "tcp") {
|
|
62692
62956
|
httpServer.listen(listenTarget.port, listenTarget.host);
|
|
62693
62957
|
} else {
|
|
62694
|
-
if (listenTarget.type === "socket" &&
|
|
62958
|
+
if (listenTarget.type === "socket" && existsSync20(listenTarget.path)) {
|
|
62695
62959
|
unlinkSync(listenTarget.path);
|
|
62696
62960
|
}
|
|
62697
62961
|
httpServer.listen(listenTarget.path);
|
|
@@ -62721,7 +62985,7 @@ async function createAppostleDaemon(config, rootLogger) {
|
|
|
62721
62985
|
await new Promise((resolve15) => {
|
|
62722
62986
|
httpServer.close(() => resolve15());
|
|
62723
62987
|
});
|
|
62724
|
-
if (listenTarget.type === "socket" &&
|
|
62988
|
+
if (listenTarget.type === "socket" && existsSync20(listenTarget.path)) {
|
|
62725
62989
|
unlinkSync(listenTarget.path);
|
|
62726
62990
|
}
|
|
62727
62991
|
};
|
|
@@ -62752,16 +63016,16 @@ async function closeAllAgents(logger, agentManager) {
|
|
|
62752
63016
|
}
|
|
62753
63017
|
|
|
62754
63018
|
// ../server/src/server/config.ts
|
|
62755
|
-
import
|
|
63019
|
+
import path36 from "node:path";
|
|
62756
63020
|
import { z as z51 } from "zod";
|
|
62757
63021
|
|
|
62758
63022
|
// ../server/src/server/speech/speech-config-resolver.ts
|
|
62759
63023
|
import { z as z50 } from "zod";
|
|
62760
63024
|
|
|
62761
63025
|
// ../server/src/server/speech/providers/local/config.ts
|
|
62762
|
-
import
|
|
63026
|
+
import path35 from "node:path";
|
|
62763
63027
|
import { z as z48 } from "zod";
|
|
62764
|
-
var DEFAULT_LOCAL_MODELS_SUBDIR =
|
|
63028
|
+
var DEFAULT_LOCAL_MODELS_SUBDIR = path35.join("models", "local-speech");
|
|
62765
63029
|
var NumberLikeSchema2 = z48.union([z48.number(), z48.string().trim().min(1)]);
|
|
62766
63030
|
var OptionalFiniteNumberSchema2 = NumberLikeSchema2.pipe(z48.coerce.number().finite()).optional();
|
|
62767
63031
|
var OptionalIntegerSchema = NumberLikeSchema2.pipe(z48.coerce.number().int()).optional();
|
|
@@ -62788,7 +63052,7 @@ function resolveLocalSpeechConfig(params) {
|
|
|
62788
63052
|
const includeProviderConfig = shouldIncludeLocalProviderConfig(params);
|
|
62789
63053
|
const parsed = LocalSpeechResolutionSchema.parse({
|
|
62790
63054
|
includeProviderConfig,
|
|
62791
|
-
modelsDir: params.env.APPOSTLE_LOCAL_MODELS_DIR ?? params.persisted.providers?.local?.modelsDir ??
|
|
63055
|
+
modelsDir: params.env.APPOSTLE_LOCAL_MODELS_DIR ?? params.persisted.providers?.local?.modelsDir ?? path35.join(params.appostleHome, DEFAULT_LOCAL_MODELS_SUBDIR),
|
|
62792
63056
|
dictationLocalSttModel: params.env.APPOSTLE_DICTATION_LOCAL_STT_MODEL ?? persistedLocalFeatureModel(
|
|
62793
63057
|
params.providers.dictationStt.provider,
|
|
62794
63058
|
params.providers.dictationStt.enabled,
|
|
@@ -63044,7 +63308,7 @@ function loadConfig(appostleHome, options) {
|
|
|
63044
63308
|
chromeEnabled,
|
|
63045
63309
|
mcpDebug: env.MCP_DEBUG === "1",
|
|
63046
63310
|
daemonIcon,
|
|
63047
|
-
agentStoragePath:
|
|
63311
|
+
agentStoragePath: path36.join(appostleHome, "agents"),
|
|
63048
63312
|
staticDir: "public",
|
|
63049
63313
|
agentClients: {},
|
|
63050
63314
|
relayEnabled,
|
|
@@ -63062,8 +63326,8 @@ function loadConfig(appostleHome, options) {
|
|
|
63062
63326
|
}
|
|
63063
63327
|
|
|
63064
63328
|
// ../server/src/server/logger.ts
|
|
63065
|
-
import { existsSync as
|
|
63066
|
-
import
|
|
63329
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync8, readdirSync as readdirSync3, renameSync as renameSync3, unlinkSync as unlinkSync2 } from "node:fs";
|
|
63330
|
+
import path37 from "node:path";
|
|
63067
63331
|
import pino from "pino";
|
|
63068
63332
|
import pretty from "pino-pretty";
|
|
63069
63333
|
import { createStream as createRotatingFileStream } from "rotating-file-stream";
|
|
@@ -63106,14 +63370,14 @@ function parsePositiveInteger(value) {
|
|
|
63106
63370
|
return parsed;
|
|
63107
63371
|
}
|
|
63108
63372
|
function resolveFilePath(appostleHome, configuredPath) {
|
|
63109
|
-
const fallback =
|
|
63373
|
+
const fallback = path37.join(appostleHome, DEFAULT_DAEMON_LOG_FILENAME);
|
|
63110
63374
|
if (!configuredPath) {
|
|
63111
63375
|
return fallback;
|
|
63112
63376
|
}
|
|
63113
|
-
if (
|
|
63377
|
+
if (path37.isAbsolute(configuredPath)) {
|
|
63114
63378
|
return configuredPath;
|
|
63115
63379
|
}
|
|
63116
|
-
return
|
|
63380
|
+
return path37.resolve(appostleHome, configuredPath);
|
|
63117
63381
|
}
|
|
63118
63382
|
function minLogLevel(levels) {
|
|
63119
63383
|
let minLevel = levels[0];
|
|
@@ -63149,21 +63413,21 @@ function normalizeLoggerConfigInput(config) {
|
|
|
63149
63413
|
return config;
|
|
63150
63414
|
}
|
|
63151
63415
|
function rotateOnRestart(filePath, maxFiles) {
|
|
63152
|
-
if (!
|
|
63153
|
-
const dir =
|
|
63154
|
-
const base =
|
|
63416
|
+
if (!existsSync21(filePath)) return;
|
|
63417
|
+
const dir = path37.dirname(filePath);
|
|
63418
|
+
const base = path37.basename(filePath);
|
|
63155
63419
|
const now = /* @__PURE__ */ new Date();
|
|
63156
63420
|
const pad = (n) => String(n).padStart(2, "0");
|
|
63157
63421
|
const ts = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}`;
|
|
63158
63422
|
try {
|
|
63159
|
-
renameSync3(filePath,
|
|
63423
|
+
renameSync3(filePath, path37.join(dir, `${ts}-00-${base}`));
|
|
63160
63424
|
} catch {
|
|
63161
63425
|
return;
|
|
63162
63426
|
}
|
|
63163
63427
|
const rotatedFiles = readdirSync3(dir).filter((f) => f.endsWith(`-${base}`) && f !== base).sort().reverse();
|
|
63164
63428
|
for (const file of rotatedFiles.slice(maxFiles)) {
|
|
63165
63429
|
try {
|
|
63166
|
-
unlinkSync2(
|
|
63430
|
+
unlinkSync2(path37.join(dir, file));
|
|
63167
63431
|
} catch {
|
|
63168
63432
|
}
|
|
63169
63433
|
}
|
|
@@ -63212,15 +63476,15 @@ function resolveLogConfig(configInput, options) {
|
|
|
63212
63476
|
}
|
|
63213
63477
|
function createRootLogger(configInput, options) {
|
|
63214
63478
|
const config = resolveLogConfig(configInput, options);
|
|
63215
|
-
|
|
63479
|
+
mkdirSync8(path37.dirname(config.file.path), { recursive: true });
|
|
63216
63480
|
const consoleStream = config.console.format === "pretty" ? pretty({
|
|
63217
63481
|
colorize: true,
|
|
63218
63482
|
singleLine: true,
|
|
63219
63483
|
ignore: "pid,hostname"
|
|
63220
63484
|
}) : pino.destination({ dest: 1, sync: false });
|
|
63221
63485
|
rotateOnRestart(config.file.path, config.file.rotate.maxFiles);
|
|
63222
|
-
const fileStream = createRotatingFileStream(
|
|
63223
|
-
path:
|
|
63486
|
+
const fileStream = createRotatingFileStream(path37.basename(config.file.path), {
|
|
63487
|
+
path: path37.dirname(config.file.path),
|
|
63224
63488
|
size: toRotatingFileStreamSize(config.file.rotate.maxSize),
|
|
63225
63489
|
maxFiles: config.file.rotate.maxFiles
|
|
63226
63490
|
});
|
|
@@ -63235,7 +63499,7 @@ function createRootLogger(configInput, options) {
|
|
|
63235
63499
|
|
|
63236
63500
|
// ../server/src/server/pid-lock.ts
|
|
63237
63501
|
import { open, readFile as readFile7, unlink as unlink4, mkdir as mkdir10 } from "node:fs/promises";
|
|
63238
|
-
import { existsSync as
|
|
63502
|
+
import { existsSync as existsSync22 } from "node:fs";
|
|
63239
63503
|
import { join as join23 } from "node:path";
|
|
63240
63504
|
import { hostname } from "node:os";
|
|
63241
63505
|
var PidLockError = class extends Error {
|
|
@@ -63264,7 +63528,7 @@ function resolveOwnerPid(ownerPid) {
|
|
|
63264
63528
|
}
|
|
63265
63529
|
async function acquirePidLock(appostleHome, listen, options) {
|
|
63266
63530
|
const pidPath = getPidFilePath(appostleHome);
|
|
63267
|
-
if (!
|
|
63531
|
+
if (!existsSync22(appostleHome)) {
|
|
63268
63532
|
await mkdir10(appostleHome, { recursive: true });
|
|
63269
63533
|
}
|
|
63270
63534
|
let existingLock = null;
|