instar 0.26.3 → 0.26.5

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 (102) hide show
  1. package/README.md +61 -7
  2. package/dashboard/index.html +55 -0
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/init.js +2 -1
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/server.d.ts.map +1 -1
  7. package/dist/commands/server.js +188 -3
  8. package/dist/commands/server.js.map +1 -1
  9. package/dist/commands/slack-cli.d.ts.map +1 -1
  10. package/dist/commands/slack-cli.js +6 -0
  11. package/dist/commands/slack-cli.js.map +1 -1
  12. package/dist/core/CapabilityMapper.d.ts.map +1 -1
  13. package/dist/core/CapabilityMapper.js +2 -0
  14. package/dist/core/CapabilityMapper.js.map +1 -1
  15. package/dist/core/EvolutionManager.d.ts +17 -0
  16. package/dist/core/EvolutionManager.d.ts.map +1 -1
  17. package/dist/core/EvolutionManager.js +64 -0
  18. package/dist/core/EvolutionManager.js.map +1 -1
  19. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  20. package/dist/core/PostUpdateMigrator.js +37 -0
  21. package/dist/core/PostUpdateMigrator.js.map +1 -1
  22. package/dist/core/SessionManager.d.ts +31 -0
  23. package/dist/core/SessionManager.d.ts.map +1 -1
  24. package/dist/core/SessionManager.js +169 -16
  25. package/dist/core/SessionManager.js.map +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/messaging/imessage/IMessageAdapter.d.ts +128 -0
  31. package/dist/messaging/imessage/IMessageAdapter.d.ts.map +1 -0
  32. package/dist/messaging/imessage/IMessageAdapter.js +541 -0
  33. package/dist/messaging/imessage/IMessageAdapter.js.map +1 -0
  34. package/dist/messaging/imessage/NativeBackend.d.ts +82 -0
  35. package/dist/messaging/imessage/NativeBackend.d.ts.map +1 -0
  36. package/dist/messaging/imessage/NativeBackend.js +353 -0
  37. package/dist/messaging/imessage/NativeBackend.js.map +1 -0
  38. package/dist/messaging/imessage/OutboundAuditLog.d.ts +49 -0
  39. package/dist/messaging/imessage/OutboundAuditLog.d.ts.map +1 -0
  40. package/dist/messaging/imessage/OutboundAuditLog.js +58 -0
  41. package/dist/messaging/imessage/OutboundAuditLog.js.map +1 -0
  42. package/dist/messaging/imessage/OutboundRateLimiter.d.ts +54 -0
  43. package/dist/messaging/imessage/OutboundRateLimiter.d.ts.map +1 -0
  44. package/dist/messaging/imessage/OutboundRateLimiter.js +111 -0
  45. package/dist/messaging/imessage/OutboundRateLimiter.js.map +1 -0
  46. package/dist/messaging/imessage/index.d.ts +10 -0
  47. package/dist/messaging/imessage/index.d.ts.map +1 -0
  48. package/dist/messaging/imessage/index.js +13 -0
  49. package/dist/messaging/imessage/index.js.map +1 -0
  50. package/dist/messaging/imessage/normalize-phone.d.ts +26 -0
  51. package/dist/messaging/imessage/normalize-phone.d.ts.map +1 -0
  52. package/dist/messaging/imessage/normalize-phone.js +55 -0
  53. package/dist/messaging/imessage/normalize-phone.js.map +1 -0
  54. package/dist/messaging/imessage/types.d.ts +95 -0
  55. package/dist/messaging/imessage/types.d.ts.map +1 -0
  56. package/dist/messaging/imessage/types.js +5 -0
  57. package/dist/messaging/imessage/types.js.map +1 -0
  58. package/dist/messaging/shared/MessagingEventBus.d.ts +5 -0
  59. package/dist/messaging/shared/MessagingEventBus.d.ts.map +1 -1
  60. package/dist/messaging/shared/MessagingEventBus.js.map +1 -1
  61. package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -1
  62. package/dist/messaging/slack/SlackAdapter.js +65 -1
  63. package/dist/messaging/slack/SlackAdapter.js.map +1 -1
  64. package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -1
  65. package/dist/messaging/slack/SocketModeClient.js +6 -0
  66. package/dist/messaging/slack/SocketModeClient.js.map +1 -1
  67. package/dist/monitoring/PresenceProxy.d.ts +6 -0
  68. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  69. package/dist/monitoring/PresenceProxy.js +46 -0
  70. package/dist/monitoring/PresenceProxy.js.map +1 -1
  71. package/dist/monitoring/QuotaExhaustionDetector.d.ts +15 -0
  72. package/dist/monitoring/QuotaExhaustionDetector.d.ts.map +1 -1
  73. package/dist/monitoring/QuotaExhaustionDetector.js +26 -3
  74. package/dist/monitoring/QuotaExhaustionDetector.js.map +1 -1
  75. package/dist/monitoring/SessionMonitor.d.ts.map +1 -1
  76. package/dist/monitoring/SessionMonitor.js +5 -2
  77. package/dist/monitoring/SessionMonitor.js.map +1 -1
  78. package/dist/monitoring/SessionRecovery.d.ts +16 -1
  79. package/dist/monitoring/SessionRecovery.d.ts.map +1 -1
  80. package/dist/monitoring/SessionRecovery.js +71 -8
  81. package/dist/monitoring/SessionRecovery.js.map +1 -1
  82. package/dist/scaffold/templates.d.ts +1 -1
  83. package/dist/scaffold/templates.d.ts.map +1 -1
  84. package/dist/scaffold/templates.js +32 -1
  85. package/dist/scaffold/templates.js.map +1 -1
  86. package/dist/scheduler/JobScheduler.js +1 -1
  87. package/dist/scheduler/JobScheduler.js.map +1 -1
  88. package/dist/server/AgentServer.d.ts +1 -0
  89. package/dist/server/AgentServer.d.ts.map +1 -1
  90. package/dist/server/AgentServer.js +1 -0
  91. package/dist/server/AgentServer.js.map +1 -1
  92. package/dist/server/routes.d.ts +1 -0
  93. package/dist/server/routes.d.ts.map +1 -1
  94. package/dist/server/routes.js +169 -0
  95. package/dist/server/routes.js.map +1 -1
  96. package/package.json +1 -1
  97. package/src/data/builtin-manifest.json +83 -67
  98. package/src/templates/hooks/intercept-imsg-send.js +68 -0
  99. package/src/templates/hooks/settings-template.json +11 -0
  100. package/src/templates/scripts/imessage-reply.sh +130 -0
  101. package/upgrades/0.26.4.md +17 -0
  102. package/upgrades/0.26.5.md +15 -0
@@ -0,0 +1,68 @@
1
+ /**
2
+ * intercept-imsg-send.js — PreToolUse hook to block direct iMessage sending.
3
+ *
4
+ * Layer 2 of the 5-layer outbound safety defense-in-depth.
5
+ *
6
+ * Blocks: imsg send, osascript+Messages.app, common indirect execution patterns.
7
+ * Allows: imsg chats, imsg --version, imsg --help (read-only operations).
8
+ *
9
+ * Known limitations (Phase 1 accepted risks):
10
+ * - Scripts written to files and executed bypass inline pattern matching
11
+ * - Base64-encoded commands bypass regex detection
12
+ * - macOS Shortcuts.app could be invoked to send messages
13
+ * - Addressed structurally in Phase 2 (OS-level permission revocation)
14
+ *
15
+ * Install: Place in .claude/hooks/ and register as PreToolUse hook on Bash tool.
16
+ * Integrity: chmod 444 after install. Server verifies SHA-256 hash periodically.
17
+ */
18
+
19
+ // Hook receives tool input on stdin
20
+ const input = await new Promise((resolve) => {
21
+ let data = '';
22
+ process.stdin.on('data', (chunk) => { data += chunk; });
23
+ process.stdin.on('end', () => {
24
+ try { resolve(JSON.parse(data)); }
25
+ catch { resolve({}); }
26
+ });
27
+ });
28
+
29
+ const toolName = input.tool_name || '';
30
+ const toolInput = input.tool_input || {};
31
+
32
+ // Only intercept Bash tool calls
33
+ if (toolName !== 'Bash') {
34
+ // Allow all non-Bash tools
35
+ process.stdout.write(JSON.stringify({ decision: 'allow' }));
36
+ process.exit(0);
37
+ }
38
+
39
+ const command = (toolInput.command || '').toString();
40
+
41
+ // Patterns that indicate direct iMessage sending
42
+ const BLOCKED_PATTERNS = [
43
+ // Direct imsg send
44
+ /\bimsg\s+send\b/i,
45
+ // AppleScript targeting Messages.app
46
+ /\bosascript\b.*\bMessages\b/i,
47
+ /\btell\s+application\s+"Messages"/i,
48
+ /\btell\s+application\s+'Messages'/i,
49
+ // Indirect execution with iMessage references
50
+ /\b(?:python3?|node|ruby|perl)\s+(?:-[ce]|--eval)\s+.*\b(?:imsg\s+send|Messages)\b/i,
51
+ // Piped execution
52
+ /\becho\s+.*\b(?:imsg\s+send|Messages)\b.*\|\s*(?:ba)?sh/i,
53
+ // Crontab modification (could schedule sends)
54
+ /\bcrontab\s+-[elr]/i,
55
+ // macOS Shortcuts that could send messages
56
+ /\bshortcuts\s+run\b.*(?:message|sms|imessage|send)/i,
57
+ ];
58
+
59
+ const isBlocked = BLOCKED_PATTERNS.some((p) => p.test(command));
60
+
61
+ if (isBlocked) {
62
+ process.stdout.write(JSON.stringify({
63
+ decision: 'block',
64
+ reason: 'Direct iMessage sending is blocked. Use imessage-reply.sh for authorized sends.',
65
+ }));
66
+ } else {
67
+ process.stdout.write(JSON.stringify({ decision: 'allow' }));
68
+ }
@@ -38,6 +38,17 @@
38
38
  }
39
39
  ]
40
40
  },
41
+ {
42
+ "matcher": "mcp__.*",
43
+ "hooks": [
44
+ {
45
+ "type": "command",
46
+ "command": "node .instar/hooks/instar/external-operation-gate.js",
47
+ "blocking": true,
48
+ "timeout": 5000
49
+ }
50
+ ]
51
+ },
41
52
  {
42
53
  "matcher": "AskUserQuestion",
43
54
  "hooks": [
@@ -0,0 +1,130 @@
1
+ #!/bin/bash
2
+ # imessage-reply.sh — Send a reply via iMessage with validate-before-send safety.
3
+ #
4
+ # Usage:
5
+ # ./imessage-reply.sh RECIPIENT "message text"
6
+ # echo "message text" | ./imessage-reply.sh RECIPIENT
7
+ # cat <<'EOF' | ./imessage-reply.sh RECIPIENT
8
+ # Multi-line message here
9
+ # EOF
10
+ #
11
+ # RECIPIENT is a phone number (+14081234567) or email (user@icloud.com).
12
+ #
13
+ # This script implements Layer 1 of the 5-layer outbound safety defense:
14
+ # 1. Validates recipient with server BEFORE sending (gets single-use token)
15
+ # 2. Sends the iMessage via `imsg send` CLI (requires Automation permission)
16
+ # 3. Confirms delivery to server with token (for logging + stall tracking)
17
+ #
18
+ # If validation fails, the message is NOT sent. This is the reverse of the
19
+ # original flow which sent first and notified second.
20
+
21
+ RECIPIENT="$1"
22
+ shift
23
+
24
+ if [ -z "$RECIPIENT" ]; then
25
+ echo "Usage: imessage-reply.sh RECIPIENT [message]" >&2
26
+ exit 1
27
+ fi
28
+
29
+ # Read message from args or stdin
30
+ if [ $# -gt 0 ]; then
31
+ MSG="$*"
32
+ else
33
+ MSG="$(cat)"
34
+ fi
35
+
36
+ if [ -z "$MSG" ]; then
37
+ echo "No message provided" >&2
38
+ exit 1
39
+ fi
40
+
41
+ # ── Setup ─────────────────────────────────────────────────────────────
42
+
43
+ PORT="${INSTAR_PORT:-4042}"
44
+
45
+ AUTH_TOKEN=""
46
+ if [ -f ".instar/config.json" ]; then
47
+ AUTH_TOKEN=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
48
+ fi
49
+
50
+ # Escape message for JSON
51
+ JSON_MSG=$(printf '%s' "$MSG" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null)
52
+ if [ -z "$JSON_MSG" ]; then
53
+ JSON_MSG="\"$(printf '%s' "$MSG" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g')\""
54
+ fi
55
+
56
+ # URL-encode the recipient
57
+ ENCODED_RECIPIENT=$(printf '%s' "$RECIPIENT" | python3 -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip(), safe=""))' 2>/dev/null)
58
+ if [ -z "$ENCODED_RECIPIENT" ]; then
59
+ ENCODED_RECIPIENT="$RECIPIENT"
60
+ fi
61
+
62
+ AUTH_HEADER=""
63
+ if [ -n "$AUTH_TOKEN" ]; then
64
+ AUTH_HEADER="Authorization: Bearer ${AUTH_TOKEN}"
65
+ fi
66
+
67
+ # ── Step 1: Validate with server BEFORE sending (get single-use token) ──
68
+
69
+ VALIDATE_RESPONSE=$(curl -s -w "\n%{http_code}" \
70
+ -X POST "http://localhost:${PORT}/imessage/validate-send/${ENCODED_RECIPIENT}" \
71
+ ${AUTH_HEADER:+-H "$AUTH_HEADER"} \
72
+ -H 'Content-Type: application/json' \
73
+ -d "{\"text\":${JSON_MSG}}" 2>/dev/null)
74
+
75
+ VALIDATE_BODY=$(echo "$VALIDATE_RESPONSE" | head -n -1)
76
+ VALIDATE_CODE=$(echo "$VALIDATE_RESPONSE" | tail -n 1)
77
+
78
+ if [ "$VALIDATE_CODE" != "200" ]; then
79
+ # Validation failed — DO NOT SEND
80
+ REASON=$(echo "$VALIDATE_BODY" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("reason","unknown"))' 2>/dev/null || echo "unknown")
81
+ echo "BLOCKED: $REASON" >&2
82
+
83
+ # Log blocked attempt locally as backup
84
+ echo "{\"blocked\":true,\"recipient\":\"${RECIPIENT}\",\"reason\":\"${REASON}\",\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" >> .instar/imessage-outbound-local.jsonl 2>/dev/null
85
+
86
+ exit 1
87
+ fi
88
+
89
+ # Extract send token
90
+ SEND_TOKEN=$(echo "$VALIDATE_BODY" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("token",""))' 2>/dev/null)
91
+
92
+ if [ -z "$SEND_TOKEN" ]; then
93
+ echo "BLOCKED: no send token received from server" >&2
94
+ exit 1
95
+ fi
96
+
97
+ # ── Step 2: Send via imsg CLI (only after validation passes) ──────────
98
+
99
+ IMSG="${IMSG_PATH:-imsg}"
100
+ if ! command -v "$IMSG" &>/dev/null; then
101
+ for candidate in /opt/homebrew/bin/imsg /usr/local/bin/imsg "$HOME/homebrew/bin/imsg"; do
102
+ if [ -x "$candidate" ]; then
103
+ IMSG="$candidate"
104
+ break
105
+ fi
106
+ done
107
+ fi
108
+
109
+ if ! command -v "$IMSG" &>/dev/null && [ ! -x "$IMSG" ]; then
110
+ echo "imsg not found. Install: brew install steipete/tap/imsg" >&2
111
+ exit 1
112
+ fi
113
+
114
+ "$IMSG" send --to "$RECIPIENT" --text "$MSG" --service imessage 2>/dev/null
115
+ SEND_STATUS=$?
116
+
117
+ if [ $SEND_STATUS -ne 0 ]; then
118
+ echo "imsg send failed (exit $SEND_STATUS)" >&2
119
+ exit 1
120
+ fi
121
+
122
+ # ── Step 3: Confirm delivery to server (with token to bind validate→send) ──
123
+
124
+ curl -s -o /dev/null -w "" -X POST "http://localhost:${PORT}/imessage/reply/${ENCODED_RECIPIENT}" \
125
+ ${AUTH_HEADER:+-H "$AUTH_HEADER"} \
126
+ -H 'Content-Type: application/json' \
127
+ -d "{\"text\":${JSON_MSG},\"sendToken\":\"${SEND_TOKEN}\"}" 2>/dev/null || \
128
+ echo "Warning: server confirmation failed (message was sent)" >&2
129
+
130
+ echo "Sent $(echo "$MSG" | wc -c | tr -d ' ') chars to $RECIPIENT"
@@ -0,0 +1,17 @@
1
+ # v0.26.4 — Inline Slack Text Snippets
2
+
3
+ ## What Changed
4
+
5
+ **Text snippet inlining** — When users share text-based content in Slack (code snippets, meeting transcripts, plain text, markdown, CSV, JSON, etc.), the content is now inlined directly into the message as a code block. Previously, snippets were saved as file references that sessions often did not read, causing agents to hallucinate content instead of working with the actual snippet.
6
+
7
+ Detects text-based mimetypes and Slack-specific filetypes (text, snippet, post). Content up to 10KB is inlined. Larger content is truncated with a reference to the full file.
8
+
9
+ ## What to Tell Your User
10
+
11
+ When you share text snippets or code blocks in Slack, the bot now reads and processes the actual content instead of just noting that a file was attached. This means meeting transcripts, code snippets, and other text content will be analyzed correctly.
12
+
13
+ ## Summary of New Capabilities
14
+
15
+ | Capability | How to Use |
16
+ |-----------|-----------|
17
+ | Snippet inlining | Share a text snippet or code block in Slack — content is read directly |
@@ -0,0 +1,15 @@
1
+ # v0.26.5 — Fix Slack Snippet Content Retrieval
2
+
3
+ ## What Changed
4
+
5
+ **Three-tier snippet content resolution** — Slack snippet downloads were returning HTML pages instead of actual content (auth/redirect issue). Now uses a three-tier approach: (1) check file preview from the event payload, (2) use files.info API to get content directly, (3) fall back to downloaded file but reject HTML responses. This prevents agents from hallucinating based on HTML markup.
6
+
7
+ ## What to Tell Your User
8
+
9
+ Fixed an issue where text snippets shared in Slack were not being read correctly. The bot now properly retrieves snippet content using multiple fallback methods, so it will respond based on what you actually shared rather than making up content.
10
+
11
+ ## Summary of New Capabilities
12
+
13
+ | Capability | How to Use |
14
+ |-----------|-----------|
15
+ | Reliable snippet reading | Share a text snippet in Slack — content is now reliably retrieved |