@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.
Files changed (106) hide show
  1. package/AGENTS.md +21 -2
  2. package/dist/os/adr/handlers/implement-stamp.d.ts.map +1 -1
  3. package/dist/os/adr/handlers/implement-stamp.js +32 -2
  4. package/dist/os/adr/handlers/implement-stamp.js.map +1 -1
  5. package/dist/os/adr/types.d.ts +2 -1
  6. package/dist/os/adr/types.d.ts.map +1 -1
  7. package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
  8. package/dist/os/compass/handlers/compass-audit-handler.js +3 -3
  9. package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
  10. package/dist/os/compass/handlers/compass-change-summary-handler.d.ts.map +1 -1
  11. package/dist/os/compass/handlers/compass-change-summary-handler.js +1 -1
  12. package/dist/os/compass/handlers/compass-change-summary-handler.js.map +1 -1
  13. package/dist/os/compass/handlers/compass-inventory-handler.d.ts.map +1 -1
  14. package/dist/os/compass/handlers/compass-inventory-handler.js +1 -1
  15. package/dist/os/compass/handlers/compass-inventory-handler.js.map +1 -1
  16. package/dist/os/compass/handlers/compass-inventory.d.ts +1 -1
  17. package/dist/os/compass/handlers/compass-inventory.d.ts.map +1 -1
  18. package/dist/os/compass/handlers/compass-inventory.js +20 -5
  19. package/dist/os/compass/handlers/compass-inventory.js.map +1 -1
  20. package/dist/os/compass/handlers/compass-migrate-handler.d.ts.map +1 -1
  21. package/dist/os/compass/handlers/compass-migrate-handler.js +1 -0
  22. package/dist/os/compass/handlers/compass-migrate-handler.js.map +1 -1
  23. package/dist/os/compass/handlers/compass-migrate.d.ts +2 -0
  24. package/dist/os/compass/handlers/compass-migrate.d.ts.map +1 -1
  25. package/dist/os/compass/handlers/compass-migrate.js +1 -1
  26. package/dist/os/compass/handlers/compass-migrate.js.map +1 -1
  27. package/dist/os/compass/handlers/resolve-scan-root.js +1 -1
  28. package/dist/os/core/handlers/pinned-validate.d.ts.map +1 -1
  29. package/dist/os/core/handlers/pinned-validate.js +26 -6
  30. package/dist/os/core/handlers/pinned-validate.js.map +1 -1
  31. package/dist/os/naming/naming-convention.d.ts.map +1 -1
  32. package/dist/os/naming/naming-convention.js +2 -0
  33. package/dist/os/naming/naming-convention.js.map +1 -1
  34. package/dist/os/rfc/frontmatter-io.d.ts.map +1 -1
  35. package/dist/os/rfc/frontmatter-io.js +1 -0
  36. package/dist/os/rfc/frontmatter-io.js.map +1 -1
  37. package/dist/os/rfc/handlers/validate-rules.d.ts.map +1 -1
  38. package/dist/os/rfc/handlers/validate-rules.js +6 -1
  39. package/dist/os/rfc/handlers/validate-rules.js.map +1 -1
  40. package/dist/os/werkstatt/handlers/workspace-deps.d.ts.map +1 -1
  41. package/dist/os/werkstatt/handlers/workspace-deps.js +4 -3
  42. package/dist/os/werkstatt/handlers/workspace-deps.js.map +1 -1
  43. package/dist/src/config/forge-config.d.ts +8 -1
  44. package/dist/src/config/forge-config.d.ts.map +1 -1
  45. package/dist/src/config/forge-config.js +52 -5
  46. package/dist/src/config/forge-config.js.map +1 -1
  47. package/dist/src/onboarding/create.d.ts.map +1 -1
  48. package/dist/src/onboarding/create.js +9 -10
  49. package/dist/src/onboarding/create.js.map +1 -1
  50. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  51. package/dist/src/onboarding/doctor.js +80 -0
  52. package/dist/src/onboarding/doctor.js.map +1 -1
  53. package/dist/src/onboarding/init.d.ts +1 -0
  54. package/dist/src/onboarding/init.d.ts.map +1 -1
  55. package/dist/src/onboarding/init.js +11 -0
  56. package/dist/src/onboarding/init.js.map +1 -1
  57. package/dist/src/onboarding/npm-token-check.d.ts +40 -0
  58. package/dist/src/onboarding/npm-token-check.d.ts.map +1 -0
  59. package/dist/src/onboarding/npm-token-check.js +104 -0
  60. package/dist/src/onboarding/npm-token-check.js.map +1 -0
  61. package/dist/src/onboarding/scaffold-project.d.ts.map +1 -1
  62. package/dist/src/onboarding/scaffold-project.js +10 -0
  63. package/dist/src/onboarding/scaffold-project.js.map +1 -1
  64. package/dist/src/onboarding/upgrade.d.ts.map +1 -1
  65. package/dist/src/onboarding/upgrade.js +4 -2
  66. package/dist/src/onboarding/upgrade.js.map +1 -1
  67. package/dist/src/profiles/profile-schema.d.ts +2 -0
  68. package/dist/src/profiles/profile-schema.d.ts.map +1 -1
  69. package/dist/src/profiles/profile-schema.js +1 -0
  70. package/dist/src/profiles/profile-schema.js.map +1 -1
  71. package/dist/src/profiles/stack-profile.d.ts +1 -0
  72. package/dist/src/profiles/stack-profile.d.ts.map +1 -1
  73. package/dist/src/profiles/stack-profile.js +2 -0
  74. package/dist/src/profiles/stack-profile.js.map +1 -1
  75. package/os/adr/handlers/implement-stamp.ts +34 -2
  76. package/os/adr/types.ts +3 -1
  77. package/os/compass/handlers/compass-audit-handler.ts +3 -0
  78. package/os/compass/handlers/compass-change-summary-handler.ts +1 -0
  79. package/os/compass/handlers/compass-inventory-handler.ts +1 -0
  80. package/os/compass/handlers/compass-inventory.ts +20 -6
  81. package/os/compass/handlers/compass-migrate-handler.ts +1 -0
  82. package/os/compass/handlers/compass-migrate.ts +9 -2
  83. package/os/compass/handlers/resolve-scan-root.ts +1 -1
  84. package/os/core/handlers/pinned-validate.ts +33 -7
  85. package/os/naming/naming-convention.ts +2 -0
  86. package/os/rfc/frontmatter-io.ts +1 -0
  87. package/os/rfc/handlers/validate-rules.ts +8 -1
  88. package/os/werkstatt/handlers/workspace-deps.ts +4 -3
  89. package/package.json +1 -1
  90. package/profiles/site-workshop.yaml +654 -0
  91. package/skills/fo/fo-idea-create-rfc/acceptance-criteria-standard.md +1 -1
  92. package/src/config/forge-config.ts +59 -5
  93. package/src/onboarding/create.ts +9 -9
  94. package/src/onboarding/doctor-token-check.test.ts +124 -0
  95. package/src/onboarding/doctor.ts +87 -0
  96. package/src/onboarding/init.ts +20 -1
  97. package/src/onboarding/npm-token-check.ts +140 -0
  98. package/src/onboarding/scaffold-project.ts +11 -0
  99. package/src/onboarding/site-workshop-profile.test.ts +84 -0
  100. package/src/onboarding/upgrade.ts +4 -1
  101. package/src/profiles/profile-schema.ts +2 -0
  102. package/src/profiles/stack-profile.ts +2 -0
  103. package/src/tests/adr-implement-stamp.test.ts +150 -0
  104. package/src/tests/doctor-profile-id-known.test.ts +237 -0
  105. package/src/tests/pinned-validate.test.ts +134 -0
  106. 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<{ relPath: string; operation: PinnedViolation["operation"] }> = [];
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
@@ -69,6 +69,8 @@ const NAMING_CONVENTION_IGNORED_TOP_LEVEL = new Set([
69
69
  ".forge",
70
70
  "patches",
71
71
  "storage",
72
+ ".check-warpgogol",
73
+ ".coverage-report-html",
72
74
  ]);
73
75
 
74
76
  // Tool-mandated filenames exempt from kebab-case (Docker, Caddy use these exact names).
@@ -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
- if (currentStatus === "implemented") {
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-engine/fingerprint and @warpgogol/werkstatt-shared/node/fs. 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>
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-engine/fingerprint");
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-engine/fingerprint and @warpgogol/werkstatt-shared are required for this command but not installed. ` +
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warpgogol/forge",
3
- "version": "5.1.1",
3
+ "version": "5.1.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",