Compare commits
	
		
			4 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0a3080518f | |||
| d0a4ddbb4b | |||
| 481339d3cb | |||
| ebc3d760af | 
@@ -1,5 +1,13 @@
 | 
			
		||||
# Changelog
 | 
			
		||||
 | 
			
		||||
## 2025-11-03 - 1.8.0 - feat(context)
 | 
			
		||||
Wire OpenAI provider through task context factory and add git-diff support to iterative context builder
 | 
			
		||||
 | 
			
		||||
- Pass AiDoc.openaiInstance through TaskContextFactory into IterativeContextBuilder to reuse the same OpenAI provider and avoid reinitialization.
 | 
			
		||||
- IterativeContextBuilder now accepts an optional OpenAiProvider and an additionalContext string; when provided, git diffs (or other extra context) are prepended to the AI context and token counts are updated.
 | 
			
		||||
- createContextForCommit now forwards the git diff into the iterative builder so commit-specific context includes the diff.
 | 
			
		||||
- Updated aidocs_classes (commit, description, readme) to supply the existing openaiInstance when creating the TaskContextFactory.
 | 
			
		||||
 | 
			
		||||
## 2025-11-03 - 1.7.0 - feat(IterativeContextBuilder)
 | 
			
		||||
Add iterative AI-driven context builder and integrate into task factory; add tests and iterative configuration
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@git.zone/tsdoc",
 | 
			
		||||
  "version": "1.7.0",
 | 
			
		||||
  "version": "1.8.1",
 | 
			
		||||
  "private": false,
 | 
			
		||||
  "description": "A comprehensive TypeScript documentation tool that leverages AI to generate and enhance project documentation, including dynamic README creation, API docs via TypeDoc, and smart commit message generation.",
 | 
			
		||||
  "type": "module",
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,10 @@ tap.test('should build commit object', async () => {
 | 
			
		||||
  expect(commitObject).toHaveProperty('recommendedNextVersionLevel');
 | 
			
		||||
  expect(commitObject).toHaveProperty('recommendedNextVersionScope');
 | 
			
		||||
  expect(commitObject).toHaveProperty('recommendedNextVersionMessage');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
tap.test('should stop AIdocs', async () => {
 | 
			
		||||
  await aidocs.stop();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.start();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
import { expect, tap } from '@push.rocks/tapbundle';
 | 
			
		||||
import * as tsdoc from '../ts/index.js';
 | 
			
		||||
 | 
			
		||||
tap.test('first test', async () => {
 | 
			
		||||
  console.log('test');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.start();
 | 
			
		||||
@@ -3,6 +3,6 @@
 | 
			
		||||
 */
 | 
			
		||||
export const commitinfo = {
 | 
			
		||||
  name: '@git.zone/tsdoc',
 | 
			
		||||
  version: '1.7.0',
 | 
			
		||||
  version: '1.8.0',
 | 
			
		||||
  description: 'A comprehensive TypeScript documentation tool that leverages AI to generate and enhance project documentation, including dynamic README creation, API docs via TypeDoc, and smart commit message generation.'
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,9 +30,20 @@ export class Commit {
 | 
			
		||||
    const diffStringArray = await gitRepo.getUncommittedDiff([
 | 
			
		||||
      'pnpm-lock.yaml',
 | 
			
		||||
      'package-lock.json',
 | 
			
		||||
      'npm-shrinkwrap.json',
 | 
			
		||||
      'yarn.lock',
 | 
			
		||||
      'deno.lock',
 | 
			
		||||
      'bun.lockb',
 | 
			
		||||
      '.claude/*',
 | 
			
		||||
      '.cursor/*',
 | 
			
		||||
      '.vscode/*',
 | 
			
		||||
      '.idea/*',
 | 
			
		||||
    ]);
 | 
			
		||||
    // Use the new TaskContextFactory for optimized context
 | 
			
		||||
    const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(this.projectDir);
 | 
			
		||||
    const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(
 | 
			
		||||
      this.projectDir,
 | 
			
		||||
      this.aiDocsRef.openaiInstance
 | 
			
		||||
    );
 | 
			
		||||
    await taskContextFactory.initialize();
 | 
			
		||||
    
 | 
			
		||||
    // Generate context specifically for commit task
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,10 @@ export class Description {
 | 
			
		||||
 | 
			
		||||
  public async build() {
 | 
			
		||||
    // Use the new TaskContextFactory for optimized context
 | 
			
		||||
    const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(this.projectDir);
 | 
			
		||||
    const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(
 | 
			
		||||
      this.projectDir,
 | 
			
		||||
      this.aiDocsRef.openaiInstance
 | 
			
		||||
    );
 | 
			
		||||
    await taskContextFactory.initialize();
 | 
			
		||||
    
 | 
			
		||||
    // Generate context specifically for description task
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,10 @@ export class Readme {
 | 
			
		||||
    let finalReadmeString = ``;
 | 
			
		||||
 | 
			
		||||
    // Use the new TaskContextFactory for optimized context
 | 
			
		||||
    const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(this.projectDir);
 | 
			
		||||
    const taskContextFactory = new (await import('../context/index.js')).TaskContextFactory(
 | 
			
		||||
      this.projectDir,
 | 
			
		||||
      this.aiDocsRef.openaiInstance
 | 
			
		||||
    );
 | 
			
		||||
    await taskContextFactory.initialize();
 | 
			
		||||
    
 | 
			
		||||
    // Generate context specifically for readme task
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ export class AiDoc {
 | 
			
		||||
        await this.npmextraKV.writeKey('OPENAI_TOKEN', this.openaiToken);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (!this.openaiToken) {
 | 
			
		||||
    if (!this.openaiToken && this.npmextraKV) {
 | 
			
		||||
      this.openaiToken = await this.npmextraKV.readKey('OPENAI_TOKEN');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -76,8 +76,12 @@ export class AiDoc {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async stop() {
 | 
			
		||||
    if (this.openaiInstance) {
 | 
			
		||||
      await this.openaiInstance.stop();
 | 
			
		||||
    }
 | 
			
		||||
    // No explicit cleanup needed for npmextraKV or aidocInteract
 | 
			
		||||
    // They don't keep event loop alive
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async buildReadme(projectDirArg: string) {
 | 
			
		||||
    const readmeInstance = new aiDocsClasses.Readme(this, projectDirArg);
 | 
			
		||||
 
 | 
			
		||||
@@ -28,17 +28,24 @@ export class IterativeContextBuilder {
 | 
			
		||||
  private config: Required<IIterativeConfig>;
 | 
			
		||||
  private tokenBudget: number = 190000;
 | 
			
		||||
  private openaiInstance: plugins.smartai.OpenAiProvider;
 | 
			
		||||
  private externalOpenaiInstance?: plugins.smartai.OpenAiProvider;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates a new IterativeContextBuilder
 | 
			
		||||
   * @param projectRoot - Root directory of the project
 | 
			
		||||
   * @param config - Iterative configuration
 | 
			
		||||
   * @param openaiInstance - Optional pre-configured OpenAI provider instance
 | 
			
		||||
   */
 | 
			
		||||
  constructor(projectRoot: string, config?: Partial<IIterativeConfig>) {
 | 
			
		||||
  constructor(
 | 
			
		||||
    projectRoot: string,
 | 
			
		||||
    config?: Partial<IIterativeConfig>,
 | 
			
		||||
    openaiInstance?: plugins.smartai.OpenAiProvider
 | 
			
		||||
  ) {
 | 
			
		||||
    this.projectRoot = projectRoot;
 | 
			
		||||
    this.lazyLoader = new LazyFileLoader(projectRoot);
 | 
			
		||||
    this.cache = new ContextCache(projectRoot);
 | 
			
		||||
    this.analyzer = new ContextAnalyzer(projectRoot);
 | 
			
		||||
    this.externalOpenaiInstance = openaiInstance;
 | 
			
		||||
 | 
			
		||||
    // Default configuration
 | 
			
		||||
    this.config = {
 | 
			
		||||
@@ -60,7 +67,11 @@ export class IterativeContextBuilder {
 | 
			
		||||
    await configManager.initialize(this.projectRoot);
 | 
			
		||||
    this.tokenBudget = configManager.getMaxTokens();
 | 
			
		||||
 | 
			
		||||
    // Initialize OpenAI instance
 | 
			
		||||
    // Use external OpenAI instance if provided, otherwise create a new one
 | 
			
		||||
    if (this.externalOpenaiInstance) {
 | 
			
		||||
      this.openaiInstance = this.externalOpenaiInstance;
 | 
			
		||||
    } else {
 | 
			
		||||
      // Initialize OpenAI instance from environment
 | 
			
		||||
      const qenvInstance = new plugins.qenv.Qenv();
 | 
			
		||||
      const openaiToken = await qenvInstance.getEnvVarOnDemand('OPENAI_TOKEN');
 | 
			
		||||
      if (!openaiToken) {
 | 
			
		||||
@@ -71,13 +82,15 @@ export class IterativeContextBuilder {
 | 
			
		||||
      });
 | 
			
		||||
      await this.openaiInstance.start();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Build context iteratively using AI decision making
 | 
			
		||||
   * @param taskType - Type of task being performed
 | 
			
		||||
   * @param additionalContext - Optional additional context (e.g., git diff for commit tasks)
 | 
			
		||||
   * @returns Complete iterative context result
 | 
			
		||||
   */
 | 
			
		||||
  public async buildContextIteratively(taskType: TaskType): Promise<IIterativeContextResult> {
 | 
			
		||||
  public async buildContextIteratively(taskType: TaskType, additionalContext?: string): Promise<IIterativeContextResult> {
 | 
			
		||||
    const startTime = Date.now();
 | 
			
		||||
    logger.log('info', '🤖 Starting iterative context building...');
 | 
			
		||||
    logger.log('info', `   Task: ${taskType}, Budget: ${this.tokenBudget} tokens, Max iterations: ${this.config.maxIterations}`);
 | 
			
		||||
@@ -100,6 +113,21 @@ export class IterativeContextBuilder {
 | 
			
		||||
    let loadedContent = '';
 | 
			
		||||
    const includedFiles: IFileInfo[] = [];
 | 
			
		||||
 | 
			
		||||
    // If additional context (e.g., git diff) is provided, prepend it
 | 
			
		||||
    if (additionalContext) {
 | 
			
		||||
      const diffSection = `
 | 
			
		||||
====== GIT DIFF ======
 | 
			
		||||
 | 
			
		||||
${additionalContext}
 | 
			
		||||
 | 
			
		||||
====== END OF GIT DIFF ======
 | 
			
		||||
`;
 | 
			
		||||
      loadedContent = diffSection;
 | 
			
		||||
      const diffTokens = this.countTokens(diffSection);
 | 
			
		||||
      totalTokensUsed += diffTokens;
 | 
			
		||||
      logger.log('info', `📝 Added git diff to context (${diffTokens} tokens)`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Phase 3: Iterative file selection and loading
 | 
			
		||||
    for (let iteration = 1; iteration <= this.config.maxIterations; iteration++) {
 | 
			
		||||
      const iterationStart = Date.now();
 | 
			
		||||
 
 | 
			
		||||
@@ -9,14 +9,17 @@ import type { IIterativeContextResult, TaskType } from './types.js';
 | 
			
		||||
export class TaskContextFactory {
 | 
			
		||||
  private projectDir: string;
 | 
			
		||||
  private configManager: ConfigManager;
 | 
			
		||||
  private openaiInstance?: any; // OpenAI provider instance
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a new TaskContextFactory
 | 
			
		||||
   * @param projectDirArg The project directory
 | 
			
		||||
   * @param openaiInstance Optional pre-configured OpenAI provider instance
 | 
			
		||||
   */
 | 
			
		||||
  constructor(projectDirArg: string) {
 | 
			
		||||
  constructor(projectDirArg: string, openaiInstance?: any) {
 | 
			
		||||
    this.projectDir = projectDirArg;
 | 
			
		||||
    this.configManager = ConfigManager.getInstance();
 | 
			
		||||
    this.openaiInstance = openaiInstance;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -32,7 +35,8 @@ export class TaskContextFactory {
 | 
			
		||||
  public async createContextForReadme(): Promise<IIterativeContextResult> {
 | 
			
		||||
    const iterativeBuilder = new IterativeContextBuilder(
 | 
			
		||||
      this.projectDir,
 | 
			
		||||
      this.configManager.getIterativeConfig()
 | 
			
		||||
      this.configManager.getIterativeConfig(),
 | 
			
		||||
      this.openaiInstance
 | 
			
		||||
    );
 | 
			
		||||
    await iterativeBuilder.initialize();
 | 
			
		||||
    return await iterativeBuilder.buildContextIteratively('readme');
 | 
			
		||||
@@ -44,7 +48,8 @@ export class TaskContextFactory {
 | 
			
		||||
  public async createContextForDescription(): Promise<IIterativeContextResult> {
 | 
			
		||||
    const iterativeBuilder = new IterativeContextBuilder(
 | 
			
		||||
      this.projectDir,
 | 
			
		||||
      this.configManager.getIterativeConfig()
 | 
			
		||||
      this.configManager.getIterativeConfig(),
 | 
			
		||||
      this.openaiInstance
 | 
			
		||||
    );
 | 
			
		||||
    await iterativeBuilder.initialize();
 | 
			
		||||
    return await iterativeBuilder.buildContextIteratively('description');
 | 
			
		||||
@@ -52,16 +57,16 @@ export class TaskContextFactory {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create context for commit message generation
 | 
			
		||||
   * @param gitDiff Optional git diff to include (currently not used in iterative mode)
 | 
			
		||||
   * @param gitDiff Optional git diff to include in the context
 | 
			
		||||
   */
 | 
			
		||||
  public async createContextForCommit(gitDiff?: string): Promise<IIterativeContextResult> {
 | 
			
		||||
    const iterativeBuilder = new IterativeContextBuilder(
 | 
			
		||||
      this.projectDir,
 | 
			
		||||
      this.configManager.getIterativeConfig()
 | 
			
		||||
      this.configManager.getIterativeConfig(),
 | 
			
		||||
      this.openaiInstance
 | 
			
		||||
    );
 | 
			
		||||
    await iterativeBuilder.initialize();
 | 
			
		||||
    // Note: git diff could be incorporated into the iterative prompts if needed
 | 
			
		||||
    return await iterativeBuilder.buildContextIteratively('commit');
 | 
			
		||||
    return await iterativeBuilder.buildContextIteratively('commit', gitDiff);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user