@agimon-ai/po-config 0.0.0-alpha.113 → 0.0.0-alpha.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/server.cjs +1 -1
- package/dist/extensions/server.mjs +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{profiles-lG_t2vKD.mjs → profiles-fcR7TAmA.mjs} +23 -3
- package/dist/profiles-fcR7TAmA.mjs.map +1 -0
- package/dist/{profiles-D_omhOvM.cjs → profiles-q6C39HtK.cjs} +28 -2
- package/dist/profiles-q6C39HtK.cjs.map +1 -0
- package/dist/profiles.cjs +2 -1
- package/dist/profiles.d.mts +2 -0
- package/dist/profiles.d.mts.map +1 -1
- package/dist/profiles.mjs +1 -1
- package/dist/selectionSwitch.cjs +1 -1
- package/dist/selectionSwitch.mjs +1 -1
- package/dist/{settingsApi-C_rqLkZZ.cjs → settingsApi-Bkgsqc4V.cjs} +24 -16
- package/dist/settingsApi-Bkgsqc4V.cjs.map +1 -0
- package/dist/{settingsApi-r4lj6nnG.mjs → settingsApi-CY5Lq55P.mjs} +27 -19
- package/dist/settingsApi-CY5Lq55P.mjs.map +1 -0
- package/package.json +4 -4
- package/dist/profiles-D_omhOvM.cjs.map +0 -1
- package/dist/profiles-lG_t2vKD.mjs.map +0 -1
- package/dist/settingsApi-C_rqLkZZ.cjs.map +0 -1
- package/dist/settingsApi-r4lj6nnG.mjs.map +0 -1
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_settingsApi = require("../settingsApi-
|
|
5
|
+
const require_settingsApi = require("../settingsApi-Bkgsqc4V.cjs");
|
|
6
6
|
const require_sessionConfig = require("../sessionConfig-DDpiIhIL.cjs");
|
|
7
7
|
let _agimon_ai_po_core_platform = require("@agimon-ai/po-core/platform");
|
|
8
8
|
let _agimon_ai_po_core_mcpProjection = require("@agimon-ai/po-core/mcpProjection");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createSettingsApi } from "../settingsApi-
|
|
1
|
+
import { t as createSettingsApi } from "../settingsApi-CY5Lq55P.mjs";
|
|
2
2
|
import { d as providePoConfigContext, o as createNativePoConfigContext } from "../sessionConfig-DB-c4mPl.mjs";
|
|
3
3
|
import { BACKGROUND_CONTEXT, requirePoFs, withAbortSignal } from "@agimon-ai/po-core/platform";
|
|
4
4
|
import { PO_MCP_PROJECTION_SERVICE, createDisabledPoMcpProjection, createPoMcpProjectionService, isPoMcpProjection } from "@agimon-ai/po-core/mcpProjection";
|
package/dist/index.cjs
CHANGED
|
@@ -9,10 +9,10 @@ const require_layeredConfig = require("./layeredConfig-BwWQJbk8.cjs");
|
|
|
9
9
|
const require_domains = require("./domains-Dg4YAym-.cjs");
|
|
10
10
|
const require_harnessState = require("./harnessState-CQBNDL1D.cjs");
|
|
11
11
|
const require_harnessStore = require("./harnessStore-Dgn3T4sR.cjs");
|
|
12
|
-
const require_settingsApi = require("./settingsApi-
|
|
12
|
+
const require_settingsApi = require("./settingsApi-Bkgsqc4V.cjs");
|
|
13
13
|
const require_piConfig = require("./piConfig-cluCie5i.cjs");
|
|
14
14
|
const require_majorModes = require("./majorModes-BmRJ4RvP.cjs");
|
|
15
|
-
const require_profiles = require("./profiles-
|
|
15
|
+
const require_profiles = require("./profiles-q6C39HtK.cjs");
|
|
16
16
|
const require_init = require("./init-MU3RliHW.cjs");
|
|
17
17
|
require("./config-zZz80Mh5.cjs");
|
|
18
18
|
const require_sessionConfig = require("./sessionConfig-DDpiIhIL.cjs");
|
package/dist/index.d.mts
CHANGED
|
@@ -19,7 +19,7 @@ import { PoApi } from "@agimon-ai/po-core/packageApi";
|
|
|
19
19
|
//#region src/services/settingsApi/index.d.ts
|
|
20
20
|
/**
|
|
21
21
|
* Config handlers are bound to their mount. Request paths cannot choose a different repository.
|
|
22
|
-
*
|
|
22
|
+
* Reads, writes and image settings all go through the host's FileSystem.
|
|
23
23
|
*/
|
|
24
24
|
export declare const createSettingsApi: (fs: FileSystem) => PoApi;
|
|
25
25
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -8,10 +8,10 @@ import { r as PO_DIR } from "./layeredConfig-gg8cI8jj.mjs";
|
|
|
8
8
|
import { _ as findPluginManifestPathAsync, b as isRemotePluginSource, c as resolvePluginDirectories, g as expandDomainNames, h as domainCompletionPrefix, l as resolvePluginEntries, m as domainCompletionItems, o as listDomainNames, s as loadDomains, u as resolveSharedSkills, v as findPluginManifestPath, x as pluginDirectoryForSource, y as MARKETPLACE_MANIFEST_RELATIVE_PATHS } from "./domains-D5M1H3rX.mjs";
|
|
9
9
|
import { i as readHarnessState, n as HARNESS_STATE_KEYS, r as projectHarnessEnvironment, t as FILE_ONLY_STATE_FIELDS } from "./harnessState-ufE-npBa.mjs";
|
|
10
10
|
import { _ as HARNESS_STATE_POINTER, a as requireHarnessPaths, d as getHarnessState, f as getSessionHarnessState, g as updateHarnessState, h as snapshotHarnessState, l as createHarnessSession, m as restoreHarnessStateSnapshot, o as requireHarnessRoot, p as loadHarnessState, r as harnessRoot, u as disposeHarnessState, v as resetHarnessStore } from "./harnessStore-yqKUx-kP.mjs";
|
|
11
|
-
import { t as createSettingsApi } from "./settingsApi-
|
|
11
|
+
import { t as createSettingsApi } from "./settingsApi-CY5Lq55P.mjs";
|
|
12
12
|
import { a as loadPiConfigAsync, c as piConfigPaths, d as MIN_IMAGE_MAX_DIMENSION, f as clampImageMaxDimension, i as loadPiConfig, l as piImageSettingsPath, o as loadPiImageSettings, p as parsePiImageSettings, s as savePiImageSettings, u as DEFAULT_IMAGE_MAX_DIMENSION } from "./piConfig-Bq36PQFF.mjs";
|
|
13
13
|
import { a as loadMajorModesConfigLenient, c as layerEntries, i as loadMajorModesConfig, l as resolveLayers, r as readPackageConfigurations, s as isLocalPackageSpecifier, u as resolvePackageConfigurations } from "./majorModes-CBTXMJZb.mjs";
|
|
14
|
-
import { _ as replaceProfileEnvironment, f as loadProfiles, h as applyProfileEnvironment, l as buildPersonaPrompt, m as PERSONA_FILES, p as resolveProfile, u as listProfileNames } from "./profiles-
|
|
14
|
+
import { _ as replaceProfileEnvironment, f as loadProfiles, h as applyProfileEnvironment, l as buildPersonaPrompt, m as PERSONA_FILES, p as resolveProfile, u as listProfileNames } from "./profiles-fcR7TAmA.mjs";
|
|
15
15
|
import { a as GLOBAL_PO_SEED_FILES, i as initializeRepositoryPoConfig, o as PO_CONFIG_TEMPLATES, r as initializeGlobalPoConfig, s as REPOSITORY_PO_CONFIG_TEMPLATES } from "./init-BJvRovAw.mjs";
|
|
16
16
|
import { t as PO_CONFIG_SERVICE } from "./config-BBvn_ZLP.mjs";
|
|
17
17
|
import { _ as supersedePoConfigTransition, a as appendPoConfigTransition, c as createPoConfigContextAsync, d as providePoConfigContext, f as readPoConfigContextGeneration, g as requirePoConfigContext, h as replacePoConfigContext, i as appendPoConfigSelection, l as freezePoConfigContext, m as readPoConfigSelection, n as PO_CONFIG_TRANSITION_ENTRY_TYPE, p as readPoConfigPendingSelection, r as acknowledgePoConfigTransition, s as createPoConfigContext, t as PO_CONFIG_ENTRY_TYPE } from "./sessionConfig-DB-c4mPl.mjs";
|
|
@@ -247,6 +247,26 @@ const BROWSER_MODES = /* @__PURE__ */ new Set([
|
|
|
247
247
|
const ALIAS_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
248
248
|
const FIELD_PATTERN = /^(?:[A-Za-z][A-Za-z0-9_.-]{0,63}|profileSecret:[A-Z][A-Z0-9_]{0,63})$/;
|
|
249
249
|
const BROWSER_PROFILE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
250
|
+
/** Browser-level defaults only. Every alias still requires its own exact recipient origins. */
|
|
251
|
+
const PROFILE_SOCIAL_BROWSER_ORIGINS = Object.freeze([
|
|
252
|
+
"https://x.com",
|
|
253
|
+
"https://www.x.com",
|
|
254
|
+
"https://twitter.com",
|
|
255
|
+
"https://www.twitter.com",
|
|
256
|
+
"https://reddit.com",
|
|
257
|
+
"https://www.reddit.com",
|
|
258
|
+
"https://linkedin.com",
|
|
259
|
+
"https://www.linkedin.com",
|
|
260
|
+
"https://facebook.com",
|
|
261
|
+
"https://www.facebook.com",
|
|
262
|
+
"https://instagram.com",
|
|
263
|
+
"https://www.instagram.com",
|
|
264
|
+
"https://tiktok.com",
|
|
265
|
+
"https://www.tiktok.com",
|
|
266
|
+
"https://youtube.com",
|
|
267
|
+
"https://www.youtube.com",
|
|
268
|
+
"https://accounts.google.com"
|
|
269
|
+
]);
|
|
250
270
|
function record(value, location, keys) {
|
|
251
271
|
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${location} must be a mapping`);
|
|
252
272
|
if (keys && Object.keys(value).some((key) => !keys.has(key))) throw new Error(`${location} contains unsupported metadata`);
|
|
@@ -312,7 +332,7 @@ function browser(value, location) {
|
|
|
312
332
|
if (pinned?.required && entry.mode !== void 0 && entry.mode !== "playwright") throw new Error(`${location}.fingerprint.required needs playwright mode`);
|
|
313
333
|
return Object.freeze({
|
|
314
334
|
profileName: entry.profileName,
|
|
315
|
-
allowedOrigins: origins(entry.allowedOrigins, `${location}.allowedOrigins`),
|
|
335
|
+
allowedOrigins: Object.freeze([.../* @__PURE__ */ new Set([...origins(entry.allowedOrigins, `${location}.allowedOrigins`), ...PROFILE_SOCIAL_BROWSER_ORIGINS])]),
|
|
316
336
|
...entry.mode === void 0 ? {} : { mode: entry.mode },
|
|
317
337
|
...entry.proxySecret === void 0 ? {} : { proxySecret: entry.proxySecret },
|
|
318
338
|
...entry.geoip === void 0 ? {} : { geoip: entry.geoip },
|
|
@@ -1037,6 +1057,6 @@ async function commitGlobalProfileRootAsync(fs, plan, context) {
|
|
|
1037
1057
|
});
|
|
1038
1058
|
}
|
|
1039
1059
|
//#endregion
|
|
1040
|
-
export { parsePersonaFrontMatter as S, replaceProfileEnvironment as _, loadProfileCatalogAsync as a,
|
|
1060
|
+
export { parsePersonaFrontMatter as C, readPersonaIcon as S, replaceProfileEnvironment as _, loadProfileCatalogAsync as a, parseProfileVaultSecrets as b, resolveProfileAsync as c, loadProfileCatalog as d, loadProfiles as f, inlineProfile as g, applyProfileEnvironment as h, listProfileNamesAsync as i, buildPersonaPrompt as l, PERSONA_FILES as m, buildPersonaPromptAsync as n, loadProfilesAsync as o, resolveProfile as p, commitGlobalProfileRootAsync as r, planGlobalProfileRootAsync as s, ProfileCatalogChangedError as t, listProfileNames as u, PROFILE_SOCIAL_BROWSER_ORIGINS as v, readPersonaIconAsync as x, parseProfileBinding as y };
|
|
1041
1061
|
|
|
1042
|
-
//# sourceMappingURL=profiles-
|
|
1062
|
+
//# sourceMappingURL=profiles-fcR7TAmA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles-fcR7TAmA.mjs","names":["isRecord","parseYaml","PARENT_DIRECTORY","Buffer","parseYaml","stringifyYaml","parseProfile","readPersonaFrontMatter","readPersonaPresentation","containsPersonaFile","readSidecar","discoverProfile","discoverProfileRoot","readProfileLayers","profilesFromLayers"],"sources":["../src/services/personaFrontMatter/index.ts","../src/services/personaIcon/core.ts","../src/services/personaIcon/sync.ts","../src/services/personaIcon/index.ts","../src/services/profileBinding/index.ts","../src/services/profiles/core.ts","../src/services/profiles/sync.ts","../src/services/profiles/index.ts"],"sourcesContent":["import { parse as parseYaml } from 'yaml';\n\nimport type { PersonaDocument, PersonaFrontMatter, PersonaVoiceOverride } from '../../types/profiles';\n\n/**\n * Optional identity a persona declares at the top of its `profile.md`.\n *\n * A profile used to be prompt text only, so there was nowhere to say who the\n * persona is or how it should sound. Front-matter puts that beside the persona\n * text it describes, which is the only place that works for both explicit\n * `profiles.yaml` entries and folders found by root discovery.\n *\n * Recognition is deliberately narrow. Personas that exist today were written\n * without any of this, and one of them may legitimately open with a horizontal\n * rule, so a leading fence alone is not enough to claim the block. A block is\n * only treated as identity when it is fenced at the very first line, closed,\n * parses as a mapping, and declares at least one field this contract owns.\n * Anything else is passed through byte for byte.\n */\n\nconst FENCE = '---';\nconst OWNED_KEYS = ['name', 'icon', 'role', 'voice'] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readVoice(value: unknown): PersonaVoiceOverride | undefined {\n if (!isRecord(value)) return undefined;\n const voice = typeof value.voice === 'string' && value.voice.trim().length > 0 ? value.voice.trim() : undefined;\n const rate = typeof value.rate === 'number' && Number.isFinite(value.rate) ? value.rate : undefined;\n if (voice === undefined && rate === undefined) return undefined;\n return { ...(voice === undefined ? {} : { voice }), ...(rate === undefined ? {} : { rate }) };\n}\n\nfunction readText(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;\n}\n\nfunction readFrontMatter(parsed: Record<string, unknown>): PersonaFrontMatter | undefined {\n const name = readText(parsed.name);\n const icon = readText(parsed.icon);\n const role = readText(parsed.role);\n const voice = readVoice(parsed.voice);\n if (name === undefined && icon === undefined && role === undefined && voice === undefined) return undefined;\n return {\n ...(name === undefined ? {} : { name }),\n ...(icon === undefined ? {} : { icon }),\n ...(role === undefined ? {} : { role }),\n ...(voice === undefined ? {} : { voice }),\n };\n}\n\n/**\n * Splits a recognised identity block off a persona document.\n *\n * Never throws: a malformed avatar must not make a persona unloadable, so an\n * unparseable or unrecognised block leaves the document exactly as it arrived.\n */\nexport function parsePersonaFrontMatter(content: string): PersonaDocument {\n const lines = content.split('\\n');\n if (lines[0]?.trimEnd() !== FENCE) return { body: content };\n\n const closingIndex = lines.findIndex((line, index) => index > 0 && line.trimEnd() === FENCE);\n if (closingIndex === -1) return { body: content };\n\n let parsed: unknown;\n try {\n parsed = parseYaml(lines.slice(1, closingIndex).join('\\n'));\n } catch {\n return { body: content };\n }\n if (!isRecord(parsed)) return { body: content };\n if (!OWNED_KEYS.some((key) => Object.hasOwn(parsed, key))) return { body: content };\n\n const frontMatter = readFrontMatter(parsed);\n if (!frontMatter) return { body: content };\n return { frontMatter, body: lines.slice(closingIndex + 1).join('\\n') };\n}\n","import { Buffer } from 'node:buffer';\nimport path from 'node:path';\n\nimport { PROFILE_ICON_MAX_DATA_URL_LENGTH, type ProfileIconMimeType } from '@agimon-ai/po-core/profileIdentity';\n\n/**\n * Pure half of persona icon loading: confinement and image sniffing. The\n * readers in `index.ts` (async, over a FileSystem) and `sync.ts` (Node shim)\n * only resolve paths and fetch bytes.\n */\nconst PARENT_DIRECTORY = '..';\n\n/**\n * Magic-byte signatures, checked instead of trusting the filename.\n *\n * `image/svg+xml` is absent on purpose: an SVG rendered same-origin executes\n * script, and the author of this path is whoever wrote the persona. Do not add\n * it to match the cockpit's broader media catalog.\n */\nconst SIGNATURES: readonly { readonly mime: ProfileIconMimeType; readonly test: (bytes: Buffer) => boolean }[] = [\n {\n mime: 'image/png',\n test: (b) => b.length > 8 && b.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])),\n },\n { mime: 'image/jpeg', test: (b) => b.length > 3 && b[0] === 0xff && b[1] === 0xd8 && b[2] === 0xff },\n { mime: 'image/gif', test: (b) => b.length > 6 && b.subarray(0, 6).toString('latin1').startsWith('GIF8') },\n {\n mime: 'image/webp',\n test: (b) =>\n b.length > 12 &&\n b.subarray(0, 4).toString('latin1') === 'RIFF' &&\n b.subarray(8, 12).toString('latin1') === 'WEBP',\n },\n];\n\n/** True when `realIconPath` lies inside `realPersonaPath` (both already canonical). */\nexport function isInsidePersona(realPersonaPath: string, realIconPath: string): boolean {\n const relative = path.relative(realPersonaPath, realIconPath);\n return !(\n relative === PARENT_DIRECTORY ||\n relative.startsWith(`${PARENT_DIRECTORY}${path.sep}`) ||\n path.isAbsolute(relative)\n );\n}\n\n/** A bounded `data:` URL for an allowed image, or undefined. */\nexport function iconDataUrl(content: Uint8Array): string | undefined {\n const bytes = Buffer.from(content.buffer, content.byteOffset, content.byteLength);\n const mime = SIGNATURES.find((signature) => signature.test(bytes))?.mime;\n if (!mime) return undefined;\n const dataUrl = `data:${mime};base64,${bytes.toString('base64')}`;\n return dataUrl.length > PROFILE_ICON_MAX_DATA_URL_LENGTH ? undefined : dataUrl;\n}\n","// sync: Preserve the exported Node-only readPersonaIcon signature until phase 2.\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { iconDataUrl, isInsidePersona } from './core';\n\n/**\n * Resolves an icon declared in persona front-matter, or undefined when it is\n * missing, unreadable, not an allowed image, escapes the persona directory, or\n * exceeds the data-URL ceiling.\n *\n * @deprecated Node-only sync shim; use readPersonaIconAsync. Removed in M2.\n */\nexport function readPersonaIcon(personaPath: string, iconRelative: string): string | undefined {\n if (path.isAbsolute(iconRelative)) return undefined;\n\n try {\n const realPersonaPath = fs.realpathSync(personaPath);\n const iconPath = path.resolve(realPersonaPath, iconRelative);\n if (!fs.existsSync(iconPath)) return undefined;\n\n const realIconPath = fs.realpathSync(iconPath);\n if (!isInsidePersona(realPersonaPath, realIconPath)) return undefined;\n if (!fs.statSync(realIconPath).isFile()) return undefined;\n\n return iconDataUrl(fs.readFileSync(realIconPath));\n } catch {\n return undefined;\n }\n}\n","import path from 'node:path';\n\nimport { getOrThrow, type FileSystem } from '@agimon-ai/po-core/platform';\n\nimport { iconDataUrl, isInsidePersona } from './core';\n\ntype IoContext = Parameters<FileSystem['readTextFile']>[1];\n\n/**\n * Reads a persona icon into a bounded `data:` URL.\n *\n * The icon travels inside the journalled identity entry rather than through an\n * HTTP route. A route would leave a request-time filesystem resolution reachable\n * from the browser for the life of a session, defended on every request forever;\n * this resolves the path once, server side, at the moment the profile loads.\n *\n * The path comes from user-authored front-matter, so it is confined the same way\n * `buildPersonaPrompt` confines persona files: a symlink must not read outside\n * the persona directory.\n *\n * Every failure is silent and returns undefined. An avatar is decoration, and a\n * broken one must never stop a persona from loading. That includes a host whose\n * filesystem lacks the persona entirely, such as the edge.\n */\nexport async function readPersonaIconAsync(\n fs: FileSystem,\n personaPath: string,\n iconRelative: string,\n context: IoContext,\n): Promise<string | undefined> {\n if (path.isAbsolute(iconRelative)) return undefined;\n\n try {\n const realPersonaPath = getOrThrow(await fs.canonicalPath(personaPath, context));\n const iconPath = path.resolve(realPersonaPath, iconRelative);\n if (!getOrThrow(await fs.exists(iconPath, context))) return undefined;\n\n const realIconPath = getOrThrow(await fs.canonicalPath(iconPath, context));\n if (!isInsidePersona(realPersonaPath, realIconPath)) return undefined;\n if (getOrThrow(await fs.fileInfo(realIconPath, context)).kind !== 'file') return undefined;\n\n return iconDataUrl(getOrThrow(await fs.readBinaryFile(realIconPath, context)));\n } catch {\n return undefined;\n }\n}\n\nexport { readPersonaIcon } from './sync';\n","import type {\n ProfileBrowserBinding,\n ProfileBrowserFingerprint,\n ProfileBrowserMode,\n ProfileIntegrationBinding,\n ProfileSecretPurpose,\n ProfileSecretReference,\n ProfileVaultSecretReference,\n} from './type';\n\nconst BINDING_KEYS = new Set(['provider', 'organizationId', 'mailboxId', 'credentialRef', 'secrets', 'browser']);\nconst SECRET_KEYS = new Set(['credentialId', 'field', 'purposes', 'allowedOrigins', 'allowedTargets']);\nconst VAULT_SECRET_KEYS = new Set(['vault', 'purposes', 'allowedOrigins', 'allowedTargets']);\nconst BROWSER_KEYS = new Set([\n 'profileName',\n 'allowedOrigins',\n 'mode',\n 'proxySecret',\n 'geoip',\n 'timezone',\n 'locale',\n 'fingerprint',\n]);\nconst FINGERPRINT_KEYS = new Set(['platform', 'seed', 'required']);\nconst PURPOSES: ReadonlySet<string> = new Set<ProfileSecretPurpose>(['browser', 'proxy', 'env', 'input']);\nconst BROWSER_MODES: ReadonlySet<string> = new Set<ProfileBrowserMode>(['playwright', 'extension', 'stealth']);\nconst ALIAS_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;\nconst FIELD_PATTERN = /^(?:[A-Za-z][A-Za-z0-9_.-]{0,63}|profileSecret:[A-Z][A-Z0-9_]{0,63})$/;\nconst BROWSER_PROFILE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;\n\n/** Browser-level defaults only. Every alias still requires its own exact recipient origins. */\nexport const PROFILE_SOCIAL_BROWSER_ORIGINS = Object.freeze([\n 'https://x.com',\n 'https://www.x.com',\n 'https://twitter.com',\n 'https://www.twitter.com',\n 'https://reddit.com',\n 'https://www.reddit.com',\n 'https://linkedin.com',\n 'https://www.linkedin.com',\n 'https://facebook.com',\n 'https://www.facebook.com',\n 'https://instagram.com',\n 'https://www.instagram.com',\n 'https://tiktok.com',\n 'https://www.tiktok.com',\n 'https://youtube.com',\n 'https://www.youtube.com',\n 'https://accounts.google.com',\n]);\nfunction record(value: unknown, location: string, keys?: ReadonlySet<string>): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`${location} must be a mapping`);\n }\n if (keys && Object.keys(value).some((key) => !keys.has(key))) {\n // Never echo an unknown key or value, either of which might contain a misplaced secret.\n throw new Error(`${location} contains unsupported metadata`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction reference(value: unknown, location: string): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > 256 || /\\s/.test(value)) {\n throw new Error(`${location} must be a non-empty reference without whitespace`);\n }\n return value;\n}\n\nfunction origins(value: unknown, location: string): readonly string[] {\n if (!Array.isArray(value) || value.length === 0) throw new Error(`${location} must contain exact HTTP(S) origins`);\n const result = value.map((entry: unknown) => {\n if (typeof entry !== 'string') throw new Error(`${location} must contain exact HTTP(S) origins`);\n let url: URL;\n try {\n url = new URL(entry);\n } catch {\n throw new Error(`${location} must contain exact HTTP(S) origins`);\n }\n if (\n (url.protocol !== 'https:' && url.protocol !== 'http:') ||\n url.origin !== entry ||\n url.username ||\n url.password\n ) {\n throw new Error(`${location} must contain exact HTTP(S) origins`);\n }\n return entry;\n });\n return Object.freeze([...new Set(result)]);\n}\n\nfunction purposes(value: unknown, location: string): readonly ProfileSecretPurpose[] {\n if (value === undefined) return Object.freeze(['browser'] as const);\n if (\n !Array.isArray(value) ||\n value.length === 0 ||\n value.some((entry: unknown) => typeof entry !== 'string' || !PURPOSES.has(entry)) ||\n new Set(value).size !== value.length\n ) {\n throw new Error(`${location} must list distinct purposes: browser, proxy, env or input`);\n }\n return Object.freeze([...(value as ProfileSecretPurpose[])]);\n}\n\nfunction timezone(value: unknown, location: string): string {\n try {\n if (typeof value === 'string' && value.length <= 64) {\n new Intl.DateTimeFormat('en-US', { timeZone: value });\n return value;\n }\n } catch {}\n throw new Error(`${location} must be an IANA timezone`);\n}\n\nfunction locale(value: unknown, location: string): string {\n try {\n if (typeof value === 'string' && value.length <= 35 && Intl.getCanonicalLocales(value).length === 1) return value;\n } catch {}\n throw new Error(`${location} must be a BCP 47 locale`);\n}\n\nfunction fingerprint(value: unknown, location: string): ProfileBrowserFingerprint {\n const entry = record(value, location, FINGERPRINT_KEYS);\n if (entry.platform !== undefined && entry.platform !== 'windows' && entry.platform !== 'macos') {\n throw new Error(`${location}.platform must be windows or macos`);\n }\n if (\n entry.seed !== undefined &&\n (typeof entry.seed !== 'number' || !Number.isInteger(entry.seed) || entry.seed < 10000 || entry.seed > 99999)\n ) {\n throw new Error(`${location}.seed must be an integer from 10000 to 99999`);\n }\n if (entry.required !== undefined && typeof entry.required !== 'boolean') {\n throw new Error(`${location}.required must be a boolean`);\n }\n return Object.freeze({\n ...(entry.platform === undefined ? {} : { platform: entry.platform as 'windows' | 'macos' }),\n ...(entry.seed === undefined ? {} : { seed: entry.seed }),\n ...(entry.required === undefined ? {} : { required: entry.required }),\n });\n}\n\nfunction browser(value: unknown, location: string): ProfileBrowserBinding {\n const entry = record(value, location, BROWSER_KEYS);\n if (typeof entry.profileName !== 'string' || !BROWSER_PROFILE_PATTERN.test(entry.profileName)) {\n throw new Error(`${location}.profileName must be a safe browser profile name`);\n }\n if (entry.mode !== undefined && (typeof entry.mode !== 'string' || !BROWSER_MODES.has(entry.mode))) {\n throw new Error(`${location}.mode must be playwright, extension or stealth`);\n }\n if (\n entry.proxySecret !== undefined &&\n (typeof entry.proxySecret !== 'string' || !ALIAS_PATTERN.test(entry.proxySecret))\n ) {\n throw new Error(`${location}.proxySecret must be an uppercase alias name`);\n }\n if (entry.geoip !== undefined && typeof entry.geoip !== 'boolean') {\n throw new Error(`${location}.geoip must be a boolean`);\n }\n const pinned =\n entry.fingerprint === undefined ? undefined : fingerprint(entry.fingerprint, `${location}.fingerprint`);\n if (pinned?.required && entry.mode !== undefined && entry.mode !== 'playwright') {\n throw new Error(`${location}.fingerprint.required needs playwright mode`);\n }\n return Object.freeze({\n profileName: entry.profileName,\n allowedOrigins: Object.freeze([\n ...new Set([...origins(entry.allowedOrigins, `${location}.allowedOrigins`), ...PROFILE_SOCIAL_BROWSER_ORIGINS]),\n ]),\n ...(entry.mode === undefined ? {} : { mode: entry.mode as ProfileBrowserMode }),\n ...(entry.proxySecret === undefined ? {} : { proxySecret: entry.proxySecret }),\n ...(entry.geoip === undefined ? {} : { geoip: entry.geoip }),\n ...(entry.timezone === undefined ? {} : { timezone: timezone(entry.timezone, `${location}.timezone`) }),\n ...(entry.locale === undefined ? {} : { locale: locale(entry.locale, `${location}.locale`) }),\n ...(pinned === undefined ? {} : { fingerprint: pinned }),\n });\n}\n\nfunction targets(\n value: unknown,\n forInput: boolean,\n location: string,\n): Readonly<Record<string, readonly string[]>> | undefined {\n if (value === undefined) {\n if (forInput) throw new Error(`${location} requires explicit input targets`);\n return undefined;\n }\n if (!forInput) throw new Error(`${location} requires the input purpose`);\n const entries = record(value, location);\n if (Object.keys(entries).length === 0) throw new Error(`${location} requires explicit input targets`);\n const result: Record<string, readonly string[]> = Object.create(null);\n for (const [surface, list] of Object.entries(entries)) {\n if (\n !/^[a-z][a-z0-9-]{0,63}$/.test(surface) ||\n ['browser', 'env', 'proxy', 'constructor', 'prototype'].includes(surface) ||\n !Array.isArray(list) ||\n list.length === 0 ||\n list.some((entry: unknown) => typeof entry !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9_.-]{0,255}$/.test(entry))\n ) {\n throw new Error(`${location} must map surfaces to exact application identifiers`);\n }\n result[surface] = Object.freeze([...new Set(list as string[])]);\n }\n return Object.freeze(result);\n}\n\nfunction delivery(secret: Record<string, unknown>, location: string) {\n const secretPurposes = purposes(secret.purposes, `${location}.purposes`);\n const forBrowser = secretPurposes.includes('browser');\n const emptyOrigins = Array.isArray(secret.allowedOrigins) && secret.allowedOrigins.length === 0;\n if (!forBrowser && secret.allowedOrigins !== undefined && !emptyOrigins) {\n throw new Error(`${location}.allowedOrigins requires the browser purpose`);\n }\n const allowedTargets = targets(secret.allowedTargets, secretPurposes.includes('input'), `${location}.allowedTargets`);\n return {\n purposes: secretPurposes,\n allowedOrigins: forBrowser\n ? origins(secret.allowedOrigins, `${location}.allowedOrigins`)\n : Object.freeze([] as string[]),\n ...(allowedTargets === undefined ? {} : { allowedTargets }),\n };\n}\n\n/** Explicit vault aliases only. Templates never name a namespace or key themselves. */\nexport function parseProfileVaultSecrets(\n value: unknown,\n location = 'Profile secrets',\n): Readonly<Record<string, ProfileVaultSecretReference>> {\n const result: Record<string, ProfileVaultSecretReference> = Object.create(null);\n for (const [alias, valueEntry] of Object.entries(record(value, location))) {\n if (!ALIAS_PATTERN.test(alias)) throw new Error(`${location} requires uppercase alias names`);\n const secret = record(valueEntry, location, VAULT_SECRET_KEYS);\n const vault = record(secret.vault, `${location}.vault`, new Set(['namespace', 'key', 'field']));\n if (\n typeof vault.namespace !== 'string' ||\n !/^[a-z][a-z0-9.-]{0,63}$/.test(vault.namespace) ||\n typeof vault.key !== 'string' ||\n vault.key.length < 1 ||\n vault.key.length > 512 ||\n /\\p{Cc}/u.test(vault.key)\n ) {\n throw new Error(`${location}.vault requires a valid namespace and key`);\n }\n const field = vault.field === undefined ? undefined : reference(vault.field, `${location}.vault.field`);\n if (\n field !== undefined &&\n (['__proto__', 'prototype', 'constructor'].includes(field) || !FIELD_PATTERN.test(field))\n ) {\n throw new Error(`${location}.vault.field must be an own string field name`);\n }\n const scope = delivery(secret, location);\n if (scope.purposes.some((purpose) => purpose !== 'browser' && purpose !== 'input')) {\n throw new Error(`${location} vault aliases support browser and input purposes only`);\n }\n result[alias] = Object.freeze({\n vault: Object.freeze({\n namespace: vault.namespace,\n key: vault.key,\n ...(field === undefined ? {} : { field }),\n }),\n ...scope,\n });\n }\n return Object.freeze(result);\n}\n\n/** Validates and deeply freezes a detached metadata snapshot. No provider SDK or secret is loaded. */\nexport function parseProfileBinding(value: unknown, location = 'Profile integration'): ProfileIntegrationBinding {\n const entry = record(value, location, BINDING_KEYS);\n const sourceSecrets = record(entry.secrets, `${location}.secrets`);\n const secrets: Record<string, ProfileSecretReference> = {};\n for (const [alias, value] of Object.entries(sourceSecrets)) {\n if (!ALIAS_PATTERN.test(alias)) throw new Error(`${location}.secrets requires uppercase alias names`);\n const secret = record(value, `${location}.secrets.${alias}`, SECRET_KEYS);\n if (typeof secret.field !== 'string' || !FIELD_PATTERN.test(secret.field)) {\n throw new Error(`${location}.secrets.${alias}.field must be a credential field name`);\n }\n secrets[alias] = Object.freeze({\n credentialId: reference(secret.credentialId, `${location}.secrets.${alias}.credentialId`),\n field: secret.field,\n ...delivery(secret, `${location}.secrets.${alias}`),\n });\n }\n const browserBinding = entry.browser === undefined ? undefined : browser(entry.browser, `${location}.browser`);\n if (\n browserBinding &&\n Object.values(secrets).some((secret) =>\n secret.allowedOrigins.some((origin) => !browserBinding.allowedOrigins.includes(origin)),\n )\n ) {\n throw new Error(`${location} secret origins must be included in browser.allowedOrigins`);\n }\n if (browserBinding?.proxySecret !== undefined && !secrets[browserBinding.proxySecret]?.purposes.includes('proxy')) {\n throw new Error(`${location}.browser.proxySecret must name a proxy-purpose secret`);\n }\n return Object.freeze({\n provider: reference(entry.provider, `${location}.provider`),\n organizationId: reference(entry.organizationId, `${location}.organizationId`),\n mailboxId: reference(entry.mailboxId, `${location}.mailboxId`),\n credentialRef: reference(entry.credentialRef, `${location}.credentialRef`),\n secrets: Object.freeze(secrets),\n ...(browserBinding === undefined ? {} : { browser: browserBinding }),\n });\n}\n","import path from 'node:path';\n\nimport { isTimeZone } from '@agimon-ai/po-core/personTimeZone';\nimport { PROFILE_ICON_MAX_DATA_URL_LENGTH, PROFILE_ICON_MIME_TYPES } from '@agimon-ai/po-core/profileIdentity';\nimport { YAMLMap, isMap, isSeq, parseDocument, parse as parseYaml, stringify as stringifyYaml } from 'yaml';\n\nimport type { PersonaFrontMatter, PersonaIdentity, PersonaVoiceOverride } from '../../types/profiles';\nimport { parsePersonaFrontMatter } from '../personaFrontMatter';\nimport { parseProfileBinding, parseProfileVaultSecrets } from '../profileBinding';\nimport type { ProfileIntegrationBinding, ProfileVaultSecretReference } from '../profileBinding/type';\n\n/** Files that make up one repository persona, concatenated in this order. */\nexport const PERSONA_FILES = ['profile.md', 'SOUL.md', 'AGENTS.md'];\n\n/** The persona file that may carry an identity block; the others are prose only. */\nexport const PERSONA_IDENTITY_FILE = 'profile.md';\n\nexport interface AgentProfile {\n name: string;\n /** Directory relative to personaRoot, which remains the persona source. */\n persona: string;\n /**\n * Root the persona path resolves against: the repository root for a\n * repository profile, the global `.po` directory for a global one.\n */\n personaRoot: string;\n /** Environment defaults. Values already exported by the caller win. */\n env: Record<string, string>;\n /** Nonsecret integration metadata. Resolved secrets never enter profile environment. */\n integration?: ProfileIntegrationBinding;\n /** Explicit, scoped vault aliases. No resolved values. */\n secrets?: Readonly<Record<string, ProfileVaultSecretReference>>;\n /** The person's IANA zone, such as `Australia/Sydney`. It wins over the zone of the device they write from. */\n timezone?: string;\n /** Display name, avatar and role declared in the persona's own front-matter, plus a source's contact. */\n identity?: PersonaIdentity;\n /** Narrowly scoped TTS override declared alongside the identity. */\n voice?: PersonaVoiceOverride;\n /** Persona prompt for a profile served from memory; directory profiles build theirs from disk. */\n personaPrompt?: string;\n}\n\n/** A profile contributed from memory, validated with the directory profile rules. */\nexport interface InlineProfileInput {\n name: string;\n /** Stable origin label, shown in place of a persona directory. */\n source: string;\n /** Persona file text keyed by file name; only PERSONA_FILES are read. */\n files: Readonly<Record<string, string>>;\n env?: unknown;\n integration?: unknown;\n secrets?: unknown;\n /** IANA zone name; checked like a directory profile's `timezone`. */\n timezone?: unknown;\n /** Display-only address shown under the profile's name, such as the mailbox it sends from. Never a secret. */\n contact?: string;\n /** The source's avatar as a `data:` URL of an allowed image type; anything else is dropped. */\n icon?: string;\n}\n\nexport interface ProfileConfigLayer {\n filePath: string;\n baseDirectory: string;\n roots: string[];\n entries: Record<string, unknown>;\n defaultProfile?: string;\n}\n\n/** An explicit entry that passed shape checks, before its persona is read from disk. */\nexport interface ProfileEntryDraft {\n name: string;\n persona: string;\n personaPath: string;\n /** Allowed roots that lexically contain the persona; the caller confirms one after resolving links. */\n lexicalRoots: string[];\n value: Record<string, unknown>;\n}\n\nexport type PersonaPresentation = { identity?: PersonaIdentity; voice?: PersonaVoiceOverride };\n\n/** A discovered profile that was skipped. Messages name keys and files, never values. */\nexport interface ProfileDiagnostic {\n filePath: string;\n profile: string;\n message: string;\n}\n\nexport type ProfileSidecar = Pick<AgentProfile, 'env' | 'integration' | 'secrets' | 'timezone'>;\n\nconst PROFILE_KEYS = new Set(['persona', 'env', 'integration', 'secrets', 'timezone']);\nconst PROFILE_CATALOG_KEYS = new Set(['roots', 'entries', 'defaultProfile']);\nconst SIDECAR_KEYS = new Set(['version', 'env', 'integration', 'secrets', 'timezone']);\nconst SIDECAR_VERSION = 1;\nconst SIDECAR_MAX_BYTES = 64 * 1024;\nexport const PROFILES_FILE = 'profiles.yaml';\n/** Optional nonsecret sidecar beside a discovered persona, validated like an explicit entry. */\nexport const PROFILE_SIDECAR_FILE = 'profile.yaml';\nconst PROFILES_ROOT_KEY = 'profiles';\nconst AGENTS_DIRECTORY = 'agents';\nexport const PARENT_DIRECTORY = '..';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function isPathInside(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return (\n relative === '' ||\n (!path.isAbsolute(relative) &&\n relative !== PARENT_DIRECTORY &&\n !relative.startsWith(`${PARENT_DIRECTORY}${path.sep}`))\n );\n}\n\nfunction parseEnvironment(name: string, value: unknown): Record<string, string> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new Error(`Profile \"${name}\" env must be a string mapping`);\n\n const environment: Record<string, string> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry !== 'string') throw new Error(`Profile \"${name}\" env.${key} must be a string`);\n if (/\\$\\{\\s*secrets?\\b|\\{\\{\\s*secrets?\\b/.test(entry)) {\n throw new Error(`Profile \"${name}\" env cannot contain secret aliases`);\n }\n environment[key] = entry;\n }\n return environment;\n}\n\n/** The profile's own zone, spread into the profile only when declared. */\nfunction parseTimezone(name: string, value: unknown): { timezone?: string } {\n if (value === undefined) return {};\n if (!isTimeZone(value)) throw new Error(`Profile \"${name}\" timezone must be an IANA zone such as Australia/Sydney`);\n return { timezone: value };\n}\n/** Strict v1 sidecar parse. YAML errors are reported generically so source text never reaches a diagnostic. */\nexport function parseProfileSidecar(name: string, text: string): ProfileSidecar {\n if (Buffer.byteLength(text) > SIDECAR_MAX_BYTES)\n throw new Error(`Profile \"${name}\" ${PROFILE_SIDECAR_FILE} is too large`);\n let document: unknown;\n try {\n document = parseYaml(text);\n } catch {\n throw new Error(`Profile \"${name}\" ${PROFILE_SIDECAR_FILE} is not valid YAML`);\n }\n if (!isRecord(document)) throw new Error(`Profile \"${name}\" ${PROFILE_SIDECAR_FILE} must be a mapping`);\n if (Object.keys(document).some((key) => !SIDECAR_KEYS.has(key))) {\n throw new Error(\n `Profile \"${name}\" ${PROFILE_SIDECAR_FILE} may only set version, env, integration, secrets and timezone`,\n );\n }\n if (document.version !== SIDECAR_VERSION) {\n throw new Error(`Profile \"${name}\" ${PROFILE_SIDECAR_FILE} must declare version: ${SIDECAR_VERSION}`);\n }\n return {\n env: parseEnvironment(name, document.env),\n ...(document.secrets === undefined ? {} : { secrets: parseProfileVaultSecrets(document.secrets) }),\n ...(document.integration === undefined\n ? {}\n : { integration: parseProfileBinding(document.integration, `Profile \"${name}\" integration`) }),\n ...parseTimezone(name, document.timezone),\n };\n}\n\nexport function sidecarDiagnostic(filePath: string, profile: string, error: unknown): ProfileDiagnostic {\n return { filePath, profile, message: error instanceof Error ? error.message : `Profile \"${profile}\" is invalid` };\n}\nfunction parseProfileRoots(value: unknown, filePath: string, baseDirectory: string): string[] {\n if (value === undefined) return [];\n if (!Array.isArray(value)) throw new Error(`profiles.roots in ${filePath} must be an array`);\n return value.map((entry, index) => {\n if (typeof entry !== 'string' || entry.trim().length === 0) {\n throw new Error(`profiles.roots[${index}] in ${filePath} must be a non-empty string`);\n }\n return path.resolve(baseDirectory, entry.trim());\n });\n}\n\nexport function parseProfileLayer(source: {\n filePath: string;\n baseDirectory: string;\n document: unknown;\n}): ProfileConfigLayer {\n if (!isRecord(source.document) || !isRecord(source.document[PROFILES_ROOT_KEY])) {\n throw new Error(`${source.filePath} must contain a profiles mapping`);\n }\n const unsupportedDocumentKeys = Object.keys(source.document).filter((key) => key !== PROFILES_ROOT_KEY);\n if (unsupportedDocumentKeys.length > 0) {\n throw new Error(`${source.filePath} may only contain profiles; unsupported: ${unsupportedDocumentKeys.join(', ')}`);\n }\n\n const profiles = source.document[PROFILES_ROOT_KEY];\n const usesCatalogShape = Object.hasOwn(profiles, 'roots') || Object.hasOwn(profiles, 'entries');\n if (!usesCatalogShape) {\n return { filePath: source.filePath, baseDirectory: source.baseDirectory, roots: [], entries: profiles };\n }\n\n const unsupportedCatalogKeys = Object.keys(profiles).filter((key) => !PROFILE_CATALOG_KEYS.has(key));\n if (unsupportedCatalogKeys.length > 0) {\n throw new Error(\n `profiles in ${source.filePath} may only contain roots, entries and defaultProfile; unsupported: ${unsupportedCatalogKeys.join(', ')}`,\n );\n }\n if (\n profiles.defaultProfile !== undefined &&\n (typeof profiles.defaultProfile !== 'string' || profiles.defaultProfile.trim().length === 0)\n ) {\n throw new Error(`profiles.defaultProfile in ${source.filePath} must be a non-empty string`);\n }\n if (profiles.entries !== undefined && !isRecord(profiles.entries)) {\n throw new Error(`profiles.entries in ${source.filePath} must be a mapping`);\n }\n return {\n filePath: source.filePath,\n baseDirectory: source.baseDirectory,\n roots: parseProfileRoots(profiles.roots, source.filePath, source.baseDirectory),\n entries: profiles.entries ?? {},\n ...(profiles.defaultProfile === undefined ? {} : { defaultProfile: String(profiles.defaultProfile).trim() }),\n };\n}\n\n/**\n * The profiles.yaml text that also lists `root` in `profiles.roots`, or undefined when it already does.\n * Comments and every other key are kept, a flat-form file moves under `entries`, and `defaultProfile` is never set.\n */\nexport function withProfileRoot(\n text: string,\n filePath: string,\n baseDirectory: string,\n root: string,\n): string | undefined {\n const document = parseDocument(text);\n if (document.errors.length > 0) throw new Error(`${filePath} is not valid YAML`);\n const current: unknown = document.toJS();\n if (current === null || current === undefined) return stringifyYaml({ [PROFILES_ROOT_KEY]: { roots: [root] } });\n const layer = parseProfileLayer({ filePath, baseDirectory, document: current });\n if (layer.roots.includes(path.resolve(baseDirectory, root))) return undefined;\n const profiles = document.get(PROFILES_ROOT_KEY, true);\n if (!isMap(profiles)) throw new Error(`${filePath} must contain a profiles mapping`);\n const roots = profiles.get('roots', true);\n if (isSeq(roots)) roots.add(document.createNode(root));\n else if (profiles.has('entries') || profiles.items.length === 0) profiles.set('roots', document.createNode([root]));\n else {\n const catalog = new YAMLMap<string, unknown>();\n catalog.set('roots', document.createNode([root]));\n catalog.set('entries', profiles);\n document.set(PROFILES_ROOT_KEY, catalog);\n }\n const output = document.toString();\n parseProfileLayer({ filePath, baseDirectory, document: parseYaml(output) });\n return output;\n}\n\n/**\n * Shape checks for one explicit entry. The caller checks the persona on disk,\n * then `profileFromDraft` parses env and integration, keeping the error order.\n */\nexport function draftProfileEntry(\n personaRoot: string,\n configuredRoots: readonly string[],\n name: string,\n value: unknown,\n): ProfileEntryDraft {\n if (!isRecord(value)) throw new Error(`Profile \"${name}\" must be a mapping`);\n\n const unsupported = Object.keys(value).filter((key) => !PROFILE_KEYS.has(key));\n if (unsupported.length > 0) {\n throw new Error(\n `Profile \"${name}\" may only set persona, env, integration, secrets or timezone; unsupported metadata`,\n );\n }\n if (typeof value.persona !== 'string' || value.persona.trim().length === 0) {\n throw new Error(`Profile \"${name}\" must set a persona`);\n }\n if (path.isAbsolute(value.persona)) {\n throw new Error(`Profile \"${name}\" persona must be relative to the config that declares it`);\n }\n\n const persona = value.persona;\n const personaPath = path.resolve(personaRoot, persona);\n const lexicalRoots = [path.resolve(personaRoot, AGENTS_DIRECTORY), ...configuredRoots].filter((root) =>\n isPathInside(root, personaPath),\n );\n if (lexicalRoots.length === 0) throw outsideAllowedRoot(name);\n return {\n name,\n persona,\n personaPath,\n lexicalRoots,\n value,\n };\n}\n\nexport function outsideAllowedRoot(name: string): Error {\n return new Error(`Profile \"${name}\" persona must stay inside agents/ or a configured profile root`);\n}\n\nexport function missingPersona(name: string, persona: string): Error {\n return new Error(`Profile \"${name}\" references a missing persona: ${persona}`);\n}\n\n/**\n * An identity block is not persona text, so a profile.md holding nothing else\n * leaves the persona empty. Say that, rather than claiming the file is unreadable.\n */\nexport function emptyPersona(name: string, persona: string, declaresIdentity: boolean): Error {\n return new Error(\n declaresIdentity\n ? `Profile \"${name}\" persona declares identity front-matter but no persona text: ${persona}`\n : `Profile \"${name}\" persona has no readable persona files: ${persona}`,\n );\n}\n\nexport function profileFromDraft(\n draft: ProfileEntryDraft,\n personaRoot: string,\n presentation: PersonaPresentation,\n): AgentProfile {\n const { name, value } = draft;\n return {\n name,\n persona: draft.persona,\n personaRoot,\n env: parseEnvironment(name, value.env),\n ...(value.secrets === undefined ? {} : { secrets: parseProfileVaultSecrets(value.secrets) }),\n ...(value.integration === undefined\n ? {}\n : { integration: parseProfileBinding(value.integration, `Profile \"${name}\" integration`) }),\n ...parseTimezone(name, value.timezone),\n ...presentation,\n };\n}\n\nexport function presentationFrom(frontMatter: PersonaFrontMatter, icon: string | undefined): PersonaPresentation {\n const identity: PersonaIdentity = {\n ...(frontMatter.name === undefined ? {} : { name: frontMatter.name }),\n ...(icon === undefined ? {} : { icon }),\n ...(frontMatter.role === undefined ? {} : { role: frontMatter.role }),\n };\n return {\n ...(Object.keys(identity).length === 0 ? {} : { identity }),\n ...(frontMatter.voice === undefined ? {} : { voice: frontMatter.voice }),\n };\n}\n\n/** Rejects a persona file whose real path left the persona directory. */\nexport function assertPersonaFileInside(\n personaPath: string,\n realFilePath: string,\n personaDirectory: string,\n file: string,\n): void {\n const relativeFilePath = path.relative(personaPath, realFilePath);\n if (relativeFilePath === PARENT_DIRECTORY || relativeFilePath.startsWith(`${PARENT_DIRECTORY}${path.sep}`)) {\n throw new Error(`Persona file must stay inside ${personaDirectory}: ${file}`);\n }\n}\n\n/** The text one persona file contributes. Only profile.md may declare identity, so only profile.md is stripped. */\nexport function personaFileSection(file: string, raw: string): string {\n return (file === PERSONA_IDENTITY_FILE ? parsePersonaFrontMatter(raw).body : raw).trim();\n}\n\nexport function personaPromptFromSections(personaDirectory: string, sections: readonly string[]): string | undefined {\n if (sections.length === 0) return undefined;\n return [`[PERSONA] You are operating as the person described below (source: ${personaDirectory}).`, ...sections].join(\n '\\n\\n',\n );\n}\n\n/** A source's avatar, kept only as a bounded base64 `data:` URL of a persona icon type, so SVG never passes. */\nfunction sourceIcon(value: unknown): string | undefined {\n if (typeof value !== 'string' || value.length > PROFILE_ICON_MAX_DATA_URL_LENGTH) return undefined;\n const mime = /^data:([a-z]+\\/[a-z]+);base64,[A-Za-z0-9+/]+={0,2}$/.exec(value)?.[1];\n return mime !== undefined && (PROFILE_ICON_MIME_TYPES as readonly string[]).includes(mime) ? value : undefined;\n}\n\n/** Builds a profile from in-memory persona text. Nothing is read from disk; only the source can supply an icon. */\nexport function inlineProfile(input: InlineProfileInput): AgentProfile {\n const { name, source, files } = input;\n const read = (file: string): string | undefined => (Object.hasOwn(files, file) ? files[file] : undefined);\n const sections = PERSONA_FILES.flatMap((file) => {\n const raw = read(file);\n const section = raw === undefined ? '' : personaFileSection(file, raw);\n return section ? [section] : [];\n });\n const identityText = read(PERSONA_IDENTITY_FILE);\n const frontMatter = identityText === undefined ? undefined : parsePersonaFrontMatter(identityText).frontMatter;\n const personaPrompt = personaPromptFromSections(source, sections);\n if (!personaPrompt) throw emptyPersona(name, source, frontMatter !== undefined);\n const presentation = frontMatter === undefined ? {} : presentationFrom(frontMatter, undefined);\n const contact = typeof input.contact === 'string' ? input.contact.trim() || undefined : undefined;\n const icon = sourceIcon(input.icon);\n const identity = {\n ...presentation.identity,\n ...(icon === undefined ? {} : { icon }),\n ...(contact === undefined ? {} : { contact }),\n };\n return {\n name,\n persona: source,\n personaRoot: '',\n env: parseEnvironment(name, input.env),\n ...(input.secrets === undefined ? {} : { secrets: parseProfileVaultSecrets(input.secrets) }),\n ...(input.integration === undefined\n ? {}\n : { integration: parseProfileBinding(input.integration, `Profile \"${name}\" integration`) }),\n ...parseTimezone(name, input.timezone),\n ...presentation,\n ...(Object.keys(identity).length === 0 ? {} : { identity }),\n personaPrompt,\n };\n}\n\nexport function sortProfiles(byName: Map<string, AgentProfile>): AgentProfile[] {\n return [...byName.values()].sort((left, right) => left.name.localeCompare(right.name));\n}\n\n/**\n * A repository declaration replaces a personal one.\n *\n * The name is a request, not a file-catalog reference: a plugin may contribute the\n * profile after this loader runs, so membership is checked by the launch against the\n * merged catalog. Malformed declarations are already rejected by `parseProfileLayer`.\n */\nexport function catalogDefaultProfile(layers: readonly ProfileConfigLayer[]): string | undefined {\n let defaultProfile: string | undefined;\n for (const layer of layers) {\n if (layer.defaultProfile !== undefined) defaultProfile = layer.defaultProfile;\n }\n return defaultProfile;\n}\n\n/** Applies profile environment defaults and returns only the values it contributed. */\nexport function applyProfileEnvironment(\n environment: NodeJS.ProcessEnv,\n defaults: Record<string, string>,\n): Record<string, string> {\n const applied: Record<string, string> = {};\n for (const [key, value] of Object.entries(defaults)) {\n if (environment[key] !== undefined) continue;\n environment[key] = value;\n applied[key] = value;\n }\n return applied;\n}\n\n/** Replaces environment defaults previously contributed by another profile. */\nexport function replaceProfileEnvironment(\n environment: NodeJS.ProcessEnv,\n previous: Record<string, string>,\n next: Record<string, string>,\n): Record<string, string> {\n for (const [key, value] of Object.entries(previous)) {\n if (environment[key] === value) delete environment[key];\n }\n return applyProfileEnvironment(environment, next);\n}\n","// sync: These helpers implement exported Node-only synchronous profile and persona APIs.\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { PersonaFrontMatter } from '../../types/profiles';\nimport { readPoConfigSources } from '../layeredConfig';\nimport { parsePersonaFrontMatter } from '../personaFrontMatter';\nimport { readPersonaIcon } from '../personaIcon';\nimport {\n PERSONA_FILES,\n PERSONA_IDENTITY_FILE,\n PROFILE_SIDECAR_FILE,\n PROFILES_FILE,\n assertPersonaFileInside,\n catalogDefaultProfile,\n draftProfileEntry,\n emptyPersona,\n isPathInside,\n missingPersona,\n outsideAllowedRoot,\n parseProfileLayer,\n parseProfileSidecar,\n personaFileSection,\n personaPromptFromSections,\n presentationFrom,\n profileFromDraft,\n sidecarDiagnostic,\n sortProfiles,\n type AgentProfile,\n type PersonaPresentation,\n type ProfileConfigLayer,\n type ProfileDiagnostic,\n type ProfileSidecar,\n} from './core';\n\nconst TEXT_ENCODING = 'utf8';\n\nfunction parseProfile(\n personaRoot: string,\n configuredRoots: readonly string[],\n name: string,\n value: unknown,\n): AgentProfile {\n const draft = draftProfileEntry(personaRoot, configuredRoots, name, value);\n if (!fs.existsSync(draft.personaPath) || !fs.statSync(draft.personaPath).isDirectory()) {\n throw missingPersona(name, draft.persona);\n }\n const realPersonaPath = fs.realpathSync(draft.personaPath);\n if (!draft.lexicalRoots.some((root) => isPathInside(fs.realpathSync(root), realPersonaPath))) {\n throw outsideAllowedRoot(name);\n }\n if (!buildPersonaPrompt(personaRoot, draft.persona)) {\n throw emptyPersona(name, draft.persona, readPersonaFrontMatter(personaRoot, draft.persona) !== undefined);\n }\n return profileFromDraft(draft, personaRoot, readPersonaPresentation(personaRoot, draft.persona));\n}\n\nfunction containsPersonaFile(directory: string): boolean {\n return PERSONA_FILES.some((file) => {\n try {\n return fs.lstatSync(path.join(directory, file)).isFile();\n } catch {\n return false;\n }\n });\n}\n\n/** Reads the optional sidecar, which must be a regular file whose real path stays in the persona directory. */\nfunction readSidecar(name: string, realDirectory: string): ProfileSidecar {\n const filePath = path.join(realDirectory, PROFILE_SIDECAR_FILE);\n if (!fs.existsSync(filePath)) return { env: {} };\n const realFilePath = fs.realpathSync(filePath);\n if (!isPathInside(realDirectory, realFilePath) || !fs.statSync(realFilePath).isFile()) {\n throw new Error(`Profile \"${name}\" ${PROFILE_SIDECAR_FILE} must be a file inside the persona directory`);\n }\n return parseProfileSidecar(name, fs.readFileSync(realFilePath, TEXT_ENCODING));\n}\n\nfunction discoverProfile(\n directory: string,\n configuredRoot: string,\n personaRoot: string,\n diagnostics: ProfileDiagnostic[],\n): AgentProfile | undefined {\n if (!containsPersonaFile(directory)) return undefined;\n const name = path.basename(directory);\n try {\n const realConfiguredRoot = fs.realpathSync(configuredRoot);\n const realDirectory = fs.realpathSync(directory);\n if (!isPathInside(realConfiguredRoot, realDirectory)) return undefined;\n const persona = path.relative(personaRoot, directory) || '.';\n if (!buildPersonaPrompt(personaRoot, persona)) return undefined;\n let sidecar: ProfileSidecar;\n try {\n sidecar = readSidecar(name, realDirectory);\n } catch (error) {\n // A bad sidecar skips only this profile, visibly, rather than failing the catalog.\n diagnostics.push(sidecarDiagnostic(path.join(directory, PROFILE_SIDECAR_FILE), name, error));\n return undefined;\n }\n return {\n name,\n persona,\n personaRoot,\n ...sidecar,\n ...readPersonaPresentation(personaRoot, persona),\n };\n } catch {\n // Automatic discovery ignores unreadable or unsafe candidates; explicit entries remain fatal.\n return undefined;\n }\n}\n\nfunction discoverProfileRoot(root: string, personaRoot: string, diagnostics: ProfileDiagnostic[]): AgentProfile[] {\n if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {\n throw new Error(`Configured profile root is not a directory: ${root}`);\n }\n\n const rootProfile = discoverProfile(root, root, personaRoot, diagnostics);\n if (rootProfile) return [rootProfile];\n\n return fs\n .readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .sort((left, right) => left.name.localeCompare(right.name))\n .flatMap((entry) => {\n const profile = discoverProfile(path.join(root, entry.name), root, personaRoot, diagnostics);\n return profile ? [profile] : [];\n });\n}\n\nfunction readProfileLayers(repoRoot: string, homeDirectory: string): ProfileConfigLayer[] {\n return readPoConfigSources<unknown>(PROFILES_FILE, repoRoot, homeDirectory).map(parseProfileLayer);\n}\n\nfunction profilesFromLayers(\n layers: readonly ProfileConfigLayer[],\n diagnostics: ProfileDiagnostic[] = [],\n): AgentProfile[] {\n const byName = new Map<string, AgentProfile>();\n for (const layer of layers) {\n for (const root of layer.roots) {\n for (const profile of discoverProfileRoot(root, layer.baseDirectory, diagnostics)) {\n byName.set(profile.name, profile);\n }\n }\n }\n for (const layer of layers) {\n for (const [name, value] of Object.entries(layer.entries)) {\n byName.set(name, parseProfile(layer.baseDirectory, layer.roots, name, value));\n }\n }\n return sortProfiles(byName);\n}\n\n/**\n * Loads profiles from the global and repository configs, repository last.\n *\n * Configured roots accumulate and inspect themselves or their direct-child\n * directories for persona files. Later discoveries replace earlier names, and\n * explicit entries replace discoveries. Legacy flat profile mappings remain\n * accepted as explicit entries.\n *\n * @deprecated Node-only sync shim; use loadProfilesAsync. Removed in M2.\n */\nexport function loadProfiles(repoRoot: string, homeDirectory: string = os.homedir()): AgentProfile[] {\n return profilesFromLayers(readProfileLayers(repoRoot, homeDirectory));\n}\n\n/**\n * The profile catalog: every resolved profile, plus the name a launch starts on\n * when the caller names none.\n *\n * `defaultProfile` mirrors `defaultMajorMode` in modes.yaml and `defaultDomains`\n * in domains.yaml, so each selection axis declares its default in its own\n * catalog. A repository declaration replaces a personal one. The name is a\n * request that need not be a file profile, because a plugin may contribute it;\n * the launch resolves it against the merged catalog and warns when it is absent.\n *\n * @deprecated Node-only sync shim; use loadProfileCatalogAsync. Removed in M2.\n */\nexport function loadProfileCatalog(\n repoRoot: string,\n homeDirectory: string = os.homedir(),\n): { profiles: AgentProfile[]; defaultProfile?: string; diagnostics?: ProfileDiagnostic[] } {\n const layers = readProfileLayers(repoRoot, homeDirectory);\n const diagnostics: ProfileDiagnostic[] = [];\n const profiles = profilesFromLayers(layers, diagnostics);\n const defaultProfile = catalogDefaultProfile(layers);\n return {\n profiles,\n ...(defaultProfile === undefined ? {} : { defaultProfile }),\n ...(diagnostics.length === 0 ? {} : { diagnostics }),\n };\n}\n\n/**\n * Resolves one selected profile and fails clearly when its name is unknown.\n *\n * @deprecated Node-only sync shim; use resolveProfileAsync. Removed in M2.\n */\nexport function resolveProfile(repoRoot: string, name: string, homeDirectory?: string): AgentProfile {\n const profile = loadProfiles(repoRoot, homeDirectory).find((candidate) => candidate.name === name);\n if (!profile) throw new Error(`Unknown profile: ${name}`);\n return profile;\n}\n\n/** @deprecated Node-only sync shim; use listProfileNamesAsync. Removed in M2. */\nexport function listProfileNames(repoRoot: string, homeDirectory?: string): string[] {\n return loadProfiles(repoRoot, homeDirectory).map((profile) => profile.name);\n}\n\nfunction readPersonaPresentation(personaRoot: string, personaDirectory: string): PersonaPresentation {\n const frontMatter = readPersonaFrontMatter(personaRoot, personaDirectory);\n if (!frontMatter) return {};\n const icon =\n frontMatter.icon === undefined\n ? undefined\n : readPersonaIcon(path.join(personaRoot, personaDirectory), frontMatter.icon);\n return presentationFrom(frontMatter, icon);\n}\n\nfunction readPersonaFrontMatter(personaRoot: string, personaDirectory: string): PersonaFrontMatter | undefined {\n try {\n const personaPath = fs.realpathSync(path.join(personaRoot, personaDirectory));\n const filePath = path.join(personaPath, PERSONA_IDENTITY_FILE);\n if (!fs.existsSync(filePath)) return undefined;\n return parsePersonaFrontMatter(fs.readFileSync(fs.realpathSync(filePath), TEXT_ENCODING)).frontMatter;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Builds the persona system-prompt block, or undefined when nothing is readable.\n *\n * @deprecated Node-only sync shim; use buildPersonaPromptAsync. Removed in M2.\n */\nexport function buildPersonaPrompt(personaRoot: string, personaDirectory: string): string | undefined {\n const sections: string[] = [];\n const personaPath = fs.realpathSync(path.join(personaRoot, personaDirectory));\n for (const file of PERSONA_FILES) {\n const filePath = path.join(personaPath, file);\n if (!fs.existsSync(filePath)) continue;\n const realFilePath = fs.realpathSync(filePath);\n assertPersonaFileInside(personaPath, realFilePath, personaDirectory, file);\n const content = personaFileSection(file, fs.readFileSync(realFilePath, TEXT_ENCODING));\n if (content) sections.push(content);\n }\n return personaPromptFromSections(personaDirectory, sections);\n}\n","import path from 'node:path';\n\nimport {\n createSerialRunner,\n getOrThrow,\n nodeHost,\n readTextIfExists,\n writeFileAtomic,\n type FileSystem,\n} from '@agimon-ai/po-core/platform';\n\nimport type { PersonaFrontMatter } from '../../types/profiles';\nimport { poConfigCandidates, readPoConfigSourcesAsync } from '../layeredConfig';\nimport { parsePersonaFrontMatter } from '../personaFrontMatter';\nimport { readPersonaIconAsync } from '../personaIcon';\nimport {\n PERSONA_FILES,\n PERSONA_IDENTITY_FILE,\n PROFILE_SIDECAR_FILE,\n PROFILES_FILE,\n assertPersonaFileInside,\n catalogDefaultProfile,\n draftProfileEntry,\n emptyPersona,\n isPathInside,\n missingPersona,\n outsideAllowedRoot,\n parseProfileLayer,\n parseProfileSidecar,\n personaFileSection,\n personaPromptFromSections,\n presentationFrom,\n profileFromDraft,\n sidecarDiagnostic,\n sortProfiles,\n withProfileRoot,\n type AgentProfile,\n type PersonaPresentation,\n type ProfileConfigLayer,\n type ProfileDiagnostic,\n type ProfileSidecar,\n} from './core';\n\ntype IoContext = Parameters<FileSystem['readTextFile']>[1];\n\n/** Profile reads over a FileSystem; the Node shims in `./sync` give the same answers from node:fs. */\n\nconst realPath = async (fs: FileSystem, target: string, context: IoContext): Promise<string> =>\n getOrThrow(await fs.canonicalPath(target, context));\n\nconst exists = async (fs: FileSystem, target: string, context: IoContext): Promise<boolean> =>\n getOrThrow(await fs.exists(target, context));\n\n/** Whether a path is a directory once links are followed, as `statSync().isDirectory()`. */\nasync function isDirectory(fs: FileSystem, target: string, context: IoContext): Promise<boolean> {\n if (!(await exists(fs, target, context))) return false;\n const info = getOrThrow(await fs.fileInfo(await realPath(fs, target, context), context));\n return info.kind === 'directory';\n}\n\nasync function readPersonaFrontMatter(\n fs: FileSystem,\n personaRoot: string,\n personaDirectory: string,\n context: IoContext,\n): Promise<PersonaFrontMatter | undefined> {\n try {\n const personaPath = await realPath(fs, path.join(personaRoot, personaDirectory), context);\n const filePath = path.join(personaPath, PERSONA_IDENTITY_FILE);\n if (!(await exists(fs, filePath, context))) return undefined;\n const text = await readTextIfExists(fs, await realPath(fs, filePath, context), context);\n return text === undefined ? undefined : parsePersonaFrontMatter(text).frontMatter;\n } catch {\n return undefined;\n }\n}\n\nasync function readPersonaPresentation(\n fs: FileSystem,\n personaRoot: string,\n personaDirectory: string,\n context: IoContext,\n): Promise<PersonaPresentation> {\n const frontMatter = await readPersonaFrontMatter(fs, personaRoot, personaDirectory, context);\n if (!frontMatter) return {};\n const icon =\n frontMatter.icon === undefined\n ? undefined\n : await readPersonaIconAsync(fs, path.join(personaRoot, personaDirectory), frontMatter.icon, context);\n return presentationFrom(frontMatter, icon);\n}\n\n/** Builds the persona system-prompt block, or undefined when nothing is readable. */\nexport async function buildPersonaPromptAsync(\n fs: FileSystem,\n personaRoot: string,\n personaDirectory: string,\n context: IoContext,\n): Promise<string | undefined> {\n const sections: string[] = [];\n const personaPath = await realPath(fs, path.join(personaRoot, personaDirectory), context);\n for (const file of PERSONA_FILES) {\n const filePath = path.join(personaPath, file);\n if (!(await exists(fs, filePath, context))) continue;\n const realFilePath = await realPath(fs, filePath, context);\n assertPersonaFileInside(personaPath, realFilePath, personaDirectory, file);\n const content = personaFileSection(file, getOrThrow(await fs.readTextFile(realFilePath, context)));\n if (content) sections.push(content);\n }\n return personaPromptFromSections(personaDirectory, sections);\n}\n\nasync function parseProfile(\n fs: FileSystem,\n personaRoot: string,\n configuredRoots: readonly string[],\n name: string,\n value: unknown,\n context: IoContext,\n): Promise<AgentProfile> {\n const draft = draftProfileEntry(personaRoot, configuredRoots, name, value);\n if (!(await isDirectory(fs, draft.personaPath, context))) throw missingPersona(name, draft.persona);\n const realPersonaPath = await realPath(fs, draft.personaPath, context);\n let allowed = false;\n for (const root of draft.lexicalRoots) {\n if (isPathInside(await realPath(fs, root, context), realPersonaPath)) {\n allowed = true;\n break;\n }\n }\n if (!allowed) throw outsideAllowedRoot(name);\n if (!(await buildPersonaPromptAsync(fs, personaRoot, draft.persona, context))) {\n const declaresIdentity = (await readPersonaFrontMatter(fs, personaRoot, draft.persona, context)) !== undefined;\n throw emptyPersona(name, draft.persona, declaresIdentity);\n }\n return profileFromDraft(draft, personaRoot, await readPersonaPresentation(fs, personaRoot, draft.persona, context));\n}\n\nasync function containsPersonaFile(fs: FileSystem, directory: string, context: IoContext): Promise<boolean> {\n for (const file of PERSONA_FILES) {\n const info = await fs.fileInfo(path.join(directory, file), context);\n if (info.ok && info.value.kind === 'file') return true;\n }\n return false;\n}\n\n/** Reads the optional sidecar, which must be a regular file whose real path stays in the persona directory. */\nasync function readSidecar(\n fs: FileSystem,\n name: string,\n realDirectory: string,\n context: IoContext,\n): Promise<ProfileSidecar> {\n const filePath = path.join(realDirectory, PROFILE_SIDECAR_FILE);\n if (!(await exists(fs, filePath, context))) return { env: {} };\n const realFilePath = await realPath(fs, filePath, context);\n if (\n !isPathInside(realDirectory, realFilePath) ||\n getOrThrow(await fs.fileInfo(realFilePath, context)).kind !== 'file'\n ) {\n throw new Error(`Profile \"${name}\" ${PROFILE_SIDECAR_FILE} must be a file inside the persona directory`);\n }\n return parseProfileSidecar(name, getOrThrow(await fs.readTextFile(realFilePath, context)));\n}\n\nasync function discoverProfile(\n fs: FileSystem,\n directory: string,\n configuredRoot: string,\n personaRoot: string,\n diagnostics: ProfileDiagnostic[],\n context: IoContext,\n): Promise<AgentProfile | undefined> {\n if (!(await containsPersonaFile(fs, directory, context))) return undefined;\n const name = path.basename(directory);\n try {\n const realConfiguredRoot = await realPath(fs, configuredRoot, context);\n const realDirectory = await realPath(fs, directory, context);\n if (!isPathInside(realConfiguredRoot, realDirectory)) return undefined;\n const persona = path.relative(personaRoot, directory) || '.';\n if (!(await buildPersonaPromptAsync(fs, personaRoot, persona, context))) return undefined;\n let sidecar: ProfileSidecar;\n try {\n sidecar = await readSidecar(fs, name, realDirectory, context);\n } catch (error) {\n // A bad sidecar skips only this profile, visibly, rather than failing the catalog.\n diagnostics.push(sidecarDiagnostic(path.join(directory, PROFILE_SIDECAR_FILE), name, error));\n return undefined;\n }\n return {\n name,\n persona,\n personaRoot,\n ...sidecar,\n ...(await readPersonaPresentation(fs, personaRoot, persona, context)),\n };\n } catch {\n // Automatic discovery ignores unreadable or unsafe candidates; explicit entries remain fatal.\n return undefined;\n }\n}\n\nasync function discoverProfileRoot(\n fs: FileSystem,\n root: string,\n personaRoot: string,\n diagnostics: ProfileDiagnostic[],\n context: IoContext,\n): Promise<AgentProfile[]> {\n if (!(await isDirectory(fs, root, context))) throw new Error(`Configured profile root is not a directory: ${root}`);\n\n const rootProfile = await discoverProfile(fs, root, root, personaRoot, diagnostics, context);\n if (rootProfile) return [rootProfile];\n\n const directories = getOrThrow(await fs.listDir(root, context))\n .filter((entry) => entry.kind === 'directory')\n .sort((left, right) => left.name.localeCompare(right.name));\n const profiles: AgentProfile[] = [];\n for (const entry of directories) {\n const profile = await discoverProfile(fs, path.join(root, entry.name), root, personaRoot, diagnostics, context);\n if (profile) profiles.push(profile);\n }\n return profiles;\n}\n\nasync function readProfileLayers(\n fs: FileSystem,\n repoRoot: string,\n context: IoContext,\n homeDirectory: string,\n): Promise<ProfileConfigLayer[]> {\n const sources = await readPoConfigSourcesAsync<unknown>(fs, PROFILES_FILE, repoRoot, context, homeDirectory);\n return sources.map(parseProfileLayer);\n}\n\nasync function profilesFromLayers(\n fs: FileSystem,\n layers: readonly ProfileConfigLayer[],\n context: IoContext,\n diagnostics: ProfileDiagnostic[] = [],\n): Promise<AgentProfile[]> {\n const byName = new Map<string, AgentProfile>();\n for (const layer of layers) {\n for (const root of layer.roots) {\n for (const profile of await discoverProfileRoot(fs, root, layer.baseDirectory, diagnostics, context)) {\n byName.set(profile.name, profile);\n }\n }\n }\n for (const layer of layers) {\n for (const [name, value] of Object.entries(layer.entries)) {\n byName.set(name, await parseProfile(fs, layer.baseDirectory, layer.roots, name, value, context));\n }\n }\n return sortProfiles(byName);\n}\n\n/**\n * Loads profiles from the global and repository configs, repository last.\n *\n * Configured roots accumulate and inspect themselves or their direct-child\n * directories for persona files. Later discoveries replace earlier names, and\n * explicit entries replace discoveries. Legacy flat profile mappings remain\n * accepted as explicit entries.\n */\nexport async function loadProfilesAsync(\n fs: FileSystem,\n repoRoot: string,\n context: IoContext,\n homeDirectory: string = nodeHost.homeDirectory(),\n): Promise<AgentProfile[]> {\n return profilesFromLayers(fs, await readProfileLayers(fs, repoRoot, context, homeDirectory), context);\n}\n\n/** The profile catalog plus the name a launch starts on when the caller names none. */\nexport async function loadProfileCatalogAsync(\n fs: FileSystem,\n repoRoot: string,\n context: IoContext,\n homeDirectory: string = nodeHost.homeDirectory(),\n): Promise<{ profiles: AgentProfile[]; defaultProfile?: string; diagnostics?: ProfileDiagnostic[] }> {\n const layers = await readProfileLayers(fs, repoRoot, context, homeDirectory);\n const diagnostics: ProfileDiagnostic[] = [];\n const profiles = await profilesFromLayers(fs, layers, context, diagnostics);\n const defaultProfile = catalogDefaultProfile(layers);\n return {\n profiles,\n ...(defaultProfile === undefined ? {} : { defaultProfile }),\n ...(diagnostics.length === 0 ? {} : { diagnostics }),\n };\n}\n\n/** Resolves one selected profile and fails clearly when its name is unknown. */\nexport async function resolveProfileAsync(\n fs: FileSystem,\n repoRoot: string,\n name: string,\n context: IoContext,\n homeDirectory?: string,\n): Promise<AgentProfile> {\n const profiles = await loadProfilesAsync(fs, repoRoot, context, homeDirectory);\n const profile = profiles.find((candidate) => candidate.name === name);\n if (!profile) throw new Error(`Unknown profile: ${name}`);\n return profile;\n}\n\nexport async function listProfileNamesAsync(\n fs: FileSystem,\n repoRoot: string,\n context: IoContext,\n homeDirectory?: string,\n): Promise<string[]> {\n return (await loadProfilesAsync(fs, repoRoot, context, homeDirectory)).map((profile) => profile.name);\n}\n\n/** Thrown when `~/.po/profiles.yaml` changed between planning and committing a root. */\nexport class ProfileCatalogChangedError extends Error {\n constructor(filePath: string) {\n super(`${filePath} changed while it was being updated`);\n this.name = 'ProfileCatalogChangedError';\n }\n}\n\n/** A pending change to the personal profiles.yaml, checked against the text it was computed from. */\nexport interface GlobalProfileRootPlan {\n readonly filePath: string;\n readonly before: string | undefined;\n readonly next: string | undefined;\n}\n\nconst profileCatalogWrites = createSerialRunner();\n\n/** Reads the personal profiles.yaml and computes the text that lists `root`. Throws when the file is invalid. */\nexport async function planGlobalProfileRootAsync(\n fs: FileSystem,\n homeDirectory: string,\n root: string,\n context: IoContext,\n): Promise<GlobalProfileRootPlan> {\n const [candidate] = poConfigCandidates(PROFILES_FILE, homeDirectory, homeDirectory);\n if (!candidate) throw new Error('No personal profiles.yaml location');\n const before = await readTextIfExists(fs, candidate.filePath, context);\n return {\n filePath: candidate.filePath,\n before,\n next: withProfileRoot(before ?? '', candidate.filePath, candidate.baseDirectory, root),\n };\n}\n\n/** Writes a plan unless the file changed since it was read, which throws ProfileCatalogChangedError. */\nexport async function commitGlobalProfileRootAsync(\n fs: FileSystem,\n plan: GlobalProfileRootPlan,\n context: IoContext,\n): Promise<void> {\n await profileCatalogWrites.forKey(path.resolve(plan.filePath))(async () => {\n if ((await readTextIfExists(fs, plan.filePath, context)) !== plan.before)\n throw new ProfileCatalogChangedError(plan.filePath);\n if (plan.next !== undefined) await writeFileAtomic(fs, plan.filePath, plan.next, context);\n });\n}\n\nexport { PERSONA_FILES, applyProfileEnvironment, inlineProfile, replaceProfileEnvironment } from './core';\nexport type { AgentProfile, InlineProfileInput, ProfileDiagnostic } from './core';\nexport { buildPersonaPrompt, listProfileNames, loadProfileCatalog, loadProfiles, resolveProfile } from './sync';\n"],"mappings":"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"}
|
|
@@ -251,6 +251,26 @@ const BROWSER_MODES = /* @__PURE__ */ new Set([
|
|
|
251
251
|
const ALIAS_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
252
252
|
const FIELD_PATTERN = /^(?:[A-Za-z][A-Za-z0-9_.-]{0,63}|profileSecret:[A-Z][A-Z0-9_]{0,63})$/;
|
|
253
253
|
const BROWSER_PROFILE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
254
|
+
/** Browser-level defaults only. Every alias still requires its own exact recipient origins. */
|
|
255
|
+
const PROFILE_SOCIAL_BROWSER_ORIGINS = Object.freeze([
|
|
256
|
+
"https://x.com",
|
|
257
|
+
"https://www.x.com",
|
|
258
|
+
"https://twitter.com",
|
|
259
|
+
"https://www.twitter.com",
|
|
260
|
+
"https://reddit.com",
|
|
261
|
+
"https://www.reddit.com",
|
|
262
|
+
"https://linkedin.com",
|
|
263
|
+
"https://www.linkedin.com",
|
|
264
|
+
"https://facebook.com",
|
|
265
|
+
"https://www.facebook.com",
|
|
266
|
+
"https://instagram.com",
|
|
267
|
+
"https://www.instagram.com",
|
|
268
|
+
"https://tiktok.com",
|
|
269
|
+
"https://www.tiktok.com",
|
|
270
|
+
"https://youtube.com",
|
|
271
|
+
"https://www.youtube.com",
|
|
272
|
+
"https://accounts.google.com"
|
|
273
|
+
]);
|
|
254
274
|
function record(value, location, keys) {
|
|
255
275
|
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${location} must be a mapping`);
|
|
256
276
|
if (keys && Object.keys(value).some((key) => !keys.has(key))) throw new Error(`${location} contains unsupported metadata`);
|
|
@@ -316,7 +336,7 @@ function browser(value, location) {
|
|
|
316
336
|
if (pinned?.required && entry.mode !== void 0 && entry.mode !== "playwright") throw new Error(`${location}.fingerprint.required needs playwright mode`);
|
|
317
337
|
return Object.freeze({
|
|
318
338
|
profileName: entry.profileName,
|
|
319
|
-
allowedOrigins: origins(entry.allowedOrigins, `${location}.allowedOrigins`),
|
|
339
|
+
allowedOrigins: Object.freeze([.../* @__PURE__ */ new Set([...origins(entry.allowedOrigins, `${location}.allowedOrigins`), ...PROFILE_SOCIAL_BROWSER_ORIGINS])]),
|
|
320
340
|
...entry.mode === void 0 ? {} : { mode: entry.mode },
|
|
321
341
|
...entry.proxySecret === void 0 ? {} : { proxySecret: entry.proxySecret },
|
|
322
342
|
...entry.geoip === void 0 ? {} : { geoip: entry.geoip },
|
|
@@ -1047,6 +1067,12 @@ Object.defineProperty(exports, "PERSONA_FILES", {
|
|
|
1047
1067
|
return PERSONA_FILES;
|
|
1048
1068
|
}
|
|
1049
1069
|
});
|
|
1070
|
+
Object.defineProperty(exports, "PROFILE_SOCIAL_BROWSER_ORIGINS", {
|
|
1071
|
+
enumerable: true,
|
|
1072
|
+
get: function() {
|
|
1073
|
+
return PROFILE_SOCIAL_BROWSER_ORIGINS;
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1050
1076
|
Object.defineProperty(exports, "ProfileCatalogChangedError", {
|
|
1051
1077
|
enumerable: true,
|
|
1052
1078
|
get: function() {
|
|
@@ -1174,4 +1200,4 @@ Object.defineProperty(exports, "resolveProfileAsync", {
|
|
|
1174
1200
|
}
|
|
1175
1201
|
});
|
|
1176
1202
|
|
|
1177
|
-
//# sourceMappingURL=profiles-
|
|
1203
|
+
//# sourceMappingURL=profiles-q6C39HtK.cjs.map
|