@deftai/directive-core 0.68.1 → 0.69.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.
- package/dist/doctor/constants.d.ts +9 -0
- package/dist/doctor/constants.js +11 -0
- package/dist/doctor/main.d.ts +47 -1
- package/dist/doctor/main.js +352 -2
- package/dist/doctor/payload-staleness.d.ts +8 -0
- package/dist/doctor/payload-staleness.js +11 -8
- package/dist/doctor/types.d.ts +48 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/init-deposit/gitignore.d.ts +18 -0
- package/dist/init-deposit/gitignore.js +94 -15
- package/dist/init-deposit/headless-manifest.d.ts +87 -0
- package/dist/init-deposit/headless-manifest.js +261 -0
- package/dist/init-deposit/index.d.ts +3 -0
- package/dist/init-deposit/index.js +3 -0
- package/dist/init-deposit/init-dispatch.d.ts +90 -0
- package/dist/init-deposit/init-dispatch.js +170 -0
- package/dist/init-deposit/refresh.d.ts +79 -2
- package/dist/init-deposit/refresh.js +177 -5
- package/dist/init-deposit/scaffold.d.ts +25 -0
- package/dist/init-deposit/scaffold.js +57 -0
- package/dist/init-deposit/untrack-core.d.ts +84 -0
- package/dist/init-deposit/untrack-core.js +150 -0
- package/dist/resolution/classify.d.ts +41 -0
- package/dist/resolution/classify.js +138 -0
- package/dist/resolution/engine-ladder.d.ts +98 -0
- package/dist/resolution/engine-ladder.js +185 -0
- package/dist/resolution/index.d.ts +19 -0
- package/dist/resolution/index.js +19 -0
- package/dist/resolution/integrity.d.ts +48 -0
- package/dist/resolution/integrity.js +80 -0
- package/dist/resolution/package-manager.d.ts +77 -0
- package/dist/resolution/package-manager.js +103 -0
- package/dist/resolution/pin.d.ts +73 -0
- package/dist/resolution/pin.js +169 -0
- package/dist/resolution/plan.d.ts +66 -0
- package/dist/resolution/plan.js +219 -0
- package/dist/resolution/skew-policy.d.ts +46 -0
- package/dist/resolution/skew-policy.js +120 -0
- package/dist/session/session-start.d.ts +2 -0
- package/dist/session/session-start.js +28 -1
- package/dist/user-config/index.d.ts +2 -0
- package/dist/user-config/index.js +2 -0
- package/dist/user-config/resolve-user-md.d.ts +76 -0
- package/dist/user-config/resolve-user-md.js +120 -0
- package/dist/xbrief-migrate/constants.d.ts +10 -0
- package/dist/xbrief-migrate/constants.js +19 -0
- package/dist/xbrief-migrate/detect.d.ts +34 -0
- package/dist/xbrief-migrate/detect.js +33 -0
- package/dist/xbrief-migrate/fs-helpers.d.ts +13 -0
- package/dist/xbrief-migrate/fs-helpers.js +46 -1
- package/dist/xbrief-migrate/index.d.ts +4 -2
- package/dist/xbrief-migrate/index.js +4 -2
- package/dist/xbrief-migrate/migrate-project.d.ts +23 -1
- package/dist/xbrief-migrate/migrate-project.js +97 -8
- package/dist/xbrief-migrate/signpost.d.ts +7 -1
- package/dist/xbrief-migrate/signpost.js +18 -3
- package/package.json +7 -3
|
@@ -3,9 +3,9 @@ import { dirname, join, relative, resolve } from "node:path";
|
|
|
3
3
|
import { checkGitClean } from "../migrate-preflight/index.js";
|
|
4
4
|
import { agentsRefreshPlan } from "../platform/agents-md.js";
|
|
5
5
|
import { patchAgentsMdHeader, renderHeaderPatchSummary } from "./agents-header.js";
|
|
6
|
-
import { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, } from "./constants.js";
|
|
7
|
-
import { detectLegacyVbriefLayout } from "./detect.js";
|
|
8
|
-
import { isDirectory } from "./fs-helpers.js";
|
|
6
|
+
import { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, VBRIEF_DEPRECATION_MARKER_BODY, VBRIEF_DEPRECATION_MARKER_FILENAME, } from "./constants.js";
|
|
7
|
+
import { detectLegacyVbriefLayout, detectXbriefConvergence } from "./detect.js";
|
|
8
|
+
import { hasVbriefDeprecationMarker, isDirectory, isEffectivelyEmptyDir } from "./fs-helpers.js";
|
|
9
9
|
import { renderXbriefMigrationLine, xbriefMigrationGuidance } from "./signpost.js";
|
|
10
10
|
import { rewriteEmbeddedTokens, transformArtifactV06ToV08Transactional } from "./transforms.js";
|
|
11
11
|
function collectFiles(root, acc = []) {
|
|
@@ -52,7 +52,7 @@ function backupLegacyTree(projectRoot, legacyDir) {
|
|
|
52
52
|
cpSync(legacyDir, join(backupRoot, LEGACY_ARTIFACT_DIR), { recursive: true });
|
|
53
53
|
return backupRoot;
|
|
54
54
|
}
|
|
55
|
-
function migrateLegacyTree(projectRoot, legacyDir) {
|
|
55
|
+
function migrateLegacyTree(projectRoot, legacyDir, options) {
|
|
56
56
|
const migratedDir = join(projectRoot, MIGRATED_ARTIFACT_DIR);
|
|
57
57
|
if (existsSync(migratedDir)) {
|
|
58
58
|
throw new Error(`refusing to migrate: '${MIGRATED_ARTIFACT_DIR}/' already exists alongside '${LEGACY_ARTIFACT_DIR}/'`);
|
|
@@ -71,7 +71,15 @@ function migrateLegacyTree(projectRoot, legacyDir) {
|
|
|
71
71
|
writeMigratedFile(srcPath, destPath);
|
|
72
72
|
}
|
|
73
73
|
renameOrReplace(stagedDir, migratedDir);
|
|
74
|
-
|
|
74
|
+
// Converge to a single unambiguous root: the fully-migrated legacy tree is
|
|
75
|
+
// either removed (default) or retained for read-compat behind an explicit
|
|
76
|
+
// deprecation marker so it never looks like an active source of truth (#2270).
|
|
77
|
+
if (options.keepLegacy) {
|
|
78
|
+
writeVbriefDeprecationMarker(legacyDir);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
rmSync(legacyDir, { recursive: true, force: true });
|
|
82
|
+
}
|
|
75
83
|
return { backupDir, files: files.length };
|
|
76
84
|
}
|
|
77
85
|
catch (err) {
|
|
@@ -79,6 +87,36 @@ function migrateLegacyTree(projectRoot, legacyDir) {
|
|
|
79
87
|
throw err;
|
|
80
88
|
}
|
|
81
89
|
}
|
|
90
|
+
/** Idempotently write the legacy-root deprecation marker (#2270). */
|
|
91
|
+
function writeVbriefDeprecationMarker(legacyDir) {
|
|
92
|
+
mkdirSync(legacyDir, { recursive: true });
|
|
93
|
+
if (hasVbriefDeprecationMarker(legacyDir)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
writeFileSync(join(legacyDir, VBRIEF_DEPRECATION_MARKER_FILENAME), VBRIEF_DEPRECATION_MARKER_BODY, "utf8");
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Converge a leftover legacy `vbrief/` root to an unambiguous state (#2270).
|
|
100
|
+
* An effectively-empty tree is removed by default (single canonical root); a
|
|
101
|
+
* tree with real content — or an empty tree when `retain` is requested — is
|
|
102
|
+
* kept for read-compat behind an explicit deprecation marker. Idempotent: a
|
|
103
|
+
* missing dir or an already-marked dir is a no-op.
|
|
104
|
+
*/
|
|
105
|
+
export function convergeLegacyVbriefRoot(projectRoot, options) {
|
|
106
|
+
const legacyDir = join(projectRoot, LEGACY_ARTIFACT_DIR);
|
|
107
|
+
if (!isDirectory(legacyDir)) {
|
|
108
|
+
return "removed";
|
|
109
|
+
}
|
|
110
|
+
if (hasVbriefDeprecationMarker(legacyDir)) {
|
|
111
|
+
return "marker";
|
|
112
|
+
}
|
|
113
|
+
if (isEffectivelyEmptyDir(legacyDir) && !options.retain) {
|
|
114
|
+
rmSync(legacyDir, { recursive: true, force: true });
|
|
115
|
+
return "removed";
|
|
116
|
+
}
|
|
117
|
+
writeVbriefDeprecationMarker(legacyDir);
|
|
118
|
+
return "marker";
|
|
119
|
+
}
|
|
82
120
|
function renameOrReplace(src, dest) {
|
|
83
121
|
if (existsSync(dest)) {
|
|
84
122
|
rmSync(dest, { recursive: true, force: true });
|
|
@@ -107,9 +145,58 @@ function runAgentsRefresh(projectRoot, frameworkRoot, io) {
|
|
|
107
145
|
io.writeOut(`AGENTS.md updated (state=${state}).\n`);
|
|
108
146
|
return 0;
|
|
109
147
|
}
|
|
110
|
-
/** Core orchestrator for the consumer xbrief rename (#2110). */
|
|
148
|
+
/** Core orchestrator for the consumer xbrief rename (#2110) + convergence (#2270). */
|
|
111
149
|
export function runXbriefMigration(args, _io) {
|
|
112
150
|
const projectRoot = resolve(args.projectRoot);
|
|
151
|
+
const legacyDir = join(projectRoot, LEGACY_ARTIFACT_DIR);
|
|
152
|
+
const keepLegacy = args.keepLegacy ?? false;
|
|
153
|
+
const convergence = detectXbriefConvergence(projectRoot);
|
|
154
|
+
switch (convergence.state) {
|
|
155
|
+
// Already converged: legacy root is retained behind an explicit marker.
|
|
156
|
+
// Rerun is a pure no-op (no re-removal, no duplicate marker) — idempotent.
|
|
157
|
+
case "xbrief-marker":
|
|
158
|
+
return {
|
|
159
|
+
kind: "converged",
|
|
160
|
+
action: "marker",
|
|
161
|
+
already: true,
|
|
162
|
+
message: `Legacy '${LEGACY_ARTIFACT_DIR}/' already carries a deprecation marker — layout already converged.`,
|
|
163
|
+
};
|
|
164
|
+
// Ambiguous dual-empty root: a fully-migrated empty legacy tree. Converge to
|
|
165
|
+
// a single canonical root by removing it (or marking it when read-compat
|
|
166
|
+
// retention is requested); never leave two indistinguishable empty roots.
|
|
167
|
+
// Read-compat retention is only honored when a canonical xbrief/ actually
|
|
168
|
+
// has content — marking an empty legacy root with no canonical replacement
|
|
169
|
+
// would strand the project behind a marker that claims a migration that
|
|
170
|
+
// never happened, so that case always removes the stray empty root.
|
|
171
|
+
case "empty-vbrief": {
|
|
172
|
+
const retain = keepLegacy && convergence.xbriefHasContent;
|
|
173
|
+
const action = convergeLegacyVbriefRoot(projectRoot, { retain });
|
|
174
|
+
let message;
|
|
175
|
+
if (action === "removed") {
|
|
176
|
+
message = convergence.xbriefHasContent
|
|
177
|
+
? `Converged layout: removed empty legacy '${LEGACY_ARTIFACT_DIR}/' — single '${MIGRATED_ARTIFACT_DIR}/' root.`
|
|
178
|
+
: `Converged layout: removed empty legacy '${LEGACY_ARTIFACT_DIR}/' — no canonical '${MIGRATED_ARTIFACT_DIR}/' root to migrate to yet.`;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
message = `Converged layout: wrote deprecation marker to legacy '${LEGACY_ARTIFACT_DIR}/' (retained for read-compat).`;
|
|
182
|
+
}
|
|
183
|
+
return { kind: "converged", action, already: false, message };
|
|
184
|
+
}
|
|
185
|
+
// Legacy content coexisting with a populated canonical xbrief/. We never
|
|
186
|
+
// destructively merge; converge non-destructively by marking the legacy
|
|
187
|
+
// tree deprecated so it no longer looks like an active source of truth.
|
|
188
|
+
case "dual-populated": {
|
|
189
|
+
convergeLegacyVbriefRoot(projectRoot, { retain: true });
|
|
190
|
+
return {
|
|
191
|
+
kind: "converged",
|
|
192
|
+
action: "marker",
|
|
193
|
+
already: false,
|
|
194
|
+
message: `Converged layout: '${MIGRATED_ARTIFACT_DIR}/' is canonical; wrote deprecation marker to legacy '${LEGACY_ARTIFACT_DIR}/' (retained for read-compat).`,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
default:
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
113
200
|
const detection = detectLegacyVbriefLayout(projectRoot);
|
|
114
201
|
if (!detection.legacyLayout) {
|
|
115
202
|
return {
|
|
@@ -117,7 +204,6 @@ export function runXbriefMigration(args, _io) {
|
|
|
117
204
|
message: "Project is already on the xbrief layout — nothing to migrate.",
|
|
118
205
|
};
|
|
119
206
|
}
|
|
120
|
-
const legacyDir = join(projectRoot, LEGACY_ARTIFACT_DIR);
|
|
121
207
|
if (!isDirectory(legacyDir)) {
|
|
122
208
|
return {
|
|
123
209
|
kind: "config",
|
|
@@ -134,7 +220,7 @@ export function runXbriefMigration(args, _io) {
|
|
|
134
220
|
}
|
|
135
221
|
}
|
|
136
222
|
try {
|
|
137
|
-
const { backupDir, files } = migrateLegacyTree(projectRoot, legacyDir);
|
|
223
|
+
const { backupDir, files } = migrateLegacyTree(projectRoot, legacyDir, { keepLegacy });
|
|
138
224
|
return { kind: "migrated", backupDir, files };
|
|
139
225
|
}
|
|
140
226
|
catch (err) {
|
|
@@ -165,6 +251,9 @@ export function emitXbriefMigration(outcome, io, options = {}) {
|
|
|
165
251
|
io.writeOut(`Migrated ${outcome.files} file(s) from ${LEGACY_ARTIFACT_DIR}/ to ${MIGRATED_ARTIFACT_DIR}/.\n` +
|
|
166
252
|
`Backup written to ${outcome.backupDir}.\n`);
|
|
167
253
|
return 0;
|
|
254
|
+
case "converged":
|
|
255
|
+
io.writeOut(`${outcome.message}\n`);
|
|
256
|
+
return 0;
|
|
168
257
|
default: {
|
|
169
258
|
const _exhaustive = outcome;
|
|
170
259
|
return _exhaustive;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
/** Operator guidance for the TS-native xbrief rename (#2034 / #2110). */
|
|
2
2
|
export declare function xbriefMigrationGuidance(): string;
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* One-line doctor / ritual signpost mirroring `renderPrecutoverLine` (#2110),
|
|
5
|
+
* reporting an unambiguous convergence state (#2270). A migrated project reads
|
|
6
|
+
* as `xbrief active` plus either `vbrief legacy marker` or `vbrief removed`; a
|
|
7
|
+
* stray empty legacy root is called out as a pending convergence rather than a
|
|
8
|
+
* generic "run migrate" dead end — never a dual-empty-root ambiguity.
|
|
9
|
+
*/
|
|
4
10
|
export declare function renderXbriefMigrationLine(projectRoot: string): string;
|
|
5
11
|
//# sourceMappingURL=signpost.d.ts.map
|
|
@@ -1,13 +1,28 @@
|
|
|
1
|
-
import { detectLegacyVbriefLayout } from "./detect.js";
|
|
1
|
+
import { detectLegacyVbriefLayout, detectXbriefConvergence } from "./detect.js";
|
|
2
2
|
/** Operator guidance for the TS-native xbrief rename (#2034 / #2110). */
|
|
3
3
|
export function xbriefMigrationGuidance() {
|
|
4
4
|
return "Run `deft migrate:xbrief` (or `task migrate:xbrief`) to convert vbrief/ to xbrief/ safely.";
|
|
5
5
|
}
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* One-line doctor / ritual signpost mirroring `renderPrecutoverLine` (#2110),
|
|
8
|
+
* reporting an unambiguous convergence state (#2270). A migrated project reads
|
|
9
|
+
* as `xbrief active` plus either `vbrief legacy marker` or `vbrief removed`; a
|
|
10
|
+
* stray empty legacy root is called out as a pending convergence rather than a
|
|
11
|
+
* generic "run migrate" dead end — never a dual-empty-root ambiguity.
|
|
12
|
+
*/
|
|
7
13
|
export function renderXbriefMigrationLine(projectRoot) {
|
|
14
|
+
const convergence = detectXbriefConvergence(projectRoot);
|
|
15
|
+
// Converged: legacy vbrief/ retained for read-compat behind an explicit marker.
|
|
16
|
+
if (convergence.state === "xbrief-marker") {
|
|
17
|
+
return "xBrief migration: converged -- xbrief active, vbrief legacy marker (read-compat).";
|
|
18
|
+
}
|
|
19
|
+
// Ambiguous dual-empty root: canonical xbrief/ (or none) plus a stray empty vbrief/.
|
|
20
|
+
if (convergence.state === "empty-vbrief") {
|
|
21
|
+
return `xBrief migration: converge pending -- xbrief active, empty legacy vbrief/ present. ${xbriefMigrationGuidance()}`;
|
|
22
|
+
}
|
|
8
23
|
const { legacyLayout, reasons } = detectLegacyVbriefLayout(projectRoot);
|
|
9
24
|
if (!legacyLayout) {
|
|
10
|
-
return "xBrief migration: none --
|
|
25
|
+
return "xBrief migration: none -- xbrief active, vbrief removed.";
|
|
11
26
|
}
|
|
12
27
|
const maxReasons = 3;
|
|
13
28
|
const shown = reasons.slice(0, maxReasons);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.69.0",
|
|
4
4
|
"description": "TypeScript engine core for the Directive framework.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -90,6 +90,10 @@
|
|
|
90
90
|
"types": "./dist/release-e2e/index.d.ts",
|
|
91
91
|
"default": "./dist/release-e2e/index.js"
|
|
92
92
|
},
|
|
93
|
+
"./resolution": {
|
|
94
|
+
"types": "./dist/resolution/index.d.ts",
|
|
95
|
+
"default": "./dist/resolution/index.js"
|
|
96
|
+
},
|
|
93
97
|
"./pr-merge-readiness": {
|
|
94
98
|
"types": "./dist/pr-merge-readiness/index.d.ts",
|
|
95
99
|
"default": "./dist/pr-merge-readiness/index.js"
|
|
@@ -245,8 +249,8 @@
|
|
|
245
249
|
"provenance": true
|
|
246
250
|
},
|
|
247
251
|
"dependencies": {
|
|
248
|
-
"@deftai/directive-content": "^0.
|
|
249
|
-
"@deftai/directive-types": "^0.
|
|
252
|
+
"@deftai/directive-content": "^0.69.0",
|
|
253
|
+
"@deftai/directive-types": "^0.69.0",
|
|
250
254
|
"archiver": "^8.0.0"
|
|
251
255
|
},
|
|
252
256
|
"scripts": {
|