itiger 0.1.0

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/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # itiger
2
+
3
+ `itiger` is a thin command adapter for internal development tools. It delegates
4
+ all work to the locally installed CLIs and never stores or manages credentials.
5
+
6
+ ```bash
7
+ npx itiger skills add fed/skills
8
+ npx itiger install -g @tiger/example
9
+ ```
10
+
11
+ `skills add owner/repo` is translated to
12
+ `https://git.tigerbrokers.net/owner/repo.git`; Git authentication remains under
13
+ the user's normal SSH keys or Git credential helper. Other `skills` arguments
14
+ and output are passed through unchanged.
15
+
16
+ When installing an `@tiger/*` package, `itiger` adds
17
+ `--@tiger:registry=http://r.npm.tigerfintech.com` unless `--registry` or an
18
+ explicit `--@tiger:registry` option is already present. Non-Tiger packages are
19
+ delegated without registry changes.
20
+
21
+ Requirements: Node.js 18 or newer, plus the local `skills` CLI for `skills`
22
+ commands and npm for package installation.
23
+
24
+ ## Development
25
+
26
+ ```bash
27
+ npm test
28
+ ```
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "itiger",
3
+ "version": "0.1.0",
4
+ "description": "A thin adapter for internal skills and @tiger npm packages.",
5
+ "type": "commonjs",
6
+ "bin": {
7
+ "itiger": "src/cli.js"
8
+ },
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
12
+ "files": [
13
+ "src"
14
+ ],
15
+ "scripts": {
16
+ "test": "node --test"
17
+ },
18
+ "license": "UNLICENSED"
19
+ }
package/src/cli.js ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { runSkills } = require('./skills-adapter');
4
+ const { runNpm } = require('./npm-adapter');
5
+
6
+ async function main() {
7
+ const args = process.argv.slice(2);
8
+ if (args[0] === 'skills') {
9
+ return runSkills(args.slice(1));
10
+ }
11
+ if (args[0] === 'install' || args[0] === 'i') {
12
+ return runNpm(args);
13
+ }
14
+
15
+ process.stderr.write('Usage: itiger skills add <owner/repo> [skills options...]\n');
16
+ process.stderr.write(' itiger install [npm options...] <package...>\n');
17
+ return 2;
18
+ }
19
+
20
+ main()
21
+ .then((code) => {
22
+ if (code !== 0) process.exitCode = code;
23
+ })
24
+ .catch((error) => {
25
+ process.stderr.write(`itiger: ${error.message}\n`);
26
+ process.exitCode = 1;
27
+ });
@@ -0,0 +1,27 @@
1
+ const { runCommand } = require('./process');
2
+
3
+ const TIGER_REGISTRY = 'http://r.npm.tigerfintech.com';
4
+
5
+ function hasExplicitRegistry(args) {
6
+ return args.some((arg, index) => (
7
+ arg === '--registry' ||
8
+ arg.startsWith('--registry=') ||
9
+ arg.startsWith('--@tiger:registry=') ||
10
+ (arg === '--@tiger:registry' && index + 1 < args.length)
11
+ ));
12
+ }
13
+
14
+ function hasTigerPackage(args) {
15
+ return args.some((arg) => /^@tiger\/[^/]+$/.test(arg));
16
+ }
17
+
18
+ function transformArgs(args) {
19
+ if (!hasTigerPackage(args) || hasExplicitRegistry(args)) return [...args];
20
+ return [...args, `--@tiger:registry=${TIGER_REGISTRY}`];
21
+ }
22
+
23
+ function runNpm(args) {
24
+ return runCommand('npm', transformArgs(args));
25
+ }
26
+
27
+ module.exports = { TIGER_REGISTRY, hasExplicitRegistry, hasTigerPackage, transformArgs, runNpm };
package/src/process.js ADDED
@@ -0,0 +1,28 @@
1
+ const { spawn } = require('node:child_process');
2
+
3
+ function runCommand(command, args) {
4
+ return new Promise((resolve) => {
5
+ let child;
6
+ try {
7
+ child = spawn(command, args, { stdio: 'inherit' });
8
+ } catch (error) {
9
+ process.stderr.write(`itiger: unable to start ${command}: ${error.message}\n`);
10
+ resolve(1);
11
+ return;
12
+ }
13
+
14
+ child.on('error', (error) => {
15
+ process.stderr.write(`itiger: unable to start ${command}: ${error.message}\n`);
16
+ resolve(1);
17
+ });
18
+ child.on('exit', (code, signal) => {
19
+ resolve(code === null ? 128 + signalNumber(signal) : code);
20
+ });
21
+ });
22
+ }
23
+
24
+ function signalNumber(signal) {
25
+ return { SIGINT: 2, SIGTERM: 15, SIGHUP: 1 }[signal] || 1;
26
+ }
27
+
28
+ module.exports = { runCommand };
@@ -0,0 +1,38 @@
1
+ const { runCommand } = require('./process');
2
+
3
+ const INTERNAL_GIT_HOST = 'git.tigerbrokers.net';
4
+
5
+ function mapRepository(repository) {
6
+ const githubUrl = repository.match(/^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/#?]+?)(?:\.git)?\/?$/i);
7
+ if (githubUrl) {
8
+ return `https://${INTERNAL_GIT_HOST}/${githubUrl[1]}/${githubUrl[2]}.git`;
9
+ }
10
+
11
+ const shorthand = repository.match(/^([^/]+)\/([^/]+)$/);
12
+ if (shorthand) {
13
+ return `https://${INTERNAL_GIT_HOST}/${shorthand[1]}/${shorthand[2]}.git`;
14
+ }
15
+
16
+ return repository;
17
+ }
18
+
19
+ function transformArgs(args) {
20
+ const transformed = [...args];
21
+ if (transformed[0] !== 'add') return transformed;
22
+
23
+ const repositoryIndex = transformed.findIndex((arg, index) => index > 0 && !arg.startsWith('-'));
24
+ if (repositoryIndex !== -1) {
25
+ transformed[repositoryIndex] = mapRepository(transformed[repositoryIndex]);
26
+ }
27
+ return transformed;
28
+ }
29
+
30
+ function runSkills(args) {
31
+ if (args.length === 0 || args[0] !== 'add') {
32
+ process.stderr.write('itiger: only "skills add" is supported through this adapter\n');
33
+ return Promise.resolve(2);
34
+ }
35
+ return runCommand('skills', transformArgs(args));
36
+ }
37
+
38
+ module.exports = { INTERNAL_GIT_HOST, mapRepository, transformArgs, runSkills };