gitea-cli-skill 0.1.0 → 0.1.7

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/assets/SKILL.md CHANGED
@@ -126,6 +126,7 @@ gitea-cli commit get <sha> --output json
126
126
  gitea-cli issue list --state open --output json
127
127
  gitea-cli issue get <number> --output json
128
128
  gitea-cli issue create -t "Title" -b "Body" --label <id> --milestone <id>
129
+ gitea-cli issue create -t "Title" --attach ./image.png --attach ./log.txt # embed attachments in body
129
130
  gitea-cli issue update <number> -t "New Title" --state closed
130
131
  gitea-cli issue close <number>
131
132
 
@@ -225,6 +226,7 @@ gitea-cli webhook test <id>
225
226
  gitea-cli release list --output json
226
227
  gitea-cli release get <tag> --output json
227
228
  gitea-cli release create --tag <tag> --name "Title" --body "Notes" --target <ref> --draft --prerelease
229
+ gitea-cli release create --tag <tag> --body-file changelog.md # use file for release notes (avoids encoding issues)
228
230
  gitea-cli release delete <tag> --force
229
231
 
230
232
  # Assets
@@ -259,6 +261,17 @@ gitea-cli milestone list --output json --owner myorg --repo myrepo
259
261
  gitea-cli issue create -t "Fix login bug" -b "Description" --label 3 --label 7 --milestone 2 --owner myorg --repo myrepo
260
262
  ```
261
263
 
264
+ ### Create issue with attachments
265
+
266
+ ```bash
267
+ # Attach images (auto-embedded as markdown images) and files (embedded as links)
268
+ gitea-cli issue create -t "Bug screenshot" -b "Steps to reproduce..." \
269
+ --attach ./screenshot.png --attach ./error.log --owner myorg --repo myrepo
270
+
271
+ # Supported image formats: png, jpg, jpeg, gif, webp, bmp, svg
272
+ # Other file types are embedded as download links
273
+ ```
274
+
262
275
  ### Monitor CI/CD pipeline
263
276
 
264
277
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitea-cli-skill",
3
- "version": "0.1.0",
3
+ "version": "0.1.7",
4
4
  "description": "Install gitea-cli as a Claude Code skill",
5
5
  "bin": {
6
6
  "gitea-cli-skill": "src/index.js"
package/src/index.js CHANGED
@@ -251,19 +251,19 @@ function installFromLocal(localDir, scriptsDir, destBinary, osArch) {
251
251
 
252
252
  async function installFromRelease(giteaHost, token, scriptsDir, destBinary, osArch) {
253
253
  console.log(` Fetching latest release from ${giteaHost}...`);
254
- if (!token) {
255
- console.error(' Error: Gitea API token is required.');
256
- console.error(' Provide via --token <token> or GITEA_TOKEN env var.');
257
- console.error(' Or use --local <dir> to install from a local build.');
258
- process.exit(1);
259
- }
260
254
 
261
255
  let release;
262
256
  try {
263
257
  release = getLatestRelease(giteaHost, GITEA_OWNER, GITEA_REPO, token);
264
258
  } catch (err) {
265
- console.error(` Failed to fetch release: ${err.message}`);
266
- console.error(' Use --local <dir> to install from a local build instead.');
259
+ if (!token) {
260
+ console.error(` Failed to fetch release without token: ${err.message}`);
261
+ console.error(' Repository may be private. Provide --token or GITEA_TOKEN env var.');
262
+ console.error(' Or use --local <dir> to install from a local build.');
263
+ } else {
264
+ console.error(` Failed to fetch release: ${err.message}`);
265
+ console.error(' Use --local <dir> to install from a local build instead.');
266
+ }
267
267
  process.exit(1);
268
268
  }
269
269
 
@@ -291,10 +291,62 @@ async function installFromRelease(giteaHost, token, scriptsDir, destBinary, osAr
291
291
  }
292
292
  }
293
293
 
294
+ // ── Context command ─────────────────────────────────────────────────────────
295
+
296
+ async function addContext(args) {
297
+ const { token: explicitToken, host: explicitHost, 'default-owner': defaultOwner, 'default-repo': defaultRepo, name: contextName } = args;
298
+ const host = explicitHost || GITEA_HOST;
299
+ const token = explicitToken || process.env.GITEA_TOKEN || null;
300
+
301
+ if (!token) {
302
+ console.error('Error: --token or GITEA_TOKEN env var is required for context setup.');
303
+ process.exit(1);
304
+ }
305
+ if (!host) {
306
+ console.error('Error: --host is required for context setup.');
307
+ process.exit(1);
308
+ }
309
+
310
+ // Find the installed gitea-cli binary
311
+ const osArch = detectOSArch();
312
+ const binaryName = osArch.os === 'windows' ? 'gitea-cli.exe' : 'gitea-cli';
313
+ const skillDir = path.join(os.homedir(), PLATFORMS.claude.dir, SKILL_NAME);
314
+ const giteaCliBin = path.join(skillDir, 'scripts', `${osArch.os}-${osArch.arch}`, binaryName);
315
+
316
+ if (!fs.existsSync(giteaCliBin)) {
317
+ // Fallback: write config manually
318
+ console.log(' gitea-cli binary not found, writing config directly...');
319
+ writeGiteaCliConfig(host, token);
320
+ console.log('Context configured successfully.');
321
+ return;
322
+ }
323
+
324
+ // Use gitea-cli config set for proper config management
325
+ const ctxName = contextName || 'default';
326
+ const cmdArgs = [
327
+ `"${giteaCliBin}"`,
328
+ 'config', 'set',
329
+ '--name', ctxName,
330
+ '--host', host.replace(/\/$/, ''),
331
+ '--token', token,
332
+ ];
333
+ if (defaultOwner) cmdArgs.push('--default-owner', defaultOwner);
334
+ if (defaultRepo) cmdArgs.push('--default-repo', defaultRepo);
335
+
336
+ try {
337
+ execSync(cmdArgs.join(' '), { stdio: 'inherit', timeout: 10000 });
338
+ } catch (err) {
339
+ console.error(`Failed to configure context: ${err.message}`);
340
+ console.error('You can manually run:');
341
+ console.error(` ${cmdArgs.join(' ')}`);
342
+ process.exit(1);
343
+ }
344
+ }
345
+
294
346
  // ── CLI ──────────────────────────────────────────────────────────────────────
295
347
 
296
348
  function parseArgs(argv) {
297
- const args = { token: null, host: null, platform: null, target: null, local: null, force: false, command: null };
349
+ const args = { token: null, host: null, platform: null, target: null, local: null, force: false, command: null, subcommand: null, name: null, 'default-owner': null, 'default-repo': null };
298
350
 
299
351
  for (let i = 2; i < argv.length; i++) {
300
352
  const arg = argv[i];
@@ -303,9 +355,13 @@ function parseArgs(argv) {
303
355
  else if (arg === '--platform' && i + 1 < argv.length) args.platform = argv[++i];
304
356
  else if (arg === '--target' && i + 1 < argv.length) args.target = argv[++i];
305
357
  else if (arg === '--local' && i + 1 < argv.length) args.local = argv[++i];
358
+ else if (arg === '--name' && i + 1 < argv.length) args.name = argv[++i];
359
+ else if (arg === '--default-owner' && i + 1 < argv.length) args['default-owner'] = argv[++i];
360
+ else if (arg === '--default-repo' && i + 1 < argv.length) args['default-repo'] = argv[++i];
306
361
  else if (arg === '--force' || arg === '-f') args.force = true;
307
362
  else if (arg === '--help' || arg === '-h') { printHelp(); process.exit(0); }
308
- else if (!arg.startsWith('-')) args.command = arg;
363
+ else if (!arg.startsWith('-') && !args.command) args.command = arg;
364
+ else if (!arg.startsWith('-') && args.command && !args.subcommand) args.subcommand = arg;
309
365
  }
310
366
  return args;
311
367
  }
@@ -318,28 +374,49 @@ function printHelp() {
318
374
  console.log(`gitea-cli-skill - Install gitea-cli as an AI agent skill
319
375
 
320
376
  Usage:
321
- npx gitea-cli-skill init [flags]
377
+ npx gitea-cli-skill init [flags] # Install skill
378
+ gitea-cli-skill add context [flags] # Configure Gitea API context
322
379
 
323
380
  Commands:
324
- init Install skill
381
+ init Install skill (download binary + SKILL.md)
382
+ add context Add or update a Gitea API context (requires --token)
325
383
 
326
- Flags:
327
- --token <t> Gitea API token (or set GITEA_TOKEN env var)
384
+ Flags (init):
385
+ --token <t> Gitea API token (needed for private repos, or set GITEA_TOKEN env var)
328
386
  --host <url> Gitea host URL (default: ${GITEA_HOST})
329
387
  --local <dir> Install from local goreleaser dist directory (skip download)
330
388
  --platform <name> Target AI platform (default: claude)
331
389
  --target <path> Custom install directory (overrides --platform)
332
390
  --force Overwrite existing binary
391
+
392
+ Flags (add context):
393
+ --name <name> Context name (default: "default")
394
+ --host <url> Gitea host URL (required)
395
+ --token <t> Gitea API token (required, or set GITEA_TOKEN env var)
396
+ --default-owner <owner> Default repository owner (optional)
397
+ --default-repo <repo> Default repository name (optional)
398
+
399
+ Global:
333
400
  -h, --help Show this help
334
401
 
335
402
  Platforms:
336
403
  ${platformList}
337
404
 
338
405
  Examples:
339
- npx gitea-cli-skill init --local ../dist # from local build
340
- npx gitea-cli-skill init --token abc123 # from Gitea release
341
- npx gitea-cli-skill init --token abc123 --platform cursor # for Cursor
342
- npx gitea-cli-skill init --local ../dist --target ~/custom # custom dir
406
+ # Step 1: Install the skill (no token needed for public repos)
407
+ npx gitea-cli-skill init
408
+
409
+ # Step 2: Configure context
410
+ gitea-cli-skill add context --host https://gitea.example.com --token abc123
411
+
412
+ # Configure context with all options
413
+ gitea-cli-skill add context --name work --host https://gitea.example.com --token abc123 --default-owner myorg
414
+
415
+ # Or install + configure in one step (for private repos)
416
+ npx gitea-cli-skill init --token abc123
417
+
418
+ # Or install from local build
419
+ npx gitea-cli-skill init --local ../dist
343
420
  `);
344
421
  }
345
422
 
@@ -347,20 +424,22 @@ async function main() {
347
424
  const args = parseArgs(process.argv);
348
425
 
349
426
  if (!args.command) { printHelp(); process.exit(0); }
350
- if (args.command !== 'init') {
351
- console.error(`Unknown command: ${args.command}`);
352
- console.error('Run with --help for usage.');
353
- process.exit(1);
354
- }
355
427
 
356
- // Validate platform name
357
- if (args.platform && !PLATFORMS[args.platform] && !args.target) {
358
- console.error(`Unknown platform: ${args.platform}`);
359
- console.error(`Available: ${Object.keys(PLATFORMS).join(', ')}, or use --target for custom path.`);
428
+ if (args.command === 'init') {
429
+ // Validate platform name
430
+ if (args.platform && !PLATFORMS[args.platform] && !args.target) {
431
+ console.error(`Unknown platform: ${args.platform}`);
432
+ console.error(`Available: ${Object.keys(PLATFORMS).join(', ')}, or use --target for custom path.`);
433
+ process.exit(1);
434
+ }
435
+ await install(args);
436
+ } else if (args.command === 'add' && args.subcommand === 'context') {
437
+ await addContext(args);
438
+ } else {
439
+ console.error(`Unknown command: ${args.command}${args.subcommand ? ' ' + args.subcommand : ''}`);
440
+ console.error('Run with --help for usage.');
360
441
  process.exit(1);
361
442
  }
362
-
363
- await install(args);
364
443
  }
365
444
 
366
445
  main().catch((err) => {