@takemo101/mikan 0.0.6 → 0.0.8
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/README.md +3 -1
- package/dist/bin.js +419 -164
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
mikan is a tiny local-first Issue board for AI-assisted development. It stores Issues as Markdown files under `.mikan/` and exposes the same board through a CLI, keyboard-first TUI, stdio MCP server, and polling watcher.
|
|
4
4
|
|
|
5
|
+
Manual: <https://takemo101.github.io/mikan/>
|
|
6
|
+
|
|
5
7
|
## Install
|
|
6
8
|
|
|
7
9
|
```sh
|
|
@@ -17,7 +19,7 @@ mikan is currently built for Bun-based execution. The npm package installs the `
|
|
|
17
19
|
|
|
18
20
|
- **Markdown source of truth**: each Issue is a file such as `.mikan/ready/MIK-001.md`.
|
|
19
21
|
- **Primitive CLI commands**: `init`, `add`, `list`, `show`, `update`, `move`, `append`, `github`, `tui`, `watch`, `mcp`, `skills`.
|
|
20
|
-
- **Keyboard TUI**: board-first flow with detail view, Note
|
|
22
|
+
- **Keyboard TUI**: board-first flow with detail view, Label/Note/Warning modals, Move shortcuts, and Archive confirmation.
|
|
21
23
|
- **MCP server**: stdio tools for agents: `get_board`, `list_issues`, `get_issue`, `create_issue`, `update_issue`, `move_issue`, `append_issue`, `mirror_issue_to_github`.
|
|
22
24
|
- **GitHub Mirror**: explicit one-way publication from local Markdown Issues to GitHub Issues.
|
|
23
25
|
- **Agent setup**: register the MCP server or install agent guidance for common AI agents.
|
package/dist/bin.js
CHANGED
|
@@ -100301,8 +100301,12 @@ function updateIssue(options) {
|
|
|
100301
100301
|
const target = findIssueById(options);
|
|
100302
100302
|
if (!target.ok)
|
|
100303
100303
|
return target;
|
|
100304
|
-
const
|
|
100305
|
-
const
|
|
100304
|
+
const existingLabels = target.value.issue.labels.map(String);
|
|
100305
|
+
const configuredLabelIds = new Set(options.config.labels.map((label) => label.id));
|
|
100306
|
+
const existingUnknownLabels = new Set(existingLabels.filter((label) => !configuredLabelIds.has(label)));
|
|
100307
|
+
const labels = options.labels ?? existingLabels;
|
|
100308
|
+
const labelsToValidate = options.preserveUnknownLabels ? labels.filter((label) => !existingUnknownLabels.has(label)) : labels;
|
|
100309
|
+
const labelsValidation = validateLabels(options.config, labelsToValidate);
|
|
100306
100310
|
if (!labelsValidation.ok)
|
|
100307
100311
|
return labelsValidation;
|
|
100308
100312
|
const dependenciesValidation = options.dependencies ? validateDependencies(options.dependencies) : undefined;
|
|
@@ -100798,9 +100802,18 @@ var labelSchema = exports_external.object({
|
|
|
100798
100802
|
id: nonEmptyString,
|
|
100799
100803
|
title: nonEmptyString
|
|
100800
100804
|
});
|
|
100805
|
+
var hookEntrySchema = exports_external.union([
|
|
100806
|
+
nonEmptyString,
|
|
100807
|
+
exports_external.object({
|
|
100808
|
+
command: nonEmptyString,
|
|
100809
|
+
when: exports_external.object({
|
|
100810
|
+
labels_include: exports_external.array(nonEmptyString).min(1).optional()
|
|
100811
|
+
}).optional()
|
|
100812
|
+
})
|
|
100813
|
+
]);
|
|
100801
100814
|
var hookSchema = exports_external.object({
|
|
100802
|
-
on_enter: exports_external.record(exports_external.string(), exports_external.array(
|
|
100803
|
-
on_transition: exports_external.record(exports_external.string(), exports_external.array(
|
|
100815
|
+
on_enter: exports_external.record(exports_external.string(), exports_external.array(hookEntrySchema)).optional(),
|
|
100816
|
+
on_transition: exports_external.record(exports_external.string(), exports_external.array(hookEntrySchema)).optional()
|
|
100804
100817
|
});
|
|
100805
100818
|
var githubSchema = exports_external.object({
|
|
100806
100819
|
repo: githubRepoSchema,
|
|
@@ -107389,7 +107402,7 @@ var import_react20 = __toESM(require_react(), 1);
|
|
|
107389
107402
|
// package.json
|
|
107390
107403
|
var package_default = {
|
|
107391
107404
|
name: "@takemo101/mikan",
|
|
107392
|
-
version: "0.0.
|
|
107405
|
+
version: "0.0.8",
|
|
107393
107406
|
private: false,
|
|
107394
107407
|
type: "module",
|
|
107395
107408
|
bin: {
|
|
@@ -107453,13 +107466,16 @@ function visibleDetailLineCount(viewportHeight) {
|
|
|
107453
107466
|
return Math.max(1, viewportHeight - 8);
|
|
107454
107467
|
}
|
|
107455
107468
|
function footerText(mode) {
|
|
107469
|
+
if (mode === "note-modal") {
|
|
107470
|
+
return "Note | Enter newline | Ctrl+S save | Esc cancel";
|
|
107471
|
+
}
|
|
107456
107472
|
if (mode === "modal") {
|
|
107457
107473
|
return "Modal | enter confirm | esc cancel | ? keys";
|
|
107458
107474
|
}
|
|
107459
107475
|
if (mode === "detail") {
|
|
107460
|
-
return "Detail | \u2191\u2193 scroll |
|
|
107476
|
+
return "Detail | \u2191\u2193 scroll | esc board | ? keys";
|
|
107461
107477
|
}
|
|
107462
|
-
return "Board | \u2191\u2193 card | \u2190\u2192 column | enter detail |
|
|
107478
|
+
return "Board | \u2191\u2193 card | \u2190\u2192 column | enter detail | ? keys";
|
|
107463
107479
|
}
|
|
107464
107480
|
|
|
107465
107481
|
// ../tui/src/selection.ts
|
|
@@ -107566,6 +107582,7 @@ function buildTuiModel(board, labels = [], githubRepo) {
|
|
|
107566
107582
|
})),
|
|
107567
107583
|
warnings: board.warnings.map(formatWarning),
|
|
107568
107584
|
...board.warnings.length > 0 ? { warningDetails: board.warnings.map(formatTuiWarning) } : {},
|
|
107585
|
+
labels: labels.map((label) => ({ id: label.id, title: label.title })),
|
|
107569
107586
|
labelTitles: Object.fromEntries(labels.map((label) => [label.id, label.title])),
|
|
107570
107587
|
githubRepo
|
|
107571
107588
|
};
|
|
@@ -107940,7 +107957,7 @@ function moveSelection(model, selection, direction, options = {}) {
|
|
|
107940
107957
|
message: undefined
|
|
107941
107958
|
};
|
|
107942
107959
|
}
|
|
107943
|
-
if (selection.detailOpen && !selection.moveOpen && !selection.noteOpen) {
|
|
107960
|
+
if (selection.detailOpen && !selection.moveOpen && !selection.noteOpen && !selection.labelOpen) {
|
|
107944
107961
|
if (direction === "up" || direction === "down") {
|
|
107945
107962
|
return {
|
|
107946
107963
|
...selection,
|
|
@@ -107961,6 +107978,9 @@ function moveSelection(model, selection, direction, options = {}) {
|
|
|
107961
107978
|
if (selection.githubConfirmOpen) {
|
|
107962
107979
|
return { ...selection, githubConfirmOpen: false };
|
|
107963
107980
|
}
|
|
107981
|
+
if (selection.labelOpen) {
|
|
107982
|
+
return { ...selection, labelOpen: false };
|
|
107983
|
+
}
|
|
107964
107984
|
if (selection.warningsOpen) {
|
|
107965
107985
|
return { ...selection, warningsOpen: false };
|
|
107966
107986
|
}
|
|
@@ -107968,7 +107988,10 @@ function moveSelection(model, selection, direction, options = {}) {
|
|
|
107968
107988
|
...selection,
|
|
107969
107989
|
detailOpen: false,
|
|
107970
107990
|
moveOpen: false,
|
|
107971
|
-
noteOpen: false
|
|
107991
|
+
noteOpen: false,
|
|
107992
|
+
noteDraft: undefined,
|
|
107993
|
+
labelOpen: false,
|
|
107994
|
+
message: selection.noteOpen ? undefined : selection.message
|
|
107972
107995
|
};
|
|
107973
107996
|
}
|
|
107974
107997
|
if (direction === "move") {
|
|
@@ -107977,6 +108000,8 @@ function moveSelection(model, selection, direction, options = {}) {
|
|
|
107977
108000
|
archiveOpen: false,
|
|
107978
108001
|
detailOpen: false,
|
|
107979
108002
|
noteOpen: false,
|
|
108003
|
+
noteDraft: undefined,
|
|
108004
|
+
labelOpen: false,
|
|
107980
108005
|
moveOpen: true,
|
|
107981
108006
|
moveTargetIndex: 0
|
|
107982
108007
|
};
|
|
@@ -107987,7 +108012,25 @@ function moveSelection(model, selection, direction, options = {}) {
|
|
|
107987
108012
|
archiveOpen: false,
|
|
107988
108013
|
detailOpen: false,
|
|
107989
108014
|
moveOpen: false,
|
|
107990
|
-
|
|
108015
|
+
labelOpen: false,
|
|
108016
|
+
noteOpen: true,
|
|
108017
|
+
noteDraft: "",
|
|
108018
|
+
message: undefined
|
|
108019
|
+
};
|
|
108020
|
+
}
|
|
108021
|
+
if (direction === "edit-labels") {
|
|
108022
|
+
const card = model.columns[selection.columnIndex]?.cards[selection.cardIndex];
|
|
108023
|
+
const knownLabelIds = new Set((model.labels ?? []).map((label) => label.id));
|
|
108024
|
+
return {
|
|
108025
|
+
...selection,
|
|
108026
|
+
archiveOpen: false,
|
|
108027
|
+
githubConfirmOpen: false,
|
|
108028
|
+
moveOpen: false,
|
|
108029
|
+
noteOpen: false,
|
|
108030
|
+
noteDraft: undefined,
|
|
108031
|
+
labelOpen: true,
|
|
108032
|
+
labelFocusIndex: 0,
|
|
108033
|
+
labelDraftIds: card?.labels.filter((label) => knownLabelIds.has(label)) ?? []
|
|
107991
108034
|
};
|
|
107992
108035
|
}
|
|
107993
108036
|
if (direction === "archive") {
|
|
@@ -107996,6 +108039,8 @@ function moveSelection(model, selection, direction, options = {}) {
|
|
|
107996
108039
|
archiveOpen: true,
|
|
107997
108040
|
moveOpen: false,
|
|
107998
108041
|
noteOpen: false,
|
|
108042
|
+
noteDraft: undefined,
|
|
108043
|
+
labelOpen: false,
|
|
107999
108044
|
githubConfirmOpen: false
|
|
108000
108045
|
};
|
|
108001
108046
|
}
|
|
@@ -108005,6 +108050,8 @@ function moveSelection(model, selection, direction, options = {}) {
|
|
|
108005
108050
|
archiveOpen: false,
|
|
108006
108051
|
moveOpen: false,
|
|
108007
108052
|
noteOpen: false,
|
|
108053
|
+
noteDraft: undefined,
|
|
108054
|
+
labelOpen: false,
|
|
108008
108055
|
githubConfirmOpen: true
|
|
108009
108056
|
};
|
|
108010
108057
|
}
|
|
@@ -108036,28 +108083,38 @@ function getAdjacentMoveTarget(model, selection, direction) {
|
|
|
108036
108083
|
const column = model.columns[selection.columnIndex + offset];
|
|
108037
108084
|
return column ? { id: column.id, title: column.title } : undefined;
|
|
108038
108085
|
}
|
|
108039
|
-
function
|
|
108040
|
-
if (!selection.
|
|
108086
|
+
function moveLabelFocus(model, selection, direction) {
|
|
108087
|
+
if (!selection.labelOpen)
|
|
108041
108088
|
return selection;
|
|
108042
|
-
|
|
108043
|
-
|
|
108044
|
-
|
|
108045
|
-
|
|
108046
|
-
|
|
108047
|
-
|
|
108048
|
-
|
|
108049
|
-
|
|
108089
|
+
return {
|
|
108090
|
+
...selection,
|
|
108091
|
+
labelFocusIndex: clamp((selection.labelFocusIndex ?? 0) + (direction === "down" ? 1 : -1), 0, Math.max(0, (model.labels ?? []).length - 1))
|
|
108092
|
+
};
|
|
108093
|
+
}
|
|
108094
|
+
function toggleFocusedLabel(model, selection) {
|
|
108095
|
+
if (!selection.labelOpen)
|
|
108096
|
+
return selection;
|
|
108097
|
+
const label = (model.labels ?? [])[selection.labelFocusIndex ?? 0];
|
|
108098
|
+
if (!label)
|
|
108050
108099
|
return selection;
|
|
108051
|
-
const
|
|
108052
|
-
|
|
108100
|
+
const current = new Set(selection.labelDraftIds ?? []);
|
|
108101
|
+
if (current.has(label.id))
|
|
108102
|
+
current.delete(label.id);
|
|
108103
|
+
else
|
|
108104
|
+
current.add(label.id);
|
|
108105
|
+
return { ...selection, labelDraftIds: [...current] };
|
|
108053
108106
|
}
|
|
108054
108107
|
function footerMode(selection) {
|
|
108055
|
-
if (selection.
|
|
108108
|
+
if (selection.noteOpen)
|
|
108109
|
+
return "note-modal";
|
|
108110
|
+
if (selection.moveOpen || selection.labelOpen || selection.archiveOpen || selection.githubConfirmOpen) {
|
|
108056
108111
|
return "modal";
|
|
108057
108112
|
}
|
|
108058
108113
|
return selection.detailOpen ? "detail" : "board";
|
|
108059
108114
|
}
|
|
108060
|
-
function keyToTuiAction(keyName2, shift = false) {
|
|
108115
|
+
function keyToTuiAction(keyName2, shift = false, ctrl = false) {
|
|
108116
|
+
if (ctrl && keyName2 === "s")
|
|
108117
|
+
return "save-note";
|
|
108061
108118
|
if (shift && keyName2 === "h")
|
|
108062
108119
|
return "move-left";
|
|
108063
108120
|
if (shift && keyName2 === "l")
|
|
@@ -108090,6 +108147,8 @@ function keyToTuiAction(keyName2, shift = false) {
|
|
|
108090
108147
|
return "move";
|
|
108091
108148
|
case "n":
|
|
108092
108149
|
return "append-note";
|
|
108150
|
+
case "e":
|
|
108151
|
+
return "edit-labels";
|
|
108093
108152
|
case "a":
|
|
108094
108153
|
return "archive";
|
|
108095
108154
|
case "g":
|
|
@@ -108136,8 +108195,31 @@ function buildNotePromptViewModel(model, selection) {
|
|
|
108136
108195
|
return {
|
|
108137
108196
|
title: `Append note to ${card.id}`,
|
|
108138
108197
|
focused: Boolean(selection.noteOpen),
|
|
108139
|
-
|
|
108140
|
-
hint: "
|
|
108198
|
+
feedback: selection.message === "Note cannot be empty" ? selection.message : undefined,
|
|
108199
|
+
hint: "Enter newline | Ctrl+S save | Esc cancel"
|
|
108200
|
+
};
|
|
108201
|
+
}
|
|
108202
|
+
function buildLabelPromptViewModel(model, selection) {
|
|
108203
|
+
const card = model.columns[selection.columnIndex]?.cards[selection.cardIndex];
|
|
108204
|
+
if (!card)
|
|
108205
|
+
return;
|
|
108206
|
+
const configuredLabels = model.labels ?? [];
|
|
108207
|
+
const draft = new Set(selection.labelDraftIds ?? card.labels);
|
|
108208
|
+
const known = new Set(configuredLabels.map((label) => label.id));
|
|
108209
|
+
return {
|
|
108210
|
+
title: `Edit Labels for ${card.id}`,
|
|
108211
|
+
focused: Boolean(selection.labelOpen),
|
|
108212
|
+
labels: configuredLabels.map((label, index2) => ({
|
|
108213
|
+
id: label.id,
|
|
108214
|
+
title: label.title,
|
|
108215
|
+
checked: draft.has(label.id),
|
|
108216
|
+
focused: index2 === (selection.labelFocusIndex ?? 0)
|
|
108217
|
+
})),
|
|
108218
|
+
unknownLabels: card.labels.filter((label) => !known.has(label)),
|
|
108219
|
+
...configuredLabels.length === 0 ? {
|
|
108220
|
+
emptyMessage: "No Labels configured. Add Labels in .mikan/config.yaml."
|
|
108221
|
+
} : {},
|
|
108222
|
+
hint: configuredLabels.length === 0 ? "esc close" : "space toggle enter save esc cancel"
|
|
108141
108223
|
};
|
|
108142
108224
|
}
|
|
108143
108225
|
function buildArchivePromptViewModel(model, selection) {
|
|
@@ -108166,66 +108248,174 @@ Local Markdown remains the source of truth.`,
|
|
|
108166
108248
|
};
|
|
108167
108249
|
}
|
|
108168
108250
|
|
|
108251
|
+
// ../tui/src/prompt-text.ts
|
|
108252
|
+
function renderMoveInteraction(model, selection) {
|
|
108253
|
+
const view = buildMovePromptViewModel(model, selection);
|
|
108254
|
+
if (!view)
|
|
108255
|
+
return ["Move", "No Issue selected"];
|
|
108256
|
+
return [
|
|
108257
|
+
`${view.title} to Status`,
|
|
108258
|
+
...view.targets.map((target) => `${target.selected ? ">" : " "} ${target.id} (${target.title})`),
|
|
108259
|
+
view.hint
|
|
108260
|
+
];
|
|
108261
|
+
}
|
|
108262
|
+
function renderLabelInteraction(model, selection) {
|
|
108263
|
+
const view = buildLabelPromptViewModel(model, selection);
|
|
108264
|
+
if (!view)
|
|
108265
|
+
return ["Edit Labels", "No Issue selected"];
|
|
108266
|
+
if (view.emptyMessage) {
|
|
108267
|
+
return [view.title, "", view.emptyMessage, "", view.hint];
|
|
108268
|
+
}
|
|
108269
|
+
return [
|
|
108270
|
+
view.title,
|
|
108271
|
+
"",
|
|
108272
|
+
...view.labels.map((label) => `${label.focused ? "\u25B6" : " "} [${label.checked ? "x" : " "}] ${label.title}`),
|
|
108273
|
+
...view.unknownLabels.length > 0 ? ["", `Unknown Labels (read-only): ${view.unknownLabels.join(", ")}`] : [],
|
|
108274
|
+
"",
|
|
108275
|
+
view.hint
|
|
108276
|
+
];
|
|
108277
|
+
}
|
|
108278
|
+
function renderArchiveInteraction(model, selection) {
|
|
108279
|
+
const view = buildArchivePromptViewModel(model, selection);
|
|
108280
|
+
if (!view)
|
|
108281
|
+
return ["Archive", "No Issue selected"];
|
|
108282
|
+
return [view.title, view.body, view.hint];
|
|
108283
|
+
}
|
|
108284
|
+
function renderGitHubMirrorInteraction(model, selection) {
|
|
108285
|
+
const view = buildGitHubMirrorPromptViewModel(model, selection);
|
|
108286
|
+
if (!view)
|
|
108287
|
+
return ["GitHub Mirror", "No Issue selected"];
|
|
108288
|
+
return [view.title, view.body, view.hint];
|
|
108289
|
+
}
|
|
108290
|
+
function renderWarningDetails(model) {
|
|
108291
|
+
return [
|
|
108292
|
+
"Warning details",
|
|
108293
|
+
...model.warnings.length > 0 ? model.warnings.map((warning) => `! ${warning}`) : ["No warnings"]
|
|
108294
|
+
];
|
|
108295
|
+
}
|
|
108296
|
+
function renderKeyHelp() {
|
|
108297
|
+
return [
|
|
108298
|
+
"Key help",
|
|
108299
|
+
"\u2191/\u2193 or j/k card/scroll",
|
|
108300
|
+
"\u2190/\u2192 or h/l column",
|
|
108301
|
+
"enter detail/confirm",
|
|
108302
|
+
"esc back/cancel",
|
|
108303
|
+
"H/L move Issue",
|
|
108304
|
+
"m move menu",
|
|
108305
|
+
"n append Note",
|
|
108306
|
+
"note: enter newline, ctrl+s save",
|
|
108307
|
+
"e edit Labels",
|
|
108308
|
+
"a archive Issue",
|
|
108309
|
+
"g GitHub Mirror",
|
|
108310
|
+
"w warning details",
|
|
108311
|
+
"r reload",
|
|
108312
|
+
"q quit"
|
|
108313
|
+
];
|
|
108314
|
+
}
|
|
108315
|
+
|
|
108169
108316
|
// ../tui/src/modals.ts
|
|
108170
108317
|
function MovePrompt(props) {
|
|
108171
|
-
|
|
108172
|
-
|
|
108173
|
-
|
|
108174
|
-
|
|
108175
|
-
}, import_react3.default.createElement("box", {
|
|
108176
|
-
id: "move-prompt",
|
|
108318
|
+
return renderModalText({
|
|
108319
|
+
theme: props.theme,
|
|
108320
|
+
backdropId: "move-modal-backdrop",
|
|
108321
|
+
panelId: "move-prompt",
|
|
108177
108322
|
title: "Move Issue",
|
|
108178
|
-
|
|
108179
|
-
|
|
108180
|
-
}, import_react3.default.createElement("text", {
|
|
108181
|
-
content: renderMoveInteraction(props.model, props.selection).join(`
|
|
108182
|
-
`)
|
|
108183
|
-
})));
|
|
108323
|
+
content: renderMoveInteraction(props.model, props.selection)
|
|
108324
|
+
});
|
|
108184
108325
|
}
|
|
108185
108326
|
function NotePrompt(props) {
|
|
108186
|
-
const
|
|
108187
|
-
|
|
108188
|
-
|
|
108189
|
-
|
|
108190
|
-
|
|
108191
|
-
|
|
108327
|
+
const view = buildNotePromptViewModel(props.model, props.selection);
|
|
108328
|
+
if (!view) {
|
|
108329
|
+
return renderModalText({
|
|
108330
|
+
theme: props.theme,
|
|
108331
|
+
backdropId: "note-modal-backdrop",
|
|
108332
|
+
panelId: "note-prompt",
|
|
108333
|
+
title: "Append Note",
|
|
108334
|
+
content: ["Append note", "No Issue selected"]
|
|
108335
|
+
});
|
|
108336
|
+
}
|
|
108337
|
+
const initialValue = props.selection.noteDraft ?? "";
|
|
108338
|
+
return renderModalShell({
|
|
108339
|
+
theme: props.theme,
|
|
108340
|
+
backdropId: "note-modal-backdrop",
|
|
108341
|
+
panelId: "note-prompt",
|
|
108192
108342
|
title: "Append Note",
|
|
108193
|
-
|
|
108194
|
-
style: modalStyle(theme)
|
|
108343
|
+
panelStyle: { height: view.feedback ? 14 : 13 }
|
|
108195
108344
|
}, import_react3.default.createElement("text", {
|
|
108196
|
-
content:
|
|
108345
|
+
content: [view.title, "", "Note:"].join(`
|
|
108197
108346
|
`)
|
|
108198
|
-
})
|
|
108347
|
+
}), import_react3.default.createElement("textarea", {
|
|
108348
|
+
id: "note-textarea",
|
|
108349
|
+
ref: props.noteTextareaRef,
|
|
108350
|
+
focused: true,
|
|
108351
|
+
initialValue,
|
|
108352
|
+
placeholder: "Write a Note...",
|
|
108353
|
+
height: 5,
|
|
108354
|
+
wrapMode: "word",
|
|
108355
|
+
keyBindings: [{ name: "s", ctrl: true, action: "submit" }],
|
|
108356
|
+
onSubmit: () => {
|
|
108357
|
+
props.onNoteSubmit?.(props.noteTextareaRef?.current?.plainText ?? "");
|
|
108358
|
+
},
|
|
108359
|
+
style: {
|
|
108360
|
+
alignSelf: "stretch",
|
|
108361
|
+
backgroundColor: props.theme?.base.canvas,
|
|
108362
|
+
textColor: props.theme?.base.text,
|
|
108363
|
+
focusedBackgroundColor: props.theme?.base.canvas,
|
|
108364
|
+
focusedTextColor: props.theme?.base.text,
|
|
108365
|
+
width: "auto"
|
|
108366
|
+
}
|
|
108367
|
+
}), import_react3.default.createElement("text", {
|
|
108368
|
+
content: ["", ...view.feedback ? [view.feedback] : [], view.hint].join(`
|
|
108369
|
+
`)
|
|
108370
|
+
}));
|
|
108371
|
+
}
|
|
108372
|
+
function LabelPrompt(props) {
|
|
108373
|
+
return renderModalText({
|
|
108374
|
+
theme: props.theme,
|
|
108375
|
+
backdropId: "label-modal-backdrop",
|
|
108376
|
+
panelId: "label-prompt",
|
|
108377
|
+
title: "Edit Labels",
|
|
108378
|
+
content: renderLabelInteraction(props.model, props.selection)
|
|
108379
|
+
});
|
|
108199
108380
|
}
|
|
108200
108381
|
function ArchivePrompt(props) {
|
|
108201
|
-
|
|
108202
|
-
|
|
108203
|
-
|
|
108204
|
-
|
|
108205
|
-
}, import_react3.default.createElement("box", {
|
|
108206
|
-
id: "archive-prompt",
|
|
108382
|
+
return renderModalText({
|
|
108383
|
+
theme: props.theme,
|
|
108384
|
+
backdropId: "archive-modal-backdrop",
|
|
108385
|
+
panelId: "archive-prompt",
|
|
108207
108386
|
title: "Archive Issue",
|
|
108208
|
-
|
|
108209
|
-
|
|
108210
|
-
}, import_react3.default.createElement("text", {
|
|
108211
|
-
content: renderArchiveInteraction(props.model, props.selection).join(`
|
|
108212
|
-
`)
|
|
108213
|
-
})));
|
|
108387
|
+
content: renderArchiveInteraction(props.model, props.selection)
|
|
108388
|
+
});
|
|
108214
108389
|
}
|
|
108215
108390
|
function GitHubMirrorPrompt(props) {
|
|
108216
|
-
|
|
108391
|
+
return renderModalText({
|
|
108392
|
+
theme: props.theme,
|
|
108393
|
+
backdropId: "github-mirror-modal-backdrop",
|
|
108394
|
+
panelId: "github-mirror-prompt",
|
|
108395
|
+
title: "GitHub Mirror",
|
|
108396
|
+
content: renderGitHubMirrorInteraction(props.model, props.selection)
|
|
108397
|
+
});
|
|
108398
|
+
}
|
|
108399
|
+
function renderModalText(options) {
|
|
108400
|
+
return renderModalShell(options, import_react3.default.createElement("text", {
|
|
108401
|
+
content: options.content.join(`
|
|
108402
|
+
`)
|
|
108403
|
+
}));
|
|
108404
|
+
}
|
|
108405
|
+
function renderModalShell(options, ...children) {
|
|
108406
|
+
const theme = options.theme ?? buildTuiTheme();
|
|
108217
108407
|
return import_react3.default.createElement("box", {
|
|
108218
|
-
id:
|
|
108408
|
+
id: options.backdropId,
|
|
108219
108409
|
style: modalBackdropStyle(theme)
|
|
108220
108410
|
}, import_react3.default.createElement("box", {
|
|
108221
|
-
id:
|
|
108222
|
-
title:
|
|
108411
|
+
id: options.panelId,
|
|
108412
|
+
title: options.title,
|
|
108223
108413
|
border: true,
|
|
108224
|
-
style:
|
|
108225
|
-
|
|
108226
|
-
|
|
108227
|
-
|
|
108228
|
-
}))
|
|
108414
|
+
style: {
|
|
108415
|
+
...modalStyle(theme),
|
|
108416
|
+
...options.panelStyle ?? {}
|
|
108417
|
+
}
|
|
108418
|
+
}, ...children));
|
|
108229
108419
|
}
|
|
108230
108420
|
function modalBackdropStyle(_theme) {
|
|
108231
108421
|
return {
|
|
@@ -108250,83 +108440,24 @@ function modalStyle(theme) {
|
|
|
108250
108440
|
};
|
|
108251
108441
|
}
|
|
108252
108442
|
function HelpPanel(props) {
|
|
108253
|
-
|
|
108254
|
-
|
|
108255
|
-
|
|
108256
|
-
|
|
108257
|
-
}, import_react3.default.createElement("box", {
|
|
108258
|
-
id: "help-panel",
|
|
108443
|
+
return renderModalText({
|
|
108444
|
+
theme: props.theme,
|
|
108445
|
+
backdropId: "help-panel-backdrop",
|
|
108446
|
+
panelId: "help-panel",
|
|
108259
108447
|
title: "Key help",
|
|
108260
|
-
|
|
108261
|
-
|
|
108262
|
-
}, import_react3.default.createElement("text", { content: renderKeyHelp().join(`
|
|
108263
|
-
`) })));
|
|
108448
|
+
content: renderKeyHelp()
|
|
108449
|
+
});
|
|
108264
108450
|
}
|
|
108265
108451
|
function WarningPanel(props) {
|
|
108266
108452
|
const theme = props.theme ?? buildTuiTheme();
|
|
108267
|
-
return
|
|
108268
|
-
|
|
108453
|
+
return renderModalText({
|
|
108454
|
+
theme,
|
|
108455
|
+
backdropId: "warning-panel-backdrop",
|
|
108456
|
+
panelId: "warning-panel",
|
|
108269
108457
|
title: "Warning details",
|
|
108270
|
-
|
|
108271
|
-
|
|
108272
|
-
|
|
108273
|
-
borderColor: theme.feedback.warning,
|
|
108274
|
-
flexDirection: "column"
|
|
108275
|
-
}
|
|
108276
|
-
}, import_react3.default.createElement("text", {
|
|
108277
|
-
content: props.model.warnings.length > 0 ? props.model.warnings.map((warning) => `! ${warning}`).join(`
|
|
108278
|
-
`) : "No warnings"
|
|
108279
|
-
}));
|
|
108280
|
-
}
|
|
108281
|
-
function renderMoveInteraction(model, selection) {
|
|
108282
|
-
const view = buildMovePromptViewModel(model, selection);
|
|
108283
|
-
if (!view)
|
|
108284
|
-
return ["Move", "No Issue selected"];
|
|
108285
|
-
return [
|
|
108286
|
-
`${view.title} to Status`,
|
|
108287
|
-
...view.targets.map((target) => `${target.selected ? ">" : " "} ${target.id} (${target.title})`),
|
|
108288
|
-
view.hint
|
|
108289
|
-
];
|
|
108290
|
-
}
|
|
108291
|
-
function renderNoteInteraction(model, selection) {
|
|
108292
|
-
const view = buildNotePromptViewModel(model, selection);
|
|
108293
|
-
if (!view)
|
|
108294
|
-
return ["Append note", "No Issue selected"];
|
|
108295
|
-
return [
|
|
108296
|
-
view.title,
|
|
108297
|
-
`Note: ${view.draft}`,
|
|
108298
|
-
...view.feedback ? [view.feedback] : [],
|
|
108299
|
-
view.hint
|
|
108300
|
-
];
|
|
108301
|
-
}
|
|
108302
|
-
function renderArchiveInteraction(model, selection) {
|
|
108303
|
-
const view = buildArchivePromptViewModel(model, selection);
|
|
108304
|
-
if (!view)
|
|
108305
|
-
return ["Archive", "No Issue selected"];
|
|
108306
|
-
return [view.title, view.body, view.hint];
|
|
108307
|
-
}
|
|
108308
|
-
function renderGitHubMirrorInteraction(model, selection) {
|
|
108309
|
-
const view = buildGitHubMirrorPromptViewModel(model, selection);
|
|
108310
|
-
if (!view)
|
|
108311
|
-
return ["GitHub Mirror", "No Issue selected"];
|
|
108312
|
-
return [view.title, view.body, view.hint];
|
|
108313
|
-
}
|
|
108314
|
-
function renderKeyHelp() {
|
|
108315
|
-
return [
|
|
108316
|
-
"Key help",
|
|
108317
|
-
"\u2191/\u2193 or j/k card/scroll",
|
|
108318
|
-
"\u2190/\u2192 or h/l column",
|
|
108319
|
-
"enter detail/confirm",
|
|
108320
|
-
"esc back/cancel",
|
|
108321
|
-
"H/L move Issue",
|
|
108322
|
-
"m move menu",
|
|
108323
|
-
"n append Note",
|
|
108324
|
-
"a archive Issue",
|
|
108325
|
-
"g GitHub Mirror",
|
|
108326
|
-
"w warning details",
|
|
108327
|
-
"r reload",
|
|
108328
|
-
"q quit"
|
|
108329
|
-
];
|
|
108458
|
+
content: renderWarningDetails(props.model).slice(1),
|
|
108459
|
+
panelStyle: { borderColor: theme.feedback.warning }
|
|
108460
|
+
});
|
|
108330
108461
|
}
|
|
108331
108462
|
|
|
108332
108463
|
// ../tui/src/mutations.ts
|
|
@@ -108347,6 +108478,9 @@ function refreshTuiModel(options) {
|
|
|
108347
108478
|
moveTargetIndex: stillSelected ? options.selection.moveTargetIndex : undefined,
|
|
108348
108479
|
noteOpen: stillSelected ? options.selection.noteOpen : false,
|
|
108349
108480
|
noteDraft: stillSelected ? options.selection.noteDraft : undefined,
|
|
108481
|
+
labelOpen: stillSelected ? options.selection.labelOpen : false,
|
|
108482
|
+
labelFocusIndex: stillSelected ? options.selection.labelFocusIndex : undefined,
|
|
108483
|
+
labelDraftIds: stillSelected ? options.selection.labelDraftIds : undefined,
|
|
108350
108484
|
message: options.selection.message,
|
|
108351
108485
|
archiveOpen: stillSelected ? options.selection.archiveOpen : false,
|
|
108352
108486
|
githubConfirmOpen: stillSelected ? options.selection.githubConfirmOpen : false,
|
|
@@ -108439,6 +108573,59 @@ function archiveSelectedIssue(options) {
|
|
|
108439
108573
|
selection: { ...result.selection, archiveOpen: false }
|
|
108440
108574
|
} : result;
|
|
108441
108575
|
}
|
|
108576
|
+
function updateSelectedIssueLabels(options) {
|
|
108577
|
+
const card = selectedCard(options.model, options.selection);
|
|
108578
|
+
if (!card) {
|
|
108579
|
+
return {
|
|
108580
|
+
ok: false,
|
|
108581
|
+
model: options.model,
|
|
108582
|
+
selection: { ...options.selection, labelOpen: false },
|
|
108583
|
+
message: "No Issue selected"
|
|
108584
|
+
};
|
|
108585
|
+
}
|
|
108586
|
+
const loaded = loadProjectConfig(options.cwd ?? process.cwd());
|
|
108587
|
+
if (!loaded.ok) {
|
|
108588
|
+
return {
|
|
108589
|
+
ok: false,
|
|
108590
|
+
model: options.model,
|
|
108591
|
+
selection: { ...options.selection, labelOpen: false },
|
|
108592
|
+
message: loaded.error.message
|
|
108593
|
+
};
|
|
108594
|
+
}
|
|
108595
|
+
const selectedKnown = new Set(options.selection.labelDraftIds ?? []);
|
|
108596
|
+
const configuredIds = loaded.value.config.labels.map((label) => label.id);
|
|
108597
|
+
const configuredSet = new Set(configuredIds);
|
|
108598
|
+
const knownLabels = configuredIds.filter((label) => selectedKnown.has(label));
|
|
108599
|
+
const unknownLabels = card.labels.filter((label) => !configuredSet.has(label));
|
|
108600
|
+
const updated = updateIssue({
|
|
108601
|
+
projectRoot: loaded.value.projectRoot,
|
|
108602
|
+
config: loaded.value.config,
|
|
108603
|
+
id: card.id,
|
|
108604
|
+
labels: [...knownLabels, ...unknownLabels],
|
|
108605
|
+
preserveUnknownLabels: true,
|
|
108606
|
+
now: options.now
|
|
108607
|
+
});
|
|
108608
|
+
if (!updated.ok) {
|
|
108609
|
+
return {
|
|
108610
|
+
ok: false,
|
|
108611
|
+
model: options.model,
|
|
108612
|
+
selection: { ...options.selection, labelOpen: false },
|
|
108613
|
+
message: updated.error.message
|
|
108614
|
+
};
|
|
108615
|
+
}
|
|
108616
|
+
const model = loadTuiModel(options.cwd);
|
|
108617
|
+
const selection = findSelectionByCardId(model, card.id) ?? clampSelection(model, options.selection);
|
|
108618
|
+
return {
|
|
108619
|
+
ok: true,
|
|
108620
|
+
model,
|
|
108621
|
+
selection: {
|
|
108622
|
+
...selection,
|
|
108623
|
+
detailOpen: options.selection.detailOpen,
|
|
108624
|
+
labelOpen: false
|
|
108625
|
+
},
|
|
108626
|
+
message: `${card.id} Labels updated`
|
|
108627
|
+
};
|
|
108628
|
+
}
|
|
108442
108629
|
async function beginSelectedIssueGitHubMirror(options) {
|
|
108443
108630
|
if (options.selection.githubBusy)
|
|
108444
108631
|
return githubAlreadyRunning(options);
|
|
@@ -108608,7 +108795,7 @@ function appendSelectedIssueNote(options) {
|
|
|
108608
108795
|
return {
|
|
108609
108796
|
ok: false,
|
|
108610
108797
|
model: options.model,
|
|
108611
|
-
selection: { ...options.selection, noteOpen:
|
|
108798
|
+
selection: { ...options.selection, noteOpen: true },
|
|
108612
108799
|
message: "Note cannot be empty"
|
|
108613
108800
|
};
|
|
108614
108801
|
}
|
|
@@ -108655,7 +108842,8 @@ function appendSelectedIssueNote(options) {
|
|
|
108655
108842
|
selection: {
|
|
108656
108843
|
...selection,
|
|
108657
108844
|
detailOpen: options.selection.detailOpen,
|
|
108658
|
-
noteOpen: false
|
|
108845
|
+
noteOpen: false,
|
|
108846
|
+
noteDraft: undefined
|
|
108659
108847
|
},
|
|
108660
108848
|
message: `${card.id} note appended`
|
|
108661
108849
|
};
|
|
@@ -108672,7 +108860,9 @@ function TuiAppView({
|
|
|
108672
108860
|
theme = buildTuiTheme(),
|
|
108673
108861
|
viewportHeight,
|
|
108674
108862
|
viewportWidth,
|
|
108675
|
-
columns
|
|
108863
|
+
columns,
|
|
108864
|
+
noteTextareaRef,
|
|
108865
|
+
onNoteSubmit
|
|
108676
108866
|
}) {
|
|
108677
108867
|
const details = selection.detailOpen ? getSelectedDetails(model, selection) : undefined;
|
|
108678
108868
|
return import_react20.default.createElement("box", {
|
|
@@ -108698,7 +108888,13 @@ function TuiAppView({
|
|
|
108698
108888
|
viewportHeight,
|
|
108699
108889
|
viewportWidth,
|
|
108700
108890
|
columns
|
|
108701
|
-
})), selection.moveOpen ? import_react20.default.createElement(MovePrompt, { model, selection, theme }) : undefined, selection.noteOpen ? import_react20.default.createElement(NotePrompt, {
|
|
108891
|
+
})), selection.moveOpen ? import_react20.default.createElement(MovePrompt, { model, selection, theme }) : undefined, selection.noteOpen ? import_react20.default.createElement(NotePrompt, {
|
|
108892
|
+
model,
|
|
108893
|
+
selection,
|
|
108894
|
+
theme,
|
|
108895
|
+
noteTextareaRef,
|
|
108896
|
+
onNoteSubmit
|
|
108897
|
+
}) : undefined, selection.labelOpen ? import_react20.default.createElement(LabelPrompt, { model, selection, theme }) : undefined, selection.archiveOpen ? import_react20.default.createElement(ArchivePrompt, { model, selection, theme }) : undefined, selection.githubConfirmOpen ? import_react20.default.createElement(GitHubMirrorPrompt, { model, selection, theme }) : undefined, selection.warningsOpen ? import_react20.default.createElement(WarningPanel, { model, theme }) : undefined, selection.helpOpen ? import_react20.default.createElement(HelpPanel, { theme }) : undefined, import_react20.default.createElement(Footer, {
|
|
108702
108898
|
message: selection.message,
|
|
108703
108899
|
mode: footerMode(selection),
|
|
108704
108900
|
theme
|
|
@@ -108732,6 +108928,19 @@ async function launchTui(options = {}) {
|
|
|
108732
108928
|
const modelRef = import_react20.default.useRef(model);
|
|
108733
108929
|
const selectionRef = import_react20.default.useRef(selection);
|
|
108734
108930
|
const githubBusyRef = import_react20.default.useRef(false);
|
|
108931
|
+
const noteTextareaRef = import_react20.default.useRef(null);
|
|
108932
|
+
const submitNote = import_react20.default.useCallback((body) => {
|
|
108933
|
+
const result = appendSelectedIssueNote({
|
|
108934
|
+
cwd: options.cwd,
|
|
108935
|
+
model: modelRef.current,
|
|
108936
|
+
selection: selectionRef.current,
|
|
108937
|
+
body
|
|
108938
|
+
});
|
|
108939
|
+
modelRef.current = result.model;
|
|
108940
|
+
selectionRef.current = { ...result.selection, message: result.message };
|
|
108941
|
+
setModel(result.model);
|
|
108942
|
+
setSelection({ ...result.selection, message: result.message });
|
|
108943
|
+
}, []);
|
|
108735
108944
|
modelRef.current = model;
|
|
108736
108945
|
selectionRef.current = selection;
|
|
108737
108946
|
import_react20.default.useEffect(() => {
|
|
@@ -108749,7 +108958,7 @@ async function launchTui(options = {}) {
|
|
|
108749
108958
|
return () => clearInterval(interval);
|
|
108750
108959
|
}, []);
|
|
108751
108960
|
useKeyboard2((key) => {
|
|
108752
|
-
const action = keyToTuiAction(key.name, key.shift);
|
|
108961
|
+
const action = keyToTuiAction(key.name, key.shift, key.ctrl);
|
|
108753
108962
|
if (selection.helpOpen) {
|
|
108754
108963
|
if (action === "escape" || action === "help") {
|
|
108755
108964
|
setSelection((current) => moveSelection(model, current, action));
|
|
@@ -108757,26 +108966,10 @@ async function launchTui(options = {}) {
|
|
|
108757
108966
|
return;
|
|
108758
108967
|
}
|
|
108759
108968
|
if (selection.noteOpen) {
|
|
108760
|
-
if (action === "help") {
|
|
108761
|
-
setSelection((current) => moveSelection(model, current, action));
|
|
108762
|
-
return;
|
|
108763
|
-
}
|
|
108764
108969
|
if (action === "escape") {
|
|
108765
108970
|
setSelection((current) => moveSelection(model, current, action));
|
|
108766
108971
|
return;
|
|
108767
108972
|
}
|
|
108768
|
-
if (action === "enter") {
|
|
108769
|
-
const result = appendSelectedIssueNote({
|
|
108770
|
-
cwd: options.cwd,
|
|
108771
|
-
model,
|
|
108772
|
-
selection,
|
|
108773
|
-
body: selection.noteDraft ?? ""
|
|
108774
|
-
});
|
|
108775
|
-
setModel(result.model);
|
|
108776
|
-
setSelection({ ...result.selection, message: result.message });
|
|
108777
|
-
return;
|
|
108778
|
-
}
|
|
108779
|
-
setSelection((current) => applyNoteInput(current, key.name, key.shift));
|
|
108780
108973
|
return;
|
|
108781
108974
|
}
|
|
108782
108975
|
if (selection.archiveOpen) {
|
|
@@ -108831,6 +109024,35 @@ async function launchTui(options = {}) {
|
|
|
108831
109024
|
}
|
|
108832
109025
|
return;
|
|
108833
109026
|
}
|
|
109027
|
+
if (selection.labelOpen) {
|
|
109028
|
+
if (action === "help") {
|
|
109029
|
+
setSelection((current) => moveSelection(model, current, action));
|
|
109030
|
+
return;
|
|
109031
|
+
}
|
|
109032
|
+
if (action === "escape") {
|
|
109033
|
+
setSelection((current) => moveSelection(model, current, action));
|
|
109034
|
+
return;
|
|
109035
|
+
}
|
|
109036
|
+
if (action === "up" || action === "down") {
|
|
109037
|
+
setSelection((current) => moveLabelFocus(model, current, action));
|
|
109038
|
+
return;
|
|
109039
|
+
}
|
|
109040
|
+
if (key.name === "space") {
|
|
109041
|
+
setSelection((current) => toggleFocusedLabel(model, current));
|
|
109042
|
+
return;
|
|
109043
|
+
}
|
|
109044
|
+
if (action === "enter") {
|
|
109045
|
+
const result = updateSelectedIssueLabels({
|
|
109046
|
+
cwd: options.cwd,
|
|
109047
|
+
model,
|
|
109048
|
+
selection
|
|
109049
|
+
});
|
|
109050
|
+
setModel(result.model);
|
|
109051
|
+
setSelection({ ...result.selection, message: result.message });
|
|
109052
|
+
return;
|
|
109053
|
+
}
|
|
109054
|
+
return;
|
|
109055
|
+
}
|
|
108834
109056
|
if (!action)
|
|
108835
109057
|
return;
|
|
108836
109058
|
if (action === "quit") {
|
|
@@ -108880,6 +109102,8 @@ async function launchTui(options = {}) {
|
|
|
108880
109102
|
setSelection((current) => moveSelection(model, current, action));
|
|
108881
109103
|
return;
|
|
108882
109104
|
}
|
|
109105
|
+
if (action === "save-note")
|
|
109106
|
+
return;
|
|
108883
109107
|
if (action === "github") {
|
|
108884
109108
|
if (githubBusyRef.current)
|
|
108885
109109
|
return;
|
|
@@ -108912,7 +109136,9 @@ async function launchTui(options = {}) {
|
|
|
108912
109136
|
selection,
|
|
108913
109137
|
viewportHeight: renderer.height,
|
|
108914
109138
|
viewportWidth: renderer.width,
|
|
108915
|
-
columns: options.columns
|
|
109139
|
+
columns: options.columns,
|
|
109140
|
+
noteTextareaRef,
|
|
109141
|
+
onNoteSubmit: submitNote
|
|
108916
109142
|
});
|
|
108917
109143
|
}
|
|
108918
109144
|
root.render(import_react20.default.createElement(App));
|
|
@@ -109191,7 +109417,10 @@ function fireHooks(loaded, issue2, fromStatus, toStatus, options) {
|
|
|
109191
109417
|
...hooks?.on_enter?.[toStatus] ?? [],
|
|
109192
109418
|
...hooks?.on_transition?.[`${fromStatus}->${toStatus}`] ?? []
|
|
109193
109419
|
];
|
|
109194
|
-
for (const
|
|
109420
|
+
for (const entry of commands2) {
|
|
109421
|
+
const command = hookCommandForIssue(entry, loaded, issue2, options);
|
|
109422
|
+
if (!command)
|
|
109423
|
+
continue;
|
|
109195
109424
|
const rendered = renderHookCommand(command, {
|
|
109196
109425
|
project_root: loaded.projectRoot,
|
|
109197
109426
|
issue_path: issue2.path,
|
|
@@ -109217,6 +109446,22 @@ function fireHooks(loaded, issue2, fromStatus, toStatus, options) {
|
|
|
109217
109446
|
}
|
|
109218
109447
|
}
|
|
109219
109448
|
}
|
|
109449
|
+
function hookCommandForIssue(entry, loaded, issue2, options) {
|
|
109450
|
+
if (typeof entry === "string")
|
|
109451
|
+
return entry;
|
|
109452
|
+
const labelsInclude = entry.when?.labels_include;
|
|
109453
|
+
if (!labelsInclude)
|
|
109454
|
+
return entry.command;
|
|
109455
|
+
const knownLabels = new Set(loaded.config.labels.map((label) => label.id));
|
|
109456
|
+
for (const label of labelsInclude) {
|
|
109457
|
+
if (!knownLabels.has(label)) {
|
|
109458
|
+
emitError(options, `hook skipped: ${String(issue2.issue.id)} references unknown label in hook filter: ${label}`);
|
|
109459
|
+
return;
|
|
109460
|
+
}
|
|
109461
|
+
}
|
|
109462
|
+
const issueLabels = new Set(issue2.issue.labels.map(String));
|
|
109463
|
+
return labelsInclude.every((label) => issueLabels.has(label)) ? entry.command : undefined;
|
|
109464
|
+
}
|
|
109220
109465
|
function recordGitHubMirrorPushFailure(projectRoot, issueId, message, options) {
|
|
109221
109466
|
appendHookFailure(projectRoot, {
|
|
109222
109467
|
timestamp: utcNow3(options.now),
|
|
@@ -109628,6 +109873,10 @@ function helpText() {
|
|
|
109628
109873
|
Usage:
|
|
109629
109874
|
mikan <command> [options]
|
|
109630
109875
|
|
|
109876
|
+
Options:
|
|
109877
|
+
-v, --version Print mikan version
|
|
109878
|
+
-h, --help Show this help
|
|
109879
|
+
|
|
109631
109880
|
Commands:
|
|
109632
109881
|
init Create .mikan project files
|
|
109633
109882
|
add Create an Issue
|
|
@@ -109858,6 +110107,9 @@ async function runCli(argv = process.argv.slice(2), options = {}) {
|
|
|
109858
110107
|
const command = argv[0];
|
|
109859
110108
|
if (!command || isHelpFlag(command))
|
|
109860
110109
|
return ok2(helpText());
|
|
110110
|
+
if (isVersionFlag(command))
|
|
110111
|
+
return ok2(`${package_default.version}
|
|
110112
|
+
`);
|
|
109861
110113
|
if (command === "help") {
|
|
109862
110114
|
const topic = argv[1];
|
|
109863
110115
|
return topic ? commandHelp(topic) : ok2(helpText());
|
|
@@ -109916,6 +110168,9 @@ Run \`mikan help tui\` for usage.`);
|
|
|
109916
110168
|
return fail2(error51 instanceof Error ? error51.message : String(error51));
|
|
109917
110169
|
}
|
|
109918
110170
|
}
|
|
110171
|
+
function isVersionFlag(input) {
|
|
110172
|
+
return input === "-v" || input === "--version";
|
|
110173
|
+
}
|
|
109919
110174
|
async function main(argv = process.argv.slice(2)) {
|
|
109920
110175
|
const result = await runInteractiveCommand(argv, { cwd: process.cwd() });
|
|
109921
110176
|
if (result.stdout)
|