@north-light/crouter 0.3.164 → 0.3.166
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/build-root.d.ts +6 -6
- package/dist/build-root.js +12 -13
- package/dist/builtin-memory/00-runtime-base.md +3 -4
- package/dist/builtin-memory/01-spine/01-no-manager.md +1 -1
- package/dist/builtin-memory/02-lifecycle/00-terminal.md +2 -0
- package/dist/builtin-memory/04-orchestration-kernel.md +16 -18
- package/dist/builtin-memory/05-kinds/advisor/00-base.md +0 -2
- package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +3 -9
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -3
- package/dist/builtin-memory/05-kinds/developer/01-orchestrator.md +2 -10
- package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
- package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +0 -2
- package/dist/builtin-memory/05-kinds/general/00-base.md +3 -5
- package/dist/builtin-memory/05-kinds/general/01-orchestrator.md +0 -4
- package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -3
- package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +12 -0
- package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +0 -2
- package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +0 -2
- package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +0 -2
- package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +0 -2
- package/dist/builtin-memory/05-kinds/review/00-base.md +0 -2
- package/dist/builtin-memory/05-kinds/review/01-orchestrator.md +1 -3
- package/dist/builtin-memory/05-kinds/spec/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +2 -4
- package/dist/builtin-memory/05-kinds/spec/requirements.md +1 -1
- package/dist/builtin-memory/advisor/council.md +40 -0
- package/dist/builtin-memory/design.md +8 -11
- package/dist/builtin-memory/development.md +6 -9
- package/dist/builtin-memory/internal/INDEX.md +4 -5
- package/dist/builtin-memory/internal/agent-shaping.md +5 -7
- package/dist/builtin-memory/internal/examples/imessage-assistant.md +3 -3
- package/dist/builtin-memory/internal/marketplaces.md +13 -14
- package/dist/builtin-memory/internal/nodes-and-canvas.md +4 -4
- package/dist/builtin-memory/internal/plugins.md +61 -45
- package/dist/builtin-memory/planning.md +4 -7
- package/dist/builtin-memory/spec.md +9 -12
- package/dist/builtin-memory/wedged-child-on-runaway-bash.md +8 -22
- package/dist/cli.js +1 -1
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +17 -4
- package/dist/clients/attach/__tests__/context-message.test.js +62 -22
- package/dist/clients/attach/__tests__/crtr-output.test.js +39 -30
- package/dist/clients/attach/render/chat-view.d.ts +20 -20
- package/dist/clients/attach/render/chat-view.js +40 -54
- package/dist/clients/attach/render/{frozen-history.d.ts → condensed-history.d.ts} +1 -18
- package/dist/clients/attach/render/condensed-history.js +60 -0
- package/dist/clients/attach/render/context-message.d.ts +1 -1
- package/dist/clients/attach/render/context-message.js +18 -41
- package/dist/clients/attach/session/bindings.d.ts +5 -3
- package/dist/clients/attach/session/bindings.js +7 -13
- package/dist/clients/attach/session/keys.d.ts +2 -0
- package/dist/clients/attach/session/keys.js +36 -37
- package/dist/clients/attach/session/profile-files.d.ts +8 -0
- package/dist/clients/attach/session/profile-files.js +157 -0
- package/dist/clients/attach/viewer.js +528 -529
- package/dist/commands/node-context.js +3 -2
- package/dist/commands/node.js +2 -2
- package/dist/commands/pkg/plugin-inspect.js +6 -7
- package/dist/commands/pkg/plugin-manage.d.ts +1 -1
- package/dist/commands/pkg/plugin-manage.js +131 -19
- package/dist/commands/pkg/plugin.js +2 -2
- package/dist/commands/pkg.js +6 -11
- package/dist/commands/profile/env.js +3 -3
- package/dist/commands/sys/config.js +17 -76
- package/dist/commands/sys/doctor.js +5 -91
- package/dist/commands/sys/setup-wizard.d.ts +9 -11
- package/dist/commands/sys/setup-wizard.js +47 -81
- package/dist/core/__tests__/base-worker-prompt.test.js +18 -21
- package/dist/core/__tests__/command-plugins-surfaces.test.js +39 -5
- package/dist/core/__tests__/command-plugins.test.js +75 -16
- package/dist/core/__tests__/review-model-floor.test.js +2 -2
- package/dist/core/__tests__/tmux-surface.test.js +10 -1
- package/dist/core/command-manifests/manifest.d.ts +24 -0
- package/dist/core/{configured-clis → command-manifests}/manifest.js +28 -25
- package/dist/core/command-manifests/registry.d.ts +1 -2
- package/dist/core/command-manifests/registry.js +2 -2
- package/dist/core/command-manifests/schema.d.ts +11 -13
- package/dist/core/command-manifests/schema.js +53 -192
- package/dist/core/command-plugins/compose.d.ts +0 -6
- package/dist/core/command-plugins/compose.js +32 -75
- package/dist/core/command-plugins/discovery.d.ts +25 -58
- package/dist/core/command-plugins/discovery.js +171 -261
- package/dist/core/command-plugins/endpoint.d.ts +24 -0
- package/dist/core/command-plugins/endpoint.js +48 -0
- package/dist/core/command-plugins/store.d.ts +16 -0
- package/dist/core/command-plugins/store.js +64 -0
- package/dist/core/command-plugins/{adapter.d.ts → transport/exec-invoke.d.ts} +3 -3
- package/dist/core/command-plugins/{adapter.js → transport/exec-invoke.js} +4 -4
- package/dist/core/{configured-clis/fetch.d.ts → command-plugins/transport/http-fetch.d.ts} +9 -18
- package/dist/core/{configured-clis/fetch.js → command-plugins/transport/http-fetch.js} +15 -35
- package/dist/core/{configured-clis/invoker.d.ts → command-plugins/transport/http-invoke.d.ts} +7 -7
- package/dist/core/{configured-clis/invoker.js → command-plugins/transport/http-invoke.js} +21 -23
- package/dist/core/command.d.ts +8 -9
- package/dist/core/command.js +6 -9
- package/dist/core/config.js +6 -10
- package/dist/core/env-name.d.ts +6 -0
- package/dist/core/env-name.js +9 -0
- package/dist/core/io.d.ts +1 -1
- package/dist/core/keybindings/__tests__/resolve.test.js +40 -3
- package/dist/core/keybindings/attach-control.d.ts +37 -0
- package/dist/core/keybindings/attach-control.js +38 -0
- package/dist/core/keybindings/catalog.d.ts +5 -4
- package/dist/core/keybindings/catalog.js +16 -8
- package/dist/core/keybindings/index.d.ts +1 -0
- package/dist/core/keybindings/index.js +1 -0
- package/dist/core/keybindings/types.d.ts +1 -1
- package/dist/core/preview-registry.js +41 -74
- package/dist/core/runtime/bearings.d.ts +2 -5
- package/dist/core/runtime/bearings.js +2 -5
- package/dist/core/runtime/broker.js +3 -2
- package/dist/core/runtime/front-door.d.ts +1 -1
- package/dist/core/runtime/front-door.js +2 -2
- package/dist/core/runtime/kickoff.d.ts +3 -3
- package/dist/core/runtime/kickoff.js +4 -3
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/situational-context.d.ts +1 -1
- package/dist/core/runtime/situational-context.js +1 -1
- package/dist/core/runtime/spawn.js +9 -9
- package/dist/core/runtime/tmux.js +29 -2
- package/dist/core/scope.d.ts +0 -5
- package/dist/core/scope.js +0 -10
- package/dist/core/user-settings.d.ts +193 -0
- package/dist/core/user-settings.js +252 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/pi-extensions/canvas-stophook.js +3 -2
- package/dist/prompts/review.js +4 -2
- package/dist/shared/generated-context.d.ts +34 -0
- package/dist/shared/generated-context.js +98 -0
- package/dist/types.d.ts +23 -16
- package/dist/types.js +3 -14
- package/dist/web-client/assets/index-BgLGlZ3D.css +2 -0
- package/dist/web-client/assets/{index-NIuSCOHM.js → index-CmoNqcCv.js} +19 -19
- package/dist/web-client/index.html +2 -2
- package/dist/web-client/sw.js +1 -1
- package/docs/public-api.md +1 -0
- package/package.json +1 -1
- package/runtime.lock.json +2 -2
- package/dist/builtin-memory/05-kinds/product/00-base.md +0 -25
- package/dist/builtin-memory/05-kinds/product/01-orchestrator.md +0 -15
- package/dist/builtin-memory/05-kinds/product/teardown.md +0 -15
- package/dist/builtin-memory/internal/workflow-codification.md +0 -82
- package/dist/builtin-memory/product.md +0 -80
- package/dist/clients/attach/render/frozen-history.js +0 -100
- package/dist/commands/pkg/cli-inspect.d.ts +0 -17
- package/dist/commands/pkg/cli-inspect.js +0 -190
- package/dist/commands/pkg/cli-manage.d.ts +0 -3
- package/dist/commands/pkg/cli-manage.js +0 -206
- package/dist/commands/pkg/cli.d.ts +0 -1
- package/dist/commands/pkg/cli.js +0 -14
- package/dist/core/configured-clis/cache.d.ts +0 -16
- package/dist/core/configured-clis/cache.js +0 -57
- package/dist/core/configured-clis/compose.d.ts +0 -14
- package/dist/core/configured-clis/compose.js +0 -60
- package/dist/core/configured-clis/discovery.d.ts +0 -47
- package/dist/core/configured-clis/discovery.js +0 -173
- package/dist/core/configured-clis/manifest.d.ts +0 -24
- package/dist/core/configured-clis/registration.d.ts +0 -40
- package/dist/core/configured-clis/registration.js +0 -201
- package/dist/web-client/assets/index-CqLKj8Xu.css +0 -2
|
@@ -11,7 +11,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
11
11
|
import { readFileSync, rmSync } from 'node:fs';
|
|
12
12
|
import { homedir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
|
-
import { BINDING_CATALOG, formatGesture, resolveUserKeybindings, } from '../keybindings/index.js';
|
|
14
|
+
import { ATTACH_CONTROL_BINDINGS, BINDING_CATALOG, encodeAttachControlInput, formatGesture, resolveUserKeybindings, } from '../keybindings/index.js';
|
|
15
15
|
import { bundledPiCommandForShell } from './pi-cli.js';
|
|
16
16
|
import { surfaceTmuxStyleArgs } from './surface-bg.js';
|
|
17
17
|
import { inboxToggleTmuxCommand } from '@crouton-kit/humanloop';
|
|
@@ -554,6 +554,13 @@ function menuActionCommand(action) {
|
|
|
554
554
|
menu: `send-keys -t '#{pane_id}' ${shellQuote(keys)}`,
|
|
555
555
|
};
|
|
556
556
|
}
|
|
557
|
+
case 'literal-input': {
|
|
558
|
+
const input = escapeTmuxFormats(action.input);
|
|
559
|
+
return {
|
|
560
|
+
argv: ['send-keys', '-l', input],
|
|
561
|
+
menu: `send-keys -l -t '#{pane_id}' ${shellQuote(input)}`,
|
|
562
|
+
};
|
|
563
|
+
}
|
|
557
564
|
case 'command': return chordCommand(action.run);
|
|
558
565
|
case 'direct': return directCommand(action.run);
|
|
559
566
|
case 'popup': return chordCommand(action.run, true);
|
|
@@ -640,6 +647,22 @@ function resolvedMenuActions(bindings) {
|
|
|
640
647
|
if (entry !== undefined)
|
|
641
648
|
entries.set(id, entry);
|
|
642
649
|
}
|
|
650
|
+
for (const { menuId, actionId } of ATTACH_CONTROL_BINDINGS) {
|
|
651
|
+
const definition = BINDING_CATALOG.find((candidate) => candidate.id === actionId);
|
|
652
|
+
if (definition === undefined)
|
|
653
|
+
throw new Error(`missing attach binding definition ${actionId}`);
|
|
654
|
+
entries.set(menuId, {
|
|
655
|
+
description: definition.name.toLowerCase(),
|
|
656
|
+
action: { kind: 'literal-input', input: encodeAttachControlInput(actionId) },
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
const attachItems = boundMenuItems(ATTACH_CONTROL_BINDINGS.map(({ menuId }) => menuId), entries, bindings);
|
|
660
|
+
if (attachItems.length > 0) {
|
|
661
|
+
entries.set('crtr.tmux.menu.attach', {
|
|
662
|
+
description: 'attach ›',
|
|
663
|
+
action: { kind: 'submenu', title: ' attach ', items: attachItems },
|
|
664
|
+
});
|
|
665
|
+
}
|
|
643
666
|
const showItems = boundMenuItems([
|
|
644
667
|
'crtr.tmux.menu.metadata',
|
|
645
668
|
'crtr.tmux.menu.context',
|
|
@@ -687,6 +710,7 @@ function menuItems(bindings, entries) {
|
|
|
687
710
|
'crtr.tmux.menu.view-settings',
|
|
688
711
|
]));
|
|
689
712
|
addGroup('Current node', boundItems([
|
|
713
|
+
'crtr.tmux.menu.attach',
|
|
690
714
|
'crtr.tmux.menu.background-bash',
|
|
691
715
|
'crtr.tmux.menu.file-review',
|
|
692
716
|
'crtr.tmux.menu.pin',
|
|
@@ -865,8 +889,11 @@ export function installTmuxBindings(bindings = resolveUserKeybindings()) {
|
|
|
865
889
|
for (const definition of BINDING_CATALOG) {
|
|
866
890
|
if (definition.pair?.field !== 'menu')
|
|
867
891
|
continue;
|
|
892
|
+
const paired = BINDING_CATALOG.find((candidate) => candidate.id === definition.pair?.pairedId);
|
|
893
|
+
if (paired?.pair?.field !== 'global')
|
|
894
|
+
continue;
|
|
868
895
|
const menuId = definition.id;
|
|
869
|
-
const globalId =
|
|
896
|
+
const globalId = paired.id;
|
|
870
897
|
const entry = menuActions.get(menuId);
|
|
871
898
|
const command = entry === undefined ? null : menuActionCommand(entry.action);
|
|
872
899
|
if (command === null)
|
package/dist/core/scope.d.ts
CHANGED
|
@@ -25,11 +25,6 @@ export declare function requireScopeRoot(scope: Scope): string;
|
|
|
25
25
|
export declare function ensureProjectScopeRoot(startDir?: string): string;
|
|
26
26
|
export declare function pluginsDir(scope: Scope): string | null;
|
|
27
27
|
export declare function marketplacesDir(scope: Scope): string | null;
|
|
28
|
-
export declare function configuredClisDir(scope: Scope): string | null;
|
|
29
|
-
/** The configured-CLIs cache parent dir under an EXACT scope-root dir. Used to
|
|
30
|
-
* address per-root caches when multiple project roots are visible; the single
|
|
31
|
-
* source of the `configured-clis` path segment. */
|
|
32
|
-
export declare function configuredClisDirForRoot(scopeRootDir: string): string;
|
|
33
28
|
/** Where substrate memory documents live per scope. Builtin memory is the
|
|
34
29
|
* special case — its own package dir (builtinMemoryRoot), since the builtin
|
|
35
30
|
* scope has no scopeRoot — mirroring viewsDir's builtin handling. User and
|
package/dist/core/scope.js
CHANGED
|
@@ -195,16 +195,6 @@ export function marketplacesDir(scope) {
|
|
|
195
195
|
const root = scopeRoot(scope);
|
|
196
196
|
return root ? join(root, 'marketplaces') : null;
|
|
197
197
|
}
|
|
198
|
-
export function configuredClisDir(scope) {
|
|
199
|
-
const root = scopeRoot(scope);
|
|
200
|
-
return root ? configuredClisDirForRoot(root) : null;
|
|
201
|
-
}
|
|
202
|
-
/** The configured-CLIs cache parent dir under an EXACT scope-root dir. Used to
|
|
203
|
-
* address per-root caches when multiple project roots are visible; the single
|
|
204
|
-
* source of the `configured-clis` path segment. */
|
|
205
|
-
export function configuredClisDirForRoot(scopeRootDir) {
|
|
206
|
-
return join(scopeRootDir, 'configured-clis');
|
|
207
|
-
}
|
|
208
198
|
/** Where substrate memory documents live per scope. Builtin memory is the
|
|
209
199
|
* special case — its own package dir (builtinMemoryRoot), since the builtin
|
|
210
200
|
* scope has no scopeRoot — mirroring viewsDir's builtin handling. User and
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { ScopeConfig } from '../types.js';
|
|
2
|
+
export interface UserSettingDefinition<Key extends string = string> {
|
|
3
|
+
key: Key;
|
|
4
|
+
label: string;
|
|
5
|
+
description: string;
|
|
6
|
+
valueConstraint: string;
|
|
7
|
+
applies: string;
|
|
8
|
+
order: number;
|
|
9
|
+
format: (config: ScopeConfig) => string;
|
|
10
|
+
cycle: (config: ScopeConfig, delta: number) => void;
|
|
11
|
+
/** Mutate `config` from a CLI string, returning a user-facing validation error on failure. */
|
|
12
|
+
setFromString: (config: ScopeConfig, raw: string) => string | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Exhaustive settings-surface coverage for ScopeConfig. Primitive preferences
|
|
16
|
+
* are required by the type to define a Settings row; structured registries must
|
|
17
|
+
* name the specialized surface that owns them. Adding a config field therefore
|
|
18
|
+
* fails typecheck until its user-facing settings coverage is decided. The
|
|
19
|
+
* auto_update nested record is exhaustive for the same reason.
|
|
20
|
+
*/
|
|
21
|
+
export declare const CONFIG_SETTINGS_COVERAGE: {
|
|
22
|
+
schema_version: {
|
|
23
|
+
surface: "specialized";
|
|
24
|
+
owner: string;
|
|
25
|
+
};
|
|
26
|
+
marketplaces: {
|
|
27
|
+
surface: "specialized";
|
|
28
|
+
owner: string;
|
|
29
|
+
};
|
|
30
|
+
plugins: {
|
|
31
|
+
surface: "specialized";
|
|
32
|
+
owner: string;
|
|
33
|
+
};
|
|
34
|
+
auto_update: {
|
|
35
|
+
surface: "settings";
|
|
36
|
+
settings: {
|
|
37
|
+
crtr: {
|
|
38
|
+
key: "auto_update.crtr";
|
|
39
|
+
label: string;
|
|
40
|
+
description: string;
|
|
41
|
+
valueConstraint: string;
|
|
42
|
+
applies: string;
|
|
43
|
+
order: number;
|
|
44
|
+
format: (config: ScopeConfig) => "notify" | "apply" | "off";
|
|
45
|
+
cycle: (config: ScopeConfig, delta: number) => void;
|
|
46
|
+
setFromString: (config: ScopeConfig, raw: string) => "auto_update.crtr must be notify, apply, or false" | null;
|
|
47
|
+
};
|
|
48
|
+
content: {
|
|
49
|
+
key: "auto_update.content";
|
|
50
|
+
label: string;
|
|
51
|
+
description: string;
|
|
52
|
+
valueConstraint: string;
|
|
53
|
+
applies: string;
|
|
54
|
+
order: number;
|
|
55
|
+
format: (config: ScopeConfig) => "notify" | "apply" | "off";
|
|
56
|
+
cycle: (config: ScopeConfig, delta: number) => void;
|
|
57
|
+
setFromString: (config: ScopeConfig, raw: string) => "auto_update.content must be notify, apply, or false" | null;
|
|
58
|
+
};
|
|
59
|
+
interval_hours: {
|
|
60
|
+
key: "auto_update.interval_hours";
|
|
61
|
+
label: string;
|
|
62
|
+
description: string;
|
|
63
|
+
valueConstraint: string;
|
|
64
|
+
applies: string;
|
|
65
|
+
order: number;
|
|
66
|
+
format: (config: ScopeConfig) => string;
|
|
67
|
+
cycle: (config: ScopeConfig, delta: number) => void;
|
|
68
|
+
setFromString: (config: ScopeConfig, raw: string) => string | null;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
max_panes_per_window: {
|
|
73
|
+
surface: "settings";
|
|
74
|
+
setting: {
|
|
75
|
+
key: "max_panes_per_window";
|
|
76
|
+
label: string;
|
|
77
|
+
description: string;
|
|
78
|
+
valueConstraint: string;
|
|
79
|
+
applies: string;
|
|
80
|
+
order: number;
|
|
81
|
+
format: (config: ScopeConfig) => string;
|
|
82
|
+
cycle: (config: ScopeConfig, delta: number) => void;
|
|
83
|
+
setFromString: (config: ScopeConfig, raw: string) => string | null;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
auto_open_child_viewers: {
|
|
87
|
+
surface: "settings";
|
|
88
|
+
setting: {
|
|
89
|
+
key: "auto_open_child_viewers";
|
|
90
|
+
label: string;
|
|
91
|
+
description: string;
|
|
92
|
+
valueConstraint: string;
|
|
93
|
+
applies: string;
|
|
94
|
+
order: number;
|
|
95
|
+
format: (config: ScopeConfig) => "off" | "on";
|
|
96
|
+
cycle: (config: ScopeConfig) => void;
|
|
97
|
+
setFromString: (config: ScopeConfig, raw: string) => string | null;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
brokerThresholds: {
|
|
101
|
+
surface: "specialized";
|
|
102
|
+
owner: string;
|
|
103
|
+
};
|
|
104
|
+
completion_bell: {
|
|
105
|
+
surface: "settings";
|
|
106
|
+
setting: {
|
|
107
|
+
key: "completion_bell";
|
|
108
|
+
label: string;
|
|
109
|
+
description: string;
|
|
110
|
+
valueConstraint: string;
|
|
111
|
+
applies: string;
|
|
112
|
+
order: number;
|
|
113
|
+
format: (config: ScopeConfig) => "off" | "on";
|
|
114
|
+
cycle: (config: ScopeConfig) => void;
|
|
115
|
+
setFromString: (config: ScopeConfig, raw: string) => string | null;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
live_cycles: {
|
|
119
|
+
surface: "settings";
|
|
120
|
+
setting: {
|
|
121
|
+
key: "live_cycles";
|
|
122
|
+
label: string;
|
|
123
|
+
description: string;
|
|
124
|
+
valueConstraint: string;
|
|
125
|
+
applies: string;
|
|
126
|
+
order: number;
|
|
127
|
+
format: (config: ScopeConfig) => string;
|
|
128
|
+
cycle: (config: ScopeConfig, delta: number) => void;
|
|
129
|
+
setFromString: (config: ScopeConfig, raw: string) => string | null;
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
condensed_history: {
|
|
133
|
+
surface: "settings";
|
|
134
|
+
setting: {
|
|
135
|
+
key: "condensed_history";
|
|
136
|
+
label: string;
|
|
137
|
+
description: string;
|
|
138
|
+
valueConstraint: string;
|
|
139
|
+
applies: string;
|
|
140
|
+
order: number;
|
|
141
|
+
format: (config: ScopeConfig) => "user" | "none" | "agent" | "both";
|
|
142
|
+
cycle: (config: ScopeConfig, delta: number) => void;
|
|
143
|
+
setFromString: (config: ScopeConfig, raw: string) => string | null;
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
fold_finished_tools: {
|
|
147
|
+
surface: "settings";
|
|
148
|
+
setting: {
|
|
149
|
+
key: "fold_finished_tools";
|
|
150
|
+
label: string;
|
|
151
|
+
description: string;
|
|
152
|
+
valueConstraint: string;
|
|
153
|
+
applies: string;
|
|
154
|
+
order: number;
|
|
155
|
+
format: (config: ScopeConfig) => "off" | "on";
|
|
156
|
+
cycle: (config: ScopeConfig) => void;
|
|
157
|
+
setFromString: (config: ScopeConfig, raw: string) => string | null;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
keybindings: {
|
|
161
|
+
surface: "specialized";
|
|
162
|
+
owner: string;
|
|
163
|
+
};
|
|
164
|
+
modelLadders: {
|
|
165
|
+
surface: "specialized";
|
|
166
|
+
owner: string;
|
|
167
|
+
};
|
|
168
|
+
modelRoutes: {
|
|
169
|
+
surface: "specialized";
|
|
170
|
+
owner: string;
|
|
171
|
+
};
|
|
172
|
+
modelRouting: {
|
|
173
|
+
surface: "specialized";
|
|
174
|
+
owner: string;
|
|
175
|
+
};
|
|
176
|
+
kinds: {
|
|
177
|
+
surface: "specialized";
|
|
178
|
+
owner: string;
|
|
179
|
+
};
|
|
180
|
+
remoteCanvas: {
|
|
181
|
+
surface: "specialized";
|
|
182
|
+
owner: string;
|
|
183
|
+
};
|
|
184
|
+
spawnEnv: {
|
|
185
|
+
surface: "specialized";
|
|
186
|
+
owner: string;
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
/** The exhaustive top-level key list used by config persistence and help. */
|
|
190
|
+
export declare const SCOPE_CONFIG_KEYS: (keyof ScopeConfig)[];
|
|
191
|
+
/** The single row registry shared by `sys setup` and `sys config set`. */
|
|
192
|
+
export declare const USER_SETTINGS: readonly UserSettingDefinition[];
|
|
193
|
+
export declare function findUserSetting(key: string): UserSettingDefinition | undefined;
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { CONDENSED_HISTORY_MODES } from '../types.js';
|
|
2
|
+
function cycleChoice(choices, current, delta) {
|
|
3
|
+
const index = choices.indexOf(current);
|
|
4
|
+
const start = index >= 0 ? index : 0;
|
|
5
|
+
return choices[(start + delta + choices.length) % choices.length];
|
|
6
|
+
}
|
|
7
|
+
function cycleNumber(choices, current, delta) {
|
|
8
|
+
const exact = choices.indexOf(current);
|
|
9
|
+
if (exact >= 0)
|
|
10
|
+
return choices[(exact + delta + choices.length) % choices.length];
|
|
11
|
+
if (delta >= 0)
|
|
12
|
+
return choices.find((choice) => choice > current) ?? choices[0];
|
|
13
|
+
return [...choices].reverse().find((choice) => choice < current) ?? choices[choices.length - 1];
|
|
14
|
+
}
|
|
15
|
+
function booleanFromString(raw, key) {
|
|
16
|
+
if (raw === 'true')
|
|
17
|
+
return true;
|
|
18
|
+
if (raw === 'false')
|
|
19
|
+
return false;
|
|
20
|
+
return `${key} must be true or false`;
|
|
21
|
+
}
|
|
22
|
+
function nonNegativeIntegerFromString(raw, key) {
|
|
23
|
+
if (!/^\d+$/.test(raw))
|
|
24
|
+
return `${key} must be an integer >= 0`;
|
|
25
|
+
const value = Number(raw);
|
|
26
|
+
if (!Number.isSafeInteger(value))
|
|
27
|
+
return `${key} must be an integer >= 0`;
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
function positiveIntegerFromString(raw, key) {
|
|
31
|
+
const value = nonNegativeIntegerFromString(raw, key);
|
|
32
|
+
if (typeof value === 'string' || value < 1)
|
|
33
|
+
return `${key} must be an integer >= 1`;
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
const AUTO_UPDATE_MODES = [false, 'notify', 'apply'];
|
|
37
|
+
const UPDATE_INTERVAL_HOURS = [0, 1, 6, 12, 24, 48, 72, 168];
|
|
38
|
+
const MAX_PANES = [1, 2, 3, 4, 5, 6, 8, 10, 12];
|
|
39
|
+
const LIVE_CYCLES = [1, 2, 3, 4, 5, 6];
|
|
40
|
+
/**
|
|
41
|
+
* Exhaustive settings-surface coverage for ScopeConfig. Primitive preferences
|
|
42
|
+
* are required by the type to define a Settings row; structured registries must
|
|
43
|
+
* name the specialized surface that owns them. Adding a config field therefore
|
|
44
|
+
* fails typecheck until its user-facing settings coverage is decided. The
|
|
45
|
+
* auto_update nested record is exhaustive for the same reason.
|
|
46
|
+
*/
|
|
47
|
+
export const CONFIG_SETTINGS_COVERAGE = {
|
|
48
|
+
schema_version: { surface: 'specialized', owner: 'internal schema migration' },
|
|
49
|
+
marketplaces: { surface: 'specialized', owner: 'Plugins and pkg market commands' },
|
|
50
|
+
plugins: { surface: 'specialized', owner: 'Plugins tab and pkg plugin commands' },
|
|
51
|
+
auto_update: {
|
|
52
|
+
surface: 'settings',
|
|
53
|
+
settings: {
|
|
54
|
+
crtr: {
|
|
55
|
+
key: 'auto_update.crtr',
|
|
56
|
+
label: 'crouter updates',
|
|
57
|
+
description: 'Notify about crouter releases, install them automatically, or turn checks off.',
|
|
58
|
+
valueConstraint: 'true|false|notify|apply; true stores notify',
|
|
59
|
+
applies: 'Applies on the next crouter command.',
|
|
60
|
+
order: 70,
|
|
61
|
+
format: (config) => config.auto_update.crtr === false ? 'off' : config.auto_update.crtr,
|
|
62
|
+
cycle: (config, delta) => { config.auto_update.crtr = cycleChoice(AUTO_UPDATE_MODES, config.auto_update.crtr, delta); },
|
|
63
|
+
setFromString: (config, raw) => {
|
|
64
|
+
const value = raw === 'true' ? 'notify' : raw;
|
|
65
|
+
if (value !== 'notify' && value !== 'apply' && value !== 'false')
|
|
66
|
+
return 'auto_update.crtr must be notify, apply, or false';
|
|
67
|
+
config.auto_update.crtr = value === 'false' ? false : value;
|
|
68
|
+
return null;
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
content: {
|
|
72
|
+
key: 'auto_update.content',
|
|
73
|
+
label: 'Content updates',
|
|
74
|
+
description: 'Notify about plugin and marketplace updates, apply them automatically, or turn checks off.',
|
|
75
|
+
valueConstraint: 'false|notify|apply',
|
|
76
|
+
applies: 'Applies on the next crouter command.',
|
|
77
|
+
order: 80,
|
|
78
|
+
format: (config) => config.auto_update.content === false ? 'off' : config.auto_update.content,
|
|
79
|
+
cycle: (config, delta) => { config.auto_update.content = cycleChoice(AUTO_UPDATE_MODES, config.auto_update.content, delta); },
|
|
80
|
+
setFromString: (config, raw) => {
|
|
81
|
+
if (raw !== 'notify' && raw !== 'apply' && raw !== 'false')
|
|
82
|
+
return 'auto_update.content must be notify, apply, or false';
|
|
83
|
+
config.auto_update.content = raw === 'false' ? false : raw;
|
|
84
|
+
return null;
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
interval_hours: {
|
|
88
|
+
key: 'auto_update.interval_hours',
|
|
89
|
+
label: 'Update interval',
|
|
90
|
+
description: 'Minimum hours between automatic update checks. Zero checks on every command.',
|
|
91
|
+
valueConstraint: 'integer >= 0',
|
|
92
|
+
applies: 'Applies on the next crouter command.',
|
|
93
|
+
order: 90,
|
|
94
|
+
format: (config) => `${config.auto_update.interval_hours}h`,
|
|
95
|
+
cycle: (config, delta) => { config.auto_update.interval_hours = cycleNumber(UPDATE_INTERVAL_HOURS, config.auto_update.interval_hours, delta); },
|
|
96
|
+
setFromString: (config, raw) => {
|
|
97
|
+
const value = nonNegativeIntegerFromString(raw, 'auto_update.interval_hours');
|
|
98
|
+
if (typeof value === 'string')
|
|
99
|
+
return value;
|
|
100
|
+
config.auto_update.interval_hours = value;
|
|
101
|
+
return null;
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
max_panes_per_window: {
|
|
107
|
+
surface: 'settings',
|
|
108
|
+
setting: {
|
|
109
|
+
key: 'max_panes_per_window',
|
|
110
|
+
label: 'Maximum panes',
|
|
111
|
+
description: 'Maximum human-review panes placed in one tmux window before using another window.',
|
|
112
|
+
valueConstraint: 'integer >= 1',
|
|
113
|
+
applies: 'Applies to the next pane placement.',
|
|
114
|
+
order: 20,
|
|
115
|
+
format: (config) => String(config.max_panes_per_window),
|
|
116
|
+
cycle: (config, delta) => { config.max_panes_per_window = cycleNumber(MAX_PANES, config.max_panes_per_window, delta); },
|
|
117
|
+
setFromString: (config, raw) => {
|
|
118
|
+
const value = positiveIntegerFromString(raw, 'max_panes_per_window');
|
|
119
|
+
if (typeof value === 'string')
|
|
120
|
+
return value;
|
|
121
|
+
config.max_panes_per_window = value;
|
|
122
|
+
return null;
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
auto_open_child_viewers: {
|
|
127
|
+
surface: 'settings',
|
|
128
|
+
setting: {
|
|
129
|
+
key: 'auto_open_child_viewers',
|
|
130
|
+
label: 'Open child panes',
|
|
131
|
+
description: 'Open each managed child beside its watched parent. Off keeps new children running in the background.',
|
|
132
|
+
valueConstraint: 'true|false',
|
|
133
|
+
applies: 'Applies to the next managed child created; independent roots still open their attended viewer.',
|
|
134
|
+
order: 10,
|
|
135
|
+
format: (config) => config.auto_open_child_viewers ? 'on' : 'off',
|
|
136
|
+
cycle: (config) => { config.auto_open_child_viewers = !config.auto_open_child_viewers; },
|
|
137
|
+
setFromString: (config, raw) => {
|
|
138
|
+
const value = booleanFromString(raw, 'auto_open_child_viewers');
|
|
139
|
+
if (typeof value === 'string')
|
|
140
|
+
return value;
|
|
141
|
+
config.auto_open_child_viewers = value;
|
|
142
|
+
return null;
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
brokerThresholds: { surface: 'specialized', owner: 'Broker limits tab' },
|
|
147
|
+
completion_bell: {
|
|
148
|
+
surface: 'settings',
|
|
149
|
+
setting: {
|
|
150
|
+
key: 'completion_bell',
|
|
151
|
+
label: 'Completion bell',
|
|
152
|
+
description: 'Ring a short sound when the node in an attached viewer finishes a turn.',
|
|
153
|
+
valueConstraint: 'true|false',
|
|
154
|
+
applies: 'Applies on the next turn end.',
|
|
155
|
+
order: 40,
|
|
156
|
+
format: (config) => config.completion_bell ? 'on' : 'off',
|
|
157
|
+
cycle: (config) => { config.completion_bell = !config.completion_bell; },
|
|
158
|
+
setFromString: (config, raw) => {
|
|
159
|
+
const value = booleanFromString(raw, 'completion_bell');
|
|
160
|
+
if (typeof value === 'string')
|
|
161
|
+
return value;
|
|
162
|
+
config.completion_bell = value;
|
|
163
|
+
return null;
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
live_cycles: {
|
|
168
|
+
surface: 'settings',
|
|
169
|
+
setting: {
|
|
170
|
+
key: 'live_cycles',
|
|
171
|
+
label: 'Live cycles',
|
|
172
|
+
description: 'Trailing refresh cycles rendered at full fidelity; older cycles condense to text.',
|
|
173
|
+
valueConstraint: 'integer >= 1',
|
|
174
|
+
applies: 'Applies on the next attach.',
|
|
175
|
+
order: 50,
|
|
176
|
+
format: (config) => String(config.live_cycles),
|
|
177
|
+
cycle: (config, delta) => { config.live_cycles = cycleNumber(LIVE_CYCLES, config.live_cycles, delta); },
|
|
178
|
+
setFromString: (config, raw) => {
|
|
179
|
+
const value = positiveIntegerFromString(raw, 'live_cycles');
|
|
180
|
+
if (typeof value === 'string')
|
|
181
|
+
return value;
|
|
182
|
+
config.live_cycles = value;
|
|
183
|
+
return null;
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
condensed_history: {
|
|
188
|
+
surface: 'settings',
|
|
189
|
+
setting: {
|
|
190
|
+
key: 'condensed_history',
|
|
191
|
+
label: 'Condensed history',
|
|
192
|
+
description: 'Messages retained from condensed cycles. Tool calls are never kept.',
|
|
193
|
+
valueConstraint: CONDENSED_HISTORY_MODES.join('|'),
|
|
194
|
+
applies: 'Applies on the next attach.',
|
|
195
|
+
order: 60,
|
|
196
|
+
format: (config) => config.condensed_history,
|
|
197
|
+
cycle: (config, delta) => { config.condensed_history = cycleChoice(CONDENSED_HISTORY_MODES, config.condensed_history, delta); },
|
|
198
|
+
setFromString: (config, raw) => {
|
|
199
|
+
if (!CONDENSED_HISTORY_MODES.includes(raw))
|
|
200
|
+
return `condensed_history must be one of: ${CONDENSED_HISTORY_MODES.join('|')}`;
|
|
201
|
+
config.condensed_history = raw;
|
|
202
|
+
return null;
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
fold_finished_tools: {
|
|
207
|
+
surface: 'settings',
|
|
208
|
+
setting: {
|
|
209
|
+
key: 'fold_finished_tools',
|
|
210
|
+
label: 'Fold finished tools',
|
|
211
|
+
description: 'Fold every settled tool call to its call line. Toggle live with /fold-tools.',
|
|
212
|
+
valueConstraint: 'true|false',
|
|
213
|
+
applies: 'Applies on the next attach.',
|
|
214
|
+
order: 30,
|
|
215
|
+
format: (config) => config.fold_finished_tools ? 'on' : 'off',
|
|
216
|
+
cycle: (config) => { config.fold_finished_tools = !config.fold_finished_tools; },
|
|
217
|
+
setFromString: (config, raw) => {
|
|
218
|
+
const value = booleanFromString(raw, 'fold_finished_tools');
|
|
219
|
+
if (typeof value === 'string')
|
|
220
|
+
return value;
|
|
221
|
+
config.fold_finished_tools = value;
|
|
222
|
+
return null;
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
keybindings: { surface: 'specialized', owner: 'Keybindings tab' },
|
|
227
|
+
modelLadders: { surface: 'specialized', owner: 'Models tab' },
|
|
228
|
+
modelRoutes: { surface: 'specialized', owner: 'Models route declarations' },
|
|
229
|
+
modelRouting: { surface: 'specialized', owner: 'Models route declarations' },
|
|
230
|
+
kinds: { surface: 'specialized', owner: 'Models tab and kind registry' },
|
|
231
|
+
remoteCanvas: { surface: 'specialized', owner: 'canvas config commands' },
|
|
232
|
+
spawnEnv: { surface: 'specialized', owner: 'spawn environment allow-list' },
|
|
233
|
+
};
|
|
234
|
+
/** The exhaustive top-level key list used by config persistence and help. */
|
|
235
|
+
export const SCOPE_CONFIG_KEYS = Object.keys(CONFIG_SETTINGS_COVERAGE);
|
|
236
|
+
function collectUserSettings() {
|
|
237
|
+
const out = [];
|
|
238
|
+
for (const coverage of Object.values(CONFIG_SETTINGS_COVERAGE)) {
|
|
239
|
+
if (coverage.surface !== 'settings')
|
|
240
|
+
continue;
|
|
241
|
+
if ('setting' in coverage)
|
|
242
|
+
out.push(coverage.setting);
|
|
243
|
+
else
|
|
244
|
+
out.push(...Object.values(coverage.settings));
|
|
245
|
+
}
|
|
246
|
+
return out.sort((a, b) => a.order - b.order);
|
|
247
|
+
}
|
|
248
|
+
/** The single row registry shared by `sys setup` and `sys config set`. */
|
|
249
|
+
export const USER_SETTINGS = collectUserSettings();
|
|
250
|
+
export function findUserSetting(key) {
|
|
251
|
+
return USER_SETTINGS.find((setting) => setting.key === key);
|
|
252
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,3 +21,7 @@ export type { CrtrError } from './core/errors.js';
|
|
|
21
21
|
export { nowIso } from './core/fs-utils.js';
|
|
22
22
|
export { validateOperationId, buildEnvelope, operationIdContext, errorClassCodes, serializeEventRecord, errorClassFromError, } from './core/events/index.js';
|
|
23
23
|
export type { BuildEnvelopeInput, ErrorClass, ErrorClassCode, ErrorClassHints, EventComponent, EventEnvelope, EventError, EventField, EventLevel, EventOutcome, OperationId, OperationIdContext, RetryDisposition, } from './core/events/index.js';
|
|
24
|
+
export { validateCommandManifest } from './core/command-manifests/manifest.js';
|
|
25
|
+
export type { CommandManifestValidation, ValidatedCommandManifest } from './core/command-manifests/manifest.js';
|
|
26
|
+
export type { CommandManifestIssue, TransportKind } from './core/command-manifests/schema.js';
|
|
27
|
+
export { SUBTREE_NAMES } from './build-root.js';
|
package/dist/index.js
CHANGED
|
@@ -42,3 +42,6 @@ export { nowIso } from './core/fs-utils.js';
|
|
|
42
42
|
// Pure envelope helpers only. Local source binding and canonical append remain
|
|
43
43
|
// internal so package consumers cannot select crouter runtime file paths.
|
|
44
44
|
export { validateOperationId, buildEnvelope, operationIdContext, errorClassCodes, serializeEventRecord, errorClassFromError, } from './core/events/index.js';
|
|
45
|
+
// ── Command-manifest compatibility ───────────────────────────────────────
|
|
46
|
+
export { validateCommandManifest } from './core/command-manifests/manifest.js';
|
|
47
|
+
export { SUBTREE_NAMES } from './build-root.js';
|
|
@@ -44,6 +44,7 @@ import { clearStopSignals, consumeStopSignals } from '../core/runtime/stop-signa
|
|
|
44
44
|
import { cliClient } from '../commands/api-client.js';
|
|
45
45
|
import { focusOf, tearDownNode } from '../core/runtime/placement.js';
|
|
46
46
|
import { readCursor, readInboxSince } from '../core/feed/inbox.js';
|
|
47
|
+
import { CONTEXT_NUDGE_CUSTOM_TYPE, formatContextNudge } from '../shared/generated-context.js';
|
|
47
48
|
/** Universal upper bound for an unfocused broker parked without runnable work. */
|
|
48
49
|
export const UNATTENDED_PARK_MS = (() => {
|
|
49
50
|
const testOverride = process.env['CRTR_TEST_UNATTENDED_PARK_MS'];
|
|
@@ -696,12 +697,12 @@ export function registerCanvasStophook(pi) {
|
|
|
696
697
|
const at = contextTokens !== null ? steerBand(contextTokens) : null;
|
|
697
698
|
if (at !== null && !firedBands.has(at)) {
|
|
698
699
|
firedBands.add(at);
|
|
699
|
-
const note =
|
|
700
|
+
const note = formatContextNudge(steerNote(at, lifecycle, mode));
|
|
700
701
|
if (runContinues) {
|
|
701
702
|
pi.sendUserMessage(note, { deliverAs: 'steer' });
|
|
702
703
|
}
|
|
703
704
|
else {
|
|
704
|
-
pi.sendMessage({ customType:
|
|
705
|
+
pi.sendMessage({ customType: CONTEXT_NUDGE_CUSTOM_TYPE, content: note, display: true }, { deliverAs: 'nextTurn' });
|
|
705
706
|
}
|
|
706
707
|
}
|
|
707
708
|
}
|
package/dist/prompts/review.js
CHANGED
|
@@ -48,8 +48,10 @@ seams to fall between — skip it for self-contained specs.
|
|
|
48
48
|
|
|
49
49
|
For larger specs touching established patterns, optionally spawn a Task
|
|
50
50
|
agent (\`general-purpose\`, \`sonnet\`) to cross-check the spec's design
|
|
51
|
-
against
|
|
52
|
-
|
|
51
|
+
against the applicable project memory documents (discover them with
|
|
52
|
+
\`crtr memory list\` and load them with \`crtr memory read\`) and the files they
|
|
53
|
+
reference, looking for contradictions with project conventions. Skip for small
|
|
54
|
+
specs.
|
|
53
55
|
|
|
54
56
|
## Calibration
|
|
55
57
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Custom message carrying the node's session-start bearings. */
|
|
2
|
+
export declare const CONTEXT_INTRO_CUSTOM_TYPE = "crtr-context";
|
|
3
|
+
/** Custom message carrying an ambient situational-context update. */
|
|
4
|
+
export declare const SITUATIONAL_CONTEXT_CUSTOM_TYPE = "crtr-situational-context";
|
|
5
|
+
/** Custom message used when a context-size nudge waits for the next turn. */
|
|
6
|
+
export declare const CONTEXT_NUDGE_CUSTOM_TYPE = "crtr-context-nudge";
|
|
7
|
+
/** Opening text of a fresh-revive kickoff user message. */
|
|
8
|
+
export declare const REVIVE_KICKOFF_SENTINEL = "You have been revived fresh after a context refresh";
|
|
9
|
+
/** Prefix shared by the producer and the compatibility classifier for context nudges. */
|
|
10
|
+
export declare const CONTEXT_NUDGE_PREFIX = "[crtr] Context ~";
|
|
11
|
+
export interface GeneratedContextMessageLike {
|
|
12
|
+
role?: string;
|
|
13
|
+
customType?: string;
|
|
14
|
+
content?: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface GeneratedContextPresentation {
|
|
17
|
+
kind: 'bearings' | 'situational' | 'revive' | 'context-nudge' | 'inbox';
|
|
18
|
+
label: string;
|
|
19
|
+
summary: string;
|
|
20
|
+
body: string;
|
|
21
|
+
}
|
|
22
|
+
/** Plain text from a generated message's string or text-block content. */
|
|
23
|
+
export declare function generatedContextText(message: GeneratedContextMessageLike): string;
|
|
24
|
+
/** Format the runtime's visible context-size guidance. */
|
|
25
|
+
export declare function formatContextNudge(note: string): string;
|
|
26
|
+
export declare function isInboxDigest(text: string): boolean;
|
|
27
|
+
export declare function extractInboxSender(text: string): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Classify a crouter-generated context message for display. The checks are
|
|
30
|
+
* exact producer-owned contracts: custom messages use their customType; the two
|
|
31
|
+
* user-message forms use the same stable sentinel/prefix their producers own.
|
|
32
|
+
* Ordinary user prompts never match and remain ordinary user prompts.
|
|
33
|
+
*/
|
|
34
|
+
export declare function generatedContextPresentation(message: GeneratedContextMessageLike): GeneratedContextPresentation | null;
|