@animalabs/agent-framework 0.28.0 → 0.30.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/README.md +88 -25
- package/dist/src/admission/admit.d.ts +90 -0
- package/dist/src/admission/admit.d.ts.map +1 -0
- package/dist/src/admission/admit.js +43 -0
- package/dist/src/admission/admit.js.map +1 -0
- package/dist/src/agent.d.ts +21 -0
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +47 -7
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/mcp-server-core.d.ts.map +1 -1
- package/dist/src/api/mcp-server-core.js +3 -12
- package/dist/src/api/mcp-server-core.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +7 -3
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/author-presentation.d.ts +50 -0
- package/dist/src/author-presentation.d.ts.map +1 -0
- package/dist/src/author-presentation.js +58 -0
- package/dist/src/author-presentation.js.map +1 -0
- package/dist/src/auto-continue.d.ts +2 -0
- package/dist/src/auto-continue.d.ts.map +1 -1
- package/dist/src/auto-continue.js +5 -2
- package/dist/src/auto-continue.js.map +1 -1
- package/dist/src/code-execution/isolate/runner.d.ts +7 -5
- package/dist/src/code-execution/isolate/runner.d.ts.map +1 -1
- package/dist/src/code-execution/isolate/runner.js +7 -5
- package/dist/src/code-execution/isolate/runner.js.map +1 -1
- package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
- package/dist/src/code-execution/isolate/scripts.js +3 -2
- package/dist/src/code-execution/isolate/scripts.js.map +1 -1
- package/dist/src/dendrite/index.d.ts +6 -0
- package/dist/src/dendrite/index.d.ts.map +1 -0
- package/dist/src/dendrite/index.js +3 -0
- package/dist/src/dendrite/index.js.map +1 -0
- package/dist/src/dendrite/presets.d.ts +60 -0
- package/dist/src/dendrite/presets.d.ts.map +1 -0
- package/dist/src/dendrite/presets.js +117 -0
- package/dist/src/dendrite/presets.js.map +1 -0
- package/dist/src/dendrite/registry.d.ts +260 -0
- package/dist/src/dendrite/registry.d.ts.map +1 -0
- package/dist/src/dendrite/registry.js +742 -0
- package/dist/src/dendrite/registry.js.map +1 -0
- package/dist/src/dendrite/types.d.ts +392 -0
- package/dist/src/dendrite/types.d.ts.map +1 -0
- package/dist/src/dendrite/types.js +24 -0
- package/dist/src/dendrite/types.js.map +1 -0
- package/dist/src/framework.d.ts +846 -67
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +4213 -924
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +46 -14
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +143 -53
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/gate/index.d.ts +1 -1
- package/dist/src/gate/index.d.ts.map +1 -1
- package/dist/src/gate/index.js +1 -1
- package/dist/src/gate/index.js.map +1 -1
- package/dist/src/gate/types.d.ts +12 -2
- package/dist/src/gate/types.d.ts.map +1 -1
- package/dist/src/heartbeat/heartbeat.d.ts +18 -0
- package/dist/src/heartbeat/heartbeat.d.ts.map +1 -1
- package/dist/src/heartbeat/heartbeat.js +34 -8
- package/dist/src/heartbeat/heartbeat.js.map +1 -1
- package/dist/src/held-writes.d.ts +3 -3
- package/dist/src/held-writes.js +3 -3
- package/dist/src/host-presentation.d.ts +174 -0
- package/dist/src/host-presentation.d.ts.map +1 -0
- package/dist/src/host-presentation.js +565 -0
- package/dist/src/host-presentation.js.map +1 -0
- package/dist/src/index.d.ts +7 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/line-reader.d.ts +4 -0
- package/dist/src/line-reader.d.ts.map +1 -0
- package/dist/src/line-reader.js +59 -0
- package/dist/src/line-reader.js.map +1 -0
- package/dist/src/mcpl/channel-registry.d.ts +118 -15
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +266 -110
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/conversation-router.js +2 -1
- package/dist/src/mcpl/conversation-router.js.map +1 -1
- package/dist/src/mcpl/convert-block.d.ts +1 -0
- package/dist/src/mcpl/convert-block.d.ts.map +1 -1
- package/dist/src/mcpl/convert-block.js +16 -4
- package/dist/src/mcpl/convert-block.js.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.js +4 -3
- package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +3 -1
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
- package/dist/src/mcpl/inbound-source.js +3 -1
- package/dist/src/mcpl/inbound-source.js.map +1 -1
- package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
- package/dist/src/mcpl/modern-connection.js +11 -7
- package/dist/src/mcpl/modern-connection.js.map +1 -1
- package/dist/src/mcpl/protocol-family.d.ts +3 -2
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
- package/dist/src/mcpl/protocol-family.js +25 -3
- package/dist/src/mcpl/protocol-family.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +9 -0
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +21 -0
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.js +2 -2
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/references.d.ts +12 -40
- package/dist/src/mcpl/references.d.ts.map +1 -1
- package/dist/src/mcpl/references.js +29 -23
- package/dist/src/mcpl/references.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +20 -20
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/skip-reply-wake.d.ts +25 -0
- package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -1
- package/dist/src/mcpl/skip-reply-wake.js +25 -0
- package/dist/src/mcpl/skip-reply-wake.js.map +1 -1
- package/dist/src/mcpl/tool-presence.d.ts.map +1 -1
- package/dist/src/mcpl/tool-presence.js +18 -17
- package/dist/src/mcpl/tool-presence.js.map +1 -1
- package/dist/src/mcpl/tool-signature.d.ts.map +1 -1
- package/dist/src/mcpl/tool-signature.js +17 -16
- package/dist/src/mcpl/tool-signature.js.map +1 -1
- package/dist/src/mcpl/toolset-host.d.ts +8 -26
- package/dist/src/mcpl/toolset-host.d.ts.map +1 -1
- package/dist/src/mcpl/toolset-host.js +16 -6
- package/dist/src/mcpl/toolset-host.js.map +1 -1
- package/dist/src/mcpl/toolsets-module.d.ts +14 -25
- package/dist/src/mcpl/toolsets-module.d.ts.map +1 -1
- package/dist/src/mcpl/toolsets-module.js +187 -50
- package/dist/src/mcpl/toolsets-module.js.map +1 -1
- package/dist/src/mcpl/transport.d.ts +1 -1
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +16 -16
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +28 -12
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/module-registry.d.ts +6 -7
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +6 -7
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/api/index.d.ts.map +1 -1
- package/dist/src/modules/api/index.js +4 -2
- package/dist/src/modules/api/index.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +33 -25
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/history/index.js +8 -6
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/sender-name.d.ts +7 -0
- package/dist/src/modules/sender-name.d.ts.map +1 -0
- package/dist/src/modules/sender-name.js +10 -0
- package/dist/src/modules/sender-name.js.map +1 -0
- package/dist/src/modules/workspace/answers.d.ts +5 -1
- package/dist/src/modules/workspace/answers.d.ts.map +1 -1
- package/dist/src/modules/workspace/answers.js +16 -1
- package/dist/src/modules/workspace/answers.js.map +1 -1
- package/dist/src/modules/workspace/direct-write.d.ts.map +1 -1
- package/dist/src/modules/workspace/direct-write.js +6 -4
- package/dist/src/modules/workspace/direct-write.js.map +1 -1
- package/dist/src/modules/workspace/effects.d.ts +4 -2
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +50 -40
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +1 -0
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +66 -36
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +51 -20
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +120 -82
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts +7 -1
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +133 -37
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/notice-tags.d.ts +81 -0
- package/dist/src/notice-tags.d.ts.map +1 -0
- package/dist/src/notice-tags.js +85 -0
- package/dist/src/notice-tags.js.map +1 -0
- package/dist/src/reasoning-loss-notice.d.ts.map +1 -1
- package/dist/src/reasoning-loss-notice.js +5 -3
- package/dist/src/reasoning-loss-notice.js.map +1 -1
- package/dist/src/silent-heartbeat.d.ts +5 -55
- package/dist/src/silent-heartbeat.d.ts.map +1 -1
- package/dist/src/silent-heartbeat.js +63 -7
- package/dist/src/silent-heartbeat.js.map +1 -1
- package/dist/src/stored-injections.d.ts +4 -0
- package/dist/src/stored-injections.d.ts.map +1 -1
- package/dist/src/stored-injections.js +6 -0
- package/dist/src/stored-injections.js.map +1 -1
- package/dist/src/supplied-text.d.ts +35 -0
- package/dist/src/supplied-text.d.ts.map +1 -0
- package/dist/src/supplied-text.js +141 -0
- package/dist/src/supplied-text.js.map +1 -0
- package/dist/src/tool-args.d.ts.map +1 -1
- package/dist/src/tool-args.js +9 -8
- package/dist/src/tool-args.js.map +1 -1
- package/dist/src/tool-image-ledger.d.ts.map +1 -1
- package/dist/src/tool-image-ledger.js +2 -1
- package/dist/src/tool-image-ledger.js.map +1 -1
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +5 -4
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts +382 -11
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +1100 -119
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/tune-out/tools.d.ts +101 -5
- package/dist/src/tune-out/tools.d.ts.map +1 -1
- package/dist/src/tune-out/tools.js +55 -18
- package/dist/src/tune-out/tools.js.map +1 -1
- package/dist/src/types/agent.d.ts +48 -9
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +142 -0
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +22 -11
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +136 -0
- package/dist/src/types/trace.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/admission/admit.ts +113 -0
- package/src/agent.ts +52 -7
- package/src/api/mcp-server-core.ts +3 -14
- package/src/api/server.ts +7 -3
- package/src/author-presentation.ts +81 -0
- package/src/auto-continue.ts +8 -2
- package/src/code-execution/isolate/runner.ts +7 -5
- package/src/code-execution/isolate/scripts.ts +3 -2
- package/src/dendrite/index.ts +32 -0
- package/src/dendrite/presets.ts +149 -0
- package/src/dendrite/registry.ts +808 -0
- package/src/dendrite/types.ts +397 -0
- package/src/framework.ts +4362 -852
- package/src/gate/event-gate.ts +159 -52
- package/src/gate/index.ts +1 -1
- package/src/gate/types.ts +12 -2
- package/src/heartbeat/heartbeat.ts +48 -9
- package/src/held-writes.ts +3 -3
- package/src/host-presentation.ts +612 -0
- package/src/index.ts +17 -4
- package/src/line-reader.ts +58 -0
- package/src/mcpl/channel-registry.ts +306 -111
- package/src/mcpl/conversation-router.ts +2 -1
- package/src/mcpl/convert-block.ts +17 -4
- package/src/mcpl/hook-orchestrator.ts +4 -3
- package/src/mcpl/inbound-source.ts +3 -1
- package/src/mcpl/modern-connection.ts +11 -7
- package/src/mcpl/protocol-family.ts +24 -3
- package/src/mcpl/push-coalescer.ts +19 -0
- package/src/mcpl/push-handler.ts +2 -2
- package/src/mcpl/references.ts +31 -23
- package/src/mcpl/server-connection.ts +20 -18
- package/src/mcpl/skip-reply-wake.ts +35 -0
- package/src/mcpl/tool-presence.ts +18 -17
- package/src/mcpl/tool-signature.ts +17 -16
- package/src/mcpl/toolset-host.ts +18 -6
- package/src/mcpl/toolsets-module.ts +149 -50
- package/src/mcpl/transport.ts +18 -14
- package/src/mcpl/types.ts +29 -12
- package/src/module-registry.ts +6 -7
- package/src/modules/api/index.ts +4 -2
- package/src/modules/discord/index.ts +37 -25
- package/src/modules/history/index.ts +8 -6
- package/src/modules/sender-name.ts +9 -0
- package/src/modules/workspace/answers.ts +20 -2
- package/src/modules/workspace/direct-write.ts +4 -3
- package/src/modules/workspace/effects.ts +50 -40
- package/src/modules/workspace/index.ts +58 -34
- package/src/modules/workspace/observe.ts +139 -88
- package/src/modules/workspace/reconcile.ts +159 -36
- package/src/notice-tags.ts +86 -0
- package/src/reasoning-loss-notice.ts +5 -3
- package/src/silent-heartbeat.ts +11 -7
- package/src/stored-injections.ts +7 -0
- package/src/supplied-text.ts +154 -0
- package/src/tool-args.ts +9 -8
- package/src/tool-image-ledger.ts +2 -1
- package/src/tool-presentation.ts +5 -4
- package/src/tune-out/coordinator.ts +1252 -123
- package/src/tune-out/tools.ts +152 -11
- package/src/types/agent.ts +51 -9
- package/src/types/framework.ts +146 -0
- package/src/types/module.ts +23 -11
- package/src/types/trace.ts +150 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Provides a unified workspace with mount-based filesystem access,
|
|
5
5
|
* auto-sync between real filesystem and Chronicle, and manual materialization.
|
|
6
6
|
*/
|
|
7
|
+
import { NOTICE_TAG } from '../../notice-tags.js';
|
|
7
8
|
import { constants as fsConstants } from 'node:fs';
|
|
8
9
|
import { open, readdir, readlink, stat, lstat, realpath } from 'node:fs/promises';
|
|
9
10
|
import { basename, dirname, isAbsolute, join, parse, resolve, relative, sep } from 'node:path';
|
|
@@ -12,7 +13,7 @@ import { MountWatcher } from './watcher.js';
|
|
|
12
13
|
import { hashContent, storedBytes, DEFAULT_MAX_FILE_SIZE } from './sync.js';
|
|
13
14
|
import { DiskAgreement, EvidenceUnavailable, callGate, sameRootIdentity } from './disk-agreement.js';
|
|
14
15
|
import { BranchIntents } from './branch-intent.js';
|
|
15
|
-
import { CHANGED, DIRECTORY, IGNORED,
|
|
16
|
+
import { CHANGED, DIRECTORY, IGNORED, NONBLOCK, OTHER_MOUNT, OUTSIDE_INCLUDE, ROOT_REPLACED, ROOT_UNAVAILABLE, beneathRoot, checkDir, checkRoot, confirmAbsent, coversLanding, directoryAt, diskSpelling, filesystemTrustsCtime, foldsCase, inOtherMount, insideMount, leadsInto, linkOnTheWay, linkRefusal, linkWords, locateRoot, looksBinary, namesHolder, nestedAtReal, nestedGuess, nestedHolder, nestedStep, observePath, parsedSpelling, passedOverAt, pathSegments, patternRefusal, readBytes, readPrefix, restBeneath, rootAbsence, sameRoot, shownLeads, sniffImageMime, surelyAtRoot, walkScope, withinIncludes } from './observe.js';
|
|
16
17
|
import { TOOL_BATCH_HOOK_TIMEOUT_MS, ensureStateRegistered } from '../../module-registry.js';
|
|
17
18
|
import { DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS } from '../../tool-result-history.js';
|
|
18
19
|
import { countBudget, decodeForEdit, hintBudget, planFile } from './edit-plan.js';
|
|
@@ -20,9 +21,9 @@ import { cutLine, editList, editReceipt, fitted, refusalText } from './edit-text
|
|
|
20
21
|
import { fileText } from './text.js';
|
|
21
22
|
import { DEFAULT_READ_LINE_LIMIT, characterPage, linePage } from './read-page.js';
|
|
22
23
|
import { grepText, textAnswer } from './result-text.js';
|
|
23
|
-
import { NOT_PUSHED_IN_OTHER_MOUNT, WALK_CAP, entryMode, pushPaths, reconcilePass, settleAdoptionBeforeMutation, } from './reconcile.js';
|
|
24
|
+
import { NOT_PUSHED_IN_OTHER_MOUNT, WALK_CAP, entryMode, explained, pushPaths, reconcilePass, settleAdoptionBeforeMutation, wayOn, } from './reconcile.js';
|
|
24
25
|
import { EffectFailed, unlinkContained } from './effects.js';
|
|
25
|
-
import { AWAITS_REOPEN,
|
|
26
|
+
import { AWAITS_REOPEN, MOUNT_IT, ROOT_RECHECK, Refusal, UNFOLLOWED_STEP, changesFiles, didNothing, errnoCode, errnoWayOn, errnoWords, hostFix, onlyTheHost, systemWords, unexpectedAnswer } from './answers.js';
|
|
26
27
|
import { unknownToolMessage } from '../unknown-tool.js';
|
|
27
28
|
import { closestNames } from '../../closest-names.js';
|
|
28
29
|
import { RecordJournal } from '../../record-journal.js';
|
|
@@ -124,6 +125,13 @@ class NotRegularFile extends WorkspaceReadError {
|
|
|
124
125
|
super('not_found', `Not a regular file: ${path}`, stage);
|
|
125
126
|
}
|
|
126
127
|
}
|
|
128
|
+
class LinkOnTheWay extends WorkspaceReadError {
|
|
129
|
+
reason;
|
|
130
|
+
constructor(code, message, reason, errno) {
|
|
131
|
+
super(code, message, 'readlink', errno);
|
|
132
|
+
this.reason = reason;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
127
135
|
class RootUnavailable extends WorkspaceReadError {
|
|
128
136
|
mount;
|
|
129
137
|
reason;
|
|
@@ -139,10 +147,10 @@ class RootUnavailable extends WorkspaceReadError {
|
|
|
139
147
|
* Why a pass decided nothing, or null where it decided its paths. A pass gives
|
|
140
148
|
* up deciding, and reports no path, when the selected branch kept changing
|
|
141
149
|
* while it gathered, or when a sync's branch was no longer selected; it then
|
|
142
|
-
* carries no branchId, and
|
|
150
|
+
* carries no branchId, and says why in `undecided`.
|
|
143
151
|
*/
|
|
144
152
|
function undecidedOf(pass) {
|
|
145
|
-
return pass.branchId === undefined ? (pass.
|
|
153
|
+
return pass.branchId === undefined ? (pass.undecided ?? 'the pass decided nothing') : null;
|
|
146
154
|
}
|
|
147
155
|
function errnoOf(err) {
|
|
148
156
|
return typeof err === 'object' && err !== null && 'code' in err && typeof err.code === 'string'
|
|
@@ -194,15 +202,16 @@ function matchesPartialPrefix(buffer, prefix) {
|
|
|
194
202
|
*/
|
|
195
203
|
async function linkReadError(mount, found, mountPrefixedPath, relativePath, nested, rootReal) {
|
|
196
204
|
if (!('link' in found)) {
|
|
197
|
-
|
|
205
|
+
const reason = linkWords(mount.config.name, found, null);
|
|
206
|
+
return new LinkOnTheWay('not_found', `Unable to read file: ${mountPrefixedPath}: ${reason}`, reason, found.code);
|
|
198
207
|
}
|
|
199
208
|
const leads = await shownLeads(rootReal, rootReal, found, mount.config.include);
|
|
200
|
-
const reason =
|
|
209
|
+
const reason = linkWords(mount.config.name, found, leads, nested, mount.config.include);
|
|
201
210
|
const holder = leads?.kind === 'inside' ? nestedHolder(leads.target, nested) : undefined;
|
|
202
211
|
const code = leads?.kind === 'outside' ? 'escape'
|
|
203
212
|
: leads?.kind === 'inside' && holder && namesHolder(leads, nested) ? 'other_mount'
|
|
204
213
|
: relativePath === found.link ? 'symlink' : 'parent_symlink';
|
|
205
|
-
return new
|
|
214
|
+
return new LinkOnTheWay(code, `${mountPrefixedPath}: ${reason}`, reason);
|
|
206
215
|
}
|
|
207
216
|
/**
|
|
208
217
|
* `to` beneath `from`, mount-relative and `/`-separated, whatever the
|
|
@@ -1996,14 +2005,14 @@ export class WorkspaceModule {
|
|
|
1996
2005
|
return { requestInference: true };
|
|
1997
2006
|
let text;
|
|
1998
2007
|
if (paths.length === 1) {
|
|
1999
|
-
text = `[
|
|
2008
|
+
text = `[${NOTICE_TAG.workspaceEvent} · ${op} · ${paths[0]}]`;
|
|
2000
2009
|
}
|
|
2001
2010
|
else {
|
|
2002
2011
|
const list = paths.map(p => `- ${p}`).join('\n');
|
|
2003
|
-
text = `[
|
|
2012
|
+
text = `[${NOTICE_TAG.workspaceEvent} · ${op} · ${paths.length} files in ${mountName}/]\n${list}`;
|
|
2004
2013
|
}
|
|
2005
2014
|
if (conflicts && conflicts.length > 0) {
|
|
2006
|
-
text += `\n[
|
|
2015
|
+
text += `\n[${NOTICE_TAG.conflictsWithDisk}: ${conflicts.join(', ')}; reading each shows how to settle it]`;
|
|
2007
2016
|
}
|
|
2008
2017
|
return {
|
|
2009
2018
|
requestInference: true,
|
|
@@ -2830,6 +2839,16 @@ export class WorkspaceModule {
|
|
|
2830
2839
|
const names = [...this.mounts.keys()];
|
|
2831
2840
|
return names.length === 0 ? 'this workspace has no mounts' : `the mounts are ${listed(names.map((name) => JSON.stringify(name)))}`;
|
|
2832
2841
|
}
|
|
2842
|
+
emptyPathField(mount, bare) {
|
|
2843
|
+
const empty = '"path" is "", which names no file or directory.';
|
|
2844
|
+
if (mount === undefined)
|
|
2845
|
+
return `${empty} Leaving "path" out ${bare}.`;
|
|
2846
|
+
if (mount === '')
|
|
2847
|
+
return `${empty} "mount" is "" too; leaving both out ${bare}.`;
|
|
2848
|
+
if (this.mounts.has(mount))
|
|
2849
|
+
return `${empty} Leaving "path" out covers mount ${JSON.stringify(mount)}.`;
|
|
2850
|
+
return `${empty} "mount" is ${JSON.stringify(mount)}, which is no mount's name; ${this.mountList()}. Leaving both out ${bare}.`;
|
|
2851
|
+
}
|
|
2833
2852
|
noSuchMountField(given, bare) {
|
|
2834
2853
|
const [close] = closestNames(given, [...this.mounts.keys()], 1);
|
|
2835
2854
|
return `"mount" is ${JSON.stringify(given)}, which is no mount's name; ${this.mountList()}.`
|
|
@@ -3568,7 +3587,7 @@ export class WorkspaceModule {
|
|
|
3568
3587
|
return `${shown} is in conflict: the workspace deleted it and disk changed it since. ` +
|
|
3569
3588
|
'Sync this path to take the disk version.';
|
|
3570
3589
|
case 'unverified':
|
|
3571
|
-
return uncheckedFile(shown, report.note);
|
|
3590
|
+
return uncheckedFile(shown, report.note, report.noteCause ?? {});
|
|
3572
3591
|
default:
|
|
3573
3592
|
return missing ?? `there's no file at ${shown}. ls or glob lists the files that exist.`;
|
|
3574
3593
|
}
|
|
@@ -3736,9 +3755,9 @@ export class WorkspaceModule {
|
|
|
3736
3755
|
const rootReal = await realpath(root).catch(() => root);
|
|
3737
3756
|
const view = this.viewOf(mount, this.agreementOrThrow().rootIdentityForRead(mount.config.name));
|
|
3738
3757
|
const proof = await confirmAbsent(view, rootReal, relativePath);
|
|
3739
|
-
if (
|
|
3758
|
+
if (!('reason' in proof))
|
|
3740
3759
|
return 'none';
|
|
3741
|
-
return { unreadable: proof === CHANGED ? containedRefusal(err, path) : proof };
|
|
3760
|
+
return { unreadable: proof.reason === CHANGED ? containedRefusal(err, path) : proof.reason };
|
|
3742
3761
|
}
|
|
3743
3762
|
async restoreEach(mount, versions, each) {
|
|
3744
3763
|
const byHash = new Map();
|
|
@@ -4700,7 +4719,7 @@ export class WorkspaceModule {
|
|
|
4700
4719
|
// whether the file is gone, so it's taken as the agent's write too.
|
|
4701
4720
|
if (error instanceof EffectFailed && error.touched) {
|
|
4702
4721
|
this.recordDirectWrite(mount, agentName, since);
|
|
4703
|
-
return { success: false, isError: true, error: `The delete of ${path} failed after it reached the file, so the file may be gone: ${directReason(error)}. ls shows whether it is.` };
|
|
4722
|
+
return { success: false, isError: true, error: `The delete of ${JSON.stringify(path)} failed after it reached the file, so the file may be gone: ${directReason(error)}. ls shows whether it is.` };
|
|
4704
4723
|
}
|
|
4705
4724
|
return { success: false, isError: true, error: directDidNothing('delete', path, error) };
|
|
4706
4725
|
}
|
|
@@ -5059,7 +5078,8 @@ export class WorkspaceModule {
|
|
|
5059
5078
|
.filter((region) => region.kind === 'error' || region.kind === 'cap' || (region.kind === 'ignored' && region.path === dir && dir !== ''))
|
|
5060
5079
|
.map((region) => ({
|
|
5061
5080
|
path: region.path,
|
|
5062
|
-
reason: region.reason === OTHER_MOUNT ? this.otherMountNote(mount.config.name, region.path, 'list', moved)
|
|
5081
|
+
reason: region.reason === OTHER_MOUNT ? this.otherMountNote(mount.config.name, region.path, 'list', moved)
|
|
5082
|
+
: explained(region.reason, region.errno !== undefined ? { errno: region.errno } : {}, 'list'),
|
|
5063
5083
|
}));
|
|
5064
5084
|
return {
|
|
5065
5085
|
view,
|
|
@@ -5669,7 +5689,10 @@ export class WorkspaceModule {
|
|
|
5669
5689
|
const pendingDeletions = [];
|
|
5670
5690
|
const modesKept = [];
|
|
5671
5691
|
let explicit = null;
|
|
5672
|
-
if (input.path) {
|
|
5692
|
+
if (input.path !== undefined) {
|
|
5693
|
+
if (input.path === '') {
|
|
5694
|
+
return { success: false, error: didNothing('materialize', this.emptyPathField(input.mount, "covers every mount that takes writes and doesn't already write them straight to disk")), isError: true };
|
|
5695
|
+
}
|
|
5673
5696
|
const parsed = await this.parsePath(input.path);
|
|
5674
5697
|
explicit = parsed;
|
|
5675
5698
|
// A path outside the mount's include that's no scope (refusesAsOutside)
|
|
@@ -5683,7 +5706,7 @@ export class WorkspaceModule {
|
|
|
5683
5706
|
if (explicit) {
|
|
5684
5707
|
mountsToMaterialize = [{ name: explicit.mount.config.name, mount: explicit.mount }];
|
|
5685
5708
|
}
|
|
5686
|
-
else if (input.mount) {
|
|
5709
|
+
else if (input.mount !== undefined) {
|
|
5687
5710
|
const m = this.mounts.get(input.mount);
|
|
5688
5711
|
if (!m) {
|
|
5689
5712
|
return { success: false, error: didNothing('materialize', this.noSuchMountField(input.mount, "covers every mount that takes writes and doesn't already write them straight to disk")), isError: true };
|
|
@@ -5885,7 +5908,9 @@ export class WorkspaceModule {
|
|
|
5885
5908
|
}
|
|
5886
5909
|
// A path names its own mount; otherwise the given mount, or every mount.
|
|
5887
5910
|
let targets;
|
|
5888
|
-
if (input.path) {
|
|
5911
|
+
if (input.path !== undefined) {
|
|
5912
|
+
if (input.path === '')
|
|
5913
|
+
return { success: false, error: didNothing('sync', this.emptyPathField(input.mount, 'covers every mount')), isError: true };
|
|
5889
5914
|
const { mount, relativePath, moved, root } = await this.parsePath(input.path);
|
|
5890
5915
|
// A path outside the mount's include that's no scope (refusesAsOutside)
|
|
5891
5916
|
// is refused; beneath a directory, the walk passes over what the include
|
|
@@ -5895,7 +5920,7 @@ export class WorkspaceModule {
|
|
|
5895
5920
|
}
|
|
5896
5921
|
targets = [{ name: mount.config.name, mount, relativePath }];
|
|
5897
5922
|
}
|
|
5898
|
-
else if (input.mount) {
|
|
5923
|
+
else if (input.mount !== undefined) {
|
|
5899
5924
|
const m = this.mounts.get(input.mount);
|
|
5900
5925
|
if (!m) {
|
|
5901
5926
|
return { success: false, error: didNothing('sync', this.noSuchMountField(input.mount, 'covers every mount')), isError: true };
|
|
@@ -5976,7 +6001,7 @@ export class WorkspaceModule {
|
|
|
5976
6001
|
// refused" don't look identical from the outside.
|
|
5977
6002
|
for (const r of pass.reports.values()) {
|
|
5978
6003
|
if (r.state === 'unverified') {
|
|
5979
|
-
allSkipped.push({ mount: name, path: r.path, reason: `disk could not be checked: ${r.note ?? 'not observed'}` });
|
|
6004
|
+
allSkipped.push({ mount: name, path: r.path, reason: `disk could not be checked: ${explained(r.note ?? 'not observed', r.noteCause ?? {}, 'sync')}` });
|
|
5980
6005
|
}
|
|
5981
6006
|
else if (r.state === 'disk-only') {
|
|
5982
6007
|
allSkipped.push({ mount: name, path: r.path, reason: 'disk-only: binary or over the size limit, never stored' });
|
|
@@ -6406,7 +6431,17 @@ function directReason(error) {
|
|
|
6406
6431
|
return error instanceof Error ? error.message : String(error);
|
|
6407
6432
|
}
|
|
6408
6433
|
function directWayOn(error) {
|
|
6409
|
-
|
|
6434
|
+
if (error instanceof FileChanged)
|
|
6435
|
+
return 'Calling again reads it afresh.';
|
|
6436
|
+
if (error instanceof WriteRefused)
|
|
6437
|
+
return error.wayOn;
|
|
6438
|
+
if (error instanceof EffectFailed) {
|
|
6439
|
+
if (error.detail.errno !== undefined)
|
|
6440
|
+
return errnoWayOn(error.detail.errno);
|
|
6441
|
+
if (error.detail.again === true)
|
|
6442
|
+
return 'Calling again checks it afresh.';
|
|
6443
|
+
}
|
|
6444
|
+
return null;
|
|
6410
6445
|
}
|
|
6411
6446
|
function directDidNothing(tool, path, error) {
|
|
6412
6447
|
const on = directWayOn(error);
|
|
@@ -6439,17 +6474,12 @@ function containedRefusal(err, path) {
|
|
|
6439
6474
|
function deletedOnDisk(path) {
|
|
6440
6475
|
return `there's no file at ${JSON.stringify(path)} any more: disk's copy was deleted since the workspace last agreed with it, and the workspace took that in first. ls or glob lists the files that exist.`;
|
|
6441
6476
|
}
|
|
6442
|
-
function uncheckedFile(shown, note) {
|
|
6477
|
+
function uncheckedFile(shown, note, cause) {
|
|
6443
6478
|
if (note === DIRECTORY)
|
|
6444
6479
|
return `${shown} is a directory, not a file; ls ${shown} lists what's in it.`;
|
|
6445
|
-
const on = note ===
|
|
6446
|
-
: note ===
|
|
6447
|
-
|
|
6448
|
-
: note === LEAVES_MOUNT ? "Calling again won't change that; if a mount holds the file it leads to, name it by its path there."
|
|
6449
|
-
: note === NOT_REGULAR ? onlyTheHost('put a regular file there')
|
|
6450
|
-
: note === CHANGED ? 'Calling again checks it afresh.'
|
|
6451
|
-
: 'Calling again checks disk again; if the same reason comes back, whoever runs this host can fix it on disk.';
|
|
6452
|
-
return `${shown} isn't in the workspace, and disk couldn't be checked: ${sentence(note ?? 'not observed')}${on !== null ? ` ${on}` : ''}`;
|
|
6480
|
+
const on = note === ROOT_REPLACED || cause.ownStep === true ? null
|
|
6481
|
+
: (note === undefined ? null : wayOn(note, cause, 'read')) ?? 'calling again checks disk again; if the same reason comes back, whoever runs this host can fix it on disk';
|
|
6482
|
+
return `${shown} isn't in the workspace, and disk couldn't be checked: ${sentence(note ?? 'not observed')}${on !== null ? ` ${on[0].toUpperCase()}${sentence(on.slice(1))}` : ''}`;
|
|
6453
6483
|
}
|
|
6454
6484
|
function namesRoot(path, mount) {
|
|
6455
6485
|
return `${JSON.stringify(path)} names the root of mount "${mount}", which isn't a file; ls "${mount}" lists the files in it.`;
|
|
@@ -6485,17 +6515,17 @@ function readRefusal(err, path) {
|
|
|
6485
6515
|
}
|
|
6486
6516
|
return `${shown} can't be read: ${sentence(err.reason)}`;
|
|
6487
6517
|
}
|
|
6488
|
-
if (err
|
|
6489
|
-
return sentence(err.
|
|
6518
|
+
if (err instanceof LinkOnTheWay)
|
|
6519
|
+
return `${shown} can't be reached: ${sentence(err.reason)}`;
|
|
6490
6520
|
switch (err.code) {
|
|
6491
6521
|
case 'directory':
|
|
6492
6522
|
return `${shown} is a directory, not a file; ls ${shown} lists what's in it.`;
|
|
6493
6523
|
case 'symlink':
|
|
6494
6524
|
return `${shown} is a symlink, and its mount doesn't follow symlinks, so the workspace's tools don't go through it. `
|
|
6495
|
-
+
|
|
6525
|
+
+ `Calling again won't change that; ${UNFOLLOWED_STEP}.`;
|
|
6496
6526
|
case 'escape':
|
|
6497
6527
|
return `${shown} leads through a symlink to a place outside its mount, so the workspace's tools don't reach it. `
|
|
6498
|
-
+
|
|
6528
|
+
+ `Calling again won't change that; ${MOUNT_IT}.`;
|
|
6499
6529
|
case 'changed':
|
|
6500
6530
|
return `${shown} changed on disk while it was being read. Calling again reads it afresh.`;
|
|
6501
6531
|
case 'not_found':
|
|
@@ -6557,7 +6587,7 @@ function remedyOfLost(lost) {
|
|
|
6557
6587
|
*/
|
|
6558
6588
|
function headMoveText(mounts) {
|
|
6559
6589
|
const one = mounts.length === 1;
|
|
6560
|
-
return `[workspace] Writes to ${listed(mounts.map((name) => `\`${name}\``))} from turns the history no longer holds are still on disk. `
|
|
6590
|
+
return `[${NOTICE_TAG.workspace}] Writes to ${listed(mounts.map((name) => `\`${name}\``))} from turns the history no longer holds are still on disk. `
|
|
6561
6591
|
+ `If ${one ? "it's a git checkout" : "they're git checkouts"}, \`git status\` and \`git diff\` show them; `
|
|
6562
6592
|
+ 'a `git checkout` of a file drops every unstaged change in it, including the ones the history still holds.';
|
|
6563
6593
|
}
|