jobarbiter 0.3.7 → 0.3.9
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/dist/lib/onboard.js +32 -15
- package/dist/lib/providers.d.ts +4 -0
- package/dist/lib/providers.js +27 -0
- package/package.json +1 -1
- package/src/lib/onboard.ts +31 -15
- package/src/lib/providers.ts +33 -0
package/dist/lib/onboard.js
CHANGED
|
@@ -435,9 +435,11 @@ async function runToolDetectionStep(prompt, config) {
|
|
|
435
435
|
console.log(` communication clarity, iteration patterns, tool fluency\n`);
|
|
436
436
|
console.log(` This is what makes your profile ${c.bold("verified")} and ${c.bold("valuable")}.`);
|
|
437
437
|
console.log(` Your observer regularly records and reports your proven AI proficiency.\n`);
|
|
438
|
-
console.log(` ${c.bold("Privacy:")} ${c.highlight("
|
|
439
|
-
console.log(`
|
|
440
|
-
console.log(`
|
|
438
|
+
console.log(` ${c.bold("Privacy:")} Analysis runs ${c.highlight("locally by your own AI agent.")}`);
|
|
439
|
+
console.log(` Your agent reads your sessions to evaluate proficiency, but`);
|
|
440
|
+
console.log(` ${c.bold("only derived scores and signals are submitted to JobArbiter.")}`);
|
|
441
|
+
console.log(` Raw session data — prompts, responses, code — never leaves`);
|
|
442
|
+
console.log(` your machine and is never stored on our servers.\n`);
|
|
441
443
|
console.log(c.dim(` Data stored locally: ~/.config/jobarbiter/observer/observations.json`));
|
|
442
444
|
console.log(c.dim(` Review anytime: jobarbiter observe review\n`));
|
|
443
445
|
const observerNames = needsObserver.map((t) => t.name).join(", ");
|
|
@@ -457,7 +459,13 @@ async function runToolDetectionStep(prompt, config) {
|
|
|
457
459
|
}
|
|
458
460
|
if (result.installed.length > 0) {
|
|
459
461
|
console.log(`\n ${sym.check} ${c.success(`${result.installed.length} observer${result.installed.length > 1 ? "s" : ""} installed!`)}`);
|
|
460
|
-
console.log(c.
|
|
462
|
+
console.log(`\n ${c.bold("What happens now?")}`);
|
|
463
|
+
console.log(` Observers activate each time you use your AI tools.`);
|
|
464
|
+
console.log(` Just work normally — every session builds your profile.\n`);
|
|
465
|
+
console.log(` ${sym.arrow} ${c.highlight("Your next AI session will begin your proficiency analysis.")}`);
|
|
466
|
+
console.log(` Your own AI agent performs the analysis locally — evaluating`);
|
|
467
|
+
console.log(` how you work, not just how much. Only derived scores are`);
|
|
468
|
+
console.log(` submitted to JobArbiter. Raw session data never leaves your machine.\n`);
|
|
461
469
|
}
|
|
462
470
|
}
|
|
463
471
|
else {
|
|
@@ -497,10 +505,11 @@ async function runConnectAIAccountsStep(prompt) {
|
|
|
497
505
|
console.log(` ${sym.bullet} Model preferences ${c.dim("(which models you reach for)")}`);
|
|
498
506
|
console.log(` ${sym.bullet} Session frequency and consistency over time`);
|
|
499
507
|
console.log(` ${sym.bullet} API spend patterns ${c.dim("(demonstrates serious usage)")}\n`);
|
|
500
|
-
console.log(` ${c.bold("
|
|
501
|
-
console.log(` ${sym.bullet}
|
|
502
|
-
console.log(` ${sym.bullet}
|
|
503
|
-
console.log(`
|
|
508
|
+
console.log(` ${c.bold("How your data stays safe:")}`);
|
|
509
|
+
console.log(` ${sym.bullet} Analysis runs ${c.bold("locally on your machine")} by your own AI agent`);
|
|
510
|
+
console.log(` ${sym.bullet} Only derived proficiency scores leave your machine — never raw`);
|
|
511
|
+
console.log(` session data, prompts, responses, or conversation content`);
|
|
512
|
+
console.log(` ${sym.bullet} ${c.bold("Nothing is stored on JobArbiter's servers")} except your scores\n`);
|
|
504
513
|
// Check for already connected providers
|
|
505
514
|
const existingProviders = loadProviderKeys();
|
|
506
515
|
if (existingProviders.length > 0) {
|
|
@@ -516,27 +525,31 @@ async function runConnectAIAccountsStep(prompt) {
|
|
|
516
525
|
console.log(` ${c.bold("Available connections:")}\n`);
|
|
517
526
|
console.log(` ${c.highlight("1.")} Anthropic API key — Pull Claude usage stats`);
|
|
518
527
|
console.log(` ${c.highlight("2.")} OpenAI API key — Pull GPT/ChatGPT usage stats`);
|
|
519
|
-
console.log(` ${c.highlight("3.")}
|
|
528
|
+
console.log(` ${c.highlight("3.")} Google AI API key — Pull Gemini usage stats`);
|
|
529
|
+
console.log(` ${c.highlight("4.")} Skip for now\n`);
|
|
520
530
|
console.log(c.dim(` You can connect accounts later with 'jobarbiter tokens connect'\n`));
|
|
521
|
-
const choice = await prompt.question(` Your choice ${c.dim("[1/2/3]")}: `);
|
|
522
|
-
if (choice === "
|
|
531
|
+
const choice = await prompt.question(` Your choice ${c.dim("[1/2/3/4]")}: `);
|
|
532
|
+
if (choice === "4" || choice.toLowerCase() === "skip" || choice === "") {
|
|
523
533
|
console.log(`\n${c.dim(" Skipped — you can connect providers later with 'jobarbiter tokens connect'")}\n`);
|
|
524
534
|
continueConnecting = false;
|
|
525
535
|
}
|
|
526
536
|
else if (choice === "1") {
|
|
527
537
|
await connectProvider(prompt, "anthropic", "Anthropic");
|
|
528
|
-
// Ask if they want to connect another
|
|
529
538
|
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
530
539
|
console.log();
|
|
531
540
|
}
|
|
532
541
|
else if (choice === "2") {
|
|
533
542
|
await connectProvider(prompt, "openai", "OpenAI");
|
|
534
|
-
|
|
543
|
+
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
544
|
+
console.log();
|
|
545
|
+
}
|
|
546
|
+
else if (choice === "3") {
|
|
547
|
+
await connectProvider(prompt, "google", "Google AI");
|
|
535
548
|
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
536
549
|
console.log();
|
|
537
550
|
}
|
|
538
551
|
else {
|
|
539
|
-
console.log(c.error(" Please enter 1, 2, or
|
|
552
|
+
console.log(c.error(" Please enter 1, 2, 3, or 4"));
|
|
540
553
|
}
|
|
541
554
|
}
|
|
542
555
|
}
|
|
@@ -567,7 +580,11 @@ async function connectProvider(prompt, providerId, providerName) {
|
|
|
567
580
|
}
|
|
568
581
|
function showWorkerCompletion(state) {
|
|
569
582
|
console.log(`${sym.done} ${c.bold("Step 7/7 — You're In!")}\n`);
|
|
570
|
-
console.log(`Your profile is live. Here's
|
|
583
|
+
console.log(`Your profile is live. Here's how it builds:\n`);
|
|
584
|
+
console.log(` 💡 ${c.bold("Your next AI session will begin your proficiency analysis.")}`);
|
|
585
|
+
console.log(` Just use your tools normally. Your own AI agent analyzes each`);
|
|
586
|
+
console.log(` session locally — evaluating how you work with AI, not just`);
|
|
587
|
+
console.log(` how much. Only proficiency scores are sent to JobArbiter.\n`);
|
|
571
588
|
console.log(` 📊 Your proficiency profile builds automatically from:`);
|
|
572
589
|
console.log(` ${c.bold("How you use AI (qualitative):")}`);
|
|
573
590
|
console.log(` ${sym.bullet} Orchestration complexity ${c.dim("— single prompts vs multi-agent pipelines")}`);
|
package/dist/lib/providers.d.ts
CHANGED
|
@@ -35,6 +35,10 @@ export declare function validateAnthropicKey(apiKey: string): Promise<Validation
|
|
|
35
35
|
* Returns validation result with usage summary if available.
|
|
36
36
|
*/
|
|
37
37
|
export declare function validateOpenAIKey(apiKey: string): Promise<ValidationResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Validate a Google AI API key by making a test API call.
|
|
40
|
+
*/
|
|
41
|
+
export declare function validateGoogleKey(apiKey: string): Promise<ValidationResult>;
|
|
38
42
|
/**
|
|
39
43
|
* Get list of supported providers.
|
|
40
44
|
*/
|
package/dist/lib/providers.js
CHANGED
|
@@ -133,6 +133,30 @@ export async function validateOpenAIKey(apiKey) {
|
|
|
133
133
|
return { valid: false, error: "Unknown error" };
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Validate a Google AI API key by making a test API call.
|
|
138
|
+
*/
|
|
139
|
+
export async function validateGoogleKey(apiKey) {
|
|
140
|
+
try {
|
|
141
|
+
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`, { method: "GET" });
|
|
142
|
+
if (response.status === 400 || response.status === 401 || response.status === 403) {
|
|
143
|
+
return { valid: false, error: "Invalid API key" };
|
|
144
|
+
}
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
return { valid: false, error: `API error: ${response.status}` };
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
valid: true,
|
|
150
|
+
summary: "API key validated",
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
if (err instanceof Error) {
|
|
155
|
+
return { valid: false, error: `Connection error: ${err.message}` };
|
|
156
|
+
}
|
|
157
|
+
return { valid: false, error: "Unknown error" };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
136
160
|
/**
|
|
137
161
|
* Get list of supported providers.
|
|
138
162
|
*/
|
|
@@ -140,6 +164,7 @@ export function getSupportedProviders() {
|
|
|
140
164
|
return [
|
|
141
165
|
{ id: "anthropic", name: "Anthropic" },
|
|
142
166
|
{ id: "openai", name: "OpenAI" },
|
|
167
|
+
{ id: "google", name: "Google AI" },
|
|
143
168
|
];
|
|
144
169
|
}
|
|
145
170
|
/**
|
|
@@ -151,6 +176,8 @@ export async function validateProviderKey(provider, apiKey) {
|
|
|
151
176
|
return validateAnthropicKey(apiKey);
|
|
152
177
|
case "openai":
|
|
153
178
|
return validateOpenAIKey(apiKey);
|
|
179
|
+
case "google":
|
|
180
|
+
return validateGoogleKey(apiKey);
|
|
154
181
|
default:
|
|
155
182
|
return { valid: false, error: `Unknown provider: ${provider}` };
|
|
156
183
|
}
|
package/package.json
CHANGED
package/src/lib/onboard.ts
CHANGED
|
@@ -529,9 +529,11 @@ async function runToolDetectionStep(
|
|
|
529
529
|
console.log(` communication clarity, iteration patterns, tool fluency\n`);
|
|
530
530
|
console.log(` This is what makes your profile ${c.bold("verified")} and ${c.bold("valuable")}.`);
|
|
531
531
|
console.log(` Your observer regularly records and reports your proven AI proficiency.\n`);
|
|
532
|
-
console.log(` ${c.bold("Privacy:")} ${c.highlight("
|
|
533
|
-
console.log(`
|
|
534
|
-
console.log(`
|
|
532
|
+
console.log(` ${c.bold("Privacy:")} Analysis runs ${c.highlight("locally by your own AI agent.")}`);
|
|
533
|
+
console.log(` Your agent reads your sessions to evaluate proficiency, but`);
|
|
534
|
+
console.log(` ${c.bold("only derived scores and signals are submitted to JobArbiter.")}`);
|
|
535
|
+
console.log(` Raw session data — prompts, responses, code — never leaves`);
|
|
536
|
+
console.log(` your machine and is never stored on our servers.\n`);
|
|
535
537
|
console.log(c.dim(` Data stored locally: ~/.config/jobarbiter/observer/observations.json`));
|
|
536
538
|
console.log(c.dim(` Review anytime: jobarbiter observe review\n`));
|
|
537
539
|
|
|
@@ -557,7 +559,13 @@ async function runToolDetectionStep(
|
|
|
557
559
|
|
|
558
560
|
if (result.installed.length > 0) {
|
|
559
561
|
console.log(`\n ${sym.check} ${c.success(`${result.installed.length} observer${result.installed.length > 1 ? "s" : ""} installed!`)}`);
|
|
560
|
-
console.log(c.
|
|
562
|
+
console.log(`\n ${c.bold("What happens now?")}`);
|
|
563
|
+
console.log(` Observers activate each time you use your AI tools.`);
|
|
564
|
+
console.log(` Just work normally — every session builds your profile.\n`);
|
|
565
|
+
console.log(` ${sym.arrow} ${c.highlight("Your next AI session will begin your proficiency analysis.")}`);
|
|
566
|
+
console.log(` Your own AI agent performs the analysis locally — evaluating`);
|
|
567
|
+
console.log(` how you work, not just how much. Only derived scores are`);
|
|
568
|
+
console.log(` submitted to JobArbiter. Raw session data never leaves your machine.\n`);
|
|
561
569
|
}
|
|
562
570
|
} else {
|
|
563
571
|
console.log(c.dim("\n Skipped — you can install observers later with 'jobarbiter observe install'.\n"));
|
|
@@ -601,10 +609,11 @@ async function runConnectAIAccountsStep(prompt: Prompt): Promise<void> {
|
|
|
601
609
|
console.log(` ${sym.bullet} Session frequency and consistency over time`);
|
|
602
610
|
console.log(` ${sym.bullet} API spend patterns ${c.dim("(demonstrates serious usage)")}\n`);
|
|
603
611
|
|
|
604
|
-
console.log(` ${c.bold("
|
|
605
|
-
console.log(` ${sym.bullet}
|
|
606
|
-
console.log(` ${sym.bullet}
|
|
607
|
-
console.log(`
|
|
612
|
+
console.log(` ${c.bold("How your data stays safe:")}`);
|
|
613
|
+
console.log(` ${sym.bullet} Analysis runs ${c.bold("locally on your machine")} by your own AI agent`);
|
|
614
|
+
console.log(` ${sym.bullet} Only derived proficiency scores leave your machine — never raw`);
|
|
615
|
+
console.log(` session data, prompts, responses, or conversation content`);
|
|
616
|
+
console.log(` ${sym.bullet} ${c.bold("Nothing is stored on JobArbiter's servers")} except your scores\n`);
|
|
608
617
|
|
|
609
618
|
// Check for already connected providers
|
|
610
619
|
const existingProviders = loadProviderKeys();
|
|
@@ -623,26 +632,29 @@ async function runConnectAIAccountsStep(prompt: Prompt): Promise<void> {
|
|
|
623
632
|
console.log(` ${c.bold("Available connections:")}\n`);
|
|
624
633
|
console.log(` ${c.highlight("1.")} Anthropic API key — Pull Claude usage stats`);
|
|
625
634
|
console.log(` ${c.highlight("2.")} OpenAI API key — Pull GPT/ChatGPT usage stats`);
|
|
626
|
-
console.log(` ${c.highlight("3.")}
|
|
635
|
+
console.log(` ${c.highlight("3.")} Google AI API key — Pull Gemini usage stats`);
|
|
636
|
+
console.log(` ${c.highlight("4.")} Skip for now\n`);
|
|
627
637
|
console.log(c.dim(` You can connect accounts later with 'jobarbiter tokens connect'\n`));
|
|
628
638
|
|
|
629
|
-
const choice = await prompt.question(` Your choice ${c.dim("[1/2/3]")}: `);
|
|
639
|
+
const choice = await prompt.question(` Your choice ${c.dim("[1/2/3/4]")}: `);
|
|
630
640
|
|
|
631
|
-
if (choice === "
|
|
641
|
+
if (choice === "4" || choice.toLowerCase() === "skip" || choice === "") {
|
|
632
642
|
console.log(`\n${c.dim(" Skipped — you can connect providers later with 'jobarbiter tokens connect'")}\n`);
|
|
633
643
|
continueConnecting = false;
|
|
634
644
|
} else if (choice === "1") {
|
|
635
645
|
await connectProvider(prompt, "anthropic", "Anthropic");
|
|
636
|
-
// Ask if they want to connect another
|
|
637
646
|
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
638
647
|
console.log();
|
|
639
648
|
} else if (choice === "2") {
|
|
640
649
|
await connectProvider(prompt, "openai", "OpenAI");
|
|
641
|
-
|
|
650
|
+
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
651
|
+
console.log();
|
|
652
|
+
} else if (choice === "3") {
|
|
653
|
+
await connectProvider(prompt, "google", "Google AI");
|
|
642
654
|
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
643
655
|
console.log();
|
|
644
656
|
} else {
|
|
645
|
-
console.log(c.error(" Please enter 1, 2, or
|
|
657
|
+
console.log(c.error(" Please enter 1, 2, 3, or 4"));
|
|
646
658
|
}
|
|
647
659
|
}
|
|
648
660
|
}
|
|
@@ -679,7 +691,11 @@ async function connectProvider(prompt: Prompt, providerId: string, providerName:
|
|
|
679
691
|
|
|
680
692
|
function showWorkerCompletion(state: OnboardState): void {
|
|
681
693
|
console.log(`${sym.done} ${c.bold("Step 7/7 — You're In!")}\n`);
|
|
682
|
-
console.log(`Your profile is live. Here's
|
|
694
|
+
console.log(`Your profile is live. Here's how it builds:\n`);
|
|
695
|
+
console.log(` 💡 ${c.bold("Your next AI session will begin your proficiency analysis.")}`);
|
|
696
|
+
console.log(` Just use your tools normally. Your own AI agent analyzes each`);
|
|
697
|
+
console.log(` session locally — evaluating how you work with AI, not just`);
|
|
698
|
+
console.log(` how much. Only proficiency scores are sent to JobArbiter.\n`);
|
|
683
699
|
|
|
684
700
|
console.log(` 📊 Your proficiency profile builds automatically from:`);
|
|
685
701
|
console.log(` ${c.bold("How you use AI (qualitative):")}`);
|
package/src/lib/providers.ts
CHANGED
|
@@ -180,6 +180,36 @@ export async function validateOpenAIKey(apiKey: string): Promise<ValidationResul
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Validate a Google AI API key by making a test API call.
|
|
185
|
+
*/
|
|
186
|
+
export async function validateGoogleKey(apiKey: string): Promise<ValidationResult> {
|
|
187
|
+
try {
|
|
188
|
+
const response = await fetch(
|
|
189
|
+
`https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey}`,
|
|
190
|
+
{ method: "GET" },
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
if (response.status === 400 || response.status === 401 || response.status === 403) {
|
|
194
|
+
return { valid: false, error: "Invalid API key" };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!response.ok) {
|
|
198
|
+
return { valid: false, error: `API error: ${response.status}` };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
valid: true,
|
|
203
|
+
summary: "API key validated",
|
|
204
|
+
};
|
|
205
|
+
} catch (err) {
|
|
206
|
+
if (err instanceof Error) {
|
|
207
|
+
return { valid: false, error: `Connection error: ${err.message}` };
|
|
208
|
+
}
|
|
209
|
+
return { valid: false, error: "Unknown error" };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
183
213
|
/**
|
|
184
214
|
* Get list of supported providers.
|
|
185
215
|
*/
|
|
@@ -187,6 +217,7 @@ export function getSupportedProviders(): Array<{ id: string; name: string }> {
|
|
|
187
217
|
return [
|
|
188
218
|
{ id: "anthropic", name: "Anthropic" },
|
|
189
219
|
{ id: "openai", name: "OpenAI" },
|
|
220
|
+
{ id: "google", name: "Google AI" },
|
|
190
221
|
];
|
|
191
222
|
}
|
|
192
223
|
|
|
@@ -199,6 +230,8 @@ export async function validateProviderKey(provider: string, apiKey: string): Pro
|
|
|
199
230
|
return validateAnthropicKey(apiKey);
|
|
200
231
|
case "openai":
|
|
201
232
|
return validateOpenAIKey(apiKey);
|
|
233
|
+
case "google":
|
|
234
|
+
return validateGoogleKey(apiKey);
|
|
202
235
|
default:
|
|
203
236
|
return { valid: false, error: `Unknown provider: ${provider}` };
|
|
204
237
|
}
|