@creator-notes/cnotes 0.54.0 → 0.56.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/README.md +2 -0
- package/dist/commands/init.js +5 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/review.d.ts +1 -0
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +292 -33
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +7 -5
- package/dist/commands/skills.js.map +1 -1
- package/dist/lib/install-skill.d.ts +3 -2
- package/dist/lib/install-skill.d.ts.map +1 -1
- package/dist/lib/install-skill.js +19 -4
- package/dist/lib/install-skill.js.map +1 -1
- package/dist/lib/review-helpers.d.ts +19 -0
- package/dist/lib/review-helpers.d.ts.map +1 -0
- package/dist/lib/review-helpers.js +74 -0
- package/dist/lib/review-helpers.js.map +1 -0
- package/dist/mcp-server.js +136 -0
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
- package/skills/cnotes/SKILL.md +60 -1
package/dist/commands/skills.js
CHANGED
|
@@ -13,9 +13,10 @@ function resolveTargets(agentOpt) {
|
|
|
13
13
|
const a = agentOpt.trim().toLowerCase();
|
|
14
14
|
if (a === "all")
|
|
15
15
|
return [...SKILL_TARGETS];
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const match = SKILL_TARGETS.find((t) => t === a);
|
|
17
|
+
if (match)
|
|
18
|
+
return [match];
|
|
19
|
+
throw new ValidationError(`Unknown --agent "${agentOpt}". Use ${SKILL_TARGETS.join(", ")}, or all.`);
|
|
19
20
|
}
|
|
20
21
|
const detected = SKILL_TARGETS.filter(hasAgentConfigDir);
|
|
21
22
|
return detected.length ? detected : [...SKILL_TARGETS];
|
|
@@ -23,7 +24,7 @@ function resolveTargets(agentOpt) {
|
|
|
23
24
|
export function registerSkillsCommands(program) {
|
|
24
25
|
const skills = program
|
|
25
26
|
.command("skills")
|
|
26
|
-
.description("Install bundled agent skills (e.g. fat-marker flows, how-to filmstrips, wayfind) into Claude Code or
|
|
27
|
+
.description("Install bundled agent skills (e.g. fat-marker flows, how-to filmstrips, wayfind) into Claude Code, Codex, or Cursor");
|
|
27
28
|
skills
|
|
28
29
|
.command("list")
|
|
29
30
|
.description("List the skills this CLI can install")
|
|
@@ -53,11 +54,12 @@ export function registerSkillsCommands(program) {
|
|
|
53
54
|
skills
|
|
54
55
|
.command("install <name>")
|
|
55
56
|
.description("Install a bundled skill into your agent's skills dir")
|
|
56
|
-
.option("--agent <agent>", "Which agent to install for: claude, codex, or all (default: auto-detect)")
|
|
57
|
+
.option("--agent <agent>", "Which agent to install for: claude, codex, cursor, or all (default: auto-detect)")
|
|
57
58
|
.addHelpText("after", `
|
|
58
59
|
Examples:
|
|
59
60
|
$ cnotes skills install fat-marker
|
|
60
61
|
$ cnotes skills install howto-filmstrips
|
|
62
|
+
$ cnotes skills install wayfind --agent cursor
|
|
61
63
|
$ cnotes skills install fat-marker --agent codex
|
|
62
64
|
$ cnotes skills install fat-marker --agent all`)
|
|
63
65
|
.action((name, options) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,aAAa,EAEb,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC;;;;;GAKG;AACH,SAAS,cAAc,CAAC,QAAiB;IACvC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACxC,IAAI,CAAC,KAAK,KAAK;YAAE,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC;QAC3C,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-install the `cnotes` skill so coding agents auto-discover it.
|
|
3
3
|
*
|
|
4
|
-
* The same bundled skill feeds
|
|
4
|
+
* The same bundled skill feeds every target:
|
|
5
5
|
* - Claude Code → ~/.claude/skills/cnotes/SKILL.md
|
|
6
6
|
* - OpenAI Codex → ~/.codex/skills/cnotes/SKILL.md
|
|
7
|
+
* - Cursor → ~/.cursor/skills/cnotes/SKILL.md
|
|
7
8
|
*
|
|
8
9
|
* The skill ships inside the published package at <package>/skills/cnotes/SKILL.md.
|
|
9
10
|
* At runtime this file lives at <package>/dist/lib/install-skill.js, so the
|
|
10
11
|
* skill source is two directories up.
|
|
11
12
|
*/
|
|
12
13
|
/** The agents we ship a discoverable skill for. */
|
|
13
|
-
export type SkillTarget = "claude" | "codex";
|
|
14
|
+
export type SkillTarget = "claude" | "codex" | "cursor";
|
|
14
15
|
export declare const SKILL_TARGETS: SkillTarget[];
|
|
15
16
|
/** Human-facing label for a target (used in init/output messages). */
|
|
16
17
|
export declare function skillTargetLabel(target: SkillTarget): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skill.d.ts","sourceRoot":"","sources":["../../src/lib/install-skill.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"install-skill.d.ts","sourceRoot":"","sources":["../../src/lib/install-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwBH,mDAAmD;AACnD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAiBxD,eAAO,MAAM,aAAa,EAA0B,WAAW,EAAE,CAAC;AAElE,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAE5D;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAOD,kEAAkE;AAClE,wBAAgB,mBAAmB,IAAI,MAAM,CAM5C;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,WAAsB,GAAG,MAAM,CAEvE;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAE9D;AAED,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,WAAsB,GAAG,OAAO,CAE7E;AAOD,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAEjE;AAkDD;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,IAAI,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,aAAa,EAAE,YAAY,EAuCvC,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAK3E;AAcD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,kBAAkB,CAexF;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,IAAI,kBAAkB,EAAE,CAc7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE,WAAsB,GAAG,kBAAkB,CAkB/E"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-install the `cnotes` skill so coding agents auto-discover it.
|
|
3
3
|
*
|
|
4
|
-
* The same bundled skill feeds
|
|
4
|
+
* The same bundled skill feeds every target:
|
|
5
5
|
* - Claude Code → ~/.claude/skills/cnotes/SKILL.md
|
|
6
6
|
* - OpenAI Codex → ~/.codex/skills/cnotes/SKILL.md
|
|
7
|
+
* - Cursor → ~/.cursor/skills/cnotes/SKILL.md
|
|
7
8
|
*
|
|
8
9
|
* The skill ships inside the published package at <package>/skills/cnotes/SKILL.md.
|
|
9
10
|
* At runtime this file lives at <package>/dist/lib/install-skill.js, so the
|
|
@@ -30,14 +31,28 @@ function skillsRootDir() {
|
|
|
30
31
|
return disk;
|
|
31
32
|
return materializedSkillsRoot();
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Config dir (under $HOME) and human-facing label per target — the one place a
|
|
36
|
+
* new agent gets added; the target list, labels and paths all derive from it.
|
|
37
|
+
*
|
|
38
|
+
* Cursor also reads ~/.claude/skills and ~/.codex/skills for compatibility, so
|
|
39
|
+
* a Cursor user who already installed for Claude Code sees the skill anyway.
|
|
40
|
+
* The explicit target is for Cursor-only setups, and so `--agent cursor` names
|
|
41
|
+
* the thing the user actually runs.
|
|
42
|
+
*/
|
|
43
|
+
const AGENTS = {
|
|
44
|
+
claude: { dir: ".claude", label: "Claude Code" },
|
|
45
|
+
codex: { dir: ".codex", label: "Codex" },
|
|
46
|
+
cursor: { dir: ".cursor", label: "Cursor" },
|
|
47
|
+
};
|
|
48
|
+
export const SKILL_TARGETS = Object.keys(AGENTS);
|
|
34
49
|
/** Human-facing label for a target (used in init/output messages). */
|
|
35
50
|
export function skillTargetLabel(target) {
|
|
36
|
-
return target
|
|
51
|
+
return AGENTS[target].label;
|
|
37
52
|
}
|
|
38
53
|
/** The config dir each agent reads its skills from. */
|
|
39
54
|
function agentConfigDir(target) {
|
|
40
|
-
return resolve(homedir(), target
|
|
55
|
+
return resolve(homedir(), AGENTS[target].dir);
|
|
41
56
|
}
|
|
42
57
|
/** Where the skill lives on disk inside the installed package. */
|
|
43
58
|
export function getBundledSkillPath() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../../src/lib/install-skill.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../../src/lib/install-skill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve what the caller handed `review get`: a request id, a raw 64-hex
|
|
3
|
+
* link token, or a full /review/<token> URL. An agent handed a review link
|
|
4
|
+
* must be able to continue from it without browser automation, so the URL is
|
|
5
|
+
* a first-class address here.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseReviewRef(raw: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Parse `--criteria`: criterion-level results for `complete`. JSON array of
|
|
10
|
+
* `{criterion, met, note?}`; a bare string is shorthand for a met criterion.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseCriteria(raw: string): Array<{
|
|
13
|
+
criterion: string;
|
|
14
|
+
met: boolean;
|
|
15
|
+
note?: string;
|
|
16
|
+
}>;
|
|
17
|
+
/** Map the CLI's outcome spelling to the wire's. */
|
|
18
|
+
export declare function parseOutcome(raw: string): "approved" | "changes_requested";
|
|
19
|
+
//# sourceMappingURL=review-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/review-helpers.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAmBlD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC,CAgCD;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,mBAAmB,CAO1E"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ValidationError } from "./errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Pure decisions shared by `cnotes review` and the MCP review tools — in
|
|
4
|
+
* lib/ so the two surfaces cannot drift, and testable without HTTP.
|
|
5
|
+
*/
|
|
6
|
+
const TOKEN_SHAPE = /^[0-9a-f]{64}$/;
|
|
7
|
+
/**
|
|
8
|
+
* Resolve what the caller handed `review get`: a request id, a raw 64-hex
|
|
9
|
+
* link token, or a full /review/<token> URL. An agent handed a review link
|
|
10
|
+
* must be able to continue from it without browser automation, so the URL is
|
|
11
|
+
* a first-class address here.
|
|
12
|
+
*/
|
|
13
|
+
export function parseReviewRef(raw) {
|
|
14
|
+
const trimmed = raw.trim();
|
|
15
|
+
if (!trimmed)
|
|
16
|
+
throw new ValidationError("Pass a request id, token, or review URL");
|
|
17
|
+
if (TOKEN_SHAPE.test(trimmed))
|
|
18
|
+
return trimmed;
|
|
19
|
+
if (trimmed.includes("/review/")) {
|
|
20
|
+
const tail = trimmed.split("/review/")[1]?.split(/[?#]/)[0] ?? "";
|
|
21
|
+
if (!TOKEN_SHAPE.test(tail)) {
|
|
22
|
+
throw new ValidationError("That review URL doesn't carry a valid token — copy the /review/<token> link as sent");
|
|
23
|
+
}
|
|
24
|
+
return tail;
|
|
25
|
+
}
|
|
26
|
+
if (!/^[a-z0-9]{16,64}$/.test(trimmed)) {
|
|
27
|
+
throw new ValidationError("Pass a request id (from `cnotes review list`), a 64-hex token, or a /review/<token> URL");
|
|
28
|
+
}
|
|
29
|
+
return trimmed;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse `--criteria`: criterion-level results for `complete`. JSON array of
|
|
33
|
+
* `{criterion, met, note?}`; a bare string is shorthand for a met criterion.
|
|
34
|
+
*/
|
|
35
|
+
export function parseCriteria(raw) {
|
|
36
|
+
let parsed;
|
|
37
|
+
try {
|
|
38
|
+
parsed = JSON.parse(raw);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw new ValidationError('--criteria must be JSON: \'[{"criterion":"Boundary confirmed","met":true},{"criterion":"Source fidelity","met":false,"note":"two extra lines"}]\'');
|
|
42
|
+
}
|
|
43
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
44
|
+
throw new ValidationError("--criteria must be a non-empty JSON array");
|
|
45
|
+
}
|
|
46
|
+
return parsed.map((entry, i) => {
|
|
47
|
+
if (typeof entry === "string") {
|
|
48
|
+
const criterion = entry.trim();
|
|
49
|
+
if (!criterion)
|
|
50
|
+
throw new ValidationError(`Criterion ${i + 1} is empty`);
|
|
51
|
+
return { criterion, met: true };
|
|
52
|
+
}
|
|
53
|
+
const row = entry;
|
|
54
|
+
const criterion = typeof row?.criterion === "string" ? row.criterion.trim() : "";
|
|
55
|
+
if (!criterion) {
|
|
56
|
+
throw new ValidationError(`Criterion ${i + 1} needs a "criterion" string`);
|
|
57
|
+
}
|
|
58
|
+
if (typeof row.met !== "boolean") {
|
|
59
|
+
throw new ValidationError(`Criterion ${i + 1} needs "met": true or false`);
|
|
60
|
+
}
|
|
61
|
+
const note = typeof row.note === "string" ? row.note.trim() : "";
|
|
62
|
+
return { criterion, met: row.met, ...(note ? { note } : {}) };
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** Map the CLI's outcome spelling to the wire's. */
|
|
66
|
+
export function parseOutcome(raw) {
|
|
67
|
+
const normalized = raw.trim().toLowerCase().replace(/-/g, "_");
|
|
68
|
+
if (normalized === "approved")
|
|
69
|
+
return "approved";
|
|
70
|
+
if (normalized === "changes_requested")
|
|
71
|
+
return "changes_requested";
|
|
72
|
+
throw new ValidationError("--outcome must be approved or changes-requested");
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=review-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-helpers.js","sourceRoot":"","sources":["../../src/lib/review-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-server.js
CHANGED
|
@@ -32,6 +32,7 @@ import { buildSchema } from "./lib/build-schema.js";
|
|
|
32
32
|
import { assertMcpLocalFileReadable, getMcpLocalFileRoots, } from "./lib/mcp-local-file.js";
|
|
33
33
|
import { attachRubricsToResults, loadRubricMap, rubricsForTypes, } from "./lib/rubrics.js";
|
|
34
34
|
import { lintNarratedVerbMentions, lintPlainTextDisplayIds, lintPlainTextDisplayIdsBatch, hasGenericMention, fetchRelationshipTypeOptions, } from "./lib/mention-lint.js";
|
|
35
|
+
import { parseReviewRef } from "./lib/review-helpers.js";
|
|
35
36
|
// ---------------------------------------------------------------------------
|
|
36
37
|
// Environment
|
|
37
38
|
// ---------------------------------------------------------------------------
|
|
@@ -786,6 +787,141 @@ server.tool("cnotes_shared_with_you", "List what teammates shared with the user:
|
|
|
786
787
|
limit: limit !== undefined ? String(limit) : undefined,
|
|
787
788
|
})));
|
|
788
789
|
// ---------------------------------------------------------------------------
|
|
790
|
+
// Review requests — the official review contract, both legs. Create one for
|
|
791
|
+
// a human or agent principal, discover the ones assigned to you, fetch the
|
|
792
|
+
// machine-readable envelope, add findings, and record exactly one outcome.
|
|
793
|
+
// ---------------------------------------------------------------------------
|
|
794
|
+
server.tool("cnotes_review_request", 'Create an official review request on a canvas. The canvas IS the request: assemble it first (context notes reused from research, Question notes to answer, an instruction text node), then point this at it. reviewer: "me" mints a SELF-REVIEW that is actionable immediately with no invitation step; a workspace member\'s user id assigns them the same way; an email binds an outside reviewer who accepts via the returned link. Returns {requestId, url, …} — the url is the canonical human review link (never assemble one yourself), the requestId is the automation handle for cnotes_review_get / cnotes_review_complete. Pass idempotencyKey so a retried create returns the same request instead of minting a sibling.', {
|
|
795
|
+
canvasId: z.string().describe('Canvas display id ("CANVAS-81") or raw id'),
|
|
796
|
+
reviewer: z
|
|
797
|
+
.string()
|
|
798
|
+
.optional()
|
|
799
|
+
.describe('"me" (self-review), a member\'s user id, or an email (outside reviewer). Omit for a link any member can claim'),
|
|
800
|
+
brief: z
|
|
801
|
+
.string()
|
|
802
|
+
.max(2000)
|
|
803
|
+
.optional()
|
|
804
|
+
.describe("One to four sentences introducing the ask. Defaults to the canvas goal"),
|
|
805
|
+
questions: z
|
|
806
|
+
.array(z.object({
|
|
807
|
+
question: z.string().min(1).max(500),
|
|
808
|
+
anchorDisplayId: z.string().max(40).nullable().describe("The card this question is about, or null"),
|
|
809
|
+
}))
|
|
810
|
+
.max(5)
|
|
811
|
+
.optional()
|
|
812
|
+
.describe("Mint these as new Question notes. Omit when the canvas already carries its questions"),
|
|
813
|
+
acceptance: z
|
|
814
|
+
.array(z.string().min(1).max(500))
|
|
815
|
+
.max(10)
|
|
816
|
+
.optional()
|
|
817
|
+
.describe("Testable acceptance criteria, one sentence each"),
|
|
818
|
+
target: z
|
|
819
|
+
.string()
|
|
820
|
+
.optional()
|
|
821
|
+
.describe('Focus the review on one place: a NOTE-… or SECTION-… display id on the canvas'),
|
|
822
|
+
source: z
|
|
823
|
+
.string()
|
|
824
|
+
.optional()
|
|
825
|
+
.describe("Provenance: the note this request grew out of (display id or note id)"),
|
|
826
|
+
idempotencyKey: z
|
|
827
|
+
.string()
|
|
828
|
+
.max(200)
|
|
829
|
+
.optional()
|
|
830
|
+
.describe("Same key = same request: a retried create returns the existing one"),
|
|
831
|
+
}, async ({ canvasId, reviewer, brief, questions, acceptance, target, source, idempotencyKey }) => withErrorHandling(() => api.post("/api/review-requests", {
|
|
832
|
+
canvasId,
|
|
833
|
+
workspaceId,
|
|
834
|
+
...(brief?.trim() ? { brief: brief.trim() } : {}),
|
|
835
|
+
...(questions?.length ? { slate: questions } : {}),
|
|
836
|
+
...(reviewer?.trim() ? { reviewer: reviewer.trim() } : {}),
|
|
837
|
+
...(acceptance?.length ? { acceptance } : {}),
|
|
838
|
+
...(target?.trim() ? { target: target.trim() } : {}),
|
|
839
|
+
...(source?.trim() ? { source: source.trim() } : {}),
|
|
840
|
+
...(idempotencyKey?.trim() ? { idempotencyKey: idempotencyKey.trim() } : {}),
|
|
841
|
+
})));
|
|
842
|
+
server.tool("cnotes_review_get", "Fetch one review request's full machine-readable envelope: lifecycle status, outcome + rationale + criterion results, requester/reviewer identities and actor kinds, the canvas target (and targetRef focus), the brief and acceptance criteria, provenance (sourceNote), the question slate, findings so far, staleness (canvasChanged — completing then needs acceptStale), the canonical human url, and allowedActions for the CALLER. Accepts a request id, a raw token, or a full /review/<token> URL — an agent handed a review link resolves it here and continues without a browser.", {
|
|
843
|
+
ref: z.string().describe("Request id, /review/<token> URL, or raw 64-hex token"),
|
|
844
|
+
}, async ({ ref }) => withErrorHandling(() => api.get(`/api/review-requests/${encodeURIComponent(parseReviewRef(ref))}`, {
|
|
845
|
+
workspaceId,
|
|
846
|
+
})));
|
|
847
|
+
server.tool("cnotes_review_list", 'List review requests. Pass canvasId for the requester view (asks out on one canvas, their status and links). Pass assignedTo: "me" for the reviewer worklist — the reviews waiting on the user\'s judgment (status "actionable", the default) or their full history (status "all"). One of canvasId / assignedTo is required.', {
|
|
848
|
+
canvasId: z.string().optional().describe('Requester view: canvas display id ("CANVAS-81") or raw id'),
|
|
849
|
+
assignedTo: z.literal("me").optional().describe('Reviewer view: the worklist assigned to the user'),
|
|
850
|
+
status: z
|
|
851
|
+
.enum(["actionable", "all"])
|
|
852
|
+
.optional()
|
|
853
|
+
.describe('With assignedTo: "actionable" (default) or "all"'),
|
|
854
|
+
}, async ({ canvasId, assignedTo, status }) => withErrorHandling(() => {
|
|
855
|
+
if (assignedTo === "me") {
|
|
856
|
+
return api.get("/api/review-requests", {
|
|
857
|
+
assignedTo: "me",
|
|
858
|
+
workspaceId,
|
|
859
|
+
...(status ? { status } : {}),
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
if (!canvasId) {
|
|
863
|
+
throw new CliError('Pass canvasId, or assignedTo: "me"');
|
|
864
|
+
}
|
|
865
|
+
return api.get("/api/review-requests", { canvasId, workspaceId });
|
|
866
|
+
}));
|
|
867
|
+
server.tool("cnotes_review_add_finding", "Add one anchored review finding to a review request — a specific observation against a card, section, or node on the reviewed canvas. Findings stay private drafts until cnotes_review_complete (or a review submit) delivers them with the outcome. Anchor to the most specific node the finding is about; compare against the request's acceptance criteria (cnotes_review_get).", {
|
|
868
|
+
requestId: z.string().describe("The review request this finding answers"),
|
|
869
|
+
node: z.string().describe('Target node: a raw canvas node id, "NOTE-12", or "SECTION-7"'),
|
|
870
|
+
text: z.string().min(1).max(4000).describe("The finding itself — specific, anchored, actionable"),
|
|
871
|
+
}, async ({ requestId, node, text }) => withErrorHandling(async () => {
|
|
872
|
+
// The envelope knows the canvas — the caller shouldn't have to.
|
|
873
|
+
const envelope = (await api.get(`/api/review-requests/${encodeURIComponent(parseReviewRef(requestId))}`, { workspaceId }));
|
|
874
|
+
return api.post(`/api/canvas/${encodeURIComponent(envelope.canvas.id)}?workspaceId=${encodeURIComponent(workspaceId)}`, {
|
|
875
|
+
action: "addComment",
|
|
876
|
+
targetNodeId: node,
|
|
877
|
+
content: text,
|
|
878
|
+
reviewRequestId: envelope.requestId,
|
|
879
|
+
});
|
|
880
|
+
}));
|
|
881
|
+
server.tool("cnotes_review_return", "Hand a review back UNCOMPLETED with a structured blocker — the honest exit when the assigned reviewer cannot judge it (missing evidence, missing access, insufficient capability). Never complete a review you could not actually perform. Terminal for this ask: the reason lands in the requester's inbox and their follow-up is a fresh, better-packaged request.", {
|
|
882
|
+
requestId: z.string().describe("The review request to hand back"),
|
|
883
|
+
reason: z
|
|
884
|
+
.string()
|
|
885
|
+
.min(1)
|
|
886
|
+
.max(500)
|
|
887
|
+
.describe("What was missing — the requester acts on this"),
|
|
888
|
+
}, async ({ requestId, reason }) => withErrorHandling(() => api.post(`/api/review-requests/${encodeURIComponent(requestId)}`, {
|
|
889
|
+
action: "return",
|
|
890
|
+
reason,
|
|
891
|
+
workspaceId,
|
|
892
|
+
})));
|
|
893
|
+
server.tool("cnotes_review_complete", 'Record a review\'s one structured outcome: "approved" or "changes_requested", with the rationale that carries the judgment and optional criterion-level results. Only the assigned reviewer can complete; the audit trail records the agent transport and the principal. Findings added against this request are delivered in the same act. If the envelope says canvasChanged, re-read the board first and pass acceptStale — completion never silently applies to a version that moved. If you cannot judge it (missing evidence, permission, capability), do NOT complete: add a finding naming the blocker and leave it actionable. Pass idempotencyKey so a retry returns the recorded outcome instead of conflicting.', {
|
|
894
|
+
requestId: z.string().describe("The review request to complete"),
|
|
895
|
+
outcome: z.enum(["approved", "changes_requested"]).describe("The verdict"),
|
|
896
|
+
rationale: z.string().min(1).max(2000).describe("Why — travels with the outcome"),
|
|
897
|
+
criteria: z
|
|
898
|
+
.array(z.object({
|
|
899
|
+
criterion: z.string().min(1).max(500),
|
|
900
|
+
met: z.boolean(),
|
|
901
|
+
note: z.string().max(1000).optional(),
|
|
902
|
+
}))
|
|
903
|
+
.max(20)
|
|
904
|
+
.optional()
|
|
905
|
+
.describe("Criterion-level results, ideally one per acceptance criterion"),
|
|
906
|
+
idempotencyKey: z
|
|
907
|
+
.string()
|
|
908
|
+
.max(200)
|
|
909
|
+
.optional()
|
|
910
|
+
.describe("Same key = same completion: a retry returns the recorded outcome"),
|
|
911
|
+
acceptStale: z
|
|
912
|
+
.boolean()
|
|
913
|
+
.optional()
|
|
914
|
+
.describe("The board moved since the ask and you judged it as it is NOW"),
|
|
915
|
+
}, async ({ requestId, outcome, rationale, criteria, idempotencyKey, acceptStale }) => withErrorHandling(() => api.post(`/api/review-requests/${encodeURIComponent(requestId)}`, {
|
|
916
|
+
action: "complete",
|
|
917
|
+
workspaceId,
|
|
918
|
+
outcome,
|
|
919
|
+
rationale,
|
|
920
|
+
...(criteria?.length ? { criterionResults: criteria } : {}),
|
|
921
|
+
...(idempotencyKey?.trim() ? { idempotencyKey: idempotencyKey.trim() } : {}),
|
|
922
|
+
...(acceptStale ? { acceptStale: true } : {}),
|
|
923
|
+
})));
|
|
924
|
+
// ---------------------------------------------------------------------------
|
|
789
925
|
// Focus plans — planned flow-state blocks (intentions). The Focus calendar
|
|
790
926
|
// overlays them on recorded attention; kept/missed is derived, so there is
|
|
791
927
|
// deliberately no "complete" tool.
|