@procedures/lib 0.0.0-stage → 0.2.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/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +119 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/cli-flags.d.ts +27 -0
- package/dist/cli-flags.d.ts.map +1 -0
- package/dist/cli-flags.js +33 -0
- package/dist/cli-flags.js.map +1 -0
- package/dist/dag/builder.d.ts +18 -0
- package/dist/dag/builder.d.ts.map +1 -0
- package/dist/dag/builder.js +35 -0
- package/dist/dag/builder.js.map +1 -0
- package/dist/dag/index.d.ts +12 -0
- package/dist/dag/index.d.ts.map +1 -0
- package/dist/dag/index.js +12 -0
- package/dist/dag/index.js.map +1 -0
- package/dist/git/index.d.ts +5 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +5 -0
- package/dist/git/index.js.map +1 -0
- package/dist/git/ref-parser.d.ts +34 -0
- package/dist/git/ref-parser.d.ts.map +1 -0
- package/dist/git/ref-parser.js +70 -0
- package/dist/git/ref-parser.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/module.d.ts +22 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +180 -0
- package/dist/module.js.map +1 -0
- package/dist/procedures/core/catch.d.ts +33 -0
- package/dist/procedures/core/catch.d.ts.map +1 -0
- package/dist/procedures/core/catch.js +118 -0
- package/dist/procedures/core/catch.js.map +1 -0
- package/dist/procedures/core/index.d.ts +9 -0
- package/dist/procedures/core/index.d.ts.map +1 -0
- package/dist/procedures/core/index.js +8 -0
- package/dist/procedures/core/index.js.map +1 -0
- package/dist/procedures/dag/index.d.ts +5 -0
- package/dist/procedures/dag/index.d.ts.map +1 -0
- package/dist/procedures/dag/index.js +5 -0
- package/dist/procedures/dag/index.js.map +1 -0
- package/dist/procedures/dag/traverse.d.ts +54 -0
- package/dist/procedures/dag/traverse.d.ts.map +1 -0
- package/dist/procedures/dag/traverse.js +252 -0
- package/dist/procedures/dag/traverse.js.map +1 -0
- package/dist/procedures/ecosystem/index.d.ts +7 -0
- package/dist/procedures/ecosystem/index.d.ts.map +1 -0
- package/dist/procedures/ecosystem/index.js +6 -0
- package/dist/procedures/ecosystem/index.js.map +1 -0
- package/dist/procedures/ecosystem/procedures.d.ts +63 -0
- package/dist/procedures/ecosystem/procedures.d.ts.map +1 -0
- package/dist/procedures/ecosystem/procedures.js +215 -0
- package/dist/procedures/ecosystem/procedures.js.map +1 -0
- package/dist/procedures/lib/audit.d.ts +29 -0
- package/dist/procedures/lib/audit.d.ts.map +1 -0
- package/dist/procedures/lib/audit.js +236 -0
- package/dist/procedures/lib/audit.js.map +1 -0
- package/dist/procedures/lib/index.d.ts +8 -0
- package/dist/procedures/lib/index.d.ts.map +1 -0
- package/dist/procedures/lib/index.js +8 -0
- package/dist/procedures/lib/index.js.map +1 -0
- package/dist/procedures/lib/new.d.ts +20 -0
- package/dist/procedures/lib/new.d.ts.map +1 -0
- package/dist/procedures/lib/new.js +205 -0
- package/dist/procedures/lib/new.js.map +1 -0
- package/dist/procedures/lib/rename.d.ts +28 -0
- package/dist/procedures/lib/rename.d.ts.map +1 -0
- package/dist/procedures/lib/rename.js +267 -0
- package/dist/procedures/lib/rename.js.map +1 -0
- package/dist/procedures/lib/scan.d.ts +14 -0
- package/dist/procedures/lib/scan.d.ts.map +1 -0
- package/dist/procedures/lib/scan.js +102 -0
- package/dist/procedures/lib/scan.js.map +1 -0
- package/dist/register.d.ts +7 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +9 -0
- package/dist/register.js.map +1 -0
- package/dist/scoped-input.d.ts +17 -0
- package/dist/scoped-input.d.ts.map +1 -0
- package/dist/scoped-input.js +23 -0
- package/dist/scoped-input.js.map +1 -0
- package/dist/types.d.ts +248 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +231 -0
- package/dist/types.js.map +1 -0
- package/dist/workspace.d.ts +46 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +98 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +87 -3
- package/src/cli-flags.ts +49 -0
- package/src/dag/builder.ts +44 -0
- package/src/dag/index.ts +23 -0
- package/src/git/index.ts +11 -0
- package/src/git/ref-parser.ts +83 -0
- package/src/index.ts +56 -0
- package/src/module.ts +232 -0
- package/src/procedures/core/catch.ts +142 -0
- package/src/procedures/core/index.ts +9 -0
- package/src/procedures/dag/index.ts +5 -0
- package/src/procedures/dag/traverse.ts +281 -0
- package/src/procedures/ecosystem/index.ts +12 -0
- package/src/procedures/ecosystem/procedures.ts +317 -0
- package/src/procedures/lib/audit.ts +307 -0
- package/src/procedures/lib/index.ts +8 -0
- package/src/procedures/lib/new.ts +253 -0
- package/src/procedures/lib/rename.ts +355 -0
- package/src/procedures/lib/scan.ts +143 -0
- package/src/register.ts +11 -0
- package/src/types.ts +526 -0
- package/src/workspace.ts +110 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace helpers
|
|
3
|
+
*
|
|
4
|
+
* The client packages live in one pnpm workspace (the client monorepo). These helpers
|
|
5
|
+
* find the workspace root and decide which dependencies link two ecosystem packages,
|
|
6
|
+
* so the lib.* procedures work on the monorepo instead of one git repository per package.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { dirname, join, resolve } from "node:path";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
import { isMark1Russell7Ref } from "./git/index.js";
|
|
13
|
+
/**
|
|
14
|
+
* Expand a leading `~/` to the home directory
|
|
15
|
+
*/
|
|
16
|
+
export function expandHome(p) {
|
|
17
|
+
if (p === "~") {
|
|
18
|
+
return homedir();
|
|
19
|
+
}
|
|
20
|
+
if (p.startsWith("~/") || p.startsWith("~\\")) {
|
|
21
|
+
return join(homedir(), p.slice(2));
|
|
22
|
+
}
|
|
23
|
+
return p;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Find the nearest folder at or above `start` that holds pnpm-workspace.yaml
|
|
27
|
+
*/
|
|
28
|
+
export function findWorkspaceRoot(start) {
|
|
29
|
+
let dir = resolve(start);
|
|
30
|
+
for (;;) {
|
|
31
|
+
if (existsSync(join(dir, "pnpm-workspace.yaml"))) {
|
|
32
|
+
return dir;
|
|
33
|
+
}
|
|
34
|
+
const parent = dirname(dir);
|
|
35
|
+
if (parent === dir) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
dir = parent;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the workspace root for a procedure call: the explicit `rootPath` if given,
|
|
43
|
+
* else the workspace that contains this package.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveWorkspaceRoot(rootPath) {
|
|
46
|
+
if (rootPath) {
|
|
47
|
+
// Only a real workspace root: lib.new runs that workspace's cue CLI, and lib.rename rewrites
|
|
48
|
+
// its files, so a rootPath elsewhere ran a script from any folder (deep dive DATA-18)
|
|
49
|
+
const root = resolve(expandHome(rootPath));
|
|
50
|
+
if (!existsSync(join(root, "pnpm-workspace.yaml"))) {
|
|
51
|
+
throw new Error(`Not a workspace root (no pnpm-workspace.yaml): ${root}`);
|
|
52
|
+
}
|
|
53
|
+
return root;
|
|
54
|
+
}
|
|
55
|
+
const own = findWorkspaceRoot(dirname(fileURLToPath(import.meta.url)));
|
|
56
|
+
if (!own) {
|
|
57
|
+
throw new Error("Could not find the workspace root (no pnpm-workspace.yaml above client-lib). Pass rootPath.");
|
|
58
|
+
}
|
|
59
|
+
return own;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The folder that holds the workspace packages
|
|
63
|
+
*/
|
|
64
|
+
export function packagesDir(root) {
|
|
65
|
+
return join(root, "packages");
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Return true if a dependency spec links to another ecosystem package:
|
|
69
|
+
* a workspace link (`workspace:*`) or a `github:mark1russell7/...` reference.
|
|
70
|
+
*/
|
|
71
|
+
export function isEcosystemDependencySpec(spec) {
|
|
72
|
+
return spec.startsWith("workspace:") || isMark1Russell7Ref(spec);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The npm scopes of the ecosystem: `@procedures` for the packages of this workspace, and
|
|
76
|
+
* `@mark1russell7` for the general packages (cue, splay, docker-sqlite and the others).
|
|
77
|
+
*/
|
|
78
|
+
export const ECOSYSTEM_SCOPES = ["@procedures/", "@mark1russell7/"];
|
|
79
|
+
/** True for the name of a package of the ecosystem scopes. */
|
|
80
|
+
export function isEcosystemPackageName(name) {
|
|
81
|
+
return ECOSYSTEM_SCOPES.some((scope) => name.startsWith(scope));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Collect the names of the ecosystem packages (`@procedures/*` and `@mark1russell7/*`) that a
|
|
85
|
+
* package.json depends on (dependencies, devDependencies and peerDependencies), without duplicates.
|
|
86
|
+
*/
|
|
87
|
+
export function extractEcosystemDeps(pkg) {
|
|
88
|
+
const names = new Set();
|
|
89
|
+
for (const deps of [pkg.dependencies, pkg.devDependencies, pkg.peerDependencies]) {
|
|
90
|
+
for (const [name, spec] of Object.entries(deps ?? {})) {
|
|
91
|
+
if (isEcosystemPackageName(name) && isEcosystemDependencySpec(spec)) {
|
|
92
|
+
names.add(name);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return [...names];
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,90 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package",
|
|
2
3
|
"name": "@procedures/lib",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "Workspace procedures for pnpm monorepos: scan the packages, scaffold a new package, audit packages against a template, rename across the workspace, and program runners.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"monorepo",
|
|
8
|
+
"pnpm",
|
|
9
|
+
"workspace",
|
|
10
|
+
"scaffold",
|
|
11
|
+
"audit",
|
|
12
|
+
"procedures"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://mark1russell7.github.io/client/",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/mark1russell7/client/issues"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/mark1russell7/client.git",
|
|
21
|
+
"directory": "packages/client-lib"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"author": "Mark Russell (https://github.com/mark1russell7)",
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./module": {
|
|
34
|
+
"types": "./dist/module.d.ts",
|
|
35
|
+
"import": "./dist/module.js"
|
|
36
|
+
},
|
|
37
|
+
"./register": {
|
|
38
|
+
"types": "./dist/register.d.ts",
|
|
39
|
+
"import": "./dist/register.js"
|
|
40
|
+
},
|
|
41
|
+
"./cli-flags": {
|
|
42
|
+
"types": "./dist/cli-flags.d.ts",
|
|
43
|
+
"import": "./dist/cli-flags.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist",
|
|
48
|
+
"src",
|
|
49
|
+
"!src/**/*.test.ts",
|
|
50
|
+
"!src/**/*.test.tsx",
|
|
51
|
+
"!src/**/__tests__",
|
|
52
|
+
"CHANGELOG.md"
|
|
53
|
+
],
|
|
54
|
+
"sideEffects": [
|
|
55
|
+
"./dist/register.js"
|
|
56
|
+
],
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=22"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public",
|
|
62
|
+
"provenance": true
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"typescript": "^7.0.2",
|
|
66
|
+
"@types/node": "^22.0.0",
|
|
67
|
+
"@mark1russell7/cue": "^1.0.0",
|
|
68
|
+
"vitest": "^5.0.3"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"@procedures/client": "0.2.0",
|
|
72
|
+
"@procedures/dag": "0.2.0",
|
|
73
|
+
"@procedures/fs": "0.2.0",
|
|
74
|
+
"@procedures/git": "0.2.0",
|
|
75
|
+
"@procedures/pnpm": "0.2.0",
|
|
76
|
+
"@procedures/shell": "0.2.0",
|
|
77
|
+
"ts-morph": "^24.0.0",
|
|
78
|
+
"zod": "^4.6.5"
|
|
79
|
+
},
|
|
80
|
+
"client": {
|
|
81
|
+
"procedures": "./dist/register.js"
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "tsc -b",
|
|
85
|
+
"typecheck": "tsc --noEmit",
|
|
86
|
+
"clean": "rm -rf dist .tsbuildinfo",
|
|
87
|
+
"test": "vitest run --passWithNoTests",
|
|
88
|
+
"test:watch": "vitest"
|
|
89
|
+
}
|
|
6
90
|
}
|
package/src/cli-flags.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The global flags of the `mark` CLI.
|
|
3
|
+
*
|
|
4
|
+
* `mark` reads a global flag before the command path. After the path, a flag is global only when
|
|
5
|
+
* the procedure does not declare a flag of that name: `mark docker compose down -v` gives `-v` to
|
|
6
|
+
* the procedure. `lib.audit` reports each procedure flag that hides a global flag in this way.
|
|
7
|
+
*
|
|
8
|
+
* This module has no side effects: `mark` imports it before it loads the procedures.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface CliGlobalFlag {
|
|
12
|
+
/** The long name, without "--" */
|
|
13
|
+
readonly long: string;
|
|
14
|
+
/** The short letter, without "-" */
|
|
15
|
+
readonly short?: string;
|
|
16
|
+
/** True when the flag takes a value */
|
|
17
|
+
readonly takesValue: boolean;
|
|
18
|
+
/** True when the flag starts a mode (the server or the REPL) and takes no command */
|
|
19
|
+
readonly mode?: boolean;
|
|
20
|
+
/** True when the flag is an option of `--server` */
|
|
21
|
+
readonly serverOption?: boolean;
|
|
22
|
+
/** The help text */
|
|
23
|
+
readonly description: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const CLI_GLOBAL_FLAGS: readonly CliGlobalFlag[] = [
|
|
27
|
+
{ long: "help", short: "h", takesValue: false, description: "Show the help" },
|
|
28
|
+
{ long: "version", short: "v", takesValue: false, description: "Show the version" },
|
|
29
|
+
{ long: "verbose", short: "V", takesValue: false, description: "Show more output" },
|
|
30
|
+
{ long: "format", short: "f", takesValue: true, description: "The output format: text, json, table or streaming" },
|
|
31
|
+
{ long: "local", takesValue: false, description: "Run the command in this process, not on the CLI server" },
|
|
32
|
+
{ long: "json", takesValue: true, description: "Run a procedure reference that is given as JSON" },
|
|
33
|
+
{ long: "no-input", takesValue: false, description: "Never ask for a missing argument (also when CI is set)" },
|
|
34
|
+
{ long: "interactive", short: "i", takesValue: false, mode: true, description: "Start the REPL" },
|
|
35
|
+
{ long: "server", takesValue: false, mode: true, description: "Start the CLI server" },
|
|
36
|
+
{ long: "port", takesValue: true, serverOption: true, description: "The port of the CLI server (with --server)" },
|
|
37
|
+
{ long: "host", takesValue: true, serverOption: true, description: "The host of the CLI server (with --server)" },
|
|
38
|
+
{
|
|
39
|
+
long: "transport",
|
|
40
|
+
takesValue: true,
|
|
41
|
+
serverOption: true,
|
|
42
|
+
description: "The transport of the CLI server: http, websocket or both (with --server)",
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
/** The global flag with this long name or short letter */
|
|
47
|
+
export function findGlobalFlag(name: string, short: boolean): CliGlobalFlag | undefined {
|
|
48
|
+
return CLI_GLOBAL_FLAGS.find((flag) => (short ? flag.short === name : flag.long === name));
|
|
49
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DAG Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds the ecosystem-specific dependency DAG from package scan results. This is the only
|
|
5
|
+
* domain-specific piece; the generic DAG algorithms (buildLeveledDAG, executeDAG, filterDAGFromRoot,
|
|
6
|
+
* getAncestors, getDescendants, ...) live in @procedures/dag. This package previously
|
|
7
|
+
* vendored a verbatim copy of those — see documentation/BUGS-2026-07.md (DAG de-dup).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { DAGNode, PackageInfo } from "../types.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Build DAG nodes from package info.
|
|
14
|
+
*
|
|
15
|
+
* Creates nodes only for packages that are mark1russell7 dependencies and exist in the scanned
|
|
16
|
+
* packages. `id` mirrors `name` so the nodes satisfy client-dag's DAGNode contract (which keys by
|
|
17
|
+
* id) while the ecosystem code keeps using the readable `name`.
|
|
18
|
+
*/
|
|
19
|
+
export function buildDAGNodes(
|
|
20
|
+
packages: Record<string, PackageInfo>
|
|
21
|
+
): Map<string, DAGNode> {
|
|
22
|
+
const nodes = new Map<string, DAGNode>();
|
|
23
|
+
|
|
24
|
+
for (const [name, info] of Object.entries(packages)) {
|
|
25
|
+
// Only include packages that have mark1russell7 dependencies or are dependencies of others.
|
|
26
|
+
const deps = info.mark1russell7Deps.filter((dep) => packages[dep] !== undefined);
|
|
27
|
+
|
|
28
|
+
const gitRef = info.gitRemote ?? `github:mark1russell7/${info.name}#${info.currentBranch ?? "main"}`;
|
|
29
|
+
const requiredBranch = info.currentBranch ?? "main";
|
|
30
|
+
|
|
31
|
+
const node: DAGNode = {
|
|
32
|
+
id: name,
|
|
33
|
+
name,
|
|
34
|
+
repoPath: info.repoPath,
|
|
35
|
+
gitRef,
|
|
36
|
+
requiredBranch,
|
|
37
|
+
dependencies: deps,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
nodes.set(name, node);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return nodes;
|
|
44
|
+
}
|
package/src/dag/index.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DAG utilities.
|
|
3
|
+
*
|
|
4
|
+
* The generic DAG algorithms are re-exported from @procedures/dag; only buildDAGNodes
|
|
5
|
+
* (which builds the ecosystem package graph) is domain-specific and stays local. This package
|
|
6
|
+
* previously vendored a verbatim copy of the generic algorithms — deduplicated here. The nodes
|
|
7
|
+
* carry an `id` (mirroring `name`) so they satisfy client-dag's generic `DAGNode` contract.
|
|
8
|
+
* See documentation/BUGS-2026-07.md (DAG de-dup / H27).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
buildLeveledDAG,
|
|
13
|
+
getTopologicalOrder,
|
|
14
|
+
visualizeDAG,
|
|
15
|
+
executeDAG,
|
|
16
|
+
executeDAGSequential,
|
|
17
|
+
createProcessor,
|
|
18
|
+
filterDAGFromRoot,
|
|
19
|
+
getAncestors,
|
|
20
|
+
getDescendants,
|
|
21
|
+
} from "@procedures/dag";
|
|
22
|
+
|
|
23
|
+
export { buildDAGNodes } from "./builder.js";
|
package/src/git/index.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git reference parser
|
|
3
|
+
*
|
|
4
|
+
* Parses git references from package.json dependencies like:
|
|
5
|
+
* - github:mark1russell7/logger#main
|
|
6
|
+
* - github:mark1russell7/client#v1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { GitRef } from "../types.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Parse a git reference string into its components
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* parseGitRef("github:mark1russell7/logger#main")
|
|
16
|
+
* // { raw: "...", host: "github", owner: "mark1russell7", repo: "logger", ref: "main" }
|
|
17
|
+
*/
|
|
18
|
+
export function parseGitRef(refString: string): GitRef | null {
|
|
19
|
+
// Pattern: host:owner/repo#ref
|
|
20
|
+
// Examples:
|
|
21
|
+
// github:mark1russell7/logger#main
|
|
22
|
+
// gitlab:user/project#develop
|
|
23
|
+
const match = refString.match(/^(\w+):([^/]+)\/([^#]+)#(.+)$/);
|
|
24
|
+
|
|
25
|
+
if (!match) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const [, host, owner, repo, ref] = match;
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
raw: refString,
|
|
33
|
+
host: host!,
|
|
34
|
+
owner: owner!,
|
|
35
|
+
repo: repo!,
|
|
36
|
+
ref: ref!,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Check if a dependency string is a git reference
|
|
42
|
+
*/
|
|
43
|
+
export function isGitRef(dep: string): boolean {
|
|
44
|
+
return /^\w+:[^/]+\/[^#]+#.+$/.test(dep);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Check if a dependency is a mark1russell7 git reference
|
|
49
|
+
*/
|
|
50
|
+
export function isMark1Russell7Ref(dep: string): boolean {
|
|
51
|
+
return dep.includes("mark1russell7/");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Extract mark1russell7 git refs from package.json dependencies
|
|
56
|
+
*/
|
|
57
|
+
export function extractMark1Russell7Deps(
|
|
58
|
+
dependencies: Record<string, string>
|
|
59
|
+
): GitRef[] {
|
|
60
|
+
const refs: GitRef[] = [];
|
|
61
|
+
|
|
62
|
+
for (const [, version] of Object.entries(dependencies)) {
|
|
63
|
+
if (isMark1Russell7Ref(version)) {
|
|
64
|
+
const ref = parseGitRef(version);
|
|
65
|
+
if (ref) {
|
|
66
|
+
refs.push(ref);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return refs;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get the package name from a git ref
|
|
76
|
+
* Uses the repo name, optionally scoped with @mark1russell7/
|
|
77
|
+
*/
|
|
78
|
+
export function getPackageNameFromRef(ref: GitRef): string {
|
|
79
|
+
// For mark1russell7 repos, the package name is usually @mark1russell7/{repo}
|
|
80
|
+
// But some packages like "client" are unscoped
|
|
81
|
+
// We'll need to check the actual package.json to be sure
|
|
82
|
+
return ref.repo;
|
|
83
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @procedures/lib
|
|
3
|
+
*
|
|
4
|
+
* Library management procedures for the workspace - scan, new, audit, rename.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export * from "./module.js";
|
|
8
|
+
|
|
9
|
+
// Re-export types
|
|
10
|
+
export * from "./types.js";
|
|
11
|
+
|
|
12
|
+
// Re-export procedures
|
|
13
|
+
export {
|
|
14
|
+
libScan,
|
|
15
|
+
libRename,
|
|
16
|
+
libNew,
|
|
17
|
+
libAudit,
|
|
18
|
+
} from "./procedures/lib/index.js";
|
|
19
|
+
|
|
20
|
+
// Re-export ecosystem procedures
|
|
21
|
+
export {
|
|
22
|
+
ecosystemProcedures,
|
|
23
|
+
EcosystemProceduresInputSchema,
|
|
24
|
+
} from "./procedures/ecosystem/index.js";
|
|
25
|
+
export type {
|
|
26
|
+
EcosystemProceduresInput,
|
|
27
|
+
EcosystemProceduresOutput,
|
|
28
|
+
ProcedureInfo,
|
|
29
|
+
PackageProcedures,
|
|
30
|
+
} from "./procedures/ecosystem/index.js";
|
|
31
|
+
|
|
32
|
+
// Re-export DAG utilities (ecosystem-specific)
|
|
33
|
+
export {
|
|
34
|
+
buildDAGNodes,
|
|
35
|
+
filterDAGFromRoot,
|
|
36
|
+
getAncestors,
|
|
37
|
+
getDescendants,
|
|
38
|
+
buildLeveledDAG,
|
|
39
|
+
getTopologicalOrder,
|
|
40
|
+
visualizeDAG,
|
|
41
|
+
executeDAG,
|
|
42
|
+
executeDAGSequential,
|
|
43
|
+
createProcessor,
|
|
44
|
+
} from "./dag/index.js";
|
|
45
|
+
|
|
46
|
+
// Re-export git utilities
|
|
47
|
+
export {
|
|
48
|
+
parseGitRef,
|
|
49
|
+
isGitRef,
|
|
50
|
+
isMark1Russell7Ref,
|
|
51
|
+
extractMark1Russell7Deps,
|
|
52
|
+
getPackageNameFromRef,
|
|
53
|
+
} from "./git/index.js";
|
|
54
|
+
|
|
55
|
+
// The global flags of the mark CLI (also at "@procedures/lib/cli-flags", with no side effects)
|
|
56
|
+
export { CLI_GLOBAL_FLAGS, findGlobalFlag, type CliGlobalFlag } from "./cli-flags.js";
|