runtrim 0.1.10 → 0.1.11

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.
Files changed (2) hide show
  1. package/dist-cli/runtrim.js +121 -92
  2. package/package.json +1 -1
@@ -5182,7 +5182,7 @@ program.command("prepare <task>").description("Prepare a guarded prompt without
5182
5182
  }
5183
5183
  );
5184
5184
  program.command("go <task>").description("Bridge Mode: generate a scoped contract, write protocol files, and prepare the guarded prompt").option("--no-clipboard", "Print prompt to terminal instead of copying to clipboard").option("--no-sync", "Skip cloud sync even if a CLI token is configured").option("--no-bridge", "Skip bridge file writing (RUNTRIM.md, contracts, memory)").option("--print", "Always print the prompt to terminal in addition to copying").option("--monitor", "Open local panel monitor in the background (best effort)").action(async (task, options) => {
5185
- var _a2, _b, _c, _d, _e, _f, _g;
5185
+ var _a2, _b, _c, _d, _e;
5186
5186
  const cwd = process.cwd();
5187
5187
  const allowed = await ensureRepoAllowedForFree(cwd);
5188
5188
  if (!allowed) return;
@@ -5289,33 +5289,19 @@ program.command("go <task>").description("Bridge Mode: generate a scoped contrac
5289
5289
  const copied = doCopy ? await copyToClipboardSafe(fullPrompt) : false;
5290
5290
  if (options.monitor) void tryLaunchPanelMonitorDetached(cwd);
5291
5291
  updateRun(run.id, { bridgeManagedFiles: bridgeManagedPaths }, cwd);
5292
- let synced = false;
5292
+ let cloudSync = { status: "skipped_no_token" };
5293
5293
  if (options.sync !== false) {
5294
- const globalAuth2 = loadGlobalAuth();
5295
- const rawToken2 = (_f = (_e = globalAuth2 == null ? void 0 : globalAuth2.token) != null ? _e : config.syncToken) != null ? _f : null;
5296
- if (rawToken2 == null ? void 0 : rawToken2.startsWith("rt_live_")) {
5297
- try {
5298
- const freshRuns = loadAllRuns(cwd);
5299
- const payload = buildSyncPayload({
5300
- cwd,
5301
- projectName,
5302
- config,
5303
- projectAudit: projectAudit != null ? projectAudit : null,
5304
- memoryMarkdown: memoryMarkdown != null ? memoryMarkdown : "",
5305
- runs: freshRuns
5306
- });
5307
- const apiBase2 = resolveApiBase(config);
5308
- const r = await fetch(`${apiBase2}/api/sync`, {
5309
- method: "POST",
5310
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${rawToken2}` },
5311
- body: JSON.stringify(payload)
5312
- });
5313
- synced = r.ok;
5314
- } catch (e) {
5315
- }
5316
- }
5294
+ cloudSync = await syncRunsToCloud({
5295
+ cwd,
5296
+ config,
5297
+ projectName,
5298
+ projectAudit: projectAudit != null ? projectAudit : null,
5299
+ memoryMarkdown: memoryMarkdown != null ? memoryMarkdown : "",
5300
+ runs: loadAllRuns(cwd),
5301
+ markPendingRunIds: [run.id]
5302
+ });
5317
5303
  }
5318
- const riskColor = (_g = { low: chalk.green, medium: chalk.yellow, high: chalk.hex("#FF8C00"), critical: chalk.red }[bridgeCtx.riskLevel]) != null ? _g : chalk.white;
5304
+ const riskColor = (_e = { low: chalk.green, medium: chalk.yellow, high: chalk.hex("#FF8C00"), critical: chalk.red }[bridgeCtx.riskLevel]) != null ? _e : chalk.white;
5319
5305
  console.log("");
5320
5306
  console.log(GO_ACCENT.bold("RunTrim go"));
5321
5307
  console.log("");
@@ -5345,7 +5331,15 @@ program.command("go <task>").description("Bridge Mode: generate a scoped contrac
5345
5331
  }
5346
5332
  if (options.sync !== false) {
5347
5333
  console.log(GO_ACCENT.bold("Cloud sync"));
5348
- console.log(DIM(" ") + (synced ? chalk.white("Synced.") : DIM("Skipped. Run runtrim login to connect your dashboard.")));
5334
+ if (cloudSync.status === "synced") {
5335
+ console.log(chalk.white(" Started run synced."));
5336
+ } else if (cloudSync.status === "failed") {
5337
+ console.log(chalk.yellow(" Failed. Run saved locally. Use runtrim sync later."));
5338
+ } else if (cloudSync.status === "skipped_no_token" || cloudSync.status === "skipped_invalid_token") {
5339
+ console.log(DIM(" Skipped. Run runtrim login to connect your dashboard."));
5340
+ } else {
5341
+ console.log(DIM(" Skipped."));
5342
+ }
5349
5343
  console.log("");
5350
5344
  }
5351
5345
  console.log(GO_ACCENT.bold("Prompt"));
@@ -6266,6 +6260,54 @@ function resolveApiBase(config) {
6266
6260
  return "https://www.runtrim.com";
6267
6261
  }
6268
6262
  }
6263
+ async function syncRunsToCloud(input) {
6264
+ var _a2, _b, _c;
6265
+ const { cwd, config, projectName, projectAudit, memoryMarkdown, runs, markPendingRunIds } = input;
6266
+ const globalAuth = loadGlobalAuth();
6267
+ const rawToken = (_b = (_a2 = globalAuth == null ? void 0 : globalAuth.token) != null ? _a2 : config.syncToken) != null ? _b : null;
6268
+ if (!rawToken) return { status: "skipped_no_token" };
6269
+ if (!rawToken.startsWith("rt_live_")) return { status: "skipped_invalid_token" };
6270
+ if (runs.length === 0) return { status: "skipped_no_runs" };
6271
+ try {
6272
+ const payload = buildSyncPayload({
6273
+ cwd,
6274
+ projectName,
6275
+ config,
6276
+ projectAudit: projectAudit != null ? projectAudit : null,
6277
+ memoryMarkdown: memoryMarkdown != null ? memoryMarkdown : "",
6278
+ runs
6279
+ });
6280
+ const apiBase = resolveApiBase(config);
6281
+ const res = await fetch(`${apiBase}/api/sync`, {
6282
+ method: "POST",
6283
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${rawToken}` },
6284
+ body: JSON.stringify(payload)
6285
+ });
6286
+ const body = await res.json().catch(() => ({}));
6287
+ if (!res.ok || !body.ok) {
6288
+ if (markPendingRunIds && markPendingRunIds.length > 0) {
6289
+ for (const id of markPendingRunIds) updateRun(id, { pendingSync: true }, cwd);
6290
+ }
6291
+ return {
6292
+ status: "failed",
6293
+ error: body.error,
6294
+ details: body.details
6295
+ };
6296
+ }
6297
+ for (const run of runs) {
6298
+ if (run.pendingSync) updateRun(run.id, { pendingSync: false }, cwd);
6299
+ }
6300
+ return {
6301
+ status: "synced",
6302
+ syncedRuns: (_c = body.syncedRuns) != null ? _c : payload.runs.length
6303
+ };
6304
+ } catch (e) {
6305
+ if (markPendingRunIds && markPendingRunIds.length > 0) {
6306
+ for (const id of markPendingRunIds) updateRun(id, { pendingSync: true }, cwd);
6307
+ }
6308
+ return { status: "failed" };
6309
+ }
6310
+ }
6269
6311
  program.command("login").description("Connect this machine to your RunTrim cloud account").option("--token <token>", "CLI token (skip interactive prompt)").action(async (opts) => {
6270
6312
  var _a2, _b, _c, _d, _e;
6271
6313
  console.log("");
@@ -6337,7 +6379,7 @@ program.command("login").description("Connect this machine to your RunTrim cloud
6337
6379
  console.log("");
6338
6380
  });
6339
6381
  program.command("finish").description("Bridge Mode: evaluate agent output, check scope, mark run completed, and sync").option("--no-sync", "Skip cloud sync even if a CLI token is configured").action(async (options) => {
6340
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
6382
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
6341
6383
  const cwd = process.cwd();
6342
6384
  console.log("");
6343
6385
  console.log(GO_ACCENT.bold("RunTrim finish"));
@@ -6450,41 +6492,28 @@ program.command("finish").description("Bridge Mode: evaluate agent output, check
6450
6492
  const bridgeRemovals = [];
6451
6493
  if (removeBridgeBlock(path10.join(cwd, "CLAUDE.md"))) bridgeRemovals.push("CLAUDE.md");
6452
6494
  if (removeBridgeBlock(path10.join(cwd, "AGENTS.md"))) bridgeRemovals.push("AGENTS.md");
6453
- let synced = false;
6495
+ let cloudSync = { status: "skipped_no_token" };
6454
6496
  if (options.sync !== false) {
6455
- const globalAuth = loadGlobalAuth();
6456
- const rawToken = (_m = (_l = globalAuth == null ? void 0 : globalAuth.token) != null ? _l : config.syncToken) != null ? _m : null;
6457
- if (rawToken == null ? void 0 : rawToken.startsWith("rt_live_")) {
6497
+ const memoryMarkdown = (() => {
6458
6498
  try {
6459
- const memoryMarkdown = (() => {
6460
- try {
6461
- return readMemory(cwd);
6462
- } catch (e) {
6463
- return null;
6464
- }
6465
- })();
6466
- const payload = buildSyncPayload({
6467
- cwd,
6468
- projectName,
6469
- config,
6470
- projectAudit: projectAudit != null ? projectAudit : null,
6471
- memoryMarkdown: memoryMarkdown != null ? memoryMarkdown : "",
6472
- runs: freshRuns
6473
- });
6474
- const apiBase = resolveApiBase(config);
6475
- const r = await fetch(`${apiBase}/api/sync`, {
6476
- method: "POST",
6477
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${rawToken}` },
6478
- body: JSON.stringify(payload)
6479
- });
6480
- synced = r.ok;
6499
+ return readMemory(cwd);
6481
6500
  } catch (e) {
6501
+ return null;
6482
6502
  }
6483
- }
6503
+ })();
6504
+ cloudSync = await syncRunsToCloud({
6505
+ cwd,
6506
+ config,
6507
+ projectName,
6508
+ projectAudit: projectAudit != null ? projectAudit : null,
6509
+ memoryMarkdown: memoryMarkdown != null ? memoryMarkdown : "",
6510
+ runs: freshRuns,
6511
+ markPendingRunIds: [activeRun.id]
6512
+ });
6484
6513
  }
6485
6514
  const scopeColor = scopeDriftStatus === "passed" ? chalk.green : scopeDriftStatus === "forbidden_touched" ? chalk.red : chalk.yellow;
6486
- const riskAfter = (_n = activeRun.contract.wasteRiskAfter) != null ? _n : "medium";
6487
- const riskColor = (_o = { low: chalk.green, medium: chalk.yellow, high: chalk.hex("#FF8C00"), critical: chalk.red }[riskAfter]) != null ? _o : chalk.white;
6515
+ const riskAfter = (_l = activeRun.contract.wasteRiskAfter) != null ? _l : "medium";
6516
+ const riskColor = (_m = { low: chalk.green, medium: chalk.yellow, high: chalk.hex("#FF8C00"), critical: chalk.red }[riskAfter]) != null ? _m : chalk.white;
6488
6517
  console.log(GO_ACCENT.bold("Run"));
6489
6518
  console.log(chalk.white(" " + truncate(activeRun.task, 70)));
6490
6519
  console.log("");
@@ -6537,7 +6566,15 @@ program.command("finish").description("Bridge Mode: evaluate agent output, check
6537
6566
  }
6538
6567
  if (options.sync !== false) {
6539
6568
  console.log(GO_ACCENT.bold("Cloud sync"));
6540
- console.log(DIM(" ") + (synced ? chalk.white("Completed.") : DIM("Skipped. Run runtrim login to connect your dashboard.")));
6569
+ if (cloudSync.status === "synced") {
6570
+ console.log(chalk.white(" Completed run synced."));
6571
+ } else if (cloudSync.status === "failed") {
6572
+ console.log(chalk.yellow(" Failed. Run saved locally. Use runtrim sync later."));
6573
+ } else if (cloudSync.status === "skipped_no_token" || cloudSync.status === "skipped_invalid_token") {
6574
+ console.log(DIM(" Skipped. Run runtrim login to connect your dashboard."));
6575
+ } else {
6576
+ console.log(DIM(" Skipped."));
6577
+ }
6541
6578
  console.log("");
6542
6579
  }
6543
6580
  console.log(GO_ACCENT.bold("Protocol"));
@@ -6552,26 +6589,12 @@ program.command("finish").description("Bridge Mode: evaluate agent output, check
6552
6589
  console.log("");
6553
6590
  });
6554
6591
  program.command("sync").description("Sync local run history and project memory to your RunTrim dashboard").option("--dry-run", "Show what would be synced without uploading").action(async (opts) => {
6555
- var _a2, _b, _c, _d, _e, _f;
6592
+ var _a2, _b;
6556
6593
  const cwd = process.cwd();
6557
6594
  console.log("");
6558
6595
  console.log(BOLD("RunTrim") + DIM(" cloud sync"));
6559
6596
  console.log("");
6560
- const globalAuth = loadGlobalAuth();
6561
6597
  const config = configExists(cwd) ? loadConfig(cwd) : DEFAULT_CONFIG;
6562
- const rawToken = (_b = (_a2 = globalAuth == null ? void 0 : globalAuth.token) != null ? _a2 : config.syncToken) != null ? _b : null;
6563
- if (!rawToken) {
6564
- console.log(chalk.yellow(" No CLI token found."));
6565
- console.log(DIM(" Run ") + GO_ACCENT("runtrim login") + DIM(" to connect cloud sync."));
6566
- console.log(DIM(" Local CLI still works without a token."));
6567
- console.log("");
6568
- return;
6569
- }
6570
- if (!rawToken.startsWith("rt_live_")) {
6571
- console.log(chalk.yellow(" Stored token format is invalid. Re-run: runtrim login"));
6572
- console.log("");
6573
- return;
6574
- }
6575
6598
  const apiBase = resolveApiBase(config);
6576
6599
  const syncUrl = `${apiBase}/api/sync`;
6577
6600
  const runs = loadAllRuns(cwd);
@@ -6582,6 +6605,7 @@ program.command("sync").description("Sync local run history and project memory t
6582
6605
  return;
6583
6606
  }
6584
6607
  const projectAudit = loadProjectAudit(cwd);
6608
+ const projectName = (_a2 = projectAudit == null ? void 0 : projectAudit.projectName) != null ? _a2 : path10.basename(cwd);
6585
6609
  const memoryMarkdown = (() => {
6586
6610
  try {
6587
6611
  return readMemory(cwd);
@@ -6591,7 +6615,7 @@ program.command("sync").description("Sync local run history and project memory t
6591
6615
  })();
6592
6616
  const payload = buildSyncPayload({
6593
6617
  cwd,
6594
- projectName: (_c = projectAudit == null ? void 0 : projectAudit.projectName) != null ? _c : path10.basename(cwd),
6618
+ projectName,
6595
6619
  config,
6596
6620
  projectAudit: projectAudit != null ? projectAudit : null,
6597
6621
  memoryMarkdown: memoryMarkdown != null ? memoryMarkdown : "",
@@ -6602,41 +6626,46 @@ program.command("sync").description("Sync local run history and project memory t
6602
6626
  console.log(DIM(" API ") + chalk.white(syncUrl));
6603
6627
  console.log("");
6604
6628
  if (opts.dryRun) {
6605
- console.log(ACCENT.bold(" Dry run \u2014 nothing uploaded."));
6629
+ console.log(ACCENT.bold(" Dry run \uFFFD nothing uploaded."));
6606
6630
  console.log("");
6607
6631
  return;
6608
6632
  }
6609
6633
  const spinner = oraFactory({ text: " Syncing...", color: "blue" }).start();
6610
6634
  try {
6611
- const res = await fetch(syncUrl, {
6612
- method: "POST",
6613
- headers: {
6614
- "Content-Type": "application/json",
6615
- Authorization: `Bearer ${rawToken}`
6616
- },
6617
- body: JSON.stringify(payload)
6635
+ const result = await syncRunsToCloud({
6636
+ cwd,
6637
+ config,
6638
+ projectName,
6639
+ projectAudit: projectAudit != null ? projectAudit : null,
6640
+ memoryMarkdown: memoryMarkdown != null ? memoryMarkdown : "",
6641
+ runs
6618
6642
  });
6619
- const body = await res.json();
6620
- if (!res.ok || !body.ok) {
6643
+ if (result.status !== "synced") {
6621
6644
  spinner.fail(" Sync failed.");
6622
6645
  console.log("");
6623
- if (body.error) {
6624
- console.log(chalk.red(" Error: ") + chalk.white(body.error));
6625
- if (res.status === 401) {
6626
- console.log(DIM(" Token may be invalid or expired. Run: runtrim login"));
6627
- }
6646
+ if (result.status === "skipped_no_token") {
6647
+ console.log(chalk.yellow(" No CLI token found."));
6648
+ console.log(DIM(" Run ") + GO_ACCENT("runtrim login") + DIM(" to connect cloud sync."));
6649
+ console.log(DIM(" Local CLI still works without a token."));
6650
+ } else if (result.status === "skipped_invalid_token") {
6651
+ console.log(chalk.yellow(" Stored token format is invalid. Re-run: runtrim login"));
6652
+ } else if (result.error) {
6653
+ console.log(chalk.red(" Error: ") + chalk.white(result.error));
6654
+ if (result.details) console.log(chalk.red(" Details: ") + chalk.white(result.details));
6655
+ } else {
6656
+ console.log(chalk.yellow(" Failed. Run saved locally. Use runtrim sync later."));
6628
6657
  }
6629
6658
  console.log("");
6630
6659
  return;
6631
6660
  }
6632
6661
  spinner.succeed(" Sync complete.");
6633
6662
  console.log("");
6634
- console.log(ACCENT.bold(" Synced") + chalk.white(` ${(_d = body.syncedRuns) != null ? _d : payload.runs.length} run${((_e = body.syncedRuns) != null ? _e : payload.runs.length) === 1 ? "" : "s"}`));
6635
- console.log(DIM(" Project ID ") + chalk.white((_f = body.projectId) != null ? _f : "\u2014"));
6663
+ const syncedRuns = (_b = result.syncedRuns) != null ? _b : payload.runs.length;
6664
+ console.log(ACCENT.bold(" Synced") + chalk.white(` ${syncedRuns} run${syncedRuns === 1 ? "" : "s"}`));
6636
6665
  console.log("");
6637
6666
  console.log(DIM(" View at ") + GO_ACCENT(`${apiBase}/app`));
6638
6667
  console.log("");
6639
- } catch (err) {
6668
+ } catch (e) {
6640
6669
  spinner.fail(" Network error. Check your connection.");
6641
6670
  console.log("");
6642
6671
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runtrim",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "CLI guard layer that scopes AI coding runs before they waste tokens.",
5
5
  "license": "MIT",
6
6
  "author": "RunTrim",