hirify-cli 0.6.3 → 0.6.5
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/cli.js +1 -1
- package/bin/lib/commands.js +12 -80
- package/bin/lib/main.js +1 -0
- package/bin/lib/setup.js +35 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/skills/hirify/SKILL.md +25 -77
package/bin/lib/cli.js
CHANGED
|
@@ -103,7 +103,7 @@ export function parse(argv) {
|
|
|
103
103
|
}
|
|
104
104
|
export function help(topic = '') {
|
|
105
105
|
const entries = Object.entries(COMMANDS).filter(([name]) => !topic || name === topic || name.startsWith(topic + ' '))
|
|
106
|
-
return `hirify - job search for AI agents\n\n${(entries.length ? entries : Object.entries(COMMANDS)).map(([name, spec]) => ` hirify ${(name + (ARGUMENTS[name] ? ' ' + ARGUMENTS[name] : '')).padEnd(35)} ${spec.description}${spec.flags?.length ? `\n ${spec.flags.map(f => '--' + f + (BOOLEAN_FLAGS.has(f) ? '' : ' <value>')).join(' ')}` : ''}`).join('\n')}\n\nGlobal options: --json, --fields a,b, --error-format json|text, --timeout <seconds>, --debug, --help.\nUse -- to end options; --name=value and --name value are supported.\
|
|
106
|
+
return `hirify - job search for AI agents\n\n${(entries.length ? entries : Object.entries(COMMANDS)).map(([name, spec]) => ` hirify ${(name + (ARGUMENTS[name] ? ' ' + ARGUMENTS[name] : '')).padEnd(35)} ${spec.description}${spec.flags?.length ? `\n ${spec.flags.map(f => '--' + f + (BOOLEAN_FLAGS.has(f) ? '' : ' <value>')).join(' ')}` : ''}`).join('\n')}\n\nGlobal options: --json, --fields a,b, --error-format json|text, --timeout <seconds>, --debug, --help.\nUse -- to end options; --name=value and --name value are supported.\nStart with hirify intro: the working method, kept current by Hirify.\nAllowances: hirify account show. Apply sends a real application: ask your user first.\nLocal agents reuse saved sign-in when allowed. Token renewal needs write access.\nSandbox access denied: request permission for the command; do not copy tokens.\nHeadless/CI: HIRIFY_KEY or hirify auth --stdin. Manual login: --no-browser.\nSSH: forward the chosen --callback-port to the same loopback port on the CLI host.\nSet up the CLI, the skill and sign-in: hirify init. The skill alone: hirify skill\n`
|
|
107
107
|
}
|
|
108
108
|
export function createOutput({ stdout = process.stdout, stderr = process.stderr, json = false, errorJSON = false, secrets = new Set() } = {}) {
|
|
109
109
|
let closed = false
|
package/bin/lib/commands.js
CHANGED
|
@@ -110,6 +110,8 @@ function printVacancies(list, meta) {
|
|
|
110
110
|
? true
|
|
111
111
|
: perPage !== null && list.length >= perPage
|
|
112
112
|
if (more && page !== null) console.log(`More: add --page ${page + 1}`)
|
|
113
|
+
// Paging is fine; a list this long usually means the criteria do not yet describe the user.
|
|
114
|
+
if (lastPage !== null && lastPage > 3) console.log(`${total ?? 'Many'} vacancies over ${lastPage} pages: narrower criteria usually give a list worth reading in full.`)
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
/** The vacancies in one saved feed, using the criteria the feed already holds. */
|
|
@@ -619,94 +621,24 @@ async function cmdWebhookCreate(args, words) {
|
|
|
619
621
|
|
|
620
622
|
const INTRO = `hirify - job search for AI agents
|
|
621
623
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
+
This is the built-in text: Hirify did not return the playbook. The working method (interviewing your
|
|
625
|
+
user, setting up the search, going through the results, judging a vacancy, applying) is the Hirify
|
|
626
|
+
playbook, kept current on the server: https://hirify.me/agent-playbook.txt. Run hirify intro again
|
|
627
|
+
when Hirify is reachable.
|
|
624
628
|
|
|
625
629
|
Setting up
|
|
626
630
|
npx -y hirify-cli@latest init installs this CLI and the agent's skill, then opens sign-in.
|
|
627
631
|
|
|
628
632
|
Signing in
|
|
629
|
-
hirify login prints a link and tries the browser when available.
|
|
633
|
+
hirify login prints a link and tries the browser when available. Your user confirms access.
|
|
630
634
|
Manual sign-in: hirify login --no-browser. For automation, use HIRIFY_KEY or hirify auth --stdin; get a key at
|
|
631
635
|
hirify.me/account/api-access.
|
|
632
636
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
hirify feed list what this account has saved
|
|
639
|
-
hirify feed show 31 the vacancies in one of them
|
|
640
|
-
|
|
641
|
-
When no feed fits, search the whole board. Search takes a phrase, and any criterion the
|
|
642
|
-
site's own filter form can express, written as an option:
|
|
643
|
-
|
|
644
|
-
hirify vacancy search "senior go"
|
|
645
|
-
hirify vacancy search "senior go" --page 2
|
|
646
|
-
hirify vacancy search "senior go" --<criterion> <value>
|
|
647
|
-
|
|
648
|
-
The criteria are the server's, not this CLI's, and nothing here names one on purpose: a
|
|
649
|
-
name written into this text would be a copy, and copies go stale quietly. Ask instead:
|
|
650
|
-
|
|
651
|
-
hirify filter guide
|
|
652
|
-
|
|
653
|
-
It prints what search can filter on and what the values are, written by the server from
|
|
654
|
-
the same source the site searches with. An option is sent on under the name you gave it;
|
|
655
|
-
give one twice and the values are joined, the way the site sends a filter with several
|
|
656
|
-
values.
|
|
657
|
-
|
|
658
|
-
Read before you spend anything
|
|
659
|
-
A card is a headline: title, company, terms. Fit is decided in the text.
|
|
660
|
-
|
|
661
|
-
hirify vacancy read senior-go-engineer
|
|
662
|
-
|
|
663
|
-
This prints the whole vacancy, and it also says which of the two ways to apply this one
|
|
664
|
-
takes, so you do not have to work that out or find out from a refusal.
|
|
665
|
-
|
|
666
|
-
What costs what
|
|
667
|
-
Lists and searches are free.
|
|
668
|
-
Reading one vacancy in full spends one of the Agent API's daily vacancy opens. There are
|
|
669
|
-
many of them, and reading a vacancy again the same day costs nothing. Read as much as you
|
|
670
|
-
need to.
|
|
671
|
-
Revealing where to apply spends 1 reveal, and reveals are the scarce one. Protect that
|
|
672
|
-
number: shortlist by reading, then reveal only the ones worth applying to.
|
|
673
|
-
Applying has a daily allowance of its own. It is not the free step it looks like.
|
|
674
|
-
hirify account show has all three, and it is the only place they are current.
|
|
675
|
-
|
|
676
|
-
Where to apply
|
|
677
|
-
hirify vacancy reveal senior-go-engineer
|
|
678
|
-
|
|
679
|
-
Gives the company, its LinkedIn page when we know it, and the address to send the
|
|
680
|
-
application to. Revealing the same vacancy again returns the same thing and costs nothing.
|
|
681
|
-
|
|
682
|
-
Applying
|
|
683
|
-
Most vacancies here came from somewhere else: company pages, Telegram channels, other
|
|
684
|
-
boards. For those, reveal brings back the address, and the application is made there rather
|
|
685
|
-
than through Hirify.
|
|
686
|
-
Vacancies hosted on Hirify can be applied to from here:
|
|
687
|
-
|
|
688
|
-
hirify profile list
|
|
689
|
-
hirify vacancy apply senior-go-engineer --profile 4 --cover "..."
|
|
690
|
-
|
|
691
|
-
An application reaches a real person and cannot be recalled. Ask first, every time, and
|
|
692
|
-
show what you are about to send. Nothing follows up afterwards: the recruiter replies
|
|
693
|
-
where they choose to.
|
|
694
|
-
|
|
695
|
-
Two more things
|
|
696
|
-
A saved search can be created from here and delivered to Telegram or to a server of yours:
|
|
697
|
-
hirify feed create, hirify feed deliver, hirify webhook list.
|
|
698
|
-
Something broken or missing: hirify feedback send bug "<title>" --body "<what happened>". It
|
|
699
|
-
reaches the team and costs nothing.
|
|
700
|
-
|
|
701
|
-
If a command you need is not here
|
|
702
|
-
hirify api call <capability> invokes any capability Hirify lists in its manifest and prints
|
|
703
|
-
the answer as it comes back, so a capability without its own command is a detour and not a
|
|
704
|
-
dead end. Inputs go in --data as a JSON object. Prefer the commands above where one fits:
|
|
705
|
-
they say what a thing costs and what a refusal means, and this one cannot.
|
|
706
|
-
|
|
707
|
-
If you are an agent
|
|
708
|
-
Install the working rules once: hirify skill. They cover the order
|
|
709
|
-
above, what needs the person's permission before you do it, and what each refusal means.
|
|
637
|
+
Commands
|
|
638
|
+
hirify account show, hirify feed list, hirify vacancy search, hirify vacancy read,
|
|
639
|
+
hirify vacancy reveal, hirify vacancy apply, hirify filter guide. Anything else:
|
|
640
|
+
hirify api call <capability>. An application reaches a real person and cannot be recalled:
|
|
641
|
+
ask your user first.
|
|
710
642
|
|
|
711
643
|
Use --json for structured results and --error-format=json for structured errors.
|
|
712
644
|
The full list of commands: hirify --help`
|
package/bin/lib/main.js
CHANGED
|
@@ -56,6 +56,7 @@ export async function main(argv = process.argv.slice(2), { baseRoot = ownRoot, b
|
|
|
56
56
|
const api = createApi({ config, http, auth, output })
|
|
57
57
|
const updater = createUpdater({ config, http, signal, output, event, packageRoot: ownRoot, baseRoot, baseVersion })
|
|
58
58
|
const local = ['auth', 'auth status', 'logout', 'doctor', 'init', 'skill', 'update'].includes(command.name)
|
|
59
|
+
if (!['init', 'skill'].includes(command.name)) { const { refreshSkill } = await import('./setup.js'); refreshSkill({ packageRoot: ownRoot, env: config.env }) }
|
|
59
60
|
if (!skipUpdate && !local) next = await updater.automatic()
|
|
60
61
|
if (next) {
|
|
61
62
|
// Dispose every timer and signal handler before handing off, at most once per invocation.
|
package/bin/lib/setup.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, cpSync, rmSync, symlinkSync, realpathSync, readFileSync } from 'node:fs'
|
|
1
|
+
import { existsSync, mkdirSync, cpSync, rmSync, symlinkSync, realpathSync, readFileSync, writeFileSync, lstatSync } from 'node:fs'
|
|
2
2
|
import { homedir } from 'node:os'
|
|
3
3
|
import { dirname, join, relative } from 'node:path'
|
|
4
4
|
import semver from 'semver'
|
|
@@ -52,6 +52,7 @@ export function installSkill({ packageRoot, env = process.env, home = homedir(),
|
|
|
52
52
|
mkdirSync(shared, { recursive: true })
|
|
53
53
|
remove(path)
|
|
54
54
|
cpSync(source, path, { recursive: true })
|
|
55
|
+
markVersion(path, packageRoot)
|
|
55
56
|
} catch (error) { throw new CliError('skill_install_failed', `Could not save the skill (${reason(error)}). This command needs write access to the home directory.`) }
|
|
56
57
|
const agents = []
|
|
57
58
|
for (const agent of agentDirectories({ env, home })) {
|
|
@@ -71,6 +72,39 @@ export function installSkill({ packageRoot, env = process.env, home = homedir(),
|
|
|
71
72
|
return { skill: SKILL_NAME, path, agents }
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
// Which CLI release the installed skill came from, so a newer CLI knows to refresh it.
|
|
76
|
+
const VERSION_MARK = '.hirify-cli-version'
|
|
77
|
+
const packageVersion = root => { try { return JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version } catch { return null } }
|
|
78
|
+
function markVersion(path, packageRoot) { const version = packageVersion(packageRoot); if (version) writeFileSync(join(path, VERSION_MARK), version + '\n') }
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Refresh a skill this CLI installed earlier, when the running CLI is newer than the release it
|
|
82
|
+
* came from: an auto-updated CLI brings its skill along, so the working rules on the computer
|
|
83
|
+
* never lag behind the CLI. Only an existing installation is touched - nothing is installed where
|
|
84
|
+
* there was none - and an older CLI never rolls a newer skill back. Agents that got a copy rather
|
|
85
|
+
* than a link get their copy refreshed too. Best effort: any failure leaves things as they were.
|
|
86
|
+
*/
|
|
87
|
+
export function refreshSkill({ packageRoot, env = process.env, home = homedir() } = {}) {
|
|
88
|
+
try {
|
|
89
|
+
const source = join(packageRoot, 'skills', SKILL_NAME)
|
|
90
|
+
const path = join(home, '.agents', 'skills', SKILL_NAME)
|
|
91
|
+
const own = packageVersion(packageRoot)
|
|
92
|
+
if (!own || !existsSync(join(path, 'SKILL.md')) || !existsSync(join(source, 'SKILL.md'))) return false
|
|
93
|
+
let installed = null
|
|
94
|
+
try { installed = readFileSync(join(path, VERSION_MARK), 'utf8').trim() } catch {}
|
|
95
|
+
if (semver.valid(installed) && !semver.gt(own, installed)) return false
|
|
96
|
+
remove(path); cpSync(source, path, { recursive: true }); markVersion(path, packageRoot)
|
|
97
|
+
for (const agent of agentDirectories({ env, home })) {
|
|
98
|
+
const target = join(agent.skills, SKILL_NAME)
|
|
99
|
+
try {
|
|
100
|
+
if (!existsSync(join(target, 'SKILL.md')) || lstatSync(target).isSymbolicLink() || realpathSync(target) === realpathSync(path)) continue
|
|
101
|
+
remove(target); cpSync(source, target, { recursive: true })
|
|
102
|
+
} catch {}
|
|
103
|
+
}
|
|
104
|
+
return true
|
|
105
|
+
} catch { return false }
|
|
106
|
+
}
|
|
107
|
+
|
|
74
108
|
/**
|
|
75
109
|
* Put the newest release of the CLI on PATH, whichever package started the command, with the
|
|
76
110
|
* person's own npm and its settings: the environment goes to npm as it is, because what npx adds
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hirify-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
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.5",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"cross-spawn": "7.0.6",
|
package/package.json
CHANGED
package/skills/hirify/SKILL.md
CHANGED
|
@@ -5,103 +5,50 @@ description: Job search through Hirify - vacancies from the user's saved feeds,
|
|
|
5
5
|
|
|
6
6
|
# Hirify job search
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
## Start here
|
|
9
|
+
|
|
10
|
+
Run `hirify intro` once per session, before anything else. It prints the Hirify playbook, the
|
|
11
|
+
working method: interviewing your user, setting up the search, going through the results, judging
|
|
12
|
+
a vacancy, applying. Hirify keeps it current on the server (it is also at
|
|
13
|
+
https://hirify.me/agent-playbook.txt), so follow it rather than any older notes. This file only
|
|
14
|
+
covers running the CLI; `reference.md` has every command.
|
|
15
|
+
|
|
16
|
+
One rule stands regardless: `vacancy apply` sends a real application that cannot be taken back.
|
|
17
|
+
Ask your user first, every time, and show what you are about to send.
|
|
10
18
|
|
|
11
19
|
## Setup and automation
|
|
12
20
|
|
|
13
21
|
Package: `hirify-cli`; command: `hirify`; Node >=18.
|
|
14
22
|
If `hirify` is missing, run `npx -y hirify-cli@latest init`: it installs the CLI and this skill,
|
|
15
|
-
then signs in. Until then use `npx -y hirify-cli <command>`. Global installs update themselves
|
|
16
|
-
pin an exact version with `HIRIFY_NO_AUTO_UPDATE=1`.
|
|
23
|
+
then signs in. Until then use `npx -y hirify-cli <command>`. Global installs update themselves,
|
|
24
|
+
and this skill with them; pin an exact version with `HIRIFY_NO_AUTO_UPDATE=1`.
|
|
17
25
|
|
|
18
|
-
To sign in, run `hirify login`;
|
|
26
|
+
To sign in, run `hirify login`; your user confirms access in the browser within five minutes.
|
|
19
27
|
It fails at once over SSH, and without a terminal in CI or with no display. `--no-browser` is
|
|
20
28
|
manual callback login. SSH needs `--callback-port` with a matching SSH local port forward. Local
|
|
21
|
-
agents reuse
|
|
29
|
+
agents reuse your user's saved sign-in when permitted to access the same configuration directory.
|
|
22
30
|
CI and separate containers can use `HIRIFY_KEY` or `hirify auth --stdin`; never put a key in a
|
|
23
31
|
command, log or chat.
|
|
24
32
|
`hirify auth status --json` identifies the local source. Environment keys override saved access;
|
|
25
33
|
logout is local and does not unset them. Use `hirify login --force` to replace expired access.
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
allowances and permissions, `--help` for commands, `capabilities show <id> --json` for inputs,
|
|
29
|
-
effects and metering. This file supplies working rules, not a snapshot of server policy.
|
|
30
|
-
|
|
31
|
-
## Two rules before anything else
|
|
32
|
-
|
|
33
|
-
**Lists are free. Three commands are metered, and they spend different things.**
|
|
34
|
-
|
|
35
|
-
- `vacancy read` spends one of the day's vacancy opens. Re-reading a vacancy the same day is free.
|
|
36
|
-
- `vacancy reveal` spends 1 reveal, and reveals are scarce. When they run out, reading still works.
|
|
37
|
-
- `vacancy apply` counts against a small daily allowance of its own and **cannot be taken back**. It
|
|
38
|
-
sends a real application, with the user's name and profile, to a person who will read it.
|
|
39
|
-
|
|
40
|
-
**`hirify account show` is the only place these numbers are true.** Read it before spending; never
|
|
41
|
-
state what is left from memory or plan a batch on a stale figure.
|
|
42
|
-
|
|
43
|
-
**Ask the user before every apply, and before anything that changes their account.** Reading needs
|
|
44
|
-
no permission. Sending, saving and configuring do.
|
|
45
|
-
|
|
46
|
-
## Working order
|
|
47
|
-
|
|
48
|
-
1. `hirify account show` before spending; use `feed list` and `feed show <id>` first.
|
|
49
|
-
2. Search when no saved feed fits. Shortlist from cards; missing contacts are normal.
|
|
50
|
-
3. `vacancy read <slug>` to assess fit from the full text rather than a headline.
|
|
51
|
-
4. `vacancy reveal <slug>` only for vacancies that still fit after reading.
|
|
52
|
-
5. Apply only after the person's approval and the rules below.
|
|
53
|
-
6. `vacancy hide`/`company hide` what the user rejected; `hidden list` shows it.
|
|
35
|
+
## Where current facts live
|
|
54
36
|
|
|
55
|
-
|
|
37
|
+
Fetch mutable facts instead of remembering them: `filter guide` for filter names, values and how
|
|
38
|
+
a request becomes a filter; `account show --json` for current allowances and permissions;
|
|
39
|
+
`--help` for commands; `capabilities show <id> --json` for inputs, effects and metering.
|
|
56
40
|
|
|
57
41
|
`vacancy search` takes a phrase and server-defined filter options; `--limit` and `--page` control
|
|
58
|
-
pagination.
|
|
59
|
-
|
|
60
|
-
1. Read `hirify filter guide` and build criteria from the user's request or profile.
|
|
61
|
-
2. Run `hirify api call filters.preview --data '{"filters":{...},"mode":"compact","per_page":20}'`.
|
|
62
|
-
3. Inspect cards and `meta.total`; refine and preview again if empty, broad or irrelevant.
|
|
63
|
-
4. Run `hirify vacancy search` with the validated criteria.
|
|
64
|
-
|
|
65
|
-
If the guide is unavailable, ask the user about criteria rather than guessing.
|
|
66
|
-
|
|
67
|
-
## Applying
|
|
68
|
-
|
|
69
|
-
Two cases, two commands:
|
|
70
|
-
|
|
71
|
-
- **Hosted on Hirify** -> `hirify vacancy apply <slug>` sends the application through Hirify.
|
|
72
|
-
- **From somewhere else** -> `hirify vacancy reveal <slug>` gives the link or contact, and the
|
|
73
|
-
application goes there rather than through Hirify. `vacancy apply` refuses these and says so.
|
|
74
|
-
What you do with that destination is between you and your user.
|
|
75
|
-
|
|
76
|
-
- **Ask first, every time, and show what you are about to send.** An application cannot be taken
|
|
77
|
-
back. Never apply to a list on a single "yes".
|
|
78
|
-
- **Never invent the cover letter.** Draft it from what the user actually said about themselves and
|
|
79
|
-
show them the draft; if they gave you nothing, ask rather than fill the gap.
|
|
80
|
-
- **Never choose the profile** when the user has several: `hirify profile list` lists them. With
|
|
81
|
-
exactly one profile it is chosen automatically.
|
|
82
|
-
- After a successful apply, say it was sent and stop. Nobody follows up: the recruiter replies where
|
|
83
|
-
they choose to, and Hirify does not track it.
|
|
84
|
-
|
|
85
|
-
## Saved searches and delivery
|
|
86
|
-
|
|
87
|
-
These commands change the user's account, so get a yes. Creation leaves delivery off: report that,
|
|
88
|
-
offer the exact `feed deliver` command, and run it only after a separate yes.
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
hirify feed create "<name>" --filters '<json>' # criteria: hirify filter guide
|
|
92
|
-
hirify feed deliver <id> --telegram | --no-telegram | --webhook <id> | --no-webhook
|
|
93
|
-
hirify webhook list
|
|
94
|
-
hirify webhook create "<name>" <url>
|
|
95
|
-
```
|
|
42
|
+
pagination. Check a draft with
|
|
43
|
+
`hirify api call filters.preview --data '{"filters":{...},"mode":"compact","per_page":20}'`.
|
|
96
44
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
store, because it signs every delivery and cannot be shown again.
|
|
45
|
+
Creating a delivery endpoint (`hirify webhook create`) returns a **secret shown once**: give it to
|
|
46
|
+
your user immediately to store, because it signs every delivery and cannot be shown again.
|
|
100
47
|
|
|
101
48
|
## Feedback and failures
|
|
102
49
|
|
|
103
50
|
`hirify feedback send <bug|feature> "<title>" --body "<text>" [--vacancy <slug>]` is free.
|
|
104
|
-
Ask first and send
|
|
51
|
+
Ask first and send your user's words. Report the actual received/queued status and retain the
|
|
105
52
|
reference; do not promise a reply or a fix. Keep an explicit `--idempotency-key` for deliberate
|
|
106
53
|
retries when the server supports it.
|
|
107
54
|
|
|
@@ -109,7 +56,7 @@ Parse `--json` success output, never human text. Use `--error-format=json` for s
|
|
|
109
56
|
errors; do not combine it with debug if expecting one object. Exit 0 means success, 1 failure,
|
|
110
57
|
2 unsupported server manifest, 130/143 interruption. Read the stable error code and message.
|
|
111
58
|
|
|
112
|
-
- `interaction_required`: ask
|
|
59
|
+
- `interaction_required`: ask your user to sign in or configure a key; do not wait on browser login.
|
|
113
60
|
- Storage access failure: compare `doctor`, `version`, and `auth status` with the normal terminal.
|
|
114
61
|
Request permission for the specific command through the agent's approval mechanism. Reading a
|
|
115
62
|
current token needs read access; renewal needs write access. Do not treat storage errors as an
|
|
@@ -118,6 +65,7 @@ errors; do not combine it with debug if expecting one object. Exit 0 means succe
|
|
|
118
65
|
- Authentication failure: inspect `auth status`; ask for `login --force` only when renewal requires
|
|
119
66
|
a new sign-in. Never expose a token.
|
|
120
67
|
- 403: permission or plan restriction. 429: pace or a named allowance; inspect `account show`.
|
|
68
|
+
- `action_required`: stop and show your user the message; it concerns their account.
|
|
121
69
|
- Network/TLS/proxy failure: fix connectivity or trust configuration; never disable TLS verification.
|
|
122
70
|
- `outcome_unknown`: a metered action or mutation may have succeeded. Check before repeating;
|
|
123
71
|
the CLI does not automatically retry it. Do not blindly repeat apply, reveal or feedback.
|