@attalabs/vinaya 0.7.1 → 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/README.md +2 -1
- package/aeg-root/enforcement.md +2 -2
- package/aeg-root/roles/planner.md +2 -2
- package/aeg-root/roles/reviewer.md +1 -1
- package/aeg-root/skills/brief-authoring/SKILL.md +1 -1
- package/aeg-root/state-machine.md +6 -6
- package/aeg-root/tranche-model.md +1 -1
- package/dist/checks/bin/check-branch-topology.js +21 -5
- package/dist/checks/bin/check-brief-shape.js +21 -5
- package/dist/checks/bin/check-closes-n.js +21 -5
- package/dist/checks/bin/check-coherence.js +200 -10
- package/dist/checks/bin/check-dead-branch-push.js +21 -5
- package/dist/checks/bin/check-dispatch-readiness.js +223 -11
- package/dist/checks/bin/check-doc-coverage-push.js +21 -5
- package/dist/checks/bin/check-doc-coverage.js +21 -5
- package/dist/checks/bin/check-first-push-dispatch.js +224 -12
- package/dist/checks/bin/check-issue-assignment.js +21 -5
- package/dist/checks/bin/check-no-disk-state.js +21 -5
- package/dist/checks/bin/check-reader-resolvable-prose.js +21 -5
- package/dist/checks/bin/check-registry-gates.js +21 -5
- package/dist/checks/bin/check-review-gate.js +21 -5
- package/dist/checks/bin/check-single-plan-pr.js +21 -5
- package/dist/checks/bin/check-test-plan.js +21 -5
- package/dist/index.js +188 -24
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { readFileSync as
|
|
5
|
-
import { dirname as
|
|
4
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
5
|
+
import { dirname as dirname8, join as join20 } from "node:path";
|
|
6
6
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7
7
|
|
|
8
8
|
// src/commands/archive.ts
|
|
@@ -332,6 +332,52 @@ var systemEnv3 = {
|
|
|
332
332
|
...process.env,
|
|
333
333
|
PATH: [process.env.PATH, "/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/bin"].filter(Boolean).join(":")
|
|
334
334
|
};
|
|
335
|
+
var defaultExec = () => execFileAsync3("git", ["remote", "get-url", "origin"], { env: systemEnv3, timeout: 5000 });
|
|
336
|
+
var cached;
|
|
337
|
+
var inflight;
|
|
338
|
+
async function resolveRepo(exec = defaultExec) {
|
|
339
|
+
if (cached !== undefined)
|
|
340
|
+
return cached;
|
|
341
|
+
const fromEnv = process.env.AEG_REPO;
|
|
342
|
+
if (fromEnv) {
|
|
343
|
+
const parsed = parseOwnerRepo(fromEnv);
|
|
344
|
+
if (parsed) {
|
|
345
|
+
cached = parsed;
|
|
346
|
+
return cached;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (inflight)
|
|
350
|
+
return inflight;
|
|
351
|
+
inflight = (async () => {
|
|
352
|
+
try {
|
|
353
|
+
const { stdout } = await exec();
|
|
354
|
+
cached = parseGitRemoteUrl(stdout.trim());
|
|
355
|
+
return cached;
|
|
356
|
+
} catch (err) {
|
|
357
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
358
|
+
console.warn(`[aeg-forge-state] resolveRepo: git remote lookup failed (will retry): ${message}`);
|
|
359
|
+
return null;
|
|
360
|
+
} finally {
|
|
361
|
+
inflight = undefined;
|
|
362
|
+
}
|
|
363
|
+
})();
|
|
364
|
+
return inflight;
|
|
365
|
+
}
|
|
366
|
+
function parseGitRemoteUrl(url) {
|
|
367
|
+
const ssh = url.match(/^git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
|
|
368
|
+
if (ssh?.[1] && ssh[2])
|
|
369
|
+
return { owner: ssh[1], repo: ssh[2] };
|
|
370
|
+
const https = url.match(/^https?:\/\/(?:[^@]+@)?github\.com\/([^/]+)\/(.+?)(?:\.git)?\/?$/);
|
|
371
|
+
if (https?.[1] && https[2])
|
|
372
|
+
return { owner: https[1], repo: https[2] };
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
function parseOwnerRepo(value) {
|
|
376
|
+
const match = value.match(/^([^/]+)\/(.+)$/);
|
|
377
|
+
if (!match?.[1] || !match[2])
|
|
378
|
+
return null;
|
|
379
|
+
return { owner: match[1], repo: match[2] };
|
|
380
|
+
}
|
|
335
381
|
// ../../packages/aeg-core/src/state-machine-model.ts
|
|
336
382
|
var FORGE_FACT_INPUTS = [
|
|
337
383
|
{
|
|
@@ -378,6 +424,11 @@ var FORGE_FACT_INPUTS = [
|
|
|
378
424
|
fact: "mergedAt",
|
|
379
425
|
readsFrom: "PullRequest.mergedAt",
|
|
380
426
|
meaning: "Timestamp for the coherence oracle grandfather cutoff. No derivation rule reads it."
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
fact: "closedByActor",
|
|
430
|
+
readsFrom: "ClosedEvent.actor.login (most recent timeline CLOSED_EVENT)",
|
|
431
|
+
meaning: "GitHub login that hand-closed the Issue. No task-status derivation rule reads it — it is consumed by dispatch-gate.ts/coherence-checks.ts A1 to recognize a hand-closed dependency as resolved (task vinaya-engine-v1 21, #99), not by this status model."
|
|
381
432
|
}
|
|
382
433
|
];
|
|
383
434
|
var DERIVED_STATUSES = [
|
|
@@ -880,6 +931,8 @@ import { fileURLToPath } from "node:url";
|
|
|
880
931
|
function packageRoot(moduleUrl) {
|
|
881
932
|
let dir = dirname(fileURLToPath(moduleUrl));
|
|
882
933
|
while (!existsSync(join(dir, "package.json"))) {
|
|
934
|
+
if (existsSync(join(dir, ".git")))
|
|
935
|
+
break;
|
|
883
936
|
const parent = dirname(dir);
|
|
884
937
|
if (parent === dir)
|
|
885
938
|
break;
|
|
@@ -1744,6 +1797,8 @@ function findLocalConfig() {
|
|
|
1744
1797
|
const candidate = join3(dir, LOCAL_CONFIG_FILENAME);
|
|
1745
1798
|
if (existsSync2(candidate))
|
|
1746
1799
|
return candidate;
|
|
1800
|
+
if (existsSync2(join3(dir, ".git")))
|
|
1801
|
+
return null;
|
|
1747
1802
|
const parent = dirname2(dir);
|
|
1748
1803
|
if (parent === dir)
|
|
1749
1804
|
return null;
|
|
@@ -5463,9 +5518,104 @@ async function quickstartCommand(args) {
|
|
|
5463
5518
|
process.exit(await runQuickstart(args, realDeps6()));
|
|
5464
5519
|
}
|
|
5465
5520
|
|
|
5521
|
+
// src/commands/studio.ts
|
|
5522
|
+
import { execFile as execFile5, spawn as spawn2 } from "node:child_process";
|
|
5523
|
+
import { existsSync as existsSync16, readFileSync as readFileSync16, renameSync } from "node:fs";
|
|
5524
|
+
import net from "node:net";
|
|
5525
|
+
import { dirname as dirname7, join as join18 } from "node:path";
|
|
5526
|
+
import { promisify as promisify5 } from "node:util";
|
|
5527
|
+
|
|
5528
|
+
// src/lib/studio-bundle.ts
|
|
5529
|
+
var STUDIO_NODE_MODULES_PACKED_DIRNAME = "_node_modules";
|
|
5530
|
+
|
|
5531
|
+
// src/commands/studio.ts
|
|
5532
|
+
var execFileAsync5 = promisify5(execFile5);
|
|
5533
|
+
function execFileForRepo(cwd) {
|
|
5534
|
+
return execFileAsync5("git", ["remote", "get-url", "origin"], { cwd, timeout: 5000 });
|
|
5535
|
+
}
|
|
5536
|
+
var PRIMARY_PORT = 3006;
|
|
5537
|
+
var FALLBACK_PORT = 3106;
|
|
5538
|
+
function resolveStudioTarget(cwd, moduleUrl = import.meta.url) {
|
|
5539
|
+
let dir = cwd;
|
|
5540
|
+
for (;; ) {
|
|
5541
|
+
const webDir = join18(dir, "apps", "vinaya", "web");
|
|
5542
|
+
const pkgPath = join18(webDir, "package.json");
|
|
5543
|
+
if (existsSync16(pkgPath)) {
|
|
5544
|
+
try {
|
|
5545
|
+
const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
|
|
5546
|
+
if (pkg.name === "@atta/vinaya-web") {
|
|
5547
|
+
return { kind: "workspace", webDir };
|
|
5548
|
+
}
|
|
5549
|
+
} catch {}
|
|
5550
|
+
}
|
|
5551
|
+
if (existsSync16(join18(dir, ".git")))
|
|
5552
|
+
break;
|
|
5553
|
+
const parent = dirname7(dir);
|
|
5554
|
+
if (parent === dir)
|
|
5555
|
+
break;
|
|
5556
|
+
dir = parent;
|
|
5557
|
+
}
|
|
5558
|
+
const standaloneWebDir = join18(packageRoot(moduleUrl), "studio-standalone", "apps", "vinaya", "web");
|
|
5559
|
+
if (existsSync16(join18(standaloneWebDir, "server.js"))) {
|
|
5560
|
+
return { kind: "package", packageDir: standaloneWebDir };
|
|
5561
|
+
}
|
|
5562
|
+
return { kind: "missing" };
|
|
5563
|
+
}
|
|
5564
|
+
function spawnDev(webDir, args) {
|
|
5565
|
+
return new Promise((resolve2) => {
|
|
5566
|
+
const child = spawn2("bun", ["run", "dev", ...args], { cwd: webDir, stdio: "inherit" });
|
|
5567
|
+
child.on("exit", (code) => resolve2(code ?? 0));
|
|
5568
|
+
});
|
|
5569
|
+
}
|
|
5570
|
+
function isPortFree(port) {
|
|
5571
|
+
return new Promise((resolve2) => {
|
|
5572
|
+
const tester = net.createServer();
|
|
5573
|
+
tester.once("error", () => resolve2(false));
|
|
5574
|
+
tester.once("listening", () => tester.close(() => resolve2(true)));
|
|
5575
|
+
tester.listen(port, "127.0.0.1");
|
|
5576
|
+
});
|
|
5577
|
+
}
|
|
5578
|
+
function ensureStudioNodeModules(bundleRoot) {
|
|
5579
|
+
const real = join18(bundleRoot, "node_modules");
|
|
5580
|
+
const packed = join18(bundleRoot, STUDIO_NODE_MODULES_PACKED_DIRNAME);
|
|
5581
|
+
if (!existsSync16(real) && existsSync16(packed)) {
|
|
5582
|
+
renameSync(packed, real);
|
|
5583
|
+
}
|
|
5584
|
+
}
|
|
5585
|
+
async function spawnStandalone(cwd, serverPath, bundleRoot) {
|
|
5586
|
+
ensureStudioNodeModules(bundleRoot);
|
|
5587
|
+
const repo = await resolveRepo(() => execFileForRepo(cwd));
|
|
5588
|
+
const primaryFree = await isPortFree(PRIMARY_PORT);
|
|
5589
|
+
const port = primaryFree ? PRIMARY_PORT : FALLBACK_PORT;
|
|
5590
|
+
if (!primaryFree) {
|
|
5591
|
+
console.info(`[studio] port ${PRIMARY_PORT} is taken — falling back to ${FALLBACK_PORT}`);
|
|
5592
|
+
}
|
|
5593
|
+
const env = { HOSTNAME: "127.0.0.1", ...process.env, PORT: String(port), VINAYA_REPO_ROOT: cwd };
|
|
5594
|
+
if (repo)
|
|
5595
|
+
env.AEG_REPO = `${repo.owner}/${repo.repo}`;
|
|
5596
|
+
return new Promise((resolve2) => {
|
|
5597
|
+
const child = spawn2("node", [serverPath], { cwd, stdio: "inherit", env });
|
|
5598
|
+
child.on("exit", (code) => resolve2(code ?? 0));
|
|
5599
|
+
});
|
|
5600
|
+
}
|
|
5601
|
+
async function runStudio(cwd, args, moduleUrl = import.meta.url) {
|
|
5602
|
+
const target = resolveStudioTarget(cwd, moduleUrl);
|
|
5603
|
+
switch (target.kind) {
|
|
5604
|
+
case "workspace":
|
|
5605
|
+
return spawnDev(target.webDir, args);
|
|
5606
|
+
case "package": {
|
|
5607
|
+
const bundleRoot = join18(target.packageDir, "..", "..", "..");
|
|
5608
|
+
return spawnStandalone(cwd, join18(target.packageDir, "server.js"), bundleRoot);
|
|
5609
|
+
}
|
|
5610
|
+
case "missing":
|
|
5611
|
+
console.error("Vinaya Studio isn't available in this install — no published @attalabs/vinaya build bundles the Studio app yet. Inside a checkout that contains Studio's source (apps/vinaya/web), `vinaya studio` runs it directly.");
|
|
5612
|
+
return 1;
|
|
5613
|
+
}
|
|
5614
|
+
}
|
|
5615
|
+
|
|
5466
5616
|
// src/commands/upgrade.ts
|
|
5467
|
-
import { existsSync as
|
|
5468
|
-
import { join as
|
|
5617
|
+
import { existsSync as existsSync17, readFileSync as readFileSync17, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "node:fs";
|
|
5618
|
+
import { join as join19 } from "node:path";
|
|
5469
5619
|
function realDeps7() {
|
|
5470
5620
|
return {
|
|
5471
5621
|
detectRepo: detectGitRepo,
|
|
@@ -5483,12 +5633,12 @@ function flags2(args) {
|
|
|
5483
5633
|
return { dryRun: args.includes("--dry-run"), yes: args.includes("--yes") };
|
|
5484
5634
|
}
|
|
5485
5635
|
function readManifest3(repoRoot) {
|
|
5486
|
-
const p =
|
|
5487
|
-
if (!
|
|
5636
|
+
const p = join19(repoRoot, CONFIG_PATH);
|
|
5637
|
+
if (!existsSync17(p))
|
|
5488
5638
|
return { kind: "missing" };
|
|
5489
5639
|
let raw;
|
|
5490
5640
|
try {
|
|
5491
|
-
raw = JSON.parse(
|
|
5641
|
+
raw = JSON.parse(readFileSync17(p, "utf-8"));
|
|
5492
5642
|
} catch (err) {
|
|
5493
5643
|
return { kind: "invalid", error: `invalid JSON: ${err.message}` };
|
|
5494
5644
|
}
|
|
@@ -5504,17 +5654,17 @@ function readManifest3(repoRoot) {
|
|
|
5504
5654
|
return { kind: "ok", manifest: parsed.data.managed };
|
|
5505
5655
|
}
|
|
5506
5656
|
function writeManifestVersion(repoRoot, manifest) {
|
|
5507
|
-
const configAbs =
|
|
5508
|
-
const seed = JSON.parse(
|
|
5657
|
+
const configAbs = join19(repoRoot, CONFIG_PATH);
|
|
5658
|
+
const seed = JSON.parse(readFileSync17(configAbs, "utf-8"));
|
|
5509
5659
|
const updated = { ...manifest, version: MANAGED_MANIFEST_VERSION };
|
|
5510
5660
|
writeFileSync9(configAbs, `${JSON.stringify({ ...seed, managed: updated }, null, 2)}
|
|
5511
5661
|
`, "utf-8");
|
|
5512
5662
|
}
|
|
5513
5663
|
function stripFor(repoRoot, path, marker, comment) {
|
|
5514
5664
|
const abs2 = resolveManagedBlockPath(repoRoot, path);
|
|
5515
|
-
if (!
|
|
5665
|
+
if (!existsSync17(abs2))
|
|
5516
5666
|
return { path, marker, comment, present: false, removesHost: false };
|
|
5517
|
-
const stripped = stripBlockFromContent(
|
|
5667
|
+
const stripped = stripBlockFromContent(readFileSync17(abs2, "utf-8"), marker, comment);
|
|
5518
5668
|
if (stripped === null)
|
|
5519
5669
|
return { path, marker, comment, present: false, removesHost: false };
|
|
5520
5670
|
return { path, marker, comment, present: true, removesHost: blockStripLeavesEmpty(stripped) };
|
|
@@ -5541,9 +5691,9 @@ function planHookRouting(repoRoot, manifest, recorded, hooksPathValue) {
|
|
|
5541
5691
|
const blocked = [];
|
|
5542
5692
|
for (const b of legacy) {
|
|
5543
5693
|
const abs2 = resolveManagedBlockPath(repoRoot, b.path);
|
|
5544
|
-
if (!
|
|
5694
|
+
if (!existsSync17(abs2))
|
|
5545
5695
|
continue;
|
|
5546
|
-
const stripped = stripBlockFromContent(
|
|
5696
|
+
const stripped = stripBlockFromContent(readFileSync17(abs2, "utf-8"), b.marker, b.comment);
|
|
5547
5697
|
if (stripped === null)
|
|
5548
5698
|
blocked.push(`${b.path} exists without vinaya's managed block`);
|
|
5549
5699
|
else if (!blockStripLeavesEmpty(stripped))
|
|
@@ -5578,8 +5728,8 @@ function planUpgrade(ops, repoRoot, manifest, routing) {
|
|
|
5578
5728
|
const ownedBlocks = new Set(manifest.blocks.map((b) => blockKey(b.path, b.marker)));
|
|
5579
5729
|
for (const op of ops) {
|
|
5580
5730
|
if (op.kind === "create-file") {
|
|
5581
|
-
const abs2 =
|
|
5582
|
-
const exists =
|
|
5731
|
+
const abs2 = join19(repoRoot, op.path);
|
|
5732
|
+
const exists = existsSync17(abs2);
|
|
5583
5733
|
const owned = ownedFiles.has(op.path);
|
|
5584
5734
|
let action;
|
|
5585
5735
|
if (op.path === CONFIG_PATH || op.path === DOC_OWNERS_PATH) {
|
|
@@ -5589,7 +5739,7 @@ function planUpgrade(ops, repoRoot, manifest, routing) {
|
|
|
5589
5739
|
} else if (!exists) {
|
|
5590
5740
|
action = "recreate";
|
|
5591
5741
|
hasChanges = true;
|
|
5592
|
-
} else if (
|
|
5742
|
+
} else if (readFileSync17(abs2, "utf-8") !== op.content) {
|
|
5593
5743
|
action = "regenerate";
|
|
5594
5744
|
hasChanges = true;
|
|
5595
5745
|
} else {
|
|
@@ -5602,11 +5752,11 @@ function planUpgrade(ops, repoRoot, manifest, routing) {
|
|
|
5602
5752
|
let action;
|
|
5603
5753
|
if (!owned) {
|
|
5604
5754
|
action = "not-installed";
|
|
5605
|
-
} else if (!
|
|
5755
|
+
} else if (!existsSync17(abs2)) {
|
|
5606
5756
|
action = "recreate-host";
|
|
5607
5757
|
hasChanges = true;
|
|
5608
5758
|
} else {
|
|
5609
|
-
const content =
|
|
5759
|
+
const content = readFileSync17(abs2, "utf-8");
|
|
5610
5760
|
const { begin, end } = markerLines(op.marker, op.comment);
|
|
5611
5761
|
if (!(content.includes(begin) && content.includes(end))) {
|
|
5612
5762
|
action = "recreate-append";
|
|
@@ -5706,7 +5856,7 @@ function renderUpgradeDiff(plan) {
|
|
|
5706
5856
|
}
|
|
5707
5857
|
function regenerateBlock(repoRoot, op) {
|
|
5708
5858
|
const abs2 = resolveManagedBlockPath(repoRoot, op.path);
|
|
5709
|
-
const content =
|
|
5859
|
+
const content = readFileSync17(abs2, "utf-8");
|
|
5710
5860
|
const stripped = stripBlockFromContent(content, op.marker, op.comment);
|
|
5711
5861
|
if (stripped !== null) {
|
|
5712
5862
|
writeFileSync9(abs2, stripped.endsWith(`
|
|
@@ -5719,7 +5869,7 @@ function applyUpgrade(plan, repoRoot) {
|
|
|
5719
5869
|
for (const e of plan.entries) {
|
|
5720
5870
|
if (e.kind === "create-file") {
|
|
5721
5871
|
if (e.action === "regenerate" || e.action === "recreate") {
|
|
5722
|
-
writeFileWithDirs(
|
|
5872
|
+
writeFileWithDirs(join19(repoRoot, e.op.path), e.op.content, e.op.mode);
|
|
5723
5873
|
}
|
|
5724
5874
|
} else {
|
|
5725
5875
|
if (e.action === "recreate-host")
|
|
@@ -5734,9 +5884,9 @@ function applyUpgrade(plan, repoRoot) {
|
|
|
5734
5884
|
if (!s.present)
|
|
5735
5885
|
continue;
|
|
5736
5886
|
const abs2 = resolveManagedBlockPath(repoRoot, s.path);
|
|
5737
|
-
if (!
|
|
5887
|
+
if (!existsSync17(abs2))
|
|
5738
5888
|
continue;
|
|
5739
|
-
const stripped = stripBlockFromContent(
|
|
5889
|
+
const stripped = stripBlockFromContent(readFileSync17(abs2, "utf-8"), s.marker, s.comment);
|
|
5740
5890
|
if (stripped === null)
|
|
5741
5891
|
continue;
|
|
5742
5892
|
if (blockStripLeavesEmpty(stripped))
|
|
@@ -6167,6 +6317,15 @@ var COMMANDS = [
|
|
|
6167
6317
|
],
|
|
6168
6318
|
status: "shipped"
|
|
6169
6319
|
},
|
|
6320
|
+
{
|
|
6321
|
+
name: "studio",
|
|
6322
|
+
description: "Launch Vinaya Studio — runs the Studio dev app when its source (apps/vinaya/web) is in a checkout above the current directory; published installs refuse with a clear message, since no published build bundles the Studio app yet",
|
|
6323
|
+
details: [
|
|
6324
|
+
"Resolution happens in this order: a workspace checkout carrying `apps/vinaya/web` (Studio's source, which lives in the attalabs monorepo — not this repository) runs the dev app directly; an install whose package root carries a `studio-standalone/` bundle would run that bundled server; anything else gets an explicit refusal and exit 1 rather than a silent no-op.",
|
|
6325
|
+
"No published `@attalabs/vinaya` build ships the `studio-standalone/` bundle today — producing and shipping it is the Studio-packaging work, tracked separately. Until it lands, this command is honest about the shapes it cannot serve instead of pretending to serve them."
|
|
6326
|
+
],
|
|
6327
|
+
status: "shipped"
|
|
6328
|
+
},
|
|
6170
6329
|
{
|
|
6171
6330
|
name: "quickstart",
|
|
6172
6331
|
description: "Guided wizard: init, doc-owners, project, commit, demo break, doctor, push — one command",
|
|
@@ -6206,9 +6365,9 @@ function printHelp() {
|
|
|
6206
6365
|
}
|
|
6207
6366
|
|
|
6208
6367
|
// src/index.ts
|
|
6209
|
-
var PACKAGE_ROOT =
|
|
6368
|
+
var PACKAGE_ROOT = join20(dirname8(fileURLToPath2(import.meta.url)), "..");
|
|
6210
6369
|
function readVersion2() {
|
|
6211
|
-
const pkg = JSON.parse(
|
|
6370
|
+
const pkg = JSON.parse(readFileSync18(join20(PACKAGE_ROOT, "package.json"), "utf-8"));
|
|
6212
6371
|
return pkg.version;
|
|
6213
6372
|
}
|
|
6214
6373
|
var [, , command, ...args] = process.argv;
|
|
@@ -6228,6 +6387,11 @@ try {
|
|
|
6228
6387
|
}
|
|
6229
6388
|
break;
|
|
6230
6389
|
}
|
|
6390
|
+
case "studio": {
|
|
6391
|
+
const code = await runStudio(process.cwd(), args);
|
|
6392
|
+
process.exit(code);
|
|
6393
|
+
break;
|
|
6394
|
+
}
|
|
6231
6395
|
case "init": {
|
|
6232
6396
|
const [subcommand, ...rest] = args;
|
|
6233
6397
|
if (subcommand === "product") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@attalabs/vinaya",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Vinaya — Agentic Engineering Harness. Deterministic checks every AI coding agent must satisfy before merge.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"scripts": {
|
|
39
39
|
"build": "bun scripts/build.ts",
|
|
40
40
|
"bundle-doctrine": "bun scripts/bundle-doctrine.ts",
|
|
41
|
+
"bundle-studio": "bun scripts/bundle-studio.ts",
|
|
41
42
|
"prepack": "bun scripts/build.ts && bun scripts/bundle-doctrine.ts",
|
|
42
43
|
"test": "bun test",
|
|
43
44
|
"typecheck": "tsc --noEmit",
|
|
@@ -49,9 +50,10 @@
|
|
|
49
50
|
"zod": "3.25.76"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
|
-
"@
|
|
53
|
+
"@attalabs/aeg-core": "workspace:*",
|
|
54
|
+
"@attalabs/aeg-forge-state": "workspace:*",
|
|
53
55
|
"@atta/typescript-config": "workspace:*",
|
|
54
|
-
"@
|
|
56
|
+
"@attalabs/vinaya-sources": "workspace:*",
|
|
55
57
|
"@types/bun": "latest",
|
|
56
58
|
"typescript": "^5.5.0"
|
|
57
59
|
}
|