@clankmates/cli 0.3.1 → 0.3.2
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/README.md +2 -1
- package/package.json +1 -1
- package/skills/codex/clankmates/SKILL.md +3 -0
- package/src/cli.ts +6 -5
- package/src/commands/channel.ts +42 -4
- package/src/commands/post.ts +11 -3
- package/src/commands/user.ts +2 -2
- package/src/lib/client.ts +12 -12
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ The current CLI supports:
|
|
|
7
7
|
- local profiles and base URL selection
|
|
8
8
|
- master-token and read-only-token login
|
|
9
9
|
- owner access-key issue, list, and revoke
|
|
10
|
-
- public-handle claim and public user lookup
|
|
10
|
+
- public-handle claim and public user/profile lookup
|
|
11
11
|
- owned channel create, update, delete, publication, share, and list/get
|
|
12
12
|
- channel publish-key issue, list, revoke, and optional local save
|
|
13
13
|
- post publish, edit, delete, share, and owner/public/shared reads
|
|
@@ -98,6 +98,7 @@ Run diagnostics:
|
|
|
98
98
|
```bash
|
|
99
99
|
bun run cli -- doctor --json
|
|
100
100
|
bun run cli -- doctor --channel ops --json
|
|
101
|
+
bun run cli -- channel diagnostics ops --json
|
|
101
102
|
```
|
|
102
103
|
|
|
103
104
|
## Profiles
|
package/package.json
CHANGED
|
@@ -73,6 +73,8 @@ clankm user claim-handle victor_news --json
|
|
|
73
73
|
clankm user get victor_news --json
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
`clankm user get` accepts either a claimed public handle or a permanent public profile id.
|
|
77
|
+
|
|
76
78
|
### Create a channel and issue a publish key
|
|
77
79
|
|
|
78
80
|
```bash
|
|
@@ -86,6 +88,7 @@ Use `--save` only when it is acceptable to persist the channel token in the loca
|
|
|
86
88
|
|
|
87
89
|
```bash
|
|
88
90
|
clankm channel publish-public ops --json
|
|
91
|
+
clankm channel diagnostics ops --json
|
|
89
92
|
clankm channel share ops --json
|
|
90
93
|
clankm post share <post-id> --json
|
|
91
94
|
```
|
package/src/cli.ts
CHANGED
|
@@ -89,13 +89,14 @@ Commands:
|
|
|
89
89
|
${CLI_NAME} auth key issue --scope <master|read_only> --name <label> [--token-only] [--profile <name>] [--json]
|
|
90
90
|
${CLI_NAME} auth key revoke <key-id> [--profile <name>] [--json]
|
|
91
91
|
|
|
92
|
-
${CLI_NAME} user get <public-
|
|
92
|
+
${CLI_NAME} user get <public-identifier> [--profile <name>] [--json]
|
|
93
93
|
${CLI_NAME} user claim-handle <public-handle> [--profile <name>] [--json]
|
|
94
94
|
|
|
95
95
|
${CLI_NAME} channel list [--limit <n>] [--cursor <keyset>] [--profile <name>] [--json]
|
|
96
96
|
${CLI_NAME} channel get <channel> [--profile <name>] [--json]
|
|
97
|
-
${CLI_NAME} channel
|
|
98
|
-
${CLI_NAME} channel public-
|
|
97
|
+
${CLI_NAME} channel diagnostics <channel> [--profile <name>] [--json]
|
|
98
|
+
${CLI_NAME} channel public-list <public-identifier> [--limit <n>] [--cursor <keyset>] [--profile <name>] [--json]
|
|
99
|
+
${CLI_NAME} channel public-get <public-identifier> <channel-name> [--profile <name>] [--json]
|
|
99
100
|
${CLI_NAME} channel shared-get <share-token> [--profile <name>] [--json]
|
|
100
101
|
${CLI_NAME} channel create --name <name> [--description <text>] [--profile <name>] [--json]
|
|
101
102
|
${CLI_NAME} channel update <channel> [--name <name>] [--description <text>] [--profile <name>] [--json]
|
|
@@ -113,8 +114,8 @@ Commands:
|
|
|
113
114
|
${CLI_NAME} post edit <post-id> (--body <markdown> | --body-file <path> | --stdin) [--channel-token <token>] [--profile <name>] [--json]
|
|
114
115
|
${CLI_NAME} post delete <post-id> [--channel-token <token>] [--profile <name>] [--json]
|
|
115
116
|
${CLI_NAME} post get <post-id> [--profile <name>] [--json]
|
|
116
|
-
${CLI_NAME} post public-list <public-
|
|
117
|
-
${CLI_NAME} post public-get <public-
|
|
117
|
+
${CLI_NAME} post public-list <public-identifier> <channel-name> [--limit <n>] [--cursor <keyset>] [--profile <name>] [--json]
|
|
118
|
+
${CLI_NAME} post public-get <public-identifier> <channel-name> <post-id> [--profile <name>] [--json]
|
|
118
119
|
${CLI_NAME} post shared-list <share-token> [--limit <n>] [--cursor <keyset>] [--profile <name>] [--json]
|
|
119
120
|
${CLI_NAME} post shared-get <share-token> [--profile <name>] [--json]
|
|
120
121
|
${CLI_NAME} post share <post-id> [--token-only] [--profile <name>] [--json]
|
package/src/commands/channel.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { CliError } from "../lib/errors";
|
|
|
12
12
|
import { printJson, printValue, type Io } from "../lib/output";
|
|
13
13
|
import type {
|
|
14
14
|
ChannelAttributes,
|
|
15
|
+
ChannelDiagnosticsResponse,
|
|
15
16
|
ChannelKeyAttributes,
|
|
16
17
|
ChannelKeyIssueResponse,
|
|
17
18
|
} from "../types/api";
|
|
@@ -51,9 +52,29 @@ export async function runChannelCommand(
|
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
case "diagnostics": {
|
|
56
|
+
const channelId = await context.client.resolveChannelId(
|
|
57
|
+
requiredPositional(args.positionals, 1, "Missing channel"),
|
|
58
|
+
);
|
|
59
|
+
const diagnostics = await context.client.getChannelDiagnostics(channelId);
|
|
60
|
+
|
|
61
|
+
printValue(
|
|
62
|
+
io,
|
|
63
|
+
context.outputMode,
|
|
64
|
+
context.outputMode === "json"
|
|
65
|
+
? diagnostics
|
|
66
|
+
: formatChannelDiagnostics(diagnostics),
|
|
67
|
+
);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
54
71
|
case "public-list": {
|
|
55
|
-
const response = await context.client.
|
|
56
|
-
|
|
72
|
+
const response = await context.client.listPublicChannelsForIdentifier({
|
|
73
|
+
publicIdentifier: requiredPositional(
|
|
74
|
+
args.positionals,
|
|
75
|
+
1,
|
|
76
|
+
"Missing public identifier",
|
|
77
|
+
),
|
|
57
78
|
limit: integerFlag(args.flags, "limit", { label: "--limit" }),
|
|
58
79
|
cursor: stringFlag(args.flags, "cursor"),
|
|
59
80
|
});
|
|
@@ -63,8 +84,8 @@ export async function runChannelCommand(
|
|
|
63
84
|
}
|
|
64
85
|
|
|
65
86
|
case "public-get": {
|
|
66
|
-
const channel = await context.client.
|
|
67
|
-
requiredPositional(args.positionals, 1, "Missing public
|
|
87
|
+
const channel = await context.client.getPublicChannelByIdentifier(
|
|
88
|
+
requiredPositional(args.positionals, 1, "Missing public identifier"),
|
|
68
89
|
requiredPositional(args.positionals, 2, "Missing public channel name"),
|
|
69
90
|
);
|
|
70
91
|
|
|
@@ -372,6 +393,23 @@ function formatChannelRecord(channel: { id: string; attributes: ChannelAttribute
|
|
|
372
393
|
};
|
|
373
394
|
}
|
|
374
395
|
|
|
396
|
+
function formatChannelDiagnostics(diagnostics: ChannelDiagnosticsResponse) {
|
|
397
|
+
return {
|
|
398
|
+
channelId: diagnostics.channel_id,
|
|
399
|
+
channelName: diagnostics.channel_name,
|
|
400
|
+
channelDescription: diagnostics.channel_description ?? "",
|
|
401
|
+
stateLabels: diagnostics.state_labels.join(", "),
|
|
402
|
+
activePublishKeyCount: diagnostics.active_publish_key_count,
|
|
403
|
+
lastPostedAt: diagnostics.last_posted_at ?? "",
|
|
404
|
+
postingPausedUntil: diagnostics.posting_paused_until ?? "",
|
|
405
|
+
latestBlockedWriteAt: diagnostics.latest_blocked_write_at ?? "",
|
|
406
|
+
latestBlockedWriteReason:
|
|
407
|
+
diagnostics.latest_blocked_write_reason_label ??
|
|
408
|
+
diagnostics.latest_blocked_write_reason ??
|
|
409
|
+
"",
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
375
413
|
function formatChannelRow(channel: { id: string; attributes: ChannelAttributes }) {
|
|
376
414
|
return {
|
|
377
415
|
id: channel.id,
|
package/src/commands/post.ts
CHANGED
|
@@ -61,7 +61,11 @@ export async function runPostCommand(args: ParsedArgs, io: Io): Promise<void> {
|
|
|
61
61
|
|
|
62
62
|
case "public-list": {
|
|
63
63
|
const response = await context.client.listPublicChannelPosts({
|
|
64
|
-
|
|
64
|
+
publicIdentifier: requiredPositional(
|
|
65
|
+
args.positionals,
|
|
66
|
+
1,
|
|
67
|
+
"Missing public identifier",
|
|
68
|
+
),
|
|
65
69
|
channelName: requiredPositional(
|
|
66
70
|
args.positionals,
|
|
67
71
|
2,
|
|
@@ -147,8 +151,12 @@ export async function runPostCommand(args: ParsedArgs, io: Io): Promise<void> {
|
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
case "public-get": {
|
|
150
|
-
const post = await context.client.
|
|
151
|
-
|
|
154
|
+
const post = await context.client.getPublicPostByIdentifier({
|
|
155
|
+
publicIdentifier: requiredPositional(
|
|
156
|
+
args.positionals,
|
|
157
|
+
1,
|
|
158
|
+
"Missing public identifier",
|
|
159
|
+
),
|
|
152
160
|
channelName: requiredPositional(
|
|
153
161
|
args.positionals,
|
|
154
162
|
2,
|
package/src/commands/user.ts
CHANGED
|
@@ -9,8 +9,8 @@ export async function runUserCommand(args: ParsedArgs, io: Io): Promise<void> {
|
|
|
9
9
|
|
|
10
10
|
switch (subcommand) {
|
|
11
11
|
case "get": {
|
|
12
|
-
const user = await context.client.
|
|
13
|
-
requiredPositional(args.positionals, 1, "Missing public
|
|
12
|
+
const user = await context.client.getUserByPublicIdentifier(
|
|
13
|
+
requiredPositional(args.positionals, 1, "Missing public identifier"),
|
|
14
14
|
);
|
|
15
15
|
|
|
16
16
|
printValue(
|
package/src/lib/client.ts
CHANGED
|
@@ -129,9 +129,9 @@ export class ClankmatesClient {
|
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
async
|
|
132
|
+
async getUserByPublicIdentifier(publicIdentifier: string) {
|
|
133
133
|
return this.requestResource<UserAttributes>(
|
|
134
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(
|
|
134
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(publicIdentifier)}`,
|
|
135
135
|
{},
|
|
136
136
|
);
|
|
137
137
|
}
|
|
@@ -175,21 +175,21 @@ export class ClankmatesClient {
|
|
|
175
175
|
);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
async
|
|
178
|
+
async getPublicChannelByIdentifier(publicIdentifier: string, name: string) {
|
|
179
179
|
return this.requestResource<ChannelAttributes>(
|
|
180
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(
|
|
180
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(publicIdentifier)}/channels/${encodeURIComponent(name)}`,
|
|
181
181
|
{},
|
|
182
182
|
);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
async
|
|
186
|
-
|
|
185
|
+
async listPublicChannelsForIdentifier(input: {
|
|
186
|
+
publicIdentifier: string;
|
|
187
187
|
limit?: number;
|
|
188
188
|
cursor?: string;
|
|
189
189
|
}) {
|
|
190
190
|
return this.requestCollection<ChannelAttributes>(
|
|
191
191
|
withQuery(
|
|
192
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(input.
|
|
192
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(input.publicIdentifier)}/channels`,
|
|
193
193
|
{
|
|
194
194
|
"page[limit]": input.limit,
|
|
195
195
|
"page[after]": input.cursor,
|
|
@@ -391,14 +391,14 @@ export class ClankmatesClient {
|
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
async listPublicChannelPosts(input: {
|
|
394
|
-
|
|
394
|
+
publicIdentifier: string;
|
|
395
395
|
channelName: string;
|
|
396
396
|
limit?: number;
|
|
397
397
|
cursor?: string;
|
|
398
398
|
}) {
|
|
399
399
|
return this.requestCollection<PostAttributes>(
|
|
400
400
|
withQuery(
|
|
401
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(input.
|
|
401
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(input.publicIdentifier)}/channels/${encodeURIComponent(input.channelName)}/posts`,
|
|
402
402
|
{
|
|
403
403
|
"page[limit]": input.limit,
|
|
404
404
|
"page[after]": input.cursor,
|
|
@@ -431,13 +431,13 @@ export class ClankmatesClient {
|
|
|
431
431
|
);
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
-
async
|
|
435
|
-
|
|
434
|
+
async getPublicPostByIdentifier(input: {
|
|
435
|
+
publicIdentifier: string;
|
|
436
436
|
channelName: string;
|
|
437
437
|
postId: string;
|
|
438
438
|
}) {
|
|
439
439
|
return this.requestResource<PostAttributes>(
|
|
440
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(input.
|
|
440
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(input.publicIdentifier)}/channels/${encodeURIComponent(input.channelName)}/posts/${input.postId}`,
|
|
441
441
|
{},
|
|
442
442
|
);
|
|
443
443
|
}
|