Add companies.sh import wrapper
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
56a39fea3d
commit
66d84ccfa3
4 changed files with 202 additions and 0 deletions
75
cli/src/__tests__/companies-sh.test.ts
Normal file
75
cli/src/__tests__/companies-sh.test.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
import { execFileSync, spawnSync } from "node:child_process";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import path from "node:path";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
const scriptPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../../companies.sh");
|
||||||
|
|
||||||
|
function runEcho(args: string[]) {
|
||||||
|
return execFileSync("bash", [scriptPath, ...args], {
|
||||||
|
cwd: path.dirname(scriptPath),
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
COMPANIES_SH_ECHO: "1",
|
||||||
|
},
|
||||||
|
encoding: "utf8",
|
||||||
|
}).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("companies.sh", () => {
|
||||||
|
it("passes through positional source imports with current company import ergonomics", () => {
|
||||||
|
expect(runEcho([
|
||||||
|
"paperclipai/companies/engineering",
|
||||||
|
"--target", "existing",
|
||||||
|
"-C", "company-123",
|
||||||
|
"--dry-run",
|
||||||
|
])).toBe(
|
||||||
|
"pnpm paperclipai company import paperclipai/companies/engineering --target existing -C company-123 --dry-run",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("accepts the optional import verb", () => {
|
||||||
|
expect(runEcho([
|
||||||
|
"import",
|
||||||
|
"./exports/acme",
|
||||||
|
"--include", "agents,skills",
|
||||||
|
"--collision", "rename",
|
||||||
|
])).toBe(
|
||||||
|
"pnpm paperclipai company import ./exports/acme --include agents\\,skills --collision rename",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes legacy --from usage into the positional source argument", () => {
|
||||||
|
expect(runEcho([
|
||||||
|
"--from", "https://github.com/org/repo/tree/main/acme",
|
||||||
|
"--ref", "release/2026-03-23",
|
||||||
|
"--yes",
|
||||||
|
])).toBe(
|
||||||
|
"pnpm paperclipai company import https://github.com/org/repo/tree/main/acme --ref release/2026-03-23 --yes",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("supports --from=value compatibility", () => {
|
||||||
|
expect(runEcho([
|
||||||
|
"--from=org/repo/company-template",
|
||||||
|
"--paperclip-url", "http://localhost:3100",
|
||||||
|
"--json",
|
||||||
|
])).toBe(
|
||||||
|
"pnpm paperclipai company import org/repo/company-template --paperclip-url http://localhost:3100 --json",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fails when no source path or URL is provided", () => {
|
||||||
|
const result = spawnSync("bash", [scriptPath, "--dry-run"], {
|
||||||
|
cwd: path.dirname(scriptPath),
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
COMPANIES_SH_ECHO: "1",
|
||||||
|
},
|
||||||
|
encoding: "utf8",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.status).toBe(1);
|
||||||
|
expect(result.stderr).toContain("source path or URL is required");
|
||||||
|
});
|
||||||
|
});
|
||||||
117
companies.sh
Executable file
117
companies.sh
Executable file
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage:
|
||||||
|
./companies.sh <path-or-url> [paperclipai company import flags...]
|
||||||
|
./companies.sh import <path-or-url> [paperclipai company import flags...]
|
||||||
|
./companies.sh --from <path-or-url> [paperclipai company import flags...]
|
||||||
|
|
||||||
|
Thin wrapper around:
|
||||||
|
pnpm paperclipai company import <path-or-url> ...
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- Accepts the source as the first positional argument, like `paperclipai company import`
|
||||||
|
- Still accepts legacy `--from <path-or-url>` for compatibility
|
||||||
|
- Runs from the repo root so it can be invoked from anywhere
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
./companies.sh org/repo/company-template --dry-run
|
||||||
|
./companies.sh import ./exports/acme --target existing -C company-123
|
||||||
|
./companies.sh --from https://github.com/org/repo/tree/main/acme --ref main
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
printf 'companies.sh: %s\n' "$*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
source_arg=""
|
||||||
|
expect_legacy_source=0
|
||||||
|
pass_through=()
|
||||||
|
|
||||||
|
if [[ $# -gt 0 && "$1" == "import" ]]; then
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
arg="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [[ "$expect_legacy_source" -eq 1 ]]; then
|
||||||
|
[[ -n "$arg" ]] || fail "--from requires a value"
|
||||||
|
[[ -z "$source_arg" ]] || fail "source path or URL was provided more than once"
|
||||||
|
source_arg="$arg"
|
||||||
|
expect_legacy_source=0
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$arg" in
|
||||||
|
help|-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--from)
|
||||||
|
expect_legacy_source=1
|
||||||
|
;;
|
||||||
|
--from=*)
|
||||||
|
value="${arg#--from=}"
|
||||||
|
[[ -n "$value" ]] || fail "--from requires a value"
|
||||||
|
[[ -z "$source_arg" ]] || fail "source path or URL was provided more than once"
|
||||||
|
source_arg="$value"
|
||||||
|
;;
|
||||||
|
--include|--target|-C|--company-id|--new-company-name|--agents|--collision|--ref|--paperclip-url|--api-base)
|
||||||
|
[[ $# -gt 0 ]] || fail "$arg requires a value"
|
||||||
|
pass_through+=("$arg" "$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--yes|--dry-run|--json)
|
||||||
|
pass_through+=("$arg")
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
if [[ $# -gt 0 ]]; then
|
||||||
|
if [[ -z "$source_arg" ]]; then
|
||||||
|
source_arg="$1"
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
fail "unexpected extra positional argument: $1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
pass_through+=("$1")
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
pass_through+=("$arg")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [[ -z "$source_arg" ]]; then
|
||||||
|
source_arg="$arg"
|
||||||
|
else
|
||||||
|
fail "unexpected extra positional argument: $arg"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ "$expect_legacy_source" -eq 0 ]] || fail "--from requires a value"
|
||||||
|
[[ -n "$source_arg" ]] || fail "source path or URL is required"
|
||||||
|
|
||||||
|
cmd=(pnpm paperclipai company import "$source_arg")
|
||||||
|
if [[ "${#pass_through[@]}" -gt 0 ]]; then
|
||||||
|
cmd+=("${pass_through[@]}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${COMPANIES_SH_ECHO:-}" == "1" ]]; then
|
||||||
|
printf '%q ' "${cmd[@]}"
|
||||||
|
printf '\n'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$repo_root"
|
||||||
|
exec "${cmd[@]}"
|
||||||
|
|
@ -54,6 +54,9 @@ pnpm paperclipai company import \
|
||||||
--target new \
|
--target new \
|
||||||
--new-company-name "Acme Imported" \
|
--new-company-name "Acme Imported" \
|
||||||
--include company,agents
|
--include company,agents
|
||||||
|
|
||||||
|
# Repo helper wrapper with the same source-first ergonomics
|
||||||
|
./companies.sh org/repo/company-template --target new --dry-run
|
||||||
```
|
```
|
||||||
|
|
||||||
## Agent Commands
|
## Agent Commands
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,13 @@ paperclipai company import org/repo
|
||||||
paperclipai company import org/repo/companies/acme
|
paperclipai company import org/repo/companies/acme
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you are working inside the Paperclip repo, `./companies.sh` is a thin wrapper around `paperclipai company import`. It accepts the same source-first form and still supports legacy `--from <path-or-url>` compatibility:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./companies.sh org/repo/companies/acme --dry-run
|
||||||
|
./companies.sh --from ./my-export --target existing --company-id abc123
|
||||||
|
```
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Option | Description | Default |
|
| Option | Description | Default |
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue