@agimon-ai/po-profile 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.
@@ -0,0 +1,179 @@
1
+ import { c as createProfileRuntime, i as profileItems, l as createProfileRuntimePlugin, s as profileTitle, t as PROFILE_COMMAND } from "../profileText-B1dz_9lS.mjs";
2
+ import { buildPersonaPrompt, loadProfiles, resolveProfile } from "@agimon-ai/po-config/profiles";
3
+ import { composeServerProviderOverrides, defineServerPlugin, packageResourcePath, readPackageResource } from "@agimon-ai/po-core/serverFacet";
4
+ import { composeRootHooks, defineHook, defineResource, defineRoot, defineRoutedContribution } from "@agimon-ai/po-core/extensionFile";
5
+ import os from "node:os";
6
+ import { DoomHeadlessPromptAdmissionError, DoomSessionSetupError, isDoomHeadlessPromptAdmissionError } from "@agimon-ai/po-core/headless";
7
+ import { DOOM_PROFILE_IDENTITY_ENTRY_TYPE } from "@agimon-ai/po-core/profileIdentity";
8
+ //#region src/extensions/workspaces/sessions/(backend)/root.server.ts
9
+ var root_server_default = defineRoot(({ agent, signal }) => {
10
+ if (!agent) return { value: void 0 };
11
+ const execution = agent.context;
12
+ const runtime = createProfileRuntime({
13
+ profileName: execution.selection.profile,
14
+ readBinding: (profileName) => resolveProfile(execution.repoRoot, profileName, execution.environment.HOME ?? os.homedir()).integration
15
+ });
16
+ const unsubscribe = agent.subscribeSelection(async (selection) => {
17
+ try {
18
+ await runtime.select(selection.profile);
19
+ } catch (error) {
20
+ throw new DoomHeadlessPromptAdmissionError(error);
21
+ }
22
+ });
23
+ const invalidate = () => runtime.invalidate();
24
+ signal.addEventListener("abort", invalidate, { once: true });
25
+ if (signal.aborted) runtime.invalidate();
26
+ return {
27
+ value: runtime,
28
+ services: [createProfileRuntimePlugin(runtime)],
29
+ async onDispose() {
30
+ unsubscribe();
31
+ signal.removeEventListener("abort", invalidate);
32
+ await runtime.dispose();
33
+ }
34
+ };
35
+ });
36
+ //#endregion
37
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/profileServer.ts
38
+ async function readSelectedPersona(execution) {
39
+ const name = execution.selection.profile;
40
+ if (!name) return "(no active profile)";
41
+ const profile = resolveProfile(execution.repoRoot, name, execution.environment?.HOME);
42
+ const prompt = buildPersonaPrompt(profile.personaRoot, profile.persona);
43
+ if (!prompt) throw new Error(`Profile "${name}" has no readable persona text`);
44
+ return prompt;
45
+ }
46
+ async function publishSelectedIdentity(execution, profile) {
47
+ const identity = resolveProfile(execution.repoRoot, profile, execution.environment.HOME).identity;
48
+ await execution.session.appendCustomEntry(DOOM_PROFILE_IDENTITY_ENTRY_TYPE, {
49
+ profile,
50
+ ...identity?.name === void 0 ? {} : { name: identity.name },
51
+ ...identity?.icon === void 0 ? {} : { icon: identity.icon }
52
+ });
53
+ }
54
+ function createProfileServerCommand(host) {
55
+ return {
56
+ name: PROFILE_COMMAND,
57
+ description: "Show or change the active Po profile.",
58
+ selectionRecovery: true,
59
+ async execute(args, execution) {
60
+ const profiles = loadProfiles(execution.repoRoot, execution.environment.HOME);
61
+ let requested = args.trim();
62
+ if (!requested) {
63
+ const selected = await execution.client.request({
64
+ kind: "select",
65
+ title: profileTitle(execution.selection.profile),
66
+ options: profileItems(profiles)
67
+ });
68
+ if (typeof selected !== "string" || !selected) return;
69
+ requested = selected;
70
+ }
71
+ if (!profiles.some(({ name }) => name === requested)) throw new Error(`Unknown profile: ${requested}`);
72
+ if (requested === execution.selection.profile && host.inspectCapabilities().ready) return;
73
+ try {
74
+ await host.changeSelection({
75
+ axis: "profile",
76
+ profile: requested
77
+ });
78
+ } catch (error) {
79
+ if (isDoomHeadlessPromptAdmissionError(error)) throw new DoomSessionSetupError("Profile integration is unavailable. Restore its credential or choose another profile.");
80
+ throw error;
81
+ }
82
+ await publishSelectedIdentity(execution, requested);
83
+ }
84
+ };
85
+ }
86
+ async function assertProfileReady(runtime) {
87
+ try {
88
+ await runtime?.ready();
89
+ } catch (error) {
90
+ throw new DoomHeadlessPromptAdmissionError(error);
91
+ }
92
+ }
93
+ const profileIdentityHook = {
94
+ event: "session_start",
95
+ async handle(_event, execution) {
96
+ const profile = execution.selection.profile;
97
+ if (profile !== void 0) await publishSelectedIdentity(execution, profile);
98
+ }
99
+ };
100
+ //#endregion
101
+ //#region src/extensions/workspaces/sessions/(backend)/command/profile.server.ts
102
+ var profile_server_default = defineRoutedContribution(({ agent }) => agent ? createProfileServerCommand(agent) : void 0, { cardinality: "optional" });
103
+ //#endregion
104
+ //#region src/extensions/workspaces/sessions/(backend)/hook/beforeAgentStart.server.ts
105
+ var beforeAgentStart_server_default = defineHook(({ root }) => ({ async handle() {
106
+ await assertProfileReady(root);
107
+ } }));
108
+ //#endregion
109
+ //#region src/extensions/workspaces/sessions/(backend)/hook/sessionStart.server.ts
110
+ var sessionStart_server_default = defineHook(({ root }) => ({
111
+ ...profileIdentityHook,
112
+ async handle(event, execution) {
113
+ await assertProfileReady(root);
114
+ await profileIdentityHook.handle(event, execution);
115
+ }
116
+ }));
117
+ //#endregion
118
+ //#region src/extensions/workspaces/sessions/(backend)/resource/poAuthorProfile.server.ts
119
+ var poAuthorProfile_server_default = defineResource({
120
+ name: "po-author-profile",
121
+ description: "Configure Po profile discovery, personas, environment defaults, and precedence in profiles.yaml. Use when creating or changing personal or repository profiles. Do not use for config.yaml runtime settings, modes.yaml, or domains.yaml.",
122
+ when: {
123
+ state: { "minor-mode": "help" },
124
+ attribution: {
125
+ kind: "minor",
126
+ mode: "help"
127
+ }
128
+ },
129
+ kind: "skill",
130
+ path: packageResourcePath(import.meta.url, "src/prompts/po-author-profile/SKILL.md"),
131
+ read: () => readPackageResource(import.meta.url, "src/prompts/po-author-profile/SKILL.md")
132
+ });
133
+ //#endregion
134
+ //#region src/extensions/workspaces/sessions/(backend)/resource/profileConfig.server.ts
135
+ var profileConfig_server_default = defineResource({
136
+ name: "po/profile-config",
137
+ kind: "context",
138
+ read: readSelectedPersona
139
+ });
140
+ //#endregion
141
+ //#region generated/server.ts
142
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
143
+ /* v8 ignore next -- generated normalization branch */
144
+ const defined = (values) => values.filter((value) => value !== void 0);
145
+ const via = (identity, value) => value === void 0 ? void 0 : {
146
+ ...identity,
147
+ ...value
148
+ };
149
+ const facet = defineServerPlugin({
150
+ name: "@agimon-ai/po-profile",
151
+ providerOverrides: composeServerProviderOverrides(root_server_default),
152
+ session: async (context) => {
153
+ const scopeSession = await root_server_default(context);
154
+ const contextSession = {
155
+ ...context,
156
+ root: scopeSession.value
157
+ };
158
+ return {
159
+ ...composeRootHooks(scopeSession),
160
+ get commands() {
161
+ return defined([via({ name: "profile" }, at(profile_server_default, contextSession))]);
162
+ },
163
+ get hooks() {
164
+ return [via({ event: "before_agent_start" }, at(beforeAgentStart_server_default, contextSession)), via({ event: "session_start" }, at(sessionStart_server_default, contextSession))];
165
+ },
166
+ get resources() {
167
+ return [at(poAuthorProfile_server_default, contextSession), at(profileConfig_server_default, contextSession)];
168
+ },
169
+ services: [...scopeSession.services ?? []],
170
+ get activities() {
171
+ return [...scopeSession.activities ?? []];
172
+ }
173
+ };
174
+ }
175
+ });
176
+ //#endregion
177
+ export { facet as default, facet };
178
+
179
+ //# sourceMappingURL=server.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.mjs","names":["rootSession","commandProfile","hookBeforeAgentStart","hookSessionStart","resourcePoAuthorProfile","resourceProfileConfig"],"sources":["../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/profileServer.ts","../../src/extensions/workspaces/sessions/(backend)/command/profile.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/beforeAgentStart.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/sessionStart.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/poAuthorProfile.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/profileConfig.server.ts","../../generated/server.ts"],"sourcesContent":["import os from 'node:os';\n\nimport { resolveProfile } from '@agimon-ai/po-config/profiles';\nimport { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport { DoomHeadlessPromptAdmissionError } from '@agimon-ai/po-core/headless';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport { createProfileRuntime, createProfileRuntimePlugin } from '../../../../services/profileRuntime';\n\nexport default defineRoot(({ agent, signal }: DoomServerPluginContext) => {\n if (!agent) return { value: undefined };\n const execution = agent.context;\n const runtime = createProfileRuntime({\n profileName: execution.selection.profile,\n readBinding: (profileName) =>\n resolveProfile(execution.repoRoot, profileName, execution.environment.HOME ?? os.homedir()).integration,\n });\n const unsubscribe = agent.subscribeSelection(async (selection) => {\n try {\n await runtime.select(selection.profile);\n } catch (error) {\n throw new DoomHeadlessPromptAdmissionError(error);\n }\n });\n const invalidate = () => runtime.invalidate();\n signal.addEventListener('abort', invalidate, { once: true });\n if (signal.aborted) runtime.invalidate();\n return {\n value: runtime,\n services: [createProfileRuntimePlugin(runtime)],\n async onDispose() {\n unsubscribe();\n signal.removeEventListener('abort', invalidate);\n await runtime.dispose();\n },\n };\n});\n","import { buildPersonaPrompt, loadProfiles, resolveProfile } from '@agimon-ai/po-config/profiles';\nimport {\n DoomHeadlessPromptAdmissionError,\n DoomSessionSetupError,\n isDoomHeadlessPromptAdmissionError,\n type DoomHeadlessCommand,\n type DoomHeadlessExecutionContext,\n type DoomHeadlessHostService,\n type DoomHeadlessHook,\n} from '@agimon-ai/po-core/headless';\nimport { DOOM_PROFILE_IDENTITY_ENTRY_TYPE } from '@agimon-ai/po-core/profileIdentity';\n\nimport type { ProfileRuntime } from '../../../../../services/profileRuntime/type';\nimport { PROFILE_COMMAND, profileItems, profileTitle } from '../../../../../services/profileText';\n\nexport async function readSelectedPersona(execution: {\n readonly repoRoot: string;\n readonly selection: { readonly profile?: string };\n readonly environment?: Readonly<Record<string, string | undefined>>;\n}): Promise<string> {\n const name = execution.selection.profile;\n if (!name) return '(no active profile)';\n const profile = resolveProfile(execution.repoRoot, name, execution.environment?.HOME);\n const prompt = buildPersonaPrompt(profile.personaRoot, profile.persona);\n if (!prompt) throw new Error(`Profile \"${name}\" has no readable persona text`);\n return prompt;\n}\n\nasync function publishSelectedIdentity(execution: DoomHeadlessExecutionContext, profile: string): Promise<void> {\n const identity = resolveProfile(execution.repoRoot, profile, execution.environment.HOME).identity;\n await execution.session.appendCustomEntry(DOOM_PROFILE_IDENTITY_ENTRY_TYPE, {\n profile,\n ...(identity?.name === undefined ? {} : { name: identity.name }),\n ...(identity?.icon === undefined ? {} : { icon: identity.icon }),\n });\n}\n\nexport function createProfileServerCommand(host: DoomHeadlessHostService): DoomHeadlessCommand {\n return {\n name: PROFILE_COMMAND,\n description: 'Show or change the active Po profile.',\n selectionRecovery: true,\n async execute(args, execution) {\n const profiles = loadProfiles(execution.repoRoot, execution.environment.HOME);\n let requested = args.trim();\n if (!requested) {\n const selected = await execution.client.request({\n kind: 'select',\n title: profileTitle(execution.selection.profile),\n options: profileItems(profiles),\n });\n if (typeof selected !== 'string' || !selected) return;\n requested = selected;\n }\n if (!profiles.some(({ name }) => name === requested)) throw new Error(`Unknown profile: ${requested}`);\n if (requested === execution.selection.profile && host.inspectCapabilities().ready) return;\n try {\n await host.changeSelection({ axis: 'profile', profile: requested });\n } catch (error) {\n if (isDoomHeadlessPromptAdmissionError(error))\n throw new DoomSessionSetupError(\n 'Profile integration is unavailable. Restore its credential or choose another profile.',\n );\n throw error;\n }\n await publishSelectedIdentity(execution, requested);\n },\n };\n}\nexport async function assertProfileReady(runtime: ProfileRuntime | undefined): Promise<void> {\n try {\n await runtime?.ready();\n } catch (error) {\n // Ordinary hook failures are advisory. This is a fail-closed admission boundary.\n throw new DoomHeadlessPromptAdmissionError(error);\n }\n}\n\nexport const profileIdentityHook: DoomHeadlessHook<'session_start'> = {\n event: 'session_start',\n async handle(_event, execution) {\n const profile = execution.selection.profile;\n if (profile !== undefined) await publishSelectedIdentity(execution, profile);\n },\n};\n","import { defineRoutedContribution } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport { createProfileServerCommand } from '../_lib/profileServer';\nexport default defineRoutedContribution(\n ({ agent }: DoomServerPluginContext) => (agent ? createProfileServerCommand(agent) : undefined),\n { cardinality: 'optional' },\n);\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { ProfileRuntime } from '../../../../../services/profileRuntime/type';\nimport { assertProfileReady } from '../_lib/profileServer';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, ProfileRuntime | undefined>) => ({\n async handle() {\n await assertProfileReady(root);\n },\n}));\n","import { defineHook, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomHeadlessExecutionContext } from '@agimon-ai/po-core/headless';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport type { ProfileRuntime } from '../../../../../services/profileRuntime/type';\nimport { assertProfileReady, profileIdentityHook } from '../_lib/profileServer';\n\nexport default defineHook(({ root }: WithRoot<DoomServerPluginContext, ProfileRuntime | undefined>) => ({\n ...profileIdentityHook,\n async handle(event: Readonly<Record<string, unknown>>, execution: DoomHeadlessExecutionContext) {\n await assertProfileReady(root);\n await profileIdentityHook.handle(event, execution);\n },\n}));\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineResource({\n name: 'po-author-profile',\n description:\n 'Configure Po profile discovery, personas, environment defaults, and precedence in profiles.yaml. Use when creating or changing personal or repository profiles. Do not use for config.yaml runtime settings, modes.yaml, or domains.yaml.',\n when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor' as const, mode: 'help' } },\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/po-author-profile/SKILL.md'),\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-author-profile/SKILL.md'),\n});\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\n\nimport { readSelectedPersona } from '../_lib/profileServer';\nexport default defineResource({ name: 'po/profile-config', kind: 'context' as const, read: readSelectedPersona });\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 commandProfile from '../src/extensions/workspaces/sessions/(backend)/command/profile.server';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/beforeAgentStart.server';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/sessionStart.server';\nimport resourcePoAuthorProfile from '../src/extensions/workspaces/sessions/(backend)/resource/poAuthorProfile.server';\nimport resourceProfileConfig from '../src/extensions/workspaces/sessions/(backend)/resource/profileConfig.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;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\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-profile',\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 defined([via({ name: 'profile' }, at(commandProfile, contextSession))]); },\n get hooks(): DoomServerSessionPlugin['hooks'] { return [via({ event: 'before_agent_start' }, at(hookBeforeAgentStart, contextSession)), via({ event: 'session_start' }, at(hookSessionStart, contextSession))]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourcePoAuthorProfile, contextSession), at(resourceProfileConfig, 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,25 @@
1
+ import { defineSelectionAxis, defineWebPlugin } from "@agimon-ai/po-core/web";
2
+ //#region src/extensions/workspaces/sessions/(frontend)/selection-axis/profile.web.ts
3
+ var profile_web_default = defineSelectionAxis({
4
+ name: "profile",
5
+ command: "profile",
6
+ statusKey: "doom-profile",
7
+ emptyLabel: "no profile",
8
+ order: 10
9
+ });
10
+ //#endregion
11
+ //#region generated/web.ts
12
+ const via = (identity, value) => value === void 0 ? void 0 : {
13
+ ...identity,
14
+ ...value
15
+ };
16
+ const webPlugin = defineWebPlugin({
17
+ id: "profile",
18
+ session: { get selectionAxes() {
19
+ return [via({ name: "profile" }, profile_web_default)];
20
+ } }
21
+ });
22
+ //#endregion
23
+ export { webPlugin };
24
+
25
+ //# sourceMappingURL=web.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.mjs","names":["selectionAxisProfile"],"sources":["../../src/extensions/workspaces/sessions/(frontend)/selection-axis/profile.web.ts","../../generated/web.ts"],"sourcesContent":["import { defineSelectionAxis } from '@agimon-ai/po-core/web';\nexport default defineSelectionAxis({\n name: 'profile',\n command: 'profile',\n statusKey: 'doom-profile',\n emptyLabel: 'no profile',\n order: 10,\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport selectionAxisProfile from '../src/extensions/workspaces/sessions/(frontend)/selection-axis/profile.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'profile',\n session: {\n get selectionAxes(): WebPluginContributions['selectionAxes'] { return [via({ name: 'profile' }, selectionAxisProfile)]; },\n },\n});\n"],"mappings":";;AACA,IAAA,sBAAe,oBAAoB;CACjC,MAAM;CACN,SAAS;CACT,WAAW;CACX,YAAY;CACZ,OAAO;AACT,CAAC;;;ACFD,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,YAAY,gBAAgB;CACvC,IAAI;CACJ,SAAS,EACP,IAAI,gBAAyD;EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,UAAU,GAAGA,mBAAoB,CAAC;CAAG,EAC1H;AACF,CAAC"}
package/dist/index.cjs ADDED
@@ -0,0 +1,12 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_profileText = require("./profileText-BkeG0Ulo.cjs");
3
+ exports.PROFILE_RUNTIME_SERVICE = require_profileText.PROFILE_RUNTIME_SERVICE;
4
+ exports.PROFILE_STATUS_KEY = require_profileText.PROFILE_STATUS_KEY;
5
+ exports.createProfileRuntime = require_profileText.createProfileRuntime;
6
+ exports.createProfileRuntimePlugin = require_profileText.createProfileRuntimePlugin;
7
+ exports.profileDescription = require_profileText.profileDescription;
8
+ exports.profileItems = require_profileText.profileItems;
9
+ exports.profileStatus = require_profileText.profileStatus;
10
+ exports.profileSummary = require_profileText.profileSummary;
11
+ exports.profileTitle = require_profileText.profileTitle;
12
+ exports.requireProfileRuntime = require_profileText.requireProfileRuntime;
@@ -0,0 +1,80 @@
1
+ import { AgentProfile, ProfileIntegrationBinding, ProfileSecretReference } from "@agimon-ai/po-config/profiles";
2
+ import { Context } from "@deepseek-ai/cordis";
3
+ //#region src/constants/profileRuntime.d.ts
4
+ export declare const PROFILE_RUNTIME_SERVICE = "po/profile-runtime";
5
+ //#endregion
6
+ //#region src/services/profileRuntime/type.d.ts
7
+ interface ProfileRuntimeSnapshot {
8
+ readonly profileName?: string;
9
+ readonly integration?: ProfileIntegrationBinding;
10
+ readonly generation: number;
11
+ readonly signal: AbortSignal;
12
+ }
13
+ /** A provider connection belongs to exactly one selection generation. */
14
+ interface ProfileSecretResolver {
15
+ resolveSecret(reference: ProfileSecretReference, signal: AbortSignal): Promise<string>;
16
+ dispose(): void | Promise<void>;
17
+ }
18
+ /** Initialize SDK clients, never call runtime.resolveSecret from inside this factory. */
19
+ type ProfileProviderFactory = (binding: ProfileIntegrationBinding, context: {
20
+ readonly profileName: string;
21
+ readonly signal: AbortSignal;
22
+ readonly generation: number;
23
+ }) => Promise<ProfileSecretResolver>;
24
+ interface ProfileSecretRequest {
25
+ /** Trusted actual target-frame origin supplied by the bound browser, never tool arguments. */
26
+ readonly origin: string;
27
+ readonly signal?: AbortSignal;
28
+ }
29
+ interface ProfileRuntime {
30
+ readSelection(): ProfileRuntimeSnapshot;
31
+ /** Rejects if a configured integration has no initialized matching provider. */
32
+ ready(): Promise<void>;
33
+ /** One provider attachment per session. Returns an awaited cleanup/detach operation. */
34
+ attachProvider(providerName: string, factory: ProfileProviderFactory): Promise<() => Promise<void>>;
35
+ resolveSecret(name: string, request: ProfileSecretRequest): Promise<string>;
36
+ select(profileName?: string): Promise<void>;
37
+ /** Synchronous fence used when the owning scope aborts, before asynchronous disposal. */
38
+ invalidate(): void;
39
+ dispose(): Promise<void>;
40
+ }
41
+ interface ProfileRuntimeOptions {
42
+ readonly profileName?: string;
43
+ /** Reads only metadata. The runtime clones it before handing it to providers. */
44
+ readonly readBinding: (profileName: string) => ProfileIntegrationBinding | undefined;
45
+ }
46
+ //#endregion
47
+ //#region src/services/profileRuntime/index.d.ts
48
+ export declare function createProfileRuntime(options: ProfileRuntimeOptions): ProfileRuntime;
49
+ /** Mounted in the scoped root services array, before dependent integration tools. */
50
+ export declare function createProfileRuntimePlugin(runtime: ProfileRuntime): (context: Context) => void;
51
+ export declare function requireProfileRuntime(context: Context): ProfileRuntime;
52
+ declare module '@deepseek-ai/cordis' {
53
+ interface Context {
54
+ 'po/profile-runtime': ProfileRuntime;
55
+ }
56
+ }
57
+ //#endregion
58
+ //#region src/services/profileText/index.d.ts
59
+ /** Footer status key the cockpit's profile axis reads. */
60
+ interface SelectItem {
61
+ value: string;
62
+ label: string;
63
+ description?: string;
64
+ }
65
+ export declare const PROFILE_STATUS_KEY = "doom-profile";
66
+ /**
67
+ * The published axis content: the active profile's name, empty while
68
+ * profiles exist with none active, and undefined to withhold the status so
69
+ * the cockpit keeps the axis off the bar entirely.
70
+ */
71
+ export declare function profileStatus(current: string | undefined, hasProfiles: boolean): string | undefined;
72
+ /** Rows for the single-select profile picker. */
73
+ export declare function profileItems(profiles: AgentProfile[]): SelectItem[];
74
+ export declare function profileDescription(profile: AgentProfile): string;
75
+ /** Shown when the picked profile is already active. */
76
+ export declare function profileSummary(profile: AgentProfile): string;
77
+ export declare function profileTitle(current?: string): string;
78
+ //#endregion
79
+ export type { ProfileProviderFactory, ProfileRuntime, ProfileRuntimeOptions, ProfileRuntimeSnapshot, ProfileSecretRequest, ProfileSecretResolver };
80
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/constants/profileRuntime.ts","../src/services/profileRuntime/type.ts","../src/services/profileRuntime/index.ts","../src/services/profileText/index.ts"],"mappings":";;;qBAAa;;;UCEI;WACN;WACA,cAAc;WACd;WACA,QAAQ;;;UAIF;EACf,cAAc,WAAW,wBAAwB,QAAQ,cAAc;EACvE,kBAAkB;;;KAIR,0BACV,SAAS,2BACT;WAAoB;WAA8B,QAAQ;WAAsB;MAC7E,QAAQ;UAEI;;WAEN;WACA,SAAS;;UAGH;EACf,iBAAiB;;EAEjB,SAAS;;EAET,eAAe,sBAAsB,SAAS,yBAAyB,cAAc;EACrF,cAAc,cAAc,SAAS,uBAAuB;EAC5D,OAAO,uBAAuB;;EAE9B;EACA,WAAW;;UAGI;WACN;;WAEA,cAAc,wBAAwB;;;;wBCmKjC,qBAAqB,SAAS,wBAAwB;;wBAKtD,2BAA2B,SAAS,kBAAkB,SAAS;wBAM/D,sBAAsB,SAAS,UAAU;;YAO7C;IACR,sBAAsB;;;;;;UC5NhB;EACR;EACA;EACA;;qBAGW;;;;;;wBAaG,cAAc,6BAA6B;;wBAM3C,aAAa,UAAU,iBAAiB;wBAQxC,mBAAmB,SAAS;;wBAM5B,eAAe,SAAS;wBAUxB,aAAa"}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { a as profileStatus, c as createProfileRuntime, d as PROFILE_RUNTIME_SERVICE, i as profileItems, l as createProfileRuntimePlugin, n as PROFILE_STATUS_KEY, o as profileSummary, r as profileDescription, s as profileTitle, u as requireProfileRuntime } from "./profileText-B1dz_9lS.mjs";
2
+ export { PROFILE_RUNTIME_SERVICE, PROFILE_STATUS_KEY, createProfileRuntime, createProfileRuntimePlugin, profileDescription, profileItems, profileStatus, profileSummary, profileTitle, requireProfileRuntime };
@@ -0,0 +1,227 @@
1
+ import { parseProfileBinding } from "@agimon-ai/po-config/profiles";
2
+ //#region src/constants/profileRuntime.ts
3
+ const PROFILE_RUNTIME_SERVICE = "po/profile-runtime";
4
+ //#endregion
5
+ //#region src/services/profileRuntime/index.ts
6
+ const UNAVAILABLE = "Profile integration provider is unavailable";
7
+ const INVALIDATED = "Profile operation was invalidated";
8
+ /** A single selected profile and provider, owned by one session, not a provider registry. */
9
+ var SessionProfileRuntime = class {
10
+ options;
11
+ controller = new AbortController();
12
+ snapshot;
13
+ provider;
14
+ connection;
15
+ transition = Promise.resolve();
16
+ retirement = Promise.resolve();
17
+ pending = /* @__PURE__ */ new Set();
18
+ initializing = false;
19
+ disposed = false;
20
+ disposal;
21
+ constructor(options) {
22
+ this.options = options;
23
+ this.snapshot = this.capture(options.profileName, 1);
24
+ }
25
+ capture(profileName, generation) {
26
+ const binding = profileName === void 0 ? void 0 : this.options.readBinding(profileName);
27
+ return Object.freeze({
28
+ ...profileName === void 0 ? {} : { profileName },
29
+ ...binding === void 0 ? {} : { integration: parseProfileBinding(binding) },
30
+ generation,
31
+ signal: this.controller.signal
32
+ });
33
+ }
34
+ readSelection() {
35
+ return this.snapshot;
36
+ }
37
+ invalidate() {
38
+ this.controller.abort();
39
+ const connection = this.connection;
40
+ this.connection = void 0;
41
+ if (connection) {
42
+ this.retirement = this.retirement.then(async () => {
43
+ try {
44
+ await connection.dispose();
45
+ } catch {
46
+ throw new Error("Profile provider disposal failed");
47
+ }
48
+ });
49
+ this.track(this.retirement);
50
+ }
51
+ }
52
+ track(work) {
53
+ this.pending.add(work);
54
+ work.then(() => this.pending.delete(work), () => this.pending.delete(work));
55
+ return work;
56
+ }
57
+ initialize() {
58
+ const snapshot = this.snapshot;
59
+ const provider = this.provider;
60
+ this.initializing = Boolean(snapshot.integration && provider);
61
+ const work = (async () => {
62
+ await this.retirement;
63
+ if (snapshot.signal.aborted) return;
64
+ if (!snapshot.integration || !provider) return;
65
+ if (snapshot.integration.provider !== provider.name) throw new Error(UNAVAILABLE);
66
+ let connection;
67
+ try {
68
+ connection = await provider.factory(snapshot.integration, {
69
+ profileName: snapshot.profileName,
70
+ generation: snapshot.generation,
71
+ signal: snapshot.signal
72
+ });
73
+ } catch {
74
+ if (snapshot.signal.aborted) return;
75
+ throw new Error("Profile provider initialization failed");
76
+ }
77
+ if (snapshot.signal.aborted || this.snapshot !== snapshot || this.disposed) {
78
+ try {
79
+ await connection.dispose();
80
+ } catch {
81
+ throw new Error("Profile provider disposal failed");
82
+ }
83
+ return;
84
+ }
85
+ this.connection = connection;
86
+ })();
87
+ this.transition = this.track(work.finally(() => {
88
+ if (this.snapshot === snapshot) this.initializing = false;
89
+ }));
90
+ return this.transition;
91
+ }
92
+ async select(profileName) {
93
+ if (this.disposed) throw new Error(INVALIDATED);
94
+ if (this.snapshot.profileName === profileName && !this.snapshot.signal.aborted && (!this.snapshot.integration || !this.provider || this.connection || this.initializing)) return;
95
+ this.invalidate();
96
+ this.controller = new AbortController();
97
+ this.snapshot = this.capture(profileName, this.snapshot.generation + 1);
98
+ await this.initialize();
99
+ }
100
+ async ready() {
101
+ const snapshot = this.snapshot;
102
+ await this.transition;
103
+ if (this.disposed || snapshot.signal.aborted || this.snapshot !== snapshot) throw new Error(INVALIDATED);
104
+ if (snapshot.integration && !this.connection) throw new Error(UNAVAILABLE);
105
+ }
106
+ async attachProvider(providerName, factory) {
107
+ if (this.disposed || this.snapshot.signal.aborted) throw new Error(INVALIDATED);
108
+ if (this.provider) throw new Error("Profile provider is already attached");
109
+ if (this.snapshot.integration && this.snapshot.integration.provider !== providerName) throw new Error(UNAVAILABLE);
110
+ const provider = {
111
+ name: providerName,
112
+ factory
113
+ };
114
+ this.provider = provider;
115
+ try {
116
+ await this.initialize();
117
+ await this.ready();
118
+ if (this.disposed || this.provider !== provider) throw new Error(INVALIDATED);
119
+ } catch {
120
+ if (this.provider === provider) this.provider = void 0;
121
+ this.invalidate();
122
+ throw new Error("Profile provider initialization failed");
123
+ }
124
+ let detached = false;
125
+ return async () => {
126
+ if (detached || this.provider !== provider) return;
127
+ detached = true;
128
+ this.invalidate();
129
+ this.provider = void 0;
130
+ this.controller = new AbortController();
131
+ this.snapshot = Object.freeze({
132
+ ...this.snapshot,
133
+ generation: this.snapshot.generation + 1,
134
+ signal: this.controller.signal
135
+ });
136
+ await this.retirement;
137
+ };
138
+ }
139
+ async resolveSecret(name, request) {
140
+ if (this.initializing) throw new Error("Profile secrets are unavailable during provider initialization");
141
+ await this.ready();
142
+ const snapshot = this.snapshot;
143
+ const connection = this.connection;
144
+ const reference = snapshot.integration?.secrets[name];
145
+ if (!connection || !reference || !Object.hasOwn(snapshot.integration.secrets, name)) throw new Error("Profile secret alias is unavailable");
146
+ if (!reference.allowedOrigins.includes(request.origin)) throw new Error("Profile secret origin is not allowed");
147
+ const signal = request.signal ? AbortSignal.any([snapshot.signal, request.signal]) : snapshot.signal;
148
+ if (signal.aborted) throw new Error(INVALIDATED);
149
+ let value;
150
+ try {
151
+ value = await connection.resolveSecret(reference, signal);
152
+ } catch {
153
+ throw new Error("Profile secret resolution failed");
154
+ }
155
+ if (signal.aborted || this.snapshot !== snapshot || this.connection !== connection) throw new Error(INVALIDATED);
156
+ if (typeof value !== "string" || value.length === 0) throw new Error("Profile secret field is unavailable");
157
+ return value;
158
+ }
159
+ dispose() {
160
+ if (this.disposal) return this.disposal;
161
+ this.disposed = true;
162
+ this.invalidate();
163
+ this.provider = void 0;
164
+ this.disposal = (async () => {
165
+ if ((await Promise.allSettled([...this.pending, this.retirement])).some((result) => result.status === "rejected")) throw new Error("Profile runtime disposal failed");
166
+ })();
167
+ return this.disposal;
168
+ }
169
+ };
170
+ function createProfileRuntime(options) {
171
+ return new SessionProfileRuntime(options);
172
+ }
173
+ /** Mounted in the scoped root services array, before dependent integration tools. */
174
+ function createProfileRuntimePlugin(runtime) {
175
+ return (context) => {
176
+ context.provide(PROFILE_RUNTIME_SERVICE, runtime);
177
+ };
178
+ }
179
+ function requireProfileRuntime(context) {
180
+ const service = context.get(PROFILE_RUNTIME_SERVICE);
181
+ if (!service) throw new Error("Profile runtime service is unavailable");
182
+ return service;
183
+ }
184
+ //#endregion
185
+ //#region src/services/profileText/index.ts
186
+ const NONE = "(none)";
187
+ const PROFILE_STATUS_KEY = "doom-profile";
188
+ /** The command a queued voice switch invokes, and the reload handoff kind it parks. */
189
+ const PROFILE_COMMAND = "profile";
190
+ /**
191
+ * The published axis content: the active profile's name, empty while
192
+ * profiles exist with none active, and undefined to withhold the status so
193
+ * the cockpit keeps the axis off the bar entirely.
194
+ */
195
+ function profileStatus(current, hasProfiles) {
196
+ if (current) return current;
197
+ return hasProfiles ? "" : void 0;
198
+ }
199
+ /** Rows for the single-select profile picker. */
200
+ function profileItems(profiles) {
201
+ return profiles.map((profile) => ({
202
+ value: profile.name,
203
+ label: profile.name,
204
+ description: profileDescription(profile)
205
+ }));
206
+ }
207
+ function profileDescription(profile) {
208
+ const environmentKeys = Object.keys(profile.env).sort();
209
+ return environmentKeys.length > 0 ? `${profile.persona} (env: ${environmentKeys.join(", ")})` : profile.persona;
210
+ }
211
+ /** Shown when the picked profile is already active. */
212
+ function profileSummary(profile) {
213
+ const environmentKeys = Object.keys(profile.env).sort();
214
+ return [
215
+ `Profile ${profile.name}`,
216
+ `Persona: ${profile.persona}`,
217
+ `Env: ${environmentKeys.join(", ") || NONE}`,
218
+ "Already loaded."
219
+ ].join("\n");
220
+ }
221
+ function profileTitle(current) {
222
+ return `Profile (current: ${current ?? NONE})`;
223
+ }
224
+ //#endregion
225
+ export { profileStatus as a, createProfileRuntime as c, PROFILE_RUNTIME_SERVICE as d, profileItems as i, createProfileRuntimePlugin as l, PROFILE_STATUS_KEY as n, profileSummary as o, profileDescription as r, profileTitle as s, PROFILE_COMMAND as t, requireProfileRuntime as u };
226
+
227
+ //# sourceMappingURL=profileText-B1dz_9lS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profileText-B1dz_9lS.mjs","names":[],"sources":["../src/constants/profileRuntime.ts","../src/services/profileRuntime/index.ts","../src/services/profileText/index.ts"],"sourcesContent":["export const PROFILE_RUNTIME_SERVICE = 'po/profile-runtime';\n","import { parseProfileBinding } from '@agimon-ai/po-config/profiles';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { PROFILE_RUNTIME_SERVICE } from '../../constants/profileRuntime';\nimport type {\n ProfileProviderFactory,\n ProfileRuntime,\n ProfileRuntimeOptions,\n ProfileRuntimeSnapshot,\n ProfileSecretRequest,\n ProfileSecretResolver,\n} from './type';\n\nconst UNAVAILABLE = 'Profile integration provider is unavailable';\nconst INVALIDATED = 'Profile operation was invalidated';\n\n/** A single selected profile and provider, owned by one session, not a provider registry. */\nclass SessionProfileRuntime implements ProfileRuntime {\n private controller = new AbortController();\n private snapshot: ProfileRuntimeSnapshot;\n private provider?: { name: string; factory: ProfileProviderFactory };\n private connection?: ProfileSecretResolver;\n private transition: Promise<void> = Promise.resolve();\n private retirement: Promise<void> = Promise.resolve();\n private readonly pending = new Set<Promise<void>>();\n private initializing = false;\n private disposed = false;\n private disposal?: Promise<void>;\n\n constructor(private readonly options: ProfileRuntimeOptions) {\n this.snapshot = this.capture(options.profileName, 1);\n }\n\n private capture(profileName: string | undefined, generation: number): ProfileRuntimeSnapshot {\n const binding = profileName === undefined ? undefined : this.options.readBinding(profileName);\n return Object.freeze({\n ...(profileName === undefined ? {} : { profileName }),\n ...(binding === undefined ? {} : { integration: parseProfileBinding(binding) }),\n generation,\n signal: this.controller.signal,\n });\n }\n\n readSelection(): ProfileRuntimeSnapshot {\n return this.snapshot;\n }\n\n invalidate(): void {\n this.controller.abort();\n const connection = this.connection;\n this.connection = undefined;\n if (connection) {\n this.retirement = this.retirement.then(async () => {\n try {\n await connection.dispose();\n } catch {\n throw new Error('Profile provider disposal failed');\n }\n });\n void this.track(this.retirement);\n }\n }\n\n private track(work: Promise<void>): Promise<void> {\n this.pending.add(work);\n // Keep rejection observable through ready/dispose while preventing an unhandled\n // rejection when selection invalidates an initialization before its owner awaits it.\n void work.then(\n () => this.pending.delete(work),\n () => this.pending.delete(work),\n );\n return work;\n }\n\n private initialize(): Promise<void> {\n const snapshot = this.snapshot;\n const provider = this.provider;\n this.initializing = Boolean(snapshot.integration && provider);\n const work = (async () => {\n await this.retirement;\n if (snapshot.signal.aborted) return;\n if (!snapshot.integration || !provider) return;\n if (snapshot.integration.provider !== provider.name) throw new Error(UNAVAILABLE);\n let connection: ProfileSecretResolver;\n try {\n connection = await provider.factory(snapshot.integration, {\n profileName: snapshot.profileName!,\n generation: snapshot.generation,\n signal: snapshot.signal,\n });\n } catch {\n // A retired factory commonly rejects on abort. That cannot remove the\n // provider attachment or poison the replacement generation.\n if (snapshot.signal.aborted) return;\n throw new Error('Profile provider initialization failed');\n }\n if (snapshot.signal.aborted || this.snapshot !== snapshot || this.disposed) {\n try {\n await connection.dispose();\n } catch {\n throw new Error('Profile provider disposal failed');\n }\n return;\n }\n this.connection = connection;\n })();\n this.transition = this.track(\n work.finally(() => {\n if (this.snapshot === snapshot) this.initializing = false;\n }),\n );\n return this.transition;\n }\n\n async select(profileName?: string): Promise<void> {\n if (this.disposed) throw new Error(INVALIDATED);\n if (\n this.snapshot.profileName === profileName &&\n !this.snapshot.signal.aborted &&\n (!this.snapshot.integration || !this.provider || this.connection || this.initializing)\n )\n return;\n this.invalidate();\n this.controller = new AbortController();\n // If reading/validation fails, leave the old generation aborted, never usable.\n this.snapshot = this.capture(profileName, this.snapshot.generation + 1);\n await this.initialize();\n }\n\n async ready(): Promise<void> {\n const snapshot = this.snapshot;\n await this.transition;\n if (this.disposed || snapshot.signal.aborted || this.snapshot !== snapshot) throw new Error(INVALIDATED);\n if (snapshot.integration && !this.connection) throw new Error(UNAVAILABLE);\n }\n\n async attachProvider(providerName: string, factory: ProfileProviderFactory): Promise<() => Promise<void>> {\n if (this.disposed || this.snapshot.signal.aborted) throw new Error(INVALIDATED);\n if (this.provider) throw new Error('Profile provider is already attached');\n if (this.snapshot.integration && this.snapshot.integration.provider !== providerName) throw new Error(UNAVAILABLE);\n const provider = { name: providerName, factory };\n this.provider = provider;\n try {\n await this.initialize();\n await this.ready();\n if (this.disposed || this.provider !== provider) throw new Error(INVALIDATED);\n } catch {\n if (this.provider === provider) this.provider = undefined;\n this.invalidate();\n throw new Error('Profile provider initialization failed');\n }\n let detached = false;\n return async () => {\n if (detached || this.provider !== provider) return;\n detached = true;\n this.invalidate();\n this.provider = undefined;\n this.controller = new AbortController();\n this.snapshot = Object.freeze({\n ...this.snapshot,\n generation: this.snapshot.generation + 1,\n signal: this.controller.signal,\n });\n await this.retirement;\n };\n }\n\n async resolveSecret(name: string, request: ProfileSecretRequest): Promise<string> {\n // Do not await ready here: a provider factory invoking this callback would\n // otherwise wait for itself. Browser creation may retain, but not invoke it.\n if (this.initializing) throw new Error('Profile secrets are unavailable during provider initialization');\n await this.ready();\n const snapshot = this.snapshot;\n const connection = this.connection;\n const reference = snapshot.integration?.secrets[name];\n if (!connection || !reference || !Object.hasOwn(snapshot.integration!.secrets, name)) {\n throw new Error('Profile secret alias is unavailable');\n }\n if (!reference.allowedOrigins.includes(request.origin)) throw new Error('Profile secret origin is not allowed');\n const signal = request.signal ? AbortSignal.any([snapshot.signal, request.signal]) : snapshot.signal;\n if (signal.aborted) throw new Error(INVALIDATED);\n let value: string;\n try {\n value = await connection.resolveSecret(reference, signal);\n } catch {\n // Provider failures must not leak API responses, credential fields or secrets.\n throw new Error('Profile secret resolution failed');\n }\n if (signal.aborted || this.snapshot !== snapshot || this.connection !== connection) throw new Error(INVALIDATED);\n if (typeof value !== 'string' || value.length === 0) throw new Error('Profile secret field is unavailable');\n return value;\n }\n\n dispose(): Promise<void> {\n if (this.disposal) return this.disposal;\n this.disposed = true;\n this.invalidate();\n this.provider = undefined;\n this.disposal = (async () => {\n const results = await Promise.allSettled([...this.pending, this.retirement]);\n if (results.some((result) => result.status === 'rejected')) throw new Error('Profile runtime disposal failed');\n })();\n return this.disposal;\n }\n}\n\nexport function createProfileRuntime(options: ProfileRuntimeOptions): ProfileRuntime {\n return new SessionProfileRuntime(options);\n}\n\n/** Mounted in the scoped root services array, before dependent integration tools. */\nexport function createProfileRuntimePlugin(runtime: ProfileRuntime): (context: Context) => void {\n return (context) => {\n context.provide(PROFILE_RUNTIME_SERVICE, runtime);\n };\n}\n\nexport function requireProfileRuntime(context: Context): ProfileRuntime {\n const service = context.get(PROFILE_RUNTIME_SERVICE);\n if (!service) throw new Error('Profile runtime service is unavailable');\n return service;\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'po/profile-runtime': ProfileRuntime;\n }\n}\n","import type { AgentProfile } from '@agimon-ai/po-config/profiles';\n\nconst NONE = '(none)';\n\n/** Footer status key the cockpit's profile axis reads. */\ninterface SelectItem {\n value: string;\n label: string;\n description?: string;\n}\n\nexport const PROFILE_STATUS_KEY = 'doom-profile';\n\n/** Identity this package registers voice capabilities under. */\nexport const PROFILE_SOURCE = '@agimon-ai/po-profile';\n\n/** The command a queued voice switch invokes, and the reload handoff kind it parks. */\nexport const PROFILE_COMMAND = 'profile';\n\n/**\n * The published axis content: the active profile's name, empty while\n * profiles exist with none active, and undefined to withhold the status so\n * the cockpit keeps the axis off the bar entirely.\n */\nexport function profileStatus(current: string | undefined, hasProfiles: boolean): string | undefined {\n if (current) return current;\n return hasProfiles ? '' : undefined;\n}\n\n/** Rows for the single-select profile picker. */\nexport function profileItems(profiles: AgentProfile[]): SelectItem[] {\n return profiles.map((profile) => ({\n value: profile.name,\n label: profile.name,\n description: profileDescription(profile),\n }));\n}\n\nexport function profileDescription(profile: AgentProfile): string {\n const environmentKeys = Object.keys(profile.env).sort();\n return environmentKeys.length > 0 ? `${profile.persona} (env: ${environmentKeys.join(', ')})` : profile.persona;\n}\n\n/** Shown when the picked profile is already active. */\nexport function profileSummary(profile: AgentProfile): string {\n const environmentKeys = Object.keys(profile.env).sort();\n return [\n `Profile ${profile.name}`,\n `Persona: ${profile.persona}`,\n `Env: ${environmentKeys.join(', ') || NONE}`,\n 'Already loaded.',\n ].join('\\n');\n}\n\nexport function profileTitle(current?: string): string {\n return `Profile (current: ${current ?? NONE})`;\n}\n"],"mappings":"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"}