@interchained/portal-cli 0.1.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.
Files changed (81) hide show
  1. package/dist/commands/adapter.d.ts +5 -0
  2. package/dist/commands/adapter.d.ts.map +1 -0
  3. package/dist/commands/adapter.js +71 -0
  4. package/dist/commands/adapter.js.map +1 -0
  5. package/dist/commands/agent-cmd.d.ts +7 -0
  6. package/dist/commands/agent-cmd.d.ts.map +1 -0
  7. package/dist/commands/agent-cmd.js +162 -0
  8. package/dist/commands/agent-cmd.js.map +1 -0
  9. package/dist/commands/audit.d.ts +18 -0
  10. package/dist/commands/audit.d.ts.map +1 -0
  11. package/dist/commands/audit.js +80 -0
  12. package/dist/commands/audit.js.map +1 -0
  13. package/dist/commands/build.d.ts +10 -0
  14. package/dist/commands/build.d.ts.map +1 -0
  15. package/dist/commands/build.js +35 -0
  16. package/dist/commands/build.js.map +1 -0
  17. package/dist/commands/contract-cmd.d.ts +7 -0
  18. package/dist/commands/contract-cmd.d.ts.map +1 -0
  19. package/dist/commands/contract-cmd.js +222 -0
  20. package/dist/commands/contract-cmd.js.map +1 -0
  21. package/dist/commands/deploy.d.ts +13 -0
  22. package/dist/commands/deploy.d.ts.map +1 -0
  23. package/dist/commands/deploy.js +135 -0
  24. package/dist/commands/deploy.js.map +1 -0
  25. package/dist/commands/dev.d.ts +10 -0
  26. package/dist/commands/dev.d.ts.map +1 -0
  27. package/dist/commands/dev.js +37 -0
  28. package/dist/commands/dev.js.map +1 -0
  29. package/dist/commands/doctor.d.ts +6 -0
  30. package/dist/commands/doctor.d.ts.map +1 -0
  31. package/dist/commands/doctor.js +139 -0
  32. package/dist/commands/doctor.js.map +1 -0
  33. package/dist/commands/explain.d.ts +6 -0
  34. package/dist/commands/explain.d.ts.map +1 -0
  35. package/dist/commands/explain.js +75 -0
  36. package/dist/commands/explain.js.map +1 -0
  37. package/dist/commands/generate.d.ts +13 -0
  38. package/dist/commands/generate.d.ts.map +1 -0
  39. package/dist/commands/generate.js +222 -0
  40. package/dist/commands/generate.js.map +1 -0
  41. package/dist/commands/guard.d.ts +12 -0
  42. package/dist/commands/guard.d.ts.map +1 -0
  43. package/dist/commands/guard.js +71 -0
  44. package/dist/commands/guard.js.map +1 -0
  45. package/dist/commands/improve.d.ts +18 -0
  46. package/dist/commands/improve.d.ts.map +1 -0
  47. package/dist/commands/improve.js +157 -0
  48. package/dist/commands/improve.js.map +1 -0
  49. package/dist/commands/lint.d.ts +5 -0
  50. package/dist/commands/lint.d.ts.map +1 -0
  51. package/dist/commands/lint.js +87 -0
  52. package/dist/commands/lint.js.map +1 -0
  53. package/dist/commands/patch.d.ts +5 -0
  54. package/dist/commands/patch.d.ts.map +1 -0
  55. package/dist/commands/patch.js +78 -0
  56. package/dist/commands/patch.js.map +1 -0
  57. package/dist/commands/preview.d.ts +4 -0
  58. package/dist/commands/preview.d.ts.map +1 -0
  59. package/dist/commands/preview.js +26 -0
  60. package/dist/commands/preview.js.map +1 -0
  61. package/dist/commands/rollback.d.ts +8 -0
  62. package/dist/commands/rollback.d.ts.map +1 -0
  63. package/dist/commands/rollback.js +88 -0
  64. package/dist/commands/rollback.js.map +1 -0
  65. package/dist/commands/test.d.ts +7 -0
  66. package/dist/commands/test.d.ts.map +1 -0
  67. package/dist/commands/test.js +57 -0
  68. package/dist/commands/test.js.map +1 -0
  69. package/dist/index.d.ts +7 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +152 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/utils/contract.d.ts +14 -0
  74. package/dist/utils/contract.d.ts.map +1 -0
  75. package/dist/utils/contract.js +53 -0
  76. package/dist/utils/contract.js.map +1 -0
  77. package/dist/utils/print.d.ts +22 -0
  78. package/dist/utils/print.d.ts.map +1 -0
  79. package/dist/utils/print.js +47 -0
  80. package/dist/utils/print.js.map +1 -0
  81. package/package.json +44 -0
@@ -0,0 +1,87 @@
1
+ /**
2
+ * portal lint — ESLint + TypeScript checks + contract schema validation.
3
+ */
4
+ import { access } from "node:fs/promises";
5
+ import { join } from "node:path";
6
+ import { execa } from "execa";
7
+ import { banner, success, fail, step, warn, blank } from "../utils/print.js";
8
+ import { loadContract } from "../utils/contract.js";
9
+ import { validateContract } from "@interchained/portal-contract";
10
+ async function exists(p) {
11
+ try {
12
+ await access(p);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ export async function lintCommand() {
20
+ banner();
21
+ const root = process.cwd();
22
+ let failed = false;
23
+ // 1. ESLint
24
+ const hasEslint = await exists(join(root, "node_modules", "eslint"));
25
+ if (hasEslint) {
26
+ step("Running ESLint…");
27
+ try {
28
+ await execa("npx", ["eslint", ".", "--ext", ".ts,.tsx", "--max-warnings", "0"], {
29
+ stdio: "inherit",
30
+ cwd: root,
31
+ env: { ...process.env, FORCE_COLOR: "1" },
32
+ });
33
+ success("ESLint passed");
34
+ }
35
+ catch {
36
+ fail("ESLint found issues");
37
+ failed = true;
38
+ }
39
+ }
40
+ else {
41
+ warn("ESLint not installed — skipping");
42
+ }
43
+ blank();
44
+ // 2. TypeScript
45
+ step("Running tsc --noEmit…");
46
+ try {
47
+ await execa("npx", ["tsc", "--noEmit"], {
48
+ stdio: "inherit",
49
+ cwd: root,
50
+ });
51
+ success("TypeScript passed");
52
+ }
53
+ catch {
54
+ fail("TypeScript errors found");
55
+ failed = true;
56
+ }
57
+ blank();
58
+ // 3. Contract validation
59
+ step("Validating app contract…");
60
+ try {
61
+ const contract = await loadContract(root);
62
+ validateContract(contract);
63
+ // Extra checks
64
+ const tokens = JSON.stringify(contract).match(/\{\{[A-Z_]+\}\}/g);
65
+ if (tokens) {
66
+ fail(`Unreplaced template tokens in contract: ${tokens.join(", ")}`);
67
+ failed = true;
68
+ }
69
+ else {
70
+ success("Contract valid");
71
+ }
72
+ }
73
+ catch (err) {
74
+ fail(`Contract invalid: ${err.message}`);
75
+ failed = true;
76
+ }
77
+ blank();
78
+ if (failed) {
79
+ fail("Lint failed — fix the issues above before committing");
80
+ process.exit(1);
81
+ }
82
+ else {
83
+ success("All lint checks passed");
84
+ blank();
85
+ }
86
+ }
87
+ //# sourceMappingURL=lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * portal patch — review and apply a pending agent-generated patch.
3
+ */
4
+ export declare function patchCommand(): Promise<void>;
5
+ //# sourceMappingURL=patch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../src/commands/patch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAsElD"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * portal patch — review and apply a pending agent-generated patch.
3
+ */
4
+ import pc from "picocolors";
5
+ import prompts from "prompts";
6
+ import { PatchStore, applyPatch, inlineDiff } from "@interchained/portal-agent";
7
+ import { banner, header, success, warn, info, blank, icon } from "../utils/print.js";
8
+ export async function patchCommand() {
9
+ banner();
10
+ const root = process.cwd();
11
+ const store = new PatchStore(root);
12
+ const all = await store.list();
13
+ const pending = all.filter((p) => p.status === "pending");
14
+ if (pending.length === 0) {
15
+ info("No pending patches.");
16
+ console.log(pc.dim(" Patches are created by portal generate and portal improve."));
17
+ blank();
18
+ return;
19
+ }
20
+ const { selected } = await prompts({
21
+ type: "select",
22
+ name: "selected",
23
+ message: `${pending.length} pending patch${pending.length !== 1 ? "es" : ""} — choose one to review:`,
24
+ choices: pending.map((p) => ({
25
+ title: `${pc.bold(p.file)} ${pc.dim(p.reason.slice(0, 60))}`,
26
+ value: p.id,
27
+ })),
28
+ });
29
+ if (!selected) {
30
+ blank();
31
+ return;
32
+ }
33
+ const patch = pending.find((p) => p.id === selected);
34
+ header(`Patch: ${patch.file}`);
35
+ console.log(pc.dim(` Agent: ${patch.agent}`));
36
+ console.log(pc.dim(` Reason: ${patch.reason}`));
37
+ if (patch.sentinelSummary) {
38
+ const si = patch.sentinelApproved ? icon.pass : icon.warn;
39
+ console.log(` ${si} Sentinel: ${patch.sentinelSummary}`);
40
+ }
41
+ blank();
42
+ console.log(pc.dim("─── diff ─────────────────────────────────────────────"));
43
+ const diffLines = inlineDiff(patch.original, patch.proposed).split("\n").slice(0, 50);
44
+ for (const line of diffLines) {
45
+ if (line.startsWith("+ "))
46
+ console.log(pc.green(line));
47
+ else if (line.startsWith("- "))
48
+ console.log(pc.red(line));
49
+ else
50
+ console.log(pc.dim(line));
51
+ }
52
+ console.log(pc.dim("──────────────────────────────────────────────────────"));
53
+ blank();
54
+ const { choice } = await prompts({
55
+ type: "select",
56
+ name: "choice",
57
+ message: `Apply patch to ${pc.bold(patch.file)}?`,
58
+ choices: [
59
+ { title: pc.green("✓ Apply"), value: "apply" },
60
+ { title: pc.yellow("~ Skip"), value: "skip" },
61
+ { title: pc.red("✗ Reject"), value: "reject" },
62
+ ],
63
+ });
64
+ if (choice === "apply") {
65
+ await store.update(patch.id, { status: "approved" });
66
+ await applyPatch({ ...patch, status: "approved" }, root, store);
67
+ success(`Applied: ${patch.file}`);
68
+ }
69
+ else if (choice === "reject") {
70
+ await store.update(patch.id, { status: "rejected" });
71
+ warn(`Rejected and removed from queue.`);
72
+ }
73
+ else {
74
+ info("Skipped.");
75
+ }
76
+ blank();
77
+ }
78
+ //# sourceMappingURL=patch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.js","sourceRoot":"","sources":["../../src/commands/patch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function previewCommand(opts?: {
2
+ port?: number;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/commands/preview.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,CAAC,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBhF"}
@@ -0,0 +1,26 @@
1
+ import { execa } from "execa";
2
+ import pc from "picocolors";
3
+ import { banner, step, fail } from "../utils/print.js";
4
+ export async function previewCommand(opts = {}) {
5
+ banner();
6
+ step("Starting production preview…");
7
+ console.log(pc.dim(" Make sure you have run portal build first.\n"));
8
+ const args = ["vite", "preview"];
9
+ if (opts.port)
10
+ args.push("--port", String(opts.port));
11
+ try {
12
+ await execa("npx", args, {
13
+ stdio: "inherit",
14
+ cwd: process.cwd(),
15
+ env: { ...process.env, FORCE_COLOR: "1" },
16
+ });
17
+ }
18
+ catch (err) {
19
+ const code = err.exitCode;
20
+ if (code !== 0 && code !== null && code !== undefined) {
21
+ fail("Preview server exited with an error.");
22
+ process.exit(code);
23
+ }
24
+ }
25
+ }
26
+ //# sourceMappingURL=preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/commands/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA0B,EAAE;IAC/D,MAAM,EAAE,CAAC;IACT,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAEtE,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEtD,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE;YACvB,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE;SAC1C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,QAAQ,CAAC;QACrD,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACtD,IAAI,CAAC,sCAAsC,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * portal rollback — revert the last applied Portal patch.
3
+ * Restores the original file content from the patch record.
4
+ */
5
+ export declare function rollbackCommand(opts?: {
6
+ id?: string;
7
+ }): Promise<void>;
8
+ //# sourceMappingURL=rollback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/commands/rollback.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,wBAAsB,eAAe,CAAC,IAAI,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA4E/E"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * portal rollback — revert the last applied Portal patch.
3
+ * Restores the original file content from the patch record.
4
+ */
5
+ import { writeFile, mkdir } from "node:fs/promises";
6
+ import { join, dirname } from "node:path";
7
+ import pc from "picocolors";
8
+ import prompts from "prompts";
9
+ import { PatchStore } from "@interchained/portal-agent";
10
+ import { banner, success, fail, warn, info, blank, header } from "../utils/print.js";
11
+ export async function rollbackCommand(opts = {}) {
12
+ banner();
13
+ const root = process.cwd();
14
+ const store = new PatchStore(root);
15
+ const all = await store.list();
16
+ const applied = all
17
+ .filter((p) => p.status === "applied")
18
+ .sort((a, b) => b.createdAt.localeCompare(a.createdAt));
19
+ if (applied.length === 0) {
20
+ info("No applied patches to roll back.");
21
+ blank();
22
+ return;
23
+ }
24
+ let targetId = opts.id;
25
+ if (!targetId) {
26
+ const { selected } = await prompts({
27
+ type: "select",
28
+ name: "selected",
29
+ message: "Which patch do you want to roll back?",
30
+ choices: applied.slice(0, 10).map((p) => ({
31
+ title: `${pc.bold(p.file)} ${pc.dim(p.reason.slice(0, 55))} ${pc.dim(p.createdAt.slice(0, 10))}`,
32
+ value: p.id,
33
+ })),
34
+ });
35
+ targetId = selected;
36
+ }
37
+ if (!targetId) {
38
+ blank();
39
+ return;
40
+ }
41
+ const patch = applied.find((p) => p.id === targetId);
42
+ if (!patch) {
43
+ fail(`Patch ${targetId} not found.`);
44
+ process.exit(1);
45
+ }
46
+ header(`Rolling back: ${patch.file}`);
47
+ console.log(pc.dim(` Reason: ${patch.reason}`));
48
+ blank();
49
+ if (!patch.original) {
50
+ warn("This patch has no original content recorded — it created a new file.");
51
+ const { confirm } = await prompts({
52
+ type: "confirm",
53
+ name: "confirm",
54
+ message: `Delete ${patch.file}?`,
55
+ initial: false,
56
+ });
57
+ if (!confirm) {
58
+ info("Cancelled.");
59
+ blank();
60
+ return;
61
+ }
62
+ const { unlink } = await import("node:fs/promises");
63
+ await unlink(join(root, patch.file)).catch(() => { });
64
+ await store.update(patch.id, { status: "rejected" });
65
+ success(`Deleted: ${patch.file}`);
66
+ blank();
67
+ return;
68
+ }
69
+ const { confirm } = await prompts({
70
+ type: "confirm",
71
+ name: "confirm",
72
+ message: `Restore ${pc.bold(patch.file)} to its pre-patch state?`,
73
+ initial: true,
74
+ });
75
+ if (!confirm) {
76
+ info("Cancelled.");
77
+ blank();
78
+ return;
79
+ }
80
+ const filePath = join(root, patch.file);
81
+ await mkdir(dirname(filePath), { recursive: true });
82
+ await writeFile(filePath, patch.original, "utf-8");
83
+ await store.update(patch.id, { status: "pending" });
84
+ success(`Rolled back: ${patch.file}`);
85
+ info(`Patch ${patch.id.slice(0, 8)} moved back to "pending" status.`);
86
+ blank();
87
+ }
88
+ //# sourceMappingURL=rollback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollback.js","sourceRoot":"","sources":["../../src/commands/rollback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * portal test — run project tests and framework-aware checks.
3
+ */
4
+ export declare function testCommand(opts?: {
5
+ watch?: boolean;
6
+ }): Promise<void>;
7
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH,wBAAsB,WAAW,CAAC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C/E"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * portal test — run project tests and framework-aware checks.
3
+ */
4
+ import { access } from "node:fs/promises";
5
+ import { join } from "node:path";
6
+ import { execa } from "execa";
7
+ import { banner, success, fail, step, blank } from "../utils/print.js";
8
+ async function exists(p) {
9
+ try {
10
+ await access(p);
11
+ return true;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ export async function testCommand(opts = {}) {
18
+ banner();
19
+ const root = process.cwd();
20
+ // Detect test runner
21
+ const hasVitest = await exists(join(root, "node_modules", "vitest"));
22
+ const hasJest = await exists(join(root, "node_modules", "jest"));
23
+ let runner;
24
+ let label;
25
+ if (hasVitest) {
26
+ runner = ["vitest", opts.watch ? "" : "run"].filter(Boolean);
27
+ label = "Vitest";
28
+ }
29
+ else if (hasJest) {
30
+ runner = ["jest", ...(opts.watch ? ["--watch"] : [])];
31
+ label = "Jest";
32
+ }
33
+ else {
34
+ // Fallback: TypeScript type check
35
+ step("No test runner found (vitest/jest) — running tsc --noEmit");
36
+ label = "TypeScript";
37
+ runner = ["tsc", "--noEmit"];
38
+ }
39
+ step(`Running ${label}…`);
40
+ blank();
41
+ try {
42
+ await execa("npx", runner, {
43
+ stdio: "inherit",
44
+ cwd: root,
45
+ env: { ...process.env, FORCE_COLOR: "1" },
46
+ });
47
+ blank();
48
+ success("Tests passed");
49
+ }
50
+ catch (err) {
51
+ blank();
52
+ fail("Tests failed");
53
+ const code = err.exitCode ?? 1;
54
+ process.exit(code);
55
+ }
56
+ }
57
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEvE,KAAK,UAAU,MAAM,CAAC,CAAS;IAC7B,IAAI,CAAC;QAAC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA4B,EAAE;IAC9D,MAAM,EAAE,CAAC;IAET,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE3B,qBAAqB;IACrB,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrE,MAAM,OAAO,GAAK,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnE,IAAI,MAAgB,CAAC;IACrB,IAAI,KAAa,CAAC;IAElB,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7D,KAAK,GAAI,QAAQ,CAAC;IACpB,CAAC;SAAM,IAAI,OAAO,EAAE,CAAC;QACnB,MAAM,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,KAAK,GAAI,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,kCAAkC;QAClC,IAAI,CAAC,2DAA2D,CAAC,CAAC;QAClE,KAAK,GAAI,YAAY,CAAC;QACtB,MAAM,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC;IAER,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE;YACzB,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,IAAI;YACT,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE;SAC1C,CAAC,CAAC;QACH,KAAK,EAAE,CAAC;QACR,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,cAAc,CAAC,CAAC;QACrB,MAAM,IAAI,GAAI,GAA6B,CAAC,QAAQ,IAAI,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Portal CLI — v1.1
4
+ * The agent-native web framework by Interchained.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Portal CLI — v1.1
4
+ * The agent-native web framework by Interchained.
5
+ */
6
+ import { program } from "commander";
7
+ import { readFileSync } from "node:fs";
8
+ import { join, dirname } from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+ import { devCommand } from "./commands/dev.js";
11
+ import { buildCommand } from "./commands/build.js";
12
+ import { previewCommand } from "./commands/preview.js";
13
+ import { doctorCommand } from "./commands/doctor.js";
14
+ import { auditCommand } from "./commands/audit.js";
15
+ import { explainCommand } from "./commands/explain.js";
16
+ import { generateCommand } from "./commands/generate.js";
17
+ import { improveCommand } from "./commands/improve.js";
18
+ import { guardCommand } from "./commands/guard.js";
19
+ import { patchCommand } from "./commands/patch.js";
20
+ import { rollbackCommand } from "./commands/rollback.js";
21
+ import { testCommand } from "./commands/test.js";
22
+ import { lintCommand } from "./commands/lint.js";
23
+ import { deployCommand } from "./commands/deploy.js";
24
+ import { adapterAddCommand } from "./commands/adapter.js";
25
+ import { agentListCommand, agentRunCommand } from "./commands/agent-cmd.js";
26
+ import { contractValidateCommand, contractInitCommand, } from "./commands/contract-cmd.js";
27
+ const __dirname = dirname(fileURLToPath(import.meta.url));
28
+ const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
29
+ program
30
+ .name("portal")
31
+ .description("Portal — agent-native web framework by Interchained")
32
+ .version(pkg.version, "-v, --version");
33
+ // ── Dev & build ───────────────────────────────────────────────────────────────
34
+ program
35
+ .command("dev")
36
+ .description("Start the Portal dev server")
37
+ .option("-p, --port <number>", "Port", parseInt)
38
+ .option("-H, --host", "Expose to all network interfaces")
39
+ .option("-o, --open", "Open in browser")
40
+ .action((opts) => devCommand(opts));
41
+ program
42
+ .command("build")
43
+ .description("Build for production")
44
+ .option("--out-dir <dir>", "Output directory", "dist")
45
+ .option("--mode <mode>", "Build mode", "production")
46
+ .option("--ssr", "Enable SSR build")
47
+ .action((opts) => buildCommand(opts));
48
+ program
49
+ .command("preview")
50
+ .description("Run the production build locally")
51
+ .option("-p, --port <number>", "Port", parseInt)
52
+ .action((opts) => previewCommand(opts));
53
+ // ── Health & docs ─────────────────────────────────────────────────────────────
54
+ program
55
+ .command("doctor")
56
+ .description("Check environment, config, contracts, and routes for issues")
57
+ .action(() => doctorCommand());
58
+ program
59
+ .command("explain <target>")
60
+ .description("Explain a route, component, or contract in plain English")
61
+ .action((target) => explainCommand(target));
62
+ // ── Audit & improve ───────────────────────────────────────────────────────────
63
+ program
64
+ .command("audit")
65
+ .description("Audit the app against its contract (SEO, CTA, brand, a11y, quality)")
66
+ .option("--ai", "Enable AI-powered deep analysis")
67
+ .option("--json", "Output as JSON")
68
+ .option("--category <cat>", "seo | cta | links | brand | accessibility | quality")
69
+ .option("--routes-dir <dir>", "Path to routes directory")
70
+ .action((opts) => auditCommand(opts));
71
+ program
72
+ .command("improve [target]")
73
+ .description("Generate AI patches to fix audit findings")
74
+ .option("--target <cat>", "Only fix one category")
75
+ .option("--auto", "Apply without prompting")
76
+ .option("--no-sentinel", "Skip sentinel review")
77
+ .option("--routes-dir <dir>", "Path to routes directory")
78
+ .action((target, opts) => improveCommand({ ...opts, target: target ?? opts.target }));
79
+ // ── Generation ────────────────────────────────────────────────────────────────
80
+ program
81
+ .command("generate <type> <description>")
82
+ .description("Generate: page | component | api | landing")
83
+ .option("-r, --route <path>", "Explicit route path, e.g. /about")
84
+ .option("--auto", "Write immediately without approval")
85
+ .option("--no-sentinel", "Skip sentinel review")
86
+ .action((type, description, opts) => generateCommand(type, description, opts));
87
+ // ── Agent safety ──────────────────────────────────────────────────────────────
88
+ program
89
+ .command("guard")
90
+ .description("Run safety checks on pending patches")
91
+ .option("--apply", "Apply patches that pass all guard checks")
92
+ .action((opts) => guardCommand(opts));
93
+ program
94
+ .command("patch")
95
+ .description("Review and apply a pending agent-generated patch")
96
+ .action(() => patchCommand());
97
+ program
98
+ .command("rollback [id]")
99
+ .description("Revert the last applied Portal patch")
100
+ .action((id) => rollbackCommand({ id }));
101
+ // ── Engineering discipline ────────────────────────────────────────────────────
102
+ program
103
+ .command("test")
104
+ .description("Run project tests and framework-aware checks")
105
+ .option("--watch", "Run in watch mode")
106
+ .action((opts) => testCommand(opts));
107
+ program
108
+ .command("lint")
109
+ .description("ESLint + TypeScript + contract schema validation")
110
+ .action(() => lintCommand());
111
+ // ── Deployment ────────────────────────────────────────────────────────────────
112
+ program
113
+ .command("deploy")
114
+ .description("Build and prepare deployment (static | node | docker)")
115
+ .option("--adapter <name>", "static | node | docker")
116
+ .option("--out-dir <dir>", "Output directory", "dist")
117
+ .option("--tag <tag>", "Docker image tag")
118
+ .action((opts) => deployCommand({ adapter: opts.adapter, outDir: opts.outDir, tag: opts.tag }));
119
+ // ── Adapters ──────────────────────────────────────────────────────────────────
120
+ const adapter = program
121
+ .command("adapter")
122
+ .description("Manage deployment adapters");
123
+ adapter
124
+ .command("add <name>")
125
+ .description("Add a deployment adapter config (static | node | docker)")
126
+ .action((name) => adapterAddCommand(name));
127
+ // ── Agent management ──────────────────────────────────────────────────────────
128
+ const agent = program
129
+ .command("agent")
130
+ .description("Manage and run Portal agents");
131
+ agent
132
+ .command("list")
133
+ .description("List all configured agents and their permissions")
134
+ .action(() => agentListCommand());
135
+ agent
136
+ .command("run <name>")
137
+ .description("Run a specific agent task manually")
138
+ .action((name) => agentRunCommand(name));
139
+ // ── Contract ──────────────────────────────────────────────────────────────────
140
+ const contract = program
141
+ .command("contract")
142
+ .description("Manage app contracts");
143
+ contract
144
+ .command("validate")
145
+ .description("Validate app.contract.ts and all related contract files")
146
+ .action(() => contractValidateCommand());
147
+ contract
148
+ .command("init")
149
+ .description("Scaffold default contracts for a new or existing Portal app")
150
+ .action(() => contractInitCommand());
151
+ program.parse(process.argv);
152
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Load app.contract.ts from a Portal project.
3
+ * Uses a simple regex-based extraction since we can't dynamically import TS at runtime.
4
+ * For full evaluation, we'd use jiti/tsx — but for MVP we parse the exported object.
5
+ */
6
+ import { type AppContract } from "@interchained/portal-contract";
7
+ export declare function findContractPath(root: string): Promise<string | null>;
8
+ /**
9
+ * Load a contract from a Portal project.
10
+ * Attempts to read and evaluate the contract file.
11
+ * Falls back to a safe empty contract if not found.
12
+ */
13
+ export declare function loadContract(root?: string): Promise<AppContract>;
14
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/utils/contract.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAC;AASnF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS3E;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,SAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAuB7E"}