sfora-cli 0.4.0 → 0.6.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.
package/dist/SforaFs.js CHANGED
@@ -73,6 +73,9 @@ function classify(path) {
73
73
  if (seg.length === 2)
74
74
  return { kind: "projectDir", slug };
75
75
  const dir = seg[2];
76
+ if (dir === "links.md" && seg.length === 3) {
77
+ return { kind: "linksFile", slug };
78
+ }
76
79
  if (dir === "posts" || dir === "drafts") {
77
80
  if (seg.length === 3)
78
81
  return { kind: "postsDir", slug, dir };
@@ -276,6 +279,13 @@ export class SforaFs {
276
279
  catch (e) {
277
280
  throw fromApi(e, "open", normalize(path));
278
281
  }
282
+ case "linksFile":
283
+ try {
284
+ return await this.#client.getProjectLinks(loc.slug);
285
+ }
286
+ catch (e) {
287
+ throw fromApi(e, "open", normalize(path));
288
+ }
279
289
  case "root":
280
290
  case "projectsDir":
281
291
  case "inboxDir":
@@ -306,6 +316,15 @@ export class SforaFs {
306
316
  if (loc.kind === "inboxFile" || loc.kind === "meFile") {
307
317
  throw eacces("open", norm);
308
318
  }
319
+ if (loc.kind === "linksFile") {
320
+ try {
321
+ await this.#client.setProjectLinks(loc.slug, toText(content));
322
+ }
323
+ catch (e) {
324
+ throw fromApi(e, "open", norm);
325
+ }
326
+ return;
327
+ }
309
328
  if (loc.kind === "root" ||
310
329
  loc.kind === "projectsDir" ||
311
330
  loc.kind === "inboxDir" ||
@@ -416,6 +435,10 @@ export class SforaFs {
416
435
  case "inboxFile":
417
436
  case "meFile":
418
437
  return this.#fileStat(new Date());
438
+ case "linksFile":
439
+ if (!(await this.#projectExists(loc.slug)))
440
+ throw enoent("stat", norm);
441
+ return this.#fileStat(new Date());
419
442
  case "projectDir":
420
443
  case "postsDir":
421
444
  case "boardDir":
@@ -489,6 +512,7 @@ export class SforaFs {
489
512
  return [
490
513
  dirent("board", true),
491
514
  dirent("drafts", true),
515
+ dirent("links.md", false),
492
516
  dirent("posts", true),
493
517
  ];
494
518
  case "postsDir": {
@@ -75,6 +75,10 @@ export declare class SforaApiClient {
75
75
  slug: string;
76
76
  name: string;
77
77
  }>;
78
+ /** `GET …/links.md` — the project's external links as markdown. */
79
+ getProjectLinks(slug: string): Promise<string>;
80
+ /** `PUT …/links.md` — replace the project's links from a markdown list. */
81
+ setProjectLinks(slug: string, markdown: string): Promise<void>;
78
82
  /**
79
83
  * `GET …/posts` or `…/drafts`. `scheduled` lists drafts that have a
80
84
  * (future) `scheduledFor` set.
@@ -90,6 +90,14 @@ export class SforaApiClient {
90
90
  const res = await this.#request("POST", "/v1/fs/projects", JSON.stringify({ name }));
91
91
  return (await res.json());
92
92
  }
93
+ /** `GET …/links.md` — the project's external links as markdown. */
94
+ async getProjectLinks(slug) {
95
+ return this.#text(`/v1/fs/projects/${encodeURIComponent(slug)}/links.md`);
96
+ }
97
+ /** `PUT …/links.md` — replace the project's links from a markdown list. */
98
+ async setProjectLinks(slug, markdown) {
99
+ await this.#request("PUT", `/v1/fs/projects/${encodeURIComponent(slug)}/links.md`, markdown);
100
+ }
93
101
  /**
94
102
  * `GET …/posts` or `…/drafts`. `scheduled` lists drafts that have a
95
103
  * (future) `scheduledFor` set.
package/dist/config.d.ts CHANGED
@@ -8,7 +8,7 @@ export interface SforaConfig {
8
8
  }>;
9
9
  }
10
10
  export declare const CONFIG_PATH: string;
11
- export declare const DEFAULT_URL = "http://localhost:2222";
11
+ export declare const DEFAULT_URL = "https://www.sfora.ai";
12
12
  export declare function readConfig(): Promise<SforaConfig>;
13
13
  export declare function writeConfig(cfg: SforaConfig): Promise<string>;
14
14
  export interface ResolvedSettings {
package/dist/config.js CHANGED
@@ -8,7 +8,9 @@ import { join } from "node:path";
8
8
  import { readFile, writeFile, mkdir, chmod } from "node:fs/promises";
9
9
  const CONFIG_DIR = join(homedir(), ".sfora");
10
10
  export const CONFIG_PATH = join(CONFIG_DIR, "config.json");
11
- export const DEFAULT_URL = "http://localhost:2222";
11
+ // Production sfora. Local development of sfora itself overrides via --url or
12
+ // SFORA_URL (e.g. the dev Convex .site host).
13
+ export const DEFAULT_URL = "https://www.sfora.ai";
12
14
  export async function readConfig() {
13
15
  try {
14
16
  const raw = await readFile(CONFIG_PATH, "utf8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sfora-cli",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "Your sfora workspace as a markdown filesystem — a CLI + MCP server. Post/task/doc, ls/cat/grep, and a shell so agents operate sfora natively.",
6
6
  "keywords": [