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.
Files changed (155) hide show
  1. package/README.md +117 -111
  2. package/README.zh.md +112 -98
  3. package/client/client.js +28533 -1511
  4. package/client/client.js.map +1 -1
  5. package/lib/application/catalog-context.js +188 -0
  6. package/lib/application/catalog.js +229 -1109
  7. package/lib/application/details.js +19 -8
  8. package/lib/application/install-store.js +95 -0
  9. package/lib/application/lsp-service.js +97 -0
  10. package/lib/application/mcp-service.js +263 -0
  11. package/lib/application/panel-resources.js +43 -14
  12. package/lib/application/ports.js +21 -0
  13. package/lib/application/project-agent-roles.js +8 -2
  14. package/lib/application/snapshot-cache.js +160 -0
  15. package/lib/application/source-store.js +521 -0
  16. package/lib/catalog/archive.js +35 -30
  17. package/lib/catalog/component-files.js +14 -6
  18. package/lib/catalog/fs-probes.js +43 -0
  19. package/lib/catalog/manifests.js +53 -92
  20. package/lib/catalog/native-project.js +2 -2
  21. package/lib/catalog/paths.js +74 -55
  22. package/lib/catalog/plugin-variables.js +38 -0
  23. package/lib/catalog/project-config.js +2 -1
  24. package/lib/catalog/project-hooks.js +23 -2
  25. package/lib/catalog/scan-resolvers.js +29 -45
  26. package/lib/catalog/skills-parse.js +61 -10
  27. package/lib/catalog/source-catalog.js +10 -4
  28. package/lib/catalog/suite-components.js +7 -7
  29. package/lib/catalog/suite-scanner.js +3 -1
  30. package/lib/catalog/surfaces.js +5 -26
  31. package/lib/catalog/validate.js +7 -11
  32. package/lib/contracts/market.js +2 -0
  33. package/lib/contracts/settings.js +63 -0
  34. package/lib/index.js +115 -217
  35. package/lib/model/layouts.js +10 -1
  36. package/lib/model/types.js +26 -3
  37. package/lib/routes.js +57 -15
  38. package/lib/runtime/agent-role-names.js +70 -0
  39. package/lib/runtime/agent-role-router.js +142 -106
  40. package/lib/runtime/commands-mounts.js +55 -11
  41. package/lib/runtime/deadline.js +54 -0
  42. package/lib/runtime/dynamic-context.js +140 -0
  43. package/lib/runtime/feedback-tool.js +101 -46
  44. package/lib/runtime/hooks-mounts.js +9 -11
  45. package/lib/runtime/host-locale.js +49 -24
  46. package/lib/runtime/lsp-direct-config.js +19 -19
  47. package/lib/runtime/lsp-mounts.js +182 -70
  48. package/lib/runtime/lsp-server-state.js +4 -4
  49. package/lib/runtime/lsp-status.js +1 -1
  50. package/lib/runtime/mcp-auth-record.js +42 -0
  51. package/lib/runtime/mcp-backend.js +14 -14
  52. package/lib/runtime/mcp-client/config.js +8 -1
  53. package/lib/runtime/mcp-client/connection.js +38 -43
  54. package/lib/runtime/mcp-client/host-contract.js +10 -0
  55. package/lib/runtime/mcp-client/host-seams.js +8 -88
  56. package/lib/runtime/mcp-client/oauth.js +5 -7
  57. package/lib/runtime/mcp-client/plugin-identity.js +28 -0
  58. package/lib/runtime/mcp-client/projection.js +202 -0
  59. package/lib/runtime/mcp-client/tools.js +4 -189
  60. package/lib/runtime/mcp-config.js +36 -14
  61. package/lib/runtime/mcp-direct-config.js +33 -16
  62. package/lib/runtime/mcp-mounts.js +35 -75
  63. package/lib/runtime/mcp-overrides.js +5 -5
  64. package/lib/runtime/mcp-redaction.js +3 -2
  65. package/lib/runtime/mcp-status.js +7 -8
  66. package/lib/runtime/mount-lifecycle.js +73 -0
  67. package/lib/runtime/profile-seam.js +321 -0
  68. package/lib/runtime/project-runtime.js +34 -17
  69. package/lib/runtime/reconcile-scheduler.js +97 -0
  70. package/lib/runtime/reconciler.js +6 -1
  71. package/lib/runtime/regions.js +0 -19
  72. package/lib/runtime/server-config.js +6 -4
  73. package/lib/runtime/settings-namespace.js +144 -0
  74. package/lib/runtime/skills-provider.js +38 -14
  75. package/lib/runtime/source-auto-update.js +66 -0
  76. package/lib/{model/state.js → runtime/state-store.js} +9 -11
  77. package/lib/runtime/storage-migration.js +35 -18
  78. package/lib/runtime/subagent-catalog.js +5 -4
  79. package/lib/runtime/timer-seat.js +80 -0
  80. package/lib/runtime/tool-registry-observer.js +20 -20
  81. package/lib/runtime/user-commands.js +7 -3
  82. package/lib/runtime/user-panels.js +125 -46
  83. package/lib/runtime/user-store.js +124 -69
  84. package/lib/types/application/catalog-context.d.ts +124 -0
  85. package/lib/types/application/catalog.d.ts +108 -304
  86. package/lib/types/application/install-store.d.ts +21 -0
  87. package/lib/types/application/lsp-service.d.ts +36 -0
  88. package/lib/types/application/mcp-service.d.ts +77 -0
  89. package/lib/types/application/panel-resources.d.ts +8 -0
  90. package/lib/types/application/ports.d.ts +72 -0
  91. package/lib/types/application/queries.d.ts +15 -26
  92. package/lib/types/application/snapshot-cache.d.ts +51 -0
  93. package/lib/types/application/source-store.d.ts +100 -0
  94. package/lib/types/catalog/archive.d.ts +3 -11
  95. package/lib/types/catalog/component-files.d.ts +4 -0
  96. package/lib/types/catalog/fs-probes.d.ts +10 -0
  97. package/lib/types/catalog/manifests.d.ts +17 -16
  98. package/lib/types/catalog/native-project.d.ts +2 -2
  99. package/lib/types/catalog/paths.d.ts +53 -15
  100. package/lib/types/catalog/plugin-variables.d.ts +16 -0
  101. package/lib/types/catalog/scan-pipeline.d.ts +3 -3
  102. package/lib/types/catalog/scan-resolvers.d.ts +3 -9
  103. package/lib/types/catalog/skills-parse.d.ts +13 -7
  104. package/lib/types/catalog/source-catalog.d.ts +10 -5
  105. package/lib/types/catalog/suite-scanner.d.ts +8 -6
  106. package/lib/types/catalog/validate.d.ts +0 -2
  107. package/lib/types/contracts/lsp-status.d.ts +35 -0
  108. package/lib/types/contracts/market.d.ts +13 -2
  109. package/lib/types/contracts/mcp-status.d.ts +4 -0
  110. package/lib/types/contracts/settings.d.ts +59 -0
  111. package/lib/types/model/layouts.d.ts +10 -0
  112. package/lib/types/model/types.d.ts +29 -5
  113. package/lib/types/runtime/agent-role-names.d.ts +6 -0
  114. package/lib/types/runtime/agent-role-router.d.ts +59 -52
  115. package/lib/types/runtime/commands-mounts.d.ts +15 -7
  116. package/lib/types/runtime/deadline.d.ts +17 -0
  117. package/lib/types/runtime/dynamic-context.d.ts +81 -0
  118. package/lib/types/runtime/feedback-tool.d.ts +33 -11
  119. package/lib/types/runtime/hooks-mounts.d.ts +1 -1
  120. package/lib/types/runtime/host-locale.d.ts +20 -2
  121. package/lib/types/runtime/lsp-direct-config.d.ts +3 -3
  122. package/lib/types/runtime/lsp-mounts.d.ts +69 -19
  123. package/lib/types/runtime/lsp-status.d.ts +2 -1
  124. package/lib/types/runtime/mcp-auth-record.d.ts +29 -0
  125. package/lib/types/runtime/mcp-backend.d.ts +10 -14
  126. package/lib/types/runtime/mcp-client/config.d.ts +8 -2
  127. package/lib/types/runtime/mcp-client/host-contract.d.ts +78 -0
  128. package/lib/types/runtime/mcp-client/host-seams.d.ts +20 -64
  129. package/lib/types/runtime/mcp-client/oauth.d.ts +1 -1
  130. package/lib/types/runtime/mcp-client/plugin-identity.d.ts +16 -0
  131. package/lib/types/runtime/mcp-client/projection.d.ts +45 -0
  132. package/lib/types/runtime/mcp-client/tools.d.ts +5 -72
  133. package/lib/types/runtime/mcp-config.d.ts +25 -4
  134. package/lib/types/runtime/mcp-direct-config.d.ts +18 -4
  135. package/lib/types/runtime/mcp-mounts.d.ts +10 -15
  136. package/lib/types/runtime/mcp-overrides.d.ts +1 -1
  137. package/lib/types/runtime/mcp-status.d.ts +1 -1
  138. package/lib/types/runtime/mount-lifecycle.d.ts +53 -0
  139. package/lib/types/runtime/profile-seam.d.ts +64 -0
  140. package/lib/types/runtime/project-runtime.d.ts +10 -3
  141. package/lib/types/runtime/reconcile-scheduler.d.ts +45 -0
  142. package/lib/types/runtime/reconciler.d.ts +2 -0
  143. package/lib/types/runtime/regions.d.ts +1 -4
  144. package/lib/types/runtime/settings-namespace.d.ts +76 -0
  145. package/lib/types/runtime/skills-provider.d.ts +11 -2
  146. package/lib/types/runtime/source-auto-update.d.ts +32 -0
  147. package/lib/types/{model/state.d.ts → runtime/state-store.d.ts} +2 -2
  148. package/lib/types/runtime/storage-migration.d.ts +5 -3
  149. package/lib/types/runtime/subagent-catalog.d.ts +2 -0
  150. package/lib/types/runtime/timer-seat.d.ts +51 -0
  151. package/lib/types/runtime/tool-registry-observer.d.ts +12 -6
  152. package/lib/types/runtime/user-panels.d.ts +69 -19
  153. package/lib/types/runtime/user-store.d.ts +67 -20
  154. package/package.json +68 -24
  155. package/schemas/README.md +1 -1
@@ -0,0 +1,188 @@
1
+ /**
2
+ * The shared mutable core of one catalog: the persisted state, the serialized
3
+ * mutation queue, the revision and scan generations, and the change pipeline
4
+ * every mutation funnels through.
5
+ *
6
+ * The collaborators receive this object instead of reaching into each other,
7
+ * so the invariants they share — one queue, one generation counter, one
8
+ * notification path — have a single owner.
9
+ */
10
+ import { join } from 'node:path';
11
+ import { MARKET_SETTINGS_DEFAULTS } from '../contracts/settings.js';
12
+ import { STATE_FILE_NAME } from '../catalog/paths.js';
13
+ import { settlesWithin } from '../runtime/deadline.js';
14
+ import { EMPTY_STATE, loadState, saveState } from '../runtime/state-store.js';
15
+ import { effectiveSurfaces } from '../model/types.js';
16
+ import { SCAN_CACHE_TTL_MS, SnapshotCache } from './snapshot-cache.js';
17
+ /** Key of one install entry in the persisted `installed` record. */
18
+ export function installKey(sourceId, suiteId) {
19
+ return `${sourceId}/${suiteId}`;
20
+ }
21
+ /**
22
+ * How long an explicit caller waits for the derived refresh before answering
23
+ * anyway. The refresh keeps running; only the wait ends.
24
+ */
25
+ export const DERIVED_REFRESH_WAIT_MS = 10_000;
26
+ export class CatalogContext {
27
+ currentState = EMPTY_STATE;
28
+ mutationQueue = Promise.resolve();
29
+ currentRevision = 0;
30
+ currentScanGeneration = 0;
31
+ /**
32
+ * The project-layout switch in effect. The host settings document owns the
33
+ * value and pushes it here on registration and on every change; the initial
34
+ * value is the contract's declared default, which is what the catalog would
35
+ * read from the document before the settings service resolves.
36
+ */
37
+ scanProjectLayoutsEnabled = MARKET_SETTINGS_DEFAULTS.scanProjectLayouts;
38
+ /** The derived refresh in flight, shared by every change that lands while it runs. */
39
+ refreshPass;
40
+ /** Whether a change landed after the running pass started; it earns one more pass. */
41
+ refreshQueued = false;
42
+ statePath;
43
+ userRoot;
44
+ dataRoot;
45
+ agentsRoot;
46
+ git;
47
+ /** Discovery scans and dimension snapshots derived from {@link state}. */
48
+ snapshots;
49
+ onChanged;
50
+ constructor(options) {
51
+ this.statePath = join(options.userRoot, STATE_FILE_NAME);
52
+ this.userRoot = options.userRoot;
53
+ this.dataRoot = options.dataRoot;
54
+ this.agentsRoot = options.agentsRoot;
55
+ this.git = options.git ?? {};
56
+ this.onChanged = options.onChanged;
57
+ this.snapshots = new SnapshotCache(this, {
58
+ user: options.userSnapshotTtlMs ?? SCAN_CACHE_TTL_MS,
59
+ project: options.projectSnapshotTtlMs ?? 5_000
60
+ });
61
+ }
62
+ get state() {
63
+ return this.currentState;
64
+ }
65
+ /** Bumped by every mutation: a snapshot built at an older revision is never published. */
66
+ get revision() {
67
+ return this.currentRevision;
68
+ }
69
+ /** Bumped by every content-changing mutation: a scan started earlier never repopulates its cache. */
70
+ get scanGeneration() {
71
+ return this.currentScanGeneration;
72
+ }
73
+ /** Whether native project layouts (`.claude/`, `.agents/`) take part in discovery. */
74
+ get scanProjectLayouts() {
75
+ return this.scanProjectLayoutsEnabled;
76
+ }
77
+ /** One install entry, or undefined when the suite is not installed. */
78
+ installed(sourceId, suiteId) {
79
+ return this.currentState.installed[installKey(sourceId, suiteId)];
80
+ }
81
+ /** Load persisted user state once at plugin activation. */
82
+ async load() {
83
+ this.currentState = await loadState(this.statePath);
84
+ this.invalidateScans();
85
+ this.invalidateSnapshot(false);
86
+ }
87
+ /** Replace the persisted state and write it out. */
88
+ async commit(next) {
89
+ this.currentState = next;
90
+ await saveState(this.statePath, next);
91
+ }
92
+ /** Apply the host's project-layout switch and invalidate every project snapshot. */
93
+ async setScanProjectLayouts(enabled) {
94
+ if (this.scanProjectLayoutsEnabled === enabled)
95
+ return;
96
+ this.scanProjectLayoutsEnabled = enabled;
97
+ await this.notifyChanged();
98
+ }
99
+ /**
100
+ * Apply the install state to freshly discovered suites: enablement, the
101
+ * effective surface toggles, and the lock/install timestamps the market
102
+ * cards report.
103
+ */
104
+ project(discovered, state, dimension) {
105
+ return discovered.map(suite => {
106
+ const installed = state.installed[installKey(suite.sourceId, suite.id)];
107
+ // Native project layouts (`.claude/`, `.agents/`) are the repository's
108
+ // own files read in place: they carry no install state and stay enabled.
109
+ const enabled = suite.manifest.layout === 'project-native' || installed?.enabled === true;
110
+ return {
111
+ ...suite,
112
+ enabled,
113
+ activeSurfaces: {
114
+ ...effectiveSurfaces(installed?.surfaces),
115
+ ...(suite.manifest.layout === 'project-native' ? suite.activeSurfaces : {}),
116
+ ...(dimension === 'project' ? { lsp: false } : {})
117
+ },
118
+ ...(installed?.lockCommit === undefined ? {} : { lockCommit: installed.lockCommit }),
119
+ ...(installed?.installedAt === undefined ? {} : { installedAt: installed.installedAt })
120
+ };
121
+ });
122
+ }
123
+ /**
124
+ * Invalidate snapshots and schedule the change pipeline. `keepScanCache`
125
+ * marks state-only mutations (install, enable, surface toggles, MCP
126
+ * overrides) whose inputs leave every checkout untouched, so the next
127
+ * snapshot re-derives from cached discovery instead of rescanning the
128
+ * filesystem.
129
+ *
130
+ * The invalidation is synchronous and the refresh is coalesced in the
131
+ * background: resolving here means the state is durable, never that every
132
+ * mount has finished. Callers that must observe the refreshed surfaces await
133
+ * {@link refreshSettled}, whose wait is bounded so one stuck mount cannot
134
+ * hold a request — or the next mutation behind it — open.
135
+ */
136
+ async notifyChanged(keepScanCache = false) {
137
+ if (!keepScanCache)
138
+ this.invalidateScans();
139
+ this.invalidateSnapshot(true);
140
+ this.scheduleRefresh();
141
+ }
142
+ /**
143
+ * Resolve once the queued derived refresh finishes, `false` when the deadline
144
+ * elapses first. The refresh itself is never cancelled.
145
+ */
146
+ async refreshSettled(deadlineMs = DERIVED_REFRESH_WAIT_MS) {
147
+ const pass = this.refreshPass;
148
+ return pass === undefined ? true : settlesWithin(pass, deadlineMs);
149
+ }
150
+ /** Queue one derived refresh; a pass already in flight absorbs it. */
151
+ scheduleRefresh() {
152
+ this.refreshQueued = true;
153
+ this.refreshPass ??= (async () => {
154
+ try {
155
+ while (this.refreshQueued) {
156
+ this.refreshQueued = false;
157
+ try {
158
+ await this.onChanged();
159
+ }
160
+ catch {
161
+ // The pipeline owner reports its own stage failures. A rejected
162
+ // pass must not wedge the queue for every later change.
163
+ }
164
+ }
165
+ }
166
+ finally {
167
+ this.refreshPass = undefined;
168
+ }
169
+ })();
170
+ }
171
+ /** Drop every cached dimension snapshot; `increment` advances the revision. */
172
+ invalidateSnapshot(increment) {
173
+ if (increment)
174
+ this.currentRevision++;
175
+ this.snapshots.invalidateSnapshots();
176
+ }
177
+ /** Drop cached discovery and advance the generation a scan is validated against. */
178
+ invalidateScans() {
179
+ this.currentScanGeneration++;
180
+ this.snapshots.invalidateScans();
181
+ }
182
+ /** Serialize one mutation behind every mutation queued before it. */
183
+ enqueue(operation) {
184
+ const result = this.mutationQueue.then(operation, operation);
185
+ this.mutationQueue = result.catch(() => { });
186
+ return result;
187
+ }
188
+ }