jioogen 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -363,9 +363,9 @@ var require_utils = __commonJS({
363
363
  fpath.split(self.sep).forEach(function(name) {
364
364
  if (!name || name.substr(-1, 1) === ":") return;
365
365
  resolvedPath += self.sep + name;
366
- var stat;
366
+ var stat2;
367
367
  try {
368
- stat = self.fs.statSync(resolvedPath);
368
+ stat2 = self.fs.statSync(resolvedPath);
369
369
  } catch (e) {
370
370
  if (e.message && e.message.startsWith("ENOENT")) {
371
371
  self.fs.mkdirSync(resolvedPath);
@@ -373,7 +373,7 @@ var require_utils = __commonJS({
373
373
  throw e;
374
374
  }
375
375
  }
376
- if (stat && stat.isFile()) throw Errors.FILE_IN_THE_WAY(`"${resolvedPath}"`);
376
+ if (stat2 && stat2.isFile()) throw Errors.FILE_IN_THE_WAY(`"${resolvedPath}"`);
377
377
  });
378
378
  }
379
379
  mkdirSync(folder);
@@ -382,8 +382,8 @@ var require_utils = __commonJS({
382
382
  const self = this;
383
383
  if (self.fs.existsSync(path)) {
384
384
  if (!overwrite) return false;
385
- var stat = self.fs.statSync(path);
386
- if (stat.isDirectory()) {
385
+ var stat2 = self.fs.statSync(path);
386
+ if (stat2.isDirectory()) {
387
387
  return false;
388
388
  }
389
389
  }
@@ -416,8 +416,8 @@ var require_utils = __commonJS({
416
416
  const self = this;
417
417
  self.fs.exists(path, function(exist) {
418
418
  if (exist && !overwrite) return callback(false);
419
- self.fs.stat(path, function(err, stat) {
420
- if (exist && stat && stat.isDirectory()) {
419
+ self.fs.stat(path, function(err, stat2) {
420
+ if (exist && stat2 && stat2.isDirectory()) {
421
421
  return callback(false);
422
422
  }
423
423
  var folder = pth.dirname(path);
@@ -469,13 +469,13 @@ var require_utils = __commonJS({
469
469
  for (const part of rel.split(pth.sep)) {
470
470
  if (!part || part === ".") continue;
471
471
  cur = pth.join(cur, part);
472
- let stat;
472
+ let stat2;
473
473
  try {
474
- stat = self.fs.lstatSync(cur);
474
+ stat2 = self.fs.lstatSync(cur);
475
475
  } catch (e) {
476
476
  break;
477
477
  }
478
- if (stat.isSymbolicLink()) throw Errors.FILE_IN_THE_WAY(`"${cur}"`);
478
+ if (stat2.isSymbolicLink()) throw Errors.FILE_IN_THE_WAY(`"${cur}"`);
479
479
  }
480
480
  };
481
481
  Utils.prototype.findFiles = function(path) {
@@ -502,11 +502,11 @@ var require_utils = __commonJS({
502
502
  self.fs.readdirSync(dir).forEach(function(file) {
503
503
  const path2 = pth.join(dir, file);
504
504
  if (escapesRoot(path2)) return;
505
- const stat = self.fs.statSync(path2);
505
+ const stat2 = self.fs.statSync(path2);
506
506
  if (!pattern || pattern.test(path2)) {
507
- files.push(pth.normalize(path2) + (stat.isDirectory() ? self.sep : ""));
507
+ files.push(pth.normalize(path2) + (stat2.isDirectory() ? self.sep : ""));
508
508
  }
509
- if (stat.isDirectory() && recursive) {
509
+ if (stat2.isDirectory() && recursive) {
510
510
  const realDir = self.fs.realpathSync(path2);
511
511
  if (!visited.has(realDir)) {
512
512
  visited.add(realDir);
@@ -553,14 +553,14 @@ var require_utils = __commonJS({
553
553
  if (!--pending) done();
554
554
  return;
555
555
  }
556
- self.fs.stat(file, function(err3, stat) {
556
+ self.fs.stat(file, function(err3, stat2) {
557
557
  if (err3) return done(err3);
558
- if (!stat) {
558
+ if (!stat2) {
559
559
  if (!--pending) done();
560
560
  return;
561
561
  }
562
- results.push(pth.normalize(file) + (stat.isDirectory() ? self.sep : ""));
563
- if (!stat.isDirectory()) {
562
+ results.push(pth.normalize(file) + (stat2.isDirectory() ? self.sep : ""));
563
+ if (!stat2.isDirectory()) {
564
564
  if (!--pending) done();
565
565
  return;
566
566
  }
@@ -8433,8 +8433,11 @@ function envValue(name) {
8433
8433
  const value = process.env[name]?.trim();
8434
8434
  return value !== void 0 && value.length > 0 ? value : void 0;
8435
8435
  }
8436
+ function configDirOverride() {
8437
+ return envValue(CONFIG_DIR_ENV) ?? envValue(LEGACY_CONFIG_DIR_ENV);
8438
+ }
8436
8439
  function configDir() {
8437
- const override = envValue(CONFIG_DIR_ENV) ?? envValue(LEGACY_CONFIG_DIR_ENV);
8440
+ const override = configDirOverride();
8438
8441
  return override !== void 0 ? resolve(override) : join2(homedir(), ".config", "jioogen");
8439
8442
  }
8440
8443
  function legacyConfigDir() {
@@ -8474,6 +8477,7 @@ async function readCredentialsFile(path) {
8474
8477
  async function readCredentials() {
8475
8478
  const primary = await readCredentialsFile(credentialsPath());
8476
8479
  if (primary !== null) return primary;
8480
+ if (configDirOverride() !== void 0) return null;
8477
8481
  const legacyPath = join2(legacyConfigDir(), CREDENTIALS_FILE);
8478
8482
  if (legacyPath === credentialsPath()) return null;
8479
8483
  return readCredentialsFile(legacyPath);
@@ -8558,6 +8562,10 @@ function isMissingFile(error) {
8558
8562
  return isRecord(error) && error.code === "ENOENT";
8559
8563
  }
8560
8564
 
8565
+ // src/errors.ts
8566
+ var UsageError = class extends Error {
8567
+ };
8568
+
8561
8569
  // src/output.ts
8562
8570
  function formatTable(headers, rows) {
8563
8571
  const widths = headers.map(
@@ -8569,11 +8577,52 @@ function formatTable(headers, rows) {
8569
8577
  }
8570
8578
 
8571
8579
  // src/sidecar.ts
8572
- import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
8580
+ import { randomUUID } from "node:crypto";
8581
+ import { mkdir as mkdir2, open, readFile as readFile3, rename, rm as rm2, stat, writeFile as writeFile2 } from "node:fs/promises";
8573
8582
  import { dirname as dirname2, join as join3 } from "node:path";
8583
+ var LOCK_RETRY_MS = 25;
8584
+ var LOCK_TIMEOUT_MS = 3e3;
8585
+ var LOCK_STALE_MS = 1e4;
8574
8586
  function sidecarPath(bundleDir) {
8575
8587
  return join3(bundleDir, EXECUTION_SIDECAR_PATH);
8576
8588
  }
8589
+ function lockPath(bundleDir) {
8590
+ return `${sidecarPath(bundleDir)}.lock`;
8591
+ }
8592
+ async function withStateLock(bundleDir, fn) {
8593
+ const target = lockPath(bundleDir);
8594
+ await mkdir2(dirname2(target), { recursive: true });
8595
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
8596
+ let handle = null;
8597
+ let staleRemoved = false;
8598
+ while (handle === null) {
8599
+ try {
8600
+ handle = await open(target, "wx");
8601
+ } catch (error) {
8602
+ if (!isLockBusy(error)) throw error;
8603
+ if (!staleRemoved && await removeStaleLock(target)) {
8604
+ staleRemoved = true;
8605
+ continue;
8606
+ }
8607
+ if (Date.now() >= deadline) {
8608
+ throw new Error(
8609
+ `Gagal mengambil lock sidecar setelah ${LOCK_TIMEOUT_MS / 1e3} detik: ${target}. Kemungkinan proses lain masih menulis; hapus file lock itu bila proses tersebut sudah mati.`
8610
+ );
8611
+ }
8612
+ await delay(LOCK_RETRY_MS);
8613
+ }
8614
+ }
8615
+ try {
8616
+ await handle.writeFile(`${process.pid}
8617
+ `, "utf8");
8618
+ return await fn();
8619
+ } finally {
8620
+ await handle.close().catch(() => {
8621
+ });
8622
+ await rm2(target, { force: true }).catch(() => {
8623
+ });
8624
+ }
8625
+ }
8577
8626
  async function readState(bundleDir) {
8578
8627
  let raw;
8579
8628
  try {
@@ -8662,8 +8711,16 @@ async function writeState(bundleDir, state) {
8662
8711
  const normalized = rebuild(state, state.tasks, state.current);
8663
8712
  const target = sidecarPath(bundleDir);
8664
8713
  await mkdir2(dirname2(target), { recursive: true });
8665
- await writeFile2(target, `${JSON.stringify(normalized, null, 2)}
8714
+ const temp = `${target}.${process.pid}.${randomUUID()}.tmp`;
8715
+ try {
8716
+ await writeFile2(temp, `${JSON.stringify(normalized, null, 2)}
8666
8717
  `, "utf8");
8718
+ await rename(temp, target);
8719
+ } catch (error) {
8720
+ await rm2(temp, { force: true }).catch(() => {
8721
+ });
8722
+ throw error;
8723
+ }
8667
8724
  return normalized;
8668
8725
  }
8669
8726
  function rebuild(state, tasks, current, now = /* @__PURE__ */ new Date()) {
@@ -8690,6 +8747,23 @@ function toTaskState(task) {
8690
8747
  function isMissingFile2(error) {
8691
8748
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
8692
8749
  }
8750
+ function isLockBusy(error) {
8751
+ return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
8752
+ }
8753
+ async function removeStaleLock(target) {
8754
+ try {
8755
+ const info = await stat(target);
8756
+ if (Date.now() - info.mtimeMs < LOCK_STALE_MS) return false;
8757
+ await rm2(target, { force: true });
8758
+ return true;
8759
+ } catch (error) {
8760
+ if (isMissingFile2(error)) return true;
8761
+ throw error;
8762
+ }
8763
+ }
8764
+ function delay(ms) {
8765
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
8766
+ }
8693
8767
 
8694
8768
  // src/skills.ts
8695
8769
  import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile3 } from "node:fs/promises";
@@ -9106,6 +9180,10 @@ async function extractBundle(bytes, targetDir) {
9106
9180
  }
9107
9181
 
9108
9182
  // src/commands.ts
9183
+ var PROJECT_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9184
+ function isValidProjectId(projectId) {
9185
+ return PROJECT_ID_RE.test(projectId.trim());
9186
+ }
9109
9187
  async function loginCommand(options) {
9110
9188
  const token = options.token ?? envFirst("JIOOGEN_TOKEN", "JIOOCODE_TOKEN");
9111
9189
  if (token !== void 0 && token.length > 0) {
@@ -9186,9 +9264,14 @@ async function projectsCommand(options) {
9186
9264
  );
9187
9265
  }
9188
9266
  async function pullCommand(projectId, options) {
9267
+ if (!isValidProjectId(projectId)) {
9268
+ throw new UsageError(
9269
+ `Project id tidak valid: ${projectId}. Gunakan UUID dari \`jioogen projects\`.`
9270
+ );
9271
+ }
9189
9272
  const { apiUrl, client } = await resolveApi(options);
9190
9273
  const target = resolve4(options.dir ?? projectId);
9191
- await assertPullTarget(target, projectId);
9274
+ await assertPullTarget(target, projectId, options.force === true);
9192
9275
  const bytes = await client.getBytes(projectPath(projectId, "/bundle"));
9193
9276
  const written = await extractBundle(bytes, target);
9194
9277
  const skills = await installAgentSkills(target);
@@ -9264,9 +9347,15 @@ async function handoffCommand(options) {
9264
9347
  }
9265
9348
  }
9266
9349
  async function taskNextCommand(options) {
9267
- const { bundleDir, state, definitions, projectId } = await loadLocalState(options);
9268
- const written = await writeState(bundleDir, state);
9269
- const next = selectNext(definitions, written.tasks);
9350
+ const { projectId, definitions, written, next } = await withLocalState(options, async (local) => {
9351
+ const written2 = await writeState(local.bundleDir, local.state);
9352
+ return {
9353
+ projectId: local.projectId,
9354
+ definitions: local.definitions,
9355
+ written: written2,
9356
+ next: selectNext(local.definitions, written2.tasks)
9357
+ };
9358
+ });
9270
9359
  if (next === null) {
9271
9360
  if (options.json === true) {
9272
9361
  console.log(JSON.stringify({ done: true, projectId }, null, 2));
@@ -9315,62 +9404,71 @@ Status: ${next.state.status} \u2014 silakan ulangi.`);
9315
9404
  Progress: ${written.counts?.done ?? 0}/${definitions.length} task selesai.`);
9316
9405
  }
9317
9406
  async function taskStartCommand(ref, options) {
9318
- const { bundleDir, state } = await loadLocalState(options);
9319
- const updated = withStatus(state, ref, "in_progress", {
9320
- awaitingCheckpoint: false,
9321
- note: ""
9407
+ const task = await withLocalState(options, async (local) => {
9408
+ assertStartDependencies(ref, local.definitions, local.state.tasks);
9409
+ const updated = withStatus(local.state, ref, "in_progress", {
9410
+ awaitingCheckpoint: false,
9411
+ note: ""
9412
+ });
9413
+ await writeState(local.bundleDir, updated);
9414
+ return updated.tasks.find((entry) => entry.ref.toUpperCase() === ref.toUpperCase());
9322
9415
  });
9323
- await writeState(bundleDir, updated);
9324
- const task = updated.tasks.find((entry) => entry.ref.toUpperCase() === ref.toUpperCase());
9325
9416
  console.log(`Started ${task?.ref ?? ref} (attempt ${task?.attempt ?? 1}).`);
9326
9417
  }
9327
9418
  async function taskCompleteCommand(ref, options) {
9328
- const { bundleDir, state, definitions } = await loadLocalState(options);
9329
- const completed = withStatus(state, ref, "done", {
9330
- note: options.note ?? "",
9331
- awaitingCheckpoint: false
9332
- });
9333
- const completedTask = completed.tasks.find(
9334
- (entry) => entry.ref.toUpperCase() === ref.toUpperCase()
9335
- );
9336
- const next = selectNext(definitions, completed.tasks);
9337
- if (completedTask !== void 0 && next !== null && isBoundary(completedTask, next.task)) {
9338
- const withCheckpoint = setCurrent(completed, {
9339
- ref: next.task.id,
9340
- ...next.task.layer !== void 0 ? { layer: next.task.layer } : {},
9341
- phase: next.task.phase,
9342
- awaitingCheckpoint: true
9419
+ const { completedTask, next, checkpoint } = await withLocalState(options, async (local) => {
9420
+ assertCompleteDependencies(ref, local.definitions, local.state.tasks, options.force === true);
9421
+ const completed = withStatus(local.state, ref, "done", {
9422
+ note: options.note ?? "",
9423
+ awaitingCheckpoint: false
9343
9424
  });
9344
- await writeState(bundleDir, withCheckpoint);
9345
- console.log(`Done ${completedTask.ref}.`);
9425
+ const completedTask2 = completed.tasks.find(
9426
+ (entry) => entry.ref.toUpperCase() === ref.toUpperCase()
9427
+ );
9428
+ const next2 = selectNext(local.definitions, completed.tasks);
9429
+ if (completedTask2 !== void 0 && next2 !== null && isBoundary(completedTask2, next2.task)) {
9430
+ const withCheckpoint = setCurrent(completed, {
9431
+ ref: next2.task.id,
9432
+ ...next2.task.layer !== void 0 ? { layer: next2.task.layer } : {},
9433
+ phase: next2.task.phase,
9434
+ awaitingCheckpoint: true
9435
+ });
9436
+ await writeState(local.bundleDir, withCheckpoint);
9437
+ return { completedTask: completedTask2, next: next2, checkpoint: true };
9438
+ }
9439
+ await writeState(local.bundleDir, completed);
9440
+ return { completedTask: completedTask2, next: next2, checkpoint: false };
9441
+ });
9442
+ console.log(`Done ${completedTask?.ref ?? ref}.`);
9443
+ if (checkpoint && next !== null) {
9346
9444
  console.log(
9347
9445
  `Checkpoint berikutnya: ${next.task.id} (${next.task.layer ?? "-"} / phase ${next.task.phase}).`
9348
9446
  );
9349
9447
  console.log("Berhenti dan minta konfirmasi user sebelum task start berikutnya.");
9350
9448
  return;
9351
9449
  }
9352
- await writeState(bundleDir, completed);
9353
- console.log(`Done ${completedTask?.ref ?? ref}.`);
9354
9450
  if (next !== null) console.log(`Berikutnya: ${next.task.id} \u2014 ${next.task.title}`);
9355
9451
  }
9356
9452
  async function taskFailCommand(ref, reasonParts, options) {
9357
9453
  const reason = reasonParts.join(" ").trim() || options.note || "";
9358
- const { bundleDir, state } = await loadLocalState(options);
9359
- const updated = withStatus(state, ref, "failed", {
9360
- note: reason,
9361
- awaitingCheckpoint: false
9454
+ await withLocalState(options, async (local) => {
9455
+ const updated = withStatus(local.state, ref, "failed", {
9456
+ note: reason,
9457
+ awaitingCheckpoint: false
9458
+ });
9459
+ await writeState(local.bundleDir, updated);
9362
9460
  });
9363
- await writeState(bundleDir, updated);
9364
9461
  console.log(`Failed ${ref}${reason.length > 0 ? `: ${reason}` : "."}`);
9365
9462
  }
9366
9463
  async function taskResetCommand(ref, reasonParts, options) {
9367
9464
  const reason = reasonParts.join(" ").trim() || options.note || "";
9368
- const { bundleDir, state } = await loadLocalState(options);
9369
- const updated = withStatus(state, ref, "todo", {
9370
- note: reason,
9371
- awaitingCheckpoint: false
9465
+ await withLocalState(options, async (local) => {
9466
+ const updated = withStatus(local.state, ref, "todo", {
9467
+ note: reason,
9468
+ awaitingCheckpoint: false
9469
+ });
9470
+ await writeState(local.bundleDir, updated);
9372
9471
  });
9373
- await writeState(bundleDir, updated);
9374
9472
  console.log(`Reset ${ref} ke todo${reason.length > 0 ? `: ${reason}` : "."}`);
9375
9473
  }
9376
9474
  async function statusCommand(options) {
@@ -9381,6 +9479,23 @@ async function statusCommand(options) {
9381
9479
  const { bundleDir, projectId } = await resolveLocalBundle(options);
9382
9480
  const existing = await readState(bundleDir);
9383
9481
  if (existing === null) {
9482
+ if (options.json === true) {
9483
+ console.log(
9484
+ JSON.stringify(
9485
+ {
9486
+ projectId,
9487
+ hasExecution: false,
9488
+ tasks: [],
9489
+ counts: summarizeExecutionCounts([]),
9490
+ current: null,
9491
+ updatedAt: null
9492
+ },
9493
+ null,
9494
+ 2
9495
+ )
9496
+ );
9497
+ return;
9498
+ }
9384
9499
  console.log(`Project ${projectId}: belum ada sidecar. Jalankan \`jioogen task next\`.`);
9385
9500
  return;
9386
9501
  }
@@ -9487,14 +9602,40 @@ async function resolveBundle(options) {
9487
9602
  const api = await resolveApi({ api: options.api ?? local.linkedApiUrl });
9488
9603
  return { ...api, ...local };
9489
9604
  }
9490
- async function loadLocalState(options) {
9605
+ async function withLocalState(options, fn) {
9491
9606
  const context = await resolveLocalBundle(options);
9492
- const definitions = await loadTasks(context.bundleDir);
9493
- const existing = await readState(context.bundleDir);
9494
- const state = existing === null ? createState(context.projectId, definitions) : mergeTasks(existing, definitions);
9495
- return { ...context, definitions, state };
9607
+ return withStateLock(context.bundleDir, async () => {
9608
+ const definitions = await loadTasks(context.bundleDir);
9609
+ const existing = await readState(context.bundleDir);
9610
+ const state = existing === null ? createState(context.projectId, definitions) : mergeTasks(existing, definitions);
9611
+ return fn({ ...context, definitions, state });
9612
+ });
9496
9613
  }
9497
- async function assertPullTarget(target, projectId) {
9614
+ function unmetDependencies(ref, definitions, states) {
9615
+ const key = ref.toUpperCase();
9616
+ const definition = definitions.find((task) => task.id.toUpperCase() === key);
9617
+ if (definition === void 0) return [];
9618
+ const byRef = new Map(states.map((state) => [state.ref.toUpperCase(), state]));
9619
+ return definition.dependsOn.filter(
9620
+ (dependency) => byRef.get(dependency.toUpperCase())?.status !== "done"
9621
+ );
9622
+ }
9623
+ function assertStartDependencies(ref, definitions, states) {
9624
+ const missing = unmetDependencies(ref, definitions, states);
9625
+ if (missing.length === 0) return;
9626
+ throw new Error(
9627
+ `Tidak bisa memulai ${ref}: dependency belum selesai (${missing.join(", ")}). Selesaikan dependency itu lebih dulu.`
9628
+ );
9629
+ }
9630
+ function assertCompleteDependencies(ref, definitions, states, force) {
9631
+ if (force) return;
9632
+ const missing = unmetDependencies(ref, definitions, states);
9633
+ if (missing.length === 0) return;
9634
+ throw new Error(
9635
+ `Tidak bisa menyelesaikan ${ref}: dependency belum selesai (${missing.join(", ")}). Selesaikan dependency itu lebih dulu, atau tambahkan --force bila memang disengaja.`
9636
+ );
9637
+ }
9638
+ async function assertPullTarget(target, projectId, force = false) {
9498
9639
  let entries;
9499
9640
  try {
9500
9641
  entries = await readdir3(target);
@@ -9510,6 +9651,11 @@ async function assertPullTarget(target, projectId) {
9510
9651
  if (link.projectId !== projectId) {
9511
9652
  throw new Error(`Direktori ${target} terikat ke project ${link.projectId}.`);
9512
9653
  }
9654
+ if (!force) {
9655
+ throw new Error(
9656
+ `Direktori ${target} sudah berisi bundle project ini; pull ulang akan menimpa edit lokal. Jalankan \`jioogen link ${projectId}\` bila hanya ingin mengikat, atau ulangi dengan --force.`
9657
+ );
9658
+ }
9513
9659
  }
9514
9660
  async function assertLinkTarget(target, projectId) {
9515
9661
  if (!await hasBundleMarkers(target)) {
@@ -9605,7 +9751,7 @@ function isMissingFile4(error) {
9605
9751
  }
9606
9752
 
9607
9753
  // src/index.ts
9608
- var VERSION = "0.2.1";
9754
+ var VERSION = "0.2.2";
9609
9755
  var USAGE = `jioogen \u2014 CLI JiooGen (task selection lokal, server read-only)
9610
9756
 
9611
9757
  Usage:
@@ -9614,14 +9760,14 @@ Usage:
9614
9760
  jioogen logout
9615
9761
  jioogen whoami
9616
9762
  jioogen projects
9617
- jioogen pull <projectId> [--dir <dir>]
9763
+ jioogen pull <projectId> [--dir <dir>] [--force]
9618
9764
  jioogen link <projectId> [--dir <dir>]
9619
9765
  jioogen skills install [--dir <dir>]
9620
9766
  jioogen check [--dir <dir>] [--json]
9621
9767
  jioogen handoff [--project <id>] [--json]
9622
9768
  jioogen task next [--json]
9623
9769
  jioogen task start <ref>
9624
- jioogen task complete <ref> [--note <text>]
9770
+ jioogen task complete <ref> [--note <text>] [--force]
9625
9771
  jioogen task fail <ref> [reason...] [--note <text>]
9626
9772
  jioogen task reset <ref> [reason...] [--note <text>]
9627
9773
  jioogen status [--remote] [--json]
@@ -9637,8 +9783,6 @@ Global options:
9637
9783
  -h, --help Tampilkan bantuan
9638
9784
  -v, --version Tampilkan versi
9639
9785
  `;
9640
- var UsageError = class extends Error {
9641
- };
9642
9786
  async function main() {
9643
9787
  let raw = {};
9644
9788
  let positionals = [];
@@ -9655,6 +9799,7 @@ async function main() {
9655
9799
  project: { type: "string" },
9656
9800
  dir: { type: "string" },
9657
9801
  remote: { type: "boolean" },
9802
+ force: { type: "boolean" },
9658
9803
  files: { type: "string" },
9659
9804
  note: { type: "string" },
9660
9805
  json: { type: "boolean" },
@@ -9680,6 +9825,7 @@ async function main() {
9680
9825
  project: text(raw.project),
9681
9826
  dir: text(raw.dir),
9682
9827
  remote: flag(raw.remote),
9828
+ force: flag(raw.force),
9683
9829
  files: text(raw.files),
9684
9830
  note: text(raw.note),
9685
9831
  json: flag(raw.json)