Skip to content
Select theme
  • Auto
  • Dark
  • Light

Move your projects with an AI agent

After the copy from Nexus, each project still names Nexus. A coding agent, such as Claude Code, can move a project with you.

The agent changes the files. It asks you for the few steps that need a person.

To make the changes yourself, see Move your projects by hand.

  1. Copy the prompt below.

  2. Fill in its first lines: your two server addresses, and the name of each repository in Nexus and in Telesphorepo. The Repositories page lists the names. A lock after a name means it is private.

  3. Open the agent in the project folder, and paste the prompt.

  4. Read the changes before you commit them.

Gradle or Maven: download addresses only

Prompt: Gradle or Maven, download addresses only
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- maven-public -> maven-public
- maven-releases -> maven-releases
Private repositories (they need a read token): none
Scope: the download addresses only. Publishing stays on Nexus: leave the publish addresses,
credentials and steps as they are.
Do this:
1. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in pom.xml, .mvn/maven.config, every settings.xml,
build.gradle(.kts), settings.gradle(.kts) (pluginManagement,
dependencyResolutionManagement), gradle.properties, gradle/*.gradle(.kts), buildSrc/,
build-logic/, init scripts and gradle/wrapper/gradle-wrapper.properties, and in CI files
(.github/workflows, Jenkinsfile, .gitlab-ci.yml and others), Dockerfiles, compose files,
scripts and READMEs. Also show me what ~/.m2/settings.xml, ~/.gradle/gradle.properties and
~/.gradle/init.d/ on this computer name. For each Nexus repository not in my list, ask me
its name and wait.
2. Change every download address.
https://nexus.example.com/repository/<nexus name>/ becomes
https://repo.example.com/maven/<telesphorepo name>. Only the prefix changes; the files keep
their paths. A <mirror> with <mirrorOf>*</mirrorOf> points at a Telesphorepo group. A
distributionUrl on a Nexus raw repository becomes https://repo.example.com/raw/<name>/<path>;
keep distributionSha256Sum.
3. Lockfiles: Gradle lockfiles and gradle/verification-metadata.xml hold no addresses. Keep
them.
4. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in
ORG_GRADLE_PROJECT_<name>Username and ORG_GRADLE_PROJECT_<name>Password for Gradle, and
TELESPHOREPO_READ_USER and TELESPHOREPO_READ_TOKEN for Maven, here and as CI secrets. Tell
me these names first, and never ask me for the token. Never use the name
TELESPHOREPO_TOKEN: the CLI sets it when it publishes. Wire the variables in. Gradle: in the
maven { } block, name = "<name>" and credentials(PasswordCredentials::class) (Groovy:
credentials(PasswordCredentials)); <name> is the repository name as a Gradle identifier
(my-libs is myLibs). Maven: a <server> whose <id> is the <id> of the repository or mirror,
with ${env.TELESPHOREPO_READ_USER} and ${env.TELESPHOREPO_READ_TOKEN}, in ~/.m2/settings.xml
and in a settings file of the project that CI passes with -s.
5. Watch for these. A hosted repository holds only its own packages: keep mavenCentral(), or
use a group with a proxy of Maven Central. A Maven group merges the versions of all its
members, as Nexus does. Maven refuses http:// addresses other than localhost; Gradle needs
isAllowInsecureProtocol = true for one.
6. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (./gradlew build --refresh-dependencies, or mvn -U
-Dmaven.repo.local=<new empty folder> verify), and check that every download comes from
repo.example.com. If your shell lacks the token variables, ask me to run the build and send
you the output.
7. Report: each file you changed, each Nexus address left and why, and each place you were
unsure about.

Gradle or Maven: full switch-over with publishing

Prompt: Gradle or Maven, full switch-over with publishing
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- maven-public -> maven-public
- maven-releases -> maven-releases
Private repositories (they need a read token): none
Scope: the full switch-over. First the download addresses, then publishing with the
Telesphorepo CLI. The copies refuse uploads until the switch-over, so we rehearse on a test
repository, maven-releases-rehearsal, and move to maven-releases after the switch-over.
Do this:
1. ME, first: ask me for the test repository and the CI pipeline, so I make them while you
work. I make a hosted Maven repository named maven-releases-rehearsal (Repositories page,
New repository), where my account has Publish. A server admin adds the CI pipeline of this
project (Settings › People and CI › CI pipelines) with the repositories
maven-releases-rehearsal and maven-releases. Tell me the values for it: for GitHub Actions,
the GitHub repository, the workflow file and the branch; for Jenkins, the Jenkins address
and the full job name.
2. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in pom.xml, .mvn/maven.config, every settings.xml,
build.gradle(.kts), settings.gradle(.kts) (pluginManagement,
dependencyResolutionManagement), gradle.properties, gradle/*.gradle(.kts), buildSrc/,
build-logic/, init scripts and gradle/wrapper/gradle-wrapper.properties, and in CI files
(.github/workflows, Jenkinsfile, .gitlab-ci.yml and others), Dockerfiles, compose files,
scripts and READMEs. Also show me what ~/.m2/settings.xml, ~/.gradle/gradle.properties and
~/.gradle/init.d/ on this computer name. Note how the project publishes to Nexus today. For
each Nexus repository not in my list, ask me its name and wait.
3. Change every download address.
https://nexus.example.com/repository/<nexus name>/ becomes
https://repo.example.com/maven/<telesphorepo name>. Only the prefix changes; the files keep
their paths. A <mirror> with <mirrorOf>*</mirrorOf> points at a Telesphorepo group. A
distributionUrl on a Nexus raw repository becomes https://repo.example.com/raw/<name>/<path>;
keep distributionSha256Sum.
4. Lockfiles: Gradle lockfiles and gradle/verification-metadata.xml hold no addresses. Keep
them.
5. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in
ORG_GRADLE_PROJECT_<name>Username and ORG_GRADLE_PROJECT_<name>Password for Gradle, and
TELESPHOREPO_READ_USER and TELESPHOREPO_READ_TOKEN for Maven, here and as CI secrets. Tell
me these names first, and never ask me for the token. Never use the name
TELESPHOREPO_TOKEN: the CLI sets it when it publishes. Wire the variables in. Gradle: in the
maven { } block, name = "<name>" and credentials(PasswordCredentials::class) (Groovy:
credentials(PasswordCredentials)); <name> is the repository name as a Gradle identifier
(my-libs is myLibs). Maven: a <server> whose <id> is the <id> of the repository or mirror,
with ${env.TELESPHOREPO_READ_USER} and ${env.TELESPHOREPO_READ_TOKEN}, in ~/.m2/settings.xml
and in a settings file of the project that CI passes with -s.
6. Watch for these. A hosted repository holds only its own packages: keep mavenCentral(), or
use a group with a proxy of Maven Central. A Maven group merges the versions of all its
members, as Nexus does. Maven refuses http:// addresses other than localhost; Gradle needs
isAllowInsecureProtocol = true for one.
7. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (./gradlew build --refresh-dependencies, or mvn -U
-Dmaven.repo.local=<new empty folder> verify), and check that every download comes from
repo.example.com. If your shell lacks the token variables, ask me to run the build and send
you the output.
8. If telesphorepo version fails, install the CLI:
curl -fsSL https://repo.example.com/install.sh | sh (Linux and macOS)
irm https://repo.example.com/install.ps1 | iex (Windows PowerShell)
It goes into ~/.local/bin (Windows: %LOCALAPPDATA%\Programs\telesphorepo). Use the full
path if that folder is not on your PATH yet.
9. Approve this computer: run telesphorepo login https://repo.example.com. It prints a link
and a code, then waits. If your shell shows output only when a command ends, run it in the
background and read its output. ME: give me the link and the code. I open the link, sign
in, check the code, click Approve device and confirm with my second step. Wait until the
CLI prints "This computer is device". This computer can then publish wherever my account
has Publish.
10. Remove the Nexus publishing: the <distributionManagement> entries and <server> credentials
for Nexus, the Nexus staging plugins (nexus-staging-maven-plugin,
io.github.gradle-nexus.publish-plugin) that target our Nexus, and the Nexus repository in
Gradle's publishing { repositories { } } (gradle publish publishes to every repository
there). Keep the maven-publish plugin, the publications, group and version. telesphorepo
publish runs mvn deploy (or ./mvnw) with the repository as the target, or gradle publish
(or ./gradlew) with an init script that adds the repository; the build files keep no
publish address. List the CI secrets nothing uses now.
11. Write telesphorepo.toml next to pom.xml or the Gradle settings file. It holds no secret, and
the project commits it:
server = "https://repo.example.com"
repo = "maven-releases-rehearsal"
If the folder has both Maven and Gradle files, add kind = "maven" or kind = "gradle".
12. CI. GitHub Actions: the publish job gets permissions: id-token: write (keep contents:
read), then actions/checkout@v7, actions/setup-java@v6 (distribution: temurin,
java-version: the project's Java version, such as 21) with no build step, then
- run: curl -fsSL https://repo.example.com/install.sh | sh
- run: telesphorepo publish
Jenkins: keep the build stage (./gradlew build, on Windows .\gradlew.bat build; or mvn -B
verify), and add a publish stage after it. Only that stage gets the identity token, which
lasts 10 minutes. Inside withCredentials([string(credentialsId: 'telesphorepo-id-token',
variable: 'OIDC_TOKEN')]) it runs, on a Unix agent:
curl -fsSL https://repo.example.com/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
telesphorepo publish
and on a Windows agent, in powershell:
& ([scriptblock]::Create((irm https://repo.example.com/install.ps1)))
telesphorepo publish
ME: Jenkins needs the plugin OpenID Connect Provider, and a credential of the kind "OpenID
Connect id token" with the ID telesphorepo-id-token and the audience
https://repo.example.com. A CI job that downloads from a private repository gets the read
token variables from secrets.
13. Publish from this computer: run telesphorepo status and check the command it names, then
run telesphorepo publish. If the server says my account may not publish, ask me for
Publish on maven-releases-rehearsal.
14. Verify: in a new temporary folder, write a minimal Gradle or Maven build that depends on
the group:artifact:version you published, from
https://repo.example.com/maven/maven-releases-rehearsal, and build it with an empty cache.
Then delete the folder.
15. Report: each file you changed, each Nexus address left and why, each place you were unsure
about, the CI secrets nothing uses now, and this note for the switch-over day: set repo in
telesphorepo.toml to maven-releases, check that the CI pipeline lists maven-releases,
publish once, then delete maven-releases-rehearsal.

npm, pnpm, Yarn or Bun: download addresses only

Prompt: npm, pnpm, Yarn or Bun, download addresses only
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- npm-group -> npm-group
- npm-hosted -> npm-hosted
Private repositories (they need a read token): none
Scope: the download addresses only. Publishing stays on Nexus: leave the publish addresses,
credentials and steps as they are.
Do this:
1. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in .npmrc (the project's and ~/.npmrc), .yarnrc.yml,
.yarnrc (Yarn 1), bunfig.toml, package.json (publishConfig, scripts), the lockfiles and the
registry-url input of actions/setup-node, and in CI files (.github/workflows, Jenkinsfile,
.gitlab-ci.yml and others), Dockerfiles, compose files, scripts and READMEs. For each Nexus
repository not in my list, ask me its name and wait.
2. Change every download address.
https://nexus.example.com/repository/<nexus name>/ becomes
https://repo.example.com/npm/<telesphorepo name>/, with the trailing slash. Scoped
registries (@acme:registry=) change the same way; Yarn 2 and later name them in
npmRegistryServer and npmScopes. Remove the Nexus _auth, always-auth and email lines. Bun
reads .npmrc, and bunfig.toml can set [install] registry and scopes. On a hosted
repository, Yarn 4 needs npmMinimalAgeGate: 0, or it installs a version only once it is a
week old; on a group or a proxy, list our own packages in npmPreapprovedPackages instead. A
plain http:// server needs its host in unsafeHttpWhitelist of Yarn.
3. Lockfiles: in package-lock.json, a Yarn 1 yarn.lock, pnpm-lock.yaml and bun.lock, change the
prefix https://nexus.example.com/repository/<nexus name>/ to
https://repo.example.com/npm/<telesphorepo name>/. The tarballs keep their paths
(<name>/-/<file>.tgz) and their integrity. A Yarn 2+ yarn.lock holds no address. Then run
the frozen install of the tool: npm ci, pnpm install --frozen-lockfile, yarn install
--immutable or bun install --frozen-lockfile.
4. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it in NPM_TOKEN, here and as a CI secret. Tell me
this name first, and never ask me for the token. Never use the name TELESPHOREPO_TOKEN: the
CLI sets it when it publishes. Wire the variable in: .npmrc gets
//repo.example.com/npm/<name>/:_authToken=${NPM_TOKEN}; .yarnrc.yml gets npmAlwaysAuth:
true and npmAuthToken: "${NPM_TOKEN}". In CI, the install step gets NPM_TOKEN from a secret.
5. Watch for these. In a Telesphorepo npm group, the first member that has a package name owns
it, and the group serves every version of that name from that member only; Nexus merges
them. If the project needs versions of one name from two members, tell me. Telesphorepo does
not serve npm audit: point an audit step at --registry=https://registry.npmjs.org/, or tell
me.
6. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (delete node_modules, then run the frozen install with an empty
cache; for npm: npm ci --cache <new empty folder>), and check that every download comes
from repo.example.com. If your shell lacks the token variable, ask me to run the build and
send you the output.
7. Report: each file you changed, each Nexus address left and why, and each place you were
unsure about.

npm, pnpm, Yarn or Bun: full switch-over with publishing

Prompt: npm, pnpm, Yarn or Bun, full switch-over with publishing
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- npm-group -> npm-group
- npm-hosted -> npm-hosted
Private repositories (they need a read token): none
Scope: the full switch-over. First the download addresses, then publishing with the
Telesphorepo CLI. The copies refuse uploads until the switch-over, so we rehearse on a test
repository, npm-hosted-rehearsal, and move to npm-hosted after the switch-over.
Do this:
1. ME, first: ask me for the test repository and the CI pipeline, so I make them while you
work. I make a hosted npm repository named npm-hosted-rehearsal (Repositories page, New
repository), where my account has Publish. A server admin adds the CI pipeline of this
project (Settings › People and CI › CI pipelines) with the repositories
npm-hosted-rehearsal and npm-hosted. Tell me the values for it: for GitHub Actions, the
GitHub repository, the workflow file and the branch; for Jenkins, the Jenkins address and
the full job name.
2. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in .npmrc (the project's and ~/.npmrc), .yarnrc.yml,
.yarnrc (Yarn 1), bunfig.toml, package.json (publishConfig, scripts), the lockfiles and the
registry-url input of actions/setup-node, and in CI files (.github/workflows, Jenkinsfile,
.gitlab-ci.yml and others), Dockerfiles, compose files, scripts and READMEs. Note how the
project publishes to Nexus today. For each Nexus repository not in my list, ask me its name
and wait.
3. Change every download address.
https://nexus.example.com/repository/<nexus name>/ becomes
https://repo.example.com/npm/<telesphorepo name>/, with the trailing slash. Scoped
registries (@acme:registry=) change the same way; Yarn 2 and later name them in
npmRegistryServer and npmScopes. Remove the Nexus _auth, always-auth and email lines. Bun
reads .npmrc, and bunfig.toml can set [install] registry and scopes. On a hosted
repository, Yarn 4 needs npmMinimalAgeGate: 0, or it installs a version only once it is a
week old; on a group or a proxy, list our own packages in npmPreapprovedPackages instead. A
plain http:// server needs its host in unsafeHttpWhitelist of Yarn.
4. Lockfiles: in package-lock.json, a Yarn 1 yarn.lock, pnpm-lock.yaml and bun.lock, change the
prefix https://nexus.example.com/repository/<nexus name>/ to
https://repo.example.com/npm/<telesphorepo name>/. The tarballs keep their paths
(<name>/-/<file>.tgz) and their integrity. A Yarn 2+ yarn.lock holds no address. Then run
the frozen install of the tool: npm ci, pnpm install --frozen-lockfile, yarn install
--immutable or bun install --frozen-lockfile.
5. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it in NPM_TOKEN, here and as a CI secret. Tell me
this name first, and never ask me for the token. Never use the name TELESPHOREPO_TOKEN: the
CLI sets it when it publishes. Wire the variable in: .npmrc gets
//repo.example.com/npm/<name>/:_authToken=${NPM_TOKEN}; .yarnrc.yml gets npmAlwaysAuth:
true and npmAuthToken: "${NPM_TOKEN}". In CI, the install step gets NPM_TOKEN from a secret.
6. Watch for these. In a Telesphorepo npm group, the first member that has a package name owns
it, and the group serves every version of that name from that member only; Nexus merges
them. If the project needs versions of one name from two members, tell me. Telesphorepo does
not serve npm audit: point an audit step at --registry=https://registry.npmjs.org/, or tell
me.
7. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (delete node_modules, then run the frozen install with an empty
cache; for npm: npm ci --cache <new empty folder>), and check that every download comes
from repo.example.com. If your shell lacks the token variable, ask me to run the build and
send you the output.
8. If telesphorepo version fails, install the CLI:
curl -fsSL https://repo.example.com/install.sh | sh (Linux and macOS)
irm https://repo.example.com/install.ps1 | iex (Windows PowerShell)
It goes into ~/.local/bin (Windows: %LOCALAPPDATA%\Programs\telesphorepo). Use the full
path if that folder is not on your PATH yet.
9. Approve this computer: run telesphorepo login https://repo.example.com. It prints a link
and a code, then waits. If your shell shows output only when a command ends, run it in the
background and read its output. ME: give me the link and the code. I open the link, sign
in, check the code, click Approve device and confirm with my second step. Wait until the
CLI prints "This computer is device". This computer can then publish wherever my account
has Publish.
10. Remove the Nexus publishing: publishConfig.registry, the Nexus publish auth lines, and the
npm publish steps of CI with their secrets. telesphorepo publish picks the tool by the
lockfile: pnpm publish (pnpm-lock.yaml), yarn npm publish (yarn.lock), bun publish
(bun.lock), else npm publish. List the CI secrets nothing uses now.
11. Write telesphorepo.toml next to package.json. It holds no secret, and the project commits
it:
server = "https://repo.example.com"
repo = "npm-hosted-rehearsal"
In a workspace, ask me which packages publish, and put a telesphorepo.toml in each of their
folders.
12. CI. GitHub Actions: the publish job gets permissions: id-token: write (keep contents:
read), then actions/checkout@v7, then the steps of the tool: npm: actions/setup-node@v5
(node-version: lts/*) and run: npm ci; pnpm: pnpm/action-setup@v4, actions/setup-node@v5
and run: pnpm install --frozen-lockfile; Yarn: actions/setup-node@v5 and run: corepack
enable && yarn install --immutable; Bun: oven-sh/setup-bun@v2 and run: bun install
--frozen-lockfile. Then
- run: curl -fsSL https://repo.example.com/install.sh | sh
- run: telesphorepo publish
Jenkins: keep the build stage (the same install command), and add a publish stage after
it. Only that stage gets the identity token, which lasts 10 minutes. Inside
withCredentials([string(credentialsId: 'telesphorepo-id-token', variable: 'OIDC_TOKEN')])
it runs, on a Unix agent:
curl -fsSL https://repo.example.com/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
telesphorepo publish
and on a Windows agent, in powershell:
& ([scriptblock]::Create((irm https://repo.example.com/install.ps1)))
telesphorepo publish
ME: Jenkins needs the plugin OpenID Connect Provider, and a credential of the kind "OpenID
Connect id token" with the ID telesphorepo-id-token and the audience
https://repo.example.com. A CI job that downloads from a private repository gets the read
token variable from secrets.
13. Publish from this computer: run telesphorepo status and check the command it names, then
run telesphorepo publish. If the server says my account may not publish, ask me for
Publish on npm-hosted-rehearsal.
14. Verify: in a new temporary folder, run npm init -y, write an .npmrc with the registry
https://repo.example.com/npm/npm-hosted-rehearsal/, and run npm install
<package>@<version>. Then delete the folder.
15. Report: each file you changed, each Nexus address left and why, each place you were unsure
about, the CI secrets nothing uses now, and this note for the switch-over day: set repo in
telesphorepo.toml to npm-hosted, check that the CI pipeline lists npm-hosted, publish
once, then delete npm-hosted-rehearsal.

Python: download addresses only

Prompt: Python, download addresses only
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- pypi-group -> pypi-group
- pypi-hosted -> pypi-hosted
Private repositories (they need a read token): none
Scope: the download addresses only. Publishing stays on Nexus: leave the publish addresses,
credentials and steps as they are.
Do this:
1. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in pip.conf or pip.ini (the project's,
~/.config/pip/pip.conf, /etc/pip.conf), requirements*.txt and constraints files
(--index-url, --extra-index-url, --trusted-host), pyproject.toml ([[tool.uv.index]],
[[tool.poetry.source]], [tool.pdm]), uv.toml, poetry.toml, setup.cfg, tox.ini, noxfile.py,
.pypirc, and PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, UV_INDEX_URL or UV_DEFAULT_INDEX, and in CI
files (.github/workflows, Jenkinsfile, .gitlab-ci.yml and others), Dockerfiles, compose
files, scripts and READMEs. For each Nexus repository not in my list, ask me its name and
wait.
2. Change every download address.
https://nexus.example.com/repository/<nexus name>/simple/ (with or without simple/) becomes
https://repo.example.com/pypi/<telesphorepo name>/simple/. On a plain http:// server, pip
needs trusted-host = <host> and uv needs allow-insecure-host.
3. Lockfiles: uv.lock and poetry.lock hold file addresses whose paths differ between Nexus and
Telesphorepo, so run the lock command instead of editing them: uv lock, or poetry lock
(Poetry 1: poetry lock --no-update). Then check git diff: the same versions and hashes,
other addresses only. In requirements files with --hash, change only the index lines.
4. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in PIP_INDEX_URL for pip,
UV_INDEX_<NAME>_USERNAME and UV_INDEX_<NAME>_PASSWORD for uv, or
POETRY_HTTP_BASIC_<SOURCE>_USERNAME and POETRY_HTTP_BASIC_<SOURCE>_PASSWORD for Poetry,
here and as CI secrets. Tell me these names first, and never ask me for the token. Never use
the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes. Wire the variables in: pip
reads credentials from the address, so the whole address with my username and the token
goes in PIP_INDEX_URL, and the files keep the address without credentials. For uv, <NAME> is
the index name in upper case, other characters as _; for Poetry, <SOURCE> is the source name
the same way.
5. Watch for these. A hosted repository holds only our own packages: their dependencies need a
group with a PyPI proxy, or PyPI itself. In a Telesphorepo PyPI group, the first member that
has a project name owns it, with every file of that project; Nexus merges them. If the
project needs files of one name from two members, tell me.
6. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (a new virtual environment, then pip install --no-cache-dir -r
requirements.txt, uv sync --no-cache, or poetry install with a new cache folder), and check
that every download comes from repo.example.com. If your shell lacks the token variables,
ask me to run the build and send you the output.
7. Report: each file you changed, each Nexus address left and why, and each place you were
unsure about.

Python: full switch-over with publishing

Prompt: Python, full switch-over with publishing
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- pypi-group -> pypi-group
- pypi-hosted -> pypi-hosted
Private repositories (they need a read token): none
Scope: the full switch-over. First the download addresses, then publishing with the
Telesphorepo CLI. The copies refuse uploads until the switch-over, so we rehearse on a test
repository, pypi-hosted-rehearsal, and move to pypi-hosted after the switch-over.
Do this:
1. ME, first: ask me for the test repository and the CI pipeline, so I make them while you
work. I make a hosted PyPI repository named pypi-hosted-rehearsal (Repositories page, New
repository), where my account has Publish. A server admin adds the CI pipeline of this
project (Settings › People and CI › CI pipelines) with the repositories
pypi-hosted-rehearsal and pypi-hosted. Tell me the values for it: for GitHub Actions, the
GitHub repository, the workflow file and the branch; for Jenkins, the Jenkins address and
the full job name.
2. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in pip.conf or pip.ini (the project's,
~/.config/pip/pip.conf, /etc/pip.conf), requirements*.txt and constraints files
(--index-url, --extra-index-url, --trusted-host), pyproject.toml ([[tool.uv.index]],
[[tool.poetry.source]], [tool.pdm]), uv.toml, poetry.toml, setup.cfg, tox.ini, noxfile.py,
.pypirc, and PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, UV_INDEX_URL or UV_DEFAULT_INDEX, and in CI
files (.github/workflows, Jenkinsfile, .gitlab-ci.yml and others), Dockerfiles, compose
files, scripts and READMEs. Note how the project publishes to Nexus today. For each Nexus
repository not in my list, ask me its name and wait.
3. Change every download address.
https://nexus.example.com/repository/<nexus name>/simple/ (with or without simple/) becomes
https://repo.example.com/pypi/<telesphorepo name>/simple/. On a plain http:// server, pip
needs trusted-host = <host> and uv needs allow-insecure-host.
4. Lockfiles: uv.lock and poetry.lock hold file addresses whose paths differ between Nexus and
Telesphorepo, so run the lock command instead of editing them: uv lock, or poetry lock
(Poetry 1: poetry lock --no-update). Then check git diff: the same versions and hashes,
other addresses only. In requirements files with --hash, change only the index lines.
5. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in PIP_INDEX_URL for pip,
UV_INDEX_<NAME>_USERNAME and UV_INDEX_<NAME>_PASSWORD for uv, or
POETRY_HTTP_BASIC_<SOURCE>_USERNAME and POETRY_HTTP_BASIC_<SOURCE>_PASSWORD for Poetry,
here and as CI secrets. Tell me these names first, and never ask me for the token. Never use
the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes. Wire the variables in: pip
reads credentials from the address, so the whole address with my username and the token
goes in PIP_INDEX_URL, and the files keep the address without credentials. For uv, <NAME> is
the index name in upper case, other characters as _; for Poetry, <SOURCE> is the source name
the same way.
6. Watch for these. A hosted repository holds only our own packages: their dependencies need a
group with a PyPI proxy, or PyPI itself. In a Telesphorepo PyPI group, the first member that
has a project name owns it, with every file of that project; Nexus merges them. If the
project needs files of one name from two members, tell me.
7. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (a new virtual environment, then pip install --no-cache-dir -r
requirements.txt, uv sync --no-cache, or poetry install with a new cache folder), and check
that every download comes from repo.example.com. If your shell lacks the token variables,
ask me to run the build and send you the output.
8. If telesphorepo version fails, install the CLI:
curl -fsSL https://repo.example.com/install.sh | sh (Linux and macOS)
irm https://repo.example.com/install.ps1 | iex (Windows PowerShell)
It goes into ~/.local/bin (Windows: %LOCALAPPDATA%\Programs\telesphorepo). Use the full
path if that folder is not on your PATH yet.
9. Approve this computer: run telesphorepo login https://repo.example.com. It prints a link
and a code, then waits. If your shell shows output only when a command ends, run it in the
background and read its output. ME: give me the link and the code. I open the link, sign
in, check the code, click Approve device and confirm with my second step. Wait until the
CLI prints "This computer is device". This computer can then publish wherever my account
has Publish.
10. Remove the Nexus publishing: the use of .pypirc, twine upload, uv publish and publish-url,
poetry publish -r and the Poetry repository config for Nexus, and their CI secrets.
telesphorepo publish runs poetry build (with [tool.poetry]), uv build (with uv.lock) or
python -m build, then uploads every wheel and sdist. List the CI secrets nothing uses now.
11. Write telesphorepo.toml next to pyproject.toml or setup.py. It holds no secret, and the
project commits it:
server = "https://repo.example.com"
repo = "pypi-hosted-rehearsal"
12. CI. GitHub Actions: the publish job gets permissions: id-token: write (keep contents:
read), then actions/checkout@v7, then the steps of the tool: uv: astral-sh/setup-uv@v7;
Poetry: actions/setup-python@v6 (python-version: 3.x) and run: pipx install poetry; pip:
actions/setup-python@v6 and run: python -m pip install build. Then
- run: curl -fsSL https://repo.example.com/install.sh | sh
- run: telesphorepo publish
Jenkins: keep the build stage (none for uv and Poetry, but the agent needs the tool
installed; for pip, python3 -m pip install --user build), and add a publish stage after
it. Only that stage gets the identity token, which lasts 10 minutes. Inside
withCredentials([string(credentialsId: 'telesphorepo-id-token', variable: 'OIDC_TOKEN')])
it runs, on a Unix agent:
curl -fsSL https://repo.example.com/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
telesphorepo publish
and on a Windows agent, in powershell:
& ([scriptblock]::Create((irm https://repo.example.com/install.ps1)))
telesphorepo publish
ME: Jenkins needs the plugin OpenID Connect Provider, and a credential of the kind "OpenID
Connect id token" with the ID telesphorepo-id-token and the audience
https://repo.example.com. A CI job that downloads from a private repository gets the read
token variables from secrets.
13. Publish from this computer: run telesphorepo status and check the command it names, then
run telesphorepo publish (telesphorepo publish dist/*.whl uploads files that are built
already). If the server says my account may not publish, ask me for Publish on
pypi-hosted-rehearsal.
14. Verify: in a new temporary virtual environment, run pip install --index-url
https://repo.example.com/pypi/pypi-hosted-rehearsal/simple/ --extra-index-url
https://pypi.org/simple/ <package>==<version>. Then delete it.
15. Report: each file you changed, each Nexus address left and why, each place you were unsure
about, the CI secrets nothing uses now, and this note for the switch-over day: set repo in
telesphorepo.toml to pypi-hosted, check that the CI pipeline lists pypi-hosted, publish
once, then delete pypi-hosted-rehearsal.

Rust and Cargo: download addresses only

Prompt: Rust and Cargo, download addresses only
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- cargo-group -> cargo-group
- cargo-hosted -> cargo-hosted
Private repositories (they need a read token): none
Scope: the download addresses only. Publishing stays on Nexus: leave the publish addresses,
credentials and steps as they are.
Do this:
1. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in .cargo/config.toml (the project's and
~/.cargo/config.toml), Cargo.toml (registry = of dependencies, publish =), Cargo.lock and
CARGO_REGISTRIES_* variables, and in CI files (.github/workflows, Jenkinsfile,
.gitlab-ci.yml and others), Dockerfiles, compose files, scripts and READMEs. For each Nexus
repository not in my list, ask me its name and wait.
2. Change every download address. The index becomes
sparse+https://repo.example.com/cargo/<telesphorepo name>/index/. Keep the registry names
that Cargo.toml uses, and change only index in [registries.<name>]. A proxy or a group of
crates.io also takes [source.crates-io] replace-with = "<name>".
3. Lockfiles: in Cargo.lock, change each source = "sparse+<Nexus index>" (or registry+) to the
Telesphorepo index, exactly as in the config. Keep every checksum. Then run cargo fetch
--locked.
4. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it in CARGO_REGISTRIES_<NAME>_TOKEN (the registry name
in upper case, - as _), here and as a CI secret. Tell me this name first, and never ask me
for the token. Never use the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes.
Wire the variable in: the registry gets credential-provider = "cargo:token", and Cargo reads
the token from the variable. This needs Cargo 1.74 or later.
5. Watch for these. In a Telesphorepo Cargo group, the first member that has a crate name owns
it, and the group serves every version of that name from that member only.
6. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (cargo build --locked with a new, empty CARGO_HOME), and check
that every download comes from repo.example.com. If your shell lacks the token variable, ask
me to run the build and send you the output.
7. Report: each file you changed, each Nexus address left and why, and each place you were
unsure about.

Rust and Cargo: full switch-over with publishing

Prompt: Rust and Cargo, full switch-over with publishing
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- cargo-group -> cargo-group
- cargo-hosted -> cargo-hosted
Private repositories (they need a read token): none
Scope: the full switch-over. First the download addresses, then publishing with the
Telesphorepo CLI. The copies refuse uploads until the switch-over, so we rehearse on a test
repository, cargo-hosted-rehearsal, and move to cargo-hosted after the switch-over.
Do this:
1. ME, first: ask me for the test repository and the CI pipeline, so I make them while you
work. I make a hosted Cargo repository named cargo-hosted-rehearsal (Repositories page, New
repository), where my account has Publish. A server admin adds the CI pipeline of this
project (Settings › People and CI › CI pipelines) with the repositories
cargo-hosted-rehearsal and cargo-hosted. Tell me the values for it: for GitHub Actions, the
GitHub repository, the workflow file and the branch; for Jenkins, the Jenkins address and
the full job name.
2. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in .cargo/config.toml (the project's and
~/.cargo/config.toml), Cargo.toml (registry = of dependencies, publish =), Cargo.lock and
CARGO_REGISTRIES_* variables, and in CI files (.github/workflows, Jenkinsfile,
.gitlab-ci.yml and others), Dockerfiles, compose files, scripts and READMEs. Note how the
project publishes to Nexus today. For each Nexus repository not in my list, ask me its name
and wait.
3. Change every download address. The index becomes
sparse+https://repo.example.com/cargo/<telesphorepo name>/index/. Keep the registry names
that Cargo.toml uses, and change only index in [registries.<name>]. A proxy or a group of
crates.io also takes [source.crates-io] replace-with = "<name>".
4. Lockfiles: in Cargo.lock, change each source = "sparse+<Nexus index>" (or registry+) to the
Telesphorepo index, exactly as in the config. Keep every checksum. Then run cargo fetch
--locked.
5. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it in CARGO_REGISTRIES_<NAME>_TOKEN (the registry name
in upper case, - as _), here and as a CI secret. Tell me this name first, and never ask me
for the token. Never use the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes.
Wire the variable in: the registry gets credential-provider = "cargo:token", and Cargo reads
the token from the variable. This needs Cargo 1.74 or later.
6. Watch for these. In a Telesphorepo Cargo group, the first member that has a crate name owns
it, and the group serves every version of that name from that member only.
7. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (cargo build --locked with a new, empty CARGO_HOME), and check
that every download comes from repo.example.com. If your shell lacks the token variable, ask
me to run the build and send you the output.
8. If telesphorepo version fails, install the CLI:
curl -fsSL https://repo.example.com/install.sh | sh (Linux and macOS)
irm https://repo.example.com/install.ps1 | iex (Windows PowerShell)
It goes into ~/.local/bin (Windows: %LOCALAPPDATA%\Programs\telesphorepo). Use the full
path if that folder is not on your PATH yet.
9. Approve this computer: run telesphorepo login https://repo.example.com. It prints a link
and a code, then waits. If your shell shows output only when a command ends, run it in the
background and read its output. ME: give me the link and the code. I open the link, sign
in, check the code, click Approve device and confirm with my second step. Wait until the
CLI prints "This computer is device". This computer can then publish wherever my account
has Publish.
10. Remove the Nexus publishing: the cargo publish --registry <nexus> steps and the Nexus
tokens. Where Cargo.toml has publish = [...] with the Nexus registry, set publish =
["telesphorepo"]: the CLI publishes with --registry telesphorepo, and Cargo refuses a
registry that the list does not name. Do not remove the key, or a plain cargo publish goes
to crates.io. List the CI secrets nothing uses now.
11. Write telesphorepo.toml next to Cargo.toml. It holds no secret, and the project commits it:
server = "https://repo.example.com"
repo = "cargo-hosted-rehearsal"
12. CI. GitHub Actions: the publish job gets permissions: id-token: write (keep contents:
read), then actions/checkout@v7, dtolnay/rust-toolchain@stable with no build step, then
- run: curl -fsSL https://repo.example.com/install.sh | sh
- run: telesphorepo publish
Jenkins: keep the build stage (cargo test), and add a publish stage after it. Only that
stage gets the identity token, which lasts 10 minutes. Inside
withCredentials([string(credentialsId: 'telesphorepo-id-token', variable: 'OIDC_TOKEN')])
it runs, on a Unix agent:
curl -fsSL https://repo.example.com/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
telesphorepo publish
and on a Windows agent, in powershell:
& ([scriptblock]::Create((irm https://repo.example.com/install.ps1)))
telesphorepo publish
ME: Jenkins needs the plugin OpenID Connect Provider, and a credential of the kind "OpenID
Connect id token" with the ID telesphorepo-id-token and the audience
https://repo.example.com. A CI job that downloads from a private repository gets the read
token variable from secrets.
13. Publish from this computer: run telesphorepo status and check the command it names, then
run telesphorepo publish. If the server says my account may not publish, ask me for
Publish on cargo-hosted-rehearsal.
14. Verify: in a new temporary folder, run cargo new verify, write a .cargo/config.toml with
the registry of cargo-hosted-rehearsal, run cargo add <crate>@<version> --registry <name>,
then cargo build. Then delete the folder.
15. Report: each file you changed, each Nexus address left and why, each place you were unsure
about, the CI secrets nothing uses now, and this note for the switch-over day: set repo in
telesphorepo.toml to cargo-hosted, check that the CI pipeline lists cargo-hosted, publish
once, then delete cargo-hosted-rehearsal.

.NET and NuGet: download addresses only

Prompt: .NET and NuGet, download addresses only
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- nuget-group -> nuget-group
- nuget-hosted -> nuget-hosted
Private repositories (they need a read token): none
Scope: the download addresses only. Publishing stays on Nexus: leave the publish addresses,
credentials and steps as they are.
Do this:
1. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in nuget.config or NuGet.Config (the solution folder, its
parents and the user's), Directory.Build.props and .targets (RestoreSources,
RestoreAdditionalProjectSources), *.csproj and *.fsproj, dotnet nuget add source, --source
and the source-url input of actions/setup-dotnet, and in CI files (.github/workflows,
Jenkinsfile, .gitlab-ci.yml and others), Dockerfiles, compose files, scripts and READMEs.
For each Nexus repository not in my list, ask me its name and wait.
2. Change every download address.
https://nexus.example.com/repository/<nexus name>/index.json (or the v2 address without
index.json) becomes https://repo.example.com/nuget/<telesphorepo name>/index.json. Keep the
source keys, so packageSourceMapping and the credentials still match. A source on plain
http:// needs allowInsecureConnections="true".
3. Lockfiles: packages.lock.json holds no address. Keep it.
4. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in NUGET_USERNAME and
NUGET_TOKEN, here and as CI secrets. Tell me these names first, and never ask me for the
token. Never use the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes. Wire the
variables in: nuget.config gets <packageSourceCredentials> under the source key (a key that
starts with a digit is written _x003N_...), with Username %NUGET_USERNAME% and
ClearTextPassword %NUGET_TOKEN%.
5. Watch for these. In a Telesphorepo NuGet group, the first member that has a package id owns
it, and the group serves every version of that id from that member only; Nexus merges them.
If the project needs versions of one id from two members, tell me.
6. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (dotnet restore --no-cache --force, then dotnet build), and check
that every download comes from repo.example.com. If your shell lacks the token variables,
ask me to run the build and send you the output.
7. Report: each file you changed, each Nexus address left and why, and each place you were
unsure about.

.NET and NuGet: full switch-over with publishing

Prompt: .NET and NuGet, full switch-over with publishing
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- nuget-group -> nuget-group
- nuget-hosted -> nuget-hosted
Private repositories (they need a read token): none
Scope: the full switch-over. First the download addresses, then publishing with the
Telesphorepo CLI. The copies refuse uploads until the switch-over, so we rehearse on a test
repository, nuget-hosted-rehearsal, and move to nuget-hosted after the switch-over.
Do this:
1. ME, first: ask me for the test repository and the CI pipeline, so I make them while you
work. I make a hosted NuGet repository named nuget-hosted-rehearsal (Repositories page, New
repository), where my account has Publish. A server admin adds the CI pipeline of this
project (Settings › People and CI › CI pipelines) with the repositories
nuget-hosted-rehearsal and nuget-hosted. Tell me the values for it: for GitHub Actions, the
GitHub repository, the workflow file and the branch; for Jenkins, the Jenkins address and
the full job name.
2. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in nuget.config or NuGet.Config (the solution folder, its
parents and the user's), Directory.Build.props and .targets (RestoreSources,
RestoreAdditionalProjectSources), *.csproj and *.fsproj, dotnet nuget add source, --source
and the source-url input of actions/setup-dotnet, and in CI files (.github/workflows,
Jenkinsfile, .gitlab-ci.yml and others), Dockerfiles, compose files, scripts and READMEs.
Note how the project publishes to Nexus today. For each Nexus repository not in my list, ask
me its name and wait.
3. Change every download address.
https://nexus.example.com/repository/<nexus name>/index.json (or the v2 address without
index.json) becomes https://repo.example.com/nuget/<telesphorepo name>/index.json. Keep the
source keys, so packageSourceMapping and the credentials still match. A source on plain
http:// needs allowInsecureConnections="true".
4. Lockfiles: packages.lock.json holds no address. Keep it.
5. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in NUGET_USERNAME and
NUGET_TOKEN, here and as CI secrets. Tell me these names first, and never ask me for the
token. Never use the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes. Wire the
variables in: nuget.config gets <packageSourceCredentials> under the source key (a key that
starts with a digit is written _x003N_...), with Username %NUGET_USERNAME% and
ClearTextPassword %NUGET_TOKEN%.
6. Watch for these. In a Telesphorepo NuGet group, the first member that has a package id owns
it, and the group serves every version of that id from that member only; Nexus merges them.
If the project needs versions of one id from two members, tell me.
7. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (dotnet restore --no-cache --force, then dotnet build), and check
that every download comes from repo.example.com. If your shell lacks the token variables,
ask me to run the build and send you the output.
8. If telesphorepo version fails, install the CLI:
curl -fsSL https://repo.example.com/install.sh | sh (Linux and macOS)
irm https://repo.example.com/install.ps1 | iex (Windows PowerShell)
It goes into ~/.local/bin (Windows: %LOCALAPPDATA%\Programs\telesphorepo). Use the full
path if that folder is not on your PATH yet.
9. Approve this computer: run telesphorepo login https://repo.example.com. It prints a link
and a code, then waits. If your shell shows output only when a command ends, run it in the
background and read its output. ME: give me the link and the code. I open the link, sign
in, check the code, click Approve device and confirm with my second step. Wait until the
CLI prints "This computer is device". This computer can then publish wherever my account
has Publish.
10. Remove the Nexus publishing: the dotnet nuget push or nuget push steps to Nexus, <apikeys>,
and the API key secrets. telesphorepo publish runs dotnet pack -c Release and pushes each
package. List the CI secrets nothing uses now.
11. Write telesphorepo.toml next to the solution or project file. It holds no secret, and the
project commits it:
server = "https://repo.example.com"
repo = "nuget-hosted-rehearsal"
12. CI. GitHub Actions: the publish job gets permissions: id-token: write (keep contents:
read), then actions/checkout@v7, actions/setup-dotnet@v5 (dotnet-version: the project's
SDK version, such as 10.0.x) with no build step, then
- run: curl -fsSL https://repo.example.com/install.sh | sh
- run: telesphorepo publish
Jenkins: keep the build stage (dotnet build -c Release), and add a publish stage after it.
Only that stage gets the identity token, which lasts 10 minutes. Inside
withCredentials([string(credentialsId: 'telesphorepo-id-token', variable: 'OIDC_TOKEN')])
it runs, on a Unix agent:
curl -fsSL https://repo.example.com/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
telesphorepo publish
and on a Windows agent, in powershell:
& ([scriptblock]::Create((irm https://repo.example.com/install.ps1)))
telesphorepo publish
ME: Jenkins needs the plugin OpenID Connect Provider, and a credential of the kind "OpenID
Connect id token" with the ID telesphorepo-id-token and the audience
https://repo.example.com. A CI job that downloads from a private repository gets the read
token variables from secrets.
13. Publish from this computer: run telesphorepo status and check the command it names, then
run telesphorepo publish (telesphorepo publish <file>.nupkg pushes packages that are built
already). If the server says my account may not publish, ask me for Publish on
nuget-hosted-rehearsal.
14. Verify: in a new temporary folder, run dotnet new console, write a nuget.config with the
source https://repo.example.com/nuget/nuget-hosted-rehearsal/index.json, and run dotnet add
package <id> --version <version>. Then delete the folder.
15. Report: each file you changed, each Nexus address left and why, each place you were unsure
about, the CI secrets nothing uses now, and this note for the switch-over day: set repo in
telesphorepo.toml to nuget-hosted, check that the CI pipeline lists nuget-hosted, publish
once, then delete nuget-hosted-rehearsal.

Docker and Helm: download addresses only

Prompt: Docker and Helm, download addresses only
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- docker-hosted -> docker-hosted
- docker-hub -> docker-hub
Nexus Docker hosts and ports (host or port -> Nexus name):
- nexus.example.com:8082 -> docker-hosted
- nexus.example.com:8083 -> docker-hub
Private repositories (they need a read token): none
Scope: the download addresses only. Publishing stays on Nexus: leave the publish addresses,
credentials and steps as they are.
Do this:
1. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host, for /repository/ and for the Nexus Docker hosts and ports. Look in Dockerfile* (FROM,
COPY --from), compose files (image:), Kubernetes manifests and Kustomize (image:, images:,
imagePullSecrets), Helm Chart.yaml (dependencies), Chart.lock, values*.yaml
(image.registry, image.repository), helmfile, skaffold, Tiltfile, devcontainer files, and
docker login, docker pull, helm registry login and helm repo add, and in CI files
(.github/workflows, Jenkinsfile, .gitlab-ci.yml and others), scripts and READMEs. For each
Nexus repository not in my list, ask me its name and wait.
2. Change every download address. Telesphorepo serves the registry at the root of its host,
and the repository name is the first part of the image name.
nexus.example.com:8082/team/app:1.0 becomes repo.example.com/docker-hosted/team/app:1.0.
Through a proxy of Docker Hub, an official image is repo.example.com/docker-hub/nginx:1.27
(or library/nginx). The manifests are the same, so each @sha256: digest stays valid. A
plain http:// server needs its host in insecure-registries of /etc/docker/daemon.json. Helm
charts are OCI artifacts in Docker repositories: a chart dependency on a Nexus Helm
repository becomes oci://repo.example.com/<name>, and its helm repo add line goes. The
Nexus copy does not include Nexus Helm repositories, so ask me which Docker repository
holds the charts.
3. Lockfiles: after a change to the Chart.yaml dependencies, run helm dependency update to
renew Chart.lock.
4. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in TELESPHOREPO_READ_USER and
TELESPHOREPO_READ_TOKEN, here and as CI secrets. Tell me these names first, and never ask
me for the token. Never use the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes.
Wire the variables in. In CI and on servers, log in from the secrets:
printf '%s' "$TELESPHOREPO_READ_TOKEN" | docker login repo.example.com -u "$TELESPHOREPO_READ_USER" --password-stdin
For Kubernetes, I make the pull secret (kubectl create secret docker-registry ...); the
manifests name only the secret. On my computer, use the credential helper of the CLI
instead. If telesphorepo version fails, install the CLI (curl -fsSL
https://repo.example.com/install.sh | sh, or on Windows irm
https://repo.example.com/install.ps1 | iex). Run telesphorepo login
https://repo.example.com; it prints a link and a code, then waits. ME: give me the link and
the code; I open the link, sign in, check the code and click Approve device with my second
step. Then add "credHelpers": {"repo.example.com": "telesphorepo"} to
~/.docker/config.json, keeping its other keys. Docker, Podman, Helm and ORAS then pull what
my account can read, with no docker login.
5. Watch for these. If the server is behind Cloudflare, each image layer must be under 100 MB
for a push; tell me about larger layers.
6. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (remove the local images with docker image rm, pull each image
again with docker compose pull or docker pull, and run docker build --pull --no-cache), and
check that every download comes from repo.example.com. If your shell lacks the token
variables, ask me to run the build and send you the output.
7. Report: each file you changed, each Nexus address left and why, and each place you were
unsure about.

Docker and Helm: full switch-over with publishing

Prompt: Docker and Helm, full switch-over with publishing
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- docker-hosted -> docker-hosted
- docker-hub -> docker-hub
Nexus Docker hosts and ports (host or port -> Nexus name):
- nexus.example.com:8082 -> docker-hosted
- nexus.example.com:8083 -> docker-hub
Private repositories (they need a read token): none
Scope: the full switch-over. First the download addresses, then publishing with the
Telesphorepo CLI. The copies refuse uploads until the switch-over, so we rehearse on a test
repository, docker-hosted-rehearsal, and move to docker-hosted after the switch-over.
Do this:
1. ME, first: ask me for the test repository and the CI pipeline, so I make them while you
work. I make a hosted Docker repository named docker-hosted-rehearsal (Repositories page,
New repository), where my account has Publish. A server admin adds the CI pipeline of this
project (Settings › People and CI › CI pipelines) with the repositories
docker-hosted-rehearsal and docker-hosted. Tell me the values for it: for GitHub Actions,
the GitHub repository, the workflow file and the branch; for Jenkins, the Jenkins address
and the full job name.
2. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host, for /repository/ and for the Nexus Docker hosts and ports. Look in Dockerfile* (FROM,
COPY --from), compose files (image:), Kubernetes manifests and Kustomize (image:, images:,
imagePullSecrets), Helm Chart.yaml (dependencies), Chart.lock, values*.yaml
(image.registry, image.repository), helmfile, skaffold, Tiltfile, devcontainer files, and
docker login, docker pull, helm registry login and helm repo add, and in CI files
(.github/workflows, Jenkinsfile, .gitlab-ci.yml and others), scripts and READMEs. Note how
the project publishes to Nexus today. For each Nexus repository not in my list, ask me its
name and wait.
3. Change every download address. Telesphorepo serves the registry at the root of its host,
and the repository name is the first part of the image name.
nexus.example.com:8082/team/app:1.0 becomes repo.example.com/docker-hosted/team/app:1.0.
Through a proxy of Docker Hub, an official image is repo.example.com/docker-hub/nginx:1.27
(or library/nginx). The manifests are the same, so each @sha256: digest stays valid. A
plain http:// server needs its host in insecure-registries of /etc/docker/daemon.json. Helm
charts are OCI artifacts in Docker repositories: a chart dependency on a Nexus Helm
repository becomes oci://repo.example.com/<name>, and its helm repo add line goes. The
Nexus copy does not include Nexus Helm repositories, so ask me which Docker repository
holds the charts.
4. Lockfiles: after a change to the Chart.yaml dependencies, run helm dependency update to
renew Chart.lock.
5. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in TELESPHOREPO_READ_USER and
TELESPHOREPO_READ_TOKEN, here and as CI secrets. Tell me these names first, and never ask
me for the token. Never use the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes.
Wire the variables in. In CI and on servers, log in from the secrets:
printf '%s' "$TELESPHOREPO_READ_TOKEN" | docker login repo.example.com -u "$TELESPHOREPO_READ_USER" --password-stdin
For Kubernetes, I make the pull secret (kubectl create secret docker-registry ...); the
manifests name only the secret. On my computer, the credential helper of steps 8 to 10
does the pulls.
6. Watch for these. If the server is behind Cloudflare, each image layer must be under 100 MB
for a push; tell me about larger layers.
7. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Build with an empty cache (remove the local images with docker image rm, pull each image
again with docker compose pull or docker pull, and run docker build --pull --no-cache), and
check that every download comes from repo.example.com. If your shell lacks the token
variables, ask me to run the build and send you the output.
8. If telesphorepo version fails, install the CLI:
curl -fsSL https://repo.example.com/install.sh | sh (Linux and macOS)
irm https://repo.example.com/install.ps1 | iex (Windows PowerShell)
It goes into ~/.local/bin (Windows: %LOCALAPPDATA%\Programs\telesphorepo). Use the full
path if that folder is not on your PATH yet.
9. Approve this computer: run telesphorepo login https://repo.example.com. It prints a link
and a code, then waits. If your shell shows output only when a command ends, run it in the
background and read its output. ME: give me the link and the code. I open the link, sign
in, check the code, click Approve device and confirm with my second step. Wait until the
CLI prints "This computer is device". This computer can then publish wherever my account
has Publish.
10. Remove the Nexus publishing: docker login to Nexus, the Nexus push credentials, and helm
push or curl uploads to Nexus. Images publish with docker push
repo.example.com/<repo>/<image>:<tag>, and the credential helper gives Docker the publish
token: after I say yes, add "credHelpers": {"repo.example.com": "telesphorepo"} to
~/.docker/config.json, keeping its other keys (telesphorepo login does not add it;
telesphorepo status shows it). Images need no telesphorepo.toml. A chart folder gets one,
and telesphorepo publish runs helm package, then helm push. List the CI secrets nothing
uses now.
11. For a Helm chart only: write telesphorepo.toml next to Chart.yaml. It holds no secret, and
the project commits it:
server = "https://repo.example.com"
repo = "docker-hosted-rehearsal"
12. CI for an image. GitHub Actions: the job gets permissions: id-token: write (keep contents:
read), and these steps (change app to the image name):
- uses: actions/checkout@v7
- run: docker build -t "repo.example.com/docker-hosted-rehearsal/app:$GITHUB_SHA" .
- run: curl -fsSL https://repo.example.com/install.sh | sh
- name: Publish to docker-hosted-rehearsal
run: |
export DOCKER_CONFIG="$(mktemp -d)"
printf '%s\n' '{"credHelpers":{"repo.example.com":"telesphorepo"}}' > "$DOCKER_CONFIG/config.json"
docker push "repo.example.com/docker-hosted-rehearsal/app:$GITHUB_SHA"
env:
TELESPHOREPO_SERVER: "https://repo.example.com"
Jenkins: the build stage runs docker build with the tag ${GIT_COMMIT:-$BUILD_NUMBER}. A
publish stage after it runs, inside
withEnv(['TELESPHOREPO_SERVER=https://repo.example.com']) and
withCredentials([string(credentialsId: 'telesphorepo-id-token', variable: 'OIDC_TOKEN')]):
curl -fsSL https://repo.example.com/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
and then the three lines of the GitHub publish step, with ${GIT_COMMIT:-$BUILD_NUMBER} as
the tag. CI for a Helm chart installs Helm (for example azure/setup-helm@v4), then the CLI,
and runs telesphorepo publish. With its identity token, a job reads only what anyone can
read, so to build from a private base image, log in with the read token before the build.
ME: Jenkins needs the plugin OpenID Connect Provider, and a credential of the kind "OpenID
Connect id token" with the ID telesphorepo-id-token and the audience
https://repo.example.com.
13. Publish from this computer: run telesphorepo status and check the credential helper entry,
then docker push repo.example.com/docker-hosted-rehearsal/<image>:<tag>. For a chart, run
telesphorepo publish in its folder. If the server says my account may not publish, ask me
for Publish on docker-hosted-rehearsal.
14. Verify: remove the local image, then docker pull
repo.example.com/docker-hosted-rehearsal/<image>:<tag>. For a chart, run helm pull
oci://repo.example.com/docker-hosted-rehearsal/<chart> --version <version> in a new
temporary folder, then delete the folder.
15. Report: each file you changed, each Nexus address left and why, each place you were unsure
about, the CI secrets nothing uses now, and this note for the switch-over day: point the
image names and the repo of telesphorepo.toml at docker-hosted, check that the CI pipeline
lists docker-hosted, publish once, then delete docker-hosted-rehearsal.

Debian or raw files: download addresses only

Prompt: Debian or raw files, download addresses only
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- apt-hosted -> apt-hosted
- raw-files -> raw-files
Private repositories (they need a read token): none
Scope: the download addresses only. Publishing stays on Nexus: leave the publish addresses,
credentials and steps as they are.
Do this:
1. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in apt sources (/etc/apt/sources.list.d/*.list and
*.sources, and the Dockerfiles, Ansible, cloud-init files or scripts that write them),
keyrings and signed-by, curl or wget of Nexus files, and in CI files (.github/workflows,
Jenkinsfile, .gitlab-ci.yml and others), Dockerfiles, compose files, scripts and READMEs.
For each Nexus repository not in my list, ask me its name and wait.
2. Change every download address. apt: deb https://nexus.example.com/repository/<nexus name>/
<dist> main becomes deb [signed-by=/etc/apt/keyrings/<name>.asc]
https://repo.example.com/debian/<name> <dist> main. The copy keeps the distribution of the
Nexus repository and puts every package in the component main. Ask me which signing key
the repository got: with the Nexus key, the machines keep their trust; with another key,
they install it from https://repo.example.com/debian/<name>/key.asc into
/etc/apt/keyrings/<name>.asc. Raw: https://nexus.example.com/repository/<nexus name>/<path>
becomes https://repo.example.com/raw/<name>/<path>; the files keep their paths.
3. Checksums: keep every sha256sum or checksum check of a downloaded file as it is.
4. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in TELESPHOREPO_READ_USER and
TELESPHOREPO_READ_TOKEN, here and as CI secrets. Tell me these names first, and never ask
me for the token. Never use the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes.
Wire the variables in. curl gets the credentials on stdin, never as an argument:
printf 'user = "%s:%s"\n' "$TELESPHOREPO_READ_USER" "$TELESPHOREPO_READ_TOKEN" | curl -fsSL -K - -o <file> <address>
apt reads credentials only from /etc/apt/auth.conf.d/. Give me these lines to run; they
read the token at a hidden prompt:
printf 'Read token: '; read -rs READ_TOKEN; echo
sudo install -m 600 /dev/null /etc/apt/auth.conf.d/<name>.conf
printf 'machine %s login <user> password %s\n' https://repo.example.com/debian/<name> "$READ_TOKEN" | sudo tee -a /etc/apt/auth.conf.d/<name>.conf > /dev/null
5. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Then test the downloads (for apt, apt-get update in a throwaway debian container with the
new source and key; for raw files, each download with curl and its checksum), and check
that every download comes from repo.example.com. If your shell lacks the token variables,
ask me to run it and send you the output.
6. Report: each file you changed, each Nexus address left and why, and each place you were
unsure about.

Debian or raw files: full switch-over with publishing

Prompt: Debian or raw files, full switch-over with publishing
Move this project from our Nexus server to Telesphorepo with me. Do every step you can. For
each step marked ME, tell me exactly what to do, then wait until I say it is done. Never put a
password or a token in a file, a command line or this chat: read each secret from an
environment variable or a CI secret. Ask me before you change a file outside the project. Keep
every checksum and hash: Telesphorepo holds the same bytes as Nexus.
Telesphorepo: https://repo.example.com
Nexus: https://nexus.example.com
Repositories (Nexus name -> Telesphorepo name):
- apt-hosted -> apt-hosted
- raw-files -> raw-files
Private repositories (they need a read token): none
Scope: the full switch-over. First the download addresses, then publishing with the
Telesphorepo CLI. The copies refuse uploads until the switch-over, so we rehearse on a test
repository, apt-hosted-rehearsal, and move to apt-hosted after the switch-over.
Do this:
1. ME, first: ask me for the test repository and the CI pipeline, so I make them while you
work. I make a hosted Debian or Raw repository named apt-hosted-rehearsal (Repositories
page, New repository), where my account has Publish. A server admin adds the CI pipeline of
this project (Settings › People and CI › CI pipelines) with the repositories
apt-hosted-rehearsal and apt-hosted. Tell me the values for it: for GitHub Actions, the
GitHub repository, the workflow file and the branch; for Jenkins, the Jenkins address and
the full job name.
2. Find every place that names Nexus. Search every file, hidden folders too, for the Nexus
host and for /repository/. Look in apt sources (/etc/apt/sources.list.d/*.list and
*.sources, and the Dockerfiles, Ansible, cloud-init files or scripts that write them),
keyrings and signed-by, curl or wget of Nexus files, and in CI files (.github/workflows,
Jenkinsfile, .gitlab-ci.yml and others), Dockerfiles, compose files, scripts and READMEs.
Note how the project publishes to Nexus today. For each Nexus repository not in my list,
ask me its name and wait.
3. Change every download address. apt: deb https://nexus.example.com/repository/<nexus name>/
<dist> main becomes deb [signed-by=/etc/apt/keyrings/<name>.asc]
https://repo.example.com/debian/<name> <dist> main. The copy keeps the distribution of the
Nexus repository and puts every package in the component main. Ask me which signing key
the repository got: with the Nexus key, the machines keep their trust; with another key,
they install it from https://repo.example.com/debian/<name>/key.asc into
/etc/apt/keyrings/<name>.asc. Raw: https://nexus.example.com/repository/<nexus name>/<path>
becomes https://repo.example.com/raw/<name>/<path>; the files keep their paths.
4. Checksums: keep every sha256sum or checksum check of a downloaded file as it is.
5. Private repositories, only if my list names one. ME: I make a read token (Settings › Tokens,
New read token, Create token) and set it, with my username, in TELESPHOREPO_READ_USER and
TELESPHOREPO_READ_TOKEN, here and as CI secrets. Tell me these names first, and never ask
me for the token. Never use the name TELESPHOREPO_TOKEN: the CLI sets it when it publishes.
Wire the variables in. curl gets the credentials on stdin, never as an argument:
printf 'user = "%s:%s"\n' "$TELESPHOREPO_READ_USER" "$TELESPHOREPO_READ_TOKEN" | curl -fsSL -K - -o <file> <address>
apt reads credentials only from /etc/apt/auth.conf.d/. Give me these lines to run; they
read the token at a hidden prompt:
printf 'Read token: '; read -rs READ_TOKEN; echo
sudo install -m 600 /dev/null /etc/apt/auth.conf.d/<name>.conf
printf 'machine %s login <user> password %s\n' https://repo.example.com/debian/<name> "$READ_TOKEN" | sudo tee -a /etc/apt/auth.conf.d/<name>.conf > /dev/null
6. Check: search again for the Nexus host and /repository/, and explain each hit that is left.
Then test the downloads (for apt, apt-get update in a throwaway debian container with the
new source and key; for raw files, each download with curl and its checksum), and check
that every download comes from repo.example.com. If your shell lacks the token variables,
ask me to run it and send you the output.
7. If telesphorepo version fails, install the CLI:
curl -fsSL https://repo.example.com/install.sh | sh (Linux and macOS)
irm https://repo.example.com/install.ps1 | iex (Windows PowerShell)
It goes into ~/.local/bin (Windows: %LOCALAPPDATA%\Programs\telesphorepo). Use the full
path if that folder is not on your PATH yet.
8. Approve this computer: run telesphorepo login https://repo.example.com. It prints a link
and a code, then waits. If your shell shows output only when a command ends, run it in the
background and read its output. ME: give me the link and the code. I open the link, sign
in, check the code, click Approve device and confirm with my second step. Wait until the
CLI prints "This computer is device". This computer can then publish wherever my account
has Publish.
9. Remove the Nexus publishing: the curl -u uploads to Nexus and their passwords. telesphorepo
publish <file> uploads files: for raw into the folder path of telesphorepo.toml, for Debian
each .deb into dist and component. List the CI secrets nothing uses now.
10. Write telesphorepo.toml next to the build script. It holds no secret, and the project
commits it:
server = "https://repo.example.com"
repo = "apt-hosted-rehearsal"
For a raw repository, add path = "<folder in the repository>". For a Debian repository,
add dist = "<distribution>" and component = "main".
11. CI. GitHub Actions: the publish job gets permissions: id-token: write (keep contents:
read), then actions/checkout@v7, the build step that makes the files, then
- run: curl -fsSL https://repo.example.com/install.sh | sh
- run: telesphorepo publish <files>
Jenkins: keep the build stage (the build that makes the files), and add a publish stage
after it. Only that stage gets the identity token, which lasts 10 minutes. Inside
withCredentials([string(credentialsId: 'telesphorepo-id-token', variable: 'OIDC_TOKEN')])
it runs, on a Unix agent:
curl -fsSL https://repo.example.com/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
telesphorepo publish <files>
and on a Windows agent, in powershell:
& ([scriptblock]::Create((irm https://repo.example.com/install.ps1)))
telesphorepo publish <files>
ME: Jenkins needs the plugin OpenID Connect Provider, and a credential of the kind "OpenID
Connect id token" with the ID telesphorepo-id-token and the audience
https://repo.example.com. A CI job that downloads from a private repository gets the read
token variables from secrets.
12. Publish from this computer: run telesphorepo status and check the command it names, then
run telesphorepo publish with the files, for example telesphorepo publish
build/hello_1.0_amd64.deb. If the server says my account may not publish, ask me for
Publish on apt-hosted-rehearsal.
13. Verify: for raw, download the file with curl and compare its SHA-256. For Debian, in a
throwaway debian container, add the source and key of apt-hosted-rehearsal, then run
apt-get update and apt-get install <package>.
14. Report: each file you changed, each Nexus address left and why, each place you were unsure
about, the CI secrets nothing uses now, and this note for the switch-over day: set repo in
telesphorepo.toml to apt-hosted, check that the CI pipeline lists apt-hosted, publish
once, then delete apt-hosted-rehearsal.

The agent asks for each step when it needs it. It waits until you say it is done.

  • Approve the computer. Open the link that the agent gives you, and sign in. Check the code, click Approve device, and confirm with your second step.
  • Make a read token, only for a private repository. Open Settings › Tokens, click New read token, type a name, and click Create token. Put it in the variables that the agent names. Never paste it to the agent.
  • Make the test repository, for the full switch-over. Open the Repositories page, and click New repository. Make a hosted repository where your account has Publish.
  • Add the CI pipeline, for the full switch-over. A server admin adds it on Settings › People and CI › CI pipelines, with the values that the agent gives you. For Jenkins, see also Set up Jenkins.

When your admin has switched over, follow the note in the agent’s report:

  1. Set repo in telesphorepo.toml to the real repository.

  2. Check that the CI pipeline lists the real repository.

  3. Publish once.

  4. Delete the test repository.

With Claude Code, you can use the skill telesphorepo-migrate instead of a prompt. It asks you for the addresses and names, and finds the ecosystems in the project by itself.

  1. Copy the skill into ~/.claude/skills/, or into .claude/skills/ of one project. On Windows, the user folder is %USERPROFILE%\.claude\skills\.

    Terminal window
    git clone --depth 1 https://github.com/Telesphorepo/Telesphorepo.git /tmp/telesphorepo
    mkdir -p ~/.claude/skills
    cp -r /tmp/telesphorepo/skills/telesphorepo-migrate ~/.claude/skills/
  2. Open Claude Code in the project folder, and ask:

    Move this project from Nexus to Telesphorepo.