codiedev 0.10.0-beta.4 → 0.10.0-beta.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.
- package/README.md +7 -1
- package/assets/tui-brand-plugin.tsx +14 -2
- package/dist/backup/cache.js +1 -5
- package/dist/backup/match.js +0 -6
- package/dist/backup/run.js +3 -35
- package/dist/captureExclusions.js +0 -12
- package/dist/captureLog.js +0 -28
- package/dist/captureReadiness.js +0 -58
- package/dist/captureSignals.js +66 -3
- package/dist/cli.js +41 -18
- package/dist/codexHookTrust.js +61 -5
- package/dist/codexLimitScan.js +2 -109
- package/dist/codie.js +27 -40
- package/dist/codieBrandInstall.js +0 -18
- package/dist/codieLauncher.js +2 -70
- package/dist/codieRuntime.js +19 -23
- package/dist/codieRuntimeInstall.js +108 -23
- package/dist/codieStartup.js +0 -3
- package/dist/codieUsage.js +38 -41
- package/dist/commands/ask.js +0 -3
- package/dist/commands/capture.js +0 -2
- package/dist/commands/createTicket.js +0 -10
- package/dist/commands/doctor.js +41 -82
- package/dist/commands/inbox.js +0 -2
- package/dist/commands/library.js +0 -3
- package/dist/commands/pack.js +573 -0
- package/dist/commands/ping.js +0 -2
- package/dist/commands/pull.js +6 -10
- package/dist/commands/push.js +2 -12
- package/dist/commands/react.js +0 -2
- package/dist/commands/reverseTicket.js +0 -33
- package/dist/commands/search.js +0 -4
- package/dist/commands/send.js +0 -5
- package/dist/commands/share.js +0 -4
- package/dist/commands/shared.js +0 -35
- package/dist/commands/traces.js +280 -0
- package/dist/configDir.js +0 -10
- package/dist/connect.js +21 -77
- package/dist/connectFlow.js +0 -9
- package/dist/copilotHooks.js +395 -0
- package/dist/copilotInstallation.js +64 -0
- package/dist/cursorHooks.js +40 -17
- package/dist/cursorLifecycle.js +109 -0
- package/dist/detection.js +0 -30
- package/dist/harnessDirs.js +73 -0
- package/dist/hook.js +193 -316
- package/dist/inboxFormat.js +0 -24
- package/dist/launchContext.js +150 -0
- package/dist/launcher.js +140 -0
- package/dist/limitEvent.js +41 -35
- package/dist/limitEventReporter.js +1 -1
- package/dist/mcp.js +3 -77
- package/dist/nativeSteering.js +24 -0
- package/dist/packs/codie.js +182 -0
- package/dist/packs/harnesses.js +374 -0
- package/dist/packs/hookGate.js +256 -0
- package/dist/packs/install.js +285 -0
- package/dist/packs/manifest.js +126 -0
- package/dist/packs/paths.js +81 -0
- package/dist/packs/shim.js +214 -0
- package/dist/packs/store.js +155 -0
- package/dist/packs/sync.js +170 -0
- package/dist/prUrl.js +0 -5
- package/dist/repoResolver.js +0 -19
- package/dist/secret.js +0 -3
- package/dist/security.js +0 -20
- package/dist/securityDeepScan.js +1 -14
- package/dist/securityDoctor.js +0 -2
- package/dist/securityFeature.js +0 -1
- package/dist/securityInstall.js +6 -13
- package/dist/securityInventory.js +23 -13
- package/dist/securityPilot.js +0 -2
- package/dist/securityPolicy.js +0 -7
- package/dist/selfUpdate.js +331 -0
- package/dist/skillMarker.js +23 -0
- package/dist/subagents.js +135 -0
- package/dist/teamSkillContext.js +10 -0
- package/dist/transcriptModels.js +6 -8
- package/dist/upgradeNudge.js +0 -30
- package/dist/utils.js +286 -733
- package/dist/version.js +0 -10
- package/dist/versionCheck.js +0 -33
- package/package.json +7 -6
- package/dist/backup/cache.d.ts +0 -14
- package/dist/backup/match.d.ts +0 -2
- package/dist/backup/run.d.ts +0 -25
- package/dist/captureExclusions.d.ts +0 -30
- package/dist/captureLog.d.ts +0 -20
- package/dist/captureReadiness.d.ts +0 -65
- package/dist/captureSignals.d.ts +0 -19
- package/dist/cli.d.ts +0 -16
- package/dist/codexHookTrust.d.ts +0 -34
- package/dist/codexLimitScan.d.ts +0 -64
- package/dist/codie.d.ts +0 -2
- package/dist/codieBrandInstall.d.ts +0 -11
- package/dist/codieLauncher.d.ts +0 -86
- package/dist/codieRuntime.d.ts +0 -29
- package/dist/codieRuntimeInstall.d.ts +0 -28
- package/dist/codieStartup.d.ts +0 -26
- package/dist/codieUsage.d.ts +0 -57
- package/dist/commands/ask.d.ts +0 -1
- package/dist/commands/capture.d.ts +0 -14
- package/dist/commands/createTicket.d.ts +0 -27
- package/dist/commands/delete.d.ts +0 -1
- package/dist/commands/doctor.d.ts +0 -1
- package/dist/commands/inbox.d.ts +0 -3
- package/dist/commands/library.d.ts +0 -2
- package/dist/commands/note.d.ts +0 -1
- package/dist/commands/ping.d.ts +0 -1
- package/dist/commands/promote.d.ts +0 -1
- package/dist/commands/pull.d.ts +0 -2
- package/dist/commands/push.d.ts +0 -33
- package/dist/commands/react.d.ts +0 -2
- package/dist/commands/reverseTicket.d.ts +0 -2
- package/dist/commands/search.d.ts +0 -2
- package/dist/commands/security.d.ts +0 -1
- package/dist/commands/send.d.ts +0 -2
- package/dist/commands/share.d.ts +0 -2
- package/dist/commands/shared.d.ts +0 -64
- package/dist/configDir.d.ts +0 -1
- package/dist/connect.d.ts +0 -1
- package/dist/connectFlow.d.ts +0 -13
- package/dist/cursorHooks.d.ts +0 -23
- package/dist/detection.d.ts +0 -30
- package/dist/hook.d.ts +0 -6
- package/dist/inboxFormat.d.ts +0 -38
- package/dist/limitEvent.d.ts +0 -16
- package/dist/limitEventReporter.d.ts +0 -21
- package/dist/mcp.d.ts +0 -12
- package/dist/prUrl.d.ts +0 -9
- package/dist/repoResolver.d.ts +0 -17
- package/dist/secret.d.ts +0 -1
- package/dist/security.d.ts +0 -102
- package/dist/securityDeepScan.d.ts +0 -41
- package/dist/securityDoctor.d.ts +0 -32
- package/dist/securityFeature.d.ts +0 -5
- package/dist/securityInstall.d.ts +0 -63
- package/dist/securityInventory.d.ts +0 -54
- package/dist/securityPilot.d.ts +0 -19
- package/dist/securityPolicy.d.ts +0 -33
- package/dist/securitySession.d.ts +0 -6
- package/dist/transcriptModels.d.ts +0 -18
- package/dist/upgradeNudge.d.ts +0 -25
- package/dist/utils.d.ts +0 -346
- package/dist/version.d.ts +0 -1
- package/dist/versionCheck.d.ts +0 -68
package/dist/mcp.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
/**
|
|
4
|
-
* Codiedev MCP server.
|
|
5
|
-
*
|
|
6
|
-
* Exposes the Codiedev artifact-collaboration surface as Model Context
|
|
7
|
-
* Protocol tools so Claude Code / Codex / any MCP-capable agent can invoke
|
|
8
|
-
* them natively from natural language (e.g. "push the spec we just worked on").
|
|
9
|
-
*
|
|
10
|
-
* Reads the same ~/.codiedev/config.json the CLI uses. Install + wire up by
|
|
11
|
-
* running `npx codiedev connect`.
|
|
12
|
-
*/
|
|
13
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
4
|
if (k2 === undefined) k2 = k;
|
|
15
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -45,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
45
35
|
})();
|
|
46
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
37
|
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
38
|
+
const skillMarker_1 = require("./skillMarker");
|
|
48
39
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
49
40
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
50
41
|
const fs = __importStar(require("fs"));
|
|
@@ -53,8 +44,6 @@ const utils_1 = require("./utils");
|
|
|
53
44
|
const shared_1 = require("./commands/shared");
|
|
54
45
|
const inboxFormat_1 = require("./inboxFormat");
|
|
55
46
|
const PKG_NAME = "codiedev";
|
|
56
|
-
// Read version from the bundled package.json so the startup log + tool reports
|
|
57
|
-
// always reflect the actually-installed version, rather than a stale constant.
|
|
58
47
|
const PKG_VERSION = (() => {
|
|
59
48
|
try {
|
|
60
49
|
const pkgPath = path.resolve(__dirname, "..", "package.json");
|
|
@@ -64,10 +53,6 @@ const PKG_VERSION = (() => {
|
|
|
64
53
|
return "unknown";
|
|
65
54
|
}
|
|
66
55
|
})();
|
|
67
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
68
|
-
// Tool definitions — descriptions tuned so Claude/Codex resolve natural-language
|
|
69
|
-
// requests into the right tool without manual steering.
|
|
70
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
71
56
|
const TOOLS = [
|
|
72
57
|
{
|
|
73
58
|
name: "codiedev_push",
|
|
@@ -449,17 +434,10 @@ const TOOLS = [
|
|
|
449
434
|
},
|
|
450
435
|
},
|
|
451
436
|
];
|
|
452
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
453
|
-
// Server
|
|
454
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
455
437
|
const server = new index_js_1.Server({ name: PKG_NAME, version: PKG_VERSION }, { capabilities: { tools: {} } });
|
|
456
438
|
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
457
439
|
tools: TOOLS,
|
|
458
440
|
}));
|
|
459
|
-
/**
|
|
460
|
-
* Fire-and-forget telemetry — POST one event per tool invocation. Never blocks,
|
|
461
|
-
* never throws into the user-facing path. Drop silently on any failure.
|
|
462
|
-
*/
|
|
463
441
|
function emitTelemetry(config, event) {
|
|
464
442
|
if (!config)
|
|
465
443
|
return;
|
|
@@ -473,7 +451,6 @@ function emitTelemetry(config, event) {
|
|
|
473
451
|
mcpVersion: PKG_VERSION,
|
|
474
452
|
},
|
|
475
453
|
}).catch(() => {
|
|
476
|
-
// Swallow — telemetry should never affect the user's session.
|
|
477
454
|
});
|
|
478
455
|
}
|
|
479
456
|
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
@@ -577,7 +554,7 @@ async function handlePush(args, config) {
|
|
|
577
554
|
}
|
|
578
555
|
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/push", {
|
|
579
556
|
config,
|
|
580
|
-
body: { filename, markdown, type, kind, tags, force },
|
|
557
|
+
body: { filename, markdown: (0, skillMarker_1.stripSkillMarker)(markdown), type, kind, tags, force },
|
|
581
558
|
});
|
|
582
559
|
const tagSummary = res.tags && res.tags.length > 0 ? `, tags=[${res.tags.join(", ")}]` : "";
|
|
583
560
|
return {
|
|
@@ -598,10 +575,6 @@ async function handlePull(args, config) {
|
|
|
598
575
|
throw new Error("key required");
|
|
599
576
|
const res = await (0, shared_1.apiRequest)("GET", "/api/cli/pull", { config, query: { key, version } });
|
|
600
577
|
const a = res.artifact;
|
|
601
|
-
// Lead with the new-vocab kind. Legacy doc-shape (spec/decision/...) is
|
|
602
|
-
// surfaced as a tag list after, so callers still see it but it's no
|
|
603
|
-
// longer the primary label. Falls back to "doc" if the row pre-dates the
|
|
604
|
-
// kind field.
|
|
605
578
|
const kindLabel = a.kind ?? "doc";
|
|
606
579
|
const tagList = (a.tags ?? []).filter((t) => t).join(", ");
|
|
607
580
|
const tagSuffix = tagList ? ` · tags: ${tagList}` : "";
|
|
@@ -609,7 +582,7 @@ async function handlePull(args, config) {
|
|
|
609
582
|
`**${kindLabel}** · v${a.version ?? 1} · ${a.lifecycle ?? "draft"}${tagSuffix} · ` +
|
|
610
583
|
`updated ${(0, shared_1.timeAgo)(a.updatedAt ?? a.createdAt)}\n\n---\n\n`;
|
|
611
584
|
return {
|
|
612
|
-
content: [{ type: "text", text: header + a.markdown }],
|
|
585
|
+
content: [{ type: "text", text: header + (a.kind === "skill" || (!a.kind && (0, skillMarker_1.looksLikeSkill)(a.markdown)) ? (0, skillMarker_1.stampSkillMarker)(a.markdown, a._id) : a.markdown) }],
|
|
613
586
|
};
|
|
614
587
|
}
|
|
615
588
|
async function handleDelete(args, config) {
|
|
@@ -685,9 +658,6 @@ async function handleInbox(args, config) {
|
|
|
685
658
|
config,
|
|
686
659
|
query: { unreadOnly: unreadOnly ? "1" : undefined, limit },
|
|
687
660
|
});
|
|
688
|
-
// Shared with `codiedev inbox` so this agent-facing path can never drift
|
|
689
|
-
// back to pings-only. CLAUDE.md routes "any messages?" here, so a
|
|
690
|
-
// mentions-blind version reproduces the bug for agents.
|
|
691
661
|
const text = (0, inboxFormat_1.formatInbox)({
|
|
692
662
|
pings: res.pings,
|
|
693
663
|
mentions: res.mentions,
|
|
@@ -754,8 +724,6 @@ async function handleShareWith(args, config) {
|
|
|
754
724
|
],
|
|
755
725
|
};
|
|
756
726
|
}
|
|
757
|
-
// noop / duplicate path — surface where the existing grant came from so
|
|
758
|
-
// the user knows whether to expect it next time.
|
|
759
727
|
const e = res.existing;
|
|
760
728
|
let why = "";
|
|
761
729
|
if (e) {
|
|
@@ -908,9 +876,6 @@ async function handleGetLibrary(args, config) {
|
|
|
908
876
|
const v = a.version ? ` v${a.version}` : "";
|
|
909
877
|
const life = a.lifecycle ? ` · ${a.lifecycle}` : "";
|
|
910
878
|
const when = a.updatedAt ? ` · ${(0, shared_1.timeAgo)(a.updatedAt)}` : "";
|
|
911
|
-
// Lead with the canonical kind (doc | skill). Tags carry the legacy
|
|
912
|
-
// doc-shape (spec/decision/...) plus any author-added labels — surface
|
|
913
|
-
// them after the kind so the row is self-describing.
|
|
914
879
|
const k = a.kind ?? (a.type === "note" ? "doc" : "doc");
|
|
915
880
|
const tagList = (a.tags ?? []).length > 0 ? ` [${a.tags.join(", ")}]` : "";
|
|
916
881
|
lines.push(`[${k}]${tagList} ${loc}${a.key ?? a.title}${v}${life}${when}`);
|
|
@@ -941,7 +906,6 @@ async function handleReverseTicket(args, config) {
|
|
|
941
906
|
const explicitTitle = asStringOrUndefined(args.title);
|
|
942
907
|
const explicitBase = asStringOrUndefined(args.base);
|
|
943
908
|
const forcedKey = asStringOrUndefined(args.forcedArtifactKey);
|
|
944
|
-
// Helper that runs git from cwd with a hard-fail on error.
|
|
945
909
|
const { execSync } = await Promise.resolve().then(() => __importStar(require("child_process")));
|
|
946
910
|
const git = (cmd) => {
|
|
947
911
|
try {
|
|
@@ -956,14 +920,12 @@ async function handleReverseTicket(args, config) {
|
|
|
956
920
|
throw new Error(`git ${cmd} failed: ${err.message}`);
|
|
957
921
|
}
|
|
958
922
|
};
|
|
959
|
-
// Confirm we're in a git repo.
|
|
960
923
|
try {
|
|
961
924
|
git("rev-parse --is-inside-work-tree");
|
|
962
925
|
}
|
|
963
926
|
catch {
|
|
964
927
|
throw new Error("Not inside a git repository. Run this from a checked-out repo.");
|
|
965
928
|
}
|
|
966
|
-
// Resolve base ref — explicit, then origin/main, then origin/master.
|
|
967
929
|
const candidates = explicitBase
|
|
968
930
|
? [explicitBase]
|
|
969
931
|
: ["origin/main", "origin/master"];
|
|
@@ -975,7 +937,6 @@ async function handleReverseTicket(args, config) {
|
|
|
975
937
|
break;
|
|
976
938
|
}
|
|
977
939
|
catch {
|
|
978
|
-
// try next
|
|
979
940
|
}
|
|
980
941
|
}
|
|
981
942
|
if (!baseRef) {
|
|
@@ -988,10 +949,6 @@ async function handleReverseTicket(args, config) {
|
|
|
988
949
|
}
|
|
989
950
|
const baseSha = git(`merge-base HEAD ${baseRef}`);
|
|
990
951
|
const headSha = git("rev-parse HEAD");
|
|
991
|
-
// Filter generated/lockfile noise so the LLM's diff budget gets spent on
|
|
992
|
-
// real source. The --stat block (collected separately below) still includes
|
|
993
|
-
// every file untouched, so excluded files still appear in the ticket's
|
|
994
|
-
// "Other files touched" section if relevant.
|
|
995
952
|
const isNoise = (p) => /(^|\/)(node_modules|dist|build|\.next|\.turbo|coverage|out)\//.test(p) ||
|
|
996
953
|
/(^|\/)package-lock\.json$/.test(p) ||
|
|
997
954
|
/(^|\/)yarn\.lock$/.test(p) ||
|
|
@@ -1001,9 +958,6 @@ async function handleReverseTicket(args, config) {
|
|
|
1001
958
|
/(^|\/)Gemfile\.lock$/.test(p) ||
|
|
1002
959
|
/(^|\/)poetry\.lock$/.test(p) ||
|
|
1003
960
|
/(^|\/)go\.sum$/.test(p);
|
|
1004
|
-
// Helper: run a shell command tolerating non-zero exit codes (git diff
|
|
1005
|
-
// --no-index exits 1 when files differ, which is the normal case).
|
|
1006
|
-
// Reuses the execSync already imported above for the git() helper.
|
|
1007
961
|
const shellTolerant = (cmd) => {
|
|
1008
962
|
try {
|
|
1009
963
|
return execSync(`${cmd} || true`, {
|
|
@@ -1018,12 +972,6 @@ async function handleReverseTicket(args, config) {
|
|
|
1018
972
|
}
|
|
1019
973
|
};
|
|
1020
974
|
const shQuote = (s) => `'${s.replace(/'/g, "'\\''")}'`;
|
|
1021
|
-
// Capture all work the developer has done relative to the base ref:
|
|
1022
|
-
// - committed changes between base and HEAD
|
|
1023
|
-
// - uncommitted modifications to tracked files
|
|
1024
|
-
// - new untracked files (path listed + content via synthetic diff)
|
|
1025
|
-
// Matches the user's intent ("ticket my current changes") rather than the
|
|
1026
|
-
// narrower "only what's been committed" interpretation.
|
|
1027
975
|
const trackedRaw = git(`diff --name-only ${baseSha}`);
|
|
1028
976
|
const trackedFiles = trackedRaw ? trackedRaw.split("\n").filter(Boolean) : [];
|
|
1029
977
|
const untrackedRaw = safeGit(() => git("ls-files --others --exclude-standard"));
|
|
@@ -1034,9 +982,6 @@ async function handleReverseTicket(args, config) {
|
|
|
1034
982
|
if (filesChanged.length === 0) {
|
|
1035
983
|
throw new Error(`No changes detected between ${baseRef} and your working tree on ${branch}.`);
|
|
1036
984
|
}
|
|
1037
|
-
// --stat block: compact ground truth for "every file touched". Tracked
|
|
1038
|
-
// changes from `git diff --stat baseSha`; untracked files appended as
|
|
1039
|
-
// synthesized stat rows so the LLM sees them with line counts.
|
|
1040
985
|
let stat = "";
|
|
1041
986
|
try {
|
|
1042
987
|
const trackedStat = git(`diff --stat=200 ${baseSha}`);
|
|
@@ -1051,10 +996,7 @@ async function handleReverseTicket(args, config) {
|
|
|
1051
996
|
.slice(0, 8_000);
|
|
1052
997
|
}
|
|
1053
998
|
catch {
|
|
1054
|
-
// Best effort.
|
|
1055
999
|
}
|
|
1056
|
-
// Diff body: 40k cap, noise-filtered. Tracked changes via `git diff baseSha`,
|
|
1057
|
-
// plus synthetic add-only diffs for untracked files via `git diff --no-index`.
|
|
1058
1000
|
let diff = "";
|
|
1059
1001
|
try {
|
|
1060
1002
|
const sourceTracked = trackedFiles.filter((f) => !isNoise(f));
|
|
@@ -1069,9 +1011,7 @@ async function handleReverseTicket(args, config) {
|
|
|
1069
1011
|
.slice(0, 40_000);
|
|
1070
1012
|
}
|
|
1071
1013
|
catch {
|
|
1072
|
-
// Best effort.
|
|
1073
1014
|
}
|
|
1074
|
-
// Repo name from origin remote.
|
|
1075
1015
|
let repo;
|
|
1076
1016
|
try {
|
|
1077
1017
|
const remoteUrl = git("config --get remote.origin.url");
|
|
@@ -1087,7 +1027,6 @@ async function handleReverseTicket(args, config) {
|
|
|
1087
1027
|
const title = explicitTitle ?? safeGit(() => git("log -1 --format=%s")) ?? `WIP: ${branch}`;
|
|
1088
1028
|
const author = safeGit(() => git("config --get user.name"));
|
|
1089
1029
|
const authorEmail = safeGit(() => git("config --get user.email"));
|
|
1090
|
-
// Post to backend.
|
|
1091
1030
|
const res = await (0, shared_1.apiRequest)("POST", "/api/cli/reverseTicketFromBranch", {
|
|
1092
1031
|
config,
|
|
1093
1032
|
body: {
|
|
@@ -1120,9 +1059,6 @@ async function handleReverseTicket(args, config) {
|
|
|
1120
1059
|
],
|
|
1121
1060
|
};
|
|
1122
1061
|
}
|
|
1123
|
-
// Always return an absolute URL so MCP clients (Copilot Chat, Claude Code,
|
|
1124
|
-
// etc.) can render the link correctly without guessing a host. Default to
|
|
1125
|
-
// codiedev.com; allow override via CODIEDEV_PORTAL_URL for self-hosted.
|
|
1126
1062
|
const portalHost = (process.env.CODIEDEV_PORTAL_URL || "https://codiedev.com").replace(/\/$/, "");
|
|
1127
1063
|
const portalLink = res.portalUrl.startsWith("http")
|
|
1128
1064
|
? res.portalUrl
|
|
@@ -1145,7 +1081,6 @@ async function handleReverseTicket(args, config) {
|
|
|
1145
1081
|
],
|
|
1146
1082
|
};
|
|
1147
1083
|
}
|
|
1148
|
-
// Run a git invocation; return undefined instead of throwing.
|
|
1149
1084
|
function safeGit(fn) {
|
|
1150
1085
|
try {
|
|
1151
1086
|
return fn();
|
|
@@ -1154,9 +1089,6 @@ function safeGit(fn) {
|
|
|
1154
1089
|
return undefined;
|
|
1155
1090
|
}
|
|
1156
1091
|
}
|
|
1157
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1158
|
-
// Helpers
|
|
1159
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1160
1092
|
function asString(v) {
|
|
1161
1093
|
return typeof v === "string" ? v : "";
|
|
1162
1094
|
}
|
|
@@ -1174,20 +1106,14 @@ function asStringArrayOrUndefined(v) {
|
|
|
1174
1106
|
return undefined;
|
|
1175
1107
|
return v.filter((x) => typeof x === "string");
|
|
1176
1108
|
}
|
|
1177
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1178
|
-
// Main
|
|
1179
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1180
1109
|
async function main() {
|
|
1181
1110
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
1182
1111
|
await server.connect(transport);
|
|
1183
|
-
// stdio transport handles I/O until process exits.
|
|
1184
|
-
// Log to stderr only — stdout is reserved for MCP protocol.
|
|
1185
1112
|
process.stderr.write(`[codiedev-mcp] ready (v${PKG_VERSION}, config ${(0, utils_1.readConfig)() ? "present" : "missing"})\n`);
|
|
1186
1113
|
}
|
|
1187
1114
|
main().catch((err) => {
|
|
1188
1115
|
process.stderr.write(`[codiedev-mcp] fatal: ${err.message}\n`);
|
|
1189
1116
|
process.exit(1);
|
|
1190
1117
|
});
|
|
1191
|
-
// Avoid "Cannot find name 'path', 'fs'" since we imported them but may not use.
|
|
1192
1118
|
void path;
|
|
1193
1119
|
void fs;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseNativeSteering = parseNativeSteering;
|
|
4
|
+
function parseNativeSteering(content) {
|
|
5
|
+
const interrupts = new Set();
|
|
6
|
+
const abortedTurns = new Set();
|
|
7
|
+
const rejections = new Set();
|
|
8
|
+
for (const [index, line] of content.split("\n").entries()) {
|
|
9
|
+
try {
|
|
10
|
+
const event = JSON.parse(line);
|
|
11
|
+
const id = String(event.id ?? event.uuid ?? event.toolCallId ?? index);
|
|
12
|
+
if (event.type === "agent.interruption")
|
|
13
|
+
interrupts.add(id);
|
|
14
|
+
if (event.type === "turn_ended" && event.status === "aborted")
|
|
15
|
+
abortedTurns.add(id);
|
|
16
|
+
if (event.type === "agent.rejection")
|
|
17
|
+
rejections.add(id);
|
|
18
|
+
if (event.type === "tool_result" && event.error?.code === "user_denied")
|
|
19
|
+
rejections.add(id);
|
|
20
|
+
}
|
|
21
|
+
catch { }
|
|
22
|
+
}
|
|
23
|
+
return { interrupts: Math.max(interrupts.size, abortedTurns.size), rejections: rejections.size };
|
|
24
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
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.levelToModel = levelToModel;
|
|
37
|
+
exports.mapAgentModel = mapAgentModel;
|
|
38
|
+
exports.codiePackConfig = codiePackConfig;
|
|
39
|
+
exports.mergeCodiePackConfig = mergeCodiePackConfig;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const url_1 = require("url");
|
|
43
|
+
const manifest_1 = require("./manifest");
|
|
44
|
+
const paths_1 = require("./paths");
|
|
45
|
+
const shim_1 = require("./shim");
|
|
46
|
+
const store_1 = require("./store");
|
|
47
|
+
const LEVEL_LABEL = { opus: "Strongest", sonnet: "Balanced", haiku: "Fastest" };
|
|
48
|
+
function newestFirst(a, b) {
|
|
49
|
+
return b.id.localeCompare(a.id, undefined, { numeric: true });
|
|
50
|
+
}
|
|
51
|
+
function levelToModel(level, catalog) {
|
|
52
|
+
const key = level.toLowerCase();
|
|
53
|
+
const tierNames = {
|
|
54
|
+
opus: ["strongest", "opus", "high", "max"],
|
|
55
|
+
sonnet: ["balanced", "sonnet", "medium", "default"],
|
|
56
|
+
haiku: ["fastest", "haiku", "low", "fast"],
|
|
57
|
+
};
|
|
58
|
+
const tiered = catalog.filter((m) => [m.tier, m.level].some((t) => typeof t === "string" && tierNames[key].includes(t.toLowerCase())));
|
|
59
|
+
if (tiered.length)
|
|
60
|
+
return { model: [...tiered].sort(newestFirst)[0].id, how: "tier" };
|
|
61
|
+
const family = catalog.filter((m) => new RegExp(`(^|[^a-z])${key}([^a-z]|$)`, "i").test(m.id));
|
|
62
|
+
if (family.length)
|
|
63
|
+
return { model: [...family].sort(newestFirst)[0].id, how: "family" };
|
|
64
|
+
const priced = catalog
|
|
65
|
+
.filter((m) => m.cost && Number.isFinite(m.cost.input) && Number.isFinite(m.cost.output))
|
|
66
|
+
.sort((a, b) => a.cost.input + a.cost.output - (b.cost.input + b.cost.output) || a.id.localeCompare(b.id));
|
|
67
|
+
if (priced.length) {
|
|
68
|
+
const index = key === "haiku" ? 0 : key === "opus" ? priced.length - 1 : Math.floor((priced.length - 1) / 2);
|
|
69
|
+
return { model: priced[index].id, how: "price" };
|
|
70
|
+
}
|
|
71
|
+
return { how: "none" };
|
|
72
|
+
}
|
|
73
|
+
function mapAgentModel(value, approved, catalog) {
|
|
74
|
+
const model = (value ?? "").trim();
|
|
75
|
+
if (!model || model === "inherit")
|
|
76
|
+
return {};
|
|
77
|
+
const key = model.toLowerCase();
|
|
78
|
+
if (LEVEL_LABEL[key]) {
|
|
79
|
+
const usable = (catalog ?? []).filter((m) => !approved || approved.has(m.id.replace(/^codiedev\//, "")));
|
|
80
|
+
const picked = levelToModel(key, usable);
|
|
81
|
+
if (!picked.model) {
|
|
82
|
+
return { note: `level ${LEVEL_LABEL[key]} (${model}): no matching approved model, using the governed default` };
|
|
83
|
+
}
|
|
84
|
+
return { model: picked.model, note: `level ${LEVEL_LABEL[key]} (${model}) → ${picked.model} (by ${picked.how})` };
|
|
85
|
+
}
|
|
86
|
+
if (!model.includes("/"))
|
|
87
|
+
return { note: `unknown level "${model}", using the governed default` };
|
|
88
|
+
if (approved) {
|
|
89
|
+
const bare = model.replace(/^codiedev\//, "");
|
|
90
|
+
if (!approved.has(bare))
|
|
91
|
+
return { note: `dropped model "${model}" (not approved for this Codiedev account)` };
|
|
92
|
+
}
|
|
93
|
+
return { model };
|
|
94
|
+
}
|
|
95
|
+
function codiePackConfig(root, options = {}) {
|
|
96
|
+
const registry = (0, store_1.readRegistry)(root);
|
|
97
|
+
const result = { skillPaths: [], agents: {}, plugins: [], notes: [] };
|
|
98
|
+
for (const [slug, entry] of Object.entries(registry.packs).sort(([a], [b]) => a.localeCompare(b))) {
|
|
99
|
+
if (!(0, manifest_1.isSafeSegment)(slug) || !Array.isArray(entry.harnesses) || !entry.harnesses.includes("codie"))
|
|
100
|
+
continue;
|
|
101
|
+
const dir = typeof entry.dir === "string" ? entry.dir : "";
|
|
102
|
+
if (!dir || !fs.existsSync(dir))
|
|
103
|
+
continue;
|
|
104
|
+
try {
|
|
105
|
+
const hooks = JSON.parse(fs.readFileSync(path.join(dir, "hooks", "hooks.json"), "utf8"))?.hooks;
|
|
106
|
+
const skipped = (0, shim_1.unsupportedShimEvents)([{ slug, root: dir, hooks: hooks ?? {} }]).get(slug);
|
|
107
|
+
if (skipped?.length)
|
|
108
|
+
result.notes.push(`pack ${slug}: hooks Codie can't run were skipped: ${skipped.join(", ")}`);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
}
|
|
112
|
+
const skills = path.join(dir, "skills");
|
|
113
|
+
if (fs.existsSync(skills))
|
|
114
|
+
result.skillPaths.push(skills);
|
|
115
|
+
const agentsDir = path.join(dir, "agents");
|
|
116
|
+
let agentFiles = [];
|
|
117
|
+
try {
|
|
118
|
+
agentFiles = fs.readdirSync(agentsDir).filter((f) => f.endsWith(".md")).sort();
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
agentFiles = [];
|
|
122
|
+
}
|
|
123
|
+
for (const file of agentFiles) {
|
|
124
|
+
const fallbackName = file.slice(0, -3);
|
|
125
|
+
let content;
|
|
126
|
+
try {
|
|
127
|
+
content = fs.readFileSync(path.join(agentsDir, file), "utf8");
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const { data, body } = (0, manifest_1.parseFrontmatter)(content);
|
|
133
|
+
const name = (0, manifest_1.isSafeSegment)(data.name) ? data.name : fallbackName;
|
|
134
|
+
if (result.agents[name]) {
|
|
135
|
+
result.notes.push(`agent "${name}" from pack ${slug} skipped (already defined by another pack)`);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const mapped = mapAgentModel(data.model, options.approvedModels, options.catalog);
|
|
139
|
+
if (mapped.note)
|
|
140
|
+
result.notes.push(`agent "${name}" (${slug}): ${mapped.note}`);
|
|
141
|
+
result.agents[name] = {
|
|
142
|
+
description: data.description || `${name} (from starter pack ${slug})`,
|
|
143
|
+
prompt: body.trim(),
|
|
144
|
+
mode: "subagent",
|
|
145
|
+
...(mapped.model ? { model: mapped.model } : {}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const shim = (0, paths_1.shimPath)(root);
|
|
150
|
+
const anyCodie = Object.values(registry.packs).some((e) => Array.isArray(e.harnesses) && e.harnesses.includes("codie"));
|
|
151
|
+
if (anyCodie && fs.existsSync(shim))
|
|
152
|
+
result.plugins.push((0, url_1.pathToFileURL)(shim).href);
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
function mergeCodiePackConfig(existing, packs) {
|
|
156
|
+
const next = { ...existing };
|
|
157
|
+
if (packs.skillPaths.length) {
|
|
158
|
+
const current = existing.skills;
|
|
159
|
+
const base = Array.isArray(current)
|
|
160
|
+
? { paths: current.filter((p) => typeof p === "string") }
|
|
161
|
+
: current && typeof current === "object"
|
|
162
|
+
? { ...current }
|
|
163
|
+
: {};
|
|
164
|
+
const paths = Array.isArray(base.paths) ? [...base.paths] : [];
|
|
165
|
+
for (const p of packs.skillPaths)
|
|
166
|
+
if (!paths.includes(p))
|
|
167
|
+
paths.push(p);
|
|
168
|
+
next.skills = { ...base, paths };
|
|
169
|
+
}
|
|
170
|
+
if (Object.keys(packs.agents).length) {
|
|
171
|
+
const current = existing.agent && typeof existing.agent === "object" ? existing.agent : {};
|
|
172
|
+
next.agent = { ...packs.agents, ...current };
|
|
173
|
+
}
|
|
174
|
+
if (packs.plugins.length) {
|
|
175
|
+
const current = Array.isArray(existing.plugin) ? [...existing.plugin] : [];
|
|
176
|
+
for (const p of packs.plugins)
|
|
177
|
+
if (!current.includes(p))
|
|
178
|
+
current.push(p);
|
|
179
|
+
next.plugin = current;
|
|
180
|
+
}
|
|
181
|
+
return next;
|
|
182
|
+
}
|