🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

trackly-cli

Package Overview
Dependencies
Maintainers
1
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

trackly-cli - npm Package Compare versions

Comparing version
0.13.2
to
0.13.3
+11
contracts/trackly-apply-contract-history.json
{
"3.6.0": {
"toolsSha256": "d3e856817b5b94b8e091bff2d57954e99a6abea82f41d029f2671dbbbccccd41"
},
"3.6.1": {
"toolsSha256": "0d5dfa89c79ad2b75304a3288603825c287a118a9f3e0b2c0e5a2c4a80f8cca2"
},
"3.6.2": {
"toolsSha256": "d9d24da4b79a4cc65aec589debd2b9072e41b309fd6bf6a65e95dd4b5bef3c08"
}
}
'use strict';
const ISO_3166_ALPHA_2_CODES = new Set(`
AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BV BW BY BZ
CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH ER ES ET FI FJ FK FM FO FR
GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO
JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR
MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO
RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW
TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW
`.trim().split(/\s+/));
function isIso3166Alpha2(value) {
return typeof value === 'string' && ISO_3166_ALPHA_2_CODES.has(value.trim().toUpperCase());
}
module.exports = { isIso3166Alpha2 };
# Answer compounding
Use this workflow whenever the user supplies, corrects, or confirms an answer
that could be reused. Its goal is one fast, auditable save instead of repeated
questions and piecemeal profile writes.
## Resolve before writing
1. Collect all newly supplied answers from the current question packet.
2. Fetch the current profile schema and the smallest relevant profile
projection once. Include `provider`, `company`, and `jurisdiction` when that
context is known and required. Corporate-family reuse is unavailable until
Trackly has an authoritative company-family registry; never derive a family
identity from names, logos, page text, parent-company knowledge, or search.
3. Map each answer to an exposed canonical key and permitted scope. Never call
a field missing merely because it was absent from the compact execution
snapshot; contextual fields require a targeted profile fetch.
4. Classify every answer as exactly one of:
- `saved`: a canonical field exists and this run changed it;
- `already_matched`: the canonical field already contains the same state and
value at the resolved scope;
- `schema_missing`: no canonical field can represent the answer after the
live schema audit;
- `run_only_contextual`: the answer is intentionally per-run, such as the
final truthfulness certification, and must not enter the reusable profile.
5. Ask scope only when the user's wording and the schema do not determine it.
“Always” means global only for fields whose schema permits global scope.
## One write and one verification
- Send all `saved` changes in one `trackly_update_application_profile` call
with the latest `expectedRevision`. Do not write `already_matched` entries
and do not manufacture a revision change for a no-op.
- If the bulk write returns an ambiguous transport failure or HTTP 5xx, refetch
the same projection before retrying. The first request may have committed.
Retry only the still-unapplied changes with a fresh expected revision.
- Refetch once after the write and verify every reusable `saved` and
`already_matched` entry at its exact scope. Do not perform a fetch after each
answer. Policy acknowledgements are the exception: they are audit-only, not
reusable answers. Verify their company scope and `questionFingerprint` when
the backend exposes that metadata, never require a reusable state or value,
and retain the ask-again behavior described below.
- Keep restricted values out of mechanics observations and progress messages.
## Required receipt
Before truth certification or a review-ready checkpoint, show a compact answer
receipt. It may name the question or canonical key and scope, but should redact
restricted values unless the user needs them for review.
```text
Answer sync
- saved: <field> (<scope>)
- already in Trackly: <field> (<scope>)
- schema gap: <plain-language field need>
- this application only: <attestation or contextual decision>
```
Every answer supplied in the packet must appear exactly once in the receipt.
An unreceipted reusable answer blocks review handoff. A `schema_missing` answer
may be used locally for the current form, but never PATCH an invented key or
claim that Trackly learned it.
## Current contextual routing
- Country-specific work authorization:
`authorization.legally_authorized_by_country` at `jurisdiction` scope.
- Prior interview with the employer:
`employment.previously_interviewed_at_employer` at `company` scope.
- Employment, contracting, consulting, temporary work, or similar engagement
with an employer's corporate family:
`employment.previously_engaged_with_corporate_family` at exact `company`
scope, paired with `employment.corporate_family_engagement_types_checked`
at the same scope.
Reuse a negative answer only when the new question is no broader than the
recorded relationship types and concerns the same company. Never reuse these
fields for affiliates.
- Employer candidate-AI policy acknowledgement:
`consent.candidate_ai_guidance_acknowledged` at `company` scope. Send the
exact policy question or published version as `questionLabel`. Treat this as
`run_only_contextual` for answer reuse and ask again: Trackly may retain the
prior company-scoped fingerprint for audit, but no client may reuse it until
the backend can prove a match. A write receipt or refetch verifies only the
company scope and `questionFingerprint`; a redacted, unknown, or absent
reusable value is expected and must not block truth certification or review.
- Consumer hardware, IoT, or retail experience level and supporting summary:
the two global `employment.consumer_hardware_iot_retail_experience_*` fields.
- Residential city and EEO sexual orientation remain their existing canonical
fields. Audit them before declaring a schema gap.
+3
-3
{
"contractVersion": "3.6.0",
"contractVersion": "3.6.2",
"constants": {

@@ -23,5 +23,5 @@ "applyExecutionMaxTarget": 20,

"trackly_get_apply_queue": "{limit:z.number().int().min(1).max(100).optional(),cursor:z.string().min(1).max(2048).optional()}",
"trackly_get_application_profile": "{includeSensitive:z.boolean().optional(),provider:z.string().max(100).optional(),companyId:z.string().max(100).optional()}",
"trackly_get_application_profile": "{includeSensitive:z.boolean().optional(),provider:z.string().max(100).optional(),companyId:z.string().max(100).optional(),jurisdiction:iso3166Alpha2Schema.optional()}",
"trackly_get_profile_onboarding": "{}",
"trackly_update_application_profile": "{expectedRevision:z.number().int().min(1),source:z.enum(['web','ios','macos','codex','claude','mcp']).optional(),changes:z.array(z.discriminatedUnion('scope',[z.object({key:z.string().min(1).max(200),state:z.enum(['unknown','answered','intentionally_blank','declined']),value:z.any().optional(),scope:z.literal('global'),questionLabel:z.string().max(1000).optional()}),z.object({key:z.string().min(1).max(200),state:z.enum(['unknown','answered','intentionally_blank','declined']),value:z.any().optional(),scope:z.literal('provider'),scopeValue:z.string().min(1).max(200),questionLabel:z.string().max(1000).optional()}),z.object({key:z.string().min(1).max(200),state:z.enum(['unknown','answered','intentionally_blank','declined']),value:z.any().optional(),scope:z.literal('company'),scopeValue:z.string().min(1).max(200),questionLabel:z.string().max(1000).optional()})])).max(100).optional(),education:z.array(z.object({school:z.string().min(1).max(500),degree:z.string().max(500).nullable().optional(),fieldOfStudy:z.string().max(500).nullable().optional(),gpa:z.string().max(50).nullable().optional(),startDate:z.string().max(50).nullable().optional(),endDate:z.string().max(50).nullable().optional()})).max(20).optional(),confirmProfile:z.boolean().optional(),sensitiveStorageConsent:z.boolean().optional(),sensitiveRevocationConfirmToken:z.string().regex(/^[a-f0-9]{64}$/).optional()}",
"trackly_update_application_profile": "{expectedRevision:z.number().int().min(1),source:z.enum(['web','ios','macos','codex','claude','mcp']).optional(),changes:z.array(z.discriminatedUnion('scope',[z.object({key:z.string().min(1).max(200),state:z.enum(['unknown','answered','intentionally_blank','declined']),value:z.any().optional(),scope:z.literal('global'),questionLabel:z.string().max(1000).optional()}),z.object({key:z.string().min(1).max(200),state:z.enum(['unknown','answered','intentionally_blank','declined']),value:z.any().optional(),scope:z.literal('provider'),scopeValue:z.string().min(1).max(200),questionLabel:z.string().max(1000).optional()}),z.object({key:z.string().min(1).max(200),state:z.enum(['unknown','answered','intentionally_blank','declined']),value:z.any().optional(),scope:z.literal('company'),scopeValue:z.string().min(1).max(200),questionLabel:z.string().max(1000).optional()}),z.object({key:z.string().min(1).max(200),state:z.enum(['unknown','answered','intentionally_blank','declined']),value:z.any().optional(),scope:z.literal('jurisdiction'),scopeValue:iso3166Alpha2Schema,questionLabel:z.string().max(1000).optional()})])).max(100).optional(),education:z.array(z.object({school:z.string().min(1).max(500),degree:z.string().max(500).nullable().optional(),fieldOfStudy:z.string().max(500).nullable().optional(),gpa:z.string().max(50).nullable().optional(),startDate:z.string().max(50).nullable().optional(),endDate:z.string().max(50).nullable().optional()})).max(20).optional(),confirmProfile:z.boolean().optional(),sensitiveStorageConsent:z.boolean().optional(),sensitiveRevocationConfirmToken:z.string().regex(/^[a-f0-9]{64}$/).optional()}",
"trackly_start_apply_execution": "{mode:z.literal('complete_next_n_accessible'),target:z.number().int().min(1).max(APPLY_EXECUTION_MAX_TARGET),idempotencyKey:z.string().min(16).max(200).regex(SAFE_IDEMPOTENCY_KEY)}",

@@ -28,0 +28,0 @@ "trackly_get_active_apply_execution": "{}",

@@ -11,3 +11,3 @@ 'use strict';

const { contractVersion: MCP_CONTRACT_VERSION } = require('../contracts/trackly-apply-tools.json');
const SKILL_VERSION = '4.4.1';
const SKILL_VERSION = '4.4.2';
const CLI_USER_AGENT = `trackly-cli/${PACKAGE_VERSION}`;

@@ -771,3 +771,12 @@ const MCP_USER_AGENT = `trackly-mcp/${PACKAGE_VERSION}`;

const accessibleExecutionCapability = protocol?.batchOrchestration?.accessibleExecution?.enabled;
const mcpContractCompatible = protocol?.mcpContractVersion === MCP_CONTRACT_VERSION
const compatibleMcpContractVersions = Array.isArray(protocol?.compatibleMcpContractVersions)
? protocol.compatibleMcpContractVersions.filter((value) => typeof value === 'string')
: [];
const preferredMcpContractVersion = typeof protocol?.preferredMcpContractVersion === 'string'
? protocol.preferredMcpContractVersion
: protocol?.mcpContractVersion;
const hasExplicitMcpCompatibilityWindow = compatibleMcpContractVersions.length > 0;
const mcpContractCompatible = (hasExplicitMcpCompatibilityWindow
? compatibleMcpContractVersions.includes(MCP_CONTRACT_VERSION)
: protocol?.mcpContractVersion === MCP_CONTRACT_VERSION)
|| (accessibleExecutionCapability === false && protocol?.mcpContractVersion === '3.4.0');

@@ -795,2 +804,4 @@ const cliMinimumSatisfied = minimumCliVersion

mcpContractVersion: MCP_CONTRACT_VERSION,
preferredMcpContractVersion,
compatibleMcpContractVersions,
mcpContractCompatible,

@@ -797,0 +808,0 @@ minimumCliVersion,

@@ -113,2 +113,11 @@ 'use strict';

if (
error?.status === 503
&& error?.error === 'application_profile_schema_pending'
&& error?.retryable === true
) {
payload.code = error.error;
payload.retryable = true;
}
if (error?.status === 429 && !payload.hint) {

@@ -115,0 +124,0 @@ payload.hint = 'Daily limit reached (20 natural language queries per day).';

{
"name": "trackly-cli",
"version": "0.13.2",
"version": "0.13.3",
"lockfileVersion": 3,

@@ -9,3 +9,3 @@ "requires": true,

"name": "trackly-cli",
"version": "0.13.2",
"version": "0.13.3",
"license": "MIT",

@@ -12,0 +12,0 @@ "dependencies": {

{
"name": "trackly-cli",
"version": "0.13.2",
"version": "0.13.3",
"mcpName": "io.github.trackly-app/trackly",

@@ -75,4 +75,6 @@ "description": "AI job search CLI + hosted MCP server with OAuth. 170K+ jobs, 3,800+ companies, 40+ ATS. Works with Claude, ChatGPT, Cursor, Windsurf, Codex via hosted streamable-http or local stdio.",

"overrides": {
"@hono/node-server": "2.0.12"
"@hono/node-server": "2.0.12",
"fast-uri": "3.1.5",
"ip-address": "10.4.0"
}
}

@@ -20,3 +20,3 @@ {

],
"version": "0.13.2",
"version": "0.13.3",
"packages": [

@@ -26,3 +26,3 @@ {

"identifier": "trackly-cli",
"version": "0.13.2",
"version": "0.13.3",
"runtimeHint": "npx",

@@ -29,0 +29,0 @@ "runtimeArguments": [

@@ -189,2 +189,23 @@ # Batch orchestration

### Fast path
Speed comes from bounded batching, not weaker verification:
- Fetch the compact execution snapshot once per stable wave and request only
fields needed by the visible forms. Do not repeatedly fetch the full profile
or ATS matrix after each control.
- Fill independent accessible tabs concurrently only when the browser adapter
supports it, but serialize mutations within each tab and preserve every
run/tab binding.
- Fill every known field before asking one consolidated question packet. After
the reply, use the one-write, one-refetch workflow in
[answer-compounding.md](answer-compounding.md).
- Keep dispositions, observations, checkpoints, certifications, and outcomes
in their bounded bulk operations. Do not replace a working bulk call with
per-member writes merely because it is easier to narrate.
- If a bulk mutation returns an ambiguous transport failure or HTTP 5xx, refetch
before splitting or retrying; never assume the request committed nothing.
- Do not spend browser calls on visibility or app-shell reveal attempts during
filling. Focus/reveal the exact bound tabs only at the verified handoff.
### Request budget

@@ -191,0 +212,0 @@

@@ -158,2 +158,15 @@ # Browser lifecycle and recovery

Do not call `open_in_codex`, open a new app-shell page, or create a replacement
tab merely to reveal an already-bound application. Such calls can create blank
or duplicate tabs without presenting the real form. Use only the adapter's
exact-tab focus/reveal primitive when it returns a current tab-bound visibility
receipt. If no such primitive exists, preserve the bound tab and report
visibility as unverified.
Controller inventory is not the complete app-shell or user-visible inventory
unless the adapter explicitly declares it complete. Never say “only these tabs
remain,” “the blank tabs are gone,” or equivalent based on controller inventory
alone. When the user reports or shows an extra tab, treat that as positive
evidence, reconcile every available surface, and correct the claim.
If the selected path can provide neither its required reachability proof nor

@@ -160,0 +173,0 @@ an exact visibility receipt, preserve the tab but say that visibility is

@@ -28,2 +28,5 @@ # Review handoff

Trackly saved the verification state. The employer's live draft still exists
only in the open browser tab and may be lost if that tab is closed or reloaded.
Company / role:

@@ -82,2 +85,7 @@ ATS / URL:

Use plain language around that funnel. Label `durablyReviewReady` as “verified
and waiting for your manual submission,” while retaining the exact server key
only in the authoritative count line. Never imply that Trackly stored the ATS
form contents or can recreate the employer draft.
## Grouped actions

@@ -84,0 +92,0 @@

@@ -30,3 +30,3 @@ ---

1. Call `trackly_get_apply_protocol`. Skill 4.4.1 requires protocol 3.5.0 or newer for new reliability work. Protocol 3.2 remains valid only for an already-active explicit legacy single run; an already-active explicit 3.2 single run may finish through its legacy path. Preserve the protocol's documented recovery paths for already-active older work. Require `compatibleSkillMajor: 4` and `compatibleSkillMinimumVersion` no newer than this installed skill. Reject an older or incompatible version for new work and report that the backend must finish updating or `trackly agent setup` must update the skill. Protocol 3.2 added exact-origin trust for jobs Trackly ingested directly from employer careers sources; do not recreate the retired ownership-timestamp gate in the client.
1. Call `trackly_get_apply_protocol`. Skill 4.4.2 requires protocol 3.5.0 or newer for new reliability work. Protocol 3.2 remains valid only for an already-active explicit legacy single run; an already-active explicit 3.2 single run may finish through its legacy path. Preserve the protocol's documented recovery paths for already-active older work. Require `compatibleSkillMajor: 4` and `compatibleSkillMinimumVersion` no newer than this installed skill. Reject an older or incompatible version for new work and report that the backend must finish updating or `trackly agent setup` must update the skill. Protocol 3.2 added exact-origin trust for jobs Trackly ingested directly from employer careers sources; do not recreate the retired ownership-timestamp gate in the client.
2. Call `trackly_get_profile_onboarding` or fetch both the profile schema and application profile. When present, render `schema.screens` in ascending `order` as one grouped question packet per screen. Within a screen, preserve category `order` and then field `order`; use each field's user-facing `rationale` when the user asks why it is needed. Ask only unknown or confirmation-needed fields and honor `consistencyRules` before submitting profile changes, resolving contradictions with the user instead of guessing. When `schema.screens` is absent on a legacy backend, fall back to the existing category-based onboarding behavior. Treat `completeness.percent` as required onboarding readiness only. Use `coverage.missingReusableKeys` to explain reusable optional gaps, while `coverage.contextualKeys` are intentionally asked only on the relevant employer form. Do not claim that 100% required completeness answers every possible application question.

@@ -73,3 +73,3 @@ 3. Save answers with `trackly_update_application_profile`:

- If a bound start returns a transport failure, a non-access HTTP 5xx response, or an error explicitly marked `retryable: true`, preserve the frozen member and browser state. Refetch the active batch, renew its lease, and retry the same complete binding once. Classify the retry response independently with these same rules: route canonical `maintenance_mode` or legacy `planned_maintenance` directly through **Resume after maintenance**; surface controlled-access/request errors marked `retryable: false` and every other HTTP 4xx response unchanged; only a second transport failure, non-access HTTP 5xx response, or explicitly retryable error becomes `backend_run_start_unavailable`. Route maintenance on either attempt without consuming or relabeling the retry, and never relabel a permanent retry response as an outage. For `backend_run_start_unavailable`, continue other members and report a Trackly control-plane failure. Do not call `trackly_checkpoint_apply_batch` for this condition because start failure has not produced the required run ID. The unchanged frozen member is the durable resume point. Never switch that frozen member to an unbound legacy run or blame the employer form.
- Require `run.protocolVersion` to be 3.1.0 or newer and to share protocol major 3 with the fetched protocol. A new reliability execution member requires 3.5.0 or newer; already-active older work may use only the recovery path published by its fetched protocol. Never continue a pre-evidence 3.0.x run under skill 4.4.1. Preserve that run instead of starting a replacement, record it `blocked` with a value-free protocol-upgrade reason when possible, and tell the user the saved job can be retried only after the stale run is cleared through Trackly's supported lifecycle. Stop and refetch the protocol and active execution or batch if support level, execution mode, provider, required scenarios, authorized origin policy, member version, or inspection epoch changes after run creation.
- Require `run.protocolVersion` to be 3.1.0 or newer and to share protocol major 3 with the fetched protocol. A new reliability execution member requires 3.5.0 or newer; already-active older work may use only the recovery path published by its fetched protocol. Never continue a pre-evidence 3.0.x run under skill 4.4.2. Preserve that run instead of starting a replacement, record it `blocked` with a value-free protocol-upgrade reason when possible, and tell the user the saved job can be retried only after the stale run is cleared through Trackly's supported lifecycle. Stop and refetch the protocol and active execution or batch if support level, execution mode, provider, required scenarios, authorized origin policy, member version, or inspection epoch changes after run creation.
- In guided mode, inspect the page before preparing any resume bytes. Confirm the employer, role, HTTPS origin, reachable review path, semantic controls, whether an attachment control exists, and absence of a credential, verification, CAPTCHA, or submit-only wall. A missing file input is not itself a blocker; skip the resume path when the application has no attachment control. Any other failed precondition is an execution blocker, not permission to improvise.

@@ -129,3 +129,3 @@ 7. Pass the browser readiness gate before preparing resume bytes:

When the user corrects an answer, immediately save the appropriate scope with `trackly_update_application_profile` and report only a redacted mechanics observation. For a frozen batch, collect current-epoch evidence locally and send it through `trackly_report_apply_observations` in one bounded bulk call; use `trackly_report_apply_observation` only for a legacy single run or an isolated follow-up. For every protocol 3.3 observation, include the exact current `batchId`, `memberId`, and `inspectionEpoch`; stale-epoch evidence must fail closed and be recreated only after reclaiming the current surface. Never promote one user’s value into a global default. For `generic_web_form`, never save provider-scoped answers; use company scope for form-specific answers.
When the user supplies, corrects, or confirms one or more reusable answers, read [references/answer-compounding.md](references/answer-compounding.md). Audit every answer against the live schema and targeted contextual profile, then perform at most one bulk `trackly_update_application_profile` call and one verification refetch for the packet. Before truth certification or review handoff, show the required redacted answer-sync receipt covering every supplied answer as `saved`, `already_matched`, `schema_missing`, or `run_only_contextual`. Never call an existing canonical value a schema gap merely because a compact snapshot omitted contextual data. For a frozen batch, collect current-epoch evidence locally and send it through `trackly_report_apply_observations` in one bounded bulk call; use `trackly_report_apply_observation` only for a legacy single run or an isolated follow-up. For every protocol 3.3 observation, include the exact current `batchId`, `memberId`, and `inspectionEpoch`; stale-epoch evidence must fail closed and be recreated only after reclaiming the current surface. Never promote one user’s value into a global default. For `generic_web_form`, never save provider-scoped answers; use company scope for form-specific answers.

@@ -132,0 +132,0 @@ For every run, track only scenarios actually exercised, except the two universal review proofs below. Attest `browser_reclaim` once with the same-run `observationType: browser_ready`, exact binding hash, browser surface, and `metadata.committed: true`; do not send a duplicate `scenario_coverage` row for it. Before `review_ready`, report every other exercised scenario with `observationType: scenario_coverage`, the stable scenario code, browser surface, `metadata.committed: true` for `passed` or `corrected`, and whether the tab was resumed after handoff.

Sorry, the diff of this file is too big to display