@namzu/sdk 51.1.0 → 52.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +119 -0
- package/dist/agents/QueryAgent.d.ts.map +1 -1
- package/dist/agents/QueryAgent.js +2 -0
- package/dist/agents/QueryAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/agents/examples/SupervisorAgent.d.ts +42 -0
- package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/examples/SupervisorAgent.js +80 -4
- package/dist/agents/examples/SupervisorAgent.js.map +1 -1
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/authorization/protected-paths.d.ts +36 -0
- package/dist/authorization/protected-paths.d.ts.map +1 -0
- package/dist/authorization/protected-paths.js +107 -0
- package/dist/authorization/protected-paths.js.map +1 -0
- package/dist/authorization/readonly-commands.d.ts +39 -0
- package/dist/authorization/readonly-commands.d.ts.map +1 -0
- package/dist/authorization/readonly-commands.js +797 -0
- package/dist/authorization/readonly-commands.js.map +1 -0
- package/dist/authorization/readonly-flags.d.ts +19 -0
- package/dist/authorization/readonly-flags.d.ts.map +1 -0
- package/dist/authorization/readonly-flags.js +178 -0
- package/dist/authorization/readonly-flags.js.map +1 -0
- package/dist/authorization/removal.d.ts +52 -0
- package/dist/authorization/removal.d.ts.map +1 -0
- package/dist/authorization/removal.js +283 -0
- package/dist/authorization/removal.js.map +1 -0
- package/dist/authorization/shell-paths.d.ts +66 -0
- package/dist/authorization/shell-paths.d.ts.map +1 -0
- package/dist/authorization/shell-paths.js +697 -0
- package/dist/authorization/shell-paths.js.map +1 -0
- package/dist/bridge/acp/update.d.ts.map +1 -1
- package/dist/bridge/acp/update.js +1 -0
- package/dist/bridge/acp/update.js.map +1 -1
- package/dist/compaction/context-window.d.ts +24 -0
- package/dist/compaction/context-window.d.ts.map +1 -1
- package/dist/compaction/context-window.js +34 -0
- package/dist/compaction/context-window.js.map +1 -1
- package/dist/compaction/manual.d.ts.map +1 -1
- package/dist/compaction/manual.js +10 -2
- package/dist/compaction/manual.js.map +1 -1
- package/dist/compaction/plan.d.ts +4 -0
- package/dist/compaction/plan.d.ts.map +1 -1
- package/dist/compaction/plan.js +6 -2
- package/dist/compaction/plan.js.map +1 -1
- package/dist/compaction/verifier.d.ts +11 -1
- package/dist/compaction/verifier.d.ts.map +1 -1
- package/dist/compaction/verifier.js +75 -23
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/config/runtime.d.ts +55 -7
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/runtime.js +23 -2
- package/dist/config/runtime.js.map +1 -1
- package/dist/connector/web/guarded-fetch.d.ts.map +1 -1
- package/dist/connector/web/guarded-fetch.js +24 -0
- package/dist/connector/web/guarded-fetch.js.map +1 -1
- package/dist/connector/web/index.d.ts +1 -1
- package/dist/connector/web/index.d.ts.map +1 -1
- package/dist/connector/web/page.d.ts +59 -0
- package/dist/connector/web/page.d.ts.map +1 -0
- package/dist/connector/web/page.js +112 -0
- package/dist/connector/web/page.js.map +1 -0
- package/dist/connector/web/types.d.ts +47 -0
- package/dist/connector/web/types.d.ts.map +1 -1
- package/dist/connector/web/types.js.map +1 -1
- package/dist/constants/continuation.d.ts +8 -0
- package/dist/constants/continuation.d.ts.map +1 -1
- package/dist/constants/continuation.js +8 -0
- package/dist/constants/continuation.js.map +1 -1
- package/dist/constants/plugin/index.d.ts +1 -1
- package/dist/constants/plugin/index.d.ts.map +1 -1
- package/dist/constants/plugin/index.js +1 -1
- package/dist/constants/plugin/index.js.map +1 -1
- package/dist/contracts/a2a.d.ts +2 -2
- package/dist/manager/agent/lifecycle.d.ts +7 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +11 -2
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/session/turn-recorder.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.js +4 -2
- package/dist/manager/session/turn-recorder.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1 -1
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/lifecycle.d.ts +6 -0
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +98 -114
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/shell-hook.d.ts +90 -22
- package/dist/plugin/shell-hook.d.ts.map +1 -1
- package/dist/plugin/shell-hook.js +434 -41
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/provider/capabilities.d.ts +9 -0
- package/dist/provider/capabilities.d.ts.map +1 -1
- package/dist/provider/capabilities.js +15 -0
- package/dist/provider/capabilities.js.map +1 -1
- package/dist/provider/errors.d.ts.map +1 -1
- package/dist/provider/errors.js +13 -0
- package/dist/provider/errors.js.map +1 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +10 -0
- package/dist/provider/fallback.js.map +1 -1
- package/dist/provider/idle-timeout.d.ts.map +1 -1
- package/dist/provider/idle-timeout.js +5 -0
- package/dist/provider/idle-timeout.js.map +1 -1
- package/dist/provider/image-input-refusal.d.ts +9 -0
- package/dist/provider/image-input-refusal.d.ts.map +1 -0
- package/dist/provider/image-input-refusal.js +54 -0
- package/dist/provider/image-input-refusal.js.map +1 -0
- package/dist/provider/index.d.ts +2 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +2 -1
- package/dist/provider/index.js.map +1 -1
- package/dist/provider/retry.d.ts +7 -2
- package/dist/provider/retry.d.ts.map +1 -1
- package/dist/provider/retry.js +38 -4
- package/dist/provider/retry.js.map +1 -1
- package/dist/public-runtime.d.ts +5 -2
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +5 -2
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +2 -2
- package/dist/public-types.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.d.ts +21 -0
- package/dist/runtime/jobs/registry.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.js +15 -2
- package/dist/runtime/jobs/registry.js.map +1 -1
- package/dist/runtime/query/deferred-sandbox.d.ts +54 -0
- package/dist/runtime/query/deferred-sandbox.d.ts.map +1 -0
- package/dist/runtime/query/deferred-sandbox.js +75 -0
- package/dist/runtime/query/deferred-sandbox.js.map +1 -0
- package/dist/runtime/query/executor/tool-call-admission.d.ts +10 -0
- package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.js +74 -13
- package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +51 -2
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +214 -9
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/finalize-turn.d.ts +6 -0
- package/dist/runtime/query/finalize-turn.d.ts.map +1 -1
- package/dist/runtime/query/finalize-turn.js +1 -1
- package/dist/runtime/query/finalize-turn.js.map +1 -1
- package/dist/runtime/query/index.d.ts +29 -0
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +108 -28
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +57 -0
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +380 -28
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts +61 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.js +94 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.js.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts +42 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +203 -23
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +10 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +165 -2
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/provider-rejected-image.d.ts +21 -1
- package/dist/runtime/query/iteration/provider-rejected-image.d.ts.map +1 -1
- package/dist/runtime/query/iteration/provider-rejected-image.js +53 -7
- package/dist/runtime/query/iteration/provider-rejected-image.js.map +1 -1
- package/dist/runtime/query/iteration/request-repair.d.ts +108 -0
- package/dist/runtime/query/iteration/request-repair.d.ts.map +1 -0
- package/dist/runtime/query/iteration/request-repair.js +593 -0
- package/dist/runtime/query/iteration/request-repair.js.map +1 -0
- package/dist/runtime/query/iteration/stream-turn.d.ts +6 -0
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +2 -2
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/path-escalation.d.ts +36 -0
- package/dist/runtime/query/path-escalation.d.ts.map +1 -0
- package/dist/runtime/query/path-escalation.js +184 -0
- package/dist/runtime/query/path-escalation.js.map +1 -0
- package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
- package/dist/runtime/query/plugin-hooks.js +8 -0
- package/dist/runtime/query/plugin-hooks.js.map +1 -1
- package/dist/runtime/query/reminders.d.ts +35 -0
- package/dist/runtime/query/reminders.d.ts.map +1 -0
- package/dist/runtime/query/reminders.js +7 -0
- package/dist/runtime/query/reminders.js.map +1 -0
- package/dist/runtime/query/request-rich-content.d.ts +5 -1
- package/dist/runtime/query/request-rich-content.d.ts.map +1 -1
- package/dist/runtime/query/request-rich-content.js +67 -25
- package/dist/runtime/query/request-rich-content.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +26 -0
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +26 -0
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +79 -5
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/tool-output-budget.d.ts +46 -0
- package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
- package/dist/runtime/query/tool-output-budget.js +85 -1
- package/dist/runtime/query/tool-output-budget.js.map +1 -1
- package/dist/runtime/query/tooling.d.ts +1 -0
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +5 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/session/paths.d.ts +5 -1
- package/dist/session/paths.d.ts.map +1 -1
- package/dist/session/paths.js +8 -0
- package/dist/session/paths.js.map +1 -1
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +2 -2
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/memory/markdown.d.ts.map +1 -1
- package/dist/store/memory/markdown.js +2 -2
- package/dist/store/memory/markdown.js.map +1 -1
- package/dist/store/memory/naming.d.ts +9 -0
- package/dist/store/memory/naming.d.ts.map +1 -1
- package/dist/store/memory/naming.js +12 -0
- package/dist/store/memory/naming.js.map +1 -1
- package/dist/tools/builtins/bash.d.ts +30 -1
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +170 -26
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/computer-use.d.ts +1 -1
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js +12 -5
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/tools/builtins/content-fingerprint.d.ts +2 -0
- package/dist/tools/builtins/content-fingerprint.d.ts.map +1 -1
- package/dist/tools/builtins/content-fingerprint.js +4 -0
- package/dist/tools/builtins/content-fingerprint.js.map +1 -1
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +60 -18
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/grep.d.ts +8 -1
- package/dist/tools/builtins/grep.d.ts.map +1 -1
- package/dist/tools/builtins/grep.js +152 -33
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/read-file.d.ts +1 -0
- package/dist/tools/builtins/read-file.d.ts.map +1 -1
- package/dist/tools/builtins/read-file.js +44 -5
- package/dist/tools/builtins/read-file.js.map +1 -1
- package/dist/tools/builtins/read-render.d.ts +52 -0
- package/dist/tools/builtins/read-render.d.ts.map +1 -1
- package/dist/tools/builtins/read-render.js +143 -0
- package/dist/tools/builtins/read-render.js.map +1 -1
- package/dist/tools/builtins/web.d.ts +13 -2
- package/dist/tools/builtins/web.d.ts.map +1 -1
- package/dist/tools/builtins/web.js +225 -32
- package/dist/tools/builtins/web.js.map +1 -1
- package/dist/tools/coordinator/ask-user-question.d.ts +2 -0
- package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
- package/dist/tools/coordinator/ask-user-question.js +256 -92
- package/dist/tools/coordinator/ask-user-question.js.map +1 -1
- package/dist/tools/coordinator/question-options.d.ts +1 -0
- package/dist/tools/coordinator/question-options.d.ts.map +1 -1
- package/dist/tools/coordinator/question-options.js +6 -1
- package/dist/tools/coordinator/question-options.js.map +1 -1
- package/dist/tools/defineTool.d.ts +4 -1
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +6 -1
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/paths.d.ts +6 -0
- package/dist/tools/paths.d.ts.map +1 -1
- package/dist/tools/paths.js +1 -1
- package/dist/tools/paths.js.map +1 -1
- package/dist/types/agent/query.d.ts +3 -0
- package/dist/types/agent/query.d.ts.map +1 -1
- package/dist/types/errors/catalog.js +1 -1
- package/dist/types/errors/catalog.js.map +1 -1
- package/dist/types/hitl/index.d.ts +104 -0
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/message/index.d.ts +1 -1
- package/dist/types/message/index.d.ts.map +1 -1
- package/dist/types/message/index.js +2 -0
- package/dist/types/message/index.js.map +1 -1
- package/dist/types/plugin/index.d.ts +93 -19
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/plugin/index.js +3 -0
- package/dist/types/plugin/index.js.map +1 -1
- package/dist/types/provider/errors.d.ts +19 -0
- package/dist/types/provider/errors.d.ts.map +1 -1
- package/dist/types/provider/errors.js +54 -5
- package/dist/types/provider/errors.js.map +1 -1
- package/dist/types/provider/interface.d.ts +12 -0
- package/dist/types/provider/interface.d.ts.map +1 -1
- package/dist/types/provider/stream.d.ts +1 -1
- package/dist/types/session/config.d.ts +14 -0
- package/dist/types/session/config.d.ts.map +1 -1
- package/dist/types/session/events.d.ts +27 -4
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/records.d.ts +9 -9
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +1 -0
- package/dist/types/session/records.js.map +1 -1
- package/dist/types/session/stop-reason.d.ts +5 -0
- package/dist/types/session/stop-reason.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +52 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/package.json +4 -2
- package/src/agents/QueryAgent.ts +5 -1
- package/src/agents/SupervisorAgent.ts +1 -1
- package/src/agents/examples/SupervisorAgent.ts +217 -106
- package/src/agents/index.ts +1 -1
- package/src/authorization/protected-paths.ts +110 -0
- package/src/authorization/readonly-commands.ts +771 -0
- package/src/authorization/readonly-flags.ts +196 -0
- package/src/authorization/removal.ts +326 -0
- package/src/authorization/shell-paths.ts +927 -0
- package/src/bridge/acp/update.ts +1 -0
- package/src/compaction/context-window.ts +41 -0
- package/src/compaction/manual.ts +10 -2
- package/src/compaction/plan.ts +11 -2
- package/src/compaction/verifier.ts +84 -22
- package/src/config/runtime.ts +23 -2
- package/src/connector/web/guarded-fetch.ts +26 -0
- package/src/connector/web/index.ts +3 -0
- package/src/connector/web/page.ts +130 -0
- package/src/connector/web/types.ts +47 -0
- package/src/constants/continuation.ts +10 -0
- package/src/constants/plugin/index.ts +1 -1
- package/src/manager/agent/lifecycle.ts +12 -4
- package/src/manager/session/turn-recorder.ts +10 -2
- package/src/plugin/index.ts +1 -0
- package/src/plugin/lifecycle.ts +107 -119
- package/src/plugin/shell-hook.ts +477 -43
- package/src/provider/capabilities.ts +17 -0
- package/src/provider/errors.ts +13 -0
- package/src/provider/fallback.ts +10 -0
- package/src/provider/idle-timeout.ts +5 -0
- package/src/provider/image-input-refusal.ts +54 -0
- package/src/provider/index.ts +2 -0
- package/src/provider/retry.ts +42 -4
- package/src/public-runtime.ts +11 -0
- package/src/public-types.ts +4 -0
- package/src/runtime/jobs/registry.ts +39 -2
- package/src/runtime/query/deferred-sandbox.ts +110 -0
- package/src/runtime/query/executor/tool-call-admission.ts +79 -13
- package/src/runtime/query/executor.ts +267 -11
- package/src/runtime/query/finalize-turn.ts +7 -1
- package/src/runtime/query/index.ts +169 -52
- package/src/runtime/query/iteration/index.ts +439 -35
- package/src/runtime/query/iteration/phases/compaction-breaker.ts +108 -0
- package/src/runtime/query/iteration/phases/compaction.ts +241 -38
- package/src/runtime/query/iteration/phases/context.ts +11 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +177 -2
- package/src/runtime/query/iteration/provider-rejected-image.ts +71 -5
- package/src/runtime/query/iteration/request-repair.ts +743 -0
- package/src/runtime/query/iteration/stream-turn.ts +11 -1
- package/src/runtime/query/path-escalation.ts +204 -0
- package/src/runtime/query/plugin-hooks.ts +8 -0
- package/src/runtime/query/reminders.ts +45 -0
- package/src/runtime/query/request-rich-content.ts +77 -27
- package/src/runtime/query/resume-pending.ts +27 -0
- package/src/runtime/query/review-policy.ts +106 -5
- package/src/runtime/query/tool-output-budget.ts +115 -1
- package/src/runtime/query/tooling.ts +6 -0
- package/src/session/paths.ts +11 -1
- package/src/store/memory/disk.ts +2 -1
- package/src/store/memory/markdown.ts +2 -1
- package/src/store/memory/naming.ts +13 -0
- package/src/tools/builtins/bash.ts +203 -34
- package/src/tools/builtins/computer-use.ts +13 -4
- package/src/tools/builtins/content-fingerprint.ts +5 -0
- package/src/tools/builtins/edit.ts +69 -19
- package/src/tools/builtins/grep.ts +159 -38
- package/src/tools/builtins/read-file.ts +48 -5
- package/src/tools/builtins/read-render.ts +193 -0
- package/src/tools/builtins/web.ts +258 -33
- package/src/tools/coordinator/ask-user-question.ts +309 -103
- package/src/tools/coordinator/question-options.ts +8 -1
- package/src/tools/defineTool.ts +11 -2
- package/src/tools/paths.ts +1 -1
- package/src/types/agent/query.ts +3 -0
- package/src/types/errors/catalog.ts +1 -1
- package/src/types/hitl/index.ts +104 -0
- package/src/types/message/index.ts +2 -0
- package/src/types/plugin/index.ts +101 -18
- package/src/types/provider/errors.ts +66 -5
- package/src/types/provider/interface.ts +13 -0
- package/src/types/provider/stream.ts +1 -1
- package/src/types/session/config.ts +14 -0
- package/src/types/session/events.ts +32 -4
- package/src/types/session/records.ts +1 -0
- package/src/types/session/stop-reason.ts +5 -0
- package/src/types/tool/index.ts +53 -2
|
@@ -228,6 +228,26 @@ export const REQUIRES_APPROVAL_UNATTENDED_REFUSAL =
|
|
|
228
228
|
export const UNKNOWN_PROGRAM_UNATTENDED_REFUSAL =
|
|
229
229
|
'Refused: a call in this batch runs a command whose own program name is decided at runtime (a substitution or a variable stands for it), which needs a person to approve it each time, and nobody can be asked in this session. Nothing in this batch ran. Write the program name literally; compute what needs computing in the arguments instead.'
|
|
230
230
|
|
|
231
|
+
/**
|
|
232
|
+
* What the model is told when a batch writes a protected path (a git hook, a
|
|
233
|
+
* shell rc file, editor or tool configuration, the project's `.namzu`
|
|
234
|
+
* directory) and nobody can be asked.
|
|
235
|
+
*
|
|
236
|
+
* Refused in every mode, `auto` included: a write there runs later, outside
|
|
237
|
+
* the turn, with the operator's rights, so an answer given before the call
|
|
238
|
+
* existed (a mode, a rule, "approve all") is not an answer about it.
|
|
239
|
+
*/
|
|
240
|
+
export const PROTECTED_PATH_UNATTENDED_REFUSAL =
|
|
241
|
+
"Refused: a call in this batch writes a protected path (a git hook or config, a shell startup file, editor or tool configuration, or the project's .namzu directory), which needs a person to approve it each time, and nobody can be asked in this session. Nothing in this batch ran. Leave those files alone, or tell the user what change you need so they can make it."
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* What the model is told when a batch removes something catastrophic (the
|
|
245
|
+
* root, the home directory, the working directory or a parent of it, a glob
|
|
246
|
+
* across directories, a target a variable may empty) and nobody can be asked.
|
|
247
|
+
*/
|
|
248
|
+
export const DANGEROUS_REMOVAL_UNATTENDED_REFUSAL =
|
|
249
|
+
'Refused: a call in this batch removes something this check treats as catastrophic (the file system root, a top-level or home directory, the working directory or a parent of it, a glob across directories, or a target a variable or substitution may leave empty), which needs a person to approve it each time, and nobody can be asked in this session. Nothing in this batch ran. Name the exact directory to remove with a literal path.'
|
|
250
|
+
|
|
231
251
|
/**
|
|
232
252
|
* What the model is told when a batch would show it the operator's screen for
|
|
233
253
|
* the first time in a session and nobody can be asked.
|
|
@@ -250,6 +270,21 @@ export interface ScreenConsentRecord {
|
|
|
250
270
|
readonly sessions: Set<string>
|
|
251
271
|
}
|
|
252
272
|
|
|
273
|
+
/** Whether the call writes a protected path or removes something catastrophic. */
|
|
274
|
+
function reachesAFloor(tc: ToolCallSummary): boolean {
|
|
275
|
+
return (
|
|
276
|
+
(tc.escalation?.protectedPaths?.length ?? 0) > 0 ||
|
|
277
|
+
tc.escalation?.dangerousRemoval !== undefined
|
|
278
|
+
)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** The refusal for a batch that reaches a floor and cannot be asked about it. */
|
|
282
|
+
function floorRefusal(toolCalls: readonly ToolCallSummary[]): string {
|
|
283
|
+
return toolCalls.some((tc) => (tc.escalation?.protectedPaths?.length ?? 0) > 0)
|
|
284
|
+
? PROTECTED_PATH_UNATTENDED_REFUSAL
|
|
285
|
+
: DANGEROUS_REMOVAL_UNATTENDED_REFUSAL
|
|
286
|
+
}
|
|
287
|
+
|
|
253
288
|
/** The batch a person is asked about. */
|
|
254
289
|
export interface ToolReviewRequest {
|
|
255
290
|
/** Originating session, preserved by createReviewHandler for host attribution. */
|
|
@@ -339,6 +374,16 @@ export interface ReviewPolicyOptions {
|
|
|
339
374
|
* `capturesScreen` declaration, read from `registry`; nothing without one.
|
|
340
375
|
*/
|
|
341
376
|
readonly capturesScreen?: (name: string, input: unknown) => boolean
|
|
377
|
+
/**
|
|
378
|
+
* The one write `plan` mode lets through: a host that gives plan mode a plan
|
|
379
|
+
* file says here which call writes it. In `plan`, a call this accepts is not
|
|
380
|
+
* a change — it is neither refused nor asked about — unless a rule asked to
|
|
381
|
+
* review it, in which case it is put to the person like a read outside the
|
|
382
|
+
* roots. Every other write stays refused. Omitted (the default), `plan`
|
|
383
|
+
* refuses every change, as it always has; the option does nothing in any
|
|
384
|
+
* other mode.
|
|
385
|
+
*/
|
|
386
|
+
readonly planModeWrite?: (call: ToolCallSummary) => boolean
|
|
342
387
|
}
|
|
343
388
|
|
|
344
389
|
/**
|
|
@@ -358,6 +403,23 @@ function isSkillGranted(tc: ToolCallSummary): boolean {
|
|
|
358
403
|
)
|
|
359
404
|
}
|
|
360
405
|
|
|
406
|
+
/**
|
|
407
|
+
* Whether a `pre_tool_use` hook's `allow` may stand in for a person on this
|
|
408
|
+
* call. The same bar as a skill's grant, repeated here so that a mark on a
|
|
409
|
+
* persisted or host-built summary cannot carry more than the kernel gave it.
|
|
410
|
+
*/
|
|
411
|
+
function isHookGranted(tc: ToolCallSummary): boolean {
|
|
412
|
+
return (
|
|
413
|
+
tc.hookGrant !== undefined &&
|
|
414
|
+
tc.hookPermission?.decision !== 'ask' &&
|
|
415
|
+
!tc.authorization?.explicitReview &&
|
|
416
|
+
tc.authorization?.decision !== 'deny' &&
|
|
417
|
+
!tc.isDestructive &&
|
|
418
|
+
tc.escalation === undefined &&
|
|
419
|
+
tc.requiresApproval !== true
|
|
420
|
+
)
|
|
421
|
+
}
|
|
422
|
+
|
|
361
423
|
/** The handler behind `createReviewPolicy`, for a host that wants only the function. */
|
|
362
424
|
export function createReviewHandler(options: ReviewPolicyOptions = {}): ResumeHandler {
|
|
363
425
|
const { prompt, registry } = options
|
|
@@ -422,7 +484,16 @@ export function createReviewHandler(options: ReviewPolicyOptions = {}): ResumeHa
|
|
|
422
484
|
if (answer.kind === 'approve-all') remembered.all = true
|
|
423
485
|
answered = answer
|
|
424
486
|
}
|
|
425
|
-
|
|
487
|
+
// The plan file, in `plan`: the one write that is not a change. A rule
|
|
488
|
+
// that asked for review keeps the call in the batch, so it is asked.
|
|
489
|
+
const isPlanFileWrite = (tc: ToolCallSummary): boolean =>
|
|
490
|
+
mode === 'plan' &&
|
|
491
|
+
options.planModeWrite?.(tc) === true &&
|
|
492
|
+
tc.authorization?.decision !== 'deny'
|
|
493
|
+
const reviewable = request.toolCalls.filter(
|
|
494
|
+
(tc) => !(isPlanFileWrite(tc) && !tc.authorization?.explicitReview),
|
|
495
|
+
)
|
|
496
|
+
if (!batchNeedsReview(reviewable, exempt)) {
|
|
426
497
|
return { action: 'approve_tools' }
|
|
427
498
|
}
|
|
428
499
|
// A batch of nothing but non-destructive file edits is the case
|
|
@@ -450,7 +521,13 @@ export function createReviewHandler(options: ReviewPolicyOptions = {}): ResumeHa
|
|
|
450
521
|
// to do, and the question such a path gets is the same in every mode that
|
|
451
522
|
// lets reads run. It goes on to that question below; `strict` still
|
|
452
523
|
// refuses it, since no rule can approve a path outside the roots.
|
|
453
|
-
if (
|
|
524
|
+
if (
|
|
525
|
+
mode === 'plan' &&
|
|
526
|
+
!onlyReadsOutsideRoots(
|
|
527
|
+
reviewable.filter((tc) => !isPlanFileWrite(tc)),
|
|
528
|
+
exempt,
|
|
529
|
+
)
|
|
530
|
+
) {
|
|
454
531
|
return { action: 'reject_tools', feedback: PLAN_MODE_REFUSAL }
|
|
455
532
|
}
|
|
456
533
|
if (mode === 'strict') return { action: 'reject_tools', feedback: STRICT_MODE_REFUSAL }
|
|
@@ -471,6 +548,9 @@ export function createReviewHandler(options: ReviewPolicyOptions = {}): ResumeHa
|
|
|
471
548
|
// This opt-in confirms only the sandbox escape. A different call in
|
|
472
549
|
// the batch, or another boundary on this same call, still needs a
|
|
473
550
|
// person; the early return must not approve that boundary too.
|
|
551
|
+
if (request.toolCalls.some(reachesAFloor)) {
|
|
552
|
+
return { action: 'reject_tools', feedback: floorRefusal(request.toolCalls) }
|
|
553
|
+
}
|
|
474
554
|
if (request.toolCalls.some((tc) => (tc.escalation?.outsidePaths?.length ?? 0) > 0)) {
|
|
475
555
|
return { action: 'reject_tools', feedback: OUTSIDE_ROOTS_UNATTENDED_REFUSAL }
|
|
476
556
|
}
|
|
@@ -495,6 +575,24 @@ export function createReviewHandler(options: ReviewPolicyOptions = {}): ResumeHa
|
|
|
495
575
|
if (answer.kind === 'approve-all') remembered.all = true
|
|
496
576
|
return { action: 'approve_tools', confirmedEscalations: escapes }
|
|
497
577
|
}
|
|
578
|
+
// A write to a protected path, or a removal of something catastrophic,
|
|
579
|
+
// is a question for a person, every time, in every mode that got this
|
|
580
|
+
// far: `auto` and a remembered "approve all" were answers given before
|
|
581
|
+
// the call existed. With nobody to ask it is refused, not approved.
|
|
582
|
+
if (request.toolCalls.some(reachesAFloor)) {
|
|
583
|
+
if (!prompt) return { action: 'reject_tools', feedback: floorRefusal(request.toolCalls) }
|
|
584
|
+
const answer = await ask()
|
|
585
|
+
if (answer.kind === 'reject') {
|
|
586
|
+
return {
|
|
587
|
+
action: 'reject_tools',
|
|
588
|
+
feedback: answer.feedback ?? DECLINED_TOOL_CALL_FEEDBACK,
|
|
589
|
+
...(answer.declined ? { declined: answer.declined } : {}),
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
// Latches for the ordinary calls that follow, never for the next floor.
|
|
593
|
+
if (answer.kind === 'approve-all') remembered.all = true
|
|
594
|
+
return { action: 'approve_tools' }
|
|
595
|
+
}
|
|
498
596
|
// A path outside the roots is a question for a person, every time,
|
|
499
597
|
// like an escape: `auto` and a remembered "approve all" were answers
|
|
500
598
|
// given about tools, before this path was named, and neither saw it.
|
|
@@ -571,15 +669,18 @@ export function createReviewHandler(options: ReviewPolicyOptions = {}): ResumeHa
|
|
|
571
669
|
(mode === 'accept-edits' && ACCEPT_EDITS_TOOLS.has(tc.name))
|
|
572
670
|
),
|
|
573
671
|
)
|
|
672
|
+
const skillsHonoured = options.skillGrants !== 'ignore'
|
|
574
673
|
if (
|
|
575
674
|
answered === undefined &&
|
|
576
|
-
options.skillGrants !== 'ignore' &&
|
|
577
675
|
needsPerson.length > 0 &&
|
|
578
|
-
needsPerson.every(isSkillGranted)
|
|
676
|
+
needsPerson.every((tc) => isHookGranted(tc) || (skillsHonoured && isSkillGranted(tc)))
|
|
579
677
|
) {
|
|
678
|
+
const byHook = needsPerson.filter(isHookGranted).map((tc) => tc.id)
|
|
679
|
+
const bySkill = needsPerson.filter((tc) => !isHookGranted(tc)).map((tc) => tc.id)
|
|
580
680
|
return {
|
|
581
681
|
action: 'approve_tools',
|
|
582
|
-
skillGranted:
|
|
682
|
+
...(bySkill.length > 0 ? { skillGranted: bySkill } : {}),
|
|
683
|
+
...(byHook.length > 0 ? { hookGranted: byHook } : {}),
|
|
583
684
|
}
|
|
584
685
|
}
|
|
585
686
|
const answer = await ask()
|
|
@@ -18,6 +18,19 @@ import { digest, spillManifest } from '../../store/evidence/format.js'
|
|
|
18
18
|
*/
|
|
19
19
|
export const DEFAULT_MAX_TOOL_OUTPUT_CHARS = 40_000
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Cap on the COMBINED model-visible text of every tool result one assistant
|
|
23
|
+
* message produced.
|
|
24
|
+
*
|
|
25
|
+
* The per-result cap alone lets eight parallel calls put 320,000 characters in
|
|
26
|
+
* front of the model at once. This is the bound on the whole batch; see
|
|
27
|
+
* {@link fitResultsToMessageBudget}.
|
|
28
|
+
*/
|
|
29
|
+
export const DEFAULT_MAX_TOOL_OUTPUT_CHARS_PER_MESSAGE = 200_000
|
|
30
|
+
|
|
31
|
+
/** Size of the preview that stands in for a result replaced to fit the message budget. */
|
|
32
|
+
export const MESSAGE_BUDGET_PREVIEW_CHARS = 2_000
|
|
33
|
+
|
|
21
34
|
/**
|
|
22
35
|
* Opening of the line that points at a spilled output.
|
|
23
36
|
*
|
|
@@ -298,7 +311,10 @@ function spill(
|
|
|
298
311
|
writeFileSync(path, bytes, { flag: 'wx', mode: 0o600 })
|
|
299
312
|
try {
|
|
300
313
|
const manifest = spillManifest(bytes)
|
|
301
|
-
writeFileSync(`${path}.manifest.json`, manifest, {
|
|
314
|
+
writeFileSync(`${path}.manifest.json`, manifest, {
|
|
315
|
+
flag: 'wx',
|
|
316
|
+
mode: 0o600,
|
|
317
|
+
})
|
|
302
318
|
return { path, integrity: digest(manifest) }
|
|
303
319
|
} catch {
|
|
304
320
|
onError?.('The full output was retained, but its integrity manifest could not be written.')
|
|
@@ -324,3 +340,101 @@ function spill(
|
|
|
324
340
|
return undefined
|
|
325
341
|
}
|
|
326
342
|
}
|
|
343
|
+
|
|
344
|
+
export interface MessageBudgetItem {
|
|
345
|
+
readonly toolCallId: string
|
|
346
|
+
readonly toolName: string
|
|
347
|
+
readonly output: string
|
|
348
|
+
/** False for a result that must stay as the tool produced it. */
|
|
349
|
+
readonly replaceable: boolean
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export interface MessageBudgetReplacement {
|
|
353
|
+
readonly output: string
|
|
354
|
+
readonly originalLength: number
|
|
355
|
+
readonly spillPath?: string
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export interface FitResultsToMessageBudgetOptions {
|
|
359
|
+
readonly maxChars: number
|
|
360
|
+
readonly spillDir?: string | undefined
|
|
361
|
+
readonly onError?: (message: string) => void
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const SPILL_LINE = new RegExp(`^${SPILL_MARKER} .+$`, 'm')
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Hold one assistant message's combined tool results under a cap.
|
|
368
|
+
*
|
|
369
|
+
* Replaceable results are replaced largest first, each by a short preview that
|
|
370
|
+
* names where its full text is kept, until the total is within `maxChars`. A
|
|
371
|
+
* result already spilled keeps the path it was given; one that was not is
|
|
372
|
+
* spilled now. Results that are not replaceable are left alone and are not
|
|
373
|
+
* counted, because nothing here could reduce them.
|
|
374
|
+
*
|
|
375
|
+
* The caller writes the replacement into the result BEFORE the result reaches
|
|
376
|
+
* the history. From then on it is just the message's content, so it is the
|
|
377
|
+
* same on every later request and a prompt-cache prefix over it stays valid;
|
|
378
|
+
* nothing is decided again on a later turn.
|
|
379
|
+
*
|
|
380
|
+
* Returns only the results that changed, keyed by `toolCallId`. Ties keep the
|
|
381
|
+
* earlier call, so the same batch always yields the same replacements.
|
|
382
|
+
*/
|
|
383
|
+
export function fitResultsToMessageBudget(
|
|
384
|
+
items: readonly MessageBudgetItem[],
|
|
385
|
+
opts: FitResultsToMessageBudgetOptions,
|
|
386
|
+
): Map<string, MessageBudgetReplacement> {
|
|
387
|
+
const replaced = new Map<string, MessageBudgetReplacement>()
|
|
388
|
+
if (!Number.isFinite(opts.maxChars) || opts.maxChars <= 0) return replaced
|
|
389
|
+
|
|
390
|
+
const candidates = items.filter((item) => item.replaceable)
|
|
391
|
+
let total = candidates.reduce((sum, item) => sum + item.output.length, 0)
|
|
392
|
+
if (total <= opts.maxChars) return replaced
|
|
393
|
+
|
|
394
|
+
const bySize = candidates
|
|
395
|
+
.map((item, index) => ({ item, index }))
|
|
396
|
+
.sort((a, b) => b.item.output.length - a.item.output.length || a.index - b.index)
|
|
397
|
+
|
|
398
|
+
for (const { item } of bySize) {
|
|
399
|
+
if (total <= opts.maxChars) break
|
|
400
|
+
const replacement = previewForMessageBudget(item, opts)
|
|
401
|
+
if (replacement.output.length >= item.output.length) continue
|
|
402
|
+
total -= item.output.length - replacement.output.length
|
|
403
|
+
replaced.set(item.toolCallId, replacement)
|
|
404
|
+
}
|
|
405
|
+
return replaced
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function previewForMessageBudget(
|
|
409
|
+
item: MessageBudgetItem,
|
|
410
|
+
opts: FitResultsToMessageBudgetOptions,
|
|
411
|
+
): MessageBudgetReplacement {
|
|
412
|
+
const spilledAt = SPILL_LINE.exec(item.output)?.[0]
|
|
413
|
+
if (spilledAt !== undefined) {
|
|
414
|
+
const output = [
|
|
415
|
+
safeHead(item.output, MESSAGE_BUDGET_PREVIEW_CHARS / 2),
|
|
416
|
+
'',
|
|
417
|
+
`[... omitted: this message's tool results together were over the ${opts.maxChars.toLocaleString()}-character budget ...]`,
|
|
418
|
+
spilledAt,
|
|
419
|
+
].join('\n')
|
|
420
|
+
return {
|
|
421
|
+
output,
|
|
422
|
+
originalLength: item.output.length,
|
|
423
|
+
spillPath: spilledAt.slice(SPILL_MARKER.length + 1),
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
const budgeted = applyToolOutputBudget({
|
|
427
|
+
toolName: item.toolName,
|
|
428
|
+
// A distinct name: the spill file is keyed by it and opened exclusively.
|
|
429
|
+
toolUseId: `${item.toolCallId}:message-budget`,
|
|
430
|
+
output: item.output,
|
|
431
|
+
maxChars: MESSAGE_BUDGET_PREVIEW_CHARS,
|
|
432
|
+
spillDir: opts.spillDir,
|
|
433
|
+
...(opts.onError ? { onError: opts.onError } : {}),
|
|
434
|
+
})
|
|
435
|
+
return {
|
|
436
|
+
output: budgeted.output,
|
|
437
|
+
originalLength: item.output.length,
|
|
438
|
+
...(budgeted.spillPath ? { spillPath: budgeted.spillPath } : {}),
|
|
439
|
+
}
|
|
440
|
+
}
|
|
@@ -54,6 +54,7 @@ export interface ToolingBootstrapConfig {
|
|
|
54
54
|
maxToolCalls?: number
|
|
55
55
|
readToolCallBudgetRecords?: () => Promise<readonly SessionRecord[]>
|
|
56
56
|
maxToolOutputChars?: number
|
|
57
|
+
maxToolOutputCharsPerMessage?: number
|
|
57
58
|
/** See `QueryParams.toolResultGuardrails`. Absent installs the shipped default; a registry's own win. */
|
|
58
59
|
toolResultGuardrails?: readonly import('../../types/guardrail/index.js').ToolResultGuardrailSpec[]
|
|
59
60
|
retainedToolPreviewChars?: number
|
|
@@ -119,6 +120,11 @@ export class ToolingBootstrap {
|
|
|
119
120
|
...(config.maxToolOutputChars !== undefined
|
|
120
121
|
? { maxToolOutputChars: config.maxToolOutputChars }
|
|
121
122
|
: {}),
|
|
123
|
+
...(config.maxToolOutputCharsPerMessage !== undefined
|
|
124
|
+
? {
|
|
125
|
+
maxToolOutputCharsPerMessage: config.maxToolOutputCharsPerMessage,
|
|
126
|
+
}
|
|
127
|
+
: {}),
|
|
122
128
|
...(config.toolResultGuardrails !== undefined
|
|
123
129
|
? { toolResultGuardrails: config.toolResultGuardrails }
|
|
124
130
|
: {}),
|
package/src/session/paths.ts
CHANGED
|
@@ -28,7 +28,7 @@ import { uuidv7 } from '../utils/uuidv7.js'
|
|
|
28
28
|
* <session-id>.jsonl the session log (source of truth)
|
|
29
29
|
* <session-id>/
|
|
30
30
|
* subagents/<child-id>.jsonl, <child-id>.meta.json, <child-id>/subagents/…
|
|
31
|
-
* tool-results/ checkpoints/ budgets/ tasks/ feedback/ goals/
|
|
31
|
+
* tool-results/ checkpoints/ budgets/ tasks/ plans/ feedback/ goals/
|
|
32
32
|
* file-history/ lease.json
|
|
33
33
|
* $TMPDIR/namzu-<user>/<slug>/<session-id>/scratchpad/
|
|
34
34
|
* ```
|
|
@@ -412,6 +412,16 @@ export class SessionPaths {
|
|
|
412
412
|
return join(this.sessionDir(locator), 'tasks')
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
+
/** The session's plan directory; a host that has a plan mode keeps its one plan file here. */
|
|
416
|
+
plans(locator: SessionLocator): string {
|
|
417
|
+
return join(this.sessionDir(locator), 'plans')
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/** The one file a session's plan mode may write: `<session-id>/plans/plan.md`. */
|
|
421
|
+
planFile(locator: SessionLocator): string {
|
|
422
|
+
return join(this.plans(locator), 'plan.md')
|
|
423
|
+
}
|
|
424
|
+
|
|
415
425
|
taskFile(locator: SessionLocator, taskId: TaskId): string {
|
|
416
426
|
return join(this.tasks(locator), `${checkId(taskId, 'task')}.json`)
|
|
417
427
|
}
|
package/src/store/memory/disk.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { InMemoryMemoryIndex, searchMemoryEntries, selectMemorySearchCandidates
|
|
|
23
23
|
import {
|
|
24
24
|
MemoryNameConflictError,
|
|
25
25
|
assertOptionalMemoryFields,
|
|
26
|
+
entryPath,
|
|
26
27
|
isMemoryName,
|
|
27
28
|
nameHolder,
|
|
28
29
|
withOptionalFields,
|
|
@@ -228,7 +229,7 @@ export class DiskMemoryStore implements ConditionalMemoryStore {
|
|
|
228
229
|
|
|
229
230
|
private contentPath(location: StorageLocation, id: MemoryId): string {
|
|
230
231
|
assertStorageMemoryId(id, (reason) => invalidContent(id, reason, { field: 'id' }))
|
|
231
|
-
const path = resolve(location.contentDir,
|
|
232
|
+
const path = resolve(entryPath(location.contentDir, id, '.json'))
|
|
232
233
|
if (dirname(path) !== location.contentDir) {
|
|
233
234
|
invalidContent(id, 'resolved path escapes the content directory', { field: 'id' })
|
|
234
235
|
}
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
MemoryContentRejectedError,
|
|
39
39
|
MemoryNameConflictError,
|
|
40
40
|
assertOptionalMemoryFields,
|
|
41
|
+
entryPath,
|
|
41
42
|
isMemoryName,
|
|
42
43
|
nameHolder,
|
|
43
44
|
slugifyMemoryName,
|
|
@@ -327,7 +328,7 @@ export class MarkdownMemoryStore implements ConditionalMemoryStore {
|
|
|
327
328
|
|
|
328
329
|
private memoryPath(dir: string, name: string): string {
|
|
329
330
|
if (!isMemoryName(name)) invalidFile(join(dir, `${name}.md`), 'name is not a memory name')
|
|
330
|
-
const path = resolve(dir,
|
|
331
|
+
const path = resolve(entryPath(dir, name, '.md'))
|
|
331
332
|
if (dirname(path) !== dir) invalidFile(path, 'resolved path escapes the memory directory')
|
|
332
333
|
return path
|
|
333
334
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sep } from 'node:path'
|
|
1
2
|
import { NamzuError } from '../../types/errors/index.js'
|
|
2
3
|
import type { MemoryId } from '../../types/ids/index.js'
|
|
3
4
|
import type {
|
|
@@ -193,3 +194,15 @@ export function withOptionalFields(
|
|
|
193
194
|
...(type !== undefined ? { type } : {}),
|
|
194
195
|
}
|
|
195
196
|
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* The path of one entry file: `dir`, a separator, `stem`, `extension`, before
|
|
200
|
+
* the caller resolves it. Written as plain concatenation on purpose. A static
|
|
201
|
+
* file tracer (the kind standalone-output builds use) evaluates
|
|
202
|
+
* `path.resolve(dir, `${stem}.ext`)` with an unknown `dir` as a wildcard and
|
|
203
|
+
* lists every `.ext` file under the repository as a runtime asset; it does not
|
|
204
|
+
* evaluate string concatenation, so this form leaves it nothing to expand.
|
|
205
|
+
*/
|
|
206
|
+
export function entryPath(dir: string, stem: string, extension: string): string {
|
|
207
|
+
return dir + sep + stem + extension
|
|
208
|
+
}
|