unfairly 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/CHANGELOG.md +10 -0
- package/dist/cmd/connect.d.ts +61 -0
- package/dist/cmd/connect.d.ts.map +1 -0
- package/dist/cmd/connect.js +164 -0
- package/dist/cmd/connect.js.map +1 -0
- package/dist/cmd/parse-share-input.d.ts +6 -0
- package/dist/cmd/parse-share-input.d.ts.map +1 -0
- package/dist/cmd/parse-share-input.js +56 -0
- package/dist/cmd/parse-share-input.js.map +1 -0
- package/dist/cmd/pull.d.ts.map +1 -1
- package/dist/cmd/pull.js +23 -1
- package/dist/cmd/pull.js.map +1 -1
- package/dist/hosts/claude-code.d.ts +14 -0
- package/dist/hosts/claude-code.d.ts.map +1 -1
- package/dist/hosts/claude-code.js +63 -0
- package/dist/hosts/claude-code.js.map +1 -1
- package/dist/hosts/claude-desktop.d.ts +76 -0
- package/dist/hosts/claude-desktop.d.ts.map +1 -1
- package/dist/hosts/claude-desktop.js +134 -0
- package/dist/hosts/claude-desktop.js.map +1 -1
- package/dist/hosts/codex.d.ts +57 -0
- package/dist/hosts/codex.d.ts.map +1 -1
- package/dist/hosts/codex.js +137 -0
- package/dist/hosts/codex.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.1 — 2026-05-16
|
|
4
|
+
|
|
5
|
+
- **Fix(pull resilience)** — `unfairly pull` and `unfairly init` no longer abort the entire sync when one vault fails. Each vault is now wrapped in its own try/catch; failures are collected, surfaced at the end with the slug + first error line, and the process exits with code 1 so CI can detect partial failures. Previously a single 404 (e.g. from a duplicate-slug ambiguity) on `hq` would crash the loop and silently skip every vault alphabetically after it. The server fix that triggered this (deterministic dedupe by slug in `/api/sync/{status,pull,push}`) shipped alongside.
|
|
6
|
+
|
|
7
|
+
## 0.8.0 — 2026-05-15
|
|
8
|
+
|
|
9
|
+
- **`unfairly connect <urlOrId>`** — wire a shared vault from a share link in one command, no browser OAuth, no signup. POSTs the link to the new `/api/share-links/<id>/mint-token` endpoint (Phase B), receives a ≤24h read-only token, and writes it to Claude Desktop, Claude Code, and Codex as scoped MCP entries keyed by `unfairly-<org>-<room>`. Accepts the full URL, `s/<uuid>` short form, or a bare UUID. `--as <email>` and `--label <text>` flow through to the audit log. Re-connecting the same share link is idempotent — strips the old entry and writes a fresh token at the same key. Hosts that aren't installed are skipped, not errored.
|
|
10
|
+
- **Multi-entry host writers** — new `addScopedClaudeDesktopEntry`, `addScopedClaudeCodeEntry`, and `addScopedCodexEntry` write per-share_link entries alongside the canonical `unfairly` entry. JSON-host entries carry `_meta.shareLinkId` for idempotent rotation; Codex blocks use a `# share_link_id = "<id>"` comment line as the equivalent tag. Numbered-slot collision handling reuses gaps (e.g. with `unfairly-org-hq` + `unfairly-org-hq-3` taken, the next new entry lands at `unfairly-org-hq-2`). Scoped Codex blocks inline the literal bearer_token — these tokens are short-lived one-offs, env-var indirection isn't worth the setup friction.
|
|
11
|
+
- **`parseShareInput`** — pure parser exported from `cmd/parse-share-input.ts`. Handles `https://app.unfairly.ai/s/<uuid>`, `https://preview.../s/<uuid>` (preserves origin so we mint against the same host), `s/<uuid>`, and bare UUIDs. Throws friendly errors on junk input.
|
|
12
|
+
|
|
3
13
|
## 0.6.1 — 2026-05-14
|
|
4
14
|
|
|
5
15
|
- **Fix(Claude Code wiring)** — `unfairly setup` now writes the user-scope `unfairly` entry directly to `~/.claude.json` instead of shelling out to `claude mcp add --header=…`. The shell-out form previously omitted the bearer entirely (`claude mcp list` showed "Needs authentication"), and even when fixed would have placed the raw token in process argv for the lifetime of the subprocess — visible to same-user processes via `ps aux` / `/proc/<pid>/cmdline`. Direct JSON edit keeps the token off the process table, same threat model as the Claude Desktop wiring. Strips any stale project-scope `projects[<cwd>].mcpServers.unfairly` left over from earlier local-scope installs so they don't shadow the user-scope entry.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Argv } from "yargs";
|
|
2
|
+
import { type AddScopedEntryInput, type AddScopedEntryResult } from "../hosts/claude-desktop.js";
|
|
3
|
+
import { type AddScopedCodexResult } from "../hosts/codex.js";
|
|
4
|
+
type ConnectArgs = {
|
|
5
|
+
urlOrId: string;
|
|
6
|
+
as?: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
api?: string;
|
|
9
|
+
};
|
|
10
|
+
export type MintResponseOk = {
|
|
11
|
+
token: string;
|
|
12
|
+
mcp_url: string;
|
|
13
|
+
org_slug: string | null;
|
|
14
|
+
room_slug: string | null;
|
|
15
|
+
expires_at: string | null;
|
|
16
|
+
};
|
|
17
|
+
export type MintResponseErr = {
|
|
18
|
+
error: string;
|
|
19
|
+
message?: string;
|
|
20
|
+
};
|
|
21
|
+
export type ConnectDeps = {
|
|
22
|
+
fetch: typeof fetch;
|
|
23
|
+
addClaudeDesktop: (input: AddScopedEntryInput) => Promise<AddScopedEntryResult>;
|
|
24
|
+
addClaudeCode: (input: AddScopedEntryInput) => Promise<AddScopedEntryResult>;
|
|
25
|
+
addCodex: (input: AddScopedEntryInput) => Promise<AddScopedCodexResult>;
|
|
26
|
+
log: (line: string) => void;
|
|
27
|
+
errLog: (line: string) => void;
|
|
28
|
+
};
|
|
29
|
+
export type ConnectOutcome = {
|
|
30
|
+
ok: boolean;
|
|
31
|
+
exitCode: number;
|
|
32
|
+
shareId?: string;
|
|
33
|
+
hosts?: {
|
|
34
|
+
claudeDesktop: AddScopedEntryResult;
|
|
35
|
+
claudeCode: AddScopedEntryResult;
|
|
36
|
+
codex: AddScopedCodexResult;
|
|
37
|
+
};
|
|
38
|
+
mint?: MintResponseOk;
|
|
39
|
+
errorCode?: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Pure-ish implementation. Tests inject `deps` to drive without hitting
|
|
43
|
+
* the network or touching real config files.
|
|
44
|
+
*/
|
|
45
|
+
export declare function runConnect(args: ConnectArgs, deps: ConnectDeps): Promise<ConnectOutcome>;
|
|
46
|
+
export declare const connectCommand: {
|
|
47
|
+
command: string;
|
|
48
|
+
describe: string;
|
|
49
|
+
builder: (yargs: Argv) => Argv<{
|
|
50
|
+
urlOrId: string;
|
|
51
|
+
} & {
|
|
52
|
+
as: string | undefined;
|
|
53
|
+
} & {
|
|
54
|
+
label: string | undefined;
|
|
55
|
+
} & {
|
|
56
|
+
api: string | undefined;
|
|
57
|
+
}>;
|
|
58
|
+
handler: (args: ConnectArgs) => Promise<void>;
|
|
59
|
+
};
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/cmd/connect.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AAI3B,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,gBAAgB,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAChF,aAAa,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACxE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,aAAa,EAAE,oBAAoB,CAAC;QACpC,UAAU,EAAE,oBAAoB,CAAC;QACjC,KAAK,EAAE,oBAAoB,CAAC;KAC7B,CAAC;IACF,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAqBF;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,cAAc,CAAC,CA4GzB;AAED,eAAO,MAAM,cAAc;;;qBAGR,IAAI;;;;;;;;;oBAmBC,WAAW;CAWlC,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { parseShareInput } from "./parse-share-input.js";
|
|
2
|
+
import { addScopedClaudeDesktopEntry, } from "../hosts/claude-desktop.js";
|
|
3
|
+
import { addScopedClaudeCodeEntry } from "../hosts/claude-code.js";
|
|
4
|
+
import { addScopedCodexEntry, } from "../hosts/codex.js";
|
|
5
|
+
const API_DEFAULT = "https://app.unfairly.ai";
|
|
6
|
+
/**
|
|
7
|
+
* Map a mint endpoint error code to a user-facing message.
|
|
8
|
+
*/
|
|
9
|
+
function describeMintError(status, code) {
|
|
10
|
+
if (status === 404 || code === "not_found") {
|
|
11
|
+
return "share link not found — double-check the URL or ask the sender to issue a new one.";
|
|
12
|
+
}
|
|
13
|
+
if (status === 410 || code === "revoked_or_expired") {
|
|
14
|
+
return "share link expired or was revoked — ask the sender for a fresh one.";
|
|
15
|
+
}
|
|
16
|
+
if (status === 429 || code === "rate_limited") {
|
|
17
|
+
return "rate limited (10 mints / hour per link) — try again in an hour.";
|
|
18
|
+
}
|
|
19
|
+
if (status === 400 || code === "no_room") {
|
|
20
|
+
return "invalid share link — it isn't bound to a vault.";
|
|
21
|
+
}
|
|
22
|
+
return `server error while minting (${status} ${code}).`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Pure-ish implementation. Tests inject `deps` to drive without hitting
|
|
26
|
+
* the network or touching real config files.
|
|
27
|
+
*/
|
|
28
|
+
export async function runConnect(args, deps) {
|
|
29
|
+
let parsed;
|
|
30
|
+
try {
|
|
31
|
+
parsed = parseShareInput(args.urlOrId);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
deps.errLog(`✗ ${err.message}`);
|
|
35
|
+
return { ok: false, exitCode: 1 };
|
|
36
|
+
}
|
|
37
|
+
const apiOrigin = args.api ?? parsed.origin ?? API_DEFAULT;
|
|
38
|
+
const mintUrl = `${apiOrigin.replace(/\/$/, "")}/api/share-links/${parsed.shareId}/mint-token`;
|
|
39
|
+
const body = {};
|
|
40
|
+
if (args.as)
|
|
41
|
+
body.email = args.as;
|
|
42
|
+
if (args.label)
|
|
43
|
+
body.label = args.label;
|
|
44
|
+
deps.log("✦ Minting a 24-hour vault token…");
|
|
45
|
+
let res;
|
|
46
|
+
try {
|
|
47
|
+
res = await deps.fetch(mintUrl, {
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: { "Content-Type": "application/json" },
|
|
50
|
+
body: JSON.stringify(body),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
deps.errLog(`✗ network error reaching ${apiOrigin}: ${err.message}`);
|
|
55
|
+
return { ok: false, exitCode: 1, shareId: parsed.shareId };
|
|
56
|
+
}
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
let parsedErr = { error: "unknown" };
|
|
59
|
+
try {
|
|
60
|
+
parsedErr = (await res.json());
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// body wasn't JSON — fall through with default
|
|
64
|
+
}
|
|
65
|
+
const message = describeMintError(res.status, parsedErr.error ?? "unknown");
|
|
66
|
+
deps.errLog(`✗ ${message}`);
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
exitCode: 1,
|
|
70
|
+
shareId: parsed.shareId,
|
|
71
|
+
errorCode: parsedErr.error,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
let mint;
|
|
75
|
+
try {
|
|
76
|
+
mint = (await res.json());
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
deps.errLog(`✗ mint endpoint returned non-JSON: ${err.message}`);
|
|
80
|
+
return { ok: false, exitCode: 1, shareId: parsed.shareId };
|
|
81
|
+
}
|
|
82
|
+
if (!mint.token || !mint.mcp_url) {
|
|
83
|
+
deps.errLog("✗ mint endpoint response missing token or mcp_url");
|
|
84
|
+
return { ok: false, exitCode: 1, shareId: parsed.shareId };
|
|
85
|
+
}
|
|
86
|
+
const input = {
|
|
87
|
+
orgSlug: mint.org_slug,
|
|
88
|
+
roomSlug: mint.room_slug,
|
|
89
|
+
shareLinkId: parsed.shareId,
|
|
90
|
+
token: mint.token,
|
|
91
|
+
mcpUrl: mint.mcp_url,
|
|
92
|
+
};
|
|
93
|
+
const [claudeDesktop, claudeCode, codex] = await Promise.all([
|
|
94
|
+
deps.addClaudeDesktop(input),
|
|
95
|
+
deps.addClaudeCode(input),
|
|
96
|
+
deps.addCodex(input),
|
|
97
|
+
]);
|
|
98
|
+
// Per-host success line.
|
|
99
|
+
const reportHost = (name, result) => {
|
|
100
|
+
if (result.status === "configured") {
|
|
101
|
+
const verb = "replaced" in result && result.replaced ? "Updated" : "Wired";
|
|
102
|
+
deps.log(`✓ ${verb} ${name} · ${result.key}`);
|
|
103
|
+
}
|
|
104
|
+
else if (result.status === "not-installed") {
|
|
105
|
+
deps.log(` (${name} not installed — skipped)`);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
deps.errLog(`✗ ${name}: ${result.message ?? "unknown error"}`);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
reportHost("Claude Desktop", claudeDesktop);
|
|
112
|
+
reportHost("Claude Code", claudeCode);
|
|
113
|
+
reportHost("Codex", codex);
|
|
114
|
+
deps.log("");
|
|
115
|
+
deps.log("→ Open your AI host. Ask: \"what's in this vault?\"");
|
|
116
|
+
if (mint.expires_at) {
|
|
117
|
+
deps.log(` Token expires at ${mint.expires_at} (≤24h).`);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
deps.log(" Token expires in 24h.");
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
ok: true,
|
|
124
|
+
exitCode: 0,
|
|
125
|
+
shareId: parsed.shareId,
|
|
126
|
+
hosts: { claudeDesktop, claudeCode, codex },
|
|
127
|
+
mint,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export const connectCommand = {
|
|
131
|
+
command: "connect <urlOrId>",
|
|
132
|
+
describe: "Connect to a shared vault via share link — mints a 24h token, wires all hosts",
|
|
133
|
+
builder: (yargs) => yargs
|
|
134
|
+
.positional("urlOrId", {
|
|
135
|
+
type: "string",
|
|
136
|
+
demandOption: true,
|
|
137
|
+
describe: "Share link URL (https://app.unfairly.ai/s/<uuid>), short form (s/<uuid>), or bare UUID",
|
|
138
|
+
})
|
|
139
|
+
.option("as", {
|
|
140
|
+
type: "string",
|
|
141
|
+
describe: "Email to attribute the token to (audit only)",
|
|
142
|
+
})
|
|
143
|
+
.option("label", {
|
|
144
|
+
type: "string",
|
|
145
|
+
describe: "Human label for the audit log (≤100 chars)",
|
|
146
|
+
})
|
|
147
|
+
.option("api", {
|
|
148
|
+
type: "string",
|
|
149
|
+
describe: "Override the API origin (defaults to the URL's origin or app.unfairly.ai)",
|
|
150
|
+
}),
|
|
151
|
+
handler: async (args) => {
|
|
152
|
+
const outcome = await runConnect(args, {
|
|
153
|
+
fetch: globalThis.fetch.bind(globalThis),
|
|
154
|
+
addClaudeDesktop: addScopedClaudeDesktopEntry,
|
|
155
|
+
addClaudeCode: addScopedClaudeCodeEntry,
|
|
156
|
+
addCodex: addScopedCodexEntry,
|
|
157
|
+
log: (line) => console.log(line),
|
|
158
|
+
errLog: (line) => console.error(line),
|
|
159
|
+
});
|
|
160
|
+
if (!outcome.ok)
|
|
161
|
+
process.exit(outcome.exitCode);
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/cmd/connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-share-input.d.ts","sourceRoot":"","sources":["../../src/cmd/parse-share-input.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CA+C/D"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// cli/src/cmd/parse-share-input.ts
|
|
2
|
+
//
|
|
3
|
+
// Parse the positional arg to `unfairly connect`. Accepts:
|
|
4
|
+
// - Full URL: https://app.unfairly.ai/s/<uuid>
|
|
5
|
+
// - Short form: s/<uuid>
|
|
6
|
+
// - Bare UUID: <uuid>
|
|
7
|
+
//
|
|
8
|
+
// Returns the share_link UUID + the origin (when present in the input)
|
|
9
|
+
// so `connect` can POST to the same host the link came from. A bare UUID
|
|
10
|
+
// or short form yields `origin: null` — callers should fall back to the
|
|
11
|
+
// production app origin.
|
|
12
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
13
|
+
export function parseShareInput(input) {
|
|
14
|
+
if (typeof input !== "string") {
|
|
15
|
+
throw new Error("share link is required");
|
|
16
|
+
}
|
|
17
|
+
const trimmed = input.trim();
|
|
18
|
+
if (trimmed.length === 0) {
|
|
19
|
+
throw new Error("share link is required");
|
|
20
|
+
}
|
|
21
|
+
// Full URL form: https://host/s/<uuid> (with optional trailing slash / query).
|
|
22
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
23
|
+
let url;
|
|
24
|
+
try {
|
|
25
|
+
url = new URL(trimmed);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new Error(`not a valid URL: ${trimmed}`);
|
|
29
|
+
}
|
|
30
|
+
const segments = url.pathname.split("/").filter(Boolean);
|
|
31
|
+
// Expect [..., "s", "<uuid>"] — find the "s/" marker.
|
|
32
|
+
const sIdx = segments.indexOf("s");
|
|
33
|
+
if (sIdx === -1 || sIdx === segments.length - 1) {
|
|
34
|
+
throw new Error(`share link URL must include /s/<id>: ${trimmed}`);
|
|
35
|
+
}
|
|
36
|
+
const candidate = segments[sIdx + 1] ?? "";
|
|
37
|
+
if (!UUID_RE.test(candidate)) {
|
|
38
|
+
throw new Error(`share id must be a UUID, got "${candidate}"`);
|
|
39
|
+
}
|
|
40
|
+
return { shareId: candidate.toLowerCase(), origin: url.origin };
|
|
41
|
+
}
|
|
42
|
+
// Short form: s/<uuid>
|
|
43
|
+
if (/^s\//i.test(trimmed)) {
|
|
44
|
+
const candidate = trimmed.slice(2);
|
|
45
|
+
if (!UUID_RE.test(candidate)) {
|
|
46
|
+
throw new Error(`share id must be a UUID, got "${candidate}"`);
|
|
47
|
+
}
|
|
48
|
+
return { shareId: candidate.toLowerCase(), origin: null };
|
|
49
|
+
}
|
|
50
|
+
// Bare UUID
|
|
51
|
+
if (UUID_RE.test(trimmed)) {
|
|
52
|
+
return { shareId: trimmed.toLowerCase(), origin: null };
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`not a recognized share link: "${input}" — expected a URL like https://app.unfairly.ai/s/<uuid>, "s/<uuid>", or a bare UUID`);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=parse-share-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-share-input.js","sourceRoot":"","sources":["../../src/cmd/parse-share-input.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,EAAE;AACF,2DAA2D;AAC3D,kDAAkD;AAClD,2BAA2B;AAC3B,yBAAyB;AACzB,EAAE;AACF,uEAAuE;AACvE,yEAAyE;AACzE,wEAAwE;AACxE,yBAAyB;AAEzB,MAAM,OAAO,GAAG,iEAAiE,CAAC;AAOlF,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,+EAA+E;IAC/E,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACzD,sDAAsD;QACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,iCAAiC,SAAS,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IAClE,CAAC;IAED,uBAAuB;IACvB,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,iCAAiC,SAAS,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5D,CAAC;IAED,YAAY;IACZ,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,KAAK,CACb,iCAAiC,KAAK,sFAAsF,CAC7H,CAAC;AACJ,CAAC"}
|
package/dist/cmd/pull.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/cmd/pull.ts"],"names":[],"mappings":"AA2BA,wBAAsB,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/cmd/pull.ts"],"names":[],"mappings":"AA2BA,wBAAsB,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,iBAmI9C"}
|
package/dist/cmd/pull.js
CHANGED
|
@@ -37,6 +37,7 @@ export async function runPull(vaultArg) {
|
|
|
37
37
|
}
|
|
38
38
|
const client = new SyncClient(manifest.api_url, token);
|
|
39
39
|
const targets = vaultArg ? [vaultArg] : Object.keys(manifest.vaults);
|
|
40
|
+
const failures = [];
|
|
40
41
|
for (const slug of targets) {
|
|
41
42
|
const v = manifest.vaults[slug];
|
|
42
43
|
if (!v) {
|
|
@@ -44,7 +45,19 @@ export async function runPull(vaultArg) {
|
|
|
44
45
|
continue;
|
|
45
46
|
}
|
|
46
47
|
process.stdout.write(`pulling ${slug}... `);
|
|
47
|
-
|
|
48
|
+
let result;
|
|
49
|
+
try {
|
|
50
|
+
result = await client.pullAll(slug, v.last_pulled_at);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
// One vault failing shouldn't kill the rest of the pull. For a single-
|
|
54
|
+
// vault target (`unfairly pull <vault>`) we still want to surface and
|
|
55
|
+
// exit non-zero — fall through to throw at the end.
|
|
56
|
+
const message = err.message.split("\n")[0];
|
|
57
|
+
console.log(`FAILED — ${message}`);
|
|
58
|
+
failures.push({ slug, message });
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
48
61
|
// Vault root: track_in_git → .unfairly/{slug}/, else .unfairly/cache/{slug}/
|
|
49
62
|
const vaultRoot = v.track_in_git ? slug : path.join("cache", slug);
|
|
50
63
|
const absVaultRoot = path.join(cwd, ".unfairly", vaultRoot);
|
|
@@ -117,5 +130,14 @@ export async function runPull(vaultArg) {
|
|
|
117
130
|
const target = path.join(cwd, ".unfairly");
|
|
118
131
|
await writeAutoloader(target, refreshed);
|
|
119
132
|
}
|
|
133
|
+
if (failures.length > 0) {
|
|
134
|
+
process.stderr.write(`\n${failures.length} vault${failures.length === 1 ? "" : "s"} failed:\n`);
|
|
135
|
+
for (const f of failures) {
|
|
136
|
+
process.stderr.write(` · ${f.slug} — ${f.message}\n`);
|
|
137
|
+
}
|
|
138
|
+
// Single-vault target → propagate so callers/CI see the failure.
|
|
139
|
+
// Multi-vault → keep what we got but signal partial failure via exit code.
|
|
140
|
+
process.exitCode = 1;
|
|
141
|
+
}
|
|
120
142
|
}
|
|
121
143
|
//# sourceMappingURL=pull.js.map
|
package/dist/cmd/pull.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/cmd/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,KAAK,UAAU,KAAK,CAAC,IAAY,EAAE,EAAU;IAC3C,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,CAAS;IAChC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,QAAiB;IAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/cmd/pull.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AddScopedEntryInput, type AddScopedEntryResult } from "./claude-desktop.js";
|
|
1
2
|
export type ClaudeCodeResult = {
|
|
2
3
|
status: "configured";
|
|
3
4
|
path: string;
|
|
@@ -57,5 +58,18 @@ export declare function mergeIntoConfig(existing: ClaudeConfig, apiUrl: string,
|
|
|
57
58
|
* `claude mcp add` would have done implicitly.
|
|
58
59
|
*/
|
|
59
60
|
export declare function configureClaudeCode(apiUrl: string, token: string): Promise<ClaudeCodeResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Add a scoped, per-share_link MCP entry to Claude Code's ~/.claude.json.
|
|
63
|
+
* Reuses the Claude Desktop entry-shape + key-picker logic (same JSON
|
|
64
|
+
* config format). Idempotent by `_meta.shareLinkId`.
|
|
65
|
+
*
|
|
66
|
+
* If the `claude` binary is not in PATH → not-installed (we don't create
|
|
67
|
+
* ~/.claude.json out of thin air for a user who hasn't installed Claude
|
|
68
|
+
* Code yet — matches `configureClaudeCode` behavior).
|
|
69
|
+
*
|
|
70
|
+
* If the binary exists but ~/.claude.json doesn't → create it with the
|
|
71
|
+
* scoped entry (fresh-install case).
|
|
72
|
+
*/
|
|
73
|
+
export declare function addScopedClaudeCodeEntry(input: AddScopedEntryInput): Promise<AddScopedEntryResult>;
|
|
60
74
|
export {};
|
|
61
75
|
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/hosts/claude-code.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/hosts/claude-code.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,gBAAgB,GACxB;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,GAC3B;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACpC,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACpE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAMzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,YAAY,CAuBd;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,CAAC,CA6C3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,oBAAoB,CAAC,CAgD/B"}
|
|
@@ -2,6 +2,7 @@ import { spawnSync } from "node:child_process";
|
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
|
+
import { addScopedEntryToConfig, } from "./claude-desktop.js";
|
|
5
6
|
/**
|
|
6
7
|
* Path to Claude Code's user-level config. Returns null on Linux only if
|
|
7
8
|
* HOME is unset (effectively never).
|
|
@@ -114,4 +115,66 @@ export async function configureClaudeCode(apiUrl, token) {
|
|
|
114
115
|
message: "wired unfairly into ~/.claude.json (user scope, literal token)",
|
|
115
116
|
};
|
|
116
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Add a scoped, per-share_link MCP entry to Claude Code's ~/.claude.json.
|
|
120
|
+
* Reuses the Claude Desktop entry-shape + key-picker logic (same JSON
|
|
121
|
+
* config format). Idempotent by `_meta.shareLinkId`.
|
|
122
|
+
*
|
|
123
|
+
* If the `claude` binary is not in PATH → not-installed (we don't create
|
|
124
|
+
* ~/.claude.json out of thin air for a user who hasn't installed Claude
|
|
125
|
+
* Code yet — matches `configureClaudeCode` behavior).
|
|
126
|
+
*
|
|
127
|
+
* If the binary exists but ~/.claude.json doesn't → create it with the
|
|
128
|
+
* scoped entry (fresh-install case).
|
|
129
|
+
*/
|
|
130
|
+
export async function addScopedClaudeCodeEntry(input) {
|
|
131
|
+
const probe = spawnSync("claude", ["--version"], { encoding: "utf-8" });
|
|
132
|
+
if (probe.error) {
|
|
133
|
+
const e = probe.error;
|
|
134
|
+
if (e.code === "ENOENT")
|
|
135
|
+
return { status: "not-installed", path: "(claude not in PATH)" };
|
|
136
|
+
return { status: "error", path: "(claude probe failed)", message: e.message };
|
|
137
|
+
}
|
|
138
|
+
const cfgPath = configPath();
|
|
139
|
+
let raw;
|
|
140
|
+
try {
|
|
141
|
+
raw = await fs.readFile(cfgPath, "utf8");
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
const e = err;
|
|
145
|
+
if (e.code === "ENOENT") {
|
|
146
|
+
raw = "";
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
return {
|
|
150
|
+
status: "error",
|
|
151
|
+
path: cfgPath,
|
|
152
|
+
message: `Could not read ${cfgPath}: ${e.message}`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
let parsed;
|
|
157
|
+
try {
|
|
158
|
+
parsed = raw.trim() === "" ? {} : JSON.parse(raw);
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
return {
|
|
162
|
+
status: "error",
|
|
163
|
+
path: cfgPath,
|
|
164
|
+
message: `Refusing to overwrite — config is not valid JSON: ${err.message}`,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const { next, key, replaced } = addScopedEntryToConfig(parsed, input);
|
|
168
|
+
try {
|
|
169
|
+
await fs.writeFile(cfgPath, JSON.stringify(next, null, 2) + "\n", "utf8");
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
return {
|
|
173
|
+
status: "error",
|
|
174
|
+
path: cfgPath,
|
|
175
|
+
message: err.message,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
return { status: "configured", path: cfgPath, key, replaced };
|
|
179
|
+
}
|
|
117
180
|
//# sourceMappingURL=claude-code.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/hosts/claude-code.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/hosts/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,10 +17,40 @@ export type UnfairlyEntry = {
|
|
|
17
17
|
Authorization: string;
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Scoped entry shape — one per share_link. The `_meta.shareLinkId` tag is
|
|
22
|
+
* what makes re-connecting idempotent: pickNextEntryKey looks for it and
|
|
23
|
+
* reuses the same key instead of stamping a numbered duplicate.
|
|
24
|
+
*/
|
|
25
|
+
export type ScopedUnfairlyEntry = {
|
|
26
|
+
type: "http";
|
|
27
|
+
url: string;
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: string;
|
|
30
|
+
};
|
|
31
|
+
_meta: {
|
|
32
|
+
shareLinkId: string;
|
|
33
|
+
source: "unfairly-connect";
|
|
34
|
+
};
|
|
35
|
+
};
|
|
20
36
|
type ConfigShape = {
|
|
21
37
|
mcpServers?: Record<string, unknown>;
|
|
22
38
|
[key: string]: unknown;
|
|
23
39
|
};
|
|
40
|
+
export type AddScopedEntryInput = {
|
|
41
|
+
orgSlug: string | null;
|
|
42
|
+
roomSlug: string | null;
|
|
43
|
+
shareLinkId: string;
|
|
44
|
+
token: string;
|
|
45
|
+
mcpUrl: string;
|
|
46
|
+
};
|
|
47
|
+
export type AddScopedEntryResult = {
|
|
48
|
+
status: "configured" | "not-installed" | "error";
|
|
49
|
+
path: string;
|
|
50
|
+
key?: string;
|
|
51
|
+
replaced?: boolean;
|
|
52
|
+
message?: string;
|
|
53
|
+
};
|
|
24
54
|
/**
|
|
25
55
|
* Path to Claude Desktop's config file by platform. Returns null on Linux
|
|
26
56
|
* (Claude Desktop is Mac/Windows only per official docs).
|
|
@@ -36,6 +66,52 @@ export declare function buildEntry(apiUrl: string, token: string): UnfairlyEntry
|
|
|
36
66
|
export declare function mergeIntoConfig(existing: ConfigShape, apiUrl: string, token: string): {
|
|
37
67
|
mcpServers: Record<string, unknown>;
|
|
38
68
|
} & ConfigShape;
|
|
69
|
+
/**
|
|
70
|
+
* Build the base key (`unfairly-<org>-<room>`) for a scoped entry, given
|
|
71
|
+
* orgSlug + roomSlug. Both may be null if the mint endpoint didn't surface
|
|
72
|
+
* them; we fall back to sensible defaults to keep the key deterministic.
|
|
73
|
+
*/
|
|
74
|
+
export declare function buildScopedKeyBase(orgSlug: string | null, roomSlug: string | null): string;
|
|
75
|
+
/**
|
|
76
|
+
* Pick a key for a new scoped entry inside `servers`:
|
|
77
|
+
* - If any existing entry has `_meta.shareLinkId === shareLinkId`, reuse
|
|
78
|
+
* that key (idempotent re-connect — overwrites with fresh token).
|
|
79
|
+
* - Else if `baseKey` itself is free, use it.
|
|
80
|
+
* - Else pick the lowest free numbered slot `${baseKey}-2`, `${baseKey}-3`, …
|
|
81
|
+
* (reuses gaps: with `{baseKey, baseKey-3}` taken, returns `baseKey-2`).
|
|
82
|
+
*
|
|
83
|
+
* Returns `{ key, replaced }`. `replaced` is true when reusing an existing
|
|
84
|
+
* key (either matching shareLinkId or baseKey collision overwrite).
|
|
85
|
+
*/
|
|
86
|
+
export declare function pickNextEntryKey(servers: Record<string, unknown>, baseKey: string, shareLinkId: string): {
|
|
87
|
+
key: string;
|
|
88
|
+
replaced: boolean;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Build a scoped entry for one share_link. Distinct from `buildEntry` in
|
|
92
|
+
* that it carries the full mcp_url (from the mint response) and tags the
|
|
93
|
+
* entry with `_meta.shareLinkId` so we can re-find it later.
|
|
94
|
+
*/
|
|
95
|
+
export declare function buildScopedEntry(mcpUrl: string, token: string, shareLinkId: string): ScopedUnfairlyEntry;
|
|
96
|
+
/**
|
|
97
|
+
* Merge a scoped entry into an existing config. Pure function: returns the
|
|
98
|
+
* new config + the key that was used + whether an entry was replaced.
|
|
99
|
+
*/
|
|
100
|
+
export declare function addScopedEntryToConfig(existing: ConfigShape, input: AddScopedEntryInput): {
|
|
101
|
+
next: ConfigShape;
|
|
102
|
+
key: string;
|
|
103
|
+
replaced: boolean;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Add a scoped, per-share_link MCP entry to Claude Desktop's config. Does
|
|
107
|
+
* NOT touch the canonical `mcpServers.unfairly` entry — those are for the
|
|
108
|
+
* user's primary token. Scoped entries live alongside as additional
|
|
109
|
+
* keys like `unfairly-acme-investors`.
|
|
110
|
+
*
|
|
111
|
+
* Returns `not-installed` when Claude Desktop config dir doesn't exist
|
|
112
|
+
* (matches `configureClaudeDesktop` behavior — never creates from scratch).
|
|
113
|
+
*/
|
|
114
|
+
export declare function addScopedClaudeDesktopEntry(input: AddScopedEntryInput): Promise<AddScopedEntryResult>;
|
|
39
115
|
/**
|
|
40
116
|
* Patch Claude Desktop's config to wire the Unfairly MCP server.
|
|
41
117
|
* - If config file does not exist → not-installed (do NOT create).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-desktop.d.ts","sourceRoot":"","sources":["../../src/hosts/claude-desktop.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAC3B;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,GACrE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACpC,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAU1C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAYvE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,WAAW,CAMvD;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,CAAC,CAqC9B"}
|
|
1
|
+
{"version":3,"file":"claude-desktop.d.ts","sourceRoot":"","sources":["../../src/hosts/claude-desktop.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,6 +42,140 @@ export function mergeIntoConfig(existing, apiUrl, token) {
|
|
|
42
42
|
next.mcpServers = servers;
|
|
43
43
|
return next;
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Sanitize org/room slug fragments for use in an MCP server key. Lowercase,
|
|
47
|
+
* alphanumeric + hyphen; falls back to "vault" when the input is empty/null.
|
|
48
|
+
*/
|
|
49
|
+
function safeSlug(s, fallback) {
|
|
50
|
+
if (!s)
|
|
51
|
+
return fallback;
|
|
52
|
+
const cleaned = s
|
|
53
|
+
.toLowerCase()
|
|
54
|
+
.replace(/[^a-z0-9-]+/g, "-")
|
|
55
|
+
.replace(/^-+|-+$/g, "");
|
|
56
|
+
return cleaned.length === 0 ? fallback : cleaned;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Build the base key (`unfairly-<org>-<room>`) for a scoped entry, given
|
|
60
|
+
* orgSlug + roomSlug. Both may be null if the mint endpoint didn't surface
|
|
61
|
+
* them; we fall back to sensible defaults to keep the key deterministic.
|
|
62
|
+
*/
|
|
63
|
+
export function buildScopedKeyBase(orgSlug, roomSlug) {
|
|
64
|
+
return `unfairly-${safeSlug(orgSlug, "org")}-${safeSlug(roomSlug, "vault")}`;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Pick a key for a new scoped entry inside `servers`:
|
|
68
|
+
* - If any existing entry has `_meta.shareLinkId === shareLinkId`, reuse
|
|
69
|
+
* that key (idempotent re-connect — overwrites with fresh token).
|
|
70
|
+
* - Else if `baseKey` itself is free, use it.
|
|
71
|
+
* - Else pick the lowest free numbered slot `${baseKey}-2`, `${baseKey}-3`, …
|
|
72
|
+
* (reuses gaps: with `{baseKey, baseKey-3}` taken, returns `baseKey-2`).
|
|
73
|
+
*
|
|
74
|
+
* Returns `{ key, replaced }`. `replaced` is true when reusing an existing
|
|
75
|
+
* key (either matching shareLinkId or baseKey collision overwrite).
|
|
76
|
+
*/
|
|
77
|
+
export function pickNextEntryKey(servers, baseKey, shareLinkId) {
|
|
78
|
+
// 1. Idempotent re-connect: look for an entry tagged with our shareLinkId.
|
|
79
|
+
for (const [key, value] of Object.entries(servers)) {
|
|
80
|
+
if (!key.startsWith(baseKey))
|
|
81
|
+
continue;
|
|
82
|
+
if (value && typeof value === "object") {
|
|
83
|
+
const meta = value._meta;
|
|
84
|
+
if (meta && meta.shareLinkId === shareLinkId) {
|
|
85
|
+
return { key, replaced: true };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// 2. Find the lowest free numbered slot. Base key is slot "1" (unsuffixed).
|
|
90
|
+
if (!(baseKey in servers)) {
|
|
91
|
+
return { key: baseKey, replaced: false };
|
|
92
|
+
}
|
|
93
|
+
let n = 2;
|
|
94
|
+
while (`${baseKey}-${n}` in servers)
|
|
95
|
+
n += 1;
|
|
96
|
+
return { key: `${baseKey}-${n}`, replaced: false };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Build a scoped entry for one share_link. Distinct from `buildEntry` in
|
|
100
|
+
* that it carries the full mcp_url (from the mint response) and tags the
|
|
101
|
+
* entry with `_meta.shareLinkId` so we can re-find it later.
|
|
102
|
+
*/
|
|
103
|
+
export function buildScopedEntry(mcpUrl, token, shareLinkId) {
|
|
104
|
+
return {
|
|
105
|
+
type: "http",
|
|
106
|
+
url: mcpUrl,
|
|
107
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
108
|
+
_meta: { shareLinkId, source: "unfairly-connect" },
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Merge a scoped entry into an existing config. Pure function: returns the
|
|
113
|
+
* new config + the key that was used + whether an entry was replaced.
|
|
114
|
+
*/
|
|
115
|
+
export function addScopedEntryToConfig(existing, input) {
|
|
116
|
+
const baseKey = buildScopedKeyBase(input.orgSlug, input.roomSlug);
|
|
117
|
+
const servers = { ...(existing.mcpServers ?? {}) };
|
|
118
|
+
const { key, replaced } = pickNextEntryKey(servers, baseKey, input.shareLinkId);
|
|
119
|
+
servers[key] = buildScopedEntry(input.mcpUrl, input.token, input.shareLinkId);
|
|
120
|
+
const next = { ...existing, mcpServers: servers };
|
|
121
|
+
return { next, key, replaced };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Add a scoped, per-share_link MCP entry to Claude Desktop's config. Does
|
|
125
|
+
* NOT touch the canonical `mcpServers.unfairly` entry — those are for the
|
|
126
|
+
* user's primary token. Scoped entries live alongside as additional
|
|
127
|
+
* keys like `unfairly-acme-investors`.
|
|
128
|
+
*
|
|
129
|
+
* Returns `not-installed` when Claude Desktop config dir doesn't exist
|
|
130
|
+
* (matches `configureClaudeDesktop` behavior — never creates from scratch).
|
|
131
|
+
*/
|
|
132
|
+
export async function addScopedClaudeDesktopEntry(input) {
|
|
133
|
+
const cfgPath = configPath();
|
|
134
|
+
if (!cfgPath) {
|
|
135
|
+
return {
|
|
136
|
+
status: "not-installed",
|
|
137
|
+
path: "(Claude Desktop not available on this platform)",
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
let existing;
|
|
141
|
+
try {
|
|
142
|
+
existing = await fs.readFile(cfgPath, "utf8");
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
const e = err;
|
|
146
|
+
if (e.code === "ENOENT")
|
|
147
|
+
return { status: "not-installed", path: cfgPath };
|
|
148
|
+
return {
|
|
149
|
+
status: "error",
|
|
150
|
+
path: cfgPath,
|
|
151
|
+
message: `Could not read ${cfgPath}: ${e.message}`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
let parsed;
|
|
155
|
+
try {
|
|
156
|
+
parsed = existing.trim() === "" ? {} : JSON.parse(existing);
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
return {
|
|
160
|
+
status: "error",
|
|
161
|
+
path: cfgPath,
|
|
162
|
+
message: `Refusing to overwrite — config is not valid JSON: ${err.message}`,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
const { next, key, replaced } = addScopedEntryToConfig(parsed, input);
|
|
166
|
+
const serialized = JSON.stringify(next, null, 2) + "\n";
|
|
167
|
+
try {
|
|
168
|
+
await fs.writeFile(cfgPath, serialized, "utf8");
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
return {
|
|
172
|
+
status: "error",
|
|
173
|
+
path: cfgPath,
|
|
174
|
+
message: err.message,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return { status: "configured", path: cfgPath, key, replaced };
|
|
178
|
+
}
|
|
45
179
|
/**
|
|
46
180
|
* Patch Claude Desktop's config to wire the Unfairly MCP server.
|
|
47
181
|
* - If config file does not exist → not-installed (do NOT create).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-desktop.js","sourceRoot":"","sources":["../../src/hosts/claude-desktop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-desktop.js","sourceRoot":"","sources":["../../src/hosts/claude-desktop.ts"],"names":[],"mappings":"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"}
|
package/dist/hosts/codex.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AddScopedEntryInput } from "./claude-desktop.js";
|
|
1
2
|
export type CodexResult = {
|
|
2
3
|
status: "configured";
|
|
3
4
|
path: string;
|
|
@@ -10,6 +11,19 @@ export type CodexResult = {
|
|
|
10
11
|
path: string;
|
|
11
12
|
message: string;
|
|
12
13
|
};
|
|
14
|
+
export type AddScopedCodexResult = {
|
|
15
|
+
status: "configured";
|
|
16
|
+
path: string;
|
|
17
|
+
key: string;
|
|
18
|
+
replaced: boolean;
|
|
19
|
+
} | {
|
|
20
|
+
status: "not-installed";
|
|
21
|
+
path: string;
|
|
22
|
+
} | {
|
|
23
|
+
status: "error";
|
|
24
|
+
path: string;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
13
27
|
/**
|
|
14
28
|
* Build the canonical [mcp_servers.unfairly] block. We own this whole
|
|
15
29
|
* section — anything inside it gets overwritten on re-runs.
|
|
@@ -36,4 +50,47 @@ export declare function stripUnfairlyBlocks(toml: string): string;
|
|
|
36
50
|
* have Codex installed.
|
|
37
51
|
*/
|
|
38
52
|
export declare function configureCodex(apiUrl: string): Promise<CodexResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Build a scoped Codex block. Inlines the literal bearer_token — these
|
|
55
|
+
* are short-lived (max 24h), one-off tokens, so env-var indirection isn't
|
|
56
|
+
* worth the setup friction. A `# share_link_id = "<id>"` comment line
|
|
57
|
+
* above the section header serves as the lookup tag for idempotent
|
|
58
|
+
* rotation.
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildScopedCodexBlock(key: string, mcpUrl: string, token: string, shareLinkId: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Find the existing scoped block keyed by `shareLinkId`, if any. The tag
|
|
63
|
+
* comment must immediately precede the section header. Returns the key
|
|
64
|
+
* from the section header, or null if no block matches.
|
|
65
|
+
*/
|
|
66
|
+
export declare function findScopedBlockKey(toml: string, shareLinkId: string): string | null;
|
|
67
|
+
/**
|
|
68
|
+
* Strip a single scoped block (tag + section + body, through but not
|
|
69
|
+
* including the next top-level `[...]` table header). Returns the
|
|
70
|
+
* remaining TOML. No-op if the block isn't present.
|
|
71
|
+
*/
|
|
72
|
+
export declare function stripScopedBlock(toml: string, shareLinkId: string): string;
|
|
73
|
+
/**
|
|
74
|
+
* Enumerate all `[mcp_servers.<key>]` keys defined in the TOML. Used to
|
|
75
|
+
* find the lowest free numbered slot for a new scoped entry.
|
|
76
|
+
*/
|
|
77
|
+
export declare function listMcpServerKeys(toml: string): string[];
|
|
78
|
+
/**
|
|
79
|
+
* Pick the next free Codex key for a scoped entry. Same numbering scheme
|
|
80
|
+
* as the JSON-host pickNextEntryKey: base key, then -2, -3, ... reusing
|
|
81
|
+
* gaps.
|
|
82
|
+
*/
|
|
83
|
+
export declare function pickNextCodexKey(toml: string, baseKey: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* Add a scoped, per-share_link MCP entry to ~/.codex/config.toml. Does
|
|
86
|
+
* NOT touch the canonical `[mcp_servers.unfairly]` env-var block — those
|
|
87
|
+
* are for the user's primary token. Scoped entries live alongside.
|
|
88
|
+
*
|
|
89
|
+
* Idempotent: if a block tagged with the same shareLinkId already
|
|
90
|
+
* exists, rotate in place (strip + append at the same key).
|
|
91
|
+
*
|
|
92
|
+
* Returns `not-installed` when ~/.codex/config.toml doesn't exist
|
|
93
|
+
* (matches `configureCodex` behavior — never creates from scratch).
|
|
94
|
+
*/
|
|
95
|
+
export declare function addScopedCodexEntry(input: AddScopedEntryInput): Promise<AddScopedCodexResult>;
|
|
39
96
|
//# sourceMappingURL=codex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/hosts/codex.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/hosts/codex.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEnF,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;CAAE,GACnF;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,oBAAoB,GAC5B;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACtE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAKvD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmBxD;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAiDzE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,MAAM,CAOR;AASD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQnF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAS1E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CASxD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,oBAAoB,CAAC,CAsD/B"}
|
package/dist/hosts/codex.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { buildScopedKeyBase } from "./claude-desktop.js";
|
|
4
5
|
const SECTION_HEADER = "[mcp_servers.unfairly]";
|
|
6
|
+
const SHARE_TAG_PREFIX = "# share_link_id = ";
|
|
5
7
|
/**
|
|
6
8
|
* Build the canonical [mcp_servers.unfairly] block. We own this whole
|
|
7
9
|
* section — anything inside it gets overwritten on re-runs.
|
|
@@ -94,4 +96,139 @@ export async function configureCodex(apiUrl) {
|
|
|
94
96
|
: "appended";
|
|
95
97
|
return { status: "configured", path: filePath, action };
|
|
96
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Build a scoped Codex block. Inlines the literal bearer_token — these
|
|
101
|
+
* are short-lived (max 24h), one-off tokens, so env-var indirection isn't
|
|
102
|
+
* worth the setup friction. A `# share_link_id = "<id>"` comment line
|
|
103
|
+
* above the section header serves as the lookup tag for idempotent
|
|
104
|
+
* rotation.
|
|
105
|
+
*/
|
|
106
|
+
export function buildScopedCodexBlock(key, mcpUrl, token, shareLinkId) {
|
|
107
|
+
return [
|
|
108
|
+
`${SHARE_TAG_PREFIX}"${shareLinkId}"`,
|
|
109
|
+
`[mcp_servers.${key}]`,
|
|
110
|
+
`url = "${mcpUrl}"`,
|
|
111
|
+
`bearer_token = "${token}"`,
|
|
112
|
+
].join("\n");
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Escape a string for safe inclusion inside a JS regex literal.
|
|
116
|
+
*/
|
|
117
|
+
function escapeRe(s) {
|
|
118
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Find the existing scoped block keyed by `shareLinkId`, if any. The tag
|
|
122
|
+
* comment must immediately precede the section header. Returns the key
|
|
123
|
+
* from the section header, or null if no block matches.
|
|
124
|
+
*/
|
|
125
|
+
export function findScopedBlockKey(toml, shareLinkId) {
|
|
126
|
+
const normalized = toml.replace(/\r\n/g, "\n");
|
|
127
|
+
const re = new RegExp(`^${escapeRe(SHARE_TAG_PREFIX)}"${escapeRe(shareLinkId)}"\\s*\\n\\[mcp_servers\\.([a-zA-Z0-9_-]+)\\]`, "m");
|
|
128
|
+
const m = normalized.match(re);
|
|
129
|
+
return m?.[1] ?? null;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Strip a single scoped block (tag + section + body, through but not
|
|
133
|
+
* including the next top-level `[...]` table header). Returns the
|
|
134
|
+
* remaining TOML. No-op if the block isn't present.
|
|
135
|
+
*/
|
|
136
|
+
export function stripScopedBlock(toml, shareLinkId) {
|
|
137
|
+
const normalized = toml.replace(/\r\n/g, "\n");
|
|
138
|
+
const re = new RegExp(`^${escapeRe(SHARE_TAG_PREFIX)}"${escapeRe(shareLinkId)}"\\s*\\n\\[mcp_servers\\.[a-zA-Z0-9_-]+\\]\\s*\\n[\\s\\S]*?(?=^\\[|$(?![\\s\\S]))`, "gm");
|
|
139
|
+
let stripped = normalized.replace(re, "");
|
|
140
|
+
stripped = stripped.replace(/\n{3,}/g, "\n\n");
|
|
141
|
+
return stripped;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Enumerate all `[mcp_servers.<key>]` keys defined in the TOML. Used to
|
|
145
|
+
* find the lowest free numbered slot for a new scoped entry.
|
|
146
|
+
*/
|
|
147
|
+
export function listMcpServerKeys(toml) {
|
|
148
|
+
const normalized = toml.replace(/\r\n/g, "\n");
|
|
149
|
+
const re = /^\[mcp_servers\.([a-zA-Z0-9_-]+)\]/gm;
|
|
150
|
+
const keys = new Set();
|
|
151
|
+
let m;
|
|
152
|
+
while ((m = re.exec(normalized)) !== null) {
|
|
153
|
+
if (m[1])
|
|
154
|
+
keys.add(m[1]);
|
|
155
|
+
}
|
|
156
|
+
return [...keys];
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Pick the next free Codex key for a scoped entry. Same numbering scheme
|
|
160
|
+
* as the JSON-host pickNextEntryKey: base key, then -2, -3, ... reusing
|
|
161
|
+
* gaps.
|
|
162
|
+
*/
|
|
163
|
+
export function pickNextCodexKey(toml, baseKey) {
|
|
164
|
+
const existing = new Set(listMcpServerKeys(toml));
|
|
165
|
+
if (!existing.has(baseKey))
|
|
166
|
+
return baseKey;
|
|
167
|
+
let n = 2;
|
|
168
|
+
while (existing.has(`${baseKey}-${n}`))
|
|
169
|
+
n += 1;
|
|
170
|
+
return `${baseKey}-${n}`;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Add a scoped, per-share_link MCP entry to ~/.codex/config.toml. Does
|
|
174
|
+
* NOT touch the canonical `[mcp_servers.unfairly]` env-var block — those
|
|
175
|
+
* are for the user's primary token. Scoped entries live alongside.
|
|
176
|
+
*
|
|
177
|
+
* Idempotent: if a block tagged with the same shareLinkId already
|
|
178
|
+
* exists, rotate in place (strip + append at the same key).
|
|
179
|
+
*
|
|
180
|
+
* Returns `not-installed` when ~/.codex/config.toml doesn't exist
|
|
181
|
+
* (matches `configureCodex` behavior — never creates from scratch).
|
|
182
|
+
*/
|
|
183
|
+
export async function addScopedCodexEntry(input) {
|
|
184
|
+
const home = os.homedir();
|
|
185
|
+
const filePath = path.join(home, ".codex", "config.toml");
|
|
186
|
+
let existing;
|
|
187
|
+
try {
|
|
188
|
+
existing = await fs.readFile(filePath, "utf-8");
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
const e = err;
|
|
192
|
+
if (e.code === "ENOENT") {
|
|
193
|
+
return { status: "not-installed", path: filePath };
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
status: "error",
|
|
197
|
+
path: filePath,
|
|
198
|
+
message: `Could not read ${filePath}: ${e.message}`,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const baseKey = buildScopedKeyBase(input.orgSlug, input.roomSlug);
|
|
202
|
+
const existingKey = findScopedBlockKey(existing, input.shareLinkId);
|
|
203
|
+
let key;
|
|
204
|
+
let replaced;
|
|
205
|
+
let stripped;
|
|
206
|
+
if (existingKey) {
|
|
207
|
+
key = existingKey;
|
|
208
|
+
replaced = true;
|
|
209
|
+
stripped = stripScopedBlock(existing, input.shareLinkId);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
stripped = existing;
|
|
213
|
+
key = pickNextCodexKey(stripped, baseKey);
|
|
214
|
+
replaced = false;
|
|
215
|
+
}
|
|
216
|
+
const block = buildScopedCodexBlock(key, input.mcpUrl, input.token, input.shareLinkId);
|
|
217
|
+
const trimmedTail = stripped.replace(/\n+$/, "");
|
|
218
|
+
const next = trimmedTail.length === 0
|
|
219
|
+
? `${block}\n`
|
|
220
|
+
: `${trimmedTail}\n\n${block}\n`;
|
|
221
|
+
try {
|
|
222
|
+
await fs.writeFile(filePath, next, "utf-8");
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
const e = err;
|
|
226
|
+
return {
|
|
227
|
+
status: "error",
|
|
228
|
+
path: filePath,
|
|
229
|
+
message: `Could not write ${filePath}: ${e.message}`,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
return { status: "configured", path: filePath, key, replaced };
|
|
233
|
+
}
|
|
97
234
|
//# sourceMappingURL=codex.js.map
|
package/dist/hosts/codex.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/hosts/codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/hosts/codex.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import yargs from "yargs";
|
|
|
7
7
|
import { hideBin } from "yargs/helpers";
|
|
8
8
|
import { inviteCommand } from "./cmd/invite.js";
|
|
9
9
|
import { joinCommand } from "./cmd/join.js";
|
|
10
|
+
import { connectCommand } from "./cmd/connect.js";
|
|
10
11
|
const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8"));
|
|
11
12
|
await yargs(hideBin(process.argv))
|
|
12
13
|
.scriptName("unfairly")
|
|
@@ -65,6 +66,7 @@ await yargs(hideBin(process.argv))
|
|
|
65
66
|
})
|
|
66
67
|
.command(inviteCommand)
|
|
67
68
|
.command(joinCommand)
|
|
69
|
+
.command(connectCommand)
|
|
68
70
|
.strict()
|
|
69
71
|
.help()
|
|
70
72
|
.parse();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|