Skip to content

Commit 8142f57

Browse files
authored
Merge pull request #113 from TrueNine/dev
Merge dev into main
2 parents e4d3416 + 8aa8903 commit 8142f57

File tree

319 files changed

+5641
-5759
lines changed

Some content is hidden

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

319 files changed

+5641
-5759
lines changed

.githooks/sync-versions.test.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ function createFixtureRepo(): string {
3535
name: '@truenine/memory-sync-cli',
3636
version: initialVersion
3737
})
38+
writeJson(join(rootDir, 'sdk', 'package.json'), {
39+
name: '@truenine/memory-sync-sdk',
40+
version: initialVersion,
41+
private: true
42+
})
3843
writeJson(join(rootDir, 'cli', 'npm', 'darwin-arm64', 'package.json'), {
3944
name: '@truenine/memory-sync-cli-darwin-arm64',
4045
version: initialVersion
@@ -101,6 +106,43 @@ describe('sync-versions hook', () => {
101106
expect(result.versionSource).toBe('cli/npm/darwin-arm64/package.json')
102107
expect(JSON.parse(readFileSync(join(rootDir, 'package.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
103108
expect(JSON.parse(readFileSync(join(rootDir, 'cli', 'package.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
109+
expect(JSON.parse(readFileSync(join(rootDir, 'sdk', 'package.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
110+
expect(JSON.parse(readFileSync(join(rootDir, 'libraries', 'logger', 'package.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
111+
expect(readFileSync(join(rootDir, 'Cargo.toml'), 'utf-8')).toContain(`version = "${nextVersion}"`)
112+
expect(readFileSync(join(rootDir, 'cli-crate', 'Cargo.toml'), 'utf-8')).toContain(`version = "${nextVersion}"`)
113+
expect(JSON.parse(readFileSync(join(rootDir, 'gui', 'src-tauri', 'tauri.conf.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
114+
expect(stagedFiles).toEqual(new Set([
115+
'Cargo.toml',
116+
'cli-crate/Cargo.toml',
117+
'cli/npm/darwin-arm64/package.json',
118+
'cli/package.json',
119+
'gui/src-tauri/tauri.conf.json',
120+
'libraries/logger/package.json',
121+
'package.json',
122+
'sdk/package.json'
123+
]))
124+
})
125+
126+
it('accepts sdk/package.json as a staged version source and propagates it', () => {
127+
const rootDir = createFixtureRepo()
128+
tempDirs.push(rootDir)
129+
130+
const nextVersion = '2026.10324.10316'
131+
writeJson(join(rootDir, 'sdk', 'package.json'), {
132+
name: '@truenine/memory-sync-sdk',
133+
version: nextVersion,
134+
private: true
135+
})
136+
runGit(rootDir, ['add', 'sdk/package.json'])
137+
138+
const result = runSyncVersions({rootDir})
139+
const stagedFiles = new Set(runGit(rootDir, ['diff', '--cached', '--name-only']).split(/\r?\n/).filter(Boolean))
140+
141+
expect(result.targetVersion).toBe(nextVersion)
142+
expect(result.versionSource).toBe('sdk/package.json')
143+
expect(JSON.parse(readFileSync(join(rootDir, 'package.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
144+
expect(JSON.parse(readFileSync(join(rootDir, 'cli', 'package.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
145+
expect(JSON.parse(readFileSync(join(rootDir, 'sdk', 'package.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
104146
expect(JSON.parse(readFileSync(join(rootDir, 'libraries', 'logger', 'package.json'), 'utf-8')) as {version: string}).toMatchObject({version: nextVersion})
105147
expect(readFileSync(join(rootDir, 'Cargo.toml'), 'utf-8')).toContain(`version = "${nextVersion}"`)
106148
expect(readFileSync(join(rootDir, 'cli-crate', 'Cargo.toml'), 'utf-8')).toContain(`version = "${nextVersion}"`)
@@ -112,7 +154,8 @@ describe('sync-versions hook', () => {
112154
'cli/package.json',
113155
'gui/src-tauri/tauri.conf.json',
114156
'libraries/logger/package.json',
115-
'package.json'
157+
'package.json',
158+
'sdk/package.json'
116159
]))
117160
})
118161

.github/workflows/release-cli.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ jobs:
239239
- uses: actions/checkout@v6
240240
- uses: ./.github/actions/setup-node-pnpm
241241
with:
242-
install: "false"
242+
install: "true"
243243
- name: Setup npm registry
244244
uses: actions/setup-node@v6
245245
with:
@@ -299,6 +299,16 @@ jobs:
299299
echo "Copying from ${artifact_dir} to ${target_dir}"
300300
cp "${artifact_dir}"*.node "$target_dir/" || { echo "ERROR: no .node files found in ${artifact_dir}"; exit 1; }
301301
done
302+
- name: Generate CLI platform package shims
303+
shell: bash
304+
run: |
305+
shopt -s nullglob
306+
dirs=(cli/npm/*/)
307+
if [ "${#dirs[@]}" -eq 0 ]; then
308+
echo "No CLI platform package directories found"
309+
exit 0
310+
fi
311+
pnpm exec tsx scripts/write-platform-package-shims.ts "${dirs[@]}"
302312
- name: Validate CLI platform packages
303313
shell: bash
304314
run: |
@@ -314,12 +324,12 @@ jobs:
314324
if [ ! -f "${target_dir}package.json" ]; then
315325
continue
316326
fi
317-
if [ ! -f "${target_dir}noop.cjs" ]; then
318-
echo "ERROR: missing ${target_dir}noop.cjs"
327+
if [ ! -f "${target_dir}noop.mjs" ]; then
328+
echo "ERROR: missing ${target_dir}noop.mjs"
319329
exit 1
320330
fi
321-
if [ ! -f "${target_dir}noop.d.ts" ]; then
322-
echo "ERROR: missing ${target_dir}noop.d.ts"
331+
if [ ! -f "${target_dir}noop.d.mts" ]; then
332+
echo "ERROR: missing ${target_dir}noop.d.mts"
323333
exit 1
324334
fi
325335
actual_count=$(find "${target_dir}" -maxdepth 1 -type f -name '*.node' | wc -l | tr -d ' ')

Cargo.lock

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[workspace]
22
resolver = "2"
33
members = [
4+
"sdk",
45
"cli",
56
"libraries/logger",
67
"libraries/md-compiler",
@@ -9,7 +10,7 @@ members = [
910
]
1011

1112
[workspace.package]
12-
version = "2026.10330.118"
13+
version = "2026.10402.103"
1314
edition = "2024"
1415
rust-version = "1.88"
1516
license = "AGPL-3.0-only"
@@ -18,7 +19,7 @@ repository = "https://github.com/TrueNine/memory-sync"
1819

1920
[workspace.dependencies]
2021
# Internal crates
21-
tnmsc = { path = "cli" }
22+
tnmsc = { path = "sdk" }
2223
tnmsc-logger = { path = "libraries/logger" }
2324
tnmsc-md-compiler = { path = "libraries/md-compiler" }
2425
tnmsc-script-runtime = { path = "libraries/script-runtime" }

README.md

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,96 @@
11
# memory-sync
22

3-
Rats 🐀 are like this: even our own brains, even our memories, are things we haul around while running through this fucked-up world!!!
3+
A rat is like this. Even its own brain, even its memory, has to be carried around in this rotten world!!!
44

5-
I am a rat. No resources will ever be proactively provided to me.
6-
So as a rat, I eat whatever I can reach: maggots in the sewer, leftovers in the slop bucket, and in extreme cases even my own kind—this is the survival mode in a world where resource allocation is brutally unfair.
5+
I am a rat. No resource is going to walk up and offer itself to me.
6+
So as a rat, I eat whatever I can reach: maggots in the sewer, leftovers in a slop bucket, and in extreme cases even my own kind. That is what survival looks like in a world where resource distribution is brutally unequal.
77

88
`memory-sync` is the same kind of **tool-rat**:
99

10-
- Does not expect any platform to grant an "official all-in-one solution"
11-
- Does not rely on privileged interfaces of any single IDE / CLI
12-
- Treats every readable config, prompt, and memory file as "edible matter" to be carried, dismantled, and recombined
13-
In this ecosystem, giants monopolise the resources, and developers are thrown into the corner like rats.
14-
`memory-sync` accepts this cruel reality, does not fantasise about fairness, and focuses on one thing only: **to chew up every fragment of resource you already have, and convert it into portable "memory" that can flow between any AI tool.**
10+
- It does not wait for any platform to hand out an "official all-in-one solution"
11+
- It does not rely on the privileged interface of any single IDE or CLI
12+
- Any configuration, prompt, memory file, or generated artifact it can read becomes something edible: something to haul away, break apart, and recombine
13+
In this ecosystem, the giants hoard the resources while developers get thrown into a corner like rats.
14+
`memory-sync` accepts this cruel reality, does not fantasize about fairness, and focuses on one thing only: **to chew through every fragment of resource you already have and turn it into portable "memory" that can flow between AI tools.**
1515

1616
![rat](/.attachments/rat.svg)
1717

18-
What can it help you do?
19-
20-
- **`.mdx` as the prompt source format**: write your prompts in MDX; `memory-sync` reads, transforms, and writes them into each tool's native config format—you maintain one source, it handles the rest.
21-
- A **universal prompt spec**: write Global / Root / Child / Skill / Command / Agent prompts in a unified structure.
22-
- **Auto-write tool config files**: AGENTS.md, .cursorrules, .kiro/, CLAUDE.md, etc.—if there is an entry point, it stuffs your memory in.
23-
- **Generate copy-ready one-shot prompts**: package project context, tech stack, and current task into AI-friendly Markdown, paste into any chat box directly.
24-
- Like a rat gnawing on cables, **gnaw structured memory out of existing directory structures and config files**, instead of asking you to rewrite everything from scratch.
25-
- **Fine-grained control**: describe rules in YAML / JSON config files, choose what to sync by project, by Agent, by tool type—no "one-size-fits-all" overwrites.
26-
- **Read-only source files**: never modifies your original repository directly, only reads and transforms, then materialises the result on the target tool side.
27-
- **Full wipe**: on sync, erases all stale prompt traces in target tools—prompts are fully computable and auditable, leaving no residue for bad actors.
28-
- **Prompts grow with you only**: memory follows you as a person, not the project. Someone else takes over the project—they cannot take your context. You move to a new project—your accumulated knowledge moves with you intact.
18+
What can it do for you?
19+
20+
- **Use `.mdx` / `.src.mdx` as the source of truth**: you maintain one source, and `memory-sync` turns it into native tool configs plus managed generated artifacts.
21+
- **Use one unified input-asset model**: Global / Workspace / Project Memory, Skills, Commands, Sub-agents, Rules, README-like outputs, and related assets all fit into one structure.
22+
- **Auto-write native tool configs**: AGENTS.md, Claude Code CLI, Codex CLI, Cursor, Windsurf, Qoder, Trae, Warp, JetBrains AI Assistant Codex, and more. If a native entry point exists, it can write there.
23+
- **Manage derived artifacts**: besides target-tool configs, it can maintain English prompt outputs, skill exports, README-like outputs, and other helper configs.
24+
- **Provide multiple entry points**: the public entry is the `tnmsc` CLI; internally there is also a private SDK, an MCP stdio server, and a Tauri GUI, all working around the same source-of-truth model.
25+
- **Control write scope precisely**: use `outputScopes`, `cleanupProtection`, and related settings to constrain writes and cleanup by project, topic, and tool.
26+
- **Keep source and derived outputs auditable**: source files, generated artifacts, and target-tool configs stay clearly separated. No hidden source edits. No hidden residue.
27+
- **Let memory grow with you**: memory follows you as a person instead of leaking with the project. If a project changes hands, they do not get your context. If you move to another project, your accumulated memory goes with you unchanged.
2928
## Install
3029

3130
```sh
32-
npm install -g @truenine/memory-sync
31+
npm install -g @truenine/memory-sync-cli
3332
```
3433

35-
## Docs
34+
Optional MCP server:
3635

37-
`https://docs.truenine.org/tnmsc`
36+
```sh
37+
npm install -g @truenine/memory-sync-mcp
38+
```
3839

3940
## Supported Tools
4041

4142
| Type | Tools |
4243
| --- | --- |
43-
| IDE | Cursor, Kiro, Windsurf, JetBrains AI |
44-
| CLI | Claude CLI, Gemini CLI, Codex CLI, Warp |
44+
| IDE / Editor | Cursor, Windsurf, Qoder, Trae, Trae CN, JetBrains AI Assistant Codex, Zed, VS Code |
45+
| CLI | Claude Code CLI, OpenAI Codex CLI, Gemini CLI, Droid CLI, Opencode CLI, Warp |
46+
| Other Outputs | AGENTS.md-style outputs, Generic Skills, README-like outputs, `.editorconfig`, `.git/info/exclude` |
4547

46-
More platforms being added continuously.
48+
More platforms are still being added.
4749

4850
## Architecture
4951

50-
- **CLI** (`@truenine/memory-sync`): core sync engine—reads config, writes target tool files, generates copy-ready prompts.
51-
- **Core** (Rust): file I/O, directory traversal, format conversion.
52-
- **Config DSL** (JSON): reads only the global config file `~/.aindex/.tnmsc.json`, which defines sync rules and target tools.
53-
- **GUI** (Tauri): desktop app that calls the CLI as its backend, providing a visual interface.
52+
- **SDK** (`@truenine/memory-sync-sdk` / `tnmsc` crate): the private mixed core for pipeline, prompt service, schema, bridge runtime, and core integration logic.
53+
- **CLI Shell** (`@truenine/memory-sync-cli`): the public `tnmsc` command entry, compatibility export surface, and platform-distribution shell.
54+
- **MCP** (`@truenine/memory-sync-mcp`): an stdio server that exposes prompt-asset management to MCP-capable hosts.
55+
- **Libraries** (`logger`, `md-compiler`, `script-runtime`): Rust-first shared libraries.
56+
- **GUI** (Tauri): the desktop workflow entry, consuming the `tnmsc` crate from `sdk`.
5457
## FAQ
5558

5659
**When AI tools finally have a unified standard, what use will this project be?**
5760

5861
Then it will have completed its historical mission.
5962

60-
**There's already AGENTS.md, agentskills, and the MCP standard—why do I still need this junk?**
63+
**There's already AGENTS.md, agentskills, and the MCP standard. Why do I still need this junk?**
6164

62-
Native-friendly, plus targeted conditional prompt authoring.
65+
Because native targets still differ, and because conditional prompt authoring still has to land somewhere concrete.
6366

64-
`AGENTS.md` is the spec; `memory-sync` is the hauler—it writes the same memory into the native config formats of a dozen tools simultaneously, sparing you the manual copy-paste grind.
67+
`AGENTS.md` is the format. `memory-sync` is the hauler plus assembler. It writes the same source of truth into multiple native configs and managed artifacts at once, so you do not have to do the copy-paste labor by hand. CLI, SDK, MCP, and GUI are just different entry points around that same model.
6568

66-
**Is there anything in your prompts you don't want to leave behind?**
69+
**Is there anything in the prompt or generated output that I may not want to leave behind?**
6770

68-
Yes. That's why `memory-sync` provides a full-wipe mode: after sync, only the content you explicitly authorised remains in the target tools—everything else is erased. Prompts are fully computable, no hidden residue, no backdoor left for anyone else.
71+
Yes. That is why `memory-sync` gives you cleanup and protection boundaries. After sync, only the managed outputs you explicitly allow should remain. Anything else should either be cleaned or protected on purpose. Prompts and derived artifacts should stay computable, auditable, and residue-free.
6972

7073
## Who is this for
7174

7275
To use `memory-sync` you need:
7376

74-
- Solid development experience, years of working with various dev tools
75-
- Proficiency with version control (Git)
76-
- Proficiency with the terminal
77+
- Solid development experience and long-term exposure to dev tools
78+
- Competence with version control (Git)
79+
- Competence with the terminal
7780
---
7881

7982
- You are writing code in a forgotten sewer.
80-
No one will proactively feed you, not even a tiny free quota, not even a half-decent document.
81-
- As a rat, you can barely get your hands on anything good:
82-
scurrying between free tiers, trial credits, education discounts, and random third-party scripts.
83+
No one is going to proactively feed you, not even a tiny free quota, not even a decent document.
84+
- As a rat, you were never going to get good food anyway:
85+
you keep scurrying between free tiers, trial credits, education discounts, and random third-party scripts.
8386
- What can you do?
84-
Keep darting between IDEs, CLIs, browser extensions, and cloud Agents, copying and pasting the same memory a hundred times.
85-
- You leech API offers from vendors day after day:
86-
today one platform runs a discount so you top up a little; tomorrow another launches a promo so you rush to scrape it.
87-
- Once they have harvested the telemetry, user profiles, and usage patterns they want,
88-
they can kick you—this stinking rat—away at any moment: price hikes, rate limits, account bans, and you have no channel to complain.
87+
Keep darting between IDEs, CLIs, browser extensions, and cloud agents, copying and pasting the same memory a hundred times.
88+
- You keep scraping vendor API deals day after day:
89+
today one platform discounts something, so you top up a little; tomorrow another launches a promotion, so you rush over there too.
90+
- Once they have harvested the telemetry, user profile, and usage pattern they wanted,
91+
they can kick you away at any moment: price hikes, quotas, bans, and no real channel for complaint.
8992
If you are barely surviving in this environment, `memory-sync` is built for you:
90-
carry fewer bricks, copy prompts fewer times—at least on the "memory" front, you are no longer completely on the passive receiving end.
93+
to help you carry a little less brick, paste the same prompt a few fewer times, and at least stop being completely passive around "memory".
9194

9295
## Who is NOT welcome
9396

@@ -96,17 +99,17 @@ Stable salary, project revenue share, budget to sign official APIs yearly.
9699
- And yet you still come down here,
97100
competing with us filthy sewer rats for the scraps in the slop bucket.
98101
- If you can afford APIs and enterprise plans, go pay for them.
99-
Do things that actually create valuepay properly, give proper feedback, nudge the ecosystem slightly in the right direction.
102+
Do things that actually create value: pay properly, give proper feedback, and nudge the ecosystem slightly in the right direction.
100103
- Instead of coming back down
101-
to strip away the tiny gap left for marginalised developers, squeezing out the last crumbs with us rats.
104+
to strip away the tiny gap left for marginalized developers, squeezing out the last crumbs with us rats.
102105
- You are a freeloader.
103-
Everything must be pre-chewed and spoon-fed; you won't even touch a terminal.
104-
- You love the grind culture.
106+
Everything must be pre-chewed and spoon-fed; you will not even touch a terminal.
107+
- You love grind culture.
105108
Treating "hustle" as virtue, "996" as glory, stepping on peers as a promotion strategy.
106109
- You leave no room for others.
107-
Not about whether you share—it's about actively stomping on people, competing maliciously, sustaining your position by suppressing peers, using others' survival space as your stepping stone.
110+
This is not about whether you share everything. It is about actively stomping on people, competing maliciously, and treating other people's survival space as your stepping stone.
108111
In other words:
109-
**this is not a tool for optimising capital costs, but a small counterattack prepared for the "rats with no choice" in a world of extreme resource inequality.**
112+
**this is not a tool for optimizing capital cost. It is a small counterattack for the "rats with no choice" in a world of extreme resource inequality.**
110113

111114
## Created by
112115

0 commit comments

Comments
 (0)