@opum-ai/lore 0.1.0 → 0.1.1
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 +33 -22
- package/bin/lore.cjs +35 -7
- package/package.json +17 -17
- package/src/adapters/backlog.ts +0 -1084
- package/src/adapters/git.ts +0 -221
- package/src/cli.ts +0 -667
- package/src/commands/agent.ts +0 -301
- package/src/commands/agents.ts +0 -302
- package/src/commands/args.ts +0 -209
- package/src/commands/changed.ts +0 -70
- package/src/commands/check.ts +0 -1031
- package/src/commands/codex-bridge.ts +0 -49
- package/src/commands/concurrency.ts +0 -48
- package/src/commands/context.ts +0 -292
- package/src/commands/discover.ts +0 -89
- package/src/commands/explorer.ts +0 -253
- package/src/commands/export.ts +0 -93
- package/src/commands/fswrite.ts +0 -928
- package/src/commands/graph.ts +0 -291
- package/src/commands/help.ts +0 -151
- package/src/commands/impact.ts +0 -59
- package/src/commands/init.ts +0 -583
- package/src/commands/instructions.ts +0 -91
- package/src/commands/link.ts +0 -929
- package/src/commands/new.ts +0 -476
- package/src/commands/orphans.ts +0 -457
- package/src/commands/path.ts +0 -67
- package/src/commands/provenance.ts +0 -68
- package/src/commands/query.ts +0 -312
- package/src/commands/reconcile-shared.ts +0 -280
- package/src/commands/rename.ts +0 -585
- package/src/commands/replace.ts +0 -320
- package/src/commands/scaffold.ts +0 -346
- package/src/commands/schema.ts +0 -293
- package/src/commands/snapshot.ts +0 -130
- package/src/commands/supersede.ts +0 -400
- package/src/commands/sync.ts +0 -371
- package/src/commands/tasks.ts +0 -271
- package/src/commands/traversal.ts +0 -151
- package/src/commands/validate.ts +0 -226
- package/src/config.ts +0 -598
- package/src/core/agent-bridge.ts +0 -287
- package/src/core/agent-context.ts +0 -498
- package/src/core/agent-profile.ts +0 -447
- package/src/core/bundle.ts +0 -893
- package/src/core/check.ts +0 -853
- package/src/core/codex-bridge.ts +0 -100
- package/src/core/concept.ts +0 -597
- package/src/core/consumer-scaffold.ts +0 -433
- package/src/core/context.ts +0 -271
- package/src/core/explorer-contract.ts +0 -441
- package/src/core/explorer-qualification.ts +0 -58
- package/src/core/explorer.ts +0 -518
- package/src/core/finding.ts +0 -31
- package/src/core/graph.ts +0 -201
- package/src/core/indexes.ts +0 -436
- package/src/core/instructions.ts +0 -209
- package/src/core/ladybug-driver.ts +0 -1795
- package/src/core/ladybug-lifecycle.ts +0 -1178
- package/src/core/ladybug-native.ts +0 -95
- package/src/core/ladybug-source.ts +0 -667
- package/src/core/links.ts +0 -681
- package/src/core/log.ts +0 -253
- package/src/core/managed-block.ts +0 -540
- package/src/core/manifest.ts +0 -718
- package/src/core/order.ts +0 -13
- package/src/core/profile.ts +0 -1007
- package/src/core/projection.ts +0 -195
- package/src/core/query.ts +0 -542
- package/src/core/reconcile.ts +0 -236
- package/src/core/replace.ts +0 -419
- package/src/core/retrieval.ts +0 -213
- package/src/core/rewrite.ts +0 -940
- package/src/core/scaffold.ts +0 -255
- package/src/core/schema.ts +0 -366
- package/src/core/snapshot-runtime.ts +0 -52
- package/src/core/snapshot-store.ts +0 -287
- package/src/core/snapshot.ts +0 -711
- package/src/core/template.ts +0 -429
- package/src/core/traversal.ts +0 -487
- package/src/core/validate.ts +0 -517
- package/src/core/workspace-contract.ts +0 -473
- package/src/core/workspace-projection.ts +0 -365
- package/src/core/workspace-retrieval.ts +0 -196
- package/src/core/workspace-source.ts +0 -174
- package/src/errors.ts +0 -697
- package/src/meta.ts +0 -7
- package/src/output.ts +0 -589
- package/src/scripts/upstream-backlog-watch.ts +0 -288
- package/src/state.ts +0 -390
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
/** Explicit workspace manifest and repository resolution boundary. */
|
|
2
|
-
|
|
3
|
-
import { lstatSync, readFileSync, realpathSync, type Stats } from "node:fs";
|
|
4
|
-
import { dirname, isAbsolute, resolve } from "node:path";
|
|
5
|
-
import type { BacklogAdapter } from "../adapters/backlog";
|
|
6
|
-
import { resolveHeadSha } from "../adapters/git";
|
|
7
|
-
import { LoreError, WarningCollector } from "../errors";
|
|
8
|
-
import { EXPECTED_LADYBUG_STORAGE_VERSION, EXPECTED_LADYBUG_VERSION } from "./ladybug-native";
|
|
9
|
-
import { type LadybugProjectionSource, loadLadybugProjectionSource } from "./ladybug-source";
|
|
10
|
-
import { parseWorkspaceManifest, type WorkspaceManifest } from "./workspace-contract";
|
|
11
|
-
import { buildWorkspaceProjection, type WorkspaceMemberSource, type WorkspaceProjection } from "./workspace-projection";
|
|
12
|
-
|
|
13
|
-
export interface LoadWorkspaceProjectionOptions {
|
|
14
|
-
readonly root: string;
|
|
15
|
-
readonly manifestPath: string;
|
|
16
|
-
readonly warnings?: WarningCollector;
|
|
17
|
-
readonly adapterForRoot?: (root: string) => BacklogAdapter | undefined;
|
|
18
|
-
readonly resolveGitCommit?: (root: string) => string | null;
|
|
19
|
-
readonly resolveGitRef?: (root: string) => string | null;
|
|
20
|
-
readonly loadMemberSource?: (member: WorkspaceMemberSourceRequest) => Promise<LadybugProjectionSource>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface WorkspaceMemberSourceRequest {
|
|
24
|
-
readonly memberId: string;
|
|
25
|
-
readonly root: string;
|
|
26
|
-
readonly warnings: WarningCollector;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface LoadedWorkspaceProjection {
|
|
30
|
-
readonly manifestPath: string;
|
|
31
|
-
readonly manifest: WorkspaceManifest;
|
|
32
|
-
readonly members: readonly WorkspaceMemberSource[];
|
|
33
|
-
readonly projection: WorkspaceProjection;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Read one explicit manifest and load every declared repository as one complete candidate. */
|
|
37
|
-
export async function loadWorkspaceProjection(
|
|
38
|
-
options: LoadWorkspaceProjectionOptions,
|
|
39
|
-
): Promise<LoadedWorkspaceProjection> {
|
|
40
|
-
const manifestPath = resolveWorkspaceManifestPath(options.root, options.manifestPath);
|
|
41
|
-
const manifest = readWorkspaceManifest(manifestPath);
|
|
42
|
-
const members: WorkspaceMemberSource[] = [];
|
|
43
|
-
for (const member of manifest.members) {
|
|
44
|
-
const root = resolveMemberRoot(manifestPath, member.locator, member.memberId);
|
|
45
|
-
let actualRef: string | null;
|
|
46
|
-
try {
|
|
47
|
-
actualRef = (options.resolveGitRef ?? resolveCurrentGitRef)(root);
|
|
48
|
-
} catch (cause) {
|
|
49
|
-
throw memberValidationFailure(member.memberId, cause);
|
|
50
|
-
}
|
|
51
|
-
if (member.expectedRef !== null && actualRef !== member.expectedRef) {
|
|
52
|
-
throw new LoreError(
|
|
53
|
-
"conflict",
|
|
54
|
-
`workspace member ${member.memberId} is at ${actualRef ?? "a detached HEAD"}, expected ${member.expectedRef}`,
|
|
55
|
-
"check out the explicit expected ref or update the manifest before retrying",
|
|
56
|
-
{ memberId: member.memberId, expectedRef: member.expectedRef, actualRef },
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
const memberWarnings = new WarningCollector();
|
|
60
|
-
let source: LadybugProjectionSource;
|
|
61
|
-
try {
|
|
62
|
-
source =
|
|
63
|
-
options.loadMemberSource === undefined
|
|
64
|
-
? await loadLadybugProjectionSource({
|
|
65
|
-
root,
|
|
66
|
-
ladybugVersion: EXPECTED_LADYBUG_VERSION,
|
|
67
|
-
ladybugStorageVersion: EXPECTED_LADYBUG_STORAGE_VERSION,
|
|
68
|
-
adapter: options.adapterForRoot?.(root),
|
|
69
|
-
resolveGitCommit: options.resolveGitCommit ?? resolveHeadSha,
|
|
70
|
-
warnings: memberWarnings,
|
|
71
|
-
})
|
|
72
|
-
: await options.loadMemberSource({ memberId: member.memberId, root, warnings: memberWarnings });
|
|
73
|
-
} catch (cause) {
|
|
74
|
-
throw memberValidationFailure(member.memberId, cause);
|
|
75
|
-
}
|
|
76
|
-
for (const warning of memberWarnings.list()) {
|
|
77
|
-
options.warnings?.add(`[${member.memberId}] ${warning}`);
|
|
78
|
-
}
|
|
79
|
-
members.push({ memberId: member.memberId, root, source });
|
|
80
|
-
}
|
|
81
|
-
return { manifestPath, manifest, members, projection: buildWorkspaceProjection(manifest, members) };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function resolveWorkspaceManifestPath(root: string, manifestPath: string): string {
|
|
85
|
-
if (manifestPath.trim() === "") {
|
|
86
|
-
throw new LoreError(
|
|
87
|
-
"usage",
|
|
88
|
-
"--workspace needs a manifest path",
|
|
89
|
-
"pass an explicit lore-workspace-manifest/1 JSON file",
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
const absolute = resolve(root, manifestPath);
|
|
93
|
-
const stat = safeLstat(absolute, "workspace manifest");
|
|
94
|
-
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
95
|
-
throw new LoreError("denied", "workspace manifest must be a real regular file, not a symlink");
|
|
96
|
-
}
|
|
97
|
-
return realpathSync(absolute);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function readWorkspaceManifest(path: string): WorkspaceManifest {
|
|
101
|
-
let value: unknown;
|
|
102
|
-
try {
|
|
103
|
-
value = JSON.parse(readFileSync(path, "utf8"));
|
|
104
|
-
} catch (cause) {
|
|
105
|
-
if (cause instanceof SyntaxError) {
|
|
106
|
-
throw new LoreError(
|
|
107
|
-
"validation",
|
|
108
|
-
`workspace manifest is not valid JSON: ${cause.message}`,
|
|
109
|
-
"fix the manifest and retry",
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
const code = (cause as NodeJS.ErrnoException).code;
|
|
113
|
-
if (code === "EACCES" || code === "EPERM") {
|
|
114
|
-
throw new LoreError("denied", "cannot read workspace manifest", "check the explicit manifest permissions");
|
|
115
|
-
}
|
|
116
|
-
if (code === "ENOENT") {
|
|
117
|
-
throw new LoreError("not_found", "cannot find workspace manifest", "check the explicit manifest path");
|
|
118
|
-
}
|
|
119
|
-
throw new LoreError("validation", "workspace manifest could not be read", "check the explicit manifest and retry");
|
|
120
|
-
}
|
|
121
|
-
try {
|
|
122
|
-
return parseWorkspaceManifest(value);
|
|
123
|
-
} catch (cause) {
|
|
124
|
-
throw new LoreError(
|
|
125
|
-
"validation",
|
|
126
|
-
cause instanceof Error ? cause.message : "workspace manifest is invalid",
|
|
127
|
-
"fix the explicit lore-workspace-manifest/1 file and retry",
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function resolveMemberRoot(manifestPath: string, locator: string, memberId: string): string {
|
|
133
|
-
const candidate = isAbsolute(locator) ? resolve(locator) : resolve(dirname(manifestPath), locator);
|
|
134
|
-
const stat = safeLstat(candidate, `workspace member ${memberId}`);
|
|
135
|
-
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
136
|
-
throw new LoreError(
|
|
137
|
-
"denied",
|
|
138
|
-
`workspace member ${memberId} must resolve to a real repository directory, not a symlink`,
|
|
139
|
-
"replace the locator with an explicit real checkout path",
|
|
140
|
-
{ memberId },
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
return realpathSync(candidate);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function safeLstat(path: string, label: string): Stats {
|
|
147
|
-
try {
|
|
148
|
-
return lstatSync(path) as Stats;
|
|
149
|
-
} catch (cause) {
|
|
150
|
-
const code = (cause as NodeJS.ErrnoException).code;
|
|
151
|
-
if (code === "EACCES" || code === "EPERM") {
|
|
152
|
-
throw new LoreError("denied", `cannot read ${label}`, "check the explicit path permissions");
|
|
153
|
-
}
|
|
154
|
-
throw new LoreError("not_found", `cannot find ${label}`, "check the explicit path exists");
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function memberValidationFailure(memberId: string, cause: unknown): LoreError {
|
|
159
|
-
const type = cause instanceof LoreError ? cause.type : "validation";
|
|
160
|
-
return new LoreError(
|
|
161
|
-
type,
|
|
162
|
-
`workspace member ${memberId} could not be validated`,
|
|
163
|
-
"inspect that explicitly selected repository and retry",
|
|
164
|
-
{ memberId },
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function resolveCurrentGitRef(root: string): string | null {
|
|
169
|
-
const result = Bun.spawnSync(["git", "symbolic-ref", "-q", "HEAD"], { cwd: root, stdout: "pipe", stderr: "pipe" });
|
|
170
|
-
if (result.exitCode === 0) return result.stdout.toString("utf8").trim();
|
|
171
|
-
// Prove this is still a valid repository/detached HEAD rather than hiding a Git error.
|
|
172
|
-
resolveHeadSha(root);
|
|
173
|
-
return null;
|
|
174
|
-
}
|