@deftai/directive-core 0.83.0 → 0.85.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/cache/fetch.d.ts +17 -0
- package/dist/cache/fetch.js +50 -0
- package/dist/cache/main.js +36 -2
- package/dist/cache/task-cache/constants.d.ts +4 -0
- package/dist/cache/task-cache/constants.js +4 -0
- package/dist/cache/task-cache/executor.d.ts +9 -0
- package/dist/cache/task-cache/executor.js +51 -0
- package/dist/cache/task-cache/hash.d.ts +17 -0
- package/dist/cache/task-cache/hash.js +92 -0
- package/dist/cache/task-cache/index.d.ts +14 -0
- package/dist/cache/task-cache/index.js +15 -0
- package/dist/cache/task-cache/lint.d.ts +4 -0
- package/dist/cache/task-cache/lint.js +55 -0
- package/dist/cache/task-cache/registry.d.ts +7 -0
- package/dist/cache/task-cache/registry.js +67 -0
- package/dist/cache/task-cache/store.d.ts +10 -0
- package/dist/cache/task-cache/store.js +48 -0
- package/dist/cache/task-cache/types.d.ts +48 -0
- package/dist/cache/task-cache/types.js +3 -0
- package/dist/check/cached-orchestrator.d.ts +16 -0
- package/dist/check/cached-orchestrator.js +76 -0
- package/dist/check/context.d.ts +30 -0
- package/dist/check/context.js +28 -0
- package/dist/check/gate-lists.d.ts +18 -0
- package/dist/check/gate-lists.js +68 -0
- package/dist/check/index.d.ts +4 -1
- package/dist/check/index.js +3 -0
- package/dist/check/orchestrator.d.ts +3 -45
- package/dist/check/orchestrator.js +8 -46
- package/dist/check/runner-detect.d.ts +20 -0
- package/dist/check/runner-detect.js +131 -0
- package/dist/doctor/checks.js +16 -1
- package/dist/doctor/constants.d.ts +2 -0
- package/dist/doctor/constants.js +8 -4
- package/dist/doctor/index.d.ts +1 -0
- package/dist/doctor/index.js +1 -0
- package/dist/doctor/main.js +13 -4
- package/dist/doctor/npm-registry.d.ts +23 -0
- package/dist/doctor/npm-registry.js +128 -0
- package/dist/doctor/npm-view.d.ts +10 -0
- package/dist/doctor/npm-view.js +31 -0
- package/dist/doctor/payload-staleness.js +2 -9
- package/dist/doctor/signpost-checks.d.ts +2 -1
- package/dist/doctor/signpost-checks.js +2 -0
- package/dist/doctor/types.d.ts +9 -0
- package/dist/eval/readback.js +6 -1
- package/dist/eval-health-relocation/evaluate.js +15 -1
- package/dist/fs/projection-containment.js +1 -1
- package/dist/hooks/cursor-hooks.d.ts +6 -20
- package/dist/hooks/cursor-hooks.js +7 -92
- package/dist/hooks/dispatcher.d.ts +2 -0
- package/dist/hooks/dispatcher.js +48 -6
- package/dist/init-deposit/agent-hooks.d.ts +2 -2
- package/dist/init-deposit/agent-hooks.js +15 -37
- package/dist/init-deposit/gitignore.js +1 -0
- package/dist/init-deposit/hygiene.d.ts +22 -0
- package/dist/init-deposit/hygiene.js +136 -4
- package/dist/init-deposit/legacy-detect.d.ts +25 -1
- package/dist/init-deposit/legacy-detect.js +143 -11
- package/dist/init-deposit/refresh.d.ts +2 -0
- package/dist/init-deposit/refresh.js +18 -5
- package/dist/policy/index.d.ts +2 -0
- package/dist/policy/index.js +2 -0
- package/dist/policy/org-force-on-migration.d.ts +44 -0
- package/dist/policy/org-force-on-migration.js +240 -0
- package/dist/policy/product-signal.d.ts +3 -1
- package/dist/policy/product-signal.js +15 -4
- package/dist/policy/value-feedback.d.ts +18 -1
- package/dist/policy/value-feedback.js +78 -5
- package/dist/preflight-cache/evaluate.js +12 -1
- package/dist/product-signal/consent-prompt.d.ts +13 -0
- package/dist/product-signal/consent-prompt.js +30 -0
- package/dist/product-signal/submit.js +22 -1
- package/dist/render/index.d.ts +1 -0
- package/dist/render/index.js +1 -0
- package/dist/render/rule-map-template.d.ts +2 -0
- package/dist/render/rule-map-template.js +407 -0
- package/dist/render/rule-map.d.ts +2 -0
- package/dist/render/rule-map.js +703 -0
- package/dist/review-monitor/constants.d.ts +7 -1
- package/dist/review-monitor/constants.js +40 -14
- package/dist/review-monitor/github-lease.d.ts +45 -0
- package/dist/review-monitor/github-lease.js +106 -0
- package/dist/review-monitor/index.d.ts +2 -0
- package/dist/review-monitor/index.js +2 -0
- package/dist/review-monitor/lease-comment.d.ts +36 -0
- package/dist/review-monitor/lease-comment.js +152 -0
- package/dist/review-monitor/record.d.ts +61 -13
- package/dist/review-monitor/record.js +379 -132
- package/dist/review-monitor/verify.d.ts +2 -0
- package/dist/review-monitor/verify.js +32 -13
- package/dist/scm/gh-rest.d.ts +7 -1
- package/dist/scm/gh-rest.js +35 -0
- package/dist/scope/decompose.js +9 -3
- package/dist/session/git.d.ts +2 -0
- package/dist/session/git.js +14 -0
- package/dist/session/session-start.js +5 -0
- package/dist/session/verify-session-ritual.js +39 -5
- package/dist/swarm/routing-set-cli.js +16 -5
- package/dist/swarm/routing.d.ts +1 -1
- package/dist/swarm/routing.js +3 -1
- package/dist/task-surface/index.js +53 -13
- package/dist/value/readback.js +6 -1
- package/dist/xbrief-migrate/constants.d.ts +6 -0
- package/dist/xbrief-migrate/constants.js +6 -0
- package/dist/xbrief-migrate/index.d.ts +2 -2
- package/dist/xbrief-migrate/index.js +2 -2
- package/dist/xbrief-migrate/migrate-project.d.ts +7 -0
- package/dist/xbrief-migrate/migrate-project.js +18 -1
- package/package.json +7 -3
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { assertDepositContained } from "../deposit/contain.js";
|
|
4
|
-
import { assertCursorApplyPatchMatchersDisjoint, CURSOR_APPLY_PATCH_ADAPTER_RELATIVE, CURSOR_APPLY_PATCH_ADAPTER_SOURCE, CURSOR_GENERIC_WRITE_HOOK_MATCHER, cursorApplyPatchAdapterEntry, DEFT_CURSOR_ADAPTER_COMMAND_MARKER, } from "../hooks/cursor-hooks.js";
|
|
5
4
|
import { DIRECT_WRITE_HOOK_MATCHER, SPAWN_HOOK_MATCHER } from "../hooks/tools.js";
|
|
6
5
|
import { isHostHookDepositEnabled, loadHostHooksPolicyFromProject, } from "../policy/host-hooks.js";
|
|
7
|
-
export { CURSOR_GENERIC_WRITE_HOOK_MATCHER, DEFT_CURSOR_ADAPTER_COMMAND_MARKER, } from "../hooks/cursor-hooks.js";
|
|
8
6
|
export { DIRECT_WRITE_HOOK_MATCHER, SPAWN_HOOK_MATCHER } from "../hooks/tools.js";
|
|
9
|
-
export const DEFT_HOOK_COMMAND_MARKER = "deft
|
|
7
|
+
export const DEFT_HOOK_COMMAND_MARKER = "deft-hook";
|
|
8
|
+
export const LEGACY_DEFT_HOOK_COMMAND_MARKER = "deft hook:dispatch";
|
|
10
9
|
export const AGENT_HOOK_PATHS = [
|
|
11
10
|
".claude/settings.json",
|
|
12
11
|
".grok/hooks/deft.json",
|
|
@@ -64,17 +63,21 @@ function nestedCommands(value) {
|
|
|
64
63
|
});
|
|
65
64
|
}
|
|
66
65
|
function isManagedNestedGroup(value) {
|
|
67
|
-
return nestedCommands(value).some((
|
|
66
|
+
return nestedCommands(value).some((command) => command.includes(DEFT_HOOK_COMMAND_MARKER) ||
|
|
67
|
+
command.includes(LEGACY_DEFT_HOOK_COMMAND_MARKER));
|
|
68
68
|
}
|
|
69
69
|
function isManagedNestedGroupForHost(value, host) {
|
|
70
|
-
return nestedCommands(value).some((command) => command.includes(DEFT_HOOK_COMMAND_MARKER)
|
|
70
|
+
return nestedCommands(value).some((command) => (command.includes(DEFT_HOOK_COMMAND_MARKER) ||
|
|
71
|
+
command.includes(LEGACY_DEFT_HOOK_COMMAND_MARKER)) &&
|
|
72
|
+
command.includes(`--host ${host}`));
|
|
71
73
|
}
|
|
72
74
|
function isManagedCursorEntry(value) {
|
|
73
75
|
const entry = object(value);
|
|
74
76
|
if (typeof entry?.command !== "string")
|
|
75
77
|
return false;
|
|
76
78
|
return (entry.command.includes(DEFT_HOOK_COMMAND_MARKER) ||
|
|
77
|
-
entry.command.includes(
|
|
79
|
+
entry.command.includes(LEGACY_DEFT_HOOK_COMMAND_MARKER) ||
|
|
80
|
+
entry.command.includes("deft-cursor-hook-adapter.mjs"));
|
|
78
81
|
}
|
|
79
82
|
function isManagedCursorEntryForHost(value) {
|
|
80
83
|
return isManagedCursorEntry(value);
|
|
@@ -142,7 +145,6 @@ function stripManagedCursorConfig(config, path) {
|
|
|
142
145
|
return { ...config, version: 1, hooks: nextHooks };
|
|
143
146
|
}
|
|
144
147
|
function mergeCursorConfig(config, path) {
|
|
145
|
-
assertCursorApplyPatchMatchersDisjoint();
|
|
146
148
|
const hooks = hooksObject(config, path);
|
|
147
149
|
const session = eventArray(hooks, "sessionStart", path).filter((entry) => !isManagedCursorEntry(entry));
|
|
148
150
|
const preTool = eventArray(hooks, "preToolUse", path).filter((entry) => !isManagedCursorEntry(entry));
|
|
@@ -150,10 +152,9 @@ function mergeCursorConfig(config, path) {
|
|
|
150
152
|
hooks.sessionStart = [...session, { command: command("cursor", "session.start"), timeout: 5 }];
|
|
151
153
|
hooks.preToolUse = [
|
|
152
154
|
...preTool,
|
|
153
|
-
cursorApplyPatchAdapterEntry(),
|
|
154
155
|
{
|
|
155
156
|
command: command("cursor", "tool.before"),
|
|
156
|
-
matcher:
|
|
157
|
+
matcher: DIRECT_WRITE_HOOK_MATCHER,
|
|
157
158
|
failClosed: true,
|
|
158
159
|
timeout: 5,
|
|
159
160
|
},
|
|
@@ -167,15 +168,6 @@ function mergeCursorConfig(config, path) {
|
|
|
167
168
|
hooks.preCompact = [...preCompact, { command: command("cursor", "session.compact"), timeout: 5 }];
|
|
168
169
|
return { ...config, version: 1, hooks };
|
|
169
170
|
}
|
|
170
|
-
function writeTextIfChanged(path, contents) {
|
|
171
|
-
if (existsSync(path) && readFileSync(path, "utf8") === contents)
|
|
172
|
-
return false;
|
|
173
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
174
|
-
const temporary = `${path}.deft-${process.pid}.tmp`;
|
|
175
|
-
writeFileSync(temporary, contents, "utf8");
|
|
176
|
-
renameSync(temporary, path);
|
|
177
|
-
return true;
|
|
178
|
-
}
|
|
179
171
|
function writeJsonIfChanged(path, payload) {
|
|
180
172
|
const next = `${JSON.stringify(payload, null, 2)}\n`;
|
|
181
173
|
if (existsSync(path) && readFileSync(path, "utf8") === next)
|
|
@@ -246,19 +238,12 @@ export function writeAgentHookDeposit(projectRoot, io = { printf: () => undefine
|
|
|
246
238
|
changedPaths.push(item.path);
|
|
247
239
|
}
|
|
248
240
|
}
|
|
249
|
-
const adapterAbsolute = join(projectRoot,
|
|
241
|
+
const adapterAbsolute = join(projectRoot, ".cursor/hooks/deft-cursor-hook-adapter.mjs");
|
|
250
242
|
assertDepositContained(projectRoot, adapterAbsolute);
|
|
251
|
-
if (
|
|
252
|
-
if (writeTextIfChanged(adapterAbsolute, CURSOR_APPLY_PATCH_ADAPTER_SOURCE)) {
|
|
253
|
-
if (!changedPaths.includes(AGENT_HOOK_PATHS[2])) {
|
|
254
|
-
changedPaths.push(AGENT_HOOK_PATHS[2]);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
else if (existsSync(adapterAbsolute)) {
|
|
243
|
+
if (existsSync(adapterAbsolute)) {
|
|
259
244
|
rmSync(adapterAbsolute, { force: true });
|
|
260
|
-
if (!
|
|
261
|
-
|
|
245
|
+
if (!changedPaths.includes(AGENT_HOOK_PATHS[2])) {
|
|
246
|
+
changedPaths.push(AGENT_HOOK_PATHS[2]);
|
|
262
247
|
}
|
|
263
248
|
}
|
|
264
249
|
if (changedPaths.length > 0) {
|
|
@@ -309,18 +294,11 @@ function hasCursorRegistration(config) {
|
|
|
309
294
|
const session = Array.isArray(hooks.sessionStart) ? hooks.sessionStart : [];
|
|
310
295
|
const preTool = Array.isArray(hooks.preToolUse) ? hooks.preToolUse : [];
|
|
311
296
|
const preCompact = Array.isArray(hooks.preCompact) ? hooks.preCompact : [];
|
|
312
|
-
const adapter = cursorApplyPatchAdapterEntry();
|
|
313
297
|
return (session.some((entry) => object(entry)?.command === command("cursor", "session.start")) &&
|
|
314
298
|
preTool.some((entry) => {
|
|
315
299
|
const hook = object(entry);
|
|
316
300
|
return (hook?.command === command("cursor", "tool.before") &&
|
|
317
|
-
hook.matcher ===
|
|
318
|
-
hook.failClosed === true);
|
|
319
|
-
}) &&
|
|
320
|
-
preTool.some((entry) => {
|
|
321
|
-
const hook = object(entry);
|
|
322
|
-
return (hook?.command === adapter.command &&
|
|
323
|
-
hook.matcher === adapter.matcher &&
|
|
301
|
+
hook.matcher === DIRECT_WRITE_HOOK_MATCHER &&
|
|
324
302
|
hook.failClosed === true);
|
|
325
303
|
}) &&
|
|
326
304
|
preTool.some((entry) => {
|
|
@@ -57,6 +57,28 @@ export declare function stageFrameworkPaths(projectDir: string, paths: readonly
|
|
|
57
57
|
* Refs #2347.
|
|
58
58
|
*/
|
|
59
59
|
export declare const STRAY_DEPOSIT_FRAMEWORK_PATHS: readonly ["packages"];
|
|
60
|
+
/**
|
|
61
|
+
* Deposit-local files generated by init/update that are intentionally absent
|
|
62
|
+
* from `@deftai/directive-content` (#2804).
|
|
63
|
+
*/
|
|
64
|
+
export declare const DEPOSIT_GENERATED_METADATA_PATHS: readonly ["VERSION"];
|
|
65
|
+
export declare function isDepositGeneratedMetadata(relPath: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* List deposit-relative paths that are absent from the installed content package,
|
|
68
|
+
* excluding generated deposit metadata such as `VERSION` (#2804).
|
|
69
|
+
*/
|
|
70
|
+
export declare function findPackageAbsentDepositPathsSync(deftDir: string, contentRoot: string): string[];
|
|
71
|
+
export declare function findPackageAbsentDepositPaths(deftDir: string, contentRoot: string): Promise<string[]>;
|
|
72
|
+
export interface PrunePackageAbsentDepositPathsResult {
|
|
73
|
+
readonly pruned: string[];
|
|
74
|
+
readonly prunedDirs: string[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Remove deposit files not shipped by `@deftai/directive-content`, preserving
|
|
78
|
+
* generated deposit metadata such as `VERSION` (#2804). Subsumes the legacy
|
|
79
|
+
* hard-coded `packages/` prune (#2347).
|
|
80
|
+
*/
|
|
81
|
+
export declare function prunePackageAbsentDepositPaths(deftDir: string, contentRoot: string, io: InitDepositIo): Promise<PrunePackageAbsentDepositPathsResult>;
|
|
60
82
|
export interface PruneStrayDepositPathsResult {
|
|
61
83
|
readonly pruned: string[];
|
|
62
84
|
}
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* Refs #1576, #1453, #1430.
|
|
6
6
|
*/
|
|
7
7
|
import { execFileSync } from "node:child_process";
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
9
|
-
import { rm, stat } from "node:fs/promises";
|
|
10
|
-
import { join, relative } from "node:path";
|
|
8
|
+
import { existsSync, readdirSync, rmSync } from "node:fs";
|
|
9
|
+
import { readdir, rm, stat } from "node:fs/promises";
|
|
10
|
+
import { dirname, join, relative } from "node:path";
|
|
11
11
|
import { gitPorcelain } from "../story-ready/git.js";
|
|
12
12
|
import { CANONICAL_INSTALL_ROOT } from "./constants.js";
|
|
13
13
|
export const CODEQL_CONFIG_REL = ".github/codeql/codeql-config.yml";
|
|
@@ -24,7 +24,6 @@ export function installerManagedMatchers() {
|
|
|
24
24
|
{ exact: ".claude/settings.json" },
|
|
25
25
|
{ exact: ".grok/hooks/deft.json" },
|
|
26
26
|
{ exact: ".cursor/hooks.json" },
|
|
27
|
-
{ exact: ".cursor/hooks/deft-cursor-hook-adapter.mjs" },
|
|
28
27
|
{ exact: ".codex/hooks.json" },
|
|
29
28
|
{ exact: ".gitattributes" },
|
|
30
29
|
{ exact: ".gitignore" },
|
|
@@ -146,6 +145,139 @@ export function stageFrameworkPaths(projectDir, paths, seams = {}) {
|
|
|
146
145
|
* Refs #2347.
|
|
147
146
|
*/
|
|
148
147
|
export const STRAY_DEPOSIT_FRAMEWORK_PATHS = ["packages"];
|
|
148
|
+
/**
|
|
149
|
+
* Deposit-local files generated by init/update that are intentionally absent
|
|
150
|
+
* from `@deftai/directive-content` (#2804).
|
|
151
|
+
*/
|
|
152
|
+
export const DEPOSIT_GENERATED_METADATA_PATHS = ["VERSION"];
|
|
153
|
+
export function isDepositGeneratedMetadata(relPath) {
|
|
154
|
+
const normalized = relPath.replace(/\\/g, "/");
|
|
155
|
+
return DEPOSIT_GENERATED_METADATA_PATHS.includes(normalized);
|
|
156
|
+
}
|
|
157
|
+
function normalizeRelativePath(relPath) {
|
|
158
|
+
return relPath.replace(/\\/g, "/");
|
|
159
|
+
}
|
|
160
|
+
function listRelativeFilePathsSync(root) {
|
|
161
|
+
if (!existsSync(root))
|
|
162
|
+
return [];
|
|
163
|
+
const results = [];
|
|
164
|
+
const walk = (dir, prefix) => {
|
|
165
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
166
|
+
const rel = normalizeRelativePath(prefix ? `${prefix}/${entry.name}` : entry.name);
|
|
167
|
+
const abs = join(dir, entry.name);
|
|
168
|
+
if (entry.isSymbolicLink())
|
|
169
|
+
continue;
|
|
170
|
+
if (entry.isDirectory()) {
|
|
171
|
+
walk(abs, rel);
|
|
172
|
+
}
|
|
173
|
+
else if (entry.isFile()) {
|
|
174
|
+
results.push(rel);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
walk(root, "");
|
|
179
|
+
return results;
|
|
180
|
+
}
|
|
181
|
+
async function listRelativeFilePaths(root) {
|
|
182
|
+
if (!existsSync(root))
|
|
183
|
+
return [];
|
|
184
|
+
const results = [];
|
|
185
|
+
const walk = async (dir, prefix) => {
|
|
186
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
187
|
+
for (const entry of entries) {
|
|
188
|
+
const rel = normalizeRelativePath(prefix ? `${prefix}/${entry.name}` : entry.name);
|
|
189
|
+
const abs = join(dir, entry.name);
|
|
190
|
+
if (entry.isSymbolicLink())
|
|
191
|
+
continue;
|
|
192
|
+
if (entry.isDirectory()) {
|
|
193
|
+
await walk(abs, rel);
|
|
194
|
+
}
|
|
195
|
+
else if (entry.isFile()) {
|
|
196
|
+
results.push(rel);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
await walk(root, "");
|
|
201
|
+
return results;
|
|
202
|
+
}
|
|
203
|
+
function contentDirectoryPaths(contentFiles) {
|
|
204
|
+
const dirs = new Set();
|
|
205
|
+
for (const file of contentFiles) {
|
|
206
|
+
let dir = dirname(file);
|
|
207
|
+
while (dir && dir !== ".") {
|
|
208
|
+
dirs.add(normalizeRelativePath(dir));
|
|
209
|
+
const parent = dirname(dir);
|
|
210
|
+
if (parent === dir)
|
|
211
|
+
break;
|
|
212
|
+
dir = parent;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return dirs;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* List deposit-relative paths that are absent from the installed content package,
|
|
219
|
+
* excluding generated deposit metadata such as `VERSION` (#2804).
|
|
220
|
+
*/
|
|
221
|
+
export function findPackageAbsentDepositPathsSync(deftDir, contentRoot) {
|
|
222
|
+
const depositFiles = listRelativeFilePathsSync(deftDir);
|
|
223
|
+
const contentFiles = new Set(listRelativeFilePathsSync(contentRoot));
|
|
224
|
+
return depositFiles
|
|
225
|
+
.filter((rel) => !contentFiles.has(rel) && !isDepositGeneratedMetadata(rel))
|
|
226
|
+
.sort();
|
|
227
|
+
}
|
|
228
|
+
export async function findPackageAbsentDepositPaths(deftDir, contentRoot) {
|
|
229
|
+
const depositFiles = await listRelativeFilePaths(deftDir);
|
|
230
|
+
const contentFiles = new Set(await listRelativeFilePaths(contentRoot));
|
|
231
|
+
return depositFiles
|
|
232
|
+
.filter((rel) => !contentFiles.has(rel) && !isDepositGeneratedMetadata(rel))
|
|
233
|
+
.sort();
|
|
234
|
+
}
|
|
235
|
+
async function pruneEmptyParentsForFile(deftDir, contentDirs, relFile) {
|
|
236
|
+
const prunedDirs = [];
|
|
237
|
+
let rel = dirname(relFile);
|
|
238
|
+
while (rel && rel !== ".") {
|
|
239
|
+
const normalized = normalizeRelativePath(rel);
|
|
240
|
+
if (contentDirs.has(normalized))
|
|
241
|
+
break;
|
|
242
|
+
const abs = join(deftDir, rel);
|
|
243
|
+
try {
|
|
244
|
+
if (!existsSync(abs) || readdirSync(abs).length !== 0)
|
|
245
|
+
break;
|
|
246
|
+
rmSync(abs, { recursive: false, force: true });
|
|
247
|
+
prunedDirs.push(normalized);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
rel = dirname(rel);
|
|
253
|
+
}
|
|
254
|
+
return prunedDirs;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Remove deposit files not shipped by `@deftai/directive-content`, preserving
|
|
258
|
+
* generated deposit metadata such as `VERSION` (#2804). Subsumes the legacy
|
|
259
|
+
* hard-coded `packages/` prune (#2347).
|
|
260
|
+
*/
|
|
261
|
+
export async function prunePackageAbsentDepositPaths(deftDir, contentRoot, io) {
|
|
262
|
+
const absent = await findPackageAbsentDepositPaths(deftDir, contentRoot);
|
|
263
|
+
const contentDirs = contentDirectoryPaths(listRelativeFilePathsSync(contentRoot));
|
|
264
|
+
const pruned = [];
|
|
265
|
+
const prunedDirs = [];
|
|
266
|
+
for (const rel of absent) {
|
|
267
|
+
try {
|
|
268
|
+
rmSync(join(deftDir, rel), { force: true });
|
|
269
|
+
pruned.push(rel);
|
|
270
|
+
prunedDirs.push(...(await pruneEmptyParentsForFile(deftDir, contentDirs, rel)));
|
|
271
|
+
}
|
|
272
|
+
catch (cause) {
|
|
273
|
+
io.printf(`Warning: could not prune .deft/core/${rel}: ${String(cause)}\n`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (pruned.length > 0) {
|
|
277
|
+
io.printf(`Pruned ${pruned.length} package-absent deposit file(s) not shipped by @deftai/directive-content (#2804).\n`);
|
|
278
|
+
}
|
|
279
|
+
return { pruned, prunedDirs };
|
|
280
|
+
}
|
|
149
281
|
/**
|
|
150
282
|
* Remove framework-source subdirectories from `.deft/core/` that are not
|
|
151
283
|
* present in the deposited content package (#2347). Silently skips any path
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
/** Non-zero exit code for a use-time legacy-layout refusal (needs-action). */
|
|
27
27
|
export declare const LEGACY_LAYOUT_REFUSED_EXIT_CODE = 2;
|
|
28
|
-
export type LegacyLayoutKind = "orphan-deft-version" | "legacy-deft-prefixed" | "git-clone-or-submodule" | "pre-v0.27-sentinel-agents-md";
|
|
28
|
+
export type LegacyLayoutKind = "orphan-deft-version" | "legacy-deft-prefixed" | "git-clone-or-submodule" | "pre-v0.27-sentinel-agents-md" | "dual-layout";
|
|
29
29
|
export interface LegacyLayoutDetection {
|
|
30
30
|
readonly legacy: boolean;
|
|
31
31
|
readonly kind: LegacyLayoutKind | null;
|
|
@@ -37,6 +37,12 @@ export interface LegacyDetectSeams {
|
|
|
37
37
|
readonly isDir?: (p: string) => boolean;
|
|
38
38
|
readonly readText?: (p: string) => string | null;
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Detect a post-bridge dual-layout: canonical `.deft/core/` plus a leftover
|
|
42
|
+
* framework-marked `deft/` tree. Doctor-only -- the npm deposit path treats
|
|
43
|
+
* `.deft/core/` as canonical and must not refuse here (#2805 / #2804 wiring).
|
|
44
|
+
*/
|
|
45
|
+
export declare function detectDualLayout(projectDir: string, seams?: LegacyDetectSeams): LegacyLayoutDetection | null;
|
|
40
46
|
/**
|
|
41
47
|
* Classify the on-disk layout at `projectDir`. Returns `legacy: false` for the
|
|
42
48
|
* canonical `.deft/core/` vendored layout and for a greenfield project (so init
|
|
@@ -58,4 +64,22 @@ export declare function buildLegacyRefusalMessage(command: "init" | "update", de
|
|
|
58
64
|
export declare function buildLegacyRefusalJson(command: "init" | "update", projectDir: string, detection: LegacyLayoutDetection): Record<string, unknown>;
|
|
59
65
|
/** One-line doctor signpost carrying the stable URL (no baked version/command). */
|
|
60
66
|
export declare function legacyLayoutSignpostLine(detection: LegacyLayoutDetection): string;
|
|
67
|
+
/** Doctor / npm signpost for the post-bridge dual-layout state (#2805). */
|
|
68
|
+
export declare function dualLayoutSignpostLine(detection: LegacyLayoutDetection): string;
|
|
69
|
+
export interface LegacyDeftCleanupSeams {
|
|
70
|
+
readonly gitPorcelain?: (projectRoot: string) => string | null;
|
|
71
|
+
readonly runGitRm?: (projectDir: string, relPath: string) => void;
|
|
72
|
+
readonly removeDir?: (absPath: string) => void;
|
|
73
|
+
}
|
|
74
|
+
export type LegacyDeftCleanupAction = "removed" | "staged" | "refused" | "skipped";
|
|
75
|
+
export interface LegacyDeftCleanupResult {
|
|
76
|
+
readonly ok: boolean;
|
|
77
|
+
readonly action: LegacyDeftCleanupAction;
|
|
78
|
+
readonly detail: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Remove a clean tracked legacy `deft/` tree after bridge migration (#2805).
|
|
82
|
+
* Refuses when the tree has local modifications or untracked files.
|
|
83
|
+
*/
|
|
84
|
+
export declare function tryCleanupLegacyDeftTree(projectDir: string, seams?: LegacyDeftCleanupSeams): LegacyDeftCleanupResult;
|
|
61
85
|
//# sourceMappingURL=legacy-detect.d.ts.map
|
|
@@ -23,11 +23,13 @@
|
|
|
23
23
|
*
|
|
24
24
|
* Refs #1912, #1669.
|
|
25
25
|
*/
|
|
26
|
-
import {
|
|
26
|
+
import { execFileSync } from "node:child_process";
|
|
27
|
+
import { rmSync, statSync } from "node:fs";
|
|
27
28
|
import { join } from "node:path";
|
|
28
29
|
import { GO_BRIDGE_RELEASES_URL, UPGRADING_DOC_URL } from "../doctor/constants.js";
|
|
29
30
|
import { extractManagedSection, parseInstallRootFromAgentsMd } from "../doctor/manifest.js";
|
|
30
31
|
import { readTextSafe } from "../doctor/paths.js";
|
|
32
|
+
import { gitPorcelain } from "../story-ready/git.js";
|
|
31
33
|
/** Non-zero exit code for a use-time legacy-layout refusal (needs-action). */
|
|
32
34
|
export const LEGACY_LAYOUT_REFUSED_EXIT_CODE = 2;
|
|
33
35
|
const NOT_LEGACY = {
|
|
@@ -53,6 +55,16 @@ function defaultIsDir(p) {
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
/** Does `.gitmodules` reference the deft framework at a deft install path? */
|
|
58
|
+
const LEGACY_DEFT_DIR = "deft";
|
|
59
|
+
function isFrameworkDeftDir(projectDir, isDir, isFile) {
|
|
60
|
+
const deftDir = join(projectDir, LEGACY_DEFT_DIR);
|
|
61
|
+
const deftMarkers = [
|
|
62
|
+
join(deftDir, "VERSION"),
|
|
63
|
+
join(deftDir, "main.md"),
|
|
64
|
+
join(deftDir, "Taskfile.yml"),
|
|
65
|
+
];
|
|
66
|
+
return isDir(deftDir) && (deftMarkers.some((m) => isFile(m)) || isDir(join(deftDir, "skills")));
|
|
67
|
+
}
|
|
56
68
|
function gitmodulesReferencesFramework(text) {
|
|
57
69
|
const normalized = text.replace(/\r\n/g, "\n").toLowerCase();
|
|
58
70
|
if (normalized.includes("deftai/directive")) {
|
|
@@ -62,6 +74,27 @@ function gitmodulesReferencesFramework(text) {
|
|
|
62
74
|
// when the url host differs (mirror, fork). Match `path = deft` / `path = .deft`.
|
|
63
75
|
return /(^|\n)\s*path\s*=\s*\.?deft(\/|\s|$)/.test(normalized);
|
|
64
76
|
}
|
|
77
|
+
const DUAL_LAYOUT_DETAIL = "Found both the canonical .deft/core/ deposit and a leftover legacy deft/ " +
|
|
78
|
+
"framework tree -- remove deft/ so .deft/core/ is the sole framework root.";
|
|
79
|
+
/**
|
|
80
|
+
* Detect a post-bridge dual-layout: canonical `.deft/core/` plus a leftover
|
|
81
|
+
* framework-marked `deft/` tree. Doctor-only -- the npm deposit path treats
|
|
82
|
+
* `.deft/core/` as canonical and must not refuse here (#2805 / #2804 wiring).
|
|
83
|
+
*/
|
|
84
|
+
export function detectDualLayout(projectDir, seams = {}) {
|
|
85
|
+
const isFile = seams.isFile ?? defaultIsFile;
|
|
86
|
+
const isDir = seams.isDir ?? defaultIsDir;
|
|
87
|
+
const hasCanonicalCore = isDir(join(projectDir, ".deft", "core"));
|
|
88
|
+
if (!hasCanonicalCore || !isFrameworkDeftDir(projectDir, isDir, isFile)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
legacy: true,
|
|
93
|
+
kind: "dual-layout",
|
|
94
|
+
detail: DUAL_LAYOUT_DETAIL,
|
|
95
|
+
evidence: [".deft/core/", "deft/"],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
65
98
|
/**
|
|
66
99
|
* Classify the on-disk layout at `projectDir`. Returns `legacy: false` for the
|
|
67
100
|
* canonical `.deft/core/` vendored layout and for a greenfield project (so init
|
|
@@ -71,10 +104,11 @@ export function detectLegacyLayout(projectDir, seams = {}) {
|
|
|
71
104
|
const isFile = seams.isFile ?? defaultIsFile;
|
|
72
105
|
const isDir = seams.isDir ?? defaultIsDir;
|
|
73
106
|
const readText = seams.readText ?? readTextSafe;
|
|
107
|
+
const hasCanonicalCore = isDir(join(projectDir, ".deft", "core"));
|
|
108
|
+
const deftDirIsFramework = isFrameworkDeftDir(projectDir, isDir, isFile);
|
|
74
109
|
// Canonical vendored layout present -> the npm path owns it; not legacy. Any
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
if (isDir(join(projectDir, ".deft", "core"))) {
|
|
110
|
+
// leftover deft/ tree is a dual-layout hygiene issue surfaced by Doctor only.
|
|
111
|
+
if (hasCanonicalCore) {
|
|
78
112
|
return NOT_LEGACY;
|
|
79
113
|
}
|
|
80
114
|
// Orphan `.deft/VERSION` (the old pre-`.deft/core/` manifest location) with no
|
|
@@ -92,13 +126,7 @@ export function detectLegacyLayout(projectDir, seams = {}) {
|
|
|
92
126
|
// framework markers. Distinguish a git-clone / submodule deposit (a `.git`
|
|
93
127
|
// inside `deft/`, or a `.gitmodules` pointing at the framework) from a plain
|
|
94
128
|
// legacy-prefixed vendored copy.
|
|
95
|
-
const deftDir = join(projectDir,
|
|
96
|
-
const deftMarkers = [
|
|
97
|
-
join(deftDir, "VERSION"),
|
|
98
|
-
join(deftDir, "main.md"),
|
|
99
|
-
join(deftDir, "Taskfile.yml"),
|
|
100
|
-
];
|
|
101
|
-
const deftDirIsFramework = isDir(deftDir) && (deftMarkers.some((m) => isFile(m)) || isDir(join(deftDir, "skills")));
|
|
129
|
+
const deftDir = join(projectDir, LEGACY_DEFT_DIR);
|
|
102
130
|
if (deftDirIsFramework) {
|
|
103
131
|
const submoduleGit = isFile(join(deftDir, ".git")) || isDir(join(deftDir, ".git"));
|
|
104
132
|
if (submoduleGit) {
|
|
@@ -215,9 +243,113 @@ export function buildLegacyRefusalJson(command, projectDir, detection) {
|
|
|
215
243
|
}
|
|
216
244
|
/** One-line doctor signpost carrying the stable URL (no baked version/command). */
|
|
217
245
|
export function legacyLayoutSignpostLine(detection) {
|
|
246
|
+
if (detection.kind === "dual-layout") {
|
|
247
|
+
return dualLayoutSignpostLine(detection);
|
|
248
|
+
}
|
|
218
249
|
return (`Legacy Deft layout detected (${detection.kind ?? "unknown"}): ${detection.detail} ` +
|
|
219
250
|
"Run the frozen Go bridge installer to migrate to .deft/core/, then use the npm " +
|
|
220
251
|
`CLI (\`npx @deftai/directive update\`). See ${UPGRADING_DOC_URL} ` +
|
|
221
252
|
`(frozen bridge: ${GO_BRIDGE_RELEASES_URL}).`);
|
|
222
253
|
}
|
|
254
|
+
/** Doctor / npm signpost for the post-bridge dual-layout state (#2805). */
|
|
255
|
+
export function dualLayoutSignpostLine(detection) {
|
|
256
|
+
return (`Dual Deft layout detected (${detection.kind ?? "dual-layout"}): ${detection.detail} ` +
|
|
257
|
+
"Remove the legacy deft/ tree so .deft/core/ is the sole framework root " +
|
|
258
|
+
"(when clean: `git rm -r deft/`; reconcile local edits first if `git status deft/` is dirty). " +
|
|
259
|
+
`See ${UPGRADING_DOC_URL}.`);
|
|
260
|
+
}
|
|
261
|
+
function porcelainEntryPath(line) {
|
|
262
|
+
let path = line.slice(3).trim().replace(/\\/g, "/");
|
|
263
|
+
if (path.startsWith('"') && path.endsWith('"')) {
|
|
264
|
+
path = path.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
265
|
+
}
|
|
266
|
+
return path;
|
|
267
|
+
}
|
|
268
|
+
function porcelainTouchesLegacyDeft(porcelain) {
|
|
269
|
+
const touched = [];
|
|
270
|
+
for (const line of porcelain.split("\n")) {
|
|
271
|
+
if (!line.trim())
|
|
272
|
+
continue;
|
|
273
|
+
const path = porcelainEntryPath(line);
|
|
274
|
+
if (path === LEGACY_DEFT_DIR || path.startsWith(`${LEGACY_DEFT_DIR}/`)) {
|
|
275
|
+
touched.push(path);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return touched;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Remove a clean tracked legacy `deft/` tree after bridge migration (#2805).
|
|
282
|
+
* Refuses when the tree has local modifications or untracked files.
|
|
283
|
+
*/
|
|
284
|
+
export function tryCleanupLegacyDeftTree(projectDir, seams = {}) {
|
|
285
|
+
const detection = detectDualLayout(projectDir);
|
|
286
|
+
if (detection === null) {
|
|
287
|
+
return {
|
|
288
|
+
ok: true,
|
|
289
|
+
action: "skipped",
|
|
290
|
+
detail: "No dual-layout legacy deft/ tree to remove.",
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const readPorcelain = seams.gitPorcelain ?? gitPorcelain;
|
|
294
|
+
const porcelain = readPorcelain(projectDir);
|
|
295
|
+
if (porcelain === null) {
|
|
296
|
+
return {
|
|
297
|
+
ok: false,
|
|
298
|
+
action: "refused",
|
|
299
|
+
detail: "Cannot determine whether the legacy deft/ tree is clean (git unavailable). " +
|
|
300
|
+
"Inspect `git status deft/` and remove the tree manually once clean.",
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
const dirtyPaths = porcelainTouchesLegacyDeft(porcelain);
|
|
304
|
+
if (dirtyPaths.length > 0) {
|
|
305
|
+
return {
|
|
306
|
+
ok: false,
|
|
307
|
+
action: "refused",
|
|
308
|
+
detail: "Refusing to remove the legacy deft/ tree because it has local modifications or " +
|
|
309
|
+
"untracked files. Reconcile or commit those changes, then re-run " +
|
|
310
|
+
"`npx @deftai/directive update`, or remove deft/ manually once clean. " +
|
|
311
|
+
`Dirty paths: ${JSON.stringify(dirtyPaths.slice(0, 5))}` +
|
|
312
|
+
(dirtyPaths.length > 5 ? ", …" : "") +
|
|
313
|
+
".",
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
const deftDir = join(projectDir, LEGACY_DEFT_DIR);
|
|
317
|
+
const removeDir = seams.removeDir ?? ((p) => rmSync(p, { recursive: true, force: true }));
|
|
318
|
+
const runGitRm = seams.runGitRm ??
|
|
319
|
+
((root, relPath) => {
|
|
320
|
+
execFileSync("git", ["rm", "-r", "--ignore-unmatch", relPath], {
|
|
321
|
+
cwd: root,
|
|
322
|
+
encoding: "utf8",
|
|
323
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
try {
|
|
327
|
+
runGitRm(projectDir, LEGACY_DEFT_DIR);
|
|
328
|
+
removeDir(deftDir);
|
|
329
|
+
return {
|
|
330
|
+
ok: true,
|
|
331
|
+
action: "staged",
|
|
332
|
+
detail: "Removed the legacy deft/ framework tree and staged its deletion; " +
|
|
333
|
+
".deft/core/ is now the sole framework root.",
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
try {
|
|
338
|
+
removeDir(deftDir);
|
|
339
|
+
return {
|
|
340
|
+
ok: true,
|
|
341
|
+
action: "removed",
|
|
342
|
+
detail: "Removed the legacy deft/ framework tree from disk; stage the deletion with " +
|
|
343
|
+
"`git add -u deft/` if it was tracked.",
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
catch (cause) {
|
|
347
|
+
return {
|
|
348
|
+
ok: false,
|
|
349
|
+
action: "refused",
|
|
350
|
+
detail: `Could not remove the legacy deft/ tree: ${String(cause)}`,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
223
355
|
//# sourceMappingURL=legacy-detect.js.map
|
|
@@ -47,6 +47,8 @@ export interface RefreshDepositSeams {
|
|
|
47
47
|
gitLsFiles?: GitLsFiles;
|
|
48
48
|
/** #2530: injected git config seams for {@link writeConsumerGitHooks}. */
|
|
49
49
|
gitHooks?: GitHooksSeams;
|
|
50
|
+
/** #2822: optional seam for trusted-org policy force-on migration. */
|
|
51
|
+
runOrgForceOn?: (projectRoot: string) => void;
|
|
50
52
|
}
|
|
51
53
|
/**
|
|
52
54
|
* The four states `directive update` classifies an EXISTING install into BEFORE
|
|
@@ -18,11 +18,13 @@ import { resolveInstalledContentRoot } from "../deposit/resolve-content.js";
|
|
|
18
18
|
import { manifestTagToVersion, parseInstallManifest } from "../doctor/manifest.js";
|
|
19
19
|
import { readCorePackageVersion } from "../engine-version.js";
|
|
20
20
|
import { resolveLifecycleRoot } from "../layout/resolve.js";
|
|
21
|
+
import { runOrgForceOnMigration } from "../policy/org-force-on-migration.js";
|
|
21
22
|
import { checkLocalEngineIntegrity, classify, ENGINE_PACKAGE, plan, renderGlobalInstall, resolveEngine, } from "../resolution/index.js";
|
|
22
23
|
import { gitPorcelain } from "../story-ready/git.js";
|
|
24
|
+
import { removeStaleMigratedFrameworkNarrative } from "../xbrief-migrate/migrate-project.js";
|
|
23
25
|
import { writeAgentHookDeposit } from "./agent-hooks.js";
|
|
24
26
|
import { ensureInitGitignoreLines, isDepositTrackedInGit } from "./gitignore.js";
|
|
25
|
-
import { depositStagePaths, isInstallerManagedPath, printCommitGuidance,
|
|
27
|
+
import { depositStagePaths, isInstallerManagedPath, printCommitGuidance, prunePackageAbsentDepositPaths, } from "./hygiene.js";
|
|
26
28
|
import { parseInitArgv } from "./init-deposit.js";
|
|
27
29
|
import { buildLegacyRefusalJson, buildLegacyRefusalMessage, detectLegacyLayout, LEGACY_LAYOUT_REFUSED_EXIT_CODE, LegacyLayoutRefusedError, } from "./legacy-detect.js";
|
|
28
30
|
import { printMigrateNudgeIfNeeded } from "./migrate.js";
|
|
@@ -409,10 +411,10 @@ export async function runRefreshDeposit(args, io, seams = {}) {
|
|
|
409
411
|
else {
|
|
410
412
|
await copyContent(contentRoot, deftDir);
|
|
411
413
|
await prunePythonArtifactsFromDeposit(deftDir, projectDir, io);
|
|
412
|
-
// #2347: prune
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
await
|
|
414
|
+
// #2804 / #2347: prune deposit paths absent from the content package. The
|
|
415
|
+
// additive file-swap never removes them, causing stale bridge-era files to
|
|
416
|
+
// survive across upgrades until manually cleaned.
|
|
417
|
+
await prunePackageAbsentDepositPaths(deftDir, contentRoot, io);
|
|
416
418
|
const nowIso = seams.nowIso ?? (() => new Date().toISOString().replace(/\.\d{3}Z$/, "Z"));
|
|
417
419
|
const manifestFields = {
|
|
418
420
|
ref: contentVersion.startsWith("v") ? contentVersion : `v${contentVersion}`,
|
|
@@ -441,6 +443,17 @@ export async function runRefreshDeposit(args, io, seams = {}) {
|
|
|
441
443
|
// lifecycle content before migrate:xbrief can transactionally converge it.
|
|
442
444
|
if (hasCanonicalXbriefLifecycle(projectDir)) {
|
|
443
445
|
syncConsumerXbriefSchemas(projectDir, deftDir);
|
|
446
|
+
removeStaleMigratedFrameworkNarrative(projectDir);
|
|
447
|
+
}
|
|
448
|
+
const runOrgForceOn = seams.runOrgForceOn ??
|
|
449
|
+
((root) => {
|
|
450
|
+
runOrgForceOnMigration(root, { actor: "directive-update" });
|
|
451
|
+
});
|
|
452
|
+
try {
|
|
453
|
+
runOrgForceOn(projectDir);
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
// Policy migration is best-effort; never block framework refresh (#2822).
|
|
444
457
|
}
|
|
445
458
|
const agentsMdUpdated = writeAgentsMd(projectDir, deftDir, io);
|
|
446
459
|
writeAgentHookDeposit(projectDir, io);
|
package/dist/policy/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./capacity.js";
|
|
|
4
4
|
export * from "./decisions.js";
|
|
5
5
|
export * from "./disclosure.js";
|
|
6
6
|
export * from "./host-hooks.js";
|
|
7
|
+
export * from "./org-force-on-migration.js";
|
|
7
8
|
export * from "./plan-extensions.js";
|
|
8
9
|
export * from "./policy-invocation.js";
|
|
9
10
|
export * from "./product-signal.js";
|
|
@@ -11,6 +12,7 @@ export * from "./resolve.js";
|
|
|
11
12
|
export * from "./runtime-authority.js";
|
|
12
13
|
export * from "./staleness-tickler.js";
|
|
13
14
|
export * from "./value-feedback.js";
|
|
15
|
+
export * from "./value-feedback-autoenable.js";
|
|
14
16
|
export * from "./wip.js";
|
|
15
17
|
export declare const FIELD_ALLOW_DIRECT_COMMITS = "plan.policy.allowDirectCommitsToMaster";
|
|
16
18
|
export declare const FIELD_WIP_CAP = "plan.policy.wipCap";
|
package/dist/policy/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export * from "./capacity.js";
|
|
|
12
12
|
export * from "./decisions.js";
|
|
13
13
|
export * from "./disclosure.js";
|
|
14
14
|
export * from "./host-hooks.js";
|
|
15
|
+
export * from "./org-force-on-migration.js";
|
|
15
16
|
export * from "./plan-extensions.js";
|
|
16
17
|
export * from "./policy-invocation.js";
|
|
17
18
|
export * from "./product-signal.js";
|
|
@@ -19,6 +20,7 @@ export * from "./resolve.js";
|
|
|
19
20
|
export * from "./runtime-authority.js";
|
|
20
21
|
export * from "./staleness-tickler.js";
|
|
21
22
|
export * from "./value-feedback.js";
|
|
23
|
+
export * from "./value-feedback-autoenable.js";
|
|
22
24
|
export * from "./wip.js";
|
|
23
25
|
export const FIELD_ALLOW_DIRECT_COMMITS = "plan.policy.allowDirectCommitsToMaster";
|
|
24
26
|
export const FIELD_WIP_CAP = "plan.policy.wipCap";
|