smashspace 0.2.0 → 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/README.md +8 -1
- package/dist/smash.mjs +45 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -89,12 +89,19 @@ smash scan --list "やること" # cards as JSON (id/title/list only)
|
|
|
89
89
|
smash scan --list "やること" --full # + description/agentMeta/labels — pick up work in ONE request
|
|
90
90
|
smash create "Fix signup bug" # add a card (to the first list, or --list; --desc for a body)
|
|
91
91
|
smash move <cardId> "レビュー" # move a card to a list by name
|
|
92
|
+
smash attachment add <cardId> ./out.png # upload a local file (agent-generated images, etc.)
|
|
92
93
|
smash archive <cardId> # archive (soft-delete) a card
|
|
93
94
|
smash --help # full command list (board/list/card/…)
|
|
94
95
|
```
|
|
95
96
|
|
|
96
97
|
Output is a concise line by default; add `--json` for machine-readable output on
|
|
97
|
-
any command.
|
|
98
|
+
any command.
|
|
99
|
+
|
|
100
|
+
**Field naming** (three concepts, three names — not a typo): a card's is
|
|
101
|
+
`title`, an artifact's is `name` (`--name`), a file/attachment's is `filename`
|
|
102
|
+
(with `sizeBytes`).
|
|
103
|
+
|
|
104
|
+
For agents:
|
|
98
105
|
|
|
99
106
|
```bash
|
|
100
107
|
smash scan --full # or --fields description,agentMeta
|
package/dist/smash.mjs
CHANGED
|
@@ -3395,7 +3395,7 @@ import { randomBytes } from "node:crypto";
|
|
|
3395
3395
|
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
3396
3396
|
import { platform as platform2 } from "node:os";
|
|
3397
3397
|
import { createInterface } from "node:readline/promises";
|
|
3398
|
-
import { relative, join as join3, dirname as dirname3 } from "node:path";
|
|
3398
|
+
import { relative, join as join3, dirname as dirname3, basename } from "node:path";
|
|
3399
3399
|
import { stdin, stdout } from "node:process";
|
|
3400
3400
|
|
|
3401
3401
|
// ../../shared/board-registry.ts
|
|
@@ -3654,6 +3654,10 @@ Use \`smash <group> --help\` for the full surface (\`board\`/\`list\`/\`card\`/
|
|
|
3654
3654
|
\`comment\`/\`checklist\`/\`label\`/\`artifact\`/\`attachment\`/\`agent-meta\`/
|
|
3655
3655
|
\`external-refs\`/\`assignees\`).
|
|
3656
3656
|
|
|
3657
|
+
**Field naming** (three concepts, three names \u2014 not a typo): a card's is
|
|
3658
|
+
\`title\`, an artifact's is \`name\` (\`--name\`), a file/attachment's is
|
|
3659
|
+
\`filename\` (with \`sizeBytes\`).
|
|
3660
|
+
|
|
3657
3661
|
## List matching
|
|
3658
3662
|
|
|
3659
3663
|
Use exact canonical names when present. For Todo-like selection, match
|
|
@@ -4343,7 +4347,47 @@ artifactCmd.command("delete <cardId> <artifactId>").description("Delete an artif
|
|
|
4343
4347
|
await api(`/api/cards/${cardId}/artifacts/${artifactId}`, { method: "DELETE" });
|
|
4344
4348
|
console.log(`\u2713 artifact ${artifactId} deleted`);
|
|
4345
4349
|
});
|
|
4350
|
+
var ATTACH_EXT_MIME = {
|
|
4351
|
+
png: "image/png",
|
|
4352
|
+
jpg: "image/jpeg",
|
|
4353
|
+
jpeg: "image/jpeg",
|
|
4354
|
+
gif: "image/gif",
|
|
4355
|
+
webp: "image/webp",
|
|
4356
|
+
svg: "image/svg+xml",
|
|
4357
|
+
bmp: "image/bmp",
|
|
4358
|
+
ico: "image/x-icon",
|
|
4359
|
+
pdf: "application/pdf",
|
|
4360
|
+
txt: "text/plain",
|
|
4361
|
+
md: "text/markdown",
|
|
4362
|
+
csv: "text/csv",
|
|
4363
|
+
json: "application/json",
|
|
4364
|
+
zip: "application/zip"
|
|
4365
|
+
};
|
|
4366
|
+
function guessMime(name) {
|
|
4367
|
+
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
4368
|
+
return ATTACH_EXT_MIME[ext] ?? "application/octet-stream";
|
|
4369
|
+
}
|
|
4346
4370
|
var attachmentCmd = program2.command("attachment").description("Card attachments");
|
|
4371
|
+
attachmentCmd.command("add <cardId> <file>").alias("upload").description("Upload a local file as a card attachment (\u2264100 MB)").action(async (cardId, filePath) => {
|
|
4372
|
+
const buf = await readFile2(filePath);
|
|
4373
|
+
const name = basename(filePath);
|
|
4374
|
+
const type = guessMime(name);
|
|
4375
|
+
const fd = new FormData();
|
|
4376
|
+
fd.append("file", new Blob([buf], { type }), name);
|
|
4377
|
+
const baseUrl = resolveBaseUrl();
|
|
4378
|
+
const token = await resolveToken(baseUrl);
|
|
4379
|
+
const res = await fetch(new URL(`/api/cards/${cardId}/attachments`, baseUrl), {
|
|
4380
|
+
method: "POST",
|
|
4381
|
+
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
|
4382
|
+
body: fd
|
|
4383
|
+
});
|
|
4384
|
+
if (!res.ok) {
|
|
4385
|
+
const text = await res.text().catch(() => "");
|
|
4386
|
+
throw new Error(`API ${res.status} /api/cards/${cardId}/attachments: ${text || res.statusText}`);
|
|
4387
|
+
}
|
|
4388
|
+
const att = await res.json();
|
|
4389
|
+
show(att, [`\u2713 attached "${att.filename ?? name}" to ${cardId} (${att.id ?? "?"})`]);
|
|
4390
|
+
});
|
|
4347
4391
|
attachmentCmd.command("list <cardId>").description("List attachments on a card").action(async (cardId) => {
|
|
4348
4392
|
const items = await api(`/api/cards/${cardId}/attachments`);
|
|
4349
4393
|
show(items, [`\u2713 ${items.length} attachment(s)`]);
|