@afromero/kin3o 0.2.4 → 0.2.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.
package/README.md CHANGED
@@ -9,6 +9,8 @@
9
9
  [![CI](https://github.com/affromero/kin3o/actions/workflows/ci.yml/badge.svg)](https://github.com/affromero/kin3o/actions/workflows/ci.yml)
10
10
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](https://www.typescriptlang.org/)
11
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
12
+ [![Socket](https://img.shields.io/badge/Socket-protected-blueviolet?logo=socket.dev)](https://socket.dev)
13
+ [![min-release-age](https://img.shields.io/badge/min--release--age-7%20days-brightgreen)](https://docs.npmjs.com/cli/v10/using-npm/config#min-release-age)
12
14
  [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/affromero/kin3o/pulls)
13
15
 
14
16
  AI-powered Lottie animation generator. Turns natural language prompts into valid, playable Lottie JSON and interactive dotLottie state machines using your existing Claude or Codex subscription.
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { existsSync, readFileSync, statSync, writeFileSync } from 'node:fs';
3
3
  import { join, resolve } from 'node:path';
4
4
  import { Command } from 'commander';
5
- import { PROVIDERS, detectAvailableProviders, getDefaultProvider } from './providers/registry.js';
5
+ import { PROVIDERS, detectAvailableProviders, getDefaultProvider, diagnoseProvider } from './providers/registry.js';
6
6
  import { buildSystemPrompt, buildInteractiveSystemPrompt, buildRefinementUserPrompt, buildInteractiveRefinementUserPrompt, loadDesignTokens } from './prompts/index.js';
7
7
  import { validateLottie, autoFix } from './validator.js';
8
8
  import { validateStateMachine } from './state-machine-validator.js';
@@ -37,7 +37,7 @@ program
37
37
  if (!providerKey) {
38
38
  providerKey = await getDefaultProvider() ?? undefined;
39
39
  if (!providerKey) {
40
- console.error(' ✗ No AI providers available. Install Claude Code, Codex, or set ANTHROPIC_API_KEY.');
40
+ console.error(' ✗ No AI providers available. Run `kin3o providers` for diagnostics.');
41
41
  process.exit(1);
42
42
  }
43
43
  }
@@ -204,7 +204,7 @@ program
204
204
  if (!providerKey) {
205
205
  providerKey = await getDefaultProvider() ?? undefined;
206
206
  if (!providerKey) {
207
- console.error(' ✗ No AI providers available. Install Claude Code, Codex, or set ANTHROPIC_API_KEY.');
207
+ console.error(' ✗ No AI providers available. Run `kin3o providers` for diagnostics.');
208
208
  process.exit(1);
209
209
  }
210
210
  }
@@ -371,9 +371,22 @@ program
371
371
  const available = await detectAvailableProviders();
372
372
  console.log('\nAvailable AI Providers:\n');
373
373
  for (const [key, config] of Object.entries(PROVIDERS)) {
374
- const status = available.includes(key) ? '✓' : '✗';
374
+ const isAvail = available.includes(key);
375
+ const status = isAvail ? '✓' : '✗';
375
376
  console.log(` ${status} ${config.displayName} (${key})`);
376
377
  console.log(` Models: ${config.models.join(', ')}`);
378
+ if (!isAvail) {
379
+ const diag = diagnoseProvider(key);
380
+ if (!diag.binaryFound) {
381
+ console.log(` Problem: "${diag.binaryName}" not found on PATH`);
382
+ console.log(` Fix: Install ${config.displayName} and ensure "${diag.binaryName}" is on your PATH`);
383
+ }
384
+ else if (!diag.authFound) {
385
+ const cmd = key === 'codex' ? 'codex auth' : 'claude';
386
+ console.log(` Problem: CLI found but not authenticated`);
387
+ console.log(` Fix: Run \`${cmd}\` to log in`);
388
+ }
389
+ }
377
390
  }
378
391
  console.log('');
379
392
  });
@@ -13,7 +13,15 @@ export interface ProviderConfig {
13
13
  }
14
14
  /** Get timeout with optional user override */
15
15
  export declare function getTimeoutMs(userOverride?: number): number;
16
+ export interface ProviderDiagnosis {
17
+ binaryFound: boolean;
18
+ authFound: boolean;
19
+ binaryName: string;
20
+ authPaths: string[];
21
+ }
16
22
  export declare const PROVIDERS: Record<string, ProviderConfig>;
23
+ /** Diagnose why a provider is or isn't available */
24
+ export declare function diagnoseProvider(key: string): ProviderDiagnosis;
17
25
  /** Detect which providers are available (binary + auth) */
18
26
  export declare function detectAvailableProviders(): Promise<string[]>;
19
27
  /** Get default provider (first available in priority order) */
@@ -29,7 +29,8 @@ export const PROVIDERS = {
29
29
  if (!hasBinary('claude'))
30
30
  return false;
31
31
  return existsSync(join(home, '.claude.json'))
32
- || existsSync(join(home, '.claude', 'credentials.json'));
32
+ || existsSync(join(home, '.claude', 'credentials.json'))
33
+ || existsSync(join(home, '.claude', '.credentials.json'));
33
34
  },
34
35
  generate: generateWithClaude,
35
36
  },
@@ -45,6 +46,31 @@ export const PROVIDERS = {
45
46
  generate: generateWithCodex,
46
47
  },
47
48
  };
49
+ const PROVIDER_BINARIES = {
50
+ 'claude-code': 'claude',
51
+ codex: 'codex',
52
+ };
53
+ const PROVIDER_AUTH_PATHS = {
54
+ 'claude-code': [
55
+ join(home, '.claude.json'),
56
+ join(home, '.claude', 'credentials.json'),
57
+ join(home, '.claude', '.credentials.json'),
58
+ ],
59
+ codex: [
60
+ join(home, '.codex', 'auth.json'),
61
+ ],
62
+ };
63
+ /** Diagnose why a provider is or isn't available */
64
+ export function diagnoseProvider(key) {
65
+ const binaryName = PROVIDER_BINARIES[key] ?? key;
66
+ const authPaths = PROVIDER_AUTH_PATHS[key] ?? [];
67
+ return {
68
+ binaryFound: hasBinary(binaryName),
69
+ authFound: authPaths.some(p => existsSync(p)),
70
+ binaryName,
71
+ authPaths,
72
+ };
73
+ }
48
74
  /** Detect which providers are available (binary + auth) */
49
75
  export async function detectAvailableProviders() {
50
76
  const available = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afromero/kin3o",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "AI-powered Lottie animation generator — text to motion from your terminal",
5
5
  "type": "module",
6
6
  "license": "MIT",