Skip to content
This repository was archived by the owner on Feb 20, 2026. It is now read-only.

Commit f815760

Browse files
committed
Exclude .DS_Store files, run prettier
1 parent 56c120e commit f815760

18 files changed

Lines changed: 696 additions & 541 deletions

.eslintrc.js

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,25 @@
11
module.exports = {
2-
parser: '@typescript-eslint/parser',
3-
extends: [
4-
'eslint:recommended',
5-
'plugin:@typescript-eslint/recommended'
6-
],
2+
parser: "@typescript-eslint/parser",
3+
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
74
parserOptions: {
85
ecmaVersion: 2022,
9-
sourceType: 'module',
10-
project: './tsconfig.json'
6+
sourceType: "module",
7+
project: "./tsconfig.json",
118
},
129
env: {
1310
node: true,
1411
es2022: true,
15-
jest: true
12+
jest: true,
1613
},
17-
plugins: ['@typescript-eslint'],
14+
plugins: ["@typescript-eslint"],
1815
rules: {
19-
'@typescript-eslint/explicit-module-boundary-types': 'off',
20-
'@typescript-eslint/no-explicit-any': 'warn',
21-
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
22-
'no-console': 'off',
23-
'semi': ['error', 'always'],
24-
'quotes': ['error', 'single'],
25-
'comma-dangle': ['error', 'never']
16+
"@typescript-eslint/explicit-module-boundary-types": "off",
17+
"@typescript-eslint/no-explicit-any": "warn",
18+
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
19+
"no-console": "off",
20+
semi: ["error", "always"],
21+
quotes: ["error", "single"],
22+
"comma-dangle": ["error", "never"],
2623
},
27-
ignorePatterns: ['dist/', 'node_modules/', 'coverage/', '*.js']
28-
};
24+
ignorePatterns: ["dist/", "node_modules/", "coverage/", "*.js"],
25+
};

TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
- a. Let user merge changes from remote to local: We would need to implement a conflict resolver somehow.
1313
- b. If conflicts arise, we could just block the operation and let user dump the current state in order not to lose work. This is the simplest option.
1414
- Either way, we need to think about how to apply new commits from the remote, because changes currently only flow from the sandbox to the shadow repo.
15-
- [ ] rsync, inotifywait, etc. should be included in the image, not installed in the fly
15+
- [ ] rsync, inotifywait, etc. should be included in the image, not installed in the fly

docs/git-operations-plan.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ This plan outlines how to safely handle Git operations (commit, push, PR) outsid
3939
```
4040

4141
2. **Shadow Repository Setup (Optimized)**
42+
4243
```typescript
4344
class ShadowRepository {
4445
private shadowPath: string;

jest.config.js

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,36 @@
11
module.exports = {
2-
preset: 'ts-jest',
3-
testEnvironment: 'node',
4-
roots: ['<rootDir>/test'],
2+
preset: "ts-jest",
3+
testEnvironment: "node",
4+
roots: ["<rootDir>/test"],
55
testMatch: [
6-
'**/test/**/*.test.ts',
7-
'**/test/**/*.test.js',
8-
'**/test/**/*.spec.ts',
9-
'**/test/**/*.spec.js'
6+
"**/test/**/*.test.ts",
7+
"**/test/**/*.test.js",
8+
"**/test/**/*.spec.ts",
9+
"**/test/**/*.spec.js",
1010
],
11-
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
11+
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
1212
transform: {
13-
'^.+\\.tsx?$': 'ts-jest',
14-
'^.+\\.jsx?$': 'babel-jest'
13+
"^.+\\.tsx?$": "ts-jest",
14+
"^.+\\.jsx?$": "babel-jest",
1515
},
1616
collectCoverageFrom: [
17-
'src/**/*.{ts,tsx}',
18-
'!src/**/*.d.ts',
19-
'!src/**/*.test.{ts,tsx}',
20-
'!src/**/*.spec.{ts,tsx}'
21-
],
22-
coverageDirectory: '<rootDir>/coverage',
23-
coverageReporters: ['text', 'lcov', 'html'],
24-
testPathIgnorePatterns: [
25-
'/node_modules/',
26-
'/dist/'
17+
"src/**/*.{ts,tsx}",
18+
"!src/**/*.d.ts",
19+
"!src/**/*.test.{ts,tsx}",
20+
"!src/**/*.spec.{ts,tsx}",
2721
],
22+
coverageDirectory: "<rootDir>/coverage",
23+
coverageReporters: ["text", "lcov", "html"],
24+
testPathIgnorePatterns: ["/node_modules/", "/dist/"],
2825
moduleNameMapper: {
29-
'^@/(.*)$': '<rootDir>/src/$1'
26+
"^@/(.*)$": "<rootDir>/src/$1",
3027
},
3128
globals: {
32-
'ts-jest': {
29+
"ts-jest": {
3330
tsconfig: {
3431
esModuleInterop: true,
35-
allowJs: true
36-
}
37-
}
38-
}
39-
};
32+
allowJs: true,
33+
},
34+
},
35+
},
36+
};

src/container.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,14 @@ exec claude --dangerously-skip-permissions' > /start-claude.sh && \\
573573
// Also copy .git directory to preserve git history
574574
console.log(chalk.blue("• Copying git history..."));
575575
const gitTarFile = `/tmp/claude-sandbox-git-${Date.now()}.tar`;
576-
// Exclude macOS resource fork files when creating git archive
577-
execSync(`tar -cf "${gitTarFile}" --exclude="._*" .git`, {
578-
cwd: workDir,
579-
stdio: "pipe",
580-
});
576+
// Exclude macOS resource fork files and .DS_Store when creating git archive
577+
execSync(
578+
`tar -cf "${gitTarFile}" --exclude="._*" --exclude=".DS_Store" .git`,
579+
{
580+
cwd: workDir,
581+
stdio: "pipe",
582+
},
583+
);
581584

582585
try {
583586
const gitStream = fs.createReadStream(gitTarFile);

src/git/shadow-repository.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,12 @@ export class ShadowRepository {
166166
try {
167167
await execAsync("git add .", { cwd: this.shadowPath });
168168
console.log(chalk.gray(" Staged all files for tracking"));
169-
169+
170170
// Create initial commit to ensure deletions can be tracked
171-
await execAsync('git commit -m "Initial snapshot of working directory" --allow-empty', { cwd: this.shadowPath });
171+
await execAsync(
172+
'git commit -m "Initial snapshot of working directory" --allow-empty',
173+
{ cwd: this.shadowPath },
174+
);
172175
console.log(chalk.gray(" Created initial commit for change tracking"));
173176
} catch (stageError: any) {
174177
console.log(chalk.gray(" Could not stage files:", stageError.message));
@@ -426,8 +429,10 @@ export class ShadowRepository {
426429

427430
// Rsync directly from container to shadow repo with proper deletion handling
428431
// First, clear the shadow repo (except .git) to ensure deletions are reflected
429-
await execAsync(`find ${this.shadowPath} -mindepth 1 -not -path '${this.shadowPath}/.git*' -delete`);
430-
432+
await execAsync(
433+
`find ${this.shadowPath} -mindepth 1 -not -path '${this.shadowPath}/.git*' -delete`,
434+
);
435+
431436
// Rsync within container to staging area using exclude file
432437
const rsyncCmd = `docker exec ${containerId} rsync -av --delete \
433438
--exclude-from=${containerExcludeFile} \

test/README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,23 @@ Tests are written using Jest with TypeScript support. The Jest configuration is
4848
### Example Unit Test
4949

5050
```typescript
51-
import { someFunction } from '../../src/someModule';
51+
import { someFunction } from "../../src/someModule";
5252

53-
describe('someFunction', () => {
54-
it('should do something', () => {
55-
const result = someFunction('input');
56-
expect(result).toBe('expected output');
53+
describe("someFunction", () => {
54+
it("should do something", () => {
55+
const result = someFunction("input");
56+
expect(result).toBe("expected output");
5757
});
5858
});
5959
```
6060

6161
## E2E Tests
6262

6363
End-to-end tests are located in `test/e2e/` and test the complete workflow of the CLI tool. These tests:
64+
6465
- Create actual Docker containers
6566
- Run Claude commands
6667
- Verify git operations
6768
- Test the full user experience
6869

69-
Run E2E tests with: `npm run test:e2e`
70+
Run E2E tests with: `npm run test:e2e`

test/e2e/README.md

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ The tests create a temporary git repository, start a claude-sandbox instance, pe
3535
## Running Tests
3636

3737
### Quick Test (Recommended)
38+
3839
```bash
3940
# Run core functionality tests
4041
node core-functionality-test.js
4142
```
4243

4344
### Individual Tests
45+
4446
```bash
4547
# Test repository to container sync
4648
node repo-to-container-sync-test.js
@@ -53,6 +55,7 @@ node test-suite.js
5355
```
5456

5557
### Automated Test Runner
58+
5659
```bash
5760
# Run all tests with cleanup
5861
./run-tests.sh
@@ -67,11 +70,13 @@ node test-suite.js
6770
## Test Process
6871

6972
1. **Setup Phase**
73+
7074
- Creates temporary git repository with dummy files
7175
- Starts claude-sandbox instance
7276
- Connects to web UI for monitoring sync events
7377

7478
2. **Test Execution**
79+
7580
- Performs file operations inside the container
7681
- Waits for synchronization to complete
7782
- Verifies shadow repository state
@@ -84,13 +89,15 @@ node test-suite.js
8489
## Key Features Tested
8590

8691
### Repository to Container Sync
92+
8793
- ✅ One-to-one file mapping from test repo to container
8894
- ✅ No extra files in container (only test repo files)
8995
- ✅ File content integrity verification
9096
- ✅ Git repository properly initialized
9197
- ✅ Correct branch creation
9298

9399
### File Synchronization
100+
94101
- ✅ New file creation and content sync
95102
- ✅ File modification and content updates
96103
- ✅ File deletion and proper removal
@@ -99,12 +106,14 @@ node test-suite.js
99106
- ✅ Special characters in filenames
100107

101108
### Git Integration
109+
102110
- ✅ Staging of additions (`A` status)
103111
- ✅ Tracking of modifications (`M` status)
104112
- ✅ Detection of deletions (`D` status)
105113
- ✅ Proper git commit workflow
106114

107115
### Web UI Integration
116+
108117
- ✅ Real-time sync event notifications
109118
- ✅ Change summary reporting
110119
- ✅ WebSocket communication
@@ -114,25 +123,30 @@ node test-suite.js
114123
### Common Issues
115124

116125
**Container startup timeout**
126+
117127
- Increase timeout values in test framework
118128
- Check Docker daemon is running
119129
- Verify claude-sandbox image exists
120130

121131
**Git lock conflicts**
132+
122133
- Tests automatically handle concurrent git operations
123134
- Temporary `.git/index.lock` files are cleaned up
124135

125136
**Port conflicts**
137+
126138
- Tests use dynamic port allocation
127139
- Multiple tests can run sequentially
128140

129141
**WebSocket connection issues**
142+
130143
- Framework includes connection retry logic
131144
- Fallback to polling if WebSocket fails
132145

133146
### Test Failure Analysis
134147

135148
Tests provide detailed error messages indicating:
149+
136150
- Which specific operation failed
137151
- Expected vs actual file states
138152
- Git status differences
@@ -145,33 +159,36 @@ Tests provide detailed error messages indicating:
145159
1. Create test function in appropriate test file
146160
2. Use framework methods for file operations:
147161
```javascript
148-
await framework.addFile('path/file.txt', 'content');
149-
await framework.modifyFile('path/file.txt', 'new content');
150-
await framework.deleteFile('path/file.txt');
162+
await framework.addFile("path/file.txt", "content");
163+
await framework.modifyFile("path/file.txt", "new content");
164+
await framework.deleteFile("path/file.txt");
151165
```
152166
3. Verify results using assertion methods:
153167
```javascript
154-
const exists = await framework.shadowFileExists('file.txt');
155-
const content = await framework.getShadowFileContent('file.txt');
168+
const exists = await framework.shadowFileExists("file.txt");
169+
const content = await framework.getShadowFileContent("file.txt");
156170
const gitStatus = await framework.getGitStatus();
157171
```
158172

159173
### Framework API
160174

161175
**File Operations**
176+
162177
- `addFile(path, content)` - Create new file
163-
- `modifyFile(path, content)` - Update existing file
178+
- `modifyFile(path, content)` - Update existing file
164179
- `deleteFile(path)` - Remove file
165180
- `moveFile(from, to)` - Rename/move file
166181
- `createDirectory(path)` - Create directory
167182

168183
**Verification Methods**
184+
169185
- `shadowFileExists(path)` - Check file existence
170186
- `getShadowFileContent(path)` - Read file content
171187
- `getGitStatus()` - Get git status output
172188
- `waitForSync()` - Wait for synchronization
173189

174190
**Event Monitoring**
191+
175192
- `receivedSyncEvents` - Array of sync notifications
176193
- WebSocket connection automatically established
177194

@@ -188,4 +205,4 @@ These tests are designed to run in automated environments:
188205
./run-tests.sh
189206
```
190207
191-
The tests provide proper exit codes (0 for success, 1 for failure) and detailed logging for debugging purposes.
208+
The tests provide proper exit codes (0 for success, 1 for failure) and detailed logging for debugging purposes.

0 commit comments

Comments
 (0)