@agimon-ai/po-minor-mode 0.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/apiContracts.cjs +17 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +13 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/catalog-CgwaiiVw.cjs +227 -0
- package/dist/catalog-CgwaiiVw.cjs.map +1 -0
- package/dist/catalog-CuwwCBW1.mjs +222 -0
- package/dist/catalog-CuwwCBW1.mjs.map +1 -0
- package/dist/catalog.cjs +3 -0
- package/dist/catalog.d.mts +14 -0
- package/dist/catalog.d.mts.map +1 -0
- package/dist/catalog.mjs +2 -0
- package/dist/command-B5HZmmyU.cjs +11 -0
- package/dist/command-B5HZmmyU.cjs.map +1 -0
- package/dist/command-BvYpwiin.mjs +6 -0
- package/dist/command-BvYpwiin.mjs.map +1 -0
- package/dist/command-DNWSjDOI.cjs +151 -0
- package/dist/command-DNWSjDOI.cjs.map +1 -0
- package/dist/command-DWrT7rjd.mjs +128 -0
- package/dist/command-DWrT7rjd.mjs.map +1 -0
- package/dist/command.cjs +8 -0
- package/dist/command.d.mts +6 -0
- package/dist/command.d.mts.map +1 -0
- package/dist/command.mjs +3 -0
- package/dist/extensions/server.cjs +135 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +130 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/headlessCommand-CH18O5s-.mjs +53 -0
- package/dist/headlessCommand-CH18O5s-.mjs.map +1 -0
- package/dist/headlessCommand-Df1-11qO.cjs +58 -0
- package/dist/headlessCommand-Df1-11qO.cjs.map +1 -0
- package/dist/index-BXJERXMH.d.mts +24 -0
- package/dist/index-BXJERXMH.d.mts.map +1 -0
- package/dist/index-DfF0dV4u.d.mts +31 -0
- package/dist/index-DfF0dV4u.d.mts.map +1 -0
- package/dist/index-n9xqlkww.d.mts +8 -0
- package/dist/index-n9xqlkww.d.mts.map +1 -0
- package/dist/index.cjs +98 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +42 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +55 -0
- package/dist/index.mjs.map +1 -0
- package/dist/minorModeCommand.cjs +5 -0
- package/dist/minorModeCommand.d.mts +2 -0
- package/dist/minorModeCommand.mjs +2 -0
- package/dist/mode-BehVDmjF.cjs +444 -0
- package/dist/mode-BehVDmjF.cjs.map +1 -0
- package/dist/mode-Dlik4anf.mjs +241 -0
- package/dist/mode-Dlik4anf.mjs.map +1 -0
- package/dist/mode-dwaC4pa1.d.mts +492 -0
- package/dist/mode-dwaC4pa1.d.mts.map +1 -0
- package/dist/mode.cjs +36 -0
- package/dist/mode.d.mts +2 -0
- package/dist/mode.mjs +2 -0
- package/dist/modeDefinition-BcqEwTzh.mjs +46 -0
- package/dist/modeDefinition-BcqEwTzh.mjs.map +1 -0
- package/dist/modeDefinition-BtgwqXMo.cjs +51 -0
- package/dist/modeDefinition-BtgwqXMo.cjs.map +1 -0
- package/dist/modeDefinition.cjs +3 -0
- package/dist/modeDefinition.d.mts +2 -0
- package/dist/modeDefinition.mjs +2 -0
- package/dist/owner-BbCQufLu.cjs +14 -0
- package/dist/owner-BbCQufLu.cjs.map +1 -0
- package/dist/owner-Bs55c_qE.mjs +9 -0
- package/dist/owner-Bs55c_qE.mjs.map +1 -0
- package/dist/owner.cjs +3 -0
- package/dist/owner.d.mts +2 -0
- package/dist/owner.mjs +2 -0
- package/dist/projection-CuqNhHKI.mjs +47 -0
- package/dist/projection-CuqNhHKI.mjs.map +1 -0
- package/dist/projection-DClKNv5Z.cjs +58 -0
- package/dist/projection-DClKNv5Z.cjs.map +1 -0
- package/dist/projection.cjs +4 -0
- package/dist/projection.d.mts +12 -0
- package/dist/projection.d.mts.map +1 -0
- package/dist/projection.mjs +2 -0
- package/dist/reloadHandoff.cjs +57 -0
- package/dist/reloadHandoff.cjs.map +1 -0
- package/dist/reloadHandoff.d.mts +11 -0
- package/dist/reloadHandoff.d.mts.map +1 -0
- package/dist/reloadHandoff.mjs +54 -0
- package/dist/reloadHandoff.mjs.map +1 -0
- package/dist/validation-BdLqKRWT.mjs +81 -0
- package/dist/validation-BdLqKRWT.mjs.map +1 -0
- package/dist/validation-CqrICENK.cjs +104 -0
- package/dist/validation-CqrICENK.cjs.map +1 -0
- package/package.json +142 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-CuwwCBW1.mjs","names":[],"sources":["../src/services/catalog/index.ts"],"sourcesContent":["import type { DoomExtensionContext } from '@agimon-ai/po-core/config';\nimport { DoomProtocolError } from '@agimon-ai/po-core/protocol';\n\nimport {\n MINOR_MODE_ACTION_TIMEOUT_MS,\n MINOR_MODE_CATALOG_SOURCE,\n MINOR_MODE_ERROR_CODE,\n MINOR_MODE_MAX_RECORDS,\n type MinorModeActionRequest,\n type MinorModeActionResponse,\n type MinorModeCatalogService,\n type MinorModeCatalogSnapshot,\n type MinorModeOwnerDefinition,\n type MinorModeOwnerHandle,\n type MinorModeRecord,\n type MinorModeRegistrationRef,\n type MinorModeSessionKind,\n} from '../../schemas/mode';\nimport { minorModeKey, validateMinorModeActionArguments, validateMinorModeDefinition } from '../validation';\n\nexport interface MinorModeCatalogHostOptions<ExtensionContext extends DoomExtensionContext = DoomExtensionContext> {\n sessionKind: MinorModeSessionKind;\n context: ExtensionContext;\n actionTimeoutMs?: number;\n restoreSnapshot?: MinorModeCatalogSnapshot;\n onRestorationError?(error: unknown): void;\n routeInvocation?(\n request: MinorModeActionRequest,\n requesterSource: string,\n invoke: () => Promise<MinorModeActionResponse>,\n ): Promise<MinorModeActionResponse>;\n}\n\ninterface ActiveOwner {\n readonly token: symbol;\n readonly definition: MinorModeOwnerDefinition<DoomExtensionContext>;\n record: MinorModeRecord;\n readonly operations: Set<AbortController>;\n}\n\ninterface PendingOperation {\n readonly requesterSource: string;\n readonly request: MinorModeActionRequest;\n readonly promise: Promise<MinorModeActionResponse>;\n}\n\nfunction protocolError(code: string, message: string, retryable = false): DoomProtocolError {\n return new DoomProtocolError({ code, message, retryable });\n}\n\nfunction registrationRef(record: MinorModeRecord): MinorModeRegistrationRef {\n return {\n source: record.descriptor.source,\n id: record.descriptor.id,\n ownerGeneration: record.ownerGeneration,\n registrationId: record.registrationId,\n };\n}\n\nfunction sameRegistration(record: MinorModeRecord, ref: MinorModeRegistrationRef): boolean {\n return (\n record.descriptor.source === ref.source &&\n record.descriptor.id === ref.id &&\n record.ownerGeneration === ref.ownerGeneration &&\n record.registrationId === ref.registrationId\n );\n}\n\nfunction sameRequest(left: MinorModeActionRequest, right: MinorModeActionRequest): boolean {\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\nfunction abortError(signal: AbortSignal): DoomProtocolError {\n const timeout = signal.reason === 'minor-mode-timeout';\n return protocolError(\n timeout ? MINOR_MODE_ERROR_CODE.actionTimeout : MINOR_MODE_ERROR_CODE.actionAborted,\n timeout ? 'Minor-mode action timed out.' : 'Minor-mode action was aborted.',\n timeout,\n );\n}\n\nasync function runAbortable<T>(operation: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) throw abortError(signal);\n return new Promise<T>((resolve, reject) => {\n const aborted = (): void => reject(abortError(signal));\n signal.addEventListener('abort', aborted, { once: true });\n operation.then(resolve, reject).finally(() => signal.removeEventListener('abort', aborted));\n });\n}\n\nexport function createMinorModeCatalogHost<ExtensionContext extends DoomExtensionContext>(\n options: MinorModeCatalogHostOptions<ExtensionContext>,\n): MinorModeCatalogService {\n const generation = `${MINOR_MODE_CATALOG_SOURCE}:${crypto.randomUUID()}`;\n const actionTimeoutMs = options.actionTimeoutMs ?? MINOR_MODE_ACTION_TIMEOUT_MS;\n const owners = new Map<string, ActiveOwner>();\n const activeByMode = new Map<string, string>();\n const pending = new Map<string, PendingOperation>();\n const listeners = new Set<() => void>();\n const restoreTimers = new Set<ReturnType<typeof setTimeout>>();\n const restoreRecords = new Map<string, MinorModeRecord>(\n (options.restoreSnapshot?.modes ?? [])\n .filter(({ state }) => state.activation === 'active' || state.activation === 'activating')\n .map((record) => [minorModeKey(record.descriptor), structuredClone(record)]),\n );\n let revision = 0;\n let disposed = false;\n\n const notify = (): void => {\n revision += 1;\n for (const listener of listeners) listener();\n };\n\n const snapshot = (): MinorModeCatalogSnapshot => ({\n hostGeneration: generation,\n revision,\n modes: [...owners.values()]\n .map(({ record }) => structuredClone(record))\n .toSorted(\n (left, right) =>\n left.descriptor.order - right.descriptor.order ||\n left.descriptor.source.localeCompare(right.descriptor.source) ||\n left.descriptor.id.localeCompare(right.descriptor.id),\n ),\n });\n\n const invokeOwner = async (\n owner: ActiveOwner,\n request: MinorModeActionRequest,\n signal: AbortSignal,\n ): Promise<MinorModeActionResponse> => {\n const action = owner.record.descriptor.actions.find(({ id }) => id === request.actionId);\n const availability = owner.record.state.actions.find(({ id }) => id === request.actionId);\n if (!action) {\n throw protocolError(\n MINOR_MODE_ERROR_CODE.actionNotFound,\n `Minor mode action '${request.actionId}' was not found.`,\n );\n }\n if (!availability?.enabled) {\n throw protocolError(\n MINOR_MODE_ERROR_CODE.actionDisabled,\n availability?.disabledReason ?? `Minor mode action '${request.actionId}' is disabled.`,\n );\n }\n if (!action.contexts.includes(options.sessionKind)) {\n throw protocolError(\n MINOR_MODE_ERROR_CODE.unsupportedContext,\n `Action '${action.id}' is unavailable in ${options.sessionKind} sessions.`,\n );\n }\n validateMinorModeActionArguments(action, request.arguments);\n try {\n const result = await runAbortable(\n Promise.resolve(\n owner.definition.handleAction(request.actionId, structuredClone(request.arguments), {\n context: options.context,\n operationId: request.operationId,\n sessionKind: options.sessionKind,\n signal,\n }),\n ),\n signal,\n );\n const current = owners.get(minorModeKey(owner.record.descriptor));\n if (disposed || current !== owner) {\n throw protocolError(MINOR_MODE_ERROR_CODE.staleRegistration, 'Minor-mode owner was replaced.');\n }\n return {\n operationId: request.operationId,\n catalogRevision: revision,\n mode: structuredClone(owner.record),\n ...(result?.message ? { message: result.message } : {}),\n };\n } catch (error) {\n if (signal.aborted) throw abortError(signal);\n if (error instanceof DoomProtocolError) throw error;\n owner.definition.onError?.(error);\n throw protocolError(MINOR_MODE_ERROR_CODE.ownerFailed, error instanceof Error ? error.message : String(error));\n }\n };\n\n const invoke = (\n request: MinorModeActionRequest,\n requesterSource: string,\n signal?: AbortSignal,\n ): Promise<MinorModeActionResponse> => {\n if (disposed) {\n return Promise.reject(protocolError(MINOR_MODE_ERROR_CODE.sessionReplaced, 'Minor-mode catalog is disposed.'));\n }\n const terminal = pending.get(request.operationId);\n if (terminal) {\n if (terminal.requesterSource !== requesterSource || !sameRequest(terminal.request, request)) {\n return Promise.reject(\n protocolError(MINOR_MODE_ERROR_CODE.registrationConflict, 'Minor-mode operation id was reused.'),\n );\n }\n return terminal.promise;\n }\n const key = minorModeKey(request.mode);\n const owner = owners.get(key);\n if (!owner || !sameRegistration(owner.record, request.mode)) {\n return Promise.reject(protocolError(MINOR_MODE_ERROR_CODE.modeNotFound, 'Minor mode is unavailable.'));\n }\n if (activeByMode.has(key)) {\n return Promise.reject(protocolError(MINOR_MODE_ERROR_CODE.modeBusy, 'Minor mode already has an active action.'));\n }\n\n const controller = new AbortController();\n const onAbort = (): void => controller.abort(signal?.reason);\n signal?.addEventListener('abort', onAbort, { once: true });\n const timer = setTimeout(() => controller.abort('minor-mode-timeout'), actionTimeoutMs);\n owner.operations.add(controller);\n activeByMode.set(key, request.operationId);\n const direct = () => invokeOwner(owner, request, controller.signal);\n const promise = Promise.resolve(\n options.routeInvocation ? options.routeInvocation(request, requesterSource, direct) : direct(),\n ).finally(() => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n owner.operations.delete(controller);\n if (activeByMode.get(key) === request.operationId) activeByMode.delete(key);\n pending.delete(request.operationId);\n });\n pending.set(request.operationId, { requesterSource, request: structuredClone(request), promise });\n return promise;\n };\n\n const scheduleRestoration = (owner: ActiveOwner): void => {\n const key = minorModeKey(owner.record.descriptor);\n const previous = restoreRecords.get(key);\n restoreRecords.delete(key);\n if (!previous) return;\n const timer = setTimeout(() => {\n restoreTimers.delete(timer);\n if (disposed || owners.get(key) !== owner || owner.record.state.activation === 'active') return;\n const action = owner.record.descriptor.actions.find(({ id }) => id === 'activate');\n const availability = owner.record.state.actions.find(({ id }) => id === 'activate');\n if (!action || action.parameters.some(({ required }) => required) || !availability?.enabled) return;\n void invoke(\n {\n operationId: `minor-mode-restore:${crypto.randomUUID()}`,\n mode: registrationRef(owner.record),\n actionId: 'activate',\n arguments: {},\n },\n MINOR_MODE_CATALOG_SOURCE,\n ).catch((error: unknown) => {\n if (options.onRestorationError) options.onRestorationError(error);\n else\n queueMicrotask(() => {\n throw error instanceof Error ? error : new Error(String(error));\n });\n });\n }, 0);\n restoreTimers.add(timer);\n };\n\n return {\n generation,\n getSnapshot: snapshot,\n list: () => snapshot().modes,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n registerOwner(definition) {\n if (disposed) throw protocolError(MINOR_MODE_ERROR_CODE.sessionReplaced, 'Minor-mode catalog is disposed.');\n if (owners.size >= MINOR_MODE_MAX_RECORDS) {\n throw protocolError(MINOR_MODE_ERROR_CODE.registrationConflict, 'Minor-mode catalog capacity reached.');\n }\n const initialState = structuredClone(definition.initialState);\n const invalid = validateMinorModeDefinition(definition.descriptor, initialState);\n if (invalid) throw protocolError(MINOR_MODE_ERROR_CODE.registrationConflict, invalid);\n const key = minorModeKey(definition.descriptor);\n if (owners.has(key)) {\n throw protocolError(\n MINOR_MODE_ERROR_CODE.registrationConflict,\n `Minor mode '${definition.descriptor.source}/${definition.descriptor.id}' already has a live owner.`,\n );\n }\n const owner: ActiveOwner = {\n token: Symbol(key),\n definition: definition as unknown as MinorModeOwnerDefinition<DoomExtensionContext>,\n operations: new Set(),\n record: {\n descriptor: structuredClone(definition.descriptor),\n state: initialState,\n ownerGeneration: `${key}:${crypto.randomUUID()}`,\n registrationId: `minor-mode-registration:${crypto.randomUUID()}`,\n stateRevision: 0,\n },\n };\n owners.set(key, owner);\n notify();\n scheduleRestoration(owner);\n let ownerDisposed = false;\n const handle: MinorModeOwnerHandle = {\n getState: () => structuredClone(owner.record.state),\n publish(state) {\n if (ownerDisposed || owners.get(key) !== owner) return;\n const validation = validateMinorModeDefinition(owner.record.descriptor, state);\n if (validation) throw new Error(validation);\n owner.record = {\n ...owner.record,\n state: structuredClone(state),\n stateRevision: owner.record.stateRevision + 1,\n };\n notify();\n },\n dispose() {\n if (ownerDisposed) return;\n ownerDisposed = true;\n if (owners.get(key) !== owner) return;\n for (const controller of owner.operations) controller.abort('minor-mode-owner-disposed');\n owner.operations.clear();\n owners.delete(key);\n notify();\n },\n };\n return handle;\n },\n invoke,\n dispose() {\n if (disposed) return;\n disposed = true;\n for (const timer of restoreTimers) clearTimeout(timer);\n restoreTimers.clear();\n for (const owner of owners.values()) {\n for (const controller of owner.operations) controller.abort('minor-mode-catalog-disposed');\n owner.operations.clear();\n }\n owners.clear();\n pending.clear();\n activeByMode.clear();\n restoreRecords.clear();\n notify();\n listeners.clear();\n },\n };\n}\n"],"mappings":"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"}
|
package/dist/catalog.cjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { D as MinorModeCatalogService, O as MinorModeCatalogSnapshot, Y as MinorModeSessionKind, x as MinorModeActionResponse, y as MinorModeActionRequest } from "./mode-dwaC4pa1.mjs";
|
|
2
|
+
import { DoomExtensionContext } from "@agimon-ai/po-core/config";
|
|
3
|
+
//#region src/services/catalog/index.d.ts
|
|
4
|
+
export interface MinorModeCatalogHostOptions<ExtensionContext extends DoomExtensionContext = DoomExtensionContext> {
|
|
5
|
+
sessionKind: MinorModeSessionKind;
|
|
6
|
+
context: ExtensionContext;
|
|
7
|
+
actionTimeoutMs?: number;
|
|
8
|
+
restoreSnapshot?: MinorModeCatalogSnapshot;
|
|
9
|
+
onRestorationError?(error: unknown): void;
|
|
10
|
+
routeInvocation?(request: MinorModeActionRequest, requesterSource: string, invoke: () => Promise<MinorModeActionResponse>): Promise<MinorModeActionResponse>;
|
|
11
|
+
}
|
|
12
|
+
export declare function createMinorModeCatalogHost<ExtensionContext extends DoomExtensionContext>(options: MinorModeCatalogHostOptions<ExtensionContext>): MinorModeCatalogService;
|
|
13
|
+
//#endregion
|
|
14
|
+
//# sourceMappingURL=catalog.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.mts","names":[],"sources":["../src/services/catalog/index.ts"],"mappings":";;;iBAoBiB,4BAA4B,yBAAyB,uBAAuB;EAC3F,aAAa;EACb,SAAS;EACT;EACA,kBAAkB;EAClB,oBAAoB;EACpB,iBACE,SAAS,wBACT,yBACA,cAAc,QAAQ,2BACrB,QAAQ;;wBA4DG,2BAA2B,yBAAyB,sBAClE,SAAS,4BAA4B,oBACpC"}
|
package/dist/catalog.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/constants/command.ts
|
|
2
|
+
const MINOR_MODE_COMMAND_DESCRIPTION = "Toggle or drive minor modes";
|
|
3
|
+
//#endregion
|
|
4
|
+
Object.defineProperty(exports, "MINOR_MODE_COMMAND_DESCRIPTION", {
|
|
5
|
+
enumerable: true,
|
|
6
|
+
get: function() {
|
|
7
|
+
return MINOR_MODE_COMMAND_DESCRIPTION;
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=command-B5HZmmyU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-B5HZmmyU.cjs","names":[],"sources":["../src/constants/command.ts"],"sourcesContent":["export const MINOR_MODE_COMMAND_DESCRIPTION = 'Toggle or drive minor modes';\n"],"mappings":";AAAA,MAAa,iCAAiC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-BvYpwiin.mjs","names":[],"sources":["../src/constants/command.ts"],"sourcesContent":["export const MINOR_MODE_COMMAND_DESCRIPTION = 'Toggle or drive minor modes';\n"],"mappings":";AAAA,MAAa,iCAAiC"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
//#region src/services/command/index.ts
|
|
2
|
+
const MINOR_MODE_COMMAND = "minor";
|
|
3
|
+
const REQUESTER_SOURCE = "@agimon-ai/po/mode-catalog/ui-command";
|
|
4
|
+
function isOn(record) {
|
|
5
|
+
return record.state.activation === "active" || record.state.activation === "deactivating";
|
|
6
|
+
}
|
|
7
|
+
/** A catalog mode addressed the way a person types it: id, label, or id stem. */
|
|
8
|
+
function matchMinorMode(records, query) {
|
|
9
|
+
const needle = query.toLowerCase();
|
|
10
|
+
return records.find((record) => record.descriptor.id.toLowerCase() === needle || record.descriptor.label.toLowerCase() === needle || record.descriptor.id.toLowerCase().split(".")[0] === needle);
|
|
11
|
+
}
|
|
12
|
+
/** The actions a session of this kind can currently take on a mode. */
|
|
13
|
+
function actionsFor(record, kind) {
|
|
14
|
+
return record.descriptor.actions.filter((action) => {
|
|
15
|
+
if (!action.contexts.includes(kind)) return false;
|
|
16
|
+
return record.state.actions.find((entry) => entry.id === action.id)?.enabled !== false;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function promptArguments(ui, action) {
|
|
20
|
+
const collected = {};
|
|
21
|
+
for (const parameter of action.parameters) {
|
|
22
|
+
if (!parameter.required) continue;
|
|
23
|
+
const title = `${action.label}: ${parameter.label}`;
|
|
24
|
+
if (parameter.kind === "boolean") {
|
|
25
|
+
const value = await ui.confirm(title, parameter.description ?? "");
|
|
26
|
+
if (value === void 0) return void 0;
|
|
27
|
+
collected[parameter.name] = value;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (parameter.kind === "enum") {
|
|
31
|
+
const options = parameter.choices.map((choice) => choice.label);
|
|
32
|
+
const picked = await ui.select(title, options);
|
|
33
|
+
const choice = picked === void 0 ? void 0 : parameter.choices[options.indexOf(picked)];
|
|
34
|
+
if (!choice) return void 0;
|
|
35
|
+
collected[parameter.name] = choice.value;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const raw = await ui.input(title, parameter.description ?? "");
|
|
39
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
40
|
+
if (parameter.kind === "number") {
|
|
41
|
+
const value = Number(raw);
|
|
42
|
+
if (!Number.isFinite(value)) {
|
|
43
|
+
await ui.notify(`${parameter.label} must be a number.`, "warning");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
collected[parameter.name] = value;
|
|
47
|
+
} else collected[parameter.name] = raw;
|
|
48
|
+
}
|
|
49
|
+
return collected;
|
|
50
|
+
}
|
|
51
|
+
/** Runs the catalog command against an explicit interaction surface. */
|
|
52
|
+
async function executeMinorModeCommand(args, options) {
|
|
53
|
+
const { catalog, kind, ui } = options;
|
|
54
|
+
if (!catalog) {
|
|
55
|
+
await ui.notify("Minor modes are unavailable in this session.", "warning");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const records = catalog.list();
|
|
59
|
+
const [modeQuery, actionQuery] = args.trim().split(/\s+/).filter(Boolean);
|
|
60
|
+
let record;
|
|
61
|
+
if (modeQuery) {
|
|
62
|
+
record = matchMinorMode(records, modeQuery);
|
|
63
|
+
if (!record) {
|
|
64
|
+
const known = records.map((entry) => entry.descriptor.label.toLowerCase()).join(", ") || "none";
|
|
65
|
+
await ui.notify(`No minor mode matches "${modeQuery}". Available: ${known}.`, "warning");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
const listed = records.filter((entry) => actionsFor(entry, kind).length > 0);
|
|
70
|
+
if (listed.length === 0) {
|
|
71
|
+
await ui.notify("No minor modes are available in this session.", "info");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const labels = listed.map((entry) => `${isOn(entry) ? "[x]" : "[ ]"} ${entry.descriptor.label}: ${entry.descriptor.description}`);
|
|
75
|
+
const on = listed.filter(isOn).length;
|
|
76
|
+
const picked = await ui.select(`Minor modes (${String(on)} on)`, labels);
|
|
77
|
+
if (picked === void 0) return;
|
|
78
|
+
record = listed[labels.indexOf(picked)];
|
|
79
|
+
if (!record) return;
|
|
80
|
+
}
|
|
81
|
+
const actions = actionsFor(record, kind);
|
|
82
|
+
if (actions.length === 0) {
|
|
83
|
+
const reasons = [...new Set(record.state.actions.map((entry) => entry.disabledReason).filter((reason) => reason !== void 0 && reason.length > 0))];
|
|
84
|
+
const because = reasons.length > 0 ? ` ${reasons.join(" ")}` : "";
|
|
85
|
+
await ui.notify(`${record.descriptor.label} has no actions available in this session.${because}`, "warning");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
let action;
|
|
89
|
+
if (actionQuery) {
|
|
90
|
+
action = actions.find((entry) => entry.id.toLowerCase() === actionQuery.toLowerCase());
|
|
91
|
+
if (!action) {
|
|
92
|
+
const known = actions.map((entry) => entry.id).join(", ");
|
|
93
|
+
await ui.notify(`No "${actionQuery}" action on ${record.descriptor.label}. Available: ${known}.`, "warning");
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
} else if (actions.length === 1) action = actions[0];
|
|
97
|
+
else {
|
|
98
|
+
const labels = actions.map((entry) => `${entry.label}: ${entry.description}`);
|
|
99
|
+
const picked = await ui.select(`${record.descriptor.label} (${record.state.activation})`, labels);
|
|
100
|
+
if (picked === void 0) return;
|
|
101
|
+
action = actions[labels.indexOf(picked)];
|
|
102
|
+
}
|
|
103
|
+
if (!action) return;
|
|
104
|
+
const argumentsValue = await promptArguments(ui, action);
|
|
105
|
+
if (argumentsValue === void 0) return;
|
|
106
|
+
try {
|
|
107
|
+
const response = await catalog.invoke({
|
|
108
|
+
operationId: globalThis.crypto.randomUUID(),
|
|
109
|
+
mode: {
|
|
110
|
+
source: record.descriptor.source,
|
|
111
|
+
id: record.descriptor.id,
|
|
112
|
+
ownerGeneration: record.ownerGeneration,
|
|
113
|
+
registrationId: record.registrationId
|
|
114
|
+
},
|
|
115
|
+
actionId: action.id,
|
|
116
|
+
arguments: argumentsValue
|
|
117
|
+
}, REQUESTER_SOURCE);
|
|
118
|
+
const state = response.mode.state;
|
|
119
|
+
const detail = state.detail ? `: ${state.detail}` : "";
|
|
120
|
+
await ui.notify(response.message ?? `${record.descriptor.label} is ${state.activation}${detail}.`, "info");
|
|
121
|
+
} catch (error) {
|
|
122
|
+
await ui.notify(`${record.descriptor.label} ${action.label} failed: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
Object.defineProperty(exports, "MINOR_MODE_COMMAND", {
|
|
127
|
+
enumerable: true,
|
|
128
|
+
get: function() {
|
|
129
|
+
return MINOR_MODE_COMMAND;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
Object.defineProperty(exports, "actionsFor", {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
get: function() {
|
|
135
|
+
return actionsFor;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
Object.defineProperty(exports, "executeMinorModeCommand", {
|
|
139
|
+
enumerable: true,
|
|
140
|
+
get: function() {
|
|
141
|
+
return executeMinorModeCommand;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
Object.defineProperty(exports, "matchMinorMode", {
|
|
145
|
+
enumerable: true,
|
|
146
|
+
get: function() {
|
|
147
|
+
return matchMinorMode;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
//# sourceMappingURL=command-DNWSjDOI.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-DNWSjDOI.cjs","names":[],"sources":["../src/services/command/index.ts"],"sourcesContent":["import type {\n MinorModeActionDescriptor,\n MinorModeArguments,\n MinorModeCatalogService,\n MinorModeRecord,\n MinorModeSessionKind,\n} from '../../schemas/mode';\n\nexport const MINOR_MODE_COMMAND = 'minor';\nexport { MINOR_MODE_COMMAND_DESCRIPTION } from '../../constants/command';\nconst REQUESTER_SOURCE = '@agimon-ai/po/mode-catalog/ui-command';\n\ntype NotificationLevel = 'info' | 'warning' | 'error';\n\nexport interface MinorModeCommandPrompter {\n select(title: string, options: readonly string[]): Promise<string | undefined>;\n input(title: string, message: string): Promise<string | undefined>;\n confirm(title: string, message: string): Promise<boolean | undefined>;\n notify(message: string, level: NotificationLevel): void | Promise<void>;\n}\n\nfunction isOn(record: MinorModeRecord): boolean {\n return record.state.activation === 'active' || record.state.activation === 'deactivating';\n}\n\n/** A catalog mode addressed the way a person types it: id, label, or id stem. */\nexport function matchMinorMode(records: readonly MinorModeRecord[], query: string): MinorModeRecord | undefined {\n const needle = query.toLowerCase();\n return records.find(\n (record) =>\n record.descriptor.id.toLowerCase() === needle ||\n record.descriptor.label.toLowerCase() === needle ||\n record.descriptor.id.toLowerCase().split('.')[0] === needle,\n );\n}\n\n/** The actions a session of this kind can currently take on a mode. */\nexport function actionsFor(record: MinorModeRecord, kind: MinorModeSessionKind): MinorModeActionDescriptor[] {\n return record.descriptor.actions.filter((action) => {\n if (!action.contexts.includes(kind)) return false;\n const availability = record.state.actions.find((entry) => entry.id === action.id);\n return availability?.enabled !== false;\n });\n}\n\nasync function promptArguments(\n ui: MinorModeCommandPrompter,\n action: MinorModeActionDescriptor,\n): Promise<MinorModeArguments | undefined> {\n const collected: MinorModeArguments = {};\n for (const parameter of action.parameters) {\n if (!parameter.required) continue;\n const title = `${action.label}: ${parameter.label}`;\n if (parameter.kind === 'boolean') {\n const value = await ui.confirm(title, parameter.description ?? '');\n if (value === undefined) return undefined;\n collected[parameter.name] = value;\n continue;\n }\n if (parameter.kind === 'enum') {\n const options = parameter.choices.map((choice) => choice.label);\n const picked = await ui.select(title, options);\n const choice = picked === undefined ? undefined : parameter.choices[options.indexOf(picked)];\n if (!choice) return undefined;\n collected[parameter.name] = choice.value;\n continue;\n }\n const raw = await ui.input(title, parameter.description ?? '');\n if (raw === undefined || raw === '') return undefined;\n if (parameter.kind === 'number') {\n const value = Number(raw);\n if (!Number.isFinite(value)) {\n await ui.notify(`${parameter.label} must be a number.`, 'warning');\n return undefined;\n }\n collected[parameter.name] = value;\n } else {\n collected[parameter.name] = raw;\n }\n }\n return collected;\n}\n\nexport interface ExecuteMinorModeCommandOptions {\n catalog: MinorModeCatalogService | undefined;\n kind: MinorModeSessionKind;\n ui: MinorModeCommandPrompter;\n}\n\n/** Runs the catalog command against an explicit interaction surface. */\nexport async function executeMinorModeCommand(args: string, options: ExecuteMinorModeCommandOptions): Promise<void> {\n const { catalog, kind, ui } = options;\n if (!catalog) {\n await ui.notify('Minor modes are unavailable in this session.', 'warning');\n return;\n }\n\n const records = catalog.list();\n const [modeQuery, actionQuery] = args.trim().split(/\\s+/).filter(Boolean);\n\n let record: MinorModeRecord | undefined;\n if (modeQuery) {\n record = matchMinorMode(records, modeQuery);\n if (!record) {\n const known = records.map((entry) => entry.descriptor.label.toLowerCase()).join(', ') || 'none';\n await ui.notify(`No minor mode matches \"${modeQuery}\". Available: ${known}.`, 'warning');\n return;\n }\n } else {\n const listed = records.filter((entry) => actionsFor(entry, kind).length > 0);\n if (listed.length === 0) {\n await ui.notify('No minor modes are available in this session.', 'info');\n return;\n }\n const labels = listed.map(\n (entry) => `${isOn(entry) ? '[x]' : '[ ]'} ${entry.descriptor.label}: ${entry.descriptor.description}`,\n );\n const on = listed.filter(isOn).length;\n const picked = await ui.select(`Minor modes (${String(on)} on)`, labels);\n if (picked === undefined) return;\n record = listed[labels.indexOf(picked)];\n if (!record) return;\n }\n\n const actions = actionsFor(record, kind);\n if (actions.length === 0) {\n // The mode already said why each action is unavailable. Repeating that\n // is the difference between a dead end and an explanation: \"requires\n // an interactive session\" tells a cockpit user to reach for the TUI,\n // where the bare sentence leaves them guessing.\n const reasons = [\n ...new Set(\n record.state.actions\n .map((entry) => entry.disabledReason)\n .filter((reason): reason is string => reason !== undefined && reason.length > 0),\n ),\n ];\n const because = reasons.length > 0 ? ` ${reasons.join(' ')}` : '';\n await ui.notify(`${record.descriptor.label} has no actions available in this session.${because}`, 'warning');\n return;\n }\n\n let action: MinorModeActionDescriptor | undefined;\n if (actionQuery) {\n action = actions.find((entry) => entry.id.toLowerCase() === actionQuery.toLowerCase());\n if (!action) {\n const known = actions.map((entry) => entry.id).join(', ');\n await ui.notify(`No \"${actionQuery}\" action on ${record.descriptor.label}. Available: ${known}.`, 'warning');\n return;\n }\n } else if (actions.length === 1) {\n action = actions[0];\n } else {\n const labels = actions.map((entry) => `${entry.label}: ${entry.description}`);\n const picked = await ui.select(`${record.descriptor.label} (${record.state.activation})`, labels);\n if (picked === undefined) return;\n action = actions[labels.indexOf(picked)];\n }\n if (!action) return;\n\n const argumentsValue = await promptArguments(ui, action);\n if (argumentsValue === undefined) return;\n\n try {\n const response = await catalog.invoke(\n {\n operationId: globalThis.crypto.randomUUID(),\n mode: {\n source: record.descriptor.source,\n id: record.descriptor.id,\n ownerGeneration: record.ownerGeneration,\n registrationId: record.registrationId,\n },\n actionId: action.id,\n arguments: argumentsValue,\n },\n REQUESTER_SOURCE,\n );\n const state = response.mode.state;\n const detail = state.detail ? `: ${state.detail}` : '';\n await ui.notify(response.message ?? `${record.descriptor.label} is ${state.activation}${detail}.`, 'info');\n } catch (error) {\n await ui.notify(\n `${record.descriptor.label} ${action.label} failed: ${error instanceof Error ? error.message : String(error)}`,\n 'error',\n );\n }\n}\n"],"mappings":";AAQA,MAAa,qBAAqB;AAElC,MAAM,mBAAmB;AAWzB,SAAS,KAAK,QAAkC;CAC9C,OAAO,OAAO,MAAM,eAAe,YAAY,OAAO,MAAM,eAAe;AAC7E;;AAGA,SAAgB,eAAe,SAAqC,OAA4C;CAC9G,MAAM,SAAS,MAAM,YAAY;CACjC,OAAO,QAAQ,MACZ,WACC,OAAO,WAAW,GAAG,YAAY,MAAM,UACvC,OAAO,WAAW,MAAM,YAAY,MAAM,UAC1C,OAAO,WAAW,GAAG,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,MACzD;AACF;;AAGA,SAAgB,WAAW,QAAyB,MAAyD;CAC3G,OAAO,OAAO,WAAW,QAAQ,QAAQ,WAAW;EAClD,IAAI,CAAC,OAAO,SAAS,SAAS,IAAI,GAAG,OAAO;EAE5C,OADqB,OAAO,MAAM,QAAQ,MAAM,UAAU,MAAM,OAAO,OAAO,EAC5D,CAAC,EAAE,YAAY;CACnC,CAAC;AACH;AAEA,eAAe,gBACb,IACA,QACyC;CACzC,MAAM,YAAgC,CAAC;CACvC,KAAK,MAAM,aAAa,OAAO,YAAY;EACzC,IAAI,CAAC,UAAU,UAAU;EACzB,MAAM,QAAQ,GAAG,OAAO,MAAM,IAAI,UAAU;EAC5C,IAAI,UAAU,SAAS,WAAW;GAChC,MAAM,QAAQ,MAAM,GAAG,QAAQ,OAAO,UAAU,eAAe,EAAE;GACjE,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;GAChC,UAAU,UAAU,QAAQ;GAC5B;EACF;EACA,IAAI,UAAU,SAAS,QAAQ;GAC7B,MAAM,UAAU,UAAU,QAAQ,KAAK,WAAW,OAAO,KAAK;GAC9D,MAAM,SAAS,MAAM,GAAG,OAAO,OAAO,OAAO;GAC7C,MAAM,SAAS,WAAW,KAAA,IAAY,KAAA,IAAY,UAAU,QAAQ,QAAQ,QAAQ,MAAM;GAC1F,IAAI,CAAC,QAAQ,OAAO,KAAA;GACpB,UAAU,UAAU,QAAQ,OAAO;GACnC;EACF;EACA,MAAM,MAAM,MAAM,GAAG,MAAM,OAAO,UAAU,eAAe,EAAE;EAC7D,IAAI,QAAQ,KAAA,KAAa,QAAQ,IAAI,OAAO,KAAA;EAC5C,IAAI,UAAU,SAAS,UAAU;GAC/B,MAAM,QAAQ,OAAO,GAAG;GACxB,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG;IAC3B,MAAM,GAAG,OAAO,GAAG,UAAU,MAAM,qBAAqB,SAAS;IACjE;GACF;GACA,UAAU,UAAU,QAAQ;EAC9B,OACE,UAAU,UAAU,QAAQ;CAEhC;CACA,OAAO;AACT;;AASA,eAAsB,wBAAwB,MAAc,SAAwD;CAClH,MAAM,EAAE,SAAS,MAAM,OAAO;CAC9B,IAAI,CAAC,SAAS;EACZ,MAAM,GAAG,OAAO,gDAAgD,SAAS;EACzE;CACF;CAEA,MAAM,UAAU,QAAQ,KAAK;CAC7B,MAAM,CAAC,WAAW,eAAe,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;CAExE,IAAI;CACJ,IAAI,WAAW;EACb,SAAS,eAAe,SAAS,SAAS;EAC1C,IAAI,CAAC,QAAQ;GACX,MAAM,QAAQ,QAAQ,KAAK,UAAU,MAAM,WAAW,MAAM,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK;GACzF,MAAM,GAAG,OAAO,0BAA0B,UAAU,gBAAgB,MAAM,IAAI,SAAS;GACvF;EACF;CACF,OAAO;EACL,MAAM,SAAS,QAAQ,QAAQ,UAAU,WAAW,OAAO,IAAI,CAAC,CAAC,SAAS,CAAC;EAC3E,IAAI,OAAO,WAAW,GAAG;GACvB,MAAM,GAAG,OAAO,iDAAiD,MAAM;GACvE;EACF;EACA,MAAM,SAAS,OAAO,KACnB,UAAU,GAAG,KAAK,KAAK,IAAI,QAAQ,MAAM,GAAG,MAAM,WAAW,MAAM,IAAI,MAAM,WAAW,aAC3F;EACA,MAAM,KAAK,OAAO,OAAO,IAAI,CAAC,CAAC;EAC/B,MAAM,SAAS,MAAM,GAAG,OAAO,gBAAgB,OAAO,EAAE,EAAE,OAAO,MAAM;EACvE,IAAI,WAAW,KAAA,GAAW;EAC1B,SAAS,OAAO,OAAO,QAAQ,MAAM;EACrC,IAAI,CAAC,QAAQ;CACf;CAEA,MAAM,UAAU,WAAW,QAAQ,IAAI;CACvC,IAAI,QAAQ,WAAW,GAAG;EAKxB,MAAM,UAAU,CACd,GAAG,IAAI,IACL,OAAO,MAAM,QACV,KAAK,UAAU,MAAM,cAAc,CAAC,CACpC,QAAQ,WAA6B,WAAW,KAAA,KAAa,OAAO,SAAS,CAAC,CACnF,CACF;EACA,MAAM,UAAU,QAAQ,SAAS,IAAI,IAAI,QAAQ,KAAK,GAAG,MAAM;EAC/D,MAAM,GAAG,OAAO,GAAG,OAAO,WAAW,MAAM,4CAA4C,WAAW,SAAS;EAC3G;CACF;CAEA,IAAI;CACJ,IAAI,aAAa;EACf,SAAS,QAAQ,MAAM,UAAU,MAAM,GAAG,YAAY,MAAM,YAAY,YAAY,CAAC;EACrF,IAAI,CAAC,QAAQ;GACX,MAAM,QAAQ,QAAQ,KAAK,UAAU,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI;GACxD,MAAM,GAAG,OAAO,OAAO,YAAY,cAAc,OAAO,WAAW,MAAM,eAAe,MAAM,IAAI,SAAS;GAC3G;EACF;CACF,OAAO,IAAI,QAAQ,WAAW,GAC5B,SAAS,QAAQ;MACZ;EACL,MAAM,SAAS,QAAQ,KAAK,UAAU,GAAG,MAAM,MAAM,IAAI,MAAM,aAAa;EAC5E,MAAM,SAAS,MAAM,GAAG,OAAO,GAAG,OAAO,WAAW,MAAM,IAAI,OAAO,MAAM,WAAW,IAAI,MAAM;EAChG,IAAI,WAAW,KAAA,GAAW;EAC1B,SAAS,QAAQ,OAAO,QAAQ,MAAM;CACxC;CACA,IAAI,CAAC,QAAQ;CAEb,MAAM,iBAAiB,MAAM,gBAAgB,IAAI,MAAM;CACvD,IAAI,mBAAmB,KAAA,GAAW;CAElC,IAAI;EACF,MAAM,WAAW,MAAM,QAAQ,OAC7B;GACE,aAAa,WAAW,OAAO,WAAW;GAC1C,MAAM;IACJ,QAAQ,OAAO,WAAW;IAC1B,IAAI,OAAO,WAAW;IACtB,iBAAiB,OAAO;IACxB,gBAAgB,OAAO;GACzB;GACA,UAAU,OAAO;GACjB,WAAW;EACb,GACA,gBACF;EACA,MAAM,QAAQ,SAAS,KAAK;EAC5B,MAAM,SAAS,MAAM,SAAS,KAAK,MAAM,WAAW;EACpD,MAAM,GAAG,OAAO,SAAS,WAAW,GAAG,OAAO,WAAW,MAAM,MAAM,MAAM,aAAa,OAAO,IAAI,MAAM;CAC3G,SAAS,OAAO;EACd,MAAM,GAAG,OACP,GAAG,OAAO,WAAW,MAAM,GAAG,OAAO,MAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC3G,OACF;CACF;AACF"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
//#region src/services/command/index.ts
|
|
2
|
+
const MINOR_MODE_COMMAND = "minor";
|
|
3
|
+
const REQUESTER_SOURCE = "@agimon-ai/po/mode-catalog/ui-command";
|
|
4
|
+
function isOn(record) {
|
|
5
|
+
return record.state.activation === "active" || record.state.activation === "deactivating";
|
|
6
|
+
}
|
|
7
|
+
/** A catalog mode addressed the way a person types it: id, label, or id stem. */
|
|
8
|
+
function matchMinorMode(records, query) {
|
|
9
|
+
const needle = query.toLowerCase();
|
|
10
|
+
return records.find((record) => record.descriptor.id.toLowerCase() === needle || record.descriptor.label.toLowerCase() === needle || record.descriptor.id.toLowerCase().split(".")[0] === needle);
|
|
11
|
+
}
|
|
12
|
+
/** The actions a session of this kind can currently take on a mode. */
|
|
13
|
+
function actionsFor(record, kind) {
|
|
14
|
+
return record.descriptor.actions.filter((action) => {
|
|
15
|
+
if (!action.contexts.includes(kind)) return false;
|
|
16
|
+
return record.state.actions.find((entry) => entry.id === action.id)?.enabled !== false;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function promptArguments(ui, action) {
|
|
20
|
+
const collected = {};
|
|
21
|
+
for (const parameter of action.parameters) {
|
|
22
|
+
if (!parameter.required) continue;
|
|
23
|
+
const title = `${action.label}: ${parameter.label}`;
|
|
24
|
+
if (parameter.kind === "boolean") {
|
|
25
|
+
const value = await ui.confirm(title, parameter.description ?? "");
|
|
26
|
+
if (value === void 0) return void 0;
|
|
27
|
+
collected[parameter.name] = value;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (parameter.kind === "enum") {
|
|
31
|
+
const options = parameter.choices.map((choice) => choice.label);
|
|
32
|
+
const picked = await ui.select(title, options);
|
|
33
|
+
const choice = picked === void 0 ? void 0 : parameter.choices[options.indexOf(picked)];
|
|
34
|
+
if (!choice) return void 0;
|
|
35
|
+
collected[parameter.name] = choice.value;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const raw = await ui.input(title, parameter.description ?? "");
|
|
39
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
40
|
+
if (parameter.kind === "number") {
|
|
41
|
+
const value = Number(raw);
|
|
42
|
+
if (!Number.isFinite(value)) {
|
|
43
|
+
await ui.notify(`${parameter.label} must be a number.`, "warning");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
collected[parameter.name] = value;
|
|
47
|
+
} else collected[parameter.name] = raw;
|
|
48
|
+
}
|
|
49
|
+
return collected;
|
|
50
|
+
}
|
|
51
|
+
/** Runs the catalog command against an explicit interaction surface. */
|
|
52
|
+
async function executeMinorModeCommand(args, options) {
|
|
53
|
+
const { catalog, kind, ui } = options;
|
|
54
|
+
if (!catalog) {
|
|
55
|
+
await ui.notify("Minor modes are unavailable in this session.", "warning");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const records = catalog.list();
|
|
59
|
+
const [modeQuery, actionQuery] = args.trim().split(/\s+/).filter(Boolean);
|
|
60
|
+
let record;
|
|
61
|
+
if (modeQuery) {
|
|
62
|
+
record = matchMinorMode(records, modeQuery);
|
|
63
|
+
if (!record) {
|
|
64
|
+
const known = records.map((entry) => entry.descriptor.label.toLowerCase()).join(", ") || "none";
|
|
65
|
+
await ui.notify(`No minor mode matches "${modeQuery}". Available: ${known}.`, "warning");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
const listed = records.filter((entry) => actionsFor(entry, kind).length > 0);
|
|
70
|
+
if (listed.length === 0) {
|
|
71
|
+
await ui.notify("No minor modes are available in this session.", "info");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const labels = listed.map((entry) => `${isOn(entry) ? "[x]" : "[ ]"} ${entry.descriptor.label}: ${entry.descriptor.description}`);
|
|
75
|
+
const on = listed.filter(isOn).length;
|
|
76
|
+
const picked = await ui.select(`Minor modes (${String(on)} on)`, labels);
|
|
77
|
+
if (picked === void 0) return;
|
|
78
|
+
record = listed[labels.indexOf(picked)];
|
|
79
|
+
if (!record) return;
|
|
80
|
+
}
|
|
81
|
+
const actions = actionsFor(record, kind);
|
|
82
|
+
if (actions.length === 0) {
|
|
83
|
+
const reasons = [...new Set(record.state.actions.map((entry) => entry.disabledReason).filter((reason) => reason !== void 0 && reason.length > 0))];
|
|
84
|
+
const because = reasons.length > 0 ? ` ${reasons.join(" ")}` : "";
|
|
85
|
+
await ui.notify(`${record.descriptor.label} has no actions available in this session.${because}`, "warning");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
let action;
|
|
89
|
+
if (actionQuery) {
|
|
90
|
+
action = actions.find((entry) => entry.id.toLowerCase() === actionQuery.toLowerCase());
|
|
91
|
+
if (!action) {
|
|
92
|
+
const known = actions.map((entry) => entry.id).join(", ");
|
|
93
|
+
await ui.notify(`No "${actionQuery}" action on ${record.descriptor.label}. Available: ${known}.`, "warning");
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
} else if (actions.length === 1) action = actions[0];
|
|
97
|
+
else {
|
|
98
|
+
const labels = actions.map((entry) => `${entry.label}: ${entry.description}`);
|
|
99
|
+
const picked = await ui.select(`${record.descriptor.label} (${record.state.activation})`, labels);
|
|
100
|
+
if (picked === void 0) return;
|
|
101
|
+
action = actions[labels.indexOf(picked)];
|
|
102
|
+
}
|
|
103
|
+
if (!action) return;
|
|
104
|
+
const argumentsValue = await promptArguments(ui, action);
|
|
105
|
+
if (argumentsValue === void 0) return;
|
|
106
|
+
try {
|
|
107
|
+
const response = await catalog.invoke({
|
|
108
|
+
operationId: globalThis.crypto.randomUUID(),
|
|
109
|
+
mode: {
|
|
110
|
+
source: record.descriptor.source,
|
|
111
|
+
id: record.descriptor.id,
|
|
112
|
+
ownerGeneration: record.ownerGeneration,
|
|
113
|
+
registrationId: record.registrationId
|
|
114
|
+
},
|
|
115
|
+
actionId: action.id,
|
|
116
|
+
arguments: argumentsValue
|
|
117
|
+
}, REQUESTER_SOURCE);
|
|
118
|
+
const state = response.mode.state;
|
|
119
|
+
const detail = state.detail ? `: ${state.detail}` : "";
|
|
120
|
+
await ui.notify(response.message ?? `${record.descriptor.label} is ${state.activation}${detail}.`, "info");
|
|
121
|
+
} catch (error) {
|
|
122
|
+
await ui.notify(`${record.descriptor.label} ${action.label} failed: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
export { matchMinorMode as i, actionsFor as n, executeMinorModeCommand as r, MINOR_MODE_COMMAND as t };
|
|
127
|
+
|
|
128
|
+
//# sourceMappingURL=command-DWrT7rjd.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-DWrT7rjd.mjs","names":[],"sources":["../src/services/command/index.ts"],"sourcesContent":["import type {\n MinorModeActionDescriptor,\n MinorModeArguments,\n MinorModeCatalogService,\n MinorModeRecord,\n MinorModeSessionKind,\n} from '../../schemas/mode';\n\nexport const MINOR_MODE_COMMAND = 'minor';\nexport { MINOR_MODE_COMMAND_DESCRIPTION } from '../../constants/command';\nconst REQUESTER_SOURCE = '@agimon-ai/po/mode-catalog/ui-command';\n\ntype NotificationLevel = 'info' | 'warning' | 'error';\n\nexport interface MinorModeCommandPrompter {\n select(title: string, options: readonly string[]): Promise<string | undefined>;\n input(title: string, message: string): Promise<string | undefined>;\n confirm(title: string, message: string): Promise<boolean | undefined>;\n notify(message: string, level: NotificationLevel): void | Promise<void>;\n}\n\nfunction isOn(record: MinorModeRecord): boolean {\n return record.state.activation === 'active' || record.state.activation === 'deactivating';\n}\n\n/** A catalog mode addressed the way a person types it: id, label, or id stem. */\nexport function matchMinorMode(records: readonly MinorModeRecord[], query: string): MinorModeRecord | undefined {\n const needle = query.toLowerCase();\n return records.find(\n (record) =>\n record.descriptor.id.toLowerCase() === needle ||\n record.descriptor.label.toLowerCase() === needle ||\n record.descriptor.id.toLowerCase().split('.')[0] === needle,\n );\n}\n\n/** The actions a session of this kind can currently take on a mode. */\nexport function actionsFor(record: MinorModeRecord, kind: MinorModeSessionKind): MinorModeActionDescriptor[] {\n return record.descriptor.actions.filter((action) => {\n if (!action.contexts.includes(kind)) return false;\n const availability = record.state.actions.find((entry) => entry.id === action.id);\n return availability?.enabled !== false;\n });\n}\n\nasync function promptArguments(\n ui: MinorModeCommandPrompter,\n action: MinorModeActionDescriptor,\n): Promise<MinorModeArguments | undefined> {\n const collected: MinorModeArguments = {};\n for (const parameter of action.parameters) {\n if (!parameter.required) continue;\n const title = `${action.label}: ${parameter.label}`;\n if (parameter.kind === 'boolean') {\n const value = await ui.confirm(title, parameter.description ?? '');\n if (value === undefined) return undefined;\n collected[parameter.name] = value;\n continue;\n }\n if (parameter.kind === 'enum') {\n const options = parameter.choices.map((choice) => choice.label);\n const picked = await ui.select(title, options);\n const choice = picked === undefined ? undefined : parameter.choices[options.indexOf(picked)];\n if (!choice) return undefined;\n collected[parameter.name] = choice.value;\n continue;\n }\n const raw = await ui.input(title, parameter.description ?? '');\n if (raw === undefined || raw === '') return undefined;\n if (parameter.kind === 'number') {\n const value = Number(raw);\n if (!Number.isFinite(value)) {\n await ui.notify(`${parameter.label} must be a number.`, 'warning');\n return undefined;\n }\n collected[parameter.name] = value;\n } else {\n collected[parameter.name] = raw;\n }\n }\n return collected;\n}\n\nexport interface ExecuteMinorModeCommandOptions {\n catalog: MinorModeCatalogService | undefined;\n kind: MinorModeSessionKind;\n ui: MinorModeCommandPrompter;\n}\n\n/** Runs the catalog command against an explicit interaction surface. */\nexport async function executeMinorModeCommand(args: string, options: ExecuteMinorModeCommandOptions): Promise<void> {\n const { catalog, kind, ui } = options;\n if (!catalog) {\n await ui.notify('Minor modes are unavailable in this session.', 'warning');\n return;\n }\n\n const records = catalog.list();\n const [modeQuery, actionQuery] = args.trim().split(/\\s+/).filter(Boolean);\n\n let record: MinorModeRecord | undefined;\n if (modeQuery) {\n record = matchMinorMode(records, modeQuery);\n if (!record) {\n const known = records.map((entry) => entry.descriptor.label.toLowerCase()).join(', ') || 'none';\n await ui.notify(`No minor mode matches \"${modeQuery}\". Available: ${known}.`, 'warning');\n return;\n }\n } else {\n const listed = records.filter((entry) => actionsFor(entry, kind).length > 0);\n if (listed.length === 0) {\n await ui.notify('No minor modes are available in this session.', 'info');\n return;\n }\n const labels = listed.map(\n (entry) => `${isOn(entry) ? '[x]' : '[ ]'} ${entry.descriptor.label}: ${entry.descriptor.description}`,\n );\n const on = listed.filter(isOn).length;\n const picked = await ui.select(`Minor modes (${String(on)} on)`, labels);\n if (picked === undefined) return;\n record = listed[labels.indexOf(picked)];\n if (!record) return;\n }\n\n const actions = actionsFor(record, kind);\n if (actions.length === 0) {\n // The mode already said why each action is unavailable. Repeating that\n // is the difference between a dead end and an explanation: \"requires\n // an interactive session\" tells a cockpit user to reach for the TUI,\n // where the bare sentence leaves them guessing.\n const reasons = [\n ...new Set(\n record.state.actions\n .map((entry) => entry.disabledReason)\n .filter((reason): reason is string => reason !== undefined && reason.length > 0),\n ),\n ];\n const because = reasons.length > 0 ? ` ${reasons.join(' ')}` : '';\n await ui.notify(`${record.descriptor.label} has no actions available in this session.${because}`, 'warning');\n return;\n }\n\n let action: MinorModeActionDescriptor | undefined;\n if (actionQuery) {\n action = actions.find((entry) => entry.id.toLowerCase() === actionQuery.toLowerCase());\n if (!action) {\n const known = actions.map((entry) => entry.id).join(', ');\n await ui.notify(`No \"${actionQuery}\" action on ${record.descriptor.label}. Available: ${known}.`, 'warning');\n return;\n }\n } else if (actions.length === 1) {\n action = actions[0];\n } else {\n const labels = actions.map((entry) => `${entry.label}: ${entry.description}`);\n const picked = await ui.select(`${record.descriptor.label} (${record.state.activation})`, labels);\n if (picked === undefined) return;\n action = actions[labels.indexOf(picked)];\n }\n if (!action) return;\n\n const argumentsValue = await promptArguments(ui, action);\n if (argumentsValue === undefined) return;\n\n try {\n const response = await catalog.invoke(\n {\n operationId: globalThis.crypto.randomUUID(),\n mode: {\n source: record.descriptor.source,\n id: record.descriptor.id,\n ownerGeneration: record.ownerGeneration,\n registrationId: record.registrationId,\n },\n actionId: action.id,\n arguments: argumentsValue,\n },\n REQUESTER_SOURCE,\n );\n const state = response.mode.state;\n const detail = state.detail ? `: ${state.detail}` : '';\n await ui.notify(response.message ?? `${record.descriptor.label} is ${state.activation}${detail}.`, 'info');\n } catch (error) {\n await ui.notify(\n `${record.descriptor.label} ${action.label} failed: ${error instanceof Error ? error.message : String(error)}`,\n 'error',\n );\n }\n}\n"],"mappings":"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"}
|
package/dist/command.cjs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_command = require("./command-B5HZmmyU.cjs");
|
|
3
|
+
const require_command$1 = require("./command-DNWSjDOI.cjs");
|
|
4
|
+
exports.MINOR_MODE_COMMAND = require_command$1.MINOR_MODE_COMMAND;
|
|
5
|
+
exports.MINOR_MODE_COMMAND_DESCRIPTION = require_command.MINOR_MODE_COMMAND_DESCRIPTION;
|
|
6
|
+
exports.actionsFor = require_command$1.actionsFor;
|
|
7
|
+
exports.executeMinorModeCommand = require_command$1.executeMinorModeCommand;
|
|
8
|
+
exports.matchMinorMode = require_command$1.matchMinorMode;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { a as executeMinorModeCommand, i as actionsFor, n as MINOR_MODE_COMMAND, o as matchMinorMode, r as MinorModeCommandPrompter, t as ExecuteMinorModeCommandOptions } from "./index-BXJERXMH.mjs";
|
|
2
|
+
//#region src/constants/command.d.ts
|
|
3
|
+
export declare const MINOR_MODE_COMMAND_DESCRIPTION = "Toggle or drive minor modes";
|
|
4
|
+
//#endregion
|
|
5
|
+
export { ExecuteMinorModeCommandOptions, MINOR_MODE_COMMAND, MinorModeCommandPrompter, actionsFor, executeMinorModeCommand, matchMinorMode };
|
|
6
|
+
//# sourceMappingURL=command.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.mts","names":[],"sources":["../src/constants/command.ts"],"mappings":";;qBAAa"}
|
package/dist/command.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { t as MINOR_MODE_COMMAND_DESCRIPTION } from "./command-BvYpwiin.mjs";
|
|
2
|
+
import { i as matchMinorMode, n as actionsFor, r as executeMinorModeCommand, t as MINOR_MODE_COMMAND } from "./command-DWrT7rjd.mjs";
|
|
3
|
+
export { MINOR_MODE_COMMAND, MINOR_MODE_COMMAND_DESCRIPTION, actionsFor, executeMinorModeCommand, matchMinorMode };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
const require_mode = require("../mode-BehVDmjF.cjs");
|
|
6
|
+
const require_catalog = require("../catalog-CgwaiiVw.cjs");
|
|
7
|
+
const require_headlessCommand = require("../headlessCommand-Df1-11qO.cjs");
|
|
8
|
+
const require_projection = require("../projection-DClKNv5Z.cjs");
|
|
9
|
+
let _agimon_ai_po_core_serverFacet = require("@agimon-ai/po-core/serverFacet");
|
|
10
|
+
let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
|
|
11
|
+
//#region src/extensions/workspaces/sessions/(backend)/root.server.ts
|
|
12
|
+
var root_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoot)(({ agent }) => {
|
|
13
|
+
if (!agent) throw new Error("Minor modes require a session host");
|
|
14
|
+
let started = false;
|
|
15
|
+
let stopped = false;
|
|
16
|
+
let pending = Promise.resolve();
|
|
17
|
+
let published;
|
|
18
|
+
const publish = () => {
|
|
19
|
+
const operation = pending.then(async () => {
|
|
20
|
+
if (!started || stopped) return;
|
|
21
|
+
const projection = require_projection.projectMinorModes(catalog.getSnapshot(), "headless");
|
|
22
|
+
const key = JSON.stringify(projection);
|
|
23
|
+
if (key === published) return;
|
|
24
|
+
await agent.context.session.appendCustomEntry(require_mode.DOOM_MINOR_MODE_ENTRY_TYPE, projection);
|
|
25
|
+
published = key;
|
|
26
|
+
});
|
|
27
|
+
pending = operation.catch(() => void 0);
|
|
28
|
+
return operation;
|
|
29
|
+
};
|
|
30
|
+
const catalog = require_catalog.createMinorModeCatalogHost({
|
|
31
|
+
sessionKind: "headless",
|
|
32
|
+
context: { sessionManager: { getSessionId: () => agent.context.sessionId } },
|
|
33
|
+
async routeInvocation(_request, _source, invoke) {
|
|
34
|
+
agent.assertActive();
|
|
35
|
+
const response = await invoke();
|
|
36
|
+
await publish();
|
|
37
|
+
return response;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const contributions = {
|
|
41
|
+
commands: [require_headlessCommand.headlessMinorModeCommand(catalog)],
|
|
42
|
+
services: [(context) => {
|
|
43
|
+
context.plugin((providerContext) => {
|
|
44
|
+
providerContext.provide(require_mode.DOOM_MINOR_MODE_CATALOG_SERVICE, catalog);
|
|
45
|
+
});
|
|
46
|
+
context.effect(() => catalog.subscribe(() => {
|
|
47
|
+
publish().catch(async (error) => {
|
|
48
|
+
if (stopped) return;
|
|
49
|
+
await agent.context.client.notify({
|
|
50
|
+
body: `Minor-mode projection failed: ${String(error)}`,
|
|
51
|
+
level: "error"
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}));
|
|
55
|
+
context.effect(() => agent.subscribeSelection(publish));
|
|
56
|
+
}],
|
|
57
|
+
hooks: [{
|
|
58
|
+
event: "session_shutdown",
|
|
59
|
+
async handle() {
|
|
60
|
+
stopped = true;
|
|
61
|
+
await pending;
|
|
62
|
+
}
|
|
63
|
+
}, {
|
|
64
|
+
event: "session_start",
|
|
65
|
+
async handle() {
|
|
66
|
+
const entries = await agent.context.session.entries({
|
|
67
|
+
type: "custom",
|
|
68
|
+
customType: require_mode.DOOM_MINOR_MODE_ENTRY_TYPE
|
|
69
|
+
});
|
|
70
|
+
const values = require_projection.restoreMinorModeSelection(entries);
|
|
71
|
+
if (values) await agent.changeSelection({
|
|
72
|
+
axis: "state",
|
|
73
|
+
key: "minor-mode",
|
|
74
|
+
values
|
|
75
|
+
});
|
|
76
|
+
started = true;
|
|
77
|
+
await publish();
|
|
78
|
+
}
|
|
79
|
+
}]
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
value: contributions,
|
|
83
|
+
services: contributions.services,
|
|
84
|
+
async onDispose() {
|
|
85
|
+
stopped = true;
|
|
86
|
+
catalog.dispose();
|
|
87
|
+
await pending;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/extensions/workspaces/sessions/(backend)/command/minor-modes.server.ts
|
|
93
|
+
var minor_modes_server_default = (0, _agimon_ai_po_core_extensionFile.defineServerCommand)((context) => context.root.commands[0]);
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts
|
|
96
|
+
var session_shutdown_server_default = (0, _agimon_ai_po_core_extensionFile.defineHook)((context) => context.root.hooks.find((hook) => hook.event === "session_shutdown"));
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/extensions/workspaces/sessions/(backend)/hook/session-start.server.ts
|
|
99
|
+
var session_start_server_default = (0, _agimon_ai_po_core_extensionFile.defineHook)((context) => context.root.hooks.find((hook) => hook.event === "session_start"));
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region generated/server.ts
|
|
102
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
103
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
104
|
+
...identity,
|
|
105
|
+
...value
|
|
106
|
+
};
|
|
107
|
+
const facet = (0, _agimon_ai_po_core_serverFacet.defineServerPlugin)({
|
|
108
|
+
name: "@agimon-ai/po-minor-mode",
|
|
109
|
+
providerOverrides: (0, _agimon_ai_po_core_serverFacet.composeServerProviderOverrides)(root_server_default),
|
|
110
|
+
session: async (context) => {
|
|
111
|
+
const scopeSession = await root_server_default(context);
|
|
112
|
+
const contextSession = {
|
|
113
|
+
...context,
|
|
114
|
+
root: scopeSession.value
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
...(0, _agimon_ai_po_core_extensionFile.composeRootHooks)(scopeSession),
|
|
118
|
+
get commands() {
|
|
119
|
+
return [via({ name: "minor-modes" }, at(minor_modes_server_default, contextSession))];
|
|
120
|
+
},
|
|
121
|
+
get hooks() {
|
|
122
|
+
return [via({ event: "session_shutdown" }, at(session_shutdown_server_default, contextSession)), via({ event: "session_start" }, at(session_start_server_default, contextSession))];
|
|
123
|
+
},
|
|
124
|
+
services: [...scopeSession.services ?? []],
|
|
125
|
+
get activities() {
|
|
126
|
+
return [...scopeSession.activities ?? []];
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
//#endregion
|
|
132
|
+
exports.default = facet;
|
|
133
|
+
exports.facet = facet;
|
|
134
|
+
|
|
135
|
+
//# sourceMappingURL=server.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["defineRoot","projectMinorModes","DOOM_MINOR_MODE_ENTRY_TYPE","createMinorModeCatalogHost","headlessMinorModeCommand","DOOM_MINOR_MODE_CATALOG_SERVICE","restoreMinorModeSelection","defineServerCommand","defineHook","defineHook","defineServerPlugin","composeServerProviderOverrides","rootSession","composeRootHooks","commandMinorModes","hookSessionShutdown","hookSessionStart"],"sources":["../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/command/minor-modes.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.server.ts","../../generated/server.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport { DOOM_MINOR_MODE_CATALOG_SERVICE, DOOM_MINOR_MODE_ENTRY_TYPE } from '../../../../schemas/mode';\nimport { createMinorModeCatalogHost } from '../../../../services/catalog';\nimport { headlessMinorModeCommand } from '../../../../services/headlessCommand';\nimport { projectMinorModes, restoreMinorModeSelection } from '../../../../services/projection';\nimport type { MinorModeServerScope } from './_lib/serverScope';\n\nexport default defineRoot(({ agent }: DoomServerPluginContext) => {\n if (!agent) throw new Error('Minor modes require a session host');\n let started = false;\n let stopped = false;\n let pending = Promise.resolve();\n let published: string | undefined;\n const publish = (): Promise<void> => {\n const operation = pending.then(async () => {\n if (!started || stopped) return;\n const projection = projectMinorModes(catalog.getSnapshot(), 'headless');\n const key = JSON.stringify(projection);\n if (key === published) return;\n await agent.context.session.appendCustomEntry(DOOM_MINOR_MODE_ENTRY_TYPE, projection);\n published = key;\n });\n pending = operation.catch(() => undefined);\n return operation;\n };\n const catalog = createMinorModeCatalogHost({\n sessionKind: 'headless',\n context: { sessionManager: { getSessionId: () => agent.context.sessionId } },\n async routeInvocation(_request, _source, invoke) {\n agent.assertActive();\n const response = await invoke();\n await publish();\n return response;\n },\n });\n const contributions: MinorModeServerScope = {\n commands: [headlessMinorModeCommand(catalog)],\n services: [\n (context: DoomServerPluginContext['context']) => {\n context.plugin((providerContext) => {\n providerContext.provide(DOOM_MINOR_MODE_CATALOG_SERVICE, catalog);\n });\n context.effect(() =>\n catalog.subscribe(() => {\n void publish().catch(async (error) => {\n if (stopped) return;\n await agent.context.client.notify({\n body: `Minor-mode projection failed: ${String(error)}`,\n level: 'error',\n });\n });\n }),\n );\n context.effect(() => agent.subscribeSelection(publish));\n },\n ],\n hooks: [\n {\n event: 'session_shutdown' as const,\n async handle() {\n stopped = true;\n await pending;\n },\n },\n {\n event: 'session_start' as const,\n async handle() {\n const entries = await agent.context.session.entries({\n type: 'custom',\n customType: DOOM_MINOR_MODE_ENTRY_TYPE,\n });\n const values = restoreMinorModeSelection(entries);\n if (values) await agent.changeSelection({ axis: 'state', key: 'minor-mode', values });\n started = true;\n await publish();\n },\n },\n ],\n };\n return {\n value: contributions,\n services: contributions.services,\n async onDispose() {\n stopped = true;\n catalog.dispose();\n await pending;\n },\n };\n});\n","import { defineServerCommand } from '@agimon-ai/po-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { MinorModeServerScope } from '../_lib/serverScope';\nexport default defineServerCommand(\n (context: WithRoot<DoomServerPluginContext, MinorModeServerScope>) => context.root.commands[0]!,\n);\n","import { defineHook } from '@agimon-ai/po-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { MinorModeServerScope } from '../_lib/serverScope';\nexport default defineHook((context: WithRoot<DoomServerPluginContext, MinorModeServerScope>) =>\n context.root.hooks.find((hook) => hook.event === 'session_shutdown')!,\n);\n","import { defineHook } from '@agimon-ai/po-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { MinorModeServerScope } from '../_lib/serverScope';\nexport default defineHook((context: WithRoot<DoomServerPluginContext, MinorModeServerScope>) =>\n context.root.hooks.find((hook) => hook.event === 'session_start')!,\n);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/po-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport commandMinorModes from '../src/extensions/workspaces/sessions/(backend)/command/minor-modes.server';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/po-minor-mode',\n providerOverrides: composeServerProviderOverrides(rootSession),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): DoomServerSessionPlugin['commands'] { return [via({ name: 'minor-modes' }, at(commandMinorModes, contextSession))]; },\n get hooks(): DoomServerSessionPlugin['hooks'] { return [via({ event: 'session_shutdown' }, at(hookSessionShutdown, contextSession)), via({ event: 'session_start' }, at(hookSessionStart, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../generated/server.ts"],"mappings":";qBAgBa,gDAAK"}
|