@agentspan/agentspan 0.0.3

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,78 @@
1
+ // Copyright (c) 2025 AgentSpan
2
+ // Licensed under the MIT License. See LICENSE file in the project root for details.
3
+
4
+ package config
5
+
6
+ import (
7
+ "encoding/json"
8
+ "os"
9
+ "path/filepath"
10
+ )
11
+
12
+ type Config struct {
13
+ ServerURL string `json:"server_url"`
14
+ AuthKey string `json:"auth_key,omitempty"`
15
+ AuthSecret string `json:"auth_secret,omitempty"`
16
+ }
17
+
18
+ func DefaultConfig() *Config {
19
+ return &Config{
20
+ ServerURL: "http://localhost:8080",
21
+ }
22
+ }
23
+
24
+ func ConfigDir() string {
25
+ home, _ := os.UserHomeDir()
26
+ return filepath.Join(home, ".agentspan")
27
+ }
28
+
29
+ func configPath() string {
30
+ return filepath.Join(ConfigDir(), "config.json")
31
+ }
32
+
33
+ func Load() *Config {
34
+ cfg := DefaultConfig()
35
+
36
+ // Env vars override
37
+ if url := os.Getenv("AGENT_SERVER_URL"); url != "" {
38
+ cfg.ServerURL = url
39
+ }
40
+ if key := os.Getenv("CONDUCTOR_AUTH_KEY"); key != "" {
41
+ cfg.AuthKey = key
42
+ }
43
+ if secret := os.Getenv("CONDUCTOR_AUTH_SECRET"); secret != "" {
44
+ cfg.AuthSecret = secret
45
+ }
46
+
47
+ // File overrides (env vars take precedence)
48
+ data, err := os.ReadFile(configPath())
49
+ if err != nil {
50
+ return cfg
51
+ }
52
+ var fileCfg Config
53
+ if json.Unmarshal(data, &fileCfg) == nil {
54
+ if cfg.ServerURL == "http://localhost:8080" && fileCfg.ServerURL != "" {
55
+ cfg.ServerURL = fileCfg.ServerURL
56
+ }
57
+ if cfg.AuthKey == "" && fileCfg.AuthKey != "" {
58
+ cfg.AuthKey = fileCfg.AuthKey
59
+ }
60
+ if cfg.AuthSecret == "" && fileCfg.AuthSecret != "" {
61
+ cfg.AuthSecret = fileCfg.AuthSecret
62
+ }
63
+ }
64
+
65
+ return cfg
66
+ }
67
+
68
+ func Save(cfg *Config) error {
69
+ dir := ConfigDir()
70
+ if err := os.MkdirAll(dir, 0o700); err != nil {
71
+ return err
72
+ }
73
+ data, err := json.MarshalIndent(cfg, "", " ")
74
+ if err != nil {
75
+ return err
76
+ }
77
+ return os.WriteFile(configPath(), data, 0o600)
78
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,22 @@
1
+ name: research-team
2
+ description: A multi-agent research team
3
+ model: openai/gpt-4o
4
+ instructions: Route user requests to the appropriate specialist agent.
5
+ strategy: handoff
6
+ agents:
7
+ - name: researcher
8
+ description: Finds and summarizes information
9
+ model: openai/gpt-4o
10
+ instructions: |
11
+ You are a research specialist. Find relevant information and provide
12
+ well-sourced summaries.
13
+ tools:
14
+ - name: web_search
15
+ type: worker
16
+ - name: writer
17
+ description: Writes polished content
18
+ model: openai/gpt-4o
19
+ instructions: |
20
+ You are a writing specialist. Take research findings and produce
21
+ clear, well-structured content.
22
+ tools: []
@@ -0,0 +1,7 @@
1
+ name: simple-assistant
2
+ description: A simple conversational assistant
3
+ model: openai/gpt-4o
4
+ instructions: |
5
+ You are a helpful AI assistant. Answer questions clearly and concisely.
6
+ maxTurns: 10
7
+ tools: []
package/go.mod ADDED
@@ -0,0 +1,17 @@
1
+ module github.com/agentspan/agentspan/cli
2
+
3
+ go 1.25.6
4
+
5
+ require (
6
+ github.com/fatih/color v1.18.0
7
+ github.com/spf13/cobra v1.10.2
8
+ gopkg.in/yaml.v3 v3.0.1
9
+ )
10
+
11
+ require (
12
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
13
+ github.com/mattn/go-colorable v0.1.13 // indirect
14
+ github.com/mattn/go-isatty v0.0.20 // indirect
15
+ github.com/spf13/pflag v1.0.9 // indirect
16
+ golang.org/x/sys v0.25.0 // indirect
17
+ )
package/go.sum ADDED
@@ -0,0 +1,24 @@
1
+ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
2
+ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
3
+ github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
4
+ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
5
+ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
6
+ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
7
+ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
8
+ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
9
+ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
10
+ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
11
+ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
12
+ github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
13
+ github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
14
+ github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
15
+ github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
16
+ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
17
+ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
18
+ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
19
+ golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
20
+ golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
21
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
22
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
23
+ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
24
+ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
package/install.js ADDED
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Copyright (c) 2025 AgentSpan
4
+ // Licensed under the MIT License. See LICENSE file in the project root for details.
5
+
6
+
7
+ const https = require('https');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const S3_BUCKET = 'https://agentspan.s3.us-east-2.amazonaws.com';
12
+ const BINARY_NAME = 'agentspan';
13
+
14
+ // Detect platform and architecture
15
+ function getPlatform() {
16
+ const platform = process.platform;
17
+ const arch = process.arch;
18
+
19
+ const platformMap = {
20
+ darwin: 'darwin',
21
+ linux: 'linux',
22
+ win32: 'windows'
23
+ };
24
+
25
+ const archMap = {
26
+ x64: 'amd64',
27
+ arm64: 'arm64'
28
+ };
29
+
30
+ if (!platformMap[platform]) {
31
+ console.error(`Unsupported platform: ${platform}`);
32
+ process.exit(1);
33
+ }
34
+
35
+ if (!archMap[arch]) {
36
+ console.error(`Unsupported architecture: ${arch}`);
37
+ process.exit(1);
38
+ }
39
+
40
+ return {
41
+ os: platformMap[platform],
42
+ arch: archMap[arch],
43
+ isWindows: platform === 'win32'
44
+ };
45
+ }
46
+
47
+ // Download binary following redirects
48
+ function downloadBinary(url, dest) {
49
+ return new Promise((resolve, reject) => {
50
+ const makeRequest = (requestUrl) => {
51
+ const mod = requestUrl.startsWith('https') ? https : require('http');
52
+ mod.get(requestUrl, { headers: { 'User-Agent': 'agentspan-npm-installer' } }, (response) => {
53
+ if (response.statusCode === 302 || response.statusCode === 301) {
54
+ makeRequest(response.headers.location);
55
+ return;
56
+ }
57
+
58
+ if (response.statusCode !== 200) {
59
+ reject(new Error(`Failed to download: ${response.statusCode}`));
60
+ return;
61
+ }
62
+
63
+ const file = fs.createWriteStream(dest);
64
+ response.pipe(file);
65
+
66
+ file.on('finish', () => {
67
+ file.close();
68
+ resolve();
69
+ });
70
+
71
+ file.on('error', (err) => {
72
+ fs.unlink(dest, () => {});
73
+ reject(err);
74
+ });
75
+ }).on('error', (err) => {
76
+ fs.unlink(dest, () => {});
77
+ reject(err);
78
+ });
79
+ };
80
+
81
+ makeRequest(url);
82
+ });
83
+ }
84
+
85
+ async function install() {
86
+ try {
87
+ console.log('Installing AgentSpan CLI...');
88
+
89
+ const { os, arch, isWindows } = getPlatform();
90
+ console.log(`Platform: ${os} ${arch}`);
91
+
92
+ const binaryName = isWindows ? `${BINARY_NAME}.exe` : BINARY_NAME;
93
+ const downloadName = isWindows ? `${BINARY_NAME}_${os}_${arch}.exe` : `${BINARY_NAME}_${os}_${arch}`;
94
+ const downloadUrl = `${S3_BUCKET}/cli/latest/${downloadName}`;
95
+
96
+ console.log(`Downloading from: ${downloadUrl}`);
97
+
98
+ // Create bin directory
99
+ const binDir = path.join(__dirname, 'bin');
100
+ if (!fs.existsSync(binDir)) {
101
+ fs.mkdirSync(binDir, { recursive: true });
102
+ }
103
+
104
+ // Download binary
105
+ const binaryPath = path.join(binDir, binaryName);
106
+ await downloadBinary(downloadUrl, binaryPath);
107
+
108
+ // Make executable (Unix-like systems)
109
+ if (!isWindows) {
110
+ fs.chmodSync(binaryPath, 0o755);
111
+ }
112
+
113
+ console.log('Installation successful!');
114
+ console.log(`Binary installed at: ${binaryPath}`);
115
+ console.log(`\nRun 'agentspan --help' to get started.`);
116
+ } catch (error) {
117
+ console.error('Installation failed:', error.message);
118
+ process.exit(1);
119
+ }
120
+ }
121
+
122
+ install();
package/install.sh ADDED
@@ -0,0 +1,104 @@
1
+ #!/bin/sh
2
+ set -e
3
+
4
+ S3_BUCKET="https://agentspan.s3.us-east-2.amazonaws.com"
5
+ BINARY_NAME="agentspan"
6
+ INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}"
7
+
8
+ # Colors for output
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ NC='\033[0m' # No Color
13
+
14
+ detect_os() {
15
+ OS="$(uname -s)"
16
+ case "$OS" in
17
+ Linux*) OS='linux';;
18
+ Darwin*) OS='darwin';;
19
+ CYGWIN*) OS='windows';;
20
+ MINGW*) OS='windows';;
21
+ *)
22
+ echo "${RED}Unsupported operating system: $OS${NC}"
23
+ exit 1
24
+ ;;
25
+ esac
26
+ }
27
+
28
+ detect_arch() {
29
+ ARCH="$(uname -m)"
30
+ case "$ARCH" in
31
+ x86_64) ARCH='amd64';;
32
+ amd64) ARCH='amd64';;
33
+ arm64) ARCH='arm64';;
34
+ aarch64) ARCH='arm64';;
35
+ *)
36
+ echo "${RED}Unsupported architecture: $ARCH${NC}"
37
+ exit 1
38
+ ;;
39
+ esac
40
+ }
41
+
42
+ install_binary() {
43
+ DOWNLOAD_URL="${S3_BUCKET}/cli/latest/${BINARY_NAME}_${OS}_${ARCH}"
44
+
45
+ if [ "$OS" = "windows" ]; then
46
+ DOWNLOAD_URL="${DOWNLOAD_URL}.exe"
47
+ BINARY_NAME="${BINARY_NAME}.exe"
48
+ fi
49
+
50
+ echo "${YELLOW}Downloading from: $DOWNLOAD_URL${NC}"
51
+
52
+ TMP_DIR=$(mktemp -d)
53
+ TMP_FILE="$TMP_DIR/$BINARY_NAME"
54
+
55
+ if ! curl -fsSL "$DOWNLOAD_URL" -o "$TMP_FILE"; then
56
+ echo "${RED}Failed to download binary${NC}"
57
+ rm -rf "$TMP_DIR"
58
+ exit 1
59
+ fi
60
+
61
+ chmod +x "$TMP_FILE"
62
+
63
+ if [ -w "$INSTALL_DIR" ]; then
64
+ mv "$TMP_FILE" "$INSTALL_DIR/$BINARY_NAME"
65
+ echo "${GREEN}Installed $BINARY_NAME to $INSTALL_DIR${NC}"
66
+ else
67
+ echo "${YELLOW}$INSTALL_DIR is not writable. Attempting to use sudo...${NC}"
68
+ sudo mv "$TMP_FILE" "$INSTALL_DIR/$BINARY_NAME"
69
+ echo "${GREEN}Installed $BINARY_NAME to $INSTALL_DIR (with sudo)${NC}"
70
+ fi
71
+
72
+ rm -rf "$TMP_DIR"
73
+ }
74
+
75
+ verify_installation() {
76
+ if command -v $BINARY_NAME >/dev/null 2>&1; then
77
+ VERSION_OUTPUT=$($BINARY_NAME version 2>&1 || true)
78
+ echo "${GREEN}Installation successful!${NC}"
79
+ echo "${GREEN} Version: $VERSION_OUTPUT${NC}"
80
+ echo ""
81
+ echo "Run '${BINARY_NAME} --help' to get started."
82
+ else
83
+ echo "${YELLOW}Binary installed but not found in PATH${NC}"
84
+ echo "You may need to add $INSTALL_DIR to your PATH:"
85
+ echo " export PATH=\"$INSTALL_DIR:\$PATH\""
86
+ fi
87
+ }
88
+
89
+ main() {
90
+ echo "${GREEN}Installing AgentSpan CLI...${NC}"
91
+ echo ""
92
+
93
+ detect_os
94
+ detect_arch
95
+
96
+ echo "Detected OS: $OS"
97
+ echo "Detected Architecture: $ARCH"
98
+ echo ""
99
+
100
+ install_binary
101
+ verify_installation
102
+ }
103
+
104
+ main
@@ -0,0 +1,121 @@
1
+ // Copyright (c) 2025 AgentSpan
2
+ // Licensed under the MIT License. See LICENSE file in the project root for details.
3
+
4
+ package progress
5
+
6
+ import (
7
+ "fmt"
8
+ "io"
9
+ "os"
10
+ "sync"
11
+ "time"
12
+ )
13
+
14
+ const (
15
+ barWidth = 30
16
+ filledChar = "█"
17
+ emptyChar = "░"
18
+ renderInterval = 100 * time.Millisecond
19
+ )
20
+
21
+ // ProgressBar tracks and renders download progress to stderr.
22
+ type ProgressBar struct {
23
+ total int64
24
+ current int64
25
+ desc string
26
+ mu sync.Mutex
27
+ lastRender time.Time
28
+ w io.Writer
29
+ }
30
+
31
+ // NewProgressBar creates a new progress bar. If total <= 0, it renders without a bar.
32
+ func NewProgressBar(total int64, desc string) *ProgressBar {
33
+ return &ProgressBar{
34
+ total: total,
35
+ desc: desc,
36
+ w: os.Stderr,
37
+ }
38
+ }
39
+
40
+ // Add advances the progress bar by n bytes.
41
+ func (p *ProgressBar) Add(n int64) {
42
+ p.mu.Lock()
43
+ defer p.mu.Unlock()
44
+ p.current += n
45
+ now := time.Now()
46
+ if now.Sub(p.lastRender) >= renderInterval {
47
+ p.render()
48
+ p.lastRender = now
49
+ }
50
+ }
51
+
52
+ // Finish renders the final state with a newline.
53
+ func (p *ProgressBar) Finish() {
54
+ p.mu.Lock()
55
+ defer p.mu.Unlock()
56
+ p.render()
57
+ fmt.Fprintln(p.w)
58
+ }
59
+
60
+ func (p *ProgressBar) render() {
61
+ if p.total > 0 {
62
+ pct := float64(p.current) / float64(p.total)
63
+ if pct > 1 {
64
+ pct = 1
65
+ }
66
+ filled := int(pct * float64(barWidth))
67
+ bar := ""
68
+ for i := 0; i < barWidth; i++ {
69
+ if i < filled {
70
+ bar += filledChar
71
+ } else {
72
+ bar += emptyChar
73
+ }
74
+ }
75
+ fmt.Fprintf(p.w, "\r%s [%s] %3.0f%% %s/%s",
76
+ p.desc, bar, pct*100,
77
+ FormatBytes(p.current), FormatBytes(p.total))
78
+ } else {
79
+ fmt.Fprintf(p.w, "\r%s %s downloaded", p.desc, FormatBytes(p.current))
80
+ }
81
+ }
82
+
83
+ // Reader wraps an io.Reader and reports progress on each Read.
84
+ type Reader struct {
85
+ reader io.Reader
86
+ bar *ProgressBar
87
+ }
88
+
89
+ // NewReader wraps r with a progress bar. desc is shown as a label.
90
+ // If total <= 0, a simple byte counter is shown instead of a bar.
91
+ func NewReader(r io.Reader, total int64, desc string) (*Reader, *ProgressBar) {
92
+ bar := NewProgressBar(total, desc)
93
+ return &Reader{reader: r, bar: bar}, bar
94
+ }
95
+
96
+ func (r *Reader) Read(p []byte) (int, error) {
97
+ n, err := r.reader.Read(p)
98
+ if n > 0 {
99
+ r.bar.Add(int64(n))
100
+ }
101
+ return n, err
102
+ }
103
+
104
+ // FormatBytes returns a human-readable byte string (e.g. "12.3 MB").
105
+ func FormatBytes(n int64) string {
106
+ const (
107
+ kb = 1024
108
+ mb = 1024 * kb
109
+ gb = 1024 * mb
110
+ )
111
+ switch {
112
+ case n >= gb:
113
+ return fmt.Sprintf("%.1f GB", float64(n)/float64(gb))
114
+ case n >= mb:
115
+ return fmt.Sprintf("%.1f MB", float64(n)/float64(mb))
116
+ case n >= kb:
117
+ return fmt.Sprintf("%.1f KB", float64(n)/float64(kb))
118
+ default:
119
+ return fmt.Sprintf("%d B", n)
120
+ }
121
+ }
package/main.go ADDED
@@ -0,0 +1,10 @@
1
+ // Copyright (c) 2025 AgentSpan
2
+ // Licensed under the MIT License. See LICENSE file in the project root for details.
3
+
4
+ package main
5
+
6
+ import "github.com/agentspan/agentspan/cli/cmd"
7
+
8
+ func main() {
9
+ cmd.Execute()
10
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@agentspan/agentspan",
3
+ "version": "0.0.3",
4
+ "description": "CLI for AgentSpan - Build, run, and manage AI agents",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "agentspan": "./cli.js"
8
+ },
9
+ "scripts": {
10
+ "postinstall": "node install.js"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/agentspan/agentspan.git"
15
+ },
16
+ "keywords": [
17
+ "agentspan",
18
+ "agent",
19
+ "ai",
20
+ "llm",
21
+ "orchestration",
22
+ "workflow",
23
+ "cli"
24
+ ],
25
+ "author": "AgentSpan",
26
+ "license": "Apache-2.0",
27
+ "bugs": {
28
+ "url": "https://github.com/agentspan/agentspan/issues"
29
+ },
30
+ "homepage": "https://github.com/agentspan/agentspan#readme",
31
+ "os": [
32
+ "darwin",
33
+ "linux",
34
+ "win32"
35
+ ],
36
+ "cpu": [
37
+ "x64",
38
+ "arm64"
39
+ ],
40
+ "engines": {
41
+ "node": ">=14"
42
+ }
43
+ }