@hydraharness/harness-client-ui-agent-preset 0.1.1-rc.6

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.
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Agent-preset default-settings controller.
3
+ *
4
+ * Options and the current default both come from one `agentPreset.list` call:
5
+ * the roster already reports which id a session with no explicit choice gets,
6
+ * so the row needs no schema introspection. Writes target the settings
7
+ * namespace's `default` field, which is what the host resolves at creation.
8
+ */
9
+ import type { IApiClient } from '@hydraharness/harness-api-remotes/client';
10
+ import { type SnapshotStore } from '@hydraharness/harness-client-runtime/client';
11
+ import type { SettingsDescribeFace } from '@hydraharness/harness-client-ui-settings/client';
12
+ /** The agent-preset settings namespace on the host wire. */
13
+ export declare const AGENT_PRESET_SETTINGS_NS = "agent-presets";
14
+ /**
15
+ * Human text for a rejected wire call. A transport failure rejects with an
16
+ * Error; a host or a runtime can reject with anything, and the surface still
17
+ * has to say something.
18
+ * @param error - the rejection value.
19
+ * @returns the message to show.
20
+ */
21
+ export declare function messageOf(error: unknown): string;
22
+ /**
23
+ * Persist one preset as the default for sessions created later.
24
+ *
25
+ * The default is a settings field rather than a preset property, so both the
26
+ * General row and the management section write it here — one home for which
27
+ * namespace and field the host resolves at session creation.
28
+ * @param api - the settings wire face.
29
+ * @param id - the preset to make default.
30
+ * @returns the failure message, or undefined once the write landed.
31
+ */
32
+ export declare function writeDefaultPreset(api: Pick<IApiClient, 'settings'>, id: string): Promise<string | undefined>;
33
+ /** One selectable preset. */
34
+ export interface AgentPresetOption {
35
+ /** Preset id, written to Settings and the label's fallback. */
36
+ id: string;
37
+ /** Whether the preset ships with the deployment or was authored locally. */
38
+ trust: 'system' | 'user';
39
+ /** Display name the preset published, absent when it published none. */
40
+ name?: string;
41
+ /** One sentence on what the preset is for. */
42
+ description?: string;
43
+ }
44
+ /** One roster entry exactly as the host reports it. */
45
+ export interface RosterPreset {
46
+ /** Preset id and directory name. */
47
+ id: string;
48
+ /** Whether the preset ships with the deployment or was authored locally. */
49
+ trust: 'system' | 'user';
50
+ /** Whether a session that names no preset gets this one. */
51
+ isDefault: boolean;
52
+ /** Display name the preset published, absent when it published none. */
53
+ name?: string;
54
+ /** One sentence on what the preset is for. */
55
+ description?: string;
56
+ /** Why the preset cannot compose a session, absent when it can. */
57
+ broken?: string;
58
+ }
59
+ /** The roster the host answered with. */
60
+ export interface RosterValue {
61
+ /** Every preset the deployment composes, in the order the host lists them. */
62
+ presets: readonly RosterPreset[];
63
+ /** Whether this browser may author presets at all. */
64
+ authorable: boolean;
65
+ /** Whether the host can open a preset directory on a native desktop. */
66
+ hasDocument: boolean;
67
+ }
68
+ /** The roster, or the message to show in its place. */
69
+ export type RosterRead = {
70
+ ok: true;
71
+ value: RosterValue;
72
+ } | {
73
+ ok: false;
74
+ error: string;
75
+ };
76
+ /**
77
+ * Read the roster, folding both refusal shapes into one message.
78
+ *
79
+ * The wire refuses in two ways — the transport rejects, or it answers an
80
+ * `ok: false` envelope — and every surface treats them identically. Folding
81
+ * them here keeps each store's `load` about what it does with a roster rather
82
+ * than about how the call can fail.
83
+ * @param api - the agent-preset wire face.
84
+ * @returns the roster, or the message to show in its place.
85
+ */
86
+ export declare function readRoster(api: Pick<IApiClient, 'agentPresets'>): Promise<RosterRead>;
87
+ /**
88
+ * Serialize roster refreshes, coalescing invalidations during a read into a
89
+ * rerun before publishing. Callers settle after the latest requested refresh.
90
+ * @param api - the agent-preset wire face.
91
+ * @param store - the surface's own snapshot store.
92
+ * @param accept - publish a successful roster into the surface's snapshot.
93
+ * @returns the refresh callback owned by this controller.
94
+ */
95
+ export declare function createRosterLoader<S extends {
96
+ status: string;
97
+ error: string | null;
98
+ }>(api: Pick<IApiClient, 'agentPresets'>, store: SnapshotStore<S>, accept: (roster: RosterValue) => void | Promise<void>): () => Promise<void>;
99
+ /**
100
+ * The roster entries as the pickers render them: healthy presets only.
101
+ *
102
+ * The chip and the row exist to choose the NEXT session's composition, and a
103
+ * broken preset cannot compose one — offering it would defer the discovery
104
+ * of that fact to a failed session start. The management section renders the
105
+ * full roster (broken rows included) from its own store instead.
106
+ *
107
+ * The chip, the row, and the management section all show the same facts, and
108
+ * `exactOptionalPropertyTypes` makes "absent" and "present as undefined"
109
+ * different shapes — so the spread dance belongs in one place rather than
110
+ * once per store.
111
+ * @param presets - the roster the host answered with.
112
+ * @returns one option per selectable preset, in roster order.
113
+ */
114
+ export declare function presetOptions(presets: readonly {
115
+ id: string;
116
+ trust: 'system' | 'user';
117
+ name?: string;
118
+ description?: string;
119
+ broken?: string;
120
+ }[]): AgentPresetOption[];
121
+ /** Agent-preset settings-row snapshot. */
122
+ export interface AgentPresetSettingsState {
123
+ status: 'idle' | 'loading' | 'ready' | 'saving' | 'unavailable' | 'error';
124
+ error: string | null;
125
+ /**
126
+ * Whether this browser may persist the choice at all. `settings.describe` is
127
+ * loopback-only and reports a read-only provider as `writable: false`; the
128
+ * row then shows the current default and disables the control rather than
129
+ * offering a write the gateway will refuse.
130
+ */
131
+ writable: boolean;
132
+ currentValue: string;
133
+ options: readonly AgentPresetOption[];
134
+ }
135
+ /** Reads the roster and persists the chosen default. */
136
+ export declare class AgentPresetSettingsController {
137
+ private readonly api;
138
+ private readonly describeFace;
139
+ /** Row snapshot the renderer subscribes to. */
140
+ readonly store: SnapshotStore<AgentPresetSettingsState>;
141
+ private readonly refresh;
142
+ /**
143
+ * @param api - the agent-preset and settings wire faces (roster and default write).
144
+ * @param describeFace - the shared mirror's describe face (writability source).
145
+ */
146
+ constructor(api: IApiClient, describeFace: SettingsDescribeFace);
147
+ private set;
148
+ /**
149
+ * Load the roster. An empty roster means the deployment composes no
150
+ * presets, which is a valid deployment rather than a failure — the row
151
+ * reports `unavailable` and renders nothing.
152
+ * @returns once the snapshot reflects the host.
153
+ */
154
+ load(): Promise<void>;
155
+ private acceptRoster;
156
+ /**
157
+ * Persist one preset as the default for sessions created later. Running
158
+ * sessions keep the composition they were created with, so this never
159
+ * disturbs work in progress.
160
+ * @param id - the preset to make default.
161
+ * @returns once the write settled and the roster was re-read.
162
+ */
163
+ select(id: string): Promise<void>;
164
+ }
165
+ //# sourceMappingURL=settings-store.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Agent-preset surface plugin, node half. The empty apply exists so the plugin
3
+ * appears in the host cordis.yml / Loader; the browser half ships the
4
+ * General-settings row through exports["./client"], discovered from the
5
+ * package.json hydra.client declaration.
6
+ */
7
+ /** Host plugin body — no host-side behavior for this surface 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-agent-preset`.
3
+ * @module @hydraharness/harness-client-ui-agent-preset/invariant
4
+ */
5
+ import type { Context } from '@hydraharness/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "client-ui-agent-preset-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
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@hydraharness/harness-client-ui-agent-preset",
3
+ "description": "Agent-preset surfaces: the default for later sessions, this session's seat, and the composition editor",
4
+ "version": "0.1.1-rc.6",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/MaiHongPhong1902/Hydra-Harness.git",
11
+ "directory": "packages/client/ui-agent-preset"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./invariant": {
22
+ "types": "./lib/types/invariant.d.ts",
23
+ "default": "./lib/invariant.js"
24
+ },
25
+ "./client": {
26
+ "types": "./lib/types/client/index.d.ts",
27
+ "default": "./lib/client.js"
28
+ },
29
+ "./src/*": "./src/*",
30
+ "./package.json": "./package.json"
31
+ },
32
+ "hydra": {
33
+ "plugin": {
34
+ "application": "Select the preset for a session and edit the composition used by future sessions."
35
+ },
36
+ "client": {
37
+ "inject": [
38
+ "@hydraharness/harness-client-connection",
39
+ "@hydraharness/harness-client-locale",
40
+ "@hydraharness/harness-client-runtime",
41
+ "@hydraharness/harness-client-ui-conversation",
42
+ "@hydraharness/harness-client-ui-settings",
43
+ "@hydraharness/harness-api-remotes"
44
+ ],
45
+ "platform": "web"
46
+ }
47
+ },
48
+ "license": "MIT",
49
+ "peerDependencies": {
50
+ "@hydraharness/cordis": "^4.0.2",
51
+ "@hydraharness/harness-api-remotes": "^0.1.1-rc.6",
52
+ "@hydraharness/harness-client-connection": "^0.1.1-rc.6",
53
+ "@hydraharness/harness-client-runtime": "^0.1.1-rc.6",
54
+ "@hydraharness/harness-client-ui-settings": "^0.1.1-rc.6",
55
+ "@hydraharness/harness-client-ui-conversation": "^0.1.1-rc.6",
56
+ "@hydraharness/harness-client-locale": "^0.1.1-rc.6",
57
+ "@hydraharness/harness-invariants": "^0.1.1-rc.6"
58
+ },
59
+ "devDependencies": {
60
+ "@types/react": "~18.3.1",
61
+ "react": "^18.2.0",
62
+ "@hydraharness/harness-api-remotes": "^0.1.1-rc.6",
63
+ "@hydraharness/harness-client-locale": "^0.1.1-rc.6",
64
+ "@hydraharness/harness-client-connection": "^0.1.1-rc.6",
65
+ "@hydraharness/harness-client-runtime": "^0.1.1-rc.6",
66
+ "@hydraharness/harness-client-ui-conversation": "^0.1.1-rc.6",
67
+ "@hydraharness/harness-client-test-runtime": "^0.1.1-rc.6",
68
+ "@hydraharness/harness-client-ui-settings": "^0.1.1-rc.6",
69
+ "@hydraharness/harness-client-ui-primitives": "^0.1.1-rc.6",
70
+ "@hydraharness/harness-invariants": "^0.1.1-rc.6",
71
+ "@hydraharness/harness-client-ui-slots": "^0.1.1-rc.6",
72
+ "@hydraharness/cordis": "^4.0.2"
73
+ },
74
+ "files": [
75
+ "lib/index.js",
76
+ "lib/invariant.js",
77
+ "lib/client.js",
78
+ "lib/types/**/*.d.ts"
79
+ ],
80
+ "scripts": {
81
+ "bundle": "tsdown",
82
+ "watch": "tsdown --watch"
83
+ }
84
+ }