jioogen 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7087,7 +7087,7 @@ var CANONICAL_CONCERNS = [
7087
7087
  // ../contracts/src/execution.ts
7088
7088
  var EXECUTION_SIDECAR_PATH = "tasks/.execution/state.json";
7089
7089
  var EXECUTION_SIDECAR_VERSION = 1;
7090
- var HANDOFF_PROMPT_VERSION = 15;
7090
+ var HANDOFF_PROMPT_VERSION = 16;
7091
7091
  var HANDOFF_AGENT_TOKEN_TTL_SECONDS = 30 * 24 * 3600;
7092
7092
  var HandoffPayloadSchema = external_exports.object({
7093
7093
  promptVersion: external_exports.literal(HANDOFF_PROMPT_VERSION),
@@ -9203,6 +9203,28 @@ async function pullCommand(projectId, options) {
9203
9203
  `Skills eksekusi terpasang: ${skills.written.length} file (AGENTS.md + 4 harness skill).`
9204
9204
  );
9205
9205
  }
9206
+ async function linkCommand(projectId, options) {
9207
+ const { apiUrl, client } = await resolveApi(options);
9208
+ const target = resolve4(options.dir ?? process.cwd());
9209
+ await assertLinkTarget(target, projectId);
9210
+ await verifyProjectAccess(client, projectId);
9211
+ await writeProjectLink(target, { projectId, apiUrl });
9212
+ const skills = await installAgentSkills(target);
9213
+ const linkedFile = join6(target, ".jioogen", "project.json");
9214
+ if (options.json === true) {
9215
+ console.log(
9216
+ JSON.stringify(
9217
+ { projectId, target, apiUrl, linkedFile, skills: skills.written.length },
9218
+ null,
9219
+ 2
9220
+ )
9221
+ );
9222
+ return;
9223
+ }
9224
+ console.log(`Project ${projectId} ter-bind ke ${target}.`);
9225
+ console.log(`File link: ${linkedFile} (API ${apiUrl}).`);
9226
+ console.log(`Skills eksekusi terpasang: ${skills.written.length} file.`);
9227
+ }
9206
9228
  async function skillsInstallCommand(options) {
9207
9229
  const link = await findProjectLink(options.dir ?? process.cwd());
9208
9230
  const bundleDir = resolve4(link?.bundleDir ?? options.dir ?? process.cwd());
@@ -9489,6 +9511,48 @@ async function assertPullTarget(target, projectId) {
9489
9511
  throw new Error(`Direktori ${target} terikat ke project ${link.projectId}.`);
9490
9512
  }
9491
9513
  }
9514
+ async function assertLinkTarget(target, projectId) {
9515
+ if (!await hasBundleMarkers(target)) {
9516
+ throw new Error(
9517
+ `Direktori ${target} tidak berisi bundle JiooGen (butuh PRD.md atau tasks/*.md). Jalankan \`jioogen pull ${projectId} --dir <dir-kosong>\` untuk mengunduh bundle baru.`
9518
+ );
9519
+ }
9520
+ const link = await findProjectLink(target);
9521
+ if (link !== null && link.projectId !== projectId) {
9522
+ throw new Error(
9523
+ `Direktori ${target} sudah terikat ke project ${link.projectId}. Hapus .jioogen/project.json di sana atau pilih --dir lain.`
9524
+ );
9525
+ }
9526
+ }
9527
+ async function hasBundleMarkers(target) {
9528
+ try {
9529
+ await readFile6(join6(target, "PRD.md"));
9530
+ return true;
9531
+ } catch (error) {
9532
+ if (!isMissingFile4(error)) throw error;
9533
+ }
9534
+ return hasTaskMarkdown(join6(target, "tasks"));
9535
+ }
9536
+ async function hasTaskMarkdown(directory) {
9537
+ let names;
9538
+ try {
9539
+ names = await readdir3(directory);
9540
+ } catch (error) {
9541
+ if (isMissingFile4(error)) return false;
9542
+ throw error;
9543
+ }
9544
+ return names.some((name) => name.toLowerCase().endsWith(".md"));
9545
+ }
9546
+ async function verifyProjectAccess(client, projectId) {
9547
+ try {
9548
+ await client.getJson(projectPath(projectId, "/execution"));
9549
+ } catch (error) {
9550
+ if (error instanceof ApiError && error.status === 404) {
9551
+ throw new Error(`Project ${projectId} tidak ditemukan atau bukan milik akun ini.`);
9552
+ }
9553
+ throw error;
9554
+ }
9555
+ }
9492
9556
  function assertBundleRelative(path) {
9493
9557
  const normalized = path.replace(/\\/g, "/");
9494
9558
  if (normalized.startsWith("/") || normalized.split("/").some((part) => part === ".." || part.length === 0)) {
@@ -9541,7 +9605,7 @@ function isMissingFile4(error) {
9541
9605
  }
9542
9606
 
9543
9607
  // src/index.ts
9544
- var VERSION = "0.2.0";
9608
+ var VERSION = "0.2.1";
9545
9609
  var USAGE = `jioogen \u2014 CLI JiooGen (task selection lokal, server read-only)
9546
9610
 
9547
9611
  Usage:
@@ -9551,6 +9615,7 @@ Usage:
9551
9615
  jioogen whoami
9552
9616
  jioogen projects
9553
9617
  jioogen pull <projectId> [--dir <dir>]
9618
+ jioogen link <projectId> [--dir <dir>]
9554
9619
  jioogen skills install [--dir <dir>]
9555
9620
  jioogen check [--dir <dir>] [--json]
9556
9621
  jioogen handoff [--project <id>] [--json]
@@ -9667,6 +9732,12 @@ async function dispatch(command, rest, options) {
9667
9732
  await pullCommand(projectId, options);
9668
9733
  return;
9669
9734
  }
9735
+ case "link": {
9736
+ const projectId = rest[0];
9737
+ if (projectId === void 0) throw new UsageError("`jioogen link` butuh <projectId>.");
9738
+ await linkCommand(projectId, options);
9739
+ return;
9740
+ }
9670
9741
  case "skills":
9671
9742
  await dispatchSkills(rest, options);
9672
9743
  return;