@deftai/directive-core 0.89.0 → 0.91.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 +1 -1
- package/dist/doctor/constants.js +2 -0
- package/dist/doctor/flags.js +21 -1
- package/dist/doctor/index.d.ts +1 -0
- package/dist/doctor/index.js +1 -0
- package/dist/doctor/main.js +22 -0
- package/dist/doctor/openclaw-skills.d.ts +143 -0
- package/dist/doctor/openclaw-skills.js +706 -0
- package/dist/doctor/types.d.ts +11 -0
- package/dist/eval/health.d.ts +10 -1
- package/dist/eval/health.js +16 -16
- package/dist/hooks/dispatcher.js +20 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/init-deposit/hygiene.js +3 -0
- package/dist/init-deposit/init-deposit.d.ts +5 -0
- package/dist/init-deposit/init-deposit.js +37 -2
- package/dist/intake/github-auth-modes.d.ts +1 -1
- package/dist/intake/github-auth-modes.js +25 -3
- package/dist/intake/issue-ingest-cli.js +13 -0
- package/dist/intake/reconcile-issues-cli.js +13 -0
- package/dist/lifecycle/events.js +2 -0
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.js +1 -0
- package/dist/lifecycle/stats.d.ts +53 -0
- package/dist/lifecycle/stats.js +286 -0
- package/dist/policy/plan-extensions.d.ts +10 -0
- package/dist/policy/plan-extensions.js +16 -0
- package/dist/pr-closing-keywords/detect.d.ts +13 -0
- package/dist/pr-closing-keywords/detect.js +73 -8
- package/dist/pr-closing-keywords/index.d.ts +2 -2
- package/dist/pr-closing-keywords/index.js +1 -1
- package/dist/pr-closing-keywords/main.js +119 -90
- package/dist/pr-closing-keywords/types.d.ts +10 -0
- package/dist/release/spawn.js +13 -0
- package/dist/release-e2e/git-ops.d.ts +7 -0
- package/dist/release-e2e/git-ops.js +35 -2
- package/dist/render/constants.d.ts +16 -0
- package/dist/render/constants.js +16 -1
- package/dist/render/export-spec.d.ts +7 -1
- package/dist/render/export-spec.js +51 -5
- package/dist/render/index.d.ts +3 -2
- package/dist/render/index.js +2 -2
- package/dist/render/roadmap-render.js +164 -60
- package/dist/render/scope-outlook.d.ts +5 -0
- package/dist/render/scope-outlook.js +3 -0
- package/dist/render/spec-render.d.ts +28 -2
- package/dist/render/spec-render.js +111 -14
- package/dist/render/text-utils.d.ts +6 -0
- package/dist/render/text-utils.js +23 -0
- package/dist/scm/binary.d.ts +3 -0
- package/dist/scm/binary.js +10 -2
- package/dist/scm/call.d.ts +5 -0
- package/dist/scm/call.js +5 -0
- package/dist/scm/index.d.ts +1 -0
- package/dist/scm/index.js +1 -0
- package/dist/scm/main.d.ts +5 -0
- package/dist/scm/main.js +27 -0
- package/dist/scm/readiness-cli.d.ts +24 -0
- package/dist/scm/readiness-cli.js +85 -0
- package/dist/scm/readiness.d.ts +104 -0
- package/dist/scm/readiness.js +421 -0
- package/dist/scope/batch-promote.d.ts +26 -0
- package/dist/scope/batch-promote.js +167 -0
- package/dist/scope/index.d.ts +1 -0
- package/dist/scope/index.js +1 -0
- package/dist/scope/main.d.ts +2 -0
- package/dist/scope/main.js +58 -7
- package/dist/scope/wip-cap-check.d.ts +6 -0
- package/dist/scope/wip-cap-check.js +14 -2
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/process-cost-constants.d.ts +9 -0
- package/dist/session/process-cost-constants.js +11 -0
- package/dist/session/process-cost.d.ts +53 -0
- package/dist/session/process-cost.js +82 -0
- package/dist/session/ritual-sentinel.d.ts +5 -0
- package/dist/session/ritual-sentinel.js +12 -1
- package/dist/session/session-ready.d.ts +67 -0
- package/dist/session/session-ready.js +264 -0
- package/dist/session/session-start.d.ts +63 -1
- package/dist/session/session-start.js +432 -24
- package/dist/session/verify-session-ritual.d.ts +8 -0
- package/dist/session/verify-session-ritual.js +95 -35
- package/dist/tool-events/classify.d.ts +20 -0
- package/dist/tool-events/classify.js +634 -0
- package/dist/tool-events/index.d.ts +10 -0
- package/dist/tool-events/index.js +10 -0
- package/dist/tool-events/summarize.d.ts +34 -0
- package/dist/tool-events/summarize.js +93 -0
- package/dist/tool-events/types.d.ts +52 -0
- package/dist/tool-events/types.js +13 -0
- package/dist/triage/welcome/index.d.ts +1 -1
- package/dist/triage/welcome/index.js +1 -1
- package/dist/triage/welcome/onboard.js +7 -1
- package/dist/triage/welcome/prior-state.d.ts +7 -0
- package/dist/triage/welcome/prior-state.js +16 -2
- package/dist/triage/welcome/writers.d.ts +10 -0
- package/dist/triage/welcome/writers.js +72 -2
- package/package.json +7 -3
|
@@ -7,7 +7,7 @@ export declare const DEPRECATED_REDIRECT_SENTINEL = "<!-- deft:deprecated-redire
|
|
|
7
7
|
export declare const DEPRECATED_SKILL_REDIRECT_SENTINEL = "<!-- deft:deprecated-skill-redirect -->";
|
|
8
8
|
export declare const REDIRECT_STUB_HEADER_LINES = 8;
|
|
9
9
|
export declare const TASKFILE_INCLUDE_SNIPPET = "version: '3'\n\nincludes:\n deft:\n taskfile: ./.deft/core/Taskfile.yml\n optional: true\n";
|
|
10
|
-
export declare const DOCTOR_ALLOWED_FLAGS: readonly ["--session", "--fix", "--repair", "--repair-taskfile", "--json", "--quiet", "--full", "--network", "--project-root", "-h", "--help"];
|
|
10
|
+
export declare const DOCTOR_ALLOWED_FLAGS: readonly ["--session", "--fix", "--repair", "--repair-taskfile", "--json", "--quiet", "--full", "--network", "--project-root", "--force", "--openclaw-all-agents", "-h", "--help"];
|
|
11
11
|
/** npm consumer deposit after #2022 Phase 3 -- Python scripts/ tree is intentionally absent. */
|
|
12
12
|
export declare const NPM_PACKAGE_NAME = "@deftai/directive";
|
|
13
13
|
export declare const PUBLIC_NPM_REGISTRY = "https://registry.npmjs.org/";
|
package/dist/doctor/constants.js
CHANGED
package/dist/doctor/flags.js
CHANGED
|
@@ -8,6 +8,8 @@ export function parseDoctorFlags(args) {
|
|
|
8
8
|
let network = false;
|
|
9
9
|
let help = false;
|
|
10
10
|
let projectRoot = null;
|
|
11
|
+
let force = false;
|
|
12
|
+
let openclawAllAgents = false;
|
|
11
13
|
const unknown = [];
|
|
12
14
|
let i = 0;
|
|
13
15
|
while (i < args.length) {
|
|
@@ -30,6 +32,12 @@ export function parseDoctorFlags(args) {
|
|
|
30
32
|
else if (token === "--network") {
|
|
31
33
|
network = true;
|
|
32
34
|
}
|
|
35
|
+
else if (token === "--force") {
|
|
36
|
+
force = true;
|
|
37
|
+
}
|
|
38
|
+
else if (token === "--openclaw-all-agents") {
|
|
39
|
+
openclawAllAgents = true;
|
|
40
|
+
}
|
|
33
41
|
else if (token === "-h" || token === "--help") {
|
|
34
42
|
help = true;
|
|
35
43
|
}
|
|
@@ -56,7 +64,19 @@ export function parseDoctorFlags(args) {
|
|
|
56
64
|
}
|
|
57
65
|
i += 1;
|
|
58
66
|
}
|
|
59
|
-
return {
|
|
67
|
+
return {
|
|
68
|
+
session,
|
|
69
|
+
fix,
|
|
70
|
+
json,
|
|
71
|
+
quiet,
|
|
72
|
+
full,
|
|
73
|
+
network,
|
|
74
|
+
help,
|
|
75
|
+
projectRoot,
|
|
76
|
+
force,
|
|
77
|
+
openclawAllAgents,
|
|
78
|
+
unknown,
|
|
79
|
+
};
|
|
60
80
|
}
|
|
61
81
|
export function formatUnknownFlagsError(unknown) {
|
|
62
82
|
return `Unknown flag(s): ${unknown.join(", ")}`;
|
package/dist/doctor/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./json.js";
|
|
|
7
7
|
export * from "./main.js";
|
|
8
8
|
export * from "./manifest.js";
|
|
9
9
|
export * from "./npm-registry.js";
|
|
10
|
+
export * from "./openclaw-skills.js";
|
|
10
11
|
export * from "./paths.js";
|
|
11
12
|
export * from "./payload-staleness.js";
|
|
12
13
|
export * from "./release-availability.js";
|
package/dist/doctor/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./json.js";
|
|
|
7
7
|
export * from "./main.js";
|
|
8
8
|
export * from "./manifest.js";
|
|
9
9
|
export * from "./npm-registry.js";
|
|
10
|
+
export * from "./openclaw-skills.js";
|
|
10
11
|
export * from "./paths.js";
|
|
11
12
|
export * from "./payload-staleness.js";
|
|
12
13
|
export * from "./release-availability.js";
|
package/dist/doctor/main.js
CHANGED
|
@@ -21,6 +21,7 @@ import { formatAllowedFlagsHint, formatUnknownFlagsError, parseDoctorFlags } fro
|
|
|
21
21
|
import { pythonJsonDump } from "./json.js";
|
|
22
22
|
import { parseInstallRootFromAgentsMd } from "./manifest.js";
|
|
23
23
|
import { runNpmRegistryMirrorCheck } from "./npm-registry.js";
|
|
24
|
+
import { runOpenClawSkillPinsCheck } from "./openclaw-skills.js";
|
|
24
25
|
import { createPlainSink } from "./output.js";
|
|
25
26
|
import { readTextSafe, resolveFrameworkRootForProject, resolvePath, resolveVersion, runningInsideDeftRepo, } from "./paths.js";
|
|
26
27
|
import { runPayloadStalenessCheck } from "./payload-staleness.js";
|
|
@@ -350,6 +351,27 @@ export function cmdDoctor(args, seams = {}) {
|
|
|
350
351
|
if (!jsonMode) {
|
|
351
352
|
sink.blank();
|
|
352
353
|
}
|
|
354
|
+
sink.info("Checking OpenClaw always-pin skills...");
|
|
355
|
+
runOpenClawSkillPinsCheck(sink, addFinding, {
|
|
356
|
+
frameworkRoot,
|
|
357
|
+
fixMode,
|
|
358
|
+
jsonMode,
|
|
359
|
+
force: flags.force,
|
|
360
|
+
allAgents: flags.openclawAllAgents,
|
|
361
|
+
seams: {
|
|
362
|
+
...seams,
|
|
363
|
+
env: seams.openclawEnv,
|
|
364
|
+
homeDir: seams.openclawHomeDir,
|
|
365
|
+
contentRootFor: seams.openclawContentRootFor,
|
|
366
|
+
isDir: seams.isDir,
|
|
367
|
+
isFile: seams.isFile,
|
|
368
|
+
isTty: seams.isTty,
|
|
369
|
+
readYn: seams.readYn,
|
|
370
|
+
},
|
|
371
|
+
});
|
|
372
|
+
if (!jsonMode) {
|
|
373
|
+
sink.blank();
|
|
374
|
+
}
|
|
353
375
|
sink.info("Checking xBRIEF project envelope version...");
|
|
354
376
|
runXbriefEnvelopeVersionCheck(projectRoot, sink, addFinding, seams);
|
|
355
377
|
let resolution = null;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw always-pin skill detect + doctor --fix wire (#3001 / #3008).
|
|
3
|
+
*
|
|
4
|
+
* When OpenClaw signals are present, doctor checks the main workspace skills
|
|
5
|
+
* root for the four always-pin skills (#2508). Missing pins emit a warning with
|
|
6
|
+
* remediation `deft doctor --fix`. Under fixMode, pins are **copied** into the
|
|
7
|
+
* workspace skills root (not symlinked into the npm content package).
|
|
8
|
+
*
|
|
9
|
+
* OpenClaw 2026.7.x rejects workspace skills that resolve outside the configured
|
|
10
|
+
* skills root (`reason=symlink-escape`). A pin that is only a symlink into
|
|
11
|
+
* `@deftai/directive-content` therefore looks "present" on disk while the host
|
|
12
|
+
* never loads it (#3008). Prefer real directory copies; treat escaping
|
|
13
|
+
* symlinks as divergent so `--fix` can replace them.
|
|
14
|
+
*
|
|
15
|
+
* Multi-seat (`workspace-*`) targets only when `--openclaw-all-agents` is set.
|
|
16
|
+
*/
|
|
17
|
+
import type { OutputSink } from "./output.js";
|
|
18
|
+
import type { DoctorSeams, Finding } from "./types.js";
|
|
19
|
+
/** Stable doctor check id for JSON findings. */
|
|
20
|
+
export declare const OPENCLAW_SKILL_PINS_CHECK = "openclaw-skill-pins";
|
|
21
|
+
/** Always-pin skill directory names (#2508 / cold-start). */
|
|
22
|
+
export declare const OPENCLAW_ALWAYS_PIN_SKILLS: readonly ["deft-directive-build", "deft-directive-pre-pr", "deft-directive-review-cycle", "deft-directive-swarm"];
|
|
23
|
+
export type OpenClawAlwaysPinSkill = (typeof OPENCLAW_ALWAYS_PIN_SKILLS)[number];
|
|
24
|
+
/** Env keys that count as strong OpenClaw signals (#3001). */
|
|
25
|
+
export declare const OPENCLAW_ENV_SIGNAL_KEYS: readonly ["OPENCLAW", "DEFT_PROBE_OPENCLAW", "DEFT_AGENT_RUNTIME", "OPENCLAW_STATE_DIR"];
|
|
26
|
+
export interface OpenClawSkillPinsSeams {
|
|
27
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
28
|
+
readonly homeDir?: () => string;
|
|
29
|
+
readonly isDir?: (path: string) => boolean;
|
|
30
|
+
readonly isFile?: (path: string) => boolean;
|
|
31
|
+
readonly pathExists?: (path: string) => boolean;
|
|
32
|
+
readonly readDir?: (path: string) => string[];
|
|
33
|
+
readonly lstatKind?: (path: string) => "file" | "dir" | "symlink" | "other" | "missing";
|
|
34
|
+
readonly mkdirp?: (path: string) => void;
|
|
35
|
+
readonly symlinkDir?: (target: string, path: string) => void;
|
|
36
|
+
readonly copyDir?: (src: string, dst: string) => void;
|
|
37
|
+
readonly removePath?: (path: string) => void;
|
|
38
|
+
readonly renamePath?: (from: string, to: string) => void;
|
|
39
|
+
readonly contentRootFor?: (frameworkRoot: string) => string;
|
|
40
|
+
readonly isTty?: () => boolean;
|
|
41
|
+
readonly readYn?: (prompt: string, defaultYes: boolean) => boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface OpenClawPinAssessment {
|
|
44
|
+
readonly skillsDir: string;
|
|
45
|
+
readonly present: readonly OpenClawAlwaysPinSkill[];
|
|
46
|
+
readonly missing: readonly OpenClawAlwaysPinSkill[];
|
|
47
|
+
readonly divergent: readonly OpenClawAlwaysPinSkill[];
|
|
48
|
+
}
|
|
49
|
+
export interface OpenClawDetectResult {
|
|
50
|
+
readonly detected: boolean;
|
|
51
|
+
readonly reasons: readonly string[];
|
|
52
|
+
readonly stateDir: string;
|
|
53
|
+
readonly mainSkillsDir: string;
|
|
54
|
+
}
|
|
55
|
+
export type PinInstallMethod = "symlink" | "copy" | "skipped" | "already-present";
|
|
56
|
+
export interface PinInstallResult {
|
|
57
|
+
readonly skillId: OpenClawAlwaysPinSkill;
|
|
58
|
+
readonly method: PinInstallMethod;
|
|
59
|
+
readonly target: string;
|
|
60
|
+
readonly source: string;
|
|
61
|
+
readonly detail?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve OpenClaw state directory: OPENCLAW_STATE_DIR or ~/.openclaw.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveOpenClawStateDir(env?: NodeJS.ProcessEnv, home?: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Main agent workspace skills root under the state dir.
|
|
69
|
+
*/
|
|
70
|
+
export declare function resolveMainSkillsDir(stateDir: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Detect OpenClaw from env signals and/or presence of the state directory.
|
|
73
|
+
*/
|
|
74
|
+
export declare function detectOpenClaw(env?: NodeJS.ProcessEnv, options?: {
|
|
75
|
+
homeDir?: string;
|
|
76
|
+
isDir?: (path: string) => boolean;
|
|
77
|
+
}): OpenClawDetectResult;
|
|
78
|
+
/**
|
|
79
|
+
* List in-scope skills directories. Default: main only.
|
|
80
|
+
* With allAgents: main + every workspace- star /skills under the state dir.
|
|
81
|
+
*/
|
|
82
|
+
export declare function listInScopeSkillsDirs(stateDir: string, allAgents: boolean, seams?: Pick<OpenClawSkillPinsSeams, "isDir" | "readDir">): string[];
|
|
83
|
+
/**
|
|
84
|
+
* Resolve content package skills/<id> for a pin.
|
|
85
|
+
*/
|
|
86
|
+
export declare function resolvePinSourceDir(contentBase: string, skillId: string): string;
|
|
87
|
+
/**
|
|
88
|
+
* True when `path` is a symlink whose resolved real path is outside `skillsDir`
|
|
89
|
+
* (OpenClaw `symlink-escape` / #3008).
|
|
90
|
+
*/
|
|
91
|
+
export declare function isEscapingSkillSymlink(skillsDir: string, path: string, seams?: Pick<OpenClawSkillPinsSeams, "lstatKind">): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Assess which always-pins are present / missing / divergent in a skills root.
|
|
94
|
+
*
|
|
95
|
+
* - present: real directory (or non-escaping symlink) with SKILL.md matching
|
|
96
|
+
* the content package when `contentBase` is supplied
|
|
97
|
+
* - missing: path does not exist
|
|
98
|
+
* - divergent: path exists but is not a usable OpenClaw pin (file, empty dir,
|
|
99
|
+
* broken link, **escaping symlink**, or **stale SKILL.md** vs package — #3008)
|
|
100
|
+
*/
|
|
101
|
+
export declare function assessOpenClawPins(skillsDir: string, seams?: Pick<OpenClawSkillPinsSeams, "isDir" | "isFile" | "pathExists" | "lstatKind">, options?: {
|
|
102
|
+
contentBase?: string;
|
|
103
|
+
}): OpenClawPinAssessment;
|
|
104
|
+
/**
|
|
105
|
+
* Install one pin into a skills root.
|
|
106
|
+
*
|
|
107
|
+
* Default: **copy** into the workspace skills root (#3008). OpenClaw rejects
|
|
108
|
+
* skills that resolve outside the workspace skills root via symlink-escape, so
|
|
109
|
+
* symlinking into the npm content package leaves pins unloaded while doctor
|
|
110
|
+
* reports "present". Opt into legacy symlink-first with `preferSymlink: true`
|
|
111
|
+
* (still falls back to copy). Never deletes unrelated user skills. Divergent
|
|
112
|
+
* targets (including escaping symlinks) require force or TTY confirm.
|
|
113
|
+
*
|
|
114
|
+
* Stale copies (SKILL.md differs from package) are not "already-present" —
|
|
115
|
+
* doctor --fix refreshes them so upgrades land without manual delete (#3008 P1).
|
|
116
|
+
* Forced replace stages into a sibling temp dir first so a failed copy does not
|
|
117
|
+
* leave the pin permanently deleted (#3008 P1).
|
|
118
|
+
*/
|
|
119
|
+
export declare function installOpenClawPin(skillId: OpenClawAlwaysPinSkill, sourceDir: string, skillsDir: string, options?: {
|
|
120
|
+
force?: boolean;
|
|
121
|
+
allowOverwrite?: boolean;
|
|
122
|
+
/** When true, try symlink first (legacy #3001). Default false — copy (#3008). */
|
|
123
|
+
preferSymlink?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* When true, refresh copied pins whose SKILL.md no longer matches the
|
|
126
|
+
* package (package upgrade path). Doctor --fix sets this.
|
|
127
|
+
*/
|
|
128
|
+
refreshStale?: boolean;
|
|
129
|
+
}, seams?: OpenClawSkillPinsSeams): PinInstallResult;
|
|
130
|
+
export interface RunOpenClawSkillPinsOptions {
|
|
131
|
+
readonly frameworkRoot: string;
|
|
132
|
+
readonly fixMode: boolean;
|
|
133
|
+
readonly jsonMode: boolean;
|
|
134
|
+
readonly force: boolean;
|
|
135
|
+
readonly allAgents: boolean;
|
|
136
|
+
readonly seams?: DoctorSeams & OpenClawSkillPinsSeams;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Doctor check: detect OpenClaw + missing always-pins; optionally fix.
|
|
140
|
+
* No-ops when OpenClaw signals are absent.
|
|
141
|
+
*/
|
|
142
|
+
export declare function runOpenClawSkillPinsCheck(sink: OutputSink, addFinding: (finding: Finding) => void, options: RunOpenClawSkillPinsOptions): void;
|
|
143
|
+
//# sourceMappingURL=openclaw-skills.d.ts.map
|