@unbrained/pm-cli 2026.5.11 → 2026.5.14
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.md +3 -116
- package/CHANGELOG.md +18 -0
- package/PRD.md +18 -39
- package/README.md +8 -5
- package/dist/cli/commander-usage.js +27 -0
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/activity.js +19 -4
- package/dist/cli/commands/activity.js.map +1 -1
- package/dist/cli/commands/calendar.js +5 -2
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/contracts.js +63 -19
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.js +58 -3
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/extension.d.ts +14 -3
- package/dist/cli/commands/extension.js +481 -95
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/index.d.ts +1 -8
- package/dist/cli/commands/index.js +1 -8
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/reindex.d.ts +8 -0
- package/dist/cli/commands/reindex.js +96 -23
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/search.js +51 -25
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/test.js +14 -6
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/upgrade.d.ts +63 -0
- package/dist/cli/commands/upgrade.js +260 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/guide-topics.js +18 -16
- package/dist/cli/guide-topics.js.map +1 -1
- package/dist/cli/help-content.js +57 -18
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/main.js +73 -7
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +24 -142
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +49 -257
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +29 -198
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +181 -204
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.d.ts +2 -2
- package/dist/cli/registration-helpers.js +1 -19
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/core/extensions/loader.js +7 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/packages/manifest.d.ts +38 -0
- package/dist/core/packages/manifest.js +221 -0
- package/dist/core/packages/manifest.js.map +1 -0
- package/dist/core/search/embedding-batches.d.ts +13 -1
- package/dist/core/search/embedding-batches.js +19 -1
- package/dist/core/search/embedding-batches.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +8 -1
- package/dist/core/store/front-matter-cache.js +20 -11
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/mcp/server.d.ts +8 -0
- package/dist/mcp/server.js +100 -43
- package/dist/mcp/server.js.map +1 -1
- package/dist/sdk/cli-contracts/commander-mutation-options.d.ts +7 -0
- package/dist/sdk/cli-contracts/commander-mutation-options.js +477 -0
- package/dist/sdk/cli-contracts/commander-mutation-options.js.map +1 -0
- package/dist/sdk/cli-contracts/commander-types.d.ts +21 -0
- package/dist/sdk/cli-contracts/commander-types.js +92 -0
- package/dist/sdk/cli-contracts/commander-types.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +22 -32
- package/dist/sdk/cli-contracts.js +155 -296
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.js +2 -0
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runtime.d.ts +29 -0
- package/dist/sdk/runtime.js +28 -0
- package/dist/sdk/runtime.js.map +1 -0
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/COMMANDS.md +17 -1
- package/docs/EXTENSIONS.md +169 -61
- package/docs/QUICKSTART.md +11 -2
- package/docs/README.md +4 -6
- package/docs/RELEASING.md +4 -2
- package/docs/SDK.md +79 -438
- package/package.json +6 -23
- package/packages/pm-beads/README.md +10 -0
- package/packages/pm-beads/extensions/beads/index.js +113 -0
- package/{.agents/pm/extensions/beads/index.js → packages/pm-beads/extensions/beads/index.ts} +42 -20
- package/{.agents/pm → packages/pm-beads}/extensions/beads/runtime.js +2 -17
- package/{.agents/pm → packages/pm-beads}/extensions/beads/runtime.ts +41 -18
- package/packages/pm-beads/package.json +50 -0
- package/packages/pm-calendar/README.md +13 -0
- package/packages/pm-calendar/extensions/calendar/index.js +56 -0
- package/packages/pm-calendar/extensions/calendar/index.ts +62 -0
- package/packages/pm-calendar/extensions/calendar/manifest.json +7 -0
- package/packages/pm-calendar/extensions/calendar/runtime.js +95 -0
- package/packages/pm-calendar/extensions/calendar/runtime.ts +104 -0
- package/packages/pm-calendar/package.json +51 -0
- package/packages/pm-governance-audit/README.md +23 -0
- package/packages/pm-governance-audit/extensions/governance-audit/index.js +117 -0
- package/packages/pm-governance-audit/extensions/governance-audit/index.ts +118 -0
- package/packages/pm-governance-audit/extensions/governance-audit/manifest.json +7 -0
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +159 -0
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +176 -0
- package/packages/pm-governance-audit/package.json +52 -0
- package/packages/pm-guide-shell/README.md +23 -0
- package/packages/pm-guide-shell/extensions/guide-shell/index.js +76 -0
- package/packages/pm-guide-shell/extensions/guide-shell/index.ts +81 -0
- package/packages/pm-guide-shell/extensions/guide-shell/manifest.json +7 -0
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +263 -0
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +327 -0
- package/packages/pm-guide-shell/package.json +52 -0
- package/packages/pm-linked-test-adapters/README.md +24 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/index.js +101 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/index.ts +102 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/manifest.json +7 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +142 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +173 -0
- package/packages/pm-linked-test-adapters/package.json +53 -0
- package/packages/pm-search-advanced/README.md +27 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.js +93 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.ts +94 -0
- package/packages/pm-search-advanced/extensions/search-advanced/manifest.json +7 -0
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +120 -0
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +144 -0
- package/packages/pm-search-advanced/package.json +54 -0
- package/packages/pm-templates/README.md +20 -0
- package/packages/pm-templates/extensions/templates/index.js +101 -0
- package/packages/pm-templates/extensions/templates/index.ts +109 -0
- package/packages/pm-templates/extensions/templates/manifest.json +7 -0
- package/packages/pm-templates/extensions/templates/runtime.js +226 -0
- package/packages/pm-templates/extensions/templates/runtime.ts +283 -0
- package/packages/pm-templates/package.json +50 -0
- package/packages/pm-todos/README.md +11 -0
- package/packages/pm-todos/extensions/todos/index.js +130 -0
- package/{.agents/pm/extensions/todos/index.js → packages/pm-todos/extensions/todos/index.ts} +47 -23
- package/{.agents/pm → packages/pm-todos}/extensions/todos/runtime.js +3 -18
- package/{.agents/pm → packages/pm-todos}/extensions/todos/runtime.ts +42 -20
- package/packages/pm-todos/package.json +51 -0
- package/plugins/pm-cli-claude/README.md +1 -2
- package/plugins/pm-cli-claude/hooks/session-start.mjs +4 -55
- package/plugins/pm-cli-claude/scripts/pm-mcp-server.mjs +4 -2
- package/plugins/pm-cli-codex/scripts/pm-mcp-server.mjs +4 -2
- package/.agents/pm/extensions/.managed-extensions.json +0 -42
- package/.agents/skills/HARNESS_COMPATIBILITY.md +0 -45
- package/.agents/skills/README.md +0 -21
- package/.agents/skills/pm-developer/SKILL.md +0 -73
- package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +0 -48
- package/.agents/skills/pm-developer/references/PROMPTS.md +0 -17
- package/.agents/skills/pm-extensions/SKILL.md +0 -57
- package/.agents/skills/pm-extensions/references/LIFECYCLE.md +0 -40
- package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +0 -25
- package/.agents/skills/pm-sdk/SKILL.md +0 -50
- package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +0 -31
- package/.agents/skills/pm-sdk/references/PROMPTS.md +0 -13
- package/.agents/skills/pm-user/SKILL.md +0 -59
- package/.agents/skills/pm-user/references/PROMPTS.md +0 -17
- package/.agents/skills/pm-user/references/WORKFLOWS.md +0 -35
- package/.pi/README.md +0 -35
- package/.pi/agents/pm-triage-agent.md +0 -19
- package/.pi/agents/pm-verification-agent.md +0 -21
- package/.pi/chains/pm-native-delivery.chain.md +0 -11
- package/.pi/extensions/pm-cli/index.js +0 -387
- package/.pi/prompts/pm-workflow.md +0 -5
- package/.pi/skills/pm-native/SKILL.md +0 -44
- package/.pi/skills/pm-release/SKILL.md +0 -35
- package/dist/pi/native.d.ts +0 -5
- package/dist/pi/native.js +0 -236
- package/dist/pi/native.js.map +0 -1
- package/docs/PI_PACKAGE.md +0 -141
- /package/{.agents/pm → packages/pm-beads}/extensions/beads/manifest.json +0 -0
- /package/{.agents/pm → packages/pm-todos}/extensions/todos/manifest.json +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { runAdvancedReindexPackage, runAdvancedSearchPackage } from "./runtime.js";
|
|
2
|
+
|
|
3
|
+
export const manifest = {
|
|
4
|
+
name: "builtin-search-advanced",
|
|
5
|
+
version: "0.1.0",
|
|
6
|
+
entry: "./index.js",
|
|
7
|
+
priority: 0,
|
|
8
|
+
capabilities: ["commands"],
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const searchAdvancedFlags = [
|
|
12
|
+
{
|
|
13
|
+
long: "--mode",
|
|
14
|
+
value_name: "value",
|
|
15
|
+
value_type: "string",
|
|
16
|
+
description: "Search mode override: keyword|semantic|hybrid.",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
long: "--include-linked",
|
|
20
|
+
value_type: "boolean",
|
|
21
|
+
description: "Include linked docs/files/tests corpus in lexical scoring.",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
long: "--include_linked",
|
|
25
|
+
value_type: "boolean",
|
|
26
|
+
description: "Alias for --include-linked.",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
long: "--title-exact",
|
|
30
|
+
value_type: "boolean",
|
|
31
|
+
description: "Require exact title phrase matching before scoring.",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
long: "--title_exact",
|
|
35
|
+
value_type: "boolean",
|
|
36
|
+
description: "Alias for --title-exact.",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
long: "--phrase-exact",
|
|
40
|
+
value_type: "boolean",
|
|
41
|
+
description: "Require exact phrase match across searchable document fields.",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
long: "--phrase_exact",
|
|
45
|
+
value_type: "boolean",
|
|
46
|
+
description: "Alias for --phrase-exact.",
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
const reindexFlags = [
|
|
51
|
+
{
|
|
52
|
+
long: "--mode",
|
|
53
|
+
value_name: "value",
|
|
54
|
+
value_type: "string",
|
|
55
|
+
description: "Reindex mode: keyword|semantic|hybrid.",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
long: "--progress",
|
|
59
|
+
value_type: "boolean",
|
|
60
|
+
description: "Emit non-interactive progress lines to stderr.",
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
function searchAdvancedCommand() {
|
|
65
|
+
return {
|
|
66
|
+
name: "search-advanced",
|
|
67
|
+
action: "search-advanced",
|
|
68
|
+
description: "Enable optional semantic and hybrid search modes via package runtime.",
|
|
69
|
+
arguments: [{ name: "keywords", required: true, variadic: true, description: "Query tokens." }],
|
|
70
|
+
run: async (context) => runAdvancedSearchPackage(context.args, context.options, context.global),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function reindexCommand() {
|
|
75
|
+
return {
|
|
76
|
+
name: "reindex",
|
|
77
|
+
action: "reindex",
|
|
78
|
+
description: "Rebuild search artifacts for keyword, semantic, and hybrid modes.",
|
|
79
|
+
flags: [...reindexFlags],
|
|
80
|
+
run: async (context) => runAdvancedReindexPackage(context.options, context.global),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function activate(api) {
|
|
85
|
+
api.registerFlags("search-advanced", [...searchAdvancedFlags]);
|
|
86
|
+
api.registerCommand(searchAdvancedCommand());
|
|
87
|
+
api.registerCommand(reindexCommand());
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export default {
|
|
91
|
+
manifest,
|
|
92
|
+
activate,
|
|
93
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { CommandDefinition, ExtensionApi } from "../../../../src/sdk/index.js";
|
|
2
|
+
import { runAdvancedReindexPackage, runAdvancedSearchPackage } from "./runtime.js";
|
|
3
|
+
|
|
4
|
+
export const manifest = {
|
|
5
|
+
name: "builtin-search-advanced",
|
|
6
|
+
version: "0.1.0",
|
|
7
|
+
entry: "./index.js",
|
|
8
|
+
priority: 0,
|
|
9
|
+
capabilities: ["commands"],
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const searchAdvancedFlags = [
|
|
13
|
+
{
|
|
14
|
+
long: "--mode",
|
|
15
|
+
value_name: "value",
|
|
16
|
+
value_type: "string",
|
|
17
|
+
description: "Search mode override: keyword|semantic|hybrid.",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
long: "--include-linked",
|
|
21
|
+
value_type: "boolean",
|
|
22
|
+
description: "Include linked docs/files/tests corpus in lexical scoring.",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
long: "--include_linked",
|
|
26
|
+
value_type: "boolean",
|
|
27
|
+
description: "Alias for --include-linked.",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
long: "--title-exact",
|
|
31
|
+
value_type: "boolean",
|
|
32
|
+
description: "Require exact title phrase matching before scoring.",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
long: "--title_exact",
|
|
36
|
+
value_type: "boolean",
|
|
37
|
+
description: "Alias for --title-exact.",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
long: "--phrase-exact",
|
|
41
|
+
value_type: "boolean",
|
|
42
|
+
description: "Require exact phrase match across searchable document fields.",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
long: "--phrase_exact",
|
|
46
|
+
value_type: "boolean",
|
|
47
|
+
description: "Alias for --phrase-exact.",
|
|
48
|
+
},
|
|
49
|
+
] as const;
|
|
50
|
+
|
|
51
|
+
const reindexFlags = [
|
|
52
|
+
{
|
|
53
|
+
long: "--mode",
|
|
54
|
+
value_name: "value",
|
|
55
|
+
value_type: "string",
|
|
56
|
+
description: "Reindex mode: keyword|semantic|hybrid.",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
long: "--progress",
|
|
60
|
+
value_type: "boolean",
|
|
61
|
+
description: "Emit non-interactive progress lines to stderr.",
|
|
62
|
+
},
|
|
63
|
+
] as const;
|
|
64
|
+
|
|
65
|
+
function searchAdvancedCommand(): CommandDefinition {
|
|
66
|
+
return {
|
|
67
|
+
name: "search-advanced",
|
|
68
|
+
action: "search-advanced",
|
|
69
|
+
description: "Enable optional semantic and hybrid search modes via package runtime.",
|
|
70
|
+
arguments: [{ name: "keywords", required: true, variadic: true, description: "Query tokens." }],
|
|
71
|
+
run: async (context) => runAdvancedSearchPackage(context.args, context.options, context.global),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function reindexCommand(): CommandDefinition {
|
|
76
|
+
return {
|
|
77
|
+
name: "reindex",
|
|
78
|
+
action: "reindex",
|
|
79
|
+
description: "Rebuild search artifacts for keyword, semantic, and hybrid modes.",
|
|
80
|
+
flags: [...reindexFlags],
|
|
81
|
+
run: async (context) => runAdvancedReindexPackage(context.options, context.global),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function activate(api: ExtensionApi): void {
|
|
86
|
+
api.registerFlags("search-advanced", [...searchAdvancedFlags]);
|
|
87
|
+
api.registerCommand(searchAdvancedCommand());
|
|
88
|
+
api.registerCommand(reindexCommand());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export default {
|
|
92
|
+
manifest,
|
|
93
|
+
activate,
|
|
94
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
|
|
4
|
+
const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
|
|
5
|
+
const sdk = await loadSearchSdkModule();
|
|
6
|
+
const {
|
|
7
|
+
EXIT_CODE,
|
|
8
|
+
PmCliError,
|
|
9
|
+
runSearch,
|
|
10
|
+
runReindex,
|
|
11
|
+
} = sdk;
|
|
12
|
+
|
|
13
|
+
async function loadSearchSdkModule() {
|
|
14
|
+
const envRoot = process.env[PM_PACKAGE_ROOT_ENV];
|
|
15
|
+
if (typeof envRoot !== "string" || envRoot.trim().length === 0) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`builtin-search-advanced requires ${PM_PACKAGE_ROOT_ENV} to locate core SDK runtime exports.`,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
const modulePath = path.join(path.resolve(envRoot.trim()), "dist", "sdk", "runtime.js");
|
|
21
|
+
try {
|
|
22
|
+
const loaded = await import(pathToFileURL(modulePath).href);
|
|
23
|
+
if (
|
|
24
|
+
typeof loaded.runSearch === "function" &&
|
|
25
|
+
typeof loaded.runReindex === "function" &&
|
|
26
|
+
typeof loaded.PmCliError === "function" &&
|
|
27
|
+
typeof loaded.EXIT_CODE === "object" &&
|
|
28
|
+
loaded.EXIT_CODE !== null
|
|
29
|
+
) {
|
|
30
|
+
return loaded;
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// Fall through to deterministic failure message below.
|
|
34
|
+
}
|
|
35
|
+
throw new Error(
|
|
36
|
+
`builtin-search-advanced failed to load SDK runtime exports from ${modulePath}.`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function readStringOption(options, key, aliases = []) {
|
|
41
|
+
const keys = [key, ...aliases];
|
|
42
|
+
for (const candidate of keys) {
|
|
43
|
+
const value = options[candidate];
|
|
44
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function readBooleanOption(options, key, aliases = []) {
|
|
52
|
+
const keys = [key, ...aliases];
|
|
53
|
+
for (const candidate of keys) {
|
|
54
|
+
const value = options[candidate];
|
|
55
|
+
if (value === undefined) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (typeof value === "boolean") {
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
if (typeof value === "string") {
|
|
62
|
+
const normalized = value.trim().toLowerCase();
|
|
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
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function resolveSearchQuery(args) {
|
|
75
|
+
const query = args
|
|
76
|
+
.map((value) => value.trim())
|
|
77
|
+
.filter((value) => value.length > 0)
|
|
78
|
+
.join(" ");
|
|
79
|
+
if (query.length === 0) {
|
|
80
|
+
throw new PmCliError("Search query must not be empty", EXIT_CODE.USAGE);
|
|
81
|
+
}
|
|
82
|
+
return query;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function normalizeAdvancedSearchOptions(rawOptions) {
|
|
86
|
+
const fields = readStringOption(rawOptions, "fields");
|
|
87
|
+
const compactRequested = readBooleanOption(rawOptions, "compact") === true;
|
|
88
|
+
const fullRequested = readBooleanOption(rawOptions, "full") === true;
|
|
89
|
+
const defaultCompact = !compactRequested && !fullRequested && fields === undefined;
|
|
90
|
+
return {
|
|
91
|
+
mode: readStringOption(rawOptions, "mode"),
|
|
92
|
+
includeLinked: readBooleanOption(rawOptions, "includeLinked", ["include_linked"]) === true ? true : undefined,
|
|
93
|
+
titleExact: readBooleanOption(rawOptions, "titleExact", ["title_exact"]) === true ? true : undefined,
|
|
94
|
+
phraseExact: readBooleanOption(rawOptions, "phraseExact", ["phrase_exact"]) === true ? true : undefined,
|
|
95
|
+
type: readStringOption(rawOptions, "type"),
|
|
96
|
+
tag: readStringOption(rawOptions, "tag"),
|
|
97
|
+
priority: readStringOption(rawOptions, "priority"),
|
|
98
|
+
deadlineBefore: readStringOption(rawOptions, "deadlineBefore", ["deadline_before"]),
|
|
99
|
+
deadlineAfter: readStringOption(rawOptions, "deadlineAfter", ["deadline_after"]),
|
|
100
|
+
limit: readStringOption(rawOptions, "limit"),
|
|
101
|
+
fields,
|
|
102
|
+
compact: compactRequested || defaultCompact ? true : undefined,
|
|
103
|
+
full: fullRequested ? true : undefined,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function normalizeReindexOptions(rawOptions) {
|
|
108
|
+
return {
|
|
109
|
+
mode: readStringOption(rawOptions, "mode"),
|
|
110
|
+
progress: readBooleanOption(rawOptions, "progress") === true ? true : undefined,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function runAdvancedSearchPackage(args, rawOptions, global) {
|
|
115
|
+
return runSearch(resolveSearchQuery(args), normalizeAdvancedSearchOptions(rawOptions), global);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export async function runAdvancedReindexPackage(rawOptions, global) {
|
|
119
|
+
return runReindex(normalizeReindexOptions(rawOptions), global);
|
|
120
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import type {
|
|
4
|
+
GlobalOptions,
|
|
5
|
+
ReindexOptions,
|
|
6
|
+
ReindexResult,
|
|
7
|
+
SearchOptions,
|
|
8
|
+
SearchResult,
|
|
9
|
+
} from "../../../../src/sdk/runtime.js";
|
|
10
|
+
|
|
11
|
+
const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
|
|
12
|
+
|
|
13
|
+
interface SearchRuntimeSdkModule {
|
|
14
|
+
EXIT_CODE: {
|
|
15
|
+
USAGE: number;
|
|
16
|
+
};
|
|
17
|
+
PmCliError: new (message: string, exitCode?: number) => Error;
|
|
18
|
+
runSearch: (query: string, options: SearchOptions, global: GlobalOptions) => Promise<SearchResult>;
|
|
19
|
+
runReindex: (options: ReindexOptions, global: GlobalOptions) => Promise<ReindexResult>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const sdk = await loadSearchSdkModule();
|
|
23
|
+
const {
|
|
24
|
+
EXIT_CODE,
|
|
25
|
+
PmCliError,
|
|
26
|
+
runSearch,
|
|
27
|
+
runReindex,
|
|
28
|
+
} = sdk;
|
|
29
|
+
|
|
30
|
+
async function loadSearchSdkModule(): Promise<SearchRuntimeSdkModule> {
|
|
31
|
+
const envRoot = process.env[PM_PACKAGE_ROOT_ENV];
|
|
32
|
+
if (typeof envRoot !== "string" || envRoot.trim().length === 0) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`builtin-search-advanced requires ${PM_PACKAGE_ROOT_ENV} to locate core SDK runtime exports.`,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
const modulePath = path.join(path.resolve(envRoot.trim()), "dist", "sdk", "runtime.js");
|
|
38
|
+
try {
|
|
39
|
+
const loaded = (await import(pathToFileURL(modulePath).href)) as Partial<SearchRuntimeSdkModule>;
|
|
40
|
+
if (
|
|
41
|
+
typeof loaded.runSearch === "function" &&
|
|
42
|
+
typeof loaded.runReindex === "function" &&
|
|
43
|
+
typeof loaded.PmCliError === "function" &&
|
|
44
|
+
typeof loaded.EXIT_CODE === "object" &&
|
|
45
|
+
loaded.EXIT_CODE !== null
|
|
46
|
+
) {
|
|
47
|
+
return loaded as SearchRuntimeSdkModule;
|
|
48
|
+
}
|
|
49
|
+
} catch {
|
|
50
|
+
// Fall through to deterministic failure message below.
|
|
51
|
+
}
|
|
52
|
+
throw new Error(
|
|
53
|
+
`builtin-search-advanced failed to load SDK runtime exports from ${modulePath}.`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function readStringOption(options: Record<string, unknown>, key: string, aliases: string[] = []): string | undefined {
|
|
58
|
+
const keys = [key, ...aliases];
|
|
59
|
+
for (const candidate of keys) {
|
|
60
|
+
const value = options[candidate];
|
|
61
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function readBooleanOption(options: Record<string, unknown>, key: string, aliases: string[] = []): boolean | undefined {
|
|
69
|
+
const keys = [key, ...aliases];
|
|
70
|
+
for (const candidate of keys) {
|
|
71
|
+
const value = options[candidate];
|
|
72
|
+
if (value === undefined) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (typeof value === "boolean") {
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
if (typeof value === "string") {
|
|
79
|
+
const normalized = value.trim().toLowerCase();
|
|
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
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function resolveSearchQuery(args: string[]): string {
|
|
92
|
+
const query = args
|
|
93
|
+
.map((value) => value.trim())
|
|
94
|
+
.filter((value) => value.length > 0)
|
|
95
|
+
.join(" ");
|
|
96
|
+
if (query.length === 0) {
|
|
97
|
+
throw new PmCliError("Search query must not be empty", EXIT_CODE.USAGE);
|
|
98
|
+
}
|
|
99
|
+
return query;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function normalizeAdvancedSearchOptions(rawOptions: Record<string, unknown>): SearchOptions {
|
|
103
|
+
const fields = readStringOption(rawOptions, "fields");
|
|
104
|
+
const compactRequested = readBooleanOption(rawOptions, "compact") === true;
|
|
105
|
+
const fullRequested = readBooleanOption(rawOptions, "full") === true;
|
|
106
|
+
const defaultCompact = !compactRequested && !fullRequested && fields === undefined;
|
|
107
|
+
return {
|
|
108
|
+
mode: readStringOption(rawOptions, "mode"),
|
|
109
|
+
includeLinked: readBooleanOption(rawOptions, "includeLinked", ["include_linked"]) === true ? true : undefined,
|
|
110
|
+
titleExact: readBooleanOption(rawOptions, "titleExact", ["title_exact"]) === true ? true : undefined,
|
|
111
|
+
phraseExact: readBooleanOption(rawOptions, "phraseExact", ["phrase_exact"]) === true ? true : undefined,
|
|
112
|
+
type: readStringOption(rawOptions, "type"),
|
|
113
|
+
tag: readStringOption(rawOptions, "tag"),
|
|
114
|
+
priority: readStringOption(rawOptions, "priority"),
|
|
115
|
+
deadlineBefore: readStringOption(rawOptions, "deadlineBefore", ["deadline_before"]),
|
|
116
|
+
deadlineAfter: readStringOption(rawOptions, "deadlineAfter", ["deadline_after"]),
|
|
117
|
+
limit: readStringOption(rawOptions, "limit"),
|
|
118
|
+
fields,
|
|
119
|
+
compact: compactRequested || defaultCompact ? true : undefined,
|
|
120
|
+
full: fullRequested ? true : undefined,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function normalizeReindexOptions(rawOptions: Record<string, unknown>): ReindexOptions {
|
|
125
|
+
return {
|
|
126
|
+
mode: readStringOption(rawOptions, "mode"),
|
|
127
|
+
progress: readBooleanOption(rawOptions, "progress") === true ? true : undefined,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export async function runAdvancedSearchPackage(
|
|
132
|
+
args: string[],
|
|
133
|
+
rawOptions: Record<string, unknown>,
|
|
134
|
+
global: GlobalOptions,
|
|
135
|
+
): Promise<SearchResult> {
|
|
136
|
+
return runSearch(resolveSearchQuery(args), normalizeAdvancedSearchOptions(rawOptions), global);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export async function runAdvancedReindexPackage(
|
|
140
|
+
rawOptions: Record<string, unknown>,
|
|
141
|
+
global: GlobalOptions,
|
|
142
|
+
): Promise<ReindexResult> {
|
|
143
|
+
return runReindex(normalizeReindexOptions(rawOptions), global);
|
|
144
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@unbrained/pm-package-search-advanced",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "First-party pm package for semantic, hybrid, and reindex search workflows.",
|
|
7
|
+
"homepage": "https://github.com/unbraind/pm-cli/tree/main/packages/pm-search-advanced#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/unbraind/pm-cli.git",
|
|
11
|
+
"directory": "packages/pm-search-advanced"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/unbraind/pm-cli/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"pm-package",
|
|
18
|
+
"project-management",
|
|
19
|
+
"search",
|
|
20
|
+
"reindex",
|
|
21
|
+
"semantic",
|
|
22
|
+
"hybrid"
|
|
23
|
+
],
|
|
24
|
+
"pm": {
|
|
25
|
+
"aliases": [
|
|
26
|
+
"search-advanced"
|
|
27
|
+
],
|
|
28
|
+
"extensions": [
|
|
29
|
+
"extensions/search-advanced"
|
|
30
|
+
],
|
|
31
|
+
"catalog": {
|
|
32
|
+
"display_name": "Advanced Search",
|
|
33
|
+
"category": "search",
|
|
34
|
+
"summary": "Enable semantic/hybrid search modes and reindex workflows.",
|
|
35
|
+
"tags": [
|
|
36
|
+
"search",
|
|
37
|
+
"semantic",
|
|
38
|
+
"hybrid",
|
|
39
|
+
"reindex"
|
|
40
|
+
],
|
|
41
|
+
"links": {
|
|
42
|
+
"docs": "https://github.com/unbraind/pm-cli/tree/main/packages/pm-search-advanced#readme",
|
|
43
|
+
"repository": "https://github.com/unbraind/pm-cli/tree/main/packages/pm-search-advanced",
|
|
44
|
+
"report": "https://github.com/unbraind/pm-cli/issues"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"docs": [
|
|
48
|
+
"README.md"
|
|
49
|
+
],
|
|
50
|
+
"examples": [
|
|
51
|
+
"README.md"
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# pm Templates Package
|
|
2
|
+
|
|
3
|
+
`@unbrained/pm-package-templates` provides reusable `pm create` templates as an installable pm package.
|
|
4
|
+
|
|
5
|
+
Install it with:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pm install templates
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Commands:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pm templates
|
|
15
|
+
pm templates list
|
|
16
|
+
pm templates save release-defaults --type Task --priority 1 --tags release
|
|
17
|
+
pm templates show release-defaults
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The package stores template documents in the active pm project root and uses only the public `@unbrained/pm-cli/sdk` runtime surface.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runTemplatesList as runTemplatesListPackage,
|
|
3
|
+
runTemplatesSave as runTemplatesSavePackage,
|
|
4
|
+
runTemplatesShow as runTemplatesShowPackage,
|
|
5
|
+
} from "./runtime.js";
|
|
6
|
+
|
|
7
|
+
export const manifest = {
|
|
8
|
+
name: "builtin-templates",
|
|
9
|
+
version: "0.1.0",
|
|
10
|
+
entry: "./index.js",
|
|
11
|
+
priority: 0,
|
|
12
|
+
capabilities: ["commands", "schema"],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function firstArg(args, commandName) {
|
|
16
|
+
const value = args[0];
|
|
17
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`${commandName} requires a template name argument.`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function runTemplatesListFromRuntime(global) {
|
|
24
|
+
return runTemplatesListPackage(global);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function runTemplatesSaveFromRuntime(args, options, global) {
|
|
28
|
+
return runTemplatesSavePackage(firstArg(args, "templates save"), options, global);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function runTemplatesShowFromRuntime(args, global) {
|
|
32
|
+
return runTemplatesShowPackage(firstArg(args, "templates show"), global);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const createOptionFlags = [
|
|
36
|
+
{ long: "--title", short: "-t", value_name: "value", value_type: "string", description: "Template default item title." },
|
|
37
|
+
{ long: "--description", short: "-d", value_name: "value", value_type: "string", description: "Template default item description." },
|
|
38
|
+
{ long: "--type", value_name: "value", value_type: "string", description: "Template default item type." },
|
|
39
|
+
{ long: "--status", short: "-s", value_name: "value", value_type: "string", description: "Template default item status." },
|
|
40
|
+
{ long: "--priority", short: "-p", value_name: "value", value_type: "string", description: "Template default priority 0..4." },
|
|
41
|
+
{ long: "--tags", value_name: "value", value_type: "string", description: "Template default comma-separated tags." },
|
|
42
|
+
{ long: "--body", short: "-b", value_name: "value", value_type: "string", description: "Template default item markdown body." },
|
|
43
|
+
{ long: "--deadline", value_name: "value", value_type: "string", description: "Template default deadline." },
|
|
44
|
+
{ long: "--estimate", value_name: "value", value_type: "string", description: "Template default estimated minutes." },
|
|
45
|
+
{ long: "--estimated-minutes", value_name: "value", value_type: "string", description: "Template default estimated minutes." },
|
|
46
|
+
{ long: "--acceptance-criteria", value_name: "value", value_type: "string", description: "Template default acceptance criteria." },
|
|
47
|
+
{ long: "--ac", value_name: "value", value_type: "string", description: "Alias for --acceptance-criteria." },
|
|
48
|
+
{ long: "--author", value_name: "value", value_type: "string", description: "Template default mutation author." },
|
|
49
|
+
{ long: "--message", value_name: "value", value_type: "string", description: "Template default history message." },
|
|
50
|
+
{ long: "--assignee", value_name: "value", value_type: "string", description: "Template default assignee." },
|
|
51
|
+
{ long: "--parent", value_name: "value", value_type: "string", description: "Template default parent item ID." },
|
|
52
|
+
{ long: "--reviewer", value_name: "value", value_type: "string", description: "Template default reviewer." },
|
|
53
|
+
{ long: "--risk", value_name: "value", value_type: "string", description: "Template default risk level." },
|
|
54
|
+
{ long: "--confidence", value_name: "value", value_type: "string", description: "Template default confidence." },
|
|
55
|
+
{ long: "--sprint", value_name: "value", value_type: "string", description: "Template default sprint identifier." },
|
|
56
|
+
{ long: "--release", value_name: "value", value_type: "string", description: "Template default release identifier." },
|
|
57
|
+
{ long: "--dep", value_name: "value", value_type: "string", description: "Template default dependency seed.", repeatable: true },
|
|
58
|
+
{ long: "--comment", value_name: "value", value_type: "string", description: "Template default comment seed.", repeatable: true },
|
|
59
|
+
{ long: "--note", value_name: "value", value_type: "string", description: "Template default note seed.", repeatable: true },
|
|
60
|
+
{ long: "--learning", value_name: "value", value_type: "string", description: "Template default learning seed.", repeatable: true },
|
|
61
|
+
{ long: "--file", value_name: "value", value_type: "string", description: "Template default linked file seed.", repeatable: true },
|
|
62
|
+
{ long: "--test", value_name: "value", value_type: "string", description: "Template default linked test seed.", repeatable: true },
|
|
63
|
+
{ long: "--doc", value_name: "value", value_type: "string", description: "Template default linked doc seed.", repeatable: true },
|
|
64
|
+
{ long: "--reminder", value_name: "value", value_type: "string", description: "Template default reminder seed.", repeatable: true },
|
|
65
|
+
{ long: "--event", value_name: "value", value_type: "string", description: "Template default event seed.", repeatable: true },
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
export function activate(api) {
|
|
69
|
+
api.registerCommand({
|
|
70
|
+
name: "templates",
|
|
71
|
+
action: "templates-list",
|
|
72
|
+
description: "List saved create templates.",
|
|
73
|
+
run: async (context) => runTemplatesListFromRuntime(context.global),
|
|
74
|
+
});
|
|
75
|
+
api.registerCommand({
|
|
76
|
+
name: "templates list",
|
|
77
|
+
action: "templates-list",
|
|
78
|
+
description: "List saved create templates.",
|
|
79
|
+
run: async (context) => runTemplatesListFromRuntime(context.global),
|
|
80
|
+
});
|
|
81
|
+
api.registerCommand({
|
|
82
|
+
name: "templates save",
|
|
83
|
+
action: "templates-save",
|
|
84
|
+
description: "Save reusable create template defaults.",
|
|
85
|
+
arguments: [{ name: "name", required: true, description: "Template name." }],
|
|
86
|
+
flags: [...createOptionFlags],
|
|
87
|
+
run: async (context) => runTemplatesSaveFromRuntime(context.args, context.options, context.global),
|
|
88
|
+
});
|
|
89
|
+
api.registerCommand({
|
|
90
|
+
name: "templates show",
|
|
91
|
+
action: "templates-show",
|
|
92
|
+
description: "Show a saved create template.",
|
|
93
|
+
arguments: [{ name: "name", required: true, description: "Template name." }],
|
|
94
|
+
run: async (context) => runTemplatesShowFromRuntime(context.args, context.global),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default {
|
|
99
|
+
manifest,
|
|
100
|
+
activate,
|
|
101
|
+
};
|