jobarbiter 0.3.8 → 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 +30 -21
- 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 +29 -21
- 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(", ");
|
|
@@ -458,11 +460,12 @@ async function runToolDetectionStep(prompt, config) {
|
|
|
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
462
|
console.log(`\n ${c.bold("What happens now?")}`);
|
|
461
|
-
console.log(` Observers
|
|
462
|
-
console.log(` Just work normally — every
|
|
463
|
-
console.log(`
|
|
464
|
-
console.log(`
|
|
465
|
-
console.log(
|
|
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`);
|
|
466
469
|
}
|
|
467
470
|
}
|
|
468
471
|
else {
|
|
@@ -502,10 +505,11 @@ async function runConnectAIAccountsStep(prompt) {
|
|
|
502
505
|
console.log(` ${sym.bullet} Model preferences ${c.dim("(which models you reach for)")}`);
|
|
503
506
|
console.log(` ${sym.bullet} Session frequency and consistency over time`);
|
|
504
507
|
console.log(` ${sym.bullet} API spend patterns ${c.dim("(demonstrates serious usage)")}\n`);
|
|
505
|
-
console.log(` ${c.bold("
|
|
506
|
-
console.log(` ${sym.bullet}
|
|
507
|
-
console.log(` ${sym.bullet}
|
|
508
|
-
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`);
|
|
509
513
|
// Check for already connected providers
|
|
510
514
|
const existingProviders = loadProviderKeys();
|
|
511
515
|
if (existingProviders.length > 0) {
|
|
@@ -521,27 +525,31 @@ async function runConnectAIAccountsStep(prompt) {
|
|
|
521
525
|
console.log(` ${c.bold("Available connections:")}\n`);
|
|
522
526
|
console.log(` ${c.highlight("1.")} Anthropic API key — Pull Claude usage stats`);
|
|
523
527
|
console.log(` ${c.highlight("2.")} OpenAI API key — Pull GPT/ChatGPT usage stats`);
|
|
524
|
-
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`);
|
|
525
530
|
console.log(c.dim(` You can connect accounts later with 'jobarbiter tokens connect'\n`));
|
|
526
|
-
const choice = await prompt.question(` Your choice ${c.dim("[1/2/3]")}: `);
|
|
527
|
-
if (choice === "
|
|
531
|
+
const choice = await prompt.question(` Your choice ${c.dim("[1/2/3/4]")}: `);
|
|
532
|
+
if (choice === "4" || choice.toLowerCase() === "skip" || choice === "") {
|
|
528
533
|
console.log(`\n${c.dim(" Skipped — you can connect providers later with 'jobarbiter tokens connect'")}\n`);
|
|
529
534
|
continueConnecting = false;
|
|
530
535
|
}
|
|
531
536
|
else if (choice === "1") {
|
|
532
537
|
await connectProvider(prompt, "anthropic", "Anthropic");
|
|
533
|
-
// Ask if they want to connect another
|
|
534
538
|
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
535
539
|
console.log();
|
|
536
540
|
}
|
|
537
541
|
else if (choice === "2") {
|
|
538
542
|
await connectProvider(prompt, "openai", "OpenAI");
|
|
539
|
-
|
|
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");
|
|
540
548
|
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
541
549
|
console.log();
|
|
542
550
|
}
|
|
543
551
|
else {
|
|
544
|
-
console.log(c.error(" Please enter 1, 2, or
|
|
552
|
+
console.log(c.error(" Please enter 1, 2, 3, or 4"));
|
|
545
553
|
}
|
|
546
554
|
}
|
|
547
555
|
}
|
|
@@ -573,9 +581,10 @@ async function connectProvider(prompt, providerId, providerName) {
|
|
|
573
581
|
function showWorkerCompletion(state) {
|
|
574
582
|
console.log(`${sym.done} ${c.bold("Step 7/7 — You're In!")}\n`);
|
|
575
583
|
console.log(`Your profile is live. Here's how it builds:\n`);
|
|
576
|
-
console.log(` 💡 ${c.bold("
|
|
577
|
-
console.log(`
|
|
578
|
-
console.log(`
|
|
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`);
|
|
579
588
|
console.log(` 📊 Your proficiency profile builds automatically from:`);
|
|
580
589
|
console.log(` ${c.bold("How you use AI (qualitative):")}`);
|
|
581
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
|
|
|
@@ -558,11 +560,12 @@ async function runToolDetectionStep(
|
|
|
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
562
|
console.log(`\n ${c.bold("What happens now?")}`);
|
|
561
|
-
console.log(` Observers
|
|
562
|
-
console.log(` Just work normally — every
|
|
563
|
-
console.log(`
|
|
564
|
-
console.log(`
|
|
565
|
-
console.log(
|
|
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`);
|
|
566
569
|
}
|
|
567
570
|
} else {
|
|
568
571
|
console.log(c.dim("\n Skipped — you can install observers later with 'jobarbiter observe install'.\n"));
|
|
@@ -606,10 +609,11 @@ async function runConnectAIAccountsStep(prompt: Prompt): Promise<void> {
|
|
|
606
609
|
console.log(` ${sym.bullet} Session frequency and consistency over time`);
|
|
607
610
|
console.log(` ${sym.bullet} API spend patterns ${c.dim("(demonstrates serious usage)")}\n`);
|
|
608
611
|
|
|
609
|
-
console.log(` ${c.bold("
|
|
610
|
-
console.log(` ${sym.bullet}
|
|
611
|
-
console.log(` ${sym.bullet}
|
|
612
|
-
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`);
|
|
613
617
|
|
|
614
618
|
// Check for already connected providers
|
|
615
619
|
const existingProviders = loadProviderKeys();
|
|
@@ -628,26 +632,29 @@ async function runConnectAIAccountsStep(prompt: Prompt): Promise<void> {
|
|
|
628
632
|
console.log(` ${c.bold("Available connections:")}\n`);
|
|
629
633
|
console.log(` ${c.highlight("1.")} Anthropic API key — Pull Claude usage stats`);
|
|
630
634
|
console.log(` ${c.highlight("2.")} OpenAI API key — Pull GPT/ChatGPT usage stats`);
|
|
631
|
-
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`);
|
|
632
637
|
console.log(c.dim(` You can connect accounts later with 'jobarbiter tokens connect'\n`));
|
|
633
638
|
|
|
634
|
-
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]")}: `);
|
|
635
640
|
|
|
636
|
-
if (choice === "
|
|
641
|
+
if (choice === "4" || choice.toLowerCase() === "skip" || choice === "") {
|
|
637
642
|
console.log(`\n${c.dim(" Skipped — you can connect providers later with 'jobarbiter tokens connect'")}\n`);
|
|
638
643
|
continueConnecting = false;
|
|
639
644
|
} else if (choice === "1") {
|
|
640
645
|
await connectProvider(prompt, "anthropic", "Anthropic");
|
|
641
|
-
// Ask if they want to connect another
|
|
642
646
|
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
643
647
|
console.log();
|
|
644
648
|
} else if (choice === "2") {
|
|
645
649
|
await connectProvider(prompt, "openai", "OpenAI");
|
|
646
|
-
|
|
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");
|
|
647
654
|
continueConnecting = await prompt.confirm(`\n Connect another provider?`, false);
|
|
648
655
|
console.log();
|
|
649
656
|
} else {
|
|
650
|
-
console.log(c.error(" Please enter 1, 2, or
|
|
657
|
+
console.log(c.error(" Please enter 1, 2, 3, or 4"));
|
|
651
658
|
}
|
|
652
659
|
}
|
|
653
660
|
}
|
|
@@ -685,9 +692,10 @@ async function connectProvider(prompt: Prompt, providerId: string, providerName:
|
|
|
685
692
|
function showWorkerCompletion(state: OnboardState): void {
|
|
686
693
|
console.log(`${sym.done} ${c.bold("Step 7/7 — You're In!")}\n`);
|
|
687
694
|
console.log(`Your profile is live. Here's how it builds:\n`);
|
|
688
|
-
console.log(` 💡 ${c.bold("
|
|
689
|
-
console.log(`
|
|
690
|
-
console.log(`
|
|
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`);
|
|
691
699
|
|
|
692
700
|
console.log(` 📊 Your proficiency profile builds automatically from:`);
|
|
693
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
|
}
|