input-kanban 0.0.1

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/ENVIRONMENT.md ADDED
@@ -0,0 +1,39 @@
1
+ # Environment Variables
2
+
3
+ This file documents the runtime environment variables supported by Input Kanban. It is intended for local deployment and runtime configuration, not as the main implementation guide for agents.
4
+
5
+ CLI options take precedence over environment variables. Environment variables take precedence over defaults.
6
+
7
+ ## Variables
8
+
9
+ - `PORT`: HTTP server port. Default: `8787`. CLI option: `--port`.
10
+ - `HOST`: HTTP bind host. Default: `127.0.0.1`. CLI option: `--host`.
11
+ - `KANBAN_DEFAULT_REPO`: Default target repository path for new runs. Default: the current working directory when `input-kanban` is launched. CLI option: `--repo`.
12
+ - `KANBAN_RUNS_DIR`: Directory for run state, logs, and artifacts. Default: `.input-kanban/runs` under the user's home directory. CLI option: `--runs-dir`.
13
+ - `KANBAN_CODEX_BIN`: Codex CLI executable name or path. Default: `codex`. CLI option: `--codex-bin`.
14
+
15
+ ## Environment Example
16
+
17
+ ```bash
18
+ PORT=8787 \
19
+ KANBAN_DEFAULT_REPO=/path/to/child-repo \
20
+ KANBAN_RUNS_DIR=/path/to/kanban-runs \
21
+ KANBAN_CODEX_BIN=codex \
22
+ input-kanban
23
+ ```
24
+
25
+ ## Equivalent CLI Example
26
+
27
+ ```bash
28
+ input-kanban \
29
+ --port 8787 \
30
+ --repo /path/to/child-repo \
31
+ --runs-dir /path/to/kanban-runs \
32
+ --codex-bin codex
33
+ ```
34
+
35
+ ## Notes
36
+
37
+ - `KANBAN_DEFAULT_REPO` / `--repo` should point to the actual git repository where work should run.
38
+ - The runtime runs directory contains task text, logs, model output, artifacts, and possible audit information. It should not be committed to git.
39
+ - Avoid writing machine-specific absolute paths into public or shared documentation.
@@ -0,0 +1,331 @@
1
+ # Input Kanban Project Guide
2
+
3
+ This document explains how Input Kanban is implemented so that humans and coding agents can quickly understand the project before making changes.
4
+
5
+ ## Current Status
6
+
7
+ Implementation status:
8
+
9
+ ```text
10
+ mvp / batch-scheduler / codex-exec-primary / buildkite-style-ui / manual-recovery / stop-archive / cli-bootstrap
11
+ ```
12
+
13
+ Recent validation:
14
+
15
+ - `npm run check` passes for the CLI entry and backend modules.
16
+ - A smoke test can start `input-kanban` on a temporary port and read `GET /api/health`.
17
+ - The frontend is a single HTML file; its inline script can be extracted and checked with `node --check` when edited.
18
+
19
+ ## Project Purpose
20
+
21
+ Input Kanban is a local Codex orchestration dashboard. It is not a business service and not a CI system.
22
+
23
+ It runs local `codex exec --json` processes, stores run state and logs on the filesystem, and serves a static HTML dashboard that polls the backend.
24
+
25
+ The intended use case is:
26
+
27
+ 1. Create a run from a user task.
28
+ 2. Ask a planner to split the task into batches and workers.
29
+ 3. Dispatch workers by strict batch barriers.
30
+ 4. Observe logs, status, artifacts, and Codex session IDs.
31
+ 5. Stop or archive runs when needed.
32
+ 6. Run one final judge pass after all batches complete.
33
+
34
+ ## Important Boundaries
35
+
36
+ - If the current workspace is a multi-repo umbrella, the target repo must be a concrete child repository, not the umbrella root.
37
+ - Workers can modify the target repository. Failed workers are not automatically retried because a partial modification may already exist.
38
+ - The planner only creates a plan and does not modify the target repo. Planner failures, invalid output, and empty plans can be safely retried before any worker or judge starts.
39
+ - Local process state, `exit_code`, logs, and artifacts are the source of truth. Codex App Server session lookup is auxiliary.
40
+ - There is no batch-level judge. Only one final judge pass runs after all batches complete.
41
+
42
+ ## CLI Entry
43
+
44
+ The npm CLI entry is:
45
+
46
+ ```text
47
+ bin/input-kanban.js
48
+ ```
49
+
50
+ It parses CLI options, sets environment variables before importing backend modules, and starts the HTTP server.
51
+
52
+ Supported options:
53
+
54
+ ```text
55
+ --host <host>
56
+ --port <port>
57
+ --repo <path>
58
+ --runs-dir <path>
59
+ --codex-bin <path>
60
+ --open
61
+ --no-open
62
+ ```
63
+
64
+ Default behavior:
65
+
66
+ - default repo: current working directory when `input-kanban` is launched;
67
+ - default host: `127.0.0.1`;
68
+ - default port: `8787`;
69
+ - default runs directory: `~/.input-kanban/runs`;
70
+ - default Codex binary: `codex`.
71
+
72
+ ## Data Model
73
+
74
+ ### Run
75
+
76
+ A run is one user-submitted task batch. It appears as one card in the left sidebar and maps to one runtime directory:
77
+
78
+ ```text
79
+ runs/<runId>/
80
+ ```
81
+
82
+ Main files:
83
+
84
+ ```text
85
+ task.md
86
+ plan.json
87
+ run_state.json
88
+ ```
89
+
90
+ ### Batch
91
+
92
+ A batch is a strict scheduling barrier produced by the planner. Only the first incomplete batch is eligible for scheduling. Later batches must wait until all earlier batches complete.
93
+
94
+ ### Task
95
+
96
+ A task is one worker inside a batch. Batch-level parallelism is controlled by `batch.maxParallel`.
97
+
98
+ ### Roles
99
+
100
+ - `planner`: read-only `codex exec` that returns a plan.
101
+ - `worker`: normally `workspace-write` `codex exec` that performs work.
102
+ - `judge`: read-only `codex exec` that performs final evaluation.
103
+
104
+ ## Run State Machine
105
+
106
+ Common run states:
107
+
108
+ - `created`: run exists, planner has not started.
109
+ - `planning`: planner is running.
110
+ - `plan_failed`: planner failed or returned output that could not be parsed.
111
+ - `plan_empty`: planner returned valid JSON but zero tasks.
112
+ - `planned`: planner produced executable tasks.
113
+ - `running`: at least one worker in the current batch is running.
114
+ - `batch_blocked`: the current batch has a `failed` or `unknown` worker; later batches will not start.
115
+ - `batches_completed`: all batches completed; final judge can run.
116
+ - `judging`: final judge is running.
117
+ - `judged`: final judge process completed.
118
+ - `judge_failed`: final judge process failed.
119
+ - `stopped`: user stopped the run; no further scheduling occurs.
120
+
121
+ ## Planner Retry Policy
122
+
123
+ Planner retry is allowed only before any worker or judge has started.
124
+
125
+ Before retrying, the backend:
126
+
127
+ 1. Moves the current `planner/` directory to `planner_attempts/attempt-XX/`.
128
+ 2. Clears current `tasks` and `batches`.
129
+ 3. Resets `judge` state.
130
+ 4. Deletes old `plan.json`.
131
+ 5. Starts a new planner in a clean `planner/` directory.
132
+
133
+ If the planner returns valid JSON with zero tasks, the run is marked `plan_empty`. The UI shows a warning and allows planning again.
134
+
135
+ ## Worker Failure Policy
136
+
137
+ Workers are not automatically retried.
138
+
139
+ Reason: a worker may have already changed files in the target repository. Retrying could duplicate edits, overwrite partial work, or create conflicts.
140
+
141
+ Recovery options:
142
+
143
+ - Inspect `events.pretty`, `stderr.log`, `last_message.md`, and artifacts.
144
+ - Manually mark `failed` or `unknown` workers as completed if the user confirms the work is actually done.
145
+ - Manual completion writes `workers/<taskId>/manual_completion.json`.
146
+ - The UI preserves the original failed or unknown status while also showing the manual completion marker.
147
+
148
+ ## Stop and Archive
149
+
150
+ ### Stop
151
+
152
+ `POST /api/runs/:runId/stop` terminates still-running local `codex exec` child processes for that run and freezes the run as `stopped`.
153
+
154
+ ### Archive
155
+
156
+ `POST /api/runs/:runId/archive` performs a soft archive:
157
+
158
+ - writes `archived: true` to `run_state.json`;
159
+ - does not move the run directory;
160
+ - hides the run from default `GET /api/runs` and the left sidebar.
161
+
162
+ Archived runs can be queried with:
163
+
164
+ ```text
165
+ GET /api/runs?includeArchived=1
166
+ ```
167
+
168
+ ## Left Sidebar Behavior
169
+
170
+ The left sidebar is rendered from API summaries, not direct file reads.
171
+
172
+ Flow:
173
+
174
+ 1. Backend scans `runs/<runId>/run_state.json`.
175
+ 2. `summaryOfRun()` creates summaries.
176
+ 3. `GET /api/runs` returns those summaries.
177
+ 4. Frontend renders run cards.
178
+
179
+ Current behavior:
180
+
181
+ - Shows the newest 10 runs by default.
182
+ - `Show more` appends 10 more runs.
183
+ - Sidebar height is fixed to the viewport; the run list has its own vertical scroll.
184
+ - Each card shows label, status, run ID, creation time, progress, running count, and failed count.
185
+ - Long labels are clamped to two lines with a browser tooltip for the full value.
186
+
187
+ ## Final Judge
188
+
189
+ Final Judge runs once after all batches complete.
190
+
191
+ Before starting the judge, the backend generates:
192
+
193
+ ```text
194
+ runs/<runId>/judge/judge_input.json
195
+ ```
196
+
197
+ This manifest is the judge's primary source of truth. It contains:
198
+
199
+ - run metadata;
200
+ - original task text;
201
+ - `plan.json`;
202
+ - batch summaries and task order;
203
+ - planner status, output, and parse errors;
204
+ - worker status, exit code, start/end timestamps, expected artifacts;
205
+ - each worker's `last_message.md`, `result.json`, `evidence.json`, `manual_completion.json`, and stderr tail.
206
+
207
+ The judge prompt instructs the model to use `judge_input.json` first and inspect other run artifacts only if needed. This makes final evaluation more deterministic than asking the judge to discover files on its own.
208
+
209
+ ## File Viewer
210
+
211
+ The file viewer calls:
212
+
213
+ ```text
214
+ GET /api/runs/:runId/tasks/:taskId/file?name=...
215
+ ```
216
+
217
+ It can read planner, worker, and judge files.
218
+
219
+ Current behavior:
220
+
221
+ - Selecting a task updates the file viewer title to `runId / taskId`.
222
+ - If a file tab is already open, switching tasks reloads the same file for the newly selected task.
223
+ - Auto refresh also reloads the selected task's selected file and attempts to preserve scroll position.
224
+ - `events.pretty` is a virtual file generated by formatting `events.jsonl` into a readable Chinese execution log.
225
+ - The execution view shows event counts and a jump-to-bottom button.
226
+ - `last_message.md` has a hover copy button in the top-left of the text area.
227
+ - `judge_input.json` can be viewed through the `Judge Input` tab.
228
+
229
+ ## Files and Responsibilities
230
+
231
+ ```text
232
+ bin/input-kanban.js CLI entry; parses args and starts server
233
+ src/server.js HTTP server, static files, API routes
234
+ src/orchestrator.js run state machine, scheduling, codex exec, stop/archive, file formatting
235
+ src/appServerClient.js Codex App Server stdio client and session lookup
236
+ src/utils.js paths, IDs, atomic JSON writes, file info, JSON extraction
237
+ public/index.html single-file frontend, no build step
238
+ README.md user-facing overview
239
+ PROJECT_GUIDE.md implementation guide for humans and agents
240
+ ENVIRONMENT.md runtime environment variable reference
241
+ ```
242
+
243
+ Runtime files:
244
+
245
+ ```text
246
+ runs/<runId>/run_state.json
247
+ runs/<runId>/task.md
248
+ runs/<runId>/plan.json
249
+ runs/<runId>/planner/
250
+ runs/<runId>/planner_attempts/attempt-XX/
251
+ runs/<runId>/workers/<taskId>/
252
+ runs/<runId>/judge/judge_input.json
253
+ runs/<runId>/judge/verdict.json
254
+ ```
255
+
256
+ ## API
257
+
258
+ - `GET /`
259
+ - `GET /api/health`
260
+ - `GET /api/runs`
261
+ - `GET /api/runs?includeArchived=1`
262
+ - `POST /api/runs`
263
+ - `GET /api/runs/:runId/status`
264
+ - `POST /api/runs/:runId/plan`
265
+ - `POST /api/runs/:runId/dispatch`
266
+ - `POST /api/runs/:runId/judge`
267
+ - `POST /api/runs/:runId/stop`
268
+ - `POST /api/runs/:runId/archive`
269
+ - `GET /api/runs/:runId/task-text`
270
+ - `GET /api/runs/:runId/tasks/:taskId/file?name=...`
271
+ - `POST /api/runs/:runId/tasks/:taskId/mark-completed`
272
+
273
+ ## Planner Output
274
+
275
+ Preferred shape:
276
+
277
+ ```json
278
+ {
279
+ "batches": [
280
+ {
281
+ "id": "batch-1",
282
+ "name": "first batch",
283
+ "maxParallel": 3,
284
+ "tasks": [
285
+ {
286
+ "id": "T-01",
287
+ "name": "short name",
288
+ "prompt": "worker prompt",
289
+ "sandbox": "workspace-write",
290
+ "expectedArtifacts": []
291
+ }
292
+ ]
293
+ }
294
+ ],
295
+ "finalJudgeRequired": true
296
+ }
297
+ ```
298
+
299
+ Backward-compatible shape:
300
+
301
+ ```json
302
+ {
303
+ "tasks": [
304
+ {
305
+ "id": "T-01",
306
+ "name": "short name",
307
+ "prompt": "worker prompt",
308
+ "sandbox": "workspace-write",
309
+ "expectedArtifacts": []
310
+ }
311
+ ]
312
+ }
313
+ ```
314
+
315
+ The old `tasks` format is wrapped into `batch-1` automatically.
316
+
317
+ ## Development Checks
318
+
319
+ ```bash
320
+ npm run check
321
+ ```
322
+
323
+ When editing `public/index.html`, also consider extracting the inline script and checking it with `node --check`.
324
+
325
+ ## Change Guidelines
326
+
327
+ - Do not add automatic worker retry unless there is a verified rollback or idempotency mechanism.
328
+ - Do not default to `--skip-git-repo-check`; prefer a concrete target child repository.
329
+ - Preserve batch barriers when modifying scheduling logic.
330
+ - Decide clearly between soft archive and physical directory archive before changing archive semantics.
331
+ - Keep the frontend buildless unless there is a strong reason to introduce a build pipeline.
package/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # Input Kanban
2
+
3
+ Input Kanban is a lightweight local dashboard for splitting a Codex task into batches and workers, running them with `codex exec`, observing status, stopping or archiving runs, and performing a final judge pass.
4
+
5
+ For implementation details and agent-facing project context, see:
6
+
7
+ ```text
8
+ PROJECT_GUIDE.md
9
+ ```
10
+
11
+ For runtime environment variables, see:
12
+
13
+ ```text
14
+ ENVIRONMENT.md
15
+ ```
16
+
17
+ ## Features
18
+
19
+ - Static HTML dashboard with no frontend build step.
20
+ - Node.js backend that can:
21
+ - create multiple runs;
22
+ - start a `codex exec` planner and materialize `plan.json`;
23
+ - safely retry planner runs before any worker or judge starts;
24
+ - detect `plan_empty` when the planner returns zero tasks;
25
+ - schedule workers by strict batch barriers and `batch.maxParallel`;
26
+ - generate `judge_input.json` before the final judge pass;
27
+ - start an independent `codex exec` final judge;
28
+ - aggregate PID, exit code, events, stderr, last message, artifacts, and Codex session IDs;
29
+ - stop runs, soft-archive runs, and manually mark failed or unknown workers as completed.
30
+
31
+ ## CLI Usage
32
+
33
+ Run from the target repository directory:
34
+
35
+ ```bash
36
+ input-kanban
37
+ ```
38
+
39
+ Or provide the target repository explicitly:
40
+
41
+ ```bash
42
+ input-kanban --repo /path/to/repo
43
+ ```
44
+
45
+ Then open:
46
+
47
+ ```text
48
+ http://127.0.0.1:8787
49
+ ```
50
+
51
+ Common options:
52
+
53
+ ```bash
54
+ input-kanban --port 8787
55
+ input-kanban --host 127.0.0.1
56
+ input-kanban --runs-dir ~/.input-kanban/runs
57
+ input-kanban --codex-bin codex
58
+ input-kanban --open
59
+ ```
60
+
61
+ ## Development
62
+
63
+ ```bash
64
+ npm start
65
+ ```
66
+
67
+ For local CLI development:
68
+
69
+ ```bash
70
+ npm link
71
+ input-kanban
72
+ ```
73
+
74
+ ## Workflow
75
+
76
+ 1. Click `New Run`, then enter a label, target repo, max parallel value, and task text.
77
+ 2. Click `Create Run`.
78
+ 3. Click `Plan` to start the planner:
79
+ - planner uses `codex exec --json --sandbox read-only`;
80
+ - output is stored under `runs/<runId>/planner/`.
81
+ 4. When planning succeeds, `plan.json` is created and the worker list is shown.
82
+ 5. Click `Dispatch` to start workers according to batch barriers and `batch.maxParallel`.
83
+ 6. The page polls status every 3 seconds.
84
+ 7. After all batches complete, click `Final Judge` to run the final judge pass.
85
+
86
+ The current UI labels are localized, but the project documentation is written in English for easier agent consumption.
87
+
88
+ ## Planner Output Format
89
+
90
+ The preferred planner response is a JSON object with `batches`. The older `tasks` shape is also supported.
91
+
92
+ ```json
93
+ {
94
+ "batches": [
95
+ {
96
+ "id": "batch-1",
97
+ "name": "first batch name",
98
+ "maxParallel": 3,
99
+ "tasks": [
100
+ {
101
+ "id": "T-01",
102
+ "name": "short name",
103
+ "prompt": "complete worker prompt",
104
+ "sandbox": "workspace-write",
105
+ "expectedArtifacts": ["tmp/example-result.json"]
106
+ }
107
+ ]
108
+ }
109
+ ],
110
+ "finalJudgeRequired": true
111
+ }
112
+ ```
113
+
114
+ The backend extracts the first JSON object from `last_message.md`. If the planner succeeds but returns zero tasks, the run is marked `plan_empty` and can be planned again before any worker or judge starts.
115
+
116
+ ## Status Sources
117
+
118
+ Worker status is primarily determined from local state:
119
+
120
+ - Node child process tracking
121
+ - `exit_code`
122
+ - `events.jsonl`
123
+ - `stderr.log`
124
+ - `last_message.md`
125
+ - expected artifacts
126
+
127
+ Codex App Server is an auxiliary source only:
128
+
129
+ - the backend starts `codex app-server --stdio`;
130
+ - it calls `thread/list`;
131
+ - it matches sessions using prompt markers:
132
+ - `ORCHESTRATOR_RUN_ID`
133
+ - `ORCHESTRATOR_TASK_ID`
134
+
135
+ A Codex App Server `notLoaded` state does not mean a worker failed. The local process, exit code, logs, and artifacts remain the source of truth.
136
+
137
+ ## Runtime Directory
138
+
139
+ ```text
140
+ runs/<runId>/
141
+ ├── task.md
142
+ ├── plan.json
143
+ ├── run_state.json
144
+ ├── planner/
145
+ ├── workers/<taskId>/
146
+ └── judge/
147
+ ├── judge_input.json
148
+ └── verdict.json
149
+ ```
150
+
151
+ The development `runs/` directory is gitignored. For CLI usage, the default runtime directory is `~/.input-kanban/runs`.
152
+
153
+ ## Checks
154
+
155
+ ```bash
156
+ npm run check
157
+ ```
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ import path from 'node:path';
3
+ import { spawn } from 'node:child_process';
4
+
5
+ function parseArgs(argv) {
6
+ const args = { host: '127.0.0.1', port: undefined, repo: undefined, runsDir: undefined, codexBin: undefined, open: false, help: false };
7
+ for (let i = 0; i < argv.length; i++) {
8
+ const arg = argv[i];
9
+ const next = () => argv[++i];
10
+ if (arg === '--help' || arg === '-h') args.help = true;
11
+ else if (arg === '--open') args.open = true;
12
+ else if (arg === '--no-open') args.open = false;
13
+ else if (arg === '--host') args.host = next();
14
+ else if (arg === '--port' || arg === '-p') args.port = Number(next());
15
+ else if (arg === '--repo' || arg === '-r') args.repo = next();
16
+ else if (arg === '--runs-dir') args.runsDir = next();
17
+ else if (arg === '--codex-bin') args.codexBin = next();
18
+ else throw new Error(`unknown argument: ${arg}`);
19
+ }
20
+ return args;
21
+ }
22
+
23
+ function printHelp() {
24
+ console.log(`input-kanban
25
+
26
+ Usage:
27
+ input-kanban [options]
28
+
29
+ Options:
30
+ --host <host> Host to bind, default 127.0.0.1
31
+ -p, --port <port> Port to bind, default 8787
32
+ -r, --repo <path> Default target repository, default current directory
33
+ --runs-dir <path> Runtime runs directory, default ~/.input-kanban/runs
34
+ --codex-bin <path> Codex CLI executable, default codex
35
+ --open Open browser after starting
36
+ --no-open Do not open browser, default
37
+ -h, --help Show help
38
+ `);
39
+ }
40
+
41
+ function openBrowser(url) {
42
+ const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'cmd' : 'xdg-open';
43
+ const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
44
+ const child = spawn(command, args, { stdio: 'ignore', detached: true });
45
+ child.unref();
46
+ }
47
+
48
+ try {
49
+ const args = parseArgs(process.argv.slice(2));
50
+ if (args.help) { printHelp(); process.exit(0); }
51
+ if (args.port) process.env.PORT = String(args.port);
52
+ if (args.host) process.env.HOST = args.host;
53
+ if (args.repo) process.env.KANBAN_DEFAULT_REPO = path.resolve(args.repo);
54
+ else if (!process.env.KANBAN_DEFAULT_REPO) process.env.KANBAN_DEFAULT_REPO = process.cwd();
55
+ if (args.runsDir) process.env.KANBAN_RUNS_DIR = path.resolve(args.runsDir);
56
+ if (args.codexBin) process.env.KANBAN_CODEX_BIN = args.codexBin;
57
+
58
+ const { startServer } = await import('../src/server.js');
59
+ const instance = await startServer({ host: process.env.HOST, port: Number(process.env.PORT || 8787), log: false });
60
+ console.log('Input Kanban started');
61
+ console.log(`URL: ${instance.url}`);
62
+ console.log(`Repo: ${instance.defaultRepo}`);
63
+ console.log(`Runs: ${instance.runsDir}`);
64
+ if (args.open) openBrowser(instance.url);
65
+ const shutdown = () => { instance.stop().finally(() => process.exit(0)); };
66
+ process.on('SIGINT', shutdown);
67
+ process.on('SIGTERM', shutdown);
68
+ } catch (error) {
69
+ console.error(error.message || String(error));
70
+ process.exit(1);
71
+ }
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "input-kanban",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "bin": {
6
+ "input-kanban": "bin/input-kanban.js"
7
+ },
8
+ "scripts": {
9
+ "start": "node bin/input-kanban.js",
10
+ "check": "node --check bin/input-kanban.js && node --check src/server.js && node --check src/orchestrator.js && node --check src/appServerClient.js && node --check src/utils.js"
11
+ },
12
+ "dependencies": {},
13
+ "description": "A local Codex orchestration kanban dashboard",
14
+ "files": [
15
+ "bin",
16
+ "src",
17
+ "public",
18
+ "README.md",
19
+ "PROJECT_GUIDE.md",
20
+ "ENVIRONMENT.md"
21
+ ],
22
+ "keywords": [
23
+ "codex",
24
+ "kanban",
25
+ "orchestration",
26
+ "cli",
27
+ "agent"
28
+ ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/zhang3xing1/Input-Kanban.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/zhang3xing1/Input-Kanban/issues"
35
+ },
36
+ "homepage": "https://github.com/zhang3xing1/Input-Kanban#readme",
37
+ "engines": {
38
+ "node": ">=20"
39
+ }
40
+ }