codiedev 0.5.2 → 0.5.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/dist/cli.js +8 -0
- package/dist/commands/delete.d.ts +1 -0
- package/dist/commands/delete.js +96 -0
- package/dist/mcp.js +127 -18
- package/dist/utils.js +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
const connect_1 = require("./connect");
|
|
19
19
|
const push_1 = require("./commands/push");
|
|
20
|
+
const delete_1 = require("./commands/delete");
|
|
20
21
|
const pull_1 = require("./commands/pull");
|
|
21
22
|
const ping_1 = require("./commands/ping");
|
|
22
23
|
const inbox_1 = require("./commands/inbox");
|
|
@@ -39,6 +40,9 @@ Artifacts:
|
|
|
39
40
|
codiedev push <file.md> Author or update an artifact
|
|
40
41
|
codiedev pull <key> [--version N] [--out path]
|
|
41
42
|
Fetch an artifact (stdout by default)
|
|
43
|
+
codiedev delete <key> [-y] Delete every version of an artifact you
|
|
44
|
+
authored (clean up bad/test pushes).
|
|
45
|
+
Asks for confirmation; -y to skip.
|
|
42
46
|
codiedev promote <artifact-id> Promote an auto-extracted artifact
|
|
43
47
|
to an authored one
|
|
44
48
|
codiedev reverse-ticket [<pr-url>] Generate a Jira ticket draft.
|
|
@@ -363,6 +367,10 @@ async function main() {
|
|
|
363
367
|
case "push":
|
|
364
368
|
await (0, push_1.runPush)(rest);
|
|
365
369
|
return;
|
|
370
|
+
case "delete":
|
|
371
|
+
case "rm":
|
|
372
|
+
await (0, delete_1.runDelete)(rest);
|
|
373
|
+
return;
|
|
366
374
|
case "pull":
|
|
367
375
|
await (0, pull_1.runPull)(rest);
|
|
368
376
|
return;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runDelete(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runDelete = runDelete;
|
|
37
|
+
const readline = __importStar(require("readline"));
|
|
38
|
+
const shared_1 = require("./shared");
|
|
39
|
+
function parseArgs(args) {
|
|
40
|
+
let key;
|
|
41
|
+
let yes = false;
|
|
42
|
+
for (const a of args) {
|
|
43
|
+
if (a === "-y" || a === "--yes") {
|
|
44
|
+
yes = true;
|
|
45
|
+
}
|
|
46
|
+
else if (!a.startsWith("--") && !key) {
|
|
47
|
+
key = a;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!key) {
|
|
51
|
+
console.error("Usage: codiedev delete <key> [-y]");
|
|
52
|
+
console.error("Example: codiedev delete spec-old.md");
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
return { key, yes };
|
|
56
|
+
}
|
|
57
|
+
async function confirm(prompt) {
|
|
58
|
+
const rl = readline.createInterface({
|
|
59
|
+
input: process.stdin,
|
|
60
|
+
output: process.stdout,
|
|
61
|
+
});
|
|
62
|
+
const answer = await new Promise((resolve) => {
|
|
63
|
+
rl.question(prompt, (ans) => resolve(ans));
|
|
64
|
+
});
|
|
65
|
+
rl.close();
|
|
66
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
67
|
+
}
|
|
68
|
+
async function runDelete(args) {
|
|
69
|
+
const { key, yes } = parseArgs(args);
|
|
70
|
+
const config = (0, shared_1.requireConfig)();
|
|
71
|
+
if (!yes) {
|
|
72
|
+
const ok = await confirm(`Delete every version of '${key}' (and its replies)? This cannot be undone. [y/N] `);
|
|
73
|
+
if (!ok) {
|
|
74
|
+
console.log("Cancelled.");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/delete", {
|
|
80
|
+
config,
|
|
81
|
+
body: { key },
|
|
82
|
+
});
|
|
83
|
+
if (res.deleted === 0) {
|
|
84
|
+
console.log(`No artifact found with key '${key}'. Nothing to delete.`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const cascaded = res.cascadedMessages > 0
|
|
88
|
+
? ` + ${res.cascadedMessages} reply${res.cascadedMessages === 1 ? "" : "ies"}`
|
|
89
|
+
: "";
|
|
90
|
+
console.log(`✓ Deleted ${res.deleted} version${res.deleted === 1 ? "" : "s"}${cascaded} of '${res.key}'.`);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
console.error(`Delete failed: ${err.message}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
package/dist/mcp.js
CHANGED
|
@@ -117,11 +117,13 @@ const TOOLS = [
|
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
119
|
name: "codiedev_pull",
|
|
120
|
-
description: "Fetch
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
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: {
|
|
@@ -137,6 +139,26 @@ const TOOLS = [
|
|
|
137
139
|
required: ["key"],
|
|
138
140
|
},
|
|
139
141
|
},
|
|
142
|
+
{
|
|
143
|
+
name: "codiedev_delete",
|
|
144
|
+
description: "Delete every version of an artifact (and its replies) by key. Use " +
|
|
145
|
+
"when the user asks to delete, remove, undo, throw away, or clean up " +
|
|
146
|
+
"an artifact (e.g., 'delete that test push', 'remove the duplicate', " +
|
|
147
|
+
"'rm spec-old'). Authorship is enforced server-side: you can only " +
|
|
148
|
+
"delete artifacts you authored. Always confirm with the user before " +
|
|
149
|
+
"calling — deletions cannot be undone.",
|
|
150
|
+
inputSchema: {
|
|
151
|
+
type: "object",
|
|
152
|
+
properties: {
|
|
153
|
+
key: {
|
|
154
|
+
type: "string",
|
|
155
|
+
description: "Filename key of the artifact to delete, e.g. 'spec-214.md'. " +
|
|
156
|
+
"Every version of this key is removed.",
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
required: ["key"],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
140
162
|
{
|
|
141
163
|
name: "codiedev_ping",
|
|
142
164
|
description: "Send a message to a teammate on CodieDev, optionally attached to a " +
|
|
@@ -374,10 +396,13 @@ const TOOLS = [
|
|
|
374
396
|
},
|
|
375
397
|
{
|
|
376
398
|
name: "codiedev_get_library",
|
|
377
|
-
description: "List artifacts in the team library
|
|
378
|
-
"
|
|
379
|
-
"
|
|
380
|
-
"
|
|
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.",
|
|
381
406
|
inputSchema: {
|
|
382
407
|
type: "object",
|
|
383
408
|
properties: {
|
|
@@ -387,10 +412,24 @@ const TOOLS = [
|
|
|
387
412
|
description: "'mine' = artifacts I authored (default). 'shared' = artifacts " +
|
|
388
413
|
"explicitly shared with me. 'all' = everything in the company.",
|
|
389
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
|
+
},
|
|
390
428
|
type: {
|
|
391
429
|
type: "string",
|
|
392
430
|
enum: ["spec", "bugfix", "decision", "proposal", "review", "note"],
|
|
393
|
-
description: "
|
|
431
|
+
description: "Legacy doc-shape filter — kept for back-compat. Prefer `kind` " +
|
|
432
|
+
"or `tag` for new code.",
|
|
394
433
|
},
|
|
395
434
|
folderPath: { type: "string", description: "Filter to one folder path." },
|
|
396
435
|
limit: { type: "integer", description: "Max rows. Default 50." },
|
|
@@ -514,6 +553,8 @@ async function dispatchTool(name, args, config) {
|
|
|
514
553
|
return await handlePush(args, config);
|
|
515
554
|
case "codiedev_pull":
|
|
516
555
|
return await handlePull(args, config);
|
|
556
|
+
case "codiedev_delete":
|
|
557
|
+
return await handleDelete(args, config);
|
|
517
558
|
case "codiedev_ping":
|
|
518
559
|
return await handlePing(args, config);
|
|
519
560
|
case "codiedev_inbox":
|
|
@@ -587,6 +628,33 @@ async function handlePull(args, config) {
|
|
|
587
628
|
content: [{ type: "text", text: header + a.markdown }],
|
|
588
629
|
};
|
|
589
630
|
}
|
|
631
|
+
async function handleDelete(args, config) {
|
|
632
|
+
const key = asString(args.key);
|
|
633
|
+
if (!key)
|
|
634
|
+
throw new Error("key required");
|
|
635
|
+
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/delete", { config, body: { key } });
|
|
636
|
+
if (res.deleted === 0) {
|
|
637
|
+
return {
|
|
638
|
+
content: [
|
|
639
|
+
{
|
|
640
|
+
type: "text",
|
|
641
|
+
text: `No artifact found with key '${key}'. Nothing to delete.`,
|
|
642
|
+
},
|
|
643
|
+
],
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
const cascaded = res.cascadedMessages > 0
|
|
647
|
+
? ` + ${res.cascadedMessages} reply${res.cascadedMessages === 1 ? "" : "ies"}`
|
|
648
|
+
: "";
|
|
649
|
+
return {
|
|
650
|
+
content: [
|
|
651
|
+
{
|
|
652
|
+
type: "text",
|
|
653
|
+
text: `✓ Deleted ${res.deleted} version${res.deleted === 1 ? "" : "s"}${cascaded} of '${res.key}'.`,
|
|
654
|
+
},
|
|
655
|
+
],
|
|
656
|
+
};
|
|
657
|
+
}
|
|
590
658
|
async function handlePing(args, config) {
|
|
591
659
|
const to = asString(args.to);
|
|
592
660
|
const body = asString(args.body);
|
|
@@ -726,16 +794,48 @@ async function handleShareWith(args, config) {
|
|
|
726
794
|
config,
|
|
727
795
|
body: { filename, to, role },
|
|
728
796
|
});
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
797
|
+
const target = `${res.recipient.name} <${res.recipient.email}>`;
|
|
798
|
+
if (res.added) {
|
|
799
|
+
return {
|
|
800
|
+
content: [
|
|
801
|
+
{
|
|
802
|
+
type: "text",
|
|
803
|
+
text: `✓ Shared ${target} on ${filename} (role=${role ?? "read"}).`,
|
|
804
|
+
},
|
|
805
|
+
],
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
if (res.updated) {
|
|
809
|
+
return {
|
|
810
|
+
content: [
|
|
811
|
+
{
|
|
812
|
+
type: "text",
|
|
813
|
+
text: `✓ Updated share for ${target} on ${filename} (role=${role ?? "read"}).`,
|
|
814
|
+
},
|
|
815
|
+
],
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
// noop / duplicate path — surface where the existing grant came from so
|
|
819
|
+
// the user knows whether to expect it next time.
|
|
820
|
+
const e = res.existing;
|
|
821
|
+
let why = "";
|
|
822
|
+
if (e) {
|
|
823
|
+
const when = e.grantedAt ? ` ${(0, shared_1.timeAgo)(e.grantedAt)}` : "";
|
|
824
|
+
if (e.source === "self") {
|
|
825
|
+
why = ` — you already shared it with them${when} (role=${e.role}).`;
|
|
826
|
+
}
|
|
827
|
+
else if (e.source === "auto") {
|
|
828
|
+
why = ` — granted automatically${when} (role=${e.role}). No action needed next time.`;
|
|
829
|
+
}
|
|
830
|
+
else {
|
|
831
|
+
why = ` — ${e.granterLabel} shared it${when} (role=${e.role}).`;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
734
834
|
return {
|
|
735
835
|
content: [
|
|
736
836
|
{
|
|
737
837
|
type: "text",
|
|
738
|
-
text: `✓
|
|
838
|
+
text: `✓ Already shared with ${target} on ${filename}${why}`,
|
|
739
839
|
},
|
|
740
840
|
],
|
|
741
841
|
};
|
|
@@ -818,6 +918,8 @@ async function handleSearch(args, config) {
|
|
|
818
918
|
async function handleGetLibrary(args, config) {
|
|
819
919
|
const scope = asStringOrUndefined(args.scope);
|
|
820
920
|
const type = asStringOrUndefined(args.type);
|
|
921
|
+
const kind = asStringOrUndefined(args.kind);
|
|
922
|
+
const tag = asStringOrUndefined(args.tag);
|
|
821
923
|
const folderPath = asStringOrUndefined(args.folderPath);
|
|
822
924
|
const limit = asIntOrUndefined(args.limit);
|
|
823
925
|
const res = await (0, shared_1.apiRequest)("GET", "/api/cli/library", {
|
|
@@ -825,6 +927,8 @@ async function handleGetLibrary(args, config) {
|
|
|
825
927
|
query: {
|
|
826
928
|
scope,
|
|
827
929
|
type,
|
|
930
|
+
kind,
|
|
931
|
+
tag,
|
|
828
932
|
folderPath,
|
|
829
933
|
limit: limit?.toString(),
|
|
830
934
|
},
|
|
@@ -840,7 +944,7 @@ async function handleGetLibrary(args, config) {
|
|
|
840
944
|
};
|
|
841
945
|
}
|
|
842
946
|
const lines = [
|
|
843
|
-
`Library · scope=${scope ?? "mine"} · ${res.artifacts.length} item${res.artifacts.length === 1 ? "" : "s"}`,
|
|
947
|
+
`Library · scope=${scope ?? "mine"}${kind ? ` · kind=${kind}` : ""} · ${res.artifacts.length} item${res.artifacts.length === 1 ? "" : "s"}`,
|
|
844
948
|
"",
|
|
845
949
|
];
|
|
846
950
|
for (const a of res.artifacts) {
|
|
@@ -848,7 +952,12 @@ async function handleGetLibrary(args, config) {
|
|
|
848
952
|
const v = a.version ? ` v${a.version}` : "";
|
|
849
953
|
const life = a.lifecycle ? ` · ${a.lifecycle}` : "";
|
|
850
954
|
const when = a.updatedAt ? ` · ${(0, shared_1.timeAgo)(a.updatedAt)}` : "";
|
|
851
|
-
|
|
955
|
+
// Lead with the canonical kind (doc | skill). Tags carry the legacy
|
|
956
|
+
// doc-shape (spec/decision/...) plus any author-added labels — surface
|
|
957
|
+
// them after the kind so the row is self-describing.
|
|
958
|
+
const k = a.kind ?? (a.type === "note" ? "doc" : "doc");
|
|
959
|
+
const tagList = (a.tags ?? []).length > 0 ? ` [${a.tags.join(", ")}]` : "";
|
|
960
|
+
lines.push(`[${k}]${tagList} ${loc}${a.key ?? a.title}${v}${life}${when}`);
|
|
852
961
|
lines.push(` ${a.title}`);
|
|
853
962
|
lines.push("");
|
|
854
963
|
}
|
package/dist/utils.js
CHANGED
|
@@ -208,6 +208,7 @@ thought, use the \`codiedev\` CLI via Bash:**
|
|
|
208
208
|
|---|---|
|
|
209
209
|
| "push this spec" / "save this as a skill" | \`codiedev push <file.md>\` |
|
|
210
210
|
| "pull X" / "grab the latest spec-X" / "what did Maya push?" | \`codiedev pull <key>\` |
|
|
211
|
+
| "delete X" / "remove that test push" / "rm spec-old" | \`codiedev delete <key>\` (always confirm with the user first) |
|
|
211
212
|
| "ping Nic about this" / "ask Maya for her take" | \`codiedev ping <name> "<msg>" [--with <key>]\` |
|
|
212
213
|
| "any messages?" / "check my inbox" / "what did Nic say?" | \`codiedev inbox\` |
|
|
213
214
|
| "read Nic's reply" / "mark that ping read" | \`codiedev read <ping-id>\` |
|