@hydraharness/harness-client-ui-input-trigger 0.0.0-stage → 0.1.1-rc.7

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/lib/index.js ADDED
@@ -0,0 +1,11 @@
1
+ //#region lib/types/index.js
2
+ /**
3
+ * Slash trigger plugin, node half. Pure UI plugin: the empty apply exists so
4
+ * the plugin appears in the host cordis.yml / Loader; the browser half ships
5
+ * via exports["./client"], discovered through the package.json hydra.client
6
+ * declaration.
7
+ */
8
+ /** Host plugin body — no host-side behavior for the slash trigger plugin. */
9
+ function apply() {}
10
+ //#endregion
11
+ export { apply };
@@ -0,0 +1,25 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@hydraharness/harness-client-ui-input-trigger`.
4
+ * @module @hydraharness/harness-client-ui-input-trigger/invariant
5
+ */
6
+ const PACKAGE_NAME = "@hydraharness/harness-client-ui-input-trigger";
7
+ /** Cordis companion plugin name. */
8
+ const name = "client-ui-input-trigger-invariant";
9
+ /** Service required before the companion can reserve package ownership. */
10
+ const inject = ["invariants"];
11
+ /**
12
+ * No runtime invariant: the trigger pipeline is a browser-side pure core
13
+ * (detect/reduce/match) plus a registry whose disposal is proven by the
14
+ * HMR-safety spec; it emits no cordis events and owns no cross-plugin
15
+ * mutable state.
16
+ */
17
+ const install = () => {};
18
+ /**
19
+ * Register this package's invariant companion.
20
+ * @param ctx - Cordis context carrying the invariant service.
21
+ * @returns the installed registration's disposer after setup succeeds.
22
+ */
23
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
24
+ //#endregion
25
+ export { apply, inject, name };
@@ -0,0 +1,11 @@
1
+ import type { PropsLocale } from '@hydraharness/harness-client-ui-slots';
2
+ import type { MenuViewInjected } from './slots.ts';
3
+ /** Full menu props: injected face + the locale seat. */
4
+ export type MenuViewProps = MenuViewInjected & PropsLocale<'slash.menu'>;
5
+ /**
6
+ * Render the candidate menu overlay entry.
7
+ * @param props - injected face (the menu store and the pick route); `t` rides the standard locale seat.
8
+ * @returns the dropdown while open; null while closed.
9
+ */
10
+ export declare function MenuView({ menu, onPick, onDismiss, t }: MenuViewProps): import("react").JSX.Element | null;
11
+ //# sourceMappingURL=MenuView.d.ts.map
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Frozen service contract of the slash pipeline. Types only. The
3
+ * InputTriggerService implementation publishes this face as `ctx.inputTriggers`; sources
4
+ * see registerSource alone, the conversation wiring layer resolves its
5
+ * per-session controller through sessionOf.
6
+ */
7
+ import type { ClientContext } from '@hydraharness/harness-client-runtime/client';
8
+ import type { InputTriggerSource } from '../types.ts';
9
+ import type { InputTriggerController } from './controller.ts';
10
+ /** The `ctx.inputTriggers` service face. */
11
+ export interface InputTriggerServiceContract {
12
+ /**
13
+ * Register one trigger source; duplicate trigger/name pairs throw.
14
+ * @param src - source that discovers and resolves slash or reference candidates.
15
+ * @returns effect disposer removing this source.
16
+ */
17
+ registerSource(src: InputTriggerSource): () => void;
18
+ /**
19
+ * Resolve the lazy controller owned by one session scope.
20
+ * @param actx - session-scoped Client context.
21
+ * @returns controller that dies with that scope.
22
+ */
23
+ sessionOf(actx: ClientContext): InputTriggerController;
24
+ }
25
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1,153 @@
1
+ /**
2
+ * InputTriggerController: the per-session half of the trigger pipeline. Owns every
3
+ * piece of mutable interaction state — the authoritative trigger hit (span
4
+ * included; it outlives menu close for space adjudication), the menu store,
5
+ * and the candidate-fetch lifecycle — and executes pick outcomes by
6
+ * dispatching the scoped input-mutation events. The root InputTriggerService keeps
7
+ * only the source roster. One controller per session scope; the service
8
+ * disposes it with the scope fiber.
9
+ */
10
+ import type { ClientContext, SessionId, SnapshotStore } from '@hydraharness/harness-client-runtime/client';
11
+ import type { MenuState, TriggerHit } from '../core/contract.ts';
12
+ import type { ArbitrateKey, ArbitrateOutcome, PickOutcome, InputTriggerSource, SubmitEnvelope, TriggerChar, TriggerGuard } from '../types.ts';
13
+ /** Roster access the controller borrows from the root service (registration order preserved). */
14
+ export interface SourceRoster {
15
+ sources(trigger: string): readonly InputTriggerSource[];
16
+ all(): readonly InputTriggerSource[];
17
+ }
18
+ /** Construction hooks for one controller. */
19
+ export interface InputTriggerControllerDeps {
20
+ /** The owning session scope (event dispatch + teardown registration site). */
21
+ actx: ClientContext;
22
+ /** The session's stable host identity (the projection handed to sources). */
23
+ sessionId: SessionId;
24
+ /** Root-service roster view. */
25
+ roster: SourceRoster;
26
+ }
27
+ /**
28
+ * Per-session trigger pipeline state and orchestration. All mutation stays
29
+ * inside; MenuView renders from {@link InputTriggerController.menu} and routes
30
+ * pointer picks back through {@link InputTriggerController.pick}.
31
+ */
32
+ export declare class InputTriggerController {
33
+ private readonly deps;
34
+ /** Menu state store (per-session; survives session switches, dies with the scope). */
35
+ readonly menu: SnapshotStore<MenuState>;
36
+ /**
37
+ * Name of the source opened through the programmatic launcher, or null for
38
+ * trigger-detected/closed menus. Composer chrome subscribes to this store
39
+ * for the launcher's expanded state without owning a second menu model.
40
+ */
41
+ readonly launcher: SnapshotStore<string | null>;
42
+ /**
43
+ * Aggregated hot reference lexicon, grouped by trigger (plain-text-reference decision;
44
+ * see .agents/notes/implemented/architecture/2026-07-25-web-input-machine-and-slash-pipeline.md):
45
+ * sources implementing the lexicon hook are polled with the session
46
+ * projection; undefined answers (roll not hot yet) are skipped; multiple
47
+ * sources on one trigger concatenate in registration order. A snapshot
48
+ * store because rolls change asynchronously (catalog settles, children
49
+ * spawn/exit) — render-side consumers subscribe instead of re-reading a
50
+ * mutable answer.
51
+ */
52
+ readonly lexicon: SnapshotStore<ReadonlyMap<TriggerChar, readonly string[]>>;
53
+ /** The authoritative hit: single truth for span CAS material (menu snapshot never carries it alone). */
54
+ private hit;
55
+ private fetch;
56
+ private disposed;
57
+ /** Per-source lexicon unsubscribers (sources without the hook never enter). */
58
+ private readonly lexiconOffs;
59
+ constructor(deps: InputTriggerControllerDeps);
60
+ /**
61
+ * Feed a draft/caret change through trigger detection and drive the menu.
62
+ * @param draft - full draft text.
63
+ * @param caret - caret offset into `draft`.
64
+ * @param guard - availability tier derived from the input phase.
65
+ * @param draftRev - the input machine's current draft revision, stamped
66
+ * into the hit span for pick-time CAS.
67
+ */
68
+ track(draft: string, caret: number, guard: TriggerGuard, draftRev: number): void;
69
+ /**
70
+ * Toggle a menu containing exactly one registered source. The supplied hit
71
+ * is a synthetic selection span rather than a typed trigger token, but
72
+ * picks deliberately reuse the ordinary source callback and scoped input
73
+ * mutation pipeline.
74
+ * @param source - registered source name under `hit.trigger`.
75
+ * @param hit - synthetic hit carrying position and pick-time draft CAS.
76
+ */
77
+ toggleSource(source: string, hit: TriggerHit): void;
78
+ /**
79
+ * Pointer pick from MenuView: route the clicked candidate through onPick
80
+ * and execute claim/insert outcomes via the scoped input events.
81
+ * @param source - source (group) name.
82
+ * @param index - candidate index within the group.
83
+ */
84
+ pick(source: string, index: number): void;
85
+ /**
86
+ * Keyboard arbitration while the menu is open.
87
+ * @param key - intercepted key.
88
+ * @param composing - inside IME composition: everything passes.
89
+ * @returns consumed / pick-highlighted / pass.
90
+ */
91
+ arbitrate(key: ArbitrateKey, composing: boolean): ArbitrateOutcome;
92
+ /**
93
+ * Space adjudication over the just-completed leading token: polls sources'
94
+ * matchSpace (hot state, synchronous) and dispatches the outcome itself.
95
+ * @returns true when a claim/insert was actually applied by the input —
96
+ * the caller preventDefaults exactly then.
97
+ */
98
+ onSpace(): boolean;
99
+ /**
100
+ * Serialize one reference occurrence to its model form via the owning
101
+ * source's codec (prompt serialization: registry → explicit
102
+ * call → await). Owner missing or codec-less rejects — the submit attempt
103
+ * blocks instead of silently downgrading to the clipboard text.
104
+ * @param source - owning source name.
105
+ * @param ref - owner-scoped reference id.
106
+ * @param signal - the submit attempt's abort signal.
107
+ * @returns the model representation (e.g. `<skill>name</skill>`).
108
+ */
109
+ serializeReference(source: string, ref: string, signal: AbortSignal): Promise<string>;
110
+ /**
111
+ * Enter last adjudication: polls sources' matchEnter in registration
112
+ * order, first non-undefined wins. The outcome returns to the caller (the
113
+ * input machine applies it inside the same submit attempt — no event).
114
+ * @param line - trimmed draft; the leading char selects the trigger roster.
115
+ * @param signal - attempt-scoped abort from the input machine.
116
+ * @param envelope - non-text submission state accompanying the draft.
117
+ * @returns the winning outcome or undefined (default sink). Rejects when a
118
+ * polled source's warmup fails or the winning source refuses the envelope —
119
+ * the caller must not silently downgrade.
120
+ */
121
+ adjudicate(line: string, signal: AbortSignal, envelope: SubmitEnvelope): Promise<PickOutcome>;
122
+ /**
123
+ * Drop the menu group of a disposed source (root registry change notification).
124
+ * @param source - the source whose registration was disposed.
125
+ */
126
+ sourceRemoved(source: InputTriggerSource): void;
127
+ /**
128
+ * Admit a source registered after this controller's birth (root registry
129
+ * change notification): warm it and fold its roll into the live lexicon —
130
+ * the constructor-time prewarm covers only the roster present at scope
131
+ * birth.
132
+ * @param source - the newly registered source.
133
+ */
134
+ sourceAdded(source: InputTriggerSource): void;
135
+ /** External dismiss (e.g. pointer outside the composer area). */
136
+ dismiss(): void;
137
+ /** Scope teardown: close and abort (the service deletes the map entry). */
138
+ dispose(): void;
139
+ /** The session projection handed to sources (agent-backed identity; constant per scope). */
140
+ private project;
141
+ /** Execute a claim/insert/text outcome via the scoped input events (actx as dispatch subject); true = the input applied it. */
142
+ private execute;
143
+ /** Re-poll every lexicon-bearing source and publish the aggregated rolls (see the store doc). */
144
+ private refreshLexicon;
145
+ /** Wire one source's lexicon invalidation channel into refresh (hookless or roll-less sources never notify). */
146
+ private watchLexicon;
147
+ /** Launch the candidate fetch for one hit generation, superseding the previous one. */
148
+ private fetchCandidates;
149
+ private stopFetch;
150
+ private clearLauncher;
151
+ private reduce;
152
+ }
153
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1,32 @@
1
+ import type { ClientContext } from '@hydraharness/harness-client-runtime/client';
2
+ import { type MenuKey } from './locales.ts';
3
+ export { InputTriggerService } from './service.ts';
4
+ export { InputTriggerController } from './controller.ts';
5
+ export type { InputTriggerControllerDeps, SourceRoster } from './controller.ts';
6
+ export type { MenuViewInjected } from './slots.ts';
7
+ export type { MenuViewProps } from './MenuView.tsx';
8
+ export type { MenuKey } from './locales.ts';
9
+ export type { ArbitrateKey, ArbitrateOutcome, BeginCommandRequest, CandidateRequest, ClientSessionContext, CommandClaim, ConsumeTokenRequest, InsertReferenceRequest, PickOutcome, PickVia, ReferenceCodec, ReferenceInsert, InputTriggerCandidate, InputTriggerPick, InputTriggerSource, SubmitEnvelope, SubmitImageAttachment, SubmitOutcome, TokenSpan, TriggerChar, TriggerGuard, TriggerPosition, } from '../types.ts';
10
+ export type { DetectTrigger, ExactMatch, MenuEvent, MenuReduce, MenuState, TriggerHit } from '../core/contract.ts';
11
+ export type { InputTriggerServiceContract } from './contract.ts';
12
+ declare module '@hydraharness/cordis' {
13
+ interface Context {
14
+ /** The outward face only; the concrete service stays inside this plugin. */
15
+ inputTriggers: import('./contract.ts').InputTriggerServiceContract;
16
+ }
17
+ }
18
+ declare module '@hydraharness/harness-client-ui-slots' {
19
+ interface LocaleNamespaceMap {
20
+ /** The candidate menu's copy: group titles keyed by source name, the pending row, and the listbox aria. */
21
+ 'slash.menu': MenuKey;
22
+ }
23
+ }
24
+ /** Required services: controller resolution reads the session scope tree; the menu copy is localized. */
25
+ export declare const inject: string[];
26
+ /**
27
+ * Client plugin body: mount the service, then register MenuView into the
28
+ * input overlay once its declarer is up.
29
+ * @param ctx - client root context.
30
+ */
31
+ export declare function apply(ctx: ClientContext): void;
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `slash.menu` namespace dictionaries: group titles keyed by source name
3
+ * (the lookup chain returns the key itself, so an unknown source shows its
4
+ * raw name), the pending row, and the listbox aria label.
5
+ */
6
+ /** English dictionary (the key-set source of truth). */
7
+ export declare const en: {
8
+ command: string;
9
+ skill: string;
10
+ subagent: string;
11
+ loading: string;
12
+ 'suggestions.aria': string;
13
+ };
14
+ /** The slash.menu namespace key union. */
15
+ export type MenuKey = keyof typeof en;
16
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * InputTriggerService (`ctx.inputTriggers`): the root half of the trigger pipeline — the
3
+ * stateless source registry plus the per-session controller map. Every piece
4
+ * of mutable interaction state (hit, menu, fetch) lives on the
5
+ * {@link InputTriggerController}; the service only registers sources, resolves
6
+ * controllers by session scope, and relays roster changes.
7
+ */
8
+ import { Service } from '@hydraharness/cordis';
9
+ import type { Context } from '@hydraharness/cordis';
10
+ import type { ClientContext } from '@hydraharness/harness-client-runtime/client';
11
+ import type { InputTriggerSource } from '../types.ts';
12
+ import { InputTriggerController } from './controller.ts';
13
+ import type { InputTriggerServiceContract } from './contract.ts';
14
+ /** The `ctx.inputTriggers` trigger pipeline service (root registry + controller resolution). */
15
+ export declare class InputTriggerService extends Service implements InputTriggerServiceContract {
16
+ static inject: string[];
17
+ private readonly live;
18
+ /**
19
+ * @param ctx - owning root context (the service registers itself as `slash`).
20
+ */
21
+ constructor(ctx: Context);
22
+ /**
23
+ * Register one trigger source. Live session controllers are notified so a
24
+ * source arriving after scope birth still warms and joins the lexicon.
25
+ * @param src - the source; (trigger, name) must be unique — duplicates throw.
26
+ * @returns the disposer (callers wrap registration in ctx.effect). Disposal
27
+ * while a controller shows the source's menu group drops that group.
28
+ */
29
+ registerSource(src: InputTriggerSource): () => void;
30
+ /**
31
+ * Resolve the per-session controller for one session scope (lazy; the
32
+ * scope disposer removes and disposes it). Construction warms the source
33
+ * roster once — sessions are always agent-backed, so scope birth is the
34
+ * single prewarm moment.
35
+ * @param actx - session-scope ctx.
36
+ * @returns the resident controller.
37
+ */
38
+ sessionOf(actx: ClientContext): InputTriggerController;
39
+ private sessions;
40
+ }
41
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1,31 @@
1
+ import type { SnapshotStore } from '@hydraharness/harness-client-runtime/client';
2
+ import type { MenuState } from '../core/contract.ts';
3
+ declare module '@hydraharness/harness-client-ui-slots' {
4
+ interface SlotMap {
5
+ /**
6
+ * The InputBar floating overlay anchor: MenuView (this package) and the
7
+ * popupSelect shell (ui-commands) contribute list entries; each reads its
8
+ * own store and renders null while closed. Declared (children table) by
9
+ * ui-conversation's composer entry; the anchor hides with the input
10
+ * under a takeover.
11
+ */
12
+ 'conversation.input.overlay': {
13
+ kind: 'list';
14
+ scope: 'session';
15
+ };
16
+ }
17
+ }
18
+ /** Injected business face of the MenuView overlay entry (copy rides the standard locale seat, not this face). */
19
+ export interface MenuViewInjected {
20
+ /** The service's menu state store (read-only here; MenuView subscribes). */
21
+ menu: SnapshotStore<MenuState>;
22
+ /**
23
+ * Pointer pick routed back through the service pipeline.
24
+ * @param source - source (group) name.
25
+ * @param index - candidate index within the group.
26
+ */
27
+ onPick: (source: string, index: number) => void;
28
+ /** Dismiss the menu (external pointer outside the composer area). */
29
+ onDismiss: () => void;
30
+ }
31
+ //# sourceMappingURL=slots.d.ts.map
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Frozen pure-core contract: trigger detection and
3
+ * menu reduction, zero React / DOM / cordis. Types only — implementations
4
+ * live in sibling modules annotated with these
5
+ * aliases; the service shell wires them to ctx.
6
+ */
7
+ import type { InputTriggerCandidate, TokenSpan, TriggerChar, TriggerGuard, TriggerPosition } from '../types.ts';
8
+ /** A detected trigger token under the caret. */
9
+ export interface TriggerHit {
10
+ readonly trigger: TriggerChar;
11
+ /** Text between the trigger char and the caret, live-filtered. */
12
+ readonly query: string;
13
+ /** True only for an open quoted `@file` token. */
14
+ readonly quoted: boolean;
15
+ /** leading = draft trimmed (whitespace incl. newlines) starts with the token. */
16
+ readonly position: TriggerPosition;
17
+ /** Token span; draftRev injected by the caller. */
18
+ readonly span: TokenSpan;
19
+ }
20
+ /**
21
+ * Detect a trigger token at the caret under the given guard tier.
22
+ * `@` uses the shared file-reference start/whitespace grammar; `/` accepts
23
+ * punctuation boundaries with URL carve-outs. `user@host` and URL `/` do not
24
+ * trigger.
25
+ * Returns null when no trigger is live at the caret.
26
+ */
27
+ export type DetectTrigger = (draft: string, caret: number, guard: TriggerGuard) => TriggerHit | null;
28
+ /** Menu state: one group per source; empty ready groups auto-close the menu. */
29
+ export interface MenuState {
30
+ readonly open: boolean;
31
+ readonly hit: TriggerHit | null;
32
+ /** Monotonic per-hit generation; stale source settlements are dropped. */
33
+ readonly generation: number;
34
+ readonly groups: readonly {
35
+ readonly source: string;
36
+ /** False when candidate section rows own all visible group labeling. */
37
+ readonly showGroupTitle?: boolean;
38
+ readonly status: 'pending' | 'ready';
39
+ readonly items: readonly InputTriggerCandidate[];
40
+ }[];
41
+ readonly highlight: {
42
+ readonly source: string;
43
+ readonly index: number;
44
+ } | null;
45
+ }
46
+ /** Menu reduction events. Source failure = silent group removal (log only; no error UI tier). */
47
+ export type MenuEvent = {
48
+ readonly type: 'hit';
49
+ readonly hit: TriggerHit | null;
50
+ } | {
51
+ readonly type: 'source-settled';
52
+ readonly generation: number;
53
+ readonly source: string;
54
+ readonly items?: readonly InputTriggerCandidate[];
55
+ } | {
56
+ readonly type: 'source-failed';
57
+ readonly generation: number;
58
+ readonly source: string;
59
+ } | {
60
+ readonly type: 'move';
61
+ readonly dir: 1 | -1;
62
+ } | {
63
+ readonly type: 'close';
64
+ };
65
+ /** Pure menu reducer; returns the same reference when the event is stale or a no-op. */
66
+ export type MenuReduce = (state: MenuState, ev: MenuEvent) => MenuState;
67
+ /**
68
+ * Exact-name lookup in one source's ready group; null when absent or the
69
+ * group is not ready.
70
+ */
71
+ export type ExactMatch = (groups: MenuState['groups'], source: string, name: string) => InputTriggerCandidate | null;
72
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1,19 @@
1
+ import type { DetectTrigger } from './contract.ts';
2
+ /**
3
+ * Detect a trigger token at the caret. `@` first uses the shared grammar,
4
+ * including an open quoted token that may span whitespace. Slash detection
5
+ * scans left to the first whitespace; slashes failing the word boundary are
6
+ * treated as ordinary token chars and the scan continues (URL slashes).
7
+ * Guard tiers: plain = both chars live; claimed = '/' fully suppressed,
8
+ * '@' live; frozen = none.
9
+ *
10
+ * @param draft - Full draft text.
11
+ * @param caret - Caret offset into `draft`.
12
+ * @param guard - Availability tier derived from the input phase.
13
+ * @returns The hit with `query` = trigger-to-caret slice and `span` =
14
+ * `{start: triggerIndex, end: caret}`; `span.draftRev` is a placeholder `0`
15
+ * — the calling shell stamps the real revision. Null when no trigger is
16
+ * live at the caret.
17
+ */
18
+ export declare const detectTrigger: DetectTrigger;
19
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Menu reduction pure core. One group per source;
3
+ * generation-gated settlement; empty ready groups auto-close. Zero React /
4
+ * DOM / cordis. Stale or no-op events return the same state reference so
5
+ * store subscribers skip re-renders.
6
+ *
7
+ * Roster protocol: the frozen `hit` event carries no source roster, so the
8
+ * reducer cannot invent groups. Opening from a closed state, the shell seeds
9
+ * the roster with {@link seedGroups} and then dispatches `hit`; a `hit`
10
+ * while open (query refinement) resets the existing groups to pending under
11
+ * a new generation. Auto-close and explicit close drop the groups.
12
+ */
13
+ import type { InputTriggerSource } from '../types.ts';
14
+ import type { ExactMatch, MenuReduce, MenuState } from './contract.ts';
15
+ /** Closed rest state with generation 0; store initializer and test seed. */
16
+ export declare const MENU_CLOSED: MenuState;
17
+ /**
18
+ * Replace the group roster with pending groups for `sources`, in order.
19
+ * Shell-side step before dispatching `hit` on a fresh menu open.
20
+ *
21
+ * @param state - Current menu state.
22
+ * @param sources - Sources registered for the hit trigger, in menu order.
23
+ * @returns State carrying the new pending roster; highlight cleared.
24
+ */
25
+ export declare function seedGroups(state: MenuState, sources: readonly Pick<InputTriggerSource, 'name' | 'showGroupTitle'>[]): MenuState;
26
+ /**
27
+ * Pure menu reducer. `hit` opens a new generation over the seeded roster
28
+ * (null hit closes); `source-settled` outside the current generation, the
29
+ * open menu, or the roster is dropped; a settlement or failure leaving every
30
+ * group ready-and-empty (or no groups) auto-closes; `source-failed` silently
31
+ * removes the group (the shell logs); `move` cycles the highlight across
32
+ * ready items.
33
+ *
34
+ * @param state - Current menu state.
35
+ * @param ev - Menu event.
36
+ * @returns Next state; the same reference when stale or a no-op.
37
+ */
38
+ export declare const menuReduce: MenuReduce;
39
+ /**
40
+ * Exact-name lookup in one source's ready group.
41
+ *
42
+ * @param groups - Menu groups.
43
+ * @param source - Source (group) name.
44
+ * @param name - Candidate name to match exactly.
45
+ * @returns The candidate, or null when the group is absent, not ready, or
46
+ * has no candidate of that name.
47
+ */
48
+ export declare const exactMatch: ExactMatch;
49
+ //# sourceMappingURL=menu.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Slash trigger plugin, node half. Pure UI plugin: the empty apply exists so
3
+ * the plugin appears in the host cordis.yml / Loader; the browser half ships
4
+ * via exports["./client"], discovered through the package.json hydra.client
5
+ * declaration.
6
+ */
7
+ /** Host plugin body — no host-side behavior for the slash trigger plugin. */
8
+ export declare function apply(): void;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@hydraharness/harness-client-ui-input-trigger`.
3
+ * @module @hydraharness/harness-client-ui-input-trigger/invariant
4
+ */
5
+ import type { Context } from '@hydraharness/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "client-ui-input-trigger-invariant";
8
+ /** Service required before the companion can reserve package ownership. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register this package's invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant service.
13
+ * @returns the installed registration's disposer after setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map