@warpgogol/forge 5.1.1 → 5.1.3
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/AGENTS.md +21 -2
- package/dist/os/adr/handlers/implement-stamp.d.ts.map +1 -1
- package/dist/os/adr/handlers/implement-stamp.js +32 -2
- package/dist/os/adr/handlers/implement-stamp.js.map +1 -1
- package/dist/os/adr/types.d.ts +2 -1
- package/dist/os/adr/types.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-audit-handler.js +3 -3
- package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-change-summary-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-change-summary-handler.js +1 -1
- package/dist/os/compass/handlers/compass-change-summary-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-inventory-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-inventory-handler.js +1 -1
- package/dist/os/compass/handlers/compass-inventory-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-inventory.d.ts +1 -1
- package/dist/os/compass/handlers/compass-inventory.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-inventory.js +20 -5
- package/dist/os/compass/handlers/compass-inventory.js.map +1 -1
- package/dist/os/compass/handlers/compass-migrate-handler.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-migrate-handler.js +1 -0
- package/dist/os/compass/handlers/compass-migrate-handler.js.map +1 -1
- package/dist/os/compass/handlers/compass-migrate.d.ts +2 -0
- package/dist/os/compass/handlers/compass-migrate.d.ts.map +1 -1
- package/dist/os/compass/handlers/compass-migrate.js +1 -1
- package/dist/os/compass/handlers/compass-migrate.js.map +1 -1
- package/dist/os/compass/handlers/resolve-scan-root.js +1 -1
- package/dist/os/core/handlers/pinned-validate.d.ts.map +1 -1
- package/dist/os/core/handlers/pinned-validate.js +26 -6
- package/dist/os/core/handlers/pinned-validate.js.map +1 -1
- package/dist/os/naming/naming-convention.d.ts.map +1 -1
- package/dist/os/naming/naming-convention.js +2 -0
- package/dist/os/naming/naming-convention.js.map +1 -1
- package/dist/os/rfc/frontmatter-io.d.ts.map +1 -1
- package/dist/os/rfc/frontmatter-io.js +1 -0
- package/dist/os/rfc/frontmatter-io.js.map +1 -1
- package/dist/os/rfc/handlers/validate-rules.d.ts.map +1 -1
- package/dist/os/rfc/handlers/validate-rules.js +6 -1
- package/dist/os/rfc/handlers/validate-rules.js.map +1 -1
- package/dist/os/werkstatt/handlers/workspace-deps.d.ts.map +1 -1
- package/dist/os/werkstatt/handlers/workspace-deps.js +4 -3
- package/dist/os/werkstatt/handlers/workspace-deps.js.map +1 -1
- package/dist/src/config/forge-config.d.ts +8 -1
- package/dist/src/config/forge-config.d.ts.map +1 -1
- package/dist/src/config/forge-config.js +52 -5
- package/dist/src/config/forge-config.js.map +1 -1
- package/dist/src/onboarding/create.d.ts.map +1 -1
- package/dist/src/onboarding/create.js +9 -10
- package/dist/src/onboarding/create.js.map +1 -1
- package/dist/src/onboarding/doctor.d.ts.map +1 -1
- package/dist/src/onboarding/doctor.js +80 -0
- package/dist/src/onboarding/doctor.js.map +1 -1
- package/dist/src/onboarding/init.d.ts +1 -0
- package/dist/src/onboarding/init.d.ts.map +1 -1
- package/dist/src/onboarding/init.js +11 -0
- package/dist/src/onboarding/init.js.map +1 -1
- package/dist/src/onboarding/npm-token-check.d.ts +40 -0
- package/dist/src/onboarding/npm-token-check.d.ts.map +1 -0
- package/dist/src/onboarding/npm-token-check.js +104 -0
- package/dist/src/onboarding/npm-token-check.js.map +1 -0
- package/dist/src/onboarding/scaffold-project.d.ts.map +1 -1
- package/dist/src/onboarding/scaffold-project.js +10 -0
- package/dist/src/onboarding/scaffold-project.js.map +1 -1
- package/dist/src/onboarding/upgrade.d.ts.map +1 -1
- package/dist/src/onboarding/upgrade.js +4 -2
- package/dist/src/onboarding/upgrade.js.map +1 -1
- package/dist/src/profiles/profile-schema.d.ts +2 -0
- package/dist/src/profiles/profile-schema.d.ts.map +1 -1
- package/dist/src/profiles/profile-schema.js +1 -0
- package/dist/src/profiles/profile-schema.js.map +1 -1
- package/dist/src/profiles/stack-profile.d.ts +1 -0
- package/dist/src/profiles/stack-profile.d.ts.map +1 -1
- package/dist/src/profiles/stack-profile.js +2 -0
- package/dist/src/profiles/stack-profile.js.map +1 -1
- package/os/adr/handlers/implement-stamp.ts +34 -2
- package/os/adr/types.ts +3 -1
- package/os/compass/handlers/compass-audit-handler.ts +3 -0
- package/os/compass/handlers/compass-change-summary-handler.ts +1 -0
- package/os/compass/handlers/compass-inventory-handler.ts +1 -0
- package/os/compass/handlers/compass-inventory.ts +20 -6
- package/os/compass/handlers/compass-migrate-handler.ts +1 -0
- package/os/compass/handlers/compass-migrate.ts +9 -2
- package/os/compass/handlers/resolve-scan-root.ts +1 -1
- package/os/core/handlers/pinned-validate.ts +33 -7
- package/os/naming/naming-convention.ts +2 -0
- package/os/rfc/frontmatter-io.ts +1 -0
- package/os/rfc/handlers/validate-rules.ts +8 -1
- package/os/werkstatt/handlers/workspace-deps.ts +4 -3
- package/package.json +1 -1
- package/profiles/site-workshop.yaml +654 -0
- package/skills/fo/fo-idea-create-rfc/acceptance-criteria-standard.md +1 -1
- package/src/config/forge-config.ts +59 -5
- package/src/onboarding/create.ts +9 -9
- package/src/onboarding/doctor-token-check.test.ts +124 -0
- package/src/onboarding/doctor.ts +87 -0
- package/src/onboarding/init.ts +20 -1
- package/src/onboarding/npm-token-check.ts +140 -0
- package/src/onboarding/scaffold-project.ts +11 -0
- package/src/onboarding/site-workshop-profile.test.ts +84 -0
- package/src/onboarding/upgrade.ts +4 -1
- package/src/profiles/profile-schema.ts +2 -0
- package/src/profiles/stack-profile.ts +2 -0
- package/src/tests/adr-implement-stamp.test.ts +150 -0
- package/src/tests/doctor-profile-id-known.test.ts +237 -0
- package/src/tests/pinned-validate.test.ts +134 -0
- package/src/tests/profile-schema.test.ts +1 -1
|
@@ -33,6 +33,7 @@ import type {
|
|
|
33
33
|
import {
|
|
34
34
|
loadPinnedManifest,
|
|
35
35
|
isPinned,
|
|
36
|
+
isIntraDirMove,
|
|
36
37
|
PINNED_MANIFEST_PATH,
|
|
37
38
|
PinnedManifestMalformedError,
|
|
38
39
|
} from "./pinned-check.ts";
|
|
@@ -51,11 +52,18 @@ const AUDIT_LOG_PATH = path.join(".forge", "pinned-audit.log");
|
|
|
51
52
|
* Git status codes:
|
|
52
53
|
* D = deleted, R = renamed (move), M = modified, A = added, C = copied
|
|
53
54
|
* Format: "R100\tdocs/old.md\tdocs/new.md" or "D\tdocs/file.md"
|
|
55
|
+
*
|
|
56
|
+
* R/C entries keep their destination in `destPath` so the violation check can
|
|
57
|
+
* apply the isIntraDirMove exemption (same rule the archive handlers use).
|
|
54
58
|
*/
|
|
55
59
|
function parseGitNameStatus(
|
|
56
60
|
output: string,
|
|
57
|
-
): Array<{ relPath: string; operation: PinnedViolation["operation"] }> {
|
|
58
|
-
const entries: Array<{
|
|
61
|
+
): Array<{ relPath: string; operation: PinnedViolation["operation"]; destPath?: string }> {
|
|
62
|
+
const entries: Array<{
|
|
63
|
+
relPath: string;
|
|
64
|
+
operation: PinnedViolation["operation"];
|
|
65
|
+
destPath?: string;
|
|
66
|
+
}> = [];
|
|
59
67
|
const lines = output.trim().split("\n").filter(Boolean);
|
|
60
68
|
|
|
61
69
|
for (const line of lines) {
|
|
@@ -69,10 +77,7 @@ function parseGitNameStatus(
|
|
|
69
77
|
if (statusCode.startsWith("D")) {
|
|
70
78
|
entries.push({ relPath: oldPath, operation: "delete" });
|
|
71
79
|
} else if (statusCode.startsWith("R") || statusCode.startsWith("C")) {
|
|
72
|
-
entries.push({ relPath: oldPath, operation: "move" });
|
|
73
|
-
if (newPath !== oldPath) {
|
|
74
|
-
entries.push({ relPath: newPath, operation: "move" });
|
|
75
|
-
}
|
|
80
|
+
entries.push({ relPath: oldPath, operation: "move", destPath: newPath });
|
|
76
81
|
} else if (statusCode.startsWith("M")) {
|
|
77
82
|
entries.push({ relPath: oldPath, operation: "modify" });
|
|
78
83
|
}
|
|
@@ -228,7 +233,28 @@ export async function runPinnedValidate(
|
|
|
228
233
|
|
|
229
234
|
// Check each changed file against the manifest
|
|
230
235
|
const allViolations: PinnedViolation[] = [];
|
|
231
|
-
for (const { relPath, operation } of changedFiles) {
|
|
236
|
+
for (const { relPath, operation, destPath } of changedFiles) {
|
|
237
|
+
if (operation === "move" && destPath) {
|
|
238
|
+
// Exempt intra-directory moves — the file stays inside the same pinned
|
|
239
|
+
// dir (e.g. docs.archive moves docs/rfcs/x.md → docs/rfcs/archive/…/x.md).
|
|
240
|
+
// Same exemption the archive handlers apply via isIntraDirMove.
|
|
241
|
+
if (isIntraDirMove(manifest, relPath, destPath)) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
for (const movePath of new Set([relPath, destPath])) {
|
|
245
|
+
const moveEntry = isPinned(manifest, movePath);
|
|
246
|
+
if (moveEntry) {
|
|
247
|
+
allViolations.push({
|
|
248
|
+
path: movePath,
|
|
249
|
+
mode: moveEntry.mode,
|
|
250
|
+
operation,
|
|
251
|
+
reason: moveEntry.reason,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
|
|
232
258
|
const entry = isPinned(manifest, relPath);
|
|
233
259
|
if (entry) {
|
|
234
260
|
// For protect mode, only delete and move are violations — modify is allowed
|
package/os/rfc/frontmatter-io.ts
CHANGED
|
@@ -56,6 +56,7 @@ export async function listRfcFiles(rfcDirPath: string): Promise<string[]> {
|
|
|
56
56
|
entry.isFile() &&
|
|
57
57
|
entry.name.endsWith(".md") &&
|
|
58
58
|
!entry.name.startsWith("rfc-0000") &&
|
|
59
|
+
!entry.name.endsWith(".generated.md") &&
|
|
59
60
|
entry.name !== "README.md"
|
|
60
61
|
) {
|
|
61
62
|
results.push(relativePath);
|
|
@@ -404,7 +404,14 @@ async function checkImplementationCommitDrift(
|
|
|
404
404
|
createdAt: string,
|
|
405
405
|
currentStatus: string,
|
|
406
406
|
): Promise<{ found: boolean; commitCount: number }> {
|
|
407
|
-
|
|
407
|
+
// Terminal statuses are exempt: implemented is the target state, and
|
|
408
|
+
// superseded/rejected RFCs may legitimately carry implement: commits from
|
|
409
|
+
// work that landed before the status transition (RFC-0769 lifecycle).
|
|
410
|
+
if (
|
|
411
|
+
currentStatus === "implemented" ||
|
|
412
|
+
currentStatus === "superseded" ||
|
|
413
|
+
currentStatus === "rejected"
|
|
414
|
+
) {
|
|
408
415
|
return { found: false, commitCount: 0 };
|
|
409
416
|
}
|
|
410
417
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
<MODULE_CONTRACT>
|
|
3
|
-
<purpose>Lazy dynamic-import bridge for @warpgogol/werkstatt-
|
|
3
|
+
<purpose>Lazy dynamic-import bridge for @warpgogol/werkstatt-shared/node/fs and @warpgogol/werkstatt-shared/fingerprint. These workspace packages are not published to npm — when forge is installed standalone from npm, they are unavailable and handlers that depend on them must degrade gracefully.</purpose>
|
|
4
4
|
<non-goals>
|
|
5
5
|
<item>Do not re-export types from @warpgogol/* — only runtime functions.</item>
|
|
6
6
|
<item>Do not use static imports — that would break npm installs without workspace deps.</item>
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
<CHANGE_SUMMARY>
|
|
10
10
|
<item>RFC-0682: extract dynamic-import helper so forge publishes without workspace:* deps.</item>
|
|
11
11
|
<item>RFC-0940: moved from os/core/handlers/ to os/werkstatt/handlers/ — this module imports @warpgogol/werkstatt-engine and belongs in the adapter directory.</item>
|
|
12
|
+
<item>2026-09-22: fingerprint import switched from @warpgogol/werkstatt-engine/fingerprint to @warpgogol/werkstatt-shared/fingerprint (canonical home since RFC-1104) — breaks the forge↔engine package cycle reported by turbo.</item>
|
|
12
13
|
</CHANGE_SUMMARY>
|
|
13
14
|
*/
|
|
14
15
|
|
|
@@ -40,7 +41,7 @@ export async function loadWorkspaceDeps(): Promise<WorkspaceDeps> {
|
|
|
40
41
|
const shareMod = await import("@warpgogol/werkstatt-shared/node/fs");
|
|
41
42
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
42
43
|
// @ts-ignore — workspace dep, may not be installed when forge is used standalone from npm
|
|
43
|
-
const fpMod = await import("@warpgogol/werkstatt-
|
|
44
|
+
const fpMod = await import("@warpgogol/werkstatt-shared/fingerprint");
|
|
44
45
|
cached = {
|
|
45
46
|
collectFiles: shareMod.collectFiles as CollectFilesFn,
|
|
46
47
|
byteHashFile: fpMod.byteHashFile as ByteHashFileFn,
|
|
@@ -48,7 +49,7 @@ export async function loadWorkspaceDeps(): Promise<WorkspaceDeps> {
|
|
|
48
49
|
return cached;
|
|
49
50
|
} catch (err) {
|
|
50
51
|
loadError =
|
|
51
|
-
`@warpgogol/werkstatt-
|
|
52
|
+
`@warpgogol/werkstatt-shared/fingerprint and @warpgogol/werkstatt-shared/node/fs are required for this command but not installed. ` +
|
|
52
53
|
`When using forge standalone from npm, install them separately or use forge within the warpgogol workspace. ` +
|
|
53
54
|
`Error: ${(err as Error).message}`;
|
|
54
55
|
throw new Error(loadError);
|