@warpgogol/forge 0.10.0 → 0.12.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.
Files changed (49) hide show
  1. package/dist/bin/cli.js +0 -0
  2. package/dist/os/core/core.module.d.ts.map +1 -1
  3. package/dist/os/core/core.module.js +129 -2
  4. package/dist/os/core/core.module.js.map +1 -1
  5. package/dist/os/core/handlers/assets-check.d.ts +19 -0
  6. package/dist/os/core/handlers/assets-check.d.ts.map +1 -0
  7. package/dist/os/core/handlers/assets-check.js +91 -0
  8. package/dist/os/core/handlers/assets-check.js.map +1 -0
  9. package/dist/os/core/handlers/assets-helpers.d.ts +28 -0
  10. package/dist/os/core/handlers/assets-helpers.d.ts.map +1 -0
  11. package/dist/os/core/handlers/assets-helpers.js +127 -0
  12. package/dist/os/core/handlers/assets-helpers.js.map +1 -0
  13. package/dist/os/core/handlers/assets-list.d.ts +9 -0
  14. package/dist/os/core/handlers/assets-list.d.ts.map +1 -0
  15. package/dist/os/core/handlers/assets-list.js +76 -0
  16. package/dist/os/core/handlers/assets-list.js.map +1 -0
  17. package/dist/os/core/handlers/determinism-check.d.ts +20 -0
  18. package/dist/os/core/handlers/determinism-check.d.ts.map +1 -0
  19. package/dist/os/core/handlers/determinism-check.js +296 -0
  20. package/dist/os/core/handlers/determinism-check.js.map +1 -0
  21. package/dist/os/core/handlers/release-prepare.d.ts +25 -0
  22. package/dist/os/core/handlers/release-prepare.d.ts.map +1 -0
  23. package/dist/os/core/handlers/release-prepare.js +226 -0
  24. package/dist/os/core/handlers/release-prepare.js.map +1 -0
  25. package/dist/os/core/handlers/release-publish.d.ts +13 -0
  26. package/dist/os/core/handlers/release-publish.d.ts.map +1 -0
  27. package/dist/os/core/handlers/release-publish.js +173 -0
  28. package/dist/os/core/handlers/release-publish.js.map +1 -0
  29. package/dist/os/core/handlers/validate.d.ts +11 -0
  30. package/dist/os/core/handlers/validate.d.ts.map +1 -1
  31. package/dist/os/core/handlers/validate.js +100 -12
  32. package/dist/os/core/handlers/validate.js.map +1 -1
  33. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  34. package/dist/src/onboarding/doctor.js +10 -2
  35. package/dist/src/onboarding/doctor.js.map +1 -1
  36. package/dist/src/onboarding/nested-agents-generate.d.ts +2 -0
  37. package/dist/src/onboarding/nested-agents-generate.d.ts.map +1 -1
  38. package/dist/src/onboarding/nested-agents-generate.js +1 -1
  39. package/dist/src/onboarding/nested-agents-generate.js.map +1 -1
  40. package/dist/src/profiles/profile-schema.d.ts +85 -0
  41. package/dist/src/profiles/profile-schema.d.ts.map +1 -1
  42. package/dist/src/profiles/profile-schema.js +34 -0
  43. package/dist/src/profiles/profile-schema.js.map +1 -1
  44. package/dist/src/profiles/stack-profile.d.ts +28 -0
  45. package/dist/src/profiles/stack-profile.d.ts.map +1 -1
  46. package/dist/src/profiles/stack-profile.js +6 -0
  47. package/dist/src/profiles/stack-profile.js.map +1 -1
  48. package/package.json +165 -69
  49. package/profiles/editframe-html.yaml +18 -3
@@ -0,0 +1,173 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>forge.release.publish — publish a prepared release to the declared target (local, R2, S3). Supports --dry-run, --json, --profile.</purpose>
4
+ <non-goals>
5
+ <item>Do not implement release preparation — that lives in release-prepare.ts.</item>
6
+ <item>Do not import from @warpgogol/* in autonomous modules — os/core/ may import from @warpgogol/*.</item>
7
+ </non-goals>
8
+ </MODULE_CONTRACT>
9
+ <CHANGE_SUMMARY>
10
+ <item>RFC-0680: initial forge.release.publish handler with local/r2/s3 targets, --dry-run, env var validation.</item>
11
+ <item>RFC-0680 review fix: remove unused readdir import (A-1).</item>
12
+ <item>RFC-0680 review fix: add S3_ENDPOINT to required env vars (G-1).</item>
13
+ <item>RFC-0680 review fix: add 30s request timeout on S3Client (G-2).</item>
14
+ </CHANGE_SUMMARY>
15
+ */
16
+ import { readFile, copyFile, mkdir } from "node:fs/promises";
17
+ import { join, basename } from "node:path";
18
+ import { resolveActiveProfile, resolveLifecycleFlags } from "./profile-resolve.js";
19
+ function getRequiredEnvVars(target) {
20
+ if (target === "r2") {
21
+ return ["R2_ACCOUNT_ID", "R2_ACCESS_KEY_ID", "R2_SECRET_ACCESS_KEY"];
22
+ }
23
+ if (target === "s3") {
24
+ return ["S3_BUCKET", "S3_ACCESS_KEY_ID", "S3_SECRET_ACCESS_KEY", "S3_ENDPOINT"];
25
+ }
26
+ return [];
27
+ }
28
+ export async function runReleasePublish(input, context) {
29
+ const { workspaceRoot, logger } = context;
30
+ const { dryRun, profileIdOverride } = resolveLifecycleFlags(input, context);
31
+ const resolved = resolveActiveProfile(workspaceRoot, context.forgeRoot, profileIdOverride);
32
+ if (!resolved) {
33
+ return {
34
+ data: {
35
+ command: "forge.release.publish",
36
+ profileId: "",
37
+ target: "",
38
+ publishedFiles: [],
39
+ manifestPath: "",
40
+ },
41
+ exitCode: 1,
42
+ summary: "No active profile found. Set `profile` in forge.yaml or use --profile <id>.",
43
+ nextSteps: [{ action: "Set profile in forge.yaml or use --profile <id>", kind: "required" }],
44
+ };
45
+ }
46
+ const { profile } = resolved;
47
+ if (!profile.release) {
48
+ return {
49
+ data: {
50
+ command: "forge.release.publish",
51
+ profileId: profile.id,
52
+ target: "",
53
+ publishedFiles: [],
54
+ manifestPath: "",
55
+ },
56
+ exitCode: 1,
57
+ summary: `Profile ${profile.id} does not declare a release configuration.`,
58
+ };
59
+ }
60
+ const releaseConfig = profile.release;
61
+ const releaseDir = join(workspaceRoot, releaseConfig.outputDir);
62
+ const manifestPath = join(releaseDir, releaseConfig.manifestName);
63
+ let manifest;
64
+ try {
65
+ const raw = await readFile(manifestPath, "utf8");
66
+ manifest = JSON.parse(raw);
67
+ }
68
+ catch {
69
+ return {
70
+ data: {
71
+ command: "forge.release.publish",
72
+ profileId: profile.id,
73
+ target: releaseConfig.target,
74
+ publishedFiles: [],
75
+ manifestPath,
76
+ },
77
+ exitCode: 1,
78
+ summary: `No release manifest found at ${manifestPath}. Run \`forge release prepare\` first.`,
79
+ };
80
+ }
81
+ const target = releaseConfig.target;
82
+ const requiredVars = getRequiredEnvVars(target);
83
+ const missingVars = requiredVars.filter((v) => !process.env[v]);
84
+ if (missingVars.length > 0) {
85
+ return {
86
+ data: {
87
+ command: "forge.release.publish",
88
+ profileId: profile.id,
89
+ target,
90
+ publishedFiles: [],
91
+ manifestPath,
92
+ },
93
+ exitCode: 1,
94
+ summary: `Missing required environment variables: ${missingVars.join(", ")}`,
95
+ };
96
+ }
97
+ const filesToPublish = [];
98
+ for (const a of manifest.artifacts) {
99
+ filesToPublish.push(join(releaseDir, basename(a.path)));
100
+ }
101
+ filesToPublish.push(manifestPath);
102
+ if (dryRun) {
103
+ logger.info(`[dry-run] forge.release.publish — profile: ${profile.id}`);
104
+ logger.info(` target: ${target}`);
105
+ for (const f of filesToPublish) {
106
+ logger.info(` file: ${f}`);
107
+ }
108
+ return {
109
+ data: {
110
+ command: "forge.release.publish",
111
+ profileId: profile.id,
112
+ target,
113
+ publishedFiles: filesToPublish.map((f) => ({
114
+ path: f,
115
+ targetPath: target === "local"
116
+ ? join(releaseDir, "published", basename(f))
117
+ : `${target}://${basename(f)}`,
118
+ })),
119
+ manifestPath,
120
+ },
121
+ summary: `[dry-run] Would publish ${filesToPublish.length} file(s) to ${target}`,
122
+ };
123
+ }
124
+ const publishedFiles = [];
125
+ if (target === "local") {
126
+ const publishedDir = join(releaseDir, "published");
127
+ await mkdir(publishedDir, { recursive: true });
128
+ for (const f of filesToPublish) {
129
+ const dst = join(publishedDir, basename(f));
130
+ await copyFile(f, dst);
131
+ publishedFiles.push({ path: f, targetPath: dst });
132
+ }
133
+ }
134
+ else if (target === "r2" || target === "s3") {
135
+ const { S3Client, PutObjectCommand } = await import("@aws-sdk/client-s3");
136
+ const { readFile: fsReadFile } = await import("node:fs/promises");
137
+ const endpoint = target === "r2"
138
+ ? `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`
139
+ : process.env.S3_ENDPOINT;
140
+ const bucket = target === "r2" ? releaseConfig.r2?.bucket : process.env.S3_BUCKET;
141
+ const accessKeyId = target === "r2" ? process.env.R2_ACCESS_KEY_ID : process.env.S3_ACCESS_KEY_ID;
142
+ const secretAccessKey = target === "r2" ? process.env.R2_SECRET_ACCESS_KEY : process.env.S3_SECRET_ACCESS_KEY;
143
+ const prefix = target === "r2" ? (releaseConfig.r2?.prefix ?? "") : "";
144
+ const client = new S3Client({
145
+ endpoint,
146
+ region: "auto",
147
+ credentials: { accessKeyId: accessKeyId, secretAccessKey: secretAccessKey },
148
+ requestHandler: { requestTimeout: 30_000 },
149
+ });
150
+ for (const f of filesToPublish) {
151
+ const key = prefix ? `${prefix}/${basename(f)}` : basename(f);
152
+ const body = await fsReadFile(f);
153
+ await client.send(new PutObjectCommand({
154
+ Bucket: bucket,
155
+ Key: key,
156
+ Body: body,
157
+ }));
158
+ publishedFiles.push({ path: f, targetPath: `${target}://${bucket}/${key}` });
159
+ }
160
+ }
161
+ logger.success(` Published ${publishedFiles.length} file(s) to ${target}`);
162
+ return {
163
+ data: {
164
+ command: "forge.release.publish",
165
+ profileId: profile.id,
166
+ target,
167
+ publishedFiles,
168
+ manifestPath,
169
+ },
170
+ summary: `Published ${publishedFiles.length} file(s) to ${target}`,
171
+ };
172
+ }
173
+ //# sourceMappingURL=release-publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-publish.js","sourceRoot":"","sources":["../../../../os/core/handlers/release-publish.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,17 @@
1
1
  import type { ForgeCommandInput, ForgeCommandResult, ForgeRuntimeContext } from "../../../src/types.ts";
2
+ export interface ValidateViolation {
3
+ file: string;
4
+ line?: number;
5
+ column?: number;
6
+ severity: "error" | "warning";
7
+ message: string;
8
+ }
2
9
  export interface ForgeValidateArtifactResult {
3
10
  id: string;
4
11
  command: string;
5
12
  exitCode: number;
13
+ passed: boolean;
14
+ violations: ValidateViolation[];
6
15
  stdout: string;
7
16
  stderr: string;
8
17
  }
@@ -10,6 +19,8 @@ export interface ForgeValidateResult {
10
19
  command: "forge.validate";
11
20
  profileId: string;
12
21
  artifacts: ForgeValidateArtifactResult[];
22
+ allPassed: boolean;
13
23
  }
24
+ export declare function parseViolations(output: string, outputFormat: "plain" | "json" | undefined, violationPattern: string | undefined): ValidateViolation[];
14
25
  export declare function runValidate(input: ForgeCommandInput, context: ForgeRuntimeContext): Promise<ForgeCommandResult<ForgeValidateResult>>;
15
26
  //# sourceMappingURL=validate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../os/core/handlers/validate.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAK/B,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,2BAA2B,EAAE,CAAC;CAC1C;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,CAAC,CA6GlD"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../os/core/handlers/validate.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAK/B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,2BAA2B,EAAE,CAAC;IACzC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,EAC1C,gBAAgB,EAAE,MAAM,GAAG,SAAS,GACnC,iBAAiB,EAAE,CAgDrB;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,CAAC,CA0JlD"}
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  <MODULE_CONTRACT>
3
- <purpose>forge.validate — execute validate commands for all artifacts declared in the active stack profile. Supports --dry-run and --json.</purpose>
3
+ <purpose>forge.validate — execute validate commands for all artifacts declared in the active stack profile. Supports --dry-run, --json, --artifact filtering, and violation parsing.</purpose>
4
4
  <non-goals>
5
5
  <item>Do not implement dev or build logic — those are separate handlers.</item>
6
6
  <item>Do not import from @warpgogol/* — this module is portable.</item>
@@ -8,15 +8,67 @@
8
8
  </MODULE_CONTRACT>
9
9
  <CHANGE_SUMMARY>
10
10
  <item>RFC-0674: initial forge.validate handler with profile resolution, --dry-run, and per-artifact execution.</item>
11
+ <item>RFC-0677: extended with --artifact filtering, violation parsing (outputFormat: json/plain), passed/allPassed fields.</item>
11
12
  </CHANGE_SUMMARY>
12
13
  */
13
14
  import { exec } from "node:child_process";
14
15
  import { promisify } from "node:util";
15
16
  import { resolveActiveProfile, resolveLifecycleFlags } from "./profile-resolve.js";
16
17
  const execAsync = promisify(exec);
18
+ export function parseViolations(output, outputFormat, violationPattern) {
19
+ if (outputFormat === "json") {
20
+ try {
21
+ const parsed = JSON.parse(output);
22
+ if (Array.isArray(parsed)) {
23
+ return parsed
24
+ .filter((v) => typeof v === "object" && v !== null)
25
+ .map((v) => ({
26
+ file: String(v["file"] ?? ""),
27
+ line: typeof v["line"] === "number" ? v["line"] : undefined,
28
+ column: typeof v["column"] === "number" ? v["column"] : undefined,
29
+ severity: (v["severity"] === "warning" ? "warning" : "error"),
30
+ message: String(v["message"] ?? ""),
31
+ }))
32
+ .filter((v) => v.file || v.message);
33
+ }
34
+ return [];
35
+ }
36
+ catch {
37
+ return [];
38
+ }
39
+ }
40
+ if (outputFormat === "plain" && violationPattern) {
41
+ try {
42
+ const regex = new RegExp(violationPattern, "gm");
43
+ const violations = [];
44
+ let match;
45
+ const MAX_MATCHES = 1000;
46
+ let matchCount = 0;
47
+ while ((match = regex.exec(output)) !== null && matchCount < MAX_MATCHES) {
48
+ matchCount++;
49
+ const groups = match.groups ?? {};
50
+ violations.push({
51
+ file: String(groups["file"] ?? ""),
52
+ line: groups["line"] ? Number(groups["line"]) : undefined,
53
+ column: groups["column"] ? Number(groups["column"]) : undefined,
54
+ severity: (groups["severity"] === "warning" ? "warning" : "error"),
55
+ message: String(groups["message"] ?? match[0]),
56
+ });
57
+ if (regex.lastIndex === match.index)
58
+ regex.lastIndex++;
59
+ }
60
+ return violations;
61
+ }
62
+ catch {
63
+ return [];
64
+ }
65
+ }
66
+ return [];
67
+ }
17
68
  export async function runValidate(input, context) {
18
69
  const { workspaceRoot, logger } = context;
19
70
  const { dryRun, profileIdOverride } = resolveLifecycleFlags(input, context);
71
+ const artifactFilter = typeof input.flags["artifact"] === "string" ? input.flags["artifact"] : undefined;
20
72
  const resolved = resolveActiveProfile(workspaceRoot, context.forgeRoot, profileIdOverride);
21
73
  if (!resolved) {
22
74
  return {
@@ -24,6 +76,7 @@ export async function runValidate(input, context) {
24
76
  command: "forge.validate",
25
77
  profileId: "",
26
78
  artifacts: [],
79
+ allPassed: false,
27
80
  },
28
81
  exitCode: 1,
29
82
  summary: "No active profile found. Set `profile` in forge.yaml or use --profile <id>.",
@@ -37,14 +90,34 @@ export async function runValidate(input, context) {
37
90
  command: "forge.validate",
38
91
  profileId: profile.id,
39
92
  artifacts: [],
93
+ allPassed: false,
40
94
  },
41
95
  exitCode: 1,
42
96
  summary: `Profile ${profile.id} does not declare any artifacts.`,
43
97
  nextSteps: [{ action: `Add artifacts section to profile ${profile.id}`, kind: "required" }],
44
98
  };
45
99
  }
100
+ if (artifactFilter) {
101
+ const found = profile.artifacts.find((a) => a.id === artifactFilter);
102
+ if (!found) {
103
+ return {
104
+ data: {
105
+ command: "forge.validate",
106
+ profileId: profile.id,
107
+ artifacts: [],
108
+ allPassed: false,
109
+ },
110
+ exitCode: 1,
111
+ summary: `Artifact ${artifactFilter} not declared in profile ${profile.id}.`,
112
+ nextSteps: [{ action: `Check artifacts in profile ${profile.id}`, kind: "required" }],
113
+ };
114
+ }
115
+ }
116
+ const artifactsToValidate = artifactFilter
117
+ ? profile.artifacts.filter((a) => a.id === artifactFilter)
118
+ : profile.artifacts;
46
119
  if (dryRun) {
47
- const commands = profile.artifacts
120
+ const commands = artifactsToValidate
48
121
  .filter((a) => a.validate)
49
122
  .map((a) => ({ artifactId: a.id, command: a.validate.command }));
50
123
  logger.info(`[dry-run] forge.validate — profile: ${profile.id}`);
@@ -59,34 +132,43 @@ export async function runValidate(input, context) {
59
132
  id: c.artifactId,
60
133
  command: c.command,
61
134
  exitCode: 0,
135
+ passed: true,
136
+ violations: [],
62
137
  stdout: "",
63
138
  stderr: "",
64
139
  })),
140
+ allPassed: true,
65
141
  },
66
142
  summary: `[dry-run] ${commands.length} validate command(s) resolved`,
67
143
  };
68
144
  }
69
145
  const results = [];
70
- let hasFailure = false;
71
- for (const artifact of profile.artifacts) {
146
+ for (const artifact of artifactsToValidate) {
72
147
  if (!artifact.validate) {
73
148
  logger.warn(`Skipping artifact ${artifact.id}: no validate command declared`);
74
149
  results.push({
75
150
  id: artifact.id,
76
151
  command: "",
77
152
  exitCode: 0,
153
+ passed: true,
154
+ violations: [],
78
155
  stdout: "",
79
156
  stderr: "skipped: no validate command",
80
157
  });
81
158
  continue;
82
159
  }
83
160
  const cmd = artifact.validate.command;
161
+ const outputFormat = artifact.validate.outputFormat;
162
+ const violationPattern = artifact.validate.violationPattern;
84
163
  try {
85
- const { stdout, stderr } = await execAsync(cmd, { cwd: workspaceRoot });
164
+ const { stdout, stderr } = await execAsync(cmd, { cwd: workspaceRoot, timeout: 30_000 });
165
+ const violations = parseViolations(stdout + "\n" + stderr, outputFormat, violationPattern);
86
166
  results.push({
87
167
  id: artifact.id,
88
168
  command: cmd,
89
169
  exitCode: 0,
170
+ passed: true,
171
+ violations,
90
172
  stdout,
91
173
  stderr,
92
174
  });
@@ -94,27 +176,33 @@ export async function runValidate(input, context) {
94
176
  }
95
177
  catch (err) {
96
178
  const e = err;
179
+ const rawStdout = e.stdout ?? "";
180
+ const rawStderr = e.stderr ?? e.message;
181
+ const violations = parseViolations(rawStdout + "\n" + rawStderr, outputFormat, violationPattern);
97
182
  results.push({
98
183
  id: artifact.id,
99
184
  command: cmd,
100
185
  exitCode: e.code ?? 1,
101
- stdout: e.stdout ?? "",
102
- stderr: e.stderr ?? e.message,
186
+ passed: false,
187
+ violations,
188
+ stdout: rawStdout,
189
+ stderr: rawStderr,
103
190
  });
104
- hasFailure = true;
105
191
  logger.error(` ${artifact.id}: FAILED (exit ${e.code ?? 1})`);
106
192
  }
107
193
  }
194
+ const allPassed = results.every((r) => r.passed);
108
195
  return {
109
196
  data: {
110
197
  command: "forge.validate",
111
198
  profileId: profile.id,
112
199
  artifacts: results,
200
+ allPassed,
113
201
  },
114
- exitCode: hasFailure ? 1 : 0,
115
- summary: hasFailure
116
- ? `forge.validate: ${results.filter((r) => r.exitCode !== 0).length} artifact(s) failed`
117
- : `forge.validate: all ${results.length} artifact(s) passed`,
202
+ exitCode: allPassed ? 0 : 1,
203
+ summary: allPassed
204
+ ? `forge.validate: all ${results.length} artifact(s) passed`
205
+ : `forge.validate: ${results.filter((r) => !r.passed).length} artifact(s) failed`,
118
206
  };
119
207
  }
120
208
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../os/core/handlers/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../os/core/handlers/validate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/onboarding/doctor.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAgBrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC5C;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AA8rBD,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC;IACzC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6JD,wBAAsB,SAAS,CAC7B,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAuPpL"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/onboarding/doctor.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAkBrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAC5C;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAosBD,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC;IACzC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6JD,wBAAsB,SAAS,CAC7B,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IAAC,QAAQ,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAuPpL"}
@@ -30,8 +30,10 @@ import { parse as parseYaml } from "yaml";
30
30
  import { resolveForgeRoot, loadForgeConfig, resolveBinding, resolveTerminology, FORGE_CLI_BINDING_DEFAULTS, resolvePmRunner } from "../config/forge-config.js";
31
31
  import { FORGE_SKILLS, discoverPackSkills } from "../registry.js";
32
32
  import { discoverWorkspaces } from "./workspace-discovery.js";
33
- import { buildNestedAgentsMd } from "./nested-agents-templates.js";
33
+ import { buildNestedAgentsMd, selectNestedTemplate } from "./nested-agents-templates.js";
34
+ import { readPackageInfo } from "./nested-agents-generate.js";
34
35
  import { listStackProfiles } from "../profiles/stack-profile.js";
36
+ import { resolveAllTerminology } from "../profiles/terminology-utils.js";
35
37
  import { TERMINOLOGY_DEFAULTS } from "../profiles/profile-schema.js";
36
38
  import { runProfileValidate } from "./profile-validate.js";
37
39
  import { parseKnowledgeFile } from "../knowledge/index.js";
@@ -621,8 +623,14 @@ async function checkNestedAgentsMd(workspaceRoot, workspaceTypes) {
621
623
  continue;
622
624
  }
623
625
  // Stale check: compare in-memory render to committed file
626
+ // Must match the generate pipeline: readPackageInfo + buildNestedAgentsMd + selectNestedTemplate
624
627
  try {
625
- const expected = buildNestedAgentsMd(ws, config);
628
+ const packageInfo = readPackageInfo(workspaceRoot, ws.path);
629
+ const fallback = buildNestedAgentsMd(ws, config, packageInfo);
630
+ const profile = config.profile;
631
+ const terminology = resolveAllTerminology(config, profile);
632
+ const wsType = workspaceTypes?.find((wt) => wt.id === ws.type);
633
+ const expected = selectNestedTemplate(wsType, profile, terminology, fallback);
626
634
  const actual = await readFile(join(workspaceRoot, ws.path, "AGENTS.md"), "utf8");
627
635
  if (expected !== actual) {
628
636
  stale++;