@agntk/cli 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.
package/dist/args.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @fileoverview CLI argument parsing for agntk.
3
+ * Lightweight hand-rolled parser — keeps dependencies at zero.
4
+ */
5
+ export interface ParsedArgs {
6
+ /** The prompt text (positional argument) */
7
+ prompt: string | null;
8
+ /** -i / --interactive */
9
+ interactive: boolean;
10
+ /** -r / --role <role> */
11
+ role: string | null;
12
+ /** -m / --model <model> */
13
+ model: string | null;
14
+ /** --memory */
15
+ memory: boolean;
16
+ /** --init */
17
+ init: boolean;
18
+ /** --tools <preset> */
19
+ tools: string | null;
20
+ /** --workspace <path> */
21
+ workspace: string | null;
22
+ /** --dry-run */
23
+ dryRun: boolean;
24
+ /** --verbose */
25
+ verbose: boolean;
26
+ /** --config <path> */
27
+ config: string | null;
28
+ /** --max-steps <n> */
29
+ maxSteps: number | null;
30
+ /** -v / --version */
31
+ version: boolean;
32
+ /** -h / --help */
33
+ help: boolean;
34
+ }
35
+ /**
36
+ * Parse CLI arguments into a typed structure.
37
+ * Supports: flags, flags with values, and a positional prompt.
38
+ */
39
+ export declare function parseArgs(argv: string[]): ParsedArgs;
40
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,yBAAyB;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,yBAAyB;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,eAAe;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa;IACb,IAAI,EAAE,OAAO,CAAC;IACd,uBAAuB;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,yBAAyB;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,sBAAsB;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,qBAAqB;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB;IAClB,IAAI,EAAE,OAAO,CAAC;CACf;AAWD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA+DpD"}
package/dist/args.js ADDED
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @fileoverview CLI argument parsing for agntk.
3
+ * Lightweight hand-rolled parser — keeps dependencies at zero.
4
+ */
5
+ const FLAGS_WITH_VALUES = new Set([
6
+ '-r', '--role',
7
+ '-m', '--model',
8
+ '--tools',
9
+ '--workspace',
10
+ '--config',
11
+ '--max-steps',
12
+ ]);
13
+ /**
14
+ * Parse CLI arguments into a typed structure.
15
+ * Supports: flags, flags with values, and a positional prompt.
16
+ */
17
+ export function parseArgs(argv) {
18
+ const result = {
19
+ prompt: null,
20
+ interactive: false,
21
+ role: null,
22
+ model: null,
23
+ memory: false,
24
+ init: false,
25
+ tools: null,
26
+ workspace: null,
27
+ dryRun: false,
28
+ verbose: false,
29
+ config: null,
30
+ maxSteps: null,
31
+ version: false,
32
+ help: false,
33
+ };
34
+ const positionals = [];
35
+ for (let i = 0; i < argv.length; i++) {
36
+ const arg = argv[i];
37
+ if (arg === '-i' || arg === '--interactive') {
38
+ result.interactive = true;
39
+ }
40
+ else if (arg === '-r' || arg === '--role') {
41
+ result.role = argv[++i] ?? null;
42
+ }
43
+ else if (arg === '-m' || arg === '--model') {
44
+ result.model = argv[++i] ?? null;
45
+ }
46
+ else if (arg === '--memory') {
47
+ result.memory = true;
48
+ }
49
+ else if (arg === '--init') {
50
+ result.init = true;
51
+ }
52
+ else if (arg === '--tools') {
53
+ result.tools = argv[++i] ?? null;
54
+ }
55
+ else if (arg === '--workspace') {
56
+ result.workspace = argv[++i] ?? null;
57
+ }
58
+ else if (arg === '--dry-run') {
59
+ result.dryRun = true;
60
+ }
61
+ else if (arg === '--verbose') {
62
+ result.verbose = true;
63
+ }
64
+ else if (arg === '--config') {
65
+ result.config = argv[++i] ?? null;
66
+ }
67
+ else if (arg === '--max-steps') {
68
+ const val = argv[++i];
69
+ result.maxSteps = val ? parseInt(val, 10) : null;
70
+ }
71
+ else if (arg === '-v' || arg === '--version') {
72
+ result.version = true;
73
+ }
74
+ else if (arg === '-h' || arg === '--help') {
75
+ result.help = true;
76
+ }
77
+ else if (arg.startsWith('-')) {
78
+ // Unknown flag — ignore for forward compatibility
79
+ }
80
+ else {
81
+ positionals.push(arg);
82
+ }
83
+ }
84
+ // Join all positionals as the prompt
85
+ if (positionals.length > 0) {
86
+ result.prompt = positionals.join(' ');
87
+ }
88
+ return result;
89
+ }
90
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview CLI entry point for agntk.
4
+ *
5
+ * Usage:
6
+ * npx agntk "do something"
7
+ * npx agntk --role coder "fix the tests"
8
+ * npx agntk -i --memory
9
+ * cat error.log | npx agntk "explain these errors"
10
+ */
11
+ import 'dotenv/config';
12
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AAGH,OAAO,eAAe,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview CLI entry point for agntk.
4
+ *
5
+ * Usage:
6
+ * npx agntk "do something"
7
+ * npx agntk --role coder "fix the tests"
8
+ * npx agntk -i --memory
9
+ * cat error.log | npx agntk "explain these errors"
10
+ */
11
+ // Load .env files before anything else reads process.env
12
+ import 'dotenv/config';
13
+ import { getVersion } from './version.js';
14
+ import { parseArgs } from './args.js';
15
+ import { resolveConfig } from './config.js';
16
+ // Note: environment.js and runner.js are dynamically imported below
17
+ // to avoid loading @agntk/core for --version and --help (fast paths)
18
+ // ============================================================================
19
+ // Help Text
20
+ // ============================================================================
21
+ function printHelp() {
22
+ const version = getVersion();
23
+ console.log(`
24
+ agntk v${version} — portable AI agent
25
+
26
+ Usage:
27
+ agntk [options] [prompt]
28
+
29
+ Options:
30
+ -i, --interactive Interactive REPL mode
31
+ -r, --role <role> Agent role (coder, researcher, analyst, generic)
32
+ -m, --model <model> Model to use (provider:model format)
33
+ --memory Enable persistent memory
34
+ --init Initialize .agntk/ directory with templates
35
+ --tools <preset> Tool preset (minimal, standard, full)
36
+ --workspace <path> Workspace root (default: cwd)
37
+ --dry-run Preview actions without executing
38
+ --verbose Show detailed logging
39
+ --config <path> Config file path
40
+ --max-steps <n> Maximum agent steps
41
+ -v, --version Show version
42
+ -h, --help Show help
43
+
44
+ Examples:
45
+ agntk "organize this folder by date"
46
+ agntk -i --memory
47
+ agntk --role coder "fix the failing tests"
48
+ cat error.log | agntk "explain these errors"
49
+ `);
50
+ }
51
+ // ============================================================================
52
+ // Main
53
+ // ============================================================================
54
+ async function main() {
55
+ const args = parseArgs(process.argv.slice(2));
56
+ // Handle --version
57
+ if (args.version) {
58
+ console.log(`agntk v${getVersion()}`);
59
+ process.exit(0);
60
+ }
61
+ // Handle --help
62
+ if (args.help) {
63
+ printHelp();
64
+ process.exit(0);
65
+ }
66
+ // Resolve configuration
67
+ const config = resolveConfig(args);
68
+ // Handle --init: create .agntk/ directory with template files
69
+ if (config.init) {
70
+ const { initMemoryDirectory } = await import('./init.js');
71
+ await initMemoryDirectory(config.workspace);
72
+ process.exit(0);
73
+ }
74
+ // Handle interactive mode
75
+ if (config.interactive) {
76
+ const { detectEnvironment } = await import('./environment.js');
77
+ const { runRepl } = await import('./repl.js');
78
+ const environment = detectEnvironment(config.workspace);
79
+ const result = await runRepl({ config, environment });
80
+ process.exit(result.success ? 0 : 1);
81
+ }
82
+ // Quick "no prompt" check before loading heavy modules
83
+ // If stdin is a TTY and no prompt was given, bail early
84
+ if (!config.prompt && process.stdin.isTTY) {
85
+ console.error('Error: No prompt provided.\n' +
86
+ 'Usage: agntk "your prompt here"\n' +
87
+ ' agntk -i (for interactive mode)\n' +
88
+ ' agntk -h (for help)');
89
+ process.exit(1);
90
+ }
91
+ // ── Lazy-load heavy modules (only when actually running an agent) ────
92
+ const { detectEnvironment } = await import('./environment.js');
93
+ const { runOneShot, readStdin } = await import('./runner.js');
94
+ // Build final prompt, combining piped input if available
95
+ let prompt = config.prompt;
96
+ const pipedInput = await readStdin();
97
+ if (pipedInput) {
98
+ if (prompt) {
99
+ prompt = `${pipedInput}\n\n${prompt}`;
100
+ }
101
+ else {
102
+ prompt = pipedInput;
103
+ }
104
+ }
105
+ if (!prompt) {
106
+ console.error('Error: No prompt provided.\n' +
107
+ 'Usage: agntk "your prompt here"\n' +
108
+ ' agntk -i (for interactive mode)\n' +
109
+ ' agntk -h (for help)');
110
+ process.exit(1);
111
+ }
112
+ // Detect environment
113
+ const environment = detectEnvironment(config.workspace);
114
+ // Run the agent
115
+ const result = await runOneShot(prompt, { config, environment });
116
+ if (!result.success) {
117
+ console.error(`Error: ${result.error}`);
118
+ process.exit(1);
119
+ }
120
+ process.exit(0);
121
+ }
122
+ main().catch((err) => {
123
+ console.error('Fatal error:', err instanceof Error ? err.message : String(err));
124
+ process.exit(1);
125
+ });
126
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @fileoverview Config resolution for agntk CLI.
3
+ * Precedence: CLI flags > env vars > config file > defaults.
4
+ */
5
+ import type { ParsedArgs } from './args.js';
6
+ export interface ResolvedCLIConfig {
7
+ /** The prompt text to send to the agent */
8
+ prompt: string | null;
9
+ /** Whether to enter interactive REPL mode */
10
+ interactive: boolean;
11
+ /** Agent role */
12
+ role: string;
13
+ /** Model identifier (provider:model format) */
14
+ model: string | null;
15
+ /** Provider extracted from model or env vars */
16
+ provider: string | null;
17
+ /** API key for the resolved provider */
18
+ apiKey: string | null;
19
+ /** Enable persistent memory */
20
+ memory: boolean;
21
+ /** Run init wizard */
22
+ init: boolean;
23
+ /** Tool preset */
24
+ toolPreset: string;
25
+ /** Workspace root directory */
26
+ workspace: string;
27
+ /** Dry run mode */
28
+ dryRun: boolean;
29
+ /** Verbose logging */
30
+ verbose: boolean;
31
+ /** Max agent steps */
32
+ maxSteps: number;
33
+ /** Path to config file */
34
+ configPath: string | null;
35
+ }
36
+ interface ApiKeyResult {
37
+ provider: string;
38
+ apiKey: string;
39
+ }
40
+ /**
41
+ * Detect API key from environment variables.
42
+ * Returns the first found key with its provider.
43
+ */
44
+ export declare function detectApiKey(): ApiKeyResult | null;
45
+ interface ConfigFileData {
46
+ role?: string;
47
+ model?: string;
48
+ memory?: boolean;
49
+ tools?: string;
50
+ maxSteps?: number;
51
+ workspace?: string;
52
+ }
53
+ /**
54
+ * Load config file from the workspace directory.
55
+ * Tries multiple filenames, returns first found.
56
+ */
57
+ export declare function loadConfigFile(workspace: string, explicitPath?: string | null): ConfigFileData;
58
+ /**
59
+ * Resolve final config from CLI args, env vars, config file, and defaults.
60
+ */
61
+ export declare function resolveConfig(args: ParsedArgs): ResolvedCLIConfig;
62
+ export {};
63
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,6CAA6C;IAC7C,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,wCAAwC;IACxC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+BAA+B;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,sBAAsB;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,sBAAsB;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAMD,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAOD;;;GAGG;AACH,wBAAgB,YAAY,IAAI,YAAY,GAAG,IAAI,CAQlD;AAMD,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAOD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CA0B9F;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,iBAAiB,CAmCjE"}
package/dist/config.js ADDED
@@ -0,0 +1,96 @@
1
+ /**
2
+ * @fileoverview Config resolution for agntk CLI.
3
+ * Precedence: CLI flags > env vars > config file > defaults.
4
+ */
5
+ import { existsSync, readFileSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ const API_KEY_ENV_VARS = [
8
+ { env: 'OPENROUTER_API_KEY', provider: 'openrouter' },
9
+ { env: 'OPENAI_API_KEY', provider: 'openai' },
10
+ ];
11
+ /**
12
+ * Detect API key from environment variables.
13
+ * Returns the first found key with its provider.
14
+ */
15
+ export function detectApiKey() {
16
+ for (const { env, provider } of API_KEY_ENV_VARS) {
17
+ const key = process.env[env];
18
+ if (key && key.trim().length > 0) {
19
+ return { provider, apiKey: key };
20
+ }
21
+ }
22
+ return null;
23
+ }
24
+ const CONFIG_FILENAMES = [
25
+ 'agent-sdk.config.json',
26
+ '.agntkrc.json',
27
+ ];
28
+ /**
29
+ * Load config file from the workspace directory.
30
+ * Tries multiple filenames, returns first found.
31
+ */
32
+ export function loadConfigFile(workspace, explicitPath) {
33
+ if (explicitPath) {
34
+ if (!existsSync(explicitPath)) {
35
+ return {};
36
+ }
37
+ try {
38
+ const content = readFileSync(explicitPath, 'utf-8');
39
+ return JSON.parse(content);
40
+ }
41
+ catch {
42
+ return {};
43
+ }
44
+ }
45
+ for (const filename of CONFIG_FILENAMES) {
46
+ const filePath = join(workspace, filename);
47
+ if (existsSync(filePath)) {
48
+ try {
49
+ const content = readFileSync(filePath, 'utf-8');
50
+ return JSON.parse(content);
51
+ }
52
+ catch {
53
+ // Silently skip unparseable files
54
+ }
55
+ }
56
+ }
57
+ return {};
58
+ }
59
+ // ============================================================================
60
+ // Config Resolution
61
+ // ============================================================================
62
+ /**
63
+ * Resolve final config from CLI args, env vars, config file, and defaults.
64
+ */
65
+ export function resolveConfig(args) {
66
+ const workspace = args.workspace ?? process.cwd();
67
+ // Load config file (lowest precedence)
68
+ const fileConfig = loadConfigFile(workspace, args.config);
69
+ // Detect API key from env
70
+ const apiKeyResult = detectApiKey();
71
+ // Parse model string (e.g., "openrouter:anthropic/claude-sonnet-4")
72
+ let provider = apiKeyResult?.provider ?? null;
73
+ let model = args.model ?? fileConfig.model ?? null;
74
+ if (model && model.includes(':')) {
75
+ const [p, ...rest] = model.split(':');
76
+ provider = p;
77
+ model = rest.join(':');
78
+ }
79
+ return {
80
+ prompt: args.prompt,
81
+ interactive: args.interactive,
82
+ role: args.role ?? fileConfig.role ?? 'generic',
83
+ model,
84
+ provider,
85
+ apiKey: apiKeyResult?.apiKey ?? null,
86
+ memory: args.memory || (fileConfig.memory ?? false),
87
+ init: args.init,
88
+ toolPreset: args.tools ?? fileConfig.tools ?? 'standard',
89
+ workspace,
90
+ dryRun: args.dryRun,
91
+ verbose: args.verbose,
92
+ maxSteps: args.maxSteps ?? fileConfig.maxSteps ?? 10,
93
+ configPath: args.config,
94
+ };
95
+ }
96
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @fileoverview Environment detection for agntk.
3
+ * Detects OS, shell, project type, git repo, available commands, TTY, CI, etc.
4
+ * This is the "invisible awareness" from PLAN.md Section 3.3.
5
+ */
6
+ export interface EnvironmentContext {
7
+ /** Operating system */
8
+ os: 'macos' | 'linux' | 'windows' | 'unknown';
9
+ /** Shell type */
10
+ shell: string;
11
+ /** Detected project type from manifest files */
12
+ projectType: string | null;
13
+ /** Detected package manager */
14
+ packageManager: string | null;
15
+ /** Whether cwd is inside a git repository */
16
+ isGitRepo: boolean;
17
+ /** Whether stdout is a terminal (interactive) */
18
+ isTTY: boolean;
19
+ /** Whether running in a CI environment */
20
+ isCI: boolean;
21
+ /** Whether running inside Docker */
22
+ isDocker: boolean;
23
+ /** Node.js version */
24
+ nodeVersion: string;
25
+ /** List of commonly useful commands that are available */
26
+ availableCommands: string[];
27
+ }
28
+ /**
29
+ * Detect the current environment context.
30
+ * All detection is synchronous and fast (<500ms typical).
31
+ */
32
+ export declare function detectEnvironment(workspace?: string): EnvironmentContext;
33
+ /**
34
+ * Format environment context as a string to inject into the agent's system prompt.
35
+ */
36
+ export declare function formatEnvironmentPrompt(ctx: EnvironmentContext): string;
37
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,WAAW,kBAAkB;IACjC,uBAAuB;IACvB,EAAE,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9C,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+BAA+B;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,KAAK,EAAE,OAAO,CAAC;IACf,0CAA0C;IAC1C,IAAI,EAAE,OAAO,CAAC;IACd,oCAAoC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,sBAAsB;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AA8HD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,MAAsB,GAAG,kBAAkB,CAavF;AAMD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CA4BvE"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * @fileoverview Environment detection for agntk.
3
+ * Detects OS, shell, project type, git repo, available commands, TTY, CI, etc.
4
+ * This is the "invisible awareness" from PLAN.md Section 3.3.
5
+ */
6
+ import { existsSync } from 'node:fs';
7
+ import { execSync } from 'node:child_process';
8
+ import { join } from 'node:path';
9
+ // ============================================================================
10
+ // Detection Functions
11
+ // ============================================================================
12
+ function detectOS() {
13
+ switch (process.platform) {
14
+ case 'darwin': return 'macos';
15
+ case 'linux': return 'linux';
16
+ case 'win32': return 'windows';
17
+ default: return 'unknown';
18
+ }
19
+ }
20
+ function detectShell() {
21
+ // Check SHELL env var (Unix)
22
+ const shellEnv = process.env['SHELL'];
23
+ if (shellEnv) {
24
+ const shellName = shellEnv.split('/').pop();
25
+ if (shellName)
26
+ return shellName;
27
+ }
28
+ // Check ComSpec (Windows)
29
+ const comspec = process.env['ComSpec'];
30
+ if (comspec) {
31
+ if (comspec.toLowerCase().includes('powershell'))
32
+ return 'powershell';
33
+ if (comspec.toLowerCase().includes('cmd'))
34
+ return 'cmd';
35
+ }
36
+ // Fallback
37
+ return process.platform === 'win32' ? 'cmd' : 'sh';
38
+ }
39
+ const MANIFEST_FILES = [
40
+ { file: 'package.json', type: 'node' },
41
+ { file: 'Cargo.toml', type: 'rust' },
42
+ { file: 'pyproject.toml', type: 'python' },
43
+ { file: 'go.mod', type: 'go' },
44
+ { file: 'Gemfile', type: 'ruby' },
45
+ { file: 'build.gradle', type: 'java' },
46
+ { file: 'pom.xml', type: 'java' },
47
+ { file: 'composer.json', type: 'php' },
48
+ { file: 'mix.exs', type: 'elixir' },
49
+ { file: 'Makefile', type: 'make' },
50
+ ];
51
+ function detectProjectType(workspace) {
52
+ for (const { file, type } of MANIFEST_FILES) {
53
+ if (existsSync(join(workspace, file))) {
54
+ return type;
55
+ }
56
+ }
57
+ return null;
58
+ }
59
+ const LOCKFILE_TO_PM = [
60
+ { file: 'pnpm-lock.yaml', pm: 'pnpm' },
61
+ { file: 'bun.lockb', pm: 'bun' },
62
+ { file: 'yarn.lock', pm: 'yarn' },
63
+ { file: 'package-lock.json', pm: 'npm' },
64
+ ];
65
+ function detectPackageManager(workspace) {
66
+ for (const { file, pm } of LOCKFILE_TO_PM) {
67
+ if (existsSync(join(workspace, file))) {
68
+ return pm;
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ function detectGitRepo(workspace) {
74
+ return existsSync(join(workspace, '.git'));
75
+ }
76
+ function detectCI() {
77
+ return !!(process.env['CI'] ||
78
+ process.env['GITHUB_ACTIONS'] ||
79
+ process.env['GITLAB_CI'] ||
80
+ process.env['CIRCLECI'] ||
81
+ process.env['JENKINS_URL'] ||
82
+ process.env['BUILDKITE'] ||
83
+ process.env['TRAVIS']);
84
+ }
85
+ function detectDocker() {
86
+ if (existsSync('/.dockerenv'))
87
+ return true;
88
+ try {
89
+ const cgroup = execSync('cat /proc/1/cgroup 2>/dev/null', { encoding: 'utf-8', timeout: 1000 });
90
+ return cgroup.includes('docker') || cgroup.includes('containerd');
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ }
96
+ const USEFUL_COMMANDS = ['git', 'node', 'npm', 'pnpm', 'bun', 'python3', 'pip3', 'docker', 'curl', 'jq', 'at', 'crontab'];
97
+ function detectAvailableCommands() {
98
+ const available = [];
99
+ const whichCmd = process.platform === 'win32' ? 'where' : 'which';
100
+ for (const cmd of USEFUL_COMMANDS) {
101
+ try {
102
+ execSync(`${whichCmd} ${cmd} 2>/dev/null`, { encoding: 'utf-8', timeout: 2000 });
103
+ available.push(cmd);
104
+ }
105
+ catch {
106
+ // Not available
107
+ }
108
+ }
109
+ return available;
110
+ }
111
+ // ============================================================================
112
+ // Main Detection
113
+ // ============================================================================
114
+ /**
115
+ * Detect the current environment context.
116
+ * All detection is synchronous and fast (<500ms typical).
117
+ */
118
+ export function detectEnvironment(workspace = process.cwd()) {
119
+ return {
120
+ os: detectOS(),
121
+ shell: detectShell(),
122
+ projectType: detectProjectType(workspace),
123
+ packageManager: detectPackageManager(workspace),
124
+ isGitRepo: detectGitRepo(workspace),
125
+ isTTY: !!process.stdout.isTTY,
126
+ isCI: detectCI(),
127
+ isDocker: detectDocker(),
128
+ nodeVersion: process.version,
129
+ availableCommands: detectAvailableCommands(),
130
+ };
131
+ }
132
+ // ============================================================================
133
+ // System Prompt Formatting
134
+ // ============================================================================
135
+ /**
136
+ * Format environment context as a string to inject into the agent's system prompt.
137
+ */
138
+ export function formatEnvironmentPrompt(ctx) {
139
+ const lines = ['## Environment'];
140
+ lines.push(`- OS: ${ctx.os}`);
141
+ lines.push(`- Shell: ${ctx.shell}`);
142
+ lines.push(`- Node: ${ctx.nodeVersion}`);
143
+ lines.push(`- Terminal: ${ctx.isTTY ? 'interactive' : 'non-interactive (piped)'}`);
144
+ if (ctx.projectType) {
145
+ lines.push(`- Project type: ${ctx.projectType}`);
146
+ }
147
+ if (ctx.packageManager) {
148
+ lines.push(`- Package manager: ${ctx.packageManager}`);
149
+ }
150
+ if (ctx.isGitRepo) {
151
+ lines.push(`- Git repository: yes`);
152
+ }
153
+ if (ctx.isCI) {
154
+ lines.push(`- Running in CI`);
155
+ }
156
+ if (ctx.isDocker) {
157
+ lines.push(`- Running in Docker`);
158
+ }
159
+ if (ctx.availableCommands.length > 0) {
160
+ lines.push(`- Available commands: ${ctx.availableCommands.join(', ')}`);
161
+ }
162
+ return lines.join('\n');
163
+ }
164
+ //# sourceMappingURL=environment.js.map