@attalabs/vinaya 0.7.1 → 0.8.0
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/dist/index.js +183 -24
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -19,12 +19,13 @@ npx @attalabs/vinaya init # or: pnpm dlx / yarn dlx / bunx
|
|
|
19
19
|
| `vinaya doctrine` | Print the absolute path of the bundled doctrine's front door (`aeg-root/skills/aeg/SKILL.md`) on this machine. The committed root `VINAYA.md` pointer names the package, never a filesystem path — this command is the read-time resolution step it hands the reader. `--json` for the enveloped `{ root, entry }` form. |
|
|
20
20
|
| `vinaya check <name> \| --all` | Run one check, or every registered check (core + `vinaya.config.json`-registered). `--json` for the enveloped `{ checks: CheckOutcome[] }` form; `--diff-only` scopes `scope: 'diff'` checks to changed files; `--parallel[=n]` caps concurrency (default: cpu-derived). Findings always print as the check contract's JSON lines on stderr, regardless of `--json`. Exit 0 iff every check passed. |
|
|
21
21
|
| `vinaya new check <name>` | Scaffold a self-contained custom check into `./scripts/vinaya-checks/<name>.ts`, ready to register in `vinaya.config.json` |
|
|
22
|
+
| `vinaya studio` | Launch Vinaya Studio. Inside a checkout that carries Studio's source (`apps/vinaya/web` — it lives in the attalabs monorepo, not this repository) it runs the dev app; a published install refuses with a clear message and exit 1, because no published build bundles the Studio app yet. Bundling Studio into the published package is tracked, unshipped work. |
|
|
22
23
|
|
|
23
24
|
## Config
|
|
24
25
|
|
|
25
26
|
Hierarchical, file-level precedence:
|
|
26
27
|
|
|
27
|
-
1. Repo-local `vinaya.config.json` (walked up from `cwd
|
|
28
|
+
1. Repo-local `vinaya.config.json` (walked up from `cwd`, stopping at the enclosing repository's root — or the filesystem root when run outside a git repository)
|
|
28
29
|
2. Global `~/.vinaya/config.json`
|
|
29
30
|
3. `null` if neither exists
|
|
30
31
|
|
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
|
{
|
|
@@ -880,6 +926,8 @@ import { fileURLToPath } from "node:url";
|
|
|
880
926
|
function packageRoot(moduleUrl) {
|
|
881
927
|
let dir = dirname(fileURLToPath(moduleUrl));
|
|
882
928
|
while (!existsSync(join(dir, "package.json"))) {
|
|
929
|
+
if (existsSync(join(dir, ".git")))
|
|
930
|
+
break;
|
|
883
931
|
const parent = dirname(dir);
|
|
884
932
|
if (parent === dir)
|
|
885
933
|
break;
|
|
@@ -1744,6 +1792,8 @@ function findLocalConfig() {
|
|
|
1744
1792
|
const candidate = join3(dir, LOCAL_CONFIG_FILENAME);
|
|
1745
1793
|
if (existsSync2(candidate))
|
|
1746
1794
|
return candidate;
|
|
1795
|
+
if (existsSync2(join3(dir, ".git")))
|
|
1796
|
+
return null;
|
|
1747
1797
|
const parent = dirname2(dir);
|
|
1748
1798
|
if (parent === dir)
|
|
1749
1799
|
return null;
|
|
@@ -5463,9 +5513,104 @@ async function quickstartCommand(args) {
|
|
|
5463
5513
|
process.exit(await runQuickstart(args, realDeps6()));
|
|
5464
5514
|
}
|
|
5465
5515
|
|
|
5516
|
+
// src/commands/studio.ts
|
|
5517
|
+
import { execFile as execFile5, spawn as spawn2 } from "node:child_process";
|
|
5518
|
+
import { existsSync as existsSync16, readFileSync as readFileSync16, renameSync } from "node:fs";
|
|
5519
|
+
import net from "node:net";
|
|
5520
|
+
import { dirname as dirname7, join as join18 } from "node:path";
|
|
5521
|
+
import { promisify as promisify5 } from "node:util";
|
|
5522
|
+
|
|
5523
|
+
// src/lib/studio-bundle.ts
|
|
5524
|
+
var STUDIO_NODE_MODULES_PACKED_DIRNAME = "_node_modules";
|
|
5525
|
+
|
|
5526
|
+
// src/commands/studio.ts
|
|
5527
|
+
var execFileAsync5 = promisify5(execFile5);
|
|
5528
|
+
function execFileForRepo(cwd) {
|
|
5529
|
+
return execFileAsync5("git", ["remote", "get-url", "origin"], { cwd, timeout: 5000 });
|
|
5530
|
+
}
|
|
5531
|
+
var PRIMARY_PORT = 3006;
|
|
5532
|
+
var FALLBACK_PORT = 3106;
|
|
5533
|
+
function resolveStudioTarget(cwd, moduleUrl = import.meta.url) {
|
|
5534
|
+
let dir = cwd;
|
|
5535
|
+
for (;; ) {
|
|
5536
|
+
const webDir = join18(dir, "apps", "vinaya", "web");
|
|
5537
|
+
const pkgPath = join18(webDir, "package.json");
|
|
5538
|
+
if (existsSync16(pkgPath)) {
|
|
5539
|
+
try {
|
|
5540
|
+
const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
|
|
5541
|
+
if (pkg.name === "@atta/vinaya-web") {
|
|
5542
|
+
return { kind: "workspace", webDir };
|
|
5543
|
+
}
|
|
5544
|
+
} catch {}
|
|
5545
|
+
}
|
|
5546
|
+
if (existsSync16(join18(dir, ".git")))
|
|
5547
|
+
break;
|
|
5548
|
+
const parent = dirname7(dir);
|
|
5549
|
+
if (parent === dir)
|
|
5550
|
+
break;
|
|
5551
|
+
dir = parent;
|
|
5552
|
+
}
|
|
5553
|
+
const standaloneWebDir = join18(packageRoot(moduleUrl), "studio-standalone", "apps", "vinaya", "web");
|
|
5554
|
+
if (existsSync16(join18(standaloneWebDir, "server.js"))) {
|
|
5555
|
+
return { kind: "package", packageDir: standaloneWebDir };
|
|
5556
|
+
}
|
|
5557
|
+
return { kind: "missing" };
|
|
5558
|
+
}
|
|
5559
|
+
function spawnDev(webDir, args) {
|
|
5560
|
+
return new Promise((resolve2) => {
|
|
5561
|
+
const child = spawn2("bun", ["run", "dev", ...args], { cwd: webDir, stdio: "inherit" });
|
|
5562
|
+
child.on("exit", (code) => resolve2(code ?? 0));
|
|
5563
|
+
});
|
|
5564
|
+
}
|
|
5565
|
+
function isPortFree(port) {
|
|
5566
|
+
return new Promise((resolve2) => {
|
|
5567
|
+
const tester = net.createServer();
|
|
5568
|
+
tester.once("error", () => resolve2(false));
|
|
5569
|
+
tester.once("listening", () => tester.close(() => resolve2(true)));
|
|
5570
|
+
tester.listen(port, "127.0.0.1");
|
|
5571
|
+
});
|
|
5572
|
+
}
|
|
5573
|
+
function ensureStudioNodeModules(bundleRoot) {
|
|
5574
|
+
const real = join18(bundleRoot, "node_modules");
|
|
5575
|
+
const packed = join18(bundleRoot, STUDIO_NODE_MODULES_PACKED_DIRNAME);
|
|
5576
|
+
if (!existsSync16(real) && existsSync16(packed)) {
|
|
5577
|
+
renameSync(packed, real);
|
|
5578
|
+
}
|
|
5579
|
+
}
|
|
5580
|
+
async function spawnStandalone(cwd, serverPath, bundleRoot) {
|
|
5581
|
+
ensureStudioNodeModules(bundleRoot);
|
|
5582
|
+
const repo = await resolveRepo(() => execFileForRepo(cwd));
|
|
5583
|
+
const primaryFree = await isPortFree(PRIMARY_PORT);
|
|
5584
|
+
const port = primaryFree ? PRIMARY_PORT : FALLBACK_PORT;
|
|
5585
|
+
if (!primaryFree) {
|
|
5586
|
+
console.info(`[studio] port ${PRIMARY_PORT} is taken — falling back to ${FALLBACK_PORT}`);
|
|
5587
|
+
}
|
|
5588
|
+
const env = { HOSTNAME: "127.0.0.1", ...process.env, PORT: String(port), VINAYA_REPO_ROOT: cwd };
|
|
5589
|
+
if (repo)
|
|
5590
|
+
env.AEG_REPO = `${repo.owner}/${repo.repo}`;
|
|
5591
|
+
return new Promise((resolve2) => {
|
|
5592
|
+
const child = spawn2("node", [serverPath], { cwd, stdio: "inherit", env });
|
|
5593
|
+
child.on("exit", (code) => resolve2(code ?? 0));
|
|
5594
|
+
});
|
|
5595
|
+
}
|
|
5596
|
+
async function runStudio(cwd, args, moduleUrl = import.meta.url) {
|
|
5597
|
+
const target = resolveStudioTarget(cwd, moduleUrl);
|
|
5598
|
+
switch (target.kind) {
|
|
5599
|
+
case "workspace":
|
|
5600
|
+
return spawnDev(target.webDir, args);
|
|
5601
|
+
case "package": {
|
|
5602
|
+
const bundleRoot = join18(target.packageDir, "..", "..", "..");
|
|
5603
|
+
return spawnStandalone(cwd, join18(target.packageDir, "server.js"), bundleRoot);
|
|
5604
|
+
}
|
|
5605
|
+
case "missing":
|
|
5606
|
+
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.");
|
|
5607
|
+
return 1;
|
|
5608
|
+
}
|
|
5609
|
+
}
|
|
5610
|
+
|
|
5466
5611
|
// src/commands/upgrade.ts
|
|
5467
|
-
import { existsSync as
|
|
5468
|
-
import { join as
|
|
5612
|
+
import { existsSync as existsSync17, readFileSync as readFileSync17, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "node:fs";
|
|
5613
|
+
import { join as join19 } from "node:path";
|
|
5469
5614
|
function realDeps7() {
|
|
5470
5615
|
return {
|
|
5471
5616
|
detectRepo: detectGitRepo,
|
|
@@ -5483,12 +5628,12 @@ function flags2(args) {
|
|
|
5483
5628
|
return { dryRun: args.includes("--dry-run"), yes: args.includes("--yes") };
|
|
5484
5629
|
}
|
|
5485
5630
|
function readManifest3(repoRoot) {
|
|
5486
|
-
const p =
|
|
5487
|
-
if (!
|
|
5631
|
+
const p = join19(repoRoot, CONFIG_PATH);
|
|
5632
|
+
if (!existsSync17(p))
|
|
5488
5633
|
return { kind: "missing" };
|
|
5489
5634
|
let raw;
|
|
5490
5635
|
try {
|
|
5491
|
-
raw = JSON.parse(
|
|
5636
|
+
raw = JSON.parse(readFileSync17(p, "utf-8"));
|
|
5492
5637
|
} catch (err) {
|
|
5493
5638
|
return { kind: "invalid", error: `invalid JSON: ${err.message}` };
|
|
5494
5639
|
}
|
|
@@ -5504,17 +5649,17 @@ function readManifest3(repoRoot) {
|
|
|
5504
5649
|
return { kind: "ok", manifest: parsed.data.managed };
|
|
5505
5650
|
}
|
|
5506
5651
|
function writeManifestVersion(repoRoot, manifest) {
|
|
5507
|
-
const configAbs =
|
|
5508
|
-
const seed = JSON.parse(
|
|
5652
|
+
const configAbs = join19(repoRoot, CONFIG_PATH);
|
|
5653
|
+
const seed = JSON.parse(readFileSync17(configAbs, "utf-8"));
|
|
5509
5654
|
const updated = { ...manifest, version: MANAGED_MANIFEST_VERSION };
|
|
5510
5655
|
writeFileSync9(configAbs, `${JSON.stringify({ ...seed, managed: updated }, null, 2)}
|
|
5511
5656
|
`, "utf-8");
|
|
5512
5657
|
}
|
|
5513
5658
|
function stripFor(repoRoot, path, marker, comment) {
|
|
5514
5659
|
const abs2 = resolveManagedBlockPath(repoRoot, path);
|
|
5515
|
-
if (!
|
|
5660
|
+
if (!existsSync17(abs2))
|
|
5516
5661
|
return { path, marker, comment, present: false, removesHost: false };
|
|
5517
|
-
const stripped = stripBlockFromContent(
|
|
5662
|
+
const stripped = stripBlockFromContent(readFileSync17(abs2, "utf-8"), marker, comment);
|
|
5518
5663
|
if (stripped === null)
|
|
5519
5664
|
return { path, marker, comment, present: false, removesHost: false };
|
|
5520
5665
|
return { path, marker, comment, present: true, removesHost: blockStripLeavesEmpty(stripped) };
|
|
@@ -5541,9 +5686,9 @@ function planHookRouting(repoRoot, manifest, recorded, hooksPathValue) {
|
|
|
5541
5686
|
const blocked = [];
|
|
5542
5687
|
for (const b of legacy) {
|
|
5543
5688
|
const abs2 = resolveManagedBlockPath(repoRoot, b.path);
|
|
5544
|
-
if (!
|
|
5689
|
+
if (!existsSync17(abs2))
|
|
5545
5690
|
continue;
|
|
5546
|
-
const stripped = stripBlockFromContent(
|
|
5691
|
+
const stripped = stripBlockFromContent(readFileSync17(abs2, "utf-8"), b.marker, b.comment);
|
|
5547
5692
|
if (stripped === null)
|
|
5548
5693
|
blocked.push(`${b.path} exists without vinaya's managed block`);
|
|
5549
5694
|
else if (!blockStripLeavesEmpty(stripped))
|
|
@@ -5578,8 +5723,8 @@ function planUpgrade(ops, repoRoot, manifest, routing) {
|
|
|
5578
5723
|
const ownedBlocks = new Set(manifest.blocks.map((b) => blockKey(b.path, b.marker)));
|
|
5579
5724
|
for (const op of ops) {
|
|
5580
5725
|
if (op.kind === "create-file") {
|
|
5581
|
-
const abs2 =
|
|
5582
|
-
const exists =
|
|
5726
|
+
const abs2 = join19(repoRoot, op.path);
|
|
5727
|
+
const exists = existsSync17(abs2);
|
|
5583
5728
|
const owned = ownedFiles.has(op.path);
|
|
5584
5729
|
let action;
|
|
5585
5730
|
if (op.path === CONFIG_PATH || op.path === DOC_OWNERS_PATH) {
|
|
@@ -5589,7 +5734,7 @@ function planUpgrade(ops, repoRoot, manifest, routing) {
|
|
|
5589
5734
|
} else if (!exists) {
|
|
5590
5735
|
action = "recreate";
|
|
5591
5736
|
hasChanges = true;
|
|
5592
|
-
} else if (
|
|
5737
|
+
} else if (readFileSync17(abs2, "utf-8") !== op.content) {
|
|
5593
5738
|
action = "regenerate";
|
|
5594
5739
|
hasChanges = true;
|
|
5595
5740
|
} else {
|
|
@@ -5602,11 +5747,11 @@ function planUpgrade(ops, repoRoot, manifest, routing) {
|
|
|
5602
5747
|
let action;
|
|
5603
5748
|
if (!owned) {
|
|
5604
5749
|
action = "not-installed";
|
|
5605
|
-
} else if (!
|
|
5750
|
+
} else if (!existsSync17(abs2)) {
|
|
5606
5751
|
action = "recreate-host";
|
|
5607
5752
|
hasChanges = true;
|
|
5608
5753
|
} else {
|
|
5609
|
-
const content =
|
|
5754
|
+
const content = readFileSync17(abs2, "utf-8");
|
|
5610
5755
|
const { begin, end } = markerLines(op.marker, op.comment);
|
|
5611
5756
|
if (!(content.includes(begin) && content.includes(end))) {
|
|
5612
5757
|
action = "recreate-append";
|
|
@@ -5706,7 +5851,7 @@ function renderUpgradeDiff(plan) {
|
|
|
5706
5851
|
}
|
|
5707
5852
|
function regenerateBlock(repoRoot, op) {
|
|
5708
5853
|
const abs2 = resolveManagedBlockPath(repoRoot, op.path);
|
|
5709
|
-
const content =
|
|
5854
|
+
const content = readFileSync17(abs2, "utf-8");
|
|
5710
5855
|
const stripped = stripBlockFromContent(content, op.marker, op.comment);
|
|
5711
5856
|
if (stripped !== null) {
|
|
5712
5857
|
writeFileSync9(abs2, stripped.endsWith(`
|
|
@@ -5719,7 +5864,7 @@ function applyUpgrade(plan, repoRoot) {
|
|
|
5719
5864
|
for (const e of plan.entries) {
|
|
5720
5865
|
if (e.kind === "create-file") {
|
|
5721
5866
|
if (e.action === "regenerate" || e.action === "recreate") {
|
|
5722
|
-
writeFileWithDirs(
|
|
5867
|
+
writeFileWithDirs(join19(repoRoot, e.op.path), e.op.content, e.op.mode);
|
|
5723
5868
|
}
|
|
5724
5869
|
} else {
|
|
5725
5870
|
if (e.action === "recreate-host")
|
|
@@ -5734,9 +5879,9 @@ function applyUpgrade(plan, repoRoot) {
|
|
|
5734
5879
|
if (!s.present)
|
|
5735
5880
|
continue;
|
|
5736
5881
|
const abs2 = resolveManagedBlockPath(repoRoot, s.path);
|
|
5737
|
-
if (!
|
|
5882
|
+
if (!existsSync17(abs2))
|
|
5738
5883
|
continue;
|
|
5739
|
-
const stripped = stripBlockFromContent(
|
|
5884
|
+
const stripped = stripBlockFromContent(readFileSync17(abs2, "utf-8"), s.marker, s.comment);
|
|
5740
5885
|
if (stripped === null)
|
|
5741
5886
|
continue;
|
|
5742
5887
|
if (blockStripLeavesEmpty(stripped))
|
|
@@ -6167,6 +6312,15 @@ var COMMANDS = [
|
|
|
6167
6312
|
],
|
|
6168
6313
|
status: "shipped"
|
|
6169
6314
|
},
|
|
6315
|
+
{
|
|
6316
|
+
name: "studio",
|
|
6317
|
+
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",
|
|
6318
|
+
details: [
|
|
6319
|
+
"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.",
|
|
6320
|
+
"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."
|
|
6321
|
+
],
|
|
6322
|
+
status: "shipped"
|
|
6323
|
+
},
|
|
6170
6324
|
{
|
|
6171
6325
|
name: "quickstart",
|
|
6172
6326
|
description: "Guided wizard: init, doc-owners, project, commit, demo break, doctor, push — one command",
|
|
@@ -6206,9 +6360,9 @@ function printHelp() {
|
|
|
6206
6360
|
}
|
|
6207
6361
|
|
|
6208
6362
|
// src/index.ts
|
|
6209
|
-
var PACKAGE_ROOT =
|
|
6363
|
+
var PACKAGE_ROOT = join20(dirname8(fileURLToPath2(import.meta.url)), "..");
|
|
6210
6364
|
function readVersion2() {
|
|
6211
|
-
const pkg = JSON.parse(
|
|
6365
|
+
const pkg = JSON.parse(readFileSync18(join20(PACKAGE_ROOT, "package.json"), "utf-8"));
|
|
6212
6366
|
return pkg.version;
|
|
6213
6367
|
}
|
|
6214
6368
|
var [, , command, ...args] = process.argv;
|
|
@@ -6228,6 +6382,11 @@ try {
|
|
|
6228
6382
|
}
|
|
6229
6383
|
break;
|
|
6230
6384
|
}
|
|
6385
|
+
case "studio": {
|
|
6386
|
+
const code = await runStudio(process.cwd(), args);
|
|
6387
|
+
process.exit(code);
|
|
6388
|
+
break;
|
|
6389
|
+
}
|
|
6231
6390
|
case "init": {
|
|
6232
6391
|
const [subcommand, ...rest] = args;
|
|
6233
6392
|
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.0",
|
|
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",
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@atta/aeg-core": "workspace:*",
|
|
54
|
+
"@atta/aeg-forge-state": "workspace:*",
|
|
53
55
|
"@atta/typescript-config": "workspace:*",
|
|
54
56
|
"@atta/vinaya-sources": "workspace:*",
|
|
55
57
|
"@types/bun": "latest",
|