@unbrained/pm-cli 2026.10.18 → 2026.10.20
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +43 -0
- package/dist/cli/error-guidance.d.ts +7 -0
- package/dist/cli/error-guidance.js +2 -2
- package/dist/cli/help-content.js +2 -2
- package/dist/cli/register-mutation.js +2 -2
- package/dist/cli/register-setup.js +1 -1
- package/dist/cli/register-structured-mutation.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +1 -1
- package/dist/cli-bundle/chunks/{chunk-PYRREEUB.js → chunk-2GGGOD7P.js} +28 -28
- package/dist/cli-bundle/chunks/chunk-7NHA5K77.js +126 -0
- package/dist/cli-bundle/chunks/chunk-7ZOIZ2AZ.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-4GA4MUTE.js → chunk-GHJOMRSF.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-KU4Q3MSI.js +8 -0
- package/dist/cli-bundle/chunks/chunk-LS55VKRK.js +3 -0
- package/dist/cli-bundle/chunks/chunk-PNPE2OVJ.js +112 -0
- package/dist/cli-bundle/chunks/chunk-PTL3TBT6.js +20 -0
- package/dist/cli-bundle/chunks/chunk-QETMESEB.js +6 -0
- package/dist/cli-bundle/chunks/{chunk-7WIEAGDS.js → chunk-QMZ73FCW.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-QQYCB2LO.js +2 -0
- package/dist/cli-bundle/chunks/chunk-RUKSEZE7.js +2 -0
- package/dist/cli-bundle/chunks/chunk-TZU6U5ZE.js +3 -0
- package/dist/cli-bundle/chunks/chunk-VLJLWZBO.js +70 -0
- package/dist/cli-bundle/chunks/chunk-VS565KBX.js +2 -0
- package/dist/cli-bundle/chunks/chunk-XAWE4EAK.js +2 -0
- package/dist/cli-bundle/chunks/chunk-YECCKB4E.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-FIJOSX2C.js → chunk-YT2Z3JPC.js} +72 -66
- package/dist/cli-bundle/chunks/chunk-YTHI5DTH.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-6VZKYJW7.js → chunk-YW6SIKYP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ZZED447K.js → chunk-ZA3XXHEE.js} +6 -6
- package/dist/cli-bundle/chunks/context-budget-recovery-L2WP5S26.js +2 -0
- package/dist/cli-bundle/chunks/indexed-receipt-blobs-U7VGKIYC.js +4 -0
- package/dist/cli-bundle/chunks/{register-list-query-PUCVYYBD.js → register-list-query-NNDV6F6I.js} +3 -3
- package/dist/cli-bundle/chunks/register-mutation-3GCBSNQS.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-YKDGNKUL.js +2 -0
- package/dist/cli-bundle/chunks/register-setup-AOUZQQWB.js +2 -0
- package/dist/cli-bundle/chunks/settlement-hook-CLRGA6O7.js +7 -0
- package/dist/cli-bundle/chunks/stage-6QXYRMSU.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-37SU7BZI.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-6IU7BESB.js +65 -0
- package/dist/cli-bundle/focused-chunks/chunk-AK2CI2GI.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-AS3MOBO3.js +25 -0
- package/dist/cli-bundle/focused-chunks/chunk-AW35RDKA.js +78 -0
- package/dist/cli-bundle/focused-chunks/chunk-E4II2D2B.js +3 -0
- package/dist/cli-bundle/focused-chunks/{chunk-A4ZHHTEX.js → chunk-F7FD25TG.js} +12 -12
- package/dist/cli-bundle/focused-chunks/chunk-FOA7XKWP.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-TB7F4FCR.js → chunk-GYHZ7W6O.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-H5Q2HUU6.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-HUZAXSIJ.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-J6EYUGAR.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-JEXZEIAX.js +91 -0
- package/dist/cli-bundle/focused-chunks/{chunk-BFEMT5U3.js → chunk-KDGUIIRU.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-ZDBS2DCT.js → chunk-KKRFSI2N.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-LJPUJ2KK.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MQ42BFGX.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-IRVL4UXR.js → chunk-NI6NS44Q.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-VAYS754X.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-Z7YIFCNE.js → chunk-VLSER3XW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-VS6VTWTZ.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-VVRXF4JO.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-ZGEK57KD.js +2 -0
- package/dist/cli-bundle/focused-chunks/context-budget-recovery-5MKOCGY5.js +2 -0
- package/dist/cli-bundle/focused-chunks/indexed-receipt-blobs-H2G6CCGO.js +4 -0
- package/dist/cli-bundle/focused-chunks/settlement-hook-5SNBBT7C.js +7 -0
- package/dist/cli-bundle/focused-chunks/stage-EMTISXR7.js +2 -0
- package/dist/cli-bundle/main.js +21 -21
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +28 -22
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +66 -53
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +8 -8
- package/dist/core/fs/fs-utils.d.ts +2 -2
- package/dist/core/fs/fs-utils.js +1 -1
- package/dist/core/history/event-index.js +2 -2
- package/dist/core/output/output.d.ts +7 -2
- package/dist/core/output/output.js +5 -5
- package/dist/core/shared/errors.d.ts +48 -0
- package/dist/core/shared/errors.js +1 -1
- package/dist/core/store/settings.js +2 -2
- package/dist/mcp/server.js +1 -1
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +1 -0
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +1 -1
- package/dist/sdk/core.d.ts +1 -1
- package/dist/sdk/core.js +1 -1
- package/dist/sdk/dependencies/context-budget-recovery.d.ts +21 -0
- package/dist/sdk/dependencies/context-budget-recovery.js +2 -0
- package/dist/sdk/dependencies.js +1 -1
- package/dist/sdk/errors.d.ts +4 -1
- package/dist/sdk/errors.js +1 -1
- package/dist/sdk/extension/install-sources.js +3 -3
- package/dist/sdk/extension/shared.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/governance/health.js +1 -1
- package/dist/sdk/history-repair.js +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/item-transaction.d.ts +13 -0
- package/dist/sdk/item-transaction.js +1 -1
- package/dist/sdk/lifecycle/structured-mutation-plan.d.ts +14 -1
- package/dist/sdk/lifecycle/structured-mutation-plan.js +1 -1
- package/dist/sdk/merge/driver.js +7 -1
- package/dist/sdk/merge/indexed-receipt-blobs.d.ts +2 -0
- package/dist/sdk/merge/indexed-receipt-blobs.js +4 -0
- package/dist/sdk/merge/install.d.ts +8 -0
- package/dist/sdk/merge/install.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +6 -0
- package/dist/sdk/merge/receipts.js +2 -2
- package/dist/sdk/merge/reconcile.d.ts +6 -0
- package/dist/sdk/merge/reconcile.js +1 -1
- package/dist/sdk/merge/settlement-hook.d.ts +12 -0
- package/dist/sdk/merge/settlement-hook.js +7 -0
- package/dist/sdk/merge/stage.d.ts +13 -0
- package/dist/sdk/merge/stage.js +2 -0
- package/dist/sdk/output/list-envelope.d.ts +7 -0
- package/dist/sdk/output/list-envelope.js +2 -0
- package/dist/sdk/output.d.ts +1 -0
- package/dist/sdk/output.js +2 -2
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/list.js +1 -1
- package/dist/sdk/relationship-context.d.ts +2 -0
- package/dist/sdk/relationship-context.js +1 -1
- package/dist/sdk/runtime-extended-actions.js +1 -1
- package/dist/sdk/structured-mutations.d.ts +2 -0
- package/dist/sdk/structured-mutations.js +1 -1
- package/docs/COMMANDS.md +27 -0
- package/docs/CONFIGURATION.md +14 -0
- package/docs/MERGE_SAFETY.md +88 -5
- package/docs/PR_REVIEW_LOOP.md +32 -12
- package/docs/SCRIPTING.md +10 -0
- package/docs/SDK.md +103 -0
- package/docs/TESTING.md +32 -1
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +6 -3
- package/marketplace.json +1 -1
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/package.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +1 -1
- package/plugins/pm-codex/plugin.json +1 -1
- package/runtime-dependencies.json +1 -1
- package/dist/cli-bundle/chunks/chunk-4V6ONLI6.js +0 -3
- package/dist/cli-bundle/chunks/chunk-7PATQWTH.js +0 -20
- package/dist/cli-bundle/chunks/chunk-AETP4JEM.js +0 -3
- package/dist/cli-bundle/chunks/chunk-LUKVNL72.js +0 -2
- package/dist/cli-bundle/chunks/chunk-OJ77ZQN3.js +0 -8
- package/dist/cli-bundle/chunks/chunk-RHQJ6VWC.js +0 -237
- package/dist/cli-bundle/chunks/chunk-RNABUEFB.js +0 -80
- package/dist/cli-bundle/chunks/chunk-TO6CIV4C.js +0 -2
- package/dist/cli-bundle/chunks/register-mutation-GGGVBXD5.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-NRZ6Q4QE.js +0 -2
- package/dist/cli-bundle/chunks/register-setup-MV3P3YSF.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2MPQUMTF.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-5UKCSZWT.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-B4YLP5ZB.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-FW7CSSKL.js +0 -75
- package/dist/cli-bundle/focused-chunks/chunk-HYPRPSYD.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-L55KQ2KT.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-MASIOFPG.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-RJ3EIHDU.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-SEL4Z2OO.js +0 -167
- package/dist/cli-bundle/focused-chunks/chunk-TZUIBG3P.js +0 -2
|
@@ -29,12 +29,12 @@ export declare function readFileIfExists(targetPath:string):Promise<string | nul
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function readRegularFile(targetPath:string,rejectionError:Error):Promise<string>;
|
|
31
31
|
/**
|
|
32
|
-
* Refuse unsafe preview storage
|
|
32
|
+
* Refuse unsafe preview storage with bounded tracker-relative diagnostics. Entry and
|
|
33
33
|
* opened-descriptor checks share this usage error so SDK callers can repair
|
|
34
34
|
* tracker configuration rather than treating a preserved safety boundary as
|
|
35
35
|
* an unexpected runtime fault. Native filesystem failures retain their codes.
|
|
36
36
|
*/
|
|
37
|
-
export declare function transactionPreviewNonRegularFileError():PmCliError;
|
|
37
|
+
export declare function transactionPreviewNonRegularFileError(relativePath?:string):PmCliError;
|
|
38
38
|
/**
|
|
39
39
|
* Replace a UTF-8 file through a sibling temporary file and atomic rename.
|
|
40
40
|
* Parent directories are created by default. Background consumers can disable
|
package/dist/core/fs/fs-utils.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3792f1fd-ed9d-5252-887d-e4517a55fb9c")}catch{}})();import*as fs from"node:fs/promises";import{constants}from"node:fs";import path from"node:path";import crypto from"node:crypto";import{EXIT_CODE}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";const WINDOWS_RENAME_RETRY_DELAYS_MS=[10,25,50,100];async function ensureDir(dirPath){await fs.mkdir(dirPath,{recursive:!0})}async function pathExists(targetPath){try{return await fs.access(targetPath),!0}catch{return!1}}function isFileAbsentError(error){return isFileMissingError(error)||isErrno(error,"ENOTDIR")}function isFileMissingError(error){return isErrno(error,"ENOENT")}async function readFileIfExists(targetPath){try{return await fs.readFile(targetPath,"utf8")}catch(error){if(isFileAbsentError(error))return null;throw error}}async function readRegularFile(targetPath,rejectionError){const handle=await fs.open(targetPath,constants.O_RDONLY|constants.O_NOFOLLOW|constants.O_NONBLOCK);try{if(!(await handle.stat()).isFile())throw rejectionError;return await handle.readFile("utf8")}finally{await handle.close()}}function transactionPreviewNonRegularFileError(relativePath){const relative=relativePath?.replaceAll(path.sep,"/"),contained=relative!==void 0&&!path.posix.isAbsolute(relative)&&!path.win32.isAbsolute(relative)&&!relative.split("/").includes(".."),first=contained?relative.split("/")[0]:void 0,areas={"settings.json":"settings",runtime:"runtime",schema:"schema",history:"history",transactions:"transactions"},area=first===void 0?"tracker_storage":Object.hasOwn(areas,first)?areas[first]:"tracker_storage",safe=contained&&relative.length>0&&relative.length<=160&&relative.split("/").every(part=>part!=="."&&/^[a-zA-Z0-9_.-]+$/u.test(part)),location=safe?relative:`${area} (entry name redacted)`;return new PmCliError(`Transaction preview requires regular files and directories. Inspect ${location} relative to the selected tracker root.`,EXIT_CODE.USAGE,{code:"transaction_preview_non_regular_file",preview_storage:{storage_area:area,...safe?{relative_entry:relative}:{},entry_redacted:!safe},required:"regular files and directories within the configured tracker storage",why:"Preview does not follow linked entries or read special files.",nextSteps:[`Inspect ${location} within the selected tracker for links, directories used as files, or special files; do not follow link targets.`,"Restore the intended regular files and directories, then retry the original dry-run command."]})}async function writeFileAtomic(targetPath,contents,options={}){const dirPath=path.dirname(targetPath);options.createParentDirectories!==!1&&await ensureDir(dirPath);const tempPath=path.join(dirPath,`.${path.basename(targetPath)}.${process.pid}.${Date.now()}.${crypto.randomBytes(4).toString("hex")}.tmp`);await fs.writeFile(tempPath,contents,"utf8");try{await fs.rename(tempPath,targetPath)}catch(error){if(process.platform==="win32"&&(isErrno(error,"EPERM")||isErrno(error,"EBUSY"))){let lastError=error;for(const delayMs of WINDOWS_RENAME_RETRY_DELAYS_MS){await new Promise(resolve=>setTimeout(resolve,delayMs));try{await fs.rename(tempPath,targetPath);return}catch(retryError){if(lastError=retryError,!isErrno(retryError,"EPERM")&&!isErrno(retryError,"EBUSY"))break}}try{await fs.unlink(tempPath)}catch{}throw lastError}if(isErrno(error,"EXDEV")){try{await fs.copyFile(tempPath,targetPath)}finally{try{await fs.unlink(tempPath)}catch{}}return}try{await fs.unlink(tempPath)}catch{}throw error}}async function appendLineAtomic(targetPath,line){const dirPath=path.dirname(targetPath);await ensureDir(dirPath);const handle=await fs.open(targetPath,"a");try{await handle.writeFile(`${line}
|
|
2
2
|
`,"utf8")}finally{await handle.close()}}async function removeFileIfExists(targetPath){try{await fs.unlink(targetPath)}catch(error){if(!isFileAbsentError(error))throw error}}function isErrno(error,code){return typeof error=="object"&&error!==null&&"code"in error&&error.code===code}export{appendLineAtomic,ensureDir,isFileAbsentError,isFileMissingError,pathExists,readFileIfExists,readRegularFile,removeFileIfExists,transactionPreviewNonRegularFileError,writeFileAtomic};
|
|
3
3
|
//# sourceMappingURL=fs-utils.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f0373f8f-7396-57df-9c8d-9a3315168b5a")}catch{}})();import fs from"node:fs/promises";import path from"node:path";import{randomUUID}from"node:crypto";import{createRequire}from"node:module";import{setImmediate as yieldToEventLoop}from"node:timers/promises";import{isFileMissingError}from"../fs/fs-utils.js";import{acquireLock,captureProcessIdentity,isProcessIdentityAlive,hasUnexpiredLockOwner}from"../lock/lock.js";import{EXIT_CODE}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{isMillisecondPrecisionRfc3339DateTime}from"../shared/time.js";import{readHistoryEntries}from"./read.js";import{classifyHistoryEvent}from"./event-classification.js";import{loadDatabaseSync,loadStableDatabaseSync}from"../store/sqlite-runtime.js";const EVENT_INDEX_FILENAME="history-event-index.sqlite",EVENT_INDEX_VERSION="6",AUTHORITATIVE_HISTORY_CACHE_LIMIT=8,HISTORY_EVENT_INDEX_LOCK_ID="history-event-index",HISTORY_EVENT_INDEX_APPEND_OWNER_PREFIX="history-event-index:append:",HISTORY_EVENT_INDEX_REPAIR_COOLDOWN_MS=5e3,HISTORY_EVENT_INDEX_LOCK_TTL_SECONDS=300,HISTORY_EVENT_INDEX_LOCK_WAIT_MS=3e4,HISTORY_EVENT_INDEX_INVALIDATION_LOCK_ID="history-event-index-invalidation",HISTORY_EVENT_INDEX_INVALIDATION_DIRECTORY="history-event-index-invalidations",HISTORY_EVENT_INDEX_INVALIDATION_MAX_UNVERIFIED_AGE_MS=HISTORY_EVENT_INDEX_LOCK_TTL_SECONDS*2*1e3,HISTORY_INDEX_CHANGED=Symbol("history-index-changed"),authoritativeHistoryCaches=new Map;function eventIndexPath(pmRoot){return path.join(pmRoot,"runtime",EVENT_INDEX_FILENAME)}function refusedHistoryRepairPath(pmRoot){return path.join(pmRoot,"runtime","history-event-index-repair-deferred")}async function hasRecentRefusedHistoryRepair(pmRoot){try{const deferredAt=Number(await fs.readFile(refusedHistoryRepairPath(pmRoot),"utf8")),age=Date.now()-deferredAt;return age>=0&&age<HISTORY_EVENT_INDEX_REPAIR_COOLDOWN_MS}catch{return!1}}async function deferAutomaticHistoryRepair(pmRoot){try{await fs.writeFile(refusedHistoryRepairPath(pmRoot),`${Date.now()}
|
|
2
2
|
`)}catch{}}function historyEventIndexInvalidationDirectory(pmRoot){return path.join(pmRoot,"runtime",HISTORY_EVENT_INDEX_INVALIDATION_DIRECTORY)}async function listHistoryEventIndexInvalidations(pmRoot){const entries=await fs.readdir(historyEventIndexInvalidationDirectory(pmRoot)).catch(error=>{if(isFileMissingError(error))return[];throw error});return{pending:entries.filter(name=>name.endsWith(".pending")).sort(),committed:entries.filter(name=>name.endsWith(".committed")).sort()}}async function recoverAbandonedHistoryEventIndexInvalidations(pmRoot){const invalidations=await listHistoryEventIndexInvalidations(pmRoot);return{pending:(await Promise.all(invalidations.pending.map(async name=>{const owner=/^(\d+)-(unknown|\d+)-(\d+)-.+\.pending$/u.exec(name);if(owner!==null){const processStartIdentity=owner[2];if(await isProcessIdentityAlive({pid:Number(owner[1]),...processStartIdentity==="unknown"?{}:{process_start_identity:processStartIdentity}},Math.max(0,Date.now()-Number(owner[3])),HISTORY_EVENT_INDEX_INVALIDATION_MAX_UNVERIFIED_AGE_MS))return name}return await fs.rm(path.join(historyEventIndexInvalidationDirectory(pmRoot),name),{force:!0}),null}))).filter(name=>name!==null),committed:invalidations.committed}}async function withHistoryEventIndexInvalidationLock(pmRoot,operation,waitMs=HISTORY_EVENT_INDEX_LOCK_WAIT_MS){const release=await acquireLock(pmRoot,HISTORY_EVENT_INDEX_INVALIDATION_LOCK_ID,HISTORY_EVENT_INDEX_LOCK_TTL_SECONDS,`history-event-index-invalidation:${process.pid}`,!1,!1,waitMs,waitMs===0?{maxWaitMs:0}:void 0);try{return await operation()}finally{await release()}}async function beginHistoryEventIndexInvalidation(pmRoot){const directory=historyEventIndexInvalidationDirectory(pmRoot);await fs.mkdir(directory,{recursive:!0});const token=randomUUID(),processIdentity=await captureProcessIdentity(),pendingPath=path.join(directory,`${processIdentity.pid}-${processIdentity.process_start_identity??"unknown"}-${Date.now()}-${token}.pending`);return await fs.writeFile(pendingPath,`pending
|
|
3
3
|
`,{flag:"wx"}),{pendingPath,committedPath:path.join(directory,`${token}.committed`)}}function sameInvalidationNames(left,right){return left.length===right.length&&left.every((name,index)=>name===right[index])}async function invalidateHistoryEventIndex(pmRoot){try{await fs.rm(eventIndexPath(pmRoot),{force:!0})}catch{}}async function recordHistoryEventIndexInvalidation(pmRoot,retainCache){const directory=historyEventIndexInvalidationDirectory(pmRoot);await fs.mkdir(directory,{recursive:!0}),await fs.writeFile(path.join(directory,`${randomUUID()}${retainCache?".contended":""}.committed`),`committed
|
|
4
4
|
`,{flag:"wx"}),retainCache||await invalidateHistoryEventIndex(pmRoot)}function hasContendedHistoryEventIndexInvalidation(invalidations){return invalidations.committed.some(name=>name.endsWith(".contended.committed"))}function hasNativeHistoryEventIndexContention(pmRoot,Database){let database;try{return database=new Database(eventIndexPath(pmRoot)),database.exec("PRAGMA busy_timeout = 0"),database.exec("BEGIN EXCLUSIVE"),!1}catch(error){return isHistoryIndexSqliteContention(error)}finally{database?.close()}}async function historyEventIndexAppendIsActive(pmRoot,invalidations){return invalidations.pending.length>0||await hasUnexpiredLockOwner(pmRoot,HISTORY_EVENT_INDEX_LOCK_ID,HISTORY_EVENT_INDEX_APPEND_OWNER_PREFIX)}async function withHistoryEventIndexLock(pmRoot,operation,waitMs=HISTORY_EVENT_INDEX_LOCK_WAIT_MS,purpose="rebuild"){const release=await acquireLock(pmRoot,HISTORY_EVENT_INDEX_LOCK_ID,HISTORY_EVENT_INDEX_LOCK_TTL_SECONDS,`history-event-index:${purpose}:${process.pid}`,!1,!1,waitMs,waitMs===0?{maxWaitMs:0}:void 0);try{return await operation()}finally{await release()}}async function readAuthoritativeHistorySnapshot(pmRoot){const historyRoot=path.join(pmRoot,"history"),entries=await fs.readdir(historyRoot,{withFileTypes:!0}).catch(error=>{if(typeof error=="object"&&error!==null&&"code"in error&&error.code==="ENOENT")return[];throw error}),cached=authoritativeHistoryCaches.get(pmRoot)??{streams:new Map,ordered_events:[]},presentStreams=new Set;let changed=!authoritativeHistoryCaches.has(pmRoot);for(const historyFile of entries.filter(entry=>entry.isFile()&&entry.name.endsWith(".jsonl")).sort((left,right)=>left.name.localeCompare(right.name))){const streamId=historyFile.name.slice(0,-6);presentStreams.add(streamId);const historyPath=path.join(historyRoot,historyFile.name),stats=await fs.stat(historyPath,{bigint:!0}),signature=[stats.dev,stats.ino,stats.size,stats.mtimeNs,stats.ctimeNs].join(":");if(cached.streams.get(streamId)?.signature===signature)continue;const history=await readIndexableHistoryEntries(historyPath,streamId);cached.streams.set(streamId,{signature,byte_size:Number(stats.size),events:history.map((entry,streamOffset)=>({stream_id:streamId,stream_offset:streamOffset,entry}))}),changed=!0}for(const streamId of cached.streams.keys())presentStreams.has(streamId)||(cached.streams.delete(streamId),changed=!0);if(changed&&(cached.ordered_events=[...cached.streams.values()].flatMap(stream=>stream.events).sort(compareHistoryEventPosition)),authoritativeHistoryCaches.delete(pmRoot),authoritativeHistoryCaches.set(pmRoot,cached),authoritativeHistoryCaches.size>AUTHORITATIVE_HISTORY_CACHE_LIMIT){const oldestRoot=authoritativeHistoryCaches.keys().next().value;authoritativeHistoryCaches.delete(oldestRoot)}return{events:cached.ordered_events,stream_byte_sizes:new Map([...cached.streams].map(([streamId,stream])=>[streamId,stream.byte_size]))}}async function readIndexableHistoryEntries(historyPath,streamId){const entries=await readHistoryEntries(historyPath,streamId);for(const[index,entry]of entries.entries())if(typeof entry.ts!="string"||!isMillisecondPrecisionRfc3339DateTime(entry.ts.trim()))throw new PmCliError(`History for ${streamId} contains an invalid or sub-millisecond timestamp at line ${index+1}. Repair or restore the history stream and retry.`,EXIT_CODE.GENERIC_FAILURE,{code:"history_timestamp_invalid"});return entries.map(entry=>({...entry,ts:new Date(entry.ts.trim()).toISOString()}))}async function readAuthoritativeHistoryEvents(pmRoot){return(await readAuthoritativeHistorySnapshot(pmRoot)).events}let RuntimeDatabaseSync;function resolveDatabaseSync(){return RuntimeDatabaseSync!==void 0||(RuntimeDatabaseSync=loadStableDatabaseSync(process.versions.node,createRequire(import.meta.url))),RuntimeDatabaseSync}function createSchema(database){database.exec(`
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
stream_id, stream_offset, ts, author, agent_harness,
|
|
41
41
|
agent_instance, op, event_class, entry_json
|
|
42
42
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(event.stream_id,event.stream_offset,entry.ts,entry.author,entry.agent_harness??null,entry.agent_instance??null,entry.op,classifyHistoryEvent(entry),JSON.stringify(entry))}function parseIndexedHistoryEvent(row){const entry=JSON.parse(String(row.entry_json));return typeof entry.ts!="string"||!isMillisecondPrecisionRfc3339DateTime(entry.ts.trim())?null:{stream_id:String(row.stream_id),stream_offset:Number(row.stream_offset),entry:{...entry,ts:new Date(entry.ts.trim()).toISOString()}}}function upsertStreamByteSize(database,streamId,byteSize){database.prepare(`INSERT INTO streams(stream_id, byte_size) VALUES (?, ?)
|
|
43
|
-
ON CONFLICT(stream_id) DO UPDATE SET byte_size = excluded.byte_size`).run(streamId,byteSize)}async function rebuildHistoryEventIndex(pmRoot,options={}){const Database=resolveDatabaseSync();return Database?withHistoryEventIndexLock(pmRoot,async()=>{let invalidations;try{invalidations=await withHistoryEventIndexInvalidationLock(pmRoot,()=>recoverAbandonedHistoryEventIndexInvalidations(pmRoot),options.lockWaitMs)}catch(error){if(error instanceof PmCliError&&error.code==="lock_conflict")return!1;throw error}if(invalidations.pending.length>0||hasContendedHistoryEventIndexInvalidation(invalidations)&&hasNativeHistoryEventIndexContention(pmRoot,Database))return!1;const targetPath=eventIndexPath(pmRoot);await fs.mkdir(path.dirname(targetPath),{recursive:!0});const temporaryPath=`${targetPath}.${randomUUID()}.tmp`;let database;try{database=new Database(temporaryPath),createSchema(database),database.exec("BEGIN IMMEDIATE");const authoritative=await readAuthoritativeHistorySnapshot(pmRoot);await populateHistoryEventIndex(database,authoritative),database.exec("COMMIT"),database.close(),database=void 0;const published=await withHistoryEventIndexInvalidationLock(pmRoot,async()=>{const current=await recoverAbandonedHistoryEventIndexInvalidations(pmRoot);return current.pending.length>0||!sameInvalidationNames(invalidations.committed,current.committed)||hasContendedHistoryEventIndexInvalidation(current)&&hasNativeHistoryEventIndexContention(pmRoot,Database)?!1:(await fs.rm(targetPath,{force:!0}),await fs.rename(temporaryPath,targetPath),!0)},options.lockWaitMs);return published&&await Promise.all(invalidations.committed.map(name=>fs.rm(path.join(historyEventIndexInvalidationDirectory(pmRoot),name),{force:!0}))),published||(await deferAutomaticHistoryRepair(pmRoot),await fs.rm(temporaryPath,{force:!0})),published}catch(error){throw await deferAutomaticHistoryRepair(pmRoot),database?.close(),await fs.rm(temporaryPath,{force:!0}),error}},options.lockWaitMs):!1}async function populateHistoryEventIndex(database,snapshot){let inserted=0;for(const event of snapshot.events)insertEvent(database,event),++inserted%500===0&&await yieldToEventLoop();for(const[streamId,byteSize]of snapshot.stream_byte_sizes)upsertStreamByteSize(database,streamId,byteSize),++inserted%500===0&&await yieldToEventLoop()}function matchesSet(value,accepted){return!accepted||accepted.length===0||accepted.includes(value)}function compareHistoryEventPosition(left,right){return left.entry.ts.localeCompare(right.entry.ts)||left.stream_id.localeCompare(right.stream_id)||left.stream_offset-right.stream_offset}function canonicalHistoryQueryTimestamp(value){const milliseconds=Date.parse(value);return Number.isFinite(milliseconds)?new Date(milliseconds).toISOString():value}function isInsideHistoryEventWindow(event,query){if(query.after_ts!==void 0&&query.after_stream_id!==void 0&&query.after_stream_offset!==void 0){if(compareHistoryEventPosition(event,{stream_id:query.after_stream_id,stream_offset:query.after_stream_offset,entry:{...event.entry,ts:canonicalHistoryQueryTimestamp(query.after_ts)}})<=0)return!1}else if(query.since_ts!==void 0&&event.entry.ts<canonicalHistoryQueryTimestamp(query.since_ts))return!1;return!0}function matchesHistoryEventHarness(event,query){return!query.harnesses||query.harnesses.length===0||query.harnesses.includes(event.entry.agent_harness??"")?!0:event.entry.agent_harness===void 0&&(query.harness_alias_authors??[]).includes(event.entry.author)}function matchesHistoryEventQuery(event,query){return!isInsideHistoryEventWindow(event,query)||!matchesSet(event.entry.op,query.ops)||!matchesSet(event.entry.author,query.authors)||!matchesSet(event.entry.agent_instance??"",query.agent_instances)||!matchesSet(event.stream_id,query.stream_ids)||!matchesHistoryEventHarness(event,query)?!1:(query.provenance??[]).every(predicate=>{const value=event.entry.agent_provenance?.[predicate.dimension]?.value;return value!==void 0&&predicate.values.includes(value)})}async function queryHistoryEventStreams(pmRoot,query){const limit=Math.max(0,Math.floor(query.limit)),rows=(await readAuthoritativeHistoryEvents(pmRoot)).filter(event=>matchesHistoryEventQuery(event,query)).slice(0,limit+1);return{events:rows.slice(0,query.limit),has_more:rows.length>query.limit}}async function historyEventIndexHasAppendBase(database,historyPath){const stored=database.prepare("SELECT byte_size FROM streams WHERE stream_id = ?").get(path.basename(historyPath,".jsonl"));let actualSize=0;try{actualSize=(await fs.stat(historyPath)).size}catch(error){if(!isFileMissingError(error))throw error}return Number(stored?.byte_size??0)===actualSize}async function appendHistoryEntryWithEventIndex(historyPath,entry,append){const pmRoot=path.dirname(path.dirname(historyPath)),Database=resolveDatabaseSync();let authoritativeAppendCommitted=!1;const appendAuthoritative=async()=>{await append(),authoritativeAppendCommitted=!0};if(!Database){await appendUnindexedHistory(pmRoot,appendAuthoritative);return}try{await withHistoryEventIndexLock(pmRoot,async()=>{const targetPath=eventIndexPath(pmRoot);try{await fs.access(targetPath)}catch{await appendAuthoritative();return}let database;try{if(database=new Database(targetPath),database.prepare("SELECT value FROM metadata WHERE key = 'version'").get()?.value!==EVENT_INDEX_VERSION)throw new TypeError("Unsupported history event index version");if(!await historyEventIndexHasAppendBase(database,historyPath))throw new TypeError("Stale history event index append base")}catch(error){if(database?.close(),isHistoryIndexSqliteContention(error))throw error;await recordHistoryEventIndexInvalidation(pmRoot,!0),await appendAuthoritative();return}try{database.exec("PRAGMA busy_timeout = 0"),database.exec("BEGIN IMMEDIATE")}catch(error){throw database.close(),error}let appended=!1;try{await appendAuthoritative(),appended=!0;const streamId=path.basename(historyPath,".jsonl"),offset=database.prepare("SELECT COALESCE(MAX(stream_offset), -1) + 1 AS value FROM events WHERE stream_id = ?").get(streamId);insertEvent(database,{stream_id:streamId,stream_offset:Number(offset.value),entry}),upsertStreamByteSize(database,streamId,(await fs.stat(historyPath)).size),database.exec("COMMIT"),database.close()}catch(error){if(database?.close(),!appended)throw error;await recordHistoryEventIndexInvalidation(pmRoot,isHistoryIndexSqliteContention(error))}},0,"append")}catch(error){if(authoritativeAppendCommitted){await invalidateHistoryEventIndex(pmRoot);return}if(!isHistoryIndexWriteContention(error))throw error;await appendUnindexedHistory(pmRoot,appendAuthoritative,isHistoryIndexSqliteContention(error))}}async function appendUnindexedHistory(pmRoot,append,nativeContention=!1){let authoritativeAppendCommitted=!1,pendingMarkerPath;try{await withHistoryEventIndexInvalidationLock(pmRoot,async()=>{const contended=nativeContention||hasContendedHistoryEventIndexInvalidation(await listHistoryEventIndexInvalidations(pmRoot)),marker=await beginHistoryEventIndexInvalidation(pmRoot);pendingMarkerPath=marker.pendingPath;try{await append(),authoritativeAppendCommitted=!0}catch(appendError){throw await fs.rm(marker.pendingPath,{force:!0}),appendError}await fs.rename(marker.pendingPath,contended?marker.committedPath.replace(/\.committed$/u,".contended.committed"):marker.committedPath),contended||await invalidateHistoryEventIndex(pmRoot)})}catch(fallbackError){if(authoritativeAppendCommitted){await invalidateHistoryEventIndex(pmRoot);try{await fs.rm(pendingMarkerPath,{force:!0})}catch{}return}throw fallbackError}}async function removeHistoryEventIndexForHistoryPath(historyPath){await fs.rm(eventIndexPath(path.dirname(path.dirname(historyPath))),{force:!0})}function appendSetPredicate(clauses,parameters,column,values){!values||values.length===0||(clauses.push(`${column} IN (${values.map(()=>"?").join(", ")})`),parameters.push(...values))}function appendHarnessPredicate(clauses,parameters,harnesses,aliasAuthors){if(!harnesses||harnesses.length===0)return;const harnessPlaceholders=harnesses.map(()=>"?").join(", "),aliases=aliasAuthors??[];if(aliases.length>0){clauses.push(`(agent_harness IN (${harnessPlaceholders}) OR (agent_harness IS NULL AND author IN (${aliases.map(()=>"?").join(", ")})))`),parameters.push(...harnesses,...aliases);return}clauses.push(`agent_harness IN (${harnessPlaceholders})`),parameters.push(...harnesses)}async function readHistoryEventIndexSnapshot(pmRoot,Database,requestedStreamIds,read){let database;try{const invalidations=await listHistoryEventIndexInvalidations(pmRoot);if(await historyEventIndexAppendIsActive(pmRoot,invalidations))return HISTORY_INDEX_CHANGED;const before=await historyEventIndexSignature(pmRoot);if(invalidations.committed.length>0)return hasContendedHistoryEventIndexInvalidation(invalidations)&&hasNativeHistoryEventIndexContention(pmRoot,Database)?HISTORY_INDEX_CHANGED:null;if(database=new Database(eventIndexPath(pmRoot),{readOnly:!0}),database.exec("BEGIN"),database.prepare("SELECT value FROM metadata WHERE key = 'version'").get()?.value!==EVENT_INDEX_VERSION)return null;const result=read(database);if(result===null)return null;const storedSizes=readHistoryEventIndexStreamSizes(database,requestedStreamIds),completed=database;database=void 0,completed.close();const streamIds=await historyIndexValidationStreamIds([...storedSizes.keys()],pmRoot,requestedStreamIds),sizesMatch=await historyIndexMatchesStreamSizes(storedSizes,pmRoot,streamIds),current=await listHistoryEventIndexInvalidations(pmRoot);return current.committed.length>0||await historyEventIndexAppendIsActive(pmRoot,current)||before!==await historyEventIndexSignature(pmRoot)?HISTORY_INDEX_CHANGED:sizesMatch?result:null}catch(error){return isHistoryIndexSqliteContention(error)?HISTORY_INDEX_CHANGED:null}finally{database?.close()}}function isHistoryIndexSqliteContention(error){return typeof error=="object"&&error!==null&&"errcode"in error&&[5,6].includes(error.errcode)}function isHistoryIndexWriteContention(error){return isHistoryIndexSqliteContention(error)||error instanceof PmCliError&&error.code==="lock_conflict"}function readHistoryEventIndexStreamSizes(database,requestedStreamIds){const storedSizes=new Map,ids=requestedStreamIds&&requestedStreamIds.length>0?[...new Set(requestedStreamIds)]:void 0;if(ids===void 0)for(const row of database.prepare("SELECT stream_id, byte_size FROM streams").all())storedSizes.set(String(row.stream_id),Number(row.byte_size));else for(let start=0;start<ids.length;start+=500){const chunk=ids.slice(start,start+500);for(const row of database.prepare(`SELECT stream_id, byte_size FROM streams WHERE stream_id IN (${chunk.map(()=>"?").join(", ")})`).all(...chunk))storedSizes.set(String(row.stream_id),Number(row.byte_size))}return storedSizes}async function historyEventIndexSignature(pmRoot){const stats=await fs.stat(eventIndexPath(pmRoot),{bigint:!0});return[stats.dev,stats.ino,stats.size,stats.mtimeNs,stats.ctimeNs].join(":")}async function readHistoryEventIndexPage(pmRoot,query){const Database=resolveDatabaseSync();if(!Database)return{result:null,repair_needed:!1};const clauses=[],parameters=[];if(query.after_ts!==void 0&&query.after_stream_id!==void 0&&query.after_stream_offset!==void 0){clauses.push("(ts > ? OR (ts = ? AND stream_id > ?) OR (ts = ? AND stream_id = ? AND stream_offset > ?))");const afterTimestamp=canonicalHistoryQueryTimestamp(query.after_ts);parameters.push(afterTimestamp,afterTimestamp,query.after_stream_id,afterTimestamp,query.after_stream_id,query.after_stream_offset)}else query.since_ts!==void 0&&(clauses.push("ts >= ?"),parameters.push(canonicalHistoryQueryTimestamp(query.since_ts)));appendSetPredicate(clauses,parameters,"op",query.ops),appendSetPredicate(clauses,parameters,"author",query.authors),appendHarnessPredicate(clauses,parameters,query.harnesses,query.harness_alias_authors),appendSetPredicate(clauses,parameters,"agent_instance",query.agent_instances);for(const predicate of query.provenance??[])clauses.push(`json_extract(entry_json, '$.agent_provenance.${predicate.dimension}.value') IN (${predicate.values.map(()=>"?").join(", ")})`),parameters.push(...predicate.values);appendSetPredicate(clauses,parameters,"stream_id",query.stream_ids);const where=clauses.length===0?"":` WHERE ${clauses.join(" AND ")}`,attempt=await readHistoryEventIndexSnapshot(pmRoot,Database,query.stream_ids,database=>{const rows=database.prepare(`SELECT stream_id, stream_offset, entry_json
|
|
43
|
+
ON CONFLICT(stream_id) DO UPDATE SET byte_size = excluded.byte_size`).run(streamId,byteSize)}async function rebuildHistoryEventIndex(pmRoot,options={}){const Database=resolveDatabaseSync();return Database?withHistoryEventIndexLock(pmRoot,async()=>{let invalidations;try{invalidations=await withHistoryEventIndexInvalidationLock(pmRoot,()=>recoverAbandonedHistoryEventIndexInvalidations(pmRoot),options.lockWaitMs)}catch(error){if(error instanceof PmCliError&&error.code==="lock_conflict")return!1;throw error}if(invalidations.pending.length>0||hasContendedHistoryEventIndexInvalidation(invalidations)&&hasNativeHistoryEventIndexContention(pmRoot,Database))return!1;const targetPath=eventIndexPath(pmRoot);await fs.mkdir(path.dirname(targetPath),{recursive:!0});const temporaryPath=`${targetPath}.${randomUUID()}.tmp`;let database;try{database=new Database(temporaryPath),createSchema(database),database.exec("BEGIN IMMEDIATE");const authoritative=await readAuthoritativeHistorySnapshot(pmRoot);await populateHistoryEventIndex(database,authoritative),database.exec("COMMIT"),database.close(),database=void 0;const published=await withHistoryEventIndexInvalidationLock(pmRoot,async()=>{const current=await recoverAbandonedHistoryEventIndexInvalidations(pmRoot);return current.pending.length>0||!sameInvalidationNames(invalidations.committed,current.committed)||hasContendedHistoryEventIndexInvalidation(current)&&hasNativeHistoryEventIndexContention(pmRoot,Database)?!1:(await fs.rm(targetPath,{force:!0}),await fs.rename(temporaryPath,targetPath),!0)},options.lockWaitMs);return published&&await Promise.all(invalidations.committed.map(name=>fs.rm(path.join(historyEventIndexInvalidationDirectory(pmRoot),name),{force:!0}))),published||(await deferAutomaticHistoryRepair(pmRoot),await fs.rm(temporaryPath,{force:!0})),published}catch(error){throw await deferAutomaticHistoryRepair(pmRoot),database?.close(),await fs.rm(temporaryPath,{force:!0}),error}},options.lockWaitMs):!1}async function populateHistoryEventIndex(database,snapshot){let inserted=0;for(const event of snapshot.events)insertEvent(database,event),++inserted%500===0&&await yieldToEventLoop();for(const[streamId,byteSize]of snapshot.stream_byte_sizes)upsertStreamByteSize(database,streamId,byteSize),++inserted%500===0&&await yieldToEventLoop()}function matchesSet(value,accepted){return!accepted||accepted.length===0||accepted.includes(value)}function compareHistoryEventPosition(left,right){return left.entry.ts.localeCompare(right.entry.ts)||left.stream_id.localeCompare(right.stream_id)||left.stream_offset-right.stream_offset}function canonicalHistoryQueryTimestamp(value){const milliseconds=Date.parse(value);return Number.isFinite(milliseconds)?new Date(milliseconds).toISOString():value}function isInsideHistoryEventWindow(event,query){if(query.after_ts!==void 0&&query.after_stream_id!==void 0&&query.after_stream_offset!==void 0){if(compareHistoryEventPosition(event,{stream_id:query.after_stream_id,stream_offset:query.after_stream_offset,entry:{...event.entry,ts:canonicalHistoryQueryTimestamp(query.after_ts)}})<=0)return!1}else if(query.since_ts!==void 0&&event.entry.ts<canonicalHistoryQueryTimestamp(query.since_ts))return!1;return!0}function matchesHistoryEventHarness(event,query){return!query.harnesses||query.harnesses.length===0||query.harnesses.includes(event.entry.agent_harness??"")?!0:event.entry.agent_harness===void 0&&(query.harness_alias_authors??[]).includes(event.entry.author)}function matchesHistoryEventQuery(event,query){return!isInsideHistoryEventWindow(event,query)||!matchesSet(event.entry.op,query.ops)||!matchesSet(event.entry.author,query.authors)||!matchesSet(event.entry.agent_instance??"",query.agent_instances)||!matchesSet(event.stream_id,query.stream_ids)||!matchesHistoryEventHarness(event,query)?!1:(query.provenance??[]).every(predicate=>{const value=event.entry.agent_provenance?.[predicate.dimension]?.value;return value!==void 0&&predicate.values.includes(value)})}async function queryHistoryEventStreams(pmRoot,query){const limit=Math.max(0,Math.floor(query.limit)),rows=(await readAuthoritativeHistoryEvents(pmRoot)).filter(event=>matchesHistoryEventQuery(event,query)).slice(0,limit+1);return{events:rows.slice(0,query.limit),has_more:rows.length>query.limit}}async function historyEventIndexHasAppendBase(database,historyPath){const stored=database.prepare("SELECT byte_size FROM streams WHERE stream_id = ?").get(path.basename(historyPath,".jsonl"));let actualSize=0;try{actualSize=(await fs.stat(historyPath)).size}catch(error){if(!isFileMissingError(error))throw error}return Number(stored?.byte_size??0)===actualSize}async function appendHistoryEntryWithEventIndex(historyPath,entry,append){const pmRoot=path.dirname(path.dirname(historyPath)),Database=resolveDatabaseSync();let authoritativeAppendCommitted=!1;const appendAuthoritative=async()=>{await append(),authoritativeAppendCommitted=!0};if(!Database){await appendUnindexedHistory(pmRoot,appendAuthoritative);return}try{await withHistoryEventIndexLock(pmRoot,async()=>{const targetPath=eventIndexPath(pmRoot);try{await fs.access(targetPath)}catch{await appendAuthoritative();return}let database;try{if(database=new Database(targetPath),database.prepare("SELECT value FROM metadata WHERE key = 'version'").get()?.value!==EVENT_INDEX_VERSION)throw new TypeError("Unsupported history event index version");if(!await historyEventIndexHasAppendBase(database,historyPath))throw new TypeError("Stale history event index append base")}catch(error){if(database?.close(),isHistoryIndexSqliteContention(error))throw error;await recordHistoryEventIndexInvalidation(pmRoot,!0),await appendAuthoritative();return}try{database.exec("PRAGMA busy_timeout = 0"),database.exec("BEGIN IMMEDIATE")}catch(error){if(database.close(),isHistoryIndexSqliteContention(error)||!(error instanceof Error)||error.code!=="ERR_SQLITE_ERROR")throw error;await recordHistoryEventIndexInvalidation(pmRoot,!1),await appendAuthoritative();return}let appended=!1;try{await appendAuthoritative(),appended=!0;const streamId=path.basename(historyPath,".jsonl"),offset=database.prepare("SELECT COALESCE(MAX(stream_offset), -1) + 1 AS value FROM events WHERE stream_id = ?").get(streamId);insertEvent(database,{stream_id:streamId,stream_offset:Number(offset.value),entry}),upsertStreamByteSize(database,streamId,(await fs.stat(historyPath)).size),database.exec("COMMIT"),database.close()}catch(error){if(database?.close(),!appended)throw error;await recordHistoryEventIndexInvalidation(pmRoot,isHistoryIndexSqliteContention(error))}},0,"append")}catch(error){if(authoritativeAppendCommitted){await invalidateHistoryEventIndex(pmRoot);return}if(!isHistoryIndexWriteContention(error))throw error;await appendUnindexedHistory(pmRoot,appendAuthoritative,isHistoryIndexSqliteContention(error))}}async function appendUnindexedHistory(pmRoot,append,nativeContention=!1){let authoritativeAppendCommitted=!1,pendingMarkerPath;try{await withHistoryEventIndexInvalidationLock(pmRoot,async()=>{const contended=nativeContention||hasContendedHistoryEventIndexInvalidation(await listHistoryEventIndexInvalidations(pmRoot)),marker=await beginHistoryEventIndexInvalidation(pmRoot);pendingMarkerPath=marker.pendingPath;try{await append(),authoritativeAppendCommitted=!0}catch(appendError){throw await fs.rm(marker.pendingPath,{force:!0}),appendError}await fs.rename(marker.pendingPath,contended?marker.committedPath.replace(/\.committed$/u,".contended.committed"):marker.committedPath),contended||await invalidateHistoryEventIndex(pmRoot)})}catch(fallbackError){if(authoritativeAppendCommitted){await invalidateHistoryEventIndex(pmRoot);try{await fs.rm(pendingMarkerPath,{force:!0})}catch{}return}throw fallbackError}}async function removeHistoryEventIndexForHistoryPath(historyPath){await fs.rm(eventIndexPath(path.dirname(path.dirname(historyPath))),{force:!0})}function appendSetPredicate(clauses,parameters,column,values){!values||values.length===0||(clauses.push(`${column} IN (${values.map(()=>"?").join(", ")})`),parameters.push(...values))}function appendHarnessPredicate(clauses,parameters,harnesses,aliasAuthors){if(!harnesses||harnesses.length===0)return;const harnessPlaceholders=harnesses.map(()=>"?").join(", "),aliases=aliasAuthors??[];if(aliases.length>0){clauses.push(`(agent_harness IN (${harnessPlaceholders}) OR (agent_harness IS NULL AND author IN (${aliases.map(()=>"?").join(", ")})))`),parameters.push(...harnesses,...aliases);return}clauses.push(`agent_harness IN (${harnessPlaceholders})`),parameters.push(...harnesses)}async function readHistoryEventIndexSnapshot(pmRoot,Database,requestedStreamIds,read){let database;try{const invalidations=await listHistoryEventIndexInvalidations(pmRoot);if(await historyEventIndexAppendIsActive(pmRoot,invalidations))return HISTORY_INDEX_CHANGED;const before=await historyEventIndexSignature(pmRoot);if(invalidations.committed.length>0)return hasContendedHistoryEventIndexInvalidation(invalidations)&&hasNativeHistoryEventIndexContention(pmRoot,Database)?HISTORY_INDEX_CHANGED:null;if(database=new Database(eventIndexPath(pmRoot),{readOnly:!0}),database.exec("BEGIN"),database.prepare("SELECT value FROM metadata WHERE key = 'version'").get()?.value!==EVENT_INDEX_VERSION)return null;const result=read(database);if(result===null)return null;const storedSizes=readHistoryEventIndexStreamSizes(database,requestedStreamIds),completed=database;database=void 0,completed.close();const streamIds=await historyIndexValidationStreamIds([...storedSizes.keys()],pmRoot,requestedStreamIds),sizesMatch=await historyIndexMatchesStreamSizes(storedSizes,pmRoot,streamIds),current=await listHistoryEventIndexInvalidations(pmRoot);return current.committed.length>0||await historyEventIndexAppendIsActive(pmRoot,current)||before!==await historyEventIndexSignature(pmRoot)?HISTORY_INDEX_CHANGED:sizesMatch?result:null}catch(error){return isHistoryIndexSqliteContention(error)?HISTORY_INDEX_CHANGED:null}finally{database?.close()}}function isHistoryIndexSqliteContention(error){return typeof error=="object"&&error!==null&&"errcode"in error&&[5,6].includes(error.errcode)}function isHistoryIndexWriteContention(error){return isHistoryIndexSqliteContention(error)||error instanceof PmCliError&&error.code==="lock_conflict"}function readHistoryEventIndexStreamSizes(database,requestedStreamIds){const storedSizes=new Map,ids=requestedStreamIds&&requestedStreamIds.length>0?[...new Set(requestedStreamIds)]:void 0;if(ids===void 0)for(const row of database.prepare("SELECT stream_id, byte_size FROM streams").all())storedSizes.set(String(row.stream_id),Number(row.byte_size));else for(let start=0;start<ids.length;start+=500){const chunk=ids.slice(start,start+500);for(const row of database.prepare(`SELECT stream_id, byte_size FROM streams WHERE stream_id IN (${chunk.map(()=>"?").join(", ")})`).all(...chunk))storedSizes.set(String(row.stream_id),Number(row.byte_size))}return storedSizes}async function historyEventIndexSignature(pmRoot){const stats=await fs.stat(eventIndexPath(pmRoot),{bigint:!0});return[stats.dev,stats.ino,stats.size,stats.mtimeNs,stats.ctimeNs].join(":")}async function readHistoryEventIndexPage(pmRoot,query){const Database=resolveDatabaseSync();if(!Database)return{result:null,repair_needed:!1};const clauses=[],parameters=[];if(query.after_ts!==void 0&&query.after_stream_id!==void 0&&query.after_stream_offset!==void 0){clauses.push("(ts > ? OR (ts = ? AND stream_id > ?) OR (ts = ? AND stream_id = ? AND stream_offset > ?))");const afterTimestamp=canonicalHistoryQueryTimestamp(query.after_ts);parameters.push(afterTimestamp,afterTimestamp,query.after_stream_id,afterTimestamp,query.after_stream_id,query.after_stream_offset)}else query.since_ts!==void 0&&(clauses.push("ts >= ?"),parameters.push(canonicalHistoryQueryTimestamp(query.since_ts)));appendSetPredicate(clauses,parameters,"op",query.ops),appendSetPredicate(clauses,parameters,"author",query.authors),appendHarnessPredicate(clauses,parameters,query.harnesses,query.harness_alias_authors),appendSetPredicate(clauses,parameters,"agent_instance",query.agent_instances);for(const predicate of query.provenance??[])clauses.push(`json_extract(entry_json, '$.agent_provenance.${predicate.dimension}.value') IN (${predicate.values.map(()=>"?").join(", ")})`),parameters.push(...predicate.values);appendSetPredicate(clauses,parameters,"stream_id",query.stream_ids);const where=clauses.length===0?"":` WHERE ${clauses.join(" AND ")}`,attempt=await readHistoryEventIndexSnapshot(pmRoot,Database,query.stream_ids,database=>{const rows=database.prepare(`SELECT stream_id, stream_offset, entry_json
|
|
44
44
|
FROM events${where}
|
|
45
45
|
ORDER BY ts, stream_id, stream_offset
|
|
46
46
|
LIMIT ?`).all(...parameters,Math.max(0,Math.floor(query.limit))+1),events=rows.slice(0,query.limit).map(parseIndexedHistoryEvent);return events.includes(null)?null:{events,has_more:rows.length>query.limit}});return{result:attempt===HISTORY_INDEX_CHANGED?null:attempt,repair_needed:attempt===null&&!await hasRecentRefusedHistoryRepair(pmRoot)}}async function queryHistoryEventIndex(pmRoot,query){return(await readHistoryEventIndexPage(pmRoot,query)).result}function collectLatestSubstantiveEvents(events,requested){const latest=Object.create(null);for(const event of events){if(!requested.has(event.stream_id)||classifyHistoryEvent(event.entry)!=="substantive")continue;const current=latest[event.stream_id];(current===void 0||compareHistoryEventPosition(current,event)<0)&&(latest[event.stream_id]=event)}return latest}async function readHistoryStreamByteSize(pmRoot,streamId){if(path.basename(streamId)!==streamId)return null;try{return(await fs.stat(path.join(pmRoot,"history",`${streamId}.jsonl`))).size}catch(error){if(isFileMissingError(error))return 0;throw error}}async function historyIndexMatchesStreamSizes(storedSizes,pmRoot,streamIds){for(let start=0;start<streamIds.length;start+=500){const chunk=streamIds.slice(start,start+500),currentSizes=await Promise.all(chunk.map(streamId=>readHistoryStreamByteSize(pmRoot,streamId)));for(const[index,currentSize]of currentSizes.entries()){if(currentSize===null)return!1;const streamId=chunk[index],storedSize=storedSizes.get(streamId);if(!(currentSize===0&&storedSize===void 0)&¤tSize!==storedSize)return!1}}return!0}async function historyIndexValidationStreamIds(indexed,pmRoot,requestedStreamIds){if(requestedStreamIds&&requestedStreamIds.length>0)return[...new Set(requestedStreamIds.filter(streamId=>streamId.trim().length>0))];const authoritative=await fs.readdir(path.join(pmRoot,"history"),{withFileTypes:!0}).then(entries=>entries.filter(entry=>entry.isFile()&&entry.name.endsWith(".jsonl")).map(entry=>entry.name.slice(0,-6))).catch(error=>{if(isFileMissingError(error))return[];throw error});return[...new Set([...indexed,...authoritative])]}async function readIndexedLatestSubstantiveEvents(Database,pmRoot,streamIds,requested){return Database?readHistoryEventIndexSnapshot(pmRoot,Database,streamIds,database=>{const indexed=[];for(let start=0;start<streamIds.length;start+=500){const chunk=streamIds.slice(start,start+500),parsed=database.prepare(`SELECT stream_id, stream_offset, entry_json
|
|
@@ -43,8 +43,13 @@ pmRoot?:string;
|
|
|
43
43
|
export declare function writeStdout(text:string):boolean;
|
|
44
44
|
/** Write stderr and preserve diagnostic delivery failures in the process exit code. */
|
|
45
45
|
export declare function writeStderr(text:string):boolean;
|
|
46
|
+
/** Independent presentation policies shared by recursive value compaction. */
|
|
47
|
+
interface OutputCompactionPolicy {
|
|
48
|
+
readonly omitDuplicateCountAliases:boolean;
|
|
49
|
+
readonly preserveRowFacts:boolean;
|
|
50
|
+
}
|
|
46
51
|
/** Keep sparse presentation rules shared while allowing lean JSON to retain count aliases. */
|
|
47
|
-
declare function compactToonValue(value:unknown,
|
|
52
|
+
declare function compactToonValue(value:unknown,policy?:OutputCompactionPolicy,preserveEmpty?:boolean):unknown | undefined;
|
|
48
53
|
/** Render objects recursively and arrays through the standard TOON encoder. */
|
|
49
54
|
declare function renderToonValue(value:unknown,depth:number):string;
|
|
50
55
|
/**
|
|
@@ -52,7 +57,7 @@ declare function renderToonValue(value:unknown,depth:number):string;
|
|
|
52
57
|
* extension overrides. SDK budget accounting uses this exact representation
|
|
53
58
|
* so reported token cost describes the bytes the host emits by default.
|
|
54
59
|
*/
|
|
55
|
-
export declare function formatBuiltInOutput(result:unknown,format:"json" | "toon"):string;
|
|
60
|
+
export declare function formatBuiltInOutput(result:unknown,format:"json" | "toon",lean?:boolean):string;
|
|
56
61
|
/** Resolve command ownership and suppression before projecting and rendering the result. */
|
|
57
62
|
export declare function formatOutput(result:unknown,options:OutputOptions):string;
|
|
58
63
|
/** Apply declared exit codes and mutation projection before writing a nonquiet result. */
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9716962d-d651-5e7a-84d8-496d35e8775f")}catch{}})();import{getActiveCommandContext,runActiveCommandOverride,runActiveRendererOverride,runActiveServiceOverrideSync,setActiveCommandResult}from"../extensions/index.js";import{EXIT_CODE}from"../shared/constants.js";import{isHostOutputSuppressed}from"./output-control.js";import{projectMutationResult}from"./mutation-projection.js";import{attachReadOutputContracts}from"../../sdk/context-intent-contracts.js";import{attachOutputTokenAccounting}from"../../sdk/output-token-accounting.js";import{propagateContextUsageServingReceipt}from"../../sdk/context-usage.js";import{isReadOutputBudgetExceeded,resolveReadOutputEncoding}from"../../sdk/read-output-contracts.js";import{encode as encodeToon}from"@toon-format/toon";import{encodePmTableRows}from"../../sdk/output/table-rows.js";import{projectPmBriefListEnvelope}from"../../sdk/output/list-envelope.js";const DECLARED_PROCESS_EXIT_CODES=new Set(Object.values(EXIT_CODE)),COLLECTION_COUNT_ALIASES=new Map([["notes_count","notes"],["tests_count","tests"]]),NATIVE_OUTPUT_MARKER="__pm_native_output";let streamErrorHandlersInstalled=!1;function isPlainObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function setActiveCommandResultOmitted(source){const omitted={read_output:{result_omitted:!0}};propagateContextUsageServingReceipt(source,omitted),setActiveCommandResult(omitted)}function setActiveCommandDeliveryResult(result,receiptSource,structuredDeliveryPreserved){if(structuredDeliveryPreserved){setActiveCommandResult(result);return}setActiveCommandResultOmitted(receiptSource)}function stripNativeOutputMarker(result){if(!isPlainObject(result)||result[NATIVE_OUTPUT_MARKER]!==!0)return result;const{[NATIVE_OUTPUT_MARKER]:_marker,...rest}=result;return rest}function isBrokenPipeError(error){return typeof error=="object"&&error!==null&&error.code==="EPIPE"}function markStdoutBrokenPipeExitCode(){(process.exitCode===void 0||process.exitCode===EXIT_CODE.SUCCESS)&&(process.exitCode=EXIT_CODE.SUCCESS)}function markStderrBrokenPipeExitCode(){(process.exitCode===void 0||process.exitCode===EXIT_CODE.SUCCESS)&&(process.exitCode=EXIT_CODE.GENERIC_FAILURE)}function markBrokenPipeExitCode(target){if(target==="stdout"){markStdoutBrokenPipeExitCode();return}markStderrBrokenPipeExitCode()}function handleUnhandledStreamError(error){const unhandled=error instanceof Error?error:new Error(String(error));setImmediate(()=>{throw unhandled})}function installStreamErrorHandlers(){streamErrorHandlersInstalled||(streamErrorHandlersInstalled=!0,process.stdout.on("error",error=>{if(isBrokenPipeError(error)){markBrokenPipeExitCode("stdout");return}handleUnhandledStreamError(error)}),process.stderr.on("error",error=>{if(isBrokenPipeError(error)){markBrokenPipeExitCode("stderr");return}handleUnhandledStreamError(error)}))}function writeToStream(target,text){installStreamErrorHandlers();try{return target==="stdout"?process.stdout.write(text):process.stderr.write(text),!0}catch(error){if(isBrokenPipeError(error))return markBrokenPipeExitCode(target),!1;throw error}}function writeStdout(text){return writeToStream("stdout",text)}function writeStderr(text){return writeToStream("stderr",text)}function renderScalar(value){return typeof value=="string"?JSON.stringify(value):typeof value=="number"||typeof value=="boolean"?String(value):value===null?"null":JSON.stringify(value)}function tabularObjectArray(value){const keys=Object.keys(value[0]);return keys.length>0&&value.every(entry=>Object.keys(entry).length===keys.length&&keys.every(key=>{if(!Object.hasOwn(entry,key))return!1;const cell=entry[key];return cell===null||typeof cell=="string"||typeof cell=="number"||typeof cell=="boolean"}))}function indentToon(encoded,depth){const indent=" ".repeat(depth);return encoded.split(`
|
|
2
2
|
`).map(line=>`${indent}${line}`).join(`
|
|
3
3
|
`)}function isNestedTableCandidateBounded(rows){const columns=new Set;let presentCells=0;for(const row of rows){const keys=Object.keys(row);presentCells+=keys.length;for(const key of keys)columns.add(key)}return rows.length*columns.size<=presentCells*2}function renderToonObjectEntry(key,entry,depth,allowNestedTable){const indent=" ".repeat(depth);if(!isPlainObject(entry)&&!Array.isArray(entry))return`${indent}${key}: ${renderScalar(entry)}`;if(Array.isArray(entry)){if(entry.length===0)return`${indent}${key}: []`;const expanded=indentToon(encodeToon({[key]:entry}),depth);if(allowNestedTable&&entry.length>=2&&entry.every(isPlainObject)&&!tabularObjectArray(entry)&&isNestedTableCandidateBounded(entry)){const table=encodePmTableRows(entry),tabular=indentToon(encodeToon({[key]:table.rows,[`${key}_encoding`]:table.encoding}),depth);if(Buffer.byteLength(tabular)<Buffer.byteLength(expanded))return tabular}return expanded}return isPlainObject(entry)&&Object.keys(entry).length===0?`${indent}${key}: {}`:`${indent}${key}:
|
|
4
|
-
${renderToonValue(entry,depth+1)}`}function
|
|
4
|
+
${renderToonValue(entry,depth+1)}`}function compactToonArray(values,policy,preserveEmpty){const compactedEntries=values.map(entry=>compactToonValue(entry,policy,preserveEmpty||policy.preserveRowFacts&&isPlainObject(entry))).filter(entry=>entry!==void 0);return compactedEntries.length>0||preserveEmpty?compactedEntries:void 0}function compactToonValue(value,policy={omitDuplicateCountAliases:!0,preserveRowFacts:!0},preserveEmpty=!1){if(value===null)return preserveEmpty?null:void 0;if(Array.isArray(value))return compactToonArray(value,policy,preserveEmpty);if(isPlainObject(value)){const compacted=[],entries=Object.entries(value).filter(([key,entry])=>{const canonicalCount=COLLECTION_COUNT_ALIASES.get(key);return!policy.omitDuplicateCountAliases||canonicalCount===void 0||!isPlainObject(value.collection_counts)||entry!==value.collection_counts[canonicalCount]});for(const[key,entry]of entries){if(key==="omitted_field_groups"&&Array.isArray(entry)&&entry.length===0){compacted.push([key,[]]);continue}const compactedEntry=compactToonValue(entry,policy,preserveEmpty);compactedEntry!==void 0&&compacted.push([key,compactedEntry])}return compacted.length>0||preserveEmpty?Object.fromEntries(compacted):void 0}return value}function renderToonValue(value,depth){const indent=" ".repeat(depth);if(Array.isArray(value))return value.length===0?"[]":indentToon(encodeToon(value),depth);if(isPlainObject(value)){const entries=Object.entries(value);return entries.length===0?"{}":entries.map(([key,entry])=>renderToonObjectEntry(key,entry,depth,!Object.hasOwn(value,`${key}_encoding`)&&!(key==="checks"&&isPlainObject(value.verdict)&&value.verdict.authority==="ok"))).join(`
|
|
5
5
|
`)}return`${indent}${renderScalar(value)}`}function renderDefaultMarkdownResult(value){if(!isPlainObject(value)||value.output_default!=="markdown"||typeof value.view!="string"||!Array.isArray(value.events)||!Array.isArray(value.days))return null;const lines=[`# pm calendar (${value.view})`,""],summary=isPlainObject(value.summary)?value.summary:{};if(lines.push(`- events: ${String(summary.events??0)}`),lines.push(""),value.events.length===0)return lines.push("No calendar events matched the selected filters."),`${lines.join(`
|
|
6
6
|
`)}
|
|
7
7
|
`;for(const event of value.events){if(!isPlainObject(event))continue;const kind=typeof event.kind=="string"?event.kind:"event",title=typeof event.item_title=="string"?event.item_title:"",itemId=typeof event.item_id=="string"?event.item_id:"",reminderText=typeof event.reminder_text=="string"&&event.reminder_text.length>0?` ${event.reminder_text}`:"";lines.push(`- [${kind}] ${itemId} ${title}${reminderText}`.trim())}return`${lines.join(`
|
|
8
8
|
`)}
|
|
9
|
-
`}const LEAN_READ_ENVELOPE_ECHO_KEYS=new Set(["filters","now","projection","sorting"]);function projectLeanJsonValue(value){const compacted=compactToonValue(value
|
|
10
|
-
`;const compactedToon=compactToonValue(
|
|
9
|
+
`}const LEAN_READ_ENVELOPE_ECHO_KEYS=new Set(["filters","now","projection","sorting"]);function projectLeanJsonValue(value){const compacted=compactToonValue(value,{omitDuplicateCountAliases:!1,preserveRowFacts:!1});if(!isPlainObject(compacted)||!Array.isArray(compacted.items))return compacted??null;const projected=Object.fromEntries(Object.entries(compacted).filter(([key])=>!LEAN_READ_ENVELOPE_ECHO_KEYS.has(key)));return projected.has_more!==!0&&delete projected.next_cursor,projected}function projectLinkedTestEvidence(value,lean){if(!isPlainObject(value)||!Array.isArray(value.run_results)||!value.run_results.every(isPlainObject))return value;const rows=value.run_results,contexts=rows.map(row=>row.execution_context).filter(context=>context!==void 0),sharedContext=contexts.length===rows.length&&contexts.length>0&&contexts.every(context=>JSON.stringify(context)===JSON.stringify(contexts[0]))?contexts[0]:void 0,runResults=rows.map(row=>{const{execution_context:_executionContext,stdout,stderr,...rest}=row;return sharedContext===void 0?row:!lean||row.status!=="passed"?{...rest,stdout,stderr}:rest});return{...value,...sharedContext===void 0?{}:{execution_context:sharedContext},run_results:runResults}}function projectEmptyCheckDetails(value){return!isPlainObject(value)||value.ok!==!0||!isPlainObject(value.verdict)||value.verdict.authority!=="ok"||!Array.isArray(value.checks)?value:{...value,checks:value.checks.map(omitEmptySuccessfulCheckDetails)}}function omitEmptySuccessfulCheckDetails(check){if(!isPlainObject(check)||check.ok!==!0||!isPlainObject(check.details)||Object.keys(check.details).length!==0)return check;const{details:_details,...rest}=check;return rest}function formatBuiltInOutput(result,format,lean=!1){if(format==="json")return`${JSON.stringify(lean?projectLeanJsonValue(result):result,null,2)}
|
|
10
|
+
`;const compactedToon=compactToonValue(projectEmptyCheckDetails(projectPmBriefListEnvelope(result)),{omitDuplicateCountAliases:!0,preserveRowFacts:!0});return compactedToon===void 0?`{}
|
|
11
11
|
`:`${renderToonValue(compactedToon,0)}
|
|
12
12
|
`}function resolveOutputService(effectiveResult,nativeOutput,options,format){const serviceOverride=nativeOutput?{handled:!1,result:effectiveResult,warnings:[]}:runActiveServiceOverrideSync("output_format",{command:options.command,args:options.commandArgs,command_options:options.commandOptions,global:{...options},pm_root:options.pmRoot,format,options:{...options},result:effectiveResult}),legacyPayloadEchoWarning=serviceOverride.warnings.find(warning=>warning.startsWith("extension_output_format_payload_echo_deprecated:"));return legacyPayloadEchoWarning!==void 0&&writeStderr(`Warning: ${legacyPayloadEchoWarning}. Returning context.payload now declines safely for compatibility; migrate the override to declineServiceOverride() or { handled: false }.
|
|
13
13
|
`),serviceOverride.handled&&typeof serviceOverride.result=="string"?{result:serviceOverride.result,rendered:serviceOverride.result.endsWith(`
|
|
14
14
|
`)?serviceOverride.result:`${serviceOverride.result}
|
|
15
15
|
`,structuredDeliveryPreserved:!1}:{result:serviceOverride.handled?serviceOverride.result:effectiveResult,rendered:null,structuredDeliveryPreserved:!serviceOverride.handled||isPlainObject(serviceOverride.result)}}function formatEffectiveOutput(effectiveResult,nativeOutput,options,defaultFormat){const activeCommandContext=getActiveCommandContext(),command=options.command??activeCommandContext?.command,commandOptions={...activeCommandContext?.options,...options.commandOptions,...Object.fromEntries([["outputInclude",options.outputInclude],["outputLimit",options.outputLimit],["outputBudget",options.outputBudget],["outputFormat",options.outputFormat],["outputSession",options.outputSession],["outputCursor",options.outputCursor],["outputRowContract",options.outputRowContract]].filter(entry=>entry[1]!==void 0))},format=resolveReadOutputEncoding(command??"",commandOptions)??defaultFormat,resolvedCommandOptions={...commandOptions,resolvedOutputFormat:format},effectiveOptions={...options,command,commandOptions:resolvedCommandOptions},service=resolveOutputService(effectiveResult,nativeOutput,effectiveOptions,format);if(service.rendered!==null)return setActiveCommandResultOmitted(effectiveResult),service.rendered;const outputResult=service.result;propagateContextUsageServingReceipt(effectiveResult,outputResult);const projectedOutputResult=command==="test"?projectLinkedTestEvidence(outputResult,options.lean===!0):outputResult,intentOutputResult=attachReadOutputContracts(command,resolvedCommandOptions,projectedOutputResult);isReadOutputBudgetExceeded(intentOutputResult)&&(process.exitCode||=EXIT_CODE.USAGE);let{structuredDeliveryPreserved}=service;const renderResolvedOutput=value=>{if(format==="toon"){const markdownDefault=renderDefaultMarkdownResult(value);if(markdownDefault!==null)return markdownDefault}const rendererOverride=nativeOutput?{rendered:null}:runActiveRendererOverride(format,value);return rendererOverride.rendered!==null?(structuredDeliveryPreserved=!1,rendererOverride.rendered.endsWith(`
|
|
16
16
|
`)?rendererOverride.rendered:`${rendererOverride.rendered}
|
|
17
|
-
`):format==="json"?formatBuiltInOutput(options.lean===!0
|
|
17
|
+
`):format==="json"?formatBuiltInOutput(value,"json",options.lean===!0):formatBuiltInOutput(value,"toon")},accountedOutputResult=options.tokenAccounting===!0?attachOutputTokenAccounting(intentOutputResult,renderResolvedOutput):intentOutputResult,rendered=renderResolvedOutput(accountedOutputResult);return setActiveCommandDeliveryResult(accountedOutputResult,effectiveResult,options.quiet!==!0&&structuredDeliveryPreserved),rendered}function formatOutput(result,options){const commandOverride=runActiveCommandOverride(result),suppressedOutput=isHostOutputSuppressed(commandOverride.result)?commandOverride.result:null,nativeResult=commandOverride.result,nativeOutput=isPlainObject(nativeResult)&&nativeResult[NATIVE_OUTPUT_MARKER]===!0,effectiveResult=suppressedOutput?suppressedOutput.result:stripNativeOutputMarker(commandOverride.result);if(setActiveCommandResult(effectiveResult),suppressedOutput)return setActiveCommandResultOmitted(effectiveResult),"";const defaultFormat=options.json===!0||options.json===void 0&&options.defaultOutputFormat==="json"?"json":"toon";return formatEffectiveOutput(effectiveResult,nativeOutput,options,defaultFormat)}function printResult(result,options){isPlainObject(result)&&Number.isInteger(result.exit_code)&&DECLARED_PROCESS_EXIT_CODES.has(Number(result.exit_code))&&(process.exitCode===void 0||process.exitCode===EXIT_CODE.SUCCESS)&&(process.exitCode=Number(result.exit_code));const projected=options.idOnly?projectMutationResult(result,{idOnly:!0}):options.fullChangedFields?result:options.noChangedFields?projectMutationResult(result,{changedFields:"compact"}):projectMutationResult(result,{compactEnvelope:!0}),rendered=formatOutput(projected,options);options.quiet||writeStdout(rendered)}function printError(message){const override=runActiveServiceOverrideSync("error_format",{message}),rendered=override.handled&&typeof override.result=="string"?override.result:message;writeStderr(rendered.endsWith(`
|
|
18
18
|
`)?rendered:`${rendered}
|
|
19
19
|
`)}const outputTestOnly={compactToonValue,renderToonValue};export{formatBuiltInOutput,formatOutput,outputTestOnly,printError,printResult,writeStderr,writeStdout};
|
|
20
20
|
//# sourceMappingURL=output.js.map
|
|
@@ -3,6 +3,42 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides shared primitives and utilities for Errors.
|
|
5
5
|
*/
|
|
6
|
+
/** Shared request identity for each canonical retry evidence state. */
|
|
7
|
+
interface PmTokenBudgetRecoveryBase {
|
|
8
|
+
/** Estimated tokens requested by the failed query. */
|
|
9
|
+
requested_tokens:number;
|
|
10
|
+
/** The emitted retry preserves selection and makes its encoding explicit. */
|
|
11
|
+
basis:"canonical_retry";
|
|
12
|
+
}
|
|
13
|
+
/** Verified budget advice, narrowed by the evidence established for the preserved retry. */
|
|
14
|
+
export type PmTokenBudgetRecovery = PmTokenBudgetRecoveryBase & ({
|
|
15
|
+
/** Every smaller positive budget was checked before proving this minimum. */
|
|
16
|
+
minimum_status:"exact";
|
|
17
|
+
/** Verified working budget; runtime validation also requires equality with the minimum. */
|
|
18
|
+
feasible_tokens:number;
|
|
19
|
+
/** Proved global minimum for the canonical retry. */
|
|
20
|
+
minimum_feasible_tokens:number;
|
|
21
|
+
/** A successful verification has no unavailable cause. */
|
|
22
|
+
reason?:undefined;
|
|
23
|
+
} | {
|
|
24
|
+
/** A working budget is verified, while a global minimum remains unproved. */
|
|
25
|
+
minimum_status:"feasible_only";
|
|
26
|
+
/** Verified working budget for the canonical retry. */
|
|
27
|
+
feasible_tokens:number;
|
|
28
|
+
/** No exact minimum is claimed for a partial search. */
|
|
29
|
+
minimum_feasible_tokens:null;
|
|
30
|
+
/** A successful verification has no unavailable cause. */
|
|
31
|
+
reason?:undefined;
|
|
32
|
+
} | {
|
|
33
|
+
/** Bounded recovery could not establish a working budget. */
|
|
34
|
+
minimum_status:"unavailable";
|
|
35
|
+
/** No working budget was verified. */
|
|
36
|
+
feasible_tokens:null;
|
|
37
|
+
/** No minimum can be claimed without a working budget. */
|
|
38
|
+
minimum_feasible_tokens:null;
|
|
39
|
+
/** Why recovery could not establish a working budget within its work limits. */
|
|
40
|
+
reason:"query_cost_limit" | "search_limit" | "output_constraints";
|
|
41
|
+
});
|
|
6
42
|
/** Carries structured recovery guidance attached to expected pm CLI errors. */
|
|
7
43
|
export interface PmCliErrorRecoveryPayload {
|
|
8
44
|
/** Strategy used to control recovery behavior. */
|
|
@@ -38,6 +74,8 @@ option_scope?:"declared_on_path" | "declared_elsewhere" | "declared_nowhere";
|
|
|
38
74
|
suggested_retry?:string;
|
|
39
75
|
/** Tokenized retry arguments for direct execution without reparsing display text. */
|
|
40
76
|
suggested_retry_args?:string[];
|
|
77
|
+
/** Bounded, verified token-budget guidance for an executable context retry. */
|
|
78
|
+
token_budget?:PmTokenBudgetRecovery;
|
|
41
79
|
/** Elapsed time in milliseconds for retry after. */
|
|
42
80
|
retry_after_ms?:number;
|
|
43
81
|
/** Value that configures or reports fallback candidates for this contract. */
|
|
@@ -68,6 +106,15 @@ op:string;
|
|
|
68
106
|
/** Resolved target identity. */
|
|
69
107
|
id:string;
|
|
70
108
|
};
|
|
109
|
+
/** Bounded storage coordinate for a refused preview entry; never an absolute path or link target. */
|
|
110
|
+
preview_storage?:{
|
|
111
|
+
/** Fixed storage category, available even when the entry name must be hidden. */
|
|
112
|
+
storage_area:string;
|
|
113
|
+
/** Safe tracker-relative path with portable slash separators, when available. */
|
|
114
|
+
relative_entry?:string;
|
|
115
|
+
/** Whether the coordinate was withheld because it was unsafe, absent, or overlong. */
|
|
116
|
+
entry_redacted:boolean;
|
|
117
|
+
};
|
|
71
118
|
/** Verified retained deletion and the latest recoverable durable address. */
|
|
72
119
|
tombstone?:{
|
|
73
120
|
/** The retained stream proves the item is currently deleted. */
|
|
@@ -206,3 +253,4 @@ readonly context:PmCliErrorContext;
|
|
|
206
253
|
/** Value that configures or reports constructor for this contract. */
|
|
207
254
|
constructor(message:string,exitCode:number,context?:PmCliErrorContext);
|
|
208
255
|
}
|
|
256
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1e7d4217-da18-5bfc-a00b-67bba61f57c2")}catch{}})();class PmCliError extends Error{exitCode;code;context;constructor(message,exitCode,context={}){super(message),this.name="PmCliError",this.exitCode=exitCode,this.context=context,this.code=context.code}}export{PmCliError};
|
|
2
2
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="bbb5e299-541d-5fff-8422-855c85cf7a31")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{lstat,realpath}from"node:fs/promises";import path from"node:path";import{validateSettings}from"./settings-validator.js";import{runActiveOnReadHooks,runActiveOnWriteHooks}from"../extensions/index.js";import{EXIT_CODE,GOVERNANCE_PRESET_DEFAULTS,SETTINGS_DEFAULTS}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{resolveAuthor}from"../shared/author.js";import{isFileAbsentError,readFileIfExists,readRegularFile,transactionPreviewNonRegularFileError}from"../fs/fs-utils.js";import{mutateWorkspaceJsonWithHistory}from"../history/workspace-history.js";import{reconcileSettingsSnapshot}from"./settings-concurrency.js";import{DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,ensureRuntimeSchemaFileScaffold,filePathForSchemaSection,loadRuntimeSchemaFromOptionalFiles,normalizeRuntimeSchemaSettings}from"../schema/runtime-schema.js";import{getSettingsPath}from"./paths.js";import{orderObject,stableValueEquals}from"../shared/serialization.js";import{normalizeItemTypeDefinition}from"../item/item-type-definition.js";import{normalizeEstimateDefaultOverrides}from"../validate/estimate-defaults.js";import{clearSettingsReadCache,collectSettingsReadCacheSignatures,getSettingsReadCacheEntry,setSettingsReadCacheEntry,settingsReadCacheSignaturesEqual}from"./settings-read-cache.js";const configurationOnlySettingsRoots=new AsyncLocalStorage;async function runWithConfigurationOnlySettings(pmRoot,run,isEnabled=()=>!0){const roots=new Set([path.resolve(pmRoot)]);try{roots.add(await realpath(pmRoot))}catch{}return configurationOnlySettingsRoots.run([...configurationOnlySettingsRoots.getStore()??[],[roots,isEnabled]],run)}function isConfigurationOnlySettingsRead(pmRoot){const root=path.resolve(pmRoot);return configurationOnlySettingsRoots.getStore()?.some(([roots,isEnabled])=>roots.has(root)&&isEnabled())??!1}const SETTINGS_WRITE_OP="settings:write",SETTINGS_PERSIST_SOURCE_SYMBOL=Symbol("pm.settings.persist_source"),MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH=128,DUPLICATE_DETECTION_MODES=new Set(["off","advisory","strict"]);function resolveGovernanceKnobsFromPreset(preset){return structuredClone(GOVERNANCE_PRESET_DEFAULTS[preset])}function normalizeGovernancePreset(value){return value==="minimal"||value==="default"||value==="strict"||value==="custom"?value:SETTINGS_DEFAULTS.governance.preset}function withGovernanceExtras(base,governance){const createDefaultType=typeof governance.create_default_type=="string"?governance.create_default_type.trim():void 0;return createDefaultType&&createDefaultType.length>0&&(base.create_default_type=createDefaultType),(governance.workflow_enforcement==="off"||governance.workflow_enforcement==="warn"||governance.workflow_enforcement==="strict")&&(base.workflow_enforcement=governance.workflow_enforcement),governance.require_close_reason===!1&&(base.require_close_reason=!1),base.duplicate_detection_mode=governance.duplicate_detection_mode,base.duplicate_detection_threshold=governance.duplicate_detection_threshold,base.duplicate_detection_limit=governance.duplicate_detection_limit,base}function normalizeGovernanceForPersist(governance){return governance.preset==="custom"?withGovernanceExtras({preset:"custom",ownership_enforcement:governance.ownership_enforcement,create_mode_default:governance.create_mode_default,close_validation_default:governance.close_validation_default,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,force_required_for_stale_lock:governance.force_required_for_stale_lock},governance):withGovernanceExtras({preset:governance.preset},governance)}function resolveGovernanceExtras(rawGovernance){const createDefaultType=typeof rawGovernance.create_default_type=="string"?rawGovernance.create_default_type.trim():void 0,extras={};createDefaultType&&createDefaultType.length>0&&(extras.create_default_type=createDefaultType),(rawGovernance.workflow_enforcement==="off"||rawGovernance.workflow_enforcement==="warn"||rawGovernance.workflow_enforcement==="strict")&&(extras.workflow_enforcement=rawGovernance.workflow_enforcement),typeof rawGovernance.require_close_reason=="boolean"&&(extras.require_close_reason=rawGovernance.require_close_reason),DUPLICATE_DETECTION_MODES.has(String(rawGovernance.duplicate_detection_mode))&&(extras.duplicate_detection_mode=rawGovernance.duplicate_detection_mode);const threshold=rawGovernance.duplicate_detection_threshold;[typeof threshold=="number",Number.isFinite(threshold),Number(threshold)>=0,Number(threshold)<=1].every(Boolean)&&(extras.duplicate_detection_threshold=threshold);const limit=rawGovernance.duplicate_detection_limit;return[typeof limit=="number",Number.isSafeInteger(limit),Number(limit)>=0,Number(limit)<=20].every(Boolean)&&(extras.duplicate_detection_limit=limit),extras}function resolveGovernanceKnobs(settings){const rawGovernance=settings.governance??{},preset=normalizeGovernancePreset(rawGovernance.preset),extras=resolveGovernanceExtras(rawGovernance);if(preset==="custom"){const baseline2=resolveGovernanceKnobsFromPreset("default"),requireCloseReason2=extras.require_close_reason??baseline2.require_close_reason;return{preset,ownership_enforcement:rawGovernance.ownership_enforcement??baseline2.ownership_enforcement,create_mode_default:rawGovernance.create_mode_default??baseline2.create_mode_default,close_validation_default:rawGovernance.close_validation_default??baseline2.close_validation_default,parent_reference:rawGovernance.parent_reference??baseline2.parent_reference,metadata_profile:rawGovernance.metadata_profile??baseline2.metadata_profile,force_required_for_stale_lock:rawGovernance.force_required_for_stale_lock??baseline2.force_required_for_stale_lock,...extras,require_close_reason:requireCloseReason2,duplicate_detection_mode:extras.duplicate_detection_mode??baseline2.duplicate_detection_mode,duplicate_detection_threshold:extras.duplicate_detection_threshold??baseline2.duplicate_detection_threshold,duplicate_detection_limit:extras.duplicate_detection_limit??baseline2.duplicate_detection_limit}}const baseline=resolveGovernanceKnobsFromPreset(preset),requireCloseReason=extras.require_close_reason??baseline.require_close_reason;return{preset,...baseline,...extras,require_close_reason:requireCloseReason}}function cloneDefaults(){return structuredClone(SETTINGS_DEFAULTS)}function normalizeSearchMutationRefreshPolicy(value){return value==="cache_only"||value==="semantic_configured"||value==="semantic_auto"?value:SETTINGS_DEFAULTS.search.mutation_refresh_policy}function normalizeSearchDefaultMode(value){return value==="auto"||value==="keyword"||value==="semantic"||value==="hybrid"?value:"auto"}function normalizeSearchQueryExpansionEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.query_expansion.enabled}function normalizeSearchQueryExpansionProvider(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.query_expansion.provider:value.trim()}function normalizeSearchRerankEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.rerank.enabled}function normalizeSearchRerankModel(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.rerank.model:value.trim()}function normalizeSearchRerankTopK(value){return typeof value=="number"&&Number.isFinite(value)&&Number.isInteger(value)&&value>0?value:SETTINGS_DEFAULTS.search.rerank.top_k}function normalizeVectorStoreCollectionName(value){if(typeof value!="string")return SETTINGS_DEFAULTS.vector_store.collection_name;const truncated=value.trim().replaceAll(/[^a-zA-Z0-9_-]/g,"_").slice(0,MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH);return truncated.length>0?truncated:SETTINGS_DEFAULTS.vector_store.collection_name}function cloneOptionalArray(value){return{present:Array.isArray(value),values:Array.isArray(value)?structuredClone(value):[]}}function buildSettingsPersistSourceSnapshot(parsedSettings,runtimeSettings){const sourceSchema=parsedSettings.schema,sourceStatuses=cloneOptionalArray(sourceSchema?.statuses),sourceFields=cloneOptionalArray(sourceSchema?.fields),sourceTypeWorkflows=cloneOptionalArray(sourceSchema?.type_workflows);return{persisted_settings:structuredClone(parsedSettings),source_settings:structuredClone(parsedSettings),has_source_item_type_definitions:Array.isArray(parsedSettings.item_types?.definitions),source_item_type_definitions:normalizeItemTypeDefinitions(parsedSettings.item_types?.definitions),has_source_schema_statuses:sourceStatuses.present,source_schema_statuses:sourceStatuses.values,has_source_schema_fields:sourceFields.present,source_schema_fields:sourceFields.values,has_source_schema_type_workflows:sourceTypeWorkflows.present,source_schema_type_workflows:sourceTypeWorkflows.values,runtime_item_type_definitions:normalizeItemTypeDefinitions(runtimeSettings.item_types?.definitions),runtime_schema_statuses:structuredClone(runtimeSettings.schema.statuses),runtime_schema_fields:structuredClone(runtimeSettings.schema.fields),runtime_schema_type_workflows:structuredClone(runtimeSettings.schema.type_workflows??[])}}function attachSettingsPersistSourceSnapshot(settings,source){Object.defineProperty(settings,SETTINGS_PERSIST_SOURCE_SYMBOL,{value:source,writable:!0,configurable:!0,enumerable:!1})}function getSettingsPersistSourceSnapshot(settings){const candidate=settings[SETTINGS_PERSIST_SOURCE_SYMBOL];if(!(!candidate||typeof candidate!="object"))return candidate}function persistSelectedItemFormat(settings){const source=getSettingsPersistSourceSnapshot(settings);if(source){const detachedSource=structuredClone(source);detachedSource.source_settings.item_format=settings.item_format,attachSettingsPersistSourceSnapshot(settings,detachedSource)}}function cloneSettingsReadResult(result){const clonedSettings=structuredClone(result.settings),persistSource=getSettingsPersistSourceSnapshot(result.settings);return persistSource&&attachSettingsPersistSourceSnapshot(clonedSettings,persistSource),{settings:clonedSettings,metadata:{has_explicit_item_format:result.metadata.has_explicit_item_format},warnings:[...result.warnings]}}function resolveSettingsReadTrackedPaths(pmRoot,schema,settingsPath){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);return[settingsPath,filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types),filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses),filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields),filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows)]}async function cacheSettingsReadResult(pmRoot,trackedPaths,result){const signatures=await collectSettingsReadCacheSignatures(trackedPaths);setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures,value:cloneSettingsReadResult(result)})}async function cacheSettingsReadResultSafe(pmRoot,trackedPaths,result){try{await cacheSettingsReadResult(pmRoot,trackedPaths,result)}catch{clearSettingsReadCache(pmRoot)}}function findSettingsReadCacheSignature(signatures,targetPath){return signatures.find(signature=>signature.path===targetPath)}function selectedSettingsReadCacheSignaturesEqual(before,after,targetPaths){for(const targetPath of targetPaths){const beforeSignature=findSettingsReadCacheSignature(before,targetPath),afterSignature=findSettingsReadCacheSignature(after,targetPath);if(!beforeSignature||!afterSignature||!settingsReadCacheSignaturesEqual([beforeSignature],[afterSignature]))return!1}return!0}async function cacheSettingsReadResultIfStable(pmRoot,trackedPaths,result,stableSignatures,stablePaths){try{const currentSignatures=await collectSettingsReadCacheSignatures(trackedPaths);if(!selectedSettingsReadCacheSignaturesEqual(stableSignatures,currentSignatures,stablePaths)){clearSettingsReadCache(pmRoot);return}setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:currentSignatures,value:cloneSettingsReadResult(result)})}catch{clearSettingsReadCache(pmRoot)}}function resolvePersistedFileBackedSchemaSections(settings,source){const normalizedSchema=normalizeRuntimeSchemaSettings(settings.schema),currentItemTypeDefinitions=normalizeItemTypeDefinitions(settings.item_types?.definitions);if(!source)return{item_type_definitions:currentItemTypeDefinitions,schema_statuses:normalizedSchema.statuses,schema_fields:normalizedSchema.fields,schema_type_workflows:normalizedSchema.type_workflows};const currentTypeWorkflows=normalizedSchema.type_workflows??[],itemTypeDefinitionsUnchanged=stableValueEquals(currentItemTypeDefinitions,source.runtime_item_type_definitions),schemaStatusesUnchanged=stableValueEquals(normalizedSchema.statuses,source.runtime_schema_statuses),schemaFieldsUnchanged=stableValueEquals(normalizedSchema.fields,source.runtime_schema_fields),schemaTypeWorkflowsUnchanged=stableValueEquals(currentTypeWorkflows,source.runtime_schema_type_workflows);return{item_type_definitions:itemTypeDefinitionsUnchanged?source.has_source_item_type_definitions?normalizeItemTypeDefinitions(source.source_item_type_definitions):[]:currentItemTypeDefinitions,schema_statuses:schemaStatusesUnchanged?source.has_source_schema_statuses?structuredClone(source.source_schema_statuses):[]:normalizedSchema.statuses,schema_fields:schemaFieldsUnchanged?source.has_source_schema_fields?structuredClone(source.source_schema_fields):[]:normalizedSchema.fields,schema_type_workflows:schemaTypeWorkflowsUnchanged?source.has_source_schema_type_workflows?structuredClone(source.source_schema_type_workflows):void 0:normalizedSchema.type_workflows}}function buildFallbackSettingsReadResult(warning){return{settings:cloneDefaults(),metadata:{has_explicit_item_format:!1},warnings:warning?[warning]:[]}}function hasExplicitItemFormat(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return!1;const itemFormat=raw.item_format;return itemFormat==="toon"||itemFormat==="json_markdown"}function normalizeStringList(values){return[...new Set((values??[]).map(value=>value.trim()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeAgentGuidanceSettings(value){const defaults=SETTINGS_DEFAULTS.agent_guidance,templateVersion=value?.template_version;return{prompt_completed:value?.prompt_completed===!0,declined:value?.declined===!0,declined_at:typeof value?.declined_at=="string"?value.declined_at:defaults.declined_at,template_version:typeof templateVersion=="number"&&Number.isInteger(templateVersion)&&templateVersion>0?templateVersion:defaults.template_version,last_checked_files:normalizeStringList(value?.last_checked_files??defaults.last_checked_files)}}function normalizeLowerStringList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeExtensionPolicyMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.mode}function normalizeExtensionTrustMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.trust_mode}function normalizeExtensionSandboxProfile(value){return value==="none"||value==="restricted"||value==="strict"?value:SETTINGS_DEFAULTS.extensions.policy.default_sandbox_profile}function normalizeExtensionPolicyOverride(override){const name=override.name.trim().toLowerCase();if(name.length===0)return null;const normalized={name};override.disabled===!0&&(normalized.disabled=!0),override.require_trusted===!0&&(normalized.require_trusted=!0),override.require_provenance===!0&&(normalized.require_provenance=!0),override.sandbox_profile!==void 0&&(normalized.sandbox_profile=normalizeExtensionSandboxProfile(override.sandbox_profile));const allowedCapabilities=normalizeLowerStringList(override.allowed_capabilities),blockedCapabilities=normalizeLowerStringList(override.blocked_capabilities),allowedSurfaces=normalizeLowerStringList(override.allowed_surfaces),blockedSurfaces=normalizeLowerStringList(override.blocked_surfaces),allowedCommands=normalizeLowerStringList(override.allowed_commands),blockedCommands=normalizeLowerStringList(override.blocked_commands),allowedActions=normalizeLowerStringList(override.allowed_actions),blockedActions=normalizeLowerStringList(override.blocked_actions),allowedServices=normalizeLowerStringList(override.allowed_services),blockedServices=normalizeLowerStringList(override.blocked_services);return allowedCapabilities.length>0&&(normalized.allowed_capabilities=allowedCapabilities),blockedCapabilities.length>0&&(normalized.blocked_capabilities=blockedCapabilities),allowedSurfaces.length>0&&(normalized.allowed_surfaces=allowedSurfaces),blockedSurfaces.length>0&&(normalized.blocked_surfaces=blockedSurfaces),allowedCommands.length>0&&(normalized.allowed_commands=allowedCommands),blockedCommands.length>0&&(normalized.blocked_commands=blockedCommands),allowedActions.length>0&&(normalized.allowed_actions=allowedActions),blockedActions.length>0&&(normalized.blocked_actions=blockedActions),allowedServices.length>0&&(normalized.allowed_services=allowedServices),blockedServices.length>0&&(normalized.blocked_services=blockedServices),normalized}function normalizeExtensionPolicyOverrides(overrides){const dedupedByName=new Map;for(const override of overrides??[]){const normalized=normalizeExtensionPolicyOverride(override);normalized&&dedupedByName.set(normalized.name,normalized)}return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function normalizePmMaxVersionExceededModeValue(value){return value==="block"||value==="warn"?value:void 0}function normalizePmMaxVersionExceededModeSetting(value){if(typeof value=="string")return normalizePmMaxVersionExceededModeValue(value);if(typeof value=="object"&&value!==null&&!Array.isArray(value)){const global2=normalizePmMaxVersionExceededModeValue(value.global),project=normalizePmMaxVersionExceededModeValue(value.project);return global2===void 0&&project===void 0?void 0:{...global2!==void 0?{global:global2}:{},...project!==void 0?{project}:{}}}}function normalizeExtensionPolicyList(policy,key){return normalizeLowerStringList(policy?.[key]??SETTINGS_DEFAULTS.extensions.policy[key])}function normalizeExtensionPolicySettings(policy){const pmMaxVersionExceededMode=normalizePmMaxVersionExceededModeSetting(policy?.pm_max_version_exceeded_mode);return{mode:normalizeExtensionPolicyMode(policy?.mode),trust_mode:normalizeExtensionTrustMode(policy?.trust_mode),...pmMaxVersionExceededMode!==void 0?{pm_max_version_exceeded_mode:pmMaxVersionExceededMode}:{},require_provenance:policy?.require_provenance===!0,trusted_extensions:normalizeExtensionPolicyList(policy,"trusted_extensions"),default_sandbox_profile:normalizeExtensionSandboxProfile(policy?.default_sandbox_profile),allowed_extensions:normalizeExtensionPolicyList(policy,"allowed_extensions"),blocked_extensions:normalizeExtensionPolicyList(policy,"blocked_extensions"),allowed_capabilities:normalizeExtensionPolicyList(policy,"allowed_capabilities"),blocked_capabilities:normalizeExtensionPolicyList(policy,"blocked_capabilities"),allowed_surfaces:normalizeExtensionPolicyList(policy,"allowed_surfaces"),blocked_surfaces:normalizeExtensionPolicyList(policy,"blocked_surfaces"),allowed_commands:normalizeExtensionPolicyList(policy,"allowed_commands"),blocked_commands:normalizeExtensionPolicyList(policy,"blocked_commands"),allowed_actions:normalizeExtensionPolicyList(policy,"allowed_actions"),blocked_actions:normalizeExtensionPolicyList(policy,"blocked_actions"),allowed_services:normalizeExtensionPolicyList(policy,"allowed_services"),blocked_services:normalizeExtensionPolicyList(policy,"blocked_services"),extension_overrides:normalizeExtensionPolicyOverrides(policy?.extension_overrides??SETTINGS_DEFAULTS.extensions.policy.extension_overrides)}}function normalizeValidationMetadataRequiredFields(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase().replaceAll("-","_")))].filter(value=>value.length>0).sort((left,right)=>left.localeCompare(right)).filter(value=>["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"].includes(value))}function normalizeValidationPatternList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function valueOrDefault(value,fallback){return value===void 0?fallback:value}function recordOrEmpty(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:{}}function arrayOrEmpty(value){return Array.isArray(value)?value:[]}function buildValidationSettings(settings,defaults,governance){return{...defaults.validation,...settings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(settings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_stale_blocker_reason_patterns??defaults.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_blocked_reason_patterns??defaults.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_resolution_patterns??defaults.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_actual_result_patterns??defaults.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(settings.validation?.estimate_defaults_by_type)}}function buildTelemetrySettings(settings,defaults){return{enabled:settings.telemetry?.enabled??defaults.telemetry.enabled,first_run_prompt_completed:settings.telemetry?.first_run_prompt_completed??defaults.telemetry.first_run_prompt_completed,capture_level:settings.telemetry?.capture_level??defaults.telemetry.capture_level,endpoint:settings.telemetry?.endpoint??defaults.telemetry.endpoint,installation_id:settings.telemetry?.installation_id??defaults.telemetry.installation_id,retention_days:settings.telemetry?.retention_days??defaults.telemetry.retention_days}}function buildSearchSettings(settings,defaults){return{...defaults.search,...settings.search,default_mode:normalizeSearchDefaultMode(settings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(settings.search?.mutation_refresh_policy),query_expansion:{...defaults.search.query_expansion,...settings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(settings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(settings.search?.query_expansion?.provider)},rerank:{...defaults.search.rerank,...settings.search?.rerank,enabled:normalizeSearchRerankEnabled(settings.search?.rerank?.enabled),model:normalizeSearchRerankModel(settings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(settings.search?.rerank?.top_k)}}}function buildVectorStoreSettings(settings,defaults){return{adapter:settings.vector_store.adapter??defaults.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(settings.vector_store.collection_name),qdrant:{...defaults.vector_store.qdrant,...settings.vector_store.qdrant},lancedb:{...defaults.vector_store.lancedb,...settings.vector_store.lancedb}}}function normalizeSettingsItemFormat(settings,defaults){return settings.item_format==="json_markdown"?"toon":settings.item_format??defaults.item_format}function buildContextSettings(settings,defaults){return{default_depth:settings.context?.default_depth??defaults.context.default_depth,activity_limit:settings.context?.activity_limit??defaults.context.activity_limit,stale_threshold_days:settings.context?.stale_threshold_days??defaults.context.stale_threshold_days,sections:{...defaults.context.sections,...settings.context?.sections}}}function buildProviderSettings(settings,defaults){return{openai:{...defaults.providers.openai,...settings.providers.openai},ollama:{...defaults.providers.ollama,...settings.providers.ollama}}}function normalizeItemTypeDefinitions(definitions){const normalized=(definitions??[]).map(definition=>normalizeItemTypeDefinition(definition)).filter(definition=>definition!==null),dedupedByName=new Map;for(const definition of normalized)dedupedByName.set(definition.name.toLowerCase(),definition);return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function mergeSettings(settings){const defaults=cloneDefaults(),governance=resolveGovernanceKnobs({governance:settings.governance??{preset:"default"}});return{...defaults,...settings,item_format:normalizeSettingsItemFormat(settings,defaults),locks:{...defaults.locks,...settings.locks},ids:{...defaults.ids,...settings.ids},agent_identity:structuredClone(settings.agent_identity??defaults.agent_identity),mutation_guard:{...defaults.mutation_guard,...settings.mutation_guard},checkpoints:{...defaults.checkpoints,...settings.checkpoints},output:{...defaults.output,...settings.output},ux:{...defaults.ux,...settings.ux},history:{...defaults.history,...settings.history,compact_policy:{...defaults.history.compact_policy,...settings.history?.compact_policy}},validation:buildValidationSettings(settings,defaults,governance),governance,workflow:{definition_of_done:[...settings.workflow?.definition_of_done??defaults.workflow.definition_of_done]},testing:{record_results_to_items:settings.testing?.record_results_to_items??defaults.testing.record_results_to_items,allow_untrusted_linked_tests:settings.testing?.allow_untrusted_linked_tests??defaults.testing.allow_untrusted_linked_tests},telemetry:buildTelemetrySettings(settings,defaults),agent_guidance:normalizeAgentGuidanceSettings(settings.agent_guidance??defaults.agent_guidance),item_types:{definitions:normalizeItemTypeDefinitions(settings.item_types?.definitions)},schema:normalizeRuntimeSchemaSettings(settings.schema??defaults.schema),context:buildContextSettings(settings,defaults),extensions:{enabled:[...settings.extensions.enabled],disabled:[...settings.extensions.disabled],policy:normalizeExtensionPolicySettings(settings.extensions.policy??defaults.extensions.policy)},search:buildSearchSettings(settings,defaults),providers:buildProviderSettings(settings,defaults),vector_store:buildVectorStoreSettings(settings,defaults)}}function orderSerializedSettingsSections(ordered){ordered.agent_identity=orderObject(ordered.agent_identity,["probes_enabled","identity_vocabulary","harness_signals"]);const orderedAgentIdentity=ordered.agent_identity;Object.hasOwn(orderedAgentIdentity,"identity_vocabulary")&&(orderedAgentIdentity.identity_vocabulary=orderObject(recordOrEmpty(orderedAgentIdentity.identity_vocabulary),["version","aliases"])),ordered.agent_identity.harness_signals=arrayOrEmpty(ordered.agent_identity.harness_signals).map(entry=>orderObject(recordOrEmpty(entry),["harness","environment_keys","model_environment_keys","session_environment_keys","provenance_environment_keys","provenance_resolvers","provenance_unavailable_dimensions","argv_markers","client_names"])),ordered.locks=orderObject(ordered.locks,["ttl_seconds","wait_ms"]),ordered.ids=orderObject(ordered.ids,["token_length"]),ordered.mutation_guard=orderObject(ordered.mutation_guard,["require_attributed_author","secret_guard","stale_in_progress_hours"]),ordered.checkpoints=orderObject(ordered.checkpoints,["retention_days"]),ordered.output=orderObject(ordered.output,["default_format"]),ordered.ux=orderObject(ordered.ux,["deprecation_hints"]),ordered.history=orderObject(ordered.history,["missing_stream","compact_policy"]),ordered.validation=orderObject(ordered.validation,["sprint_release_format","parent_reference","metadata_profile","metadata_required_fields","lifecycle_stale_blocker_reason_patterns","lifecycle_closure_like_blocked_reason_patterns","lifecycle_closure_like_resolution_patterns","lifecycle_closure_like_actual_result_patterns","estimate_defaults_by_type"]),ordered.governance=orderObject(ordered.governance,["preset","ownership_enforcement","create_mode_default","close_validation_default","require_close_reason","parent_reference","metadata_profile","force_required_for_stale_lock","create_default_type","workflow_enforcement","duplicate_detection_mode","duplicate_detection_threshold","duplicate_detection_limit"]),ordered.workflow=orderObject(ordered.workflow,["definition_of_done"]),ordered.testing=orderObject(ordered.testing,["record_results_to_items","allow_untrusted_linked_tests"]),ordered.telemetry=orderObject(ordered.telemetry,["enabled","first_run_prompt_completed","capture_level","endpoint","installation_id","retention_days"]),ordered.agent_guidance=orderObject(ordered.agent_guidance,["prompt_completed","declined","declined_at","template_version","last_checked_files"]),ordered.item_types=orderObject(ordered.item_types,["definitions"]),ordered.schema=orderObject(ordered.schema,["version","files","statuses","fields","workflow","type_workflows","unknown_field_policy"]),ordered.schema.files=orderObject(recordOrEmpty(ordered.schema.files),["types","statuses","fields","workflows"]),ordered.schema.workflow=orderObject(recordOrEmpty(ordered.schema.workflow),["draft_status","open_status","in_progress_status","blocked_status","close_status","canceled_status"]),ordered.context=orderObject(ordered.context,["default_depth","activity_limit","stale_threshold_days","sections"]),ordered.context.sections=orderObject(recordOrEmpty(ordered.context.sections),["hierarchy","activity","progress","blockers","files","workload","staleness","tests"]),ordered.extensions=orderObject(ordered.extensions,["enabled","disabled","policy"]),ordered.extensions.policy=orderObject(recordOrEmpty(ordered.extensions.policy),["mode","trust_mode","pm_max_version_exceeded_mode","require_provenance","trusted_extensions","default_sandbox_profile","allowed_extensions","blocked_extensions","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services","extension_overrides"]),ordered.extensions.policy.extension_overrides=arrayOrEmpty(ordered.extensions.policy.extension_overrides).map(entry=>orderObject(recordOrEmpty(entry),["name","disabled","require_trusted","require_provenance","sandbox_profile","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"])),ordered.search=orderObject(ordered.search,["score_threshold","hybrid_semantic_weight","max_results","embedding_model","embedding_corpus_max_characters","embedding_batch_size","embedding_timeout_ms","scanner_max_batch_retries","provider","default_mode","mutation_refresh_policy","query_expansion","rerank"]),ordered.search.query_expansion=orderObject(recordOrEmpty(ordered.search.query_expansion),["enabled","provider"]),ordered.search.rerank=orderObject(recordOrEmpty(ordered.search.rerank),["enabled","model","top_k"]),ordered.providers=orderObject(ordered.providers,["openai","ollama"]),ordered.providers.openai=orderObject(recordOrEmpty(ordered.providers.openai),["base_url","api_key","model"]),ordered.providers.ollama=orderObject(recordOrEmpty(ordered.providers.ollama),["base_url","model"]),ordered.vector_store=orderObject(ordered.vector_store,["adapter","collection_name","qdrant","lancedb"]),ordered.vector_store.qdrant=orderObject(recordOrEmpty(ordered.vector_store.qdrant),["url","api_key"]),ordered.vector_store.lancedb=orderObject(recordOrEmpty(ordered.vector_store.lancedb),["path"])}function buildSerializeBaseSettings(settings){return{...settings,locks:valueOrDefault(settings.locks,SETTINGS_DEFAULTS.locks),ids:valueOrDefault(settings.ids,SETTINGS_DEFAULTS.ids),agent_identity:valueOrDefault(settings.agent_identity,SETTINGS_DEFAULTS.agent_identity),mutation_guard:valueOrDefault(settings.mutation_guard,SETTINGS_DEFAULTS.mutation_guard),checkpoints:valueOrDefault(settings.checkpoints,SETTINGS_DEFAULTS.checkpoints),output:valueOrDefault(settings.output,SETTINGS_DEFAULTS.output),ux:valueOrDefault(settings.ux,SETTINGS_DEFAULTS.ux),history:valueOrDefault(settings.history,SETTINGS_DEFAULTS.history),validation:valueOrDefault(settings.validation,SETTINGS_DEFAULTS.validation),workflow:valueOrDefault(settings.workflow,SETTINGS_DEFAULTS.workflow),testing:valueOrDefault(settings.testing,SETTINGS_DEFAULTS.testing),telemetry:valueOrDefault(settings.telemetry,SETTINGS_DEFAULTS.telemetry),agent_guidance:valueOrDefault(settings.agent_guidance,SETTINGS_DEFAULTS.agent_guidance),item_types:valueOrDefault(settings.item_types,SETTINGS_DEFAULTS.item_types),schema:valueOrDefault(settings.schema,SETTINGS_DEFAULTS.schema),context:valueOrDefault(settings.context,SETTINGS_DEFAULTS.context),extensions:valueOrDefault(settings.extensions,SETTINGS_DEFAULTS.extensions),search:valueOrDefault(settings.search,SETTINGS_DEFAULTS.search),providers:valueOrDefault(settings.providers,SETTINGS_DEFAULTS.providers),vector_store:valueOrDefault(settings.vector_store,SETTINGS_DEFAULTS.vector_store)}}function buildSerializedValidationSettings(baseSettings,governance){return{...baseSettings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(baseSettings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_stale_blocker_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_blocked_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_resolution_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_actual_result_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(baseSettings.validation?.estimate_defaults_by_type)}}function buildSerializedSearchSettings(baseSettings){return{...SETTINGS_DEFAULTS.search,...baseSettings.search,default_mode:normalizeSearchDefaultMode(baseSettings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(baseSettings.search?.mutation_refresh_policy),query_expansion:{...SETTINGS_DEFAULTS.search.query_expansion,...baseSettings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(baseSettings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(baseSettings.search?.query_expansion?.provider)},rerank:{...SETTINGS_DEFAULTS.search.rerank,...baseSettings.search?.rerank,enabled:normalizeSearchRerankEnabled(baseSettings.search?.rerank?.enabled),model:normalizeSearchRerankModel(baseSettings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(baseSettings.search?.rerank?.top_k)}}}function buildSerializedContextSettings(baseSettings){return{default_depth:baseSettings.context?.default_depth??SETTINGS_DEFAULTS.context.default_depth,activity_limit:baseSettings.context?.activity_limit??SETTINGS_DEFAULTS.context.activity_limit,stale_threshold_days:baseSettings.context?.stale_threshold_days??SETTINGS_DEFAULTS.context.stale_threshold_days,sections:{...SETTINGS_DEFAULTS.context.sections,...baseSettings.context?.sections}}}function buildSerializedVectorStoreSettings(baseSettings){return{...baseSettings.vector_store,adapter:baseSettings.vector_store?.adapter??SETTINGS_DEFAULTS.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(baseSettings.vector_store?.collection_name),qdrant:{...baseSettings.vector_store?.qdrant},lancedb:{...baseSettings.vector_store?.lancedb}}}function buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections){return{...baseSettings,item_format:"toon",validation:buildSerializedValidationSettings(baseSettings,governance),governance,agent_guidance:normalizeAgentGuidanceSettings(baseSettings.agent_guidance),item_types:{definitions:persistedFileBackedSections.item_type_definitions},schema:{...normalizedSchema,statuses:persistedFileBackedSections.schema_statuses,fields:persistedFileBackedSections.schema_fields,type_workflows:persistedFileBackedSections.schema_type_workflows},search:buildSerializedSearchSettings(baseSettings),context:buildSerializedContextSettings(baseSettings),extensions:{enabled:normalizeStringList(baseSettings.extensions?.enabled),disabled:normalizeStringList(baseSettings.extensions?.disabled),policy:normalizeExtensionPolicySettings(baseSettings.extensions?.policy)},vector_store:buildSerializedVectorStoreSettings(baseSettings)}}function overlayPresentSettingsSource(target,source){for(const key of Object.keys(source)){const value=Reflect.get(source,key),existing=target[key];typeof value=="object"&&value!==null&&!Array.isArray(value)&&typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?overlayPresentSettingsSource(existing,value):target[key]=structuredClone(value)}}function applySettingsDelta(target,baseline,current){const keys=new Set([...Object.keys(baseline),...Object.keys(current)]);for(const key of keys){const before=baseline[key],after=current[key];if(!stableValueEquals(before,after)){if(after===void 0){delete target[key];continue}if(typeof before=="object"&&before!==null&&!Array.isArray(before)&&typeof after=="object"&&after!==null&&!Array.isArray(after)){const existing=target[key],nestedTarget=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?existing:{};applySettingsDelta(nestedTarget,before,after),Object.keys(nestedTarget).length>0?target[key]=nestedTarget:delete target[key];continue}target[key]=structuredClone(after)}}}const SETTINGS_TOP_LEVEL_KEY_ORDER=["version","id_prefix","ids","author_default","agent_identity","mutation_guard","item_format","locks","checkpoints","output","ux","history","validation","governance","workflow","testing","telemetry","agent_guidance","item_types","schema","context","extensions","search","providers","vector_store"];function buildOrderedSettingsForSerialization(settings,persistSource){const baseSettings=buildSerializeBaseSettings(settings),governance=resolveGovernanceKnobs(baseSettings),normalizedSchema=normalizeRuntimeSchemaSettings(baseSettings.schema),persistedFileBackedSections=resolvePersistedFileBackedSchemaSections(baseSettings,persistSource),normalizedSettings=buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections),ordered=orderObject({...normalizedSettings,governance:normalizeGovernanceForPersist(governance)},SETTINGS_TOP_LEVEL_KEY_ORDER);return orderSerializedSettingsSections(ordered),ordered}function serializeSettings(settings,options={}){const persistSource=options.source===void 0?options.persist_source:buildSettingsPersistSourceSnapshot(options.source.validated,mergeSettings(options.source.validated)),ordered=buildOrderedSettingsForSerialization(settings,persistSource);if(persistSource){const baselineSettings=mergeSettings(persistSource.source_settings);baselineSettings.item_types={definitions:structuredClone(persistSource.runtime_item_type_definitions)},baselineSettings.schema={...baselineSettings.schema,statuses:structuredClone(persistSource.runtime_schema_statuses),fields:structuredClone(persistSource.runtime_schema_fields),type_workflows:structuredClone(persistSource.runtime_schema_type_workflows)};const baseline=buildOrderedSettingsForSerialization(baselineSettings,persistSource);options.source!==void 0&&overlayPresentSettingsSource(baseline,options.source.validated);const sparse=structuredClone(options.source===void 0?persistSource.source_settings:options.source.raw);return applySettingsDelta(sparse,baseline,ordered),`${JSON.stringify(orderObject(sparse,SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0caecc9d-687a-5b36-b19c-2f2a9c7a1a8a")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{lstat,realpath}from"node:fs/promises";import path from"node:path";import{validateSettings}from"./settings-validator.js";import{runActiveOnReadHooks,runActiveOnWriteHooks}from"../extensions/index.js";import{EXIT_CODE,GOVERNANCE_PRESET_DEFAULTS,SETTINGS_DEFAULTS}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{resolveAuthor}from"../shared/author.js";import{isFileAbsentError,readFileIfExists,readRegularFile,transactionPreviewNonRegularFileError}from"../fs/fs-utils.js";import{mutateWorkspaceJsonWithHistory}from"../history/workspace-history.js";import{reconcileSettingsSnapshot}from"./settings-concurrency.js";import{DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,ensureRuntimeSchemaFileScaffold,filePathForSchemaSection,loadRuntimeSchemaFromOptionalFiles,normalizeRuntimeSchemaSettings}from"../schema/runtime-schema.js";import{getSettingsPath}from"./paths.js";import{orderObject,stableValueEquals}from"../shared/serialization.js";import{normalizeItemTypeDefinition}from"../item/item-type-definition.js";import{normalizeEstimateDefaultOverrides}from"../validate/estimate-defaults.js";import{clearSettingsReadCache,collectSettingsReadCacheSignatures,getSettingsReadCacheEntry,setSettingsReadCacheEntry,settingsReadCacheSignaturesEqual}from"./settings-read-cache.js";const configurationOnlySettingsRoots=new AsyncLocalStorage;async function runWithConfigurationOnlySettings(pmRoot,run,isEnabled=()=>!0){const roots=new Set([path.resolve(pmRoot)]);try{roots.add(await realpath(pmRoot))}catch{}return configurationOnlySettingsRoots.run([...configurationOnlySettingsRoots.getStore()??[],[roots,isEnabled]],run)}function isConfigurationOnlySettingsRead(pmRoot){const root=path.resolve(pmRoot);return configurationOnlySettingsRoots.getStore()?.some(([roots,isEnabled])=>roots.has(root)&&isEnabled())??!1}const SETTINGS_WRITE_OP="settings:write",SETTINGS_PERSIST_SOURCE_SYMBOL=Symbol("pm.settings.persist_source"),MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH=128,DUPLICATE_DETECTION_MODES=new Set(["off","advisory","strict"]);function resolveGovernanceKnobsFromPreset(preset){return structuredClone(GOVERNANCE_PRESET_DEFAULTS[preset])}function normalizeGovernancePreset(value){return value==="minimal"||value==="default"||value==="strict"||value==="custom"?value:SETTINGS_DEFAULTS.governance.preset}function withGovernanceExtras(base,governance){const createDefaultType=typeof governance.create_default_type=="string"?governance.create_default_type.trim():void 0;return createDefaultType&&createDefaultType.length>0&&(base.create_default_type=createDefaultType),(governance.workflow_enforcement==="off"||governance.workflow_enforcement==="warn"||governance.workflow_enforcement==="strict")&&(base.workflow_enforcement=governance.workflow_enforcement),governance.require_close_reason===!1&&(base.require_close_reason=!1),base.duplicate_detection_mode=governance.duplicate_detection_mode,base.duplicate_detection_threshold=governance.duplicate_detection_threshold,base.duplicate_detection_limit=governance.duplicate_detection_limit,base}function normalizeGovernanceForPersist(governance){return governance.preset==="custom"?withGovernanceExtras({preset:"custom",ownership_enforcement:governance.ownership_enforcement,create_mode_default:governance.create_mode_default,close_validation_default:governance.close_validation_default,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,force_required_for_stale_lock:governance.force_required_for_stale_lock},governance):withGovernanceExtras({preset:governance.preset},governance)}function resolveGovernanceExtras(rawGovernance){const createDefaultType=typeof rawGovernance.create_default_type=="string"?rawGovernance.create_default_type.trim():void 0,extras={};createDefaultType&&createDefaultType.length>0&&(extras.create_default_type=createDefaultType),(rawGovernance.workflow_enforcement==="off"||rawGovernance.workflow_enforcement==="warn"||rawGovernance.workflow_enforcement==="strict")&&(extras.workflow_enforcement=rawGovernance.workflow_enforcement),typeof rawGovernance.require_close_reason=="boolean"&&(extras.require_close_reason=rawGovernance.require_close_reason),DUPLICATE_DETECTION_MODES.has(String(rawGovernance.duplicate_detection_mode))&&(extras.duplicate_detection_mode=rawGovernance.duplicate_detection_mode);const threshold=rawGovernance.duplicate_detection_threshold;[typeof threshold=="number",Number.isFinite(threshold),Number(threshold)>=0,Number(threshold)<=1].every(Boolean)&&(extras.duplicate_detection_threshold=threshold);const limit=rawGovernance.duplicate_detection_limit;return[typeof limit=="number",Number.isSafeInteger(limit),Number(limit)>=0,Number(limit)<=20].every(Boolean)&&(extras.duplicate_detection_limit=limit),extras}function resolveGovernanceKnobs(settings){const rawGovernance=settings.governance??{},preset=normalizeGovernancePreset(rawGovernance.preset),extras=resolveGovernanceExtras(rawGovernance);if(preset==="custom"){const baseline2=resolveGovernanceKnobsFromPreset("default"),requireCloseReason2=extras.require_close_reason??baseline2.require_close_reason;return{preset,ownership_enforcement:rawGovernance.ownership_enforcement??baseline2.ownership_enforcement,create_mode_default:rawGovernance.create_mode_default??baseline2.create_mode_default,close_validation_default:rawGovernance.close_validation_default??baseline2.close_validation_default,parent_reference:rawGovernance.parent_reference??baseline2.parent_reference,metadata_profile:rawGovernance.metadata_profile??baseline2.metadata_profile,force_required_for_stale_lock:rawGovernance.force_required_for_stale_lock??baseline2.force_required_for_stale_lock,...extras,require_close_reason:requireCloseReason2,duplicate_detection_mode:extras.duplicate_detection_mode??baseline2.duplicate_detection_mode,duplicate_detection_threshold:extras.duplicate_detection_threshold??baseline2.duplicate_detection_threshold,duplicate_detection_limit:extras.duplicate_detection_limit??baseline2.duplicate_detection_limit}}const baseline=resolveGovernanceKnobsFromPreset(preset),requireCloseReason=extras.require_close_reason??baseline.require_close_reason;return{preset,...baseline,...extras,require_close_reason:requireCloseReason}}function cloneDefaults(){return structuredClone(SETTINGS_DEFAULTS)}function normalizeSearchMutationRefreshPolicy(value){return value==="cache_only"||value==="semantic_configured"||value==="semantic_auto"?value:SETTINGS_DEFAULTS.search.mutation_refresh_policy}function normalizeSearchDefaultMode(value){return value==="auto"||value==="keyword"||value==="semantic"||value==="hybrid"?value:"auto"}function normalizeSearchQueryExpansionEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.query_expansion.enabled}function normalizeSearchQueryExpansionProvider(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.query_expansion.provider:value.trim()}function normalizeSearchRerankEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.rerank.enabled}function normalizeSearchRerankModel(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.rerank.model:value.trim()}function normalizeSearchRerankTopK(value){return typeof value=="number"&&Number.isFinite(value)&&Number.isInteger(value)&&value>0?value:SETTINGS_DEFAULTS.search.rerank.top_k}function normalizeVectorStoreCollectionName(value){if(typeof value!="string")return SETTINGS_DEFAULTS.vector_store.collection_name;const truncated=value.trim().replaceAll(/[^a-zA-Z0-9_-]/g,"_").slice(0,MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH);return truncated.length>0?truncated:SETTINGS_DEFAULTS.vector_store.collection_name}function cloneOptionalArray(value){return{present:Array.isArray(value),values:Array.isArray(value)?structuredClone(value):[]}}function buildSettingsPersistSourceSnapshot(parsedSettings,runtimeSettings){const sourceSchema=parsedSettings.schema,sourceStatuses=cloneOptionalArray(sourceSchema?.statuses),sourceFields=cloneOptionalArray(sourceSchema?.fields),sourceTypeWorkflows=cloneOptionalArray(sourceSchema?.type_workflows);return{persisted_settings:structuredClone(parsedSettings),source_settings:structuredClone(parsedSettings),has_source_item_type_definitions:Array.isArray(parsedSettings.item_types?.definitions),source_item_type_definitions:normalizeItemTypeDefinitions(parsedSettings.item_types?.definitions),has_source_schema_statuses:sourceStatuses.present,source_schema_statuses:sourceStatuses.values,has_source_schema_fields:sourceFields.present,source_schema_fields:sourceFields.values,has_source_schema_type_workflows:sourceTypeWorkflows.present,source_schema_type_workflows:sourceTypeWorkflows.values,runtime_item_type_definitions:normalizeItemTypeDefinitions(runtimeSettings.item_types?.definitions),runtime_schema_statuses:structuredClone(runtimeSettings.schema.statuses),runtime_schema_fields:structuredClone(runtimeSettings.schema.fields),runtime_schema_type_workflows:structuredClone(runtimeSettings.schema.type_workflows??[])}}function attachSettingsPersistSourceSnapshot(settings,source){Object.defineProperty(settings,SETTINGS_PERSIST_SOURCE_SYMBOL,{value:source,writable:!0,configurable:!0,enumerable:!1})}function getSettingsPersistSourceSnapshot(settings){const candidate=settings[SETTINGS_PERSIST_SOURCE_SYMBOL];if(!(!candidate||typeof candidate!="object"))return candidate}function persistSelectedItemFormat(settings){const source=getSettingsPersistSourceSnapshot(settings);if(source){const detachedSource=structuredClone(source);detachedSource.source_settings.item_format=settings.item_format,attachSettingsPersistSourceSnapshot(settings,detachedSource)}}function cloneSettingsReadResult(result){const clonedSettings=structuredClone(result.settings),persistSource=getSettingsPersistSourceSnapshot(result.settings);return persistSource&&attachSettingsPersistSourceSnapshot(clonedSettings,persistSource),{settings:clonedSettings,metadata:{has_explicit_item_format:result.metadata.has_explicit_item_format},warnings:[...result.warnings]}}function resolveSettingsReadTrackedPaths(pmRoot,schema,settingsPath){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);return[settingsPath,filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types),filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses),filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields),filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows)]}async function cacheSettingsReadResult(pmRoot,trackedPaths,result){const signatures=await collectSettingsReadCacheSignatures(trackedPaths);setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures,value:cloneSettingsReadResult(result)})}async function cacheSettingsReadResultSafe(pmRoot,trackedPaths,result){try{await cacheSettingsReadResult(pmRoot,trackedPaths,result)}catch{clearSettingsReadCache(pmRoot)}}function findSettingsReadCacheSignature(signatures,targetPath){return signatures.find(signature=>signature.path===targetPath)}function selectedSettingsReadCacheSignaturesEqual(before,after,targetPaths){for(const targetPath of targetPaths){const beforeSignature=findSettingsReadCacheSignature(before,targetPath),afterSignature=findSettingsReadCacheSignature(after,targetPath);if(!beforeSignature||!afterSignature||!settingsReadCacheSignaturesEqual([beforeSignature],[afterSignature]))return!1}return!0}async function cacheSettingsReadResultIfStable(pmRoot,trackedPaths,result,stableSignatures,stablePaths){try{const currentSignatures=await collectSettingsReadCacheSignatures(trackedPaths);if(!selectedSettingsReadCacheSignaturesEqual(stableSignatures,currentSignatures,stablePaths)){clearSettingsReadCache(pmRoot);return}setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:currentSignatures,value:cloneSettingsReadResult(result)})}catch{clearSettingsReadCache(pmRoot)}}function resolvePersistedFileBackedSchemaSections(settings,source){const normalizedSchema=normalizeRuntimeSchemaSettings(settings.schema),currentItemTypeDefinitions=normalizeItemTypeDefinitions(settings.item_types?.definitions);if(!source)return{item_type_definitions:currentItemTypeDefinitions,schema_statuses:normalizedSchema.statuses,schema_fields:normalizedSchema.fields,schema_type_workflows:normalizedSchema.type_workflows};const currentTypeWorkflows=normalizedSchema.type_workflows??[],itemTypeDefinitionsUnchanged=stableValueEquals(currentItemTypeDefinitions,source.runtime_item_type_definitions),schemaStatusesUnchanged=stableValueEquals(normalizedSchema.statuses,source.runtime_schema_statuses),schemaFieldsUnchanged=stableValueEquals(normalizedSchema.fields,source.runtime_schema_fields),schemaTypeWorkflowsUnchanged=stableValueEquals(currentTypeWorkflows,source.runtime_schema_type_workflows);return{item_type_definitions:itemTypeDefinitionsUnchanged?source.has_source_item_type_definitions?normalizeItemTypeDefinitions(source.source_item_type_definitions):[]:currentItemTypeDefinitions,schema_statuses:schemaStatusesUnchanged?source.has_source_schema_statuses?structuredClone(source.source_schema_statuses):[]:normalizedSchema.statuses,schema_fields:schemaFieldsUnchanged?source.has_source_schema_fields?structuredClone(source.source_schema_fields):[]:normalizedSchema.fields,schema_type_workflows:schemaTypeWorkflowsUnchanged?source.has_source_schema_type_workflows?structuredClone(source.source_schema_type_workflows):void 0:normalizedSchema.type_workflows}}function buildFallbackSettingsReadResult(warning){return{settings:cloneDefaults(),metadata:{has_explicit_item_format:!1},warnings:warning?[warning]:[]}}function hasExplicitItemFormat(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return!1;const itemFormat=raw.item_format;return itemFormat==="toon"||itemFormat==="json_markdown"}function normalizeStringList(values){return[...new Set((values??[]).map(value=>value.trim()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeAgentGuidanceSettings(value){const defaults=SETTINGS_DEFAULTS.agent_guidance,templateVersion=value?.template_version;return{prompt_completed:value?.prompt_completed===!0,declined:value?.declined===!0,declined_at:typeof value?.declined_at=="string"?value.declined_at:defaults.declined_at,template_version:typeof templateVersion=="number"&&Number.isInteger(templateVersion)&&templateVersion>0?templateVersion:defaults.template_version,last_checked_files:normalizeStringList(value?.last_checked_files??defaults.last_checked_files)}}function normalizeLowerStringList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeExtensionPolicyMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.mode}function normalizeExtensionTrustMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.trust_mode}function normalizeExtensionSandboxProfile(value){return value==="none"||value==="restricted"||value==="strict"?value:SETTINGS_DEFAULTS.extensions.policy.default_sandbox_profile}function normalizeExtensionPolicyOverride(override){const name=override.name.trim().toLowerCase();if(name.length===0)return null;const normalized={name};override.disabled===!0&&(normalized.disabled=!0),override.require_trusted===!0&&(normalized.require_trusted=!0),override.require_provenance===!0&&(normalized.require_provenance=!0),override.sandbox_profile!==void 0&&(normalized.sandbox_profile=normalizeExtensionSandboxProfile(override.sandbox_profile));const allowedCapabilities=normalizeLowerStringList(override.allowed_capabilities),blockedCapabilities=normalizeLowerStringList(override.blocked_capabilities),allowedSurfaces=normalizeLowerStringList(override.allowed_surfaces),blockedSurfaces=normalizeLowerStringList(override.blocked_surfaces),allowedCommands=normalizeLowerStringList(override.allowed_commands),blockedCommands=normalizeLowerStringList(override.blocked_commands),allowedActions=normalizeLowerStringList(override.allowed_actions),blockedActions=normalizeLowerStringList(override.blocked_actions),allowedServices=normalizeLowerStringList(override.allowed_services),blockedServices=normalizeLowerStringList(override.blocked_services);return allowedCapabilities.length>0&&(normalized.allowed_capabilities=allowedCapabilities),blockedCapabilities.length>0&&(normalized.blocked_capabilities=blockedCapabilities),allowedSurfaces.length>0&&(normalized.allowed_surfaces=allowedSurfaces),blockedSurfaces.length>0&&(normalized.blocked_surfaces=blockedSurfaces),allowedCommands.length>0&&(normalized.allowed_commands=allowedCommands),blockedCommands.length>0&&(normalized.blocked_commands=blockedCommands),allowedActions.length>0&&(normalized.allowed_actions=allowedActions),blockedActions.length>0&&(normalized.blocked_actions=blockedActions),allowedServices.length>0&&(normalized.allowed_services=allowedServices),blockedServices.length>0&&(normalized.blocked_services=blockedServices),normalized}function normalizeExtensionPolicyOverrides(overrides){const dedupedByName=new Map;for(const override of overrides??[]){const normalized=normalizeExtensionPolicyOverride(override);normalized&&dedupedByName.set(normalized.name,normalized)}return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function normalizePmMaxVersionExceededModeValue(value){return value==="block"||value==="warn"?value:void 0}function normalizePmMaxVersionExceededModeSetting(value){if(typeof value=="string")return normalizePmMaxVersionExceededModeValue(value);if(typeof value=="object"&&value!==null&&!Array.isArray(value)){const global2=normalizePmMaxVersionExceededModeValue(value.global),project=normalizePmMaxVersionExceededModeValue(value.project);return global2===void 0&&project===void 0?void 0:{...global2!==void 0?{global:global2}:{},...project!==void 0?{project}:{}}}}function normalizeExtensionPolicyList(policy,key){return normalizeLowerStringList(policy?.[key]??SETTINGS_DEFAULTS.extensions.policy[key])}function normalizeExtensionPolicySettings(policy){const pmMaxVersionExceededMode=normalizePmMaxVersionExceededModeSetting(policy?.pm_max_version_exceeded_mode);return{mode:normalizeExtensionPolicyMode(policy?.mode),trust_mode:normalizeExtensionTrustMode(policy?.trust_mode),...pmMaxVersionExceededMode!==void 0?{pm_max_version_exceeded_mode:pmMaxVersionExceededMode}:{},require_provenance:policy?.require_provenance===!0,trusted_extensions:normalizeExtensionPolicyList(policy,"trusted_extensions"),default_sandbox_profile:normalizeExtensionSandboxProfile(policy?.default_sandbox_profile),allowed_extensions:normalizeExtensionPolicyList(policy,"allowed_extensions"),blocked_extensions:normalizeExtensionPolicyList(policy,"blocked_extensions"),allowed_capabilities:normalizeExtensionPolicyList(policy,"allowed_capabilities"),blocked_capabilities:normalizeExtensionPolicyList(policy,"blocked_capabilities"),allowed_surfaces:normalizeExtensionPolicyList(policy,"allowed_surfaces"),blocked_surfaces:normalizeExtensionPolicyList(policy,"blocked_surfaces"),allowed_commands:normalizeExtensionPolicyList(policy,"allowed_commands"),blocked_commands:normalizeExtensionPolicyList(policy,"blocked_commands"),allowed_actions:normalizeExtensionPolicyList(policy,"allowed_actions"),blocked_actions:normalizeExtensionPolicyList(policy,"blocked_actions"),allowed_services:normalizeExtensionPolicyList(policy,"allowed_services"),blocked_services:normalizeExtensionPolicyList(policy,"blocked_services"),extension_overrides:normalizeExtensionPolicyOverrides(policy?.extension_overrides??SETTINGS_DEFAULTS.extensions.policy.extension_overrides)}}function normalizeValidationMetadataRequiredFields(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase().replaceAll("-","_")))].filter(value=>value.length>0).sort((left,right)=>left.localeCompare(right)).filter(value=>["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"].includes(value))}function normalizeValidationPatternList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function valueOrDefault(value,fallback){return value===void 0?fallback:value}function recordOrEmpty(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:{}}function arrayOrEmpty(value){return Array.isArray(value)?value:[]}function buildValidationSettings(settings,defaults,governance){return{...defaults.validation,...settings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(settings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_stale_blocker_reason_patterns??defaults.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_blocked_reason_patterns??defaults.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_resolution_patterns??defaults.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_actual_result_patterns??defaults.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(settings.validation?.estimate_defaults_by_type)}}function buildTelemetrySettings(settings,defaults){return{enabled:settings.telemetry?.enabled??defaults.telemetry.enabled,first_run_prompt_completed:settings.telemetry?.first_run_prompt_completed??defaults.telemetry.first_run_prompt_completed,capture_level:settings.telemetry?.capture_level??defaults.telemetry.capture_level,endpoint:settings.telemetry?.endpoint??defaults.telemetry.endpoint,installation_id:settings.telemetry?.installation_id??defaults.telemetry.installation_id,retention_days:settings.telemetry?.retention_days??defaults.telemetry.retention_days}}function buildSearchSettings(settings,defaults){return{...defaults.search,...settings.search,default_mode:normalizeSearchDefaultMode(settings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(settings.search?.mutation_refresh_policy),query_expansion:{...defaults.search.query_expansion,...settings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(settings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(settings.search?.query_expansion?.provider)},rerank:{...defaults.search.rerank,...settings.search?.rerank,enabled:normalizeSearchRerankEnabled(settings.search?.rerank?.enabled),model:normalizeSearchRerankModel(settings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(settings.search?.rerank?.top_k)}}}function buildVectorStoreSettings(settings,defaults){return{adapter:settings.vector_store.adapter??defaults.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(settings.vector_store.collection_name),qdrant:{...defaults.vector_store.qdrant,...settings.vector_store.qdrant},lancedb:{...defaults.vector_store.lancedb,...settings.vector_store.lancedb}}}function normalizeSettingsItemFormat(settings,defaults){return settings.item_format==="json_markdown"?"toon":settings.item_format??defaults.item_format}function buildContextSettings(settings,defaults){return{default_depth:settings.context?.default_depth??defaults.context.default_depth,activity_limit:settings.context?.activity_limit??defaults.context.activity_limit,stale_threshold_days:settings.context?.stale_threshold_days??defaults.context.stale_threshold_days,sections:{...defaults.context.sections,...settings.context?.sections}}}function buildProviderSettings(settings,defaults){return{openai:{...defaults.providers.openai,...settings.providers.openai},ollama:{...defaults.providers.ollama,...settings.providers.ollama}}}function normalizeItemTypeDefinitions(definitions){const normalized=(definitions??[]).map(definition=>normalizeItemTypeDefinition(definition)).filter(definition=>definition!==null),dedupedByName=new Map;for(const definition of normalized)dedupedByName.set(definition.name.toLowerCase(),definition);return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function mergeSettings(settings){const defaults=cloneDefaults(),governance=resolveGovernanceKnobs({governance:settings.governance??{preset:"default"}});return{...defaults,...settings,item_format:normalizeSettingsItemFormat(settings,defaults),locks:{...defaults.locks,...settings.locks},ids:{...defaults.ids,...settings.ids},agent_identity:structuredClone(settings.agent_identity??defaults.agent_identity),mutation_guard:{...defaults.mutation_guard,...settings.mutation_guard},checkpoints:{...defaults.checkpoints,...settings.checkpoints},output:{...defaults.output,...settings.output},ux:{...defaults.ux,...settings.ux},history:{...defaults.history,...settings.history,compact_policy:{...defaults.history.compact_policy,...settings.history?.compact_policy}},validation:buildValidationSettings(settings,defaults,governance),governance,workflow:{definition_of_done:[...settings.workflow?.definition_of_done??defaults.workflow.definition_of_done]},testing:{record_results_to_items:settings.testing?.record_results_to_items??defaults.testing.record_results_to_items,allow_untrusted_linked_tests:settings.testing?.allow_untrusted_linked_tests??defaults.testing.allow_untrusted_linked_tests},telemetry:buildTelemetrySettings(settings,defaults),agent_guidance:normalizeAgentGuidanceSettings(settings.agent_guidance??defaults.agent_guidance),item_types:{definitions:normalizeItemTypeDefinitions(settings.item_types?.definitions)},schema:normalizeRuntimeSchemaSettings(settings.schema??defaults.schema),context:buildContextSettings(settings,defaults),extensions:{enabled:[...settings.extensions.enabled],disabled:[...settings.extensions.disabled],policy:normalizeExtensionPolicySettings(settings.extensions.policy??defaults.extensions.policy)},search:buildSearchSettings(settings,defaults),providers:buildProviderSettings(settings,defaults),vector_store:buildVectorStoreSettings(settings,defaults)}}function orderSerializedSettingsSections(ordered){ordered.agent_identity=orderObject(ordered.agent_identity,["probes_enabled","identity_vocabulary","harness_signals"]);const orderedAgentIdentity=ordered.agent_identity;Object.hasOwn(orderedAgentIdentity,"identity_vocabulary")&&(orderedAgentIdentity.identity_vocabulary=orderObject(recordOrEmpty(orderedAgentIdentity.identity_vocabulary),["version","aliases"])),ordered.agent_identity.harness_signals=arrayOrEmpty(ordered.agent_identity.harness_signals).map(entry=>orderObject(recordOrEmpty(entry),["harness","environment_keys","model_environment_keys","session_environment_keys","provenance_environment_keys","provenance_resolvers","provenance_unavailable_dimensions","argv_markers","client_names"])),ordered.locks=orderObject(ordered.locks,["ttl_seconds","wait_ms"]),ordered.ids=orderObject(ordered.ids,["token_length"]),ordered.mutation_guard=orderObject(ordered.mutation_guard,["require_attributed_author","secret_guard","stale_in_progress_hours"]),ordered.checkpoints=orderObject(ordered.checkpoints,["retention_days"]),ordered.output=orderObject(ordered.output,["default_format"]),ordered.ux=orderObject(ordered.ux,["deprecation_hints"]),ordered.history=orderObject(ordered.history,["missing_stream","compact_policy"]),ordered.validation=orderObject(ordered.validation,["sprint_release_format","parent_reference","metadata_profile","metadata_required_fields","lifecycle_stale_blocker_reason_patterns","lifecycle_closure_like_blocked_reason_patterns","lifecycle_closure_like_resolution_patterns","lifecycle_closure_like_actual_result_patterns","estimate_defaults_by_type"]),ordered.governance=orderObject(ordered.governance,["preset","ownership_enforcement","create_mode_default","close_validation_default","require_close_reason","parent_reference","metadata_profile","force_required_for_stale_lock","create_default_type","workflow_enforcement","duplicate_detection_mode","duplicate_detection_threshold","duplicate_detection_limit"]),ordered.workflow=orderObject(ordered.workflow,["definition_of_done"]),ordered.testing=orderObject(ordered.testing,["record_results_to_items","allow_untrusted_linked_tests"]),ordered.telemetry=orderObject(ordered.telemetry,["enabled","first_run_prompt_completed","capture_level","endpoint","installation_id","retention_days"]),ordered.agent_guidance=orderObject(ordered.agent_guidance,["prompt_completed","declined","declined_at","template_version","last_checked_files"]),ordered.item_types=orderObject(ordered.item_types,["definitions"]),ordered.schema=orderObject(ordered.schema,["version","files","statuses","fields","workflow","type_workflows","unknown_field_policy"]),ordered.schema.files=orderObject(recordOrEmpty(ordered.schema.files),["types","statuses","fields","workflows"]),ordered.schema.workflow=orderObject(recordOrEmpty(ordered.schema.workflow),["draft_status","open_status","in_progress_status","blocked_status","close_status","canceled_status"]),ordered.context=orderObject(ordered.context,["default_depth","activity_limit","stale_threshold_days","sections"]),ordered.context.sections=orderObject(recordOrEmpty(ordered.context.sections),["hierarchy","activity","progress","blockers","files","workload","staleness","tests"]),ordered.extensions=orderObject(ordered.extensions,["enabled","disabled","policy"]),ordered.extensions.policy=orderObject(recordOrEmpty(ordered.extensions.policy),["mode","trust_mode","pm_max_version_exceeded_mode","require_provenance","trusted_extensions","default_sandbox_profile","allowed_extensions","blocked_extensions","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services","extension_overrides"]),ordered.extensions.policy.extension_overrides=arrayOrEmpty(ordered.extensions.policy.extension_overrides).map(entry=>orderObject(recordOrEmpty(entry),["name","disabled","require_trusted","require_provenance","sandbox_profile","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"])),ordered.search=orderObject(ordered.search,["score_threshold","hybrid_semantic_weight","max_results","embedding_model","embedding_corpus_max_characters","embedding_batch_size","embedding_timeout_ms","scanner_max_batch_retries","provider","default_mode","mutation_refresh_policy","query_expansion","rerank"]),ordered.search.query_expansion=orderObject(recordOrEmpty(ordered.search.query_expansion),["enabled","provider"]),ordered.search.rerank=orderObject(recordOrEmpty(ordered.search.rerank),["enabled","model","top_k"]),ordered.providers=orderObject(ordered.providers,["openai","ollama"]),ordered.providers.openai=orderObject(recordOrEmpty(ordered.providers.openai),["base_url","api_key","model"]),ordered.providers.ollama=orderObject(recordOrEmpty(ordered.providers.ollama),["base_url","model"]),ordered.vector_store=orderObject(ordered.vector_store,["adapter","collection_name","qdrant","lancedb"]),ordered.vector_store.qdrant=orderObject(recordOrEmpty(ordered.vector_store.qdrant),["url","api_key"]),ordered.vector_store.lancedb=orderObject(recordOrEmpty(ordered.vector_store.lancedb),["path"])}function buildSerializeBaseSettings(settings){return{...settings,locks:valueOrDefault(settings.locks,SETTINGS_DEFAULTS.locks),ids:valueOrDefault(settings.ids,SETTINGS_DEFAULTS.ids),agent_identity:valueOrDefault(settings.agent_identity,SETTINGS_DEFAULTS.agent_identity),mutation_guard:valueOrDefault(settings.mutation_guard,SETTINGS_DEFAULTS.mutation_guard),checkpoints:valueOrDefault(settings.checkpoints,SETTINGS_DEFAULTS.checkpoints),output:valueOrDefault(settings.output,SETTINGS_DEFAULTS.output),ux:valueOrDefault(settings.ux,SETTINGS_DEFAULTS.ux),history:valueOrDefault(settings.history,SETTINGS_DEFAULTS.history),validation:valueOrDefault(settings.validation,SETTINGS_DEFAULTS.validation),workflow:valueOrDefault(settings.workflow,SETTINGS_DEFAULTS.workflow),testing:valueOrDefault(settings.testing,SETTINGS_DEFAULTS.testing),telemetry:valueOrDefault(settings.telemetry,SETTINGS_DEFAULTS.telemetry),agent_guidance:valueOrDefault(settings.agent_guidance,SETTINGS_DEFAULTS.agent_guidance),item_types:valueOrDefault(settings.item_types,SETTINGS_DEFAULTS.item_types),schema:valueOrDefault(settings.schema,SETTINGS_DEFAULTS.schema),context:valueOrDefault(settings.context,SETTINGS_DEFAULTS.context),extensions:valueOrDefault(settings.extensions,SETTINGS_DEFAULTS.extensions),search:valueOrDefault(settings.search,SETTINGS_DEFAULTS.search),providers:valueOrDefault(settings.providers,SETTINGS_DEFAULTS.providers),vector_store:valueOrDefault(settings.vector_store,SETTINGS_DEFAULTS.vector_store)}}function buildSerializedValidationSettings(baseSettings,governance){return{...baseSettings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(baseSettings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_stale_blocker_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_blocked_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_resolution_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_actual_result_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(baseSettings.validation?.estimate_defaults_by_type)}}function buildSerializedSearchSettings(baseSettings){return{...SETTINGS_DEFAULTS.search,...baseSettings.search,default_mode:normalizeSearchDefaultMode(baseSettings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(baseSettings.search?.mutation_refresh_policy),query_expansion:{...SETTINGS_DEFAULTS.search.query_expansion,...baseSettings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(baseSettings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(baseSettings.search?.query_expansion?.provider)},rerank:{...SETTINGS_DEFAULTS.search.rerank,...baseSettings.search?.rerank,enabled:normalizeSearchRerankEnabled(baseSettings.search?.rerank?.enabled),model:normalizeSearchRerankModel(baseSettings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(baseSettings.search?.rerank?.top_k)}}}function buildSerializedContextSettings(baseSettings){return{default_depth:baseSettings.context?.default_depth??SETTINGS_DEFAULTS.context.default_depth,activity_limit:baseSettings.context?.activity_limit??SETTINGS_DEFAULTS.context.activity_limit,stale_threshold_days:baseSettings.context?.stale_threshold_days??SETTINGS_DEFAULTS.context.stale_threshold_days,sections:{...SETTINGS_DEFAULTS.context.sections,...baseSettings.context?.sections}}}function buildSerializedVectorStoreSettings(baseSettings){return{...baseSettings.vector_store,adapter:baseSettings.vector_store?.adapter??SETTINGS_DEFAULTS.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(baseSettings.vector_store?.collection_name),qdrant:{...baseSettings.vector_store?.qdrant},lancedb:{...baseSettings.vector_store?.lancedb}}}function buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections){return{...baseSettings,item_format:"toon",validation:buildSerializedValidationSettings(baseSettings,governance),governance,agent_guidance:normalizeAgentGuidanceSettings(baseSettings.agent_guidance),item_types:{definitions:persistedFileBackedSections.item_type_definitions},schema:{...normalizedSchema,statuses:persistedFileBackedSections.schema_statuses,fields:persistedFileBackedSections.schema_fields,type_workflows:persistedFileBackedSections.schema_type_workflows},search:buildSerializedSearchSettings(baseSettings),context:buildSerializedContextSettings(baseSettings),extensions:{enabled:normalizeStringList(baseSettings.extensions?.enabled),disabled:normalizeStringList(baseSettings.extensions?.disabled),policy:normalizeExtensionPolicySettings(baseSettings.extensions?.policy)},vector_store:buildSerializedVectorStoreSettings(baseSettings)}}function overlayPresentSettingsSource(target,source){for(const key of Object.keys(source)){const value=Reflect.get(source,key),existing=target[key];typeof value=="object"&&value!==null&&!Array.isArray(value)&&typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?overlayPresentSettingsSource(existing,value):target[key]=structuredClone(value)}}function applySettingsDelta(target,baseline,current){const keys=new Set([...Object.keys(baseline),...Object.keys(current)]);for(const key of keys){const before=baseline[key],after=current[key];if(!stableValueEquals(before,after)){if(after===void 0){delete target[key];continue}if(typeof before=="object"&&before!==null&&!Array.isArray(before)&&typeof after=="object"&&after!==null&&!Array.isArray(after)){const existing=target[key],nestedTarget=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?existing:{};applySettingsDelta(nestedTarget,before,after),Object.keys(nestedTarget).length>0?target[key]=nestedTarget:delete target[key];continue}target[key]=structuredClone(after)}}}const SETTINGS_TOP_LEVEL_KEY_ORDER=["version","id_prefix","ids","author_default","agent_identity","mutation_guard","item_format","locks","checkpoints","output","ux","history","validation","governance","workflow","testing","telemetry","agent_guidance","item_types","schema","context","extensions","search","providers","vector_store"];function buildOrderedSettingsForSerialization(settings,persistSource){const baseSettings=buildSerializeBaseSettings(settings),governance=resolveGovernanceKnobs(baseSettings),normalizedSchema=normalizeRuntimeSchemaSettings(baseSettings.schema),persistedFileBackedSections=resolvePersistedFileBackedSchemaSections(baseSettings,persistSource),normalizedSettings=buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections),ordered=orderObject({...normalizedSettings,governance:normalizeGovernanceForPersist(governance)},SETTINGS_TOP_LEVEL_KEY_ORDER);return orderSerializedSettingsSections(ordered),ordered}function serializeSettings(settings,options={}){const persistSource=options.source===void 0?options.persist_source:buildSettingsPersistSourceSnapshot(options.source.validated,mergeSettings(options.source.validated)),ordered=buildOrderedSettingsForSerialization(settings,persistSource);if(persistSource){const baselineSettings=mergeSettings(persistSource.source_settings);baselineSettings.item_types={definitions:structuredClone(persistSource.runtime_item_type_definitions)},baselineSettings.schema={...baselineSettings.schema,statuses:structuredClone(persistSource.runtime_schema_statuses),fields:structuredClone(persistSource.runtime_schema_fields),type_workflows:structuredClone(persistSource.runtime_schema_type_workflows)};const baseline=buildOrderedSettingsForSerialization(baselineSettings,persistSource);options.source!==void 0&&overlayPresentSettingsSource(baseline,options.source.validated);const sparse=structuredClone(options.source===void 0?persistSource.source_settings:options.source.raw);return applySettingsDelta(sparse,baseline,ordered),`${JSON.stringify(orderObject(sparse,SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
|
|
2
2
|
`}return`${JSON.stringify(ordered,null,2)}
|
|
3
|
-
`}async function readConfigurationOnlySettings(pmRoot){let root;try{root=await realpath(pmRoot)}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}const file=getSettingsPath(root);let entry;try{entry=await lstat(file)}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}if(!entry.isFile())throw transactionPreviewNonRegularFileError();let raw;try{raw=await readRegularFile(file,transactionPreviewNonRegularFileError())}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}let parsed;try{parsed=JSON.parse(raw)}catch{return buildFallbackSettingsReadResult("settings_read_invalid_json")}const validated=validateSettings(parsed);return validated.success?{settings:mergeSettings(validated.data),metadata:{has_explicit_item_format:hasExplicitItemFormat(parsed)},warnings:validated.data.item_format==="json_markdown"?["settings_item_format_legacy_json_markdown_coerced_to_toon"]:[]}:buildFallbackSettingsReadResult("settings_read_invalid_schema")}async function readSettingsWithMetadata(pmRoot){if(isConfigurationOnlySettingsRead(pmRoot))return readConfigurationOnlySettings(pmRoot);const settingsPath=getSettingsPath(pmRoot);let trackedPathsForFailure=[settingsPath];await runActiveOnReadHooks({path:settingsPath,scope:"project"});const cachedResult=getSettingsReadCacheEntry(pmRoot);if(cachedResult){const currentSignatures=await collectSettingsReadCacheSignatures(cachedResult.tracked_paths);if(settingsReadCacheSignaturesEqual(currentSignatures,cachedResult.signatures))return cloneSettingsReadResult(cachedResult.value)}const settingsOnlySignatures=await collectSettingsReadCacheSignatures([settingsPath]);let raw;try{raw=await readFileIfExists(settingsPath)}catch{return buildFallbackSettingsReadResult("settings_read_fs_error")}if(raw===null){const fallback=buildFallbackSettingsReadResult();return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsOnlySignatures,[settingsPath]),fallback}const settingsSignaturesAfterRead=await collectSettingsReadCacheSignatures([settingsPath]);if(!settingsReadCacheSignaturesEqual(settingsOnlySignatures,settingsSignaturesAfterRead))return clearSettingsReadCache(pmRoot),readSettingsWithMetadata(pmRoot);let parsed;try{parsed=JSON.parse(raw)}catch{const fallback=buildFallbackSettingsReadResult("settings_read_invalid_json");return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsSignaturesAfterRead,[settingsPath]),fallback}const validated=validateSettings(parsed);if(!validated.success){const fallback=buildFallbackSettingsReadResult("settings_read_invalid_schema");return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsSignaturesAfterRead,[settingsPath]),fallback}try{const mergedSettings=mergeSettings(validated.data),trackedPaths=resolveSettingsReadTrackedPaths(pmRoot,mergedSettings.schema,settingsPath);trackedPathsForFailure=trackedPaths;const signaturesBeforeSchemaLoad=await collectSettingsReadCacheSignatures(trackedPaths),schemaScaffold=await ensureRuntimeSchemaFileScaffold(pmRoot,mergedSettings.schema),loadedSchemaSections=await loadRuntimeSchemaFromOptionalFiles(pmRoot,mergedSettings.schema),signaturesAfterSchemaLoad=await collectSettingsReadCacheSignatures(trackedPaths),settings={...mergedSettings,item_types:{definitions:normalizeItemTypeDefinitions([...mergedSettings.item_types.definitions,...arrayOrEmpty(loadedSchemaSections.type_definitions_from_file)])},schema:loadedSchemaSections.schema};attachSettingsPersistSourceSnapshot(settings,buildSettingsPersistSourceSnapshot(validated.data,settings));const result={settings,metadata:{has_explicit_item_format:hasExplicitItemFormat(parsed)},warnings:[...validated.data.item_format==="json_markdown"?["settings_item_format_legacy_json_markdown_coerced_to_toon"]:[],...schemaScaffold.created_paths.map(createdPath=>`runtime_schema_bootstrap_created:${createdPath}`),...loadedSchemaSections.warnings]};return schemaScaffold.created_paths.length===0?settingsReadCacheSignaturesEqual(signaturesBeforeSchemaLoad,signaturesAfterSchemaLoad)?setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:signaturesAfterSchemaLoad,value:cloneSettingsReadResult(result)}):clearSettingsReadCache(pmRoot):clearSettingsReadCache(pmRoot),result}catch{const fallback=buildFallbackSettingsReadResult("settings_read_merge_failed");return await cacheSettingsReadResultSafe(pmRoot,trackedPathsForFailure,fallback),fallback}}async function readSettings(pmRoot){return(await readSettingsWithMetadata(pmRoot)).settings}async function writeSettings(pmRoot,settings,op=SETTINGS_WRITE_OP){const settingsPath=getSettingsPath(pmRoot),source=getSettingsPersistSourceSnapshot(settings),afterRaw=serializeSettings(settings,{persist_source:source}),proposed=JSON.parse(afterRaw);try{await mutateWorkspaceJsonWithHistory({pmRoot,filePath:settingsPath,mutate:beforeRaw=>{let current=null;if(beforeRaw!==null)try{current=JSON.parse(beforeRaw)}catch{throw new PmCliError("Existing settings.json is malformed; the settings write was refused.",EXIT_CODE.USAGE,{code:"settings_write_invalid_existing_json",reason:"existing_settings_json_malformed",why:"Writing defaults over malformed settings could destroy intended project configuration.",nextSteps:["Repair the syntax in .agents/pm/settings.json, then retry the original command.","Run pm health to confirm the settings warning has cleared."]})}return{raw:source?`${JSON.stringify(orderObject(reconcileSettingsSnapshot(source.persisted_settings,proposed,current),SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
|
|
3
|
+
`}async function readConfigurationOnlySettings(pmRoot){let root;try{root=await realpath(pmRoot)}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}const file=getSettingsPath(root);let entry;try{entry=await lstat(file)}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}if(!entry.isFile())throw transactionPreviewNonRegularFileError("settings.json");let raw;try{raw=await readRegularFile(file,transactionPreviewNonRegularFileError("settings.json"))}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}let parsed;try{parsed=JSON.parse(raw)}catch{return buildFallbackSettingsReadResult("settings_read_invalid_json")}const validated=validateSettings(parsed);return validated.success?{settings:mergeSettings(validated.data),metadata:{has_explicit_item_format:hasExplicitItemFormat(parsed)},warnings:validated.data.item_format==="json_markdown"?["settings_item_format_legacy_json_markdown_coerced_to_toon"]:[]}:buildFallbackSettingsReadResult("settings_read_invalid_schema")}async function readSettingsWithMetadata(pmRoot){if(isConfigurationOnlySettingsRead(pmRoot))return readConfigurationOnlySettings(pmRoot);const settingsPath=getSettingsPath(pmRoot);let trackedPathsForFailure=[settingsPath];await runActiveOnReadHooks({path:settingsPath,scope:"project"});const cachedResult=getSettingsReadCacheEntry(pmRoot);if(cachedResult){const currentSignatures=await collectSettingsReadCacheSignatures(cachedResult.tracked_paths);if(settingsReadCacheSignaturesEqual(currentSignatures,cachedResult.signatures))return cloneSettingsReadResult(cachedResult.value)}const settingsOnlySignatures=await collectSettingsReadCacheSignatures([settingsPath]);let raw;try{raw=await readFileIfExists(settingsPath)}catch{return buildFallbackSettingsReadResult("settings_read_fs_error")}if(raw===null){const fallback=buildFallbackSettingsReadResult();return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsOnlySignatures,[settingsPath]),fallback}const settingsSignaturesAfterRead=await collectSettingsReadCacheSignatures([settingsPath]);if(!settingsReadCacheSignaturesEqual(settingsOnlySignatures,settingsSignaturesAfterRead))return clearSettingsReadCache(pmRoot),readSettingsWithMetadata(pmRoot);let parsed;try{parsed=JSON.parse(raw)}catch{const fallback=buildFallbackSettingsReadResult("settings_read_invalid_json");return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsSignaturesAfterRead,[settingsPath]),fallback}const validated=validateSettings(parsed);if(!validated.success){const fallback=buildFallbackSettingsReadResult("settings_read_invalid_schema");return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsSignaturesAfterRead,[settingsPath]),fallback}try{const mergedSettings=mergeSettings(validated.data),trackedPaths=resolveSettingsReadTrackedPaths(pmRoot,mergedSettings.schema,settingsPath);trackedPathsForFailure=trackedPaths;const signaturesBeforeSchemaLoad=await collectSettingsReadCacheSignatures(trackedPaths),schemaScaffold=await ensureRuntimeSchemaFileScaffold(pmRoot,mergedSettings.schema),loadedSchemaSections=await loadRuntimeSchemaFromOptionalFiles(pmRoot,mergedSettings.schema),signaturesAfterSchemaLoad=await collectSettingsReadCacheSignatures(trackedPaths),settings={...mergedSettings,item_types:{definitions:normalizeItemTypeDefinitions([...mergedSettings.item_types.definitions,...arrayOrEmpty(loadedSchemaSections.type_definitions_from_file)])},schema:loadedSchemaSections.schema};attachSettingsPersistSourceSnapshot(settings,buildSettingsPersistSourceSnapshot(validated.data,settings));const result={settings,metadata:{has_explicit_item_format:hasExplicitItemFormat(parsed)},warnings:[...validated.data.item_format==="json_markdown"?["settings_item_format_legacy_json_markdown_coerced_to_toon"]:[],...schemaScaffold.created_paths.map(createdPath=>`runtime_schema_bootstrap_created:${createdPath}`),...loadedSchemaSections.warnings]};return schemaScaffold.created_paths.length===0?settingsReadCacheSignaturesEqual(signaturesBeforeSchemaLoad,signaturesAfterSchemaLoad)?setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:signaturesAfterSchemaLoad,value:cloneSettingsReadResult(result)}):clearSettingsReadCache(pmRoot):clearSettingsReadCache(pmRoot),result}catch{const fallback=buildFallbackSettingsReadResult("settings_read_merge_failed");return await cacheSettingsReadResultSafe(pmRoot,trackedPathsForFailure,fallback),fallback}}async function readSettings(pmRoot){return(await readSettingsWithMetadata(pmRoot)).settings}async function writeSettings(pmRoot,settings,op=SETTINGS_WRITE_OP){const settingsPath=getSettingsPath(pmRoot),source=getSettingsPersistSourceSnapshot(settings),afterRaw=serializeSettings(settings,{persist_source:source}),proposed=JSON.parse(afterRaw);try{await mutateWorkspaceJsonWithHistory({pmRoot,filePath:settingsPath,mutate:beforeRaw=>{let current=null;if(beforeRaw!==null)try{current=JSON.parse(beforeRaw)}catch{throw new PmCliError("Existing settings.json is malformed; the settings write was refused.",EXIT_CODE.USAGE,{code:"settings_write_invalid_existing_json",reason:"existing_settings_json_malformed",why:"Writing defaults over malformed settings could destroy intended project configuration.",nextSteps:["Repair the syntax in .agents/pm/settings.json, then retry the original command.","Run pm health to confirm the settings warning has cleared."]})}return{raw:source?`${JSON.stringify(orderObject(reconcileSettingsSnapshot(source.persisted_settings,proposed,current),SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
|
|
4
4
|
`:afterRaw,result:void 0}},op,author:resolveAuthor(void 0,settings.author_default),lockTtlSeconds:settings.locks.ttl_seconds,lockWaitMs:settings.locks.wait_ms,recordCreation:!1}),source&&attachSettingsPersistSourceSnapshot(settings,{...source,persisted_settings:structuredClone(proposed)}),await runActiveOnWriteHooks({path:settingsPath,scope:"project",op})}finally{clearSettingsReadCache(pmRoot)}}const settingsStoreTestOnly={applySettingsDelta,hasExplicitItemFormat,buildSettingsPersistSourceSnapshot,cacheSettingsReadResultIfStable,cacheSettingsReadResultSafe,mergeSettings,normalizeExtensionPolicySettings,normalizeExtensionPolicyOverride,normalizeExtensionPolicyOverrides,normalizeExtensionPolicyMode,normalizePmMaxVersionExceededModeSetting,normalizeExtensionSandboxProfile,normalizeExtensionTrustMode,normalizeLowerStringList,normalizeStringList,valueOrDefault,arrayOrEmpty,normalizeValidationPatternList,normalizeValidationMetadataRequiredFields,resolveSettingsReadTrackedPaths,resolvePersistedFileBackedSchemaSections,selectedSettingsReadCacheSignaturesEqual};export{isConfigurationOnlySettingsRead,mergeSettings,normalizeItemTypeDefinitions,persistSelectedItemFormat,readSettings,readSettingsWithMetadata,resolveGovernanceKnobs,runWithConfigurationOnlySettings,serializeSettings,settingsStoreTestOnly,writeSettings};
|
|
5
5
|
//# sourceMappingURL=settings.js.map
|