@unbrained/pm-cli 2026.8.21 → 2026.8.22
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 +16 -0
- package/dist/cli/error-guidance.d.ts +9 -4
- package/dist/cli/error-guidance.js +16 -15
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +40 -7
- package/dist/cli-bundle/bundle-manifest.json +153 -153
- package/dist/cli-bundle/chunks/{chunk-BKYB45NQ.js → chunk-BWX4SK46.js} +48 -48
- package/dist/cli-bundle/chunks/chunk-EMWDM5FI.js +13 -0
- package/dist/cli-bundle/chunks/chunk-HYG6LRL4.js +200 -0
- package/dist/cli-bundle/chunks/{chunk-LARJJ3RK.js → chunk-MYYI3ZOA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BUNIEJNE.js → chunk-MZTZQTMS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-LOVTQ52Z.js → chunk-QI2CT3IX.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-SMWXHMVB.js +35 -0
- package/dist/cli-bundle/chunks/{chunk-N3DSV4CH.js → chunk-U6GQ4VMV.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-3AFAUHUE.js → chunk-VMMIL3SI.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-WG4STC36.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-JSLOFXGA.js → chunk-YBPJAOQQ.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-F57EWDEF.js → register-list-query-HZKBQNWW.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-7IY2D5KO.js → register-mutation-HTKEEGRD.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-FALL3YTU.js → register-operations-6EMRWJJY.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-HXU7IZZD.js → register-setup-QK4OTOXN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FJ22HNRP.js → chunk-2ARQGDDW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-CKKQSJNN.js → chunk-2AZT5WXZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-F4YEW5I2.js → chunk-2POVTNLY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3LKU6PTJ.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-5SHSBMX2.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-FH6DYED3.js → chunk-6S2MO3Q3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-UZE7XUZK.js → chunk-A2BC5PQL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-C4S4A4JJ.js +5 -0
- package/dist/cli-bundle/focused-chunks/{chunk-KDNG7TKQ.js → chunk-D6RBZEJJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-E2EWYPY6.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-4ERLO7QD.js → chunk-GMYPD4FX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-L5LDSRO2.js +155 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZOSEELYJ.js → chunk-MB37AYN6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-MCOR37QK.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2NIY5NKG.js → chunk-PH2OXXVZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-YKBKIEAJ.js → chunk-PMGJUFNQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-R6SR45XU.js +50 -0
- package/dist/cli-bundle/focused-chunks/chunk-WZE4LIPW.js +8 -0
- 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 +32 -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/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/item/id.js +20 -5
- package/dist/core/item/item-format.js +27 -2
- package/dist/core/shared/errors.d.ts +4 -0
- package/dist/core/shared/errors.js +2 -2
- 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 +324 -2
- package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
- 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.d.ts +1 -1
- package/dist/sdk/cli-contracts.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/generated/generated-error-code-catalog-part-1.js +38 -14
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
- 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 +1 -7
- package/dist/sdk/governance/validate.js +47 -99
- 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 +2 -2
- package/dist/sdk/index.js +3 -3
- package/dist/sdk/item-children.js +21 -8
- package/dist/sdk/lifecycle/create.js +125 -96
- 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 +171 -83
- 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-contracts.d.ts +5 -1
- package/dist/sdk/read-output-contracts.js +87 -22
- package/dist/sdk/relationship-context.js +3 -4
- package/dist/sdk/relationships.js +17 -10
- package/dist/sdk/runtime.d.ts +3 -2
- package/dist/sdk/runtime.js +3 -2
- package/dist/sdk/test/batch.js +13 -5
- package/dist/sdk/test/execution.js +10 -2
- package/dist/types.d.ts +11 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_UX_CONTRACTS.md +20 -4
- package/docs/COMMANDS.md +29 -14
- package/docs/DEPENDENCY_KIND_CONTRACT.md +31 -3
- package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +98 -0
- package/docs/EXTENSIONS.md +2 -1
- package/docs/README.md +1 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +9 -2
- package/docs/RELATIONSHIP_GRAPH.md +6 -3
- package/docs/TESTING.md +15 -0
- 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-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +593 -35
- package/dist/cli-bundle/chunks/chunk-2MA6ZQVZ.js +0 -197
- package/dist/cli-bundle/chunks/chunk-7VHZS727.js +0 -5
- package/dist/cli-bundle/chunks/chunk-OCLPLFAY.js +0 -35
- package/dist/cli-bundle/chunks/chunk-S4IRYKBU.js +0 -13
- package/dist/cli-bundle/focused-chunks/chunk-7WZRLCYF.js +0 -50
- 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
|
@@ -4,13 +4,16 @@
|
|
|
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]="4dff80ab-acfc-5f81-a546-3f19629d97be")}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";
|
|
@@ -1440,114 +1443,140 @@ async function writeCreatedItem(params) {
|
|
|
1440
1443
|
const { pmRoot, type, id, settings, typeRegistry, author, extensionFieldNames, afterDocument, beforeDocument, historyMessage, changedFields, nowValue, similarityCandidate, allowDuplicate, } = params;
|
|
1441
1444
|
const itemPath = getItemPath(pmRoot, type, id, settings.item_format, typeRegistry.type_to_folder);
|
|
1442
1445
|
const historyPath = getHistoryPath(pmRoot, id);
|
|
1443
|
-
const
|
|
1446
|
+
const relationshipRegistry = resolveWorkspaceRelationshipKindRegistry();
|
|
1447
|
+
const hierarchyMutationRequired = afterDocument.metadata.parent !== undefined ||
|
|
1448
|
+
(afterDocument.metadata.dependencies ?? []).some((dependency) => relationshipRegistry.resolve(dependency.kind)?.hierarchy);
|
|
1449
|
+
const hierarchyLockRelease = await acquireHierarchyMutationLock({
|
|
1450
|
+
pmRoot,
|
|
1451
|
+
author,
|
|
1452
|
+
ttlSeconds: settings.locks.ttl_seconds,
|
|
1453
|
+
waitMs: settings.locks.wait_ms,
|
|
1454
|
+
required: hierarchyMutationRequired,
|
|
1455
|
+
});
|
|
1456
|
+
let hierarchyLockHeld = hierarchyMutationRequired;
|
|
1444
1457
|
let hookWarnings = [];
|
|
1445
1458
|
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 = [];
|
|
1459
|
+
const lockRelease = await acquireLock(pmRoot, id, settings.locks.ttl_seconds, author, false, settings.governance.force_required_for_stale_lock, settings.locks.wait_ms);
|
|
1471
1460
|
try {
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1461
|
+
const graphBeforeCreate = afterDocument.metadata.parent !== undefined ||
|
|
1462
|
+
(afterDocument.metadata.dependencies !== undefined &&
|
|
1463
|
+
afterDocument.metadata.dependencies.length > 0)
|
|
1464
|
+
? await listAllItemMetadataLight(pmRoot, settings.item_format, typeRegistry.type_to_folder, undefined, settings.schema)
|
|
1465
|
+
: undefined;
|
|
1466
|
+
const existing = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
|
|
1467
|
+
if (existing) {
|
|
1468
|
+
throw new PmCliError(`Item "${id}" already exists`, EXIT_CODE.CONFLICT);
|
|
1469
|
+
}
|
|
1470
|
+
if (graphBeforeCreate) {
|
|
1471
|
+
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
1472
|
+
assertHierarchyMutationAllowed(graphBeforeCreate, [...graphBeforeCreate, afterDocument.metadata], id, (status) => isTerminalStatus(status, statusRegistry), relationshipRegistry);
|
|
1473
|
+
}
|
|
1474
|
+
await runActiveBeforeMutationHooks({
|
|
1475
|
+
pm_root: pmRoot,
|
|
1476
|
+
operation: "create",
|
|
1477
|
+
before: null,
|
|
1478
|
+
after: afterDocument,
|
|
1479
|
+
changed_fields: changedFields,
|
|
1480
|
+
sdk: createMutationGuardSdk({
|
|
1475
1481
|
pmRoot,
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1482
|
+
settings,
|
|
1483
|
+
typeToFolder: typeRegistry.type_to_folder,
|
|
1484
|
+
}),
|
|
1485
|
+
});
|
|
1486
|
+
const releaseDerivedIndexLock = await acquireItemMetadataDerivedIndexLock(pmRoot, author, {
|
|
1487
|
+
required: settings.governance.duplicate_detection_mode === "strict" &&
|
|
1488
|
+
allowDuplicate !== true,
|
|
1489
|
+
});
|
|
1490
|
+
let derivedIndexWarnings = [];
|
|
1491
|
+
try {
|
|
1492
|
+
if (settings.governance.duplicate_detection_mode === "strict" &&
|
|
1493
|
+
allowDuplicate !== true) {
|
|
1494
|
+
await evaluateSimilarityGovernance(similarityCandidate, {
|
|
1495
|
+
pmRoot,
|
|
1496
|
+
mode: "strict",
|
|
1497
|
+
threshold: settings.governance.duplicate_detection_threshold,
|
|
1498
|
+
limit: settings.governance.duplicate_detection_limit,
|
|
1499
|
+
allowDuplicate: false,
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
await writeFileAtomic(itemPath, serializeItemDocument(afterDocument, {
|
|
1503
|
+
format: settings.item_format,
|
|
1504
|
+
schema: settings.schema,
|
|
1505
|
+
extensionFieldNames,
|
|
1506
|
+
}));
|
|
1507
|
+
try {
|
|
1508
|
+
const entry = createHistoryEntry({
|
|
1509
|
+
nowIso: nowValue,
|
|
1510
|
+
author,
|
|
1511
|
+
op: "create",
|
|
1512
|
+
before: beforeDocument,
|
|
1513
|
+
after: afterDocument,
|
|
1514
|
+
message: historyMessage,
|
|
1515
|
+
});
|
|
1516
|
+
await appendHistoryEntry(historyPath, entry);
|
|
1517
|
+
}
|
|
1518
|
+
catch (error) {
|
|
1519
|
+
await removeFileIfExists(itemPath);
|
|
1520
|
+
throw error;
|
|
1521
|
+
}
|
|
1522
|
+
if (hierarchyLockHeld) {
|
|
1523
|
+
await hierarchyLockRelease();
|
|
1524
|
+
hierarchyLockHeld = false;
|
|
1525
|
+
}
|
|
1526
|
+
derivedIndexWarnings = await refreshItemMetadataDerivedIndex({
|
|
1527
|
+
pmRoot,
|
|
1528
|
+
preferredFormat: settings.item_format,
|
|
1529
|
+
typeToFolder: typeRegistry.type_to_folder,
|
|
1530
|
+
schema: settings.schema,
|
|
1531
|
+
itemPath,
|
|
1532
|
+
document: afterDocument,
|
|
1480
1533
|
});
|
|
1481
1534
|
}
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1535
|
+
finally {
|
|
1536
|
+
await releaseDerivedIndexLock();
|
|
1537
|
+
}
|
|
1538
|
+
hookWarnings = [
|
|
1539
|
+
...(graphBeforeCreate
|
|
1540
|
+
? collectNewOrderingCycleWarnings(graphBeforeCreate, [...graphBeforeCreate, afterDocument.metadata], id)
|
|
1541
|
+
: []),
|
|
1542
|
+
...derivedIndexWarnings,
|
|
1543
|
+
...(await runActiveOnWriteHooks({
|
|
1544
|
+
path: itemPath,
|
|
1545
|
+
scope: "project",
|
|
1491
1546
|
op: "create",
|
|
1547
|
+
item_id: afterDocument.metadata.id,
|
|
1548
|
+
item_type: afterDocument.metadata.type,
|
|
1492
1549
|
before: beforeDocument,
|
|
1493
1550
|
after: afterDocument,
|
|
1494
|
-
|
|
1495
|
-
})
|
|
1496
|
-
await
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1551
|
+
changed_fields: changedFields,
|
|
1552
|
+
})),
|
|
1553
|
+
...(await runActiveOnWriteHooks({
|
|
1554
|
+
path: historyPath,
|
|
1555
|
+
scope: "project",
|
|
1556
|
+
op: "create:history",
|
|
1557
|
+
item_id: afterDocument.metadata.id,
|
|
1558
|
+
item_type: afterDocument.metadata.type,
|
|
1559
|
+
before: beforeDocument,
|
|
1560
|
+
after: afterDocument,
|
|
1561
|
+
changed_fields: changedFields,
|
|
1562
|
+
})),
|
|
1563
|
+
];
|
|
1564
|
+
recordAfterCommandAffectedItem({
|
|
1565
|
+
id: afterDocument.metadata.id,
|
|
1566
|
+
op: "create",
|
|
1567
|
+
item_type: afterDocument.metadata.type,
|
|
1568
|
+
status: afterDocument.metadata.status,
|
|
1569
|
+
current: projectAfterCommandItemSnapshot(afterDocument.metadata, changedFields),
|
|
1570
|
+
changed_fields: changedFields,
|
|
1509
1571
|
});
|
|
1510
1572
|
}
|
|
1511
1573
|
finally {
|
|
1512
|
-
await
|
|
1574
|
+
await lockRelease();
|
|
1513
1575
|
}
|
|
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
1576
|
}
|
|
1549
1577
|
finally {
|
|
1550
|
-
|
|
1578
|
+
if (hierarchyLockHeld)
|
|
1579
|
+
await hierarchyLockRelease();
|
|
1551
1580
|
}
|
|
1552
1581
|
return hookWarnings;
|
|
1553
1582
|
}
|
|
@@ -1886,4 +1915,4 @@ export const _testOnlyCreateCommand = {
|
|
|
1886
1915
|
typeOptionExampleValue,
|
|
1887
1916
|
};
|
|
1888
1917
|
//# sourceMappingURL=create.js.map
|
|
1889
|
-
//# debugId=
|
|
1918
|
+
//# debugId=4dff80ab-acfc-5f81-a546-3f19629d97be
|
|
@@ -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;
|