Skip to content

Commit 50cb078

Browse files
committed
v0.0.1: initial release
0 parents  commit 50cb078

File tree

126 files changed

+28352
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+28352
-0
lines changed

.github/workflows/release.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Release on Tag Push
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Extract version from tag
19+
id: version
20+
run: echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
21+
22+
- name: Extract changelog for this version
23+
id: changelog
24+
run: |
25+
TAG="${{ steps.version.outputs.tag }}"
26+
# Extract the section for this tag from changelog
27+
# Matches from "## vX.Y.Z" (with optional suffix) to the next "## " or EOF
28+
BODY=$(awk -v tag="$TAG" '
29+
BEGIN { found=0 }
30+
/^## / {
31+
if (found) exit
32+
# Match the tag, allowing optional suffix after version (e.g. "- Breaking change")
33+
header=$2
34+
# Remove trailing characters after version pattern
35+
gsub(/[^v0-9.].*/, "", header)
36+
if (header == tag) { found=1; next }
37+
}
38+
found { print }
39+
' docs/changelog.md)
40+
41+
# Fail if no changelog found
42+
if [ -z "$BODY" ]; then
43+
echo "::warning::No changelog entry found for $TAG, using default message"
44+
BODY="Release $TAG"
45+
fi
46+
47+
# Write to file to preserve multiline content
48+
echo "$BODY" > /tmp/release-body.md
49+
50+
- name: Delete existing release if present
51+
run: |
52+
TAG="${{ steps.version.outputs.tag }}"
53+
if gh release view "$TAG" &>/dev/null; then
54+
echo "Deleting existing release for $TAG"
55+
gh release delete "$TAG" --yes
56+
fi
57+
env:
58+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59+
60+
- name: Create GitHub Release
61+
run: |
62+
TAG="${{ steps.version.outputs.tag }}"
63+
gh release create "$TAG" \
64+
--title "$TAG" \
65+
--notes-file /tmp/release-body.md
66+
env:
67+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
node_modules/
2+
dist/
3+
store/
4+
data/
5+
*.db
6+
*.db-journal
7+
.DS_Store
8+
.env
9+
.env.local
10+
packages/ui/build/
11+
__pycache__/
12+
13+
14+
# AI config files (managed by AI Sync)
15+
.agent/
16+
.agents/
17+
.aider*
18+
.claude-plugin/
19+
.claude/
20+
.copilot/
21+
.cursor/
22+
.cursorrules
23+
.gemini/
24+
.github/copilot-instructions.md
25+
.github/skills
26+
.ipynb_checkpoints
27+
.mcp.json
28+
.opencode/
29+
.windsurfrules
30+
CLAUDE.md
31+
GEMINI.md
32+
# End AI Sync managed

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ignore-scripts=false

.prettierignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules/
2+
dist/
3+
packages/ui/build/
4+
*.db
5+
pnpm-lock.yaml

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"editor.defaultFormatter": "esbenp.prettier-vscode",
3+
"editor.formatOnSave": true,
4+
"prettier.configPath": "./prettier.config.js",
5+
"css.customData": [],
6+
"css.lint.unknownAtRules": "ignore"
7+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 AI Sync
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# AI Sync
2+
3+
<p align="center">
4+
<img src="assets/logo.svg" alt="AI Sync Logo" width="100" />
5+
</p>
6+
7+
Centralized management tool for AI configuration files across Git repositories and local AI services. Keep files like `CLAUDE.md`, `.cursor/`, `GEMINI.md` synced across all your repos, and sync local AI service settings (e.g., `~/.claude/` for Claude Code) — all without committing them.
8+
9+
> [!WARNING]
10+
> Under development, use at your own risk.
11+
12+
## How it works
13+
14+
- A **central store** (a separate git repo you choose) holds all AI config files, organized by repository and service
15+
- A **sync engine** watches for changes on both sides and syncs automatically using **git 3-way merge** — non-conflicting changes are auto-merged
16+
- **AI service configs** (e.g., Claude Code's `~/.claude/`) can be synced with predefined file patterns — no manual path browsing needed
17+
- **Multi-machine support** — each machine gets a unique identity; a git-tracked `machines.json` maps repo paths per machine, so the same store works across machines with different directory layouts. Repos are auto-linked on startup
18+
- A **web UI** lets you manage repos, services, edit files, and resolve conflicts
19+
- AI files are automatically **git-ignored** and **removed from git tracking** in target repos
20+
- **App code and user data are fully separated** — update the tool without affecting your data
21+
22+
## Quick Start
23+
24+
**Prerequisites:** Node.js 22+, pnpm 10+
25+
26+
```bash
27+
# Install
28+
pnpm install
29+
30+
# Build
31+
pnpm build
32+
33+
# Run (production)
34+
pnpm start
35+
```
36+
37+
Open http://localhost:2703
38+
39+
## Usage
40+
41+
1. On first launch, the UI shows a **setup screen** — pick a directory for your data store
42+
2. This directory becomes a Git repo containing all your AI config files and the SQLite database
43+
3. Click **Add Repository** to register a local git repo
44+
4. The tool scans for AI config files, copies them to the store, and starts syncing
45+
5. AI files are added to the target repo's `.gitignore` and removed from git tracking
46+
6. Click **Add Service** to sync local AI service configs (e.g., Claude Code) — the tool auto-detects installed services and uses predefined file patterns
47+
7. Edit files in the UI or directly in the repo/service directory — changes sync both ways
48+
8. Conflicts (both sides changed) appear in the detail page for resolution
49+
50+
### Data directory structure
51+
52+
```
53+
<your-data-dir>/ # Git repo (you chose this path)
54+
├── machines.json # Machine-to-path mappings (git-tracked)
55+
├── repos/
56+
│ ├── _default/ # Template for new repos
57+
│ ├── my-project/ # AI files for my-project
58+
│ └── another-project/ # AI files for another-project
59+
├── services/
60+
│ └── claude-code/ # Claude Code config files
61+
└── .db/
62+
└── ai-sync.db # SQLite database (git-ignored)
63+
```
64+
65+
### Override data directory
66+
67+
```bash
68+
DATA_DIR=/path/to/data pnpm start
69+
```
70+
71+
## Setting up on a new machine
72+
73+
```bash
74+
git clone <this-repo-url>
75+
cd ai-sync
76+
pnpm install && pnpm build && pnpm start
77+
```
78+
79+
On the setup screen, point to your existing data directory (clone your store repo first if needed).
80+
81+
The app will automatically assign a machine identity and **auto-link** any repos that already have a path mapping for this machine in `machines.json`. Repos that can't be auto-linked appear as **Unlinked Repositories** on the dashboard — click **Link** to map them to local paths, **Auto-link All** to link everything at once, or the **trash icon** to remove repos you no longer need.
82+
83+
## Development
84+
85+
```bash
86+
# Start both server and UI with hot reload
87+
pnpm dev # open http://localhost:5173
88+
89+
# Or run them separately
90+
pnpm dev:server # Fastify on :2703
91+
pnpm dev:ui # Vite on :5173 (proxies API to :2703)
92+
93+
# Test
94+
pnpm test # Run all tests
95+
96+
# Format & lint
97+
pnpm format # Format all code with Prettier
98+
pnpm format:check # Check formatting without writing
99+
pnpm lint # Run ESLint on all packages
100+
pnpm lint:fix # Auto-fix ESLint issues
101+
```
102+
103+
### Reset to fresh state
104+
105+
To return to the initial setup screen (e.g. to pick a different data directory):
106+
107+
- **Via the UI**: Click the **Change** button next to the data directory path on the Dashboard
108+
- **Via the command line**:
109+
110+
```bash
111+
rm ~/.ai-sync/config.json
112+
```
113+
114+
This only removes the pointer to your data directory — it does **not** delete your data files.
115+
116+
To fully wipe everything (data directory + config):
117+
118+
```bash
119+
rm ~/.ai-sync/config.json
120+
rm -rf /path/to/your/data-dir # the directory you chose during setup
121+
```
122+
123+
## Tech Stack
124+
125+
| Layer | Technology |
126+
| -------- | ----------------------------------------------------------- |
127+
| Backend | Fastify 5, TypeScript, better-sqlite3, chokidar, simple-git |
128+
| Frontend | React 19, Vite, shadcn/ui, Tailwind CSS, CodeMirror 6 |
129+
| Monorepo | pnpm workspace (`packages/server` + `packages/ui`) |
130+
131+
## Project Structure
132+
133+
```
134+
├── packages/server/ # Fastify backend + sync engine
135+
├── packages/ui/ # React SPA
136+
├── dev-docs/ # Documentation for development
137+
└── docs/ # Documentation for the project
138+
```
139+
140+
User data is stored externally in the directory you choose during setup (config saved at `~/.ai-sync/config.json`).
141+
142+
See [docs/intro.md](docs/intro.md) for supported AI file patterns and services, [docs/how-to.md](docs/how-to.md) for a detailed usage guide, and [dev-docs/project.md](dev-docs/project.md) for development documentation.
143+
144+
## License
145+
146+
[MIT](LICENSE)

assets/logo.svg

Lines changed: 1 addition & 0 deletions
Loading

dev-docs/TODO.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# TODO
2+
3+
- [x] Auto detect new updates available for the app and notify the user to update.
4+
- [x] Add a clone button to the tree view so that we can clone a folder/file from the tree view of a repository to another/some repositories.
5+
- [x] Should support to backup the ~/.claude settings to the store. Only important files/folders.
6+
- [ ] Add share button to package files/folders to share with other users. Export to a zip file.
7+
- [ ] Add import button to import files/folders from a zip file to the store.
8+
- [ ] Add export button to export files/folders from the store to a zip file.
9+
- [x] Add "show conflict only" button in the dashboard.

0 commit comments

Comments
 (0)