kanbo-cli 0.1.3 → 0.2.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/LICENSE +75 -21
- package/README.md +4 -2
- package/dist/cli.cjs +26 -46
- package/dist/cli.cjs.map +1 -1
- package/dist/lib/index.cjs +1 -259
- package/dist/lib/index.d.cts +15 -95
- package/dist/lib/index.d.mts +15 -95
- package/dist/lib/index.mjs +2 -256
- package/dist/lib/{manifest-BBJIrMw7.cjs → manifest-D9nCRtXM.cjs} +27 -47
- package/dist/lib/manifest-D9nCRtXM.cjs.map +1 -0
- package/dist/lib/{manifest-mkDJmxt2.mjs → manifest-DHV2fRdO.mjs} +27 -47
- package/dist/lib/manifest-DHV2fRdO.mjs.map +1 -0
- package/dist/lib/mcp/index.cjs +1 -1
- package/dist/lib/mcp/index.mjs +1 -1
- package/dist/lib/migrations-path-CZxVOgeD.cjs.map +1 -1
- package/dist/lib/migrations-path-Ciwan537.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/lib/index.cjs.map +0 -1
- package/dist/lib/index.mjs.map +0 -1
- package/dist/lib/manifest-BBJIrMw7.cjs.map +0 -1
- package/dist/lib/manifest-mkDJmxt2.mjs.map +0 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
Required Notice: Copyright (c) 2026 Krowli (https://github.com/Krowli/kanbo)
|
|
2
|
+
|
|
3
|
+
# PolyForm Noncommercial License 1.0.0
|
|
4
|
+
|
|
5
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
6
|
+
|
|
7
|
+
## Acceptance
|
|
8
|
+
|
|
9
|
+
In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
|
|
14
|
+
|
|
15
|
+
## Distribution License
|
|
16
|
+
|
|
17
|
+
The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
|
|
18
|
+
|
|
19
|
+
## Notices
|
|
20
|
+
|
|
21
|
+
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
|
|
22
|
+
|
|
23
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
24
|
+
|
|
25
|
+
## Changes and New Works License
|
|
26
|
+
|
|
27
|
+
The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
|
|
28
|
+
|
|
29
|
+
## Patent License
|
|
30
|
+
|
|
31
|
+
The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
|
|
32
|
+
|
|
33
|
+
## Noncommercial Purposes
|
|
34
|
+
|
|
35
|
+
Any noncommercial purpose is a permitted purpose.
|
|
36
|
+
|
|
37
|
+
## Personal Uses
|
|
38
|
+
|
|
39
|
+
Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
|
|
40
|
+
|
|
41
|
+
## Noncommercial Organizations
|
|
42
|
+
|
|
43
|
+
Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
|
|
44
|
+
|
|
45
|
+
## Fair Use
|
|
46
|
+
|
|
47
|
+
You may have "fair use" rights for the software under the law. These terms do not limit them.
|
|
48
|
+
|
|
49
|
+
## No Other Rights
|
|
50
|
+
|
|
51
|
+
These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
|
|
52
|
+
|
|
53
|
+
## Patent Defense
|
|
54
|
+
|
|
55
|
+
If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
|
|
56
|
+
|
|
57
|
+
## Violations
|
|
58
|
+
|
|
59
|
+
The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
|
|
60
|
+
|
|
61
|
+
## No Liability
|
|
62
|
+
|
|
63
|
+
***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
|
|
64
|
+
|
|
65
|
+
## Definitions
|
|
66
|
+
|
|
67
|
+
The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
|
|
68
|
+
|
|
69
|
+
**You** refers to the individual or entity agreeing to these terms.
|
|
70
|
+
|
|
71
|
+
**Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
|
72
|
+
|
|
73
|
+
**Your licenses** are all the licenses granted to you for the software under these terms.
|
|
74
|
+
|
|
75
|
+
**Use** means anything you do with the software requiring one of your licenses.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/Krowli/kanbo/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/kanbo-cli)
|
|
5
|
-
[](LICENSE)
|
|
6
6
|
[](docs/installation.md)
|
|
7
7
|
|
|
8
8
|
**A Kanban board your AI agents drive, and you watch.** kanbo is a board that lives next to your code — a SQLite file in the project, or a shared Postgres/Supabase database — with a command line and an MCP server made for coding agents. Agents take cards, move them, write a one-line status at every step, split work into subtasks and link their pull requests; when they need you, they hand the card over and stop. Only a person approves or sends a card back, and kanbo enforces that rather than asking nicely. You follow along in a terminal or on a small board page in your browser.
|
|
@@ -77,4 +77,6 @@ Every entry point — the CLI, the MCP server, the HTTP server — calls the sam
|
|
|
77
77
|
|
|
78
78
|
## License
|
|
79
79
|
|
|
80
|
-
[
|
|
80
|
+
[PolyForm Noncommercial 1.0.0](LICENSE) — free for personal, research, educational and other noncommercial use. Commercial use — selling it, or building it into a paid product or service — needs a separate license: write to lionmause999@gmail.com.
|
|
81
|
+
|
|
82
|
+
Versions up to and including 0.2.0 were released under MIT and stay under MIT.
|
package/dist/cli.cjs
CHANGED
|
@@ -3084,7 +3084,7 @@ var import_picocolors = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin((
|
|
|
3084
3084
|
* `package.version`. A build carries it as a literal; running from source
|
|
3085
3085
|
* (tests, `tsx`) reads the package's own `package.json` instead.
|
|
3086
3086
|
*/
|
|
3087
|
-
const KANBO_PACKAGE_VERSION = "0.1
|
|
3087
|
+
const KANBO_PACKAGE_VERSION = "0.2.1";
|
|
3088
3088
|
/**
|
|
3089
3089
|
* Every exit code this tool promises, and what it means — the capabilities
|
|
3090
3090
|
* manifest's `exitCodes` reads this rather than naming the codes again. `0` and
|
|
@@ -10789,15 +10789,12 @@ async function approve(store, issueId, input, actor, scope) {
|
|
|
10789
10789
|
* leaves even says "returned by you".
|
|
10790
10790
|
*/
|
|
10791
10791
|
async function returnCard(store, issueId, input, actor, scope) {
|
|
10792
|
-
if (actor.kind !== "user") throw new BoardError("board_return_requires_user", {
|
|
10793
|
-
issueId,
|
|
10794
|
-
actorKind: actor.kind
|
|
10795
|
-
});
|
|
10796
10792
|
return await runBoardWrite(store, async ({ tx }) => {
|
|
10793
|
+
await ensureDefaultColumns(tx, (await requireCard$1(tx, issueId)).workspaceId, { tx });
|
|
10794
|
+
const target = await assertReturnable(tx, issueId, input, actor);
|
|
10797
10795
|
const card = await requireCard$1(tx, issueId);
|
|
10798
|
-
const columns = await ensureDefaultColumns(tx, card.workspaceId, { tx });
|
|
10799
10796
|
const updates = {
|
|
10800
|
-
statusId:
|
|
10797
|
+
statusId: target.id,
|
|
10801
10798
|
waitingFor: null,
|
|
10802
10799
|
updatedAt: currentUnixSeconds()
|
|
10803
10800
|
};
|
|
@@ -10818,6 +10815,27 @@ async function returnCard(store, issueId, input, actor, scope) {
|
|
|
10818
10815
|
};
|
|
10819
10816
|
}, scope);
|
|
10820
10817
|
}
|
|
10818
|
+
/**
|
|
10819
|
+
* Every reason `returnCard` would refuse, asked on reads alone, and the column
|
|
10820
|
+
* the card would go back to when none applies.
|
|
10821
|
+
*
|
|
10822
|
+
* `returnCard` asks exactly this inside its write. A caller that has to undo
|
|
10823
|
+
* something of its own before the return — stop listening for the approval the
|
|
10824
|
+
* card is waiting on, say — asks it first, so a return the board refuses leaves
|
|
10825
|
+
* that untouched. The refusals are the same `BoardError` codes: an actor who is
|
|
10826
|
+
* not a person (`board_return_requires_user`), a card that is not there
|
|
10827
|
+
* (`issue_not_found`), a named column the workspace does not hold
|
|
10828
|
+
* (`issue_status_not_found`), and a card already in the first column with no
|
|
10829
|
+
* column named (`board_return_no_previous_column`).
|
|
10830
|
+
*/
|
|
10831
|
+
async function assertReturnable(store, issueId, input, actor) {
|
|
10832
|
+
if (actor.kind !== "user") throw new BoardError("board_return_requires_user", {
|
|
10833
|
+
issueId,
|
|
10834
|
+
actorKind: actor.kind
|
|
10835
|
+
});
|
|
10836
|
+
const card = await requireCard$1(store, issueId);
|
|
10837
|
+
return input.toStatusName ? await requireColumn(store, card.workspaceId, input.toStatusName) : previousColumn(await listColumns(store, card.workspaceId), card);
|
|
10838
|
+
}
|
|
10821
10839
|
/** Write a comment on the card, as the actor unless the caller names another author. */
|
|
10822
10840
|
async function addComment(store, input, actor, scope) {
|
|
10823
10841
|
return await runBoardWrite(store, async ({ tx }) => {
|
|
@@ -11695,6 +11713,7 @@ function createBoardOps(store) {
|
|
|
11695
11713
|
waitApproval: async (issueId, input, actor, scope) => await waitApproval(store, issueId, input, actor, scope),
|
|
11696
11714
|
approve: async (issueId, input, actor, scope) => await approve(store, issueId, input, actor, scope),
|
|
11697
11715
|
returnCard: async (issueId, input, actor, scope) => await returnCard(store, issueId, input, actor, scope),
|
|
11716
|
+
assertReturnable: async (issueId, input, actor) => await assertReturnable(store, issueId, input, actor),
|
|
11698
11717
|
readApproval: async (issueId) => await readApproval(store, issueId),
|
|
11699
11718
|
linkPullRequest: async (issueId, urlOrRef, actor, scope) => await linkPullRequest(store, issueId, urlOrRef, actor, scope),
|
|
11700
11719
|
unlinkPullRequest: async (issueId, linkId, actor, scope) => await unlinkPullRequest(store, issueId, linkId, actor, scope),
|
|
@@ -43395,21 +43414,6 @@ function sendBoardPage(response, pathname, assets) {
|
|
|
43395
43414
|
* reason turned around: the answer will be yes once the card meets them, and
|
|
43396
43415
|
* `details.unmet` says what is missing.
|
|
43397
43416
|
*
|
|
43398
|
-
* The five failures about where a board is kept read the same rule. A database
|
|
43399
|
-
* that holds no board this build can speak for is 409 — the setting is there,
|
|
43400
|
-
* the board behind it is not yet, and `board-storage prepare` is what settles
|
|
43401
|
-
* that — and one nobody could reach at all is 503, because nothing about the
|
|
43402
|
-
* request was wrong. A workspace naming no board at all is 404: the caller
|
|
43403
|
-
* asked about a setting that is not there. A board still holding cards when
|
|
43404
|
-
* somebody asks to point the workspace elsewhere is 409, because the answer
|
|
43405
|
-
* would have been yes on an empty board and `board-storage migrate` is what
|
|
43406
|
-
* makes it one. An operation naming cards from two different boards is 400: no
|
|
43407
|
-
* transaction reaches both, so the caller asked for something that cannot be
|
|
43408
|
-
* done. A copy that would land on a card number or a column name the target
|
|
43409
|
-
* already holds under a different id is 409 for the same reason the others
|
|
43410
|
-
* are: the answer would have been yes on a target that did not hold that
|
|
43411
|
-
* board, and `details.conflicts` names every value that clashed.
|
|
43412
|
-
*
|
|
43413
43417
|
* A failure may also be renamed here: the package names its codes after the
|
|
43414
43418
|
* board, while every error the `/issues` routes answer with is named after the
|
|
43415
43419
|
* issue, and a client matching on `issue_*` should not have to learn a second
|
|
@@ -43431,10 +43435,6 @@ const BOARD_ERROR_RESPONSES = {
|
|
|
43431
43435
|
message: "The card does not meet what that column asks for yet",
|
|
43432
43436
|
code: "issue_column_rules_unmet"
|
|
43433
43437
|
},
|
|
43434
|
-
board_copy_conflict: {
|
|
43435
|
-
status: 409,
|
|
43436
|
-
message: "That board already holds cards or columns of this workspace under the same numbers or names; nothing was copied"
|
|
43437
|
-
},
|
|
43438
43438
|
board_entry_rule_invalid: {
|
|
43439
43439
|
status: 400,
|
|
43440
43440
|
message: "Unknown column entry rule"
|
|
@@ -43443,10 +43443,6 @@ const BOARD_ERROR_RESPONSES = {
|
|
|
43443
43443
|
status: 400,
|
|
43444
43444
|
message: "Execution mode cannot change once the card has been launched"
|
|
43445
43445
|
},
|
|
43446
|
-
board_mixed_workspaces: {
|
|
43447
|
-
status: 400,
|
|
43448
|
-
message: "Those cards are not all on the same board"
|
|
43449
|
-
},
|
|
43450
43446
|
board_pull_request_invalid: {
|
|
43451
43447
|
status: 400,
|
|
43452
43448
|
message: "Not a GitHub pull request: give its URL or owner/repo#number"
|
|
@@ -43506,22 +43502,6 @@ const BOARD_ERROR_RESPONSES = {
|
|
|
43506
43502
|
status: 400,
|
|
43507
43503
|
message: "A sprint cannot start after it is due"
|
|
43508
43504
|
},
|
|
43509
|
-
board_storage_not_configured: {
|
|
43510
|
-
status: 404,
|
|
43511
|
-
message: "This workspace names no board storage"
|
|
43512
|
-
},
|
|
43513
|
-
board_storage_not_empty: {
|
|
43514
|
-
status: 409,
|
|
43515
|
-
message: "That board still holds cards of this workspace; move them with migrate before changing where the board is kept"
|
|
43516
|
-
},
|
|
43517
|
-
board_storage_not_prepared: {
|
|
43518
|
-
status: 409,
|
|
43519
|
-
message: "That board has not been prepared yet"
|
|
43520
|
-
},
|
|
43521
|
-
board_storage_unavailable: {
|
|
43522
|
-
status: 503,
|
|
43523
|
-
message: "That board could not be reached"
|
|
43524
|
-
},
|
|
43525
43505
|
issue_comment_delete_requires_user: {
|
|
43526
43506
|
status: 403,
|
|
43527
43507
|
message: "Only a person can delete a comment the board wrote"
|