@unbrained/pm-cli 2026.8.21 → 2026.8.23
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 +44 -0
- package/dist/cli/error-guidance.d.ts +22 -4
- package/dist/cli/error-guidance.js +73 -16
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +51 -9
- package/dist/cli/register-mutation.js +6 -6
- package/dist/cli/register-operations.d.ts +73 -0
- package/dist/cli/register-operations.js +39 -14
- package/dist/cli/register-setup.js +3 -3
- package/dist/cli/schema-registration-helpers.d.ts +8 -1
- package/dist/cli/schema-registration-helpers.js +14 -5
- package/dist/cli-bundle/bundle-manifest.json +149 -149
- package/dist/cli-bundle/chunks/chunk-3ENVHX6C.js +36 -0
- package/dist/cli-bundle/chunks/{chunk-LOVTQ52Z.js → chunk-DW2CGEMU.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-EG6CLDZT.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-LARJJ3RK.js → chunk-F3AI2JFL.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-N3DSV4CH.js → chunk-HWZ6CELB.js} +8 -8
- package/dist/cli-bundle/chunks/chunk-HZBMLSZI.js +201 -0
- package/dist/cli-bundle/chunks/chunk-JB4KZWBF.js +3 -0
- package/dist/cli-bundle/chunks/chunk-KPH73XXJ.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-BKYB45NQ.js → chunk-KXPMB2YL.js} +50 -50
- package/dist/cli-bundle/chunks/{chunk-BUNIEJNE.js → chunk-QDVHNHAQ.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TFI5V5N2.js +13 -0
- package/dist/cli-bundle/chunks/{register-list-query-F57EWDEF.js → register-list-query-UJB5FMV2.js} +2 -2
- package/dist/cli-bundle/chunks/register-mutation-NX5XE4VX.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-RXIJIYXC.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-HXU7IZZD.js → register-setup-GFUZEKRE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-F4YEW5I2.js → chunk-37Z4OEAP.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3UPTYG44.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-5S7E72FY.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-4ERLO7QD.js → chunk-AUFH5H35.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-E7X25GC3.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-FQCSTBWE.js +4 -0
- package/dist/cli-bundle/focused-chunks/{chunk-FH6DYED3.js → chunk-FZS4H32O.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-IFLWKY2R.js +156 -0
- package/dist/cli-bundle/focused-chunks/{chunk-YKBKIEAJ.js → chunk-JOWDB2MH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-LYVSW5VM.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-MRCNF3U6.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-UZE7XUZK.js → chunk-OFVUGTLJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FJ22HNRP.js → chunk-OGLQBL46.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-OY7QAV4Y.js +51 -0
- package/dist/cli-bundle/focused-chunks/chunk-QGFNI65N.js +26 -0
- package/dist/cli-bundle/focused-chunks/{chunk-KDNG7TKQ.js → chunk-R27IDGHD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-UYRFYCDQ.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2NIY5NKG.js → chunk-ZHVA42R5.js} +9 -9
- package/dist/cli-bundle/main.js +13 -13
- 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 +40 -40
- 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 +33 -32
- 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 +5 -5
- package/dist/core/config/nested-settings.js +8 -2
- package/dist/core/config/positional-value.d.ts +1 -1
- package/dist/core/config/positional-value.js +5 -2
- package/dist/core/extensions/extension-hook-runtime.js +22 -20
- package/dist/core/extensions/extension-types.d.ts +8 -1
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +7 -3
- package/dist/core/extensions/service-ownership.d.ts +8 -0
- package/dist/core/extensions/service-ownership.js +20 -0
- package/dist/core/history/history.js +3 -3
- package/dist/core/item/id.js +20 -5
- package/dist/core/item/item-format.js +81 -2
- package/dist/core/reproducibility/context.d.ts +4 -0
- package/dist/core/reproducibility/context.js +14 -8
- package/dist/core/shared/author.d.ts +55 -1
- package/dist/core/shared/author.js +333 -16
- package/dist/core/shared/constants.js +3 -2
- package/dist/core/shared/errors.d.ts +4 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/store/settings-validator.d.ts +1 -0
- package/dist/core/store/settings-validator.js +6 -3
- package/dist/core/store/settings.js +5 -2
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +30 -9
- package/dist/sdk/agent/identity-config.d.ts +63 -0
- package/dist/sdk/agent/identity-config.js +107 -0
- package/dist/sdk/agent/refusal-corpus-contracts.d.ts +76 -0
- package/dist/sdk/agent/refusal-corpus-contracts.js +194 -0
- package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
- package/dist/sdk/authoring.d.ts +1 -1
- package/dist/sdk/authoring.js +2 -2
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +77 -0
- package/dist/sdk/cli-contracts/agent-output-contracts.js +326 -2
- package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
- package/dist/sdk/cli-contracts/flag-contracts.js +9 -2
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +4 -4
- package/dist/sdk/cli-contracts/registration-helpers.js +5 -2
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +3 -1
- package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +22 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +14 -3
- package/dist/sdk/cli-contracts.d.ts +4 -4
- package/dist/sdk/cli-contracts.js +5 -5
- package/dist/sdk/config.d.ts +6 -1
- package/dist/sdk/config.js +119 -14
- package/dist/sdk/context-intent-contracts.js +4 -2
- package/dist/sdk/core-governance.d.ts +1 -1
- package/dist/sdk/core-governance.js +3 -3
- package/dist/sdk/extension/install-sources.d.ts +1 -1
- package/dist/sdk/extension/install-sources.js +6 -3
- package/dist/sdk/extension/output-ownership.d.ts +1 -0
- package/dist/sdk/extension/output-ownership.js +3 -2
- package/dist/sdk/extension/scaffold.js +11 -5
- package/dist/sdk/flag-invocation-contracts.js +4 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +74 -2
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +87 -26
- package/dist/sdk/governance/assurance-action.js +30 -10
- package/dist/sdk/governance/health.d.ts +3 -0
- package/dist/sdk/governance/health.js +39 -7
- package/dist/sdk/governance/hierarchy-validation.d.ts +29 -0
- package/dist/sdk/governance/hierarchy-validation.js +109 -0
- package/dist/sdk/governance/validate.d.ts +3 -9
- package/dist/sdk/governance/validate.js +84 -111
- package/dist/sdk/graph/assembly.d.ts +6 -1
- package/dist/sdk/graph/assembly.js +16 -22
- package/dist/sdk/graph/governance-contracts.d.ts +1 -1
- package/dist/sdk/graph/governance-contracts.js +8 -2
- package/dist/sdk/graph/governance.js +46 -2
- package/dist/sdk/graph/hierarchy-integrity.d.ts +94 -0
- package/dist/sdk/graph/hierarchy-integrity.js +311 -0
- package/dist/sdk/graph/index.d.ts +2 -1
- package/dist/sdk/graph/index.js +3 -2
- package/dist/sdk/graph/remediation.js +32 -2
- package/dist/sdk/graph/run.d.ts +31 -2
- package/dist/sdk/graph/run.js +80 -31
- package/dist/sdk/graph/workspace-relationship-kind-registry.d.ts +8 -0
- package/dist/sdk/graph/workspace-relationship-kind-registry.js +28 -0
- package/dist/sdk/index.d.ts +8 -3
- package/dist/sdk/index.js +9 -4
- package/dist/sdk/item-children.js +21 -8
- package/dist/sdk/lifecycle/create.js +129 -97
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.d.ts +15 -0
- package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +25 -0
- package/dist/sdk/lifecycle/update.d.ts +2 -0
- package/dist/sdk/lifecycle/update.js +174 -84
- package/dist/sdk/merge/three-way.js +105 -26
- package/dist/sdk/query/complete-list.d.ts +3 -3
- package/dist/sdk/query/complete-list.js +46 -3
- package/dist/sdk/query/list.d.ts +4 -3
- package/dist/sdk/query/list.js +89 -49
- package/dist/sdk/read-output-budget.d.ts +21 -0
- package/dist/sdk/read-output-budget.js +39 -2
- package/dist/sdk/read-output-contracts.d.ts +10 -4
- package/dist/sdk/read-output-contracts.js +105 -32
- package/dist/sdk/relationship-context.js +3 -4
- package/dist/sdk/relationships.js +17 -10
- package/dist/sdk/reproducibility/process.d.ts +19 -0
- package/dist/sdk/reproducibility/process.js +88 -0
- package/dist/sdk/runtime-primitives.d.ts +1 -1
- package/dist/sdk/runtime-primitives.js +3 -3
- package/dist/sdk/runtime.d.ts +3 -2
- package/dist/sdk/runtime.js +7 -5
- package/dist/sdk/test/batch.d.ts +6 -0
- package/dist/sdk/test/batch.js +26 -6
- package/dist/sdk/test/entry.d.ts +1 -1
- package/dist/sdk/test/entry.js +3 -2
- package/dist/sdk/test/execution.d.ts +28 -3
- package/dist/sdk/test/execution.js +201 -34
- package/dist/sdk/test/parsers.d.ts +6 -0
- package/dist/sdk/test/parsers.js +21 -2
- package/dist/sdk/test/trust.d.ts +33 -0
- package/dist/sdk/test/trust.js +207 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_PROVENANCE_ADR.md +41 -5
- package/docs/AGENT_UX_CONTRACTS.md +20 -4
- package/docs/COMMANDS.md +29 -14
- package/docs/CONFIGURATION.md +4 -0
- package/docs/DEPENDENCY_KIND_CONTRACT.md +31 -3
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +115 -0
- package/docs/EXTENSIONS.md +2 -1
- package/docs/MERGE_SAFETY.md +15 -1
- package/docs/README.md +1 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +19 -2
- package/docs/RELATIONSHIP_GRAPH.md +6 -3
- package/docs/REPRODUCIBLE_WORKSPACES.md +42 -8
- package/docs/SDK.md +9 -0
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +6 -4
- package/docs/SDK_EVIDENCE_TRACEABILITY.md +1 -1
- package/docs/TESTING.md +83 -1
- package/docs/agent-task-token-baseline.json +2 -2
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
- package/marketplace.json +2 -2
- package/package.json +2 -2
- 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-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +1021 -53
- package/dist/cli-bundle/chunks/chunk-2MA6ZQVZ.js +0 -197
- package/dist/cli-bundle/chunks/chunk-3AFAUHUE.js +0 -2
- package/dist/cli-bundle/chunks/chunk-7VHZS727.js +0 -5
- package/dist/cli-bundle/chunks/chunk-JSLOFXGA.js +0 -3
- package/dist/cli-bundle/chunks/chunk-OCLPLFAY.js +0 -35
- package/dist/cli-bundle/chunks/chunk-S4IRYKBU.js +0 -13
- package/dist/cli-bundle/chunks/register-mutation-7IY2D5KO.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-FALL3YTU.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-7WZRLCYF.js +0 -50
- package/dist/cli-bundle/focused-chunks/chunk-CKKQSJNN.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-EEFKYMDR.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-F2A56DHV.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-FV5ACOK7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-JEAVFOWM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-NJ63LOP6.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-NXRTQ7HI.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-TJ7EMJ46.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-ZOSEELYJ.js +0 -26
|
@@ -4,18 +4,22 @@
|
|
|
4
4
|
* Implements the pm create command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!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]="
|
|
7
|
+
!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]="f8c8e154-737b-58db-9a8b-7f4399342e83")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
9
|
-
import { removeFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, generateItemId, normalizeItemId, canonicalDocument, normalizeItemMetadata, serializeItemDocument, assertParentReferenceIsNotSelf, isPlaceholderReferenceToken, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, resolvePriority, getFocusedItem, normalizeStatusInput, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, acquireLock, printError, buildInvalidTypeError, resolveTypeSynonym, collectRuntimeCreateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, ITEM_METADATA_KEY_ORDER, PmCliError, nowIso, resolveIsoOrRelative, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveCommandHandler, runActiveBeforeMutationHooks, runActiveOnWriteHooks, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, listAllItemMetadataLight, locateItem, createMutationGuardSdk, getHistoryPath, getItemPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
|
|
9
|
+
import { removeFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, generateItemId, normalizeItemId, canonicalDocument, normalizeItemMetadata, serializeItemDocument, assertParentReferenceIsNotSelf, isPlaceholderReferenceToken, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, resolvePriority, getFocusedItem, normalizeStatusInput, isTerminalStatus, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, acquireLock, printError, buildInvalidTypeError, resolveTypeSynonym, collectRuntimeCreateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, ITEM_METADATA_KEY_ORDER, PmCliError, nowIso, resolveIsoOrRelative, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveCommandHandler, runActiveBeforeMutationHooks, runActiveOnWriteHooks, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, listAllItemMetadataLight, locateItem, createMutationGuardSdk, getHistoryPath, getItemPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
|
|
10
10
|
import { requireTerminalReasonWithRecovery } from "../lifecycle-policy.js";
|
|
11
11
|
import { evaluateSimilarityGovernance, similarityAdvisoryWarnings, } from "../similarity.js";
|
|
12
12
|
import { acquireItemMetadataDerivedIndexLock, refreshItemMetadataDerivedIndex, } from "../item-metadata-index.js";
|
|
13
13
|
import { collectNewOrderingCycleWarnings } from "../graph/mutation-advisory.js";
|
|
14
|
+
import { assertHierarchyMutationAllowed } from "../graph/hierarchy-integrity.js";
|
|
15
|
+
import { resolveWorkspaceRelationshipKindRegistry } from "../graph/assembly.js";
|
|
16
|
+
import { acquireHierarchyMutationLock } from "./hierarchy-mutation-lock.js";
|
|
14
17
|
import { normalizeRiskInput, normalizeSeverityInput, parseConfidenceInput, parseRegressionInput, } from "./metadata-normalizers.js";
|
|
15
18
|
import { applyLegacyNoneCollectionNormalizers, createLegacyNoneCollectionNormalizers, assertNoLegacyNoneToken, assertNoLegacyNoneTokens, isLegacyNoneToken, } from "./legacy-none-tokens.js";
|
|
16
19
|
import { suggestNextLifecycleTransition, } from "./lifecycle-transitions.js";
|
|
17
|
-
import { parseLinkedTestAssertionEqualsMap, parseLinkedTestAssertionGteMap, parseLinkedTestBoolean, parseLinkedTestContextMode, parseLinkedTestEnvClear, parseLinkedTestEnvSet, parseLinkedTestMinLines, parseLinkedTestRegexList, parseLinkedTestStringList, } from "../test/parsers.js";
|
|
20
|
+
import { parseLinkedTestAssertionEqualsMap, parseLinkedTestAssertionGteMap, parseLinkedTestBoolean, parseLinkedTestContextMode, parseLinkedTestEnvClear, parseLinkedTestEnvSet, parseLinkedTestMinLines, parseLinkedTestRegexList, parseLinkedTestStringList, parseLinkedTestWorkspaceContextMode, } from "../test/parsers.js";
|
|
18
21
|
import { looksLikeStructuredLinkedTestEntry, normalizeStructuredLinkedTestEntry, } from "../test/entry.js";
|
|
22
|
+
import { attachLinkedTestMutationProvenance } from "../test/trust.js";
|
|
19
23
|
import { COMMON_UNSET_FIELD_DEFINITIONS_AFTER_AUTHOR, COMMON_UNSET_FIELD_DEFINITIONS_BEFORE_AUTHOR, parseCommandUnsetTargets, resolveRuntimeUnsetFieldDefinition, } from "./shared-unset-fields.js";
|
|
20
24
|
import { ensureEnumValue } from "./recurrence-parsers.js";
|
|
21
25
|
import { assertDependencyEdgesAllowed, assertDependencyTargetsResolvable, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
|
|
@@ -324,6 +328,7 @@ export function parseTests(raw) {
|
|
|
324
328
|
? parseOptionalNumber(timeoutRaw, "timeout_seconds")
|
|
325
329
|
: undefined,
|
|
326
330
|
pm_context_mode: parseLinkedTestContextMode(kv.pm_context_mode, "--test"),
|
|
331
|
+
workspace_context_mode: parseLinkedTestWorkspaceContextMode(kv.workspace_context_mode, "--test"),
|
|
327
332
|
env_set: parseLinkedTestEnvSet(kv.env_set, "--test"),
|
|
328
333
|
env_clear: parseLinkedTestEnvClear(kv.env_clear, "--test"),
|
|
329
334
|
shared_host_safe: parseLinkedTestBoolean(kv.shared_host_safe, "--test", "shared_host_safe"),
|
|
@@ -1440,114 +1445,140 @@ async function writeCreatedItem(params) {
|
|
|
1440
1445
|
const { pmRoot, type, id, settings, typeRegistry, author, extensionFieldNames, afterDocument, beforeDocument, historyMessage, changedFields, nowValue, similarityCandidate, allowDuplicate, } = params;
|
|
1441
1446
|
const itemPath = getItemPath(pmRoot, type, id, settings.item_format, typeRegistry.type_to_folder);
|
|
1442
1447
|
const historyPath = getHistoryPath(pmRoot, id);
|
|
1443
|
-
const
|
|
1448
|
+
const relationshipRegistry = resolveWorkspaceRelationshipKindRegistry();
|
|
1449
|
+
const hierarchyMutationRequired = afterDocument.metadata.parent !== undefined ||
|
|
1450
|
+
(afterDocument.metadata.dependencies ?? []).some((dependency) => relationshipRegistry.resolve(dependency.kind)?.hierarchy);
|
|
1451
|
+
const hierarchyLockRelease = await acquireHierarchyMutationLock({
|
|
1452
|
+
pmRoot,
|
|
1453
|
+
author,
|
|
1454
|
+
ttlSeconds: settings.locks.ttl_seconds,
|
|
1455
|
+
waitMs: settings.locks.wait_ms,
|
|
1456
|
+
required: hierarchyMutationRequired,
|
|
1457
|
+
});
|
|
1458
|
+
let hierarchyLockHeld = hierarchyMutationRequired;
|
|
1444
1459
|
let hookWarnings = [];
|
|
1445
1460
|
try {
|
|
1446
|
-
const
|
|
1447
|
-
afterDocument.metadata.dependencies.length > 0
|
|
1448
|
-
? await listAllItemMetadataLight(pmRoot, settings.item_format, typeRegistry.type_to_folder, undefined, settings.schema)
|
|
1449
|
-
: undefined;
|
|
1450
|
-
const existing = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
|
|
1451
|
-
if (existing) {
|
|
1452
|
-
throw new PmCliError(`Item "${id}" already exists`, EXIT_CODE.CONFLICT);
|
|
1453
|
-
}
|
|
1454
|
-
await runActiveBeforeMutationHooks({
|
|
1455
|
-
pm_root: pmRoot,
|
|
1456
|
-
operation: "create",
|
|
1457
|
-
before: null,
|
|
1458
|
-
after: afterDocument,
|
|
1459
|
-
changed_fields: changedFields,
|
|
1460
|
-
sdk: createMutationGuardSdk({
|
|
1461
|
-
pmRoot,
|
|
1462
|
-
settings,
|
|
1463
|
-
typeToFolder: typeRegistry.type_to_folder,
|
|
1464
|
-
}),
|
|
1465
|
-
});
|
|
1466
|
-
const releaseDerivedIndexLock = await acquireItemMetadataDerivedIndexLock(pmRoot, author, {
|
|
1467
|
-
required: settings.governance.duplicate_detection_mode === "strict" &&
|
|
1468
|
-
allowDuplicate !== true,
|
|
1469
|
-
});
|
|
1470
|
-
let derivedIndexWarnings = [];
|
|
1461
|
+
const lockRelease = await acquireLock(pmRoot, id, settings.locks.ttl_seconds, author, false, settings.governance.force_required_for_stale_lock, settings.locks.wait_ms);
|
|
1471
1462
|
try {
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1463
|
+
const graphBeforeCreate = afterDocument.metadata.parent !== undefined ||
|
|
1464
|
+
(afterDocument.metadata.dependencies !== undefined &&
|
|
1465
|
+
afterDocument.metadata.dependencies.length > 0)
|
|
1466
|
+
? await listAllItemMetadataLight(pmRoot, settings.item_format, typeRegistry.type_to_folder, undefined, settings.schema)
|
|
1467
|
+
: undefined;
|
|
1468
|
+
const existing = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
|
|
1469
|
+
if (existing) {
|
|
1470
|
+
throw new PmCliError(`Item "${id}" already exists`, EXIT_CODE.CONFLICT);
|
|
1471
|
+
}
|
|
1472
|
+
if (graphBeforeCreate) {
|
|
1473
|
+
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
1474
|
+
assertHierarchyMutationAllowed(graphBeforeCreate, [...graphBeforeCreate, afterDocument.metadata], id, (status) => isTerminalStatus(status, statusRegistry), relationshipRegistry);
|
|
1475
|
+
}
|
|
1476
|
+
await runActiveBeforeMutationHooks({
|
|
1477
|
+
pm_root: pmRoot,
|
|
1478
|
+
operation: "create",
|
|
1479
|
+
before: null,
|
|
1480
|
+
after: afterDocument,
|
|
1481
|
+
changed_fields: changedFields,
|
|
1482
|
+
sdk: createMutationGuardSdk({
|
|
1475
1483
|
pmRoot,
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1484
|
+
settings,
|
|
1485
|
+
typeToFolder: typeRegistry.type_to_folder,
|
|
1486
|
+
}),
|
|
1487
|
+
});
|
|
1488
|
+
const releaseDerivedIndexLock = await acquireItemMetadataDerivedIndexLock(pmRoot, author, {
|
|
1489
|
+
required: settings.governance.duplicate_detection_mode === "strict" &&
|
|
1490
|
+
allowDuplicate !== true,
|
|
1491
|
+
});
|
|
1492
|
+
let derivedIndexWarnings = [];
|
|
1493
|
+
try {
|
|
1494
|
+
if (settings.governance.duplicate_detection_mode === "strict" &&
|
|
1495
|
+
allowDuplicate !== true) {
|
|
1496
|
+
await evaluateSimilarityGovernance(similarityCandidate, {
|
|
1497
|
+
pmRoot,
|
|
1498
|
+
mode: "strict",
|
|
1499
|
+
threshold: settings.governance.duplicate_detection_threshold,
|
|
1500
|
+
limit: settings.governance.duplicate_detection_limit,
|
|
1501
|
+
allowDuplicate: false,
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1504
|
+
await writeFileAtomic(itemPath, serializeItemDocument(afterDocument, {
|
|
1505
|
+
format: settings.item_format,
|
|
1506
|
+
schema: settings.schema,
|
|
1507
|
+
extensionFieldNames,
|
|
1508
|
+
}));
|
|
1509
|
+
try {
|
|
1510
|
+
const entry = createHistoryEntry({
|
|
1511
|
+
nowIso: nowValue,
|
|
1512
|
+
author,
|
|
1513
|
+
op: "create",
|
|
1514
|
+
before: beforeDocument,
|
|
1515
|
+
after: afterDocument,
|
|
1516
|
+
message: historyMessage,
|
|
1517
|
+
});
|
|
1518
|
+
await appendHistoryEntry(historyPath, entry);
|
|
1519
|
+
}
|
|
1520
|
+
catch (error) {
|
|
1521
|
+
await removeFileIfExists(itemPath);
|
|
1522
|
+
throw error;
|
|
1523
|
+
}
|
|
1524
|
+
if (hierarchyLockHeld) {
|
|
1525
|
+
await hierarchyLockRelease();
|
|
1526
|
+
hierarchyLockHeld = false;
|
|
1527
|
+
}
|
|
1528
|
+
derivedIndexWarnings = await refreshItemMetadataDerivedIndex({
|
|
1529
|
+
pmRoot,
|
|
1530
|
+
preferredFormat: settings.item_format,
|
|
1531
|
+
typeToFolder: typeRegistry.type_to_folder,
|
|
1532
|
+
schema: settings.schema,
|
|
1533
|
+
itemPath,
|
|
1534
|
+
document: afterDocument,
|
|
1480
1535
|
});
|
|
1481
1536
|
}
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1537
|
+
finally {
|
|
1538
|
+
await releaseDerivedIndexLock();
|
|
1539
|
+
}
|
|
1540
|
+
hookWarnings = [
|
|
1541
|
+
...(graphBeforeCreate
|
|
1542
|
+
? collectNewOrderingCycleWarnings(graphBeforeCreate, [...graphBeforeCreate, afterDocument.metadata], id)
|
|
1543
|
+
: []),
|
|
1544
|
+
...derivedIndexWarnings,
|
|
1545
|
+
...(await runActiveOnWriteHooks({
|
|
1546
|
+
path: itemPath,
|
|
1547
|
+
scope: "project",
|
|
1491
1548
|
op: "create",
|
|
1549
|
+
item_id: afterDocument.metadata.id,
|
|
1550
|
+
item_type: afterDocument.metadata.type,
|
|
1492
1551
|
before: beforeDocument,
|
|
1493
1552
|
after: afterDocument,
|
|
1494
|
-
|
|
1495
|
-
})
|
|
1496
|
-
await
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1553
|
+
changed_fields: changedFields,
|
|
1554
|
+
})),
|
|
1555
|
+
...(await runActiveOnWriteHooks({
|
|
1556
|
+
path: historyPath,
|
|
1557
|
+
scope: "project",
|
|
1558
|
+
op: "create:history",
|
|
1559
|
+
item_id: afterDocument.metadata.id,
|
|
1560
|
+
item_type: afterDocument.metadata.type,
|
|
1561
|
+
before: beforeDocument,
|
|
1562
|
+
after: afterDocument,
|
|
1563
|
+
changed_fields: changedFields,
|
|
1564
|
+
})),
|
|
1565
|
+
];
|
|
1566
|
+
recordAfterCommandAffectedItem({
|
|
1567
|
+
id: afterDocument.metadata.id,
|
|
1568
|
+
op: "create",
|
|
1569
|
+
item_type: afterDocument.metadata.type,
|
|
1570
|
+
status: afterDocument.metadata.status,
|
|
1571
|
+
current: projectAfterCommandItemSnapshot(afterDocument.metadata, changedFields),
|
|
1572
|
+
changed_fields: changedFields,
|
|
1509
1573
|
});
|
|
1510
1574
|
}
|
|
1511
1575
|
finally {
|
|
1512
|
-
await
|
|
1576
|
+
await lockRelease();
|
|
1513
1577
|
}
|
|
1514
|
-
hookWarnings = [
|
|
1515
|
-
...(graphBeforeCreate
|
|
1516
|
-
? collectNewOrderingCycleWarnings(graphBeforeCreate, [...graphBeforeCreate, afterDocument.metadata], id)
|
|
1517
|
-
: []),
|
|
1518
|
-
...derivedIndexWarnings,
|
|
1519
|
-
...(await runActiveOnWriteHooks({
|
|
1520
|
-
path: itemPath,
|
|
1521
|
-
scope: "project",
|
|
1522
|
-
op: "create",
|
|
1523
|
-
item_id: afterDocument.metadata.id,
|
|
1524
|
-
item_type: afterDocument.metadata.type,
|
|
1525
|
-
before: beforeDocument,
|
|
1526
|
-
after: afterDocument,
|
|
1527
|
-
changed_fields: changedFields,
|
|
1528
|
-
})),
|
|
1529
|
-
...(await runActiveOnWriteHooks({
|
|
1530
|
-
path: historyPath,
|
|
1531
|
-
scope: "project",
|
|
1532
|
-
op: "create:history",
|
|
1533
|
-
item_id: afterDocument.metadata.id,
|
|
1534
|
-
item_type: afterDocument.metadata.type,
|
|
1535
|
-
before: beforeDocument,
|
|
1536
|
-
after: afterDocument,
|
|
1537
|
-
changed_fields: changedFields,
|
|
1538
|
-
})),
|
|
1539
|
-
];
|
|
1540
|
-
recordAfterCommandAffectedItem({
|
|
1541
|
-
id: afterDocument.metadata.id,
|
|
1542
|
-
op: "create",
|
|
1543
|
-
item_type: afterDocument.metadata.type,
|
|
1544
|
-
status: afterDocument.metadata.status,
|
|
1545
|
-
current: projectAfterCommandItemSnapshot(afterDocument.metadata, changedFields),
|
|
1546
|
-
changed_fields: changedFields,
|
|
1547
|
-
});
|
|
1548
1578
|
}
|
|
1549
1579
|
finally {
|
|
1550
|
-
|
|
1580
|
+
if (hierarchyLockHeld)
|
|
1581
|
+
await hierarchyLockRelease();
|
|
1551
1582
|
}
|
|
1552
1583
|
return hookWarnings;
|
|
1553
1584
|
}
|
|
@@ -1576,6 +1607,7 @@ export async function runCreate(options, global) {
|
|
|
1576
1607
|
const learnings = parseLogSeed("--learning", resolvedOptions.learning, nowValue, author);
|
|
1577
1608
|
const files = parseFiles(resolvedOptions.file);
|
|
1578
1609
|
const tests = parseTests(resolvedOptions.test);
|
|
1610
|
+
tests.values = await attachLinkedTestMutationProvenance(tests.values, author, nowValue);
|
|
1579
1611
|
const docs = parseDocs(resolvedOptions.doc);
|
|
1580
1612
|
const reminders = parseReminders(resolvedOptions.reminder, nowValue);
|
|
1581
1613
|
const events = parseEvents(resolvedOptions.event, nowValue);
|
|
@@ -1886,4 +1918,4 @@ export const _testOnlyCreateCommand = {
|
|
|
1886
1918
|
typeOptionExampleValue,
|
|
1887
1919
|
};
|
|
1888
1920
|
//# sourceMappingURL=create.js.map
|
|
1889
|
-
//# debugId=
|
|
1921
|
+
//# debugId=f8c8e154-737b-58db-9a8b-7f4399342e83
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Inputs for the internal workspace-wide hierarchy mutation lock. */
|
|
2
|
+
export interface HierarchyMutationLockOptions {
|
|
3
|
+
/** Tracker root whose hierarchy is being changed. */
|
|
4
|
+
pmRoot: string;
|
|
5
|
+
/** Principal recorded as the lock owner. */
|
|
6
|
+
author: string;
|
|
7
|
+
/** Tracker-configured stale-lock lifetime. */
|
|
8
|
+
ttlSeconds: number;
|
|
9
|
+
/** Tracker-configured bounded lock wait. */
|
|
10
|
+
waitMs: number;
|
|
11
|
+
/** Whether this mutation can add hierarchy evidence. */
|
|
12
|
+
required: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Acquire the shared hierarchy writer lock, or return a no-op release. */
|
|
15
|
+
export declare function acquireHierarchyMutationLock(options: HierarchyMutationLockOptions): Promise<() => Promise<void>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/lifecycle/hierarchy-mutation-lock
|
|
3
|
+
*
|
|
4
|
+
* Serializes hierarchy-affecting create and update transactions so each
|
|
5
|
+
* before/after integrity decision is made from a fresh workspace snapshot.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
!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]="39a36d42-29b1-5f0f-a8b2-f3bfc0ef78c2")}catch(e){}}();
|
|
9
|
+
import { acquireLock } from "../../core/lock/lock.js";
|
|
10
|
+
const HIERARCHY_MUTATION_LOCK_ID = "hierarchy-integrity";
|
|
11
|
+
/** Acquire the shared hierarchy writer lock, or return a no-op release. */
|
|
12
|
+
export async function acquireHierarchyMutationLock(options) {
|
|
13
|
+
const release = options.required
|
|
14
|
+
? await acquireLock(options.pmRoot, HIERARCHY_MUTATION_LOCK_ID, options.ttlSeconds, options.author, false, false, options.waitMs)
|
|
15
|
+
: async () => { };
|
|
16
|
+
let released = false;
|
|
17
|
+
return async () => {
|
|
18
|
+
if (released)
|
|
19
|
+
return;
|
|
20
|
+
released = true;
|
|
21
|
+
await release();
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=hierarchy-mutation-lock.js.map
|
|
25
|
+
//# debugId=39a36d42-29b1-5f0f-a8b2-f3bfc0ef78c2
|
|
@@ -121,6 +121,8 @@ interface DependencyRemovalSelector {
|
|
|
121
121
|
id: string;
|
|
122
122
|
kind?: (typeof DEPENDENCY_KIND_VALUES)[number];
|
|
123
123
|
source_kind?: string;
|
|
124
|
+
author?: string;
|
|
125
|
+
created_at?: string;
|
|
124
126
|
}
|
|
125
127
|
/** Parse dependency additions into their canonical storage representation. */
|
|
126
128
|
export declare function parseDependencyAdditions(raw: string[] | undefined, prefix: string, nowIso: string, fallbackAuthor: string): ParsedDependencyUpdates;
|