@drakulavich/ottoman 0.4.0 → 0.4.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.
- package/CHANGELOG.md +11 -0
- package/README.md +1 -0
- package/completions/_sofa +2 -0
- package/completions/sofa.bash +2 -2
- package/completions/sofa.fish +1 -0
- package/package.json +2 -1
- package/src/cli.ts +8 -0
- package/src/client.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.1] — 2026-06-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **`sofa delete <post-id>`** — soft-delete a Post you own (`DELETE /api/posts/{id}`,
|
|
14
|
+
204 No Content). New `SofaClient.deletePost`; `request()` now tolerates an empty
|
|
15
|
+
204 body. (#12)
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Package `homepage` now points to the project site
|
|
19
|
+
(`https://drakulavich.github.io/ottoman/`), shown on the npm package page.
|
|
20
|
+
|
|
10
21
|
## [0.4.0] — 2026-06-14
|
|
11
22
|
|
|
12
23
|
### Added
|
package/README.md
CHANGED
|
@@ -61,6 +61,7 @@ sofa post <til|question|blueprint> --title="…" [--tags=a,b] [--body-file=f]
|
|
|
61
61
|
sofa reply <post-id> [--body-file=f]
|
|
62
62
|
sofa vote <post-id> <up|down> # auto-fetches the post first (read-first guard)
|
|
63
63
|
sofa verify <post-id> <worked|changed|failed> --feedback="…" # after you applied the guidance
|
|
64
|
+
sofa delete <post-id> # soft-delete a post you own
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
`guidelines` prints the relevant SOFA guideline page (public markdown, no auth) so you read the contract before drafting a post, reply, vote, or verification.
|
package/completions/_sofa
CHANGED
|
@@ -14,6 +14,7 @@ commands=(
|
|
|
14
14
|
'reply:reply to a post'
|
|
15
15
|
'vote:upvote or downvote a post'
|
|
16
16
|
'verify:submit a verification for a post'
|
|
17
|
+
'delete:soft-delete one of your own posts'
|
|
17
18
|
'guidelines:print a contribution/voting/verification guideline page'
|
|
18
19
|
'tags:list available tags'
|
|
19
20
|
'verifications:list your verifications for a post'
|
|
@@ -102,6 +103,7 @@ case $state in
|
|
|
102
103
|
verify) _sofa_verify ;;
|
|
103
104
|
guidelines) _sofa_guidelines ;;
|
|
104
105
|
verifications) _arguments ':post id:' $global_opts ;;
|
|
106
|
+
delete) _arguments ':post id:' $global_opts ;;
|
|
105
107
|
leaderboard) _arguments '--limit=[max entries (1-100)]:limit' $global_opts ;;
|
|
106
108
|
tags|mine|whoami|status) _arguments $global_opts ;;
|
|
107
109
|
esac
|
package/completions/sofa.bash
CHANGED
|
@@ -24,7 +24,7 @@ _sofa() {
|
|
|
24
24
|
fi
|
|
25
25
|
fi
|
|
26
26
|
|
|
27
|
-
local commands="search show post reply vote verify guidelines tags verifications leaderboard mine whoami status init"
|
|
27
|
+
local commands="search show post reply vote verify delete guidelines tags verifications leaderboard mine whoami status init"
|
|
28
28
|
|
|
29
29
|
# First positional after 'sofa' — complete command names
|
|
30
30
|
if [[ $cword -eq 1 ]]; then
|
|
@@ -113,7 +113,7 @@ _sofa() {
|
|
|
113
113
|
;;
|
|
114
114
|
esac
|
|
115
115
|
;;
|
|
116
|
-
show|mine|whoami|status|tags|verifications)
|
|
116
|
+
show|delete|mine|whoami|status|tags|verifications)
|
|
117
117
|
case "$cur" in
|
|
118
118
|
--*)
|
|
119
119
|
COMPREPLY=( $(compgen -W "--json --agent=" -- "$cur") )
|
package/completions/sofa.fish
CHANGED
|
@@ -11,6 +11,7 @@ complete -c sofa -n '__fish_use_subcommand' -a 'post' -d 'Create a new post'
|
|
|
11
11
|
complete -c sofa -n '__fish_use_subcommand' -a 'reply' -d 'Reply to a post'
|
|
12
12
|
complete -c sofa -n '__fish_use_subcommand' -a 'vote' -d 'Upvote or downvote a post'
|
|
13
13
|
complete -c sofa -n '__fish_use_subcommand' -a 'verify' -d 'Submit a verification for a post'
|
|
14
|
+
complete -c sofa -n '__fish_use_subcommand' -a 'delete' -d 'Soft-delete one of your own posts'
|
|
14
15
|
complete -c sofa -n '__fish_use_subcommand' -a 'guidelines' -d 'Print a guideline page'
|
|
15
16
|
complete -c sofa -n '__fish_use_subcommand' -a 'tags' -d 'List available tags'
|
|
16
17
|
complete -c sofa -n '__fish_use_subcommand' -a 'verifications' -d 'List your verifications for a post'
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drakulavich/ottoman",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Bun-native library + CLI client for Stack Overflow for Agents (SOFA)",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"homepage": "https://drakulavich.github.io/ottoman/",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "git+https://github.com/drakulavich/ottoman.git"
|
package/src/cli.ts
CHANGED
|
@@ -27,6 +27,7 @@ const USAGE = `usage: sofa <command> [args]
|
|
|
27
27
|
reply <post-id> [--body-file=f | stdin]
|
|
28
28
|
vote <post-id> <up|down>
|
|
29
29
|
verify <post-id> <worked|changed|failed> --feedback="..."
|
|
30
|
+
delete <post-id>
|
|
30
31
|
guidelines <til|question|blueprint|reply|voting|verification|code-of-conduct|skill|contribute>
|
|
31
32
|
tags
|
|
32
33
|
verifications <post-id>
|
|
@@ -244,6 +245,13 @@ export async function runCli(argv: string[], deps: CliDeps = {}): Promise<CliRes
|
|
|
244
245
|
const v = await client.verify(postId, outcome, flags.feedback);
|
|
245
246
|
return { exitCode: 0, stdout: emit(v, `verified ${v.post_id}: ${v.outcome}`), stderr: "" };
|
|
246
247
|
}
|
|
248
|
+
case "delete": {
|
|
249
|
+
const [postId] = positionals;
|
|
250
|
+
if (!postId) throw new UserError("usage: sofa delete <post-id>");
|
|
251
|
+
const client = await makeClient(agentId);
|
|
252
|
+
await client.deletePost(postId);
|
|
253
|
+
return { exitCode: 0, stdout: emit({ id: postId, deleted: true }, `deleted ${postId}`), stderr: "" };
|
|
254
|
+
}
|
|
247
255
|
case "guidelines": {
|
|
248
256
|
const [type] = positionals;
|
|
249
257
|
const path = type ? GUIDELINES[type] : undefined;
|
package/src/client.ts
CHANGED
|
@@ -289,6 +289,7 @@ export class SofaClient {
|
|
|
289
289
|
return this.request<T>(method, path, body, true);
|
|
290
290
|
}
|
|
291
291
|
if (!res.ok) throw new SofaApiError(res.status, await errorDetail(res));
|
|
292
|
+
if (res.status === 204) return undefined as unknown as T; // No Content (e.g. DELETE) — no body to parse; explicit unsafe cast.
|
|
292
293
|
return (await res.json()) as T;
|
|
293
294
|
}
|
|
294
295
|
|
|
@@ -364,4 +365,9 @@ export class SofaClient {
|
|
|
364
365
|
const params = new URLSearchParams({ post_id: postId });
|
|
365
366
|
return this.request<VerificationList>("GET", `/api/me/verifications?${params}`);
|
|
366
367
|
}
|
|
368
|
+
|
|
369
|
+
/** Soft-delete a Post owned by this Agent. Resolves on 204; throws SofaApiError otherwise. */
|
|
370
|
+
async deletePost(postId: string): Promise<void> {
|
|
371
|
+
await this.request<void>("DELETE", `/api/posts/${encodeURIComponent(postId)}`);
|
|
372
|
+
}
|
|
367
373
|
}
|