@unbrained/pm-cli 2026.5.18 → 2026.5.27
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/CHANGELOG.md +953 -472
- package/README.md +4 -11
- package/dist/cli/bootstrap-args.d.ts +18 -1
- package/dist/cli/bootstrap-args.js +143 -3
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commander-usage.js +147 -10
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/annotation-command.d.ts +49 -0
- package/dist/cli/commands/annotation-command.js +135 -0
- package/dist/cli/commands/annotation-command.js.map +1 -0
- package/dist/cli/commands/append.js +5 -8
- package/dist/cli/commands/append.js.map +1 -1
- package/dist/cli/commands/calendar.js +3 -6
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/claim.js +15 -24
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/close.js +63 -10
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/comments.d.ts +5 -0
- package/dist/cli/commands/comments.js +27 -117
- package/dist/cli/commands/comments.js.map +1 -1
- package/dist/cli/commands/completion.d.ts +2 -2
- package/dist/cli/commands/completion.js +203 -63
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/config.d.ts +1 -1
- package/dist/cli/commands/config.js +82 -4
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/context.js +4 -10
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/contracts.js +168 -36
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.js +53 -313
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/dedupe-audit.js +7 -4
- package/dist/cli/commands/dedupe-audit.js.map +1 -1
- package/dist/cli/commands/delete.d.ts +3 -0
- package/dist/cli/commands/delete.js +11 -9
- package/dist/cli/commands/delete.js.map +1 -1
- package/dist/cli/commands/docs.d.ts +2 -12
- package/dist/cli/commands/docs.js +8 -316
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/event-validation-messages.d.ts +3 -0
- package/dist/cli/commands/event-validation-messages.js +44 -0
- package/dist/cli/commands/event-validation-messages.js.map +1 -0
- package/dist/cli/commands/extension/bundled-catalog.d.ts +14 -0
- package/dist/cli/commands/extension/bundled-catalog.js +268 -0
- package/dist/cli/commands/extension/bundled-catalog.js.map +1 -0
- package/dist/cli/commands/extension/doctor.d.ts +31 -0
- package/dist/cli/commands/extension/doctor.js +345 -0
- package/dist/cli/commands/extension/doctor.js.map +1 -0
- package/dist/cli/commands/extension/install-sources.d.ts +37 -0
- package/dist/cli/commands/extension/install-sources.js +384 -0
- package/dist/cli/commands/extension/install-sources.js.map +1 -0
- package/dist/cli/commands/extension/managed-state.d.ts +48 -0
- package/dist/cli/commands/extension/managed-state.js +172 -0
- package/dist/cli/commands/extension/managed-state.js.map +1 -0
- package/dist/cli/commands/extension/scaffold.d.ts +14 -0
- package/dist/cli/commands/extension/scaffold.js +169 -0
- package/dist/cli/commands/extension/scaffold.js.map +1 -0
- package/dist/cli/commands/extension/shared.d.ts +14 -0
- package/dist/cli/commands/extension/shared.js +106 -0
- package/dist/cli/commands/extension/shared.js.map +1 -0
- package/dist/cli/commands/extension.d.ts +37 -68
- package/dist/cli/commands/extension.js +157 -1319
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/files.d.ts +1 -12
- package/dist/cli/commands/files.js +14 -318
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/gc.js +17 -4
- package/dist/cli/commands/gc.js.map +1 -1
- package/dist/cli/commands/get.d.ts +3 -2
- package/dist/cli/commands/get.js +52 -9
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/health.d.ts +10 -0
- package/dist/cli/commands/health.js +269 -76
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history-redact.d.ts +8 -0
- package/dist/cli/commands/history-redact.js +35 -113
- package/dist/cli/commands/history-redact.js.map +1 -1
- package/dist/cli/commands/history-repair.d.ts +33 -0
- package/dist/cli/commands/history-repair.js +172 -0
- package/dist/cli/commands/history-repair.js.map +1 -0
- package/dist/cli/commands/history.d.ts +4 -4
- package/dist/cli/commands/history.js +10 -88
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/index.d.ts +3 -1
- package/dist/cli/commands/index.js +5 -3
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +28 -0
- package/dist/cli/commands/init.js +23 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/learnings.js +20 -119
- package/dist/cli/commands/learnings.js.map +1 -1
- package/dist/cli/commands/legacy-none-tokens.d.ts +3 -0
- package/dist/cli/commands/legacy-none-tokens.js +39 -0
- package/dist/cli/commands/legacy-none-tokens.js.map +1 -0
- package/dist/cli/commands/linked-artifacts.d.ts +96 -0
- package/dist/cli/commands/linked-artifacts.js +335 -0
- package/dist/cli/commands/linked-artifacts.js.map +1 -0
- package/dist/cli/commands/linked-test-entry.d.ts +3 -0
- package/dist/cli/commands/linked-test-entry.js +62 -0
- package/dist/cli/commands/linked-test-entry.js.map +1 -0
- package/dist/cli/commands/linked-test-parsers.d.ts +28 -0
- package/dist/cli/commands/linked-test-parsers.js +192 -0
- package/dist/cli/commands/linked-test-parsers.js.map +1 -0
- package/dist/cli/commands/list.js +49 -24
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/normalize.js +4 -3
- package/dist/cli/commands/normalize.js.map +1 -1
- package/dist/cli/commands/notes.js +20 -119
- package/dist/cli/commands/notes.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +3 -0
- package/dist/cli/commands/plan.js +184 -22
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/recurrence-parsers.d.ts +26 -0
- package/dist/cli/commands/recurrence-parsers.js +98 -0
- package/dist/cli/commands/recurrence-parsers.js.map +1 -0
- package/dist/cli/commands/restore.js +24 -56
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/schema.d.ts +31 -0
- package/dist/cli/commands/schema.js +98 -0
- package/dist/cli/commands/schema.js.map +1 -0
- package/dist/cli/commands/search.js +154 -42
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/templates.d.ts +4 -0
- package/dist/cli/commands/templates.js +89 -17
- package/dist/cli/commands/templates.js.map +1 -1
- package/dist/cli/commands/test/linked-command-detection.d.ts +37 -0
- package/dist/cli/commands/test/linked-command-detection.js +200 -0
- package/dist/cli/commands/test/linked-command-detection.js.map +1 -0
- package/dist/cli/commands/test-all.js +4 -8
- package/dist/cli/commands/test-all.js.map +1 -1
- package/dist/cli/commands/test.d.ts +2 -2
- package/dist/cli/commands/test.js +12 -357
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update-many.js +6 -9
- package/dist/cli/commands/update-many.js.map +1 -1
- package/dist/cli/commands/update.js +167 -401
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +3 -1
- package/dist/cli/commands/validate.js +23 -71
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +1 -0
- package/dist/cli/error-guidance.js +100 -6
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/extension-command-help.d.ts +0 -1
- package/dist/cli/extension-command-help.js +2 -13
- package/dist/cli/extension-command-help.js.map +1 -1
- package/dist/cli/extension-command-options.d.ts +1 -0
- package/dist/cli/extension-command-options.js +106 -7
- package/dist/cli/extension-command-options.js.map +1 -1
- package/dist/cli/help-content.d.ts +0 -1
- package/dist/cli/help-content.js +13 -9
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/help-json-payload.d.ts +1 -0
- package/dist/cli/help-json-payload.js +33 -3
- package/dist/cli/help-json-payload.js.map +1 -1
- package/dist/cli/main.d.ts +11 -0
- package/dist/cli/main.js +109 -55
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.d.ts +5 -2
- package/dist/cli/register-list-query.js +254 -192
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.d.ts +1 -1
- package/dist/cli/register-mutation.js +247 -64
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +17 -12
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +33 -16
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.d.ts +0 -2
- package/dist/cli/registration-helpers.js +14 -40
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli.js +25 -4
- package/dist/cli.js.map +1 -1
- package/dist/core/config/positional-value.d.ts +44 -0
- package/dist/core/config/positional-value.js +109 -0
- package/dist/core/config/positional-value.js.map +1 -0
- package/dist/core/extensions/extension-capability-aliases.d.ts +14 -0
- package/dist/core/extensions/extension-capability-aliases.js +159 -0
- package/dist/core/extensions/extension-capability-aliases.js.map +1 -0
- package/dist/core/extensions/extension-hook-runtime.d.ts +13 -0
- package/dist/core/extensions/extension-hook-runtime.js +414 -0
- package/dist/core/extensions/extension-hook-runtime.js.map +1 -0
- package/dist/core/extensions/extension-policy.d.ts +69 -0
- package/dist/core/extensions/extension-policy.js +481 -0
- package/dist/core/extensions/extension-policy.js.map +1 -0
- package/dist/core/extensions/extension-registries.d.ts +8 -0
- package/dist/core/extensions/extension-registries.js +52 -0
- package/dist/core/extensions/extension-registries.js.map +1 -0
- package/dist/core/extensions/extension-runtime-helpers.d.ts +6 -0
- package/dist/core/extensions/extension-runtime-helpers.js +29 -0
- package/dist/core/extensions/extension-runtime-helpers.js.map +1 -0
- package/dist/core/extensions/extension-types.d.ts +13 -39
- package/dist/core/extensions/extension-types.js +34 -2
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +7 -1
- package/dist/core/extensions/index.js +11 -14
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +4 -22
- package/dist/core/extensions/loader.js +23 -1146
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/fs/path-utils.d.ts +1 -0
- package/dist/core/fs/path-utils.js +12 -0
- package/dist/core/fs/path-utils.js.map +1 -0
- package/dist/core/history/drift-scan.d.ts +22 -0
- package/dist/core/history/drift-scan.js +149 -0
- package/dist/core/history/drift-scan.js.map +1 -0
- package/dist/core/history/history-rewrite.d.ts +43 -0
- package/dist/core/history/history-rewrite.js +48 -0
- package/dist/core/history/history-rewrite.js.map +1 -0
- package/dist/core/history/history.js +5 -4
- package/dist/core/history/history.js.map +1 -1
- package/dist/core/history/replay.d.ts +82 -0
- package/dist/core/history/replay.js +250 -0
- package/dist/core/history/replay.js.map +1 -0
- package/dist/core/item/item-format.js +11 -8
- package/dist/core/item/item-format.js.map +1 -1
- package/dist/core/item/item-record.d.ts +19 -0
- package/dist/core/item/item-record.js +24 -0
- package/dist/core/item/item-record.js.map +1 -0
- package/dist/core/item/item-type-definition.d.ts +52 -0
- package/dist/core/item/item-type-definition.js +123 -0
- package/dist/core/item/item-type-definition.js.map +1 -0
- package/dist/core/item/parse.js +3 -2
- package/dist/core/item/parse.js.map +1 -1
- package/dist/core/item/priority.d.ts +23 -0
- package/dist/core/item/priority.js +55 -0
- package/dist/core/item/priority.js.map +1 -0
- package/dist/core/item/status.d.ts +14 -1
- package/dist/core/item/status.js +22 -2
- package/dist/core/item/status.js.map +1 -1
- package/dist/core/item/toon-decode.d.ts +19 -0
- package/dist/core/item/toon-decode.js +69 -0
- package/dist/core/item/toon-decode.js.map +1 -0
- package/dist/core/item/type-registry.js +13 -84
- package/dist/core/item/type-registry.js.map +1 -1
- package/dist/core/output/mutation-projection.d.ts +31 -0
- package/dist/core/output/mutation-projection.js +103 -0
- package/dist/core/output/mutation-projection.js.map +1 -0
- package/dist/core/output/output.d.ts +2 -0
- package/dist/core/output/output.js +5 -3
- package/dist/core/output/output.js.map +1 -1
- package/dist/core/packages/manifest.js +3 -9
- package/dist/core/packages/manifest.js.map +1 -1
- package/dist/core/schema/item-types-file.d.ts +85 -0
- package/dist/core/schema/item-types-file.js +243 -0
- package/dist/core/schema/item-types-file.js.map +1 -0
- package/dist/core/schema/runtime-schema.d.ts +2 -1
- package/dist/core/schema/runtime-schema.js +17 -45
- package/dist/core/schema/runtime-schema.js.map +1 -1
- package/dist/core/search/semantic-defaults.js +3 -3
- package/dist/core/search/semantic-defaults.js.map +1 -1
- package/dist/core/search/vector-stores.js +46 -9
- package/dist/core/search/vector-stores.js.map +1 -1
- package/dist/core/sentry/helpers.d.ts +1 -1
- package/dist/core/sentry/helpers.js +20 -3
- package/dist/core/sentry/helpers.js.map +1 -1
- package/dist/core/shared/author.d.ts +1 -0
- package/dist/core/shared/author.js +9 -0
- package/dist/core/shared/author.js.map +1 -0
- package/dist/core/shared/command-types.d.ts +1 -0
- package/dist/core/shared/command-types.js +2 -2
- package/dist/core/shared/command-types.js.map +1 -1
- package/dist/core/shared/constants.d.ts +10 -1
- package/dist/core/shared/constants.js +56 -58
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/lazy-module.d.ts +1 -0
- package/dist/core/shared/lazy-module.js +11 -0
- package/dist/core/shared/lazy-module.js.map +1 -0
- package/dist/core/shared/option-alias-visibility.d.ts +44 -0
- package/dist/core/shared/option-alias-visibility.js +76 -0
- package/dist/core/shared/option-alias-visibility.js.map +1 -0
- package/dist/core/shared/primitives.d.ts +23 -0
- package/dist/core/shared/primitives.js +39 -2
- package/dist/core/shared/primitives.js.map +1 -1
- package/dist/core/shared/text-normalization.d.ts +0 -1
- package/dist/core/shared/text-normalization.js +2 -5
- package/dist/core/shared/text-normalization.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +16 -2
- package/dist/core/store/front-matter-cache.js +99 -33
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/core/store/item-store.d.ts +2 -0
- package/dist/core/store/item-store.js +76 -110
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/settings-validator.d.ts +106 -0
- package/dist/core/store/settings-validator.js +279 -0
- package/dist/core/store/settings-validator.js.map +1 -0
- package/dist/core/store/settings.js +6 -343
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/telemetry/runtime.js +5 -3
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/mcp/server.js +138 -39
- package/dist/mcp/server.js.map +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +20 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +156 -0
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +14 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +243 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +11 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +901 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +18 -33
- package/dist/sdk/cli-contracts.js +96 -1238
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/package-import-adapters.d.ts +74 -0
- package/dist/sdk/package-import-adapters.js +186 -0
- package/dist/sdk/package-import-adapters.js.map +1 -0
- package/dist/sdk/package-runtime-options.d.ts +26 -0
- package/dist/sdk/package-runtime-options.js +71 -0
- package/dist/sdk/package-runtime-options.js.map +1 -0
- package/dist/sdk/runtime.d.ts +27 -1
- package/dist/sdk/runtime.js +48 -3
- package/dist/sdk/runtime.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.js +10 -2
- package/dist/types.js.map +1 -1
- package/docs/AGENT_GUIDE.md +13 -11
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/CLAUDE_CODE_PLUGIN.md +5 -28
- package/docs/CODEX_PLUGIN.md +5 -5
- package/docs/COMMANDS.md +58 -9
- package/docs/CONFIGURATION.md +16 -1
- package/docs/EXTENSIONS.md +4 -63
- package/docs/RELEASING.md +12 -8
- package/docs/SDK.md +11 -2
- package/marketplace.json +7 -3
- package/package.json +18 -14
- package/packages/pm-beads/extensions/beads/index.js +2 -49
- package/packages/pm-beads/extensions/beads/index.ts +2 -54
- package/packages/pm-beads/extensions/beads/runtime-loader.js +86 -0
- package/packages/pm-beads/extensions/beads/runtime-loader.ts +88 -0
- package/packages/pm-beads/extensions/beads/runtime.js +26 -115
- package/packages/pm-beads/extensions/beads/runtime.ts +33 -132
- package/packages/pm-calendar/README.md +3 -1
- package/packages/pm-calendar/extensions/calendar/index.js +66 -2
- package/packages/pm-calendar/extensions/calendar/index.ts +71 -2
- package/packages/pm-calendar/extensions/calendar/runtime.js +1 -0
- package/packages/pm-calendar/extensions/calendar/runtime.ts +1 -0
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +14 -41
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +25 -41
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +10 -50
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +17 -50
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +8 -40
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +10 -40
- package/packages/pm-search-advanced/README.md +8 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.js +75 -1
- package/packages/pm-search-advanced/extensions/search-advanced/index.ts +74 -0
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +58 -33
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +60 -33
- package/packages/pm-templates/extensions/templates/runtime.js +11 -202
- package/packages/pm-templates/extensions/templates/runtime.ts +38 -230
- package/packages/pm-todos/extensions/todos/index.js +3 -50
- package/packages/pm-todos/extensions/todos/index.ts +3 -55
- package/packages/pm-todos/extensions/todos/runtime-loader.js +86 -0
- package/packages/pm-todos/extensions/todos/runtime-loader.ts +88 -0
- package/packages/pm-todos/extensions/todos/runtime.js +24 -117
- package/packages/pm-todos/extensions/todos/runtime.ts +32 -129
- package/plugins/pm-claude/README.md +2 -2
- package/plugins/pm-claude/commands/pm-planner.md +1 -15
- package/plugins/pm-claude/scripts/pm-mcp-server.mjs +5 -2
- package/plugins/pm-claude/skills/pm-planner/SKILL.md +3 -21
- package/plugins/pm-codex/scripts/pm-mcp-server.mjs +15 -6
- package/plugins/pm-codex/skills/pm-native/SKILL.md +1 -13
- package/PRD.md +0 -1734
- package/dist/core/output/command-aware.d.ts +0 -1
- package/dist/core/output/command-aware.js +0 -397
- package/dist/core/output/command-aware.js.map +0 -1
|
@@ -8,6 +8,8 @@ const {
|
|
|
8
8
|
PmCliError,
|
|
9
9
|
runSearch,
|
|
10
10
|
runReindex,
|
|
11
|
+
readStringOption,
|
|
12
|
+
readBooleanOption,
|
|
11
13
|
} = sdk;
|
|
12
14
|
|
|
13
15
|
async function loadSearchSdkModule() {
|
|
@@ -24,6 +26,8 @@ async function loadSearchSdkModule() {
|
|
|
24
26
|
typeof loaded.runSearch === "function" &&
|
|
25
27
|
typeof loaded.runReindex === "function" &&
|
|
26
28
|
typeof loaded.PmCliError === "function" &&
|
|
29
|
+
typeof loaded.readStringOption === "function" &&
|
|
30
|
+
typeof loaded.readBooleanOption === "function" &&
|
|
27
31
|
typeof loaded.EXIT_CODE === "object" &&
|
|
28
32
|
loaded.EXIT_CODE !== null
|
|
29
33
|
) {
|
|
@@ -37,58 +41,79 @@ async function loadSearchSdkModule() {
|
|
|
37
41
|
);
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
const SEARCH_VALUE_FLAGS = new Set([
|
|
45
|
+
"--mode",
|
|
46
|
+
"--type",
|
|
47
|
+
"--tag",
|
|
48
|
+
"--priority",
|
|
49
|
+
"--deadline-before",
|
|
50
|
+
"--deadline_before",
|
|
51
|
+
"--deadline-after",
|
|
52
|
+
"--deadline_after",
|
|
53
|
+
"--limit",
|
|
54
|
+
"--fields",
|
|
55
|
+
]);
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
const SEARCH_BOOLEAN_FLAGS = new Set([
|
|
58
|
+
"--semantic",
|
|
59
|
+
"--hybrid",
|
|
60
|
+
"--include-linked",
|
|
61
|
+
"--include_linked",
|
|
62
|
+
"--title-exact",
|
|
63
|
+
"--title_exact",
|
|
64
|
+
"--phrase-exact",
|
|
65
|
+
"--phrase_exact",
|
|
66
|
+
"--compact",
|
|
67
|
+
"--full",
|
|
68
|
+
"--json",
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
function stripSearchOptionTokens(args) {
|
|
72
|
+
const queryTokens = [];
|
|
73
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
74
|
+
const token = args[index]?.trim() ?? "";
|
|
75
|
+
const equalsIndex = token.indexOf("=");
|
|
76
|
+
const flagName = equalsIndex > 0 ? token.slice(0, equalsIndex) : token;
|
|
77
|
+
if (SEARCH_VALUE_FLAGS.has(flagName)) {
|
|
78
|
+
if (equalsIndex < 0) {
|
|
79
|
+
index += 1;
|
|
80
|
+
}
|
|
56
81
|
continue;
|
|
57
82
|
}
|
|
58
|
-
if (
|
|
59
|
-
|
|
83
|
+
if (SEARCH_BOOLEAN_FLAGS.has(flagName)) {
|
|
84
|
+
continue;
|
|
60
85
|
}
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
if (normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "on") {
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
66
|
-
if (normalized === "false" || normalized === "0" || normalized === "no" || normalized === "off") {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
86
|
+
if (token.length > 0) {
|
|
87
|
+
queryTokens.push(token);
|
|
69
88
|
}
|
|
70
89
|
}
|
|
71
|
-
return
|
|
90
|
+
return queryTokens;
|
|
72
91
|
}
|
|
73
92
|
|
|
74
93
|
function resolveSearchQuery(args) {
|
|
75
|
-
const query = args
|
|
76
|
-
.map((value) => value.trim())
|
|
77
|
-
.filter((value) => value.length > 0)
|
|
78
|
-
.join(" ");
|
|
94
|
+
const query = stripSearchOptionTokens(args).join(" ");
|
|
79
95
|
if (query.length === 0) {
|
|
80
96
|
throw new PmCliError("Search query must not be empty", EXIT_CODE.USAGE);
|
|
81
97
|
}
|
|
82
98
|
return query;
|
|
83
99
|
}
|
|
84
100
|
|
|
85
|
-
function normalizeAdvancedSearchOptions(rawOptions) {
|
|
101
|
+
function normalizeAdvancedSearchOptions(rawOptions, args) {
|
|
86
102
|
const fields = readStringOption(rawOptions, "fields");
|
|
87
103
|
const compactRequested = readBooleanOption(rawOptions, "compact") === true;
|
|
88
104
|
const fullRequested = readBooleanOption(rawOptions, "full") === true;
|
|
89
105
|
const defaultCompact = !compactRequested && !fullRequested && fields === undefined;
|
|
106
|
+
const explicitMode = readStringOption(rawOptions, "mode");
|
|
107
|
+
const argFlags = new Set(args.map((value) => value?.trim() ?? ""));
|
|
108
|
+
const mode =
|
|
109
|
+
explicitMode ??
|
|
110
|
+
(readBooleanOption(rawOptions, "semantic") === true || argFlags.has("--semantic")
|
|
111
|
+
? "semantic"
|
|
112
|
+
: readBooleanOption(rawOptions, "hybrid") === true || argFlags.has("--hybrid")
|
|
113
|
+
? "hybrid"
|
|
114
|
+
: "keyword");
|
|
90
115
|
return {
|
|
91
|
-
mode
|
|
116
|
+
mode,
|
|
92
117
|
includeLinked: readBooleanOption(rawOptions, "includeLinked", ["include_linked"]) === true ? true : undefined,
|
|
93
118
|
titleExact: readBooleanOption(rawOptions, "titleExact", ["title_exact"]) === true ? true : undefined,
|
|
94
119
|
phraseExact: readBooleanOption(rawOptions, "phraseExact", ["phrase_exact"]) === true ? true : undefined,
|
|
@@ -112,7 +137,7 @@ function normalizeReindexOptions(rawOptions) {
|
|
|
112
137
|
}
|
|
113
138
|
|
|
114
139
|
export async function runAdvancedSearchPackage(args, rawOptions, global) {
|
|
115
|
-
return runSearch(resolveSearchQuery(args), normalizeAdvancedSearchOptions(rawOptions), global);
|
|
140
|
+
return runSearch(resolveSearchQuery(args), normalizeAdvancedSearchOptions(rawOptions, args), global);
|
|
116
141
|
}
|
|
117
142
|
|
|
118
143
|
export async function runAdvancedReindexPackage(rawOptions, global) {
|
|
@@ -17,6 +17,8 @@ interface SearchRuntimeSdkModule {
|
|
|
17
17
|
PmCliError: new (message: string, exitCode?: number) => Error;
|
|
18
18
|
runSearch: (query: string, options: SearchOptions, global: GlobalOptions) => Promise<SearchResult>;
|
|
19
19
|
runReindex: (options: ReindexOptions, global: GlobalOptions) => Promise<ReindexResult>;
|
|
20
|
+
readStringOption: (options: Record<string, unknown>, key: string, aliases?: string[]) => string | undefined;
|
|
21
|
+
readBooleanOption: (options: Record<string, unknown>, key: string, aliases?: string[]) => boolean | undefined;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
const sdk = await loadSearchSdkModule();
|
|
@@ -25,6 +27,8 @@ const {
|
|
|
25
27
|
PmCliError,
|
|
26
28
|
runSearch,
|
|
27
29
|
runReindex,
|
|
30
|
+
readStringOption,
|
|
31
|
+
readBooleanOption,
|
|
28
32
|
} = sdk;
|
|
29
33
|
|
|
30
34
|
async function loadSearchSdkModule(): Promise<SearchRuntimeSdkModule> {
|
|
@@ -41,6 +45,8 @@ async function loadSearchSdkModule(): Promise<SearchRuntimeSdkModule> {
|
|
|
41
45
|
typeof loaded.runSearch === "function" &&
|
|
42
46
|
typeof loaded.runReindex === "function" &&
|
|
43
47
|
typeof loaded.PmCliError === "function" &&
|
|
48
|
+
typeof loaded.readStringOption === "function" &&
|
|
49
|
+
typeof loaded.readBooleanOption === "function" &&
|
|
44
50
|
typeof loaded.EXIT_CODE === "object" &&
|
|
45
51
|
loaded.EXIT_CODE !== null
|
|
46
52
|
) {
|
|
@@ -54,58 +60,79 @@ async function loadSearchSdkModule(): Promise<SearchRuntimeSdkModule> {
|
|
|
54
60
|
);
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
const SEARCH_VALUE_FLAGS = new Set([
|
|
64
|
+
"--mode",
|
|
65
|
+
"--type",
|
|
66
|
+
"--tag",
|
|
67
|
+
"--priority",
|
|
68
|
+
"--deadline-before",
|
|
69
|
+
"--deadline_before",
|
|
70
|
+
"--deadline-after",
|
|
71
|
+
"--deadline_after",
|
|
72
|
+
"--limit",
|
|
73
|
+
"--fields",
|
|
74
|
+
]);
|
|
67
75
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
const SEARCH_BOOLEAN_FLAGS = new Set([
|
|
77
|
+
"--semantic",
|
|
78
|
+
"--hybrid",
|
|
79
|
+
"--include-linked",
|
|
80
|
+
"--include_linked",
|
|
81
|
+
"--title-exact",
|
|
82
|
+
"--title_exact",
|
|
83
|
+
"--phrase-exact",
|
|
84
|
+
"--phrase_exact",
|
|
85
|
+
"--compact",
|
|
86
|
+
"--full",
|
|
87
|
+
"--json",
|
|
88
|
+
]);
|
|
89
|
+
|
|
90
|
+
function stripSearchOptionTokens(args: string[]): string[] {
|
|
91
|
+
const queryTokens: string[] = [];
|
|
92
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
93
|
+
const token = args[index]?.trim() ?? "";
|
|
94
|
+
const equalsIndex = token.indexOf("=");
|
|
95
|
+
const flagName = equalsIndex > 0 ? token.slice(0, equalsIndex) : token;
|
|
96
|
+
if (SEARCH_VALUE_FLAGS.has(flagName)) {
|
|
97
|
+
if (equalsIndex < 0) {
|
|
98
|
+
index += 1;
|
|
99
|
+
}
|
|
73
100
|
continue;
|
|
74
101
|
}
|
|
75
|
-
if (
|
|
76
|
-
|
|
102
|
+
if (SEARCH_BOOLEAN_FLAGS.has(flagName)) {
|
|
103
|
+
continue;
|
|
77
104
|
}
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
if (normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "on") {
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
if (normalized === "false" || normalized === "0" || normalized === "no" || normalized === "off") {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
105
|
+
if (token.length > 0) {
|
|
106
|
+
queryTokens.push(token);
|
|
86
107
|
}
|
|
87
108
|
}
|
|
88
|
-
return
|
|
109
|
+
return queryTokens;
|
|
89
110
|
}
|
|
90
111
|
|
|
91
112
|
function resolveSearchQuery(args: string[]): string {
|
|
92
|
-
const query = args
|
|
93
|
-
.map((value) => value.trim())
|
|
94
|
-
.filter((value) => value.length > 0)
|
|
95
|
-
.join(" ");
|
|
113
|
+
const query = stripSearchOptionTokens(args).join(" ");
|
|
96
114
|
if (query.length === 0) {
|
|
97
115
|
throw new PmCliError("Search query must not be empty", EXIT_CODE.USAGE);
|
|
98
116
|
}
|
|
99
117
|
return query;
|
|
100
118
|
}
|
|
101
119
|
|
|
102
|
-
function normalizeAdvancedSearchOptions(rawOptions: Record<string, unknown
|
|
120
|
+
function normalizeAdvancedSearchOptions(rawOptions: Record<string, unknown>, args: string[]): SearchOptions {
|
|
103
121
|
const fields = readStringOption(rawOptions, "fields");
|
|
104
122
|
const compactRequested = readBooleanOption(rawOptions, "compact") === true;
|
|
105
123
|
const fullRequested = readBooleanOption(rawOptions, "full") === true;
|
|
106
124
|
const defaultCompact = !compactRequested && !fullRequested && fields === undefined;
|
|
125
|
+
const explicitMode = readStringOption(rawOptions, "mode");
|
|
126
|
+
const argFlags = new Set(args.map((value) => value?.trim() ?? ""));
|
|
127
|
+
const mode =
|
|
128
|
+
explicitMode ??
|
|
129
|
+
(readBooleanOption(rawOptions, "semantic") === true || argFlags.has("--semantic")
|
|
130
|
+
? "semantic"
|
|
131
|
+
: readBooleanOption(rawOptions, "hybrid") === true || argFlags.has("--hybrid")
|
|
132
|
+
? "hybrid"
|
|
133
|
+
: "keyword");
|
|
107
134
|
return {
|
|
108
|
-
mode
|
|
135
|
+
mode,
|
|
109
136
|
includeLinked: readBooleanOption(rawOptions, "includeLinked", ["include_linked"]) === true ? true : undefined,
|
|
110
137
|
titleExact: readBooleanOption(rawOptions, "titleExact", ["title_exact"]) === true ? true : undefined,
|
|
111
138
|
phraseExact: readBooleanOption(rawOptions, "phraseExact", ["phrase_exact"]) === true ? true : undefined,
|
|
@@ -133,7 +160,7 @@ export async function runAdvancedSearchPackage(
|
|
|
133
160
|
rawOptions: Record<string, unknown>,
|
|
134
161
|
global: GlobalOptions,
|
|
135
162
|
): Promise<SearchResult> {
|
|
136
|
-
return runSearch(resolveSearchQuery(args), normalizeAdvancedSearchOptions(rawOptions), global);
|
|
163
|
+
return runSearch(resolveSearchQuery(args), normalizeAdvancedSearchOptions(rawOptions, args), global);
|
|
137
164
|
}
|
|
138
165
|
|
|
139
166
|
export async function runAdvancedReindexPackage(
|
|
@@ -1,226 +1,35 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
1
|
import path from "node:path";
|
|
3
2
|
import { pathToFileURL } from "node:url";
|
|
4
|
-
|
|
5
3
|
const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
|
|
6
4
|
const sdk = await loadTemplatesSdkModule();
|
|
7
|
-
const {
|
|
8
|
-
CREATE_COMMANDER_REPEATABLE_OPTION_CONTRACTS,
|
|
9
|
-
EXIT_CODE,
|
|
10
|
-
PmCliError,
|
|
11
|
-
getSettingsPath,
|
|
12
|
-
nowIso,
|
|
13
|
-
pathExists,
|
|
14
|
-
readFileIfExists,
|
|
15
|
-
resolvePmRoot,
|
|
16
|
-
writeFileAtomic,
|
|
17
|
-
} = sdk;
|
|
18
|
-
|
|
19
5
|
async function loadTemplatesSdkModule() {
|
|
20
6
|
const envRoot = process.env[PM_PACKAGE_ROOT_ENV];
|
|
21
7
|
if (typeof envRoot !== "string" || envRoot.trim().length === 0) {
|
|
22
|
-
throw new Error(
|
|
23
|
-
`builtin-templates requires ${PM_PACKAGE_ROOT_ENV} to locate core SDK runtime exports.`,
|
|
24
|
-
);
|
|
8
|
+
throw new Error(`builtin-templates requires ${PM_PACKAGE_ROOT_ENV} to locate core SDK runtime exports.`);
|
|
25
9
|
}
|
|
26
10
|
const modulePath = path.join(path.resolve(envRoot.trim()), "dist", "sdk", "index.js");
|
|
27
11
|
try {
|
|
28
12
|
const loaded = await import(pathToFileURL(modulePath).href);
|
|
29
|
-
if (
|
|
30
|
-
typeof loaded.
|
|
31
|
-
typeof loaded.
|
|
32
|
-
typeof loaded.
|
|
33
|
-
Array.isArray(loaded.CREATE_COMMANDER_REPEATABLE_OPTION_CONTRACTS)
|
|
34
|
-
) {
|
|
13
|
+
if (typeof loaded.loadCreateTemplateOptions === "function" &&
|
|
14
|
+
typeof loaded.runTemplatesList === "function" &&
|
|
15
|
+
typeof loaded.runTemplatesSave === "function" &&
|
|
16
|
+
typeof loaded.runTemplatesShow === "function") {
|
|
35
17
|
return loaded;
|
|
36
18
|
}
|
|
37
19
|
} catch {
|
|
38
20
|
// Fall through to deterministic failure message below.
|
|
39
21
|
}
|
|
40
|
-
throw new Error(
|
|
41
|
-
`builtin-templates failed to load SDK runtime exports from ${modulePath}.`,
|
|
42
|
-
);
|
|
22
|
+
throw new Error(`builtin-templates failed to load template runtime exports from ${modulePath}.`);
|
|
43
23
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const TEMPLATE_FILE_EXTENSION = ".json";
|
|
47
|
-
const TEMPLATE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
48
|
-
const TEMPLATE_OPTION_REPEATABLE_KEY_SET = new Set(CREATE_COMMANDER_REPEATABLE_OPTION_CONTRACTS.map((entry) => entry.target));
|
|
49
|
-
|
|
50
|
-
function normalizeTemplateName(rawName) {
|
|
51
|
-
const name = rawName.trim();
|
|
52
|
-
if (!TEMPLATE_NAME_PATTERN.test(name)) {
|
|
53
|
-
throw new PmCliError(
|
|
54
|
-
`Invalid template name "${rawName}". Expected 1-64 characters matching [A-Za-z0-9][A-Za-z0-9._-]*.`,
|
|
55
|
-
EXIT_CODE.USAGE,
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
return name;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function templatesDirectory(pmRoot) {
|
|
62
|
-
return path.join(pmRoot, TEMPLATE_DIRECTORY_NAME);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function templatePath(pmRoot, normalizedName) {
|
|
66
|
-
return path.join(templatesDirectory(pmRoot), `${normalizedName}${TEMPLATE_FILE_EXTENSION}`);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function ensureTrackerInitialized(pmRoot) {
|
|
70
|
-
if (!(await pathExists(getSettingsPath(pmRoot)))) {
|
|
71
|
-
throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function sortTemplateOptions(options) {
|
|
76
|
-
return Object.fromEntries(Object.entries(options).sort(([left], [right]) => left.localeCompare(right)));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function extractTemplateOptions(rawOptions) {
|
|
80
|
-
const next = {};
|
|
81
|
-
for (const [key, value] of Object.entries(rawOptions)) {
|
|
82
|
-
if (value === undefined) {
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
if (TEMPLATE_OPTION_REPEATABLE_KEY_SET.has(key)) {
|
|
86
|
-
if (typeof value === "string") {
|
|
87
|
-
next[key] = [value];
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (!Array.isArray(value)) {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
const values = value.filter((entry) => typeof entry === "string");
|
|
94
|
-
if (values.length > 0) {
|
|
95
|
-
next[key] = values;
|
|
96
|
-
}
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
if (typeof value === "string") {
|
|
100
|
-
next[key] = value;
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
if (Array.isArray(value) && value.every((entry) => typeof entry === "string")) {
|
|
104
|
-
next[key] = [...value];
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return sortTemplateOptions(next);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function parseStoredTemplateOptions(rawOptions, templateName) {
|
|
111
|
-
if (typeof rawOptions !== "object" || rawOptions === null || Array.isArray(rawOptions)) {
|
|
112
|
-
throw new PmCliError(`Template "${templateName}" has invalid options payload.`, EXIT_CODE.GENERIC_FAILURE);
|
|
113
|
-
}
|
|
114
|
-
const normalized = {};
|
|
115
|
-
for (const [key, value] of Object.entries(rawOptions)) {
|
|
116
|
-
const normalizedKey = key.trim();
|
|
117
|
-
if (normalizedKey.length === 0) {
|
|
118
|
-
throw new PmCliError(`Template "${templateName}" contains an empty option key.`, EXIT_CODE.GENERIC_FAILURE);
|
|
119
|
-
}
|
|
120
|
-
if (typeof value === "string") {
|
|
121
|
-
normalized[normalizedKey] = value;
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
if (Array.isArray(value) && value.every((entry) => typeof entry === "string")) {
|
|
125
|
-
normalized[normalizedKey] = [...value];
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
throw new PmCliError(`Template "${templateName}" contains invalid value for option "${normalizedKey}".`, EXIT_CODE.GENERIC_FAILURE);
|
|
129
|
-
}
|
|
130
|
-
return sortTemplateOptions(normalized);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function parseStoredTemplateDocument(raw, normalizedName) {
|
|
134
|
-
let parsed;
|
|
135
|
-
try {
|
|
136
|
-
parsed = JSON.parse(raw);
|
|
137
|
-
} catch {
|
|
138
|
-
throw new PmCliError(`Template "${normalizedName}" contains invalid JSON.`, EXIT_CODE.GENERIC_FAILURE);
|
|
139
|
-
}
|
|
140
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
141
|
-
throw new PmCliError(`Template "${normalizedName}" has invalid document shape.`, EXIT_CODE.GENERIC_FAILURE);
|
|
142
|
-
}
|
|
143
|
-
const options = parseStoredTemplateOptions(parsed.options, normalizedName);
|
|
144
|
-
const now = nowIso();
|
|
145
|
-
return {
|
|
146
|
-
name: typeof parsed.name === "string" && parsed.name.trim().length > 0 ? parsed.name.trim() : normalizedName,
|
|
147
|
-
created_at: typeof parsed.created_at === "string" ? parsed.created_at : now,
|
|
148
|
-
updated_at: typeof parsed.updated_at === "string" ? parsed.updated_at : now,
|
|
149
|
-
options,
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async function readStoredTemplateDocument(pmRoot, normalizedName) {
|
|
154
|
-
const raw = await readFileIfExists(templatePath(pmRoot, normalizedName));
|
|
155
|
-
if (raw === null) {
|
|
156
|
-
throw new PmCliError(`Template "${normalizedName}" not found`, EXIT_CODE.NOT_FOUND);
|
|
157
|
-
}
|
|
158
|
-
return parseStoredTemplateDocument(raw, normalizedName);
|
|
24
|
+
export async function loadCreateTemplateOptions(pmRoot, rawTemplateName) {
|
|
25
|
+
return sdk.loadCreateTemplateOptions(pmRoot, rawTemplateName);
|
|
159
26
|
}
|
|
160
|
-
|
|
161
27
|
export async function runTemplatesSave(rawTemplateName, options, global) {
|
|
162
|
-
|
|
163
|
-
await ensureTrackerInitialized(pmRoot);
|
|
164
|
-
const normalizedName = normalizeTemplateName(rawTemplateName);
|
|
165
|
-
const nextOptions = extractTemplateOptions(options);
|
|
166
|
-
if (Object.keys(nextOptions).length === 0) {
|
|
167
|
-
throw new PmCliError("templates save requires at least one create option flag", EXIT_CODE.USAGE);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const now = nowIso();
|
|
171
|
-
const storedPath = templatePath(pmRoot, normalizedName);
|
|
172
|
-
let createdAt = now;
|
|
173
|
-
if (await pathExists(storedPath)) {
|
|
174
|
-
const existing = await readStoredTemplateDocument(pmRoot, normalizedName);
|
|
175
|
-
createdAt = existing.created_at;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const document = {
|
|
179
|
-
name: normalizedName,
|
|
180
|
-
created_at: createdAt,
|
|
181
|
-
updated_at: now,
|
|
182
|
-
options: nextOptions,
|
|
183
|
-
};
|
|
184
|
-
await fs.mkdir(templatesDirectory(pmRoot), { recursive: true });
|
|
185
|
-
await writeFileAtomic(storedPath, `${JSON.stringify(document, null, 2)}\n`);
|
|
186
|
-
return {
|
|
187
|
-
name: document.name,
|
|
188
|
-
created_at: document.created_at,
|
|
189
|
-
updated_at: document.updated_at,
|
|
190
|
-
path: storedPath,
|
|
191
|
-
options: document.options,
|
|
192
|
-
};
|
|
28
|
+
return sdk.runTemplatesSave(rawTemplateName, options, global);
|
|
193
29
|
}
|
|
194
|
-
|
|
195
30
|
export async function runTemplatesList(global) {
|
|
196
|
-
|
|
197
|
-
await ensureTrackerInitialized(pmRoot);
|
|
198
|
-
const dirPath = templatesDirectory(pmRoot);
|
|
199
|
-
if (!(await pathExists(dirPath))) {
|
|
200
|
-
return { templates: [], count: 0 };
|
|
201
|
-
}
|
|
202
|
-
const entries = await fs.readdir(dirPath);
|
|
203
|
-
const templates = entries
|
|
204
|
-
.filter((entry) => entry.toLowerCase().endsWith(TEMPLATE_FILE_EXTENSION))
|
|
205
|
-
.map((entry) => entry.slice(0, -TEMPLATE_FILE_EXTENSION.length))
|
|
206
|
-
.filter((entry) => TEMPLATE_NAME_PATTERN.test(entry))
|
|
207
|
-
.sort((left, right) => left.localeCompare(right));
|
|
208
|
-
return {
|
|
209
|
-
templates,
|
|
210
|
-
count: templates.length,
|
|
211
|
-
};
|
|
31
|
+
return sdk.runTemplatesList(global);
|
|
212
32
|
}
|
|
213
|
-
|
|
214
33
|
export async function runTemplatesShow(rawTemplateName, global) {
|
|
215
|
-
|
|
216
|
-
await ensureTrackerInitialized(pmRoot);
|
|
217
|
-
const normalizedName = normalizeTemplateName(rawTemplateName);
|
|
218
|
-
const stored = await readStoredTemplateDocument(pmRoot, normalizedName);
|
|
219
|
-
return {
|
|
220
|
-
name: stored.name,
|
|
221
|
-
created_at: stored.created_at,
|
|
222
|
-
updated_at: stored.updated_at,
|
|
223
|
-
path: templatePath(pmRoot, normalizedName),
|
|
224
|
-
options: stored.options,
|
|
225
|
-
};
|
|
34
|
+
return sdk.runTemplatesShow(rawTemplateName, global);
|
|
226
35
|
}
|