agl 21.0.2 → 22.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +19 -0
- package/dist_serve/bundle.js +520 -509
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.aglhome.d.ts +25 -0
- package/dist_ts/classes.aglhome.js +65 -0
- package/dist_ts/classes.authmodels.js +7 -12
- package/dist_ts/classes.authstore.d.ts +1 -2
- package/dist_ts/classes.authstore.js +2 -34
- package/dist_ts/classes.cli.js +93 -35
- package/dist_ts/classes.config.d.ts +2 -11
- package/dist_ts/classes.config.js +14 -80
- package/dist_ts/classes.controller.d.ts +4 -1
- package/dist_ts/classes.controller.js +109 -46
- package/dist_ts/classes.embeddeddb.js +6 -5
- package/dist_ts/classes.gitreversion.js +3 -2
- package/dist_ts/classes.upgradecoordinator.d.ts +6 -1
- package/dist_ts/classes.upgradecoordinator.js +588 -177
- package/dist_ts/classes.upgradetransaction.js +46 -12
- package/dist_ts/classes.uploadmanager.d.ts +12 -0
- package/dist_ts/classes.uploadmanager.js +204 -2
- package/dist_ts/constants.upgradeenvironment.d.ts +2 -0
- package/dist_ts/constants.upgradeenvironment.js +3 -0
- package/dist_ts/functions.controllerdataroot.d.ts +4 -5
- package/dist_ts/functions.controllerdataroot.js +4 -29
- package/dist_ts/functions.embeddeddb.d.ts +1 -1
- package/dist_ts/functions.embeddeddb.js +8 -3
- package/dist_ts/functions.runtimeenvironment.js +2 -1
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +2 -1
- package/dist_ts/interfaces.config.d.ts +5 -7
- package/dist_ts_migration/classes.documentmigrationrunner.js +5 -1
- package/dist_ts_migration/index.d.ts +4 -0
- package/dist_ts_migration/index.js +5 -1
- package/dist_ts_migration/v23_aglhome.d.ts +91 -0
- package/dist_ts_migration/v23_aglhome.js +1775 -0
- package/dist_ts_migration/v23_runtimeconfig.d.ts +11 -0
- package/dist_ts_migration/v23_runtimeconfig.js +87 -0
- package/dist_ts_migration/v24_legacyterminallayout.d.ts +18 -0
- package/dist_ts_migration/v24_legacyterminallayout.js +79 -0
- package/dist_ts_migration/v24_legacyterminallayoutmigration.d.ts +6 -0
- package/dist_ts_migration/v24_legacyterminallayoutmigration.js +67 -0
- package/dist_ts_migration/v2_controllerdataroot.d.ts +5 -0
- package/dist_ts_migration/v2_controllerdataroot.js +176 -15
- package/package.json +1 -1
- package/readme.md +116 -35
- package/readme.plan.md +24 -9
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.aglhome.ts +116 -0
- package/ts/classes.authmodels.ts +5 -13
- package/ts/classes.authstore.ts +1 -54
- package/ts/classes.cli.ts +92 -34
- package/ts/classes.config.ts +20 -117
- package/ts/classes.controller.ts +146 -52
- package/ts/classes.embeddeddb.ts +5 -4
- package/ts/classes.gitreversion.ts +3 -2
- package/ts/classes.upgradecoordinator.ts +668 -191
- package/ts/classes.upgradetransaction.ts +46 -11
- package/ts/classes.uploadmanager.ts +231 -1
- package/ts/constants.upgradeenvironment.ts +2 -0
- package/ts/functions.controllerdataroot.ts +11 -47
- package/ts/functions.embeddeddb.ts +13 -2
- package/ts/functions.runtimeenvironment.ts +1 -0
- package/ts/index.ts +1 -0
- package/ts/interfaces.config.ts +5 -7
- package/ts_migration/classes.documentmigrationrunner.ts +4 -0
- package/ts_migration/index.ts +4 -0
- package/ts_migration/v23_aglhome.ts +2101 -0
- package/ts_migration/v23_runtimeconfig.ts +112 -0
- package/ts_migration/v24_legacyterminallayout.ts +131 -0
- package/ts_migration/v24_legacyterminallayoutmigration.ts +88 -0
- package/ts_migration/v2_controllerdataroot.ts +174 -16
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements.harnesscontrollerapp.ts +32 -2
package/ts/classes.controller.ts
CHANGED
|
@@ -129,6 +129,7 @@ import {
|
|
|
129
129
|
resolveInitialRuntimeConfig,
|
|
130
130
|
resolveStoredRuntimeConfig,
|
|
131
131
|
} from './classes.config.js';
|
|
132
|
+
import { resolveAGLHomePaths } from './classes.aglhome.js';
|
|
132
133
|
import { ensureControllerDataRootForStartup } from './functions.controllerdataroot.js';
|
|
133
134
|
import { SmartDataAuthStore } from './classes.authstore.js';
|
|
134
135
|
import { PasskeyManager } from './classes.passkeymanager.js';
|
|
@@ -301,6 +302,10 @@ import {
|
|
|
301
302
|
resolveCurrentPnpmGlobalInstallation,
|
|
302
303
|
resolveInheritedUpgradeTargetInstallation,
|
|
303
304
|
} from './classes.upgradetransaction.js';
|
|
305
|
+
import {
|
|
306
|
+
upgradeCoordinationRootEnvironmentVariable,
|
|
307
|
+
upgradeTokenEnvironmentVariable,
|
|
308
|
+
} from './constants.upgradeenvironment.js';
|
|
304
309
|
|
|
305
310
|
const currentCliName = String(controllerPackageName) === upgradePackageTransitionSource.packageName
|
|
306
311
|
? upgradePackageTransitionSource.cliName
|
|
@@ -1373,6 +1378,13 @@ interface IControllerHarnessSessionEnumeration {
|
|
|
1373
1378
|
flex: PromiseSettledResult<IControllerSession[]>;
|
|
1374
1379
|
}
|
|
1375
1380
|
|
|
1381
|
+
interface IControllerHarnessSessionEnumerationTask {
|
|
1382
|
+
task: Promise<IControllerHarnessSessionEnumeration>;
|
|
1383
|
+
invalidated: boolean;
|
|
1384
|
+
settled: boolean;
|
|
1385
|
+
waiterCount: number;
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1376
1388
|
export class OpenCodeController {
|
|
1377
1389
|
public readonly options: IControllerStartOptions;
|
|
1378
1390
|
|
|
@@ -1443,6 +1455,7 @@ export class OpenCodeController {
|
|
|
1443
1455
|
private flexAutoAcceptDrainTask?: Promise<void>;
|
|
1444
1456
|
private runtimeConfig?: Awaited<ReturnType<typeof resolveInitialRuntimeConfig>>;
|
|
1445
1457
|
private controllerId?: string;
|
|
1458
|
+
private openCodeRuntimeDirectory?: string;
|
|
1446
1459
|
private authStore?: SmartDataAuthStore;
|
|
1447
1460
|
private passkeyManager?: PasskeyManager;
|
|
1448
1461
|
private openCodeSupervisor?: OpenCodeSupervisor;
|
|
@@ -1503,7 +1516,7 @@ export class OpenCodeController {
|
|
|
1503
1516
|
private readonly activeOperations = new Set<Promise<unknown>>();
|
|
1504
1517
|
private readonly harnessSessionEnumerationTasks = new Map<
|
|
1505
1518
|
string,
|
|
1506
|
-
|
|
1519
|
+
IControllerHarnessSessionEnumerationTask
|
|
1507
1520
|
>();
|
|
1508
1521
|
private readonly sessionLayoutOperationTails = new Map<string, Promise<void>>();
|
|
1509
1522
|
private readonly sessionLayoutOperationDepths = new Map<string, number>();
|
|
@@ -1594,6 +1607,23 @@ export class OpenCodeController {
|
|
|
1594
1607
|
});
|
|
1595
1608
|
}
|
|
1596
1609
|
|
|
1610
|
+
private captureInheritedUpgradeCoordination(): void {
|
|
1611
|
+
try {
|
|
1612
|
+
if (Boolean(this.options.upgradeToken) !== Boolean(this.options.upgradeGlobalRoot)) {
|
|
1613
|
+
throw new Error('Inherited upgrade coordination requires both its token and global root.');
|
|
1614
|
+
}
|
|
1615
|
+
if (!this.options.upgradeToken || !this.options.upgradeGlobalRoot) return;
|
|
1616
|
+
if (process.env[upgradeTokenEnvironmentVariable] !== this.options.upgradeToken) {
|
|
1617
|
+
throw new Error('The inherited upgrade coordination token changed before controller startup.');
|
|
1618
|
+
}
|
|
1619
|
+
this.upgradeToken = this.options.upgradeToken;
|
|
1620
|
+
this.upgradeCoordinator = new UpgradeCoordinator(this.options.upgradeGlobalRoot);
|
|
1621
|
+
} finally {
|
|
1622
|
+
delete process.env[upgradeTokenEnvironmentVariable];
|
|
1623
|
+
delete process.env[upgradeCoordinationRootEnvironmentVariable];
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1597
1627
|
public async start(): Promise<IControllerStartResult> {
|
|
1598
1628
|
if (this.lifecycleState === 'ready') {
|
|
1599
1629
|
return { status: this.getStatus(), publicUrl: this.requireRuntimeConfig().publicOrigin };
|
|
@@ -1705,7 +1735,9 @@ export class OpenCodeController {
|
|
|
1705
1735
|
}
|
|
1706
1736
|
|
|
1707
1737
|
private async performStart(): Promise<IControllerStartResult> {
|
|
1738
|
+
process.env.AGL_HOME = resolveAGLHomePaths().root;
|
|
1708
1739
|
this.lifecycleState = 'starting';
|
|
1740
|
+
this.captureInheritedUpgradeCoordination();
|
|
1709
1741
|
const identity = await readControllerProcessIdentity(process.pid);
|
|
1710
1742
|
this.assertStartActive();
|
|
1711
1743
|
if (identity) {
|
|
@@ -1714,9 +1746,11 @@ export class OpenCodeController {
|
|
|
1714
1746
|
}
|
|
1715
1747
|
let upgradeCliPath: string | undefined;
|
|
1716
1748
|
if (this.options.upgradeToken && this.options.upgradeGlobalRoot) {
|
|
1717
|
-
|
|
1718
|
-
this.
|
|
1719
|
-
|
|
1749
|
+
const inheritedCoordinator = this.upgradeCoordinator;
|
|
1750
|
+
if (!inheritedCoordinator || this.upgradeToken !== this.options.upgradeToken) {
|
|
1751
|
+
throw new Error('The inherited upgrade coordination was not captured before startup.');
|
|
1752
|
+
}
|
|
1753
|
+
const transaction = await inheritedCoordinator.readTransaction(this.options.upgradeToken);
|
|
1720
1754
|
const installation = await resolveInheritedUpgradeTargetInstallation(transaction);
|
|
1721
1755
|
const cliPath = await plugins.fs.promises.realpath(
|
|
1722
1756
|
plugins.url.fileURLToPath(new URL('../cli.js', import.meta.url)),
|
|
@@ -1732,11 +1766,11 @@ export class OpenCodeController {
|
|
|
1732
1766
|
cliName: currentCliName,
|
|
1733
1767
|
cliRelativePath: './cli.js',
|
|
1734
1768
|
});
|
|
1735
|
-
this.upgradeStatus = await
|
|
1769
|
+
this.upgradeStatus = await inheritedCoordinator.readSanitizedUpgradeStatus(
|
|
1736
1770
|
this.options.upgradeToken,
|
|
1737
1771
|
);
|
|
1738
1772
|
upgradeCliPath = cliPath;
|
|
1739
|
-
await
|
|
1773
|
+
await inheritedCoordinator.recordController(this.options.upgradeToken, {
|
|
1740
1774
|
pid: process.pid,
|
|
1741
1775
|
processGroupId: this.processGroupId,
|
|
1742
1776
|
fingerprint: this.processFingerprint,
|
|
@@ -1872,6 +1906,17 @@ export class OpenCodeController {
|
|
|
1872
1906
|
this.assertStartActive();
|
|
1873
1907
|
this.runtimeConfig = runtimeConfig;
|
|
1874
1908
|
this.controllerId = authDocument.id;
|
|
1909
|
+
this.openCodeRuntimeDirectory = plugins.path.join(
|
|
1910
|
+
dataDirectory,
|
|
1911
|
+
'runtime',
|
|
1912
|
+
'opencode',
|
|
1913
|
+
plugins.crypto.createHash('sha256').update(authDocument.id, 'utf8').digest('hex'),
|
|
1914
|
+
);
|
|
1915
|
+
await plugins.fs.promises.mkdir(this.openCodeRuntimeDirectory, {
|
|
1916
|
+
recursive: true,
|
|
1917
|
+
mode: 0o700,
|
|
1918
|
+
});
|
|
1919
|
+
await plugins.fs.promises.chmod(this.openCodeRuntimeDirectory, 0o700);
|
|
1875
1920
|
|
|
1876
1921
|
const passkeyManager = new PasskeyManager({ store: authStore });
|
|
1877
1922
|
this.passkeyManager = passkeyManager;
|
|
@@ -1972,16 +2017,11 @@ export class OpenCodeController {
|
|
|
1972
2017
|
this.setupCodeExpiresAt = setupAuthority?.expiresAt.getTime();
|
|
1973
2018
|
this.assertStartActive();
|
|
1974
2019
|
|
|
1975
|
-
|
|
1976
|
-
|
|
2020
|
+
const pendingProjectRemovals = await this.registerExplicitInitialProject(
|
|
2021
|
+
this.options.runtimeOverrides.initialProjectDirectory,
|
|
2022
|
+
);
|
|
1977
2023
|
const startupProjectState = await this.reconcileProjectState(false);
|
|
1978
2024
|
for (const project of pendingProjectRemovals) this.retiringProjectIds.add(project.id);
|
|
1979
|
-
for (const project of startupProjectState.projects) {
|
|
1980
|
-
await this.runSessionLayoutOperation(
|
|
1981
|
-
project.id,
|
|
1982
|
-
() => authStore.pruneTerminalLayoutEntries(project.id, []),
|
|
1983
|
-
);
|
|
1984
|
-
}
|
|
1985
2025
|
const startupSettings = await authStore.getSettings();
|
|
1986
2026
|
this.defaultModels = startupSettings.defaultModels;
|
|
1987
2027
|
this.autoAcceptPermissions = startupSettings.autoAcceptPermissions === true;
|
|
@@ -2107,6 +2147,7 @@ export class OpenCodeController {
|
|
|
2107
2147
|
database: flexDatabase,
|
|
2108
2148
|
flexCredentialDirectory: plugins.path.join(
|
|
2109
2149
|
dataDirectory,
|
|
2150
|
+
'credentials',
|
|
2110
2151
|
'flex-provider-credentials',
|
|
2111
2152
|
plugins.crypto.createHash('sha256').update(controllerId, 'utf8').digest('hex'),
|
|
2112
2153
|
),
|
|
@@ -2212,7 +2253,8 @@ export class OpenCodeController {
|
|
|
2212
2253
|
browserResourceHost = new ControllerBrowserResourceHost({
|
|
2213
2254
|
runtimeDirectory: plugins.path.join(
|
|
2214
2255
|
dataDirectory,
|
|
2215
|
-
'
|
|
2256
|
+
'runtime',
|
|
2257
|
+
'browser',
|
|
2216
2258
|
plugins.crypto.createHash('sha256').update(controllerId).digest('hex'),
|
|
2217
2259
|
),
|
|
2218
2260
|
authorizeCapability: (requestArg) => (
|
|
@@ -2338,6 +2380,19 @@ export class OpenCodeController {
|
|
|
2338
2380
|
};
|
|
2339
2381
|
}
|
|
2340
2382
|
|
|
2383
|
+
private coordinatorForUpgradeToken(
|
|
2384
|
+
tokenArg: string,
|
|
2385
|
+
globalRootArg: string,
|
|
2386
|
+
): UpgradeCoordinator {
|
|
2387
|
+
if (this.upgradeToken === tokenArg && this.upgradeCoordinator) {
|
|
2388
|
+
if (this.upgradeCoordinator.canonicalGlobalRoot !== globalRootArg) {
|
|
2389
|
+
throw new Error('The inherited upgrade coordination global root changed unexpectedly.');
|
|
2390
|
+
}
|
|
2391
|
+
return this.upgradeCoordinator;
|
|
2392
|
+
}
|
|
2393
|
+
return new UpgradeCoordinator(globalRootArg);
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2341
2396
|
private startOpenCodeEventStream(
|
|
2342
2397
|
openCodeClientArg: OpenCodeClientAdapter,
|
|
2343
2398
|
skipInitialStreamAdvanceArg = false,
|
|
@@ -2476,9 +2531,12 @@ export class OpenCodeController {
|
|
|
2476
2531
|
|
|
2477
2532
|
private createOpenCodeSupervisor(): OpenCodeSupervisor {
|
|
2478
2533
|
const runtimeConfig = this.requireRuntimeConfig();
|
|
2534
|
+
if (!this.openCodeRuntimeDirectory) {
|
|
2535
|
+
throw new Error('The OpenCode runtime directory is unavailable.');
|
|
2536
|
+
}
|
|
2479
2537
|
let supervisor!: OpenCodeSupervisor;
|
|
2480
2538
|
supervisor = new OpenCodeSupervisor({
|
|
2481
|
-
directory:
|
|
2539
|
+
directory: this.openCodeRuntimeDirectory,
|
|
2482
2540
|
port: runtimeConfig.opencodePort,
|
|
2483
2541
|
onChildExit: () => {
|
|
2484
2542
|
this.openCodeSupervisorExitSignals.get(supervisor)?.resolve();
|
|
@@ -3192,6 +3250,7 @@ export class OpenCodeController {
|
|
|
3192
3250
|
this.authStore = undefined;
|
|
3193
3251
|
this.passkeyManager = undefined;
|
|
3194
3252
|
this.controllerId = undefined;
|
|
3253
|
+
this.openCodeRuntimeDirectory = undefined;
|
|
3195
3254
|
}
|
|
3196
3255
|
});
|
|
3197
3256
|
}
|
|
@@ -3312,7 +3371,10 @@ export class OpenCodeController {
|
|
|
3312
3371
|
try {
|
|
3313
3372
|
const installation = await resolveCurrentPnpmGlobalInstallation();
|
|
3314
3373
|
const status = this.getStatus();
|
|
3315
|
-
const coordinator =
|
|
3374
|
+
const coordinator = this.coordinatorForUpgradeToken(
|
|
3375
|
+
requestArg.token,
|
|
3376
|
+
installation.globalRoot,
|
|
3377
|
+
);
|
|
3316
3378
|
await coordinator.consumeLaunchGrant({
|
|
3317
3379
|
token: requestArg.token,
|
|
3318
3380
|
port: this.requireRuntimeConfig().controllerPort,
|
|
@@ -3372,7 +3434,10 @@ export class OpenCodeController {
|
|
|
3372
3434
|
return this.runOperation(peer, async (signalArg) => (
|
|
3373
3435
|
this.runUpgradePreparationAdmission(async () => {
|
|
3374
3436
|
const installation = await resolveCurrentPnpmGlobalInstallation();
|
|
3375
|
-
const coordinator =
|
|
3437
|
+
const coordinator = this.coordinatorForUpgradeToken(
|
|
3438
|
+
requestArg.token,
|
|
3439
|
+
installation.globalRoot,
|
|
3440
|
+
);
|
|
3376
3441
|
const status = this.getStatus();
|
|
3377
3442
|
await coordinator.consumeControllerActionGrant({
|
|
3378
3443
|
token: requestArg.token,
|
|
@@ -3406,7 +3471,10 @@ export class OpenCodeController {
|
|
|
3406
3471
|
return this.runOperation(peer, async () => (
|
|
3407
3472
|
this.runUpgradePreparationAdmission(async () => {
|
|
3408
3473
|
const installation = await resolveCurrentPnpmGlobalInstallation();
|
|
3409
|
-
const coordinator =
|
|
3474
|
+
const coordinator = this.coordinatorForUpgradeToken(
|
|
3475
|
+
requestArg.token,
|
|
3476
|
+
installation.globalRoot,
|
|
3477
|
+
);
|
|
3410
3478
|
if (await this.upgradePreparationReplayIsAccepted(
|
|
3411
3479
|
coordinator,
|
|
3412
3480
|
requestArg.token,
|
|
@@ -3454,7 +3522,10 @@ export class OpenCodeController {
|
|
|
3454
3522
|
);
|
|
3455
3523
|
return this.runOperation(peer, async () => {
|
|
3456
3524
|
const installation = await resolveCurrentPnpmGlobalInstallation();
|
|
3457
|
-
const coordinator =
|
|
3525
|
+
const coordinator = this.coordinatorForUpgradeToken(
|
|
3526
|
+
requestArg.token,
|
|
3527
|
+
installation.globalRoot,
|
|
3528
|
+
);
|
|
3458
3529
|
const status = this.getStatus();
|
|
3459
3530
|
await coordinator.consumeControllerActionGrant({
|
|
3460
3531
|
token: requestArg.token,
|
|
@@ -6187,20 +6258,17 @@ export class OpenCodeController {
|
|
|
6187
6258
|
return projectsRoot;
|
|
6188
6259
|
}
|
|
6189
6260
|
|
|
6190
|
-
private async
|
|
6191
|
-
|
|
6261
|
+
private async registerExplicitInitialProject(
|
|
6262
|
+
initialProjectDirectoryArg: string | undefined,
|
|
6192
6263
|
): Promise<IControllerProjectDocument[]> {
|
|
6193
6264
|
const authStore = this.requireAuthStore();
|
|
6194
|
-
const
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
]);
|
|
6198
|
-
if (activeProjects.length === 0 && pendingRemovals.length === 0) {
|
|
6199
|
-
const workspaceDirectory = await resolveCanonicalDirectory(workspaceDirectoryArg);
|
|
6265
|
+
const pendingRemovals = await authStore.listPendingProjectRemovals();
|
|
6266
|
+
if (initialProjectDirectoryArg !== undefined) {
|
|
6267
|
+
const initialProjectDirectory = await resolveCanonicalDirectory(initialProjectDirectoryArg);
|
|
6200
6268
|
await authStore.createProject(
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6269
|
+
this.deriveProjectName(initialProjectDirectory.directory),
|
|
6270
|
+
initialProjectDirectory.directory,
|
|
6271
|
+
initialProjectDirectory,
|
|
6204
6272
|
);
|
|
6205
6273
|
}
|
|
6206
6274
|
return pendingRemovals;
|
|
@@ -7293,31 +7361,55 @@ export class OpenCodeController {
|
|
|
7293
7361
|
}
|
|
7294
7362
|
}
|
|
7295
7363
|
|
|
7296
|
-
private enumerateHarnessSessions(
|
|
7364
|
+
private async enumerateHarnessSessions(
|
|
7297
7365
|
projectIdArg: string,
|
|
7298
7366
|
directoryArg: string,
|
|
7299
7367
|
signalArg: AbortSignal,
|
|
7300
7368
|
): Promise<IControllerHarnessSessionEnumeration> {
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
Promise.
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7369
|
+
while (true) {
|
|
7370
|
+
signalArg.throwIfAborted();
|
|
7371
|
+
let shared = this.harnessSessionEnumerationTasks.get(projectIdArg);
|
|
7372
|
+
if (!shared || shared.invalidated) {
|
|
7373
|
+
const lifecycleSignal = this.operationAbortController.signal;
|
|
7374
|
+
const operation = Promise.allSettled([
|
|
7375
|
+
Promise.resolve().then(() => (
|
|
7376
|
+
this.requireOpenCodeClient().listSessions(directoryArg, lifecycleSignal)
|
|
7377
|
+
)),
|
|
7378
|
+
Promise.resolve().then(() => this.listFlexSessions(projectIdArg, lifecycleSignal)),
|
|
7379
|
+
]).then(([openCode, flex]) => ({ openCode, flex }));
|
|
7380
|
+
let taskRecord!: IControllerHarnessSessionEnumerationTask;
|
|
7381
|
+
let trackedTask!: Promise<IControllerHarnessSessionEnumeration>;
|
|
7382
|
+
trackedTask = this.trackOperationPromise(operation, () => {
|
|
7383
|
+
taskRecord.settled = true;
|
|
7384
|
+
const current = this.harnessSessionEnumerationTasks.get(projectIdArg);
|
|
7385
|
+
if (current === taskRecord && taskRecord.waiterCount === 0) {
|
|
7386
|
+
this.harnessSessionEnumerationTasks.delete(projectIdArg);
|
|
7387
|
+
}
|
|
7388
|
+
});
|
|
7389
|
+
taskRecord = {
|
|
7390
|
+
task: trackedTask,
|
|
7391
|
+
invalidated: false,
|
|
7392
|
+
settled: false,
|
|
7393
|
+
waiterCount: 0,
|
|
7394
|
+
};
|
|
7395
|
+
shared = taskRecord;
|
|
7396
|
+
this.harnessSessionEnumerationTasks.set(projectIdArg, shared);
|
|
7397
|
+
}
|
|
7398
|
+
shared.waiterCount += 1;
|
|
7399
|
+
try {
|
|
7400
|
+
const result = await this.waitForPromiseWithSignal(shared.task, signalArg);
|
|
7401
|
+
if (!shared.invalidated) return result;
|
|
7402
|
+
} finally {
|
|
7403
|
+
shared.waiterCount -= 1;
|
|
7404
|
+
if (
|
|
7405
|
+
shared.settled
|
|
7406
|
+
&& shared.waiterCount === 0
|
|
7407
|
+
&& this.harnessSessionEnumerationTasks.get(projectIdArg) === shared
|
|
7408
|
+
) {
|
|
7314
7409
|
this.harnessSessionEnumerationTasks.delete(projectIdArg);
|
|
7315
7410
|
}
|
|
7316
|
-
}
|
|
7317
|
-
this.harnessSessionEnumerationTasks.set(projectIdArg, trackedTask);
|
|
7318
|
-
sharedTask = trackedTask;
|
|
7411
|
+
}
|
|
7319
7412
|
}
|
|
7320
|
-
return this.waitForPromiseWithSignal(sharedTask, signalArg);
|
|
7321
7413
|
}
|
|
7322
7414
|
|
|
7323
7415
|
private toFlexSession(
|
|
@@ -11653,7 +11745,7 @@ export class OpenCodeController {
|
|
|
11653
11745
|
signalArg?: AbortSignal,
|
|
11654
11746
|
): Promise<IControllerSession> {
|
|
11655
11747
|
if (sessionIdArg.harnessId === 'opencode') {
|
|
11656
|
-
return this.requireOpenCodeClient().
|
|
11748
|
+
return this.requireOpenCodeClient().getSessionSnapshot(
|
|
11657
11749
|
directoryArg,
|
|
11658
11750
|
sessionIdArg.nativeId,
|
|
11659
11751
|
signalArg,
|
|
@@ -11910,6 +12002,9 @@ export class OpenCodeController {
|
|
|
11910
12002
|
projectIdArg: string,
|
|
11911
12003
|
sessionIdArg: IControllerRuntimeId,
|
|
11912
12004
|
): void {
|
|
12005
|
+
const enumeration = this.harnessSessionEnumerationTasks.get(projectIdArg);
|
|
12006
|
+
if (enumeration) enumeration.invalidated = true;
|
|
12007
|
+
this.harnessSessionEnumerationTasks.delete(projectIdArg);
|
|
11913
12008
|
if (sessionIdArg.harnessId === 'opencode') {
|
|
11914
12009
|
this.purgeOpenCodeStreamStateForSession(projectIdArg, sessionIdArg);
|
|
11915
12010
|
} else if (sessionIdArg.harnessId === 'flex') {
|
|
@@ -14170,13 +14265,12 @@ export class OpenCodeController {
|
|
|
14170
14265
|
if (!client) return;
|
|
14171
14266
|
const deadline = AbortSignal.timeout(abortConversationsOnStopTimeoutMs);
|
|
14172
14267
|
const directories = new Set<string>();
|
|
14173
|
-
if (this.runtimeConfig) directories.add(this.runtimeConfig.workspaceDirectory);
|
|
14174
14268
|
try {
|
|
14175
14269
|
for (const project of (await this.authStore?.listProjects()) ?? []) {
|
|
14176
14270
|
directories.add(project.directory);
|
|
14177
14271
|
}
|
|
14178
14272
|
} catch {
|
|
14179
|
-
// Project registry unavailable
|
|
14273
|
+
// Project registry unavailable; shutdown continues with owned resources.
|
|
14180
14274
|
}
|
|
14181
14275
|
for (const directory of directories) {
|
|
14182
14276
|
try {
|
package/ts/classes.embeddeddb.ts
CHANGED
|
@@ -46,10 +46,8 @@ export class EmbeddedControllerDatabase {
|
|
|
46
46
|
constructor(private readonly options: IEmbeddedControllerDatabaseOptions) {}
|
|
47
47
|
|
|
48
48
|
public get socketPath(): string {
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
// deterministic, so a second controller process attaches to the same
|
|
52
|
-
// engine, and independent of how deep the data directory is nested.
|
|
49
|
+
// The hashed name is deterministic so another AGL process can attach to
|
|
50
|
+
// the same engine without owning its storage files.
|
|
53
51
|
return embeddedDatabaseSocketPath(this.options.dataDirectory);
|
|
54
52
|
}
|
|
55
53
|
|
|
@@ -74,6 +72,9 @@ export class EmbeddedControllerDatabase {
|
|
|
74
72
|
if (this.localDb || this.migrationRunner?.hasOwnedResources) {
|
|
75
73
|
throw new Error('Embedded database startup cleanup must complete before retrying.');
|
|
76
74
|
}
|
|
75
|
+
const socketDirectory = plugins.path.dirname(this.socketPath);
|
|
76
|
+
await plugins.fs.promises.mkdir(socketDirectory, { recursive: true, mode: 0o700 });
|
|
77
|
+
await plugins.fs.promises.chmod(socketDirectory, 0o700);
|
|
77
78
|
if (this.options.legacyDataDirectory) {
|
|
78
79
|
const migrationRunner = new EmbeddedDatabaseMigrationRunner({
|
|
79
80
|
sourceDirectory: this.options.legacyDataDirectory,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
|
+
import { resolveAGLHomePaths } from './classes.aglhome.js';
|
|
2
3
|
import {
|
|
3
4
|
assertCanonicalDirectory,
|
|
4
5
|
assertCanonicalFilesystemObject,
|
|
@@ -746,8 +747,8 @@ export class ControllerGitReversion {
|
|
|
746
747
|
this.validateLimits();
|
|
747
748
|
this.maximumPrivateTreeEntries = privateTreeTraversalLimit(this.limits);
|
|
748
749
|
this.rootDirectory = optionsArg.temporaryRoot ?? plugins.path.join(
|
|
749
|
-
|
|
750
|
-
|
|
750
|
+
resolveAGLHomePaths().gitReversion,
|
|
751
|
+
sha256(optionsArg.ownerId),
|
|
751
752
|
);
|
|
752
753
|
if (!plugins.path.isAbsolute(this.rootDirectory)) {
|
|
753
754
|
throw new Error('The Git reversion temporary root must be absolute.');
|