hirify-cli 0.4.5 → 0.4.6

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 CHANGED
@@ -55,6 +55,9 @@ values are available. It comes from the server, so it stays current as search ch
55
55
  requires a compact preview before the final search, so the agent can correct an empty or irrelevant
56
56
  filter before relying on it.
57
57
 
58
+ New saved searches start with delivery off. Enable Telegram explicitly with
59
+ `hirify feed deliver <id> --telegram` after the user approves notifications.
60
+
58
61
  Add `--json` to any command for the server's answer as JSON instead of the text a person reads.
59
62
  `--fields a,b` narrows a compact answer to the fields you name. Put `HIRIFY_DEBUG=1` in front of a
60
63
  command when you need the server's own reply to attach to a bug report.
package/bin/hirify.js CHANGED
@@ -81,8 +81,8 @@ const HELP = `hirify - job search for AI agents
81
81
 
82
82
  hirify feed list the feeds you saved on the site
83
83
  hirify feed show <id> vacancies from one feed [--limit N] [--page N]
84
- hirify feed create <name> save a search [--filters JSON] [--webhook N]
85
- hirify feed deliver <id> change how a feed reaches you
84
+ hirify feed create <name> save a search [--filters JSON] [--telegram] [--webhook N]
85
+ hirify feed deliver <id> change delivery [--telegram|--no-telegram] [--webhook N|--no-webhook]
86
86
 
87
87
  hirify profile list the profiles you can apply with
88
88
  hirify webhook list your delivery endpoints
@@ -295,7 +295,26 @@ function printNotice(notice) {
295
295
 
296
296
  // Text our own server wrote for the agent to read: application rules, address rejections.
297
297
  // Passing it through beats paraphrasing, because paraphrasing drifts from the real rule.
298
- const serverMessage = (body) => (typeof body?.message === 'string' && body.message ? body.message : null)
298
+ function serverMessage(body) {
299
+ const firstLine = (value) => {
300
+ if (typeof value === 'string' && value.trim()) return value.trim()
301
+ if (Array.isArray(value)) {
302
+ for (const item of value) {
303
+ const line = firstLine(item)
304
+ if (line) return line
305
+ }
306
+ }
307
+ if (value && typeof value === 'object') {
308
+ for (const item of Object.values(value)) {
309
+ const line = firstLine(item)
310
+ if (line) return line
311
+ }
312
+ }
313
+ return null
314
+ }
315
+
316
+ return firstLine(body?.error?.details) || firstLine(body?.error?.message) || firstLine(body?.message)
317
+ }
299
318
 
300
319
  /**
301
320
  * The one-line report for a policy restriction: a canonical 403 that names itself
@@ -1429,7 +1448,7 @@ async function cmdFeedCreate(args, words) {
1429
1448
  }
1430
1449
  }
1431
1450
 
1432
- const payload = { name, filters }
1451
+ const payload = { name, filters, notify_telegram: false }
1433
1452
  if (args.includes('--no-telegram')) payload.notify_telegram = false
1434
1453
  if (args.includes('--telegram')) payload.notify_telegram = true
1435
1454
  const webhook = flag(args, '--webhook')
@@ -1441,13 +1460,19 @@ async function cmdFeedCreate(args, words) {
1441
1460
  const res = await callCapability('feeds.create', { payload, allow: [201, 422] })
1442
1461
  if (res.status === 422) die(serverMessage(res.body) || 'the feed was not created. Please check the criteria.')
1443
1462
 
1444
- out(res.body, () => printFeedState(res.body?.data ?? {}, 'Saved.'))
1463
+ out(res.body, () => {
1464
+ const feed = res.body?.data ?? {}
1465
+ printFeedState(feed, 'Saved.')
1466
+ if (!feed.notify_telegram && !feed.webhook_endpoint_id) {
1467
+ console.log(`To receive new matches in Telegram: hirify feed deliver ${feed.id ?? '<id>'} --telegram`)
1468
+ }
1469
+ })
1445
1470
  }
1446
1471
 
1447
1472
  /** Change where a feed is delivered, without touching what it searches for. */
1448
1473
  async function cmdFeedDeliver(args, words) {
1449
1474
  const [id] = words
1450
- if (!id || !/^\d+$/.test(id)) die('a feed id is required: hirify feed deliver <id> [--telegram] [--webhook <id>]')
1475
+ if (!id || !/^\d+$/.test(id)) die('a feed id is required: hirify feed deliver <id> [--telegram|--no-telegram] [--webhook <id>|--no-webhook]')
1451
1476
 
1452
1477
  const payload = {}
1453
1478
  if (args.includes('--telegram')) payload.notify_telegram = true
@@ -1475,7 +1500,7 @@ function printFeedState(f, lead) {
1475
1500
  f.webhook_endpoint_id ? `webhook ${f.webhook_endpoint_id}` : null,
1476
1501
  ].filter(Boolean)
1477
1502
  console.log(`${lead} Feed ${f.id ?? '-'}: ${f.name || '(untitled)'}`)
1478
- console.log(where.length ? `Delivered to: ${where.join(' and ')}` : 'Not delivered anywhere yet.')
1503
+ console.log(where.length ? `Delivered to: ${where.join(' and ')}` : 'Delivery is off.')
1479
1504
  }
1480
1505
 
1481
1506
  /** The delivery endpoints on the account. Free; creating one needs the plan. */
@@ -1803,7 +1828,7 @@ async function cmdFilterGuide() {
1803
1828
  ' their names have to come from someone who knows them.')
1804
1829
  }
1805
1830
 
1806
- const guide = typeof res.body?.guide === 'string' ? res.body.guide.trim() : ''
1831
+ const guide = typeof res.body?.data?.guide === 'string' ? res.body.data.guide.trim() : ''
1807
1832
  if (!guide) die('the server answered without a guide. Please try again in a minute.')
1808
1833
 
1809
1834
  out(res.body, () => console.log(guide))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hirify-cli",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "Hirify CLI for AI agents: browser sign-in, job feeds, search, reading a vacancy in full, contacts to apply to, and applying on Hirify.",
5
5
  "bin": {
6
6
  "hirify": "bin/hirify.js"
@@ -8,6 +8,14 @@ description: Job search through Hirify - vacancies from the user's saved feeds,
8
8
  Use the Hirify job board through the `hirify` CLI. This file gives the working order; `reference.md`
9
9
  has every command in full, and `hirify intro` is the server's guide.
10
10
 
11
+ ## Setup
12
+
13
+ The CLI is the npm package `hirify-cli`; the command is `hirify`. It needs Node 18 or newer and
14
+ network access to api.hirify.me. If `hirify` is not on PATH, run every command in this file as
15
+ `npx -y hirify-cli <command>` instead: the same CLI, nothing installed. `npm install -g hirify-cli`
16
+ puts `hirify` on PATH for good and keeps itself up to date; offer it, and run it only after the user
17
+ says yes.
18
+
11
19
  ## What stays here, and what you fetch
12
20
 
13
21
  This installed file holds only stable rules. Fetch anything Hirify can change:
@@ -90,7 +98,8 @@ Two cases, two commands:
90
98
 
91
99
  ## Saved searches and delivery
92
100
 
93
- These change the user's account, so the same rule holds: propose, get a yes, then do it.
101
+ These commands change the user's account, so get a yes. Creation leaves delivery off: report that,
102
+ offer the exact `feed deliver` command, and run it only after a separate yes.
94
103
 
95
104
  ```bash
96
105
  hirify feed create "<name>" --filters '<json>' # criteria: hirify filter guide
@@ -99,7 +108,7 @@ hirify webhook list
99
108
  hirify webhook create "<name>" <url>
100
109
  ```
101
110
 
102
- `--filters` takes the same criteria as the site's filter form; read `hirify filter guide` first.
111
+ `--filters` uses the site's filter criteria; read `hirify filter guide` first.
103
112
  Creating a delivery endpoint returns a **secret shown once**: give it to the user immediately to
104
113
  store, because it signs every delivery and cannot be shown again.
105
114
 
@@ -114,6 +123,9 @@ gives a ticket number or says there is none yet, nothing writes back, and no fix
114
123
  **The message you were given is the truth; this is a map of the kinds, not strings to match.** Every
115
124
  failure exits non-zero and writes one line to stderr. Read that line and tell the user what it says.
116
125
 
126
+ - **`hirify: command not found`**: run the command as `npx -y hirify-cli <command>`; see Setup.
127
+ - **"the network seems to be unavailable"**: api.hirify.me is unreachable. Sandboxed agents often run
128
+ with network off (Codex CLI does by default); ask the user to allow it for the session, then retry.
117
129
  - **Not signed in**: ask the user to run `hirify login` (it opens a browser and needs a person -
118
130
  never run it yourself). On a server with no browser: `hirify auth <key>`, key from
119
131
  hirify.me/account/api-access.
@@ -6,6 +6,9 @@ Commands are a noun and a verb: the noun is the thing you are working with, the
6
6
  to it. `hirify <noun>` on its own lists the verbs that noun takes. `login`, `logout`, `auth` and
7
7
  `intro` stay single words: they are not operations on a thing.
8
8
 
9
+ The CLI is the npm package `hirify-cli`. Every command below is written as `hirify ...`; when `hirify`
10
+ is not on PATH, run it as `npx -y hirify-cli ...` instead (see Setup in `SKILL.md`).
11
+
9
12
  **This file describes the CLI, not the state of Hirify.** It is installed with the skill and never
10
13
  updated afterwards, so it names no filter, no limit and no number that our side can change. Those
11
14
  come from commands: `hirify filter guide` for filters, `hirify account show` for what is left,
@@ -212,11 +215,15 @@ hirify webhook list
212
215
  hirify webhook create "<name>" <url>
213
216
  ```
214
217
 
215
- These change the user's account. Propose, get a yes, then run them.
218
+ These change the user's account. Propose, get a yes, then run them. A new saved search has delivery
219
+ off by default. Enabling Telegram or a webhook is a separate account change and needs a separate
220
+ yes, even when creating the search was already approved.
216
221
 
217
222
  `--filters` takes the same criteria the site's filter form produces, as JSON, and the names come
218
223
  from `hirify filter guide`. Omitting it saves a feed with no criteria, which means "send me
219
224
  everything" and is legal.
225
+ After creation, report that delivery is off and show the exact `feed deliver` command. Run that
226
+ command only after the user approves delivery.
220
227
 
221
228
  `webhook create` answers with the endpoint and a **secret shown once**. Hand it to the user
222
229
  immediately and tell them to store it: it signs every delivery and cannot be shown again.