@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.
@@ -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(`📊 Raw git diff statistics:`);
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: 100000, // Reserve 100k tokens for diffs
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(`📝 Processed diff statistics:`);
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(`✅ DiffProcessor reduced token usage: ${estimatedTokens.toLocaleString()} ${processedDiff.totalTokens.toLocaleString()}`);
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 DualAgentOrchestrator for commit message generation
119
- const commitOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
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
- // Register scoped filesystem tool for agent exploration
152
- commitOrchestrator.registerScopedFilesystemTool(this.projectDir, [
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
- await commitOrchestrator.start();
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 a filesystem tool to explore the project if needed:
167
- - Use tree to see project structure
168
- - Use read to read package.json or source files for context
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 output (inside the task_complete tags) must be ONLY valid JSON - the raw JSON object, nothing else.
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
- const commitResult = await commitOrchestrator.run(commitTaskPrompt);
198
- await commitOrchestrator.stop();
203
+ logger.log('info', 'Starting commit message generation with agent...');
199
204
 
200
- if (!commitResult.success) {
201
- throw new Error(`Commit message generation failed: ${commitResult.status}`);
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.result
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
- // Use DualAgentOrchestrator for changelog generation with Guardian validation
230
- const changelogOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
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
- await changelogOrchestrator.start();
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 descriptiom here
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 changelogOrchestrator.run(changelogTaskPrompt);
276
- await changelogOrchestrator.stop();
277
-
278
- if (!changelogResult.success) {
279
- throw new Error(`Changelog generation failed: ${changelogResult.status}`);
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.result.replaceAll('```markdown', '').replaceAll('```', ''),
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 DualAgentOrchestrator with filesystem tool for agent-driven exploration
23
- const descriptionOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
24
- smartAiInstance: this.aiDocsRef.smartAiInstance,
25
- defaultProvider: 'openai',
26
- maxIterations: 15,
27
- maxResultChars: 10000, // Limit tool output to prevent token explosion
28
- maxHistoryMessages: 15, // Limit history window
29
- logPrefix: '[Description]',
30
- onProgress: (event) => logger.log(event.logLevel, event.logMessage),
31
- guardianPolicyPrompt: `
32
- You validate description generation tool calls and outputs.
33
-
34
- APPROVE tool calls for:
35
- - Reading package.json, npmextra.json, or source files in the ts/ directory
36
- - Listing directory contents to understand project structure
37
- - Using tree to see project structure
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 tool to explore the project and understand what it does:
68
- 1. First, use tree to see the project structure
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
- const descriptionResult = await descriptionOrchestrator.run(descriptionTaskPrompt);
87
- await descriptionOrchestrator.stop();
62
+ logger.log('info', 'Starting description generation with agent...');
88
63
 
89
- if (!descriptionResult.success) {
90
- throw new Error(`Description generation failed: ${descriptionResult.status}`);
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.result);
73
+ console.log(descriptionResult.text);
94
74
  const resultObject: IDescriptionInterface = JSON.parse(
95
- descriptionResult.result.replace('```json', '').replace('```', ''),
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.result;
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 DualAgentOrchestrator with filesystem tool for agent-driven exploration
32
- const readmeOrchestrator = new plugins.smartagent.DualAgentOrchestrator({
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
- // Register scoped filesystem tool for agent exploration
69
- readmeOrchestrator.registerScopedFilesystemTool(this.projectDir);
34
+ const readmeSystemPrompt = `
35
+ You create markdown READMEs for npm projects. You only output the markdown readme.
70
36
 
71
- await readmeOrchestrator.start();
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 tool to explore the project and understand what it does:
79
- 1. First, use tree to see the project structure (maxDepth: 3)
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
- const readmeResult = await readmeOrchestrator.run(readmeTaskPrompt);
110
- await readmeOrchestrator.stop();
85
+ logger.log('info', 'Starting README generation with agent...');
111
86
 
112
- if (!readmeResult.success) {
113
- throw new Error(`README generation failed: ${readmeResult.status}`);
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.result
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
- // Create a new orchestrator with filesystem tool for each submodule
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
- // Register scoped filesystem tool for the submodule directory
173
- subModuleOrchestrator.registerScopedFilesystemTool(subModulePath);
127
+ const subModuleSystemPrompt = `
128
+ You create markdown READMEs for npm projects. You only output the markdown readme.
174
129
 
175
- await subModuleOrchestrator.start();
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 tool to explore the submodule:
187
- 1. Use tree to see the submodule structure
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 subModuleOrchestrator.run(subModulePrompt);
212
- await subModuleOrchestrator.stop();
213
-
214
- if (subModuleResult.success) {
215
- const subModuleReadmeString = subModuleResult.result
216
- .replace(/^```markdown\n?/i, '')
217
- .replace(/\n?```$/i, '') + '\n' + legalInfo;
218
- await plugins.fsInstance
219
- .file(plugins.path.join(subModulePath, 'readme.md'))
220
- .encoding('utf8')
221
- .write(subModuleReadmeString);
222
- logger.log('success', `Built readme for ${subModule}`);
223
- } else {
224
- logger.log('error', `Failed to build readme for ${subModule}: ${subModuleResult.status}`);
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;
@@ -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 smartAiInstance: plugins.smartai.SmartAi;
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
- // lets assume we have an OPENAI_Token now
88
- this.smartAiInstance = new plugins.smartai.SmartAi({
89
- openaiToken: this.openaiToken,
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
- if (this.smartAiInstance) {
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,