@git.zone/tsdoc 2.0.5 → 2.1.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.
@@ -1,108 +1,155 @@
1
1
  import * as plugins from './plugins.js';
2
2
 
3
3
  import * as aiDocsClasses from './aidocs_classes/index.js';
4
+ import { logger } from './logging.js';
5
+
6
+ export type TAiDocAuthMode = plugins.tsagent.TTsAgentAuthMode;
7
+
8
+ export interface IAiDocConfig extends plugins.tsagent.ITsAgentConfig {}
9
+
10
+ export interface IAiDocResolvedConfig extends plugins.tsagent.ITsAgentResolvedConfig {}
11
+
12
+ export const defaultAiDocConfig: IAiDocResolvedConfig = {
13
+ ...plugins.tsagent.defaultTsAgentConfig,
14
+ };
15
+
16
+ type TAiDocRunAgentOptions = Parameters<plugins.tsagent.TsAgent['runAgent']>[0];
17
+ type TAiDocRunAgentResult = Awaited<ReturnType<plugins.tsagent.TsAgent['runAgent']>>;
18
+
19
+ const normalizeAuthMode = (value: unknown): TAiDocAuthMode | undefined => {
20
+ return value === 'auto' || value === 'chatgpt' || value === 'apiKey' ? value : undefined;
21
+ };
22
+
23
+ const normalizeProvider = (value: unknown): plugins.smartai.TProvider | undefined => {
24
+ return ['anthropic', 'openai', 'google', 'groq', 'mistral', 'xai', 'perplexity', 'ollama'].includes(String(value))
25
+ ? value as plugins.smartai.TProvider
26
+ : undefined;
27
+ };
28
+
29
+ const normalizeChatGptSources = (value: unknown): plugins.smartaiOpenAiChatGptAuth.TOpenAiChatGptAuthSource[] | undefined => {
30
+ const input = typeof value === 'string' ? value.split(',').map(source => source.trim()) : value;
31
+ if (!Array.isArray(input)) return undefined;
32
+ const sources = input.filter((source): source is plugins.smartaiOpenAiChatGptAuth.TOpenAiChatGptAuthSource => {
33
+ return source === 'opencode' || source === 'codex' || source === 'smartai';
34
+ });
35
+ return sources.length > 0 ? sources : undefined;
36
+ };
37
+
38
+ const normalizeOpenAiReasoningEffort = (value: unknown): plugins.smartai.TOpenAiReasoningEffort | undefined => {
39
+ return ['none', 'minimal', 'low', 'medium', 'high', 'xhigh'].includes(String(value))
40
+ ? value as plugins.smartai.TOpenAiReasoningEffort
41
+ : undefined;
42
+ };
4
43
 
5
44
  export class AiDoc {
45
+ private tsAgent?: plugins.tsagent.TsAgent;
6
46
  private openaiToken = '';
7
47
 
8
48
  public smartconfigKV?: plugins.smartconfig.KeyValueStore<{ OPENAI_TOKEN: string }>;
9
- public qenvInstance!: plugins.qenv.Qenv;
10
- public aidocInteract!: plugins.smartinteract.SmartInteract;
11
- public model!: plugins.smartai.LanguageModelV3;
49
+ public qenvInstance?: plugins.qenv.Qenv;
50
+ public aidocInteract?: plugins.smartinteract.SmartInteract;
51
+ public model!: plugins.tsagent.TsAgent['model'];
52
+ public providerOptions?: IAiDocResolvedConfig['providerOptions'];
53
+ public config: IAiDocResolvedConfig = defaultAiDocConfig;
54
+ public selectedAuthSource: string = 'none';
12
55
 
13
- argvArg: any;
56
+ public argvArg: any;
14
57
 
15
58
  constructor(argvArg?: any) {
16
- this.argvArg = argvArg;
59
+ this.argvArg = argvArg || {};
17
60
  }
18
61
 
19
- private printSanitizedToken() {
20
- // Check if the token length is greater than the sum of startLength and endLength
21
- let printToken: string;
22
- if (this.openaiToken.length > 6) {
23
- // Extract the beginning and end parts of the token
24
- const start = this.openaiToken.substring(0, 3);
25
- const end = this.openaiToken.substring(this.openaiToken.length - 3);
26
- printToken = `${start}...${end}`;
27
- } else {
28
- // If the token is not long enough, return it as is
29
- printToken = this.openaiToken;
62
+ private get activeTsAgent(): plugins.tsagent.TsAgent {
63
+ if (!this.tsAgent) {
64
+ throw new Error('AiDoc.start() must be called before running AI tasks.');
30
65
  }
31
- console.log(`OpenAI Token on record: ${printToken}`);
66
+ return this.tsAgent;
32
67
  }
33
68
 
34
- public async start() {
35
- // lets care about prerequisites
36
- this.aidocInteract = new plugins.smartinteract.SmartInteract();
37
- this.qenvInstance = new plugins.qenv.Qenv();
38
- const openaiTokenFromEnv = await this.qenvInstance.getEnvVarOnDemand('OPENAI_TOKEN');
39
- if (openaiTokenFromEnv) {
40
- this.openaiToken = openaiTokenFromEnv;
41
- } else {
42
- // Migrate old KV store path to new path if needed
43
- const homeDir = plugins.smartpath.get.home();
44
- const oldKvPath = plugins.path.join(homeDir, '.smartconfig/kv/tsdoc.json');
45
- const newKvDir = plugins.path.join(homeDir, '.smartconfig/kv/@git.zone');
46
- const newKvPath = plugins.path.join(newKvDir, 'tsdoc.json');
47
- if (
48
- await plugins.fsInstance.file(oldKvPath).exists() &&
49
- !(await plugins.fsInstance.file(newKvPath).exists())
50
- ) {
51
- console.log('Migrating tsdoc KeyValueStore to @git.zone/tsdoc...');
52
- await plugins.fsInstance.directory(newKvDir).recursive().create();
53
- await plugins.fsInstance.file(oldKvPath).copy(newKvPath);
54
- await plugins.fsInstance.file(oldKvPath).delete();
55
- console.log('Migration complete: tsdoc.json -> @git.zone/tsdoc.json');
56
- }
57
-
58
- this.smartconfigKV = new plugins.smartconfig.KeyValueStore({
59
- typeArg: 'userHomeDir',
60
- identityArg: '@git.zone/tsdoc',
61
- mandatoryKeys: ['OPENAI_TOKEN'],
62
- });
63
-
64
- const missingKeys = await this.smartconfigKV.getMissingMandatoryKeys();
65
- if (missingKeys.length > 0) {
66
- // lets try argv
67
- if (this.argvArg?.OPENAI_TOKEN) {
68
- this.openaiToken = this.argvArg.OPENAI_TOKEN;
69
- } else {
70
- // lets try smartinteract
71
- // wait for a second until OpenAI fixes punycode problem...
72
- await plugins.smartdelay.delayFor(1000);
73
- const answerObject = await this.aidocInteract.askQuestion({
74
- type: 'input',
75
- message: `Please provide your OpenAI token. This will be persisted in your home directory.`,
76
- name: 'OPENAI_TOKEN',
77
- default: '',
78
- });
79
- this.openaiToken = answerObject.value;
80
- }
81
-
82
- this.printSanitizedToken();
83
- await this.smartconfigKV.writeKey('OPENAI_TOKEN', this.openaiToken);
84
- }
85
- }
86
- if (!this.openaiToken && this.smartconfigKV) {
87
- this.openaiToken = await this.smartconfigKV.readKey('OPENAI_TOKEN');
69
+ private async migrateKeyValueStore(): Promise<void> {
70
+ const homeDir = plugins.smartpath.get.home();
71
+ const oldKvPath = plugins.path.join(homeDir, '.smartconfig/kv/tsdoc.json');
72
+ const newKvDir = plugins.path.join(homeDir, '.smartconfig/kv/@git.zone');
73
+ const newKvPath = plugins.path.join(newKvDir, 'tsdoc.json');
74
+ if (
75
+ await plugins.fsInstance.file(oldKvPath).exists() &&
76
+ !(await plugins.fsInstance.file(newKvPath).exists())
77
+ ) {
78
+ logger.log('info', 'Migrating tsdoc KeyValueStore to @git.zone/tsdoc...');
79
+ await plugins.fsInstance.directory(newKvDir).recursive().create();
80
+ await plugins.fsInstance.file(oldKvPath).copy(newKvPath);
81
+ await plugins.fsInstance.file(oldKvPath).delete();
82
+ logger.log('success', 'Migration complete: tsdoc.json -> @git.zone/tsdoc.json');
88
83
  }
84
+ }
85
+
86
+ private async resolveTsdocEnvConfig(): Promise<IAiDocConfig> {
87
+ this.qenvInstance = new plugins.qenv.Qenv();
88
+ const envProvider = normalizeProvider(await this.qenvInstance.getEnvVarOnDemand('TSDOC_AI_PROVIDER'));
89
+ const envModel = await this.qenvInstance.getEnvVarOnDemand('TSDOC_AI_MODEL');
90
+ const envAuthMode = normalizeAuthMode(await this.qenvInstance.getEnvVarOnDemand('TSDOC_AUTH_MODE'));
91
+ const envChatGptSources = normalizeChatGptSources(await this.qenvInstance.getEnvVarOnDemand('TSDOC_CHATGPT_AUTH_SOURCES'));
92
+ const envReasoningEffort = normalizeOpenAiReasoningEffort(await this.qenvInstance.getEnvVarOnDemand('TSDOC_OPENAI_REASONING_EFFORT'));
93
+ return {
94
+ provider: envProvider,
95
+ model: envModel || undefined,
96
+ authMode: envAuthMode,
97
+ chatGptAuthSources: envChatGptSources,
98
+ providerOptions: envReasoningEffort ? {
99
+ openai: {
100
+ reasoningEffort: envReasoningEffort,
101
+ },
102
+ } : undefined,
103
+ };
104
+ }
89
105
 
90
- // Create model using getModel()
91
- this.model = plugins.smartai.getModel({
92
- provider: 'openai',
93
- model: 'gpt-5.4',
94
- apiKey: this.openaiToken,
106
+ public async start() {
107
+ await this.migrateKeyValueStore();
108
+ this.smartconfigKV = new plugins.smartconfig.KeyValueStore({
109
+ typeArg: 'userHomeDir',
110
+ identityArg: '@git.zone/tsdoc',
111
+ mandatoryKeys: ['OPENAI_TOKEN'],
95
112
  });
113
+
114
+ this.tsAgent = new plugins.tsagent.TsAgent({
115
+ argvArg: this.argvArg,
116
+ projectDir: process.cwd(),
117
+ projectConfigKeys: ['@git.zone/tsagent', 'tsdoc', '@git.zone/tsdoc'],
118
+ legacyTokenStoreIdentities: ['@git.zone/tsdoc'],
119
+ config: await this.resolveTsdocEnvConfig(),
120
+ });
121
+ await this.tsAgent.start();
122
+
123
+ this.model = this.tsAgent.model;
124
+ this.providerOptions = this.tsAgent.providerOptions;
125
+ this.config = this.tsAgent.config as IAiDocResolvedConfig;
126
+ this.selectedAuthSource = this.tsAgent.selectedAuthSource;
127
+ this.openaiToken = this.tsAgent.getOpenaiToken();
128
+ if (this.selectedAuthSource !== 'none') {
129
+ logger.log('info', `Using AI auth from ${this.selectedAuthSource}.`);
130
+ }
96
131
  }
97
132
 
98
133
  public async stop() {
99
- // No lifecycle management needed with getModel() API
134
+ await this.tsAgent?.stop();
100
135
  }
101
136
 
102
137
  public getOpenaiToken(): string {
103
138
  return this.openaiToken;
104
139
  }
105
140
 
141
+ public async runAgent(options: TAiDocRunAgentOptions): Promise<TAiDocRunAgentResult> {
142
+ const result = await this.activeTsAgent.runAgent({
143
+ ...options,
144
+ sessionId: options.sessionId ?? `tsdoc:${options.taskName}:${plugins.path.resolve(options.projectDir)}`,
145
+ });
146
+ logger.log(
147
+ 'info',
148
+ `[${options.taskName}] tokens input=${result.usage.inputTokens} output=${result.usage.outputTokens} total=${result.usage.totalTokens} cacheRead=${result.usage.cacheReadTokens} cacheWrite=${result.usage.cacheWriteTokens}`,
149
+ );
150
+ return result;
151
+ }
152
+
106
153
  public async buildReadme(projectDirArg: string) {
107
154
  const readmeInstance = new aiDocsClasses.Readme(this, projectDirArg);
108
155
  return await readmeInstance.build();
@@ -160,24 +160,18 @@ export class DiffProcessor {
160
160
 
161
161
  const lines = diffString.split('\n');
162
162
  let filepath = '';
163
+ let oldPath = '';
164
+ let newPath = '';
163
165
  let status: 'added' | 'modified' | 'deleted' = 'modified';
164
166
  let linesAdded = 0;
165
167
  let linesRemoved = 0;
166
168
 
167
169
  // Parse diff header to extract filepath and status
168
170
  for (const line of lines) {
169
- if (line.startsWith('--- a/')) {
170
- filepath = line.substring(6);
171
- } else if (line.startsWith('+++ b/')) {
172
- const newPath = line.substring(6);
173
- if (newPath === '/dev/null') {
174
- status = 'deleted';
175
- } else if (filepath === '/dev/null') {
176
- status = 'added';
177
- filepath = newPath;
178
- } else {
179
- filepath = newPath;
180
- }
171
+ if (line.startsWith('--- ')) {
172
+ oldPath = this.normalizeDiffPath(line.substring(4));
173
+ } else if (line.startsWith('+++ ')) {
174
+ newPath = this.normalizeDiffPath(line.substring(4));
181
175
  } else if (line.startsWith('+') && !line.startsWith('+++')) {
182
176
  linesAdded++;
183
177
  } else if (line.startsWith('-') && !line.startsWith('---')) {
@@ -185,6 +179,16 @@ export class DiffProcessor {
185
179
  }
186
180
  }
187
181
 
182
+ if (oldPath === '/dev/null') {
183
+ status = 'added';
184
+ filepath = newPath;
185
+ } else if (newPath === '/dev/null') {
186
+ status = 'deleted';
187
+ filepath = oldPath;
188
+ } else {
189
+ filepath = newPath || oldPath;
190
+ }
191
+
188
192
  const totalLines = linesAdded + linesRemoved;
189
193
  const estimatedTokens = Math.ceil(diffString.length / 4);
190
194
 
@@ -199,6 +203,12 @@ export class DiffProcessor {
199
203
  };
200
204
  }
201
205
 
206
+ private normalizeDiffPath(pathArg: string): string {
207
+ const cleanPath = pathArg.trim().split('\t')[0].split(' ')[0];
208
+ if (cleanPath === '/dev/null') return cleanPath;
209
+ return cleanPath.replace(/^a\//, '').replace(/^b\//, '');
210
+ }
211
+
202
212
  /**
203
213
  * Prioritize files by importance (source files before build artifacts)
204
214
  */
@@ -215,7 +225,7 @@ export class DiffProcessor {
215
225
  */
216
226
  private getFileImportanceScore(filepath: string): number {
217
227
  // Source files - highest priority
218
- if (filepath.match(/^(src|lib|app|components|pages|api)\//)) {
228
+ if (filepath.match(/^(ts|ts_web|src|lib|app|components|pages|api)\//)) {
219
229
  return 100;
220
230
  }
221
231
 
@@ -9,7 +9,8 @@ export class TypeDoc {
9
9
 
10
10
  // Static
11
11
  public static async isTypeDocDir(dirPathArg: string): Promise<boolean> {
12
- return true;
12
+ return await plugins.fsInstance.file(plugins.path.join(dirPathArg, 'ts/index.ts')).exists()
13
+ || await plugins.fsInstance.file(plugins.path.join(dirPathArg, 'ts_web/index.ts')).exists();
13
14
  }
14
15
 
15
16
  // Instance
@@ -32,26 +33,48 @@ export class TypeDoc {
32
33
  include: [] as string[],
33
34
  };
34
35
  let startDirectory = '';
35
- if (await plugins.fsInstance.directory(plugins.path.join(paths.cwd, './ts')).exists()) {
36
- data.include.push(plugins.path.join(paths.cwd, './ts/**/*'));
36
+ if (await plugins.fsInstance.directory(plugins.path.join(this.typedocDirectory, './ts')).exists()) {
37
+ data.include.push(plugins.path.join(this.typedocDirectory, './ts/**/*'));
37
38
  startDirectory = 'ts';
38
39
  }
39
40
 
40
- if (await plugins.fsInstance.directory(plugins.path.join(paths.cwd, './ts_web')).exists()) {
41
- data.include.push(plugins.path.join(paths.cwd, './ts_web/**/*'));
41
+ if (await plugins.fsInstance.directory(plugins.path.join(this.typedocDirectory, './ts_web')).exists()) {
42
+ data.include.push(plugins.path.join(this.typedocDirectory, './ts_web/**/*'));
42
43
  if (!startDirectory) {
43
44
  startDirectory = 'ts_web';
44
45
  }
45
46
  }
46
47
 
47
- await plugins.fsInstance.file(paths.tsconfigFile).encoding('utf8').write(JSON.stringify(data));
48
- let targetDir = paths.publicDir;
48
+ if (!startDirectory) {
49
+ throw new Error(`No TypeDoc entrypoint found in ${this.typedocDirectory}`);
50
+ }
51
+
52
+ const tempDir = plugins.path.join(this.typedocDirectory, '.nogit', 'tsdoc');
53
+ const tempTsconfigFile = plugins.path.join(tempDir, 'tsconfig.json');
54
+ await plugins.fsInstance.directory(tempDir).recursive().create();
55
+ await plugins.fsInstance.file(tempTsconfigFile).encoding('utf8').write(JSON.stringify(data));
56
+ const publicDir = plugins.path.join(this.typedocDirectory, 'public');
57
+ let targetDir = publicDir;
49
58
  if (options?.publicSubdir) {
50
- targetDir = plugins.path.join(targetDir, options.publicSubdir);
59
+ targetDir = plugins.path.resolve(plugins.path.join(targetDir, options.publicSubdir));
60
+ const resolvedPublicDir = plugins.path.resolve(publicDir);
61
+ if (!targetDir.startsWith(`${resolvedPublicDir}${plugins.path.sep}`) && targetDir !== resolvedPublicDir) {
62
+ throw new Error(`Invalid publicSubdir outside public directory: ${options.publicSubdir}`);
63
+ }
64
+ }
65
+ try {
66
+ const result = await this.smartshellInstance.exec(
67
+ `typedoc --tsconfig ${shellQuote(tempTsconfigFile)} --out ${shellQuote(targetDir)} ${shellQuote(plugins.path.join(this.typedocDirectory, startDirectory, 'index.ts'))}`,
68
+ );
69
+ if (result.exitCode !== 0) {
70
+ throw new Error('typedoc command failed.');
71
+ }
72
+ } finally {
73
+ if (await plugins.fsInstance.file(tempTsconfigFile).exists()) {
74
+ await plugins.fsInstance.file(tempTsconfigFile).delete();
75
+ }
51
76
  }
52
- await this.smartshellInstance.exec(
53
- `typedoc --tsconfig ${paths.tsconfigFile} --out ${targetDir} ${startDirectory}/index.ts`,
54
- );
55
- await plugins.fsInstance.file(paths.tsconfigFile).delete();
56
77
  }
57
78
  }
79
+
80
+ const shellQuote = (value: string): string => `'${value.replaceAll("'", "'\\''")}'`;
package/ts/cli.ts CHANGED
@@ -4,6 +4,41 @@ import { logger } from './logging.js';
4
4
 
5
5
  import { TypeDoc } from './classes.typedoc.js';
6
6
  import { AiDoc } from './classes.aidoc.js';
7
+ import { NoChangesError } from './aidocs_classes/commit.js';
8
+
9
+ const createAiDoc = async (argvArg: any): Promise<AiDoc> => {
10
+ const aidocInstance = new AiDoc(argvArg);
11
+ await aidocInstance.start();
12
+ return aidocInstance;
13
+ };
14
+
15
+ const getSmartcliArgv = (): string[] | undefined => {
16
+ if (process.argv.length === 0) return undefined;
17
+ if (process.argv[0] === process.execPath) return undefined;
18
+ return [process.execPath, 'tsdoc', ...process.argv];
19
+ };
20
+
21
+ const handleAuthCommand = async (argvArg: any): Promise<void> => {
22
+ const subcommand = argvArg._?.[1] ?? 'status';
23
+ if (subcommand === 'login') {
24
+ await plugins.tsagent.loginChatGptAuth();
25
+ return;
26
+ }
27
+
28
+ const inspections = await plugins.tsagent.inspectChatGptAuthSources();
29
+ console.log('OpenAI ChatGPT auth sources:');
30
+ for (const inspection of inspections) {
31
+ const status = inspection.usable
32
+ ? 'usable'
33
+ : inspection.exists
34
+ ? inspection.expired
35
+ ? 'expired'
36
+ : 'not usable'
37
+ : 'missing';
38
+ const account = inspection.email ? ` (${inspection.email})` : '';
39
+ console.log(` ${inspection.source}: ${status}${account} - ${inspection.filePath}`);
40
+ }
41
+ };
7
42
 
8
43
  export const run = async () => {
9
44
  const tsdocCli = new plugins.smartcli.Smartcli();
@@ -28,8 +63,7 @@ export const run = async () => {
28
63
  });
29
64
 
30
65
  tsdocCli.addCommand('aidoc').subscribe(async (argvArg) => {
31
- const aidocInstance = new AiDoc();
32
- await aidocInstance.start();
66
+ const aidocInstance = await createAiDoc(argvArg);
33
67
 
34
68
  logger.log('info', `Generating new readme...`);
35
69
  logger.log('info', `This may take some time...`);
@@ -39,9 +73,12 @@ export const run = async () => {
39
73
  await aidocInstance.buildDescription(paths.cwd);
40
74
  });
41
75
 
76
+ tsdocCli.addCommand('aidocs').subscribe(async (argvArg) => {
77
+ tsdocCli.triggerCommand('aidoc', argvArg);
78
+ });
79
+
42
80
  tsdocCli.addCommand('readme').subscribe(async (argvArg) => {
43
- const aidocInstance = new AiDoc();
44
- await aidocInstance.start();
81
+ const aidocInstance = await createAiDoc(argvArg);
45
82
 
46
83
  logger.log('info', `Generating new readme...`);
47
84
  logger.log('info', `This may take some time...`);
@@ -49,8 +86,7 @@ export const run = async () => {
49
86
  });
50
87
 
51
88
  tsdocCli.addCommand('description').subscribe(async (argvArg) => {
52
- const aidocInstance = new AiDoc();
53
- await aidocInstance.start();
89
+ const aidocInstance = await createAiDoc(argvArg);
54
90
 
55
91
  logger.log('info', `Generating new description and keywords...`);
56
92
  logger.log('info', `This may take some time...`);
@@ -58,17 +94,30 @@ export const run = async () => {
58
94
  });
59
95
 
60
96
  tsdocCli.addCommand('commit').subscribe(async (argvArg) => {
61
- const aidocInstance = new AiDoc();
62
- await aidocInstance.start();
97
+ const aidocInstance = await createAiDoc(argvArg);
63
98
 
64
99
  logger.log('info', `Generating commit message...`);
65
100
  logger.log('info', `This may take some time...`);
66
- const commitObject = await aidocInstance.buildNextCommitObject(paths.cwd);
101
+ let commitObject: Awaited<ReturnType<AiDoc['buildNextCommitObject']>>;
102
+ try {
103
+ commitObject = await aidocInstance.buildNextCommitObject(paths.cwd);
104
+ } catch (error) {
105
+ if (error instanceof NoChangesError || (error as Error).name === 'NoChangesError') {
106
+ logger.log('info', 'No uncommitted changes found.');
107
+ console.log(JSON.stringify({ ok: true, noChanges: true }, null, 2));
108
+ return;
109
+ }
110
+ throw error;
111
+ }
67
112
 
68
113
  logger.log('ok', `Commit message generated:`);
69
114
  console.log(JSON.stringify(commitObject, null, 2));
70
115
  });
71
116
 
117
+ tsdocCli.addCommand('auth').subscribe(async (argvArg) => {
118
+ await handleAuthCommand(argvArg);
119
+ });
120
+
72
121
  tsdocCli.addCommand('test').subscribe((argvArg) => {
73
122
  tsdocCli.triggerCommand('typedoc', argvArg);
74
123
  process.on('exit', async () => {
@@ -76,5 +125,5 @@ export const run = async () => {
76
125
  });
77
126
  });
78
127
 
79
- tsdocCli.startParse();
128
+ tsdocCli.startParse(getSmartcliArgv());
80
129
  };
@@ -0,0 +1,5 @@
1
+ import * as plugins from './plugins.js';
2
+
3
+ export const createReadOnlyFileSystemTools = async (rootDirArg: string) => {
4
+ return await plugins.tsagent.createReadOnlyProjectTools(rootDirArg);
5
+ };
package/ts/index.ts CHANGED
@@ -10,3 +10,4 @@ export const runCli = async () => {
10
10
 
11
11
  // exports
12
12
  export * from './classes.aidoc.js';
13
+ export { NoChangesError } from './aidocs_classes/commit.js';
package/ts/plugins.ts CHANGED
@@ -1,14 +1,17 @@
1
1
  // node native
2
+ import * as fs from 'node:fs/promises';
2
3
  import * as path from 'path';
3
4
 
4
- export { path };
5
+ export { fs, path };
5
6
 
6
7
  // pushrocks scope
7
8
  import * as smartconfig from '@push.rocks/smartconfig';
8
9
  import * as qenv from '@push.rocks/qenv';
9
10
  import * as smartagent from '@push.rocks/smartagent';
11
+ import * as smartagentCompaction from '@push.rocks/smartagent/compaction';
10
12
  import * as smartagentTools from '@push.rocks/smartagent/tools';
11
13
  import * as smartai from '@push.rocks/smartai';
14
+ import * as smartaiOpenAiChatGptAuth from '@push.rocks/smartai/openai-chatgpt-auth';
12
15
  import * as smartcli from '@push.rocks/smartcli';
13
16
  import * as smartdelay from '@push.rocks/smartdelay';
14
17
  import * as smartfile from '@push.rocks/smartfile';
@@ -25,8 +28,10 @@ export {
25
28
  smartconfig,
26
29
  qenv,
27
30
  smartagent,
31
+ smartagentCompaction,
28
32
  smartagentTools,
29
33
  smartai,
34
+ smartaiOpenAiChatGptAuth,
30
35
  smartcli,
31
36
  smartdelay,
32
37
  smartfile,
@@ -48,9 +53,10 @@ export const fsInstance = new smartfs.SmartFs(smartFsNodeProvider);
48
53
  export const smartfileFactory = smartfile.SmartFileFactory.nodeFs();
49
54
 
50
55
  // @git.zone scope
56
+ import * as tsagent from '@git.zone/tsagent';
51
57
  import * as tspublish from '@git.zone/tspublish';
52
58
 
53
- export { tspublish };
59
+ export { tsagent, tspublish };
54
60
 
55
61
  // third party scope
56
62
  import * as typedoc from 'typedoc';