feature-architect-agent 1.0.9 → 1.0.10

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.
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"AAQA,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACjB,GACL,OAAO,CAAC,IAAI,CAAC,CAgJf"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"AAQA,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACjB,GACL,OAAO,CAAC,IAAI,CAAC,CAyJf"}
@@ -39,7 +39,12 @@ async function planCommand(feature, options = {}) {
39
39
  // Auto-detect if not specified
40
40
  if (!provider) {
41
41
  // Check for API keys in environment (no built-in keys for security)
42
- if (process.env.GOOGLE_API_KEY) {
42
+ // Opencode first (free local models)
43
+ if (process.env.OPENCODE_BASE_URL || process.env.OPENCODE_URL) {
44
+ provider = 'opencode';
45
+ apiKey = 'not-needed';
46
+ }
47
+ else if (process.env.GOOGLE_API_KEY) {
43
48
  provider = 'google';
44
49
  apiKey = process.env.GOOGLE_API_KEY;
45
50
  }
@@ -58,14 +63,16 @@ async function planCommand(feature, options = {}) {
58
63
  }
59
64
  else {
60
65
  (0, logger_js_1.error)('No API key found');
61
- (0, logger_js_1.dim)('You need to set an API key to use this tool.');
66
+ (0, logger_js_1.dim)('You need to set an API key or local LLM to use this tool.');
62
67
  (0, logger_js_1.dim)('');
63
68
  (0, logger_js_1.dim)('Choose one of these options:');
64
- (0, logger_js_1.dim)(' export GOOGLE_API_KEY=xxx # For Gemini (recommended)');
69
+ (0, logger_js_1.dim)(' export OPENCODE_BASE_URL=http://localhost:11434/v1 # For OpenCode/Ollama (FREE)');
70
+ (0, logger_js_1.dim)(' export GOOGLE_API_KEY=xxx # For Gemini');
65
71
  (0, logger_js_1.dim)(' export OPENAI_API_KEY=sk-xxx # For OpenAI');
66
72
  (0, logger_js_1.dim)(' export ANTHROPIC_API_KEY=sk-ant-xxx # For Claude');
67
73
  (0, logger_js_1.dim)('');
68
74
  (0, logger_js_1.dim)('Get API keys:');
75
+ (0, logger_js_1.dim)(' OpenCode/Ollama: Install locally - FREE!');
69
76
  (0, logger_js_1.dim)(' Gemini: https://aistudio.google.com/app/apikey');
70
77
  (0, logger_js_1.dim)(' OpenAI: https://platform.openai.com/api-keys');
71
78
  (0, logger_js_1.dim)(' Anthropic: https://console.anthropic.com/settings/keys');
@@ -89,6 +96,10 @@ async function planCommand(feature, options = {}) {
89
96
  provider = 'google';
90
97
  apiKey = (0, api_config_js_1.getApiKey)('google');
91
98
  }
99
+ else if (providerLower === 'opencode' || providerLower === 'ollama') {
100
+ provider = 'opencode';
101
+ apiKey = 'not-needed'; // Local LLMs don't need API keys
102
+ }
92
103
  if (!apiKey) {
93
104
  (0, logger_js_1.error)(`No API key found for ${provider}`);
94
105
  (0, logger_js_1.dim)(`Set it with: export ${provider.toUpperCase()}_API_KEY=xxx`);
@@ -0,0 +1,38 @@
1
+ /**
2
+ * OpenCode Provider
3
+ *
4
+ * For local LLM servers with OpenAI-compatible APIs.
5
+ * Commonly used with:
6
+ * - OpenCode
7
+ * - LM Studio
8
+ * - LocalAI
9
+ * - text-generation-webui
10
+ */
11
+ import type { LLMProvider } from './types.js';
12
+ export interface OpenCodeConfig {
13
+ baseURL?: string;
14
+ model?: string;
15
+ }
16
+ export declare class OpenCodeProvider implements LLMProvider {
17
+ private baseURL;
18
+ private model;
19
+ private apiKey;
20
+ constructor(apiKey?: string, // Local servers often don't need API keys
21
+ config?: OpenCodeConfig);
22
+ generate(prompt: string, options?: {
23
+ temperature?: number;
24
+ maxTokens?: number;
25
+ }): Promise<string>;
26
+ /**
27
+ * Update the model being used
28
+ */
29
+ setModel(model: string): void;
30
+ /**
31
+ * Get current configuration
32
+ */
33
+ getConfig(): {
34
+ baseURL: string;
35
+ model: string;
36
+ };
37
+ }
38
+ //# sourceMappingURL=Opencode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Opencode.d.ts","sourceRoot":"","sources":["../../src/llm/Opencode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,gBAAiB,YAAW,WAAW;IAClD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;gBAGrB,MAAM,GAAE,MAAqB,EAAE,0CAA0C;IACzE,MAAM,GAAE,cAAmB;IAOvB,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACzD,OAAO,CAAC,MAAM,CAAC;IAgDlB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B;;OAEG;IACH,SAAS,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAGhD"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /**
3
+ * OpenCode Provider
4
+ *
5
+ * For local LLM servers with OpenAI-compatible APIs.
6
+ * Commonly used with:
7
+ * - OpenCode
8
+ * - LM Studio
9
+ * - LocalAI
10
+ * - text-generation-webui
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.OpenCodeProvider = void 0;
14
+ class OpenCodeProvider {
15
+ baseURL;
16
+ model;
17
+ apiKey;
18
+ constructor(apiKey = 'not-needed', // Local servers often don't need API keys
19
+ config = {}) {
20
+ this.baseURL = config.baseURL || process.env.OPENCODE_BASE_URL || 'http://localhost:11434/v1';
21
+ this.model = config.model || process.env.OPENCODE_MODEL || 'llama3.2';
22
+ this.apiKey = apiKey;
23
+ }
24
+ async generate(prompt, options = {}) {
25
+ const temperature = options.temperature ?? 0.7;
26
+ const maxTokens = options.maxTokens ?? 8000;
27
+ try {
28
+ const response = await fetch(`${this.baseURL}/chat/completions`, {
29
+ method: 'POST',
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ ...(this.apiKey && this.apiKey !== 'not-needed' && {
33
+ Authorization: `Bearer ${this.apiKey}`
34
+ })
35
+ },
36
+ body: JSON.stringify({
37
+ model: this.model,
38
+ messages: [
39
+ {
40
+ role: 'user',
41
+ content: prompt
42
+ }
43
+ ],
44
+ temperature,
45
+ max_tokens: maxTokens
46
+ })
47
+ });
48
+ if (!response.ok) {
49
+ const errorText = await response.text();
50
+ throw new Error(`OpenCode API error: ${response.status} ${response.statusText}\n${errorText}`);
51
+ }
52
+ const data = await response.json();
53
+ if (data.error) {
54
+ throw new Error(`OpenCode API error: ${data.error.message || JSON.stringify(data.error)}`);
55
+ }
56
+ return data.choices[0]?.message?.content || '';
57
+ }
58
+ catch (error) {
59
+ if (error instanceof Error) {
60
+ throw new Error(`OpenCode request failed: ${error.message}`);
61
+ }
62
+ throw new Error('OpenCode request failed with unknown error');
63
+ }
64
+ }
65
+ /**
66
+ * Update the model being used
67
+ */
68
+ setModel(model) {
69
+ this.model = model;
70
+ }
71
+ /**
72
+ * Get current configuration
73
+ */
74
+ getConfig() {
75
+ return { baseURL: this.baseURL, model: this.model };
76
+ }
77
+ }
78
+ exports.OpenCodeProvider = OpenCodeProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/llm/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3G,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAWD,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CAsClE"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/llm/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3G,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAWD,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CA4ClE"}
@@ -4,6 +4,7 @@ exports.createProvider = createProvider;
4
4
  const Claude_js_1 = require("./Claude.js");
5
5
  const OpenAI_js_1 = require("./OpenAI.js");
6
6
  const Gemini_js_1 = require("./Gemini.js");
7
+ const Opencode_js_1 = require("./Opencode.js");
7
8
  /**
8
9
  * Normalize provider name - accepts both 'claude'/'anthropic' and 'gemini'/'google'
9
10
  */
@@ -28,7 +29,10 @@ function createProvider(config) {
28
29
  case 'gemini':
29
30
  return new Gemini_js_1.GeminiProvider(apiKey, config.model || 'gemini-flash-latest');
30
31
  case 'opencode':
31
- throw new Error('OpenCode provider not yet implemented');
32
+ return new Opencode_js_1.OpenCodeProvider(apiKey || 'not-needed', {
33
+ baseURL: process.env.OPENCODE_BASE_URL || 'http://localhost:11434/v1',
34
+ model: config.model || process.env.OPENCODE_MODEL || 'llama3.2'
35
+ });
32
36
  case 'ollama':
33
37
  throw new Error('Ollama provider not yet implemented');
34
38
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feature-architect-agent",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "AI-powered feature planning agent - generates complete technical specifications",
5
5
  "main": "dist/index.js",
6
6
  "bin": {