diff --git a/skills/linear-cli/SKILL.md b/skills/linear-cli/SKILL.md index 2812806f..f25f57f2 100644 --- a/skills/linear-cli/SKILL.md +++ b/skills/linear-cli/SKILL.md @@ -57,23 +57,79 @@ linear issue comment add ENG-123 --body-file /tmp/comment.md **Only use inline flags** (`--description`, `--body`) for simple, single-line content. -## Available Commands +## Command Reference + +All subcommands with flags (omitting universal `-h/--help` and `-w/--workspace`): ``` -linear auth # Manage Linear authentication -linear issue # Manage Linear issues -linear team # Manage Linear teams -linear project # Manage Linear projects -linear project-update # Manage project status updates -linear cycle # Manage Linear team cycles -linear milestone # Manage Linear project milestones -linear initiative # Manage Linear initiatives -linear initiative-update # Manage initiative status updates (timeline posts) -linear label # Manage Linear issue labels -linear document # Manage Linear documents -linear config # Interactively generate .linear.toml configuration -linear schema # Print the GraphQL schema to stdout -linear api # Make a raw GraphQL API request +linear auth login [--key ] # Add a workspace credential +linear auth logout [--force] # Remove a workspace credential +linear auth list # List configured workspaces +linear auth default # Set the default workspace +linear auth token # Print the configured API token +linear auth whoami # Print information about the authenticated user +linear issue id # Print the issue based on the current git branch +linear issue list [--state ] [--all-states] [--assignee ] [--all-assignees] [--unassigned] [--sort ] [--team ] [--project ] [--cycle ] [--limit ] [--web] [--app] [--no-pager] # List your issues +linear issue title # Print the issue title +linear issue start [--all-assignees] [--unassigned] [--from-ref ] [--branch ] # Start working on an issue +linear issue view [--web] [--app] [--no-comments] [--no-pager] [--json] [--no-download] # View issue details (default) or open in browser/app +linear issue url # Print the issue URL +linear issue describe [--references] # Print the issue title and Linear-issue trailer +linear issue commits # Show all commits for a Linear issue (jj only) +linear issue pull-request [--base ] [--draft] [--title ] [--web] [--head <branch>] # Create a GitHub pull request with issue details +linear issue delete [--confirm] [--bulk <ids...>] [--bulk-file <file>] [--bulk-stdin] # Delete an issue +linear issue create [--start] [--assignee <assignee>] [--due-date <dueDate>] [--parent <parent>] [--priority <priority>] [--estimate <estimate>] [--description <description>] [--description-file <path>] [--label <label>] [--team <team>] [--project <project>] [--state <state>] [--milestone <milestone>] [--cycle <cycle>] [--no-use-default-template] [--no-interactive] [--title <title>] # Create a linear issue +linear issue update [--assignee <assignee>] [--due-date <dueDate>] [--parent <parent>] [--priority <priority>] [--estimate <estimate>] [--description <description>] [--description-file <path>] [--label <label>] [--team <team>] [--project <project>] [--state <state>] [--milestone <milestone>] [--cycle <cycle>] [--title <title>] # Update a linear issue +linear issue comment add [--body <text>] [--body-file <path>] [--parent <id>] [--attach <filepath>] # Add a comment to an issue or reply to a comment +linear issue comment delete # Delete a comment +linear issue comment update [--body <text>] [--body-file <path>] # Update an existing comment +linear issue comment list [--json] # List comments for an issue +linear issue attach [--title <title>] [--comment <body>] # Attach a file to an issue +linear issue relation add # Add a relation between two issues +linear issue relation delete # Delete a relation between two issues +linear issue relation list # List relations for an issue +linear team create [--name <name>] [--description <description>] [--key <key>] [--private] [--no-interactive] # Create a linear team +linear team delete [--move-issues <targetTeam>] [--force] # Delete a Linear team +linear team list [--web] [--app] # List teams +linear team id # Print the configured team id +linear team autolinks # Configure GitHub repository autolinks for Linear issues with this team prefix +linear team members [--all] # List team members +linear project list [--team <team>] [--all-teams] [--status <status>] [--web] [--app] [--json] # List projects +linear project view [--web] [--app] # View project details +linear project create [--name <name>] [--description <description>] [--team <team>] [--lead <lead>] [--status <status>] [--start-date <startDate>] [--target-date <targetDate>] [--initiative <initiative>] [--interactive] [--json] # Create a new Linear project +linear project update [--name <name>] [--description <description>] [--status <status>] [--lead <lead>] [--start-date <startDate>] [--target-date <targetDate>] [--team <team>] # Update a Linear project +linear project delete [--force] # Delete (trash) a Linear project +linear project-update create [--body <body>] [--body-file <path>] [--health <health>] [--interactive] # Create a new status update for a project +linear project-update list [--json] [--limit <limit>] # List status updates for a project +linear cycle list [--team <team>] # List cycles for a team +linear cycle view [--team <team>] # View cycle details +linear milestone list [--project <projectId>] # List milestones for a project +linear milestone view # View milestone details +linear milestone create [--project <projectId>] [--name <name>] [--description <description>] [--target-date <date>] # Create a new project milestone +linear milestone update [--name <name>] [--description <description>] [--target-date <date>] [--sort-order <value>] [--project <projectId>] # Update an existing project milestone +linear milestone delete [--force] # Delete a project milestone +linear initiative list [--status <status>] [--all-statuses] [--owner <owner>] [--web] [--app] [--json] [--archived] # List initiatives +linear initiative view [--web] [--app] [--json] # View initiative details +linear initiative create [--name <name>] [--description <description>] [--status <status>] [--owner <owner>] [--target-date <targetDate>] [--color <color>] [--icon <icon>] [--interactive] # Create a new Linear initiative +linear initiative archive [--force] [--bulk <ids...>] [--bulk-file <file>] [--bulk-stdin] # Archive a Linear initiative +linear initiative update [--name <name>] [--description <description>] [--status <status>] [--owner <owner>] [--target-date <targetDate>] [--color <color>] [--icon <icon>] [--interactive] # Update a Linear initiative +linear initiative unarchive [--force] # Unarchive a Linear initiative +linear initiative delete [--force] [--bulk <ids...>] [--bulk-file <file>] [--bulk-stdin] # Permanently delete a Linear initiative +linear initiative add-project [--sort-order <sortOrder>] # Link a project to an initiative +linear initiative remove-project [--force] # Unlink a project from an initiative +linear initiative-update create [--body <body>] [--body-file <path>] [--health <health>] [--interactive] # Create a new status update for an initiative +linear initiative-update list [--json] [--limit <limit>] # List status updates for an initiative +linear label list [--team <teamKey>] [--all] [--json] # List issue labels +linear label create [--name <name>] [--color <color>] [--description <description>] [--team <teamKey>] [--interactive] # Create a new issue label +linear label delete [--team <teamKey>] [--force] # Delete an issue label +linear document list [--project <project>] [--issue <issue>] [--json] [--limit <limit>] # List documents +linear document view [--raw] [--web] [--json] # View a document's content +linear document create [--title <title>] [--content <content>] [--content-file <path>] [--project <project>] [--issue <issue>] [--icon <icon>] [--interactive] # Create a new document +linear document update [--title <title>] [--content <content>] [--content-file <path>] [--icon <icon>] [--edit] # Update an existing document +linear document delete [--yes] [--bulk <ids...>] [--bulk-file <file>] [--bulk-stdin] # Delete a document (moves to trash) +linear config # Interactively generate .linear.toml configuration +linear schema [--json] [--output <file>] # Print the GraphQL schema to stdout +linear api [--variable <variable>] [--variables-json <json>] [--paginate] [--silent] # Make a raw GraphQL API request ``` ## Reference Documentation diff --git a/skills/linear-cli/SKILL.template.md b/skills/linear-cli/SKILL.template.md index 0d2294b0..b83415f8 100644 --- a/skills/linear-cli/SKILL.template.md +++ b/skills/linear-cli/SKILL.template.md @@ -57,7 +57,9 @@ linear issue comment add ENG-123 --body-file /tmp/comment.md **Only use inline flags** (`--description`, `--body`) for simple, single-line content. -## Available Commands +## Command Reference + +All subcommands with flags (omitting universal `-h/--help` and `-w/--workspace`): {{COMMANDS}} diff --git a/skills/linear-cli/references/issue.md b/skills/linear-cli/references/issue.md index 12de728d..7ae2352e 100644 --- a/skills/linear-cli/references/issue.md +++ b/skills/linear-cli/references/issue.md @@ -67,23 +67,22 @@ Description: Options: - -h, --help - Show this help. - -w, --workspace <slug> - Target workspace (uses credentials) - -s, --state <state> - Filter by issue state (can be repeated for multiple states) (Default: [ "unstarted" ], Values: "triage", "backlog", - "unstarted", "started", "completed", "canceled") - --all-states - Show issues from all states - --assignee <assignee> - Filter by assignee (username) - -A, --all-assignees - Show issues for all assignees - -U, --unassigned - Show only unassigned issues - --sort <sort> - Sort order (can also be set via LINEAR_ISSUE_SORT) (Values: "manual", "priority") - --team <team> - Team to list issues for (if not your default team) - --project <project> - Filter by project name - --cycle <cycle> - Filter by cycle name, number, or 'active' - --milestone <milestone> - Filter by project milestone name (requires --project) - --limit <limit> - Maximum number of issues to fetch (default: 50, use 0 for unlimited) (Default: 50) - -w, --web - Open in web browser - -a, --app - Open in Linear.app - --no-pager - Disable automatic paging for long output + -h, --help - Show this help. + -w, --workspace <slug> - Target workspace (uses credentials) + -s, --state <state> - Filter by issue state (can be repeated for multiple states) (Default: [ "unstarted" ], Values: "triage", "backlog", + "unstarted", "started", "completed", "canceled") + --all-states - Show issues from all states + --assignee <assignee> - Filter by assignee (username) + -A, --all-assignees - Show issues for all assignees + -U, --unassigned - Show only unassigned issues + --sort <sort> - Sort order (can also be set via LINEAR_ISSUE_SORT) (Values: "manual", "priority") + --team <team> - Team to list issues for (if not your default team) + --project <project> - Filter by project name + --cycle <cycle> - Filter by cycle name, number, or 'active' + --limit <limit> - Maximum number of issues to fetch (default: 50, use 0 for unlimited) (Default: 50) + -w, --web - Open in web browser + -a, --app - Open in Linear.app + --no-pager - Disable automatic paging for long output ``` ### title diff --git a/skills/linear-cli/scripts/generate-docs.ts b/skills/linear-cli/scripts/generate-docs.ts index 2aef2518..588af85c 100644 --- a/skills/linear-cli/scripts/generate-docs.ts +++ b/skills/linear-cli/scripts/generate-docs.ts @@ -291,16 +291,64 @@ function generateIndex(commands: CommandInfo[]): string { return lines.join("\n") + "\n" } +function extractCompactFlags(helpText: string): string { + const flagParts: string[] = [] + const lines = helpText.split("\n") + let inOptions = false + + for (const line of lines) { + if (/^Options:/.test(line)) { + inOptions = true + continue + } + if (inOptions) { + if (/^(Commands:|Examples:|Arguments:)/.test(line)) break + if (!line.match(/^ {2}-/)) continue + // Match: "-X, --long-name" or "--long-name" or "-X" optionally followed by <arg> + const m = line.match( + /^ {2,}(-[a-zA-Z](?:,\s+--[-a-zA-Z0-9]+)*|--[-a-zA-Z0-9]+)(?:\s+<([^>]+)>)?/, + ) + if (!m) continue + const flagStr = m[1].trim() + const argStr = m[2] + // Skip universal flags: -h/--help and --workspace + if (flagStr.includes("--help")) continue + if (flagStr.includes("--workspace")) continue + // Prefer long form for readability + const longMatch = flagStr.match(/--[-a-zA-Z0-9]+/) + const primaryFlag = longMatch + ? longMatch[0] + : flagStr.split(",")[0].trim() + const part = argStr ? `${primaryFlag} <${argStr}>` : primaryFlag + flagParts.push(`[${part}]`) + } + } + + return flagParts.join(" ") +} + +function getAllLeafCommands( + cmd: CommandInfo, +): { name: string; description: string; help: string }[] { + if (cmd.subcommands.length === 0) { + return [{ name: cmd.name, description: cmd.description, help: cmd.help }] + } + return cmd.subcommands.flatMap(getAllLeafCommands) +} + function generateCommandsSection(commands: CommandInfo[]): string { const lines: string[] = [] lines.push("```") - // Find max command name length for alignment - const maxLen = Math.max(...commands.map((c) => c.name.length)) - for (const cmd of commands) { - const padding = " ".repeat(maxLen - cmd.name.length + 2) - lines.push(`linear ${cmd.name}${padding}# ${cmd.description}`) + const leafCmds = getAllLeafCommands(cmd) + for (const leaf of leafCmds) { + const flags = extractCompactFlags(leaf.help) + const cmdStr = flags + ? `linear ${leaf.name} ${flags}` + : `linear ${leaf.name}` + lines.push(`${cmdStr} # ${leaf.description}`) + } } lines.push("```")