wikiwiki 0.6.0 → 0.7.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/CHANGELOG.md +22 -0
- data/README.ja.md +26 -2
- data/README.md +26 -2
- data/lib/wikiwiki/api.rb +4 -0
- data/lib/wikiwiki/cli/commands/attachment/delete.rb +0 -14
- data/lib/wikiwiki/cli/commands/attachment/put.rb +5 -10
- data/lib/wikiwiki/cli/commands/page/delete.rb +32 -0
- data/lib/wikiwiki/cli/commands/page/put.rb +4 -0
- data/lib/wikiwiki/cli.rb +1 -3
- data/lib/wikiwiki/version.rb +1 -1
- data/lib/wikiwiki/wiki.rb +15 -1
- data/lib/wikiwiki.rb +4 -0
- data/sig/wikiwiki/cli/commands/attachment.rbs +0 -9
- data/sig/wikiwiki/cli/commands/page.rbs +15 -0
- data/sig/wikiwiki/wiki.rbs +2 -0
- data/sig/wikiwiki.rbs +3 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 637f781de0cde55bb67c79d67624df9cc4255bac9e35e6b144fc6170d34b1d5d
|
|
4
|
+
data.tar.gz: 3155651131252d9e84260584fb3f7dcd6c21ffd52ac48fe16da2b605ac1948ae
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e5a8ce9a48d65aa95d7334289e5966a72228f9da9adc22799ac7ef63de802f463e882e5aec90e784d35f8411688ec24af6ddd9b9b14702a6988c61fc4d7a1357
|
|
7
|
+
data.tar.gz: 432bc7bfc745d96b4fcb00e296dbb3fb96ebe34a8bd9d6b06042054e633ca12a7863ce6a1d77bb638f81232258b5400102ed04fd02d65a8693735576bd0cea6c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.7.1] - 2025-11-03
|
|
4
|
+
|
|
5
|
+
### Documentation
|
|
6
|
+
|
|
7
|
+
- Added security notes to README about path traversal risks when using API-provided names in bulk download automation scripts
|
|
8
|
+
|
|
9
|
+
## [0.7.0] - 2025-11-03
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Page deletion support
|
|
14
|
+
- `Wiki#delete_page` method to delete pages
|
|
15
|
+
- `wikiwiki page delete` command in CLI
|
|
16
|
+
- Validation in `Wiki#update_page` and `wikiwiki page put` to prevent accidental deletion with empty content
|
|
17
|
+
- `ConflictError` exception class for HTTP 409 Conflict responses
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- `attachment put --force` behavior: attempts upload first, then deletes and retries on conflict (409 error)
|
|
22
|
+
- Previously: checked existence first, then deleted and uploaded
|
|
23
|
+
- Now: optimistic upload pattern eliminates Time-of-Check-Time-of-Use (TOCTOU) race conditions
|
|
24
|
+
|
|
3
25
|
## [0.6.0] - 2025-11-02
|
|
4
26
|
|
|
5
27
|
### Added
|
data/README.ja.md
CHANGED
|
@@ -87,6 +87,9 @@ wikiwiki page get FrontPage frontpage.txt
|
|
|
87
87
|
wikiwiki page put TestPage < content.txt
|
|
88
88
|
wikiwiki page put TestPage content.txt
|
|
89
89
|
|
|
90
|
+
# ページを削除
|
|
91
|
+
wikiwiki page delete TestPage
|
|
92
|
+
|
|
90
93
|
# 添付ファイル一覧
|
|
91
94
|
wikiwiki attachment list FrontPage
|
|
92
95
|
|
|
@@ -109,8 +112,9 @@ wikiwiki page get FrontPage existing.txt --force
|
|
|
109
112
|
wikiwiki attachment put FrontPage logo.png --force
|
|
110
113
|
|
|
111
114
|
# 注意: --force による添付ファイルの上書きはアトミックではありません。
|
|
112
|
-
#
|
|
113
|
-
#
|
|
115
|
+
# まずアップロードを試み、競合エラー(ファイルが既に存在)が発生した場合、
|
|
116
|
+
# 既存ファイルを削除してアップロードをリトライします。
|
|
117
|
+
# リトライに失敗した場合、添付ファイルは失われます。
|
|
114
118
|
|
|
115
119
|
# コマンドラインで認証情報を指定(環境変数より優先)
|
|
116
120
|
wikiwiki --wiki-id=your-wiki-id --password=your-password page list
|
|
@@ -126,6 +130,23 @@ wikiwiki page list --verbose
|
|
|
126
130
|
wikiwiki page list --debug
|
|
127
131
|
```
|
|
128
132
|
|
|
133
|
+
**一括ダウンロード時のセキュリティ注意:**
|
|
134
|
+
|
|
135
|
+
APIから取得したページ名や添付ファイル名を使用してページや添付ファイルを一括ダウンロードする自動化処理を行う場合、これらの名前にパストラバーサルシーケンス(例:`../../../etc/passwd`)が含まれている可能性があることに注意してください。ファイルパスとして使用する前に、必ず検証またはサニタイズを行ってください:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# 悪い例: シェルスクリプトでAPIから取得した名前を直接使用
|
|
139
|
+
for name in $(wikiwiki page list --json | jq -r '.[]'); do
|
|
140
|
+
wikiwiki page get "$name" "$name.txt" # 安全でない: nameに../が含まれる可能性
|
|
141
|
+
done
|
|
142
|
+
|
|
143
|
+
# 良い例: 自動化スクリプト内で名前をサニタイズ
|
|
144
|
+
for name in $(wikiwiki page list --json | jq -r '.[]'); do
|
|
145
|
+
safe_name=$(basename "$name") # ディレクトリ成分を削除
|
|
146
|
+
wikiwiki page get "$name" "$safe_name.txt"
|
|
147
|
+
done
|
|
148
|
+
```
|
|
149
|
+
|
|
129
150
|
### Rubyライブラリ
|
|
130
151
|
|
|
131
152
|
ライブラリを使用する基本的な例:
|
|
@@ -160,6 +181,9 @@ wiki.update_page(page_name: "TestPage", source: <<~SOURCE)
|
|
|
160
181
|
# Hello World
|
|
161
182
|
SOURCE
|
|
162
183
|
|
|
184
|
+
# ページを削除
|
|
185
|
+
wiki.delete_page(page_name: "TestPage")
|
|
186
|
+
|
|
163
187
|
# 添付ファイル名の一覧を取得
|
|
164
188
|
attachment_names = wiki.attachment_names(page_name: "FrontPage")
|
|
165
189
|
|
data/README.md
CHANGED
|
@@ -87,6 +87,9 @@ wikiwiki page get FrontPage frontpage.txt
|
|
|
87
87
|
wikiwiki page put TestPage < content.txt
|
|
88
88
|
wikiwiki page put TestPage content.txt
|
|
89
89
|
|
|
90
|
+
# Delete page
|
|
91
|
+
wikiwiki page delete TestPage
|
|
92
|
+
|
|
90
93
|
# List attachments
|
|
91
94
|
wikiwiki attachment list FrontPage
|
|
92
95
|
|
|
@@ -109,8 +112,9 @@ wikiwiki page get FrontPage existing.txt --force
|
|
|
109
112
|
wikiwiki attachment put FrontPage logo.png --force
|
|
110
113
|
|
|
111
114
|
# Note: Attachment overwrite with --force is not atomic.
|
|
112
|
-
#
|
|
113
|
-
#
|
|
115
|
+
# First attempts to upload; if it fails due to conflict (file exists),
|
|
116
|
+
# deletes the existing file and retries the upload.
|
|
117
|
+
# If retry fails, the attachment will be lost.
|
|
114
118
|
|
|
115
119
|
# Authentication via command line (overrides environment variables)
|
|
116
120
|
wikiwiki --wiki-id=your-wiki-id --password=your-password page list
|
|
@@ -126,6 +130,23 @@ wikiwiki page list --verbose
|
|
|
126
130
|
wikiwiki page list --debug
|
|
127
131
|
```
|
|
128
132
|
|
|
133
|
+
**Security Note for Bulk Downloads:**
|
|
134
|
+
|
|
135
|
+
When automating bulk downloads of pages or attachments using page/attachment names from the API, be aware that these names may contain path traversal sequences (e.g., `../../../etc/passwd`). Always validate or sanitize names before using them as file paths:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Bad: Direct use of API-provided names in shell scripts
|
|
139
|
+
for name in $(wikiwiki page list --json | jq -r '.[]'); do
|
|
140
|
+
wikiwiki page get "$name" "$name.txt" # UNSAFE if name contains ../
|
|
141
|
+
done
|
|
142
|
+
|
|
143
|
+
# Good: Sanitize names in your automation script
|
|
144
|
+
for name in $(wikiwiki page list --json | jq -r '.[]'); do
|
|
145
|
+
safe_name=$(basename "$name") # Remove directory components
|
|
146
|
+
wikiwiki page get "$name" "$safe_name.txt"
|
|
147
|
+
done
|
|
148
|
+
```
|
|
149
|
+
|
|
129
150
|
### Ruby Library
|
|
130
151
|
|
|
131
152
|
Basic example using the library:
|
|
@@ -160,6 +181,9 @@ wiki.update_page(page_name: "TestPage", source: <<~SOURCE)
|
|
|
160
181
|
# Hello World
|
|
161
182
|
SOURCE
|
|
162
183
|
|
|
184
|
+
# Delete a page
|
|
185
|
+
wiki.delete_page(page_name: "TestPage")
|
|
186
|
+
|
|
163
187
|
# List attachment names
|
|
164
188
|
attachment_names = wiki.attachment_names(page_name: "FrontPage")
|
|
165
189
|
|
data/lib/wikiwiki/api.rb
CHANGED
|
@@ -62,6 +62,7 @@ module Wikiwiki
|
|
|
62
62
|
# @param source [String] the page source content
|
|
63
63
|
# @return [void]
|
|
64
64
|
# @raise [Error] if request fails
|
|
65
|
+
# @note Passing an empty string as source will delete the page
|
|
65
66
|
def put_page(encoded_page_name:, source:)
|
|
66
67
|
uri = BASE_URL + "/#{wiki_id}/page/#{encoded_page_name}"
|
|
67
68
|
response = request(:put, uri, body: {"source" => source})
|
|
@@ -171,6 +172,7 @@ module Wikiwiki
|
|
|
171
172
|
# @return [Hash] parsed response body
|
|
172
173
|
# @raise [AuthenticationError] if authentication fails (401)
|
|
173
174
|
# @raise [ResourceNotFoundError] if resource not found (404)
|
|
175
|
+
# @raise [ConflictError] if conflict occurs (409)
|
|
174
176
|
# @raise [ServerError] if server error (5xx)
|
|
175
177
|
# @raise [APIError] if other API request fails
|
|
176
178
|
private def parse_json_response(response)
|
|
@@ -181,6 +183,8 @@ module Wikiwiki
|
|
|
181
183
|
raise AuthenticationError, message
|
|
182
184
|
when 404
|
|
183
185
|
raise ResourceNotFoundError, message
|
|
186
|
+
when 409
|
|
187
|
+
raise ConflictError, message
|
|
184
188
|
when 500..599
|
|
185
189
|
raise ServerError, message
|
|
186
190
|
else
|
|
@@ -21,24 +21,10 @@ module Wikiwiki
|
|
|
21
21
|
def call(page_name:, file_name:, out: $stdout, err: $stderr, **)
|
|
22
22
|
wiki = create_wiki(out:, err:, **)
|
|
23
23
|
|
|
24
|
-
# Check if page exists first
|
|
25
|
-
unless page_exists?(wiki, page_name:)
|
|
26
|
-
raise ArgumentError, "Page '#{page_name}' does not exist"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Check if attachment exists
|
|
30
|
-
unless attachment_exists?(wiki, page_name:, attachment_name: file_name)
|
|
31
|
-
raise ArgumentError, "Attachment '#{file_name}' does not exist on page '#{page_name}'"
|
|
32
|
-
end
|
|
33
|
-
|
|
34
24
|
wiki.delete_attachment(page_name:, attachment_name: file_name)
|
|
35
25
|
|
|
36
26
|
say("Attachment '#{file_name}' deleted from page '#{page_name}'", out:, **)
|
|
37
27
|
end
|
|
38
|
-
|
|
39
|
-
private def page_exists?(wiki, page_name:) = wiki.page_names.include?(page_name)
|
|
40
|
-
|
|
41
|
-
private def attachment_exists?(wiki, page_name:, attachment_name:) = wiki.attachment_names(page_name:).include?(attachment_name)
|
|
42
28
|
end
|
|
43
29
|
end
|
|
44
30
|
|
|
@@ -35,22 +35,17 @@ module Wikiwiki
|
|
|
35
35
|
raise ArgumentError, "File size (#{content.bytesize} bytes) exceeds maximum allowed size (#{MAX_ATTACHMENT_SIZE} bytes / 512 KiB)"
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
begin
|
|
39
|
+
wiki.add_attachment(page_name:, attachment_name:, content:)
|
|
40
|
+
rescue ConflictError
|
|
39
41
|
raise ArgumentError, "Attachment '#{attachment_name}' already exists. Use --force to overwrite." unless force
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
rescue ResourceNotFoundError
|
|
44
|
-
# Already deleted by another process, continue
|
|
45
|
-
end
|
|
43
|
+
wiki.delete_attachment(page_name:, attachment_name:)
|
|
44
|
+
retry
|
|
46
45
|
end
|
|
47
46
|
|
|
48
|
-
wiki.add_attachment(page_name:, attachment_name:, content:)
|
|
49
|
-
|
|
50
47
|
say("Attachment '#{attachment_name}' uploaded to page '#{page_name}'", out:, **)
|
|
51
48
|
end
|
|
52
|
-
|
|
53
|
-
private def attachment_exists?(wiki, page_name:, attachment_name:) = wiki.attachment_names(page_name:).include?(attachment_name)
|
|
54
49
|
end
|
|
55
50
|
end
|
|
56
51
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wikiwiki
|
|
4
|
+
class CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Page
|
|
7
|
+
# Delete a page
|
|
8
|
+
class Delete < Base
|
|
9
|
+
desc "Delete a page"
|
|
10
|
+
|
|
11
|
+
argument :page_name, required: true, desc: "Page name"
|
|
12
|
+
|
|
13
|
+
# Execute the delete command
|
|
14
|
+
#
|
|
15
|
+
# @param page_name [String] name of the page to delete
|
|
16
|
+
# @param out [IO] output stream
|
|
17
|
+
# @param err [IO] error stream
|
|
18
|
+
# @return [void]
|
|
19
|
+
def call(page_name:, out: $stdout, err: $stderr, **)
|
|
20
|
+
wiki = create_wiki(out:, err:, **)
|
|
21
|
+
|
|
22
|
+
wiki.delete_page(page_name:)
|
|
23
|
+
|
|
24
|
+
say("Page '#{page_name}' deleted successfully", out:, **)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
register "page delete", Page::Delete
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -18,6 +18,8 @@ module Wikiwiki
|
|
|
18
18
|
# @param out [IO] output stream
|
|
19
19
|
# @param err [IO] error stream
|
|
20
20
|
# @return [void]
|
|
21
|
+
# @raise [ArgumentError] if source content is empty
|
|
22
|
+
# @note To delete a page, use `wikiwiki page delete` instead
|
|
21
23
|
def call(page_name:, input_file: nil, out: $stdout, err: $stderr, **)
|
|
22
24
|
wiki = create_wiki(out:, err:, **)
|
|
23
25
|
|
|
@@ -27,6 +29,8 @@ module Wikiwiki
|
|
|
27
29
|
$stdin.read
|
|
28
30
|
end
|
|
29
31
|
|
|
32
|
+
raise ArgumentError, "Page source must not be empty. Use 'wikiwiki page delete' to delete a page." if source.empty?
|
|
33
|
+
|
|
30
34
|
wiki.update_page(page_name:, source:)
|
|
31
35
|
|
|
32
36
|
say("Page '#{page_name}' updated successfully", out:, **)
|
data/lib/wikiwiki/cli.rb
CHANGED
|
@@ -9,12 +9,10 @@ module Wikiwiki
|
|
|
9
9
|
# Provides commands for managing wiki pages and attachments through the terminal.
|
|
10
10
|
# Supports authentication via API key or password, with configurable logging and output modes.
|
|
11
11
|
class CLI
|
|
12
|
-
#
|
|
12
|
+
# Initialize the CLI with output streams
|
|
13
13
|
#
|
|
14
|
-
# @param argv [Array<String>] command-line arguments
|
|
15
14
|
# @param out [IO] standard output (defaults to $stdout)
|
|
16
15
|
# @param err [IO] error output (defaults to $stderr)
|
|
17
|
-
# @return [Integer] exit code (0 for success, 1 for error)
|
|
18
16
|
def initialize(out: $stdout, err: $stderr)
|
|
19
17
|
@out = out
|
|
20
18
|
@err = err
|
data/lib/wikiwiki/version.rb
CHANGED
data/lib/wikiwiki/wiki.rb
CHANGED
|
@@ -70,14 +70,28 @@ module Wikiwiki
|
|
|
70
70
|
# Updates a page with new content
|
|
71
71
|
#
|
|
72
72
|
# @param page_name [String] the name of the page to update
|
|
73
|
-
# @param source [String] the new page source content
|
|
73
|
+
# @param source [String] the new page source content (must not be empty)
|
|
74
74
|
# @return [void]
|
|
75
|
+
# @raise [ArgumentError] if source is empty
|
|
75
76
|
# @raise [Wikiwiki::Error] if the update fails
|
|
77
|
+
# @note To delete a page, use {#delete_page} instead
|
|
76
78
|
def update_page(page_name:, source:)
|
|
79
|
+
raise ArgumentError, "Page source must not be empty. Use delete_page to delete a page." if source.empty?
|
|
80
|
+
|
|
77
81
|
encoded_page_name = ERB::Util.url_encode(page_name)
|
|
78
82
|
api.put_page(encoded_page_name:, source:)
|
|
79
83
|
end
|
|
80
84
|
|
|
85
|
+
# Deletes a page
|
|
86
|
+
#
|
|
87
|
+
# @param page_name [String] the name of the page to delete
|
|
88
|
+
# @return [void]
|
|
89
|
+
# @raise [Wikiwiki::Error] if the deletion fails
|
|
90
|
+
def delete_page(page_name:)
|
|
91
|
+
encoded_page_name = ERB::Util.url_encode(page_name)
|
|
92
|
+
api.put_page(encoded_page_name:, source: "")
|
|
93
|
+
end
|
|
94
|
+
|
|
81
95
|
# Retrieves attachment file names on a page
|
|
82
96
|
#
|
|
83
97
|
# @param page_name [String] the name of the page
|
data/lib/wikiwiki.rb
CHANGED
|
@@ -32,6 +32,10 @@ module Wikiwiki
|
|
|
32
32
|
# Raised when HTTP status is 404
|
|
33
33
|
class ResourceNotFoundError < APIError; end
|
|
34
34
|
|
|
35
|
+
# Conflict error
|
|
36
|
+
# Raised when HTTP status is 409
|
|
37
|
+
class ConflictError < APIError; end
|
|
38
|
+
|
|
35
39
|
# Server error
|
|
36
40
|
# Raised when HTTP status is 5xx
|
|
37
41
|
class ServerError < APIError; end
|
|
@@ -65,10 +65,6 @@ module Wikiwiki
|
|
|
65
65
|
?verbose: bool,
|
|
66
66
|
?debug: bool
|
|
67
67
|
) -> void
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
def attachment_exists?: (Wiki wiki, page_name: String, attachment_name: String) -> bool
|
|
72
68
|
end
|
|
73
69
|
|
|
74
70
|
class Delete < Base
|
|
@@ -84,11 +80,6 @@ module Wikiwiki
|
|
|
84
80
|
?verbose: bool,
|
|
85
81
|
?debug: bool
|
|
86
82
|
) -> void
|
|
87
|
-
|
|
88
|
-
private
|
|
89
|
-
|
|
90
|
-
def page_exists?: (Wiki wiki, page_name: String) -> bool
|
|
91
|
-
def attachment_exists?: (Wiki wiki, page_name: String, attachment_name: String) -> bool
|
|
92
83
|
end
|
|
93
84
|
end
|
|
94
85
|
end
|
|
@@ -61,6 +61,21 @@ module Wikiwiki
|
|
|
61
61
|
?debug: bool
|
|
62
62
|
) -> void
|
|
63
63
|
end
|
|
64
|
+
|
|
65
|
+
class Delete < Base
|
|
66
|
+
def call: (
|
|
67
|
+
page_name: String,
|
|
68
|
+
?out: IO,
|
|
69
|
+
?err: IO,
|
|
70
|
+
?wiki_id: String?,
|
|
71
|
+
?api_key_id: String?,
|
|
72
|
+
?secret: String?,
|
|
73
|
+
?password: String?,
|
|
74
|
+
?token: String?,
|
|
75
|
+
?verbose: bool,
|
|
76
|
+
?debug: bool
|
|
77
|
+
) -> void
|
|
78
|
+
end
|
|
64
79
|
end
|
|
65
80
|
end
|
|
66
81
|
end
|
data/sig/wikiwiki/wiki.rbs
CHANGED
|
@@ -14,6 +14,8 @@ module Wikiwiki
|
|
|
14
14
|
|
|
15
15
|
def update_page: (page_name: String, source: String) -> void
|
|
16
16
|
|
|
17
|
+
def delete_page: (page_name: String) -> void
|
|
18
|
+
|
|
17
19
|
def attachment_names: (page_name: String) -> Array[String]
|
|
18
20
|
|
|
19
21
|
def attachment: (page_name: String, attachment_name: String, ?rev: String?) -> Attachment
|
data/sig/wikiwiki.rbs
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wikiwiki
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OZAWA Sakuro
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-11-
|
|
11
|
+
date: 2025-11-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -95,6 +95,7 @@ files:
|
|
|
95
95
|
- lib/wikiwiki/cli/commands/attachment/show.rb
|
|
96
96
|
- lib/wikiwiki/cli/commands/auth.rb
|
|
97
97
|
- lib/wikiwiki/cli/commands/base.rb
|
|
98
|
+
- lib/wikiwiki/cli/commands/page/delete.rb
|
|
98
99
|
- lib/wikiwiki/cli/commands/page/get.rb
|
|
99
100
|
- lib/wikiwiki/cli/commands/page/list.rb
|
|
100
101
|
- lib/wikiwiki/cli/commands/page/put.rb
|