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
84 changes: 74 additions & 10 deletions contracts/runpane/contract.json
Original file line number Diff line number Diff line change
Expand Up @@ -525,14 +525,15 @@
" runpane repos list [--json]",
" runpane repos add --path <path> [--name <name>]",
" runpane panes list [--repo <selector>] [--json]",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [--wait-ready]",
" runpane panels create --pane <pane-id> --agent codex --no-focus --yes",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [--source user|agent] [--focus|--no-focus] [--wait-ready]",
" runpane panels create --pane <pane-id> --agent <codex|claude> [--source user|agent] [--focus|--no-focus] --yes",
" runpane panels list --pane <pane-id> [--json]",
" runpane panels output --panel <panel-id> [--limit <count>] [--json]",
" runpane panels screen --panel <panel-id> [--limit <count>] [--json]",
" runpane panels input --panel <panel-id> --input-file <path|-> --yes",
" runpane panels submit --panel <panel-id> --text <text> --yes",
" runpane panels wait --panel <panel-id> [--for ready|idle|text] [--json]",
" runpane panels input --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit-composer --panel <panel-id> [--strategy auto|codex-ctrl-enter|enter] --yes [--json]",
" runpane panels wait --panel <panel-id> [--for initialized|ready|idle|text] [--json]",
" runpane help [command]",
"",
"Quick start:",
Expand Down Expand Up @@ -660,6 +661,18 @@
" --dry-run Validate and preview without adding the repo",
" --yes Skip confirmation for mutating commands"
],
"panes": [
"Pane session commands.",
"",
"Usage:",
" runpane panes <command> [options]",
"",
"Commands:",
" runpane panes list [--repo <selector>] [--json]",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [options]",
"",
"Run \"runpane help panes list\" or \"runpane help panes create\" for command-specific options."
],
"panes list": [
"Usage:",
" runpane panes list [--repo <selector>] [--json]",
Expand Down Expand Up @@ -702,6 +715,24 @@
" --dry-run Validate and preview without creating panes",
" --yes Skip confirmation for mutating commands"
],
"panels": [
"Terminal-backed panel commands.",
"",
"Usage:",
" runpane panels <command> [options]",
"",
"Commands:",
" runpane panels create --pane <pane-id> --agent <codex|claude> [options]",
" runpane panels list --pane <pane-id> [--json]",
" runpane panels screen --panel <panel-id> [--limit <count>] [--json]",
" runpane panels output --panel <panel-id> [--limit <count>] [--json]",
" runpane panels input --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit-composer --panel <panel-id> [--strategy auto|codex-ctrl-enter|enter] --yes [--json]",
" runpane panels wait --panel <panel-id> [--for initialized|ready|idle|text] [--json]",
"",
"Run \"runpane help panels create\" or another command-specific topic for options."
],
"panels list": [
"Usage:",
" runpane panels list --pane <pane-id> [--json]",
Expand Down Expand Up @@ -858,14 +889,15 @@
" runpane repos list [--json]",
" runpane repos add --path <path> [--name <name>]",
" runpane panes list [--repo <selector>] [--json]",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [--wait-ready]",
" python -m runpane panels create --pane <pane-id> --agent codex --no-focus --yes",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [--source user|agent] [--focus|--no-focus] [--wait-ready]",
" python -m runpane panels create --pane <pane-id> --agent <codex|claude> [--source user|agent] [--focus|--no-focus] --yes",
" runpane panels list --pane <pane-id> [--json]",
" runpane panels output --panel <panel-id> [--limit <count>] [--json]",
" runpane panels screen --panel <panel-id> [--limit <count>] [--json]",
" runpane panels input --panel <panel-id> --input-file <path|-> --yes",
" runpane panels submit --panel <panel-id> --text <text> --yes",
" runpane panels wait --panel <panel-id> [--for ready|idle|text] [--json]",
" runpane panels input --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit-composer --panel <panel-id> [--strategy auto|codex-ctrl-enter|enter] --yes [--json]",
" runpane panels wait --panel <panel-id> [--for initialized|ready|idle|text] [--json]",
" runpane help [command]",
"",
"Quick start:",
Expand Down Expand Up @@ -982,6 +1014,18 @@
" --dry-run",
" --yes"
],
"panes": [
"Pane session commands.",
"",
"Usage:",
" runpane panes <command> [options]",
"",
"Commands:",
" runpane panes list [--repo <selector>] [--json]",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [options]",
"",
"Run \"runpane help panes list\" or \"runpane help panes create\" for command-specific options."
],
"panes list": [
"Usage:",
" runpane panes list [--repo <selector>] [--json]",
Expand Down Expand Up @@ -1024,6 +1068,24 @@
" --dry-run Validate and preview without creating panes",
" --yes Skip confirmation for mutating commands"
],
"panels": [
"Terminal-backed panel commands.",
"",
"Usage:",
" runpane panels <command> [options]",
"",
"Commands:",
" runpane panels create --pane <pane-id> --agent <codex|claude> [options]",
" runpane panels list --pane <pane-id> [--json]",
" runpane panels screen --panel <panel-id> [--limit <count>] [--json]",
" runpane panels output --panel <panel-id> [--limit <count>] [--json]",
" runpane panels input --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit-composer --panel <panel-id> [--strategy auto|codex-ctrl-enter|enter] --yes [--json]",
" runpane panels wait --panel <panel-id> [--for initialized|ready|idle|text] [--json]",
"",
"Run \"runpane help panels create\" or another command-specific topic for options."
],
"panels list": [
"Usage:",
" runpane panels list --pane <pane-id> [--json]",
Expand Down Expand Up @@ -1548,12 +1610,14 @@
"runpane repos add",
"runpane panes list",
"runpane panes create",
"runpane panels create",
"runpane panels list",
"runpane panels output",
"runpane panels input",
"runpane agents doctor",
"runpane panels screen",
"runpane panels submit",
"runpane panels submit-composer",
"runpane panels wait",
"runpane doctor --json",
"runpane agent-context --json",
Expand Down
8 changes: 8 additions & 0 deletions contracts/runpane/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,10 @@
"agents doctor",
"repos list",
"repos add",
"panes",
"panes list",
"panes create",
"panels",
"panels create",
"panels list",
"panels output",
Expand Down Expand Up @@ -386,12 +388,18 @@
"repos add": {
"$ref": "#/$defs/helpLines"
},
"panes": {
"$ref": "#/$defs/helpLines"
},
"panes list": {
"$ref": "#/$defs/helpLines"
},
"panes create": {
"$ref": "#/$defs/helpLines"
},
"panels": {
"$ref": "#/$defs/helpLines"
},
"panels create": {
"$ref": "#/$defs/helpLines"
},
Expand Down
11 changes: 11 additions & 0 deletions packages/runpane-py/src/runpane/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
FORMATS = set(RUNPANE_CONTRACT["enums"]["artifactFormats"])
CHANNELS = set(RUNPANE_CONTRACT["enums"]["channels"])
AGENTS = set(RUNPANE_CONTRACT["enums"]["agents"])
COMMAND_GROUP_HELP_TOPICS = {"panes", "panels"}

REMOTE_VALUE_FLAGS = {flag["name"] for flag in RUNPANE_CONTRACT["flags"]["remoteValue"]}
REMOTE_BOOLEAN_FLAGS = {flag["name"] for flag in RUNPANE_CONTRACT["flags"]["remoteBoolean"]}
Expand Down Expand Up @@ -349,6 +350,10 @@ def parse_args(argv: List[str]) -> ParsedArgs:
args.pop(0)
return ParsedArgs(command="help", help_topic=" ".join(args) or None)

group_help_topic = match_command_group_help(args)
if group_help_topic:
return ParsedArgs(command="help", help_topic=group_help_topic)

matched = match_command(args)
if not matched:
raise ValueError(f"Unknown command: {first}\n\n{help_text(None)}")
Expand Down Expand Up @@ -437,6 +442,12 @@ def match_command(args: List[str]) -> Optional[Tuple[str, List[str]]]:
return None


def match_command_group_help(args: List[str]) -> Optional[str]:
if len(args) != 2 or args[1] not in {"-h", "--help"}:
return None
return args[0] if args[0] in COMMAND_GROUP_HELP_TOPICS else None


def parse_local_boolean_flag(parsed: ParsedArgs, flag: str) -> None:
if flag == "--json":
parsed.json = True
Expand Down
2 changes: 1 addition & 1 deletion packages/runpane-py/src/runpane/generated_contract.py

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions packages/runpane/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const TARGETS = new Set<string>(RUNPANE_CONTRACT.enums.installTargets);
const FORMATS = new Set<string>(RUNPANE_CONTRACT.enums.artifactFormats);
const CHANNELS = new Set<string>(RUNPANE_CONTRACT.enums.channels);
const AGENTS = new Set<string>(RUNPANE_CONTRACT.enums.agents);
const COMMAND_GROUP_HELP_TOPICS = new Set(['panes', 'panels']);

const REMOTE_VALUE_FLAGS = new Set<string>(RUNPANE_CONTRACT.flags.remoteValue.map((flag) => flag.name));
const REMOTE_BOOLEAN_FLAGS = new Set<string>(RUNPANE_CONTRACT.flags.remoteBoolean.map((flag) => flag.name));
Expand Down Expand Up @@ -100,6 +101,15 @@ export function parseRunpaneArgs(argv: string[]): ParsedArgs {
};
}

const groupHelpTopic = matchCommandGroupHelp(args);
if (groupHelpTopic) {
return {
command: 'help',
helpTopic: groupHelpTopic,
...DEFAULTS
};
}

const matched = matchCommand(args);
if (!matched) {
throw new Error(`Unknown command: ${first}\n\n${helpText()}`);
Expand Down Expand Up @@ -223,6 +233,13 @@ function matchCommand(args: string[]): { name: string; tokens: string[] } | unde
);
}

function matchCommandGroupHelp(args: string[]): string | undefined {
if (args.length !== 2 || !['-h', '--help'].includes(args[1])) {
return undefined;
}
return COMMAND_GROUP_HELP_TOPICS.has(args[0]) ? args[0] : undefined;
}

function createFlagSet(flags: readonly { name: string; aliases?: readonly string[] }[]): Set<string> {
return new Set(flags.flatMap((flag) => [flag.name, ...(flag.aliases ?? [])]));
}
Expand Down
84 changes: 74 additions & 10 deletions packages/runpane/src/generated/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,14 +527,15 @@ export const RUNPANE_CONTRACT = {
" runpane repos list [--json]",
" runpane repos add --path <path> [--name <name>]",
" runpane panes list [--repo <selector>] [--json]",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [--wait-ready]",
" runpane panels create --pane <pane-id> --agent codex --no-focus --yes",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [--source user|agent] [--focus|--no-focus] [--wait-ready]",
" runpane panels create --pane <pane-id> --agent <codex|claude> [--source user|agent] [--focus|--no-focus] --yes",
" runpane panels list --pane <pane-id> [--json]",
" runpane panels output --panel <panel-id> [--limit <count>] [--json]",
" runpane panels screen --panel <panel-id> [--limit <count>] [--json]",
" runpane panels input --panel <panel-id> --input-file <path|-> --yes",
" runpane panels submit --panel <panel-id> --text <text> --yes",
" runpane panels wait --panel <panel-id> [--for ready|idle|text] [--json]",
" runpane panels input --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit-composer --panel <panel-id> [--strategy auto|codex-ctrl-enter|enter] --yes [--json]",
" runpane panels wait --panel <panel-id> [--for initialized|ready|idle|text] [--json]",
" runpane help [command]",
"",
"Quick start:",
Expand Down Expand Up @@ -662,6 +663,18 @@ export const RUNPANE_CONTRACT = {
" --dry-run Validate and preview without adding the repo",
" --yes Skip confirmation for mutating commands"
],
"panes": [
"Pane session commands.",
"",
"Usage:",
" runpane panes <command> [options]",
"",
"Commands:",
" runpane panes list [--repo <selector>] [--json]",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [options]",
"",
"Run \"runpane help panes list\" or \"runpane help panes create\" for command-specific options."
],
"panes list": [
"Usage:",
" runpane panes list [--repo <selector>] [--json]",
Expand Down Expand Up @@ -704,6 +717,24 @@ export const RUNPANE_CONTRACT = {
" --dry-run Validate and preview without creating panes",
" --yes Skip confirmation for mutating commands"
],
"panels": [
"Terminal-backed panel commands.",
"",
"Usage:",
" runpane panels <command> [options]",
"",
"Commands:",
" runpane panels create --pane <pane-id> --agent <codex|claude> [options]",
" runpane panels list --pane <pane-id> [--json]",
" runpane panels screen --panel <panel-id> [--limit <count>] [--json]",
" runpane panels output --panel <panel-id> [--limit <count>] [--json]",
" runpane panels input --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit-composer --panel <panel-id> [--strategy auto|codex-ctrl-enter|enter] --yes [--json]",
" runpane panels wait --panel <panel-id> [--for initialized|ready|idle|text] [--json]",
"",
"Run \"runpane help panels create\" or another command-specific topic for options."
],
"panels list": [
"Usage:",
" runpane panels list --pane <pane-id> [--json]",
Expand Down Expand Up @@ -860,14 +891,15 @@ export const RUNPANE_CONTRACT = {
" runpane repos list [--json]",
" runpane repos add --path <path> [--name <name>]",
" runpane panes list [--repo <selector>] [--json]",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [--wait-ready]",
" python -m runpane panels create --pane <pane-id> --agent codex --no-focus --yes",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [--source user|agent] [--focus|--no-focus] [--wait-ready]",
" python -m runpane panels create --pane <pane-id> --agent <codex|claude> [--source user|agent] [--focus|--no-focus] --yes",
" runpane panels list --pane <pane-id> [--json]",
" runpane panels output --panel <panel-id> [--limit <count>] [--json]",
" runpane panels screen --panel <panel-id> [--limit <count>] [--json]",
" runpane panels input --panel <panel-id> --input-file <path|-> --yes",
" runpane panels submit --panel <panel-id> --text <text> --yes",
" runpane panels wait --panel <panel-id> [--for ready|idle|text] [--json]",
" runpane panels input --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit-composer --panel <panel-id> [--strategy auto|codex-ctrl-enter|enter] --yes [--json]",
" runpane panels wait --panel <panel-id> [--for initialized|ready|idle|text] [--json]",
" runpane help [command]",
"",
"Quick start:",
Expand Down Expand Up @@ -984,6 +1016,18 @@ export const RUNPANE_CONTRACT = {
" --dry-run",
" --yes"
],
"panes": [
"Pane session commands.",
"",
"Usage:",
" runpane panes <command> [options]",
"",
"Commands:",
" runpane panes list [--repo <selector>] [--json]",
" runpane panes create --repo <selector> --name <name> --agent <codex|claude> [options]",
"",
"Run \"runpane help panes list\" or \"runpane help panes create\" for command-specific options."
],
"panes list": [
"Usage:",
" runpane panes list [--repo <selector>] [--json]",
Expand Down Expand Up @@ -1026,6 +1070,24 @@ export const RUNPANE_CONTRACT = {
" --dry-run Validate and preview without creating panes",
" --yes Skip confirmation for mutating commands"
],
"panels": [
"Terminal-backed panel commands.",
"",
"Usage:",
" runpane panels <command> [options]",
"",
"Commands:",
" runpane panels create --pane <pane-id> --agent <codex|claude> [options]",
" runpane panels list --pane <pane-id> [--json]",
" runpane panels screen --panel <panel-id> [--limit <count>] [--json]",
" runpane panels output --panel <panel-id> [--limit <count>] [--json]",
" runpane panels input --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit --panel <panel-id> (--text <text>|--input-file <path|->) --yes [--json]",
" runpane panels submit-composer --panel <panel-id> [--strategy auto|codex-ctrl-enter|enter] --yes [--json]",
" runpane panels wait --panel <panel-id> [--for initialized|ready|idle|text] [--json]",
"",
"Run \"runpane help panels create\" or another command-specific topic for options."
],
"panels list": [
"Usage:",
" runpane panels list --pane <pane-id> [--json]",
Expand Down Expand Up @@ -1550,12 +1612,14 @@ export const RUNPANE_CONTRACT = {
"runpane repos add",
"runpane panes list",
"runpane panes create",
"runpane panels create",
"runpane panels list",
"runpane panels output",
"runpane panels input",
"runpane agents doctor",
"runpane panels screen",
"runpane panels submit",
"runpane panels submit-composer",
"runpane panels wait",
"runpane doctor --json",
"runpane agent-context --json",
Expand Down
Loading
Loading