@tankgate/core 0.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.
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Agent Detection Module
3
+ *
4
+ * Detects which AI coding agent is being used in a project by examining
5
+ * configuration files, directory structures, and package.json scripts.
6
+ */
7
+ import type { DetectionResult } from './types';
8
+ export type { AgentType, DetectionResult } from './types';
9
+ /**
10
+ * Detect the AI agent being used in a project
11
+ */
12
+ export declare function detectAgent(projectPath: string): Promise<DetectionResult | null>;
13
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1D;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAetF"}
package/dist/detect.js ADDED
@@ -0,0 +1,302 @@
1
+ /**
2
+ * Agent Detection Module
3
+ *
4
+ * Detects which AI coding agent is being used in a project by examining
5
+ * configuration files, directory structures, and package.json scripts.
6
+ */
7
+ import { access, readFile, stat } from 'fs/promises';
8
+ import { join } from 'path';
9
+ /**
10
+ * Detect the AI agent being used in a project
11
+ */
12
+ export async function detectAgent(projectPath) {
13
+ const checks = [
14
+ () => detectOpenClaw(projectPath),
15
+ () => detectClaudeCode(projectPath),
16
+ () => detectAider(projectPath),
17
+ () => detectCline(projectPath),
18
+ () => detectContinue(projectPath),
19
+ ];
20
+ for (const check of checks) {
21
+ const result = await check();
22
+ if (result)
23
+ return result;
24
+ }
25
+ return null;
26
+ }
27
+ /**
28
+ * Check if a file or directory exists
29
+ */
30
+ async function exists(path) {
31
+ try {
32
+ await access(path);
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ /**
40
+ * Check if a path is a directory
41
+ */
42
+ async function isDirectory(path) {
43
+ try {
44
+ const s = await stat(path);
45
+ return s.isDirectory();
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
51
+ /**
52
+ * Read and parse package.json
53
+ */
54
+ async function readPackageJson(projectPath) {
55
+ try {
56
+ const content = await readFile(join(projectPath, 'package.json'), 'utf-8');
57
+ return JSON.parse(content);
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ /**
64
+ * Read VSCode settings.json
65
+ * Note: VSCode settings.json supports JSON with Comments (JSONC)
66
+ */
67
+ async function readVscodeSettings(projectPath) {
68
+ try {
69
+ const content = await readFile(join(projectPath, '.vscode', 'settings.json'), 'utf-8');
70
+ // Handle JSON with comments using a more robust approach
71
+ // This strips // line comments and /* block comments */ while
72
+ // attempting to preserve them inside strings
73
+ const cleaned = stripJsonComments(content);
74
+ return JSON.parse(cleaned);
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }
80
+ /**
81
+ * Strip JSON comments while preserving them inside strings
82
+ * Handles line comments (//) and block comments (/* ... * /)
83
+ */
84
+ function stripJsonComments(content) {
85
+ let result = '';
86
+ let inString = false;
87
+ let stringChar = '';
88
+ let i = 0;
89
+ while (i < content.length) {
90
+ const char = content[i];
91
+ const nextChar = content[i + 1];
92
+ // Handle string boundaries
93
+ if (!inString && (char === '"' || char === "'")) {
94
+ inString = true;
95
+ stringChar = char;
96
+ result += char;
97
+ i++;
98
+ continue;
99
+ }
100
+ if (inString) {
101
+ // Check for escape sequence
102
+ if (char === '\\' && i + 1 < content.length) {
103
+ result += char + nextChar;
104
+ i += 2;
105
+ continue;
106
+ }
107
+ // Check for end of string
108
+ if (char === stringChar) {
109
+ inString = false;
110
+ stringChar = '';
111
+ }
112
+ result += char;
113
+ i++;
114
+ continue;
115
+ }
116
+ // Handle // line comments
117
+ if (char === '/' && nextChar === '/') {
118
+ // Skip until end of line
119
+ while (i < content.length && content[i] !== '\n') {
120
+ i++;
121
+ }
122
+ continue;
123
+ }
124
+ // Handle /* block comments */
125
+ if (char === '/' && nextChar === '*') {
126
+ i += 2;
127
+ // Skip until */
128
+ while (i < content.length - 1) {
129
+ if (content[i] === '*' && content[i + 1] === '/') {
130
+ i += 2;
131
+ break;
132
+ }
133
+ i++;
134
+ }
135
+ continue;
136
+ }
137
+ result += char;
138
+ i++;
139
+ }
140
+ return result;
141
+ }
142
+ /**
143
+ * Read VSCode extensions.json
144
+ */
145
+ async function readVscodeExtensions(projectPath) {
146
+ try {
147
+ const content = await readFile(join(projectPath, '.vscode', 'extensions.json'), 'utf-8');
148
+ const parsed = JSON.parse(content);
149
+ return parsed.recommendations ?? [];
150
+ }
151
+ catch {
152
+ return null;
153
+ }
154
+ }
155
+ /**
156
+ * Detect OpenClaw agent
157
+ * - .openclaw directory
158
+ * - .openclaw/config.yaml
159
+ */
160
+ async function detectOpenClaw(projectPath) {
161
+ const evidence = [];
162
+ let confidence = 'low';
163
+ const openclawDir = join(projectPath, '.openclaw');
164
+ if (await isDirectory(openclawDir)) {
165
+ evidence.push('.openclaw directory found');
166
+ confidence = 'high';
167
+ // Check for config file for higher confidence
168
+ if (await exists(join(openclawDir, 'config.yaml'))) {
169
+ evidence.push('.openclaw/config.yaml found');
170
+ confidence = 'high';
171
+ }
172
+ }
173
+ if (evidence.length === 0) {
174
+ return null;
175
+ }
176
+ return { agent: 'openclaw', confidence, evidence };
177
+ }
178
+ /**
179
+ * Detect Claude Code agent
180
+ * - .claude directory (CLAUDE.md, settings)
181
+ * - CLAUDE.md file in project root
182
+ */
183
+ async function detectClaudeCode(projectPath) {
184
+ const evidence = [];
185
+ let confidence = 'low';
186
+ // Check for .claude directory
187
+ const claudeDir = join(projectPath, '.claude');
188
+ if (await isDirectory(claudeDir)) {
189
+ evidence.push('.claude directory found');
190
+ confidence = 'high';
191
+ }
192
+ // Check for CLAUDE.md file
193
+ if (await exists(join(projectPath, 'CLAUDE.md'))) {
194
+ evidence.push('CLAUDE.md found');
195
+ confidence = confidence === 'high' ? 'high' : 'medium';
196
+ }
197
+ if (evidence.length === 0) {
198
+ return null;
199
+ }
200
+ return { agent: 'claude-code', confidence, evidence };
201
+ }
202
+ /**
203
+ * Detect Aider agent
204
+ * - .aider.chat.history.md file
205
+ * - .aider.input.history file
206
+ * - aider in package.json scripts
207
+ */
208
+ async function detectAider(projectPath) {
209
+ const evidence = [];
210
+ let confidence = 'low';
211
+ // Check for aider history files
212
+ if (await exists(join(projectPath, '.aider.chat.history.md'))) {
213
+ evidence.push('.aider.chat.history.md found');
214
+ confidence = 'high';
215
+ }
216
+ if (await exists(join(projectPath, '.aider.input.history'))) {
217
+ evidence.push('.aider.input.history found');
218
+ confidence = 'high';
219
+ }
220
+ // Check package.json for aider scripts
221
+ const pkg = await readPackageJson(projectPath);
222
+ if (pkg?.scripts && typeof pkg.scripts === 'object') {
223
+ const scripts = pkg.scripts;
224
+ for (const [name, script] of Object.entries(scripts)) {
225
+ if (script.includes('aider')) {
226
+ evidence.push(`package.json script "${name}" contains aider`);
227
+ confidence = confidence === 'high' ? 'high' : 'medium';
228
+ }
229
+ }
230
+ }
231
+ if (evidence.length === 0) {
232
+ return null;
233
+ }
234
+ return { agent: 'aider', confidence, evidence };
235
+ }
236
+ /**
237
+ * Detect Cline agent (VSCode extension)
238
+ * - cline extension in .vscode/extensions.json
239
+ * - .cline directory
240
+ */
241
+ async function detectCline(projectPath) {
242
+ const evidence = [];
243
+ let confidence = 'low';
244
+ // Check for .cline directory
245
+ if (await isDirectory(join(projectPath, '.cline'))) {
246
+ evidence.push('.cline directory found');
247
+ confidence = 'high';
248
+ }
249
+ // Check VSCode extensions
250
+ const extensions = await readVscodeExtensions(projectPath);
251
+ if (extensions) {
252
+ for (const ext of extensions) {
253
+ if (ext.includes('saoudrizwan.claude-dev') || ext.includes('cline')) {
254
+ evidence.push(`VSCode extension "${ext}" found`);
255
+ confidence = confidence === 'high' ? 'high' : 'medium';
256
+ }
257
+ }
258
+ }
259
+ if (evidence.length === 0) {
260
+ return null;
261
+ }
262
+ return { agent: 'cline', confidence, evidence };
263
+ }
264
+ /**
265
+ * Detect Continue agent (VSCode extension)
266
+ * - continue extension in .vscode/extensions.json
267
+ * - .continue directory
268
+ * - continue.config.json / config.yaml
269
+ */
270
+ async function detectContinue(projectPath) {
271
+ const evidence = [];
272
+ let confidence = 'low';
273
+ // Check for .continue directory
274
+ if (await isDirectory(join(projectPath, '.continue'))) {
275
+ evidence.push('.continue directory found');
276
+ confidence = 'high';
277
+ }
278
+ // Check for continue config files
279
+ if (await exists(join(projectPath, 'continue.config.json'))) {
280
+ evidence.push('continue.config.json found');
281
+ confidence = confidence === 'high' ? 'high' : 'medium';
282
+ }
283
+ if (await exists(join(projectPath, '.continue', 'config.yaml'))) {
284
+ evidence.push('.continue/config.yaml found');
285
+ confidence = confidence === 'high' ? 'high' : 'medium';
286
+ }
287
+ // Check VSCode extensions
288
+ const extensions = await readVscodeExtensions(projectPath);
289
+ if (extensions) {
290
+ for (const ext of extensions) {
291
+ if (ext.includes('continue.continue') || ext.includes('Continue')) {
292
+ evidence.push(`VSCode extension "${ext}" found`);
293
+ confidence = confidence === 'high' ? 'high' : 'medium';
294
+ }
295
+ }
296
+ }
297
+ if (evidence.length === 0) {
298
+ return null;
299
+ }
300
+ return { agent: 'continue', confidence, evidence };
301
+ }
302
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Config YAML Generator
3
+ *
4
+ * Generates the .tankgate/config.yaml configuration file.
5
+ */
6
+ import type { InitOptions } from '../types';
7
+ export declare function generateConfigYaml(options: InitOptions): string;
8
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/generators/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAkD/D"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Config YAML Generator
3
+ *
4
+ * Generates the .tankgate/config.yaml configuration file.
5
+ */
6
+ export function generateConfigYaml(options) {
7
+ const { agent, mode, profile, approval } = options;
8
+ return `# TankGate Configuration
9
+ # Generated by tankgate init
10
+ # Documentation: https://tankgate.dev/docs/configuration
11
+
12
+ # Agent configuration
13
+ agent:
14
+ # The AI agent being secured
15
+ type: ${agent}
16
+ # Security mode: contained (Docker isolation) or convenience (host)
17
+ mode: ${mode}
18
+
19
+ # Scanner configuration
20
+ scanner:
21
+ # Profile: fast (regex only), standard (regex + ML), paranoid (always ML)
22
+ profile: ${profile}
23
+ # Timeout for ML scanner requests (ms)
24
+ timeout: 5000
25
+ # Backend: builtin, llm-guard, lakera
26
+ backend: builtin
27
+ # ${profile === 'paranoid' ? 'Endpoint for external scanner (when using llm-guard backend)' : '# Endpoint for external scanner (when using llm-guard backend)'}
28
+ # endpoint: http://scanner:8080
29
+
30
+ # Approval channel configuration
31
+ approval:
32
+ # Channel: none (block dangerous actions) or telegram (mobile approval)
33
+ channel: ${approval}
34
+ # Timeout for approval requests (seconds)
35
+ timeout: 300
36
+ ${approval === 'telegram' ? `
37
+ # Telegram configuration (set in .env)
38
+ # TELEGRAM_BOT_TOKEN - Bot token from @BotFather
39
+ # TELEGRAM_CHAT_ID - Your chat ID from @userinfobot` : '# Telegram not configured'}
40
+
41
+ # Logging configuration
42
+ logging:
43
+ # Level: debug, info, warn, error
44
+ level: info
45
+ # Format: json, pretty
46
+ format: pretty
47
+
48
+ # Audit configuration
49
+ audit:
50
+ # Path to audit database
51
+ db: ./audit.db
52
+ # Enable HMAC chain for tamper-evidence
53
+ chain: true
54
+ `;
55
+ }
56
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/generators/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,UAAU,kBAAkB,CAAC,OAAoB;IACrD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAEnD,OAAO;;;;;;;UAOC,KAAK;;UAEL,IAAI;;;;;aAKD,OAAO;;;;;MAKd,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,8DAA8D,CAAC,CAAC,CAAC,gEAAgE;;;;;;aAMnJ,QAAQ;;;IAGjB,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC;;;sDAGwB,CAAC,CAAC,CAAC,2BAA2B;;;;;;;;;;;;;;;CAenF,CAAC;AACF,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Docker Compose Generator
3
+ *
4
+ * Generates a docker-compose.tankgate.yml file based on init options.
5
+ * Supports contained mode with network isolation and scanner services.
6
+ */
7
+ import type { AgentType } from '../types';
8
+ /**
9
+ * Default Docker images - can be overridden via environment variables
10
+ */
11
+ declare const DOCKER_IMAGES: {
12
+ tankgate: string;
13
+ openclaw: string;
14
+ scanner: string;
15
+ };
16
+ export interface DockerComposeOptions {
17
+ agent: AgentType;
18
+ mode: 'contained' | 'convenience';
19
+ profile: 'fast' | 'standard' | 'paranoid';
20
+ approval: 'telegram' | 'none';
21
+ images?: {
22
+ tankgate?: string;
23
+ openclaw?: string;
24
+ scanner?: string;
25
+ };
26
+ }
27
+ /**
28
+ * Generate a docker-compose.tankgate.yml file
29
+ */
30
+ export declare function generateDockerCompose(options: DockerComposeOptions): string;
31
+ /**
32
+ * Get docker-compose filename for a given mode
33
+ */
34
+ export declare function getComposeFilename(_options: DockerComposeOptions): string;
35
+ /**
36
+ * Get default Docker images (for documentation/testing)
37
+ */
38
+ export declare function getDefaultImages(): typeof DOCKER_IMAGES;
39
+ export {};
40
+ //# sourceMappingURL=docker-compose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-compose.d.ts","sourceRoot":"","sources":["../../src/generators/docker-compose.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;GAEG;AACH,QAAA,MAAM,aAAa;;;;CAIlB,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,WAAW,GAAG,aAAa,CAAC;IAClC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IAC1C,QAAQ,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AA2BD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CA0C3E;AA0FD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,CAEzE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,aAAa,CAEvD"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Docker Compose Generator
3
+ *
4
+ * Generates a docker-compose.tankgate.yml file based on init options.
5
+ * Supports contained mode with network isolation and scanner services.
6
+ */
7
+ import { stringify } from 'yaml';
8
+ /**
9
+ * Default Docker images - can be overridden via environment variables
10
+ */
11
+ const DOCKER_IMAGES = {
12
+ tankgate: process.env.TANKGATE_IMAGE || 'ghcr.io/tankpkg/tankgate:latest',
13
+ openclaw: process.env.TANKGATE_OPENCLAW_IMAGE || 'minimus/openclaw:latest',
14
+ scanner: process.env.TANKGATE_SCANNER_IMAGE || 'protectai/llm-guard:latest',
15
+ };
16
+ /**
17
+ * Generate a docker-compose.tankgate.yml file
18
+ */
19
+ export function generateDockerCompose(options) {
20
+ const compose = {
21
+ services: {},
22
+ };
23
+ // Add networks for contained mode
24
+ if (options.mode === 'contained') {
25
+ compose.networks = {
26
+ internal: { internal: true },
27
+ external: {},
28
+ };
29
+ }
30
+ // TankGate proxy service (always present)
31
+ compose.services.tankgate = generateTankgateService(options);
32
+ // Add OpenClaw service in contained mode
33
+ if (options.mode === 'contained' && options.agent === 'openclaw') {
34
+ compose.services.openclaw = generateOpenclawService(options);
35
+ }
36
+ // Add scanner service for paranoid profile
37
+ if (options.profile === 'paranoid') {
38
+ compose.services.scanner = generateScannerService(options);
39
+ }
40
+ // Convert to YAML with header comment
41
+ const header = `# TankGate Docker Compose Configuration
42
+ # Generated by tankgate init
43
+ #
44
+ # Images (can be overridden via environment variables):
45
+ # TANKGATE_IMAGE=${DOCKER_IMAGES.tankgate}
46
+ # TANKGATE_OPENCLAW_IMAGE=${DOCKER_IMAGES.openclaw}
47
+ # TANKGATE_SCANNER_IMAGE=${DOCKER_IMAGES.scanner}
48
+ #
49
+ # Usage:
50
+ # docker compose -f docker-compose.tankgate.yml up -d
51
+ # docker compose -f docker-compose.tankgate.yml down
52
+ #
53
+ `;
54
+ return header + stringify(compose, { lineWidth: 0 });
55
+ }
56
+ /**
57
+ * Generate the main TankGate proxy service
58
+ */
59
+ function generateTankgateService(options) {
60
+ const image = options.images?.tankgate || DOCKER_IMAGES.tankgate;
61
+ const environment = {
62
+ OPENAI_API_KEY: '${OPENAI_API_KEY}',
63
+ TANKGATE_SCANNER_PROFILE: options.profile,
64
+ TANKGATE_AUDIT_DB: '/data/audit.db',
65
+ ANTHROPIC_API_KEY: '${ANTHROPIC_API_KEY:-}',
66
+ };
67
+ // Add Telegram configuration for approval channel
68
+ if (options.approval === 'telegram') {
69
+ environment['TELEGRAM_BOT_TOKEN'] = '${TELEGRAM_BOT_TOKEN:-}';
70
+ environment['TELEGRAM_CHAT_ID'] = '${TELEGRAM_CHAT_ID:-}';
71
+ }
72
+ // Add scanner endpoint for paranoid profile
73
+ if (options.profile === 'paranoid') {
74
+ environment['TANKGATE_SCANNER_ENDPOINT'] = 'http://scanner:8080';
75
+ }
76
+ const service = {
77
+ image,
78
+ container_name: 'tankgate',
79
+ environment,
80
+ volumes: [
81
+ './.tankgate:/etc/tankgate:ro',
82
+ './:/workspace:rw',
83
+ 'tankgate-data:/data',
84
+ ],
85
+ ports: ['8080:8080'],
86
+ restart: 'unless-stopped',
87
+ };
88
+ // Network configuration for contained mode
89
+ if (options.mode === 'contained') {
90
+ service.networks = ['internal', 'external'];
91
+ }
92
+ // Add dependency on scanner for paranoid profile
93
+ if (options.profile === 'paranoid') {
94
+ service.depends_on = ['scanner'];
95
+ }
96
+ return service;
97
+ }
98
+ /**
99
+ * Generate OpenClaw agent service (contained mode only)
100
+ */
101
+ function generateOpenclawService(options) {
102
+ const image = options.images?.openclaw || DOCKER_IMAGES.openclaw;
103
+ return {
104
+ image,
105
+ container_name: 'openclaw',
106
+ environment: {
107
+ // Route through TankGate proxy
108
+ OPENAI_BASE_URL: 'http://tankgate:8080/v1',
109
+ ANTHROPIC_BASE_URL: 'http://tankgate:8080/v1',
110
+ },
111
+ volumes: [
112
+ './:/workspace:rw',
113
+ ],
114
+ networks: ['internal'],
115
+ depends_on: ['tankgate'],
116
+ restart: 'unless-stopped',
117
+ };
118
+ }
119
+ /**
120
+ * Generate LLM Guard scanner service (paranoid profile only)
121
+ */
122
+ function generateScannerService(options) {
123
+ const image = options.images?.scanner || DOCKER_IMAGES.scanner;
124
+ return {
125
+ image,
126
+ container_name: 'tankgate-scanner',
127
+ ports: ['8081:8080'],
128
+ networks: ['internal'],
129
+ restart: 'unless-stopped',
130
+ };
131
+ }
132
+ /**
133
+ * Get docker-compose filename for a given mode
134
+ */
135
+ export function getComposeFilename(_options) {
136
+ return 'docker-compose.tankgate.yml';
137
+ }
138
+ /**
139
+ * Get default Docker images (for documentation/testing)
140
+ */
141
+ export function getDefaultImages() {
142
+ return { ...DOCKER_IMAGES };
143
+ }
144
+ //# sourceMappingURL=docker-compose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-compose.js","sourceRoot":"","sources":["../../src/generators/docker-compose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Environment File Generator
3
+ *
4
+ * Generates the .env.example file with all required environment variables.
5
+ */
6
+ import type { InitOptions } from '../types';
7
+ export declare function generateEnvExample(options: InitOptions): string;
8
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/generators/env.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAwE/D"}