@joycostudio/scripts 0.0.3 → 0.0.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/README.md +1 -0
- package/dist/cli.js +201 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ pnpx @joycostudio/scripts compress ./images ./output --quality 80
|
|
|
10
10
|
pnpx @joycostudio/scripts resize ./images ./output --width 1920 --height 1080
|
|
11
11
|
pnpx @joycostudio/scripts sequence -z 4 ./frames ./output/frame_%n.png
|
|
12
12
|
pnpx @joycostudio/scripts fix-svg src --dry --print
|
|
13
|
+
pnpx @joycostudio/scripts agents -s codex
|
|
13
14
|
```
|
|
14
15
|
|
|
15
16
|
For local development, build the CLI before running it directly:
|
package/dist/cli.js
CHANGED
|
@@ -502,10 +502,10 @@ var require_help = __commonJS({
|
|
|
502
502
|
function formatList(textArray) {
|
|
503
503
|
return textArray.join("\n").replace(/^/gm, " ".repeat(itemIndentWidth));
|
|
504
504
|
}
|
|
505
|
-
let
|
|
505
|
+
let output2 = [`Usage: ${helper.commandUsage(cmd)}`, ""];
|
|
506
506
|
const commandDescription = helper.commandDescription(cmd);
|
|
507
507
|
if (commandDescription.length > 0) {
|
|
508
|
-
|
|
508
|
+
output2 = output2.concat([
|
|
509
509
|
helper.wrap(commandDescription, helpWidth, 0),
|
|
510
510
|
""
|
|
511
511
|
]);
|
|
@@ -517,7 +517,7 @@ var require_help = __commonJS({
|
|
|
517
517
|
);
|
|
518
518
|
});
|
|
519
519
|
if (argumentList.length > 0) {
|
|
520
|
-
|
|
520
|
+
output2 = output2.concat(["Arguments:", formatList(argumentList), ""]);
|
|
521
521
|
}
|
|
522
522
|
const optionList = helper.visibleOptions(cmd).map((option) => {
|
|
523
523
|
return formatItem(
|
|
@@ -526,7 +526,7 @@ var require_help = __commonJS({
|
|
|
526
526
|
);
|
|
527
527
|
});
|
|
528
528
|
if (optionList.length > 0) {
|
|
529
|
-
|
|
529
|
+
output2 = output2.concat(["Options:", formatList(optionList), ""]);
|
|
530
530
|
}
|
|
531
531
|
if (this.showGlobalOptions) {
|
|
532
532
|
const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
|
|
@@ -536,7 +536,7 @@ var require_help = __commonJS({
|
|
|
536
536
|
);
|
|
537
537
|
});
|
|
538
538
|
if (globalOptionList.length > 0) {
|
|
539
|
-
|
|
539
|
+
output2 = output2.concat([
|
|
540
540
|
"Global Options:",
|
|
541
541
|
formatList(globalOptionList),
|
|
542
542
|
""
|
|
@@ -550,9 +550,9 @@ var require_help = __commonJS({
|
|
|
550
550
|
);
|
|
551
551
|
});
|
|
552
552
|
if (commandList.length > 0) {
|
|
553
|
-
|
|
553
|
+
output2 = output2.concat(["Commands:", formatList(commandList), ""]);
|
|
554
554
|
}
|
|
555
|
-
return
|
|
555
|
+
return output2.join("\n");
|
|
556
556
|
}
|
|
557
557
|
/**
|
|
558
558
|
* Calculate the pad width from the maximum term length.
|
|
@@ -964,8 +964,8 @@ var require_command = __commonJS({
|
|
|
964
964
|
"../node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports2) {
|
|
965
965
|
var EventEmitter = require("node:events").EventEmitter;
|
|
966
966
|
var childProcess = require("node:child_process");
|
|
967
|
-
var
|
|
968
|
-
var
|
|
967
|
+
var path8 = require("node:path");
|
|
968
|
+
var fs7 = require("node:fs");
|
|
969
969
|
var process2 = require("node:process");
|
|
970
970
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
971
971
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1897,11 +1897,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1897
1897
|
let launchWithNode = false;
|
|
1898
1898
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1899
1899
|
function findFile(baseDir, baseName) {
|
|
1900
|
-
const localBin =
|
|
1901
|
-
if (
|
|
1902
|
-
if (sourceExt.includes(
|
|
1900
|
+
const localBin = path8.resolve(baseDir, baseName);
|
|
1901
|
+
if (fs7.existsSync(localBin)) return localBin;
|
|
1902
|
+
if (sourceExt.includes(path8.extname(baseName))) return void 0;
|
|
1903
1903
|
const foundExt = sourceExt.find(
|
|
1904
|
-
(ext) =>
|
|
1904
|
+
(ext) => fs7.existsSync(`${localBin}${ext}`)
|
|
1905
1905
|
);
|
|
1906
1906
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1907
1907
|
return void 0;
|
|
@@ -1913,21 +1913,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1913
1913
|
if (this._scriptPath) {
|
|
1914
1914
|
let resolvedScriptPath;
|
|
1915
1915
|
try {
|
|
1916
|
-
resolvedScriptPath =
|
|
1916
|
+
resolvedScriptPath = fs7.realpathSync(this._scriptPath);
|
|
1917
1917
|
} catch (err) {
|
|
1918
1918
|
resolvedScriptPath = this._scriptPath;
|
|
1919
1919
|
}
|
|
1920
|
-
executableDir =
|
|
1921
|
-
|
|
1920
|
+
executableDir = path8.resolve(
|
|
1921
|
+
path8.dirname(resolvedScriptPath),
|
|
1922
1922
|
executableDir
|
|
1923
1923
|
);
|
|
1924
1924
|
}
|
|
1925
1925
|
if (executableDir) {
|
|
1926
1926
|
let localFile = findFile(executableDir, executableFile);
|
|
1927
1927
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1928
|
-
const legacyName =
|
|
1928
|
+
const legacyName = path8.basename(
|
|
1929
1929
|
this._scriptPath,
|
|
1930
|
-
|
|
1930
|
+
path8.extname(this._scriptPath)
|
|
1931
1931
|
);
|
|
1932
1932
|
if (legacyName !== this._name) {
|
|
1933
1933
|
localFile = findFile(
|
|
@@ -1938,7 +1938,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1938
1938
|
}
|
|
1939
1939
|
executableFile = localFile || executableFile;
|
|
1940
1940
|
}
|
|
1941
|
-
launchWithNode = sourceExt.includes(
|
|
1941
|
+
launchWithNode = sourceExt.includes(path8.extname(executableFile));
|
|
1942
1942
|
let proc;
|
|
1943
1943
|
if (process2.platform !== "win32") {
|
|
1944
1944
|
if (launchWithNode) {
|
|
@@ -2778,7 +2778,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2778
2778
|
* @return {Command}
|
|
2779
2779
|
*/
|
|
2780
2780
|
nameFromFilename(filename) {
|
|
2781
|
-
this._name =
|
|
2781
|
+
this._name = path8.basename(filename, path8.extname(filename));
|
|
2782
2782
|
return this;
|
|
2783
2783
|
}
|
|
2784
2784
|
/**
|
|
@@ -2792,9 +2792,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2792
2792
|
* @param {string} [path]
|
|
2793
2793
|
* @return {(string|null|Command)}
|
|
2794
2794
|
*/
|
|
2795
|
-
executableDir(
|
|
2796
|
-
if (
|
|
2797
|
-
this._executableDir =
|
|
2795
|
+
executableDir(path9) {
|
|
2796
|
+
if (path9 === void 0) return this._executableDir;
|
|
2797
|
+
this._executableDir = path9;
|
|
2798
2798
|
return this;
|
|
2799
2799
|
}
|
|
2800
2800
|
/**
|
|
@@ -3052,7 +3052,7 @@ var {
|
|
|
3052
3052
|
// package.json
|
|
3053
3053
|
var package_default = {
|
|
3054
3054
|
name: "@joycostudio/scripts",
|
|
3055
|
-
version: "0.0.
|
|
3055
|
+
version: "0.0.5",
|
|
3056
3056
|
description: "Joyco utility scripts as a pnpx CLI",
|
|
3057
3057
|
bin: {
|
|
3058
3058
|
scripts: "dist/cli.js"
|
|
@@ -3503,6 +3503,179 @@ function register4(program2) {
|
|
|
3503
3503
|
addExamples(command, ["scripts fix-svg src", "scripts fix-svg src --dry --print"]);
|
|
3504
3504
|
}
|
|
3505
3505
|
|
|
3506
|
+
// src/commands/agents.ts
|
|
3507
|
+
var import_path7 = __toESM(require("path"));
|
|
3508
|
+
var import_promises5 = __toESM(require("fs/promises"));
|
|
3509
|
+
var import_promises6 = require("node:readline/promises");
|
|
3510
|
+
var import_node_process = require("node:process");
|
|
3511
|
+
|
|
3512
|
+
// src/core/agents.ts
|
|
3513
|
+
var import_promises4 = __toESM(require("fs/promises"));
|
|
3514
|
+
var import_path6 = __toESM(require("path"));
|
|
3515
|
+
var AGENTS_URL = "https://registry.joyco.studio/AGENTS.md";
|
|
3516
|
+
var agentStrategies = {
|
|
3517
|
+
codex: {
|
|
3518
|
+
defaultPath: "AGENTS.md",
|
|
3519
|
+
description: "Codex reads AGENTS.md from the project root."
|
|
3520
|
+
},
|
|
3521
|
+
claude: {
|
|
3522
|
+
defaultPath: "CLAUDE.md",
|
|
3523
|
+
description: "Claude Code reads CLAUDE.md from the project root."
|
|
3524
|
+
},
|
|
3525
|
+
cursor: {
|
|
3526
|
+
defaultPath: "AGENTS.md",
|
|
3527
|
+
description: "Cursor reads AGENTS.md from the project root."
|
|
3528
|
+
}
|
|
3529
|
+
};
|
|
3530
|
+
function parseAgentStrategy(value) {
|
|
3531
|
+
const normalized = value.trim().toLowerCase();
|
|
3532
|
+
if (normalized in agentStrategies) {
|
|
3533
|
+
return normalized;
|
|
3534
|
+
}
|
|
3535
|
+
const choices = Object.keys(agentStrategies).join(", ");
|
|
3536
|
+
throw new Error(`Unknown strategy "${value}". Choose one of: ${choices}.`);
|
|
3537
|
+
}
|
|
3538
|
+
function getDefaultAgentsPath(strategy) {
|
|
3539
|
+
return agentStrategies[strategy].defaultPath;
|
|
3540
|
+
}
|
|
3541
|
+
function resolveAgentsPath({
|
|
3542
|
+
strategy,
|
|
3543
|
+
outputPath,
|
|
3544
|
+
cwd = process.cwd()
|
|
3545
|
+
}) {
|
|
3546
|
+
return import_path6.default.resolve(cwd, outputPath ?? getDefaultAgentsPath(strategy));
|
|
3547
|
+
}
|
|
3548
|
+
async function fetchAgentsMd(url = AGENTS_URL) {
|
|
3549
|
+
const response = await fetch(url, {
|
|
3550
|
+
headers: {
|
|
3551
|
+
"Cache-Control": "no-cache"
|
|
3552
|
+
}
|
|
3553
|
+
});
|
|
3554
|
+
if (!response.ok) {
|
|
3555
|
+
throw new Error(
|
|
3556
|
+
`Failed to fetch ${url} (${response.status} ${response.statusText}).`
|
|
3557
|
+
);
|
|
3558
|
+
}
|
|
3559
|
+
return response.text();
|
|
3560
|
+
}
|
|
3561
|
+
async function writeAgentsFile(outputPath, contents, mode) {
|
|
3562
|
+
await import_promises4.default.mkdir(import_path6.default.dirname(outputPath), { recursive: true });
|
|
3563
|
+
if (mode === "append") {
|
|
3564
|
+
const needsNewline = !contents.startsWith("\n") && contents.length > 0;
|
|
3565
|
+
await import_promises4.default.appendFile(outputPath, needsNewline ? `
|
|
3566
|
+
${contents}` : contents, "utf8");
|
|
3567
|
+
return;
|
|
3568
|
+
}
|
|
3569
|
+
const flag = mode === "create" ? "wx" : "w";
|
|
3570
|
+
await import_promises4.default.writeFile(outputPath, contents, { encoding: "utf8", flag });
|
|
3571
|
+
}
|
|
3572
|
+
async function pullAgents({
|
|
3573
|
+
strategy,
|
|
3574
|
+
outputPath,
|
|
3575
|
+
writeMode = "create",
|
|
3576
|
+
cwd = process.cwd()
|
|
3577
|
+
}) {
|
|
3578
|
+
const resolvedPath = resolveAgentsPath({ strategy, outputPath, cwd });
|
|
3579
|
+
const contents = await fetchAgentsMd();
|
|
3580
|
+
await writeAgentsFile(resolvedPath, contents, writeMode);
|
|
3581
|
+
return {
|
|
3582
|
+
outputPath: resolvedPath,
|
|
3583
|
+
bytes: Buffer.byteLength(contents, "utf8")
|
|
3584
|
+
};
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3587
|
+
// src/commands/agents.ts
|
|
3588
|
+
var strategyChoices = Object.entries(agentStrategies).map(([key, value]) => `${key}=${value.defaultPath}`).join(", ");
|
|
3589
|
+
async function fileExists(filePath) {
|
|
3590
|
+
try {
|
|
3591
|
+
await import_promises5.default.access(filePath);
|
|
3592
|
+
return true;
|
|
3593
|
+
} catch (error) {
|
|
3594
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
3595
|
+
const errorCode = error.code;
|
|
3596
|
+
if (errorCode === "ENOENT") {
|
|
3597
|
+
return false;
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
throw error;
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
async function promptExistingFile(outputPath) {
|
|
3604
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
3605
|
+
throw new Error(
|
|
3606
|
+
"Output file already exists. Re-run in an interactive terminal to choose overwrite, append, or cancel."
|
|
3607
|
+
);
|
|
3608
|
+
}
|
|
3609
|
+
const rl = (0, import_promises6.createInterface)({ input: import_node_process.stdin, output: import_node_process.stdout });
|
|
3610
|
+
try {
|
|
3611
|
+
while (true) {
|
|
3612
|
+
const answer = await rl.question(
|
|
3613
|
+
`
|
|
3614
|
+
File already exists at ${outputPath}. Overwrite (o), append (a), or cancel (c)? `
|
|
3615
|
+
);
|
|
3616
|
+
const normalized = answer.trim().toLowerCase();
|
|
3617
|
+
if (normalized === "o" || normalized === "overwrite") {
|
|
3618
|
+
return "overwrite";
|
|
3619
|
+
}
|
|
3620
|
+
if (normalized === "a" || normalized === "append") {
|
|
3621
|
+
return "append";
|
|
3622
|
+
}
|
|
3623
|
+
if (normalized === "c" || normalized === "cancel") {
|
|
3624
|
+
return "cancel";
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
} finally {
|
|
3628
|
+
rl.close();
|
|
3629
|
+
}
|
|
3630
|
+
}
|
|
3631
|
+
function register5(program2) {
|
|
3632
|
+
const command = program2.command("agents").description("Download the latest AGENTS.md for a selected agent tool strategy.").usage("[dest_path] [-s <strategy>]").argument(
|
|
3633
|
+
"[dest_path]",
|
|
3634
|
+
"Output path (defaults to the strategy's standard location)."
|
|
3635
|
+
).option(
|
|
3636
|
+
"-s, --strategy <strategy>",
|
|
3637
|
+
`Agent tool strategy (${strategyChoices}).`,
|
|
3638
|
+
parseAgentStrategy,
|
|
3639
|
+
"codex"
|
|
3640
|
+
).action(async (destPath, options, cmd) => {
|
|
3641
|
+
try {
|
|
3642
|
+
const strategySource = cmd.getOptionValueSource?.("strategy");
|
|
3643
|
+
if (destPath && strategySource === "cli") {
|
|
3644
|
+
throw new Error("Choose either an output path or -s/--strategy, not both.");
|
|
3645
|
+
}
|
|
3646
|
+
const resolvedPath = resolveAgentsPath({
|
|
3647
|
+
strategy: options.strategy,
|
|
3648
|
+
outputPath: destPath,
|
|
3649
|
+
cwd: process.cwd()
|
|
3650
|
+
});
|
|
3651
|
+
const displayPath = import_path7.default.relative(process.cwd(), resolvedPath);
|
|
3652
|
+
let writeMode = "create";
|
|
3653
|
+
if (await fileExists(resolvedPath)) {
|
|
3654
|
+
const choice = await promptExistingFile(displayPath);
|
|
3655
|
+
if (choice === "cancel") {
|
|
3656
|
+
console.log("Canceled.");
|
|
3657
|
+
process.exit(1);
|
|
3658
|
+
}
|
|
3659
|
+
writeMode = choice;
|
|
3660
|
+
}
|
|
3661
|
+
await pullAgents({
|
|
3662
|
+
strategy: options.strategy,
|
|
3663
|
+
outputPath: resolvedPath,
|
|
3664
|
+
writeMode
|
|
3665
|
+
});
|
|
3666
|
+
console.log(`Saved agent instructions to ${displayPath}`);
|
|
3667
|
+
} catch (error) {
|
|
3668
|
+
handleCommandError(error);
|
|
3669
|
+
}
|
|
3670
|
+
});
|
|
3671
|
+
addExamples(command, [
|
|
3672
|
+
"scripts agents",
|
|
3673
|
+
"scripts agents -s claude",
|
|
3674
|
+
"scripts agents -s cursor",
|
|
3675
|
+
"scripts agents ./config/AGENTS.md"
|
|
3676
|
+
]);
|
|
3677
|
+
}
|
|
3678
|
+
|
|
3506
3679
|
// src/cli.ts
|
|
3507
3680
|
var cliName = "scripts";
|
|
3508
3681
|
var cliDescription = "Joyco utility scripts bundled as a pnpx CLI.";
|
|
@@ -3510,15 +3683,16 @@ var commandRegistrations = [
|
|
|
3510
3683
|
register,
|
|
3511
3684
|
register2,
|
|
3512
3685
|
register3,
|
|
3513
|
-
register4
|
|
3686
|
+
register4,
|
|
3687
|
+
register5
|
|
3514
3688
|
];
|
|
3515
3689
|
function buildProgram() {
|
|
3516
3690
|
const program2 = new Command();
|
|
3517
3691
|
program2.name(cliName);
|
|
3518
3692
|
program2.description(cliDescription);
|
|
3519
3693
|
program2.version(package_default.version);
|
|
3520
|
-
for (const
|
|
3521
|
-
|
|
3694
|
+
for (const register6 of commandRegistrations) {
|
|
3695
|
+
register6(program2);
|
|
3522
3696
|
}
|
|
3523
3697
|
return program2;
|
|
3524
3698
|
}
|