@tekmidian/pai 0.60.1 → 0.62.0
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/{async-CLvuY7b-.mjs → async-DNVWtQl2.mjs} +2 -2
- package/dist/{async-CLvuY7b-.mjs.map → async-DNVWtQl2.mjs.map} +1 -1
- package/dist/{chain-CGyAIHo4.mjs → chain-CuaDawK9.mjs} +4 -4
- package/dist/{chain-CGyAIHo4.mjs.map → chain-CuaDawK9.mjs.map} +1 -1
- package/dist/cli/index.mjs +13 -13
- package/dist/cli/program.mjs +13 -13
- package/dist/{context-handover-cache-BzM7Qudn.mjs → context-handover-cache-DFNnlWv2.mjs} +4 -4
- package/dist/{context-handover-cache-BzM7Qudn.mjs.map → context-handover-cache-DFNnlWv2.mjs.map} +1 -1
- package/dist/daemon/index.mjs +10 -10
- package/dist/{daemon-B_TodsIS.mjs → daemon-Bf7Eock4.mjs} +45 -24
- package/dist/{daemon-B_TodsIS.mjs.map → daemon-Bf7Eock4.mjs.map} +1 -1
- package/dist/daemon-bJi1gDkG.mjs +19 -0
- package/dist/daemon-mcp/index.mjs +8 -10
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/{factory-EUUhSSoq.mjs → factory-BozZa81q.mjs} +3 -3
- package/dist/{factory-EUUhSSoq.mjs.map → factory-BozZa81q.mjs.map} +1 -1
- package/dist/{factory-DW7BCJJT.mjs → factory-UO9_DFMN.mjs} +1 -1
- package/dist/{fallback-CjdakQVu.mjs → fallback-F0TWGVM2.mjs} +11 -13
- package/dist/{fallback-CjdakQVu.mjs.map → fallback-F0TWGVM2.mjs.map} +1 -1
- package/dist/{helpers-D9WkIf9R.mjs → helpers-Dj-B314s.mjs} +3 -2
- package/dist/{helpers-D9WkIf9R.mjs.map → helpers-Dj-B314s.mjs.map} +1 -1
- package/dist/hooks/block-sleep-poll.mjs.map +2 -2
- package/dist/hooks/context-compression-hook.mjs.map +1 -1
- package/dist/hooks/load-project-context.mjs +8513 -133
- package/dist/hooks/load-project-context.mjs.map +4 -4
- package/dist/hooks/post-compact-inject.mjs.map +1 -1
- package/dist/hooks/route-agents-to-worker.mjs +3 -3
- package/dist/hooks/route-agents-to-worker.mjs.map +2 -2
- package/dist/hooks/security-validator.mjs +58 -58
- package/dist/hooks/security-validator.mjs.map +3 -3
- package/dist/hooks/stop-hook.mjs +15 -15
- package/dist/hooks/stop-hook.mjs.map +3 -3
- package/dist/hooks/update-tab-on-action.mjs +14 -12
- package/dist/hooks/update-tab-on-action.mjs.map +3 -3
- package/dist/hooks/update-tab-titles.mjs +13 -9
- package/dist/hooks/update-tab-titles.mjs.map +3 -3
- package/dist/hooks/worker-guard.mjs +7859 -0
- package/dist/hooks/worker-guard.mjs.map +7 -0
- package/dist/hooks/worker-proxy.mjs +3 -3
- package/dist/hooks/worker-proxy.mjs.map +2 -2
- package/dist/hooks/worker-status-line.mjs +104 -11
- package/dist/hooks/worker-status-line.mjs.map +4 -4
- package/dist/hooks/worker-supervision.mjs +3 -3
- package/dist/hooks/worker-supervision.mjs.map +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{indexer-backend-DcDtin1O.mjs → indexer-backend-BN9rpp9O.mjs} +2 -2
- package/dist/{main-resolver-BFQfU5xo.mjs → main-resolver-BIft_FVF.mjs} +4 -4
- package/dist/{main-resolver-BFQfU5xo.mjs.map → main-resolver-BIft_FVF.mjs.map} +1 -1
- package/dist/{main-resolver-VMBENifT.mjs → main-resolver-C9-poMdi.mjs} +2 -2
- package/dist/{planner-DN967Lvm.mjs → planner-BG9ivPj0.mjs} +6 -6
- package/dist/{planner-DN967Lvm.mjs.map → planner-BG9ivPj0.mjs.map} +1 -1
- package/dist/{postgres-nvU5pShF.mjs → postgres-CxD6_Dca.mjs} +3 -3
- package/dist/{postgres-nvU5pShF.mjs.map → postgres-CxD6_Dca.mjs.map} +1 -1
- package/dist/{program-BnsjB57Q.mjs → program-BRvCzhjx.mjs} +249 -82
- package/dist/program-BRvCzhjx.mjs.map +1 -0
- package/dist/{run-FeM1_UVa.mjs → run-BVQZI79D.mjs} +610 -253
- package/dist/run-BVQZI79D.mjs.map +1 -0
- package/dist/{run-env-CEHTeIUM.mjs → run-env-BE5xyCwy.mjs} +25 -6
- package/dist/run-env-BE5xyCwy.mjs.map +1 -0
- package/dist/{server-CekGOJcp.mjs → server-BY6AedmC.mjs} +2 -2
- package/dist/{server-CekGOJcp.mjs.map → server-BY6AedmC.mjs.map} +1 -1
- package/dist/{session-keepalive-Bc9aT678.mjs → session-keepalive-DJA97K2X.mjs} +4 -4
- package/dist/{session-keepalive-Bc9aT678.mjs.map → session-keepalive-DJA97K2X.mjs.map} +1 -1
- package/dist/{sqlite-D9p5a4qe.mjs → sqlite-CfKfuggn.mjs} +2 -2
- package/dist/{sqlite-D9p5a4qe.mjs.map → sqlite-CfKfuggn.mjs.map} +1 -1
- package/dist/{tools-r-7ZG8B5.mjs → tools-B52IvaU6.mjs} +3 -3
- package/dist/{tools-qXyHFwNj.mjs → tools-DFdPbX-X.mjs} +2 -2
- package/dist/{tools-qXyHFwNj.mjs.map → tools-DFdPbX-X.mjs.map} +1 -1
- package/dist/{vault-indexer-DHYBpRZ5.mjs → vault-indexer-mCFus_AM.mjs} +2 -2
- package/dist/{vault-indexer-DHYBpRZ5.mjs.map → vault-indexer-mCFus_AM.mjs.map} +1 -1
- package/dist/{wakeup-C48hcN6O.mjs → wakeup-DO1O4udw.mjs} +2 -2
- package/dist/{wakeup-C48hcN6O.mjs.map → wakeup-DO1O4udw.mjs.map} +1 -1
- package/dist/{work-queue-worker-BL4dq5P7.mjs → work-queue-worker-BbrC3I_R.mjs} +2 -2
- package/dist/{work-queue-worker-BL4dq5P7.mjs.map → work-queue-worker-BbrC3I_R.mjs.map} +1 -1
- package/dist/work-queue-worker-z-AATZ2t.mjs +11 -0
- package/docs/commands/README.md +2 -0
- package/docs/commands/worker.md +28 -0
- package/package.json +2 -2
- package/scripts/build-hooks.mjs +6 -5
- package/scripts/build-skill-stubs.mjs +6 -5
- package/src/hooks/ts/lib/tab-title.ts +18 -0
- package/src/hooks/ts/lib/worker-guard.test.ts +188 -0
- package/src/hooks/ts/lib/worker-guard.ts +315 -0
- package/src/hooks/ts/post-tool-use/update-tab-on-action.ts +3 -20
- package/src/hooks/ts/pre-tool-use/worker-guard.ts +75 -0
- package/src/hooks/ts/session-start/load-project-context.ts +14 -0
- package/src/hooks/ts/stop/stop-hook.ts +4 -15
- package/src/hooks/ts/user-prompt/update-tab-titles.ts +2 -10
- package/dist/daemon-jviL3VVJ.mjs +0 -19
- package/dist/program-BnsjB57Q.mjs.map +0 -1
- package/dist/run-FeM1_UVa.mjs.map +0 -1
- package/dist/run-env-CEHTeIUM.mjs.map +0 -1
- package/dist/work-queue-worker-DVOVcEnO.mjs +0 -11
|
@@ -3,27 +3,27 @@ import { a as slugify$1, i as parseSessionFilename } from "./migrate-BD7D8EEh.mj
|
|
|
3
3
|
import { n as ensurePaiMarker } from "./pai-marker-D1MMswkz.mjs";
|
|
4
4
|
import { t as STOP_WORDS } from "./stop-words-ClCwO8mZ.mjs";
|
|
5
5
|
import { t as applyRecencyBoost } from "./search-BaTbyWjK.mjs";
|
|
6
|
-
import { a as getStorageBackend, i as getRegistryBackend, r as createStorageBackend, s as humanDuration } from "./factory-
|
|
7
|
-
import { a as formatDetectionJson, i as formatDetection, n as migrateIdentityFile, r as detectProject } from "./wakeup-
|
|
8
|
-
import { B as claudeProjectsDir, C as findLatestNote, H as scanTranscriptFolders, I as resolveHome, L as saveScanConfig, M as cmdScan, N as loadScanConfig, P as migrateScanConfig, R as upsertProject, S as applyContinue, T as readBodyFile, U as transcriptFiles, V as findMovedProjects, d as migrateWorkQueue, g as migrateSummaryCooldowns, t as readContextHandoverCache, v as extractAndStoreTriples, w as findNotesDir$1, x as appendCheckpointToNote, z as upsertSession } from "./context-handover-cache-
|
|
6
|
+
import { a as getStorageBackend, i as getRegistryBackend, r as createStorageBackend, s as humanDuration } from "./factory-BozZa81q.mjs";
|
|
7
|
+
import { a as formatDetectionJson, i as formatDetection, n as migrateIdentityFile, r as detectProject } from "./wakeup-DO1O4udw.mjs";
|
|
8
|
+
import { B as claudeProjectsDir, C as findLatestNote, H as scanTranscriptFolders, I as resolveHome, L as saveScanConfig, M as cmdScan, N as loadScanConfig, P as migrateScanConfig, R as upsertProject, S as applyContinue, T as readBodyFile, U as transcriptFiles, V as findMovedProjects, d as migrateWorkQueue, g as migrateSummaryCooldowns, t as readContextHandoverCache, v as extractAndStoreTriples, w as findNotesDir$1, x as appendCheckpointToNote, z as upsertSession } from "./context-handover-cache-DFNnlWv2.mjs";
|
|
9
9
|
import { a as paiHomePath, i as paiHomeDir, n as migratePaiDir, o as resolvePaiFile, r as migratePaiFile, t as PaiFileMigrationError } from "./pai-home-CeOIYltV.mjs";
|
|
10
10
|
import { b as OWNER_LABEL_PREFIX, c as migrateConfigFile, d as readMainConfigRaw, f as writeMainConfigRaw, h as resolvedMainConfigPath, l as paiConfigFilePath, m as migrateMainConfigToYaml, n as CONFIG_FILE$2, o as expandHome, p as MainConfigError, s as loadConfig, t as CONFIG_DIR, u as paiConfigYamlFilePath, v as readJsonStrict, x as UNROUTED, y as writeJsonAtomic } from "./config-CQCmH_gV.mjs";
|
|
11
11
|
import { a as schedulerLogPath, i as paiSocketPath, n as daemonLogPath, r as daemonPidPath } from "./runtime-paths-BRwDeBEg.mjs";
|
|
12
|
-
import {
|
|
13
|
-
import { A as
|
|
12
|
+
import { B as contextWindowFromModelId, C as nativeAnthropicProvider, E as readWorkersSection, F as parseWorkersYamlDocument, I as relocateWorkersYaml, L as workersYamlLegacyNotice, M as inlineWorkersYamlKeys, N as migrateWorkersToYaml, P as needsWorkersYamlRelocation, R as workersYamlPath, S as maskKey, V as stripModelVariant, b as isModelCapability, f as PROVIDER_TAGS, j as initWorkersYaml, m as WorkersConfigError, r as ANTHROPIC_NATIVE, t as buildRunEnv, u as MODEL_CAPABILITIES, v as expandHome$1, y as getProviderOrNative, z as DEFAULT_CONTEXT_WINDOW } from "./run-env-BE5xyCwy.mjs";
|
|
13
|
+
import { A as appendLedger, B as loadStatus, D as mergeWorker, E as git, G as saveStatus, J as longInlinePromptHint, K as setWorkerLabel, M as UNLABELED, O as uncommittedPaths, Q as expandMcpNames, R as isChatPane, T as gcWorktrees, V as loadStatuses, W as ownsPid, Y as parseRunnerArgs, Z as describeMcp, a as projectLaunchConfig, c as handoffFromInside, f as checkPaneForWorker, g as markControlsHeld, h as clickrControlsArgv, i as usageContextTokens, m as openPaneForWorker, n as runWorker, o as parseWorkerReport, p as openFollowPane, q as waitForTerminalStatus, r as testProvider, u as sayToWorker, w as discardWorker, z as isLive } from "./run-BVQZI79D.mjs";
|
|
14
14
|
import { t as MergeError } from "./merge-xoyfZQ4W.mjs";
|
|
15
15
|
import { n as oldFederationPath, t as federationDbPath } from "./federation-db-w8e-sKjp.mjs";
|
|
16
16
|
import { r as registryDbPath, t as oldRegistryPath } from "./registry-db-Bkpbp7Gf.mjs";
|
|
17
|
-
import { i as indexProjectWithBackend } from "./async-
|
|
17
|
+
import { i as indexProjectWithBackend } from "./async-DNVWtQl2.mjs";
|
|
18
18
|
import { t as PaiClient } from "./ipc-client-Dasm515c.mjs";
|
|
19
|
-
import { A as getConfigValueOp, C as psOutput, D as resolveSpecPath, E as readSpecPrompt, M as setConfigValueOp, N as unsetConfigValueOp, O as MainConfigOpsError, S as followWorkers, T as statusLineOutput, _ as setWorkersEnabled, a as addProvider, b as updateProvider, c as describeModels, d as removeProvider, f as resolveProviderName, g as setProviderModel, h as setProviderEnabled, i as fallbackStatusText, j as listConfigOp, k as formatConfigGetOutput, l as describeProviders, m as setClass, n as fallbackOn, o as classTargetText, p as setCapabilityPreference, r as fallbackStatus, s as describeCapabilities, t as fallbackOff, u as modelPrefsText, v as unsetCapabilityPreference, w as replayOutput, x as useProvider, y as unsetClass } from "./fallback-
|
|
20
|
-
import { _ as resolveSessionByNameOrId, a as buildDeduped, c as hasConversation, d as providerResumePlan, f as restoreTopLevel, g as migrateSessionScanCache, h as fmtAge, l as launchInDir, m as printExitDir, o as normalizeName$2, p as resumeArgvText, s as renderDedupedSessions, t as cmdMain, u as launchPrompt, v as scanCacheFilePath, y as scanSessions } from "./main-resolver-
|
|
19
|
+
import { A as getConfigValueOp, C as psOutput, D as resolveSpecPath, E as readSpecPrompt, M as setConfigValueOp, N as unsetConfigValueOp, O as MainConfigOpsError, S as followWorkers, T as statusLineOutput, _ as setWorkersEnabled, a as addProvider, b as updateProvider, c as describeModels, d as removeProvider, f as resolveProviderName, g as setProviderModel, h as setProviderEnabled, i as fallbackStatusText, j as listConfigOp, k as formatConfigGetOutput, l as describeProviders, m as setClass, n as fallbackOn, o as classTargetText, p as setCapabilityPreference, r as fallbackStatus, s as describeCapabilities, t as fallbackOff, u as modelPrefsText, v as unsetCapabilityPreference, w as replayOutput, x as useProvider, y as unsetClass } from "./fallback-F0TWGVM2.mjs";
|
|
20
|
+
import { _ as resolveSessionByNameOrId, a as buildDeduped, c as hasConversation, d as providerResumePlan, f as restoreTopLevel, g as migrateSessionScanCache, h as fmtAge$1, l as launchInDir, m as printExitDir, o as normalizeName$2, p as resumeArgvText, s as renderDedupedSessions, t as cmdMain, u as launchPrompt, v as scanCacheFilePath, y as scanSessions } from "./main-resolver-BIft_FVF.mjs";
|
|
21
21
|
import { n as queriesDirPath, t as migrateQueriesDir } from "./query-feedback-xz5axTj3.mjs";
|
|
22
|
-
import { h as ledgerPath, m as eventsPath, n as ensureProxyRunning, p as ensureNoMcpConfig, r as stopProxy, t as DEFAULT_PROXY_PORT, v as workersLogDir } from "./server-
|
|
22
|
+
import { _ as statusPath, h as ledgerPath, m as eventsPath, n as ensureProxyRunning, p as ensureNoMcpConfig, r as stopProxy, t as DEFAULT_PROXY_PORT, v as workersLogDir } from "./server-BY6AedmC.mjs";
|
|
23
23
|
import { i as sendToSession, n as fetchLiveSessions, r as revealItermSession, t as callAiBroker } from "./aibroker-client-BK1h--W_.mjs";
|
|
24
|
-
import { a as totalUsageTokens, i as parseSessionUsage, r as sessionKeepaliveLedgerSummary, t as loadSessionKeepaliveState } from "./session-keepalive-
|
|
25
|
-
import { t as runChain } from "./chain-
|
|
26
|
-
import { appendFileSync, chmodSync, copyFileSync, cpSync, createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
24
|
+
import { a as totalUsageTokens, i as parseSessionUsage, r as sessionKeepaliveLedgerSummary, t as loadSessionKeepaliveState } from "./session-keepalive-DJA97K2X.mjs";
|
|
25
|
+
import { t as runChain } from "./chain-CuaDawK9.mjs";
|
|
26
|
+
import { appendFileSync, chmodSync, closeSync, copyFileSync, cpSync, createReadStream, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
27
27
|
import { homedir, platform, tmpdir, userInfo } from "node:os";
|
|
28
28
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
29
29
|
import chalk from "chalk";
|
|
@@ -161,7 +161,7 @@ async function cmdPromote(opts) {
|
|
|
161
161
|
console.error(dim$1(` Pick a durable location for the new project.`));
|
|
162
162
|
process.exit(1);
|
|
163
163
|
}
|
|
164
|
-
const { getRegistryBackend } = await import("./factory-
|
|
164
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
165
165
|
const registryBackend = await getRegistryBackend();
|
|
166
166
|
const encodedDir = encodeDir(targetPath);
|
|
167
167
|
if (await registryBackend.getProjectBySlug(slug) ?? await registryBackend.getProjectByRootPath(targetPath) ?? await registryBackend.getProjectByEncodedDir(encodedDir)) {
|
|
@@ -2035,7 +2035,7 @@ async function cmdUnregister(slug, opts = {}) {
|
|
|
2035
2035
|
//#region src/cli/commands/project/projects-index.ts
|
|
2036
2036
|
function registerProjectsCommands(projectsCmd) {
|
|
2037
2037
|
projectsCmd.command("list", { isDefault: true }).description("Show the unified deduped listing (same as `pai`).\nUse --all to include cold / zero-session / archived projects.").option("--all", "Show all entries including cold / zero-session / archived projects").option("-n, --n <count>", "Max rows to show", "20").action(async (opts) => {
|
|
2038
|
-
const { cmdMain } = await import("./main-resolver-
|
|
2038
|
+
const { cmdMain } = await import("./main-resolver-C9-poMdi.mjs");
|
|
2039
2039
|
await cmdMain(void 0, void 0, opts);
|
|
2040
2040
|
});
|
|
2041
2041
|
projectsCmd.command("list-raw").description("Raw registry listing with slug, path, status, last_active columns").option("--all", "Include archived projects (default: active only)").option("--status <status>", "Filter by status: active | archived").option("--tag <tag>", "Filter by tag").option("--type <type>", "Filter by type").action(async (opts) => {
|
|
@@ -2630,13 +2630,13 @@ function migrateFederationDbOrphan(dryRun) {
|
|
|
2630
2630
|
if (existsSync(oldPath) && !dryRun) {
|
|
2631
2631
|
let heldOpen = false;
|
|
2632
2632
|
try {
|
|
2633
|
-
|
|
2633
|
+
execFileSync("lsof", [oldPath], { stdio: "pipe" });
|
|
2634
2634
|
heldOpen = true;
|
|
2635
2635
|
} catch {}
|
|
2636
2636
|
if (heldOpen) {
|
|
2637
2637
|
console.log(" federation database (orphan): held open by the daemon — restarting it first");
|
|
2638
|
-
|
|
2639
|
-
|
|
2638
|
+
execFileSync("pai", ["daemon", "restart"], { stdio: "inherit" });
|
|
2639
|
+
execFileSync("sleep", ["2"]);
|
|
2640
2640
|
}
|
|
2641
2641
|
}
|
|
2642
2642
|
return migrateOrphanFederationDb({ dryRun });
|
|
@@ -2644,12 +2644,12 @@ function migrateFederationDbOrphan(dryRun) {
|
|
|
2644
2644
|
function checkpointAndVerify(oldPath, newPath, label) {
|
|
2645
2645
|
let hasSqlite3 = true;
|
|
2646
2646
|
try {
|
|
2647
|
-
|
|
2647
|
+
execFileSync("which", ["sqlite3"], { stdio: "pipe" });
|
|
2648
2648
|
} catch {
|
|
2649
2649
|
hasSqlite3 = false;
|
|
2650
2650
|
}
|
|
2651
2651
|
if (hasSqlite3) try {
|
|
2652
|
-
|
|
2652
|
+
execFileSync("sqlite3", [oldPath, "PRAGMA wal_checkpoint(TRUNCATE);"], { stdio: "pipe" });
|
|
2653
2653
|
} catch {}
|
|
2654
2654
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10).replace(/-/g, "");
|
|
2655
2655
|
for (const suffix of ["-wal", "-shm"]) {
|
|
@@ -2659,7 +2659,7 @@ function checkpointAndVerify(oldPath, newPath, label) {
|
|
|
2659
2659
|
} catch {}
|
|
2660
2660
|
}
|
|
2661
2661
|
if (hasSqlite3) try {
|
|
2662
|
-
const check =
|
|
2662
|
+
const check = execFileSync("sqlite3", [newPath, "PRAGMA integrity_check;"], { stdio: "pipe" }).toString().trim();
|
|
2663
2663
|
if (check !== "ok") throw new PaiFileMigrationError(`${newPath}: PRAGMA integrity_check reported "${check}" — investigate before trusting this copy`);
|
|
2664
2664
|
} catch (e) {
|
|
2665
2665
|
if (e instanceof PaiFileMigrationError) throw e;
|
|
@@ -2682,13 +2682,13 @@ function migrateRegistryDbFile(dryRun) {
|
|
|
2682
2682
|
if (!existsSync(oldPath) || dryRun) return migratePaiFile(newPath, [oldPath], { dryRun });
|
|
2683
2683
|
let heldOpen = false;
|
|
2684
2684
|
try {
|
|
2685
|
-
|
|
2685
|
+
execFileSync("lsof", [oldPath], { stdio: "pipe" });
|
|
2686
2686
|
heldOpen = true;
|
|
2687
2687
|
} catch {}
|
|
2688
2688
|
if (heldOpen) {
|
|
2689
2689
|
console.log(" registry database: held open by the daemon — restarting it first");
|
|
2690
|
-
|
|
2691
|
-
|
|
2690
|
+
execFileSync("pai", ["daemon", "restart"], { stdio: "inherit" });
|
|
2691
|
+
execFileSync("sleep", ["2"]);
|
|
2692
2692
|
}
|
|
2693
2693
|
const result = migratePaiFile(newPath, [oldPath], { dryRun: false });
|
|
2694
2694
|
if (result.fromPath) checkpointAndVerify(oldPath, newPath, "registry database");
|
|
@@ -2711,13 +2711,13 @@ function migrateFederationDbFile(dryRun) {
|
|
|
2711
2711
|
if (!existsSync(oldPath) || dryRun) return migratePaiFile(newPath, [oldPath], { dryRun });
|
|
2712
2712
|
let heldOpen = false;
|
|
2713
2713
|
try {
|
|
2714
|
-
|
|
2714
|
+
execFileSync("lsof", [oldPath], { stdio: "pipe" });
|
|
2715
2715
|
heldOpen = true;
|
|
2716
2716
|
} catch {}
|
|
2717
2717
|
if (heldOpen) {
|
|
2718
2718
|
console.log(" federation database (live): held open by the daemon — restarting it first");
|
|
2719
|
-
|
|
2720
|
-
|
|
2719
|
+
execFileSync("pai", ["daemon", "restart"], { stdio: "inherit" });
|
|
2720
|
+
execFileSync("sleep", ["2"]);
|
|
2721
2721
|
}
|
|
2722
2722
|
const result = migratePaiFile(newPath, [oldPath], { dryRun: false });
|
|
2723
2723
|
if (result.fromPath) checkpointAndVerify(oldPath, newPath, "federation database");
|
|
@@ -3247,7 +3247,7 @@ function registerStatsCommands(memoryCmd) {
|
|
|
3247
3247
|
//#region src/cli/commands/memory/sources-cmd.ts
|
|
3248
3248
|
function registerSourcesCommand(memoryCmd) {
|
|
3249
3249
|
memoryCmd.command("sources").description("Show what the indexer has taken in: composition by source, which roots\ncontent enters from, the heaviest single files, and how many chunks are\nrewritten per day (which distinguishes a finite backlog from a treadmill).").option("--limit <n>", "Rows per section (default 8)", "8").action(async (opts) => {
|
|
3250
|
-
const { createStorageBackend } = await import("./factory-
|
|
3250
|
+
const { createStorageBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
3251
3251
|
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
3252
3252
|
const { cmdMemorySources } = await import("./sources-BBe3AZ-W.mjs");
|
|
3253
3253
|
let backend;
|
|
@@ -4752,15 +4752,29 @@ function registerBackupCommands(program) {
|
|
|
4752
4752
|
const sqlDest = join(backupDir, "postgres-pai.sql");
|
|
4753
4753
|
console.log(dim$1(` Running pg_dump on ${DOCKER_CONTAINER$1} (this may take a moment)...`));
|
|
4754
4754
|
try {
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4755
|
+
execFileSync("docker", [
|
|
4756
|
+
"inspect",
|
|
4757
|
+
DOCKER_CONTAINER$1,
|
|
4758
|
+
"--format={{.State.Status}}"
|
|
4759
|
+
], { stdio: "pipe" });
|
|
4760
|
+
const sqlFd = openSync(sqlDest, "w");
|
|
4761
|
+
try {
|
|
4762
|
+
const dump = spawnSync("docker", [
|
|
4763
|
+
"exec",
|
|
4764
|
+
DOCKER_CONTAINER$1,
|
|
4765
|
+
"pg_dump",
|
|
4766
|
+
"-U",
|
|
4767
|
+
PG_USER$1,
|
|
4768
|
+
PG_DATABASE$1
|
|
4769
|
+
], { stdio: [
|
|
4759
4770
|
"pipe",
|
|
4771
|
+
sqlFd,
|
|
4760
4772
|
"pipe"
|
|
4761
|
-
]
|
|
4762
|
-
|
|
4763
|
-
}
|
|
4773
|
+
] });
|
|
4774
|
+
if (dump.status !== 0) throw new Error(dump.stderr?.toString().trim() || `pg_dump exited with code ${dump.status}`);
|
|
4775
|
+
} finally {
|
|
4776
|
+
closeSync(sqlFd);
|
|
4777
|
+
}
|
|
4764
4778
|
results.push({
|
|
4765
4779
|
label: "Postgres DB",
|
|
4766
4780
|
path: sqlDest,
|
|
@@ -5650,7 +5664,7 @@ function cmdOpen(opts) {
|
|
|
5650
5664
|
const url = `obsidian://open?vault=${encodeURIComponent(vaultName)}`;
|
|
5651
5665
|
console.log(dim$1(` Opening: ${url}`));
|
|
5652
5666
|
try {
|
|
5653
|
-
|
|
5667
|
+
execFileSync("open", [url], { stdio: "ignore" });
|
|
5654
5668
|
console.log(ok$1(` Opened vault "${vaultName}" in Obsidian.`));
|
|
5655
5669
|
} catch (e) {
|
|
5656
5670
|
console.error(err(` Failed to open Obsidian: ${e}`));
|
|
@@ -7038,10 +7052,19 @@ function cmdLogs(opts) {
|
|
|
7038
7052
|
return;
|
|
7039
7053
|
}
|
|
7040
7054
|
if (opts.follow) try {
|
|
7041
|
-
|
|
7055
|
+
execFileSync("tail", [
|
|
7056
|
+
"-f",
|
|
7057
|
+
"-n",
|
|
7058
|
+
lines,
|
|
7059
|
+
DAEMON_LOG
|
|
7060
|
+
], { stdio: "inherit" });
|
|
7042
7061
|
} catch {}
|
|
7043
7062
|
else try {
|
|
7044
|
-
|
|
7063
|
+
execFileSync("tail", [
|
|
7064
|
+
"-n",
|
|
7065
|
+
lines,
|
|
7066
|
+
DAEMON_LOG
|
|
7067
|
+
], { stdio: "inherit" });
|
|
7045
7068
|
} catch (e) {
|
|
7046
7069
|
const msg = e instanceof Error ? e.message : String(e);
|
|
7047
7070
|
console.error(err(`Could not read log: ${msg}`));
|
|
@@ -7050,7 +7073,7 @@ function cmdLogs(opts) {
|
|
|
7050
7073
|
}
|
|
7051
7074
|
function registerDaemonCommands(daemonCmd) {
|
|
7052
7075
|
daemonCmd.command("serve").description("Start the PAI daemon in the foreground").action(async () => {
|
|
7053
|
-
const { serve } = await import("./daemon-
|
|
7076
|
+
const { serve } = await import("./daemon-bJi1gDkG.mjs");
|
|
7054
7077
|
const { loadConfig: lc, ensureConfigDir } = await import("./config-DjXq_W42.mjs");
|
|
7055
7078
|
ensureConfigDir();
|
|
7056
7079
|
await serve(lc());
|
|
@@ -7228,11 +7251,20 @@ function registerRestoreCommands(program) {
|
|
|
7228
7251
|
if (hasSql && opts.postgres) {
|
|
7229
7252
|
console.log(dim$1(" Restoring Postgres database (this may take a while)..."));
|
|
7230
7253
|
try {
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
});
|
|
7254
|
+
execFileSync("docker", [
|
|
7255
|
+
"inspect",
|
|
7256
|
+
DOCKER_CONTAINER,
|
|
7257
|
+
"--format={{.State.Status}}"
|
|
7258
|
+
], { stdio: "pipe" });
|
|
7259
|
+
execFileSync("docker", [
|
|
7260
|
+
"exec",
|
|
7261
|
+
DOCKER_CONTAINER,
|
|
7262
|
+
"psql",
|
|
7263
|
+
"-U",
|
|
7264
|
+
PG_USER,
|
|
7265
|
+
"-c",
|
|
7266
|
+
`DROP DATABASE IF EXISTS ${PG_DATABASE}; CREATE DATABASE ${PG_DATABASE} OWNER ${PG_USER};`
|
|
7267
|
+
], { stdio: "pipe" });
|
|
7236
7268
|
const sqlContent = readFileSync(join(resolvedDir, "postgres-pai.sql"), "utf8");
|
|
7237
7269
|
const psqlResult = spawnSync("docker", [
|
|
7238
7270
|
"exec",
|
|
@@ -8376,6 +8408,11 @@ async function stepSettings(rl, daName) {
|
|
|
8376
8408
|
matcher: "Bash",
|
|
8377
8409
|
command: "${ADAPTER_DIR}/Hooks/security-validator.mjs"
|
|
8378
8410
|
},
|
|
8411
|
+
{
|
|
8412
|
+
hookType: "PreToolUse",
|
|
8413
|
+
matcher: "Bash|Edit|Write|MultiEdit|NotebookEdit",
|
|
8414
|
+
command: "${ADAPTER_DIR}/Hooks/worker-guard.mjs"
|
|
8415
|
+
},
|
|
8379
8416
|
{
|
|
8380
8417
|
hookType: "PreToolUse",
|
|
8381
8418
|
matcher: "*",
|
|
@@ -9304,7 +9341,7 @@ async function stepTaskBus(rl) {
|
|
|
9304
9341
|
if (await promptYesNo(rl, "Found TODOIST_API_KEY in the environment. Use it?", true)) apiKey = envToken;
|
|
9305
9342
|
}
|
|
9306
9343
|
while (!apiKey) {
|
|
9307
|
-
apiKey = (await prompt$1(rl, " Paste your Todoist API token: ")).trim();
|
|
9344
|
+
apiKey = (await prompt$1(rl, " Paste your Todoist API token here: ")).trim();
|
|
9308
9345
|
if (!apiKey) console.log(c.warn(" A token is required, or answer no to skip the task bus."));
|
|
9309
9346
|
}
|
|
9310
9347
|
line$1();
|
|
@@ -15574,20 +15611,32 @@ function pgDump(container, pgConfig, destPath) {
|
|
|
15574
15611
|
const database = resolvePgDatabaseName(pgConfig);
|
|
15575
15612
|
const user = pgConfig.user ?? "pai";
|
|
15576
15613
|
mkdirSync(dirname(destPath), { recursive: true });
|
|
15614
|
+
const fd = openSync(destPath, "w");
|
|
15577
15615
|
try {
|
|
15578
|
-
|
|
15579
|
-
|
|
15580
|
-
|
|
15581
|
-
|
|
15582
|
-
|
|
15583
|
-
|
|
15584
|
-
|
|
15585
|
-
|
|
15616
|
+
const dump = spawnSync("docker", [
|
|
15617
|
+
"exec",
|
|
15618
|
+
container,
|
|
15619
|
+
"pg_dump",
|
|
15620
|
+
"-U",
|
|
15621
|
+
user,
|
|
15622
|
+
"-Fc",
|
|
15623
|
+
database
|
|
15624
|
+
], { stdio: [
|
|
15625
|
+
"pipe",
|
|
15626
|
+
fd,
|
|
15627
|
+
"pipe"
|
|
15628
|
+
] });
|
|
15629
|
+
if (dump.status !== 0) return {
|
|
15630
|
+
ok: false,
|
|
15631
|
+
reason: `pg_dump failed: ${dump.stderr?.toString().trim() || `pg_dump exited with code ${dump.status}`}`
|
|
15632
|
+
};
|
|
15586
15633
|
} catch (e) {
|
|
15587
15634
|
return {
|
|
15588
15635
|
ok: false,
|
|
15589
15636
|
reason: `pg_dump failed: ${e instanceof Error ? e.message.split("\n")[0] : String(e)}`
|
|
15590
15637
|
};
|
|
15638
|
+
} finally {
|
|
15639
|
+
closeSync(fd);
|
|
15591
15640
|
}
|
|
15592
15641
|
if (!existsSync(destPath) || statSync(destPath).size === 0) return {
|
|
15593
15642
|
ok: false,
|
|
@@ -16042,7 +16091,7 @@ async function migrateToPostgres(opts = {}) {
|
|
|
16042
16091
|
const dump = pgDump(container, pgConfig, dumpPath);
|
|
16043
16092
|
if (!dump.ok) return refused(dump.reason, dryRun);
|
|
16044
16093
|
}
|
|
16045
|
-
const { PostgresBackend } = await import("./postgres-
|
|
16094
|
+
const { PostgresBackend } = await import("./postgres-CxD6_Dca.mjs");
|
|
16046
16095
|
await PostgresBackend.ensureDatabase(pgConfig);
|
|
16047
16096
|
const sqlite = new BetterSqlite3(sqliteFederationPath, { readonly: true });
|
|
16048
16097
|
const registrySqlite = sqliteRegistryPath === sqliteFederationPath ? sqlite : new BetterSqlite3(sqliteRegistryPath, { readonly: true });
|
|
@@ -16613,7 +16662,7 @@ async function getSessionTags(registryBackend, sessionId) {
|
|
|
16613
16662
|
* Session CRUD commands: list, info, rename, slug, tag, route, active, auto-route.
|
|
16614
16663
|
*/
|
|
16615
16664
|
async function cmdList(projectSlug, opts) {
|
|
16616
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16665
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
16617
16666
|
const registryBackend = await getRegistryBackend();
|
|
16618
16667
|
const limit = parseInt(opts.limit ?? "20", 10);
|
|
16619
16668
|
let project;
|
|
@@ -16678,7 +16727,7 @@ async function cmdList(projectSlug, opts) {
|
|
|
16678
16727
|
console.log(dim$1(` ${rows.length} session(s) shown (limit: ${limit})`));
|
|
16679
16728
|
}
|
|
16680
16729
|
async function cmdInfo(projectSlug, sessionNumber) {
|
|
16681
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16730
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
16682
16731
|
const registryBackend = await getRegistryBackend();
|
|
16683
16732
|
const project = await getProject$1(registryBackend, projectSlug);
|
|
16684
16733
|
if (!project) {
|
|
@@ -16702,7 +16751,7 @@ async function cmdInfo(projectSlug, sessionNumber) {
|
|
|
16702
16751
|
console.log();
|
|
16703
16752
|
}
|
|
16704
16753
|
async function cmdRename(projectSlug, numberOrLatest, newSlug) {
|
|
16705
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16754
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
16706
16755
|
await cmdRenameWith(await getRegistryBackend(), projectSlug, numberOrLatest, newSlug);
|
|
16707
16756
|
}
|
|
16708
16757
|
async function cmdRenameWith(registryBackend, projectSlug, numberOrLatest, newSlug) {
|
|
@@ -16765,7 +16814,7 @@ async function cmdRenameWith(registryBackend, projectSlug, numberOrLatest, newSl
|
|
|
16765
16814
|
console.log();
|
|
16766
16815
|
}
|
|
16767
16816
|
async function cmdSlug(projectSlug, numberOrLatest, opts) {
|
|
16768
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16817
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
16769
16818
|
const registryBackend = await getRegistryBackend();
|
|
16770
16819
|
const project = await getProject$1(registryBackend, projectSlug);
|
|
16771
16820
|
if (!project) {
|
|
@@ -16795,7 +16844,7 @@ async function cmdSlug(projectSlug, numberOrLatest, opts) {
|
|
|
16795
16844
|
}
|
|
16796
16845
|
}
|
|
16797
16846
|
async function cmdTag(projectSlug, sessionNumber, rawTags) {
|
|
16798
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16847
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
16799
16848
|
const registryBackend = await getRegistryBackend();
|
|
16800
16849
|
const project = await getProject$1(registryBackend, projectSlug);
|
|
16801
16850
|
if (!project) {
|
|
@@ -16835,7 +16884,7 @@ async function cmdTag(projectSlug, sessionNumber, rawTags) {
|
|
|
16835
16884
|
console.log();
|
|
16836
16885
|
}
|
|
16837
16886
|
async function cmdRoute(projectSlug, sessionNumber, targetProjectSlug, opts) {
|
|
16838
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16887
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
16839
16888
|
const registryBackend = await getRegistryBackend();
|
|
16840
16889
|
const project = await getProject$1(registryBackend, projectSlug);
|
|
16841
16890
|
if (!project) {
|
|
@@ -16877,7 +16926,7 @@ async function cmdRoute(projectSlug, sessionNumber, targetProjectSlug, opts) {
|
|
|
16877
16926
|
console.log();
|
|
16878
16927
|
}
|
|
16879
16928
|
async function cmdActive(opts) {
|
|
16880
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16929
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
16881
16930
|
const registryBackend = await getRegistryBackend();
|
|
16882
16931
|
const minutes = parseInt(opts.minutes ?? "60", 10);
|
|
16883
16932
|
const cutoff = Date.now() - minutes * 60 * 1e3;
|
|
@@ -16965,7 +17014,7 @@ async function cmdActive(opts) {
|
|
|
16965
17014
|
}
|
|
16966
17015
|
async function cmdAutoRoute(opts) {
|
|
16967
17016
|
const { autoRoute, formatAutoRouteJson } = await import("./auto-route-CF8WNaoy.mjs");
|
|
16968
|
-
const { getRegistryBackend, createStorageBackend } = await import("./factory-
|
|
17017
|
+
const { getRegistryBackend, createStorageBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
16969
17018
|
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
16970
17019
|
const config = loadConfig();
|
|
16971
17020
|
const registryBackend = await getRegistryBackend();
|
|
@@ -17202,7 +17251,7 @@ async function cmdPause(opts) {
|
|
|
17202
17251
|
process.exitCode = 1;
|
|
17203
17252
|
return;
|
|
17204
17253
|
}
|
|
17205
|
-
const { getRegistryBackend } = await import("./factory-
|
|
17254
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
17206
17255
|
const registryBackend = await getRegistryBackend();
|
|
17207
17256
|
const cwd = process.cwd();
|
|
17208
17257
|
const project = await resolveProjectByCwd(registryBackend, cwd);
|
|
@@ -17597,7 +17646,7 @@ function buildStopBody(project, sessionId) {
|
|
|
17597
17646
|
}
|
|
17598
17647
|
}
|
|
17599
17648
|
async function cmdHandover(projectSlug, numberOrLatest, sessionId) {
|
|
17600
|
-
const { getRegistryBackend } = await import("./factory-
|
|
17649
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
17601
17650
|
const registryBackend = await getRegistryBackend();
|
|
17602
17651
|
let project;
|
|
17603
17652
|
if (projectSlug) {
|
|
@@ -17893,7 +17942,7 @@ function touchSentinel(rootPath) {
|
|
|
17893
17942
|
async function cmdAutosave(opts) {
|
|
17894
17943
|
const minGap = parseInt(opts.minGap ?? String(DEFAULT_MIN_GAP), 10);
|
|
17895
17944
|
const cwd = process.cwd();
|
|
17896
|
-
const { getRegistryBackend } = await import("./factory-
|
|
17945
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
17897
17946
|
const registryBackend = await getRegistryBackend();
|
|
17898
17947
|
const project = await resolveProjectByCwd(registryBackend, cwd);
|
|
17899
17948
|
if (!project) return;
|
|
@@ -18018,7 +18067,7 @@ async function cmdRecent(opts) {
|
|
|
18018
18067
|
shortId: s.shortId,
|
|
18019
18068
|
resumable: s.resumable,
|
|
18020
18069
|
sessionStatus: s.sessionStatus,
|
|
18021
|
-
age: fmtAge(s.mtime),
|
|
18070
|
+
age: fmtAge$1(s.mtime),
|
|
18022
18071
|
mtime: s.mtime,
|
|
18023
18072
|
name: s.friendlyName,
|
|
18024
18073
|
lastUserPrompt: s.lastUserPrompt,
|
|
@@ -18056,7 +18105,7 @@ async function cmdRecent(opts) {
|
|
|
18056
18105
|
return [
|
|
18057
18106
|
chalk.dim(String(idx + 1)),
|
|
18058
18107
|
chalk.cyan(s.shortId),
|
|
18059
|
-
dim$1(fmtAge(s.mtime)),
|
|
18108
|
+
dim$1(fmtAge$1(s.mtime)),
|
|
18060
18109
|
name.length > 26 ? name.slice(0, 25) + "…" : name,
|
|
18061
18110
|
prompt,
|
|
18062
18111
|
s.userLines > 0 ? String(s.userLines) : dim$1("—"),
|
|
@@ -18156,7 +18205,7 @@ async function cmdGoto(query, opts) {
|
|
|
18156
18205
|
console.log(` fallback: ${chalk.yellow(argvFresh)}`);
|
|
18157
18206
|
if (resumableSession) {
|
|
18158
18207
|
console.log(`\n uuid: ${resumableSession.uuid}`);
|
|
18159
|
-
console.log(` age: ${fmtAge(resumableSession.mtime)}`);
|
|
18208
|
+
console.log(` age: ${fmtAge$1(resumableSession.mtime)}`);
|
|
18160
18209
|
console.log(` status: ${resumableSession.sessionStatus}`);
|
|
18161
18210
|
console.log(` sys: ${resumableSession.topLevelSystemLines} system lines`);
|
|
18162
18211
|
}
|
|
@@ -18802,9 +18851,15 @@ function fail$3(e) {
|
|
|
18802
18851
|
process.exitCode = 1;
|
|
18803
18852
|
}
|
|
18804
18853
|
function registerWorkerModelCommand(workerCmd) {
|
|
18805
|
-
workerCmd.command("model [what] [model]").description("Model ids per provider: no args lists them,\n`model <model-id>` sets the active provider's default model (back-compat),\n`model <capability>` shows one capability, `model <capability> <model-id>` sets it.\nCapability names are open (default, fast, image, … — any ^[a-z][a-z0-9-]*$ name);\n`pai worker capability` picks which provider serves one across the whole config.\n--provider targets another provider.").option("--provider <name>", "Provider to read or change (default: the active one)").action((what, model, opts) => {
|
|
18854
|
+
workerCmd.command("model [what] [model]").description("Model ids per provider: no args lists them,\n`model <model-id>` sets the active provider's default model (back-compat),\n`model <capability>` shows one capability, `model <capability> <model-id>` sets it.\nCapability names are open (default, fast, image, … — any ^[a-z][a-z0-9-]*$ name);\n`pai worker capability` picks which provider serves one across the whole config.\n--provider targets another provider.").option("--provider <name>", "Provider to read or change (default: the active one)").option("--capability <name>", "Capability to set/show, with a model id as the only argument (same as the MCP tool)").action((what, model, opts) => {
|
|
18806
18855
|
try {
|
|
18807
18856
|
const { workers } = readWorkersSection();
|
|
18857
|
+
if (opts.capability !== void 0) {
|
|
18858
|
+
if (!isModelCapability(opts.capability)) throw new WorkersConfigError(`"${opts.capability}" is not a valid capability name`);
|
|
18859
|
+
if (model !== void 0) throw new WorkersConfigError("with --capability pass only a model id");
|
|
18860
|
+
model = what;
|
|
18861
|
+
what = opts.capability;
|
|
18862
|
+
}
|
|
18808
18863
|
if (what === void 0) {
|
|
18809
18864
|
for (const line of describeModels(workers)) console.log(` ${line}`);
|
|
18810
18865
|
return;
|
|
@@ -18815,14 +18870,14 @@ function registerWorkerModelCommand(workerCmd) {
|
|
|
18815
18870
|
capability = what;
|
|
18816
18871
|
if (model === void 0) {
|
|
18817
18872
|
const name = resolveProviderName(workers, opts.provider);
|
|
18818
|
-
const p = workers
|
|
18873
|
+
const p = getProviderOrNative(workers, name);
|
|
18819
18874
|
if (p) console.log(` ${name} ${capability} ${p.models[capability] ?? "(none)"}`);
|
|
18820
18875
|
return;
|
|
18821
18876
|
}
|
|
18822
18877
|
id = model;
|
|
18823
18878
|
} else if (model !== void 0) throw new WorkersConfigError(`unexpected second argument "${model}" — usage: model [<capability>] <model-id>`);
|
|
18824
18879
|
const name = resolveProviderName(workers, opts.provider);
|
|
18825
|
-
const p = setProviderModel(name, capability, id)
|
|
18880
|
+
const p = getProviderOrNative(setProviderModel(name, capability, id), name);
|
|
18826
18881
|
if (p) {
|
|
18827
18882
|
console.log(ok$1(`${name} ${capability} model: ${p.models[capability]}`));
|
|
18828
18883
|
console.log(dim$1(` ${modelPrefsText(p)}`));
|
|
@@ -18960,6 +19015,89 @@ function registerWorkerConfigCommands(workerCmd) {
|
|
|
18960
19015
|
});
|
|
18961
19016
|
}
|
|
18962
19017
|
|
|
19018
|
+
//#endregion
|
|
19019
|
+
//#region src/workers/pending.ts
|
|
19020
|
+
/**
|
|
19021
|
+
* Pending worker results: finished workers whose worktree branch still holds
|
|
19022
|
+
* work that never reached the repo (commits not in HEAD, or uncommitted
|
|
19023
|
+
* files). Surfaced by `pai worker ps/pending`, the SessionStart hook, the
|
|
19024
|
+
* status line and the prepublish gate so an unmerged fix cannot be forgotten.
|
|
19025
|
+
*/
|
|
19026
|
+
/** Stale after this long: `pai worker gc` (archive) instead of merge. */
|
|
19027
|
+
const STALE_HOURS = 24;
|
|
19028
|
+
function toplevel(dir) {
|
|
19029
|
+
try {
|
|
19030
|
+
return git(dir, ["rev-parse", "--show-toplevel"]);
|
|
19031
|
+
} catch {
|
|
19032
|
+
return null;
|
|
19033
|
+
}
|
|
19034
|
+
}
|
|
19035
|
+
function fmtAge(ms) {
|
|
19036
|
+
const h = Math.floor(ms / 36e5);
|
|
19037
|
+
return h >= 48 ? `${Math.floor(h / 24)}d` : h >= 1 ? `${h}h` : `${Math.floor(ms / 6e4)}m`;
|
|
19038
|
+
}
|
|
19039
|
+
/** Finished workers with unmerged work; `repoRoot` limits to one repo, else every repo. */
|
|
19040
|
+
function pendingResults(logDir, repoRoot, now = Date.now()) {
|
|
19041
|
+
const want = repoRoot ? toplevel(repoRoot) : null;
|
|
19042
|
+
if (repoRoot && !want) return [];
|
|
19043
|
+
const out = [];
|
|
19044
|
+
for (const st of loadStatuses(logDir)) {
|
|
19045
|
+
if (st.archived || st.merged || isLive(st)) continue;
|
|
19046
|
+
if (!st.worktreeDir || !existsSync(st.worktreeDir)) continue;
|
|
19047
|
+
const repo = toplevel(st.cwd);
|
|
19048
|
+
if (!repo || want && repo !== want) continue;
|
|
19049
|
+
let commits = 0;
|
|
19050
|
+
let dirty = 0;
|
|
19051
|
+
try {
|
|
19052
|
+
if (st.branch) commits = git(repo, [
|
|
19053
|
+
"cherry",
|
|
19054
|
+
"HEAD",
|
|
19055
|
+
`refs/heads/${st.branch}`
|
|
19056
|
+
]).split("\n").filter((l) => l.startsWith("+")).length;
|
|
19057
|
+
dirty = uncommittedPaths(st.worktreeDir).filter((p) => !/(^|\/)node_modules(\/|$)/.test(p)).length;
|
|
19058
|
+
} catch {
|
|
19059
|
+
continue;
|
|
19060
|
+
}
|
|
19061
|
+
if (!commits && !dirty) continue;
|
|
19062
|
+
let ageMs = 0;
|
|
19063
|
+
try {
|
|
19064
|
+
ageMs = Math.max(0, now - statSync(statusPath(logDir, st.id)).mtimeMs);
|
|
19065
|
+
} catch {}
|
|
19066
|
+
out.push({
|
|
19067
|
+
id: st.id,
|
|
19068
|
+
label: st.label,
|
|
19069
|
+
repo,
|
|
19070
|
+
ageMs,
|
|
19071
|
+
age: fmtAge(ageMs),
|
|
19072
|
+
commits,
|
|
19073
|
+
dirty
|
|
19074
|
+
});
|
|
19075
|
+
}
|
|
19076
|
+
return out;
|
|
19077
|
+
}
|
|
19078
|
+
/** One human line per result, with the exact next command. */
|
|
19079
|
+
function formatPending(results, showRepo = false) {
|
|
19080
|
+
return results.map((r) => {
|
|
19081
|
+
const next = r.ageMs > STALE_HOURS * 36e5 ? "pai worker gc" : `pai worker merge ${r.id}`;
|
|
19082
|
+
const repo = showRepo ? ` ${r.repo}` : "";
|
|
19083
|
+
return `${r.id} ${r.age} ${r.commits} commit(s), ${r.dirty} dirty ${r.label}${repo} -> ${next}`;
|
|
19084
|
+
}).join("\n");
|
|
19085
|
+
}
|
|
19086
|
+
/**
|
|
19087
|
+
* Release gate: exit code and message for `pai worker pending --gate`.
|
|
19088
|
+
* PAI_ALLOW_PENDING=1 overrides.
|
|
19089
|
+
*/
|
|
19090
|
+
function pendingGate(results, env = process.env) {
|
|
19091
|
+
if (!results.length || env.PAI_ALLOW_PENDING === "1") return {
|
|
19092
|
+
code: 0,
|
|
19093
|
+
message: ""
|
|
19094
|
+
};
|
|
19095
|
+
return {
|
|
19096
|
+
code: 1,
|
|
19097
|
+
message: `${results.length} unmerged worker result(s) in this repo — merge or discard before publishing:\n${formatPending(results)}\nOverride deliberately with PAI_ALLOW_PENDING=1.`
|
|
19098
|
+
};
|
|
19099
|
+
}
|
|
19100
|
+
|
|
18963
19101
|
//#endregion
|
|
18964
19102
|
//#region src/workers/wait.ts
|
|
18965
19103
|
/**
|
|
@@ -19141,7 +19279,24 @@ function registerWorkerCommands(workerCmd) {
|
|
|
19141
19279
|
});
|
|
19142
19280
|
workerCmd.command("ps").description("List workers of this session (RUNNING + FINISHED); --all for every worker").option("--all", "Show workers of all sessions, not just this terminal's").action((opts) => {
|
|
19143
19281
|
try {
|
|
19144
|
-
|
|
19282
|
+
const logDir = currentLogDir();
|
|
19283
|
+
const pending = pendingResults(logDir, process.cwd()).length;
|
|
19284
|
+
if (pending) console.log(`${pending} unmerged result(s) — pai worker pending`);
|
|
19285
|
+
console.log(psOutput(logDir, opts.all === true));
|
|
19286
|
+
} catch (e) {
|
|
19287
|
+
fail(e);
|
|
19288
|
+
}
|
|
19289
|
+
});
|
|
19290
|
+
workerCmd.command("pending").description("Finished workers whose branch or worktree holds work not yet merged into this repo").option("--all", "Every repo in the log dir, not just the current one").option("--json", "Machine-readable output").option("--gate", "Release gate: exit 1 with the list unless PAI_ALLOW_PENDING=1").action((opts) => {
|
|
19291
|
+
try {
|
|
19292
|
+
const res = pendingResults(currentLogDir(), opts.all ? void 0 : process.cwd());
|
|
19293
|
+
if (opts.gate) {
|
|
19294
|
+
const g = pendingGate(res);
|
|
19295
|
+
if (g.message) console.error(g.message);
|
|
19296
|
+
process.exit(g.code);
|
|
19297
|
+
}
|
|
19298
|
+
if (opts.json) console.log(JSON.stringify(res, null, 2));
|
|
19299
|
+
else console.log(res.length ? formatPending(res, opts.all === true) : "no pending worker results");
|
|
19145
19300
|
} catch (e) {
|
|
19146
19301
|
fail(e);
|
|
19147
19302
|
}
|
|
@@ -19179,7 +19334,7 @@ function registerWorkerCommands(workerCmd) {
|
|
|
19179
19334
|
const logDir = currentLogDir();
|
|
19180
19335
|
const term = process.env.ITERM_SESSION_ID ?? "";
|
|
19181
19336
|
if (id) {
|
|
19182
|
-
const msg = opts.check ? await checkPaneForWorker(id, workers.pane.fontSize, term) : await openPaneForWorker(logDir, workers, id, term);
|
|
19337
|
+
const msg = opts.check ? await checkPaneForWorker(id, workers.pane.fontSize, term) : (await openPaneForWorker(logDir, workers, id, term)).message;
|
|
19183
19338
|
console.log(msg);
|
|
19184
19339
|
} else console.log(await openFollowPane(logDir, workers, term, opts.check === true));
|
|
19185
19340
|
} catch (e) {
|
|
@@ -19290,6 +19445,18 @@ function registerWorkerCommands(workerCmd) {
|
|
|
19290
19445
|
fail(e);
|
|
19291
19446
|
}
|
|
19292
19447
|
});
|
|
19448
|
+
workerCmd.command("gc").description("Archive leftover worker worktrees (state kept under refs/pai-archive/<id>; gitignored files are not kept)").option("--older-than <hours>", "minimum age of a finished worker", "24").option("--dry-run", "print what would be archived, change nothing").action((opts) => {
|
|
19449
|
+
try {
|
|
19450
|
+
const hours = Number(opts.olderThan);
|
|
19451
|
+
if (!Number.isFinite(hours) || hours < 0) throw new Error(`bad --older-than "${opts.olderThan}"`);
|
|
19452
|
+
const res = gcWorktrees(currentLogDir(), hours, opts.dryRun === true);
|
|
19453
|
+
const verb = opts.dryRun ? "would archive" : "archived";
|
|
19454
|
+
for (const r of res) console.log(r.skipped ? `skipped ${r.id}: ${r.skipped}` : `${verb} ${r.id} -> ${r.archive}`);
|
|
19455
|
+
console.log(`${res.filter((r) => r.archive).length} ${opts.dryRun ? "would be archived" : "archived"}`);
|
|
19456
|
+
} catch (e) {
|
|
19457
|
+
fail(e);
|
|
19458
|
+
}
|
|
19459
|
+
});
|
|
19293
19460
|
workerCmd.command("kill <id>").description("Send SIGTERM to a running worker process").action(async (id) => {
|
|
19294
19461
|
try {
|
|
19295
19462
|
const logDir = currentLogDir();
|
|
@@ -20170,7 +20337,7 @@ async function countVectorDbPaths(oldPaths) {
|
|
|
20170
20337
|
if (oldPaths.length === 0) return 0;
|
|
20171
20338
|
try {
|
|
20172
20339
|
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
20173
|
-
const { createStorageBackend } = await import("./factory-
|
|
20340
|
+
const { createStorageBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
20174
20341
|
const config = loadConfig();
|
|
20175
20342
|
if (config.storageBackend !== "postgres") return 0;
|
|
20176
20343
|
const backend = await createStorageBackend(config);
|
|
@@ -20188,7 +20355,7 @@ async function updateVectorDbPaths(moves) {
|
|
|
20188
20355
|
if (moves.length === 0) return 0;
|
|
20189
20356
|
try {
|
|
20190
20357
|
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
20191
|
-
const { createStorageBackend } = await import("./factory-
|
|
20358
|
+
const { createStorageBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
20192
20359
|
const config = loadConfig();
|
|
20193
20360
|
if (config.storageBackend !== "postgres") return 0;
|
|
20194
20361
|
const backend = await createStorageBackend(config);
|
|
@@ -20275,7 +20442,7 @@ async function displayDryRun(plans) {
|
|
|
20275
20442
|
console.log();
|
|
20276
20443
|
}
|
|
20277
20444
|
async function executeCleanup(plans, skipReindex) {
|
|
20278
|
-
const { getRegistryBackend } = await import("./factory-
|
|
20445
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
20279
20446
|
const registryBackend = await getRegistryBackend();
|
|
20280
20447
|
let deleted = 0;
|
|
20281
20448
|
let renamed = 0;
|
|
@@ -20472,7 +20639,7 @@ async function executeCleanup(plans, skipReindex) {
|
|
|
20472
20639
|
//#region src/cli/commands/session-cleanup/index.ts
|
|
20473
20640
|
function registerSessionCleanupCommand(sessionCmd) {
|
|
20474
20641
|
sessionCmd.command("cleanup [project-slug]").description("Clean up session notes: delete empties, auto-name unnamed, move into YYYY/MM/ hierarchy, renumber").option("--execute", "Actually perform the cleanup (default is dry-run)").option("--no-renumber", "Skip renumbering sessions after deletions").option("--no-reindex", "Skip triggering memory re-index after moves").action(async (projectSlug, opts) => {
|
|
20475
|
-
const { getRegistryBackend } = await import("./factory-
|
|
20642
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
20476
20643
|
const registryBackend = await getRegistryBackend();
|
|
20477
20644
|
const dryRun = !opts.execute;
|
|
20478
20645
|
const skipReindex = opts.reindex === false;
|
|
@@ -20542,7 +20709,7 @@ function finalizeNote(notePath) {
|
|
|
20542
20709
|
}
|
|
20543
20710
|
async function cmdEnd(opts) {
|
|
20544
20711
|
await cmdPause(opts);
|
|
20545
|
-
const { getRegistryBackend } = await import("./factory-
|
|
20712
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
20546
20713
|
const registryBackend = await getRegistryBackend();
|
|
20547
20714
|
const cwd = process.cwd();
|
|
20548
20715
|
const project = await registryBackend.findProjectByCwdPrefix(cwd);
|
|
@@ -20990,7 +21157,7 @@ async function cmdFind(query, opts) {
|
|
|
20990
21157
|
*/
|
|
20991
21158
|
async function getProjects(includeArchived) {
|
|
20992
21159
|
try {
|
|
20993
|
-
const { getRegistryBackend } = await import("./factory-
|
|
21160
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
20994
21161
|
const rows = await (await getRegistryBackend()).listProjectsWithSessionStats();
|
|
20995
21162
|
return includeArchived ? rows : rows.filter((p) => p.status === "active");
|
|
20996
21163
|
} catch {
|
|
@@ -21131,7 +21298,7 @@ function buildFeedFrom(allSessions, projects, liveSessions, allProjects) {
|
|
|
21131
21298
|
const tag = tagFor(e.status);
|
|
21132
21299
|
const name = chalk.white(pad(e.name, 22));
|
|
21133
21300
|
const where = dir ? dim$1(shorten(dir, 40)) : chalk.green("(running in another tab)");
|
|
21134
|
-
const age = e.status === "live" ? chalk.green("now") : e.lastActivity > 0 ? dim$1(fmtAge(e.lastActivity)) : dim$1("—");
|
|
21301
|
+
const age = e.status === "live" ? chalk.green("now") : e.lastActivity > 0 ? dim$1(fmtAge$1(e.lastActivity)) : dim$1("—");
|
|
21135
21302
|
const kwDisp = kw ? dim$1(" " + kw) : "";
|
|
21136
21303
|
const display = `${tag} ${name} ${pad(age, 5)} ${where}${kwDisp}`;
|
|
21137
21304
|
const search = `${e.name} ${dir ?? ""} ${kw}`.toLowerCase();
|
|
@@ -21197,7 +21364,7 @@ function contextFor(rec) {
|
|
|
21197
21364
|
const notes = recentMarkdown(rec.dir, 4);
|
|
21198
21365
|
if (notes.length) {
|
|
21199
21366
|
lines.push(dim$1("recent notes:"));
|
|
21200
|
-
for (const n of notes) lines.push(" " + dim$1(n.rel.slice(0, 60)) + " " + dim$1(fmtAge(n.mtime)));
|
|
21367
|
+
for (const n of notes) lines.push(" " + dim$1(n.rel.slice(0, 60)) + " " + dim$1(fmtAge$1(n.mtime)));
|
|
21201
21368
|
} else lines.push(dim$1("(no notes here yet)"));
|
|
21202
21369
|
ctxCache.set(rec.dir, lines);
|
|
21203
21370
|
return lines;
|
|
@@ -21464,7 +21631,7 @@ async function cmdPick(opts = {}) {
|
|
|
21464
21631
|
const onRemove = async (rec) => {
|
|
21465
21632
|
if (!rec.slug) return false;
|
|
21466
21633
|
try {
|
|
21467
|
-
const { getRegistryBackend } = await import("./factory-
|
|
21634
|
+
const { getRegistryBackend } = await import("./factory-UO9_DFMN.mjs");
|
|
21468
21635
|
const registryBackend = await getRegistryBackend();
|
|
21469
21636
|
const project = await registryBackend.getProjectBySlug(rec.slug);
|
|
21470
21637
|
if (!project || project.status !== "active") return false;
|
|
@@ -21749,4 +21916,4 @@ claude() {
|
|
|
21749
21916
|
|
|
21750
21917
|
//#endregion
|
|
21751
21918
|
export { drainStdio as n, buildProgram as t };
|
|
21752
|
-
//# sourceMappingURL=program-
|
|
21919
|
+
//# sourceMappingURL=program-BRvCzhjx.mjs.map
|