@unbrained/pm-cli 2026.9.30 → 2026.10.2
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 +20 -0
- package/dist/cli/error-guidance.d.ts +5 -0
- package/dist/cli/error-guidance.js +1 -1
- package/dist/cli/main.js +2 -2
- package/dist/cli/register-list-query.d.ts +8 -5
- package/dist/cli/register-list-query.js +2 -2
- package/dist/cli/register-structured-mutation.d.ts +2 -0
- package/dist/cli/register-structured-mutation.js +1 -1
- package/dist/cli/runtime/projection-retry.d.ts +9 -0
- package/dist/cli/runtime/projection-retry.js +2 -0
- package/dist/cli/runtime/selection.d.ts +5 -1
- package/dist/cli/runtime/selection.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +157 -157
- package/dist/cli-bundle/chunks/{chunk-EGAIIWI3.js → chunk-7FUEQOYG.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-7NL3A2BY.js +2 -0
- package/dist/cli-bundle/chunks/chunk-CZLAWXDR.js +8 -0
- package/dist/cli-bundle/chunks/chunk-HY6M34B4.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-O23CQ5T4.js → chunk-MTJMOI4I.js} +14 -14
- package/dist/cli-bundle/chunks/chunk-R4TUD355.js +6 -0
- package/dist/cli-bundle/chunks/chunk-R7ULWMBG.js +238 -0
- package/dist/cli-bundle/chunks/chunk-SV7CZEVV.js +20 -0
- package/dist/cli-bundle/chunks/chunk-TRYXVQ7W.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-BTCE36JS.js → chunk-WP6NRH72.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XRN3JYNN.js → chunk-XOUBIF6Z.js} +38 -38
- package/dist/cli-bundle/chunks/chunk-Z2GYDSAO.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-6YEET7XI.js → chunk-ZI7F3FVE.js} +47 -47
- package/dist/cli-bundle/chunks/{register-list-query-SYNBVMNG.js → register-list-query-R4PHNB7W.js} +6 -6
- package/dist/cli-bundle/chunks/register-mutation-PDDAUDYV.js +20 -0
- package/dist/cli-bundle/chunks/{register-operations-7FCJUC4Z.js → register-operations-A5HJT46K.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-YTWW2KL5.js → register-setup-EZ2F25JI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-MOUCTR72.js → chunk-3BIYG72P.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-T4PZJQG4.js → chunk-4FFPGNCJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-AKB3JN57.js → chunk-BLCTBSGT.js} +45 -45
- package/dist/cli-bundle/focused-chunks/{chunk-XUCXRZZZ.js → chunk-DBD4W4QP.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-KZULQIAG.js → chunk-E754JDLY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-4AORVUT4.js → chunk-EJN7DY3B.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-OMBDUJWZ.js → chunk-FKK2HI3S.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-GBD4EN6S.js +12 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZJ3CLTV4.js → chunk-GMYUNHST.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-IR4UXLRP.js +20 -0
- package/dist/cli-bundle/focused-chunks/{chunk-RIJQQOEZ.js → chunk-UTRSM3ZK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-EVMH4SKN.js → chunk-VVWYI2X7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-WCY6HRZO.js +30 -0
- package/dist/cli-bundle/focused-chunks/{chunk-XB5Q2P7Z.js → chunk-XRSCIYHR.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-YC32ZSLS.js +165 -0
- package/dist/cli-bundle/focused-chunks/{chunk-IQBFYQF2.js → chunk-ZIXFMIUL.js} +2 -2
- package/dist/cli-bundle/main.js +22 -22
- 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 +2 -2
- 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 +48 -48
- 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 +7 -7
- package/dist/core/fs/fs-utils.d.ts +11 -0
- package/dist/core/fs/fs-utils.js +2 -2
- package/dist/core/shared/errors.d.ts +9 -0
- package/dist/core/shared/errors.js +1 -1
- package/dist/core/store/settings.d.ts +15 -5
- package/dist/core/store/settings.js +3 -3
- package/dist/core/telemetry/runtime.js +3 -3
- package/dist/mcp/server.js +1 -1
- package/dist/sdk/agent/closed-domain-contracts.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/item-transaction.d.ts +11 -0
- package/dist/sdk/item-transaction.js +1 -1
- package/dist/sdk/merge/install.d.ts +2 -2
- package/dist/sdk/merge/install.js +1 -1
- package/dist/sdk/pagination.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/context.d.ts +2 -0
- package/dist/sdk/query/context.js +1 -1
- package/dist/sdk/query/get.d.ts +19 -15
- package/dist/sdk/query/get.js +1 -1
- package/dist/sdk/query/list.js +1 -1
- package/dist/sdk/query/search-contracts.js +1 -1
- package/dist/sdk/query/search-pagination.d.ts +4 -0
- package/dist/sdk/query/search-pagination.js +1 -1
- package/dist/sdk/query/search.js +1 -1
- package/dist/sdk/read-output/options.d.ts +14 -0
- package/dist/sdk/read-output/options.js +2 -0
- package/dist/sdk/read-output-budget.js +1 -1
- package/dist/sdk/read-output-contracts.js +1 -1
- package/dist/sdk/read-output-rows.d.ts +4 -0
- package/dist/sdk/read-output-rows.js +1 -1
- package/dist/sdk/runtime-primitives.d.ts +2 -2
- package/dist/sdk/runtime-primitives.js +1 -1
- package/dist/sdk/runtime.js +1 -1
- package/dist/sdk/workspace-transaction.d.ts +2 -0
- package/dist/sdk/workspace-transaction.js +2 -2
- package/docs/BOUNDED_CONTEXT_READS.md +10 -7
- package/docs/COMMANDS.md +1 -1
- package/docs/MERGE_SAFETY.md +12 -6
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +27 -0
- package/docs/SDK.md +98 -0
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +6 -3
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/package.json +2 -2
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +2 -2
- package/plugins/pm-codex/plugin.json +1 -1
- package/dist/cli-bundle/chunks/chunk-6XTJLOKW.js +0 -3
- package/dist/cli-bundle/chunks/chunk-A6NDNRCK.js +0 -6
- package/dist/cli-bundle/chunks/chunk-BNAT4EYR.js +0 -20
- package/dist/cli-bundle/chunks/chunk-BX4LEJX4.js +0 -8
- package/dist/cli-bundle/chunks/chunk-FYTXVVZG.js +0 -2
- package/dist/cli-bundle/chunks/chunk-UIAH7UFK.js +0 -238
- package/dist/cli-bundle/chunks/chunk-USTAFHIM.js +0 -2
- package/dist/cli-bundle/chunks/chunk-YM342ELM.js +0 -3
- package/dist/cli-bundle/chunks/register-mutation-4GSUK23D.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-3CAZ7Z4R.js +0 -30
- package/dist/cli-bundle/focused-chunks/chunk-EFD4ATS7.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-IDB6E3ZV.js +0 -165
- package/dist/cli-bundle/focused-chunks/chunk-UPOMLSW7.js +0 -20
|
@@ -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
|
-
`)}function hasValidJournalMetadata(journal){return Number.isInteger(journal.attempt)&&typeof journal.author==="string"&&typeof journal.createdAt==="string"&&typeof journal.updatedAt==="string"}function createResultMap(source){return Object.assign(Object.create(null),source)}function cloneJournalValue(value,label){try{const serialized=JSON.stringify(value,(_key,nestedValue)=>{if(typeof nestedValue==="number"&&!Number.isFinite(nestedValue))throw new TypeError(`${label} contains a non-finite number`);if(nestedValue===void 0||typeof nestedValue==="function"||typeof nestedValue==="symbol")throw new TypeError(`${label} contains a non-JSON value`);return nestedValue});return JSON.parse(serialized)}catch(error){throw new TypeError(`${label} must be JSON serializable`,{cause:error})}}function cloneOptionalJournalValue(value,label){return value===void 0?void 0:cloneJournalValue(value,label)}function setJournalEntry(target,stepId,value,label){const cloned=cloneOptionalJournalValue(value,label);if(cloned===void 0)delete target[stepId];else target[stepId]=cloned}function isJournalMap(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)}function hasUniqueKnownStepIds(value,stepIds){return Array.isArray(value)&&new Set(value).size===value.length&&value.every(stepId=>typeof stepId==="string"&&stepIds.includes(stepId))}function hasValidJournalLifecycle(journal,stepIds){if(!hasUniqueKnownStepIds(journal.startedStepIds,stepIds)||!hasUniqueKnownStepIds(journal.completedStepIds,stepIds)||!isJournalMap(journal.results)||!isJournalMap(journal.compensationData))return false;const startedStepIds=journal.startedStepIds;const started=new Set(startedStepIds);const completedStepIds=journal.completedStepIds;const completed=new Set(completedStepIds);if(Object.keys(journal.compensationData).some(stepId=>!started.has(stepId))||Object.keys(journal.results).some(stepId=>!completed.has(stepId)))return false;if(journal.status==="committed")return stepIds.every(stepId=>completed.has(stepId));return journal.status!=="compensated"||completed.size===0&&started.size===0}function parseJournal(raw,transactionId,stepIds){let parsed;try{parsed=JSON.parse(raw)}catch{throw new TypeError(`Workspace transaction ${transactionId} journal is invalid JSON`)}if(!parsed||typeof parsed!=="object"||Array.isArray(parsed))throw new TypeError(`Workspace transaction ${transactionId} journal is invalid`);const journal=parsed;const identityMatches=journal.schemaVersion===1&&journal.transactionId===transactionId;const stepsMatch=Array.isArray(journal.stepIds)&&journal.stepIds.length===stepIds.length&&journal.stepIds.every((stepId,index)=>stepId===stepIds[index]);const lifecycleMatches=hasValidJournalLifecycle(journal,stepIds);const metadataMatches=hasValidJournalMetadata(journal);const statusMatches=["applying","compensating","compensated","committed"].includes(String(journal.status));if(!identityMatches||!stepsMatch||!lifecycleMatches||!metadataMatches||!statusMatches)throw new TypeError(`Workspace transaction ${transactionId} journal does not match the supplied plan`);return{...journal,results:createResultMap(journal.results),compensationData:createResultMap(journal.compensationData)}}async function prepareJournalForApply(options,transactionId,author,stepIds,existing){let journal=existing;const recovered=journal!==void 0;if(journal?.status==="compensating")await compensateAppliedSteps(options,journal);if(journal===void 0||journal.status==="compensated"){const timestamp=nowIso();journal={schemaVersion:1,transactionId,author,status:"applying",attempt:(journal?.attempt??0)+1,createdAt:journal?.createdAt??timestamp,updatedAt:timestamp,stepIds,startedStepIds:[],completedStepIds:[],results:createResultMap(),compensationData:createResultMap()};await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"prepared")}return{journal,recovered}}async function applyPreparedTransaction(options,journal,recovered){try{await discoverAppliedSteps(journal,options.steps);await writeJournal(options.pmRoot,journal);const completed=new Set(journal.completedStepIds);const started=new Set(journal.startedStepIds);for(const step of options.steps){if(completed.has(step.id))continue;const inspection=await step.inspect();let result=cloneOptionalJournalValue(inspection.result,`Step ${step.id} result`);if(inspection.state!=="applied"){const compensationData=await step.prepareCompensation?.();setJournalEntry(journal.compensationData,step.id,compensationData,`Step ${step.id} compensation data`);started.add(step.id);journal.startedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>started.has(stepId));await writeJournal(options.pmRoot,journal);const appliedResult=await step.apply();result=cloneOptionalJournalValue(appliedResult,`Step ${step.id} result`)}await emitTransition(options,journal,"step_applied",step.id);completed.add(step.id);journal.completedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>completed.has(stepId));setJournalEntry(journal.results,step.id,result,`Step ${step.id} result`);await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"step_recorded",step.id)}await emitTransition(options,journal,"committing");journal.status="committed";await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"committed");return{transactionId:journal.transactionId,status:"committed",recovered,results:createResultMap(journal.results)}}catch(error){if(error instanceof WorkspaceTransactionInterruptedError||journal.status==="committed")throw error;try{await compensateAppliedSteps(options,journal)}catch(compensationError){throw new AggregateError([error,compensationError],`Workspace transaction failed and compensation failed: ${String(compensationError)}`,{cause:compensationError})}throw error}}async function loadJournal(pmRoot,transactionId,stepIds){try{return parseJournal(await readFile(journalPath(pmRoot,transactionId),"utf8"),transactionId,stepIds)}catch(error){if(error!==null&&typeof error==="object"&&"code"in error&&isFileMissingError(error))return void 0;throw error}}async function emitTransition(options,journal,transition,stepId){await options.onTransition?.({transactionId:journal.transactionId,attempt:journal.attempt,transition,...stepId===void 0?{}:{stepId}})}async function discoverAppliedSteps(journal,steps){const completed=new Set;const results=createResultMap();for(const step of steps){const inspection=await step.inspect();if(inspection.state==="applied"){completed.add(step.id);setJournalEntry(results,step.id,inspection.result,`Step ${step.id} result`)}}journal.results=results;journal.completedStepIds=steps.map(step=>step.id).filter(stepId=>completed.has(stepId))}async function compensateAppliedSteps(options,journal){journal.status="compensating";await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"compensating");const completed=new Set(journal.completedStepIds);const started=new Set(journal.startedStepIds);for(const step of[...options.steps].reverse()){if(!started.has(step.id)&&!completed.has(step.id))continue;let shouldCompensate;try{shouldCompensate=started.has(step.id)&&(await step.inspect()).state==="applied"}catch{shouldCompensate=started.has(step.id)}if(shouldCompensate){await emitTransition(options,journal,"step_compensating",step.id);await step.compensate(journal.compensationData[step.id])}completed.delete(step.id);started.delete(step.id);journal.completedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>completed.has(stepId));journal.startedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>started.has(stepId));delete journal.results[step.id];delete journal.compensationData[step.id];await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"step_compensated",step.id)}journal.status="compensated";await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"compensated")}async function commitWorkspaceTransaction(options){const
|
|
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]="d9ef3878-afce-5983-8fe9-8a896f82d0a7")}catch(e2){}})();import{mkdir,readFile}from"node:fs/promises";import path from"node:path";import{acquireLock}from"../core/lock/lock.js";import{isFileMissingError,writeFileAtomic}from"../core/fs/fs-utils.js";import{nowIso}from"../core/shared/time.js";class WorkspaceTransactionInterruptedError extends Error{constructor(message="Workspace transaction interrupted"){super(message);this.name="WorkspaceTransactionInterruptedError"}}const WORKSPACE_TRANSACTION_LOCK_ID="sdk-workspace-transaction";const TRANSACTION_ID_PATTERN=/^[a-zA-Z0-9._-]+$/;const DEFAULT_LOCK_TTL_SECONDS=30;const DEFAULT_LOCK_WAIT_MS=3e3;function requiredIdentifier(value,label){if(typeof value!=="string")throw new TypeError(`${label} must be a string`);const normalized=value.trim();if(!normalized||!TRANSACTION_ID_PATTERN.test(normalized))throw new TypeError(`${label} must match [a-zA-Z0-9._-]+`);return normalized}function requiredText(value,label){if(typeof value!=="string")throw new TypeError(`${label} must be a string`);const normalized=value.trim();if(!normalized)throw new TypeError(`${label} must be non-empty`);return normalized}function validateWorkspaceTransactionIdentity(options){return{pmRoot:requiredText(options.pmRoot,"Transaction pmRoot"),transactionId:requiredIdentifier(options.transactionId,"Transaction id"),author:requiredText(options.author,"Transaction author")}}function positiveInteger(value,fallback,label){const resolved=value??fallback;if(!Number.isInteger(resolved)||resolved<=0)throw new TypeError(`${label} must be a positive integer`);return resolved}function journalPath(pmRoot,transactionId){return path.join(pmRoot,"transactions","sdk",`${transactionId}.json`)}async function writeJournal(pmRoot,journal){journal.updatedAt=nowIso();const target=journalPath(pmRoot,journal.transactionId);await mkdir(path.dirname(target),{recursive:true});await writeFileAtomic(target,`${JSON.stringify(journal,null,2)}
|
|
2
|
+
`)}function hasValidJournalMetadata(journal){return Number.isInteger(journal.attempt)&&typeof journal.author==="string"&&typeof journal.createdAt==="string"&&typeof journal.updatedAt==="string"}function createResultMap(source){return Object.assign(Object.create(null),source)}function cloneJournalValue(value,label){try{const serialized=JSON.stringify(value,(_key,nestedValue)=>{if(typeof nestedValue==="number"&&!Number.isFinite(nestedValue))throw new TypeError(`${label} contains a non-finite number`);if(nestedValue===void 0||typeof nestedValue==="function"||typeof nestedValue==="symbol")throw new TypeError(`${label} contains a non-JSON value`);return nestedValue});return JSON.parse(serialized)}catch(error){throw new TypeError(`${label} must be JSON serializable`,{cause:error})}}function cloneOptionalJournalValue(value,label){return value===void 0?void 0:cloneJournalValue(value,label)}function setJournalEntry(target,stepId,value,label){const cloned=cloneOptionalJournalValue(value,label);if(cloned===void 0)delete target[stepId];else target[stepId]=cloned}function isJournalMap(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)}function hasUniqueKnownStepIds(value,stepIds){return Array.isArray(value)&&new Set(value).size===value.length&&value.every(stepId=>typeof stepId==="string"&&stepIds.includes(stepId))}function hasValidJournalLifecycle(journal,stepIds){if(!hasUniqueKnownStepIds(journal.startedStepIds,stepIds)||!hasUniqueKnownStepIds(journal.completedStepIds,stepIds)||!isJournalMap(journal.results)||!isJournalMap(journal.compensationData))return false;const startedStepIds=journal.startedStepIds;const started=new Set(startedStepIds);const completedStepIds=journal.completedStepIds;const completed=new Set(completedStepIds);if(Object.keys(journal.compensationData).some(stepId=>!started.has(stepId))||Object.keys(journal.results).some(stepId=>!completed.has(stepId)))return false;if(journal.status==="committed")return stepIds.every(stepId=>completed.has(stepId));return journal.status!=="compensated"||completed.size===0&&started.size===0}function parseJournal(raw,transactionId,stepIds){let parsed;try{parsed=JSON.parse(raw)}catch{throw new TypeError(`Workspace transaction ${transactionId} journal is invalid JSON`)}if(!parsed||typeof parsed!=="object"||Array.isArray(parsed))throw new TypeError(`Workspace transaction ${transactionId} journal is invalid`);const journal=parsed;const identityMatches=journal.schemaVersion===1&&journal.transactionId===transactionId;const stepsMatch=Array.isArray(journal.stepIds)&&journal.stepIds.length===stepIds.length&&journal.stepIds.every((stepId,index)=>stepId===stepIds[index]);const lifecycleMatches=hasValidJournalLifecycle(journal,stepIds);const metadataMatches=hasValidJournalMetadata(journal);const statusMatches=["applying","compensating","compensated","committed"].includes(String(journal.status));if(!identityMatches||!stepsMatch||!lifecycleMatches||!metadataMatches||!statusMatches)throw new TypeError(`Workspace transaction ${transactionId} journal does not match the supplied plan`);return{...journal,results:createResultMap(journal.results),compensationData:createResultMap(journal.compensationData)}}async function prepareJournalForApply(options,transactionId,author,stepIds,existing){let journal=existing;const recovered=journal!==void 0;if(journal?.status==="compensating")await compensateAppliedSteps(options,journal);if(journal===void 0||journal.status==="compensated"){const timestamp=nowIso();journal={schemaVersion:1,transactionId,author,status:"applying",attempt:(journal?.attempt??0)+1,createdAt:journal?.createdAt??timestamp,updatedAt:timestamp,stepIds,startedStepIds:[],completedStepIds:[],results:createResultMap(),compensationData:createResultMap()};await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"prepared")}return{journal,recovered}}async function applyPreparedTransaction(options,journal,recovered){try{await discoverAppliedSteps(journal,options.steps);await writeJournal(options.pmRoot,journal);const completed=new Set(journal.completedStepIds);const started=new Set(journal.startedStepIds);for(const step of options.steps){if(completed.has(step.id))continue;const inspection=await step.inspect();let result=cloneOptionalJournalValue(inspection.result,`Step ${step.id} result`);if(inspection.state!=="applied"){const compensationData=await step.prepareCompensation?.();setJournalEntry(journal.compensationData,step.id,compensationData,`Step ${step.id} compensation data`);started.add(step.id);journal.startedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>started.has(stepId));await writeJournal(options.pmRoot,journal);const appliedResult=await step.apply();result=cloneOptionalJournalValue(appliedResult,`Step ${step.id} result`)}await emitTransition(options,journal,"step_applied",step.id);completed.add(step.id);journal.completedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>completed.has(stepId));setJournalEntry(journal.results,step.id,result,`Step ${step.id} result`);await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"step_recorded",step.id)}await emitTransition(options,journal,"committing");journal.status="committed";await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"committed");return{transactionId:journal.transactionId,status:"committed",recovered,results:createResultMap(journal.results)}}catch(error){if(error instanceof WorkspaceTransactionInterruptedError||journal.status==="committed")throw error;try{await compensateAppliedSteps(options,journal)}catch(compensationError){throw new AggregateError([error,compensationError],`Workspace transaction failed and compensation failed: ${String(compensationError)}`,{cause:compensationError})}throw error}}async function loadJournal(pmRoot,transactionId,stepIds){try{return parseJournal(await readFile(journalPath(pmRoot,transactionId),"utf8"),transactionId,stepIds)}catch(error){if(error!==null&&typeof error==="object"&&"code"in error&&isFileMissingError(error))return void 0;throw error}}async function emitTransition(options,journal,transition,stepId){await options.onTransition?.({transactionId:journal.transactionId,attempt:journal.attempt,transition,...stepId===void 0?{}:{stepId}})}async function discoverAppliedSteps(journal,steps){const completed=new Set;const results=createResultMap();for(const step of steps){const inspection=await step.inspect();if(inspection.state==="applied"){completed.add(step.id);setJournalEntry(results,step.id,inspection.result,`Step ${step.id} result`)}}journal.results=results;journal.completedStepIds=steps.map(step=>step.id).filter(stepId=>completed.has(stepId))}async function compensateAppliedSteps(options,journal){journal.status="compensating";await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"compensating");const completed=new Set(journal.completedStepIds);const started=new Set(journal.startedStepIds);for(const step of[...options.steps].reverse()){if(!started.has(step.id)&&!completed.has(step.id))continue;let shouldCompensate;try{shouldCompensate=started.has(step.id)&&(await step.inspect()).state==="applied"}catch{shouldCompensate=started.has(step.id)}if(shouldCompensate){await emitTransition(options,journal,"step_compensating",step.id);await step.compensate(journal.compensationData[step.id])}completed.delete(step.id);started.delete(step.id);journal.completedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>completed.has(stepId));journal.startedStepIds=options.steps.map(candidate=>candidate.id).filter(stepId=>started.has(stepId));delete journal.results[step.id];delete journal.compensationData[step.id];await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"step_compensated",step.id)}journal.status="compensated";await writeJournal(options.pmRoot,journal);await emitTransition(options,journal,"compensated")}async function commitWorkspaceTransaction(options){const{pmRoot,transactionId,author}=validateWorkspaceTransactionIdentity(options);const lockTtlSeconds=positiveInteger(options.lockTtlSeconds,DEFAULT_LOCK_TTL_SECONDS,"Transaction lock TTL");const lockWaitMs=positiveInteger(options.lockWaitMs,DEFAULT_LOCK_WAIT_MS,"Transaction lock wait");const steps=[...options.steps];if(steps.length===0)throw new TypeError("Workspace transaction requires at least one step");const stepIds=steps.map(step=>{const stepId=requiredIdentifier(step.id,"Transaction step id");if(stepId!==step.id)throw new TypeError("Transaction step id must not contain surrounding whitespace");return stepId});if(new Set(stepIds).size!==stepIds.length)throw new TypeError("Workspace transaction step ids must be unique");const stableOptions={...options,pmRoot,transactionId,author,steps,lockTtlSeconds,lockWaitMs};const release=await acquireLock(pmRoot,WORKSPACE_TRANSACTION_LOCK_ID,lockTtlSeconds,author,false,false,lockWaitMs);try{const existing=await loadJournal(pmRoot,transactionId,stepIds);const recovered=existing!==void 0;if(existing?.status==="committed")return{transactionId,status:"committed",recovered:true,results:createResultMap(existing.results)};const prepared=await prepareJournalForApply(stableOptions,transactionId,author,stepIds,existing);return await applyPreparedTransaction(stableOptions,prepared.journal,recovered||prepared.recovered)}finally{await release()}}export{WorkspaceTransactionInterruptedError,commitWorkspaceTransaction,validateWorkspaceTransactionIdentity};
|
|
3
3
|
//# sourceMappingURL=workspace-transaction.js.map
|
|
@@ -4,8 +4,9 @@ Tracked by [pm-pshhry](../.agents/pm/issues/pm-pshhry.toon),
|
|
|
4
4
|
[pm-ydshl9](../.agents/pm/issues/pm-ydshl9.toon),
|
|
5
5
|
[pm-bab3gb](../.agents/pm/issues/pm-bab3gb.toon),
|
|
6
6
|
[pm-fx80w2](../.agents/pm/issues/pm-fx80w2.toon),
|
|
7
|
-
[pm-gtw5zh](../.agents/pm/issues/pm-gtw5zh.toon),
|
|
8
|
-
[pm-s8ybl9](../.agents/pm/issues/pm-s8ybl9.toon)
|
|
7
|
+
[pm-gtw5zh](../.agents/pm/issues/pm-gtw5zh.toon),
|
|
8
|
+
[pm-s8ybl9](../.agents/pm/issues/pm-s8ybl9.toon), and
|
|
9
|
+
[pm-x8jdt8](../.agents/pm/issues/pm-x8jdt8.toon).
|
|
9
10
|
|
|
10
11
|
Project management is context management. Routine reads should pay for the
|
|
11
12
|
requested evidence, and derived feedback should not grow with every candidate
|
|
@@ -21,12 +22,14 @@ The cost still depends on the addressed record, registered type directories,
|
|
|
21
22
|
and extension activation; this is not a constant-latency guarantee for arbitrary
|
|
22
23
|
extensions or unbounded individual history streams.
|
|
23
24
|
|
|
24
|
-
Request hierarchy work explicitly with `--fields id,children`, `--tree`,
|
|
25
|
-
deep
|
|
25
|
+
Request hierarchy work explicitly with `--fields id,children`, `--tree`, a
|
|
26
|
+
deep read of a container or custom type, or a full read of any type. These
|
|
27
|
+
paths preserve registered hierarchy semantics,
|
|
26
28
|
including inverse and custom relationship kinds, rather than treating only the
|
|
27
|
-
scalar `parent` field as authoritative. An
|
|
28
|
-
restore selector in the omission receipt
|
|
29
|
-
projections retain a zero-count rollup
|
|
29
|
+
scalar `parent` field as authoritative. An uncomputed `children` facet carries a
|
|
30
|
+
restore selector in the omission receipt even for Task items, which may have
|
|
31
|
+
children. Explicit full and child-field projections retain a zero-count rollup
|
|
32
|
+
for an empty item; a deep container read does the same.
|
|
30
33
|
|
|
31
34
|
Caller-carried output sessions retain only portable item identities in
|
|
32
35
|
`next_state.seen_item_ids`. Workspace activity such as `_workspace` remains
|
package/docs/COMMANDS.md
CHANGED
|
@@ -184,7 +184,7 @@ As a read-only structured surface, `duplicates` accepts the universal output
|
|
|
184
184
|
controls, including `--output-format json`, `--lean`, projection/amount
|
|
185
185
|
controls, and token accounting, while its default TOON output remains bounded.
|
|
186
186
|
Tracked by [pm-gh1076](../.agents/pm/issues/pm-gh1076.toon).
|
|
187
|
-
Use `pm get <id>` to read a single item by ID — the single-item read primitive used throughout the agent loop. It accepts `--fields <list>` and `--depth brief|standard|deep|full` for token-minimal projections, and `--tree`/`--tree-depth <n>` to include descendants. The universal `--output-include` selector can request stored collections directly, for example `pm get <id> --output-include comments,learnings,tests`; the same bare and `item.<field>` grammar works through CLI, SDK, and MCP transports. Standard/deep reads expose a normalized `schedule` facet (`deadline`, `start_at`, `end_at`, `location`, reminders, and events) when scheduling metadata exists. Standard reads of every item type avoid a workspace child scan. For container-oriented built-ins (Epic, Feature, Milestone, and Plan) and custom types, `--depth deep
|
|
187
|
+
Use `pm get <id>` to read a single item by ID — the single-item read primitive used throughout the agent loop. It accepts `--fields <list>` and `--depth brief|standard|deep|full` for token-minimal projections, and `--tree`/`--tree-depth <n>` to include descendants. The universal `--output-include` selector can request stored collections directly, for example `pm get <id> --output-include comments,learnings,tests`; the same bare and `item.<field>` grammar works through CLI, SDK, and MCP transports. Standard/deep reads expose a normalized `schedule` facet (`deadline`, `start_at`, `end_at`, `location`, reminders, and events) when scheduling metadata exists. Standard reads of every item type avoid a workspace child scan. For container-oriented built-ins (Epic, Feature, Milestone, and Plan) and custom types, `--depth deep` adds type-agnostic child counts, a bounded sample, and continuation metadata. Explicit `--full` and `--depth full` reads compute that rollup for every type, including Task parents. An explicit `--fields id,children` requests that rollup without the other deep fields. A read without a child rollup retains a `children` omission hint until a rollup proves the item has no children. See [bounded context reads](BOUNDED_CONTEXT_READS.md) for the cost contract. `pm get <id> --json` returns the `body` inside the `item` object (`.item.body`); see [Full results, totals, and bodies](#full-results-totals-and-bodies). To duplicate an existing item as a starting point, `pm copy <id> --title "New title"` clones it into a fresh id with lifecycle fields reset.
|
|
188
188
|
|
|
189
189
|
When the strongest duplicate match is terminal because the same work recurred,
|
|
190
190
|
reuse its lineage instead of creating or copying another item:
|
package/docs/MERGE_SAFETY.md
CHANGED
|
@@ -14,7 +14,9 @@ compatibility is tracked by
|
|
|
14
14
|
Lossless concurrent acceptance-criteria composition is tracked by
|
|
15
15
|
[pm-inn5y5](../.agents/pm/issues/pm-inn5y5.toon).
|
|
16
16
|
The Bun launcher and strict-health repair are tracked by
|
|
17
|
-
[pm-vks66s](../.agents/pm/issues/pm-vks66s.toon).
|
|
17
|
+
[pm-vks66s](../.agents/pm/issues/pm-vks66s.toon), with the Bun 1.3.5
|
|
18
|
+
package-runner recurrence tracked by
|
|
19
|
+
[pm-aaxq4n](../.agents/pm/issues/pm-aaxq4n.toon).
|
|
18
20
|
Recency-aware scalar convergence, bounded fresh-clone decision evidence, and
|
|
19
21
|
audited pre-durable receipt dispositions are tracked by
|
|
20
22
|
[pm-7wzb6d](../.agents/pm/issues/pm-7wzb6d.toon),
|
|
@@ -44,11 +46,15 @@ The clone-local driver values record the absolute runtime launcher and bundled
|
|
|
44
46
|
`dist/cli.js` path resolved by the installing SDK. With Node, the installer
|
|
45
47
|
preserves an absolute PATH symlink when it resolves to the executing runtime, so
|
|
46
48
|
a runtime manager can retarget that launcher during upgrades without breaking
|
|
47
|
-
every clone. With Bun,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
every clone. With Bun, the installer checks the absolute executable published
|
|
50
|
+
by the package runner, absolute `PATH` entries, and the directly invoked binary
|
|
51
|
+
for a matching Bun version, then records its stable target. Known temporary
|
|
52
|
+
`bun-node-*` launcher copies are rejected even when their version matches.
|
|
53
|
+
Relative paths, inaccessible launchers, and
|
|
54
|
+
different runtimes are ignored. If no durable matching Bun launcher is available,
|
|
55
|
+
installation fails with recovery guidance before it writes Git configuration or
|
|
56
|
+
the shared fence; a temporary `bunx` runtime is never recorded as a successful
|
|
57
|
+
driver installation.
|
|
52
58
|
Git therefore does not depend
|
|
53
59
|
on a bare `pm` command or the caller's later `PATH` when it merges tracker data.
|
|
54
60
|
The item-path placeholder is stored as bare `%P`: Git performs the required
|
|
@@ -244,6 +244,24 @@ Explicit overrides below 256 tokens are rejected because the minimum
|
|
|
244
244
|
machine-readable receipt cannot fit; malformed or absent overrides retain the
|
|
245
245
|
declared intent budget.
|
|
246
246
|
|
|
247
|
+
Projection refusals repair the original CLI invocation: tracker selection,
|
|
248
|
+
operands, output encoding, filters and unrelated controls survive the retry.
|
|
249
|
+
Unknown field selectors are removed while valid requested selectors remain.
|
|
250
|
+
Full/projection conflicts retain the selected full or brief mode and remove the
|
|
251
|
+
conflicting projection and intent controls. If that correction cannot be
|
|
252
|
+
constructed safely, the error does not advertise an automatic retry.
|
|
253
|
+
Tracked by [pm-gh1364](../.agents/pm/issues/pm-gh1364.toon).
|
|
254
|
+
|
|
255
|
+
For a budget-compacted producer page, follow
|
|
256
|
+
`output_budget_truncation.recovery.cursor` with `--output-cursor`, keeping the
|
|
257
|
+
original arguments and any `--after` value. Once that cursor is absent, use the
|
|
258
|
+
producer `next_cursor` with `--after` and remove `--output-cursor`. Universal
|
|
259
|
+
output shaping and continuation controls do not change producer query identity;
|
|
260
|
+
actual filter and scope changes still invalidate its cursor. Emitted `count`
|
|
261
|
+
and `summary.returned_focus` describe delivered rows; matching-population totals
|
|
262
|
+
remain separate, including explicit count-only aggregates. Context hierarchy companions may repeat while continuing a
|
|
263
|
+
focus collection. Tracked by [pm-gh1371](../.agents/pm/issues/pm-gh1371.toon).
|
|
264
|
+
|
|
247
265
|
The first cursor page carries the complete projection, filtering, sorting,
|
|
248
266
|
completeness, row, and omission contracts. Continuation pages replace those
|
|
249
267
|
chain-invariant blocks with `continuation_contract`, which carries the cursor's
|
|
@@ -380,3 +398,12 @@ key continue to receive the same rows.
|
|
|
380
398
|
Dependency token accounting includes the projection declaration and derived
|
|
381
399
|
receipt. Reported `usedTokens` and truncation estimates therefore describe the
|
|
382
400
|
final serialized result, not a pre-receipt intermediate.
|
|
401
|
+
|
|
402
|
+
When context field selection hides focus roles or blocker flags, optional
|
|
403
|
+
`summary.focus_row_states` strings retain those classifications across JSON
|
|
404
|
+
transport. Each character corresponds to a delivered record in its named focus
|
|
405
|
+
section: `i`/`I` means in progress, `o`/`O` means open; uppercase means blocked.
|
|
406
|
+
Continuation and compaction slice these receipts with the rows. Self-describing
|
|
407
|
+
focus rows need no extra receipt. Semantic receipts are preserved during
|
|
408
|
+
explanatory-string compaction, and corrupt alphabet or row-count mismatches are
|
|
409
|
+
rejected.
|
package/docs/SDK.md
CHANGED
|
@@ -1449,6 +1449,104 @@ the same durable coordinator, restoring annotations, linked artifacts,
|
|
|
1449
1449
|
lifecycle fields, and claim ownership on failure. It is the SDK primitive
|
|
1450
1450
|
behind `pm item complete`.
|
|
1451
1451
|
|
|
1452
|
+
`previewItemMutations` validates an ordered plan with the same transaction
|
|
1453
|
+
coordinator and lifecycle primitives as apply, using a disposable copy of the
|
|
1454
|
+
tracker. Earlier staged creates, evidence updates and closures participate in
|
|
1455
|
+
later validation. Existing journals retain the coordinator's replay and
|
|
1456
|
+
plan-identity behavior. The preview coordinator writes no source item, history,
|
|
1457
|
+
claim, lock or journal data. Active declarative extension registrations are preserved;
|
|
1458
|
+
executable extension guards, hooks, service overrides, and package command
|
|
1459
|
+
handlers remain disabled. Package-backed `--template` create input cannot be
|
|
1460
|
+
semantically previewed through its package handler; expand it into explicit core
|
|
1461
|
+
mutation options before preview.
|
|
1462
|
+
|
|
1463
|
+
Staging excludes derived `search` and `locks` content and unrelated runtime state,
|
|
1464
|
+
retaining registered item folders, explicitly configured schema files, and
|
|
1465
|
+
`runtime/session.json` for core focus and inherited-parent semantics. Root-layout
|
|
1466
|
+
trackers copy only tracker-owned files and directories, including standard and
|
|
1467
|
+
custom item folders and configured schema files; unrelated project content is
|
|
1468
|
+
excluded. Preview accepts regular files and directories. Entry checks reject
|
|
1469
|
+
existing interior symbolic links and special files; an explicitly selected root
|
|
1470
|
+
link is resolved once to establish the tracker boundary. Absolute configured
|
|
1471
|
+
schema paths inside that resolved boundary are
|
|
1472
|
+
remapped only in the staged settings. Schema files configured outside the
|
|
1473
|
+
tracker fail with `transaction_preview_external_schema`; relocate them inside
|
|
1474
|
+
the selected tracker root before retrying.
|
|
1475
|
+
|
|
1476
|
+
Preview requires trusted, stable directory entries and ancestors. Where Node
|
|
1477
|
+
exposes `O_NOFOLLOW` and `O_NONBLOCK`, descriptor opens request those POSIX guards.
|
|
1478
|
+
Windows retains entry checks, regular-file descriptor checks and snapshot
|
|
1479
|
+
comparisons without these flags. Portable Node APIs do not pin directory entries
|
|
1480
|
+
or ancestors, and later fingerprints cannot prevent hostile path redirection
|
|
1481
|
+
before a read. Use a caller-owned isolated copy when an untrusted actor can
|
|
1482
|
+
concurrently replace workspace paths.
|
|
1483
|
+
|
|
1484
|
+
Durable source bytes are fingerprinted before and after copying and compared
|
|
1485
|
+
with the staged copy. An inconsistent copy or a file disappearing during the
|
|
1486
|
+
scan fails with `transaction_preview_snapshot_changed` and can be retried.
|
|
1487
|
+
File contents are hashed in bounded streams so large history files do not
|
|
1488
|
+
require whole-file buffers. `PmCliError` failures from staged step inspection,
|
|
1489
|
+
compensation preparation and apply preserve their lifecycle classification and
|
|
1490
|
+
include a structured `transaction_operation` with the zero-based index,
|
|
1491
|
+
operation and requested target ID from the mutation plan, after any batch-local
|
|
1492
|
+
reference resolution. That ID need not be prefix-normalized. Native errors and
|
|
1493
|
+
compensation or recovery failures retain the coordinator's error semantics; if
|
|
1494
|
+
compensation also fails, its `AggregateError` preserves the decorated primary
|
|
1495
|
+
error.
|
|
1496
|
+
|
|
1497
|
+
CLI `item mutate --dry-run`, `item complete --dry-run`, and MCP `pm_mutate`
|
|
1498
|
+
with `dryRun: true` share this validation. CLI structured previews use
|
|
1499
|
+
`runWithConfigurationOnlySettings(pmRoot, run, isEnabled?)` across bootstrap,
|
|
1500
|
+
command execution and error cleanup. The optional predicate defaults to enabled.
|
|
1501
|
+
Scoped settings reads validate `settings.json` and
|
|
1502
|
+
merge inline configuration with defaults, without loading or scaffolding optional
|
|
1503
|
+
schema files, running settings-read hooks, or consulting or populating hydrated
|
|
1504
|
+
settings caches. Only selected bootstrap/action tracker roots, the actual global
|
|
1505
|
+
tracker root, and their resolved aliases are scoped.
|
|
1506
|
+
|
|
1507
|
+
Nested async-local scopes compose through new policy layers without modifying
|
|
1508
|
+
their ancestors. Matching-root reads evaluate live predicates, so returning
|
|
1509
|
+
`false` disables that layer while an enabled caller-owned ancestor can still
|
|
1510
|
+
protect the same root. Concurrent invocations keep separate policies, and scopes
|
|
1511
|
+
restore when the callback returns or throws. Staged and unrelated roots retain
|
|
1512
|
+
normal settings behavior, including schema-file hydration.
|
|
1513
|
+
|
|
1514
|
+
CLI bootstrap conservatively protects normalized invocations in the `item`
|
|
1515
|
+
namespace that contain a literal `--dry-run`, before extension option contracts
|
|
1516
|
+
are available. These settings policies cover command registration, invocation
|
|
1517
|
+
base-settings reads and parser-error cleanup. The earliest root `preAction` hook
|
|
1518
|
+
then settles invocation-owned policies from the actual selected command path and
|
|
1519
|
+
effective `optsWithGlobals()` values, before host-owned consent, migration and
|
|
1520
|
+
telemetry preparation. The real parser owns required-option values, `--`
|
|
1521
|
+
boundaries, positional child selection and inherited option precedence. For
|
|
1522
|
+
example, an extension's required `--package-note --dry-run` consumes `--dry-run`
|
|
1523
|
+
as its value. Without a separate preview flag, ordinary apply disables its own
|
|
1524
|
+
policy layers and resumes normal source/global settings hydration, consent,
|
|
1525
|
+
identity initialization and migration preparation. Explicit caller-owned layers
|
|
1526
|
+
remain effective. Genuine previews remain scoped when extension options are
|
|
1527
|
+
present.
|
|
1528
|
+
Structured CLI previews skip host-owned extension
|
|
1529
|
+
migration execution, first-use telemetry consent persistence and installation-ID
|
|
1530
|
+
initialization. Pending migration effects on a later commit remain unvalidated.
|
|
1531
|
+
Existing consented telemetry with a persisted identity still
|
|
1532
|
+
enters derived local queues; preview schedules no flush worker, and later normal
|
|
1533
|
+
commands retain delivery. Normal CLI extension discovery and activation happen
|
|
1534
|
+
before staged execution and retain their existing policy. CLI parser/preflight
|
|
1535
|
+
overrides and before/after-command hooks are also outside staged
|
|
1536
|
+
suppression; `--no-extensions` disables those executable paths.
|
|
1537
|
+
|
|
1538
|
+
`ItemMutationPreviewValidation`
|
|
1539
|
+
reports `validated: true, state: "staged_snapshot"` when the coordinator
|
|
1540
|
+
executes the staged plan. An already committed journal instead returns
|
|
1541
|
+
`validated: false, state: "replayed_committed_plan"`, matching idempotent apply
|
|
1542
|
+
without freshly executing or validating the supplied lifecycle steps. Both
|
|
1543
|
+
results disclose
|
|
1544
|
+
`unresolved_commit_constraints: ["concurrent_tracker_changes",
|
|
1545
|
+
"extension_mutation_guards_and_hooks"]`. Newly staged validation proves core
|
|
1546
|
+
semantic validity at that snapshot; commit still checks current state and runs
|
|
1547
|
+
extension guards and hooks. Preview cost is proportional to the tracker data
|
|
1548
|
+
staged, rather than unrelated root-layout project content.
|
|
1549
|
+
|
|
1452
1550
|
`itemDocumentToMutationOptions` is the companion full-document adapter. It
|
|
1453
1551
|
accepts either a direct `ItemDocument` or the envelope returned by
|
|
1454
1552
|
`pm get <id> --json`, strips read-only metadata, maps canonical snake-case item
|
|
@@ -4,12 +4,12 @@ Tracker: `pm-f05lsg`.
|
|
|
4
4
|
|
|
5
5
|
Every catalog code is listed. An `uncovered` row is an explicit closure obligation, never an omission or implied approval.
|
|
6
6
|
|
|
7
|
-
- Catalog error codes:
|
|
7
|
+
- Catalog error codes: 393
|
|
8
8
|
- Executable error codes: 19
|
|
9
9
|
- Executable-code ratchet floor: 18
|
|
10
10
|
- Required executable canonical codes: `bulk_ids_input_empty`, `bulk_ids_input_missing_path`, `bulk_ids_input_unreadable`, `invalid_argument_value`, `manifest_unknown_key`, `missing_lifecycle_target`, `missing_required_argument`, `no_version_bounds_declared`, `projection_options_mutually_exclusive`, `tracker_not_initialized`, `tracker_root_missing`, `tracker_root_not_directory`, `tracker_root_unreadable`, `unknown_context_intent`, `unknown_field_projection`, `unknown_option`, `unknown_subcommand`
|
|
11
|
-
- Uncovered error codes:
|
|
12
|
-
- Coverage fraction: 0.
|
|
11
|
+
- Uncovered error codes: 374
|
|
12
|
+
- Coverage fraction: 0.048346
|
|
13
13
|
- Closed-domain probes: 19
|
|
14
14
|
- Grammar probes: 117
|
|
15
15
|
|
|
@@ -200,6 +200,7 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
200
200
|
| `mcp_annotation_file_unavailable` | `mcp_annotation_file_unavailable` | uncovered | none | 0 |
|
|
201
201
|
| `mcp_stdin_unavailable` | `mcp_stdin_unavailable` | uncovered | none | 0 |
|
|
202
202
|
| `mcp_task_not_found_or_not_authorized` | `mcp_task_not_found_or_not_authorized` | uncovered | none | 0 |
|
|
203
|
+
| `merge_bun_launcher_unavailable` | `merge_bun_launcher_unavailable` | uncovered | none | 0 |
|
|
203
204
|
| `merge_conflict_markers_detected` | `merge_conflict_markers_detected` | uncovered | none | 0 |
|
|
204
205
|
| `merge_decisions_unreviewed` | `merge_decisions_unreviewed` | uncovered | none | 0 |
|
|
205
206
|
| `merge_driver_configuration_drift` | `merge_driver_configuration_drift` | uncovered | none | 0 |
|
|
@@ -320,6 +321,8 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
320
321
|
| `tracker_root_missing` | `tracker_root_missing` | executable | owned_state | 1 |
|
|
321
322
|
| `tracker_root_not_directory` | `tracker_root_not_directory` | executable | owned_state | 1 |
|
|
322
323
|
| `tracker_root_unreadable` | `tracker_root_unreadable` | executable | owned_state | 1 |
|
|
324
|
+
| `transaction_preview_external_schema` | `transaction_preview_external_schema` | uncovered | none | 0 |
|
|
325
|
+
| `transaction_preview_snapshot_changed` | `transaction_preview_snapshot_changed` | uncovered | none | 0 |
|
|
323
326
|
| `type_duplicate` | `type_duplicate` | uncovered | none | 0 |
|
|
324
327
|
| `type_invalid` | `type_invalid` | uncovered | none | 0 |
|
|
325
328
|
| `undeclared_observation` | `undeclared_observation` | uncovered | none | 0 |
|
package/marketplace.json
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
"url": "https://github.com/unbraind/pm-cli"
|
|
6
6
|
},
|
|
7
7
|
"description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
|
|
8
|
-
"version": "2026.
|
|
8
|
+
"version": "2026.10.2",
|
|
9
9
|
"plugins": [
|
|
10
10
|
{
|
|
11
11
|
"name": "pm-claude",
|
|
12
12
|
"source": "./plugins/pm-claude",
|
|
13
13
|
"description": "Native pm CLI integration for Claude Code — 32 MCP tools, 14 workflow skills with slash invocations, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
|
|
14
|
-
"version": "2026.
|
|
14
|
+
"version": "2026.10.2",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "unbrained",
|
|
17
17
|
"url": "https://github.com/unbraind/pm-cli"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-digital-twin",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.10.2",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Beyond-PM exemplar: a temporal production-facility digital twin built entirely on public pm SDK and extension primitives.",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "pm-claude",
|
|
4
4
|
"displayName": "pm CLI",
|
|
5
5
|
"description": "Native pm CLI integration for Claude Code — 32 MCP tools, 14 skills with slash invocations, 4 subagents (coordinator, delivery-chain, triage, verification), hybrid TUI task tracking (pm as persistent store + Claude Code task panel as live view), session context injection, and full git-based project management without leaving Claude Code.",
|
|
6
|
-
"version": "2026.
|
|
6
|
+
"version": "2026.10.2",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "unbrained",
|
|
9
9
|
"url": "https://github.com/unbraind/pm-cli"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "pm-codex",
|
|
4
|
-
"version": "2026.
|
|
4
|
+
"version": "2026.10.2",
|
|
5
5
|
"description": "Repository-native project context workflows and a version-pinned pm MCP server for Codex.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "unbrained",
|