instar 0.24.13 → 0.24.14

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 (90) hide show
  1. package/.claude/skills/setup-wizard/skill.md +281 -5
  2. package/dashboard/index.html +341 -0
  3. package/dist/cli.js +18 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/server.d.ts.map +1 -1
  6. package/dist/commands/server.js +188 -1
  7. package/dist/commands/server.js.map +1 -1
  8. package/dist/commands/slack-cli.d.ts +16 -0
  9. package/dist/commands/slack-cli.d.ts.map +1 -0
  10. package/dist/commands/slack-cli.js +198 -0
  11. package/dist/commands/slack-cli.js.map +1 -0
  12. package/dist/core/AgentRegistry.d.ts.map +1 -1
  13. package/dist/core/AgentRegistry.js +24 -6
  14. package/dist/core/AgentRegistry.js.map +1 -1
  15. package/dist/core/SleepWakeDetector.d.ts +11 -0
  16. package/dist/core/SleepWakeDetector.d.ts.map +1 -1
  17. package/dist/core/SleepWakeDetector.js +16 -1
  18. package/dist/core/SleepWakeDetector.js.map +1 -1
  19. package/dist/lifeline/ServerSupervisor.d.ts +13 -0
  20. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
  21. package/dist/lifeline/ServerSupervisor.js +129 -0
  22. package/dist/lifeline/ServerSupervisor.js.map +1 -1
  23. package/dist/messaging/SessionSummarySentinel.js +1 -1
  24. package/dist/messaging/TelegramAdapter.d.ts +1 -0
  25. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  26. package/dist/messaging/TelegramAdapter.js +4 -1
  27. package/dist/messaging/TelegramAdapter.js.map +1 -1
  28. package/dist/messaging/slack/ChannelManager.d.ts +36 -0
  29. package/dist/messaging/slack/ChannelManager.d.ts.map +1 -0
  30. package/dist/messaging/slack/ChannelManager.js +100 -0
  31. package/dist/messaging/slack/ChannelManager.js.map +1 -0
  32. package/dist/messaging/slack/FileHandler.d.ts +30 -0
  33. package/dist/messaging/slack/FileHandler.d.ts.map +1 -0
  34. package/dist/messaging/slack/FileHandler.js +87 -0
  35. package/dist/messaging/slack/FileHandler.js.map +1 -0
  36. package/dist/messaging/slack/RingBuffer.d.ts +22 -0
  37. package/dist/messaging/slack/RingBuffer.d.ts.map +1 -0
  38. package/dist/messaging/slack/RingBuffer.js +48 -0
  39. package/dist/messaging/slack/RingBuffer.js.map +1 -0
  40. package/dist/messaging/slack/SlackAdapter.d.ts +136 -0
  41. package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -0
  42. package/dist/messaging/slack/SlackAdapter.js +572 -0
  43. package/dist/messaging/slack/SlackAdapter.js.map +1 -0
  44. package/dist/messaging/slack/SlackApiClient.d.ts +51 -0
  45. package/dist/messaging/slack/SlackApiClient.d.ts.map +1 -0
  46. package/dist/messaging/slack/SlackApiClient.js +94 -0
  47. package/dist/messaging/slack/SlackApiClient.js.map +1 -0
  48. package/dist/messaging/slack/SocketModeClient.d.ts +44 -0
  49. package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -0
  50. package/dist/messaging/slack/SocketModeClient.js +209 -0
  51. package/dist/messaging/slack/SocketModeClient.js.map +1 -0
  52. package/dist/messaging/slack/index.d.ts +12 -0
  53. package/dist/messaging/slack/index.d.ts.map +1 -0
  54. package/dist/messaging/slack/index.js +15 -0
  55. package/dist/messaging/slack/index.js.map +1 -0
  56. package/dist/messaging/slack/sanitize.d.ts +39 -0
  57. package/dist/messaging/slack/sanitize.d.ts.map +1 -0
  58. package/dist/messaging/slack/sanitize.js +71 -0
  59. package/dist/messaging/slack/sanitize.js.map +1 -0
  60. package/dist/messaging/slack/types.d.ts +155 -0
  61. package/dist/messaging/slack/types.d.ts.map +1 -0
  62. package/dist/messaging/slack/types.js +54 -0
  63. package/dist/messaging/slack/types.js.map +1 -0
  64. package/dist/monitoring/PresenceProxy.d.ts +157 -0
  65. package/dist/monitoring/PresenceProxy.d.ts.map +1 -0
  66. package/dist/monitoring/PresenceProxy.js +891 -0
  67. package/dist/monitoring/PresenceProxy.js.map +1 -0
  68. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
  69. package/dist/monitoring/SessionWatchdog.js +2 -0
  70. package/dist/monitoring/SessionWatchdog.js.map +1 -1
  71. package/dist/server/AgentServer.d.ts +1 -0
  72. package/dist/server/AgentServer.d.ts.map +1 -1
  73. package/dist/server/AgentServer.js +49 -47
  74. package/dist/server/AgentServer.js.map +1 -1
  75. package/dist/server/routes.d.ts +1 -0
  76. package/dist/server/routes.d.ts.map +1 -1
  77. package/dist/server/routes.js +213 -4
  78. package/dist/server/routes.js.map +1 -1
  79. package/package.json +1 -1
  80. package/src/data/builtin-manifest.json +94 -78
  81. package/src/templates/hooks/slack-channel-context.sh +98 -0
  82. package/src/templates/scripts/slack-reply.sh +64 -0
  83. package/upgrades/0.24.11.md +23 -0
  84. package/upgrades/0.24.14.md +26 -0
  85. package/upgrades/0.24.6.md +20 -0
  86. package/upgrades/0.24.7.md +24 -0
  87. package/upgrades/0.24.8.md +19 -0
  88. package/upgrades/0.24.9.md +19 -0
  89. package/upgrades/NEXT.md +35 -0
  90. /package/.claude/skills/secret-setup/{skill.md → SKILL.md} +0 -0
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env bash
2
+ # slack-channel-context.sh — UserPromptSubmit hook
3
+ #
4
+ # Detects [slack:CHANNEL_ID] prefix in user messages and injects
5
+ # channel conversation history as JSON context.
6
+ #
7
+ # Reads from the ring buffer cache via instar server API —
8
+ # zero Slack API calls per prompt.
9
+
10
+ set -euo pipefail
11
+
12
+ # Read user prompt from stdin (JSON format from Claude Code)
13
+ INPUT=$(cat)
14
+ PROMPT=$(echo "$INPUT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('userMessage',''))" 2>/dev/null) || exit 0
15
+
16
+ # Check for [slack:C...] prefix
17
+ if [[ "$PROMPT" =~ \[slack:([A-Z0-9]+)\] ]]; then
18
+ CHANNEL_ID="${BASH_REMATCH[1]}"
19
+ else
20
+ exit 0
21
+ fi
22
+
23
+ # Get port and auth from config
24
+ PORT="${INSTAR_PORT:-}"
25
+ AUTH=""
26
+
27
+ if [ -f ".instar/config.json" ]; then
28
+ if [ -z "$PORT" ]; then
29
+ CONFIG_PORT=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('port',''))" 2>/dev/null)
30
+ [ -n "$CONFIG_PORT" ] && PORT="$CONFIG_PORT"
31
+ fi
32
+ AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
33
+ fi
34
+
35
+ PORT="${PORT:-4042}"
36
+
37
+ # Check server health
38
+ if ! curl -sf "http://localhost:${PORT}/health" >/dev/null 2>&1; then
39
+ exit 0 # Server not running — graceful degradation
40
+ fi
41
+
42
+ # Fetch channel history from ring buffer cache
43
+ MESSAGES=$(curl -sf \
44
+ ${AUTH:+-H "Authorization: Bearer $AUTH"} \
45
+ "http://localhost:${PORT}/slack/channels/${CHANNEL_ID}/messages?limit=30" 2>/dev/null) || exit 0
46
+
47
+ # Format thread history for session context
48
+ python3 -c "
49
+ import json, sys
50
+ from datetime import datetime
51
+
52
+ data = json.loads('''${MESSAGES}''')
53
+ messages = data.get('messages', [])
54
+
55
+ if not messages:
56
+ sys.exit(0)
57
+
58
+ lines = ['--- Thread History (last {} messages) ---'.format(len(messages))]
59
+ lines.append('IMPORTANT: Read this history carefully before taking any action.')
60
+ lines.append('Your task is to continue THIS conversation, not start something new.')
61
+ lines.append('Topic: slack-{}'.format('${CHANNEL_ID}'))
62
+ lines.append('')
63
+
64
+ unanswered = 0
65
+ for msg in messages:
66
+ ts = msg.get('ts', '')
67
+ try:
68
+ dt = datetime.fromtimestamp(float(ts))
69
+ time_str = dt.strftime('%H:%M:%S')
70
+ except:
71
+ time_str = ts
72
+
73
+ user = msg.get('user', 'unknown')
74
+ text = msg.get('text', '')
75
+
76
+ # Truncate very long messages
77
+ if len(text) > 2000:
78
+ text = text[:2000] + '...'
79
+
80
+ # Determine if from user or agent
81
+ sender = 'User' if msg.get('fromUser', True) else 'Agent'
82
+ lines.append('[{}] {}: {}'.format(time_str, sender, text))
83
+
84
+ lines.append('')
85
+ lines.append('--- End Thread History ---')
86
+ lines.append('')
87
+ lines.append('CRITICAL: You MUST relay your response back to Slack after responding.')
88
+ lines.append('Use the relay script:')
89
+ lines.append('')
90
+ lines.append(\"cat <<'EOF' | .claude/scripts/slack-reply.sh ${CHANNEL_ID}\")
91
+ lines.append('Your response text here')
92
+ lines.append('EOF')
93
+ lines.append('')
94
+ lines.append('Strip the [slack:${CHANNEL_ID}] prefix before interpreting the message.')
95
+ lines.append('Only relay conversational text — not tool output or internal reasoning.')
96
+
97
+ print('\n'.join(lines))
98
+ " 2>/dev/null || exit 0
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env bash
2
+ # slack-reply.sh — Send a message to a Slack channel via the instar server.
3
+ #
4
+ # Usage:
5
+ # slack-reply.sh CHANNEL_ID "message text"
6
+ # echo "message" | slack-reply.sh CHANNEL_ID
7
+ # cat <<'EOF' | slack-reply.sh CHANNEL_ID
8
+ # Multi-line message here
9
+ # EOF
10
+
11
+ set -euo pipefail
12
+
13
+ CHANNEL_ID="$1"
14
+ shift
15
+
16
+ # Read message from args or stdin
17
+ if [ $# -gt 0 ]; then
18
+ MESSAGE="$*"
19
+ else
20
+ MESSAGE="$(cat)"
21
+ fi
22
+
23
+ if [ -z "$MESSAGE" ]; then
24
+ echo "Error: no message text provided" >&2
25
+ exit 1
26
+ fi
27
+
28
+ # Get port from env or config
29
+ PORT="${INSTAR_PORT:-}"
30
+ AUTH=""
31
+
32
+ if [ -f ".instar/config.json" ]; then
33
+ if [ -z "$PORT" ]; then
34
+ CONFIG_PORT=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('port',''))" 2>/dev/null)
35
+ [ -n "$CONFIG_PORT" ] && PORT="$CONFIG_PORT"
36
+ fi
37
+ AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
38
+ fi
39
+
40
+ PORT="${PORT:-4042}"
41
+
42
+ # JSON-escape the message
43
+ ESCAPED=$(python3 -c "import json,sys; print(json.dumps(sys.stdin.read()))" <<< "$MESSAGE" 2>/dev/null)
44
+ # Fallback to basic bash escaping if python unavailable
45
+ if [ -z "$ESCAPED" ]; then
46
+ ESCAPED="\"$(echo "$MESSAGE" | sed 's/\\/\\\\/g; s/"/\\"/g')\""
47
+ fi
48
+
49
+ # Send via Instar server
50
+ RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
51
+ "http://localhost:${PORT}/slack/reply/${CHANNEL_ID}" \
52
+ -H "Content-Type: application/json" \
53
+ ${AUTH:+-H "Authorization: Bearer $AUTH"} \
54
+ -d "{\"text\": ${ESCAPED}}")
55
+
56
+ HTTP_CODE=$(echo "$RESPONSE" | tail -1)
57
+ BODY=$(echo "$RESPONSE" | sed '$d')
58
+
59
+ if [ "$HTTP_CODE" = "200" ]; then
60
+ echo "Sent ${#MESSAGE} chars to channel ${CHANNEL_ID}"
61
+ else
62
+ echo "Failed (HTTP ${HTTP_CODE}): ${BODY}" >&2
63
+ exit 1
64
+ fi
@@ -0,0 +1,23 @@
1
+ # Upgrade Guide — v0.24.11
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ - **Health endpoint no longer blocks on stale sessions**: The health check previously called synchronous tmux operations for every tracked session, blocking the event loop. With many stale sessions (common after restart loops), this caused health check timeouts, which triggered MORE restarts — a death spiral. Now uses a cached session count updated asynchronously by the monitor tick.
8
+
9
+ - **Startup session purge**: Before monitoring starts, the server now does a fast one-pass purge of all session records whose tmux sessions no longer exist. Uses a 1-second timeout per session to fail fast. This prevents the startup overload where the server spent all its boot time polling dead sessions.
10
+
11
+ - **CoherenceMonitor suppresses known-pending updates**: When the AutoUpdater has already applied a version and a restart is pending (deferred for active sessions), the CoherenceMonitor no longer flags the version mismatch as a failure. This eliminates the race condition where both systems fought over restart decisions.
12
+
13
+ ## What to Tell Your User
14
+
15
+ - **Stability improvement**: "The server should be much more resilient to restart loops now. Even if many sessions build up, the health check stays fast and the server won't get stuck in a crash-restart cycle. Stale sessions are cleaned up instantly on boot instead of dragging things down."
16
+
17
+ ## Summary of New Capabilities
18
+
19
+ | Capability | How to Use |
20
+ |-----------|-----------|
21
+ | Non-blocking health endpoint | Automatic — no action needed |
22
+ | Startup session purge | Automatic — runs on every server boot |
23
+ | CoherenceMonitor update suppression | Automatic — no action needed |
@@ -0,0 +1,26 @@
1
+ # Upgrade Guide — v0.24.14
2
+
3
+ ## What Changed
4
+
5
+ ### Server Supervisor Self-Healing
6
+
7
+ The ServerSupervisor now runs preflight diagnostics before every server spawn attempt. Previously, if the shadow install was missing or the node symlink was broken, the server would crash immediately on startup — and restarting via `/lifeline restart` would just repeat the same failure.
8
+
9
+ Now, before each spawn, the supervisor checks and auto-repairs:
10
+
11
+ - **Missing shadow install** — reinstalls via npm automatically
12
+ - **Broken node symlink** — recreates it from available node binaries
13
+ - **Stale lifeline locks** — removes locks older than 10 minutes
14
+
15
+ This means `/lifeline restart` now actually fixes the problem instead of blindly retrying a broken state. Agents on remote machines can self-recover from common post-update failures without manual SSH intervention.
16
+
17
+ ## What to Tell Your User
18
+
19
+ Your agent's server is now more resilient. If the server goes down due to a missing or corrupted install, the system will automatically detect and fix the issue before restarting. The /lifeline restart command in Telegram now does real recovery, not just a blind retry.
20
+
21
+ ## Summary of New Capabilities
22
+
23
+ - **Preflight self-healing**: Server supervisor diagnoses and fixes common startup failures before each spawn
24
+ - **Shadow install auto-repair**: Missing shadow installs are reinstalled automatically
25
+ - **Node symlink recovery**: Broken node symlinks are recreated from available binaries
26
+ - **Stale lock cleanup**: Old lifeline locks are removed to prevent restart deadlocks
@@ -0,0 +1,20 @@
1
+ # Upgrade Guide — v0.24.6
2
+
3
+ <!-- bump: patch -->
4
+ <!-- Valid values: patch, minor, major -->
5
+ <!-- patch = bug fixes, refactors, test additions, doc updates -->
6
+ <!-- minor = new features, new APIs, new capabilities (backwards-compatible) -->
7
+ <!-- major = breaking changes to existing APIs or behavior -->
8
+
9
+ ## What Changed
10
+
11
+ - **PermissionRequest auto-approve hook**: Subagents spawned via the Agent tool don't inherit `--dangerously-skip-permissions` from the parent session. This caused permission prompts that blocked autonomous work. A new catch-all `PermissionRequest` hook (`auto-approve-permissions.js`) unconditionally approves all permission requests. Real safety remains in PreToolUse hooks.
12
+ - The hook is automatically added to `settings.json` during init and on upgrade via PostUpdateMigrator.
13
+
14
+ ## What to Tell Your User
15
+
16
+ No user-facing changes. This fix ensures autonomous sessions and subagents run without interruption.
17
+
18
+ ## Summary of New Capabilities
19
+
20
+ - Auto-approve permissions for subagent sessions (prevents blocking on tool use prompts)
@@ -0,0 +1,24 @@
1
+ # Upgrade Guide — v0.24.7
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ - **Tunnel reconnect storm fix**: Added a start mutex to TunnelManager so concurrent `start()` calls coalesce instead of racing. Sleep/wake handler now disables auto-reconnect before force-stopping the tunnel, preventing exit handlers from spawning competing reconnection chains. Previously, sleep/wake cycles could trigger dozens of concurrent tunnel reconnection attempts.
8
+
9
+ - **Non-fatal crash prevention**: The uncaught exception handler no longer crashes the server for "Cannot set headers after they are sent to the client" and similar HTTP lifecycle errors. These are expected during tunnel transitions and don't affect server stability. Previously, a single double-response event would kill the entire server process.
10
+
11
+ - **Lifeline startup grace period fix**: During the 3-minute startup grace period, the Lifeline now probes health optimistically. Previously, health checks were completely skipped during boot, causing incoming Telegram messages to be queued with "Server is temporarily down" even when the server was fully responsive (typically within ~10 seconds of restart).
12
+
13
+ - **Queue delivery confirmation**: When queued messages are replayed after server recovery, the Lifeline now sends a per-topic confirmation ("Server recovered — your queued message has been delivered") so users know their message actually reached the session.
14
+
15
+ ## What to Tell Your User
16
+
17
+ Server stability improvements. The server is much less likely to restart unexpectedly, and when it does restart, your messages should flow through almost immediately instead of being queued for up to 3 minutes. You'll also get a confirmation when any queued messages are delivered.
18
+
19
+ ## Summary of New Capabilities
20
+
21
+ - Tunnel reconnection is now atomic — no more reconnect storms after sleep/wake
22
+ - Non-fatal HTTP errors are logged as warnings instead of crashing the server
23
+ - Messages reach sessions within seconds of a restart instead of waiting 3 minutes
24
+ - Queued message delivery is confirmed via Telegram
@@ -0,0 +1,19 @@
1
+ # Upgrade Guide — v0.24.8
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ - **Lifeline auto-restart after update**: When the server recovers from a planned update restart, the supervisor now emits an `updateApplied` event. The lifeline listens for this and self-exits after a 5-second flush delay. launchd KeepAlive respawns it with the updated shadow install binary. This ensures both the server AND lifeline always run the same version after an update.
8
+
9
+ - Both restart detection paths are covered: when the supervisor reads the restart request directly, and when the ForegroundRestartWatcher consumes it first (via the planned-exit marker).
10
+
11
+ ## What to Tell Your User
12
+
13
+ - **Seamless updates**: "Updates now apply to the entire system automatically — both the server and the Telegram connection. Previously, part of the system could run stale code after an update until the machine rebooted. Now everything picks up new code within seconds."
14
+
15
+ ## Summary of New Capabilities
16
+
17
+ | Capability | How to Use |
18
+ |-----------|-----------|
19
+ | Lifeline auto-restart on update | Automatic — no action needed |
@@ -0,0 +1,19 @@
1
+ # Upgrade Guide — v0.24.9
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ - **Restart window**: New config option to control when update restarts happen. When set, automatic restarts are deferred until the configured time window. Updates are still downloaded and applied to the shadow install immediately — only the process restart is held. Manual triggers via the API or conversational commands bypass the window.
8
+
9
+ - Configurable in the agent's config at the path "updates.restartWindow" with start and end times in 24-hour local time format. Supports windows that wrap midnight (e.g., 23:00-05:00).
10
+
11
+ ## What to Tell Your User
12
+
13
+ - **Restart window**: "I can now schedule update restarts for off-hours so they don't disrupt your workflow. Updates still download instantly, but the actual server restart waits for the quiet window. If you ever need an immediate update, just ask — manual triggers always work regardless of the window."
14
+
15
+ ## Summary of New Capabilities
16
+
17
+ | Capability | How to Use |
18
+ |-----------|-----------|
19
+ | Restart window | Set "updates.restartWindow" in config with start/end times (e.g., "02:00"-"05:00") |
@@ -0,0 +1,35 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- bump: patch -->
4
+ <!-- Valid values: patch, minor, major -->
5
+ <!-- patch = bug fixes, refactors, test additions, doc updates -->
6
+ <!-- minor = new features, new APIs, new capabilities (backwards-compatible) -->
7
+ <!-- major = breaking changes to existing APIs or behavior -->
8
+
9
+ ## What Changed
10
+
11
+ <!-- Describe what changed technically. What new features, APIs, behavioral changes? -->
12
+ <!-- Write this for the AGENT — they need to understand the system deeply. -->
13
+
14
+ ## What to Tell Your User
15
+
16
+ <!-- Write talking points the agent should relay to their user. -->
17
+ <!-- This should be warm, conversational, user-facing — not a changelog. -->
18
+ <!-- Focus on what THEY can now do, not internal plumbing. -->
19
+ <!-- -->
20
+ <!-- PROHIBITED in this section (will fail validation): -->
21
+ <!-- camelCase config keys: silentReject, maxRetries, telegramNotify -->
22
+ <!-- Inline code backtick references like silentReject: false -->
23
+ <!-- Fenced code blocks -->
24
+ <!-- Instructions to edit files or run commands -->
25
+ <!-- -->
26
+ <!-- CORRECT style: "I can turn that on for you" not "set X to false" -->
27
+ <!-- The agent relays this to their user — keep it human. -->
28
+
29
+ - **[Feature name]**: "[Brief, friendly description of what this means for the user]"
30
+
31
+ ## Summary of New Capabilities
32
+
33
+ | Capability | How to Use |
34
+ |-----------|-----------|
35
+ | [Capability] | [Endpoint, command, or "automatic"] |