jobarbiter 0.3.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/dist/index.d.ts +2 -0
- package/dist/index.js +816 -0
- package/dist/lib/api.d.ts +8 -0
- package/dist/lib/api.js +40 -0
- package/dist/lib/config.d.ts +9 -0
- package/dist/lib/config.js +43 -0
- package/dist/lib/output.d.ts +8 -0
- package/dist/lib/output.js +85 -0
- package/package.json +24 -0
- package/src/index.ts +852 -0
- package/src/lib/api.ts +62 -0
- package/src/lib/config.ts +55 -0
- package/src/lib/output.ts +86 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Config } from "./config.js";
|
|
2
|
+
export declare class ApiError extends Error {
|
|
3
|
+
status: number;
|
|
4
|
+
body: Record<string, unknown>;
|
|
5
|
+
constructor(status: number, body: Record<string, unknown>);
|
|
6
|
+
}
|
|
7
|
+
export declare function api(config: Config, method: string, path: string, body?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
8
|
+
export declare function apiUnauthenticated(baseUrl: string, method: string, path: string, body?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
package/dist/lib/api.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export class ApiError extends Error {
|
|
2
|
+
status;
|
|
3
|
+
body;
|
|
4
|
+
constructor(status, body) {
|
|
5
|
+
super(body.error || `HTTP ${status}`);
|
|
6
|
+
this.status = status;
|
|
7
|
+
this.body = body;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export async function api(config, method, path, body) {
|
|
11
|
+
const url = `${config.baseUrl}${path}`;
|
|
12
|
+
const headers = {
|
|
13
|
+
"Authorization": `Bearer ${config.apiKey}`,
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
"User-Agent": "jobarbiter-cli/0.3.0",
|
|
16
|
+
};
|
|
17
|
+
const response = await fetch(url, {
|
|
18
|
+
method,
|
|
19
|
+
headers,
|
|
20
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
21
|
+
});
|
|
22
|
+
const data = await response.json();
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw new ApiError(response.status, data);
|
|
25
|
+
}
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
export async function apiUnauthenticated(baseUrl, method, path, body) {
|
|
29
|
+
const url = `${baseUrl}${path}`;
|
|
30
|
+
const response = await fetch(url, {
|
|
31
|
+
method,
|
|
32
|
+
headers: { "Content-Type": "application/json" },
|
|
33
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
34
|
+
});
|
|
35
|
+
const data = await response.json();
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new ApiError(response.status, data);
|
|
38
|
+
}
|
|
39
|
+
return data;
|
|
40
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
userType: "worker" | "employer" | "seeker" | "poster";
|
|
5
|
+
}
|
|
6
|
+
export declare function getConfigPath(): string;
|
|
7
|
+
export declare function loadConfig(): Config | null;
|
|
8
|
+
export declare function saveConfig(config: Config): void;
|
|
9
|
+
export declare function requireConfig(): Config;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const CONFIG_DIR = join(homedir(), ".config", "jobarbiter");
|
|
5
|
+
const CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
6
|
+
export function getConfigPath() {
|
|
7
|
+
return CONFIG_FILE;
|
|
8
|
+
}
|
|
9
|
+
export function loadConfig() {
|
|
10
|
+
// Environment variables override file config
|
|
11
|
+
const envKey = process.env.JOBARBITER_API_KEY;
|
|
12
|
+
const envUrl = process.env.JOBARBITER_BASE_URL;
|
|
13
|
+
const envType = process.env.JOBARBITER_USER_TYPE;
|
|
14
|
+
if (envKey) {
|
|
15
|
+
return {
|
|
16
|
+
apiKey: envKey,
|
|
17
|
+
baseUrl: envUrl || "https://jobarbiter-api-production.up.railway.app",
|
|
18
|
+
userType: envType || "worker",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (!existsSync(CONFIG_FILE))
|
|
22
|
+
return null;
|
|
23
|
+
try {
|
|
24
|
+
const raw = readFileSync(CONFIG_FILE, "utf-8");
|
|
25
|
+
return JSON.parse(raw);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function saveConfig(config) {
|
|
32
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
33
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
|
|
34
|
+
}
|
|
35
|
+
export function requireConfig() {
|
|
36
|
+
const config = loadConfig();
|
|
37
|
+
if (!config) {
|
|
38
|
+
console.error("Not configured. Run: jobarbiter register --email YOUR_EMAIL --type seeker");
|
|
39
|
+
console.error("Or set JOBARBITER_API_KEY environment variable.");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
return config;
|
|
43
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting — JSON for agents, readable for humans
|
|
3
|
+
*/
|
|
4
|
+
export declare function setJsonMode(enabled: boolean): void;
|
|
5
|
+
export declare function output(data: Record<string, unknown>): void;
|
|
6
|
+
export declare function outputList(items: Array<Record<string, unknown>>, title?: string): void;
|
|
7
|
+
export declare function success(message: string): void;
|
|
8
|
+
export declare function error(message: string): void;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting — JSON for agents, readable for humans
|
|
3
|
+
*/
|
|
4
|
+
let jsonMode = false;
|
|
5
|
+
export function setJsonMode(enabled) {
|
|
6
|
+
jsonMode = enabled;
|
|
7
|
+
}
|
|
8
|
+
export function output(data) {
|
|
9
|
+
if (jsonMode) {
|
|
10
|
+
console.log(JSON.stringify(data, null, 2));
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
printReadable(data);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function outputList(items, title) {
|
|
17
|
+
if (jsonMode) {
|
|
18
|
+
console.log(JSON.stringify(items, null, 2));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (title)
|
|
22
|
+
console.log(`\n${title} (${items.length})\n${"─".repeat(40)}`);
|
|
23
|
+
if (items.length === 0) {
|
|
24
|
+
console.log(" (none)");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
for (const item of items) {
|
|
28
|
+
printReadable(item);
|
|
29
|
+
console.log("");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function success(message) {
|
|
33
|
+
if (jsonMode) {
|
|
34
|
+
console.log(JSON.stringify({ status: "ok", message }));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(`✓ ${message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function error(message) {
|
|
41
|
+
if (jsonMode) {
|
|
42
|
+
console.error(JSON.stringify({ status: "error", error: message }));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.error(`✗ ${message}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function printReadable(data, indent = 0) {
|
|
49
|
+
const pad = " ".repeat(indent);
|
|
50
|
+
for (const [key, value] of Object.entries(data)) {
|
|
51
|
+
if (key === "ai_disclosure")
|
|
52
|
+
continue; // skip noise in human output
|
|
53
|
+
if (value === null || value === undefined)
|
|
54
|
+
continue;
|
|
55
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
56
|
+
console.log(`${pad}${formatKey(key)}:`);
|
|
57
|
+
printReadable(value, indent + 1);
|
|
58
|
+
}
|
|
59
|
+
else if (Array.isArray(value)) {
|
|
60
|
+
if (value.length === 0)
|
|
61
|
+
continue;
|
|
62
|
+
if (typeof value[0] === "string") {
|
|
63
|
+
console.log(`${pad}${formatKey(key)}: ${value.join(", ")}`);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log(`${pad}${formatKey(key)}:`);
|
|
67
|
+
for (const item of value) {
|
|
68
|
+
if (typeof item === "object") {
|
|
69
|
+
printReadable(item, indent + 1);
|
|
70
|
+
console.log("");
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.log(`${pad} - ${item}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
console.log(`${pad}${formatKey(key)}: ${value}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function formatKey(key) {
|
|
84
|
+
return key.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
|
|
85
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jobarbiter",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "CLI for JobArbiter — the first AI Proficiency Marketplace",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"jobarbiter": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsx src/index.ts"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["jobarbiter", "ai", "agents", "jobs", "matching", "x402"],
|
|
14
|
+
"author": "RetroDigio",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"commander": "^13.0.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"typescript": "^5.7.0",
|
|
21
|
+
"tsx": "^4.0.0",
|
|
22
|
+
"@types/node": "^22.0.0"
|
|
23
|
+
}
|
|
24
|
+
}
|