glab-agent 0.2.0 → 0.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glab-agent",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "description": "Multi-agent GitLab To-Do watcher with YAML-defined agents, skills, and GitLab registry.",
6
6
  "license": "MIT",
@@ -83,8 +83,8 @@ Options:
83
83
  --project <dir> Target project directory (default: cwd)
84
84
 
85
85
  Commands:
86
- init [name] Initialize .glab-agent/ and optionally create an agent
87
- --provider <claude|codex> --labels <l1,l2> --token-env <VAR>
86
+ init [name] Initialize agent config (--repo for full Agents repo setup)
87
+ --provider <claude|codex> --labels <l1,l2> --repo -h
88
88
  list List all agent definitions
89
89
  start <name|--all> Start agent(s) as background watcher process
90
90
  stop <name|--all> Stop agent(s)
@@ -104,6 +104,9 @@ Commands:
104
104
  skills import <url> Import skills from GitHub repo (--force to overwrite)
105
105
  wiki setup Populate project GitLab Wiki with documentation pages
106
106
  doctor Check prerequisites and environment
107
+
108
+ Options:
109
+ --version, -v Show version
107
110
  `);
108
111
  }
109
112
 
@@ -457,6 +460,12 @@ export async function validateGitlabToken(host: string, token: string): Promise<
457
460
  }
458
461
 
459
462
  async function cmdInit(name?: string, options?: { provider?: string; labels?: string; tokenEnv?: string; repo?: boolean; botUsername?: string }): Promise<void> {
463
+ // Warn if not in a git repository
464
+ if (!existsSync(path.join(PROJECT_DIR, ".git"))) {
465
+ console.warn(`⚠️ No .git/ found in ${PROJECT_DIR}. Are you in the right directory?`);
466
+ console.warn(` Agents repos should be git repositories. Run 'git init' first.\n`);
467
+ }
468
+
460
469
  const base = agentBaseDir(PROJECT_DIR);
461
470
  const dirs = [
462
471
  path.join(base, "agents"),
@@ -570,6 +579,7 @@ heartbeat/
570
579
  console.log(`\nNext steps:`);
571
580
  console.log(` 1. Create an agent: glab-agent init <name> --provider claude`);
572
581
  console.log(` 2. Check dependencies: glab-agent doctor`);
582
+ console.log(`\nTip: Use 'glab-agent init --repo' for a complete Agents management repo with README and defaults.`);
573
583
  if (remote) {
574
584
  console.log(`\nDocumentation: ${wikiUrl(remote.host, remote.projectPath, "getting-started")}`);
575
585
  console.log(` (Run 'glab-agent wiki setup' to populate the project wiki)`);
@@ -618,9 +628,78 @@ heartbeat/
618
628
 
619
629
  // --repo: generate self-contained product landing page README (done after all init so we have remote/provider/botUsername)
620
630
  if (options?.repo) {
631
+ // If no agent name given with --repo, create a default one
632
+ let effectiveName = name;
633
+ if (!effectiveName) {
634
+ const defaultName = "my-bot";
635
+ const provider = (resolvedProvider === "claude" || resolvedProvider === "codex") ? resolvedProvider as "claude" | "codex" : "claude";
636
+ const yamlPath = path.join(base, "agents", `${defaultName}.yaml`);
637
+ try {
638
+ await readFile(yamlPath, "utf8");
639
+ } catch {
640
+ const yamlContent = generateAgentYaml(defaultName, provider, [], "GITLAB_TOKEN", { host: remote?.host });
641
+ await writeFile(yamlPath, yamlContent, "utf8");
642
+ console.log(`Created default agent: ${yamlPath}`);
643
+ effectiveName = defaultName;
644
+ }
645
+ }
646
+
647
+ // Create .env.example
648
+ const envExamplePath = path.join(base, ".env.example");
649
+ try {
650
+ await readFile(envExamplePath, "utf8");
651
+ } catch {
652
+ const host = remote?.host ?? "gitlab.com";
653
+ const protocol = host.startsWith("localhost") || host.startsWith("127.") ? "http" : "https";
654
+ const envExample = `# GitLab Personal Access Token
655
+ # Create at: ${protocol}://${host}/-/user_settings/personal_access_tokens
656
+ # Required scopes: api, read_user, read_repository, write_repository
657
+ # Tip: Use a bot account's token so agent actions appear as the bot, not you.
658
+ GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
659
+ `;
660
+ await writeFile(envExamplePath, envExample, "utf8");
661
+ console.log(`Created ${envExamplePath}`);
662
+ }
663
+
664
+ // Create default skill
665
+ const defaultSkillPath = path.join(base, "skills", "test-before-commit.md");
666
+ try {
667
+ await readFile(defaultSkillPath, "utf8");
668
+ } catch {
669
+ const skillContent = `---
670
+ name: test-before-commit
671
+ description: Always run tests before committing
672
+ ---
673
+
674
+ Before committing any code change, run the project's test suite.
675
+ If tests fail, fix the code before committing.
676
+ Do not skip tests or use --no-verify to bypass hooks.
677
+ `;
678
+ await writeFile(defaultSkillPath, skillContent, "utf8");
679
+ console.log(`Created default skill: ${defaultSkillPath}`);
680
+ }
681
+
682
+ // Create root .gitignore (for the Agents repo itself)
683
+ const rootGitignorePath = path.join(PROJECT_DIR, ".gitignore");
684
+ try {
685
+ await readFile(rootGitignorePath, "utf8");
686
+ } catch {
687
+ const rootGitignore = `.glab-agent/.env
688
+ .glab-agent/state/
689
+ .glab-agent/pid/
690
+ .glab-agent/logs/
691
+ .glab-agent/worktrees/
692
+ .glab-agent/metrics/
693
+ .glab-agent/heartbeat/
694
+ .DS_Store
695
+ `;
696
+ await writeFile(rootGitignorePath, rootGitignore, "utf8");
697
+ console.log(`Created .gitignore`);
698
+ }
699
+
621
700
  const readmePath = path.join(PROJECT_DIR, "README.md");
622
701
  const readmeContent = buildRepoReadme({
623
- agentName: name ?? undefined,
702
+ agentName: effectiveName ?? undefined,
624
703
  provider: resolvedProvider,
625
704
  host: remote?.host,
626
705
  projectPath: remote?.projectPath,
@@ -741,7 +820,7 @@ async function cmdDoctor(): Promise<void> {
741
820
  label: "Agent definitions",
742
821
  ok: false,
743
822
  optional: false,
744
- message: "no .yaml files found in .glab-agent/agents/"
823
+ message: "no agent definitions found in .glab-agent/agents/ — run 'glab-agent init <name> --provider claude' to create one"
745
824
  });
746
825
  }
747
826
 
@@ -1940,6 +2019,28 @@ export function buildClaudeMdSection(agentName?: string, host?: string, projectP
1940
2019
  "- Agent definitions: `.glab-agent/agents/*.yaml`",
1941
2020
  "- Shared skills: `.glab-agent/skills/*.md`",
1942
2021
  "- Tokens: `.glab-agent/.env` (gitignored)",
2022
+ "",
2023
+ "### Agent YAML Format",
2024
+ "",
2025
+ "```yaml",
2026
+ "name: my-bot",
2027
+ "provider: claude # or codex",
2028
+ "gitlab:",
2029
+ " token_env: GITLAB_TOKEN",
2030
+ "prompt:",
2031
+ " preamble: |",
2032
+ " Project-specific instructions here.",
2033
+ "triggers:",
2034
+ " labels: [] # empty = all issues, or [\"bug\", \"feature\"]",
2035
+ " exclude_labels: [\"Done\"]",
2036
+ "skills:",
2037
+ " - test-before-commit",
2038
+ "poll_interval_seconds: 60",
2039
+ "```",
2040
+ "",
2041
+ "### Setup New Agents Repo",
2042
+ "",
2043
+ "`glab-agent init --repo` creates a complete Agents management repo with README, default agent, skills, and .env template.",
1943
2044
  );
1944
2045
  if (host && projectPath) {
1945
2046
  const protocol = host.startsWith("localhost") || host.startsWith("127.") ? "http" : "https";
@@ -1982,6 +2083,11 @@ export function buildAgentSkill(): string {
1982
2083
  "- `glab-agent history <name>` — Show recent execution history",
1983
2084
  "- `glab-agent report <name> --since 7d` — Performance report (add `--publish` to write to GitLab Wiki)",
1984
2085
  "",
2086
+ "## Setup",
2087
+ "- `glab-agent init <name> --provider claude` — Create a single agent",
2088
+ "- `glab-agent init --repo` — Create a full Agents management repo (README + default agent + skills)",
2089
+ "- `glab-agent wiki setup` — Populate GitLab Wiki with documentation",
2090
+ "",
1985
2091
  "## Configuration",
1986
2092
  "- Agent YAML: `.glab-agent/agents/<name>.yaml`",
1987
2093
  "- Shared skills: `.glab-agent/skills/<name>.md`",
@@ -2078,8 +2184,39 @@ async function main(): Promise<void> {
2078
2184
  const command = args[0];
2079
2185
  const target = args[1];
2080
2186
 
2187
+ // Handle --version / version / -v
2188
+ if (command === "--version" || command === "version" || command === "-v") {
2189
+ const pkgPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../package.json");
2190
+ try {
2191
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
2192
+ console.log(`glab-agent v${pkg.version}`);
2193
+ } catch {
2194
+ console.log("glab-agent (version unknown)");
2195
+ }
2196
+ return;
2197
+ }
2198
+
2081
2199
  switch (command) {
2082
2200
  case "init": {
2201
+ if (args.includes("--help") || args.includes("-h")) {
2202
+ console.log(`Usage: glab-agent init [<name>] [options]
2203
+
2204
+ Create agent configuration in the current project.
2205
+
2206
+ Options:
2207
+ <name> Agent name (e.g., my-bot). Omit for base init only.
2208
+ --provider <p> AI provider: claude (default) or codex
2209
+ --labels <l> Comma-separated trigger labels
2210
+ --token-env <var> Token env variable name (default: GITLAB_TOKEN)
2211
+ --repo Generate full Agents management repo (README + default agent + skills + .env.example)
2212
+ --help, -h Show this help
2213
+
2214
+ Examples:
2215
+ glab-agent init my-bot --provider claude # Create a Claude agent
2216
+ glab-agent init --repo # Full Agents repo with README
2217
+ glab-agent init my-bot --repo # Agents repo + named agent`);
2218
+ break;
2219
+ }
2083
2220
  const initProvider = extractFlag(args, "--provider");
2084
2221
  const initLabels = extractFlag(args, "--labels");
2085
2222
  const initTokenEnv = extractFlag(args, "--token-env");