diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index c27d931..56c3c22 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -5,3 +5,7 @@ {"_type":"issue","id":"gh-toy-69s","title":"Handle SIGINT gracefully (Ctrl-C)","description":"The tool should catch SIGINT (Ctrl-C) and exit cleanly without a Python traceback or incomplete output. Acceptance: Ctrl-C prints 'Interrupted.' and exits with code 130, no stack trace shown, partial output files cleaned up.","status":"open","priority":2,"issue_type":"feature","owner":"azure-pipeline@test.com","created_at":"2026-05-12T20:47:14Z","created_by":"Azure Pipeline","updated_at":"2026-05-12T20:47:14Z","external_ref":"gh-5","labels":["e2e-testing"],"dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"gh-toy-aqd","title":"Add JSON output mode via --json flag","description":"Add a --json flag so all command output can be emitted as machine-readable JSON for scripting and CI pipelines. Acceptance: --json flag accepted on any subcommand, output is valid JSON, human-readable output is default, errors also JSON-formatted.","status":"open","priority":2,"issue_type":"feature","owner":"azure-pipeline@test.com","created_at":"2026-05-12T20:47:13Z","created_by":"Azure Pipeline","updated_at":"2026-05-12T20:47:13Z","external_ref":"gh-4","labels":["e2e-testing"],"dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"gh-toy-s5k","title":"Tag filtering endpoint","description":"GET /api/notes?tag=work returns only notes with that tag. Already partially implemented - needs tests.","status":"open","priority":2,"issue_type":"feature","owner":"azure-pipeline@test.com","created_at":"2026-05-12T20:46:52Z","created_by":"Azure Pipeline","updated_at":"2026-05-12T20:46:52Z","labels":["e2e-testing"],"dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"gh-toy-yjy","title":"Note","status":"closed","priority":2,"issue_type":"task","owner":"akhil@apralabs.com","created_at":"2026-05-12T05:30:38Z","created_by":"Akhil Kumar","updated_at":"2026-05-12T20:12:22Z","closed_at":"2026-05-12T20:12:22Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"gh-toy-06i","title":"Pagination","status":"open","priority":2,"issue_type":"task","owner":"akhil@apralabs.com","created_at":"2026-05-12T05:30:33Z","created_by":"Akhil Kumar","updated_at":"2026-05-12T20:22:14Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"gh-toy-gw1","title":"Full-text","status":"open","priority":2,"issue_type":"task","owner":"akhil@apralabs.com","created_at":"2026-05-12T05:30:24Z","created_by":"Akhil Kumar","updated_at":"2026-05-12T20:22:15Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"gh-toy-bzq","title":"Tag filtering endpoint","description":"GET /api/notes?tag=work returns only notes with that tag. Already partially implemented — needs tests.","status":"open","priority":2,"issue_type":"feature","owner":"azure-pipeline@test.com","created_at":"2026-05-09T03:13:59Z","created_by":"Azure Pipeline","updated_at":"2026-05-12T20:22:15Z","dependency_count":0,"dependent_count":0,"comment_count":0} diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 0000000..926c9e6 --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,28 @@ +import { validateString } from "./utils/validation"; + +export function runCLI(args: string[]) { + if (args.includes("--version") || args.includes("-v")) { + console.log("fleet-e2e-toy v1.0.0"); + process.exit(0); + } + + if (args.includes("--help") || args.includes("-h") || args.includes("help")) { + console.log("Usage: fleet-e2e-toy [options] [command] [argument]"); + console.log(""); + console.log("Options:"); + console.log(" -v, --version Print version information"); + console.log(" -h, --help Print help information"); + console.log(""); + console.log("Commands:"); + console.log(" help Print help information"); + process.exit(0); + } + + if (args.length > 0) { + const arg = args[0]; + if (!validateString(arg)) { + console.error("Error: Input cannot be empty or whitespace only."); + process.exit(1); + } + } +} diff --git a/src/index.ts b/src/index.ts index 9e7603c..45fbcd4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,11 @@ import app from "./app"; +import { runCLI } from "./cli"; + +const args = process.argv.slice(2); + +if (args.length > 0) { + runCLI(args); +} const PORT = process.env.PORT ?? 3000; diff --git a/src/utils/validation.ts b/src/utils/validation.ts index 9cfb289..f50553e 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -76,3 +76,7 @@ export function validateUpdateInput( return { valid: true, data }; } + +export function validateString(input: string): boolean { + return input.trim().length > 0; +} diff --git a/tests/validation.test.ts b/tests/validation.test.ts index f55f70f..374e825 100644 --- a/tests/validation.test.ts +++ b/tests/validation.test.ts @@ -1,4 +1,4 @@ -import { validateCreateInput, validateUpdateInput } from "../src/utils/validation"; +import { validateCreateInput, validateUpdateInput, validateString } from "../src/utils/validation"; describe("validateCreateInput", () => { it("accepts valid input with all fields", () => { @@ -64,3 +64,16 @@ describe("validateUpdateInput", () => { expect(result.valid).toBe(true); }); }); + +describe("validateString", () => { + it("returns true for non-empty strings", () => { + expect(validateString("hello")).toBe(true); + expect(validateString(" a ")).toBe(true); + }); + + it("returns false for empty or whitespace-only strings", () => { + expect(validateString("")).toBe(false); + expect(validateString(" ")).toBe(false); + expect(validateString("\t\n")).toBe(false); + }); +}); diff --git a/tool b/tool new file mode 100644 index 0000000..00f63e9 --- /dev/null +++ b/tool @@ -0,0 +1,2 @@ +#!/bin/bash +npx ts-node src/index.ts "$@"