codeblog-app 2.3.2 → 2.3.3

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.
Files changed (83) hide show
  1. package/drizzle/0000_init.sql +34 -0
  2. package/drizzle/meta/_journal.json +13 -0
  3. package/drizzle.config.ts +10 -0
  4. package/package.json +73 -8
  5. package/src/ai/__tests__/chat.test.ts +188 -0
  6. package/src/ai/__tests__/compat.test.ts +46 -0
  7. package/src/ai/__tests__/home.ai-stream.integration.test.ts +77 -0
  8. package/src/ai/__tests__/provider-registry.test.ts +98 -0
  9. package/src/ai/__tests__/provider.test.ts +239 -0
  10. package/src/ai/__tests__/stream-events.test.ts +152 -0
  11. package/src/ai/__tests__/tools.test.ts +93 -0
  12. package/src/ai/chat.ts +336 -0
  13. package/src/ai/configure.ts +144 -0
  14. package/src/ai/models.ts +67 -0
  15. package/src/ai/provider-registry.ts +150 -0
  16. package/src/ai/provider.ts +264 -0
  17. package/src/ai/stream-events.ts +64 -0
  18. package/src/ai/tools.ts +118 -0
  19. package/src/ai/types.ts +105 -0
  20. package/src/auth/index.ts +49 -0
  21. package/src/auth/oauth.ts +141 -0
  22. package/src/cli/__tests__/commands.test.ts +229 -0
  23. package/src/cli/cmd/agent.ts +97 -0
  24. package/src/cli/cmd/ai.ts +10 -0
  25. package/src/cli/cmd/chat.ts +190 -0
  26. package/src/cli/cmd/comment.ts +67 -0
  27. package/src/cli/cmd/config.ts +154 -0
  28. package/src/cli/cmd/feed.ts +53 -0
  29. package/src/cli/cmd/forum.ts +106 -0
  30. package/src/cli/cmd/login.ts +45 -0
  31. package/src/cli/cmd/logout.ts +14 -0
  32. package/src/cli/cmd/me.ts +188 -0
  33. package/src/cli/cmd/post.ts +25 -0
  34. package/src/cli/cmd/publish.ts +64 -0
  35. package/src/cli/cmd/scan.ts +78 -0
  36. package/src/cli/cmd/search.ts +35 -0
  37. package/src/cli/cmd/setup.ts +632 -0
  38. package/src/cli/cmd/tui.ts +20 -0
  39. package/src/cli/cmd/uninstall.ts +281 -0
  40. package/src/cli/cmd/update.ts +139 -0
  41. package/src/cli/cmd/vote.ts +50 -0
  42. package/src/cli/cmd/whoami.ts +18 -0
  43. package/src/cli/mcp-print.ts +6 -0
  44. package/src/cli/ui.ts +357 -0
  45. package/src/config/index.ts +125 -0
  46. package/src/flag/index.ts +23 -0
  47. package/src/global/index.ts +38 -0
  48. package/src/id/index.ts +20 -0
  49. package/src/index.ts +212 -0
  50. package/src/mcp/__tests__/client.test.ts +149 -0
  51. package/src/mcp/__tests__/e2e.ts +331 -0
  52. package/src/mcp/__tests__/integration.ts +148 -0
  53. package/src/mcp/client.ts +118 -0
  54. package/src/server/index.ts +48 -0
  55. package/src/storage/chat.ts +73 -0
  56. package/src/storage/db.ts +85 -0
  57. package/src/storage/schema.sql.ts +39 -0
  58. package/src/storage/schema.ts +1 -0
  59. package/src/tui/__tests__/input-intent.test.ts +27 -0
  60. package/src/tui/__tests__/stream-assembler.test.ts +33 -0
  61. package/src/tui/ai-stream.ts +28 -0
  62. package/src/tui/app.tsx +224 -0
  63. package/src/tui/commands.ts +224 -0
  64. package/src/tui/context/exit.tsx +15 -0
  65. package/src/tui/context/helper.tsx +25 -0
  66. package/src/tui/context/route.tsx +24 -0
  67. package/src/tui/context/theme.tsx +471 -0
  68. package/src/tui/input-intent.ts +26 -0
  69. package/src/tui/routes/home.tsx +1053 -0
  70. package/src/tui/routes/model.tsx +213 -0
  71. package/src/tui/routes/notifications.tsx +87 -0
  72. package/src/tui/routes/post.tsx +102 -0
  73. package/src/tui/routes/search.tsx +105 -0
  74. package/src/tui/routes/setup.tsx +267 -0
  75. package/src/tui/routes/trending.tsx +107 -0
  76. package/src/tui/stream-assembler.ts +49 -0
  77. package/src/util/__tests__/context.test.ts +31 -0
  78. package/src/util/__tests__/lazy.test.ts +37 -0
  79. package/src/util/context.ts +23 -0
  80. package/src/util/error.ts +46 -0
  81. package/src/util/lazy.ts +18 -0
  82. package/src/util/log.ts +144 -0
  83. package/tsconfig.json +11 -0
@@ -0,0 +1,64 @@
1
+ import type { CommandModule } from "yargs"
2
+ import { mcpPrint } from "../mcp-print"
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
+ console.log("")
43
+ await mcpPrint("weekly_digest", mcpArgs)
44
+ console.log("")
45
+ return
46
+ }
47
+
48
+ UI.info("Scanning IDE sessions and generating post...")
49
+ const mcpArgs: Record<string, unknown> = {
50
+ dry_run: args.dryRun,
51
+ }
52
+ if (args.source) mcpArgs.source = args.source
53
+ if (args.language) mcpArgs.language = args.language
54
+ if (args.style) mcpArgs.style = args.style
55
+
56
+ console.log("")
57
+ await mcpPrint("auto_post", mcpArgs)
58
+ console.log("")
59
+ } catch (err) {
60
+ UI.error(`Publish failed: ${err instanceof Error ? err.message : String(err)}`)
61
+ process.exitCode = 1
62
+ }
63
+ },
64
+ }
@@ -0,0 +1,78 @@
1
+ import type { CommandModule } from "yargs"
2
+ import { McpBridge } from "../../mcp/client"
3
+ import { mcpPrint } from "../mcp-print"
4
+ import { UI } from "../ui"
5
+
6
+ export const ScanCommand: CommandModule = {
7
+ command: "scan",
8
+ describe: "Scan local IDE sessions",
9
+ builder: (yargs) =>
10
+ yargs
11
+ .option("limit", {
12
+ describe: "Max sessions to show",
13
+ type: "number",
14
+ default: 20,
15
+ })
16
+ .option("source", {
17
+ describe: "Filter by IDE source",
18
+ type: "string",
19
+ })
20
+ .option("status", {
21
+ describe: "Show scanner status",
22
+ type: "boolean",
23
+ default: false,
24
+ }),
25
+ handler: async (args) => {
26
+ try {
27
+ if (args.status) {
28
+ console.log("")
29
+ console.log(` ${UI.Style.TEXT_NORMAL_BOLD}CodeBlog Status${UI.Style.TEXT_NORMAL}`)
30
+ console.log("")
31
+ await mcpPrint("codeblog_status")
32
+ console.log("")
33
+ return
34
+ }
35
+
36
+ const mcpArgs: Record<string, unknown> = { limit: args.limit }
37
+ if (args.source) mcpArgs.source = args.source
38
+
39
+ const text = await McpBridge.callTool("scan_sessions", mcpArgs)
40
+ let sessions: Array<{
41
+ id: string; source: string; project: string; title: string;
42
+ messages: number; human: number; ai: number; modified: string;
43
+ size: string; path: string; preview?: string
44
+ }>
45
+
46
+ try {
47
+ sessions = JSON.parse(text)
48
+ } catch {
49
+ // Fallback: just print the raw text
50
+ console.log(text)
51
+ return
52
+ }
53
+
54
+ if (sessions.length === 0) {
55
+ UI.info("No IDE sessions found. Try running with --status to check scanner availability.")
56
+ return
57
+ }
58
+
59
+ console.log("")
60
+ console.log(` ${UI.Style.TEXT_NORMAL_BOLD}Found ${sessions.length} sessions${UI.Style.TEXT_NORMAL}`)
61
+ console.log("")
62
+
63
+ for (const session of sessions) {
64
+ const source = `${UI.Style.TEXT_INFO}[${session.source}]${UI.Style.TEXT_NORMAL}`
65
+ const date = new Date(session.modified).toLocaleDateString()
66
+ const msgs = `${UI.Style.TEXT_DIM}${session.human}h/${session.ai}a msgs${UI.Style.TEXT_NORMAL}`
67
+
68
+ console.log(` ${source} ${UI.Style.TEXT_NORMAL_BOLD}${session.project}${UI.Style.TEXT_NORMAL} ${UI.Style.TEXT_DIM}${date}${UI.Style.TEXT_NORMAL}`)
69
+ console.log(` ${session.title}`)
70
+ console.log(` ${msgs} ${UI.Style.TEXT_DIM}${session.id}${UI.Style.TEXT_NORMAL}`)
71
+ console.log("")
72
+ }
73
+ } catch (err) {
74
+ UI.error(`Scan failed: ${err instanceof Error ? err.message : String(err)}`)
75
+ process.exitCode = 1
76
+ }
77
+ },
78
+ }
@@ -0,0 +1,35 @@
1
+ import type { CommandModule } from "yargs"
2
+ import { mcpPrint } from "../mcp-print"
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
+ console.log("")
23
+ console.log(` ${UI.Style.TEXT_NORMAL_BOLD}Results for "${args.query}"${UI.Style.TEXT_NORMAL}`)
24
+ console.log("")
25
+ await mcpPrint("search_posts", {
26
+ query: args.query,
27
+ limit: args.limit,
28
+ })
29
+ console.log("")
30
+ } catch (err) {
31
+ UI.error(`Search failed: ${err instanceof Error ? err.message : String(err)}`)
32
+ process.exitCode = 1
33
+ }
34
+ },
35
+ }