myclaude-code 8.8.9 → 8.8.11
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/README.md +71 -878
- package/dist/cli.js +78 -76
- package/dist/login-redirect-command.js +36 -0
- package/dist/openai-responses-adapter.js +1241 -0
- package/dist/provider-command.js +427 -0
- package/dist/provider-setup.js +3621 -0
- package/dist/team-command.js +250 -0
- package/image.png +0 -0
- package/install.sh +18 -57
- package/package.json +18 -5
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { homedir } from 'node:os'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
|
|
5
|
+
function getClaudeConfigDir() {
|
|
6
|
+
return process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude')
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function getTeamsDir() {
|
|
10
|
+
return join(getClaudeConfigDir(), 'teams')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function buildNoTeamsText() {
|
|
14
|
+
return [
|
|
15
|
+
`No local agent teams were found under ${getTeamsDir()}.`,
|
|
16
|
+
'',
|
|
17
|
+
'This usually means no team has been created in this config directory yet.',
|
|
18
|
+
'Teams are created by the native TeamCreate workflow during an agent-teams session.',
|
|
19
|
+
'If you are using a GPT gateway through the Anthropic-compatible route, run `/provider validate` first to confirm that native tool calling is actually available.',
|
|
20
|
+
'',
|
|
21
|
+
'Next step:',
|
|
22
|
+
'1. Launch myclaude with `--agent-teams`.',
|
|
23
|
+
'2. Ask myclaude to create a real team, for example: `Create a team named demo-team with two teammates for this repo.`',
|
|
24
|
+
'',
|
|
25
|
+
'If you expected teams from another config root, check `CLAUDE_CONFIG_DIR`.',
|
|
26
|
+
].join('\n')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function sanitizeName(value) {
|
|
30
|
+
return String(value || '')
|
|
31
|
+
.replace(/[^a-zA-Z0-9]/g, '-')
|
|
32
|
+
.toLowerCase()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function readJsonFile(path) {
|
|
36
|
+
try {
|
|
37
|
+
if (!existsSync(path)) return null
|
|
38
|
+
const raw = readFileSync(path, 'utf8').trim()
|
|
39
|
+
if (!raw) return null
|
|
40
|
+
return JSON.parse(raw)
|
|
41
|
+
} catch {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getTeamConfigPath(teamName) {
|
|
47
|
+
return join(getTeamsDir(), sanitizeName(teamName), 'config.json')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getTeamSummaries() {
|
|
51
|
+
try {
|
|
52
|
+
const teamsDir = getTeamsDir()
|
|
53
|
+
if (!existsSync(teamsDir)) return []
|
|
54
|
+
const entries = readdirSync(teamsDir, { withFileTypes: true })
|
|
55
|
+
const summaries = []
|
|
56
|
+
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
if (!entry.isDirectory()) continue
|
|
59
|
+
const config = readJsonFile(join(teamsDir, entry.name, 'config.json'))
|
|
60
|
+
if (!config || !Array.isArray(config.members)) continue
|
|
61
|
+
|
|
62
|
+
const teammates = config.members.filter(
|
|
63
|
+
member => member && member.name !== 'team-lead',
|
|
64
|
+
)
|
|
65
|
+
const runningCount = teammates.filter(
|
|
66
|
+
member => member.isActive !== false,
|
|
67
|
+
).length
|
|
68
|
+
const idleCount = teammates.length - runningCount
|
|
69
|
+
|
|
70
|
+
summaries.push({
|
|
71
|
+
name: String(config.name || entry.name),
|
|
72
|
+
memberCount: teammates.length,
|
|
73
|
+
runningCount,
|
|
74
|
+
idleCount,
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return summaries.sort((left, right) => left.name.localeCompare(right.name))
|
|
79
|
+
} catch {
|
|
80
|
+
return []
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getCurrentTeamName(context) {
|
|
85
|
+
try {
|
|
86
|
+
return context?.getAppState?.()?.teamContext?.teamName || null
|
|
87
|
+
} catch {
|
|
88
|
+
return null
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function resolveTeamName(query) {
|
|
93
|
+
const normalizedQuery = String(query || '').trim().toLowerCase()
|
|
94
|
+
if (!normalizedQuery) return null
|
|
95
|
+
const teams = getTeamSummaries()
|
|
96
|
+
const exact = teams.find(team => team.name.toLowerCase() === normalizedQuery)
|
|
97
|
+
if (exact) return exact.name
|
|
98
|
+
return (
|
|
99
|
+
teams.find(team => team.name.toLowerCase().includes(normalizedQuery))?.name ??
|
|
100
|
+
null
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function getTeamDetails(teamName) {
|
|
105
|
+
const config = readJsonFile(getTeamConfigPath(teamName))
|
|
106
|
+
if (!config || !Array.isArray(config.members)) return null
|
|
107
|
+
const teammates = config.members.filter(
|
|
108
|
+
member => member && member.name !== 'team-lead',
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
name: String(config.name || teamName),
|
|
113
|
+
configPath: getTeamConfigPath(teamName),
|
|
114
|
+
teammates: teammates.map(member => ({
|
|
115
|
+
name: String(member.name || 'unknown'),
|
|
116
|
+
agentType: member.agentType ? String(member.agentType) : null,
|
|
117
|
+
model: member.model ? String(member.model) : null,
|
|
118
|
+
status: member.isActive === false ? 'idle' : 'running',
|
|
119
|
+
})),
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function buildHelpText() {
|
|
124
|
+
return [
|
|
125
|
+
'Usage: /team [list|current|status [name]|show [name]|help]',
|
|
126
|
+
'',
|
|
127
|
+
`Show real local agent-team status from ${getTeamsDir()}.`,
|
|
128
|
+
'',
|
|
129
|
+
'Examples:',
|
|
130
|
+
' /team',
|
|
131
|
+
' /team list',
|
|
132
|
+
' /team current',
|
|
133
|
+
' /team status myteam',
|
|
134
|
+
' /team show myteam',
|
|
135
|
+
'',
|
|
136
|
+
'To activate live agent-team workflows in a new session, launch myclaude with',
|
|
137
|
+
'`--agent-teams` or set `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` before start.',
|
|
138
|
+
].join('\n')
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function formatTeamLine(team) {
|
|
142
|
+
return `${team.name} · ${team.memberCount} teammates · ${team.runningCount} running · ${team.idleCount} idle`
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function formatTeamStatus(teamName) {
|
|
146
|
+
const details = getTeamDetails(teamName)
|
|
147
|
+
if (!details) {
|
|
148
|
+
return `No team named '${teamName}' was found under ${getTeamsDir()}.`
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const sections = [
|
|
152
|
+
`Team: ${details.name}`,
|
|
153
|
+
`Config: ${details.configPath}`,
|
|
154
|
+
`Teammates: ${details.teammates.length}`,
|
|
155
|
+
`Running: ${details.teammates.filter(member => member.status === 'running').length}`,
|
|
156
|
+
`Idle: ${details.teammates.filter(member => member.status === 'idle').length}`,
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
if (details.teammates.length === 0) {
|
|
160
|
+
sections.push('Members:\n- No teammates are currently registered.')
|
|
161
|
+
return sections.join('\n')
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
sections.push(
|
|
165
|
+
[
|
|
166
|
+
'Members:',
|
|
167
|
+
...details.teammates.map(member => {
|
|
168
|
+
const extras = [member.status, member.agentType, member.model].filter(
|
|
169
|
+
Boolean,
|
|
170
|
+
)
|
|
171
|
+
return `- ${member.name} · ${extras.join(' · ')}`
|
|
172
|
+
}),
|
|
173
|
+
].join('\n'),
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
return sections.join('\n')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function call(args, context) {
|
|
180
|
+
const trimmedArgs = String(args || '').trim()
|
|
181
|
+
|
|
182
|
+
if (
|
|
183
|
+
!trimmedArgs ||
|
|
184
|
+
trimmedArgs === 'help' ||
|
|
185
|
+
trimmedArgs === '--help' ||
|
|
186
|
+
trimmedArgs === '-h'
|
|
187
|
+
) {
|
|
188
|
+
const currentTeamName = getCurrentTeamName(context)
|
|
189
|
+
if (currentTeamName) {
|
|
190
|
+
return {
|
|
191
|
+
type: 'text',
|
|
192
|
+
value: formatTeamStatus(currentTeamName),
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const teams = getTeamSummaries()
|
|
197
|
+
if (teams.length > 0) {
|
|
198
|
+
return {
|
|
199
|
+
type: 'text',
|
|
200
|
+
value: ['Available teams:', ...teams.map(team => `- ${formatTeamLine(team)}`), '', buildHelpText()].join('\n'),
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
type: 'text',
|
|
206
|
+
value: [
|
|
207
|
+
buildNoTeamsText(),
|
|
208
|
+
'',
|
|
209
|
+
buildHelpText(),
|
|
210
|
+
].join('\n'),
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (trimmedArgs === 'list') {
|
|
215
|
+
const teams = getTeamSummaries()
|
|
216
|
+
return {
|
|
217
|
+
type: 'text',
|
|
218
|
+
value:
|
|
219
|
+
teams.length === 0
|
|
220
|
+
? buildNoTeamsText()
|
|
221
|
+
: ['Available teams:', ...teams.map(team => `- ${formatTeamLine(team)}`)].join('\n'),
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const statusMatch = trimmedArgs.match(/^(current|status|show)(?:\s+(.+))?$/i)
|
|
226
|
+
if (statusMatch) {
|
|
227
|
+
const explicitTeamName = statusMatch[2]?.trim()
|
|
228
|
+
const teamName =
|
|
229
|
+
explicitTeamName || getCurrentTeamName(context) || getTeamSummaries()[0]?.name
|
|
230
|
+
return {
|
|
231
|
+
type: 'text',
|
|
232
|
+
value: teamName
|
|
233
|
+
? formatTeamStatus(teamName)
|
|
234
|
+
: buildNoTeamsText(),
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const resolvedTeamName = resolveTeamName(trimmedArgs)
|
|
239
|
+
if (resolvedTeamName) {
|
|
240
|
+
return {
|
|
241
|
+
type: 'text',
|
|
242
|
+
value: formatTeamStatus(resolvedTeamName),
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
type: 'text',
|
|
248
|
+
value: `Unknown /team argument '${trimmedArgs}'. Run /team help for usage.`,
|
|
249
|
+
}
|
|
250
|
+
}
|
package/image.png
ADDED
|
Binary file
|
package/install.sh
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
INSTALL_ROOT="${MYCLAUDE_INSTALL_ROOT:-$HOME/.local/share/myclaude}"
|
|
6
|
-
BIN_DIR="${MYCLAUDE_BIN_DIR:-$HOME/.local/bin}"
|
|
4
|
+
PACKAGE="${MYCLAUDE_PACKAGE:-myclaude-code}"
|
|
7
5
|
VERSION_INPUT="${1:-${MYCLAUDE_VERSION:-latest}}"
|
|
8
|
-
ALIASES="${MYCLAUDE_ALIASES:-myclaude mycode claude}"
|
|
9
6
|
|
|
10
7
|
need_cmd() {
|
|
11
8
|
if ! command -v "$1" >/dev/null 2>&1; then
|
|
@@ -14,17 +11,6 @@ need_cmd() {
|
|
|
14
11
|
fi
|
|
15
12
|
}
|
|
16
13
|
|
|
17
|
-
detect_version() {
|
|
18
|
-
if [[ "$VERSION_INPUT" != "latest" ]]; then
|
|
19
|
-
printf '%s' "${VERSION_INPUT#v}"
|
|
20
|
-
return 0
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" \
|
|
24
|
-
| sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v\([^"]*\)".*/\1/p' \
|
|
25
|
-
| head -n 1
|
|
26
|
-
}
|
|
27
|
-
|
|
28
14
|
check_node() {
|
|
29
15
|
need_cmd node
|
|
30
16
|
|
|
@@ -36,58 +22,33 @@ check_node() {
|
|
|
36
22
|
fi
|
|
37
23
|
}
|
|
38
24
|
|
|
25
|
+
resolve_version() {
|
|
26
|
+
if [[ "$VERSION_INPUT" != "latest" ]]; then
|
|
27
|
+
printf '%s' "${VERSION_INPUT#v}"
|
|
28
|
+
return 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
npm view "$PACKAGE" version
|
|
32
|
+
}
|
|
33
|
+
|
|
39
34
|
main() {
|
|
40
|
-
need_cmd
|
|
41
|
-
need_cmd tar
|
|
42
|
-
need_cmd sed
|
|
35
|
+
need_cmd npm
|
|
43
36
|
check_node
|
|
44
37
|
|
|
45
|
-
case "$(uname -s)" in
|
|
46
|
-
Darwin|Linux) ;;
|
|
47
|
-
*)
|
|
48
|
-
printf 'This installer currently supports macOS and Linux only.\n' >&2
|
|
49
|
-
exit 1
|
|
50
|
-
;;
|
|
51
|
-
esac
|
|
52
|
-
|
|
53
38
|
local version
|
|
54
|
-
version="$(
|
|
39
|
+
version="$(resolve_version)"
|
|
55
40
|
if [[ -z "$version" ]]; then
|
|
56
|
-
printf 'Unable to determine the
|
|
41
|
+
printf 'Unable to determine the latest %s version from npm.\n' "$PACKAGE" >&2
|
|
57
42
|
exit 1
|
|
58
43
|
fi
|
|
59
44
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
local tmp_dir
|
|
63
|
-
tmp_dir="$(mktemp -d)"
|
|
64
|
-
trap 'rm -rf "$tmp_dir"' EXIT
|
|
65
|
-
|
|
66
|
-
printf 'Downloading myclaude %s...\n' "$version"
|
|
67
|
-
curl -fL "$download_url" -o "$tmp_dir/$asset"
|
|
68
|
-
|
|
69
|
-
tar -xzf "$tmp_dir/$asset" -C "$tmp_dir"
|
|
45
|
+
printf 'Installing %s@%s from npm...\n' "$PACKAGE" "$version"
|
|
46
|
+
npm install -g "${PACKAGE}@${version}" --force
|
|
70
47
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
mv "$tmp_dir/myclaude" "$INSTALL_ROOT/versions/$version"
|
|
74
|
-
|
|
75
|
-
ln -sfn "$INSTALL_ROOT/versions/$version" "$INSTALL_ROOT/current"
|
|
76
|
-
|
|
77
|
-
local alias_name
|
|
78
|
-
for alias_name in $ALIASES; do
|
|
79
|
-
ln -sfn "$INSTALL_ROOT/current/bin/$alias_name" "$BIN_DIR/$alias_name"
|
|
80
|
-
done
|
|
81
|
-
|
|
82
|
-
printf 'Installed myclaude %s to %s\n' "$version" "$INSTALL_ROOT/current"
|
|
83
|
-
printf 'Available commands: %s\n' "$ALIASES"
|
|
84
|
-
|
|
85
|
-
if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
|
|
86
|
-
printf 'Add %s to your PATH if needed:\n' "$BIN_DIR"
|
|
87
|
-
printf ' export PATH="%s:$PATH"\n' "$BIN_DIR"
|
|
88
|
-
fi
|
|
48
|
+
printf 'Installed %s@%s\n' "$PACKAGE" "$version"
|
|
49
|
+
printf 'Available commands: myclaude, mycode, claude\n'
|
|
89
50
|
|
|
90
|
-
|
|
51
|
+
myclaude --version || true
|
|
91
52
|
}
|
|
92
53
|
|
|
93
54
|
main "$@"
|
package/package.json
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myclaude-code",
|
|
3
|
-
"version": "8.8.
|
|
4
|
-
"description": "myclaude
|
|
3
|
+
"version": "8.8.11",
|
|
4
|
+
"description": "myclaude: fast-start AI coding CLI with no Claude Code login and quick third-party API setup",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"myclaude",
|
|
7
|
+
"mycode",
|
|
8
|
+
"cli",
|
|
9
|
+
"ai",
|
|
10
|
+
"anthropic-compatible",
|
|
11
|
+
"openrouter",
|
|
12
|
+
"glm",
|
|
13
|
+
"minimax",
|
|
14
|
+
"kimi"
|
|
15
|
+
],
|
|
5
16
|
"type": "module",
|
|
6
17
|
"bin": {
|
|
7
18
|
"myclaude": "dist/cli.js",
|
|
@@ -9,7 +20,8 @@
|
|
|
9
20
|
"claude": "dist/cli.js"
|
|
10
21
|
},
|
|
11
22
|
"files": [
|
|
12
|
-
"dist
|
|
23
|
+
"dist",
|
|
24
|
+
"image.png",
|
|
13
25
|
"README.md",
|
|
14
26
|
"install.sh"
|
|
15
27
|
],
|
|
@@ -19,7 +31,7 @@
|
|
|
19
31
|
},
|
|
20
32
|
"repository": {
|
|
21
33
|
"type": "git",
|
|
22
|
-
"url": "https://github.com/mycode699/myclaude-code.git"
|
|
34
|
+
"url": "git+https://github.com/mycode699/myclaude-code.git"
|
|
23
35
|
},
|
|
24
36
|
"publishConfig": {
|
|
25
37
|
"access": "public"
|
|
@@ -29,7 +41,8 @@
|
|
|
29
41
|
"build": "npm run prepare-src && node scripts/build.mjs",
|
|
30
42
|
"check": "npm run prepare-src && tsc --noEmit",
|
|
31
43
|
"start": "node dist/cli.js",
|
|
32
|
-
"package:release": "node scripts/package-release.mjs"
|
|
44
|
+
"package:release": "node scripts/package-release.mjs",
|
|
45
|
+
"verify:provider": "node scripts/verify-provider-route.mjs"
|
|
33
46
|
},
|
|
34
47
|
"engines": {
|
|
35
48
|
"node": ">=18.0.0"
|