@north-light/crouter 0.3.262 → 0.3.269
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/dist/api/client.d.ts +5 -1
- package/dist/api/client.js +6 -0
- package/dist/api/dto/canvas.d.ts +53 -2
- package/dist/api/dto/health.d.ts +2 -0
- package/dist/api/dto/nodes.d.ts +6 -2
- package/dist/api/routes.d.ts +1 -0
- package/dist/api/routes.js +1 -0
- package/dist/builtin-memory/05-kinds/advisor/advice-contract.md +2 -2
- package/dist/builtin-memory/internal/memory-loading.md +3 -3
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +50 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +46 -6
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +10 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
- package/dist/clients/attach/input/controller.d.ts +4 -0
- package/dist/clients/attach/input/controller.js +8 -0
- package/dist/clients/attach/session/bindings.d.ts +3 -0
- package/dist/clients/attach/session/bindings.js +7 -0
- package/dist/clients/attach/session/keys.d.ts +2 -0
- package/dist/clients/attach/session/keys.js +3 -3
- package/dist/clients/attach/session/whip-achievements.d.ts +4 -0
- package/dist/clients/attach/session/whip-achievements.js +145 -0
- package/dist/clients/attach/slash/dispatch.js +5 -3
- package/dist/clients/attach/viewer.js +668 -667
- package/dist/commands/canvas-history/grep.js +3 -22
- package/dist/commands/canvas-history/read.js +5 -3
- package/dist/commands/canvas-history/search.js +3 -22
- package/dist/commands/canvas-history/shared.d.ts +8 -0
- package/dist/commands/canvas-history/shared.js +64 -1
- package/dist/commands/canvas-history/stats.d.ts +1 -0
- package/dist/commands/canvas-history/stats.js +68 -0
- package/dist/commands/canvas-history.js +4 -3
- package/dist/commands/memory/read.js +15 -38
- package/dist/commands/memory/shared.d.ts +1 -1
- package/dist/commands/memory/shared.js +1 -1
- package/dist/commands/node/create.js +2 -2
- package/dist/commands/sys/config.js +19 -2
- package/dist/commands/sys/context/admin/docs-panel.d.ts +3 -3
- package/dist/commands/sys/context/admin/model.d.ts +7 -2
- package/dist/commands/sys/context/admin/model.js +7 -1
- package/dist/commands/sys/context/admin/read-view.d.ts +5 -5
- package/dist/commands/sys/context/admin/read-view.js +9 -4
- package/dist/commands/sys/context/resolve.d.ts +32 -3
- package/dist/commands/sys/context/resolve.js +74 -25
- package/dist/commands/sys/panels/models-panel.d.ts +28 -5
- package/dist/commands/sys/panels/models-panel.js +560 -75
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +1 -1
- package/dist/core/__tests__/integration/revive.test.js +4 -2
- package/dist/core/__tests__/model-pin-durability.test.js +25 -1
- package/dist/core/__tests__/model-routes-config.test.d.ts +1 -0
- package/dist/core/__tests__/model-routes-config.test.js +142 -0
- package/dist/core/__tests__/on-read-nested-store.test.js +8 -0
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +264 -1
- package/dist/core/__tests__/relaunch-root.test.js +17 -0
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +21 -6
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +19 -2
- package/dist/core/broker-client/__tests__/transport-relay.test.js +3 -1
- package/dist/core/broker-client/transport-relay.js +5 -1
- package/dist/core/canvas/__tests__/history-transcript.test.d.ts +1 -0
- package/dist/core/canvas/__tests__/history-transcript.test.js +102 -0
- package/dist/core/canvas/browse/app.d.ts +1 -1
- package/dist/core/canvas/browse/app.js +13 -10
- package/dist/core/canvas/browse/model.js +16 -1
- package/dist/core/canvas/browse/render.d.ts +23 -3
- package/dist/core/canvas/browse/render.js +429 -64
- package/dist/core/canvas/canvas.js +12 -8
- package/dist/core/canvas/extensions.d.ts +1 -1
- package/dist/core/canvas/extensions.js +7 -1
- package/dist/core/canvas/history.d.ts +36 -1
- package/dist/core/canvas/history.js +328 -7
- package/dist/core/canvas/labels.d.ts +2 -2
- package/dist/core/canvas/migrations.js +32 -0
- package/dist/core/canvas/node-recap.d.ts +23 -0
- package/dist/core/canvas/node-recap.js +67 -0
- package/dist/core/canvas/render-source.d.ts +34 -2
- package/dist/core/canvas/render-source.js +83 -24
- package/dist/core/canvas/types.d.ts +9 -0
- package/dist/core/config.d.ts +19 -2
- package/dist/core/config.js +174 -51
- package/dist/core/keybindings/catalog.d.ts +2 -2
- package/dist/core/keybindings/catalog.js +11 -8
- package/dist/core/model-routes.js +11 -4
- package/dist/core/runtime/broker/auth-reload.js +4 -1
- package/dist/core/runtime/broker/fault-retry.js +7 -2
- package/dist/core/runtime/broker/frame-client.js +4 -0
- package/dist/core/runtime/broker/frame-dispatch.js +7 -0
- package/dist/core/runtime/broker/inbox.d.ts +12 -2
- package/dist/core/runtime/broker/inbox.js +68 -38
- package/dist/core/runtime/broker-protocol.d.ts +6 -0
- package/dist/core/runtime/broker.js +14 -0
- package/dist/core/runtime/canvas-extensions.d.ts +1 -0
- package/dist/core/runtime/canvas-extensions.js +2 -0
- package/dist/core/runtime/interactive-deliver.d.ts +8 -2
- package/dist/core/runtime/interactive-deliver.js +12 -3
- package/dist/core/runtime/launch-target.js +1 -1
- package/dist/core/runtime/launch.d.ts +12 -6
- package/dist/core/runtime/launch.js +19 -17
- package/dist/core/runtime/model-swap.d.ts +5 -4
- package/dist/core/runtime/model-swap.js +7 -5
- package/dist/core/runtime/promote.js +2 -1
- package/dist/core/runtime/reset.js +4 -2
- package/dist/core/runtime/revive.js +22 -0
- package/dist/core/runtime/spawn.d.ts +3 -3
- package/dist/core/runtime/spawn.js +20 -3
- package/dist/core/runtime/stamp/channel.d.ts +18 -0
- package/dist/core/runtime/stamp/channel.js +74 -0
- package/dist/core/runtime/stamp/protocol.d.ts +86 -0
- package/dist/core/runtime/stamp/protocol.js +113 -0
- package/dist/core/runtime/tmux-driver.d.ts +11 -1
- package/dist/core/runtime/tmux-driver.js +27 -11
- package/dist/core/self-update.js +2 -5
- package/dist/core/substrate/listings.d.ts +1 -1
- package/dist/core/substrate/listings.js +6 -2
- package/dist/core/substrate/on-read.d.ts +61 -5
- package/dist/core/substrate/on-read.js +129 -22
- package/dist/core/substrate/render.d.ts +3 -2
- package/dist/core/substrate/render.js +133 -38
- package/dist/core/tui/draw.d.ts +1 -0
- package/dist/core/tui/draw.js +5 -1
- package/dist/core/tui/markdown.d.ts +17 -0
- package/dist/core/tui/markdown.js +407 -0
- package/dist/core/user-settings.d.ts +4 -0
- package/dist/core/user-settings.js +1 -0
- package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -0
- package/dist/daemon/api/__tests__/seam/api-server.test.js +34 -0
- package/dist/daemon/api/bridge.d.ts +3 -2
- package/dist/daemon/api/bridge.js +34 -9
- package/dist/daemon/api/handlers/canvas.js +80 -18
- package/dist/daemon/api/handlers/health.js +17 -12
- package/dist/daemon/api/handlers/messages.js +12 -1
- package/dist/daemon/api/handlers/nodes.js +10 -3
- package/dist/daemon/api/map.js +2 -0
- package/dist/daemon/messaging/node-message.js +15 -1
- package/dist/daemon/reconcilers/broker-supervision.js +26 -9
- package/dist/daemon/reconcilers/live-obligation.d.ts +8 -1
- package/dist/daemon/reconcilers/live-obligation.js +17 -0
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +2 -2
- package/dist/pi-extensions/canvas-inbox-watcher.js +27 -2
- package/dist/pi-extensions/canvas-recap.js +4 -0
- package/dist/pi-extensions/canvas-stamp.d.ts +14 -0
- package/dist/pi-extensions/canvas-stamp.js +77 -0
- package/dist/pi-extensions/canvas-stophook.js +3 -0
- package/dist/shared/__tests__/env-boundary.test.js +4 -2
- package/dist/shared/crtr-version.d.ts +2 -0
- package/dist/shared/crtr-version.js +18 -0
- package/dist/shared/env.d.ts +10 -0
- package/dist/shared/env.js +19 -4
- package/dist/types.d.ts +14 -2
- package/dist/types.js +4 -0
- package/package.json +1 -1
- package/runtime.lock.json +2 -2
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { resolve as resolvePath } from 'node:path';
|
|
5
5
|
import { realpathOrSelf } from '../../../../core/fs-utils.js';
|
|
6
6
|
import { planDelivery, } from '../../../../core/substrate/plan.js';
|
|
7
|
+
import { assembleEventAccounting, effectivePlan, } from '../resolve.js';
|
|
7
8
|
import { RUNGS, SURFACE_EVENTS, previewLine, rungRank, } from '../../../../core/substrate/schema.js';
|
|
8
9
|
import { scopeForCwd, profileNameFor } from '../../../../core/substrate/subject-fields.js';
|
|
9
10
|
import { resolveMemoryDocForTarget } from '../../../../core/memory-resolver.js';
|
|
@@ -71,7 +72,12 @@ export class PlanSet {
|
|
|
71
72
|
const held = this.plans.get(event);
|
|
72
73
|
if (held !== undefined)
|
|
73
74
|
return held;
|
|
74
|
-
const
|
|
75
|
+
const subject = subjectOf(this.snapshot);
|
|
76
|
+
const target = targetOf(this.snapshot);
|
|
77
|
+
const payload = this.payload(event);
|
|
78
|
+
const direct = planDelivery(subject, target, event, payload);
|
|
79
|
+
const rendered = assembleEventAccounting({ subject, target, nodeMissing: false }, event, payload);
|
|
80
|
+
const computed = effectivePlan(direct, rendered.accounting.deliveries, payload);
|
|
75
81
|
this.plans.set(event, computed);
|
|
76
82
|
return computed;
|
|
77
83
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Rung, type SurfaceEvent } from '../../../../core/substrate/schema.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { EffectiveDeliveryRecord } from '../resolve.js';
|
|
3
3
|
import type { NodeConfigSubject } from '../../../../core/substrate/subject-fields.js';
|
|
4
4
|
/** The profile project entry whose `memory` rung ceilings this document's
|
|
5
5
|
* store, or null when no project governs it. */
|
|
@@ -11,7 +11,7 @@ export interface CapOwner {
|
|
|
11
11
|
* the sibling events' records, and the two facts the shell resolves. */
|
|
12
12
|
export interface DossierContext {
|
|
13
13
|
event: SurfaceEvent;
|
|
14
|
-
records: Map<SurfaceEvent,
|
|
14
|
+
records: Map<SurfaceEvent, EffectiveDeliveryRecord>;
|
|
15
15
|
capOwner: CapOwner | null;
|
|
16
16
|
readOnly: boolean;
|
|
17
17
|
/** The configuration every record here was planned against — what a failed
|
|
@@ -20,12 +20,12 @@ export interface DossierContext {
|
|
|
20
20
|
}
|
|
21
21
|
/** The resting card, and — when `bodyOpen` — the document's own text beneath
|
|
22
22
|
* it in place of the affordance line that names it. */
|
|
23
|
-
export declare function renderDossierRead(record:
|
|
23
|
+
export declare function renderDossierRead(record: EffectiveDeliveryRecord, context: DossierContext, width: number, bodyOpen: boolean): string[];
|
|
24
24
|
/** Identity and routing — what the edit face keeps overhead of its field list,
|
|
25
25
|
* because they are the context a field is being edited against. */
|
|
26
|
-
export declare function renderDossierHeader(record:
|
|
26
|
+
export declare function renderDossierHeader(record: EffectiveDeliveryRecord, context: DossierContext, width: number): string[];
|
|
27
27
|
/** Does it load here, what does it cost, and — only when there is one — what
|
|
28
28
|
* interfered. The three questions the old verdict, cost table and event grid
|
|
29
29
|
* each answered a piece of. */
|
|
30
|
-
export declare function renderDossierDelivery(record:
|
|
30
|
+
export declare function renderDossierDelivery(record: EffectiveDeliveryRecord, context: DossierContext, width: number): string[];
|
|
31
31
|
export declare function bodyLineCount(body: string): number;
|
|
@@ -25,11 +25,13 @@ const INDENT = ' ';
|
|
|
25
25
|
export function renderDossierRead(record, context, width, bodyOpen) {
|
|
26
26
|
const inner = Math.max(1, width - INDENT.length);
|
|
27
27
|
const out = renderDossierHeader(record, context, width);
|
|
28
|
-
if (record.doc.shortForm.trim() !== '') {
|
|
29
|
-
out.push('');
|
|
30
|
-
out.push(...indent(wrapped(record.doc.shortForm, inner)));
|
|
31
|
-
}
|
|
32
28
|
out.push(...renderDossierDelivery(record, context, width));
|
|
29
|
+
// The gist sits against the body it summarizes: last of the card, directly
|
|
30
|
+
// above the affordance that opens the text it stands in for.
|
|
31
|
+
const gist = record.doc.shortForm.trim();
|
|
32
|
+
if (gist !== '') {
|
|
33
|
+
out.push('', theme.fg('dim', `${INDENT}SHORT FORM`), ...indent(wrapped(gist, inner)));
|
|
34
|
+
}
|
|
33
35
|
const lines = bodyLineCount(record.doc.body);
|
|
34
36
|
if (bodyOpen) {
|
|
35
37
|
out.push('');
|
|
@@ -139,6 +141,9 @@ export function renderDossierDelivery(record, context, width) {
|
|
|
139
141
|
? `capped to ${record.cappedRung} by a profile ceiling on this store`
|
|
140
142
|
: `capped to ${record.cappedRung} by the ${context.capOwner.memory} ceiling on ${context.capOwner.path}`);
|
|
141
143
|
}
|
|
144
|
+
if (record.deliveryCause !== undefined) {
|
|
145
|
+
out.push(...dim(record.deliveryCause, width));
|
|
146
|
+
}
|
|
142
147
|
if (record.shadowedBy !== null) {
|
|
143
148
|
out.push(...indent(wrapped(`shadowed by the ${record.shadowedBy.scope} copy at ${record.shadowedBy.path}`, inner)).map((line) => theme.fg('muted', line)));
|
|
144
149
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { type MemoryTarget } from '../../../core/memory-resolver.js';
|
|
2
|
-
import { type DeliveryPayload, type DeliveryRecord, type GateOutcome } from '../../../core/substrate/plan.js';
|
|
1
|
+
import { type MemoryDoc, type MemoryTarget } from '../../../core/memory-resolver.js';
|
|
2
|
+
import { type DeliveryPayload, type DeliveryPlan, type DeliveryRecord, type GateOutcome } from '../../../core/substrate/plan.js';
|
|
3
3
|
import { type GateClause } from '../../../core/substrate/gate-explain.js';
|
|
4
|
+
import { deliveryAccounting } from '../../../core/substrate/on-read.js';
|
|
4
5
|
import { type Rung, type SurfaceEntry, type SurfaceEvent } from '../../../core/substrate/schema.js';
|
|
5
6
|
import { type NodeConfigSubject } from '../../../core/substrate/subject-fields.js';
|
|
6
7
|
export declare const resolveLeaf: import("../../../core/command.js").LeafDef;
|
|
@@ -26,6 +27,10 @@ export interface PayloadFlags {
|
|
|
26
27
|
export declare function payloadFor(event: SurfaceEvent, flags: PayloadFlags, target: MemoryTarget): DeliveryPayload;
|
|
27
28
|
export declare function subjectSummary(subject: NodeConfigSubject): Record<string, unknown>;
|
|
28
29
|
export declare function optionalString(value: unknown): string | null;
|
|
30
|
+
export interface EffectiveDeliveryRecord extends DeliveryRecord {
|
|
31
|
+
/** Present when the renderer raised this doc beyond its direct event plan. */
|
|
32
|
+
deliveryCause?: string;
|
|
33
|
+
}
|
|
29
34
|
export interface DocRow {
|
|
30
35
|
name: string;
|
|
31
36
|
kind: string;
|
|
@@ -40,13 +45,24 @@ export interface DocRow {
|
|
|
40
45
|
doc_gate: string;
|
|
41
46
|
entry_gate: string | null;
|
|
42
47
|
matched_entry: string | null;
|
|
48
|
+
delivery_cause?: string;
|
|
43
49
|
excluded?: string;
|
|
44
50
|
}
|
|
51
|
+
/** Overlay the production renderer's actual document deliveries onto direct
|
|
52
|
+
* planner records. The plan still supplies gates, caps, and exclusion detail;
|
|
53
|
+
* only an attachment that genuinely rendered may raise its final rung. */
|
|
54
|
+
export declare function effectivePlan(plan: DeliveryPlan, deliveries: ReadonlyMap<string, {
|
|
55
|
+
rung: Rung;
|
|
56
|
+
cause?: string;
|
|
57
|
+
source?: MemoryDoc;
|
|
58
|
+
}>, payload?: DeliveryPayload): DeliveryPlan & {
|
|
59
|
+
docs: EffectiveDeliveryRecord[];
|
|
60
|
+
};
|
|
45
61
|
/** A document delivers when it won its canonical name AND resolved to a rung
|
|
46
62
|
* above the no-delivery floor — boot keeps rung-`none` winners in the plan so
|
|
47
63
|
* the catalog can still count them. */
|
|
48
64
|
export declare function delivers(record: DeliveryRecord): boolean;
|
|
49
|
-
export declare function docRow(record:
|
|
65
|
+
export declare function docRow(record: EffectiveDeliveryRecord, includeAll: boolean, subject: NodeConfigSubject | null): DocRow;
|
|
50
66
|
/** A gate verdict as one cell: `pass`, or `fail:` plus the clauses that failed
|
|
51
67
|
* — the planner's generic sentence only when the explainer cannot decompose
|
|
52
68
|
* the predicate. */
|
|
@@ -55,5 +71,18 @@ export declare function entryText(entry: SurfaceEntry | null): string | null;
|
|
|
55
71
|
/** Why a considered document delivers nothing, in the order the planner applies
|
|
56
72
|
* its checks — the first failing one is the answer an engineer acts on. */
|
|
57
73
|
export declare function exclusionReason(record: DeliveryRecord, subject: NodeConfigSubject | null): string;
|
|
74
|
+
/** Every renderer resolves its corpus from the AMBIENT process (cwd plus the
|
|
75
|
+
* two env seams), not from a target argument, so a snapshot dialed away from
|
|
76
|
+
* this process is only honored by standing in its place for the call. The
|
|
77
|
+
* session parse cache is cleared on both sides so neither the emulated corpus
|
|
78
|
+
* nor the real one is served from the other's scan. */
|
|
79
|
+
export interface AccountedEventRender {
|
|
80
|
+
assembled: string;
|
|
81
|
+
accounting: ReturnType<typeof deliveryAccounting>;
|
|
82
|
+
}
|
|
83
|
+
/** Run the production renderer once and retain the structured document
|
|
84
|
+
* deliveries it recorded. Context diagnostics and the admin viewer consume
|
|
85
|
+
* this result rather than reconstructing attachment/companion fixpoints. */
|
|
86
|
+
export declare function assembleEventAccounting(snapshot: ContextSnapshot, event: SurfaceEvent, payload: DeliveryPayload): AccountedEventRender;
|
|
58
87
|
export declare function describeSubject(subject: Record<string, unknown>): string;
|
|
59
88
|
export declare function cell(v: unknown): string;
|
|
@@ -19,9 +19,9 @@ import { planDelivery, } from '../../../core/substrate/plan.js';
|
|
|
19
19
|
import { explainRecordGate, formatClause } from '../../../core/substrate/gate-explain.js';
|
|
20
20
|
import { emptyContextExposureState, exposureTarget } from '../../../core/substrate/injected-store.js';
|
|
21
21
|
import { renderPreferencesForSubject, renderKnowledgeForSubject } from '../../../core/substrate/render.js';
|
|
22
|
-
import { memoryReadDocBlocks, renderOnCommandDocsForSubject, renderOnReadDocsForSubject, renderPreCommandDocsForSubject, renderWorkspaceOpenDocsForSubject, } from '../../../core/substrate/on-read.js';
|
|
22
|
+
import { deliveryAccounting, memoryReadDocBlocks, renderOnCommandDocsForSubject, renderOnReadDocsForSubject, renderPreCommandDocsForSubject, renderWorkspaceOpenDocsForSubject, } from '../../../core/substrate/on-read.js';
|
|
23
23
|
import { clearSessionCache } from '../../../core/substrate/session-cache.js';
|
|
24
|
-
import { rungAtLeast, SURFACE_EVENTS, } from '../../../core/substrate/schema.js';
|
|
24
|
+
import { parseSubstrateDoc, rungAtLeast, SURFACE_EVENTS, } from '../../../core/substrate/schema.js';
|
|
25
25
|
import { scopeForCwd, profileNameFor } from '../../../core/substrate/subject-fields.js';
|
|
26
26
|
import { resetScopeCache } from '../../../core/scope.js';
|
|
27
27
|
import { getDefaultProfileId } from '../../../core/profiles/default-binding.js';
|
|
@@ -52,7 +52,7 @@ export const resolveLeaf = defineLeaf({
|
|
|
52
52
|
{ name: 'event', type: 'string', required: false, constraint: 'The resolved event. Absent with --all-events, where every entry in `plans` carries its own.' },
|
|
53
53
|
{ name: 'subject', type: 'object', required: true, constraint: 'The configuration snapshot used: kind, mode, lifecycle, hasManager, profile, scope.' },
|
|
54
54
|
{ name: 'target', type: 'object', required: true, constraint: 'Store resolution inputs: cwd, profileId, nodeId.' },
|
|
55
|
-
{ name: 'docs', type: 'array', required: false, constraint: 'One entry per document, at `docs`/`all` granularity: name, kind, scope, store_path, authored_rung, project_memory_cap, capped_rung, final_rung, winner, shadowed_by, doc_gate, entry_gate, matched_entry, and excluded when --all includes a non-delivering document.' },
|
|
55
|
+
{ name: 'docs', type: 'array', required: false, constraint: 'One entry per document, at `docs`/`all` granularity: name, kind, scope, store_path, authored_rung, project_memory_cap, capped_rung, final_rung, winner, shadowed_by, doc_gate, entry_gate, matched_entry, delivery_cause when the renderer raised it through a content attachment, and excluded when --all includes a non-delivering document.' },
|
|
56
56
|
{ name: 'counts', type: 'object', required: false, constraint: 'At `summary` granularity: {considered, delivered: {content, preview, name}, delivered_total, excluded: {<reason>: count}}.' },
|
|
57
57
|
{ name: 'all_ignored', type: 'boolean', required: false, constraint: 'Present only when --all is supplied with --granularity assembled; true means assembled text is unchanged because --all applies only to docs granularity.' },
|
|
58
58
|
{ name: 'assembled', type: 'string', required: false, constraint: 'At `assembled` granularity: the exact text the node would receive for this event.' },
|
|
@@ -188,15 +188,59 @@ async function fetchSubjectOrNull(nodeId) {
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
function planSection(snapshot, event, payload, granularity, includeAll) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const plan = planDelivery(snapshot.subject, snapshot.target, event, payload);
|
|
191
|
+
const rendered = assembleEventAccounting(snapshot, event, payload);
|
|
192
|
+
if (granularity === 'assembled')
|
|
193
|
+
return { event, assembled: rendered.assembled };
|
|
194
|
+
const plan = effectivePlan(planDelivery(snapshot.subject, snapshot.target, event, payload), rendered.accounting.deliveries, payload);
|
|
195
195
|
if (granularity === 'summary')
|
|
196
196
|
return { event, counts: countsOf(plan) };
|
|
197
197
|
const docs = plan.docs.filter((r) => includeAll || delivers(r)).map((r) => docRow(r, includeAll, plan.subject));
|
|
198
198
|
return { event, docs };
|
|
199
199
|
}
|
|
200
|
+
/** Overlay the production renderer's actual document deliveries onto direct
|
|
201
|
+
* planner records. The plan still supplies gates, caps, and exclusion detail;
|
|
202
|
+
* only an attachment that genuinely rendered may raise its final rung. */
|
|
203
|
+
export function effectivePlan(plan, deliveries, payload = {}) {
|
|
204
|
+
const seen = new Set();
|
|
205
|
+
const docs = plan.docs.map((record) => {
|
|
206
|
+
seen.add(realpathOrSelf(record.doc.path));
|
|
207
|
+
const delivered = deliveries.get(realpathOrSelf(record.doc.path));
|
|
208
|
+
if (delivered === undefined || !rungAtLeast(delivered.rung, record.finalRung))
|
|
209
|
+
return record;
|
|
210
|
+
const raised = delivered.rung !== record.finalRung;
|
|
211
|
+
return {
|
|
212
|
+
...record,
|
|
213
|
+
// A companion has its own memory-read winner set. If it is shadowed or
|
|
214
|
+
// silent in the outer event plan but genuinely rendered through that
|
|
215
|
+
// attachment, the rendered delivery is the truth this view reports.
|
|
216
|
+
...(raised ? { winner: true, shadowedBy: null } : {}),
|
|
217
|
+
finalRung: delivered.rung,
|
|
218
|
+
...(raised && delivered.cause !== undefined ? { deliveryCause: delivered.cause } : {}),
|
|
219
|
+
};
|
|
220
|
+
});
|
|
221
|
+
for (const delivered of deliveries.values()) {
|
|
222
|
+
if (delivered.source === undefined || seen.has(realpathOrSelf(delivered.source.path)))
|
|
223
|
+
continue;
|
|
224
|
+
const doc = parseSubstrateDoc(delivered.source);
|
|
225
|
+
if (doc === null)
|
|
226
|
+
continue;
|
|
227
|
+
// Workspace-open deliberately plans only project stores, while its real
|
|
228
|
+
// listing/companion attachments answer from the full target view. Plan this
|
|
229
|
+
// one rendered source solely to retain normal dossier metadata, then make
|
|
230
|
+
// its renderer-recorded rung and cause authoritative.
|
|
231
|
+
const record = planDelivery(plan.subject, plan.target, plan.event, payload, [{ doc, source: delivered.source }]).docs[0];
|
|
232
|
+
if (record === undefined)
|
|
233
|
+
continue;
|
|
234
|
+
docs.push({
|
|
235
|
+
...record,
|
|
236
|
+
winner: true,
|
|
237
|
+
shadowedBy: null,
|
|
238
|
+
finalRung: delivered.rung,
|
|
239
|
+
...(delivered.cause === undefined ? {} : { deliveryCause: delivered.cause }),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
return { ...plan, docs };
|
|
243
|
+
}
|
|
200
244
|
/** A document delivers when it won its canonical name AND resolved to a rung
|
|
201
245
|
* above the no-delivery floor — boot keeps rung-`none` winners in the plan so
|
|
202
246
|
* the catalog can still count them. */
|
|
@@ -218,6 +262,7 @@ export function docRow(record, includeAll, subject) {
|
|
|
218
262
|
doc_gate: gateText(record.docGate, explainRecordGate(record, 'doc', subject)),
|
|
219
263
|
entry_gate: record.entryGate === null ? null : gateText(record.entryGate, explainRecordGate(record, 'entry', subject)),
|
|
220
264
|
matched_entry: entryText(record.matchedEntry),
|
|
265
|
+
...(record.deliveryCause === undefined ? {} : { delivery_cause: record.deliveryCause }),
|
|
221
266
|
};
|
|
222
267
|
if (includeAll && !delivers(record))
|
|
223
268
|
row.excluded = exclusionReason(record, subject);
|
|
@@ -294,26 +339,23 @@ function exclusionBucket(record) {
|
|
|
294
339
|
}
|
|
295
340
|
return record.cappedRung === 'none' ? 'capped' : 'rung_none';
|
|
296
341
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
* this process is only honored by standing in its place for the call. The
|
|
302
|
-
* session parse cache is cleared on both sides so neither the emulated corpus
|
|
303
|
-
* nor the real one is served from the other's scan. */
|
|
304
|
-
function assembleEvent(snapshot, event, payload) {
|
|
342
|
+
/** Run the production renderer once and retain the structured document
|
|
343
|
+
* deliveries it recorded. Context diagnostics and the admin viewer consume
|
|
344
|
+
* this result rather than reconstructing attachment/companion fixpoints. */
|
|
345
|
+
export function assembleEventAccounting(snapshot, event, payload) {
|
|
305
346
|
const restore = {
|
|
306
347
|
cwd: process.cwd(),
|
|
307
348
|
profileId: envProfileId(),
|
|
308
349
|
nodeId: envNodeId(),
|
|
309
350
|
};
|
|
351
|
+
const accounting = deliveryAccounting();
|
|
310
352
|
clearSessionCache();
|
|
311
353
|
resetScopeCache();
|
|
312
354
|
try {
|
|
313
355
|
process.chdir(snapshot.target.cwd);
|
|
314
356
|
setEnv('CRTR_PROFILE_ID', snapshot.target.profileId ?? undefined);
|
|
315
357
|
setEnv('CRTR_NODE_ID', snapshot.target.nodeId ?? undefined);
|
|
316
|
-
return renderEvent(snapshot, event, payload);
|
|
358
|
+
return { assembled: renderEvent(snapshot, event, payload, accounting), accounting };
|
|
317
359
|
}
|
|
318
360
|
finally {
|
|
319
361
|
process.chdir(restore.cwd);
|
|
@@ -329,29 +371,34 @@ function setEnv(name, value) {
|
|
|
329
371
|
else
|
|
330
372
|
process.env[name] = value;
|
|
331
373
|
}
|
|
332
|
-
function renderEvent(snapshot, event, payload) {
|
|
374
|
+
function renderEvent(snapshot, event, payload, accounting) {
|
|
333
375
|
const { subject, target } = snapshot;
|
|
334
376
|
switch (event) {
|
|
335
377
|
case 'boot': {
|
|
336
|
-
const { block } = renderPreferencesForSubject(subject);
|
|
337
|
-
const knowledge = target.nodeId === null ? '' : renderKnowledgeForSubject(subject, target.nodeId);
|
|
378
|
+
const { block } = renderPreferencesForSubject(subject, undefined, accounting);
|
|
379
|
+
const knowledge = target.nodeId === null ? '' : renderKnowledgeForSubject(subject, target.nodeId, undefined, accounting);
|
|
338
380
|
return knowledge === '' ? block : `${block}\n\n${knowledge}`;
|
|
339
381
|
}
|
|
340
382
|
case 'workspace-open':
|
|
341
|
-
return renderWorkspaceOpenDocsForSubject(subject, target.cwd, target.profileId);
|
|
383
|
+
return renderWorkspaceOpenDocsForSubject(subject, target.cwd, target.profileId, undefined, accounting);
|
|
342
384
|
case 'read':
|
|
343
|
-
return payload.absoluteFile === undefined ? '' : renderOnReadDocsForSubject(subject, payload.absoluteFile);
|
|
385
|
+
return payload.absoluteFile === undefined ? '' : renderOnReadDocsForSubject(subject, payload.absoluteFile, undefined, accounting);
|
|
344
386
|
case 'memory-read': {
|
|
345
387
|
const name = payload.resolvedCanonicalName;
|
|
346
388
|
if (name === undefined)
|
|
347
389
|
return '';
|
|
348
|
-
const blocks = memoryReadDocBlocks(
|
|
390
|
+
const blocks = memoryReadDocBlocks(payload.resolvedDocPath ?? '', name, {
|
|
391
|
+
subject,
|
|
392
|
+
target: exposureTarget(emptyContextExposureState(), 'transcript'),
|
|
393
|
+
listings: 'blocks',
|
|
394
|
+
accounting,
|
|
395
|
+
});
|
|
349
396
|
return blocks.length === 0 ? '' : `<auto-loaded-context>\n${blocks.join('\n')}\n</auto-loaded-context>`;
|
|
350
397
|
}
|
|
351
398
|
case 'command':
|
|
352
|
-
return payload.command === undefined ? '' : renderOnCommandDocsForSubject(subject, payload.command);
|
|
399
|
+
return payload.command === undefined ? '' : renderOnCommandDocsForSubject(subject, payload.command, undefined, accounting);
|
|
353
400
|
case 'pre-command':
|
|
354
|
-
return payload.command === undefined ? '' : renderPreCommandDocsForSubject(subject, payload.command);
|
|
401
|
+
return payload.command === undefined ? '' : renderPreCommandDocsForSubject(subject, payload.command, undefined, accounting);
|
|
355
402
|
}
|
|
356
403
|
}
|
|
357
404
|
/** The read document never delivers to itself, so the plan needs its physical
|
|
@@ -403,7 +450,8 @@ function renderSection(section) {
|
|
|
403
450
|
if (docs.length === 0)
|
|
404
451
|
return 'No document delivers for this event.';
|
|
405
452
|
const showExcluded = docs.some((d) => d.excluded !== undefined);
|
|
406
|
-
const
|
|
453
|
+
const showCause = docs.some((d) => d.delivery_cause !== undefined);
|
|
454
|
+
const cols = ['document', 'scope', 'kind', 'authored', 'cap', 'final', 'matched', 'gate', ...(showCause ? ['cause'] : []), ...(showExcluded ? ['excluded'] : [])];
|
|
407
455
|
const rows = docs.map((d) => [
|
|
408
456
|
d.name,
|
|
409
457
|
d.scope,
|
|
@@ -413,6 +461,7 @@ function renderSection(section) {
|
|
|
413
461
|
d.final_rung,
|
|
414
462
|
d.matched_entry ?? '—',
|
|
415
463
|
d.doc_gate,
|
|
464
|
+
...(showCause ? [d.delivery_cause ?? ''] : []),
|
|
416
465
|
...(showExcluded ? [d.excluded ?? ''] : []),
|
|
417
466
|
]);
|
|
418
467
|
return [
|
|
@@ -10,6 +10,8 @@ export declare class ModelsPanel implements SetupPanel {
|
|
|
10
10
|
private readonly label;
|
|
11
11
|
private mode;
|
|
12
12
|
private ladders;
|
|
13
|
+
private modelRoutes;
|
|
14
|
+
private legacyModelRoutes;
|
|
13
15
|
private kinds;
|
|
14
16
|
/** The ladder providers this panel offers — only columns whose runtime
|
|
15
17
|
* provider is signed in (all of them when nobody is, so config stays
|
|
@@ -27,8 +29,11 @@ export declare class ModelsPanel implements SetupPanel {
|
|
|
27
29
|
private modelSelector;
|
|
28
30
|
private thinkingSelector;
|
|
29
31
|
private pending;
|
|
30
|
-
private
|
|
31
|
-
private
|
|
32
|
+
private choice;
|
|
33
|
+
private choiceIndex;
|
|
34
|
+
private routeForm;
|
|
35
|
+
private readonly routeInput;
|
|
36
|
+
private pendingRouteCell;
|
|
32
37
|
onChange?: () => void;
|
|
33
38
|
constructor(tui: TUI, runtime: ModelRuntime, registry: ModelRegistry, matches: (id: BindingId, data: string) => boolean, label: (id: BindingId) => string);
|
|
34
39
|
/** Same signed-in rule as the broker's Alt+M cycle: pool occupancy for a
|
|
@@ -38,6 +43,8 @@ export declare class ModelsPanel implements SetupPanel {
|
|
|
38
43
|
private cycleTarget;
|
|
39
44
|
private shadowingPath;
|
|
40
45
|
private savedButShadowed;
|
|
46
|
+
private routeIds;
|
|
47
|
+
private routeFamilies;
|
|
41
48
|
private buildRows;
|
|
42
49
|
private reload;
|
|
43
50
|
/** Re-read config and auth state — called when the Models tab is entered so
|
|
@@ -50,12 +57,26 @@ export declare class ModelsPanel implements SetupPanel {
|
|
|
50
57
|
private clampColumn;
|
|
51
58
|
handleInput(data: string): boolean;
|
|
52
59
|
private activateCell;
|
|
53
|
-
|
|
60
|
+
private portableSelection;
|
|
61
|
+
private familyLabel;
|
|
62
|
+
private familyOptions;
|
|
63
|
+
/** Snapshot of the mode's current family+strength. For orchestrator this
|
|
54
64
|
* falls back to the base `model` when no explicit override exists, so the
|
|
55
65
|
* inherited pair is what an edit preserves. */
|
|
56
66
|
private kindSelection;
|
|
57
67
|
private openDimensionPicker;
|
|
58
|
-
private
|
|
68
|
+
private writeKindSelection;
|
|
69
|
+
private commitChoice;
|
|
70
|
+
private openRouteForm;
|
|
71
|
+
private closeRouteForm;
|
|
72
|
+
private activateRouteField;
|
|
73
|
+
private setRouteProvider;
|
|
74
|
+
private openRouteCell;
|
|
75
|
+
private onRouteModelPicked;
|
|
76
|
+
private saveRoute;
|
|
77
|
+
private declaringPath;
|
|
78
|
+
private deleteRoute;
|
|
79
|
+
private showModelSelector;
|
|
59
80
|
private openModelPicker;
|
|
60
81
|
private onModelPicked;
|
|
61
82
|
private onThinkingPicked;
|
|
@@ -66,7 +87,9 @@ export declare class ModelsPanel implements SetupPanel {
|
|
|
66
87
|
private targetKindOverride;
|
|
67
88
|
footerHint(): string;
|
|
68
89
|
/** Body lines only — the caller frames and windows them. */
|
|
69
|
-
private
|
|
90
|
+
private renderChoicePicker;
|
|
91
|
+
private renderRouteForm;
|
|
92
|
+
private renderRouteDelete;
|
|
70
93
|
/** Fits the panel body into `budget` rows. The wizard draws header/tabs above
|
|
71
94
|
* and a footer below, so a body taller than its budget pushes the tab strip
|
|
72
95
|
* off the top of the terminal — the panel must window itself instead. Chrome
|