omakit 0.2.1 → 0.2.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omakit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "The safe place to find out: everything knowable about an Omarchy Quattro plugin submission before you post it, on your own machine. Agent-first, read-only against the marketplace, posts nothing, zero dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Maarten Tolhuijs",
|
|
@@ -56,7 +56,15 @@ export function subcommandsOf(commands = COMMANDS) {
|
|
|
56
56
|
* expression is exported so a test can run it through jq.
|
|
57
57
|
*/
|
|
58
58
|
export const PLUGIN_IDS_JQ = "[.[] | select(((.kinds // []) | index(\"bar\")) | not)] | sort_by(.enabled | not) | .[].id"
|
|
59
|
-
|
|
59
|
+
/**
|
|
60
|
+
* The pipeline, in the shell's own syntax. `timeout 1` bounds the wait
|
|
61
|
+
* where coreutils has it; a system without `timeout` (measured: the macOS
|
|
62
|
+
* runner in CI, where the TAB fell back to directories) runs the command
|
|
63
|
+
* unbounded rather than never, since `omarchy-shell` itself gives up on
|
|
64
|
+
* its IPC timeout.
|
|
65
|
+
*/
|
|
66
|
+
export const PLUGIN_IDS_COMMAND = `omarchy-shell shell listPlugins 2>/dev/null | jq -r '${PLUGIN_IDS_JQ}' 2>/dev/null`
|
|
67
|
+
export const PLUGIN_IDS_TIMED = `timeout 1 ${PLUGIN_IDS_COMMAND}`
|
|
60
68
|
|
|
61
69
|
/** What a valued flag takes, by its placeholder: a controlled value, a file, or free text. */
|
|
62
70
|
function placeholderKind(placeholder) {
|
|
@@ -175,7 +183,7 @@ function bash({ subcommands, categories, tags, pin, version }) {
|
|
|
175
183
|
lines.push("# left out, read at TAB time; nothing when the shell does not answer in a")
|
|
176
184
|
lines.push("# second, and the caller falls back to a directory.")
|
|
177
185
|
lines.push("_omakit_plugin_ids() {")
|
|
178
|
-
lines.push(` ${PLUGIN_IDS_COMMAND}`)
|
|
186
|
+
lines.push(` if command -v timeout >/dev/null 2>&1; then ${PLUGIN_IDS_TIMED}; else ${PLUGIN_IDS_COMMAND}; fi`)
|
|
179
187
|
lines.push("}")
|
|
180
188
|
lines.push("")
|
|
181
189
|
lines.push("# A controlled value may contain a space, so each match is one line and is")
|
|
@@ -243,7 +251,7 @@ function zsh({ subcommands, categories, tags, pin, version }) {
|
|
|
243
251
|
lines.push("# left out, read at TAB time; a directory when the shell does not answer.")
|
|
244
252
|
lines.push("_omakit_plugins() {")
|
|
245
253
|
lines.push(" local -a ids")
|
|
246
|
-
lines.push(` ids=(\${(f)"$(${PLUGIN_IDS_COMMAND})"})`)
|
|
254
|
+
lines.push(` if (( $+commands[timeout] )); then ids=(\${(f)"$(${PLUGIN_IDS_TIMED})"}); else ids=(\${(f)"$(${PLUGIN_IDS_COMMAND})"}); fi`)
|
|
247
255
|
lines.push(" if (( ${#ids} )); then compadd -a ids; else _directories; fi")
|
|
248
256
|
lines.push("}")
|
|
249
257
|
lines.push("")
|
|
@@ -263,7 +271,7 @@ function fish({ subcommands, categories, tags, pin, version }) {
|
|
|
263
271
|
lines.push("# left out, read at TAB time; nothing when the shell does not answer, and")
|
|
264
272
|
lines.push("# the directories offered beside them stand.")
|
|
265
273
|
lines.push("function __omakit_plugin_ids")
|
|
266
|
-
lines.push(` ${PLUGIN_IDS_COMMAND}`)
|
|
274
|
+
lines.push(` if command -q timeout; ${PLUGIN_IDS_TIMED}; else; ${PLUGIN_IDS_COMMAND}; end`)
|
|
267
275
|
lines.push("end")
|
|
268
276
|
lines.push("")
|
|
269
277
|
for (const sub of subcommands) {
|
|
@@ -416,10 +416,10 @@ export function continuation(value, c) {
|
|
|
416
416
|
* under itself. There is exactly one of these under any failure, and it is the
|
|
417
417
|
* only line in the tool that starts with an arrow, so it can be found by shape.
|
|
418
418
|
*/
|
|
419
|
-
export function action(text, c, { indent = GUTTER } = {}) {
|
|
419
|
+
export function action(text, c, { indent = GUTTER, width: total = COLUMNS } = {}) {
|
|
420
420
|
// Painted after wrapping, and all of it cyan: the whole line is the thing
|
|
421
421
|
// to do, so a backticked word inside it has nothing to stand out from.
|
|
422
|
-
const lines = wrap(text, { indent: indent + 2 })
|
|
422
|
+
const lines = wrap(text, { indent: indent + 2, width: total })
|
|
423
423
|
return lines.map((line, index) => (index === 0
|
|
424
424
|
? `${" ".repeat(indent)}${c("typeable.bold", ARROW)} ${c("typeable", line.trimStart())}`
|
|
425
425
|
: `${" ".repeat(indent + 2)}${c("typeable", line.trimStart())}`))
|
|
@@ -155,7 +155,10 @@ export const COMPLETION_REFRESH_ARGS = Object.freeze(["setup", "--completion"])
|
|
|
155
155
|
|
|
156
156
|
function refreshCompletionWith(root, stream) {
|
|
157
157
|
const entryPoint = join(root, "bin/omakit")
|
|
158
|
-
|
|
158
|
+
// The reason names the relative path: the root is printed above it, and a
|
|
159
|
+
// temporary directory on macOS is long enough to push an absolute one
|
|
160
|
+
// past eighty columns in a sentence (measured in CI: 109).
|
|
161
|
+
if (!existsSync(entryPoint)) return { ran: false, reason: "this install has no bin/omakit under its root" }
|
|
159
162
|
try {
|
|
160
163
|
const out = execFileSync(process.execPath, [entryPoint, ...COMPLETION_REFRESH_ARGS], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] })
|
|
161
164
|
stream.write(out)
|
package/tools/weigh/confirm.mjs
CHANGED
|
@@ -5,13 +5,30 @@
|
|
|
5
5
|
// typed here is written anywhere.
|
|
6
6
|
|
|
7
7
|
import { createInterface } from "node:readline"
|
|
8
|
-
import { action, colourEnabled, styler } from "../marketplace/style.mjs"
|
|
8
|
+
import { action, colourEnabled, COLUMNS, styler } from "../marketplace/style.mjs"
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* The question as it is written to the terminal: the arrow line, wrapped
|
|
12
|
+
* at the contract width like every other action, with `[y/N]:` at the end
|
|
13
|
+
* of the last line, and no newline after it, so the cursor waits there.
|
|
14
|
+
* Measured on 0.2.1: the question grew a clause about --runs, wrapped to
|
|
15
|
+
* two lines, and only the first was written, so a person saw "for a" and
|
|
16
|
+
* no prompt, pressed Enter to see the rest, and the empty line was No.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} question
|
|
19
|
+
* @param {(name: string, text: string) => string} c
|
|
20
|
+
* @param {{ width?: number }} [options]
|
|
21
|
+
* @returns {string} every line, joined, ending in `[y/N]: `
|
|
13
22
|
*/
|
|
14
|
-
export function
|
|
23
|
+
export function renderQuestion(question, c, { width = COLUMNS } = {}) {
|
|
24
|
+
return `${action(`${question} [y/N]:`, c, { indent: 0, width }).join("\n")} `
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {{ input?: NodeJS.ReadStream, output?: NodeJS.WriteStream, colour?: boolean, question: string, width?: number }} options
|
|
29
|
+
* @returns {Promise<boolean>} true only for `y` or `yes`, in any case; an empty line and the end of stdin are no
|
|
30
|
+
*/
|
|
31
|
+
export function askYes({ input = process.stdin, output = process.stderr, colour = colourEnabled(output), question, width = COLUMNS }) {
|
|
15
32
|
const c = styler(colour)
|
|
16
33
|
return new Promise((resolve) => {
|
|
17
34
|
const rl = createInterface({ input, terminal: false })
|
|
@@ -27,6 +44,6 @@ export function askYes({ input = process.stdin, output = process.stderr, colour
|
|
|
27
44
|
if (!answered) output.write("\n")
|
|
28
45
|
settle(false)
|
|
29
46
|
})
|
|
30
|
-
output.write(
|
|
47
|
+
output.write(renderQuestion(question, c, { width }))
|
|
31
48
|
})
|
|
32
49
|
}
|