@sema-agent/core 7.51.1 → 7.52.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 +550 -2
- package/dist/agents/agent-transcript-tool.d.ts +1 -1
- package/dist/agents/cascade.js +4 -0
- package/dist/agents/cumulative-stats.d.ts +3 -0
- package/dist/agents/cumulative-stats.js +3 -0
- package/dist/agents/list-agents-tool.d.ts +1 -1
- package/dist/agents/read-inbox-tool.d.ts +1 -1
- package/dist/agents/repair-loop.js +4 -0
- package/dist/agents/send-message-tool.d.ts +11 -16
- package/dist/agents/send-message-tool.js +11 -13
- package/dist/agents/subagent.d.ts +5 -0
- package/dist/agents/subagent.js +7 -4
- package/dist/agents/tool-filter.d.ts +40 -13
- package/dist/agents/tool-filter.js +28 -14
- package/dist/bench/metrics.d.ts +1 -0
- package/dist/brain/anthropic.js +16 -12
- package/dist/brain/model-presets.d.ts +4 -5
- package/dist/brain/model-presets.js +4 -4
- package/dist/brain/open-responses.js +16 -12
- package/dist/brain/openai.js +16 -12
- package/dist/brain/request-params.d.ts +12 -33
- package/dist/brain/request-params.js +5 -2
- package/dist/brain/request-route.d.ts +9 -8
- package/dist/brain/request-route.js +1 -0
- package/dist/brain/route-adjudicator.d.ts +117 -47
- package/dist/brain/route-adjudicator.js +171 -42
- package/dist/brain/route-conformance.js +2 -2
- package/dist/brain/status-sink.d.ts +18 -0
- package/dist/brain/status-sink.js +7 -0
- package/dist/core/allow-entry.d.ts +42 -8
- package/dist/core/allow-entry.js +24 -17
- package/dist/core/auto-compaction.d.ts +23 -20
- package/dist/core/auto-compaction.js +37 -16
- package/dist/core/auto-promote.d.ts +2 -1
- package/dist/core/auto-promote.js +2 -2
- package/dist/core/caller-tool-name.d.ts +9 -0
- package/dist/core/caller-tool-name.js +13 -0
- package/dist/core/checkpoint-requirements.d.ts +7 -1
- package/dist/core/checkpoint-requirements.js +2 -0
- package/dist/core/checkpoint-store.d.ts +36 -12
- package/dist/core/checkpoint-store.js +1 -1
- package/dist/core/child-clamp-seats.d.ts +6 -0
- package/dist/core/child-clamp-seats.js +2 -1
- package/dist/core/credential-vocabulary.d.ts +33 -8
- package/dist/core/credential-vocabulary.js +32 -7
- package/dist/core/decision-receipt.d.ts +2 -2
- package/dist/core/delegation-frames.d.ts +9 -2
- package/dist/core/delegation-name.d.ts +18 -0
- package/dist/core/delegation-name.js +47 -0
- package/dist/core/engine-capabilities.d.ts +8 -1
- package/dist/core/engine-capabilities.js +1 -1
- package/dist/core/engine-notice.d.ts +36 -19
- package/dist/core/frontmatter-fence.d.ts +10 -0
- package/dist/core/frontmatter-fence.js +6 -0
- package/dist/core/gate-fold.js +5 -23
- package/dist/core/gate-lanes.js +356 -270
- package/dist/core/governance-codes.d.ts +9 -4
- package/dist/core/governance-codes.js +9 -3
- package/dist/core/hooks.d.ts +276 -734
- package/dist/core/hooks.js +97 -192
- package/dist/{tools/fs → core}/image-admission.d.ts +21 -3
- package/dist/{tools/fs → core}/image-admission.js +24 -6
- package/dist/core/locked-config.d.ts +26 -5
- package/dist/core/locked-config.js +31 -6
- package/dist/core/mcp-connection-pool.d.ts +4 -1
- package/dist/core/mcp-connection-pool.js +7 -2
- package/dist/core/mcp-probe.d.ts +12 -9
- package/dist/core/mcp-probe.js +2 -2
- package/dist/core/mcp-server-spec.d.ts +53 -7
- package/dist/core/mcp-server-spec.js +84 -1
- package/dist/core/mcp.d.ts +11 -7
- package/dist/core/mcp.js +27 -9
- package/dist/core/memory-engine/data-plane.js +5 -1
- package/dist/core/memory-engine/distiller.js +16 -2
- package/dist/core/memory-engine/engine.d.ts +8 -11
- package/dist/core/memory-engine/engine.js +9 -5
- package/dist/core/memory-engine/frontmatter.d.ts +6 -0
- package/dist/core/memory-engine/frontmatter.js +19 -16
- package/dist/core/memory.d.ts +2 -2
- package/dist/core/mode-policy.d.ts +4 -0
- package/dist/core/mode-policy.js +7 -5
- package/dist/core/model-seat.d.ts +4 -1
- package/dist/core/mods/dollar.d.ts +109 -0
- package/dist/core/mods/dollar.js +154 -0
- package/dist/core/mods/host.d.ts +23 -0
- package/dist/core/mods/host.js +21 -0
- package/dist/core/mods/kernel/budget.d.ts +43 -0
- package/dist/core/mods/kernel/budget.js +83 -0
- package/dist/core/mods/kernel/dispatch.d.ts +100 -0
- package/dist/core/mods/kernel/dispatch.js +701 -0
- package/dist/core/mods/kernel/events.d.ts +242 -0
- package/dist/core/mods/kernel/events.js +210 -0
- package/dist/core/mods/kernel/index.d.ts +6 -0
- package/dist/core/mods/kernel/index.js +5 -0
- package/dist/core/mods/kernel/receive.d.ts +65 -0
- package/dist/core/mods/kernel/receive.js +123 -0
- package/dist/core/mods/kernel/registration.d.ts +131 -0
- package/dist/core/mods/kernel/registration.js +102 -0
- package/dist/core/mods/kernel/site-rules.d.ts +84 -0
- package/dist/core/mods/kernel/site-rules.js +104 -0
- package/dist/core/mods/stations.d.ts +350 -0
- package/dist/core/mods/stations.js +444 -0
- package/dist/core/own-property-receipt.js +11 -23
- package/dist/core/parent-spec-seat.d.ts +18 -7
- package/dist/core/parent-spec-seat.js +6 -2
- package/dist/core/path-identity.js +2 -1
- package/dist/core/permission-rule-syntax.d.ts +15 -0
- package/dist/core/permission-rule-syntax.js +24 -16
- package/dist/core/permission-rules.d.ts +7 -1
- package/dist/core/permission-rules.js +26 -15
- package/dist/core/prompt-section-seat.d.ts +15 -27
- package/dist/core/prompt-section-seat.js +73 -40
- package/dist/core/protocol-http-auth.d.ts +3 -1
- package/dist/core/protocol-http-auth.js +2 -0
- package/dist/core/reminder-mint.d.ts +2 -2
- package/dist/core/remote-env.d.ts +24 -12
- package/dist/core/remote-env.js +1 -0
- package/dist/core/resume-startup-cause.d.ts +16 -1
- package/dist/core/resume-startup-cause.js +4 -1
- package/dist/core/retired-keys.d.ts +4 -0
- package/dist/core/retired-keys.js +3 -0
- package/dist/core/runner/announce-once-ledger.d.ts +31 -1
- package/dist/core/runner/announce-once-ledger.js +22 -0
- package/dist/core/runner/assemble-result.d.ts +9 -0
- package/dist/core/runner/assemble-result.js +3 -1
- package/dist/core/runner/call-hook-stations.d.ts +23 -27
- package/dist/core/runner/call-hook-stations.js +58 -42
- package/dist/core/runner/caller-stop-gate.d.ts +25 -0
- package/dist/core/runner/caller-stop-gate.js +7 -0
- package/dist/core/runner/compaction-seams.d.ts +8 -22
- package/dist/core/runner/compaction-seams.js +28 -53
- package/dist/core/runner/construction-doors.js +11 -1
- package/dist/core/runner/contracts.d.ts +85 -83
- package/dist/core/runner/credential-origin-seat.d.ts +2 -0
- package/dist/core/runner/credential-origin-seat.js +19 -0
- package/dist/core/runner/extra-body-dropped-seat.d.ts +2 -6
- package/dist/core/runner/gate-exit.d.ts +47 -36
- package/dist/core/runner/gate-exit.js +8 -2
- package/dist/core/runner/image.js +1 -2
- package/dist/core/runner/inline-image.js +1 -1
- package/dist/core/runner/notice-seat-input.d.ts +11 -0
- package/dist/core/runner/notice-seat-input.js +1 -0
- package/dist/core/runner/person-path-rows.js +1 -0
- package/dist/core/runner/prepare-acquire-reconcile.js +5 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +5 -7
- package/dist/core/runner/prepare-ask-lane.js +6 -15
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -2
- package/dist/core/runner/prepare-caps-and-workflow.js +25 -8
- package/dist/core/runner/prepare-config-doors.d.ts +5 -0
- package/dist/core/runner/prepare-config-doors.js +9 -0
- package/dist/core/runner/prepare-defer-classify.js +3 -4
- package/dist/core/runner/prepare-gate-stations.d.ts +8 -11
- package/dist/core/runner/prepare-gate-stations.js +11 -10
- package/dist/core/runner/prepare-inherited-gate.d.ts +8 -12
- package/dist/core/runner/prepare-inherited-gate.js +8 -21
- package/dist/core/runner/prepare-memory-engine-session.js +1 -1
- package/dist/core/runner/prepare-park-ask.js +10 -14
- package/dist/core/runner/prepare-policy-chain.d.ts +18 -16
- package/dist/core/runner/prepare-policy-chain.js +98 -101
- package/dist/core/runner/prepare-project-context.js +7 -10
- package/dist/core/runner/prepare-prompt-assembly.d.ts +45 -40
- package/dist/core/runner/prepare-prompt-assembly.js +134 -101
- package/dist/core/runner/prepare-prompt-inputs.d.ts +18 -19
- package/dist/core/runner/prepare-prompt-inputs.js +5 -7
- package/dist/core/runner/prepare-protocol-tools.d.ts +6 -4
- package/dist/core/runner/prepare-protocol-tools.js +2 -2
- package/dist/core/runner/prepare-safety-scan.js +6 -10
- package/dist/core/runner/prepare-suspend-saga.d.ts +6 -0
- package/dist/core/runner/prepare-suspend-saga.js +7 -5
- package/dist/core/runner/prepare-task.js +33 -15
- package/dist/core/runner/prepare-turn-wiring.d.ts +13 -15
- package/dist/core/runner/prepare-turn-wiring.js +29 -27
- package/dist/core/runner/prepare-wiring-manifest.d.ts +5 -6
- package/dist/core/runner/prepare-wiring-manifest.js +7 -7
- package/dist/core/runner/resume-apply.d.ts +5 -2
- package/dist/core/runner/resume-apply.js +24 -42
- package/dist/core/runner/resume-checkpoint-screen.d.ts +1 -0
- package/dist/core/runner/resume-checkpoint-screen.js +9 -1
- package/dist/core/runner/resume-preflight.js +38 -16
- package/dist/core/runner/retired-runner-deps.js +3 -1
- package/dist/core/runner/run-brain-sinks.d.ts +3 -2
- package/dist/core/runner/run-brain-sinks.js +5 -1
- package/dist/core/runner/run-compaction-machinery.d.ts +7 -1
- package/dist/core/runner/run-compaction-machinery.js +7 -33
- package/dist/core/runner/run-harness-handlers.js +4 -2
- package/dist/core/runner/run-identity-wiring.d.ts +3 -1
- package/dist/core/runner/run-identity-wiring.js +3 -2
- package/dist/core/runner/run-leg.js +62 -84
- package/dist/core/runner/run-notification-lane.js +1 -0
- package/dist/core/runner/run-recovery-lanes.d.ts +3 -0
- package/dist/core/runner/run-recovery-lanes.js +11 -10
- package/dist/core/runner/run-settle-and-teardown.js +9 -28
- package/dist/core/runner/run-stop-and-final-verify.js +18 -25
- package/dist/core/runner/run-terminal-adoption.d.ts +3 -0
- package/dist/core/runner/run-terminal-adoption.js +33 -22
- package/dist/core/runner/run-tool-mount-facts.js +5 -3
- package/dist/core/runner/run-turn-boundary.js +23 -34
- package/dist/core/runner/runtask.d.ts +6 -7
- package/dist/core/runner/runtask.js +14 -72
- package/dist/core/runner/session-rule-policy.d.ts +6 -4
- package/dist/core/runner/session-rule-policy.js +17 -10
- package/dist/core/runner/side-call-account.d.ts +68 -0
- package/dist/core/runner/side-call-account.js +61 -0
- package/dist/core/runner/stream-halt-verbs.js +12 -17
- package/dist/core/runner/stream-lifecycle-verbs.js +8 -5
- package/dist/core/runner/stream-steer-verb.d.ts +1 -1
- package/dist/core/runner/stream-steer-verb.js +20 -38
- package/dist/core/runner/sub-agent-deny-lists.d.ts +121 -22
- package/dist/core/runner/sub-agent-deny-lists.js +228 -71
- package/dist/core/runner/tool-end-body.d.ts +5 -6
- package/dist/core/runner/tool-end-body.js +6 -4
- package/dist/core/runner/tool-not-executed.d.ts +15 -0
- package/dist/core/runner/tool-not-executed.js +30 -0
- package/dist/core/runner/tool-occurrence.d.ts +8 -7
- package/dist/core/runner/tool-occurrence.js +5 -5
- package/dist/core/runner/tool-result-media-seat.d.ts +1 -1
- package/dist/core/runner-deps.d.ts +20 -28
- package/dist/core/safety-merge-corpus.js +18 -2
- package/dist/core/secret-env.d.ts +93 -20
- package/dist/core/secret-env.js +192 -38
- package/dist/core/session-policy-store.d.ts +93 -17
- package/dist/core/session-policy-store.js +178 -25
- package/dist/core/session-reconcile.d.ts +4 -0
- package/dist/core/session-reconcile.js +2 -1
- package/dist/core/shell-read-silence.js +3 -32
- package/dist/core/side-query.d.ts +5 -3
- package/dist/core/skill-grant.d.ts +3 -2
- package/dist/core/skill-grant.js +17 -9
- package/dist/core/skills-directory.d.ts +31 -11
- package/dist/core/skills-directory.js +655 -104
- package/dist/core/task-event.d.ts +13 -3
- package/dist/core/task-result.d.ts +8 -0
- package/dist/core/task-spec.d.ts +20 -19
- package/dist/core/task-stream.d.ts +14 -4
- package/dist/core/tighten-task-spec.d.ts +4 -3
- package/dist/core/tighten-task-spec.js +2 -4
- package/dist/core/tool-check-reading.d.ts +74 -0
- package/dist/core/tool-check-reading.js +80 -0
- package/dist/core/tool-policy.d.ts +59 -18
- package/dist/core/tool-policy.js +77 -12
- package/dist/core/tool-registry.d.ts +20 -0
- package/dist/core/tool-registry.js +4 -0
- package/dist/core/tool-spec.d.ts +10 -6
- package/dist/core/tools.js +2 -0
- package/dist/core/trace.d.ts +51 -32
- package/dist/core/types.d.ts +2 -1
- package/dist/core/types.js +1 -0
- package/dist/core/unc-spelling.d.ts +10 -0
- package/dist/core/unc-spelling.js +3 -0
- package/dist/core/untrusted-egress.d.ts +8 -0
- package/dist/core/untrusted-egress.js +4 -1
- package/dist/core/user-attachment.d.ts +12 -2
- package/dist/core/user-attachment.js +17 -2
- package/dist/core/wiring-manifest.d.ts +14 -13
- package/dist/core/wiring-manifest.js +2 -2
- package/dist/engine/compaction/utils.js +1 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +4 -3
- package/dist/engine/execution-env/symlink-chain.js +1 -1
- package/dist/engine/harness/agent-harness.d.ts +1 -1
- package/dist/engine/harness/agent-harness.js +3 -3
- package/dist/engine/harness/types.d.ts +17 -16
- package/dist/engine/harness/types.js +7 -1
- package/dist/engine/llm/types.d.ts +12 -7
- package/dist/engine/loop/agent-loop.js +1 -1
- package/dist/engine/loop/types.d.ts +1 -1
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
- package/dist/engine/session/import-validate.js +3 -10
- package/dist/engine/session/session.d.ts +4 -4
- package/dist/engine/session/session.js +4 -4
- package/dist/index.d.ts +24 -17
- package/dist/index.js +15 -12
- package/dist/internal/harness.d.ts +1 -1
- package/dist/internal/harness.js +1 -1
- package/dist/orchestration/run-spec.d.ts +4 -6
- package/dist/orchestration/run-spec.js +39 -63
- package/dist/orchestration/run-workflow-tool.js +1 -2
- package/dist/orchestration/workflow.d.ts +11 -3
- package/dist/orchestration/workflow.js +11 -2
- package/dist/prompt-assembly/artifact-store.d.ts +37 -56
- package/dist/prompt-assembly/artifact-store.js +31 -49
- package/dist/prompt-assembly/artifact.d.ts +89 -76
- package/dist/prompt-assembly/artifact.js +167 -146
- package/dist/prompt-assembly/assemble.d.ts +34 -29
- package/dist/prompt-assembly/assemble.js +33 -220
- package/dist/prompt-assembly/bands.d.ts +20 -0
- package/dist/prompt-assembly/bands.js +18 -0
- package/dist/prompt-assembly/catalog/constitution.d.ts +23 -0
- package/dist/prompt-assembly/catalog/constitution.js +69 -0
- package/dist/prompt-assembly/catalog/core-behavior.d.ts +9 -0
- package/dist/prompt-assembly/catalog/core-behavior.js +85 -0
- package/dist/prompt-assembly/catalog/index.d.ts +11 -0
- package/dist/prompt-assembly/catalog/index.js +59 -0
- package/dist/prompt-assembly/catalog/modes.d.ts +15 -0
- package/dist/prompt-assembly/catalog/modes.js +137 -0
- package/dist/prompt-assembly/catalog/role.d.ts +10 -0
- package/dist/prompt-assembly/catalog/role.js +157 -0
- package/dist/prompt-assembly/catalog/schema.d.ts +124 -0
- package/dist/prompt-assembly/catalog/schema.js +25 -0
- package/dist/prompt-assembly/catalog/sections.d.ts +9 -0
- package/dist/prompt-assembly/catalog/sections.js +98 -0
- package/dist/prompt-assembly/catalog/team.d.ts +4 -0
- package/dist/prompt-assembly/catalog/team.js +258 -0
- package/dist/prompt-assembly/composer.d.ts +24 -28
- package/dist/prompt-assembly/composer.js +124 -46
- package/dist/prompt-assembly/epoch.d.ts +89 -79
- package/dist/prompt-assembly/epoch.js +115 -142
- package/dist/prompt-assembly/explain.d.ts +58 -34
- package/dist/prompt-assembly/explain.js +21 -24
- package/dist/prompt-assembly/overlay.d.ts +127 -0
- package/dist/prompt-assembly/overlay.js +301 -0
- package/dist/prompt-assembly/renderers.d.ts +21 -0
- package/dist/prompt-assembly/renderers.js +39 -0
- package/dist/prompt-assembly/section-usage.d.ts +3 -3
- package/dist/prompt-assembly/section-usage.js +1 -1
- package/dist/prompt-assembly/select.d.ts +56 -0
- package/dist/prompt-assembly/select.js +69 -0
- package/dist/prompt-assembly/sugar.d.ts +31 -0
- package/dist/prompt-assembly/sugar.js +20 -0
- package/dist/prompt-assembly/turn-snapshot.d.ts +3 -2
- package/dist/prompt-assembly/types.d.ts +45 -148
- package/dist/prompts/coordinator.d.ts +2 -21
- package/dist/prompts/coordinator.js +3 -255
- package/dist/prompts/cowork.d.ts +27 -16
- package/dist/prompts/cowork.js +2 -23
- package/dist/prompts/default.d.ts +38 -500
- package/dist/prompts/default.js +20 -285
- package/dist/prompts/supervisor.d.ts +6 -71
- package/dist/prompts/supervisor.js +6 -117
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/dist/tools/fs/bash-readonly-classifier.d.ts +6 -5
- package/dist/tools/fs/dir-entries.d.ts +4 -2
- package/dist/tools/fs/dir-entries.js +16 -4
- package/dist/tools/fs/fs-bash.d.ts +1 -1
- package/dist/tools/fs/fs-bash.js +22 -11
- package/dist/tools/fs/fs-pdf.js +17 -13
- package/dist/tools/fs/fs-read.js +4 -3
- package/dist/tools/fs/fs-shared.d.ts +1 -10
- package/dist/tools/fs/fs-shared.js +3 -4
- package/dist/tools/fs/fs-write.js +2 -1
- package/dist/tools/fs/notebook.js +1 -1
- package/dist/tools/fs/pdf.d.ts +20 -10
- package/dist/tools/fs/pdf.js +19 -10
- package/dist/tools/fs/program-read-model.d.ts +68 -8
- package/dist/tools/fs/program-read-model.js +112 -33
- package/dist/tools/fs/program-read-model.rows.js +30 -10
- package/dist/tools/fs/read-deny-home.d.ts +25 -9
- package/dist/tools/fs/read-deny-home.js +28 -27
- package/dist/tools/fs/read-deny.d.ts +41 -11
- package/dist/tools/fs/read-deny.js +51 -5
- package/dist/tools/fs/safety.d.ts +4 -26
- package/dist/tools/fs/safety.js +10 -32
- package/dist/tools/fs/search.js +15 -10
- package/dist/tools/fs/shell-read-argv.d.ts +3 -2
- package/dist/tools/fs/shell-read-argv.js +118 -38
- package/dist/tools/fs/shell-read-establish.d.ts +5 -5
- package/dist/tools/fs/shell-read-establish.js +11 -61
- package/dist/tools/fs/shell-read-identity.js +6 -3
- package/dist/tools/fs/shell-read-judge.d.ts +13 -15
- package/dist/tools/fs/shell-read-judge.js +18 -4
- package/dist/tools/fs/shell-read-plan.d.ts +2 -2
- package/dist/tools/web.js +1 -1
- package/package.json +13 -1
- package/test/export-surface.snapshot.json +256 -99
- package/wire-changes/core@7.51.1.json +5 -5
- package/wire-changes/core@7.51.2.json +293 -0
- package/wire-changes/core@7.52.0.json +5859 -0
- package/dist/core/hook-seats.d.ts +0 -66
- package/dist/core/hook-seats.js +0 -37
- package/dist/prompt-assembly/packs/sema-default.d.ts +0 -2
- package/dist/prompt-assembly/packs/sema-default.js +0 -147
- package/dist/prompts/simple-sections.d.ts +0 -58
- package/dist/prompts/simple-sections.js +0 -43
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* judging was cut short by an abort — the listing is a prefix, not the directory).
|
|
23
23
|
*/
|
|
24
24
|
import type { ExecutionEnv } from "../../internal/harness-types.js";
|
|
25
|
-
import
|
|
25
|
+
import { FileError, type FileInfo, type FileKind, type Result } from "../../internal/harness.js";
|
|
26
26
|
import { type HomeViewEnv, type HomeViewsCarrier } from "./read-deny-home.js";
|
|
27
27
|
/** The upstream at-mention's cap on listed entries. */
|
|
28
28
|
export declare const DIRECTORY_LISTING_MAX_ENTRIES = 1000;
|
|
@@ -37,7 +37,9 @@ export type EntryDenyTable = {
|
|
|
37
37
|
export type EntryDenyJudge = (path: string, leaf?: "file") => Promise<{
|
|
38
38
|
pattern: string;
|
|
39
39
|
} | null>;
|
|
40
|
-
/** The per-entry judge over `deny` (literal spelling, then the home view).
|
|
40
|
+
/** The per-entry judge over `deny` (literal spelling, then the home view). An entry whose home view nobody could read is not
|
|
41
|
+
* an entry with no view: the judgment of the traversal did not finish, and the call is refused whole
|
|
42
|
+
* ({@link HomeViewUnreadError}, thrown) — what the walk would serve was not judged, so neither it nor a partial result is. */
|
|
41
43
|
export declare function createEntryDenyJudge(env: HomeViewEnv, deny: EntryDenyTable, signal?: AbortSignal): EntryDenyJudge;
|
|
42
44
|
export interface DirectoryEntry {
|
|
43
45
|
name: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FileError } from "../../internal/harness.js";
|
|
2
|
+
import { HomeViewUnreadError, homeViewsOf } from "./read-deny-home.js";
|
|
2
3
|
import { DATA_LABEL_UNSAFE, quoteDataLabel } from "../../internal/llm.js";
|
|
3
4
|
export const DIRECTORY_LISTING_MAX_ENTRIES = 1000;
|
|
4
5
|
export function createEntryDenyJudge(env, deny, signal) {
|
|
@@ -7,8 +8,11 @@ export function createEntryDenyJudge(env, deny, signal) {
|
|
|
7
8
|
const hit = deny.matchPath(path);
|
|
8
9
|
if (hit)
|
|
9
10
|
return hit;
|
|
10
|
-
const
|
|
11
|
-
|
|
11
|
+
const home = await views.of(path, leaf !== undefined ? { leaf } : undefined);
|
|
12
|
+
const viewHit = home.view !== undefined ? deny.matchPath(home.view) : null;
|
|
13
|
+
if (viewHit === null && home.unread !== undefined)
|
|
14
|
+
throw new HomeViewUnreadError(path, home.unread);
|
|
15
|
+
return viewHit;
|
|
12
16
|
};
|
|
13
17
|
}
|
|
14
18
|
export async function enumerateDirectory(env, dir, judge, signal, list = (d) => env.listDir(d, signal)) {
|
|
@@ -25,7 +29,15 @@ export async function enumerateDirectory(env, dir, judge, signal, list = (d) =>
|
|
|
25
29
|
incomplete = true;
|
|
26
30
|
break;
|
|
27
31
|
}
|
|
28
|
-
|
|
32
|
+
let hit;
|
|
33
|
+
try {
|
|
34
|
+
hit = judge === undefined ? null : await judge(info.path, info.kind === "directory" ? undefined : "file");
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
if (e instanceof HomeViewUnreadError)
|
|
38
|
+
return { ok: false, error: new FileError("unknown", e.message, info.path) };
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
29
41
|
if (hit) {
|
|
30
42
|
omitted++;
|
|
31
43
|
if (!omittedPatterns.includes(hit.pattern))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AgentTool, type ExecutionEnv } from "../../internal/harness.js";
|
|
2
2
|
import { type TaskRegistry } from "../../core/task-registry.js";
|
|
3
3
|
import { type CwdRef } from "./fs-shared.js";
|
|
4
4
|
import type { ReversibilityVerdict } from "../../core/types.js";
|
package/dist/tools/fs/fs-bash.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
import { defineTool, errorResult } from "../../core/tools.js";
|
|
4
|
+
import { isTimeCutCode } from "../../internal/harness.js";
|
|
4
5
|
import { defaultTaskRegistry } from "../../core/task-registry.js";
|
|
5
6
|
import { accountDroppedBytes, spoolDropNote } from "../../core/task-registry-shared.js";
|
|
6
7
|
import { RollingTailBuffer } from "../../core/exec-output-tail.js";
|
|
@@ -8,7 +9,8 @@ import { TASK_OUTPUT_TOOL_NAME, TASK_STOP_TOOL_NAME, TASK_OUTPUT_MISSING_ID_MESS
|
|
|
8
9
|
import { envDeclaresRetain, hasBackgroundShell, retainsBackgroundProcesses } from "../../core/background-shell.js";
|
|
9
10
|
import { delimitUntrusted } from "../../core/untrusted-text.js";
|
|
10
11
|
import { MCP_IMAGE_MAX_BASE64 } from "../../core/mcp.js";
|
|
11
|
-
import {
|
|
12
|
+
import { withinAnyRoot } from "./safety.js";
|
|
13
|
+
import { imageMagicMatches } from "../../core/image-admission.js";
|
|
12
14
|
import { isDeadCwd, diagnoseDeadCwd } from "./dead-cwd.js";
|
|
13
15
|
import { boundaryIsTheSandbox, hasDestroy, isIsolated } from "../../core/remote-env.js";
|
|
14
16
|
import { ghRateLimitHint } from "./gh-rate-limit.js";
|
|
@@ -375,7 +377,7 @@ async function runShell(env, cwd, toolName, command, timeoutSec, caps, signal, c
|
|
|
375
377
|
isError: true,
|
|
376
378
|
};
|
|
377
379
|
}
|
|
378
|
-
if (res.error.code
|
|
380
|
+
if (isTimeCutCode(res.error.code) || res.error.code === "aborted" || res.error.code === "callback_error") {
|
|
379
381
|
const rawStdout = res.error.partialStdout ?? "";
|
|
380
382
|
const rawStderr = res.error.partialStderr ?? "";
|
|
381
383
|
const cutOverflowFile = rawStdout.length > bashMaxOutputChars() || rawStderr.length > bashMaxOutputChars()
|
|
@@ -383,19 +385,26 @@ async function runShell(env, cwd, toolName, command, timeoutSec, caps, signal, c
|
|
|
383
385
|
: undefined;
|
|
384
386
|
const pStdout = clipShellOutput(rawStdout);
|
|
385
387
|
const pStderr = clipShellOutput(rawStderr);
|
|
388
|
+
const noOutputSec = res.error.code === "liveness_no_output" && typeof res.error.noOutputSec === "number" && Number.isFinite(res.error.noOutputSec) && Math.floor(res.error.noOutputSec) >= 1
|
|
389
|
+
? Math.floor(res.error.noOutputSec)
|
|
390
|
+
: undefined;
|
|
386
391
|
const headline = res.error.code === "timeout"
|
|
387
392
|
? cappedByMaxTimeout
|
|
388
393
|
? `Command timed out after ${timeout}s — requested ${requestedSec}s, capped at ${caps.maxSec}s (engine ceiling: requests above ${caps.maxSec}s are reduced to it). The process was killed; output produced before the cutoff is shown below. Re-running with a larger timeout gets the same ${caps.maxSec}s ceiling — use run_in_background for work that needs longer, a narrower command, or resume from the partial progress below.`
|
|
389
394
|
: `Command timed out after ${timeout}s (timeout limit: ${timeout}s). The process was killed; output produced before the cutoff is shown below. Re-running the same command will likely time out again — consider run_in_background for long commands, a narrower command, or resuming from the partial progress below.`
|
|
390
|
-
: res.error.code === "
|
|
391
|
-
? `Command was
|
|
392
|
-
:
|
|
395
|
+
: res.error.code === "liveness_no_output"
|
|
396
|
+
? `Command was killed after producing no output for ${noOutputSec !== undefined ? `${noOutputSec}s` : "the environment's no-output window"} (a command that writes nothing to stdout or stderr that long is treated as hung; this is not the timeout you requested). Output produced before the cutoff is shown below. Re-running the same command will likely stall the same way — make it print progress as it works, use run_in_background for long quiet commands, or split it into smaller steps.`
|
|
397
|
+
: res.error.code === "aborted"
|
|
398
|
+
? `Command was interrupted (aborted) before completion. Output produced before the interrupt is shown below.`
|
|
399
|
+
: `Command started but its completion could not be observed — a host-side output-stream callback failed mid-run and the process was terminated (${res.error.message}). Output captured before the cut is shown below; its effects up to that point may have landed. Verify before assuming it needs a full re-run.`;
|
|
393
400
|
const captured = (pStdout ? `--- partial stdout ---\n${pStdout}` : "") +
|
|
394
401
|
(pStderr ? `${pStdout ? "\n" : ""}--- partial stderr ---\n${pStderr}` : "");
|
|
395
402
|
const zeroOutput = captured.length === 0;
|
|
396
|
-
const zeroOutputHint = res.error.code === "
|
|
397
|
-
? ` — the process
|
|
398
|
-
: ""
|
|
403
|
+
const zeroOutputHint = res.error.code === "liveness_no_output"
|
|
404
|
+
? ` — the process wrote nothing to its stdio for ${noOutputSec !== undefined ? `the whole ${noOutputSec}s window` : "the whole window"}; it may have been stalled before producing output, or holding it in a block buffer`
|
|
405
|
+
: res.error.code === "timeout" && timeout >= 60
|
|
406
|
+
? ` — the process ran the full ${timeout}s without writing to its stdio; it may have been stalled before producing output, or holding it in a block buffer`
|
|
407
|
+
: "";
|
|
399
408
|
const body = !zeroOutput
|
|
400
409
|
? `\n${delimitUntrusted("partial command output", captured)}`
|
|
401
410
|
: `\n(no output was produced before the cutoff${zeroOutputHint})`;
|
|
@@ -414,9 +423,11 @@ async function runShell(env, cwd, toolName, command, timeoutSec, caps, signal, c
|
|
|
414
423
|
timeoutSec: timeout,
|
|
415
424
|
...(cappedByMaxTimeout ? { requestedTimeoutSec: requestedSec, cappedToMaxTimeoutSec: caps.maxSec } : {}),
|
|
416
425
|
}
|
|
417
|
-
: res.error.code === "
|
|
418
|
-
? {
|
|
419
|
-
:
|
|
426
|
+
: res.error.code === "liveness_no_output"
|
|
427
|
+
? { livenessNoOutput: true, ...(noOutputSec !== undefined ? { noOutputSec } : {}) }
|
|
428
|
+
: res.error.code === "aborted"
|
|
429
|
+
? { aborted: true }
|
|
430
|
+
: { callbackError: true }),
|
|
420
431
|
},
|
|
421
432
|
...(zeroOutput ? { isError: true } : {}),
|
|
422
433
|
};
|
package/dist/tools/fs/fs-pdf.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { delimitUntrusted } from "../../core/untrusted-text.js";
|
|
2
2
|
import { MCP_IMAGE_MAX_BASE64 } from "../../core/mcp.js";
|
|
3
|
-
import { PDF_FALLBACK_RENDER_PAGES, PDF_INLINE_PAGE_THRESHOLD, PDF_MAX_EXTRACT_SIZE, PDF_MAX_PAGES_PER_READ,
|
|
3
|
+
import { PDF_FALLBACK_RENDER_PAGES, PDF_INLINE_PAGE_THRESHOLD, PDF_MAX_EXTRACT_SIZE, PDF_MAX_PAGES_PER_READ, extractPdfPagesAsImages, extractPdfTextLayer, getPdfPageCount, parsePdfPageRange, pdfCutWords, } from "./pdf.js";
|
|
4
|
+
import { PDF_TARGET_RAW_SIZE, pdfMagicMatches } from "../../core/image-admission.js";
|
|
4
5
|
import { resolveAutoDownsampler, enoentMessage, MAX_READ_BYTES } from "./fs-shared.js";
|
|
5
6
|
import { planReminderDisclosure, renderReminderDisclosureTrailer } from "../../core/reminder-disclosure.js";
|
|
6
7
|
import { MARKED_BLOCK_AFTER_DATA } from "../../core/reminder-mint.js";
|
|
@@ -81,8 +82,9 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
|
|
|
81
82
|
const t = await extractPdfTextLayer(env, key, { first: range.first, last }, signal);
|
|
82
83
|
if (t.ok) {
|
|
83
84
|
const { body, truncated } = boundPdfExtractedText(t.text);
|
|
84
|
-
const
|
|
85
|
-
|
|
85
|
+
const words = t.cut !== undefined ? pdfCutWords(t.cut) : undefined;
|
|
86
|
+
const timeoutNote = words !== undefined
|
|
87
|
+
? `; PARTIAL — pdftotext ${words.clause}, so the text below covers only what was extracted before the ${words.noun}; use a narrower pages range for the rest`
|
|
86
88
|
: "";
|
|
87
89
|
return {
|
|
88
90
|
content: [
|
|
@@ -94,7 +96,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
|
|
|
94
96
|
],
|
|
95
97
|
details: {
|
|
96
98
|
type: "document",
|
|
97
|
-
file: { type: "application/pdf", originalSize: size, ...(pageCount !== undefined ? { pageCount } : {}), pages: `${range.first}-${last}`, ...(t.
|
|
99
|
+
file: { type: "application/pdf", originalSize: size, ...(pageCount !== undefined ? { pageCount } : {}), pages: `${range.first}-${last}`, ...(t.cut !== undefined ? { timedOut: true } : {}) },
|
|
98
100
|
fallback: { level: 1, reason: "model lacks document input; text layer extracted via pdftotext" },
|
|
99
101
|
},
|
|
100
102
|
};
|
|
@@ -128,10 +130,11 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
|
|
|
128
130
|
return blocks;
|
|
129
131
|
const requestedPages = last - range.first + 1;
|
|
130
132
|
const renderedAll = extract.pages.length >= requestedPages;
|
|
131
|
-
const
|
|
133
|
+
const words = extract.cut !== undefined ? pdfCutWords(extract.cut) : undefined;
|
|
134
|
+
const header = words !== undefined
|
|
132
135
|
? renderedAll
|
|
133
|
-
? `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""}: pdftoppm
|
|
134
|
-
: `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""}: pdftoppm
|
|
136
|
+
? `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""}: pdftoppm ${words.clause}, but all ${requestedPages} requested page${requestedPages === 1 ? "" : "s"} were rendered before the ${words.noun} hit at teardown (100 dpi); nothing is missing.]`
|
|
137
|
+
: `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""}: pdftoppm ${words.clause}; rendered ${extract.pages.length} of ${requestedPages} requested page${requestedPages === 1 ? "" : "s"} before the ${words.noun} (100 dpi). Read the remaining pages with a narrower range (e.g. pages: "${range.first + extract.pages.length}-${last}").]`
|
|
135
138
|
: `[PDF: ${path} — pages ${range.first}-${last}${pageCount !== undefined ? ` of ${pageCount}` : ""} rendered as ${extract.pages.length} image${extract.pages.length === 1 ? "" : "s"} (100 dpi)]`;
|
|
136
139
|
const content = [
|
|
137
140
|
{ type: "text", text: header },
|
|
@@ -147,7 +150,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
|
|
|
147
150
|
...(pageCount !== undefined ? { pageCount } : {}),
|
|
148
151
|
pages: `${range.first}-${last}`,
|
|
149
152
|
renderedPages: extract.pages.length,
|
|
150
|
-
...(extract.
|
|
153
|
+
...(extract.cut !== undefined ? { requestedPages, timedOut: true } : {}),
|
|
151
154
|
},
|
|
152
155
|
},
|
|
153
156
|
};
|
|
@@ -164,8 +167,9 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
|
|
|
164
167
|
const t = await extractPdfTextLayer(env, key, undefined, signal);
|
|
165
168
|
if (t.ok) {
|
|
166
169
|
const { body, truncated } = boundPdfExtractedText(t.text);
|
|
167
|
-
const
|
|
168
|
-
|
|
170
|
+
const words = t.cut !== undefined ? pdfCutWords(t.cut) : undefined;
|
|
171
|
+
const timeoutNote = words !== undefined
|
|
172
|
+
? `; PARTIAL — pdftotext ${words.clause}, so the text below covers only what was extracted before the ${words.noun}; use the pages parameter for the rest`
|
|
169
173
|
: "";
|
|
170
174
|
return {
|
|
171
175
|
content: [
|
|
@@ -177,7 +181,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
|
|
|
177
181
|
],
|
|
178
182
|
details: {
|
|
179
183
|
type: "document",
|
|
180
|
-
file: { ...fileCard, ...(t.
|
|
184
|
+
file: { ...fileCard, ...(t.cut !== undefined ? { timedOut: true } : {}) },
|
|
181
185
|
fallback: { level: 1, reason: "model lacks document input; text layer extracted via pdftotext" },
|
|
182
186
|
},
|
|
183
187
|
};
|
|
@@ -190,7 +194,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
|
|
|
190
194
|
if (extract.ok) {
|
|
191
195
|
const blocks = await pdfPagesToImageBlocks(extract.pages, path, downsamplerOpt);
|
|
192
196
|
if (typeof blocks !== "string") {
|
|
193
|
-
const renderTimeoutNote = extract.
|
|
197
|
+
const renderTimeoutNote = extract.cut !== undefined ? ` pdftoppm ${pdfCutWords(extract.cut).clause} — only the pages that finished rendering are included.` : "";
|
|
194
198
|
return {
|
|
195
199
|
content: [
|
|
196
200
|
{
|
|
@@ -202,7 +206,7 @@ export async function readPdfFile(env, path, key, pages, signal, downsamplerOpt,
|
|
|
202
206
|
],
|
|
203
207
|
details: {
|
|
204
208
|
type: "document",
|
|
205
|
-
file: { ...fileCard, pages: `1-${extract.pages.length}`, renderedPages: extract.pages.length, ...(extract.
|
|
209
|
+
file: { ...fileCard, pages: `1-${extract.pages.length}`, renderedPages: extract.pages.length, ...(extract.cut !== undefined ? { timedOut: true } : {}) },
|
|
206
210
|
fallback: { level: 2, reason: `model lacks document input; ${textWhy}; rendered first ${extract.pages.length} page(s) via pdftoppm` },
|
|
207
211
|
},
|
|
208
212
|
};
|
package/dist/tools/fs/fs-read.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { defineTool, errorResult } from "../../core/tools.js";
|
|
3
|
-
import { sha256, resolveKey, violationText, violationDetails, binaryMagicFormat, hasBinaryExtension, isBinaryContent,
|
|
3
|
+
import { sha256, resolveKey, violationText, violationDetails, binaryMagicFormat, hasBinaryExtension, isBinaryContent, imageMimeForRead, } from "./safety.js";
|
|
4
4
|
import { decodeTextBytes } from "./encoding.js";
|
|
5
5
|
import { isNotebookPath, parseNotebookCells, renderNotebookCells, stripNotebookImageData, NOTEBOOK_IMAGE_BASE64_BUDGET } from "./notebook.js";
|
|
6
6
|
import { MCP_IMAGE_MAX_BASE64, IMAGE_TARGET_RAW_SIZE } from "../../core/mcp.js";
|
|
7
|
-
import { countPdfPagesFromBytes, PDF_MAX_PAGES_PER_READ
|
|
7
|
+
import { countPdfPagesFromBytes, PDF_MAX_PAGES_PER_READ } from "./pdf.js";
|
|
8
8
|
import { MAX_READ_BYTES, SLICED_READ_MAX_BYTES, NO_DOWNSAMPLER_IMAGE_CAP_HINT, resolveAutoDownsampler, MAX_READ_OUTPUT_CHARS, FILE_PATH_PARAMS, countLines, seededFileUnchangedReminder, enoentMessage, } from "./fs-shared.js";
|
|
9
9
|
import { readPdfFile } from "./fs-pdf.js";
|
|
10
10
|
import { seatForCall, seatReady } from "./read-deny.js";
|
|
@@ -12,7 +12,8 @@ import { thrownText } from "../../core/thrown-value.js";
|
|
|
12
12
|
import { MARKED_BLOCK_AFTER_DATA, openSystemReminder } from "../../core/reminder-mint.js";
|
|
13
13
|
import { planReminderDisclosure, commitReminderDisclosureEffects, renderReminderDisclosureTrailer, } from "../../core/reminder-disclosure.js";
|
|
14
14
|
import { toolFace } from "../../core/tool-catalog-entries.js";
|
|
15
|
-
import {
|
|
15
|
+
import { fileArgPath } from "../../core/tool-registry.js";
|
|
16
|
+
import { admitImageBytes, imageReadCap, PDF_TARGET_RAW_SIZE, pdfMagicMatches } from "../../core/image-admission.js";
|
|
16
17
|
import { createEntryDenyJudge, enumerateDirectory } from "./dir-entries.js";
|
|
17
18
|
import { FileError } from "../../internal/harness.js";
|
|
18
19
|
export const READ_OUTCOMES = Object.freeze(["attached", "partial", "unchanged", "not_attached"]);
|
|
@@ -111,16 +111,7 @@ export declare function applyRecordedEdit(text: string, edit: RecordedEdit): str
|
|
|
111
111
|
* both sharper shapes describe files Read handled successfully, so the encoding-deadlock sentence
|
|
112
112
|
* would be false there — and stacking two escape routes on one refusal buries the one that applies. */
|
|
113
113
|
export declare function notReadRefusalText(env: ExecutionEnv, toolName: string, key: string, v: Pick<FsViolation, "code" | "message" | "partialView">, signal?: AbortSignal, fallbackHint?: string): Promise<string>;
|
|
114
|
-
/**
|
|
115
|
-
* `ImageContent` block (base64) rather than refused. Bounded so a huge image cannot blow the request.
|
|
116
|
-
* This stat-time cap only bounds the READ; the accept/refuse decision is the base64 gate below (the
|
|
117
|
-
* provider limit is on base64 LENGTH, so the effective no-sharp accept bound is raw ≤ 3.75MB). */
|
|
118
|
-
export declare const MAX_IMAGE_READ_BYTES: number;
|
|
119
|
-
/** Byte cap on a Read-image WITH a downsampler: sharp can shrink a big photo to CC's 2000×2000/3.75MB
|
|
120
|
-
* target, so the smaller hard refusal does not apply (CC readImageWithTokenBudget reads the file
|
|
121
|
-
* unbounded; we keep an OOM sanity bound — deliberate delta, camera photos fit comfortably). */
|
|
122
|
-
export declare const MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES: number;
|
|
123
|
-
/** The no-downsampler cap above is a DELIBERATE bound and does not move — but its refusal must not
|
|
114
|
+
/** The no-downsampler cap (`MAX_IMAGE_READ_BYTES`, core/image-admission.ts) is a DELIBERATE bound and does not move — but its refusal must not
|
|
124
115
|
* read like a hard ceiling. Whether the higher cap is reachable depends on an OPTIONAL dependency the
|
|
125
116
|
* caller can install, and only this package knows that, so the refusal names the move instead of
|
|
126
117
|
* leaving the caller to guess that the limit is negotiable. Appended ONLY on the no-downsampler
|
|
@@ -6,6 +6,7 @@ import { shellQuote } from "./search.js";
|
|
|
6
6
|
import { isNotebookPath } from "./notebook.js";
|
|
7
7
|
import { homeViewsOf } from "./read-deny-home.js";
|
|
8
8
|
import { sharpImageDownsampler } from "../../core/mcp.js";
|
|
9
|
+
import { MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES } from "../../core/image-admission.js";
|
|
9
10
|
import { deliverEngineNotice } from "../../core/types.js";
|
|
10
11
|
import { resolveEnvBudget } from "../../core/env-budget.js";
|
|
11
12
|
import { openSystemReminder } from "../../core/reminder-mint.js";
|
|
@@ -55,8 +56,6 @@ export async function notReadRefusalText(env, toolName, key, v, signal, fallback
|
|
|
55
56
|
return `${base} ${OVERSIZE_READ_ESCAPE_HINT}`;
|
|
56
57
|
return fallbackHint === undefined ? base : `${base} ${fallbackHint}`;
|
|
57
58
|
}
|
|
58
|
-
export const MAX_IMAGE_READ_BYTES = 5 * 1024 * 1024;
|
|
59
|
-
export const MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES = 64 * 1024 * 1024;
|
|
60
59
|
export const NO_DOWNSAMPLER_IMAGE_CAP_HINT = `Install the optional "sharp" dependency (declared in this package's optionalDependencies) to read images up to ${MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES} bytes — it downsamples them to fit the API image limit.`;
|
|
61
60
|
let autoDownsampler;
|
|
62
61
|
export function resolveAutoDownsampler() {
|
|
@@ -366,8 +365,8 @@ export async function enoentMessage(env, key, cwd, signal, readDeny) {
|
|
|
366
365
|
return false;
|
|
367
366
|
if (readDeny.matchPath(path) != null)
|
|
368
367
|
return true;
|
|
369
|
-
const
|
|
370
|
-
return view !== undefined && readDeny.matchPath(view) != null;
|
|
368
|
+
const home = await views.of(path, leaf !== undefined ? { leaf } : undefined);
|
|
369
|
+
return home.unread !== undefined || (home.view !== undefined && readDeny.matchPath(home.view) != null);
|
|
371
370
|
};
|
|
372
371
|
if (sep > 0) {
|
|
373
372
|
const parent = key.slice(0, sep);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
import { defineTool, errorResult } from "../../core/tools.js";
|
|
4
|
-
import { sha256, resolveKey, violationText, violationDetails, requireRead, checkStale, checkEditMatch, checkNoChange,
|
|
4
|
+
import { sha256, resolveKey, violationText, violationDetails, requireRead, checkStale, checkEditMatch, checkNoChange, resolveQuoteMatch, adaptNewStringQuotes, resolveEscapeMatch, adaptNewStringEscapes, escapeMatchWasAttempted, ESCAPE_MATCH_MISS_NOTE, deletionOldString, countOccurrences, READ_REFUSED_ESCAPE_HINT, } from "./safety.js";
|
|
5
5
|
import { decodeTextBytes, encodeTextForFile, normalizeEditText, normalizeFileText } from "./encoding.js";
|
|
6
6
|
import { seatForCall } from "./read-deny.js";
|
|
7
7
|
import { MAX_EDIT_BYTES, decodeEditBytes, tooLargeToEditMessage, truncatedUtf16BodyMessage, persistedTextOf, notReadRefusalText, enoentMessage, FILE_STATE_TRAILER, FILE_PATH_PARAMS, coerceWriteArguments, ipynbRedirect, countLines, applyRecordedEdit, } from "./fs-shared.js";
|
|
8
8
|
import { toolFace } from "../../core/tool-catalog-entries.js";
|
|
9
|
+
import { fileArgPath } from "../../core/tool-registry.js";
|
|
9
10
|
import { thrownText } from "../../core/thrown-value.js";
|
|
10
11
|
async function envFinalWrite(env, key, content, signal, opts) {
|
|
11
12
|
const fireEdited = () => {
|
package/dist/tools/fs/pdf.d.ts
CHANGED
|
@@ -20,13 +20,10 @@ import type { ExecutionEnv } from "../../internal/harness-types.js";
|
|
|
20
20
|
export declare const PDF_MAX_PAGES_PER_READ = 20;
|
|
21
21
|
/** Above this page count a whole-PDF read is refused and `pages` is required (CC `PDF_AT_MENTION_INLINE_THRESHOLD`). */
|
|
22
22
|
export declare const PDF_INLINE_PAGE_THRESHOLD = 10;
|
|
23
|
-
/** Max raw size
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
/** Max raw size the page-extraction (pdftoppm) path accepts (CC `PDF_MAX_EXTRACT_SIZE`). The whole-send target
|
|
24
|
+
* (`PDF_TARGET_RAW_SIZE`) and the `%PDF-` signature test (`pdfMagicMatches`) are the document admission's own
|
|
25
|
+
* (core/image-admission.ts). */
|
|
26
26
|
export declare const PDF_MAX_EXTRACT_SIZE: number;
|
|
27
|
-
/** True when the bytes start with the `%PDF-` magic. Magic outranks extension both ways: a mis-named
|
|
28
|
-
* `.pdf` without it is refused, and a non-`.pdf` file carrying it is read AS a PDF. */
|
|
29
|
-
export declare function pdfMagicMatches(bytes: Uint8Array): boolean;
|
|
30
27
|
/** A parsed 1-indexed inclusive page range. `last === Infinity` for an open range ("10-"). */
|
|
31
28
|
export interface PdfPageRange {
|
|
32
29
|
first: number;
|
|
@@ -75,12 +72,25 @@ export declare function pdfModelCapabilitiesOf(model?: {
|
|
|
75
72
|
}): PdfModelCapabilities;
|
|
76
73
|
/** Timeout for the poppler extraction commands (pdftotext / pdftoppm), in seconds. */
|
|
77
74
|
export declare const PDF_EXEC_TIMEOUT_SEC = 120;
|
|
75
|
+
/** What cut a run short: the wall-clock budget (always a number), or the env's silence window (a number only when the env states it — otherwise the budget did not elapse and no number is honest). */
|
|
76
|
+
export type PdfCut = {
|
|
77
|
+
readonly kind: "budget";
|
|
78
|
+
readonly sec: number;
|
|
79
|
+
} | {
|
|
80
|
+
readonly kind: "silence";
|
|
81
|
+
readonly sec?: number;
|
|
82
|
+
};
|
|
83
|
+
/** A cut in words: the clause that says it (`timed out after 120s` / `was cut after producing no output for 30s` / `was cut for producing no output`) and the noun a later clause calls it. */
|
|
84
|
+
export declare function pdfCutWords(cut: PdfCut): {
|
|
85
|
+
clause: string;
|
|
86
|
+
noun: string;
|
|
87
|
+
};
|
|
78
88
|
export type PdfTextResult = {
|
|
79
89
|
ok: true;
|
|
80
90
|
text: string;
|
|
81
|
-
/** Set when pdftotext
|
|
91
|
+
/** Set when pdftotext was cut by a time bound but had already written partial text: the extraction is
|
|
82
92
|
* INCOMPLETE (covers only the leading part of the requested range) and the caller must say so. */
|
|
83
|
-
|
|
93
|
+
cut?: PdfCut;
|
|
84
94
|
} | {
|
|
85
95
|
ok: false;
|
|
86
96
|
toolMissing: boolean;
|
|
@@ -104,9 +114,9 @@ export type PdfExtractResult = {
|
|
|
104
114
|
pageNumber: number;
|
|
105
115
|
jpeg: Uint8Array;
|
|
106
116
|
}>;
|
|
107
|
-
/** Set when pdftoppm
|
|
117
|
+
/** Set when pdftoppm was cut by a time bound but had already rendered complete leading pages: `pages`
|
|
108
118
|
* covers only a PREFIX of the requested range and the caller must label the delivery as partial. */
|
|
109
|
-
|
|
119
|
+
cut?: PdfCut;
|
|
110
120
|
} | {
|
|
111
121
|
ok: false;
|
|
112
122
|
toolMissing: boolean;
|
package/dist/tools/fs/pdf.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
+
import { isTimeCutCode } from "../../internal/harness.js";
|
|
1
2
|
export const PDF_MAX_PAGES_PER_READ = 20;
|
|
2
3
|
export const PDF_INLINE_PAGE_THRESHOLD = 10;
|
|
3
|
-
export const PDF_TARGET_RAW_SIZE = 20 * 1024 * 1024;
|
|
4
4
|
export const PDF_MAX_EXTRACT_SIZE = 100 * 1024 * 1024;
|
|
5
|
-
export function pdfMagicMatches(bytes) {
|
|
6
|
-
return bytes.length >= 5 && bytes[0] === 0x25 && bytes[1] === 0x50 && bytes[2] === 0x44 && bytes[3] === 0x46 && bytes[4] === 0x2d;
|
|
7
|
-
}
|
|
8
5
|
export function parsePdfPageRange(pages) {
|
|
9
6
|
const s = pages.trim();
|
|
10
7
|
const single = /^(\d+)$/.exec(s);
|
|
@@ -60,6 +57,16 @@ export function pdfModelCapabilitiesOf(model) {
|
|
|
60
57
|
return { document, vision };
|
|
61
58
|
}
|
|
62
59
|
export const PDF_EXEC_TIMEOUT_SEC = 120;
|
|
60
|
+
function cutOf(e) {
|
|
61
|
+
if (e.code !== "liveness_no_output")
|
|
62
|
+
return { kind: "budget", sec: PDF_EXEC_TIMEOUT_SEC };
|
|
63
|
+
return e.noOutputSec !== undefined ? { kind: "silence", sec: e.noOutputSec } : { kind: "silence" };
|
|
64
|
+
}
|
|
65
|
+
export function pdfCutWords(cut) {
|
|
66
|
+
if (cut.kind === "budget")
|
|
67
|
+
return { clause: `timed out after ${cut.sec}s`, noun: "timeout" };
|
|
68
|
+
return { clause: cut.sec !== undefined ? `was cut after producing no output for ${cut.sec}s` : "was cut for producing no output", noun: "cut" };
|
|
69
|
+
}
|
|
63
70
|
export async function extractPdfTextLayer(env, absPath, range, signal) {
|
|
64
71
|
const tmp = await env.createTempDir("sema-pdf-text-", signal);
|
|
65
72
|
if (!tmp.ok)
|
|
@@ -73,16 +80,17 @@ export async function extractPdfTextLayer(env, absPath, range, signal) {
|
|
|
73
80
|
const cmd = `pdftotext -layout ${rangeArgs}${shellQuote(absPath)} ${shellQuote(outR.value)}`;
|
|
74
81
|
const r = await env.exec(cmd, { timeout: PDF_EXEC_TIMEOUT_SEC, abortSignal: signal });
|
|
75
82
|
if (!r.ok) {
|
|
76
|
-
if (r.error.code
|
|
83
|
+
if (isTimeCutCode(r.error.code)) {
|
|
84
|
+
const cut = cutOf(r.error);
|
|
77
85
|
const partial = await env.readBinaryFile(outR.value, signal);
|
|
78
86
|
const text = partial.ok ? Buffer.from(partial.value).toString("utf8") : "";
|
|
79
87
|
if (text.trim())
|
|
80
|
-
return { ok: true, text,
|
|
88
|
+
return { ok: true, text, cut };
|
|
81
89
|
return {
|
|
82
90
|
ok: false,
|
|
83
91
|
toolMissing: false,
|
|
84
92
|
timedOut: true,
|
|
85
|
-
error: `pdftotext
|
|
93
|
+
error: `pdftotext ${pdfCutWords(cut).clause} before writing any text. Use the pages parameter to extract a narrower range (e.g. pages: "1-5").`,
|
|
86
94
|
};
|
|
87
95
|
}
|
|
88
96
|
return { ok: false, toolMissing: false, error: r.error.message };
|
|
@@ -129,7 +137,8 @@ export async function extractPdfPagesAsImages(env, absPath, first, last, signal)
|
|
|
129
137
|
const cmd = `pdftoppm -jpeg -r 100 -f ${first} -l ${last} ${shellQuote(absPath)} ${shellQuote(prefixR.value)}`;
|
|
130
138
|
const r = await env.exec(cmd, { timeout: PDF_EXEC_TIMEOUT_SEC, abortSignal: signal });
|
|
131
139
|
if (!r.ok) {
|
|
132
|
-
if (r.error.code
|
|
140
|
+
if (isTimeCutCode(r.error.code)) {
|
|
141
|
+
const cut = cutOf(r.error);
|
|
133
142
|
const listed = await listRenderedJpegs(env, dir, signal);
|
|
134
143
|
const jpgs = listed.ok ? listed.jpgs : [];
|
|
135
144
|
const pages = [];
|
|
@@ -140,12 +149,12 @@ export async function extractPdfPagesAsImages(env, absPath, first, last, signal)
|
|
|
140
149
|
pages.push({ pageNumber: first + i, jpeg: bin.value });
|
|
141
150
|
}
|
|
142
151
|
if (pages.length > 0)
|
|
143
|
-
return { ok: true, pages,
|
|
152
|
+
return { ok: true, pages, cut };
|
|
144
153
|
return {
|
|
145
154
|
ok: false,
|
|
146
155
|
toolMissing: false,
|
|
147
156
|
timedOut: true,
|
|
148
|
-
error: `pdftoppm
|
|
157
|
+
error: `pdftoppm ${pdfCutWords(cut).clause} before finishing any page. Request a narrower pages range (e.g. a single page like pages: "${first}").`,
|
|
149
158
|
};
|
|
150
159
|
}
|
|
151
160
|
return { ok: false, toolMissing: false, error: r.error.message };
|
|
@@ -172,9 +172,18 @@ export interface OptionSpec {
|
|
|
172
172
|
* `date -s`), `executes` a command (`find -exec`), or `none` — neither, which the binary gate witnesses for every
|
|
173
173
|
* option that states it (the read-only form of a program admits only such options). Absent: not stated. */
|
|
174
174
|
readonly effect?: "writes" | "executes" | "none";
|
|
175
|
-
/** The option's value names a FILE the program reads its OPERANDS from (`find -files0-from`, `tar -T`)
|
|
176
|
-
* or opens is not in the command line
|
|
175
|
+
/** The option's value names a FILE the program reads its OPERANDS from (`find -files0-from`, `tar -T`) — or, a switch, says they
|
|
176
|
+
* arrive on its standard input (`ack -x`): what it walks or opens is not in the command line, so a segment that selects it has
|
|
177
|
+
* reads the station cannot establish ({@link deliversOperands}); the list file itself is a read like any other and meets the deny
|
|
178
|
+
* rows as itself. */
|
|
177
179
|
readonly delivers?: "operands";
|
|
180
|
+
/** The option's value is a PLACE the program's walk works in or compares (`tar -C DIR`, `diff --from-file=DIR`): a root of a
|
|
181
|
+
* recursive form, whichever way the value is spelled. Absent: a path value is a file the program READS (a config, ignore or
|
|
182
|
+
* exclusion file, an archive, a pattern file) or an entry it examines — judged as itself, never a root, so it does not count
|
|
183
|
+
* as the root the walk was given (`rg --ignore-file ig pat` walks `.`). A list the operands come from ({@link delivers}) is a
|
|
184
|
+
* root of a recursive form too, in either spelling: the program works on what the list names, not on the working directory
|
|
185
|
+
* (and, the names not being in the text, the segment is not vouched: {@link deliversOperands}). */
|
|
186
|
+
readonly walks?: true;
|
|
178
187
|
/** The option's value bounds the program's output, in bytes or in lines (`head -c` / `head -n`). */
|
|
179
188
|
readonly bounds?: "bytes" | "lines";
|
|
180
189
|
/** The option's value is what the row's LAST operand would otherwise be (`cp -t <dir>`), so every operand is an
|
|
@@ -236,6 +245,12 @@ export interface Grammar {
|
|
|
236
245
|
/** With no operand, this implementation walks the working directory (`grep -r pat`); absent, it walks nothing (it
|
|
237
246
|
* reads its standard input, or refuses to run). */
|
|
238
247
|
readonly walksCwdWithoutOperand?: true;
|
|
248
|
+
/** Whether this implementation reads an unambiguous PREFIX of a long option's name as that option (`getopt_long`, Perl's
|
|
249
|
+
* Getopt::Long: `grep --max 1`, `tar --dir d`). Absent = it does; `false` = only the exact name is an option and a prefix
|
|
250
|
+
* is an unrecognised flag that runs nothing (ripgrep's parser: `rg --ignore-f x` is an error while `rg --ignore` is the
|
|
251
|
+
* switch). Every reader that matches a long name against the table asks this one fact, so a name a row leaves undeclared is
|
|
252
|
+
* never read as the abbreviation of a declared one in a program that does not take abbreviations. */
|
|
253
|
+
readonly acceptsAbbreviations?: boolean;
|
|
239
254
|
/** The traditional FIRST-argument form `<sign><number><letters>` (`tail +0f`, `tail -1f`): the signs this
|
|
240
255
|
* implementation reads it with, and the option each letter names. */
|
|
241
256
|
readonly obsoleteFirst?: {
|
|
@@ -412,9 +427,11 @@ export declare function movesBaseByStack(name: string): boolean;
|
|
|
412
427
|
/** The LONG-OPTION name carried by a token (`--file=p` → `file`, `--reg` → `reg`); `undefined` for anything that is
|
|
413
428
|
* not a long option with a non-empty name (`--`, `--=x`, a short option). */
|
|
414
429
|
export declare function longOptionNameOf(tok: string): string | undefined;
|
|
415
|
-
/** Is `name` a spelling
|
|
416
|
-
*
|
|
417
|
-
|
|
430
|
+
/** Is `name` a spelling of the long option `full`? The exact name always; a proper prefix — an abbreviation — only where the
|
|
431
|
+
* program takes them (`accepts`: {@link Grammar.acceptsAbbreviations}, or {@link Merged.abbreviable} of a merged name). Every
|
|
432
|
+
* prefix counts there — `getopt_long`'s ambiguity is not modelled, and each caller makes that over-approximation land on its
|
|
433
|
+
* own safe side. This is the one place a long name is matched against another. */
|
|
434
|
+
export declare function isLongOptionSpellingOf(name: string, full: string, accepts: boolean): boolean;
|
|
418
435
|
/** The languages whose program text the read station parses (the rest is program text it does not read). */
|
|
419
436
|
export declare const READ_LANGUAGES: ReadonlySet<string>;
|
|
420
437
|
/**
|
|
@@ -472,6 +489,8 @@ export interface FirstOperandSlot {
|
|
|
472
489
|
readonly role: ArgRole;
|
|
473
490
|
readonly suppliedByLetters: string;
|
|
474
491
|
readonly suppliedByLongNames: readonly string[];
|
|
492
|
+
/** The long names of {@link suppliedByLongNames} a prefix of which supplies it too ({@link Grammar.acceptsAbbreviations}). */
|
|
493
|
+
readonly abbreviableLongNames: readonly string[];
|
|
475
494
|
/** The other letters that take a value in every implementation: in a cluster, the rest of the token is theirs. */
|
|
476
495
|
readonly valueLetters: string;
|
|
477
496
|
}
|
|
@@ -480,7 +499,7 @@ export declare function firstOperandSlot(row: ProgramRow | undefined, view?: Vie
|
|
|
480
499
|
* a letter that delivers the slot supplies it, and the first OTHER letter that takes a value owns the rest of the
|
|
481
500
|
* token (`grep -Dread x f`: `read` is `-D`'s value, its `e` delivers nothing); a letter the row does not declare is
|
|
482
501
|
* stepped over (it may be a switch), as digits are (grep's obsolete numeric context spec: `-2ebeta`). A long option
|
|
483
|
-
* supplies it by
|
|
502
|
+
* supplies it by its name, or by a prefix of it where the program takes abbreviations. Over-triggering makes the first operand a CHECKED path candidate, the safe side. */
|
|
484
503
|
export declare function suppliesFirstOperandSlot(slot: FirstOperandSlot, tok: string): boolean;
|
|
485
504
|
/** The row's options stand anywhere in its argv in every implementation (`find`'s predicates past its paths), so the
|
|
486
505
|
* "is a dash-word past the first operand still an option" ambiguity does not exist for it. */
|
|
@@ -544,6 +563,7 @@ type Event<R> =
|
|
|
544
563
|
readonly role: R;
|
|
545
564
|
readonly consumed: boolean;
|
|
546
565
|
readonly spec?: OptionSpec;
|
|
566
|
+
readonly unsettled?: true;
|
|
547
567
|
}
|
|
548
568
|
/** An operand, the `ordinal`-th. `slot` = the first-operand slot's role when the slot applies; `role` = the role the
|
|
549
569
|
* row declares for an operand at this position past the slot (a URL, a name it only examines); `dash` = the word is
|
|
@@ -559,13 +579,25 @@ type Event<R> =
|
|
|
559
579
|
export type ArgEvent = Event<ArgRole>;
|
|
560
580
|
export type ArgRoleEvent = Event<ArgRole | undefined>;
|
|
561
581
|
/** The candidate extraction's walk (the program word excluded). `firstOperandSlot: false` reads every operand as an
|
|
562
|
-
* ordinary one.
|
|
582
|
+
* ordinary one. `ownedValues`: a bare option of a traversing program that may take the NEXT word as its value
|
|
583
|
+
* ({@link bareOptionValueOf}) hands that word over as a value read both ways (`consumed: false`) — what the roots of a
|
|
584
|
+
* recursive form are read from. */
|
|
563
585
|
export declare function readArgs(row: ProgramRow | undefined, words: readonly ArgWord[], opts: {
|
|
564
586
|
readonly firstOperandSlot: boolean | "program-text";
|
|
587
|
+
readonly ownedValues?: true;
|
|
565
588
|
}): ArgEvent[];
|
|
566
589
|
/** The role walk: the SAME walk, every declared option read by its declared arity and role. What the binary gate
|
|
567
590
|
* predicts a binary opens is read off these events. */
|
|
568
591
|
export declare function readArgRoles(row: ProgramRow, args: readonly string[]): ArgRoleEvent[];
|
|
592
|
+
/**
|
|
593
|
+
* Does this invocation take the program's OPERANDS from a list file ({@link OptionSpec.delivers}: `ack --files-from LIST`,
|
|
594
|
+
* `tar -T LIST`, `find -files0-from LIST`)? What the program then walks or opens is written in a file this reading does not
|
|
595
|
+
* open — no root of it is in the command. The reading of a check that only ever refuses or asks ({@link selectedOptions} over the
|
|
596
|
+
* merged row: a word spelled as the option counts, an abbreviation that reaches it counts, a value spelled like it counts). The
|
|
597
|
+
* traditional key word is every letter of it an option — each value-taking letter takes one of the arguments that follow, in
|
|
598
|
+
* order, so none owns the rest of the word (`tar cfT out.tar list` takes `list` for `T`).
|
|
599
|
+
*/
|
|
600
|
+
export declare function deliversOperands(row: ProgramRow | undefined, args: readonly string[]): boolean;
|
|
569
601
|
/**
|
|
570
602
|
* Does this invocation walk its operands' subtrees AND hand back their CONTENTS? Detection over-approximates: a flag
|
|
571
603
|
* misread as recursive costs one ask, an under-read hides a traversal. A value-taking letter owns its value only where
|
|
@@ -596,6 +628,33 @@ export declare function declaresOption(row: ProgramRow, pred: (spec: OptionSpec)
|
|
|
596
628
|
* count must still see. getopt's cluster rule: the FIRST value-taking letter owns the rest of the token.
|
|
597
629
|
*/
|
|
598
630
|
export declare function takesSeparatedDatum(row: ProgramRow | undefined, tok: string): boolean;
|
|
631
|
+
/**
|
|
632
|
+
* The value the NEXT word may be, for an option token written BARE (no value attached) — the one place the "which word does this
|
|
633
|
+
* option own" question of a cluster or an optional count is answered. Each grammar of the row reads the token as getopt does (a
|
|
634
|
+
* cluster: a letter the row does not declare is a switch, the first value-taking letter owns the rest of the token, so the next
|
|
635
|
+
* word only when it ends the token; a long name: the name or, where the grammar takes abbreviations, any name it abbreviates,
|
|
636
|
+
* `--name=` carries its own value):
|
|
637
|
+
* · a REQUIRED value is the next word wherever the option is read — the extraction's slot reading fails to see it where the token
|
|
638
|
+
* is a cluster with a letter the row leaves undeclared (`rg -nA 2 pat`: rg / ag / ack declare no switches), and `tok` is then
|
|
639
|
+
* read the speculative way;
|
|
640
|
+
* · an OPTIONAL count (the value only attached) is the next word to a parser that reads an optional integer (Getopt::Long's `:i`:
|
|
641
|
+
* ack's `-A` / `-B` / `-C`) or a required one (GNU grep's `--context`) when that word is spelled like a count, and an operand to
|
|
642
|
+
* a parser that reads it attached-only (getopt_long's optional argument: ag's long names, BSD grep) — the row files it
|
|
643
|
+
* attached-only, the reading that consumes nothing.
|
|
644
|
+
* · a long name the row declares NOWHERE (not as a name, nor — in a grammar that takes abbreviations — as the abbreviation of one)
|
|
645
|
+
* may take the next word: the row cannot say it does not (`rg --hostname-bin x pat`, whose option runs a program, is left
|
|
646
|
+
* undeclared on purpose; `rg --ignore pat sub`, a switch of rg that is no abbreviation of `--ignore-file` there) — the word's value role is
|
|
647
|
+
* {@link UNDECLARED_VALUE}, no more than "names no file", as it is also read as whatever it is on its own. A long name with its
|
|
648
|
+
* value attached owns nothing, and one the row declares as a switch owns nothing.
|
|
649
|
+
* A SHORT letter the row leaves undeclared owns no word: the rows of rg / ag / ack declare no switches, so every word behind `-i`
|
|
650
|
+
* would otherwise be one — the letter is read as the switch it is in rg (whose table of value letters is complete). The extraction
|
|
651
|
+
* reads the word both ways (`consumed: false` — as the value, and as whatever it is on its own). Served to the contents walkers
|
|
652
|
+
* (`readArgs` `ownedValues`), whose rows carry no single-dash WORD options (`find -name`): a cluster here is always letters.
|
|
653
|
+
*/
|
|
654
|
+
export declare function bareOptionValueOf(row: ProgramRow, tok: string, next: string | undefined): {
|
|
655
|
+
readonly role: ArgRole;
|
|
656
|
+
readonly spec?: OptionSpec;
|
|
657
|
+
} | undefined;
|
|
599
658
|
/**
|
|
600
659
|
* Does this option word carry, ATTACHED, the value `-` for an option whose value is a file the program opens or names
|
|
601
660
|
* (`grep -f-`, `diff --from-file=-`, `diff -X-`) — or for a spelling the row does not account for? Such a word makes the
|
|
@@ -623,7 +682,8 @@ interface OptionScan {
|
|
|
623
682
|
* Every option spec an argv selects. A short cluster is read as getopt reads it, scanning left to right: a declared
|
|
624
683
|
* letter is selected; a value-taking letter owns the rest of the token (and the next word, when it ends the token); a
|
|
625
684
|
* letter the row does not declare is read as a switch and the scan goes on. A long option is every name its spelling
|
|
626
|
-
* can abbreviate (the exact name alone where there is one
|
|
685
|
+
* can abbreviate where the grammar takes abbreviations (the exact name alone where there is one, and always in a grammar
|
|
686
|
+
* that takes none); a dash word its exact name. Two readings:
|
|
627
687
|
* · over ONE implementation's view ({@link implementationsOf}): what that program selects — a separated value is
|
|
628
688
|
* stepped over, `--` ends the options, and so does the first operand where the grammar stops there;
|
|
629
689
|
* · over the row (every implementation merged): every word is read as the option it SPELLS — a value spelled like an
|