dsh-agent-plugins-market 0.6.2 → 0.7.0

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