@kigo-dev/sindri 0.1.0 → 0.1.4

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 CHANGED
@@ -22,10 +22,17 @@ names, parameters and this document are English. The contract lives in
22
22
  | `list_apps` | – | The PM's apps, with local folder state. |
23
23
  | `versions` | `app` | Published versions, most recent first. |
24
24
  | `rollback` | `app`, `version` | `POST rollback`, then downloads that version's archive and replaces the local tree (keeps `node_modules`, `.sindri`, `.env.local`). Stops the preview first: PGlite allows one process per data dir. |
25
+ | `update_template` | `app` | `POST /v1/apps/<app>/template`: Sindri replaces the files the app never customised with the current template (customised ones come back in `skipped`) and publishes «Plantilla actualizada». When `published`, downloads the new archive and replaces the local tree like `rollback` (stops the preview, re-migrates, rewrites `last-published.json`). Refuses with "Publica o descarta tus cambios antes de actualizar la plantilla" while the folder has unpublished edits. |
26
+ | `rename_app` | `app`, `new_name?`, `display_name?` | At least one. `display_name`: writes `display_name:` in the app's `kigo-app.yaml` (line edit, no YAML library) and runs the `publish` flow with the message «Ahora se llama «<display_name>»». `new_name`: refuses with "Publica tus cambios antes de cambiar la dirección" while the folder has unpublished edits (same check as `status`), `POST /v1/apps/<app>/rename`, then stops the preview, moves `~/Sindri/<app>` to `~/Sindri/<new_name>` and `apps/<owner>/<app>` to `apps/<owner>/<new_name>`, rewrites `name:` in `kigo-app.yaml` exactly like the builder and rewrites `.sindri/last-published.json` so `status` is clean. Both together: visible name first (a publish under the old address), then the address. |
27
+ | `delete_app` | `app`, `confirm` | `confirm` must equal `app` (the PM typed it; the instructions forbid Claude from filling it in). Stops the preview, `DELETE /v1/apps/<app>`, then moves `~/Sindri/<app>` to `~/Sindri/.papelera/<app>-<YYYYMMDD-HHmm>` (Mexico City time) instead of deleting. A 404 from the API with the folder present still moves the folder and says so. |
25
28
  | `share` | `app` | The Slack line. |
29
+ | `help` | – | No network. `{ summary, space_url, logged_in, apps_dir }`: the Spanish introduction Claude gives on first contact (what Sindri is, what to ask for, limits, the Mi espacio link https://sindri.kigo.dev), whether credentials are stored on this computer (keychain or file, no API call) and where the apps live. |
30
+ | `design_guide` | `app`, `topic?` | No network. Reads the `kigo-sindri-design` skill the template ships at `apps/<owner>/<app>/.claude/skills/kigo-sindri-design/`: without `topic`, `SKILL.md` plus `topics` (the file names under `references/` without `.md`); with `topic`, that reference file. `{ ok, summary, topic, topics, content }`, `content` verbatim markdown for Claude to follow (never pasted to the PM). `ok:false, code:"no_design_guide"` when the app predates the skill (Claude runs `update_template` once and retries); `code:"unknown_topic"` lists the valid topics. Also exposed as MCP resources `sindri://design-guide/<app>` and `sindri://design-guide/<app>/<topic>`. |
26
31
 
27
32
  Every result is `{ ok, summary, ...data }`. `needs_login: true` / `needs_setup: true` tell Claude
28
- which tool to run first. The server also ships `instructions` describing how to talk to the PM.
33
+ which tool to run first. `list_apps` also returns `space_url`. The server also ships
34
+ `instructions` describing how to talk to the PM (first contact via `help`, address vs visible
35
+ name, typed confirmation before `delete_app`).
29
36
 
30
37
  ## Install
31
38
 
@@ -36,7 +43,7 @@ which tool to run first. The server also ships `instructions` describing how to
36
43
  **Claude Code:**
37
44
 
38
45
  ```
39
- claude mcp add sindri -- npx -y @kigo-dev/sindri
46
+ claude mcp add sindri -- npx -y @kigo-dev/sindri@0.1.4
40
47
  ```
41
48
 
42
49
  **Manual check without an MCP client:**
@@ -82,12 +89,31 @@ archive ships it (`package.json`, `pnpm-workspace.yaml`, `pnpm-lock.yaml`, `tsco
82
89
  and cannot install standalone. `pnpm install` runs at that root; `preview`, `db:migrate`,
83
90
  `db:seed`, `tsc`, the tree hash, `.env.local`, `.sindri/last-published.json` and the `publish`
84
91
  tarball (paths relative to the app) all live at `apps/<owner>/<name>`. `replaceTree` swaps the
85
- whole root on `create_app`/`rollback` but keeps every `node_modules` and the app's `.sindri/`
92
+ whole root on `create_app`/`rollback`/`update_template` but keeps every `node_modules` and the app's `.sindri/`
86
93
  and `.env*`. The owner is the single folder under `apps/`, else the `owner` from `GET /v1/me`
87
94
  (cached in `~/.sindri/me.json`).
88
95
 
96
+ Claude Code loads project skills from the folder it is opened in, and a PM opens the root
97
+ (`~/Sindri/<name>`), not the app dir. So after every operation that writes the tree
98
+ (`create_app`, `rollback`, `update_template`, `rename_app`) the connector puts a relative symlink at
99
+ `~/Sindri/<name>/.claude/skills/kigo-sindri-design` pointing to
100
+ `apps/<owner>/<name>/.claude/skills/kigo-sindri-design` when that folder exists (`linkDesignGuide`
101
+ in `layout.ts`). It is idempotent, skips silently when the app has no skill and never replaces a
102
+ real directory at that place. The root is neither hashed nor packed, so the link changes nothing
103
+ for `status` or `publish`; the app's own `.claude/` is part of the tree and travels to Sindri.
104
+
105
+ `rename_app` with `new_name` moves the root and the app dir in place (nothing is downloaded) and
106
+ then applies the one edit the builder made in its copy, `name:` in `kigo-app.yaml`, written as
107
+ `name: "<new_name>"` (JSON-quoted, the shape `mcp` `renderManifest` uses). The tree hash the
108
+ connector stores in `last-published.json` is over the same file set `publish` uploads (everything
109
+ except `node_modules`, `.next`, `.sindri`, `dist`, `.turbo`, `.git`, `.env*`, `.DS_Store`), so a
110
+ file the builder ignores but the connector hashes would make `status` report unpublished edits
111
+ after a rename; `test/tools.test.ts` builds the builder's post-rename tree (old archive, moved,
112
+ `name:` edited) and asserts both hashes are equal. Deleted apps are never removed from disk: they
113
+ go to `~/Sindri/.papelera/`, which no tool scans (`.papelera` is not a valid app name).
114
+
89
115
  ## Local database
90
116
 
91
117
  The template runs on PGlite when `KIGO_ENV=local` and no `DATABASE_URL` is set; data lives in
92
118
  `<app>/.sindri/pglite/`. PGlite is single-process: the connector never runs migrations while a
93
- preview is up, and stops the preview before a rollback replaces the tree.
119
+ preview is up, and stops the preview before a rollback or a template update replaces the tree.