artyfax 0.2.2 → 0.2.3

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 (2) hide show
  1. package/dist/cli.js +26 -2
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -23,6 +23,10 @@ async function apiFetch(config, path, init) {
23
23
  headers: {
24
24
  "Content-Type": "application/json",
25
25
  "X-API-Key": config.apiKey,
26
+ // design-34: identify the CLI on the server side so saved_via can
27
+ // bucket CLI saves correctly. Format mirrors common CLI tools so a
28
+ // server-side regex can stay simple.
29
+ "User-Agent": `artyfax-cli/${VERSION}`,
26
30
  ...init?.headers
27
31
  }
28
32
  });
@@ -229,6 +233,10 @@ async function save(config, opts) {
229
233
  content = await encryptSecure(content, sdk);
230
234
  }
231
235
  try {
236
+ let isDuplicate2 = function(r) {
237
+ return "status" in r && r.status === "duplicate";
238
+ };
239
+ var isDuplicate = isDuplicate2;
232
240
  const body = {
233
241
  title: opts.title || void 0,
234
242
  content: content || void 0,
@@ -241,12 +249,25 @@ async function save(config, opts) {
241
249
  if (opts.tags) body.tags = opts.tags.split(",").map((t) => t.trim());
242
250
  if (opts.theme) body.theme = opts.theme;
243
251
  if (opts.parentId) body.parent_id = opts.parentId;
252
+ if (opts.force) body.force_new = true;
244
253
  const result = await apiFetch(
245
254
  config,
246
255
  "/ingest",
247
256
  { method: "POST", body: JSON.stringify(body) }
248
257
  );
249
258
  spin.stop();
259
+ if (isDuplicate2(result)) {
260
+ if (opts.json) {
261
+ console.log(JSON.stringify(result));
262
+ } else {
263
+ const date = new Date(result.existing_saved_at).toLocaleDateString();
264
+ console.log(
265
+ `${c.muted("Already saved:")} ${result.existing_slug} ${c.muted(`(${date})`)}
266
+ ${c.muted("Use --force to save a new copy.")}`
267
+ );
268
+ }
269
+ return;
270
+ }
250
271
  if (opts.json) {
251
272
  console.log(JSON.stringify(result.document));
252
273
  } else {
@@ -524,7 +545,7 @@ async function update(config, slugOrId, file, json) {
524
545
  spin.text = "Uploading\u2026";
525
546
  await apiFetch(config, `/documents/${doc.id}/content`, {
526
547
  method: "PATCH",
527
- body: JSON.stringify({ content })
548
+ body: JSON.stringify({ content, source: "cli" })
528
549
  });
529
550
  spin.stop();
530
551
  if (json) {
@@ -916,7 +937,7 @@ async function skillUpdate() {
916
937
  }
917
938
 
918
939
  // src/cli.ts
919
- var VERSION = true ? "0.2.2" : "0.0.0-dev";
940
+ var VERSION = true ? "0.2.3" : "0.0.0-dev";
920
941
  function brandedHelp() {
921
942
  return `
922
943
  ${c.amber("artyfax")} ${c.muted(`v${VERSION}`)} \u2014 your personal document library
@@ -986,6 +1007,7 @@ ${c.bright("Options:")}
986
1007
  --theme <name> Theme override
987
1008
  --parent <id> Parent document ID
988
1009
  --title <name> Title (default: derived from filename)
1010
+ --force Save a new copy even if the URL was already saved
989
1011
  --json JSON output
990
1012
 
991
1013
  ${c.bright("Examples:")}
@@ -1230,6 +1252,7 @@ async function main() {
1230
1252
  docType: flags["doc-type"] || "article",
1231
1253
  theme: flags.theme,
1232
1254
  parentId: flags.parent,
1255
+ force: !!flags.force,
1233
1256
  json
1234
1257
  });
1235
1258
  break;
@@ -1255,6 +1278,7 @@ async function main() {
1255
1278
  docType: flags["doc-type"] || "original",
1256
1279
  theme: flags.theme,
1257
1280
  parentId: flags.parent,
1281
+ force: !!flags.force,
1258
1282
  json
1259
1283
  });
1260
1284
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artyfax",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "CLI for Artyfax - your personal document library. Save, theme, search, and share.",
5
5
  "type": "module",
6
6
  "bin": {