@heyditto/cli 2.5.1 → 2.6.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 +52 -20
- package/dist/commands.d.ts +34 -3
- package/dist/commands.js +130 -59
- package/dist/commands.js.map +1 -1
- package/dist/secret-stores/aws.d.ts +8 -0
- package/dist/secret-stores/aws.js +59 -0
- package/dist/secret-stores/aws.js.map +1 -0
- package/dist/secret-stores/azure.d.ts +7 -0
- package/dist/secret-stores/azure.js +63 -0
- package/dist/secret-stores/azure.js.map +1 -0
- package/dist/secret-stores/cloudflare.d.ts +7 -0
- package/dist/secret-stores/cloudflare.js +46 -0
- package/dist/secret-stores/cloudflare.js.map +1 -0
- package/dist/secret-stores/doppler.d.ts +7 -0
- package/dist/secret-stores/doppler.js +52 -0
- package/dist/secret-stores/doppler.js.map +1 -0
- package/dist/secret-stores/exec.d.ts +55 -0
- package/dist/secret-stores/exec.js +132 -0
- package/dist/secret-stores/exec.js.map +1 -0
- package/dist/secret-stores/fly.d.ts +7 -0
- package/dist/secret-stores/fly.js +54 -0
- package/dist/secret-stores/fly.js.map +1 -0
- package/dist/secret-stores/gcloud.d.ts +7 -0
- package/dist/secret-stores/gcloud.js +62 -0
- package/dist/secret-stores/gcloud.js.map +1 -0
- package/dist/secret-stores/github.d.ts +9 -0
- package/dist/secret-stores/github.js +74 -0
- package/dist/secret-stores/github.js.map +1 -0
- package/dist/secret-stores/gitlab.d.ts +7 -0
- package/dist/secret-stores/gitlab.js +82 -0
- package/dist/secret-stores/gitlab.js.map +1 -0
- package/dist/secret-stores/index.d.ts +42 -0
- package/dist/secret-stores/index.js +106 -0
- package/dist/secret-stores/index.js.map +1 -0
- package/dist/secret-stores/kubernetes.d.ts +8 -0
- package/dist/secret-stores/kubernetes.js +76 -0
- package/dist/secret-stores/kubernetes.js.map +1 -0
- package/dist/secret-stores/naming.d.ts +20 -0
- package/dist/secret-stores/naming.js +62 -0
- package/dist/secret-stores/naming.js.map +1 -0
- package/dist/secret-stores/onepassword.d.ts +7 -0
- package/dist/secret-stores/onepassword.js +50 -0
- package/dist/secret-stores/onepassword.js.map +1 -0
- package/dist/secret-stores/types.d.ts +108 -0
- package/dist/secret-stores/types.js +25 -0
- package/dist/secret-stores/types.js.map +1 -0
- package/dist/secret-stores/vault.d.ts +7 -0
- package/dist/secret-stores/vault.js +47 -0
- package/dist/secret-stores/vault.js.map +1 -0
- package/dist/secret-stores/vercel.d.ts +9 -0
- package/dist/secret-stores/vercel.js +49 -0
- package/dist/secret-stores/vercel.js.map +1 -0
- package/dist/teleport/harness.d.ts +5 -0
- package/dist/teleport/harness.js +21 -5
- package/dist/teleport/harness.js.map +1 -1
- package/dist/teleport/types.d.ts +7 -0
- package/dist/teleport/types.js +12 -1
- package/dist/teleport/types.js.map +1 -1
- package/dist/teleport/worktree.js +2 -0
- package/dist/teleport/worktree.js.map +1 -1
- package/package.json +1 -1
- package/dist/gh-secret.d.ts +0 -31
- package/dist/gh-secret.js +0 -94
- package/dist/gh-secret.js.map +0 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Kubernetes. The manifest is built here and piped in, so the plaintext never
|
|
4
|
+
* reaches argv (`--from-literal` would) and never touches disk. A merge patch
|
|
5
|
+
* comes first because it leaves the secret's other keys alone; `apply` is the
|
|
6
|
+
* fallback that creates the secret when it does not exist yet.
|
|
7
|
+
*/
|
|
8
|
+
export declare const kubernetes: SecretStore;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { PATH_PLACEHOLDER, preflight } from "./exec.js";
|
|
2
|
+
import { resourceName, slug } from "./naming.js";
|
|
3
|
+
/** The merge patch the first attempt sends: adds this key, leaves the rest. */
|
|
4
|
+
function mergePatch(key, value) {
|
|
5
|
+
return `${JSON.stringify({ stringData: { [key]: value } })}\n`;
|
|
6
|
+
}
|
|
7
|
+
const INSTALL_HINT = "install kubectl from https://kubernetes.io/docs/tasks/tools (brew install kubectl), then point it at a cluster with `kubectl config use-context`";
|
|
8
|
+
function target(options) {
|
|
9
|
+
const namespace = options.namespace ? slug("--namespace", options.namespace, /^[a-z0-9-]+$/) : "default";
|
|
10
|
+
const key = options.k8sKey ? slug("--k8s-key", options.k8sKey, /^[A-Za-z0-9_.-]+$/) : "key";
|
|
11
|
+
return { describe: `Kubernetes secret in namespace ${namespace} (key ${key})`, fields: { namespace, key } };
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Kubernetes. The manifest is built here and piped in, so the plaintext never
|
|
15
|
+
* reaches argv (`--from-literal` would) and never touches disk. A merge patch
|
|
16
|
+
* comes first because it leaves the secret's other keys alone; `apply` is the
|
|
17
|
+
* fallback that creates the secret when it does not exist yet.
|
|
18
|
+
*/
|
|
19
|
+
export const kubernetes = {
|
|
20
|
+
id: "kubernetes",
|
|
21
|
+
label: "Kubernetes",
|
|
22
|
+
bin: "kubectl",
|
|
23
|
+
shorthand: "--k8s-secret",
|
|
24
|
+
nameLabel: "NAME",
|
|
25
|
+
installHint: INSTALL_HINT,
|
|
26
|
+
versionArgs: ["version", "--client=true"],
|
|
27
|
+
options: ["namespace", "k8sKey"],
|
|
28
|
+
validateName: (name) => {
|
|
29
|
+
const trimmed = name.trim();
|
|
30
|
+
if (trimmed !== trimmed.toLowerCase()) {
|
|
31
|
+
throw new Error(`"${name}" is not a valid Kubernetes secret name (lowercase letters, digits, dashes and dots only)`);
|
|
32
|
+
}
|
|
33
|
+
return resourceName("Kubernetes secret", trimmed, ".");
|
|
34
|
+
},
|
|
35
|
+
preflight: () => preflight({
|
|
36
|
+
bin: "kubectl",
|
|
37
|
+
label: "Kubernetes",
|
|
38
|
+
installHint: INSTALL_HINT,
|
|
39
|
+
versionArgs: kubernetes.versionArgs,
|
|
40
|
+
authArgs: ["config", "current-context"],
|
|
41
|
+
authHint: "Select a cluster with `kubectl config use-context <name>` first.",
|
|
42
|
+
}),
|
|
43
|
+
resolveTarget: target,
|
|
44
|
+
deliveries: (name, t) => {
|
|
45
|
+
const { namespace, key } = t.fields;
|
|
46
|
+
return [
|
|
47
|
+
{
|
|
48
|
+
note: "kubectl patch secret",
|
|
49
|
+
kind: "path",
|
|
50
|
+
args: ["patch", "secret", name, "--namespace", namespace, "--type", "merge", "--patch-file", PATH_PLACEHOLDER],
|
|
51
|
+
payload: (value) => mergePatch(key, value),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
note: "kubectl apply",
|
|
55
|
+
kind: "stdin",
|
|
56
|
+
args: ["apply", "--namespace", namespace, "-f", "-"],
|
|
57
|
+
payload: (value) => `${JSON.stringify({
|
|
58
|
+
apiVersion: "v1",
|
|
59
|
+
kind: "Secret",
|
|
60
|
+
type: "Opaque",
|
|
61
|
+
metadata: { name, namespace },
|
|
62
|
+
stringData: { [key]: value },
|
|
63
|
+
})}\n`,
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
},
|
|
67
|
+
usage: (name, t, gateway) => [
|
|
68
|
+
"Mount it into a pod:",
|
|
69
|
+
" env:",
|
|
70
|
+
" - name: OPENAI_API_KEY",
|
|
71
|
+
` valueFrom: { secretKeyRef: { name: ${name}, key: ${t.fields.key} } }`,
|
|
72
|
+
` - name: OPENAI_BASE_URL`,
|
|
73
|
+
` value: ${gateway.openaiBaseUrl}`,
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=kubernetes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kubernetes.js","sourceRoot":"","sources":["../../src/secret-stores/kubernetes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-platform name rules. Each store rejects names its platform would refuse
|
|
3
|
+
* anyway, before a key is minted, with a message that says what is allowed.
|
|
4
|
+
*/
|
|
5
|
+
/** Env-var style: letters, digits, underscores; not leading with a digit. */
|
|
6
|
+
export declare function envStyleName(label: string, name: string): string;
|
|
7
|
+
/** GitHub Actions additionally reserves the GITHUB_ prefix. */
|
|
8
|
+
export declare function validateSecretName(name: string): string;
|
|
9
|
+
export declare function validateRepo(repo: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* RFC 1123-ish resource names used by Google Secret Manager, Azure Key Vault
|
|
12
|
+
* and Kubernetes: letters, digits, dashes (Google also allows underscores).
|
|
13
|
+
*/
|
|
14
|
+
export declare function resourceName(label: string, name: string, extra?: string): string;
|
|
15
|
+
/** Free-form single-line title (1Password items). */
|
|
16
|
+
export declare function titleName(label: string, name: string): string;
|
|
17
|
+
/** A Vault kv path: slash-separated segments, no leading or trailing slash. */
|
|
18
|
+
export declare function secretPath(label: string, name: string): string;
|
|
19
|
+
/** Rejects a scoping flag's value that the platform would not accept. */
|
|
20
|
+
export declare function slug(flag: string, value: string, pattern?: RegExp): string;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-platform name rules. Each store rejects names its platform would refuse
|
|
3
|
+
* anyway, before a key is minted, with a message that says what is allowed.
|
|
4
|
+
*/
|
|
5
|
+
/** Env-var style: letters, digits, underscores; not leading with a digit. */
|
|
6
|
+
export function envStyleName(label, name) {
|
|
7
|
+
const trimmed = name.trim();
|
|
8
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed)) {
|
|
9
|
+
throw new Error(`"${name}" is not a valid ${label} name (letters, digits and underscores; cannot start with a digit)`);
|
|
10
|
+
}
|
|
11
|
+
return trimmed;
|
|
12
|
+
}
|
|
13
|
+
/** GitHub Actions additionally reserves the GITHUB_ prefix. */
|
|
14
|
+
export function validateSecretName(name) {
|
|
15
|
+
const trimmed = envStyleName("GitHub Actions secret", name);
|
|
16
|
+
if (/^GITHUB_/i.test(trimmed)) {
|
|
17
|
+
throw new Error(`"${name}" is reserved: GitHub Actions secret names cannot start with GITHUB_`);
|
|
18
|
+
}
|
|
19
|
+
return trimmed;
|
|
20
|
+
}
|
|
21
|
+
export function validateRepo(repo) {
|
|
22
|
+
const trimmed = repo.trim();
|
|
23
|
+
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(trimmed)) {
|
|
24
|
+
throw new Error(`--repo must be owner/repo, got "${repo}"`);
|
|
25
|
+
}
|
|
26
|
+
return trimmed;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* RFC 1123-ish resource names used by Google Secret Manager, Azure Key Vault
|
|
30
|
+
* and Kubernetes: letters, digits, dashes (Google also allows underscores).
|
|
31
|
+
*/
|
|
32
|
+
export function resourceName(label, name, extra = "") {
|
|
33
|
+
const trimmed = name.trim();
|
|
34
|
+
const pattern = new RegExp(`^[A-Za-z0-9][A-Za-z0-9${extra}-]{0,253}$`);
|
|
35
|
+
if (!pattern.test(trimmed)) {
|
|
36
|
+
throw new Error(`"${name}" is not a valid ${label} name (letters, digits${extra.includes("_") ? ", underscores" : ""} and dashes, starting with a letter or digit)`);
|
|
37
|
+
}
|
|
38
|
+
return trimmed;
|
|
39
|
+
}
|
|
40
|
+
/** Free-form single-line title (1Password items). */
|
|
41
|
+
export function titleName(label, name) {
|
|
42
|
+
const trimmed = name.trim();
|
|
43
|
+
if (!trimmed || /[\n\r]/.test(trimmed))
|
|
44
|
+
throw new Error(`"${name}" is not a valid ${label} (one non-empty line)`);
|
|
45
|
+
return trimmed;
|
|
46
|
+
}
|
|
47
|
+
/** A Vault kv path: slash-separated segments, no leading or trailing slash. */
|
|
48
|
+
export function secretPath(label, name) {
|
|
49
|
+
const trimmed = name.trim().replace(/^\/+|\/+$/g, "");
|
|
50
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9_.\-/]*$/.test(trimmed)) {
|
|
51
|
+
throw new Error(`"${name}" is not a valid ${label} (letters, digits, dashes, dots, underscores and slashes)`);
|
|
52
|
+
}
|
|
53
|
+
return trimmed;
|
|
54
|
+
}
|
|
55
|
+
/** Rejects a scoping flag's value that the platform would not accept. */
|
|
56
|
+
export function slug(flag, value, pattern = /^[A-Za-z0-9_.-]+$/) {
|
|
57
|
+
const trimmed = value.trim();
|
|
58
|
+
if (!pattern.test(trimmed))
|
|
59
|
+
throw new Error(`${flag} must be a valid name, got "${value}"`);
|
|
60
|
+
return trimmed;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/secret-stores/naming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,IAAY;IACtD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,oBAAoB,KAAK,oEAAoE,CAAC,CAAC;IACzH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAC;IAC5D,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,sEAAsE,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,GAAG,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,IAAY,EAAE,KAAK,GAAG,EAAE;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,yBAAyB,KAAK,YAAY,CAAC,CAAC;IACvE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,oBAAoB,KAAK,yBAAyB,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,+CAA+C,CAAC,CAAC;IACvK,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,IAAY;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,oBAAoB,KAAK,uBAAuB,CAAC,CAAC;IAClH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,IAAY;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,gCAAgC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,oBAAoB,KAAK,2DAA2D,CAAC,CAAC;IAChH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,KAAa,EAAE,OAAO,GAAG,mBAAmB;IAC7E,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,+BAA+B,KAAK,GAAG,CAAC,CAAC;IAC5F,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* 1Password. Assignment statements (`credential=…`) put the value in argv and
|
|
4
|
+
* the docs say so explicitly, so this pipes an item JSON template into
|
|
5
|
+
* `op item create -` instead: the plaintext only ever crosses stdin.
|
|
6
|
+
*/
|
|
7
|
+
export declare const onepassword: SecretStore;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { preflight } from "./exec.js";
|
|
2
|
+
import { slug, titleName } from "./naming.js";
|
|
3
|
+
const INSTALL_HINT = "install the 1Password CLI from https://developer.1password.com/docs/cli/get-started (brew install 1password-cli), then sign in with `op signin`";
|
|
4
|
+
function target(options) {
|
|
5
|
+
const vault = options.opVault ? slug("--op-vault", options.opVault, /^[^\n\r]+$/) : "Private";
|
|
6
|
+
return { describe: `1Password vault ${vault}`, fields: { vault } };
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 1Password. Assignment statements (`credential=…`) put the value in argv and
|
|
10
|
+
* the docs say so explicitly, so this pipes an item JSON template into
|
|
11
|
+
* `op item create -` instead: the plaintext only ever crosses stdin.
|
|
12
|
+
*/
|
|
13
|
+
export const onepassword = {
|
|
14
|
+
id: "1password",
|
|
15
|
+
label: "1Password",
|
|
16
|
+
bin: "op",
|
|
17
|
+
shorthand: "--op-item",
|
|
18
|
+
nameLabel: "TITLE",
|
|
19
|
+
installHint: INSTALL_HINT,
|
|
20
|
+
options: ["opVault"],
|
|
21
|
+
validateName: (name) => titleName("1Password item title", name),
|
|
22
|
+
preflight: () => preflight({
|
|
23
|
+
bin: "op",
|
|
24
|
+
label: "1Password",
|
|
25
|
+
installHint: INSTALL_HINT,
|
|
26
|
+
authArgs: ["whoami"],
|
|
27
|
+
authHint: "Run `op signin` first (or enable the desktop app's CLI integration).",
|
|
28
|
+
}),
|
|
29
|
+
resolveTarget: target,
|
|
30
|
+
deliveries: (title, t) => [
|
|
31
|
+
{
|
|
32
|
+
note: "op item create",
|
|
33
|
+
kind: "stdin",
|
|
34
|
+
args: ["item", "create", "--vault", t.fields.vault, "-"],
|
|
35
|
+
payload: (value) => `${JSON.stringify({
|
|
36
|
+
title,
|
|
37
|
+
category: "API_CREDENTIAL",
|
|
38
|
+
fields: [{ id: "credential", label: "credential", type: "CONCEALED", value }],
|
|
39
|
+
})}\n`,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
usage: (title, t, gateway) => [
|
|
43
|
+
"Read it back without ever printing it:",
|
|
44
|
+
` op read "op://${t.fields.vault}/${title}/credential"`,
|
|
45
|
+
` # op run --env-file=.env -- your-command, with .env holding`,
|
|
46
|
+
` # OPENAI_API_KEY=op://${t.fields.vault}/${title}/credential`,
|
|
47
|
+
` # OPENAI_BASE_URL=${gateway.openaiBaseUrl}`,
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=onepassword.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onepassword.js","sourceRoot":"","sources":["../../src/secret-stores/onepassword.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG9C,MAAM,YAAY,GAChB,iJAAiJ,CAAC;AAEpJ,SAAS,MAAM,CAAC,OAAqB;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9F,OAAO,EAAE,QAAQ,EAAE,mBAAmB,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;AACrE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,WAAW;IAClB,GAAG,EAAE,IAAI;IACT,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,OAAO;IAClB,WAAW,EAAE,YAAY;IACzB,OAAO,EAAE,CAAC,SAAS,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,sBAAsB,EAAE,IAAI,CAAC;IAC/D,SAAS,EAAE,GAAG,EAAE,CACd,SAAS,CAAC;QACR,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,WAAW;QAClB,WAAW,EAAE,YAAY;QACzB,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,QAAQ,EAAE,sEAAsE;KACjF,CAAC;IACJ,aAAa,EAAE,MAAM;IACrB,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QACxB;YACE,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC;YACxD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,GAAG,IAAI,CAAC,SAAS,CAAC;gBAChB,KAAK;gBACL,QAAQ,EAAE,gBAAgB;gBAC1B,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;aAC9E,CAAC,IAAI;SACT;KACF;IACD,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC5B,wCAAwC;QACxC,mBAAmB,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,cAAc;QACxD,+DAA+D;QAC/D,6BAA6B,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,aAAa;QACjE,yBAAyB,OAAO,CAAC,aAAa,EAAE;KACjD;CACF,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shape for every secret store the CLI can hand a freshly minted key to.
|
|
3
|
+
*
|
|
4
|
+
* The contract every store must honour: the plaintext key travels to the
|
|
5
|
+
* platform CLI over stdin (directly, or through a path the CLI reads such as
|
|
6
|
+
* `/dev/stdin`), never through argv. Anything in argv is visible to every
|
|
7
|
+
* process on the machine via `ps`, and lands in shell history when a human
|
|
8
|
+
* copies the command.
|
|
9
|
+
*/
|
|
10
|
+
/** Stable ids, also the values accepted by `--store`. */
|
|
11
|
+
export declare const STORE_IDS: readonly ["github", "gitlab", "aws", "gcloud", "azure", "1password", "vault", "doppler", "cloudflare", "vercel", "kubernetes", "fly"];
|
|
12
|
+
export type StoreId = (typeof STORE_IDS)[number];
|
|
13
|
+
/** Flags that scope where a secret lands. Each store reads the ones it supports. */
|
|
14
|
+
export interface StoreOptions {
|
|
15
|
+
/** Secret / variable / item name, from --secret or a store shorthand. */
|
|
16
|
+
secret?: string;
|
|
17
|
+
repo?: string;
|
|
18
|
+
env?: string;
|
|
19
|
+
org?: string;
|
|
20
|
+
region?: string;
|
|
21
|
+
project?: string;
|
|
22
|
+
keyVault?: string;
|
|
23
|
+
opVault?: string;
|
|
24
|
+
mount?: string;
|
|
25
|
+
field?: string;
|
|
26
|
+
dopplerConfig?: string;
|
|
27
|
+
worker?: string;
|
|
28
|
+
vercelTarget?: string;
|
|
29
|
+
namespace?: string;
|
|
30
|
+
k8sKey?: string;
|
|
31
|
+
app?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Every option name a store may claim, for the "unsupported flag" check. */
|
|
34
|
+
export type StoreOptionKey = Exclude<keyof StoreOptions, "secret">;
|
|
35
|
+
/**
|
|
36
|
+
* Where the secret lands, resolved from the flags (and sometimes the current
|
|
37
|
+
* directory). `fields` are echoed into `--output json`; `describe` is the human
|
|
38
|
+
* sentence in the confirmation prompt and the success line.
|
|
39
|
+
*/
|
|
40
|
+
export interface StoreTarget {
|
|
41
|
+
describe: string;
|
|
42
|
+
fields: Record<string, string>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* How the plaintext reaches the platform CLI.
|
|
46
|
+
*
|
|
47
|
+
* - `stdin`: the value (or a rendered `payload`) is written to the child's stdin.
|
|
48
|
+
* - `path`: argv names a file the CLI reads. On POSIX that is `/dev/stdin` with
|
|
49
|
+
* the value piped in; on Windows the runner writes a 0600 temp file and
|
|
50
|
+
* substitutes its path for the `{}` placeholder.
|
|
51
|
+
*
|
|
52
|
+
* `note` explains what the attempt does, for the error message when every
|
|
53
|
+
* attempt fails.
|
|
54
|
+
*/
|
|
55
|
+
export type Delivery = {
|
|
56
|
+
note: string;
|
|
57
|
+
/** Wraps the plaintext (a JSON template, a KEY=VALUE line) before it is sent. */
|
|
58
|
+
payload?: (value: string) => string;
|
|
59
|
+
} & ({
|
|
60
|
+
kind: "stdin";
|
|
61
|
+
args: string[];
|
|
62
|
+
} | {
|
|
63
|
+
kind: "path";
|
|
64
|
+
args: string[];
|
|
65
|
+
});
|
|
66
|
+
export interface Gateway {
|
|
67
|
+
/** OpenAI-compatible base, e.g. https://inference.heyditto.ai/v1 */
|
|
68
|
+
openaiBaseUrl: string;
|
|
69
|
+
/** Anthropic base (no /v1), e.g. https://inference.heyditto.ai */
|
|
70
|
+
anthropicBaseUrl: string;
|
|
71
|
+
}
|
|
72
|
+
export interface SecretStore {
|
|
73
|
+
id: StoreId;
|
|
74
|
+
/** Human label, e.g. "GitHub Actions". */
|
|
75
|
+
label: string;
|
|
76
|
+
/** Executable the CLI delegates to. */
|
|
77
|
+
bin: string;
|
|
78
|
+
/** Other names the same CLI ships under, e.g. flyctl for fly. */
|
|
79
|
+
altBins?: readonly string[];
|
|
80
|
+
/** How this CLI reports its version (az and vault do not take --version). */
|
|
81
|
+
versionArgs?: readonly string[];
|
|
82
|
+
/** Shorthand flag that both selects this store and names the secret. */
|
|
83
|
+
shorthand: string;
|
|
84
|
+
/** What the shorthand's value is called in help text, e.g. "NAME" or "TITLE". */
|
|
85
|
+
nameLabel: string;
|
|
86
|
+
/** How to get the CLI and sign in, quoted in errors when it is missing. */
|
|
87
|
+
installHint: string;
|
|
88
|
+
/** Scoping options this store understands; anything else is rejected. */
|
|
89
|
+
options: readonly StoreOptionKey[];
|
|
90
|
+
/** Rejects names the platform will not accept. Returns the trimmed name. */
|
|
91
|
+
validateName(name: string): string;
|
|
92
|
+
/** Cheap failure before anything is minted: binary present and signed in. */
|
|
93
|
+
preflight(): void;
|
|
94
|
+
/** Reads the scoping flags; may infer from the cwd the way `gh` does. */
|
|
95
|
+
resolveTarget(options: StoreOptions): StoreTarget;
|
|
96
|
+
/**
|
|
97
|
+
* Attempts, in order, for storing `name` at `target`. Several platforms
|
|
98
|
+
* separate "create" from "add a new version", so the second attempt runs
|
|
99
|
+
* only when the first fails (e.g. the secret already exists).
|
|
100
|
+
*/
|
|
101
|
+
deliveries(name: string, target: StoreTarget): Delivery[];
|
|
102
|
+
/** How to read the secret back / wire it into a runtime. */
|
|
103
|
+
usage(name: string, target: StoreTarget, gateway: Gateway): string[];
|
|
104
|
+
/** Key label in the Ditto app. Defaults to `<store>:<target>:<name>`. */
|
|
105
|
+
keyName?(name: string, target: StoreTarget): string;
|
|
106
|
+
/** Platform reference for the stored value, echoed in `--output json`. */
|
|
107
|
+
snippet?(name: string, target: StoreTarget): string;
|
|
108
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shape for every secret store the CLI can hand a freshly minted key to.
|
|
3
|
+
*
|
|
4
|
+
* The contract every store must honour: the plaintext key travels to the
|
|
5
|
+
* platform CLI over stdin (directly, or through a path the CLI reads such as
|
|
6
|
+
* `/dev/stdin`), never through argv. Anything in argv is visible to every
|
|
7
|
+
* process on the machine via `ps`, and lands in shell history when a human
|
|
8
|
+
* copies the command.
|
|
9
|
+
*/
|
|
10
|
+
/** Stable ids, also the values accepted by `--store`. */
|
|
11
|
+
export const STORE_IDS = [
|
|
12
|
+
"github",
|
|
13
|
+
"gitlab",
|
|
14
|
+
"aws",
|
|
15
|
+
"gcloud",
|
|
16
|
+
"azure",
|
|
17
|
+
"1password",
|
|
18
|
+
"vault",
|
|
19
|
+
"doppler",
|
|
20
|
+
"cloudflare",
|
|
21
|
+
"vercel",
|
|
22
|
+
"kubernetes",
|
|
23
|
+
"fly",
|
|
24
|
+
];
|
|
25
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/secret-stores/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yDAAyD;AACzD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,OAAO;IACP,WAAW;IACX,OAAO;IACP,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,YAAY;IACZ,KAAK;CACG,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* HashiCorp Vault kv. `FIELD=-` makes Vault read that single field's value
|
|
4
|
+
* from stdin. `kv patch` leaves the path's other fields alone but needs the
|
|
5
|
+
* path to exist, so `kv put` is the fallback that creates it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const vault: SecretStore;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { preflight } from "./exec.js";
|
|
2
|
+
import { secretPath, slug } from "./naming.js";
|
|
3
|
+
const INSTALL_HINT = "install the Vault CLI from https://developer.hashicorp.com/vault/install (brew install hashicorp/tap/vault), then export VAULT_ADDR and run `vault login`";
|
|
4
|
+
function target(options) {
|
|
5
|
+
const mount = options.mount ? slug("--mount", options.mount, /^[A-Za-z0-9_.\-/]+$/) : "secret";
|
|
6
|
+
const field = options.field ? slug("--field", options.field, /^[A-Za-z0-9_.-]+$/) : "token";
|
|
7
|
+
return { describe: `Vault ${mount}/ (field ${field})`, fields: { mount, field } };
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* HashiCorp Vault kv. `FIELD=-` makes Vault read that single field's value
|
|
11
|
+
* from stdin. `kv patch` leaves the path's other fields alone but needs the
|
|
12
|
+
* path to exist, so `kv put` is the fallback that creates it.
|
|
13
|
+
*/
|
|
14
|
+
export const vault = {
|
|
15
|
+
id: "vault",
|
|
16
|
+
label: "HashiCorp Vault",
|
|
17
|
+
bin: "vault",
|
|
18
|
+
shorthand: "--vault-secret",
|
|
19
|
+
nameLabel: "PATH",
|
|
20
|
+
installHint: INSTALL_HINT,
|
|
21
|
+
versionArgs: ["version"],
|
|
22
|
+
options: ["mount", "field"],
|
|
23
|
+
validateName: (name) => secretPath("Vault kv path", name),
|
|
24
|
+
preflight: () => preflight({
|
|
25
|
+
bin: "vault",
|
|
26
|
+
label: "HashiCorp Vault",
|
|
27
|
+
installHint: INSTALL_HINT,
|
|
28
|
+
versionArgs: vault.versionArgs,
|
|
29
|
+
authArgs: ["token", "lookup"],
|
|
30
|
+
authHint: "Set VAULT_ADDR and run `vault login` first.",
|
|
31
|
+
}),
|
|
32
|
+
resolveTarget: target,
|
|
33
|
+
deliveries: (path, t) => {
|
|
34
|
+
const args = (verb) => ["kv", verb, `-mount=${t.fields.mount}`, path, `${t.fields.field}=-`];
|
|
35
|
+
return [
|
|
36
|
+
{ note: "vault kv patch", kind: "stdin", args: args("patch") },
|
|
37
|
+
{ note: "vault kv put", kind: "stdin", args: args("put") },
|
|
38
|
+
];
|
|
39
|
+
},
|
|
40
|
+
usage: (path, t, gateway) => [
|
|
41
|
+
"Read it back at runtime:",
|
|
42
|
+
` vault kv get -mount=${t.fields.mount} -field=${t.fields.field} ${path}`,
|
|
43
|
+
` # export OPENAI_API_KEY=$(…) with OPENAI_BASE_URL=${gateway.openaiBaseUrl}`,
|
|
44
|
+
` # or ANTHROPIC_AUTH_TOKEN with ANTHROPIC_BASE_URL=${gateway.anthropicBaseUrl}`,
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/secret-stores/vault.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,YAAY,GAChB,2JAA2J,CAAC;AAE9J,SAAS,MAAM,CAAC,OAAqB;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/F,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5F,OAAO,EAAE,QAAQ,EAAE,SAAS,KAAK,YAAY,KAAK,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAgB;IAChC,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,iBAAiB;IACxB,GAAG,EAAE,OAAO;IACZ,SAAS,EAAE,gBAAgB;IAC3B,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,YAAY;IACzB,WAAW,EAAE,CAAC,SAAS,CAAC;IACxB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC;IACzD,SAAS,EAAE,GAAG,EAAE,CACd,SAAS,CAAC;QACR,GAAG,EAAE,OAAO;QACZ,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,YAAY;QACzB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC7B,QAAQ,EAAE,6CAA6C;KACxD,CAAC;IACJ,aAAa,EAAE,MAAM;IACrB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QACrG,OAAO;YACL,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;YAC9D,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE;SAC3D,CAAC;IACJ,CAAC;IACD,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3B,0BAA0B;QAC1B,yBAAyB,CAAC,CAAC,MAAM,CAAC,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE;QAC1E,uDAAuD,OAAO,CAAC,aAAa,EAAE;QAC9E,uDAAuD,OAAO,CAAC,gBAAgB,EAAE;KAClF;CACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Vercel environment variables. `vercel env add NAME <target>` takes the value
|
|
4
|
+
* from stdin (its `--value` flag is the argv-leaking alternative); `--force`
|
|
5
|
+
* replaces an existing variable and `--sensitive` hides it from the dashboard.
|
|
6
|
+
*/
|
|
7
|
+
export declare const vercel: SecretStore;
|
|
8
|
+
/** Exported for the flag's help text and tests. */
|
|
9
|
+
export declare const VERCEL_TARGETS: readonly ["production", "preview", "development"];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { preflight } from "./exec.js";
|
|
2
|
+
import { envStyleName } from "./naming.js";
|
|
3
|
+
const INSTALL_HINT = "install the Vercel CLI from https://vercel.com/docs/cli (npm i -g vercel), then run `vercel login` and `vercel link`";
|
|
4
|
+
const TARGETS = ["production", "preview", "development"];
|
|
5
|
+
function target(options) {
|
|
6
|
+
const raw = options.vercelTarget?.trim() ?? "production";
|
|
7
|
+
if (!TARGETS.includes(raw)) {
|
|
8
|
+
throw new Error(`--vercel-target must be one of: ${TARGETS.join(", ")}`);
|
|
9
|
+
}
|
|
10
|
+
return { describe: `Vercel ${raw} environment`, fields: { target: raw } };
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Vercel environment variables. `vercel env add NAME <target>` takes the value
|
|
14
|
+
* from stdin (its `--value` flag is the argv-leaking alternative); `--force`
|
|
15
|
+
* replaces an existing variable and `--sensitive` hides it from the dashboard.
|
|
16
|
+
*/
|
|
17
|
+
export const vercel = {
|
|
18
|
+
id: "vercel",
|
|
19
|
+
label: "Vercel",
|
|
20
|
+
bin: "vercel",
|
|
21
|
+
shorthand: "--vercel-env",
|
|
22
|
+
nameLabel: "NAME",
|
|
23
|
+
installHint: INSTALL_HINT,
|
|
24
|
+
options: ["vercelTarget"],
|
|
25
|
+
validateName: (name) => envStyleName("Vercel environment variable", name),
|
|
26
|
+
preflight: () => preflight({
|
|
27
|
+
bin: "vercel",
|
|
28
|
+
label: "Vercel",
|
|
29
|
+
installHint: INSTALL_HINT,
|
|
30
|
+
authArgs: ["whoami"],
|
|
31
|
+
authHint: "Run `vercel login` first, or set VERCEL_TOKEN.",
|
|
32
|
+
}),
|
|
33
|
+
resolveTarget: target,
|
|
34
|
+
deliveries: (name, t) => [
|
|
35
|
+
{
|
|
36
|
+
note: "vercel env add",
|
|
37
|
+
kind: "stdin",
|
|
38
|
+
args: ["env", "add", name, t.fields.target, "--force", "--sensitive", "--yes", "--non-interactive"],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
usage: (name, t, gateway) => [
|
|
42
|
+
`Pull it into a local .env: vercel env pull --environment=${t.fields.target}`,
|
|
43
|
+
` # ${name} is in the ${t.fields.target} environment of the linked project`,
|
|
44
|
+
` # point clients at OPENAI_BASE_URL=${gateway.openaiBaseUrl}`,
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
/** Exported for the flag's help text and tests. */
|
|
48
|
+
export const VERCEL_TARGETS = TARGETS;
|
|
49
|
+
//# sourceMappingURL=vercel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel.js","sourceRoot":"","sources":["../../src/secret-stores/vercel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,YAAY,GAChB,sHAAsH,CAAC;AAEzH,MAAM,OAAO,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,aAAa,CAAU,CAAC;AAElE,SAAS,MAAM,CAAC,OAAqB;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,YAAY,CAAC;IACzD,IAAI,CAAE,OAA6B,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,UAAU,GAAG,cAAc,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;AAC5E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAgB;IACjC,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,QAAQ;IACf,GAAG,EAAE,QAAQ;IACb,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,YAAY;IACzB,OAAO,EAAE,CAAC,cAAc,CAAC;IACzB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,6BAA6B,EAAE,IAAI,CAAC;IACzE,SAAS,EAAE,GAAG,EAAE,CACd,SAAS,CAAC;QACR,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,YAAY;QACzB,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,QAAQ,EAAE,gDAAgD;KAC3D,CAAC;IACJ,aAAa,EAAE,MAAM;IACrB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QACvB;YACE,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,CAAC;SACpG;KACF;IACD,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3B,4DAA4D,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE;QAC7E,OAAO,IAAI,cAAc,CAAC,CAAC,MAAM,CAAC,MAAM,oCAAoC;QAC5E,wCAAwC,OAAO,CAAC,aAAa,EAAE;KAChE;CACF,CAAC;AAEF,mDAAmD;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC"}
|
|
@@ -8,6 +8,11 @@ export interface HarnessLocation {
|
|
|
8
8
|
/** Absolute directory the session is keyed under (Claude project dir). */
|
|
9
9
|
keyDir?: string;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The directory as Claude Code sees it: canonical (symlinks resolved, e.g.
|
|
13
|
+
* macOS /tmp → /private/tmp) when it exists, else just absolute.
|
|
14
|
+
*/
|
|
15
|
+
export declare function canonicalCwd(cwd: string): string;
|
|
11
16
|
/** Locates Claude Code transcript files for a session recorded under `cwd`. */
|
|
12
17
|
export declare function locateClaude(sessionId: string, cwd: string): Promise<HarnessLocation | null>;
|
|
13
18
|
/** Locates a Codex rollout transcript by thread id. */
|
package/dist/teleport/harness.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
2
3
|
import { access, mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
3
4
|
import os from "node:os";
|
|
4
5
|
import path from "node:path";
|
|
@@ -10,9 +11,21 @@ function claudeHome() {
|
|
|
10
11
|
function codexHome() {
|
|
11
12
|
return process.env.CODEX_HOME?.trim() || path.join(os.homedir(), ".codex");
|
|
12
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* The directory as Claude Code sees it: canonical (symlinks resolved, e.g.
|
|
16
|
+
* macOS /tmp → /private/tmp) when it exists, else just absolute.
|
|
17
|
+
*/
|
|
18
|
+
export function canonicalCwd(cwd) {
|
|
19
|
+
try {
|
|
20
|
+
return realpathSync(cwd);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return path.resolve(cwd);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
13
26
|
/** Locates Claude Code transcript files for a session recorded under `cwd`. */
|
|
14
27
|
export async function locateClaude(sessionId, cwd) {
|
|
15
|
-
const projectDir = path.join(claudeHome(), "projects", cwdSlug(cwd));
|
|
28
|
+
const projectDir = path.join(claudeHome(), "projects", cwdSlug(canonicalCwd(cwd)));
|
|
16
29
|
const jsonl = path.join(projectDir, `${sessionId}.jsonl`);
|
|
17
30
|
if (!(await exists(jsonl)))
|
|
18
31
|
return null;
|
|
@@ -74,14 +87,17 @@ export async function restoreClaudeTranscript(tarFile, compression, sessionId, o
|
|
|
74
87
|
const res = spawnSync("tar", ["-x", flag, "-f", tarFile, "-C", home], { maxBuffer: 64 * 1024 * 1024 });
|
|
75
88
|
if (res.status !== 0)
|
|
76
89
|
throw new Error(`tar extract failed: ${res.stderr?.toString().trim()}`);
|
|
77
|
-
|
|
90
|
+
const fromCwd = canonicalCwd(originalCwd);
|
|
91
|
+
const toCwd = canonicalCwd(targetCwd);
|
|
92
|
+
if (fromCwd === toCwd)
|
|
78
93
|
return;
|
|
79
|
-
const fromDir = path.join(claudeHome(), "projects", cwdSlug(
|
|
80
|
-
const toDir = path.join(claudeHome(), "projects", cwdSlug(
|
|
94
|
+
const fromDir = path.join(claudeHome(), "projects", cwdSlug(fromCwd));
|
|
95
|
+
const toDir = path.join(claudeHome(), "projects", cwdSlug(toCwd));
|
|
81
96
|
await mkdir(toDir, { recursive: true });
|
|
82
97
|
const fromJsonl = path.join(fromDir, `${sessionId}.jsonl`);
|
|
83
98
|
if (await exists(fromJsonl)) {
|
|
84
|
-
|
|
99
|
+
// Rewrite both the recorded and the canonical spelling of the source path.
|
|
100
|
+
const rewritten = (await readFile(fromJsonl, "utf8")).split(fromCwd).join(toCwd).split(originalCwd).join(toCwd);
|
|
85
101
|
await writeFile(path.join(toDir, `${sessionId}.jsonl`), rewritten);
|
|
86
102
|
}
|
|
87
103
|
const fromSub = path.join(fromDir, sessionId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/teleport/harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAsC,OAAO,EAAE,MAAM,YAAY,CAAC;AAYzE,SAAS,UAAU;IACjB,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC7E,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB,EAAE,GAAW;IAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/teleport/harness.ts"],"names":[],"mappings":"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"}
|
package/dist/teleport/types.d.ts
CHANGED
|
@@ -91,6 +91,13 @@ export interface Manifest {
|
|
|
91
91
|
/** Paths that never travel in a capsule: secrets, caches and build output. */
|
|
92
92
|
export declare const DEFAULT_EXCLUDES: readonly string[];
|
|
93
93
|
/** Claude Code keys its project dir on the absolute cwd with `/` and `:` replaced by `-`. */
|
|
94
|
+
/**
|
|
95
|
+
* Claude Code's project directory name for a working directory: every character
|
|
96
|
+
* outside [A-Za-z0-9] becomes "-" (underscores, dots, spaces and non-ASCII
|
|
97
|
+
* included; runs of dashes are kept). Verified empirically against Claude Code
|
|
98
|
+
* 2.1.x: `/private/tmp/tp slug_test.v1-é` → `-private-tmp-tp-slug-test-v1--`.
|
|
99
|
+
* Callers pass the canonical (realpath) directory, which is what Claude hashes.
|
|
100
|
+
*/
|
|
94
101
|
export declare function cwdSlug(cwd: string): string;
|
|
95
102
|
export declare function machineInfo(cliVersion: string): Manifest["machine"];
|
|
96
103
|
/** True when a repo-relative path matches one of the exclude globs. */
|