@mstar-harness/dsh 2.1.1
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/README.i18n.yaml +7 -0
- package/README.md +448 -0
- package/README.zh.md +221 -0
- package/bundle/README.md +312 -0
- package/bundle/cordis.patch.yml +17 -0
- package/dist/client/index.d.ts +14 -0
- package/dist/client/panel/PanelView.d.ts +67 -0
- package/dist/client/panel/TabNav.d.ts +28 -0
- package/dist/client/panel/graph/event-log.d.ts +76 -0
- package/dist/client/panel/graph/project-graph.d.ts +499 -0
- package/dist/client/panel/graph/schema.d.ts +224 -0
- package/dist/client/panel/guards.d.ts +12 -0
- package/dist/client/panel/locale.d.ts +134 -0
- package/dist/client/panel/pages/AgentCanvasPage.d.ts +363 -0
- package/dist/client/panel/pages/EventLogPage.d.ts +48 -0
- package/dist/client/panel/pages/IterationInfoSection.d.ts +80 -0
- package/dist/client/panel/pages/IterationTaskPage.d.ts +37 -0
- package/dist/client/panel/panel-meta.d.ts +18 -0
- package/dist/client/panel/plan-sort.d.ts +54 -0
- package/dist/client/panel/sidebar.d.ts +17 -0
- package/dist/client/panel/state-section.d.ts +23 -0
- package/dist/client/panel/use-mstar-engine-status.d.ts +42 -0
- package/dist/client/panel/zones/Legend.d.ts +18 -0
- package/dist/client/panel/zones/TaskBoard.d.ts +40 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +4486 -0
- package/dist/gates/_shared.d.ts +198 -0
- package/dist/gates/adapter.d.ts +131 -0
- package/dist/gates/agent-flow.d.ts +320 -0
- package/dist/gates/catalog.d.ts +118 -0
- package/dist/gates/dispatch.d.ts +152 -0
- package/dist/gates/seams.d.ts +152 -0
- package/dist/gates/skill-lint.d.ts +87 -0
- package/dist/gates/status.d.ts +81 -0
- package/dist/gates/tools.d.ts +37 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.js +5748 -0
- package/dist/invariant.d.ts +15 -0
- package/dist/invariant.js +29 -0
- package/dist/service.d.ts +96 -0
- package/dist/types.d.ts +241 -0
- package/harness-commands/codebase-audit.md +40 -0
- package/harness-commands/iteration-drive.md +129 -0
- package/harness-commands/iteration-loop.md +139 -0
- package/harness-commands/iteration-start.md +179 -0
- package/harness-skills/grill-me/SKILL.md +10 -0
- package/harness-skills/mstar-audit/SKILL.md +183 -0
- package/harness-skills/mstar-audit/references/audit-playbook.md +130 -0
- package/harness-skills/mstar-audit/references/finding-format.md +65 -0
- package/harness-skills/mstar-branch-worktree/SKILL.md +219 -0
- package/harness-skills/mstar-branch-worktree/references/parallel-writable-pre-dispatch.md +68 -0
- package/harness-skills/mstar-coding-behavior/SKILL.md +147 -0
- package/harness-skills/mstar-compound/SKILL.md +105 -0
- package/harness-skills/mstar-compound/assets/resolution-template.md +94 -0
- package/harness-skills/mstar-compound/references/category-mapping.md +37 -0
- package/harness-skills/mstar-compound/references/compound-workflow.md +155 -0
- package/harness-skills/mstar-compound/references/concepts-vocabulary.md +44 -0
- package/harness-skills/mstar-compound/references/schema.yaml +122 -0
- package/harness-skills/mstar-compound-refresh/SKILL.md +140 -0
- package/harness-skills/mstar-compound-refresh/references/project-knowledge-bootstrap.md +164 -0
- package/harness-skills/mstar-design-md/SKILL.md +142 -0
- package/harness-skills/mstar-design-md/references/completeness-checklist.md +181 -0
- package/harness-skills/mstar-design-md/references/design-md-spec.md +508 -0
- package/harness-skills/mstar-design-md/references/vercel-example.md +200 -0
- package/harness-skills/mstar-design-md/templates/DESIGN.dark.md.template +354 -0
- package/harness-skills/mstar-design-md/templates/DESIGN.md.template +474 -0
- package/harness-skills/mstar-dispatch-gates/SKILL.md +128 -0
- package/harness-skills/mstar-dispatch-gates/references/leaf-executor-checklist.md +23 -0
- package/harness-skills/mstar-harness-core/SKILL.md +180 -0
- package/harness-skills/mstar-host/SKILL.md +78 -0
- package/harness-skills/mstar-host/references/_shared/host-role-binding-core.md +51 -0
- package/harness-skills/mstar-host/references/_shared/plan-mode-bridge-core.md +91 -0
- package/harness-skills/mstar-host/references/codex.md +61 -0
- package/harness-skills/mstar-host/references/cursor-plan-mode-bridge.md +159 -0
- package/harness-skills/mstar-host/references/cursor.md +183 -0
- package/harness-skills/mstar-host/references/dsh.md +502 -0
- package/harness-skills/mstar-host/references/kimi-plan-mode-bridge.md +36 -0
- package/harness-skills/mstar-host/references/kimi.md +136 -0
- package/harness-skills/mstar-host/references/omp-plan-mode-bridge.md +32 -0
- package/harness-skills/mstar-host/references/omp.md +244 -0
- package/harness-skills/mstar-host/references/opencode.md +76 -0
- package/harness-skills/mstar-host/references/parallel-dispatch.md +68 -0
- package/harness-skills/mstar-host/references/zcode-plan-mode-bridge.md +36 -0
- package/harness-skills/mstar-host/references/zcode.md +129 -0
- package/harness-skills/mstar-iteration/SKILL.md +393 -0
- package/harness-skills/mstar-iteration/references/autonomous-direction-lock.md +90 -0
- package/harness-skills/mstar-iteration/references/iteration-artifact-boundaries.md +103 -0
- package/harness-skills/mstar-iteration/references/iteration-compass-template.md +142 -0
- package/harness-skills/mstar-iteration/references/iteration-corpus-hygiene.md +45 -0
- package/harness-skills/mstar-iteration/references/iteration-workspace-readme-template.md +27 -0
- package/harness-skills/mstar-iteration/references/phase-2-worktree-lease.md +193 -0
- package/harness-skills/mstar-iteration/references/phase-3-iteration-close.md +95 -0
- package/harness-skills/mstar-iteration/references/phase-4-5-pr-delivery.md +84 -0
- package/harness-skills/mstar-iteration/references/phase5-helper-discovery.md +24 -0
- package/harness-skills/mstar-phase-gates/SKILL.md +112 -0
- package/harness-skills/mstar-plan-artifacts/SKILL.md +46 -0
- package/harness-skills/mstar-plan-artifacts/references/done-compaction.md +88 -0
- package/harness-skills/mstar-plan-artifacts/references/knowledge-and-designs.md +100 -0
- package/harness-skills/mstar-plan-artifacts/references/plan-files-and-reports.md +99 -0
- package/harness-skills/mstar-plan-artifacts/references/plan-quality-bar.md +99 -0
- package/harness-skills/mstar-plan-artifacts/references/status-and-residuals.md +570 -0
- package/harness-skills/mstar-plan-artifacts/templates/README.md +9 -0
- package/harness-skills/mstar-plan-artifacts/templates/notes.empty.json +5 -0
- package/harness-skills/mstar-plan-artifacts/templates/plan.main.md +54 -0
- package/harness-skills/mstar-plan-artifacts/templates/plans-done.empty.json +3 -0
- package/harness-skills/mstar-plan-artifacts/templates/status.empty.json +7 -0
- package/harness-skills/mstar-plan-conventions/SKILL.md +165 -0
- package/harness-skills/mstar-plan-conventions/references/artifact-storage-paths.md +50 -0
- package/harness-skills/mstar-plan-conventions/references/effort-estimation.md +38 -0
- package/harness-skills/mstar-plan-conventions/references/harness-bootstrap-and-agents-layering.md +93 -0
- package/harness-skills/mstar-review-qc/SKILL.md +60 -0
- package/harness-skills/mstar-review-qc/references/review-responsibility-boundaries.md +54 -0
- package/harness-skills/mstar-roles/SKILL.md +86 -0
- package/harness-skills/mstar-roles/references/_shared/leaf-executor-core.md +46 -0
- package/harness-skills/mstar-roles/references/architect.md +114 -0
- package/harness-skills/mstar-roles/references/code-reviewer.md +109 -0
- package/harness-skills/mstar-roles/references/frontend-dev.md +70 -0
- package/harness-skills/mstar-roles/references/fullstack-dev-shared.md +89 -0
- package/harness-skills/mstar-roles/references/ops-engineer.md +78 -0
- package/harness-skills/mstar-roles/references/product-manager.md +107 -0
- package/harness-skills/mstar-roles/references/project-manager/dispatch-and-assignment.md +198 -0
- package/harness-skills/mstar-roles/references/project-manager/plan-management.md +61 -0
- package/harness-skills/mstar-roles/references/project-manager/qa-trigger-matrix.md +56 -0
- package/harness-skills/mstar-roles/references/project-manager/qc-and-residuals.md +98 -0
- package/harness-skills/mstar-roles/references/project-manager/routing-and-dev-allocation.md +99 -0
- package/harness-skills/mstar-roles/references/project-manager.md +310 -0
- package/harness-skills/mstar-roles/references/prompt-engineer.md +71 -0
- package/harness-skills/mstar-roles/references/qa-engineer/acceptance-gate.md +62 -0
- package/harness-skills/mstar-roles/references/qa-engineer.md +79 -0
- package/harness-skills/mstar-roles/references/qc-specialist/deep-review-lenses.md +95 -0
- package/harness-skills/mstar-roles/references/qc-specialist/report-template.md +72 -0
- package/harness-skills/mstar-roles/references/qc-specialist/reviewer-checklist.md +44 -0
- package/harness-skills/mstar-roles/references/qc-specialist/reviewer-workflow.md +57 -0
- package/harness-skills/mstar-roles/references/qc-specialist-shared.md +128 -0
- package/harness-skills/mstar-roles/references/writing-specialist.md +59 -0
- package/harness-skills/mstar-sdd/SKILL.md +133 -0
- package/harness-skills/mstar-sdd/references/file-handoffs.md +83 -0
- package/harness-skills/mstar-sdd/references/implementer-continuation-prompt.md +44 -0
- package/harness-skills/mstar-sdd/references/implementer-prompt.md +56 -0
- package/harness-skills/mstar-sdd/references/sticky-implementer-session.md +103 -0
- package/harness-skills/mstar-sdd/references/task-reviewer-prompt.md +53 -0
- package/harness-skills/mstar-skill-authoring/SKILL.md +162 -0
- package/harness-skills/mstar-skill-authoring/references/skillsbench-authoring.md +117 -0
- package/harness-skills/mstar-strategy/SKILL.md +130 -0
- package/harness-skills/pm/SKILL.md +40 -0
- package/package.json +92 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import z from 'schemastery';
|
|
2
|
+
import type { GateResult, ValidationResult } from '@mstar-harness/engine';
|
|
3
|
+
import type { Config as SkillLocalConfig } from '@deepseek-ai/dsh-skill-filesystem';
|
|
4
|
+
import type { IterationGateListView, IterationGateViolationView } from '../types.ts';
|
|
5
|
+
/** Canonical harness status file name (mstar-plan-artifacts status.json). */
|
|
6
|
+
export declare const STATUS_FILE = "status.json";
|
|
7
|
+
/** Plugin configuration. */
|
|
8
|
+
export interface Config {
|
|
9
|
+
/**
|
|
10
|
+
* Explicit harness root. When set, wins over engine probing (plan-conventions
|
|
11
|
+
* `{HARNESS_DIR}` resolution order); when absent the plugin probes from
|
|
12
|
+
* the SESSION workspace root (`agent.session.header.cwd`) — never the
|
|
13
|
+
* process cwd — walking `.mstar/` → `.agents/` → `.plans/`/`plans/`.
|
|
14
|
+
* Required for repos whose harness root is not a probed name (e.g. a
|
|
15
|
+
* `.harness/` maintenance root).
|
|
16
|
+
*/
|
|
17
|
+
harnessDir?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Per-deployment enforcement override. `hard` forces
|
|
20
|
+
* hard gates, `soft` forces warn-only even when an active iteration compass
|
|
21
|
+
* declares `enforcement: hard` (local rollback); absent → the compass
|
|
22
|
+
* frontmatter decides, warn-only when no compass hardens (never a global default).
|
|
23
|
+
*/
|
|
24
|
+
enforcement?: 'hard' | 'soft';
|
|
25
|
+
/**
|
|
26
|
+
* Model-facing delegation tool name(s) the dispatch gate matches. The dsh
|
|
27
|
+
* subagent tool registers as `subagent` by default, but its `toolName`
|
|
28
|
+
* config may rename instances (tool-subagent README: each instance needs a
|
|
29
|
+
* distinct name), so the match list is deployment-settable. Defaults to
|
|
30
|
+
* `['subagent']`.
|
|
31
|
+
*/
|
|
32
|
+
dispatchTools?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* The dispatching agent's own harness role/type (e.g. `fullstack-dev`), used
|
|
35
|
+
* as the anti-recursion binding: an Assignment whose `Execute as` equals this
|
|
36
|
+
* role is a self-dispatch (critical violation — leaf executors must not
|
|
37
|
+
* re-invoke their own role). dsh exposes no agent role on the tool-execution
|
|
38
|
+
* context, so the deployment declares it. Absent → the anti-recursion
|
|
39
|
+
* precheck is skipped (an empty binding is not self-recursion).
|
|
40
|
+
*/
|
|
41
|
+
dispatchBinding?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Additional skill roots registered with the dsh skill-filesystem provider
|
|
44
|
+
* (skill-filesystem `Config.customSkillDirs` semantics — scanned after project
|
|
45
|
+
* roots and before user roots — single canonical mount).
|
|
46
|
+
* Dev-time: the mirror `<repo-root>/skills` absolute path. Each root's
|
|
47
|
+
* children are skill dirs (`<name>/SKILL.md`) or flat skill files
|
|
48
|
+
* (`<name>.md`). Absent → no custom-root registration.
|
|
49
|
+
*/
|
|
50
|
+
skillRoots?: string[];
|
|
51
|
+
/**
|
|
52
|
+
* Bundled skill root registered with the dsh skill-filesystem provider
|
|
53
|
+
* (skill-filesystem `Config.bundledSkillDir` semantics — scanned last, trusted).
|
|
54
|
+
* Production: a `skills/` dir shipped inside the plugin package (the
|
|
55
|
+
* canonical published form — dsh defaults `$DSH_BUNDLED_SKILL_DIR` when
|
|
56
|
+
* default roots are included; this plugin mounts an isolated provider, so
|
|
57
|
+
* the bundled root is registered explicitly). Absent → no bundled-root
|
|
58
|
+
* registration.
|
|
59
|
+
*/
|
|
60
|
+
bundledSkillDir?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Catalog refresh interval in milliseconds — how often the per-workspace
|
|
63
|
+
* pre-step catalog cache (engine-status watermark, iteration-gate row,
|
|
64
|
+
* harness-state row) re-reads status.json / the compass / the knowledge
|
|
65
|
+
* index. Default 60000: a mid-session plan/compass/residual change lands
|
|
66
|
+
* within one TTL (the hot path stays a timestamp compare + cache hit
|
|
67
|
+
* between refreshes; a bounded sync re-read per workspace at most once
|
|
68
|
+
* per interval). Absent → 60000.
|
|
69
|
+
*/
|
|
70
|
+
catalogTtlMs?: number;
|
|
71
|
+
}
|
|
72
|
+
/** Schemastery configuration schema for the plugin consumer. Object keys are optional by default (`.optional()` is a vendored-fork addition not present in npm schemastery); omitted ARRAY keys would materialize as `[]` (schemastery empty-value default — the tool-subagent `toolFilter` pitfall), so both dispatch keys preserve omission via `.default(undefined)`. */
|
|
73
|
+
export declare const Config: z<Config>;
|
|
74
|
+
/** One violation line for logs and the typed veto message. */
|
|
75
|
+
export declare function formatViolation(violation: ValidationResult): string;
|
|
76
|
+
/** Narrow an unknown value to a record. */
|
|
77
|
+
export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Resolve the hard-enforcement flag for the artifact gates: explicit
|
|
80
|
+
* Config override wins, else the iteration compass frontmatter (when a
|
|
81
|
+
* harness dir resolves), else warn-only. {@link resolveHard} parity with a
|
|
82
|
+
* null-tolerant harness dir — the skill roots and the artifact
|
|
83
|
+
* seams (design-md / audit / compound / roles) do not require
|
|
84
|
+
* `{HARNESS_DIR}` (compound scoping is the only seam that does, and only
|
|
85
|
+
* for its knowledge-path matcher).
|
|
86
|
+
*/
|
|
87
|
+
export declare function resolveSeamHard(harnessDir: string | null, config: Config): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Resolve the plugin package's own `harness-skills/` mirror (synced from the
|
|
90
|
+
* repo root by `bundle-assets` at build/postinstall; gitignored), anchored at
|
|
91
|
+
* the file URL of one module in the package. Pure — the caller passes its own
|
|
92
|
+
* module URL string, so the dual-depth resolution is directly unit-testable
|
|
93
|
+
* at either layout depth without touching `import.meta`. Resolved
|
|
94
|
+
* package-relative — NOT cwd-anchored — so the shipped bundled mount works
|
|
95
|
+
* from any launch cwd (this resolves the cwd-anchoring limitation for the
|
|
96
|
+
* default; an explicit `bundledSkillDir` still wins). Returns undefined when
|
|
97
|
+
* the mirror is absent (e.g. a checkout where `bundle-assets` has not run —
|
|
98
|
+
* the default mount is then inert).
|
|
99
|
+
*
|
|
100
|
+
* Dual-depth probe semantics: the module moved from `src/index.ts` (one level
|
|
101
|
+
* below the package root) into `src/gates/_shared.ts` (two levels below in
|
|
102
|
+
* the source layout, but still inlined one level below in the bundled
|
|
103
|
+
* `dist/index.js`). Probe both depths — same dual-depth pattern as
|
|
104
|
+
* `pluginVersion()` — so the mirror resolves identically from source and from
|
|
105
|
+
* the bundle (behavior-preserving move; the dist path is the original one):
|
|
106
|
+
* - `'../harness-skills'` — dist 布局候选(`dist/index.js` 深度):shipped
|
|
107
|
+
* form(`package.json` `main: ./dist/index.js`),第一候选直接命中;
|
|
108
|
+
* - `'../../harness-skills'` — 源码布局候选(`src/gates/` 深度):dev-time
|
|
109
|
+
* form;该深度下第一候选解析到 `src/harness-skills`——非规范路径——落空后
|
|
110
|
+
* 命中本候选(规范 `packages/dsh/harness-skills`)。
|
|
111
|
+
* `src/harness-skills` 非规范(镜像仅由 `bundle-assets` 生成到规范位置);
|
|
112
|
+
* 若同名目录意外出现(陈旧镜像),shallow-first 既定——dist 布局命中优先于
|
|
113
|
+
* 源码布局,与 `pluginVersion()` 探测顺序一致(源/dist 不分叉)。
|
|
114
|
+
*
|
|
115
|
+
* @param fileUrl - the module's `import.meta.url` string (or any file URL at
|
|
116
|
+
* the depth whose layout should be probed).
|
|
117
|
+
*/
|
|
118
|
+
export declare function resolvePackagedSkillsDir(fileUrl: string): string | undefined;
|
|
119
|
+
export declare function packagedSkillsDir(): string | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* Per-workspace `{HARNESS_DIR}` resolution for the plugin.
|
|
122
|
+
*
|
|
123
|
+
* The probe NEVER starts from the process cwd — it starts from the WORKSPACE
|
|
124
|
+
* root of the session whose agent drives the event (the session cwd,
|
|
125
|
+
* `agent.session.header.cwd` — the dsh workspace the user opened) AND stops
|
|
126
|
+
* there: `workspaceRoot = 探测起点` (roadmap §7c), so the walk-up never
|
|
127
|
+
* leaves the session workspace (the `~/.mstar` global-collision defect is
|
|
128
|
+
* the special case) and the dsh boundary deliberately diverges from the
|
|
129
|
+
* CLI's git-top-level boundary. An
|
|
130
|
+
* explicit `harnessDir` config still wins outright (resolved once at boot;
|
|
131
|
+
* a relative value is launch-cwd anchored — config path anchoring, not
|
|
132
|
+
* probing — matching the `bundledSkillDir` precedent and the engine's
|
|
133
|
+
* `resolve(startDir, explicit)` semantics). Probing results are memoized
|
|
134
|
+
* per workspace root, so the agent-loop hot path does one Map lookup after
|
|
135
|
+
* the first event of each workspace.
|
|
136
|
+
*
|
|
137
|
+
* An event without a session workspace (no agent / no header cwd) resolves
|
|
138
|
+
* to the explicit config or `null` — never a process-cwd probe: without a
|
|
139
|
+
* workspace there is nothing to probe FROM.
|
|
140
|
+
*/
|
|
141
|
+
export declare class HarnessResolver {
|
|
142
|
+
private readonly explicit;
|
|
143
|
+
private readonly cache;
|
|
144
|
+
constructor(explicit: string | undefined);
|
|
145
|
+
/**
|
|
146
|
+
* Resolve for one workspace root (the session cwd).
|
|
147
|
+
* @param cwd - the workspace root; `undefined` when the event carries no session.
|
|
148
|
+
* @returns the resolved `{HARNESS_DIR}` (explicit override, else the probe
|
|
149
|
+
* from the workspace root), or `null` when none resolves.
|
|
150
|
+
*
|
|
151
|
+
* Boundary (roadmap §7c): the probe stops AT the workspace root —
|
|
152
|
+
* `workspaceRoot = 探测起点` (the session cwd itself), so it never walks up
|
|
153
|
+
* beyond the session workspace (the `~/.mstar` global-collision special
|
|
154
|
+
* case), and it does NOT inherit the engine's default git-top-level
|
|
155
|
+
* boundary (the CLI surface). An empty/missing `cwd` keeps the current
|
|
156
|
+
* contract: `null`, never a process-cwd probe.
|
|
157
|
+
*/
|
|
158
|
+
forWorkspace(cwd: string | undefined): string | null;
|
|
159
|
+
/**
|
|
160
|
+
* Resolve for one agent: the workspace root is the agent's session cwd.
|
|
161
|
+
* @param agent - the agent handle an event carries (structural read).
|
|
162
|
+
*/
|
|
163
|
+
forAgent(agent: unknown): string | null;
|
|
164
|
+
}
|
|
165
|
+
/** The workspace root of one agent — the session cwd (structural read; never trusts the runtime shape). */
|
|
166
|
+
export declare function sessionCwdOf(agent: unknown): string | undefined;
|
|
167
|
+
/** The tool-execution actor of one fs-intent event, when it carries an agent. */
|
|
168
|
+
export declare function actorAgentOf(actor: object | undefined): unknown;
|
|
169
|
+
/**
|
|
170
|
+
* Map one engine `ValidationResult` to its lossless JSON view (`fix` omitted
|
|
171
|
+
* when absent so `additionalProperties: false` never sees an undefined key).
|
|
172
|
+
* The view interfaces live in `types.ts` (shared with the pre-step
|
|
173
|
+
* iteration-gate catalog row).
|
|
174
|
+
*/
|
|
175
|
+
export declare function iterationViolationView(v: ValidationResult): IterationGateViolationView;
|
|
176
|
+
/** Map one engine gate (`GateResult`) to its JSON view. */
|
|
177
|
+
export declare function iterationGateView(gate: GateResult): IterationGateListView;
|
|
178
|
+
/**
|
|
179
|
+
* Build the dsh skill-filesystem registration payload from the plugin Config
|
|
180
|
+
* (single canonical mount). Semantics mirror the skill-filesystem
|
|
181
|
+
* `Config` contract: `skillRoots` → `customSkillDirs` (custom roots),
|
|
182
|
+
* `bundledSkillDir` → `bundledSkillDir` (bundled root). The provider is
|
|
183
|
+
* named `mstar` and default roots are excluded (`includeDefaultRoots: false`
|
|
184
|
+
* — the repository-plugin convention: an isolated provider must see only its
|
|
185
|
+
* explicit roots, so the mstar mount never claims the host app's own skills;
|
|
186
|
+
* without this the app's user/project skills would be re-discovered under
|
|
187
|
+
* the mstar provider). Returns `undefined` when nothing is configured — no
|
|
188
|
+
* registration happens.
|
|
189
|
+
*
|
|
190
|
+
* The bundled default is the package's OWN `harness-skills/` mirror (synced
|
|
191
|
+
* from the repo root by `bundle-assets` at build/postinstall; gitignored),
|
|
192
|
+
* resolved package-relative — NOT cwd-anchored — so a deployment launching
|
|
193
|
+
* from any cwd gets the bundled mount (this resolves the
|
|
194
|
+
* cwd-anchoring limitation for the shipped default; an explicit
|
|
195
|
+
* `bundledSkillDir` still wins).
|
|
196
|
+
* @param config - validated plugin configuration.
|
|
197
|
+
*/
|
|
198
|
+
export declare function skillLocalConfig(config: Config): SkillLocalConfig | undefined;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Service, type Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { AssignmentFields, GateResult, HostAdapter, IntegrationMergeLease, ValidationResult } from '@mstar-harness/engine';
|
|
3
|
+
import type { ToolExecution } from '@deepseek-ai/dsh-tools';
|
|
4
|
+
import type { HarnessResolver, Config } from './_shared.ts';
|
|
5
|
+
import type { AgentFlowPairing } from './agent-flow.ts';
|
|
6
|
+
/** Options for {@link DshHostAdapter}. */
|
|
7
|
+
export interface DshHostAdapterOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The per-workspace `{HARNESS_DIR}` resolver (explicit config wins; the
|
|
10
|
+
* probe never starts from the process cwd). The exec-bound gate paths
|
|
11
|
+
* resolve per the calling session's workspace.
|
|
12
|
+
*/
|
|
13
|
+
readonly resolver: HarnessResolver;
|
|
14
|
+
/** The plugin Config the gates resolve enforcement + anti-recursion binding from. */
|
|
15
|
+
readonly config: Config;
|
|
16
|
+
/**
|
|
17
|
+
* The apply-scoped agent-flow pairing store (plan
|
|
18
|
+
* `20260811-panel-f4-timeliness` Task 1 — created by the entry `apply`,
|
|
19
|
+
* shared with the settle listener): passed to `recordDispatch` so an
|
|
20
|
+
* exec-bound dispatch registers `callId → dispatchRef` for the later
|
|
21
|
+
* post-execute settle pairing. Absent (host-adapter tests / direct
|
|
22
|
+
* construction) → no pairing registration (record-only).
|
|
23
|
+
*/
|
|
24
|
+
readonly pairing?: AgentFlowPairing;
|
|
25
|
+
/**
|
|
26
|
+
* Log sink for `HostAdapter.log`. Defaults to the dsh ctx logger scoped
|
|
27
|
+
* `mstar/host-adapter` (dsh logger naming: `<scope>/<subject>`).
|
|
28
|
+
*/
|
|
29
|
+
readonly log?: (level: 'info' | 'warn' | 'error', msg: string) => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The plugin's `HostAdapter` implementation (engine `host.ts` type-only
|
|
33
|
+
* contract) — the HOST-FACING facade over the gate
|
|
34
|
+
* internals: `host: 'dsh'`, `log` → dsh ctx logger, and the optional hooks
|
|
35
|
+
* wired to the SAME code paths the in-plugin gates use, so host hooks and
|
|
36
|
+
* gates share ONE validation path:
|
|
37
|
+
*
|
|
38
|
+
* - `beforeStatusWrite(path, doc)` — validates the incoming document when
|
|
39
|
+
* the host provides it (the write's content — the opencode consumer
|
|
40
|
+
* convention for this engine hook), else the current on-disk document at
|
|
41
|
+
* `path` via the gate's single-read `validateStatusDoc` semantics (missing
|
|
42
|
+
* file = first create = pass). Both inputs flow through
|
|
43
|
+
* `validateStatusValue` — the same pipeline the fs-intent gate runs, so
|
|
44
|
+
* codes match by construction. Returns the FIRST violation: the engine
|
|
45
|
+
* hook shape is one `ValidationResult`; the gate's full violation list
|
|
46
|
+
* stays available on the fs-intent slot.
|
|
47
|
+
* - `beforeDispatch(assignment)` — the dispatch gate validation path
|
|
48
|
+
* (engine `composeDispatchGate` — fields + branch gate + anti-recursion —
|
|
49
|
+
* plus worktree L1/L2 checks; read-only roles skip the branch gate). The lease gate
|
|
50
|
+
* stays listener-side: it binds the ToolExecution context (session id)
|
|
51
|
+
* this hook's contract does not carry. The parsed `AssignmentFields` form
|
|
52
|
+
* is normalized to the engine's own header grammar (lossless — the
|
|
53
|
+
* parsers read exactly these labels) and gated through the same text path.
|
|
54
|
+
* Enforcement is applied like the listener (opencode parity): the
|
|
55
|
+
* returned GateResult carries `hardBlocked` so a refusal-capable host can
|
|
56
|
+
* refuse the dispatch.
|
|
57
|
+
* - `beforeMerge(lease)` — thin wrapper over the engine
|
|
58
|
+
* `validateIntegrationMergeLease` (reserve/validate the integration merge
|
|
59
|
+
* lease; the reservation WRITE into status.json is a P3 seam).
|
|
60
|
+
*/
|
|
61
|
+
export declare class DshHostAdapter extends Service implements HostAdapter {
|
|
62
|
+
/** Engine host identity (`HostId` union). */
|
|
63
|
+
readonly host: "dsh";
|
|
64
|
+
private readonly resolver;
|
|
65
|
+
private readonly config;
|
|
66
|
+
private readonly pairing;
|
|
67
|
+
private readonly logSink;
|
|
68
|
+
constructor(ctx: Context, options: DshHostAdapterOptions);
|
|
69
|
+
/**
|
|
70
|
+
* `HostAdapter.log` — the adapter's own reporting channel (the gates keep
|
|
71
|
+
* their scoped loggers; this is the host-facing sink).
|
|
72
|
+
* @param level - log level.
|
|
73
|
+
* @param msg - message.
|
|
74
|
+
*/
|
|
75
|
+
log(level: 'info' | 'warn' | 'error', msg: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Shared status-gate core (plugin-internal): the fs-intent listeners and
|
|
78
|
+
* the `beforeStatusWrite` on-disk fallback route through this method —
|
|
79
|
+
* ONE validation code path. Missing file = first create = pass (the
|
|
80
|
+
* intent waterfall carries no incoming content, so the vetoable signal is
|
|
81
|
+
* the pre-write on-disk state).
|
|
82
|
+
* @param statusPath - the canonical `{HARNESS_DIR}/status.json` path.
|
|
83
|
+
*/
|
|
84
|
+
statusGate(statusPath: string): GateResult;
|
|
85
|
+
/**
|
|
86
|
+
* Shared dispatch-gate core (plugin-internal): the `tools/pre-execute`
|
|
87
|
+
* listener and `beforeDispatch` route through this method — ONE
|
|
88
|
+
* validation code path (field gate + anti-recursion + branch gate +
|
|
89
|
+
* worktree L1/L2 checks; read-only roles skip the branch gate). The
|
|
90
|
+
* listener passes `exec` so the lease gate (ToolExecution-bound: session
|
|
91
|
+
* id, in-flight call) joins the same verdict; the host hook has no exec
|
|
92
|
+
* context and covers the field/branch/anti-recursion/worktree path.
|
|
93
|
+
* @param prompt - the Assignment text (engine header grammar).
|
|
94
|
+
* @param exec - the in-flight delegation tool call (listener path only).
|
|
95
|
+
* @param hard - the caller's ONE `resolveDispatchHard` resolution (qc1
|
|
96
|
+
* F-002 / qc2 F-3 / qc3 F-002 fix-wave): passed in so the record block and
|
|
97
|
+
* the caller's enforcement decision share a single compass resolution;
|
|
98
|
+
* when omitted (external callers) the adapter resolves it itself.
|
|
99
|
+
*/
|
|
100
|
+
dispatchGate(prompt: string, exec?: ToolExecution, hard?: boolean): GateResult;
|
|
101
|
+
/**
|
|
102
|
+
* `HostAdapter.beforeStatusWrite` — see the class doc for the doc-first /
|
|
103
|
+
* on-disk-fallback semantics. Never throws; a failing gate maps to its
|
|
104
|
+
* FIRST violation (severity/code/message/fix/aliases preserved — failing
|
|
105
|
+
* gates always carry ≥1 violation), a passing gate to
|
|
106
|
+
* `host.beforeStatusWrite.ok` (the engine test convention for this hook).
|
|
107
|
+
* @param path - the status.json target path.
|
|
108
|
+
* @param doc - the document about to be written (undefined → validate the
|
|
109
|
+
* on-disk document at `path`).
|
|
110
|
+
*/
|
|
111
|
+
beforeStatusWrite(path: string, doc: unknown): Promise<ValidationResult>;
|
|
112
|
+
/**
|
|
113
|
+
* `HostAdapter.beforeDispatch` — the dispatch gate validation path (see
|
|
114
|
+
* the class doc). Accepts the raw Assignment text (full fidelity: the
|
|
115
|
+
* `Enforcement` header flag participates in enforcement resolution) or the
|
|
116
|
+
* parsed `AssignmentFields` (engine-typed hook input; normalized to the
|
|
117
|
+
* engine's header grammar before gating). Returns the enforced GateResult
|
|
118
|
+
* — `hardBlocked` mirrors the `tools/pre-execute` deny decision under the
|
|
119
|
+
* same enforcement resolution.
|
|
120
|
+
* @param assignment - raw Assignment text or parsed header fields.
|
|
121
|
+
*/
|
|
122
|
+
beforeDispatch(assignment: AssignmentFields | string): Promise<GateResult>;
|
|
123
|
+
/**
|
|
124
|
+
* `HostAdapter.beforeMerge` — reserve/validate the integration merge
|
|
125
|
+
* lease. Thin wrapper over the engine `validateIntegrationMergeLease`
|
|
126
|
+
* (the engine owns the lease shape; the reservation write into
|
|
127
|
+
* `{HARNESS_DIR}/status.json` is a P3 seam).
|
|
128
|
+
* @param lease - the `metadata.integration_merge_lease` object.
|
|
129
|
+
*/
|
|
130
|
+
beforeMerge(lease: IntegrationMergeLease): Promise<GateResult>;
|
|
131
|
+
}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { type Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { AgentFlowView } from '../types.ts';
|
|
3
|
+
import type { Config } from './_shared.ts';
|
|
4
|
+
/** The agent-flow ledger file name under `{HARNESS_DIR}`. */
|
|
5
|
+
export declare const AGENT_FLOW_FILE = "agent-flow.jsonl";
|
|
6
|
+
/** Truncation bound: the ledger keeps only the most recent events. */
|
|
7
|
+
export declare const AGENT_FLOW_MAX_EVENTS = 500;
|
|
8
|
+
/** Default read limit (the catalog passes 50 per spec §2.2). */
|
|
9
|
+
export declare const AGENT_FLOW_DEFAULT_LIMIT = 50;
|
|
10
|
+
/**
|
|
11
|
+
* The append size gate (qc2 F-1 / qc3 F-001/003 — fix-wave): the truncation
|
|
12
|
+
* read-modify-write runs only when the file exceeds ~500 lines' typical
|
|
13
|
+
* size (conservative ≈ 500 × 128 B average line); smaller files stay
|
|
14
|
+
* append-only. The bound is therefore approximate ("~500 events") — a file
|
|
15
|
+
* of unusually tiny events can grow past 500 lines under the gate until its
|
|
16
|
+
* BYTES cross the threshold (documented tradeoff; the gate keeps the common
|
|
17
|
+
* small-file append path free of a full read per dispatch).
|
|
18
|
+
*/
|
|
19
|
+
export declare const AGENT_FLOW_SIZE_GATE_BYTES: number;
|
|
20
|
+
/** Logger label for the agent-flow ledger (dsh logger naming: `<scope>/<subject>`). */
|
|
21
|
+
export declare const AGENT_FLOW_LOGGER = "mstar/agent-flow";
|
|
22
|
+
/**
|
|
23
|
+
* The settle seam name — the dsh-tools registry's `tools/post-execute`
|
|
24
|
+
* waterfall. VERIFIED to be dispatched by the real registry for every tool
|
|
25
|
+
* call (`runPostExecute` → `postExecute`, upstream source; pinned by the
|
|
26
|
+
* real-call probe in `tests/agent-flow.spec.ts`), so settles are no longer
|
|
27
|
+
* host-emission-dependent (plan `20260811-panel-f4-timeliness` Task 1 — the
|
|
28
|
+
* old "not part of the verified surface" assumption is obsolete).
|
|
29
|
+
*/
|
|
30
|
+
export declare const SETTLE_SEAM = "tools/post-execute";
|
|
31
|
+
/**
|
|
32
|
+
* The once-per-apply settle-pairing trace (plan `20260811-panel-f4-timeliness`
|
|
33
|
+
* Task 1). Historical name `SETTLE_SEAM_UNAVAILABLE_NOTE` (qc1 F-105 / qc2
|
|
34
|
+
* N-002 fix-wave): the old name claimed the seam was UNAVAILABLE, which the
|
|
35
|
+
* message itself refutes — the seam IS a verified part of the registry
|
|
36
|
+
* surface, so the constant was renamed to the accurate `PAIRING` name. The
|
|
37
|
+
* message states the VERIFIED pairing facts: the seam is emitted by the
|
|
38
|
+
* registry; foreground dispatch calls settle via it, background subagents
|
|
39
|
+
* settle via `ctx.jobs.onJobDone` pairing; only unpaired payloads stay
|
|
40
|
+
* dispatch-only (never fabricated settlement). Logged ONCE per logger binding
|
|
41
|
+
* (≈ once per apply — the same module-level flag, qc1 F-006) when the pairing
|
|
42
|
+
* listener is registered.
|
|
43
|
+
*/
|
|
44
|
+
export declare const SETTLE_SEAM_PAIRING_NOTE = "settle seam \"tools/post-execute\" IS part of the verified dsh-tools registry surface (runPostExecute dispatches it for every tool call) \u2014 foreground dispatch calls settle here, background subagents settle via ctx.jobs.onJobDone pairing; only UNPAIRED payloads (non-dispatch tools, calls outside the apply-scoped pairing window) stay dispatch-only \u2014 never a fabricated settle";
|
|
45
|
+
/** Dispatch verdict vocabulary (spec §2.1.3). */
|
|
46
|
+
export type DispatchVerdict = 'ok' | 'advisory' | 'denied';
|
|
47
|
+
/** Settle outcome vocabulary (spec §2.1.3). */
|
|
48
|
+
export type SettleOutcome = 'ok' | 'error' | 'denied';
|
|
49
|
+
/**
|
|
50
|
+
* One v1 ledger event (spec §2.1.3 schema — the JSONL line). Optional fields
|
|
51
|
+
* are OMITTED from the serialized line when absent (Session.append's lossless
|
|
52
|
+
* JSON discipline starts at the record boundary).
|
|
53
|
+
*/
|
|
54
|
+
export type AgentFlowEvent = {
|
|
55
|
+
v: 1;
|
|
56
|
+
ts: number;
|
|
57
|
+
kind: 'dispatch';
|
|
58
|
+
/** The dispatching session's stable id (exec.agent.id; host-hook path has no exec → absent). */
|
|
59
|
+
agent?: string;
|
|
60
|
+
/** Assignment `Execute as` ('' when missing). */
|
|
61
|
+
role: string;
|
|
62
|
+
/** planIdOf(header): `Plan Path` / `SDD dir` / `plan_id` basename. */
|
|
63
|
+
planId?: string;
|
|
64
|
+
/** Body `Task N` best-effort extraction (taskIdOf). */
|
|
65
|
+
taskId?: string;
|
|
66
|
+
/** Assignment `Task category`. */
|
|
67
|
+
taskCategory?: string;
|
|
68
|
+
/** Gate verdict derivation: no violations → ok; hard + violations → denied; else advisory. */
|
|
69
|
+
verdict: DispatchVerdict;
|
|
70
|
+
/** resolveDispatchHard result (recorded unconditionally, incl. hard denies). */
|
|
71
|
+
hard: boolean;
|
|
72
|
+
} | {
|
|
73
|
+
v: 1;
|
|
74
|
+
ts: number;
|
|
75
|
+
kind: 'settle';
|
|
76
|
+
/** The settled session's stable id (the paired dispatch's agent). */
|
|
77
|
+
agent?: string;
|
|
78
|
+
outcome: SettleOutcome;
|
|
79
|
+
durationMs?: number;
|
|
80
|
+
/**
|
|
81
|
+
* The PAIRED dispatch's identity (plan `20260811-panel-f4-timeliness`
|
|
82
|
+
* Task 1) — same field names + semantics as the dispatch event:
|
|
83
|
+
* `role` is the Assignment `Execute as` ('' when missing), `planId` /
|
|
84
|
+
* `taskId` the plan + `Task N` tags. Written for every paired settle;
|
|
85
|
+
* ABSENT on unpaired (legacy) settles — the client pairs on identity
|
|
86
|
+
* presence. The registry background-task id is deliberately NOT
|
|
87
|
+
* written here (`taskRef` is reserved as the distinct field name if a
|
|
88
|
+
* future audit needs it — it never collides with `taskId`).
|
|
89
|
+
*/
|
|
90
|
+
role?: string;
|
|
91
|
+
planId?: string;
|
|
92
|
+
taskId?: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* The identity of one recorded dispatch, carried by the pairing store so a
|
|
96
|
+
* later completion (post-execute settle / onJobDone terminal) can record a
|
|
97
|
+
* settle carrying the SAME identity fields as its dispatch event.
|
|
98
|
+
*/
|
|
99
|
+
export interface AgentFlowDispatchRef {
|
|
100
|
+
/** The resolved `{HARNESS_DIR}` the dispatch recorded into (settles record into the same ledger). */
|
|
101
|
+
harnessDir: string;
|
|
102
|
+
/** The dispatching session's stable id ('' when the exec carried none). */
|
|
103
|
+
agent?: string;
|
|
104
|
+
/** Assignment `Execute as` ('' when missing — the dispatch event's grammar). */
|
|
105
|
+
role: string;
|
|
106
|
+
/** `planIdOf(header)` — the dispatch event's grammar. */
|
|
107
|
+
planId?: string;
|
|
108
|
+
/** `taskIdOf(prompt)` — the Assignment `Task N` tag, NOT a registry task id. */
|
|
109
|
+
taskId?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The apply-scoped pairing store (plan `20260811-panel-f4-timeliness` Task 1,
|
|
113
|
+
* decision D1 — created in the entry `apply`, same lifetime as the catalog
|
|
114
|
+
* cache; an HMR restart resets it, and completions outside the window stay
|
|
115
|
+
* unpaired → no settle, the documented honest degrade). Maps are keyed by
|
|
116
|
+
* the TWO verified pairing keys: the tool-call `callId` (pre → post-execute)
|
|
117
|
+
* and the registry background-task id (post-execute background shape →
|
|
118
|
+
* `onJobDone` terminal).
|
|
119
|
+
*/
|
|
120
|
+
export interface AgentFlowPairing {
|
|
121
|
+
/**
|
|
122
|
+
* The agent-namespaced call key → the dispatch it recorded (populated by
|
|
123
|
+
* `recordDispatch` when an exec is present). Key = `${sessionId}\u0000${callId}`
|
|
124
|
+
* (qc1 F-101 fix-wave): a raw `ToolExecution.callId` is NOT globally unique
|
|
125
|
+
* in one process — dsh runs many sessions concurrently and upstream mints
|
|
126
|
+
* per-message ids (`call-${index}`), so the dispatching session id must
|
|
127
|
+
* namespace the key or session B's same-id call could overwrite session A's
|
|
128
|
+
* pairing and mis-pair A's settle into B's dispatchRef. Consumed (deleted)
|
|
129
|
+
* by the post-execute branch — the map holds only in-flight calls.
|
|
130
|
+
*/
|
|
131
|
+
dispatchByCallId: Map<string, AgentFlowDispatchRef>;
|
|
132
|
+
/** Registry background-job id (`JobSnapshot.id`) → the dispatch that started it (populated by the post-execute background branch; consumed by `recordTaskSettle`). */
|
|
133
|
+
dispatchByTaskId: Map<string, AgentFlowDispatchRef>;
|
|
134
|
+
}
|
|
135
|
+
/** Module-scoped log sink (bound to `mstar/agent-flow` by the entry at apply). */
|
|
136
|
+
type AgentFlowLogSink = (level: 'info' | 'warn' | 'error', message: string) => void;
|
|
137
|
+
/**
|
|
138
|
+
* Module-scoped catalog-invalidation hook (plan `20260811-panel-f4-timeliness`
|
|
139
|
+
* Task 1 — the `invalidateCatalog` 挂钩 that Task 2 consumes): called with
|
|
140
|
+
* the affected `{HARNESS_DIR}` after every SUCCESSFUL ledger record
|
|
141
|
+
* (`recordDispatch` / `recordSettle`). The entry binds the real invalidation
|
|
142
|
+
* closure at apply (Task 2 shipped the apply-scoped harnessDir → cache-key
|
|
143
|
+
* reverse-map closure in `index.ts` — see `createCatalogInvalidation`);
|
|
144
|
+
* unbound → no-op. Never throws into the record path.
|
|
145
|
+
*/
|
|
146
|
+
type AgentFlowInvalidator = (harnessDir: string) => void;
|
|
147
|
+
/**
|
|
148
|
+
* Bind the module's catalog-invalidation hook (plan
|
|
149
|
+
* `20260811-panel-f4-timeliness` Task 1 — same pattern as
|
|
150
|
+
* {@link setAgentFlowLogger}; the entry binds at apply; Task 2 shipped the
|
|
151
|
+
* real binding — the apply-scoped harnessDir → cache-key reverse-map
|
|
152
|
+
* closure in `index.ts`).
|
|
153
|
+
* @param invalidate - the hook (`undefined` clears the binding).
|
|
154
|
+
* @returns the PREVIOUS hook (tests restore it in a `finally`).
|
|
155
|
+
*/
|
|
156
|
+
export declare function setAgentFlowInvalidator(invalidate: AgentFlowInvalidator | undefined): AgentFlowInvalidator | undefined;
|
|
157
|
+
/**
|
|
158
|
+
* Bind the module's log sink (called once at apply; tests may rebind to
|
|
159
|
+
* capture ledger logs). Rebinding RESETS the once-per-apply settle trace
|
|
160
|
+
* flag — each binding is a fresh "apply" (production binds once; tests bind
|
|
161
|
+
* per case for deterministic capture).
|
|
162
|
+
* @param sink - the sink (entry binds `ctx.logger('mstar/agent-flow')`);
|
|
163
|
+
* `undefined` clears the binding (restores the pre-bind no-op state).
|
|
164
|
+
* @returns the PREVIOUS sink (tests restore it in a `finally`).
|
|
165
|
+
*/
|
|
166
|
+
export declare function setAgentFlowLogger(sink: AgentFlowLogSink | undefined): AgentFlowLogSink | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* Best-effort extraction of the targeted `Task N` from the Assignment BODY
|
|
169
|
+
* (spec §2.1.1 — `taskIdOf`). The engine `assignmentHeaderRegion` boundary is
|
|
170
|
+
* reused: only text AFTER the header region is scanned, so a `## Task N`
|
|
171
|
+
* example quoted in the header never resolves a task id. Only a LEVEL-2
|
|
172
|
+
* heading (`^## Task N`) matches (qc2 F-8: an example or sub-heading at
|
|
173
|
+
* another depth before the real task must not resolve — lower false-hit
|
|
174
|
+
* surface); normalized to `T<n>` (matches the panel render `planId#taskId`,
|
|
175
|
+
* e.g. `20260810-x#T2`).
|
|
176
|
+
* @param prompt - the full Assignment text.
|
|
177
|
+
*/
|
|
178
|
+
export declare function taskIdOf(prompt: string): string | undefined;
|
|
179
|
+
/**
|
|
180
|
+
* Record one dispatch event (spec §2.1.3). Fully try/catch-contained — NEVER
|
|
181
|
+
* throws into the gate; a failing record logs only (`mstar/agent-flow`).
|
|
182
|
+
* Verdict derivation (ok/advisory/denied, incl. hard denies) and the header
|
|
183
|
+
* identity derivation (role / planId / taskId / taskCategory) reuse the gate's
|
|
184
|
+
* own parsers — one grammar.
|
|
185
|
+
*
|
|
186
|
+
* Pairing (plan `20260811-panel-f4-timeliness` Task 1): when the input
|
|
187
|
+
* carries an `exec` AND the apply-scoped `pairing` store, the successful
|
|
188
|
+
* record registers the agent-namespaced key `${sessionId}\u0000${callId}` →
|
|
189
|
+
* dispatchRef (the full dispatch identity), so a later
|
|
190
|
+
* `tools/post-execute` for the same call can settle with the SAME identity
|
|
191
|
+
* (qc1 F-101 fix-wave: the session id namespaces the key — a raw callId is
|
|
192
|
+
* not globally unique across sessions in one process). The pairing registers
|
|
193
|
+
* only after the ledger append SUCCEEDED — a failed record never pairs to a
|
|
194
|
+
* phantom dispatch. An exec-less record (host-hook path) has no callId → no
|
|
195
|
+
* pairing. The pairing sub-path has its OWN catch scope (qc1 F-106 / qc2
|
|
196
|
+
* N-001 / qc3 F-006 fix-wave): a `Map.set` throw must not log "record
|
|
197
|
+
* failed" after the dispatch was already appended.
|
|
198
|
+
* @param input - harness dir + exec (agent id) + Assignment text + the gate's
|
|
199
|
+
* violations + the hard-enforcement resolution + the apply-scoped pairing
|
|
200
|
+
* store (the adapter passes its own; direct callers may omit it).
|
|
201
|
+
*/
|
|
202
|
+
export declare function recordDispatch(input: {
|
|
203
|
+
harnessDir: string;
|
|
204
|
+
exec?: unknown;
|
|
205
|
+
prompt: string;
|
|
206
|
+
violations: readonly unknown[];
|
|
207
|
+
hard: boolean;
|
|
208
|
+
pairing?: AgentFlowPairing;
|
|
209
|
+
}): void;
|
|
210
|
+
/**
|
|
211
|
+
* Record one settle event (spec §2.1.3). Fully try/catch-contained; a failing
|
|
212
|
+
* record logs only. Callers resolve the harness dir from the PAIRED dispatch
|
|
213
|
+
* (the pairing store's dispatchRef — never a payload probe).
|
|
214
|
+
* @param input - harness dir + agent id + outcome + optional duration + the
|
|
215
|
+
* PAIRED dispatch's identity (`role`/`planId`/`taskId` — same field names +
|
|
216
|
+
* semantics as the dispatch event; written for every paired settle, so the
|
|
217
|
+
* client can exactly pair the settle back to its dispatch).
|
|
218
|
+
*/
|
|
219
|
+
export declare function recordSettle(input: {
|
|
220
|
+
harnessDir: string;
|
|
221
|
+
agent?: string;
|
|
222
|
+
outcome: SettleOutcome;
|
|
223
|
+
durationMs?: number;
|
|
224
|
+
role?: string;
|
|
225
|
+
planId?: string;
|
|
226
|
+
taskId?: string;
|
|
227
|
+
}): void;
|
|
228
|
+
/**
|
|
229
|
+
* Read the agent-flow ledger as the catalog view (spec §2.1.3 — fix-wave
|
|
230
|
+
* qc1 F-001 / qc2 F-6): the latest events first (bounded by `limit`) plus
|
|
231
|
+
* the role × outcome summary over the SAME window (so `by role` counts sum
|
|
232
|
+
* to the event count). A MISSING ledger file returns the EMPTY view
|
|
233
|
+
* `{ events: [], summary: [] }` — recording hasn't started (it begins at
|
|
234
|
+
* plan merge), and the panel renders its "no actual dispatches yet" empty
|
|
235
|
+
* state instead of an evidence-missing degrade; only an UNREADABLE file
|
|
236
|
+
* returns null (advisory degrade — the catalog renders no agent-flow line).
|
|
237
|
+
* Malformed lines are skipped, never fatal.
|
|
238
|
+
* @param harnessDir - the resolved `{HARNESS_DIR}`.
|
|
239
|
+
* @param limit - explicit window bound: `undefined` → `AGENT_FLOW_DEFAULT_LIMIT`;
|
|
240
|
+
* otherwise `Math.max(0, Math.floor(limit))` — `0` requests the EMPTY window.
|
|
241
|
+
*/
|
|
242
|
+
export declare function readAgentFlow(harnessDir: string, limit?: number): AgentFlowView | null;
|
|
243
|
+
/**
|
|
244
|
+
* The `tools/post-execute` settle pairing (plan `20260811-panel-f4-timeliness`
|
|
245
|
+
* Task 1 — replaces the old defensive payload probing): the VERIFIED
|
|
246
|
+
* dsh-tools registry dispatches this seam for every tool call
|
|
247
|
+
* (`runPostExecute` → `postExecute`, upstream source), so the listener only
|
|
248
|
+
* decides whether a completion signal exists for the PAIRED dispatch:
|
|
249
|
+
*
|
|
250
|
+
* - non-dispatch tool (`exec.name` ∉ Config `dispatchTools`) → nothing;
|
|
251
|
+
* - dispatch tool whose agent-namespaced call key
|
|
252
|
+
* (`${sessionId}\u0000${callId}`, qc1 F-101 fix-wave) is not in the pairing
|
|
253
|
+
* store (HMR reset, host-hook dispatch, non-gate path) → nothing (warned
|
|
254
|
+
* once per registration — honest degrade, never fabricated settlement);
|
|
255
|
+
* - `result.isError === true` OR an `error` payload present → settle `error`
|
|
256
|
+
* immediately (fabrication guard, qc2 F-001 / qc3 F-003a — the dispatch
|
|
257
|
+
* call failed; a result carrying `error` without `isError` never settles ok);
|
|
258
|
+
* - successful `result.value` shape `{ kind: 'background', taskId }` with a
|
|
259
|
+
* valid taskId → store `taskId → dispatchRef` (the real settle arrives via
|
|
260
|
+
* `ctx.jobs.onJobDone`); `{ kind: 'background' }` WITHOUT a valid taskId
|
|
261
|
+
* → nothing mappable (no settle, qc3 F-003b);
|
|
262
|
+
* - `{ kind: 'continuable', subagentId }` → no terminal signal this round →
|
|
263
|
+
* no settle (documented limit — the child owns its turns);
|
|
264
|
+
* - any other successful value (foreground `{ kind: 'foreground', … }`
|
|
265
|
+
* included) → settle `ok` (the call completed synchronously).
|
|
266
|
+
* The consumed `dispatchByCallId` entry is DELETED after the branch resolves
|
|
267
|
+
* the call (map pruning, qc1 F-102 / qc2 F-002 / qc3 F-002 — each callId
|
|
268
|
+
* pairs exactly once; the map holds only in-flight calls).
|
|
269
|
+
*
|
|
270
|
+
* The waterfall MUST be delegated via `next()` on every path — returning
|
|
271
|
+
* without calling `next` bails the chain and breaks every tool call. A
|
|
272
|
+
* throwing record never propagates.
|
|
273
|
+
*
|
|
274
|
+
* Cordis typing note: `ctx.on` only accepts declared event keys and
|
|
275
|
+
* `tools/post-execute` is undeclared — the registration casts through the
|
|
276
|
+
* runtime-accepted event-name string (the event bus dispatches any name).
|
|
277
|
+
* @param ctx - registrant context (fiber disposal unwinds the listener).
|
|
278
|
+
* @param config - the plugin Config (dispatch-tool matching).
|
|
279
|
+
* @param pairing - the apply-scoped pairing store (dispatchByCallId read,
|
|
280
|
+
* dispatchByTaskId written by the background branch).
|
|
281
|
+
*/
|
|
282
|
+
export declare function registerSettleListener(ctx: Context, config: Config, pairing: AgentFlowPairing): void;
|
|
283
|
+
/**
|
|
284
|
+
* The structural read of the dsh-jobs terminal snapshot the pairing consumes
|
|
285
|
+
* (plan `20260811-panel-f4-timeliness` Task 1). The `ctx.jobs.onJobDone`
|
|
286
|
+
* contract was verified against the upstream `@deepseek-ai/dsh-jobs`
|
|
287
|
+
* `types.ts`: `JobDoneListener = (snapshot, owner) => …`, terminal
|
|
288
|
+
* `snapshot.status` ∈ `completed | killed | failed`, `startedAt`/`finishedAt`
|
|
289
|
+
* are epoch ms (`finishedAt` absent while running). Structural (no runtime or
|
|
290
|
+
* type import of the optional dsh-jobs seam — the plugin treats it as an
|
|
291
|
+
* optional service, wired via `ctx.inject(['jobs'])`).
|
|
292
|
+
*/
|
|
293
|
+
export interface TaskDoneSnapshot {
|
|
294
|
+
/** The registry-issued task id (`<kind>-N`, e.g. `subagent-1`). */
|
|
295
|
+
id: string;
|
|
296
|
+
/** Terminal lifecycle status: `completed | killed | failed`. */
|
|
297
|
+
status: string;
|
|
298
|
+
/** Epoch ms when the task was registered. */
|
|
299
|
+
startedAt?: number;
|
|
300
|
+
/** Epoch ms when the task settled. */
|
|
301
|
+
finishedAt?: number;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Record the settle for one background-task terminal (plan
|
|
305
|
+
* `20260811-panel-f4-timeliness` Task 1 — the `ctx.jobs.onJobDone` path):
|
|
306
|
+
* the snapshot's task id must hit the pairing store's `dispatchByTaskId`
|
|
307
|
+
* (populated by the post-execute background branch) — a miss records NOTHING
|
|
308
|
+
* (honest degrade, never fabricated). Outcome mapping: `completed → ok` /
|
|
309
|
+
* `killed → denied` / `failed → error`; `durationMs = finishedAt − startedAt`
|
|
310
|
+
* when both are present. After a SUCCESSFUL settle the consumed
|
|
311
|
+
* `dispatchByTaskId` entry is deleted (map pruning, qc1 F-102 / qc2 F-002 /
|
|
312
|
+
* qc3 F-002 — the map holds only in-flight tasks; a contract-violating
|
|
313
|
+
* non-terminal snapshot records nothing and KEEPS the entry so a later real
|
|
314
|
+
* terminal can still settle). Fully contained — never throws into the task
|
|
315
|
+
* registry's listener notification.
|
|
316
|
+
* @param snapshot - the terminal task snapshot (structural read).
|
|
317
|
+
* @param pairing - the apply-scoped pairing store.
|
|
318
|
+
*/
|
|
319
|
+
export declare function recordTaskSettle(snapshot: TaskDoneSnapshot, pairing: AgentFlowPairing): void;
|
|
320
|
+
export {};
|