@pcircle/memesh 4.8.2 → 4.8.3
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/mcp.json +7 -0
- package/.codex-plugin/plugin.json +6 -0
- package/AGENTS.md +10 -5
- package/README.de.md +11 -10
- package/README.md +23 -11
- package/README.zh-TW.md +23 -11
- package/dashboard/dist/index.html +3 -3
- package/dist/core/agent-message-inbox.d.ts +2 -2
- package/dist/core/agent-message-inbox.d.ts.map +1 -1
- package/dist/core/agent-message-inbox.js +10 -5
- package/dist/core/agent-message-inbox.js.map +1 -1
- package/dist/core/agent-messaging.d.ts +7 -0
- package/dist/core/agent-messaging.d.ts.map +1 -1
- package/dist/core/agent-messaging.js +28 -9
- package/dist/core/agent-messaging.js.map +1 -1
- package/dist/core/agent-router.d.ts +27 -20
- package/dist/core/agent-router.d.ts.map +1 -1
- package/dist/core/agent-router.js +114 -43
- package/dist/core/agent-router.js.map +1 -1
- package/dist/core/briefing.d.ts +1 -1
- package/dist/core/briefing.d.ts.map +1 -1
- package/dist/core/briefing.js +18 -6
- package/dist/core/briefing.js.map +1 -1
- package/dist/core/citation-rule.d.ts.map +1 -1
- package/dist/core/citation-rule.js +5 -2
- package/dist/core/citation-rule.js.map +1 -1
- package/dist/core/doctor.d.ts +8 -0
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +309 -10
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/install-channel.d.ts +3 -0
- package/dist/core/install-channel.d.ts.map +1 -1
- package/dist/core/install-channel.js +79 -2
- package/dist/core/install-channel.js.map +1 -1
- package/dist/core/install-hooks.d.ts.map +1 -1
- package/dist/core/install-hooks.js +10 -6
- package/dist/core/install-hooks.js.map +1 -1
- package/dist/core/lesson-slug.d.ts.map +1 -1
- package/dist/core/lesson-slug.js +6 -4
- package/dist/core/lesson-slug.js.map +1 -1
- package/dist/core/llm-client.d.ts.map +1 -1
- package/dist/core/llm-client.js +4 -1
- package/dist/core/llm-client.js.map +1 -1
- package/dist/core/llm-validator.d.ts.map +1 -1
- package/dist/core/llm-validator.js +6 -15
- package/dist/core/llm-validator.js.map +1 -1
- package/dist/core/ollama-host.d.ts +6 -0
- package/dist/core/ollama-host.d.ts.map +1 -0
- package/dist/core/ollama-host.js +30 -0
- package/dist/core/ollama-host.js.map +1 -0
- package/dist/core/schema-export.d.ts.map +1 -1
- package/dist/core/schema-export.js +8 -6
- package/dist/core/schema-export.js.map +1 -1
- package/dist/core/work-topology.d.ts +3 -0
- package/dist/core/work-topology.d.ts.map +1 -1
- package/dist/core/work-topology.js +24 -2
- package/dist/core/work-topology.js.map +1 -1
- package/dist/host-adapters/claude-channel.d.ts +0 -58
- package/dist/host-adapters/claude-channel.d.ts.map +1 -1
- package/dist/host-adapters/claude-channel.js +0 -242
- package/dist/host-adapters/claude-channel.js.map +1 -1
- package/dist/host-adapters/codex-cli-queue.d.ts.map +1 -1
- package/dist/host-adapters/codex-cli-queue.js +15 -12
- package/dist/host-adapters/codex-cli-queue.js.map +1 -1
- package/dist/host-runtime/acp.d.ts +2 -0
- package/dist/host-runtime/acp.d.ts.map +1 -1
- package/dist/host-runtime/acp.js +4 -0
- package/dist/host-runtime/acp.js.map +1 -1
- package/dist/host-runtime/claude.d.ts +2 -0
- package/dist/host-runtime/claude.d.ts.map +1 -1
- package/dist/host-runtime/claude.js +6 -5
- package/dist/host-runtime/claude.js.map +1 -1
- package/dist/host-runtime/codex-session.d.ts +3 -1
- package/dist/host-runtime/codex-session.d.ts.map +1 -1
- package/dist/host-runtime/codex-session.js +7 -5
- package/dist/host-runtime/codex-session.js.map +1 -1
- package/dist/host-runtime/codex.d.ts +2 -0
- package/dist/host-runtime/codex.d.ts.map +1 -1
- package/dist/host-runtime/codex.js +4 -0
- package/dist/host-runtime/codex.js.map +1 -1
- package/dist/host-runtime/router-client.d.ts +2 -0
- package/dist/host-runtime/router-client.d.ts.map +1 -1
- package/dist/host-runtime/router-client.js.map +1 -1
- package/dist/skills-manifest.json +23 -13
- package/dist/storage/graph-repairs.d.ts.map +1 -1
- package/dist/storage/graph-repairs.js +70 -22
- package/dist/storage/graph-repairs.js.map +1 -1
- package/dist/transports/agent-messaging.d.ts +10 -1
- package/dist/transports/agent-messaging.d.ts.map +1 -1
- package/dist/transports/agent-messaging.js +92 -9
- package/dist/transports/agent-messaging.js.map +1 -1
- package/dist/transports/cli/cli.d.ts +4 -0
- package/dist/transports/cli/cli.d.ts.map +1 -1
- package/dist/transports/cli/cli.js +65 -26
- package/dist/transports/cli/cli.js.map +1 -1
- package/dist/transports/mcp/handlers.d.ts +10 -6
- package/dist/transports/mcp/handlers.d.ts.map +1 -1
- package/dist/transports/mcp/handlers.js +21 -9
- package/dist/transports/mcp/handlers.js.map +1 -1
- package/dist/transports/schemas.d.ts +5 -0
- package/dist/transports/schemas.d.ts.map +1 -1
- package/dist/transports/schemas.js +8 -1
- package/dist/transports/schemas.js.map +1 -1
- package/docs/platforms/README.md +1 -1
- package/docs/platforms/agent-messaging.md +89 -36
- package/llms-install.md +29 -6
- package/package.json +5 -1
- package/scripts/hooks/_generated/agent-message-inbox.js +10 -5
- package/scripts/hooks/_generated/citation-rule.js +5 -2
- package/scripts/hooks/_generated/work-topology.js +24 -2
- package/scripts/hooks/_shared.js +1 -1
- package/scripts/hooks/session-start.js +37 -23
- package/scripts/upgrade-plugin.sh +531 -81
- package/skills/memesh/SKILL.md +20 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"citation-rule.js","sourceRoot":"","sources":["../../src/core/citation-rule.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"citation-rule.js","sourceRoot":"","sources":["../../src/core/citation-rule.ts"],"names":[],"mappings":"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"}
|
package/dist/core/doctor.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ interface DoctorOptions {
|
|
|
38
38
|
getUpdateCheckImpl?: typeof getUpdateCheck;
|
|
39
39
|
getCurrentInstallChannelImpl?: typeof getCurrentInstallChannel;
|
|
40
40
|
installedPluginsPathImpl?: string;
|
|
41
|
+
marketplaceHeadShaImpl?: (host: import('./install-channel.js').PluginHost) => string | null;
|
|
42
|
+
pluginCacheDiscoveryImpl?: () => PluginCacheDiscovery[];
|
|
41
43
|
getInstallChannelSupportImpl?: typeof getInstallChannelSupport;
|
|
42
44
|
existsSyncImpl?: typeof fs.existsSync;
|
|
43
45
|
readFileSyncImpl?: typeof fs.readFileSync;
|
|
@@ -64,6 +66,12 @@ interface DoctorOptions {
|
|
|
64
66
|
probeMessageRouterStatus?: boolean;
|
|
65
67
|
messageRouterStatusProbeImpl?: () => Promise<MessageRouterStatusProbe>;
|
|
66
68
|
}
|
|
69
|
+
interface PluginCacheDiscovery {
|
|
70
|
+
host: import('./install-channel.js').PluginHost;
|
|
71
|
+
packageRoot: string;
|
|
72
|
+
installedPluginsPath?: string;
|
|
73
|
+
unverifiableReason?: string;
|
|
74
|
+
}
|
|
67
75
|
type MessageRouterStatusProbe = {
|
|
68
76
|
socket_path: string;
|
|
69
77
|
socket: 'reachable' | 'missing' | 'insecure' | 'unreachable';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/core/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAQpB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAA4D,MAAM,aAAa,CAAC;AAE1H,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACL,YAAY,EAAE,aAAa,EAAyB,cAAc,EAEnE,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/core/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/core/doctor.js
CHANGED
|
@@ -12,7 +12,7 @@ import { probeProvider } from './llm-validator.js';
|
|
|
12
12
|
import { openDatabase, closeDatabase, getPendingReindexInfo, isDatabaseOpen, readVectorGeneration, generationRowIds, } from '../db.js';
|
|
13
13
|
import { getUpdateCheck } from './version-check.js';
|
|
14
14
|
import { classifyBump } from './updater.js';
|
|
15
|
-
import { getCurrentInstallChannel, getInstallChannelSupport, detectPluginHost } from './install-channel.js';
|
|
15
|
+
import { getCurrentInstallChannel, getInstallChannelSupport, detectPluginHost, pluginHostConfigRoot, versionedPluginCacheRoots, PLUGIN_REFRESH_COMMANDS, } from './install-channel.js';
|
|
16
16
|
import { getInstallRecord } from './install-id.js';
|
|
17
17
|
import { citationRulePath, citationRuleState } from './citation-rule.js';
|
|
18
18
|
import { getDbPath, getMemeshDirFromDbPath, homeDir, memeshDir, getProjectName } from './paths.js';
|
|
@@ -27,6 +27,7 @@ import { parseSqliteUtcMs } from './time-utils.js';
|
|
|
27
27
|
import { autoCaptureDecision } from './capture-flag.js';
|
|
28
28
|
import { guardFromMetadata } from './guards.js';
|
|
29
29
|
import { getAgentMessageStorageReport } from './agent-message-storage.js';
|
|
30
|
+
import { readHostConfigFile } from '../host-runtime/config.js';
|
|
30
31
|
const EMBEDDING_PROBE_TIMEOUT_MS = 15000;
|
|
31
32
|
const EXPECTED_HOOK_TYPES = ['PreToolUse', 'SessionStart', 'PostToolUse', 'Stop', 'PreCompact'];
|
|
32
33
|
const AGENT_MESSAGE_STORAGE_QUOTA_ENV = 'MEMESH_AGENT_MESSAGE_STORAGE_QUOTA_BYTES';
|
|
@@ -147,6 +148,15 @@ function inspectAgentMessageStorage(db, databasePath, policy) {
|
|
|
147
148
|
return undefined;
|
|
148
149
|
}
|
|
149
150
|
}
|
|
151
|
+
function inspectCodexSessionSetup(codexPluginCacheDetected, existsSyncImpl) {
|
|
152
|
+
if (!codexPluginCacheDetected)
|
|
153
|
+
return null;
|
|
154
|
+
const configPath = path.join(getMemeshDirFromDbPath(), 'hosts', 'codex-session.json');
|
|
155
|
+
if (existsSyncImpl(configPath)) {
|
|
156
|
+
return createCheck('codex-session-setup', 'Codex ordinary-session notification setup', 'pass', 'A Codex plugin cache copy was detected, but this proves only that cached source exists, not that the plugin is enabled or registered. The explicit opt-in ordinary-session notification setup is present; durable inbox remains available, and MeMesh will not auto-attach.');
|
|
157
|
+
}
|
|
158
|
+
return createCheck('codex-session-setup', 'Codex ordinary-session notification setup', 'warn', 'A Codex plugin cache copy was detected, but this proves only that cached source exists, not that the plugin is enabled or registered. Durable inbox remains available, but live ordinary-session wakeup is inactive. Setup is explicit opt-in; MeMesh will not auto-attach.', 'Run `memesh agent setup codex-session --project <project> --principal <principal> --workspace <exact-workspace>`, then restart Codex.', { code: 'codex-session.config-missing' });
|
|
159
|
+
}
|
|
150
160
|
function configuredAgentMessageStoragePolicy(explicit) {
|
|
151
161
|
if (explicit !== undefined)
|
|
152
162
|
return explicit;
|
|
@@ -235,8 +245,12 @@ function extractHookScriptPaths(hooksConfig, packageRoot) {
|
|
|
235
245
|
return [];
|
|
236
246
|
const scripts = new Set();
|
|
237
247
|
for (const entries of Object.values(hooks)) {
|
|
238
|
-
|
|
239
|
-
|
|
248
|
+
if (!Array.isArray(entries))
|
|
249
|
+
continue;
|
|
250
|
+
for (const entry of entries) {
|
|
251
|
+
if (!Array.isArray(entry.hooks))
|
|
252
|
+
continue;
|
|
253
|
+
for (const hook of entry.hooks) {
|
|
240
254
|
if (typeof hook.command !== 'string')
|
|
241
255
|
continue;
|
|
242
256
|
const command = hook.command.replace('${CLAUDE_PLUGIN_ROOT}/', '');
|
|
@@ -259,7 +273,10 @@ function inspectHooksConfig(packageRoot, platform, existsSyncImpl, readFileSyncI
|
|
|
259
273
|
createCheck('hooks-config', 'Hooks config', 'fail', 'hooks/hooks.json is not valid JSON.', `Fix ${hooksPath} so Claude Code can load the hook definitions.`, { code: 'hooks-config.invalid-json', params: { path: hooksPath } }),
|
|
260
274
|
];
|
|
261
275
|
}
|
|
262
|
-
const
|
|
276
|
+
const parsedHooks = parsed.value.hooks;
|
|
277
|
+
const hookTypes = parsedHooks && typeof parsedHooks === 'object' && !Array.isArray(parsedHooks)
|
|
278
|
+
? Object.keys(parsedHooks)
|
|
279
|
+
: [];
|
|
263
280
|
const missingTypes = EXPECTED_HOOK_TYPES.filter((type) => !hookTypes.includes(type));
|
|
264
281
|
const configCheck = missingTypes.length > 0
|
|
265
282
|
? createCheck('hooks-config', 'Hooks config', 'fail', `hooks/hooks.json is missing expected hook types: ${missingTypes.join(', ')}.`, 'Restore the shipped hook configuration or reinstall MeMesh.', { code: 'hooks-config.missing-types', params: { types: missingTypes.join(', ') } })
|
|
@@ -623,6 +640,255 @@ function inspectShellCli(installChannel, packageRoot, resolveShellMemeshImpl) {
|
|
|
623
640
|
? `\`memesh\` resolves to ${shellPath}.`
|
|
624
641
|
: `No shell-PATH \`memesh\` detected. If you want terminal access, run \`npm install -g @pcircle/memesh\` (this install is a ${installChannel}, so the check is informational only).`);
|
|
625
642
|
}
|
|
643
|
+
function defaultMarketplaceHeadSha(host) {
|
|
644
|
+
if (host === 'codex') {
|
|
645
|
+
const codexHome = pluginHostConfigRoot('codex');
|
|
646
|
+
return readCodexInstallRevision(path.join(codexHome, '.tmp', 'marketplaces', 'pcircle-memesh'), fs.readFileSync);
|
|
647
|
+
}
|
|
648
|
+
const dir = path.join(pluginHostConfigRoot('claude-code'), 'plugins', 'marketplaces', 'pcircle-memesh');
|
|
649
|
+
try {
|
|
650
|
+
const out = execFileSync('git', ['-C', dir, 'rev-parse', 'HEAD'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
651
|
+
return /^[0-9a-f]{40}$/.test(out) ? out : null;
|
|
652
|
+
}
|
|
653
|
+
catch {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
function readCodexInstallRevision(root, readFileSyncImpl) {
|
|
658
|
+
const parsed = parseJsonFile(path.join(root, '.codex-marketplace-install.json'), readFileSyncImpl);
|
|
659
|
+
if (!parsed.ok)
|
|
660
|
+
return null;
|
|
661
|
+
const rev = parsed.value.revision;
|
|
662
|
+
return typeof rev === 'string' && /^[0-9a-f]{40}$/.test(rev) ? rev : null;
|
|
663
|
+
}
|
|
664
|
+
function pluginCacheUnverifiable(host, missing) {
|
|
665
|
+
const hostLabel = host === 'codex' ? 'Codex' : 'Claude Code';
|
|
666
|
+
const command = PLUGIN_REFRESH_COMMANDS[host];
|
|
667
|
+
return createCheck('plugin-cache', `Plugin cache source record is current (${hostLabel})`, 'warn', `Could not tell whether the plugin cache matches the marketplace: ${missing}. The version alone cannot answer this — two builds can carry the same version.`, `Run \`${command}\` — it re-stages the cache from the marketplace and records the commit, after which this check can answer.`, { code: 'plugin-cache.unverifiable', params: { host: hostLabel, command } });
|
|
668
|
+
}
|
|
669
|
+
function readClaudePluginEntries(registryPath, readFileSyncImpl, existsSyncImpl) {
|
|
670
|
+
if (!existsSyncImpl(registryPath)) {
|
|
671
|
+
return { exists: false, readable: false, defined: false, malformed: false, entries: [] };
|
|
672
|
+
}
|
|
673
|
+
const parsed = parseJsonFile(registryPath, readFileSyncImpl);
|
|
674
|
+
if (!parsed.ok)
|
|
675
|
+
return { exists: true, readable: false, defined: false, malformed: false, entries: [] };
|
|
676
|
+
const raw = parsed.value?.plugins?.['memesh@pcircle-memesh'];
|
|
677
|
+
const entries = Array.isArray(raw)
|
|
678
|
+
? raw.filter((entry) => !!entry && typeof entry === 'object')
|
|
679
|
+
: [];
|
|
680
|
+
return {
|
|
681
|
+
exists: true,
|
|
682
|
+
readable: true,
|
|
683
|
+
defined: raw !== undefined,
|
|
684
|
+
malformed: raw !== undefined && (!Array.isArray(raw) || entries.length !== raw.length),
|
|
685
|
+
entries,
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
function defaultPluginCacheDiscovery(readFileSyncImpl, existsSyncImpl) {
|
|
689
|
+
const discovered = [];
|
|
690
|
+
const claudeConfigRoot = pluginHostConfigRoot('claude-code');
|
|
691
|
+
const claudeRegistry = path.join(claudeConfigRoot, 'plugins', 'installed_plugins.json');
|
|
692
|
+
const claudeCacheRoot = path.join(claudeConfigRoot, 'plugins', 'cache', 'pcircle-memesh', 'memesh');
|
|
693
|
+
const registry = readClaudePluginEntries(claudeRegistry, readFileSyncImpl, existsSyncImpl);
|
|
694
|
+
const entries = registry.entries;
|
|
695
|
+
if (registry.malformed) {
|
|
696
|
+
discovered.push({
|
|
697
|
+
host: 'claude-code',
|
|
698
|
+
packageRoot: claudeCacheRoot,
|
|
699
|
+
installedPluginsPath: claudeRegistry,
|
|
700
|
+
unverifiableReason: 'installed_plugins.json has a malformed memesh entry',
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
else if (entries.length > 0) {
|
|
704
|
+
const cachesByRoot = new Map();
|
|
705
|
+
for (const entry of entries) {
|
|
706
|
+
const recordedInstallPath = typeof entry.installPath === 'string' && entry.installPath.length > 0
|
|
707
|
+
? entry.installPath
|
|
708
|
+
: null;
|
|
709
|
+
const installPath = recordedInstallPath ?? claudeCacheRoot;
|
|
710
|
+
const cache = {
|
|
711
|
+
host: 'claude-code', packageRoot: installPath, installedPluginsPath: claudeRegistry,
|
|
712
|
+
...(!recordedInstallPath ? { unverifiableReason: 'an installed_plugins.json entry has no usable installPath' }
|
|
713
|
+
: !existsSyncImpl(installPath) ? { unverifiableReason: `the recorded plugin cache does not exist at ${installPath}` } : {}),
|
|
714
|
+
};
|
|
715
|
+
const rootKey = path.resolve(installPath);
|
|
716
|
+
const existing = cachesByRoot.get(rootKey);
|
|
717
|
+
if (!existing)
|
|
718
|
+
cachesByRoot.set(rootKey, cache);
|
|
719
|
+
else if (!existing.unverifiableReason && cache.unverifiableReason) {
|
|
720
|
+
existing.unverifiableReason = cache.unverifiableReason;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
discovered.push(...cachesByRoot.values());
|
|
724
|
+
}
|
|
725
|
+
else if (registry.defined) {
|
|
726
|
+
const cachedRoots = versionedPluginCacheRoots(claudeCacheRoot);
|
|
727
|
+
if (cachedRoots.length > 0) {
|
|
728
|
+
discovered.push({
|
|
729
|
+
host: 'claude-code',
|
|
730
|
+
packageRoot: cachedRoots[cachedRoots.length - 1],
|
|
731
|
+
installedPluginsPath: claudeRegistry,
|
|
732
|
+
unverifiableReason: 'installed_plugins.json records no active memesh install while a versioned plugin cache still exists',
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
else if (!registry.readable) {
|
|
737
|
+
const cachedRoots = versionedPluginCacheRoots(claudeCacheRoot);
|
|
738
|
+
const cachedRoot = cachedRoots[cachedRoots.length - 1];
|
|
739
|
+
if (cachedRoot) {
|
|
740
|
+
discovered.push({
|
|
741
|
+
host: 'claude-code', packageRoot: cachedRoot, installedPluginsPath: claudeRegistry,
|
|
742
|
+
unverifiableReason: registry.exists
|
|
743
|
+
? 'installed_plugins.json could not be read or parsed'
|
|
744
|
+
: 'installed_plugins.json does not exist while a versioned plugin cache still exists',
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
const codexHome = pluginHostConfigRoot('codex');
|
|
749
|
+
const codexCacheRoot = path.join(codexHome, 'plugins', 'cache', 'pcircle-memesh', 'memesh');
|
|
750
|
+
const codexRoots = versionedPluginCacheRoots(codexCacheRoot);
|
|
751
|
+
if (codexRoots.length === 1) {
|
|
752
|
+
discovered.push({ host: 'codex', packageRoot: codexRoots[0] });
|
|
753
|
+
}
|
|
754
|
+
else if (codexRoots.length > 1) {
|
|
755
|
+
discovered.push({
|
|
756
|
+
host: 'codex',
|
|
757
|
+
packageRoot: codexRoots[codexRoots.length - 1],
|
|
758
|
+
unverifiableReason: `several versioned Codex plugin cache directories exist under ${codexCacheRoot}`,
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
return discovered;
|
|
762
|
+
}
|
|
763
|
+
function inspectPluginCacheCurrency(installChannel, pluginHost, packageRoot, installedPluginsPath, readFileSyncImpl, existsSyncImpl, marketplaceHeadShaImpl) {
|
|
764
|
+
if (installChannel !== 'plugin-marketplace')
|
|
765
|
+
return null;
|
|
766
|
+
const host = pluginHost === 'codex' ? 'codex' : 'claude-code';
|
|
767
|
+
const hostLabel = host === 'codex' ? 'Codex' : 'Claude Code';
|
|
768
|
+
const command = PLUGIN_REFRESH_COMMANDS[host];
|
|
769
|
+
let installedSha;
|
|
770
|
+
let installedMissing;
|
|
771
|
+
if (host === 'codex') {
|
|
772
|
+
installedSha = readCodexInstallRevision(packageRoot, readFileSyncImpl);
|
|
773
|
+
installedMissing = 'the plugin cache carries no readable .codex-marketplace-install.json revision';
|
|
774
|
+
}
|
|
775
|
+
else {
|
|
776
|
+
const registryPath = installedPluginsPath ?? path.join(pluginHostConfigRoot('claude-code'), 'plugins', 'installed_plugins.json');
|
|
777
|
+
const registry = readClaudePluginEntries(registryPath, readFileSyncImpl, existsSyncImpl);
|
|
778
|
+
const entries = registry.entries;
|
|
779
|
+
const here = path.resolve(packageRoot);
|
|
780
|
+
const matching = entries.filter(e => typeof e?.installPath === 'string' && path.resolve(e.installPath) === here);
|
|
781
|
+
const soleEntry = entries.length === 1 ? entries[0] : undefined;
|
|
782
|
+
const soleEntryHasPath = typeof soleEntry?.installPath === 'string' && soleEntry.installPath.length > 0;
|
|
783
|
+
const entry = matching.length === 1 ? matching[0] : undefined;
|
|
784
|
+
installedSha = !registry.malformed
|
|
785
|
+
&& typeof entry?.gitCommitSha === 'string'
|
|
786
|
+
&& /^[0-9a-f]{40}$/.test(entry.gitCommitSha)
|
|
787
|
+
? entry.gitCommitSha
|
|
788
|
+
: null;
|
|
789
|
+
if (!registry.exists) {
|
|
790
|
+
installedMissing = `installed_plugins.json does not exist at ${registryPath}`;
|
|
791
|
+
}
|
|
792
|
+
else if (!registry.readable) {
|
|
793
|
+
installedMissing = 'installed_plugins.json could not be read or parsed';
|
|
794
|
+
}
|
|
795
|
+
else if (registry.malformed) {
|
|
796
|
+
installedMissing = 'installed_plugins.json has a malformed memesh entry';
|
|
797
|
+
}
|
|
798
|
+
else if (!registry.defined) {
|
|
799
|
+
installedMissing = 'installed_plugins.json has no memesh@pcircle-memesh entry';
|
|
800
|
+
}
|
|
801
|
+
else if (entries.length === 0) {
|
|
802
|
+
installedMissing = 'installed_plugins.json records no active memesh install for this cache';
|
|
803
|
+
}
|
|
804
|
+
else if (matching.length > 1) {
|
|
805
|
+
installedMissing = `installed_plugins.json lists ${matching.length} memesh entries for this install (${packageRoot})`;
|
|
806
|
+
}
|
|
807
|
+
else if (matching.length === 0 && soleEntryHasPath) {
|
|
808
|
+
installedMissing = `the only memesh entry in installed_plugins.json names another install, not this one (${packageRoot})`;
|
|
809
|
+
}
|
|
810
|
+
else if (matching.length === 0 && soleEntry) {
|
|
811
|
+
installedMissing = 'the only memesh entry in installed_plugins.json has no usable installPath to identify this cache';
|
|
812
|
+
}
|
|
813
|
+
else if (entries.length > 1 && matching.length === 0) {
|
|
814
|
+
installedMissing = `installed_plugins.json lists ${entries.length} memesh entries and none of them is this install (${packageRoot})`;
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
installedMissing = 'installed_plugins.json does not record the commit this plugin was installed from';
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
const marketplaceSha = marketplaceHeadShaImpl(host);
|
|
821
|
+
if (!installedSha || !marketplaceSha) {
|
|
822
|
+
const missing = !installedSha ? installedMissing : `the ${hostLabel} marketplace snapshot has no readable commit`;
|
|
823
|
+
return pluginCacheUnverifiable(host, missing);
|
|
824
|
+
}
|
|
825
|
+
if (installedSha === marketplaceSha) {
|
|
826
|
+
return createCheck('plugin-cache', `Plugin cache source record is current (${hostLabel})`, 'pass', `The plugin cache records marketplace commit ${marketplaceSha.slice(0, 8)}, which matches the current marketplace snapshot.`);
|
|
827
|
+
}
|
|
828
|
+
return createCheck('plugin-cache', `Plugin cache source record is current (${hostLabel})`, 'warn', `The plugin cache records commit ${installedSha.slice(0, 8)}, but the marketplace has moved to ${marketplaceSha.slice(0, 8)} under the same version — ${hostLabel} does not normally refresh a cache whose version did not change, so refresh the cache before relying on the newer marketplace code.`, `Run \`${command}\` to refresh the cache in place, then restart ${hostLabel}.`, { code: 'plugin-cache.stale', params: { installed: installedSha.slice(0, 8), marketplace: marketplaceSha.slice(0, 8), host: hostLabel, command } });
|
|
829
|
+
}
|
|
830
|
+
function inspectClaudeChannelRegistration(existsSyncImpl, readFileSyncImpl) {
|
|
831
|
+
const configPath = path.join(homeDir(), '.claude.json');
|
|
832
|
+
let parsed = null;
|
|
833
|
+
if (existsSyncImpl(configPath)) {
|
|
834
|
+
try {
|
|
835
|
+
const value = JSON.parse(readFileSyncImpl(configPath, 'utf8'));
|
|
836
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
837
|
+
throw new Error('not an object');
|
|
838
|
+
parsed = value;
|
|
839
|
+
}
|
|
840
|
+
catch {
|
|
841
|
+
return createCheck('claude-channel', 'Claude Channel registration', 'warn', 'The canonical Claude user config could not be read as JSON, so the memesh-channel registration is malformed or unverifiable.', 'Repair the owner-controlled Claude config with `claude mcp remove memesh-channel` and re-run `memesh agent setup claude` to obtain a fresh registration command.');
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
const servers = parsed?.mcpServers;
|
|
845
|
+
const server = servers && typeof servers === 'object' && !Array.isArray(servers)
|
|
846
|
+
? servers['memesh-channel']
|
|
847
|
+
: undefined;
|
|
848
|
+
if (server === undefined) {
|
|
849
|
+
return createCheck('claude-channel', 'Claude Channel registration', 'warn', 'No user-scoped memesh-channel registration was found. Durable MCP/inbox messaging can still work, but live Claude Channel notification is inactive. The upstream research-preview channel remains opt-in.', 'If you want the opt-in channel, run `memesh agent setup claude` and then register the printed user-scoped MCP command.');
|
|
850
|
+
}
|
|
851
|
+
const record = server && typeof server === 'object' && !Array.isArray(server)
|
|
852
|
+
? server
|
|
853
|
+
: null;
|
|
854
|
+
const command = record?.command;
|
|
855
|
+
const rawArgs = record?.args;
|
|
856
|
+
const args = Array.isArray(rawArgs) ? rawArgs : null;
|
|
857
|
+
const configIndex = args?.indexOf('--config') ?? -1;
|
|
858
|
+
const target = args && configIndex >= 0 && typeof args[configIndex + 1] === 'string'
|
|
859
|
+
? args[configIndex + 1]
|
|
860
|
+
: null;
|
|
861
|
+
let targetConfigValid = false;
|
|
862
|
+
if (target) {
|
|
863
|
+
try {
|
|
864
|
+
const config = readHostConfigFile(target);
|
|
865
|
+
const required = ['router_socket', 'token_file', 'project', 'principal_id'];
|
|
866
|
+
targetConfigValid = config.server_name === 'memesh-channel'
|
|
867
|
+
&& required.every((key) => {
|
|
868
|
+
const value = config[key];
|
|
869
|
+
return typeof value === 'string'
|
|
870
|
+
&& value.length > 0
|
|
871
|
+
&& Buffer.byteLength(value) <= 4096;
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
catch {
|
|
875
|
+
targetConfigValid = false;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
const coherent = command === 'memesh-host-claude'
|
|
879
|
+
&& args !== null
|
|
880
|
+
&& args.length === 2
|
|
881
|
+
&& configIndex === 0
|
|
882
|
+
&& target !== null
|
|
883
|
+
&& targetConfigValid;
|
|
884
|
+
if (!coherent) {
|
|
885
|
+
const reason = command !== 'memesh-host-claude' || args === null || configIndex !== 0 || target === null
|
|
886
|
+
? 'the command or --config declaration is malformed'
|
|
887
|
+
: 'the declared owner config target is missing, insecure, malformed, or incomplete';
|
|
888
|
+
return createCheck('claude-channel', 'Claude Channel registration', 'warn', `The user-scoped memesh-channel registration is present but ${reason}. Live Claude Channel notification is not established.`, 'Remove and re-register the owner-controlled memesh-channel entry with `memesh agent setup claude`; keep its generated config file owner-private.');
|
|
889
|
+
}
|
|
890
|
+
return createInfo('claude-channel', 'Claude Channel registration', 'The user-scoped memesh-channel registration and owner-private config target are coherent (CONFIGURED). Development-channel admission and agent surfacing are not verified; durable MCP/inbox messaging remains a separate path.');
|
|
891
|
+
}
|
|
626
892
|
function inspectDashboardArtifact(packageRoot, existsSyncImpl) {
|
|
627
893
|
const dashboardPath = path.join(packageRoot, 'dashboard', 'dist', 'index.html');
|
|
628
894
|
if (!existsSyncImpl(dashboardPath)) {
|
|
@@ -742,7 +1008,7 @@ function verifySkillsManifest(packageRoot, existsSyncImpl, readFileSyncImpl, ins
|
|
|
742
1008
|
catch (err) {
|
|
743
1009
|
return createCheck('skills-manifest', 'Skills + hooks integrity', 'fail', `skills-manifest.json is unreadable (${err instanceof Error ? err.message : 'parse error'}).`, `Reinstall the package: ${reinstall} If the problem persists open an issue.`, { code: 'skills-manifest.unreadable', params: { detail: err instanceof Error ? err.message : 'parse error' } });
|
|
744
1010
|
}
|
|
745
|
-
const entries = manifest.entries
|
|
1011
|
+
const entries = Array.isArray(manifest.entries) ? manifest.entries : [];
|
|
746
1012
|
if (entries.length === 0) {
|
|
747
1013
|
return createCheck('skills-manifest', 'Skills + hooks integrity', 'fail', 'skills-manifest.json contains zero entries.', `Reinstall the package: ${reinstall}`, { code: 'skills-manifest.empty' });
|
|
748
1014
|
}
|
|
@@ -806,7 +1072,7 @@ function probeInstalledMessageCapability(packageRoot) {
|
|
|
806
1072
|
const tool = (await client.listTools()).tools.find((candidate) => candidate.name === 'message');
|
|
807
1073
|
assert.ok(tool, 'installed MCP did not advertise message');
|
|
808
1074
|
const actions = tool.inputSchema?.properties?.action?.enum;
|
|
809
|
-
assert.deepEqual(actions, ['send', 'poll', 'fetch', 'intake', 'ack', 'disposition', 'activation', 'receipts']);
|
|
1075
|
+
assert.deepEqual(actions, ['send', 'poll', 'discover', 'fetch', 'intake', 'ack', 'disposition', 'activation', 'receipts']);
|
|
810
1076
|
} finally { await client.close(); }
|
|
811
1077
|
`], {
|
|
812
1078
|
cwd: packageRoot,
|
|
@@ -825,11 +1091,11 @@ function probeInstalledMessageCapability(packageRoot) {
|
|
|
825
1091
|
}
|
|
826
1092
|
function inspectMessageCapability(packageRoot, enabled, probe) {
|
|
827
1093
|
if (!enabled) {
|
|
828
|
-
return createInfo('message-capability', 'Message adapter imports', 'Not verified (opt-in). Set MEMESH_DOCTOR_PROBE_MESSAGE_CAPABILITY=1 to start this installed MCP and verify its
|
|
1094
|
+
return createInfo('message-capability', 'Message adapter imports', 'Not verified (opt-in). Set MEMESH_DOCTOR_PROBE_MESSAGE_CAPABILITY=1 to start this installed MCP and verify its nine-action message schema plus bundled host-adapter imports. This does not check a live router socket or host registration.');
|
|
829
1095
|
}
|
|
830
1096
|
const result = probe(packageRoot);
|
|
831
1097
|
if (result.ok)
|
|
832
|
-
return createCheck('message-capability', 'Message adapter imports', 'pass', 'This installed MCP advertised the
|
|
1098
|
+
return createCheck('message-capability', 'Message adapter imports', 'pass', 'This installed MCP advertised the nine-action message schema and all bundled host adapters imported successfully. No live router socket, host registration, or host acceptance was verified.');
|
|
833
1099
|
return createCheck('message-capability', 'Message adapter imports', 'fail', `Installed message capability probe failed: ${result.message}.`, 'Reinstall or rebuild this package, then retry with MEMESH_DOCTOR_PROBE_MESSAGE_CAPABILITY=1.', { code: 'message-capability.probe-failed', params: { detail: result.message } });
|
|
834
1100
|
}
|
|
835
1101
|
async function defaultMessageRouterStatusProbe() {
|
|
@@ -938,7 +1204,7 @@ function summarizeOverallStatus(checks) {
|
|
|
938
1204
|
return 'PASS';
|
|
939
1205
|
}
|
|
940
1206
|
export async function runDoctor(options) {
|
|
941
|
-
const { packageRoot, packageVersion, probeHttp = false, probeCapabilities = false, embedTextImpl = embedText, probeProviderImpl = probeProvider, httpBaseUrl = 'http://127.0.0.1:3737', platform = process.platform, openDatabaseImpl = openDatabase, closeDatabaseImpl = closeDatabase, isDatabaseOpenImpl = isDatabaseOpen, detectCapabilitiesImpl = detectCapabilities, getConfigPathImpl = getConfigPath, getUpdateCheckImpl = getUpdateCheck, getCurrentInstallChannelImpl = getCurrentInstallChannel, installedPluginsPathImpl, getInstallChannelSupportImpl = getInstallChannelSupport, existsSyncImpl = fs.existsSync, readFileSyncImpl = fs.readFileSync, statSyncImpl = fs.statSync, fetchImpl = fetch, agentMessageStoragePolicy, nativeBindingProbeImpl, resolveShellMemeshImpl = defaultResolveShellMemesh, probeMessageCapability = process.env.MEMESH_DOCTOR_PROBE_MESSAGE_CAPABILITY === '1', messageCapabilityProbeImpl = probeInstalledMessageCapability, probeMessageRouterStatus = process.env.MEMESH_DOCTOR_PROBE_MESSAGE_ROUTER === '1', messageRouterStatusProbeImpl = defaultMessageRouterStatusProbe, } = options;
|
|
1207
|
+
const { packageRoot, packageVersion, probeHttp = false, probeCapabilities = false, embedTextImpl = embedText, probeProviderImpl = probeProvider, httpBaseUrl = 'http://127.0.0.1:3737', platform = process.platform, openDatabaseImpl = openDatabase, closeDatabaseImpl = closeDatabase, isDatabaseOpenImpl = isDatabaseOpen, detectCapabilitiesImpl = detectCapabilities, getConfigPathImpl = getConfigPath, getUpdateCheckImpl = getUpdateCheck, getCurrentInstallChannelImpl = getCurrentInstallChannel, installedPluginsPathImpl, marketplaceHeadShaImpl = defaultMarketplaceHeadSha, pluginCacheDiscoveryImpl, getInstallChannelSupportImpl = getInstallChannelSupport, existsSyncImpl = fs.existsSync, readFileSyncImpl = fs.readFileSync, statSyncImpl = fs.statSync, fetchImpl = fetch, agentMessageStoragePolicy, nativeBindingProbeImpl, resolveShellMemeshImpl = defaultResolveShellMemesh, probeMessageCapability = process.env.MEMESH_DOCTOR_PROBE_MESSAGE_CAPABILITY === '1', messageCapabilityProbeImpl = probeInstalledMessageCapability, probeMessageRouterStatus = process.env.MEMESH_DOCTOR_PROBE_MESSAGE_ROUTER === '1', messageRouterStatusProbeImpl = defaultMessageRouterStatusProbe, } = options;
|
|
942
1208
|
const wasDbOpenBeforeUs = isDatabaseOpenImpl();
|
|
943
1209
|
const safeCloseDatabaseImpl = wasDbOpenBeforeUs
|
|
944
1210
|
? () => undefined
|
|
@@ -1143,8 +1409,41 @@ export async function runDoctor(options) {
|
|
|
1143
1409
|
checks.push(inspectConfigFile(existsSyncImpl, readFileSyncImpl, getConfigPathImpl, detectCapabilitiesImpl().llm));
|
|
1144
1410
|
checks.push(inspectMcpConfig(packageRoot, existsSyncImpl, readFileSyncImpl));
|
|
1145
1411
|
checks.push(...inspectHooksConfig(packageRoot, platform, existsSyncImpl, readFileSyncImpl, statSyncImpl));
|
|
1146
|
-
const
|
|
1412
|
+
const pluginHost = detectPluginHost(packageRoot);
|
|
1413
|
+
let codexPluginCacheDetected = pluginHost === 'codex';
|
|
1414
|
+
let claudePluginCacheDetected = pluginHost === 'claude-code';
|
|
1415
|
+
const wiring = inspectHookWiring(existsSyncImpl, readFileSyncImpl, memeshDir(), install, installedPluginsPathImpl, pluginHost);
|
|
1416
|
+
const pluginCache = inspectPluginCacheCurrency(install, pluginHost, packageRoot, installedPluginsPathImpl, readFileSyncImpl, existsSyncImpl, marketplaceHeadShaImpl);
|
|
1417
|
+
if (pluginCache)
|
|
1418
|
+
checks.push(pluginCache);
|
|
1419
|
+
if (install === 'npm-global') {
|
|
1420
|
+
const discoveredCounts = new Map();
|
|
1421
|
+
const discoveredPluginCaches = pluginCacheDiscoveryImpl
|
|
1422
|
+
? pluginCacheDiscoveryImpl()
|
|
1423
|
+
: defaultPluginCacheDiscovery(readFileSyncImpl, existsSyncImpl);
|
|
1424
|
+
for (const discovered of discoveredPluginCaches) {
|
|
1425
|
+
if (discovered.host === 'codex')
|
|
1426
|
+
codexPluginCacheDetected = true;
|
|
1427
|
+
if (discovered.host === 'claude-code')
|
|
1428
|
+
claudePluginCacheDetected = true;
|
|
1429
|
+
const check = discovered.unverifiableReason
|
|
1430
|
+
? pluginCacheUnverifiable(discovered.host, discovered.unverifiableReason)
|
|
1431
|
+
: inspectPluginCacheCurrency('plugin-marketplace', discovered.host, discovered.packageRoot, discovered.installedPluginsPath, readFileSyncImpl, existsSyncImpl, marketplaceHeadShaImpl);
|
|
1432
|
+
if (check) {
|
|
1433
|
+
const hostName = discovered.host;
|
|
1434
|
+
const index = (discoveredCounts.get(discovered.host) ?? 0) + 1;
|
|
1435
|
+
discoveredCounts.set(discovered.host, index);
|
|
1436
|
+
checks.push({ ...check, id: `plugin-cache-${hostName}${index === 1 ? '' : `-${index}`}` });
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1147
1440
|
checks.push(wiring);
|
|
1441
|
+
if (claudePluginCacheDetected) {
|
|
1442
|
+
checks.push(inspectClaudeChannelRegistration(existsSyncImpl, readFileSyncImpl));
|
|
1443
|
+
}
|
|
1444
|
+
const codexSessionSetup = inspectCodexSessionSetup(codexPluginCacheDetected, existsSyncImpl);
|
|
1445
|
+
if (codexSessionSetup)
|
|
1446
|
+
checks.push(codexSessionSetup);
|
|
1148
1447
|
const captureWired = wiring.status === 'pass'
|
|
1149
1448
|
&& (wiring.params === undefined || wiring.params.captureWired === 1);
|
|
1150
1449
|
checks.push(inspectHookActivity(openDatabaseImpl, safeCloseDatabaseImpl, existsSyncImpl, statSyncImpl, captureWired));
|