agentic-comments 0.5.1 → 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/worker.js CHANGED
@@ -1,18 +1,19 @@
1
1
  import {
2
2
  CommentsService,
3
3
  TEXT_ROOT
4
- } from "./chunk-NQWRFKJ6.js";
4
+ } from "./chunk-T77DPNIV.js";
5
5
  import {
6
6
  ACCEPT_SCOPE,
7
7
  CommentsError,
8
+ MODERATE_SCOPE,
8
9
  exact,
9
10
  invalid,
10
11
  stamp
11
- } from "./chunk-BSNBDKR2.js";
12
+ } from "./chunk-VAVKBAHM.js";
12
13
 
13
14
  // src/worker.ts
14
15
  import { Hono } from "hono";
15
- import { StoreConflictError, assertRegion, isScope, parseRegion, hasScope, parsePrincipal } from "agentic-identity";
16
+ import { StoreConflictError, assertRegion, createStoreAuth, isScope, parseRegion, hasScope, parsePrincipal } from "agentic-identity";
16
17
  import { requirePrincipal } from "agentic-identity/http";
17
18
  import { D1_SCHEMA, createD1Store } from "agentic-identity/cloudflare";
18
19
  import * as Y from "yjs";
@@ -86,7 +87,7 @@ function createTokenAuth(raw) {
86
87
  };
87
88
  }
88
89
  function actorOf(context) {
89
- const scopes = hasScope(context.scopes, ADMIN) ? [ACCEPT_SCOPE] : [];
90
+ const scopes = hasScope(context.scopes, ADMIN) ? [ACCEPT_SCOPE, MODERATE_SCOPE] : [];
90
91
  return stamp({ kind: context.kind, name: context.principalId, scopes });
91
92
  }
92
93
  var DOCS = "comments_docs";
@@ -155,6 +156,7 @@ var STATUS = {
155
156
  INVALID_INPUT: 400,
156
157
  INVALID_ANCHOR: 400,
157
158
  NO_THREAD: 404,
159
+ NO_MESSAGE: 404,
158
160
  NO_SUGGESTION: 404,
159
161
  NO_DOCUMENT: 404,
160
162
  THREAD_RESOLVED: 409,
@@ -191,8 +193,28 @@ function createApp(source, options = {}) {
191
193
  });
192
194
  app2.get("/health", (c) => c.json({ ok: true, pack: "agentic-comments" }));
193
195
  app2.use("/api/v1/*", async (c, next) => {
194
- const auth = typeof options.auth === "function" ? options.auth(c.env ?? {}) : options.auth ?? createTokenAuth(c.env?.AGENTIC_COMMENTS_TOKENS);
195
- const context = await requirePrincipal(c.req.raw, auth, { origins: options.origins });
196
+ let auth;
197
+ if (typeof options.auth === "function") auth = options.auth(c.env ?? {});
198
+ else if (options.auth) auth = options.auth;
199
+ else {
200
+ const staticOn = c.env?.AGENTIC_COMMENTS_UNSAFE_STATIC_TOKENS === "1";
201
+ if (c.env?.AGENTIC_COMMENTS_TOKENS && !staticOn) {
202
+ return fail("NOT_CONFIGURED", "AGENTIC_COMMENTS_TOKENS is a dev fallback. Set AGENTIC_COMMENTS_UNSAFE_STATIC_TOKENS=1 to use it, or remove it and issue agentic-identity credentials", 503);
203
+ }
204
+ const store = (await docsOf(c)).store;
205
+ const auths = [createStoreAuth(store)];
206
+ if (staticOn) auths.push(createTokenAuth(c.env?.AGENTIC_COMMENTS_TOKENS));
207
+ auth = {
208
+ async authenticate(request) {
209
+ for (const each of auths) {
210
+ const found = await each.authenticate(request);
211
+ if (found) return found;
212
+ }
213
+ return null;
214
+ }
215
+ };
216
+ }
217
+ const context = await requirePrincipal(c.req.raw, auth, { origins: options.origins, scope: READ });
196
218
  if (context instanceof Response) {
197
219
  if (context.status === 401) return Response.json({ error: { code: "UNAUTHENTICATED", message: "send a valid bearer token" } }, { status: 401, headers: { "www-authenticate": "Bearer" } });
198
220
  if (context.status === 403) return fail("FORBIDDEN", "this credential may not do this", 403);
@@ -237,6 +259,14 @@ function createApp(source, options = {}) {
237
259
  for (const action of ["resolve", "reopen"]) {
238
260
  app2.post(`${doc}/threads/:id/${action}`, (c) => act(c, COMMENT, true, (s) => s[action](c.req.param("id"))));
239
261
  }
262
+ app2.patch(`${doc}/threads/:id/messages/:message`, async (c) => {
263
+ const input = await body(c);
264
+ return act(c, COMMENT, true, (s) => s.editMessage(c.req.param("id"), c.req.param("message"), input));
265
+ });
266
+ app2.delete(`${doc}/threads/:id/messages/:message`, (c) => act(c, COMMENT, true, (s) => s.deleteMessage(c.req.param("id"), c.req.param("message"))));
267
+ app2.delete(`${doc}/threads/:id`, (c) => act(c, COMMENT, true, (s) => s.deleteThread(c.req.param("id"))));
268
+ app2.get(`${doc}/people/:name/export`, (c) => act(c, READ, false, (s) => s.exportPerson(c.req.param("name"))));
269
+ app2.delete(`${doc}/people/:name`, (c) => act(c, COMMENT, true, (s) => s.erasePerson(c.req.param("name"))));
240
270
  app2.post(`${doc}/threads/:id/relocate`, (c) => act(c, WRITE, true, (s) => s.relocate(c.req.param("id"))));
241
271
  app2.get(`${doc}/suggestions`, (c) => act(c, READ, false, (s) => s.suggestions(c.req.query())));
242
272
  app2.post(`${doc}/suggestions`, async (c) => {
package/llms.txt CHANGED
@@ -7,6 +7,7 @@ Keywords: comments,threads,mentions,suggestions,annotations,collaboration,agents
7
7
  - SDK: import { Comments, Suggestions, textAnchor } from "agentic-comments". The host calls stamp(); an agent never does.
8
8
  - Plain text anchors: import { createAnchor, resolveAnchor, mapRange } from "agentic-comments/anchor". No Yjs. resolveAnchor maps through edits, then falls back to quote + context, else orphaned.
9
9
  - Threads live on a Yjs document and merge across replicas.
10
+ - Lifecycle: comments.editMessage, deleteMessage, deleteThread, exportPerson, erasePerson (and the same on the CLI, MCP, HTTP API, and client). Only the author may change their own messages; comments:moderate may change anyone's.
10
11
  - Events: new Notifications(comments, suggestions).subscribe(listener). Ids only, never text.
11
12
  - CLI: agentic-comments <command>. MCP: agentic-comments mcp. Both use a local store file.
12
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-comments",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Comment threads and suggestions anchored to any content, from people and agents.",
5
5
  "keywords": [
6
6
  "comments",
@@ -76,7 +76,7 @@
76
76
  },
77
77
  "dependencies": {
78
78
  "@modelcontextprotocol/sdk": "^1.32.2",
79
- "agentic-identity": "^0.6.0",
79
+ "agentic-identity": "^0.7.0",
80
80
  "hono": "^4.13.14",
81
81
  "zod": "^3.25.76"
82
82
  },
@@ -1,7 +0,0 @@
1
- type CommentsErrorCode = "INVALID_AUTHOR" | "INVALID_INPUT" | "INVALID_ANCHOR" | "NO_THREAD" | "THREAD_RESOLVED" | "CORRUPT" | "NO_SUGGESTION" | "FORBIDDEN" | "ALREADY_DECIDED" | "APPLY_FAILED" | "RELOCATE_FAILED" | "STORE_MISSING" | "STORE_EXISTS" | "STORE_CORRUPT" | "STORE_LOCKED" | "STORE_FULL" | "NO_DOCUMENT" | "DOCUMENT_EXISTS" | "CONFLICT" | "MISCONFIGURED" | "USAGE";
2
- declare class CommentsError extends Error {
3
- readonly code: CommentsErrorCode;
4
- constructor(code: CommentsErrorCode, message: string);
5
- }
6
-
7
- export { type CommentsErrorCode as C, CommentsError as a };
@@ -1,11 +0,0 @@
1
- import {
2
- createMcpServer,
3
- startMcp
4
- } from "./chunk-TFRLOBJW.js";
5
- import "./chunk-REFQNIEP.js";
6
- import "./chunk-NQWRFKJ6.js";
7
- import "./chunk-BSNBDKR2.js";
8
- export {
9
- createMcpServer,
10
- startMcp
11
- };