@hacksmith/doraval 0.2.23 → 0.2.25
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/bin/doraval.js +301 -64
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -144,6 +144,7 @@ doraval journal update # pull latest from remote
|
|
|
144
144
|
|
|
145
145
|
Requires the GitHub CLI (`gh`). Journal lives in a private GitHub repo you control.
|
|
146
146
|
|
|
147
|
+
doraval update # self-update doraval to the latest version
|
|
147
148
|
doraval claude new # interactive wizard for skills/plugins (follows official table)
|
|
148
149
|
|
|
149
150
|
## Options
|
package/bin/doraval.js
CHANGED
|
@@ -595,6 +595,71 @@ var init_dist = __esm(() => {
|
|
|
595
595
|
negativePrefixRe = /^no[-A-Z]/;
|
|
596
596
|
});
|
|
597
597
|
|
|
598
|
+
// package.json
|
|
599
|
+
var require_package = __commonJS((exports, module) => {
|
|
600
|
+
module.exports = {
|
|
601
|
+
name: "@hacksmith/doraval",
|
|
602
|
+
version: "0.2.25",
|
|
603
|
+
author: "Saif",
|
|
604
|
+
repository: {
|
|
605
|
+
type: "git",
|
|
606
|
+
url: "git+https://github.com/saif-shines/doraval.git"
|
|
607
|
+
},
|
|
608
|
+
devDependencies: {
|
|
609
|
+
"@types/bun": "latest"
|
|
610
|
+
},
|
|
611
|
+
bin: {
|
|
612
|
+
doraval: "bin/doraval-wrapper.js",
|
|
613
|
+
dora: "bin/doraval-wrapper.js"
|
|
614
|
+
},
|
|
615
|
+
description: "The context engineering toolkit for coding agents",
|
|
616
|
+
engines: {
|
|
617
|
+
bun: ">=1.2.0",
|
|
618
|
+
node: ">=14.18.0"
|
|
619
|
+
},
|
|
620
|
+
files: [
|
|
621
|
+
"bin/",
|
|
622
|
+
"dist/",
|
|
623
|
+
"README.md"
|
|
624
|
+
],
|
|
625
|
+
keywords: [
|
|
626
|
+
"cli",
|
|
627
|
+
"skills",
|
|
628
|
+
"plugins",
|
|
629
|
+
"agent",
|
|
630
|
+
"validation",
|
|
631
|
+
"lint",
|
|
632
|
+
"claude-code",
|
|
633
|
+
"grok",
|
|
634
|
+
"cursor",
|
|
635
|
+
"windsurf",
|
|
636
|
+
"mcp"
|
|
637
|
+
],
|
|
638
|
+
license: "MIT",
|
|
639
|
+
workspaces: [
|
|
640
|
+
"apps/*"
|
|
641
|
+
],
|
|
642
|
+
scripts: {
|
|
643
|
+
build: "bun build ./src/cli/index.ts --outfile ./bin/doraval.js --target bun",
|
|
644
|
+
dev: "bun run ./src/cli/index.ts",
|
|
645
|
+
test: "bun test",
|
|
646
|
+
typecheck: "bunx tsc --noEmit --skipLibCheck",
|
|
647
|
+
prepublishOnly: `bun run build && node -e "const p=require('./package.json'),j=require('./jsr.json');if(p.version!==j.version){console.error('Version mismatch: package.json='+p.version+' jsr.json='+j.version);process.exit(1)}"`,
|
|
648
|
+
bump: "bun run scripts/bump.ts",
|
|
649
|
+
release: "bun run scripts/release.ts",
|
|
650
|
+
"jsr:publish": "bunx jsr publish",
|
|
651
|
+
"site:dev": "cd apps/website && bun run dev",
|
|
652
|
+
"site:build": "cd apps/website && bun run build",
|
|
653
|
+
"site:preview": "cd apps/website && bun run preview"
|
|
654
|
+
},
|
|
655
|
+
type: "module",
|
|
656
|
+
dependencies: {
|
|
657
|
+
citty: "^0.2.2",
|
|
658
|
+
picocolors: "^1.1.1"
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
});
|
|
662
|
+
|
|
598
663
|
// node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
599
664
|
var require_picocolors = __commonJS((exports, module) => {
|
|
600
665
|
var p = process || {};
|
|
@@ -4756,72 +4821,243 @@ Project-specific decisions.
|
|
|
4756
4821
|
});
|
|
4757
4822
|
});
|
|
4758
4823
|
|
|
4759
|
-
// src/
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
devDependencies: {
|
|
4771
|
-
"@types/bun": "latest"
|
|
4772
|
-
},
|
|
4773
|
-
bin: {
|
|
4774
|
-
doraval: "bin/doraval-wrapper.js",
|
|
4775
|
-
dora: "bin/doraval-wrapper.js"
|
|
4776
|
-
},
|
|
4777
|
-
description: "The context engineering toolkit for coding agents",
|
|
4778
|
-
engines: {
|
|
4779
|
-
bun: ">=1.2.0",
|
|
4780
|
-
node: ">=14.18.0"
|
|
4781
|
-
},
|
|
4782
|
-
files: [
|
|
4783
|
-
"bin/",
|
|
4784
|
-
"dist/",
|
|
4785
|
-
"README.md"
|
|
4786
|
-
],
|
|
4787
|
-
keywords: [
|
|
4788
|
-
"cli",
|
|
4789
|
-
"skills",
|
|
4790
|
-
"plugins",
|
|
4791
|
-
"agent",
|
|
4792
|
-
"validation",
|
|
4793
|
-
"lint",
|
|
4794
|
-
"claude-code",
|
|
4795
|
-
"grok",
|
|
4796
|
-
"cursor",
|
|
4797
|
-
"windsurf",
|
|
4798
|
-
"mcp"
|
|
4799
|
-
],
|
|
4800
|
-
license: "MIT",
|
|
4801
|
-
workspaces: [
|
|
4802
|
-
"apps/*"
|
|
4803
|
-
],
|
|
4804
|
-
scripts: {
|
|
4805
|
-
build: "bun build ./src/cli/index.ts --outfile ./bin/doraval.js --target bun",
|
|
4806
|
-
dev: "bun run ./src/cli/index.ts",
|
|
4807
|
-
test: "bun test",
|
|
4808
|
-
typecheck: "bunx tsc --noEmit --skipLibCheck",
|
|
4809
|
-
prepublishOnly: `bun run build && node -e "const p=require('./package.json'),j=require('./jsr.json');if(p.version!==j.version){console.error('Version mismatch: package.json='+p.version+' jsr.json='+j.version);process.exit(1)}"`,
|
|
4810
|
-
bump: "bun run scripts/bump.ts",
|
|
4811
|
-
release: "bun run scripts/release.ts",
|
|
4812
|
-
"jsr:publish": "bunx jsr publish",
|
|
4813
|
-
"site:dev": "cd apps/website && bun run dev",
|
|
4814
|
-
"site:build": "cd apps/website && bun run build",
|
|
4815
|
-
"site:preview": "cd apps/website && bun run preview"
|
|
4816
|
-
},
|
|
4817
|
-
type: "module",
|
|
4818
|
-
dependencies: {
|
|
4819
|
-
citty: "^0.2.2",
|
|
4820
|
-
picocolors: "^1.1.1"
|
|
4824
|
+
// src/core/update.ts
|
|
4825
|
+
import { execSync } from "child_process";
|
|
4826
|
+
import { existsSync as existsSync25 } from "fs";
|
|
4827
|
+
import { resolve as resolve15 } from "path";
|
|
4828
|
+
import { homedir as homedir2 } from "os";
|
|
4829
|
+
function isInPath(cmd) {
|
|
4830
|
+
try {
|
|
4831
|
+
execSync(`which ${cmd}`, { stdio: "ignore" });
|
|
4832
|
+
return true;
|
|
4833
|
+
} catch {
|
|
4834
|
+
return false;
|
|
4821
4835
|
}
|
|
4822
|
-
}
|
|
4836
|
+
}
|
|
4837
|
+
async function autoDetect() {
|
|
4838
|
+
const execPath = process.execPath;
|
|
4839
|
+
const argv0 = process.argv[0] || "";
|
|
4840
|
+
if (execPath.includes("/Cellar/") || execPath.includes("/homebrew/") || execPath.includes("/opt/homebrew/")) {
|
|
4841
|
+
if (isInPath("brew"))
|
|
4842
|
+
return { type: "homebrew" };
|
|
4843
|
+
}
|
|
4844
|
+
if (execPath.includes("/.npm/") || argv0.includes("npm")) {
|
|
4845
|
+
return { type: "npm" };
|
|
4846
|
+
}
|
|
4847
|
+
if (execPath.includes("/.bun/") || argv0.includes("bun")) {
|
|
4848
|
+
return { type: "bun" };
|
|
4849
|
+
}
|
|
4850
|
+
const home = homedir2();
|
|
4851
|
+
const possibleGlobals = [
|
|
4852
|
+
resolve15(home, ".npm-global/bin/doraval"),
|
|
4853
|
+
resolve15(home, ".bun/bin/doraval")
|
|
4854
|
+
];
|
|
4855
|
+
for (const p of possibleGlobals) {
|
|
4856
|
+
if (existsSync25(p)) {
|
|
4857
|
+
if (p.includes(".npm"))
|
|
4858
|
+
return { type: "npm" };
|
|
4859
|
+
if (p.includes(".bun"))
|
|
4860
|
+
return { type: "bun" };
|
|
4861
|
+
}
|
|
4862
|
+
}
|
|
4863
|
+
return null;
|
|
4864
|
+
}
|
|
4865
|
+
async function detectInstallMethod(options) {
|
|
4866
|
+
if (options?.force) {
|
|
4867
|
+
if (["homebrew", "npm", "bun"].includes(options.force)) {
|
|
4868
|
+
return { type: options.force };
|
|
4869
|
+
}
|
|
4870
|
+
if (options.force === "npx" || options.force === "bunx") {
|
|
4871
|
+
return { type: "transient", via: options.force };
|
|
4872
|
+
}
|
|
4873
|
+
}
|
|
4874
|
+
const auto = await autoDetect();
|
|
4875
|
+
if (auto)
|
|
4876
|
+
return auto;
|
|
4877
|
+
const marker = await readInstallMarker();
|
|
4878
|
+
if (marker)
|
|
4879
|
+
return marker;
|
|
4880
|
+
return { type: "transient", via: "npx" };
|
|
4881
|
+
}
|
|
4882
|
+
async function fetchLatestVersionInfo() {
|
|
4883
|
+
const npmRes = await fetch("https://registry.npmjs.org/@hacksmith/doraval/latest");
|
|
4884
|
+
if (!npmRes.ok)
|
|
4885
|
+
throw new Error("Failed to fetch from npm");
|
|
4886
|
+
const npmData = await npmRes.json();
|
|
4887
|
+
const version = npmData.version;
|
|
4888
|
+
let summary = "New release available.";
|
|
4889
|
+
try {
|
|
4890
|
+
const ghRes = await fetch("https://api.github.com/repos/saif-shines/doraval/releases/latest", {
|
|
4891
|
+
headers: { "User-Agent": "doraval-update" }
|
|
4892
|
+
});
|
|
4893
|
+
if (ghRes.ok) {
|
|
4894
|
+
const ghData = await ghRes.json();
|
|
4895
|
+
const body = (ghData.body || "").trim();
|
|
4896
|
+
const lines = body.split(`
|
|
4897
|
+
`).filter((l) => l.trim().startsWith("-") || l.trim().startsWith("*")).slice(0, 2);
|
|
4898
|
+
if (lines.length)
|
|
4899
|
+
summary = lines.join(" ").slice(0, 200);
|
|
4900
|
+
else if (body)
|
|
4901
|
+
summary = body.split(`
|
|
4902
|
+
`)[0].slice(0, 150);
|
|
4903
|
+
}
|
|
4904
|
+
} catch {}
|
|
4905
|
+
return { version, summary };
|
|
4906
|
+
}
|
|
4907
|
+
function buildUpgradeCommand(method) {
|
|
4908
|
+
switch (method.type) {
|
|
4909
|
+
case "homebrew":
|
|
4910
|
+
return ["brew", "upgrade", "doraval"];
|
|
4911
|
+
case "npm":
|
|
4912
|
+
return ["npm", "install", "-g", "@hacksmith/doraval@latest"];
|
|
4913
|
+
case "bun":
|
|
4914
|
+
return ["bun", "add", "-g", "@hacksmith/doraval@latest"];
|
|
4915
|
+
default:
|
|
4916
|
+
throw new Error("Cannot build upgrade command for transient installs");
|
|
4917
|
+
}
|
|
4918
|
+
}
|
|
4919
|
+
function shouldUpdate(current, latest) {
|
|
4920
|
+
if (current === latest)
|
|
4921
|
+
return false;
|
|
4922
|
+
const c = current.split(".").map(Number);
|
|
4923
|
+
const l = latest.split(".").map(Number);
|
|
4924
|
+
for (let i = 0;i < 3; i++) {
|
|
4925
|
+
if ((l[i] || 0) > (c[i] || 0))
|
|
4926
|
+
return true;
|
|
4927
|
+
if ((l[i] || 0) < (c[i] || 0))
|
|
4928
|
+
return false;
|
|
4929
|
+
}
|
|
4930
|
+
return false;
|
|
4931
|
+
}
|
|
4932
|
+
async function readInstallMarker() {
|
|
4933
|
+
try {
|
|
4934
|
+
const { readFile } = await import("fs/promises");
|
|
4935
|
+
const data = await readFile(MARKER_PATH, "utf8");
|
|
4936
|
+
const parsed = JSON.parse(data);
|
|
4937
|
+
if (parsed && parsed.type)
|
|
4938
|
+
return parsed;
|
|
4939
|
+
} catch {}
|
|
4940
|
+
return null;
|
|
4941
|
+
}
|
|
4942
|
+
async function writeInstallMarker(method) {
|
|
4943
|
+
try {
|
|
4944
|
+
const { mkdir, writeFile } = await import("fs/promises");
|
|
4945
|
+
const { dirname: dirname2 } = await import("path");
|
|
4946
|
+
await mkdir(dirname2(MARKER_PATH), { recursive: true });
|
|
4947
|
+
await writeFile(MARKER_PATH, JSON.stringify(method, null, 2));
|
|
4948
|
+
} catch {}
|
|
4949
|
+
}
|
|
4950
|
+
var MARKER_PATH;
|
|
4951
|
+
var init_update2 = __esm(() => {
|
|
4952
|
+
MARKER_PATH = resolve15(homedir2(), ".doraval", "install.json");
|
|
4953
|
+
});
|
|
4954
|
+
|
|
4955
|
+
// src/cli/commands/update.ts
|
|
4956
|
+
var exports_update2 = {};
|
|
4957
|
+
__export(exports_update2, {
|
|
4958
|
+
default: () => update_default2
|
|
4959
|
+
});
|
|
4960
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
4961
|
+
async function confirmUpdate() {
|
|
4962
|
+
const { createInterface } = await import("readline");
|
|
4963
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
4964
|
+
return new Promise((resolve16) => {
|
|
4965
|
+
rl.question("Update now? (y/N) ", (answer) => {
|
|
4966
|
+
rl.close();
|
|
4967
|
+
resolve16(answer.toLowerCase().startsWith("y"));
|
|
4968
|
+
});
|
|
4969
|
+
});
|
|
4970
|
+
}
|
|
4971
|
+
var update_default2;
|
|
4972
|
+
var init_update3 = __esm(() => {
|
|
4973
|
+
init_dist();
|
|
4974
|
+
init_out();
|
|
4975
|
+
init_update2();
|
|
4976
|
+
update_default2 = defineCommand({
|
|
4977
|
+
meta: {
|
|
4978
|
+
name: "update",
|
|
4979
|
+
description: "Update doraval to the latest version"
|
|
4980
|
+
},
|
|
4981
|
+
args: {
|
|
4982
|
+
check: {
|
|
4983
|
+
type: "boolean",
|
|
4984
|
+
description: "Only check for updates, do not install",
|
|
4985
|
+
default: false
|
|
4986
|
+
},
|
|
4987
|
+
yes: {
|
|
4988
|
+
type: "boolean",
|
|
4989
|
+
description: "Skip confirmation prompt",
|
|
4990
|
+
default: false
|
|
4991
|
+
}
|
|
4992
|
+
},
|
|
4993
|
+
async run({ args }) {
|
|
4994
|
+
const currentVersion = require_package().version;
|
|
4995
|
+
const argv1 = process.argv[1] || "";
|
|
4996
|
+
const isNpx = process.env.npm_execpath?.includes("npx") || argv1.includes("/.npm/") || process.env.npm_lifecycle_script?.includes("npx");
|
|
4997
|
+
const isBunx = process.env.BUN_INSTALL || argv1.includes(".bun/bin/bunx") || argv1.includes("bunx");
|
|
4998
|
+
if (isNpx || isBunx) {
|
|
4999
|
+
ui.info("It looks like you're using doraval via npx or bunx.");
|
|
5000
|
+
ui.info("These always fetch the latest version on the next run.");
|
|
5001
|
+
ui.info("");
|
|
5002
|
+
ui.info("For easier updates, install globally:");
|
|
5003
|
+
ui.info(" brew install saif-shines/tap/doraval");
|
|
5004
|
+
ui.info(" npm install -g @hacksmith/doraval");
|
|
5005
|
+
ui.info(" bun add -g @hacksmith/doraval");
|
|
5006
|
+
process.exit(0);
|
|
5007
|
+
}
|
|
5008
|
+
const method = await detectInstallMethod();
|
|
5009
|
+
if (method.type === "transient") {
|
|
5010
|
+
ui.info("Transient usage detected. Install globally for update support.");
|
|
5011
|
+
process.exit(0);
|
|
5012
|
+
}
|
|
5013
|
+
const latestInfo = await fetchLatestVersionInfo();
|
|
5014
|
+
if (!shouldUpdate(currentVersion, latestInfo.version)) {
|
|
5015
|
+
ui.success(`doraval is up to date (${currentVersion}).`);
|
|
5016
|
+
process.exit(0);
|
|
5017
|
+
}
|
|
5018
|
+
if (args.check) {
|
|
5019
|
+
ui.info(`Update available: ${currentVersion} \u2192 ${latestInfo.version}`);
|
|
5020
|
+
process.exit(1);
|
|
5021
|
+
}
|
|
5022
|
+
ui.heading("doraval update");
|
|
5023
|
+
ui.info(` Current: ${currentVersion}`);
|
|
5024
|
+
ui.info(` Latest: ${latestInfo.version}
|
|
5025
|
+
`);
|
|
5026
|
+
ui.info(` ${latestInfo.summary}
|
|
5027
|
+
`);
|
|
5028
|
+
if (!args.yes) {
|
|
5029
|
+
const confirmed = await confirmUpdate();
|
|
5030
|
+
if (!confirmed) {
|
|
5031
|
+
ui.info("Update cancelled.");
|
|
5032
|
+
process.exit(0);
|
|
5033
|
+
}
|
|
5034
|
+
}
|
|
5035
|
+
const cmd = buildUpgradeCommand(method);
|
|
5036
|
+
ui.info(`Running: ${cmd.join(" ")}
|
|
5037
|
+
`);
|
|
5038
|
+
const result = spawnSync6(cmd[0], cmd.slice(1), { stdio: "inherit" });
|
|
5039
|
+
if (result.status === 0) {
|
|
5040
|
+
ui.success(`Successfully updated to ${latestInfo.version}.`);
|
|
5041
|
+
ui.info("You may need to restart your shell to pick up the new version.");
|
|
5042
|
+
await writeInstallMarker(method);
|
|
5043
|
+
} else {
|
|
5044
|
+
ui.fail("Update failed.");
|
|
5045
|
+
ui.info("Common fixes:");
|
|
5046
|
+
if (cmd[0] === "brew")
|
|
5047
|
+
ui.info(" \u2022 Try: sudo brew upgrade doraval or ensure you are in the admin group");
|
|
5048
|
+
if (cmd[0] === "npm" || cmd[0] === "bun")
|
|
5049
|
+
ui.info(" \u2022 Try running with appropriate permissions or check network.");
|
|
5050
|
+
ui.info(`
|
|
5051
|
+
Raw output above.`);
|
|
5052
|
+
process.exit(result.status ?? 1);
|
|
5053
|
+
}
|
|
5054
|
+
}
|
|
5055
|
+
});
|
|
5056
|
+
});
|
|
4823
5057
|
|
|
4824
5058
|
// src/cli/index.ts
|
|
5059
|
+
init_dist();
|
|
5060
|
+
var import__package = __toESM(require_package(), 1);
|
|
4825
5061
|
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
4826
5062
|
var skill = defineCommand({
|
|
4827
5063
|
meta: {
|
|
@@ -4894,13 +5130,14 @@ var doraemonArt = `
|
|
|
4894
5130
|
var main = defineCommand({
|
|
4895
5131
|
meta: {
|
|
4896
5132
|
name: "doraval",
|
|
4897
|
-
version:
|
|
5133
|
+
version: import__package.default.version,
|
|
4898
5134
|
description: "The context engineering toolkit for coding agents"
|
|
4899
5135
|
},
|
|
4900
5136
|
subCommands: {
|
|
4901
5137
|
validate: () => Promise.resolve().then(() => (init_validate_top(), exports_validate_top)).then((m) => m.default),
|
|
4902
5138
|
init: () => Promise.resolve().then(() => (init_init2(), exports_init2)).then((m) => m.default),
|
|
4903
5139
|
bump: () => Promise.resolve().then(() => (init_bump(), exports_bump)).then((m) => m.default),
|
|
5140
|
+
update: () => Promise.resolve().then(() => (init_update3(), exports_update2)).then((m) => m.default),
|
|
4904
5141
|
skill: () => Promise.resolve(skill),
|
|
4905
5142
|
journal: () => Promise.resolve(journal),
|
|
4906
5143
|
claude: () => Promise.resolve(claude),
|