@cursor/july 0.1.30 → 0.1.32
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/AGENTS.md +1 -1
- package/README.md +10 -5
- package/dist/bin/agent-serve.js +4 -4
- package/dist/channels/github/index.d.ts +1 -1
- package/dist/channels/github/index.js +1 -1
- package/dist/channels/slack/bot-mentions.d.ts +1 -1
- package/dist/channels/slack/bot-mentions.d.ts.map +1 -1
- package/dist/channels/slack/bot-mentions.js +1 -1
- package/dist/channels/slack/eval-directive.js +1 -1
- package/dist/channels/slack/external-policy.d.ts +1 -1
- package/dist/channels/slack/external-policy.js +1 -1
- package/dist/channels/slack/log.d.ts +1 -1
- package/dist/channels/slack/log.js +1 -1
- package/dist/channels/slack/post-update-delivery.d.ts +85 -0
- package/dist/channels/slack/post-update-delivery.d.ts.map +1 -0
- package/dist/channels/slack/setup.js +1 -1
- package/dist/channels/slack/socket-mode.js +1 -1
- package/dist/docs/404.html +3 -3
- package/dist/docs/ab.html +11 -11
- package/dist/docs/assets/{ab.md.BMCZ6Hd7.js → ab.md.DAQoJ-up.js} +6 -6
- package/dist/docs/assets/{ab.md.BMCZ6Hd7.lean.js → ab.md.DAQoJ-up.lean.js} +1 -1
- package/dist/docs/assets/{app.Cm4lsMc4.js → app.C2aVczmo.js} +1 -1
- package/dist/docs/assets/building-with-agents.md.CnHqvYDd.js +13 -0
- package/dist/docs/assets/{building-with-agents.md.CJCtZCyi.lean.js → building-with-agents.md.CnHqvYDd.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.xgMnlUSO.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.CYUFXspH.js → VPLocalSearchBox.DLEzetbD.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CTjkX9vc.js → theme.BkOH1oMp.js} +2 -2
- package/dist/docs/assets/concepts.md.DFaQEFkA.js +4 -0
- package/dist/docs/assets/concepts.md.DFaQEFkA.lean.js +1 -0
- package/dist/docs/assets/deployment.md.9MYBuKM1.js +55 -0
- package/dist/docs/assets/deployment.md.9MYBuKM1.lean.js +1 -0
- package/dist/docs/assets/{evals.md.DYOjkRCX.js → evals.md.BIUoVZ6X.js} +13 -13
- package/dist/docs/assets/evals.md.BIUoVZ6X.lean.js +1 -0
- package/dist/docs/assets/{example-agents_approval-buddy.md.DFGBYLcc.js → example-agents_approval-buddy.md.BhEfleVx.js} +4 -4
- package/dist/docs/assets/{example-agents_approval-buddy.md.DFGBYLcc.lean.js → example-agents_approval-buddy.md.BhEfleVx.lean.js} +1 -1
- package/dist/docs/assets/example-agents_benny.md.2Et1qa8f.js +7 -0
- package/dist/docs/assets/{example-agents_bugbot.md.DelIdhxB.js → example-agents_bugbot.md.ByUexi5i.js} +5 -5
- package/dist/docs/assets/{example-agents_codebase-wiki.md.DC6sgwn0.js → example-agents_codebase-wiki.md.B4y-7ZVW.js} +6 -6
- package/dist/docs/assets/{example-agents_codebase-wiki.md.DC6sgwn0.lean.js → example-agents_codebase-wiki.md.B4y-7ZVW.lean.js} +1 -1
- package/dist/docs/assets/{example-agents_codeowners-review.md.Ku_tG2RY.js → example-agents_codeowners-review.md.D6ay4nvf.js} +6 -6
- package/dist/docs/assets/{example-agents_codeowners-review.md.Ku_tG2RY.lean.js → example-agents_codeowners-review.md.D6ay4nvf.lean.js} +1 -1
- package/dist/docs/assets/{example-agents_concierge.md.4rQTSMXt.js → example-agents_concierge.md.lL8rhYlj.js} +7 -7
- package/dist/docs/assets/{example-agents_fsd.md.CzgUrDfi.js → example-agents_fsd.md.DfNKQTHz.js} +5 -5
- package/dist/docs/assets/example-agents_index.md.DgGBwckv.js +2 -0
- package/dist/docs/assets/example-agents_index.md.DgGBwckv.lean.js +1 -0
- package/dist/docs/assets/{example-agents_knowledge-base.md.BPJiVueF.js → example-agents_knowledge-base.md.CzyZ2DCr.js} +5 -5
- package/dist/docs/assets/{example-agents_knowledge-base.md.BPJiVueF.lean.js → example-agents_knowledge-base.md.CzyZ2DCr.lean.js} +1 -1
- package/dist/docs/assets/example-agents_oncall.md.wFFXXEyW.js +10 -0
- package/dist/docs/assets/{example-agents_security-reviewer.md.Dhj_m7_B.js → example-agents_security-reviewer.md.Dkf1gyo6.js} +8 -8
- package/dist/docs/assets/example-agents_slack-agent.md.DvgvT4nn.js +5 -0
- package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.js +24 -0
- package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.lean.js +1 -0
- package/dist/docs/assets/{guides_agent-to-agent.md.Bpzgq2Pq.js → guides_agent-to-agent.md.Bmbxy-FA.js} +4 -4
- package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.js +9 -0
- package/dist/docs/assets/{guides_github.md.DOOCpqsW.js → guides_github.md.R2QlpR75.js} +5 -5
- package/dist/docs/assets/{guides_human-in-the-loop.md.DlUqsp1S.js → guides_human-in-the-loop.md.BWvT7UqY.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.Dd8EgSem.js → guides_mcp-oauth.md.C7G7IykG.js} +5 -5
- package/dist/docs/assets/guides_mcp-oauth.md.C7G7IykG.lean.js +1 -0
- package/dist/docs/assets/guides_slack.md.zriQpU_9.js +47 -0
- package/dist/docs/assets/guides_slack.md.zriQpU_9.lean.js +1 -0
- package/dist/docs/assets/{guides_webhooks.md.wSOYas3X.js → guides_webhooks.md.DiAwSR42.js} +1 -1
- package/dist/docs/assets/{hillclimbing.md.DHNast08.js → hillclimbing.md.D9Y1_bYh.js} +1 -1
- package/dist/docs/assets/index.md.CZqbBJPB.js +20 -0
- package/dist/docs/assets/index.md.CZqbBJPB.lean.js +1 -0
- package/dist/docs/assets/{quickstart.md.BU6Iwi_9.js → quickstart.md.TnEXYgYW.js} +12 -12
- package/dist/docs/assets/{reference_agent-config.md.DrW2JUM8.js → reference_agent-config.md.kuN6-OxK.js} +1 -1
- package/dist/docs/assets/reference_cli.md.sD-IUWjg.js +73 -0
- package/dist/docs/assets/{reference_cli.md.ccoKOoXt.lean.js → reference_cli.md.sD-IUWjg.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.B9Q3TOve.js → reference_connections.md.DGqAsFXb.js} +3 -3
- package/dist/docs/assets/reference_http-api.md.CfVM_ICa.js +11 -0
- package/dist/docs/assets/{reference_project-layout.md.Bd_CKtNS.js → reference_project-layout.md.D8E6ZmHJ.js} +4 -4
- package/dist/docs/assets/{reference_project-layout.md.Bd_CKtNS.lean.js → reference_project-layout.md.D8E6ZmHJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.w_F2mXB6.js → reference_schedules.md.gmfYzf_I.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.DLd6mvbv.js → reference_sessions.md.C_ouF_uf.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.BRSDnTbN.js → reference_tools.md.BswAQM41.js} +3 -3
- package/dist/docs/assets/{scaffolding-agents.md.C3pTrmoE.js → scaffolding-agents.md.Bsr9Pwzu.js} +1 -1
- package/dist/docs/assets/{scaffolding-agents.md.C3pTrmoE.lean.js → scaffolding-agents.md.Bsr9Pwzu.lean.js} +1 -1
- package/dist/docs/assets/{storage.md.DRTdnFvd.js → storage.md.xZoiGM58.js} +3 -3
- package/dist/docs/assets/storage.md.xZoiGM58.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.B5RVX_tL.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.CmQkmnzC.lean.js → troubleshooting.md.B5RVX_tL.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +12 -12
- package/dist/docs/concepts.html +6 -6
- package/dist/docs/deployment.html +32 -32
- package/dist/docs/evals.html +19 -19
- package/dist/docs/example-agents/approval-buddy.html +9 -9
- package/dist/docs/example-agents/benny.html +11 -11
- package/dist/docs/example-agents/bugbot.html +10 -10
- package/dist/docs/example-agents/codebase-wiki.html +11 -11
- package/dist/docs/example-agents/codeowners-review.html +11 -11
- package/dist/docs/example-agents/concierge.html +12 -12
- package/dist/docs/example-agents/fsd.html +10 -10
- package/dist/docs/example-agents/index.html +7 -7
- package/dist/docs/example-agents/knowledge-base.html +10 -10
- package/dist/docs/example-agents/oncall.html +10 -10
- package/dist/docs/example-agents/security-reviewer.html +13 -13
- package/dist/docs/example-agents/slack-agent.html +10 -10
- package/dist/docs/example-agents/weather-agent.html +16 -16
- package/dist/docs/guides/agent-to-agent.html +9 -9
- package/dist/docs/guides/cloud-runtime.html +7 -7
- package/dist/docs/guides/github.html +10 -10
- package/dist/docs/guides/human-in-the-loop.html +7 -7
- package/dist/docs/guides/mcp-oauth.html +11 -11
- package/dist/docs/guides/slack.html +22 -17
- package/dist/docs/guides/webhooks.html +7 -7
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +7 -7
- package/dist/docs/index.html +9 -9
- package/dist/docs/quickstart.html +17 -17
- package/dist/docs/reference/agent-config.html +7 -7
- package/dist/docs/reference/channels.html +5 -5
- package/dist/docs/reference/cli.html +56 -48
- package/dist/docs/reference/connections.html +9 -9
- package/dist/docs/reference/hooks.html +5 -5
- package/dist/docs/reference/http-api.html +7 -7
- package/dist/docs/reference/instructions.html +5 -5
- package/dist/docs/reference/playground.html +5 -5
- package/dist/docs/reference/project-layout.html +9 -9
- package/dist/docs/reference/prompt.html +5 -5
- package/dist/docs/reference/schedules.html +7 -7
- package/dist/docs/reference/sessions.html +8 -8
- package/dist/docs/reference/skills.html +5 -5
- package/dist/docs/reference/subagents.html +5 -5
- package/dist/docs/reference/tools.html +9 -9
- package/dist/docs/scaffolding-agents.html +6 -6
- package/dist/docs/storage.html +9 -9
- package/dist/docs/troubleshooting.html +6 -6
- package/dist/evals/reporters.d.ts +1 -1
- package/dist/evals/reporters.js +1 -1
- package/dist/evals.d.ts +2 -2
- package/dist/files-backends/agent-store-presigned-url.d.ts +3 -0
- package/dist/files-backends/agent-store-presigned-url.d.ts.map +1 -0
- package/dist/files-backends/agent-store-presigned-url.js +1023 -0
- package/dist/files-backends/cursor-hosted.d.ts +87 -0
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -0
- package/dist/files-backends/cursor-hosted.js +563 -0
- package/dist/files-backends/local-fs.d.ts +33 -0
- package/dist/files-backends/local-fs.d.ts.map +1 -0
- package/dist/files-backends/local-fs.js +199 -0
- package/dist/files.d.ts +139 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +89 -0
- package/dist/internal/ab-collector.js +2 -2
- package/dist/internal/ab-fold.js +1 -1
- package/dist/internal/cli-ax.d.ts +2 -2
- package/dist/internal/cli-ax.js +2 -2
- package/dist/internal/cli-deploy.d.ts +1 -1
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +7 -2
- package/dist/internal/cli-docs.d.ts +1 -1
- package/dist/internal/cli-docs.js +1 -1
- package/dist/internal/cli-github.js +13 -13
- package/dist/internal/cli-mcp-oauth.d.ts +1 -1
- package/dist/internal/cli-mcp-oauth.js +2 -2
- package/dist/internal/cli-mcp.d.ts +3 -3
- package/dist/internal/cli-mcp.js +4 -4
- package/dist/internal/cli-skills.js +1 -1
- package/dist/internal/cloud-turn-cost.d.ts +9 -1
- package/dist/internal/cloud-turn-cost.d.ts.map +1 -1
- package/dist/internal/cloud-turn-cost.js +14 -4
- package/dist/internal/cursor/account-mcp.js +5 -5
- package/dist/internal/cursor/backend-client.js +1 -1
- package/dist/internal/cursor/github-credentials.js +3 -3
- package/dist/internal/cursor-account-mcp-auth.d.ts +1 -1
- package/dist/internal/cursor-account-mcp-auth.js +1 -1
- package/dist/internal/cursor-event-relay.js +1 -1
- package/dist/internal/cursor-relay-core.d.ts +1 -1
- package/dist/internal/cursor-relay-core.d.ts.map +1 -1
- package/dist/internal/cursor-slack-relay.js +1 -1
- package/dist/internal/deploy-client.d.ts +6 -1
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +3 -2
- package/dist/internal/deploy-source.d.ts +2 -2
- package/dist/internal/deploy-source.js +2 -2
- package/dist/internal/discovery.js +2 -2
- package/dist/internal/distribution.d.ts +5 -5
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +6 -6
- package/dist/internal/docs-site.js +5 -5
- package/dist/internal/eval-run-store.js +8 -8
- package/dist/internal/evals-client.d.ts +1 -1
- package/dist/internal/evals-client.js +1 -1
- package/dist/internal/github-fanout.js +2 -2
- package/dist/internal/host-files.d.ts +29 -0
- package/dist/internal/host-files.d.ts.map +1 -0
- package/dist/internal/host-files.js +283 -0
- package/dist/internal/host-platforms.js +5 -5
- package/dist/internal/hosting.d.ts +1 -1
- package/dist/internal/hosting.js +1 -1
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +26 -0
- package/dist/internal/install-cursor-skills.d.ts +1 -1
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +33 -4
- package/dist/internal/json-dir-store.d.ts +32 -0
- package/dist/internal/json-dir-store.d.ts.map +1 -0
- package/dist/internal/local-control-plane.js +2 -2
- package/dist/internal/logs-client.d.ts +2 -2
- package/dist/internal/logs-client.js +2 -2
- package/dist/internal/mcp-endpoint.js +1 -1
- package/dist/internal/mcp-oauth.js +2 -2
- package/dist/internal/persistence-coordinator.d.ts +127 -0
- package/dist/internal/persistence-coordinator.d.ts.map +1 -0
- package/dist/internal/platform-schedule-sync.js +2 -2
- package/dist/internal/playground/toolchain.js +6 -6
- package/dist/internal/reminder-runner.js +13 -13
- package/dist/internal/resolved-connections.js +6 -6
- package/dist/internal/schedule-runner.js +1 -1
- package/dist/internal/sdk-runner.js +5 -5
- package/dist/internal/server.js +16 -16
- package/dist/internal/session-cost.d.ts +3 -2
- package/dist/internal/session-cost.d.ts.map +1 -1
- package/dist/internal/session-cost.js +7 -6
- package/dist/internal/session-engine.d.ts +31 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +119 -31
- package/dist/internal/slack-provision-client.js +1 -1
- package/dist/internal/storage-coordinator.js +7 -7
- package/dist/internal/trajectory.js +2 -2
- package/dist/internal/turn-cost.d.ts +27 -0
- package/dist/internal/turn-cost.d.ts.map +1 -0
- package/dist/internal/turn-cost.js +83 -0
- package/dist/internal/update-check.d.ts +3 -3
- package/dist/internal/update-check.d.ts.map +1 -1
- package/dist/internal/update-check.js +5 -5
- package/dist/memory.d.ts +1 -1
- package/dist/memory.js +1 -1
- package/dist/multi-tenant.d.ts +80 -0
- package/dist/multi-tenant.d.ts.map +1 -0
- package/dist/multi-tenant.js +69 -0
- package/dist/persistence.d.ts +184 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/playground/assets/index-50PKeJlG.css +1 -0
- package/dist/playground/assets/index-C0f2Wl1q.js +85 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +1 -1
- package/dist/types.d.ts +120 -16
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +23 -23
- package/docs/ab.md +12 -12
- package/docs/building-with-agents.md +9 -9
- package/docs/concepts.md +11 -11
- package/docs/deployment.md +55 -43
- package/docs/evals.md +20 -20
- package/docs/example-agents/approval-buddy.md +9 -9
- package/docs/example-agents/benny.md +13 -13
- package/docs/example-agents/bugbot.md +6 -6
- package/docs/example-agents/codebase-wiki.md +8 -8
- package/docs/example-agents/codeowners-review.md +8 -8
- package/docs/example-agents/concierge.md +10 -10
- package/docs/example-agents/fsd.md +7 -7
- package/docs/example-agents/index.md +8 -8
- package/docs/example-agents/knowledge-base.md +9 -9
- package/docs/example-agents/oncall.md +7 -7
- package/docs/example-agents/security-reviewer.md +12 -12
- package/docs/example-agents/slack-agent.md +10 -10
- package/docs/example-agents/weather-agent.md +30 -26
- package/docs/guides/agent-to-agent.md +4 -4
- package/docs/guides/cloud-runtime.md +3 -3
- package/docs/guides/github.md +6 -6
- package/docs/guides/human-in-the-loop.md +1 -1
- package/docs/guides/mcp-oauth.md +9 -9
- package/docs/guides/slack.md +94 -21
- package/docs/guides/webhooks.md +1 -1
- package/docs/hillclimbing.md +3 -3
- package/docs/quickstart.md +18 -18
- package/docs/reference/agent-config.md +1 -1
- package/docs/reference/cli.md +110 -79
- package/docs/reference/connections.md +3 -3
- package/docs/reference/http-api.md +2 -2
- package/docs/reference/project-layout.md +7 -7
- package/docs/reference/schedules.md +1 -1
- package/docs/reference/sessions.md +7 -7
- package/docs/reference/tools.md +3 -3
- package/docs/scaffolding-agents.md +2 -2
- package/docs/storage.md +5 -5
- package/docs/troubleshooting.md +11 -10
- package/package.json +5 -2
- package/skills/ab/SKILL.md +5 -5
- package/skills/create-agent/SKILL.md +17 -17
- package/skills/debug/SKILL.md +10 -10
- package/skills/evals/SKILL.md +13 -13
- package/skills/framework-map/SKILL.md +3 -3
- package/skills/github/SKILL.md +11 -11
- package/skills/hillclimb/SKILL.md +9 -9
- package/skills/mcp-auth/SKILL.md +11 -11
- package/skills/setup-slack/SKILL.md +28 -28
- package/src/bin/agent-serve.ts +4 -4
- package/src/channels/github/index.ts +1 -1
- package/src/channels/slack/bot-mentions.ts +1 -1
- package/src/channels/slack/eval-directive.ts +1 -1
- package/src/channels/slack/external-policy.ts +1 -1
- package/src/channels/slack/log.ts +1 -1
- package/src/channels/slack/setup.ts +1 -1
- package/src/channels/slack/socket-mode.ts +1 -1
- package/src/evals/reporters.ts +1 -1
- package/src/evals.ts +2 -2
- package/src/files-backends/agent-store-presigned-url.ts +8 -0
- package/src/files-backends/cursor-hosted.ts +724 -0
- package/src/files-backends/local-fs.ts +178 -0
- package/src/files.ts +195 -0
- package/src/internal/ab-collector.ts +2 -2
- package/src/internal/ab-fold.ts +1 -1
- package/src/internal/cli-ax.ts +2 -2
- package/src/internal/cli-deploy.ts +7 -2
- package/src/internal/cli-docs.ts +1 -1
- package/src/internal/cli-github.ts +13 -13
- package/src/internal/cli-mcp-oauth.ts +2 -2
- package/src/internal/cli-mcp.ts +4 -4
- package/src/internal/cli-skills.ts +1 -1
- package/src/internal/cloud-turn-cost.ts +20 -4
- package/src/internal/cursor/account-mcp.ts +5 -5
- package/src/internal/cursor/backend-client.ts +1 -1
- package/src/internal/cursor/github-credentials.ts +3 -3
- package/src/internal/cursor-account-mcp-auth.ts +1 -1
- package/src/internal/cursor-event-relay.ts +1 -1
- package/src/internal/cursor-relay-core.ts +1 -1
- package/src/internal/cursor-slack-relay.ts +1 -1
- package/src/internal/deploy-client.ts +8 -2
- package/src/internal/deploy-source.ts +2 -2
- package/src/internal/discovery.ts +2 -2
- package/src/internal/distribution.ts +6 -6
- package/src/internal/docs-site.ts +5 -5
- package/src/internal/eval-run-store.ts +8 -8
- package/src/internal/evals-client.ts +1 -1
- package/src/internal/github-fanout.ts +2 -2
- package/src/internal/host-files.ts +372 -0
- package/src/internal/host-platforms.ts +5 -5
- package/src/internal/hosting.ts +1 -1
- package/src/internal/http-channel.ts +30 -0
- package/src/internal/install-cursor-skills.ts +31 -3
- package/src/internal/local-control-plane.ts +2 -2
- package/src/internal/logs-client.ts +2 -2
- package/src/internal/mcp-endpoint.ts +1 -1
- package/src/internal/mcp-oauth.ts +2 -2
- package/src/internal/platform-schedule-sync.ts +2 -2
- package/src/internal/playground/toolchain.ts +6 -6
- package/src/internal/reminder-runner.ts +13 -13
- package/src/internal/resolved-connections.ts +6 -6
- package/src/internal/schedule-runner.ts +1 -1
- package/src/internal/sdk-runner.ts +5 -5
- package/src/internal/server.ts +16 -16
- package/src/internal/session-cost.ts +7 -6
- package/src/internal/session-engine.ts +141 -28
- package/src/internal/slack-provision-client.ts +1 -1
- package/src/internal/storage-coordinator.ts +7 -7
- package/src/internal/trajectory.ts +2 -2
- package/src/internal/turn-cost.ts +110 -0
- package/src/internal/update-check.ts +6 -6
- package/src/memory.ts +1 -1
- package/src/storage.ts +1 -1
- package/src/types.ts +148 -16
- package/dist/docs/assets/building-with-agents.md.CJCtZCyi.js +0 -13
- package/dist/docs/assets/chunks/@localSearchIndexroot.CbQshWFK.js +0 -1
- package/dist/docs/assets/concepts.md.Cfb9b-k1.js +0 -4
- package/dist/docs/assets/concepts.md.Cfb9b-k1.lean.js +0 -1
- package/dist/docs/assets/deployment.md.TecHo0_2.js +0 -55
- package/dist/docs/assets/deployment.md.TecHo0_2.lean.js +0 -1
- package/dist/docs/assets/evals.md.DYOjkRCX.lean.js +0 -1
- package/dist/docs/assets/example-agents_benny.md.B0gjhI-p.js +0 -7
- package/dist/docs/assets/example-agents_index.md.D2PEVSXl.js +0 -2
- package/dist/docs/assets/example-agents_index.md.D2PEVSXl.lean.js +0 -1
- package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.js +0 -10
- package/dist/docs/assets/example-agents_slack-agent.md.buLbgvBf.js +0 -5
- package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.js +0 -24
- package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.lean.js +0 -1
- package/dist/docs/assets/guides_cloud-runtime.md.gVzabdQL.js +0 -9
- package/dist/docs/assets/guides_mcp-oauth.md.Dd8EgSem.lean.js +0 -1
- package/dist/docs/assets/guides_slack.md.CjmJSvZS.js +0 -42
- package/dist/docs/assets/guides_slack.md.CjmJSvZS.lean.js +0 -1
- package/dist/docs/assets/index.md.CH_s5uZe.js +0 -20
- package/dist/docs/assets/index.md.CH_s5uZe.lean.js +0 -1
- package/dist/docs/assets/reference_cli.md.ccoKOoXt.js +0 -65
- package/dist/docs/assets/reference_http-api.md.BncLd3PZ.js +0 -11
- package/dist/docs/assets/storage.md.DRTdnFvd.lean.js +0 -1
- package/dist/docs/assets/troubleshooting.md.CmQkmnzC.js +0 -1
- package/dist/internal/model-pricing.d.ts +0 -49
- package/dist/internal/model-pricing.d.ts.map +0 -1
- package/dist/internal/model-pricing.js +0 -377
- package/dist/playground/assets/index-CquRB-l0.js +0 -85
- package/dist/playground/assets/index-Dj0bWpkn.css +0 -1
- package/src/internal/model-pricing.ts +0 -426
- /package/dist/docs/assets/{example-agents_benny.md.B0gjhI-p.lean.js → example-agents_benny.md.2Et1qa8f.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_bugbot.md.DelIdhxB.lean.js → example-agents_bugbot.md.ByUexi5i.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_concierge.md.4rQTSMXt.lean.js → example-agents_concierge.md.lL8rhYlj.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_fsd.md.CzgUrDfi.lean.js → example-agents_fsd.md.DfNKQTHz.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_oncall.md.BG_sUMly.lean.js → example-agents_oncall.md.wFFXXEyW.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_security-reviewer.md.Dhj_m7_B.lean.js → example-agents_security-reviewer.md.Dkf1gyo6.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_slack-agent.md.buLbgvBf.lean.js → example-agents_slack-agent.md.DvgvT4nn.lean.js} +0 -0
- /package/dist/docs/assets/{guides_agent-to-agent.md.Bpzgq2Pq.lean.js → guides_agent-to-agent.md.Bmbxy-FA.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-runtime.md.gVzabdQL.lean.js → guides_cloud-runtime.md.BZ2GA7Es.lean.js} +0 -0
- /package/dist/docs/assets/{guides_github.md.DOOCpqsW.lean.js → guides_github.md.R2QlpR75.lean.js} +0 -0
- /package/dist/docs/assets/{guides_human-in-the-loop.md.DlUqsp1S.lean.js → guides_human-in-the-loop.md.BWvT7UqY.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.wSOYas3X.lean.js → guides_webhooks.md.DiAwSR42.lean.js} +0 -0
- /package/dist/docs/assets/{hillclimbing.md.DHNast08.lean.js → hillclimbing.md.D9Y1_bYh.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.BU6Iwi_9.lean.js → quickstart.md.TnEXYgYW.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.DrW2JUM8.lean.js → reference_agent-config.md.kuN6-OxK.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.B9Q3TOve.lean.js → reference_connections.md.DGqAsFXb.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.BncLd3PZ.lean.js → reference_http-api.md.CfVM_ICa.lean.js} +0 -0
- /package/dist/docs/assets/{reference_schedules.md.w_F2mXB6.lean.js → reference_schedules.md.gmfYzf_I.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.DLd6mvbv.lean.js → reference_sessions.md.C_ouF_uf.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.BRSDnTbN.lean.js → reference_tools.md.BswAQM41.lean.js} +0 -0
|
@@ -0,0 +1,1023 @@
|
|
|
1
|
+
// ../../node_modules/.pnpm/@connectrpc+connect@1.6.1_patch_hash=c9c7616ccfc0246b19c6537f56676d8501713cb6c94b440d13_ef7275568c8b1f1f499006dc986c70d2/node_modules/@connectrpc/connect/dist/esm/code.js
|
|
2
|
+
var Code;
|
|
3
|
+
(function(Code2) {
|
|
4
|
+
Code2[Code2["Canceled"] = 1] = "Canceled";
|
|
5
|
+
Code2[Code2["Unknown"] = 2] = "Unknown";
|
|
6
|
+
Code2[Code2["InvalidArgument"] = 3] = "InvalidArgument";
|
|
7
|
+
Code2[Code2["DeadlineExceeded"] = 4] = "DeadlineExceeded";
|
|
8
|
+
Code2[Code2["NotFound"] = 5] = "NotFound";
|
|
9
|
+
Code2[Code2["AlreadyExists"] = 6] = "AlreadyExists";
|
|
10
|
+
Code2[Code2["PermissionDenied"] = 7] = "PermissionDenied";
|
|
11
|
+
Code2[Code2["ResourceExhausted"] = 8] = "ResourceExhausted";
|
|
12
|
+
Code2[Code2["FailedPrecondition"] = 9] = "FailedPrecondition";
|
|
13
|
+
Code2[Code2["Aborted"] = 10] = "Aborted";
|
|
14
|
+
Code2[Code2["OutOfRange"] = 11] = "OutOfRange";
|
|
15
|
+
Code2[Code2["Unimplemented"] = 12] = "Unimplemented";
|
|
16
|
+
Code2[Code2["Internal"] = 13] = "Internal";
|
|
17
|
+
Code2[Code2["Unavailable"] = 14] = "Unavailable";
|
|
18
|
+
Code2[Code2["DataLoss"] = 15] = "DataLoss";
|
|
19
|
+
Code2[Code2["Unauthenticated"] = 16] = "Unauthenticated";
|
|
20
|
+
})(Code || (Code = {}));
|
|
21
|
+
|
|
22
|
+
// ../agent-store-sync/dist/bcs-transport.js
|
|
23
|
+
var DIRECTORY_LIST_PAGE_SIZE = 1e3;
|
|
24
|
+
var DIRECTORY_LIST_MAX_PAGES = 10;
|
|
25
|
+
var DIRECTORY_LIST_MAX_ENTRIES = DIRECTORY_LIST_PAGE_SIZE * DIRECTORY_LIST_MAX_PAGES;
|
|
26
|
+
|
|
27
|
+
// ../agent-store-sync/dist/conflict-events.js
|
|
28
|
+
import * as fs2 from "node:fs";
|
|
29
|
+
|
|
30
|
+
// ../agent-store-sync/dist/paths.js
|
|
31
|
+
import * as fs from "node:fs";
|
|
32
|
+
import * as os from "node:os";
|
|
33
|
+
import * as path from "node:path";
|
|
34
|
+
var PRIVATE_DIR_MODE = 448;
|
|
35
|
+
var AgentStorePathError = class extends Error {
|
|
36
|
+
constructor({ code, message, failedPath }) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = "AgentStorePathError";
|
|
39
|
+
this.code = code;
|
|
40
|
+
this.failedPath = failedPath;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
function assertNoSymlinkInPath(targetPath, options = {}) {
|
|
44
|
+
const deps = getDeps(options);
|
|
45
|
+
const resolved = deps.path.resolve(targetPath);
|
|
46
|
+
const segments = getPathSegments(resolved, deps.path);
|
|
47
|
+
for (const segment of segments) {
|
|
48
|
+
const stat = tryLstat(segment, deps.fs);
|
|
49
|
+
if (!stat) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (stat.isSymbolicLink()) {
|
|
53
|
+
throw new AgentStorePathError({
|
|
54
|
+
code: "symlink_refused",
|
|
55
|
+
message: `Refusing to use symlinked agent store path: ${segment}`,
|
|
56
|
+
failedPath: segment
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function ensureSecureDirectoryChain(targetDir, options = {}) {
|
|
62
|
+
const deps = getDeps(options);
|
|
63
|
+
const resolvedTarget = deps.path.resolve(targetDir);
|
|
64
|
+
const trustedBase = options.trustedBase !== void 0 ? deps.path.resolve(options.trustedBase) : findTrustedDirectoryAncestor(resolvedTarget, deps);
|
|
65
|
+
if (resolvedTarget === trustedBase) {
|
|
66
|
+
assertRealDirectorySegment(trustedBase, deps);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const relative = deps.path.relative(trustedBase, resolvedTarget);
|
|
70
|
+
if (relative.length === 0 || relative.startsWith("..") || deps.path.isAbsolute(relative)) {
|
|
71
|
+
throw new AgentStorePathError({
|
|
72
|
+
code: "invalid_store_base",
|
|
73
|
+
message: `Refusing to create ${resolvedTarget} outside trusted base ${trustedBase}`,
|
|
74
|
+
failedPath: resolvedTarget
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const segments = relative.split(deps.path.sep).filter((segment) => segment.length > 0);
|
|
78
|
+
let current = trustedBase;
|
|
79
|
+
for (const segment of segments) {
|
|
80
|
+
assertRealDirectorySegment(current, deps);
|
|
81
|
+
current = deps.path.join(current, segment);
|
|
82
|
+
ensureRealDirectorySegment(current, deps);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function getDeps(options) {
|
|
86
|
+
var _a;
|
|
87
|
+
var _b, _c, _d, _e, _f, _g, _h;
|
|
88
|
+
return {
|
|
89
|
+
env: (_b = options.env) !== null && _b !== void 0 ? _b : process.env,
|
|
90
|
+
fs: (_c = options.fs) !== null && _c !== void 0 ? _c : fs,
|
|
91
|
+
geteuid: (_d = options.geteuid) !== null && _d !== void 0 ? _d : (_a = process.geteuid) === null || _a === void 0 ? void 0 : _a.bind(process),
|
|
92
|
+
osTmpdir: (_e = options.osTmpdir) !== null && _e !== void 0 ? _e : os.tmpdir,
|
|
93
|
+
path: (_f = options.path) !== null && _f !== void 0 ? _f : path,
|
|
94
|
+
platform: (_g = options.platform) !== null && _g !== void 0 ? _g : process.platform,
|
|
95
|
+
windowsAcl: (_h = options.windowsAcl) !== null && _h !== void 0 ? _h : {}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function assertDirectoryStat(targetPath, stat) {
|
|
99
|
+
if (stat.isSymbolicLink()) {
|
|
100
|
+
throw new AgentStorePathError({
|
|
101
|
+
code: "symlink_refused",
|
|
102
|
+
message: `Refusing to use symlinked agent store path: ${targetPath}`,
|
|
103
|
+
failedPath: targetPath
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (!stat.isDirectory()) {
|
|
107
|
+
throw new AgentStorePathError({
|
|
108
|
+
code: "not_directory",
|
|
109
|
+
message: `Agent store path is not a directory: ${targetPath}`,
|
|
110
|
+
failedPath: targetPath
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function findTrustedDirectoryAncestor(targetPath, deps) {
|
|
115
|
+
var _a;
|
|
116
|
+
const segments = getPathSegments(deps.path.resolve(targetPath), deps.path);
|
|
117
|
+
let trusted = (_a = segments[0]) !== null && _a !== void 0 ? _a : deps.path.resolve(targetPath);
|
|
118
|
+
for (let i = 1; i < segments.length; i++) {
|
|
119
|
+
const segment = segments[i];
|
|
120
|
+
const stat = tryLstat(segment, deps.fs);
|
|
121
|
+
if (!stat) {
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
if (stat.isSymbolicLink()) {
|
|
125
|
+
throw new AgentStorePathError({
|
|
126
|
+
code: "symlink_refused",
|
|
127
|
+
message: `Refusing to use symlinked agent store path: ${segment}`,
|
|
128
|
+
failedPath: segment
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (!stat.isDirectory()) {
|
|
132
|
+
throw new AgentStorePathError({
|
|
133
|
+
code: "not_directory",
|
|
134
|
+
message: `Agent store path is not a directory: ${segment}`,
|
|
135
|
+
failedPath: segment
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
trusted = segment;
|
|
139
|
+
}
|
|
140
|
+
return trusted;
|
|
141
|
+
}
|
|
142
|
+
function assertRealDirectorySegment(targetPath, deps) {
|
|
143
|
+
const stat = tryLstat(targetPath, deps.fs);
|
|
144
|
+
if (!stat) {
|
|
145
|
+
throw new AgentStorePathError({
|
|
146
|
+
code: "not_directory",
|
|
147
|
+
message: `Trusted directory does not exist: ${targetPath}`,
|
|
148
|
+
failedPath: targetPath
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
assertDirectoryStat(targetPath, stat);
|
|
152
|
+
}
|
|
153
|
+
function ensureRealDirectorySegment(targetPath, deps) {
|
|
154
|
+
let stat = tryLstat(targetPath, deps.fs);
|
|
155
|
+
if (!stat) {
|
|
156
|
+
try {
|
|
157
|
+
deps.fs.mkdirSync(targetPath, { mode: PRIVATE_DIR_MODE });
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (!isNodeError(error) || error.code !== "EEXIST") {
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
stat = tryLstat(targetPath, deps.fs);
|
|
164
|
+
if (!stat) {
|
|
165
|
+
throw new AgentStorePathError({
|
|
166
|
+
code: "not_directory",
|
|
167
|
+
message: `Failed to create directory: ${targetPath}`,
|
|
168
|
+
failedPath: targetPath
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
assertDirectoryStat(targetPath, stat);
|
|
173
|
+
}
|
|
174
|
+
function getPathSegments(targetPath, pathModule) {
|
|
175
|
+
const root = pathModule.parse(targetPath).root;
|
|
176
|
+
const rest = targetPath.slice(root.length);
|
|
177
|
+
const parts = rest.split(/[\\/]+/).filter(Boolean);
|
|
178
|
+
const segments = [];
|
|
179
|
+
let current = root;
|
|
180
|
+
if (root) {
|
|
181
|
+
segments.push(root);
|
|
182
|
+
}
|
|
183
|
+
for (const part of parts) {
|
|
184
|
+
current = current === root ? pathModule.join(root, part) : pathModule.join(current, part);
|
|
185
|
+
segments.push(current);
|
|
186
|
+
}
|
|
187
|
+
return segments;
|
|
188
|
+
}
|
|
189
|
+
function tryLstat(targetPath, fsModule) {
|
|
190
|
+
try {
|
|
191
|
+
return fsModule.lstatSync(targetPath);
|
|
192
|
+
} catch (err) {
|
|
193
|
+
if (isNodeError(err) && err.code === "ENOENT") {
|
|
194
|
+
return void 0;
|
|
195
|
+
}
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function isNodeError(err) {
|
|
200
|
+
return err instanceof Error && typeof err.code === "string";
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ../agent-store-sync/dist/conflict-events.js
|
|
204
|
+
var CONFLICT_JOURNAL_ROTATE_BYTES = 4 * 1024 * 1024;
|
|
205
|
+
var O_NOFOLLOW_FLAG = fs2.constants.O_NOFOLLOW;
|
|
206
|
+
|
|
207
|
+
// ../agent-store-sync/dist/local-index.js
|
|
208
|
+
import * as fs4 from "node:fs";
|
|
209
|
+
import * as path3 from "node:path";
|
|
210
|
+
|
|
211
|
+
// ../agent-store-sync/dist/secure-open.js
|
|
212
|
+
import * as fs3 from "node:fs";
|
|
213
|
+
import * as path2 from "node:path";
|
|
214
|
+
function openSecureSqlitePath(resolvedPath, mode) {
|
|
215
|
+
const parentDir = path2.dirname(resolvedPath);
|
|
216
|
+
const parentDirFd = openParentDirectoryNoFollow(parentDir);
|
|
217
|
+
let cleanupParentFd = true;
|
|
218
|
+
try {
|
|
219
|
+
const parentStat = fs3.fstatSync(parentDirFd);
|
|
220
|
+
if (!parentStat.isDirectory()) {
|
|
221
|
+
throw new AgentStorePathError({
|
|
222
|
+
code: "symlink_refused",
|
|
223
|
+
message: `Refusing to open sqlite under non-directory parent: ${parentDir}`,
|
|
224
|
+
failedPath: parentDir
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
const parentIdentity = {
|
|
228
|
+
dev: parentStat.dev,
|
|
229
|
+
ino: parentStat.ino
|
|
230
|
+
};
|
|
231
|
+
assertParentDirInodeMatchesPath(parentIdentity, parentDir);
|
|
232
|
+
const leafFd = openRegularFileNoFollowCreate(resolvedPath, mode);
|
|
233
|
+
let leafIdentity;
|
|
234
|
+
try {
|
|
235
|
+
const leafStat = fs3.fstatSync(leafFd);
|
|
236
|
+
if (!leafStat.isFile()) {
|
|
237
|
+
throw new AgentStorePathError({
|
|
238
|
+
code: "symlink_refused",
|
|
239
|
+
message: `Refusing to open non-regular sqlite path: ${resolvedPath}`,
|
|
240
|
+
failedPath: resolvedPath
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
assertResolvedPathStillCanonical(resolvedPath);
|
|
244
|
+
leafIdentity = { dev: leafStat.dev, ino: leafStat.ino };
|
|
245
|
+
} finally {
|
|
246
|
+
fs3.closeSync(leafFd);
|
|
247
|
+
}
|
|
248
|
+
let verified = false;
|
|
249
|
+
let closed = false;
|
|
250
|
+
const closeParent = () => {
|
|
251
|
+
if (closed) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
closed = true;
|
|
255
|
+
fs3.closeSync(parentDirFd);
|
|
256
|
+
};
|
|
257
|
+
const verifyOpenedInode = () => {
|
|
258
|
+
if (verified) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
assertParentDirInodeMatchesPath(parentIdentity, parentDir);
|
|
262
|
+
assertLeafInodeUnchanged(resolvedPath, leafIdentity);
|
|
263
|
+
verified = true;
|
|
264
|
+
};
|
|
265
|
+
cleanupParentFd = false;
|
|
266
|
+
return {
|
|
267
|
+
sqlitePath: resolvedPath,
|
|
268
|
+
verifyOpenedInode,
|
|
269
|
+
close: closeParent
|
|
270
|
+
};
|
|
271
|
+
} finally {
|
|
272
|
+
if (cleanupParentFd) {
|
|
273
|
+
fs3.closeSync(parentDirFd);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function openRegularFileNoFollowCreate(filePath, mode) {
|
|
278
|
+
const flags = symlinkSafeOpenCreateFlags();
|
|
279
|
+
try {
|
|
280
|
+
return fs3.openSync(filePath, flags, mode);
|
|
281
|
+
} catch (error) {
|
|
282
|
+
if (isNofollowSymlinkRefusal(error)) {
|
|
283
|
+
throw new AgentStorePathError({
|
|
284
|
+
code: "symlink_refused",
|
|
285
|
+
message: `Refusing to open symlinked path: ${filePath}`,
|
|
286
|
+
failedPath: filePath
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function openParentDirectoryNoFollow(parentDir) {
|
|
293
|
+
const flags = symlinkSafeDirectoryOpenFlags();
|
|
294
|
+
try {
|
|
295
|
+
return fs3.openSync(parentDir, flags);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
if (isNofollowSymlinkRefusal(error) || isNodeError2(error) && error.code === "ENOTDIR" && isSymlink(parentDir)) {
|
|
298
|
+
throw new AgentStorePathError({
|
|
299
|
+
code: "symlink_refused",
|
|
300
|
+
message: `Refusing to open sqlite under symlinked parent: ${parentDir}`,
|
|
301
|
+
failedPath: parentDir
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function isSymlink(targetPath) {
|
|
308
|
+
try {
|
|
309
|
+
return fs3.lstatSync(targetPath).isSymbolicLink();
|
|
310
|
+
} catch (_a) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function assertResolvedPathStillCanonical(resolvedPath) {
|
|
315
|
+
let realpath;
|
|
316
|
+
try {
|
|
317
|
+
realpath = fs3.realpathSync.native(resolvedPath);
|
|
318
|
+
} catch (error) {
|
|
319
|
+
throw new AgentStorePathError({
|
|
320
|
+
code: "symlink_refused",
|
|
321
|
+
message: `Unable to resolve realpath for ${resolvedPath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
322
|
+
failedPath: resolvedPath
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
if (realpath !== resolvedPath) {
|
|
326
|
+
throw new AgentStorePathError({
|
|
327
|
+
code: "symlink_refused",
|
|
328
|
+
message: `Refusing path with symlinked parent: ${resolvedPath} -> ${realpath}`,
|
|
329
|
+
failedPath: resolvedPath
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function assertLeafInodeUnchanged(resolvedPath, expected) {
|
|
334
|
+
const flags = symlinkSafeReopenFlags();
|
|
335
|
+
let fd;
|
|
336
|
+
try {
|
|
337
|
+
fd = fs3.openSync(resolvedPath, flags);
|
|
338
|
+
} catch (error) {
|
|
339
|
+
if (isNofollowSymlinkRefusal(error)) {
|
|
340
|
+
throw new AgentStorePathError({
|
|
341
|
+
code: "symlink_refused",
|
|
342
|
+
message: `Sqlite path became symlinked between open and verification: ${resolvedPath}`,
|
|
343
|
+
failedPath: resolvedPath
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
throw error;
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
const stat = fs3.fstatSync(fd);
|
|
350
|
+
assertResolvedPathStillCanonical(resolvedPath);
|
|
351
|
+
if (stat.dev !== expected.dev || stat.ino !== expected.ino) {
|
|
352
|
+
throw new AgentStorePathError({
|
|
353
|
+
code: "symlink_refused",
|
|
354
|
+
message: `Sqlite path inode drifted between open and verification (expected dev=${expected.dev} ino=${expected.ino}, got dev=${stat.dev} ino=${stat.ino}): ${resolvedPath}`,
|
|
355
|
+
failedPath: resolvedPath
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
} finally {
|
|
359
|
+
fs3.closeSync(fd);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function assertParentDirInodeMatchesPath(expected, parentDir) {
|
|
363
|
+
let pathStat;
|
|
364
|
+
try {
|
|
365
|
+
pathStat = fs3.lstatSync(parentDir);
|
|
366
|
+
} catch (error) {
|
|
367
|
+
throw new AgentStorePathError({
|
|
368
|
+
code: "symlink_refused",
|
|
369
|
+
message: `Unable to lstat parent directory ${parentDir}: ${error instanceof Error ? error.message : String(error)}`,
|
|
370
|
+
failedPath: parentDir
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
if (pathStat.isSymbolicLink()) {
|
|
374
|
+
throw new AgentStorePathError({
|
|
375
|
+
code: "symlink_refused",
|
|
376
|
+
message: `Parent directory became symlinked between open and verification: ${parentDir}`,
|
|
377
|
+
failedPath: parentDir
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
if (pathStat.dev !== expected.dev || pathStat.ino !== expected.ino) {
|
|
381
|
+
throw new AgentStorePathError({
|
|
382
|
+
code: "symlink_refused",
|
|
383
|
+
message: `Parent directory inode drifted between open and verification (expected dev=${expected.dev} ino=${expected.ino}, got dev=${pathStat.dev} ino=${pathStat.ino}): ${parentDir}`,
|
|
384
|
+
failedPath: parentDir
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function symlinkSafeOpenCreateFlags() {
|
|
389
|
+
var _a;
|
|
390
|
+
const constants3 = fs3.constants;
|
|
391
|
+
let flags = (_a = constants3.O_RDWR) !== null && _a !== void 0 ? _a : 0;
|
|
392
|
+
if (typeof constants3.O_CREAT === "number") {
|
|
393
|
+
flags |= constants3.O_CREAT;
|
|
394
|
+
}
|
|
395
|
+
if (typeof constants3.O_NOFOLLOW === "number") {
|
|
396
|
+
flags |= constants3.O_NOFOLLOW;
|
|
397
|
+
}
|
|
398
|
+
if (typeof constants3.O_CLOEXEC === "number") {
|
|
399
|
+
flags |= constants3.O_CLOEXEC;
|
|
400
|
+
}
|
|
401
|
+
return flags;
|
|
402
|
+
}
|
|
403
|
+
function symlinkSafeReopenFlags() {
|
|
404
|
+
var _a;
|
|
405
|
+
const constants3 = fs3.constants;
|
|
406
|
+
let flags = (_a = constants3.O_RDONLY) !== null && _a !== void 0 ? _a : 0;
|
|
407
|
+
if (typeof constants3.O_NOFOLLOW === "number") {
|
|
408
|
+
flags |= constants3.O_NOFOLLOW;
|
|
409
|
+
}
|
|
410
|
+
if (typeof constants3.O_CLOEXEC === "number") {
|
|
411
|
+
flags |= constants3.O_CLOEXEC;
|
|
412
|
+
}
|
|
413
|
+
return flags;
|
|
414
|
+
}
|
|
415
|
+
function symlinkSafeDirectoryOpenFlags() {
|
|
416
|
+
var _a;
|
|
417
|
+
const constants3 = fs3.constants;
|
|
418
|
+
let flags = (_a = constants3.O_RDONLY) !== null && _a !== void 0 ? _a : 0;
|
|
419
|
+
if (typeof constants3.O_DIRECTORY === "number") {
|
|
420
|
+
flags |= constants3.O_DIRECTORY;
|
|
421
|
+
}
|
|
422
|
+
if (typeof constants3.O_NOFOLLOW === "number") {
|
|
423
|
+
flags |= constants3.O_NOFOLLOW;
|
|
424
|
+
}
|
|
425
|
+
if (typeof constants3.O_CLOEXEC === "number") {
|
|
426
|
+
flags |= constants3.O_CLOEXEC;
|
|
427
|
+
}
|
|
428
|
+
return flags;
|
|
429
|
+
}
|
|
430
|
+
function isNofollowSymlinkRefusal(error) {
|
|
431
|
+
if (!isNodeError2(error)) {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
if (error.code === "ELOOP" || error.code === "EMLINK") {
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
if (error.code === "EPERM" && hasNofollowConstant()) {
|
|
438
|
+
return true;
|
|
439
|
+
}
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
function hasNofollowConstant() {
|
|
443
|
+
return typeof fs3.constants.O_NOFOLLOW === "number";
|
|
444
|
+
}
|
|
445
|
+
function isNodeError2(error) {
|
|
446
|
+
return error instanceof Error && typeof error.code === "string";
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// ../agent-store-sync/dist/local-index.js
|
|
450
|
+
var CURRENT_SCHEMA_VERSION = 3;
|
|
451
|
+
var PRIVATE_FILE_MODE = 384;
|
|
452
|
+
var META_DELETION_ARMED = "deletion_armed";
|
|
453
|
+
var META_FILES_ROOT_DEV = "files_root_dev";
|
|
454
|
+
var META_FILES_ROOT_INO = "files_root_ino";
|
|
455
|
+
var LocalIndexError = class extends Error {
|
|
456
|
+
constructor(code, message) {
|
|
457
|
+
super(message);
|
|
458
|
+
this.code = code;
|
|
459
|
+
this.name = "LocalIndexError";
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
var LocalAgentStoreIndex = class _LocalAgentStoreIndex {
|
|
463
|
+
static open(indexPath, options) {
|
|
464
|
+
const resolvedPath = path3.resolve(indexPath);
|
|
465
|
+
const existing = _LocalAgentStoreIndex.openHandles.get(resolvedPath);
|
|
466
|
+
if (existing !== void 0 && !existing.closed) {
|
|
467
|
+
return existing;
|
|
468
|
+
}
|
|
469
|
+
assertNoSymlinkInPath(resolvedPath);
|
|
470
|
+
ensureSecureDirectoryChain(path3.dirname(resolvedPath));
|
|
471
|
+
assertNoSymlinkInPath(resolvedPath);
|
|
472
|
+
const opened = openSecureSqlitePath(resolvedPath, PRIVATE_FILE_MODE);
|
|
473
|
+
let db;
|
|
474
|
+
try {
|
|
475
|
+
db = new options.sqlite(opened.sqlitePath);
|
|
476
|
+
opened.verifyOpenedInode();
|
|
477
|
+
restrictIndexFileModes(resolvedPath);
|
|
478
|
+
const index = new _LocalAgentStoreIndex(resolvedPath, db);
|
|
479
|
+
index.opened = opened;
|
|
480
|
+
index.migrate();
|
|
481
|
+
index.restrictFileModes();
|
|
482
|
+
_LocalAgentStoreIndex.openHandles.set(resolvedPath, index);
|
|
483
|
+
return index;
|
|
484
|
+
} catch (error) {
|
|
485
|
+
db === null || db === void 0 ? void 0 : db.close();
|
|
486
|
+
opened.close();
|
|
487
|
+
throw error;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
constructor(indexPath, db) {
|
|
491
|
+
this.indexPath = indexPath;
|
|
492
|
+
this.db = db;
|
|
493
|
+
this.closed = false;
|
|
494
|
+
}
|
|
495
|
+
close() {
|
|
496
|
+
var _a;
|
|
497
|
+
if (this.closed) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
this.db.close();
|
|
501
|
+
(_a = this.opened) === null || _a === void 0 ? void 0 : _a.close();
|
|
502
|
+
this.opened = void 0;
|
|
503
|
+
this.closed = true;
|
|
504
|
+
_LocalAgentStoreIndex.openHandles.delete(this.indexPath);
|
|
505
|
+
}
|
|
506
|
+
getFile(relPath) {
|
|
507
|
+
const row = this.db.prepare("SELECT rel_path, last_synced_sha, last_seen_etag, size, last_synced_ms, direction, state, tombstone_etag, deleted_at_ms FROM files WHERE rel_path = ?").get(relPath);
|
|
508
|
+
return row === void 0 ? void 0 : fileEntryFromRow(row);
|
|
509
|
+
}
|
|
510
|
+
listFiles() {
|
|
511
|
+
const rows = this.db.prepare("SELECT rel_path, last_synced_sha, last_seen_etag, size, last_synced_ms, direction, state, tombstone_etag, deleted_at_ms FROM files ORDER BY rel_path ASC").all();
|
|
512
|
+
return rows.map(fileEntryFromRow);
|
|
513
|
+
}
|
|
514
|
+
upsertFile(entry) {
|
|
515
|
+
var _a, _b;
|
|
516
|
+
const state = (_a = entry.state) !== null && _a !== void 0 ? _a : "live";
|
|
517
|
+
const tombstoneEtag = state === "tombstoned" ? entry.tombstoneEtag : null;
|
|
518
|
+
const deletedAtMs = state === "tombstoned" ? entry.deletedAtMs : null;
|
|
519
|
+
this.db.prepare(`
|
|
520
|
+
INSERT INTO files (
|
|
521
|
+
rel_path,
|
|
522
|
+
last_synced_sha,
|
|
523
|
+
last_seen_etag,
|
|
524
|
+
size,
|
|
525
|
+
last_synced_ms,
|
|
526
|
+
direction,
|
|
527
|
+
state,
|
|
528
|
+
tombstone_etag,
|
|
529
|
+
deleted_at_ms
|
|
530
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
531
|
+
ON CONFLICT(rel_path) DO UPDATE SET
|
|
532
|
+
last_synced_sha = excluded.last_synced_sha,
|
|
533
|
+
last_seen_etag = excluded.last_seen_etag,
|
|
534
|
+
size = excluded.size,
|
|
535
|
+
last_synced_ms = excluded.last_synced_ms,
|
|
536
|
+
direction = excluded.direction,
|
|
537
|
+
state = excluded.state,
|
|
538
|
+
tombstone_etag = excluded.tombstone_etag,
|
|
539
|
+
deleted_at_ms = excluded.deleted_at_ms
|
|
540
|
+
`).run(entry.relPath, entry.lastSyncedSha, (_b = entry.lastSeenEtag) !== null && _b !== void 0 ? _b : null, entry.size, entry.lastSyncedMs, entry.direction, state, tombstoneEtag !== null && tombstoneEtag !== void 0 ? tombstoneEtag : null, deletedAtMs !== null && deletedAtMs !== void 0 ? deletedAtMs : null);
|
|
541
|
+
this.restrictFileModes();
|
|
542
|
+
}
|
|
543
|
+
listPendingDeletes() {
|
|
544
|
+
const rows = this.db.prepare("SELECT rel_path, base_etag, requested_at_ms, mutation_id FROM pending_deletes ORDER BY rel_path ASC").all();
|
|
545
|
+
return rows.map((row) => {
|
|
546
|
+
var _a;
|
|
547
|
+
return {
|
|
548
|
+
relPath: row.rel_path,
|
|
549
|
+
baseEtag: row.base_etag,
|
|
550
|
+
requestedAtMs: row.requested_at_ms,
|
|
551
|
+
mutationId: (_a = row.mutation_id) !== null && _a !== void 0 ? _a : void 0
|
|
552
|
+
};
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
hasPendingDelete(relPath) {
|
|
556
|
+
const row = this.db.prepare("SELECT rel_path FROM pending_deletes WHERE rel_path = ?").get(relPath);
|
|
557
|
+
return row !== void 0;
|
|
558
|
+
}
|
|
559
|
+
upsertPendingDelete(entry) {
|
|
560
|
+
var _a;
|
|
561
|
+
this.db.prepare(`
|
|
562
|
+
INSERT INTO pending_deletes (
|
|
563
|
+
rel_path,
|
|
564
|
+
base_etag,
|
|
565
|
+
requested_at_ms,
|
|
566
|
+
mutation_id
|
|
567
|
+
) VALUES (?, ?, ?, ?)
|
|
568
|
+
ON CONFLICT(rel_path) DO UPDATE SET
|
|
569
|
+
base_etag = excluded.base_etag,
|
|
570
|
+
requested_at_ms = excluded.requested_at_ms,
|
|
571
|
+
mutation_id = excluded.mutation_id
|
|
572
|
+
`).run(entry.relPath, entry.baseEtag, entry.requestedAtMs, (_a = entry.mutationId) !== null && _a !== void 0 ? _a : null);
|
|
573
|
+
this.restrictFileModes();
|
|
574
|
+
}
|
|
575
|
+
removePendingDelete(relPath) {
|
|
576
|
+
const result = this.db.prepare("DELETE FROM pending_deletes WHERE rel_path = ?").run(relPath);
|
|
577
|
+
return result.changes > 0;
|
|
578
|
+
}
|
|
579
|
+
/** Recovery-mode escape hatch: drop every unflushed deletion intent. */
|
|
580
|
+
clearPendingDeletes() {
|
|
581
|
+
const result = this.db.prepare("DELETE FROM pending_deletes").run();
|
|
582
|
+
return result.changes;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Durable recovery step: unarm scan-based deletion, forget the recorded
|
|
586
|
+
* `files/` root identity, and drop every unflushed deletion intent in one
|
|
587
|
+
* shot. Called when the identity guard trips so a subsequent round starts
|
|
588
|
+
* from the legacy restore semantics until a clean round re-arms. Returns
|
|
589
|
+
* the number of pending deletes cleared.
|
|
590
|
+
*/
|
|
591
|
+
disarmDeletionAndClearPending() {
|
|
592
|
+
const disarm = this.db.transaction(() => {
|
|
593
|
+
this.db.prepare(`
|
|
594
|
+
INSERT INTO meta (key, value)
|
|
595
|
+
VALUES (?, ?)
|
|
596
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
597
|
+
`).run(META_DELETION_ARMED, "0");
|
|
598
|
+
this.db.prepare("DELETE FROM meta WHERE key = ?").run(META_FILES_ROOT_DEV);
|
|
599
|
+
this.db.prepare("DELETE FROM meta WHERE key = ?").run(META_FILES_ROOT_INO);
|
|
600
|
+
return this.db.prepare("DELETE FROM pending_deletes").run().changes;
|
|
601
|
+
});
|
|
602
|
+
const cleared = disarm();
|
|
603
|
+
this.restrictFileModes();
|
|
604
|
+
return cleared;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Arms scan-based deletion and records the `files/` root identity in one
|
|
608
|
+
* SQLite transaction so a crash cannot leave `deletion_armed=1` without
|
|
609
|
+
* both identity keys (which the next round would treat as compromised).
|
|
610
|
+
*/
|
|
611
|
+
armDeletionWithIdentity(identity) {
|
|
612
|
+
const arm = this.db.transaction(() => {
|
|
613
|
+
const upsert = this.db.prepare(`
|
|
614
|
+
INSERT INTO meta (key, value)
|
|
615
|
+
VALUES (?, ?)
|
|
616
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
617
|
+
`);
|
|
618
|
+
upsert.run(META_DELETION_ARMED, "1");
|
|
619
|
+
upsert.run(META_FILES_ROOT_DEV, String(identity.dev));
|
|
620
|
+
upsert.run(META_FILES_ROOT_INO, String(identity.ino));
|
|
621
|
+
});
|
|
622
|
+
arm();
|
|
623
|
+
this.restrictFileModes();
|
|
624
|
+
}
|
|
625
|
+
deleteFile(relPath) {
|
|
626
|
+
const result = this.db.prepare("DELETE FROM files WHERE rel_path = ?").run(relPath);
|
|
627
|
+
if (result.changes > 0) {
|
|
628
|
+
this.restrictFileModes();
|
|
629
|
+
}
|
|
630
|
+
return result.changes > 0;
|
|
631
|
+
}
|
|
632
|
+
getMeta(key) {
|
|
633
|
+
const row = this.db.prepare("SELECT value FROM meta WHERE key = ?").get(key);
|
|
634
|
+
return row === null || row === void 0 ? void 0 : row.value;
|
|
635
|
+
}
|
|
636
|
+
setMeta(entry) {
|
|
637
|
+
this.db.prepare(`
|
|
638
|
+
INSERT INTO meta (key, value)
|
|
639
|
+
VALUES (?, ?)
|
|
640
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
641
|
+
`).run(entry.key, entry.value);
|
|
642
|
+
this.restrictFileModes();
|
|
643
|
+
}
|
|
644
|
+
migrate() {
|
|
645
|
+
this.db.pragma("journal_mode = WAL");
|
|
646
|
+
this.db.pragma("synchronous = NORMAL");
|
|
647
|
+
this.db.pragma("busy_timeout = 5000");
|
|
648
|
+
this.db.exec(`
|
|
649
|
+
CREATE TABLE IF NOT EXISTS meta (
|
|
650
|
+
key TEXT PRIMARY KEY,
|
|
651
|
+
value TEXT NOT NULL
|
|
652
|
+
);
|
|
653
|
+
`);
|
|
654
|
+
const version = this.getMeta("schema_version");
|
|
655
|
+
if (version === void 0) {
|
|
656
|
+
this.createCurrentSchema();
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
const parsedVersion = Number(version);
|
|
660
|
+
if (!Number.isInteger(parsedVersion) || parsedVersion < 1 || parsedVersion > CURRENT_SCHEMA_VERSION) {
|
|
661
|
+
throw new LocalIndexError("unsupported_schema_version", `Unsupported agent store index schema version: ${version}`);
|
|
662
|
+
}
|
|
663
|
+
this.createFilesTableIfNeeded();
|
|
664
|
+
if (parsedVersion < 2) {
|
|
665
|
+
this.migrateV1ToV2();
|
|
666
|
+
}
|
|
667
|
+
if (parsedVersion < 3) {
|
|
668
|
+
this.migrateV2ToV3();
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
createCurrentSchema() {
|
|
672
|
+
this.createFilesTableIfNeeded();
|
|
673
|
+
this.createPendingDeletesTableIfNeeded();
|
|
674
|
+
this.setMeta({
|
|
675
|
+
key: "schema_version",
|
|
676
|
+
value: String(CURRENT_SCHEMA_VERSION)
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
createFilesTableIfNeeded() {
|
|
680
|
+
this.db.exec(`
|
|
681
|
+
CREATE TABLE IF NOT EXISTS files (
|
|
682
|
+
rel_path TEXT PRIMARY KEY,
|
|
683
|
+
last_synced_sha TEXT NOT NULL,
|
|
684
|
+
last_seen_etag TEXT,
|
|
685
|
+
size INTEGER NOT NULL,
|
|
686
|
+
last_synced_ms INTEGER NOT NULL,
|
|
687
|
+
direction TEXT NOT NULL CHECK(direction IN ('pulled', 'pushed')),
|
|
688
|
+
state TEXT NOT NULL DEFAULT 'live' CHECK(state IN ('live', 'tombstoned')),
|
|
689
|
+
tombstone_etag TEXT,
|
|
690
|
+
deleted_at_ms INTEGER
|
|
691
|
+
);
|
|
692
|
+
`);
|
|
693
|
+
}
|
|
694
|
+
createPendingDeletesTableIfNeeded() {
|
|
695
|
+
this.db.exec(`
|
|
696
|
+
CREATE TABLE IF NOT EXISTS pending_deletes (
|
|
697
|
+
rel_path TEXT PRIMARY KEY,
|
|
698
|
+
base_etag TEXT NOT NULL,
|
|
699
|
+
requested_at_ms INTEGER NOT NULL,
|
|
700
|
+
mutation_id TEXT
|
|
701
|
+
);
|
|
702
|
+
`);
|
|
703
|
+
}
|
|
704
|
+
migrateV1ToV2() {
|
|
705
|
+
const columns = this.db.prepare("PRAGMA table_info(files)").all();
|
|
706
|
+
if (columns.some((column) => column.name === "last_seen_sha")) {
|
|
707
|
+
this.db.exec("ALTER TABLE files RENAME COLUMN last_seen_sha TO last_synced_sha");
|
|
708
|
+
}
|
|
709
|
+
if (!columns.some((column) => column.name === "last_seen_etag")) {
|
|
710
|
+
this.db.exec("ALTER TABLE files ADD COLUMN last_seen_etag TEXT");
|
|
711
|
+
}
|
|
712
|
+
this.setMeta({
|
|
713
|
+
key: "schema_version",
|
|
714
|
+
value: "2"
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
migrateV2ToV3() {
|
|
718
|
+
const columns = this.db.prepare("PRAGMA table_info(files)").all();
|
|
719
|
+
if (!columns.some((column) => column.name === "state")) {
|
|
720
|
+
this.db.exec("ALTER TABLE files ADD COLUMN state TEXT NOT NULL DEFAULT 'live' CHECK(state IN ('live', 'tombstoned'))");
|
|
721
|
+
}
|
|
722
|
+
if (!columns.some((column) => column.name === "tombstone_etag")) {
|
|
723
|
+
this.db.exec("ALTER TABLE files ADD COLUMN tombstone_etag TEXT");
|
|
724
|
+
}
|
|
725
|
+
if (!columns.some((column) => column.name === "deleted_at_ms")) {
|
|
726
|
+
this.db.exec("ALTER TABLE files ADD COLUMN deleted_at_ms INTEGER");
|
|
727
|
+
}
|
|
728
|
+
this.createPendingDeletesTableIfNeeded();
|
|
729
|
+
this.setMeta({
|
|
730
|
+
key: "schema_version",
|
|
731
|
+
value: String(CURRENT_SCHEMA_VERSION)
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
restrictFileModes() {
|
|
735
|
+
restrictIndexFileModes(this.indexPath);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
LocalAgentStoreIndex.openHandles = /* @__PURE__ */ new Map();
|
|
739
|
+
function fileEntryFromRow(row) {
|
|
740
|
+
var _a, _b, _c;
|
|
741
|
+
return {
|
|
742
|
+
relPath: row.rel_path,
|
|
743
|
+
lastSyncedSha: row.last_synced_sha,
|
|
744
|
+
lastSeenEtag: (_a = row.last_seen_etag) !== null && _a !== void 0 ? _a : void 0,
|
|
745
|
+
size: row.size,
|
|
746
|
+
lastSyncedMs: row.last_synced_ms,
|
|
747
|
+
direction: row.direction,
|
|
748
|
+
state: row.state,
|
|
749
|
+
tombstoneEtag: (_b = row.tombstone_etag) !== null && _b !== void 0 ? _b : void 0,
|
|
750
|
+
deletedAtMs: (_c = row.deleted_at_ms) !== null && _c !== void 0 ? _c : void 0
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
function restrictIndexFileModes(indexPath) {
|
|
754
|
+
for (const filePath of [indexPath, `${indexPath}-wal`, `${indexPath}-shm`]) {
|
|
755
|
+
if (fs4.existsSync(filePath)) {
|
|
756
|
+
fs4.chmodSync(filePath, PRIVATE_FILE_MODE);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// ../agent-store-sync/dist/metrics-emitter.js
|
|
762
|
+
var NOOP_METRICS_EMITTER = Object.freeze({
|
|
763
|
+
onDiskFull() {
|
|
764
|
+
},
|
|
765
|
+
onSymlinkRefused() {
|
|
766
|
+
},
|
|
767
|
+
onNetworkError() {
|
|
768
|
+
},
|
|
769
|
+
onRoundCompleted() {
|
|
770
|
+
},
|
|
771
|
+
onError() {
|
|
772
|
+
},
|
|
773
|
+
onConflict() {
|
|
774
|
+
},
|
|
775
|
+
tokenMinted() {
|
|
776
|
+
},
|
|
777
|
+
tokenRefreshUnauthorized() {
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
// ../agent-store-sync/dist/metrics-aggregator.js
|
|
782
|
+
var DISK_FULL_REPEAT_WINDOW_MS = 5 * 60 * 1e3;
|
|
783
|
+
|
|
784
|
+
// ../agent-store-sync/dist/presigned-url.js
|
|
785
|
+
var PresignedUrlRejectedError = class extends Error {
|
|
786
|
+
constructor(options) {
|
|
787
|
+
super(options.message);
|
|
788
|
+
this.name = "PresignedUrlRejectedError";
|
|
789
|
+
this.code = options.code;
|
|
790
|
+
this.url = options.url;
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
function defaultPresignedUrlValidator(url) {
|
|
794
|
+
assertSafeAuthority(url);
|
|
795
|
+
if (url.protocol !== "https:") {
|
|
796
|
+
throw new PresignedUrlRejectedError({
|
|
797
|
+
code: "scheme_not_allowed",
|
|
798
|
+
message: `Refused presigned URL with non-https scheme: ${url.protocol}`,
|
|
799
|
+
url: redactPresignedUrlString(url)
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
const hostname = stripIPv6Brackets(url.hostname);
|
|
803
|
+
if (isLocalOrInternalHost(hostname)) {
|
|
804
|
+
throw new PresignedUrlRejectedError({
|
|
805
|
+
code: "private_host_not_allowed",
|
|
806
|
+
message: `Refused https presigned URL with private/internal host: ${hostname}`,
|
|
807
|
+
url: redactPresignedUrlString(url)
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
if (!isAwsS3Hostname(hostname)) {
|
|
811
|
+
throw new PresignedUrlRejectedError({
|
|
812
|
+
code: "host_not_allowed",
|
|
813
|
+
message: `Refused presigned URL whose host is not an AWS S3 endpoint: ${hostname}`,
|
|
814
|
+
url: redactPresignedUrlString(url)
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function isAwsS3Hostname(hostname) {
|
|
819
|
+
const lowered = hostname.toLowerCase();
|
|
820
|
+
if (lowered !== "amazonaws.com" && !lowered.endsWith(".amazonaws.com")) {
|
|
821
|
+
return false;
|
|
822
|
+
}
|
|
823
|
+
const labels = lowered.split(".");
|
|
824
|
+
return labels.some((label) => S3_OBJECT_LABELS.has(label));
|
|
825
|
+
}
|
|
826
|
+
var S3_OBJECT_LABELS = /* @__PURE__ */ new Set(["s3", "s3-accelerate", "s3-fips"]);
|
|
827
|
+
function createHostAllowlistValidator(allowedHosts) {
|
|
828
|
+
const allowed = new Set(allowedHosts.map((host) => host.toLowerCase()));
|
|
829
|
+
return (url) => {
|
|
830
|
+
defaultPresignedUrlValidator(url);
|
|
831
|
+
if (!allowed.has(url.hostname.toLowerCase())) {
|
|
832
|
+
throw new PresignedUrlRejectedError({
|
|
833
|
+
code: "host_not_allowed",
|
|
834
|
+
message: `Refused presigned URL whose host is not in the allowlist: ${url.hostname}`,
|
|
835
|
+
url: redactPresignedUrlString(url)
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
var BCS_AGENT_STORE_BUCKET_HOSTS = [
|
|
841
|
+
"agent-stores.s3.us-east-1.amazonaws.com",
|
|
842
|
+
"agent-stores.s3.amazonaws.com"
|
|
843
|
+
];
|
|
844
|
+
function createBcsPresignedUrlValidator() {
|
|
845
|
+
return createHostAllowlistValidator(BCS_AGENT_STORE_BUCKET_HOSTS);
|
|
846
|
+
}
|
|
847
|
+
function isLocalAgentStoreBackendUrl(backendUrl) {
|
|
848
|
+
const trimmed = backendUrl.trim();
|
|
849
|
+
if (trimmed === "") {
|
|
850
|
+
return false;
|
|
851
|
+
}
|
|
852
|
+
return trimmed.includes("localhost") || trimmed.includes("lclhst.build");
|
|
853
|
+
}
|
|
854
|
+
function createAgentStorePresignedUrlValidatorForBackend(backendUrl) {
|
|
855
|
+
return isLocalAgentStoreBackendUrl(backendUrl) ? createLocalDevAgentStorePresignedUrlValidator() : createBcsPresignedUrlValidator();
|
|
856
|
+
}
|
|
857
|
+
function createLocalDevAgentStorePresignedUrlValidator() {
|
|
858
|
+
const bcsValidator = createBcsPresignedUrlValidator();
|
|
859
|
+
return (url) => {
|
|
860
|
+
assertSafeAuthority(url);
|
|
861
|
+
const hostname = stripIPv6Brackets(url.hostname);
|
|
862
|
+
if (url.protocol === "http:" && isLoopbackHostName(hostname)) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
bcsValidator(url);
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
function assertSafeAuthority(url) {
|
|
869
|
+
if (url.username !== "" || url.password !== "") {
|
|
870
|
+
throw new PresignedUrlRejectedError({
|
|
871
|
+
code: "userinfo_not_allowed",
|
|
872
|
+
message: "Refused presigned URL with embedded userinfo",
|
|
873
|
+
url: redactPresignedUrlString(url)
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
function redactPresignedUrlString(url) {
|
|
878
|
+
try {
|
|
879
|
+
const parsed = typeof url === "string" ? new URL(url) : url;
|
|
880
|
+
return `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
|
|
881
|
+
} catch (_a) {
|
|
882
|
+
return "<unparseable-presigned-url>";
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
function isLoopbackHostName(hostname) {
|
|
886
|
+
const lowered = hostname.toLowerCase();
|
|
887
|
+
return lowered === "localhost" || lowered === "ip6-localhost" || lowered === "127.0.0.1" || lowered === "::1" || lowered === "0:0:0:0:0:0:0:1";
|
|
888
|
+
}
|
|
889
|
+
function isLocalOrInternalHost(hostname) {
|
|
890
|
+
if (hostname.length === 0) {
|
|
891
|
+
return true;
|
|
892
|
+
}
|
|
893
|
+
if (isLoopbackHostName(hostname)) {
|
|
894
|
+
return true;
|
|
895
|
+
}
|
|
896
|
+
if (isIPv4Address(hostname)) {
|
|
897
|
+
return isPrivateOrInternalIPv4(hostname);
|
|
898
|
+
}
|
|
899
|
+
if (isIPv6Address(hostname)) {
|
|
900
|
+
return isPrivateOrInternalIPv6(hostname);
|
|
901
|
+
}
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
904
|
+
function stripIPv6Brackets(hostname) {
|
|
905
|
+
return hostname.startsWith("[") && hostname.endsWith("]") ? hostname.slice(1, -1) : hostname;
|
|
906
|
+
}
|
|
907
|
+
function isIPv4Address(hostname) {
|
|
908
|
+
const parts = hostname.split(".");
|
|
909
|
+
if (parts.length !== 4) {
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
return parts.every((part) => {
|
|
913
|
+
if (part.length === 0 || part.length > 3) {
|
|
914
|
+
return false;
|
|
915
|
+
}
|
|
916
|
+
if (!/^\d+$/.test(part)) {
|
|
917
|
+
return false;
|
|
918
|
+
}
|
|
919
|
+
const n = Number(part);
|
|
920
|
+
return Number.isInteger(n) && n >= 0 && n <= 255;
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
function isPrivateOrInternalIPv4(hostname) {
|
|
924
|
+
const [a, b] = hostname.split(".").map(Number);
|
|
925
|
+
if (a === void 0 || b === void 0) {
|
|
926
|
+
return true;
|
|
927
|
+
}
|
|
928
|
+
if (a === 0)
|
|
929
|
+
return true;
|
|
930
|
+
if (a === 10)
|
|
931
|
+
return true;
|
|
932
|
+
if (a === 127)
|
|
933
|
+
return true;
|
|
934
|
+
if (a === 169 && b === 254)
|
|
935
|
+
return true;
|
|
936
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
937
|
+
return true;
|
|
938
|
+
if (a === 192 && b === 168)
|
|
939
|
+
return true;
|
|
940
|
+
if (a === 100 && b >= 64 && b <= 127)
|
|
941
|
+
return true;
|
|
942
|
+
if (a >= 224 && a <= 239)
|
|
943
|
+
return true;
|
|
944
|
+
if (a >= 240)
|
|
945
|
+
return true;
|
|
946
|
+
return false;
|
|
947
|
+
}
|
|
948
|
+
function isIPv6Address(hostname) {
|
|
949
|
+
return hostname.includes(":");
|
|
950
|
+
}
|
|
951
|
+
function isPrivateOrInternalIPv6(hostname) {
|
|
952
|
+
const lowered = hostname.toLowerCase();
|
|
953
|
+
if (lowered === "::" || lowered === "::1") {
|
|
954
|
+
return true;
|
|
955
|
+
}
|
|
956
|
+
const mapped = extractIPv4MappedAddress(lowered);
|
|
957
|
+
if (mapped !== void 0) {
|
|
958
|
+
return isPrivateOrInternalIPv4(mapped);
|
|
959
|
+
}
|
|
960
|
+
if (lowered.startsWith("fc") || lowered.startsWith("fd")) {
|
|
961
|
+
return true;
|
|
962
|
+
}
|
|
963
|
+
if (lowered.startsWith("fe8") || lowered.startsWith("fe9")) {
|
|
964
|
+
return true;
|
|
965
|
+
}
|
|
966
|
+
if (lowered.startsWith("fea") || lowered.startsWith("feb")) {
|
|
967
|
+
return true;
|
|
968
|
+
}
|
|
969
|
+
if (lowered.startsWith("ff")) {
|
|
970
|
+
return true;
|
|
971
|
+
}
|
|
972
|
+
return false;
|
|
973
|
+
}
|
|
974
|
+
function extractIPv4MappedAddress(hostname) {
|
|
975
|
+
const dotted = hostname.match(/^(?:0:0:0:0:0|::):?ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i);
|
|
976
|
+
if (dotted) {
|
|
977
|
+
return dotted[1];
|
|
978
|
+
}
|
|
979
|
+
if (hostname.startsWith("::ffff:")) {
|
|
980
|
+
const tail = hostname.slice("::ffff:".length);
|
|
981
|
+
if (isIPv4Address(tail)) {
|
|
982
|
+
return tail;
|
|
983
|
+
}
|
|
984
|
+
const hex = tail.match(/^([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
|
|
985
|
+
if (hex) {
|
|
986
|
+
const high = Number.parseInt(hex[1], 16);
|
|
987
|
+
const low = Number.parseInt(hex[2], 16);
|
|
988
|
+
if (Number.isFinite(high) && Number.isFinite(low) && high >= 0 && high <= 65535 && low >= 0 && low <= 65535) {
|
|
989
|
+
return `${high >> 8 & 255}.${high & 255}.${low >> 8 & 255}.${low & 255}`;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
return void 0;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// ../agent-store-sync/dist/resilience-events.js
|
|
997
|
+
var NOOP_RESILIENCE_LISTENER = Object.freeze({
|
|
998
|
+
onDiskFull() {
|
|
999
|
+
},
|
|
1000
|
+
onSymlinkRefused() {
|
|
1001
|
+
},
|
|
1002
|
+
onNetworkError() {
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
// ../agent-store-sync/dist/retrying-client.js
|
|
1007
|
+
var RETRYABLE_CONNECT_CODES = /* @__PURE__ */ new Set([
|
|
1008
|
+
Code.Unavailable,
|
|
1009
|
+
Code.ResourceExhausted,
|
|
1010
|
+
Code.Internal,
|
|
1011
|
+
Code.Aborted,
|
|
1012
|
+
Code.DeadlineExceeded
|
|
1013
|
+
]);
|
|
1014
|
+
|
|
1015
|
+
// ../agent-store-sync/dist/store-lock.js
|
|
1016
|
+
var STORE_LOCK_STALE_MS = 10 * 60 * 1e3;
|
|
1017
|
+
|
|
1018
|
+
// ../agent-store-sync/dist/sync-engine.js
|
|
1019
|
+
var DEFAULT_MAX_FILE_SIZE_BYTES = 100 * 1024 * 1024;
|
|
1020
|
+
var TOMBSTONE_ROW_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
1021
|
+
export {
|
|
1022
|
+
createAgentStorePresignedUrlValidatorForBackend
|
|
1023
|
+
};
|