cleargate 0.7.0 → 0.8.1
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/MANIFEST.json +2 -2
- package/dist/cli.cjs +256 -29
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +252 -29
- package/dist/cli.js.map +1 -1
- package/dist/templates/cleargate-planning/MANIFEST.json +2 -2
- package/package.json +1 -1
- package/templates/cleargate-planning/MANIFEST.json +2 -2
package/dist/MANIFEST.json
CHANGED
package/dist/cli.cjs
CHANGED
|
@@ -627,7 +627,7 @@ var import_commander = require("commander");
|
|
|
627
627
|
// package.json
|
|
628
628
|
var package_default = {
|
|
629
629
|
name: "cleargate",
|
|
630
|
-
version: "0.
|
|
630
|
+
version: "0.8.1",
|
|
631
631
|
private: false,
|
|
632
632
|
type: "module",
|
|
633
633
|
description: "Planning framework for Claude Code agents \u2014 sprint/epic/story protocol, four-agent loop (architect/developer/qa/reporter), Karpathy-style awareness wiki.",
|
|
@@ -2052,9 +2052,16 @@ function mergeMcpJson(existing, entry) {
|
|
|
2052
2052
|
next.mcpServers = servers;
|
|
2053
2053
|
return JSON.stringify(next, null, 2) + "\n";
|
|
2054
2054
|
}
|
|
2055
|
-
function
|
|
2055
|
+
function buildStdioEntry(pinVersion) {
|
|
2056
|
+
return {
|
|
2057
|
+
command: "npx",
|
|
2058
|
+
args: ["-y", `cleargate@${pinVersion}`, "mcp", "serve"]
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
var STDIO_ENTRY_DEFAULT = buildStdioEntry("latest");
|
|
2062
|
+
function injectMcpJson(cwd, pinVersion = "latest") {
|
|
2056
2063
|
const dst = path8.join(cwd, ".mcp.json");
|
|
2057
|
-
const entry =
|
|
2064
|
+
const entry = buildStdioEntry(pinVersion);
|
|
2058
2065
|
let existing = null;
|
|
2059
2066
|
let existingRaw = null;
|
|
2060
2067
|
if (fs8.existsSync(dst)) {
|
|
@@ -3162,7 +3169,7 @@ async function initHandler(opts = {}) {
|
|
|
3162
3169
|
`);
|
|
3163
3170
|
}
|
|
3164
3171
|
try {
|
|
3165
|
-
const action = injectMcpJson(cwd, "
|
|
3172
|
+
const action = injectMcpJson(cwd, pinVersion ?? "latest");
|
|
3166
3173
|
if (action === "created") {
|
|
3167
3174
|
stdout(
|
|
3168
3175
|
`[cleargate init] Created .mcp.json (cleargate MCP server registered) \u2014 restart Claude Code to load it.
|
|
@@ -8016,7 +8023,7 @@ function extractFrontmatterBlock(raw) {
|
|
|
8016
8023
|
// src/lib/intake.ts
|
|
8017
8024
|
async function runIntakeBranch(opts) {
|
|
8018
8025
|
const {
|
|
8019
|
-
mcp,
|
|
8026
|
+
mcp: mcp2,
|
|
8020
8027
|
identity,
|
|
8021
8028
|
sprintRoot,
|
|
8022
8029
|
projectRoot,
|
|
@@ -8027,7 +8034,7 @@ async function runIntakeBranch(opts) {
|
|
|
8027
8034
|
const pendingSyncDir = path39.join(projectRoot, ".cleargate", "delivery", "pending-sync");
|
|
8028
8035
|
let remoteItems = [];
|
|
8029
8036
|
try {
|
|
8030
|
-
remoteItems = await
|
|
8037
|
+
remoteItems = await mcp2.call(
|
|
8031
8038
|
"cleargate_detect_new_items",
|
|
8032
8039
|
{ label: labelFilter }
|
|
8033
8040
|
);
|
|
@@ -8389,9 +8396,9 @@ async function syncCheckHandler(opts = {}) {
|
|
|
8389
8396
|
}
|
|
8390
8397
|
} catch {
|
|
8391
8398
|
}
|
|
8392
|
-
let
|
|
8399
|
+
let mcp2;
|
|
8393
8400
|
if (opts.mcp) {
|
|
8394
|
-
|
|
8401
|
+
mcp2 = opts.mcp;
|
|
8395
8402
|
} else {
|
|
8396
8403
|
let baseUrl = env["CLEARGATE_MCP_URL"];
|
|
8397
8404
|
if (!baseUrl || !baseUrl.trim()) {
|
|
@@ -8420,10 +8427,10 @@ async function syncCheckHandler(opts = {}) {
|
|
|
8420
8427
|
await emitError("adapter-not-configured", nowIso);
|
|
8421
8428
|
return;
|
|
8422
8429
|
}
|
|
8423
|
-
|
|
8430
|
+
mcp2 = createMcpClient({ baseUrl: baseUrl.trim(), token: accessToken });
|
|
8424
8431
|
}
|
|
8425
8432
|
try {
|
|
8426
|
-
const adapterInfo = await
|
|
8433
|
+
const adapterInfo = await mcp2.adapterInfo();
|
|
8427
8434
|
if (!adapterInfo.configured || adapterInfo.name === "no-adapter-configured") {
|
|
8428
8435
|
await emitError("adapter-not-configured", nowIso);
|
|
8429
8436
|
return;
|
|
@@ -8432,7 +8439,7 @@ async function syncCheckHandler(opts = {}) {
|
|
|
8432
8439
|
}
|
|
8433
8440
|
let refs;
|
|
8434
8441
|
try {
|
|
8435
|
-
refs = await
|
|
8442
|
+
refs = await mcp2.call("cleargate_list_remote_updates", { since });
|
|
8436
8443
|
} catch (err) {
|
|
8437
8444
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8438
8445
|
await emitError(msg, nowIso);
|
|
@@ -8452,9 +8459,9 @@ async function syncHandler(opts = {}) {
|
|
|
8452
8459
|
const identity = resolveIdentity(projectRoot);
|
|
8453
8460
|
const sprintRoot = resolveActiveSprintDir(projectRoot);
|
|
8454
8461
|
const sprintId = path43.basename(sprintRoot);
|
|
8455
|
-
let
|
|
8462
|
+
let mcp2;
|
|
8456
8463
|
if (opts.mcp) {
|
|
8457
|
-
|
|
8464
|
+
mcp2 = opts.mcp;
|
|
8458
8465
|
} else {
|
|
8459
8466
|
let baseUrl = env["CLEARGATE_MCP_URL"];
|
|
8460
8467
|
if (!baseUrl || !baseUrl.trim()) {
|
|
@@ -8497,11 +8504,11 @@ async function syncHandler(opts = {}) {
|
|
|
8497
8504
|
exit(2);
|
|
8498
8505
|
return;
|
|
8499
8506
|
}
|
|
8500
|
-
|
|
8507
|
+
mcp2 = createMcpClient({ baseUrl: baseUrl.trim(), token: accessToken });
|
|
8501
8508
|
}
|
|
8502
8509
|
let adapterInfo;
|
|
8503
8510
|
try {
|
|
8504
|
-
adapterInfo = await
|
|
8511
|
+
adapterInfo = await mcp2.adapterInfo();
|
|
8505
8512
|
} catch {
|
|
8506
8513
|
adapterInfo = { configured: true, name: "unknown" };
|
|
8507
8514
|
}
|
|
@@ -8522,13 +8529,13 @@ async function syncHandler(opts = {}) {
|
|
|
8522
8529
|
}
|
|
8523
8530
|
} catch {
|
|
8524
8531
|
}
|
|
8525
|
-
const remoteRefs = await
|
|
8532
|
+
const remoteRefs = await mcp2.call(
|
|
8526
8533
|
"cleargate_list_remote_updates",
|
|
8527
8534
|
{ since: lastRemoteSync }
|
|
8528
8535
|
);
|
|
8529
8536
|
const pulled = [];
|
|
8530
8537
|
for (const ref of remoteRefs) {
|
|
8531
|
-
const item = await
|
|
8538
|
+
const item = await mcp2.call(
|
|
8532
8539
|
"cleargate_pull_item",
|
|
8533
8540
|
{ remote_id: ref.remote_id }
|
|
8534
8541
|
);
|
|
@@ -8540,7 +8547,7 @@ async function syncHandler(opts = {}) {
|
|
|
8540
8547
|
let intakeResult = { created: 0, items: [] };
|
|
8541
8548
|
try {
|
|
8542
8549
|
intakeResult = await runIntakeBranch({
|
|
8543
|
-
mcp,
|
|
8550
|
+
mcp: mcp2,
|
|
8544
8551
|
identity,
|
|
8545
8552
|
sprintRoot,
|
|
8546
8553
|
projectRoot,
|
|
@@ -8566,7 +8573,7 @@ async function syncHandler(opts = {}) {
|
|
|
8566
8573
|
const activeSet = await resolveActiveItems(projectRoot, localRefs, nowFn);
|
|
8567
8574
|
for (const remoteId of activeSet) {
|
|
8568
8575
|
try {
|
|
8569
|
-
const comments = await
|
|
8576
|
+
const comments = await mcp2.call(
|
|
8570
8577
|
"cleargate_pull_comments",
|
|
8571
8578
|
{ remote_id: remoteId }
|
|
8572
8579
|
);
|
|
@@ -8720,7 +8727,7 @@ async function syncHandler(opts = {}) {
|
|
|
8720
8727
|
await appendSyncLog(sprintRoot, entry);
|
|
8721
8728
|
}
|
|
8722
8729
|
for (const { localPath, fm, body, itemId } of pushQueue) {
|
|
8723
|
-
await
|
|
8730
|
+
await mcp2.call("push_item", {
|
|
8724
8731
|
cleargate_id: itemId,
|
|
8725
8732
|
type: typeof fm["story_id"] === "string" ? "story" : typeof fm["epic_id"] === "string" ? "epic" : typeof fm["proposal_id"] === "string" ? "proposal" : "story",
|
|
8726
8733
|
payload: fm
|
|
@@ -8853,9 +8860,9 @@ async function pullHandler(idOrRemoteId, opts = {}) {
|
|
|
8853
8860
|
const nowFn = opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
8854
8861
|
const identity = resolveIdentity(projectRoot);
|
|
8855
8862
|
const sprintRoot = resolveActiveSprintDir(projectRoot);
|
|
8856
|
-
let
|
|
8863
|
+
let mcp2;
|
|
8857
8864
|
if (opts.mcp) {
|
|
8858
|
-
|
|
8865
|
+
mcp2 = opts.mcp;
|
|
8859
8866
|
} else {
|
|
8860
8867
|
let baseUrl = env["CLEARGATE_MCP_URL"];
|
|
8861
8868
|
if (!baseUrl || !baseUrl.trim()) {
|
|
@@ -8890,7 +8897,7 @@ async function pullHandler(idOrRemoteId, opts = {}) {
|
|
|
8890
8897
|
exit(2);
|
|
8891
8898
|
return;
|
|
8892
8899
|
}
|
|
8893
|
-
|
|
8900
|
+
mcp2 = createMcpClient({ baseUrl: baseUrl.trim(), token: accessToken });
|
|
8894
8901
|
}
|
|
8895
8902
|
const remoteId = await resolveRemoteId(idOrRemoteId, projectRoot);
|
|
8896
8903
|
if (!remoteId) {
|
|
@@ -8899,7 +8906,7 @@ async function pullHandler(idOrRemoteId, opts = {}) {
|
|
|
8899
8906
|
exit(1);
|
|
8900
8907
|
return;
|
|
8901
8908
|
}
|
|
8902
|
-
const remoteItem = await
|
|
8909
|
+
const remoteItem = await mcp2.call("cleargate_pull_item", { remote_id: remoteId });
|
|
8903
8910
|
if (!remoteItem) {
|
|
8904
8911
|
stderr(`Error: item ${remoteId} not found on MCP server.
|
|
8905
8912
|
`);
|
|
@@ -8959,7 +8966,7 @@ async function pullHandler(idOrRemoteId, opts = {}) {
|
|
|
8959
8966
|
stdout(`pull: ${remoteId} applied to ${path44.relative(projectRoot, localPath)}
|
|
8960
8967
|
`);
|
|
8961
8968
|
if (opts.comments) {
|
|
8962
|
-
const comments = await
|
|
8969
|
+
const comments = await mcp2.call(
|
|
8963
8970
|
"cleargate_pull_comments",
|
|
8964
8971
|
{ remote_id: remoteId }
|
|
8965
8972
|
);
|
|
@@ -9157,10 +9164,10 @@ async function handlePush(filePath, ctx) {
|
|
|
9157
9164
|
if (h1) payloadForPush["title"] = h1;
|
|
9158
9165
|
}
|
|
9159
9166
|
payloadForPush["body"] = body;
|
|
9160
|
-
const
|
|
9167
|
+
const mcp2 = await resolveMcp();
|
|
9161
9168
|
let result;
|
|
9162
9169
|
try {
|
|
9163
|
-
result = await
|
|
9170
|
+
result = await mcp2.call("push_item", {
|
|
9164
9171
|
cleargate_id: itemId,
|
|
9165
9172
|
type,
|
|
9166
9173
|
payload: payloadForPush,
|
|
@@ -9212,9 +9219,9 @@ async function handleRevert(idOrRemoteId, ctx) {
|
|
|
9212
9219
|
exit(1);
|
|
9213
9220
|
return;
|
|
9214
9221
|
}
|
|
9215
|
-
const
|
|
9222
|
+
const mcp2 = await resolveMcp();
|
|
9216
9223
|
try {
|
|
9217
|
-
await
|
|
9224
|
+
await mcp2.call("sync_status", {
|
|
9218
9225
|
cleargate_id: itemId,
|
|
9219
9226
|
new_status: "archived-without-shipping"
|
|
9220
9227
|
});
|
|
@@ -9653,6 +9660,218 @@ function hotfixNewHandler(opts, cli) {
|
|
|
9653
9660
|
return exitFn(0);
|
|
9654
9661
|
}
|
|
9655
9662
|
|
|
9663
|
+
// src/commands/mcp-serve.ts
|
|
9664
|
+
init_cjs_shims();
|
|
9665
|
+
var readline5 = __toESM(require("readline"), 1);
|
|
9666
|
+
init_config();
|
|
9667
|
+
init_factory();
|
|
9668
|
+
|
|
9669
|
+
// src/auth/refresh.ts
|
|
9670
|
+
init_cjs_shims();
|
|
9671
|
+
async function refreshAccessToken(baseUrl, refreshToken, deps = {}) {
|
|
9672
|
+
const fetchFn = deps.fetch ?? globalThis.fetch;
|
|
9673
|
+
const res = await fetchFn(`${baseUrl}/auth/refresh`, {
|
|
9674
|
+
method: "POST",
|
|
9675
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
9676
|
+
body: JSON.stringify({ refresh_token: refreshToken })
|
|
9677
|
+
});
|
|
9678
|
+
if (!res.ok) {
|
|
9679
|
+
const body = await res.json().catch(() => ({}));
|
|
9680
|
+
throw new RefreshError(res.status, body.error ?? "unknown_error");
|
|
9681
|
+
}
|
|
9682
|
+
const json = await res.json();
|
|
9683
|
+
if (typeof json.access_token !== "string" || typeof json.refresh_token !== "string" || typeof json.expires_in !== "number") {
|
|
9684
|
+
throw new RefreshError(500, "malformed_response");
|
|
9685
|
+
}
|
|
9686
|
+
return json;
|
|
9687
|
+
}
|
|
9688
|
+
var RefreshError = class extends Error {
|
|
9689
|
+
constructor(status, code) {
|
|
9690
|
+
super(`refresh failed: ${status} ${code}`);
|
|
9691
|
+
this.status = status;
|
|
9692
|
+
this.code = code;
|
|
9693
|
+
this.name = "RefreshError";
|
|
9694
|
+
}
|
|
9695
|
+
status;
|
|
9696
|
+
code;
|
|
9697
|
+
};
|
|
9698
|
+
var AuthFetcher = class {
|
|
9699
|
+
constructor(opts) {
|
|
9700
|
+
this.opts = opts;
|
|
9701
|
+
}
|
|
9702
|
+
opts;
|
|
9703
|
+
accessToken = null;
|
|
9704
|
+
accessExpiresAt = 0;
|
|
9705
|
+
inflight = null;
|
|
9706
|
+
/** Returns a fresh access token, refreshing if needed. */
|
|
9707
|
+
async getAccessToken() {
|
|
9708
|
+
const now = (this.opts.now ?? (() => Date.now()))();
|
|
9709
|
+
const skewMs = (this.opts.skewSeconds ?? 60) * 1e3;
|
|
9710
|
+
if (this.accessToken && now < this.accessExpiresAt - skewMs) {
|
|
9711
|
+
return this.accessToken;
|
|
9712
|
+
}
|
|
9713
|
+
if (this.inflight) return this.inflight;
|
|
9714
|
+
this.inflight = this.refreshNow().finally(() => {
|
|
9715
|
+
this.inflight = null;
|
|
9716
|
+
});
|
|
9717
|
+
return this.inflight;
|
|
9718
|
+
}
|
|
9719
|
+
/** Force the next call to refresh. Used after a 401. */
|
|
9720
|
+
invalidate() {
|
|
9721
|
+
this.accessToken = null;
|
|
9722
|
+
this.accessExpiresAt = 0;
|
|
9723
|
+
}
|
|
9724
|
+
async refreshNow() {
|
|
9725
|
+
const stored = await this.opts.loadRefresh();
|
|
9726
|
+
if (!stored) {
|
|
9727
|
+
throw new RefreshError(401, "no_refresh_token");
|
|
9728
|
+
}
|
|
9729
|
+
const exchanged = await refreshAccessToken(this.opts.baseUrl, stored, {
|
|
9730
|
+
...this.opts.fetch ? { fetch: this.opts.fetch } : {},
|
|
9731
|
+
...this.opts.now ? { now: this.opts.now } : {}
|
|
9732
|
+
});
|
|
9733
|
+
await this.opts.saveRefresh(exchanged.refresh_token);
|
|
9734
|
+
const now = (this.opts.now ?? (() => Date.now()))();
|
|
9735
|
+
this.accessToken = exchanged.access_token;
|
|
9736
|
+
this.accessExpiresAt = now + exchanged.expires_in * 1e3;
|
|
9737
|
+
return exchanged.access_token;
|
|
9738
|
+
}
|
|
9739
|
+
};
|
|
9740
|
+
|
|
9741
|
+
// src/commands/mcp-serve.ts
|
|
9742
|
+
var DEFAULT_BASE_URL = "https://cleargate-mcp.soula.ge";
|
|
9743
|
+
async function mcpServeHandler(opts) {
|
|
9744
|
+
const fetchFn = opts.fetch ?? globalThis.fetch;
|
|
9745
|
+
const stdout = opts.stdout ?? ((s) => process.stdout.write(s));
|
|
9746
|
+
const stderr = opts.stderr ?? ((s) => process.stderr.write(s));
|
|
9747
|
+
const exit = opts.exit ?? ((c) => process.exit(c));
|
|
9748
|
+
const cfg = loadConfig({
|
|
9749
|
+
flags: { profile: opts.profile, mcpUrl: opts.mcpUrlFlag }
|
|
9750
|
+
});
|
|
9751
|
+
const baseUrl = cfg.mcpUrl ?? DEFAULT_BASE_URL;
|
|
9752
|
+
const store = await (opts.createStore ?? createTokenStore)({
|
|
9753
|
+
...opts.keychainService !== void 0 ? { keychainService: opts.keychainService } : {},
|
|
9754
|
+
...opts.forceBackend !== void 0 ? { forceBackend: opts.forceBackend } : {}
|
|
9755
|
+
});
|
|
9756
|
+
const fetcher = new AuthFetcher({
|
|
9757
|
+
baseUrl,
|
|
9758
|
+
loadRefresh: () => store.load(opts.profile),
|
|
9759
|
+
saveRefresh: (t) => store.save(opts.profile, t),
|
|
9760
|
+
...opts.fetch !== void 0 ? { fetch: opts.fetch } : {},
|
|
9761
|
+
...opts.now !== void 0 ? { now: opts.now } : {}
|
|
9762
|
+
});
|
|
9763
|
+
try {
|
|
9764
|
+
await fetcher.getAccessToken();
|
|
9765
|
+
} catch (err) {
|
|
9766
|
+
if (err instanceof RefreshError) {
|
|
9767
|
+
stderr(
|
|
9768
|
+
`cleargate mcp serve: refresh failed (${err.status} ${err.code}). Run \`cleargate join <invite-url>\` to re-authenticate.
|
|
9769
|
+
`
|
|
9770
|
+
);
|
|
9771
|
+
} else {
|
|
9772
|
+
stderr(
|
|
9773
|
+
`cleargate mcp serve: ${err instanceof Error ? err.message : String(err)}
|
|
9774
|
+
`
|
|
9775
|
+
);
|
|
9776
|
+
}
|
|
9777
|
+
return exit(1);
|
|
9778
|
+
}
|
|
9779
|
+
const inputStream = opts.stdin ?? process.stdin;
|
|
9780
|
+
const rl = readline5.createInterface({
|
|
9781
|
+
input: inputStream,
|
|
9782
|
+
output: void 0,
|
|
9783
|
+
terminal: false
|
|
9784
|
+
});
|
|
9785
|
+
for await (const line of rl) {
|
|
9786
|
+
if (!line.trim()) continue;
|
|
9787
|
+
try {
|
|
9788
|
+
await proxyOne(line, baseUrl, fetcher, fetchFn, stdout, stderr);
|
|
9789
|
+
} catch (err) {
|
|
9790
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
9791
|
+
stderr(`cleargate mcp serve: proxy error: ${errMsg}
|
|
9792
|
+
`);
|
|
9793
|
+
const id = extractId(line);
|
|
9794
|
+
if (id !== void 0) {
|
|
9795
|
+
stdout(
|
|
9796
|
+
JSON.stringify({
|
|
9797
|
+
jsonrpc: "2.0",
|
|
9798
|
+
id,
|
|
9799
|
+
error: { code: -32603, message: `proxy error: ${errMsg}` }
|
|
9800
|
+
}) + "\n"
|
|
9801
|
+
);
|
|
9802
|
+
}
|
|
9803
|
+
}
|
|
9804
|
+
}
|
|
9805
|
+
}
|
|
9806
|
+
async function proxyOne(line, baseUrl, fetcher, fetchFn, stdout, stderr) {
|
|
9807
|
+
let parsed;
|
|
9808
|
+
try {
|
|
9809
|
+
parsed = JSON.parse(line);
|
|
9810
|
+
} catch {
|
|
9811
|
+
stderr(`cleargate mcp serve: ignoring non-JSON line: ${line.slice(0, 80)}
|
|
9812
|
+
`);
|
|
9813
|
+
return;
|
|
9814
|
+
}
|
|
9815
|
+
const isNotification = !("id" in parsed) || parsed.id === void 0 || parsed.id === null;
|
|
9816
|
+
let access = await fetcher.getAccessToken();
|
|
9817
|
+
let res = await postFrame(baseUrl, line, access, fetchFn);
|
|
9818
|
+
if (res.status === 401) {
|
|
9819
|
+
fetcher.invalidate();
|
|
9820
|
+
access = await fetcher.getAccessToken();
|
|
9821
|
+
res = await postFrame(baseUrl, line, access, fetchFn);
|
|
9822
|
+
}
|
|
9823
|
+
if (isNotification) {
|
|
9824
|
+
await res.arrayBuffer().catch(() => void 0);
|
|
9825
|
+
return;
|
|
9826
|
+
}
|
|
9827
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
9828
|
+
if (ct.includes("text/event-stream")) {
|
|
9829
|
+
await streamSse(res, stdout);
|
|
9830
|
+
} else {
|
|
9831
|
+
const text = await res.text();
|
|
9832
|
+
if (text.length > 0) stdout(text + "\n");
|
|
9833
|
+
}
|
|
9834
|
+
}
|
|
9835
|
+
async function postFrame(baseUrl, body, accessToken, fetchFn) {
|
|
9836
|
+
return fetchFn(`${baseUrl}/mcp`, {
|
|
9837
|
+
method: "POST",
|
|
9838
|
+
headers: {
|
|
9839
|
+
"Content-Type": "application/json",
|
|
9840
|
+
Accept: "application/json, text/event-stream",
|
|
9841
|
+
Authorization: `Bearer ${accessToken}`
|
|
9842
|
+
},
|
|
9843
|
+
body
|
|
9844
|
+
});
|
|
9845
|
+
}
|
|
9846
|
+
async function streamSse(res, stdout) {
|
|
9847
|
+
if (!res.body) return;
|
|
9848
|
+
const reader = res.body.getReader();
|
|
9849
|
+
const decoder = new TextDecoder("utf-8");
|
|
9850
|
+
let buf = "";
|
|
9851
|
+
for (; ; ) {
|
|
9852
|
+
const { value, done } = await reader.read();
|
|
9853
|
+
if (done) break;
|
|
9854
|
+
buf += decoder.decode(value, { stream: true });
|
|
9855
|
+
let nl;
|
|
9856
|
+
while ((nl = buf.indexOf("\n")) !== -1) {
|
|
9857
|
+
const ln = buf.slice(0, nl);
|
|
9858
|
+
buf = buf.slice(nl + 1);
|
|
9859
|
+
if (ln.startsWith("data:")) {
|
|
9860
|
+
const payload = ln.slice(5).trim();
|
|
9861
|
+
if (payload) stdout(payload + "\n");
|
|
9862
|
+
}
|
|
9863
|
+
}
|
|
9864
|
+
}
|
|
9865
|
+
}
|
|
9866
|
+
function extractId(line) {
|
|
9867
|
+
try {
|
|
9868
|
+
const obj = JSON.parse(line);
|
|
9869
|
+
return "id" in obj ? obj.id : void 0;
|
|
9870
|
+
} catch {
|
|
9871
|
+
return void 0;
|
|
9872
|
+
}
|
|
9873
|
+
}
|
|
9874
|
+
|
|
9656
9875
|
// src/cli.ts
|
|
9657
9876
|
var program = new import_commander.Command();
|
|
9658
9877
|
program.name("cleargate").description("ClearGate CLI \u2014 connects AI agent teams to the ClearGate MCP server").version(package_default.version, "-V, --version").option("--profile <name>", "configuration profile to use", "default").option("--mcp-url <url>", "MCP server URL (overrides config file and env)").showHelpAfterError("(use `cleargate --help`)");
|
|
@@ -9895,5 +10114,13 @@ var hotfix = program.command("hotfix").description("hotfix lane commands (off-sp
|
|
|
9895
10114
|
hotfix.command("new <slug>").description("scaffold a new HOTFIX-NNN_<slug>.md in pending-sync/").action((slug) => {
|
|
9896
10115
|
hotfixNewHandler({ slug });
|
|
9897
10116
|
});
|
|
10117
|
+
var mcp = program.command("mcp").description("MCP-server bridge commands (stdio shim, registration helpers)");
|
|
10118
|
+
mcp.command("serve").description("run a stdio MCP server that proxies to the cleargate HTTP /mcp endpoint with auto-refresh Bearer auth").action(async (_opts, command) => {
|
|
10119
|
+
const globals = command.parent.parent.opts();
|
|
10120
|
+
await mcpServeHandler({
|
|
10121
|
+
profile: globals.profile,
|
|
10122
|
+
...globals.mcpUrl !== void 0 ? { mcpUrlFlag: globals.mcpUrl } : {}
|
|
10123
|
+
});
|
|
10124
|
+
});
|
|
9898
10125
|
void program.parseAsync(process.argv);
|
|
9899
10126
|
//# sourceMappingURL=cli.cjs.map
|