@adapt-toolkit/a2adapt 0.7.0 → 0.8.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.
- package/dist/hooks/runner.js +41 -1
- package/dist/index.js +22 -3
- package/package.json +1 -1
package/dist/hooks/runner.js
CHANGED
|
@@ -100,9 +100,26 @@ function identityExists(name) {
|
|
|
100
100
|
return false;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
function anyIdentityBound() {
|
|
104
|
+
let snap;
|
|
105
|
+
try {
|
|
106
|
+
snap = JSON.parse(fs.readFileSync(join(STATE_DIR, "bindings.json"), "utf8"));
|
|
107
|
+
} catch {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
if (!Array.isArray(snap.bound) || snap.bound.length === 0) return false;
|
|
111
|
+
const pid = Number(snap.pid);
|
|
112
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
113
|
+
try {
|
|
114
|
+
process.kill(pid, 0);
|
|
115
|
+
return true;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
return err.code === "EPERM";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
103
120
|
function renderIdentityDirective(name, exists) {
|
|
104
121
|
const bind = exists ? `call \`choose_identity({ name: "${name}" })\` to bind it to this session` : `it does not exist yet \u2014 call \`create_identity({ name: "${name}" })\` to create and bind it`;
|
|
105
|
-
return `a2adapt \u2014 this workspace is pinned to identity "${name}" (via ${IDENTITY_FILE}). Before other a2adapt work, ${bind}. Then arm a Monitor on the wake source \`a2adapt-mcp watch ${name}\` so new mail wakes you. Do this once, up front
|
|
122
|
+
return `a2adapt \u2014 this workspace is pinned to identity "${name}" (via ${IDENTITY_FILE}). Before other a2adapt work, ${bind}. Then arm a Monitor on the wake source \`a2adapt-mcp watch ${name}\` so new mail wakes you. Do this once, up front. The pin is the workspace default: if the user explicitly asks to use a different identity, bind that instead \u2014 the user's choice always wins. If choose_identity reports the identity is held by another session, do NOT retry with force \u2014 tell the user it is bound elsewhere and ask whether to forcibly rebind it to this session; only pass force=true after they confirm.`;
|
|
106
123
|
}
|
|
107
124
|
function sessionStart() {
|
|
108
125
|
const raw = readStdin();
|
|
@@ -131,6 +148,26 @@ function sessionStart() {
|
|
|
131
148
|
}
|
|
132
149
|
});
|
|
133
150
|
}
|
|
151
|
+
function userPromptSubmit() {
|
|
152
|
+
const raw = readStdin();
|
|
153
|
+
let cwd = process.cwd();
|
|
154
|
+
if (raw) {
|
|
155
|
+
try {
|
|
156
|
+
const payload = JSON.parse(raw);
|
|
157
|
+
if (typeof payload.cwd === "string" && payload.cwd) cwd = payload.cwd;
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const pinned = findPinnedIdentity(cwd);
|
|
162
|
+
if (!pinned || anyIdentityBound()) return noop();
|
|
163
|
+
emit({
|
|
164
|
+
continue: true,
|
|
165
|
+
hookSpecificOutput: {
|
|
166
|
+
hookEventName: "UserPromptSubmit",
|
|
167
|
+
additionalContext: renderIdentityDirective(pinned, identityExists(pinned))
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
134
171
|
function main() {
|
|
135
172
|
const kind = process.argv[2] ?? "";
|
|
136
173
|
try {
|
|
@@ -138,6 +175,9 @@ function main() {
|
|
|
138
175
|
case "session-start":
|
|
139
176
|
sessionStart();
|
|
140
177
|
return;
|
|
178
|
+
case "user-prompt-submit":
|
|
179
|
+
userPromptSubmit();
|
|
180
|
+
return;
|
|
141
181
|
default:
|
|
142
182
|
noop();
|
|
143
183
|
return;
|
package/dist/index.js
CHANGED
|
@@ -22489,7 +22489,7 @@ function loadConfig() {
|
|
|
22489
22489
|
}
|
|
22490
22490
|
|
|
22491
22491
|
// src/index.ts
|
|
22492
|
-
var VERSION = true ? "0.
|
|
22492
|
+
var VERSION = true ? "0.8.0" : "0.0.0-dev";
|
|
22493
22493
|
var CONFIG = loadConfig();
|
|
22494
22494
|
var STATE_DIR = CONFIG.stateDir;
|
|
22495
22495
|
var BROKER_URL = CONFIG.brokerUrl;
|
|
@@ -22531,6 +22531,17 @@ var identities = /* @__PURE__ */ new Map();
|
|
|
22531
22531
|
var sessionBinding = /* @__PURE__ */ new Map();
|
|
22532
22532
|
var bindingOwner = /* @__PURE__ */ new Map();
|
|
22533
22533
|
var evictedSessions = /* @__PURE__ */ new Set();
|
|
22534
|
+
var bindingsSnapshotPath = () => join2(STATE_DIR, "bindings.json");
|
|
22535
|
+
function persistBindings() {
|
|
22536
|
+
try {
|
|
22537
|
+
fs2.mkdirSync(STATE_DIR, { recursive: true });
|
|
22538
|
+
const tmp = `${bindingsSnapshotPath()}.tmp`;
|
|
22539
|
+
fs2.writeFileSync(tmp, JSON.stringify({ pid: process.pid, bound: [...bindingOwner.keys()] }));
|
|
22540
|
+
fs2.renameSync(tmp, bindingsSnapshotPath());
|
|
22541
|
+
} catch (err) {
|
|
22542
|
+
log("failed to persist bindings snapshot:", String(err));
|
|
22543
|
+
}
|
|
22544
|
+
}
|
|
22534
22545
|
var identityDir = (name) => join2(STATE_DIR, name);
|
|
22535
22546
|
var seedPath = (dir) => join2(dir, "identity.seed");
|
|
22536
22547
|
var dataPath = (dir) => join2(dir, "state_data.bin");
|
|
@@ -22771,6 +22782,7 @@ async function bootWrapper() {
|
|
|
22771
22782
|
}
|
|
22772
22783
|
}
|
|
22773
22784
|
}
|
|
22785
|
+
persistBindings();
|
|
22774
22786
|
}
|
|
22775
22787
|
function resolveBound(sessionId) {
|
|
22776
22788
|
if (evictedSessions.has(sessionId)) {
|
|
@@ -22784,6 +22796,7 @@ function resolveBound(sessionId) {
|
|
|
22784
22796
|
if (!id) {
|
|
22785
22797
|
sessionBinding.delete(sessionId);
|
|
22786
22798
|
bindingOwner.delete(name);
|
|
22799
|
+
persistBindings();
|
|
22787
22800
|
return { error: `The bound identity "${name}" no longer exists. Choose another with choose_identity.` };
|
|
22788
22801
|
}
|
|
22789
22802
|
return { id };
|
|
@@ -22796,6 +22809,7 @@ function bindSession(sessionId, name) {
|
|
|
22796
22809
|
sessionBinding.set(sessionId, name);
|
|
22797
22810
|
bindingOwner.set(name, sessionId);
|
|
22798
22811
|
evictedSessions.delete(sessionId);
|
|
22812
|
+
persistBindings();
|
|
22799
22813
|
}
|
|
22800
22814
|
function renderContacts(v) {
|
|
22801
22815
|
const out = [];
|
|
@@ -22879,7 +22893,7 @@ function createMcpServer(getSessionId) {
|
|
|
22879
22893
|
);
|
|
22880
22894
|
server.tool(
|
|
22881
22895
|
"choose_identity",
|
|
22882
|
-
"Bind an existing identity to this session so the messaging tools act as it. Binding is exclusive: if the identity is already in use by another session, this is declined unless force=true, which evicts the other session.",
|
|
22896
|
+
"Bind an existing identity to this session so the messaging tools act as it. Binding is exclusive: if the identity is already in use by another session, this is declined unless force=true, which evicts the other session. Never pass force=true on your own initiative \u2014 ask the user and get an explicit confirmation first.",
|
|
22883
22897
|
{
|
|
22884
22898
|
name: external_exports.string().min(1).describe("Name of the identity to bind."),
|
|
22885
22899
|
force: external_exports.boolean().default(false).describe("Evict another session that holds this identity.")
|
|
@@ -22892,7 +22906,10 @@ function createMcpServer(getSessionId) {
|
|
|
22892
22906
|
const holder = bindingOwner.get(name);
|
|
22893
22907
|
if (holder && holder !== sid) {
|
|
22894
22908
|
if (!force) {
|
|
22895
|
-
return textResult(
|
|
22909
|
+
return textResult(
|
|
22910
|
+
`choose_identity declined: "${name}" is currently bound to another session. Do not retry with force=true on your own \u2014 tell the user the identity is in use elsewhere and ask whether to forcibly rebind it here; only retry with force=true after they explicitly confirm.`,
|
|
22911
|
+
true
|
|
22912
|
+
);
|
|
22896
22913
|
}
|
|
22897
22914
|
evictedSessions.add(holder);
|
|
22898
22915
|
sessionBinding.delete(holder);
|
|
@@ -22947,6 +22964,7 @@ ${lines.join("\n")}`);
|
|
|
22947
22964
|
if (holder) {
|
|
22948
22965
|
bindingOwner.delete(name);
|
|
22949
22966
|
sessionBinding.delete(holder);
|
|
22967
|
+
persistBindings();
|
|
22950
22968
|
}
|
|
22951
22969
|
try {
|
|
22952
22970
|
fs2.rmSync(id.dir, { recursive: true, force: true });
|
|
@@ -23234,6 +23252,7 @@ async function main() {
|
|
|
23234
23252
|
if (name && bindingOwner.get(name) === sid) bindingOwner.delete(name);
|
|
23235
23253
|
sessionBinding.delete(sid);
|
|
23236
23254
|
evictedSessions.delete(sid);
|
|
23255
|
+
persistBindings();
|
|
23237
23256
|
log(`session ${sid.slice(0, 8)}\u2026 closed`);
|
|
23238
23257
|
}
|
|
23239
23258
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adapt-toolkit/a2adapt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "MCP server daemon for a2adapt — one native ADAPT wrapper hosting N self-sovereign identities, exposing secure agent-to-agent messaging tools over HTTP (Streamable HTTP). Run `a2adapt-mcp start`.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|