@trygentic/agentloop 0.1.1-alpha.3 → 0.4.0-alpha.5

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  **Commercial License Agreement**
2
2
  Software: AgentLoop
3
- Copyright © Troy Edwards Jr, All Rights Reserved
3
+ Copyright © Trygentic, Inc., All Rights Reserved
4
4
 
5
5
  This Software is licensed, not sold.
6
6
 
package/README.md CHANGED
@@ -44,6 +44,20 @@ npm install @trygentic/agentloop
44
44
  npx @trygentic/agentloop
45
45
  ```
46
46
 
47
+ ### Development Setup
48
+
49
+ ```bash
50
+ # Clone with submodule
51
+ git clone --recursive https://github.com/trygentic/agentloop
52
+
53
+ # Or if already cloned
54
+ git submodule update --init --recursive
55
+
56
+ # Install and build
57
+ npm install
58
+ npm run build
59
+ ```
60
+
47
61
  ## Quick Start
48
62
 
49
63
  ```bash
@@ -418,33 +432,33 @@ The AgentLoop daemon allows you to run the orchestrator as a persistent backgrou
418
432
 
419
433
  ## Configuration
420
434
 
421
- AgentLoop uses TOML configuration files with a layered priority system.
435
+ AgentLoop uses YAML configuration files with a layered priority system.
422
436
 
423
437
  ### Configuration File Locations
424
438
 
425
439
  | Location | Purpose |
426
440
  |----------|---------|
427
- | `./.agentloop/config.toml` | Project-level config (local overrides) |
428
- | `~/.config/agentloop/config.toml` | User-level config (global defaults) |
441
+ | `./.agentloop/config.yaml` | Project-level config (local overrides) |
442
+ | `~/.config/agentloop/config.yaml` | User-level config (global defaults) |
429
443
  | `~/.config/agentloop/` | Database, credentials, and cache |
430
444
 
431
445
  ### Configuration Priority (Highest to Lowest)
432
446
 
433
447
  1. Environment variables
434
- 2. Project config (`./.agentloop/config.toml`)
435
- 3. User config (`~/.config/agentloop/config.toml`)
448
+ 2. Project config (`./.agentloop/config.yaml`)
449
+ 3. User config (`~/.config/agentloop/config.yaml`)
436
450
  4. Default values
437
451
 
438
452
  ---
439
453
 
440
454
  ### Orchestrator Settings
441
455
 
442
- ```toml
443
- [orchestrator]
444
- max_parallel_agents = 1 # Number of agents that can run in parallel
445
- use_worktrees = false # Enable git worktrees for parallel development
446
- worktrees_dir = ".worktrees" # Directory for worktrees (relative to project)
447
- cleanup_worktrees_on_complete = false # Auto-cleanup worktrees after completion
456
+ ```yaml
457
+ orchestrator:
458
+ max_parallel_agents: 1 # Number of agents that can run in parallel
459
+ use_worktrees: false # Enable git worktrees for parallel development
460
+ worktrees_dir: ".worktrees" # Directory for worktrees (relative to project)
461
+ cleanup_worktrees_on_complete: false # Auto-cleanup worktrees after completion
448
462
  ```
449
463
 
450
464
  | Option | Default | Env Variable | Description |
@@ -458,19 +472,19 @@ cleanup_worktrees_on_complete = false # Auto-cleanup worktrees after completion
458
472
 
459
473
  ### Container Sandbox Settings
460
474
 
461
- ```toml
462
- [orchestrator.container_sandbox]
463
- enabled = false # Enable Podman sandboxing
464
- container_image = "agentloop-worker"
465
- network_mode = "slirp4netns" # none, slirp4netns, or host
466
- memory_limit = "4g"
467
- cpu_limit = "2"
468
-
469
- [orchestrator.container_sandbox.agent_images]
470
- engineer = "agentloop-worker"
471
- qa-tester = "agentloop-qa-worker"
472
- analyzer = "agentloop-worker"
473
- product-manager = "agentloop-worker"
475
+ ```yaml
476
+ orchestrator:
477
+ container_sandbox:
478
+ enabled: false # Enable Podman sandboxing
479
+ container_image: "agentloop-worker"
480
+ network_mode: "slirp4netns" # none, slirp4netns, or host
481
+ memory_limit: "4g"
482
+ cpu_limit: "2"
483
+ agent_images:
484
+ engineer: "agentloop-worker"
485
+ qa-tester: "agentloop-qa-worker"
486
+ analyzer: "agentloop-worker"
487
+ product-manager: "agentloop-worker"
474
488
  ```
475
489
 
476
490
  | Option | Default | Description |
@@ -485,10 +499,10 @@ product-manager = "agentloop-worker"
485
499
 
486
500
  ### GitHub Settings
487
501
 
488
- ```toml
489
- [github]
490
- enabled = true
491
- token = "ghp_your_token_here" # Or use GITHUB_PERSONAL_ACCESS_TOKEN env var
502
+ ```yaml
503
+ github:
504
+ enabled: true
505
+ token: "ghp_your_token_here" # Or use GITHUB_PERSONAL_ACCESS_TOKEN env var
492
506
  ```
493
507
 
494
508
  | Option | Default | Env Variable | Description |
@@ -500,19 +514,19 @@ token = "ghp_your_token_here" # Or use GITHUB_PERSONAL_ACCESS_TOKEN env var
500
514
 
501
515
  ### Jira Settings
502
516
 
503
- ```toml
504
- [jira]
505
- siteUrl = "https://yourcompany.atlassian.net"
506
- project = "PROJ"
507
- boardId = "123"
517
+ ```yaml
518
+ jira:
519
+ siteUrl: "https://yourcompany.atlassian.net"
520
+ project: "PROJ"
521
+ boardId: "123"
508
522
 
509
- # Basic Auth (simpler)
510
- email = "user@example.com"
511
- apiToken = "your_api_token"
523
+ # Basic Auth (simpler)
524
+ email: "user@example.com"
525
+ apiToken: "your_api_token"
512
526
 
513
- # Or OAuth (more secure) - set via /jira set-oauth command
514
- # clientId = "your_oauth_client_id"
515
- # clientSecret = "your_oauth_client_secret"
527
+ # Or OAuth (more secure) - set via /jira set-oauth command
528
+ # clientId: "your_oauth_client_id"
529
+ # clientSecret: "your_oauth_client_secret"
516
530
  ```
517
531
 
518
532
  | Option | Description |
@@ -527,29 +541,28 @@ apiToken = "your_api_token"
527
541
 
528
542
  ### Example Configuration
529
543
 
530
- **User-level defaults** (`~/.config/agentloop/config.toml`):
531
- ```toml
532
- [github]
533
- enabled = true
544
+ **User-level defaults** (`~/.config/agentloop/config.yaml`):
545
+ ```yaml
546
+ github:
547
+ enabled: true
534
548
 
535
- [orchestrator]
536
- max_parallel_agents = 4
537
- use_worktrees = true
549
+ orchestrator:
550
+ max_parallel_agents: 4
551
+ use_worktrees: true
538
552
  ```
539
553
 
540
- **Project-level overrides** (`./.agentloop/config.toml`):
541
- ```toml
542
- [orchestrator]
543
- max_parallel_agents = 10
544
-
545
- [orchestrator.container_sandbox]
546
- enabled = true
547
- network_mode = "slirp4netns"
548
-
549
- [jira]
550
- siteUrl = "https://company.atlassian.net"
551
- project = "MYPROJ"
552
- boardId = "42"
554
+ **Project-level overrides** (`./.agentloop/config.yaml`):
555
+ ```yaml
556
+ orchestrator:
557
+ max_parallel_agents: 10
558
+ container_sandbox:
559
+ enabled: true
560
+ network_mode: "slirp4netns"
561
+
562
+ jira:
563
+ siteUrl: "https://company.atlassian.net"
564
+ project: "MYPROJ"
565
+ boardId: "42"
553
566
  ```
554
567
 
555
568
  ---
@@ -595,6 +608,112 @@ agentloop config
595
608
  - npm or yarn
596
609
  - Podman (optional, for container sandboxing)
597
610
 
611
+ ## Architecture
612
+
613
+ AgentLoop uses [OpenCode](https://github.com/anthropics/opencode) as a git submodule for:
614
+
615
+ - **Tool System** (`@opencode/tool/`): Built-in tools (bash, read, write, edit, grep, glob, etc.)
616
+ - **LLM Abstraction** (`@opencode/session/llm`): Vercel AI SDK integration with streaming support
617
+ - **Provider Management** (`@opencode/provider/`): 18+ bundled AI SDK providers
618
+
619
+ ### Core Technologies
620
+
621
+ - **OCLIF**: CLI framework for command-line interface
622
+ - **OpenTUI**: Terminal UI framework (React-like components)
623
+ - **Better SQLite3**: Local database for state management
624
+ - **MCP (Model Context Protocol)**: Extensible tool system
625
+
626
+ ### Supported Providers
627
+
628
+ All providers supported by OpenCode (via Vercel AI SDK):
629
+ - **Anthropic** - Claude 4, Claude Sonnet, Claude Haiku
630
+ - **OpenAI** - GPT-4o, o1, o3
631
+ - **Google** - Gemini Pro, Gemini Flash
632
+ - **xAI** - Grok
633
+ - **DeepSeek** - DeepSeek Chat, DeepSeek Coder
634
+ - **OpenCode Zen** - Free tier for getting started
635
+ - And many more through OpenRouter
636
+
637
+
638
+ ## MCP Servers
639
+
640
+ AgentLoop integrates with various Model Context Protocol (MCP) servers to enhance agent capabilities:
641
+
642
+ ### Configured MCP Servers
643
+
644
+ | Server | Description | Tools |
645
+ |--------|-------------|-------|
646
+ | **serena** | Code editing and codebase traversal | File operations, symbol manipulation, code generation |
647
+ | **code-graph-rag** | Semantic code analysis with RAG | 24 tools for code search, similarity detection, impact analysis |
648
+ | **playwright** | Browser automation and testing | Web scraping, UI testing, interaction automation |
649
+ | **supabase** | Database operations | SQL execution, migrations, schema management |
650
+ | **mcp-atlassian** | Jira integration | Issue tracking, project management |
651
+ | **agentloop-debug** | Internal debugging tools | Task management, agent coordination |
652
+
653
+ ### Code Graph RAG MCP
654
+
655
+ The **code-graph-rag-mcp** server provides advanced semantic code analysis:
656
+
657
+ - **Semantic Search**: Find code by meaning, not just keywords
658
+ - **Code Similarity**: Detect duplicate code and similar patterns
659
+ - **Impact Analysis**: Assess the impact of potential changes
660
+ - **Performance**: 5.5x faster than traditional file-based search
661
+ - **Languages**: Supports TypeScript, JavaScript, Python, Java, Go, Rust, C++, C#, Ruby, PHP
662
+
663
+ **Requirements**: Node.js 18+, 2GB RAM minimum (8GB recommended)
664
+
665
+ For detailed information, see [docs/mcp/CODE_GRAPH_RAG_MCP.md](./docs/mcp/CODE_GRAPH_RAG_MCP.md)
666
+
667
+ ### Configuring MCP Servers
668
+
669
+ MCP servers are configured in `.mcp.json`:
670
+
671
+ ```json
672
+ {
673
+ "mcpServers": {
674
+ "code-graph-rag": {
675
+ "command": "npx",
676
+ "args": ["-y", "@er77/code-graph-rag-mcp", "/work"],
677
+ "env": {
678
+ "MCP_SEMANTIC_WARMUP_LIMIT": "1000"
679
+ }
680
+ }
681
+ }
682
+ }
683
+ ```
684
+
685
+ For more MCP integration examples, see [docs/mcp/GITHUB_MCP_INTEGRATION.md](./docs/mcp/GITHUB_MCP_INTEGRATION.md)
686
+
687
+
688
+
689
+ ## Templates
690
+
691
+ Built-in agent templates are distributed as part of the npm package in the `.claude/agents/` directory. When you install AgentLoop, these templates are automatically available and loaded by the agent system.
692
+
693
+ ## Migration Notes
694
+
695
+ This project recently migrated from a Single Executable Application (SEA) binary distribution to a standard npm package. See [docs/SEA_MIGRATION.md](./docs/SEA_MIGRATION.md) for details about the changes and benefits.
696
+
697
+ ## Contributing
698
+
699
+ Contributions are welcome! Please ensure:
700
+
701
+ 1. Code follows the existing style (run `npm run format`)
702
+ 2. TypeScript compiles without errors (`npm run typecheck`)
703
+ 3. Linting passes (`npm run lint`)
704
+ 4. Tests pass (`npm test`)
705
+
706
+ ## Additional Documentation
707
+
708
+ For more detailed information about specific features:
709
+
710
+ - **[Architecture Overview](docs/architecture/overview.md)**: OpenCode integration and system architecture
711
+ - **[Project-Scoped Tasks](docs/PROJECT_SCOPED_TASKS.md)**: How tasks are isolated by project directory
712
+ - **[Project Metadata](docs/PROJECT_METADATA.md)**: Understanding project_name and project_id fields for remote syncing
713
+ - **[Authentication](docs/auth/IMPLEMENTATION.md)**: Authentication flow and credential management
714
+ - **[Mixpanel Integration](docs/MIXPANEL_IMPLEMENTATION.md)**: Telemetry and analytics
715
+ - **[Other Documentation](docs/)**: Additional implementation details and guides
716
+
598
717
  ## License
599
718
 
600
719
  See [License](./license)
package/bin/agentloop ADDED
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * AgentLoop npm shim
5
+ *
6
+ * This thin wrapper finds and executes the platform-specific binary.
7
+ * The binary is installed via optionalDependencies during npm install.
8
+ */
9
+
10
+ import { execSync, spawn } from "child_process";
11
+ import fs from "fs";
12
+ import os from "os";
13
+ import path from "path";
14
+ import { fileURLToPath } from "url";
15
+
16
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
+
18
+ function isMusl() {
19
+ if (os.platform() !== "linux") return false;
20
+ try {
21
+ const output = execSync("ldd --version 2>&1", { encoding: "utf8" });
22
+ return output.includes("musl");
23
+ } catch {
24
+ try {
25
+ const release = fs.readFileSync("/etc/os-release", "utf8");
26
+ return release.includes("Alpine");
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+ }
32
+
33
+ function findBinary() {
34
+ const platform = os.platform() === "win32" ? "windows" : os.platform();
35
+ const arch = os.arch() === "arm64" ? "arm64" : "x64";
36
+ const suffix = isMusl() ? "-musl" : "";
37
+ const packageName = `@trygentic/agentloop-${platform}-${arch}${suffix}`;
38
+ const executableName = platform === "windows" ? "agentloop-cli.exe" : "agentloop-cli";
39
+
40
+ // Check for symlinked binary in same directory (created by postinstall)
41
+ const localBinary = path.join(__dirname, executableName);
42
+ if (fs.existsSync(localBinary)) {
43
+ return localBinary;
44
+ }
45
+
46
+ // Find in node_modules
47
+ const nodeModules = path.resolve(__dirname, "..", "node_modules");
48
+ const packageBinary = path.join(nodeModules, packageName, "bin", executableName);
49
+ if (fs.existsSync(packageBinary)) {
50
+ return packageBinary;
51
+ }
52
+
53
+ // Try global node_modules
54
+ const globalNodeModules = path.resolve(__dirname, "..", "..", "..");
55
+ const globalBinary = path.join(globalNodeModules, packageName, "bin", executableName);
56
+ if (fs.existsSync(globalBinary)) {
57
+ return globalBinary;
58
+ }
59
+
60
+ console.error(`Error: Could not find agentloop binary for ${platform}-${arch}${suffix}`);
61
+ console.error(`Expected package: ${packageName}`);
62
+ console.error(`\nTry reinstalling: npm install -g @trygentic/agentloop`);
63
+ process.exit(1);
64
+ }
65
+
66
+ const binary = findBinary();
67
+ const child = spawn(binary, process.argv.slice(2), {
68
+ stdio: "inherit",
69
+ env: process.env,
70
+ });
71
+
72
+ child.on("error", (err) => {
73
+ console.error(`Failed to start agentloop: ${err.message}`);
74
+ process.exit(1);
75
+ });
76
+
77
+ child.on("exit", (code, signal) => {
78
+ if (signal) {
79
+ process.kill(process.pid, signal);
80
+ } else {
81
+ process.exit(code ?? 0);
82
+ }
83
+ });
package/package.json CHANGED
@@ -1,96 +1,28 @@
1
1
  {
2
2
  "name": "@trygentic/agentloop",
3
- "version": "0.1.1-alpha.3",
4
- "description": "An autonomous agent orchestrator abstraction over Claude Code",
5
- "author": "trygentic.ai",
6
- "license": "SEE LICENSE IN LICENSE",
7
- "main": "dist-obfuscated/index.js",
8
- "type": "module",
3
+ "version": "0.4.0-alpha.5",
4
+ "description": "AI-powered autonomous coding agent",
9
5
  "bin": {
10
- "agentloop": "./bin/run.js"
6
+ "agentloop": "./bin/agentloop"
11
7
  },
12
8
  "scripts": {
13
- "build:agents": "node --loader ts-node/esm scripts/build-agents.ts",
14
- "prebuild": "npm run build:agents",
15
- "build": "tsc",
16
- "bundle": "node scripts/bundle.cjs",
17
- "build:bundled": "npm run build && npm run bundle",
18
- "build:obfuscated": "npm run build:bundled && npm run obfuscate",
19
- "build:obfuscated:prod": "npm run build:obfuscated && npm run upload-sourcemaps",
20
- "obfuscate": "node scripts/obfuscate.cjs",
21
- "upload-sourcemaps": "node scripts/upload-sourcemaps.cjs",
22
- "dev": "tsc --watch",
23
- "clean": "rm -rf dist dist-bundled *.tsbuildinfo",
24
- "start": "node --loader ts-node/esm ./bin/run.js",
25
- "typecheck": "tsc --noEmit",
26
- "lint": "eslint src --ext .ts,.tsx",
27
- "format": "prettier --write \"src/**/*.{ts,tsx}\"",
28
- "reset-mock": "npm run build && node --loader ts-node/esm scripts/reset-mock.ts",
29
- "clear-mock": "npm run build && node --loader ts-node/esm scripts/clear-mock.ts",
30
- "prepare": "lefthook install",
31
- "prepublishOnly": "npm run verify-no-sourcemaps",
32
- "verify-no-sourcemaps": "node scripts/verify-no-sourcemaps.cjs"
9
+ "postinstall": "node ./scripts/postinstall.mjs"
33
10
  },
34
- "dependencies": {
35
- "@anthropic-ai/claude-agent-sdk": "0.1.14",
36
- "@oclif/core": "^3.15.1",
37
- "@sentry/node": "^10.23.0",
38
- "@ts-dag/builder": "^0.1.0-alpha.6",
39
- "@ts-dag/visualizer": "^0.1.0-alpha.1",
40
- "@types/better-sqlite3": "^7.6.13",
41
- "@types/nunjucks": "^3.2.6",
42
- "better-sqlite3": "^12.4.1",
43
- "chalk": "^5.6.2",
44
- "conf": "^15.0.2",
45
- "dotenv": "^17.2.3",
46
- "ink": "^5.2.1",
47
- "ink-spinner": "^5.0.0",
48
- "ink-text-input": "^6.0.0",
49
- "mistreevous": "^4.3.1",
50
- "mixpanel": "^0.18.1",
51
- "node-machine-id": "^1.1.12",
52
- "nunjucks": "^3.2.4",
53
- "open": "^9.1.0",
54
- "react": "^18.2.0",
55
- "smol-toml": "^1.5.2",
56
- "zod": "^3.25.76"
11
+ "optionalDependencies": {
12
+ "@trygentic/agentloop-darwin-arm64": "0.4.0-alpha.5",
13
+ "@trygentic/agentloop-darwin-x64": "0.4.0-alpha.5",
14
+ "@trygentic/agentloop-linux-arm64": "0.4.0-alpha.5",
15
+ "@trygentic/agentloop-linux-x64": "0.4.0-alpha.5",
16
+ "@trygentic/agentloop-linux-x64-musl": "0.4.0-alpha.5",
17
+ "@trygentic/agentloop-linux-arm64-musl": "0.4.0-alpha.5",
18
+ "@trygentic/agentloop-windows-x64": "0.4.0-alpha.5"
57
19
  },
58
- "devDependencies": {
59
- "@modelcontextprotocol/sdk": "^1.23.0",
60
- "@sentry/cli": "^2.40.0",
61
- "@types/node": "^20.10.6",
62
- "@types/react": "^18.2.46",
63
- "@typescript-eslint/eslint-plugin": "^6.17.0",
64
- "@typescript-eslint/parser": "^6.17.0",
65
- "esbuild": "^0.27.0",
66
- "eslint": "^8.56.0",
67
- "glob": "^11.0.3",
68
- "javascript-obfuscator": "^4.1.1",
69
- "lefthook": "^1.10.1",
70
- "prettier": "^3.1.1",
71
- "ts-node": "^10.9.2",
72
- "typescript": ">=4.3.5 <5.4.0"
73
- },
74
- "files": [
75
- "dist-obfuscated/**/*",
76
- "!dist-obfuscated/**/*.ts",
77
- "!dist-obfuscated/**/*.d.ts",
78
- "!dist-obfuscated/**/*.map",
79
- "bin/**/*",
80
- "README.md",
81
- "LICENSE"
82
- ],
83
20
  "engines": {
84
21
  "node": ">=18.0.0"
85
22
  },
86
- "oclif": {
87
- "bin": "agentloop",
88
- "dirname": "agentloop",
89
- "commands": "./dist-obfuscated/commands",
90
- "topicSeparator": " ",
91
- "topics": {},
92
- "hooks": {
93
- "prerun": "./dist-obfuscated/hooks/prerun/check-auth.js"
94
- }
95
- }
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/trygentic/agentloop"
26
+ },
27
+ "license": "SEE LICENSE IN LICENSE"
96
28
  }
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * AgentLoop postinstall script
5
+ *
6
+ * Creates symlinks from the main package's bin to the platform executables
7
+ * for faster execution (avoids the Node.js shim overhead).
8
+ *
9
+ * If symlink creation fails (e.g., on Windows), the shim will handle
10
+ * executable discovery at runtime.
11
+ */
12
+
13
+ import fs from "fs";
14
+ import os from "os";
15
+ import path from "path";
16
+ import { fileURLToPath } from "url";
17
+ import { execSync } from "child_process";
18
+
19
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
20
+
21
+ const platform = os.platform() === "win32" ? "windows" : os.platform();
22
+ const arch = os.arch() === "arm64" ? "arm64" : "x64";
23
+
24
+ // For Linux, detect musl vs glibc
25
+ function isMusl() {
26
+ if (platform !== "linux") return false;
27
+ try {
28
+ const output = execSync("ldd --version 2>&1", { encoding: "utf8" });
29
+ return output.includes("musl");
30
+ } catch {
31
+ try {
32
+ const release = fs.readFileSync("/etc/os-release", "utf8");
33
+ return release.includes("Alpine");
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+ }
39
+
40
+ const suffix = isMusl() ? "-musl" : "";
41
+ const packageName = `@trygentic/agentloop-${platform}-${arch}${suffix}`;
42
+ const ext = platform === "windows" ? ".exe" : "";
43
+
44
+ // Binaries to link
45
+ const binaries = ["agentloop", "agentloop-daemon"];
46
+
47
+ // Find the platform-specific package
48
+ const nodeModules = path.resolve(__dirname, "..", "node_modules");
49
+ const binDir = path.join(__dirname, "..", "bin");
50
+
51
+ let linked = 0;
52
+ for (const binary of binaries) {
53
+ const executableName = `${binary}${ext}`;
54
+ const sourcePath = path.join(nodeModules, packageName, "bin", executableName);
55
+ const targetPath = path.join(binDir, executableName);
56
+
57
+ if (fs.existsSync(sourcePath)) {
58
+ try {
59
+ // Remove existing file/symlink
60
+ if (fs.existsSync(targetPath)) {
61
+ fs.unlinkSync(targetPath);
62
+ }
63
+
64
+ // Create symlink (Unix) or copy (Windows)
65
+ if (platform === "windows") {
66
+ fs.copyFileSync(sourcePath, targetPath);
67
+ } else {
68
+ fs.symlinkSync(sourcePath, targetPath);
69
+ }
70
+ linked++;
71
+ } catch {
72
+ // Symlink failed, shim will handle at runtime
73
+ }
74
+ }
75
+ }
76
+
77
+ if (linked > 0) {
78
+ console.log(`agentloop: linked ${linked} executable(s) for ${platform}-${arch}${suffix}`);
79
+ } else {
80
+ console.log(`agentloop: platform executables not found (${packageName})`);
81
+ console.log("agentloop: will use runtime executable resolution");
82
+ }
package/bin/dev.js DELETED
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env node
2
- import "dotenv/config";
3
- try {
4
- await import("../dist/instrument.js");
5
- } catch (error) {
6
- }
7
- import { execute } from "@oclif/core";
8
- import { readFileSync, writeFileSync } from "fs";
9
- import { dirname, join } from "path";
10
- import { fileURLToPath } from "url";
11
- const __dirname = dirname(fileURLToPath(import.meta.url));
12
- const packageJsonPath = join(__dirname, "..", "package.json");
13
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
14
- if (packageJson.oclif) {
15
- if (packageJson.oclif.commands) {
16
- packageJson.oclif.commands = packageJson.oclif.commands.replace("dist-obfuscated", "dist");
17
- }
18
- if (packageJson.oclif.hooks) {
19
- Object.keys(packageJson.oclif.hooks).forEach((hookName) => {
20
- const hookValue = packageJson.oclif.hooks[hookName];
21
- if (typeof hookValue === "string") {
22
- packageJson.oclif.hooks[hookName] = hookValue.replace("dist-obfuscated", "dist");
23
- }
24
- });
25
- }
26
- }
27
- const manifestPath = join(__dirname, "..", "oclif.manifest.json");
28
- let manifestModified = false;
29
- try {
30
- const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
31
- if (manifest.commands) {
32
- Object.keys(manifest.commands).forEach((commandId) => {
33
- const command = manifest.commands[commandId];
34
- if (command.relativePath && Array.isArray(command.relativePath)) {
35
- const originalPath = [...command.relativePath];
36
- command.relativePath = command.relativePath.map(
37
- (path) => path === "dist-obfuscated" ? "dist" : path
38
- );
39
- if (JSON.stringify(originalPath) !== JSON.stringify(command.relativePath)) {
40
- manifestModified = true;
41
- }
42
- }
43
- });
44
- }
45
- if (manifestModified) {
46
- writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
47
- }
48
- } catch (error) {
49
- }
50
- await execute({
51
- development: false,
52
- // Use false to avoid src/ directory loading
53
- dir: import.meta.url,
54
- loadOptions: { root: join(__dirname, ".."), pjson: packageJson }
55
- });