careervivid 1.12.27 → 1.12.36

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.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * agentAuditLog.ts — Forensic audit trail for every agent tool call.
3
+ *
4
+ * Architecture:
5
+ * PRIMARY: Local JSONL append at ~/.careervivid/agent-audit.log
6
+ * Fast, offline, zero network dependency.
7
+ * Each line is a self-contained JSON record.
8
+ *
9
+ * SECONDARY: Firebase Firestore (jastalk-firebase / agent_audit_logs)
10
+ * Written fire-and-forget (non-blocking). Fails silently.
11
+ * Gives cloud visibility and cross-device forensics via the web dashboard.
12
+ *
13
+ * Usage (in repl.ts):
14
+ * import { auditLog, flushAuditLog } from "./agentAuditLog.js";
15
+ * auditLog({ sessionId, tool: name, args, result, durationMs });
16
+ * // On session end:
17
+ * await flushAuditLog();
18
+ */
19
+ export interface AuditEntry {
20
+ ts: string;
21
+ sessionId: string;
22
+ tool: string;
23
+ args: Record<string, unknown>;
24
+ resultSummary: string;
25
+ durationMs: number;
26
+ ok: boolean;
27
+ }
28
+ export declare let SESSION_ID: string;
29
+ export declare function auditLog(entry: {
30
+ sessionId?: string;
31
+ tool: string;
32
+ args: Record<string, unknown>;
33
+ result: string;
34
+ durationMs: number;
35
+ }): void;
36
+ export declare function flushAuditLog(): Promise<void>;
37
+ export declare function writeSessionSummary(stats: {
38
+ turns: number;
39
+ mutations: number;
40
+ toolCalls: number;
41
+ creditsUsed?: number;
42
+ }): Promise<void>;
43
+ //# sourceMappingURL=agentAuditLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentAuditLog.d.ts","sourceRoot":"","sources":["../../src/agent/agentAuditLog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;CACb;AAID,eAAO,IAAI,UAAU,QAA2B,CAAC;AA8BjD,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAuBP;AAwCD,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAMnD;AAID,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBhB"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * agentAuditLog.ts — Forensic audit trail for every agent tool call.
3
+ *
4
+ * Architecture:
5
+ * PRIMARY: Local JSONL append at ~/.careervivid/agent-audit.log
6
+ * Fast, offline, zero network dependency.
7
+ * Each line is a self-contained JSON record.
8
+ *
9
+ * SECONDARY: Firebase Firestore (jastalk-firebase / agent_audit_logs)
10
+ * Written fire-and-forget (non-blocking). Fails silently.
11
+ * Gives cloud visibility and cross-device forensics via the web dashboard.
12
+ *
13
+ * Usage (in repl.ts):
14
+ * import { auditLog, flushAuditLog } from "./agentAuditLog.js";
15
+ * auditLog({ sessionId, tool: name, args, result, durationMs });
16
+ * // On session end:
17
+ * await flushAuditLog();
18
+ */
19
+ import { appendFileSync, existsSync, mkdirSync } from "fs";
20
+ import { resolve } from "path";
21
+ import { homedir } from "os";
22
+ import { randomUUID } from "crypto";
23
+ // ── Session-level state ───────────────────────────────────────────────────────
24
+ export let SESSION_ID = randomUUID().slice(0, 8);
25
+ const pendingFirestore = [];
26
+ // ── Local JSONL path ──────────────────────────────────────────────────────────
27
+ function getAuditLogPath() {
28
+ const dir = resolve(homedir(), ".careervivid");
29
+ if (!existsSync(dir))
30
+ mkdirSync(dir, { recursive: true });
31
+ return resolve(dir, "agent-audit.log");
32
+ }
33
+ // ── Sanitize args (remove any key that looks like a secret) ─────────────────
34
+ function sanitizeArgs(args) {
35
+ const REDACT_KEYS = /key|secret|password|token|auth|credential/i;
36
+ const out = {};
37
+ for (const [k, v] of Object.entries(args)) {
38
+ if (REDACT_KEYS.test(k)) {
39
+ out[k] = "***REDACTED***";
40
+ }
41
+ else if (typeof v === "string" && v.length > 300) {
42
+ out[k] = v.slice(0, 300) + "…";
43
+ }
44
+ else {
45
+ out[k] = v;
46
+ }
47
+ }
48
+ return out;
49
+ }
50
+ // ── Core log function (sync local + async Firestore) ─────────────────────────
51
+ export function auditLog(entry) {
52
+ const record = {
53
+ ts: new Date().toISOString(),
54
+ sessionId: entry.sessionId ?? SESSION_ID,
55
+ tool: entry.tool,
56
+ args: sanitizeArgs(entry.args),
57
+ resultSummary: entry.result.slice(0, 200).replace(/\n/g, " "),
58
+ durationMs: Math.round(entry.durationMs),
59
+ ok: !entry.result.startsWith("❌"),
60
+ };
61
+ // ── 1. Local JSONL (synchronous, never fails) ─────────────────────────────
62
+ try {
63
+ appendFileSync(getAuditLogPath(), JSON.stringify(record) + "\n", "utf-8");
64
+ }
65
+ catch {
66
+ // Silently swallow — never break the agent because of logging
67
+ }
68
+ // ── 2. Firebase Firestore (fire-and-forget — non-blocking) ───────────────
69
+ pendingFirestore.push(record);
70
+ void writeToFirestore(record).catch(() => {
71
+ // Silently swallow — Firebase being unavailable must not affect the agent
72
+ });
73
+ }
74
+ // ── Firebase write (dynamic import to avoid hard dependency) ─────────────────
75
+ async function writeToFirestore(record) {
76
+ // Only attempt if firebase-admin is installed (it's optional)
77
+ let admin;
78
+ try {
79
+ admin = await import("firebase-admin");
80
+ }
81
+ catch {
82
+ return; // firebase-admin not installed — skip silently
83
+ }
84
+ try {
85
+ if (!admin.apps?.length) {
86
+ // Use Application Default Credentials (works in GCP/Cloud Shell)
87
+ // or the service account key if present
88
+ const keyPath = resolve(homedir(), ".careervivid", "firebase-service-account.json");
89
+ const credential = existsSync(keyPath)
90
+ ? admin.credential.cert(keyPath)
91
+ : admin.credential.applicationDefault();
92
+ admin.initializeApp({
93
+ credential,
94
+ projectId: "jastalk-firebase",
95
+ });
96
+ }
97
+ const db = admin.firestore();
98
+ await db.collection("agent_audit_logs").add({
99
+ ...record,
100
+ createdAt: admin.firestore.FieldValue.serverTimestamp(),
101
+ });
102
+ }
103
+ catch {
104
+ // Any Firebase error is silently swallowed
105
+ }
106
+ }
107
+ // ── Flush pending entries (call on session end) ───────────────────────────────
108
+ export async function flushAuditLog() {
109
+ // Pending Firestore writes are already in-flight via fire-and-forget.
110
+ // Give them 2 seconds to complete before exit.
111
+ if (pendingFirestore.length > 0) {
112
+ await new Promise(r => setTimeout(r, 2000));
113
+ }
114
+ }
115
+ // ── Session summary (call on exit) ─────────────────────────────────────────
116
+ export async function writeSessionSummary(stats) {
117
+ const record = {
118
+ type: "session_summary",
119
+ sessionId: SESSION_ID,
120
+ ts: new Date().toISOString(),
121
+ ...stats,
122
+ };
123
+ try {
124
+ appendFileSync(getAuditLogPath(), JSON.stringify(record) + "\n", "utf-8");
125
+ }
126
+ catch { /* silent */ }
127
+ // Firestore session summary
128
+ let admin;
129
+ try {
130
+ admin = await import("firebase-admin");
131
+ }
132
+ catch {
133
+ return;
134
+ }
135
+ try {
136
+ if (admin.apps?.length) {
137
+ const db = admin.firestore();
138
+ await db.collection("agent_session_summaries").add({
139
+ ...record,
140
+ createdAt: admin.firestore.FieldValue.serverTimestamp(),
141
+ });
142
+ }
143
+ }
144
+ catch { /* silent */ }
145
+ }
@@ -14,7 +14,6 @@ export declare const BASE_IDENTITY: string;
14
14
  export declare const RESUME_SECTION: string;
15
15
  export declare const CODING_SECTION: string;
16
16
  export declare const JOBS_TOOLS_SECTION: string;
17
- export declare const BROWSER_SECTION: string;
18
17
  export declare const JOBS_HARNESS: string;
19
18
  export declare const GREETING_PROTOCOL: string;
20
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/agent/instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,aAAa,QAalB,CAAC;AAMT,eAAO,MAAM,cAAc,QAcnB,CAAC;AAMT,eAAO,MAAM,cAAc,QAgBnB,CAAC;AAMT,eAAO,MAAM,kBAAkB,QA2BvB,CAAC;AAMT,eAAO,MAAM,eAAe,QAOpB,CAAC;AAMT,eAAO,MAAM,YAAY,QAoBjB,CAAC;AAMT,eAAO,MAAM,iBAAiB,QActB,CAAC;AAMT;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,MAAM,CA0BT"}
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/agent/instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,aAAa,QAalB,CAAC;AAMT,eAAO,MAAM,cAAc,QAcnB,CAAC;AAMT,eAAO,MAAM,cAAc,QAgBnB,CAAC;AAMT,eAAO,MAAM,kBAAkB,QAqCvB,CAAC;AAMT,eAAO,MAAM,YAAY,QAuCjB,CAAC;AAMT,eAAO,MAAM,iBAAiB,QActB,CAAC;AAMT;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,MAAM,CAyBT"}
@@ -74,62 +74,80 @@ export const JOBS_TOOLS_SECTION = `
74
74
  - **tailor_resume** — Tailor/refine the user's resume for a specific role or JD.
75
75
  - **delete_resume** — Permanently delete a resume (ask for confirmation first).
76
76
 
77
- ### Job Search & Tracker
78
- - **search_jobs** — Search for jobs scored against the user's resume (call get_resume first).
79
- - **save_job** — Save a job to the online Kanban board.
80
- - **list_jobs** — Show the online Kanban board.
81
- - **update_job_status** Move a job through: To Apply → Applied → Interviewing → Offered/Rejected.
82
-
83
- ### Local Pipeline (CSV v2)
84
- - **list_local_jobs** Show the local pipeline (supports tier/status filters and sort_by).
85
- - **add_local_job** Add a new company to the tracker.
86
- - **update_local_job** — Update any field on a job entry.
87
- - **score_pipeline** Priority-ranked view; use for "what next?" questions.
88
- - **get_pipeline_metrics** — Full analytics: apply rate, avg scores, salary data, stale count.
89
- - **flag_stale_jobs** Surface cold companies with next-action recommendations.
77
+ ### Job Search
78
+ - **search_jobs** — Search for jobs scored against the user's resume. Returns results for review (dry_run by default — does NOT auto-save).
79
+
80
+ ### CSV Pipeline Tracker (tracker_*)
81
+ These tools read/write jobs.csv the local career-ops pipeline spreadsheet.
82
+ - **tracker_list_jobs** — Show the pipeline (supports tier/status filters and sort_by).
83
+ - **tracker_add_job** — Add a new company to the tracker.
84
+ - **tracker_update_job** Update any field on a job entry (status, scores, notes, follow-up).
85
+ - **tracker_rank_priority** Priority-ranked view; use for "what next?" questions.
86
+ - **tracker_dashboard** — Full analytics: apply rate, avg scores, salary data, stale count.
87
+ - **tracker_find_stale** Surface cold companies with next-action recommendations.
88
+ - **tracker_inspect_quality**— Scan for duplicates, missing URLs, and corrupted data (read-only).
89
+ - **tracker_recheck_urls** Re-verify all careers URLs in the tracker; annotates dead links in notes.
90
+
91
+ ### Web Kanban Board (kanban_*)
92
+ These tools read/write the Firebase Kanban board at careervivid.app/job-tracker.
93
+ - **kanban_add_job** — Save a job card to the web Kanban board.
94
+ - **kanban_list_jobs** — Show the web Kanban board.
95
+ - **kanban_update_status** — Move a Kanban card to a new status column.
96
+
97
+ ### Browser Automation (browser_*)
98
+ - **browser_autofill_application** ⭐ — Auto-fill an application form in Chrome (does NOT submit).
99
+ - browser_navigate, browser_state, browser_click, browser_type, browser_select, browser_scroll, browser_screenshot
90
100
 
91
101
  ### URL Safety (Mandatory)
92
- - **verify_url** — Verify a single link is alive before sharing it.
93
- - **verify_search_results** — Verify all URLs returned by search_jobs before presenting them.
102
+ - **verify_url** — Verify a single link is alive before sharing it.
103
+ - **verify_job_urls** — Verify all URLs from a search_jobs result batch.
94
104
  NEVER share a link without verifying it first.
95
105
  `.trim();
96
106
  // ---------------------------------------------------------------------------
97
- // §5 — Browser control (appended in --jobs mode)
107
+ // §5 — Autonomous execution harness (appended in --jobs mode)
98
108
  // ---------------------------------------------------------------------------
99
- export const BROWSER_SECTION = `
100
- ## Browser Control
109
+ export const JOBS_HARNESS = `
110
+ ## Autonomy Rules (Non-Negotiable)
101
111
 
102
- - **browser_use_agent** PRIMARY autonomous form-filling agent (pass URL + full resume context)
103
- - browser_navigate, browser_state, browser_click, browser_type, browser_select, browser_scroll, browser_screenshot
112
+ ### What you may do freely (no confirmation needed)
113
+ - Call any read-only tool (tracker_list_jobs, tracker_dashboard, tracker_rank_priority, tracker_find_stale, tracker_inspect_quality, tracker_recheck_urls, search_jobs, get_resume, etc.)
114
+ - Add a new company/job entry via tracker_add_job (when the user explicitly names a company or approves a search result)
115
+ - Update non-status fields (attention_score, excitement, notes, follow_up_date, etc.) via tracker_update_job
104
116
 
105
- NEVER submit a form without explicit user confirmation.
106
- `.trim();
107
- // ---------------------------------------------------------------------------
108
- // §6 Autonomous execution harness (appended in --jobs mode)
109
- // ---------------------------------------------------------------------------
110
- export const JOBS_HARNESS = `
111
- ## Autonomous Execution Directives (Non-Negotiable)
117
+ ### What requires explicit user confirmation
118
+ - Changing status to "Applied", "Rejected", or "Ghosted" — present the proposed change and wait for "yes"
119
+ - Deleting any entry
120
+ - Submitting any web form via browser tools
121
+
122
+ ### Anti-hallucination rules (CRITICAL)
123
+ - NEVER invent company names. All companies added via tracker_add_job MUST come from:
124
+ (a) verified search_jobs results with a real URL, OR (b) explicit user input naming the company.
125
+ - If search_jobs returns 0 results: say so — do NOT generate fictional alternative companies.
126
+ - Do NOT add more than 5 new companies in a single response without user review.
127
+ - A company without a valid careers_url (starting with http) is flagged as unverified — add it with a note.
112
128
 
113
- 1. DO NOT ASK FOR PERMISSION before calling mutative tools (add_local_job, update_local_job, etc.) unless the action is destructive.
114
- 2. Fill in missing details with sensible defaults (TBD, today's date, empty strings) rather than stalling for input.
115
- 3. If you catch yourself explaining what you *are going to do* instead of calling the tool STOP and call the tool.
116
- 4. Complete the full workflow (e.g., tailoring a resume, finding jobs) ONLY if explicitly requested or obviously needed. However, if the user just asks a simple targeted question (e.g., "Did you find X?", "Is my resume up to date?"), DO NOT trigger an unprompted mass workflow (like saving extra companies and rewriting multiple resumes). Answer the question immediately.
129
+ ### Deduplication rule (MANDATORY)
130
+ Before calling tracker_add_job, ALWAYS check tracker_list_jobs to see if the company+role already exists.
131
+ If it does, call tracker_update_job instead — never create a duplicate row.
117
132
 
118
133
  ## Mandatory Tool Dispatch Table
119
134
 
120
135
  | User asks about… | Call… |
121
136
  |-----------------------------------------------|--------------------------------|
122
- | pipeline, job list, tracker | list_local_jobs |
123
- | priority, what next, best ROI | score_pipeline |
124
- | stats, dashboard, apply rate, search health | get_pipeline_metrics |
125
- | stale, cold, neglecting, need attention | flag_stale_jobs |
126
- | adding a company, new job | add_local_job |
127
- | updating status, marking applied, follow-up | update_local_job |
137
+ | pipeline, job list, tracker | tracker_list_jobs |
138
+ | priority, what next, best ROI | tracker_rank_priority |
139
+ | stats, dashboard, apply rate, search health | tracker_dashboard |
140
+ | stale, cold, neglecting, need attention | tracker_find_stale |
141
+ | duplicates, data quality, audit | tracker_inspect_quality |
142
+ | stale/dead job URLs, link check | tracker_recheck_urls |
143
+ | adding a company, new job | tracker_add_job |
144
+ | updating status, marking applied, follow-up | tracker_update_job |
145
+ | Kanban board, web tracker | kanban_list_jobs |
128
146
  | resume, background, skills, experience | get_resume |
129
147
  | find jobs, search roles | get_resume → search_jobs |
130
148
  `.trim();
131
149
  // ---------------------------------------------------------------------------
132
- // §7 — Greeting protocol (shared across modes)
150
+ // §6 — Greeting protocol (shared across modes)
133
151
  // ---------------------------------------------------------------------------
134
152
  export const GREETING_PROTOCOL = `
135
153
  ## Greeting Protocol
@@ -147,7 +165,7 @@ When the user sends a generic greeting ("hey", "hi", "hello", "start"), respond
147
165
  Just tell me what you need!"
148
166
  `.trim();
149
167
  // ---------------------------------------------------------------------------
150
- // §8 — Assembled system prompts per mode (the public API)
168
+ // §7 — Assembled system prompts per mode (the public API)
151
169
  // ---------------------------------------------------------------------------
152
170
  /**
153
171
  * Returns the assembled system prompt for a given agent mode.
@@ -159,7 +177,6 @@ export function buildSystemPrompt(options) {
159
177
  BASE_IDENTITY,
160
178
  RESUME_SECTION,
161
179
  JOBS_TOOLS_SECTION,
162
- BROWSER_SECTION,
163
180
  JOBS_HARNESS,
164
181
  GREETING_PROTOCOL,
165
182
  ].join("\n\n---\n\n");
@@ -1 +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;AAmBlC,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,IAgC3B,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IA6B7B,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,IAmE9B,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,IAwB9B,CAAC;AAMF,eAAO,MAAM,cAAc,EAAE,IAyO5B,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,IAAI,EAU/B,CAAC"}
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;AAmBlC,eAAO,MAAM,cAAc,EAAE,IAmG5B,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,IAgC3B,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IA6B7B,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,IAmE9B,CAAC;AAMF,eAAO,MAAM,gBAAgB,EAAE,IAwB9B,CAAC;AAMF,eAAO,MAAM,cAAc,EAAE,IAyO5B,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,IAAI,EAU/B,CAAC"}
@@ -12,10 +12,10 @@ import { jobsHunt, jobsCreate, jobsList, jobsUpdate, resumeGet, resumesList, res
12
12
  // ---------------------------------------------------------------------------
13
13
  export const SearchJobsTool = {
14
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.`,
15
+ description: `Search for jobs matching a role and location, scored against the user's resume.
16
+ Returns a scored list of job opportunities with AI summaries and missing skills.
17
+ Use this when the user asks to "find jobs", "search for roles", "look for positions", etc.
18
+ By default operates in dry_run mode results are shown for review, nothing is saved automatically.`,
19
19
  parameters: {
20
20
  type: Type.OBJECT,
21
21
  properties: {
@@ -33,12 +33,16 @@ Use this when the user asks to "find jobs", "search for roles", "look for positi
33
33
  },
34
34
  min_score: {
35
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.",
36
+ description: "Optional. Minimum match score (0-100). Default is 70. Use 80 for excellent matches only.",
37
37
  },
38
38
  resume_id: {
39
39
  type: Type.STRING,
40
40
  description: "Optional. Specific resume ID to score against. If omitted, uses the user's latest resume.",
41
41
  },
42
+ dry_run: {
43
+ type: Type.BOOLEAN,
44
+ description: "Optional. Default: true. If true, shows results for review without auto-saving. Set false only if user explicitly says to save all results.",
45
+ },
42
46
  },
43
47
  required: ["role"],
44
48
  },
@@ -59,7 +63,7 @@ Use this when the user asks to "find jobs", "search for roles", "look for positi
59
63
  role: args.role,
60
64
  location: args.location,
61
65
  count: args.count ?? 10,
62
- minScore: args.min_score,
66
+ minScore: args.min_score ?? 70, // default 70 to filter low-quality results
63
67
  });
64
68
  if (isApiError(result)) {
65
69
  return `Error searching jobs: ${result.message}`;
@@ -79,15 +83,20 @@ Use this when the user asks to "find jobs", "search for roles", "look for positi
79
83
  ` Job ID: ${job.id}`);
80
84
  })
81
85
  .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}`);
86
+ const isDryRun = args.dry_run !== false; // default true
87
+ const dryRunNote = isDryRun
88
+ ? `\n\n📋 Review above. Say "add [company] to my tracker" to save specific ones.`
89
+ : "";
90
+ return (`Found ${result.total} jobs for "${args.role}"${args.location ? ` in ${args.location}` : ""}. ` +
91
+ `Showing top ${result.jobs.length} (min score ${args.min_score ?? 70}%):\n\n${jobList}` +
92
+ dryRunNote);
84
93
  },
85
94
  };
86
95
  // ---------------------------------------------------------------------------
87
96
  // Tool: save_job
88
97
  // ---------------------------------------------------------------------------
89
98
  export const SaveJobTool = {
90
- name: "save_job",
99
+ name: "kanban_add_job",
91
100
  description: `Save a job to the user's CareerVivid job tracker Kanban board.
92
101
  The job will appear in the "To Apply" column of the /job-tracker page.
93
102
  Use this after finding interesting jobs via search_jobs, or when the user asks to "save", "add", or "track" a specific job.`,
@@ -154,7 +163,7 @@ Use this after finding interesting jobs via search_jobs, or when the user asks t
154
163
  // Tool: list_jobs
155
164
  // ---------------------------------------------------------------------------
156
165
  export const ListJobsTool = {
157
- name: "list_jobs",
166
+ name: "kanban_list_jobs",
158
167
  description: `List the user's jobs from their CareerVivid job tracker Kanban board.
159
168
  Can filter by status. Use this when the user asks "what jobs do I have?", "show my tracker",
160
169
  "what's in my job pipeline?", "check my interviews", etc.`,
@@ -216,7 +225,7 @@ Can filter by status. Use this when the user asks "what jobs do I have?", "show
216
225
  // Tool: update_job_status
217
226
  // ---------------------------------------------------------------------------
218
227
  export const UpdateJobStatusTool = {
219
- name: "update_job_status",
228
+ name: "kanban_update_status",
220
229
  description: `Move a job to a different status on the CareerVivid Kanban board.
221
230
  Use this when the user mentions: "I got an interview", "I applied to X", "I got an offer",
222
231
  "X rejected me", "move Y to applied", etc. The change will be visible in the /job-tracker UI.`,
@@ -412,7 +421,7 @@ MAKE SURE the user actually intends to delete it, as this is permanent.`,
412
421
  // Tool: apply_to_job
413
422
  // ---------------------------------------------------------------------------
414
423
  export const ApplyToJobTool = {
415
- name: "apply_to_job",
424
+ name: "browser_autofill_application",
416
425
  description: `Open a job application in the user's Chrome browser and auto-fill it with AI-tailored answers.
417
426
  This tool launches Playwright, navigates to the job URL, extracts the form fields, fills them
418
427
  with AI-generated answers from the user's resume, and shows the user a final preview before submitting.
@@ -19,11 +19,18 @@
19
19
  * flag_stale_jobs → surface companies with no recent activity
20
20
  */
21
21
  import { Tool } from "../Tool.js";
22
+ export interface JobValidationResult {
23
+ ok: boolean;
24
+ blockers: string[];
25
+ warnings: string[];
26
+ }
22
27
  export declare const ListLocalJobsTool: Tool;
23
28
  export declare const UpdateLocalJobTool: Tool;
24
29
  export declare const AddLocalJobTool: Tool;
25
30
  export declare const ScorePipelineTool: Tool;
26
31
  export declare const GetPipelineMetricsTool: Tool;
27
32
  export declare const FlagStaleJobsTool: Tool;
33
+ export declare const InspectQualityTool: Tool;
34
+ export declare const RecheckUrlsTool: Tool;
28
35
  export declare const ALL_LOCAL_TRACKER_TOOLS: Tool[];
29
36
  //# sourceMappingURL=local-tracker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-tracker.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/local-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAwKlC,eAAO,MAAM,iBAAiB,EAAE,IA8H/B,CAAC;AAMF,eAAO,MAAM,kBAAkB,EAAE,IA2HhC,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IAmG7B,CAAC;AAMF,eAAO,MAAM,iBAAiB,EAAE,IA2F/B,CAAC;AAMF,eAAO,MAAM,sBAAsB,EAAE,IA+GpC,CAAC;AAMF,eAAO,MAAM,iBAAiB,EAAE,IAoE/B,CAAC;AAMF,eAAO,MAAM,uBAAuB,EAAE,IAAI,EAOzC,CAAC"}
1
+ {"version":3,"file":"local-tracker.d.ts","sourceRoot":"","sources":["../../../src/agent/tools/local-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAkClC,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAuRD,eAAO,MAAM,iBAAiB,EAAE,IA8H/B,CAAC;AAMF,eAAO,MAAM,kBAAkB,EAAE,IAgJhC,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IAkJ7B,CAAC;AAMF,eAAO,MAAM,iBAAiB,EAAE,IA2F/B,CAAC;AAMF,eAAO,MAAM,sBAAsB,EAAE,IA+GpC,CAAC;AAMF,eAAO,MAAM,iBAAiB,EAAE,IAoE/B,CAAC;AAMF,eAAO,MAAM,kBAAkB,EAAE,IAsEhC,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,IAoG7B,CAAC;AAMF,eAAO,MAAM,uBAAuB,EAAE,IAAI,EASzC,CAAC"}