@buba_71/levit 0.3.3 → 0.3.4

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/bin/cli.js CHANGED
@@ -4,18 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- const init_1 = require("../src/init");
7
+ const init_1 = require("../src/commands/init");
8
+ const version_1 = require("../src/core/version");
8
9
  const node_path_1 = __importDefault(require("node:path"));
9
- const fs_extra_1 = __importDefault(require("fs-extra"));
10
- function getVersion() {
11
- try {
12
- const packageJson = fs_extra_1.default.readJsonSync(node_path_1.default.join(__dirname, "..", "..", "package.json"));
13
- return packageJson.version;
14
- }
15
- catch {
16
- return "unknown";
17
- }
18
- }
19
10
  function showHelp() {
20
11
  console.log(`
21
12
  Usage: levit [command] [options]
@@ -35,7 +26,7 @@ function main() {
35
26
  process.exit(0);
36
27
  }
37
28
  if (args.includes("-v") || args.includes("--version")) {
38
- console.log(`levit-kit v${getVersion()}`);
29
+ console.log(`levit-kit v${(0, version_1.getVersion)()}`);
39
30
  process.exit(0);
40
31
  }
41
32
  if (args[0] === "init") {
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initProject = initProject;
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const paths_1 = require("../core/paths");
9
+ const version_1 = require("../core/version");
10
+ const init_1 = require("../init");
11
+ /**
12
+ * Initializes a new project by copying the default template.
13
+ *
14
+ * @param projectName The name of the project to create
15
+ * @param targetPath The absolute path where the project should be created
16
+ */
17
+ function initProject(projectName, targetPath) {
18
+ const templatePath = (0, paths_1.getTemplatePath)("default");
19
+ const version = (0, version_1.getVersion)();
20
+ if (!projectName) {
21
+ throw new Error("Project name is required.");
22
+ }
23
+ // Ensure project name is valid for a directory
24
+ if (!/^[a-z0-9-_]+$/i.test(projectName)) {
25
+ throw new Error("Invalid project name. Use only letters, numbers, dashes, and underscores.");
26
+ }
27
+ if (fs_extra_1.default.existsSync(targetPath)) {
28
+ throw new Error(`Directory "${projectName}" already exists.`);
29
+ }
30
+ if (!fs_extra_1.default.existsSync(templatePath)) {
31
+ throw new Error(`Default template not found at ${templatePath}`);
32
+ }
33
+ try {
34
+ (0, init_1.generateProject)(targetPath, "default");
35
+ console.log("");
36
+ console.log(`🚀 levit-kit v${version}`);
37
+ console.log("");
38
+ console.log(" ✔ Structure initialized");
39
+ console.log(" ✔ Conventions applied");
40
+ console.log("");
41
+ console.log(`✨ Project "${projectName}" is ready for development.`);
42
+ console.log("");
43
+ console.log("Next steps:");
44
+ console.log(` 1. cd ${projectName}`);
45
+ console.log(" 2. Review SOCIAL_CONTRACT.md to understand the foundations");
46
+ console.log(" 3. Define your first feature in features/README.md");
47
+ console.log("");
48
+ }
49
+ catch (error) {
50
+ // Attempt clean up if directory was created but copy failed
51
+ if (fs_extra_1.default.existsSync(targetPath) && fs_extra_1.default.readdirSync(targetPath).length === 0) {
52
+ fs_extra_1.default.rmSync(targetPath, { recursive: true, force: true });
53
+ }
54
+ throw error;
55
+ }
56
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getPackageRoot = getPackageRoot;
7
+ exports.getTemplatesPath = getTemplatesPath;
8
+ exports.getTemplatePath = getTemplatePath;
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ /**
11
+ * Resolves the root directory of the levit-kit package.
12
+ * Assuming this file is at src/core/paths.ts,
13
+ * after compilation it will be at dist/src/core/paths.js.
14
+ */
15
+ function getPackageRoot() {
16
+ return node_path_1.default.resolve(__dirname, "..", "..", "..");
17
+ }
18
+ /**
19
+ * Returns the absolute path to the templates directory.
20
+ */
21
+ function getTemplatesPath() {
22
+ return node_path_1.default.join(getPackageRoot(), "templates");
23
+ }
24
+ /**
25
+ * Returns the absolute path to a specific template.
26
+ */
27
+ function getTemplatePath(templateName = "default") {
28
+ return node_path_1.default.join(getTemplatesPath(), templateName);
29
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getVersion = getVersion;
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const paths_1 = require("./paths");
10
+ /**
11
+ * Reads and returns the version from the package.json.
12
+ */
13
+ function getVersion() {
14
+ try {
15
+ const packageJsonPath = node_path_1.default.join((0, paths_1.getPackageRoot)(), "package.json");
16
+ const packageJson = fs_extra_1.default.readJsonSync(packageJsonPath);
17
+ return packageJson.version || "unknown";
18
+ }
19
+ catch {
20
+ return "unknown";
21
+ }
22
+ }
package/dist/src/init.js CHANGED
@@ -3,49 +3,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.initProject = initProject;
6
+ exports.generateProject = generateProject;
7
7
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
- const node_path_1 = __importDefault(require("node:path"));
9
- function getPackageRoot() {
10
- // Use __dirname to reliably locate the package root relative to this file
11
- // compiled file is in dist/src/init.js, so we go up two levels to reach package root
12
- return node_path_1.default.resolve(__dirname, "..", "..");
13
- }
14
- function getVersion() {
15
- try {
16
- const packageJson = fs_extra_1.default.readJsonSync(node_path_1.default.join(getPackageRoot(), "package.json"));
17
- return packageJson.version;
18
- }
19
- catch {
20
- return "0.0.0";
21
- }
22
- }
23
- function initProject(projectName, targetPath) {
24
- const packageRoot = getPackageRoot();
25
- const templatePath = node_path_1.default.join(packageRoot, "templates", "default");
26
- const version = getVersion();
27
- if (!projectName) {
28
- throw new Error("Project name is required.");
29
- }
30
- if (fs_extra_1.default.existsSync(targetPath)) {
31
- throw new Error(`Directory "${projectName}" already exists.`);
32
- }
8
+ const paths_1 = require("./core/paths");
9
+ /**
10
+ * Core generation logic for a new project.
11
+ * Responsible only for file system operations.
12
+ */
13
+ function generateProject(targetPath, templateName = "default") {
14
+ const templatePath = (0, paths_1.getTemplatePath)(templateName);
33
15
  if (!fs_extra_1.default.existsSync(templatePath)) {
34
- throw new Error(`Default template not found at ${templatePath}`);
16
+ throw new Error(`Template "${templateName}" not found.`);
17
+ }
18
+ if (fs_extra_1.default.existsSync(targetPath) && fs_extra_1.default.readdirSync(targetPath).length > 0) {
19
+ throw new Error(`Target directory "${targetPath}" is not empty.`);
35
20
  }
36
21
  fs_extra_1.default.ensureDirSync(targetPath);
37
22
  fs_extra_1.default.copySync(templatePath, targetPath);
38
- console.log("");
39
- console.log(`🚀 levit-kit v${version}`);
40
- console.log("");
41
- console.log(" ✔ Project directory created");
42
- console.log(" ✔ Template copied");
43
- console.log("");
44
- console.log(`✨ Project "${projectName}" initialized successfully.`);
45
- console.log("");
46
- console.log("Next steps:");
47
- console.log(` - cd ${projectName}`);
48
- console.log(" - Read SOCIAL_CONTRACT.md");
49
- console.log(" - Start defining features");
50
- console.log("");
51
23
  }
@@ -8,7 +8,8 @@ const node_assert_1 = __importDefault(require("node:assert"));
8
8
  const node_fs_1 = __importDefault(require("node:fs"));
9
9
  const node_path_1 = __importDefault(require("node:path"));
10
10
  const node_os_1 = __importDefault(require("node:os"));
11
- const init_1 = require("../src/init");
11
+ const node_child_process_1 = require("node:child_process");
12
+ const init_1 = require("../src/commands/init");
12
13
  function exists(p) {
13
14
  return node_fs_1.default.existsSync(p);
14
15
  }
@@ -26,8 +27,32 @@ function exists(p) {
26
27
  node_assert_1.default.ok(exists(node_path_1.default.join(projectPath, "roles")));
27
28
  node_assert_1.default.ok(exists(node_path_1.default.join(projectPath, "pipelines")));
28
29
  node_assert_1.default.ok(exists(node_path_1.default.join(projectPath, "docs")));
30
+ node_assert_1.default.ok(exists(node_path_1.default.join(projectPath, "roles", "README.md")), "Roles README should exist");
31
+ // New files assertions
32
+ node_assert_1.default.ok(exists(node_path_1.default.join(projectPath, ".gitignore")), ".gitignore should exist");
33
+ node_assert_1.default.ok(exists(node_path_1.default.join(projectPath, "package.json")), "package.json should exist");
29
34
  // Agent boundaries
30
35
  node_assert_1.default.ok(exists(node_path_1.default.join(projectPath, "agents", "AGENTS.md")), "Agent guidelines should exist");
31
36
  // Feature contract
32
37
  node_assert_1.default.ok(exists(node_path_1.default.join(projectPath, "features", "README.md")), "Feature README should exist");
38
+ // Clean up
39
+ node_fs_1.default.rmSync(tempDir, { recursive: true, force: true });
40
+ });
41
+ (0, node_test_1.default)("CLI --help works", () => {
42
+ const output = (0, node_child_process_1.execSync)("node dist/bin/cli.js --help").toString();
43
+ node_assert_1.default.ok(output.includes("Usage: levit [command] [options]"));
44
+ node_assert_1.default.ok(output.includes("init <project-name>"));
45
+ });
46
+ (0, node_test_1.default)("CLI --version works", () => {
47
+ const output = (0, node_child_process_1.execSync)("node dist/bin/cli.js --version").toString();
48
+ node_assert_1.default.ok(output.startsWith("levit-kit v"));
49
+ });
50
+ (0, node_test_1.default)("CLI name validation works", () => {
51
+ try {
52
+ (0, node_child_process_1.execSync)("node dist/bin/cli.js init invalid/name");
53
+ node_assert_1.default.fail("Should have failed with invalid name");
54
+ }
55
+ catch (error) {
56
+ node_assert_1.default.ok(error.stderr.toString().includes("Error: Invalid project name"));
57
+ }
33
58
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buba_71/levit",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Hybrid starter kit for Antigravity projects",
5
5
  "author": "David BUBA",
6
6
  "license": "MIT",
@@ -10,4 +10,11 @@ Agents are not allowed to:
10
10
  - restructure the repository
11
11
  - introduce implicit behavior
12
12
 
13
+ ---
14
+
15
+ ## Related Resources
16
+
17
+ - [Project Roles](../roles/README.md): Understand the specific responsibilities within this project.
18
+ - [Feature Contracts](../features/README.md): High-level intents and constraints for new developments.
19
+
13
20
  When unsure, agents must ask for human validation.
@@ -6,3 +6,5 @@ Add pipelines only when:
6
6
  - the need is explicit
7
7
  - the impact is understood
8
8
  - the behavior is documented
9
+
10
+ Favor **modular CI/CD configurations** that remain intelligible and decoupled from the business logic.
@@ -0,0 +1,13 @@
1
+ # Project Roles
2
+
3
+ This directory contains the definitions of human and agent roles within this project.
4
+
5
+ ## Available Roles
6
+
7
+ - [DevOps](devops.md): Infrastructure, deployment, and operational requirements.
8
+ - [QA](qa.md): Quality standards, testing expectations, and validation criteria.
9
+ - [Security](security.md): Threat assumptions and security constraints.
10
+
11
+ ## Goal
12
+
13
+ The goal of defining roles is to **reduce ambiguity**. Each role document should clearly state its boundaries and responsibilities to facilitate collaboration between humans and AI agents.