@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
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
import { PM_PI_TOOL_PARAMETERS_SCHEMA, PM_TOOL_ACTIONS } from "../../../dist/sdk/cli-contracts.js";
|
|
2
|
-
import { runNativePmAction } from "../../../dist/pi/native.js";
|
|
3
|
-
|
|
4
|
-
const PM_PI_TOOL_PARAMETERS_SCHEMA_COMPAT = {
|
|
5
|
-
...PM_PI_TOOL_PARAMETERS_SCHEMA,
|
|
6
|
-
additionalProperties: true,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
function contentText(result) {
|
|
10
|
-
if (typeof result === "string") return result;
|
|
11
|
-
return JSON.stringify(result, null, 2);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function firstText(result) {
|
|
15
|
-
const entry = Array.isArray(result?.content) ? result.content.find((part) => part?.type === "text") : undefined;
|
|
16
|
-
return typeof entry?.text === "string" ? entry.text : "";
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function truncatePlain(value, width) {
|
|
20
|
-
const text = String(value ?? "");
|
|
21
|
-
let visible = 0;
|
|
22
|
-
let output = "";
|
|
23
|
-
for (let index = 0; index < text.length; index += 1) {
|
|
24
|
-
const char = text[index];
|
|
25
|
-
if (char === "\u001b") {
|
|
26
|
-
const match = text.slice(index).match(/^\u001b\[[0-9;?]*[ -/]*[@-~]/);
|
|
27
|
-
if (match) {
|
|
28
|
-
output += match[0];
|
|
29
|
-
index += match[0].length - 1;
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (visible >= Math.max(0, width - 1)) return `${output}…`;
|
|
34
|
-
output += char;
|
|
35
|
-
visible += 1;
|
|
36
|
-
}
|
|
37
|
-
return output;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function statusIcon(status, theme) {
|
|
41
|
-
const normalized = String(status ?? "").toLowerCase();
|
|
42
|
-
if (normalized === "closed") return theme.fg("success", "✓");
|
|
43
|
-
if (normalized === "blocked") return theme.fg("warning", "!");
|
|
44
|
-
if (normalized === "in_progress") return theme.fg("accent", "▶");
|
|
45
|
-
if (normalized === "canceled") return theme.fg("dim", "×");
|
|
46
|
-
return theme.fg("dim", "○");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
class PmPanelComponent {
|
|
50
|
-
constructor(title, lines, theme, onClose) {
|
|
51
|
-
this.title = title;
|
|
52
|
-
this.lines = lines;
|
|
53
|
-
this.theme = theme;
|
|
54
|
-
this.onClose = onClose;
|
|
55
|
-
this.cachedWidth = undefined;
|
|
56
|
-
this.cachedLines = undefined;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
handleInput(data) {
|
|
60
|
-
if (data === "\u001b" || data === "\u0003" || data === "q" || data === "Q") {
|
|
61
|
-
this.onClose?.();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
render(width) {
|
|
66
|
-
if (this.cachedLines && this.cachedWidth === width) return this.cachedLines;
|
|
67
|
-
const theme = this.theme;
|
|
68
|
-
const usable = Math.max(20, width);
|
|
69
|
-
const border = theme.fg("borderMuted", "─".repeat(Math.max(0, usable)));
|
|
70
|
-
const rendered = [
|
|
71
|
-
border,
|
|
72
|
-
truncatePlain(`${theme.fg("accent", theme.bold(` pm ${this.title} `))}${theme.fg("dim", "q/esc closes")}`, usable),
|
|
73
|
-
border,
|
|
74
|
-
...this.lines.map((line) => truncatePlain(line, usable)),
|
|
75
|
-
border,
|
|
76
|
-
];
|
|
77
|
-
this.cachedWidth = width;
|
|
78
|
-
this.cachedLines = rendered;
|
|
79
|
-
return rendered;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
invalidate() {
|
|
83
|
-
this.cachedWidth = undefined;
|
|
84
|
-
this.cachedLines = undefined;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function makeItemLine(item, theme) {
|
|
89
|
-
const id = theme.fg("accent", item.id ?? "unknown");
|
|
90
|
-
const type = theme.fg("muted", item.type ?? "Item");
|
|
91
|
-
const status = statusIcon(item.status, theme);
|
|
92
|
-
const priority = item.priority === undefined ? "" : theme.fg("dim", ` p${item.priority}`);
|
|
93
|
-
const owner = item.assignee ? theme.fg("dim", ` @${item.assignee}`) : "";
|
|
94
|
-
return `${status} ${id} ${type}${priority}${owner} ${item.title ?? "(untitled)"}`;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function contextLines(result, theme) {
|
|
98
|
-
const lines = [];
|
|
99
|
-
const summary = result?.summary;
|
|
100
|
-
if (summary) {
|
|
101
|
-
lines.push(
|
|
102
|
-
`${theme.fg("muted", "summary")} active=${summary.active_items ?? 0} open=${summary.open ?? 0} in_progress=${summary.in_progress ?? 0} blocked=${summary.blocked ?? 0}`,
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
const high = Array.isArray(result?.high_level) ? result.high_level : [];
|
|
106
|
-
const low = Array.isArray(result?.low_level) ? result.low_level : [];
|
|
107
|
-
if (high.length > 0) {
|
|
108
|
-
lines.push("", theme.fg("accent", "High level"));
|
|
109
|
-
lines.push(...high.map((item) => makeItemLine(item, theme)));
|
|
110
|
-
}
|
|
111
|
-
if (low.length > 0) {
|
|
112
|
-
lines.push("", theme.fg("accent", "Tasks"));
|
|
113
|
-
lines.push(...low.map((item) => makeItemLine(item, theme)));
|
|
114
|
-
}
|
|
115
|
-
if (lines.length === 0) lines.push(theme.fg("dim", "No pm context items found."));
|
|
116
|
-
return lines;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function listLines(result, theme) {
|
|
120
|
-
const items = Array.isArray(result?.items) ? result.items : Array.isArray(result) ? result : [];
|
|
121
|
-
if (items.length === 0) return [theme.fg("dim", "No items.")];
|
|
122
|
-
return items.map((entry) => makeItemLine(entry.item ?? entry, theme));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function historyLines(result, theme) {
|
|
126
|
-
const entries = Array.isArray(result?.history) ? result.history : Array.isArray(result?.entries) ? result.entries : [];
|
|
127
|
-
if (entries.length === 0) return [theme.fg("dim", "No history entries.")];
|
|
128
|
-
return entries.slice(0, 30).map((entry) => {
|
|
129
|
-
const at = entry.timestamp ?? entry.created_at ?? "";
|
|
130
|
-
const op = entry.op ?? entry.operation ?? entry.type ?? "history";
|
|
131
|
-
const author = entry.author ? ` ${theme.fg("dim", `@${entry.author}`)}` : "";
|
|
132
|
-
const message = entry.message ?? entry.text ?? entry.reason ?? "";
|
|
133
|
-
return `${theme.fg("muted", at)} ${theme.fg("accent", op)}${author} ${message}`;
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function getItemLines(result, theme) {
|
|
138
|
-
const item = result?.item ?? result;
|
|
139
|
-
if (!item || typeof item !== "object") return [theme.fg("dim", "No item details.")];
|
|
140
|
-
const lines = [makeItemLine(item, theme)];
|
|
141
|
-
if (item.description) lines.push("", item.description);
|
|
142
|
-
if (item.acceptance_criteria) lines.push("", `${theme.fg("accent", "Acceptance")}: ${item.acceptance_criteria}`);
|
|
143
|
-
if (Array.isArray(item.comments) && item.comments.length > 0) {
|
|
144
|
-
lines.push("", theme.fg("accent", "Recent comments"));
|
|
145
|
-
for (const comment of item.comments.slice(-5)) {
|
|
146
|
-
lines.push(`${theme.fg("muted", comment.created_at ?? "")} ${comment.author ?? "unknown"}: ${comment.text ?? ""}`);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return lines;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function resultLines(details, theme) {
|
|
153
|
-
const action = details?.action;
|
|
154
|
-
const result = details?.result;
|
|
155
|
-
if (action === "context") return contextLines(result, theme);
|
|
156
|
-
if (String(action ?? "").startsWith("list") || action === "search") return listLines(result, theme);
|
|
157
|
-
if (action === "history" || action === "activity") return historyLines(result, theme);
|
|
158
|
-
if (action === "get") return getItemLines(result, theme);
|
|
159
|
-
const raw = contentText(result);
|
|
160
|
-
return raw.split("\n").slice(0, 40);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function errorDetails(error) {
|
|
164
|
-
return {
|
|
165
|
-
message: error instanceof Error ? error.message : String(error),
|
|
166
|
-
code: typeof error?.exitCode === "number" ? error.exitCode : 1,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function uiTheme(ctx) {
|
|
171
|
-
return ctx.ui?.theme ?? {
|
|
172
|
-
fg: (_name, text) => String(text),
|
|
173
|
-
bold: (text) => String(text),
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
async function showPanel(ctx, title, lines, overlay = true) {
|
|
178
|
-
if (!ctx.hasUI || typeof ctx.ui?.custom !== "function") {
|
|
179
|
-
ctx.ui.notify(lines.join("\n"), "info");
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
await ctx.ui.custom((_tui, theme, _keybindings, done) => new PmPanelComponent(title, lines, theme, () => done(undefined)), {
|
|
183
|
-
overlay,
|
|
184
|
-
overlayOptions: { anchor: "right-center", width: "70%", minWidth: 60, maxHeight: "85%", margin: 1 },
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async function runForCommand(ctx, params) {
|
|
189
|
-
return runNativePmAction({ cwd: ctx.cwd, ...params });
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export function createPmToolDefinition() {
|
|
193
|
-
return {
|
|
194
|
-
name: "pm",
|
|
195
|
-
label: "pm",
|
|
196
|
-
description:
|
|
197
|
-
"Use pm natively from Pi without shelling out to the pm CLI. Supports pm project context, search, lifecycle mutations, links, tests, validation, extension management, templates, calendar, guide, audit, beads, todos, and managed test-run workflows.",
|
|
198
|
-
promptSnippet: "Run native pm project-management operations without bash or the pm CLI.",
|
|
199
|
-
promptGuidelines: [
|
|
200
|
-
"Use the pm tool instead of bash pm commands for project-management operations when this tool is available.",
|
|
201
|
-
"Use pm action=context/list-open/list-in-progress/search before creating new work items.",
|
|
202
|
-
"For mutations, set author explicitly and link changed files/tests/docs through pm actions before closing work.",
|
|
203
|
-
"Use pm action=contracts or guide when you need exact action/flag support instead of guessing parameters.",
|
|
204
|
-
],
|
|
205
|
-
parameters: PM_PI_TOOL_PARAMETERS_SCHEMA_COMPAT,
|
|
206
|
-
async execute(_toolCallId, params, _signal, onUpdate, ctx) {
|
|
207
|
-
onUpdate?.({ content: [{ type: "text", text: `Running native pm action: ${params.action}` }] });
|
|
208
|
-
try {
|
|
209
|
-
const result = await runNativePmAction({ cwd: ctx?.cwd, ...params });
|
|
210
|
-
return {
|
|
211
|
-
content: [{ type: "text", text: contentText(result) }],
|
|
212
|
-
details: { ok: true, action: params.action, result, native: true },
|
|
213
|
-
};
|
|
214
|
-
} catch (error) {
|
|
215
|
-
const details = errorDetails(error);
|
|
216
|
-
throw new Error(`pm ${params.action ?? "action"} failed: ${details.message}`);
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
renderCall(args, theme) {
|
|
220
|
-
const action = args?.action ?? "action";
|
|
221
|
-
const target = args?.id ?? args?.query ?? args?.target ?? args?.title ?? "";
|
|
222
|
-
return new PmPanelComponent("tool", [`${theme.fg("toolTitle", theme.bold("pm"))} ${theme.fg("accent", action)} ${theme.fg("dim", target)}`], theme);
|
|
223
|
-
},
|
|
224
|
-
renderResult(result, { expanded, isPartial }, theme) {
|
|
225
|
-
if (isPartial) return new PmPanelComponent("running", [theme.fg("warning", "Running…")], theme);
|
|
226
|
-
const details = result?.details;
|
|
227
|
-
if (!details?.ok) return new PmPanelComponent("result", [firstText(result) || contentText(result)], theme);
|
|
228
|
-
const lines = resultLines(details, theme);
|
|
229
|
-
const visible = expanded ? lines : lines.slice(0, 12);
|
|
230
|
-
if (!expanded && lines.length > visible.length) visible.push(theme.fg("dim", `… ${lines.length - visible.length} more; expand tool output for details`));
|
|
231
|
-
return new PmPanelComponent(String(details.action ?? "result"), visible, theme);
|
|
232
|
-
},
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
export function registerPmCommands(pi) {
|
|
237
|
-
pi.registerCommand("pm-context", {
|
|
238
|
-
description: "Show pm context snapshot using the native pm integration",
|
|
239
|
-
handler: async (args, ctx) => {
|
|
240
|
-
const limit = args?.trim() || "10";
|
|
241
|
-
const result = await runForCommand(ctx, { action: "context", limit, json: true });
|
|
242
|
-
await showPanel(ctx, "context", contextLines(result, uiTheme(ctx)));
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
pi.registerCommand("pm-board", {
|
|
247
|
-
description: "Open an interactive pm dashboard panel: /pm-board [limit]",
|
|
248
|
-
handler: async (args, ctx) => {
|
|
249
|
-
const limit = args?.trim() || "12";
|
|
250
|
-
const result = await runForCommand(ctx, { action: "context", limit, depth: "standard", json: true });
|
|
251
|
-
await showPanel(ctx, "board", contextLines(result, uiTheme(ctx)));
|
|
252
|
-
},
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
pi.registerCommand("pm-item", {
|
|
256
|
-
description: "Open pm item details: /pm-item <id>",
|
|
257
|
-
getArgumentCompletions: () => null,
|
|
258
|
-
handler: async (args, ctx) => {
|
|
259
|
-
const id = args?.trim();
|
|
260
|
-
if (!id) return ctx.ui.notify("Usage: /pm-item <id>", "error");
|
|
261
|
-
const result = await runForCommand(ctx, { action: "get", id, json: true });
|
|
262
|
-
await showPanel(ctx, id, getItemLines(result, uiTheme(ctx)));
|
|
263
|
-
},
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
pi.registerCommand("pm-history", {
|
|
267
|
-
description: "Open pm item history/activity panel: /pm-history <id>",
|
|
268
|
-
handler: async (args, ctx) => {
|
|
269
|
-
const id = args?.trim();
|
|
270
|
-
if (!id) return ctx.ui.notify("Usage: /pm-history <id>", "error");
|
|
271
|
-
const result = await runForCommand(ctx, { action: "history", id, limit: 30, json: true });
|
|
272
|
-
await showPanel(ctx, `${id} history`, historyLines(result, uiTheme(ctx)));
|
|
273
|
-
},
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
pi.registerCommand("pm-start", {
|
|
277
|
-
description: "Start/claim a pm item: /pm-start <id>",
|
|
278
|
-
handler: async (args, ctx) => {
|
|
279
|
-
const id = args?.trim();
|
|
280
|
-
if (!id) return ctx.ui.notify("Usage: /pm-start <id>", "error");
|
|
281
|
-
const result = await runForCommand(ctx, { action: "start-task", id, author: "pi-agent" });
|
|
282
|
-
ctx.ui.notify(contentText(result), "success");
|
|
283
|
-
},
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
pi.registerCommand("pm-close", {
|
|
287
|
-
description: "Close and release a pm item: /pm-close <id> <reason>",
|
|
288
|
-
handler: async (args, ctx) => {
|
|
289
|
-
const [id, ...reasonParts] = (args ?? "").trim().split(/\s+/);
|
|
290
|
-
const reason = reasonParts.join(" ");
|
|
291
|
-
if (!id || !reason) return ctx.ui.notify("Usage: /pm-close <id> <reason>", "error");
|
|
292
|
-
const result = await runForCommand(ctx, { action: "close-task", id, text: reason, author: "pi-agent", validateClose: "warn" });
|
|
293
|
-
ctx.ui.notify(contentText(result), "success");
|
|
294
|
-
},
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
pi.registerCommand("pm-actions", {
|
|
298
|
-
description: "List native pm tool actions",
|
|
299
|
-
handler: async (_args, ctx) => {
|
|
300
|
-
await showPanel(ctx, "actions", PM_TOOL_ACTIONS.map((action) => `• ${action}`));
|
|
301
|
-
},
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
pi.registerCommand("pm-workflows", {
|
|
305
|
-
description: "Show native pm workflow shortcuts and bundled Pi resources",
|
|
306
|
-
handler: async (_args, ctx) => {
|
|
307
|
-
await showPanel(ctx, "workflows", [
|
|
308
|
-
"1. /pm-board to inspect focus/context items.",
|
|
309
|
-
"2. Use the pm tool action=search/list-open/list-in-progress before creating work.",
|
|
310
|
-
"3. /pm-start <id> or pm action=start-task to claim and move in_progress.",
|
|
311
|
-
"4. Use pm action=files/docs/test to link implementation evidence.",
|
|
312
|
-
"5. Run pm action=test/validate and close with pm action=close-task.",
|
|
313
|
-
"Bundled resources: pm-native and pm-release skills, pm-workflow prompt, pm subagent templates in .pi/agents.",
|
|
314
|
-
]);
|
|
315
|
-
},
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
function patchPmToolParametersInProviderPayload(payload) {
|
|
320
|
-
if (!payload || typeof payload !== "object" || !Array.isArray(payload.tools)) {
|
|
321
|
-
return undefined;
|
|
322
|
-
}
|
|
323
|
-
let changed = false;
|
|
324
|
-
const tools = payload.tools.map((tool) => {
|
|
325
|
-
if (!tool || typeof tool !== "object") {
|
|
326
|
-
return tool;
|
|
327
|
-
}
|
|
328
|
-
if (tool.name === "pm") {
|
|
329
|
-
const parameters = tool.parameters;
|
|
330
|
-
if (!parameters || parameters.type !== "object") {
|
|
331
|
-
changed = true;
|
|
332
|
-
return { ...tool, parameters: PM_PI_TOOL_PARAMETERS_SCHEMA_COMPAT };
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
if (tool.function?.name === "pm") {
|
|
336
|
-
const parameters = tool.function.parameters;
|
|
337
|
-
if (!parameters || parameters.type !== "object") {
|
|
338
|
-
changed = true;
|
|
339
|
-
return { ...tool, function: { ...tool.function, parameters: PM_PI_TOOL_PARAMETERS_SCHEMA_COMPAT } };
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
return tool;
|
|
343
|
-
});
|
|
344
|
-
return changed ? { ...payload, tools } : undefined;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
function installPmAutocomplete(ctx) {
|
|
348
|
-
if (typeof ctx.ui?.addAutocompleteProvider !== "function") return;
|
|
349
|
-
ctx.ui.addAutocompleteProvider((current) => ({
|
|
350
|
-
async getSuggestions(lines, line, col, options) {
|
|
351
|
-
const beforeCursor = (lines[line] ?? "").slice(0, col);
|
|
352
|
-
const match = beforeCursor.match(/(?:^|[\s(])@(pm-[a-z0-9-]*)$/i);
|
|
353
|
-
if (!match) return current.getSuggestions(lines, line, col, options);
|
|
354
|
-
try {
|
|
355
|
-
const result = await runNativePmAction({ cwd: ctx.cwd, action: "list-open", limit: 20, json: true });
|
|
356
|
-
const items = Array.isArray(result?.items) ? result.items : [];
|
|
357
|
-
return {
|
|
358
|
-
prefix: `@${match[1] ?? ""}`,
|
|
359
|
-
items: items.map((item) => ({ value: `@${item.id}`, label: item.id, description: item.title ?? item.status ?? "pm item" })),
|
|
360
|
-
};
|
|
361
|
-
} catch {
|
|
362
|
-
return current.getSuggestions(lines, line, col, options);
|
|
363
|
-
}
|
|
364
|
-
},
|
|
365
|
-
applyCompletion(lines, line, col, item, prefix) {
|
|
366
|
-
return current.applyCompletion(lines, line, col, item, prefix);
|
|
367
|
-
},
|
|
368
|
-
shouldTriggerFileCompletion(lines, line, col) {
|
|
369
|
-
return current.shouldTriggerFileCompletion?.(lines, line, col) ?? true;
|
|
370
|
-
},
|
|
371
|
-
}));
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
export default function pmCliPiExtension(pi) {
|
|
375
|
-
pi.registerTool(createPmToolDefinition());
|
|
376
|
-
pi.on("before_provider_request", (event) => patchPmToolParametersInProviderPayload(event.payload));
|
|
377
|
-
registerPmCommands(pi);
|
|
378
|
-
pi.on("session_start", async (_event, ctx) => {
|
|
379
|
-
ctx.ui.setStatus?.("pm", ctx.ui.theme?.fg ? ctx.ui.theme.fg("accent", "pm native") : "pm native");
|
|
380
|
-
ctx.ui.setWidget?.("pm-native", ["pm native ready • /pm-board • /pm-actions • @pm-id autocomplete"], { placement: "belowEditor" });
|
|
381
|
-
installPmAutocomplete(ctx);
|
|
382
|
-
});
|
|
383
|
-
pi.on("session_shutdown", async (_event, ctx) => {
|
|
384
|
-
ctx.ui.setStatus?.("pm", undefined);
|
|
385
|
-
ctx.ui.setWidget?.("pm-native", undefined);
|
|
386
|
-
});
|
|
387
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Start a pm-tracked implementation workflow using the native pm Pi tool.
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Use the native `pm` tool to orient, find an existing relevant item, claim it, link evidence, verify, and close/release only after acceptance criteria are met. Do not run `pm` via bash when the native tool is available.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pm-native
|
|
3
|
-
description: Native pm integration for Pi. Use when planning, claiming, updating, linking files/tests/docs, validating, or closing pm CLI work through the Pi pm tool instead of shelling out to the pm CLI.
|
|
4
|
-
license: MIT
|
|
5
|
-
compatibility: Pi coding-agent with the @unbrained/pm-cli Pi package installed.
|
|
6
|
-
metadata:
|
|
7
|
-
owner: unbrained
|
|
8
|
-
domain: pm-cli
|
|
9
|
-
scope: pi-native
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# pm Native for Pi
|
|
13
|
-
|
|
14
|
-
Use the `pm` tool for project-management operations. Do not run `pm ...` through bash when the native tool is available. In interactive Pi, use `/pm-board`, `/pm-item <id>`, `/pm-history <id>`, `/pm-actions`, and `/pm-workflows` when the user would benefit from seeing tracker state in the TUI.
|
|
15
|
-
|
|
16
|
-
## Required Loop
|
|
17
|
-
|
|
18
|
-
1. Orient before creating work:
|
|
19
|
-
- `pm` action `context` with `limit: 10`
|
|
20
|
-
- `pm` action `search` with relevant keywords
|
|
21
|
-
- `pm` action `list-open` and `list-in-progress`
|
|
22
|
-
2. Claim work with action `claim` or `start-task`.
|
|
23
|
-
3. Mutate with explicit `author`.
|
|
24
|
-
4. Link evidence:
|
|
25
|
-
- action `files` with `add`
|
|
26
|
-
- action `docs` with `add`
|
|
27
|
-
- action `test` with sandbox-safe commands
|
|
28
|
-
5. Verify with action `test`, `validate`, and project test commands when appropriate.
|
|
29
|
-
6. Close with action `close-task` or `close`, then release if needed.
|
|
30
|
-
7. For exact feature support, call `pm` action `contracts` or `guide` instead of guessing flags.
|
|
31
|
-
|
|
32
|
-
## Common Tool Calls
|
|
33
|
-
|
|
34
|
-
- Context: `{ "action": "context", "limit": 10 }`
|
|
35
|
-
- Search: `{ "action": "search", "query": "pi native extension", "limit": 10 }`
|
|
36
|
-
- Claim: `{ "action": "claim", "id": "pm-1234", "author": "pi-agent" }`
|
|
37
|
-
- Link file: `{ "action": "files", "id": "pm-1234", "add": ["path=src/file.ts,scope=project,note=implementation"], "author": "pi-agent" }`
|
|
38
|
-
- Add comment: `{ "action": "comments", "id": "pm-1234", "add": ["Evidence: build and tests passed"], "author": "pi-agent" }`
|
|
39
|
-
- Close: `{ "action": "close-task", "id": "pm-1234", "text": "All acceptance criteria met", "author": "pi-agent", "validateClose": "warn" }`
|
|
40
|
-
- Extension lifecycle: `{ "action": "extension", "install": true, "target": "todos", "scope": "project" }`
|
|
41
|
-
- Templates: `{ "action": "templates-list" }`
|
|
42
|
-
- Managed tests: `{ "action": "test-runs-list" }`
|
|
43
|
-
|
|
44
|
-
Use `pm guide` topics through action `guide` for deeper command docs. The bundled Pi package also provides project subagent definitions (`pm-triage-agent`, `pm-verification-agent`) and a `pm-native-delivery` chain for installations that use pi-subagents.
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pm-release
|
|
3
|
-
description: Release-readiness workflow for pm projects in Pi. Use when running final validation, coverage, package checks, GitHub checks, and closure evidence through the native pm integration.
|
|
4
|
-
license: MIT
|
|
5
|
-
compatibility: Pi coding-agent with the @unbrained/pm-cli Pi package installed.
|
|
6
|
-
metadata:
|
|
7
|
-
owner: unbrained
|
|
8
|
-
domain: pm-cli
|
|
9
|
-
scope: release
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# pm Release Workflow for Pi
|
|
13
|
-
|
|
14
|
-
Use the native `pm` tool for tracker state and linked evidence. Use shell only for non-pm project build/test commands.
|
|
15
|
-
|
|
16
|
-
## Release Checklist
|
|
17
|
-
|
|
18
|
-
1. `pm` action `context` with `depth: "standard"`.
|
|
19
|
-
2. Run linked tests with `pm` action `test` and `run: true` for active work items.
|
|
20
|
-
3. Run validation with `pm` action `validate`, usually `checkResolution: true`, `checkHistoryDrift: true`, and relevant file checks.
|
|
21
|
-
4. Run package install/discovery smoke for Pi packages:
|
|
22
|
-
- local: `pi install -l .` or `pi -e .`
|
|
23
|
-
- npm after publish: `pi install npm:@unbrained/pm-cli`
|
|
24
|
-
5. Use `gh` only to inspect GitHub checks after pushing.
|
|
25
|
-
6. Add a `comments` evidence entry with exact command summaries.
|
|
26
|
-
7. Close/release the pm item with `close-task` once acceptance criteria are met.
|
|
27
|
-
|
|
28
|
-
## Evidence Format
|
|
29
|
-
|
|
30
|
-
Record:
|
|
31
|
-
- Changed package resources (`pi.extensions`, `pi.skills`, `pi.prompts`)
|
|
32
|
-
- Native pm tool smoke result
|
|
33
|
-
- Build/test/coverage result
|
|
34
|
-
- Pi install smoke result
|
|
35
|
-
- GitHub checks status
|
package/dist/pi/native.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { GlobalOptions } from "../core/shared/command-types.js";
|
|
2
|
-
export type NativePmArgs = Record<string, unknown>;
|
|
3
|
-
export declare function nativeGlobalOptions(args: NativePmArgs): GlobalOptions;
|
|
4
|
-
export declare function nativeCommandOptions(args: NativePmArgs): Record<string, unknown>;
|
|
5
|
-
export declare function runNativePmAction(args: NativePmArgs): Promise<unknown>;
|