shapeup-cli 0.3.2 → 0.3.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89595c1b4509ab13079e503ff5b94894c469220c070d1983389d8cd4ba3d2756
4
- data.tar.gz: eb5c3bde6d0988fdfc125a78268216f5dfb8736a4ff7082ed588d71de0ea6587
3
+ metadata.gz: 167d55101c1c27e4ce1bd6dc8e6f52599937489e4a6218c248f901a150282273
4
+ data.tar.gz: d511b7da6d77e6437ee431951dd591f59b6ed70807be55618564c79b2e9a828b
5
5
  SHA512:
6
- metadata.gz: f7b3825df0045f80896ffbc17db90f57048084aa7eb2ac92ecb17b584c769d3affbcd7503fef3703fc7faf6d98c6127b557ffbdf5feb028d14e29db29a360424
7
- data.tar.gz: 5edd8c20f3ae4da183309750cb18cb5204036c955322c443e1d2e75e971f0c88a6e3e508d25723b30da5dee994d5cf1627486548f8b8d8fd729c151d10979143
6
+ metadata.gz: 6cc0fc54f960c09e7338a5ca49ed2eb61820b9246438c2533ce1f1686f5dd4e4b053aed3f63a79e5855a046bff5b859efcf137b1f8db0bdceb8a014220a2c0aa
7
+ data.tar.gz: f4dbcbd90cd4ac33b2d9096fb683b08e76f71f042184faee5a4b91bd7a88802655a593c5b4a60ade0925ad14d07c5c8e7d37991dd31327a6f8c6adef598c403f
@@ -108,6 +108,22 @@ module ShapeupCli
108
108
  def positional_args
109
109
  @remaining.reject { |a| a.start_with?("--") }
110
110
  end
111
+
112
+ # Presence-only boolean flag. Returns true if present, removes from @remaining.
113
+ def consume_flag(flag)
114
+ !!@remaining.delete(flag)
115
+ end
116
+
117
+ # Parse --comments/--no-comments + --comments-limit N into MCP args.
118
+ def comment_flags
119
+ args = {}
120
+ args[:include_comments] = false if consume_flag("--no-comments")
121
+ consume_flag("--comments") # explicit opt-in, no-op since default is true
122
+ if (limit = extract_option("--comments-limit"))
123
+ args[:comments_limit] = limit.to_i
124
+ end
125
+ args
126
+ end
111
127
  end
112
128
  end
113
129
  end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShapeupCli
4
+ module Commands
5
+ class Checklist < Base
6
+ def self.metadata
7
+ {
8
+ command: "checklist",
9
+ path: "shapeup checklist",
10
+ short: "Manage the checklist on a pitch or issue",
11
+ subcommands: [
12
+ { name: "list", short: "List items (default)", path: "shapeup checklist --pitch <id>" },
13
+ { name: "add", short: "Add an item", path: 'shapeup checklist add --pitch <id> "Item text"' },
14
+ { name: "tick", short: "Mark an item complete", path: "shapeup checklist tick <item_id>" },
15
+ { name: "untick", short: "Mark an item incomplete", path: "shapeup checklist untick <item_id>" },
16
+ { name: "edit", short: "Rename an item", path: 'shapeup checklist edit <item_id> "New text"' },
17
+ { name: "remove", short: "Delete an item", path: "shapeup checklist remove <item_id>" }
18
+ ],
19
+ flags: [
20
+ { name: "pitch", type: "string", usage: "Pitch ID (for list/add)" },
21
+ { name: "issue", type: "string", usage: "Issue ID (for list/add)" }
22
+ ],
23
+ examples: [
24
+ "shapeup checklist --pitch 42",
25
+ "shapeup checklist --issue 7",
26
+ 'shapeup checklist add --pitch 42 "Confirm Slack webhook"',
27
+ "shapeup checklist tick 18",
28
+ "shapeup checklist untick 18",
29
+ 'shapeup checklist edit 18 "Confirm Slack webhook secret rotation"',
30
+ "shapeup checklist remove 18"
31
+ ]
32
+ }
33
+ end
34
+
35
+ def execute
36
+ subcommand = positional_arg(0)
37
+
38
+ case subcommand
39
+ when "add" then add
40
+ when "tick" then tick
41
+ when "untick" then untick
42
+ when "edit" then edit
43
+ when "remove" then remove
44
+ when "list", nil then list
45
+ else list
46
+ end
47
+ end
48
+
49
+ private
50
+ def list
51
+ type, id = resolve_target
52
+ result = call_tool("list_checklist_items", checklistable_type: type, checklistable_id: id.to_s)
53
+
54
+ render result,
55
+ summary: "Checklist on #{type} ##{id}",
56
+ breadcrumbs: [
57
+ { cmd: "shapeup checklist add --#{type.downcase == 'package' ? 'pitch' : 'issue'} #{id} \"Item\"", description: "Add an item" },
58
+ { cmd: "shapeup checklist tick <item_id>", description: "Tick an item" }
59
+ ]
60
+ end
61
+
62
+ def add
63
+ type, id = resolve_target
64
+ text = positional_arg(1) || abort('Usage: shapeup checklist add --pitch <id> "Item text"')
65
+
66
+ result = call_tool("create_checklist_item", checklistable_type: type, checklistable_id: id.to_s, content: text)
67
+
68
+ render result,
69
+ summary: "Item added to #{type} ##{id}",
70
+ breadcrumbs: [
71
+ { cmd: "shapeup checklist --#{type.downcase == 'package' ? 'pitch' : 'issue'} #{id}", description: "View checklist" }
72
+ ]
73
+ end
74
+
75
+ def tick
76
+ item_id = positional_arg(1) || abort("Usage: shapeup checklist tick <item_id>")
77
+
78
+ result = call_tool("update_checklist_item", checklist_item: item_id.to_s, completed: true)
79
+
80
+ render result, summary: "Item ##{item_id} ticked"
81
+ end
82
+
83
+ def untick
84
+ item_id = positional_arg(1) || abort("Usage: shapeup checklist untick <item_id>")
85
+
86
+ result = call_tool("update_checklist_item", checklist_item: item_id.to_s, completed: false)
87
+
88
+ render result, summary: "Item ##{item_id} unticked"
89
+ end
90
+
91
+ def edit
92
+ item_id = positional_arg(1) || abort('Usage: shapeup checklist edit <item_id> "New text"')
93
+ text = positional_arg(2) || abort('Usage: shapeup checklist edit <item_id> "New text"')
94
+
95
+ result = call_tool("update_checklist_item", checklist_item: item_id.to_s, content: text)
96
+
97
+ render result, summary: "Item ##{item_id} updated"
98
+ end
99
+
100
+ def remove
101
+ item_id = positional_arg(1) || abort("Usage: shapeup checklist remove <item_id>")
102
+
103
+ result = call_tool("delete_checklist_item", checklist_item: item_id.to_s)
104
+
105
+ render result, summary: "Item ##{item_id} removed"
106
+ end
107
+
108
+ def resolve_target
109
+ pitch = extract_option("--pitch")
110
+ issue = extract_option("--issue")
111
+
112
+ if pitch
113
+ [ "Package", pitch ]
114
+ elsif issue
115
+ [ "Issue", issue ]
116
+ else
117
+ abort("Specify a target: --pitch <id> or --issue <id>")
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -25,6 +25,8 @@ module ShapeupCli
25
25
  { name: "watch", short: "Watch an issue", path: "shapeup issues watch <id>" },
26
26
  { name: "unwatch", short: "Stop watching an issue", path: "shapeup issues unwatch <id>" },
27
27
  { name: "watching", short: "List issues you are watching", path: "shapeup watching" },
28
+ { name: "convert", short: "Convert issue into a new pitch", path: "shapeup issues convert <id>" },
29
+ { name: "add-to-pitch", short: "Fold issue content into an existing pitch", path: "shapeup issues add-to-pitch <id> --pitch <pitch_id>" },
28
30
  { name: "delete", short: "Delete an issue", path: "shapeup issues delete <id>" }
29
31
  ],
30
32
  flags: [
@@ -37,7 +39,10 @@ module ShapeupCli
37
39
  { name: "all", type: "bool", usage: "Include done/closed issues (hidden by default)" },
38
40
  { name: "content", type: "string", usage: "Issue content/description" },
39
41
  { name: "title", type: "string", usage: "Issue title (for update)" },
40
- { name: "archived", type: "bool", usage: "Include iceboxed issues in list" }
42
+ { name: "pitch", type: "string", usage: "Pitch ID (for add-to-pitch)" },
43
+ { name: "archived", type: "bool", usage: "Include iceboxed issues in list" },
44
+ { name: "no-comments", type: "bool", usage: "Hide embedded comments on show (default: show)" },
45
+ { name: "comments-limit", type: "integer", usage: "Max comments to embed on show (default: 10, max: 50)" }
41
46
  ],
42
47
  examples: [
43
48
  "shapeup issues",
@@ -58,7 +63,9 @@ module ShapeupCli
58
63
  "shapeup issues assign 42 --user 7",
59
64
  "shapeup issues unassign 42",
60
65
  "shapeup issues watch 42",
61
- "shapeup watching"
66
+ "shapeup watching",
67
+ "shapeup issues convert 42",
68
+ "shapeup issues add-to-pitch 42 --pitch 10"
62
69
  ]
63
70
  }
64
71
  end
@@ -67,22 +74,24 @@ module ShapeupCli
67
74
  subcommand = positional_arg(0)
68
75
 
69
76
  case subcommand
70
- when "show" then show
71
- when "create" then create
72
- when "update" then update
73
- when "move" then move
74
- when "done" then mark_done
75
- when "close" then close
76
- when "reopen" then reopen
77
- when "icebox" then icebox
78
- when "defrost" then defrost
79
- when "assign" then assign
80
- when "unassign" then unassign
81
- when "watch" then watch
82
- when "unwatch" then unwatch
83
- when "watching" then watching
84
- when "delete" then delete
85
- when "list", nil then list
77
+ when "show" then show
78
+ when "create" then create
79
+ when "update" then update
80
+ when "move" then move
81
+ when "done" then mark_done
82
+ when "close" then close
83
+ when "reopen" then reopen
84
+ when "icebox" then icebox
85
+ when "defrost" then defrost
86
+ when "assign" then assign
87
+ when "unassign" then unassign
88
+ when "watch" then watch
89
+ when "unwatch" then unwatch
90
+ when "watching" then watching
91
+ when "convert" then convert
92
+ when "add-to-pitch" then add_to_pitch
93
+ when "delete" then delete
94
+ when "list", nil then list
86
95
  else
87
96
  # Bare numeric arg = show
88
97
  if subcommand&.match?(/\A\d+\z/)
@@ -125,14 +134,15 @@ module ShapeupCli
125
134
 
126
135
  def show
127
136
  id = positional_arg(1) || positional_arg(0) || abort("Usage: shapeup issue <id>")
128
- result = call_tool("show_issue", issue: id.to_s)
137
+ result = call_tool("show_issue", issue: id.to_s, **comment_flags)
129
138
 
130
139
  render result,
131
140
  summary: "Issue ##{id}",
132
141
  breadcrumbs: [
133
142
  { cmd: "shapeup issues move #{id} --column <id>", description: "Move to column" },
134
143
  { cmd: "shapeup issues icebox #{id}", description: "Move to icebox" },
135
- { cmd: "shapeup issues watch #{id}", description: "Watch this issue" }
144
+ { cmd: "shapeup issues watch #{id}", description: "Watch this issue" },
145
+ { cmd: "shapeup issue #{id} --no-comments", description: "Hide embedded comments" }
136
146
  ]
137
147
  end
138
148
 
@@ -331,6 +341,32 @@ module ShapeupCli
331
341
  { cmd: "shapeup issues", description: "List remaining issues" }
332
342
  ]
333
343
  end
344
+
345
+ def convert
346
+ id = positional_arg(1) || abort("Usage: shapeup issues convert <id>")
347
+
348
+ result = call_tool("convert_issue_to_pitch", issue: id.to_s)
349
+
350
+ render result,
351
+ summary: "Issue ##{id} converted to a pitch",
352
+ breadcrumbs: [
353
+ { cmd: "shapeup pitches", description: "List pitches" },
354
+ { cmd: "shapeup pitch <id>", description: "Open the new pitch" }
355
+ ]
356
+ end
357
+
358
+ def add_to_pitch
359
+ id = positional_arg(1) || abort('Usage: shapeup issues add-to-pitch <id> --pitch <pitch_id>')
360
+ pitch_id = extract_option("--pitch") || abort('Usage: shapeup issues add-to-pitch <id> --pitch <pitch_id>')
361
+
362
+ result = call_tool("add_issue_to_pitch", issue: id.to_s, package: pitch_id.to_s)
363
+
364
+ render result,
365
+ summary: "Issue ##{id} folded into pitch ##{pitch_id}",
366
+ breadcrumbs: [
367
+ { cmd: "shapeup pitch #{pitch_id}", description: "Open the pitch" }
368
+ ]
369
+ end
334
370
  end
335
371
  end
336
372
  end
@@ -17,15 +17,19 @@ module ShapeupCli
17
17
  flags: [
18
18
  { name: "status", type: "string", usage: "Filter by status: idea, framed, shaped" },
19
19
  { name: "cycle", type: "string", usage: "Filter by cycle ID" },
20
+ { name: "tag", type: "string", usage: "Filter by tag name" },
20
21
  { name: "limit", type: "integer", usage: "Limit number of results" },
21
22
  { name: "stream", type: "string", usage: "Stream name or ID (for create)" },
22
23
  { name: "appetite", type: "string", usage: "Appetite: unknown, small_batch, big_batch (for create, default: big_batch)" },
23
- { name: "cycle-id", type: "string", usage: "Assign to cycle ID (for create)" }
24
+ { name: "cycle-id", type: "string", usage: "Assign to cycle ID (for create)" },
25
+ { name: "no-comments", type: "bool", usage: "Hide embedded comments on show (default: show)" },
26
+ { name: "comments-limit", type: "integer", usage: "Max comments to embed on show (default: 10, max: 50)" }
24
27
  ],
25
28
  examples: [
26
29
  "shapeup pitches list",
27
30
  "shapeup pitches list --status shaped",
28
31
  "shapeup pitches list --cycle 5",
32
+ "shapeup pitches list --tag q3-plan",
29
33
  "shapeup pitch 42",
30
34
  "shapeup pitch 42 --json",
31
35
  "shapeup pitches create \"Redesign Search\" --stream \"Platform\"",
@@ -51,9 +55,11 @@ module ShapeupCli
51
55
  def list
52
56
  cycle_id = extract_option("--cycle")
53
57
  status = extract_option("--status")
58
+ tag = extract_option("--tag")
54
59
  limit = extract_option("--limit")&.to_i
55
60
  args = {}
56
61
  args[:cycle] = cycle_id if cycle_id
62
+ args[:tag] = tag if tag
57
63
 
58
64
  result = call_tool("list_packages", **args)
59
65
  data = Output.extract_data(result)
@@ -66,6 +72,7 @@ module ShapeupCli
66
72
  summary = "Pitches"
67
73
  summary += " (#{status})" if status
68
74
  summary += " in cycle #{cycle_id}" if cycle_id
75
+ summary += " tagged #{tag}" if tag
69
76
  summary += " — #{packages.length} results"
70
77
 
71
78
  render_list(packages, summary)
@@ -74,7 +81,7 @@ module ShapeupCli
74
81
  def show(id = nil)
75
82
  id ||= positional_arg(1) || abort("Usage: shapeup pitches show <id>")
76
83
 
77
- result = call_tool("show_package", package: id.to_s)
84
+ result = call_tool("show_package", package: id.to_s, **comment_flags)
78
85
 
79
86
  render result,
80
87
  summary: "Pitch ##{id}",
@@ -82,7 +89,8 @@ module ShapeupCli
82
89
  { cmd: "shapeup scopes list --pitch #{id}", description: "List scopes" },
83
90
  { cmd: "shapeup scopes create --pitch #{id} \"Title\"", description: "Add a scope" },
84
91
  { cmd: "shapeup todo \"Task\" --pitch #{id}", description: "Add a task" },
85
- { cmd: "shapeup tasks list --pitch #{id}", description: "List all tasks" }
92
+ { cmd: "shapeup tasks list --pitch #{id}", description: "List all tasks" },
93
+ { cmd: "shapeup pitch #{id} --no-comments", description: "Hide embedded comments" }
86
94
  ]
87
95
  end
88
96
 
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShapeupCli
4
+ module Commands
5
+ class Tags < Base
6
+ def self.metadata
7
+ {
8
+ command: "tags",
9
+ path: "shapeup tags",
10
+ short: "List, add, and remove tags on pitches and issues",
11
+ subcommands: [
12
+ { name: "list", short: "List the org's tag vocabulary (default)", path: "shapeup tags" },
13
+ { name: "add", short: "Tag a pitch or issue", path: "shapeup tags add --pitch <id> <name>" },
14
+ { name: "remove", short: "Untag a pitch or issue", path: "shapeup tags remove --pitch <id> <name>" }
15
+ ],
16
+ flags: [
17
+ { name: "pitch", type: "string", usage: "Pitch ID (for add/remove)" },
18
+ { name: "issue", type: "string", usage: "Issue ID (for add/remove)" }
19
+ ],
20
+ examples: [
21
+ "shapeup tags",
22
+ "shapeup tags add --pitch 42 q3-plan",
23
+ "shapeup tags add --issue 7 needs-design",
24
+ "shapeup tags remove --pitch 42 q3-plan",
25
+ "shapeup pitches list --tag q3-plan"
26
+ ]
27
+ }
28
+ end
29
+
30
+ def execute
31
+ subcommand = positional_arg(0)
32
+
33
+ case subcommand
34
+ when "add" then add
35
+ when "remove" then remove
36
+ when "list", nil then list
37
+ else list
38
+ end
39
+ end
40
+
41
+ private
42
+ def list
43
+ result = call_tool("list_tags")
44
+
45
+ render result,
46
+ summary: "Tags",
47
+ breadcrumbs: [
48
+ { cmd: "shapeup tags add --pitch <id> <name>", description: "Tag a pitch" },
49
+ { cmd: "shapeup pitches list --tag <name>", description: "Filter pitches by tag" }
50
+ ]
51
+ end
52
+
53
+ def add
54
+ type, id = resolve_target
55
+ name = positional_arg(1) || abort("Usage: shapeup tags add --pitch <id> <name>")
56
+
57
+ result = call_tool("add_tag", taggable_type: type, taggable_id: id.to_s, name: name)
58
+
59
+ render result, summary: "Tagged #{type} ##{id}"
60
+ end
61
+
62
+ def remove
63
+ type, id = resolve_target
64
+ name = positional_arg(1) || abort("Usage: shapeup tags remove --pitch <id> <name>")
65
+
66
+ result = call_tool("remove_tag", taggable_type: type, taggable_id: id.to_s, name: name)
67
+
68
+ render result, summary: "Untagged #{type} ##{id}"
69
+ end
70
+
71
+ def resolve_target
72
+ pitch = extract_option("--pitch")
73
+ issue = extract_option("--issue")
74
+
75
+ if pitch
76
+ [ "Package", pitch ]
77
+ elsif issue
78
+ [ "Issue", issue ]
79
+ else
80
+ abort("Specify a target: --pitch <id> or --issue <id>")
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -62,6 +62,9 @@ module ShapeupCli
62
62
  issues unwatch <id> Stop watching
63
63
  watching List issues you are watching
64
64
  issues delete <id> Delete an issue
65
+ issues convert <id> Convert issue to a new pitch
66
+ issues add-to-pitch <id> --pitch <pid>
67
+ Fold issue into an existing pitch
65
68
 
66
69
  Comments:
67
70
  comments list --issue <id> List comments on an issue
@@ -69,6 +72,22 @@ module ShapeupCli
69
72
  comments add --issue <id> "Text" Add a comment to an issue
70
73
  comments add --pitch <id> "Text" Add a comment to a pitch
71
74
 
75
+ Checklist:
76
+ checklist --pitch <id> List the checklist on a pitch
77
+ checklist --issue <id> List the checklist on an issue
78
+ checklist add --pitch <id> "Text" Add an item
79
+ checklist tick <item_id> Mark an item complete
80
+ checklist untick <item_id> Mark an item incomplete
81
+ checklist edit <item_id> "Text" Rename an item
82
+ checklist remove <item_id> Delete an item
83
+
84
+ Tags:
85
+ tags List the org's tag vocabulary
86
+ tags add --pitch <id> <name> Tag a pitch
87
+ tags add --issue <id> <name> Tag an issue
88
+ tags remove --pitch <id> <name> Untag a pitch
89
+ tags remove --issue <id> <name> Untag an issue
90
+
72
91
  My Work:
73
92
  my-work, me Show everything assigned to me
74
93
 
@@ -128,10 +147,12 @@ module ShapeupCli
128
147
  tasks Manage tasks (list, create, complete)
129
148
  todo Create a task (shortcut)
130
149
  done Complete task(s) (shortcut)
131
- issues Manage issues (list, show, create, move, icebox, watch)
150
+ issues Manage issues (list, show, create, move, icebox, watch, convert, add-to-pitch)
132
151
  issue Show an issue (shortcut)
133
152
  watching List watched issues (shortcut)
134
153
  comments List and add comments (list, add)
154
+ checklist Manage checklist items on pitches/issues (list, add, tick, untick, edit, remove)
155
+ tags List/add/remove tags on pitches and issues
135
156
  my-work / me Show my assigned work
136
157
  search Search everything
137
158
  config Show/set config (set, show, init)
@@ -159,3 +180,5 @@ require_relative "commands/auth"
159
180
  require_relative "commands/config_cmd"
160
181
  require_relative "commands/setup"
161
182
  require_relative "commands/comments"
183
+ require_relative "commands/checklist"
184
+ require_relative "commands/tags"
data/lib/shapeup_cli.rb CHANGED
@@ -16,7 +16,7 @@ require_relative "shapeup_cli/output"
16
16
  require_relative "shapeup_cli/commands"
17
17
 
18
18
  module ShapeupCli
19
- VERSION = "0.3.2"
19
+ VERSION = "0.3.4"
20
20
  DEFAULT_HOST = "https://shapeup.cc"
21
21
 
22
22
  # Exit codes
@@ -30,18 +30,20 @@ module ShapeupCli
30
30
  EXIT_INTERRUPTED = 130
31
31
 
32
32
  COMMAND_MAP = {
33
- "orgs" => Commands::Orgs,
34
- "pitches" => Commands::Pitches,
35
- "cycle" => Commands::Cycle,
36
- "scopes" => Commands::Scopes,
37
- "tasks" => Commands::Tasks,
38
- "issues" => Commands::Issues,
39
- "my-work" => Commands::MyWork,
40
- "search" => Commands::Search,
41
- "auth" => Commands::Auth,
42
- "config" => Commands::ConfigCmd,
43
- "setup" => Commands::Setup,
44
- "comments" => Commands::Comments
33
+ "orgs" => Commands::Orgs,
34
+ "pitches" => Commands::Pitches,
35
+ "cycle" => Commands::Cycle,
36
+ "scopes" => Commands::Scopes,
37
+ "tasks" => Commands::Tasks,
38
+ "issues" => Commands::Issues,
39
+ "my-work" => Commands::MyWork,
40
+ "search" => Commands::Search,
41
+ "auth" => Commands::Auth,
42
+ "config" => Commands::ConfigCmd,
43
+ "setup" => Commands::Setup,
44
+ "comments" => Commands::Comments,
45
+ "checklist" => Commands::Checklist,
46
+ "tags" => Commands::Tags
45
47
  }.freeze
46
48
 
47
49
  def self.run(argv)
@@ -77,6 +79,8 @@ module ShapeupCli
77
79
  when "issue" then Commands::Issues.run(["show"] + args)
78
80
  when "watching" then Commands::Issues.run(["watching"] + args)
79
81
  when "comments" then Commands::Comments.run(args)
82
+ when "checklist" then Commands::Checklist.run(args)
83
+ when "tags" then Commands::Tags.run(args)
80
84
  when "my-work", "me" then Commands::MyWork.run(args)
81
85
  when "search" then Commands::Search.run(args)
82
86
  when "config" then Commands::ConfigCmd.run(args)
@@ -133,11 +133,26 @@ Manage pitches, scopes, tasks, issues, and cycles via the ShapeUp CLI. Columns a
133
133
  | Unassign from issue | `shapeup issues unassign <id>` (self) / `--user <id>` |
134
134
  | Watch / unwatch | `shapeup issues watch <id>` / `unwatch <id>` |
135
135
  | My watched issues | `shapeup watching --json` |
136
+ | Convert issue to pitch | `shapeup issues convert <id>` |
137
+ | Fold issue into pitch | `shapeup issues add-to-pitch <id> --pitch <pitch_id>` |
136
138
  | **Comments** | |
137
139
  | List comments on issue | `shapeup comments list --issue <id> --json` |
138
140
  | List comments on pitch | `shapeup comments list --pitch <id> --json` |
139
141
  | Add comment to issue | `shapeup comments add --issue <id> "Comment text"` |
140
142
  | Add comment to pitch | `shapeup comments add --pitch <id> "Comment text"` |
143
+ | **Checklist** | |
144
+ | List checklist on pitch | `shapeup checklist --pitch <id>` |
145
+ | List checklist on issue | `shapeup checklist --issue <id>` |
146
+ | Add an item | `shapeup checklist add --pitch <id> "Item text"` |
147
+ | Tick / untick an item | `shapeup checklist tick <item_id>` / `untick <item_id>` |
148
+ | Rename an item | `shapeup checklist edit <item_id> "New text"` |
149
+ | Remove an item | `shapeup checklist remove <item_id>` |
150
+ | **Tags** | |
151
+ | List tag vocabulary | `shapeup tags` |
152
+ | Tag a pitch | `shapeup tags add --pitch <id> <name>` |
153
+ | Tag an issue | `shapeup tags add --issue <id> <name>` |
154
+ | Untag | `shapeup tags remove --pitch <id> <name>` |
155
+ | Filter pitches by tag | `shapeup pitches list --tag <name>` |
141
156
  | **Pitches** | |
142
157
  | List pitches | `shapeup pitches list --json` |
143
158
  | List shaped only | `shapeup pitches list --status shaped --json` |
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shapeup-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ShapeUp
@@ -27,6 +27,7 @@ files:
27
27
  - lib/shapeup_cli/commands.rb
28
28
  - lib/shapeup_cli/commands/auth.rb
29
29
  - lib/shapeup_cli/commands/base.rb
30
+ - lib/shapeup_cli/commands/checklist.rb
30
31
  - lib/shapeup_cli/commands/comments.rb
31
32
  - lib/shapeup_cli/commands/config_cmd.rb
32
33
  - lib/shapeup_cli/commands/cycle.rb
@@ -39,6 +40,7 @@ files:
39
40
  - lib/shapeup_cli/commands/scopes.rb
40
41
  - lib/shapeup_cli/commands/search.rb
41
42
  - lib/shapeup_cli/commands/setup.rb
43
+ - lib/shapeup_cli/commands/tags.rb
42
44
  - lib/shapeup_cli/commands/tasks.rb
43
45
  - lib/shapeup_cli/config.rb
44
46
  - lib/shapeup_cli/output.rb
@@ -64,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
66
  - !ruby/object:Gem::Version
65
67
  version: '0'
66
68
  requirements: []
67
- rubygems_version: 3.6.9
69
+ rubygems_version: 4.0.6
68
70
  specification_version: 4
69
71
  summary: ShapeUp CLI — manage pitches, scopes, tasks, and cycles from the terminal
70
72
  test_files: []