pim-agent 0.13.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/packages/core/src/attachments/AttachmentStore.ts +8 -13
- package/packages/core/src/attachments/Attachments.ts +2 -4
- package/packages/core/src/extensions/CoreExtensions.ts +1 -1
- package/packages/core/src/extensions/apply-patch/coordinator.ts +1 -1
- package/packages/core/src/extensions/apply-patch/executor.ts +21 -25
- package/packages/core/src/extensions/apply-patch/matcher.ts +1 -1
- package/packages/core/src/extensions/apply-patch/model.ts +2 -6
- package/packages/core/src/extensions/apply-patch/parser.ts +60 -162
- package/packages/core/src/extensions/apply-patch/schema.ts +0 -1
- package/packages/core/src/extensions/bash/MemoryCap.ts +5 -4
- package/packages/core/src/extensions/bash/capture.ts +16 -23
- package/packages/core/src/extensions/bash/format.ts +2 -2
- package/packages/core/src/extensions/bash/image.ts +4 -8
- package/packages/core/src/extensions/bash/index.ts +1 -1
- package/packages/core/src/extensions/bash/render.ts +1 -1
- package/packages/core/src/extensions/bash/run.ts +9 -15
- package/packages/core/src/extensions/bash/schema.ts +4 -4
- package/packages/core/src/extensions/edit/edit.ts +14 -33
- package/packages/core/src/extensions/glob/glob.ts +1 -3
- package/packages/core/src/extensions/glob/index.ts +7 -9
- package/packages/core/src/extensions/glob/render.ts +2 -4
- package/packages/core/src/extensions/glob/schema.ts +1 -1
- package/packages/core/src/extensions/grep/grep.ts +7 -7
- package/packages/core/src/extensions/grep/render.ts +5 -6
- package/packages/core/src/extensions/grep/schema.ts +3 -7
- package/packages/core/src/extensions/read/ImageMemory.ts +2 -8
- package/packages/core/src/extensions/read/image.ts +3 -3
- package/packages/core/src/extensions/read/index.ts +2 -14
- package/packages/core/src/extensions/read/read.ts +5 -6
- package/packages/core/src/extensions/read/render.ts +1 -1
- package/packages/core/src/extensions/read/schema.ts +2 -2
- package/packages/core/src/extensions/subagent/render.ts +2 -2
- package/packages/core/src/extensions/subagent/subagent.ts +10 -21
- package/packages/core/src/extensions/system-prompt/index.ts +1 -2
- package/packages/core/src/extensions/system-prompt/prompt.ts +2 -4
- package/packages/core/src/extensions/todo/render.ts +1 -4
- package/packages/core/src/extensions/todo/todo.ts +16 -23
- package/packages/core/src/extensions/web-fetch/JinaReaderClient.ts +3 -11
- package/packages/core/src/extensions/web-fetch/WebViewFetchClient.ts +1 -3
- package/packages/core/src/extensions/web-fetch/fetch.ts +4 -12
- package/packages/core/src/extensions/web-fetch/image.ts +3 -4
- package/packages/core/src/extensions/web-fetch/index.ts +2 -13
- package/packages/core/src/extensions/web-fetch/render.ts +3 -4
- package/packages/core/src/extensions/web-fetch/schema.ts +3 -4
- package/packages/core/src/extensions/web-search/ExaMcpClient.ts +23 -31
- package/packages/core/src/extensions/web-search/SearchBreaker.ts +1 -1
- package/packages/core/src/extensions/web-search/SearchChain.ts +6 -5
- package/packages/core/src/extensions/web-search/providers/DuckDuckGoProvider.ts +2 -2
- package/packages/core/src/extensions/web-search/providers/FirecrawlProvider.ts +1 -2
- package/packages/core/src/extensions/web-search/providers/SearchProvider.ts +3 -3
- package/packages/core/src/extensions/write/write.ts +1 -1
- package/packages/core/src/picker/InProcessFilePickerSuggestionEngine.ts +1 -3
- package/packages/core/src/picker/PickerItem.ts +1 -1
- package/packages/core/src/picker/PickerService.ts +3 -7
- package/packages/core/src/picker/RemoteFilePickerSuggestionEngine.ts +1 -2
- package/packages/core/src/picker/catalog.ts +7 -15
- package/packages/core/src/picker/filePickerWorker.ts +1 -3
- package/packages/core/src/picker/ranker.ts +1 -1
- package/packages/core/src/picker/token.ts +3 -4
- package/packages/core/src/session/AgentRuntime.ts +5 -8
- package/packages/core/src/session/EventLog.ts +6 -12
- package/packages/core/src/session/ReadCursors.ts +3 -4
- package/packages/core/src/session/SearchIndex.ts +49 -86
- package/packages/core/src/session/SearchTokens.ts +4 -7
- package/packages/core/src/session/SessionCache.ts +8 -6
- package/packages/core/src/session/SessionDigest.ts +10 -19
- package/packages/core/src/session/SessionHost.ts +53 -83
- package/packages/core/src/session/SessionLease.ts +12 -15
- package/packages/core/src/session/SessionMeta.ts +16 -32
- package/packages/core/src/session/SessionName.ts +3 -7
- package/packages/core/src/session/SessionRegistry.ts +13 -29
- package/packages/core/src/session/SessionUi.ts +12 -16
- package/packages/core/src/session/WriteMark.ts +7 -16
- package/packages/core/src/shared/Cli.ts +1 -1
- package/packages/core/src/shared/DaemonUnit.ts +1 -2
- package/packages/core/src/shared/DiffLines.ts +16 -34
- package/packages/core/src/shared/DiffRenderer.ts +8 -27
- package/packages/core/src/shared/Directories.ts +4 -4
- package/packages/core/src/shared/EditMatcher.ts +18 -50
- package/packages/core/src/shared/ExtensionToggles.ts +3 -6
- package/packages/core/src/shared/FileEnumerator.ts +73 -57
- package/packages/core/src/shared/FileScanner.ts +5 -13
- package/packages/core/src/shared/FileWatch.ts +13 -17
- package/packages/core/src/shared/Format.ts +2 -3
- package/packages/core/src/shared/FuzzyMatcher.ts +18 -19
- package/packages/core/src/shared/Git.ts +22 -47
- package/packages/core/src/shared/GitMonitor.ts +12 -23
- package/packages/core/src/shared/GlobExclusions.ts +0 -4
- package/packages/core/src/shared/Http.ts +1 -1
- package/packages/core/src/shared/ImageMime.ts +3 -5
- package/packages/core/src/shared/Images.ts +17 -27
- package/packages/core/src/shared/Languages.ts +2 -2
- package/packages/core/src/shared/Levenshtein.ts +1 -6
- package/packages/core/src/shared/Lines.ts +1 -1
- package/packages/core/src/shared/McpClient.ts +2 -2
- package/packages/core/src/shared/PatchSummary.ts +1 -1
- package/packages/core/src/shared/Paths.ts +4 -1
- package/packages/core/src/shared/PiExtensions.ts +5 -12
- package/packages/core/src/shared/PimSettings.ts +14 -15
- package/packages/core/src/shared/Proc.ts +2 -3
- package/packages/core/src/shared/RateLimiter.ts +1 -1
- package/packages/core/src/shared/Renderer.ts +1 -3
- package/packages/core/src/shared/RepoDiff.ts +24 -46
- package/packages/core/src/shared/SearchRender.ts +3 -4
- package/packages/core/src/shared/SpillCache.ts +2 -3
- package/packages/core/src/shared/SubagentLogs.ts +4 -6
- package/packages/core/src/shared/Supervisor.ts +19 -32
- package/packages/core/src/shared/Surface.ts +1 -1
- package/packages/core/src/shared/Sweeper.ts +1 -1
- package/packages/core/src/shared/Tools.ts +17 -30
- package/packages/core/src/shared/Updater.ts +15 -15
- package/packages/core/src/view/BodyRenderer.ts +1 -1
- package/packages/core/src/view/DiffBlocks.ts +0 -1
- package/packages/core/src/view/DiffExpand.ts +10 -25
- package/packages/core/src/view/DiffLayout.ts +2 -2
- package/packages/core/src/view/DiffPairs.ts +2 -2
- package/packages/core/src/view/MarkdownPainter.ts +2 -19
- package/packages/core/src/view/MovePath.ts +4 -17
- package/packages/core/src/view/Painting.ts +4 -4
- package/packages/core/src/view/ViewBlock.ts +11 -12
- package/packages/daemon/src/Daemon.ts +2 -7
- package/packages/daemon/src/DaemonInstall.ts +5 -12
- package/packages/daemon/src/Surfaces.ts +3 -12
- package/packages/daemon/src/TelegramSurface.ts +0 -1
- package/packages/daemon/src/index.ts +0 -1
- package/packages/protocol/src/Command.ts +33 -41
- package/packages/protocol/src/Diff.ts +0 -5
- package/packages/protocol/src/ImageRoute.ts +2 -5
- package/packages/protocol/src/ServerEvent.ts +68 -105
- package/packages/server/src/AttachmentEndpoint.ts +45 -19
- package/packages/server/src/ClientConnection.ts +11 -12
- package/packages/server/src/ImageEndpoint.ts +3 -4
- package/packages/server/src/ProbeClient.ts +26 -59
- package/packages/server/src/Reloader.ts +4 -7
- package/packages/server/src/SendFileTool.ts +1 -1
- package/packages/server/src/SessionCatalogue.ts +35 -47
- package/packages/server/src/SessionProjection.ts +7 -12
- package/packages/server/src/SessionStream.ts +33 -80
- package/packages/server/src/StaticClient.ts +7 -8
- package/packages/server/src/WebOptions.ts +2 -6
- package/packages/server/src/WsGateway.ts +35 -96
- package/packages/server/src/probe.ts +6 -18
- package/packages/telegram/src/Bot.ts +2 -2
- package/packages/telegram/src/Commands.ts +108 -65
- package/packages/telegram/src/Config.ts +1 -6
- package/packages/telegram/src/Markdown.ts +4 -13
- package/packages/telegram/src/Renderer.ts +1 -1
- package/packages/telegram/src/Session.ts +3 -10
- package/packages/telegram/src/TaskScheduler.ts +31 -10
- package/packages/telegram/src/TaskStore.ts +11 -1
- package/packages/telegram/src/TaskTool.ts +1 -1
- package/packages/telegram/src/UpdateConfirm.ts +2 -2
- package/packages/tui/src/extensions/_init/index.ts +2 -5
- package/packages/tui/src/extensions/file-picker/index.ts +2 -6
- package/packages/tui/src/extensions/footer/index.ts +0 -1
- package/packages/tui/src/extensions/footer/powerline.ts +16 -28
- package/packages/tui/src/extensions/pim/index.ts +1 -1
- package/packages/tui/src/extensions/session-lease/index.ts +5 -6
- package/packages/tui/src/extensions/working-indicator/index.ts +1 -2
- package/packages/tui/src/themes/themeCliArgs.ts +1 -1
- package/packages/web/dist/client/assets/{abnfDiagram-O67JEVCF-CZ7V84ot.js → abnfDiagram-O67JEVCF-w0u0UKcC.js} +1 -1
- package/packages/web/dist/client/assets/{arc-DiHGkUvc.js → arc-C8AeY-3C.js} +1 -1
- package/packages/web/dist/client/assets/architecture-7GRP2DOG-D-GDy9ga.js +1 -0
- package/packages/web/dist/client/assets/{architectureDiagram-NJMV4G6O-XS5DhfJB.js → architectureDiagram-NJMV4G6O-CLdCZfsP.js} +1 -1
- package/packages/web/dist/client/assets/{blockDiagram-BEXU5L5S-BCsgLvy1.js → blockDiagram-BEXU5L5S-BgAbOzdH.js} +1 -1
- package/packages/web/dist/client/assets/{c4Diagram-YGBWAQC7-Bj9LcWNm.js → c4Diagram-YGBWAQC7-DGRXXzDl.js} +1 -1
- package/packages/web/dist/client/assets/channel-BJtpIKaC.js +1 -0
- package/packages/web/dist/client/assets/{chunk-3FUC2YCW-BmDurFxp.js → chunk-3FUC2YCW-Dmz4_CY0.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-5DYCD2WN-DAjG-pqn.js → chunk-5DYCD2WN-D6q0r_NW.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-742MDFTN-Bmxs5puY.js → chunk-742MDFTN-biXvhzMn.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7INBJB4K-Di7kIxrQ.js → chunk-7INBJB4K-CtfPEr8P.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7M6MHVWA-CSc8sR0b.js → chunk-7M6MHVWA-CTixWKLk.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-7PRAP22T-C8kd5QvY.js → chunk-7PRAP22T-DijOiKl2.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-GTNCS2PH-DG2b2LYE.js → chunk-GTNCS2PH-DLId7dTl.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-GWA4HPMP-DdLaLQCu.js → chunk-GWA4HPMP-YUQxYmiu.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-MBY4JIJT-C1j0yQlk.js → chunk-MBY4JIJT-VWR3HSRr.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-NETBCI7D-Bfq9H74p.js → chunk-NETBCI7D-B8SeJoMY.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-O7XYJQB3-ZHvBmBO-.js → chunk-O7XYJQB3-CeLpEz0Q.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-UA2S7LBM-ku1JeHSK.js → chunk-UA2S7LBM-cBGKkXV_.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-WEXAMYUT-BP1iga_7.js → chunk-WEXAMYUT-BesXAOy9.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-XXDRQBXY-BBeccPcX.js → chunk-XXDRQBXY-DiuGUc8m.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-Z7XXMR3K-SMHZugaR.js → chunk-Z7XXMR3K-Dr2W5_t1.js} +1 -1
- package/packages/web/dist/client/assets/{chunk-ZIGJFQKS-CFU_JLG4.js → chunk-ZIGJFQKS-CwoMYXLJ.js} +1 -1
- package/packages/web/dist/client/assets/{classDiagram-v2-NBCMYWYE-CYviuQzJ.js → classDiagram-v2-NBCMYWYE-Gc3jAsDf.js} +1 -1
- package/packages/web/dist/client/assets/{core-DyHsgs5k.js → core-C27Q2ZSN.js} +1 -1
- package/packages/web/dist/client/assets/{cose-bilkent-JH36ORCC-9v2ZkJzo.js → cose-bilkent-JH36ORCC-ox5QohTH.js} +1 -1
- package/packages/web/dist/client/assets/{cynefin-OW5HDTMX-Bx5xRadi.js → cynefin-OW5HDTMX-CjQ-AjuJ.js} +1 -1
- package/packages/web/dist/client/assets/{cynefinDiagram-VND7K2PF-BRfGDKqa.js → cynefinDiagram-VND7K2PF-BVajmbbO.js} +1 -1
- package/packages/web/dist/client/assets/{dagre-6A5THRUB-C4l-2L2e.js → dagre-6A5THRUB-BtXhDxGN.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-22UHCM2B-d_hQ3kyi.js → diagram-22UHCM2B-DwjrV0H_.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-3UASUU5V-DrEeguPI.js → diagram-3UASUU5V-DQ1E_6hO.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-ATOU4E4O-BmfQ22pD.js → diagram-ATOU4E4O-wVYWlHRV.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-CDSNMT55-BjVWjuPF.js → diagram-CDSNMT55-CMlxHWMz.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-MLGK6HIB-wDjk-O8i.js → diagram-MLGK6HIB-Cbiwo7t9.js} +1 -1
- package/packages/web/dist/client/assets/{diagram-MPIPVDR6-DqXQFE1s.js → diagram-MPIPVDR6-Cv4zIyW1.js} +1 -1
- package/packages/web/dist/client/assets/{dist-BddGOpie.js → dist-Dl4GbwtH.js} +1 -1
- package/packages/web/dist/client/assets/{ebnfDiagram-ZINNZB2B-UB8kOITM.js → ebnfDiagram-ZINNZB2B-Bd8xl8W2.js} +1 -1
- package/packages/web/dist/client/assets/{elk-276RUBZZ-D4miYQnD.js → elk-276RUBZZ-DPRtUxgw.js} +1 -1
- package/packages/web/dist/client/assets/{erDiagram-OPXOYQCR--RXKv7KH.js → erDiagram-OPXOYQCR-BNoG4SxS.js} +1 -1
- package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-Dh9l6A3t.js +1 -0
- package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-DoJ97uSW.js +1 -0
- package/packages/web/dist/client/assets/{ganttDiagram-FUAMR5RP-C0CFpE5x.js → ganttDiagram-FUAMR5RP-BtFYI7uw.js} +1 -1
- package/packages/web/dist/client/assets/{gitGraph-4MIJSDKK-VPL7nv2c.js → gitGraph-4MIJSDKK-Di6RG5Kg.js} +1 -1
- package/packages/web/dist/client/assets/{gitGraphDiagram-X574FWY7-CgxJA-T8.js → gitGraphDiagram-X574FWY7-J4_JKGBH.js} +1 -1
- package/packages/web/dist/client/assets/index-BD7ptjuS.css +1 -0
- package/packages/web/dist/client/assets/{index-XTlTnQmx.js → index-Cn66jcLF.js} +7 -7
- package/packages/web/dist/client/assets/{info-A6RAGUB7-P0-o68pj.js → info-A6RAGUB7-wk6vNDP4.js} +1 -1
- package/packages/web/dist/client/assets/{infoDiagram-VRGFBTTK-DFJZNRUP.js → infoDiagram-VRGFBTTK-Zl7Uhlcj.js} +1 -1
- package/packages/web/dist/client/assets/{ishikawaDiagram-OU5B5YK6-ZkyhNd1T.js → ishikawaDiagram-OU5B5YK6-I0VVed8w.js} +1 -1
- package/packages/web/dist/client/assets/{journeyDiagram-ZHPQQLJL-DFevH8my.js → journeyDiagram-ZHPQQLJL-CLGZAy0Q.js} +1 -1
- package/packages/web/dist/client/assets/{kanban-definition-PNTS6WVX-l7e7ZZDC.js → kanban-definition-PNTS6WVX-D3Zv63YL.js} +1 -1
- package/packages/web/dist/client/assets/{line-DO_s6Ujd.js → line-C4_qzTJY.js} +1 -1
- package/packages/web/dist/client/assets/{linear-C4xH5PPc.js → linear-Dbp9FWGm.js} +1 -1
- package/packages/web/dist/client/assets/{mermaid-parser.core-nQaTP3VY.js → mermaid-parser.core-Cbd2Flfk.js} +3 -3
- package/packages/web/dist/client/assets/{mermaid.core-Cz05yTZh.js → mermaid.core-CPXk02t0.js} +4 -4
- package/packages/web/dist/client/assets/{mindmap-definition-NLK3R4M7-CHOEuHm2.js → mindmap-definition-NLK3R4M7-hcjd2vg0.js} +1 -1
- package/packages/web/dist/client/assets/{packet-AYTQ26CC-BH3ehPMo.js → packet-AYTQ26CC-CLiY7MdL.js} +1 -1
- package/packages/web/dist/client/assets/{pegDiagram-GJSIUBJH-CkWBLtad.js → pegDiagram-GJSIUBJH-Or6L-npJ.js} +1 -1
- package/packages/web/dist/client/assets/{pie-WAS4IAKB-nNVEq3dx.js → pie-WAS4IAKB-DTF5qxhB.js} +1 -1
- package/packages/web/dist/client/assets/{pieDiagram-5QR66LMP-DimUBAgN.js → pieDiagram-5QR66LMP-wDNyDsTs.js} +1 -1
- package/packages/web/dist/client/assets/{quadrantDiagram-O4NWA36T-BR0XpRGQ.js → quadrantDiagram-O4NWA36T-BL_0xWWi.js} +1 -1
- package/packages/web/dist/client/assets/{radar-RG4KPBEZ-paA-H3mb.js → radar-RG4KPBEZ-hK8uEd3E.js} +1 -1
- package/packages/web/dist/client/assets/{railroad-74A4TZTK-yEiKB3rz.js → railroad-74A4TZTK-Cj1mtGfH.js} +1 -1
- package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-t8ibqa0P.js +1 -0
- package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-B4RYlcUM.js +1 -0
- package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-DFqfvrfB.js +1 -0
- package/packages/web/dist/client/assets/{railroadDiagram-XR7U4H2S--TXe6rdU.js → railroadDiagram-XR7U4H2S-BUXe7pvJ.js} +1 -1
- package/packages/web/dist/client/assets/{requirementDiagram-PLB6GJNP-DyqH36Za.js → requirementDiagram-PLB6GJNP-DBnKurFY.js} +1 -1
- package/packages/web/dist/client/assets/{sankeyDiagram-IPEJSGJF-Bg6e3BlM.js → sankeyDiagram-IPEJSGJF-BDlSxPY7.js} +1 -1
- package/packages/web/dist/client/assets/{sequenceDiagram-PO4LG4MO-ClGf85My.js → sequenceDiagram-PO4LG4MO-BcKSq_cS.js} +1 -1
- package/packages/web/dist/client/assets/{src-DF7hQfMh.js → src-kcIgRrGC.js} +1 -1
- package/packages/web/dist/client/assets/{stateDiagram-v2-GCMORJYK-BK8TpxNo.js → stateDiagram-v2-GCMORJYK-D-1tpyK1.js} +1 -1
- package/packages/web/dist/client/assets/{swimlanes-2SLR337P-DDnTIT9M.js → swimlanes-2SLR337P-edQaMeEJ.js} +1 -1
- package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-vI6XtOyR.js +8 -0
- package/packages/web/dist/client/assets/{timeline-definition-EJHVYXUP-mBBbH3bk.js → timeline-definition-EJHVYXUP-BHspcgaG.js} +1 -1
- package/packages/web/dist/client/assets/{treeView-Q6P3EWNA-CTK7tRwR.js → treeView-Q6P3EWNA-Bvc71ryx.js} +1 -1
- package/packages/web/dist/client/assets/{treemap-WGGIJYW6-vOI-Ef_m.js → treemap-WGGIJYW6-CoZvoF_t.js} +1 -1
- package/packages/web/dist/client/assets/{usecaseDiagram-POWQR4AR-COcii8x-.js → usecaseDiagram-POWQR4AR-B203AiCD.js} +1 -1
- package/packages/web/dist/client/assets/{vennDiagram-UO4OBE2U-D6kmDGpM.js → vennDiagram-UO4OBE2U-Cia3spa9.js} +1 -1
- package/packages/web/dist/client/assets/{wardley-WFR3VGLG-CtE2KI9r.js → wardley-WFR3VGLG-C7qHTXAu.js} +1 -1
- package/packages/web/dist/client/assets/{wardleyDiagram-VNRHLVJA-ncxNGWnW.js → wardleyDiagram-VNRHLVJA-CK2R_SgC.js} +1 -1
- package/packages/web/dist/client/assets/{xychartDiagram-PMCCYNJV-DUvd2Qze.js → xychartDiagram-PMCCYNJV-BBLqtYJ_.js} +1 -1
- package/packages/web/dist/client/index.html +2 -2
- package/packages/web/dist/client/assets/architecture-7GRP2DOG-HIzEIkwQ.js +0 -1
- package/packages/web/dist/client/assets/channel-BCA6qe9I.js +0 -1
- package/packages/web/dist/client/assets/eventmodeling-NTZA5JFV-l6SYFw1s.js +0 -1
- package/packages/web/dist/client/assets/flowDiagram-KWPJA3E3-CWW9qnqm.js +0 -1
- package/packages/web/dist/client/assets/index-D9_XJLSc.css +0 -1
- package/packages/web/dist/client/assets/railroad-abnf-HS5TGJTU-mVQx9aVM.js +0 -1
- package/packages/web/dist/client/assets/railroad-ebnf-LZEXJU2U-CllXx1OJ.js +0 -1
- package/packages/web/dist/client/assets/railroad-peg-WCYAUIDC-BBD2Q5W_.js +0 -1
- package/packages/web/dist/client/assets/swimlanesDiagram-TC7HE7FX-CM8UnP5t.js +0 -8
|
@@ -28,7 +28,7 @@ export type ToolDiff = {
|
|
|
28
28
|
readonly hunks: readonly ToolDiffHunk[];
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
//
|
|
31
|
+
// The EOF newline is a flag, not an empty last line, or diffs gain a phantom blank line.
|
|
32
32
|
export type ToolDiffSide = {
|
|
33
33
|
readonly lines: readonly string[];
|
|
34
34
|
readonly hasTrailingNewline: boolean;
|
|
@@ -48,16 +48,11 @@ function buildToolDiff(
|
|
|
48
48
|
|
|
49
49
|
const lines = build(oldSide.lines, newSide.lines);
|
|
50
50
|
|
|
51
|
-
if (
|
|
51
|
+
if (lines.every((line) => line.kind === "context")) {
|
|
52
52
|
return undefined;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
path,
|
|
59
|
-
hunks: buildHunks(emphasized, contextSize),
|
|
60
|
-
};
|
|
55
|
+
return { path, hunks: buildHunks(attachEmphasis(lines), contextSize) };
|
|
61
56
|
}
|
|
62
57
|
|
|
63
58
|
function fromText(text: string): ToolDiffSide {
|
|
@@ -82,48 +77,35 @@ function attachEmphasis(
|
|
|
82
77
|
let i = 0;
|
|
83
78
|
|
|
84
79
|
while (i < result.length) {
|
|
85
|
-
if (result[i]
|
|
80
|
+
if (result[i]!.kind !== "removed") {
|
|
86
81
|
i += 1;
|
|
87
82
|
continue;
|
|
88
83
|
}
|
|
89
84
|
|
|
90
85
|
let removedEnd = i;
|
|
91
|
-
while (
|
|
92
|
-
removedEnd < result.length &&
|
|
93
|
-
result[removedEnd]?.kind === "removed"
|
|
94
|
-
) {
|
|
86
|
+
while (result[removedEnd]?.kind === "removed") {
|
|
95
87
|
removedEnd += 1;
|
|
96
88
|
}
|
|
97
|
-
|
|
98
89
|
let addedEnd = removedEnd;
|
|
99
|
-
while (
|
|
90
|
+
while (result[addedEnd]?.kind === "added") {
|
|
100
91
|
addedEnd += 1;
|
|
101
92
|
}
|
|
102
93
|
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
const added = result[removedEnd + k];
|
|
110
|
-
|
|
111
|
-
if (removed === undefined || added === undefined) {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
|
|
94
|
+
// Only pair lines when the removed and added runs are the same length.
|
|
95
|
+
const count = removedEnd - i;
|
|
96
|
+
if (count === addedEnd - removedEnd) {
|
|
97
|
+
for (let k = 0; k < count; k += 1) {
|
|
98
|
+
const removed = result[i + k]!;
|
|
99
|
+
const added = result[removedEnd + k]!;
|
|
115
100
|
const ranges = computeIntraLineRanges(removed.text, added.text);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
101
|
+
if (ranges !== undefined) {
|
|
102
|
+
result[i + k] = { ...removed, emphasis: ranges.removed };
|
|
103
|
+
result[removedEnd + k] = { ...added, emphasis: ranges.added };
|
|
119
104
|
}
|
|
120
|
-
|
|
121
|
-
result[i + k] = { ...removed, emphasis: ranges.removed };
|
|
122
|
-
result[removedEnd + k] = { ...added, emphasis: ranges.added };
|
|
123
105
|
}
|
|
124
106
|
}
|
|
125
107
|
|
|
126
|
-
i = addedEnd
|
|
108
|
+
i = addedEnd;
|
|
127
109
|
}
|
|
128
110
|
|
|
129
111
|
return result;
|
|
@@ -112,8 +112,7 @@ function backgroundsFor(theme: Theme): DiffBackgrounds {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
function isLightTheme(theme: Theme): boolean {
|
|
115
|
-
|
|
116
|
-
return name === "light" || name.includes("light");
|
|
115
|
+
return theme.name?.toLowerCase().includes("light") ?? false;
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
function renderHunk(
|
|
@@ -174,10 +173,6 @@ function applyEmphasis(
|
|
|
174
173
|
lineBg: string,
|
|
175
174
|
emphBg: string
|
|
176
175
|
): string {
|
|
177
|
-
if (ranges.length === 0) {
|
|
178
|
-
return text;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
176
|
const starts = new Set<number>();
|
|
182
177
|
const ends = new Set<number>();
|
|
183
178
|
|
|
@@ -192,6 +187,9 @@ function applyEmphasis(
|
|
|
192
187
|
return text;
|
|
193
188
|
}
|
|
194
189
|
|
|
190
|
+
const marker = (pos: number): string =>
|
|
191
|
+
(ends.has(pos) ? lineBg : "") + (starts.has(pos) ? emphBg : "");
|
|
192
|
+
|
|
195
193
|
let result = "";
|
|
196
194
|
let visiblePos = 0;
|
|
197
195
|
let i = 0;
|
|
@@ -209,16 +207,9 @@ function applyEmphasis(
|
|
|
209
207
|
continue;
|
|
210
208
|
}
|
|
211
209
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
if (ends.has(visiblePos)) {
|
|
217
|
-
result += lineBg;
|
|
218
|
-
}
|
|
219
|
-
if (starts.has(visiblePos)) {
|
|
220
|
-
result += emphBg;
|
|
221
|
-
}
|
|
210
|
+
const mark = marker(visiblePos);
|
|
211
|
+
if (mark !== "") {
|
|
212
|
+
result += text.slice(segStart, i) + mark;
|
|
222
213
|
segStart = i;
|
|
223
214
|
}
|
|
224
215
|
|
|
@@ -226,17 +217,7 @@ function applyEmphasis(
|
|
|
226
217
|
i += 1;
|
|
227
218
|
}
|
|
228
219
|
|
|
229
|
-
|
|
230
|
-
result += text.slice(segStart, i);
|
|
231
|
-
}
|
|
232
|
-
if (ends.has(visiblePos)) {
|
|
233
|
-
result += lineBg;
|
|
234
|
-
}
|
|
235
|
-
if (starts.has(visiblePos)) {
|
|
236
|
-
result += emphBg;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return result;
|
|
220
|
+
return result + text.slice(segStart) + marker(visiblePos);
|
|
240
221
|
}
|
|
241
222
|
|
|
242
223
|
function applyBackground(
|
|
@@ -10,11 +10,11 @@ export type DirectoryEntry = {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export type DirectoryListing = {
|
|
13
|
-
/**
|
|
13
|
+
/** Absolute, resolved, `~` expanded. */
|
|
14
14
|
readonly path: string;
|
|
15
|
-
/** Absent at the
|
|
15
|
+
/** Absent at the filesystem root. */
|
|
16
16
|
readonly parent?: string;
|
|
17
|
-
/**
|
|
17
|
+
/** Subdirectories only, name-sorted, hidden included. */
|
|
18
18
|
readonly entries: readonly DirectoryEntry[];
|
|
19
19
|
};
|
|
20
20
|
|
|
@@ -78,7 +78,7 @@ function refusal(error: unknown, path: string): string {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
/**
|
|
81
|
+
/** Not recursive: a missing parent is an error. */
|
|
82
82
|
async function create(path: string): Promise<void> {
|
|
83
83
|
const name = basename(Paths.expandHome(path));
|
|
84
84
|
if (name === "" || name === "." || name === "..") {
|
|
@@ -81,7 +81,9 @@ function resolve(
|
|
|
81
81
|
|
|
82
82
|
if (replaceAll) {
|
|
83
83
|
return {
|
|
84
|
-
ranges:
|
|
84
|
+
ranges: candidates
|
|
85
|
+
.map((candidate) => candidate.range)
|
|
86
|
+
.sort((left, right) => left[0] - right[0]),
|
|
85
87
|
strategy: strategy.name,
|
|
86
88
|
matchCount: candidates.length,
|
|
87
89
|
};
|
|
@@ -441,25 +443,10 @@ function unicodeNormalized({
|
|
|
441
443
|
content,
|
|
442
444
|
oldString,
|
|
443
445
|
}: MatchInput): readonly Candidate[] {
|
|
444
|
-
// normalizeUnicode
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
let index = 0;
|
|
449
|
-
|
|
450
|
-
while (true) {
|
|
451
|
-
const start = normalizedContent.indexOf(normalizedOld, index);
|
|
452
|
-
|
|
453
|
-
if (start === -1) {
|
|
454
|
-
break;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
const end = start + oldString.length;
|
|
458
|
-
candidates.push({ range: [start, end], text: content.slice(start, end) });
|
|
459
|
-
index = Math.max(start + 1, end);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
return candidates;
|
|
446
|
+
// normalizeUnicode must map 1:1 by UTF-16 code unit, or offsets desync.
|
|
447
|
+
return findAll(normalizeUnicode(content), normalizeUnicode(oldString)).map(
|
|
448
|
+
({ range }) => ({ range, text: content.slice(...range) })
|
|
449
|
+
);
|
|
463
450
|
}
|
|
464
451
|
|
|
465
452
|
function blockAnchor(input: MatchInput): readonly Candidate[] {
|
|
@@ -477,7 +464,7 @@ function blockAnchor(input: MatchInput): readonly Candidate[] {
|
|
|
477
464
|
) / middleCount;
|
|
478
465
|
}
|
|
479
466
|
|
|
480
|
-
//
|
|
467
|
+
// Rejects unrelated blocks that merely share first and last lines.
|
|
481
468
|
return similarity >= 0.3;
|
|
482
469
|
});
|
|
483
470
|
}
|
|
@@ -598,10 +585,6 @@ function dedupeCandidates(
|
|
|
598
585
|
return deduped;
|
|
599
586
|
}
|
|
600
587
|
|
|
601
|
-
function sortRanges(ranges: readonly EditRange[]): readonly EditRange[] {
|
|
602
|
-
return [...ranges].sort((left, right) => left[0] - right[0]);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
588
|
function logicalLines(content: string): readonly string[] {
|
|
606
589
|
if (content.length === 0) {
|
|
607
590
|
return [];
|
|
@@ -653,31 +636,17 @@ function offsetLines(content: string): readonly OffsetLine[] {
|
|
|
653
636
|
return lines;
|
|
654
637
|
}
|
|
655
638
|
|
|
639
|
+
const CONTROL_ESCAPES: Readonly<Record<string, string>> = {
|
|
640
|
+
n: "\n",
|
|
641
|
+
t: "\t",
|
|
642
|
+
r: "\r",
|
|
643
|
+
};
|
|
644
|
+
|
|
656
645
|
function unescapeString(text: string): string {
|
|
657
|
-
return text.replace(
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
case "t":
|
|
662
|
-
return "\t";
|
|
663
|
-
case "r":
|
|
664
|
-
return "\r";
|
|
665
|
-
case "'":
|
|
666
|
-
return "'";
|
|
667
|
-
case '"':
|
|
668
|
-
return '"';
|
|
669
|
-
case "`":
|
|
670
|
-
return "`";
|
|
671
|
-
case "\\":
|
|
672
|
-
return "\\";
|
|
673
|
-
case "\n":
|
|
674
|
-
return "\n";
|
|
675
|
-
case "$":
|
|
676
|
-
return "$";
|
|
677
|
-
default:
|
|
678
|
-
return match;
|
|
679
|
-
}
|
|
680
|
-
});
|
|
646
|
+
return text.replace(
|
|
647
|
+
/\\(n|t|r|'|"|`|\\|\n|\$)/gu,
|
|
648
|
+
(_, value: string) => CONTROL_ESCAPES[value] ?? value
|
|
649
|
+
);
|
|
681
650
|
}
|
|
682
651
|
|
|
683
652
|
function escapeSequences(text: string): readonly string[] {
|
|
@@ -763,5 +732,4 @@ export const EditMatcher = {
|
|
|
763
732
|
renderNotFound,
|
|
764
733
|
lineRangeFor,
|
|
765
734
|
NotFoundError,
|
|
766
|
-
MultipleMatchesError,
|
|
767
735
|
};
|
|
@@ -2,7 +2,7 @@ import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
|
|
|
2
2
|
|
|
3
3
|
import { PimSettings } from "./PimSettings";
|
|
4
4
|
|
|
5
|
-
// Pi's `enabled` filter
|
|
5
|
+
// Pi's `enabled` filter skips inline factories, so pim keeps its own roster.
|
|
6
6
|
const EXTENSIONS = {
|
|
7
7
|
_init: "Splash screen, runtime guard, /clear",
|
|
8
8
|
"apply-patch": "apply_patch tool",
|
|
@@ -34,8 +34,7 @@ const DEFAULT_DISABLED: readonly PimExtensionName[] = ["todo", "tps"];
|
|
|
34
34
|
|
|
35
35
|
const REQUIRED: readonly PimExtensionName[] = ["_init", "pim", "session-lease"];
|
|
36
36
|
|
|
37
|
-
//
|
|
38
|
-
// the label it gives them — the terminal menu names them by key, this does not.
|
|
37
|
+
// The only toggles the browser shows.
|
|
39
38
|
const WEB = [{ name: "todo", label: "Todo Tool" }] as const satisfies readonly {
|
|
40
39
|
name: PimExtensionName;
|
|
41
40
|
label: string;
|
|
@@ -53,7 +52,7 @@ function describe(name: PimExtensionName): string {
|
|
|
53
52
|
return EXTENSIONS[name];
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
//
|
|
55
|
+
// Checked inside the factory because pi re-runs factories on `ctx.reload()`.
|
|
57
56
|
function gate(
|
|
58
57
|
name: PimExtensionName,
|
|
59
58
|
factory: ExtensionFactory
|
|
@@ -79,7 +78,6 @@ async function isDisabled(name: string): Promise<boolean> {
|
|
|
79
78
|
return !enabled(name, toggles);
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
// Serialized: each call is a read-modify-write of the same record.
|
|
83
81
|
async function setDisabled(name: string, isOff: boolean): Promise<void> {
|
|
84
82
|
if (!isKnown(name)) {
|
|
85
83
|
throw new Error(`Unknown pim extension "${name}"`);
|
|
@@ -128,7 +126,6 @@ export const ExtensionToggles = {
|
|
|
128
126
|
NAMES,
|
|
129
127
|
WEB,
|
|
130
128
|
isRequired,
|
|
131
|
-
isKnown,
|
|
132
129
|
describe,
|
|
133
130
|
gate,
|
|
134
131
|
disabled,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readdir } from "node:fs/promises";
|
|
1
|
+
import { readdir, stat } from "node:fs/promises";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import ignore, { type Ignore } from "ignore";
|
|
4
4
|
|
|
@@ -86,8 +86,8 @@ function pushRules(out: string[], content: string): void {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
//
|
|
90
|
-
//
|
|
89
|
+
// Rewrites a nested .gitignore relative to the repo root. Slash-free patterns gain `**/`
|
|
90
|
+
// so they still match at any depth below their directory.
|
|
91
91
|
function reanchorRules(
|
|
92
92
|
content: string,
|
|
93
93
|
basePrefix: string,
|
|
@@ -122,10 +122,30 @@ function reanchorRules(
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
function addDirRules(
|
|
126
|
+
out: string[],
|
|
127
|
+
content: string,
|
|
128
|
+
dirAbs: string,
|
|
129
|
+
repoRootAbs: string
|
|
130
|
+
): void {
|
|
131
|
+
const dirRel = relFromBase(dirAbs, repoRootAbs);
|
|
132
|
+
if (dirRel === undefined || dirRel === "") {
|
|
133
|
+
pushRules(out, content);
|
|
134
|
+
} else {
|
|
135
|
+
reanchorRules(content, `${dirRel}/`, out);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
125
139
|
async function findRepoRoot(start: string): Promise<string | undefined> {
|
|
126
140
|
let dir = start;
|
|
127
141
|
for (;;) {
|
|
128
|
-
|
|
142
|
+
// `.git` is a directory in a normal repo and a file in a worktree.
|
|
143
|
+
if (
|
|
144
|
+
await stat(join(dir, ".git")).then(
|
|
145
|
+
() => true,
|
|
146
|
+
() => false
|
|
147
|
+
)
|
|
148
|
+
) {
|
|
129
149
|
return dir;
|
|
130
150
|
}
|
|
131
151
|
const parent = dirname(dir);
|
|
@@ -177,7 +197,7 @@ async function processDir(
|
|
|
177
197
|
if (ctx.useIgnore) {
|
|
178
198
|
const hasDotGit = entries.some((e) => e.name === ".git");
|
|
179
199
|
if (hasDotGit) {
|
|
180
|
-
// A
|
|
200
|
+
// A nested repo does not inherit its parent's rules.
|
|
181
201
|
inRepo = true;
|
|
182
202
|
repoRootAbs = currentDir.abs;
|
|
183
203
|
rules = await repoBaseRules(currentDir.abs, ctx.globalGitIgnore);
|
|
@@ -191,14 +211,8 @@ async function processDir(
|
|
|
191
211
|
join(currentDir.abs, ".gitignore")
|
|
192
212
|
);
|
|
193
213
|
if (content !== undefined) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (dirRel === undefined || dirRel === "") {
|
|
197
|
-
pushRules(next, content);
|
|
198
|
-
} else {
|
|
199
|
-
reanchorRules(content, `${dirRel}/`, next);
|
|
200
|
-
}
|
|
201
|
-
rules = next;
|
|
214
|
+
rules = rules.slice();
|
|
215
|
+
addDirRules(rules, content, currentDir.abs, repoRootAbs);
|
|
202
216
|
matcher = ignore().add(rules);
|
|
203
217
|
}
|
|
204
218
|
}
|
|
@@ -255,13 +269,11 @@ async function processDir(
|
|
|
255
269
|
|
|
256
270
|
if (entry.isFile() || isSymlink) {
|
|
257
271
|
ctx.result.push(relPath);
|
|
258
|
-
continue;
|
|
259
272
|
}
|
|
260
273
|
}
|
|
261
274
|
}
|
|
262
275
|
|
|
263
|
-
// Refill
|
|
264
|
-
// stack before any child was pushed and silently return a partial listing.
|
|
276
|
+
// Refill on each completion: fixed workers would exit early while the stack holds only the root.
|
|
265
277
|
function drain(ctx: WalkContext): Promise<void> {
|
|
266
278
|
let inFlight = 0;
|
|
267
279
|
return new Promise<void>((resolve, reject) => {
|
|
@@ -282,6 +294,41 @@ function drain(ctx: WalkContext): Promise<void> {
|
|
|
282
294
|
});
|
|
283
295
|
}
|
|
284
296
|
|
|
297
|
+
/** Rules from a repo strictly above `root`; `root`'s own .gitignore is read by processDir. */
|
|
298
|
+
async function enclosingRepo(
|
|
299
|
+
root: string,
|
|
300
|
+
globalGitIgnore: string | undefined
|
|
301
|
+
): Promise<
|
|
302
|
+
{ readonly repoRoot: string; readonly rules: string[] } | undefined
|
|
303
|
+
> {
|
|
304
|
+
const repoRoot = await findRepoRoot(root);
|
|
305
|
+
if (repoRoot === undefined || repoRoot === root) {
|
|
306
|
+
return undefined;
|
|
307
|
+
}
|
|
308
|
+
const rules = await repoBaseRules(repoRoot, globalGitIgnore);
|
|
309
|
+
|
|
310
|
+
// Shallowest first: gitignore precedence is by depth.
|
|
311
|
+
const intermediates: string[] = [];
|
|
312
|
+
let dir = dirname(root);
|
|
313
|
+
while (dir !== repoRoot && dir.length > repoRoot.length) {
|
|
314
|
+
intermediates.push(dir);
|
|
315
|
+
const parent = dirname(dir);
|
|
316
|
+
if (parent === dir) {
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
dir = parent;
|
|
320
|
+
}
|
|
321
|
+
intermediates.reverse();
|
|
322
|
+
|
|
323
|
+
for (const dirAbs of intermediates) {
|
|
324
|
+
const content = await readIgnoreFile(join(dirAbs, ".gitignore"));
|
|
325
|
+
if (content !== undefined) {
|
|
326
|
+
addDirRules(rules, content, dirAbs, repoRoot);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return { repoRoot, rules };
|
|
330
|
+
}
|
|
331
|
+
|
|
285
332
|
/** All files under `root` as root-relative POSIX paths; `.gitignore` is honored only inside a repo. */
|
|
286
333
|
async function enumerate(
|
|
287
334
|
root: string,
|
|
@@ -298,43 +345,9 @@ async function enumerate(
|
|
|
298
345
|
pathname === undefined ? undefined : await readIgnoreFile(pathname);
|
|
299
346
|
}
|
|
300
347
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
let initialRules: string[] = [];
|
|
305
|
-
if (useIgnore) {
|
|
306
|
-
const repoRoot = await findRepoRoot(root);
|
|
307
|
-
if (repoRoot !== undefined && repoRoot !== root) {
|
|
308
|
-
initialInRepo = true;
|
|
309
|
-
initialRepoRootAbs = repoRoot;
|
|
310
|
-
initialRules = await repoBaseRules(repoRoot, globalGitIgnore);
|
|
311
|
-
|
|
312
|
-
// Shallowest first: gitignore precedence is by depth.
|
|
313
|
-
const intermediates: string[] = [];
|
|
314
|
-
let dir = dirname(root);
|
|
315
|
-
while (dir !== repoRoot && dir.length > repoRoot.length) {
|
|
316
|
-
intermediates.push(dir);
|
|
317
|
-
const parent = dirname(dir);
|
|
318
|
-
if (parent === dir) {
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
dir = parent;
|
|
322
|
-
}
|
|
323
|
-
intermediates.reverse();
|
|
324
|
-
|
|
325
|
-
for (const dirAbs of intermediates) {
|
|
326
|
-
const content = await readIgnoreFile(join(dirAbs, ".gitignore"));
|
|
327
|
-
if (content !== undefined) {
|
|
328
|
-
const dirRel = relFromBase(dirAbs, repoRoot);
|
|
329
|
-
if (dirRel === undefined || dirRel === "") {
|
|
330
|
-
pushRules(initialRules, content);
|
|
331
|
-
} else {
|
|
332
|
-
reanchorRules(content, `${dirRel}/`, initialRules);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
348
|
+
const enclosing = useIgnore
|
|
349
|
+
? await enclosingRepo(root, globalGitIgnore)
|
|
350
|
+
: undefined;
|
|
338
351
|
|
|
339
352
|
const ctx: WalkContext = {
|
|
340
353
|
includeDotfiles,
|
|
@@ -344,10 +357,13 @@ async function enumerate(
|
|
|
344
357
|
{
|
|
345
358
|
abs: root,
|
|
346
359
|
rel: "",
|
|
347
|
-
inRepo:
|
|
348
|
-
repoRootAbs:
|
|
349
|
-
ignoreRules:
|
|
350
|
-
matcher:
|
|
360
|
+
inRepo: enclosing !== undefined,
|
|
361
|
+
repoRootAbs: enclosing?.repoRoot ?? root,
|
|
362
|
+
ignoreRules: enclosing?.rules ?? [],
|
|
363
|
+
matcher:
|
|
364
|
+
enclosing === undefined
|
|
365
|
+
? EMPTY_MATCHER
|
|
366
|
+
: ignore().add(enclosing.rules),
|
|
351
367
|
},
|
|
352
368
|
],
|
|
353
369
|
result: [],
|
|
@@ -21,19 +21,11 @@ async function scan(
|
|
|
21
21
|
});
|
|
22
22
|
const matcher = new Bun.Glob(await expandDirectory(absoluteRoot, pattern));
|
|
23
23
|
const excludes = GlobExclusions.compile(options.exclude);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
if (GlobExclusions.ignores(excludes, relativePath)) {
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
files.push(join(absoluteRoot, relativePath));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return files;
|
|
24
|
+
return relativePaths
|
|
25
|
+
.filter(
|
|
26
|
+
(path) => matcher.match(path) && !GlobExclusions.ignores(excludes, path)
|
|
27
|
+
)
|
|
28
|
+
.map((path) => join(absoluteRoot, path));
|
|
37
29
|
}
|
|
38
30
|
|
|
39
31
|
async function expandDirectory(
|
|
@@ -8,10 +8,7 @@ import { basename, dirname, join } from "node:path";
|
|
|
8
8
|
|
|
9
9
|
const POLL_MS = 1_000;
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* A burst coalesces into one event, and the read it triggers can land inside
|
|
13
|
-
* the burst — so look once more after it, or the last write waits on the poll.
|
|
14
|
-
*/
|
|
11
|
+
/** A burst arrives as one event, so look again shortly after to catch its last write. */
|
|
15
12
|
const SETTLE_MS = 25;
|
|
16
13
|
|
|
17
14
|
function signatureOf(path: string): string {
|
|
@@ -21,7 +18,7 @@ function signatureOf(path: string): string {
|
|
|
21
18
|
: `${stats.mtimeMs}:${stats.size}:${stats.ino}`;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
/**
|
|
21
|
+
/** Calls `onChange` only when the path's stat signature changed. */
|
|
25
22
|
function tracker(path: string, onChange: () => void): () => void {
|
|
26
23
|
let signature = signatureOf(path);
|
|
27
24
|
return (): void => {
|
|
@@ -34,11 +31,7 @@ function tracker(path: string, onChange: () => void): () => void {
|
|
|
34
31
|
};
|
|
35
32
|
}
|
|
36
33
|
|
|
37
|
-
/**
|
|
38
|
-
* `fs.watch` reports nothing at all on some filesystems and network mounts, so
|
|
39
|
-
* the poll beside it is not optional. The poll also re-arms the watcher, which
|
|
40
|
-
* a directory that does not exist yet refuses to give.
|
|
41
|
-
*/
|
|
34
|
+
/** `fs.watch` is silent on some filesystems, so a poll always runs too and re-arms a watcher that failed. */
|
|
42
35
|
function follow(
|
|
43
36
|
watched: string,
|
|
44
37
|
entry: string | undefined,
|
|
@@ -86,27 +79,31 @@ function follow(
|
|
|
86
79
|
};
|
|
87
80
|
}
|
|
88
81
|
|
|
89
|
-
/**
|
|
82
|
+
/** Watches the parent directory, so the file need not exist yet. `onLook` sees every stat, changed or not. */
|
|
90
83
|
function file(
|
|
91
84
|
path: string,
|
|
92
85
|
onChange: () => void,
|
|
93
|
-
pollMs: number = POLL_MS
|
|
86
|
+
pollMs: number = POLL_MS,
|
|
87
|
+
onLook?: () => void
|
|
94
88
|
): () => void {
|
|
95
|
-
const
|
|
89
|
+
const track = tracker(path, onChange);
|
|
90
|
+
const check = (): void => {
|
|
91
|
+
track();
|
|
92
|
+
onLook?.();
|
|
93
|
+
};
|
|
96
94
|
return follow(dirname(path), basename(path), check, check, pollMs);
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
/** Fires
|
|
97
|
+
/** Fires on entries added, removed or written. The poll only sees adds and removes. */
|
|
100
98
|
function directory(
|
|
101
99
|
path: string,
|
|
102
100
|
onChange: () => void,
|
|
103
101
|
pollMs: number = POLL_MS
|
|
104
102
|
): () => void {
|
|
105
|
-
// Writing a file moves nothing on the directory holding it, so the poll answers only for entries coming and going.
|
|
106
103
|
return follow(path, undefined, onChange, tracker(path, onChange), pollMs);
|
|
107
104
|
}
|
|
108
105
|
|
|
109
|
-
/**
|
|
106
|
+
/** Empty when `path` is missing. */
|
|
110
107
|
function subdirectories(path: string): readonly string[] {
|
|
111
108
|
try {
|
|
112
109
|
return readdirSync(path, { withFileTypes: true })
|
|
@@ -117,5 +114,4 @@ function subdirectories(path: string): readonly string[] {
|
|
|
117
114
|
}
|
|
118
115
|
}
|
|
119
116
|
|
|
120
|
-
/** Watching paths other processes write: an `fs.watch` that may do nothing, backed by a poll that always does. */
|
|
121
117
|
export const FileWatch = { file, directory, subdirectories };
|
|
@@ -26,7 +26,6 @@ function formatElapsed(ms: number): string {
|
|
|
26
26
|
: `${seconds}s`;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/** How full the context window reads, as a verdict each frontend colours. */
|
|
30
29
|
export type ContextFill = "ok" | "warn" | "full";
|
|
31
30
|
|
|
32
31
|
function contextFill(percent: number): ContextFill {
|
|
@@ -46,7 +45,7 @@ function scaleBytes(total: number): readonly [string, string] {
|
|
|
46
45
|
return [value.toFixed(2).replace(/\.?0+$/u, ""), unit];
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
/**
|
|
48
|
+
/** `40 bytes`, `240 KB`, `1.5 MB`. */
|
|
50
49
|
function bytes(total: number): string {
|
|
51
50
|
if (total < 1024) {
|
|
52
51
|
return `${total} bytes`;
|
|
@@ -55,7 +54,7 @@ function bytes(total: number): string {
|
|
|
55
54
|
return `${value} ${unit}`;
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
/**
|
|
57
|
+
/** `40B`, `240KB`, `1.5MB`. */
|
|
59
58
|
function bytesCompact(total: number): string {
|
|
60
59
|
if (total < 1024) {
|
|
61
60
|
return `${total}B`;
|