askgloss 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -1,14 +1,14 @@
1
- # askgloss
2
-
3
- Runs the [Gloss](https://askgloss.app) server on your computer with your own OpenAI API key, so you can use the Gloss Chrome extension without an account or daily limits. OpenAI bills your key directly.
4
-
5
- ```sh
6
- npx askgloss
7
- ```
8
-
9
- Paste your OpenAI API key when asked (or set `OPENAI_API_KEY`). Keep the window open while you use Gloss; the extension connects to `http://127.0.0.1:3000`. Requires Node.js 20 or later.
10
-
11
- - `--port <number>` listens on another port. Enter the new address under "Your own server" in Gloss Settings.
12
- - `--forget` deletes the saved key.
13
-
14
- Websites can't use it: the server refuses requests from web pages. Page content, screenshots and voice go from the extension to this server and on to OpenAI; nothing goes through askgloss.app.
1
+ # askgloss
2
+
3
+ Runs the [Gloss](https://askgloss.app) server on your computer with your own OpenAI API key, so you can use the Gloss Chrome extension without an account or daily limits. OpenAI bills your key directly.
4
+
5
+ ```sh
6
+ npx askgloss
7
+ ```
8
+
9
+ Paste your OpenAI API key when asked (or set `OPENAI_API_KEY`). Keep the window open while you use Gloss; the extension connects to `http://127.0.0.1:3000`. Requires Node.js 20 or later.
10
+
11
+ - `--port <number>` listens on another port. Enter the new address under "Your own server" in Gloss Settings.
12
+ - `--forget` deletes the saved key.
13
+
14
+ Websites can't use it: the server refuses requests from web pages. Page content, screenshots and voice go from the extension to this server and on to OpenAI; nothing goes through askgloss.app.
package/dist/cli/index.js CHANGED
@@ -48,9 +48,8 @@ async function checkKey(apiKey) {
48
48
  const response = await fetch('https://api.openai.com/v1/models', { headers: { Authorization: 'Bearer ' + apiKey }, signal: AbortSignal.timeout(15000) }).catch(() => null);
49
49
  if (!response)
50
50
  return 'Could not reach OpenAI. Check your internet connection.';
51
- if (response.status === 401)
52
- return 'OpenAI rejected that key.';
53
- return response.ok ? '' : `OpenAI returned an error (${response.status}).`;
51
+ // Only a rejected key is fatal. Restricted keys may lack permission to list models yet still run Gloss.
52
+ return response.status === 401 ? 'OpenAI rejected that key.' : '';
54
53
  }
55
54
  // Exiting through process.exit while a fetch socket is still open crashes Node on Windows, so failures set exitCode and return.
56
55
  async function getKey() {
@@ -82,6 +81,11 @@ async function getKey() {
82
81
  return apiKey;
83
82
  }
84
83
  const port = Number(option('--port') || process.env.PORT || 3000);
84
+ // Only Gloss may spend this key: other extensions with access to 127.0.0.1 are refused. EXTENSION_ID
85
+ // (comma-separated) replaces the list, for example for an unpacked build loaded from another folder.
86
+ // TODO: add the Chrome Web Store ID once the listing exists.
87
+ const glossExtensionIds = ['onooiajelfmchgbghniiaogkaahgkmpc', 'hlbhiofbfhhfhcbgohbmhgkhdnmpfcjm'];
88
+ const extensionIds = process.env.EXTENSION_ID?.split(',').map(id => id.trim()).filter(Boolean) || glossExtensionIds;
85
89
  // Only problems reach the terminal; conversations and page content are never printed.
86
90
  const log = (event, details = {}) => {
87
91
  if (event === 'openai.error')
@@ -93,7 +97,7 @@ const apiKey = await getKey();
93
97
  if (!apiKey)
94
98
  process.exitCode = 1;
95
99
  else {
96
- const server = createApp({ apiKey, log, accessToken: '', clerkJwtKey: '' });
100
+ const server = createApp({ apiKey, log, accessToken: '', clerkJwtKey: '', extensionIds });
97
101
  server.on('error', (error) => {
98
102
  console.error(error.code === 'EADDRINUSE' ? `Port ${port} is already in use. Is Gloss already running? Otherwise try \`npx askgloss --port ${port + 1}\`.` : error.message);
99
103
  process.exitCode = 1;
@@ -67,7 +67,7 @@ async function readJson(req, limit) {
67
67
  }
68
68
  }
69
69
  const listFromEnv = (value) => (value || '').split(',').map(item => item.trim()).filter(Boolean);
70
- export function createHandler({ apiKey = process.env.OPENAI_API_KEY, accessToken = process.env.ACCESS_TOKEN, clerkJwtKey = process.env.CLERK_JWT_KEY, authorizedParties = listFromEnv(process.env.CLERK_AUTHORIZED_PARTIES), extensionId = process.env.EXTENSION_ID, usage = createUsage(), fetchImpl = fetch, log = createLogger() } = {}) {
70
+ export function createHandler({ apiKey = process.env.OPENAI_API_KEY, accessToken = process.env.ACCESS_TOKEN, clerkJwtKey = process.env.CLERK_JWT_KEY, authorizedParties = listFromEnv(process.env.CLERK_AUTHORIZED_PARTIES), extensionIds = listFromEnv(process.env.EXTENSION_ID), usage = createUsage(), fetchImpl = fetch, log = createLogger() } = {}) {
71
71
  const authenticate = createAuth({ accessToken, clerkJwtKey, authorizedParties });
72
72
  async function callOpenAI(path, body) {
73
73
  if (!apiKey)
@@ -141,7 +141,7 @@ export function createHandler({ apiKey = process.env.OPENAI_API_KEY, accessToken
141
141
  async function handle(req, requestId) {
142
142
  // Only the extension may call this server. Never enable website CORS.
143
143
  const origin = req.headers.origin;
144
- if (origin && (!/^chrome-extension:\/\/[a-p]{32}$/.test(origin) || (extensionId && origin !== 'chrome-extension://' + extensionId)))
144
+ if (origin && (!/^chrome-extension:\/\/[a-p]{32}$/.test(origin) || (extensionIds.length && !extensionIds.includes(origin.slice(19)))))
145
145
  throw new HttpError(403, 'Only the browser extension can connect.');
146
146
  // Vercel's rewrite adds the route as a query string; only the path matters.
147
147
  const path = (req.url || '').split('?')[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "askgloss",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Run the Gloss server on your computer with your own OpenAI API key.",
5
5
  "homepage": "https://askgloss.app",
6
6
  "repository": { "type": "git", "url": "git+https://github.com/adamblumoff/browser-live-ui.git", "directory": "cli" },