@deftai/directive-core 0.86.0 → 0.87.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/check/gate-lists.js +1 -0
- package/dist/doctor/main.d.ts +6 -5
- package/dist/doctor/main.js +32 -18
- package/dist/doctor/taskfile.d.ts +8 -0
- package/dist/doctor/taskfile.js +19 -0
- package/dist/hooks/dispatcher.d.ts +21 -1
- package/dist/hooks/dispatcher.js +85 -15
- package/dist/intake/issue-emit.d.ts +45 -2
- package/dist/intake/issue-emit.js +420 -17
- package/dist/intake/issue-ingest.js +54 -4
- package/dist/platform/platform-capabilities.js +3 -0
- package/dist/review-monitor/constants.js +3 -2
- package/dist/review-monitor/tier-detection.d.ts +6 -2
- package/dist/review-monitor/tier-detection.js +27 -2
- package/dist/scope/transition.js +43 -0
- package/dist/session/release-availability.d.ts +2 -0
- package/dist/session/release-availability.js +23 -8
- package/dist/swarm/routing-set-cli.js +5 -10
- package/dist/swarm/routing.d.ts +3 -2
- package/dist/swarm/routing.js +16 -4
- package/dist/triage/help/registry-data.d.ts +7 -7
- package/dist/triage/help/registry-data.js +15 -6
- package/dist/triage/queue/index.d.ts +1 -0
- package/dist/triage/queue/index.js +1 -0
- package/dist/triage/queue/show.d.ts +69 -0
- package/dist/triage/queue/show.js +293 -0
- package/dist/triage/scope/cli.js +3 -0
- package/dist/triage/scope/coverage.d.ts +2 -0
- package/dist/triage/scope/coverage.js +18 -3
- package/dist/verify-source/index.d.ts +1 -0
- package/dist/verify-source/index.js +1 -0
- package/dist/verify-source/openclaw-tier1.d.ts +37 -0
- package/dist/verify-source/openclaw-tier1.js +100 -0
- package/dist/xbrief-migrate/migrate-project.js +9 -5
- package/package.json +3 -3
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import { MONITORING_TIER_1, MONITORING_TIER_2, MONITORING_TIER_3 } from "./constants.js";
|
|
2
2
|
const TRUTHY = new Set(["1", "true", "yes", "on"]);
|
|
3
|
+
/** Accepted `--platform-primitive` values (register CLI + help text). */
|
|
4
|
+
export const PLATFORM_PRIMITIVES = [
|
|
5
|
+
"start_agent",
|
|
6
|
+
"spawn_subagent",
|
|
7
|
+
"cursor-task",
|
|
8
|
+
"sessions_spawn",
|
|
9
|
+
"openclaw-sessions-spawn",
|
|
10
|
+
];
|
|
11
|
+
export const PLATFORM_PRIMITIVE_SET = new Set(PLATFORM_PRIMITIVES);
|
|
3
12
|
function envTruthy(environ, name) {
|
|
4
13
|
return TRUTHY.has((environ[name] ?? "").trim().toLowerCase());
|
|
5
14
|
}
|
|
6
15
|
function probeOverride(environ) {
|
|
7
16
|
const raw = (environ.DEFT_MONITOR_TIER ?? environ.DEFT_MONITOR_TIER_OVERRIDE ?? "").trim();
|
|
8
17
|
if (raw === "1" || raw.toLowerCase() === "tier1") {
|
|
9
|
-
const
|
|
18
|
+
const requested = (environ.DEFT_MONITOR_TIER1_PRIMITIVE ?? "cursor-task").trim();
|
|
19
|
+
const primitive = PLATFORM_PRIMITIVE_SET.has(requested)
|
|
20
|
+
? requested
|
|
21
|
+
: "cursor-task";
|
|
10
22
|
return { tier: MONITORING_TIER_1, primitive, descriptor: "override-tier1" };
|
|
11
23
|
}
|
|
12
24
|
if (raw === "3" || raw.toLowerCase() === "tier3") {
|
|
@@ -16,7 +28,7 @@ function probeOverride(environ) {
|
|
|
16
28
|
}
|
|
17
29
|
/**
|
|
18
30
|
* Inline Tier-1 detection aligned with the swarm Phase 3 / review-cycle matrix
|
|
19
|
-
* (#1877 / #2655). Prefer `task platform:capabilities` when available (#1357);
|
|
31
|
+
* (#1877 / #2655 / #2876). Prefer `task platform:capabilities` when available (#1357);
|
|
20
32
|
* this probe does not block MVP.
|
|
21
33
|
*/
|
|
22
34
|
export function probeMonitoringTier(environ = process.env) {
|
|
@@ -41,6 +53,19 @@ export function probeMonitoringTier(environ = process.env) {
|
|
|
41
53
|
};
|
|
42
54
|
}
|
|
43
55
|
const runtime = (environ.DEFT_AGENT_RUNTIME ?? "").trim().toLowerCase();
|
|
56
|
+
// OpenClaw: sessions_spawn is the Tier-1 Approach 1 primitive (#2876).
|
|
57
|
+
// Alias openclaw-sessions-spawn accepted on register for explicit naming.
|
|
58
|
+
if (envTruthy(environ, "DEFT_PROBE_SESSIONS_SPAWN") ||
|
|
59
|
+
envTruthy(environ, "DEFT_HAS_SESSIONS_SPAWN") ||
|
|
60
|
+
envTruthy(environ, "DEFT_PROBE_OPENCLAW") ||
|
|
61
|
+
envTruthy(environ, "OPENCLAW") ||
|
|
62
|
+
runtime === "openclaw" ||
|
|
63
|
+
runtime === "openclaw-sessions-spawn") {
|
|
64
|
+
const alias = (environ.DEFT_MONITOR_TIER1_PRIMITIVE ?? "").trim() === "openclaw-sessions-spawn"
|
|
65
|
+
? "openclaw-sessions-spawn"
|
|
66
|
+
: "sessions_spawn";
|
|
67
|
+
return { tier: MONITORING_TIER_1, primitive: alias, descriptor: "openclaw" };
|
|
68
|
+
}
|
|
44
69
|
if (envTruthy(environ, "DEFT_PROBE_GROK_BUILD") ||
|
|
45
70
|
envTruthy(environ, "GROK_BUILD") ||
|
|
46
71
|
runtime === "grok-build") {
|
package/dist/scope/transition.js
CHANGED
|
@@ -11,6 +11,43 @@ import { detectLifecycleFolder, updateDecomposedChildBackReferences, updateDecom
|
|
|
11
11
|
import { syncProjectDefinitionAfterScopeMove } from "./project-definition-sync.js";
|
|
12
12
|
import { syncSpecificationAfterScopeMove } from "./specification-sync.js";
|
|
13
13
|
import { utcNowIso } from "./vbrief-json.js";
|
|
14
|
+
/** Item statuses that still represent unfinished work and should advance on terminal transitions (#2862). */
|
|
15
|
+
const NON_TERMINAL_ITEM_STATUSES = new Set(["pending", "proposed", "running"]);
|
|
16
|
+
/** Terminal lifecycle actions that reconcile the brief's own plan.items (#2862). */
|
|
17
|
+
const OWN_ITEMS_RECONCILE_ACTIONS = new Set(["complete", "fail", "cancel"]);
|
|
18
|
+
/**
|
|
19
|
+
* Advance non-terminal plan.items / subItems to the terminal target status.
|
|
20
|
+
* Leaves cancelled / failed / completed / other non-pending-proposed-running items alone (#2862).
|
|
21
|
+
*/
|
|
22
|
+
function advanceNonTerminalOwnItems(items, targetStatus) {
|
|
23
|
+
if (!Array.isArray(items)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
for (const item of items) {
|
|
27
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const obj = item;
|
|
31
|
+
const status = String(obj.status ?? "");
|
|
32
|
+
if (NON_TERMINAL_ITEM_STATUSES.has(status)) {
|
|
33
|
+
obj.status = targetStatus;
|
|
34
|
+
}
|
|
35
|
+
advanceNonTerminalOwnItems(obj.subItems, targetStatus);
|
|
36
|
+
advanceNonTerminalOwnItems(obj.items, targetStatus);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Refresh the document envelope `updated` stamp to match `plan.updated`.
|
|
41
|
+
* Stamps whichever of xBRIEFInfo (v0.8) / vBRIEFInfo (v0.6) is present — never creates one (#2862 / #2346).
|
|
42
|
+
*/
|
|
43
|
+
function stampEnvelopeUpdated(data, nowIso) {
|
|
44
|
+
for (const key of ["xBRIEFInfo", "vBRIEFInfo"]) {
|
|
45
|
+
const env = data[key];
|
|
46
|
+
if (typeof env === "object" && env !== null && !Array.isArray(env)) {
|
|
47
|
+
env.updated = nowIso;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
14
51
|
export function runTransition(action, filePath, now = new Date()) {
|
|
15
52
|
if (!(action in TRANSITIONS)) {
|
|
16
53
|
const valid = Object.keys(TRANSITIONS).sort().join(", ");
|
|
@@ -96,6 +133,12 @@ export function runTransition(action, filePath, now = new Date()) {
|
|
|
96
133
|
const nowIso = utcNowIso(now);
|
|
97
134
|
planObj.status = targetStatus;
|
|
98
135
|
planObj.updated = nowIso;
|
|
136
|
+
// Keep the envelope clock aligned with plan.updated on every mutating transition (#2862).
|
|
137
|
+
stampEnvelopeUpdated(data, nowIso);
|
|
138
|
+
// Reconcile the completing brief's own plan.items (mirrors #1527 / #2566 registry sync) (#2862).
|
|
139
|
+
if (OWN_ITEMS_RECONCILE_ACTIONS.has(act)) {
|
|
140
|
+
advanceNonTerminalOwnItems(planObj.items, targetStatus);
|
|
141
|
+
}
|
|
99
142
|
if (act === "complete") {
|
|
100
143
|
stampCompletionMetadata(planObj, projectRoot, nowIso);
|
|
101
144
|
}
|
|
@@ -4,9 +4,15 @@ import { dirname, join } from "node:path";
|
|
|
4
4
|
import { locateManifest, parseInstallManifest } from "../doctor/manifest.js";
|
|
5
5
|
import { runningInsideDeftRepo } from "../doctor/paths.js";
|
|
6
6
|
import { evaluateReleaseAvailability } from "../doctor/release-availability.js";
|
|
7
|
+
import { resolveTriageCachePath } from "../triage/cache-path.js";
|
|
7
8
|
const THROTTLE_MS = 24 * 60 * 60 * 1000;
|
|
8
9
|
const PUBLIC_NPM_REGISTRY = "https://registry.npmjs.org/";
|
|
9
|
-
const
|
|
10
|
+
const STATE_FILE_NAME = "release-availability-state.json";
|
|
11
|
+
/** Display/back-compat constant; resolution flows through resolveTriageCachePath (#2869). */
|
|
12
|
+
export const STATE_RELATIVE_PATH = join("xbrief", ".triage-cache", STATE_FILE_NAME);
|
|
13
|
+
function resolveReleaseAvailabilityStatePath(projectRoot) {
|
|
14
|
+
return resolveTriageCachePath(projectRoot, STATE_FILE_NAME);
|
|
15
|
+
}
|
|
10
16
|
function defaultReadText(path) {
|
|
11
17
|
try {
|
|
12
18
|
return readFileSync(path, "utf8");
|
|
@@ -91,18 +97,27 @@ export function probeSessionReleaseAvailability(projectRoot, options = {}) {
|
|
|
91
97
|
const availability = evaluateReleaseAvailability(installed, npmResult.ok ? npmResult.version : null);
|
|
92
98
|
if (availability.status !== "available")
|
|
93
99
|
return { lines };
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
let statePath = null;
|
|
101
|
+
try {
|
|
102
|
+
statePath = resolveReleaseAvailabilityStatePath(projectRoot);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Symlink-escaping triage-cache path: skip throttle state; still emit advisory (#2869).
|
|
106
|
+
statePath = null;
|
|
107
|
+
}
|
|
108
|
+
const state = parseState(statePath !== null ? (options.readState ?? defaultReadText)(statePath) : null);
|
|
96
109
|
const now = options.now ?? new Date();
|
|
97
110
|
if (isThrottled(state, availability.latestVersion, now))
|
|
98
111
|
return { lines: [] };
|
|
99
112
|
const message = `[deft release] Newer Directive release available: v${availability.latestVersion} ` +
|
|
100
113
|
`(installed v${availability.installedVersion}). Run \`npm i -g @deftai/directive@latest\`.`;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
114
|
+
if (statePath !== null) {
|
|
115
|
+
try {
|
|
116
|
+
(options.writeState ?? defaultWriteState)(statePath, `${JSON.stringify({ latestVersion: availability.latestVersion, notifiedAt: now.toISOString() }, null, 2)}\n`);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// The advisory remains useful if its best-effort throttle state cannot persist.
|
|
120
|
+
}
|
|
106
121
|
}
|
|
107
122
|
return { lines: [...lines, message] };
|
|
108
123
|
}
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { PROJECTION_CONTAINMENT_REFUSED_EXIT_CODE, ProjectionContainmentError, } from "../fs/projection-containment.js";
|
|
5
|
-
import { getPlatformCapabilities } from "../intake/platform-capabilities.js";
|
|
6
5
|
import { EXIT_CONFIG_ERROR, EXIT_OK } from "./constants.js";
|
|
7
|
-
import {
|
|
6
|
+
import { HARNESS_BOUND_PROVIDERS, ROUTING_MODE_HARNESS_DEFAULT, ROUTING_MODE_PINNED, resolveDispatchProvider, resolveRoutingPath, SWARM_WORKER_ROLES, writeModelDecision, } from "./routing.js";
|
|
8
7
|
export function routingSetMain(argv = process.argv.slice(2)) {
|
|
9
8
|
let projectRoot = ".";
|
|
10
9
|
let provider = null;
|
|
@@ -47,14 +46,10 @@ export function routingSetMain(argv = process.argv.slice(2)) {
|
|
|
47
46
|
}
|
|
48
47
|
let resolvedProvider = provider;
|
|
49
48
|
if (resolvedProvider === null || resolvedProvider.length === 0) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
catch {
|
|
55
|
-
runtimeMode = "";
|
|
56
|
-
}
|
|
57
|
-
resolvedProvider = dispatchProviderFromRuntime(runtimeMode);
|
|
49
|
+
// Same key as launch + verify:routing: OPENCLAW / sessions_spawn → openclaw
|
|
50
|
+
// (#2875 Greptile P1). Do not map via runtimeMode alone — OpenClaw-only envs
|
|
51
|
+
// are often local-unsandboxed while still dispatching under provider openclaw.
|
|
52
|
+
resolvedProvider = resolveDispatchProvider(process.env);
|
|
58
53
|
}
|
|
59
54
|
if (harnessDefault) {
|
|
60
55
|
if (model !== null) {
|
package/dist/swarm/routing.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const ROUTING_MODE_HARNESS_DEFAULT = "harness-default";
|
|
|
9
9
|
export declare const ROUTING_FILENAME = "routing.local.json";
|
|
10
10
|
/** Providers whose model is harness-bound -- deft cannot pin or verify a slug. */
|
|
11
11
|
export declare const HARNESS_BOUND_PROVIDERS: Set<string>;
|
|
12
|
-
/** Providers whose per-role model must be decided before sub-agent dispatch (#1739 / #1877). */
|
|
12
|
+
/** Providers whose per-role model must be decided before sub-agent dispatch (#1739 / #1877 / #2875). */
|
|
13
13
|
export declare const ROUTING_GATED_DISPATCH_PROVIDERS: Set<string>;
|
|
14
14
|
export interface RouteDecision {
|
|
15
15
|
model: string | null;
|
|
@@ -54,7 +54,8 @@ export declare function dispatchProviderFromRuntime(runtimeMode: string): string
|
|
|
54
54
|
* Resolve the `dispatch_provider` routing key from the active runtime envelope.
|
|
55
55
|
* Separate from `runtime_mode` (#1557): Cursor sessions may carry
|
|
56
56
|
* `runtime_mode=cloud-headless` for gh-auth purposes but route under provider
|
|
57
|
-
* `cursor` for model selection (#1877).
|
|
57
|
+
* `cursor` for model selection (#1877). OpenClaw routes under `openclaw` when
|
|
58
|
+
* `sessions_spawn` / OPENCLAW signals are present (#2875).
|
|
58
59
|
*/
|
|
59
60
|
export declare function resolveDispatchProvider(environ?: NodeJS.ProcessEnv): string;
|
|
60
61
|
/**
|
package/dist/swarm/routing.js
CHANGED
|
@@ -32,8 +32,8 @@ export const ROUTING_MODE_HARNESS_DEFAULT = "harness-default";
|
|
|
32
32
|
export const ROUTING_FILENAME = "routing.local.json";
|
|
33
33
|
/** Providers whose model is harness-bound -- deft cannot pin or verify a slug. */
|
|
34
34
|
export const HARNESS_BOUND_PROVIDERS = new Set(["grok"]);
|
|
35
|
-
/** Providers whose per-role model must be decided before sub-agent dispatch (#1739 / #1877). */
|
|
36
|
-
export const ROUTING_GATED_DISPATCH_PROVIDERS = new Set(["cursor", "grok"]);
|
|
35
|
+
/** Providers whose per-role model must be decided before sub-agent dispatch (#1739 / #1877 / #2875). */
|
|
36
|
+
export const ROUTING_GATED_DISPATCH_PROVIDERS = new Set(["cursor", "grok", "openclaw"]);
|
|
37
37
|
const TRUTHY_ENV = new Set(["1", "true", "yes", "on"]);
|
|
38
38
|
function envTruthy(environ, name) {
|
|
39
39
|
return TRUTHY_ENV.has((environ[name] ?? "").trim().toLowerCase());
|
|
@@ -149,6 +149,9 @@ export function dispatchProviderFromRuntime(runtimeMode) {
|
|
|
149
149
|
if (normalized.length === 0) {
|
|
150
150
|
return "unknown";
|
|
151
151
|
}
|
|
152
|
+
if (normalized.includes("openclaw")) {
|
|
153
|
+
return "openclaw";
|
|
154
|
+
}
|
|
152
155
|
if (normalized.includes("grok")) {
|
|
153
156
|
return "grok";
|
|
154
157
|
}
|
|
@@ -161,13 +164,20 @@ export function dispatchProviderFromRuntime(runtimeMode) {
|
|
|
161
164
|
* Resolve the `dispatch_provider` routing key from the active runtime envelope.
|
|
162
165
|
* Separate from `runtime_mode` (#1557): Cursor sessions may carry
|
|
163
166
|
* `runtime_mode=cloud-headless` for gh-auth purposes but route under provider
|
|
164
|
-
* `cursor` for model selection (#1877).
|
|
167
|
+
* `cursor` for model selection (#1877). OpenClaw routes under `openclaw` when
|
|
168
|
+
* `sessions_spawn` / OPENCLAW signals are present (#2875).
|
|
165
169
|
*/
|
|
166
170
|
export function resolveDispatchProvider(environ = process.env) {
|
|
167
171
|
if (envTruthy(environ, "CURSOR_COMPOSER") || envTruthy(environ, "CURSOR_AGENT")) {
|
|
168
172
|
return "cursor";
|
|
169
173
|
}
|
|
170
174
|
const runtime = (environ.DEFT_AGENT_RUNTIME ?? "").trim().toLowerCase();
|
|
175
|
+
if (envTruthy(environ, "OPENCLAW") ||
|
|
176
|
+
envTruthy(environ, "DEFT_HAS_SESSIONS_SPAWN") ||
|
|
177
|
+
envTruthy(environ, "DEFT_PROBE_SESSIONS_SPAWN") ||
|
|
178
|
+
runtime === "openclaw") {
|
|
179
|
+
return "openclaw";
|
|
180
|
+
}
|
|
171
181
|
if (envTruthy(environ, "GROK_BUILD") || runtime === "grok-build") {
|
|
172
182
|
return "grok";
|
|
173
183
|
}
|
|
@@ -178,7 +188,9 @@ export function resolveDispatchProvider(environ = process.env) {
|
|
|
178
188
|
envTruthy(environ, "BUILDKITE") ||
|
|
179
189
|
(envTruthy(environ, "CI") &&
|
|
180
190
|
!envTruthy(environ, "CURSOR_COMPOSER") &&
|
|
181
|
-
!envTruthy(environ, "CURSOR_AGENT")
|
|
191
|
+
!envTruthy(environ, "CURSOR_AGENT") &&
|
|
192
|
+
!envTruthy(environ, "OPENCLAW") &&
|
|
193
|
+
!envTruthy(environ, "DEFT_HAS_SESSIONS_SPAWN"))) {
|
|
182
194
|
return "cloud-headless";
|
|
183
195
|
}
|
|
184
196
|
return "unknown";
|
|
@@ -135,13 +135,13 @@ export declare const registryData: {
|
|
|
135
135
|
};
|
|
136
136
|
readonly "task triage:show": {
|
|
137
137
|
readonly name: "task triage:show";
|
|
138
|
-
readonly summary: "Per-issue detail
|
|
139
|
-
readonly refs: "(D11 / #1128)";
|
|
140
|
-
readonly description: "Per-issue read-only detail (cached upstream payload + latest triage decision + audit timeline).
|
|
141
|
-
readonly usage: "task triage:show -- <N> [--repo=owner/name]";
|
|
142
|
-
readonly flags: readonly [readonly ["<N>", "(required)", "Issue number (positional)."], readonly ["--repo owner/name", "(git remote)", "Explicit repo override."]];
|
|
143
|
-
readonly examples: readonly ["task triage:show -- 42", "task triage:show -- 42 --repo deftai/directive"];
|
|
144
|
-
readonly see_also: readonly ["task triage:queue", "task triage:status", "#1119 / D11"];
|
|
138
|
+
readonly summary: "Per-issue detail + optional operator brief";
|
|
139
|
+
readonly refs: "(D11 / #1128, #2890)";
|
|
140
|
+
readonly description: "Per-issue read-only detail (cached upstream payload + latest triage decision + audit timeline). --format=operator emits a pasteable Phase 3 candidate brief backbone (title/link/labels/summary/AC/latest decision/active-xBRIEF); agent still owns lean. Exit 0 on hit, 1 on cache miss.";
|
|
141
|
+
readonly usage: "task triage:show -- <N> [--format=default|operator] [--repo=owner/name]";
|
|
142
|
+
readonly flags: readonly [readonly ["<N>", "(required)", "Issue number (positional)."], readonly ["--format default|operator", "default", "default = audit/cache detail; operator = Phase 3 pasteable brief (#2890)."], readonly ["--repo owner/name", "(git remote)", "Explicit repo override."]];
|
|
143
|
+
readonly examples: readonly ["task triage:show -- 42", "task triage:show -- 42 --format=operator", "task triage:show -- 42 --repo deftai/directive"];
|
|
144
|
+
readonly see_also: readonly ["task triage:queue", "task triage:status", "#1119 / D11", "#2890"];
|
|
145
145
|
readonly placeholder: false;
|
|
146
146
|
};
|
|
147
147
|
readonly "task triage:scope": {
|
|
@@ -209,16 +209,25 @@ export const registryData = {
|
|
|
209
209
|
},
|
|
210
210
|
"task triage:show": {
|
|
211
211
|
name: "task triage:show",
|
|
212
|
-
summary: "Per-issue detail
|
|
213
|
-
refs: "(D11 / #1128)",
|
|
214
|
-
description: "Per-issue read-only detail (cached upstream payload + latest triage decision + audit timeline).
|
|
215
|
-
usage: "task triage:show -- <N> [--repo=owner/name]",
|
|
212
|
+
summary: "Per-issue detail + optional operator brief",
|
|
213
|
+
refs: "(D11 / #1128, #2890)",
|
|
214
|
+
description: "Per-issue read-only detail (cached upstream payload + latest triage decision + audit timeline). --format=operator emits a pasteable Phase 3 candidate brief backbone (title/link/labels/summary/AC/latest decision/active-xBRIEF); agent still owns lean. Exit 0 on hit, 1 on cache miss.",
|
|
215
|
+
usage: "task triage:show -- <N> [--format=default|operator] [--repo=owner/name]",
|
|
216
216
|
flags: [
|
|
217
217
|
["<N>", "(required)", "Issue number (positional)."],
|
|
218
|
+
[
|
|
219
|
+
"--format default|operator",
|
|
220
|
+
"default",
|
|
221
|
+
"default = audit/cache detail; operator = Phase 3 pasteable brief (#2890).",
|
|
222
|
+
],
|
|
218
223
|
["--repo owner/name", "(git remote)", "Explicit repo override."],
|
|
219
224
|
],
|
|
220
|
-
examples: [
|
|
221
|
-
|
|
225
|
+
examples: [
|
|
226
|
+
"task triage:show -- 42",
|
|
227
|
+
"task triage:show -- 42 --format=operator",
|
|
228
|
+
"task triage:show -- 42 --repo deftai/directive",
|
|
229
|
+
],
|
|
230
|
+
see_also: ["task triage:queue", "task triage:status", "#1119 / D11", "#2890"],
|
|
222
231
|
placeholder: false,
|
|
223
232
|
},
|
|
224
233
|
"task triage:scope": {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* triage:show default + operator brief renderers (#1128 / #2890).
|
|
3
|
+
*
|
|
4
|
+
* Default format mirrors the pre-Python-removal `render_show` surface.
|
|
5
|
+
* `--format=operator` emits a pasteable Phase 3 candidate brief backbone;
|
|
6
|
+
* the agent still owns lean (not invented here).
|
|
7
|
+
*/
|
|
8
|
+
/** Loose audit row for show renderers (actions + queue shapes both work). */
|
|
9
|
+
export type ShowAuditRow = {
|
|
10
|
+
readonly decision?: string;
|
|
11
|
+
readonly timestamp?: string;
|
|
12
|
+
readonly actor?: string;
|
|
13
|
+
readonly reason?: string;
|
|
14
|
+
readonly issue_number?: number;
|
|
15
|
+
readonly repo?: string;
|
|
16
|
+
};
|
|
17
|
+
/** One cached issue with body fields needed by show/operator formats. */
|
|
18
|
+
export interface CachedIssueDetail {
|
|
19
|
+
readonly number: number;
|
|
20
|
+
readonly title: string;
|
|
21
|
+
readonly state: string;
|
|
22
|
+
readonly labels: readonly string[];
|
|
23
|
+
readonly updatedAt: string;
|
|
24
|
+
readonly body: string;
|
|
25
|
+
readonly htmlUrl: string | null;
|
|
26
|
+
}
|
|
27
|
+
/** Collapse CR/LF so cached attacker text cannot break markdown bullets (P2). */
|
|
28
|
+
export declare function oneLine(value: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a safe issue link. Always construct the canonical github.com path for
|
|
31
|
+
* `owner/name#N` rather than trusting payload URL substrings (CodeQL
|
|
32
|
+
* incomplete-url-substring-sanitization).
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveIssueHtmlUrl(repo: string, number: number): string;
|
|
35
|
+
/** Load a single cached issue (include closed) or null on miss. */
|
|
36
|
+
export declare function loadCachedIssueDetail(repo: string, number: number, options?: {
|
|
37
|
+
readonly projectRoot: string;
|
|
38
|
+
/** Absolute/relative path to `.deft-cache` root (CLI `--cache-root`). */
|
|
39
|
+
readonly cacheRoot?: string | null;
|
|
40
|
+
readonly source?: string;
|
|
41
|
+
}): CachedIssueDetail | null;
|
|
42
|
+
/** Default triage:show text (audit/cache oriented). */
|
|
43
|
+
export declare function renderShow(options: {
|
|
44
|
+
readonly issue: CachedIssueDetail | null;
|
|
45
|
+
readonly repo: string;
|
|
46
|
+
readonly number: number;
|
|
47
|
+
readonly latestDecision: ShowAuditRow | null;
|
|
48
|
+
readonly history: readonly ShowAuditRow[];
|
|
49
|
+
readonly inActiveXbrief: boolean;
|
|
50
|
+
}): string;
|
|
51
|
+
/**
|
|
52
|
+
* Extract a short problem/context summary (2–5 lines) from issue body.
|
|
53
|
+
* Prefers text before the first `##` section; falls back to leading paragraphs.
|
|
54
|
+
*/
|
|
55
|
+
export declare function extractBodySummary(body: string, maxLines?: number): string;
|
|
56
|
+
/**
|
|
57
|
+
* Extract acceptance-criteria bullets from body, or a thin-body note.
|
|
58
|
+
* Looks for AC / Acceptance headings and checkbox / bullet lists under them.
|
|
59
|
+
*/
|
|
60
|
+
export declare function extractAcceptanceCriteria(body: string): readonly string[];
|
|
61
|
+
/** Operator-facing pasteable brief backbone for Phase 3 decisions (#2890). */
|
|
62
|
+
export declare function renderOperatorBrief(options: {
|
|
63
|
+
readonly issue: CachedIssueDetail | null;
|
|
64
|
+
readonly repo: string;
|
|
65
|
+
readonly number: number;
|
|
66
|
+
readonly latestDecision: ShowAuditRow | null;
|
|
67
|
+
readonly inActiveXbrief: boolean;
|
|
68
|
+
}): string;
|
|
69
|
+
//# sourceMappingURL=show.d.ts.map
|