@git.zone/tsagent 1.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.
package/dist_ts/cli.js ADDED
@@ -0,0 +1,129 @@
1
+ import * as plugins from './plugins.js';
2
+ import * as paths from './paths.js';
3
+ import { TsAgent, inspectChatGptAuthSources, loginChatGptAuth } from './classes.tsagent.js';
4
+ const sensitiveConfigKeyRegex = /(^apiKey$|api[_-]?key|token|secret|password|credential|authorization)/i;
5
+ const redactSensitiveConfigValues = (valueArg, keyArg) => {
6
+ if (keyArg && sensitiveConfigKeyRegex.test(keyArg)) {
7
+ return valueArg ? '[redacted]' : valueArg;
8
+ }
9
+ if (Array.isArray(valueArg)) {
10
+ return valueArg.map(value => redactSensitiveConfigValues(value));
11
+ }
12
+ if (typeof valueArg === 'object' && valueArg !== null) {
13
+ return Object.fromEntries(Object.entries(valueArg).map(([key, value]) => [
14
+ key,
15
+ redactSensitiveConfigValues(value, key),
16
+ ]));
17
+ }
18
+ return valueArg;
19
+ };
20
+ export const redactConfigForOutput = (configArg) => {
21
+ return redactSensitiveConfigValues(configArg);
22
+ };
23
+ const getPrompt = async (argvArg) => {
24
+ const positional = (argvArg._ || []).slice(1).join(' ').trim();
25
+ if (positional)
26
+ return positional;
27
+ if (typeof argvArg.prompt === 'string')
28
+ return argvArg.prompt;
29
+ const interact = new plugins.smartinteract.SmartInteract();
30
+ const answer = await interact.askQuestion({
31
+ type: 'input',
32
+ name: 'prompt',
33
+ message: 'What should tsagent help with?',
34
+ default: '',
35
+ });
36
+ return answer.value;
37
+ };
38
+ const runChat = async (argvArg) => {
39
+ const prompt = await getPrompt(argvArg);
40
+ const agent = new TsAgent({ argvArg, projectDir: paths.cwd });
41
+ await agent.start();
42
+ try {
43
+ const tools = argvArg.repo ? await agent.createReadOnlyProjectTools(paths.cwd) : undefined;
44
+ const result = await agent.runAgent({
45
+ taskName: 'chat',
46
+ projectDir: paths.cwd,
47
+ system: argvArg.repo
48
+ ? 'You are a concise repo-aware engineering assistant. You can read files but must not reveal secrets.'
49
+ : 'You are a concise engineering assistant.',
50
+ prompt,
51
+ tools,
52
+ maxSteps: argvArg.repo ? 20 : 3,
53
+ useCompaction: true,
54
+ onToolCall: (toolName) => console.log(`[tool] ${toolName}`),
55
+ });
56
+ console.log(result.text);
57
+ }
58
+ finally {
59
+ await agent.stop();
60
+ }
61
+ };
62
+ const runAuth = async (argvArg) => {
63
+ const subcommand = argvArg._?.[1] || 'status';
64
+ if (subcommand === 'login') {
65
+ await loginChatGptAuth();
66
+ return;
67
+ }
68
+ const inspections = await inspectChatGptAuthSources();
69
+ console.log('OpenAI ChatGPT auth sources:');
70
+ for (const inspection of inspections) {
71
+ const status = inspection.usable
72
+ ? 'usable'
73
+ : inspection.exists
74
+ ? inspection.expired
75
+ ? 'expired'
76
+ : 'not usable'
77
+ : 'missing';
78
+ const account = inspection.email ? ` (${inspection.email})` : '';
79
+ console.log(` ${inspection.source}: ${status}${account} - ${inspection.filePath}`);
80
+ }
81
+ };
82
+ const runConfig = async (argvArg) => {
83
+ const subcommand = argvArg._?.[1] || 'show';
84
+ if (subcommand !== 'show') {
85
+ throw new Error(`Unknown config subcommand: ${subcommand}`);
86
+ }
87
+ const agent = new TsAgent({ argvArg, projectDir: paths.cwd });
88
+ await agent.start();
89
+ try {
90
+ console.log(JSON.stringify({
91
+ config: redactConfigForOutput(agent.config),
92
+ selectedAuthSource: agent.selectedAuthSource,
93
+ }, null, 2));
94
+ }
95
+ finally {
96
+ await agent.stop();
97
+ }
98
+ };
99
+ const printHelp = () => {
100
+ console.log(`
101
+ Usage: tsagent <command> [options]
102
+
103
+ Commands:
104
+ chat [--repo] [prompt] Chat directly with the configured model
105
+ auth [status|login] Inspect or create ChatGPT subscription auth
106
+ config show Show resolved tsagent config
107
+
108
+ Examples:
109
+ tsagent chat "explain this project"
110
+ tsagent chat --repo "which file exports the public API?"
111
+ tsagent auth status
112
+ `);
113
+ };
114
+ export const runCli = async () => {
115
+ const cli = new plugins.smartcli.Smartcli();
116
+ cli.standardCommand().subscribe(async (argvArg) => {
117
+ if (argvArg.help || argvArg.h) {
118
+ printHelp();
119
+ return;
120
+ }
121
+ await runChat(argvArg);
122
+ });
123
+ cli.addCommand('chat').subscribe(runChat);
124
+ cli.addCommand('auth').subscribe(runAuth);
125
+ cli.addCommand('config').subscribe(runConfig);
126
+ cli.addCommand('help').subscribe(async () => printHelp());
127
+ cli.startParse();
128
+ };
129
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsZ0JBQWdCLEVBQStCLE1BQU0sc0JBQXNCLENBQUM7QUFFekgsTUFBTSx1QkFBdUIsR0FBRyx3RUFBd0UsQ0FBQztBQUV6RyxNQUFNLDJCQUEyQixHQUFHLENBQUMsUUFBaUIsRUFBRSxNQUFlLEVBQVcsRUFBRTtJQUNsRixJQUFJLE1BQU0sSUFBSSx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUNuRCxPQUFPLFFBQVEsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUNELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQzVCLE9BQU8sUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLDJCQUEyQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUNELElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN0RCxPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDdkUsR0FBRztZQUNILDJCQUEyQixDQUFDLEtBQUssRUFBRSxHQUFHLENBQUM7U0FDeEMsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQyxDQUFDO0FB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
@@ -0,0 +1,3 @@
1
+ export * from './classes.tsagent.js';
2
+ export * from './tools.project.js';
3
+ export * from './cli.js';
@@ -0,0 +1,4 @@
1
+ export * from './classes.tsagent.js';
2
+ export * from './tools.project.js';
3
+ export * from './cli.js';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxVQUFVLENBQUMifQ==
@@ -0,0 +1,2 @@
1
+ export declare const cwd: string;
2
+ export declare const packageBase: string;
@@ -0,0 +1,4 @@
1
+ import * as plugins from './plugins.js';
2
+ export const cwd = process.cwd();
3
+ export const packageBase = plugins.path.resolve(new URL('..', import.meta.url).pathname);
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxNQUFNLENBQUMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pDLE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyJ9
@@ -0,0 +1,14 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ export { fs, path };
4
+ import * as qenv from '@push.rocks/qenv';
5
+ import * as smartagent from '@push.rocks/smartagent';
6
+ import * as smartagentCompaction from '@push.rocks/smartagent/compaction';
7
+ import * as smartai from '@push.rocks/smartai';
8
+ import * as smartaiOpenAiChatGptAuth from '@push.rocks/smartai/openai-chatgpt-auth';
9
+ import * as smartcli from '@push.rocks/smartcli';
10
+ import * as smartconfig from '@push.rocks/smartconfig';
11
+ import * as smartdelay from '@push.rocks/smartdelay';
12
+ import * as smartinteract from '@push.rocks/smartinteract';
13
+ import * as smartpath from '@push.rocks/smartpath';
14
+ export { qenv, smartagent, smartagentCompaction, smartai, smartaiOpenAiChatGptAuth, smartcli, smartconfig, smartdelay, smartinteract, smartpath, };
@@ -0,0 +1,17 @@
1
+ // node native scope
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ export { fs, path };
5
+ // @push.rocks scope
6
+ import * as qenv from '@push.rocks/qenv';
7
+ import * as smartagent from '@push.rocks/smartagent';
8
+ import * as smartagentCompaction from '@push.rocks/smartagent/compaction';
9
+ import * as smartai from '@push.rocks/smartai';
10
+ import * as smartaiOpenAiChatGptAuth from '@push.rocks/smartai/openai-chatgpt-auth';
11
+ import * as smartcli from '@push.rocks/smartcli';
12
+ import * as smartconfig from '@push.rocks/smartconfig';
13
+ import * as smartdelay from '@push.rocks/smartdelay';
14
+ import * as smartinteract from '@push.rocks/smartinteract';
15
+ import * as smartpath from '@push.rocks/smartpath';
16
+ export { qenv, smartagent, smartagentCompaction, smartai, smartaiOpenAiChatGptAuth, smartcli, smartconfig, smartdelay, smartinteract, smartpath, };
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdkMsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUM7QUFFbEMsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUVwQixvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEtBQUssVUFBVSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JELE9BQU8sS0FBSyxvQkFBb0IsTUFBTSxtQ0FBbUMsQ0FBQztBQUMxRSxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBQy9DLE9BQU8sS0FBSyx3QkFBd0IsTUFBTSx5Q0FBeUMsQ0FBQztBQUNwRixPQUFPLEtBQUssUUFBUSxNQUFNLHNCQUFzQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssYUFBYSxNQUFNLDJCQUEyQixDQUFDO0FBQzNELE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFFbkQsT0FBTyxFQUNMLElBQUksRUFDSixVQUFVLEVBQ1Ysb0JBQW9CLEVBQ3BCLE9BQU8sRUFDUCx3QkFBd0IsRUFDeEIsUUFBUSxFQUNSLFdBQVcsRUFDWCxVQUFVLEVBQ1YsYUFBYSxFQUNiLFNBQVMsR0FDVixDQUFDIn0=
@@ -0,0 +1,2 @@
1
+ import * as plugins from './plugins.js';
2
+ export declare const createReadOnlyProjectTools: (rootDirArg: string) => Promise<plugins.smartai.ToolSet>;
@@ -0,0 +1,126 @@
1
+ import * as plugins from './plugins.js';
2
+ const defaultDeniedSegments = new Set([
3
+ '.cache',
4
+ '.git',
5
+ '.next',
6
+ '.nogit',
7
+ '.rpt2_cache',
8
+ 'build',
9
+ 'coverage',
10
+ 'dist',
11
+ 'node_modules',
12
+ 'out',
13
+ ]);
14
+ const defaultDeniedBasenames = new Set([
15
+ '.npmrc',
16
+ 'bun.lockb',
17
+ 'credentials.json',
18
+ 'deno.lock',
19
+ 'npm-shrinkwrap.json',
20
+ 'package-lock.json',
21
+ 'pnpm-lock.yaml',
22
+ 'yarn.lock',
23
+ ]);
24
+ const assertAllowedRelativePath = (relativePath) => {
25
+ const normalized = relativePath.split(plugins.path.sep).join('/');
26
+ const parts = normalized.split('/').filter(Boolean);
27
+ const basename = parts.at(-1) ?? normalized;
28
+ if (basename === '.env' || basename.startsWith('.env.')) {
29
+ throw new Error(`Access denied: ${relativePath} may contain environment secrets.`);
30
+ }
31
+ if (basename.endsWith('.pem') || basename.endsWith('.key') || basename.endsWith('.p12')) {
32
+ throw new Error(`Access denied: ${relativePath} may contain private key material.`);
33
+ }
34
+ if (defaultDeniedBasenames.has(basename)) {
35
+ throw new Error(`Access denied: ${relativePath} is excluded from AI file access.`);
36
+ }
37
+ for (const segment of parts) {
38
+ if (defaultDeniedSegments.has(segment) || segment.startsWith('dist_')) {
39
+ throw new Error(`Access denied: ${relativePath} is excluded from AI file access.`);
40
+ }
41
+ }
42
+ };
43
+ const realpathIfExists = async (pathArg) => {
44
+ try {
45
+ return await plugins.fs.realpath(pathArg);
46
+ }
47
+ catch {
48
+ return plugins.path.resolve(pathArg);
49
+ }
50
+ };
51
+ const resolveAllowedPath = async (rootDirArg, inputPathArg) => {
52
+ const rootReal = await plugins.fs.realpath(plugins.path.resolve(rootDirArg));
53
+ const resolvedCandidate = plugins.path.resolve(plugins.path.isAbsolute(inputPathArg)
54
+ ? inputPathArg
55
+ : plugins.path.join(rootReal, inputPathArg));
56
+ const resolvedReal = await realpathIfExists(resolvedCandidate);
57
+ if (resolvedReal !== rootReal && !resolvedReal.startsWith(`${rootReal}${plugins.path.sep}`)) {
58
+ throw new Error(`Access denied: "${inputPathArg}" is outside allowed root "${rootDirArg}"`);
59
+ }
60
+ const relativePath = plugins.path.relative(rootReal, resolvedReal) || '.';
61
+ assertAllowedRelativePath(relativePath);
62
+ return { resolvedPath: resolvedReal, relativePath };
63
+ };
64
+ const listDirectory = async (rootDirArg, dirPathArg, recursive = false) => {
65
+ const { resolvedPath } = await resolveAllowedPath(rootDirArg, dirPathArg);
66
+ const entries = await plugins.fs.readdir(resolvedPath, { withFileTypes: true });
67
+ const result = [];
68
+ for (const entry of entries) {
69
+ const childPath = plugins.path.join(resolvedPath, entry.name);
70
+ const childRelativeInput = plugins.path.relative(rootDirArg, childPath) || entry.name;
71
+ try {
72
+ const allowed = await resolveAllowedPath(rootDirArg, childRelativeInput);
73
+ const stat = await plugins.fs.stat(allowed.resolvedPath);
74
+ result.push(`${allowed.relativePath}${stat.isDirectory() ? '/' : ''}`);
75
+ if (recursive && stat.isDirectory()) {
76
+ result.push(...await listDirectory(rootDirArg, allowed.relativePath, true));
77
+ }
78
+ }
79
+ catch {
80
+ continue;
81
+ }
82
+ }
83
+ return result.sort();
84
+ };
85
+ export const createReadOnlyProjectTools = async (rootDirArg) => {
86
+ const rootDir = await plugins.fs.realpath(plugins.path.resolve(rootDirArg));
87
+ return {
88
+ read_file: plugins.smartagent.tool({
89
+ description: 'Read file contents within the project. Secret and generated paths are blocked.',
90
+ inputSchema: plugins.smartagent.z.object({
91
+ path: plugins.smartagent.z.string().describe('Absolute or project-relative path to the file'),
92
+ startLine: plugins.smartagent.z.number().optional().describe('First line, 1-indexed and inclusive'),
93
+ endLine: plugins.smartagent.z.number().optional().describe('Last line, 1-indexed and inclusive'),
94
+ }),
95
+ execute: async ({ path: filePath, startLine, endLine }) => {
96
+ const { resolvedPath } = await resolveAllowedPath(rootDir, filePath);
97
+ const stat = await plugins.fs.stat(resolvedPath);
98
+ if (!stat.isFile()) {
99
+ throw new Error(`Cannot read non-file path: ${filePath}`);
100
+ }
101
+ const content = await plugins.fs.readFile(resolvedPath, 'utf8');
102
+ const selectedContent = startLine !== undefined || endLine !== undefined
103
+ ? content.split('\n').slice((startLine ?? 1) - 1, endLine).join('\n')
104
+ : content;
105
+ return plugins.smartagent.truncateOutput(selectedContent).content;
106
+ },
107
+ }),
108
+ list_directory: plugins.smartagent.tool({
109
+ description: 'List project files and directories. Secret and generated paths are omitted.',
110
+ inputSchema: plugins.smartagent.z.object({
111
+ path: plugins.smartagent.z.string().describe('Absolute or project-relative directory path to list'),
112
+ recursive: plugins.smartagent.z.boolean().optional().describe('List recursively'),
113
+ }),
114
+ execute: async ({ path: dirPath, recursive }) => {
115
+ const { resolvedPath } = await resolveAllowedPath(rootDir, dirPath);
116
+ const stat = await plugins.fs.stat(resolvedPath);
117
+ if (!stat.isDirectory()) {
118
+ throw new Error(`Cannot list non-directory path: ${dirPath}`);
119
+ }
120
+ const entries = await listDirectory(rootDir, dirPath, recursive === true);
121
+ return plugins.smartagent.truncateOutput(entries.join('\n')).content;
122
+ },
123
+ }),
124
+ };
125
+ };
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHMucHJvamVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3Rvb2xzLnByb2plY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFFeEMsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNwQyxRQUFRO0lBQ1IsTUFBTTtJQUNOLE9BQU87SUFDUCxRQUFRO0lBQ1IsYUFBYTtJQUNiLE9BQU87SUFDUCxVQUFVO0lBQ1YsTUFBTTtJQUNOLGNBQWM7SUFDZCxLQUFLO0NBQ04sQ0FBQyxDQUFDO0FBRUgsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNyQyxRQUFRO0lBQ1IsV0FBVztJQUNYLGtCQUFrQjtJQUNsQixXQUFXO0lBQ1gscUJBQXFCO0lBQ3JCLG1CQUFtQjtJQUNuQixnQkFBZ0I7SUFDaEIsV0FBVztDQUNaLENBQUMsQ0FBQztBQUVILE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxZQUFvQixFQUFRLEVBQUU7SUFDL0QsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNsRSxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNwRCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDO0lBRTVDLElBQUksUUFBUSxLQUFLLE1BQU0sSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDeEQsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsWUFBWSxtQ0FBbUMsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FB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
package/license.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Task Venture Capital GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@git.zone/tsagent",
3
+ "version": "1.1.0",
4
+ "private": false,
5
+ "description": "Shared AI agent runtime, authentication, and CLI for git.zone TypeScript tooling.",
6
+ "main": "dist_ts/index.js",
7
+ "typings": "dist_ts/index.d.ts",
8
+ "type": "module",
9
+ "bin": {
10
+ "tsagent": "./cli.js"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://code.foss.global/git.zone/tsagent.git"
15
+ },
16
+ "keywords": [
17
+ "AI",
18
+ "agent",
19
+ "smartagent",
20
+ "smartai",
21
+ "TypeScript",
22
+ "CLI",
23
+ "tooling",
24
+ "git.zone"
25
+ ],
26
+ "author": "Task Venture Capital GmbH",
27
+ "license": "MIT",
28
+ "bugs": {
29
+ "url": "https://code.foss.global/git.zone/tsagent/issues"
30
+ },
31
+ "homepage": "https://code.foss.global/git.zone/tsagent#readme",
32
+ "dependencies": {
33
+ "@push.rocks/qenv": "^6.1.4",
34
+ "@push.rocks/smartagent": "^3.3.0",
35
+ "@push.rocks/smartai": "^4.0.0",
36
+ "@push.rocks/smartcli": "^4.0.21",
37
+ "@push.rocks/smartconfig": "^6.1.1",
38
+ "@push.rocks/smartdelay": "^3.1.0",
39
+ "@push.rocks/smartfs": "^1.5.1",
40
+ "@push.rocks/smartinteract": "^2.0.16",
41
+ "@push.rocks/smartpath": "^6.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "@git.zone/tsbuild": "^4.4.2",
45
+ "@git.zone/tsrun": "^2.0.4",
46
+ "@git.zone/tstest": "^3.6.6",
47
+ "@types/node": "^25.9.1"
48
+ },
49
+ "files": [
50
+ "ts/**/*",
51
+ "dist/**/*",
52
+ "dist_*/**/*",
53
+ "dist_ts/**/*",
54
+ "assets/**/*",
55
+ "cli.js",
56
+ ".smartconfig.json",
57
+ "readme.md",
58
+ "license.md"
59
+ ],
60
+ "browserslist": [
61
+ "last 1 chrome versions"
62
+ ],
63
+ "scripts": {
64
+ "test": "tstest test/ --verbose --logfile --timeout 120",
65
+ "build": "tsbuild tsfolders",
66
+ "buildDocs": "tsdoc"
67
+ }
68
+ }
package/readme.md ADDED
@@ -0,0 +1,126 @@
1
+ # @git.zone/tsagent
2
+
3
+ `tsagent` is the shared AI runtime for `@git.zone` tools. It centralizes model setup, ChatGPT/API-key auth, safe read-only project tools, structured agent tasks, and a small direct chat CLI.
4
+
5
+ ## Issue Reporting and Security
6
+
7
+ For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ pnpm add @git.zone/tsagent
13
+ ```
14
+
15
+ For CLI-only development tooling, install it as a dev dependency:
16
+
17
+ ```sh
18
+ pnpm add --save-dev @git.zone/tsagent
19
+ ```
20
+
21
+ ## CLI
22
+
23
+ ```sh
24
+ tsagent chat "explain this repository"
25
+ tsagent chat --repo "which files define the public API?"
26
+ tsagent auth status
27
+ tsagent auth login
28
+ tsagent config show
29
+ ```
30
+
31
+ ## Configuration
32
+
33
+ Project defaults live in `.smartconfig.json` under `@git.zone/tsagent`:
34
+
35
+ ```json
36
+ {
37
+ "@git.zone/tsagent": {
38
+ "provider": "openai",
39
+ "model": "gpt-5.5",
40
+ "authMode": "auto",
41
+ "chatGptAuthSources": ["opencode", "codex", "smartai"],
42
+ "providerOptions": {
43
+ "openai": {
44
+ "reasoningEffort": "xhigh"
45
+ }
46
+ },
47
+ "cache": "auto"
48
+ }
49
+ }
50
+ ```
51
+
52
+ Auth state is user-local. API-key fallback is stored in `~/.smartconfig/kv/@git.zone/tsagent.json`; ChatGPT subscription auth uses the existing `opencode`, `codex`, or `smartai` auth sources.
53
+
54
+ Environment overrides:
55
+
56
+ ```sh
57
+ TSAGENT_AI_PROVIDER=openai
58
+ TSAGENT_AI_MODEL=gpt-5.5
59
+ TSAGENT_AUTH_MODE=auto
60
+ TSAGENT_CHATGPT_AUTH_SOURCES=opencode,codex,smartai
61
+ TSAGENT_OPENAI_REASONING_EFFORT=xhigh
62
+ OPENAI_TOKEN=...
63
+ ```
64
+
65
+ Provider API-key environment variables use `OPENAI_TOKEN` or `OPENAI_API_KEY` for OpenAI, and `<PROVIDER>_TOKEN` or `<PROVIDER>_API_KEY` for other providers.
66
+
67
+ ## Library
68
+
69
+ ```ts
70
+ import { TsAgent } from '@git.zone/tsagent';
71
+
72
+ const agent = new TsAgent({ projectDir: process.cwd() });
73
+ await agent.start();
74
+
75
+ const result = await agent.runJsonTask({
76
+ taskName: 'inspect-project',
77
+ projectDir: process.cwd(),
78
+ system: 'Return JSON only.',
79
+ prompt: 'Identify the main package purpose.',
80
+ validate: (value) => {
81
+ if (typeof value !== 'object' || !value) return 'Return an object.';
82
+ },
83
+ });
84
+
85
+ await agent.stop();
86
+ ```
87
+
88
+ Project tools are read-only by default and block common secret, generated, dependency, and private paths.
89
+
90
+ ## API
91
+
92
+ Top-level exports:
93
+
94
+ ```ts
95
+ import {
96
+ TsAgent,
97
+ createReadOnlyProjectTools,
98
+ defaultTsAgentConfig,
99
+ inspectChatGptAuthSources,
100
+ loginChatGptAuth,
101
+ runCli,
102
+ } from '@git.zone/tsagent';
103
+ ```
104
+
105
+ `TsAgent` is the main runtime facade. `createReadOnlyProjectTools()` exposes safe `read_file` and `list_directory` tools for agent tasks. `inspectChatGptAuthSources()` and `loginChatGptAuth()` are CLI/auth helpers for ChatGPT subscription auth.
106
+
107
+ ## License and Legal Information
108
+
109
+ This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the repository license file.
110
+
111
+ **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
112
+
113
+ ### Trademarks
114
+
115
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
116
+
117
+ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
118
+
119
+ ### Company Information
120
+
121
+ Task Venture Capital GmbH<br>
122
+ Registered at District Court Bremen HRB 35230 HB, Germany
123
+
124
+ For any legal inquiries or further information, please contact us via email at hello@task.vc.
125
+
126
+ By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * autocreated commitinfo by @push.rocks/commitinfo
3
+ */
4
+ export const commitinfo = {
5
+ name: '@git.zone/tsagent',
6
+ version: '1.1.0',
7
+ description: 'Shared AI agent runtime, authentication, and CLI for git.zone TypeScript tooling.'
8
+ }