wangchuan 5.0.0 → 5.2.0
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/README.md +19 -8
- package/README.zh-CN.md +19 -8
- package/dist/bin/wangchuan.d.ts +10 -7
- package/dist/bin/wangchuan.d.ts.map +1 -1
- package/dist/bin/wangchuan.js +31 -11
- package/dist/bin/wangchuan.js.map +1 -1
- package/dist/src/agents/index.d.ts +5 -0
- package/dist/src/agents/index.d.ts.map +1 -1
- package/dist/src/agents/index.js +32 -0
- package/dist/src/agents/index.js.map +1 -1
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +3 -17
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +70 -6
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/key.d.ts.map +1 -1
- package/dist/src/commands/key.js +1 -17
- package/dist/src/commands/key.js.map +1 -1
- package/dist/src/commands/memory.js +44 -2
- package/dist/src/commands/memory.js.map +1 -1
- package/dist/src/commands/pull.js.map +1 -1
- package/dist/src/commands/push.js.map +1 -1
- package/dist/src/commands/snapshot.d.ts.map +1 -1
- package/dist/src/commands/snapshot.js +1 -19
- package/dist/src/commands/snapshot.js.map +1 -1
- package/dist/src/commands/sync.d.ts.map +1 -1
- package/dist/src/commands/sync.js +1 -15
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/watch.js.map +1 -1
- package/dist/src/core/config.d.ts.map +1 -1
- package/dist/src/core/config.js +4 -2
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/crypto.d.ts +2 -0
- package/dist/src/core/crypto.d.ts.map +1 -1
- package/dist/src/core/crypto.js +10 -2
- package/dist/src/core/crypto.js.map +1 -1
- package/dist/src/core/merge.d.ts +1 -1
- package/dist/src/core/merge.d.ts.map +1 -1
- package/dist/src/core/merge.js +2 -18
- package/dist/src/core/merge.js.map +1 -1
- package/dist/src/core/migrate.d.ts.map +1 -1
- package/dist/src/core/migrate.js +5 -20
- package/dist/src/core/migrate.js.map +1 -1
- package/dist/src/core/sync-lock.d.ts.map +1 -1
- package/dist/src/core/sync-lock.js +20 -1
- package/dist/src/core/sync-lock.js.map +1 -1
- package/dist/src/core/sync.d.ts +4 -4
- package/dist/src/core/sync.d.ts.map +1 -1
- package/dist/src/core/sync.js +60 -25
- package/dist/src/core/sync.js.map +1 -1
- package/dist/src/i18n.d.ts.map +1 -1
- package/dist/src/i18n.js +17 -1
- package/dist/src/i18n.js.map +1 -1
- package/dist/src/types.d.ts +13 -3
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/fs.d.ts +18 -0
- package/dist/src/utils/fs.d.ts.map +1 -0
- package/dist/src/utils/fs.js +56 -0
- package/dist/src/utils/fs.js.map +1 -0
- package/dist/src/utils/lcs.d.ts +8 -0
- package/dist/src/utils/lcs.d.ts.map +1 -0
- package/dist/src/utils/lcs.js +20 -0
- package/dist/src/utils/lcs.js.map +1 -0
- package/dist/src/utils/linediff.d.ts +1 -1
- package/dist/src/utils/linediff.d.ts.map +1 -1
- package/dist/src/utils/linediff.js +22 -39
- package/dist/src/utils/linediff.js.map +1 -1
- package/dist/test/merge.test.d.ts +5 -0
- package/dist/test/merge.test.d.ts.map +1 -0
- package/dist/test/merge.test.js +226 -0
- package/dist/test/merge.test.js.map +1 -0
- package/package.json +2 -2
- package/skill/SKILL.md +50 -3
package/dist/src/core/merge.js
CHANGED
|
@@ -1,27 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* merge.ts — Three-way merge for plain text files
|
|
3
3
|
*
|
|
4
|
-
* Uses the LCS algorithm from
|
|
4
|
+
* Uses the shared LCS algorithm from utils/lcs.ts to compute diffs between
|
|
5
5
|
* base-local and base-remote, then merges non-overlapping changes
|
|
6
6
|
* and inserts conflict markers for overlapping edits.
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
* Compute LCS table between two string arrays.
|
|
10
|
-
* Iterative version (avoids stack overflow on large files).
|
|
11
|
-
*/
|
|
12
|
-
function buildLcsTable(a, b) {
|
|
13
|
-
const m = a.length;
|
|
14
|
-
const n = b.length;
|
|
15
|
-
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
16
|
-
for (let i = 1; i <= m; i++) {
|
|
17
|
-
for (let j = 1; j <= n; j++) {
|
|
18
|
-
dp[i][j] = a[i - 1] === b[j - 1]
|
|
19
|
-
? (dp[i - 1][j - 1] + 1)
|
|
20
|
-
: Math.max(dp[i - 1][j], dp[i][j - 1]);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return dp;
|
|
24
|
-
}
|
|
8
|
+
import { buildLcsTable } from '../utils/lcs.js';
|
|
25
9
|
/**
|
|
26
10
|
* Extract edit regions: contiguous stretches where the modified text
|
|
27
11
|
* differs from the base. Returns regions sorted by baseStart.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../src/core/merge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../src/core/merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/core/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/core/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAuInD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,eAAe,CAepE"}
|
package/dist/src/core/migrate.js
CHANGED
|
@@ -18,23 +18,8 @@ import path from 'path';
|
|
|
18
18
|
import { config, CONFIG_VERSION } from './config.js';
|
|
19
19
|
import { expandHome } from './sync.js';
|
|
20
20
|
import { logger } from '../utils/logger.js';
|
|
21
|
+
import { copyDirSync } from '../utils/fs.js';
|
|
21
22
|
import { t } from '../i18n.js';
|
|
22
|
-
/** Recursively copy directory */
|
|
23
|
-
function copyDirRecursive(src, dest) {
|
|
24
|
-
if (!fs.existsSync(src))
|
|
25
|
-
return;
|
|
26
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
27
|
-
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
28
|
-
const srcPath = path.join(src, entry.name);
|
|
29
|
-
const destPath = path.join(dest, entry.name);
|
|
30
|
-
if (entry.isDirectory()) {
|
|
31
|
-
copyDirRecursive(srcPath, destPath);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
fs.copyFileSync(srcPath, destPath);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
23
|
/** Recursively remove directory */
|
|
39
24
|
function rmDirRecursive(dir) {
|
|
40
25
|
if (!fs.existsSync(dir))
|
|
@@ -63,7 +48,7 @@ function migrateV1toV2(cfg) {
|
|
|
63
48
|
logger.warn(t('migrate.incomplete'));
|
|
64
49
|
if (fs.existsSync(backupDir)) {
|
|
65
50
|
rmDirRecursive(repoPath);
|
|
66
|
-
|
|
51
|
+
copyDirSync(backupDir, repoPath);
|
|
67
52
|
fs.unlinkSync(lockFile);
|
|
68
53
|
logger.ok(t('migrate.rolledBack'));
|
|
69
54
|
}
|
|
@@ -74,7 +59,7 @@ function migrateV1toV2(cfg) {
|
|
|
74
59
|
// ── 1. Full backup ──────────────────────────────────────────────
|
|
75
60
|
if (!fs.existsSync(backupDir)) {
|
|
76
61
|
logger.info(t('migrate.backingUp'));
|
|
77
|
-
|
|
62
|
+
copyDirSync(repoPath, backupDir);
|
|
78
63
|
}
|
|
79
64
|
// ── Write migration lock ────────────────────────────────────────
|
|
80
65
|
fs.writeFileSync(lockFile, `migrating v1→v2 at ${new Date().toISOString()}`, 'utf-8');
|
|
@@ -95,7 +80,7 @@ function migrateV1toV2(cfg) {
|
|
|
95
80
|
if (!fs.existsSync(sharedSkills)) {
|
|
96
81
|
const ocSkills = path.join(repoPath, 'agents', 'openclaw', 'skills');
|
|
97
82
|
if (fs.existsSync(ocSkills)) {
|
|
98
|
-
|
|
83
|
+
copyDirSync(ocSkills, sharedSkills);
|
|
99
84
|
logger.debug(' openclaw/skills → shared/skills/');
|
|
100
85
|
}
|
|
101
86
|
}
|
|
@@ -134,7 +119,7 @@ function migrateV1toV2(cfg) {
|
|
|
134
119
|
logger.info(t('migrate.rollingBack'));
|
|
135
120
|
try {
|
|
136
121
|
rmDirRecursive(repoPath);
|
|
137
|
-
|
|
122
|
+
copyDirSync(backupDir, repoPath);
|
|
138
123
|
if (fs.existsSync(lockFile))
|
|
139
124
|
fs.unlinkSync(lockFile);
|
|
140
125
|
logger.ok(t('migrate.rolledBackOk'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../src/core/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAQ,IAAI,CAAC;AACtB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../src/core/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-lock.d.ts","sourceRoot":"","sources":["../../../src/core/sync-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAuBD,eAAO,MAAM,QAAQ;;IAGnB;;;;;OAKG;iCACqB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-lock.d.ts","sourceRoot":"","sources":["../../../src/core/sync-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAuBD,eAAO,MAAM,QAAQ;;IAGnB;;;;;OAKG;iCACqB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;IAsC9C,4BAA4B;4BACjB,IAAI;IAOf,uDAAuD;2BAC7C,OAAO;IAIjB,iDAAiD;yBACzC,QAAQ,GAAG,IAAI;IAIvB,+CAA+C;yCACf,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;CAW9C,CAAC"}
|
|
@@ -59,7 +59,26 @@ export const syncLock = {
|
|
|
59
59
|
pid: process.pid,
|
|
60
60
|
};
|
|
61
61
|
fs.mkdirSync(WANGCHUAN_DIR, { recursive: true });
|
|
62
|
-
|
|
62
|
+
try {
|
|
63
|
+
// Atomic exclusive create — prevents race condition between concurrent processes
|
|
64
|
+
fs.writeFileSync(LOCK_PATH, JSON.stringify(lock, null, 2), { encoding: 'utf-8', flag: 'wx' });
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err.code === 'EEXIST') {
|
|
68
|
+
// Another process acquired the lock between our read and write
|
|
69
|
+
const raceWinner = readLock();
|
|
70
|
+
if (raceWinner && isPidAlive(raceWinner.pid)) {
|
|
71
|
+
throw new Error(t('syncLock.anotherRunning', { pid: raceWinner.pid }));
|
|
72
|
+
}
|
|
73
|
+
// Stale — clean up and retry once
|
|
74
|
+
await this.cleanDirtyState(repoPath);
|
|
75
|
+
fs.unlinkSync(LOCK_PATH);
|
|
76
|
+
fs.writeFileSync(LOCK_PATH, JSON.stringify(lock, null, 2), { encoding: 'utf-8', flag: 'wx' });
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
63
82
|
logger.trace(t('syncLock.acquired'));
|
|
64
83
|
},
|
|
65
84
|
/** Release the sync lock */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-lock.js","sourceRoot":"","sources":["../../../src/core/sync-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAQ,IAAI,CAAC;AACtB,OAAO,EAAE,MAAQ,IAAI,CAAC;AACtB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAW,YAAY,CAAC;AAEpC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAC5D,MAAM,SAAS,GAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;AAOjE,6DAA6D;AAC7D,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,SAAS,QAAQ;IACf,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAa,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,SAAS;IAEnB;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,QAAgB;QAC5B,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAC;QAC5B,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,yBAAyB,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACvE,CAAC;YACD,sCAAsC;YACtC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC5D,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;QAED,MAAM,IAAI,GAAa;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC;QACF,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-lock.js","sourceRoot":"","sources":["../../../src/core/sync-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAQ,IAAI,CAAC;AACtB,OAAO,EAAE,MAAQ,IAAI,CAAC;AACtB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAW,YAAY,CAAC;AAEpC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAC5D,MAAM,SAAS,GAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;AAOjE,6DAA6D;AAC7D,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,SAAS,QAAQ;IACf,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAa,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,SAAS;IAEnB;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,QAAgB;QAC5B,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAC;QAC5B,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,yBAAyB,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACvE,CAAC;YACD,sCAAsC;YACtC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC5D,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;QAED,MAAM,IAAI,GAAa;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC;QACF,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC;YACH,iFAAiF;YACjF,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAChG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,+DAA+D;gBAC/D,MAAM,UAAU,GAAG,QAAQ,EAAE,CAAC;gBAC9B,IAAI,UAAU,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7C,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,yBAAyB,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBACzE,CAAC;gBACD,kCAAkC;gBAClC,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;gBACrC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;gBACzB,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAChG,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,4BAA4B;IAC5B,OAAO;QACL,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACzB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,MAAM;QACJ,OAAO,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,iDAAiD;IACjD,IAAI;QACF,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,+CAA+C;IAC/C,KAAK,CAAC,eAAe,CAAC,QAAgB;QACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO;QACxD,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;YACjD,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;YAChC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;CACO,CAAC"}
|
package/dist/src/core/sync.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export declare function matchesIgnore(relPath: string, patterns: readonly string
|
|
|
36
36
|
* @param agent Only return entries for specified agent, undefined = all
|
|
37
37
|
* @param filter Optional --only / --exclude filtering
|
|
38
38
|
*/
|
|
39
|
-
export declare function buildFileEntries(cfg: WangchuanConfig, repoDirBase?: string, agent?: AgentName, filter?: FilterOptions): FileEntry[];
|
|
39
|
+
export declare function buildFileEntries(cfg: WangchuanConfig, repoDirBase?: string, agent?: AgentName | string, filter?: FilterOptions): FileEntry[];
|
|
40
40
|
/**
|
|
41
41
|
* Actually delete stale files from repo (after user confirmation).
|
|
42
42
|
*/
|
|
@@ -74,9 +74,9 @@ export declare const syncEngine: {
|
|
|
74
74
|
/**
|
|
75
75
|
* Push: distribute shared content to all agents, then collect files to repo.
|
|
76
76
|
*/
|
|
77
|
-
readonly stageToRepo: (cfg: WangchuanConfig, agent?: AgentName, filter?: FilterOptions) => Promise<StageResult>;
|
|
78
|
-
readonly restoreFromRepo: (cfg: WangchuanConfig, agent?: AgentName, filter?: FilterOptions) => Promise<RestoreResult>;
|
|
79
|
-
readonly diff: (cfg: WangchuanConfig, agent?: AgentName, filter?: FilterOptions) => Promise<DiffResult>;
|
|
77
|
+
readonly stageToRepo: (cfg: WangchuanConfig, agent?: AgentName | string, filter?: FilterOptions) => Promise<StageResult>;
|
|
78
|
+
readonly restoreFromRepo: (cfg: WangchuanConfig, agent?: AgentName | string, filter?: FilterOptions) => Promise<RestoreResult>;
|
|
79
|
+
readonly diff: (cfg: WangchuanConfig, agent?: AgentName | string, filter?: FilterOptions) => Promise<DiffResult>;
|
|
80
80
|
};
|
|
81
81
|
export {};
|
|
82
82
|
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/core/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/core/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAgBH,OAAO,KAAK,EACV,eAAe,EACf,SAAS,EACT,WAAW,EACX,aAAa,EACb,UAAU,EACV,SAAS,EAGT,aAAa,EACb,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAGrB,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG5C;AAQD;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAW7C;AAED,qDAAqD;AACrD,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAenF;AA0PD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,EACpB,WAAW,CAAC,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,EAC1B,MAAM,CAAC,EAAE,aAAa,GACrB,SAAS,EAAE,CAyBb;AA2UD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CAqB7E;AAaD,6BAA6B;AAC7B,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAK/C;AAED,iDAAiD;AACjD,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAyBD,iCAAiC;AACjC,wBAAgB,wBAAwB,IAAI,mBAAmB,EAAE,CAKhE;AAED,mDAAmD;AACnD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ErF;AAoDD,wCAAwC;AACxC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAiBD,iBAAS,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAQvD;AA0KD,eAAO,MAAM,UAAU;;;;;;;;;;IAWrB;;OAEG;gCACoB,eAAe,UAAU,SAAS,GAAG,MAAM,WAAW,aAAa,KAAG,OAAO,CAAC,WAAW,CAAC;oCAqItF,eAAe,UAAU,SAAS,GAAG,MAAM,WAAW,aAAa,KAAG,OAAO,CAAC,aAAa,CAAC;yBA4QvG,eAAe,UAAU,SAAS,GAAG,MAAM,WAAW,aAAa,KAAG,OAAO,CAAC,UAAU,CAAC;CAwDjG,CAAC"}
|
package/dist/src/core/sync.js
CHANGED
|
@@ -20,6 +20,7 @@ import { cryptoEngine } from './crypto.js';
|
|
|
20
20
|
import { jsonField } from './json-field.js';
|
|
21
21
|
import { validator } from '../utils/validator.js';
|
|
22
22
|
import { logger } from '../utils/logger.js';
|
|
23
|
+
import { walkDir as walkDirBase } from '../utils/fs.js';
|
|
23
24
|
import { askConflict } from '../utils/prompt.js';
|
|
24
25
|
import { threeWayMerge } from './merge.js';
|
|
25
26
|
import { gitEngine } from './git.js';
|
|
@@ -117,24 +118,13 @@ function globMatch(str, pattern) {
|
|
|
117
118
|
regex += '$';
|
|
118
119
|
return new RegExp(regex).test(str);
|
|
119
120
|
}
|
|
121
|
+
/** Walk directory with .wangchuanignore filtering */
|
|
120
122
|
function walkDir(dirAbs) {
|
|
121
|
-
const results = [];
|
|
122
|
-
if (!fs.existsSync(dirAbs))
|
|
123
|
-
return results;
|
|
124
123
|
const ignorePatterns = loadIgnorePatterns();
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
if (ignorePatterns.length > 0 && matchesIgnore(subPath, ignorePatterns))
|
|
132
|
-
return;
|
|
133
|
-
results.push(subPath);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
fs.readdirSync(dirAbs).forEach(f => walk(f));
|
|
137
|
-
return results;
|
|
124
|
+
const filter = ignorePatterns.length > 0
|
|
125
|
+
? (relPath) => !matchesIgnore(relPath, ignorePatterns)
|
|
126
|
+
: undefined;
|
|
127
|
+
return walkDirBase(dirAbs, filter);
|
|
138
128
|
}
|
|
139
129
|
/** Deduplicate by repoRel, keeping the first occurrence */
|
|
140
130
|
function deduplicateEntries(entries) {
|
|
@@ -333,13 +323,21 @@ function applyFilter(entries, filter) {
|
|
|
333
323
|
export function buildFileEntries(cfg, repoDirBase, agent, filter) {
|
|
334
324
|
const entries = [];
|
|
335
325
|
const profiles = cfg.profiles.default;
|
|
336
|
-
// per-agent entries
|
|
326
|
+
// per-agent entries (built-in agents)
|
|
337
327
|
for (const name of AGENT_NAMES) {
|
|
338
328
|
const p = profiles[name];
|
|
339
329
|
if (!p.enabled || (agent && agent !== name))
|
|
340
330
|
continue;
|
|
341
331
|
entries.push(...buildAgentEntries(name, p, repoDirBase));
|
|
342
332
|
}
|
|
333
|
+
// custom agents (config-driven, basic file sync only)
|
|
334
|
+
if (cfg.customAgents) {
|
|
335
|
+
for (const [name, profile] of Object.entries(cfg.customAgents)) {
|
|
336
|
+
if (agent && agent !== name)
|
|
337
|
+
continue;
|
|
338
|
+
entries.push(...buildAgentEntries(name, profile, repoDirBase));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
343
341
|
// shared entries (excluded when --agent filter is active, since shared belongs to no single agent)
|
|
344
342
|
if (!agent) {
|
|
345
343
|
entries.push(...buildSharedEntries(cfg, repoDirBase));
|
|
@@ -1059,6 +1057,24 @@ function contentUnchanged(existingPath, newContent) {
|
|
|
1059
1057
|
const h2 = crypto.createHash('sha256').update(newContent).digest('hex');
|
|
1060
1058
|
return h1 === h2;
|
|
1061
1059
|
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Check if an encrypted file's plaintext matches new plaintext content.
|
|
1062
|
+
* Decrypts the existing .enc file and compares with the new plaintext,
|
|
1063
|
+
* avoiding false-positive diffs caused by random IV in AES-256-GCM.
|
|
1064
|
+
*/
|
|
1065
|
+
function encryptedPlaintextUnchanged(existingEncPath, newPlaintext, keyPath) {
|
|
1066
|
+
if (!fs.existsSync(existingEncPath))
|
|
1067
|
+
return false;
|
|
1068
|
+
try {
|
|
1069
|
+
const existingEnc = fs.readFileSync(existingEncPath, 'utf-8').trim();
|
|
1070
|
+
const existingPlain = cryptoEngine.decryptString(existingEnc, keyPath);
|
|
1071
|
+
return Buffer.from(existingPlain, 'utf-8').equals(newPlaintext);
|
|
1072
|
+
}
|
|
1073
|
+
catch {
|
|
1074
|
+
// Decryption failure (key changed, corrupted file) → treat as changed
|
|
1075
|
+
return false;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1062
1078
|
export const syncEngine = {
|
|
1063
1079
|
expandHome,
|
|
1064
1080
|
buildFileEntries,
|
|
@@ -1098,12 +1114,12 @@ export const syncEngine = {
|
|
|
1098
1114
|
const partial = jsonField.extractFields(fullJson, entry.jsonExtract.fields);
|
|
1099
1115
|
const content = JSON.stringify(partial, null, 2);
|
|
1100
1116
|
if (entry.encrypt) {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
if (contentUnchanged(destAbs, newBuf)) {
|
|
1117
|
+
// Compare plaintext to avoid false diffs from random IV
|
|
1118
|
+
if (encryptedPlaintextUnchanged(destAbs, Buffer.from(content, 'utf-8'), keyPath)) {
|
|
1104
1119
|
result.unchanged.push(entry.repoRel);
|
|
1105
1120
|
continue;
|
|
1106
1121
|
}
|
|
1122
|
+
const encrypted = cryptoEngine.encryptString(content, keyPath);
|
|
1107
1123
|
fs.writeFileSync(destAbs, encrypted, 'utf-8');
|
|
1108
1124
|
result.encrypted.push(entry.repoRel);
|
|
1109
1125
|
}
|
|
@@ -1140,6 +1156,12 @@ export const syncEngine = {
|
|
|
1140
1156
|
}
|
|
1141
1157
|
}
|
|
1142
1158
|
if (entry.encrypt) {
|
|
1159
|
+
// Compare plaintext to avoid false diffs from random IV
|
|
1160
|
+
const srcBuf = fs.readFileSync(entry.srcAbs);
|
|
1161
|
+
if (encryptedPlaintextUnchanged(destAbs, srcBuf, keyPath)) {
|
|
1162
|
+
result.unchanged.push(entry.repoRel);
|
|
1163
|
+
continue;
|
|
1164
|
+
}
|
|
1143
1165
|
cryptoEngine.encryptFile(entry.srcAbs, destAbs, keyPath);
|
|
1144
1166
|
result.encrypted.push(entry.repoRel);
|
|
1145
1167
|
progressIdx++;
|
|
@@ -1152,9 +1174,10 @@ export const syncEngine = {
|
|
|
1152
1174
|
}
|
|
1153
1175
|
result.synced.push(entry.repoRel);
|
|
1154
1176
|
}
|
|
1155
|
-
// ── Detect stale files in repo (full push only)
|
|
1156
|
-
//
|
|
1157
|
-
|
|
1177
|
+
// ── Detect stale files in repo (full push only, skip when filtering) ──
|
|
1178
|
+
// When --only/--exclude is active, the entry set is incomplete — stale detection
|
|
1179
|
+
// would wrongly flag legitimately synced files as stale, causing data loss.
|
|
1180
|
+
if (!agent && !filter) {
|
|
1158
1181
|
const syncedEntries = entries.filter(e => fs.existsSync(e.srcAbs));
|
|
1159
1182
|
const stale = detectStaleFiles(repoPath, syncedEntries);
|
|
1160
1183
|
if (stale.length > 0) {
|
|
@@ -1210,6 +1233,17 @@ export const syncEngine = {
|
|
|
1210
1233
|
result.skippedAgents.push(name);
|
|
1211
1234
|
}
|
|
1212
1235
|
}
|
|
1236
|
+
// Also check custom agents
|
|
1237
|
+
if (cfg.customAgents) {
|
|
1238
|
+
for (const [name, profile] of Object.entries(cfg.customAgents)) {
|
|
1239
|
+
if (agent && agent !== name)
|
|
1240
|
+
continue;
|
|
1241
|
+
const wsPath = expandHome(profile.workspacePath);
|
|
1242
|
+
if (!fs.existsSync(wsPath)) {
|
|
1243
|
+
result.skippedAgents.push(name);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1213
1247
|
// ── Verify integrity checksums before restore ────────────────
|
|
1214
1248
|
verifyIntegrity(repoPath);
|
|
1215
1249
|
// ── Backup local files before overwriting ────────────────────
|
|
@@ -1345,8 +1379,9 @@ export const syncEngine = {
|
|
|
1345
1379
|
}
|
|
1346
1380
|
if (isDiff) {
|
|
1347
1381
|
// ── Three-way merge for non-encrypted plain text files ──
|
|
1348
|
-
const
|
|
1349
|
-
|
|
1382
|
+
const ext = path.extname(entry.repoRel).toLowerCase();
|
|
1383
|
+
const MERGEABLE_EXTS = new Set(['.md', '.txt', '.json', '.yaml', '.yml']);
|
|
1384
|
+
const isTextMergeable = !entry.encrypt && MERGEABLE_EXTS.has(ext);
|
|
1350
1385
|
if (isTextMergeable && remoteContent !== undefined) {
|
|
1351
1386
|
// Try to get the base version from git history (pre-pull version)
|
|
1352
1387
|
const baseContent = await gitEngine.showFile(repoPath, 'HEAD~1', entry.repoRel);
|