@zoulabo/line-hive 0.1.0

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 (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +457 -0
  3. package/bin/line-hive.js +44 -0
  4. package/dist/cli/config-writer.js +320 -0
  5. package/dist/cli/config-writer.js.map +1 -0
  6. package/dist/cli/doctor.js.map +1 -0
  7. package/dist/cli/init.js +85 -0
  8. package/dist/cli/init.js.map +1 -0
  9. package/dist/cli/prompts.js +35 -0
  10. package/dist/cli/prompts.js.map +1 -0
  11. package/dist/cli/test-connection.js +135 -0
  12. package/dist/cli/test-connection.js.map +1 -0
  13. package/dist/cli/webhook-capture.js +31 -0
  14. package/dist/cli/webhook-capture.js.map +1 -0
  15. package/dist/config.js +62 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/constants.js +15 -0
  18. package/dist/constants.js.map +1 -0
  19. package/dist/i18n.js +100 -0
  20. package/dist/i18n.js.map +1 -0
  21. package/dist/index.js +126 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/line/client.js +72 -0
  24. package/dist/line/client.js.map +1 -0
  25. package/dist/line/messages.js +217 -0
  26. package/dist/line/messages.js.map +1 -0
  27. package/dist/line/webhook.js +485 -0
  28. package/dist/line/webhook.js.map +1 -0
  29. package/dist/logger.js +5 -0
  30. package/dist/logger.js.map +1 -0
  31. package/dist/server.js +143 -0
  32. package/dist/server.js.map +1 -0
  33. package/dist/src/cli/config-writer.js +18 -0
  34. package/dist/src/cli/config-writer.js.map +1 -0
  35. package/dist/src/cli/init.js +11 -0
  36. package/dist/src/cli/init.js.map +1 -0
  37. package/dist/src/cli/prompts.js +38 -0
  38. package/dist/src/cli/prompts.js.map +1 -0
  39. package/dist/src/cli/webhook-capture.js +37 -0
  40. package/dist/src/cli/webhook-capture.js.map +1 -0
  41. package/dist/src/config.js +44 -0
  42. package/dist/src/config.js.map +1 -0
  43. package/dist/src/index.js +53 -0
  44. package/dist/src/index.js.map +1 -0
  45. package/dist/src/line/client.js +20 -0
  46. package/dist/src/line/client.js.map +1 -0
  47. package/dist/src/line/webhook.js +131 -0
  48. package/dist/src/line/webhook.js.map +1 -0
  49. package/dist/src/logger.js +11 -0
  50. package/dist/src/logger.js.map +1 -0
  51. package/dist/src/server.js +140 -0
  52. package/dist/src/server.js.map +1 -0
  53. package/dist/src/store/messageStore.js +222 -0
  54. package/dist/src/store/messageStore.js.map +1 -0
  55. package/dist/src/store/statusStore.js +87 -0
  56. package/dist/src/store/statusStore.js.map +1 -0
  57. package/dist/src/tools/cancelWait.js +26 -0
  58. package/dist/src/tools/cancelWait.js.map +1 -0
  59. package/dist/src/tools/checkMessages.js +16 -0
  60. package/dist/src/tools/checkMessages.js.map +1 -0
  61. package/dist/src/tools/getReply.js +15 -0
  62. package/dist/src/tools/getReply.js.map +1 -0
  63. package/dist/src/tools/sendMessage.js +58 -0
  64. package/dist/src/tools/sendMessage.js.map +1 -0
  65. package/dist/src/tools/setStatus.js +23 -0
  66. package/dist/src/tools/setStatus.js.map +1 -0
  67. package/dist/src/tools/waitForReply.js +85 -0
  68. package/dist/src/tools/waitForReply.js.map +1 -0
  69. package/dist/src/types/index.js +3 -0
  70. package/dist/src/types/index.js.map +1 -0
  71. package/dist/store/messageStore.js +513 -0
  72. package/dist/store/messageStore.js.map +1 -0
  73. package/dist/store/statusStore.js +320 -0
  74. package/dist/store/statusStore.js.map +1 -0
  75. package/dist/tools/ask.js +240 -0
  76. package/dist/tools/ask.js.map +1 -0
  77. package/dist/tools/cancelWait.js +30 -0
  78. package/dist/tools/cancelWait.js.map +1 -0
  79. package/dist/tools/checkMessages.js +23 -0
  80. package/dist/tools/checkMessages.js.map +1 -0
  81. package/dist/tools/getReply.js +12 -0
  82. package/dist/tools/getReply.js.map +1 -0
  83. package/dist/tools/listAgents.js +25 -0
  84. package/dist/tools/listAgents.js.map +1 -0
  85. package/dist/tools/sendMessage.js +99 -0
  86. package/dist/tools/sendMessage.js.map +1 -0
  87. package/dist/tools/setStatus.js +48 -0
  88. package/dist/tools/setStatus.js.map +1 -0
  89. package/dist/tools/waitForReply.js +36 -0
  90. package/dist/tools/waitForReply.js.map +1 -0
  91. package/dist/tools/waitForReplyInternal.js +66 -0
  92. package/dist/tools/waitForReplyInternal.js.map +1 -0
  93. package/dist/tunnel.js +124 -0
  94. package/dist/tunnel.js.map +1 -0
  95. package/dist/types/index.js +2 -0
  96. package/dist/types/index.js.map +1 -0
  97. package/dist/util/persistUserId.js.map +1 -0
  98. package/dist/util/sendWithTokenPool.js +51 -0
  99. package/dist/util/sendWithTokenPool.js.map +1 -0
  100. package/dist/util/sleep.js +5 -0
  101. package/dist/util/sleep.js.map +1 -0
  102. package/dist/util/toolHelpers.js +60 -0
  103. package/dist/util/toolHelpers.js.map +1 -0
  104. package/package.json +61 -0
  105. package/templates/line-notification.instructions.md +105 -0
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@zoulabo/line-hive",
3
+ "version": "0.1.0",
4
+ "description": "MCP server connecting AI coding agents to LINE Messaging API. Monitor agent progress, provide input, and get notifications from your phone.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "line-hive": "./bin/line-hive.js"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/zoulabo/line-hive"
15
+ },
16
+ "homepage": "https://github.com/zoulabo/line-hive#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/zoulabo/line-hive/issues"
19
+ },
20
+ "keywords": [
21
+ "mcp",
22
+ "line",
23
+ "messaging",
24
+ "copilot",
25
+ "cursor",
26
+ "claude",
27
+ "ai-agent",
28
+ "notifications",
29
+ "model-context-protocol"
30
+ ],
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "files": [
35
+ "dist/",
36
+ "bin/",
37
+ "templates/",
38
+ "LICENSE",
39
+ "README.md"
40
+ ],
41
+ "scripts": {
42
+ "build": "tsc -p tsconfig.json",
43
+ "watch": "tsc --watch -p tsconfig.json",
44
+ "start": "node dist/index.js",
45
+ "test": "vitest run",
46
+ "prepublishOnly": "npm run build && npm test"
47
+ },
48
+ "dependencies": {
49
+ "@line/bot-sdk": "^9.0.0",
50
+ "@modelcontextprotocol/sdk": "^1.0.0",
51
+ "better-sqlite3": "^11.0.0",
52
+ "pino": "^9.0.0"
53
+ },
54
+ "devDependencies": {
55
+ "@types/better-sqlite3": "^7.0.0",
56
+ "@types/node": "^20.0.0",
57
+ "tsx": "^4.21.0",
58
+ "typescript": "^5.0.0",
59
+ "vitest": "^3.0.0"
60
+ }
61
+ }
@@ -0,0 +1,105 @@
1
+ # LINE Communication Protocol
2
+
3
+ **HARD RULE: When a LINE session is active, all replies MUST be sent via `line_ask`. Do not respond in this chat.**
4
+
5
+ You have LINE messaging tools available. The user monitors your progress via LINE on their phone.
6
+
7
+ LINE tools are **only used during LINE sessions** — two-way conversations initiated by the user. Outside of a LINE session, do not call any `line_*` tools.
8
+
9
+ ## LINE Session
10
+
11
+ A LINE session means the user is communicating via LINE. When active, use `line_ask` for all communication and `line_set_status` for progress updates.
12
+
13
+ ### Activation — starts when ANY of these happen:
14
+ - User says "continue on LINE", "talk on LINE", "notify me on LINE", or similar
15
+ - User says "preapprove for LINE", "preapproval for LINE", "prepare for LINE", or "prime LINE" (prepare and continue in LINE; run pre-flight, then activate session)
16
+ - You receive a `pendingReply` from `line_set_status`
17
+ - You call `line_ask`
18
+
19
+ ### Agent Naming
20
+
21
+ **First `line_set_status` call — always include `agentName`**: Pick a unique, creative, gender-neutral persona name. Be inventive — mythological, celestial, elemental, or abstract names work well. **Avoid common/obvious names.** Check `line_list_agents` first and pick something not already in use. Without `agentName`, messages show the generic workspace name.
22
+
23
+ **Name uniqueness is enforced by the server.** If another live agent already uses the same `agentName`, `line_set_status`, `line_ask`, and `line_send_message` will return an `agent_name_taken` error. If this happens, pick a different name and retry.
24
+
25
+ After your first call with `agentName`, the server remembers it — no need to repeat in `line_set_status`. However, **always pass `agentName` to `line_ask`** for correct routing when multiple agents share the same workspace.
26
+
27
+ ### Pre-Flight Tool Approval
28
+
29
+ When a LINE session is activated by the user (they say "continue on LINE", "preapprove for LINE", etc.), you MUST run a pre-flight approval sequence **before** the user leaves. This ensures the agent won't block on tool permission prompts while the user is away.
30
+
31
+ **Steps:**
32
+ 1. Tell the user: "I need to trigger tool approvals. Accept each permission prompt. Then **send `?` in LINE or tap Continue** to prime a reply token, and confirm here when done."
33
+ 2. Fire all non-ask approval triggers in parallel:
34
+ - **File read**: `read_file("package.json", limit: 3)`
35
+ - **Terminal**: `ls package.json` (or `dir package.json` on Windows)
36
+ *(a real filesystem command triggers tool permission grants)*
37
+ - **File edit**: `create_file("/dev/null", "")` (triggers file-write permission without modifying any real file)
38
+ - **LINE status**: `line_set_status({ description: "pre-flight", agentName: "<name>" })`
39
+ - **LINE list agents**: `line_list_agents()` (for name uniqueness check)
40
+ 3. **Do NOT call `line_ask` during pre-flight** — no reply token exists yet, so it would waste a push message. Wait for the user to confirm they've sent `?` in LINE or tapped Continue.
41
+ 4. Once the user confirms (types anything in chat like "done", "ready", "ok"), start the LINE session with `line_ask`. The primed reply token ensures the first message is free.
42
+
43
+ **Skip pre-flight when:**
44
+ - The session was activated by `pendingReply` (user already at phone, tools should already be approved from earlier interaction)
45
+ - The user has already approved tools earlier in the same conversation
46
+ - The agent runs with auto-approved tool permissions (e.g., Claude Code with `--dangerously-skip-permissions`)
47
+
48
+ ### Deactivation — ends ONLY when:
49
+ - **User types directly into the chat** — they're back at the computer
50
+ - User explicitly says "stop LINE" or "go quiet"
51
+
52
+ ### CRITICAL: Never End a Session Based on Message Content
53
+
54
+ **NEVER interpret the user's reply as a reason to stop the LINE session.** The user may say "done", "ok", "thanks", "got it", "no more", or similar — these are conversational replies, NOT deactivation signals. Always call `line_ask` again after processing any reply.
55
+
56
+ The ONLY deactivation triggers are listed above. Everything else keeps the session going.
57
+
58
+ ### Active Session Rules
59
+
60
+ 1. **Use `line_ask` for all communication.** It sends your message and waits for the reply in one step. **Always pass `agentName`** for correct routing: `line_ask({ text: "...", agentName: "<name>" })`.
61
+ 2. **Never use `line_send_message`** during an active session — it's for internal use only.
62
+ 3. **The server automatically appends** `— Waiting for your reply (Xh timeout)` to every `line_ask` message with the actual timeout duration. You do NOT need to add this yourself.
63
+ 4. **After receiving a reply, always call `line_ask` again** with your next update or question. Keep the loop going until timeout or explicit deactivation.
64
+ 5. **`queuedRemaining`** in the `line_ask` response shows how many user messages are queued. When `queuedRemaining > 0`, the LINE message automatically shows a "📬 N more" button. The user taps it to pop the next message to the agent — no extra action needed from you.
65
+ 6. **Use `line_set_status` for progress updates** between `line_ask` calls. Status is auto-managed based on your tool calls — you only set the description:
66
+ - `line_set_status({ description: "<task>" })` — sets status to "working" with the given description
67
+ - `line_set_status({})` or `line_set_status({ description: null })` — sets status to "idle"
68
+ - Other statuses are set automatically: `needs_input` when `line_ask` starts waiting, `error` on failures/cancellations, `idle` on timeouts
69
+ 7. **Every `line_set_status` call may return a `pendingReply`**. Always check and act on it.
70
+ 8. **Keep messages short** — 1-3 sentences. No multi-paragraph essays.
71
+ 9. **Never send filler messages** — no "Resending...", "Processing...", "Still here...", or similar noise. Only send messages with real content.
72
+
73
+ ### Timeout Handling
74
+
75
+ When `line_ask` returns `{"success": false, "error": "timeout"}`, the agent status is automatically set to `idle`. Stop the loop. The user will reply when ready — their message creates a `pendingReply` that you'll receive on your next `line_set_status` call, which re-activates the LINE session.
76
+
77
+ > **Note:** The user may send short messages (e.g., ".", "ok", "continue") just to replenish reply tokens. Treat these as keep-alives — do NOT reply to them, just continue waiting.
78
+
79
+ ### Outside a LINE Session
80
+
81
+ Do NOT call any `line_*` tools. No status updates, no messages.
82
+
83
+ ## Interactive Mode (ON DEMAND)
84
+
85
+ Off by default. Activate only when user explicitly requests confirmations — e.g., "ask me on LINE before changes", "confirm on LINE".
86
+
87
+ When active, **before** modifying files or running commands:
88
+
89
+ ```
90
+ line_ask("⏳ About to: <action summary> — confirm?")
91
+ ```
92
+
93
+ If the user says no, respect that. For batched operations, send a single confirmation.
94
+
95
+ Interactive mode implies an active LINE session. Both deactivate together.
96
+
97
+ ## DO NOT
98
+
99
+ - Call `line_*` tools outside of a LINE session
100
+ - Send LINE messages when the user is typing directly in the chat
101
+ - Interpret reply content ("done", "ok", "thanks") as session termination
102
+ - Spam reports more often than every 2 minutes
103
+ - Send filler messages ("Processing...", "Resending...", "Still here...")
104
+ - Use interactive mode unless the user asked for it
105
+ - **Pass LINE tools to subagents** — only the top-level agent should call `line_*` tools. When launching subagents (via `runSubagent` or similar), never include LINE tools in their prompt or capabilities