@unbrained/pm-cli 2026.5.10 → 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/.claude-plugin/marketplace.json +4 -4
- package/.pi/README.md +10 -1
- 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 +276 -36
- package/.pi/skills/pm-native/SKILL.md +6 -2
- package/CHANGELOG.md +7 -0
- package/README.md +9 -1
- 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/completion.js +7 -3
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/contracts.d.ts +19 -0
- package/dist/cli/commands/contracts.js +33 -1
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.js +112 -51
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/docs.js +9 -2
- 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 +9 -2
- package/dist/cli/commands/files.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/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/reindex.js +173 -135
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/search.js +16 -6
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/test.js +9 -2
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update.js +70 -39
- package/dist/cli/commands/update.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/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-setup.js +14 -0
- 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/lock/lock.js +2 -0
- package/dist/core/lock/lock.js.map +1 -1
- package/dist/core/sentry/instrument.d.ts +15 -0
- package/dist/core/sentry/instrument.js +35 -3
- package/dist/core/sentry/instrument.js.map +1 -1
- package/dist/core/shared/constants.js +20 -0
- 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/paths.js +34 -1
- package/dist/core/store/paths.js.map +1 -1
- package/dist/core/store/settings.js +210 -1
- 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/mcp/server.js +3 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/pi/native.js +57 -4
- package/dist/pi/native.js.map +1 -1
- package/dist/sdk/cli-contracts.d.ts +21 -1
- package/dist/sdk/cli-contracts.js +250 -0
- 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 +41 -0
- package/dist/types.js.map +1 -1
- package/docs/CLAUDE_CODE_PLUGIN.md +39 -0
- package/docs/EXTENSIONS.md +687 -0
- package/docs/MIGRATION_CLI_SIMPLIFICATION.md +64 -0
- package/docs/PI_PACKAGE.md +95 -10
- package/docs/SDK.md +441 -0
- 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 +3 -3
- package/package.json +1 -1
- package/plugins/pm-cli-claude/.claude-plugin/plugin.json +2 -2
- package/plugins/pm-cli-claude/README.md +55 -14
- 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/hooks/session-start.mjs +87 -22
|
@@ -19,7 +19,8 @@ import { locateItem } from "../../core/store/item-store.js";
|
|
|
19
19
|
import { getHistoryPath, getItemPath, getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
|
|
20
20
|
import { readSettings } from "../../core/store/settings.js";
|
|
21
21
|
import { loadCreateTemplateOptions } from "./templates.js";
|
|
22
|
-
import {
|
|
22
|
+
import { normalizeRiskInput, normalizeSeverityInput, parseConfidenceInput, parseRegressionInput, } from "./metadata-normalizers.js";
|
|
23
|
+
import { DEPENDENCY_KIND_VALUES, ISSUE_SEVERITY_VALUES, RECURRENCE_FREQUENCY_VALUES, RECURRENCE_WEEKDAY_VALUES, RISK_VALUES, SCOPE_VALUES, } from "../../types/index.js";
|
|
23
24
|
const CREATE_MODE_VALUES = ["strict", "progressive"];
|
|
24
25
|
const SCHEDULE_CREATE_PRESET_VALUES = ["lightweight"];
|
|
25
26
|
const SCHEDULE_CREATE_PRESET_TYPES = new Set(["Reminder", "Meeting", "Event"]);
|
|
@@ -171,38 +172,6 @@ function parseStatusValue(value, statusRegistry) {
|
|
|
171
172
|
}
|
|
172
173
|
return normalized;
|
|
173
174
|
}
|
|
174
|
-
function normalizeRiskInput(value) {
|
|
175
|
-
const trimmed = value.trim();
|
|
176
|
-
return trimmed.toLowerCase() === "med" ? "medium" : trimmed;
|
|
177
|
-
}
|
|
178
|
-
function normalizeSeverityInput(value) {
|
|
179
|
-
const trimmed = value.trim();
|
|
180
|
-
return trimmed.toLowerCase() === "med" ? "medium" : trimmed;
|
|
181
|
-
}
|
|
182
|
-
function parseConfidenceInput(value) {
|
|
183
|
-
const trimmed = value.trim().toLowerCase();
|
|
184
|
-
if (trimmed === "med") {
|
|
185
|
-
return "medium";
|
|
186
|
-
}
|
|
187
|
-
if (CONFIDENCE_TEXT_VALUES.includes(trimmed)) {
|
|
188
|
-
return trimmed;
|
|
189
|
-
}
|
|
190
|
-
const parsed = parseOptionalNumber(value, "confidence");
|
|
191
|
-
if (!Number.isInteger(parsed) || parsed < 0 || parsed > 100) {
|
|
192
|
-
throw new PmCliError("Confidence must be an integer 0..100 or one of low|med|medium|high", EXIT_CODE.USAGE);
|
|
193
|
-
}
|
|
194
|
-
return parsed;
|
|
195
|
-
}
|
|
196
|
-
function parseRegressionInput(value) {
|
|
197
|
-
const normalized = value.trim().toLowerCase();
|
|
198
|
-
if (normalized === "true" || normalized === "1") {
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
201
|
-
if (normalized === "false" || normalized === "0") {
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
throw new PmCliError("Regression must be one of true|false|1|0", EXIT_CODE.USAGE);
|
|
205
|
-
}
|
|
206
175
|
function parseCreatedAt(value, currentIso) {
|
|
207
176
|
if (!value || value.trim() === "" || value.trim().toLowerCase() === "now") {
|
|
208
177
|
return currentIso;
|
|
@@ -237,6 +206,61 @@ function assertNoLegacyNoneTokens(values, flag, replacementHint) {
|
|
|
237
206
|
const suffix = replacementHint ? ` ${replacementHint}` : "";
|
|
238
207
|
throw new PmCliError(`${flag} no longer accepts "none" or "null".${suffix}`.trim(), EXIT_CODE.USAGE);
|
|
239
208
|
}
|
|
209
|
+
const CREATE_LEGACY_NONE_COLLECTION_NORMALIZERS = [
|
|
210
|
+
{ optionKey: "dep", clearFlagKey: "clearDeps", valueFlag: "--dep", clearFlag: "--clear-deps" },
|
|
211
|
+
{ optionKey: "comment", clearFlagKey: "clearComments", valueFlag: "--comment", clearFlag: "--clear-comments" },
|
|
212
|
+
{ optionKey: "note", clearFlagKey: "clearNotes", valueFlag: "--note", clearFlag: "--clear-notes" },
|
|
213
|
+
{ optionKey: "learning", clearFlagKey: "clearLearnings", valueFlag: "--learning", clearFlag: "--clear-learnings" },
|
|
214
|
+
{ optionKey: "file", clearFlagKey: "clearFiles", valueFlag: "--file", clearFlag: "--clear-files" },
|
|
215
|
+
{ optionKey: "test", clearFlagKey: "clearTests", valueFlag: "--test", clearFlag: "--clear-tests" },
|
|
216
|
+
{ optionKey: "doc", clearFlagKey: "clearDocs", valueFlag: "--doc", clearFlag: "--clear-docs" },
|
|
217
|
+
{ optionKey: "reminder", clearFlagKey: "clearReminders", valueFlag: "--reminder", clearFlag: "--clear-reminders" },
|
|
218
|
+
{ optionKey: "event", clearFlagKey: "clearEvents", valueFlag: "--event", clearFlag: "--clear-events" },
|
|
219
|
+
{ optionKey: "typeOption", clearFlagKey: "clearTypeOptions", valueFlag: "--type-option", clearFlag: "--clear-type-options" },
|
|
220
|
+
];
|
|
221
|
+
function normalizeLegacyNoneCreateOptions(options) {
|
|
222
|
+
const normalized = {
|
|
223
|
+
...options,
|
|
224
|
+
unset: options.unset ? [...options.unset] : undefined,
|
|
225
|
+
};
|
|
226
|
+
const appendUnsetTarget = (value) => {
|
|
227
|
+
const current = normalized.unset ? [...normalized.unset] : [];
|
|
228
|
+
if (!current.includes(value)) {
|
|
229
|
+
current.push(value);
|
|
230
|
+
}
|
|
231
|
+
normalized.unset = current;
|
|
232
|
+
};
|
|
233
|
+
if (isLegacyNoneToken(normalized.template)) {
|
|
234
|
+
normalized.template = undefined;
|
|
235
|
+
}
|
|
236
|
+
const scalarOptionKeys = new Set([...CREATE_OPTION_KEY_TO_UNSET_CANONICAL.keys(), "rank"]);
|
|
237
|
+
for (const optionKey of scalarOptionKeys) {
|
|
238
|
+
const candidate = normalized[optionKey];
|
|
239
|
+
if (typeof candidate !== "string" || !isLegacyNoneToken(candidate)) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const canonicalUnset = optionKey === "rank" ? "order" : (CREATE_OPTION_KEY_TO_UNSET_CANONICAL.get(optionKey) ?? optionKey);
|
|
243
|
+
appendUnsetTarget(canonicalUnset);
|
|
244
|
+
normalized[optionKey] = undefined;
|
|
245
|
+
}
|
|
246
|
+
for (const definition of CREATE_LEGACY_NONE_COLLECTION_NORMALIZERS) {
|
|
247
|
+
const entries = normalized[definition.optionKey];
|
|
248
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const hasLegacy = entries.some((entry) => isLegacyNoneToken(entry));
|
|
252
|
+
if (!hasLegacy) {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
const concreteEntries = entries.filter((entry) => !isLegacyNoneToken(entry));
|
|
256
|
+
if (concreteEntries.length > 0) {
|
|
257
|
+
throw new PmCliError(`Cannot mix legacy clear token "none"/"null" with concrete ${definition.valueFlag} entries. Use ${definition.clearFlag} to clear or provide explicit entries.`, EXIT_CODE.USAGE);
|
|
258
|
+
}
|
|
259
|
+
normalized[definition.optionKey] = undefined;
|
|
260
|
+
normalized[definition.clearFlagKey] = true;
|
|
261
|
+
}
|
|
262
|
+
return normalized;
|
|
263
|
+
}
|
|
240
264
|
function parseOptionalString(value) {
|
|
241
265
|
if (value === undefined)
|
|
242
266
|
return undefined;
|
|
@@ -299,11 +323,14 @@ function parseDependencies(raw, nowValue, prefix) {
|
|
|
299
323
|
return { values: undefined, explicitEmpty: false };
|
|
300
324
|
assertNoLegacyNoneTokens(raw, "--dep", "Use --clear-deps to clear dependencies.");
|
|
301
325
|
const values = raw.map((entry) => {
|
|
302
|
-
const
|
|
326
|
+
const trimmedEntry = entry.trim();
|
|
327
|
+
const kv = looksLikeStructuredEntry(trimmedEntry, ["id", "kind", "author", "created_at"])
|
|
328
|
+
? parseCsvKv(entry, "--dep")
|
|
329
|
+
: { id: trimmedEntry, kind: "related" };
|
|
303
330
|
const id = parseOptionalString(kv.id);
|
|
304
331
|
const kind = parseOptionalString(kv.kind);
|
|
305
332
|
if (!id || !kind) {
|
|
306
|
-
throw new PmCliError("--dep requires id and kind", EXIT_CODE.USAGE);
|
|
333
|
+
throw new PmCliError("--dep requires id and kind, or a bare item id to create a related dependency", EXIT_CODE.USAGE);
|
|
307
334
|
}
|
|
308
335
|
if (id.trim().toLowerCase() === "undefined") {
|
|
309
336
|
throw new PmCliError(`--dep id must not use placeholder token "${id}". Use --clear-deps to clear dependencies.`, EXIT_CODE.USAGE);
|
|
@@ -317,6 +344,13 @@ function parseDependencies(raw, nowValue, prefix) {
|
|
|
317
344
|
});
|
|
318
345
|
return { values, explicitEmpty: false };
|
|
319
346
|
}
|
|
347
|
+
function looksLikeStructuredEntry(raw, keys) {
|
|
348
|
+
if (raw.startsWith("```") || raw.includes("\n")) {
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
const keyPattern = keys.map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
|
352
|
+
return new RegExp(`^(?:[-*+]\\s+)?(?:${keyPattern})\\s*[:=]`, "i").test(raw);
|
|
353
|
+
}
|
|
320
354
|
export function parseLogSeed(optionName, raw, nowValue, fallbackAuthor) {
|
|
321
355
|
if (!raw || raw.length === 0)
|
|
322
356
|
return { values: undefined, explicitEmpty: false };
|
|
@@ -343,17 +377,18 @@ export function parseLogSeed(optionName, raw, nowValue, fallbackAuthor) {
|
|
|
343
377
|
kv = parseCsvKv(entry, optionName);
|
|
344
378
|
}
|
|
345
379
|
catch (error) {
|
|
346
|
-
if (optionName === "--comment") {
|
|
380
|
+
if (optionName === "--comment" || optionName === "--note" || optionName === "--learning") {
|
|
347
381
|
return buildPlainTextCommentSeed();
|
|
348
382
|
}
|
|
349
383
|
throw error;
|
|
350
384
|
}
|
|
351
385
|
const unsupportedKeys = Object.keys(kv).filter((key) => !LOG_SEED_ALLOWED_KEYS.has(key));
|
|
352
386
|
if (unsupportedKeys.length > 0) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
387
|
+
return {
|
|
388
|
+
created_at: parseCreatedAt(kv.created_at, nowValue),
|
|
389
|
+
author: parseOptionalString(kv.author) ?? fallbackAuthor,
|
|
390
|
+
text: trimmedEntry,
|
|
391
|
+
};
|
|
357
392
|
}
|
|
358
393
|
const text = kv.text ?? "";
|
|
359
394
|
if (text === "") {
|
|
@@ -372,9 +407,12 @@ export function parseFiles(raw) {
|
|
|
372
407
|
return { values: undefined, explicitEmpty: false };
|
|
373
408
|
assertNoLegacyNoneTokens(raw, "--file", "Use --clear-files to clear linked files.");
|
|
374
409
|
const values = raw.map((entry) => {
|
|
375
|
-
const
|
|
410
|
+
const trimmedEntry = entry.trim();
|
|
411
|
+
const kv = looksLikeStructuredEntry(trimmedEntry, ["path", "scope", "note"])
|
|
412
|
+
? parseCsvKv(entry, "--file")
|
|
413
|
+
: { path: trimmedEntry };
|
|
376
414
|
if (!kv.path) {
|
|
377
|
-
throw new PmCliError("--file requires path=<value>", EXIT_CODE.USAGE);
|
|
415
|
+
throw new PmCliError("--file requires path=<value> or a bare file path", EXIT_CODE.USAGE);
|
|
378
416
|
}
|
|
379
417
|
return {
|
|
380
418
|
path: kv.path,
|
|
@@ -559,11 +597,32 @@ export function parseTests(raw) {
|
|
|
559
597
|
return { values: undefined, explicitEmpty: false };
|
|
560
598
|
assertNoLegacyNoneTokens(raw, "--test", "Use --clear-tests to clear linked tests.");
|
|
561
599
|
const values = raw.map((entry) => {
|
|
562
|
-
const
|
|
600
|
+
const trimmedEntry = entry.trim();
|
|
601
|
+
const kv = looksLikeStructuredEntry(trimmedEntry, [
|
|
602
|
+
"command",
|
|
603
|
+
"path",
|
|
604
|
+
"scope",
|
|
605
|
+
"timeout",
|
|
606
|
+
"timeout_seconds",
|
|
607
|
+
"pm_context_mode",
|
|
608
|
+
"env_set",
|
|
609
|
+
"env_clear",
|
|
610
|
+
"shared_host_safe",
|
|
611
|
+
"assert_stdout_contains",
|
|
612
|
+
"assert_stdout_regex",
|
|
613
|
+
"assert_stderr_contains",
|
|
614
|
+
"assert_stderr_regex",
|
|
615
|
+
"assert_stdout_min_lines",
|
|
616
|
+
"assert_json_field_equals",
|
|
617
|
+
"assert_json_field_gte",
|
|
618
|
+
"note",
|
|
619
|
+
])
|
|
620
|
+
? parseCsvKv(entry, "--test")
|
|
621
|
+
: { command: trimmedEntry };
|
|
563
622
|
const command = parseOptionalString(kv.command);
|
|
564
623
|
const filePath = parseOptionalString(kv.path);
|
|
565
624
|
if (!command) {
|
|
566
|
-
throw new PmCliError("--test requires command=<value> (path=<value> is optional metadata)", EXIT_CODE.USAGE);
|
|
625
|
+
throw new PmCliError("--test requires command=<value> or a bare command (path=<value> is optional metadata)", EXIT_CODE.USAGE);
|
|
567
626
|
}
|
|
568
627
|
const timeoutSecondsRaw = parseOptionalString(kv.timeout_seconds);
|
|
569
628
|
const timeoutAliasRaw = parseOptionalString(kv.timeout);
|
|
@@ -597,9 +656,12 @@ export function parseDocs(raw) {
|
|
|
597
656
|
return { values: undefined, explicitEmpty: false };
|
|
598
657
|
assertNoLegacyNoneTokens(raw, "--doc", "Use --clear-docs to clear linked docs.");
|
|
599
658
|
const values = raw.map((entry) => {
|
|
600
|
-
const
|
|
659
|
+
const trimmedEntry = entry.trim();
|
|
660
|
+
const kv = looksLikeStructuredEntry(trimmedEntry, ["path", "scope", "note"])
|
|
661
|
+
? parseCsvKv(entry, "--doc")
|
|
662
|
+
: { path: trimmedEntry };
|
|
601
663
|
if (!kv.path) {
|
|
602
|
-
throw new PmCliError("--doc requires path=<value>", EXIT_CODE.USAGE);
|
|
664
|
+
throw new PmCliError("--doc requires path=<value> or a bare doc path", EXIT_CODE.USAGE);
|
|
603
665
|
}
|
|
604
666
|
return {
|
|
605
667
|
path: kv.path,
|
|
@@ -705,9 +767,9 @@ function parseEvents(raw, nowValue) {
|
|
|
705
767
|
const referenceDate = new Date(nowValue);
|
|
706
768
|
const values = raw.map((entry) => {
|
|
707
769
|
const kv = parseCsvKv(entry, "--event");
|
|
708
|
-
const startRaw = parseOptionalString(kv.start)?.trim();
|
|
770
|
+
const startRaw = parseOptionalString(kv.start ?? kv.date)?.trim();
|
|
709
771
|
if (!startRaw) {
|
|
710
|
-
throw new PmCliError("--event requires start=<iso|relative>", EXIT_CODE.USAGE);
|
|
772
|
+
throw new PmCliError("--event requires start=<iso|relative> or date=<iso|relative>", EXIT_CODE.USAGE);
|
|
711
773
|
}
|
|
712
774
|
const startAt = resolveIsoOrRelative(startRaw, referenceDate, "event.start");
|
|
713
775
|
const endRaw = parseOptionalString(kv.end)?.trim();
|
|
@@ -1087,21 +1149,20 @@ function ensureInitHasRun(pmRoot) {
|
|
|
1087
1149
|
});
|
|
1088
1150
|
}
|
|
1089
1151
|
export async function runCreate(options, global) {
|
|
1090
|
-
let resolvedOptions = await resolveCreateStdinInputs(options);
|
|
1152
|
+
let resolvedOptions = normalizeLegacyNoneCreateOptions(await resolveCreateStdinInputs(options));
|
|
1091
1153
|
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
1092
1154
|
await ensureInitHasRun(pmRoot);
|
|
1093
1155
|
const settings = await readSettings(pmRoot);
|
|
1094
1156
|
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
1095
1157
|
const runtimeFieldRegistry = resolveRuntimeFieldRegistry(settings.schema);
|
|
1096
1158
|
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
1097
|
-
assertNoLegacyNoneToken(resolvedOptions.template, "--template", "Omit --template to skip template usage.");
|
|
1098
1159
|
if (resolvedOptions.template !== undefined) {
|
|
1099
1160
|
const templateName = resolvedOptions.template.trim();
|
|
1100
1161
|
if (templateName.length === 0) {
|
|
1101
1162
|
throw new PmCliError("--template must not be empty. Omit --template to disable template usage.", EXIT_CODE.USAGE);
|
|
1102
1163
|
}
|
|
1103
1164
|
const templateOptions = await loadCreateTemplateOptions(pmRoot, templateName);
|
|
1104
|
-
resolvedOptions = mergeCreateOptionsWithTemplate(templateOptions, resolvedOptions);
|
|
1165
|
+
resolvedOptions = normalizeLegacyNoneCreateOptions(mergeCreateOptionsWithTemplate(templateOptions, resolvedOptions));
|
|
1105
1166
|
}
|
|
1106
1167
|
if (resolvedOptions.type === undefined) {
|
|
1107
1168
|
throw new PmCliError("Missing required option --type <value>", EXIT_CODE.USAGE);
|