@jmfederico/pi-web 1.202607.0 → 1.202607.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -9
- package/dist/cli.js +305 -322
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/{CodeViewer-tXF3UTsY.js → CodeViewer-B4M13447.js} +1 -1
- package/dist/client/assets/{TerminalPanel-D_ihiWAt.js → TerminalPanel-Bmvj-Ecn.js} +1 -1
- package/dist/client/assets/{UnifiedDiffViewer-BziirXBJ.js → UnifiedDiffViewer-C0hygwRo.js} +1 -1
- package/dist/client/assets/index-TvPsRyS1.js +3545 -0
- package/dist/client/index.html +6 -6
- package/dist/client/manifest.webmanifest +4 -4
- package/dist/config.js +157 -2
- package/dist/config.js.map +1 -1
- package/dist/nativeServices/serviceDoctor.js +480 -0
- package/dist/nativeServices/serviceDoctor.js.map +1 -0
- package/dist/nativeServices/serviceInstall.js +35 -0
- package/dist/nativeServices/serviceInstall.js.map +1 -0
- package/dist/nativeServices/servicePlan.js +358 -0
- package/dist/nativeServices/servicePlan.js.map +1 -0
- package/dist/nativeServices/serviceProbe.js +447 -0
- package/dist/nativeServices/serviceProbe.js.map +1 -0
- package/dist/nativeServices/serviceRendering.js +122 -0
- package/dist/nativeServices/serviceRendering.js.map +1 -0
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +12 -0
- package/dist/plugin-api.d.ts +2 -0
- package/dist/server/activeAgentProfileProvider.js +25 -0
- package/dist/server/activeAgentProfileProvider.js.map +1 -0
- package/dist/server/app.js +57 -16
- package/dist/server/app.js.map +1 -1
- package/dist/server/configRoutes.js +43 -9
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/diagnostics/nodePtyNativeModule.js +36 -0
- package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -0
- package/dist/server/git/gitService.js +176 -5
- package/dist/server/git/gitService.js.map +1 -1
- package/dist/server/machines/machinePluginProxyRoutes.js +7 -4
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +16 -4
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineRoutes.js +1 -1
- package/dist/server/machines/machineRoutes.js.map +1 -1
- package/dist/server/machines/machineService.js +2 -2
- package/dist/server/machines/machineService.js.map +1 -1
- package/dist/server/piPackageRoutes.js +7 -3
- package/dist/server/piPackageRoutes.js.map +1 -1
- package/dist/server/piPackageService.js +34 -2
- package/dist/server/piPackageService.js.map +1 -1
- package/dist/server/piWebPluginService.js +48 -12
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebReleaseLookupCache.js +37 -0
- package/dist/server/piWebReleaseLookupCache.js.map +1 -0
- package/dist/server/piWebStatus.js +38 -39
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/piWebStatusCache.js +19 -6
- package/dist/server/piWebStatusCache.js.map +1 -1
- package/dist/server/realtime/sessionEventHub.js +37 -7
- package/dist/server/realtime/sessionEventHub.js.map +1 -1
- package/dist/server/sessiond/sessionDaemonStartup.js +49 -0
- package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -0
- package/dist/server/sessiond.js +128 -62
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/authProviderOptions.js +30 -32
- package/dist/server/sessions/authProviderOptions.js.map +1 -1
- package/dist/server/sessions/authRoutes.js +14 -4
- package/dist/server/sessions/authRoutes.js.map +1 -1
- package/dist/server/sessions/authService.js +140 -29
- package/dist/server/sessions/authService.js.map +1 -1
- package/dist/server/sessions/globalProviderPolicy.js +98 -0
- package/dist/server/sessions/globalProviderPolicy.js.map +1 -0
- package/dist/server/sessions/modelCatalogRefresher.js +184 -0
- package/dist/server/sessions/modelCatalogRefresher.js.map +1 -0
- package/dist/server/sessions/oauthLoginFlowService.js +176 -53
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
- package/dist/server/sessions/piSessionManagerGateway.js +22 -21
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +936 -111
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/plainTextTheme.js +112 -0
- package/dist/server/sessions/plainTextTheme.js.map +1 -0
- package/dist/server/sessions/sessionArchiveMigration.js +590 -0
- package/dist/server/sessions/sessionArchiveMigration.js.map +1 -0
- package/dist/server/sessions/sessionArchiveStore.js +7 -4
- package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +68 -9
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionNotificationStore.js +484 -0
- package/dist/server/sessions/sessionNotificationStore.js.map +1 -0
- package/dist/server/sessions/sessionRoutes.js +202 -2
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/sessionService.js +2 -0
- package/dist/server/sessions/sessionService.js.map +1 -0
- package/dist/server/sessions/sessionTreeProjection.js +250 -0
- package/dist/server/sessions/sessionTreeProjection.js.map +1 -0
- package/dist/server/sessions/sessionUnreadStore.js +520 -0
- package/dist/server/sessions/sessionUnreadStore.js.map +1 -0
- package/dist/server/sessions/spawnSessionTool.js +2 -2
- package/dist/server/sessions/spawnSessionTool.js.map +1 -1
- package/dist/server/sessions/spawnSubsessionTool.js +69 -31
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
- package/dist/server/terminals/terminalService.js +10 -4
- package/dist/server/terminals/terminalService.js.map +1 -1
- package/dist/sessiond/activeAgentProfile.js +31 -0
- package/dist/sessiond/activeAgentProfile.js.map +1 -0
- package/dist/sessiond/sessionDaemonClient.js +38 -0
- package/dist/sessiond/sessionDaemonClient.js.map +1 -1
- package/dist/shared/activeAgentProfile.js +76 -0
- package/dist/shared/activeAgentProfile.js.map +1 -0
- package/dist/shared/apiTypes.d.ts +256 -4
- package/dist/shared/apiTypes.js +12 -0
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +11 -0
- package/dist/shared/capabilities.js.map +1 -1
- package/dist/shared/federatedRoutes.js +12 -0
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/piWebStatusParsing.js +6 -0
- package/dist/shared/piWebStatusParsing.js.map +1 -1
- package/docs/config.md +85 -12
- package/docs/plugins.md +29 -11
- package/install.sh +1 -1
- package/package.json +9 -8
- package/dist/client/assets/index-Brfk1lwl.js +0 -2950
|
@@ -3,6 +3,7 @@ export class SessionEventHub {
|
|
|
3
3
|
constructor() {
|
|
4
4
|
this.socketsBySession = new Map();
|
|
5
5
|
this.globalSockets = new Set();
|
|
6
|
+
this.seqBySession = new Map();
|
|
6
7
|
}
|
|
7
8
|
add(sessionId, socket) {
|
|
8
9
|
let sockets = this.socketsBySession.get(sessionId);
|
|
@@ -20,20 +21,49 @@ export class SessionEventHub {
|
|
|
20
21
|
socket.on("close", () => this.globalSockets.delete(socket));
|
|
21
22
|
}
|
|
22
23
|
publish(sessionId, event) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
const seq = (this.seqBySession.get(sessionId) ?? 0) + 1;
|
|
25
|
+
this.seqBySession.set(sessionId, seq);
|
|
26
|
+
const payload = JSON.stringify({ ...projectBrowserSessionEvent(event), seq });
|
|
27
|
+
this.sendToSockets(this.socketsBySession.get(sessionId), payload);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Last per-session sequence number stamped by {@link publish} (0 before any
|
|
31
|
+
* event). Callers building a join-time stream snapshot read this as the
|
|
32
|
+
* watermark: buffered live events with `seq <= currentSeq` are already
|
|
33
|
+
* reflected in the snapshot's partial and must be dropped by the client.
|
|
34
|
+
*/
|
|
35
|
+
currentSeq(sessionId) {
|
|
36
|
+
return this.seqBySession.get(sessionId) ?? 0;
|
|
28
37
|
}
|
|
29
38
|
publishGlobal(event) {
|
|
30
39
|
this.publishRealtime(event);
|
|
31
40
|
}
|
|
41
|
+
publishNotificationSummary(event) {
|
|
42
|
+
const payload = JSON.stringify(event);
|
|
43
|
+
this.sendToSockets(this.globalSockets, payload);
|
|
44
|
+
}
|
|
32
45
|
publishRealtime(event) {
|
|
33
46
|
const payload = JSON.stringify(event);
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
this.sendToSockets(this.globalSockets, payload);
|
|
48
|
+
}
|
|
49
|
+
sendToSockets(sockets, payload) {
|
|
50
|
+
if (sockets === undefined)
|
|
51
|
+
return;
|
|
52
|
+
for (const socket of sockets) {
|
|
53
|
+
if (socket.readyState !== socket.OPEN)
|
|
54
|
+
continue;
|
|
55
|
+
try {
|
|
36
56
|
socket.send(payload);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
sockets.delete(socket);
|
|
60
|
+
try {
|
|
61
|
+
socket.terminate();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Removal is authoritative; cleanup failure must not block healthy sockets.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
37
67
|
}
|
|
38
68
|
}
|
|
39
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionEventHub.js","sourceRoot":"","sources":["../../../src/server/realtime/sessionEventHub.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"sessionEventHub.js","sourceRoot":"","sources":["../../../src/server/realtime/sessionEventHub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { migrateLegacySessionArchive, } from "../sessions/sessionArchiveMigration.js";
|
|
2
|
+
/**
|
|
3
|
+
* Keeps archive migration ahead of every archive-state consumer in sessiond.
|
|
4
|
+
* A failed eligible migration stops startup so runtime writes cannot make a
|
|
5
|
+
* clean retry ambiguous; mutation-free eligibility skips still start normally.
|
|
6
|
+
*/
|
|
7
|
+
export async function runSessionDaemonStartup(steps) {
|
|
8
|
+
const result = await (steps.migrateArchive ?? migrateLegacySessionArchive)();
|
|
9
|
+
reportMigrationResult(result, steps.logger);
|
|
10
|
+
if (result.status === "failed") {
|
|
11
|
+
throw new Error(`Legacy session archive migration failed during ${result.phase}; session daemon startup stopped`, { cause: result.error });
|
|
12
|
+
}
|
|
13
|
+
const runtime = await steps.createRuntime();
|
|
14
|
+
steps.registerRoutes(runtime);
|
|
15
|
+
await steps.listen(runtime);
|
|
16
|
+
return runtime;
|
|
17
|
+
}
|
|
18
|
+
function reportMigrationResult(result, logger) {
|
|
19
|
+
if (result.status === "skipped") {
|
|
20
|
+
if (result.reason === "inspection-failed") {
|
|
21
|
+
logger.warn({ err: result.error, reason: result.reason }, "could not inspect legacy session archive migration eligibility; continuing session daemon startup without migration");
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
logger.debug({ reason: result.reason }, "legacy session archive migration is not eligible; continuing session daemon startup");
|
|
25
|
+
}
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (result.status === "failed") {
|
|
29
|
+
logger.error({
|
|
30
|
+
err: result.error,
|
|
31
|
+
phase: result.phase,
|
|
32
|
+
rollbackErrorCount: result.rollbackErrors.length,
|
|
33
|
+
rollbackErrors: result.rollbackErrors,
|
|
34
|
+
}, result.rollbackErrors.length === 0
|
|
35
|
+
? "legacy session archive migration failed before commit; stopping session daemon startup"
|
|
36
|
+
: "legacy session archive migration failed before commit and rollback was incomplete; stopping session daemon startup");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (result.cleanup === "incomplete") {
|
|
40
|
+
logger.warn({
|
|
41
|
+
archiveFileCount: result.archiveFileCount,
|
|
42
|
+
cleanupErrorCount: result.cleanupErrors.length,
|
|
43
|
+
cleanupErrors: result.cleanupErrors,
|
|
44
|
+
}, "legacy session archive migration committed but cleanup was incomplete; continuing with the migrated destination archive");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
logger.info({ archiveFileCount: result.archiveFileCount }, "migrated legacy session archive to the configured PI_WEB_DATA_DIR");
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=sessionDaemonStartup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionDaemonStartup.js","sourceRoot":"","sources":["../../../src/server/sessiond/sessionDaemonStartup.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,GAE5B,MAAM,wCAAwC,CAAC;AAiBhD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAyC;IAEzC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,2BAA2B,CAAC,EAAE,CAAC;IAC7E,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAE5C,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,kDAAkD,MAAM,CAAC,KAAK,kCAAkC,EAChG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CACxB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC;IAC5C,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAA2C,EAC3C,MAAkC;IAElC,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CACT,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAC5C,qHAAqH,CACtH,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CACV,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EACzB,qFAAqF,CACtF,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,KAAK,CACV;YACE,GAAG,EAAE,MAAM,CAAC,KAAK;YACjB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,kBAAkB,EAAE,MAAM,CAAC,cAAc,CAAC,MAAM;YAChD,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,EACD,MAAM,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC;YAChC,CAAC,CAAC,wFAAwF;YAC1F,CAAC,CAAC,oHAAoH,CACzH,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CACT;YACE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,iBAAiB,EAAE,MAAM,CAAC,aAAa,CAAC,MAAM;YAC9C,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,EACD,yHAAyH,CAC1H,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,CAAC,IAAI,CACT,EAAE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,EAC7C,mEAAmE,CACpE,CAAC;AACJ,CAAC"}
|
package/dist/server/sessiond.js
CHANGED
|
@@ -7,9 +7,14 @@ import { WorkspaceActivityService } from "./activity/workspaceActivityService.js
|
|
|
7
7
|
import { registerWorkspaceActivityRoutes } from "./activity/workspaceActivityRoutes.js";
|
|
8
8
|
import { SessionEventHub } from "./realtime/sessionEventHub.js";
|
|
9
9
|
import { AuthService } from "./sessions/authService.js";
|
|
10
|
+
import { bootstrapAndFreezeGlobalExtensionProviders } from "./sessions/globalProviderPolicy.js";
|
|
10
11
|
import { registerAuthRoutes } from "./sessions/authRoutes.js";
|
|
12
|
+
import { ModelCatalogRefresher } from "./sessions/modelCatalogRefresher.js";
|
|
11
13
|
import { PiSessionService } from "./sessions/piSessionService.js";
|
|
14
|
+
import { createPiSessionManagerGateway } from "./sessions/piSessionManagerGateway.js";
|
|
12
15
|
import { registerSessionRoutes } from "./sessions/sessionRoutes.js";
|
|
16
|
+
import { SessionNotificationStore } from "./sessions/sessionNotificationStore.js";
|
|
17
|
+
import { FileSessionUnreadPersistence, SessionUnreadStore } from "./sessions/sessionUnreadStore.js";
|
|
13
18
|
import { ProjectScopedSpawnTargetResolver } from "./sessions/spawnTargetResolver.js";
|
|
14
19
|
import { ProjectService } from "./projects/projectService.js";
|
|
15
20
|
import { ProjectStore } from "./storage/projectStore.js";
|
|
@@ -19,69 +24,130 @@ import { TerminalService } from "./terminals/terminalService.js";
|
|
|
19
24
|
import { registerTerminalRoutes } from "./terminals/terminalRoutes.js";
|
|
20
25
|
import { getPiWebRuntimeComponent } from "./piWebStatus.js";
|
|
21
26
|
import { SESSIOND_RUNTIME_CAPABILITIES } from "../shared/capabilities.js";
|
|
22
|
-
import { effectivePiWebConfig, maxUploadBytes,
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
import { agentSessionDirEnvKeys, effectivePiWebConfig, maxUploadBytes, offlineModeEnabled } from "../config.js";
|
|
28
|
+
import { createActiveAgentProfileDescriptor } from "../sessiond/activeAgentProfile.js";
|
|
29
|
+
import { runSessionDaemonStartup } from "./sessiond/sessionDaemonStartup.js";
|
|
30
|
+
const daemonEnvironment = Object.freeze({ ...process.env });
|
|
31
|
+
const { config } = effectivePiWebConfig({ env: daemonEnvironment });
|
|
32
|
+
const activeAgentProfile = createActiveAgentProfileDescriptor({
|
|
33
|
+
command: config.agent.command,
|
|
34
|
+
dir: config.agent.dir,
|
|
35
|
+
sessionDirEnvKeys: agentSessionDirEnvKeys(config.agent.command),
|
|
36
|
+
});
|
|
37
|
+
const app = Fastify({ logger: true, bodyLimit: maxUploadBytes(daemonEnvironment, config) });
|
|
25
38
|
await app.register(fastifyWebsocket);
|
|
26
|
-
|
|
27
|
-
const workspaceActivity = new WorkspaceActivityService(eventHub);
|
|
28
|
-
const auth = new AuthService();
|
|
29
|
-
const spawnTargets = spawnSessionsEnabled(process.env, config)
|
|
30
|
-
? new ProjectScopedSpawnTargetResolver({ projects: new ProjectService(new ProjectStore()), workspaces: new WorkspaceService() })
|
|
31
|
-
: undefined;
|
|
32
|
-
const sessions = new PiSessionService(eventHub, {
|
|
33
|
-
modelRegistry: auth.modelRegistry,
|
|
34
|
-
workspaceActivity,
|
|
39
|
+
await runSessionDaemonStartup({
|
|
35
40
|
logger: app.log,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
41
|
+
async createRuntime() {
|
|
42
|
+
const eventHub = new SessionEventHub();
|
|
43
|
+
const notificationStore = new SessionNotificationStore();
|
|
44
|
+
const unreadStore = new SessionUnreadStore({
|
|
45
|
+
persistence: new FileSessionUnreadPersistence(),
|
|
46
|
+
onPersistenceError(operation, error) {
|
|
47
|
+
app.log.error({ err: error, operation }, "session unread persistence failed");
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
await unreadStore.load();
|
|
51
|
+
const workspaceActivity = new WorkspaceActivityService(eventHub);
|
|
52
|
+
const auth = await AuthService.create({ agentDir: activeAgentProfile.dir, logger: app.log });
|
|
53
|
+
// Capture providers registered by global extensions while the runtime is
|
|
54
|
+
// still mutable, then freeze every later extension-provider mutation before
|
|
55
|
+
// any real session can load project resources.
|
|
56
|
+
await bootstrapAndFreezeGlobalExtensionProviders(auth.runtime, activeAgentProfile.dir, app.log);
|
|
57
|
+
// The shared model runtime is constructed offline so request paths never
|
|
58
|
+
// wait on provider-catalog fetches; this is the single bounded network
|
|
59
|
+
// refresher, and auth changes (login/logout) ask it for a prompt run. It
|
|
60
|
+
// stays fully inert when the operator asked for offline behavior.
|
|
61
|
+
const catalogRefresher = new ModelCatalogRefresher({
|
|
62
|
+
runtime: auth.runtime,
|
|
63
|
+
logger: app.log,
|
|
64
|
+
offline: offlineModeEnabled(daemonEnvironment),
|
|
65
|
+
});
|
|
66
|
+
catalogRefresher.start();
|
|
67
|
+
auth.subscribe(() => { catalogRefresher.requestRefresh(); });
|
|
68
|
+
const spawnTargets = config.spawnSessions
|
|
69
|
+
? new ProjectScopedSpawnTargetResolver({ projects: new ProjectService(new ProjectStore()), workspaces: new WorkspaceService() })
|
|
70
|
+
: undefined;
|
|
71
|
+
const sessions = new PiSessionService(eventHub, {
|
|
72
|
+
modelRuntime: auth.runtime,
|
|
73
|
+
agentDir: activeAgentProfile.dir,
|
|
74
|
+
workspaceActivity,
|
|
75
|
+
logger: app.log,
|
|
76
|
+
...(spawnTargets === undefined ? {} : { spawnTargets }),
|
|
77
|
+
subsessionsEnabled: spawnTargets !== undefined && config.subsessions,
|
|
78
|
+
notificationStore,
|
|
79
|
+
unreadStore,
|
|
80
|
+
sessionManager: createPiSessionManagerGateway({
|
|
81
|
+
agentDir: activeAgentProfile.dir,
|
|
82
|
+
env: daemonEnvironment,
|
|
83
|
+
sessionDirEnvKeys: activeAgentProfile.sessionDirEnvKeys,
|
|
84
|
+
}),
|
|
85
|
+
});
|
|
86
|
+
auth.subscribe((change) => { sessions.applyAuthChange(change); });
|
|
87
|
+
const terminals = new TerminalService(eventHub, workspaceActivity);
|
|
88
|
+
const runtimeComponent = Object.freeze({
|
|
89
|
+
...getPiWebRuntimeComponent("sessiond", SESSIOND_RUNTIME_CAPABILITIES),
|
|
90
|
+
activeAgentProfile,
|
|
91
|
+
});
|
|
92
|
+
return { eventHub, workspaceActivity, auth, sessions, terminals, unreadStore, activeAgentProfile, runtimeComponent, catalogRefresher };
|
|
93
|
+
},
|
|
94
|
+
registerRoutes({ eventHub, workspaceActivity, auth, sessions, terminals, runtimeComponent }) {
|
|
95
|
+
registerWorkspaceActivityRoutes(app, workspaceActivity);
|
|
96
|
+
registerAuthRoutes(app, auth);
|
|
97
|
+
registerSessionRoutes(app, sessions, eventHub);
|
|
98
|
+
registerTerminalRoutes(app, terminals);
|
|
99
|
+
app.get("/health", () => ({
|
|
100
|
+
ok: true,
|
|
101
|
+
activeSessions: sessions.activeCount(),
|
|
102
|
+
checkedAt: new Date().toISOString(),
|
|
103
|
+
version: {
|
|
104
|
+
component: runtimeComponent.component,
|
|
105
|
+
label: runtimeComponent.label,
|
|
106
|
+
...(runtimeComponent.runtimeVersion === undefined ? {} : { runtimeVersion: runtimeComponent.runtimeVersion }),
|
|
107
|
+
stale: false,
|
|
108
|
+
available: runtimeComponent.available,
|
|
109
|
+
},
|
|
110
|
+
}));
|
|
111
|
+
app.get("/runtime", () => runtimeComponent);
|
|
112
|
+
},
|
|
113
|
+
async listen({ auth, sessions, terminals, unreadStore, catalogRefresher }) {
|
|
114
|
+
let shuttingDown = false;
|
|
115
|
+
async function shutdown(signal) {
|
|
116
|
+
if (shuttingDown)
|
|
117
|
+
return;
|
|
118
|
+
shuttingDown = true;
|
|
119
|
+
app.log.info({ signal }, "shutting down session daemon");
|
|
120
|
+
const attempt = async (operation, run) => {
|
|
121
|
+
try {
|
|
122
|
+
await run();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
process.exitCode = 1;
|
|
126
|
+
app.log.error({ err: error, operation }, "session daemon shutdown operation failed");
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
await attempt("dispose terminals", () => { terminals.dispose(); });
|
|
130
|
+
await attempt("dispose catalog refresher", () => { catalogRefresher.dispose(); });
|
|
131
|
+
await attempt("dispose auth", () => { auth.dispose(); });
|
|
132
|
+
await attempt("dispose sessions", () => sessions.dispose());
|
|
133
|
+
await attempt("flush session unread state", () => unreadStore.flush());
|
|
134
|
+
await attempt("close server", () => app.close());
|
|
135
|
+
}
|
|
136
|
+
process.once("SIGINT", (signal) => { void shutdown(signal); });
|
|
137
|
+
process.once("SIGTERM", (signal) => { void shutdown(signal); });
|
|
138
|
+
const portValue = daemonEnvironment["PI_WEB_SESSIOND_PORT"];
|
|
139
|
+
const port = portValue !== undefined && portValue !== "" ? Number(portValue) : undefined;
|
|
140
|
+
const host = daemonEnvironment["PI_WEB_SESSIOND_HOST"] ?? "127.0.0.1";
|
|
141
|
+
if (port !== undefined) {
|
|
142
|
+
await app.listen({ port, host });
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
const path = sessiondSocketPath();
|
|
146
|
+
await mkdir(dirname(path), { recursive: true });
|
|
147
|
+
await rm(path, { force: true });
|
|
148
|
+
await app.listen({ path });
|
|
149
|
+
process.on("exit", () => void rm(path, { force: true }));
|
|
150
|
+
}
|
|
151
|
+
},
|
|
59
152
|
});
|
|
60
|
-
app.get("/runtime", () => getPiWebRuntimeComponent("sessiond", SESSIOND_RUNTIME_CAPABILITIES));
|
|
61
|
-
let shuttingDown = false;
|
|
62
|
-
async function shutdown(signal) {
|
|
63
|
-
if (shuttingDown)
|
|
64
|
-
return;
|
|
65
|
-
shuttingDown = true;
|
|
66
|
-
app.log.info({ signal }, "shutting down session daemon");
|
|
67
|
-
terminals.dispose();
|
|
68
|
-
auth.dispose();
|
|
69
|
-
await sessions.dispose();
|
|
70
|
-
await app.close();
|
|
71
|
-
}
|
|
72
|
-
process.once("SIGINT", (signal) => { void shutdown(signal); });
|
|
73
|
-
process.once("SIGTERM", (signal) => { void shutdown(signal); });
|
|
74
|
-
const portValue = process.env["PI_WEB_SESSIOND_PORT"];
|
|
75
|
-
const port = portValue !== undefined && portValue !== "" ? Number(portValue) : undefined;
|
|
76
|
-
const host = process.env["PI_WEB_SESSIOND_HOST"] ?? "127.0.0.1";
|
|
77
|
-
if (port !== undefined) {
|
|
78
|
-
await app.listen({ port, host });
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
const path = sessiondSocketPath();
|
|
82
|
-
await mkdir(dirname(path), { recursive: true });
|
|
83
|
-
await rm(path, { force: true });
|
|
84
|
-
await app.listen({ path });
|
|
85
|
-
process.on("exit", () => void rm(path, { force: true }));
|
|
86
|
-
}
|
|
87
153
|
//# sourceMappingURL=sessiond.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessiond.js","sourceRoot":"","sources":["../../src/server/sessiond.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAClF,OAAO,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sessiond.js","sourceRoot":"","sources":["../../src/server/sessiond.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,49 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
export function getLoginProviderOptions(runtime, authType) {
|
|
2
|
+
const providers = runtime.getProviders();
|
|
3
|
+
const options = [];
|
|
4
|
+
for (const provider of providers) {
|
|
5
|
+
if (provider.auth.oauth === undefined)
|
|
6
|
+
continue;
|
|
7
|
+
options.push({
|
|
8
|
+
id: provider.id,
|
|
9
|
+
name: provider.name,
|
|
10
|
+
authType: "oauth",
|
|
11
|
+
status: truthfulProviderStatus(runtime, provider.id),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
for (const provider of providers) {
|
|
15
|
+
if (provider.auth.apiKey?.login === undefined)
|
|
14
16
|
continue;
|
|
15
17
|
options.push({
|
|
16
|
-
id:
|
|
17
|
-
name:
|
|
18
|
+
id: provider.id,
|
|
19
|
+
name: provider.name,
|
|
18
20
|
authType: "api_key",
|
|
19
|
-
status:
|
|
21
|
+
status: truthfulProviderStatus(runtime, provider.id),
|
|
22
|
+
loginFlow: "interactive",
|
|
20
23
|
});
|
|
21
24
|
}
|
|
22
25
|
return filterAndSort(options, authType);
|
|
23
26
|
}
|
|
24
|
-
export function getLogoutProviderOptions(
|
|
27
|
+
export async function getLogoutProviderOptions(runtime) {
|
|
28
|
+
const providerNames = new Map(runtime.getProviders().map((provider) => [provider.id, provider.name]));
|
|
25
29
|
const options = [];
|
|
26
|
-
for (const
|
|
27
|
-
const credential = modelRegistry.authStorage.get(providerId);
|
|
28
|
-
if (credential === undefined)
|
|
29
|
-
continue;
|
|
30
|
+
for (const credential of await runtime.listCredentials()) {
|
|
30
31
|
options.push({
|
|
31
|
-
id: providerId,
|
|
32
|
-
name:
|
|
32
|
+
id: credential.providerId,
|
|
33
|
+
name: providerNames.get(credential.providerId) ?? credential.providerId,
|
|
33
34
|
authType: credential.type,
|
|
34
|
-
status:
|
|
35
|
+
status: truthfulProviderStatus(runtime, credential.providerId),
|
|
35
36
|
});
|
|
36
37
|
}
|
|
37
38
|
return filterAndSort(options);
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (oauthProviderIds.has(providerId))
|
|
45
|
-
return false;
|
|
46
|
-
return true;
|
|
40
|
+
function truthfulProviderStatus(runtime, providerId) {
|
|
41
|
+
const reported = runtime.getProviderAuthStatus(providerId);
|
|
42
|
+
// ModelRuntime reports any stored entry as configured before checking whether
|
|
43
|
+
// the provider can resolve all required credential and ambient fields.
|
|
44
|
+
return reported.configured && !runtime.hasConfiguredAuth(providerId) ? { configured: false } : reported;
|
|
47
45
|
}
|
|
48
46
|
function filterAndSort(options, authType) {
|
|
49
47
|
const filtered = authType === undefined ? options : options.filter((option) => option.authType === authType);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authProviderOptions.js","sourceRoot":"","sources":["../../../src/server/sessions/authProviderOptions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authProviderOptions.js","sourceRoot":"","sources":["../../../src/server/sessions/authProviderOptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export function registerAuthRoutes(app, auth, prefix = "") {
|
|
2
2
|
app.get(`${prefix}/auth/providers`, async (request, reply) => {
|
|
3
3
|
try {
|
|
4
|
-
return auth.authProviders(request.query.mode ?? "login", request.query.authType);
|
|
4
|
+
return await auth.authProviders(request.query.mode ?? "login", request.query.authType);
|
|
5
5
|
}
|
|
6
6
|
catch (error) {
|
|
7
7
|
return reply.code(404).send({ error: error instanceof Error ? error.message : String(error) });
|
|
@@ -9,7 +9,17 @@ export function registerAuthRoutes(app, auth, prefix = "") {
|
|
|
9
9
|
});
|
|
10
10
|
app.post(`${prefix}/auth/api-key`, async (request, reply) => {
|
|
11
11
|
try {
|
|
12
|
-
return auth.saveApiKey(request.body.providerId, request.body.key);
|
|
12
|
+
return await auth.saveApiKey(request.body.providerId, request.body.key);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
// Additive endpoint for newer browsers; the one-secret route remains for
|
|
19
|
+
// rolling compatibility with older browser bundles.
|
|
20
|
+
app.post(`${prefix}/auth/api-key/interactive`, async (request, reply) => {
|
|
21
|
+
try {
|
|
22
|
+
return await auth.startApiKeyLogin(request.body.providerId);
|
|
13
23
|
}
|
|
14
24
|
catch (error) {
|
|
15
25
|
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
|
@@ -17,7 +27,7 @@ export function registerAuthRoutes(app, auth, prefix = "") {
|
|
|
17
27
|
});
|
|
18
28
|
app.post(`${prefix}/auth/logout`, async (request, reply) => {
|
|
19
29
|
try {
|
|
20
|
-
return auth.logoutProvider(request.body.providerId);
|
|
30
|
+
return await auth.logoutProvider(request.body.providerId);
|
|
21
31
|
}
|
|
22
32
|
catch (error) {
|
|
23
33
|
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
|
@@ -25,7 +35,7 @@ export function registerAuthRoutes(app, auth, prefix = "") {
|
|
|
25
35
|
});
|
|
26
36
|
app.post(`${prefix}/auth/oauth`, async (request, reply) => {
|
|
27
37
|
try {
|
|
28
|
-
return auth.startOAuthLogin(request.body.providerId);
|
|
38
|
+
return await auth.startOAuthLogin(request.body.providerId);
|
|
29
39
|
}
|
|
30
40
|
catch (error) {
|
|
31
41
|
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authRoutes.js","sourceRoot":"","sources":["../../../src/server/sessions/authRoutes.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,kBAAkB,CAAC,GAAoB,EAAE,IAAiB,EAAE,MAAM,GAAG,EAAE;IACrF,GAAG,CAAC,GAAG,CAAiF,GAAG,MAAM,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC3I,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"authRoutes.js","sourceRoot":"","sources":["../../../src/server/sessions/authRoutes.ts"],"names":[],"mappings":"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"}
|