Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions .agents/pm/features/pm-rnpb.toon

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions .agents/pm/history/pm-rnpb.jsonl

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ pm init --defaults --with-packages
pm init --agent-guidance status
pm init --agent-guidance add
pm config project list
pm health --check-only
pm health --check-only --summary --json
```

`pm init` creates `.agents/pm`. `pm health --check-only` inspects without refreshing optional search artifacts.
`pm init` creates `.agents/pm`. `pm health --check-only --summary --json` gives the smallest machine-readable health gate without refreshing optional search artifacts.
`pm init --agent-guidance ask` is the default behavior: prompt in TTY only when AGENTS/CLAUDE guidance is missing and no decline is recorded.
Use `--agent-guidance add` to write guidance, `--agent-guidance skip` to persist a decline without writing, and `--agent-guidance status` to inspect guidance state.
Use `--with-packages` for one-step agent setup when bundled package commands should be active immediately.
Expand Down
2 changes: 1 addition & 1 deletion docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Use standalone checks when validating a repository:
```bash
pm validate --check-resolution --check-history-drift
pm validate --check-files --scan-mode tracked-all
pm health --check-only
pm health --check-only --summary --json
```

## Search Configuration
Expand Down
16 changes: 16 additions & 0 deletions src/cli/commands/completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ export function generateBashScript(
" history)",
` COMPREPLY=(${compgen("--limit --compact --full --diff --verify --json --quiet --path --no-extensions --no-pager --profile --help")})`,
" ;;",
" get)",
` COMPREPLY=(${compgen("--depth --full --fields --json --quiet --path --no-extensions --no-pager --profile --help")})`,
" ;;",
" history-redact)",
` COMPREPLY=(${compgen("--literal --regex --replacement --dry-run --author --message --force --json --quiet --path --no-extensions --no-pager --profile --help")})`,
" ;;",
Expand Down Expand Up @@ -725,6 +728,14 @@ _pm() {
'--json[Output JSON]' \\
'--quiet[Suppress stdout]'
;;
get)
_arguments \\
'--depth[Detail depth]:(brief standard deep)' \\
'--full[Explicit full item read]' \\
'--fields[Render custom comma-separated item fields]:fields' \\
'--json[Output JSON]' \\
'--quiet[Suppress stdout]'
;;
history-redact)
_arguments \\
'--literal[Literal string matcher to redact from history/item payloads]:literal' \\
Expand Down Expand Up @@ -1468,6 +1479,11 @@ complete -c pm -n '__fish_seen_subcommand_from guide' -a '${guideTopicChoices}'
complete -c pm -n '__fish_seen_subcommand_from reindex' -l mode -d 'Reindex mode' -r -a 'keyword semantic hybrid'
complete -c pm -n '__fish_seen_subcommand_from reindex' -l progress -d 'Emit progress updates to stderr'

# get flags
complete -c pm -n '__fish_seen_subcommand_from get' -l depth -d 'Detail depth' -r -a 'brief standard deep'
complete -c pm -n '__fish_seen_subcommand_from get' -l full -d 'Explicit full item read'
complete -c pm -n '__fish_seen_subcommand_from get' -l fields -d 'Render custom comma-separated item fields' -r

# history / activity flags
complete -c pm -n '__fish_seen_subcommand_from history' -l limit -d 'Max history entries' -r
complete -c pm -n '__fish_seen_subcommand_from history' -l compact -d 'Condensed history projection'
Expand Down
6 changes: 5 additions & 1 deletion src/cli/commands/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type GetDepth = (typeof GET_DEPTH_VALUES)[number];
export interface GetOptions {
depth?: string;
fields?: string;
full?: boolean;
}

function toClaimHistoryContext(
Expand Down Expand Up @@ -175,7 +176,10 @@ function fieldsIncludeRoot(fields: string[], name: string): boolean {
}

export async function runGet(id: string, global: GlobalOptions, options: GetOptions = {}): Promise<GetResult> {
const depth = parseGetDepth(options.depth);
if (options.full && (options.fields !== undefined || options.depth !== undefined)) {
throw new PmCliError("Get projection options are mutually exclusive; remove the extra projection flag and retry.", EXIT_CODE.USAGE);
}
const depth = options.full ? "deep" : parseGetDepth(options.depth);
const fields = parseGetFields(options.fields);
const pmRoot = resolvePmRoot(process.cwd(), global.path);
if (!(await pathExists(getSettingsPath(pmRoot)))) {
Expand Down
2 changes: 1 addition & 1 deletion src/cli/commands/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ export async function runHistory(id: string, options: HistoryCommandOptions, glo
};

if (options.diff) {
result.diff = compactHistory ?? buildDiffEntries(history, Math.max(0, fullHistory.length - history.length));
result.diff = compact ? [] : buildDiffEntries(history, Math.max(0, fullHistory.length - history.length));
}

if (options.verify) {
Expand Down
2 changes: 1 addition & 1 deletion src/cli/help-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,8 @@ const HELP_BY_COMMAND_PATH: Record<string, HelpBundle> = {
why: "Validates tracker/runtime health including extension triage, migration, and integrity diagnostics.",
examples: [
"pm health",
"pm health --check-only --summary --json",
"pm health --brief --json",
"pm health --check-only --brief --json",
"pm health --no-refresh",
"pm health --refresh-vectors",
],
Expand Down
2 changes: 2 additions & 0 deletions src/cli/register-list-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ export function registerListQueryCommands(program: Command): void {
.command("get")
.argument("<id>", "Item id")
.option("--depth <value>", "Detail depth: brief|standard|deep (default: deep)")
.option("--full", "Explicit full item read; equivalent to --depth deep (mutually exclusive with --depth/--fields)")
.option("--fields <value>", "Render custom comma-separated item metadata fields (for example: --fields id,title,status,parent,type)")
.description("Show item details by ID.")
.action(async (id: string, options: Record<string, unknown>, command) => {
Expand All @@ -243,6 +244,7 @@ export function registerListQueryCommands(program: Command): void {
{
depth: typeof options.depth === "string" ? options.depth : undefined,
fields: typeof options.fields === "string" ? options.fields : undefined,
full: Boolean(options.full),
},
);
printResult(result, globalOptions);
Expand Down
5 changes: 3 additions & 2 deletions src/sdk/cli-contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,7 @@ export const CONTEXT_FLAG_CONTRACTS: CliFlagContract[] = [

export const GET_FLAG_CONTRACTS: CliFlagContract[] = [
{ flag: "--depth" },
{ flag: "--full" },
{ flag: "--fields" },
];

Expand Down Expand Up @@ -2146,7 +2147,7 @@ const PM_TOOL_ACTION_SCHEMA_CONTRACTS: Record<string, PmActionSchemaContract> =
guide: { optional: ["format", "depth"] },
context: { optional: CONTEXT_CONTRACT_PARAMETER_KEYS },
ctx: { optional: CONTEXT_CONTRACT_PARAMETER_KEYS },
get: { required: ["id"], optional: ["depth", "fields"] },
get: { required: ["id"], optional: ["depth", "full", "fields"] },
Comment thread
coderabbitai[bot] marked this conversation as resolved.
search: {
optional: SEARCH_CONTRACT_PARAMETER_KEYS,
anyOfRequired: [["query"], ["keywords"]],
Expand Down Expand Up @@ -2835,7 +2836,7 @@ const PM_TOOL_PARAMETER_METADATA: Record<string, { description: string; examples
description: "Render compact projection output for search and list-family actions.",
},
full: {
description: "Render full nested search hit payload output.",
description: "Enable command-specific full/detail output mode when supported, such as deep item reads for get or full payload mode for search/history.",
},
fields: {
description: "Comma-separated projection fields for get, search, or list-family outputs.",
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/completion-command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,21 @@ describe("generateBashScript", () => {
expect(script).toContain("--stream");
});

it("includes get projection flags", () => {
const bashScript = generateBashScript();
expect(bashScript).toContain("get)");
expect(bashScript).toContain("--depth --full --fields");

const zshScript = generateZshScript();
expect(zshScript).toContain("get)");
expect(zshScript).toContain("--depth[Detail depth]:(brief standard deep)");
expect(zshScript).toContain("--full[Explicit full item read]");

const fishScript = generateFishScript();
expect(fishScript).toContain("__fish_seen_subcommand_from get");
expect(fishScript).toContain("-l full -d 'Explicit full item read'");
});

it("includes search-specific flags", () => {
const script = generateBashScript();
expect(script).toContain("--mode");
Expand Down
6 changes: 5 additions & 1 deletion tests/unit/contracts-command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ describe("contracts command runtime", () => {
]),
);
expect(fullResult.command_flags?.find((entry) => entry.command === "get")?.flags).toEqual(
expect.arrayContaining([expect.objectContaining({ flag: "--depth" }), expect.objectContaining({ flag: "--fields" })]),
expect.arrayContaining([
expect.objectContaining({ flag: "--depth" }),
expect.objectContaining({ flag: "--full" }),
expect.objectContaining({ flag: "--fields" }),
]),
);
expect(fullResult.commander_aliases).toBeDefined();
expect(
Expand Down
12 changes: 12 additions & 0 deletions tests/unit/get-append-command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ describe("runGet and runAppend", () => {
expect(deep.linked.files).toHaveLength(1);
expect(deep.body).toBe("depth body");

const explicitFull = await runGet(id, { path: context.pmPath }, { full: true });
expect(explicitFull.item.comments).toBeDefined();
expect(explicitFull.item.notes).toBeDefined();
expect(explicitFull.linked.files).toHaveLength(1);
expect(explicitFull.body).toBe("depth body");

const standard = await runGet(id, { path: context.pmPath }, { depth: "standard" });
expect(standard.item.id).toBe(id);
expect(standard.item.comments).toBeUndefined();
Expand All @@ -165,6 +171,12 @@ describe("runGet and runAppend", () => {
await expect(runGet(id, { path: context.pmPath }, { depth: "verbose" })).rejects.toMatchObject<PmCliError>({
exitCode: EXIT_CODE.USAGE,
});
await expect(runGet(id, { path: context.pmPath }, { full: true, fields: "id,title" })).rejects.toMatchObject<PmCliError>({
exitCode: EXIT_CODE.USAGE,
});
await expect(runGet(id, { path: context.pmPath }, { full: true, depth: "brief" })).rejects.toMatchObject<PmCliError>({
exitCode: EXIT_CODE.USAGE,
});
});
});

Expand Down
5 changes: 5 additions & 0 deletions tests/unit/history-activity-command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ describe("runHistory and runActivity", () => {
expect(cliDefault.json).toMatchObject({ compact: true, history: [] });
expect((cliDefault.json as { compact_history?: unknown[] }).compact_history?.length).toBeGreaterThan(0);

const compactDiff = context.runCli(["history", id, "--json", "--diff"], { expectJson: true });
expect(compactDiff.code).toBe(0);
expect(compactDiff.json).toMatchObject({ compact: true, history: [] });
expect((compactDiff.json as { diff?: unknown[] }).diff).toEqual([]);

const cliFull = context.runCli(["history", id, "--json", "--full"], { expectJson: true });
expect(cliFull.code).toBe(0);
expect(cliFull.json).toMatchObject({ compact: false });
Expand Down