@git.zone/tsdoc 1.11.4 → 2.0.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/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/aidocs_classes/commit.js +81 -86
- package/dist_ts/aidocs_classes/description.js +29 -48
- package/dist_ts/aidocs_classes/readme.js +57 -95
- package/dist_ts/classes.aidoc.d.ts +1 -6
- package/dist_ts/classes.aidoc.js +7 -17
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/package.json +13 -13
- package/readme.hints.md +10 -1
- package/readme.md +137 -313
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/aidocs_classes/commit.ts +84 -87
- package/ts/aidocs_classes/description.ts +31 -51
- package/ts/aidocs_classes/readme.ts +57 -96
- package/ts/classes.aidoc.ts +10 -21
- package/ts/plugins.ts +2 -0
|
@@ -4,6 +4,25 @@ import { ProjectContext } from './projectcontext.js';
|
|
|
4
4
|
import { DiffProcessor } from '../classes.diffprocessor.js';
|
|
5
5
|
import { logger } from '../logging.js';
|
|
6
6
|
|
|
7
|
+
// Token budget configuration for OpenAI API limits
|
|
8
|
+
const TOKEN_BUDGET = {
|
|
9
|
+
OPENAI_CONTEXT_LIMIT: 272000, // OpenAI's configured limit
|
|
10
|
+
SAFETY_MARGIN: 10000, // Buffer to avoid hitting exact limit
|
|
11
|
+
SMARTAGENT_OVERHEAD: 180000, // System msgs, tools, history, formatting
|
|
12
|
+
TASK_PROMPT_OVERHEAD: 2000, // Task prompt template size
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Calculate max tokens available for diff content based on total budget
|
|
17
|
+
*/
|
|
18
|
+
function calculateMaxDiffTokens(): number {
|
|
19
|
+
const available = TOKEN_BUDGET.OPENAI_CONTEXT_LIMIT
|
|
20
|
+
- TOKEN_BUDGET.SAFETY_MARGIN
|
|
21
|
+
- TOKEN_BUDGET.SMARTAGENT_OVERHEAD
|
|
22
|
+
- TOKEN_BUDGET.TASK_PROMPT_OVERHEAD;
|
|
23
|
+
return Math.max(available, 30000);
|
|
24
|
+
}
|
|
25
|
+
|
|
7
26
|
export interface INextCommitObject {
|
|
8
27
|
recommendedNextVersionLevel: 'fix' | 'feat' | 'BREAKING CHANGE'; // the recommended next version level of the project
|
|
9
28
|
recommendedNextVersionScope: string; // the recommended scope name of the next version, like "core" or "cli", or specific class names.
|
|
@@ -84,15 +103,19 @@ export class Commit {
|
|
|
84
103
|
const totalChars = diffStringArray.join('\n\n').length;
|
|
85
104
|
const estimatedTokens = Math.ceil(totalChars / 4);
|
|
86
105
|
|
|
87
|
-
console.log(
|
|
106
|
+
console.log(`Raw git diff statistics:`);
|
|
88
107
|
console.log(` Files changed: ${diffStringArray.length}`);
|
|
89
108
|
console.log(` Total characters: ${totalChars.toLocaleString()}`);
|
|
90
109
|
console.log(` Estimated tokens: ${estimatedTokens.toLocaleString()}`);
|
|
91
110
|
console.log(` Exclusion patterns: ${excludePatterns.length}`);
|
|
92
111
|
|
|
112
|
+
// Calculate available tokens for diff based on total budget
|
|
113
|
+
const maxDiffTokens = calculateMaxDiffTokens();
|
|
114
|
+
console.log(`Token budget: ${maxDiffTokens.toLocaleString()} tokens for diff (limit: ${TOKEN_BUDGET.OPENAI_CONTEXT_LIMIT.toLocaleString()}, overhead: ${(TOKEN_BUDGET.SMARTAGENT_OVERHEAD + TOKEN_BUDGET.TASK_PROMPT_OVERHEAD).toLocaleString()})`);
|
|
115
|
+
|
|
93
116
|
// Use DiffProcessor to intelligently handle large diffs
|
|
94
117
|
const diffProcessor = new DiffProcessor({
|
|
95
|
-
maxDiffTokens
|
|
118
|
+
maxDiffTokens, // Dynamic based on total budget
|
|
96
119
|
smallFileLines: 300, // Most source files are under 300 lines
|
|
97
120
|
mediumFileLines: 800, // Only very large files get head/tail treatment
|
|
98
121
|
sampleHeadLines: 75, // When sampling, show more context
|
|
@@ -102,77 +125,60 @@ export class Commit {
|
|
|
102
125
|
const processedDiff = diffProcessor.processDiffs(diffStringArray);
|
|
103
126
|
processedDiffString = diffProcessor.formatForContext(processedDiff);
|
|
104
127
|
|
|
105
|
-
console.log(
|
|
128
|
+
console.log(`Processed diff statistics:`);
|
|
106
129
|
console.log(` Full diffs: ${processedDiff.fullDiffs.length} files`);
|
|
107
130
|
console.log(` Summarized: ${processedDiff.summarizedDiffs.length} files`);
|
|
108
131
|
console.log(` Metadata only: ${processedDiff.metadataOnly.length} files`);
|
|
109
132
|
console.log(` Final tokens: ${processedDiff.totalTokens.toLocaleString()}`);
|
|
110
133
|
|
|
111
134
|
if (estimatedTokens > 50000) {
|
|
112
|
-
console.log(
|
|
135
|
+
console.log(`DiffProcessor reduced token usage: ${estimatedTokens.toLocaleString()} -> ${processedDiff.totalTokens.toLocaleString()}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Validate total tokens won't exceed limit
|
|
139
|
+
const totalEstimatedTokens = processedDiff.totalTokens
|
|
140
|
+
+ TOKEN_BUDGET.SMARTAGENT_OVERHEAD
|
|
141
|
+
+ TOKEN_BUDGET.TASK_PROMPT_OVERHEAD;
|
|
142
|
+
|
|
143
|
+
if (totalEstimatedTokens > TOKEN_BUDGET.OPENAI_CONTEXT_LIMIT - TOKEN_BUDGET.SAFETY_MARGIN) {
|
|
144
|
+
console.log(`Warning: Estimated tokens (${totalEstimatedTokens.toLocaleString()}) approaching limit`);
|
|
145
|
+
console.log(` Consider splitting into smaller commits`);
|
|
113
146
|
}
|
|
114
147
|
} else {
|
|
115
148
|
processedDiffString = 'No changes.';
|
|
116
149
|
}
|
|
117
150
|
|
|
118
|
-
// Use
|
|
119
|
-
const
|
|
120
|
-
smartAiInstance: this.aiDocsRef.smartAiInstance,
|
|
121
|
-
defaultProvider: 'openai',
|
|
122
|
-
logPrefix: '[Commit]',
|
|
123
|
-
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
|
|
124
|
-
guardianPolicyPrompt: `
|
|
125
|
-
You validate commit messages for semantic versioning compliance.
|
|
126
|
-
|
|
127
|
-
APPROVE tool calls for:
|
|
128
|
-
- Reading package.json or source files to understand project context
|
|
129
|
-
- Using tree to see project structure
|
|
130
|
-
- Listing directory contents
|
|
131
|
-
|
|
132
|
-
REJECT tool calls for:
|
|
133
|
-
- Reading files outside the project directory
|
|
134
|
-
- Writing, deleting, or modifying any files
|
|
135
|
-
- Any destructive operations
|
|
136
|
-
|
|
137
|
-
APPROVE final output if:
|
|
138
|
-
- Version level (fix/feat/BREAKING CHANGE) matches the scope of changes in the diff
|
|
139
|
-
- Commit message is clear, professional, and follows conventional commit conventions
|
|
140
|
-
- No personal information, licensing details, or AI mentions (Claude/Codex) included
|
|
141
|
-
- JSON structure is valid with all required fields
|
|
142
|
-
- Scope accurately reflects the changed modules/files
|
|
143
|
-
|
|
144
|
-
REJECT final output if:
|
|
145
|
-
- Version level doesn't match the scope of changes (e.g., "feat" for a typo fix should be "fix")
|
|
146
|
-
- Message is vague, unprofessional, or contains sensitive information
|
|
147
|
-
- JSON is malformed or missing required fields
|
|
148
|
-
`,
|
|
149
|
-
});
|
|
151
|
+
// Use runAgent for commit message generation with filesystem tool
|
|
152
|
+
const fsTools = plugins.smartagentTools.filesystemTool({ rootDir: this.projectDir });
|
|
150
153
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
'.nogit/**',
|
|
154
|
-
'node_modules/**',
|
|
155
|
-
'.git/**',
|
|
156
|
-
'dist/**',
|
|
157
|
-
'dist_*/**',
|
|
158
|
-
]);
|
|
154
|
+
const commitSystemPrompt = `
|
|
155
|
+
You create commit messages for git commits following semantic versioning conventions.
|
|
159
156
|
|
|
160
|
-
|
|
157
|
+
You have access to filesystem tools to explore the project if needed.
|
|
158
|
+
|
|
159
|
+
IMPORTANT RULES:
|
|
160
|
+
- Only READ files (package.json, source files) for context
|
|
161
|
+
- Do NOT write, delete, or modify any files
|
|
162
|
+
- Version level (fix/feat/BREAKING CHANGE) must match the scope of changes
|
|
163
|
+
- Commit message must be clear, professional, and follow conventional commit conventions
|
|
164
|
+
- Do NOT include personal information, licensing details, or AI mentions (Claude/Codex)
|
|
165
|
+
- JSON structure must be valid with all required fields
|
|
166
|
+
- Scope must accurately reflect the changed modules/files
|
|
167
|
+
`;
|
|
161
168
|
|
|
162
169
|
const commitTaskPrompt = `
|
|
163
|
-
You create a commit message for a git commit.
|
|
164
170
|
Project directory: ${this.projectDir}
|
|
165
171
|
|
|
166
|
-
You have access to
|
|
167
|
-
- Use
|
|
168
|
-
- Use
|
|
172
|
+
You have access to filesystem tools to explore the project if needed:
|
|
173
|
+
- Use list_directory to see project structure
|
|
174
|
+
- Use read_file to read package.json or source files for context
|
|
169
175
|
|
|
170
176
|
Analyze the git diff below to understand what changed and generate a commit message.
|
|
171
177
|
|
|
172
178
|
You should not include any licensing information or personal information.
|
|
173
179
|
Never mention CLAUDE code, or codex.
|
|
174
180
|
|
|
175
|
-
Your final
|
|
181
|
+
Your final response must be ONLY valid JSON - the raw JSON object, nothing else.
|
|
176
182
|
No explanations, no summaries, no markdown - just the JSON object that can be parsed with JSON.parse().
|
|
177
183
|
|
|
178
184
|
Here is the structure of the JSON you must return:
|
|
@@ -194,15 +200,19 @@ ${processedDiffString}
|
|
|
194
200
|
Analyze these changes and output the JSON commit message object.
|
|
195
201
|
`;
|
|
196
202
|
|
|
197
|
-
|
|
198
|
-
await commitOrchestrator.stop();
|
|
203
|
+
logger.log('info', 'Starting commit message generation with agent...');
|
|
199
204
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
205
|
+
const commitResult = await plugins.smartagent.runAgent({
|
|
206
|
+
model: this.aiDocsRef.model,
|
|
207
|
+
prompt: commitTaskPrompt,
|
|
208
|
+
system: commitSystemPrompt,
|
|
209
|
+
tools: fsTools,
|
|
210
|
+
maxSteps: 10,
|
|
211
|
+
onToolCall: (toolName) => logger.log('info', `[Commit] Tool call: ${toolName}`),
|
|
212
|
+
});
|
|
203
213
|
|
|
204
214
|
// Extract JSON from result - handle cases where AI adds text around it
|
|
205
|
-
let jsonString = commitResult.
|
|
215
|
+
let jsonString = commitResult.text
|
|
206
216
|
.replace(/```json\n?/gi, '')
|
|
207
217
|
.replace(/```\n?/gi, '');
|
|
208
218
|
|
|
@@ -226,30 +236,16 @@ Analyze these changes and output the JSON commit message object.
|
|
|
226
236
|
const commitMessages = await gitRepo.getAllCommitMessages();
|
|
227
237
|
console.log(JSON.stringify(commitMessages, null, 2));
|
|
228
238
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
smartAiInstance: this.aiDocsRef.smartAiInstance,
|
|
232
|
-
defaultProvider: 'openai',
|
|
233
|
-
logPrefix: '[Changelog]',
|
|
234
|
-
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
|
|
235
|
-
guardianPolicyPrompt: `
|
|
236
|
-
You validate changelog generation.
|
|
237
|
-
|
|
238
|
-
APPROVE if:
|
|
239
|
-
- Changelog follows proper markdown format with ## headers for each version
|
|
240
|
-
- Entries are chronologically ordered (newest first)
|
|
241
|
-
- Version ranges for trivial commits are properly summarized
|
|
242
|
-
- No duplicate or empty entries
|
|
243
|
-
- Format matches: ## yyyy-mm-dd - x.x.x - scope
|
|
244
|
-
|
|
245
|
-
REJECT with feedback if:
|
|
246
|
-
- Markdown formatting is incorrect
|
|
247
|
-
- Entries are not meaningful or helpful
|
|
248
|
-
- Dates or versions are malformed
|
|
249
|
-
`,
|
|
250
|
-
});
|
|
239
|
+
const changelogSystemPrompt = `
|
|
240
|
+
You generate changelog.md files for software projects.
|
|
251
241
|
|
|
252
|
-
|
|
242
|
+
RULES:
|
|
243
|
+
- Changelog must follow proper markdown format with ## headers for each version
|
|
244
|
+
- Entries must be chronologically ordered (newest first)
|
|
245
|
+
- Version ranges for trivial commits should be properly summarized
|
|
246
|
+
- No duplicate or empty entries
|
|
247
|
+
- Format: ## yyyy-mm-dd - x.x.x - scope
|
|
248
|
+
`;
|
|
253
249
|
|
|
254
250
|
const changelogTaskPrompt = `
|
|
255
251
|
You are building a changelog.md file for the project.
|
|
@@ -258,7 +254,7 @@ Omit commits and versions that lack relevant changes, but make sure to mention t
|
|
|
258
254
|
A changelog entry should look like this:
|
|
259
255
|
|
|
260
256
|
## yyyy-mm-dd - x.x.x - scope here
|
|
261
|
-
main
|
|
257
|
+
main description here
|
|
262
258
|
|
|
263
259
|
- detailed bullet points follow
|
|
264
260
|
|
|
@@ -272,16 +268,17 @@ Here are the commit messages:
|
|
|
272
268
|
${JSON.stringify(commitMessages, null, 2)}
|
|
273
269
|
`;
|
|
274
270
|
|
|
275
|
-
const changelogResult = await
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
271
|
+
const changelogResult = await plugins.smartagent.runAgent({
|
|
272
|
+
model: this.aiDocsRef.model,
|
|
273
|
+
prompt: changelogTaskPrompt,
|
|
274
|
+
system: changelogSystemPrompt,
|
|
275
|
+
maxSteps: 1,
|
|
276
|
+
onToolCall: (toolName) => logger.log('info', `[Changelog] Tool call: ${toolName}`),
|
|
277
|
+
});
|
|
281
278
|
|
|
282
279
|
previousChangelog = plugins.smartfileFactory.fromString(
|
|
283
280
|
previousChangelogPath,
|
|
284
|
-
changelogResult.
|
|
281
|
+
changelogResult.text.replaceAll('```markdown', '').replaceAll('```', ''),
|
|
285
282
|
'utf8'
|
|
286
283
|
);
|
|
287
284
|
}
|
|
@@ -19,53 +19,29 @@ export class Description {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
public async build() {
|
|
22
|
-
// Use
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
REJECT tool calls for:
|
|
40
|
-
- Reading files outside the project directory
|
|
41
|
-
- Writing, deleting, or modifying any files
|
|
42
|
-
- Any destructive operations
|
|
43
|
-
|
|
44
|
-
For final output, APPROVE if:
|
|
45
|
-
- JSON is valid and parseable
|
|
46
|
-
- Description is a clear, concise one-sentence summary
|
|
47
|
-
- Keywords are relevant to the project's use cases
|
|
48
|
-
- Both description and keywords fields are present
|
|
49
|
-
|
|
50
|
-
REJECT final output if:
|
|
51
|
-
- JSON is malformed or wrapped in markdown code blocks
|
|
52
|
-
- Description is too long or vague
|
|
53
|
-
- Keywords are irrelevant or generic
|
|
54
|
-
`,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// Register scoped filesystem tool for agent exploration
|
|
58
|
-
descriptionOrchestrator.registerScopedFilesystemTool(this.projectDir);
|
|
59
|
-
|
|
60
|
-
await descriptionOrchestrator.start();
|
|
22
|
+
// Use runAgent with filesystem tool for agent-driven exploration
|
|
23
|
+
const fsTools = plugins.smartagentTools.filesystemTool({ rootDir: this.projectDir });
|
|
24
|
+
|
|
25
|
+
const descriptionSystemPrompt = `
|
|
26
|
+
You create project descriptions and keywords for npm packages.
|
|
27
|
+
|
|
28
|
+
You have access to filesystem tools to explore the project.
|
|
29
|
+
|
|
30
|
+
IMPORTANT RULES:
|
|
31
|
+
- Only READ files (package.json, npmextra.json, source files in ts/)
|
|
32
|
+
- Do NOT write, delete, or modify any files
|
|
33
|
+
- Your final response must be valid JSON only
|
|
34
|
+
- Description must be a clear, concise one-sentence summary
|
|
35
|
+
- Keywords must be relevant to the project's use cases
|
|
36
|
+
- Both description and keywords fields must be present
|
|
37
|
+
- Do NOT wrap JSON in markdown code blocks
|
|
38
|
+
`;
|
|
61
39
|
|
|
62
40
|
const descriptionTaskPrompt = `
|
|
63
|
-
You create a project description and keywords for an npm package.
|
|
64
|
-
|
|
65
41
|
PROJECT DIRECTORY: ${this.projectDir}
|
|
66
42
|
|
|
67
|
-
Use the filesystem
|
|
68
|
-
1. First, use
|
|
43
|
+
Use the filesystem tools to explore the project and understand what it does:
|
|
44
|
+
1. First, use list_directory to see the project structure
|
|
69
45
|
2. Read package.json to understand the package name and current description
|
|
70
46
|
3. Read npmextra.json if it exists for additional metadata
|
|
71
47
|
4. Read key source files in ts/ directory to understand the implementation
|
|
@@ -83,16 +59,20 @@ Your answer should be parseable with JSON.parse() without modifying anything.
|
|
|
83
59
|
Don't wrap the JSON in \`\`\`json\`\`\` - just return the raw JSON object.
|
|
84
60
|
`;
|
|
85
61
|
|
|
86
|
-
|
|
87
|
-
await descriptionOrchestrator.stop();
|
|
62
|
+
logger.log('info', 'Starting description generation with agent...');
|
|
88
63
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
64
|
+
const descriptionResult = await plugins.smartagent.runAgent({
|
|
65
|
+
model: this.aiDocsRef.model,
|
|
66
|
+
prompt: descriptionTaskPrompt,
|
|
67
|
+
system: descriptionSystemPrompt,
|
|
68
|
+
tools: fsTools,
|
|
69
|
+
maxSteps: 15,
|
|
70
|
+
onToolCall: (toolName) => logger.log('info', `[Description] Tool call: ${toolName}`),
|
|
71
|
+
});
|
|
92
72
|
|
|
93
|
-
console.log(descriptionResult.
|
|
73
|
+
console.log(descriptionResult.text);
|
|
94
74
|
const resultObject: IDescriptionInterface = JSON.parse(
|
|
95
|
-
descriptionResult.
|
|
75
|
+
descriptionResult.text.replace('```json', '').replace('```', ''),
|
|
96
76
|
);
|
|
97
77
|
|
|
98
78
|
// Use ProjectContext to get file handles for writing
|
|
@@ -120,6 +100,6 @@ Don't wrap the JSON in \`\`\`json\`\`\` - just return the raw JSON object.
|
|
|
120
100
|
console.log(`\n======================\n`);
|
|
121
101
|
console.log(JSON.stringify(resultObject, null, 2));
|
|
122
102
|
console.log(`\n======================\n`);
|
|
123
|
-
return descriptionResult.
|
|
103
|
+
return descriptionResult.text;
|
|
124
104
|
}
|
|
125
105
|
}
|
|
@@ -28,55 +28,31 @@ export class Readme {
|
|
|
28
28
|
console.log(error);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
// Use
|
|
32
|
-
const
|
|
33
|
-
smartAiInstance: this.aiDocsRef.smartAiInstance,
|
|
34
|
-
defaultProvider: 'openai',
|
|
35
|
-
maxIterations: 25,
|
|
36
|
-
maxResultChars: 15000, // Limit tool output to prevent token explosion
|
|
37
|
-
maxHistoryMessages: 20, // Limit history window
|
|
38
|
-
logPrefix: '[README]',
|
|
39
|
-
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
|
|
40
|
-
guardianPolicyPrompt: `
|
|
41
|
-
You validate README generation tool calls and outputs.
|
|
42
|
-
|
|
43
|
-
APPROVE tool calls for:
|
|
44
|
-
- Reading any files within the project directory (package.json, ts/*.ts, readme.md, etc.)
|
|
45
|
-
- Using tree to see project structure
|
|
46
|
-
- Using glob to find source files
|
|
47
|
-
- Listing directory contents
|
|
48
|
-
|
|
49
|
-
REJECT tool calls for:
|
|
50
|
-
- Reading files outside the project directory
|
|
51
|
-
- Writing, deleting, or modifying any files
|
|
52
|
-
- Any destructive operations
|
|
53
|
-
|
|
54
|
-
For final README output, APPROVE if:
|
|
55
|
-
- README follows proper markdown format
|
|
56
|
-
- Contains Install and Usage sections
|
|
57
|
-
- Code examples are correct TypeScript/ESM syntax
|
|
58
|
-
- Documentation is comprehensive and helpful
|
|
59
|
-
|
|
60
|
-
REJECT final output if:
|
|
61
|
-
- README is incomplete or poorly formatted
|
|
62
|
-
- Contains licensing information (added separately)
|
|
63
|
-
- Uses CommonJS syntax instead of ESM
|
|
64
|
-
- Contains "in conclusion" or similar filler
|
|
65
|
-
`,
|
|
66
|
-
});
|
|
31
|
+
// Use runAgent with filesystem tool for agent-driven exploration
|
|
32
|
+
const fsTools = plugins.smartagentTools.filesystemTool({ rootDir: this.projectDir });
|
|
67
33
|
|
|
68
|
-
|
|
69
|
-
|
|
34
|
+
const readmeSystemPrompt = `
|
|
35
|
+
You create markdown READMEs for npm projects. You only output the markdown readme.
|
|
70
36
|
|
|
71
|
-
|
|
37
|
+
You have access to filesystem tools to explore the project. Use them to understand the codebase.
|
|
38
|
+
|
|
39
|
+
IMPORTANT RULES:
|
|
40
|
+
- Only READ files within the project directory
|
|
41
|
+
- Do NOT write, delete, or modify any files
|
|
42
|
+
- README must follow proper markdown format
|
|
43
|
+
- Must contain Install and Usage sections
|
|
44
|
+
- Code examples must use correct TypeScript/ESM syntax
|
|
45
|
+
- Documentation must be comprehensive and helpful
|
|
46
|
+
- Do NOT include licensing information (added separately)
|
|
47
|
+
- Do NOT use CommonJS syntax - only ESM
|
|
48
|
+
- Do NOT include "in conclusion" or similar filler
|
|
49
|
+
`;
|
|
72
50
|
|
|
73
51
|
const readmeTaskPrompt = `
|
|
74
|
-
You create markdown READMEs for npm projects. You only output the markdown readme.
|
|
75
|
-
|
|
76
52
|
PROJECT DIRECTORY: ${this.projectDir}
|
|
77
53
|
|
|
78
|
-
Use the filesystem
|
|
79
|
-
1. First, use
|
|
54
|
+
Use the filesystem tools to explore the project and understand what it does:
|
|
55
|
+
1. First, use list_directory to see the project structure
|
|
80
56
|
2. Read package.json to understand the package name, description, and dependencies
|
|
81
57
|
3. Read the existing readme.md if it exists (use it as a base, improve and expand)
|
|
82
58
|
4. Read readme.hints.md if it exists (contains hints for documentation)
|
|
@@ -106,15 +82,19 @@ Then generate a comprehensive README following this template:
|
|
|
106
82
|
]
|
|
107
83
|
`;
|
|
108
84
|
|
|
109
|
-
|
|
110
|
-
await readmeOrchestrator.stop();
|
|
85
|
+
logger.log('info', 'Starting README generation with agent...');
|
|
111
86
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
87
|
+
const readmeResult = await plugins.smartagent.runAgent({
|
|
88
|
+
model: this.aiDocsRef.model,
|
|
89
|
+
prompt: readmeTaskPrompt,
|
|
90
|
+
system: readmeSystemPrompt,
|
|
91
|
+
tools: fsTools,
|
|
92
|
+
maxSteps: 25,
|
|
93
|
+
onToolCall: (toolName) => logger.log('info', `[README] Tool call: ${toolName}`),
|
|
94
|
+
});
|
|
115
95
|
|
|
116
96
|
// Clean up markdown formatting if wrapped in code blocks
|
|
117
|
-
let resultMessage = readmeResult.
|
|
97
|
+
let resultMessage = readmeResult.text
|
|
118
98
|
.replace(/^```markdown\n?/i, '')
|
|
119
99
|
.replace(/\n?```$/i, '');
|
|
120
100
|
|
|
@@ -142,40 +122,19 @@ Then generate a comprehensive README following this template:
|
|
|
142
122
|
.encoding('utf8')
|
|
143
123
|
.read();
|
|
144
124
|
|
|
145
|
-
|
|
146
|
-
const subModuleOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
|
|
147
|
-
smartAiInstance: this.aiDocsRef.smartAiInstance,
|
|
148
|
-
defaultProvider: 'openai',
|
|
149
|
-
maxIterations: 20,
|
|
150
|
-
maxResultChars: 12000,
|
|
151
|
-
maxHistoryMessages: 15,
|
|
152
|
-
logPrefix: `[README:${subModule}]`,
|
|
153
|
-
onProgress: (event) => logger.log(event.logLevel, event.logMessage),
|
|
154
|
-
guardianPolicyPrompt: `
|
|
155
|
-
You validate README generation for submodules.
|
|
156
|
-
|
|
157
|
-
APPROVE tool calls for:
|
|
158
|
-
- Reading any files within the submodule directory
|
|
159
|
-
- Using tree to see structure
|
|
160
|
-
- Using glob to find source files
|
|
161
|
-
|
|
162
|
-
REJECT tool calls for:
|
|
163
|
-
- Reading files outside the submodule directory
|
|
164
|
-
- Writing, deleting, or modifying any files
|
|
165
|
-
- Any destructive operations
|
|
166
|
-
|
|
167
|
-
APPROVE final README if comprehensive, well-formatted markdown with ESM TypeScript examples.
|
|
168
|
-
REJECT incomplete READMEs or those with licensing info.
|
|
169
|
-
`,
|
|
170
|
-
});
|
|
125
|
+
const subModuleFsTools = plugins.smartagentTools.filesystemTool({ rootDir: subModulePath });
|
|
171
126
|
|
|
172
|
-
|
|
173
|
-
|
|
127
|
+
const subModuleSystemPrompt = `
|
|
128
|
+
You create markdown READMEs for npm projects. You only output the markdown readme.
|
|
174
129
|
|
|
175
|
-
|
|
130
|
+
IMPORTANT RULES:
|
|
131
|
+
- Only READ files within the submodule directory
|
|
132
|
+
- Do NOT write, delete, or modify any files
|
|
133
|
+
- README must be comprehensive, well-formatted markdown with ESM TypeScript examples
|
|
134
|
+
- Do NOT include licensing information (added separately)
|
|
135
|
+
`;
|
|
176
136
|
|
|
177
137
|
const subModulePrompt = `
|
|
178
|
-
You create markdown READMEs for npm projects. You only output the markdown readme.
|
|
179
138
|
SUB MODULE: ${subModule}
|
|
180
139
|
SUB MODULE DIRECTORY: ${subModulePath}
|
|
181
140
|
|
|
@@ -183,8 +142,8 @@ IMPORTANT: YOU ARE CREATING THE README FOR THIS SUB MODULE: ${subModule}
|
|
|
183
142
|
The Sub Module will be published with:
|
|
184
143
|
${JSON.stringify(tspublishData, null, 2)}
|
|
185
144
|
|
|
186
|
-
Use the filesystem
|
|
187
|
-
1. Use
|
|
145
|
+
Use the filesystem tools to explore the submodule:
|
|
146
|
+
1. Use list_directory to see the submodule structure
|
|
188
147
|
2. Read package.json to understand the submodule
|
|
189
148
|
3. Read source files in ts/ directory to understand the implementation
|
|
190
149
|
|
|
@@ -208,21 +167,23 @@ Generate a README following the template:
|
|
|
208
167
|
Don't use \`\`\` at the beginning or end. Only for code blocks.
|
|
209
168
|
`;
|
|
210
169
|
|
|
211
|
-
const subModuleResult = await
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
170
|
+
const subModuleResult = await plugins.smartagent.runAgent({
|
|
171
|
+
model: this.aiDocsRef.model,
|
|
172
|
+
prompt: subModulePrompt,
|
|
173
|
+
system: subModuleSystemPrompt,
|
|
174
|
+
tools: subModuleFsTools,
|
|
175
|
+
maxSteps: 20,
|
|
176
|
+
onToolCall: (toolName) => logger.log('info', `[README:${subModule}] Tool call: ${toolName}`),
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const subModuleReadmeString = subModuleResult.text
|
|
180
|
+
.replace(/^```markdown\n?/i, '')
|
|
181
|
+
.replace(/\n?```$/i, '') + '\n' + legalInfo;
|
|
182
|
+
await plugins.fsInstance
|
|
183
|
+
.file(plugins.path.join(subModulePath, 'readme.md'))
|
|
184
|
+
.encoding('utf8')
|
|
185
|
+
.write(subModuleReadmeString);
|
|
186
|
+
logger.log('success', `Built readme for ${subModule}`);
|
|
226
187
|
}
|
|
227
188
|
|
|
228
189
|
return resultMessage;
|
package/ts/classes.aidoc.ts
CHANGED
|
@@ -8,7 +8,7 @@ export class AiDoc {
|
|
|
8
8
|
public npmextraKV: plugins.npmextra.KeyValueStore;
|
|
9
9
|
public qenvInstance: plugins.qenv.Qenv;
|
|
10
10
|
public aidocInteract: plugins.smartinteract.SmartInteract;
|
|
11
|
-
public
|
|
11
|
+
public model: plugins.smartai.LanguageModelV3;
|
|
12
12
|
|
|
13
13
|
argvArg: any;
|
|
14
14
|
|
|
@@ -84,27 +84,16 @@ export class AiDoc {
|
|
|
84
84
|
this.openaiToken = await this.npmextraKV.readKey('OPENAI_TOKEN');
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
//
|
|
88
|
-
this.
|
|
89
|
-
|
|
87
|
+
// Create model using getModel()
|
|
88
|
+
this.model = plugins.smartai.getModel({
|
|
89
|
+
provider: 'openai',
|
|
90
|
+
model: 'gpt-5.4',
|
|
91
|
+
apiKey: this.openaiToken,
|
|
90
92
|
});
|
|
91
|
-
await this.smartAiInstance.start();
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
public async stop() {
|
|
95
|
-
|
|
96
|
-
await this.smartAiInstance.stop();
|
|
97
|
-
}
|
|
98
|
-
// No explicit cleanup needed for npmextraKV or aidocInteract
|
|
99
|
-
// They don't keep event loop alive
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Get the OpenAI provider for direct chat calls
|
|
104
|
-
* This is a convenience getter to access the provider from SmartAi
|
|
105
|
-
*/
|
|
106
|
-
public get openaiProvider(): plugins.smartai.OpenAiProvider {
|
|
107
|
-
return this.smartAiInstance.openaiProvider;
|
|
96
|
+
// No lifecycle management needed with getModel() API
|
|
108
97
|
}
|
|
109
98
|
|
|
110
99
|
public getOpenaiToken(): string {
|
|
@@ -130,7 +119,7 @@ export class AiDoc {
|
|
|
130
119
|
const projectContextInstance = new aiDocsClasses.ProjectContext(projectDirArg);
|
|
131
120
|
return await projectContextInstance.gatherFiles();
|
|
132
121
|
}
|
|
133
|
-
|
|
122
|
+
|
|
134
123
|
/**
|
|
135
124
|
* Get the context with token count information
|
|
136
125
|
* @param projectDirArg The path to the project directory
|
|
@@ -141,7 +130,7 @@ export class AiDoc {
|
|
|
141
130
|
await projectContextInstance.update();
|
|
142
131
|
return projectContextInstance.getContextWithTokenCount();
|
|
143
132
|
}
|
|
144
|
-
|
|
133
|
+
|
|
145
134
|
/**
|
|
146
135
|
* Get just the token count for a project's context
|
|
147
136
|
* @param projectDirArg The path to the project directory
|
|
@@ -152,7 +141,7 @@ export class AiDoc {
|
|
|
152
141
|
await projectContextInstance.update();
|
|
153
142
|
return projectContextInstance.getTokenCount();
|
|
154
143
|
}
|
|
155
|
-
|
|
144
|
+
|
|
156
145
|
/**
|
|
157
146
|
* Estimate token count in a text string
|
|
158
147
|
* @param text The text to estimate tokens for
|
package/ts/plugins.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { path };
|
|
|
7
7
|
import * as npmextra from '@push.rocks/npmextra';
|
|
8
8
|
import * as qenv from '@push.rocks/qenv';
|
|
9
9
|
import * as smartagent from '@push.rocks/smartagent';
|
|
10
|
+
import * as smartagentTools from '@push.rocks/smartagent/tools';
|
|
10
11
|
import * as smartai from '@push.rocks/smartai';
|
|
11
12
|
import * as smartcli from '@push.rocks/smartcli';
|
|
12
13
|
import * as smartdelay from '@push.rocks/smartdelay';
|
|
@@ -24,6 +25,7 @@ export {
|
|
|
24
25
|
npmextra,
|
|
25
26
|
qenv,
|
|
26
27
|
smartagent,
|
|
28
|
+
smartagentTools,
|
|
27
29
|
smartai,
|
|
28
30
|
smartcli,
|
|
29
31
|
smartdelay,
|