@takemo101/mikan 0.0.8 → 0.0.10

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.
Files changed (3) hide show
  1. package/README.md +7 -2
  2. package/dist/bin.js +172 -39
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -57,14 +57,19 @@ GitHub Mirror is one-way publication from local Markdown Issues to GitHub Issues
57
57
 
58
58
  mikan wires into AI coding agents two independent ways. Neither models agents or adds a runtime: mikan stays **stdio MCP only** — no HTTP server, port, auth, scheduler, or workflow engine.
59
59
 
60
- - `mikan mcp add --agent <agent>` registers the stdio MCP server in the agent's MCP config. Agents: `pi`, `antigravity`, `jcode`, `claude-code`, `opencode`, `codex`.
61
- - `mikan skills add --agent <agent>` installs a small mikan `SKILL.md` that teaches the agent to drive the board through the MCP tools, including one-way GitHub Mirror publication tools. Agents: `claude-code`, `opencode`, `codex`. This is **separate** from MCP registration — installing skills never changes MCP config.
60
+ - `mikan mcp add --agent <agent>` registers the stdio MCP server in the agent's MCP config. Agents: `pi`, `antigravity`, `jcode`, `claude-code`, `opencode`, `codex`, `copilot-vscode`, `copilot-cli`.
61
+ - `mikan skills add --agent <agent>` installs a small mikan `SKILL.md` using each agent's native Agent Skills convention. Agents: `pi`, `antigravity`, `jcode`, `claude-code`, `opencode`, `codex`, `copilot-vscode`, `copilot-cli`. This is **separate** from MCP registration — installing skills never changes MCP config.
62
62
 
63
63
  ```sh
64
64
  mikan mcp add --agent claude-code
65
65
  mikan mcp add --agent opencode --no-global
66
66
  mikan mcp add --agent codex # global only
67
+ mikan mcp add --agent copilot-vscode --no-global # VS Code workspace only
68
+ mikan mcp add --agent copilot-cli # global only
69
+ mikan skills add --agent pi
70
+ mikan skills add --agent antigravity --no-global
67
71
  mikan skills add --agent claude-code
72
+ mikan skills add --agent copilot-cli
68
73
  mikan mcp llms # incur-backed discovery manifest
69
74
  ```
70
75
 
package/dist/bin.js CHANGED
@@ -100489,6 +100489,7 @@ function validateStatus(config2, status) {
100489
100489
  }
100490
100490
  function validateLabels(config2, labels) {
100491
100491
  const known = new Set(config2.labels.map((label) => label.id));
100492
+ const seen = new Set;
100492
100493
  const parsed = [];
100493
100494
  for (const label of labels) {
100494
100495
  if (!known.has(label)) {
@@ -100504,6 +100505,13 @@ function validateLabels(config2, labels) {
100504
100505
  error: { kind: "unknown_label", message: labelId.error.message }
100505
100506
  };
100506
100507
  }
100508
+ if (seen.has(label)) {
100509
+ return {
100510
+ ok: false,
100511
+ error: { kind: "unknown_label", message: `Duplicate Label: ${label}` }
100512
+ };
100513
+ }
100514
+ seen.add(label);
100507
100515
  parsed.push(labelId.value);
100508
100516
  }
100509
100517
  return { ok: true, value: parsed };
@@ -106953,6 +106961,55 @@ var codexInstaller = {
106953
106961
  install: installCodexMcpServer
106954
106962
  };
106955
106963
 
106964
+ // ../mcp/src/installers/copilot-cli.ts
106965
+ var copilotCliAdapter = {
106966
+ agent: "copilot-cli",
106967
+ serversKey: "mcpServers",
106968
+ resolveTarget: (options) => {
106969
+ if (!isGlobalScope(options)) {
106970
+ throw new Error("GitHub Copilot CLI MCP configuration is global-only; it has no " + "verified workspace-local scope. Re-run `mikan mcp add --agent " + "copilot-cli` without --no-global to register the server in " + "~/.copilot/mcp-config.json.");
106971
+ }
106972
+ return {
106973
+ path: homePath(options, ".copilot", "mcp-config.json"),
106974
+ scope: "global"
106975
+ };
106976
+ },
106977
+ buildEntry: (spec) => ({
106978
+ type: "local",
106979
+ command: spec.command,
106980
+ args: spec.args,
106981
+ env: spec.env,
106982
+ tools: ["*"]
106983
+ })
106984
+ };
106985
+ var copilotCliInstaller = createInstaller(copilotCliAdapter);
106986
+
106987
+ // ../mcp/src/installers/copilot-vscode.ts
106988
+ var copilotVscodeAdapter = {
106989
+ agent: "copilot-vscode",
106990
+ serversKey: "servers",
106991
+ resolveTarget: (options) => {
106992
+ if (isGlobalScope(options)) {
106993
+ throw new Error("VS Code user-profile MCP configuration path is not verified; " + "re-run `mikan mcp add --agent copilot-vscode --no-global` " + "to register mikan in .vscode/mcp.json for this workspace.");
106994
+ }
106995
+ return {
106996
+ path: workspacePath(options, ".vscode", "mcp.json"),
106997
+ scope: "workspace"
106998
+ };
106999
+ },
107000
+ buildEntry: (spec) => {
107001
+ const entry = {
107002
+ type: "stdio",
107003
+ command: spec.command,
107004
+ args: spec.args
107005
+ };
107006
+ if (Object.keys(spec.env).length > 0)
107007
+ entry.env = spec.env;
107008
+ return entry;
107009
+ }
107010
+ };
107011
+ var copilotVscodeInstaller = createInstaller(copilotVscodeAdapter);
107012
+
106956
107013
  // ../mcp/src/installers/jcode.ts
106957
107014
  var jcodeAdapter = {
106958
107015
  agent: "jcode",
@@ -107009,7 +107066,9 @@ var mcpAgentInstallers = [
107009
107066
  jcodeInstaller,
107010
107067
  claudeCodeInstaller,
107011
107068
  opencodeInstaller,
107012
- codexInstaller
107069
+ codexInstaller,
107070
+ copilotVscodeInstaller,
107071
+ copilotCliInstaller
107013
107072
  ];
107014
107073
  function installMcpServerForAgent(agent, options = {}) {
107015
107074
  const installer = mcpAgentInstallers.find((entry) => entry.agent === agent);
@@ -107019,12 +107078,11 @@ function installMcpServerForAgent(agent, options = {}) {
107019
107078
  return installer.install(options);
107020
107079
  }
107021
107080
  // ../mcp/src/skills/shared.ts
107022
- var skillDocument = `---
107081
+ var skillFrontmatter = `---
107023
107082
  name: mikan
107024
107083
  description: mikan is a local-first Issue board for AI-assisted development. Use it to read the board; create, update, move, and append to Issues; and explicitly publish GitHub Mirrors through the mikan MCP tools. Trigger when the user wants to see the board, add or change an Issue, move an Issue to another Status, record a Report or Note, publish a GitHub Mirror, or decide what to work on next.
107025
- ---
107026
-
107027
- # mikan
107084
+ ---`;
107085
+ var instructionDocument = `# mikan
107028
107086
 
107029
107087
  mikan is a tiny, local-first, Markdown-backed Issue board. Each Issue has a
107030
107088
  stable Issue ID such as \`MIK-001\`, one current Status (the board Column it
@@ -107062,6 +107120,9 @@ mikan does not schedule, auto-move, or block Issues on dependencies.
107062
107120
  Use Issue, Issue ID, Status, Column, Label, Report, Note, and Dependency. Avoid
107063
107121
  Task, ticket, profile, and role.
107064
107122
  `;
107123
+ var skillDocument = `${skillFrontmatter}
107124
+
107125
+ ${instructionDocument}`;
107065
107126
  function globalSkillPath(options, ...segments) {
107066
107127
  return homePath(options, ...segments);
107067
107128
  }
@@ -107079,6 +107140,19 @@ function createSkillInstaller(adapter) {
107079
107140
  };
107080
107141
  }
107081
107142
 
107143
+ // ../mcp/src/skills/antigravity.ts
107144
+ var antigravityAdapter2 = {
107145
+ agent: "antigravity",
107146
+ resolveTarget: (options) => isGlobalScope(options) ? {
107147
+ path: globalSkillPath(options, ".gemini", "antigravity-cli", "skills", "mikan", "SKILL.md"),
107148
+ scope: "global"
107149
+ } : {
107150
+ path: workspaceSkillPath(options, ".agents", "skills", "mikan", "SKILL.md"),
107151
+ scope: "workspace"
107152
+ }
107153
+ };
107154
+ var antigravitySkillInstaller = createSkillInstaller(antigravityAdapter2);
107155
+
107082
107156
  // ../mcp/src/skills/claude-code.ts
107083
107157
  var claudeCodeAdapter2 = {
107084
107158
  agent: "claude-code",
@@ -107107,6 +107181,45 @@ var codexAdapter = {
107107
107181
  };
107108
107182
  var codexSkillInstaller = createSkillInstaller(codexAdapter);
107109
107183
 
107184
+ // ../mcp/src/skills/copilot-cli.ts
107185
+ var copilotCliAdapter2 = {
107186
+ agent: "copilot-cli",
107187
+ resolveTarget: (options) => isGlobalScope(options) ? {
107188
+ path: globalSkillPath(options, ".copilot", "skills", "mikan", "SKILL.md"),
107189
+ scope: "global"
107190
+ } : {
107191
+ path: workspaceSkillPath(options, ".github", "skills", "mikan", "SKILL.md"),
107192
+ scope: "workspace"
107193
+ }
107194
+ };
107195
+ var copilotCliSkillInstaller = createSkillInstaller(copilotCliAdapter2);
107196
+
107197
+ // ../mcp/src/skills/copilot-vscode.ts
107198
+ var copilotVscodeAdapter2 = {
107199
+ agent: "copilot-vscode",
107200
+ resolveTarget: (options) => isGlobalScope(options) ? {
107201
+ path: globalSkillPath(options, ".copilot", "skills", "mikan", "SKILL.md"),
107202
+ scope: "global"
107203
+ } : {
107204
+ path: workspaceSkillPath(options, ".github", "skills", "mikan", "SKILL.md"),
107205
+ scope: "workspace"
107206
+ }
107207
+ };
107208
+ var copilotVscodeSkillInstaller = createSkillInstaller(copilotVscodeAdapter2);
107209
+
107210
+ // ../mcp/src/skills/jcode.ts
107211
+ var jcodeAdapter2 = {
107212
+ agent: "jcode",
107213
+ resolveTarget: (options) => isGlobalScope(options) ? {
107214
+ path: globalSkillPath(options, ".jcode", "skills", "mikan", "SKILL.md"),
107215
+ scope: "global"
107216
+ } : {
107217
+ path: workspaceSkillPath(options, ".jcode", "skills", "mikan", "SKILL.md"),
107218
+ scope: "workspace"
107219
+ }
107220
+ };
107221
+ var jcodeSkillInstaller = createSkillInstaller(jcodeAdapter2);
107222
+
107110
107223
  // ../mcp/src/skills/opencode.ts
107111
107224
  var opencodeAdapter2 = {
107112
107225
  agent: "opencode",
@@ -107120,11 +107233,29 @@ var opencodeAdapter2 = {
107120
107233
  };
107121
107234
  var opencodeSkillInstaller = createSkillInstaller(opencodeAdapter2);
107122
107235
 
107236
+ // ../mcp/src/skills/pi.ts
107237
+ var piAdapter2 = {
107238
+ agent: "pi",
107239
+ resolveTarget: (options) => isGlobalScope(options) ? {
107240
+ path: globalSkillPath(options, ".pi", "agent", "skills", "mikan", "SKILL.md"),
107241
+ scope: "global"
107242
+ } : {
107243
+ path: workspaceSkillPath(options, ".pi", "skills", "mikan", "SKILL.md"),
107244
+ scope: "workspace"
107245
+ }
107246
+ };
107247
+ var piSkillInstaller = createSkillInstaller(piAdapter2);
107248
+
107123
107249
  // ../mcp/src/skills/index.ts
107124
107250
  var skillAgentInstallers = [
107251
+ piSkillInstaller,
107252
+ antigravitySkillInstaller,
107253
+ jcodeSkillInstaller,
107125
107254
  claudeCodeSkillInstaller,
107126
107255
  opencodeSkillInstaller,
107127
- codexSkillInstaller
107256
+ codexSkillInstaller,
107257
+ copilotVscodeSkillInstaller,
107258
+ copilotCliSkillInstaller
107128
107259
  ];
107129
107260
  function installSkillForAgent(agent, options = {}) {
107130
107261
  const installer = skillAgentInstallers.find((entry) => entry.agent === agent);
@@ -107402,7 +107533,7 @@ var import_react20 = __toESM(require_react(), 1);
107402
107533
  // package.json
107403
107534
  var package_default = {
107404
107535
  name: "@takemo101/mikan",
107405
- version: "0.0.8",
107536
+ version: "0.0.10",
107406
107537
  private: false,
107407
107538
  type: "module",
107408
107539
  bin: {
@@ -107463,7 +107594,7 @@ function visibleColumnCountForViewport(viewportWidth) {
107463
107594
  return Math.min(MAX_VISIBLE_COLUMNS, Math.max(MIN_VISIBLE_COLUMNS, fitted));
107464
107595
  }
107465
107596
  function visibleDetailLineCount(viewportHeight) {
107466
- return Math.max(1, viewportHeight - 8);
107597
+ return Math.max(1, viewportHeight - 7);
107467
107598
  }
107468
107599
  function footerText(mode) {
107469
107600
  if (mode === "note-modal") {
@@ -107868,10 +107999,6 @@ function detailTitleContent(page, theme) {
107868
107999
  fg(theme.base.muted)(" \u2502 "),
107869
108000
  fg(theme.base.text)(page.title)
107870
108001
  ];
107871
- if (page.lineRangeText) {
107872
- chunks.push(fg(theme.base.muted)(" \u2502 "));
107873
- chunks.push(fg(theme.base.muted)(page.lineRangeText));
107874
- }
107875
108002
  return new StyledText(chunks);
107876
108003
  }
107877
108004
  function detailMetaContent(page, theme) {
@@ -107920,22 +108047,21 @@ function DetailPage(props) {
107920
108047
  content: detailTitleContent(page, theme)
107921
108048
  }), import_react2.default.createElement("text", {
107922
108049
  content: detailMetaContent(page, theme)
107923
- })), import_react2.default.createElement("box", {
108050
+ })), import_react2.default.createElement("scrollbox", {
107924
108051
  id: "detail-markdown-body",
108052
+ ref: props.detailScrollBoxRef,
108053
+ scrollY: true,
108054
+ scrollX: false,
107925
108055
  style: {
107926
- flexDirection: "column",
107927
108056
  flexGrow: 1,
107928
108057
  minHeight: 0,
107929
108058
  overflow: "hidden"
107930
108059
  }
107931
108060
  }, import_react2.default.createElement("markdown", {
107932
108061
  id: "detail-markdown",
107933
- content: page.visibleMarkdownLines.join(`
107934
- `),
108062
+ content: page.markdown,
107935
108063
  style: {
107936
- flexGrow: 1,
107937
- minHeight: 0,
107938
- overflow: "hidden"
108064
+ width: "100%"
107939
108065
  }
107940
108066
  })));
107941
108067
  }
@@ -107944,7 +108070,7 @@ function DetailPage(props) {
107944
108070
  var import_react3 = __toESM(require_react(), 1);
107945
108071
 
107946
108072
  // ../tui/src/navigation.ts
107947
- function moveSelection(model, selection, direction, options = {}) {
108073
+ function moveSelection(model, selection, direction, _options = {}) {
107948
108074
  if (direction === "enter") {
107949
108075
  const card = model.columns[selection.columnIndex]?.cards[selection.cardIndex];
107950
108076
  if (!card) {
@@ -107959,10 +108085,7 @@ function moveSelection(model, selection, direction, options = {}) {
107959
108085
  }
107960
108086
  if (selection.detailOpen && !selection.moveOpen && !selection.noteOpen && !selection.labelOpen) {
107961
108087
  if (direction === "up" || direction === "down") {
107962
- return {
107963
- ...selection,
107964
- detailScrollOffset: clamp((selection.detailScrollOffset ?? 0) + (direction === "down" ? 1 : -1), 0, detailScrollMax(model, selection, options))
107965
- };
108088
+ return selection;
107966
108089
  }
107967
108090
  if (direction === "left" || direction === "right") {
107968
108091
  return selection;
@@ -108163,14 +108286,6 @@ function keyToTuiAction(keyName2, shift = false, ctrl = false) {
108163
108286
  return;
108164
108287
  }
108165
108288
  }
108166
- function detailScrollMax(model, selection, options = {}) {
108167
- const details = getSelectedDetails(model, selection);
108168
- if (!details)
108169
- return 0;
108170
- const visibleLineCount = options.viewportHeight ? visibleDetailLineCount(options.viewportHeight) : 40;
108171
- return Math.max(0, stripFrontmatter(details.markdown).trimEnd().split(`
108172
- `).length - visibleLineCount);
108173
- }
108174
108289
 
108175
108290
  // ../tui/src/prompt-view-model.ts
108176
108291
  function buildMovePromptViewModel(model, selection) {
@@ -108862,7 +108977,8 @@ function TuiAppView({
108862
108977
  viewportWidth,
108863
108978
  columns,
108864
108979
  noteTextareaRef,
108865
- onNoteSubmit
108980
+ onNoteSubmit,
108981
+ detailScrollBoxRef
108866
108982
  }) {
108867
108983
  const details = selection.detailOpen ? getSelectedDetails(model, selection) : undefined;
108868
108984
  return import_react20.default.createElement("box", {
@@ -108880,7 +108996,8 @@ function TuiAppView({
108880
108996
  model,
108881
108997
  selection,
108882
108998
  theme,
108883
- viewportHeight
108999
+ viewportHeight,
109000
+ detailScrollBoxRef
108884
109001
  }) : import_react20.default.createElement(BoardView, {
108885
109002
  model,
108886
109003
  selection,
@@ -108929,6 +109046,7 @@ async function launchTui(options = {}) {
108929
109046
  const selectionRef = import_react20.default.useRef(selection);
108930
109047
  const githubBusyRef = import_react20.default.useRef(false);
108931
109048
  const noteTextareaRef = import_react20.default.useRef(null);
109049
+ const detailScrollBoxRef = import_react20.default.useRef(null);
108932
109050
  const submitNote = import_react20.default.useCallback((body) => {
108933
109051
  const result = appendSelectedIssueNote({
108934
109052
  cwd: options.cwd,
@@ -109055,6 +109173,10 @@ async function launchTui(options = {}) {
109055
109173
  }
109056
109174
  if (!action)
109057
109175
  return;
109176
+ if (selection.detailOpen && !selection.moveOpen && !selection.noteOpen && !selection.labelOpen && (action === "up" || action === "down")) {
109177
+ detailScrollBoxRef.current?.scrollBy(action === "down" ? 1 : -1);
109178
+ return;
109179
+ }
109058
109180
  if (action === "quit") {
109059
109181
  stop();
109060
109182
  return;
@@ -109138,7 +109260,8 @@ async function launchTui(options = {}) {
109138
109260
  viewportWidth: renderer.width,
109139
109261
  columns: options.columns,
109140
109262
  noteTextareaRef,
109141
- onNoteSubmit: submitNote
109263
+ onNoteSubmit: submitNote,
109264
+ detailScrollBoxRef
109142
109265
  });
109143
109266
  }
109144
109267
  root.render(import_react20.default.createElement(App));
@@ -109543,7 +109666,8 @@ function readCurrentSnapshot(loaded) {
109543
109666
  function writeSnapshot(path5, snapshot) {
109544
109667
  mkdirSync7(dirname8(path5), { recursive: true });
109545
109668
  const tmp = `${path5}.${process.pid}.${Date.now()}.tmp`;
109546
- writeFileSync7(tmp, JSON.stringify(snapshot, null, 2));
109669
+ writeFileSync7(tmp, `${JSON.stringify(snapshot, null, 2)}
109670
+ `);
109547
109671
  renameSync4(tmp, path5);
109548
109672
  }
109549
109673
  function watcherSnapshotPath(projectRoot) {
@@ -110036,13 +110160,14 @@ Usage:
110036
110160
  mikan mcp llms [--full]
110037
110161
 
110038
110162
  Options:
110039
- -a, --agent <agent> Agent to configure: pi, antigravity, jcode, claude-code, opencode, codex
110163
+ -a, --agent <agent> Agent to configure: pi, antigravity, jcode, claude-code, opencode, codex, copilot-vscode, copilot-cli
110040
110164
  --no-global Write workspace-local config instead of global config
110041
110165
  --full With llms: print the full incur manifest
110042
110166
  -h, --help Show this help
110043
110167
 
110044
110168
  Notes:
110045
- codex registers in global ~/.codex/config.toml only; --no-global is rejected.
110169
+ codex and copilot-cli register globally only; --no-global is rejected.
110170
+ copilot-vscode writes workspace .vscode/mcp.json only; use --no-global.
110046
110171
  Use mikan mcp add for native per-agent registration. Use mikan mcp llms for
110047
110172
  incur-backed discovery: it prints a manifest for agents that read incur
110048
110173
  manifests directly and never installs anything. Passing --agent to llms is
@@ -110055,6 +110180,8 @@ Examples:
110055
110180
  mikan mcp add --agent claude-code
110056
110181
  mikan mcp add --agent opencode --no-global
110057
110182
  mikan mcp add --agent codex
110183
+ mikan mcp add --agent copilot-vscode --no-global
110184
+ mikan mcp add --agent copilot-cli
110058
110185
  mikan mcp llms
110059
110186
  mikan mcp llms --full
110060
110187
  `;
@@ -110069,17 +110196,23 @@ Usage:
110069
110196
  mikan skills add --agent <agent> [--no-global]
110070
110197
 
110071
110198
  Options:
110072
- -a, --agent <agent> Agent to install the mikan skill for: claude-code, opencode, codex
110199
+ -a, --agent <agent> Agent to install guidance for: pi, antigravity, jcode, claude-code, opencode, codex, copilot-vscode, copilot-cli
110073
110200
  --no-global Install workspace-local guidance instead of global
110074
110201
  -h, --help Show this help
110075
110202
 
110076
110203
  Notes:
110077
110204
  codex installs the skill globally only; --no-global is rejected for codex.
110205
+ antigravity also has a shared skill location at ~/.gemini/skills/; mikan's global install targets the Antigravity CLI path.
110078
110206
 
110079
110207
  Examples:
110208
+ mikan skills add --agent pi
110209
+ mikan skills add --agent antigravity --no-global
110210
+ mikan skills add --agent jcode
110080
110211
  mikan skills add --agent claude-code
110081
110212
  mikan skills add --agent opencode --no-global
110082
110213
  mikan skills add -a codex
110214
+ mikan skills add --agent copilot-vscode --no-global
110215
+ mikan skills add --agent copilot-cli
110083
110216
  `;
110084
110217
  }
110085
110218
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takemo101/mikan",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {