@aigne/doc-smith 0.4.5 → 0.5.1
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/CHANGELOG.md +19 -0
- package/agents/batch-translate.yaml +3 -0
- package/agents/check-feedback-refiner.mjs +79 -0
- package/agents/check-structure-plan.mjs +16 -0
- package/agents/detail-generator-and-translate.yaml +3 -0
- package/agents/detail-regenerator.yaml +3 -0
- package/agents/docs-generator.yaml +3 -0
- package/agents/feedback-refiner.yaml +48 -0
- package/agents/find-items-by-paths.mjs +5 -1
- package/agents/find-user-preferences-by-path.mjs +37 -0
- package/agents/input-generator.mjs +8 -9
- package/agents/manage-prefs.mjs +203 -0
- package/agents/publish-docs.mjs +1 -1
- package/agents/retranslate.yaml +3 -0
- package/agents/structure-planning.yaml +3 -0
- package/aigne.yaml +4 -0
- package/package.json +3 -2
- package/prompts/content-detail-generator.md +8 -0
- package/prompts/feedback-refiner.md +84 -0
- package/prompts/structure-planning.md +8 -0
- package/prompts/translator.md +8 -0
- package/tests/{test-all-validation-cases.mjs → all-validation-cases.test.mjs} +60 -137
- package/tests/check-detail-result.test.mjs +46 -82
- package/tests/load-sources.test.mjs +103 -291
- package/tests/preferences-utils.test.mjs +369 -0
- package/tests/{test-save-docs.mjs → save-docs.test.mjs} +29 -47
- package/tests/save-value-to-config.test.mjs +165 -288
- package/utils/constants.mjs +8 -8
- package/utils/preferences-utils.mjs +175 -0
- package/utils/utils.mjs +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { parse, stringify } from "yaml";
|
|
5
|
+
|
|
6
|
+
const PREFERENCES_DIR = ".aigne/doc-smith";
|
|
7
|
+
const PREFERENCES_FILE = "preferences.yml";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generate a random preference ID
|
|
11
|
+
* @returns {string} Random ID with pref_ prefix
|
|
12
|
+
*/
|
|
13
|
+
function generatePreferenceId() {
|
|
14
|
+
return `pref_${randomBytes(8).toString("hex")}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the full path to the preferences file
|
|
19
|
+
* @returns {string} Full path to preferences.yml
|
|
20
|
+
*/
|
|
21
|
+
function getPreferencesFilePath() {
|
|
22
|
+
return join(process.cwd(), PREFERENCES_DIR, PREFERENCES_FILE);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Ensure the preferences directory exists
|
|
27
|
+
*/
|
|
28
|
+
function ensurePreferencesDir() {
|
|
29
|
+
const preferencesDir = join(process.cwd(), PREFERENCES_DIR);
|
|
30
|
+
if (!existsSync(preferencesDir)) {
|
|
31
|
+
mkdirSync(preferencesDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Read existing preferences from file
|
|
37
|
+
* @returns {Object} Preferences object with rules array
|
|
38
|
+
*/
|
|
39
|
+
export function readPreferences() {
|
|
40
|
+
const filePath = getPreferencesFilePath();
|
|
41
|
+
|
|
42
|
+
if (!existsSync(filePath)) {
|
|
43
|
+
return { rules: [] };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const content = readFileSync(filePath, "utf8");
|
|
48
|
+
const preferences = parse(content);
|
|
49
|
+
return preferences || { rules: [] };
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.warn(`Warning: Failed to read preferences file at ${filePath}: ${error.message}`);
|
|
52
|
+
return { rules: [] };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Write preferences to file
|
|
58
|
+
* @param {Object} preferences - Preferences object to save
|
|
59
|
+
*/
|
|
60
|
+
export function writePreferences(preferences) {
|
|
61
|
+
ensurePreferencesDir();
|
|
62
|
+
const filePath = getPreferencesFilePath();
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const yamlContent = stringify(preferences, {
|
|
66
|
+
indent: 2,
|
|
67
|
+
lineWidth: 120,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
writeFileSync(filePath, yamlContent, "utf8");
|
|
71
|
+
} catch (error) {
|
|
72
|
+
throw new Error(`Failed to write preferences file: ${error.message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Add a new preference rule
|
|
78
|
+
* @param {Object} ruleData - Rule data from feedbackRefiner
|
|
79
|
+
* @param {string} ruleData.rule - The rule text
|
|
80
|
+
* @param {string} ruleData.scope - Rule scope (global, structure, document, translation)
|
|
81
|
+
* @param {boolean} ruleData.limitToInputPaths - Whether to limit to input paths
|
|
82
|
+
* @param {string} feedback - Original user feedback
|
|
83
|
+
* @param {string[]} [paths] - Optional paths to save with the rule
|
|
84
|
+
* @returns {Object} The created preference rule
|
|
85
|
+
*/
|
|
86
|
+
export function addPreferenceRule(ruleData, feedback, paths = []) {
|
|
87
|
+
const preferences = readPreferences();
|
|
88
|
+
|
|
89
|
+
const newRule = {
|
|
90
|
+
id: generatePreferenceId(),
|
|
91
|
+
active: true,
|
|
92
|
+
scope: ruleData.scope,
|
|
93
|
+
rule: ruleData.rule,
|
|
94
|
+
feedback: feedback,
|
|
95
|
+
createdAt: new Date().toISOString(),
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Add paths if limitToInputPaths is true and paths are provided
|
|
99
|
+
if (ruleData.limitToInputPaths && paths && paths.length > 0) {
|
|
100
|
+
newRule.paths = paths;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Add the new rule to the beginning of the array (newest first)
|
|
104
|
+
preferences.rules.unshift(newRule);
|
|
105
|
+
|
|
106
|
+
writePreferences(preferences);
|
|
107
|
+
|
|
108
|
+
return newRule;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get all active preference rules for a specific scope
|
|
113
|
+
* @param {string} scope - The scope to filter by (global, structure, document, translation)
|
|
114
|
+
* @param {string[]} [currentPaths] - Current paths to match against rules with path restrictions
|
|
115
|
+
* @returns {Object[]} Array of matching active rules
|
|
116
|
+
*/
|
|
117
|
+
export function getActiveRulesForScope(scope, currentPaths = []) {
|
|
118
|
+
const preferences = readPreferences();
|
|
119
|
+
|
|
120
|
+
return preferences.rules.filter((rule) => {
|
|
121
|
+
// Must be active and match scope
|
|
122
|
+
if (!rule.active || rule.scope !== scope) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// If rule has path restrictions, check if any current path matches
|
|
127
|
+
if (rule.paths && rule.paths.length > 0) {
|
|
128
|
+
if (currentPaths.length === 0) {
|
|
129
|
+
return false; // Rule has path restrictions but no current paths provided
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check if any current path matches any rule path pattern
|
|
133
|
+
return currentPaths.some((currentPath) => rule.paths.includes(currentPath));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return true; // No path restrictions, include the rule
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Deactivate a preference rule by ID
|
|
142
|
+
* @param {string} ruleId - The ID of the rule to deactivate
|
|
143
|
+
* @returns {boolean} True if rule was found and deactivated
|
|
144
|
+
*/
|
|
145
|
+
export function deactivateRule(ruleId) {
|
|
146
|
+
const preferences = readPreferences();
|
|
147
|
+
const rule = preferences.rules.find((r) => r.id === ruleId);
|
|
148
|
+
|
|
149
|
+
if (rule) {
|
|
150
|
+
rule.active = false;
|
|
151
|
+
writePreferences(preferences);
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Remove a preference rule by ID
|
|
160
|
+
* @param {string} ruleId - The ID of the rule to remove
|
|
161
|
+
* @returns {boolean} True if rule was found and removed
|
|
162
|
+
*/
|
|
163
|
+
export function removeRule(ruleId) {
|
|
164
|
+
const preferences = readPreferences();
|
|
165
|
+
const initialLength = preferences.rules.length;
|
|
166
|
+
|
|
167
|
+
preferences.rules = preferences.rules.filter((r) => r.id !== ruleId);
|
|
168
|
+
|
|
169
|
+
if (preferences.rules.length < initialLength) {
|
|
170
|
+
writePreferences(preferences);
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return false;
|
|
175
|
+
}
|
package/utils/utils.mjs
CHANGED