@agentuity/cli 1.0.7 → 1.0.9
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/cli.d.ts.map +1 -1
- package/dist/cli.js +32 -4
- package/dist/cli.js.map +1 -1
- package/dist/cmd/ai/claude-code/constants.d.ts +13 -0
- package/dist/cmd/ai/claude-code/constants.d.ts.map +1 -0
- package/dist/cmd/ai/claude-code/constants.js +16 -0
- package/dist/cmd/ai/claude-code/constants.js.map +1 -0
- package/dist/cmd/ai/claude-code/index.d.ts +3 -0
- package/dist/cmd/ai/claude-code/index.d.ts.map +1 -0
- package/dist/cmd/ai/claude-code/index.js +22 -0
- package/dist/cmd/ai/claude-code/index.js.map +1 -0
- package/dist/cmd/ai/claude-code/install.d.ts +3 -0
- package/dist/cmd/ai/claude-code/install.d.ts.map +1 -0
- package/dist/cmd/ai/claude-code/install.js +133 -0
- package/dist/cmd/ai/claude-code/install.js.map +1 -0
- package/dist/cmd/ai/claude-code/uninstall.d.ts +3 -0
- package/dist/cmd/ai/claude-code/uninstall.d.ts.map +1 -0
- package/dist/cmd/ai/claude-code/uninstall.js +105 -0
- package/dist/cmd/ai/claude-code/uninstall.js.map +1 -0
- package/dist/cmd/ai/index.d.ts.map +1 -1
- package/dist/cmd/ai/index.js +6 -0
- package/dist/cmd/ai/index.js.map +1 -1
- package/dist/cmd/build/vite/db-rewrite.d.ts +50 -0
- package/dist/cmd/build/vite/db-rewrite.d.ts.map +1 -0
- package/dist/cmd/build/vite/db-rewrite.js +169 -0
- package/dist/cmd/build/vite/db-rewrite.js.map +1 -0
- package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/registry-generator.js +7 -0
- package/dist/cmd/build/vite/registry-generator.js.map +1 -1
- package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -1
- package/dist/cmd/build/vite/server-bundler.js +71 -1
- package/dist/cmd/build/vite/server-bundler.js.map +1 -1
- package/dist/cmd/canary/index.d.ts.map +1 -1
- package/dist/cmd/canary/index.js +3 -1
- package/dist/cmd/canary/index.js.map +1 -1
- package/dist/cmd/cloud/agent/list.d.ts.map +1 -1
- package/dist/cmd/cloud/agent/list.js +17 -4
- package/dist/cmd/cloud/agent/list.js.map +1 -1
- package/dist/cmd/cloud/apikey/list.d.ts.map +1 -1
- package/dist/cmd/cloud/apikey/list.js +3 -0
- package/dist/cmd/cloud/apikey/list.js.map +1 -1
- package/dist/cmd/cloud/db/list.d.ts.map +1 -1
- package/dist/cmd/cloud/db/list.js +2 -1
- package/dist/cmd/cloud/db/list.js.map +1 -1
- package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/list.js +14 -6
- package/dist/cmd/cloud/deployment/list.js.map +1 -1
- package/dist/cmd/cloud/deployment/remove.js +2 -2
- package/dist/cmd/cloud/deployment/remove.js.map +1 -1
- package/dist/cmd/cloud/deployment/rollback.js +2 -2
- package/dist/cmd/cloud/deployment/rollback.js.map +1 -1
- package/dist/cmd/cloud/deployment/show.js +2 -2
- package/dist/cmd/cloud/deployment/show.js.map +1 -1
- package/dist/cmd/cloud/deployment/undeploy.js +2 -2
- package/dist/cmd/cloud/deployment/undeploy.js.map +1 -1
- package/dist/cmd/cloud/env/list.d.ts.map +1 -1
- package/dist/cmd/cloud/env/list.js +14 -4
- package/dist/cmd/cloud/env/list.js.map +1 -1
- package/dist/cmd/cloud/eval/list.d.ts.map +1 -1
- package/dist/cmd/cloud/eval/list.js +6 -1
- package/dist/cmd/cloud/eval/list.js.map +1 -1
- package/dist/cmd/cloud/eval-run/list.d.ts.map +1 -1
- package/dist/cmd/cloud/eval-run/list.js +6 -1
- package/dist/cmd/cloud/eval-run/list.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/list-namespaces.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/list-namespaces.js +5 -2
- package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/util.d.ts +1 -1
- package/dist/cmd/cloud/keyvalue/util.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/util.js +3 -2
- package/dist/cmd/cloud/keyvalue/util.js.map +1 -1
- package/dist/cmd/cloud/machine/list.d.ts.map +1 -1
- package/dist/cmd/cloud/machine/list.js +5 -2
- package/dist/cmd/cloud/machine/list.js.map +1 -1
- package/dist/cmd/cloud/queue/list.d.ts.map +1 -1
- package/dist/cmd/cloud/queue/list.js +3 -1
- package/dist/cmd/cloud/queue/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.js +5 -3
- package/dist/cmd/cloud/sandbox/execution/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/list.js +4 -1
- package/dist/cmd/cloud/sandbox/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/runtime/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/runtime/list.js +4 -2
- package/dist/cmd/cloud/sandbox/runtime/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.js +4 -2
- package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
- package/dist/cmd/cloud/session/list.d.ts.map +1 -1
- package/dist/cmd/cloud/session/list.js +6 -1
- package/dist/cmd/cloud/session/list.js.map +1 -1
- package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/list.js +2 -1
- package/dist/cmd/cloud/storage/list.js.map +1 -1
- package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/list.js +5 -2
- package/dist/cmd/cloud/stream/list.js.map +1 -1
- package/dist/cmd/cloud/thread/list.d.ts.map +1 -1
- package/dist/cmd/cloud/thread/list.js +4 -1
- package/dist/cmd/cloud/thread/list.js.map +1 -1
- package/dist/cmd/cloud/vector/list-namespaces.d.ts.map +1 -1
- package/dist/cmd/cloud/vector/list-namespaces.js +5 -2
- package/dist/cmd/cloud/vector/list-namespaces.js.map +1 -1
- package/dist/cmd/cloud/vector/util.d.ts +1 -1
- package/dist/cmd/cloud/vector/util.d.ts.map +1 -1
- package/dist/cmd/cloud/vector/util.js +3 -2
- package/dist/cmd/cloud/vector/util.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +2 -0
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/project/add/database.d.ts.map +1 -1
- package/dist/cmd/project/add/database.js +43 -3
- package/dist/cmd/project/add/database.js.map +1 -1
- package/dist/cmd/project/add/storage.d.ts.map +1 -1
- package/dist/cmd/project/add/storage.js +43 -3
- package/dist/cmd/project/add/storage.js.map +1 -1
- package/dist/cmd/upgrade/index.d.ts.map +1 -1
- package/dist/cmd/upgrade/index.js +25 -10
- package/dist/cmd/upgrade/index.js.map +1 -1
- package/dist/cmd/upgrade/npm-availability.d.ts +45 -12
- package/dist/cmd/upgrade/npm-availability.d.ts.map +1 -1
- package/dist/cmd/upgrade/npm-availability.js +73 -26
- package/dist/cmd/upgrade/npm-availability.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +15 -2
- package/dist/version-check.js.map +1 -1
- package/package.json +6 -6
- package/src/cli.ts +41 -4
- package/src/cmd/ai/claude-code/constants.ts +26 -0
- package/src/cmd/ai/claude-code/index.ts +23 -0
- package/src/cmd/ai/claude-code/install.ts +181 -0
- package/src/cmd/ai/claude-code/uninstall.ts +122 -0
- package/src/cmd/ai/index.ts +6 -0
- package/src/cmd/build/vite/db-rewrite.ts +189 -0
- package/src/cmd/build/vite/registry-generator.ts +7 -0
- package/src/cmd/build/vite/server-bundler.ts +89 -3
- package/src/cmd/canary/index.ts +3 -1
- package/src/cmd/cloud/agent/list.ts +19 -4
- package/src/cmd/cloud/apikey/list.ts +4 -0
- package/src/cmd/cloud/db/list.ts +2 -1
- package/src/cmd/cloud/deployment/list.ts +16 -6
- package/src/cmd/cloud/deployment/remove.ts +2 -2
- package/src/cmd/cloud/deployment/rollback.ts +2 -2
- package/src/cmd/cloud/deployment/show.ts +2 -2
- package/src/cmd/cloud/deployment/undeploy.ts +2 -2
- package/src/cmd/cloud/env/list.ts +17 -4
- package/src/cmd/cloud/eval/list.ts +7 -1
- package/src/cmd/cloud/eval-run/list.ts +7 -1
- package/src/cmd/cloud/keyvalue/list-namespaces.ts +5 -2
- package/src/cmd/cloud/keyvalue/util.ts +12 -8
- package/src/cmd/cloud/machine/list.ts +5 -2
- package/src/cmd/cloud/queue/list.ts +3 -1
- package/src/cmd/cloud/sandbox/execution/list.ts +11 -3
- package/src/cmd/cloud/sandbox/list.ts +5 -1
- package/src/cmd/cloud/sandbox/runtime/list.ts +4 -2
- package/src/cmd/cloud/sandbox/snapshot/list.ts +4 -2
- package/src/cmd/cloud/session/list.ts +7 -1
- package/src/cmd/cloud/storage/list.ts +2 -1
- package/src/cmd/cloud/stream/list.ts +7 -2
- package/src/cmd/cloud/thread/list.ts +5 -1
- package/src/cmd/cloud/vector/list-namespaces.ts +5 -2
- package/src/cmd/cloud/vector/util.ts +12 -8
- package/src/cmd/dev/index.ts +2 -0
- package/src/cmd/project/add/database.ts +54 -3
- package/src/cmd/project/add/storage.ts +54 -3
- package/src/cmd/upgrade/index.ts +36 -11
- package/src/cmd/upgrade/npm-availability.ts +106 -36
- package/src/version-check.ts +22 -2
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
export interface ClaudeSettings {
|
|
5
|
+
permissions?: {
|
|
6
|
+
allow?: string[];
|
|
7
|
+
deny?: string[];
|
|
8
|
+
};
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const CLAUDE_DIR = join(homedir(), '.claude');
|
|
13
|
+
export const CLAUDE_SETTINGS_FILE = join(CLAUDE_DIR, 'settings.local.json');
|
|
14
|
+
export const PLUGIN_INSTALL_DIR = join(homedir(), '.agentuity', 'plugins', 'claude-code');
|
|
15
|
+
|
|
16
|
+
export const AGENTUITY_ALLOW_PERMISSIONS = [
|
|
17
|
+
'Bash(agentuity cloud *)',
|
|
18
|
+
'Bash(agentuity auth whoami *)',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export const AGENTUITY_DENY_PERMISSIONS = [
|
|
22
|
+
'Bash(agentuity cloud secrets *)',
|
|
23
|
+
'Bash(agentuity cloud secret *)',
|
|
24
|
+
'Bash(agentuity cloud apikey *)',
|
|
25
|
+
'Bash(agentuity auth token *)',
|
|
26
|
+
];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createCommand } from '../../../types';
|
|
2
|
+
import { installSubcommand } from './install';
|
|
3
|
+
import { uninstallSubcommand } from './uninstall';
|
|
4
|
+
import { getCommand } from '../../../command-prefix';
|
|
5
|
+
|
|
6
|
+
export const command = createCommand({
|
|
7
|
+
name: 'claude-code',
|
|
8
|
+
description: 'Agentuity Coder plugin for Claude Code',
|
|
9
|
+
tags: ['fast'],
|
|
10
|
+
examples: [
|
|
11
|
+
{
|
|
12
|
+
command: getCommand('ai claude-code install'),
|
|
13
|
+
description: 'Install Agentuity Coder plugin for Claude Code',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
command: getCommand('ai claude-code uninstall'),
|
|
17
|
+
description: 'Uninstall Agentuity Coder plugin for Claude Code',
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
subcommands: [installSubcommand, uninstallSubcommand],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export default command;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { createSubcommand, type CommandContext } from '../../../types';
|
|
4
|
+
import * as tui from '../../../tui';
|
|
5
|
+
import { getCommand } from '../../../command-prefix';
|
|
6
|
+
import {
|
|
7
|
+
type ClaudeSettings,
|
|
8
|
+
CLAUDE_DIR,
|
|
9
|
+
CLAUDE_SETTINGS_FILE,
|
|
10
|
+
PLUGIN_INSTALL_DIR,
|
|
11
|
+
AGENTUITY_ALLOW_PERMISSIONS,
|
|
12
|
+
AGENTUITY_DENY_PERMISSIONS,
|
|
13
|
+
} from './constants';
|
|
14
|
+
|
|
15
|
+
async function readClaudeSettings(): Promise<ClaudeSettings> {
|
|
16
|
+
try {
|
|
17
|
+
if (await Bun.file(CLAUDE_SETTINGS_FILE).exists()) {
|
|
18
|
+
const content = readFileSync(CLAUDE_SETTINGS_FILE, 'utf-8');
|
|
19
|
+
return JSON.parse(content);
|
|
20
|
+
}
|
|
21
|
+
} catch {
|
|
22
|
+
// invalid or missing
|
|
23
|
+
}
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function writeClaudeSettings(settings: ClaudeSettings): void {
|
|
28
|
+
mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
29
|
+
writeFileSync(CLAUDE_SETTINGS_FILE, JSON.stringify(settings, null, 2) + '\n');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function configurePermissions(settings: ClaudeSettings): number {
|
|
33
|
+
if (!settings.permissions) {
|
|
34
|
+
settings.permissions = {};
|
|
35
|
+
}
|
|
36
|
+
if (!settings.permissions.allow) {
|
|
37
|
+
settings.permissions.allow = [];
|
|
38
|
+
}
|
|
39
|
+
if (!settings.permissions.deny) {
|
|
40
|
+
settings.permissions.deny = [];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let added = 0;
|
|
44
|
+
|
|
45
|
+
for (const perm of AGENTUITY_ALLOW_PERMISSIONS) {
|
|
46
|
+
if (!settings.permissions.allow.includes(perm)) {
|
|
47
|
+
settings.permissions.allow.push(perm);
|
|
48
|
+
added++;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (const perm of AGENTUITY_DENY_PERMISSIONS) {
|
|
53
|
+
if (!settings.permissions.deny.includes(perm)) {
|
|
54
|
+
settings.permissions.deny.push(perm);
|
|
55
|
+
added++;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return added;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function installPackage(logger: { debug: (msg: string) => void }): Promise<string | null> {
|
|
63
|
+
mkdirSync(PLUGIN_INSTALL_DIR, { recursive: true });
|
|
64
|
+
|
|
65
|
+
const packageJsonPath = join(PLUGIN_INSTALL_DIR, 'package.json');
|
|
66
|
+
if (!(await Bun.file(packageJsonPath).exists())) {
|
|
67
|
+
writeFileSync(
|
|
68
|
+
packageJsonPath,
|
|
69
|
+
JSON.stringify({ name: 'agentuity-claude-code-plugin', private: true }, null, 2)
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
logger.debug(`Installing @agentuity/claude-code to ${PLUGIN_INSTALL_DIR}`);
|
|
74
|
+
|
|
75
|
+
const proc = Bun.spawn(['bun', 'add', '@agentuity/claude-code@latest'], {
|
|
76
|
+
cwd: PLUGIN_INSTALL_DIR,
|
|
77
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
await proc.exited;
|
|
81
|
+
|
|
82
|
+
const pluginPath = join(PLUGIN_INSTALL_DIR, 'node_modules', '@agentuity', 'claude-code');
|
|
83
|
+
if (await Bun.file(join(pluginPath, '.claude-plugin', 'plugin.json')).exists()) {
|
|
84
|
+
return pluginPath;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const installSubcommand = createSubcommand({
|
|
91
|
+
name: 'install',
|
|
92
|
+
description: 'Install Agentuity Coder plugin for Claude Code',
|
|
93
|
+
tags: ['fast'],
|
|
94
|
+
requires: { auth: true, apiClient: true, org: true },
|
|
95
|
+
examples: [
|
|
96
|
+
{
|
|
97
|
+
command: getCommand('ai claude-code install'),
|
|
98
|
+
description: 'Install Agentuity Coder plugin for Claude Code',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
async handler(ctx: CommandContext<{ auth: true; apiClient: true; org: true }>) {
|
|
102
|
+
const { options, orgId, logger } = ctx;
|
|
103
|
+
const jsonMode = !!options?.json;
|
|
104
|
+
|
|
105
|
+
if (!jsonMode) {
|
|
106
|
+
tui.newline();
|
|
107
|
+
tui.output(tui.bold('Installing Agentuity Coder plugin for Claude Code'));
|
|
108
|
+
tui.newline();
|
|
109
|
+
tui.success(`Using organization: ${orgId}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!jsonMode) {
|
|
113
|
+
tui.info('Installing @agentuity/claude-code package...');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const pluginPath = await installPackage(logger);
|
|
117
|
+
|
|
118
|
+
if (!pluginPath) {
|
|
119
|
+
if (jsonMode) {
|
|
120
|
+
return { success: false, orgId, error: 'Failed to install package' };
|
|
121
|
+
}
|
|
122
|
+
logger.fatal(
|
|
123
|
+
'Failed to install @agentuity/claude-code package. Make sure bun is installed and try again'
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!jsonMode) {
|
|
128
|
+
tui.success(`Plugin installed to: ${pluginPath}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const settings = await readClaudeSettings();
|
|
132
|
+
|
|
133
|
+
const permissionsAdded = configurePermissions(settings);
|
|
134
|
+
if (permissionsAdded > 0) {
|
|
135
|
+
if (!jsonMode) {
|
|
136
|
+
tui.success(
|
|
137
|
+
`Configured ${permissionsAdded} permission rules for Agentuity Cloud commands`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
if (!jsonMode) {
|
|
142
|
+
tui.info('Permissions already configured');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
writeClaudeSettings(settings);
|
|
147
|
+
|
|
148
|
+
if (!jsonMode) {
|
|
149
|
+
tui.newline();
|
|
150
|
+
tui.output(tui.bold('Agentuity Coder plugin installed successfully!'));
|
|
151
|
+
tui.newline();
|
|
152
|
+
|
|
153
|
+
tui.info('To use the plugin, start Claude Code with:');
|
|
154
|
+
tui.output(` ${tui.ICONS.bullet} ${tui.bold(`claude --plugin-dir ${pluginPath}`)}`);
|
|
155
|
+
tui.newline();
|
|
156
|
+
|
|
157
|
+
tui.info('Or install permanently via the Claude Code marketplace:');
|
|
158
|
+
tui.output(` ${tui.ICONS.bullet} ${tui.bold('/plugin marketplace add agentuity/sdk')}`);
|
|
159
|
+
tui.output(
|
|
160
|
+
` ${tui.ICONS.bullet} ${tui.bold('/plugin install agentuity-coder@agentuity')}`
|
|
161
|
+
);
|
|
162
|
+
tui.newline();
|
|
163
|
+
|
|
164
|
+
tui.info('Available commands in Claude Code:');
|
|
165
|
+
tui.output(
|
|
166
|
+
` ${tui.ICONS.bullet} ${tui.muted('/agentuity-coder')} - Run a task with the agent team`
|
|
167
|
+
);
|
|
168
|
+
tui.output(
|
|
169
|
+
` ${tui.ICONS.bullet} ${tui.muted('/agentuity-cadence')} - Start autonomous long-running task`
|
|
170
|
+
);
|
|
171
|
+
tui.output(
|
|
172
|
+
` ${tui.ICONS.bullet} ${tui.muted('/agentuity-memory-save')} - Save session context to memory`
|
|
173
|
+
);
|
|
174
|
+
tui.newline();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return { success: true, orgId, pluginPath };
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
export default installSubcommand;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, rmSync } from 'node:fs';
|
|
2
|
+
import { createSubcommand, type CommandContext } from '../../../types';
|
|
3
|
+
import * as tui from '../../../tui';
|
|
4
|
+
import { getCommand } from '../../../command-prefix';
|
|
5
|
+
import {
|
|
6
|
+
type ClaudeSettings,
|
|
7
|
+
CLAUDE_SETTINGS_FILE,
|
|
8
|
+
PLUGIN_INSTALL_DIR,
|
|
9
|
+
AGENTUITY_ALLOW_PERMISSIONS,
|
|
10
|
+
AGENTUITY_DENY_PERMISSIONS,
|
|
11
|
+
} from './constants';
|
|
12
|
+
|
|
13
|
+
export const uninstallSubcommand = createSubcommand({
|
|
14
|
+
name: 'uninstall',
|
|
15
|
+
description: 'Uninstall Agentuity Coder plugin for Claude Code',
|
|
16
|
+
tags: ['fast'],
|
|
17
|
+
examples: [
|
|
18
|
+
{
|
|
19
|
+
command: getCommand('ai claude-code uninstall'),
|
|
20
|
+
description: 'Uninstall Agentuity Coder plugin for Claude Code',
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
async handler(ctx: CommandContext) {
|
|
24
|
+
const { options } = ctx;
|
|
25
|
+
const jsonMode = !!options?.json;
|
|
26
|
+
|
|
27
|
+
if (!jsonMode) {
|
|
28
|
+
tui.newline();
|
|
29
|
+
tui.output(tui.bold('Uninstalling Agentuity Coder plugin for Claude Code'));
|
|
30
|
+
tui.newline();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let removedPlugin = false;
|
|
34
|
+
let removedPermissions = false;
|
|
35
|
+
|
|
36
|
+
if (await Bun.file(`${PLUGIN_INSTALL_DIR}/package.json`).exists()) {
|
|
37
|
+
try {
|
|
38
|
+
rmSync(PLUGIN_INSTALL_DIR, { recursive: true, force: true });
|
|
39
|
+
removedPlugin = true;
|
|
40
|
+
if (!jsonMode) {
|
|
41
|
+
tui.success('Removed plugin installation directory');
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (!jsonMode) {
|
|
45
|
+
tui.warning(`Failed to remove plugin directory: ${error}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
if (!jsonMode) {
|
|
50
|
+
tui.info('Plugin installation directory not found - nothing to remove');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (await Bun.file(CLAUDE_SETTINGS_FILE).exists()) {
|
|
55
|
+
try {
|
|
56
|
+
const content = readFileSync(CLAUDE_SETTINGS_FILE, 'utf-8');
|
|
57
|
+
const settings: ClaudeSettings = JSON.parse(content);
|
|
58
|
+
|
|
59
|
+
if (settings.permissions) {
|
|
60
|
+
const allPerms = [...AGENTUITY_ALLOW_PERMISSIONS, ...AGENTUITY_DENY_PERMISSIONS];
|
|
61
|
+
|
|
62
|
+
if (settings.permissions.allow) {
|
|
63
|
+
const originalAllowLen = settings.permissions.allow.length;
|
|
64
|
+
settings.permissions.allow = settings.permissions.allow.filter(
|
|
65
|
+
(p) => !allPerms.includes(p)
|
|
66
|
+
);
|
|
67
|
+
if (settings.permissions.allow.length < originalAllowLen) {
|
|
68
|
+
removedPermissions = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (settings.permissions.deny) {
|
|
73
|
+
const originalDenyLen = settings.permissions.deny.length;
|
|
74
|
+
settings.permissions.deny = settings.permissions.deny.filter(
|
|
75
|
+
(p) => !allPerms.includes(p)
|
|
76
|
+
);
|
|
77
|
+
if (settings.permissions.deny.length < originalDenyLen) {
|
|
78
|
+
removedPermissions = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (removedPermissions) {
|
|
83
|
+
writeFileSync(CLAUDE_SETTINGS_FILE, JSON.stringify(settings, null, 2) + '\n');
|
|
84
|
+
if (!jsonMode) {
|
|
85
|
+
tui.success('Removed Agentuity permissions from Claude Code settings');
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
if (!jsonMode) {
|
|
89
|
+
tui.info('No Agentuity permissions found in Claude Code settings');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (!jsonMode) {
|
|
95
|
+
tui.warning(`Failed to update Claude Code settings: ${error}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
if (!jsonMode) {
|
|
100
|
+
tui.info('Claude Code settings file not found');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!jsonMode) {
|
|
105
|
+
tui.newline();
|
|
106
|
+
|
|
107
|
+
if (removedPlugin || removedPermissions) {
|
|
108
|
+
tui.output(tui.bold('Agentuity Coder plugin uninstalled successfully'));
|
|
109
|
+
} else {
|
|
110
|
+
tui.output(tui.bold('Agentuity Coder plugin was not installed'));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
tui.newline();
|
|
114
|
+
tui.info(`To reinstall, run: ${tui.bold(getCommand('ai claude-code install'))}`);
|
|
115
|
+
tui.newline();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return { success: true, removedPlugin, removedPermissions };
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
export default uninstallSubcommand;
|
package/src/cmd/ai/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import capabilitiesCommand from './capabilities';
|
|
|
3
3
|
import promptCommand from './prompt';
|
|
4
4
|
import schemaCommand from './schema';
|
|
5
5
|
import opencodeCommand from './opencode';
|
|
6
|
+
import claudeCodeCommand from './claude-code';
|
|
6
7
|
import introSubcommand from './intro';
|
|
7
8
|
import detectSubcommand from './detect';
|
|
8
9
|
import { getCommand } from '../../command-prefix';
|
|
@@ -25,6 +26,10 @@ export const command = createCommand({
|
|
|
25
26
|
command: getCommand('ai opencode install'),
|
|
26
27
|
description: 'Install Agentuity Open Code plugin',
|
|
27
28
|
},
|
|
29
|
+
{
|
|
30
|
+
command: getCommand('ai claude-code install'),
|
|
31
|
+
description: 'Install Agentuity Coder plugin for Claude Code',
|
|
32
|
+
},
|
|
28
33
|
{
|
|
29
34
|
command: getCommand('ai capabilities show'),
|
|
30
35
|
description: 'Show CLI capabilities for AI agents',
|
|
@@ -38,6 +43,7 @@ export const command = createCommand({
|
|
|
38
43
|
detectSubcommand,
|
|
39
44
|
introSubcommand,
|
|
40
45
|
opencodeCommand,
|
|
46
|
+
claudeCodeCommand,
|
|
41
47
|
capabilitiesCommand,
|
|
42
48
|
promptCommand,
|
|
43
49
|
schemaCommand,
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DB import rewriting helpers for the Bun.build plugin.
|
|
3
|
+
*
|
|
4
|
+
* These functions rewrite `import { SQL } from 'bun'` → `@agentuity/postgres`
|
|
5
|
+
* and `import { Pool } from 'pg'` → `@agentuity/postgres` so that
|
|
6
|
+
* the Agentuity resilient postgres driver is bundled into the server output.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Map a file path to the appropriate Bun loader based on extension.
|
|
11
|
+
*/
|
|
12
|
+
export const getLoaderForPath = (filePath: string): string => {
|
|
13
|
+
if (filePath.endsWith('.tsx')) return 'tsx';
|
|
14
|
+
if (filePath.endsWith('.jsx')) return 'jsx';
|
|
15
|
+
if (filePath.endsWith('.ts')) return 'ts';
|
|
16
|
+
if (filePath.endsWith('.mts') || filePath.endsWith('.cts')) return 'ts';
|
|
17
|
+
if (filePath.endsWith('.js')) return 'js';
|
|
18
|
+
if (filePath.endsWith('.mjs')) return 'js';
|
|
19
|
+
if (filePath.endsWith('.cjs')) return 'js';
|
|
20
|
+
return 'js';
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Split named import/export specifiers, moving the `targetName` specifier
|
|
25
|
+
* to the `move` list while leaving everything else in `stay`.
|
|
26
|
+
*
|
|
27
|
+
* Type-only specifiers (prefixed with `type `) always stay.
|
|
28
|
+
* Aliases (`SQL as Foo`) are matched on the import name, not the alias.
|
|
29
|
+
*/
|
|
30
|
+
export const rewriteNamedSpecifiers = (
|
|
31
|
+
specifiers: string,
|
|
32
|
+
targetName: string
|
|
33
|
+
): {
|
|
34
|
+
stay: string[];
|
|
35
|
+
move: string[];
|
|
36
|
+
moved: boolean;
|
|
37
|
+
} => {
|
|
38
|
+
const stay: string[] = [];
|
|
39
|
+
const move: string[] = [];
|
|
40
|
+
for (const raw of specifiers.split(',')) {
|
|
41
|
+
const spec = raw.trim();
|
|
42
|
+
if (!spec) continue;
|
|
43
|
+
const isType = spec.startsWith('type ');
|
|
44
|
+
const specText = isType ? spec.slice(5).trim() : spec;
|
|
45
|
+
const [importName] = specText.split(/\s+as\s+/);
|
|
46
|
+
if (!isType && importName === targetName) {
|
|
47
|
+
move.push(specText);
|
|
48
|
+
} else {
|
|
49
|
+
stay.push(spec);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { stay, move, moved: move.length > 0 };
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Rewrite `import { SQL } from 'bun'` → `import { SQL } from '@agentuity/postgres'`.
|
|
58
|
+
*
|
|
59
|
+
* - Type-only imports (`import type { SQL }`) are left untouched.
|
|
60
|
+
* - Inline type specifiers (`import { type SQL }`) are left untouched.
|
|
61
|
+
* - Mixed imports are split: non-SQL specifiers stay with `'bun'`.
|
|
62
|
+
* - Works with both single and double quotes, with or without semicolons.
|
|
63
|
+
* - Preserves leading indentation.
|
|
64
|
+
*/
|
|
65
|
+
export const rewriteBunImports = (contents: string): { contents: string; changed: boolean } => {
|
|
66
|
+
const bunNamedRegex =
|
|
67
|
+
/(^|\n)([\t ]*)(import|export)\s+(type\s+)?\{([^}]+)\}\s+from\s+(['"])bun\6\s*;?/g;
|
|
68
|
+
let changed = false;
|
|
69
|
+
const updated = contents.replace(
|
|
70
|
+
bunNamedRegex,
|
|
71
|
+
(match, prefix, indent, keyword, typeKeyword, specifiers) => {
|
|
72
|
+
if (typeKeyword) {
|
|
73
|
+
return match;
|
|
74
|
+
}
|
|
75
|
+
const { stay, move, moved } = rewriteNamedSpecifiers(specifiers, 'SQL');
|
|
76
|
+
if (!moved) {
|
|
77
|
+
return match;
|
|
78
|
+
}
|
|
79
|
+
changed = true;
|
|
80
|
+
const statements: string[] = [];
|
|
81
|
+
if (stay.length > 0) {
|
|
82
|
+
statements.push(`${indent}${keyword} { ${stay.join(', ')} } from 'bun';`);
|
|
83
|
+
}
|
|
84
|
+
if (move.length > 0) {
|
|
85
|
+
statements.push(
|
|
86
|
+
`${indent}${keyword} { ${move.join(', ')} } from '@agentuity/postgres';`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return `${prefix}${statements.join('\n')}`;
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return { contents: updated, changed };
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Rewrite `import { Pool } from 'pg'` → `import { Pool } from '@agentuity/postgres'`.
|
|
98
|
+
*
|
|
99
|
+
* - Type-only imports (`import type { Pool }`) are left untouched.
|
|
100
|
+
* - Namespace imports (`import * as pg`) are left untouched.
|
|
101
|
+
* - Default imports (`import pg from 'pg'`) are left untouched.
|
|
102
|
+
* - Mixed default+named imports are split correctly.
|
|
103
|
+
* - Works with both `import` and `export` statements.
|
|
104
|
+
*/
|
|
105
|
+
export const rewritePgImports = (contents: string): { contents: string; changed: boolean } => {
|
|
106
|
+
const importRegex = /(^|\n)([\t ]*)(import)\s+(type\s+)?([^;]+?)\s+from\s+(['"])pg\6\s*;?/g;
|
|
107
|
+
const exportRegex = /(^|\n)([\t ]*)(export)\s+(?!type\b)\{([^}]+)\}\s+from\s+(['"])pg\5\s*;?/g;
|
|
108
|
+
let changed = false;
|
|
109
|
+
|
|
110
|
+
const updatedImports = contents.replace(
|
|
111
|
+
importRegex,
|
|
112
|
+
(match, prefix, indent, keyword, typeKeyword, clause) => {
|
|
113
|
+
if (typeKeyword) {
|
|
114
|
+
return match; // import type { ... } from 'pg' — skip entirely
|
|
115
|
+
}
|
|
116
|
+
const trimmed = clause.trim();
|
|
117
|
+
if (trimmed.startsWith('*')) {
|
|
118
|
+
return match;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let defaultImport: string | undefined;
|
|
122
|
+
let namedSpecifiers: string | undefined;
|
|
123
|
+
if (trimmed.startsWith('{')) {
|
|
124
|
+
namedSpecifiers = trimmed.slice(1, trimmed.lastIndexOf('}'));
|
|
125
|
+
} else if (trimmed.includes('{')) {
|
|
126
|
+
const [defaultPart, rest] = trimmed.split('{', 2);
|
|
127
|
+
defaultImport = defaultPart.replace(/,\s*$/, '').trim();
|
|
128
|
+
namedSpecifiers = rest.slice(0, rest.lastIndexOf('}'));
|
|
129
|
+
} else {
|
|
130
|
+
defaultImport = trimmed;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const movedNamed = namedSpecifiers
|
|
134
|
+
? rewriteNamedSpecifiers(namedSpecifiers, 'Pool')
|
|
135
|
+
: { stay: [], move: [], moved: false };
|
|
136
|
+
const moveDefault = false; // Default import is the entire pg module, not Pool — keep it with 'pg'
|
|
137
|
+
const shouldMove = moveDefault || movedNamed.moved;
|
|
138
|
+
|
|
139
|
+
if (!shouldMove) {
|
|
140
|
+
return match;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
changed = true;
|
|
144
|
+
const statements: string[] = [];
|
|
145
|
+
const pgNamed = movedNamed.stay;
|
|
146
|
+
const postgresNamed = movedNamed.move;
|
|
147
|
+
const pgDefault = moveDefault ? undefined : defaultImport;
|
|
148
|
+
const postgresDefault = moveDefault ? defaultImport : undefined;
|
|
149
|
+
|
|
150
|
+
if (pgDefault || pgNamed.length > 0) {
|
|
151
|
+
const parts: string[] = [];
|
|
152
|
+
if (pgDefault) parts.push(pgDefault);
|
|
153
|
+
if (pgNamed.length > 0) parts.push(`{ ${pgNamed.join(', ')} }`);
|
|
154
|
+
statements.push(`${indent}${keyword} ${parts.join(', ')} from 'pg';`);
|
|
155
|
+
}
|
|
156
|
+
if (postgresDefault || postgresNamed.length > 0) {
|
|
157
|
+
const parts: string[] = [];
|
|
158
|
+
if (postgresDefault) parts.push(postgresDefault);
|
|
159
|
+
if (postgresNamed.length > 0) parts.push(`{ ${postgresNamed.join(', ')} }`);
|
|
160
|
+
statements.push(`${indent}${keyword} ${parts.join(', ')} from '@agentuity/postgres';`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return `${prefix}${statements.join('\n')}`;
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
const updatedExports = updatedImports.replace(
|
|
168
|
+
exportRegex,
|
|
169
|
+
(match, prefix, indent, keyword, specifiers) => {
|
|
170
|
+
const { stay, move, moved } = rewriteNamedSpecifiers(specifiers, 'Pool');
|
|
171
|
+
if (!moved) {
|
|
172
|
+
return match;
|
|
173
|
+
}
|
|
174
|
+
changed = true;
|
|
175
|
+
const statements: string[] = [];
|
|
176
|
+
if (stay.length > 0) {
|
|
177
|
+
statements.push(`${indent}${keyword} { ${stay.join(', ')} } from 'pg';`);
|
|
178
|
+
}
|
|
179
|
+
if (move.length > 0) {
|
|
180
|
+
statements.push(
|
|
181
|
+
`${indent}${keyword} { ${move.join(', ')} } from '@agentuity/postgres';`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return `${prefix}${statements.join('\n')}`;
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
return { contents: updatedExports, changed };
|
|
189
|
+
};
|
|
@@ -658,6 +658,13 @@ export async function generateRouteRegistry(
|
|
|
658
658
|
});
|
|
659
659
|
|
|
660
660
|
if (apiRoutes.length === 0 && websocketRoutes.length === 0 && sseRoutes.length === 0) {
|
|
661
|
+
// Clean up stale routes.ts from previous builds (issue #924)
|
|
662
|
+
// When all API routes are removed, the old file would reference deleted modules
|
|
663
|
+
const generatedDir = join(srcDir, 'generated');
|
|
664
|
+
const registryPath = join(generatedDir, 'routes.ts');
|
|
665
|
+
if (existsSync(registryPath)) {
|
|
666
|
+
unlinkSync(registryPath);
|
|
667
|
+
}
|
|
661
668
|
return;
|
|
662
669
|
}
|
|
663
670
|
|