codekanban 0.18.0 → 0.20.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/.dockerignore +91 -0
- package/package.json +6 -6
- package/packages/node-sdk/README.md +39 -0
- package/packages/node-sdk/package.json +37 -0
- package/packages/node-sdk/src/cli.js +229 -0
- package/packages/node-sdk/src/client.js +323 -0
- package/packages/node-sdk/src/command-builder.js +129 -0
- package/packages/node-sdk/src/errors.js +28 -0
- package/packages/node-sdk/src/index.js +17 -0
- package/packages/node-sdk/src/terminal-connection.js +133 -0
- package/packages/node-sdk/src/utils.js +99 -0
- package/skills/codekanban-project-session/agents/openai.yaml +4 -0
- package/skills/codekanban-project-session/scripts/run-codekanban-session.mjs +7 -0
- package/tools/claude-terminal-analyzer/README.md +162 -0
- package/tools/claude-terminal-analyzer/build.bat +9 -0
- package/website/index.html +756 -0
- package/website/zh.html +756 -0
package/.dockerignore
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Git
|
|
2
|
+
.git
|
|
3
|
+
.gitignore
|
|
4
|
+
.gitattributes
|
|
5
|
+
.github
|
|
6
|
+
|
|
7
|
+
# Build artifacts
|
|
8
|
+
CodeKanban.exe
|
|
9
|
+
CodeKanban
|
|
10
|
+
test.exe
|
|
11
|
+
bin/
|
|
12
|
+
binary/
|
|
13
|
+
ui/dist/
|
|
14
|
+
|
|
15
|
+
# Development files
|
|
16
|
+
*.md
|
|
17
|
+
docs/
|
|
18
|
+
|
|
19
|
+
# Data and config
|
|
20
|
+
data/
|
|
21
|
+
config.yaml
|
|
22
|
+
config.yaml.testbak
|
|
23
|
+
*.db
|
|
24
|
+
*.db-*
|
|
25
|
+
|
|
26
|
+
# Node modules
|
|
27
|
+
ui/node_modules/
|
|
28
|
+
node_modules/
|
|
29
|
+
|
|
30
|
+
# Temporary files
|
|
31
|
+
tmp/
|
|
32
|
+
*.tmp
|
|
33
|
+
*.log
|
|
34
|
+
nul
|
|
35
|
+
|
|
36
|
+
# IDE and editor files
|
|
37
|
+
.vscode/
|
|
38
|
+
.idea/
|
|
39
|
+
*.swp
|
|
40
|
+
*.swo
|
|
41
|
+
*~
|
|
42
|
+
|
|
43
|
+
# Testing
|
|
44
|
+
*_test.go
|
|
45
|
+
test_*.txt
|
|
46
|
+
|
|
47
|
+
# Python
|
|
48
|
+
__pycache__/
|
|
49
|
+
*.py[cod]
|
|
50
|
+
*.pyo
|
|
51
|
+
*.pyd
|
|
52
|
+
.Python
|
|
53
|
+
build.py
|
|
54
|
+
build-npm.py
|
|
55
|
+
build-npm-multipackage.py
|
|
56
|
+
publish-all-packages.py
|
|
57
|
+
|
|
58
|
+
# OS files
|
|
59
|
+
.DS_Store
|
|
60
|
+
Thumbs.db
|
|
61
|
+
desktop.ini
|
|
62
|
+
|
|
63
|
+
# Archives
|
|
64
|
+
*.zip
|
|
65
|
+
*.tar
|
|
66
|
+
*.tar.gz
|
|
67
|
+
*.rar
|
|
68
|
+
|
|
69
|
+
# Tools and scripts
|
|
70
|
+
tools/
|
|
71
|
+
worktrees/
|
|
72
|
+
recordings/
|
|
73
|
+
|
|
74
|
+
# NPM packages
|
|
75
|
+
npm-bin/
|
|
76
|
+
npm-packages/
|
|
77
|
+
package.json
|
|
78
|
+
.npmignore
|
|
79
|
+
|
|
80
|
+
# OpenAPI
|
|
81
|
+
openapi.json
|
|
82
|
+
|
|
83
|
+
# MCP
|
|
84
|
+
.playwright-mcp/
|
|
85
|
+
.claude/
|
|
86
|
+
|
|
87
|
+
# Misc
|
|
88
|
+
1.txt
|
|
89
|
+
中文测试.txt
|
|
90
|
+
aicode-kanban.zip
|
|
91
|
+
.goreleaser.yml
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codekanban",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "An auxiliary programming tool for the AI era, helping you speed up 10x.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codekanban": "npm-bin/codekanban.js"
|
|
7
7
|
},
|
|
8
8
|
"optionalDependencies": {
|
|
9
|
-
"@codekanban/win32-x64": "0.
|
|
10
|
-
"@codekanban/darwin-x64": "0.
|
|
11
|
-
"@codekanban/darwin-arm64": "0.
|
|
12
|
-
"@codekanban/linux-x64": "0.
|
|
13
|
-
"@codekanban/linux-arm64": "0.
|
|
9
|
+
"@codekanban/win32-x64": "0.20.0",
|
|
10
|
+
"@codekanban/darwin-x64": "0.20.0",
|
|
11
|
+
"@codekanban/darwin-arm64": "0.20.0",
|
|
12
|
+
"@codekanban/linux-x64": "0.20.0",
|
|
13
|
+
"@codekanban/linux-arm64": "0.20.0"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"ai",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# `@codekanban/sdk`
|
|
2
|
+
|
|
3
|
+
Node SDK and CLI for CodeKanban project workflows.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Resolve CodeKanban projects by `projectId` or local `path`
|
|
8
|
+
- Auto-create projects for new paths
|
|
9
|
+
- Select the main worktree automatically
|
|
10
|
+
- Launch terminal + agent workflows for `codex` or `claude`
|
|
11
|
+
- Support `standard`, `plan`, and `yolo` Codex profiles
|
|
12
|
+
- Read terminal session lists and AI session summaries
|
|
13
|
+
- Read AI conversations and continue existing terminal sessions
|
|
14
|
+
|
|
15
|
+
## CLI
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
node packages/node-sdk/bin/codekanban-sdk.js workflow start --base-url http://127.0.0.1:3000 --path D:\repo --profile plan --add-dir D:\shared --prompt "Inspect and plan the refactor"
|
|
19
|
+
node packages/node-sdk/bin/codekanban-sdk.js session list --base-url http://127.0.0.1:3000 --path D:\repo
|
|
20
|
+
node packages/node-sdk/bin/codekanban-sdk.js session conversation --base-url http://127.0.0.1:3000 --id <db-id>
|
|
21
|
+
node packages/node-sdk/bin/codekanban-sdk.js terminal continue --base-url http://127.0.0.1:3000 --session-id <terminal-session-id> --prompt "Continue from the previous plan"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Library
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import { CodeKanbanClient } from '@codekanban/sdk';
|
|
28
|
+
|
|
29
|
+
const client = new CodeKanbanClient({ baseURL: 'http://127.0.0.1:3000' });
|
|
30
|
+
|
|
31
|
+
const result = await client.startWorkflow({
|
|
32
|
+
path: 'D:/repo',
|
|
33
|
+
prompt: 'Inspect the repository and produce a plan first.',
|
|
34
|
+
profile: 'plan',
|
|
35
|
+
permissions: {
|
|
36
|
+
addDirs: ['D:/shared'],
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codekanban/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Node SDK and CLI for launching CodeKanban project workflows and reading business sessions.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.js",
|
|
9
|
+
"./cli": "./src/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"codekanban-sdk": "./bin/codekanban-sdk.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin",
|
|
16
|
+
"src",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20.19.0"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"codekanban",
|
|
24
|
+
"sdk",
|
|
25
|
+
"codex",
|
|
26
|
+
"terminal",
|
|
27
|
+
"ai-session",
|
|
28
|
+
"workflow"
|
|
29
|
+
],
|
|
30
|
+
"author": "fy0",
|
|
31
|
+
"license": "Apache-2.0",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/fy0/CodeKanban"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/fy0/CodeKanban#readme"
|
|
37
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { CodeKanbanClient } from './client.js';
|
|
2
|
+
import { buildAgentLaunchSpec } from './command-builder.js';
|
|
3
|
+
import { createJsonOutput } from './utils.js';
|
|
4
|
+
|
|
5
|
+
function readFlagValue(argv, index, flag) {
|
|
6
|
+
const value = argv[index + 1];
|
|
7
|
+
if (value == null || value.startsWith('--')) {
|
|
8
|
+
throw new Error(`${flag} requires a value`);
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function parseCliArgs(argv) {
|
|
14
|
+
const positionals = [];
|
|
15
|
+
const flags = {
|
|
16
|
+
addDirs: [],
|
|
17
|
+
extraArgs: [],
|
|
18
|
+
includeTerminal: true,
|
|
19
|
+
includeAI: true,
|
|
20
|
+
refresh: false,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
24
|
+
const token = argv[index];
|
|
25
|
+
if (!token.startsWith('--')) {
|
|
26
|
+
positionals.push(token);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
switch (token) {
|
|
31
|
+
case '--base-url':
|
|
32
|
+
flags.baseURL = readFlagValue(argv, index, token);
|
|
33
|
+
index += 1;
|
|
34
|
+
break;
|
|
35
|
+
case '--project-id':
|
|
36
|
+
flags.projectId = readFlagValue(argv, index, token);
|
|
37
|
+
index += 1;
|
|
38
|
+
break;
|
|
39
|
+
case '--path':
|
|
40
|
+
flags.path = readFlagValue(argv, index, token);
|
|
41
|
+
index += 1;
|
|
42
|
+
break;
|
|
43
|
+
case '--prompt':
|
|
44
|
+
flags.prompt = readFlagValue(argv, index, token);
|
|
45
|
+
index += 1;
|
|
46
|
+
break;
|
|
47
|
+
case '--agent':
|
|
48
|
+
flags.agent = readFlagValue(argv, index, token);
|
|
49
|
+
index += 1;
|
|
50
|
+
break;
|
|
51
|
+
case '--profile':
|
|
52
|
+
flags.profile = readFlagValue(argv, index, token);
|
|
53
|
+
index += 1;
|
|
54
|
+
break;
|
|
55
|
+
case '--sandbox':
|
|
56
|
+
flags.sandbox = readFlagValue(argv, index, token);
|
|
57
|
+
index += 1;
|
|
58
|
+
break;
|
|
59
|
+
case '--approval-policy':
|
|
60
|
+
flags.approvalPolicy = readFlagValue(argv, index, token);
|
|
61
|
+
index += 1;
|
|
62
|
+
break;
|
|
63
|
+
case '--add-dir':
|
|
64
|
+
flags.addDirs.push(readFlagValue(argv, index, token));
|
|
65
|
+
index += 1;
|
|
66
|
+
break;
|
|
67
|
+
case '--extra-arg':
|
|
68
|
+
flags.extraArgs.push(readFlagValue(argv, index, token));
|
|
69
|
+
index += 1;
|
|
70
|
+
break;
|
|
71
|
+
case '--title':
|
|
72
|
+
flags.title = readFlagValue(argv, index, token);
|
|
73
|
+
index += 1;
|
|
74
|
+
break;
|
|
75
|
+
case '--working-dir':
|
|
76
|
+
flags.workingDir = readFlagValue(argv, index, token);
|
|
77
|
+
index += 1;
|
|
78
|
+
break;
|
|
79
|
+
case '--task-id':
|
|
80
|
+
flags.taskId = readFlagValue(argv, index, token);
|
|
81
|
+
index += 1;
|
|
82
|
+
break;
|
|
83
|
+
case '--worktree-id':
|
|
84
|
+
flags.worktreeId = readFlagValue(argv, index, token);
|
|
85
|
+
index += 1;
|
|
86
|
+
break;
|
|
87
|
+
case '--session-id':
|
|
88
|
+
flags.sessionId = readFlagValue(argv, index, token);
|
|
89
|
+
index += 1;
|
|
90
|
+
break;
|
|
91
|
+
case '--id':
|
|
92
|
+
flags.id = readFlagValue(argv, index, token);
|
|
93
|
+
index += 1;
|
|
94
|
+
break;
|
|
95
|
+
case '--tool-use-id':
|
|
96
|
+
flags.toolUseId = readFlagValue(argv, index, token);
|
|
97
|
+
index += 1;
|
|
98
|
+
break;
|
|
99
|
+
case '--refresh':
|
|
100
|
+
flags.refresh = true;
|
|
101
|
+
break;
|
|
102
|
+
case '--no-terminal':
|
|
103
|
+
flags.includeTerminal = false;
|
|
104
|
+
break;
|
|
105
|
+
case '--no-ai':
|
|
106
|
+
flags.includeAI = false;
|
|
107
|
+
break;
|
|
108
|
+
default:
|
|
109
|
+
throw new Error(`unknown flag: ${token}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
positionals,
|
|
115
|
+
flags,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function buildPermissions(flags) {
|
|
120
|
+
const permissions = {};
|
|
121
|
+
if (flags.sandbox) {
|
|
122
|
+
permissions.sandbox = flags.sandbox;
|
|
123
|
+
}
|
|
124
|
+
if (flags.approvalPolicy) {
|
|
125
|
+
permissions.approvalPolicy = flags.approvalPolicy;
|
|
126
|
+
}
|
|
127
|
+
if (flags.addDirs.length > 0) {
|
|
128
|
+
permissions.addDirs = flags.addDirs;
|
|
129
|
+
}
|
|
130
|
+
return Object.keys(permissions).length > 0 ? permissions : undefined;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function sanitizeConnection(value) {
|
|
134
|
+
if (!value || typeof value !== 'object') {
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
const next = { ...value };
|
|
138
|
+
delete next.connection;
|
|
139
|
+
return next;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function printJson(stream, payload) {
|
|
143
|
+
stream.write(createJsonOutput(payload));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function runCli(argv) {
|
|
147
|
+
try {
|
|
148
|
+
const { positionals, flags } = parseCliArgs(argv);
|
|
149
|
+
const [scope, action] = positionals;
|
|
150
|
+
if (!scope || !action) {
|
|
151
|
+
throw new Error('usage: <workflow|session|terminal> <action> --base-url <url> [...]');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (scope === 'workflow' && action === 'command') {
|
|
155
|
+
const result = buildAgentLaunchSpec({
|
|
156
|
+
agent: flags.agent,
|
|
157
|
+
profile: flags.profile,
|
|
158
|
+
permissions: buildPermissions(flags),
|
|
159
|
+
extraArgs: flags.extraArgs,
|
|
160
|
+
prompt: flags.prompt || 'Inspect the project and respond.',
|
|
161
|
+
});
|
|
162
|
+
printJson(process.stdout, sanitizeConnection(result));
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!flags.baseURL) {
|
|
167
|
+
throw new Error('--base-url is required');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const client = new CodeKanbanClient({ baseURL: flags.baseURL });
|
|
171
|
+
let result;
|
|
172
|
+
|
|
173
|
+
if (scope === 'workflow' && action === 'start') {
|
|
174
|
+
result = await client.startWorkflow({
|
|
175
|
+
projectId: flags.projectId,
|
|
176
|
+
path: flags.path,
|
|
177
|
+
worktreeId: flags.worktreeId,
|
|
178
|
+
prompt: flags.prompt,
|
|
179
|
+
agent: flags.agent,
|
|
180
|
+
profile: flags.profile,
|
|
181
|
+
permissions: buildPermissions(flags),
|
|
182
|
+
extraArgs: flags.extraArgs,
|
|
183
|
+
title: flags.title,
|
|
184
|
+
workingDir: flags.workingDir,
|
|
185
|
+
taskId: flags.taskId,
|
|
186
|
+
});
|
|
187
|
+
} else if (scope === 'session' && action === 'list') {
|
|
188
|
+
result = await client.listSessions({
|
|
189
|
+
projectId: flags.projectId,
|
|
190
|
+
path: flags.path,
|
|
191
|
+
includeTerminal: flags.includeTerminal,
|
|
192
|
+
includeAI: flags.includeAI,
|
|
193
|
+
});
|
|
194
|
+
} else if (scope === 'session' && action === 'conversation') {
|
|
195
|
+
result = await client.getAISessionConversation({
|
|
196
|
+
id: flags.id,
|
|
197
|
+
sessionId: flags.sessionId,
|
|
198
|
+
refresh: flags.refresh,
|
|
199
|
+
});
|
|
200
|
+
} else if (scope === 'session' && action === 'tool-result') {
|
|
201
|
+
result = await client.getAISessionToolResult({
|
|
202
|
+
id: flags.id,
|
|
203
|
+
sessionId: flags.sessionId,
|
|
204
|
+
toolUseId: flags.toolUseId,
|
|
205
|
+
});
|
|
206
|
+
} else if (scope === 'terminal' && action === 'continue') {
|
|
207
|
+
result = await client.continueTerminalSession({
|
|
208
|
+
projectId: flags.projectId,
|
|
209
|
+
path: flags.path,
|
|
210
|
+
sessionId: flags.sessionId,
|
|
211
|
+
prompt: flags.prompt,
|
|
212
|
+
});
|
|
213
|
+
} else {
|
|
214
|
+
throw new Error(`unsupported command: ${scope} ${action}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
printJson(process.stdout, sanitizeConnection(result));
|
|
218
|
+
return 0;
|
|
219
|
+
} catch (error) {
|
|
220
|
+
const payload = {
|
|
221
|
+
error: {
|
|
222
|
+
name: error instanceof Error ? error.name : 'Error',
|
|
223
|
+
message: error instanceof Error ? error.message : String(error),
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
printJson(process.stderr, payload);
|
|
227
|
+
return 1;
|
|
228
|
+
}
|
|
229
|
+
}
|