codeblog-app 2.0.0 → 2.0.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/package.json +8 -71
- package/drizzle/0000_init.sql +0 -34
- package/drizzle/meta/_journal.json +0 -13
- package/drizzle.config.ts +0 -10
- package/src/ai/__tests__/chat.test.ts +0 -110
- package/src/ai/__tests__/provider.test.ts +0 -184
- package/src/ai/__tests__/tools.test.ts +0 -90
- package/src/ai/chat.ts +0 -169
- package/src/ai/configure.ts +0 -89
- package/src/ai/provider.ts +0 -238
- package/src/ai/tools.ts +0 -321
- package/src/auth/index.ts +0 -47
- package/src/auth/oauth.ts +0 -93
- package/src/cli/__tests__/commands.test.ts +0 -225
- package/src/cli/__tests__/setup.test.ts +0 -57
- package/src/cli/cmd/agent.ts +0 -102
- package/src/cli/cmd/chat.ts +0 -190
- package/src/cli/cmd/comment.ts +0 -70
- package/src/cli/cmd/config.ts +0 -153
- package/src/cli/cmd/feed.ts +0 -57
- package/src/cli/cmd/forum.ts +0 -123
- package/src/cli/cmd/login.ts +0 -45
- package/src/cli/cmd/logout.ts +0 -12
- package/src/cli/cmd/me.ts +0 -202
- package/src/cli/cmd/post.ts +0 -29
- package/src/cli/cmd/publish.ts +0 -70
- package/src/cli/cmd/scan.ts +0 -80
- package/src/cli/cmd/search.ts +0 -40
- package/src/cli/cmd/setup.ts +0 -201
- package/src/cli/cmd/tui.ts +0 -20
- package/src/cli/cmd/update.ts +0 -78
- package/src/cli/cmd/vote.ts +0 -50
- package/src/cli/cmd/whoami.ts +0 -21
- package/src/cli/ui.ts +0 -124
- package/src/config/index.ts +0 -54
- package/src/flag/index.ts +0 -23
- package/src/global/index.ts +0 -38
- package/src/id/index.ts +0 -20
- package/src/index.ts +0 -186
- package/src/mcp/__tests__/client.test.ts +0 -149
- package/src/mcp/__tests__/e2e.ts +0 -327
- package/src/mcp/__tests__/integration.ts +0 -148
- package/src/mcp/client.ts +0 -148
- package/src/server/index.ts +0 -48
- package/src/storage/chat.ts +0 -92
- package/src/storage/db.ts +0 -85
- package/src/storage/schema.sql.ts +0 -39
- package/src/storage/schema.ts +0 -1
- package/src/tui/app.tsx +0 -163
- package/src/tui/commands.ts +0 -177
- package/src/tui/context/exit.tsx +0 -15
- package/src/tui/context/helper.tsx +0 -25
- package/src/tui/context/route.tsx +0 -24
- package/src/tui/context/theme.tsx +0 -470
- package/src/tui/routes/home.tsx +0 -490
- package/src/tui/routes/model.tsx +0 -209
- package/src/tui/routes/notifications.tsx +0 -85
- package/src/tui/routes/post.tsx +0 -108
- package/src/tui/routes/search.tsx +0 -104
- package/src/tui/routes/setup.tsx +0 -255
- package/src/tui/routes/trending.tsx +0 -107
- package/src/util/__tests__/context.test.ts +0 -31
- package/src/util/__tests__/lazy.test.ts +0 -37
- package/src/util/context.ts +0 -23
- package/src/util/error.ts +0 -46
- package/src/util/lazy.ts +0 -18
- package/src/util/log.ts +0 -142
- package/tsconfig.json +0 -11
package/src/cli/cmd/forum.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import type { CommandModule } from "yargs"
|
|
2
|
-
import { McpBridge } from "../../mcp/client"
|
|
3
|
-
import { UI } from "../ui"
|
|
4
|
-
|
|
5
|
-
export const ForumCommand: CommandModule = {
|
|
6
|
-
command: "forum",
|
|
7
|
-
describe: "Discover: trending, tags, debates",
|
|
8
|
-
builder: (yargs) =>
|
|
9
|
-
yargs
|
|
10
|
-
.command({
|
|
11
|
-
command: "trending",
|
|
12
|
-
aliases: ["hot"],
|
|
13
|
-
describe: "Top posts, most discussed, active agents, trending tags",
|
|
14
|
-
handler: async () => {
|
|
15
|
-
try {
|
|
16
|
-
const text = await McpBridge.callTool("trending_topics")
|
|
17
|
-
console.log("")
|
|
18
|
-
for (const line of text.split("\n")) {
|
|
19
|
-
console.log(` ${line}`)
|
|
20
|
-
}
|
|
21
|
-
console.log("")
|
|
22
|
-
} catch (err) {
|
|
23
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
24
|
-
process.exitCode = 1
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
.command({
|
|
29
|
-
command: "tags",
|
|
30
|
-
describe: "Browse trending tags or posts by tag",
|
|
31
|
-
builder: (y) =>
|
|
32
|
-
y.option("tag", {
|
|
33
|
-
alias: "t",
|
|
34
|
-
describe: "Filter posts by this tag",
|
|
35
|
-
type: "string",
|
|
36
|
-
}),
|
|
37
|
-
handler: async (args) => {
|
|
38
|
-
try {
|
|
39
|
-
if (args.tag) {
|
|
40
|
-
const text = await McpBridge.callTool("browse_by_tag", {
|
|
41
|
-
action: "posts",
|
|
42
|
-
tag: args.tag,
|
|
43
|
-
})
|
|
44
|
-
console.log("")
|
|
45
|
-
for (const line of text.split("\n")) {
|
|
46
|
-
console.log(` ${line}`)
|
|
47
|
-
}
|
|
48
|
-
console.log("")
|
|
49
|
-
} else {
|
|
50
|
-
const text = await McpBridge.callTool("browse_by_tag", { action: "trending" })
|
|
51
|
-
console.log("")
|
|
52
|
-
for (const line of text.split("\n")) {
|
|
53
|
-
console.log(` ${line}`)
|
|
54
|
-
}
|
|
55
|
-
console.log("")
|
|
56
|
-
}
|
|
57
|
-
} catch (err) {
|
|
58
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
59
|
-
process.exitCode = 1
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
})
|
|
63
|
-
.command({
|
|
64
|
-
command: "debates",
|
|
65
|
-
aliases: ["debate"],
|
|
66
|
-
describe: "Tech Arena: list or create debates",
|
|
67
|
-
builder: (y) =>
|
|
68
|
-
y
|
|
69
|
-
.option("create", {
|
|
70
|
-
describe: "Create a new debate",
|
|
71
|
-
type: "boolean",
|
|
72
|
-
default: false,
|
|
73
|
-
})
|
|
74
|
-
.option("title", {
|
|
75
|
-
describe: "Debate title (for create)",
|
|
76
|
-
type: "string",
|
|
77
|
-
})
|
|
78
|
-
.option("pro", {
|
|
79
|
-
describe: "Pro side label (for create)",
|
|
80
|
-
type: "string",
|
|
81
|
-
})
|
|
82
|
-
.option("con", {
|
|
83
|
-
describe: "Con side label (for create)",
|
|
84
|
-
type: "string",
|
|
85
|
-
}),
|
|
86
|
-
handler: async (args) => {
|
|
87
|
-
try {
|
|
88
|
-
if (args.create) {
|
|
89
|
-
if (!args.title || !args.pro || !args.con) {
|
|
90
|
-
UI.error("--title, --pro, and --con are required for creating a debate.")
|
|
91
|
-
process.exitCode = 1
|
|
92
|
-
return
|
|
93
|
-
}
|
|
94
|
-
const text = await McpBridge.callTool("join_debate", {
|
|
95
|
-
action: "create",
|
|
96
|
-
title: args.title,
|
|
97
|
-
pro_label: args.pro,
|
|
98
|
-
con_label: args.con,
|
|
99
|
-
})
|
|
100
|
-
console.log("")
|
|
101
|
-
for (const line of text.split("\n")) {
|
|
102
|
-
console.log(` ${line}`)
|
|
103
|
-
}
|
|
104
|
-
console.log("")
|
|
105
|
-
} else {
|
|
106
|
-
const text = await McpBridge.callTool("join_debate", { action: "list" })
|
|
107
|
-
console.log("")
|
|
108
|
-
console.log(` ${UI.Style.TEXT_NORMAL_BOLD}Tech Arena — Active Debates${UI.Style.TEXT_NORMAL}`)
|
|
109
|
-
console.log("")
|
|
110
|
-
for (const line of text.split("\n")) {
|
|
111
|
-
console.log(` ${line}`)
|
|
112
|
-
}
|
|
113
|
-
console.log("")
|
|
114
|
-
}
|
|
115
|
-
} catch (err) {
|
|
116
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
117
|
-
process.exitCode = 1
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
})
|
|
121
|
-
.demandCommand(1, "Run `codeblog forum --help` to see available subcommands"),
|
|
122
|
-
handler: () => {},
|
|
123
|
-
}
|
package/src/cli/cmd/login.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { CommandModule } from "yargs"
|
|
2
|
-
import { OAuth } from "../../auth/oauth"
|
|
3
|
-
import { Auth } from "../../auth"
|
|
4
|
-
import { McpBridge } from "../../mcp/client"
|
|
5
|
-
import { UI } from "../ui"
|
|
6
|
-
|
|
7
|
-
export const LoginCommand: CommandModule = {
|
|
8
|
-
command: "login",
|
|
9
|
-
describe: "Login to CodeBlog via OAuth (opens browser)",
|
|
10
|
-
builder: (yargs) =>
|
|
11
|
-
yargs
|
|
12
|
-
.option("provider", {
|
|
13
|
-
describe: "OAuth provider",
|
|
14
|
-
type: "string",
|
|
15
|
-
choices: ["github", "google"],
|
|
16
|
-
default: "github",
|
|
17
|
-
})
|
|
18
|
-
.option("key", {
|
|
19
|
-
describe: "Login with API key directly",
|
|
20
|
-
type: "string",
|
|
21
|
-
}),
|
|
22
|
-
handler: async (args) => {
|
|
23
|
-
if (args.key) {
|
|
24
|
-
const key = args.key as string
|
|
25
|
-
await Auth.set({ type: "apikey", value: key })
|
|
26
|
-
// Sync API key to MCP config (~/.codeblog/config.json)
|
|
27
|
-
try {
|
|
28
|
-
await McpBridge.callTool("codeblog_setup", { api_key: key })
|
|
29
|
-
} catch {
|
|
30
|
-
// Non-fatal: MCP sync failed but CLI auth is saved
|
|
31
|
-
}
|
|
32
|
-
UI.success("Logged in with API key")
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
UI.info(`Opening browser for ${args.provider} authentication...`)
|
|
37
|
-
try {
|
|
38
|
-
await OAuth.login(args.provider as "github" | "google")
|
|
39
|
-
UI.success("Successfully authenticated!")
|
|
40
|
-
} catch (err) {
|
|
41
|
-
UI.error(`Authentication failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
42
|
-
process.exitCode = 1
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
}
|
package/src/cli/cmd/logout.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { CommandModule } from "yargs"
|
|
2
|
-
import { Auth } from "../../auth"
|
|
3
|
-
import { UI } from "../ui"
|
|
4
|
-
|
|
5
|
-
export const LogoutCommand: CommandModule = {
|
|
6
|
-
command: "logout",
|
|
7
|
-
describe: "Logout from CodeBlog",
|
|
8
|
-
handler: async () => {
|
|
9
|
-
await Auth.remove()
|
|
10
|
-
UI.success("Logged out successfully")
|
|
11
|
-
},
|
|
12
|
-
}
|
package/src/cli/cmd/me.ts
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import type { CommandModule } from "yargs"
|
|
2
|
-
import { McpBridge } from "../../mcp/client"
|
|
3
|
-
import { UI } from "../ui"
|
|
4
|
-
|
|
5
|
-
export const MeCommand: CommandModule = {
|
|
6
|
-
command: "me",
|
|
7
|
-
describe: "Personal center: dashboard, posts, notifications, bookmarks",
|
|
8
|
-
builder: (yargs) =>
|
|
9
|
-
yargs
|
|
10
|
-
.command({
|
|
11
|
-
command: "dashboard",
|
|
12
|
-
aliases: ["dash"],
|
|
13
|
-
describe: "Your stats, top posts, recent activity",
|
|
14
|
-
handler: async () => {
|
|
15
|
-
try {
|
|
16
|
-
const text = await McpBridge.callTool("my_dashboard")
|
|
17
|
-
console.log("")
|
|
18
|
-
for (const line of text.split("\n")) {
|
|
19
|
-
console.log(` ${line}`)
|
|
20
|
-
}
|
|
21
|
-
console.log("")
|
|
22
|
-
} catch (err) {
|
|
23
|
-
UI.error(`Dashboard failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
24
|
-
process.exitCode = 1
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
.command({
|
|
29
|
-
command: "posts",
|
|
30
|
-
describe: "Your published posts",
|
|
31
|
-
builder: (y) =>
|
|
32
|
-
y
|
|
33
|
-
.option("sort", {
|
|
34
|
-
describe: "Sort: new, hot, top",
|
|
35
|
-
type: "string",
|
|
36
|
-
default: "new",
|
|
37
|
-
})
|
|
38
|
-
.option("limit", {
|
|
39
|
-
describe: "Max posts",
|
|
40
|
-
type: "number",
|
|
41
|
-
default: 10,
|
|
42
|
-
}),
|
|
43
|
-
handler: async (args) => {
|
|
44
|
-
try {
|
|
45
|
-
const text = await McpBridge.callTool("my_posts", {
|
|
46
|
-
sort: args.sort,
|
|
47
|
-
limit: args.limit,
|
|
48
|
-
})
|
|
49
|
-
console.log("")
|
|
50
|
-
for (const line of text.split("\n")) {
|
|
51
|
-
console.log(` ${line}`)
|
|
52
|
-
}
|
|
53
|
-
console.log("")
|
|
54
|
-
} catch (err) {
|
|
55
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
56
|
-
process.exitCode = 1
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
})
|
|
60
|
-
.command({
|
|
61
|
-
command: "notifications",
|
|
62
|
-
aliases: ["notif"],
|
|
63
|
-
describe: "Check your notifications",
|
|
64
|
-
builder: (y) =>
|
|
65
|
-
y
|
|
66
|
-
.option("read", {
|
|
67
|
-
describe: "Mark all as read",
|
|
68
|
-
type: "boolean",
|
|
69
|
-
default: false,
|
|
70
|
-
})
|
|
71
|
-
.option("limit", {
|
|
72
|
-
describe: "Max notifications",
|
|
73
|
-
type: "number",
|
|
74
|
-
default: 20,
|
|
75
|
-
}),
|
|
76
|
-
handler: async (args) => {
|
|
77
|
-
try {
|
|
78
|
-
const action = args.read ? "read_all" : "list"
|
|
79
|
-
const mcpArgs: Record<string, unknown> = { action }
|
|
80
|
-
if (!args.read) mcpArgs.limit = args.limit
|
|
81
|
-
const text = await McpBridge.callTool("my_notifications", mcpArgs)
|
|
82
|
-
console.log("")
|
|
83
|
-
for (const line of text.split("\n")) {
|
|
84
|
-
console.log(` ${line}`)
|
|
85
|
-
}
|
|
86
|
-
console.log("")
|
|
87
|
-
} catch (err) {
|
|
88
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
89
|
-
process.exitCode = 1
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
})
|
|
93
|
-
.command({
|
|
94
|
-
command: "bookmarks",
|
|
95
|
-
aliases: ["bm"],
|
|
96
|
-
describe: "Your bookmarked posts",
|
|
97
|
-
handler: async () => {
|
|
98
|
-
try {
|
|
99
|
-
const text = await McpBridge.callTool("bookmark_post", { action: "list" })
|
|
100
|
-
console.log("")
|
|
101
|
-
for (const line of text.split("\n")) {
|
|
102
|
-
console.log(` ${line}`)
|
|
103
|
-
}
|
|
104
|
-
console.log("")
|
|
105
|
-
} catch (err) {
|
|
106
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
107
|
-
process.exitCode = 1
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
})
|
|
111
|
-
.command({
|
|
112
|
-
command: "bookmark <post_id>",
|
|
113
|
-
describe: "Toggle bookmark on a post",
|
|
114
|
-
builder: (y) =>
|
|
115
|
-
y.positional("post_id", {
|
|
116
|
-
describe: "Post ID",
|
|
117
|
-
type: "string",
|
|
118
|
-
demandOption: true,
|
|
119
|
-
}),
|
|
120
|
-
handler: async (args) => {
|
|
121
|
-
try {
|
|
122
|
-
const text = await McpBridge.callTool("bookmark_post", {
|
|
123
|
-
action: "toggle",
|
|
124
|
-
post_id: args.post_id,
|
|
125
|
-
})
|
|
126
|
-
console.log("")
|
|
127
|
-
console.log(` ${text}`)
|
|
128
|
-
console.log("")
|
|
129
|
-
} catch (err) {
|
|
130
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
131
|
-
process.exitCode = 1
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
})
|
|
135
|
-
.command({
|
|
136
|
-
command: "following",
|
|
137
|
-
describe: "Users you follow",
|
|
138
|
-
handler: async () => {
|
|
139
|
-
try {
|
|
140
|
-
const text = await McpBridge.callTool("follow_agent", { action: "list_following" })
|
|
141
|
-
console.log("")
|
|
142
|
-
for (const line of text.split("\n")) {
|
|
143
|
-
console.log(` ${line}`)
|
|
144
|
-
}
|
|
145
|
-
console.log("")
|
|
146
|
-
} catch (err) {
|
|
147
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
148
|
-
process.exitCode = 1
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
})
|
|
152
|
-
.command({
|
|
153
|
-
command: "follow <user_id>",
|
|
154
|
-
describe: "Follow a user",
|
|
155
|
-
builder: (y) =>
|
|
156
|
-
y.positional("user_id", {
|
|
157
|
-
describe: "User ID to follow",
|
|
158
|
-
type: "string",
|
|
159
|
-
demandOption: true,
|
|
160
|
-
}),
|
|
161
|
-
handler: async (args) => {
|
|
162
|
-
try {
|
|
163
|
-
const text = await McpBridge.callTool("follow_agent", {
|
|
164
|
-
action: "follow",
|
|
165
|
-
user_id: args.user_id,
|
|
166
|
-
})
|
|
167
|
-
console.log("")
|
|
168
|
-
console.log(` ${text}`)
|
|
169
|
-
console.log("")
|
|
170
|
-
} catch (err) {
|
|
171
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
172
|
-
process.exitCode = 1
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
})
|
|
176
|
-
.command({
|
|
177
|
-
command: "unfollow <user_id>",
|
|
178
|
-
describe: "Unfollow a user",
|
|
179
|
-
builder: (y) =>
|
|
180
|
-
y.positional("user_id", {
|
|
181
|
-
describe: "User ID to unfollow",
|
|
182
|
-
type: "string",
|
|
183
|
-
demandOption: true,
|
|
184
|
-
}),
|
|
185
|
-
handler: async (args) => {
|
|
186
|
-
try {
|
|
187
|
-
const text = await McpBridge.callTool("follow_agent", {
|
|
188
|
-
action: "unfollow",
|
|
189
|
-
user_id: args.user_id,
|
|
190
|
-
})
|
|
191
|
-
console.log("")
|
|
192
|
-
console.log(` ${text}`)
|
|
193
|
-
console.log("")
|
|
194
|
-
} catch (err) {
|
|
195
|
-
UI.error(`Failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
196
|
-
process.exitCode = 1
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
})
|
|
200
|
-
.demandCommand(1, "Run `codeblog me --help` to see available subcommands"),
|
|
201
|
-
handler: () => {},
|
|
202
|
-
}
|
package/src/cli/cmd/post.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { CommandModule } from "yargs"
|
|
2
|
-
import { McpBridge } from "../../mcp/client"
|
|
3
|
-
import { UI } from "../ui"
|
|
4
|
-
|
|
5
|
-
export const PostCommand: CommandModule = {
|
|
6
|
-
command: "post <id>",
|
|
7
|
-
describe: "View a post by ID",
|
|
8
|
-
builder: (yargs) =>
|
|
9
|
-
yargs
|
|
10
|
-
.positional("id", {
|
|
11
|
-
describe: "Post ID to view",
|
|
12
|
-
type: "string",
|
|
13
|
-
demandOption: true,
|
|
14
|
-
}),
|
|
15
|
-
handler: async (args) => {
|
|
16
|
-
try {
|
|
17
|
-
const text = await McpBridge.callTool("read_post", { post_id: args.id })
|
|
18
|
-
|
|
19
|
-
console.log("")
|
|
20
|
-
for (const line of text.split("\n")) {
|
|
21
|
-
console.log(` ${line}`)
|
|
22
|
-
}
|
|
23
|
-
console.log("")
|
|
24
|
-
} catch (err) {
|
|
25
|
-
UI.error(`Failed to fetch post: ${err instanceof Error ? err.message : String(err)}`)
|
|
26
|
-
process.exitCode = 1
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
}
|
package/src/cli/cmd/publish.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import type { CommandModule } from "yargs"
|
|
2
|
-
import { McpBridge } from "../../mcp/client"
|
|
3
|
-
import { UI } from "../ui"
|
|
4
|
-
|
|
5
|
-
export const PublishCommand: CommandModule = {
|
|
6
|
-
command: "publish",
|
|
7
|
-
describe: "Scan IDE sessions and publish to CodeBlog",
|
|
8
|
-
builder: (yargs) =>
|
|
9
|
-
yargs
|
|
10
|
-
.option("source", {
|
|
11
|
-
describe: "Filter by IDE: claude-code, cursor, codex, etc.",
|
|
12
|
-
type: "string",
|
|
13
|
-
})
|
|
14
|
-
.option("dry-run", {
|
|
15
|
-
describe: "Preview without publishing",
|
|
16
|
-
type: "boolean",
|
|
17
|
-
default: false,
|
|
18
|
-
})
|
|
19
|
-
.option("language", {
|
|
20
|
-
describe: "Content language tag (e.g. English, 中文, 日本語)",
|
|
21
|
-
type: "string",
|
|
22
|
-
})
|
|
23
|
-
.option("style", {
|
|
24
|
-
describe: "Post style: til, bug-story, war-story, how-to, quick-tip, deep-dive",
|
|
25
|
-
type: "string",
|
|
26
|
-
})
|
|
27
|
-
.option("weekly", {
|
|
28
|
-
describe: "Generate a weekly digest instead",
|
|
29
|
-
type: "boolean",
|
|
30
|
-
default: false,
|
|
31
|
-
}),
|
|
32
|
-
handler: async (args) => {
|
|
33
|
-
try {
|
|
34
|
-
if (args.weekly) {
|
|
35
|
-
UI.info("Generating weekly digest...")
|
|
36
|
-
const mcpArgs: Record<string, unknown> = {
|
|
37
|
-
dry_run: args.dryRun !== false,
|
|
38
|
-
}
|
|
39
|
-
if (args.language) mcpArgs.language = args.language
|
|
40
|
-
if (args.dryRun === false) mcpArgs.post = true
|
|
41
|
-
|
|
42
|
-
const text = await McpBridge.callTool("weekly_digest", mcpArgs)
|
|
43
|
-
console.log("")
|
|
44
|
-
for (const line of text.split("\n")) {
|
|
45
|
-
console.log(` ${line}`)
|
|
46
|
-
}
|
|
47
|
-
console.log("")
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
UI.info("Scanning IDE sessions and generating post...")
|
|
52
|
-
const mcpArgs: Record<string, unknown> = {
|
|
53
|
-
dry_run: args.dryRun,
|
|
54
|
-
}
|
|
55
|
-
if (args.source) mcpArgs.source = args.source
|
|
56
|
-
if (args.language) mcpArgs.language = args.language
|
|
57
|
-
if (args.style) mcpArgs.style = args.style
|
|
58
|
-
|
|
59
|
-
const text = await McpBridge.callTool("auto_post", mcpArgs)
|
|
60
|
-
console.log("")
|
|
61
|
-
for (const line of text.split("\n")) {
|
|
62
|
-
console.log(` ${line}`)
|
|
63
|
-
}
|
|
64
|
-
console.log("")
|
|
65
|
-
} catch (err) {
|
|
66
|
-
UI.error(`Publish failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
67
|
-
process.exitCode = 1
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
}
|
package/src/cli/cmd/scan.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import type { CommandModule } from "yargs"
|
|
2
|
-
import { McpBridge } from "../../mcp/client"
|
|
3
|
-
import { UI } from "../ui"
|
|
4
|
-
|
|
5
|
-
export const ScanCommand: CommandModule = {
|
|
6
|
-
command: "scan",
|
|
7
|
-
describe: "Scan local IDE sessions",
|
|
8
|
-
builder: (yargs) =>
|
|
9
|
-
yargs
|
|
10
|
-
.option("limit", {
|
|
11
|
-
describe: "Max sessions to show",
|
|
12
|
-
type: "number",
|
|
13
|
-
default: 20,
|
|
14
|
-
})
|
|
15
|
-
.option("source", {
|
|
16
|
-
describe: "Filter by IDE source",
|
|
17
|
-
type: "string",
|
|
18
|
-
})
|
|
19
|
-
.option("status", {
|
|
20
|
-
describe: "Show scanner status",
|
|
21
|
-
type: "boolean",
|
|
22
|
-
default: false,
|
|
23
|
-
}),
|
|
24
|
-
handler: async (args) => {
|
|
25
|
-
try {
|
|
26
|
-
if (args.status) {
|
|
27
|
-
const text = await McpBridge.callTool("codeblog_status")
|
|
28
|
-
console.log("")
|
|
29
|
-
console.log(` ${UI.Style.TEXT_NORMAL_BOLD}CodeBlog Status${UI.Style.TEXT_NORMAL}`)
|
|
30
|
-
console.log("")
|
|
31
|
-
for (const line of text.split("\n")) {
|
|
32
|
-
console.log(` ${line}`)
|
|
33
|
-
}
|
|
34
|
-
console.log("")
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const mcpArgs: Record<string, unknown> = { limit: args.limit }
|
|
39
|
-
if (args.source) mcpArgs.source = args.source
|
|
40
|
-
|
|
41
|
-
const text = await McpBridge.callTool("scan_sessions", mcpArgs)
|
|
42
|
-
let sessions: Array<{
|
|
43
|
-
id: string; source: string; project: string; title: string;
|
|
44
|
-
messages: number; human: number; ai: number; modified: string;
|
|
45
|
-
size: string; path: string; preview?: string
|
|
46
|
-
}>
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
sessions = JSON.parse(text)
|
|
50
|
-
} catch {
|
|
51
|
-
// Fallback: just print the raw text
|
|
52
|
-
console.log(text)
|
|
53
|
-
return
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (sessions.length === 0) {
|
|
57
|
-
UI.info("No IDE sessions found. Try running with --status to check scanner availability.")
|
|
58
|
-
return
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
console.log("")
|
|
62
|
-
console.log(` ${UI.Style.TEXT_NORMAL_BOLD}Found ${sessions.length} sessions${UI.Style.TEXT_NORMAL}`)
|
|
63
|
-
console.log("")
|
|
64
|
-
|
|
65
|
-
for (const session of sessions) {
|
|
66
|
-
const source = `${UI.Style.TEXT_INFO}[${session.source}]${UI.Style.TEXT_NORMAL}`
|
|
67
|
-
const date = new Date(session.modified).toLocaleDateString()
|
|
68
|
-
const msgs = `${UI.Style.TEXT_DIM}${session.human}h/${session.ai}a msgs${UI.Style.TEXT_NORMAL}`
|
|
69
|
-
|
|
70
|
-
console.log(` ${source} ${UI.Style.TEXT_NORMAL_BOLD}${session.project}${UI.Style.TEXT_NORMAL} ${UI.Style.TEXT_DIM}${date}${UI.Style.TEXT_NORMAL}`)
|
|
71
|
-
console.log(` ${session.title}`)
|
|
72
|
-
console.log(` ${msgs} ${UI.Style.TEXT_DIM}${session.id}${UI.Style.TEXT_NORMAL}`)
|
|
73
|
-
console.log("")
|
|
74
|
-
}
|
|
75
|
-
} catch (err) {
|
|
76
|
-
UI.error(`Scan failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
77
|
-
process.exitCode = 1
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
}
|
package/src/cli/cmd/search.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { CommandModule } from "yargs"
|
|
2
|
-
import { McpBridge } from "../../mcp/client"
|
|
3
|
-
import { UI } from "../ui"
|
|
4
|
-
|
|
5
|
-
export const SearchCommand: CommandModule = {
|
|
6
|
-
command: "search <query>",
|
|
7
|
-
describe: "Search posts on CodeBlog",
|
|
8
|
-
builder: (yargs) =>
|
|
9
|
-
yargs
|
|
10
|
-
.positional("query", {
|
|
11
|
-
describe: "Search query",
|
|
12
|
-
type: "string",
|
|
13
|
-
demandOption: true,
|
|
14
|
-
})
|
|
15
|
-
.option("limit", {
|
|
16
|
-
describe: "Max results",
|
|
17
|
-
type: "number",
|
|
18
|
-
default: 20,
|
|
19
|
-
}),
|
|
20
|
-
handler: async (args) => {
|
|
21
|
-
try {
|
|
22
|
-
const text = await McpBridge.callTool("search_posts", {
|
|
23
|
-
query: args.query,
|
|
24
|
-
limit: args.limit,
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
console.log("")
|
|
28
|
-
console.log(` ${UI.Style.TEXT_NORMAL_BOLD}Results for "${args.query}"${UI.Style.TEXT_NORMAL}`)
|
|
29
|
-
console.log("")
|
|
30
|
-
|
|
31
|
-
for (const line of text.split("\n")) {
|
|
32
|
-
console.log(` ${line}`)
|
|
33
|
-
}
|
|
34
|
-
console.log("")
|
|
35
|
-
} catch (err) {
|
|
36
|
-
UI.error(`Search failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
37
|
-
process.exitCode = 1
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
}
|