@forwardimpact/libwiki 0.2.18 → 0.2.19
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/package.json +2 -2
- package/src/commands/claim.js +3 -1
- package/src/wiki-sync.js +26 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forwardimpact/libwiki",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.19",
|
|
4
4
|
"description": "Wiki lifecycle primitives — stable memory for agent teams so coordination persists across sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wiki",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@forwardimpact/libeval": "^0.1.49",
|
|
51
51
|
"@forwardimpact/libpreflight": "^0.1.0",
|
|
52
52
|
"@forwardimpact/libutil": "^0.1.0",
|
|
53
|
-
"@forwardimpact/libxmr": "^
|
|
53
|
+
"@forwardimpact/libxmr": "^2.0.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@forwardimpact/libmock": "^0.1.0"
|
package/src/commands/claim.js
CHANGED
|
@@ -22,7 +22,9 @@ async function pushWiki(wikiSync, runtime, message) {
|
|
|
22
22
|
if (!wikiSync) return;
|
|
23
23
|
try {
|
|
24
24
|
await wikiSync.inheritIdentity();
|
|
25
|
-
|
|
25
|
+
// claim/release contract is a 1-line MEMORY.md change; the pathspec keeps
|
|
26
|
+
// foreign uncommitted files from parallel writers out of the commit.
|
|
27
|
+
const result = await wikiSync.commitAndPush(message, ["MEMORY.md"]);
|
|
26
28
|
if (result.pushed)
|
|
27
29
|
runtime.proc.stdout.write("push: committed and pushed\n");
|
|
28
30
|
} catch (err) {
|
package/src/wiki-sync.js
CHANGED
|
@@ -102,9 +102,13 @@ export class WikiSync {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
/**
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Whether the wiki working tree has no uncommitted changes, optionally
|
|
107
|
+
* limited to `paths`.
|
|
108
|
+
* @param {string[]} [paths] - Pathspecs to scope the check to.
|
|
109
|
+
*/
|
|
110
|
+
async isClean(paths) {
|
|
111
|
+
const r = await this.#git.status({ cwd: this.#wikiDir, paths });
|
|
108
112
|
return r.stdout.trim() === "";
|
|
109
113
|
}
|
|
110
114
|
|
|
@@ -119,14 +123,27 @@ export class WikiSync {
|
|
|
119
123
|
}
|
|
120
124
|
|
|
121
125
|
/**
|
|
122
|
-
* Stage and commit
|
|
126
|
+
* Stage and commit working-tree changes, then fetch, rebase on
|
|
123
127
|
* origin/master (falling back to a merge with -X ours if the rebase fails),
|
|
124
128
|
* and push if HEAD is ahead of origin/master. The commit gate and the push
|
|
125
129
|
* gate are independent so a clean tree with local commits still pushes.
|
|
130
|
+
*
|
|
131
|
+
* Without `paths` the commit sweeps the whole tree (`fit-wiki push`
|
|
132
|
+
* contract). With `paths` the commit is pathspec-scoped so foreign residue
|
|
133
|
+
* from parallel writers in the shared workspace is never swept in; the
|
|
134
|
+
* rebase and merge fallback then run with --autostash because that residue
|
|
135
|
+
* stays uncommitted in the tree.
|
|
136
|
+
*
|
|
137
|
+
* @param {string} message - The commit message.
|
|
138
|
+
* @param {string[]} [paths] - Pathspecs limiting what gets committed.
|
|
126
139
|
*/
|
|
127
|
-
async commitAndPush(message) {
|
|
128
|
-
if (!(await this.isClean())) {
|
|
129
|
-
|
|
140
|
+
async commitAndPush(message, paths) {
|
|
141
|
+
if (!(await this.isClean(paths))) {
|
|
142
|
+
if (paths?.length) {
|
|
143
|
+
await this.#git.commitPaths(message, paths, { cwd: this.#wikiDir });
|
|
144
|
+
} else {
|
|
145
|
+
await this.#git.commitAll(message, { cwd: this.#wikiDir });
|
|
146
|
+
}
|
|
130
147
|
}
|
|
131
148
|
if (!(await this.#hasCommitsAhead())) {
|
|
132
149
|
return { pushed: false, reason: "clean" };
|
|
@@ -134,12 +151,14 @@ export class WikiSync {
|
|
|
134
151
|
await this.fetch();
|
|
135
152
|
const rebase = await this.#git.rebase("origin/master", {
|
|
136
153
|
cwd: this.#wikiDir,
|
|
154
|
+
autostash: true,
|
|
137
155
|
});
|
|
138
156
|
if (rebase.exitCode !== 0) {
|
|
139
157
|
await this.#git.rebaseAbort({ cwd: this.#wikiDir });
|
|
140
158
|
await this.#git.mergeOursStrategy({
|
|
141
159
|
cwd: this.#wikiDir,
|
|
142
160
|
ref: "origin/master",
|
|
161
|
+
autostash: true,
|
|
143
162
|
});
|
|
144
163
|
}
|
|
145
164
|
// Resolve auth first so a misconfigured `resolveToken` still surfaces; the
|