@popmelt.com/core 0.21.1 → 0.22.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.
@@ -0,0 +1,44 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, join, parse, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ export function locatePopmeltCli(start = process.cwd()) {
6
+ try {
7
+ const runtimePath = join(dirname(fileURLToPath(import.meta.url)), '..', 'runtime.json');
8
+ const runtime = JSON.parse(readFileSync(runtimePath, 'utf8'));
9
+ if (typeof runtime.cliPath === 'string' && existsSync(runtime.cliPath)) {
10
+ return { command: process.execPath, prefix: [runtime.cliPath] };
11
+ }
12
+ } catch {
13
+ // Source checkouts do not have an installed-runtime pointer yet.
14
+ }
15
+ // Prefer the package that supplied this plugin when loaded with --plugin-dir.
16
+ const packaged = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'dist', 'cli.mjs');
17
+ if (existsSync(packaged)) return { command: process.execPath, prefix: [packaged] };
18
+ let current = resolve(start);
19
+ const root = parse(current).root;
20
+ while (true) {
21
+ const candidates = [
22
+ join(current, 'node_modules', '@popmelt.com', 'core', 'dist', 'cli.mjs'),
23
+ join(current, 'packages', 'popmelt', 'dist', 'cli.mjs'),
24
+ ];
25
+ for (const candidate of candidates) {
26
+ if (existsSync(candidate)) return { command: process.execPath, prefix: [candidate] };
27
+ }
28
+ const packagePath = join(current, 'package.json');
29
+ if (existsSync(packagePath)) {
30
+ try {
31
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf8'));
32
+ if (pkg.name === '@popmelt.com/core') {
33
+ const local = join(current, 'dist', 'cli.mjs');
34
+ if (existsSync(local)) return { command: process.execPath, prefix: [local] };
35
+ }
36
+ } catch {
37
+ // Ignore malformed package metadata and continue searching upward.
38
+ }
39
+ }
40
+ if (current === root) break;
41
+ current = dirname(current);
42
+ }
43
+ return { command: 'popmelt', prefix: [] };
44
+ }
@@ -0,0 +1,13 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { locatePopmeltCli } from './locate-cli.mjs';
3
+ import { pluginEnvironment } from './environment.mjs';
4
+
5
+ const cli = locatePopmeltCli();
6
+ const child = spawn(cli.command, [...cli.prefix, 'claude', 'mcp'], {
7
+ cwd: process.cwd(), env: pluginEnvironment(), stdio: 'inherit',
8
+ });
9
+ child.on('error', () => process.exit(1));
10
+ child.on('exit', (code, signal) => {
11
+ if (signal) process.kill(process.pid, signal);
12
+ else process.exit(code ?? 1);
13
+ });
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: popmelt-core
3
+ description: Use Popmelt Core when the user asks to inspect project memory, expand relevant product context, review a surfaced decision candidate, ground a surfaced Imprint explanation, or discuss the current Popmelt thread.
4
+ ---
5
+
6
+ # Popmelt Core
7
+
8
+ Popmelt pairs the current Claude Code conversation with a durable project thread. Ambient hooks already retrieve context and capture ordinary turns, so do not call tools merely to announce or duplicate that automatic work.
9
+
10
+ Use the tools deliberately:
11
+
12
+ - Pass the exact `tool session` ID supplied by the Ambient Popmelt Core context as `sessionId` on every tool call. This routes the call to the correct project even when the MCP process has a different working directory.
13
+
14
+ - Use `popmelt_orient_stores` only after the human explicitly chooses the writable primary store and any mounted read stores from an ambient orientation packet. Save that choice as the workspace default unless the human explicitly requests a session-only override. Store proximity, nesting, size, or recency never implies that choice.
15
+ - Use `popmelt_expand_context` when the automatically supplied packet is truncated or the user explicitly asks for broader history.
16
+ - Use `popmelt_inspect_thread` when the user asks to inspect the paired thread or its evidence.
17
+ - Use `popmelt_review_decision` only after the human explicitly resolves the exact surfaced candidate. Preserve the actions `accept`, `edit_and_accept`, `reject`, and `defer`. Never infer acceptance from implementation, praise, silence, or ambiguity.
18
+ - Use `popmelt_ground_imprint` only after the human explicitly answers a surfaced grounding question. Preserve the actions `yes`, `this_time`, and `no`.
19
+ - Use `popmelt_assess_turn` only when the current collaboration changed reusable shared understanding. Ordinary completion and tool evidence are captured automatically.
20
+
21
+ Accepted product decisions are authoritative within scope. Imprint explanations are provisional and advisory. The human remains the authority for both decision acceptance and Imprint grounding.
22
+
23
+ If Popmelt reports `already_managed_by_bridge`, stop calling Popmelt Core tools for that run; the toolbar bridge owns the turn lifecycle.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "popmelt-core",
3
- "version": "0.21.1",
3
+ "version": "0.22.1",
4
4
  "description": "Point out what you mean, talk through changes, and keep your AI on the same page.",
5
5
  "author": {
6
6
  "name": "Popmelt",