@celsoft/coordinator 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +107 -0
  3. package/THIRD_PARTY_NOTICES.md +2005 -0
  4. package/agents/console.md +20 -0
  5. package/agents/free.md +110 -0
  6. package/build/0-JP6XL6LB.js +17 -0
  7. package/build/1-A52YZWNS.js +17 -0
  8. package/build/2-CLH2NM6F.js +32 -0
  9. package/build/3-4N467IB6.js +45 -0
  10. package/build/4-WL5H4LUW.js +29 -0
  11. package/build/_layout.svelte-KPUSX7LQ.js +27 -0
  12. package/build/_page.svelte-22H56UR6.js +7972 -0
  13. package/build/_page.svelte-CVWUNRQC.js +135 -0
  14. package/build/_page.svelte-LTZXBHMT.js +57 -0
  15. package/build/_server.ts-3KVBYN6P.js +20 -0
  16. package/build/_server.ts-3POPKVEM.js +47 -0
  17. package/build/_server.ts-5735T2V5.js +31 -0
  18. package/build/_server.ts-5VXGNWV2.js +38 -0
  19. package/build/_server.ts-645KP7WP.js +42 -0
  20. package/build/_server.ts-A3AA24Z2.js +28 -0
  21. package/build/_server.ts-CITUOEM6.js +58 -0
  22. package/build/_server.ts-I7HMTPOA.js +25 -0
  23. package/build/_server.ts-M5BQ4LLX.js +30 -0
  24. package/build/_server.ts-OB4O27HF.js +683 -0
  25. package/build/_server.ts-OJT7HE7M.js +15 -0
  26. package/build/_server.ts-OYGWVLZM.js +12 -0
  27. package/build/_server.ts-T75UVMQP.js +38 -0
  28. package/build/_server.ts-WYZYNHUZ.js +28 -0
  29. package/build/_server.ts-Z26EB47B.js +486 -0
  30. package/build/chunk-4CIG53L5.js +33 -0
  31. package/build/chunk-BJTJS3XY.js +338 -0
  32. package/build/chunk-F2CNWJZM.js +14 -0
  33. package/build/chunk-HGYE3UTU.js +416 -0
  34. package/build/chunk-KAYW2W7H.js +1311 -0
  35. package/build/chunk-LFP3UPCM.js +10 -0
  36. package/build/chunk-M44JEFEH.js +62 -0
  37. package/build/chunk-MC5AGLMY.js +39 -0
  38. package/build/chunk-NCZ77J5E.js +19798 -0
  39. package/build/chunk-NVNLDPUJ.js +2122 -0
  40. package/build/chunk-PDCON4KS.js +494 -0
  41. package/build/chunk-Q4OQNY5M.js +25 -0
  42. package/build/chunk-QCUOR2U5.js +75 -0
  43. package/build/chunk-R6RYZZWA.js +46 -0
  44. package/build/chunk-SOJTASZC.js +51 -0
  45. package/build/chunk-SU26PJVX.js +410 -0
  46. package/build/chunk-U5BSBG4R.js +506 -0
  47. package/build/chunk-UEKOZGRO.js +37 -0
  48. package/build/chunk-W6EFUWJ2.js +9 -0
  49. package/build/chunk-WOPREK6Q.js +117 -0
  50. package/build/chunk-WWJ3F4QS.js +127 -0
  51. package/build/chunk-ZGZJEEE3.js +1091 -0
  52. package/build/client/_app/immutable/assets/0.BGa5ZNDM.css +1 -0
  53. package/build/client/_app/immutable/chunks/BUrrLYDt.js +2 -0
  54. package/build/client/_app/immutable/chunks/BgFr_EyZ.js +4 -0
  55. package/build/client/_app/immutable/chunks/Bjy-W4x2.js +82 -0
  56. package/build/client/_app/immutable/chunks/C8qZab0y.js +56 -0
  57. package/build/client/_app/immutable/chunks/C90fLsA5.js +4 -0
  58. package/build/client/_app/immutable/chunks/CRzLMJPS.js +1 -0
  59. package/build/client/_app/immutable/chunks/DLT1iIlz.js +2 -0
  60. package/build/client/_app/immutable/chunks/pIrVVOVY.js +2 -0
  61. package/build/client/_app/immutable/entry/app.0DERehLW.js +3 -0
  62. package/build/client/_app/immutable/entry/payload.DSmR2FwN.js +2 -0
  63. package/build/client/_app/immutable/entry/start.B7srFiqh.js +3 -0
  64. package/build/client/_app/immutable/nodes/0.aD9vJoxR.js +2 -0
  65. package/build/client/_app/immutable/nodes/1.Br4FL91i.js +2 -0
  66. package/build/client/_app/immutable/nodes/2.vl6OYfu3.js +8 -0
  67. package/build/client/_app/immutable/nodes/3.VYqJOLAF.js +2 -0
  68. package/build/client/_app/immutable/nodes/4.jF9UVlFN.js +2 -0
  69. package/build/client/_app/version.json +1 -0
  70. package/build/client/apple-touch-icon.png +0 -0
  71. package/build/client/favicon.ico +0 -0
  72. package/build/client/favicon.svg +48 -0
  73. package/build/client/icon-192.png +0 -0
  74. package/build/client/icon-512.png +0 -0
  75. package/build/client/icon-maskable-512.png +0 -0
  76. package/build/client/icon.svg +44 -0
  77. package/build/client/manifest.webmanifest +15 -0
  78. package/build/error.svelte-JXZDY65F.js +51 -0
  79. package/build/handler.js +716 -0
  80. package/build/hooks.server-34IMHRKC.js +43 -0
  81. package/build/instance-NP3FJIWW.js +2967 -0
  82. package/client/client.mjs +28 -0
  83. package/client/hooks.mjs +7 -0
  84. package/client/register.mjs +5 -0
  85. package/dist/cli.js +62826 -0
  86. package/dist/port.js +36691 -0
  87. package/package.json +20 -1
  88. package/skills/agents/.claude-plugin/plugin.json +5 -0
  89. package/skills/agents/hooks/hooks.json +1 -0
  90. package/skills/agents/hooks/register.ts +57 -0
  91. package/skills/agents/skills/bus-work/SKILL.md +66 -0
  92. package/skills/agents/skills/plan/SKILL.md +98 -0
  93. package/skills/console/.claude-plugin/plugin.json +5 -0
  94. package/skills/console/hooks/hooks.json +1 -0
  95. package/skills/console/hooks/register.ts +10 -0
  96. package/skills/console/skills/bus/SKILL.md +61 -0
  97. package/skills/default/.claude-plugin/plugin.json +5 -0
  98. package/skills/default/skills/git-workflow/SKILL.md +294 -0
  99. package/skills/default/skills/git-workflow/mise-tasks/_lib.sh +107 -0
  100. package/skills/default/skills/git-workflow/mise-tasks/clone +36 -0
  101. package/skills/default/skills/git-workflow/mise-tasks/repo-list +8 -0
  102. package/skills/default/skills/git-workflow/mise-tasks/unpushed +26 -0
  103. package/skills/default/skills/git-workflow/mise-tasks/worktree-add +60 -0
  104. package/skills/default/skills/github/SKILL.md +208 -0
  105. package/skills/default/skills/github/scripts/gh-org +196 -0
  106. package/skills/default/skills/plan-page/SKILL.md +300 -0
  107. package/skills/default/skills/plan-page/assets/index.html +854 -0
  108. package/skills/default/skills/plan-page/scripts/inline +46 -0
  109. package/skills/default/skills/plan-page/scripts/stage +26 -0
  110. package/skills/default/skills/secrets/SKILL.md +134 -0
  111. package/skills/default/skills/secrets/scripts/secrets-check +87 -0
  112. package/skills/default/skills/writing-style/SKILL.md +45 -0
  113. package/skills/extra/.claude-plugin/plugin.json +5 -0
  114. package/skills/extra/skills/artifacts/SKILL.md +52 -0
  115. package/skills/extra/skills/github-actions/SKILL.md +78 -0
  116. package/skills/extra/skills/github-actions/scan +32 -0
  117. package/skills/extra/skills/markdown-review/SKILL.md +70 -0
  118. package/skills/extra/skills/markdown-review/assets/index.html +201 -0
  119. package/skills/extra/skills/markdown-review/scripts/stage +36 -0
  120. package/skills/extra/skills/mise-usage/SKILL.md +155 -0
  121. package/skills/extra/skills/plugin-authoring/SKILL.md +317 -0
  122. package/skills/extra/skills/project-conventions/SKILL.md +64 -0
  123. package/skills/extra/skills/questions/SKILL.md +156 -0
  124. package/skills/extra/skills/questions/assets/index.html +376 -0
  125. package/skills/extra/skills/questions/scripts/stage +26 -0
  126. package/skills/extra/skills/serve/SKILL.md +165 -0
  127. package/skills/extra/skills/serve/scripts/serve +268 -0
  128. package/skills/extra/skills/serve/scripts/server.py +345 -0
  129. package/skills/extra/skills/skill-dependencies/SKILL.md +65 -0
  130. package/skills/extra/skills/skill-maintenance/SKILL.md +101 -0
  131. package/skills/extra/skills/ticketing/SKILL.md +125 -0
@@ -0,0 +1,201 @@
1
+ <title>Markdown Review</title>
2
+ <style>
3
+ :root {
4
+ --bg: #fbfaf8; --fg: #1f1d1a; --muted: #6b665e; --line: #e4e0d8;
5
+ --code-bg: #f1eee8; --accent: #2f5fbf; --table-head: #f4f1eb;
6
+ --panel: #f5f3ef; --current: #e8e4dc; --group: #e9eef8;
7
+ }
8
+ @media (prefers-color-scheme: dark) {
9
+ :root:not([data-theme="light"]) {
10
+ --bg: #17181a; --fg: #e6e3dd; --muted: #9a958c; --line: #2e3033;
11
+ --code-bg: #222427; --accent: #8fb1ff; --table-head: #1f2123;
12
+ --panel: #1c1d20; --current: #2a2c30; --group: #22293a;
13
+ }
14
+ }
15
+ :root[data-theme="dark"] {
16
+ --bg: #17181a; --fg: #e6e3dd; --muted: #9a958c; --line: #2e3033;
17
+ --code-bg: #222427; --accent: #8fb1ff; --table-head: #1f2123;
18
+ --panel: #1c1d20; --current: #2a2c30; --group: #22293a;
19
+ }
20
+ * { box-sizing: border-box; }
21
+ html, body { height: 100%; }
22
+ body {
23
+ margin: 0; background: var(--bg); color: var(--fg); overflow: hidden;
24
+ font: 16px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
25
+ }
26
+ .layout { display: grid; grid-template-columns: 280px 1fr; height: 100vh; height: 100dvh; }
27
+
28
+ nav {
29
+ overflow-y: auto; background: var(--panel); border-right: 1px solid var(--line);
30
+ padding: 24px 12px 48px; font-size: 14px; line-height: 1.4;
31
+ }
32
+ nav .doc-title { font-weight: 600; padding: 0 8px 12px; }
33
+ nav a {
34
+ display: block; color: var(--muted); text-decoration: none;
35
+ padding: 5px 8px; border-radius: 6px;
36
+ }
37
+ nav a:hover { color: var(--fg); }
38
+ nav a.current { background: var(--current); color: var(--fg); }
39
+ nav a.level-3 { padding-left: 22px; }
40
+ nav a.level-4 { padding-left: 36px; font-size: 13px; }
41
+
42
+ #content { overflow-y: auto; }
43
+ main { max-width: 780px; margin: 0 auto; padding: 32px 24px 96px; }
44
+ .file { color: var(--muted); font: 13px ui-monospace, SFMono-Regular, Menlo, monospace; margin-bottom: 24px; }
45
+ .toggle {
46
+ display: none; position: fixed; top: 12px; right: 12px; z-index: 3;
47
+ background: var(--panel); color: var(--fg); border: 1px solid var(--line);
48
+ border-radius: 8px; padding: 6px 12px; font: inherit; font-size: 14px;
49
+ }
50
+
51
+ h1, h2, h3, h4 { line-height: 1.25; margin: 1.8em 0 0.6em; scroll-margin-top: 16px; }
52
+ h1 { font-size: 2em; margin-top: 0; }
53
+ h2 { font-size: 1.45em; padding-bottom: 0.3em; border-bottom: 1px solid var(--line); }
54
+ h3 { font-size: 1.15em; }
55
+ a { color: var(--accent); }
56
+ p, ul, ol, table, pre, blockquote { margin: 0 0 1em; }
57
+ li { margin: 0.25em 0; }
58
+ code { font: 0.9em ui-monospace, SFMono-Regular, Menlo, monospace; background: var(--code-bg); padding: 0.1em 0.35em; border-radius: 4px; }
59
+ pre { background: var(--code-bg); padding: 14px 16px; border-radius: 8px; overflow-x: auto; }
60
+ pre code { background: none; padding: 0; font-size: 0.85em; }
61
+ blockquote { border-left: 3px solid var(--line); margin-left: 0; padding-left: 16px; color: var(--muted); }
62
+ .table-wrap { overflow-x: auto; margin: 0 0 1em; }
63
+ table { border-collapse: collapse; width: 100%; font-size: 0.93em; margin: 0; }
64
+ th, td { border: 1px solid var(--line); padding: 8px 10px; text-align: left; vertical-align: top; }
65
+ th { background: var(--table-head); }
66
+ td[colspan], th[colspan] { background: var(--group); }
67
+ img { max-width: 100%; }
68
+ hr { border: 0; border-top: 1px solid var(--line); margin: 2em 0; }
69
+ .mermaid { display: flex; justify-content: center; margin: 0 0 1em; overflow-x: auto; }
70
+ .status { color: var(--muted); }
71
+
72
+ @media (max-width: 760px) {
73
+ .layout { grid-template-columns: 1fr; }
74
+ nav {
75
+ display: none; position: fixed; inset: 0 0 0 auto; width: min(300px, 85vw); z-index: 2;
76
+ border-right: 0; border-left: 1px solid var(--line); padding-top: 56px;
77
+ }
78
+ body.outline-open nav { display: block; }
79
+ .toggle { display: block; }
80
+ main { padding: 56px 16px 96px; }
81
+ }
82
+ </style>
83
+
84
+ <button class="toggle" id="toggle" type="button">Outline</button>
85
+ <div class="layout">
86
+ <nav id="outline" aria-label="Outline"></nav>
87
+ <div id="content">
88
+ <main>
89
+ <div class="file" id="file"></div>
90
+ <article id="doc"><p class="status">Loading…</p></article>
91
+ </main>
92
+ </div>
93
+ </div>
94
+
95
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.2/marked.min.js"></script>
96
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.1.6/purify.min.js"></script>
97
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.4.0/mermaid.min.js"></script>
98
+ <script>
99
+ (async () => {
100
+ const doc = document.getElementById("doc");
101
+ const outline = document.getElementById("outline");
102
+ const content = document.getElementById("content");
103
+
104
+ document.getElementById("toggle").addEventListener("click", () => document.body.classList.toggle("outline-open"));
105
+
106
+ const fail = (message) => {
107
+ doc.innerHTML = "";
108
+ const p = document.createElement("p");
109
+ p.className = "status";
110
+ p.textContent = message;
111
+ doc.append(p);
112
+ };
113
+
114
+ let file;
115
+ try {
116
+ const manifest = await (await fetch("document.json", { cache: "no-cache" })).json();
117
+ file = manifest.file;
118
+ if (typeof file !== "string" || !file) throw new Error("document.json has no file");
119
+ } catch (error) {
120
+ return fail("Could not read document.json: " + error.message);
121
+ }
122
+
123
+ document.getElementById("file").textContent = file;
124
+ const response = await fetch(encodeURI(file), { cache: "no-cache" }).catch(() => null);
125
+ if (!response || !response.ok) return fail("Could not load " + file + ".");
126
+ const markdown = await response.text();
127
+
128
+ doc.innerHTML = DOMPurify.sanitize(marked.parse(markdown, { gfm: true }));
129
+
130
+ for (const table of doc.querySelectorAll("table")) {
131
+ const wrap = document.createElement("div");
132
+ wrap.className = "table-wrap";
133
+ table.replaceWith(wrap);
134
+ wrap.append(table);
135
+ }
136
+
137
+ const title = doc.querySelector("h1");
138
+ document.title = title ? title.textContent : file;
139
+ buildOutline(title ? title.textContent : file);
140
+
141
+ const diagrams = [...doc.querySelectorAll("pre > code.language-mermaid")];
142
+ if (diagrams.length) {
143
+ for (const code of diagrams) {
144
+ const div = document.createElement("div");
145
+ div.className = "mermaid";
146
+ div.textContent = code.textContent;
147
+ code.parentElement.replaceWith(div);
148
+ }
149
+ const theme = document.documentElement.dataset.theme;
150
+ const dark = theme ? theme === "dark" : matchMedia("(prefers-color-scheme: dark)").matches;
151
+ mermaid.initialize({ startOnLoad: false, theme: dark ? "dark" : "default", securityLevel: "strict" });
152
+ await mermaid.run({ nodes: doc.querySelectorAll(".mermaid") });
153
+ }
154
+
155
+ function buildOutline(docTitle) {
156
+ const heading = document.createElement("div");
157
+ heading.className = "doc-title";
158
+ heading.textContent = docTitle;
159
+ outline.append(heading);
160
+
161
+ const used = new Set();
162
+ const entries = [];
163
+ for (const h of doc.querySelectorAll("h2, h3, h4")) {
164
+ const base = h.textContent.toLowerCase().trim().replace(/[^\w]+/g, "-").replace(/^-|-$/g, "") || "section";
165
+ let id = base;
166
+ for (let n = 2; used.has(id); n++) id = base + "-" + n;
167
+ used.add(id);
168
+ h.id = id;
169
+
170
+ const link = document.createElement("a");
171
+ link.href = "#" + id;
172
+ link.className = "level-" + h.tagName[1];
173
+ link.textContent = h.textContent;
174
+ link.addEventListener("click", (event) => {
175
+ event.preventDefault();
176
+ h.scrollIntoView({ behavior: "smooth", block: "start" });
177
+ document.body.classList.remove("outline-open");
178
+ });
179
+ outline.append(link);
180
+ entries.push({ h, link });
181
+ }
182
+
183
+ let current;
184
+ const mark = () => {
185
+ const top = content.getBoundingClientRect().top + 24;
186
+ let active = entries[0];
187
+ for (const entry of entries) {
188
+ if (entry.h.getBoundingClientRect().top <= top) active = entry;
189
+ else break;
190
+ }
191
+ if (!active || active === current) return;
192
+ current?.link.classList.remove("current");
193
+ active.link.classList.add("current");
194
+ active.link.scrollIntoView({ block: "nearest" });
195
+ current = active;
196
+ };
197
+ content.addEventListener("scroll", mark, { passive: true });
198
+ mark();
199
+ }
200
+ })();
201
+ </script>
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # stage: prepare the renderer page and document.json for one markdown file.
4
+ #
5
+ # Usage: stage <markdown-file> <out-dir>
6
+ # Prints the three paths to publish, one per line.
7
+
8
+ set -euo pipefail
9
+
10
+ if [ $# -ne 2 ]; then
11
+ echo "usage: stage <markdown-file> <out-dir>" >&2
12
+ exit 2
13
+ fi
14
+
15
+ markdown=$1
16
+ out=$2
17
+ here=$(cd "$(dirname "$0")/.." && pwd)
18
+
19
+ if [ ! -f "$markdown" ]; then
20
+ echo "NOT_FOUND: $markdown" >&2
21
+ exit 1
22
+ fi
23
+
24
+ name=$(basename "$markdown")
25
+ case $name in
26
+ *\"* | *\\*) echo "BAD_NAME: rename the file without quotes or backslashes" >&2; exit 1 ;;
27
+ index.html | document.json) echo "BAD_NAME: $name is reserved by the renderer" >&2; exit 1 ;;
28
+ esac
29
+
30
+ mkdir -p "$out"
31
+ cp "$here/assets/index.html" "$out/index.html"
32
+ printf '{ "file": "%s" }\n' "$name" > "$out/document.json"
33
+
34
+ echo "PAGE: $out/index.html"
35
+ echo "MANIFEST: $out/document.json"
36
+ echo "MARKDOWN: $name <- $(cd "$(dirname "$markdown")" && pwd)/$name"
@@ -0,0 +1,155 @@
1
+ ---
2
+ name: mise-usage
3
+ description: "How to use mise in a project: running commands, managing tools, .env and .venv, Python/uv setup, writing tasks, and driving tasks from Claude."
4
+ verified: 2026-10-16
5
+ ---
6
+
7
+ # Mise Usage
8
+
9
+ ## Claude has no mise environment
10
+
11
+ When Claude runs a Bash command, it is **not** in an activated mise shell. Tools declared in `mise.toml` (`python`, `uv`, `node`, etc.) are not on PATH, `.venv` is not activated, and `.env` is not loaded.
12
+
13
+ **Never run raw tool commands** (`python`, `uv`, `pip`, `node`, or anything else managed by
14
+ mise), and **never run `mise exec`.** Every command goes through a mise task:
15
+
16
+ - **Know the tasks.** Run `mise tasks` at the start of a session, and use a task over the
17
+ equivalent raw command whenever one exists.
18
+ - **No task fits.** Write a new file task for the command (see [Writing tasks](#writing-tasks))
19
+ and run it with `mise run`. Tasks carry the full environment: tools, `.env`, `.venv`.
20
+
21
+ ## mise.toml structure
22
+
23
+ `mise.toml` at the repo root declares tools and environment:
24
+
25
+ ```toml
26
+ [tools]
27
+ python = "3.13"
28
+ uv = "latest"
29
+ node = "22"
30
+
31
+ [env]
32
+ _.file = ".env" # autoload .env
33
+ _.python.venv = { path = ".venv", create = true } # manage .venv
34
+ UV_PYTHON = { value = "{{ tools.python.path }}", tools = true }
35
+ ```
36
+
37
+ `mise install` installs all declared tools. After that, `mise run` has the full environment.
38
+
39
+ **Pin every tool.** Give each one an explicit version or backend (`node = "22"`,
40
+ `ubi:owner/repo`, `npm:pkg`), so `mise install` provisions identical versions on every
41
+ machine. `latest` is acceptable only where drift genuinely does not matter.
42
+
43
+ **`[env]` holds non-secret values only.** mise exports `[env]` into every interactive
44
+ shell in the repo and every child process, so anything there is far more widely visible
45
+ than it looks: a token in `[env]` can shadow an unrelated tool's own credential. Keep
46
+ `[env]` to identifiers such as account ids, bucket names, and hostnames. Secrets live in
47
+ `.env.secrets` and are sourced inside the one task that needs them, never autoloaded and
48
+ never declared here. See `secrets`.
49
+
50
+ ## .env autoloading
51
+
52
+ Declare `_.file = ".env"` in the `[env]` block and mise loads it automatically for every `mise run` invocation. Never manually source `.env` before running commands. Gitignore `.env`; commit `.env.example` with placeholder values.
53
+
54
+ **Never autoload `.env.secrets`.** Autoloading is safe for `.env` precisely because `.env` holds no secrets. `.env.secrets` is different: it is sourced explicitly inside the task that needs it, so the values exist only in that process and never reach an interactive shell. Do not add it to `_.file`.
55
+
56
+ ## .venv management
57
+
58
+ Declare `_.python.venv = { path = ".venv", create = true, uv_create = true }` in the `[env]` block and mise creates and activates the `.venv` automatically, using `uv` to create it (much faster than the stdlib `venv`). Never run `python -m venv`, `uv venv`, or any manual venv command: mise owns this.
59
+
60
+ ## Python and uv conventions
61
+
62
+ - Declare `python` and `uv` in `[tools]`; set `UV_PYTHON` so uv uses mise's Python, not system Python
63
+ - Declare dependencies in `pyproject.toml`: never `requirements.txt`
64
+ - Install/sync deps with `uv sync` inside a mise task
65
+ - Commit `uv.lock` for reproducible installs
66
+
67
+ ## Writing tasks
68
+
69
+ All scripts run by humans or Claude are mise file tasks written in zsh. Never embed script logic in `mise.toml` or skills.
70
+
71
+ ```zsh
72
+ #!/usr/bin/env zsh
73
+ #MISE description="What this task does"
74
+
75
+ # task logic here
76
+ ```
77
+
78
+ Requirements: `#!/usr/bin/env zsh` on line 1, `#MISE description="..."` on line 2, file executable (`chmod +x`). Add `#MISE depends=["other:task"]` for prerequisites.
79
+
80
+ **File tasks only. Never an inline `[tasks]` table in `mise.toml`.** One location for every task keeps them discoverable and reviewable, and a task that starts inline never gets moved.
81
+
82
+ Arguments come after `--` and are read as `"$@"`: `mise run deploy -- --dry-run`. List everything with `mise tasks`.
83
+
84
+ **Warning:** Some formatters add a space after `#`, turning `#MISE` into `# MISE`, which breaks parsing. Use `# [MISE]` if that happens.
85
+
86
+ ### Naming
87
+
88
+ A task's name is its path under the tasks directory. Subdirectories create `:`-namespaced names; `_default` makes a namespace directly runnable:
89
+
90
+ ```
91
+ foo # mise run foo
92
+ group/bar # mise run group:bar
93
+ group/_default # mise run group
94
+ ```
95
+
96
+ ### Shared helper library
97
+
98
+ A shared helper must be **non-executable** and named with a leading underscore. mise discovers *executable* files under `mise-tasks/` as tasks, so a `chmod +x` helper shows up as a phantom task that does nothing when run.
99
+
100
+ Source it at the top of every task: resolve it from the script's own path so it works regardless of where `mise run` is invoked:
101
+
102
+ ```zsh
103
+ source "${0:A:h}/_lib.sh" # ${0:A} = symlink-resolved absolute path; :h = dirname
104
+ ```
105
+
106
+ A helper library should provide:
107
+
108
+ ```zsh
109
+ header "..." # bold heading
110
+ info "..." # informational line
111
+ success "..." # ✓ line
112
+ warn "..." # ⚠ warning line
113
+ error "..." # ✗ to stderr
114
+ dim "..." # dimmed text (e.g. echoing a command before running it)
115
+ ask "prompt" "default" # interactive text input → result in $REPLY
116
+ confirm "prompt" # yes/no prompt → returns 0 for yes, 1 for no
117
+ ```
118
+
119
+ It should also restore the working directory on source, so tasks act on the directory where `mise run` was invoked:
120
+
121
+ ```zsh
122
+ [[ -n "${MISE_ORIGINAL_CWD}" ]] && cd "$MISE_ORIGINAL_CWD"
123
+ ```
124
+
125
+ ### Idempotency
126
+
127
+ Tasks must be safe to re-run. Check before mutating: don't assume state is clean.
128
+
129
+ ## Troubleshooting mise activation
130
+
131
+ If `mise run` fails because `mise` is not found, the shell is not activated. Check:
132
+
133
+ ```bash
134
+ command -v mise # should print a path
135
+ echo $MISE_SHELL # should print "zsh", "bash", etc.; empty means not activated
136
+ ```
137
+
138
+ **Do not activate it yourself.** Tell the user mise is not activated in their shell, and
139
+ point them at mise's own activation docs (https://mise.jdx.dev/getting-started.html). Their
140
+ shell startup files are theirs: a line you append may duplicate one their dotfiles already
141
+ manage.
142
+
143
+ After it is activated, open a new terminal; the current session will not pick it up.
144
+ Once activated, `mise install` installs the tools declared in `mise.toml` for the current
145
+ project.
146
+
147
+ ## Driving tasks from Claude
148
+
149
+ When a skill drives a mise task that would otherwise trigger a Bash permission prompt, collapse the two prompts into one with `allowed-tools` in the skill's frontmatter:
150
+
151
+ ```yaml
152
+ allowed-tools: Bash(mise run my:task:*)
153
+ ```
154
+
155
+ The grant is active only while the skill runs and lapses when it finishes. The `AskUserQuestion` in the skill becomes the single decision point. Never blanket-allow mise in `settings.json` (`Bash(mise run:*)`): that silences prompts for tasks that have no approval gate.