@unbrained/pm-cli 2026.9.17 → 2026.9.19
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 +2 -2
- package/CHANGELOG.md +49 -0
- package/dist/cli/invocation-profile.d.ts +26 -0
- package/dist/cli/invocation-profile.js +3 -0
- package/dist/cli/register-operations.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +149 -149
- package/dist/cli-bundle/chunks/{chunk-LD2FH2YE.js → chunk-7CN53F4S.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-AACGU5IA.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-Q6KPZGMP.js → chunk-CCLWCESZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-T526C5DX.js → chunk-J7NP7QLW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UF75LUAK.js → chunk-K4VAU4HU.js} +63 -63
- package/dist/cli-bundle/chunks/chunk-KHN4NMKT.js +238 -0
- package/dist/cli-bundle/chunks/{chunk-YZXB4XGA.js → chunk-KYG2QKNY.js} +29 -29
- package/dist/cli-bundle/chunks/{chunk-CPFBDM53.js → chunk-OQS2Y6VN.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-G2IJF244.js → chunk-QA4GUEKJ.js} +20 -20
- package/dist/cli-bundle/chunks/chunk-QTHR3LXF.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-5ZY4WE3F.js → chunk-RVMDPIGD.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-WASMH647.js +8 -0
- package/dist/cli-bundle/chunks/{register-list-query-ISM35VIX.js → register-list-query-RMZNHSII.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-KHMBJJS6.js → register-mutation-HJGSGX3H.js} +2 -2
- package/dist/cli-bundle/chunks/register-operations-LBEMFUMM.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-YAURJMY5.js → register-setup-MU557JAA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-G4TKJZ4A.js → chunk-5SZ4JSPZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-NOK652OP.js → chunk-7Y7PAC56.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5KYHDFDN.js → chunk-ARK4FIO4.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-LNM3BS45.js → chunk-CJ4QA4RW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-I32L3FWW.js +12 -0
- package/dist/cli-bundle/focused-chunks/{chunk-267N774W.js → chunk-I4WDON3K.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-7ZC4CKOX.js → chunk-IKPR4VVN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-J3GN4SQT.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-GKSAMNBG.js → chunk-OOZHQFBF.js} +16 -16
- package/dist/cli-bundle/focused-chunks/{chunk-JZSLDLR4.js → chunk-P4BA7OX7.js} +27 -26
- package/dist/cli-bundle/focused-chunks/chunk-QL4MO5M2.js +30 -0
- package/dist/cli-bundle/focused-chunks/chunk-TDHVROGL.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-V3YMNAO7.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-YDFEWXXZ.js +59 -0
- package/dist/cli-bundle/focused-chunks/{chunk-WUMGGQYN.js → chunk-ZDBKYZFE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-BFUXTNZU.js → chunk-ZI2YBJFH.js} +2 -2
- package/dist/cli-bundle/main.js +2 -2
- 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 +25 -25
- 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 +41 -41
- 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/cli.js +1 -1
- package/dist/core/checkpoint/mutation-checkpoint.d.ts +1 -1
- package/dist/core/checkpoint/mutation-checkpoint.js +2 -2
- package/dist/core/config/nested-settings.js +1 -1
- package/dist/core/fs/atomic-create.d.ts +7 -0
- package/dist/core/fs/atomic-create.js +2 -0
- package/dist/core/history/history.js +1 -1
- package/dist/core/schema/runtime-schema.d.ts +1 -1
- package/dist/core/schema/runtime-schema.js +2 -2
- package/dist/core/session/session-state.js +1 -1
- package/dist/core/shared/secret-rules.d.ts +110 -0
- package/dist/core/shared/secret-rules.js +2 -0
- package/dist/core/store/settings-concurrency.d.ts +7 -0
- package/dist/core/store/settings-concurrency.js +2 -0
- package/dist/core/store/settings.d.ts +8 -1
- package/dist/core/store/settings.js +3 -2
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.js +1 -1
- package/dist/sdk/cli-contracts/command-aliases.js +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
- package/dist/sdk/cli-program.js +1 -1
- package/dist/sdk/context-intent-contracts.js +1 -1
- package/dist/sdk/context-relevance.js +1 -1
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +1 -1
- package/dist/sdk/extension/install-runtime.d.ts +1 -1
- package/dist/sdk/extension/install-runtime.js +2 -2
- package/dist/sdk/governance/health.js +1 -1
- package/dist/sdk/governance/provenance-health.d.ts +27 -0
- package/dist/sdk/governance/provenance-health.js +1 -1
- package/dist/sdk/graph/index.d.ts +1 -0
- package/dist/sdk/graph/index.js +1 -1
- package/dist/sdk/graph/query-contracts.d.ts +18 -0
- package/dist/sdk/graph/query-contracts.js +2 -0
- package/dist/sdk/graph/run.d.ts +2 -0
- package/dist/sdk/graph/run.js +1 -1
- package/dist/sdk/graph/traversal.js +1 -1
- package/dist/sdk/guide-topics.js +1 -1
- package/dist/sdk/lifecycle/event-validation-messages.d.ts +1 -1
- package/dist/sdk/lifecycle/event-validation-messages.js +1 -1
- package/dist/sdk/lifecycle-policy.js +1 -1
- package/dist/sdk/mutation-guard.d.ts +8 -1
- package/dist/sdk/mutation-guard.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/next-ready-budget.d.ts +20 -0
- package/dist/sdk/query/next-ready-budget.js +2 -0
- package/dist/sdk/query/next.d.ts +7 -2
- package/dist/sdk/query/next.js +1 -1
- package/dist/sdk/read-output-budget.d.ts +3 -1
- package/dist/sdk/read-output-budget.js +1 -1
- package/dist/sdk/read-output-contracts.js +1 -1
- package/dist/sdk/read-output-session.js +1 -1
- package/dist/sdk/test/execution.d.ts +6 -5
- package/dist/sdk/test/execution.js +2 -2
- package/dist/sdk/test/json-path.d.ts +11 -0
- package/dist/sdk/test/json-path.js +2 -0
- package/docs/BUILD_AND_RELEASE_ACCEPTANCE.md +66 -0
- package/docs/MCP_OPTION_CONFORMANCE.md +41 -0
- package/docs/MUTATION_INTEGRITY.md +36 -4
- package/docs/NEXT_SELECTION_BUDGETS.md +93 -0
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +18 -2
- package/docs/PACKED_FIRST_RUN.md +8 -4
- package/docs/PERFORMANCE.md +37 -0
- package/docs/README.md +2 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +8 -4
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +28 -4
- package/docs/SDK_LIFECYCLE.md +16 -2
- package/docs/WORKSPACE_CONCURRENCY.md +67 -0
- package/docs/agent-task-token-baseline.json +7 -7
- package/docs/generated/AGENT_CAPABILITY_ROUTING.md +1 -1
- package/docs/generated/AGENT_COMMAND_SURFACE.md +3 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +3 -0
- package/marketplace.json +2 -2
- package/package.json +11 -9
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/README.md +43 -2
- package/packages/pm-calendar/extensions/calendar/command-definitions.ts +52 -0
- package/packages/pm-calendar/extensions/calendar/index.ts +2 -0
- package/packages/pm-calendar/extensions/calendar/manifest.json +3 -3
- package/packages/pm-calendar/extensions/calendar/shortcuts.ts +15 -0
- 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-codex/.codex-plugin/plugin.json +1 -1
- package/scripts/build-lease.mjs +43 -0
- package/scripts/build.mjs +40 -0
- package/dist/cli-bundle/chunks/chunk-C3MFMGCR.js +0 -20
- package/dist/cli-bundle/chunks/chunk-DN2RIHRN.js +0 -3
- package/dist/cli-bundle/chunks/chunk-E67MIO3Z.js +0 -8
- package/dist/cli-bundle/chunks/chunk-UJSB6NO6.js +0 -237
- package/dist/cli-bundle/chunks/register-operations-HHDROJD6.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-5FSGN4MP.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-7S7XWMXC.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-IVWUQE7T.js +0 -59
- package/dist/cli-bundle/focused-chunks/chunk-OCTTDZOU.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-OWDDVMAP.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-Z4PWEIMX.js +0 -30
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="51825a77-c7de-51ca-aa9e-4362278019ec")}catch(e2){}})();import fs from"node:fs";import*as nodeModule from"node:module";import os from"node:os";import path from"node:path";import{fileURLToPath}from"node:url";import{runCliWithBundleIntegrity}from"./cli/bundle-integrity.js";import{runRuntimeCompatibleCli}from"./cli/runtime-compatibility-boundary.js";import{registerInvocationProfile}from"./cli/invocation-profile.js";import{pruneCompileCacheGenerations,resolveCompileCacheGeneration}from"./sdk/compile-cache.js";function enableNodeCompileCache(){const{enableCompileCache}=nodeModule;if(typeof enableCompileCache!=="function"||process.env.PM_CLI_DISABLE_COMPILE_CACHE==="1"){return}const userCacheKey=typeof process.getuid==="function"?String(process.getuid()):os.userInfo().username.replace(/[^a-zA-Z0-9._-]/g,"_");const configuredCacheDir=process.env.PM_CLI_COMPILE_CACHE_DIR;const defaultCacheRoot=path.join(os.tmpdir(),`pm-cli-node-compile-cache-${userCacheKey}`);const generation=resolveCompileCacheGeneration(readPackageVersionForPath(fileURLToPath(import.meta.url)));const cacheDir=configuredCacheDir??path.join(defaultCacheRoot,generation);try{if(configuredCacheDir===void 0){pruneCompileCacheGenerations(defaultCacheRoot,generation)}enableCompileCache(cacheDir)}catch{}}function findPackageJson(startPath){let current=path.dirname(path.resolve(startPath));while(true){const candidate=path.join(current,"package.json");if(fs.existsSync(candidate)){return candidate}const parent=path.dirname(current);if(parent===current){return void 0}current=parent}}function printFastVersionIfRequested(){const args=process.argv.slice(2);const versionArgs=args.filter(arg=>arg!=="--no-extensions"&&arg!=="--profile");if(versionArgs.length!==1||versionArgs[0]!=="--version"&&versionArgs[0]!=="-V"){return false}const version=readPackageVersionForPath(fileURLToPath(import.meta.url));if(version===void 0){return false}console.log(version);return true}function readPackageVersionForPath(startPath){const packageJsonPath=findPackageJson(startPath);if(!packageJsonPath){return void 0}try{const parsed=JSON.parse(fs.readFileSync(packageJsonPath,"utf8"));if(typeof parsed.version!=="string"){return void 0}return parsed.version}catch{return void 0}}const _testOnly={enableNodeCompileCache,findPackageJson,printFastVersionIfRequested,readPackageVersionForPath};registerInvocationProfile(process.argv.slice(2));if(!printFastVersionIfRequested()){enableNodeCompileCache();const cliEntrypointPath=fileURLToPath(import.meta.url);const executingVersion=readPackageVersionForPath(cliEntrypointPath);const invocationArgv=process.argv.slice(2);await runRuntimeCompatibleCli({executingVersion,projectRoot:process.cwd(),argv:invocationArgv,allowStale:process.env.PM_ALLOW_STALE_CLI==="1",run:()=>runCliWithBundleIntegrity(invocationArgv,cliEntrypointPath,()=>import("./cli-bundle/main.js"),process.stderr.write.bind(process.stderr)),writeError:process.stderr.write.bind(process.stderr)})}export{_testOnly};
|
|
3
3
|
//# sourceMappingURL=cli.js.map
|
|
@@ -55,7 +55,7 @@ export declare function createCheckpointId(prefix: string, nowValue: string): st
|
|
|
55
55
|
export declare function checkpointDirectoryPath(pmRoot: string, subdir: string): string;
|
|
56
56
|
/** Implements checkpoint file path for the public runtime surface of this module. */
|
|
57
57
|
export declare function checkpointFilePath(pmRoot: string, subdir: string, checkpointId: string): string;
|
|
58
|
-
/**
|
|
58
|
+
/** Publish immutable checkpoint bytes once, including through path aliases; identical retries succeed and conflicting IDs preserve the original evidence. */
|
|
59
59
|
export declare function writeMutationCheckpoint(pmRoot: string, subdir: string, checkpointId: string, payload: unknown): Promise<string>;
|
|
60
60
|
/** Implements load mutation checkpoint for the public runtime surface of this module. */
|
|
61
61
|
export declare function loadMutationCheckpoint(pmRoot: string, subdir: string, rawCheckpointId: string, schemaVersion: number): Promise<LoadedMutationCheckpoint>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
-
`)
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="93b04081-a71a-5987-8fb6-09a8d045c1da")}catch(e2){}})();import{readFile}from"node:fs/promises";import path from"node:path";import{pathExists,readFileIfExists}from"../fs/fs-utils.js";import{createFileAtomic}from"../fs/atomic-create.js";import{EXIT_CODE}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{toErrorMessage}from"../shared/primitives.js";import{nowIso}from"../shared/time.js";function normalizeCheckpointId(raw){const trimmed=raw.trim();if(!trimmed){throw new PmCliError("--rollback requires a non-empty checkpoint ID",EXIT_CODE.USAGE)}if(!/^[a-zA-Z0-9._-]+$/.test(trimmed)){throw new PmCliError("--rollback checkpoint ID must match [a-zA-Z0-9._-]+",EXIT_CODE.USAGE)}return trimmed}function createCheckpointId(prefix,nowValue){const compactTimestamp=nowValue.replace(/[-:.TZ]/g,"").slice(0,14);const randomSuffix=Math.random().toString(36).slice(2,8);return`${prefix}-${compactTimestamp}-${randomSuffix}`}function checkpointDirectoryPath(pmRoot,subdir){return path.join(pmRoot,"checkpoints",subdir)}function checkpointFilePath(pmRoot,subdir,checkpointId){return path.join(checkpointDirectoryPath(pmRoot,subdir),`${checkpointId}.json`)}async function writeMutationCheckpoint(pmRoot,subdir,checkpointId,payload){const filePath=checkpointFilePath(pmRoot,subdir,checkpointId);const raw=`${JSON.stringify(payload,null,2)}
|
|
2
|
+
`;if(!await createFileAtomic(filePath,raw)&&await readFileIfExists(filePath)!==raw){throw new PmCliError(`Checkpoint ${checkpointId} already exists with different contents; use a new checkpoint ID.`,EXIT_CODE.CONFLICT)}return filePath}function parseCheckpointItems(record,checkpointId){if(!Array.isArray(record.items)){throw new PmCliError(`Checkpoint ${checkpointId} is missing items`,EXIT_CODE.GENERIC_FAILURE)}return record.items.map(entry=>{if(!entry||typeof entry!=="object"){throw new PmCliError(`Checkpoint ${checkpointId} contains an invalid item entry`,EXIT_CODE.GENERIC_FAILURE)}const row=entry;if(typeof row.id!=="string"||row.id.trim().length===0){throw new PmCliError(`Checkpoint ${checkpointId} contains an item entry without ID`,EXIT_CODE.GENERIC_FAILURE)}if(typeof row.target_updated_at!=="string"||row.target_updated_at.trim().length===0){throw new PmCliError(`Checkpoint ${checkpointId} contains an item entry without target_updated_at`,EXIT_CODE.GENERIC_FAILURE)}return{id:row.id.trim(),target_updated_at:row.target_updated_at.trim()}})}async function loadMutationCheckpoint(pmRoot,subdir,rawCheckpointId,schemaVersion){const normalizedId=normalizeCheckpointId(rawCheckpointId);const filePath=checkpointFilePath(pmRoot,subdir,normalizedId);if(!await pathExists(filePath)){throw new PmCliError(`Checkpoint ${normalizedId} not found`,EXIT_CODE.NOT_FOUND)}const raw=await readFile(filePath,"utf8");let parsed;try{parsed=JSON.parse(raw)}catch(error){throw new PmCliError(`Checkpoint ${normalizedId} contains invalid JSON: ${toErrorMessage(error)}`,EXIT_CODE.GENERIC_FAILURE)}if(!parsed||typeof parsed!=="object"){throw new PmCliError(`Checkpoint ${normalizedId} is invalid`,EXIT_CODE.GENERIC_FAILURE)}const record=parsed;if(record.schema_version!==schemaVersion){throw new PmCliError(`Checkpoint ${normalizedId} has unsupported schema version`,EXIT_CODE.GENERIC_FAILURE)}const items=parseCheckpointItems(record,normalizedId);return{record,items,path:filePath,id:typeof record.id==="string"?record.id:normalizedId,created_at:typeof record.created_at==="string"?record.created_at:nowIso(),author:typeof record.author==="string"?record.author:"unknown"}}async function restoreCheckpointItems(items,restore){const rows=[];const restoredIds=[];for(const entry of items){try{const restored=await restore(entry.id,entry.target_updated_at);rows.push({id:entry.id,status:"restored",changed_fields:restored.changed_fields,warnings:restored.warnings});restoredIds.push(entry.id)}catch(error){rows.push({id:entry.id,status:"failed",error:toErrorMessage(error)})}}return{rows,restored_ids:restoredIds,failed_count:rows.filter(row=>row.status==="failed").length}}export{checkpointDirectoryPath,checkpointFilePath,createCheckpointId,loadMutationCheckpoint,normalizeCheckpointId,restoreCheckpointItems,writeMutationCheckpoint};
|
|
3
3
|
//# sourceMappingURL=mutation-checkpoint.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ae6d96af-b482-5238-af32-20bb7c3753cb")}catch(e2){}})();const NESTED_SETTING_DESCRIPTORS=[{key:"search_provider",path:"search.provider",kind:"string",summary:"Search embedding provider name (e.g. openai, ollama, or an extension provider)."},{key:"search_default_mode",path:"search.default_mode",kind:"string",choices:["auto","keyword","semantic","hybrid"],summary:"Mode a bare pm search runs in: auto (hybrid when semantic search is explicitly configured and runnable, else keyword), or a pinned keyword, semantic, or hybrid."},{key:"search_mutation_refresh_policy",path:"search.mutation_refresh_policy",kind:"string",choices:["cache_only","semantic_configured","semantic_auto"],summary:"Mutation-time search refresh policy: cache_only, semantic_configured, or semantic_auto."},{key:"search_query_expansion_enabled",path:"search.query_expansion.enabled",kind:"boolean",summary:"Enable or disable query expansion for semantic/hybrid search."},{key:"search_query_expansion_provider",path:"search.query_expansion.provider",kind:"string",summary:"Query expansion provider name (built-in openai/ollama or extension provider)."},{key:"search_rerank_enabled",path:"search.rerank.enabled",kind:"boolean",summary:"Enable or disable post-retrieval reranking for hybrid search."},{key:"search_rerank_model",path:"search.rerank.model",kind:"string",summary:"Rerank model name override used by built-in providers."},{key:"search_rerank_top_k",path:"search.rerank.top_k",kind:"integer",min:1,summary:"Number of top hybrid candidates to rerank when rerank is enabled."},{key:"search_embedding_model",path:"search.embedding_model",kind:"string",summary:"Default embedding model name (overrides provider-specific model when set)."},{key:"search_embedding_corpus_max_characters",path:"search.embedding_corpus_max_characters",kind:"integer",min:1,summary:"Maximum semantic corpus characters per item before truncation."},{key:"search_embedding_batch_size",path:"search.embedding_batch_size",kind:"integer",min:1,summary:"Number of items embedded per request batch."},{key:"search_embedding_timeout_ms",path:"search.embedding_timeout_ms",kind:"integer",min:1,summary:"Per-request embedding timeout in milliseconds."},{key:"search_score_threshold",path:"search.score_threshold",kind:"number",summary:"Minimum score for a hit to be returned (0 keeps all matches)."},{key:"search_hybrid_semantic_weight",path:"search.hybrid_semantic_weight",kind:"ratio",summary:"Hybrid mode semantic weight in [0, 1] (1-weight goes to keyword)."},{key:"search_max_results",path:"search.max_results",kind:"integer",min:1,summary:"Default upper bound on search hits when --limit is not supplied."},{key:"search_bm25_k1",path:"search.bm25.k1",kind:"number",min:0,summary:"Offline BM25 term-frequency saturation (k1); higher saturates repeated terms slower (default 1.2)."},{key:"search_bm25_b",path:"search.bm25.b",kind:"ratio",summary:"Offline BM25 document-length normalization (b) in [0, 1]; 0 disables, 1 fully normalizes (default 0.75)."},{key:"openai_base_url",path:"providers.openai.base_url",kind:"string",summary:"OpenAI-compatible API base URL (LM Studio/vLLM also use this)."},{key:"openai_api_key",path:"providers.openai.api_key",kind:"string",summary:"OpenAI-compatible API key."},{key:"openai_model",path:"providers.openai.model",kind:"string",summary:"OpenAI-compatible embedding model name."},{key:"ollama_base_url",path:"providers.ollama.base_url",kind:"string",summary:"Ollama API base URL (typically http://localhost:11434)."},{key:"ollama_model",path:"providers.ollama.model",kind:"string",summary:"Ollama embedding model name (e.g. nomic-embed-text)."},{key:"vector_store_adapter",path:"vector_store.adapter",kind:"string",summary:"Vector store adapter name (lancedb, qdrant, or an extension adapter)."},{key:"vector_store_collection_name",path:"vector_store.collection_name",kind:"string",non_empty:true,summary:"Vector collection/table name shared by Qdrant and LanceDB adapters."},{key:"qdrant_url",path:"vector_store.qdrant.url",kind:"string",summary:"Qdrant HTTP API URL."},{key:"qdrant_api_key",path:"vector_store.qdrant.api_key",kind:"string",summary:"Qdrant API key (empty if running unauthenticated)."},{key:"lancedb_path",path:"vector_store.lancedb.path",kind:"string",summary:"LanceDB storage path (relative to pm root or absolute)."},{key:"id_prefix",path:"id_prefix",kind:"string",non_empty:true,summary:'Prefix for generated item IDs (e.g. "pm" produces pm-xxxx).'},{key:"author_default",path:"author_default",kind:"string",non_empty:true,summary:"Default author recorded on mutations when --author is not supplied."},{key:"agent_identity_probes_enabled",path:"agent_identity.probes_enabled",kind:"boolean",summary:"Allow privacy-bounded local harness provenance probes; no network or subprocess access is permitted."},{key:"mutation_guard_require_attributed_author",path:"mutation_guard.require_attributed_author",kind:"boolean",summary:"Reject mutations whose effective author resolves to unknown."},{key:"mutation_guard_secret_guard",path:"mutation_guard.secret_guard",kind:"string",choices:["off","advise","block"],summary:"Detect credential-shaped mutation content: off, advise, or block."},{key:"mutation_guard_stale_in_progress_hours",path:"mutation_guard.stale_in_progress_hours",kind:"integer",min:1,summary:"Age threshold for unclaimed in-progress work surfaced by health."},{key:"governance_duplicate_detection_mode",path:"governance.duplicate_detection_mode",kind:"string",choices:["off","advisory","strict"],summary:"Create/copy duplicate governance: off, advisory, or strict explicit-bypass enforcement."},{key:"governance_duplicate_detection_threshold",path:"governance.duplicate_detection_threshold",kind:"ratio",summary:"Minimum shared similarity score in [0, 1] for create/copy duplicate governance."},{key:"governance_duplicate_detection_limit",path:"governance.duplicate_detection_limit",kind:"integer",min:0,max:20,summary:"Maximum likely duplicates returned by create/copy governance (0-20)."},{key:"output_default_format",path:"output.default_format",kind:"string",choices:["toon","json"],summary:"Default output format for commands that support it: toon or json."},{key:"ux_deprecation_hints",path:"ux.deprecation_hints",kind:"boolean",summary:"Emit one stderr migration hint for deprecated command aliases."},{key:"locks_ttl_seconds",path:"locks.ttl_seconds",kind:"integer",min:1,summary:"Claim/lock time-to-live in seconds before a stale lock can be reclaimed."},{key:"locks_wait_ms",path:"locks.wait_ms",kind:"integer",min:0,summary:"Bounded jittered wait in milliseconds before a contended item mutation fails with lock_conflict; 0 fails fast. PM_LOCK_WAIT_MS overrides per invocation."},{key:"ids_token_length",path:"ids.token_length",kind:"integer",min:4,max:12,summary:"Random base36 token length for newly minted item ids (4-12, default 4). Raise it to shrink cross-branch id collision odds in concurrent multi-agent workflows (pm-pibw)."},{key:"checkpoints_retention_days",path:"checkpoints.retention_days",kind:"integer",min:1,summary:"Age in days above which pm gc --scope checkpoints prunes bulk-mutation rollback checkpoints."},{key:"schema_unknown_field_policy",path:"schema.unknown_field_policy",kind:"string",choices:["allow","warn","reject"],summary:"How item I/O handles metadata keys not in the field registry: allow, warn, or reject."},{key:"history_compact_policy_enabled",path:"history.compact_policy.enabled",kind:"boolean",summary:"Enable the history-compaction advisory: pm health warns on over-threshold streams."},{key:"history_compact_policy_max_entries",path:"history.compact_policy.max_entries",kind:"integer",min:1,summary:"Entry count above which a history stream is flagged (and the default pm history-compact --all-over threshold)."},{key:"history_compact_policy_trigger",path:"history.compact_policy.trigger",kind:"string",choices:["health_warn","auto"],summary:"History-compaction policy intent: health_warn (advisory only) or auto (scheduled sweeps expected)."}];const DESCRIPTOR_BY_KEY=new Map(NESTED_SETTING_DESCRIPTORS.flatMap(descriptor=>[[descriptor.key,descriptor],[descriptor.path.toLowerCase().replaceAll("-","_"),descriptor]]));function resolveNestedSettingDescriptor(raw){if(typeof raw!=="string"){return void 0}const normalized=raw.trim().toLowerCase().replaceAll("-","_");if(normalized.length===0){return void 0}return DESCRIPTOR_BY_KEY.get(normalized)}function parseNestedBooleanValue(descriptor,rawValue){const normalized=rawValue.trim().toLowerCase();if(normalized==="true"||normalized==="1"||normalized==="yes"||normalized==="on"){return{ok:true,parsed:{descriptor,value:true}}}if(normalized==="false"||normalized==="0"||normalized==="no"||normalized==="off"){return{ok:true,parsed:{descriptor,value:false}}}return{ok:false,error:{message:`Config set ${descriptor.key} requires a boolean value (true|false), got "${rawValue}"`}}}function parseNestedStringValue(descriptor,rawValue,trimmed){if(descriptor.non_empty===true&&trimmed.length===0){return{ok:false,error:{message:`Config set ${descriptor.key} requires a non-empty value`}}}if(descriptor.choices&&!descriptor.choices.includes(trimmed)){return{ok:false,error:{message:`Config set ${descriptor.key} must be one of ${descriptor.choices.join("|")}, got "${rawValue}"`}}}return{ok:true,parsed:{descriptor,value:trimmed}}}function parseFiniteNestedNumber(descriptor,rawValue,trimmed){if(trimmed.length===0){return{ok:false,error:{message:`Config set ${descriptor.key} requires a non-empty value`}}}const parsed=Number(trimmed);if(!Number.isFinite(parsed)){return{ok:false,error:{message:`Config set ${descriptor.key} requires a finite number, got "${rawValue}"`}}}return{ok:true,value:parsed}}function parseNestedIntegerValue(descriptor,rawValue,value){if(!Number.isInteger(value)||value<0){return{ok:false,error:{message:`Config set ${descriptor.key} requires a non-negative integer, got "${rawValue}"`}}}if(descriptor.min!==void 0&&value<descriptor.min){return{ok:false,error:{message:`Config set ${descriptor.key} requires an integer >= ${descriptor.min}, got "${rawValue}" (the runtime silently ignores 0 here and falls back to the default)`}}}if(descriptor.max!==void 0&&value>descriptor.max){return{ok:false,error:{message:`Config set ${descriptor.key} requires an integer <= ${descriptor.max}, got "${rawValue}"`}}}return{ok:true,parsed:{descriptor,value}}}function parseNestedRatioValue(descriptor,rawValue,value){if(value<0||value>1){return{ok:false,error:{message:`Config set ${descriptor.key} requires a number in [0, 1], got "${rawValue}"`}}}return{ok:true,parsed:{descriptor,value}}}function parseNestedNumberValue(descriptor,rawValue,value){if(descriptor.min!==void 0&&value<descriptor.min){return{ok:false,error:{message:`Config set ${descriptor.key} requires a number >= ${descriptor.min}, got "${rawValue}"`}}}return{ok:true,parsed:{descriptor,value}}}function parseNestedSettingValue(descriptor,rawValue){if(typeof rawValue!=="string"){return{ok:false,error:{message:`Config set ${descriptor.key} requires a string value`}}}const trimmed=rawValue.trim();if(descriptor.kind==="boolean"){return parseNestedBooleanValue(descriptor,rawValue)}if(descriptor.kind==="string"){return parseNestedStringValue(descriptor,rawValue,trimmed)}const parsed=parseFiniteNestedNumber(descriptor,rawValue,trimmed);if(!parsed.ok){return{ok:false,error:parsed.error}}if(descriptor.kind==="integer"){return parseNestedIntegerValue(descriptor,rawValue,parsed.value)}if(descriptor.kind==="ratio"){return parseNestedRatioValue(descriptor,rawValue,parsed.value)}return parseNestedNumberValue(descriptor,rawValue,parsed.value)}function readNestedSettingValue(settings,descriptor){const segments=descriptor.path.split(".");let cursor=settings;for(const segment of segments){if(typeof cursor!=="object"||cursor===null){return null}cursor=cursor[segment]}if(typeof cursor==="string"||typeof cursor==="number"||typeof cursor==="boolean"){return cursor}return null}function writeNestedSettingValue(settings,descriptor,value){const segments=descriptor.path.split(".");let cursor=settings;for(let index=0;index<segments.length-1;index+=1){const segment=segments[index];const existing=cursor[segment];if(typeof existing!=="object"||existing===null||Array.isArray(existing)){const next={};cursor[segment]=next;cursor=next}else{cursor=existing}}const leafKey=segments[segments.length-1];const previous=cursor[leafKey];if(previous===value){return false}cursor[leafKey]=value;return true}export{NESTED_SETTING_DESCRIPTORS,parseNestedSettingValue,readNestedSettingValue,resolveNestedSettingDescriptor,writeNestedSettingValue};
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="2d4017d7-771b-53a1-ae56-71df7e1a0ac4")}catch(e2){}})();const NESTED_SETTING_DESCRIPTORS=[{key:"search_provider",path:"search.provider",kind:"string",summary:"Search embedding provider name (e.g. openai, ollama, or an extension provider)."},{key:"search_default_mode",path:"search.default_mode",kind:"string",choices:["auto","keyword","semantic","hybrid"],summary:"Mode a bare pm search runs in: auto (hybrid when semantic search is explicitly configured and runnable, else keyword), or a pinned keyword, semantic, or hybrid."},{key:"search_mutation_refresh_policy",path:"search.mutation_refresh_policy",kind:"string",choices:["cache_only","semantic_configured","semantic_auto"],summary:"Mutation-time search refresh policy: cache_only, semantic_configured, or semantic_auto."},{key:"search_query_expansion_enabled",path:"search.query_expansion.enabled",kind:"boolean",summary:"Enable or disable query expansion for semantic/hybrid search."},{key:"search_query_expansion_provider",path:"search.query_expansion.provider",kind:"string",summary:"Query expansion provider name (built-in openai/ollama or extension provider)."},{key:"search_rerank_enabled",path:"search.rerank.enabled",kind:"boolean",summary:"Enable or disable post-retrieval reranking for hybrid search."},{key:"search_rerank_model",path:"search.rerank.model",kind:"string",summary:"Rerank model name override used by built-in providers."},{key:"search_rerank_top_k",path:"search.rerank.top_k",kind:"integer",min:1,summary:"Number of top hybrid candidates to rerank when rerank is enabled."},{key:"search_embedding_model",path:"search.embedding_model",kind:"string",summary:"Default embedding model name (overrides provider-specific model when set)."},{key:"search_embedding_corpus_max_characters",path:"search.embedding_corpus_max_characters",kind:"integer",min:1,summary:"Maximum semantic corpus characters per item before truncation."},{key:"search_embedding_batch_size",path:"search.embedding_batch_size",kind:"integer",min:1,summary:"Number of items embedded per request batch."},{key:"search_embedding_timeout_ms",path:"search.embedding_timeout_ms",kind:"integer",min:1,summary:"Per-request embedding timeout in milliseconds."},{key:"search_score_threshold",path:"search.score_threshold",kind:"number",summary:"Minimum score for a hit to be returned (0 keeps all matches)."},{key:"search_hybrid_semantic_weight",path:"search.hybrid_semantic_weight",kind:"ratio",summary:"Hybrid mode semantic weight in [0, 1] (1-weight goes to keyword)."},{key:"search_max_results",path:"search.max_results",kind:"integer",min:1,summary:"Default upper bound on search hits when --limit is not supplied."},{key:"search_bm25_k1",path:"search.bm25.k1",kind:"number",min:0,summary:"Offline BM25 term-frequency saturation (k1); higher saturates repeated terms slower (default 1.2)."},{key:"search_bm25_b",path:"search.bm25.b",kind:"ratio",summary:"Offline BM25 document-length normalization (b) in [0, 1]; 0 disables, 1 fully normalizes (default 0.75)."},{key:"openai_base_url",path:"providers.openai.base_url",kind:"string",summary:"OpenAI-compatible API base URL (LM Studio/vLLM also use this)."},{key:"openai_api_key",path:"providers.openai.api_key",kind:"string",summary:"OpenAI-compatible API key."},{key:"openai_model",path:"providers.openai.model",kind:"string",summary:"OpenAI-compatible embedding model name."},{key:"ollama_base_url",path:"providers.ollama.base_url",kind:"string",summary:"Ollama API base URL (typically http://localhost:11434)."},{key:"ollama_model",path:"providers.ollama.model",kind:"string",summary:"Ollama embedding model name (e.g. nomic-embed-text)."},{key:"vector_store_adapter",path:"vector_store.adapter",kind:"string",summary:"Vector store adapter name (lancedb, qdrant, or an extension adapter)."},{key:"vector_store_collection_name",path:"vector_store.collection_name",kind:"string",non_empty:true,summary:"Vector collection/table name shared by Qdrant and LanceDB adapters."},{key:"qdrant_url",path:"vector_store.qdrant.url",kind:"string",summary:"Qdrant HTTP API URL."},{key:"qdrant_api_key",path:"vector_store.qdrant.api_key",kind:"string",summary:"Qdrant API key (empty if running unauthenticated)."},{key:"lancedb_path",path:"vector_store.lancedb.path",kind:"string",summary:"LanceDB storage path (relative to pm root or absolute)."},{key:"id_prefix",path:"id_prefix",kind:"string",non_empty:true,summary:'Prefix for generated item IDs (e.g. "pm" produces pm-xxxx).'},{key:"author_default",path:"author_default",kind:"string",non_empty:true,summary:"Default author recorded on mutations when --author is not supplied."},{key:"agent_identity_probes_enabled",path:"agent_identity.probes_enabled",kind:"boolean",summary:"Allow privacy-bounded local harness provenance probes; no network or subprocess access is permitted."},{key:"mutation_guard_require_attributed_author",path:"mutation_guard.require_attributed_author",kind:"boolean",summary:"Reject mutations whose effective author resolves to unknown."},{key:"mutation_guard_secret_guard",path:"mutation_guard.secret_guard",kind:"string",choices:["off","advise","block"],summary:"Detect credential-shaped mutation content: off, advise, or block."},{key:"mutation_guard_stale_in_progress_hours",path:"mutation_guard.stale_in_progress_hours",kind:"integer",min:1,summary:"Age threshold for unclaimed in-progress work surfaced by health."},{key:"governance_duplicate_detection_mode",path:"governance.duplicate_detection_mode",kind:"string",choices:["off","advisory","strict"],summary:"Create/copy duplicate governance: off, advisory, or strict explicit-bypass enforcement."},{key:"governance_duplicate_detection_threshold",path:"governance.duplicate_detection_threshold",kind:"ratio",summary:"Minimum shared similarity score in [0, 1] for create/copy duplicate governance."},{key:"governance_duplicate_detection_limit",path:"governance.duplicate_detection_limit",kind:"integer",min:0,max:20,summary:"Maximum likely duplicates returned by create/copy governance (0-20)."},{key:"output_default_format",path:"output.default_format",kind:"string",choices:["toon","json"],summary:"Default output format for commands that support it: toon or json."},{key:"ux_deprecation_hints",path:"ux.deprecation_hints",kind:"boolean",summary:"Emit one stderr migration hint for deprecated command aliases."},{key:"locks_ttl_seconds",path:"locks.ttl_seconds",kind:"integer",min:1,summary:"Claim/lock time-to-live in seconds before a stale lock can be reclaimed."},{key:"locks_wait_ms",path:"locks.wait_ms",kind:"integer",min:0,summary:"Bounded jittered wait in milliseconds before a contended item mutation fails with lock_conflict; 0 fails fast. PM_LOCK_WAIT_MS overrides per invocation."},{key:"ids_token_length",path:"ids.token_length",kind:"integer",min:4,max:12,summary:"Random base36 token length for newly minted item ids (4-12, default 4). Raise it to shrink cross-branch id collision odds in concurrent multi-agent workflows (pm-pibw)."},{key:"checkpoints_retention_days",path:"checkpoints.retention_days",kind:"integer",min:1,summary:"Age in days above which pm gc --scope checkpoints prunes bulk-mutation rollback checkpoints."},{key:"schema_unknown_field_policy",path:"schema.unknown_field_policy",kind:"string",choices:["allow","warn","reject"],summary:"How item I/O handles metadata keys not in the field registry: allow, warn, or reject."},{key:"history_compact_policy_enabled",path:"history.compact_policy.enabled",kind:"boolean",summary:"Enable the history-compaction advisory: pm health warns on over-threshold streams."},{key:"history_compact_policy_max_entries",path:"history.compact_policy.max_entries",kind:"integer",min:1,summary:"Entry count above which a history stream is flagged (and the default pm history-compact --all-over threshold)."},{key:"history_compact_policy_trigger",path:"history.compact_policy.trigger",kind:"string",choices:["health_warn","auto"],summary:"History-compaction policy intent: health_warn (advisory only) or auto (scheduled sweeps expected)."}];const DESCRIPTOR_BY_KEY=new Map(NESTED_SETTING_DESCRIPTORS.flatMap(descriptor=>[[descriptor.key,descriptor],[descriptor.path.toLowerCase().replaceAll("-","_"),descriptor]]));function resolveNestedSettingDescriptor(raw){if(typeof raw!=="string"){return void 0}const normalized=raw.trim().toLowerCase().replaceAll("-","_");if(normalized.length===0){return void 0}return DESCRIPTOR_BY_KEY.get(normalized)}function parseNestedBooleanValue(descriptor,rawValue){const normalized=rawValue.trim().toLowerCase();if(normalized==="true"||normalized==="1"||normalized==="yes"||normalized==="on"){return{ok:true,parsed:{descriptor,value:true}}}if(normalized==="false"||normalized==="0"||normalized==="no"||normalized==="off"){return{ok:true,parsed:{descriptor,value:false}}}return{ok:false,error:{message:`Config set ${descriptor.key} requires a boolean value (true|false), got "${rawValue}"`}}}function parseNestedStringValue(descriptor,rawValue,trimmed){if(descriptor.non_empty===true&&trimmed.length===0){return{ok:false,error:{message:`Config set ${descriptor.key} requires a non-empty value`}}}if(descriptor.choices&&!descriptor.choices.includes(trimmed)){return{ok:false,error:{message:`Config set ${descriptor.key} must be one of ${descriptor.choices.join("|")}, got "${rawValue}"`}}}return{ok:true,parsed:{descriptor,value:trimmed}}}function parseFiniteNestedNumber(descriptor,rawValue,trimmed){if(trimmed.length===0){return{ok:false,error:{message:`Config set ${descriptor.key} requires a non-empty value`}}}const parsed=Number(trimmed);if(!Number.isFinite(parsed)){return{ok:false,error:{message:`Config set ${descriptor.key} requires a finite number, got "${rawValue}"`}}}return{ok:true,value:parsed}}function parseNestedIntegerValue(descriptor,rawValue,value){if(!Number.isInteger(value)||value<0){return{ok:false,error:{message:`Config set ${descriptor.key} requires a non-negative integer, got "${rawValue}"`}}}if(descriptor.min!==void 0&&value<descriptor.min){return{ok:false,error:{message:`Config set ${descriptor.key} requires an integer >= ${descriptor.min}, got "${rawValue}" (the runtime silently ignores 0 here and falls back to the default)`}}}if(descriptor.max!==void 0&&value>descriptor.max){return{ok:false,error:{message:`Config set ${descriptor.key} requires an integer <= ${descriptor.max}, got "${rawValue}"`}}}return{ok:true,parsed:{descriptor,value}}}function parseNestedRatioValue(descriptor,rawValue,value){if(value<0||value>1){return{ok:false,error:{message:`Config set ${descriptor.key} requires a number in [0, 1], got "${rawValue}"`}}}return{ok:true,parsed:{descriptor,value}}}function parseNestedNumberValue(descriptor,rawValue,value){if(descriptor.min!==void 0&&value<descriptor.min){return{ok:false,error:{message:`Config set ${descriptor.key} requires a number >= ${descriptor.min}, got "${rawValue}"`}}}return{ok:true,parsed:{descriptor,value}}}function parseNestedSettingValue(descriptor,rawValue){if(typeof rawValue!=="string"){return{ok:false,error:{message:`Config set ${descriptor.key} requires a string value`}}}const trimmed=rawValue.trim();if(descriptor.kind==="boolean"){return parseNestedBooleanValue(descriptor,rawValue)}if(descriptor.kind==="string"){return parseNestedStringValue(descriptor,rawValue,trimmed)}const parsed=parseFiniteNestedNumber(descriptor,rawValue,trimmed);if(!parsed.ok){return{ok:false,error:parsed.error}}if(descriptor.kind==="integer"){return parseNestedIntegerValue(descriptor,rawValue,parsed.value)}if(descriptor.kind==="ratio"){return parseNestedRatioValue(descriptor,rawValue,parsed.value)}return parseNestedNumberValue(descriptor,rawValue,parsed.value)}function readNestedSettingValue(settings,descriptor){const segments=descriptor.path.split(".");let cursor=settings;for(const segment of segments){if(typeof cursor!=="object"||cursor===null){return null}const property=Object.getOwnPropertyDescriptor(cursor,segment);if(!property||!Object.hasOwn(property,"value")){return null}cursor=property.value}if(typeof cursor==="string"||typeof cursor==="number"||typeof cursor==="boolean"){return cursor}return null}function writeNestedSettingValue(settings,descriptor,value){const segments=descriptor.path.split(".");if(segments.some(segment=>segment.length===0||["__proto__","constructor","prototype"].includes(segment))){throw new Error("Unsafe settings path")}let cursor=settings;for(let index=0;index<segments.length-1;index+=1){const segment=segments[index];const existing=Object.getOwnPropertyDescriptor(cursor,segment)?.value;if(typeof existing!=="object"||existing===null||Array.isArray(existing)){const next={};Object.defineProperty(cursor,segment,{value:next,writable:true,enumerable:true,configurable:true});cursor=next}else{cursor=existing}}const leafKey=segments[segments.length-1];const previous=Object.getOwnPropertyDescriptor(cursor,leafKey)?.value;if(previous===value){return false}Object.defineProperty(cursor,leafKey,{value,writable:true,enumerable:true,configurable:true});return true}export{NESTED_SETTING_DESCRIPTORS,parseNestedSettingValue,readNestedSettingValue,resolveNestedSettingDescriptor,writeNestedSettingValue};
|
|
2
2
|
//# sourceMappingURL=nested-settings.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stage bytes beside the destination, then atomically link them into an absent
|
|
3
|
+
* pathname. A competing creator wins without being overwritten. Hard-link
|
|
4
|
+
* failures other than EEXIST propagate; no unsafe overwrite fallback is used.
|
|
5
|
+
* Publication provides atomic visibility, not fsync-backed power-loss durability.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createFileAtomic(targetPath: string, contents: string): Promise<boolean>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="fcbdb4d9-ea0e-5944-98c3-4d1944d2641d")}catch(e2){}})();import{link,mkdir,mkdtemp,rm,writeFile}from"node:fs/promises";import path from"node:path";async function createFileAtomic(targetPath,contents){const parent=path.dirname(targetPath);await mkdir(parent,{recursive:true});const staging=await mkdtemp(path.join(parent,".pm-seed-"));const stagedFile=path.join(staging,"value");try{await writeFile(stagedFile,contents,"utf8");try{await link(stagedFile,targetPath);return true}catch(error){if(error.code==="EEXIST"){return false}throw error}}finally{await rm(staging,{recursive:true,force:true})}}export{createFileAtomic};
|
|
2
|
+
//# sourceMappingURL=atomic-create.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6583b1e2-5eae-5e97-af83-a78adac1d571")}catch(e2){}})();import jsonPatch from"fast-json-patch";import{normalizeHistoryOperationForWrite}from"./operation-contract.js";import{CURRENT_HISTORY_HASH_ALGORITHM,historyDigest,resolveHistoryHashAlgorithm}from"./digest.js";import fs from"node:fs/promises";import path from"node:path";import{EXIT_CODE,ITEM_METADATA_KEY_ORDER}from"../shared/constants.js";import{runActiveServiceOverride}from"../extensions/index.js";import{appendLineAtomic}from"../fs/fs-utils.js";import{canonicalDocument}from"../item/item-format.js";import{toItemRecord}from"../item/item-record.js";import{orderObject,sha256Hex,stableStringify}from"../shared/serialization.js";import{isMillisecondPrecisionRfc3339DateTime,nowIso}from"../shared/time.js";import{diagnoseAgentIdentity,resolveHistoryAgentIdentity,resolveHistoryAuthorSource}from"../shared/author.js";import{appendHistoryEntryWithEventIndex,removeHistoryEventIndexForHistoryPath}from"./event-index.js";import{classifyHistoryEvent}from"./event-classification.js";import{invalidateHistoryDriftCacheForPath}from"./drift-cache.js";import{PmCliError}from"../shared/errors.js";const EMPTY_LEGACY_HASH_DOCUMENT={front_matter:{},body:""};const CURRENT_HISTORY_ITEM_HASH_VERSION=3;const SUPPORTED_HISTORY_ITEM_HASH_VERSIONS=[1,2,3];const CURRENT_HISTORY_RECORD_HASH_VERSION=1;const SUPPORTED_HISTORY_RECORD_HASH_VERSIONS=[1];function hashHistoryRecord(entry){return historyDigest(stableStringify(entry),entry.hash_algorithm)}function hashHistoryPatch(patch){return sha256Hex(stableStringify(patch))}function hashHistoryStream(entries){return sha256Hex(stableStringify(entries))}function sealHistoryRecord(entry){const sealed={...entry,record_hash_version:CURRENT_HISTORY_RECORD_HASH_VERSION};const{record_hash:_recordHash,...canonical}=sealed;return{...sealed,record_hash:hashHistoryRecord(canonical)}}function verifyHistoryRecordHash(entry){try{resolveHistoryHashAlgorithm(entry.hash_algorithm)}catch{return{ok:false,error:"unsupported_history_hash_algorithm"}}if(entry.record_hash_version===void 0&&entry.record_hash===void 0){return{ok:true,coverage:"item_state_only"}}if(entry.record_hash_version===void 0||entry.record_hash===void 0){return{ok:false,error:"incomplete_record_hash_envelope"}}if(!SUPPORTED_HISTORY_RECORD_HASH_VERSIONS.includes(entry.record_hash_version)){return{ok:false,error:"unsupported_record_hash_version"}}const{record_hash:_recordHash,...canonical}=entry;return hashHistoryRecord(canonical)===entry.record_hash?{ok:true,coverage:"record_and_item_state"}:{ok:false,error:"record_hash_mismatch"}}function createHistoryRewriteEvidence(original,options){const evidence={before_hash:original.before_hash,after_hash:original.after_hash,patch_hash:hashHistoryPatch(original.patch)};if(original.hash_algorithm!==void 0)evidence.hash_algorithm=original.hash_algorithm;if(original.item_hash_version!==void 0){evidence.item_hash_version=original.item_hash_version}if(options.retainOriginalPatch){evidence.patch=structuredClone(original.patch)}if(options.retainPriorRecordHash!==false&&original.record_hash_version!==void 0&&original.record_hash!==void 0){evidence.record_hash_version=original.record_hash_version;evidence.record_hash=original.record_hash;evidence.record=structuredClone(original)}return evidence}function resealHistoryRewrite(original,rewritten,options={}){const originalRecordVerification=verifyHistoryRecordHash(original);if(!originalRecordVerification.ok){throw new TypeError(originalRecordVerification.error)}const originalPatchHash=hashHistoryPatch(original.patch);const retainsRewriteEvidence=options.retainPriorRecord===true||original.before_hash!==rewritten.before_hash||original.after_hash!==rewritten.after_hash||original.item_hash_version!==rewritten.item_hash_version||original.hash_algorithm!==rewritten.hash_algorithm||originalPatchHash!==hashHistoryPatch(rewritten.patch);const sealed=sealHistoryRecord({...rewritten,...retainsRewriteEvidence?{reanchor_evidence:[...rewritten.reanchor_evidence??[],createHistoryRewriteEvidence(original,options)]}:{}});const evidenceVerification=verifyHistoryRewriteEvidence(sealed);if(!evidenceVerification.ok){throw new TypeError(evidenceVerification.error)}return sealed}function isHistoryPatch(value){if(!Array.isArray(value)||Object.keys(value).length!==value.length){return false}return value.every(operation=>{if(!isRecord(operation)||typeof operation.path!=="string"){return false}if(operation.op==="move"||operation.op==="copy"){return typeof operation.from==="string"}if(["add","replace","test"].includes(operation.op)){return Object.hasOwn(operation,"value")}return operation.op==="remove"})}function isRetainedHistoryRecordShape(value){return isRecord(value)&&typeof value.ts==="string"&&typeof value.author==="string"&&typeof value.op==="string"&&typeof value.before_hash==="string"&&typeof value.after_hash==="string"&&isHistoryPatch(value.patch)}function hasCompleteRetainedRecordHashEnvelope(evidence){const hasVersion=evidence.record_hash_version!==void 0;const hasHash=evidence.record_hash!==void 0;return hasVersion===hasHash}function isHistoryReanchorEvidence(evidence){if(!isRecord(evidence)||!hasCompleteRetainedRecordHashEnvelope(evidence)||typeof evidence.before_hash!=="string"||typeof evidence.after_hash!=="string"||typeof evidence.patch_hash!=="string"||!/^[a-f0-9]{64}$/u.test(evidence.patch_hash)||evidence.patch!==void 0&&!isHistoryPatch(evidence.patch)||evidence.record_hash_version!==void 0&&typeof evidence.record_hash_version!=="number"||evidence.record_hash!==void 0&&(typeof evidence.record_hash!=="string"||!/^(?:[a-f0-9]{64}|[a-f0-9]{128})$/u.test(evidence.record_hash))){return false}return evidence.record===void 0||isRetainedHistoryRecordShape(evidence.record)}function isHistoryRewriteEvidenceList(evidenceEntries){try{for(const evidence of evidenceEntries){if(!isHistoryReanchorEvidence(evidence))return false;resolveHistoryHashAlgorithm(evidence.hash_algorithm)}return true}catch{return false}}function matchesRetainedHistoryRecord(evidence){const record=evidence.record;return record!==void 0&&record.before_hash===evidence.before_hash&&record.after_hash===evidence.after_hash&&record.item_hash_version===evidence.item_hash_version&&record.hash_algorithm===evidence.hash_algorithm&&record.record_hash_version===evidence.record_hash_version&&record.record_hash===evidence.record_hash&&hashHistoryPatch(record.patch)===evidence.patch_hash}function reconstructPriorHistoryRecord(current,evidence,priorEvidence){if(evidence.patch&&hashHistoryPatch(evidence.patch)!==evidence.patch_hash){return{kind:"patch_hash_mismatch"}}if(evidence.record){if(!matchesRetainedHistoryRecord(evidence)){return{kind:"record_hash_mismatch"}}return{kind:"record",entry:evidence.record}}const priorPatch=evidence.patch??current.patch;if(hashHistoryPatch(priorPatch)!==evidence.patch_hash){return{kind:"digest_only"}}const priorRecord={...current,before_hash:evidence.before_hash,after_hash:evidence.after_hash,patch:priorPatch,hash_algorithm:evidence.hash_algorithm,...evidence.item_hash_version===void 0?{}:{item_hash_version:evidence.item_hash_version},...evidence.record_hash_version===void 0?{}:{record_hash_version:evidence.record_hash_version},...evidence.record_hash===void 0?{}:{record_hash:evidence.record_hash},...priorEvidence.length===0?{}:{reanchor_evidence:priorEvidence}};if(evidence.hash_algorithm===void 0)delete priorRecord.hash_algorithm;if(priorEvidence.length===0)delete priorRecord.reanchor_evidence;if(evidence.item_hash_version===void 0){delete priorRecord.item_hash_version}return evidence.record_hash_version===void 0||evidence.record_hash===void 0?{kind:"legacy",entry:priorRecord}:{kind:"record",entry:priorRecord}}function verifyHistoryRewriteEvidence(entry){const evidenceEntries=entry.reanchor_evidence;if(evidenceEntries===void 0)return{ok:true,coverage:"none"};if(!Array.isArray(evidenceEntries)||!isHistoryRewriteEvidenceList(evidenceEntries)){return{ok:false,error:"rewrite_evidence_invalid"}}if(evidenceEntries.length===0)return{ok:true,coverage:"none"};let reconstructed=entry;for(let index=evidenceEntries.length-1;index>=0;index-=1){const evidence=evidenceEntries[index];const prior=reconstructPriorHistoryRecord(reconstructed,evidence,evidenceEntries.slice(0,index));if(prior.kind==="patch_hash_mismatch"){return{ok:false,error:"rewrite_evidence_patch_hash_mismatch"}}if(prior.kind==="record_hash_mismatch"){return{ok:false,error:"rewrite_evidence_record_hash_mismatch"}}if(prior.kind==="digest_only"){return{ok:true,coverage:"digest_only"}}if(prior.kind==="legacy"){return{ok:true,coverage:"legacy_anchor_only"}}if(!verifyHistoryRecordHash(prior.entry).ok){return{ok:false,error:"rewrite_evidence_record_hash_mismatch"}}reconstructed=prior.entry}return{ok:true,coverage:"complete"}}function compareOptionalStrings(left,right){return(left??"").localeCompare(right??"")}function compareOptionalNumbers(left,right){return(left??0)-(right??0)}function compareJsonValues(left,right,fallback){return JSON.stringify(left??fallback).localeCompare(JSON.stringify(right??fallback))}function compareLegacyLinkedTests(left,right){const comparisons=[left.scope.localeCompare(right.scope),compareOptionalStrings(left.path,right.path),compareOptionalStrings(left.command,right.command),compareOptionalNumbers(left.timeout_seconds,right.timeout_seconds),compareOptionalStrings(left.pm_context_mode,right.pm_context_mode),Number(Boolean(left.shared_host_safe))-Number(Boolean(right.shared_host_safe)),compareJsonValues(left.env_clear,right.env_clear,[]),compareJsonValues(left.env_set,right.env_set,{}),compareJsonValues(left.assert_stdout_contains,right.assert_stdout_contains,[]),compareJsonValues(left.assert_stdout_regex,right.assert_stdout_regex,[]),compareJsonValues(left.assert_stderr_contains,right.assert_stderr_contains,[]),compareJsonValues(left.assert_stderr_regex,right.assert_stderr_regex,[]),compareOptionalNumbers(left.assert_stdout_min_lines,right.assert_stdout_min_lines),compareJsonValues(left.assert_json_field_equals,right.assert_json_field_equals,{}),compareJsonValues(left.assert_json_field_gte,right.assert_json_field_gte,{}),compareOptionalStrings(left.note,right.note)];return comparisons.find(comparison=>comparison!==0)??0}function decodeJsonPointer(path2){if(!path2||path2==="/"){return[]}if(!path2.startsWith("/")){return[]}return path2.slice(1).split("/").map(segment=>segment.replaceAll("~1","/").replaceAll("~0","~"))}function isDefinedPointerPath(document,path2){const segments=decodeJsonPointer(path2);if(segments.length===0){return true}let cursor=document;for(const segment of segments){const arrayIndex=/^(0|[1-9]\d*)$/.test(segment)?Number(segment):-1;const next=Array.isArray(cursor)?arrayIndex>=0&&arrayIndex<cursor.length?cursor[arrayIndex]:void 0:isRecord(cursor)&&Object.prototype.hasOwnProperty.call(cursor,segment)?cursor[segment]:void 0;if(next===void 0)return false;cursor=next}return true}function normalizeHistoryPatchOps(beforeDocument,patch){const normalized=[];let replayCursor=structuredClone(beforeDocument);for(const operation of patch){const normalizedOperation=operation.op==="replace"&&!isDefinedPointerPath(replayCursor,operation.path)?{...operation,op:"add"}:operation;normalized.push(normalizedOperation);replayCursor=jsonPatch.applyPatch(replayCursor,[normalizedOperation],true,true).newDocument}return normalized}function canonicalHashDocument(document,version,legacyV2Fields=false){const hasMetadata=document.metadata&&Object.keys(document.metadata).length>0;if(!hasMetadata){return{front_matter:{},body:document.body??""}}const canonical=canonicalDocument(document);const usesLegacyFields=version===1||version===2&&legacyV2Fields;const epochMetadata=usesLegacyFields?{...canonical.metadata,...canonical.metadata.dependencies===void 0?{}:{dependencies:canonical.metadata.dependencies.map(dependency=>({...dependency,id:dependency.id.toLowerCase()}))},...canonical.metadata.tests===void 0?{}:{tests:canonical.metadata.tests.map(({workspace_context_mode:_workspaceContextMode,provenance:_provenance,provenance_invalid:_provenanceInvalid,...test})=>test)},...canonical.metadata.test_runs===void 0?{}:{test_runs:canonical.metadata.test_runs.map(({executions:_executions,...testRun})=>testRun)}}:canonical.metadata;const metadata=version===1&&epochMetadata.tests?{...epochMetadata,tests:[...epochMetadata.tests].sort(compareLegacyLinkedTests)}:epochMetadata;const orderedMetadata=orderObject(toItemRecord(metadata),ITEM_METADATA_KEY_ORDER);return{front_matter:orderedMetadata,body:canonical.body}}function canonicalPatchDocument(document){const hasMetadata=document.metadata&&Object.keys(document.metadata).length>0;if(!hasMetadata){return{metadata:{},body:document.body??""}}const canonical=canonicalDocument(document);const orderedMetadata=orderObject(toItemRecord(canonical.metadata),ITEM_METADATA_KEY_ORDER);return{metadata:orderedMetadata,body:canonical.body}}function hashDocument(document){return hashDocumentForVersion(document,CURRENT_HISTORY_ITEM_HASH_VERSION)}function hashDocumentForVersion(document,version,algorithm){if(!SUPPORTED_HISTORY_ITEM_HASH_VERSIONS.some(supportedVersion=>supportedVersion===version)){throw new TypeError(`unsupported_item_hash_version:${String(version)}`)}return historyDigest(stableStringify(canonicalHashDocument(document,version)),algorithm)}function hashDocumentVerificationCandidates(document,version,algorithm){const canonicalHash=hashDocumentForVersion(document,version,algorithm);return version===2?[canonicalHash,historyDigest(stableStringify(canonicalHashDocument(document,version,true)),algorithm)]:[canonicalHash]}function hashEmptyDocument(){return sha256Hex(stableStringify(EMPTY_LEGACY_HASH_DOCUMENT))}function createHistoryEntry(params){const operation=normalizeHistoryOperationForWrite(params.op);const beforeHashCanonical=canonicalHashDocument(params.before,CURRENT_HISTORY_ITEM_HASH_VERSION);const afterHashCanonical=canonicalHashDocument(params.after,CURRENT_HISTORY_ITEM_HASH_VERSION);const beforePatchCanonical=canonicalPatchDocument(params.before);const afterPatchCanonical=canonicalPatchDocument(params.after);const rawPatch=jsonPatch.compare(beforePatchCanonical,afterPatchCanonical);const patch=normalizeHistoryPatchOps(beforePatchCanonical,rawPatch);const agentIdentity=resolveHistoryAgentIdentity(params.author);const provenanceOutcomes=agentIdentity.harness?Object.fromEntries(Object.entries(diagnoseAgentIdentity().provenance_outcomes).filter(([,outcome])=>outcome.resolver!==void 0&&outcome.status!=="resolved")):void 0;const context=provenanceOutcomes===void 0||Object.keys(provenanceOutcomes).length===0?params.context:{...params.context,agent_provenance_outcomes:provenanceOutcomes};const algorithm=params.hashAlgorithm??CURRENT_HISTORY_HASH_ALGORITHM;const entry={hash_algorithm:algorithm,ts:params.nowIso,author:params.author,author_source:params.authorSource??resolveHistoryAuthorSource(params.author),...agentIdentity.harness?{agent_harness:agentIdentity.harness}:{},...agentIdentity.model?{agent_model:agentIdentity.model}:{},...agentIdentity.model_source?{agent_model_source:agentIdentity.model_source}:{},...agentIdentity.instance?{agent_instance:agentIdentity.instance}:{},...agentIdentity.provenance?{agent_provenance:agentIdentity.provenance}:{},...agentIdentity.episode?{agent_episode:agentIdentity.episode}:{},op:operation,patch,before_hash:historyDigest(stableStringify(beforeHashCanonical),algorithm),after_hash:historyDigest(stableStringify(afterHashCanonical),algorithm),item_hash_version:CURRENT_HISTORY_ITEM_HASH_VERSION,message:params.message===void 0?void 0:params.message,...context===void 0?{}:{context}};return sealHistoryRecord({...entry,event_class:classifyHistoryEvent(entry)})}function isRecord(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function invalidHistoryTimestamp(message){return new PmCliError(message,EXIT_CODE.GENERIC_FAILURE,{code:"history_timestamp_invalid"})}function fallbackHistoryTimestamp(entry){const ts=entry.ts.trim();if(ts.length===0)return nowIso();if(!isMillisecondPrecisionRfc3339DateTime(ts)){throw invalidHistoryTimestamp("History timestamp must be a valid RFC 3339 date-time with millisecond precision")}if(ts!==entry.ts){throw invalidHistoryTimestamp("History timestamp must not contain surrounding whitespace")}return entry.ts}function withHistoryTimestamp(value,fallbackTs){const ts=value.ts;if(typeof ts==="string"&&ts.trim().length>0){if(!isMillisecondPrecisionRfc3339DateTime(ts)){throw invalidHistoryTimestamp("History timestamp must be a valid RFC 3339 date-time with millisecond precision")}return value}return{...value,ts:fallbackTs}}function serializeHistoryLine(value,fallbackEntry){const fallbackTs=fallbackHistoryTimestamp(fallbackEntry);if(typeof value==="string"){let parsed;try{parsed=JSON.parse(value)}catch{return value}if(isRecord(parsed)){return JSON.stringify(withHistoryTimestamp(parsed,fallbackTs))}return value}if(isRecord(value)){return JSON.stringify(withHistoryTimestamp(value,fallbackTs))}return JSON.stringify(value)}async function applyHistoryAppendOverride(historyPath,entry,result){if(result===false)return true;if(typeof result==="string"){const line2=serializeHistoryLine(result,entry);await appendHistoryLineWithIdentityReservation(historyPath,line2);await invalidateHistoryDriftCacheForPath(historyPath);await removeHistoryEventIndexForHistoryPath(historyPath);return true}if(typeof result!=="object"||result===null)return false;const record=result;if(record.skip===true)return true;const nextHistoryPath=typeof record.history_path==="string"?record.history_path:historyPath;const line=serializeHistoryLine(typeof record.line==="string"?record.line:record.entry??entry,entry);await appendHistoryLineWithIdentityReservation(nextHistoryPath,line);await invalidateHistoryDriftCacheForPath(nextHistoryPath);await removeHistoryEventIndexForHistoryPath(nextHistoryPath);return true}async function appendHistoryLineWithIdentityReservation(historyPath,line){let record;try{record=JSON.parse(line)}catch{record=null}if(!isRecord(record)||record.op!=="create"){await appendLineAtomic(historyPath,line);return}await fs.mkdir(path.dirname(historyPath),{recursive:true});try{await fs.writeFile(historyPath,`${line}
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8c02324c-231c-54ae-8edb-256ac7e04b50")}catch(e2){}})();import jsonPatch from"fast-json-patch";import{normalizeHistoryOperationForWrite}from"./operation-contract.js";import{CURRENT_HISTORY_HASH_ALGORITHM,historyDigest,resolveHistoryHashAlgorithm}from"./digest.js";import fs from"node:fs/promises";import path from"node:path";import{EXIT_CODE,ITEM_METADATA_KEY_ORDER}from"../shared/constants.js";import{runActiveServiceOverride}from"../extensions/index.js";import{appendLineAtomic}from"../fs/fs-utils.js";import{canonicalDocument}from"../item/item-format.js";import{toItemRecord}from"../item/item-record.js";import{orderObject,sha256Hex,stableStringify}from"../shared/serialization.js";import{isMillisecondPrecisionRfc3339DateTime,nowIso}from"../shared/time.js";import{diagnoseAgentIdentity,resolveHistoryAgentIdentity,resolveHistoryAuthorSource}from"../shared/author.js";import{appendHistoryEntryWithEventIndex,removeHistoryEventIndexForHistoryPath}from"./event-index.js";import{classifyHistoryEvent}from"./event-classification.js";import{invalidateHistoryDriftCacheForPath}from"./drift-cache.js";import{PmCliError}from"../shared/errors.js";const EMPTY_LEGACY_HASH_DOCUMENT={front_matter:{},body:""};const CURRENT_HISTORY_ITEM_HASH_VERSION=3;const SUPPORTED_HISTORY_ITEM_HASH_VERSIONS=[1,2,3];const CURRENT_HISTORY_RECORD_HASH_VERSION=1;const SUPPORTED_HISTORY_RECORD_HASH_VERSIONS=[1];function hashHistoryRecord(entry){return historyDigest(stableStringify(entry),entry.hash_algorithm)}function hashHistoryPatch(patch){return sha256Hex(stableStringify(patch))}function hashHistoryStream(entries){return sha256Hex(stableStringify(entries))}function sealHistoryRecord(entry){const sealed={...entry,record_hash_version:CURRENT_HISTORY_RECORD_HASH_VERSION};const{record_hash:_recordHash,...canonical}=sealed;return{...sealed,record_hash:hashHistoryRecord(canonical)}}function verifyHistoryRecordHash(entry){try{resolveHistoryHashAlgorithm(entry.hash_algorithm)}catch{return{ok:false,error:"unsupported_history_hash_algorithm"}}if(entry.record_hash_version===void 0&&entry.record_hash===void 0){return{ok:true,coverage:"item_state_only"}}if(entry.record_hash_version===void 0||entry.record_hash===void 0){return{ok:false,error:"incomplete_record_hash_envelope"}}if(!SUPPORTED_HISTORY_RECORD_HASH_VERSIONS.includes(entry.record_hash_version)){return{ok:false,error:"unsupported_record_hash_version"}}const{record_hash:_recordHash,...canonical}=entry;return hashHistoryRecord(canonical)===entry.record_hash?{ok:true,coverage:"record_and_item_state"}:{ok:false,error:"record_hash_mismatch"}}function createHistoryRewriteEvidence(original,options){const evidence={before_hash:original.before_hash,after_hash:original.after_hash,patch_hash:hashHistoryPatch(original.patch)};if(original.hash_algorithm!==void 0)evidence.hash_algorithm=original.hash_algorithm;if(original.item_hash_version!==void 0){evidence.item_hash_version=original.item_hash_version}if(options.retainOriginalPatch){evidence.patch=structuredClone(original.patch)}if(options.retainPriorRecordHash!==false&&original.record_hash_version!==void 0&&original.record_hash!==void 0){evidence.record_hash_version=original.record_hash_version;evidence.record_hash=original.record_hash;evidence.record=structuredClone(original)}return evidence}function resealHistoryRewrite(original,rewritten,options={}){const originalRecordVerification=verifyHistoryRecordHash(original);if(!originalRecordVerification.ok){throw new TypeError(originalRecordVerification.error)}const originalPatchHash=hashHistoryPatch(original.patch);const retainsRewriteEvidence=options.retainPriorRecord===true||original.before_hash!==rewritten.before_hash||original.after_hash!==rewritten.after_hash||original.item_hash_version!==rewritten.item_hash_version||original.hash_algorithm!==rewritten.hash_algorithm||originalPatchHash!==hashHistoryPatch(rewritten.patch);const sealed=sealHistoryRecord({...rewritten,...retainsRewriteEvidence?{reanchor_evidence:[...rewritten.reanchor_evidence??[],createHistoryRewriteEvidence(original,options)]}:{}});const evidenceVerification=verifyHistoryRewriteEvidence(sealed);if(!evidenceVerification.ok){throw new TypeError(evidenceVerification.error)}return sealed}function isHistoryPatch(value){if(!Array.isArray(value)||Object.keys(value).length!==value.length){return false}return value.every(operation=>{if(!isRecord(operation)||typeof operation.path!=="string"){return false}if(operation.op==="move"||operation.op==="copy"){return typeof operation.from==="string"}if(["add","replace","test"].includes(operation.op)){return Object.hasOwn(operation,"value")}return operation.op==="remove"})}function isRetainedHistoryRecordShape(value){return isRecord(value)&&typeof value.ts==="string"&&typeof value.author==="string"&&typeof value.op==="string"&&typeof value.before_hash==="string"&&typeof value.after_hash==="string"&&isHistoryPatch(value.patch)}function hasCompleteRetainedRecordHashEnvelope(evidence){const hasVersion=evidence.record_hash_version!==void 0;const hasHash=evidence.record_hash!==void 0;return hasVersion===hasHash}function isHistoryReanchorEvidence(evidence){if(!isRecord(evidence)||!hasCompleteRetainedRecordHashEnvelope(evidence)||typeof evidence.before_hash!=="string"||typeof evidence.after_hash!=="string"||typeof evidence.patch_hash!=="string"||!/^[a-f0-9]{64}$/u.test(evidence.patch_hash)||evidence.patch!==void 0&&!isHistoryPatch(evidence.patch)||evidence.record_hash_version!==void 0&&typeof evidence.record_hash_version!=="number"||evidence.record_hash!==void 0&&(typeof evidence.record_hash!=="string"||!/^(?:[a-f0-9]{64}|[a-f0-9]{128})$/u.test(evidence.record_hash))){return false}return evidence.record===void 0||isRetainedHistoryRecordShape(evidence.record)}function isHistoryRewriteEvidenceList(evidenceEntries){try{for(const evidence of evidenceEntries){if(!isHistoryReanchorEvidence(evidence))return false;resolveHistoryHashAlgorithm(evidence.hash_algorithm)}return true}catch{return false}}function matchesRetainedHistoryRecord(evidence){const record=evidence.record;return record!==void 0&&record.before_hash===evidence.before_hash&&record.after_hash===evidence.after_hash&&record.item_hash_version===evidence.item_hash_version&&record.hash_algorithm===evidence.hash_algorithm&&record.record_hash_version===evidence.record_hash_version&&record.record_hash===evidence.record_hash&&hashHistoryPatch(record.patch)===evidence.patch_hash}function reconstructPriorHistoryRecord(current,evidence,priorEvidence){if(evidence.patch&&hashHistoryPatch(evidence.patch)!==evidence.patch_hash){return{kind:"patch_hash_mismatch"}}if(evidence.record){if(!matchesRetainedHistoryRecord(evidence)){return{kind:"record_hash_mismatch"}}return{kind:"record",entry:evidence.record}}const priorPatch=evidence.patch??current.patch;if(hashHistoryPatch(priorPatch)!==evidence.patch_hash){return{kind:"digest_only"}}const priorRecord={...current,before_hash:evidence.before_hash,after_hash:evidence.after_hash,patch:priorPatch,hash_algorithm:evidence.hash_algorithm,...evidence.item_hash_version===void 0?{}:{item_hash_version:evidence.item_hash_version},...evidence.record_hash_version===void 0?{}:{record_hash_version:evidence.record_hash_version},...evidence.record_hash===void 0?{}:{record_hash:evidence.record_hash},...priorEvidence.length===0?{}:{reanchor_evidence:priorEvidence}};if(evidence.hash_algorithm===void 0)delete priorRecord.hash_algorithm;if(priorEvidence.length===0)delete priorRecord.reanchor_evidence;if(evidence.item_hash_version===void 0){delete priorRecord.item_hash_version}return evidence.record_hash_version===void 0||evidence.record_hash===void 0?{kind:"legacy",entry:priorRecord}:{kind:"record",entry:priorRecord}}function verifyHistoryRewriteEvidence(entry){const evidenceEntries=entry.reanchor_evidence;if(evidenceEntries===void 0)return{ok:true,coverage:"none"};if(!Array.isArray(evidenceEntries)||!isHistoryRewriteEvidenceList(evidenceEntries)){return{ok:false,error:"rewrite_evidence_invalid"}}if(evidenceEntries.length===0)return{ok:true,coverage:"none"};let reconstructed=entry;for(let index=evidenceEntries.length-1;index>=0;index-=1){const evidence=evidenceEntries[index];const prior=reconstructPriorHistoryRecord(reconstructed,evidence,evidenceEntries.slice(0,index));if(prior.kind==="patch_hash_mismatch"){return{ok:false,error:"rewrite_evidence_patch_hash_mismatch"}}if(prior.kind==="record_hash_mismatch"){return{ok:false,error:"rewrite_evidence_record_hash_mismatch"}}if(prior.kind==="digest_only"){return{ok:true,coverage:"digest_only"}}if(prior.kind==="legacy"){return{ok:true,coverage:"legacy_anchor_only"}}if(!verifyHistoryRecordHash(prior.entry).ok){return{ok:false,error:"rewrite_evidence_record_hash_mismatch"}}reconstructed=prior.entry}return{ok:true,coverage:"complete"}}function compareOptionalStrings(left,right){return(left??"").localeCompare(right??"")}function compareOptionalNumbers(left,right){return(left??0)-(right??0)}function compareJsonValues(left,right,fallback){return JSON.stringify(left??fallback).localeCompare(JSON.stringify(right??fallback))}function compareLegacyLinkedTests(left,right){const comparisons=[left.scope.localeCompare(right.scope),compareOptionalStrings(left.path,right.path),compareOptionalStrings(left.command,right.command),compareOptionalNumbers(left.timeout_seconds,right.timeout_seconds),compareOptionalStrings(left.pm_context_mode,right.pm_context_mode),Number(Boolean(left.shared_host_safe))-Number(Boolean(right.shared_host_safe)),compareJsonValues(left.env_clear,right.env_clear,[]),compareJsonValues(left.env_set,right.env_set,{}),compareJsonValues(left.assert_stdout_contains,right.assert_stdout_contains,[]),compareJsonValues(left.assert_stdout_regex,right.assert_stdout_regex,[]),compareJsonValues(left.assert_stderr_contains,right.assert_stderr_contains,[]),compareJsonValues(left.assert_stderr_regex,right.assert_stderr_regex,[]),compareOptionalNumbers(left.assert_stdout_min_lines,right.assert_stdout_min_lines),compareJsonValues(left.assert_json_field_equals,right.assert_json_field_equals,{}),compareJsonValues(left.assert_json_field_gte,right.assert_json_field_gte,{}),compareOptionalStrings(left.note,right.note)];return comparisons.find(comparison=>comparison!==0)??0}function decodeJsonPointer(path2){if(!path2||path2==="/"){return[]}if(!path2.startsWith("/")){return[]}return path2.slice(1).split("/").map(segment=>segment.replaceAll("~1","/").replaceAll("~0","~"))}function isDefinedPointerPath(document,path2){const segments=decodeJsonPointer(path2);if(segments.length===0){return true}let cursor=document;for(const segment of segments){const arrayIndex=/^(0|[1-9]\d*)$/.test(segment)?Number(segment):-1;const next=Array.isArray(cursor)?arrayIndex>=0&&arrayIndex<cursor.length?cursor[arrayIndex]:void 0:isRecord(cursor)&&Object.prototype.hasOwnProperty.call(cursor,segment)?cursor[segment]:void 0;if(next===void 0)return false;cursor=next}return true}function normalizeHistoryPatchOps(beforeDocument,patch){const normalized=[];let replayCursor=structuredClone(beforeDocument);for(const operation of patch){const normalizedOperation=operation.op==="replace"&&!isDefinedPointerPath(replayCursor,operation.path)?{...operation,op:"add"}:operation;normalized.push(normalizedOperation);replayCursor=jsonPatch.applyPatch(replayCursor,[normalizedOperation],true,true).newDocument}return normalized}function canonicalHashDocument(document,version,legacyV2Fields=false){const hasMetadata=document.metadata&&Object.keys(document.metadata).length>0;if(!hasMetadata){return{front_matter:{},body:document.body??""}}const canonical=canonicalDocument(document);const usesLegacyFields=version===1||version===2&&legacyV2Fields;const epochMetadata=usesLegacyFields?{...canonical.metadata,...canonical.metadata.dependencies===void 0?{}:{dependencies:canonical.metadata.dependencies.map(dependency=>({...dependency,id:dependency.id.toLowerCase()}))},...canonical.metadata.tests===void 0?{}:{tests:canonical.metadata.tests.map(({workspace_context_mode:_workspaceContextMode,provenance:_provenance,provenance_invalid:_provenanceInvalid,...test})=>test)},...canonical.metadata.test_runs===void 0?{}:{test_runs:canonical.metadata.test_runs.map(({executions:_executions,...testRun})=>testRun)}}:canonical.metadata;const metadata=version===1&&epochMetadata.tests?{...epochMetadata,tests:[...epochMetadata.tests].sort(compareLegacyLinkedTests)}:epochMetadata;const orderedMetadata=orderObject(toItemRecord(metadata),ITEM_METADATA_KEY_ORDER);return{front_matter:orderedMetadata,body:canonical.body}}function canonicalPatchDocument(document){const hasMetadata=document.metadata&&Object.keys(document.metadata).length>0;if(!hasMetadata){return{metadata:{},body:document.body??""}}const canonical=canonicalDocument(document);const orderedMetadata=orderObject(toItemRecord(canonical.metadata),ITEM_METADATA_KEY_ORDER);return{metadata:orderedMetadata,body:canonical.body}}function hashDocument(document){return hashDocumentForVersion(document,CURRENT_HISTORY_ITEM_HASH_VERSION)}function hashDocumentForVersion(document,version,algorithm){if(!SUPPORTED_HISTORY_ITEM_HASH_VERSIONS.some(supportedVersion=>supportedVersion===version)){throw new TypeError(`unsupported_item_hash_version:${String(version)}`)}return historyDigest(stableStringify(canonicalHashDocument(document,version)),algorithm)}function hashDocumentVerificationCandidates(document,version,algorithm){const canonicalHash=hashDocumentForVersion(document,version,algorithm);return version===2?[canonicalHash,historyDigest(stableStringify(canonicalHashDocument(document,version,true)),algorithm)]:[canonicalHash]}function hashEmptyDocument(){return sha256Hex(stableStringify(EMPTY_LEGACY_HASH_DOCUMENT))}function createHistoryEntry(params){const operation=normalizeHistoryOperationForWrite(params.op);const beforeHashCanonical=canonicalHashDocument(params.before,CURRENT_HISTORY_ITEM_HASH_VERSION);const afterHashCanonical=canonicalHashDocument(params.after,CURRENT_HISTORY_ITEM_HASH_VERSION);const beforePatchCanonical=canonicalPatchDocument(params.before);const afterPatchCanonical=canonicalPatchDocument(params.after);const rawPatch=jsonPatch.compare(beforePatchCanonical,afterPatchCanonical);const patch=normalizeHistoryPatchOps(beforePatchCanonical,rawPatch);const agentIdentity=resolveHistoryAgentIdentity(params.author);const provenanceOutcomes=agentIdentity.harness?Object.fromEntries(Object.entries(diagnoseAgentIdentity().provenance_outcomes).filter(([dimension,outcome])=>outcome.resolver!==void 0&&(outcome.status!=="resolved"||agentIdentity.provenance?.[dimension]?.source==="probe"))):void 0;const context=provenanceOutcomes===void 0||Object.keys(provenanceOutcomes).length===0?params.context:{...params.context,agent_provenance_outcomes:provenanceOutcomes};const algorithm=params.hashAlgorithm??CURRENT_HISTORY_HASH_ALGORITHM;const entry={hash_algorithm:algorithm,ts:params.nowIso,author:params.author,author_source:params.authorSource??resolveHistoryAuthorSource(params.author),...agentIdentity.harness?{agent_harness:agentIdentity.harness}:{},...agentIdentity.model?{agent_model:agentIdentity.model}:{},...agentIdentity.model_source?{agent_model_source:agentIdentity.model_source}:{},...agentIdentity.instance?{agent_instance:agentIdentity.instance}:{},...agentIdentity.provenance?{agent_provenance:agentIdentity.provenance}:{},...agentIdentity.episode?{agent_episode:agentIdentity.episode}:{},op:operation,patch,before_hash:historyDigest(stableStringify(beforeHashCanonical),algorithm),after_hash:historyDigest(stableStringify(afterHashCanonical),algorithm),item_hash_version:CURRENT_HISTORY_ITEM_HASH_VERSION,message:params.message===void 0?void 0:params.message,...context===void 0?{}:{context}};return sealHistoryRecord({...entry,event_class:classifyHistoryEvent(entry)})}function isRecord(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function invalidHistoryTimestamp(message){return new PmCliError(message,EXIT_CODE.GENERIC_FAILURE,{code:"history_timestamp_invalid"})}function fallbackHistoryTimestamp(entry){const ts=entry.ts.trim();if(ts.length===0)return nowIso();if(!isMillisecondPrecisionRfc3339DateTime(ts)){throw invalidHistoryTimestamp("History timestamp must be a valid RFC 3339 date-time with millisecond precision")}if(ts!==entry.ts){throw invalidHistoryTimestamp("History timestamp must not contain surrounding whitespace")}return entry.ts}function withHistoryTimestamp(value,fallbackTs){const ts=value.ts;if(typeof ts==="string"&&ts.trim().length>0){if(!isMillisecondPrecisionRfc3339DateTime(ts)){throw invalidHistoryTimestamp("History timestamp must be a valid RFC 3339 date-time with millisecond precision")}return value}return{...value,ts:fallbackTs}}function serializeHistoryLine(value,fallbackEntry){const fallbackTs=fallbackHistoryTimestamp(fallbackEntry);if(typeof value==="string"){let parsed;try{parsed=JSON.parse(value)}catch{return value}if(isRecord(parsed)){return JSON.stringify(withHistoryTimestamp(parsed,fallbackTs))}return value}if(isRecord(value)){return JSON.stringify(withHistoryTimestamp(value,fallbackTs))}return JSON.stringify(value)}async function applyHistoryAppendOverride(historyPath,entry,result){if(result===false)return true;if(typeof result==="string"){const line2=serializeHistoryLine(result,entry);await appendHistoryLineWithIdentityReservation(historyPath,line2);await invalidateHistoryDriftCacheForPath(historyPath);await removeHistoryEventIndexForHistoryPath(historyPath);return true}if(typeof result!=="object"||result===null)return false;const record=result;if(record.skip===true)return true;const nextHistoryPath=typeof record.history_path==="string"?record.history_path:historyPath;const line=serializeHistoryLine(typeof record.line==="string"?record.line:record.entry??entry,entry);await appendHistoryLineWithIdentityReservation(nextHistoryPath,line);await invalidateHistoryDriftCacheForPath(nextHistoryPath);await removeHistoryEventIndexForHistoryPath(nextHistoryPath);return true}async function appendHistoryLineWithIdentityReservation(historyPath,line){let record;try{record=JSON.parse(line)}catch{record=null}if(!isRecord(record)||record.op!=="create"){await appendLineAtomic(historyPath,line);return}await fs.mkdir(path.dirname(historyPath),{recursive:true});try{await fs.writeFile(historyPath,`${line}
|
|
2
2
|
`,{encoding:"utf8",flag:"wx"})}catch(error){if(error.code!=="EEXIST")throw error;throw new PmCliError("This item identity is reserved by an existing history stream.",EXIT_CODE.CONFLICT,{code:"item_identity_reserved",required:"Choose a new item ID or restore the original item from its history.",nextSteps:["Run pm history <id> --full, then pm restore <id> <version> to recover the original item."]})}}async function appendHistoryEntry(historyPath,entry){const override=await runActiveServiceOverride("history_append",{history_path:historyPath,entry});if(override.handled&&await applyHistoryAppendOverride(historyPath,entry,override.result)){return}const timestampedEntry=entry.ts.trim().length>0?entry:{...entry,ts:fallbackHistoryTimestamp(entry)};const normalizedEntry=sealHistoryRecord({...timestampedEntry,hash_algorithm:resolveHistoryHashAlgorithm(timestampedEntry.hash_algorithm),event_class:classifyHistoryEvent(timestampedEntry)});await appendHistoryEntryWithEventIndex(historyPath,normalizedEntry,async()=>{await appendHistoryLineWithIdentityReservation(historyPath,serializeHistoryLine(normalizedEntry,normalizedEntry))});await invalidateHistoryDriftCacheForPath(historyPath)}const _testOnly={decodeJsonPointer,isDefinedPointerPath};export{CURRENT_HISTORY_ITEM_HASH_VERSION,CURRENT_HISTORY_RECORD_HASH_VERSION,SUPPORTED_HISTORY_ITEM_HASH_VERSIONS,SUPPORTED_HISTORY_RECORD_HASH_VERSIONS,_testOnly,appendHistoryEntry,createHistoryEntry,hashDocument,hashDocumentForVersion,hashDocumentVerificationCandidates,hashEmptyDocument,hashHistoryPatch,hashHistoryRecord,hashHistoryStream,resealHistoryRewrite,sealHistoryRecord,verifyHistoryRecordHash,verifyHistoryRewriteEvidence};
|
|
3
3
|
//# sourceMappingURL=history.js.map
|
|
@@ -117,7 +117,7 @@ export declare function normalizeRuntimeSchemaSettings(schema: Partial<RuntimeSc
|
|
|
117
117
|
export declare function filePathForSchemaSection(pmRoot: string, configuredPath: string | undefined, fallbackPath: string): string;
|
|
118
118
|
/** Resolves the active tracker's `schema/types.json` path so user-facing hints (e.g. the invalid-type error) point at the real `--pm-path` location instead of the hardcoded `.agents/pm` default. Mirrors how `pm schema add/remove-type` report their target path. */
|
|
119
119
|
export declare function resolveItemTypesFilePath(pmRoot: string, schema: RuntimeSchemaSettings): string;
|
|
120
|
-
/**
|
|
120
|
+
/** Publish missing schema seeds without overwriting definitions created by a concurrent reader or schema mutation. */
|
|
121
121
|
export declare function ensureRuntimeSchemaFileScaffold(pmRoot: string, schema: RuntimeSchemaSettings): Promise<RuntimeSchemaFileBootstrapResult>;
|
|
122
122
|
/** Implements load runtime schema from optional files for the public runtime surface of this module. */
|
|
123
123
|
export declare function loadRuntimeSchemaFromOptionalFiles(pmRoot: string, schema: RuntimeSchemaSettings): Promise<LoadedRuntimeSchemaSections>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="87798e93-c34c-5355-aa60-695fb9e3eef1")}catch(e2){}})();import path from"node:path";import{pathExists,readFileIfExists,writeFileAtomic}from"../fs/fs-utils.js";import{DEFAULT_STATUS_DEFINITIONS,DEFAULT_WORKFLOW_DEFINITION}from"../shared/constants.js";import{RUNTIME_FIELD_COMMAND_VALUES,RUNTIME_FIELD_TYPE_VALUES,RUNTIME_STATUS_ROLE_VALUES,RUNTIME_UNKNOWN_FIELD_POLICY_VALUES,STATUS_VALUES}from"../../types/index.js";import{normalizeStatusToken}from"./status-token.js";const DEFAULT_RUNTIME_SCHEMA_FILE_PATHS=Object.freeze({types:"schema/types.json",statuses:"schema/statuses.json",fields:"schema/fields.json",workflows:"schema/workflows.json"});const DEFAULT_RUNTIME_WORKFLOW=DEFAULT_WORKFLOW_DEFINITION;const DEFAULT_RUNTIME_STATUS_DEFINITIONS=DEFAULT_STATUS_DEFINITIONS;const DEFAULT_RUNTIME_FIELD_COMMANDS=["create","update"];const RUNTIME_STATUS_ROLE_SET=new Set(RUNTIME_STATUS_ROLE_VALUES);const RUNTIME_FIELD_TYPE_SET=new Set(RUNTIME_FIELD_TYPE_VALUES);const RUNTIME_FIELD_COMMAND_SET=new Set(RUNTIME_FIELD_COMMAND_VALUES);const RUNTIME_UNKNOWN_FIELD_POLICY_SET=new Set(RUNTIME_UNKNOWN_FIELD_POLICY_VALUES);const RUNTIME_FIELD_VALUE_TYPE_SET=new Set(["string","number","boolean","array","object"]);const MAX_RUNTIME_FIELD_VALUE_SCHEMA_DEPTH=16;function isPlainObject(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}const RUNTIME_FIELD_VALUE_SCHEMA_SHAPE_VALIDATORS=[schema=>schema.type===void 0||typeof schema.type==="string"&&RUNTIME_FIELD_VALUE_TYPE_SET.has(schema.type),schema=>!Object.hasOwn(schema,"const")||isStructuredJsonValue(schema.const),schema=>schema.enum===void 0||Array.isArray(schema.enum)&&schema.enum.every(entry=>isStructuredJsonValue(entry)),schema=>schema.min_length===void 0||Number.isInteger(schema.min_length)&&schema.min_length>=0,schema=>schema.min_items===void 0||Number.isInteger(schema.min_items)&&schema.min_items>=0,schema=>schema.format===void 0||schema.format==="date-time",schema=>schema.required===void 0||Array.isArray(schema.required)&&schema.required.every(entry=>typeof entry==="string"&&entry.length>0),schema=>schema.additional_properties===void 0||typeof schema.additional_properties==="boolean",schema=>schema.properties===void 0||isPlainObject(schema.properties),schema=>schema.one_of===void 0||Array.isArray(schema.one_of)&&schema.one_of.length>0];function isStructuredJsonValue(value,ancestors=new Set){if(value===null||typeof value==="string"||typeof value==="boolean"){return true}if(typeof value==="number")return Number.isFinite(value);if(typeof value!=="object"||ancestors.has(value))return false;ancestors.add(value);const valid=Array.isArray(value)?value.every(entry=>isStructuredJsonValue(entry,ancestors)):Object.values(value).every(entry=>isStructuredJsonValue(entry,ancestors));ancestors.delete(value);return valid}function normalizeRuntimeFieldValueSchema(value,depth=0,ancestors=new Set){if(!isPlainObject(value)||depth>MAX_RUNTIME_FIELD_VALUE_SCHEMA_DEPTH||ancestors.has(value)){return void 0}ancestors.add(value);const schema=value;const type=schema.type;const enumValues=schema.enum;const oneOf=schema.one_of;const properties=schema.properties;const items=schema.items;const required=schema.required;const minLength=schema.min_length;const minItems=schema.min_items;const format=schema.format;const additionalProperties=schema.additional_properties;if(!RUNTIME_FIELD_VALUE_SCHEMA_SHAPE_VALIDATORS.every(check=>check(schema))){ancestors.delete(value);return void 0}const normalizedProperties=properties===void 0?void 0:Object.fromEntries(Object.entries(properties).map(([key,entry])=>[key,normalizeRuntimeFieldValueSchema(entry,depth+1,ancestors)]));const normalizedItems=items===void 0?void 0:normalizeRuntimeFieldValueSchema(items,depth+1,ancestors);const normalizedOneOf=oneOf===void 0?void 0:oneOf.map(entry=>normalizeRuntimeFieldValueSchema(entry,depth+1,ancestors));const normalizedNestedSchemas=[...Object.values(normalizedProperties??{}),...items===void 0?[]:[normalizedItems],...normalizedOneOf??[]];if(normalizedNestedSchemas.some(entry=>entry===void 0)){ancestors.delete(value);return void 0}ancestors.delete(value);return Object.fromEntries(Object.entries({type,const:Object.hasOwn(schema,"const")?schema.const:void 0,enum:enumValues,min_length:minLength,min_items:minItems,format,properties:normalizedProperties,required:required===void 0?void 0:[...new Set(required)],additional_properties:additionalProperties,items:normalizedItems,one_of:normalizedOneOf}).filter(([,entry])=>entry!==void 0))}function normalizeStringList(values){const candidates=Array.isArray(values)?values:[];return[...new Set(candidates.map(value=>typeof value==="string"?value.trim():"").filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeStatusId(value){if(typeof value!=="string"||value.length===0){return void 0}const normalized=normalizeStatusToken(value);return normalized.length>0?normalized:void 0}function stripFlagPrefix(value){return value.startsWith("--")?value.slice(2):value}function normalizeCliToken(value){return typeof value==="string"?stripFlagPrefix(value.trim().toLowerCase().replaceAll(/[\s_]+/g,"-")):""}function keyToDefaultCliFlag(value){return value.replaceAll("_","-")}function toCamelCase(input){const segments=input.replaceAll(/[^A-Za-z0-9]+/g," ").trim().split(/\s+/).filter(segment=>segment.length>0).map(segment=>segment.toLowerCase());if(segments.length===0){return input}const[first,...rest]=segments;return`${first}${rest.map(segment=>`${segment.slice(0,1).toUpperCase()}${segment.slice(1)}`).join("")}`}function normalizeRuntimeStatusDefinition(definition,fallbackOrder){const id=normalizeStatusId(definition.id);if(!id){return null}const aliases=[...new Set(normalizeStringList(definition.aliases).map(normalizeStatusToken).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right));const roles=normalizeStringList(definition.roles).filter(value=>RUNTIME_STATUS_ROLE_SET.has(value));const description=definition.description?.trim();const order=typeof definition.order==="number"&&Number.isFinite(definition.order)?definition.order:fallbackOrder;return{id,aliases,roles,description:description&&description.length>0?description:void 0,order}}function normalizeRuntimeWorkflow(workflow){return{draft_status:normalizeStatusId(workflow?.draft_status),open_status:normalizeStatusId(workflow?.open_status),in_progress_status:normalizeStatusId(workflow?.in_progress_status),blocked_status:normalizeStatusId(workflow?.blocked_status),close_status:normalizeStatusId(workflow?.close_status),canceled_status:normalizeStatusId(workflow?.canceled_status)}}function appendTypeWorkflowPair(record,pair){if(!Array.isArray(pair)||pair.length!==2){return}const from=normalizeStatusToken(pair[0]);const to=normalizeStatusToken(pair[1]);if(from.length===0||to.length===0){return}if(record.pairs.some(candidate=>candidate[0]===from&&candidate[1]===to)){return}record.pairs.push([from,to])}function normalizedTypeWorkflowEntry(entry){const rawType=typeof entry?.type==="string"?entry.type.trim():"";if(rawType.length===0||!Array.isArray(entry?.allowed_transitions)){return null}const record={type:rawType,pairs:[],denyAll:entry.allowed_transitions.length===0};for(const pair of entry.allowed_transitions){appendTypeWorkflowPair(record,pair)}return{typeKey:rawType.toLowerCase(),record}}function normalizeTypeWorkflowDefinitions(workflows){if(!Array.isArray(workflows)||workflows.length===0){return void 0}const byTypeKey=new Map;for(const entry of workflows){const normalized2=normalizedTypeWorkflowEntry(entry);if(normalized2===null){continue}const record=byTypeKey.get(normalized2.typeKey)??normalized2.record;record.denyAll||=normalized2.record.denyAll;for(const pair of normalized2.record.pairs){appendTypeWorkflowPair(record,pair)}byTypeKey.set(normalized2.typeKey,record)}const normalized=[];for(const record of byTypeKey.values()){if(record.pairs.length>0||record.denyAll){normalized.push({type:record.type,allowed_transitions:record.pairs})}}normalized.sort((left,right)=>left.type.localeCompare(right.type));return normalized.length>0?normalized:void 0}function normalizeRuntimeFieldDefinition(definition){const key=normalizeStatusToken(definition.key??"");if(!key){return null}const metadataKey=normalizeStatusToken(definition.metadata_key??definition.front_matter_key??key);const cliFlag=normalizeCliToken(definition.cli_flag??keyToDefaultCliFlag(key));if(!cliFlag){return null}const cliAliases=normalizeStringList(definition.cli_aliases).map(value=>normalizeCliToken(value)).filter(value=>value.length>0&&value!==cliFlag);const typeCandidate=typeof definition.type==="string"?definition.type.trim().toLowerCase():"string";const type=RUNTIME_FIELD_TYPE_SET.has(typeCandidate)?typeCandidate:"string";const commands=(()=>{const normalized=normalizeStringList(definition.commands).filter(value=>RUNTIME_FIELD_COMMAND_SET.has(value));if(normalized.length>0){return normalized}return[...DEFAULT_RUNTIME_FIELD_COMMANDS]})();const description=definition.description?.trim();const requiredTypes=normalizeStringList(definition.required_types);const valueSchema=definition.value_schema===void 0?void 0:normalizeRuntimeFieldValueSchema(definition.value_schema);if(definition.value_schema!==void 0&&valueSchema===void 0){return null}return{key,metadata_key:metadataKey,cli_flag:cliFlag,cli_aliases:cliAliases,description:description&&description.length>0?description:void 0,type,commands,repeatable:[definition.repeatable===true,type==="string_array"].includes(true),required:definition.required===true,required_on_create:definition.required_on_create===true,required_types:requiredTypes,allow_unset:definition.allow_unset!==false,value_schema:valueSchema}}function normalizeRuntimeStatusDefinitions(statusesSource){const dedupedById=new Map;for(const[index,definition]of statusesSource.entries()){const normalized=normalizeRuntimeStatusDefinition(definition,index);if(normalized){dedupedById.set(normalized.id,normalized)}}const values=sortRuntimeStatusDefinitions([...dedupedById.values()]);if(values.length>0){return values}return sortRuntimeStatusDefinitions(DEFAULT_RUNTIME_STATUS_DEFINITIONS.map((definition,index)=>normalizeRuntimeStatusDefinition(definition,index)).filter(definition=>definition!==null))}function sortRuntimeStatusDefinitions(definitions){return definitions.sort((left,right)=>left.order===right.order?left.id.localeCompare(right.id):left.order-right.order)}function normalizeRuntimeFieldDefinitions(fieldsSource){const dedupedByKey=new Map;for(const definition of fieldsSource??[]){const normalized=normalizeRuntimeFieldDefinition(definition);if(normalized){dedupedByKey.set(normalized.key,normalized)}}return[...dedupedByKey.values()].sort((left,right)=>left.key.localeCompare(right.key))}function serializeRuntimeStatusDefinition(definition){return{id:definition.id,aliases:definition.aliases.length>0?[...definition.aliases]:void 0,roles:definition.roles.length>0?[...definition.roles]:void 0,description:definition.description,order:definition.order}}function serializeRuntimeFieldDefinition(definition){return{key:definition.key,metadata_key:definition.metadata_key!==definition.key?definition.metadata_key:void 0,cli_flag:definition.cli_flag!==keyToDefaultCliFlag(definition.key)?definition.cli_flag:void 0,cli_aliases:definition.cli_aliases.length>0?[...definition.cli_aliases]:void 0,description:definition.description,type:definition.type,commands:[...definition.commands],repeatable:definition.repeatable===true?true:void 0,required:definition.required===true?true:void 0,required_on_create:definition.required_on_create===true?true:void 0,required_types:definition.required_types.length>0?[...definition.required_types]:void 0,allow_unset:definition.allow_unset===false?false:void 0,value_schema:definition.value_schema}}function normalizeUnknownFieldPolicy(policy){const candidate=typeof policy==="string"?policy.trim().toLowerCase():"allow";return RUNTIME_UNKNOWN_FIELD_POLICY_SET.has(candidate)?candidate:"allow"}function normalizeRuntimeSchemaSettings(schema){const files={...DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,...schema?.files};const statusesSource=schema?.statuses&&schema.statuses.length>0?schema.statuses:DEFAULT_RUNTIME_STATUS_DEFINITIONS;const normalizedStatuses=normalizeRuntimeStatusDefinitions(statusesSource);const normalizedFields=normalizeRuntimeFieldDefinitions(schema?.fields);return{version:typeof schema?.version==="number"&&Number.isFinite(schema.version)?Math.floor(schema.version):1,files,statuses:normalizedStatuses.map(serializeRuntimeStatusDefinition),fields:normalizedFields.map(serializeRuntimeFieldDefinition),workflow:{...DEFAULT_RUNTIME_WORKFLOW,...normalizeRuntimeWorkflow(schema?.workflow)},type_workflows:normalizeTypeWorkflowDefinitions(schema?.type_workflows),unknown_field_policy:normalizeUnknownFieldPolicy(schema?.unknown_field_policy)}}function serializeJson(value){return`${JSON.stringify(value,null,2)}
|
|
2
|
-
`}function buildTypesFileSeed(){return{definitions:[]}}function buildStatusesFileSeed(){return{statuses:DEFAULT_RUNTIME_STATUS_DEFINITIONS}}function buildFieldsFileSeed(){return{fields:[]}}function buildWorkflowsFileSeed(){return{workflow:DEFAULT_RUNTIME_WORKFLOW}}function parseOptionalJson(raw,warningKey,warnings){try{return JSON.parse(raw)}catch{warnings.push(warningKey);return void 0}}function readTypeDefinitionsFromSchemaFile(parsed){if(Array.isArray(parsed)){return parsed}if(typeof parsed!=="object"||parsed===null){return void 0}const record=parsed;if(Array.isArray(record.definitions)){return record.definitions}if(typeof record.item_types==="object"&&record.item_types!==null){const itemTypesRecord=record.item_types;if(Array.isArray(itemTypesRecord.definitions)){return itemTypesRecord.definitions}}return void 0}function readStatusesFromSchemaFile(parsed){if(Array.isArray(parsed)){return parsed}if(typeof parsed!=="object"||parsed===null){return void 0}const record=parsed;if(Array.isArray(record.statuses)){return record.statuses}if(Array.isArray(record.definitions)){return record.definitions}return void 0}function readFieldsFromSchemaFile(parsed){if(Array.isArray(parsed)){return parsed}if(typeof parsed!=="object"||parsed===null){return void 0}const record=parsed;if(Array.isArray(record.fields)){return record.fields}if(Array.isArray(record.definitions)){return record.definitions}return void 0}function readWorkflowFromSchemaFile(parsed){if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){return void 0}const record=parsed;if(typeof record.workflow==="object"&&record.workflow!==null&&!Array.isArray(record.workflow)){return record.workflow}if(typeof record.workflows==="object"&&record.workflows!==null&&!Array.isArray(record.workflows)){return record.workflows}return record}function readTypeWorkflowsFromSchemaFile(parsed){if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){return void 0}const record=parsed;if(Array.isArray(record.type_workflows)){return record.type_workflows}return void 0}function filePathForSchemaSection(pmRoot,configuredPath,fallbackPath){const normalized=configuredPath?.trim()||fallbackPath;if(path.isAbsolute(normalized)){return normalized}return path.join(pmRoot,normalized)}function resolveItemTypesFilePath(pmRoot,schema){return filePathForSchemaSection(pmRoot,schema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types)}async function ensureRuntimeSchemaFileScaffold(pmRoot,schema){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);const specs=[{path:filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types),seed:buildTypesFileSeed()},{path:filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses),seed:buildStatusesFileSeed()},{path:filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields),seed:buildFieldsFileSeed()},{path:filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows),seed:buildWorkflowsFileSeed()}];const createdPaths=[];for(const spec of specs){if(await pathExists(spec.path)){continue}await writeFileAtomic(spec.path,serializeJson(spec.seed));createdPaths.push(spec.path)}return{created_paths:createdPaths}}async function loadRuntimeSchemaFromOptionalFiles(pmRoot,schema){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);const warnings=[];const typeFilePath=filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types);const statusFilePath=filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses);const fieldsFilePath=filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields);const workflowsFilePath=filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows);let loadedTypeDefinitions;let loadedStatuses;let loadedFields;let loadedWorkflow;let loadedTypeWorkflows;const readAndParse=async(targetPath,warningKey)=>{const raw=await readFileIfExists(targetPath);if(raw===null){return void 0}return parseOptionalJson(raw,warningKey,warnings)};const parsedTypes=await readAndParse(typeFilePath,"runtime_schema_types_invalid_json");if(parsedTypes!==void 0){loadedTypeDefinitions=readTypeDefinitionsFromSchemaFile(parsedTypes);if(loadedTypeDefinitions===void 0){warnings.push("runtime_schema_types_invalid_shape")}}const parsedStatuses=await readAndParse(statusFilePath,"runtime_schema_statuses_invalid_json");if(parsedStatuses!==void 0){loadedStatuses=readStatusesFromSchemaFile(parsedStatuses);if(loadedStatuses===void 0){warnings.push("runtime_schema_statuses_invalid_shape")}}const parsedFields=await readAndParse(fieldsFilePath,"runtime_schema_fields_invalid_json");if(parsedFields!==void 0){loadedFields=readFieldsFromSchemaFile(parsedFields);if(loadedFields===void 0){warnings.push("runtime_schema_fields_invalid_shape")}}const parsedWorkflow=await readAndParse(workflowsFilePath,"runtime_schema_workflows_invalid_json");if(parsedWorkflow!==void 0){loadedWorkflow=readWorkflowFromSchemaFile(parsedWorkflow);if(loadedWorkflow===void 0){warnings.push("runtime_schema_workflows_invalid_shape")}loadedTypeWorkflows=readTypeWorkflowsFromSchemaFile(parsedWorkflow)}const mergedSchema=normalizeRuntimeSchemaSettings({...normalizedSchema,statuses:[...normalizedSchema.statuses,...loadedStatuses??[]],fields:[...normalizedSchema.fields,...loadedFields??[]],workflow:{...normalizedSchema.workflow,...loadedWorkflow},type_workflows:[...normalizedSchema.type_workflows??[],...loadedTypeWorkflows??[]]});return{schema:mergedSchema,type_definitions_from_file:loadedTypeDefinitions,warnings,created_paths:[]}}function preferredStatusForRole(definitions,role,fallbackValues,fallbackFirst=false){const normalizedFallbacks=fallbackValues.map(value=>normalizeStatusId(value)).filter(value=>typeof value==="string");const fallbackMatch=normalizedFallbacks.find(normalized=>definitions.some(definition=>definition.id===normalized));if(fallbackFirst&&fallbackMatch!==void 0){return fallbackMatch}const withRole=definitions.find(definition=>definition.roles.includes(role));if(withRole!==void 0){return withRole.id}return fallbackMatch??definitions[0]?.id}function buildRuntimeStatusIndexes(definitions){const aliasToId=new Map;const byId=new Map;for(const definition of definitions){byId.set(definition.id,definition);aliasToId.set(definition.id,definition.id);aliasToId.set(definition.id.replaceAll("_","-"),definition.id);aliasToId.set(definition.id.replaceAll("_"," "),definition.id);for(const alias of definition.aliases){aliasToId.set(alias,definition.id);aliasToId.set(alias.replaceAll("_","-"),definition.id);aliasToId.set(alias.replaceAll("_"," "),definition.id)}}return{aliasToId,byId}}function buildRuntimeStatusRoleSets(definitions){const result={activeStatuses:new Set,blockedStatuses:new Set,draftStatuses:new Set,terminalCanceledStatuses:new Set,terminalDoneStatuses:new Set,terminalStatuses:new Set};for(const definition of definitions){const roles=new Set(definition.roles);if(roles.has("terminal")||roles.has("terminal_done")||roles.has("terminal_canceled")){result.terminalStatuses.add(definition.id)}if(roles.has("terminal_done"))result.terminalDoneStatuses.add(definition.id);if(roles.has("terminal_canceled")){result.terminalCanceledStatuses.add(definition.id)}if(roles.has("active"))result.activeStatuses.add(definition.id);if(roles.has("blocked"))result.blockedStatuses.add(definition.id);if(roles.has("draft"))result.draftStatuses.add(definition.id)}return result}function resolveRuntimeStatusRegistry(schema){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);const definitions=normalizedSchema.statuses.map((definition,index)=>normalizeRuntimeStatusDefinition(definition,index)).filter(definition=>definition!==null);const{aliasToId,byId}=buildRuntimeStatusIndexes(definitions);const{activeStatuses,blockedStatuses,draftStatuses,terminalCanceledStatuses,terminalDoneStatuses,terminalStatuses}=buildRuntimeStatusRoleSets(definitions);const workflow=normalizedSchema.workflow;const openStatus=normalizeStatusId(workflow.open_status)??preferredStatusForRole(definitions,"default_open",["open","in_progress",STATUS_VALUES[0]]);const inProgressStatus=normalizeStatusId(workflow.in_progress_status)??preferredStatusForRole(definitions,"active",["in_progress","in-progress",openStatus],true);const blockedStatus=normalizeStatusId(workflow.blocked_status)??preferredStatusForRole(definitions,"blocked",["blocked"]);const closeStatus=normalizeStatusId(workflow.close_status)??preferredStatusForRole(definitions,"default_close",["closed","done","complete"]);const canceledStatus=normalizeStatusId(workflow.canceled_status)??preferredStatusForRole(definitions,"default_cancel",["canceled","cancelled"]);return{definitions,by_id:byId,alias_to_id:aliasToId,terminal_statuses:terminalStatuses,terminal_done_statuses:terminalDoneStatuses,terminal_canceled_statuses:terminalCanceledStatuses,active_statuses:activeStatuses,blocked_statuses:blockedStatuses,draft_statuses:draftStatuses,open_status:openStatus,in_progress_status:inProgressStatus,blocked_status:blockedStatus,close_status:closeStatus,canceled_status:canceledStatus}}function normalizeStatusInputWithRegistry(value,registry){const normalized=normalizeStatusToken(value);if(!normalized){return void 0}return registry.alias_to_id.get(normalized)}function resolveRuntimeFieldRegistry(schema){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);const dedupedByKey=new Map;const normalizedFields=normalizedSchema.fields.map(definition=>normalizeRuntimeFieldDefinition(definition)).filter(definition=>definition!==null);for(const normalized of normalizedFields){dedupedByKey.set(normalized.key,normalized)}const definitions=[...dedupedByKey.values()].sort((left,right)=>left.key.localeCompare(right.key));const byKey=new Map;const byCliToken=new Map;const commandToFields=new Map;for(const definition of definitions){byKey.set(definition.key,definition);byCliToken.set(definition.cli_flag,definition);for(const alias of definition.cli_aliases){byCliToken.set(alias,definition)}for(const command of definition.commands){const existing=commandToFields.get(command)??[];existing.push(definition);commandToFields.set(command,existing)}}for(const[command,fieldDefinitions]of commandToFields.entries()){fieldDefinitions.sort((left,right)=>left.key.localeCompare(right.key));commandToFields.set(command,fieldDefinitions)}return{definitions,by_key:byKey,by_cli_token:byCliToken,command_to_fields:commandToFields}}function runtimeFieldOptionTarget(field){return toCamelCase(field.key)}function statusIsTerminal(status,registry){const normalized=normalizeStatusInputWithRegistry(status,registry);if(!normalized){return false}return registry.terminal_statuses.has(normalized)}export{DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,DEFAULT_RUNTIME_STATUS_DEFINITIONS,DEFAULT_RUNTIME_WORKFLOW,ensureRuntimeSchemaFileScaffold,filePathForSchemaSection,loadRuntimeSchemaFromOptionalFiles,normalizeRuntimeSchemaSettings,normalizeStatusInputWithRegistry,resolveItemTypesFilePath,resolveRuntimeFieldRegistry,resolveRuntimeStatusRegistry,runtimeFieldOptionTarget,statusIsTerminal};
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5e083565-3e07-5fb3-81ce-c392feaa8630")}catch(e2){}})();import path from"node:path";import{pathExists,readFileIfExists}from"../fs/fs-utils.js";import{createFileAtomic}from"../fs/atomic-create.js";import{DEFAULT_STATUS_DEFINITIONS,DEFAULT_WORKFLOW_DEFINITION}from"../shared/constants.js";import{RUNTIME_FIELD_COMMAND_VALUES,RUNTIME_FIELD_TYPE_VALUES,RUNTIME_STATUS_ROLE_VALUES,RUNTIME_UNKNOWN_FIELD_POLICY_VALUES,STATUS_VALUES}from"../../types/index.js";import{normalizeStatusToken}from"./status-token.js";const DEFAULT_RUNTIME_SCHEMA_FILE_PATHS=Object.freeze({types:"schema/types.json",statuses:"schema/statuses.json",fields:"schema/fields.json",workflows:"schema/workflows.json"});const DEFAULT_RUNTIME_WORKFLOW=DEFAULT_WORKFLOW_DEFINITION;const DEFAULT_RUNTIME_STATUS_DEFINITIONS=DEFAULT_STATUS_DEFINITIONS;const DEFAULT_RUNTIME_FIELD_COMMANDS=["create","update"];const RUNTIME_STATUS_ROLE_SET=new Set(RUNTIME_STATUS_ROLE_VALUES);const RUNTIME_FIELD_TYPE_SET=new Set(RUNTIME_FIELD_TYPE_VALUES);const RUNTIME_FIELD_COMMAND_SET=new Set(RUNTIME_FIELD_COMMAND_VALUES);const RUNTIME_UNKNOWN_FIELD_POLICY_SET=new Set(RUNTIME_UNKNOWN_FIELD_POLICY_VALUES);const RUNTIME_FIELD_VALUE_TYPE_SET=new Set(["string","number","boolean","array","object"]);const MAX_RUNTIME_FIELD_VALUE_SCHEMA_DEPTH=16;function isPlainObject(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}const RUNTIME_FIELD_VALUE_SCHEMA_SHAPE_VALIDATORS=[schema=>schema.type===void 0||typeof schema.type==="string"&&RUNTIME_FIELD_VALUE_TYPE_SET.has(schema.type),schema=>!Object.hasOwn(schema,"const")||isStructuredJsonValue(schema.const),schema=>schema.enum===void 0||Array.isArray(schema.enum)&&schema.enum.every(entry=>isStructuredJsonValue(entry)),schema=>schema.min_length===void 0||Number.isInteger(schema.min_length)&&schema.min_length>=0,schema=>schema.min_items===void 0||Number.isInteger(schema.min_items)&&schema.min_items>=0,schema=>schema.format===void 0||schema.format==="date-time",schema=>schema.required===void 0||Array.isArray(schema.required)&&schema.required.every(entry=>typeof entry==="string"&&entry.length>0),schema=>schema.additional_properties===void 0||typeof schema.additional_properties==="boolean",schema=>schema.properties===void 0||isPlainObject(schema.properties),schema=>schema.one_of===void 0||Array.isArray(schema.one_of)&&schema.one_of.length>0];function isStructuredJsonValue(value,ancestors=new Set){if(value===null||typeof value==="string"||typeof value==="boolean"){return true}if(typeof value==="number")return Number.isFinite(value);if(typeof value!=="object"||ancestors.has(value))return false;ancestors.add(value);const valid=Array.isArray(value)?value.every(entry=>isStructuredJsonValue(entry,ancestors)):Object.values(value).every(entry=>isStructuredJsonValue(entry,ancestors));ancestors.delete(value);return valid}function normalizeRuntimeFieldValueSchema(value,depth=0,ancestors=new Set){if(!isPlainObject(value)||depth>MAX_RUNTIME_FIELD_VALUE_SCHEMA_DEPTH||ancestors.has(value)){return void 0}ancestors.add(value);const schema=value;const type=schema.type;const enumValues=schema.enum;const oneOf=schema.one_of;const properties=schema.properties;const items=schema.items;const required=schema.required;const minLength=schema.min_length;const minItems=schema.min_items;const format=schema.format;const additionalProperties=schema.additional_properties;if(!RUNTIME_FIELD_VALUE_SCHEMA_SHAPE_VALIDATORS.every(check=>check(schema))){ancestors.delete(value);return void 0}const normalizedProperties=properties===void 0?void 0:Object.fromEntries(Object.entries(properties).map(([key,entry])=>[key,normalizeRuntimeFieldValueSchema(entry,depth+1,ancestors)]));const normalizedItems=items===void 0?void 0:normalizeRuntimeFieldValueSchema(items,depth+1,ancestors);const normalizedOneOf=oneOf===void 0?void 0:oneOf.map(entry=>normalizeRuntimeFieldValueSchema(entry,depth+1,ancestors));const normalizedNestedSchemas=[...Object.values(normalizedProperties??{}),...items===void 0?[]:[normalizedItems],...normalizedOneOf??[]];if(normalizedNestedSchemas.some(entry=>entry===void 0)){ancestors.delete(value);return void 0}ancestors.delete(value);return Object.fromEntries(Object.entries({type,const:Object.hasOwn(schema,"const")?schema.const:void 0,enum:enumValues,min_length:minLength,min_items:minItems,format,properties:normalizedProperties,required:required===void 0?void 0:[...new Set(required)],additional_properties:additionalProperties,items:normalizedItems,one_of:normalizedOneOf}).filter(([,entry])=>entry!==void 0))}function normalizeStringList(values){const candidates=Array.isArray(values)?values:[];return[...new Set(candidates.map(value=>typeof value==="string"?value.trim():"").filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeStatusId(value){if(typeof value!=="string"||value.length===0){return void 0}const normalized=normalizeStatusToken(value);return normalized.length>0?normalized:void 0}function stripFlagPrefix(value){return value.startsWith("--")?value.slice(2):value}function normalizeCliToken(value){return typeof value==="string"?stripFlagPrefix(value.trim().toLowerCase().replaceAll(/[\s_]+/g,"-")):""}function keyToDefaultCliFlag(value){return value.replaceAll("_","-")}function toCamelCase(input){const segments=input.replaceAll(/[^A-Za-z0-9]+/g," ").trim().split(/\s+/).filter(segment=>segment.length>0).map(segment=>segment.toLowerCase());if(segments.length===0){return input}const[first,...rest]=segments;return`${first}${rest.map(segment=>`${segment.slice(0,1).toUpperCase()}${segment.slice(1)}`).join("")}`}function normalizeRuntimeStatusDefinition(definition,fallbackOrder){const id=normalizeStatusId(definition.id);if(!id){return null}const aliases=[...new Set(normalizeStringList(definition.aliases).map(normalizeStatusToken).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right));const roles=normalizeStringList(definition.roles).filter(value=>RUNTIME_STATUS_ROLE_SET.has(value));const description=definition.description?.trim();const order=typeof definition.order==="number"&&Number.isFinite(definition.order)?definition.order:fallbackOrder;return{id,aliases,roles,description:description&&description.length>0?description:void 0,order}}function normalizeRuntimeWorkflow(workflow){return{draft_status:normalizeStatusId(workflow?.draft_status),open_status:normalizeStatusId(workflow?.open_status),in_progress_status:normalizeStatusId(workflow?.in_progress_status),blocked_status:normalizeStatusId(workflow?.blocked_status),close_status:normalizeStatusId(workflow?.close_status),canceled_status:normalizeStatusId(workflow?.canceled_status)}}function appendTypeWorkflowPair(record,pair){if(!Array.isArray(pair)||pair.length!==2){return}const from=normalizeStatusToken(pair[0]);const to=normalizeStatusToken(pair[1]);if(from.length===0||to.length===0){return}if(record.pairs.some(candidate=>candidate[0]===from&&candidate[1]===to)){return}record.pairs.push([from,to])}function normalizedTypeWorkflowEntry(entry){const rawType=typeof entry?.type==="string"?entry.type.trim():"";if(rawType.length===0||!Array.isArray(entry?.allowed_transitions)){return null}const record={type:rawType,pairs:[],denyAll:entry.allowed_transitions.length===0};for(const pair of entry.allowed_transitions){appendTypeWorkflowPair(record,pair)}return{typeKey:rawType.toLowerCase(),record}}function normalizeTypeWorkflowDefinitions(workflows){if(!Array.isArray(workflows)||workflows.length===0){return void 0}const byTypeKey=new Map;for(const entry of workflows){const normalized2=normalizedTypeWorkflowEntry(entry);if(normalized2===null){continue}const record=byTypeKey.get(normalized2.typeKey)??normalized2.record;record.denyAll||=normalized2.record.denyAll;for(const pair of normalized2.record.pairs){appendTypeWorkflowPair(record,pair)}byTypeKey.set(normalized2.typeKey,record)}const normalized=[];for(const record of byTypeKey.values()){if(record.pairs.length>0||record.denyAll){normalized.push({type:record.type,allowed_transitions:record.pairs})}}normalized.sort((left,right)=>left.type.localeCompare(right.type));return normalized.length>0?normalized:void 0}function normalizeRuntimeFieldDefinition(definition){const key=normalizeStatusToken(definition.key??"");if(!key){return null}const metadataKey=normalizeStatusToken(definition.metadata_key??definition.front_matter_key??key);const cliFlag=normalizeCliToken(definition.cli_flag??keyToDefaultCliFlag(key));if(!cliFlag){return null}const cliAliases=normalizeStringList(definition.cli_aliases).map(value=>normalizeCliToken(value)).filter(value=>value.length>0&&value!==cliFlag);const typeCandidate=typeof definition.type==="string"?definition.type.trim().toLowerCase():"string";const type=RUNTIME_FIELD_TYPE_SET.has(typeCandidate)?typeCandidate:"string";const commands=(()=>{const normalized=normalizeStringList(definition.commands).filter(value=>RUNTIME_FIELD_COMMAND_SET.has(value));if(normalized.length>0){return normalized}return[...DEFAULT_RUNTIME_FIELD_COMMANDS]})();const description=definition.description?.trim();const requiredTypes=normalizeStringList(definition.required_types);const valueSchema=definition.value_schema===void 0?void 0:normalizeRuntimeFieldValueSchema(definition.value_schema);if(definition.value_schema!==void 0&&valueSchema===void 0){return null}return{key,metadata_key:metadataKey,cli_flag:cliFlag,cli_aliases:cliAliases,description:description&&description.length>0?description:void 0,type,commands,repeatable:[definition.repeatable===true,type==="string_array"].includes(true),required:definition.required===true,required_on_create:definition.required_on_create===true,required_types:requiredTypes,allow_unset:definition.allow_unset!==false,value_schema:valueSchema}}function normalizeRuntimeStatusDefinitions(statusesSource){const dedupedById=new Map;for(const[index,definition]of statusesSource.entries()){const normalized=normalizeRuntimeStatusDefinition(definition,index);if(normalized){dedupedById.set(normalized.id,normalized)}}const values=sortRuntimeStatusDefinitions([...dedupedById.values()]);if(values.length>0){return values}return sortRuntimeStatusDefinitions(DEFAULT_RUNTIME_STATUS_DEFINITIONS.map((definition,index)=>normalizeRuntimeStatusDefinition(definition,index)).filter(definition=>definition!==null))}function sortRuntimeStatusDefinitions(definitions){return definitions.sort((left,right)=>left.order===right.order?left.id.localeCompare(right.id):left.order-right.order)}function normalizeRuntimeFieldDefinitions(fieldsSource){const dedupedByKey=new Map;for(const definition of fieldsSource??[]){const normalized=normalizeRuntimeFieldDefinition(definition);if(normalized){dedupedByKey.set(normalized.key,normalized)}}return[...dedupedByKey.values()].sort((left,right)=>left.key.localeCompare(right.key))}function serializeRuntimeStatusDefinition(definition){return{id:definition.id,aliases:definition.aliases.length>0?[...definition.aliases]:void 0,roles:definition.roles.length>0?[...definition.roles]:void 0,description:definition.description,order:definition.order}}function serializeRuntimeFieldDefinition(definition){return{key:definition.key,metadata_key:definition.metadata_key!==definition.key?definition.metadata_key:void 0,cli_flag:definition.cli_flag!==keyToDefaultCliFlag(definition.key)?definition.cli_flag:void 0,cli_aliases:definition.cli_aliases.length>0?[...definition.cli_aliases]:void 0,description:definition.description,type:definition.type,commands:[...definition.commands],repeatable:definition.repeatable===true?true:void 0,required:definition.required===true?true:void 0,required_on_create:definition.required_on_create===true?true:void 0,required_types:definition.required_types.length>0?[...definition.required_types]:void 0,allow_unset:definition.allow_unset===false?false:void 0,value_schema:definition.value_schema}}function normalizeUnknownFieldPolicy(policy){const candidate=typeof policy==="string"?policy.trim().toLowerCase():"allow";return RUNTIME_UNKNOWN_FIELD_POLICY_SET.has(candidate)?candidate:"allow"}function normalizeRuntimeSchemaSettings(schema){const files={...DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,...schema?.files};const statusesSource=schema?.statuses&&schema.statuses.length>0?schema.statuses:DEFAULT_RUNTIME_STATUS_DEFINITIONS;const normalizedStatuses=normalizeRuntimeStatusDefinitions(statusesSource);const normalizedFields=normalizeRuntimeFieldDefinitions(schema?.fields);return{version:typeof schema?.version==="number"&&Number.isFinite(schema.version)?Math.floor(schema.version):1,files,statuses:normalizedStatuses.map(serializeRuntimeStatusDefinition),fields:normalizedFields.map(serializeRuntimeFieldDefinition),workflow:{...DEFAULT_RUNTIME_WORKFLOW,...normalizeRuntimeWorkflow(schema?.workflow)},type_workflows:normalizeTypeWorkflowDefinitions(schema?.type_workflows),unknown_field_policy:normalizeUnknownFieldPolicy(schema?.unknown_field_policy)}}function parseOptionalJson(raw,warningKey,warnings){try{return JSON.parse(raw)}catch{warnings.push(warningKey);return void 0}}function readTypeDefinitionsFromSchemaFile(parsed){if(Array.isArray(parsed)){return parsed}if(typeof parsed!=="object"||parsed===null){return void 0}const record=parsed;if(Array.isArray(record.definitions)){return record.definitions}if(typeof record.item_types==="object"&&record.item_types!==null){const itemTypesRecord=record.item_types;if(Array.isArray(itemTypesRecord.definitions)){return itemTypesRecord.definitions}}return void 0}function readStatusesFromSchemaFile(parsed){if(Array.isArray(parsed)){return parsed}if(typeof parsed!=="object"||parsed===null){return void 0}const record=parsed;if(Array.isArray(record.statuses)){return record.statuses}if(Array.isArray(record.definitions)){return record.definitions}return void 0}function readFieldsFromSchemaFile(parsed){if(Array.isArray(parsed)){return parsed}if(typeof parsed!=="object"||parsed===null){return void 0}const record=parsed;if(Array.isArray(record.fields)){return record.fields}if(Array.isArray(record.definitions)){return record.definitions}return void 0}function readWorkflowFromSchemaFile(parsed){if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){return void 0}const record=parsed;if(typeof record.workflow==="object"&&record.workflow!==null&&!Array.isArray(record.workflow)){return record.workflow}if(typeof record.workflows==="object"&&record.workflows!==null&&!Array.isArray(record.workflows)){return record.workflows}return record}function readTypeWorkflowsFromSchemaFile(parsed){if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){return void 0}const record=parsed;if(Array.isArray(record.type_workflows)){return record.type_workflows}return void 0}function filePathForSchemaSection(pmRoot,configuredPath,fallbackPath){const normalized=configuredPath?.trim()||fallbackPath;if(path.isAbsolute(normalized)){return normalized}return path.join(pmRoot,normalized)}function resolveItemTypesFilePath(pmRoot,schema){return filePathForSchemaSection(pmRoot,schema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types)}async function ensureRuntimeSchemaFileScaffold(pmRoot,schema){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);const specs=[{path:filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types),seed:{definitions:[]}},{path:filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses),seed:{statuses:DEFAULT_RUNTIME_STATUS_DEFINITIONS}},{path:filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields),seed:{fields:[]}},{path:filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows),seed:{workflow:DEFAULT_RUNTIME_WORKFLOW}}];const createdPaths=[];for(const spec of specs){if(await pathExists(spec.path)){continue}if(await createFileAtomic(spec.path,`${JSON.stringify(spec.seed,null,2)}
|
|
2
|
+
`)){createdPaths.push(spec.path)}}return{created_paths:createdPaths}}async function loadRuntimeSchemaFromOptionalFiles(pmRoot,schema){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);const warnings=[];const typeFilePath=filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types);const statusFilePath=filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses);const fieldsFilePath=filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields);const workflowsFilePath=filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows);let loadedTypeDefinitions;let loadedStatuses;let loadedFields;let loadedWorkflow;let loadedTypeWorkflows;const readAndParse=async(targetPath,warningKey)=>{const raw=await readFileIfExists(targetPath);if(raw===null){return void 0}return parseOptionalJson(raw,warningKey,warnings)};const parsedTypes=await readAndParse(typeFilePath,"runtime_schema_types_invalid_json");if(parsedTypes!==void 0){loadedTypeDefinitions=readTypeDefinitionsFromSchemaFile(parsedTypes);if(loadedTypeDefinitions===void 0){warnings.push("runtime_schema_types_invalid_shape")}}const parsedStatuses=await readAndParse(statusFilePath,"runtime_schema_statuses_invalid_json");if(parsedStatuses!==void 0){loadedStatuses=readStatusesFromSchemaFile(parsedStatuses);if(loadedStatuses===void 0){warnings.push("runtime_schema_statuses_invalid_shape")}}const parsedFields=await readAndParse(fieldsFilePath,"runtime_schema_fields_invalid_json");if(parsedFields!==void 0){loadedFields=readFieldsFromSchemaFile(parsedFields);if(loadedFields===void 0){warnings.push("runtime_schema_fields_invalid_shape")}}const parsedWorkflow=await readAndParse(workflowsFilePath,"runtime_schema_workflows_invalid_json");if(parsedWorkflow!==void 0){loadedWorkflow=readWorkflowFromSchemaFile(parsedWorkflow);if(loadedWorkflow===void 0){warnings.push("runtime_schema_workflows_invalid_shape")}loadedTypeWorkflows=readTypeWorkflowsFromSchemaFile(parsedWorkflow)}const mergedSchema=normalizeRuntimeSchemaSettings({...normalizedSchema,statuses:[...normalizedSchema.statuses,...loadedStatuses??[]],fields:[...normalizedSchema.fields,...loadedFields??[]],workflow:{...normalizedSchema.workflow,...loadedWorkflow},type_workflows:[...normalizedSchema.type_workflows??[],...loadedTypeWorkflows??[]]});return{schema:mergedSchema,type_definitions_from_file:loadedTypeDefinitions,warnings,created_paths:[]}}function preferredStatusForRole(definitions,role,fallbackValues,fallbackFirst=false){const normalizedFallbacks=fallbackValues.map(value=>normalizeStatusId(value)).filter(value=>typeof value==="string");const fallbackMatch=normalizedFallbacks.find(normalized=>definitions.some(definition=>definition.id===normalized));if(fallbackFirst&&fallbackMatch!==void 0){return fallbackMatch}const withRole=definitions.find(definition=>definition.roles.includes(role));if(withRole!==void 0){return withRole.id}return fallbackMatch??definitions[0]?.id}function buildRuntimeStatusIndexes(definitions){const aliasToId=new Map;const byId=new Map;for(const definition of definitions){byId.set(definition.id,definition);aliasToId.set(definition.id,definition.id);aliasToId.set(definition.id.replaceAll("_","-"),definition.id);aliasToId.set(definition.id.replaceAll("_"," "),definition.id);for(const alias of definition.aliases){aliasToId.set(alias,definition.id);aliasToId.set(alias.replaceAll("_","-"),definition.id);aliasToId.set(alias.replaceAll("_"," "),definition.id)}}return{aliasToId,byId}}function buildRuntimeStatusRoleSets(definitions){const result={activeStatuses:new Set,blockedStatuses:new Set,draftStatuses:new Set,terminalCanceledStatuses:new Set,terminalDoneStatuses:new Set,terminalStatuses:new Set};for(const definition of definitions){const roles=new Set(definition.roles);if(roles.has("terminal")||roles.has("terminal_done")||roles.has("terminal_canceled")){result.terminalStatuses.add(definition.id)}if(roles.has("terminal_done"))result.terminalDoneStatuses.add(definition.id);if(roles.has("terminal_canceled")){result.terminalCanceledStatuses.add(definition.id)}if(roles.has("active"))result.activeStatuses.add(definition.id);if(roles.has("blocked"))result.blockedStatuses.add(definition.id);if(roles.has("draft"))result.draftStatuses.add(definition.id)}return result}function resolveRuntimeStatusRegistry(schema){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);const definitions=normalizedSchema.statuses.map((definition,index)=>normalizeRuntimeStatusDefinition(definition,index)).filter(definition=>definition!==null);const{aliasToId,byId}=buildRuntimeStatusIndexes(definitions);const{activeStatuses,blockedStatuses,draftStatuses,terminalCanceledStatuses,terminalDoneStatuses,terminalStatuses}=buildRuntimeStatusRoleSets(definitions);const workflow=normalizedSchema.workflow;const openStatus=normalizeStatusId(workflow.open_status)??preferredStatusForRole(definitions,"default_open",["open","in_progress",STATUS_VALUES[0]]);const inProgressStatus=normalizeStatusId(workflow.in_progress_status)??preferredStatusForRole(definitions,"active",["in_progress","in-progress",openStatus],true);const blockedStatus=normalizeStatusId(workflow.blocked_status)??preferredStatusForRole(definitions,"blocked",["blocked"]);const closeStatus=normalizeStatusId(workflow.close_status)??preferredStatusForRole(definitions,"default_close",["closed","done","complete"]);const canceledStatus=normalizeStatusId(workflow.canceled_status)??preferredStatusForRole(definitions,"default_cancel",["canceled","cancelled"]);return{definitions,by_id:byId,alias_to_id:aliasToId,terminal_statuses:terminalStatuses,terminal_done_statuses:terminalDoneStatuses,terminal_canceled_statuses:terminalCanceledStatuses,active_statuses:activeStatuses,blocked_statuses:blockedStatuses,draft_statuses:draftStatuses,open_status:openStatus,in_progress_status:inProgressStatus,blocked_status:blockedStatus,close_status:closeStatus,canceled_status:canceledStatus}}function normalizeStatusInputWithRegistry(value,registry){const normalized=normalizeStatusToken(value);if(!normalized){return void 0}return registry.alias_to_id.get(normalized)}function resolveRuntimeFieldRegistry(schema){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);const dedupedByKey=new Map;const normalizedFields=normalizedSchema.fields.map(definition=>normalizeRuntimeFieldDefinition(definition)).filter(definition=>definition!==null);for(const normalized of normalizedFields){dedupedByKey.set(normalized.key,normalized)}const definitions=[...dedupedByKey.values()].sort((left,right)=>left.key.localeCompare(right.key));const byKey=new Map;const byCliToken=new Map;const commandToFields=new Map;for(const definition of definitions){byKey.set(definition.key,definition);byCliToken.set(definition.cli_flag,definition);for(const alias of definition.cli_aliases){byCliToken.set(alias,definition)}for(const command of definition.commands){const existing=commandToFields.get(command)??[];existing.push(definition);commandToFields.set(command,existing)}}for(const[command,fieldDefinitions]of commandToFields.entries()){fieldDefinitions.sort((left,right)=>left.key.localeCompare(right.key));commandToFields.set(command,fieldDefinitions)}return{definitions,by_key:byKey,by_cli_token:byCliToken,command_to_fields:commandToFields}}function runtimeFieldOptionTarget(field){return toCamelCase(field.key)}function statusIsTerminal(status,registry){const normalized=normalizeStatusInputWithRegistry(status,registry);if(!normalized){return false}return registry.terminal_statuses.has(normalized)}export{DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,DEFAULT_RUNTIME_STATUS_DEFINITIONS,DEFAULT_RUNTIME_WORKFLOW,ensureRuntimeSchemaFileScaffold,filePathForSchemaSection,loadRuntimeSchemaFromOptionalFiles,normalizeRuntimeSchemaSettings,normalizeStatusInputWithRegistry,resolveItemTypesFilePath,resolveRuntimeFieldRegistry,resolveRuntimeStatusRegistry,runtimeFieldOptionTarget,statusIsTerminal};
|
|
3
3
|
//# sourceMappingURL=runtime-schema.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8192f2f3-b5a0-510e-a7d4-963041cce389")}catch(e2){}})();import{createHash}from"node:crypto";import{existsSync,promises as fs,readFileSync}from"node:fs";import path from"node:path";import{writeFileAtomic}from"../fs/fs-utils.js";import{acquireLock}from"../lock/lock.js";import{SETTINGS_DEFAULTS}from"../shared/constants.js";import{getRuntimePath}from"../store/paths.js";const SESSION_FILENAME="session.json";function isBoundedNonEmptyString(value,maximum){return typeof value==="string"&&value.length>0&&value.length<=maximum}function parseSemanticAttribution(value){if(value===null||typeof value!=="object"||Array.isArray(value)){return void 0}const record=value;const validRole=["implementer","planner","release-operator"].includes(String(record.role));const validConfidence=["high","medium"].includes(String(record.confidence));const validTopic=isBoundedNonEmptyString(record.topic,256);const validEvidence=Array.isArray(record.evidence)&&record.evidence.length<=32&&record.evidence.every(entry=>typeof entry==="string"&&entry.length<=128);const validActiveItems=Array.isArray(record.active_item_ids)&&record.active_item_ids.length<=64&&record.active_item_ids.every(entry=>isBoundedNonEmptyString(entry,128));const validFocus=record.focused_item_id===void 0||isBoundedNonEmptyString(record.focused_item_id,128);if(![validRole,validConfidence,validTopic,validEvidence,validActiveItems,validFocus,record.rule_version==="v2"].every(Boolean)){return void 0}return record}function parseSemanticAttributionMap(value){if(value===null||typeof value!=="object"||Array.isArray(value)){return void 0}const entries=Object.entries(value).slice(0,128).flatMap(([key,attribution])=>{const parsed=parseSemanticAttribution(attribution);return parsed&&key.length<=128?[[key,parsed]]:[]});return entries.length>0?Object.fromEntries(entries):void 0}function getSessionStatePath(pmRoot){return path.join(getRuntimePath(pmRoot),SESSION_FILENAME)}async function readSessionState(pmRoot){try{const raw=await fs.readFile(getSessionStatePath(pmRoot),"utf8");const parsed=JSON.parse(raw);if(parsed===null||typeof parsed!=="object"||Array.isArray(parsed)){return{}}const record=parsed;const focused=record.focused_item;const semanticAttribution=parseSemanticAttributionMap(record.semantic_attribution);if(typeof focused==="string"&&focused.trim().length>0){return{focused_item:focused,...semanticAttribution?{semantic_attribution:semanticAttribution}:{}}}return semanticAttribution?{semantic_attribution:semanticAttribution}:{}}catch{return{}}}async function mutateSessionState(pmRoot,mutate){const release=await acquireLock(pmRoot,"session-state",SETTINGS_DEFAULTS.locks.ttl_seconds,"session-state",false,true,SETTINGS_DEFAULTS.locks.wait_ms);try{const state=await readSessionState(pmRoot);mutate(state);const target=getSessionStatePath(pmRoot);await fs.mkdir(path.dirname(target),{recursive:true});await writeFileAtomic(target,JSON.stringify(state))}finally{await release()}}function semanticAttributionKey(principal){const instance=/#([a-f0-9]{24})$/u.exec(principal.trim())?.[1];return instance??`author-${createHash("sha256").update(principal).digest("hex").slice(0,24)}`}function normalizedEvidence(values){return[...new Set(values.map(value=>value.trim()).filter(Boolean))].slice(0,32).map(value=>value.slice(0,128))}function worksetTopic(activeItemIds){const ids=[...new Set(activeItemIds)].sort((left,right)=>left.localeCompare(right));if(ids.length===1)return ids[0];const complete=`workset:${ids.join("+")}`;if(complete.length<=256)return complete;const visible=ids.join("+").slice(0,230);return`workset:${visible}+${createHash("sha256").update(ids.join("\0")).digest("hex").slice(0,12)}`}async function updateSemanticAttribution(pmRoot,key,mutate){await mutateSessionState(pmRoot,state=>{const attributions={...state.semantic_attribution};const next=mutate(attributions[key]);if(next===void 0)delete attributions[key];else attributions[key]=next;if(Object.keys(attributions).length===0){delete state.semantic_attribution}else{state.semantic_attribution=attributions}})}async function recordClaimedWorkAttribution(params){const key=semanticAttributionKey(params.principal);await updateSemanticAttribution(params.pmRoot,key,current=>{const activeItemIds=[...new Set([...current?.active_item_ids??[],params.itemId])].slice(-64).sort((left,right)=>left.localeCompare(right));const focusedItemId=current?.focused_item_id;return{role:"implementer",topic:focusedItemId??worksetTopic(activeItemIds),confidence:focusedItemId?"high":"medium",rule_version:"v2",evidence:normalizedEvidence([...activeItemIds.map(id=>`claim:${id}`),...focusedItemId?[`focus:${focusedItemId}`]:[],...(params.lineageIds??[]).map(id=>`lineage:${id}`)]),active_item_ids:activeItemIds,...focusedItemId?{focused_item_id:focusedItemId}:{}}})}async function releaseClaimedWorkAttribution(params){const key=semanticAttributionKey(params.principal);await updateSemanticAttribution(params.pmRoot,key,current=>{if(!current)return void 0;const activeItemIds=current.active_item_ids.filter(id=>id!==params.itemId);if(activeItemIds.length===0&&!current.focused_item_id)return void 0;const focusedItemId=current.focused_item_id;return{...current,role:"release-operator",topic:focusedItemId??worksetTopic(activeItemIds),confidence:focusedItemId?"high":"medium",evidence:normalizedEvidence([...activeItemIds.map(id=>`claim:${id}`),...focusedItemId?[`focus:${focusedItemId}`]:[],`release:${params.itemId}`]),active_item_ids:activeItemIds}})}async function recordFocusedWorkAttribution(params){const key=semanticAttributionKey(params.principal);await updateSemanticAttribution(params.pmRoot,key,current=>{const activeItemIds=current?.active_item_ids??[];if(!params.itemId&&activeItemIds.length===0)return void 0;const focusedItemId=params.itemId;return{role:focusedItemId?"planner":current.role,topic:focusedItemId??worksetTopic(activeItemIds),confidence:focusedItemId?"high":"medium",rule_version:"v2",evidence:normalizedEvidence([...activeItemIds.map(id=>`claim:${id}`),...focusedItemId?[`focus:${focusedItemId}`]:[],...(params.lineageIds??[]).map(id=>`lineage:${id}`)]),active_item_ids:activeItemIds,...focusedItemId?{focused_item_id:focusedItemId}:{}}})}function resolveAttributionRoot(cwd,env){const configured=env.PM_PATH?.trim();if(configured){const resolved=path.resolve(cwd,configured);if(existsSync(path.join(resolved,"settings.json")))return resolved;const nested=path.join(resolved,".agents","pm");if(existsSync(path.join(nested,"settings.json")))return nested}let cursor=path.resolve(cwd);for(let depth=0;depth<32;depth+=1){const candidate=path.join(cursor,".agents","pm");if(existsSync(path.join(candidate,"settings.json")))return candidate;const parent=path.dirname(cursor);if(parent===cursor)break;cursor=parent}return void 0}function readAgentSemanticAttributionSync(params){if(!params.key)return void 0;const pmRoot=resolveAttributionRoot(params.cwd,params.env);if(!pmRoot)return void 0;try{const parsed=JSON.parse(readFileSync(getSessionStatePath(pmRoot),"utf8"));return parseSemanticAttribution(parsed.semantic_attribution?.[params.key])}catch{return void 0}}async function getFocusedItem(pmRoot){const state=await readSessionState(pmRoot);return state.focused_item}async function setFocusedItem(pmRoot,id){await mutateSessionState(pmRoot,state=>{state.focused_item=id})}async function clearFocusedItem(pmRoot){await mutateSessionState(pmRoot,state=>{delete state.focused_item})}export{clearFocusedItem,getFocusedItem,getSessionStatePath,readAgentSemanticAttributionSync,readSessionState,recordClaimedWorkAttribution,recordFocusedWorkAttribution,releaseClaimedWorkAttribution,semanticAttributionKey,setFocusedItem};
|
|
2
2
|
//# sourceMappingURL=session-state.js.map
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/shared/secret-rules
|
|
3
|
+
* Single credential and private-context detector inventory for mutation preflight
|
|
4
|
+
* and repository scanning. Diagnostics must never include matched text.
|
|
5
|
+
*/
|
|
6
|
+
/** One detector and any explicit repository-only scope exception. */
|
|
7
|
+
export interface SecretRule {
|
|
8
|
+
/** Repository diagnostic identifier. */
|
|
9
|
+
name: string;
|
|
10
|
+
/** Compatible SDK diagnostic identifier. */
|
|
11
|
+
mutationRule: string;
|
|
12
|
+
/** Global pattern; consumers reset lastIndex before each scan. */
|
|
13
|
+
regex: RegExp;
|
|
14
|
+
/** Repository paths with deliberate fixture exemptions. */
|
|
15
|
+
excludeFiles?: RegExp;
|
|
16
|
+
/** Repository paths eligible for this rule. */
|
|
17
|
+
includeFiles?: RegExp;
|
|
18
|
+
/** Why the repository gate deliberately omits this mutation heuristic. */
|
|
19
|
+
mutationOnlyReason?: string;
|
|
20
|
+
/** Minimum Shannon entropy of the first capture group, when applicable. */
|
|
21
|
+
minimumEntropy?: number;
|
|
22
|
+
}
|
|
23
|
+
/** Canonical patterns; repository exemptions never exempt mutation payloads. */
|
|
24
|
+
export declare const SECRET_RULES: readonly [{
|
|
25
|
+
readonly name: "private-key";
|
|
26
|
+
readonly mutationRule: "private_key";
|
|
27
|
+
readonly regex: RegExp;
|
|
28
|
+
}, {
|
|
29
|
+
readonly name: "github-token";
|
|
30
|
+
readonly mutationRule: "github_token";
|
|
31
|
+
readonly regex: RegExp;
|
|
32
|
+
}, {
|
|
33
|
+
readonly name: "npm-token";
|
|
34
|
+
readonly mutationRule: "npm_token";
|
|
35
|
+
readonly regex: RegExp;
|
|
36
|
+
}, {
|
|
37
|
+
readonly name: "aws-access-key";
|
|
38
|
+
readonly mutationRule: "aws_access_key";
|
|
39
|
+
readonly regex: RegExp;
|
|
40
|
+
}, {
|
|
41
|
+
readonly name: "google-api-key";
|
|
42
|
+
readonly mutationRule: "google_api_key";
|
|
43
|
+
readonly regex: RegExp;
|
|
44
|
+
}, {
|
|
45
|
+
readonly name: "slack-token";
|
|
46
|
+
readonly mutationRule: "slack_token";
|
|
47
|
+
readonly regex: RegExp;
|
|
48
|
+
}, {
|
|
49
|
+
readonly name: "anthropic-api-key";
|
|
50
|
+
readonly mutationRule: "anthropic_api_key";
|
|
51
|
+
readonly regex: RegExp;
|
|
52
|
+
}, {
|
|
53
|
+
readonly name: "openai-api-key";
|
|
54
|
+
readonly mutationRule: "openai_api_key";
|
|
55
|
+
readonly regex: RegExp;
|
|
56
|
+
}, {
|
|
57
|
+
readonly name: "gitlab-token";
|
|
58
|
+
readonly mutationRule: "gitlab_token";
|
|
59
|
+
readonly regex: RegExp;
|
|
60
|
+
}, {
|
|
61
|
+
readonly name: "jwt-like-token";
|
|
62
|
+
readonly mutationRule: "jwt_like_token";
|
|
63
|
+
readonly regex: RegExp;
|
|
64
|
+
}, {
|
|
65
|
+
readonly name: "npm-auth-token-assignment";
|
|
66
|
+
readonly mutationRule: "npm_auth_token_assignment";
|
|
67
|
+
readonly regex: RegExp;
|
|
68
|
+
}, {
|
|
69
|
+
readonly name: "sentry-user-token";
|
|
70
|
+
readonly mutationRule: "sentry_user_token";
|
|
71
|
+
readonly regex: RegExp;
|
|
72
|
+
}, {
|
|
73
|
+
readonly name: "sentry-org-token";
|
|
74
|
+
readonly mutationRule: "sentry_org_token";
|
|
75
|
+
readonly regex: RegExp;
|
|
76
|
+
}, {
|
|
77
|
+
readonly name: "private-ip";
|
|
78
|
+
readonly mutationRule: "private_ip";
|
|
79
|
+
readonly regex: RegExp;
|
|
80
|
+
}, {
|
|
81
|
+
readonly name: "private-ssh-target";
|
|
82
|
+
readonly mutationRule: "private_ssh_target";
|
|
83
|
+
readonly regex: RegExp;
|
|
84
|
+
}, {
|
|
85
|
+
readonly name: "sshpass-inline-password";
|
|
86
|
+
readonly mutationRule: "sshpass_inline_password";
|
|
87
|
+
readonly regex: RegExp;
|
|
88
|
+
}, {
|
|
89
|
+
readonly name: "password-assignment";
|
|
90
|
+
readonly mutationRule: "password_assignment";
|
|
91
|
+
readonly regex: RegExp;
|
|
92
|
+
}, {
|
|
93
|
+
readonly name: "absolute-home-path";
|
|
94
|
+
readonly mutationRule: "absolute_home_path";
|
|
95
|
+
readonly regex: RegExp;
|
|
96
|
+
readonly excludeFiles: RegExp;
|
|
97
|
+
}, {
|
|
98
|
+
readonly name: "user-at-private-host";
|
|
99
|
+
readonly mutationRule: "user_at_private_host";
|
|
100
|
+
readonly regex: RegExp;
|
|
101
|
+
readonly excludeFiles: RegExp;
|
|
102
|
+
}, {
|
|
103
|
+
readonly name: "high-entropy-assignment";
|
|
104
|
+
readonly mutationRule: "high_entropy_assignment";
|
|
105
|
+
readonly regex: RegExp;
|
|
106
|
+
readonly mutationOnlyReason: "Generic assignments in source code are not credentials; preserve the existing mutation heuristic without treating source identifiers as secrets.";
|
|
107
|
+
readonly minimumEntropy: 3.5;
|
|
108
|
+
}];
|
|
109
|
+
/** Accept a pattern match, applying the declared entropy predicate when present. */
|
|
110
|
+
export declare function acceptsSecretMatch(rule: SecretRule, match: RegExpMatchArray): boolean;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d7a68072-168d-509a-95ec-145635d71d46")}catch(e2){}})();const SECRET_RULES=[{name:"private-key",mutationRule:"private_key",regex:/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/g},{name:"github-token",mutationRule:"github_token",regex:/\b(?:gh[opsru]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})\b/g},{name:"npm-token",mutationRule:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g},{name:"aws-access-key",mutationRule:"aws_access_key",regex:/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g},{name:"google-api-key",mutationRule:"google_api_key",regex:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"slack-token",mutationRule:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g},{name:"anthropic-api-key",mutationRule:"anthropic_api_key",regex:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g},{name:"openai-api-key",mutationRule:"openai_api_key",regex:/\bsk-(?!ant-)[A-Za-z0-9_-]{20,}\b/g},{name:"gitlab-token",mutationRule:"gitlab_token",regex:/\bglpat-[A-Za-z0-9_.-]{20,}\b/g},{name:"jwt-like-token",mutationRule:"jwt_like_token",regex:/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g},{name:"npm-auth-token-assignment",mutationRule:"npm_auth_token_assignment",regex:/_authToken\s*=\s*\S+/g},{name:"sentry-user-token",mutationRule:"sentry_user_token",regex:/\bsntryu_[A-Za-z0-9]{20,}\b/g},{name:"sentry-org-token",mutationRule:"sentry_org_token",regex:/\bsntrys_[A-Za-z0-9_-]{20,}\b/g},{name:"private-ip",mutationRule:"private_ip",regex:/\b(?:10\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|172\.(?:1[6-9]|2\d|3[01])\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|192\.168\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d))\b/g},{name:"private-ssh-target",mutationRule:"private_ssh_target",regex:/\b(?:ssh|scp|rsync)\s+[A-Za-z0-9._-]+@(?:10\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|172\.(?:1[6-9]|2\d|3[01])\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|192\.168\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d))\b/g},{name:"sshpass-inline-password",mutationRule:"sshpass_inline_password",regex:/\bsshpass\s+-p\s+["'][^"']{6,}["']/g},{name:"password-assignment",mutationRule:"password_assignment",regex:/\b(?:password|passphrase)\s*[:=]\s*(?:(?!<|\$\{|\$\()[A-Za-z0-9!@#$%^&*._+\-=]{8,}|"(?!<|\$\{|\$\()[^"]{8,}"|'(?!<|\$\{|\$\()[^']{8,}')/gi},{name:"absolute-home-path",mutationRule:"absolute_home_path",regex:/(?:^|[\s"'`(=])\/home\/[A-Za-z0-9._-]+\/[^\s"'`),;]+/g,excludeFiles:/^(?:tests\/|examples\/)/},{name:"user-at-private-host",mutationRule:"user_at_private_host",regex:/\b[A-Za-z0-9._-]+@(?:10\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|172\.(?:1[6-9]|2\d|3[01])\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|192\.168\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d))\b/g,excludeFiles:/^(?:tests\/|examples\/)/},{name:"high-entropy-assignment",mutationRule:"high_entropy_assignment",regex:/\b(?:token|secret|password|passwd|api[_-]?key)\s*[:=]\s*["']?([A-Za-z0-9+/=_-]{24,})/gi,mutationOnlyReason:"Generic assignments in source code are not credentials; preserve the existing mutation heuristic without treating source identifiers as secrets.",minimumEntropy:3.5}];function acceptsSecretMatch(rule,match){if(rule.minimumEntropy===void 0)return true;const value=match[1];const counts=new Map;for(const character of value){counts.set(character,(counts.get(character)??0)+1)}let entropy=0;for(const count of counts.values()){const probability=count/value.length;entropy-=probability*Math.log2(probability)}return entropy>=rule.minimumEntropy}export{SECRET_RULES,acceptsSecretMatch};
|
|
2
|
+
//# sourceMappingURL=secret-rules.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preserve concurrent edits to untouched leaves. Arrays and scalar values are
|
|
3
|
+
* indivisible: incompatible edits to the same leaf refuse the entire write.
|
|
4
|
+
* The root must remain an object even for an unchanged snapshot. Error receipts
|
|
5
|
+
* contain a key path, never the potentially secret values.
|
|
6
|
+
*/
|
|
7
|
+
export declare function reconcileSettingsSnapshot(baseline: unknown, proposed: unknown, current: unknown, segments?: readonly string[]): unknown;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e2270ad2-349e-5e8c-b23c-3cf0645907dc")}catch(e2){}})();import{EXIT_CODE}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{stableValueEquals}from"../shared/serialization.js";function isRecord(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function reconcileSettingsSnapshot(baseline,proposed,current,segments=[]){if(stableValueEquals(baseline,proposed)&&(segments.length>0||isRecord(current)))return current;if(stableValueEquals(baseline,current)||stableValueEquals(proposed,current)){return proposed}if((baseline===void 0||isRecord(baseline))&&isRecord(proposed)&&isRecord(current)){const before=baseline??{};const keys=new Set([...Object.keys(before),...Object.keys(proposed),...Object.keys(current)]);return Object.fromEntries([...keys].flatMap(key=>{const merged=reconcileSettingsSnapshot(Object.hasOwn(before,key)?before[key]:void 0,Object.hasOwn(proposed,key)?proposed[key]:void 0,Object.hasOwn(current,key)?current[key]:void 0,[...segments,key]);return merged===void 0?[]:[[key,merged]]}))}throw new PmCliError(`Settings changed concurrently at ${segments.join(".")||"<root>"}; read the latest settings and reapply the intended change.`,EXIT_CODE.CONFLICT,{reason:"stale_settings_snapshot",required:"Read a fresh settings snapshot and reapply the intended change.",why:"Another writer changed the same setting after this snapshot was read.",examples:["pm config project export --json"],nextSteps:["Read the current settings, then retry the original config operation."]})}export{reconcileSettingsSnapshot};
|
|
2
|
+
//# sourceMappingURL=settings-concurrency.js.map
|
|
@@ -8,6 +8,8 @@ import { collectSettingsReadCacheSignatures } from "./settings-read-cache.js";
|
|
|
8
8
|
import type { ExtensionGovernancePolicy, PmMaxVersionExceededModeSetting } from "../extensions/extension-types.js";
|
|
9
9
|
import type { ExtensionSandboxProfile, ExtensionPolicyMode, ExtensionPolicyOverrideSettings, ExtensionTrustMode, GovernanceSettings, ItemTypeDefinition, PmSettings, ValidateMetadataRequiredField } from "../../types/index.js";
|
|
10
10
|
interface SettingsPersistSourceSnapshot {
|
|
11
|
+
/** Last sparse state proposed by this instance, independent of peer edits. */
|
|
12
|
+
persisted_settings: unknown;
|
|
11
13
|
source_settings: ParsedSettings;
|
|
12
14
|
has_source_item_type_definitions: boolean;
|
|
13
15
|
source_item_type_definitions: ItemTypeDefinition[];
|
|
@@ -85,7 +87,12 @@ export declare function serializeSettings(settings: PmSettings, options?: Serial
|
|
|
85
87
|
export declare function readSettingsWithMetadata(pmRoot: string): Promise<SettingsReadResult>;
|
|
86
88
|
/** Implements read settings for the public runtime surface of this module. */
|
|
87
89
|
export declare function readSettings(pmRoot: string): Promise<PmSettings>;
|
|
88
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* Persist edits to a readSettings snapshot under the workspace-history lock.
|
|
92
|
+
* Disjoint concurrent edits survive; overlapping stale edits fail before any
|
|
93
|
+
* write. Caller-constructed settings without a read snapshot replace the whole
|
|
94
|
+
* document. History append failures compensate the document before unlocking.
|
|
95
|
+
*/
|
|
89
96
|
export declare function writeSettings(pmRoot: string, settings: PmSettings, op?: string): Promise<void>;
|
|
90
97
|
/** Public contract for settings store test only, shared by SDK and presentation-layer consumers. */
|
|
91
98
|
export declare const settingsStoreTestOnly: {
|