agentloom 0.1.4 → 0.1.6

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.
@@ -29,6 +29,13 @@ export function readLockfile(paths) {
29
29
  selectedSourceMcpServers: Array.isArray(entry.selectedSourceMcpServers)
30
30
  ? entry.selectedSourceMcpServers
31
31
  : undefined,
32
+ importedRules: Array.isArray(entry.importedRules)
33
+ ? entry.importedRules
34
+ : [],
35
+ selectedSourceRules: Array.isArray(entry.selectedSourceRules)
36
+ ? entry.selectedSourceRules
37
+ : undefined,
38
+ ruleRenameMap: normalizeRenameMap(entry.ruleRenameMap),
32
39
  importedSkills: Array.isArray(entry.importedSkills)
33
40
  ? entry.importedSkills
34
41
  : [],
@@ -79,6 +86,7 @@ export function upsertLockEntry(lockfile, entry) {
79
86
  sameRequestedAgents(item.requestedAgents, entry.requestedAgents) &&
80
87
  sameSelection(item.selectedSourceCommands, entry.selectedSourceCommands) &&
81
88
  sameSelection(item.selectedSourceMcpServers, entry.selectedSourceMcpServers) &&
89
+ sameSelection(item.selectedSourceRules, entry.selectedSourceRules) &&
82
90
  sameSelection(item.selectedSourceSkills, entry.selectedSourceSkills) &&
83
91
  sameSelection(item.skillsProviders, entry.skillsProviders));
84
92
  if (index >= 0) {
@@ -1,8 +1,10 @@
1
- import { readJsonIfExists, writeJsonAtomic } from "./fs.js";
1
+ import path from "node:path";
2
+ import { readJsonIfExists, toPosixPath, writeJsonAtomic } from "./fs.js";
2
3
  const EMPTY_MANIFEST = {
3
4
  version: 1,
4
5
  generatedFiles: [],
5
6
  };
7
+ const ENTITY_TYPES = ["agent", "command", "mcp", "rule", "skill"];
6
8
  export function readManifest(paths) {
7
9
  const manifest = readJsonIfExists(paths.manifestPath);
8
10
  if (!manifest ||
@@ -10,14 +12,129 @@ export function readManifest(paths) {
10
12
  !Array.isArray(manifest.generatedFiles)) {
11
13
  return { ...EMPTY_MANIFEST };
12
14
  }
13
- const generatedByEntity = manifest.generatedByEntity && typeof manifest.generatedByEntity === "object"
14
- ? manifest.generatedByEntity
15
- : undefined;
15
+ const generatedByEntity = normalizeGeneratedByEntityForRuntime(paths, manifest.generatedByEntity);
16
+ const codex = normalizeCodexMetadata(manifest.codex);
16
17
  return {
17
- ...manifest,
18
+ version: 1,
19
+ generatedFiles: normalizePathListForRuntime(paths, manifest.generatedFiles),
18
20
  generatedByEntity,
21
+ codex,
19
22
  };
20
23
  }
21
24
  export function writeManifest(paths, manifest) {
22
- writeJsonAtomic(paths.manifestPath, manifest);
25
+ const generatedByEntity = normalizeGeneratedByEntityForDisk(paths, manifest.generatedByEntity);
26
+ const codex = normalizeCodexMetadata(manifest.codex);
27
+ writeJsonAtomic(paths.manifestPath, {
28
+ version: 1,
29
+ generatedFiles: normalizePathListForDisk(paths, manifest.generatedFiles),
30
+ generatedByEntity,
31
+ codex,
32
+ });
33
+ }
34
+ function normalizeGeneratedByEntityForRuntime(paths, generatedByEntity) {
35
+ if (!generatedByEntity || typeof generatedByEntity !== "object") {
36
+ return undefined;
37
+ }
38
+ const normalized = {};
39
+ for (const entity of ENTITY_TYPES) {
40
+ const values = normalizePathListForRuntime(paths, generatedByEntity[entity]);
41
+ if (values.length === 0)
42
+ continue;
43
+ normalized[entity] = values;
44
+ }
45
+ return Object.keys(normalized).length > 0 ? normalized : {};
46
+ }
47
+ function normalizeGeneratedByEntityForDisk(paths, generatedByEntity) {
48
+ if (!generatedByEntity || typeof generatedByEntity !== "object") {
49
+ return undefined;
50
+ }
51
+ const normalized = {};
52
+ for (const entity of ENTITY_TYPES) {
53
+ const values = normalizePathListForDisk(paths, generatedByEntity[entity]);
54
+ if (values.length === 0)
55
+ continue;
56
+ normalized[entity] = values;
57
+ }
58
+ return Object.keys(normalized).length > 0 ? normalized : {};
59
+ }
60
+ function normalizePathListForRuntime(paths, value) {
61
+ if (!Array.isArray(value))
62
+ return [];
63
+ const normalized = value
64
+ .filter((item) => typeof item === "string")
65
+ .map((item) => resolveManifestPathForRuntime(paths, item))
66
+ .filter((item) => item.length > 0);
67
+ return [...new Set(normalized)].sort();
68
+ }
69
+ function normalizePathListForDisk(paths, value) {
70
+ if (!Array.isArray(value))
71
+ return [];
72
+ const normalized = value
73
+ .filter((item) => typeof item === "string")
74
+ .map((item) => resolveManifestPathForDisk(paths, item))
75
+ .filter((item) => item.length > 0);
76
+ return [...new Set(normalized)].sort();
77
+ }
78
+ function resolveManifestPathForRuntime(paths, filePath) {
79
+ const normalized = filePath.trim();
80
+ if (!normalized)
81
+ return "";
82
+ if (normalized === "~") {
83
+ return paths.homeDir;
84
+ }
85
+ if (normalized.startsWith("~/")) {
86
+ return path.resolve(paths.homeDir, normalized.slice(2));
87
+ }
88
+ if (path.isAbsolute(normalized)) {
89
+ return path.normalize(normalized);
90
+ }
91
+ return path.resolve(paths.workspaceRoot, normalized);
92
+ }
93
+ function resolveManifestPathForDisk(paths, filePath) {
94
+ const normalized = filePath.trim();
95
+ if (!normalized)
96
+ return "";
97
+ if (!path.isAbsolute(normalized)) {
98
+ return toPosixPath(normalized);
99
+ }
100
+ const absolutePath = path.normalize(normalized);
101
+ if (paths.scope === "global") {
102
+ if (isSubpath(paths.homeDir, absolutePath)) {
103
+ const relativePath = path.relative(paths.homeDir, absolutePath);
104
+ return relativePath ? `~/${toPosixPath(relativePath)}` : "~";
105
+ }
106
+ return toPosixPath(absolutePath);
107
+ }
108
+ if (isSubpath(paths.workspaceRoot, absolutePath)) {
109
+ const relativePath = path.relative(paths.workspaceRoot, absolutePath);
110
+ return toPosixPath(relativePath || ".");
111
+ }
112
+ if (isSubpath(paths.homeDir, absolutePath)) {
113
+ const relativePath = path.relative(paths.homeDir, absolutePath);
114
+ return relativePath ? `~/${toPosixPath(relativePath)}` : "~";
115
+ }
116
+ return toPosixPath(absolutePath);
117
+ }
118
+ function isSubpath(rootPath, candidatePath) {
119
+ const relative = path.relative(rootPath, candidatePath);
120
+ return (relative === "" ||
121
+ (!relative.startsWith("..") && !path.isAbsolute(relative)));
122
+ }
123
+ function normalizeCodexMetadata(codex) {
124
+ if (!codex || typeof codex !== "object")
125
+ return undefined;
126
+ const roles = Array.isArray(codex.roles)
127
+ ? [...new Set(codex.roles.filter((item) => !!item))].sort()
128
+ : undefined;
129
+ const mcpServers = Array.isArray(codex.mcpServers)
130
+ ? [
131
+ ...new Set(codex.mcpServers.filter((item) => !!item)),
132
+ ].sort()
133
+ : undefined;
134
+ if (!roles && !mcpServers)
135
+ return undefined;
136
+ return {
137
+ roles,
138
+ mcpServers,
139
+ };
23
140
  }