praetom 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -0
- package/dist/_esm-loader.d.ts +49 -0
- package/dist/_esm-loader.d.ts.map +1 -0
- package/dist/_esm-loader.js +131 -0
- package/dist/_esm-loader.js.map +1 -0
- package/dist/_internal.d.ts +63 -0
- package/dist/_internal.d.ts.map +1 -0
- package/dist/_internal.js +357 -0
- package/dist/_internal.js.map +1 -0
- package/dist/browser.d.ts +90 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +357 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli/cli.d.ts +3 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +97 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/commands/discover.d.ts +3 -0
- package/dist/cli/commands/discover.d.ts.map +1 -0
- package/dist/cli/commands/discover.js +15 -0
- package/dist/cli/commands/discover.js.map +1 -0
- package/dist/cli/commands/features.d.ts +5 -0
- package/dist/cli/commands/features.d.ts.map +1 -0
- package/dist/cli/commands/features.js +83 -0
- package/dist/cli/commands/features.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +52 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/login.d.ts +20 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +138 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +3 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +15 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/rotate.d.ts +3 -0
- package/dist/cli/commands/rotate.d.ts.map +1 -0
- package/dist/cli/commands/rotate.js +33 -0
- package/dist/cli/commands/rotate.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +54 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/uninstall.d.ts +3 -0
- package/dist/cli/commands/uninstall.d.ts.map +1 -0
- package/dist/cli/commands/uninstall.js +63 -0
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/commands/usage.d.ts +3 -0
- package/dist/cli/commands/usage.d.ts.map +1 -0
- package/dist/cli/commands/usage.js +19 -0
- package/dist/cli/commands/usage.js.map +1 -0
- package/dist/cli/commands/whoami.d.ts +3 -0
- package/dist/cli/commands/whoami.d.ts.map +1 -0
- package/dist/cli/commands/whoami.js +37 -0
- package/dist/cli/commands/whoami.js.map +1 -0
- package/dist/cli/util/agent-env.d.ts +13 -0
- package/dist/cli/util/agent-env.d.ts.map +1 -0
- package/dist/cli/util/agent-env.js +28 -0
- package/dist/cli/util/agent-env.js.map +1 -0
- package/dist/cli/util/api.d.ts +36 -0
- package/dist/cli/util/api.d.ts.map +1 -0
- package/dist/cli/util/api.js +84 -0
- package/dist/cli/util/api.js.map +1 -0
- package/dist/cli/util/auth-file.d.ts +25 -0
- package/dist/cli/util/auth-file.d.ts.map +1 -0
- package/dist/cli/util/auth-file.js +74 -0
- package/dist/cli/util/auth-file.js.map +1 -0
- package/dist/cli/util/git.d.ts +28 -0
- package/dist/cli/util/git.d.ts.map +1 -0
- package/dist/cli/util/git.js +103 -0
- package/dist/cli/util/git.js.map +1 -0
- package/dist/cli/util/run.d.ts +26 -0
- package/dist/cli/util/run.d.ts.map +1 -0
- package/dist/cli/util/run.js +31 -0
- package/dist/cli/util/run.js.map +1 -0
- package/dist/edge.d.ts +34 -0
- package/dist/edge.d.ts.map +1 -0
- package/dist/edge.js +127 -0
- package/dist/edge.js.map +1 -0
- package/dist/server.d.ts +69 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +193 -0
- package/dist/server.js.map +1 -0
- package/dist/vite/index.d.ts +48 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +138 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/webpack/index.d.ts +64 -0
- package/dist/webpack/index.d.ts.map +1 -0
- package/dist/webpack/index.js +106 -0
- package/dist/webpack/index.js.map +1 -0
- package/dist/webpack/loader.d.ts +27 -0
- package/dist/webpack/loader.d.ts.map +1 -0
- package/dist/webpack/loader.js +54 -0
- package/dist/webpack/loader.js.map +1 -0
- package/dist/webpack/shared.d.ts +25 -0
- package/dist/webpack/shared.d.ts.map +1 -0
- package/dist/webpack/shared.js +63 -0
- package/dist/webpack/shared.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/cli/util/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE1D,qBAAa,QAAS,SAAQ,KAAK;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;gBACD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAM3D;AAED,qBAAa,qBAAsB,SAAQ,KAAK;;CAO/C;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC,CAItD;AAED,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yFAAyF;IACzF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAkBD,wBAAsB,UAAU,CAAC,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAGhD"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the praetom API. Wraps fetch with the Bearer header and
|
|
3
|
+
* normalizes errors into shapes commands can branch on.
|
|
4
|
+
*/
|
|
5
|
+
import { readAuth } from "./auth-file.js";
|
|
6
|
+
export class ApiError extends Error {
|
|
7
|
+
status;
|
|
8
|
+
body;
|
|
9
|
+
constructor(status, body, message) {
|
|
10
|
+
super(message ?? `praetom API ${status}: ${body.slice(0, 200)}`);
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.body = body;
|
|
13
|
+
this.name = "ApiError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class NotAuthenticatedError extends Error {
|
|
17
|
+
constructor() {
|
|
18
|
+
super("Not signed in. Run `praetom login` to authenticate, or set PRAETOM_TOKEN.");
|
|
19
|
+
this.name = "NotAuthenticatedError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export async function requireAuth() {
|
|
23
|
+
const auth = await readAuth();
|
|
24
|
+
if (!auth)
|
|
25
|
+
throw new NotAuthenticatedError();
|
|
26
|
+
return auth;
|
|
27
|
+
}
|
|
28
|
+
function appendQuery(url, query) {
|
|
29
|
+
if (!query)
|
|
30
|
+
return url;
|
|
31
|
+
const entries = Object.entries(query).filter((kv) => typeof kv[1] === "string" && kv[1].length > 0);
|
|
32
|
+
if (entries.length === 0)
|
|
33
|
+
return url;
|
|
34
|
+
const sep = url.includes("?") ? "&" : "?";
|
|
35
|
+
const qs = entries
|
|
36
|
+
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
37
|
+
.join("&");
|
|
38
|
+
return `${url}${sep}${qs}`;
|
|
39
|
+
}
|
|
40
|
+
export async function apiRequest(path, opts = {}) {
|
|
41
|
+
const auth = opts.unauthenticated ? null : await requireAuth();
|
|
42
|
+
const base = opts.apiBase ?? auth?.apiBase ?? "https://praetom.com";
|
|
43
|
+
const url = appendQuery(`${base}${path.startsWith("/") ? path : `/${path}`}`, opts.query);
|
|
44
|
+
const headers = {
|
|
45
|
+
Accept: "application/json",
|
|
46
|
+
"User-Agent": "praetom-cli",
|
|
47
|
+
};
|
|
48
|
+
if (auth)
|
|
49
|
+
headers["Authorization"] = `Bearer ${auth.token}`;
|
|
50
|
+
if (opts.body !== undefined)
|
|
51
|
+
headers["Content-Type"] = "application/json";
|
|
52
|
+
const res = await fetch(url, {
|
|
53
|
+
method: opts.method ?? "GET",
|
|
54
|
+
headers,
|
|
55
|
+
body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
|
|
56
|
+
});
|
|
57
|
+
const text = await res.text().catch(() => "");
|
|
58
|
+
if (!res.ok) {
|
|
59
|
+
if (res.status === 401) {
|
|
60
|
+
throw new NotAuthenticatedError();
|
|
61
|
+
}
|
|
62
|
+
throw new ApiError(res.status, text);
|
|
63
|
+
}
|
|
64
|
+
if (!text)
|
|
65
|
+
return undefined;
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(text);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new ApiError(res.status, text, "praetom API returned non-JSON");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Build the standard query bag every workspace-scoped command sends:
|
|
75
|
+
* just `workspace` when `--workspace <slug>` was passed. Returns
|
|
76
|
+
* `undefined` when there's nothing to send so callers don't pollute the
|
|
77
|
+
* URL with empty query strings.
|
|
78
|
+
*/
|
|
79
|
+
export function workspaceQuery(ctx) {
|
|
80
|
+
if (!ctx.workspace)
|
|
81
|
+
return undefined;
|
|
82
|
+
return { workspace: ctx.workspace };
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/cli/util/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local authentication artifact for the praetom CLI.
|
|
3
|
+
*
|
|
4
|
+
* Lives at `$XDG_CONFIG_HOME/praetom/auth.json` (default
|
|
5
|
+
* `~/.config/praetom/auth.json`), mode 600. Carries the Bearer token the
|
|
6
|
+
* user generated in the dashboard and any non-default API base URL.
|
|
7
|
+
*
|
|
8
|
+
* Precedence at runtime:
|
|
9
|
+
* 1. `PRAETOM_TOKEN` env var, plus optional `PRAETOM_API_BASE` env
|
|
10
|
+
* 2. auth.json contents
|
|
11
|
+
* 3. nothing — commands needing auth fail with a "run `praetom login`" hint
|
|
12
|
+
*
|
|
13
|
+
* `login` writes here; `logout` removes here; every other command reads.
|
|
14
|
+
*/
|
|
15
|
+
export declare const DEFAULT_API_BASE = "https://praetom.com";
|
|
16
|
+
export interface AuthState {
|
|
17
|
+
token: string;
|
|
18
|
+
apiBase: string;
|
|
19
|
+
source: "env" | "file";
|
|
20
|
+
}
|
|
21
|
+
export declare function authFilePath(): string;
|
|
22
|
+
export declare function readAuth(): Promise<AuthState | null>;
|
|
23
|
+
export declare function writeAuth(token: string, apiBase?: string): Promise<void>;
|
|
24
|
+
export declare function deleteAuth(): Promise<boolean>;
|
|
25
|
+
//# sourceMappingURL=auth-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-file.d.ts","sourceRoot":"","sources":["../../../src/cli/util/auth-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AAStD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;CACxB;AAED,wBAAgB,YAAY,IAAI,MAAM,CAIrC;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAwB1D;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS9E;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CASnD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local authentication artifact for the praetom CLI.
|
|
3
|
+
*
|
|
4
|
+
* Lives at `$XDG_CONFIG_HOME/praetom/auth.json` (default
|
|
5
|
+
* `~/.config/praetom/auth.json`), mode 600. Carries the Bearer token the
|
|
6
|
+
* user generated in the dashboard and any non-default API base URL.
|
|
7
|
+
*
|
|
8
|
+
* Precedence at runtime:
|
|
9
|
+
* 1. `PRAETOM_TOKEN` env var, plus optional `PRAETOM_API_BASE` env
|
|
10
|
+
* 2. auth.json contents
|
|
11
|
+
* 3. nothing — commands needing auth fail with a "run `praetom login`" hint
|
|
12
|
+
*
|
|
13
|
+
* `login` writes here; `logout` removes here; every other command reads.
|
|
14
|
+
*/
|
|
15
|
+
import { promises as fs } from "node:fs";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { dirname, join } from "node:path";
|
|
18
|
+
export const DEFAULT_API_BASE = "https://praetom.com";
|
|
19
|
+
export function authFilePath() {
|
|
20
|
+
const xdg = process.env["XDG_CONFIG_HOME"];
|
|
21
|
+
if (xdg && xdg.length > 0)
|
|
22
|
+
return join(xdg, "praetom", "auth.json");
|
|
23
|
+
return join(homedir(), ".config", "praetom", "auth.json");
|
|
24
|
+
}
|
|
25
|
+
export async function readAuth() {
|
|
26
|
+
const envToken = process.env["PRAETOM_TOKEN"];
|
|
27
|
+
if (envToken && envToken.length > 0) {
|
|
28
|
+
return {
|
|
29
|
+
token: envToken,
|
|
30
|
+
apiBase: (process.env["PRAETOM_API_BASE"] ?? DEFAULT_API_BASE).replace(/\/+$/, ""),
|
|
31
|
+
source: "env",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const raw = await fs.readFile(authFilePath(), "utf8");
|
|
36
|
+
const parsed = JSON.parse(raw);
|
|
37
|
+
if (!parsed.token)
|
|
38
|
+
return null;
|
|
39
|
+
return {
|
|
40
|
+
token: parsed.token,
|
|
41
|
+
apiBase: (parsed.apiBase ?? DEFAULT_API_BASE).replace(/\/+$/, ""),
|
|
42
|
+
source: "file",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
const err = e;
|
|
47
|
+
if (err.code === "ENOENT")
|
|
48
|
+
return null;
|
|
49
|
+
throw e;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export async function writeAuth(token, apiBase) {
|
|
53
|
+
const path = authFilePath();
|
|
54
|
+
await fs.mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
55
|
+
const payload = {
|
|
56
|
+
token,
|
|
57
|
+
apiBase: apiBase && apiBase !== DEFAULT_API_BASE ? apiBase : undefined,
|
|
58
|
+
savedAt: new Date().toISOString(),
|
|
59
|
+
};
|
|
60
|
+
await fs.writeFile(path, JSON.stringify(payload, null, 2) + "\n", { mode: 0o600 });
|
|
61
|
+
}
|
|
62
|
+
export async function deleteAuth() {
|
|
63
|
+
try {
|
|
64
|
+
await fs.unlink(authFilePath());
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
const err = e;
|
|
69
|
+
if (err.code === "ENOENT")
|
|
70
|
+
return false;
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=auth-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-file.js","sourceRoot":"","sources":["../../../src/cli/util/auth-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect the GitHub `owner/name` for the current working directory from
|
|
3
|
+
* its git remote. Powers `praetom init`, `praetom status`, `praetom
|
|
4
|
+
* rotate` — anything that takes an implicit repo context.
|
|
5
|
+
*
|
|
6
|
+
* Resolution:
|
|
7
|
+
* 1. `--repo owner/name` global flag wins (handled by callers — not
|
|
8
|
+
* here).
|
|
9
|
+
* 2. The cwd's `origin` remote, parsed for owner/name.
|
|
10
|
+
*
|
|
11
|
+
* We never shell out; we read `.git/config` directly so this works on
|
|
12
|
+
* machines where `git` isn't on $PATH (rare, but agents sometimes ship
|
|
13
|
+
* minimal environments).
|
|
14
|
+
*/
|
|
15
|
+
export interface RepoIdentity {
|
|
16
|
+
owner: string;
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function detectRepoFromCwd(startDir?: string): Promise<RepoIdentity | null>;
|
|
20
|
+
export declare function parseRepoUrl(url: string): RepoIdentity | null;
|
|
21
|
+
export declare function parseRepoFlag(flag: string): RepoIdentity | null;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the repo for a command: --repo flag wins, fall back to cwd
|
|
24
|
+
* detection. Returns null if neither path yields a usable identity; the
|
|
25
|
+
* caller decides how to error.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveRepo(flag: string | undefined): Promise<RepoIdentity | null>;
|
|
28
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../src/cli/util/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,GAAE,MAAsB,GAC/B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAe9B;AAoCD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAW7D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAI/D;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAG9B"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect the GitHub `owner/name` for the current working directory from
|
|
3
|
+
* its git remote. Powers `praetom init`, `praetom status`, `praetom
|
|
4
|
+
* rotate` — anything that takes an implicit repo context.
|
|
5
|
+
*
|
|
6
|
+
* Resolution:
|
|
7
|
+
* 1. `--repo owner/name` global flag wins (handled by callers — not
|
|
8
|
+
* here).
|
|
9
|
+
* 2. The cwd's `origin` remote, parsed for owner/name.
|
|
10
|
+
*
|
|
11
|
+
* We never shell out; we read `.git/config` directly so this works on
|
|
12
|
+
* machines where `git` isn't on $PATH (rare, but agents sometimes ship
|
|
13
|
+
* minimal environments).
|
|
14
|
+
*/
|
|
15
|
+
import { promises as fs } from "node:fs";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
export async function detectRepoFromCwd(startDir = process.cwd()) {
|
|
18
|
+
const gitDir = await findGitDir(startDir);
|
|
19
|
+
if (!gitDir)
|
|
20
|
+
return null;
|
|
21
|
+
let config;
|
|
22
|
+
try {
|
|
23
|
+
config = await fs.readFile(join(gitDir, "config"), "utf8");
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
// Match `[remote "origin"]` block, then any `url = ...` line until the
|
|
29
|
+
// next section header. Simple state machine — git's INI is loose but
|
|
30
|
+
// origin's url is always on its own line inside its block.
|
|
31
|
+
const origin = extractRemoteUrl(config, "origin");
|
|
32
|
+
if (!origin)
|
|
33
|
+
return null;
|
|
34
|
+
return parseRepoUrl(origin);
|
|
35
|
+
}
|
|
36
|
+
async function findGitDir(start) {
|
|
37
|
+
let dir = start;
|
|
38
|
+
while (true) {
|
|
39
|
+
const candidate = join(dir, ".git");
|
|
40
|
+
try {
|
|
41
|
+
const stat = await fs.stat(candidate);
|
|
42
|
+
if (stat.isDirectory())
|
|
43
|
+
return candidate;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
/* not here, walk up */
|
|
47
|
+
}
|
|
48
|
+
const parent = join(dir, "..");
|
|
49
|
+
if (parent === dir)
|
|
50
|
+
return null;
|
|
51
|
+
dir = parent;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function extractRemoteUrl(config, remoteName) {
|
|
55
|
+
const lines = config.split("\n");
|
|
56
|
+
let inBlock = false;
|
|
57
|
+
for (const raw of lines) {
|
|
58
|
+
const line = raw.trim();
|
|
59
|
+
if (line.startsWith("[")) {
|
|
60
|
+
inBlock =
|
|
61
|
+
line === `[remote "${remoteName}"]` ||
|
|
62
|
+
line === `[remote '${remoteName}']`;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (!inBlock)
|
|
66
|
+
continue;
|
|
67
|
+
const m = /^url\s*=\s*(.+?)\s*$/.exec(line);
|
|
68
|
+
if (m)
|
|
69
|
+
return m[1] ?? null;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
export function parseRepoUrl(url) {
|
|
74
|
+
// Strip trailing .git if present.
|
|
75
|
+
const trimmed = url.replace(/\.git$/, "");
|
|
76
|
+
// HTTPS: https://github.com/owner/name
|
|
77
|
+
// SSH: git@github.com:owner/name
|
|
78
|
+
// GitHub CLI: gh:owner/name
|
|
79
|
+
let m = /^https?:\/\/[^/]+\/([^/]+)\/([^/]+)$/.exec(trimmed);
|
|
80
|
+
if (m)
|
|
81
|
+
return { owner: m[1], name: m[2] };
|
|
82
|
+
m = /^[^@]+@[^:]+:([^/]+)\/([^/]+)$/.exec(trimmed);
|
|
83
|
+
if (m)
|
|
84
|
+
return { owner: m[1], name: m[2] };
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
export function parseRepoFlag(flag) {
|
|
88
|
+
const m = /^([^/]+)\/([^/]+)$/.exec(flag.trim());
|
|
89
|
+
if (!m)
|
|
90
|
+
return null;
|
|
91
|
+
return { owner: m[1], name: m[2] };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Resolve the repo for a command: --repo flag wins, fall back to cwd
|
|
95
|
+
* detection. Returns null if neither path yields a usable identity; the
|
|
96
|
+
* caller decides how to error.
|
|
97
|
+
*/
|
|
98
|
+
export async function resolveRepo(flag) {
|
|
99
|
+
if (flag)
|
|
100
|
+
return parseRepoFlag(flag);
|
|
101
|
+
return detectRepoFromCwd();
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/cli/util/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { detectAgent } from "./agent-env.js";
|
|
3
|
+
/**
|
|
4
|
+
* Shared run-context that every command receives. Carries the global flags
|
|
5
|
+
* pre-parsed plus the detected agent (so commands can tailor wording).
|
|
6
|
+
*/
|
|
7
|
+
export interface RunContext {
|
|
8
|
+
workspace: string | undefined;
|
|
9
|
+
repo: string | undefined;
|
|
10
|
+
json: boolean;
|
|
11
|
+
nonInteractive: boolean;
|
|
12
|
+
agent: ReturnType<typeof detectAgent>;
|
|
13
|
+
}
|
|
14
|
+
export type CommandFn = (ctx: RunContext) => Promise<void> | void;
|
|
15
|
+
/**
|
|
16
|
+
* Lift a command implementation into commander's action signature: parse the
|
|
17
|
+
* global flags off the program root and hand the command a clean RunContext.
|
|
18
|
+
*/
|
|
19
|
+
export declare function runCommand(program: Command, fn: CommandFn): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Stub helper: print a "not implemented yet" message and exit with code 2 so
|
|
22
|
+
* automated callers see a non-zero status. Once a command is implemented,
|
|
23
|
+
* replace the call to this with the real body.
|
|
24
|
+
*/
|
|
25
|
+
export declare function notImplemented(ctx: RunContext, name: string): never;
|
|
26
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/util/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAElE;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAe/E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CASnE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { detectAgent } from "./agent-env.js";
|
|
2
|
+
/**
|
|
3
|
+
* Lift a command implementation into commander's action signature: parse the
|
|
4
|
+
* global flags off the program root and hand the command a clean RunContext.
|
|
5
|
+
*/
|
|
6
|
+
export async function runCommand(program, fn) {
|
|
7
|
+
const opts = program.opts();
|
|
8
|
+
const ctx = {
|
|
9
|
+
workspace: opts.workspace,
|
|
10
|
+
repo: opts.repo,
|
|
11
|
+
json: opts.json === true,
|
|
12
|
+
nonInteractive: opts.nonInteractive === true,
|
|
13
|
+
agent: detectAgent(),
|
|
14
|
+
};
|
|
15
|
+
await fn(ctx);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Stub helper: print a "not implemented yet" message and exit with code 2 so
|
|
19
|
+
* automated callers see a non-zero status. Once a command is implemented,
|
|
20
|
+
* replace the call to this with the real body.
|
|
21
|
+
*/
|
|
22
|
+
export function notImplemented(ctx, name) {
|
|
23
|
+
if (ctx.json) {
|
|
24
|
+
process.stdout.write(JSON.stringify({ error: "not_implemented", command: name }) + "\n");
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
process.stderr.write(`praetom ${name}: not implemented yet.\n`);
|
|
28
|
+
}
|
|
29
|
+
process.exit(2);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/util/run.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAgB7C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAgB,EAAE,EAAa;IAC9D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAKrB,CAAC;IACL,MAAM,GAAG,GAAe;QACtB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,IAAI;QACxB,cAAc,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI;QAC5C,KAAK,EAAE,WAAW,EAAE;KACrB,CAAC;IACF,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAe,EAAE,IAAY;IAC1D,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CACnE,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,0BAA0B,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
package/dist/edge.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge runtime stub — Vercel Edge / Cloudflare Workers / similar.
|
|
3
|
+
*
|
|
4
|
+
* Edge can't do auto-wrap (no Module._load equivalent) and can't use
|
|
5
|
+
* Node's AsyncLocalStorage either. v1 ships a minimal surface:
|
|
6
|
+
*
|
|
7
|
+
* - register() — sets config, no-op for autowrap
|
|
8
|
+
* - emit() — fire-and-forget OTLP span POST
|
|
9
|
+
*
|
|
10
|
+
* Edge workers are short-lived per request, so the buffering + interval
|
|
11
|
+
* flush pattern from /server and /browser doesn't apply. Each emit()
|
|
12
|
+
* call fires a fetch immediately; the worker should `ctx.waitUntil()`
|
|
13
|
+
* if it wants to be sure the request lands before the worker terminates.
|
|
14
|
+
*
|
|
15
|
+
* Customers running on edge: use emit() explicitly inside the handler,
|
|
16
|
+
* since there's no boundary wrap covering them automatically. The
|
|
17
|
+
* eventName carries the feature attribution.
|
|
18
|
+
*/
|
|
19
|
+
export interface RegisterOptions {
|
|
20
|
+
ingestId?: string;
|
|
21
|
+
endpoint?: string;
|
|
22
|
+
silent?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function register(opts?: RegisterOptions): Promise<void>;
|
|
25
|
+
export declare function emit(eventName: string, payload?: Record<string, unknown>): void;
|
|
26
|
+
/**
|
|
27
|
+
* Edge counterpart of the server's `__praetomWrapEntryPoint`. Bundler-
|
|
28
|
+
* plugin-emitted code can call the same symbol regardless of build
|
|
29
|
+
* layer; on edge, the wrap collapses to a single `emit(slug)` call
|
|
30
|
+
* after the handler resolves. No async-context — edge workers are
|
|
31
|
+
* request-scoped so the "current feature" is whatever this handler is.
|
|
32
|
+
*/
|
|
33
|
+
export declare function __praetomWrapEntryPoint<T>(slug: string, _entryName: string, original: (...args: unknown[]) => Promise<T> | T): (...args: unknown[]) => Promise<T>;
|
|
34
|
+
//# sourceMappingURL=edge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge.d.ts","sourceRoot":"","sources":["../src/edge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAYH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBxE;AAED,wBAAgB,IAAI,CAClB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,IAAI,CAmDN;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAC/C,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAWpC"}
|
package/dist/edge.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge runtime stub — Vercel Edge / Cloudflare Workers / similar.
|
|
3
|
+
*
|
|
4
|
+
* Edge can't do auto-wrap (no Module._load equivalent) and can't use
|
|
5
|
+
* Node's AsyncLocalStorage either. v1 ships a minimal surface:
|
|
6
|
+
*
|
|
7
|
+
* - register() — sets config, no-op for autowrap
|
|
8
|
+
* - emit() — fire-and-forget OTLP span POST
|
|
9
|
+
*
|
|
10
|
+
* Edge workers are short-lived per request, so the buffering + interval
|
|
11
|
+
* flush pattern from /server and /browser doesn't apply. Each emit()
|
|
12
|
+
* call fires a fetch immediately; the worker should `ctx.waitUntil()`
|
|
13
|
+
* if it wants to be sure the request lands before the worker terminates.
|
|
14
|
+
*
|
|
15
|
+
* Customers running on edge: use emit() explicitly inside the handler,
|
|
16
|
+
* since there's no boundary wrap covering them automatically. The
|
|
17
|
+
* eventName carries the feature attribution.
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_OTLP_ENDPOINT = "https://praetom.com/api/otlp/v1/traces";
|
|
20
|
+
let _config = null;
|
|
21
|
+
export async function register(opts = {}) {
|
|
22
|
+
const ingestId = opts.ingestId ??
|
|
23
|
+
(typeof process !== "undefined"
|
|
24
|
+
? process.env?.PRAETOM_INGEST_ID
|
|
25
|
+
: undefined);
|
|
26
|
+
if (!ingestId) {
|
|
27
|
+
if (!opts.silent) {
|
|
28
|
+
// eslint-disable-next-line no-console
|
|
29
|
+
console.warn("[praetom] PRAETOM_INGEST_ID not set; instrumentation disabled");
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
_config = {
|
|
34
|
+
ingestId,
|
|
35
|
+
endpoint: opts.endpoint ?? DEFAULT_OTLP_ENDPOINT,
|
|
36
|
+
silent: opts.silent ?? false,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function emit(eventName, payload) {
|
|
40
|
+
if (!_config)
|
|
41
|
+
return;
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
const traceId = randHex(16);
|
|
44
|
+
const spanId = randHex(8);
|
|
45
|
+
const attrs = [
|
|
46
|
+
{ key: "praetom.feature", value: { stringValue: eventName } },
|
|
47
|
+
];
|
|
48
|
+
if (payload) {
|
|
49
|
+
for (const [k, v] of Object.entries(payload)) {
|
|
50
|
+
if (v == null)
|
|
51
|
+
continue;
|
|
52
|
+
attrs.push({
|
|
53
|
+
key: k,
|
|
54
|
+
value: {
|
|
55
|
+
stringValue: typeof v === "string" ? v : JSON.stringify(v),
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const body = {
|
|
61
|
+
resourceSpans: [
|
|
62
|
+
{
|
|
63
|
+
scopeSpans: [
|
|
64
|
+
{
|
|
65
|
+
scope: { name: "praetom", version: "0.4.0" },
|
|
66
|
+
spans: [
|
|
67
|
+
{
|
|
68
|
+
traceId,
|
|
69
|
+
spanId,
|
|
70
|
+
name: eventName,
|
|
71
|
+
kind: 2,
|
|
72
|
+
startTimeUnixNano: `${now}000000`,
|
|
73
|
+
endTimeUnixNano: `${now}000000`,
|
|
74
|
+
attributes: attrs,
|
|
75
|
+
status: { code: 1 },
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
// Fire-and-forget. Caller should ctx.waitUntil() if they care about delivery.
|
|
84
|
+
void fetch(_config.endpoint, {
|
|
85
|
+
method: "POST",
|
|
86
|
+
headers: {
|
|
87
|
+
"content-type": "application/json",
|
|
88
|
+
authorization: `Bearer ${_config.ingestId}`,
|
|
89
|
+
},
|
|
90
|
+
body: JSON.stringify(body),
|
|
91
|
+
}).catch(() => { });
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Edge counterpart of the server's `__praetomWrapEntryPoint`. Bundler-
|
|
95
|
+
* plugin-emitted code can call the same symbol regardless of build
|
|
96
|
+
* layer; on edge, the wrap collapses to a single `emit(slug)` call
|
|
97
|
+
* after the handler resolves. No async-context — edge workers are
|
|
98
|
+
* request-scoped so the "current feature" is whatever this handler is.
|
|
99
|
+
*/
|
|
100
|
+
export function __praetomWrapEntryPoint(slug, _entryName, original) {
|
|
101
|
+
return async function (...args) {
|
|
102
|
+
try {
|
|
103
|
+
const result = await original.apply(this, args);
|
|
104
|
+
emit(slug);
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
emit(slug, { error: e.message });
|
|
109
|
+
throw e;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function randHex(bytes) {
|
|
114
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
115
|
+
const arr = new Uint8Array(bytes);
|
|
116
|
+
crypto.getRandomValues(arr);
|
|
117
|
+
return [...arr].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
118
|
+
}
|
|
119
|
+
let out = "";
|
|
120
|
+
for (let i = 0; i < bytes; i++) {
|
|
121
|
+
out += Math.floor(Math.random() * 256)
|
|
122
|
+
.toString(16)
|
|
123
|
+
.padStart(2, "0");
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=edge.js.map
|
package/dist/edge.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge.js","sourceRoot":"","sources":["../src/edge.ts"],"names":[],"mappings":"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"}
|