discourse_cli_tool 0.1.0 → 0.2.1
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 +4 -4
- data/lib/discourse_cli/cli.rb +1 -0
- data/lib/discourse_cli/commands/skill.rb +63 -0
- data/lib/discourse_cli/commands/topics.rb +3 -9
- data/lib/discourse_cli/version.rb +1 -1
- data/lib/discourse_cli.rb +1 -0
- data/lib/rubygems_plugin.rb +36 -0
- data/skill/dsc/SKILL.md +47 -0
- data/skill/dsc/references/categories.md +39 -0
- data/skill/dsc/references/posts.md +41 -0
- data/skill/dsc/references/topics.md +49 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2f85a2451232e1d21e616d56497f3a2eefcd7875525278e61821454ef72069d3
|
|
4
|
+
data.tar.gz: 4849b6f1dfa072a46ff7855fd9bf637d6e28000324cc85aa737f852203fad5f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 41e07d72153230d31b6572e2392e747dc076d9accba1d4b37abadb1a14422d95a0df2e4d599a631be472195fa6772ec952898523eec08d03ffd597387a0896f6
|
|
7
|
+
data.tar.gz: ee479f290a32beb230091d6647e40d540f5897b7db39ccb9f0bcba03c708d04c6a7cb7c61bfcad984d325ae79d3447c43a19137b5da9f7c2e2832c26976f6c5d
|
data/lib/discourse_cli/cli.rb
CHANGED
|
@@ -12,5 +12,6 @@ module DiscourseCli
|
|
|
12
12
|
register(Commands::Categories, "categories", "categories <command>", "Manage categories")
|
|
13
13
|
register(Commands::Topics, "topics", "topics <command>", "Manage topics")
|
|
14
14
|
register(Commands::Posts, "posts", "posts <command>", "Manage posts")
|
|
15
|
+
register(Commands::Skill, "skill", "skill <command>", "Manage the dsc LLM skill")
|
|
15
16
|
end
|
|
16
17
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module DiscourseCli
|
|
6
|
+
module Commands
|
|
7
|
+
class Skill < Base
|
|
8
|
+
def self.agent_paths
|
|
9
|
+
{
|
|
10
|
+
claude: File.expand_path("~/.claude/skills/dsc"),
|
|
11
|
+
codex: File.expand_path("~/.codex/skills/dsc"),
|
|
12
|
+
gemini: File.expand_path("~/.gemini/skills/dsc"),
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
desc "install", "Install the dsc skill for LLM coding agents"
|
|
17
|
+
option :claude, type: :boolean, default: false, desc: "Install for Claude Code"
|
|
18
|
+
option :codex, type: :boolean, default: false, desc: "Install for Codex"
|
|
19
|
+
option :gemini, type: :boolean, default: false, desc: "Install for Gemini CLI"
|
|
20
|
+
def install
|
|
21
|
+
targets = selected_agents
|
|
22
|
+
skill_source = self.class.skill_source
|
|
23
|
+
|
|
24
|
+
unless File.exist?(skill_source)
|
|
25
|
+
$stderr.puts "Skill source not found at #{skill_source}"
|
|
26
|
+
exit 1
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
targets.each do |agent, path|
|
|
30
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
31
|
+
|
|
32
|
+
if File.symlink?(path) && File.readlink(path) == skill_source
|
|
33
|
+
puts "#{agent}: already installed"
|
|
34
|
+
next
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
File.unlink(path) if File.symlink?(path) || File.exist?(path)
|
|
38
|
+
File.symlink(skill_source, path)
|
|
39
|
+
puts "#{agent}: installed → #{path}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.skill_source
|
|
44
|
+
spec = Gem::Specification.find_by_name("discourse_cli_tool")
|
|
45
|
+
File.join(spec.gem_dir, "skill", "dsc")
|
|
46
|
+
rescue Gem::MissingSpecError
|
|
47
|
+
File.expand_path("../../../skill/dsc", __dir__)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def selected_agents
|
|
53
|
+
paths = self.class.agent_paths
|
|
54
|
+
any_selected = options[:claude] || options[:codex] || options[:gemini]
|
|
55
|
+
agents = any_selected ? {} : paths.dup
|
|
56
|
+
agents[:claude] = paths[:claude] if options[:claude]
|
|
57
|
+
agents[:codex] = paths[:codex] if options[:codex]
|
|
58
|
+
agents[:gemini] = paths[:gemini] if options[:gemini]
|
|
59
|
+
agents
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -22,7 +22,7 @@ module DiscourseCli
|
|
|
22
22
|
|
|
23
23
|
desc "create", "Create a topic (opens $EDITOR if --raw not given)"
|
|
24
24
|
option :title, type: :string, required: true
|
|
25
|
-
option :category, type: :
|
|
25
|
+
option :category, type: :numeric, desc: "Category ID"
|
|
26
26
|
option :tags, type: :string, desc: "Comma-separated tags"
|
|
27
27
|
option :raw, type: :string
|
|
28
28
|
def create
|
|
@@ -37,7 +37,7 @@ module DiscourseCli
|
|
|
37
37
|
|
|
38
38
|
desc "update ID", "Update a topic"
|
|
39
39
|
option :title, type: :string
|
|
40
|
-
option :category, type: :
|
|
40
|
+
option :category, type: :numeric, desc: "Category ID"
|
|
41
41
|
option :raw, type: :string, desc: "Replace first post content (opens $EDITOR if not given and no other options)"
|
|
42
42
|
def update(id)
|
|
43
43
|
updated_anything = false
|
|
@@ -48,13 +48,7 @@ module DiscourseCli
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
if options[:category]
|
|
51
|
-
|
|
52
|
-
cat = cats.find { |c| c["slug"] == options[:category] || c["name"] == options[:category] }
|
|
53
|
-
unless cat
|
|
54
|
-
$stderr.puts "Category not found: #{options[:category]}"
|
|
55
|
-
exit 1
|
|
56
|
-
end
|
|
57
|
-
client.recategorize_topic(id.to_i, cat["id"])
|
|
51
|
+
client.recategorize_topic(id.to_i, options[:category])
|
|
58
52
|
updated_anything = true
|
|
59
53
|
end
|
|
60
54
|
|
data/lib/discourse_cli.rb
CHANGED
|
@@ -10,4 +10,5 @@ require_relative "discourse_cli/commands/config"
|
|
|
10
10
|
require_relative "discourse_cli/commands/categories"
|
|
11
11
|
require_relative "discourse_cli/commands/topics"
|
|
12
12
|
require_relative "discourse_cli/commands/posts"
|
|
13
|
+
require_relative "discourse_cli/commands/skill"
|
|
13
14
|
require_relative "discourse_cli/cli"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
def dsc_skill_agent_paths
|
|
4
|
+
%w[
|
|
5
|
+
~/.claude/skills/dsc
|
|
6
|
+
~/.codex/skills/dsc
|
|
7
|
+
~/.gemini/skills/dsc
|
|
8
|
+
].map { |p| File.expand_path(p) }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Gem.post_install do |installer|
|
|
12
|
+
next unless installer.spec.name == "discourse_cli_tool"
|
|
13
|
+
|
|
14
|
+
skill_source = File.join(installer.spec.gem_dir, "skill", "dsc")
|
|
15
|
+
next unless File.exist?(skill_source)
|
|
16
|
+
|
|
17
|
+
dsc_skill_agent_paths.each do |path|
|
|
18
|
+
next unless File.symlink?(path)
|
|
19
|
+
|
|
20
|
+
File.unlink(path)
|
|
21
|
+
File.symlink(skill_source, path)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Gem.pre_uninstall do |uninstaller|
|
|
26
|
+
next unless uninstaller.spec.name == "discourse_cli_tool"
|
|
27
|
+
|
|
28
|
+
skill_source = File.join(uninstaller.spec.gem_dir, "skill", "dsc")
|
|
29
|
+
|
|
30
|
+
dsc_skill_agent_paths.each do |path|
|
|
31
|
+
next unless File.symlink?(path) && File.readlink(path) == skill_source
|
|
32
|
+
|
|
33
|
+
File.unlink(path)
|
|
34
|
+
puts "Removed dsc skill from #{path}"
|
|
35
|
+
end
|
|
36
|
+
end
|
data/skill/dsc/SKILL.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dsc
|
|
3
|
+
description: Manage Discourse forums from the command line — create and manage topics, posts, and categories using the dsc CLI. Use when working with a Discourse forum, creating posts or topics, managing categories, or any Discourse content task.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dsc — Discourse CLI
|
|
7
|
+
|
|
8
|
+
`dsc` wraps the Discourse API. Install: `gem install discourse_cli_tool`
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
dsc config set --site mysite --host https://forum.example.com --api-key KEY --api-username admin
|
|
14
|
+
dsc config list
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Config precedence: CLI flags > `DISCOURSE_HOST` / `DISCOURSE_API_KEY` / `DISCOURSE_API_USERNAME` env vars > `~/.config/dsc/config.yml`
|
|
18
|
+
|
|
19
|
+
## Global flags
|
|
20
|
+
|
|
21
|
+
| Flag | Description |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `--site NAME` | Use a named site from config |
|
|
24
|
+
| `--host URL` | Override host |
|
|
25
|
+
| `--api-key KEY` | Override API key |
|
|
26
|
+
| `--api-username USER` | Override API username |
|
|
27
|
+
| `--json` | Output raw JSON (pipe to jq) |
|
|
28
|
+
| `--quiet` | Suppress output, exit code only |
|
|
29
|
+
|
|
30
|
+
## Raw content (topics and posts)
|
|
31
|
+
|
|
32
|
+
Commands that accept `--raw` resolve content in this order:
|
|
33
|
+
1. `--raw "inline content"` — use directly
|
|
34
|
+
2. No flag, stdin is piped — read from stdin
|
|
35
|
+
3. No flag, interactive terminal — open `$EDITOR`
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
dsc topics create --title "Hello" --raw "Content" # inline
|
|
39
|
+
echo "Content" | dsc topics create --title "Hello" # stdin
|
|
40
|
+
dsc topics create --title "Hello" # opens $EDITOR
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Command reference
|
|
44
|
+
|
|
45
|
+
- **[references/categories.md](references/categories.md)** — list, show, create, update, delete categories
|
|
46
|
+
- **[references/topics.md](references/topics.md)** — list, show, create, update, delete topics
|
|
47
|
+
- **[references/posts.md](references/posts.md)** — list, show, create, update, delete posts
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Categories
|
|
2
|
+
|
|
3
|
+
## List
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
dsc categories list
|
|
7
|
+
dsc categories list --json | jq '.[].name'
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Show
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
dsc categories show ID
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Create
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
dsc categories create --name "Announcements"
|
|
20
|
+
dsc categories create --name "Announcements" --color 0088CC --text-color FFFFFF
|
|
21
|
+
dsc categories create --name "Announcements" --description "Official announcements"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Options: `--name` (required), `--color HEX`, `--text-color HEX`, `--description TEXT`
|
|
25
|
+
|
|
26
|
+
## Update
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
dsc categories update ID --name "News"
|
|
30
|
+
dsc categories update ID --name "News" --color FF0000
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Options: `--name` (required), `--color HEX`, `--text-color HEX`, `--description TEXT`
|
|
34
|
+
|
|
35
|
+
## Delete
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
dsc categories delete ID
|
|
39
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Posts
|
|
2
|
+
|
|
3
|
+
## List
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
dsc posts list
|
|
7
|
+
dsc posts list --json
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Show
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
dsc posts show ID
|
|
14
|
+
dsc posts show ID --json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Create
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
dsc posts create --topic-id ID --raw "Reply content"
|
|
21
|
+
dsc posts create --topic-id ID # opens $EDITOR
|
|
22
|
+
echo "Reply" | dsc posts create --topic-id ID # from stdin
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Options: `--topic-id` (required), `--raw TEXT`
|
|
26
|
+
|
|
27
|
+
## Update
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
dsc posts update ID --raw "Edited content"
|
|
31
|
+
dsc posts update ID # opens $EDITOR
|
|
32
|
+
echo "New content" | dsc posts update ID # from stdin
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Options: `--raw TEXT`
|
|
36
|
+
|
|
37
|
+
## Delete
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
dsc posts delete ID
|
|
41
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Topics
|
|
2
|
+
|
|
3
|
+
## List
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
dsc topics list
|
|
7
|
+
dsc topics list --category announcements
|
|
8
|
+
dsc topics list --json | jq '.[].title'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Show
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
dsc topics show ID
|
|
15
|
+
dsc topics show ID --json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Create
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
dsc topics create --title "Hello World" --raw "Content here"
|
|
22
|
+
dsc topics create --title "Hello World" --category news
|
|
23
|
+
dsc topics create --title "Hello World" --tags "tag1,tag2"
|
|
24
|
+
dsc topics create --title "Hello World" # opens $EDITOR
|
|
25
|
+
echo "Content" | dsc topics create --title "Hello World" # from stdin
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Options: `--title` (required), `--raw TEXT`, `--category SLUG`, `--tags TAG1,TAG2`
|
|
29
|
+
|
|
30
|
+
## Update
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
dsc topics update ID --title "New Title"
|
|
34
|
+
dsc topics update ID --raw "New content" # edits first post, opens $EDITOR if omitted
|
|
35
|
+
dsc topics update ID --category new-slug
|
|
36
|
+
dsc topics update ID --title "New Title" --raw "New content"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Options: `--title TEXT`, `--raw TEXT`, `--category SLUG`
|
|
40
|
+
|
|
41
|
+
Note: `--category` looks up category by slug or name. Updating raw content edits the topic's first post.
|
|
42
|
+
|
|
43
|
+
When only `--title` or `--category` is given (no `--raw`, no piped stdin), content is left unchanged.
|
|
44
|
+
|
|
45
|
+
## Delete
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
dsc topics delete ID
|
|
49
|
+
```
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: discourse_cli_tool
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tim Case
|
|
@@ -108,11 +108,17 @@ files:
|
|
|
108
108
|
- lib/discourse_cli/commands/categories.rb
|
|
109
109
|
- lib/discourse_cli/commands/config.rb
|
|
110
110
|
- lib/discourse_cli/commands/posts.rb
|
|
111
|
+
- lib/discourse_cli/commands/skill.rb
|
|
111
112
|
- lib/discourse_cli/commands/topics.rb
|
|
112
113
|
- lib/discourse_cli/config.rb
|
|
113
114
|
- lib/discourse_cli/editor.rb
|
|
114
115
|
- lib/discourse_cli/formatter.rb
|
|
115
116
|
- lib/discourse_cli/version.rb
|
|
117
|
+
- lib/rubygems_plugin.rb
|
|
118
|
+
- skill/dsc/SKILL.md
|
|
119
|
+
- skill/dsc/references/categories.md
|
|
120
|
+
- skill/dsc/references/posts.md
|
|
121
|
+
- skill/dsc/references/topics.md
|
|
116
122
|
homepage: https://github.com/timcase/discourse-cli-tool
|
|
117
123
|
licenses:
|
|
118
124
|
- MIT
|
|
@@ -131,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
131
137
|
- !ruby/object:Gem::Version
|
|
132
138
|
version: '0'
|
|
133
139
|
requirements: []
|
|
134
|
-
rubygems_version: 4.0.
|
|
140
|
+
rubygems_version: 4.0.13
|
|
135
141
|
specification_version: 4
|
|
136
142
|
summary: CLI tool for managing Discourse forums from the command line
|
|
137
143
|
test_files: []
|