@tsuzuku/arise 1.0.1 → 1.1.1
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/index.js +2 -1
- package/lib/cli.js +4 -0
- package/lib/config.js +55 -2
- package/lib/git.js +8 -0
- package/lib/herdr.js +100 -0
- package/lib/lifecycle/create.js +23 -13
- package/lib/lifecycle/nuke.js +16 -11
- package/package.json +1 -2
- package/types.d.ts +1 -0
- package/worktree.schema.json +0 -130
package/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const pkg = require('./package.json');
|
|
1
2
|
const { parseArgs, showUsage } = require('./lib/cli');
|
|
2
3
|
const { resolveConfiguration } = require('./lib/config');
|
|
3
4
|
const { executeCreate } = require('./lib/lifecycle/create');
|
|
@@ -12,7 +13,7 @@ async function run(argv = process.argv.slice(2), cwd = process.cwd()) {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
if (flags.showVersion) {
|
|
15
|
-
console.log(
|
|
16
|
+
console.log(`arise v${pkg.version}`);
|
|
16
17
|
process.exit(0);
|
|
17
18
|
}
|
|
18
19
|
|
package/lib/cli.js
CHANGED
|
@@ -33,6 +33,7 @@ Agent Skill Arguments:
|
|
|
33
33
|
--local, --workspace Install skill locally to current workspace (.agents/skills).
|
|
34
34
|
|
|
35
35
|
General Arguments:
|
|
36
|
+
--yes, -y (Optional) Automatically answer yes to confirmation prompts (e.g. installing Herdr).
|
|
36
37
|
--help, -h Show this help message.
|
|
37
38
|
--version, -v Show version information.
|
|
38
39
|
`);
|
|
@@ -45,6 +46,7 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
45
46
|
dirOnly: false,
|
|
46
47
|
keepRemote: false,
|
|
47
48
|
force: false,
|
|
49
|
+
yes: false,
|
|
48
50
|
branch: null,
|
|
49
51
|
dirname: null,
|
|
50
52
|
workspaceName: null,
|
|
@@ -84,6 +86,8 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
84
86
|
flags.keepRemote = true;
|
|
85
87
|
} else if (arg === '--force' || arg === '-f') {
|
|
86
88
|
flags.force = true;
|
|
89
|
+
} else if (arg === '--yes' || arg === '-y') {
|
|
90
|
+
flags.yes = true;
|
|
87
91
|
} else if (arg === '--branch' || arg === '-b') {
|
|
88
92
|
flags.branch = argv[i + 1];
|
|
89
93
|
i++;
|
package/lib/config.js
CHANGED
|
@@ -70,7 +70,56 @@ function loadConfigFile(filePath) {
|
|
|
70
70
|
|
|
71
71
|
function resolveConfiguration(flags = {}, cwd = process.cwd()) {
|
|
72
72
|
const repoRoot = git.getRepoRootDir(cwd);
|
|
73
|
-
const
|
|
73
|
+
const searchDirs = [];
|
|
74
|
+
|
|
75
|
+
const addSearchDir = (dir) => {
|
|
76
|
+
if (dir && !searchDirs.includes(dir)) {
|
|
77
|
+
searchDirs.push(dir);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
let worktrees = [];
|
|
82
|
+
try {
|
|
83
|
+
worktrees = git.getWorktrees({ repoDir: repoRoot });
|
|
84
|
+
} catch (e) {}
|
|
85
|
+
|
|
86
|
+
// 1. Explicit directory if --dirname / -d is passed
|
|
87
|
+
if (flags.dirname) {
|
|
88
|
+
const resolvedDir = path.isAbsolute(flags.dirname)
|
|
89
|
+
? flags.dirname
|
|
90
|
+
: path.resolve(repoRoot || cwd, flags.dirname);
|
|
91
|
+
addSearchDir(resolvedDir);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 2. Directory for the specified branch (--branch / -b)
|
|
95
|
+
if (flags.branch) {
|
|
96
|
+
const matchingWt = worktrees.find((wt) => wt.branch === flags.branch);
|
|
97
|
+
if (matchingWt && matchingWt.path) {
|
|
98
|
+
addSearchDir(matchingWt.path);
|
|
99
|
+
}
|
|
100
|
+
const branchDir = path.resolve(repoRoot || cwd, flags.branch.replace(/\//g, '-'));
|
|
101
|
+
addSearchDir(branchDir);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 3. Current working directory
|
|
105
|
+
addSearchDir(cwd);
|
|
106
|
+
|
|
107
|
+
// 4. Repository root directory
|
|
108
|
+
if (repoRoot) {
|
|
109
|
+
addSearchDir(repoRoot);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 5. Fallback to existing worktrees (prioritizing primary branches like main, master, develop)
|
|
113
|
+
const primaryBranches = ['main', 'master', 'develop', 'prod', 'staging'];
|
|
114
|
+
const primaryWts = worktrees.filter((wt) => !wt.isBare && wt.branch && primaryBranches.includes(wt.branch));
|
|
115
|
+
for (const wt of primaryWts) {
|
|
116
|
+
if (wt.path) addSearchDir(wt.path);
|
|
117
|
+
}
|
|
118
|
+
for (const wt of worktrees) {
|
|
119
|
+
if (wt.path && !wt.isBare) addSearchDir(wt.path);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const configFile = findConfigFile(searchDirs);
|
|
74
123
|
const fileConfig = loadConfigFile(configFile);
|
|
75
124
|
|
|
76
125
|
// 1. Resolve Preset
|
|
@@ -80,7 +129,11 @@ function resolveConfiguration(flags = {}, cwd = process.cwd()) {
|
|
|
80
129
|
preset = getPreset(presetName);
|
|
81
130
|
}
|
|
82
131
|
if (!preset) {
|
|
83
|
-
|
|
132
|
+
const detectDir = (configFile && path.dirname(configFile)) || cwd;
|
|
133
|
+
preset = detectPreset(detectDir);
|
|
134
|
+
if (preset.name === 'generic' && detectDir !== cwd) {
|
|
135
|
+
preset = detectPreset(cwd);
|
|
136
|
+
}
|
|
84
137
|
}
|
|
85
138
|
|
|
86
139
|
// 2. Merge Repo Settings
|
package/lib/git.js
CHANGED
|
@@ -7,6 +7,10 @@ function getGitPrefix(options = {}) {
|
|
|
7
7
|
return `git --git-dir="${options.bareRepo}"`;
|
|
8
8
|
}
|
|
9
9
|
if (options.repoDir) {
|
|
10
|
+
const dotBare = path.join(options.repoDir, '.bare');
|
|
11
|
+
if (fs.existsSync(dotBare)) {
|
|
12
|
+
return `git --git-dir="${dotBare}"`;
|
|
13
|
+
}
|
|
10
14
|
return `git -C "${options.repoDir}"`;
|
|
11
15
|
}
|
|
12
16
|
return 'git';
|
|
@@ -16,6 +20,10 @@ function getRepoRootDir(cwd = process.cwd(), bareRepo = null) {
|
|
|
16
20
|
if (bareRepo && fs.existsSync(bareRepo)) {
|
|
17
21
|
return bareRepo;
|
|
18
22
|
}
|
|
23
|
+
const dotBare = path.join(cwd, '.bare');
|
|
24
|
+
if (fs.existsSync(dotBare)) {
|
|
25
|
+
return cwd;
|
|
26
|
+
}
|
|
19
27
|
try {
|
|
20
28
|
const commonDir = execSync('git rev-parse --git-common-dir', { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
21
29
|
const absoluteCommonDir = path.isAbsolute(commonDir) ? commonDir : path.resolve(cwd, commonDir);
|
package/lib/herdr.js
CHANGED
|
@@ -1,4 +1,101 @@
|
|
|
1
1
|
const { execSync, spawnSync } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const readline = require('readline');
|
|
5
|
+
|
|
6
|
+
function isCommandAvailable(cmd) {
|
|
7
|
+
try {
|
|
8
|
+
const checkCmd = process.platform === 'win32' ? `where ${cmd}` : `command -v ${cmd}`;
|
|
9
|
+
execSync(checkCmd, { stdio: 'ignore' });
|
|
10
|
+
return true;
|
|
11
|
+
} catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isHerdrInstalled() {
|
|
17
|
+
const localBin = path.join(os.homedir(), '.local', 'bin');
|
|
18
|
+
if (process.env.PATH && !process.env.PATH.split(path.delimiter).includes(localBin)) {
|
|
19
|
+
process.env.PATH = `${localBin}${path.delimiter}${process.env.PATH}`;
|
|
20
|
+
}
|
|
21
|
+
return isCommandAvailable('herdr');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getRecommendedInstallCommand() {
|
|
25
|
+
if (process.platform === 'darwin' && isCommandAvailable('brew')) {
|
|
26
|
+
return {
|
|
27
|
+
name: 'Homebrew',
|
|
28
|
+
cmd: 'brew install herdr',
|
|
29
|
+
docsUrl: 'https://herdr.dev/docs/install/#install-with-homebrew',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (isCommandAvailable('mise')) {
|
|
33
|
+
return {
|
|
34
|
+
name: 'mise',
|
|
35
|
+
cmd: 'mise use -g herdr',
|
|
36
|
+
docsUrl: 'https://herdr.dev/docs/install/#install-with-mise',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (process.platform === 'win32') {
|
|
40
|
+
return {
|
|
41
|
+
name: 'PowerShell Installer',
|
|
42
|
+
cmd: 'powershell -ExecutionPolicy Bypass -c "irm https://herdr.dev/install.ps1 | iex"',
|
|
43
|
+
docsUrl: 'https://herdr.dev/docs/install/',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
name: 'Official Install Script',
|
|
48
|
+
cmd: 'curl -fsSL https://herdr.dev/install.sh | sh',
|
|
49
|
+
docsUrl: 'https://herdr.dev/docs/install/',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function promptUser(question) {
|
|
54
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
55
|
+
return new Promise((resolve) => {
|
|
56
|
+
rl.question(question, (answer) => {
|
|
57
|
+
rl.close();
|
|
58
|
+
resolve(answer.trim());
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function ensureHerdrInstalled(options = {}) {
|
|
64
|
+
if (isHerdrInstalled()) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const { name, cmd, docsUrl } = getRecommendedInstallCommand();
|
|
69
|
+
const autoConfirm = Boolean(options.yes);
|
|
70
|
+
|
|
71
|
+
if (!autoConfirm && (!process.stdin.isTTY || process.env.CI)) {
|
|
72
|
+
console.error(`\n[arise] Error: "herdr" is required to manage terminal workspaces but was not found in PATH.`);
|
|
73
|
+
console.error(`Please install Herdr before running arise:\n ${cmd}\n`);
|
|
74
|
+
console.error(`Docs: ${docsUrl || 'https://herdr.dev/docs/install/'}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!autoConfirm) {
|
|
79
|
+
console.log(`\n[arise] "herdr" is required to manage terminal workspaces but was not found in PATH.`);
|
|
80
|
+
const answer = await promptUser(`Would you like arise to install Herdr now via ${name} (\`${cmd}\`)? [Y/n]: `);
|
|
81
|
+
if (answer && !/^(y|yes)$/i.test(answer)) {
|
|
82
|
+
console.error('\nCannot proceed without Herdr. Aborting.');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log(`\n==> Installing Herdr via ${name}...`);
|
|
88
|
+
const result = spawnSync(cmd, { stdio: 'inherit', shell: true });
|
|
89
|
+
|
|
90
|
+
if (result.status !== 0 || !isHerdrInstalled()) {
|
|
91
|
+
console.error(`\n[arise] Failed to automatically install Herdr.`);
|
|
92
|
+
console.error(`Please visit https://herdr.dev/docs/install/ to install manually.`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log(`[arise] Herdr installed successfully!\n`);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
2
99
|
|
|
3
100
|
function parseJsonFromOutput(output) {
|
|
4
101
|
if (!output) return null;
|
|
@@ -105,6 +202,9 @@ function attachOrSwitchSession(sessionName) {
|
|
|
105
202
|
}
|
|
106
203
|
|
|
107
204
|
module.exports = {
|
|
205
|
+
isHerdrInstalled,
|
|
206
|
+
getRecommendedInstallCommand,
|
|
207
|
+
ensureHerdrInstalled,
|
|
108
208
|
listWorkspaces,
|
|
109
209
|
createWorkspace,
|
|
110
210
|
closeWorkspace,
|
package/lib/lifecycle/create.js
CHANGED
|
@@ -4,6 +4,7 @@ const git = require('../git');
|
|
|
4
4
|
const herdr = require('../herdr');
|
|
5
5
|
const layout = require('../layout');
|
|
6
6
|
const { createContext } = require('../context');
|
|
7
|
+
const { resolveConfiguration } = require('../config');
|
|
7
8
|
const { showUsage } = require('../cli');
|
|
8
9
|
|
|
9
10
|
async function executeCreate(flags, config, cwd = process.cwd()) {
|
|
@@ -24,8 +25,8 @@ async function executeCreate(flags, config, cwd = process.cwd()) {
|
|
|
24
25
|
|
|
25
26
|
// 2. Resolve Session / Workspace Name
|
|
26
27
|
const baseWorkspace = flags.workspaceName || dirname.replace(/[\s.:]/g, '_');
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
let prefix = config.workspace.labelPrefix || '';
|
|
29
|
+
let sessionName = (prefix && !baseWorkspace.startsWith(prefix.trim()))
|
|
29
30
|
? `${prefix}${baseWorkspace}`
|
|
30
31
|
: baseWorkspace;
|
|
31
32
|
|
|
@@ -69,28 +70,37 @@ async function executeCreate(flags, config, cwd = process.cwd()) {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
// 5.
|
|
73
|
+
// 5. Re-resolve config using target worktree directory for branch-specific overrides
|
|
74
|
+
const activeConfig = resolveConfiguration(flags, worktreePathToUse);
|
|
75
|
+
prefix = activeConfig.workspace.labelPrefix || '';
|
|
76
|
+
sessionName = (prefix && !baseWorkspace.startsWith(prefix.trim()))
|
|
77
|
+
? `${prefix}${baseWorkspace}`
|
|
78
|
+
: baseWorkspace;
|
|
79
|
+
|
|
80
|
+
// Initialize Context for Hooks
|
|
73
81
|
const ctx = createContext({
|
|
74
82
|
worktreePath: worktreePathToUse,
|
|
75
83
|
repoRoot,
|
|
76
|
-
bareRepo:
|
|
84
|
+
bareRepo: activeConfig.repo.bareRepo,
|
|
77
85
|
branch,
|
|
78
|
-
source: flags.source ||
|
|
86
|
+
source: flags.source || activeConfig.repo.defaultBaseBranch,
|
|
79
87
|
flags,
|
|
80
|
-
preset:
|
|
81
|
-
config,
|
|
88
|
+
preset: activeConfig.preset,
|
|
89
|
+
config: activeConfig,
|
|
82
90
|
});
|
|
83
91
|
|
|
84
92
|
// 6. Run Preset / Config Hooks
|
|
85
|
-
if (typeof
|
|
86
|
-
await
|
|
93
|
+
if (typeof activeConfig.hooks.onSyncPrimary === 'function') {
|
|
94
|
+
await activeConfig.hooks.onSyncPrimary(ctx);
|
|
87
95
|
}
|
|
88
96
|
|
|
89
|
-
if (!worktreeExists && typeof
|
|
90
|
-
await
|
|
97
|
+
if (!worktreeExists && typeof activeConfig.hooks.onScaffold === 'function') {
|
|
98
|
+
await activeConfig.hooks.onScaffold(ctx);
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
// 7. Orchestrate Herdr Workspace
|
|
102
|
+
await herdr.ensureHerdrInstalled({ yes: flags.yes });
|
|
103
|
+
|
|
94
104
|
console.log(`\n==> Creating Herdr workspace "${sessionName}"...`);
|
|
95
105
|
let ws;
|
|
96
106
|
try {
|
|
@@ -103,10 +113,10 @@ async function executeCreate(flags, config, cwd = process.cwd()) {
|
|
|
103
113
|
// 8. Render Terminal Layout
|
|
104
114
|
console.log(`==> Configuring terminal panes...`);
|
|
105
115
|
layout.renderLayout({
|
|
106
|
-
layout:
|
|
116
|
+
layout: activeConfig.layout,
|
|
107
117
|
rootPaneId: ws.rootPaneId,
|
|
108
118
|
cwd: worktreePathToUse,
|
|
109
|
-
focusTarget: flags.focusTarget ||
|
|
119
|
+
focusTarget: flags.focusTarget || activeConfig.workspace.defaultFocus,
|
|
110
120
|
});
|
|
111
121
|
|
|
112
122
|
// Focus the workspace
|
package/lib/lifecycle/nuke.js
CHANGED
|
@@ -4,6 +4,7 @@ const { execSync } = require('child_process');
|
|
|
4
4
|
const git = require('../git');
|
|
5
5
|
const herdr = require('../herdr');
|
|
6
6
|
const { createContext } = require('../context');
|
|
7
|
+
const { resolveConfiguration } = require('../config');
|
|
7
8
|
const { showUsage } = require('../cli');
|
|
8
9
|
|
|
9
10
|
async function executeNuke(flags, config, cwd = process.cwd()) {
|
|
@@ -50,6 +51,10 @@ async function executeNuke(flags, config, cwd = process.cwd()) {
|
|
|
50
51
|
const targetDirname = path.basename(targetWorktreePath);
|
|
51
52
|
const targetSessionName = targetDirname.replace(/[\s.:]/g, '_');
|
|
52
53
|
|
|
54
|
+
const activeConfig = fs.existsSync(targetWorktreePath)
|
|
55
|
+
? resolveConfiguration(flags, targetWorktreePath)
|
|
56
|
+
: config;
|
|
57
|
+
|
|
53
58
|
let targetBranch = flags.branch;
|
|
54
59
|
if (!targetBranch && existingWorktree && existingWorktree.branch) {
|
|
55
60
|
targetBranch = existingWorktree.branch;
|
|
@@ -64,14 +69,14 @@ async function executeNuke(flags, config, cwd = process.cwd()) {
|
|
|
64
69
|
}
|
|
65
70
|
if (!targetBranch) {
|
|
66
71
|
try {
|
|
67
|
-
const gitCmd = git.getGitPrefix({ repoDir: repoRoot, bareRepo:
|
|
72
|
+
const gitCmd = git.getGitPrefix({ repoDir: repoRoot, bareRepo: activeConfig.repo.bareRepo });
|
|
68
73
|
execSync(`${gitCmd} rev-parse --verify "${target}"`, { stdio: 'ignore' });
|
|
69
74
|
targetBranch = target;
|
|
70
75
|
} catch (e) {}
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
console.log(`\n=== Starting Worktree Nuke ===`);
|
|
74
|
-
console.log(`Active Preset: ${
|
|
79
|
+
console.log(`Active Preset: ${activeConfig.preset ? activeConfig.preset.name : 'generic'}`);
|
|
75
80
|
console.log(`Repository Root: ${repoRoot}`);
|
|
76
81
|
console.log(`Target Worktree Path: ${targetWorktreePath}`);
|
|
77
82
|
console.log(`Associated Branch: ${targetBranch || '(None detected)'}`);
|
|
@@ -96,16 +101,16 @@ async function executeNuke(flags, config, cwd = process.cwd()) {
|
|
|
96
101
|
const ctx = createContext({
|
|
97
102
|
worktreePath: targetWorktreePath,
|
|
98
103
|
repoRoot,
|
|
99
|
-
bareRepo:
|
|
104
|
+
bareRepo: activeConfig.repo.bareRepo,
|
|
100
105
|
branch: targetBranch,
|
|
101
106
|
flags,
|
|
102
|
-
preset:
|
|
103
|
-
config,
|
|
107
|
+
preset: activeConfig.preset,
|
|
108
|
+
config: activeConfig,
|
|
104
109
|
});
|
|
105
110
|
|
|
106
111
|
// Pre-Nuke Hook
|
|
107
|
-
if (typeof
|
|
108
|
-
await
|
|
112
|
+
if (typeof activeConfig.hooks.onPreNuke === 'function') {
|
|
113
|
+
await activeConfig.hooks.onPreNuke(ctx);
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
// 1. Remove Worktree & Directory
|
|
@@ -139,12 +144,12 @@ async function executeNuke(flags, config, cwd = process.cwd()) {
|
|
|
139
144
|
// Helper for final cleanup steps (Herdr workspace close + Post-Nuke hook)
|
|
140
145
|
const finishCleanup = async () => {
|
|
141
146
|
// Post-Nuke Hook
|
|
142
|
-
if (typeof
|
|
143
|
-
await
|
|
147
|
+
if (typeof activeConfig.hooks.onPostNuke === 'function') {
|
|
148
|
+
await activeConfig.hooks.onPostNuke(ctx);
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
// Close Herdr Workspace if running (performed last so active pane is not terminated mid-cleanup)
|
|
147
|
-
const prefix =
|
|
152
|
+
const prefix = activeConfig.workspace.labelPrefix || '';
|
|
148
153
|
const matchTargets = [
|
|
149
154
|
targetSessionName,
|
|
150
155
|
targetDirname,
|
|
@@ -165,7 +170,7 @@ async function executeNuke(flags, config, cwd = process.cwd()) {
|
|
|
165
170
|
return;
|
|
166
171
|
}
|
|
167
172
|
|
|
168
|
-
const protectedBranches =
|
|
173
|
+
const protectedBranches = activeConfig.repo.protectedBranches || ['main', 'master', 'develop', 'prod', 'staging', 'production'];
|
|
169
174
|
if (targetBranch && protectedBranches.includes(targetBranch)) {
|
|
170
175
|
console.warn(`\n==> WARNING: "${targetBranch}" is a protected branch. Skipping local and remote branch deletion.`);
|
|
171
176
|
await finishCleanup();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsuzuku/arise",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"index.js",
|
|
21
21
|
"types.d.ts",
|
|
22
22
|
"arise.schema.json",
|
|
23
|
-
"worktree.schema.json",
|
|
24
23
|
"README.md"
|
|
25
24
|
],
|
|
26
25
|
"engines": {
|
package/types.d.ts
CHANGED
package/worktree.schema.json
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"title": "HerdrWorktreeConfig",
|
|
4
|
-
"description": "Configuration schema for Herdr Worktree (.worktreerc.json)",
|
|
5
|
-
"type": "object",
|
|
6
|
-
"properties": {
|
|
7
|
-
"preset": {
|
|
8
|
-
"type": "string",
|
|
9
|
-
"description": "Preset name to use ('node', 'laravel', 'generic' or custom registered preset)"
|
|
10
|
-
},
|
|
11
|
-
"repo": {
|
|
12
|
-
"type": "object",
|
|
13
|
-
"description": "Repository topology and branch configuration",
|
|
14
|
-
"properties": {
|
|
15
|
-
"bareRepo": {
|
|
16
|
-
"type": ["string", "null"],
|
|
17
|
-
"description": "Path to bare git repository (e.g. '/path/to/bare/repo.git')"
|
|
18
|
-
},
|
|
19
|
-
"worktreesBase": {
|
|
20
|
-
"type": ["string", "null"],
|
|
21
|
-
"description": "Base directory where worktrees should be placed (e.g. '/path/to/worktrees')"
|
|
22
|
-
},
|
|
23
|
-
"defaultBaseBranch": {
|
|
24
|
-
"type": "string",
|
|
25
|
-
"description": "Default base branch to branch off (e.g. 'develop', 'prod', 'main')"
|
|
26
|
-
},
|
|
27
|
-
"protectedBranches": {
|
|
28
|
-
"type": "array",
|
|
29
|
-
"items": { "type": "string" },
|
|
30
|
-
"description": "Array of branch names protected against deletion during --nuke"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"additionalProperties": false
|
|
34
|
-
},
|
|
35
|
-
"workspace": {
|
|
36
|
-
"type": "object",
|
|
37
|
-
"description": "Herdr workspace naming, agent, and focus configuration",
|
|
38
|
-
"properties": {
|
|
39
|
-
"labelPrefix": {
|
|
40
|
-
"type": "string",
|
|
41
|
-
"description": "Prefix added to Herdr workspace labels (e.g. '[BE] ')"
|
|
42
|
-
},
|
|
43
|
-
"agent": {
|
|
44
|
-
"type": ["string", "object", "null"],
|
|
45
|
-
"description": "CLI AI agent to run in the workspace pane ('agy', 'claude', 'aider', 'copilot', 'none', or custom command object)",
|
|
46
|
-
"properties": {
|
|
47
|
-
"cmd": {
|
|
48
|
-
"type": ["string", "null"],
|
|
49
|
-
"description": "Command to execute the agent"
|
|
50
|
-
},
|
|
51
|
-
"title": {
|
|
52
|
-
"type": "string",
|
|
53
|
-
"description": "Display title for the agent pane in Herdr"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
"defaultFocus": {
|
|
58
|
-
"type": "string",
|
|
59
|
-
"description": "Default pane to focus upon creation ('agent', 'agy', 'claude', 'vim', 'logs', 'server', 'shell')"
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
"additionalProperties": false
|
|
63
|
-
},
|
|
64
|
-
"layout": {
|
|
65
|
-
"type": "array",
|
|
66
|
-
"description": "Declarative 4-pane quadrant layout definitions",
|
|
67
|
-
"items": {
|
|
68
|
-
"type": "object",
|
|
69
|
-
"required": ["id", "title"],
|
|
70
|
-
"properties": {
|
|
71
|
-
"id": {
|
|
72
|
-
"type": "string",
|
|
73
|
-
"description": "Unique identifier for this pane within the layout"
|
|
74
|
-
},
|
|
75
|
-
"title": {
|
|
76
|
-
"type": "string",
|
|
77
|
-
"description": "Title displayed on the Herdr pane"
|
|
78
|
-
},
|
|
79
|
-
"cmd": {
|
|
80
|
-
"type": ["string", "null"],
|
|
81
|
-
"description": "Command to run when pane is opened (e.g. 'vim .', 'npm run dev', 'tail -f ...')"
|
|
82
|
-
},
|
|
83
|
-
"position": {
|
|
84
|
-
"type": "string",
|
|
85
|
-
"enum": ["root"],
|
|
86
|
-
"description": "Set to 'root' for the initial root pane"
|
|
87
|
-
},
|
|
88
|
-
"from": {
|
|
89
|
-
"type": "string",
|
|
90
|
-
"description": "ID of parent pane to split from"
|
|
91
|
-
},
|
|
92
|
-
"split": {
|
|
93
|
-
"type": "string",
|
|
94
|
-
"enum": ["right", "down"],
|
|
95
|
-
"description": "Split direction ('right' or 'down')"
|
|
96
|
-
},
|
|
97
|
-
"focus": {
|
|
98
|
-
"type": "boolean",
|
|
99
|
-
"description": "Whether this pane should receive focus by default"
|
|
100
|
-
},
|
|
101
|
-
"isAgent": {
|
|
102
|
-
"type": "boolean",
|
|
103
|
-
"description": "Whether this pane is designated as the AI CLI agent pane"
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
"additionalProperties": false
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
"scaffold": {
|
|
110
|
-
"type": "object",
|
|
111
|
-
"description": "Scaffolding options (environment files, symlinks, dependency installation, etc.)",
|
|
112
|
-
"properties": {
|
|
113
|
-
"envSource": {
|
|
114
|
-
"type": ["string", "null"],
|
|
115
|
-
"description": "Path to .env source file to copy into new worktree"
|
|
116
|
-
},
|
|
117
|
-
"symlink": {
|
|
118
|
-
"type": ["string", "null"],
|
|
119
|
-
"description": "Path to web server symlink to update to active worktree"
|
|
120
|
-
},
|
|
121
|
-
"install": {
|
|
122
|
-
"type": ["string", "boolean", "null"],
|
|
123
|
-
"description": "Command to run to install dependencies upon creation (e.g. 'npm install --legacy-peer-deps', 'pnpm install', 'composer install --no-interaction'), or false/null to skip installation."
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
"additionalProperties": true
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
"additionalProperties": false
|
|
130
|
-
}
|