@tekmidian/pai 1.0.0 → 1.0.3
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/.claude-plugin/plugin.json +1 -1
- package/README.md +67 -5
- package/dist/aibroker-client-BxzeEHPF.mjs +3 -0
- package/dist/{aibroker-client-CXEYBzbf.mjs → aibroker-client-CQPGqLxL.mjs} +1 -1
- package/dist/atomic-file-BorMa4T3.mjs +21 -0
- package/dist/{auto-route-D5SXrMpB.mjs → auto-route-B7Yu6Uam.mjs} +3 -3
- package/dist/auto-route-CjjQqU1o.mjs +11 -0
- package/dist/budget-Dod6rnA9.mjs +15 -0
- package/dist/{caller-identity-CVTuiLSs.mjs → caller-identity-yLFb7CKq.mjs} +6 -5
- package/dist/{capacity-DaXrVj3J.mjs → capacity-DEveQdFV.mjs} +3 -3
- package/dist/{chain-BcQlIlEd.mjs → chain-7n9Gx56r.mjs} +5 -5
- package/dist/cli/index.mjs +1628 -370
- package/dist/{cockpit-actions-ODmt8yF9.mjs → cockpit-actions-BBHeyEZI.mjs} +84 -42
- package/dist/cockpit-actions-DR9X514g.mjs +20 -0
- package/dist/cockpit-memory--dnShXBA.mjs +20 -0
- package/dist/{config-BSXKyeJ1.mjs → config-Bu1_vbY8.mjs} +42 -3
- package/dist/{config-B955yYmo.mjs → config-Cxi-aBf4.mjs} +2 -2
- package/dist/{config-TaWmdTLx.mjs → config-DtENJ6cL.mjs} +1 -1
- package/dist/{config-D5chi2LO.mjs → config-XpZWOYOG.mjs} +2 -2
- package/dist/{controls-BGkK_Bdi.mjs → controls-CPoeudou.mjs} +37 -22
- package/dist/daemon/index.mjs +43 -42
- package/dist/daemon-DKdBNKfa.mjs +45 -0
- package/dist/{daemon-CorGh6Ub.mjs → daemon-DPAo6WTa.mjs} +103 -55
- package/dist/daemon-mcp/index.mjs +40 -39
- package/dist/{define-DGFu-sCf.mjs → define-CjJsmq-6.mjs} +1 -1
- package/dist/{detect-C1d5cUkT.mjs → detect-9CZNO0yf.mjs} +2 -2
- package/dist/detect-D1ziFFfA.mjs +10 -0
- package/dist/{embed-pass-CeQD8kRE.mjs → embed-pass-DIWjA68P.mjs} +5 -5
- package/dist/{embedding-gate-BHuBsgHD.mjs → embedding-gate-6rZrWRXa.mjs} +5 -5
- package/dist/{embedding-gate-Z7CJSOJk.mjs → embedding-gate-Cnk4YCyX.mjs} +3 -3
- package/dist/{embeddings-D4t6L-EH.mjs → embeddings-BVq3esBF.mjs} +1 -1
- package/dist/{embeddings-OF9Pt4by.mjs → embeddings-CIkJBKd-.mjs} +1 -1
- package/dist/{endreason-x1KOSrcO.mjs → endreason-C577xIQz.mjs} +7 -6
- package/dist/{env-DArqGq-Z.mjs → env-BE8mrsxr.mjs} +1 -1
- package/dist/factory-Bsib-qDG.mjs +9 -0
- package/dist/{factory-BtjbQ0np.mjs → factory-DjAAsqr_.mjs} +15 -13
- package/dist/{fallback-BIyEpPsQ.mjs → fallback-DFlItw1Z.mjs} +5 -5
- package/dist/{fmt-age-BiSHrTKN.mjs → fmt-age-ByDkvkoU.mjs} +1 -1
- package/dist/{health-C6jZWvRG.mjs → health-Dnym-qcT.mjs} +4 -4
- package/dist/{helpers-DFmYRCOa.mjs → helpers-BD6V-p9w.mjs} +2 -2
- package/dist/helpers-CMGjy_0N.mjs +10 -0
- package/dist/{helpers-CJpb_MNB.mjs → helpers-CRuBUas3.mjs} +87 -38
- package/dist/hooks/capture-all-events.mjs +52 -11
- package/dist/hooks/capture-session-summary.mjs +64 -47
- package/dist/hooks/capture-tool-output.mjs +49 -8
- package/dist/hooks/context-compression-hook.mjs +30 -10
- package/dist/hooks/initialize-session.mjs +1 -0
- package/dist/hooks/load-core-context.mjs +1 -1
- package/dist/hooks/load-project-context.mjs +32 -29
- package/dist/hooks/security-validator.mjs +45 -13
- package/dist/hooks/stop-hook.mjs +54 -16
- package/dist/hooks/supervision-banner.mjs +9 -0
- package/dist/hooks/sync-todo-to-md.mjs +147 -113
- package/dist/hooks/worker-edit-repair.mjs +2 -1
- package/dist/hooks/worker-guard.mjs +40 -16
- package/dist/hooks/worker-note.mjs +12 -5
- package/dist/hooks/worker-path-repair.mjs +1 -1
- package/dist/hooks/worker-pool-host.mjs +329 -231
- package/dist/hooks/worker-status-line.mjs +195 -114
- package/dist/index.d.mts +18 -0
- package/dist/index.mjs +12 -12
- package/dist/{indexer-backend-BM2CUSu8.mjs → indexer-backend-Cll7le4P.mjs} +149 -96
- package/dist/{ipc-client-BMqWw_gv.mjs → ipc-client-CaiGJnSM.mjs} +1 -1
- package/dist/{ipc-client-YYDD6zzU.mjs → ipc-client-ZRmDKd5Z.mjs} +1 -1
- package/dist/kill-tree-BG7dRVtp.mjs +10 -0
- package/dist/{kill-tree-BjYz5BxK.mjs → kill-tree-EWYaEk5v.mjs} +8 -8
- package/dist/{launch-CLp0OJxV.mjs → launch-CXVlZjHt.mjs} +8 -8
- package/dist/{launch-DgqQdAjI.mjs → launch-Jh5NVeNe.mjs} +3 -3
- package/dist/local-candidate-DLdwQt0s.mjs +112 -0
- package/dist/local-instances-DOxSgT_L.mjs +210 -0
- package/dist/local-instances-ZeRkkuS5.mjs +6 -0
- package/dist/{local-tiers-DPZYqv9m.mjs → local-tiers-BE4jGaMa.mjs} +2 -2
- package/dist/{local-tiers-DnBIAkbK.mjs → local-tiers-DNMI5W86.mjs} +3 -3
- package/dist/{main-config-ops-C0SflOWk.mjs → main-config-ops-BEMpuhDz.mjs} +3 -3
- package/dist/{main-resolver-DVPpSWVy.mjs → main-resolver-3Ns1HPmS.mjs} +18 -17
- package/dist/{migrate-BUJHadA8.mjs → migrate-DrA_OwlZ.mjs} +45 -14
- package/dist/min-max-DrSRUaWQ.mjs +16 -0
- package/dist/{model-inventory-Dasber3S.mjs → model-inventory-BFVSNFT3.mjs} +13 -12
- package/dist/{models-add-Bt7aUHDs.mjs → models-add-C1QIc1DA.mjs} +39 -38
- package/dist/operator-BTqvTIc8.mjs +7 -0
- package/dist/{operator-DZxcP-g8.mjs → operator-CyuB3aVw.mjs} +3 -3
- package/dist/{pai-marker-kIYuNt3c.mjs → pai-marker-BcZyJguM.mjs} +7 -6
- package/dist/{pane-audit-OGYrOAik.mjs → pane-audit-DKQt71s4.mjs} +7 -7
- package/dist/{paths-DoRuFc60.mjs → paths-CFHTloSe.mjs} +3 -3
- package/dist/{paths-DoIyRnhx.mjs → paths-CHifubDh.mjs} +3 -3
- package/dist/{planner-DLGOYlVb.mjs → planner-BmFACdLa.mjs} +31 -30
- package/dist/{pool-CZ5MZaXg.mjs → pool-Dh-q3iJi.mjs} +45 -6
- package/dist/{pool-cli-BxNSPzzY.mjs → pool-cli-BggU8GRp.mjs} +5 -5
- package/dist/{pool-cli-CbJfl37y.mjs → pool-cli-DQ6OzRy2.mjs} +6 -6
- package/dist/postgres-BdBNkL_l.mjs +7 -0
- package/dist/{postgres-CDnd_k5f.mjs → postgres-C6ti4haA.mjs} +55 -34
- package/dist/{project-setup-DM4npnL3.mjs → project-setup-jvfONJTQ.mjs} +131 -74
- package/dist/providers-BeDiVEb-.mjs +16 -0
- package/dist/{providers-UsKtLcUR.mjs → providers-CblTFrhz.mjs} +6 -6
- package/dist/{query-feedback-I-txSnld.mjs → query-feedback-BRfPtqki.mjs} +2 -2
- package/dist/registrable-BzH4TObg.mjs +9 -0
- package/dist/{registrable-LrRIVYQc.mjs → registrable-DpyTtajg.mjs} +4 -4
- package/dist/{render-BDbb4CF-.mjs → render-BYmQkuLd.mjs} +8 -8
- package/dist/render-CoMvwMPs.mjs +13 -0
- package/dist/{reranker-B4r4vykM.mjs → reranker-8g6xMwP7.mjs} +1 -1
- package/dist/{reranker-DxxMCtA0.mjs → reranker-CqCbpGnX.mjs} +1 -1
- package/dist/root-FtJsxYnm.mjs +36 -0
- package/dist/{root-BMeJuHOb.mjs → root-Xglu0OPD.mjs} +11 -11
- package/dist/route-table-B7zpoypi.mjs +15 -0
- package/dist/{router-L8Nu-OHF.mjs → router-CQSc3lk3.mjs} +17 -7
- package/dist/{router-D6Ec6Fid.mjs → router-DwHJRgG9.mjs} +1 -1
- package/dist/{routing-CUyiglfu.mjs → routing-BAAST9vT.mjs} +27 -308
- package/dist/{routing-ZuGlc0ge.mjs → routing-CENt4HH1.mjs} +13 -12
- package/dist/{run-ulAi5dFD.mjs → run-CSC7mgPf.mjs} +35 -33
- package/dist/{scan-B7I0gPe-.mjs → scan-C_Y5W9py.mjs} +6 -6
- package/dist/{local-candidate-jOjTNlOL.mjs → scheduler-CtUyWJ3O.mjs} +7 -109
- package/dist/scheduler-dmHXoRvm.mjs +3 -0
- package/dist/{scope-D5VSQxe4.mjs → scope-D-h6F6DN.mjs} +4 -4
- package/dist/{search-CPoE0830.mjs → search-RSyeQqj1.mjs} +18 -18
- package/dist/{session-CNXF6DLP.mjs → session-8iqQDkqb.mjs} +55 -31
- package/dist/session-BeqAbNPd.mjs +35 -0
- package/dist/session-scan-BJI_ZO8M.mjs +9 -0
- package/dist/{session-scan-BDLEc4w1.mjs → session-scan-W-gbwJHM.mjs} +6 -6
- package/dist/{sources-CjhUKKtO.mjs → sources-ESUkZaWv.mjs} +1 -1
- package/dist/{status-DYydKQUI.mjs → status-Dm4dYciN.mjs} +4 -4
- package/dist/{status-CvVi9cDf.mjs → status-ggJ7lgVg.mjs} +17 -9
- package/dist/{stop-words-SdSL1WKH.mjs → stop-words-DSEYQdNe.mjs} +1 -1
- package/dist/{test-isolation-CoDeOVXb.mjs → test-isolation-lqSmYxr0.mjs} +1 -1
- package/dist/{timeouts-OwEONmc8.mjs → timeouts-1MLooEBB.mjs} +1 -1
- package/dist/{tool-errors-AeRQuG3Y.mjs → tool-errors-7E13StWd.mjs} +4 -3
- package/dist/{tool-errors-R5E0fCgf.mjs → tool-errors-CJWODvlo.mjs} +6 -6
- package/dist/viewer-CqozWW39.mjs +22 -0
- package/dist/{viewer-DtWj5Vti.mjs → viewer-mDXUNHNy.mjs} +15 -15
- package/dist/{wait-BMUR-U-U.mjs → wait-ByV0OyMZ.mjs} +3 -3
- package/dist/{worker-config-BLqa1yiD.mjs → worker-config-CJhEMk19.mjs} +294 -92
- package/dist/worker-config-DESkIjMF.mjs +41 -0
- package/dist/{workers-config-DEI9lrV4.mjs → workers-config-f8KrkY4L.mjs} +2 -2
- package/dist/{worktree-zmRf556h.mjs → worktree-CRs2gyg0.mjs} +37 -7
- package/dist/{zettelkasten-nigq7fqs.mjs → zettelkasten-B_rRRRvD.mjs} +5 -5
- package/dist/{zettelkasten-Cr_Xj0mG.mjs → zettelkasten-BzMm8REH.mjs} +29 -19
- package/docs/README.md +2 -0
- package/docs/cockpit.md +10 -4
- package/docs/commands/README.md +4 -4
- package/docs/commands/backup.md +2 -0
- package/docs/commands/install.md +29 -4
- package/docs/commands/providers.md +1 -1
- package/docs/commands/restore.md +4 -0
- package/docs/commands/setup.md +29 -4
- package/docs/commands/worker.md +1 -1
- package/docs/config.md +2 -0
- package/docs/features.md +299 -0
- package/docs/images/architecture.drawio +51 -0
- package/docs/images/architecture.png +0 -0
- package/docs/images/architecture.svg +3 -0
- package/docs/images/cockpit-01-system-tokens.jpg +0 -0
- package/docs/images/cockpit-02-totals-cache.jpg +0 -0
- package/docs/images/cockpit-03-local-servers-models-pool.jpg +0 -0
- package/docs/images/cockpit-04-workers-memory.jpg +0 -0
- package/docs/images/cockpit-05-performance.jpg +0 -0
- package/docs/images/cockpit-06-runs-speed-routing.jpg +0 -0
- package/docs/images/cockpit-07-settings-registry.jpg +0 -0
- package/docs/install/index.md +29 -0
- package/docs/three-tier-coding.md +1 -1
- package/gemini-extension.json +1 -1
- package/package.json +1 -5
- package/pai-plugin.json +1 -1
- package/plugins/context-preservation/plugin.json +1 -1
- package/plugins/core/plugin.json +1 -1
- package/plugins/core/skills/setup/SKILL.md +41 -9
- package/plugins/creative/plugin.json +1 -1
- package/plugins/observability/plugin.json +1 -1
- package/plugins/productivity/plugin.json +1 -1
- package/plugins/semantic-search/plugin.json +1 -1
- package/plugins/ui/plugin.json +1 -1
- package/plugins/zettelkasten/plugin.json +1 -1
- package/src/hooks/session-autosave.sh +8 -1
- package/src/hooks/session-stop.sh +8 -1
- package/src/hooks/ts/capture-all-events.ts +7 -12
- package/src/hooks/ts/lib/context-fill.ts +2 -1
- package/src/hooks/ts/lib/path-repair.ts +1 -1
- package/src/hooks/ts/lib/project-utils/notify.ts +1 -0
- package/src/hooks/ts/lib/project-utils/session-notes.ts +23 -6
- package/src/hooks/ts/lib/raw-capture.ts +36 -0
- package/src/hooks/ts/lib/session-summary.ts +129 -0
- package/src/hooks/ts/lib/todo-sync.ts +120 -0
- package/src/hooks/ts/lib/worker-git-guard.ts +1 -1
- package/src/hooks/ts/post-tool-use/capture-tool-output.ts +6 -10
- package/src/hooks/ts/post-tool-use/sync-todo-to-md.ts +5 -105
- package/src/hooks/ts/pre-compact/context-compression-hook.ts +1 -1
- package/src/hooks/ts/pre-tool-use/security-validator.ts +35 -14
- package/src/hooks/ts/session-end/capture-session-summary.ts +20 -128
- package/src/hooks/ts/session-start/load-core-context.ts +3 -3
- package/src/hooks/ts/session-start/load-project-context.ts +18 -22
- package/src/hooks/ts/stop/stop-hook.ts +13 -5
- package/src/hooks/ztk-auto.sh +7 -2
- package/dist/aibroker-client-JjE74jo0.mjs +0 -3
- package/dist/auto-route-BRk8NEFv.mjs +0 -11
- package/dist/budget-DuhQ2zzG.mjs +0 -14
- package/dist/cockpit-actions-DcQ-ucU8.mjs +0 -19
- package/dist/cockpit-memory-KV45PPO2.mjs +0 -19
- package/dist/daemon-C7yt_ptC.mjs +0 -44
- package/dist/detect-DRUkmHnb.mjs +0 -10
- package/dist/factory-DAGG9_n8.mjs +0 -9
- package/dist/helpers-DPJEHPq6.mjs +0 -10
- package/dist/kill-tree-LV0Q7Mte.mjs +0 -10
- package/dist/operator-CfL0HiBK.mjs +0 -7
- package/dist/postgres-DgqWyqhN.mjs +0 -7
- package/dist/providers-CTu2s1z2.mjs +0 -15
- package/dist/registrable-D9aNZOTh.mjs +0 -9
- package/dist/render-BSfVlYHj.mjs +0 -13
- package/dist/root-xI9DqVIe.mjs +0 -35
- package/dist/route-table-HjvnLVEU.mjs +0 -14
- package/dist/session-BJHzmUg2.mjs +0 -34
- package/dist/session-scan-YORKE1NO.mjs +0 -9
- package/dist/viewer-B8709jDN.mjs +0 -22
- package/dist/worker-config-D8tRuvo7.mjs +0 -40
- package/docs/images/cockpit-limits-routing.jpg +0 -0
- package/docs/images/cockpit-models.jpg +0 -0
- package/docs/images/cockpit-usage.jpg +0 -0
- package/docs/images/cockpit-workers-system.jpg +0 -0
- package/scripts/build-docs.mjs +0 -41
- package/scripts/build-hooks.mjs +0 -311
- package/scripts/build-skill-stubs.mjs +0 -216
- package/scripts/copy-defaults.mjs +0 -46
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { _ as resolvePaiFile, d as defaultPaiHomeDir, g as paiHomePath } from "./runtime-paths-WsO9sJFc.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { a as parseSessionTitleChunk, c as yieldToEventLoop, f as fileContentHash, h as sha256File, i as isPathTooBroadForContentScan, n as chunkId, o as walkContentFiles, r as detectTier, s as walkMdFiles, t as INDEX_YIELD_EVERY, u as chunkMarkdown } from "./helpers-
|
|
4
|
-
import { t as STOP_WORDS } from "./stop-words-
|
|
5
|
-
import { n as buildFtsQuery, r as isQuerySyntaxError } from "./search-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
2
|
+
import { M as postgresConnectionString, c as loadConfig, k as DEFAULT_PG_CONNECTION_TIMEOUT_MS } from "./config-Bu1_vbY8.mjs";
|
|
3
|
+
import { a as parseSessionTitleChunk, c as yieldToEventLoop, f as fileContentHash, h as sha256File, i as isPathTooBroadForContentScan, n as chunkId, o as walkContentFiles, r as detectTier, s as walkMdFiles, t as INDEX_YIELD_EVERY, u as chunkMarkdown } from "./helpers-CRuBUas3.mjs";
|
|
4
|
+
import { t as STOP_WORDS } from "./stop-words-DSEYQdNe.mjs";
|
|
5
|
+
import { n as buildFtsQuery, r as isQuerySyntaxError } from "./search-RSyeQqj1.mjs";
|
|
6
|
+
import { n as minOf, t as maxOf } from "./min-max-DrSRUaWQ.mjs";
|
|
7
|
+
import { a as entityContentId, t as PostgresBackend } from "./postgres-C6ti4haA.mjs";
|
|
8
|
+
import { p as LEGACY_EMBEDDING_BINDING } from "./embedding-gate-6rZrWRXa.mjs";
|
|
9
|
+
import { i as deserializeEmbedding, r as cosineSimilarity } from "./embeddings-BVq3esBF.mjs";
|
|
10
|
+
import { n as routeNotification } from "./router-CQSc3lk3.mjs";
|
|
10
11
|
import { existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
|
|
11
12
|
import { basename, dirname, join, relative } from "node:path";
|
|
12
13
|
import pg from "pg";
|
|
@@ -478,8 +479,8 @@ async function findTunnelsForSlugMap(db, slugMap, opts) {
|
|
|
478
479
|
const totalOccurrences = rows.reduce((s, r) => s + Number(r.cnt), 0);
|
|
479
480
|
if (totalOccurrences < opts.min_occurrences) continue;
|
|
480
481
|
const projects = rows.map((r) => slugMap[r.project_id] ?? String(r.project_id)).filter(Boolean);
|
|
481
|
-
const firstSeen =
|
|
482
|
-
const lastSeen =
|
|
482
|
+
const firstSeen = minOf(rows.map((r) => r.first_seen));
|
|
483
|
+
const lastSeen = maxOf(rows.map((r) => r.last_seen));
|
|
483
484
|
tunnels.push({
|
|
484
485
|
concept: term,
|
|
485
486
|
projects,
|
|
@@ -2547,8 +2548,9 @@ var SQLiteRegistryBackend = class {
|
|
|
2547
2548
|
`;
|
|
2548
2549
|
if (where.length) sql += " WHERE " + where.join(" AND ");
|
|
2549
2550
|
sql += " ORDER BY s.date DESC, s.number DESC";
|
|
2550
|
-
const limit = opts.limit ?? 20;
|
|
2551
|
-
sql +=
|
|
2551
|
+
const limit = Math.max(1, Math.trunc(Number(opts.limit ?? 20)) || 20);
|
|
2552
|
+
sql += " LIMIT ?";
|
|
2553
|
+
params.push(limit);
|
|
2552
2554
|
return this.db.prepare(sql).all(...params);
|
|
2553
2555
|
}
|
|
2554
2556
|
async findSessionByFilename(projectId, filename) {
|
|
@@ -2913,4 +2915,4 @@ async function closeStorage() {
|
|
|
2913
2915
|
|
|
2914
2916
|
//#endregion
|
|
2915
2917
|
export { getStorageBackend as a, MergeError as c, getBackendOutage as d, humanDuration as f, getRegistryBackend as i, federationDbPath as l, createRegistryBackend as n, oldRegistryPath as o, createStorageBackend as r, registryDbPath as s, closeStorage as t, oldFederationPath as u };
|
|
2916
|
-
//# sourceMappingURL=factory-
|
|
2918
|
+
//# sourceMappingURL=factory-DjAAsqr_.mjs.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { l as claudeHomeDir, t as aibrokerHomeDir } from "./runtime-paths-WsO9sJFc.mjs";
|
|
2
|
-
import { F as writeWorkersSection, N as resolveModelCapability, P as resolveProviderKey, c as WorkersConfigError, j as readWorkersSection } from "./config-
|
|
3
|
-
import { D as readJsonStrict, O as writeJsonAtomic } from "./config-
|
|
4
|
-
import { u as workersLogDir } from "./paths-
|
|
5
|
-
import { _ as resolveTarget } from "./routing-
|
|
2
|
+
import { F as writeWorkersSection, N as resolveModelCapability, P as resolveProviderKey, c as WorkersConfigError, j as readWorkersSection } from "./config-XpZWOYOG.mjs";
|
|
3
|
+
import { D as readJsonStrict, O as writeJsonAtomic } from "./config-Bu1_vbY8.mjs";
|
|
4
|
+
import { u as workersLogDir } from "./paths-CHifubDh.mjs";
|
|
5
|
+
import { _ as resolveTarget } from "./routing-BAAST9vT.mjs";
|
|
6
6
|
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
import { execFileSync } from "node:child_process";
|
|
@@ -272,4 +272,4 @@ function fallbackStatusText(s) {
|
|
|
272
272
|
|
|
273
273
|
//#endregion
|
|
274
274
|
export { fallbackStatusText as i, fallbackOn as n, fallbackStatus as r, fallbackOff as t };
|
|
275
|
-
//# sourceMappingURL=fallback-
|
|
275
|
+
//# sourceMappingURL=fallback-DFlItw1Z.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { g as paiHomePath } from "./runtime-paths-WsO9sJFc.mjs";
|
|
2
|
-
import { t as ANTHROPIC_NATIVE } from "./config-
|
|
3
|
-
import { A as budgetSkipReason, D as budgetExceeded, E as budgetCache, M as budgetWall } from "./routing-
|
|
4
|
-
import { n as tierProviderNames, t as isLocalCandidate } from "./local-candidate-
|
|
2
|
+
import { t as ANTHROPIC_NATIVE } from "./config-XpZWOYOG.mjs";
|
|
3
|
+
import { A as budgetSkipReason, D as budgetExceeded, E as budgetCache, M as budgetWall } from "./routing-BAAST9vT.mjs";
|
|
4
|
+
import { n as tierProviderNames, t as isLocalCandidate } from "./local-candidate-DLdwQt0s.mjs";
|
|
5
5
|
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { Chalk } from "chalk";
|
|
7
7
|
|
|
@@ -311,4 +311,4 @@ function saveBudgetSnapshot(map, now = Date.now()) {
|
|
|
311
311
|
|
|
312
312
|
//#endregion
|
|
313
313
|
export { colorEnabled as a, renderCommandHelp as c, renderOverview as d, renderTable as f, saveBudgetSnapshot as i, renderMarkdown as l, usageLine as m, readBudget as n, makeStyle as o, suggest as p, readBudgetSnapshot as r, mdCommand as s, providerHealth as t, renderMore as u };
|
|
314
|
-
//# sourceMappingURL=health-
|
|
314
|
+
//# sourceMappingURL=health-Dnym-qcT.mjs.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getRegistryBackend } from "./factory-
|
|
1
|
+
import { i as getRegistryBackend } from "./factory-DjAAsqr_.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/cli/impl/project/helpers.ts
|
|
4
4
|
/**
|
|
@@ -66,4 +66,4 @@ async function upsertTag(tagName) {
|
|
|
66
66
|
|
|
67
67
|
//#endregion
|
|
68
68
|
export { getSessionCount as a, upsertTag as c, getProjectTags as i, getProject as n, requireProject as o, getProjectAliases as r, resolveIdentifier as s, getLastSessionDate as t };
|
|
69
|
-
//# sourceMappingURL=helpers-
|
|
69
|
+
//# sourceMappingURL=helpers-BD6V-p9w.mjs.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "./config-Bu1_vbY8.mjs";
|
|
2
|
+
import "./helpers-CRuBUas3.mjs";
|
|
3
|
+
import "./factory-DjAAsqr_.mjs";
|
|
4
|
+
import "./postgres-C6ti4haA.mjs";
|
|
5
|
+
import "./embedding-gate-6rZrWRXa.mjs";
|
|
6
|
+
import "./embeddings-BVq3esBF.mjs";
|
|
7
|
+
import "./router-CQSc3lk3.mjs";
|
|
8
|
+
import { a as getSessionCount, c as upsertTag, i as getProjectTags, n as getProject, o as requireProject, r as getProjectAliases, s as resolveIdentifier, t as getLastSessionDate } from "./helpers-BD6V-p9w.mjs";
|
|
9
|
+
|
|
10
|
+
export { getProject };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readdirSync } from "node:fs";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
2
3
|
import { basename, join, normalize } from "node:path";
|
|
3
4
|
import { homedir } from "node:os";
|
|
4
|
-
import { createHash } from "node:crypto";
|
|
5
5
|
|
|
6
6
|
//#region src/utils/hash.ts
|
|
7
7
|
/**
|
|
@@ -94,8 +94,16 @@ function buildOutline(content) {
|
|
|
94
94
|
const headings = parseHeadings(lines);
|
|
95
95
|
const roots = [];
|
|
96
96
|
const stack = [];
|
|
97
|
+
const nextSame = new Array(headings.length);
|
|
98
|
+
const pending = [];
|
|
99
|
+
for (let i = headings.length - 1; i >= 0; i--) {
|
|
100
|
+
const h = headings[i];
|
|
101
|
+
while (pending.length > 0 && pending[pending.length - 1].level > h.level) pending.pop();
|
|
102
|
+
nextSame[i] = pending[pending.length - 1];
|
|
103
|
+
pending.push(h);
|
|
104
|
+
}
|
|
97
105
|
headings.forEach((h, i) => {
|
|
98
|
-
const next =
|
|
106
|
+
const next = nextSame[i];
|
|
99
107
|
const endLine = Math.max(h.line, next ? next.line - 1 : last);
|
|
100
108
|
const node = {
|
|
101
109
|
level: h.level,
|
|
@@ -126,7 +134,7 @@ function splitBySections(lines) {
|
|
|
126
134
|
const text = current.map((l) => l.text).join("\n");
|
|
127
135
|
sections.push({
|
|
128
136
|
lines: current,
|
|
129
|
-
tokens:
|
|
137
|
+
tokens: sizeOf(text),
|
|
130
138
|
headingPath: currentPath
|
|
131
139
|
});
|
|
132
140
|
current = [];
|
|
@@ -151,7 +159,7 @@ function splitByParagraphs(block) {
|
|
|
151
159
|
const text = current.map((l) => l.text).join("\n");
|
|
152
160
|
paragraphs.push({
|
|
153
161
|
lines: [...current],
|
|
154
|
-
tokens:
|
|
162
|
+
tokens: sizeOf(text),
|
|
155
163
|
headingPath: block.headingPath
|
|
156
164
|
});
|
|
157
165
|
current = [];
|
|
@@ -160,47 +168,86 @@ function splitByParagraphs(block) {
|
|
|
160
168
|
const text = current.map((l) => l.text).join("\n");
|
|
161
169
|
paragraphs.push({
|
|
162
170
|
lines: current,
|
|
163
|
-
tokens:
|
|
171
|
+
tokens: sizeOf(text),
|
|
164
172
|
headingPath: block.headingPath
|
|
165
173
|
});
|
|
166
174
|
}
|
|
167
175
|
return paragraphs.length > 0 ? paragraphs : [block];
|
|
168
176
|
}
|
|
177
|
+
/** Characters per budget token above which a block counts as oversized (guards CJK / unbroken text). */
|
|
178
|
+
const MAX_CHARS_PER_TOKEN = 6;
|
|
179
|
+
/** Chunk size measure: word-based token estimate, floored by a character-length estimate. */
|
|
180
|
+
function sizeOf(text) {
|
|
181
|
+
return Math.max(estimateTokens(text), Math.ceil(text.length / MAX_CHARS_PER_TOKEN));
|
|
182
|
+
}
|
|
183
|
+
/** Split one over-budget line at sentence ends, then whitespace, then hard by characters. */
|
|
184
|
+
function splitLine(text, lineNo, budget) {
|
|
185
|
+
if (sizeOf(text) <= budget) return [{
|
|
186
|
+
text,
|
|
187
|
+
lineNo,
|
|
188
|
+
join: ""
|
|
189
|
+
}];
|
|
190
|
+
const maxChars = budget * MAX_CHARS_PER_TOKEN;
|
|
191
|
+
const pieces = [];
|
|
192
|
+
const push = (t, join) => {
|
|
193
|
+
if (t) pieces.push({
|
|
194
|
+
text: t,
|
|
195
|
+
lineNo,
|
|
196
|
+
join
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
let acc = "";
|
|
200
|
+
const emit = () => {
|
|
201
|
+
push(acc, pieces.length > 0 ? " " : "");
|
|
202
|
+
acc = "";
|
|
203
|
+
};
|
|
204
|
+
const addWord = (word) => {
|
|
205
|
+
if (acc && sizeOf(acc + " " + word) > budget) emit();
|
|
206
|
+
if (sizeOf(word) > budget) {
|
|
207
|
+
if (acc) emit();
|
|
208
|
+
for (let i = 0; i < word.length; i += maxChars) push(word.slice(i, i + maxChars), i === 0 ? pieces.length > 0 ? " " : "" : "");
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
acc = acc ? acc + " " + word : word;
|
|
212
|
+
};
|
|
213
|
+
for (const sentence of text.split(/(?<=[.!?])\s+(?=[A-Z"'])/)) {
|
|
214
|
+
if (acc && sizeOf(acc + " " + sentence) > budget) emit();
|
|
215
|
+
if (sizeOf(sentence) <= budget) acc = acc ? acc + " " + sentence : sentence;
|
|
216
|
+
else for (const word of sentence.split(/\s+/).filter(Boolean)) addWord(word);
|
|
217
|
+
}
|
|
218
|
+
emit();
|
|
219
|
+
return pieces;
|
|
220
|
+
}
|
|
169
221
|
/**
|
|
170
|
-
* Split
|
|
171
|
-
* too large
|
|
222
|
+
* Split an oversized LineBlock at line boundaries; lines that are themselves
|
|
223
|
+
* too large are split by sentence, whitespace, then characters. Original line
|
|
224
|
+
* breaks and real line numbers are kept.
|
|
172
225
|
*/
|
|
173
|
-
function
|
|
174
|
-
const sentences = block.lines.map((l) => l.text).join(" ").split(/(?<=[.!?])\s+(?=[A-Z"'])/g);
|
|
226
|
+
function splitOversized(block, budget) {
|
|
175
227
|
const result = [];
|
|
176
|
-
let
|
|
177
|
-
|
|
178
|
-
const endLine = block.lines[block.lines.length - 1]?.lineNo ?? startLine;
|
|
179
|
-
const totalLines = endLine - startLine + 1;
|
|
180
|
-
const linesPerSentence = Math.max(1, Math.floor(totalLines / Math.max(1, sentences.length)));
|
|
181
|
-
let sentenceIdx = 0;
|
|
182
|
-
let approxLine = startLine;
|
|
228
|
+
let cur = [];
|
|
229
|
+
let curText = "";
|
|
183
230
|
const flush = () => {
|
|
184
|
-
if (
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
lines: [{
|
|
188
|
-
text: accText.trim(),
|
|
189
|
-
lineNo: approxLine
|
|
190
|
-
}],
|
|
191
|
-
tokens: estimateTokens(accText),
|
|
231
|
+
if (cur.length > 0) result.push({
|
|
232
|
+
lines: cur,
|
|
233
|
+
tokens: sizeOf(curText),
|
|
192
234
|
headingPath: block.headingPath
|
|
193
235
|
});
|
|
194
|
-
|
|
195
|
-
|
|
236
|
+
cur = [];
|
|
237
|
+
curText = "";
|
|
238
|
+
};
|
|
239
|
+
const add = (piece, sep) => {
|
|
240
|
+
const last = cur[cur.length - 1];
|
|
241
|
+
if (last && piece.join && last.lineNo === piece.lineNo) last.text += piece.join + piece.text;
|
|
242
|
+
else cur.push({
|
|
243
|
+
text: piece.text,
|
|
244
|
+
lineNo: piece.lineNo
|
|
245
|
+
});
|
|
246
|
+
curText += (curText ? sep : "") + piece.text;
|
|
196
247
|
};
|
|
197
|
-
for (const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (estimateTokens(candidateText) > maxTokens && accText) {
|
|
201
|
-
flush();
|
|
202
|
-
accText = sentence;
|
|
203
|
-
} else accText = candidateText;
|
|
248
|
+
for (const line of block.lines) for (const piece of splitLine(line.text, line.lineNo, budget)) {
|
|
249
|
+
if (cur.length > 0 && sizeOf(curText + "\n" + piece.text) > budget) flush();
|
|
250
|
+
add(piece, piece.join ? piece.join : "\n");
|
|
204
251
|
}
|
|
205
252
|
flush();
|
|
206
253
|
return result.length > 0 ? result : [block];
|
|
@@ -239,9 +286,12 @@ function buildOverlapPrefix(lastChunk, overlapTokens) {
|
|
|
239
286
|
/**
|
|
240
287
|
* Strip `<private>...</private>` blocks from content before indexing.
|
|
241
288
|
* Content within these tags is excluded from memory — never stored or searched.
|
|
289
|
+
* Newlines are preserved so line numbers still match the file; an unclosed
|
|
290
|
+
* tag hides everything after it.
|
|
242
291
|
*/
|
|
243
292
|
function stripPrivateTags(content) {
|
|
244
|
-
|
|
293
|
+
const blank = (m) => m.replace(/[^\n]/g, "");
|
|
294
|
+
return content.replace(/<private>[\s\S]*?<\/private>/gi, blank).replace(/<private>[\s\S]*$/i, blank);
|
|
245
295
|
}
|
|
246
296
|
/** One breadcrumb line ("[A > B]\n") for a non-empty heading path, else "". */
|
|
247
297
|
function breadcrumb(path) {
|
|
@@ -258,7 +308,7 @@ function chunkMarkdown(content, opts) {
|
|
|
258
308
|
})));
|
|
259
309
|
const finalBlocks = [];
|
|
260
310
|
for (const section of sections) {
|
|
261
|
-
const budget = Math.max(1, maxTokens -
|
|
311
|
+
const budget = Math.max(1, maxTokens - sizeOf(breadcrumb(section.headingPath)));
|
|
262
312
|
if (section.tokens <= budget) {
|
|
263
313
|
finalBlocks.push(section);
|
|
264
314
|
continue;
|
|
@@ -269,8 +319,7 @@ function chunkMarkdown(content, opts) {
|
|
|
269
319
|
finalBlocks.push(para);
|
|
270
320
|
continue;
|
|
271
321
|
}
|
|
272
|
-
|
|
273
|
-
finalBlocks.push(...sentences);
|
|
322
|
+
finalBlocks.push(...splitOversized(para, budget));
|
|
274
323
|
}
|
|
275
324
|
}
|
|
276
325
|
const chunks = [];
|
|
@@ -516,4 +565,4 @@ const INDEX_YIELD_EVERY = 10;
|
|
|
516
565
|
|
|
517
566
|
//#endregion
|
|
518
567
|
export { parseSessionTitleChunk as a, yieldToEventLoop as c, estimateTokens as d, fileContentHash as f, sha256File as h, isPathTooBroadForContentScan as i, buildOutline as l, sha256 as m, chunkId as n, walkContentFiles as o, parseHeadings as p, detectTier as r, walkMdFiles as s, INDEX_YIELD_EVERY as t, chunkMarkdown as u };
|
|
519
|
-
//# sourceMappingURL=helpers-
|
|
568
|
+
//# sourceMappingURL=helpers-CRuBUas3.mjs.map
|
|
@@ -7365,7 +7365,7 @@ var require_dist = __commonJS({
|
|
|
7365
7365
|
});
|
|
7366
7366
|
|
|
7367
7367
|
// src/hooks/ts/capture-all-events.ts
|
|
7368
|
-
import { readFileSync as readFileSync4,
|
|
7368
|
+
import { readFileSync as readFileSync4, existsSync as existsSync5 } from "fs";
|
|
7369
7369
|
import { join as join6 } from "path";
|
|
7370
7370
|
|
|
7371
7371
|
// src/hooks/ts/lib/pai-paths.ts
|
|
@@ -7718,6 +7718,51 @@ var CONFIG_DIR = dirname3(CONFIG_FILE);
|
|
|
7718
7718
|
// src/session/checkpoint-block.ts
|
|
7719
7719
|
var AUTHORED_GRACE_MS = 60 * 60 * 1e3;
|
|
7720
7720
|
|
|
7721
|
+
// src/hooks/ts/lib/raw-capture.ts
|
|
7722
|
+
import { appendFileSync, chmodSync as chmodSync2, existsSync as existsSync4, mkdirSync as mkdirSync3, renameSync as renameSync3, statSync as statSync2 } from "fs";
|
|
7723
|
+
|
|
7724
|
+
// src/workers/ps-table.ts
|
|
7725
|
+
var PS_MAX_BUFFER = 64 * 1024 * 1024;
|
|
7726
|
+
|
|
7727
|
+
// src/hooks/ts/lib/loop-guard.ts
|
|
7728
|
+
var LOOP_MAX_REPEATS = 4;
|
|
7729
|
+
var LOOP_READ_STREAK = Number(process.env.PAI_LOOP_READ_STREAK) > 0 ? Number(process.env.PAI_LOOP_READ_STREAK) : 15;
|
|
7730
|
+
var SELF = "If your part is done, commit and write your R report. If you are stuck, report the blocker in R x= (or use pai worker help if available).";
|
|
7731
|
+
var LOOP_DENY_REASON = `loop guard: you ran this command ${LOOP_MAX_REPEATS} times with the same result and nothing changed. Stop repeating it. ${SELF}`;
|
|
7732
|
+
var WAIT_CAP_MS = 45 * 6e4;
|
|
7733
|
+
var FP_FULL_READ_BYTES = 256 * 1024;
|
|
7734
|
+
var FP_TOTAL_BYTES = 4 * 1024 * 1024;
|
|
7735
|
+
var SECRET_LINE = /pass(?:word|wd)|secret|token|api[_-]?key|credential|authorization|bearer|private key|^\s*(?:export\s+)?[A-Z][A-Z0-9_]*(?:KEY|SECRET|TOKEN|PASS\w*|CRED\w*|AUTH\w*)\s*=|\b(?:sk|ghp|gho|xox[bap])[-_][A-Za-z0-9_-]{16,}|\b[A-Za-z0-9+]{40,}={0,2}(?![\w/])|\b[a-z][a-z0-9+.-]*:\/\/[^\s\/:@]+:[^\s\/@]+@|\b(?:AKIA|ASIA|AGPA|AIDA|AROA)[A-Z0-9]{16}\b|\bgh[pousr]_[A-Za-z0-9]{20,}/i;
|
|
7736
|
+
var MASKED_LINE = "[line masked: looks like a secret]";
|
|
7737
|
+
function maskSecrets(text) {
|
|
7738
|
+
return text.split("\n").map((l) => SECRET_LINE.test(l) ? MASKED_LINE : l).join("\n");
|
|
7739
|
+
}
|
|
7740
|
+
|
|
7741
|
+
// src/hooks/ts/lib/raw-capture.ts
|
|
7742
|
+
var RAW_CAPTURE_MAX_BYTES = 10 * 1024 * 1024;
|
|
7743
|
+
function redactDeep(value) {
|
|
7744
|
+
if (typeof value === "string") return maskSecrets(value);
|
|
7745
|
+
if (Array.isArray(value)) return value.map(redactDeep);
|
|
7746
|
+
if (value && typeof value === "object") {
|
|
7747
|
+
const out = {};
|
|
7748
|
+
for (const [k, v] of Object.entries(value)) out[k] = redactDeep(v);
|
|
7749
|
+
return out;
|
|
7750
|
+
}
|
|
7751
|
+
return value;
|
|
7752
|
+
}
|
|
7753
|
+
function appendRawCapture(file, dir, line, maxBytes = RAW_CAPTURE_MAX_BYTES) {
|
|
7754
|
+
if (!existsSync4(dir)) mkdirSync3(dir, { recursive: true, mode: 448 });
|
|
7755
|
+
try {
|
|
7756
|
+
if (statSync2(file).size + Buffer.byteLength(line) > maxBytes) renameSync3(file, `${file}.1`);
|
|
7757
|
+
} catch {
|
|
7758
|
+
}
|
|
7759
|
+
appendFileSync(file, line, { mode: 384 });
|
|
7760
|
+
try {
|
|
7761
|
+
chmodSync2(file, 384);
|
|
7762
|
+
} catch {
|
|
7763
|
+
}
|
|
7764
|
+
}
|
|
7765
|
+
|
|
7721
7766
|
// src/hooks/ts/capture-all-events.ts
|
|
7722
7767
|
function getLocalTimestamp() {
|
|
7723
7768
|
const date = /* @__PURE__ */ new Date();
|
|
@@ -7739,10 +7784,7 @@ function getEventsFilePath() {
|
|
|
7739
7784
|
const month = String(localDate.getMonth() + 1).padStart(2, "0");
|
|
7740
7785
|
const day = String(localDate.getDate()).padStart(2, "0");
|
|
7741
7786
|
const monthDir = join6(historyDir(), "raw-outputs", `${year}-${month}`);
|
|
7742
|
-
|
|
7743
|
-
mkdirSync3(monthDir, { recursive: true });
|
|
7744
|
-
}
|
|
7745
|
-
return join6(monthDir, `${year}-${month}-${day}_all-events.jsonl`);
|
|
7787
|
+
return { dir: monthDir, file: join6(monthDir, `${year}-${month}-${day}_all-events.jsonl`) };
|
|
7746
7788
|
}
|
|
7747
7789
|
function getSessionMappingFile() {
|
|
7748
7790
|
return agentSessionsPath();
|
|
@@ -7750,7 +7792,7 @@ function getSessionMappingFile() {
|
|
|
7750
7792
|
function getAgentForSession(sessionId) {
|
|
7751
7793
|
try {
|
|
7752
7794
|
const mappingFile = getSessionMappingFile();
|
|
7753
|
-
if (
|
|
7795
|
+
if (existsSync5(mappingFile)) {
|
|
7754
7796
|
const mappings = JSON.parse(readFileSync4(mappingFile, "utf-8"));
|
|
7755
7797
|
return mappings[sessionId] || "pai";
|
|
7756
7798
|
}
|
|
@@ -7762,7 +7804,7 @@ function setAgentForSession(sessionId, agentName) {
|
|
|
7762
7804
|
try {
|
|
7763
7805
|
const mappingFile = getSessionMappingFile();
|
|
7764
7806
|
let mappings = {};
|
|
7765
|
-
if (
|
|
7807
|
+
if (existsSync5(mappingFile)) {
|
|
7766
7808
|
try {
|
|
7767
7809
|
mappings = JSON.parse(readFileSync4(mappingFile, "utf-8"));
|
|
7768
7810
|
} catch {
|
|
@@ -7817,7 +7859,7 @@ async function main() {
|
|
|
7817
7859
|
source_app: agentName,
|
|
7818
7860
|
session_id: hookData.session_id || "main",
|
|
7819
7861
|
hook_event_type: eventType,
|
|
7820
|
-
payload: hookData,
|
|
7862
|
+
payload: redactDeep(hookData),
|
|
7821
7863
|
timestamp: Date.now(),
|
|
7822
7864
|
timestamp_local: getLocalTimestamp()
|
|
7823
7865
|
};
|
|
@@ -7828,9 +7870,8 @@ async function main() {
|
|
|
7828
7870
|
hookData.description
|
|
7829
7871
|
);
|
|
7830
7872
|
}
|
|
7831
|
-
const
|
|
7832
|
-
|
|
7833
|
-
appendFileSync(eventsFile, jsonLine, "utf-8");
|
|
7873
|
+
const events = getEventsFilePath();
|
|
7874
|
+
appendRawCapture(events.file, events.dir, JSON.stringify(event) + "\n");
|
|
7834
7875
|
} catch (error) {
|
|
7835
7876
|
console.error("Event capture error:", error);
|
|
7836
7877
|
}
|
|
@@ -47,8 +47,9 @@ function paiSocketPath() {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// src/hooks/ts/session-end/capture-session-summary.ts
|
|
50
|
-
import { writeFileSync, mkdirSync as mkdirSync2, existsSync as
|
|
51
|
-
import {
|
|
50
|
+
import { writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync4, readFileSync as readFileSync4, unlinkSync } from "fs";
|
|
51
|
+
import { tmpdir } from "os";
|
|
52
|
+
import { join as join4 } from "path";
|
|
52
53
|
|
|
53
54
|
// src/hooks/ts/lib/pai-paths.ts
|
|
54
55
|
import { homedir as homedir2 } from "os";
|
|
@@ -139,47 +140,10 @@ function historyDir() {
|
|
|
139
140
|
return resolvePaiFile(paiHomePath("History"), [oldHistoryDir()], "pai config migrate --history");
|
|
140
141
|
}
|
|
141
142
|
|
|
142
|
-
// src/hooks/ts/
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
for await (const chunk of process.stdin) {
|
|
147
|
-
chunks.push(chunk);
|
|
148
|
-
}
|
|
149
|
-
const input = Buffer.concat(chunks).toString("utf-8");
|
|
150
|
-
if (!input || input.trim() === "") {
|
|
151
|
-
process.exit(0);
|
|
152
|
-
}
|
|
153
|
-
if (!process.env.__PAI_HOOK_BG) {
|
|
154
|
-
const { spawn } = await import("child_process");
|
|
155
|
-
const child = spawn(process.execPath, [process.argv[1], "--background"], {
|
|
156
|
-
detached: true,
|
|
157
|
-
stdio: "ignore",
|
|
158
|
-
env: { ...process.env, __PAI_HOOK_BG: "1", __PAI_HOOK_INPUT: input }
|
|
159
|
-
});
|
|
160
|
-
child.unref();
|
|
161
|
-
process.exit(0);
|
|
162
|
-
}
|
|
163
|
-
const data = JSON.parse(process.env.__PAI_HOOK_INPUT || input);
|
|
164
|
-
const now = /* @__PURE__ */ new Date();
|
|
165
|
-
const timestamp = now.toISOString().replace(/:/g, "").replace(/\..+/, "").replace("T", "-");
|
|
166
|
-
const yearMonth = timestamp.substring(0, 7);
|
|
167
|
-
const sessionInfo = await analyzeSession(data.conversation_id, yearMonth);
|
|
168
|
-
const filename = `${timestamp}_SESSION_${sessionInfo.focus}.md`;
|
|
169
|
-
const sessionDir = join3(historyDir(), "sessions", yearMonth);
|
|
170
|
-
if (!existsSync3(sessionDir)) {
|
|
171
|
-
mkdirSync2(sessionDir, { recursive: true });
|
|
172
|
-
}
|
|
173
|
-
const sessionDoc = formatSessionDocument(timestamp, data, sessionInfo);
|
|
174
|
-
writeFileSync(join3(sessionDir, filename), sessionDoc);
|
|
175
|
-
await storeStructuredSummary(data.conversation_id, sessionInfo);
|
|
176
|
-
process.exit(0);
|
|
177
|
-
} catch (error) {
|
|
178
|
-
console.error(`[UOCS] SessionEnd hook error: ${error}`);
|
|
179
|
-
process.exit(0);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
async function analyzeSession(conversationId, yearMonth) {
|
|
143
|
+
// src/hooks/ts/lib/session-summary.ts
|
|
144
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync as readdirSync2 } from "fs";
|
|
145
|
+
import { join as join3 } from "path";
|
|
146
|
+
async function analyzeSession(sessionId, yearMonth) {
|
|
183
147
|
const rawOutputsDir = join3(historyDir(), "raw-outputs", yearMonth);
|
|
184
148
|
let filesChanged = [];
|
|
185
149
|
let commandsExecuted = [];
|
|
@@ -197,7 +161,7 @@ async function analyzeSession(conversationId, yearMonth) {
|
|
|
197
161
|
for (const line of lines) {
|
|
198
162
|
try {
|
|
199
163
|
const entry = JSON.parse(line);
|
|
200
|
-
if (entry.session ===
|
|
164
|
+
if (entry.session === sessionId) {
|
|
201
165
|
toolsUsed.add(entry.tool);
|
|
202
166
|
if (entry.tool === "Edit" || entry.tool === "Write") {
|
|
203
167
|
if (entry.input?.file_path) {
|
|
@@ -228,12 +192,13 @@ async function analyzeSession(conversationId, yearMonth) {
|
|
|
228
192
|
}
|
|
229
193
|
function formatSessionDocument(timestamp, data, info) {
|
|
230
194
|
const date = timestamp.substring(0, 10);
|
|
231
|
-
const
|
|
195
|
+
const hhmmss = timestamp.substring(11);
|
|
196
|
+
const time = `${hhmmss.slice(0, 2)}:${hhmmss.slice(2, 4)}:${hhmmss.slice(4, 6)}`;
|
|
232
197
|
const da = process.env.DA || "PAI";
|
|
233
198
|
return `---
|
|
234
199
|
capture_type: SESSION
|
|
235
200
|
timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
236
|
-
session_id: ${data.
|
|
201
|
+
session_id: ${data.session_id}
|
|
237
202
|
duration_minutes: ${info.duration}
|
|
238
203
|
executor: ${da}
|
|
239
204
|
---
|
|
@@ -242,7 +207,7 @@ executor: ${da}
|
|
|
242
207
|
|
|
243
208
|
**Date:** ${date}
|
|
244
209
|
**Time:** ${time}
|
|
245
|
-
**Session ID:** ${data.
|
|
210
|
+
**Session ID:** ${data.session_id}
|
|
246
211
|
|
|
247
212
|
---
|
|
248
213
|
|
|
@@ -285,6 +250,58 @@ For detailed tool outputs, see: \`${join3(historyDir(), "raw-outputs", timestamp
|
|
|
285
250
|
**Generated:** ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
286
251
|
`;
|
|
287
252
|
}
|
|
253
|
+
|
|
254
|
+
// src/hooks/ts/session-end/capture-session-summary.ts
|
|
255
|
+
async function main() {
|
|
256
|
+
try {
|
|
257
|
+
const chunks = [];
|
|
258
|
+
for await (const chunk of process.stdin) {
|
|
259
|
+
chunks.push(chunk);
|
|
260
|
+
}
|
|
261
|
+
const input = Buffer.concat(chunks).toString("utf-8");
|
|
262
|
+
if ((!input || input.trim() === "") && !process.env.__PAI_HOOK_INPUT_FILE) {
|
|
263
|
+
process.exit(0);
|
|
264
|
+
}
|
|
265
|
+
if (!process.env.__PAI_HOOK_BG) {
|
|
266
|
+
const { spawn } = await import("child_process");
|
|
267
|
+
const inputFile2 = join4(tmpdir(), `pai-session-end-${process.pid}-${Date.now()}.json`);
|
|
268
|
+
writeFileSync(inputFile2, input, { mode: 384 });
|
|
269
|
+
const child = spawn(process.execPath, [process.argv[1], "--background"], {
|
|
270
|
+
detached: true,
|
|
271
|
+
stdio: "ignore",
|
|
272
|
+
env: { ...process.env, __PAI_HOOK_BG: "1", __PAI_HOOK_INPUT_FILE: inputFile2 }
|
|
273
|
+
});
|
|
274
|
+
child.unref();
|
|
275
|
+
process.exit(0);
|
|
276
|
+
}
|
|
277
|
+
const inputFile = process.env.__PAI_HOOK_INPUT_FILE;
|
|
278
|
+
let raw = input;
|
|
279
|
+
if (inputFile) {
|
|
280
|
+
raw = readFileSync4(inputFile, "utf-8");
|
|
281
|
+
try {
|
|
282
|
+
unlinkSync(inputFile);
|
|
283
|
+
} catch {
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const data = JSON.parse(raw);
|
|
287
|
+
const now = /* @__PURE__ */ new Date();
|
|
288
|
+
const timestamp = now.toISOString().replace(/:/g, "").replace(/\..+/, "").replace("T", "-");
|
|
289
|
+
const yearMonth = timestamp.substring(0, 7);
|
|
290
|
+
const sessionInfo = await analyzeSession(data.session_id, yearMonth);
|
|
291
|
+
const filename = `${timestamp}_SESSION_${sessionInfo.focus}.md`;
|
|
292
|
+
const sessionDir = join4(historyDir(), "sessions", yearMonth);
|
|
293
|
+
if (!existsSync4(sessionDir)) {
|
|
294
|
+
mkdirSync2(sessionDir, { recursive: true });
|
|
295
|
+
}
|
|
296
|
+
const sessionDoc = formatSessionDocument(timestamp, data, sessionInfo);
|
|
297
|
+
writeFileSync(join4(sessionDir, filename), sessionDoc);
|
|
298
|
+
await storeStructuredSummary(data.session_id, sessionInfo);
|
|
299
|
+
process.exit(0);
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error(`[UOCS] SessionEnd hook error: ${error}`);
|
|
302
|
+
process.exit(0);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
288
305
|
async function storeStructuredSummary(sessionId, info) {
|
|
289
306
|
try {
|
|
290
307
|
const cwd = process.cwd();
|