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
55 changes: 39 additions & 16 deletions packages/cli/src/formatters/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,32 +111,55 @@ function toDocumentRow(item: {
};
}

function toHumanRows(items: readonly unknown[]): readonly unknown[] {
function pickFields(
item: Record<string, unknown>,
fields: readonly string[] | undefined,
): Record<string, unknown> {
if (!fields || fields.length === 0) {
return item;
}

return Object.fromEntries(fields.map((field) => [field, item[field]]));
}

function toHumanRowsWithOptions(
items: readonly unknown[],
options: Pick<GlobalOptions, "fields" | "view">,
): readonly unknown[] {
if (options.view === "detail") {
return items.map((item) => (isRecord(item) ? pickFields(item, options.fields) : item));
}

if (items.every(isIssueLike)) {
return items.map((item) => ({
key: item.identifier,
title: item.title,
state: item.stateName ?? "-",
priority: item.priority,
updated: formatUpdatedAt(item.updatedAt),
}));
return items.map((item) =>
pickFields(
{
key: item.identifier,
title: item.title,
state: item.stateName ?? "-",
priority: item.priority,
updated: formatUpdatedAt(item.updatedAt),
},
options.fields,
),
);
}

if (items.every(isDocumentLike)) {
return items.map(toDocumentRow);
return items.map((item) => pickFields(toDocumentRow(item), options.fields));
}

return items;
return items.map((item) => (isRecord(item) ? pickFields(item, options.fields) : item));
}

function printHumanData(data: unknown): void {
function printHumanData(data: unknown, options: GlobalOptions): void {
if (Array.isArray(data)) {
console.table(toHumanRows(data));
console.table(toHumanRowsWithOptions(data, options));
return;
}

if (isPageResult(data)) {
console.table(toHumanRows(data.items));
console.table(toHumanRowsWithOptions(data.items, options));
if (data.nextCursor) {
console.log(`Next cursor: ${data.nextCursor}`);
}
Expand All @@ -145,11 +168,11 @@ function printHumanData(data: unknown): void {

if (data !== null && typeof data === "object") {
if (isDocumentLike(data)) {
console.table([toDocumentRow(data)]);
console.table([pickFields(toDocumentRow(data), options.fields)]);
return;
}

console.table([data]);
console.table([pickFields(data as Record<string, unknown>, options.fields)]);
return;
}

Expand All @@ -166,7 +189,7 @@ export function renderEnvelope<Data>(envelope: OutputEnvelope<Data>, options: Gl
if (!options.quiet) {
console.log(`${envelope.entity}.${envelope.action}`);
}
printHumanData(envelope.data);
printHumanData(envelope.data, options);
return;
}

Expand Down
24 changes: 22 additions & 2 deletions packages/cli/src/help/root-help.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
export const rootHelpText = `
Agent-first Linear CLI
Linear CLI v2

Task-first workflows:
linear doctor
linear my-work --mine
linear triage --team ENG
linear project status <project-id>
linear updates --limit 20

Examples:
linear auth login
linear auth login --manual
linear auth status --json
linear auth api-key-set --api-key "$LINEAR_API_KEY"
linear doctor
linear my-work --limit 10
linear triage --team ENG --view detail
linear issues --help
linear issues branch --help
linear issues list --limit 10
linear issues list --limit 10 --state "In Progress" --assignee me
linear issues branch ANN-123 --json
linear issues browse
linear issues create --template "Bug Report" --input '{"teamId":"<team-id>"}'
linear customers list
linear customer-needs list
linear milestones list
linear project-updates list
linear initiative-updates list
linear notifications list
linear initiatives list
linear documents list
linear templates list
Expand All @@ -20,6 +36,8 @@ Examples:

Output:
- Human-readable tables by default
- Detail views with --view detail
- Field selection with --fields identifier,title,assigneeName
- Strict machine output with --json

Docs:
Expand All @@ -31,6 +49,8 @@ export const issuesHelpText = `
Examples:
linear issues --help
linear issues list --limit 10 --json
linear issues list --mine --state "Todo" --view detail
linear issues list --fields identifier,title,assigneeName,projectName
linear issues create --template "Bug Report" --input '{"teamId":"<team-id>"}' --json
`;

Expand Down
Loading
Loading