@dezkareid/osddt 1.11.2 → 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 +46 -67
- package/dist/utils/worktree.d.ts +3 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -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,34 +824,25 @@ async function writeAgentFiles(cwd, agents, npxCommand) {
|
|
|
857
824
|
console.log('');
|
|
858
825
|
}
|
|
859
826
|
}
|
|
860
|
-
function isGitRepository(cwd) {
|
|
861
|
-
try {
|
|
862
|
-
execSync('git rev-parse --git-dir', { cwd, stdio: 'ignore' });
|
|
863
|
-
return true;
|
|
864
|
-
}
|
|
865
|
-
catch {
|
|
866
|
-
return false;
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
827
|
function cloneBareRepository(cwd, repositoryUrl) {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
execSync(
|
|
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' });
|
|
873
831
|
console.log('');
|
|
832
|
+
return barePath;
|
|
874
833
|
}
|
|
875
834
|
async function setupWorktreeEnvironment(cwd, worktreeRepository) {
|
|
876
|
-
|
|
877
|
-
cloneBareRepository(cwd, worktreeRepository);
|
|
878
|
-
}
|
|
835
|
+
const barePath = cloneBareRepository(cwd, worktreeRepository);
|
|
879
836
|
console.log('Checking environment for git worktree support...\n');
|
|
880
|
-
const allPassed = await runWorktreeChecks(
|
|
837
|
+
const allPassed = await runWorktreeChecks(barePath);
|
|
881
838
|
console.log('');
|
|
882
839
|
if (!allPassed) {
|
|
883
840
|
console.log('Some checks failed. Resolve the issues above before using the worktree workflow.');
|
|
884
841
|
process.exit(1);
|
|
885
842
|
}
|
|
886
|
-
await initStateFile(
|
|
843
|
+
await initStateFile(barePath);
|
|
887
844
|
console.log('');
|
|
845
|
+
return barePath;
|
|
888
846
|
}
|
|
889
847
|
async function runSetup(cwd, rawAgents, rawRepoType, rawWorktreeRepository) {
|
|
890
848
|
const agents = rawAgents !== undefined ? parseAgents(rawAgents) : await askAgents();
|
|
@@ -896,8 +854,9 @@ async function runSetup(cwd, rawAgents, rawRepoType, rawWorktreeRepository) {
|
|
|
896
854
|
const worktreeRepository = rawWorktreeRepository !== undefined ? rawWorktreeRepository : (await askWorktreeUrl()) || undefined;
|
|
897
855
|
if (rawWorktreeRepository === undefined)
|
|
898
856
|
console.log('');
|
|
857
|
+
let barePath;
|
|
899
858
|
if (worktreeRepository) {
|
|
900
|
-
await setupWorktreeEnvironment(cwd, worktreeRepository);
|
|
859
|
+
barePath = await setupWorktreeEnvironment(cwd, worktreeRepository);
|
|
901
860
|
}
|
|
902
861
|
const npxCommand = await resolveNpxCommand(cwd);
|
|
903
862
|
console.log('Setting up OSDDT command files...\n');
|
|
@@ -905,6 +864,8 @@ async function runSetup(cwd, rawAgents, rawRepoType, rawWorktreeRepository) {
|
|
|
905
864
|
const config = { repoType, agents };
|
|
906
865
|
if (worktreeRepository)
|
|
907
866
|
config['worktree-repository'] = worktreeRepository;
|
|
867
|
+
if (barePath)
|
|
868
|
+
config['bare-path'] = barePath;
|
|
908
869
|
await writeConfig(cwd, config);
|
|
909
870
|
console.log('\nSetup complete!');
|
|
910
871
|
console.log('Commands created: osddt.spec, osddt.plan, osddt.tasks, osddt.implement');
|
|
@@ -956,7 +917,13 @@ function todayPrefix() {
|
|
|
956
917
|
const dd = String(now.getDate()).padStart(2, '0');
|
|
957
918
|
return `${yyyy}-${mm}-${dd}`;
|
|
958
919
|
}
|
|
959
|
-
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
|
+
}
|
|
960
927
|
return execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim();
|
|
961
928
|
}
|
|
962
929
|
function stateFilePath$2(repoRoot) {
|
|
@@ -975,7 +942,7 @@ async function runDone(featureName, cwd, worktree) {
|
|
|
975
942
|
console.log(`Moved: working-on/${featureName} → done/${destName}`);
|
|
976
943
|
if (!worktree)
|
|
977
944
|
return;
|
|
978
|
-
const repoRoot = resolveRepoRoot$2(process.cwd());
|
|
945
|
+
const repoRoot = await resolveRepoRoot$2(process.cwd());
|
|
979
946
|
const stateFile = stateFilePath$2(repoRoot);
|
|
980
947
|
if (!(await fs.pathExists(stateFile))) {
|
|
981
948
|
console.error(`Warning: .osddt-worktrees not found at ${stateFile}. Skipping worktree cleanup.`);
|
|
@@ -1143,9 +1110,6 @@ function contextCommand() {
|
|
|
1143
1110
|
return cmd;
|
|
1144
1111
|
}
|
|
1145
1112
|
|
|
1146
|
-
function resolveRepoRoot$1(cwd) {
|
|
1147
|
-
return execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim();
|
|
1148
|
-
}
|
|
1149
1113
|
function repoName(repoRoot) {
|
|
1150
1114
|
return path.basename(repoRoot);
|
|
1151
1115
|
}
|
|
@@ -1187,6 +1151,15 @@ async function prompt(question) {
|
|
|
1187
1151
|
});
|
|
1188
1152
|
});
|
|
1189
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
|
+
}
|
|
1190
1163
|
async function createWorktree(branch, worktreePath, repoRoot) {
|
|
1191
1164
|
if (await fs.pathExists(worktreePath)) {
|
|
1192
1165
|
console.log(`\nDirectory already exists at: ${worktreePath}`);
|
|
@@ -1214,15 +1187,15 @@ async function createWorktree(branch, worktreePath, repoRoot) {
|
|
|
1214
1187
|
}
|
|
1215
1188
|
async function runStartWorktree(featureName, options) {
|
|
1216
1189
|
const cwd = process.cwd();
|
|
1217
|
-
const repoRoot = resolveRepoRoot$1(cwd);
|
|
1190
|
+
const repoRoot = await resolveRepoRoot$1(cwd);
|
|
1218
1191
|
const branch = `feat/${featureName}`;
|
|
1219
1192
|
// Read .osddtrc
|
|
1220
|
-
const rcPath = path.join(
|
|
1193
|
+
const rcPath = path.join(cwd, '.osddtrc');
|
|
1221
1194
|
let rc = { repoType: 'single' };
|
|
1222
1195
|
if (await fs.pathExists(rcPath)) {
|
|
1223
1196
|
rc = await fs.readJson(rcPath);
|
|
1224
1197
|
}
|
|
1225
|
-
// Resolve worktree path
|
|
1198
|
+
// Resolve worktree path — base is parent of repoRoot (i.e. cwd when using .bare)
|
|
1226
1199
|
const base = rc.worktreeBase ?? path.dirname(repoRoot);
|
|
1227
1200
|
const worktreePath = path.join(base, `${repoName(repoRoot)}-${featureName}`);
|
|
1228
1201
|
// Check state file for existing entry
|
|
@@ -1274,14 +1247,20 @@ function startWorktreeCommand() {
|
|
|
1274
1247
|
return cmd;
|
|
1275
1248
|
}
|
|
1276
1249
|
|
|
1277
|
-
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
|
+
}
|
|
1278
1257
|
return execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim();
|
|
1279
1258
|
}
|
|
1280
1259
|
function stateFilePath(repoRoot) {
|
|
1281
1260
|
return path.join(path.dirname(repoRoot), '.osddt-worktrees');
|
|
1282
1261
|
}
|
|
1283
1262
|
async function runWorktreeInfo(featureName) {
|
|
1284
|
-
const repoRoot = resolveRepoRoot(process.cwd());
|
|
1263
|
+
const repoRoot = await resolveRepoRoot(process.cwd());
|
|
1285
1264
|
const stateFile = stateFilePath(repoRoot);
|
|
1286
1265
|
if (!(await fs.pathExists(stateFile))) {
|
|
1287
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>;
|