codiedev 0.5.3 → 0.5.5

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/mcp.js +86 -19
  2. package/package.json +1 -1
package/dist/mcp.js CHANGED
@@ -117,11 +117,13 @@ const TOOLS = [
117
117
  },
118
118
  {
119
119
  name: "codiedev_pull",
120
- description: "Fetch an artifact (spec, review, decision, proposal, bugfix, or " +
121
- "note) from the team's CodieDev artifact layer. Use when the user " +
122
- "asks to pull, grab, fetch, or resume work on a named artifact, or " +
123
- "when they want to see what a teammate pushed. Returns the full " +
124
- "markdown content.",
120
+ description: "Fetch any artifact (doc or skill) from the team's CodieDev artifact " +
121
+ "layer. Works for specs, decisions, proposals, bugfixes, reviews, " +
122
+ "notes, AND skills (SKILL.md frontmatter files surfaced as slash " +
123
+ "commands). Use when the user asks to pull, grab, fetch, or resume " +
124
+ "work on a named artifact, when they want to load a skill into " +
125
+ "their session (e.g. 'pull the writing-emails skill'), or when they " +
126
+ "want to see what a teammate pushed. Returns the full markdown.",
125
127
  inputSchema: {
126
128
  type: "object",
127
129
  properties: {
@@ -394,10 +396,13 @@ const TOOLS = [
394
396
  },
395
397
  {
396
398
  name: "codiedev_get_library",
397
- description: "List artifacts in the team library, scoped to what the current " +
398
- "user authored, what's been shared with them, or everything in the " +
399
- "company. Use when the user asks 'show me my artifacts', 'what did " +
400
- "I push?', 'what has Greg shared with me?', or 'browse the library'.",
399
+ description: "List artifacts in the team library both docs (spec / decision / " +
400
+ "proposal / bugfix / review / note) and skills (SKILL.md frontmatter " +
401
+ "files surfaced as slash commands). Each row reports its `kind` " +
402
+ "(doc | skill) and `tags`. Use when the user asks 'show me my " +
403
+ "artifacts', 'what skills do we have?', 'what did I push?', 'what " +
404
+ "has Greg shared with me?', or 'browse the library'. Filter by " +
405
+ "`kind` to narrow to docs-only or skills-only.",
401
406
  inputSchema: {
402
407
  type: "object",
403
408
  properties: {
@@ -407,10 +412,24 @@ const TOOLS = [
407
412
  description: "'mine' = artifacts I authored (default). 'shared' = artifacts " +
408
413
  "explicitly shared with me. 'all' = everything in the company.",
409
414
  },
415
+ kind: {
416
+ type: "string",
417
+ enum: ["doc", "skill"],
418
+ description: "Filter to one kind. `skill` = files with SKILL.md frontmatter " +
419
+ "(slash commands). `doc` = everything else (specs, decisions, " +
420
+ "etc.). Omit to return both.",
421
+ },
422
+ tag: {
423
+ type: "string",
424
+ description: "Filter to one tag (e.g. 'spec', 'decision', 'auth'). The " +
425
+ "legacy doc-shape (spec/decision/...) is automatically " +
426
+ "available as a tag, plus anything the author added.",
427
+ },
410
428
  type: {
411
429
  type: "string",
412
430
  enum: ["spec", "bugfix", "decision", "proposal", "review", "note"],
413
- description: "Filter to one artifact type.",
431
+ description: "Legacy doc-shape filter kept for back-compat. Prefer `kind` " +
432
+ "or `tag` for new code.",
414
433
  },
415
434
  folderPath: { type: "string", description: "Filter to one folder path." },
416
435
  limit: { type: "integer", description: "Max rows. Default 50." },
@@ -602,8 +621,15 @@ async function handlePull(args, config) {
602
621
  throw new Error("key required");
603
622
  const res = await (0, shared_1.apiRequest)("GET", "/api/cli/pull", { config, query: { key, version } });
604
623
  const a = res.artifact;
624
+ // Lead with the new-vocab kind. Legacy doc-shape (spec/decision/...) is
625
+ // surfaced as a tag list after, so callers still see it but it's no
626
+ // longer the primary label. Falls back to "doc" if the row pre-dates the
627
+ // kind field.
628
+ const kindLabel = a.kind ?? "doc";
629
+ const tagList = (a.tags ?? []).filter((t) => t).join(", ");
630
+ const tagSuffix = tagList ? ` · tags: ${tagList}` : "";
605
631
  const header = `# ${a.title}\n\n` +
606
- `**${a.type}** · v${a.version ?? 1} · ${a.lifecycle ?? "draft"} · ` +
632
+ `**${kindLabel}** · v${a.version ?? 1} · ${a.lifecycle ?? "draft"}${tagSuffix} · ` +
607
633
  `updated ${(0, shared_1.timeAgo)(a.updatedAt ?? a.createdAt)}\n\n---\n\n`;
608
634
  return {
609
635
  content: [{ type: "text", text: header + a.markdown }],
@@ -775,16 +801,48 @@ async function handleShareWith(args, config) {
775
801
  config,
776
802
  body: { filename, to, role },
777
803
  });
778
- const verb = res.action === "added"
779
- ? "Shared"
780
- : res.action === "updated"
781
- ? "Updated share for"
782
- : "Already shared with";
804
+ const target = `${res.recipient.name} <${res.recipient.email}>`;
805
+ if (res.added) {
806
+ return {
807
+ content: [
808
+ {
809
+ type: "text",
810
+ text: `✓ Shared ${target} on ${filename} (role=${role ?? "read"}).`,
811
+ },
812
+ ],
813
+ };
814
+ }
815
+ if (res.updated) {
816
+ return {
817
+ content: [
818
+ {
819
+ type: "text",
820
+ text: `✓ Updated share for ${target} on ${filename} (role=${role ?? "read"}).`,
821
+ },
822
+ ],
823
+ };
824
+ }
825
+ // noop / duplicate path — surface where the existing grant came from so
826
+ // the user knows whether to expect it next time.
827
+ const e = res.existing;
828
+ let why = "";
829
+ if (e) {
830
+ const when = e.grantedAt ? ` ${(0, shared_1.timeAgo)(e.grantedAt)}` : "";
831
+ if (e.source === "self") {
832
+ why = ` — you already shared it with them${when} (role=${e.role}).`;
833
+ }
834
+ else if (e.source === "auto") {
835
+ why = ` — granted automatically${when} (role=${e.role}). No action needed next time.`;
836
+ }
837
+ else {
838
+ why = ` — ${e.granterLabel} shared it${when} (role=${e.role}).`;
839
+ }
840
+ }
783
841
  return {
784
842
  content: [
785
843
  {
786
844
  type: "text",
787
- text: `✓ ${verb} ${res.recipient.name} <${res.recipient.email}> on ${filename} (role=${role ?? "read"}).`,
845
+ text: `✓ Already shared with ${target} on ${filename}${why}`,
788
846
  },
789
847
  ],
790
848
  };
@@ -867,6 +925,8 @@ async function handleSearch(args, config) {
867
925
  async function handleGetLibrary(args, config) {
868
926
  const scope = asStringOrUndefined(args.scope);
869
927
  const type = asStringOrUndefined(args.type);
928
+ const kind = asStringOrUndefined(args.kind);
929
+ const tag = asStringOrUndefined(args.tag);
870
930
  const folderPath = asStringOrUndefined(args.folderPath);
871
931
  const limit = asIntOrUndefined(args.limit);
872
932
  const res = await (0, shared_1.apiRequest)("GET", "/api/cli/library", {
@@ -874,6 +934,8 @@ async function handleGetLibrary(args, config) {
874
934
  query: {
875
935
  scope,
876
936
  type,
937
+ kind,
938
+ tag,
877
939
  folderPath,
878
940
  limit: limit?.toString(),
879
941
  },
@@ -889,7 +951,7 @@ async function handleGetLibrary(args, config) {
889
951
  };
890
952
  }
891
953
  const lines = [
892
- `Library · scope=${scope ?? "mine"} · ${res.artifacts.length} item${res.artifacts.length === 1 ? "" : "s"}`,
954
+ `Library · scope=${scope ?? "mine"}${kind ? ` · kind=${kind}` : ""} · ${res.artifacts.length} item${res.artifacts.length === 1 ? "" : "s"}`,
893
955
  "",
894
956
  ];
895
957
  for (const a of res.artifacts) {
@@ -897,7 +959,12 @@ async function handleGetLibrary(args, config) {
897
959
  const v = a.version ? ` v${a.version}` : "";
898
960
  const life = a.lifecycle ? ` · ${a.lifecycle}` : "";
899
961
  const when = a.updatedAt ? ` · ${(0, shared_1.timeAgo)(a.updatedAt)}` : "";
900
- lines.push(`[${a.type}] ${loc}${a.key ?? a.title}${v}${life}${when}`);
962
+ // Lead with the canonical kind (doc | skill). Tags carry the legacy
963
+ // doc-shape (spec/decision/...) plus any author-added labels — surface
964
+ // them after the kind so the row is self-describing.
965
+ const k = a.kind ?? (a.type === "note" ? "doc" : "doc");
966
+ const tagList = (a.tags ?? []).length > 0 ? ` [${a.tags.join(", ")}]` : "";
967
+ lines.push(`[${k}]${tagList} ${loc}${a.key ?? a.title}${v}${life}${when}`);
901
968
  lines.push(` ${a.title}`);
902
969
  lines.push("");
903
970
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codiedev",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "Connect Claude Code or Codex to CodieDev for org-wide session capture and artifact collaboration",
5
5
  "bin": {
6
6
  "codiedev": "./dist/cli.js",