@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/index.js
CHANGED
|
@@ -24951,6 +24951,18 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
24951
24951
|
import { stat as stat3 } from "node:fs/promises";
|
|
24952
24952
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
24953
24953
|
var LOCAL_BOT_GRANT_LIFETIME_MILLISECONDS = 90 * 24 * 60 * 60 * 1e3;
|
|
24954
|
+
var identifier2 = external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/);
|
|
24955
|
+
var savedApprovalSchema = external_exports.object({
|
|
24956
|
+
local_grant_id: identifier2,
|
|
24957
|
+
bot_id: identifier2,
|
|
24958
|
+
binding_id: identifier2,
|
|
24959
|
+
binding_revision: external_exports.number().int().positive(),
|
|
24960
|
+
agent_ref: identifier2,
|
|
24961
|
+
workspace_ref: external_exports.string().min(1).max(2048),
|
|
24962
|
+
revocation_epoch: external_exports.number().int().nonnegative(),
|
|
24963
|
+
agent_identity_digest: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
24964
|
+
workspace_identity_digest: external_exports.string().regex(/^[a-f0-9]{64}$/)
|
|
24965
|
+
}).readonly();
|
|
24954
24966
|
var LocalBotAuthorizationError = class extends Error {
|
|
24955
24967
|
code;
|
|
24956
24968
|
constructor(code, message, options = {}) {
|
|
@@ -25055,6 +25067,17 @@ function parseTargets(encoded) {
|
|
|
25055
25067
|
}
|
|
25056
25068
|
var LocalBotGrantStore = class {
|
|
25057
25069
|
#database;
|
|
25070
|
+
static containsBot = (path2, botId) => {
|
|
25071
|
+
const database = new DatabaseSync3(path2, { readOnly: true });
|
|
25072
|
+
try {
|
|
25073
|
+
if (database.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'local_bot_grants'").get() === void 0) {
|
|
25074
|
+
return false;
|
|
25075
|
+
}
|
|
25076
|
+
return database.prepare("SELECT local_grant_id FROM local_bot_grants WHERE bot_id = ? LIMIT 1").get(botId) !== void 0;
|
|
25077
|
+
} finally {
|
|
25078
|
+
database.close();
|
|
25079
|
+
}
|
|
25080
|
+
};
|
|
25058
25081
|
constructor(path2) {
|
|
25059
25082
|
this.#database = new DatabaseSync3(path2);
|
|
25060
25083
|
this.#database.exec(`
|
|
@@ -25088,6 +25111,78 @@ var LocalBotGrantStore = class {
|
|
|
25088
25111
|
) STRICT;
|
|
25089
25112
|
`);
|
|
25090
25113
|
}
|
|
25114
|
+
/** Only the local CLI may invoke this explicit approval transition. */
|
|
25115
|
+
reapprove = async (botId, catalog, directories, bindingAuthorityId, now, signal) => {
|
|
25116
|
+
signal.throwIfAborted();
|
|
25117
|
+
if (!identifier2.safeParse(botId).success) {
|
|
25118
|
+
throw new LocalBotAuthorizationError("invalid_request", "The Bot ID is invalid");
|
|
25119
|
+
}
|
|
25120
|
+
const row = this.#database.prepare("SELECT * FROM local_bot_grants WHERE bot_id = ? ORDER BY binding_revision DESC LIMIT 1").get(botId);
|
|
25121
|
+
if (row === void 0) {
|
|
25122
|
+
throw new LocalBotAuthorizationError("bot_not_found", "This machine has no saved approval for that Bot");
|
|
25123
|
+
}
|
|
25124
|
+
const parsed = savedApprovalSchema.safeParse(row);
|
|
25125
|
+
if (!parsed.success) {
|
|
25126
|
+
throw new LocalBotAuthorizationError("local_grant_invalid", "The saved Bot approval is invalid", {
|
|
25127
|
+
cause: parsed.error
|
|
25128
|
+
});
|
|
25129
|
+
}
|
|
25130
|
+
const saved = parsed.data;
|
|
25131
|
+
const agent = catalog.find(saved.agent_ref);
|
|
25132
|
+
if (!agent.capabilities.embeddedContextPrompt) {
|
|
25133
|
+
throw new LocalBotAuthorizationError("binding_incompatible", "The local Agent cannot apply Bot context");
|
|
25134
|
+
}
|
|
25135
|
+
const [adapterUnchanged, agentUnchanged] = await Promise.all([
|
|
25136
|
+
revalidateExecutable(agent.adapterIdentity),
|
|
25137
|
+
revalidateExecutable(agent.agentIdentity)
|
|
25138
|
+
]);
|
|
25139
|
+
signal.throwIfAborted();
|
|
25140
|
+
if (!adapterUnchanged || !agentUnchanged) {
|
|
25141
|
+
throw new LocalBotAuthorizationError(
|
|
25142
|
+
"binding_incompatible",
|
|
25143
|
+
"The local Agent executable changed before approval"
|
|
25144
|
+
);
|
|
25145
|
+
}
|
|
25146
|
+
const workspacePath = await directories.resolve(bindingAuthorityId, saved.workspace_ref, signal);
|
|
25147
|
+
const workspaceIdentityDigest = await workspaceDigest(workspacePath);
|
|
25148
|
+
signal.throwIfAborted();
|
|
25149
|
+
this.#database.exec("BEGIN IMMEDIATE");
|
|
25150
|
+
try {
|
|
25151
|
+
const result = this.#database.prepare(`UPDATE local_bot_grants
|
|
25152
|
+
SET agent_identity_digest = ?, workspace_identity_digest = ?, workspace_path = ?,
|
|
25153
|
+
revoked_at = NULL, expires_at = ?, revocation_epoch = revocation_epoch + 1
|
|
25154
|
+
WHERE local_grant_id = ? AND revocation_epoch = ?
|
|
25155
|
+
AND agent_identity_digest = ? AND workspace_identity_digest = ?
|
|
25156
|
+
AND binding_revision = (SELECT MAX(binding_revision) FROM local_bot_grants WHERE bot_id = ?)`).run(
|
|
25157
|
+
agentDigest(agent),
|
|
25158
|
+
workspaceIdentityDigest,
|
|
25159
|
+
workspacePath,
|
|
25160
|
+
now + LOCAL_BOT_GRANT_LIFETIME_MILLISECONDS,
|
|
25161
|
+
saved.local_grant_id,
|
|
25162
|
+
saved.revocation_epoch,
|
|
25163
|
+
saved.agent_identity_digest,
|
|
25164
|
+
saved.workspace_identity_digest,
|
|
25165
|
+
botId
|
|
25166
|
+
);
|
|
25167
|
+
if (result.changes !== 1) {
|
|
25168
|
+
throw new LocalBotAuthorizationError(
|
|
25169
|
+
"binding_not_approved",
|
|
25170
|
+
"The Bot binding changed during approval; run the command again"
|
|
25171
|
+
);
|
|
25172
|
+
}
|
|
25173
|
+
this.#database.prepare(`INSERT INTO audit_events (recorded_at, event, command_id, session_id, details_json)
|
|
25174
|
+
VALUES (?, 'bot_binding_locally_reapproved', ?, '', ?)`).run(
|
|
25175
|
+
new Date(now).toISOString(),
|
|
25176
|
+
saved.binding_id,
|
|
25177
|
+
JSON.stringify({ botId, bindingId: saved.binding_id, agentRef: saved.agent_ref })
|
|
25178
|
+
);
|
|
25179
|
+
this.#database.exec("COMMIT");
|
|
25180
|
+
} catch (cause) {
|
|
25181
|
+
this.#database.exec("ROLLBACK");
|
|
25182
|
+
throw cause;
|
|
25183
|
+
}
|
|
25184
|
+
return { bindingId: saved.binding_id, workspacePath, agentRef: saved.agent_ref };
|
|
25185
|
+
};
|
|
25091
25186
|
approve = async (request, catalog, directories, bindingAuthorityId, now, signal) => {
|
|
25092
25187
|
signal.throwIfAborted();
|
|
25093
25188
|
const existing = this.#database.prepare(
|
|
@@ -31712,7 +31807,7 @@ async function executeSessionConfigure(publisher, socket, command, config2, dire
|
|
|
31712
31807
|
reportOperationFailure(socket, command.requestId, command.sessionId, error61);
|
|
31713
31808
|
}
|
|
31714
31809
|
}
|
|
31715
|
-
async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, timer, signal) {
|
|
31810
|
+
async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, activateAttempt, timer, signal) {
|
|
31716
31811
|
const activities = new CoalescingDaemonActivityPublisher(timer, (activity) => {
|
|
31717
31812
|
publisher.recordAttempt(command.sessionId, encodeDaemonActivity(command, activity), attemptId);
|
|
31718
31813
|
});
|
|
@@ -31741,6 +31836,7 @@ async function executePrompt(outbox, publisher, command, config2, directories, a
|
|
|
31741
31836
|
}),
|
|
31742
31837
|
attemptId
|
|
31743
31838
|
);
|
|
31839
|
+
activateAttempt();
|
|
31744
31840
|
const attachments = await resolvePromptArtifacts(config2, command, signal);
|
|
31745
31841
|
let stopReason;
|
|
31746
31842
|
if (command.disposition === SessionPromptDisposition.Steer) {
|
|
@@ -31852,7 +31948,7 @@ function botExecutionAgent(agent, contextHandle, socketPath) {
|
|
|
31852
31948
|
agent.capabilities
|
|
31853
31949
|
);
|
|
31854
31950
|
}
|
|
31855
|
-
async function executeBotPrompt(outbox, publisher, command, config2, directories, audit, sessions, grants, contexts, applicator, ipc, attemptId, timer, signal) {
|
|
31951
|
+
async function executeBotPrompt(outbox, publisher, command, config2, directories, audit, sessions, grants, contexts, applicator, ipc, attemptId, activateAttempt, timer, signal) {
|
|
31856
31952
|
const activities = new CoalescingDaemonActivityPublisher(timer, (activity) => {
|
|
31857
31953
|
publisher.recordAttempt(command.sessionId, encodeDaemonActivity(command, activity), attemptId);
|
|
31858
31954
|
});
|
|
@@ -31933,6 +32029,7 @@ async function executeBotPrompt(outbox, publisher, command, config2, directories
|
|
|
31933
32029
|
}),
|
|
31934
32030
|
attemptId
|
|
31935
32031
|
);
|
|
32032
|
+
activateAttempt();
|
|
31936
32033
|
const result = await sessions.runPrompt({
|
|
31937
32034
|
additionalDirectories: resolved.additionalDirectories,
|
|
31938
32035
|
agent,
|
|
@@ -32126,11 +32223,13 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32126
32223
|
}
|
|
32127
32224
|
const turn = new ActiveDaemonTurn(command, receipt.attemptId);
|
|
32128
32225
|
activeTurns.set(command.commandId, turn);
|
|
32129
|
-
|
|
32130
|
-
|
|
32131
|
-
|
|
32226
|
+
const activateAttempt = () => {
|
|
32227
|
+
if (trackActiveAttempt) {
|
|
32228
|
+
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
32229
|
+
}
|
|
32230
|
+
};
|
|
32132
32231
|
try {
|
|
32133
|
-
await execute(receipt.attemptId, turn.signal);
|
|
32232
|
+
await execute(receipt.attemptId, activateAttempt, turn.signal);
|
|
32134
32233
|
} finally {
|
|
32135
32234
|
activeTurns.delete(command.commandId);
|
|
32136
32235
|
if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
|
|
@@ -32215,7 +32314,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32215
32314
|
delivery,
|
|
32216
32315
|
command,
|
|
32217
32316
|
true,
|
|
32218
|
-
(attemptId, executionSignal) => executeBotPrompt(
|
|
32317
|
+
(attemptId, activateAttempt, executionSignal) => executeBotPrompt(
|
|
32219
32318
|
outbox,
|
|
32220
32319
|
publisher,
|
|
32221
32320
|
command,
|
|
@@ -32228,6 +32327,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32228
32327
|
applicator,
|
|
32229
32328
|
ipc,
|
|
32230
32329
|
attemptId,
|
|
32330
|
+
activateAttempt,
|
|
32231
32331
|
timer,
|
|
32232
32332
|
executionSignal
|
|
32233
32333
|
)
|
|
@@ -32240,7 +32340,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32240
32340
|
delivery,
|
|
32241
32341
|
command,
|
|
32242
32342
|
command.disposition !== SessionPromptDisposition.Steer,
|
|
32243
|
-
(attemptId, executionSignal) => executePrompt(
|
|
32343
|
+
(attemptId, activateAttempt, executionSignal) => executePrompt(
|
|
32244
32344
|
outbox,
|
|
32245
32345
|
publisher,
|
|
32246
32346
|
command,
|
|
@@ -32249,6 +32349,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32249
32349
|
audit,
|
|
32250
32350
|
sessions,
|
|
32251
32351
|
attemptId,
|
|
32352
|
+
activateAttempt,
|
|
32252
32353
|
timer,
|
|
32253
32354
|
executionSignal
|
|
32254
32355
|
)
|
|
@@ -32750,7 +32851,6 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32750
32851
|
}
|
|
32751
32852
|
const turn2 = new ActiveDaemonTurn(command2, receipt2.attemptId);
|
|
32752
32853
|
activeTurns.set(command2.commandId, turn2);
|
|
32753
|
-
activeAttemptIds.set(command2.sessionId, receipt2.attemptId);
|
|
32754
32854
|
void executeBotPrompt(
|
|
32755
32855
|
outbox,
|
|
32756
32856
|
publisher,
|
|
@@ -32764,6 +32864,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32764
32864
|
applicator,
|
|
32765
32865
|
ipc,
|
|
32766
32866
|
receipt2.attemptId,
|
|
32867
|
+
() => activeAttemptIds.set(command2.sessionId, receipt2.attemptId),
|
|
32767
32868
|
timer,
|
|
32768
32869
|
turn2.signal
|
|
32769
32870
|
).catch((error61) => {
|
|
@@ -32790,9 +32891,6 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32790
32891
|
}
|
|
32791
32892
|
const turn = new ActiveDaemonTurn(command, receipt.attemptId);
|
|
32792
32893
|
activeTurns.set(command.commandId, turn);
|
|
32793
|
-
if (command.disposition !== SessionPromptDisposition.Steer) {
|
|
32794
|
-
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
32795
|
-
}
|
|
32796
32894
|
void executePrompt(
|
|
32797
32895
|
outbox,
|
|
32798
32896
|
publisher,
|
|
@@ -32802,6 +32900,11 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
32802
32900
|
audit,
|
|
32803
32901
|
sessions,
|
|
32804
32902
|
receipt.attemptId,
|
|
32903
|
+
() => {
|
|
32904
|
+
if (command.disposition !== SessionPromptDisposition.Steer) {
|
|
32905
|
+
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
32906
|
+
}
|
|
32907
|
+
},
|
|
32805
32908
|
timer,
|
|
32806
32909
|
turn.signal
|
|
32807
32910
|
).catch((error61) => {
|