@openthread/claude-code-plugin 0.1.5 → 0.1.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openthread/claude-code-plugin",
3
- "version": "0.1.5",
4
- "description": "Share Claude Code conversations to OpenThread",
3
+ "version": "0.1.8",
4
+ "description": "Share Claude Code conversations to OpenThread — the StackOverflow for AI agents. One command to publish any session to the community platform for the agentic AI era.",
5
5
  "bin": {
6
6
  "openthread-claude": "bin/cli.sh"
7
7
  },
@@ -13,11 +13,16 @@
13
13
  "scripts/auth.sh",
14
14
  "scripts/share.sh",
15
15
  "scripts/token.sh",
16
+ "scripts/lib/",
16
17
  "icon.svg"
17
18
  ],
18
19
  "scripts": {
19
20
  "prepack": "node -e \"const fs=require('fs');const v=JSON.parse(fs.readFileSync('package.json','utf8')).version;const p=JSON.parse(fs.readFileSync('.claude-plugin/plugin.json','utf8'));p.version=v;fs.writeFileSync('.claude-plugin/plugin.json',JSON.stringify(p,null,2)+'\\n')\"",
20
- "postinstall": "node bin/postinstall.js"
21
+ "postinstall": "node bin/postinstall.js",
22
+ "test": "node bin/__tests__/settings-writer.test.js"
23
+ },
24
+ "dependencies": {
25
+ "keytar": "^7.9.0"
21
26
  },
22
27
  "keywords": [
23
28
  "claude-code",
@@ -25,8 +30,21 @@
25
30
  "openthread",
26
31
  "plugin",
27
32
  "ai",
28
- "conversation",
29
- "share"
33
+ "ai-agents",
34
+ "agentic-ai",
35
+ "ai-conversation",
36
+ "ai-conversations",
37
+ "ai-thread",
38
+ "ai-thread-sharing",
39
+ "share-claude",
40
+ "share-conversation",
41
+ "claude-share",
42
+ "ai-community",
43
+ "stackoverflow-for-ai",
44
+ "claude-code-plugin",
45
+ "anthropic",
46
+ "prompt-sharing",
47
+ "ai-social"
30
48
  ],
31
49
  "author": "OpenThread",
32
50
  "license": "MIT"
package/scripts/auth.sh CHANGED
@@ -30,9 +30,13 @@ main() {
30
30
 
31
31
  generate_pkce
32
32
 
33
+ # Generate state parameter for CSRF protection
34
+ STATE=$(openssl rand -hex 16)
35
+
33
36
  # Create a temp file for server output
34
37
  AUTH_OUTPUT=$(mktemp)
35
- trap 'rm -f "$AUTH_OUTPUT"' EXIT
38
+ STATE_OUTPUT=$(mktemp)
39
+ trap 'rm -f "$AUTH_OUTPUT" "$STATE_OUTPUT"' EXIT
36
40
 
37
41
  # Start local callback server, capturing output
38
42
  python3 -c "
@@ -46,12 +50,16 @@ class Handler(http.server.BaseHTTPRequestHandler):
46
50
 
47
51
  if parsed.path == '/callback' and 'code' in params:
48
52
  code = params['code'][0]
53
+ state = params.get('state', [None])[0]
49
54
  self.send_response(200)
50
55
  self.send_header('Content-Type', 'text/html')
51
56
  self.end_headers()
52
57
  self.wfile.write(b'<html><body><h2>Authorization successful!</h2><p>You can close this tab and return to Claude Code.</p><script>window.close()</script></body></html>')
53
58
  with open('$AUTH_OUTPUT', 'w') as f:
54
59
  f.write(code)
60
+ if state:
61
+ with open('$STATE_OUTPUT', 'w') as f:
62
+ f.write(state)
55
63
  else:
56
64
  self.send_response(404)
57
65
  self.end_headers()
@@ -79,7 +87,7 @@ except OSError as e:
79
87
  fi
80
88
 
81
89
  # Build authorization URL and open browser
82
- AUTH_URL="${WEB_BASE}/extension/callback?code_challenge=${CODE_CHALLENGE}&extension_id=${EXTENSION_ID}&redirect_uri=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${REDIRECT_URI}', safe=''))")"
90
+ AUTH_URL="${WEB_BASE}/extension/callback?code_challenge=${CODE_CHALLENGE}&extension_id=${EXTENSION_ID}&redirect_uri=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${REDIRECT_URI}', safe=''))")&state=${STATE}"
83
91
 
84
92
  echo "Opening browser for authorization..." >&2
85
93
 
@@ -115,6 +123,15 @@ except OSError as e:
115
123
  return $?
116
124
  fi
117
125
 
126
+ # Verify state parameter to prevent CSRF
127
+ if [ -s "$STATE_OUTPUT" ]; then
128
+ RECEIVED_STATE=$(cat "$STATE_OUTPUT")
129
+ if [ "$RECEIVED_STATE" != "$STATE" ]; then
130
+ echo "ERROR: State parameter mismatch — auth may have been tampered with." >&2
131
+ return 1
132
+ fi
133
+ fi
134
+
118
135
  # Exchange the code for tokens
119
136
  exchange_code "$AUTH_CODE"
120
137
  }
@@ -154,7 +171,8 @@ exchange_code() {
154
171
  -d "{
155
172
  \"code\": \"${auth_code}\",
156
173
  \"codeVerifier\": \"${CODE_VERIFIER}\",
157
- \"extensionId\": \"${EXTENSION_ID}\"
174
+ \"extensionId\": \"${EXTENSION_ID}\",
175
+ \"redirectUri\": \"${REDIRECT_URI}\"
158
176
  }")
159
177
 
160
178
  HTTP_CODE=$(echo "$RESPONSE" | tail -1)
@@ -0,0 +1 @@
1
+ """Shared Python helpers for the OpenThread Claude Code plugin."""