@moxt-ai/mobius 0.0.29 → 0.0.30
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/bots/bot-approve-command.d.ts +2 -0
- package/dist/bots/bot-approve-command.d.ts.map +1 -0
- package/dist/bots/bot-approve-command.js +78 -0
- package/dist/bots/bot-approve-command.js.map +1 -0
- package/dist/bots/local-bot-grant-store.d.ts +7 -0
- package/dist/bots/local-bot-grant-store.d.ts.map +1 -1
- package/dist/bots/local-bot-grant-store.js +89 -0
- package/dist/bots/local-bot-grant-store.js.map +1 -1
- package/dist/cli.js +951 -731
- package/dist/cli.js.map +4 -4
- package/dist/index.js +115 -12
- package/dist/index.js.map +3 -3
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +18 -14
- package/dist/run-daemon.js.map +1 -1
- package/dist/runtime.js +115 -12
- package/dist/runtime.js.map +3 -3
- package/package.json +1 -1
package/dist/runtime.js
CHANGED
|
@@ -27969,6 +27969,18 @@ import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
|
27969
27969
|
import { stat as stat7 } from "node:fs/promises";
|
|
27970
27970
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
27971
27971
|
var LOCAL_BOT_GRANT_LIFETIME_MILLISECONDS = 90 * 24 * 60 * 60 * 1e3;
|
|
27972
|
+
var identifier2 = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/);
|
|
27973
|
+
var savedApprovalSchema = external_exports.object({
|
|
27974
|
+
local_grant_id: identifier2,
|
|
27975
|
+
bot_id: identifier2,
|
|
27976
|
+
binding_id: identifier2,
|
|
27977
|
+
binding_revision: external_exports.number().int().positive(),
|
|
27978
|
+
agent_ref: identifier2,
|
|
27979
|
+
workspace_ref: external_exports.string().min(1).max(2048),
|
|
27980
|
+
revocation_epoch: external_exports.number().int().nonnegative(),
|
|
27981
|
+
agent_identity_digest: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
27982
|
+
workspace_identity_digest: external_exports.string().regex(/^[a-f0-9]{64}$/)
|
|
27983
|
+
}).readonly();
|
|
27972
27984
|
var LocalBotAuthorizationError = class extends Error {
|
|
27973
27985
|
code;
|
|
27974
27986
|
constructor(code, message, options = {}) {
|
|
@@ -28073,6 +28085,17 @@ function parseTargets(encoded) {
|
|
|
28073
28085
|
}
|
|
28074
28086
|
var LocalBotGrantStore = class {
|
|
28075
28087
|
#database;
|
|
28088
|
+
static containsBot = (path2, botId) => {
|
|
28089
|
+
const database = new DatabaseSync3(path2, { readOnly: true });
|
|
28090
|
+
try {
|
|
28091
|
+
if (database.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'local_bot_grants'").get() === void 0) {
|
|
28092
|
+
return false;
|
|
28093
|
+
}
|
|
28094
|
+
return database.prepare("SELECT local_grant_id FROM local_bot_grants WHERE bot_id = ? LIMIT 1").get(botId) !== void 0;
|
|
28095
|
+
} finally {
|
|
28096
|
+
database.close();
|
|
28097
|
+
}
|
|
28098
|
+
};
|
|
28076
28099
|
constructor(path2) {
|
|
28077
28100
|
this.#database = new DatabaseSync3(path2);
|
|
28078
28101
|
this.#database.exec(`
|
|
@@ -28106,6 +28129,78 @@ var LocalBotGrantStore = class {
|
|
|
28106
28129
|
) STRICT;
|
|
28107
28130
|
`);
|
|
28108
28131
|
}
|
|
28132
|
+
/** Only the local CLI may invoke this explicit approval transition. */
|
|
28133
|
+
reapprove = async (botId, catalog, directories, bindingAuthorityId, now, signal) => {
|
|
28134
|
+
signal.throwIfAborted();
|
|
28135
|
+
if (!identifier2.safeParse(botId).success) {
|
|
28136
|
+
throw new LocalBotAuthorizationError("invalid_request", "The Bot ID is invalid");
|
|
28137
|
+
}
|
|
28138
|
+
const row = this.#database.prepare("SELECT * FROM local_bot_grants WHERE bot_id = ? ORDER BY binding_revision DESC LIMIT 1").get(botId);
|
|
28139
|
+
if (row === void 0) {
|
|
28140
|
+
throw new LocalBotAuthorizationError("bot_not_found", "This machine has no saved approval for that Bot");
|
|
28141
|
+
}
|
|
28142
|
+
const parsed = savedApprovalSchema.safeParse(row);
|
|
28143
|
+
if (!parsed.success) {
|
|
28144
|
+
throw new LocalBotAuthorizationError("local_grant_invalid", "The saved Bot approval is invalid", {
|
|
28145
|
+
cause: parsed.error
|
|
28146
|
+
});
|
|
28147
|
+
}
|
|
28148
|
+
const saved = parsed.data;
|
|
28149
|
+
const agent = catalog.find(saved.agent_ref);
|
|
28150
|
+
if (!agent.capabilities.embeddedContextPrompt) {
|
|
28151
|
+
throw new LocalBotAuthorizationError("binding_incompatible", "The local Agent cannot apply Bot context");
|
|
28152
|
+
}
|
|
28153
|
+
const [adapterUnchanged, agentUnchanged] = await Promise.all([
|
|
28154
|
+
revalidateExecutable(agent.adapterIdentity),
|
|
28155
|
+
revalidateExecutable(agent.agentIdentity)
|
|
28156
|
+
]);
|
|
28157
|
+
signal.throwIfAborted();
|
|
28158
|
+
if (!adapterUnchanged || !agentUnchanged) {
|
|
28159
|
+
throw new LocalBotAuthorizationError(
|
|
28160
|
+
"binding_incompatible",
|
|
28161
|
+
"The local Agent executable changed before approval"
|
|
28162
|
+
);
|
|
28163
|
+
}
|
|
28164
|
+
const workspacePath = await directories.resolve(bindingAuthorityId, saved.workspace_ref, signal);
|
|
28165
|
+
const workspaceIdentityDigest = await workspaceDigest(workspacePath);
|
|
28166
|
+
signal.throwIfAborted();
|
|
28167
|
+
this.#database.exec("BEGIN IMMEDIATE");
|
|
28168
|
+
try {
|
|
28169
|
+
const result = this.#database.prepare(`UPDATE local_bot_grants
|
|
28170
|
+
SET agent_identity_digest = ?, workspace_identity_digest = ?, workspace_path = ?,
|
|
28171
|
+
revoked_at = NULL, expires_at = ?, revocation_epoch = revocation_epoch + 1
|
|
28172
|
+
WHERE local_grant_id = ? AND revocation_epoch = ?
|
|
28173
|
+
AND agent_identity_digest = ? AND workspace_identity_digest = ?
|
|
28174
|
+
AND binding_revision = (SELECT MAX(binding_revision) FROM local_bot_grants WHERE bot_id = ?)`).run(
|
|
28175
|
+
agentDigest(agent),
|
|
28176
|
+
workspaceIdentityDigest,
|
|
28177
|
+
workspacePath,
|
|
28178
|
+
now + LOCAL_BOT_GRANT_LIFETIME_MILLISECONDS,
|
|
28179
|
+
saved.local_grant_id,
|
|
28180
|
+
saved.revocation_epoch,
|
|
28181
|
+
saved.agent_identity_digest,
|
|
28182
|
+
saved.workspace_identity_digest,
|
|
28183
|
+
botId
|
|
28184
|
+
);
|
|
28185
|
+
if (result.changes !== 1) {
|
|
28186
|
+
throw new LocalBotAuthorizationError(
|
|
28187
|
+
"binding_not_approved",
|
|
28188
|
+
"The Bot binding changed during approval; run the command again"
|
|
28189
|
+
);
|
|
28190
|
+
}
|
|
28191
|
+
this.#database.prepare(`INSERT INTO audit_events (recorded_at, event, command_id, session_id, details_json)
|
|
28192
|
+
VALUES (?, 'bot_binding_locally_reapproved', ?, '', ?)`).run(
|
|
28193
|
+
new Date(now).toISOString(),
|
|
28194
|
+
saved.binding_id,
|
|
28195
|
+
JSON.stringify({ botId, bindingId: saved.binding_id, agentRef: saved.agent_ref })
|
|
28196
|
+
);
|
|
28197
|
+
this.#database.exec("COMMIT");
|
|
28198
|
+
} catch (cause) {
|
|
28199
|
+
this.#database.exec("ROLLBACK");
|
|
28200
|
+
throw cause;
|
|
28201
|
+
}
|
|
28202
|
+
return { bindingId: saved.binding_id, workspacePath, agentRef: saved.agent_ref };
|
|
28203
|
+
};
|
|
28109
28204
|
approve = async (request, catalog, directories, bindingAuthorityId, now, signal) => {
|
|
28110
28205
|
signal.throwIfAborted();
|
|
28111
28206
|
const existing = this.#database.prepare(
|
|
@@ -31149,7 +31244,7 @@ async function executeSessionConfigure(publisher, socket, command, config2, dire
|
|
|
31149
31244
|
reportOperationFailure(socket, command.requestId, command.sessionId, error61);
|
|
31150
31245
|
}
|
|
31151
31246
|
}
|
|
31152
|
-
async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, timer, signal) {
|
|
31247
|
+
async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, activateAttempt, timer, signal) {
|
|
31153
31248
|
const activities = new CoalescingDaemonActivityPublisher(timer, (activity) => {
|
|
31154
31249
|
publisher.recordAttempt(command.sessionId, encodeDaemonActivity(command, activity), attemptId);
|
|
31155
31250
|
});
|
|
@@ -31178,6 +31273,7 @@ async function executePrompt(outbox, publisher, command, config2, directories, a
|
|
|
31178
31273
|
}),
|
|
31179
31274
|
attemptId
|
|
31180
31275
|
);
|
|
31276
|
+
activateAttempt();
|
|
31181
31277
|
const attachments = await resolvePromptArtifacts(config2, command, signal);
|
|
31182
31278
|
let stopReason;
|
|
31183
31279
|
if (command.disposition === SessionPromptDisposition.Steer) {
|
|
@@ -31289,7 +31385,7 @@ function botExecutionAgent(agent, contextHandle, socketPath) {
|
|
|
31289
31385
|
agent.capabilities
|
|
31290
31386
|
);
|
|
31291
31387
|
}
|
|
31292
|
-
async function executeBotPrompt(outbox, publisher, command, config2, directories, audit, sessions, grants, contexts, applicator, ipc, attemptId, timer, signal) {
|
|
31388
|
+
async function executeBotPrompt(outbox, publisher, command, config2, directories, audit, sessions, grants, contexts, applicator, ipc, attemptId, activateAttempt, timer, signal) {
|
|
31293
31389
|
const activities = new CoalescingDaemonActivityPublisher(timer, (activity) => {
|
|
31294
31390
|
publisher.recordAttempt(command.sessionId, encodeDaemonActivity(command, activity), attemptId);
|
|
31295
31391
|
});
|
|
@@ -31370,6 +31466,7 @@ async function executeBotPrompt(outbox, publisher, command, config2, directories
|
|
|
31370
31466
|
}),
|
|
31371
31467
|
attemptId
|
|
31372
31468
|
);
|
|
31469
|
+
activateAttempt();
|
|
31373
31470
|
const result = await sessions.runPrompt({
|
|
31374
31471
|
additionalDirectories: resolved.additionalDirectories,
|
|
31375
31472
|
agent,
|
|
@@ -31563,11 +31660,13 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31563
31660
|
}
|
|
31564
31661
|
const turn = new ActiveDaemonTurn(command, receipt.attemptId);
|
|
31565
31662
|
activeTurns.set(command.commandId, turn);
|
|
31566
|
-
|
|
31567
|
-
|
|
31568
|
-
|
|
31663
|
+
const activateAttempt = () => {
|
|
31664
|
+
if (trackActiveAttempt) {
|
|
31665
|
+
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
31666
|
+
}
|
|
31667
|
+
};
|
|
31569
31668
|
try {
|
|
31570
|
-
await execute(receipt.attemptId, turn.signal);
|
|
31669
|
+
await execute(receipt.attemptId, activateAttempt, turn.signal);
|
|
31571
31670
|
} finally {
|
|
31572
31671
|
activeTurns.delete(command.commandId);
|
|
31573
31672
|
if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
|
|
@@ -31652,7 +31751,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31652
31751
|
delivery,
|
|
31653
31752
|
command,
|
|
31654
31753
|
true,
|
|
31655
|
-
(attemptId, executionSignal) => executeBotPrompt(
|
|
31754
|
+
(attemptId, activateAttempt, executionSignal) => executeBotPrompt(
|
|
31656
31755
|
outbox,
|
|
31657
31756
|
publisher,
|
|
31658
31757
|
command,
|
|
@@ -31665,6 +31764,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31665
31764
|
applicator,
|
|
31666
31765
|
ipc,
|
|
31667
31766
|
attemptId,
|
|
31767
|
+
activateAttempt,
|
|
31668
31768
|
timer,
|
|
31669
31769
|
executionSignal
|
|
31670
31770
|
)
|
|
@@ -31677,7 +31777,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31677
31777
|
delivery,
|
|
31678
31778
|
command,
|
|
31679
31779
|
command.disposition !== SessionPromptDisposition.Steer,
|
|
31680
|
-
(attemptId, executionSignal) => executePrompt(
|
|
31780
|
+
(attemptId, activateAttempt, executionSignal) => executePrompt(
|
|
31681
31781
|
outbox,
|
|
31682
31782
|
publisher,
|
|
31683
31783
|
command,
|
|
@@ -31686,6 +31786,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31686
31786
|
audit,
|
|
31687
31787
|
sessions,
|
|
31688
31788
|
attemptId,
|
|
31789
|
+
activateAttempt,
|
|
31689
31790
|
timer,
|
|
31690
31791
|
executionSignal
|
|
31691
31792
|
)
|
|
@@ -32187,7 +32288,6 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32187
32288
|
}
|
|
32188
32289
|
const turn2 = new ActiveDaemonTurn(command2, receipt2.attemptId);
|
|
32189
32290
|
activeTurns.set(command2.commandId, turn2);
|
|
32190
|
-
activeAttemptIds.set(command2.sessionId, receipt2.attemptId);
|
|
32191
32291
|
void executeBotPrompt(
|
|
32192
32292
|
outbox,
|
|
32193
32293
|
publisher,
|
|
@@ -32201,6 +32301,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32201
32301
|
applicator,
|
|
32202
32302
|
ipc,
|
|
32203
32303
|
receipt2.attemptId,
|
|
32304
|
+
() => activeAttemptIds.set(command2.sessionId, receipt2.attemptId),
|
|
32204
32305
|
timer,
|
|
32205
32306
|
turn2.signal
|
|
32206
32307
|
).catch((error61) => {
|
|
@@ -32227,9 +32328,6 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32227
32328
|
}
|
|
32228
32329
|
const turn = new ActiveDaemonTurn(command, receipt.attemptId);
|
|
32229
32330
|
activeTurns.set(command.commandId, turn);
|
|
32230
|
-
if (command.disposition !== SessionPromptDisposition.Steer) {
|
|
32231
|
-
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
32232
|
-
}
|
|
32233
32331
|
void executePrompt(
|
|
32234
32332
|
outbox,
|
|
32235
32333
|
publisher,
|
|
@@ -32239,6 +32337,11 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32239
32337
|
audit,
|
|
32240
32338
|
sessions,
|
|
32241
32339
|
receipt.attemptId,
|
|
32340
|
+
() => {
|
|
32341
|
+
if (command.disposition !== SessionPromptDisposition.Steer) {
|
|
32342
|
+
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
32343
|
+
}
|
|
32344
|
+
},
|
|
32242
32345
|
timer,
|
|
32243
32346
|
turn.signal
|
|
32244
32347
|
).catch((error61) => {
|