@animalabs/agent-framework 0.23.1 → 0.24.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 +212 -42
- package/dist/src/agent.d.ts +60 -9
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +92 -12
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +14 -12
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/code-execution/engine.d.ts +177 -0
- package/dist/src/code-execution/engine.d.ts.map +1 -0
- package/dist/src/code-execution/engine.js +494 -0
- package/dist/src/code-execution/engine.js.map +1 -0
- package/dist/src/code-execution/index.d.ts +5 -10
- package/dist/src/code-execution/index.d.ts.map +1 -1
- package/dist/src/code-execution/index.js +5 -9
- package/dist/src/code-execution/index.js.map +1 -1
- package/dist/src/code-execution/isolate/calls.d.ts +114 -0
- package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/calls.js +145 -0
- package/dist/src/code-execution/isolate/calls.js.map +1 -0
- package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
- package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child-entry.js +5 -0
- package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
- package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
- package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child-main.js +132 -0
- package/dist/src/code-execution/isolate/child-main.js.map +1 -0
- package/dist/src/code-execution/isolate/child.d.ts +44 -0
- package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child.js +315 -0
- package/dist/src/code-execution/isolate/child.js.map +1 -0
- package/dist/src/code-execution/isolate/frames.d.ts +80 -0
- package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/frames.js +210 -0
- package/dist/src/code-execution/isolate/frames.js.map +1 -0
- package/dist/src/code-execution/isolate/output.d.ts +68 -0
- package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/output.js +143 -0
- package/dist/src/code-execution/isolate/output.js.map +1 -0
- package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
- package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/prelude.js +401 -0
- package/dist/src/code-execution/isolate/prelude.js.map +1 -0
- package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
- package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/protocol.js +150 -0
- package/dist/src/code-execution/isolate/protocol.js.map +1 -0
- package/dist/src/code-execution/isolate/render.d.ts +57 -0
- package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/render.js +214 -0
- package/dist/src/code-execution/isolate/render.js.map +1 -0
- package/dist/src/code-execution/isolate/runner.d.ts +250 -0
- package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/runner.js +854 -0
- package/dist/src/code-execution/isolate/runner.js.map +1 -0
- package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
- package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/scripts.js +357 -0
- package/dist/src/code-execution/isolate/scripts.js.map +1 -0
- package/dist/src/code-execution/quickjs.wasm +0 -0
- package/dist/src/code-execution/tool-definition.d.ts +93 -43
- package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
- package/dist/src/code-execution/tool-definition.js +176 -142
- package/dist/src/code-execution/tool-definition.js.map +1 -1
- package/dist/src/deadline-timer.d.ts +3 -0
- package/dist/src/deadline-timer.d.ts.map +1 -1
- package/dist/src/deadline-timer.js +1 -1
- package/dist/src/deadline-timer.js.map +1 -1
- package/dist/src/framework.d.ts +1036 -440
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +4131 -2228
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +28 -1
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +88 -10
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/held-writes.d.ts +16 -3
- package/dist/src/held-writes.d.ts.map +1 -1
- package/dist/src/held-writes.js +16 -3
- package/dist/src/held-writes.js.map +1 -1
- package/dist/src/index.d.ts +6 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +471 -75
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +1673 -337
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts +12 -7
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/conversation-router.js +12 -7
- package/dist/src/mcpl/conversation-router.js.map +1 -1
- package/dist/src/mcpl/convert-block.d.ts.map +1 -1
- package/dist/src/mcpl/convert-block.js +9 -5
- package/dist/src/mcpl/convert-block.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +50 -0
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
- package/dist/src/mcpl/inbound-source.js +130 -0
- package/dist/src/mcpl/inbound-source.js.map +1 -1
- package/dist/src/mcpl/index.d.ts +2 -1
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js +3 -2
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/log-value.d.ts +6 -0
- package/dist/src/mcpl/log-value.d.ts.map +1 -1
- package/dist/src/mcpl/log-value.js +8 -0
- package/dist/src/mcpl/log-value.js.map +1 -1
- package/dist/src/mcpl/modern-connection.d.ts +15 -6
- package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
- package/dist/src/mcpl/modern-connection.js +168 -53
- package/dist/src/mcpl/modern-connection.js.map +1 -1
- package/dist/src/mcpl/prose-grammar.d.ts +4 -5
- package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
- package/dist/src/mcpl/prose-grammar.js +4 -5
- package/dist/src/mcpl/prose-grammar.js.map +1 -1
- package/dist/src/mcpl/protocol-family.d.ts +97 -10
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
- package/dist/src/mcpl/protocol-family.js +173 -16
- package/dist/src/mcpl/protocol-family.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +132 -14
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +227 -50
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +6 -1
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js +4 -1
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +4 -4
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +50 -21
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +158 -74
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/tags.d.ts +24 -0
- package/dist/src/mcpl/tags.d.ts.map +1 -1
- package/dist/src/mcpl/tags.js +33 -0
- package/dist/src/mcpl/tags.js.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
- package/dist/src/mcpl/transport.d.ts +55 -7
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +163 -34
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +22 -6
- 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 +4 -2
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +100 -13
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +8 -13
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +27 -4
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +15 -3
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +27 -5
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/index.d.ts +1 -1
- package/dist/src/modules/index.d.ts.map +1 -1
- package/dist/src/modules/index.js.map +1 -1
- package/dist/src/modules/unknown-tool.d.ts +4 -1
- package/dist/src/modules/unknown-tool.d.ts.map +1 -1
- package/dist/src/modules/unknown-tool.js +4 -1
- package/dist/src/modules/unknown-tool.js.map +1 -1
- package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
- package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
- package/dist/src/modules/workspace/branch-intent.js +3 -1
- package/dist/src/modules/workspace/branch-intent.js.map +1 -1
- package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
- package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
- package/dist/src/modules/workspace/edit-plan.js +794 -0
- package/dist/src/modules/workspace/edit-plan.js.map +1 -0
- package/dist/src/modules/workspace/edit-text.d.ts +117 -0
- package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
- package/dist/src/modules/workspace/edit-text.js +584 -0
- package/dist/src/modules/workspace/edit-text.js.map +1 -0
- package/dist/src/modules/workspace/effects.d.ts +5 -4
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +78 -25
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +484 -61
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +2173 -645
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +213 -38
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +416 -36
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +15 -8
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/modules/workspace/text.d.ts +32 -0
- package/dist/src/modules/workspace/text.d.ts.map +1 -0
- package/dist/src/modules/workspace/text.js +67 -0
- package/dist/src/modules/workspace/text.js.map +1 -0
- package/dist/src/modules/workspace/types.d.ts +210 -6
- package/dist/src/modules/workspace/types.d.ts.map +1 -1
- package/dist/src/modules/workspace/types.js.map +1 -1
- package/dist/src/modules/workspace/watcher.d.ts +3 -2
- package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
- package/dist/src/modules/workspace/watcher.js.map +1 -1
- package/dist/src/operator-log.d.ts +52 -24
- package/dist/src/operator-log.d.ts.map +1 -1
- package/dist/src/operator-log.js.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
- package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
- package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
- package/dist/src/recovery/offline-branch.d.ts +26 -1
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +164 -39
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/recovery/recover-cli.js +23 -4
- package/dist/src/recovery/recover-cli.js.map +1 -1
- package/dist/src/send-tools.d.ts +11 -0
- package/dist/src/send-tools.d.ts.map +1 -0
- package/dist/src/send-tools.js +11 -0
- package/dist/src/send-tools.js.map +1 -0
- package/dist/src/tool-result-guard.d.ts +4 -3
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +5 -4
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tool-result-history.d.ts +1 -1
- package/dist/src/tool-result-history.js +1 -1
- package/dist/src/tune-out/coordinator.d.ts +21 -0
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +139 -37
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/types/agent.d.ts +4 -0
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +62 -9
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +62 -58
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +40 -8
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +111 -10
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/src/usage/types.d.ts +16 -0
- package/dist/src/usage/types.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.d.ts +14 -1
- package/dist/src/usage/usage-tracker.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.js +81 -41
- package/dist/src/usage/usage-tracker.js.map +1 -1
- package/package.json +6 -5
- package/src/agent.ts +93 -12
- package/src/api/server.ts +14 -12
- package/src/code-execution/engine.ts +595 -0
- package/src/code-execution/index.ts +5 -17
- package/src/code-execution/isolate/calls.ts +199 -0
- package/src/code-execution/isolate/child-entry.ts +5 -0
- package/src/code-execution/isolate/child-main.ts +132 -0
- package/src/code-execution/isolate/child.ts +327 -0
- package/src/code-execution/isolate/frames.ts +209 -0
- package/src/code-execution/isolate/output.ts +161 -0
- package/src/code-execution/isolate/prelude.ts +409 -0
- package/src/code-execution/isolate/protocol.ts +240 -0
- package/src/code-execution/isolate/render.ts +230 -0
- package/src/code-execution/isolate/runner.ts +911 -0
- package/src/code-execution/isolate/scripts.ts +479 -0
- package/src/code-execution/quickjs.wasm +0 -0
- package/src/code-execution/quickjs.wasm.LICENSES +149 -0
- package/src/code-execution/tool-definition.ts +236 -167
- package/src/deadline-timer.ts +1 -1
- package/src/framework.ts +4507 -2406
- package/src/gate/event-gate.ts +78 -11
- package/src/held-writes.ts +17 -3
- package/src/index.ts +30 -22
- package/src/mcpl/channel-registry.ts +1825 -368
- package/src/mcpl/conversation-router.ts +12 -7
- package/src/mcpl/convert-block.ts +9 -5
- package/src/mcpl/inbound-source.ts +131 -0
- package/src/mcpl/index.ts +4 -2
- package/src/mcpl/log-value.ts +9 -0
- package/src/mcpl/modern-connection.ts +162 -53
- package/src/mcpl/prose-grammar.ts +4 -5
- package/src/mcpl/protocol-family.ts +199 -21
- package/src/mcpl/push-coalescer.ts +306 -62
- package/src/mcpl/push-handler.ts +10 -2
- package/src/mcpl/reference-fetcher.ts +4 -4
- package/src/mcpl/server-connection.ts +180 -79
- package/src/mcpl/tags.ts +36 -0
- package/src/mcpl/tool-result-normalize.ts +2 -1
- package/src/mcpl/transport.ts +162 -33
- package/src/mcpl/types.ts +23 -6
- package/src/module-registry.ts +92 -13
- package/src/modules/discord/index.ts +8 -13
- package/src/modules/history/index.ts +25 -3
- package/src/modules/history/semantic.ts +29 -6
- package/src/modules/index.ts +1 -0
- package/src/modules/unknown-tool.ts +4 -1
- package/src/modules/workspace/branch-intent.ts +3 -1
- package/src/modules/workspace/edit-plan.ts +954 -0
- package/src/modules/workspace/edit-text.ts +618 -0
- package/src/modules/workspace/effects.ts +70 -19
- package/src/modules/workspace/index.ts +2247 -642
- package/src/modules/workspace/observe.ts +465 -56
- package/src/modules/workspace/reconcile.ts +14 -7
- package/src/modules/workspace/text.ts +68 -0
- package/src/modules/workspace/types.ts +211 -6
- package/src/modules/workspace/watcher.ts +3 -2
- package/src/operator-log.ts +47 -19
- package/src/recovery/discord-awareness-outbox.ts +1500 -356
- package/src/recovery/offline-branch.ts +189 -55
- package/src/recovery/recover-cli.ts +25 -4
- package/src/send-tools.ts +11 -0
- package/src/tool-result-guard.ts +6 -5
- package/src/tool-result-history.ts +1 -1
- package/src/tune-out/coordinator.ts +163 -42
- package/src/types/agent.ts +4 -0
- package/src/types/events.ts +62 -9
- package/src/types/framework.ts +62 -58
- package/src/types/module.ts +40 -8
- package/src/types/trace.ts +121 -15
- package/src/usage/types.ts +16 -0
- package/src/usage/usage-tracker.ts +86 -43
- package/dist/src/code-execution/py-runner.d.ts +0 -191
- package/dist/src/code-execution/py-runner.d.ts.map +0 -1
- package/dist/src/code-execution/py-runner.js +0 -655
- package/dist/src/code-execution/py-runner.js.map +0 -1
- package/dist/src/code-execution/runtime-py.d.ts +0 -50
- package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
- package/dist/src/code-execution/runtime-py.js +0 -677
- package/dist/src/code-execution/runtime-py.js.map +0 -1
- package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
- package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
- package/dist/src/mcpl/prose-stream-router.js +0 -291
- package/dist/src/mcpl/prose-stream-router.js.map +0 -1
- package/src/code-execution/py-runner.ts +0 -791
- package/src/code-execution/runtime-py.ts +0 -677
- package/src/mcpl/prose-stream-router.ts +0 -268
|
@@ -72,6 +72,7 @@ import {
|
|
|
72
72
|
readPath,
|
|
73
73
|
sniffImageMime,
|
|
74
74
|
walkScope,
|
|
75
|
+
withinIncludes,
|
|
75
76
|
} from './observe.js';
|
|
76
77
|
import { EffectFailed, type Expect, chainOf, chmodContained, narrowedTo, syncDirectories, unlinkContained, writeContained } from './effects.js';
|
|
77
78
|
|
|
@@ -856,16 +857,22 @@ async function gather(store: JsStore, agreement: DiskAgreement, mount: MountRunt
|
|
|
856
857
|
}
|
|
857
858
|
|
|
858
859
|
// Which paths to decide: what disk shows, and what the store, P and intent
|
|
859
|
-
// track. The tracked ones are read synchronously, on this branch.
|
|
860
|
+
// track. The tracked ones are read synchronously, on this branch. A path
|
|
861
|
+
// the mount's include doesn't cover is outside the mount, so no pass
|
|
862
|
+
// decides it: the workspace's history may hold it from before the include,
|
|
863
|
+
// and it stays there as it is. So is one in a nested mount's directory
|
|
864
|
+
// that mount's include leaves out, such as history taken in before the
|
|
865
|
+
// mount was nested there: it's no mount's (namesNestedPlace).
|
|
860
866
|
const candidates = new Set<string>();
|
|
867
|
+
const inside = (p: string): boolean => withinIncludes(mount.view, p);
|
|
861
868
|
let walk: Walk | null = null;
|
|
862
869
|
if (scope.kind === 'paths') {
|
|
863
|
-
for (const p of scope.paths) candidates.add(p);
|
|
870
|
+
for (const p of scope.paths) if (inside(p)) candidates.add(p);
|
|
864
871
|
} else {
|
|
865
872
|
const prefix = scope.dir ? scope.dir + '/' : undefined;
|
|
866
|
-
for (const e of store.treeList(mount.treeStateId, prefix)) if (inScope(e.path, scope)) candidates.add(e.path);
|
|
867
|
-
for (const [p] of agreement.paths(mount.name, scope.dir)) if (inScope(p, scope)) candidates.add(p);
|
|
868
|
-
for (const [p] of mount.intents.list(scope.dir)) if (inScope(p, scope)) candidates.add(p);
|
|
873
|
+
for (const e of store.treeList(mount.treeStateId, prefix)) if (inScope(e.path, scope) && inside(e.path)) candidates.add(e.path);
|
|
874
|
+
for (const [p] of agreement.paths(mount.name, scope.dir)) if (inScope(p, scope) && inside(p)) candidates.add(p);
|
|
875
|
+
for (const [p] of mount.intents.list(scope.dir)) if (inScope(p, scope) && inside(p)) candidates.add(p);
|
|
869
876
|
if (rootUnavailable === null) {
|
|
870
877
|
const resumeAfter = opts.resume ? agreement.walkResumesAfter(mount.name, scope.dir) : undefined;
|
|
871
878
|
walk = await walkScope(mount.view, mount.rootReal, scope.dir, scope.recursive, opts.cap ?? mount.walkCap, {
|
|
@@ -1146,8 +1153,8 @@ export async function reconcilePass(
|
|
|
1146
1153
|
// it, so it's always named. Another mount's directory met beneath the
|
|
1147
1154
|
// scope is passed over by design even where this mount's tree holds
|
|
1148
1155
|
// copies there: no tool of this mount syncs, pushes or clears them
|
|
1149
|
-
// (listings show
|
|
1150
|
-
// as unreached would never clear.
|
|
1156
|
+
// (listings show those that mount's include covers, naming their
|
|
1157
|
+
// holder), so naming the directory as unreached would never clear.
|
|
1151
1158
|
const wholeScope = scope.kind === 'dir' && scope.dir !== '' && region.path === scope.dir;
|
|
1152
1159
|
const unreached = hides && region.reason !== OTHER_MOUNT;
|
|
1153
1160
|
if (region.kind === 'error' || region.kind === 'cap' || unreached || wholeScope) result.incomplete.push({ path: region.path, reason: region.reason });
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lines numbered the way `cat -n` numbers them, with a long one cut, and a
|
|
3
|
+
* string's length as JSON, which a budget for a stored result counts. edit's
|
|
4
|
+
* answers use them.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Whether the bytes open with a UTF-8 byte order mark. */
|
|
8
|
+
export function hasBom(bytes: Uint8Array): boolean {
|
|
9
|
+
return bytes.length >= 3 && bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** How long a line read shows before it cuts the line. */
|
|
13
|
+
export const MAX_LINE_CHARS = 2000;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Where to cut a string at or just before `at` without splitting a surrogate
|
|
17
|
+
* pair: a lone surrogate isn't text, and a model provider can refuse a
|
|
18
|
+
* request that carries one.
|
|
19
|
+
*/
|
|
20
|
+
export function safeCut(value: string, at: number): number {
|
|
21
|
+
if (at <= 0 || at >= value.length) return Math.max(0, Math.min(at, value.length));
|
|
22
|
+
const before = value.charCodeAt(at - 1);
|
|
23
|
+
return before >= 0xd800 && before <= 0xdbff ? at - 1 : at;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* One line numbered the way `cat -n` numbers it: a six-wide number, a tab and
|
|
28
|
+
* the line. A line longer than `maxChars` is cut, saying how many characters
|
|
29
|
+
* it holds past the cut, and `readOn` adds how to read them.
|
|
30
|
+
*/
|
|
31
|
+
export function numberedLine(line: string, n: number, maxChars = MAX_LINE_CHARS, readOn?: (cut: number) => string): string {
|
|
32
|
+
const number = String(n).padStart(6);
|
|
33
|
+
if (line.length <= maxChars) return `${number}\t${line}`;
|
|
34
|
+
const cut = safeCut(line, maxChars);
|
|
35
|
+
return `${number}\t${line.slice(0, cut)} [… ${line.length - cut} more chars${readOn ? `; ${readOn(cut)}` : ''}]`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Lines numbered from `start`, each as numberedLine shows it. */
|
|
39
|
+
export function numbered(lines: string[], start: number, maxChars = MAX_LINE_CHARS): string {
|
|
40
|
+
return lines.map((line, i) => numberedLine(line, start + i, maxChars)).join('\n');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* How many characters a string takes inside JSON's quotes, as JSON.stringify
|
|
45
|
+
* writes it: a quote, a backslash or a control character is escaped, and so
|
|
46
|
+
* is a lone surrogate.
|
|
47
|
+
*/
|
|
48
|
+
export function jsonLength(value: string): number {
|
|
49
|
+
let length = 0;
|
|
50
|
+
for (let i = 0; i < value.length; i++) length += jsonCharLength(value, i);
|
|
51
|
+
return length;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** The JSON length of the code unit at `i`, as jsonLength counts it. */
|
|
55
|
+
export function jsonCharLength(value: string, i: number): number {
|
|
56
|
+
const c = value.charCodeAt(i);
|
|
57
|
+
if (c === 0x22 || c === 0x5c) return 2;
|
|
58
|
+
if (c < 0x20) return c === 0x08 || c === 0x09 || c === 0x0a || c === 0x0c || c === 0x0d ? 2 : 6;
|
|
59
|
+
if (c >= 0xd800 && c <= 0xdbff) {
|
|
60
|
+
const next = value.charCodeAt(i + 1);
|
|
61
|
+
return next >= 0xdc00 && next <= 0xdfff ? 1 : 6;
|
|
62
|
+
}
|
|
63
|
+
if (c >= 0xdc00 && c <= 0xdfff) {
|
|
64
|
+
const before = i > 0 ? value.charCodeAt(i - 1) : 0;
|
|
65
|
+
return before >= 0xd800 && before <= 0xdbff ? 1 : 6;
|
|
66
|
+
}
|
|
67
|
+
return 1;
|
|
68
|
+
}
|
|
@@ -16,6 +16,50 @@ export interface MountConfig {
|
|
|
16
16
|
path: string;
|
|
17
17
|
/** Access mode */
|
|
18
18
|
mode: 'read-write' | 'read-only';
|
|
19
|
+
/**
|
|
20
|
+
* Where the mount's tools get what they read (default: 'chronicle').
|
|
21
|
+
* - 'chronicle': the workspace keeps the mount's files in its store, where
|
|
22
|
+
* writes and edits land first, and takes in disk's changes under the
|
|
23
|
+
* three-way rule as its listings, searches, syncs and scans reach them.
|
|
24
|
+
* A read of a path the store doesn't hold takes in a new file there;
|
|
25
|
+
* otherwise it reads the store's copy.
|
|
26
|
+
* - 'direct': for a checkout an agent reads, not one it changes. Every
|
|
27
|
+
* read, listing and search is disk's own copy as it is when it runs,
|
|
28
|
+
* and none of its files go into the store. No scan or watcher
|
|
29
|
+
* runs, so no call waits behind one, and `sync`, `materialize` and the
|
|
30
|
+
* watch settings have nothing to act on. Only with `mode: 'read-only'`,
|
|
31
|
+
* and not with `watch` other than 'never', `watchDebounceMs`,
|
|
32
|
+
* `watchRootPollMs`, a `wakeOnChange` that would wake (true, or a
|
|
33
|
+
* non-empty list) or `autoMaterialize: true`: each of those would never
|
|
34
|
+
* act, and the workspace refuses the mount. Its `ignore`
|
|
35
|
+
* has a default (see there). Paths, links, its `include`, other mounts'
|
|
36
|
+
* directories, size limits and the walk cap hold as on a 'chronicle'
|
|
37
|
+
* mount. Its tools read beneath whatever directory is at its
|
|
38
|
+
* root, with no check against the one a 'chronicle' run of it last
|
|
39
|
+
* agreed with. Where that root now lies elsewhere than the last start
|
|
40
|
+
* placed it, each call nests in it, as a start would now, every mount
|
|
41
|
+
* configured beneath its path, where that path leads beneath its root,
|
|
42
|
+
* and every other mount whose root, as that start placed it, lies
|
|
43
|
+
* beneath where its root lies now, or whose configured path lies
|
|
44
|
+
* beneath a directory that start found there. A mount configured
|
|
45
|
+
* elsewhere whose own root has moved since, and the other mounts' own
|
|
46
|
+
* placements, wait for the next start, so a direct root moved into
|
|
47
|
+
* another mount's directory is still that mount's too.
|
|
48
|
+
*
|
|
49
|
+
* A mount configured 'direct' runs as 'chronicle' from a start that finds
|
|
50
|
+
* the store holding changes there that disk lacks, on the branch selected
|
|
51
|
+
* then: a draft, a workspace deletion or a conflict, as `status` counts
|
|
52
|
+
* them pending, or an intent the workspace can't read, which may hold one
|
|
53
|
+
* of those. They stay in view, and the workspace says so on stderr and
|
|
54
|
+
* through the framework's ops alerts, naming them and the ways to start it
|
|
55
|
+
* direct. It runs unwatched, and walks by the direct kind's default
|
|
56
|
+
* ignore list where its config names none; `ls` without a path, and
|
|
57
|
+
* `status`, give its `backend` as 'chronicle' and that list. A mount that
|
|
58
|
+
* ran direct and runs as 'chronicle' again takes in what disk changed
|
|
59
|
+
* meanwhile as its listings, searches and syncs reach it, as an unwatched
|
|
60
|
+
* 'chronicle' mount does after any time away.
|
|
61
|
+
*/
|
|
62
|
+
backend?: 'chronicle' | 'direct';
|
|
19
63
|
/**
|
|
20
64
|
* Watch mode for filesystem changes:
|
|
21
65
|
* - 'always': chokidar watches continuously; each event re-observes its paths
|
|
@@ -25,8 +69,8 @@ export interface MountConfig {
|
|
|
25
69
|
* the round goes on. Each scan walks from the mount's start, so on a
|
|
26
70
|
* mount over its `walkCap` it covers the first `walkCap` entries every
|
|
27
71
|
* time, and files past them come in as `walkCap` describes
|
|
28
|
-
* - 'never': no background reads; listings
|
|
29
|
-
* the
|
|
72
|
+
* - 'never': no background reads; listings still observe the paths they
|
|
73
|
+
* show, and a read observes a path the store doesn't hold
|
|
30
74
|
*/
|
|
31
75
|
watch?: 'always' | 'on-agent-action' | 'never';
|
|
32
76
|
/** Debounce window in ms for watch: 'always' mode (default: 300) */
|
|
@@ -43,17 +87,157 @@ export interface MountConfig {
|
|
|
43
87
|
* says, a directory with what lies beneath it: `.name.swp` and `.name.swx`
|
|
44
88
|
* (the whole name), and names ending in `~` or in `.subl…tmp`, matched by
|
|
45
89
|
* `^\..+\.sw[px]$`, `~$` and `\.subl.*\.tmp$`.
|
|
90
|
+
*
|
|
91
|
+
* A mount configured direct (`backend`) whose config names no list takes
|
|
92
|
+
* `node_modules`, `dist`, `.git`, `build`, `coverage`, `target`,
|
|
93
|
+
* `__pycache__` and `.venv`, each matching that name at any depth,
|
|
94
|
+
* whichever kind it runs as. A direct mount's walks of the whole mount,
|
|
95
|
+
* and of any path no pattern covers, pass over what the list covers. A
|
|
96
|
+
* listing, glob or grep whose path, or whose pattern's directory, the
|
|
97
|
+
* list covers is walked all the same, the patterns covering it set aside
|
|
98
|
+
* and the rest applying beneath it, as a sync that names a path walks it
|
|
99
|
+
* on a 'chronicle' mount.
|
|
46
100
|
*/
|
|
47
101
|
ignore?: string[];
|
|
102
|
+
/**
|
|
103
|
+
* The files this mount holds, when it holds only some of what is under its
|
|
104
|
+
* path: the same pattern forms as `ignore`, read for files. A name or an
|
|
105
|
+
* extension glob covers a file by its own name, at any depth, and a directory
|
|
106
|
+
* glob (`dir/**`) covers what lies beneath that directory, and not a file
|
|
107
|
+
* named like it. Unlike `ignore`, a pattern that matches a directory's name
|
|
108
|
+
* covers nothing beneath it, since each file is covered by its own name:
|
|
109
|
+
* `["gate.json"]` holds every file named `gate.json`, and no other file
|
|
110
|
+
* beneath a directory of that name. A subtree is named with `dir/**`.
|
|
111
|
+
*
|
|
112
|
+
* It's the mount's boundary for content: no workspace path reads, stores,
|
|
113
|
+
* serves or writes back a file it doesn't cover, and no tool lists,
|
|
114
|
+
* matches or names one, beyond echoing a path it was given, which it may
|
|
115
|
+
* spell as disk does. A walk passes over one and counts it under
|
|
116
|
+
* `passedOver`, and passes over a link its names don't cover with the
|
|
117
|
+
* reason a mount without an include gives a link it doesn't enter, "a
|
|
118
|
+
* symlink, not walked", where the link leads to a directory, and wherever
|
|
119
|
+
* it leads on a mount that doesn't follow links. No pass decides a change
|
|
120
|
+
* the watcher reports there, and a materialize doesn't write it back even
|
|
121
|
+
* when the workspace's history holds it. A materialize that names a
|
|
122
|
+
* directory inside the mount counts each such entry beneath it under
|
|
123
|
+
* `passedOver`,
|
|
124
|
+
* with the reason and without its path, a deletion or conflict held there
|
|
125
|
+
* included; one of the whole mount takes none of them up. The file
|
|
126
|
+
* operations (read, write, edit, delete, and the module's binary and disk
|
|
127
|
+
* reads and writes) refuse a path it doesn't cover as outside the mount's
|
|
128
|
+
* include, a directory's included, and `resolveAbsolutePath` returns null
|
|
129
|
+
* for one; the mount's root is inside. Whether a name is taken isn't
|
|
130
|
+
* withheld: a refusal may show that something occupies a path the caller
|
|
131
|
+
* named. On a mount that follows links, a path is judged where it lands as
|
|
132
|
+
* well as where it's named, as disk spells it there: a covered path that
|
|
133
|
+
* reaches a file the include doesn't cover, through a link at the path or
|
|
134
|
+
* on its way, is refused as one that leaves the mount (the file operations
|
|
135
|
+
* refuse it before anything is stored), and a listing from where a link
|
|
136
|
+
* leads passes over such a file. A covered path whose landing realpath
|
|
137
|
+
* can't resolve, as for a loop or a directory this process can't search,
|
|
138
|
+
* is refused too, by every file operation, a delete included, since
|
|
139
|
+
* where it lands can't be judged.
|
|
140
|
+
*
|
|
141
|
+
* A sync, materialize, grep, glob or ls that names a path the include
|
|
142
|
+
* doesn't cover takes it as a directory, its scope, exactly where a listing
|
|
143
|
+
* names one: where disk has a directory reached from the mount's root
|
|
144
|
+
* through directories, with no link among them, or the workspace's history
|
|
145
|
+
* holds an entry beneath it that the include covers, and that a nested
|
|
146
|
+
* mount's include covers too where it lies in that mount's directory. A
|
|
147
|
+
* directory `ignore` covers is a scope too when it's named, though a
|
|
148
|
+
* listing passes over it. Each refuses any other path the include doesn't
|
|
149
|
+
* cover. A covered path is a file to a sync, materialize or grep when disk
|
|
150
|
+
* or history has a file there, and otherwise a directory; a glob takes its
|
|
151
|
+
* path as a directory. Beneath a directory, each passes over what the
|
|
152
|
+
* include doesn't cover, and a listing that isn't recursive names each
|
|
153
|
+
* directory directly beneath its path that disk has, and each that a
|
|
154
|
+
* covered entry in history implies, with only the files the include
|
|
155
|
+
* covers. A mount running direct has no history (`backend`), so there
|
|
156
|
+
* disk alone decides each of these. `ignore` still applies to what
|
|
157
|
+
* `include` covers.
|
|
158
|
+
*
|
|
159
|
+
* On a disk that folds names, the parse reads a path in disk's spelling,
|
|
160
|
+
* as the walk names what it lists, so a covered name whose file disk
|
|
161
|
+
* spells otherwise is outside the mount, and the include's refusal shows
|
|
162
|
+
* the path as given. A path that names one of the workspace's entries
|
|
163
|
+
* exactly, or does once its directories take disk's spelling, keeps the
|
|
164
|
+
* entry's spelling, as the parse gives it, and what lies past a link on
|
|
165
|
+
* the way keeps the caller's spelling, since the parse reads nothing past
|
|
166
|
+
* a link. Other answers name a path as the parse spells it, a name the
|
|
167
|
+
* include leaves out included, since how disk spells a name the caller
|
|
168
|
+
* gave is no content of that file. Where a
|
|
169
|
+
* followed path lands is judged as disk spells it there, and a path that
|
|
170
|
+
* meets no link where the parse names it.
|
|
171
|
+
* `resolveAbsolutePath`, which is synchronous, judges the include on the
|
|
172
|
+
* path as given and follows no link: on such a disk it returns the path to
|
|
173
|
+
* a covered name's file that disk spells otherwise, and null for a covered
|
|
174
|
+
* file named in another case.
|
|
175
|
+
*
|
|
176
|
+
* A path in a nested mount's directory is that mount's, whatever this
|
|
177
|
+
* include covers: every tool gives the answer that names the mount holding
|
|
178
|
+
* it and the path to use there. Through a link a mount follows, a place in
|
|
179
|
+
* that directory is named only where it's a directory, or a file that
|
|
180
|
+
* mount's own include covers with no file on its way, and is otherwise
|
|
181
|
+
* refused as leaving the mount. On a mount that doesn't follow links, a
|
|
182
|
+
* link on a path's way is refused, as on any such mount (followSymlinks).
|
|
183
|
+
* A nested mount's root is placed where disk has it at each start, and its
|
|
184
|
+
* directory is matched by spelling, so four cases fall outside this, as
|
|
185
|
+
* for any nested mount, and a fifth on a direct one: on a disk that folds
|
|
186
|
+
* names, a mount configured
|
|
187
|
+
* through a link that spells a directory otherwise than disk does isn't
|
|
188
|
+
* found nested, and this mount holds its files as its own; on such a disk,
|
|
189
|
+
* a path through a link that spells a nested mount's directory otherwise
|
|
190
|
+
* than that mount's configured path does, whether the link or the
|
|
191
|
+
* configured path is the one spelled otherwise than disk, isn't found to
|
|
192
|
+
* lead there, and this mount reads, lists, searches and writes there as
|
|
193
|
+
* its own, creating files too, though a walk from its root passes over the
|
|
194
|
+
* directory; on such a disk, a place in a nested mount's directory that a
|
|
195
|
+
* link does lead to is judged by that mount's include, and named, in the
|
|
196
|
+
* spelling the link's target gives, so a refusal can name a file disk
|
|
197
|
+
* spells outside that include, or leave a covered one unnamed; and a
|
|
198
|
+
* nested mount whose root moves while running, as `acceptRoot` takes,
|
|
199
|
+
* stays placed where it was until the next start; and where a direct
|
|
200
|
+
* mount's root is repointed between a read's parse and its open, a race
|
|
201
|
+
* left to whoever writes the disk, a mount nested in it by its
|
|
202
|
+
* directories alone, since its real root holds that root, can have the
|
|
203
|
+
* read serve a path in its directory.
|
|
204
|
+
*
|
|
205
|
+
* Text the host registers for a path (`registerGeneratedTextFile`) is
|
|
206
|
+
* served there whatever the include says, since it isn't one of the
|
|
207
|
+
* mount's files: it's matched by the path a spelling resolves to, before
|
|
208
|
+
* anything else checks the path, so every spelling that resolves to its
|
|
209
|
+
* registered path reads it, and none writes it. On a disk that folds names,
|
|
210
|
+
* a spelling in another case isn't its path, and reaches whatever file disk
|
|
211
|
+
* has there. The framework keeps its own files (`tool-results/`, `refs/`)
|
|
212
|
+
* only in a writable mount without an include, and what it kept in a mount
|
|
213
|
+
* before the mount had one is outside the mount once it has one, unless the
|
|
214
|
+
* include covers it.
|
|
215
|
+
*
|
|
216
|
+
* Left out, the mount holds everything under its path. Given, it's a list
|
|
217
|
+
* of at least one string, each a name, an `*.ext` glob or a `dir/**` glob,
|
|
218
|
+
* whose directory may be nested (`a/b/**`). The module refuses a pattern
|
|
219
|
+
* with a `/` that isn't such a glob, a `*` anywhere but a leading `*.` or
|
|
220
|
+
* that trailing `/**`, an empty, `.` or `..` segment, and, where `\` is the
|
|
221
|
+
* platform's separator, a `\`. Any other pattern is a file name, matched
|
|
222
|
+
* literally, so `[id].tsx` names the file of that name.
|
|
223
|
+
*/
|
|
224
|
+
include?: string[];
|
|
48
225
|
/**
|
|
49
226
|
* Whether to follow symlinks (default: false). Without it, no symlink on a
|
|
50
227
|
* path is followed: not one at the path itself, and not one among the
|
|
51
228
|
* directories on its way beneath the mount's root, wherever it leads. A path
|
|
52
229
|
* with a symlink among its directories is refused naming the link, and for
|
|
53
|
-
* a link inside the mount, its target
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
230
|
+
* a link inside the mount, its target where a tool could name it: a
|
|
231
|
+
* directory, or a file the include of the mount it lies in covers, where
|
|
232
|
+
* that mount has one. On a mount with an include, a link the include
|
|
233
|
+
* doesn't cover is outside the mount itself, and its refusal tells nothing
|
|
234
|
+
* of where it leads. A mount root that is itself a symlink is still the
|
|
235
|
+
* root. With it, a symlink on a path is followed while what it reaches
|
|
236
|
+
* stays inside the mount, which on a mount with an include means a
|
|
237
|
+
* directory or a file the include covers. Either way, a listing or a
|
|
238
|
+
* sync's walk descends
|
|
239
|
+
* into no symlinked directory beneath its scope; with it, a scope named
|
|
240
|
+
* through a link is listed from where the link leads.
|
|
57
241
|
*/
|
|
58
242
|
followSymlinks?: boolean;
|
|
59
243
|
/** Maximum file size in bytes (default: 5MB) */
|
|
@@ -148,6 +332,13 @@ export interface WorkspaceConfig {
|
|
|
148
332
|
export interface MountState {
|
|
149
333
|
/** The mount config */
|
|
150
334
|
config: MountConfig;
|
|
335
|
+
/**
|
|
336
|
+
* Whether the mount runs direct (`MountConfig.backend`), as the workspace
|
|
337
|
+
* decides when initStore gives the store and again at each start: a mount
|
|
338
|
+
* configured direct runs as 'chronicle' while the store holds changes
|
|
339
|
+
* there that disk lacks.
|
|
340
|
+
*/
|
|
341
|
+
direct: boolean;
|
|
151
342
|
/** Tree state ID in Chronicle */
|
|
152
343
|
treeStateId: string;
|
|
153
344
|
/** Branch-local intent (tombstones, store origin, conflicts) for this mount's paths */
|
|
@@ -257,6 +448,20 @@ export interface EditInput {
|
|
|
257
448
|
replaceAll?: boolean;
|
|
258
449
|
}
|
|
259
450
|
|
|
451
|
+
export interface EditManyInput {
|
|
452
|
+
/** The edits, each matched in its file as the call reads it, all in one mount's files. */
|
|
453
|
+
edits: Array<{
|
|
454
|
+
/** File path (mount-prefixed) */
|
|
455
|
+
path: string;
|
|
456
|
+
/** Exact text to replace */
|
|
457
|
+
oldString: string;
|
|
458
|
+
/** Text to replace it with */
|
|
459
|
+
newString: string;
|
|
460
|
+
/** How many times oldString occurs in the file (default: 1); every one is replaced. */
|
|
461
|
+
occurrences?: number;
|
|
462
|
+
}>;
|
|
463
|
+
}
|
|
464
|
+
|
|
260
465
|
export interface DeleteInput {
|
|
261
466
|
/** File path (mount-prefixed) */
|
|
262
467
|
path: string;
|
|
@@ -28,8 +28,9 @@ export interface WatcherEvents {
|
|
|
28
28
|
* identical to an empty directory in the recorded state.
|
|
29
29
|
*/
|
|
30
30
|
export interface WatcherLifecycle {
|
|
31
|
-
/** Fires when chokidar completes
|
|
32
|
-
*
|
|
31
|
+
/** Fires when chokidar completes an attach's initial scan, so again after a
|
|
32
|
+
* re-attach. An attach closed before its scan completes, by a re-attach or
|
|
33
|
+
* a stop, never fires it: chokidar drops its listeners at the close. */
|
|
33
34
|
onReady?: () => void;
|
|
34
35
|
/** Fires on any chokidar-reported error (ENOENT, EACCES, platform faults). */
|
|
35
36
|
onError?: (err: Error) => void;
|
package/src/operator-log.ts
CHANGED
|
@@ -118,35 +118,63 @@ export function capIds(ids: string[]): { ids: string[]; count: number; truncated
|
|
|
118
118
|
: { ids, count: ids.length };
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Facts every surgery marker receipt carries, whatever happened: the
|
|
123
|
+
* publication scope chosen (`none` unless the operator chose marks), how many
|
|
124
|
+
* removed addressable Discord messages the choice leaves unmarked (outside its
|
|
125
|
+
* scope or its authorized refs; whether the chosen ones are scheduled is the
|
|
126
|
+
* receipt's `status`), and how many authorized refs it did not remove (a
|
|
127
|
+
* delayed application whose anchor no longer covered them; their marks are
|
|
128
|
+
* never widened to anything else).
|
|
129
|
+
*/
|
|
130
|
+
export interface SurgeryMarkerFacts {
|
|
131
|
+
scope: 'none' | 'addressed' | 'all';
|
|
132
|
+
unmarked: number;
|
|
133
|
+
notRemoved: number;
|
|
134
|
+
}
|
|
135
|
+
|
|
121
136
|
/**
|
|
122
137
|
* What a live surgery did about Discord awareness marks, reported apart from
|
|
123
138
|
* the body change itself. A surgery that returns has applied its body change;
|
|
124
139
|
* this says only whether marks were scheduled:
|
|
125
140
|
*
|
|
126
|
-
* - `none` — no marks were
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* - `queued` —
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
141
|
+
* - `none` — no marks were requested (the default), or none of the removed
|
|
142
|
+
* messages fell within the chosen scope and authorized refs. It says
|
|
143
|
+
* nothing about whether Discord messages were removed: `unmarked` counts
|
|
144
|
+
* the addressable ones left unmarked, the surgery's `removedRefs` list
|
|
145
|
+
* every one, and the operator log's `discordRefs` counts them.
|
|
146
|
+
* - `queued` — one add request per mark is recorded, and delivered when its
|
|
147
|
+
* route is up: a pass starts at once unless the host is stopping, and a
|
|
148
|
+
* later one (a reconnect, a tools-list change or the next start) takes
|
|
149
|
+
* what remains. If a delivery pass fails, the requests stay recorded and
|
|
150
|
+
* the `discord-awareness-delivery` ops alert says so. The same alert names
|
|
151
|
+
* the marks a pass, or a start, gave up on: refused by Discord for good,
|
|
152
|
+
* or after three unconfirmed attempts. It is not a delivery claim: what
|
|
153
|
+
* Discord answers is kept in the awareness ledger.
|
|
137
154
|
* - `not-scheduled` — the body change landed, but recording the batch as
|
|
138
|
-
* active failed,
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* retirement. `batchId` names a retained batch whose scheduling outcome is
|
|
142
|
-
* unresolved: any later reconciliation or restart that can read it may
|
|
143
|
-
* promote and deliver it, and nothing here promises otherwise.
|
|
155
|
+
* active failed, or it was never recorded: none of its marks will be
|
|
156
|
+
* delivered. `error` says why, and whether the batch was retired or stays
|
|
157
|
+
* prepared for a start to retire.
|
|
144
158
|
*/
|
|
145
|
-
export type SurgeryMarkerReceipt =
|
|
159
|
+
export type SurgeryMarkerReceipt = SurgeryMarkerFacts & (
|
|
146
160
|
| { status: 'none'; queued: 0 }
|
|
147
161
|
| { status: 'queued'; queued: number; batchId: string }
|
|
148
162
|
| { status: 'not-scheduled'; queued: 0; error: string }
|
|
149
|
-
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
/** What a surgery would remove and which messages each marks scope covers. */
|
|
166
|
+
export interface SurgeryMarksPreview {
|
|
167
|
+
messagesRemoved: number;
|
|
168
|
+
/** Removed messages that carry a Discord address at all. */
|
|
169
|
+
addressable: number;
|
|
170
|
+
emoji: string;
|
|
171
|
+
scopes: Record<'addressed' | 'all', {
|
|
172
|
+
count: number;
|
|
173
|
+
channels: Array<{ channelId: string; count: number }>;
|
|
174
|
+
/** Pass back as `marks.refs` to bind the choice to exactly these. */
|
|
175
|
+
refs: Array<{ serverId: string; channelId: string; messageId: string }>;
|
|
176
|
+
}>;
|
|
177
|
+
}
|
|
150
178
|
|
|
151
179
|
/** Thrown by live surgery methods when a request cannot be honored. `code`
|
|
152
180
|
* lets surfaces distinguish "agent busy — quiesce first" from bad input. */
|