hirify-cli 0.6.1 → 0.6.2
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/bin/lib/commands.js +10 -2
- package/bin/lib/setup.js +15 -9
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/bin/lib/commands.js
CHANGED
|
@@ -204,6 +204,14 @@ function detailRows(pairs) {
|
|
|
204
204
|
.map(([label, text]) => `${(label + ':').padEnd(10)}${text}`)
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
/**
|
|
208
|
+
* The word that names a vacancy, offered under both names a manifest may use for the path
|
|
209
|
+
* slot. Hirify moved vacancies.read and vacancies.reveal from `{slug}` to `{vacancy_id}` on
|
|
210
|
+
* 2026-09-30 and reads a non-numeric value in that slot as the slug, so one set of params
|
|
211
|
+
* serves the old manifest, the new one, a slug and a numeric id alike.
|
|
212
|
+
*/
|
|
213
|
+
const vacancyRef = (word) => ({ slug: word, vacancy_id: word })
|
|
214
|
+
|
|
207
215
|
/**
|
|
208
216
|
* One vacancy in full, with the text a person reads on the site. This is the command an
|
|
209
217
|
* agent shortlists with, so it is deliberately the cheap one: it counts against the day's
|
|
@@ -218,7 +226,7 @@ async function cmdVacancyRead(args, words) {
|
|
|
218
226
|
'\n Slugs come from hirify vacancy search or hirify feed show.')
|
|
219
227
|
}
|
|
220
228
|
|
|
221
|
-
const res = await callCapability('vacancies.read', { params:
|
|
229
|
+
const res = await callCapability('vacancies.read', { params: vacancyRef(slug), allow: [200, 404] })
|
|
222
230
|
if (res.status === 404) die('there is no vacancy with that slug.')
|
|
223
231
|
|
|
224
232
|
const d = res.body?.data ?? {}
|
|
@@ -276,7 +284,7 @@ function contactLine(c) {
|
|
|
276
284
|
async function cmdVacancyReveal(args, words) {
|
|
277
285
|
const [slug] = words
|
|
278
286
|
if (!slug) die('a vacancy slug is required: hirify vacancy reveal <slug>')
|
|
279
|
-
const body = await callCapability('vacancies.reveal', { params:
|
|
287
|
+
const body = await callCapability('vacancies.reveal', { params: vacancyRef(slug) })
|
|
280
288
|
const d = body?.data ?? {}
|
|
281
289
|
out(body, () => {
|
|
282
290
|
console.log(`company: ${d.company ?? '-'}`)
|
package/bin/lib/setup.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, cpSync, rmSync, symlinkSync, realpathSync, readFileSync } from 'node:fs'
|
|
2
2
|
import { homedir } from 'node:os'
|
|
3
|
-
import { join, relative } from 'node:path'
|
|
3
|
+
import { dirname, join, relative } from 'node:path'
|
|
4
4
|
import semver from 'semver'
|
|
5
5
|
import { CliError } from './errors.js'
|
|
6
6
|
import { PACKAGE_NAME, runProcess } from './update.js'
|
|
@@ -31,12 +31,19 @@ const remove = path => rmSync(path, { recursive: true, force: true })
|
|
|
31
31
|
// OS messages may carry private paths, so only the code is reported.
|
|
32
32
|
const reason = error => ['EACCES', 'EPERM', 'EROFS', 'ENOSPC', 'EDQUOT', 'ENOTDIR', 'ENOENT', 'EEXIST', 'ELOOP'].includes(error?.code) ? error.code : 'unknown'
|
|
33
33
|
|
|
34
|
+
// A junction needs no elevated rights on Windows; elsewhere the link stays relative.
|
|
35
|
+
const linkSkill = (path, target, platform) => (platform === 'win32'
|
|
36
|
+
? symlinkSync(realpathSync(path), target, 'junction')
|
|
37
|
+
: symlinkSync(relative(dirname(target), realpathSync(path)), target, 'dir'))
|
|
38
|
+
|
|
34
39
|
/**
|
|
35
40
|
* Install the skill carried by this package: one shared copy under `~/.agents/skills`, linked into
|
|
36
41
|
* every agent found here. The skill comes from the package of the CLI it is for, so the two match.
|
|
37
|
-
* An agent that cannot be written to is reported and does not stop the others.
|
|
42
|
+
* An agent that cannot be written to is reported and does not stop the others. An agent that
|
|
43
|
+
* cannot take a link gets a copy, and the result says so: a copy does not follow the shared one
|
|
44
|
+
* when the CLI updates, so the person knows to run `hirify skill` again.
|
|
38
45
|
*/
|
|
39
|
-
export function installSkill({ packageRoot, env = process.env, home = homedir(), platform = process.platform } = {}) {
|
|
46
|
+
export function installSkill({ packageRoot, env = process.env, home = homedir(), platform = process.platform, link = linkSkill } = {}) {
|
|
40
47
|
const source = join(packageRoot, 'skills', SKILL_NAME)
|
|
41
48
|
if (!existsSync(join(source, 'SKILL.md'))) throw new CliError('skill_missing', 'This installation does not carry the skill. Install it with: npx skills add hirifyme/hirify-cli')
|
|
42
49
|
const shared = join(home, '.agents', 'skills')
|
|
@@ -56,12 +63,9 @@ export function installSkill({ packageRoot, env = process.env, home = homedir(),
|
|
|
56
63
|
if (parent === realpathSync(shared)) { agents.push({ agent: agent.name, installed: true }); continue }
|
|
57
64
|
const target = join(parent, SKILL_NAME)
|
|
58
65
|
remove(target)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
else symlinkSync(relative(parent, realpathSync(path)), target, 'dir')
|
|
63
|
-
} catch { cpSync(source, target, { recursive: true }) }
|
|
64
|
-
agents.push({ agent: agent.name, installed: true })
|
|
66
|
+
let copied = false
|
|
67
|
+
try { link(path, target, platform) } catch { cpSync(source, target, { recursive: true }); copied = true }
|
|
68
|
+
agents.push(copied ? { agent: agent.name, installed: true, copied: true } : { agent: agent.name, installed: true })
|
|
65
69
|
} catch (error) { agents.push({ agent: agent.name, installed: false, reason: reason(error) }) }
|
|
66
70
|
}
|
|
67
71
|
return { skill: SKILL_NAME, path, agents }
|
|
@@ -104,5 +108,7 @@ export function describeSkill(result) {
|
|
|
104
108
|
const failed = result.agents.filter(item => !item.installed).map(item => `${item.agent} (${item.reason})`)
|
|
105
109
|
const lines = [done.length ? `The skill is installed for ${done.join(', ')}.` : `The skill is saved in ${result.path}. No supported agent was found on this computer.`]
|
|
106
110
|
if (failed.length) lines.push(`It could not be installed for ${failed.join(', ')}. Check that the agent's skills directory is a folder you can write to, then run hirify skill.`)
|
|
111
|
+
const copies = result.agents.filter(item => item.copied).map(item => item.agent)
|
|
112
|
+
if (copies.length) lines.push(`For ${copies.join(', ')} the skill is a copy, not a link: after the CLI updates, run hirify skill to refresh it.`)
|
|
107
113
|
return lines
|
|
108
114
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hirify-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "hirify-cli",
|
|
9
|
-
"version": "0.6.
|
|
9
|
+
"version": "0.6.2",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"cross-spawn": "7.0.6",
|
package/package.json
CHANGED