codekanban 0.19.0 → 0.21.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 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.19.0",
3
+ "version": "0.21.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.19.0",
10
- "@codekanban/darwin-x64": "0.19.0",
11
- "@codekanban/darwin-arm64": "0.19.0",
12
- "@codekanban/linux-x64": "0.19.0",
13
- "@codekanban/linux-arm64": "0.19.0"
9
+ "@codekanban/win32-x64": "0.21.0",
10
+ "@codekanban/darwin-x64": "0.21.0",
11
+ "@codekanban/darwin-arm64": "0.21.0",
12
+ "@codekanban/linux-x64": "0.21.0",
13
+ "@codekanban/linux-arm64": "0.21.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
+ }