@unbrained/pm-cli 2026.5.6 → 2026.5.11
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/.agents/pm/extensions/.managed-extensions.json +2 -2
- package/.agents/pm/extensions/beads/runtime.js +4 -4
- package/.agents/pm/extensions/beads/runtime.ts +5 -5
- package/.agents/pm/extensions/todos/runtime.js +7 -7
- package/.agents/pm/extensions/todos/runtime.ts +10 -10
- package/.agents/skills/HARNESS_COMPATIBILITY.md +45 -0
- package/.agents/skills/README.md +21 -0
- package/.agents/skills/pm-developer/SKILL.md +73 -0
- package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +48 -0
- package/.agents/skills/pm-developer/references/PROMPTS.md +17 -0
- package/.agents/skills/pm-extensions/SKILL.md +57 -0
- package/.agents/skills/pm-extensions/references/LIFECYCLE.md +40 -0
- package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +25 -0
- package/.agents/skills/pm-sdk/SKILL.md +50 -0
- package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +31 -0
- package/.agents/skills/pm-sdk/references/PROMPTS.md +13 -0
- package/.agents/skills/pm-user/SKILL.md +59 -0
- package/.agents/skills/pm-user/references/PROMPTS.md +17 -0
- package/.agents/skills/pm-user/references/WORKFLOWS.md +35 -0
- package/.claude-plugin/marketplace.json +38 -0
- package/.pi/README.md +35 -0
- package/.pi/agents/pm-triage-agent.md +19 -0
- package/.pi/agents/pm-verification-agent.md +21 -0
- package/.pi/chains/pm-native-delivery.chain.md +11 -0
- package/.pi/extensions/pm-cli/index.js +387 -0
- package/.pi/prompts/pm-workflow.md +5 -0
- package/.pi/skills/pm-native/SKILL.md +44 -0
- package/.pi/skills/pm-release/SKILL.md +35 -0
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +13 -0
- package/PRD.md +16 -16
- package/README.md +30 -4
- package/dist/cli/argv-utils.d.ts +5 -0
- package/dist/cli/argv-utils.js +34 -0
- package/dist/cli/argv-utils.js.map +1 -0
- package/dist/cli/bootstrap-args.d.ts +15 -0
- package/dist/cli/bootstrap-args.js +211 -0
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commander-usage.js +109 -3
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/claim.js +6 -6
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/close.js +9 -9
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/comments.d.ts +2 -0
- package/dist/cli/commands/comments.js +57 -8
- package/dist/cli/commands/comments.js.map +1 -1
- package/dist/cli/commands/completion.js +40 -7
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/config.js +6 -3
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/contracts.d.ts +19 -0
- package/dist/cli/commands/contracts.js +36 -1
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.d.ts +2 -2
- package/dist/cli/commands/create.js +116 -55
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/docs.js +13 -6
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/extension.d.ts +3 -1
- package/dist/cli/commands/extension.js +174 -2
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/files.js +19 -12
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/get.js +5 -5
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/guide.d.ts +55 -0
- package/dist/cli/commands/guide.js +260 -0
- package/dist/cli/commands/guide.js.map +1 -0
- package/dist/cli/commands/health.js +1 -1
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history.js +30 -10
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.js +1 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.js +21 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/learnings.js +3 -3
- package/dist/cli/commands/learnings.js.map +1 -1
- package/dist/cli/commands/metadata-normalizers.d.ts +4 -0
- package/dist/cli/commands/metadata-normalizers.js +37 -0
- package/dist/cli/commands/metadata-normalizers.js.map +1 -0
- package/dist/cli/commands/notes.js +3 -3
- package/dist/cli/commands/notes.js.map +1 -1
- package/dist/cli/commands/reindex.js +180 -156
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/restore.d.ts +2 -2
- package/dist/cli/commands/restore.js +44 -24
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/search.d.ts +2 -0
- package/dist/cli/commands/search.js +45 -26
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/test-all.d.ts +2 -0
- package/dist/cli/commands/test-all.js +2 -0
- package/dist/cli/commands/test-all.js.map +1 -1
- package/dist/cli/commands/test.d.ts +1 -0
- package/dist/cli/commands/test.js +13 -5
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update.js +188 -157
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/validate.js +1 -1
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +9 -1
- package/dist/cli/error-guidance.js +147 -6
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/guide-topics.d.ts +25 -0
- package/dist/cli/guide-topics.js +283 -0
- package/dist/cli/guide-topics.js.map +1 -0
- package/dist/cli/help-content.js +25 -1
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/help-json-payload.js +11 -1
- package/dist/cli/help-json-payload.js.map +1 -1
- package/dist/cli/main.js +69 -6
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +38 -1
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +17 -4
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-setup.js +15 -1
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/telemetry-flush.d.ts +2 -0
- package/dist/cli/telemetry-flush.js +4 -0
- package/dist/cli/telemetry-flush.js.map +1 -0
- package/dist/cli.js +1 -2
- package/dist/cli.js.map +1 -1
- package/dist/core/extensions/extension-types.d.ts +72 -0
- package/dist/core/extensions/extension-types.js +24 -0
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -0
- package/dist/core/extensions/loader.js +766 -7
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/history/history.js +32 -11
- package/dist/core/history/history.js.map +1 -1
- package/dist/core/item/item-format.d.ts +2 -2
- package/dist/core/item/item-format.js +16 -16
- package/dist/core/item/item-format.js.map +1 -1
- package/dist/core/lock/lock.js +2 -0
- package/dist/core/lock/lock.js.map +1 -1
- package/dist/core/schema/runtime-field-filters.js +1 -1
- package/dist/core/schema/runtime-field-filters.js.map +1 -1
- package/dist/core/schema/runtime-field-values.js +2 -2
- package/dist/core/schema/runtime-field-values.js.map +1 -1
- package/dist/core/schema/runtime-schema.d.ts +1 -1
- package/dist/core/schema/runtime-schema.js +3 -3
- package/dist/core/schema/runtime-schema.js.map +1 -1
- package/dist/core/search/cache.js +7 -21
- package/dist/core/search/cache.js.map +1 -1
- package/dist/core/search/corpus.d.ts +13 -0
- package/dist/core/search/corpus.js +74 -0
- package/dist/core/search/corpus.js.map +1 -0
- package/dist/core/search/embedding-batches.js +90 -30
- package/dist/core/search/embedding-batches.js.map +1 -1
- package/dist/core/sentry/instrument.d.ts +18 -1
- package/dist/core/sentry/instrument.js +128 -12
- package/dist/core/sentry/instrument.js.map +1 -1
- package/dist/core/shared/constants.d.ts +1 -1
- package/dist/core/shared/constants.js +21 -1
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/errors.d.ts +8 -0
- package/dist/core/shared/errors.js.map +1 -1
- package/dist/core/shared/levenshtein.d.ts +1 -0
- package/dist/core/shared/levenshtein.js +37 -0
- package/dist/core/shared/levenshtein.js.map +1 -0
- package/dist/core/store/front-matter-cache.d.ts +1 -1
- package/dist/core/store/front-matter-cache.js +13 -13
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/core/store/item-format-migration.js +5 -2
- package/dist/core/store/item-format-migration.js.map +1 -1
- package/dist/core/store/item-store.js +16 -15
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/paths.js +35 -2
- package/dist/core/store/paths.js.map +1 -1
- package/dist/core/store/settings.js +216 -2
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/telemetry/runtime.d.ts +1 -0
- package/dist/core/telemetry/runtime.js +102 -3
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/core/test/item-test-run-tracking.js +2 -2
- package/dist/core/test/item-test-run-tracking.js.map +1 -1
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +407 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/pi/native.d.ts +5 -0
- package/dist/pi/native.js +236 -0
- package/dist/pi/native.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +24 -2
- package/dist/sdk/cli-contracts.js +317 -2
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/index.d.ts +12 -1
- package/dist/sdk/index.js +8 -1
- package/dist/sdk/index.js.map +1 -1
- package/dist/types.d.ts +51 -2
- package/dist/types.js.map +1 -1
- package/docs/AGENT_GUIDE.md +15 -0
- package/docs/ARCHITECTURE.md +2 -2
- package/docs/CLAUDE_CODE_PLUGIN.md +225 -0
- package/docs/CODEX_PLUGIN.md +33 -0
- package/docs/COMMANDS.md +6 -2
- package/docs/CONFIGURATION.md +2 -8
- package/docs/EXTENSIONS.md +688 -0
- package/docs/MIGRATION_CLI_SIMPLIFICATION.md +64 -0
- package/docs/PI_PACKAGE.md +141 -0
- package/docs/QUICKSTART.md +1 -0
- package/docs/README.md +30 -1
- package/docs/RELEASING.md +4 -2
- package/docs/SDK.md +444 -2
- package/docs/examples/ci/github-actions-pm-extension-gate.yml +53 -0
- package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +41 -0
- package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +45 -0
- package/docs/examples/policy-restricted-extension/README.md +74 -0
- package/docs/examples/policy-restricted-extension/index.js +21 -0
- package/docs/examples/policy-restricted-extension/manifest.json +21 -0
- package/docs/examples/policy-restricted-extension/package.json +8 -0
- package/docs/examples/sdk-app-embedding/README.md +39 -0
- package/docs/examples/sdk-app-embedding/package.json +9 -0
- package/docs/examples/sdk-app-embedding/run-embedded-pm.mjs +61 -0
- package/docs/examples/sdk-contract-consumer/README.md +57 -0
- package/docs/examples/sdk-contract-consumer/inspect-contracts.mjs +47 -0
- package/docs/examples/sdk-contract-consumer/package.json +10 -0
- package/docs/examples/starter-extension/README.md +57 -42
- package/docs/examples/starter-extension/manifest.json +15 -0
- package/marketplace.json +34 -0
- package/package.json +38 -4
- package/plugins/pm-cli-claude/.claude-plugin/plugin.json +23 -0
- package/plugins/pm-cli-claude/.mcp.json +12 -0
- package/plugins/pm-cli-claude/README.md +225 -0
- package/plugins/pm-cli-claude/agents/pm-coordinator.md +48 -0
- package/plugins/pm-cli-claude/agents/pm-delivery-chain.md +88 -0
- package/plugins/pm-cli-claude/agents/pm-triage-agent.md +83 -0
- package/plugins/pm-cli-claude/agents/pm-verification-agent.md +88 -0
- package/plugins/pm-cli-claude/commands/pm-audit.md +39 -0
- package/plugins/pm-cli-claude/commands/pm-calendar.md +41 -0
- package/plugins/pm-cli-claude/commands/pm-close-task.md +20 -0
- package/plugins/pm-cli-claude/commands/pm-developer.md +38 -0
- package/plugins/pm-cli-claude/commands/pm-init.md +44 -0
- package/plugins/pm-cli-claude/commands/pm-list.md +39 -0
- package/plugins/pm-cli-claude/commands/pm-new.md +36 -0
- package/plugins/pm-cli-claude/commands/pm-planner.md +51 -0
- package/plugins/pm-cli-claude/commands/pm-release.md +41 -0
- package/plugins/pm-cli-claude/commands/pm-search.md +21 -0
- package/plugins/pm-cli-claude/commands/pm-start-task.md +27 -0
- package/plugins/pm-cli-claude/commands/pm-status.md +15 -0
- package/plugins/pm-cli-claude/commands/pm-triage.md +35 -0
- package/plugins/pm-cli-claude/commands/pm-workflow.md +49 -0
- package/plugins/pm-cli-claude/hooks/hooks.json +17 -0
- package/plugins/pm-cli-claude/hooks/session-start.mjs +120 -0
- package/plugins/pm-cli-claude/scripts/pm-mcp-server.mjs +60 -0
- package/plugins/pm-cli-claude/skills/pm-audit/SKILL.md +88 -0
- package/plugins/pm-cli-claude/skills/pm-developer/SKILL.md +116 -0
- package/plugins/pm-cli-claude/skills/pm-planner/SKILL.md +118 -0
- package/plugins/pm-cli-claude/skills/pm-release/SKILL.md +83 -0
- package/plugins/pm-cli-claude/skills/pm-workflow/SKILL.md +148 -0
- package/plugins/pm-cli-codex/.codex-plugin/plugin.json +45 -0
- package/plugins/pm-cli-codex/.mcp.json +14 -0
- package/plugins/pm-cli-codex/README.md +30 -0
- package/plugins/pm-cli-codex/assets/pm-cli-small.svg +4 -0
- package/plugins/pm-cli-codex/commands/pm-audit.md +8 -0
- package/plugins/pm-cli-codex/commands/pm-close-task.md +9 -0
- package/plugins/pm-cli-codex/commands/pm-start-task.md +9 -0
- package/plugins/pm-cli-codex/scripts/pm-mcp-server.mjs +54 -0
- package/plugins/pm-cli-codex/skills/pm-auditor/SKILL.md +21 -0
- package/plugins/pm-cli-codex/skills/pm-auditor/agents/openai.yaml +6 -0
- package/plugins/pm-cli-codex/skills/pm-native/SKILL.md +57 -0
- package/plugins/pm-cli-codex/skills/pm-native/agents/openai.yaml +6 -0
- package/plugins/pm-cli-codex/skills/pm-release/SKILL.md +19 -0
- package/plugins/pm-cli-codex/skills/pm-release/agents/openai.yaml +6 -0
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import jsonPatch from "fast-json-patch";
|
|
2
|
-
import {
|
|
2
|
+
import { FRONT_MATTER_KEY_ORDER } from "../shared/constants.js";
|
|
3
3
|
import { runActiveServiceOverride } from "../extensions/index.js";
|
|
4
4
|
import { appendLineAtomic } from "../fs/fs-utils.js";
|
|
5
5
|
import { canonicalDocument } from "../item/item-format.js";
|
|
6
6
|
import { orderObject, sha256Hex, stableStringify } from "../shared/serialization.js";
|
|
7
|
+
const EMPTY_LEGACY_HASH_DOCUMENT = {
|
|
8
|
+
front_matter: {},
|
|
9
|
+
body: "",
|
|
10
|
+
};
|
|
7
11
|
function decodeJsonPointer(path) {
|
|
8
12
|
if (!path || path === "/") {
|
|
9
13
|
return [];
|
|
@@ -65,38 +69,55 @@ function normalizeHistoryPatchOps(beforeDocument, patch) {
|
|
|
65
69
|
return normalized;
|
|
66
70
|
}
|
|
67
71
|
function canonicalHashDocument(document) {
|
|
68
|
-
const
|
|
69
|
-
if (!
|
|
72
|
+
const hasMetadata = document.metadata && Object.keys(document.metadata).length > 0;
|
|
73
|
+
if (!hasMetadata) {
|
|
70
74
|
return {
|
|
71
75
|
front_matter: {},
|
|
72
76
|
body: document.body ?? "",
|
|
73
77
|
};
|
|
74
78
|
}
|
|
75
79
|
const canonical = canonicalDocument(document);
|
|
76
|
-
const orderedFrontMatter = orderObject(canonical.
|
|
80
|
+
const orderedFrontMatter = orderObject(canonical.metadata, FRONT_MATTER_KEY_ORDER);
|
|
77
81
|
return {
|
|
78
82
|
front_matter: orderedFrontMatter,
|
|
79
83
|
body: canonical.body,
|
|
80
84
|
};
|
|
81
85
|
}
|
|
86
|
+
function canonicalPatchDocument(document) {
|
|
87
|
+
const hasMetadata = document.metadata && Object.keys(document.metadata).length > 0;
|
|
88
|
+
if (!hasMetadata) {
|
|
89
|
+
return {
|
|
90
|
+
metadata: {},
|
|
91
|
+
body: document.body ?? "",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const canonical = canonicalDocument(document);
|
|
95
|
+
const orderedMetadata = orderObject(canonical.metadata, FRONT_MATTER_KEY_ORDER);
|
|
96
|
+
return {
|
|
97
|
+
metadata: orderedMetadata,
|
|
98
|
+
body: canonical.body,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
82
101
|
export function hashDocument(document) {
|
|
83
102
|
return sha256Hex(stableStringify(canonicalHashDocument(document)));
|
|
84
103
|
}
|
|
85
104
|
export function hashEmptyDocument() {
|
|
86
|
-
return sha256Hex(stableStringify(
|
|
105
|
+
return sha256Hex(stableStringify(EMPTY_LEGACY_HASH_DOCUMENT));
|
|
87
106
|
}
|
|
88
107
|
export function createHistoryEntry(params) {
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
const
|
|
108
|
+
const beforeHashCanonical = canonicalHashDocument(params.before);
|
|
109
|
+
const afterHashCanonical = canonicalHashDocument(params.after);
|
|
110
|
+
const beforePatchCanonical = canonicalPatchDocument(params.before);
|
|
111
|
+
const afterPatchCanonical = canonicalPatchDocument(params.after);
|
|
112
|
+
const rawPatch = jsonPatch.compare(beforePatchCanonical, afterPatchCanonical);
|
|
113
|
+
const patch = normalizeHistoryPatchOps(beforePatchCanonical, rawPatch);
|
|
93
114
|
return {
|
|
94
115
|
ts: params.nowIso,
|
|
95
116
|
author: params.author,
|
|
96
117
|
op: params.op,
|
|
97
118
|
patch,
|
|
98
|
-
before_hash: sha256Hex(stableStringify(
|
|
99
|
-
after_hash: sha256Hex(stableStringify(
|
|
119
|
+
before_hash: sha256Hex(stableStringify(beforeHashCanonical)),
|
|
120
|
+
after_hash: sha256Hex(stableStringify(afterHashCanonical)),
|
|
100
121
|
message: params.message === undefined ? undefined : params.message,
|
|
101
122
|
};
|
|
102
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.js","sourceRoot":"/","sources":["core/history/history.ts"],"names":[],"mappings":"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","sourcesContent":["import jsonPatch from \"fast-json-patch\";\nimport { EMPTY_CANONICAL_DOCUMENT, FRONT_MATTER_KEY_ORDER } from \"../shared/constants.js\";\nimport { runActiveServiceOverride } from \"../extensions/index.js\";\nimport { appendLineAtomic } from \"../fs/fs-utils.js\";\nimport { canonicalDocument } from \"../item/item-format.js\";\nimport { orderObject, sha256Hex, stableStringify } from \"../shared/serialization.js\";\nimport type { HistoryEntry, HistoryPatchOp, ItemDocument } from \"../../types/index.js\";\n\nfunction decodeJsonPointer(path: string): string[] {\n if (!path || path === \"/\") {\n return [];\n }\n if (!path.startsWith(\"/\")) {\n return [];\n }\n return path\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n}\n\nfunction isDefinedPointerPath(document: unknown, path: string): boolean {\n const segments = decodeJsonPointer(path);\n if (segments.length === 0) {\n return true;\n }\n let cursor: unknown = document;\n for (const segment of segments) {\n if (Array.isArray(cursor)) {\n if (segment === \"-\" || !/^(0|[1-9]\\d*)$/.test(segment)) {\n return false;\n }\n const index = Number(segment);\n if (!Number.isInteger(index) || index < 0 || index >= cursor.length) {\n return false;\n }\n const next = cursor[index];\n if (next === undefined) {\n return false;\n }\n cursor = next;\n continue;\n }\n if (typeof cursor !== \"object\" || cursor === null) {\n return false;\n }\n if (!Object.prototype.hasOwnProperty.call(cursor, segment)) {\n return false;\n }\n const next = (cursor as Record<string, unknown>)[segment];\n if (next === undefined) {\n return false;\n }\n cursor = next;\n }\n return true;\n}\n\nfunction normalizeHistoryPatchOps(\n beforeDocument: { front_matter: Record<string, unknown>; body: string },\n patch: HistoryPatchOp[],\n): HistoryPatchOp[] {\n const normalized: HistoryPatchOp[] = [];\n let replayCursor: unknown = structuredClone(beforeDocument);\n for (const operation of patch) {\n const normalizedOperation =\n operation.op === \"replace\" && !isDefinedPointerPath(replayCursor, operation.path)\n ? ({ ...operation, op: \"add\" } as HistoryPatchOp)\n : operation;\n normalized.push(normalizedOperation);\n replayCursor = jsonPatch.applyPatch(\n replayCursor,\n [normalizedOperation as jsonPatch.Operation],\n true,\n true,\n ).newDocument as unknown;\n }\n return normalized;\n}\n\nfunction canonicalHashDocument(document: ItemDocument): { front_matter: Record<string, unknown>; body: string } {\n const hasFrontMatter = document.front_matter && Object.keys(document.front_matter).length > 0;\n if (!hasFrontMatter) {\n return {\n front_matter: {},\n body: document.body ?? \"\",\n };\n }\n const canonical = canonicalDocument(document);\n const orderedFrontMatter = orderObject(\n canonical.front_matter as unknown as Record<string, unknown>,\n FRONT_MATTER_KEY_ORDER,\n );\n return {\n front_matter: orderedFrontMatter,\n body: canonical.body,\n };\n}\n\nexport function hashDocument(document: ItemDocument): string {\n return sha256Hex(stableStringify(canonicalHashDocument(document)));\n}\n\nexport function hashEmptyDocument(): string {\n return sha256Hex(stableStringify(EMPTY_CANONICAL_DOCUMENT));\n}\n\nexport function createHistoryEntry(params: {\n nowIso: string;\n author: string;\n op: string;\n before: ItemDocument;\n after: ItemDocument;\n message?: string;\n}): HistoryEntry {\n const beforeCanonical = canonicalHashDocument(params.before);\n const afterCanonical = canonicalHashDocument(params.after);\n const rawPatch = jsonPatch.compare(beforeCanonical, afterCanonical) as HistoryPatchOp[];\n const patch = normalizeHistoryPatchOps(beforeCanonical, rawPatch);\n\n return {\n ts: params.nowIso,\n author: params.author,\n op: params.op,\n patch,\n before_hash: sha256Hex(stableStringify(beforeCanonical)),\n after_hash: sha256Hex(stableStringify(afterCanonical)),\n message: params.message === undefined ? undefined : params.message,\n };\n}\n\nexport async function appendHistoryEntry(historyPath: string, entry: HistoryEntry): Promise<void> {\n const override = await runActiveServiceOverride(\"history_append\", {\n history_path: historyPath,\n entry,\n });\n if (override.handled) {\n if (override.result === false) {\n return;\n }\n if (typeof override.result === \"string\") {\n await appendLineAtomic(historyPath, override.result);\n return;\n }\n if (typeof override.result === \"object\" && override.result !== null) {\n const record = override.result as {\n history_path?: unknown;\n entry?: unknown;\n line?: unknown;\n skip?: unknown;\n };\n if (record.skip === true) {\n return;\n }\n const nextHistoryPath = typeof record.history_path === \"string\" ? record.history_path : historyPath;\n if (typeof record.line === \"string\") {\n await appendLineAtomic(nextHistoryPath, record.line);\n return;\n }\n const nextEntry = (record.entry ?? entry) as HistoryEntry;\n await appendLineAtomic(nextHistoryPath, JSON.stringify(nextEntry));\n return;\n }\n }\n await appendLineAtomic(historyPath, JSON.stringify(entry));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"/","sources":["core/history/history.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGrF,MAAM,0BAA0B,GAAG;IACjC,YAAY,EAAE,EAAE;IAChB,IAAI,EAAE,EAAE;CACT,CAAC;AAEF,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,IAAI;SACR,KAAK,CAAC,CAAC,CAAC;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAiB,EAAE,IAAY;IAC3D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,GAAY,QAAQ,CAAC;IAC/B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,IAAI,OAAO,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACpE,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,GAAG,IAAI,CAAC;YACd,SAAS;QACX,CAAC;QACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,IAAI,GAAI,MAAkC,CAAC,OAAO,CAAC,CAAC;QAC1D,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,wBAAwB,CAC/B,cAAmE,EACnE,KAAuB;IAEvB,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,IAAI,YAAY,GAAY,eAAe,CAAC,cAAc,CAAC,CAAC;IAC5D,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;QAC9B,MAAM,mBAAmB,GACvB,SAAS,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC;YAC/E,CAAC,CAAE,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,KAAK,EAAqB;YACjD,CAAC,CAAC,SAAS,CAAC;QAChB,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACrC,YAAY,GAAG,SAAS,CAAC,UAAU,CACjC,YAAY,EACZ,CAAC,mBAA0C,CAAC,EAC5C,IAAI,EACJ,IAAI,CACL,CAAC,WAAsB,CAAC;IAC3B,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAsB;IACnD,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACnF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,YAAY,EAAE,EAAE;YAChB,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;SAC1B,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,kBAAkB,GAAG,WAAW,CAAC,SAAS,CAAC,QAA8C,EAAE,sBAAsB,CAAC,CAAC;IACzH,OAAO;QACL,YAAY,EAAE,kBAAkB;QAChC,IAAI,EAAE,SAAS,CAAC,IAAI;KACrB,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,QAAsB;IACpD,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACnF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;SAC1B,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,WAAW,CAAC,SAAS,CAAC,QAA8C,EAAE,sBAAsB,CAAC,CAAC;IACtH,OAAO;QACL,QAAQ,EAAE,eAAe;QACzB,IAAI,EAAE,SAAS,CAAC,IAAI;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAsB;IACjD,OAAO,SAAS,CAAC,eAAe,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,SAAS,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAOlC;IACC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/D,MAAM,oBAAoB,GAAG,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE,mBAAmB,CAAqB,CAAC;IAClG,MAAM,KAAK,GAAG,wBAAwB,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;IAEvE,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,MAAM;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,KAAK;QACL,WAAW,EAAE,SAAS,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;QAC5D,UAAU,EAAE,SAAS,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;QAC1D,OAAO,EAAE,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO;KACnE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,WAAmB,EAAE,KAAmB;IAC/E,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,gBAAgB,EAAE;QAChE,YAAY,EAAE,WAAW;QACzB,KAAK;KACN,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,IAAI,QAAQ,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QACD,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,gBAAgB,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACpE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAKvB,CAAC;YACF,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YACD,MAAM,eAAe,GAAG,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;YACpG,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpC,MAAM,gBAAgB,CAAC,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;gBACrD,OAAO;YACT,CAAC;YACD,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAiB,CAAC;YAC1D,MAAM,gBAAgB,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;IACH,CAAC;IACD,MAAM,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["import jsonPatch from \"fast-json-patch\";\nimport { FRONT_MATTER_KEY_ORDER } from \"../shared/constants.js\";\nimport { runActiveServiceOverride } from \"../extensions/index.js\";\nimport { appendLineAtomic } from \"../fs/fs-utils.js\";\nimport { canonicalDocument } from \"../item/item-format.js\";\nimport { orderObject, sha256Hex, stableStringify } from \"../shared/serialization.js\";\nimport type { HistoryEntry, HistoryPatchOp, ItemDocument } from \"../../types/index.js\";\n\nconst EMPTY_LEGACY_HASH_DOCUMENT = {\n front_matter: {},\n body: \"\",\n};\n\nfunction decodeJsonPointer(path: string): string[] {\n if (!path || path === \"/\") {\n return [];\n }\n if (!path.startsWith(\"/\")) {\n return [];\n }\n return path\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n}\n\nfunction isDefinedPointerPath(document: unknown, path: string): boolean {\n const segments = decodeJsonPointer(path);\n if (segments.length === 0) {\n return true;\n }\n let cursor: unknown = document;\n for (const segment of segments) {\n if (Array.isArray(cursor)) {\n if (segment === \"-\" || !/^(0|[1-9]\\d*)$/.test(segment)) {\n return false;\n }\n const index = Number(segment);\n if (!Number.isInteger(index) || index < 0 || index >= cursor.length) {\n return false;\n }\n const next = cursor[index];\n if (next === undefined) {\n return false;\n }\n cursor = next;\n continue;\n }\n if (typeof cursor !== \"object\" || cursor === null) {\n return false;\n }\n if (!Object.prototype.hasOwnProperty.call(cursor, segment)) {\n return false;\n }\n const next = (cursor as Record<string, unknown>)[segment];\n if (next === undefined) {\n return false;\n }\n cursor = next;\n }\n return true;\n}\n\nfunction normalizeHistoryPatchOps(\n beforeDocument: { metadata: Record<string, unknown>; body: string },\n patch: HistoryPatchOp[],\n): HistoryPatchOp[] {\n const normalized: HistoryPatchOp[] = [];\n let replayCursor: unknown = structuredClone(beforeDocument);\n for (const operation of patch) {\n const normalizedOperation =\n operation.op === \"replace\" && !isDefinedPointerPath(replayCursor, operation.path)\n ? ({ ...operation, op: \"add\" } as HistoryPatchOp)\n : operation;\n normalized.push(normalizedOperation);\n replayCursor = jsonPatch.applyPatch(\n replayCursor,\n [normalizedOperation as jsonPatch.Operation],\n true,\n true,\n ).newDocument as unknown;\n }\n return normalized;\n}\n\nfunction canonicalHashDocument(document: ItemDocument): { front_matter: Record<string, unknown>; body: string } {\n const hasMetadata = document.metadata && Object.keys(document.metadata).length > 0;\n if (!hasMetadata) {\n return {\n front_matter: {},\n body: document.body ?? \"\",\n };\n }\n const canonical = canonicalDocument(document);\n const orderedFrontMatter = orderObject(canonical.metadata as unknown as Record<string, unknown>, FRONT_MATTER_KEY_ORDER);\n return {\n front_matter: orderedFrontMatter,\n body: canonical.body,\n };\n}\n\nfunction canonicalPatchDocument(document: ItemDocument): { metadata: Record<string, unknown>; body: string } {\n const hasMetadata = document.metadata && Object.keys(document.metadata).length > 0;\n if (!hasMetadata) {\n return {\n metadata: {},\n body: document.body ?? \"\",\n };\n }\n const canonical = canonicalDocument(document);\n const orderedMetadata = orderObject(canonical.metadata as unknown as Record<string, unknown>, FRONT_MATTER_KEY_ORDER);\n return {\n metadata: orderedMetadata,\n body: canonical.body,\n };\n}\n\nexport function hashDocument(document: ItemDocument): string {\n return sha256Hex(stableStringify(canonicalHashDocument(document)));\n}\n\nexport function hashEmptyDocument(): string {\n return sha256Hex(stableStringify(EMPTY_LEGACY_HASH_DOCUMENT));\n}\n\nexport function createHistoryEntry(params: {\n nowIso: string;\n author: string;\n op: string;\n before: ItemDocument;\n after: ItemDocument;\n message?: string;\n}): HistoryEntry {\n const beforeHashCanonical = canonicalHashDocument(params.before);\n const afterHashCanonical = canonicalHashDocument(params.after);\n const beforePatchCanonical = canonicalPatchDocument(params.before);\n const afterPatchCanonical = canonicalPatchDocument(params.after);\n const rawPatch = jsonPatch.compare(beforePatchCanonical, afterPatchCanonical) as HistoryPatchOp[];\n const patch = normalizeHistoryPatchOps(beforePatchCanonical, rawPatch);\n\n return {\n ts: params.nowIso,\n author: params.author,\n op: params.op,\n patch,\n before_hash: sha256Hex(stableStringify(beforeHashCanonical)),\n after_hash: sha256Hex(stableStringify(afterHashCanonical)),\n message: params.message === undefined ? undefined : params.message,\n };\n}\n\nexport async function appendHistoryEntry(historyPath: string, entry: HistoryEntry): Promise<void> {\n const override = await runActiveServiceOverride(\"history_append\", {\n history_path: historyPath,\n entry,\n });\n if (override.handled) {\n if (override.result === false) {\n return;\n }\n if (typeof override.result === \"string\") {\n await appendLineAtomic(historyPath, override.result);\n return;\n }\n if (typeof override.result === \"object\" && override.result !== null) {\n const record = override.result as {\n history_path?: unknown;\n entry?: unknown;\n line?: unknown;\n skip?: unknown;\n };\n if (record.skip === true) {\n return;\n }\n const nextHistoryPath = typeof record.history_path === \"string\" ? record.history_path : historyPath;\n if (typeof record.line === \"string\") {\n await appendLineAtomic(nextHistoryPath, record.line);\n return;\n }\n const nextEntry = (record.entry ?? entry) as HistoryEntry;\n await appendLineAtomic(nextHistoryPath, JSON.stringify(nextEntry));\n return;\n }\n }\n await appendLineAtomic(historyPath, JSON.stringify(entry));\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { ItemDocument,
|
|
1
|
+
import type { ItemDocument, ItemMetadata, RuntimeSchemaSettings } from "../../types/index.js";
|
|
2
2
|
import type { ItemFormat } from "../../types/index.js";
|
|
3
3
|
export interface ItemDocumentFormatOptions {
|
|
4
4
|
format?: ItemFormat;
|
|
5
5
|
schema?: RuntimeSchemaSettings;
|
|
6
6
|
onWarning?: (warning: string) => void;
|
|
7
7
|
}
|
|
8
|
-
export declare function normalizeFrontMatter(frontMatter:
|
|
8
|
+
export declare function normalizeFrontMatter(frontMatter: ItemMetadata, options?: Pick<ItemDocumentFormatOptions, "schema" | "onWarning">): ItemMetadata;
|
|
9
9
|
export declare function splitFrontMatter(content: string): {
|
|
10
10
|
frontMatter: string;
|
|
11
11
|
body: string;
|
|
@@ -219,25 +219,25 @@ function assertValidFrontMatter(frontMatter, runtimeContext) {
|
|
|
219
219
|
}
|
|
220
220
|
if (runtimeContext?.fieldRegistry) {
|
|
221
221
|
for (const definition of runtimeContext.fieldRegistry.definitions) {
|
|
222
|
-
const fieldValue = record[definition.
|
|
222
|
+
const fieldValue = record[definition.metadata_key];
|
|
223
223
|
if (fieldValue === undefined) {
|
|
224
224
|
if (runtimeFieldRequiredForType(definition, itemType)) {
|
|
225
|
-
validationError(`missing required schema field: ${definition.
|
|
225
|
+
validationError(`missing required schema field: ${definition.metadata_key}`);
|
|
226
226
|
}
|
|
227
227
|
continue;
|
|
228
228
|
}
|
|
229
229
|
try {
|
|
230
|
-
record[definition.
|
|
230
|
+
record[definition.metadata_key] = coerceRuntimeFieldValue(definition, fieldValue, `metadata field "${definition.metadata_key}"`);
|
|
231
231
|
}
|
|
232
232
|
catch (error) {
|
|
233
|
-
validationError(error instanceof Error ? error.message.replace(/^Invalid\s+/u, "") : `invalid ${definition.
|
|
233
|
+
validationError(error instanceof Error ? error.message.replace(/^Invalid\s+/u, "") : `invalid ${definition.metadata_key} value`);
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
if (runtimeContext && runtimeContext.unknownFieldPolicy !== "allow") {
|
|
238
238
|
const knownKeys = new Set(STATIC_FRONT_MATTER_FIELD_SET);
|
|
239
239
|
for (const definition of runtimeContext.fieldRegistry?.definitions ?? []) {
|
|
240
|
-
knownKeys.add(definition.
|
|
240
|
+
knownKeys.add(definition.metadata_key);
|
|
241
241
|
}
|
|
242
242
|
const unknownKeys = Object.keys(record).filter((key) => !knownKeys.has(key)).sort((left, right) => left.localeCompare(right));
|
|
243
243
|
if (unknownKeys.length > 0) {
|
|
@@ -693,17 +693,17 @@ export function normalizeFrontMatter(frontMatter, options = {}) {
|
|
|
693
693
|
}
|
|
694
694
|
if (runtimeContext?.fieldRegistry) {
|
|
695
695
|
for (const definition of runtimeContext.fieldRegistry.definitions) {
|
|
696
|
-
const currentValue = normalized[definition.
|
|
696
|
+
const currentValue = normalized[definition.metadata_key];
|
|
697
697
|
if (currentValue === undefined) {
|
|
698
698
|
continue;
|
|
699
699
|
}
|
|
700
|
-
normalized[definition.
|
|
700
|
+
normalized[definition.metadata_key] = coerceRuntimeFieldValue(definition, currentValue, `metadata field "${definition.metadata_key}"`);
|
|
701
701
|
}
|
|
702
702
|
}
|
|
703
703
|
if (runtimeContext && runtimeContext.unknownFieldPolicy !== "allow") {
|
|
704
704
|
const knownKeys = new Set(STATIC_FRONT_MATTER_FIELD_SET);
|
|
705
705
|
for (const definition of runtimeContext.fieldRegistry?.definitions ?? []) {
|
|
706
|
-
knownKeys.add(definition.
|
|
706
|
+
knownKeys.add(definition.metadata_key);
|
|
707
707
|
}
|
|
708
708
|
const unknownKeys = Object.keys(normalized)
|
|
709
709
|
.filter((key) => !knownKeys.has(key))
|
|
@@ -814,7 +814,7 @@ function parseJsonMarkdownItemDocument(content, runtimeContext, options = {}) {
|
|
|
814
814
|
}
|
|
815
815
|
assertValidFrontMatter(parsed, runtimeContext);
|
|
816
816
|
return {
|
|
817
|
-
|
|
817
|
+
metadata: normalizeFrontMatter(parsed, options),
|
|
818
818
|
body: normalizeBody(body),
|
|
819
819
|
};
|
|
820
820
|
}
|
|
@@ -832,7 +832,7 @@ function parseToonItemDocument(content, runtimeContext, options = {}) {
|
|
|
832
832
|
assertValidFrontMatter(record.front_matter, runtimeContext);
|
|
833
833
|
assertFrontMatterCondition(record.body === undefined || typeof record.body === "string", "TOON item document body must be a string");
|
|
834
834
|
return {
|
|
835
|
-
|
|
835
|
+
metadata: normalizeFrontMatter(record.front_matter, options),
|
|
836
836
|
body: normalizeBody(typeof record.body === "string" ? record.body : ""),
|
|
837
837
|
};
|
|
838
838
|
}
|
|
@@ -840,12 +840,12 @@ function parseToonItemDocument(content, runtimeContext, options = {}) {
|
|
|
840
840
|
assertFrontMatterCondition(body === undefined || typeof body === "string", "TOON item document body must be a string");
|
|
841
841
|
assertValidFrontMatter(frontMatterRecord, runtimeContext);
|
|
842
842
|
return {
|
|
843
|
-
|
|
843
|
+
metadata: normalizeFrontMatter(frontMatterRecord, options),
|
|
844
844
|
body: normalizeBody(typeof body === "string" ? body : ""),
|
|
845
845
|
};
|
|
846
846
|
}
|
|
847
847
|
function serializeJsonMarkdownItemDocument(document, options = {}) {
|
|
848
|
-
const normalizedFrontMatter = normalizeFrontMatter(document.
|
|
848
|
+
const normalizedFrontMatter = normalizeFrontMatter(document.metadata, options);
|
|
849
849
|
const orderedFrontMatter = orderFrontMatter(normalizedFrontMatter);
|
|
850
850
|
const serializedFrontMatter = JSON.stringify(orderedFrontMatter, null, 2);
|
|
851
851
|
const normalizedBody = normalizeBody(document.body ?? "");
|
|
@@ -855,7 +855,7 @@ function serializeJsonMarkdownItemDocument(document, options = {}) {
|
|
|
855
855
|
return `${serializedFrontMatter}\n\n${normalizedBody}\n`;
|
|
856
856
|
}
|
|
857
857
|
function serializeToonItemDocument(document, options = {}) {
|
|
858
|
-
const normalizedFrontMatter = normalizeFrontMatter(document.
|
|
858
|
+
const normalizedFrontMatter = normalizeFrontMatter(document.metadata, options);
|
|
859
859
|
const orderedFrontMatter = orderFrontMatter(normalizedFrontMatter);
|
|
860
860
|
const normalizedBody = normalizeBody(document.body ?? "");
|
|
861
861
|
return `${encodeToon({ ...orderedFrontMatter, body: normalizedBody })}\n`;
|
|
@@ -871,19 +871,19 @@ export function parseItemDocument(content, options = {}) {
|
|
|
871
871
|
nextSteps: ["Resolve conflicts, save the file, then rerun the pm command."],
|
|
872
872
|
});
|
|
873
873
|
}
|
|
874
|
-
const format = options.format ?? "
|
|
874
|
+
const format = options.format ?? "toon";
|
|
875
875
|
const runtimeContext = resolveRuntimeSchemaValidationContext(options);
|
|
876
876
|
return format === "toon"
|
|
877
877
|
? parseToonItemDocument(content, runtimeContext, options)
|
|
878
878
|
: parseJsonMarkdownItemDocument(content, runtimeContext, options);
|
|
879
879
|
}
|
|
880
880
|
export function serializeItemDocument(document, options = {}) {
|
|
881
|
-
const format = options.format ?? "
|
|
881
|
+
const format = options.format ?? "toon";
|
|
882
882
|
return format === "toon" ? serializeToonItemDocument(document, options) : serializeJsonMarkdownItemDocument(document, options);
|
|
883
883
|
}
|
|
884
884
|
export function canonicalDocument(document, options = {}) {
|
|
885
885
|
return {
|
|
886
|
-
|
|
886
|
+
metadata: normalizeFrontMatter(document.metadata, options),
|
|
887
887
|
body: normalizeBody(document.body ?? ""),
|
|
888
888
|
};
|
|
889
889
|
}
|