@treeseed/dsh-chapters 0.1.16 → 0.1.18
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/cordis.patch.yml +211 -8
- package/docs/backlog.md +79 -0
- package/docs/contract.md +93 -6
- package/docs/development.md +64 -1
- package/docs/plans-carriage.md +1 -1
- package/docs/verify.md +2 -1
- package/lib/index.d.ts +50 -32
- package/lib/index.js +146 -110
- package/lib/index.js.map +1 -1
- package/lib/preset.d.ts +186 -0
- package/lib/preset.js +212 -0
- package/lib/preset.js.map +1 -0
- package/package.json +9 -5
- package/presets/chapters/agent.cordis.yml +0 -272
- package/presets/chapters/preset.yml +0 -3
- package/presets/probe-roots/agent.cordis.yml +0 -11
- package/presets/probe-roots/preset.yml +0 -3
package/lib/preset.d.ts
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `chapters` agent preset row — our implementation of the host's own
|
|
3
|
+
* `@deepseek-ai/dsh-agent-preset` declaration row, mounted from the bundle patch
|
|
4
|
+
* (`cordis.patch.yml`, row id `preset-chapters`), so the preset is a visible Loader entry
|
|
5
|
+
* exactly like `preset-standard` / `preset-ptc` rather than something a plugin does aside.
|
|
6
|
+
*
|
|
7
|
+
* WHY OUR ROW AND NOT THE HOST PACKAGE DIRECTLY
|
|
8
|
+
* --------------------------------------------
|
|
9
|
+
* A preset can be unusable in two ways and both are total: one unresolvable child row makes
|
|
10
|
+
* the WHOLE preset `broken` (`mountPreset` throws on any failed row → `record.broken` →
|
|
11
|
+
* `retain()` refuses with `agent-preset/invalid`), which is the same user-visible failure as
|
|
12
|
+
* a missing preset — every chapters session stops composing while its durable log sits there
|
|
13
|
+
* intact. Measured on the stable release with a composition copy-anchored to the alpha:
|
|
14
|
+
* `@deepseek-ai/dsh-tool-schedule` is not published at 0.2.0-rc.2 at all, and the boot said
|
|
15
|
+
* `preset "chapters" is DECLARED BUT BROKEN — tool-schedule … never started`.
|
|
16
|
+
*
|
|
17
|
+
* So this row does what the host's does, plus drop-what-will-not-load. It also refuses to
|
|
18
|
+
* brick a host predating the mechanism: a `@deepseek-ai/dsh-agent-preset` row is
|
|
19
|
+
* unresolvable before 0.1.7-alpha.1, and ONE unresolvable row aborts a legacy plugin tree
|
|
20
|
+
* (`plugin tree failed to load: … Cannot find package`), while a row naming our own package
|
|
21
|
+
* resolves wherever our package runs. The support floor is 0.2.0, so that is now
|
|
22
|
+
* belt-and-braces rather than the reason — and it is why the row plugin is ours.
|
|
23
|
+
*
|
|
24
|
+
* WHAT IS COPIED FROM THE HOST'S PLUGIN, LINE FOR LINE
|
|
25
|
+
* ---------------------------------------------------
|
|
26
|
+
* - `static inject = ['agentPresets']` — the registry's shape, never a version test.
|
|
27
|
+
* - `static [EntryGroup.key] = true` — "preserve child expressions until their own plugins
|
|
28
|
+
* activate". Without it the Loader interpolates `!!js` against the HOST context, and
|
|
29
|
+
* `disabled: !!js process.platform === 'win32'` stops belonging to the child row that
|
|
30
|
+
* owns it.
|
|
31
|
+
* - `[Service.init]` `yield`s the registry's disposer, so Cordis owns the registration's
|
|
32
|
+
* lifetime. That also disposes of the trap the first draft fell into: calling
|
|
33
|
+
* `ctx.effect(disposer)` from `apply()` fires when the apply FIBER finishes, which
|
|
34
|
+
* un-registered the preset the instant it had been registered (measured on 0.2.0-rc.2:
|
|
35
|
+
* `register()` reported success while the roster came back without `chapters`).
|
|
36
|
+
*
|
|
37
|
+
* @module dsh-chapters/src/preset
|
|
38
|
+
*/
|
|
39
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
40
|
+
import { EntryGroup } from '@deepseek-ai/cordis-plugin-loader';
|
|
41
|
+
import z from '@deepseek-ai/schemastery';
|
|
42
|
+
/** One mounted plugin row of a preset composition (the Loader's own shape). A group row
|
|
43
|
+
* carries its children in `config`; an ordinary row carries a config map. */
|
|
44
|
+
export interface PresetRow {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
config?: Record<string, unknown> | PresetRow[];
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
group?: boolean;
|
|
50
|
+
isolate?: Record<string, boolean>;
|
|
51
|
+
}
|
|
52
|
+
/** The preset definition, in the shape `AgentPresetRegistry.register()` accepts — the host
|
|
53
|
+
* plugin's own Config: id, name?, description?, order, plugins. */
|
|
54
|
+
export interface PresetDefinition {
|
|
55
|
+
id: string;
|
|
56
|
+
name?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
order?: number;
|
|
59
|
+
plugins: PresetRow[];
|
|
60
|
+
}
|
|
61
|
+
/** The preset identity. `config.id` is DURABLE STATE: every continuation child's log
|
|
62
|
+
* records it as `agent-preset/selected`, so renaming it orphans those sessions. */
|
|
63
|
+
export declare const CHAPTERS_PRESET_ID = "chapters";
|
|
64
|
+
/**
|
|
65
|
+
* Drop rows whose module cannot be imported, keeping the group structure intact.
|
|
66
|
+
*
|
|
67
|
+
* The probe is asked with the row's FULL specifier, so a package that still exists but no
|
|
68
|
+
* longer exports the subpath a row names (`…/tools`, `…/list-agents`) is caught too — those
|
|
69
|
+
* renames are what eat presets between host versions.
|
|
70
|
+
*
|
|
71
|
+
* @param rows the composition, groups included.
|
|
72
|
+
* @param resolvable asked with each row's module specifier. MUST NOT throw.
|
|
73
|
+
* @returns the composition to register, and every drop NAMED — a silent drop is how a
|
|
74
|
+
* preset loses a tool nobody notices.
|
|
75
|
+
*/
|
|
76
|
+
export declare function pruneUnresolvableRows(rows: PresetRow[], resolvable: (specifier: string) => boolean): {
|
|
77
|
+
kept: PresetRow[];
|
|
78
|
+
dropped: string[];
|
|
79
|
+
};
|
|
80
|
+
/** What registering a preset can end up as. Every arm has its own log line and its own
|
|
81
|
+
* remedy, because the silent case is the one that cost a human hours. */
|
|
82
|
+
export type RegisterOutcome = {
|
|
83
|
+
state: 'registered';
|
|
84
|
+
} | {
|
|
85
|
+
state: 'pruned';
|
|
86
|
+
dropped: string[];
|
|
87
|
+
} | {
|
|
88
|
+
state: 'already-declared';
|
|
89
|
+
} | {
|
|
90
|
+
state: 'unsupported';
|
|
91
|
+
} | {
|
|
92
|
+
state: 'failed';
|
|
93
|
+
reason: string;
|
|
94
|
+
};
|
|
95
|
+
/** The narrow surface of `ctx.get('agentPresets')` this row uses. */
|
|
96
|
+
export interface PresetRegistryLike {
|
|
97
|
+
register?: (definition: PresetDefinition) => Promise<() => Promise<void>>;
|
|
98
|
+
list?: () => Promise<unknown>;
|
|
99
|
+
/** `compositionInventory()` in `@deepseek-ai/dsh-agent-preset-registry`: every declared
|
|
100
|
+
* preset with its mounted rows and their Loader states. */
|
|
101
|
+
compositionInventory?: () => Promise<unknown>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Register a declared preset, dropping rows this host cannot import.
|
|
105
|
+
*
|
|
106
|
+
* Split out of the plugin class so every arm is unit-testable without a host: the caller
|
|
107
|
+
* hands in the registry surface and a resolver.
|
|
108
|
+
*
|
|
109
|
+
* @returns the outcome AND the disposer the registry hands back — the caller must keep it
|
|
110
|
+
* alive for the row's lifetime, which is what yielding it from `[Service.init]`
|
|
111
|
+
* does; nothing else has the right lifetime (see the module header).
|
|
112
|
+
*/
|
|
113
|
+
export declare function registerPrunedPreset(presets: PresetRegistryLike | undefined, definition: PresetDefinition, resolvable: (specifier: string) => boolean): Promise<{
|
|
114
|
+
outcome: RegisterOutcome;
|
|
115
|
+
disposer?: () => Promise<void>;
|
|
116
|
+
}>;
|
|
117
|
+
/** One mounted row of a live preset composition, as the host's inventory reports it.
|
|
118
|
+
* `fiberState` is the Loader's state for that row; an enabled row that is not `active`
|
|
119
|
+
* cannot serve a session, and the roster's `broken` flag reports that only for the whole
|
|
120
|
+
* mount — which is why the witness asks for the rows as well. */
|
|
121
|
+
export interface InventoryRow {
|
|
122
|
+
entryId?: string;
|
|
123
|
+
moduleName?: string;
|
|
124
|
+
enabled?: boolean;
|
|
125
|
+
fiberState?: string;
|
|
126
|
+
}
|
|
127
|
+
/** One preset's entry in a `compositionInventory()` response. */
|
|
128
|
+
export interface InventoryEntry {
|
|
129
|
+
id?: string;
|
|
130
|
+
broken?: string;
|
|
131
|
+
rows?: InventoryRow[];
|
|
132
|
+
}
|
|
133
|
+
/** Find one preset in an inventory response, tolerating a missing or odd shape. */
|
|
134
|
+
export declare function inventoryEntry(raw: unknown, presetId: string): InventoryEntry | undefined;
|
|
135
|
+
/** Enabled rows of one preset that are not active. A row `pending` a host service can still
|
|
136
|
+
* activate later, so this is reported apart from `broken` and never as a refusal. */
|
|
137
|
+
export declare function unusableRows(entry: InventoryEntry | undefined): string[];
|
|
138
|
+
/**
|
|
139
|
+
* Whether a module specifier can be imported from THIS package's resolution family.
|
|
140
|
+
*
|
|
141
|
+
* Two limits are the host's, not ours to paper over: a RELATIVE specifier resolves without
|
|
142
|
+
* touching the filesystem (so a file-URL row would always be reported resolvable — the
|
|
143
|
+
* composition uses package specifiers only, and the drift test pins that), and a name that
|
|
144
|
+
* resolves is not yet a name that ACTIVATES, which is what the roster line reports as
|
|
145
|
+
* `DECLARED BUT BROKEN`. Never throws: an unresolvable specifier is the answer.
|
|
146
|
+
*/
|
|
147
|
+
export declare function resolvableFromThisPackage(specifier: string): boolean;
|
|
148
|
+
/** The narrow slice of the Cordis context this row needs. */
|
|
149
|
+
interface RowCtx {
|
|
150
|
+
agentPresets: PresetRegistryLike;
|
|
151
|
+
logger?: {
|
|
152
|
+
info?: (m: string) => void;
|
|
153
|
+
warn?: (m: string) => void;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* The declaration row. `config` IS the preset definition, exactly as the host's
|
|
158
|
+
* `AgentPreset` plugin consumes it, so a profile patch can override `preset-chapters`
|
|
159
|
+
* wholesale or `disabled: true` it — the two things a runtime registration done in
|
|
160
|
+
* `apply()` cannot offer, and the reason this is a row.
|
|
161
|
+
*/
|
|
162
|
+
export default class ChaptersPresetRow {
|
|
163
|
+
static inject: readonly ["agentPresets"];
|
|
164
|
+
/** Preserve child `!!js` expressions until their own plugins activate. */
|
|
165
|
+
static [EntryGroup.key]: boolean;
|
|
166
|
+
static Config: z<Schemastery.ObjectS<{
|
|
167
|
+
id: z<string, string>;
|
|
168
|
+
name: z<string, string>;
|
|
169
|
+
description: z<string, string>;
|
|
170
|
+
order: z<number, number>;
|
|
171
|
+
plugins: z<any[], any[]>;
|
|
172
|
+
}>, Schemastery.ObjectT<{
|
|
173
|
+
id: z<string, string>;
|
|
174
|
+
name: z<string, string>;
|
|
175
|
+
description: z<string, string>;
|
|
176
|
+
order: z<number, number>;
|
|
177
|
+
plugins: z<any[], any[]>;
|
|
178
|
+
}>>;
|
|
179
|
+
ctx: RowCtx;
|
|
180
|
+
config: PresetDefinition;
|
|
181
|
+
constructor(ctx: RowCtx, config: PresetDefinition);
|
|
182
|
+
/** Registers, then yields the disposer so Cordis owns the registration's lifetime — the
|
|
183
|
+
* host's own row plugin does exactly this (`yield await this.ctx.agentPresets.register(…)`). */
|
|
184
|
+
[Service.init](): AsyncGenerator<() => Promise<void>, void>;
|
|
185
|
+
}
|
|
186
|
+
export {};
|
package/lib/preset.js
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `chapters` agent preset row — our implementation of the host's own
|
|
3
|
+
* `@deepseek-ai/dsh-agent-preset` declaration row, mounted from the bundle patch
|
|
4
|
+
* (`cordis.patch.yml`, row id `preset-chapters`), so the preset is a visible Loader entry
|
|
5
|
+
* exactly like `preset-standard` / `preset-ptc` rather than something a plugin does aside.
|
|
6
|
+
*
|
|
7
|
+
* WHY OUR ROW AND NOT THE HOST PACKAGE DIRECTLY
|
|
8
|
+
* --------------------------------------------
|
|
9
|
+
* A preset can be unusable in two ways and both are total: one unresolvable child row makes
|
|
10
|
+
* the WHOLE preset `broken` (`mountPreset` throws on any failed row → `record.broken` →
|
|
11
|
+
* `retain()` refuses with `agent-preset/invalid`), which is the same user-visible failure as
|
|
12
|
+
* a missing preset — every chapters session stops composing while its durable log sits there
|
|
13
|
+
* intact. Measured on the stable release with a composition copy-anchored to the alpha:
|
|
14
|
+
* `@deepseek-ai/dsh-tool-schedule` is not published at 0.2.0-rc.2 at all, and the boot said
|
|
15
|
+
* `preset "chapters" is DECLARED BUT BROKEN — tool-schedule … never started`.
|
|
16
|
+
*
|
|
17
|
+
* So this row does what the host's does, plus drop-what-will-not-load. It also refuses to
|
|
18
|
+
* brick a host predating the mechanism: a `@deepseek-ai/dsh-agent-preset` row is
|
|
19
|
+
* unresolvable before 0.1.7-alpha.1, and ONE unresolvable row aborts a legacy plugin tree
|
|
20
|
+
* (`plugin tree failed to load: … Cannot find package`), while a row naming our own package
|
|
21
|
+
* resolves wherever our package runs. The support floor is 0.2.0, so that is now
|
|
22
|
+
* belt-and-braces rather than the reason — and it is why the row plugin is ours.
|
|
23
|
+
*
|
|
24
|
+
* WHAT IS COPIED FROM THE HOST'S PLUGIN, LINE FOR LINE
|
|
25
|
+
* ---------------------------------------------------
|
|
26
|
+
* - `static inject = ['agentPresets']` — the registry's shape, never a version test.
|
|
27
|
+
* - `static [EntryGroup.key] = true` — "preserve child expressions until their own plugins
|
|
28
|
+
* activate". Without it the Loader interpolates `!!js` against the HOST context, and
|
|
29
|
+
* `disabled: !!js process.platform === 'win32'` stops belonging to the child row that
|
|
30
|
+
* owns it.
|
|
31
|
+
* - `[Service.init]` `yield`s the registry's disposer, so Cordis owns the registration's
|
|
32
|
+
* lifetime. That also disposes of the trap the first draft fell into: calling
|
|
33
|
+
* `ctx.effect(disposer)` from `apply()` fires when the apply FIBER finishes, which
|
|
34
|
+
* un-registered the preset the instant it had been registered (measured on 0.2.0-rc.2:
|
|
35
|
+
* `register()` reported success while the roster came back without `chapters`).
|
|
36
|
+
*
|
|
37
|
+
* @module dsh-chapters/src/preset
|
|
38
|
+
*/
|
|
39
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
40
|
+
import { EntryGroup } from '@deepseek-ai/cordis-plugin-loader';
|
|
41
|
+
import z from '@deepseek-ai/schemastery';
|
|
42
|
+
/** The preset identity. `config.id` is DURABLE STATE: every continuation child's log
|
|
43
|
+
* records it as `agent-preset/selected`, so renaming it orphans those sessions. */
|
|
44
|
+
export const CHAPTERS_PRESET_ID = 'chapters';
|
|
45
|
+
/** Whether a row's module must be probed at all. `cordis:` rows are pseudo-modules the
|
|
46
|
+
* Loader always provides; our own package is by definition present — its realm row is the
|
|
47
|
+
* whole point of the preset, and pruning it would quietly delete the feature. */
|
|
48
|
+
function needsProbe(row) {
|
|
49
|
+
return !row.name.startsWith('cordis:') && !row.name.startsWith('@treeseed/dsh-chapters');
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Drop rows whose module cannot be imported, keeping the group structure intact.
|
|
53
|
+
*
|
|
54
|
+
* The probe is asked with the row's FULL specifier, so a package that still exists but no
|
|
55
|
+
* longer exports the subpath a row names (`…/tools`, `…/list-agents`) is caught too — those
|
|
56
|
+
* renames are what eat presets between host versions.
|
|
57
|
+
*
|
|
58
|
+
* @param rows the composition, groups included.
|
|
59
|
+
* @param resolvable asked with each row's module specifier. MUST NOT throw.
|
|
60
|
+
* @returns the composition to register, and every drop NAMED — a silent drop is how a
|
|
61
|
+
* preset loses a tool nobody notices.
|
|
62
|
+
*/
|
|
63
|
+
export function pruneUnresolvableRows(rows, resolvable) {
|
|
64
|
+
const dropped = [];
|
|
65
|
+
const keep = (row) => {
|
|
66
|
+
if (!needsProbe(row))
|
|
67
|
+
return true;
|
|
68
|
+
if (resolvable(row.name))
|
|
69
|
+
return true;
|
|
70
|
+
dropped.push(`${row.id} (${row.name})`);
|
|
71
|
+
return false;
|
|
72
|
+
};
|
|
73
|
+
const visit = (list) => list.flatMap((row) => {
|
|
74
|
+
if (row.group !== true || !Array.isArray(row.config))
|
|
75
|
+
return keep(row) ? [row] : [];
|
|
76
|
+
const children = row.config.filter(keep);
|
|
77
|
+
if (children.length === 0) {
|
|
78
|
+
dropped.push(`${row.id} (group emptied)`);
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return [{ ...row, config: children }];
|
|
82
|
+
});
|
|
83
|
+
return { kept: visit(rows), dropped };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Register a declared preset, dropping rows this host cannot import.
|
|
87
|
+
*
|
|
88
|
+
* Split out of the plugin class so every arm is unit-testable without a host: the caller
|
|
89
|
+
* hands in the registry surface and a resolver.
|
|
90
|
+
*
|
|
91
|
+
* @returns the outcome AND the disposer the registry hands back — the caller must keep it
|
|
92
|
+
* alive for the row's lifetime, which is what yielding it from `[Service.init]`
|
|
93
|
+
* does; nothing else has the right lifetime (see the module header).
|
|
94
|
+
*/
|
|
95
|
+
export async function registerPrunedPreset(presets, definition, resolvable) {
|
|
96
|
+
if (typeof presets?.register !== 'function')
|
|
97
|
+
return { outcome: { state: 'unsupported' } };
|
|
98
|
+
const { kept, dropped } = pruneUnresolvableRows(definition.plugins, resolvable);
|
|
99
|
+
const pruned = { ...definition, plugins: kept };
|
|
100
|
+
let disposer;
|
|
101
|
+
try {
|
|
102
|
+
disposer = await presets.register(pruned);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const reason = String(error?.message ?? error);
|
|
106
|
+
// A duplicate is not our failure: someone declared `chapters` themselves — a profile
|
|
107
|
+
// patch override is a legitimate choice. Their row wins; ours must not throw, because a
|
|
108
|
+
// row that fails to activate takes the preset with it, and the roster line with it.
|
|
109
|
+
if (/duplicate agent preset/i.test(reason))
|
|
110
|
+
return { outcome: { state: 'already-declared' } };
|
|
111
|
+
return { outcome: { state: 'failed', reason } };
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
outcome: dropped.length > 0 ? { state: 'pruned', dropped } : { state: 'registered' },
|
|
115
|
+
disposer,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/** Find one preset in an inventory response, tolerating a missing or odd shape. */
|
|
119
|
+
export function inventoryEntry(raw, presetId) {
|
|
120
|
+
return Array.isArray(raw) ? raw.find((entry) => entry?.id === presetId) : undefined;
|
|
121
|
+
}
|
|
122
|
+
/** Enabled rows of one preset that are not active. A row `pending` a host service can still
|
|
123
|
+
* activate later, so this is reported apart from `broken` and never as a refusal. */
|
|
124
|
+
export function unusableRows(entry) {
|
|
125
|
+
if (!Array.isArray(entry?.rows))
|
|
126
|
+
return [];
|
|
127
|
+
return entry.rows
|
|
128
|
+
.filter((row) => row.enabled !== false && typeof row.fiberState === 'string' && row.fiberState !== 'active')
|
|
129
|
+
.map((row) => `${row.entryId ?? '?'} (${row.moduleName ?? '?'}) ${row.fiberState}`);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Whether a module specifier can be imported from THIS package's resolution family.
|
|
133
|
+
*
|
|
134
|
+
* Two limits are the host's, not ours to paper over: a RELATIVE specifier resolves without
|
|
135
|
+
* touching the filesystem (so a file-URL row would always be reported resolvable — the
|
|
136
|
+
* composition uses package specifiers only, and the drift test pins that), and a name that
|
|
137
|
+
* resolves is not yet a name that ACTIVATES, which is what the roster line reports as
|
|
138
|
+
* `DECLARED BUT BROKEN`. Never throws: an unresolvable specifier is the answer.
|
|
139
|
+
*/
|
|
140
|
+
export function resolvableFromThisPackage(specifier) {
|
|
141
|
+
if (specifier.startsWith('.') || specifier.startsWith('/') || specifier.startsWith('file:'))
|
|
142
|
+
return true;
|
|
143
|
+
try {
|
|
144
|
+
import.meta.resolve(specifier);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The declaration row. `config` IS the preset definition, exactly as the host's
|
|
153
|
+
* `AgentPreset` plugin consumes it, so a profile patch can override `preset-chapters`
|
|
154
|
+
* wholesale or `disabled: true` it — the two things a runtime registration done in
|
|
155
|
+
* `apply()` cannot offer, and the reason this is a row.
|
|
156
|
+
*/
|
|
157
|
+
export default class ChaptersPresetRow {
|
|
158
|
+
static inject = ['agentPresets'];
|
|
159
|
+
/** Preserve child `!!js` expressions until their own plugins activate. */
|
|
160
|
+
static [EntryGroup.key] = true;
|
|
161
|
+
static Config = z.object({
|
|
162
|
+
id: z.string().required(),
|
|
163
|
+
name: z.string(),
|
|
164
|
+
description: z.string(),
|
|
165
|
+
order: z.number(),
|
|
166
|
+
plugins: z.array(z.any()).required(),
|
|
167
|
+
});
|
|
168
|
+
ctx;
|
|
169
|
+
config;
|
|
170
|
+
constructor(ctx, config) {
|
|
171
|
+
this.ctx = ctx;
|
|
172
|
+
this.config = config;
|
|
173
|
+
}
|
|
174
|
+
/** Registers, then yields the disposer so Cordis owns the registration's lifetime — the
|
|
175
|
+
* host's own row plugin does exactly this (`yield await this.ctx.agentPresets.register(…)`). */
|
|
176
|
+
async *[Service.init]() {
|
|
177
|
+
const { outcome, disposer } = await registerPrunedPreset(this.ctx.agentPresets, this.config, resolvableFromThisPackage);
|
|
178
|
+
const log = (message, warn) => {
|
|
179
|
+
// `ctx.logger` alone is invisible to a headless `dsh web` (r19), so the loud arms go
|
|
180
|
+
// to stderr as well — a health line nobody reads is how the silent case survived.
|
|
181
|
+
if (warn) {
|
|
182
|
+
this.ctx.logger?.warn?.(message);
|
|
183
|
+
console.error(message);
|
|
184
|
+
}
|
|
185
|
+
else
|
|
186
|
+
this.ctx.logger?.info?.(message);
|
|
187
|
+
};
|
|
188
|
+
if (outcome.state === 'unsupported') {
|
|
189
|
+
// Pre-0.1.7 hosts have no register(). They are below the support floor, but saying so
|
|
190
|
+
// beats aborting their plugin tree over a row they cannot read.
|
|
191
|
+
log(`dsh-chapters: this host cannot register preset declaration rows (before 0.2.0) — the "${CHAPTERS_PRESET_ID}" preset cannot exist here; the chapters tools still work`, true);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (outcome.state === 'already-declared') {
|
|
195
|
+
log(`dsh-chapters: preset "${this.config.id}" is also declared by another row — that one is kept, this bundle's copy stands down`, false);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (outcome.state === 'failed') {
|
|
199
|
+
log(`dsh-chapters: UNHEALTHY — registering the "${this.config.id}" preset was refused: ${outcome.reason} — every session choosing it will fail to compose`, true);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (outcome.state === 'pruned') {
|
|
203
|
+
log(`dsh-chapters: preset "${this.config.id}" registered — dropped ${outcome.dropped.length} row(s) this host cannot import: ${outcome.dropped.join(', ')} (one unresolvable row would make the whole preset broken, so they are gone rather than mounted)`, false);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
log(`dsh-chapters: preset "${this.config.id}" registered as a declaration row`, false);
|
|
207
|
+
}
|
|
208
|
+
if (disposer !== undefined)
|
|
209
|
+
yield disposer;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=preset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset.js","sourceRoot":"","sources":["../src/preset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAC9D,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAuBxC;oFACoF;AACpF,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAA;AAE5C;;kFAEkF;AAClF,SAAS,UAAU,CAAC,GAAc;IAChC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAA;AAC1F,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAiB,EACjB,UAA0C;IAE1C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,MAAM,IAAI,GAAG,CAAC,GAAc,EAAW,EAAE;QACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QACjC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QACrC,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAA;QACvC,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IACD,MAAM,KAAK,GAAG,CAAC,IAAiB,EAAe,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAe,EAAE;QAClF,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACnF,MAAM,QAAQ,GAAI,GAAG,CAAC,MAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACzD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,kBAAkB,CAAC,CAAA;YACzC,OAAO,EAAE,CAAA;QACX,CAAC;QACD,OAAO,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IACF,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAA;AACvC,CAAC;AAoBD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAuC,EACvC,UAA4B,EAC5B,UAA0C;IAE1C,IAAI,OAAO,OAAO,EAAE,QAAQ,KAAK,UAAU;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CAAA;IACzF,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,qBAAqB,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IAC/E,MAAM,MAAM,GAAG,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC/C,IAAI,QAA6B,CAAA;IACjC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,MAAM,CAAE,KAAe,EAAE,OAAO,IAAI,KAAK,CAAC,CAAA;QACzD,qFAAqF;QACrF,wFAAwF;QACxF,oFAAoF;QACpF,IAAI,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,CAAA;QAC7F,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAA;IACjD,CAAC;IACD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE;QACpF,QAAQ;KACT,CAAA;AACH,CAAC;AAoBD,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,QAAgB;IAC3D,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAwB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC3G,CAAC;AAED;sFACsF;AACtF,MAAM,UAAU,YAAY,CAAC,KAAiC;IAC5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IAC1C,OAAQ,KAAK,CAAC,IAAuB;SAClC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC;SAC3G,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,KAAK,GAAG,CAAC,UAAU,IAAI,GAAG,KAAK,GAAG,CAAC,UAAU,EAAE,CAAC,CAAA;AACvF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,SAAiB;IACzD,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAA;IACxG,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAQD;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC,MAAM,CAAC,MAAM,GAAG,CAAC,cAAc,CAAU,CAAA;IAEzC,0EAA0E;IAC1E,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IAE9B,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;QACvB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACzB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;QACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;KACrC,CAAC,CAAA;IAEF,GAAG,CAAQ;IACX,MAAM,CAAkB;IAExB,YAAY,GAAW,EAAE,MAAwB;QAC/C,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED;qGACiG;IACjG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;QACnB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAA;QACvH,MAAM,GAAG,GAAG,CAAC,OAAe,EAAE,IAAa,EAAQ,EAAE;YACnD,qFAAqF;YACrF,kFAAkF;YAClF,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,CAAA;gBAChC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACxB,CAAC;;gBAAM,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,CAAA;QACzC,CAAC,CAAA;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;YACpC,sFAAsF;YACtF,gEAAgE;YAChE,GAAG,CAAC,yFAAyF,kBAAkB,2DAA2D,EAAE,IAAI,CAAC,CAAA;YACjL,OAAM;QACR,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,kBAAkB,EAAE,CAAC;YACzC,GAAG,CAAC,yBAAyB,IAAI,CAAC,MAAM,CAAC,EAAE,sFAAsF,EAAE,KAAK,CAAC,CAAA;YACzI,OAAM;QACR,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,GAAG,CAAC,8CAA8C,IAAI,CAAC,MAAM,CAAC,EAAE,yBAAyB,OAAO,CAAC,MAAM,mDAAmD,EAAE,IAAI,CAAC,CAAA;YACjK,OAAM;QACR,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,GAAG,CAAC,yBAAyB,IAAI,CAAC,MAAM,CAAC,EAAE,0BAA0B,OAAO,CAAC,OAAO,CAAC,MAAM,oCAAoC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,kGAAkG,EAAE,KAAK,CAAC,CAAA;QACrQ,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,yBAAyB,IAAI,CAAC,MAAM,CAAC,EAAE,mCAAmC,EAAE,KAAK,CAAC,CAAA;QACxF,CAAC;QACD,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,QAAQ,CAAA;IAC5C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treeseed/dsh-chapters",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "dsh plugin: verbatim chapter archive + zero-token index for small-context models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
14
14
|
"./package.json": "./package.json",
|
|
15
15
|
"./engine": "./lib/engine.js",
|
|
16
|
-
"./
|
|
16
|
+
"./preset": "./lib/preset.js",
|
|
17
17
|
"./tools": "./lib/tools.js",
|
|
18
18
|
"./store": "./lib/store.js",
|
|
19
19
|
"./registry": "./lib/registry.js",
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
23
|
"lib",
|
|
24
|
-
"presets",
|
|
25
24
|
"cordis.patch.yml",
|
|
26
25
|
"docs",
|
|
27
26
|
"README.md"
|
|
@@ -66,7 +65,8 @@
|
|
|
66
65
|
"@deepseek-ai/dsh-home-paths": "*",
|
|
67
66
|
"@deepseek-ai/dsh-storage-domain": "*",
|
|
68
67
|
"@deepseek-ai/dsh-tools": "*",
|
|
69
|
-
"@deepseek-ai/schemastery": "*"
|
|
68
|
+
"@deepseek-ai/schemastery": "*",
|
|
69
|
+
"@deepseek-ai/cordis-plugin-loader": "*"
|
|
70
70
|
},
|
|
71
71
|
"peerDependenciesMeta": {
|
|
72
72
|
"@deepseek-ai/cordis": {
|
|
@@ -89,6 +89,9 @@
|
|
|
89
89
|
},
|
|
90
90
|
"@deepseek-ai/dsh-home-paths": {
|
|
91
91
|
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"@deepseek-ai/cordis-plugin-loader": {
|
|
94
|
+
"optional": true
|
|
92
95
|
}
|
|
93
96
|
},
|
|
94
97
|
"devDependencies": {
|
|
@@ -113,7 +116,8 @@
|
|
|
113
116
|
"react": "^18.2.0",
|
|
114
117
|
"react-dom": "^18.2.0",
|
|
115
118
|
"tsdown": "^0.22.2",
|
|
116
|
-
"typescript": "^5.9.3"
|
|
119
|
+
"typescript": "^5.9.3",
|
|
120
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.4"
|
|
117
121
|
},
|
|
118
122
|
"dependencies": {
|
|
119
123
|
"isomorphic-git": "^1.42.2",
|