@artblocks/abx-cli 0.1.0-alpha.1 → 0.1.0-alpha.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/dist/main.js +86 -28
- package/dist/main.js.map +1 -1
- package/dist/update-check.d.ts +29 -6
- package/dist/update-check.d.ts.map +1 -1
- package/dist/update-check.js +60 -20
- package/dist/update-check.js.map +1 -1
- package/package.json +4 -4
- package/skill/SKILL.md +4 -0
package/dist/main.js
CHANGED
|
@@ -34,13 +34,14 @@
|
|
|
34
34
|
* abx storage backup-key copy the managed Turbo/Arweave key (holds credits) to a safe path
|
|
35
35
|
* abx status list indexed projects + node info
|
|
36
36
|
* abx doctor check environment (key, RPC, balance, factory, storage)
|
|
37
|
-
* abx skill install install the abx agent skill into your agent
|
|
37
|
+
* abx skill install install the version-locked abx agent skill into your agent(s)
|
|
38
|
+
* (default: Claude Code + the neutral .agents/skills; --agent/--global)
|
|
38
39
|
*
|
|
39
40
|
* Every write picks a signing lane: default hot (env key signs), `--sign` (a human
|
|
40
41
|
* approves in their own wallet via a one-shot localhost page), `--unsigned` (print
|
|
41
42
|
* the tx for a multisig / offline signer). The agent picks the lane; the CLI signs.
|
|
42
43
|
*/
|
|
43
|
-
import { appendFileSync, copyFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
44
|
+
import { appendFileSync, copyFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
44
45
|
import { randomBytes } from 'node:crypto';
|
|
45
46
|
import { basename, extname, join as joinPath, resolve as resolvePath } from 'node:path';
|
|
46
47
|
import { fileURLToPath } from 'node:url';
|
|
@@ -54,7 +55,7 @@ import { DEP_RESOLUTION, deploySeedSource, deploySeriesCodeFactory, prepareCodeS
|
|
|
54
55
|
import { checkRegistryDeps, dependencySetupCalls, parseDepFlag, resolveDepRegistryPointer } from './deps.js';
|
|
55
56
|
import { composeParamsKeys, expectedChainComplete, hasOnChainUriLane, onchainUriSetupCalls, onChainUriReport } from './onchain-uri.js';
|
|
56
57
|
import { parseFlags, unknownFlags } from './flags.js';
|
|
57
|
-
import { checkForCliUpdate, compareVersions, installedSkillVersions, readCliVersion,
|
|
58
|
+
import { AGENT_SKILL_PARENTS, checkForCliUpdate, compareVersions, installedSkillVersions, readCliVersion, readSkillVersion, SKILL_DIR_NAME, } from './update-check.js';
|
|
58
59
|
import { analyzeScript, recommendLane } from './inspect.js';
|
|
59
60
|
import { parseSchemaSpecs, describeSchema } from './schema.js';
|
|
60
61
|
import { parseSeriesTraits, looksPerTokenAttributes, parseSeriesTraitsById } from './series-traits.js';
|
|
@@ -4260,6 +4261,21 @@ async function cmdDoctor(flags) {
|
|
|
4260
4261
|
const jwk = loadArweaveJwk();
|
|
4261
4262
|
console.log(` ${dim('↳ Turbo/Arweave key ' + (jwk ? arweaveAddress(jwk) + ' ' : '') + 'holds your upload credits — back it up: `abx storage backup-key --out <path>`')}`);
|
|
4262
4263
|
}
|
|
4264
|
+
// Agent skill co-versioning — the skill drives this CLI and is version-locked to it (its version
|
|
4265
|
+
// lives in SKILL.md frontmatter). Report any installed copy and flag drift; notify-only, so a
|
|
4266
|
+
// stale/absent skill never fails doctor (`abx skill install` resyncs).
|
|
4267
|
+
const cliVersion = readCliVersion();
|
|
4268
|
+
const skillVersions = installedSkillVersions();
|
|
4269
|
+
const staleSkills = skillVersions.filter((v) => compareVersions(cliVersion, v) > 0);
|
|
4270
|
+
if (skillVersions.length === 0) {
|
|
4271
|
+
console.log(` ${dim('↳ agent skill: not installed here — `abx skill install` so a coding agent can drive abx')}`);
|
|
4272
|
+
}
|
|
4273
|
+
else if (staleSkills.length > 0) {
|
|
4274
|
+
console.log(` ${c.orange}⚠${c.reset} agent skill behind CLI${dim(` installed v${staleSkills.join(', v')} · CLI v${cliVersion} — refresh: `)}${g('abx skill install')}`);
|
|
4275
|
+
}
|
|
4276
|
+
else {
|
|
4277
|
+
check(`agent skill in sync (v${cliVersion})`, true);
|
|
4278
|
+
}
|
|
4263
4279
|
console.log('');
|
|
4264
4280
|
}
|
|
4265
4281
|
// ── shared output ─────────────────────────────────────────────────────────--
|
|
@@ -4558,12 +4574,15 @@ function keepAlive() {
|
|
|
4558
4574
|
// ── per-command usage (printed by `<cmd> --help` / `abx help <cmd>`; read-only) ──
|
|
4559
4575
|
const COMMAND_HELP = {
|
|
4560
4576
|
skill: `
|
|
4561
|
-
${bold('abx skill')} ${dim('— install the abx agent skill so your coding agent can drive abx')}
|
|
4562
|
-
${g('abx skill install')} copy the skill
|
|
4563
|
-
${
|
|
4564
|
-
${g('--
|
|
4577
|
+
${bold('abx skill')} ${dim('— install the version-locked abx agent skill so your coding agent can drive abx')}
|
|
4578
|
+
${g('abx skill install')} copy the bundled skill (version-locked to this CLI) into your agent(s)
|
|
4579
|
+
${dim('default: both')} ${bold('.claude/skills')} ${dim('(Claude Code) and')} ${bold('.agents/skills')} ${dim('(Cursor · Codex · Gemini · Copilot)')}
|
|
4580
|
+
${g('--agent <name>')} only one agent: ${dim('claude | cursor | codex | gemini | copilot')}
|
|
4581
|
+
${g('--global')} install into your home dir (~) instead of the current project
|
|
4582
|
+
${g('--target <dir>')} install the skill folder straight under <dir> (writes <dir>/abx-self-host)
|
|
4565
4583
|
${g('abx skill path')} print the absolute path to the bundled skill (for ${g('npx skills add <path>')} or manual copy)
|
|
4566
|
-
${dim('Restart your agent after installing so it picks up the skill.
|
|
4584
|
+
${dim('Restart your agent after installing so it picks up the skill. Once the repo is public, the git-based')}
|
|
4585
|
+
${dim('cross-agent installer also works (not version-locked):')} ${g('npx skills add ArtBlocks/abx --skill abx-self-host')}`,
|
|
4567
4586
|
deploy: `
|
|
4568
4587
|
${bold('abx deploy')} ${dim('— deploy + index a 1/1 (no server). Sends a tx in the chosen lane.')}
|
|
4569
4588
|
--image <path> custody your own image (png · jpg · gif · svg · webp); else generative demo art
|
|
@@ -5019,7 +5038,7 @@ function help() {
|
|
|
5019
5038
|
${g('abx forget')} <address> drop a project's local registration + projection (on-chain untouched)
|
|
5020
5039
|
${g('abx status')} list indexed projects + node info
|
|
5021
5040
|
${g('abx doctor')} check environment (key, RPC, balance, factory, storage)
|
|
5022
|
-
${g('abx skill install')} install the abx
|
|
5041
|
+
${g('abx skill install')} install the version-locked abx skill into your agent(s) [--agent <name>] [--global] [--target <dir>] · ${g('abx skill path')} prints the bundled skill
|
|
5023
5042
|
${g('abx version')} print the installed CLI version
|
|
5024
5043
|
|
|
5025
5044
|
${dim('Run')} ${g('abx <command> --help')} ${dim('for per-command usage. --help / -h never executes — it only prints usage.')}
|
|
@@ -5041,8 +5060,13 @@ function parseSaltFlag(raw) {
|
|
|
5041
5060
|
// ── skill: install the abx agent skill into the user's coding agent ───────────────────────
|
|
5042
5061
|
// The skill is the agentic half of the toolkit — the CLI is only useful once an agent knows how
|
|
5043
5062
|
// to drive it. It ships bundled inside the published package (packages/cli/skill/, created at
|
|
5044
|
-
// prepack); in dev the same command reads the canonical copy straight from the repo.
|
|
5045
|
-
//
|
|
5063
|
+
// prepack); in dev the same command reads the canonical copy straight from the repo. This is the
|
|
5064
|
+
// CANONICAL install path precisely because the bundle is version-locked to the CLI it ships inside
|
|
5065
|
+
// (the version lives in SKILL.md frontmatter — see update-check.ts). By default it writes to BOTH
|
|
5066
|
+
// `.claude/skills` (Claude Code) and the neutral `.agents/skills` (Cursor · Codex · Gemini ·
|
|
5067
|
+
// Copilot all read it), so one command covers the whole ecosystem; `--agent` narrows it. A separate
|
|
5068
|
+
// git-based channel, `npx skills add ArtBlocks/abx --skill abx-self-host`, works once the repo is public but is NOT
|
|
5069
|
+
// version-locked to a local CLI — prefer `abx skill install`.
|
|
5046
5070
|
/** Locate the skill folder: the bundled copy beside the compiled CLI (published), else the
|
|
5047
5071
|
* canonical repo copy (dev). Returns null if neither is present. */
|
|
5048
5072
|
function resolveBundledSkill() {
|
|
@@ -5106,37 +5130,71 @@ function cmdScaffoldRenderer(rest, flags) {
|
|
|
5106
5130
|
console.log(` ${g('abx deploy-code --image-renderer <MyRenderer> --attributes-renderer <MyTraits> --onchain-uri --schema palette:HexColor:TokenOwner --name "…" --symbol …')}`);
|
|
5107
5131
|
info(`full walkthrough: ${bold(`${basename(dir)}/README.md`)} · interface + invariants: https://abx.docs.artblocks.io/protocol/renderers/`);
|
|
5108
5132
|
}
|
|
5133
|
+
/** Human label for each skills-parent dir — which agents pick the skill up from there. */
|
|
5134
|
+
const SKILL_PARENT_LABELS = {
|
|
5135
|
+
'.claude/skills': 'Claude Code',
|
|
5136
|
+
'.agents/skills': 'Cursor · Codex · Gemini · Copilot',
|
|
5137
|
+
};
|
|
5138
|
+
/** Resolve which skills-parent dirs `install` should write to. No `--agent` → the whole-ecosystem
|
|
5139
|
+
* default (Claude Code + the neutral `.agents/skills` everyone else reads). `--agent a,b` narrows
|
|
5140
|
+
* to those agents' dirs (de-duped, since several share `.agents/skills`). */
|
|
5141
|
+
function resolveInstallParents(agentFlag) {
|
|
5142
|
+
if (!agentFlag || agentFlag === 'true')
|
|
5143
|
+
return ['.claude/skills', '.agents/skills'];
|
|
5144
|
+
const parents = new Set();
|
|
5145
|
+
for (const raw of agentFlag.split(',')) {
|
|
5146
|
+
const a = raw.trim().toLowerCase();
|
|
5147
|
+
const parent = AGENT_SKILL_PARENTS[a];
|
|
5148
|
+
if (!parent) {
|
|
5149
|
+
throw new Error(`unknown --agent '${a}'. Use one of: ${Object.keys(AGENT_SKILL_PARENTS).join(', ')} (or omit --agent to install for every agent).`);
|
|
5150
|
+
}
|
|
5151
|
+
parents.add(parent);
|
|
5152
|
+
}
|
|
5153
|
+
return [...parents];
|
|
5154
|
+
}
|
|
5155
|
+
/** Copy the bundled skill folder to `dest`, replacing any prior copy so a re-install after an
|
|
5156
|
+
* upgrade never leaves stale reference files behind. */
|
|
5157
|
+
function installSkillTo(src, dest) {
|
|
5158
|
+
mkdirSync(joinPath(dest, '..'), { recursive: true });
|
|
5159
|
+
rmSync(dest, { recursive: true, force: true });
|
|
5160
|
+
cpSync(src, dest, { recursive: true });
|
|
5161
|
+
}
|
|
5109
5162
|
async function cmdSkill(rest, flags) {
|
|
5110
5163
|
const sub = rest[0] ?? 'install';
|
|
5111
5164
|
const src = resolveBundledSkill();
|
|
5112
5165
|
if (!src) {
|
|
5113
5166
|
throw new Error('bundled skill not found (expected <pkg>/skill or .claude/skills/abx-self-host). ' +
|
|
5114
|
-
'Reinstall @artblocks/abx-cli, or install cross-agent with: npx skills add ArtBlocks/abx');
|
|
5167
|
+
'Reinstall @artblocks/abx-cli, or install cross-agent with: npx skills add ArtBlocks/abx --skill abx-self-host');
|
|
5115
5168
|
}
|
|
5116
5169
|
if (sub === 'path') {
|
|
5117
5170
|
console.log(src);
|
|
5118
5171
|
return;
|
|
5119
5172
|
}
|
|
5120
5173
|
if (sub === 'install') {
|
|
5121
|
-
const
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
}
|
|
5131
|
-
catch {
|
|
5132
|
-
/* non-fatal */
|
|
5174
|
+
const version = readSkillVersion(joinPath(src, 'SKILL.md')) ?? readCliVersion();
|
|
5175
|
+
// Escape hatch: --target <dir> writes the skill folder straight under <dir> (for an agent
|
|
5176
|
+
// whose skills dir we don't special-case, or a bespoke location).
|
|
5177
|
+
if (typeof flags.target === 'string' && flags.target !== 'true') {
|
|
5178
|
+
const dest = joinPath(resolvePath(flags.target), SKILL_DIR_NAME);
|
|
5179
|
+
installSkillTo(src, dest);
|
|
5180
|
+
ok(`installed the abx skill v${version} → ${dest}`);
|
|
5181
|
+
info('restart your agent so it loads the skill, then ask it to launch an NFT with abx.');
|
|
5182
|
+
return;
|
|
5133
5183
|
}
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5184
|
+
const base = flags.global !== undefined ? homedir() : process.cwd();
|
|
5185
|
+
const parents = resolveInstallParents(flags.agent);
|
|
5186
|
+
ok(`installed the abx skill v${version}${flags.global !== undefined ? ' (global, ~)' : ''}:`);
|
|
5187
|
+
for (const parent of parents) {
|
|
5188
|
+
const dest = joinPath(base, parent, SKILL_DIR_NAME);
|
|
5189
|
+
installSkillTo(src, dest);
|
|
5190
|
+
const label = SKILL_PARENT_LABELS[parent];
|
|
5191
|
+
console.log(` ${g(joinPath(parent, SKILL_DIR_NAME))}${label ? dim(' → ' + label) : ''}`);
|
|
5192
|
+
}
|
|
5193
|
+
info('restart your agent so it loads the skill, then ask it to launch an NFT with abx.');
|
|
5194
|
+
info(`the skill is version-locked to this CLI (v${version}); re-run ${g('abx skill install')} after upgrading so the two stay in sync.`);
|
|
5137
5195
|
return;
|
|
5138
5196
|
}
|
|
5139
|
-
throw new Error('usage: abx skill <install|path> [--global] [--target <dir>]');
|
|
5197
|
+
throw new Error('usage: abx skill <install|path> [--agent claude|cursor|codex|gemini|copilot] [--global] [--target <dir>]');
|
|
5140
5198
|
}
|
|
5141
5199
|
main().catch((err) => {
|
|
5142
5200
|
// Keep the actionable message; strip viem's verbose boilerplate trailer (Docs:/Version: lines) so
|