nightralph 0.0.52 → 0.0.54
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 +145 -16
- package/dist/display.js +80 -62
- package/dist/display.js.map +2 -2
- package/dist/index.js +2099 -314
- package/dist/index.js.map +4 -4
- package/dist/learnings.js +356 -0
- package/dist/learnings.js.map +7 -0
- package/dist/meta.json +234 -14
- package/dist/orchestrator.js +528 -142
- package/dist/orchestrator.js.map +3 -3
- package/dist/preflight.js +34 -0
- package/dist/preflight.js.map +7 -0
- package/dist/progress.js +5 -4
- package/dist/progress.js.map +2 -2
- package/dist/retry.js +83 -0
- package/dist/retry.js.map +7 -0
- package/dist/review.js +662 -0
- package/dist/review.js.map +7 -0
- package/dist/rules.js +54 -0
- package/dist/rules.js.map +7 -0
- package/dist/src/display.d.ts +35 -33
- package/dist/src/display.d.ts.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/learnings.d.ts +68 -0
- package/dist/src/learnings.d.ts.map +1 -0
- package/dist/src/orchestrator.d.ts +24 -11
- package/dist/src/orchestrator.d.ts.map +1 -1
- package/dist/src/preflight.d.ts +6 -0
- package/dist/src/preflight.d.ts.map +1 -0
- package/dist/src/progress.d.ts +1 -1
- package/dist/src/progress.d.ts.map +1 -1
- package/dist/src/retry.d.ts +26 -0
- package/dist/src/retry.d.ts.map +1 -0
- package/dist/src/review.d.ts +127 -0
- package/dist/src/review.d.ts.map +1 -0
- package/dist/src/rules.d.ts +10 -0
- package/dist/src/rules.d.ts.map +1 -0
- package/dist/src/testcmd.d.ts +1 -0
- package/dist/src/testcmd.d.ts.map +1 -1
- package/dist/src/worktree.d.ts +30 -1
- package/dist/src/worktree.d.ts.map +1 -1
- package/dist/testcmd.js +13 -0
- package/dist/testcmd.js.map +2 -2
- package/dist/worktree.js +236 -32
- package/dist/worktree.js.map +2 -2
- package/package.json +5 -4
package/dist/worktree.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/worktree.ts"],
|
|
4
|
-
"sourcesContent": ["import { execFile, execFileSync } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { basename, dirname, join, resolve } from 'node:path'\nimport { existsSync } from 'node:fs'\nimport type { Ticket } from './orchestrator.js'\n\nconst execFileAsync = promisify(execFile)\n\nexport function getRepoRoot ():string {\n const stdout = execFileSync(\n 'git',\n ['rev-parse', '--show-toplevel'],\n { encoding:'utf8' }\n )\n return stdout.trim()\n}\n\nexport function getRepoName ():string {\n const commonDir = execFileSync(\n 'git',\n ['rev-parse', '--git-common-dir'],\n { encoding:'utf8' }\n ).trim()\n return basename(dirname(resolve(commonDir)))\n}\n\nexport function getCurrentBranch ():string {\n const stdout = execFileSync(\n 'git',\n ['rev-parse', '--abbrev-ref', 'HEAD'],\n { encoding:'utf8' }\n )\n return stdout.trim()\n}\n\nasync function branchExists (\n repoRoot:string,\n branchName:string\n):Promise<boolean> {\n try {\n await execFileAsync(\n 'git',\n ['show-ref', '--verify', '--quiet', `refs/heads/${branchName}`],\n { cwd:repoRoot }\n )\n return true\n } catch {\n return false\n }\n}\n\nexport function buildBranchName (\n repoName:string,\n ticket:Ticket\n):string {\n const num = String(ticket.num).padStart(2, '0')\n const prefix = ticket.feature ?\n `${ticket.feature}-` :\n ''\n return `${repoName}--${prefix}${num}-${ticket.slug}`\n}\n\nasync function createWorktreeNow (\n opts:{\n repoRoot:string\n repoName:string\n baseBranch:string\n ticket:Ticket\n }\n):Promise<{ worktreePath:string; branchName:string }> {\n const { repoRoot, repoName, baseBranch, ticket } = opts\n const branchName = buildBranchName(repoName, ticket)\n const num = String(ticket.num).padStart(2, '0')\n const prefix = ticket.feature ?\n `${ticket.feature}-` :\n ''\n const worktreePath = join(\n repoRoot,\n '..',\n `${repoName}.${prefix}${num}-${ticket.slug}`\n )\n\n if (existsSync(worktreePath)) {\n try {\n await execFileAsync(\n 'git',\n ['worktree', 'remove', '--force', worktreePath],\n { cwd:repoRoot }\n )\n } catch {\n // directory may not be a registered worktree anymore;\n // prune stale entries below and let worktree add fail\n // loudly if the path is still unusable\n }\n }\n\n try {\n await execFileAsync(\n 'git',\n ['worktree', 'prune'],\n { cwd:repoRoot }\n )\n } catch {\n // best-effort cleanup of stale worktree metadata\n }\n\n if (await branchExists(repoRoot, branchName)) {\n await execFileAsync(\n 'git',\n ['branch', '-D', branchName],\n { cwd:repoRoot }\n )\n }\n\n await execFileAsync(\n 'git',\n [\n 'worktree',\n 'add',\n '-b',\n branchName,\n worktreePath,\n baseBranch,\n ],\n { cwd:repoRoot }\n )\n\n return { worktreePath, branchName }\n}\n\nlet worktreeQueue:Promise<unknown> = Promise.resolve()\n\nexport function createWorktree (\n opts:{\n repoRoot:string\n repoName:string\n baseBranch:string\n ticket:Ticket\n }\n):Promise<{ worktreePath:string; branchName:string }> {\n const result = worktreeQueue.then(() => createWorktreeNow(opts))\n worktreeQueue = result.catch(() => {})\n return result\n}\n\nasync function removeWorktreeNow (\n worktreePath:string,\n opts?:{ force?:boolean }\n):Promise<void> {\n const args = [\n '-C', worktreePath,\n 'worktree', 'remove',\n ]\n if (opts?.force) args.push('--force')\n args.push(worktreePath)\n await execFileAsync('git', args)\n}\n\nexport function removeWorktree (\n worktreePath:string,\n opts?:{ force?:boolean }\n):Promise<void> {\n const result = worktreeQueue.then(\n () => removeWorktreeNow(worktreePath, opts)\n )\n worktreeQueue = result.catch(() => {})\n return result\n}\n\nexport function hasNewCommits (\n repoRoot:string,\n base:string,\n branch:string\n):boolean {\n const stdout = execFileSync(\n 'git',\n ['rev-list', '--count', `${base}..${branch}`],\n { cwd:repoRoot, encoding:'utf8' }\n )\n return Number(stdout.trim()) > 0\n}\n\nexport function isDirty (cwd:string):boolean {\n const stdout = execFileSync(\n 'git',\n ['status', '--porcelain'],\n { cwd, encoding:'utf8' }\n )\n return stdout.trim().length > 0\n}\n\nexport async function commitDirty (\n cwd:string,\n message?:string\n):Promise<boolean> {\n if (!isDirty(cwd)) return false\n await execFileAsync(\n 'git',\n ['add', '-A'],\n { cwd }\n )\n try {\n await execFileAsync(\n 'git',\n [\n 'commit', '-m',\n message ??\n 'nightralph: auto-commit ' +\n 'remaining changes',\n ],\n { cwd }\n )\n return true\n } catch {\n return false\n }\n}\n\nexport async function listWorktrees (\n repoRoot:string\n):Promise<Array<string>> {\n const { stdout } = await execFileAsync(\n 'git',\n ['worktree', 'list', '--porcelain'],\n { cwd:repoRoot }\n )\n return stdout\n .trim()\n .split('\\n')\n .filter(line => line.startsWith('worktree '))\n .map(line => line.substring('worktree '.length))\n}\n"],
|
|
5
|
-
"mappings": ";;AAAA,SAAS,UAAU,oBAAoB;AACvC,SAAS,iBAAiB;AAC1B,SAAS,UAAU,SAAS,MAAM,eAAe;AACjD,SAAS,kBAAkB;AAG3B,MAAM,gBAAgB,UAAU,QAAQ;AAEjC,SAAS,cAAsB;AAClC,QAAM,SAAS;AAAA,IACX;AAAA,IACA,CAAC,aAAa,iBAAiB;AAAA,IAC/B,EAAE,UAAS,OAAO;AAAA,EACtB;AACA,SAAO,OAAO,KAAK;AACvB;AAPgB;AAST,SAAS,cAAsB;AAClC,QAAM,YAAY;AAAA,IACd;AAAA,IACA,CAAC,aAAa,kBAAkB;AAAA,IAChC,EAAE,UAAS,OAAO;AAAA,EACtB,EAAE,KAAK;AACP,SAAO,SAAS,QAAQ,QAAQ,SAAS,CAAC,CAAC;AAC/C;AAPgB;AAST,SAAS,
|
|
4
|
+
"sourcesContent": ["import { execFile, execFileSync } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { basename, dirname, join, resolve } from 'node:path'\nimport { existsSync } from 'node:fs'\nimport type { Ticket } from './orchestrator.js'\n\nconst execFileAsync = promisify(execFile)\n\nexport function getRepoRoot ():string {\n const stdout = execFileSync(\n 'git',\n ['rev-parse', '--show-toplevel'],\n { encoding:'utf8' }\n )\n return stdout.trim()\n}\n\nexport function getRepoName ():string {\n const commonDir = execFileSync(\n 'git',\n ['rev-parse', '--git-common-dir'],\n { encoding:'utf8' }\n ).trim()\n return basename(dirname(resolve(commonDir)))\n}\n\nexport function getCurrentBranch (cwd?:string):string {\n const stdout = execFileSync(\n 'git',\n ['rev-parse', '--abbrev-ref', 'HEAD'],\n { cwd, encoding:'utf8' }\n )\n return stdout.trim()\n}\n\nexport function localBranchExists (\n repoRoot:string,\n name:string\n):boolean {\n try {\n execFileSync(\n 'git',\n ['show-ref', '--verify', '--quiet', `refs/heads/${name}`],\n { cwd:repoRoot, stdio:'ignore' }\n )\n return true\n } catch {\n return false\n }\n}\n\n// The repo's default branch: what origin/HEAD points at, else a\n// local main or master, else null.\nexport function getDefaultBranch (repoRoot:string):string|null {\n try {\n const ref = execFileSync(\n 'git',\n [\n 'symbolic-ref', '--quiet', '--short',\n 'refs/remotes/origin/HEAD',\n ],\n {\n cwd:repoRoot,\n encoding:'utf8',\n stdio:['ignore', 'pipe', 'ignore'],\n }\n ).trim()\n if (ref) return ref.replace(/^origin\\//, '')\n } catch {\n // no origin/HEAD\n }\n for (const name of ['main', 'master']) {\n if (localBranchExists(repoRoot, name)) return name\n }\n return null\n}\n\n// Uses `--` rather than `/` for the same reason as\n// buildBranchName: refs/heads/X/Y cannot coexist with\n// refs/heads/X.\nexport function integrationBranchName (\n features:ReadonlyArray<string>\n):string {\n const distinct = [...new Set(features.filter(Boolean))]\n return distinct.length === 1 ?\n `nightralph--${distinct[0]}` :\n 'nightralph--all'\n}\n\n// The integration branch to use, or null to merge into the\n// current branch as before. Only a run launched from the default\n// branch gets one.\nexport function planIntegrationBranch (\n current:string,\n defaultBranch:string|null,\n features:ReadonlyArray<string>\n):string|null {\n if (!defaultBranch || current === 'HEAD') return null\n if (current !== defaultBranch) return null\n return integrationBranchName(features)\n}\n\nexport type IntegrationPlan = {\n // where this run's work lands\n branch:string\n created:boolean\n resumed:boolean\n // commits on the launch branch that `branch` lacks\n behind:number\n // true when a resumed branch that was already contained in the\n // launch branch was moved up to it\n fastForwarded:boolean\n launchBranch:string\n // the default branch when `branch` is an integration branch,\n // else null; the review falls back to its merge-base\n forkedFrom:string|null\n}\n\nfunction gitText (cwd:string, args:string[]):string {\n return execFileSync('git', args, { cwd, encoding:'utf8' }).trim()\n}\n\n// Enters the integration branch when the run was launched from\n// the default branch, creating it or resuming it. Callers must\n// scan tickets after this, since ticket statuses live on the\n// branch it checks out.\nexport function prepareIntegrationBranch (\n repoRoot:string,\n features:ReadonlyArray<string>\n):IntegrationPlan {\n const current = getCurrentBranch(repoRoot)\n const defaultBranch = getDefaultBranch(repoRoot)\n const name = planIntegrationBranch(\n current, defaultBranch, features\n )\n if (!name) {\n const onIntegration = defaultBranch !== null &&\n current === integrationBranchName(features)\n return {\n branch:current,\n created:false,\n resumed:false,\n behind:0,\n fastForwarded:false,\n launchBranch:current,\n forkedFrom:onIntegration ? defaultBranch : null,\n }\n }\n if (isDirty(repoRoot)) {\n throw new Error(\n 'Working tree is dirty; commit or stash ' +\n 'changes before running'\n )\n }\n if (localBranchExists(repoRoot, name)) {\n // Merged into the launch branch already: nothing of its own\n // to lose, so bring it up to date\n const contained = isAncestor(repoRoot, name, current)\n gitText(repoRoot, ['checkout', '--quiet', name])\n let behind = Number(gitText(\n repoRoot, ['rev-list', '--count', `${name}..${current}`]\n ))\n const fastForwarded = contained && behind > 0\n if (fastForwarded) {\n gitText(repoRoot, ['merge', '--ff-only', '--quiet', current])\n behind = 0\n }\n return {\n branch:name,\n created:false,\n resumed:true,\n behind,\n fastForwarded,\n launchBranch:current,\n forkedFrom:defaultBranch,\n }\n }\n gitText(repoRoot, ['checkout', '--quiet', '-b', name])\n return {\n branch:name,\n created:true,\n resumed:false,\n behind:0,\n fastForwarded:false,\n launchBranch:current,\n forkedFrom:defaultBranch,\n }\n}\n\n// What prepareIntegrationBranch would do, for --dry-run.\nexport function describeIntegrationBranch (\n repoRoot:string,\n features:ReadonlyArray<string>\n):string {\n const current = getCurrentBranch(repoRoot)\n const name = planIntegrationBranch(\n current, getDefaultBranch(repoRoot), features\n )\n if (!name) return `Branch: merges into ${current}`\n return localBranchExists(repoRoot, name) ?\n `Branch: would resume ${name}` :\n `Branch: would create ${name} from ${current}`\n}\n\nasync function branchExists (\n repoRoot:string,\n branchName:string\n):Promise<boolean> {\n try {\n await execFileAsync(\n 'git',\n ['show-ref', '--verify', '--quiet', `refs/heads/${branchName}`],\n { cwd:repoRoot }\n )\n return true\n } catch {\n return false\n }\n}\n\nexport function buildBranchName (\n repoName:string,\n ticket:Ticket\n):string {\n const num = String(ticket.num).padStart(2, '0')\n const prefix = ticket.feature ?\n `${ticket.feature}-` :\n ''\n return `${repoName}--${prefix}${num}-${ticket.slug}`\n}\n\nasync function removeWorktreeNow (\n worktreePath:string,\n opts?:{ force?:boolean }\n):Promise<void> {\n const args = [\n '-C', worktreePath,\n 'worktree', 'remove',\n ]\n if (opts?.force) args.push('--force')\n args.push(worktreePath)\n await execFileAsync('git', args)\n}\n\n// Creates a worktree on a fresh branch, first clearing any stale\n// worktree at the path and any leftover branch of the same name,\n// so re-running after a failed run is safe.\nasync function addWorktreeNow (opts:{\n repoRoot:string\n baseBranch:string\n branchName:string\n worktreePath:string\n}):Promise<{ worktreePath:string; branchName:string }> {\n const { repoRoot, baseBranch, branchName, worktreePath } = opts\n\n if (existsSync(worktreePath)) {\n try {\n await execFileAsync(\n 'git',\n ['worktree', 'remove', '--force', worktreePath],\n { cwd:repoRoot }\n )\n } catch {\n // directory may not be a registered worktree anymore;\n // prune stale entries below and let worktree add fail\n // loudly if the path is still unusable\n }\n }\n\n try {\n await execFileAsync(\n 'git',\n ['worktree', 'prune'],\n { cwd:repoRoot }\n )\n } catch {\n // best-effort cleanup of stale worktree metadata\n }\n\n if (await branchExists(repoRoot, branchName)) {\n await execFileAsync(\n 'git',\n ['branch', '-D', branchName],\n { cwd:repoRoot }\n )\n }\n\n await execFileAsync(\n 'git',\n [\n 'worktree',\n 'add',\n '-b',\n branchName,\n worktreePath,\n baseBranch,\n ],\n { cwd:repoRoot }\n )\n\n return { worktreePath, branchName }\n}\n\nlet worktreeQueue:Promise<unknown> = Promise.resolve()\n\n// Serializes every worktree and branch mutation module-wide, so\n// concurrent calls cannot race on shared git refs or on\n// .git/worktrees metadata.\nfunction enqueue<T> (fn:() => Promise<T>):Promise<T> {\n const result = worktreeQueue.then(fn)\n worktreeQueue = result.catch(() => {})\n return result\n}\n\nexport function createWorktree (\n opts:{\n repoRoot:string\n repoName:string\n baseBranch:string\n ticket:Ticket\n }\n):Promise<{ worktreePath:string; branchName:string }> {\n const { repoRoot, repoName, ticket } = opts\n const num = String(ticket.num).padStart(2, '0')\n const prefix = ticket.feature ?\n `${ticket.feature}-` :\n ''\n return enqueue(() => addWorktreeNow({\n repoRoot,\n baseBranch:opts.baseBranch,\n branchName:buildBranchName(repoName, ticket),\n worktreePath:join(\n repoRoot,\n '..',\n `${repoName}.${prefix}${num}-${ticket.slug}`\n ),\n }))\n}\n\n// A worktree that belongs to no ticket, e.g. the review pass:\n// `<repo>.<name>` on branch `<repo>--<name>`. Ticket branches\n// always carry a number, so the names cannot collide.\nexport function createNamedWorktree (\n opts:{\n repoRoot:string\n repoName:string\n baseBranch:string\n name:string\n }\n):Promise<{ worktreePath:string; branchName:string }> {\n const { repoRoot, repoName, name } = opts\n return enqueue(() => addWorktreeNow({\n repoRoot,\n baseBranch:opts.baseBranch,\n branchName:`${repoName}--${name}`,\n worktreePath:join(repoRoot, '..', `${repoName}.${name}`),\n }))\n}\n\nexport function removeWorktree (\n worktreePath:string,\n opts?:{ force?:boolean }\n):Promise<void> {\n return enqueue(() => removeWorktreeNow(worktreePath, opts))\n}\n\n// Deletes a local branch; a missing branch is not an error.\nexport function deleteBranch (\n repoRoot:string,\n name:string\n):Promise<void> {\n return enqueue(async () => {\n if (!(await branchExists(repoRoot, name))) return\n await execFileAsync(\n 'git', ['branch', '-D', name], { cwd:repoRoot }\n )\n })\n}\n\nexport function hasNewCommits (\n repoRoot:string,\n base:string,\n branch:string\n):boolean {\n const stdout = execFileSync(\n 'git',\n ['rev-list', '--count', `${base}..${branch}`],\n { cwd:repoRoot, encoding:'utf8' }\n )\n return Number(stdout.trim()) > 0\n}\n\nexport function headCommit (cwd:string):string {\n return gitText(cwd, ['rev-parse', 'HEAD'])\n}\n\nexport function mergeBase (\n cwd:string,\n a:string,\n b:string\n):string|null {\n try {\n return gitText(cwd, ['merge-base', a, b]) || null\n } catch {\n return null\n }\n}\n\n// False when `ancestor` is not an ancestor of `of`, or is not a\n// commit this repo knows.\nexport function isAncestor (\n cwd:string,\n ancestor:string,\n of:string\n):boolean {\n try {\n execFileSync(\n 'git',\n ['merge-base', '--is-ancestor', ancestor, of],\n { cwd, stdio:'ignore' }\n )\n return true\n } catch {\n return false\n }\n}\n\n// True when from..to changes any path outside `excludeDir`.\nexport function hasChangesOutside (\n cwd:string,\n from:string,\n to:string,\n excludeDir:string\n):boolean {\n try {\n execFileSync(\n 'git',\n [\n 'diff', '--quiet', `${from}..${to}`,\n '--', '.', `:(exclude)${excludeDir}`,\n ],\n { cwd, stdio:'ignore' }\n )\n return false\n } catch {\n return true\n }\n}\n\nexport function isDirty (cwd:string):boolean {\n const stdout = execFileSync(\n 'git',\n ['status', '--porcelain'],\n { cwd, encoding:'utf8' }\n )\n return stdout.trim().length > 0\n}\n\nexport async function commitDirty (\n cwd:string,\n message?:string\n):Promise<boolean> {\n if (!isDirty(cwd)) return false\n await execFileAsync(\n 'git',\n ['add', '-A'],\n { cwd }\n )\n try {\n await execFileAsync(\n 'git',\n [\n 'commit', '-m',\n message ??\n 'nightralph: auto-commit ' +\n 'remaining changes',\n ],\n { cwd }\n )\n return true\n } catch {\n return false\n }\n}\n\nexport async function listWorktrees (\n repoRoot:string\n):Promise<Array<string>> {\n const { stdout } = await execFileAsync(\n 'git',\n ['worktree', 'list', '--porcelain'],\n { cwd:repoRoot }\n )\n return stdout\n .trim()\n .split('\\n')\n .filter(line => line.startsWith('worktree '))\n .map(line => line.substring('worktree '.length))\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nightralph",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.54",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Orchestrator that runs a single-agent session per issue.",
|
|
6
6
|
"bin": {
|
|
@@ -17,15 +17,16 @@
|
|
|
17
17
|
"lint": "eslint \"./**/*.{ts,js}\"",
|
|
18
18
|
"start": "npm run build && node dist/index.js",
|
|
19
19
|
"build": "mkdir -p ./dist && rm -rf ./dist/* && npm run build-esm && npm run copy",
|
|
20
|
-
"build-esm": "esbuild src/index.ts --bundle --format=esm --platform=node --packages=external --metafile=dist/meta.json --keep-names --tsconfig=tsconfig.build.json --outfile=./dist/index.js --sourcemap && esbuild src/orchestrator.ts src/setup.ts src/resolve.ts src/worktree.ts src/progress.ts src/merge.ts src/display.ts src/testcmd.ts --format=esm --keep-names --tsconfig=tsconfig.build.json --outdir=./dist --sourcemap && tsc --emitDeclarationOnly --project tsconfig.build.json",
|
|
20
|
+
"build-esm": "esbuild src/index.ts --bundle --format=esm --platform=node --packages=external --metafile=dist/meta.json --keep-names --tsconfig=tsconfig.build.json --outfile=./dist/index.js --sourcemap && esbuild src/orchestrator.ts src/setup.ts src/resolve.ts src/worktree.ts src/progress.ts src/merge.ts src/display.ts src/testcmd.ts src/preflight.ts src/learnings.ts src/retry.ts src/rules.ts src/review.ts --format=esm --keep-names --tsconfig=tsconfig.build.json --outdir=./dist --sourcemap && tsc --emitDeclarationOnly --project tsconfig.build.json",
|
|
21
21
|
"copy": "mkdir -p ./dist/skills ./dist/docs-templates && cp -r ./src/skills/* ./dist/skills && cp -r ./src/docs-templates/* ./dist/docs-templates",
|
|
22
22
|
"clone-skills": "bash scripts/clone-skills.sh",
|
|
23
23
|
"toc": "markdown-toc --maxdepth 4 -i README.md",
|
|
24
24
|
"preversion": "npm run lint",
|
|
25
|
+
"prepublishOnly": "npm run build",
|
|
25
26
|
"version": "npm run toc && git add README.md",
|
|
26
|
-
"postversion": "git push --follow-tags
|
|
27
|
+
"postversion": "npm publish && git push --follow-tags",
|
|
27
28
|
"demo": "npm run build && node test/demo-display.mjs",
|
|
28
|
-
"test": "
|
|
29
|
+
"test": "bash scripts/test.sh"
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"@inquirer/prompts": "^8.7.0",
|