@claudemini/shit-cli 1.6.0 → 1.7.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
@@ -254,6 +254,7 @@ Set one of these environment variables to enable AI-powered session summaries:
254
254
 
255
255
  ```bash
256
256
  export OPENAI_API_KEY=sk-... # Uses gpt-4o-mini by default
257
+ export OPENAI_BASE_URL=https://api.openai.com/v1 # Optional: OpenAI-compatible base URL
257
258
  export ANTHROPIC_API_KEY=sk-... # Uses claude-3-haiku by default
258
259
  ```
259
260
 
@@ -268,6 +269,8 @@ shit summarize <session-id>
268
269
  |----------|-------------|
269
270
  | `SHIT_LOG_DIR` | Custom log directory (default: `.shit-logs` in project root) |
270
271
  | `OPENAI_API_KEY` | Enable AI summaries via OpenAI |
272
+ | `OPENAI_BASE_URL` | OpenAI-compatible base URL for summaries (default: `https://api.openai.com/v1`) |
273
+ | `OPENAI_ENDPOINT` | Full OpenAI-compatible endpoint (overrides `OPENAI_BASE_URL`) |
271
274
  | `ANTHROPIC_API_KEY` | Enable AI summaries via Anthropic |
272
275
 
273
276
  ## Security
package/lib/summarize.js CHANGED
@@ -16,24 +16,15 @@ const DEFAULT_CONFIG = {
16
16
  model: 'gpt-4o-mini',
17
17
  max_tokens: 1000,
18
18
  temperature: 0.7,
19
+ openai_base_url: 'https://api.openai.com/v1',
19
20
  };
20
21
 
21
22
  /**
22
23
  * Get API configuration from environment or config file
23
24
  */
24
25
  function getApiConfig(projectRoot) {
25
- // Check for environment variables first
26
26
  const config = { ...DEFAULT_CONFIG };
27
27
 
28
- // OpenAI
29
- if (process.env.OPENAI_API_KEY) {
30
- config.provider = 'openai';
31
- config.api_key = process.env.OPENAI_API_KEY;
32
- } else if (process.env.ANTHROPIC_API_KEY) {
33
- config.provider = 'anthropic';
34
- config.api_key = process.env.ANTHROPIC_API_KEY;
35
- }
36
-
37
28
  // Check for project config
38
29
  const configFile = join(projectRoot, '.shit-logs', 'config.json');
39
30
  if (existsSync(configFile)) {
@@ -45,6 +36,22 @@ function getApiConfig(projectRoot) {
45
36
  }
46
37
  }
47
38
 
39
+ // Environment variables override file config
40
+ if (process.env.OPENAI_API_KEY) {
41
+ config.provider = 'openai';
42
+ config.api_key = process.env.OPENAI_API_KEY;
43
+ } else if (process.env.ANTHROPIC_API_KEY) {
44
+ config.provider = 'anthropic';
45
+ config.api_key = process.env.ANTHROPIC_API_KEY;
46
+ }
47
+
48
+ if (process.env.OPENAI_BASE_URL) {
49
+ config.openai_base_url = process.env.OPENAI_BASE_URL;
50
+ }
51
+ if (process.env.OPENAI_ENDPOINT) {
52
+ config.openai_endpoint = process.env.OPENAI_ENDPOINT;
53
+ }
54
+
48
55
  return config;
49
56
  }
50
57
 
@@ -159,8 +166,21 @@ function buildSummarizePrompt(context) {
159
166
  /**
160
167
  * Call OpenAI API
161
168
  */
162
- async function callOpenAI(apiKey, model, prompt, maxTokens, temperature) {
163
- const response = await fetch('https://api.openai.com/v1/chat/completions', {
169
+ function resolveOpenAIEndpoint(config) {
170
+ const explicitEndpoint = (config.openai_endpoint || '').trim();
171
+ if (explicitEndpoint) {
172
+ return explicitEndpoint;
173
+ }
174
+
175
+ const baseUrl = String(config.openai_base_url || DEFAULT_CONFIG.openai_base_url).trim().replace(/\/+$/, '');
176
+ if (baseUrl.endsWith('/chat/completions')) {
177
+ return baseUrl;
178
+ }
179
+ return `${baseUrl}/chat/completions`;
180
+ }
181
+
182
+ async function callOpenAI(apiKey, endpoint, model, prompt, maxTokens, temperature) {
183
+ const response = await fetch(endpoint, {
164
184
  method: 'POST',
165
185
  headers: {
166
186
  'Content-Type': 'application/json',
@@ -247,8 +267,10 @@ export async function summarizeSession(projectRoot, sessionId, sessionDir) {
247
267
  config.temperature
248
268
  );
249
269
  } else {
270
+ const openaiEndpoint = resolveOpenAIEndpoint(config);
250
271
  summary = await callOpenAI(
251
272
  config.api_key,
273
+ openaiEndpoint,
252
274
  config.model || 'gpt-4o-mini',
253
275
  prompt,
254
276
  config.max_tokens,
@@ -301,9 +323,11 @@ export default async function summarize(args) {
301
323
  console.log('Usage: shit summarize <session-id>');
302
324
  console.log('\nEnvironment variables:');
303
325
  console.log(' OPENAI_API_KEY # Use OpenAI for summarization');
326
+ console.log(' OPENAI_BASE_URL # OpenAI-compatible base URL (e.g. https://api.openai.com/v1)');
327
+ console.log(' OPENAI_ENDPOINT # Full OpenAI-compatible endpoint (overrides OPENAI_BASE_URL)');
304
328
  console.log(' ANTHROPIC_API_KEY # Use Anthropic for summarization');
305
329
  console.log('\nConfiguration (.shit-logs/config.json):');
306
- console.log(` {"provider": "openai", "model": "gpt-4o-mini"}`);
330
+ console.log(` {"provider": "openai", "model": "gpt-4o-mini", "openai_base_url": "https://api.openai.com/v1"}`);
307
331
  process.exit(1);
308
332
  }
309
333
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudemini/shit-cli",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Session-based Hook Intelligence Tracker - Zero-dependency memory system for human-AI coding sessions",
5
5
  "type": "module",
6
6
  "bin": {