Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion scripts/assemble.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ function loadArtifacts(dirName) {
}));
}

function loadAppArtifacts(dirName) {
const dirPath = path.join(ROOT, dirName);
if (!fs.existsSync(dirPath)) {
return [];
}

return fs
.readdirSync(dirPath, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => ({
id: entry.name,
data: readJson(path.join(dirPath, entry.name, "package.json")),
}));
}

// Read manifest
const manifest = readJson(path.join(ROOT, "manifest.json"));

Expand All @@ -46,7 +61,7 @@ const bundle = {
agents: loadArtifacts("agents"),
projects: loadArtifacts("projects"),
automations: loadArtifacts("automations"),
apps: loadArtifacts("apps"),
apps: loadAppArtifacts("apps"),
assembledAt: new Date().toISOString(),
};

Expand Down
24 changes: 22 additions & 2 deletions scripts/summary.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import path from "node:path";

const ROOT = process.cwd();

const BUNDLE_DIRS = ["agents", "apps", "automations", "projects"];
const JSON_DIRS = ["agents", "automations", "projects"];
const APP_DIR = "apps";

function listJsonFiles(dirName) {
const dirPath = path.join(ROOT, dirName);
Expand All @@ -18,6 +19,19 @@ function listJsonFiles(dirName) {
.sort();
}

function listAppDirs(dirName) {
const dirPath = path.join(ROOT, dirName);
if (!fs.existsSync(dirPath)) {
return [];
}

return fs
.readdirSync(dirPath, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)
.sort();
}

function readJson(filePath) {
const raw = fs.readFileSync(filePath, "utf8");
return JSON.parse(raw);
Expand All @@ -41,7 +55,7 @@ console.log(`Name: ${manifest.name ?? "Unknown"}`);
console.log(`Space ID: ${manifest.spaceId ?? "Unknown"}`);
console.log(`Version: ${manifest.version ?? "Unknown"}`);

for (const dirName of BUNDLE_DIRS) {
for (const dirName of JSON_DIRS) {
const files = listJsonFiles(dirName);
printHeader(`${dirName} (${files.length})`);

Expand All @@ -51,4 +65,10 @@ for (const dirName of BUNDLE_DIRS) {
}
}

const appDirs = listAppDirs(APP_DIR);
printHeader(`${APP_DIR} (${appDirs.length})`);
for (const name of appDirs) {
console.log(`- ${name}`);
}

console.log("\nSummary completed.");
43 changes: 34 additions & 9 deletions scripts/validate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import path from "node:path";

const ROOT = process.cwd();

const REQUIRED_DIRS = ["agents", "apps", "automations", "projects"];
const JSON_DIRS = ["agents", "automations", "projects"];
const APP_DIR = "apps";

const errors = [];

Expand Down Expand Up @@ -46,6 +47,25 @@ function listJsonFiles(dirName) {
return files;
}

function listAppDirs(dirName) {
const dirPath = path.join(ROOT, dirName);
if (!fs.existsSync(dirPath)) {
fail(`Missing directory: ${dirName}`);
return [];
}

const dirs = fs
.readdirSync(dirPath, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => path.join(dirPath, entry.name));

if (dirs.length === 0) {
fail(`Directory has no app subdirectories: ${dirName}`);
}

return dirs;
}

function validateManifest() {
const filePath = path.join(ROOT, "manifest.json");
if (!fs.existsSync(filePath)) {
Expand Down Expand Up @@ -87,17 +107,21 @@ function validateAgents() {
}

function validateApps() {
for (const filePath of listJsonFiles("apps")) {
const data = readJson(filePath);
for (const appDir of listAppDirs(APP_DIR)) {
const pkgPath = path.join(appDir, "package.json");
const rel = path.relative(ROOT, appDir);

if (!fs.existsSync(pkgPath)) {
fail(`${rel}: missing package.json`);
continue;
}

const data = readJson(pkgPath);
if (data == null) {
continue;
}

const rel = path.relative(ROOT, filePath);
assert(
typeof data.src === "object" && data.src != null,
`${rel}: src object is required`,
);
assert(typeof data.name === "string", `${rel}/package.json: name must be a string`);
}
}

Expand Down Expand Up @@ -138,9 +162,10 @@ function validateProjects() {

validateManifest();

for (const dirName of REQUIRED_DIRS) {
for (const dirName of JSON_DIRS) {
listJsonFiles(dirName);
}
listAppDirs(APP_DIR);

validateAgents();
validateApps();
Expand Down
Loading