bravenlab 0.1.0 → 0.1.3
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 +15 -16
- package/dist/auth.js +49 -24
- package/dist/auth.js.map +3 -3
- package/dist/bin.js +292 -113
- package/dist/bin.js.map +4 -4
- package/dist/cli.js +234 -61
- package/dist/cli.js.map +4 -4
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/cli.ts
|
|
2
2
|
import { Argument as Argument4, Command as Command4, Flag as Flag4 } from "effect/cli";
|
|
3
|
-
import { Console as
|
|
3
|
+
import { Console as Console9, Effect as Effect35, Match as Match11, Option as Option34 } from "effect";
|
|
4
4
|
|
|
5
5
|
// ../agent-tools/src/catalog.ts
|
|
6
6
|
import { Tool as Tool2 } from "effect/ai";
|
|
@@ -606,7 +606,7 @@ var catalog = [...tools, ...webTools].map(
|
|
|
606
606
|
toEntry
|
|
607
607
|
);
|
|
608
608
|
var remoteTools = catalog.filter(
|
|
609
|
-
(
|
|
609
|
+
(entry) => entry.surfaces.includes("mcp") && !entry.local
|
|
610
610
|
);
|
|
611
611
|
|
|
612
612
|
// ../agent-tools/src/server.ts
|
|
@@ -858,7 +858,7 @@ var layer2 = Layer3.effect(Scopes)(
|
|
|
858
858
|
return Scopes.of({ scopes });
|
|
859
859
|
})
|
|
860
860
|
);
|
|
861
|
-
var permit = (access, tool,
|
|
861
|
+
var permit = (access, tool, run2) => Arr.some(scopesOf(tool), (scope) => Arr.contains(access.scopes, scope)) ? run2 : Effect3.fail(
|
|
862
862
|
new AgentToolError({
|
|
863
863
|
message: `${tool.name} needs the ${scopesOf(tool).join("/")} scope; this server allows ${access.scopes.join(", ")}. Nothing was changed. Set BRAVEN_MCP_SCOPES to include it, or run it from the CLI or dashboard.`,
|
|
864
864
|
code: "forbidden"
|
|
@@ -1226,7 +1226,7 @@ var canonicalValue = (value3) => {
|
|
|
1226
1226
|
Object.entries(value3),
|
|
1227
1227
|
Order.mapInput(
|
|
1228
1228
|
Order.String,
|
|
1229
|
-
(
|
|
1229
|
+
(entry) => entry[0]
|
|
1230
1230
|
)
|
|
1231
1231
|
),
|
|
1232
1232
|
([key2, field2]) => {
|
|
@@ -2122,7 +2122,7 @@ var stableText = (value3) => Match4.value(value3).pipe(
|
|
|
2122
2122
|
Object.entries(record2),
|
|
2123
2123
|
Order2.mapInput(
|
|
2124
2124
|
Order2.String,
|
|
2125
|
-
(
|
|
2125
|
+
(entry) => entry[0]
|
|
2126
2126
|
)
|
|
2127
2127
|
),
|
|
2128
2128
|
([key2, field2]) => `${key2.length}:${key2}=${stableText(field2)}`
|
|
@@ -2858,7 +2858,7 @@ var mergeRuntime = (state, base, local, remote) => {
|
|
|
2858
2858
|
scalarKey,
|
|
2859
2859
|
scalarJson
|
|
2860
2860
|
);
|
|
2861
|
-
const
|
|
2861
|
+
const entry = field(
|
|
2862
2862
|
state,
|
|
2863
2863
|
"/runtime/entry",
|
|
2864
2864
|
base.entry,
|
|
@@ -2885,7 +2885,7 @@ var mergeRuntime = (state, base, local, remote) => {
|
|
|
2885
2885
|
(value3) => stableText(Schema12.encodeSync(Schema12.Array(Schema12.String))(value3)),
|
|
2886
2886
|
(value3) => asJson(Schema12.encodeSync(Schema12.Array(Schema12.String))(value3))
|
|
2887
2887
|
);
|
|
2888
|
-
return Option7.all({ python, entry
|
|
2888
|
+
return Option7.all({ python, entry, requirements, imports }).pipe(
|
|
2889
2889
|
Option7.map(
|
|
2890
2890
|
(fields) => new IrRuntime({
|
|
2891
2891
|
python: fields.python,
|
|
@@ -4967,7 +4967,7 @@ var make = (options) => {
|
|
|
4967
4967
|
const valuesOf = (entries, category) => R5.fromEntries(
|
|
4968
4968
|
Arr12.flatMap(
|
|
4969
4969
|
entries,
|
|
4970
|
-
(
|
|
4970
|
+
(entry) => entry.category === category && entry.value !== null ? [[entry.key, entry.value]] : []
|
|
4971
4971
|
)
|
|
4972
4972
|
);
|
|
4973
4973
|
return {
|
|
@@ -5375,7 +5375,6 @@ var fail6 = (message, exitCode = EXIT_FAILURE) => Effect15.fail(new CliFailure({
|
|
|
5375
5375
|
var oneLine2 = (value3) => Str8.trim(Str8.replace(/\s+/g, " ")(String(value3))).slice(0, 300);
|
|
5376
5376
|
|
|
5377
5377
|
// ../identity-store/src/identity.ts
|
|
5378
|
-
import { Entry } from "@napi-rs/keyring";
|
|
5379
5378
|
import { Context as Context6, Effect as Effect16, Layer as Layer5, Option as Option20, pipe } from "effect";
|
|
5380
5379
|
import * as Arr13 from "effect/Array";
|
|
5381
5380
|
import * as R6 from "effect/Record";
|
|
@@ -5385,7 +5384,6 @@ import * as Predicate from "effect/Predicate";
|
|
|
5385
5384
|
import * as Schema22 from "effect/Schema";
|
|
5386
5385
|
import * as Str9 from "effect/String";
|
|
5387
5386
|
var CONFIG_VERSION = 1;
|
|
5388
|
-
var KEYCHAIN_SERVICE = "braven";
|
|
5389
5387
|
var CredentialKind = Schema22.Literals(["session", "apiKey"]);
|
|
5390
5388
|
var Account = class extends Schema22.Class("Account")({
|
|
5391
5389
|
origin: Schema22.String,
|
|
@@ -5422,29 +5420,56 @@ var ConfigFile = class extends Schema22.Class("ConfigFile")({
|
|
|
5422
5420
|
var ConfigJson = Schema22.fromJsonString(ConfigFile, { space: 2 });
|
|
5423
5421
|
var StoreConfig = class extends Context6.Service()("braven/StoreConfig") {
|
|
5424
5422
|
};
|
|
5425
|
-
var
|
|
5426
|
-
|
|
5423
|
+
var CREDENTIALS_FILE = "credentials.json";
|
|
5424
|
+
var Secrets = class extends Context6.Service()(
|
|
5425
|
+
"braven/Secrets"
|
|
5427
5426
|
) {
|
|
5428
5427
|
};
|
|
5429
|
-
var
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
}
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5428
|
+
var SecretsJson = Schema22.fromJsonString(
|
|
5429
|
+
Schema22.Record(Schema22.String, Schema22.String),
|
|
5430
|
+
{ space: 2 }
|
|
5431
|
+
);
|
|
5432
|
+
var credentialsPath = (configPath2) => Str9.replace(/config\.json$/, CREDENTIALS_FILE)(configPath2);
|
|
5433
|
+
var secretsLayer = Layer5.effect(Secrets)(
|
|
5434
|
+
Effect16.gen(function* () {
|
|
5435
|
+
const { path } = yield* StoreConfig;
|
|
5436
|
+
const fs = yield* FileSystem11.FileSystem;
|
|
5437
|
+
const pathService = yield* Path11.Path;
|
|
5438
|
+
const file = credentialsPath(path);
|
|
5439
|
+
const read2 = () => Effect16.gen(function* () {
|
|
5440
|
+
if (!(yield* fs.exists(file).pipe(Effect16.mapError(storageFailure("read", file))))) {
|
|
5441
|
+
return {};
|
|
5442
|
+
}
|
|
5443
|
+
const text = yield* fs.readFileString(file).pipe(Effect16.mapError(storageFailure("read", file)));
|
|
5444
|
+
return yield* Schema22.decodeUnknownEffect(SecretsJson)(text).pipe(
|
|
5445
|
+
Effect16.mapError(
|
|
5446
|
+
(cause) => new CliFailure({
|
|
5447
|
+
message: `${file} is not a credentials file: ${oneLine2(cause.message)}`,
|
|
5448
|
+
exitCode: EXIT_FAILURE
|
|
5449
|
+
})
|
|
5450
|
+
)
|
|
5451
|
+
);
|
|
5452
|
+
});
|
|
5453
|
+
const write2 = (secrets) => Effect16.gen(function* () {
|
|
5454
|
+
const text = yield* Schema22.encodeUnknownEffect(SecretsJson)(
|
|
5455
|
+
secrets
|
|
5456
|
+
).pipe(Effect16.mapError(storageFailure("encode", file)));
|
|
5457
|
+
yield* fs.makeDirectory(pathService.dirname(file), { recursive: true }).pipe(Effect16.mapError(storageFailure("create", file)));
|
|
5458
|
+
const temporary = `${file}.tmp`;
|
|
5459
|
+
yield* fs.writeFileString(temporary, text, { mode: 384 }).pipe(Effect16.mapError(storageFailure("write", file)));
|
|
5460
|
+
yield* fs.chmod(temporary, 384).pipe(Effect16.mapError(storageFailure("write", file)));
|
|
5461
|
+
yield* fs.rename(temporary, file).pipe(Effect16.mapError(storageFailure("write", file)));
|
|
5462
|
+
});
|
|
5463
|
+
const update = (change) => Effect16.gen(function* () {
|
|
5464
|
+
yield* write2(change(yield* read2()));
|
|
5465
|
+
});
|
|
5466
|
+
return Secrets.of({
|
|
5467
|
+
get: (account) => read2().pipe(Effect16.map((all4) => Option20.fromNullishOr(all4[account]))),
|
|
5468
|
+
set: (account, secret) => update((all4) => R6.set(all4, account, secret)),
|
|
5469
|
+
remove: (account) => update((all4) => R6.remove(all4, account))
|
|
5470
|
+
});
|
|
5446
5471
|
})
|
|
5447
|
-
|
|
5472
|
+
);
|
|
5448
5473
|
var accountKey = (origin, email) => `${normalizeOrigin(origin)}|${email}`;
|
|
5449
5474
|
var normalizeOrigin = (origin) => Str9.replace(/\/+$/, "")(origin);
|
|
5450
5475
|
var storageFailure = (action, path) => (cause) => new CliFailure({
|
|
@@ -5511,8 +5536,8 @@ var storeCredential = (credential, label = Option20.none()) => Effect16.gen(func
|
|
|
5511
5536
|
}
|
|
5512
5537
|
const origin = normalizeOrigin(credential.origin);
|
|
5513
5538
|
const key2 = accountKey(origin, credential.email);
|
|
5514
|
-
const
|
|
5515
|
-
yield*
|
|
5539
|
+
const secrets = yield* Secrets;
|
|
5540
|
+
yield* secrets.set(key2, credential.secret);
|
|
5516
5541
|
const config = yield* loadConfig();
|
|
5517
5542
|
const account = new Account({
|
|
5518
5543
|
origin,
|
|
@@ -5559,8 +5584,8 @@ var removeCredential = (email) => Effect16.gen(function* () {
|
|
|
5559
5584
|
if (Option20.isNone(account)) return Option20.none();
|
|
5560
5585
|
const target = account.value;
|
|
5561
5586
|
const key2 = accountKey(target.origin, target.email);
|
|
5562
|
-
const
|
|
5563
|
-
yield*
|
|
5587
|
+
const secrets = yield* Secrets;
|
|
5588
|
+
yield* secrets.remove(key2);
|
|
5564
5589
|
const accounts = config.accounts.filter(
|
|
5565
5590
|
(stored) => accountKey(stored.origin, stored.email) !== key2
|
|
5566
5591
|
);
|
|
@@ -5607,8 +5632,8 @@ var storedCredential = (options) => Effect16.gen(function* () {
|
|
|
5607
5632
|
const account = Option20.isSome(options.origin) || Option20.isSome(options.email) ? findAccount(config, options.origin, options.email) : currentAccount(config);
|
|
5608
5633
|
if (Option20.isNone(account)) return Option20.none();
|
|
5609
5634
|
const stored = account.value;
|
|
5610
|
-
const
|
|
5611
|
-
const secret = yield*
|
|
5635
|
+
const secrets = yield* Secrets;
|
|
5636
|
+
const secret = yield* secrets.get(accountKey(stored.origin, stored.email));
|
|
5612
5637
|
if (Option20.isNone(secret)) return Option20.none();
|
|
5613
5638
|
return Option20.some({
|
|
5614
5639
|
origin: stored.origin,
|
|
@@ -8256,20 +8281,40 @@ import * as P6 from "effect/Predicate";
|
|
|
8256
8281
|
import * as R7 from "effect/Record";
|
|
8257
8282
|
import * as Schema30 from "effect/Schema";
|
|
8258
8283
|
import * as Str11 from "effect/String";
|
|
8259
|
-
var CLIENTS = [
|
|
8284
|
+
var CLIENTS = [
|
|
8285
|
+
"claude",
|
|
8286
|
+
"cursor",
|
|
8287
|
+
"opencode",
|
|
8288
|
+
"zed",
|
|
8289
|
+
"vscode"
|
|
8290
|
+
];
|
|
8260
8291
|
var serversKey = {
|
|
8261
8292
|
claude: "mcpServers",
|
|
8262
8293
|
cursor: "mcpServers",
|
|
8294
|
+
opencode: "mcp",
|
|
8263
8295
|
zed: "context_servers",
|
|
8264
8296
|
vscode: "servers"
|
|
8265
8297
|
};
|
|
8266
8298
|
var displayName = {
|
|
8267
8299
|
claude: "Claude Desktop",
|
|
8268
8300
|
cursor: "Cursor",
|
|
8301
|
+
opencode: "opencode",
|
|
8269
8302
|
zed: "Zed",
|
|
8270
8303
|
vscode: "VS Code"
|
|
8271
8304
|
};
|
|
8272
|
-
var serverEntry = (client) => client
|
|
8305
|
+
var serverEntry = (client) => Match10.value(client).pipe(
|
|
8306
|
+
Match10.when("vscode", () => ({
|
|
8307
|
+
type: "stdio",
|
|
8308
|
+
command: "braven",
|
|
8309
|
+
args: ["mcp"]
|
|
8310
|
+
})),
|
|
8311
|
+
Match10.when("opencode", () => ({
|
|
8312
|
+
type: "local",
|
|
8313
|
+
command: ["braven", "mcp"],
|
|
8314
|
+
enabled: true
|
|
8315
|
+
})),
|
|
8316
|
+
Match10.orElse(() => ({ command: "braven", args: ["mcp"] }))
|
|
8317
|
+
);
|
|
8273
8318
|
var isRecord = (value3) => P6.isObject(value3);
|
|
8274
8319
|
var asRecord = (value3) => Option33.liftPredicate(isRecord)(value3);
|
|
8275
8320
|
var value2 = (shape, name) => Option33.filter(Option33.fromNullishOr(shape.values[name]), Str11.isNonEmpty);
|
|
@@ -8293,6 +8338,10 @@ var applications = (shape) => Match10.value(shape.platform).pipe(
|
|
|
8293
8338
|
)
|
|
8294
8339
|
)
|
|
8295
8340
|
);
|
|
8341
|
+
var configHome = (shape) => Option33.getOrElse(
|
|
8342
|
+
value2(shape, "XDG_CONFIG_HOME"),
|
|
8343
|
+
() => join9(shape, shape.home, ".config")
|
|
8344
|
+
);
|
|
8296
8345
|
var configPathFor = (client, shape) => Match10.value(client).pipe(
|
|
8297
8346
|
Match10.when(
|
|
8298
8347
|
"claude",
|
|
@@ -8311,14 +8360,21 @@ var configPathFor = (client, shape) => Match10.value(client).pipe(
|
|
|
8311
8360
|
)
|
|
8312
8361
|
)
|
|
8313
8362
|
),
|
|
8363
|
+
Match10.when(
|
|
8364
|
+
"opencode",
|
|
8365
|
+
() => Option33.getOrElse(
|
|
8366
|
+
value2(shape, "OPENCODE_CONFIG"),
|
|
8367
|
+
() => join9(shape, configHome(shape), "opencode", "opencode.json")
|
|
8368
|
+
)
|
|
8369
|
+
),
|
|
8314
8370
|
Match10.when("vscode", () => join9(shape, shape.cwd, ".vscode", "mcp.json")),
|
|
8315
8371
|
Match10.exhaustive
|
|
8316
8372
|
);
|
|
8317
8373
|
var decodeJson2 = Schema30.decodeUnknownOption(
|
|
8318
8374
|
Schema30.fromJsonString(Schema30.Unknown)
|
|
8319
8375
|
);
|
|
8320
|
-
var withoutEmptyEnv = (
|
|
8321
|
-
onNone: () =>
|
|
8376
|
+
var withoutEmptyEnv = (entry) => Option33.match(asRecord(entry), {
|
|
8377
|
+
onNone: () => entry,
|
|
8322
8378
|
onSome: (record2) => Option33.match(Option33.flatMap(R7.get(record2, "env"), asRecord), {
|
|
8323
8379
|
onNone: () => record2,
|
|
8324
8380
|
onSome: (env) => Match10.value(R7.isEmptyRecord(env)).pipe(
|
|
@@ -8334,16 +8390,16 @@ var withServer = (config, key2, servers, client) => ({
|
|
|
8334
8390
|
var invalid = (reason) => ({ kind: "invalid", reason });
|
|
8335
8391
|
var mergeEntry = (client, config, key2, servers, force) => Option33.match(R7.get(servers, "braven"), {
|
|
8336
8392
|
onNone: () => withServer(config, key2, servers, client),
|
|
8337
|
-
onSome: (
|
|
8393
|
+
onSome: (entry) => Bool2.match(
|
|
8338
8394
|
Equal.equals(
|
|
8339
|
-
withoutEmptyEnv(
|
|
8395
|
+
withoutEmptyEnv(entry),
|
|
8340
8396
|
withoutEmptyEnv(serverEntry(client))
|
|
8341
8397
|
),
|
|
8342
8398
|
{
|
|
8343
8399
|
onTrue: () => ({ kind: "unchanged" }),
|
|
8344
8400
|
onFalse: () => Bool2.match(force, {
|
|
8345
8401
|
onTrue: () => withServer(config, key2, servers, client),
|
|
8346
|
-
onFalse: () => ({ kind: "conflict", current:
|
|
8402
|
+
onFalse: () => ({ kind: "conflict", current: entry })
|
|
8347
8403
|
})
|
|
8348
8404
|
}
|
|
8349
8405
|
)
|
|
@@ -8438,10 +8494,10 @@ var install = Effect33.fn("mcp.install")(function* (options) {
|
|
|
8438
8494
|
{ kind: "conflict" },
|
|
8439
8495
|
({ current }) => Effect33.flatMap(
|
|
8440
8496
|
inline(current),
|
|
8441
|
-
(
|
|
8497
|
+
(entry) => Console7.log(
|
|
8442
8498
|
`braven is already configured differently:
|
|
8443
8499
|
file ${options.path}
|
|
8444
|
-
current ${
|
|
8500
|
+
current ${entry}`
|
|
8445
8501
|
).pipe(
|
|
8446
8502
|
Effect33.andThen(
|
|
8447
8503
|
fail6(
|
|
@@ -8506,8 +8562,81 @@ var installCommand = Effect33.fn("mcp.installCommand")(
|
|
|
8506
8562
|
}
|
|
8507
8563
|
);
|
|
8508
8564
|
|
|
8565
|
+
// src/desktop.ts
|
|
8566
|
+
import { Console as Console8, Effect as Effect34 } from "effect";
|
|
8567
|
+
import { execFile } from "node:child_process";
|
|
8568
|
+
import { cpSync, existsSync, mkdtempSync, rmSync } from "node:fs";
|
|
8569
|
+
import { homedir, tmpdir } from "node:os";
|
|
8570
|
+
import { join as join10, resolve } from "node:path";
|
|
8571
|
+
var destinationOf = (input) => input.destination ?? (input.system === true ? "/Applications/Braven.app" : join10(homedir(), "Applications", "Braven.app"));
|
|
8572
|
+
var run = (bin, args) => Effect34.tryPromise({
|
|
8573
|
+
try: () => new Promise((resolvePromise, reject) => {
|
|
8574
|
+
execFile(
|
|
8575
|
+
bin,
|
|
8576
|
+
[...args],
|
|
8577
|
+
(error, stdout) => error === null ? resolvePromise(stdout) : reject(error)
|
|
8578
|
+
);
|
|
8579
|
+
}),
|
|
8580
|
+
catch: (cause) => new Error(`${bin} failed: ${String(cause)}`)
|
|
8581
|
+
});
|
|
8582
|
+
var copyApp = (source, destination) => Effect34.sync(() => {
|
|
8583
|
+
if (!existsSync(join10(source, "Contents", "Info.plist")))
|
|
8584
|
+
throw new Error(`${source} is not a Braven.app`);
|
|
8585
|
+
rmSync(destination, { recursive: true, force: true });
|
|
8586
|
+
cpSync(source, destination, { recursive: true });
|
|
8587
|
+
});
|
|
8588
|
+
var installDesktop = Effect34.fn("desktop.install")(function* (input) {
|
|
8589
|
+
if (process.platform === "win32") {
|
|
8590
|
+
if (input.exe === void 0)
|
|
8591
|
+
return yield* Effect34.fail(
|
|
8592
|
+
new Error("pass --exe <Braven-Setup.exe> on Windows")
|
|
8593
|
+
);
|
|
8594
|
+
yield* run(
|
|
8595
|
+
resolve(input.exe),
|
|
8596
|
+
input.silent === true ? ["/SILENT", "/SUPPRESSMSGBOXES", "/NORESTART"] : []
|
|
8597
|
+
);
|
|
8598
|
+
yield* Console8.log(
|
|
8599
|
+
input.silent === true ? "installer finished" : "the installer will finish in its own window"
|
|
8600
|
+
);
|
|
8601
|
+
return;
|
|
8602
|
+
}
|
|
8603
|
+
if (process.platform !== "darwin")
|
|
8604
|
+
return yield* Effect34.fail(
|
|
8605
|
+
new Error("the watcher window is available on macOS and Windows")
|
|
8606
|
+
);
|
|
8607
|
+
if (input.dmg === void 0 && input.app === void 0)
|
|
8608
|
+
return yield* Effect34.fail(
|
|
8609
|
+
new Error("pass --dmg <file.dmg> or --app <Braven.app>")
|
|
8610
|
+
);
|
|
8611
|
+
const destination = destinationOf(input);
|
|
8612
|
+
if (input.app !== void 0) {
|
|
8613
|
+
yield* copyApp(resolve(input.app), destination);
|
|
8614
|
+
} else {
|
|
8615
|
+
const mount = mkdtempSync(join10(tmpdir(), "braven-dmg-"));
|
|
8616
|
+
yield* Effect34.ensuring(
|
|
8617
|
+
Effect34.gen(function* () {
|
|
8618
|
+
yield* run("hdiutil", [
|
|
8619
|
+
"attach",
|
|
8620
|
+
"-nobrowse",
|
|
8621
|
+
"-readonly",
|
|
8622
|
+
"-mountpoint",
|
|
8623
|
+
mount,
|
|
8624
|
+
resolve(input.dmg)
|
|
8625
|
+
]);
|
|
8626
|
+
yield* copyApp(join10(mount, "Braven.app"), destination);
|
|
8627
|
+
}),
|
|
8628
|
+
Effect34.sync(() => {
|
|
8629
|
+
void run("hdiutil", ["detach", mount]);
|
|
8630
|
+
rmSync(mount, { recursive: true, force: true });
|
|
8631
|
+
})
|
|
8632
|
+
);
|
|
8633
|
+
}
|
|
8634
|
+
yield* Console8.log(`installed ${destination}`);
|
|
8635
|
+
yield* run("open", [destination]);
|
|
8636
|
+
});
|
|
8637
|
+
|
|
8509
8638
|
// src/cli.ts
|
|
8510
|
-
var VERSION = "0.0.0";
|
|
8639
|
+
var VERSION = true ? "0.1.3" : "0.0.0";
|
|
8511
8640
|
var originFlag = Flag4.String("origin").pipe(
|
|
8512
8641
|
Flag4.optional,
|
|
8513
8642
|
Flag4.withDescription(
|
|
@@ -8558,7 +8687,7 @@ var login2 = Command4.make(
|
|
|
8558
8687
|
),
|
|
8559
8688
|
email: emailFlag
|
|
8560
8689
|
},
|
|
8561
|
-
|
|
8690
|
+
Effect35.fn(function* ({
|
|
8562
8691
|
origin,
|
|
8563
8692
|
webOrigin,
|
|
8564
8693
|
device,
|
|
@@ -8602,7 +8731,7 @@ var keyAddCommand = Command4.make(
|
|
|
8602
8731
|
),
|
|
8603
8732
|
origin: originFlag
|
|
8604
8733
|
},
|
|
8605
|
-
|
|
8734
|
+
Effect35.fn(function* ({ key: key2, email, label, origin }) {
|
|
8606
8735
|
const environment = yield* Environment;
|
|
8607
8736
|
yield* keyAdd({
|
|
8608
8737
|
origin: resolveOrigin(origin, environment),
|
|
@@ -8645,7 +8774,7 @@ var pushCommand2 = Command4.make(
|
|
|
8645
8774
|
)
|
|
8646
8775
|
)
|
|
8647
8776
|
},
|
|
8648
|
-
|
|
8777
|
+
Effect35.fn(function* ({ file, override, path, projectId }) {
|
|
8649
8778
|
yield* push2({ file, override, path, projectId });
|
|
8650
8779
|
})
|
|
8651
8780
|
).pipe(
|
|
@@ -8664,14 +8793,14 @@ var configSetCommand = Command4.make(
|
|
|
8664
8793
|
name: Argument4.Literals("name", ["company", "project"]),
|
|
8665
8794
|
value: Argument4.String("value")
|
|
8666
8795
|
},
|
|
8667
|
-
|
|
8796
|
+
Effect35.fn(function* ({ name, value: value3 }) {
|
|
8668
8797
|
yield* configSet({ name, value: value3 });
|
|
8669
8798
|
})
|
|
8670
8799
|
).pipe(Command4.withDescription("set a default"));
|
|
8671
8800
|
var configUseCommand = Command4.make(
|
|
8672
8801
|
"use",
|
|
8673
8802
|
{ email: Argument4.String("email") },
|
|
8674
|
-
|
|
8803
|
+
Effect35.fn(function* ({ email }) {
|
|
8675
8804
|
yield* configUse(email);
|
|
8676
8805
|
})
|
|
8677
8806
|
).pipe(Command4.withDescription("switch the current account"));
|
|
@@ -8688,7 +8817,7 @@ var configCommand = Command4.make("config", {}, () => configShow()).pipe(
|
|
|
8688
8817
|
var logoutCommand = Command4.make(
|
|
8689
8818
|
"logout",
|
|
8690
8819
|
{ email: emailFlag },
|
|
8691
|
-
|
|
8820
|
+
Effect35.fn(function* ({ email }) {
|
|
8692
8821
|
yield* logout(email);
|
|
8693
8822
|
})
|
|
8694
8823
|
).pipe(
|
|
@@ -8713,14 +8842,57 @@ var mcpInstallCommand = Command4.make(
|
|
|
8713
8842
|
Flag4.withDescription("write this file instead of the client's default")
|
|
8714
8843
|
)
|
|
8715
8844
|
},
|
|
8716
|
-
|
|
8845
|
+
Effect35.fn(function* ({ client, force, path }) {
|
|
8717
8846
|
yield* installCommand({ client, force, path });
|
|
8718
8847
|
})
|
|
8719
8848
|
).pipe(
|
|
8720
8849
|
Command4.withDescription(
|
|
8721
|
-
"merge the Braven server into a client's MCP config (Claude, Cursor, Zed, VS Code)"
|
|
8850
|
+
"merge the Braven server into a client's MCP config (Claude, Cursor, opencode, Zed, VS Code)"
|
|
8722
8851
|
)
|
|
8723
8852
|
);
|
|
8853
|
+
var desktopInstallCommand = Command4.make(
|
|
8854
|
+
"install",
|
|
8855
|
+
{
|
|
8856
|
+
dmg: Flag4.String("dmg").pipe(
|
|
8857
|
+
Flag4.optional,
|
|
8858
|
+
Flag4.withDescription("a Braven DMG to install")
|
|
8859
|
+
),
|
|
8860
|
+
app: Flag4.String("app").pipe(
|
|
8861
|
+
Flag4.optional,
|
|
8862
|
+
Flag4.withDescription("an already-built Braven.app")
|
|
8863
|
+
),
|
|
8864
|
+
exe: Flag4.String("exe").pipe(
|
|
8865
|
+
Flag4.optional,
|
|
8866
|
+
Flag4.withDescription("a Windows Braven installer (.exe)")
|
|
8867
|
+
),
|
|
8868
|
+
silent: Flag4.Boolean("silent").pipe(
|
|
8869
|
+
Flag4.withDefault(false),
|
|
8870
|
+
Flag4.withDescription("Windows: run the installer without its wizard")
|
|
8871
|
+
),
|
|
8872
|
+
system: Flag4.Boolean("system").pipe(
|
|
8873
|
+
Flag4.withDefault(false),
|
|
8874
|
+
Flag4.withDescription("install into /Applications")
|
|
8875
|
+
),
|
|
8876
|
+
destination: Flag4.String("destination").pipe(
|
|
8877
|
+
Flag4.optional,
|
|
8878
|
+
Flag4.withDescription("install here instead of ~/Applications")
|
|
8879
|
+
)
|
|
8880
|
+
},
|
|
8881
|
+
Effect35.fn(function* ({ dmg, app, exe, silent, system, destination }) {
|
|
8882
|
+
yield* installDesktop({
|
|
8883
|
+
dmg: Option34.getOrUndefined(dmg),
|
|
8884
|
+
app: Option34.getOrUndefined(app),
|
|
8885
|
+
exe: Option34.getOrUndefined(exe),
|
|
8886
|
+
silent,
|
|
8887
|
+
system,
|
|
8888
|
+
destination: Option34.getOrUndefined(destination)
|
|
8889
|
+
});
|
|
8890
|
+
})
|
|
8891
|
+
).pipe(Command4.withDescription("copy the watcher window into Applications"));
|
|
8892
|
+
var desktopCommand = Command4.make("desktop", {}).pipe(
|
|
8893
|
+
Command4.withDescription("the watcher window (macOS)"),
|
|
8894
|
+
Command4.withSubcommands([desktopInstallCommand])
|
|
8895
|
+
);
|
|
8724
8896
|
var mcpCommand = Command4.make("mcp", {}, () => runMcp(VERSION)).pipe(
|
|
8725
8897
|
Command4.withDescription(
|
|
8726
8898
|
"run the Braven MCP server over stdio (connect Claude, Cursor, or Zed here)"
|
|
@@ -8738,6 +8910,7 @@ var braven = Command4.make("braven").pipe(
|
|
|
8738
8910
|
pushCommand2,
|
|
8739
8911
|
agentCommand,
|
|
8740
8912
|
mcpCommand,
|
|
8913
|
+
desktopCommand,
|
|
8741
8914
|
whoamiCommand,
|
|
8742
8915
|
configCommand,
|
|
8743
8916
|
logoutCommand
|
|
@@ -8783,15 +8956,15 @@ var describe = (error) => Match11.value(error).pipe(
|
|
|
8783
8956
|
})),
|
|
8784
8957
|
Match11.orElse((other) => ({ code: EXIT_USAGE, message: other.message }))
|
|
8785
8958
|
);
|
|
8786
|
-
var main =
|
|
8959
|
+
var main = Effect35.fn("braven")(function* (args) {
|
|
8787
8960
|
return yield* runCli(args).pipe(
|
|
8788
|
-
|
|
8789
|
-
|
|
8961
|
+
Effect35.as(0),
|
|
8962
|
+
Effect35.catch((error) => {
|
|
8790
8963
|
const described = describe(error);
|
|
8791
|
-
if (described.code === 0) return
|
|
8792
|
-
if (described.message.length === 0) return
|
|
8793
|
-
return
|
|
8794
|
-
|
|
8964
|
+
if (described.code === 0) return Effect35.succeed(0);
|
|
8965
|
+
if (described.message.length === 0) return Effect35.succeed(described.code);
|
|
8966
|
+
return Console9.error(`braven: ${oneLine2(described.message)}`).pipe(
|
|
8967
|
+
Effect35.as(described.code)
|
|
8795
8968
|
);
|
|
8796
8969
|
})
|
|
8797
8970
|
);
|