@kaitranntt/ccs 3.4.6 → 4.1.0
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/.claude/agents/ccs-delegator.md +117 -0
- package/.claude/commands/ccs/glm/continue.md +22 -0
- package/.claude/commands/ccs/glm.md +22 -0
- package/.claude/commands/ccs/kimi/continue.md +22 -0
- package/.claude/commands/ccs/kimi.md +22 -0
- package/.claude/skills/ccs-delegation/SKILL.md +54 -0
- package/.claude/skills/ccs-delegation/references/README.md +24 -0
- package/.claude/skills/ccs-delegation/references/delegation-guidelines.md +99 -0
- package/.claude/skills/ccs-delegation/references/headless-workflow.md +174 -0
- package/.claude/skills/ccs-delegation/references/troubleshooting.md +268 -0
- package/README.ja.md +470 -146
- package/README.md +532 -145
- package/README.vi.md +484 -157
- package/VERSION +1 -1
- package/bin/auth/auth-commands.js +98 -13
- package/bin/auth/profile-detector.js +11 -6
- package/bin/ccs.js +148 -2
- package/bin/delegation/README.md +189 -0
- package/bin/delegation/delegation-handler.js +212 -0
- package/bin/delegation/headless-executor.js +617 -0
- package/bin/delegation/result-formatter.js +483 -0
- package/bin/delegation/session-manager.js +156 -0
- package/bin/delegation/settings-parser.js +109 -0
- package/bin/management/doctor.js +94 -1
- package/bin/utils/claude-symlink-manager.js +238 -0
- package/bin/utils/delegation-validator.js +154 -0
- package/bin/utils/error-codes.js +59 -0
- package/bin/utils/error-manager.js +38 -32
- package/bin/utils/helpers.js +65 -1
- package/bin/utils/progress-indicator.js +111 -0
- package/bin/utils/prompt.js +134 -0
- package/bin/utils/shell-completion.js +234 -0
- package/lib/ccs +575 -25
- package/lib/ccs.ps1 +381 -20
- package/lib/error-codes.ps1 +55 -0
- package/lib/error-codes.sh +63 -0
- package/lib/progress-indicator.ps1 +120 -0
- package/lib/progress-indicator.sh +117 -0
- package/lib/prompt.ps1 +109 -0
- package/lib/prompt.sh +99 -0
- package/package.json +2 -1
- package/scripts/completion/README.md +308 -0
- package/scripts/completion/ccs.bash +81 -0
- package/scripts/completion/ccs.fish +92 -0
- package/scripts/completion/ccs.ps1 +157 -0
- package/scripts/completion/ccs.zsh +130 -0
- package/scripts/postinstall.js +35 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { HeadlessExecutor } = require('./headless-executor');
|
|
5
|
+
const { SessionManager } = require('./session-manager');
|
|
6
|
+
const { ResultFormatter } = require('./result-formatter');
|
|
7
|
+
const { DelegationValidator } = require('../utils/delegation-validator');
|
|
8
|
+
const { SettingsParser } = require('./settings-parser');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Delegation command handler
|
|
12
|
+
* Routes -p flag commands to HeadlessExecutor with enhanced features
|
|
13
|
+
*/
|
|
14
|
+
class DelegationHandler {
|
|
15
|
+
/**
|
|
16
|
+
* Route delegation command
|
|
17
|
+
* @param {Array<string>} args - Full args array from ccs.js
|
|
18
|
+
*/
|
|
19
|
+
async route(args) {
|
|
20
|
+
try {
|
|
21
|
+
// 1. Parse args into { profile, prompt, options }
|
|
22
|
+
const parsed = this._parseArgs(args);
|
|
23
|
+
|
|
24
|
+
// 2. Detect special profiles (glm:continue, kimi:continue)
|
|
25
|
+
if (parsed.profile.includes(':continue')) {
|
|
26
|
+
return await this._handleContinue(parsed);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 3. Validate profile
|
|
30
|
+
this._validateProfile(parsed.profile);
|
|
31
|
+
|
|
32
|
+
// 4. Execute via HeadlessExecutor
|
|
33
|
+
const result = await HeadlessExecutor.execute(
|
|
34
|
+
parsed.profile,
|
|
35
|
+
parsed.prompt,
|
|
36
|
+
parsed.options
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// 5. Format and display results
|
|
40
|
+
const formatted = ResultFormatter.format(result);
|
|
41
|
+
console.log(formatted);
|
|
42
|
+
|
|
43
|
+
// 6. Exit with proper code
|
|
44
|
+
process.exit(result.exitCode || 0);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error(`[X] Delegation error: ${error.message}`);
|
|
47
|
+
if (process.env.CCS_DEBUG) {
|
|
48
|
+
console.error(error.stack);
|
|
49
|
+
}
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Handle continue command (resume last session)
|
|
56
|
+
* @param {Object} parsed - Parsed args
|
|
57
|
+
*/
|
|
58
|
+
async _handleContinue(parsed) {
|
|
59
|
+
const baseProfile = parsed.profile.replace(':continue', '');
|
|
60
|
+
|
|
61
|
+
// Get last session from SessionManager
|
|
62
|
+
const sessionMgr = new SessionManager();
|
|
63
|
+
const lastSession = sessionMgr.getLastSession(baseProfile);
|
|
64
|
+
|
|
65
|
+
if (!lastSession) {
|
|
66
|
+
console.error(`[X] No previous session found for ${baseProfile}`);
|
|
67
|
+
console.error(` Start a new session first with: ccs ${baseProfile} -p "task"`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Execute with resume flag
|
|
72
|
+
const result = await HeadlessExecutor.execute(
|
|
73
|
+
baseProfile,
|
|
74
|
+
parsed.prompt,
|
|
75
|
+
{
|
|
76
|
+
...parsed.options,
|
|
77
|
+
resumeSession: true,
|
|
78
|
+
sessionId: lastSession.sessionId
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const formatted = ResultFormatter.format(result);
|
|
83
|
+
console.log(formatted);
|
|
84
|
+
|
|
85
|
+
process.exit(result.exitCode || 0);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Parse args into structured format
|
|
90
|
+
* @param {Array<string>} args - Raw args
|
|
91
|
+
* @returns {Object} { profile, prompt, options }
|
|
92
|
+
*/
|
|
93
|
+
_parseArgs(args) {
|
|
94
|
+
// Extract profile (first non-flag arg or 'default')
|
|
95
|
+
const profile = this._extractProfile(args);
|
|
96
|
+
|
|
97
|
+
// Extract prompt from -p or --prompt
|
|
98
|
+
const prompt = this._extractPrompt(args);
|
|
99
|
+
|
|
100
|
+
// Extract options (--timeout, --permission-mode, etc.)
|
|
101
|
+
const options = this._extractOptions(args);
|
|
102
|
+
|
|
103
|
+
return { profile, prompt, options };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Extract profile from args (first non-flag arg)
|
|
108
|
+
* @param {Array<string>} args - Args array
|
|
109
|
+
* @returns {string} Profile name
|
|
110
|
+
*/
|
|
111
|
+
_extractProfile(args) {
|
|
112
|
+
// Find first arg that doesn't start with '-' and isn't -p value
|
|
113
|
+
let skipNext = false;
|
|
114
|
+
for (let i = 0; i < args.length; i++) {
|
|
115
|
+
if (skipNext) {
|
|
116
|
+
skipNext = false;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (args[i] === '-p' || args[i] === '--prompt') {
|
|
121
|
+
skipNext = true;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!args[i].startsWith('-')) {
|
|
126
|
+
return args[i];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// No profile specified, return null (will error in validation)
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Extract prompt from -p flag
|
|
136
|
+
* @param {Array<string>} args - Args array
|
|
137
|
+
* @returns {string} Prompt text
|
|
138
|
+
*/
|
|
139
|
+
_extractPrompt(args) {
|
|
140
|
+
const pIndex = args.indexOf('-p');
|
|
141
|
+
const promptIndex = args.indexOf('--prompt');
|
|
142
|
+
|
|
143
|
+
const index = pIndex !== -1 ? pIndex : promptIndex;
|
|
144
|
+
|
|
145
|
+
if (index === -1 || index === args.length - 1) {
|
|
146
|
+
console.error('[X] Missing prompt after -p flag');
|
|
147
|
+
console.error(' Usage: ccs glm -p "task description"');
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return args[index + 1];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Extract options from remaining args
|
|
156
|
+
* @param {Array<string>} args - Args array
|
|
157
|
+
* @returns {Object} Options for HeadlessExecutor
|
|
158
|
+
*/
|
|
159
|
+
_extractOptions(args) {
|
|
160
|
+
const cwd = process.cwd();
|
|
161
|
+
|
|
162
|
+
// Read default permission mode from .claude/settings.local.json
|
|
163
|
+
// Falls back to 'acceptEdits' if file doesn't exist
|
|
164
|
+
const defaultPermissionMode = SettingsParser.parseDefaultPermissionMode(cwd);
|
|
165
|
+
|
|
166
|
+
const options = {
|
|
167
|
+
cwd,
|
|
168
|
+
outputFormat: 'stream-json',
|
|
169
|
+
permissionMode: defaultPermissionMode
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// Parse permission-mode (CLI flag overrides settings file)
|
|
173
|
+
const permModeIndex = args.indexOf('--permission-mode');
|
|
174
|
+
if (permModeIndex !== -1 && permModeIndex < args.length - 1) {
|
|
175
|
+
options.permissionMode = args[permModeIndex + 1];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Parse timeout
|
|
179
|
+
const timeoutIndex = args.indexOf('--timeout');
|
|
180
|
+
if (timeoutIndex !== -1 && timeoutIndex < args.length - 1) {
|
|
181
|
+
options.timeout = parseInt(args[timeoutIndex + 1], 10);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return options;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Validate profile exists and is configured
|
|
189
|
+
* @param {string} profile - Profile name
|
|
190
|
+
*/
|
|
191
|
+
_validateProfile(profile) {
|
|
192
|
+
if (!profile) {
|
|
193
|
+
console.error('[X] No profile specified');
|
|
194
|
+
console.error(' Usage: ccs <profile> -p "task"');
|
|
195
|
+
console.error(' Examples: ccs glm -p "task", ccs kimi -p "task"');
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Use DelegationValidator to check profile
|
|
200
|
+
const validation = DelegationValidator.validate(profile);
|
|
201
|
+
if (!validation.valid) {
|
|
202
|
+
console.error(`[X] Profile '${profile}' is not configured for delegation`);
|
|
203
|
+
console.error(` ${validation.error}`);
|
|
204
|
+
console.error('');
|
|
205
|
+
console.error(' Run: ccs doctor');
|
|
206
|
+
console.error(' Or configure: ~/.ccs/${profile}.settings.json');
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
module.exports = DelegationHandler;
|