dsh-agent-plugins-market 0.6.2 → 0.7.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.md +117 -111
- package/README.zh.md +112 -98
- package/client/client.js +28533 -1511
- package/client/client.js.map +1 -1
- package/lib/application/catalog-context.js +188 -0
- package/lib/application/catalog.js +229 -1109
- package/lib/application/details.js +19 -8
- package/lib/application/install-store.js +95 -0
- package/lib/application/lsp-service.js +97 -0
- package/lib/application/mcp-service.js +263 -0
- package/lib/application/panel-resources.js +43 -14
- package/lib/application/ports.js +21 -0
- package/lib/application/project-agent-roles.js +8 -2
- package/lib/application/snapshot-cache.js +160 -0
- package/lib/application/source-store.js +521 -0
- package/lib/catalog/archive.js +35 -30
- package/lib/catalog/component-files.js +14 -6
- package/lib/catalog/fs-probes.js +43 -0
- package/lib/catalog/manifests.js +53 -92
- package/lib/catalog/native-project.js +2 -2
- package/lib/catalog/paths.js +74 -55
- package/lib/catalog/plugin-variables.js +38 -0
- package/lib/catalog/project-config.js +2 -1
- package/lib/catalog/project-hooks.js +23 -2
- package/lib/catalog/scan-resolvers.js +29 -45
- package/lib/catalog/skills-parse.js +61 -10
- package/lib/catalog/source-catalog.js +10 -4
- package/lib/catalog/suite-components.js +7 -7
- package/lib/catalog/suite-scanner.js +3 -1
- package/lib/catalog/surfaces.js +5 -26
- package/lib/catalog/validate.js +7 -11
- package/lib/contracts/market.js +2 -0
- package/lib/contracts/settings.js +63 -0
- package/lib/index.js +115 -217
- package/lib/model/layouts.js +10 -1
- package/lib/model/types.js +26 -3
- package/lib/routes.js +57 -15
- package/lib/runtime/agent-role-names.js +70 -0
- package/lib/runtime/agent-role-router.js +142 -106
- package/lib/runtime/commands-mounts.js +55 -11
- package/lib/runtime/deadline.js +54 -0
- package/lib/runtime/dynamic-context.js +140 -0
- package/lib/runtime/feedback-tool.js +101 -46
- package/lib/runtime/hooks-mounts.js +9 -11
- package/lib/runtime/host-locale.js +49 -24
- package/lib/runtime/lsp-direct-config.js +19 -19
- package/lib/runtime/lsp-mounts.js +182 -70
- package/lib/runtime/lsp-server-state.js +4 -4
- package/lib/runtime/lsp-status.js +1 -1
- package/lib/runtime/mcp-auth-record.js +42 -0
- package/lib/runtime/mcp-backend.js +14 -14
- package/lib/runtime/mcp-client/config.js +8 -1
- package/lib/runtime/mcp-client/connection.js +38 -43
- package/lib/runtime/mcp-client/host-contract.js +10 -0
- package/lib/runtime/mcp-client/host-seams.js +8 -88
- package/lib/runtime/mcp-client/oauth.js +5 -7
- package/lib/runtime/mcp-client/plugin-identity.js +28 -0
- package/lib/runtime/mcp-client/projection.js +202 -0
- package/lib/runtime/mcp-client/tools.js +4 -189
- package/lib/runtime/mcp-config.js +36 -14
- package/lib/runtime/mcp-direct-config.js +33 -16
- package/lib/runtime/mcp-mounts.js +35 -75
- package/lib/runtime/mcp-overrides.js +5 -5
- package/lib/runtime/mcp-redaction.js +3 -2
- package/lib/runtime/mcp-status.js +7 -8
- package/lib/runtime/mount-lifecycle.js +73 -0
- package/lib/runtime/profile-seam.js +321 -0
- package/lib/runtime/project-runtime.js +34 -17
- package/lib/runtime/reconcile-scheduler.js +97 -0
- package/lib/runtime/reconciler.js +6 -1
- package/lib/runtime/regions.js +0 -19
- package/lib/runtime/server-config.js +6 -4
- package/lib/runtime/settings-namespace.js +144 -0
- package/lib/runtime/skills-provider.js +38 -14
- package/lib/runtime/source-auto-update.js +66 -0
- package/lib/{model/state.js → runtime/state-store.js} +9 -11
- package/lib/runtime/storage-migration.js +35 -18
- package/lib/runtime/subagent-catalog.js +5 -4
- package/lib/runtime/timer-seat.js +80 -0
- package/lib/runtime/tool-registry-observer.js +20 -20
- package/lib/runtime/user-commands.js +7 -3
- package/lib/runtime/user-panels.js +125 -46
- package/lib/runtime/user-store.js +124 -69
- package/lib/types/application/catalog-context.d.ts +124 -0
- package/lib/types/application/catalog.d.ts +108 -304
- package/lib/types/application/install-store.d.ts +21 -0
- package/lib/types/application/lsp-service.d.ts +36 -0
- package/lib/types/application/mcp-service.d.ts +77 -0
- package/lib/types/application/panel-resources.d.ts +8 -0
- package/lib/types/application/ports.d.ts +72 -0
- package/lib/types/application/queries.d.ts +15 -26
- package/lib/types/application/snapshot-cache.d.ts +51 -0
- package/lib/types/application/source-store.d.ts +100 -0
- package/lib/types/catalog/archive.d.ts +3 -11
- package/lib/types/catalog/component-files.d.ts +4 -0
- package/lib/types/catalog/fs-probes.d.ts +10 -0
- package/lib/types/catalog/manifests.d.ts +17 -16
- package/lib/types/catalog/native-project.d.ts +2 -2
- package/lib/types/catalog/paths.d.ts +53 -15
- package/lib/types/catalog/plugin-variables.d.ts +16 -0
- package/lib/types/catalog/scan-pipeline.d.ts +3 -3
- package/lib/types/catalog/scan-resolvers.d.ts +3 -9
- package/lib/types/catalog/skills-parse.d.ts +13 -7
- package/lib/types/catalog/source-catalog.d.ts +10 -5
- package/lib/types/catalog/suite-scanner.d.ts +8 -6
- package/lib/types/catalog/validate.d.ts +0 -2
- package/lib/types/contracts/lsp-status.d.ts +35 -0
- package/lib/types/contracts/market.d.ts +13 -2
- package/lib/types/contracts/mcp-status.d.ts +4 -0
- package/lib/types/contracts/settings.d.ts +59 -0
- package/lib/types/model/layouts.d.ts +10 -0
- package/lib/types/model/types.d.ts +29 -5
- package/lib/types/runtime/agent-role-names.d.ts +6 -0
- package/lib/types/runtime/agent-role-router.d.ts +59 -52
- package/lib/types/runtime/commands-mounts.d.ts +15 -7
- package/lib/types/runtime/deadline.d.ts +17 -0
- package/lib/types/runtime/dynamic-context.d.ts +81 -0
- package/lib/types/runtime/feedback-tool.d.ts +33 -11
- package/lib/types/runtime/hooks-mounts.d.ts +1 -1
- package/lib/types/runtime/host-locale.d.ts +20 -2
- package/lib/types/runtime/lsp-direct-config.d.ts +3 -3
- package/lib/types/runtime/lsp-mounts.d.ts +69 -19
- package/lib/types/runtime/lsp-status.d.ts +2 -1
- package/lib/types/runtime/mcp-auth-record.d.ts +29 -0
- package/lib/types/runtime/mcp-backend.d.ts +10 -14
- package/lib/types/runtime/mcp-client/config.d.ts +8 -2
- package/lib/types/runtime/mcp-client/host-contract.d.ts +78 -0
- package/lib/types/runtime/mcp-client/host-seams.d.ts +20 -64
- package/lib/types/runtime/mcp-client/oauth.d.ts +1 -1
- package/lib/types/runtime/mcp-client/plugin-identity.d.ts +16 -0
- package/lib/types/runtime/mcp-client/projection.d.ts +45 -0
- package/lib/types/runtime/mcp-client/tools.d.ts +5 -72
- package/lib/types/runtime/mcp-config.d.ts +25 -4
- package/lib/types/runtime/mcp-direct-config.d.ts +18 -4
- package/lib/types/runtime/mcp-mounts.d.ts +10 -15
- package/lib/types/runtime/mcp-overrides.d.ts +1 -1
- package/lib/types/runtime/mcp-status.d.ts +1 -1
- package/lib/types/runtime/mount-lifecycle.d.ts +53 -0
- package/lib/types/runtime/profile-seam.d.ts +64 -0
- package/lib/types/runtime/project-runtime.d.ts +10 -3
- package/lib/types/runtime/reconcile-scheduler.d.ts +45 -0
- package/lib/types/runtime/reconciler.d.ts +2 -0
- package/lib/types/runtime/regions.d.ts +1 -4
- package/lib/types/runtime/settings-namespace.d.ts +76 -0
- package/lib/types/runtime/skills-provider.d.ts +11 -2
- package/lib/types/runtime/source-auto-update.d.ts +32 -0
- package/lib/types/{model/state.d.ts → runtime/state-store.d.ts} +2 -2
- package/lib/types/runtime/storage-migration.d.ts +5 -3
- package/lib/types/runtime/subagent-catalog.d.ts +2 -0
- package/lib/types/runtime/timer-seat.d.ts +51 -0
- package/lib/types/runtime/tool-registry-observer.d.ts +12 -6
- package/lib/types/runtime/user-panels.d.ts +69 -19
- package/lib/types/runtime/user-store.d.ts +67 -20
- package/package.json +68 -24
- package/schemas/README.md +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Resolve read-only project roles from the calling session, never from tool-supplied paths. */
|
|
2
2
|
import { defaultMarkdownResources, resourceText } from '../catalog/component-files.js';
|
|
3
|
+
import { pluginRootOf } from '../catalog/plugin-variables.js';
|
|
4
|
+
import { suiteDataDir } from '../catalog/paths.js';
|
|
3
5
|
import { parseAgentRole } from '../runtime/agent-role-router.js';
|
|
4
6
|
export async function projectAgentRoles(catalog, parent) {
|
|
5
7
|
const cwd = parent?.session?.header?.cwd;
|
|
@@ -8,8 +10,10 @@ export async function projectAgentRoles(catalog, parent) {
|
|
|
8
10
|
const snapshot = await catalog.readProjectCatalog(cwd);
|
|
9
11
|
const entries = [];
|
|
10
12
|
for (const suite of snapshot.enabledSuites) {
|
|
11
|
-
if (suite.activeSurfaces
|
|
13
|
+
if (suite.activeSurfaces.agents === false)
|
|
12
14
|
continue;
|
|
15
|
+
const suiteRoot = pluginRootOf(suite);
|
|
16
|
+
const suiteData = suiteRoot === undefined ? undefined : suiteDataDir(catalog.dataRoot, suite.sourceId, suite.id);
|
|
13
17
|
for (const resource of suite.resources?.agents ?? (await defaultMarkdownResources(suite.root, 'agents'))) {
|
|
14
18
|
const path = resource.file;
|
|
15
19
|
const rawText = await resourceText(resource).catch(error => {
|
|
@@ -27,7 +31,9 @@ export async function projectAgentRoles(catalog, parent) {
|
|
|
27
31
|
rawText,
|
|
28
32
|
title: policy.title ?? resource.name.replace(/\.agent$/, ''),
|
|
29
33
|
description: policy.description ?? `${suite.manifest.name}: ${resource.name}`,
|
|
30
|
-
disabled: policy.disabled
|
|
34
|
+
disabled: policy.disabled,
|
|
35
|
+
...(suiteRoot === undefined ? {} : { suiteRoot }),
|
|
36
|
+
...(suiteData === undefined ? {} : { suiteData })
|
|
31
37
|
});
|
|
32
38
|
}
|
|
33
39
|
catch {
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discovery caching: one scan cache shared by every dimension, plus a
|
|
3
|
+
* freshness-bounded snapshot per dimension.
|
|
4
|
+
*
|
|
5
|
+
* Install / enable / surface toggles re-derive a snapshot from cached
|
|
6
|
+
* discovery (a cheap mapping) instead of re-walking every checkout — a full
|
|
7
|
+
* rescan of a 2,500-suite catalog costs ~1s and UI mutations happen in bursts.
|
|
8
|
+
* Content-changing mutations (add / update / remove / adopt / refresh /
|
|
9
|
+
* acquire) clear every cached discovery generation; the TTL bounds staleness
|
|
10
|
+
* for in-place working-tree edits of local sources.
|
|
11
|
+
*/
|
|
12
|
+
import { join, resolve } from 'node:path';
|
|
13
|
+
import { resolveProjectRoot, STATE_FILE_NAME } from '../catalog/paths.js';
|
|
14
|
+
import { discoverSourceListWithNotes } from '../catalog/source-catalog.js';
|
|
15
|
+
import { loadState } from '../runtime/state-store.js';
|
|
16
|
+
export const SCAN_CACHE_TTL_MS = 30_000;
|
|
17
|
+
const SCAN_CACHE_MAX_ENTRIES = 8;
|
|
18
|
+
export class SnapshotCache {
|
|
19
|
+
host;
|
|
20
|
+
ttls;
|
|
21
|
+
scanCache = new Map();
|
|
22
|
+
scanPromises = new Map();
|
|
23
|
+
userSnapshot;
|
|
24
|
+
userSnapshotExpiresAt = 0;
|
|
25
|
+
userSnapshotPromise;
|
|
26
|
+
/** Project-dimension snapshots keyed by project root, with TTL freshness. */
|
|
27
|
+
projectSnapshots = new Map();
|
|
28
|
+
projectSnapshotPromises = new Map();
|
|
29
|
+
constructor(host, ttls) {
|
|
30
|
+
this.host = host;
|
|
31
|
+
this.ttls = ttls;
|
|
32
|
+
}
|
|
33
|
+
/** Read one coherent user-dimension snapshot, reusing in-flight discovery. */
|
|
34
|
+
async readUserCatalog() {
|
|
35
|
+
// TTL 0 disables snapshot caching: every read observes fresh discovery,
|
|
36
|
+
// mirroring the project dimension's caching-disabled semantics.
|
|
37
|
+
if (this.ttls.user <= 0)
|
|
38
|
+
return this.build(this.host.state, 'user', this.host.userRoot);
|
|
39
|
+
if (this.userSnapshot !== undefined && Date.now() < this.userSnapshotExpiresAt)
|
|
40
|
+
return this.userSnapshot;
|
|
41
|
+
if (this.userSnapshotPromise !== undefined)
|
|
42
|
+
return this.userSnapshotPromise;
|
|
43
|
+
const revision = this.host.revision;
|
|
44
|
+
const generation = this.host.scanGeneration;
|
|
45
|
+
const promise = this.build(this.host.state, 'user', this.host.userRoot)
|
|
46
|
+
.then(snapshot => {
|
|
47
|
+
if (revision === this.host.revision && generation === this.host.scanGeneration) {
|
|
48
|
+
this.userSnapshot = snapshot;
|
|
49
|
+
this.userSnapshotExpiresAt = Date.now() + this.ttls.user;
|
|
50
|
+
}
|
|
51
|
+
return snapshot;
|
|
52
|
+
})
|
|
53
|
+
.finally(() => {
|
|
54
|
+
if (this.userSnapshotPromise === promise)
|
|
55
|
+
this.userSnapshotPromise = undefined;
|
|
56
|
+
});
|
|
57
|
+
this.userSnapshotPromise = promise;
|
|
58
|
+
return promise;
|
|
59
|
+
}
|
|
60
|
+
/** Read one coherent project-dimension snapshot for a workspace cwd. */
|
|
61
|
+
async readProjectCatalog(cwd) {
|
|
62
|
+
const projectRoot = await resolveProjectRoot(cwd);
|
|
63
|
+
// A cwd with no `.git` ancestor resolves to itself as its own project root,
|
|
64
|
+
// so a session started in the harness home lands on the user dimension root.
|
|
65
|
+
// That directory is the user's catalog, not a project's: reading it would
|
|
66
|
+
// present every user-level suite as a project suite of that one session.
|
|
67
|
+
if (resolve(projectRoot) === resolve(this.host.userRoot)) {
|
|
68
|
+
return { revision: this.host.revision, sources: [], suites: [], enabledSuites: [] };
|
|
69
|
+
}
|
|
70
|
+
if (this.ttls.project <= 0)
|
|
71
|
+
return this.buildProjectSnapshot(projectRoot);
|
|
72
|
+
const cached = this.projectSnapshots.get(projectRoot);
|
|
73
|
+
if (cached !== undefined && cached.expiresAt > Date.now())
|
|
74
|
+
return cached.snapshot;
|
|
75
|
+
const inFlight = this.projectSnapshotPromises.get(projectRoot);
|
|
76
|
+
if (inFlight !== undefined)
|
|
77
|
+
return inFlight;
|
|
78
|
+
const revision = this.host.revision;
|
|
79
|
+
const generation = this.host.scanGeneration;
|
|
80
|
+
const promise = this.buildProjectSnapshot(projectRoot)
|
|
81
|
+
.then(snapshot => {
|
|
82
|
+
if (revision === this.host.revision && generation === this.host.scanGeneration) {
|
|
83
|
+
this.projectSnapshots.set(projectRoot, { snapshot, expiresAt: Date.now() + this.ttls.project });
|
|
84
|
+
}
|
|
85
|
+
return snapshot;
|
|
86
|
+
})
|
|
87
|
+
.finally(() => {
|
|
88
|
+
if (this.projectSnapshotPromises.get(projectRoot) === promise)
|
|
89
|
+
this.projectSnapshotPromises.delete(projectRoot);
|
|
90
|
+
});
|
|
91
|
+
this.projectSnapshotPromises.set(projectRoot, promise);
|
|
92
|
+
return promise;
|
|
93
|
+
}
|
|
94
|
+
/** One snapshot for a dimension root, reusing cached discovery when it is fresh. */
|
|
95
|
+
async build(state, dimension, dimensionRoot, skipScanCache = false) {
|
|
96
|
+
const fingerprint = JSON.stringify([dimension, dimensionRoot, state.sources, this.host.scanProjectLayouts]);
|
|
97
|
+
const cached = this.scanCache.get(fingerprint);
|
|
98
|
+
// The user snapshot's TTL also bounds scan reuse: a snapshot rebuild that
|
|
99
|
+
// replays a 30s scan cache would silently outlive its own staleness bound.
|
|
100
|
+
const scanCacheTtl = dimension === 'user' ? Math.min(this.ttls.user, SCAN_CACHE_TTL_MS) : SCAN_CACHE_TTL_MS;
|
|
101
|
+
const cacheFresh = !skipScanCache && cached !== undefined && Date.now() - cached.at < scanCacheTtl;
|
|
102
|
+
let discovered;
|
|
103
|
+
let scanNotes;
|
|
104
|
+
if (cacheFresh && cached !== undefined) {
|
|
105
|
+
discovered = cached.discovered;
|
|
106
|
+
scanNotes = cached.scanNotes;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
const generation = this.host.scanGeneration;
|
|
110
|
+
let pending = this.scanPromises.get(fingerprint);
|
|
111
|
+
if (pending === undefined) {
|
|
112
|
+
pending = discoverSourceListWithNotes(state.sources, dimension, dimensionRoot, this.host.scanProjectLayouts);
|
|
113
|
+
this.scanPromises.set(fingerprint, pending);
|
|
114
|
+
}
|
|
115
|
+
let result;
|
|
116
|
+
try {
|
|
117
|
+
result = await pending;
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
if (this.scanPromises.get(fingerprint) === pending)
|
|
121
|
+
this.scanPromises.delete(fingerprint);
|
|
122
|
+
}
|
|
123
|
+
discovered = result.suites;
|
|
124
|
+
scanNotes = result.scanNotes;
|
|
125
|
+
// A scan started before a content mutation must not repopulate its cache.
|
|
126
|
+
if (generation === this.host.scanGeneration) {
|
|
127
|
+
if (this.scanCache.size >= SCAN_CACHE_MAX_ENTRIES)
|
|
128
|
+
this.scanCache.clear();
|
|
129
|
+
this.scanCache.set(fingerprint, { at: Date.now(), discovered, scanNotes });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const suites = this.host.project(discovered, state, dimension);
|
|
133
|
+
return {
|
|
134
|
+
revision: this.host.revision,
|
|
135
|
+
sources: [...state.sources],
|
|
136
|
+
suites,
|
|
137
|
+
enabledSuites: suites.filter(suite => suite.enabled),
|
|
138
|
+
...(Object.keys(scanNotes).length > 0 ? { scanNotes } : {})
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/** Drop every cached dimension snapshot and its in-flight dedupe slot. */
|
|
142
|
+
invalidateSnapshots() {
|
|
143
|
+
this.userSnapshot = undefined;
|
|
144
|
+
this.userSnapshotExpiresAt = 0;
|
|
145
|
+
this.userSnapshotPromise = undefined;
|
|
146
|
+
this.projectSnapshots.clear();
|
|
147
|
+
this.projectSnapshotPromises.clear();
|
|
148
|
+
}
|
|
149
|
+
/** Drop cached discovery and its in-flight dedupe slots. */
|
|
150
|
+
invalidateScans() {
|
|
151
|
+
this.scanCache.clear();
|
|
152
|
+
this.scanPromises.clear();
|
|
153
|
+
}
|
|
154
|
+
async buildProjectSnapshot(projectRoot) {
|
|
155
|
+
const state = await loadState(join(projectRoot, STATE_FILE_NAME));
|
|
156
|
+
// TTL 0 means caching is disabled for this dimension: bypass the scan
|
|
157
|
+
// cache so every read observes the working tree as it stands.
|
|
158
|
+
return this.build(state, 'project', projectRoot, this.ttls.project <= 0);
|
|
159
|
+
}
|
|
160
|
+
}
|