cli4ai 0.9.2 → 1.0.1

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 ADDED
@@ -0,0 +1,109 @@
1
+ Business Source License 1.1
2
+
3
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
4
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
5
+
6
+ -----------------------------------------------------------------------------
7
+
8
+ Parameters
9
+
10
+ Licensor: cli4ai
11
+ Licensed Work: cli4ai
12
+ The Licensed Work is (c) 2024 cli4ai
13
+ Additional Use Grant: You may make use of the Licensed Work, provided that
14
+ you do not use the Licensed Work for a Commercial
15
+ Purpose.
16
+
17
+ A "Commercial Purpose" means use in production for
18
+ commercial or for-profit purposes including, but not
19
+ limited to: (a) integrating the Licensed Work into a
20
+ commercial product or service; (b) using the Licensed
21
+ Work to provide commercial services to third parties;
22
+ (c) using the Licensed Work in a business's internal
23
+ production environment.
24
+
25
+ Non-commercial use, personal projects, evaluation,
26
+ development, testing, educational use, and use by
27
+ non-profit organizations are permitted.
28
+
29
+ Change Date: December 19, 2029
30
+ Change License: Apache License, Version 2.0
31
+
32
+ -----------------------------------------------------------------------------
33
+
34
+ Terms
35
+
36
+ The Licensor hereby grants you the right to copy, modify, create derivative
37
+ works, redistribute, and make non-production use of the Licensed Work. The
38
+ Licensor may make an Additional Use Grant, above, permitting limited
39
+ production use.
40
+
41
+ Effective on the Change Date, or the fourth anniversary of the first publicly
42
+ available distribution of a specific version of the Licensed Work under this
43
+ License, whichever comes first, the Licensor hereby grants you rights under
44
+ the terms of the Change License, and the rights granted in the paragraph
45
+ above terminate.
46
+
47
+ If your use of the Licensed Work does not comply with the requirements
48
+ currently in effect as described in this License, you must purchase a
49
+ commercial license from the Licensor, its affiliated entities, or authorized
50
+ resellers, or you must refrain from using the Licensed Work.
51
+
52
+ All copies of the original and modified Licensed Work, and derivative works
53
+ of the Licensed Work, are subject to this License. This License applies
54
+ separately for each version of the Licensed Work and the Change Date may vary
55
+ for each version of the Licensed Work released by Licensor.
56
+
57
+ You must conspicuously display this License on each original or modified copy
58
+ of the Licensed Work. If you receive the Licensed Work in original or
59
+ modified form from a third party, the terms and conditions set forth in this
60
+ License apply to your use of that work.
61
+
62
+ Any use of the Licensed Work in violation of this License will automatically
63
+ terminate your rights under this License for the current and all other
64
+ versions of the Licensed Work.
65
+
66
+ This License does not grant you any right in any trademark or logo of
67
+ Licensor or its affiliates (provided that you may use a trademark or logo of
68
+ Licensor as expressly required by this License).
69
+
70
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
71
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
72
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
73
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
74
+ TITLE.
75
+
76
+ MariaDB hereby grants you permission to use this License's text to license
77
+ your works, and to refer to it using the trademark "Business Source License",
78
+ as long as you comply with the Covenants of Licensor below.
79
+
80
+ -----------------------------------------------------------------------------
81
+
82
+ Covenants of Licensor
83
+
84
+ In consideration of the right to use this License's text and the "Business
85
+ Source License" name and trademark, Licensor covenants to MariaDB, and to all
86
+ other recipients of the licensed work to be provided by Licensor:
87
+
88
+ 1. To specify as the Change License the GPL Version 2.0 or any later version,
89
+ or a license that is compatible with GPL Version 2.0 or a later version,
90
+ where "compatible" means that software provided under the Change License can
91
+ be included in a program with software provided under GPL Version 2.0 or a
92
+ later version. Licensor may specify additional Change Licenses without
93
+ limitation.
94
+
95
+ 2. To either: (a) specify an additional grant of rights to use that does not
96
+ impose any additional restriction on the right granted in this License, as
97
+ the Additional Use Grant; or (b) insert the text "None".
98
+
99
+ 3. To specify a Change Date.
100
+
101
+ 4. Not to modify this License in any other way.
102
+
103
+ -----------------------------------------------------------------------------
104
+
105
+ Notice
106
+
107
+ The Business Source License (this document, or the "License") is not an Open
108
+ Source license. However, the Licensed Work will eventually be made available
109
+ under an Open Source License, as stated in this License.
package/README.md CHANGED
@@ -1,21 +1,15 @@
1
1
  # cli4ai
2
2
 
3
- > Official CLI4AI package • https://cli4ai.com
3
+ [![npm version](https://img.shields.io/npm/v/cli4ai.svg)](https://www.npmjs.com/package/cli4ai)
4
+ [![License: BSL 1.1](https://img.shields.io/badge/License-BSL_1.1-blue.svg)](./LICENSE)
4
5
 
5
- The package manager for AI CLI tools.
6
+ **The package manager for AI CLI tools.**
6
7
 
7
- ## Setup
8
+ Give your AI agents superpowers with ready-to-use tools for GitHub, Slack, Gmail, databases, and more. Install in seconds, run from anywhere, integrate with Claude via MCP.
8
9
 
9
10
  ```bash
10
- # Install cli4ai
11
11
  npm i -g cli4ai
12
- # or (optional)
13
- bun install -g cli4ai
14
-
15
- # Install a package
16
12
  cli4ai add -g github
17
-
18
- # Run it
19
13
  cli4ai run github notifs
20
14
  ```
21
15
 
@@ -23,30 +17,53 @@ cli4ai run github notifs
23
17
 
24
18
  AI agents need tools. MCP servers are complex to set up. cli4ai makes it simple:
25
19
 
26
- - **Install tools in seconds** - `cli4ai add github` just works
27
- - **Run from anywhere** - `cli4ai run <tool> <command>`
28
- - **No MCP boilerplate** - cli4ai wraps CLI tools as MCP servers automatically
29
- - **Local-first** - Tools are just scripts, no cloud required
20
+ - **Install tools in seconds** `cli4ai add github` just works
21
+ - **Run from anywhere** `cli4ai run <tool> <command>`
22
+ - **MCP integration** Wrap any CLI tool as an MCP server automatically
23
+ - **Local-first** Tools are just TypeScript scripts, no cloud required
24
+ - **Unified interface** — All tools output JSON for easy parsing
25
+
26
+ ## Available Packages
27
+
28
+ See the [packages repo](https://github.com/cli4ai/packages) for source code and documentation.
29
+
30
+ | Package | Description |
31
+ |---------|-------------|
32
+ | `github` | GitHub notifications, repos, issues, PRs |
33
+ | `slack` | Slack messages, channels, users |
34
+ | `gmail` | Gmail inbox, threads, send/reply |
35
+ | `twitter` | Twitter/X timeline, search, post |
36
+ | `youtube` | YouTube transcripts and metadata |
37
+ | `mongodb` | MongoDB queries and schemas |
38
+ | `postgres` | PostgreSQL read-only queries |
39
+ | `snowflake` | Snowflake data warehouse queries |
40
+ | `chrome` | Browser automation with Puppeteer |
41
+ | `linkedin` | LinkedIn feed and profiles |
42
+ | `fireflies` | Fireflies.ai meeting transcripts |
43
+ | `dataforseo` | SEO keywords, trends, backlinks |
44
+ | `ipinfo` | IP address geolocation |
45
+ | `history` | Chrome browser history |
46
+ | `openapi` | Turn any OpenAPI spec into a CLI |
47
+
48
+ Browse all packages: `cli4ai browse`
30
49
 
31
50
  ## Quick Start
32
51
 
33
52
  ```bash
34
- # Add a local registry (directory containing tools)
35
- cli4ai config --add-registry ~/my-tools
36
-
37
- # Search for tools
38
- cli4ai search github
53
+ # Install cli4ai globally
54
+ npm i -g cli4ai
39
55
 
40
- # Install globally (available everywhere)
56
+ # Install a tool
41
57
  cli4ai add -g github
42
58
 
43
- # Install locally (project-scoped)
44
- cd ~/my-project
45
- cli4ai add mongodb
46
-
47
- # Run tools
59
+ # Run a command
48
60
  cli4ai run github notifs
49
- cli4ai run mongodb databases
61
+
62
+ # See available commands
63
+ cli4ai info github
64
+
65
+ # Update all tools
66
+ cli4ai update
50
67
  ```
51
68
 
52
69
  ## Commands
@@ -58,14 +75,14 @@ cli4ai run mongodb databases
58
75
  | `cli4ai add <pkg>` | Install package locally |
59
76
  | `cli4ai add -g <pkg>` | Install package globally |
60
77
  | `cli4ai remove <pkg>` | Uninstall package |
61
- | `cli4ai remove -g <pkg>` | Uninstall global package |
62
- | `cli4ai list` | List local packages |
63
- | `cli4ai list -g` | List global packages |
78
+ | `cli4ai list` | List installed packages |
79
+ | `cli4ai update` | Update all packages |
64
80
 
65
81
  ### Discovery
66
82
 
67
83
  | Command | Description |
68
84
  |---------|-------------|
85
+ | `cli4ai browse` | Interactive package browser |
69
86
  | `cli4ai search <query>` | Search for packages |
70
87
  | `cli4ai info <pkg>` | Show package details |
71
88
 
@@ -76,108 +93,24 @@ cli4ai run mongodb databases
76
93
  | `cli4ai run <pkg> <cmd> [args]` | Run a tool command |
77
94
  | `cli4ai start <pkg>` | Start package as MCP server |
78
95
 
79
- Notes:
80
- - Tool flags are supported: `cli4ai run chrome screenshot https://example.com --full-page`
81
- - If a flag conflicts with `cli4ai run` options, use `--` to pass-through: `cli4ai run <pkg> <cmd> -- --help`
82
-
83
- ### Configuration
84
-
85
- | Command | Description |
86
- |---------|-------------|
87
- | `cli4ai config` | Show current config |
88
- | `cli4ai config --add-registry <path>` | Add local registry |
89
- | `cli4ai config --remove-registry <path>` | Remove registry |
90
-
91
- ### Project Setup
92
-
93
- | Command | Description |
94
- |---------|-------------|
95
- | `cli4ai init [name]` | Create a new tool project |
96
- | `cli4ai mcp-config` | Generate Claude Code MCP config |
97
-
98
- ## Package Format
99
-
100
- Tools are defined by a `cli4ai.json` manifest:
101
-
102
- ```json
103
- {
104
- "name": "github",
105
- "version": "1.0.0",
106
- "description": "GitHub CLI wrapper",
107
- "entry": "run.ts",
108
- "runtime": "bun",
109
- "commands": {
110
- "notifs": {
111
- "description": "Your notifications"
112
- },
113
- "repos": {
114
- "description": "List repositories",
115
- "args": [
116
- { "name": "user", "required": false }
117
- ]
118
- }
119
- },
120
- "env": {
121
- "GITHUB_TOKEN": {
122
- "required": false,
123
- "description": "Personal access token"
124
- }
125
- },
126
- "mcp": {
127
- "enabled": true
128
- }
129
- }
130
- ```
131
-
132
- ### Manifest Fields
133
-
134
- | Field | Required | Description |
135
- |-------|----------|-------------|
136
- | `name` | Yes | Package name (lowercase, hyphens ok) |
137
- | `version` | Yes | Semver version |
138
- | `entry` | Yes | Entry point script |
139
- | `description` | No | Package description |
140
- | `runtime` | No | Runtime: `bun` (default), `node`, `deno` |
141
- | `commands` | No | Command definitions for MCP |
142
- | `env` | No | Environment variable requirements |
143
- | `mcp.enabled` | No | Enable MCP server mode |
144
-
145
- ## Storage Locations
146
-
147
- ```
148
- ~/.cli4ai/
149
- ├── config.json # Global configuration
150
- ├── packages/ # Globally installed packages
151
- │ └── github/
152
- └── bin/ # PATH-linked executables (optional)
153
-
154
- ./
155
- ├── cli4ai.json # Project manifest (if a tool)
156
- ├── cli4ai.lock # Lock file (reproducible installs)
157
- └── .cli4ai/
158
- └── packages/ # Locally installed packages
159
- ```
160
-
161
96
  ## MCP Integration
162
97
 
163
- cli4ai can generate configuration for Claude Code:
98
+ cli4ai tools can run as MCP servers for Claude:
164
99
 
165
100
  ```bash
166
- # Generate config for all installed packages
101
+ # Generate Claude Code config
167
102
  cli4ai mcp-config
168
103
 
169
- # Generate for specific packages
170
- cli4ai mcp-config --packages github,slack
171
-
172
- # Get snippet for a single package
173
- cli4ai mcp-config --package github --snippet
104
+ # Start a tool as MCP server
105
+ cli4ai start github
174
106
  ```
175
107
 
176
- Output:
108
+ Add to your Claude Code MCP settings:
109
+
177
110
  ```json
178
111
  {
179
112
  "mcpServers": {
180
- "cli4ai-github": {
113
+ "github": {
181
114
  "command": "cli4ai",
182
115
  "args": ["start", "github"]
183
116
  }
@@ -185,50 +118,26 @@ Output:
185
118
  }
186
119
  ```
187
120
 
188
- Add this to your Claude Code MCP settings.
189
-
190
- ## Local Registries
191
-
192
- cli4ai discovers packages from local directories:
193
-
194
- ```bash
195
- # Add a registry
196
- cli4ai config --add-registry ~/agent-tools
197
-
198
- # Now packages in ~/agent-tools are discoverable
199
- cli4ai search github # Finds ~/agent-tools/github/
200
- ```
201
-
202
- A registry is just a directory containing tool folders, each with a `cli4ai.json`.
203
-
204
121
  ## Creating Tools
205
122
 
206
123
  ```bash
207
- # Create a new tool
208
- cli4ai init my-tool
209
- cd my-tool
124
+ # Quick scaffold with defaults
125
+ npx create-cli4ai my-tool -y
210
126
 
211
- # Edit `run.ts` and `cli4ai.json`
127
+ # Interactive mode (prompts for commands, args, env vars)
128
+ npx create-cli4ai
212
129
 
213
- # Test locally
214
- bun run run.ts hello world
215
-
216
- # Install for testing
217
- cd ~/some-project
218
- cli4ai add --local ~/path/to/my-tool -y
219
- cli4ai run my-tool hello world
130
+ # Or use the built-in init
131
+ cli4ai init my-tool
220
132
  ```
221
133
 
222
- ### Tool Entry Point
223
-
224
- Tools are simple CLI scripts that output JSON:
134
+ Tools are TypeScript scripts with a `cli4ai.json` manifest:
225
135
 
226
136
  ```typescript
227
- #!/usr/bin/env bun
228
-
137
+ #!/usr/bin/env npx tsx
229
138
  import { cli, output } from '@cli4ai/lib/cli.ts';
230
139
 
231
- const program = cli('my-tool', '1.0.0', 'Example tool');
140
+ const program = cli('my-tool', '1.0.0', 'My awesome tool');
232
141
 
233
142
  program
234
143
  .command('hello [name]')
@@ -240,36 +149,45 @@ program
240
149
  program.parse();
241
150
  ```
242
151
 
243
- When run via `cli4ai run`, these env vars are set for convenience:
244
- - `CLI4AI_CWD`: directory where you invoked `cli4ai`
245
- - `C4AI_PACKAGE_DIR`: installed package directory
246
- - `C4AI_PACKAGE_NAME`: resolved package name
247
- - `C4AI_ENTRY`: absolute path to the tool entry file
248
-
249
- ## Global vs Local Install
250
-
251
- | Aspect | Global (`-g`) | Local (default) |
252
- |--------|---------------|-----------------|
253
- | Location | `~/.cli4ai/packages/` | `./.cli4ai/packages/` |
254
- | Scope | Available everywhere | Project only |
255
- | Lock file | No | Yes (`cli4ai.lock`) |
256
- | Use case | Utilities (github, slack) | Project-specific (mongodb) |
257
-
258
- ## Environment Variables
259
-
260
- Tools can require environment variables:
261
-
262
152
  ```json
263
153
  {
264
- "env": {
265
- "API_KEY": { "required": true },
266
- "DEBUG": { "required": false, "default": "false" }
154
+ "name": "my-tool",
155
+ "version": "1.0.0",
156
+ "description": "My awesome tool",
157
+ "entry": "run.ts",
158
+ "runtime": "node",
159
+ "commands": {
160
+ "hello": {
161
+ "description": "Say hello",
162
+ "args": [{ "name": "name", "required": false }]
163
+ }
267
164
  }
268
165
  }
269
166
  ```
270
167
 
271
- Set them in your shell or `.env` file.
168
+ ## Storage
169
+
170
+ ```
171
+ ~/.cli4ai/
172
+ ├── config.json # Global configuration
173
+ ├── packages/ # Globally installed packages
174
+ └── bin/ # PATH-linked executables
175
+
176
+ ./.cli4ai/
177
+ └── packages/ # Locally installed packages
178
+ ```
179
+
180
+ ## Requirements
181
+
182
+ - Node.js 18+
183
+ - npm or bun
184
+
185
+ ## Related
186
+
187
+ - [cli4ai/packages](https://github.com/cli4ai/packages) — Official tool packages
188
+ - [cli4ai/create-cli4ai](https://github.com/cli4ai/create-cli4ai) — Scaffold new tools
189
+ - [cli4ai.com](https://cli4ai.com) — Website and documentation
272
190
 
273
191
  ## License
274
192
 
275
- MIT
193
+ [BSL 1.1](./LICENSE) — Free for non-commercial use. Converts to Apache 2.0 on December 19, 2029.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cli4ai",
3
- "version": "0.9.2",
3
+ "version": "1.0.1",
4
4
  "description": "The package manager for AI CLI tools - cli4ai.com",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,7 +26,7 @@
26
26
  "vitest": "^2.0.0"
27
27
  },
28
28
  "author": "cliforai",
29
- "license": "MIT",
29
+ "license": "BUSL-1.1",
30
30
  "repository": {
31
31
  "type": "git",
32
32
  "url": "https://github.com/cliforai/framework"
package/src/bin.ts CHANGED
@@ -92,10 +92,8 @@ function checkUpdatesInBackground(): void {
92
92
  const packages = getNpmGlobalPackages();
93
93
  if (packages.length > 0) {
94
94
  // Spawn a background process to check updates and cache results
95
- const child = Bun.spawn(['sh', '-c', `
96
- # Quick npm check (with timeout)
97
- timeout 3 npm view cli4ai version 2>/dev/null > /tmp/.cli4ai-update-check 2>&1 &
98
- `], {
95
+ const { spawn } = require('child_process');
96
+ const child = spawn('sh', ['-c', 'timeout 3 npm view cli4ai version 2>/dev/null > /tmp/.cli4ai-update-check 2>&1 &'], {
99
97
  detached: true,
100
98
  stdio: ['ignore', 'ignore', 'ignore']
101
99
  });
@@ -18,6 +18,7 @@ import {
18
18
  } from '../core/config.js';
19
19
  import { lockPackage, computeDirectoryIntegrity, type LockedPackage } from '../core/lockfile.js';
20
20
  import { linkPackageDirect, isBinInPath, getPathInstructions } from '../core/link.js';
21
+ import { getRegistryIntegrity, verifyPackageIntegrity } from '../core/registry.js';
21
22
 
22
23
  interface AddOptions {
23
24
  local?: boolean;
@@ -217,11 +218,10 @@ async function downloadFromNpm(packageName: string, targetDir: string): Promise<
217
218
  /**
218
219
  * Check if a CLI tool is available
219
220
  */
220
- async function checkCliTool(name: string): Promise<boolean> {
221
+ function checkCliTool(name: string): boolean {
221
222
  try {
222
- const proc = Bun.spawn(['which', name], { stdout: 'pipe', stderr: 'pipe' });
223
- await proc.exited;
224
- return proc.exitCode === 0;
223
+ const result = spawnSync('which', [name], { stdio: 'pipe' });
224
+ return result.status === 0;
225
225
  } catch {
226
226
  return false;
227
227
  }
@@ -369,7 +369,7 @@ export async function addCommand(packages: string[], options: AddOptions): Promi
369
369
  for (const peer of plan.peerDependencies) {
370
370
  // Check if it's a CLI tool (not a cli4ai package reference)
371
371
  if (!peer.version.includes('cli4ai')) {
372
- const available = await checkCliTool(peer.name);
372
+ const available = checkCliTool(peer.name);
373
373
  if (!available) {
374
374
  peerWarnings.push(`${peer.name} is not installed on your system`);
375
375
  }
@@ -417,6 +417,27 @@ export async function addCommand(packages: string[], options: AddOptions): Promi
417
417
  await installNpmDependencies(result.path, plan.manifest.dependencies);
418
418
  }
419
419
 
420
+ // SECURITY: Verify integrity against registry
421
+ let integrity: string | undefined;
422
+ try {
423
+ const verification = await verifyPackageIntegrity(result.name, result.path);
424
+ integrity = verification.actual;
425
+
426
+ if (verification.expected) {
427
+ if (verification.valid) {
428
+ log(` integrity: ${integrity.slice(0, 20)}... ✓`);
429
+ } else {
430
+ log(` ⚠️ Integrity mismatch!`);
431
+ log(` Expected: ${verification.expected.slice(0, 30)}...`);
432
+ log(` Actual: ${verification.actual.slice(0, 30)}...`);
433
+ }
434
+ } else {
435
+ log(` integrity: ${integrity.slice(0, 20)}...`);
436
+ }
437
+ } catch (err) {
438
+ log(` warning: could not compute integrity hash`);
439
+ }
440
+
420
441
  // Link to PATH for global installs
421
442
  if (options.global) {
422
443
  result.binPath = linkPackageDirect(plan.manifest, result.path);
@@ -424,15 +445,6 @@ export async function addCommand(packages: string[], options: AddOptions): Promi
424
445
  } else {
425
446
  log(`✓ ${result.name}@${result.version}`);
426
447
 
427
- // SECURITY: Compute integrity hash for the installed package
428
- let integrity: string | undefined;
429
- try {
430
- integrity = computeDirectoryIntegrity(result.path);
431
- log(` integrity: ${integrity.slice(0, 20)}...`);
432
- } catch (err) {
433
- log(` warning: could not compute integrity hash`);
434
- }
435
-
436
448
  // Update lockfile (only for local/project installs)
437
449
  const lockedPkg: LockedPackage = {
438
450
  name: result.name,
@@ -146,7 +146,7 @@ function getBaseManifest(templateName: string, runtime: 'node' | 'bun'): Partial
146
146
  runtime,
147
147
  description: `${templateName === 'basic' ? 'CLI' : templateName} tool`,
148
148
  author,
149
- license: 'MIT',
149
+ license: 'BUSL-1.1',
150
150
  keywords,
151
151
  mcp: { enabled: true, transport: 'stdio' },
152
152
  };