@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.
Files changed (47) hide show
  1. package/.claude/agents/ccs-delegator.md +117 -0
  2. package/.claude/commands/ccs/glm/continue.md +22 -0
  3. package/.claude/commands/ccs/glm.md +22 -0
  4. package/.claude/commands/ccs/kimi/continue.md +22 -0
  5. package/.claude/commands/ccs/kimi.md +22 -0
  6. package/.claude/skills/ccs-delegation/SKILL.md +54 -0
  7. package/.claude/skills/ccs-delegation/references/README.md +24 -0
  8. package/.claude/skills/ccs-delegation/references/delegation-guidelines.md +99 -0
  9. package/.claude/skills/ccs-delegation/references/headless-workflow.md +174 -0
  10. package/.claude/skills/ccs-delegation/references/troubleshooting.md +268 -0
  11. package/README.ja.md +470 -146
  12. package/README.md +532 -145
  13. package/README.vi.md +484 -157
  14. package/VERSION +1 -1
  15. package/bin/auth/auth-commands.js +98 -13
  16. package/bin/auth/profile-detector.js +11 -6
  17. package/bin/ccs.js +148 -2
  18. package/bin/delegation/README.md +189 -0
  19. package/bin/delegation/delegation-handler.js +212 -0
  20. package/bin/delegation/headless-executor.js +617 -0
  21. package/bin/delegation/result-formatter.js +483 -0
  22. package/bin/delegation/session-manager.js +156 -0
  23. package/bin/delegation/settings-parser.js +109 -0
  24. package/bin/management/doctor.js +94 -1
  25. package/bin/utils/claude-symlink-manager.js +238 -0
  26. package/bin/utils/delegation-validator.js +154 -0
  27. package/bin/utils/error-codes.js +59 -0
  28. package/bin/utils/error-manager.js +38 -32
  29. package/bin/utils/helpers.js +65 -1
  30. package/bin/utils/progress-indicator.js +111 -0
  31. package/bin/utils/prompt.js +134 -0
  32. package/bin/utils/shell-completion.js +234 -0
  33. package/lib/ccs +575 -25
  34. package/lib/ccs.ps1 +381 -20
  35. package/lib/error-codes.ps1 +55 -0
  36. package/lib/error-codes.sh +63 -0
  37. package/lib/progress-indicator.ps1 +120 -0
  38. package/lib/progress-indicator.sh +117 -0
  39. package/lib/prompt.ps1 +109 -0
  40. package/lib/prompt.sh +99 -0
  41. package/package.json +2 -1
  42. package/scripts/completion/README.md +308 -0
  43. package/scripts/completion/ccs.bash +81 -0
  44. package/scripts/completion/ccs.fish +92 -0
  45. package/scripts/completion/ccs.ps1 +157 -0
  46. package/scripts/completion/ccs.zsh +130 -0
  47. 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;