@prover-coder-ai/context-doc 1.0.8 → 1.0.10
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/dist/shell/cli.js +5 -0
- package/dist/shell/codexSync.js +21 -7
- package/dist/shell/qwenSync.js +17 -2
- package/dist/shell/syncKnowledge.js +1 -13
- package/package.json +3 -3
- package/src/shell/cli.ts +7 -0
- package/src/shell/codexSync.ts +56 -19
- package/src/shell/qwenSync.ts +26 -16
- package/src/shell/syncKnowledge.ts +1 -18
package/dist/shell/codexSync.js
CHANGED
|
@@ -37,12 +37,16 @@ const resolveSourceDir = (cwd, override, metaRoot) => pipe(Effect.sync(() => {
|
|
|
37
37
|
: path.join(metaRoot, ".codex");
|
|
38
38
|
const localSource = path.join(cwd, ".codex");
|
|
39
39
|
const homeSource = path.join(os.homedir(), ".codex");
|
|
40
|
+
const localKnowledge = path.join(cwd, ".knowledge", ".codex");
|
|
41
|
+
const homeKnowledge = path.join(os.homedir(), ".knowledge", ".codex");
|
|
40
42
|
const candidates = [
|
|
41
43
|
override,
|
|
42
44
|
envSource,
|
|
43
45
|
metaCandidate,
|
|
44
46
|
localSource,
|
|
45
47
|
homeSource,
|
|
48
|
+
localKnowledge,
|
|
49
|
+
homeKnowledge,
|
|
46
50
|
].filter((candidate) => candidate !== undefined);
|
|
47
51
|
const existing = candidates.find((candidate) => fs.existsSync(candidate));
|
|
48
52
|
return { existing, candidates };
|
|
@@ -92,6 +96,17 @@ const selectRelevantFiles = (files, locator) => Effect.reduce(files, [], (acc, f
|
|
|
92
96
|
}
|
|
93
97
|
return acc;
|
|
94
98
|
})));
|
|
99
|
+
const resolveLocator = (options) => pipe(readRepositoryUrl(options.cwd, options.repositoryUrlOverride), Effect.map((repositoryUrl) => buildProjectLocator(repositoryUrl, options.cwd)), Effect.catchAll(() => Effect.gen(function* (__) {
|
|
100
|
+
yield* __(Console.log("Codex repository url missing; falling back to cwd-only match"));
|
|
101
|
+
return buildProjectLocator(options.cwd, options.cwd);
|
|
102
|
+
})));
|
|
103
|
+
const copyCodexFiles = (sourceDir, destinationDir, locator) => Effect.gen(function* (_) {
|
|
104
|
+
yield* _(ensureDirectory(destinationDir));
|
|
105
|
+
const allJsonlFiles = yield* _(collectJsonlFiles(sourceDir));
|
|
106
|
+
const relevantFiles = yield* _(selectRelevantFiles(allJsonlFiles, locator));
|
|
107
|
+
yield* _(Effect.forEach(relevantFiles, (filePath) => copyRelevantFile(sourceDir, destinationDir, filePath)));
|
|
108
|
+
yield* _(Console.log(`Codex: copied ${relevantFiles.length} files from ${sourceDir} to ${destinationDir}`));
|
|
109
|
+
});
|
|
95
110
|
// CHANGE: Extract Codex dialog sync into dedicated module for clarity.
|
|
96
111
|
// WHY: Separate Codex-specific shell effects from other sync flows.
|
|
97
112
|
// QUOTE(ТЗ): "вынеси в отдельный файл"
|
|
@@ -103,13 +118,12 @@ const selectRelevantFiles = (files, locator) => Effect.reduce(files, [], (acc, f
|
|
|
103
118
|
// INVARIANT: ∀f ∈ copiedFiles: linesMatchProject(f, locator)
|
|
104
119
|
// COMPLEXITY: O(n) time / O(n) space, n = |files|
|
|
105
120
|
export const syncCodex = (options) => Effect.gen(function* (_) {
|
|
106
|
-
const
|
|
121
|
+
const locator = yield* _(resolveLocator(options));
|
|
107
122
|
const sourceDir = yield* _(resolveSourceDir(options.cwd, options.sourceDir, options.metaRoot));
|
|
108
123
|
const destinationDir = options.destinationDir ?? path.join(options.cwd, ".knowledge", ".codex");
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
yield* _(
|
|
114
|
-
yield* _(Console.log(`Synced ${relevantFiles.length} dialog files into .knowledge/.codex from ${sourceDir}`));
|
|
124
|
+
if (path.resolve(sourceDir) === path.resolve(destinationDir)) {
|
|
125
|
+
yield* _(Console.log("Codex source equals destination; skipping copy to avoid duplicates"));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
yield* _(copyCodexFiles(sourceDir, destinationDir, locator));
|
|
115
129
|
}).pipe(Effect.catchAll((error) => Console.log(`Codex source not found; skipped syncing Codex dialog files (${error.reason})`)));
|
package/dist/shell/qwenSync.js
CHANGED
|
@@ -34,18 +34,33 @@ const resolveQwenSourceDir = (cwd, override, metaRoot) => Effect.gen(function* (
|
|
|
34
34
|
: metaRoot.endsWith(".qwen")
|
|
35
35
|
? metaRoot
|
|
36
36
|
: path.join(metaRoot, ".qwen");
|
|
37
|
+
const metaKnowledge = path.join(metaRoot ?? "", ".knowledge", ".qwen");
|
|
37
38
|
const homeBase = path.join(os.homedir(), ".qwen");
|
|
39
|
+
const homeKnowledge = path.join(os.homedir(), ".knowledge", ".qwen");
|
|
38
40
|
const candidates = [
|
|
39
41
|
override,
|
|
40
42
|
envSource,
|
|
41
43
|
baseFromMeta ? path.join(baseFromMeta, "tmp", hash) : undefined,
|
|
42
44
|
path.join(cwd, ".qwen", "tmp", hash),
|
|
45
|
+
path.join(cwd, ".knowledge", ".qwen", "tmp", hash),
|
|
46
|
+
metaKnowledge ? path.join(metaKnowledge, "tmp", hash) : undefined,
|
|
43
47
|
path.join(homeBase, "tmp", hash),
|
|
48
|
+
path.join(homeKnowledge, "tmp", hash),
|
|
44
49
|
].filter((candidate) => candidate !== undefined);
|
|
45
50
|
const found = candidates.find((candidate) => fs.existsSync(candidate));
|
|
46
51
|
if (found === undefined) {
|
|
47
|
-
return yield* _(Effect.fail(syncError(".qwen", `Qwen source directory is missing
|
|
52
|
+
return yield* _(Effect.fail(syncError(".qwen", `Qwen source directory is missing for hash ${hash}`)));
|
|
48
53
|
}
|
|
49
54
|
return found;
|
|
50
55
|
});
|
|
51
|
-
export const syncQwen = (options) => pipe(resolveQwenSourceDir(options.cwd, options.qwenSourceDir, options.metaRoot), Effect.
|
|
56
|
+
export const syncQwen = (options) => pipe(resolveQwenSourceDir(options.cwd, options.qwenSourceDir, options.metaRoot), Effect.flatMap((qwenSource) => Effect.gen(function* (_) {
|
|
57
|
+
const destination = path.join(options.cwd, ".knowledge", ".qwen");
|
|
58
|
+
if (path.resolve(qwenSource) === path.resolve(destination)) {
|
|
59
|
+
yield* _(Console.log("Qwen source equals destination; skipping copy to avoid duplicates"));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
yield* _(ensureDirectory(destination));
|
|
63
|
+
const qwenRoot = path.dirname(path.dirname(qwenSource));
|
|
64
|
+
const copiedCount = yield* _(copyDirectoryJsonOnly(qwenSource, destination));
|
|
65
|
+
yield* _(Console.log(`Qwen: copied ${copiedCount} files from ${qwenRoot} to ${destination}`));
|
|
66
|
+
})), Effect.catchAll((error) => Console.log(`Qwen source not found; skipped syncing Qwen dialog files (${error.reason})`)));
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { pathToFileURL } from "node:url";
|
|
3
2
|
import { Effect } from "effect";
|
|
4
3
|
import { syncCodex } from "./codexSync.js";
|
|
5
4
|
import { syncQwen } from "./qwenSync.js";
|
|
@@ -8,14 +7,7 @@ export const buildSyncProgram = (options) => Effect.gen(function* (_) {
|
|
|
8
7
|
yield* _(syncCodex(options));
|
|
9
8
|
yield* _(syncQwen(options));
|
|
10
9
|
});
|
|
11
|
-
const
|
|
12
|
-
const entry = process.argv[1];
|
|
13
|
-
if (entry === undefined) {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
return import.meta.url === pathToFileURL(entry).href;
|
|
17
|
-
};
|
|
18
|
-
const parseArgs = () => {
|
|
10
|
+
export const parseArgs = () => {
|
|
19
11
|
const argv = process.argv.slice(2);
|
|
20
12
|
let result = { cwd: process.cwd() };
|
|
21
13
|
const mapping = {
|
|
@@ -42,7 +34,3 @@ const parseArgs = () => {
|
|
|
42
34
|
}
|
|
43
35
|
return result;
|
|
44
36
|
};
|
|
45
|
-
if (isMainModule()) {
|
|
46
|
-
const program = buildSyncProgram(parseArgs());
|
|
47
|
-
Effect.runSync(program);
|
|
48
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prover-coder-ai/context-doc",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
"build": "tsc -p tsconfig.build.json",
|
|
9
9
|
"lint": "npx --no-install @ton-ai-core/vibecode-linter src/",
|
|
10
10
|
"test": "npx --no-install @ton-ai-core/vibecode-linter tests/ && vitest run --passWithNoTests",
|
|
11
|
-
"sync:knowledge": "
|
|
11
|
+
"sync:knowledge": "npm run build && PKG=prover-coder-ai-context-doc-$(node -p \"require('./package.json').version\").tgz && rm -f \"$PKG\" && npm pack >/dev/null && npx -y -p \"./$PKG\" context-doc",
|
|
12
12
|
"release": "npm run build && npm run lint && npm version patch && npm publish --access public"
|
|
13
13
|
},
|
|
14
14
|
"bin": {
|
|
15
|
-
"context-doc": "dist/shell/
|
|
15
|
+
"context-doc": "dist/shell/cli.js"
|
|
16
16
|
},
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
package/src/shell/cli.ts
ADDED
package/src/shell/codexSync.ts
CHANGED
|
@@ -57,12 +57,17 @@ const resolveSourceDir = (
|
|
|
57
57
|
: path.join(metaRoot, ".codex");
|
|
58
58
|
const localSource = path.join(cwd, ".codex");
|
|
59
59
|
const homeSource = path.join(os.homedir(), ".codex");
|
|
60
|
+
const localKnowledge = path.join(cwd, ".knowledge", ".codex");
|
|
61
|
+
const homeKnowledge = path.join(os.homedir(), ".knowledge", ".codex");
|
|
62
|
+
|
|
60
63
|
const candidates = [
|
|
61
64
|
override,
|
|
62
65
|
envSource,
|
|
63
66
|
metaCandidate,
|
|
64
67
|
localSource,
|
|
65
68
|
homeSource,
|
|
69
|
+
localKnowledge,
|
|
70
|
+
homeKnowledge,
|
|
66
71
|
].filter((candidate): candidate is string => candidate !== undefined);
|
|
67
72
|
|
|
68
73
|
const existing = candidates.find((candidate) => fs.existsSync(candidate));
|
|
@@ -150,6 +155,47 @@ const selectRelevantFiles = (
|
|
|
150
155
|
),
|
|
151
156
|
);
|
|
152
157
|
|
|
158
|
+
const resolveLocator = (
|
|
159
|
+
options: SyncOptions,
|
|
160
|
+
): Effect.Effect<ProjectLocator, SyncError> =>
|
|
161
|
+
pipe(
|
|
162
|
+
readRepositoryUrl(options.cwd, options.repositoryUrlOverride),
|
|
163
|
+
Effect.map((repositoryUrl) =>
|
|
164
|
+
buildProjectLocator(repositoryUrl, options.cwd),
|
|
165
|
+
),
|
|
166
|
+
Effect.catchAll(() =>
|
|
167
|
+
Effect.gen(function* (__) {
|
|
168
|
+
yield* __(
|
|
169
|
+
Console.log(
|
|
170
|
+
"Codex repository url missing; falling back to cwd-only match",
|
|
171
|
+
),
|
|
172
|
+
);
|
|
173
|
+
return buildProjectLocator(options.cwd, options.cwd);
|
|
174
|
+
}),
|
|
175
|
+
),
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const copyCodexFiles = (
|
|
179
|
+
sourceDir: string,
|
|
180
|
+
destinationDir: string,
|
|
181
|
+
locator: ProjectLocator,
|
|
182
|
+
): Effect.Effect<void, SyncError> =>
|
|
183
|
+
Effect.gen(function* (_) {
|
|
184
|
+
yield* _(ensureDirectory(destinationDir));
|
|
185
|
+
const allJsonlFiles = yield* _(collectJsonlFiles(sourceDir));
|
|
186
|
+
const relevantFiles = yield* _(selectRelevantFiles(allJsonlFiles, locator));
|
|
187
|
+
yield* _(
|
|
188
|
+
Effect.forEach(relevantFiles, (filePath) =>
|
|
189
|
+
copyRelevantFile(sourceDir, destinationDir, filePath),
|
|
190
|
+
),
|
|
191
|
+
);
|
|
192
|
+
yield* _(
|
|
193
|
+
Console.log(
|
|
194
|
+
`Codex: copied ${relevantFiles.length} files from ${sourceDir} to ${destinationDir}`,
|
|
195
|
+
),
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
|
|
153
199
|
// CHANGE: Extract Codex dialog sync into dedicated module for clarity.
|
|
154
200
|
// WHY: Separate Codex-specific shell effects from other sync flows.
|
|
155
201
|
// QUOTE(ТЗ): "вынеси в отдельный файл"
|
|
@@ -164,32 +210,23 @@ export const syncCodex = (
|
|
|
164
210
|
options: SyncOptions,
|
|
165
211
|
): Effect.Effect<void, SyncError> =>
|
|
166
212
|
Effect.gen(function* (_) {
|
|
167
|
-
const
|
|
168
|
-
readRepositoryUrl(options.cwd, options.repositoryUrlOverride),
|
|
169
|
-
);
|
|
213
|
+
const locator = yield* _(resolveLocator(options));
|
|
170
214
|
const sourceDir = yield* _(
|
|
171
215
|
resolveSourceDir(options.cwd, options.sourceDir, options.metaRoot),
|
|
172
216
|
);
|
|
173
217
|
const destinationDir =
|
|
174
218
|
options.destinationDir ?? path.join(options.cwd, ".knowledge", ".codex");
|
|
175
219
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
copyRelevantFile(sourceDir, destinationDir, filePath),
|
|
185
|
-
),
|
|
186
|
-
);
|
|
220
|
+
if (path.resolve(sourceDir) === path.resolve(destinationDir)) {
|
|
221
|
+
yield* _(
|
|
222
|
+
Console.log(
|
|
223
|
+
"Codex source equals destination; skipping copy to avoid duplicates",
|
|
224
|
+
),
|
|
225
|
+
);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
187
228
|
|
|
188
|
-
yield* _(
|
|
189
|
-
Console.log(
|
|
190
|
-
`Synced ${relevantFiles.length} dialog files into .knowledge/.codex from ${sourceDir}`,
|
|
191
|
-
),
|
|
192
|
-
);
|
|
229
|
+
yield* _(copyCodexFiles(sourceDir, destinationDir, locator));
|
|
193
230
|
}).pipe(
|
|
194
231
|
Effect.catchAll((error) =>
|
|
195
232
|
Console.log(
|
package/src/shell/qwenSync.ts
CHANGED
|
@@ -49,14 +49,19 @@ const resolveQwenSourceDir = (
|
|
|
49
49
|
: metaRoot.endsWith(".qwen")
|
|
50
50
|
? metaRoot
|
|
51
51
|
: path.join(metaRoot, ".qwen");
|
|
52
|
+
const metaKnowledge = path.join(metaRoot ?? "", ".knowledge", ".qwen");
|
|
52
53
|
const homeBase = path.join(os.homedir(), ".qwen");
|
|
54
|
+
const homeKnowledge = path.join(os.homedir(), ".knowledge", ".qwen");
|
|
53
55
|
|
|
54
56
|
const candidates = [
|
|
55
57
|
override,
|
|
56
58
|
envSource,
|
|
57
59
|
baseFromMeta ? path.join(baseFromMeta, "tmp", hash) : undefined,
|
|
58
60
|
path.join(cwd, ".qwen", "tmp", hash),
|
|
61
|
+
path.join(cwd, ".knowledge", ".qwen", "tmp", hash),
|
|
62
|
+
metaKnowledge ? path.join(metaKnowledge, "tmp", hash) : undefined,
|
|
59
63
|
path.join(homeBase, "tmp", hash),
|
|
64
|
+
path.join(homeKnowledge, "tmp", hash),
|
|
60
65
|
].filter((candidate): candidate is string => candidate !== undefined);
|
|
61
66
|
|
|
62
67
|
const found = candidates.find((candidate) => fs.existsSync(candidate));
|
|
@@ -66,7 +71,7 @@ const resolveQwenSourceDir = (
|
|
|
66
71
|
Effect.fail(
|
|
67
72
|
syncError(
|
|
68
73
|
".qwen",
|
|
69
|
-
`Qwen source directory is missing
|
|
74
|
+
`Qwen source directory is missing for hash ${hash}`,
|
|
70
75
|
),
|
|
71
76
|
),
|
|
72
77
|
);
|
|
@@ -80,24 +85,29 @@ export const syncQwen = (
|
|
|
80
85
|
): Effect.Effect<void, SyncError> =>
|
|
81
86
|
pipe(
|
|
82
87
|
resolveQwenSourceDir(options.cwd, options.qwenSourceDir, options.metaRoot),
|
|
83
|
-
Effect.tap((qwenSource) =>
|
|
84
|
-
Console.log(`Qwen source resolved: ${qwenSource}`),
|
|
85
|
-
),
|
|
86
88
|
Effect.flatMap((qwenSource) =>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
Effect.gen(function* (_) {
|
|
90
|
+
const destination = path.join(options.cwd, ".knowledge", ".qwen");
|
|
91
|
+
if (path.resolve(qwenSource) === path.resolve(destination)) {
|
|
92
|
+
yield* _(
|
|
93
|
+
Console.log(
|
|
94
|
+
"Qwen source equals destination; skipping copy to avoid duplicates",
|
|
95
|
+
),
|
|
96
|
+
);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
yield* _(ensureDirectory(destination));
|
|
101
|
+
const qwenRoot = path.dirname(path.dirname(qwenSource));
|
|
102
|
+
const copiedCount = yield* _(
|
|
103
|
+
copyDirectoryJsonOnly(qwenSource, destination),
|
|
104
|
+
);
|
|
105
|
+
yield* _(
|
|
96
106
|
Console.log(
|
|
97
|
-
`
|
|
107
|
+
`Qwen: copied ${copiedCount} files from ${qwenRoot} to ${destination}`,
|
|
98
108
|
),
|
|
99
|
-
)
|
|
100
|
-
),
|
|
109
|
+
);
|
|
110
|
+
}),
|
|
101
111
|
),
|
|
102
112
|
Effect.catchAll((error) =>
|
|
103
113
|
Console.log(
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { pathToFileURL } from "node:url";
|
|
3
2
|
import { Effect } from "effect";
|
|
4
3
|
import { syncCodex } from "./codexSync.js";
|
|
5
4
|
import { syncQwen } from "./qwenSync.js";
|
|
@@ -14,17 +13,7 @@ export const buildSyncProgram = (
|
|
|
14
13
|
yield* _(syncQwen(options));
|
|
15
14
|
});
|
|
16
15
|
|
|
17
|
-
const
|
|
18
|
-
const entry = process.argv[1];
|
|
19
|
-
|
|
20
|
-
if (entry === undefined) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return import.meta.url === pathToFileURL(entry).href;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const parseArgs = (): SyncOptions => {
|
|
16
|
+
export const parseArgs = (): SyncOptions => {
|
|
28
17
|
const argv = process.argv.slice(2);
|
|
29
18
|
let result: SyncOptions = { cwd: process.cwd() };
|
|
30
19
|
|
|
@@ -55,9 +44,3 @@ const parseArgs = (): SyncOptions => {
|
|
|
55
44
|
|
|
56
45
|
return result;
|
|
57
46
|
};
|
|
58
|
-
|
|
59
|
-
if (isMainModule()) {
|
|
60
|
-
const program = buildSyncProgram(parseArgs());
|
|
61
|
-
|
|
62
|
-
Effect.runSync(program);
|
|
63
|
-
}
|