careervivid 1.11.5 → 1.12.1
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 +21 -6
- package/dist/agent/QueryEngine.d.ts.map +1 -1
- package/dist/agent/QueryEngine.js +12 -2
- package/dist/agent/tools/jobs.d.ts +16 -0
- package/dist/agent/tools/jobs.d.ts.map +1 -0
- package/dist/agent/tools/jobs.js +332 -0
- package/dist/api.d.ts +86 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +70 -0
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +75 -6
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +4 -1
- package/dist/commands/jobAgent.d.ts +16 -0
- package/dist/commands/jobAgent.d.ts.map +1 -0
- package/dist/commands/jobAgent.js +252 -0
- package/dist/commands/jobs.d.ts +8 -0
- package/dist/commands/jobs.d.ts.map +1 -1
- package/dist/commands/jobs.js +361 -23
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -146,15 +146,24 @@ cv profile export --format gdoc
|
|
|
146
146
|
|
|
147
147
|
### `cv jobs`
|
|
148
148
|
|
|
149
|
-
Automate your job application tracking.
|
|
149
|
+
Automate your job application tracking with AI.
|
|
150
150
|
|
|
151
151
|
| Subcommand | Description |
|
|
152
152
|
|---|---|
|
|
153
|
-
| `cv jobs
|
|
153
|
+
| `cv jobs hunt` | AI-powered job search scored against your resume → auto-saves to /job-tracker |
|
|
154
|
+
| `cv jobs update` | Interactively update a job application status on your Kanban board |
|
|
155
|
+
| `cv jobs list` | View your current job tracker board |
|
|
156
|
+
| `cv jobs sync-gmail` | [Legacy] Scan Gmail for applications and sync to a Google Sheet |
|
|
154
157
|
|
|
155
158
|
```bash
|
|
156
|
-
#
|
|
157
|
-
cv jobs
|
|
159
|
+
# AI-powered job search scored against your resume (uses configuration keys)
|
|
160
|
+
cv jobs hunt --role "Software Engineer" --score 60
|
|
161
|
+
|
|
162
|
+
# View your job tracking board
|
|
163
|
+
cv jobs list
|
|
164
|
+
|
|
165
|
+
# Update status of an application
|
|
166
|
+
cv jobs update
|
|
158
167
|
```
|
|
159
168
|
|
|
160
169
|
---
|
|
@@ -202,10 +211,16 @@ View and modify CLI configuration stored at `~/.careervividrc.json`.
|
|
|
202
211
|
| `cv config get <key>` | Print a single config value |
|
|
203
212
|
| `cv config set <key> <value>` | Update a config value |
|
|
204
213
|
|
|
214
|
+
**Available Keys:**
|
|
215
|
+
- \`apiKey\`: Your CareerVivid API key.
|
|
216
|
+
- \`geminiKey\`: Your Gemini API key for local AI-powered job application tracking and parsing.
|
|
217
|
+
- \`targetCompanies\`: Comma-separated list of target organizations to focus search on ATS boards (used by \`cv jobs hunt\`).
|
|
218
|
+
- \`apiUrl\`: Optional API endpoint override (default: \`https://careervivid.app/api\`).
|
|
219
|
+
|
|
205
220
|
```bash
|
|
206
221
|
cv config show
|
|
207
|
-
cv config get
|
|
208
|
-
cv config set
|
|
222
|
+
cv config get targetCompanies
|
|
223
|
+
cv config set targetCompanies "OpenAI, Google, Vercel"
|
|
209
224
|
```
|
|
210
225
|
|
|
211
226
|
---
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryEngine.d.ts","sourceRoot":"","sources":["../../src/agent/QueryEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,uBAAuB,EAAE,OAAO,EAAQ,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,IAAI,EAAsB,MAAM,WAAW,CAAC;AAMrD,eAAO,MAAM,0BAA0B,QA8B/B,CAAC;AAMT,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACtE,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACvD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,kDAAkD;IAClD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,wEAAwE;IACxE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAyCD;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,gBAAgB,CAAS;gBAErB,OAAO,GAAE,kBAAuB;IAyBrC,UAAU,IAAI,OAAO,EAAE;IAIvB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE;IAIpC,8CAA8C;IACvC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE;IAW7B,OAAO,CAAC,mBAAmB;YAcb,YAAY;YAOZ,gBAAgB;IA6DjB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IA8E5E;;;;OAIG;IACU,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"QueryEngine.d.ts","sourceRoot":"","sources":["../../src/agent/QueryEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,uBAAuB,EAAE,OAAO,EAAQ,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,IAAI,EAAsB,MAAM,WAAW,CAAC;AAMrD,eAAO,MAAM,0BAA0B,QA8B/B,CAAC;AAMT,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACtE,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACvD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,kDAAkD;IAClD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,wEAAwE;IACxE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAyCD;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,gBAAgB,CAAS;gBAErB,OAAO,GAAE,kBAAuB;IAyBrC,UAAU,IAAI,OAAO,EAAE;IAIvB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE;IAIpC,8CAA8C;IACvC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE;IAW7B,OAAO,CAAC,mBAAmB;YAcb,YAAY;YAOZ,gBAAgB;IA6DjB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IA8E5E;;;;OAIG;IACU,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;CAqFtF"}
|
|
@@ -286,8 +286,18 @@ export class QueryEngine {
|
|
|
286
286
|
let accumulatedText = '';
|
|
287
287
|
let accumulatedFunctionCalls = [];
|
|
288
288
|
for await (const chunk of streamResponse) {
|
|
289
|
-
//
|
|
290
|
-
|
|
289
|
+
// Manually extract text to avoid the SDK's "there are non-text parts" warning
|
|
290
|
+
let chunkText = '';
|
|
291
|
+
const parts = chunk.candidates?.[0]?.content?.parts || [];
|
|
292
|
+
if (parts.length > 0) {
|
|
293
|
+
chunkText = parts
|
|
294
|
+
.filter(p => p.text && !p.functionCall && !p.thought)
|
|
295
|
+
.map(p => p.text)
|
|
296
|
+
.join('');
|
|
297
|
+
}
|
|
298
|
+
else if (chunk.text && !chunk.text.includes('there are non-text parts')) {
|
|
299
|
+
chunkText = chunk.text;
|
|
300
|
+
}
|
|
291
301
|
if (chunkText) {
|
|
292
302
|
accumulatedText += chunkText;
|
|
293
303
|
if (hooks?.onChunk)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job-hunting tools for the CareerVivid Job Agent.
|
|
3
|
+
*
|
|
4
|
+
* These tools wrap the existing jobs API methods so the Gemini agent can
|
|
5
|
+
* autonomously hunt for jobs, save them to the tracker, and update statuses
|
|
6
|
+
* using natural language instructions from the user.
|
|
7
|
+
*/
|
|
8
|
+
import { Tool } from "../Tool.js";
|
|
9
|
+
export declare const SearchJobsTool: Tool;
|
|
10
|
+
export declare const SaveJobTool: Tool;
|
|
11
|
+
export declare const ListJobsTool: Tool;
|
|
12
|
+
export declare const UpdateJobStatusTool: Tool;
|
|
13
|
+
export declare const GetResumeTool: Tool;
|
|
14
|
+
export declare const ListResumesTool: Tool;
|
|
15
|
+
export declare const ALL_JOB_TOOLS: Tool[];
|
|
16
|
+
//# sourceMappingURL=jobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/jobs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAiBlC,eAAO,MAAM,cAAc,EAAE,IA0F5B,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,IA4EzB,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,IAgE1B,CAAC;AAMF,eAAO,MAAM,mBAAmB,EAAE,IAwDjC,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,IA8B3B,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IA6B7B,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,IAAI,EAO/B,CAAC"}
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job-hunting tools for the CareerVivid Job Agent.
|
|
3
|
+
*
|
|
4
|
+
* These tools wrap the existing jobs API methods so the Gemini agent can
|
|
5
|
+
* autonomously hunt for jobs, save them to the tracker, and update statuses
|
|
6
|
+
* using natural language instructions from the user.
|
|
7
|
+
*/
|
|
8
|
+
import { Type } from "@google/genai";
|
|
9
|
+
import { jobsHunt, jobsCreate, jobsList, jobsUpdate, resumeGet, resumesList, isApiError, } from "../../api.js";
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Tool: search_jobs
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
export const SearchJobsTool = {
|
|
14
|
+
name: "search_jobs",
|
|
15
|
+
description: `Search for jobs that match a given role and location.
|
|
16
|
+
The search automatically scores results against the user's CareerVivid resume.
|
|
17
|
+
Returns a list of scored job opportunities with AI summaries and missing skills.
|
|
18
|
+
Use this when the user asks to "find jobs", "search for roles", "look for positions", etc.`,
|
|
19
|
+
parameters: {
|
|
20
|
+
type: Type.OBJECT,
|
|
21
|
+
properties: {
|
|
22
|
+
role: {
|
|
23
|
+
type: Type.STRING,
|
|
24
|
+
description: 'The job title or role to search for. Examples: "Software Engineer", "Product Manager", "Data Scientist".',
|
|
25
|
+
},
|
|
26
|
+
location: {
|
|
27
|
+
type: Type.STRING,
|
|
28
|
+
description: 'Optional. Preferred job location. Examples: "San Francisco, CA", "Remote", "New York". Default is remote-friendly if omitted.',
|
|
29
|
+
},
|
|
30
|
+
count: {
|
|
31
|
+
type: Type.NUMBER,
|
|
32
|
+
description: "Optional. Number of job results to return. Default is 10. Maximum is 20.",
|
|
33
|
+
},
|
|
34
|
+
min_score: {
|
|
35
|
+
type: Type.NUMBER,
|
|
36
|
+
description: "Optional. Minimum match score (0-100) to include in results. Use 60 for good matches, 80 for excellent matches only.",
|
|
37
|
+
},
|
|
38
|
+
resume_id: {
|
|
39
|
+
type: Type.STRING,
|
|
40
|
+
description: "Optional. Specific resume ID to score against. If omitted, uses the user's latest resume.",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
required: ["role"],
|
|
44
|
+
},
|
|
45
|
+
execute: async (args) => {
|
|
46
|
+
// Optionally fetch resume content to include in the scoring request
|
|
47
|
+
let resumeContent;
|
|
48
|
+
try {
|
|
49
|
+
const resumeResult = await resumeGet(args.resume_id);
|
|
50
|
+
if (!isApiError(resumeResult)) {
|
|
51
|
+
resumeContent = resumeResult.cvMarkdown;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Proceed without resume — backend will use stored resume
|
|
56
|
+
}
|
|
57
|
+
const result = await jobsHunt({
|
|
58
|
+
resumeContent,
|
|
59
|
+
role: args.role,
|
|
60
|
+
location: args.location,
|
|
61
|
+
count: args.count ?? 10,
|
|
62
|
+
minScore: args.min_score,
|
|
63
|
+
});
|
|
64
|
+
if (isApiError(result)) {
|
|
65
|
+
return `Error searching jobs: ${result.message}`;
|
|
66
|
+
}
|
|
67
|
+
if (result.jobs.length === 0) {
|
|
68
|
+
return `No jobs found matching "${args.role}"${args.location ? ` in ${args.location}` : ""}. Try broadening your search or adjusting the location.`;
|
|
69
|
+
}
|
|
70
|
+
const jobList = result.jobs
|
|
71
|
+
.map((job, i) => {
|
|
72
|
+
const scoreBar = "█".repeat(Math.round(job.score / 10)) + "░".repeat(10 - Math.round(job.score / 10));
|
|
73
|
+
const missing = job.missingSkills.length > 0 ? `\n Missing skills: ${job.missingSkills.join(", ")}` : "";
|
|
74
|
+
return (`${i + 1}. [${job.scoreLabel.toUpperCase()} ${job.score}/100] ${job.title} @ ${job.company}\n` +
|
|
75
|
+
` Score: ${scoreBar} ${job.score}%\n` +
|
|
76
|
+
` Location: ${job.location || "Not specified"}${job.salary ? ` | Salary: ${job.salary}` : ""}\n` +
|
|
77
|
+
` Summary: ${job.aiSummary}${missing}\n` +
|
|
78
|
+
` URL: ${job.url}\n` +
|
|
79
|
+
` Job ID: ${job.id}`);
|
|
80
|
+
})
|
|
81
|
+
.join("\n\n");
|
|
82
|
+
return (`Found ${result.total} jobs for "${args.role}"${args.location ? ` in ${args.location}` : ""}.\n` +
|
|
83
|
+
`Showing top ${result.jobs.length} results:\n\n${jobList}`);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Tool: save_job
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
export const SaveJobTool = {
|
|
90
|
+
name: "save_job",
|
|
91
|
+
description: `Save a job to the user's CareerVivid job tracker Kanban board.
|
|
92
|
+
The job will appear in the "To Apply" column of the /job-tracker page.
|
|
93
|
+
Use this after finding interesting jobs via search_jobs, or when the user asks to "save", "add", or "track" a specific job.`,
|
|
94
|
+
parameters: {
|
|
95
|
+
type: Type.OBJECT,
|
|
96
|
+
properties: {
|
|
97
|
+
job_title: {
|
|
98
|
+
type: Type.STRING,
|
|
99
|
+
description: "The job title / position name.",
|
|
100
|
+
},
|
|
101
|
+
company_name: {
|
|
102
|
+
type: Type.STRING,
|
|
103
|
+
description: "The name of the company.",
|
|
104
|
+
},
|
|
105
|
+
location: {
|
|
106
|
+
type: Type.STRING,
|
|
107
|
+
description: "Optional. Job location (city, state, or 'Remote').",
|
|
108
|
+
},
|
|
109
|
+
job_url: {
|
|
110
|
+
type: Type.STRING,
|
|
111
|
+
description: "Optional. URL to the job posting.",
|
|
112
|
+
},
|
|
113
|
+
job_description: {
|
|
114
|
+
type: Type.STRING,
|
|
115
|
+
description: "Optional. Brief description or key details of the role.",
|
|
116
|
+
},
|
|
117
|
+
ai_score: {
|
|
118
|
+
type: Type.NUMBER,
|
|
119
|
+
description: "Optional. AI match score (0-100) from search_jobs results.",
|
|
120
|
+
},
|
|
121
|
+
ai_summary: {
|
|
122
|
+
type: Type.STRING,
|
|
123
|
+
description: "Optional. AI-generated summary of the job from search_jobs results.",
|
|
124
|
+
},
|
|
125
|
+
notes: {
|
|
126
|
+
type: Type.STRING,
|
|
127
|
+
description: "Optional. Personal notes about this job opportunity.",
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
required: ["job_title", "company_name"],
|
|
131
|
+
},
|
|
132
|
+
execute: async (args) => {
|
|
133
|
+
const result = await jobsCreate({
|
|
134
|
+
jobTitle: args.job_title,
|
|
135
|
+
companyName: args.company_name,
|
|
136
|
+
location: args.location,
|
|
137
|
+
jobPostURL: args.job_url,
|
|
138
|
+
jobDescription: args.job_description,
|
|
139
|
+
aiScore: args.ai_score,
|
|
140
|
+
aiSummary: args.ai_summary,
|
|
141
|
+
notes: args.notes,
|
|
142
|
+
});
|
|
143
|
+
if (isApiError(result)) {
|
|
144
|
+
return `Error saving job: ${result.message}`;
|
|
145
|
+
}
|
|
146
|
+
return (`✅ Saved "${args.job_title}" at ${args.company_name} to your job tracker!\n` +
|
|
147
|
+
` Status: To Apply\n` +
|
|
148
|
+
` Job ID: ${result.id}\n` +
|
|
149
|
+
` View it at: https://careervivid.app/job-tracker\n\n` +
|
|
150
|
+
`Agent Instruction: Please tell the user that the job is saved and remind them that they need to apply for it. Also let them know that you can help them update the job application status (To Apply, Applied, Interviewing, Offered, Rejected) whenever they are ready.`);
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// Tool: list_jobs
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
export const ListJobsTool = {
|
|
157
|
+
name: "list_jobs",
|
|
158
|
+
description: `List the user's jobs from their CareerVivid job tracker Kanban board.
|
|
159
|
+
Can filter by status. Use this when the user asks "what jobs do I have?", "show my tracker",
|
|
160
|
+
"what's in my job pipeline?", "check my interviews", etc.`,
|
|
161
|
+
parameters: {
|
|
162
|
+
type: Type.OBJECT,
|
|
163
|
+
properties: {
|
|
164
|
+
status: {
|
|
165
|
+
type: Type.STRING,
|
|
166
|
+
description: 'Optional. Filter by application status. One of: "To Apply", "Applied", "Interviewing", "Offered", "Rejected". If omitted, returns all jobs.',
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
execute: async (args) => {
|
|
171
|
+
const validStatuses = [
|
|
172
|
+
"To Apply", "Applied", "Interviewing", "Offered", "Rejected",
|
|
173
|
+
];
|
|
174
|
+
const status = validStatuses.includes(args.status)
|
|
175
|
+
? args.status
|
|
176
|
+
: undefined;
|
|
177
|
+
const result = await jobsList(status);
|
|
178
|
+
if (isApiError(result)) {
|
|
179
|
+
return `Error fetching job tracker: ${result.message}`;
|
|
180
|
+
}
|
|
181
|
+
if (result.jobs.length === 0) {
|
|
182
|
+
const statusMsg = status ? ` with status "${status}"` : "";
|
|
183
|
+
return `Your job tracker is empty${statusMsg}. Use search_jobs to find opportunities and save_job to add them!`;
|
|
184
|
+
}
|
|
185
|
+
// Group by status for a clear overview
|
|
186
|
+
const grouped = {};
|
|
187
|
+
for (const job of result.jobs) {
|
|
188
|
+
const s = job.applicationStatus;
|
|
189
|
+
if (!grouped[s])
|
|
190
|
+
grouped[s] = [];
|
|
191
|
+
grouped[s].push(job);
|
|
192
|
+
}
|
|
193
|
+
const statusOrder = ["To Apply", "Applied", "Interviewing", "Offered", "Rejected"];
|
|
194
|
+
const lines = [`Your Job Tracker (${result.total} total):\n`];
|
|
195
|
+
for (const s of statusOrder) {
|
|
196
|
+
const jobs = grouped[s];
|
|
197
|
+
if (!jobs || jobs.length === 0)
|
|
198
|
+
continue;
|
|
199
|
+
lines.push(`── ${s.toUpperCase()} (${jobs.length}) ──`);
|
|
200
|
+
for (const job of jobs) {
|
|
201
|
+
const score = job.aiScore !== null ? ` [${job.aiScore}%]` : "";
|
|
202
|
+
const updated = job.updatedAt
|
|
203
|
+
? ` | Updated: ${new Date(job.updatedAt).toLocaleDateString()}`
|
|
204
|
+
: "";
|
|
205
|
+
lines.push(` • ${job.jobTitle} @ ${job.companyName}${score} | ${job.location || "N/A"}${updated}`);
|
|
206
|
+
lines.push(` ID: ${job.id} | URL: ${job.jobPostURL || "N/A"}`);
|
|
207
|
+
if (job.notes)
|
|
208
|
+
lines.push(` Notes: ${job.notes}`);
|
|
209
|
+
}
|
|
210
|
+
lines.push("");
|
|
211
|
+
}
|
|
212
|
+
return lines.join("\n");
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
// Tool: update_job_status
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
export const UpdateJobStatusTool = {
|
|
219
|
+
name: "update_job_status",
|
|
220
|
+
description: `Move a job to a different status on the CareerVivid Kanban board.
|
|
221
|
+
Use this when the user mentions: "I got an interview", "I applied to X", "I got an offer",
|
|
222
|
+
"X rejected me", "move Y to applied", etc. The change will be visible in the /job-tracker UI.`,
|
|
223
|
+
parameters: {
|
|
224
|
+
type: Type.OBJECT,
|
|
225
|
+
properties: {
|
|
226
|
+
job_id: {
|
|
227
|
+
type: Type.STRING,
|
|
228
|
+
description: "The job ID to update. Get this from list_jobs or from a previous save_job call.",
|
|
229
|
+
},
|
|
230
|
+
new_status: {
|
|
231
|
+
type: Type.STRING,
|
|
232
|
+
description: 'The new application status. Must be one of: "To Apply", "Applied", "Interviewing", "Offered", "Rejected".',
|
|
233
|
+
},
|
|
234
|
+
notes: {
|
|
235
|
+
type: Type.STRING,
|
|
236
|
+
description: "Optional. Add or update notes about this status change (e.g. interview date, interviewer name, feedback).",
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
required: ["job_id", "new_status"],
|
|
240
|
+
},
|
|
241
|
+
execute: async (args) => {
|
|
242
|
+
const validStatuses = [
|
|
243
|
+
"To Apply", "Applied", "Interviewing", "Offered", "Rejected",
|
|
244
|
+
];
|
|
245
|
+
if (!validStatuses.includes(args.new_status)) {
|
|
246
|
+
return (`Invalid status "${args.new_status}". ` +
|
|
247
|
+
`Valid options are: ${validStatuses.join(", ")}.`);
|
|
248
|
+
}
|
|
249
|
+
const result = await jobsUpdate({
|
|
250
|
+
jobId: args.job_id,
|
|
251
|
+
status: args.new_status,
|
|
252
|
+
notes: args.notes,
|
|
253
|
+
});
|
|
254
|
+
if (isApiError(result)) {
|
|
255
|
+
return `Error updating job: ${result.message}`;
|
|
256
|
+
}
|
|
257
|
+
const notesMsg = args.notes ? `\n Notes: "${args.notes}"` : "";
|
|
258
|
+
return (`✅ Job tracker updated!\n` +
|
|
259
|
+
` Job ID: ${result.jobId}\n` +
|
|
260
|
+
` New Status: ${result.newStatus}${notesMsg}\n` +
|
|
261
|
+
` View your board at: https://careervivid.app/job-tracker`);
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
// ---------------------------------------------------------------------------
|
|
265
|
+
// Tool: get_resume
|
|
266
|
+
// ---------------------------------------------------------------------------
|
|
267
|
+
export const GetResumeTool = {
|
|
268
|
+
name: "get_resume",
|
|
269
|
+
description: `Fetch the user's resume from their CareerVivid profile.
|
|
270
|
+
Use this to understand the user's background, skills, and experience when giving
|
|
271
|
+
personalized job advice, tailoring cover letters, or analyzing job fit.`,
|
|
272
|
+
parameters: {
|
|
273
|
+
type: Type.OBJECT,
|
|
274
|
+
properties: {
|
|
275
|
+
resume_id: {
|
|
276
|
+
type: Type.STRING,
|
|
277
|
+
description: "Optional. Specific resume ID to retrieve. If omitted, fetches the latest resume.",
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
execute: async (args) => {
|
|
282
|
+
const result = await resumeGet(args.resume_id);
|
|
283
|
+
if (isApiError(result)) {
|
|
284
|
+
return `Error fetching resume: ${result.message}`;
|
|
285
|
+
}
|
|
286
|
+
const updated = result.updatedAt
|
|
287
|
+
? `\nLast updated: ${new Date(result.updatedAt).toLocaleDateString()}`
|
|
288
|
+
: "";
|
|
289
|
+
return (`Resume: "${result.title}" (ID: ${result.resumeId})${updated}\n\n` +
|
|
290
|
+
`--- RESUME CONTENT ---\n${result.cvMarkdown}\n--- END OF RESUME ---`);
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
// ---------------------------------------------------------------------------
|
|
294
|
+
// Tool: list_resumes
|
|
295
|
+
// ---------------------------------------------------------------------------
|
|
296
|
+
export const ListResumesTool = {
|
|
297
|
+
name: "list_resumes",
|
|
298
|
+
description: `List all of the user's resumes on CareerVivid.
|
|
299
|
+
Use this when the user asks "how many resumes do I have?", "list my resumes", or "show my resumes".
|
|
300
|
+
This returns lightweight metadata including resume ID and title, which can be useful when calling search_jobs or get_resume.`,
|
|
301
|
+
parameters: {
|
|
302
|
+
type: Type.OBJECT,
|
|
303
|
+
properties: {},
|
|
304
|
+
},
|
|
305
|
+
execute: async () => {
|
|
306
|
+
const result = await resumesList();
|
|
307
|
+
if (isApiError(result)) {
|
|
308
|
+
return `Error fetching resumes: ${result.message}`;
|
|
309
|
+
}
|
|
310
|
+
if (result.total === 0 || !result.resumes || result.resumes.length === 0) {
|
|
311
|
+
return "You don't have any resumes uploaded yet. Visit CareerVivid to upload one!";
|
|
312
|
+
}
|
|
313
|
+
const lines = [`You have ${result.total} resume(s) on CareerVivid:\n`];
|
|
314
|
+
for (const res of result.resumes) {
|
|
315
|
+
const updated = res.updatedAt ? ` (Updated: ${new Date(res.updatedAt).toLocaleDateString()})` : "";
|
|
316
|
+
lines.push(`- "${res.title}" [ID: ${res.id}]${updated}`);
|
|
317
|
+
}
|
|
318
|
+
lines.push("\nUse get_resume with a specific ID to view its content.");
|
|
319
|
+
return lines.join("\n");
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
// ---------------------------------------------------------------------------
|
|
323
|
+
// All job tools export
|
|
324
|
+
// ---------------------------------------------------------------------------
|
|
325
|
+
export const ALL_JOB_TOOLS = [
|
|
326
|
+
GetResumeTool,
|
|
327
|
+
ListResumesTool,
|
|
328
|
+
SearchJobsTool,
|
|
329
|
+
SaveJobTool,
|
|
330
|
+
ListJobsTool,
|
|
331
|
+
UpdateJobStatusTool,
|
|
332
|
+
];
|
package/dist/api.d.ts
CHANGED
|
@@ -72,4 +72,90 @@ export declare function uploadPortfolioAsset(image: string, path: string, mimeTy
|
|
|
72
72
|
downloadUrl: string;
|
|
73
73
|
} | ApiError>;
|
|
74
74
|
export declare function isApiError(v: unknown): v is ApiError;
|
|
75
|
+
export type ApplicationStatus = "To Apply" | "Applied" | "Interviewing" | "Offered" | "Rejected";
|
|
76
|
+
export interface ScoredJob {
|
|
77
|
+
id: string;
|
|
78
|
+
title: string;
|
|
79
|
+
company: string;
|
|
80
|
+
location: string;
|
|
81
|
+
description: string;
|
|
82
|
+
url: string;
|
|
83
|
+
salary?: string;
|
|
84
|
+
score: number;
|
|
85
|
+
scoreLabel: "Excellent" | "Good" | "Fair" | "Low";
|
|
86
|
+
aiSummary: string;
|
|
87
|
+
missingSkills: string[];
|
|
88
|
+
}
|
|
89
|
+
export interface JobTrackerItem {
|
|
90
|
+
id: string;
|
|
91
|
+
jobTitle: string;
|
|
92
|
+
companyName: string;
|
|
93
|
+
location: string;
|
|
94
|
+
applicationStatus: ApplicationStatus;
|
|
95
|
+
aiScore: number | null;
|
|
96
|
+
jobPostURL: string;
|
|
97
|
+
updatedAt: string | null;
|
|
98
|
+
notes: string;
|
|
99
|
+
}
|
|
100
|
+
export interface ResumeResult {
|
|
101
|
+
resumeId: string;
|
|
102
|
+
title: string;
|
|
103
|
+
cvMarkdown: string;
|
|
104
|
+
updatedAt: string | null;
|
|
105
|
+
}
|
|
106
|
+
export interface ResumesListResult {
|
|
107
|
+
resumes: {
|
|
108
|
+
id: string;
|
|
109
|
+
title: string;
|
|
110
|
+
updatedAt: string | null;
|
|
111
|
+
}[];
|
|
112
|
+
total: number;
|
|
113
|
+
}
|
|
114
|
+
/** Fetch the user's latest resume from CareerVivid via API key */
|
|
115
|
+
export declare function resumeGet(resumeId?: string): Promise<ResumeResult | ApiError>;
|
|
116
|
+
/** Fetch a lightweight list of the user's resumes */
|
|
117
|
+
export declare function resumesList(): Promise<ResumesListResult | ApiError>;
|
|
118
|
+
/** Run an agentic job search scored against the resume */
|
|
119
|
+
export declare function jobsHunt(payload: {
|
|
120
|
+
resumeContent?: string;
|
|
121
|
+
role: string;
|
|
122
|
+
location?: string;
|
|
123
|
+
count?: number;
|
|
124
|
+
minScore?: number;
|
|
125
|
+
targetOrgs?: string[];
|
|
126
|
+
}): Promise<{
|
|
127
|
+
jobs: ScoredJob[];
|
|
128
|
+
total: number;
|
|
129
|
+
} | ApiError>;
|
|
130
|
+
/** Add a job to the user's Kanban tracker */
|
|
131
|
+
export declare function jobsCreate(payload: {
|
|
132
|
+
jobTitle: string;
|
|
133
|
+
companyName: string;
|
|
134
|
+
location?: string;
|
|
135
|
+
jobPostURL?: string;
|
|
136
|
+
jobDescription?: string;
|
|
137
|
+
aiScore?: number;
|
|
138
|
+
aiSummary?: string;
|
|
139
|
+
notes?: string;
|
|
140
|
+
}): Promise<{
|
|
141
|
+
success: boolean;
|
|
142
|
+
id: string;
|
|
143
|
+
message: string;
|
|
144
|
+
} | ApiError>;
|
|
145
|
+
/** Move a job to a new status on the Kanban board */
|
|
146
|
+
export declare function jobsUpdate(payload: {
|
|
147
|
+
jobId: string;
|
|
148
|
+
status: ApplicationStatus;
|
|
149
|
+
notes?: string;
|
|
150
|
+
}): Promise<{
|
|
151
|
+
success: boolean;
|
|
152
|
+
jobId: string;
|
|
153
|
+
newStatus: string;
|
|
154
|
+
message: string;
|
|
155
|
+
} | ApiError>;
|
|
156
|
+
/** List jobs currently in the user's tracker */
|
|
157
|
+
export declare function jobsList(status?: ApplicationStatus): Promise<{
|
|
158
|
+
jobs: JobTrackerItem[];
|
|
159
|
+
total: number;
|
|
160
|
+
} | ApiError>;
|
|
75
161
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
CHANGED
|
@@ -151,3 +151,73 @@ export async function uploadPortfolioAsset(image, path, mimeType) {
|
|
|
151
151
|
export function isApiError(v) {
|
|
152
152
|
return typeof v === "object" && v !== null && v.isError === true;
|
|
153
153
|
}
|
|
154
|
+
// ── Cloud Function base URL ───────────────────────────────────────────────────
|
|
155
|
+
// The CLI job-hunt endpoints are deployed as standalone Cloud Functions,
|
|
156
|
+
// not via the /api proxy used by publishPost. This mirrors the verifyAuth pattern.
|
|
157
|
+
const CLI_FUNCTIONS_BASE = process.env.CV_FUNCTIONS_URL ||
|
|
158
|
+
"https://us-west1-jastalk-firebase.cloudfunctions.net";
|
|
159
|
+
async function cfRequest(method, functionName, body, queryParams) {
|
|
160
|
+
const apiKey = requireApiKey();
|
|
161
|
+
let url = `${CLI_FUNCTIONS_BASE}/${functionName}`;
|
|
162
|
+
if (queryParams) {
|
|
163
|
+
const qs = new URLSearchParams(queryParams).toString();
|
|
164
|
+
if (qs)
|
|
165
|
+
url += `?${qs}`;
|
|
166
|
+
}
|
|
167
|
+
const response = await fetch(url, {
|
|
168
|
+
method,
|
|
169
|
+
headers: {
|
|
170
|
+
"Content-Type": "application/json",
|
|
171
|
+
"x-api-key": apiKey,
|
|
172
|
+
"User-Agent": `careervivid-cli/${CLI_VERSION}`,
|
|
173
|
+
},
|
|
174
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
175
|
+
});
|
|
176
|
+
const text = await response.text();
|
|
177
|
+
let parsed = {};
|
|
178
|
+
try {
|
|
179
|
+
parsed = JSON.parse(text);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
parsed = { message: text };
|
|
183
|
+
}
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
return {
|
|
186
|
+
isError: true,
|
|
187
|
+
statusCode: response.status,
|
|
188
|
+
message: parsed.error || parsed.message || `HTTP ${response.status}`,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return parsed;
|
|
192
|
+
}
|
|
193
|
+
// ── Job Hunt API Methods ──────────────────────────────────────────────────────
|
|
194
|
+
/** Fetch the user's latest resume from CareerVivid via API key */
|
|
195
|
+
export async function resumeGet(resumeId) {
|
|
196
|
+
const params = {};
|
|
197
|
+
if (resumeId)
|
|
198
|
+
params.resumeId = resumeId;
|
|
199
|
+
return cfRequest("GET", "cliResumeGet", undefined, Object.keys(params).length ? params : undefined);
|
|
200
|
+
}
|
|
201
|
+
/** Fetch a lightweight list of the user's resumes */
|
|
202
|
+
export async function resumesList() {
|
|
203
|
+
return cfRequest("GET", "cliResumesList");
|
|
204
|
+
}
|
|
205
|
+
/** Run an agentic job search scored against the resume */
|
|
206
|
+
export async function jobsHunt(payload) {
|
|
207
|
+
return cfRequest("POST", "cliJobsHunt", payload);
|
|
208
|
+
}
|
|
209
|
+
/** Add a job to the user's Kanban tracker */
|
|
210
|
+
export async function jobsCreate(payload) {
|
|
211
|
+
return cfRequest("POST", "cliJobsCreate", payload);
|
|
212
|
+
}
|
|
213
|
+
/** Move a job to a new status on the Kanban board */
|
|
214
|
+
export async function jobsUpdate(payload) {
|
|
215
|
+
return cfRequest("POST", "cliJobsUpdate", payload);
|
|
216
|
+
}
|
|
217
|
+
/** List jobs currently in the user's tracker */
|
|
218
|
+
export async function jobsList(status) {
|
|
219
|
+
const params = {};
|
|
220
|
+
if (status)
|
|
221
|
+
params.status = status;
|
|
222
|
+
return cfRequest("GET", "cliJobsList", undefined, Object.keys(params).length ? params : undefined);
|
|
223
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2FpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA2SpD"}
|