@dezkareid/osddt 1.11.1 → 1.11.3
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/index.js +51 -54
- package/dist/utils/worktree.d.ts +3 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,10 +3,10 @@ import { Command } from 'commander';
|
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
6
7
|
import select from '@inquirer/select';
|
|
7
8
|
import checkbox from '@inquirer/checkbox';
|
|
8
9
|
import input from '@inquirer/input';
|
|
9
|
-
import { execSync } from 'child_process';
|
|
10
10
|
import readline from 'readline';
|
|
11
11
|
|
|
12
12
|
function getRepoPreamble(npxCommand) {
|
|
@@ -716,39 +716,8 @@ function checkGitVersion() {
|
|
|
716
716
|
return { label: 'Git version >= 2.5', passed: false, detail: 'git not found or not executable' };
|
|
717
717
|
}
|
|
718
718
|
}
|
|
719
|
-
function
|
|
720
|
-
|
|
721
|
-
const gitCommonDir = execSync('git rev-parse --git-common-dir', { cwd, encoding: 'utf-8' }).trim();
|
|
722
|
-
const gitDir = execSync('git rev-parse --git-dir', { cwd, encoding: 'utf-8' }).trim();
|
|
723
|
-
const isWorktree = gitDir !== gitCommonDir && gitDir !== '.git';
|
|
724
|
-
return {
|
|
725
|
-
label: 'Current directory is not a worktree',
|
|
726
|
-
passed: !isWorktree,
|
|
727
|
-
detail: isWorktree
|
|
728
|
-
? `This directory is itself a worktree (git-dir: ${gitDir}). Run setup from the main repository.`
|
|
729
|
-
: 'OK',
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
catch {
|
|
733
|
-
return { label: 'Current directory is not a worktree', passed: false, detail: 'Not inside a git repository' };
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
async function checkTargetWritable(cwd) {
|
|
737
|
-
let targetBase;
|
|
738
|
-
try {
|
|
739
|
-
const repoRoot = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim();
|
|
740
|
-
const rcPath = path.join(repoRoot, '.osddtrc');
|
|
741
|
-
if (await fs.pathExists(rcPath)) {
|
|
742
|
-
const rc = await fs.readJson(rcPath);
|
|
743
|
-
targetBase = rc.worktreeBase ?? path.dirname(repoRoot);
|
|
744
|
-
}
|
|
745
|
-
else {
|
|
746
|
-
targetBase = path.dirname(repoRoot);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
catch {
|
|
750
|
-
return { label: 'Worktree target directory is writable', passed: false, detail: 'Could not resolve repo root' };
|
|
751
|
-
}
|
|
719
|
+
async function checkTargetWritable(barePath) {
|
|
720
|
+
const targetBase = path.dirname(barePath);
|
|
752
721
|
try {
|
|
753
722
|
await fs.access(targetBase, fs.constants.W_OK);
|
|
754
723
|
return { label: 'Worktree target directory is writable', passed: true, detail: `${targetBase} is writable` };
|
|
@@ -757,10 +726,9 @@ async function checkTargetWritable(cwd) {
|
|
|
757
726
|
return { label: 'Worktree target directory is writable', passed: false, detail: `${targetBase} is not writable` };
|
|
758
727
|
}
|
|
759
728
|
}
|
|
760
|
-
async function initStateFile(
|
|
729
|
+
async function initStateFile(barePath) {
|
|
761
730
|
try {
|
|
762
|
-
const
|
|
763
|
-
const stateFile = path.join(path.dirname(repoRoot), '.osddt-worktrees');
|
|
731
|
+
const stateFile = path.join(path.dirname(barePath), '.osddt-worktrees');
|
|
764
732
|
if (!(await fs.pathExists(stateFile))) {
|
|
765
733
|
await fs.writeJson(stateFile, [], { spaces: 2 });
|
|
766
734
|
console.log(` ✓ Initialized worktree state file: ${stateFile}`);
|
|
@@ -780,11 +748,10 @@ function printCheckResult(result) {
|
|
|
780
748
|
console.log(` → ${result.detail}`);
|
|
781
749
|
}
|
|
782
750
|
}
|
|
783
|
-
async function runWorktreeChecks(
|
|
751
|
+
async function runWorktreeChecks(barePath) {
|
|
784
752
|
const results = [
|
|
785
753
|
checkGitVersion(),
|
|
786
|
-
|
|
787
|
-
await checkTargetWritable(cwd),
|
|
754
|
+
await checkTargetWritable(barePath),
|
|
788
755
|
];
|
|
789
756
|
for (const result of results) {
|
|
790
757
|
printCheckResult(result);
|
|
@@ -857,16 +824,25 @@ async function writeAgentFiles(cwd, agents, npxCommand) {
|
|
|
857
824
|
console.log('');
|
|
858
825
|
}
|
|
859
826
|
}
|
|
860
|
-
|
|
827
|
+
function cloneBareRepository(cwd, repositoryUrl) {
|
|
828
|
+
const barePath = path.join(cwd, '.bare');
|
|
829
|
+
console.log(`Cloning bare repository into ${barePath} ...\n`);
|
|
830
|
+
execSync(`git clone --bare "${repositoryUrl}" "${barePath}"`, { stdio: 'inherit' });
|
|
831
|
+
console.log('');
|
|
832
|
+
return barePath;
|
|
833
|
+
}
|
|
834
|
+
async function setupWorktreeEnvironment(cwd, worktreeRepository) {
|
|
835
|
+
const barePath = cloneBareRepository(cwd, worktreeRepository);
|
|
861
836
|
console.log('Checking environment for git worktree support...\n');
|
|
862
|
-
const allPassed = await runWorktreeChecks(
|
|
837
|
+
const allPassed = await runWorktreeChecks(barePath);
|
|
863
838
|
console.log('');
|
|
864
839
|
if (!allPassed) {
|
|
865
840
|
console.log('Some checks failed. Resolve the issues above before using the worktree workflow.');
|
|
866
841
|
process.exit(1);
|
|
867
842
|
}
|
|
868
|
-
await initStateFile(
|
|
843
|
+
await initStateFile(barePath);
|
|
869
844
|
console.log('');
|
|
845
|
+
return barePath;
|
|
870
846
|
}
|
|
871
847
|
async function runSetup(cwd, rawAgents, rawRepoType, rawWorktreeRepository) {
|
|
872
848
|
const agents = rawAgents !== undefined ? parseAgents(rawAgents) : await askAgents();
|
|
@@ -878,8 +854,9 @@ async function runSetup(cwd, rawAgents, rawRepoType, rawWorktreeRepository) {
|
|
|
878
854
|
const worktreeRepository = rawWorktreeRepository !== undefined ? rawWorktreeRepository : (await askWorktreeUrl()) || undefined;
|
|
879
855
|
if (rawWorktreeRepository === undefined)
|
|
880
856
|
console.log('');
|
|
857
|
+
let barePath;
|
|
881
858
|
if (worktreeRepository) {
|
|
882
|
-
await setupWorktreeEnvironment(cwd);
|
|
859
|
+
barePath = await setupWorktreeEnvironment(cwd, worktreeRepository);
|
|
883
860
|
}
|
|
884
861
|
const npxCommand = await resolveNpxCommand(cwd);
|
|
885
862
|
console.log('Setting up OSDDT command files...\n');
|
|
@@ -887,6 +864,8 @@ async function runSetup(cwd, rawAgents, rawRepoType, rawWorktreeRepository) {
|
|
|
887
864
|
const config = { repoType, agents };
|
|
888
865
|
if (worktreeRepository)
|
|
889
866
|
config['worktree-repository'] = worktreeRepository;
|
|
867
|
+
if (barePath)
|
|
868
|
+
config['bare-path'] = barePath;
|
|
890
869
|
await writeConfig(cwd, config);
|
|
891
870
|
console.log('\nSetup complete!');
|
|
892
871
|
console.log('Commands created: osddt.spec, osddt.plan, osddt.tasks, osddt.implement');
|
|
@@ -938,7 +917,13 @@ function todayPrefix() {
|
|
|
938
917
|
const dd = String(now.getDate()).padStart(2, '0');
|
|
939
918
|
return `${yyyy}-${mm}-${dd}`;
|
|
940
919
|
}
|
|
941
|
-
function resolveRepoRoot$2(cwd) {
|
|
920
|
+
async function resolveRepoRoot$2(cwd) {
|
|
921
|
+
const rcPath = path.join(cwd, '.osddtrc');
|
|
922
|
+
if (await fs.pathExists(rcPath)) {
|
|
923
|
+
const rc = await fs.readJson(rcPath);
|
|
924
|
+
if (rc['bare-path'])
|
|
925
|
+
return rc['bare-path'];
|
|
926
|
+
}
|
|
942
927
|
return execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim();
|
|
943
928
|
}
|
|
944
929
|
function stateFilePath$2(repoRoot) {
|
|
@@ -957,7 +942,7 @@ async function runDone(featureName, cwd, worktree) {
|
|
|
957
942
|
console.log(`Moved: working-on/${featureName} → done/${destName}`);
|
|
958
943
|
if (!worktree)
|
|
959
944
|
return;
|
|
960
|
-
const repoRoot = resolveRepoRoot$2(process.cwd());
|
|
945
|
+
const repoRoot = await resolveRepoRoot$2(process.cwd());
|
|
961
946
|
const stateFile = stateFilePath$2(repoRoot);
|
|
962
947
|
if (!(await fs.pathExists(stateFile))) {
|
|
963
948
|
console.error(`Warning: .osddt-worktrees not found at ${stateFile}. Skipping worktree cleanup.`);
|
|
@@ -1125,9 +1110,6 @@ function contextCommand() {
|
|
|
1125
1110
|
return cmd;
|
|
1126
1111
|
}
|
|
1127
1112
|
|
|
1128
|
-
function resolveRepoRoot$1(cwd) {
|
|
1129
|
-
return execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim();
|
|
1130
|
-
}
|
|
1131
1113
|
function repoName(repoRoot) {
|
|
1132
1114
|
return path.basename(repoRoot);
|
|
1133
1115
|
}
|
|
@@ -1169,6 +1151,15 @@ async function prompt(question) {
|
|
|
1169
1151
|
});
|
|
1170
1152
|
});
|
|
1171
1153
|
}
|
|
1154
|
+
async function resolveRepoRoot$1(cwd) {
|
|
1155
|
+
const rcPath = path.join(cwd, '.osddtrc');
|
|
1156
|
+
if (await fs.pathExists(rcPath)) {
|
|
1157
|
+
const rc = await fs.readJson(rcPath);
|
|
1158
|
+
if (rc['bare-path'])
|
|
1159
|
+
return rc['bare-path'];
|
|
1160
|
+
}
|
|
1161
|
+
return execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim();
|
|
1162
|
+
}
|
|
1172
1163
|
async function createWorktree(branch, worktreePath, repoRoot) {
|
|
1173
1164
|
if (await fs.pathExists(worktreePath)) {
|
|
1174
1165
|
console.log(`\nDirectory already exists at: ${worktreePath}`);
|
|
@@ -1196,15 +1187,15 @@ async function createWorktree(branch, worktreePath, repoRoot) {
|
|
|
1196
1187
|
}
|
|
1197
1188
|
async function runStartWorktree(featureName, options) {
|
|
1198
1189
|
const cwd = process.cwd();
|
|
1199
|
-
const repoRoot = resolveRepoRoot$1(cwd);
|
|
1190
|
+
const repoRoot = await resolveRepoRoot$1(cwd);
|
|
1200
1191
|
const branch = `feat/${featureName}`;
|
|
1201
1192
|
// Read .osddtrc
|
|
1202
|
-
const rcPath = path.join(
|
|
1193
|
+
const rcPath = path.join(cwd, '.osddtrc');
|
|
1203
1194
|
let rc = { repoType: 'single' };
|
|
1204
1195
|
if (await fs.pathExists(rcPath)) {
|
|
1205
1196
|
rc = await fs.readJson(rcPath);
|
|
1206
1197
|
}
|
|
1207
|
-
// Resolve worktree path
|
|
1198
|
+
// Resolve worktree path — base is parent of repoRoot (i.e. cwd when using .bare)
|
|
1208
1199
|
const base = rc.worktreeBase ?? path.dirname(repoRoot);
|
|
1209
1200
|
const worktreePath = path.join(base, `${repoName(repoRoot)}-${featureName}`);
|
|
1210
1201
|
// Check state file for existing entry
|
|
@@ -1256,14 +1247,20 @@ function startWorktreeCommand() {
|
|
|
1256
1247
|
return cmd;
|
|
1257
1248
|
}
|
|
1258
1249
|
|
|
1259
|
-
function resolveRepoRoot(cwd) {
|
|
1250
|
+
async function resolveRepoRoot(cwd) {
|
|
1251
|
+
const rcPath = path.join(cwd, '.osddtrc');
|
|
1252
|
+
if (await fs.pathExists(rcPath)) {
|
|
1253
|
+
const rc = await fs.readJson(rcPath);
|
|
1254
|
+
if (rc['bare-path'])
|
|
1255
|
+
return rc['bare-path'];
|
|
1256
|
+
}
|
|
1260
1257
|
return execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim();
|
|
1261
1258
|
}
|
|
1262
1259
|
function stateFilePath(repoRoot) {
|
|
1263
1260
|
return path.join(path.dirname(repoRoot), '.osddt-worktrees');
|
|
1264
1261
|
}
|
|
1265
1262
|
async function runWorktreeInfo(featureName) {
|
|
1266
|
-
const repoRoot = resolveRepoRoot(process.cwd());
|
|
1263
|
+
const repoRoot = await resolveRepoRoot(process.cwd());
|
|
1267
1264
|
const stateFile = stateFilePath(repoRoot);
|
|
1268
1265
|
if (!(await fs.pathExists(stateFile))) {
|
|
1269
1266
|
console.error(`No .osddt-worktrees file found at: ${stateFile}`);
|
package/dist/utils/worktree.d.ts
CHANGED
|
@@ -4,8 +4,7 @@ export interface CheckResult {
|
|
|
4
4
|
detail: string;
|
|
5
5
|
}
|
|
6
6
|
export declare function checkGitVersion(): CheckResult;
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function initStateFile(cwd: string): Promise<void>;
|
|
7
|
+
export declare function checkTargetWritable(barePath: string): Promise<CheckResult>;
|
|
8
|
+
export declare function initStateFile(barePath: string): Promise<void>;
|
|
10
9
|
export declare function printCheckResult(result: CheckResult): void;
|
|
11
|
-
export declare function runWorktreeChecks(
|
|
10
|
+
export declare function runWorktreeChecks(barePath: string): Promise<boolean>;
|