@alook/daemon 0.1.7 → 0.1.9
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/cli/index.js +176 -5
- package/dist/index.js +11 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -16635,6 +16635,7 @@ var communityBotBinding = sqliteTable("community_bot_binding", {
|
|
|
16635
16635
|
userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
|
|
16636
16636
|
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "restrict" }),
|
|
16637
16637
|
runtime: text("runtime").notNull(),
|
|
16638
|
+
instruction: text("instruction").notNull().default(""),
|
|
16638
16639
|
modelName: text("model_name"),
|
|
16639
16640
|
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
16640
16641
|
}, (t) => [index("idx_community_bot_binding_machine").on(t.machineId)]);
|
|
@@ -16851,12 +16852,19 @@ import * as fs from "fs";
|
|
|
16851
16852
|
import * as path from "path";
|
|
16852
16853
|
// ../shared/src/constants/community.ts
|
|
16853
16854
|
var MAX_PROFILE_NAME_LENGTH = 100;
|
|
16855
|
+
var MAX_PROFILE_ABOUT_LENGTH = 1000;
|
|
16854
16856
|
var MAX_MESSAGE_CONTENT_LENGTH = 4000;
|
|
16855
16857
|
var MAX_EMOJI_BYTES = 32;
|
|
16856
16858
|
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
16857
16859
|
var MAX_ATTACHMENT_SIZE_BYTES = 25 * 1024 * 1024;
|
|
16858
16860
|
var MAX_ATTACHMENT_THUMBNAIL_SIZE_BYTES = 50 * 1024;
|
|
16859
16861
|
var MAX_SERVER_ICON_SIZE_BYTES = 5 * 1024 * 1024;
|
|
16862
|
+
var ALLOWED_ICON_MIME_TYPES = [
|
|
16863
|
+
"image/png",
|
|
16864
|
+
"image/jpeg",
|
|
16865
|
+
"image/webp",
|
|
16866
|
+
"image/gif"
|
|
16867
|
+
];
|
|
16860
16868
|
var MAX_ICON_SOURCE_FILE_SIZE_BYTES = 15 * 1024 * 1024;
|
|
16861
16869
|
// ../shared/src/utils/slug.ts
|
|
16862
16870
|
init_nanoid();
|
|
@@ -17538,6 +17546,16 @@ var CommunityAgentAttachmentUploadResponseSchema = exports_external.object({
|
|
|
17538
17546
|
var CommunityAgentAttachmentDownloadRequestSchema = exports_external.object({
|
|
17539
17547
|
id: exports_external.string().min(1)
|
|
17540
17548
|
});
|
|
17549
|
+
var CommunityAgentUpdateProfileRequestSchema = exports_external.object({
|
|
17550
|
+
bio: exports_external.string().max(MAX_PROFILE_ABOUT_LENGTH).optional(),
|
|
17551
|
+
avatar: exports_external.object({
|
|
17552
|
+
filename: exports_external.string().min(1),
|
|
17553
|
+
contentType: exports_external.enum(ALLOWED_ICON_MIME_TYPES),
|
|
17554
|
+
data: exports_external.instanceof(Uint8Array).refine((value) => value.byteLength > 0, "avatar must not be empty").refine((value) => value.byteLength <= MAX_SERVER_ICON_SIZE_BYTES, `avatar must be ≤ ${MAX_SERVER_ICON_SIZE_BYTES} bytes`)
|
|
17555
|
+
}).optional()
|
|
17556
|
+
}).refine((value) => value.bio !== undefined || value.avatar !== undefined, {
|
|
17557
|
+
message: "bio or avatar is required"
|
|
17558
|
+
});
|
|
17541
17559
|
var CommunityAgentInboxPullRequestSchema = exports_external.object({
|
|
17542
17560
|
max: exports_external.number().int().min(1).max(200).optional()
|
|
17543
17561
|
});
|
|
@@ -18689,6 +18707,7 @@ function createProxyServerApi(config2) {
|
|
|
18689
18707
|
}
|
|
18690
18708
|
if (!res.ok) {
|
|
18691
18709
|
const e = new Error(json2?.error ?? `proxy ${method} failed (${res.status})`);
|
|
18710
|
+
e.status = res.status;
|
|
18692
18711
|
if (json2?.code !== undefined)
|
|
18693
18712
|
e.code = json2.code;
|
|
18694
18713
|
if (json2?.hint !== undefined)
|
|
@@ -18697,6 +18716,24 @@ function createProxyServerApi(config2) {
|
|
|
18697
18716
|
}
|
|
18698
18717
|
return json2;
|
|
18699
18718
|
}
|
|
18719
|
+
function isTransientProfileStepError(err) {
|
|
18720
|
+
const message2 = err instanceof Error ? err.message : String(err);
|
|
18721
|
+
const status = typeof err === "object" && err !== null && "status" in err ? err.status : undefined;
|
|
18722
|
+
return typeof status === "number" && status >= 500 && status <= 599 || /upstream returned 5\d\d/.test(message2) || message2.includes("upstream body read failed") || message2.includes("fetch failed") || message2.includes("ECONNRESET") || message2.includes("ETIMEDOUT") || message2.includes("socket hang up") || message2.includes("network");
|
|
18723
|
+
}
|
|
18724
|
+
async function withProfileStepRetry(step) {
|
|
18725
|
+
const maxAttempts = 4;
|
|
18726
|
+
for (let attempt = 0;attempt < maxAttempts; attempt += 1) {
|
|
18727
|
+
try {
|
|
18728
|
+
return await step();
|
|
18729
|
+
} catch (err) {
|
|
18730
|
+
if (!isTransientProfileStepError(err) || attempt === maxAttempts - 1)
|
|
18731
|
+
throw err;
|
|
18732
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(2000, 150 * 2 ** attempt)));
|
|
18733
|
+
}
|
|
18734
|
+
}
|
|
18735
|
+
throw new Error("profile step retry exhausted");
|
|
18736
|
+
}
|
|
18700
18737
|
async function callUpload(req) {
|
|
18701
18738
|
const form = new FormData;
|
|
18702
18739
|
const blobType = req.file.contentType ?? "application/octet-stream";
|
|
@@ -18937,6 +18974,57 @@ function createProxyServerApi(config2) {
|
|
|
18937
18974
|
});
|
|
18938
18975
|
return parseJsonResponse(res, "nap");
|
|
18939
18976
|
}
|
|
18977
|
+
async function callUpdateProfile(req) {
|
|
18978
|
+
const parsed = CommunityAgentUpdateProfileRequestSchema.safeParse(req);
|
|
18979
|
+
if (!parsed.success) {
|
|
18980
|
+
throw new Error(parsed.error.issues[0]?.message ?? "invalid profile update");
|
|
18981
|
+
}
|
|
18982
|
+
const updated = [];
|
|
18983
|
+
let avatarUrl;
|
|
18984
|
+
if (req.avatar) {
|
|
18985
|
+
const body = await withProfileStepRetry(async () => {
|
|
18986
|
+
const form = new FormData;
|
|
18987
|
+
const blob2 = new Blob([new Uint8Array(req.avatar.data)], { type: req.avatar.contentType });
|
|
18988
|
+
form.append("file", blob2, req.avatar.filename);
|
|
18989
|
+
const res = await fetchImpl(`${base}/api/community/users/me/avatar`, {
|
|
18990
|
+
method: "POST",
|
|
18991
|
+
headers: { authorization: `Bearer ${config2.voucher}` },
|
|
18992
|
+
body: form
|
|
18993
|
+
});
|
|
18994
|
+
return parseJsonResponse(res, "updateProfile avatar");
|
|
18995
|
+
});
|
|
18996
|
+
avatarUrl = body.url;
|
|
18997
|
+
updated.push("avatar");
|
|
18998
|
+
}
|
|
18999
|
+
let bio;
|
|
19000
|
+
if (req.bio !== undefined) {
|
|
19001
|
+
try {
|
|
19002
|
+
const body = await withProfileStepRetry(async () => {
|
|
19003
|
+
const res = await fetchImpl(`${base}/api/community/users/me/profile`, {
|
|
19004
|
+
method: "PATCH",
|
|
19005
|
+
headers: {
|
|
19006
|
+
"content-type": "application/json",
|
|
19007
|
+
authorization: `Bearer ${config2.voucher}`
|
|
19008
|
+
},
|
|
19009
|
+
body: JSON.stringify({ aboutMe: req.bio })
|
|
19010
|
+
});
|
|
19011
|
+
return parseJsonResponse(res, "updateProfile bio");
|
|
19012
|
+
});
|
|
19013
|
+
bio = body.aboutMe;
|
|
19014
|
+
updated.push("bio");
|
|
19015
|
+
} catch (err) {
|
|
19016
|
+
if (avatarUrl !== undefined && err instanceof Error) {
|
|
19017
|
+
err.hint = "avatar was applied; bio was not applied";
|
|
19018
|
+
}
|
|
19019
|
+
throw err;
|
|
19020
|
+
}
|
|
19021
|
+
}
|
|
19022
|
+
return {
|
|
19023
|
+
updated,
|
|
19024
|
+
...bio !== undefined ? { bio } : {},
|
|
19025
|
+
...avatarUrl !== undefined ? { avatarUrl } : {}
|
|
19026
|
+
};
|
|
19027
|
+
}
|
|
18940
19028
|
async function callInboxSnapshot() {
|
|
18941
19029
|
const res = await fetchImpl(`${base}/api/community/users/me/inbox/snapshot`, {
|
|
18942
19030
|
method: "GET",
|
|
@@ -19014,6 +19102,7 @@ function createProxyServerApi(config2) {
|
|
|
19014
19102
|
listMembers: callListMembers,
|
|
19015
19103
|
attachmentUpload: callUpload,
|
|
19016
19104
|
attachmentDownload: callDownload,
|
|
19105
|
+
updateProfile: callUpdateProfile,
|
|
19017
19106
|
reactAdd: callReactAdd,
|
|
19018
19107
|
markSet: callMarkSet,
|
|
19019
19108
|
markRemove: callMarkRemove,
|
|
@@ -19098,6 +19187,10 @@ function cliCommandsSection() {
|
|
|
19098
19187
|
`1. \`${CLI} friend request --username "<name#0042>"\` — ask to friend a user by handle. ` + `Your owner must approve it in DM before it goes through, so expect a \`pending\` ` + `result with a hint (a same-owner sibling bot auto-accepts instead).`,
|
|
19099
19188
|
`2. \`${CLI} friend list\` — list your friends and pending requests ` + `(\`accepted\`, \`pendingOutgoing\`, \`pendingIncoming\`).`,
|
|
19100
19189
|
"",
|
|
19190
|
+
"### Settings",
|
|
19191
|
+
"",
|
|
19192
|
+
`1. \`${CLI} setting profile --set-bio <text> --set-avatar <path>\` — update your public bio ` + `and/or avatar. At least one flag is required; pass \`--set-bio ""\` to clear the bio.`,
|
|
19193
|
+
"",
|
|
19101
19194
|
"### Context Lifecycle",
|
|
19102
19195
|
"",
|
|
19103
19196
|
`1. \`${CLI} nap --handoff <file>\` (or \`--text <note>\`) — reset your current session and ` + `start fresh. The required handoff is injected into the new session so your future self can ` + `quickly pick up unfinished work. Never nap on your own; only do it when someone explicitly asks.`,
|
|
@@ -22010,6 +22103,8 @@ function parseBearer(authHeader) {
|
|
|
22010
22103
|
return m ? m[1].trim() : null;
|
|
22011
22104
|
}
|
|
22012
22105
|
var DEFAULT_CAPABILITY_RESOLVER = (method, pathname) => {
|
|
22106
|
+
if ((method === "GET" || method === "PATCH") && pathname === "/api/community/users/me/profile" || method === "POST" && pathname === "/api/community/users/me/avatar")
|
|
22107
|
+
return "profile";
|
|
22013
22108
|
if (pathname.includes("/attachment"))
|
|
22014
22109
|
return "attach";
|
|
22015
22110
|
if (/\/friends(\/|$|\?)/.test(pathname))
|
|
@@ -25184,6 +25279,10 @@ function deriveAuditLogSubcommand(pathname, method) {
|
|
|
25184
25279
|
return "inboxSnapshot";
|
|
25185
25280
|
if (/^\/api\/community\/users\/me\/inbox\/ack(\/|$|\?)/.test(canonical))
|
|
25186
25281
|
return null;
|
|
25282
|
+
if (method === "PATCH" && canonical === "/api/community/users/me/profile")
|
|
25283
|
+
return "profileBioUpdate";
|
|
25284
|
+
if (method === "POST" && canonical === "/api/community/users/me/avatar")
|
|
25285
|
+
return "profileAvatarUpdate";
|
|
25187
25286
|
if (/^\/api\/community\/bots\/me\/nap(\/|$|\?)/.test(canonical))
|
|
25188
25287
|
return "nap";
|
|
25189
25288
|
return null;
|
|
@@ -27082,7 +27181,7 @@ async function daemonReplace(opts) {
|
|
|
27082
27181
|
}
|
|
27083
27182
|
|
|
27084
27183
|
// src/cli/daemonRunner.ts
|
|
27085
|
-
var CAPABILITIES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge", "attach", "friend"];
|
|
27184
|
+
var CAPABILITIES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge", "attach", "friend", "profile"];
|
|
27086
27185
|
var DAEMON_LOG_MAX_BYTES = 8 * 1024 * 1024;
|
|
27087
27186
|
var DAEMON_ERROR_MESSAGE_MAX_CHARS = 512;
|
|
27088
27187
|
var DIAGNOSTIC_MAX_LINE_BYTES = 128 * 1024;
|
|
@@ -28057,6 +28156,17 @@ async function daemonResume(opts) {
|
|
|
28057
28156
|
resumeRequestId: opts.requestId
|
|
28058
28157
|
});
|
|
28059
28158
|
}
|
|
28159
|
+
async function daemonStartById(opts) {
|
|
28160
|
+
const baseDir = opts.baseDir || process.env.ALOOK_DATA_DIR || DEFAULT_BASE_DIR;
|
|
28161
|
+
const record2 = readDaemonLaunchRecord(baseDir, opts.id);
|
|
28162
|
+
await daemonStart({
|
|
28163
|
+
machineKey: record2.credential,
|
|
28164
|
+
serverUrl: record2.serverUrl,
|
|
28165
|
+
wsUrl: record2.wsUrl,
|
|
28166
|
+
baseDir,
|
|
28167
|
+
foreground: opts.foreground
|
|
28168
|
+
});
|
|
28169
|
+
}
|
|
28060
28170
|
function runnerArguments() {
|
|
28061
28171
|
const command = process.env.ALOOK_DAEMON_PACKAGE_WRAPPER === "1" ? ["run"] : ["daemon", "run"];
|
|
28062
28172
|
return [...process.execArgv, process.argv[1], ...command];
|
|
@@ -28426,7 +28536,8 @@ function contentTypeFromFilename(filename) {
|
|
|
28426
28536
|
}
|
|
28427
28537
|
function isTransientMutationError(err) {
|
|
28428
28538
|
const msg = err instanceof Error ? err.message : String(err);
|
|
28429
|
-
|
|
28539
|
+
const status = typeof err === "object" && err !== null && "status" in err ? err.status : undefined;
|
|
28540
|
+
return typeof status === "number" && status >= 500 && status <= 599 || /upstream returned 5\d\d/.test(msg) || msg.includes("upstream body read failed") || msg.includes("fetch failed") || msg.includes("ECONNRESET") || msg.includes("ETIMEDOUT") || msg.includes("socket hang up") || msg.includes("network");
|
|
28430
28541
|
}
|
|
28431
28542
|
async function withTransientMutationRetry(mutation) {
|
|
28432
28543
|
const MAX_ATTEMPTS = 4;
|
|
@@ -28690,6 +28801,43 @@ async function cmdAttachmentDownload(opts) {
|
|
|
28690
28801
|
}
|
|
28691
28802
|
return result;
|
|
28692
28803
|
}
|
|
28804
|
+
async function cmdSettingProfile(opts) {
|
|
28805
|
+
const bio = opts.setBio;
|
|
28806
|
+
const avatarPath = opts.setAvatar;
|
|
28807
|
+
if (bio === undefined && avatarPath === undefined) {
|
|
28808
|
+
throw new CliError("setting profile: --set-bio <text> or --set-avatar <path> is required");
|
|
28809
|
+
}
|
|
28810
|
+
if (bio !== undefined && bio.length > MAX_PROFILE_ABOUT_LENGTH) {
|
|
28811
|
+
throw new CliError(`setting profile: bio must be ≤ ${MAX_PROFILE_ABOUT_LENGTH} characters`);
|
|
28812
|
+
}
|
|
28813
|
+
let avatar;
|
|
28814
|
+
if (avatarPath !== undefined) {
|
|
28815
|
+
const fs13 = await import("fs/promises");
|
|
28816
|
+
let bytes;
|
|
28817
|
+
try {
|
|
28818
|
+
bytes = await fs13.readFile(avatarPath);
|
|
28819
|
+
} catch (err) {
|
|
28820
|
+
throw new CliError(`setting profile: cannot read avatar: ${err.message}`);
|
|
28821
|
+
}
|
|
28822
|
+
if (bytes.byteLength === 0)
|
|
28823
|
+
throw new CliError("setting profile: avatar file is empty");
|
|
28824
|
+
if (bytes.byteLength > MAX_SERVER_ICON_SIZE_BYTES) {
|
|
28825
|
+
throw new CliError(`setting profile: avatar too large — ${bytes.byteLength} bytes, max ${MAX_SERVER_ICON_SIZE_BYTES}`);
|
|
28826
|
+
}
|
|
28827
|
+
const pathMod = await import("path");
|
|
28828
|
+
const filename = pathMod.basename(avatarPath);
|
|
28829
|
+
const contentType = contentTypeFromFilename(filename);
|
|
28830
|
+
if (!ALLOWED_ICON_MIME_TYPES.includes(contentType)) {
|
|
28831
|
+
throw new CliError("setting profile: avatar must be png / jpeg / webp / gif");
|
|
28832
|
+
}
|
|
28833
|
+
avatar = { filename, contentType, data: new Uint8Array(bytes) };
|
|
28834
|
+
}
|
|
28835
|
+
const api2 = getApi();
|
|
28836
|
+
return api2.updateProfile({
|
|
28837
|
+
...bio !== undefined ? { bio } : {},
|
|
28838
|
+
...avatar ? { avatar } : {}
|
|
28839
|
+
});
|
|
28840
|
+
}
|
|
28693
28841
|
async function cmdInboxPull(opts) {
|
|
28694
28842
|
const api2 = getApi();
|
|
28695
28843
|
const agent2 = agentId(opts);
|
|
@@ -28943,6 +29091,12 @@ function buildProgram() {
|
|
|
28943
29091
|
const result = await cmdFriendList({ ...globalOpts, ...localOpts });
|
|
28944
29092
|
printEnvelope({ success: result });
|
|
28945
29093
|
});
|
|
29094
|
+
const setting = program.command("setting").description("account settings").exitOverride();
|
|
29095
|
+
setting.configureOutput({ writeOut: () => {}, writeErr: () => {} });
|
|
29096
|
+
setting.command("profile").description("update your public bio and/or avatar").option("--set-bio <text>", "set public bio; pass an empty string to clear it").option("--set-avatar <path>", "upload a png, jpeg, webp, or gif avatar").exitOverride().configureOutput({ writeOut: () => {}, writeErr: () => {} }).action(async function() {
|
|
29097
|
+
const result = await cmdSettingProfile({ ...program.opts(), ...this.opts() });
|
|
29098
|
+
printEnvelope({ success: result });
|
|
29099
|
+
});
|
|
28946
29100
|
program.command("nap").description("end your session and start fresh, carrying a handoff to your reborn self (read the nap rule first)").option("--handoff <file>", "path to your handoff note (your note to your reborn self)").option("--text <note>", "inline handoff note (alternative to --handoff)").exitOverride().configureOutput({ writeOut: () => {}, writeErr: () => {} }).action(async function() {
|
|
28947
29101
|
const localOpts = this.opts();
|
|
28948
29102
|
const globalOpts = program.opts();
|
|
@@ -28951,10 +29105,23 @@ function buildProgram() {
|
|
|
28951
29105
|
});
|
|
28952
29106
|
const daemon = program.command("daemon").description("daemon operations").exitOverride();
|
|
28953
29107
|
daemon.configureOutput({ writeOut: () => {}, writeErr: () => {} });
|
|
28954
|
-
daemon.command("start").description("start the daemon (connects to server, manages agent lifecycles)").
|
|
29108
|
+
daemon.command("start").description("start the daemon (connects to server, manages agent lifecycles)").option("--machine-key <key>", "machine key for first-time pairing").option("--id <machineId>", "restart a previously paired machine by id").option("--server-url <url>", "server HTTP URL (or ALOOK_SERVER_URL env)").option("--ws-url <url>", "server WebSocket URL (or ALOOK_SERVER_WS_URL env)").option("--base-dir <path>", "data directory for agent workspaces and pidfile (or ALOOK_DATA_DIR env)").option("--foreground", "run in the current process and tee daemon logs to the terminal").exitOverride().configureOutput({ writeOut: () => {}, writeErr: () => {} }).action(async function() {
|
|
28955
29109
|
const localOpts = this.opts();
|
|
29110
|
+
const machineKey = localOpts.machineKey;
|
|
29111
|
+
const id = localOpts.id;
|
|
29112
|
+
if (!machineKey && !id || machineKey && id) {
|
|
29113
|
+
throw new CliError("daemon start requires exactly one of --machine-key <key> or --id <machineId>");
|
|
29114
|
+
}
|
|
29115
|
+
if (id) {
|
|
29116
|
+
await daemonStartById({
|
|
29117
|
+
id,
|
|
29118
|
+
baseDir: localOpts.baseDir,
|
|
29119
|
+
foreground: localOpts.foreground === true
|
|
29120
|
+
});
|
|
29121
|
+
return;
|
|
29122
|
+
}
|
|
28956
29123
|
await daemonStart({
|
|
28957
|
-
machineKey
|
|
29124
|
+
machineKey,
|
|
28958
29125
|
serverUrl: localOpts.serverUrl,
|
|
28959
29126
|
wsUrl: localOpts.wsUrl,
|
|
28960
29127
|
baseDir: localOpts.baseDir,
|
|
@@ -28987,9 +29154,13 @@ function buildProgram() {
|
|
|
28987
29154
|
baseDir: localOpts.baseDir
|
|
28988
29155
|
});
|
|
28989
29156
|
});
|
|
28990
|
-
daemon.command("list").description("list running daemons on this machine").option("--base-dir <path>", "data directory (or ALOOK_DATA_DIR env)").exitOverride().configureOutput({ writeOut: () => {}, writeErr: () => {} }).action(function() {
|
|
29157
|
+
daemon.command("list").description("list running daemons on this machine").option("--base-dir <path>", "data directory (or ALOOK_DATA_DIR env)").option("--json", "print a machine-readable JSON envelope").exitOverride().configureOutput({ writeOut: () => {}, writeErr: () => {} }).action(function() {
|
|
28991
29158
|
const localOpts = this.opts();
|
|
28992
29159
|
const daemons = daemonList({ baseDir: localOpts.baseDir });
|
|
29160
|
+
if (localOpts.json === true) {
|
|
29161
|
+
printEnvelope({ success: { daemons } });
|
|
29162
|
+
return;
|
|
29163
|
+
}
|
|
28993
29164
|
process.stdout.write(renderDaemonList(daemons) + `
|
|
28994
29165
|
`);
|
|
28995
29166
|
});
|
package/dist/index.js
CHANGED
|
@@ -82,6 +82,10 @@ function cliCommandsSection() {
|
|
|
82
82
|
`1. \`${CLI} friend request --username "<name#0042>"\` — ask to friend a user by handle. ` + `Your owner must approve it in DM before it goes through, so expect a \`pending\` ` + `result with a hint (a same-owner sibling bot auto-accepts instead).`,
|
|
83
83
|
`2. \`${CLI} friend list\` — list your friends and pending requests ` + `(\`accepted\`, \`pendingOutgoing\`, \`pendingIncoming\`).`,
|
|
84
84
|
"",
|
|
85
|
+
"### Settings",
|
|
86
|
+
"",
|
|
87
|
+
`1. \`${CLI} setting profile --set-bio <text> --set-avatar <path>\` — update your public bio ` + `and/or avatar. At least one flag is required; pass \`--set-bio ""\` to clear the bio.`,
|
|
88
|
+
"",
|
|
85
89
|
"### Context Lifecycle",
|
|
86
90
|
"",
|
|
87
91
|
`1. \`${CLI} nap --handoff <file>\` (or \`--text <note>\`) — reset your current session and ` + `start fresh. The required handoff is injected into the new session so your future self can ` + `quickly pick up unfinished work. Never nap on your own; only do it when someone explicitly asks.`,
|
|
@@ -21638,6 +21642,7 @@ var communityBotBinding = sqliteTable("community_bot_binding", {
|
|
|
21638
21642
|
userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
|
|
21639
21643
|
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "restrict" }),
|
|
21640
21644
|
runtime: text("runtime").notNull(),
|
|
21645
|
+
instruction: text("instruction").notNull().default(""),
|
|
21641
21646
|
modelName: text("model_name"),
|
|
21642
21647
|
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21643
21648
|
}, (t) => [index("idx_community_bot_binding_machine").on(t.machineId)]);
|
|
@@ -21947,6 +21952,8 @@ function parseBearer(authHeader) {
|
|
|
21947
21952
|
return m ? m[1].trim() : null;
|
|
21948
21953
|
}
|
|
21949
21954
|
var DEFAULT_CAPABILITY_RESOLVER = (method, pathname) => {
|
|
21955
|
+
if ((method === "GET" || method === "PATCH") && pathname === "/api/community/users/me/profile" || method === "POST" && pathname === "/api/community/users/me/avatar")
|
|
21956
|
+
return "profile";
|
|
21950
21957
|
if (pathname.includes("/attachment"))
|
|
21951
21958
|
return "attach";
|
|
21952
21959
|
if (/\/friends(\/|$|\?)/.test(pathname))
|
|
@@ -23689,6 +23696,10 @@ function deriveAuditLogSubcommand(pathname, method) {
|
|
|
23689
23696
|
return "inboxSnapshot";
|
|
23690
23697
|
if (/^\/api\/community\/users\/me\/inbox\/ack(\/|$|\?)/.test(canonical))
|
|
23691
23698
|
return null;
|
|
23699
|
+
if (method === "PATCH" && canonical === "/api/community/users/me/profile")
|
|
23700
|
+
return "profileBioUpdate";
|
|
23701
|
+
if (method === "POST" && canonical === "/api/community/users/me/avatar")
|
|
23702
|
+
return "profileAvatarUpdate";
|
|
23692
23703
|
if (/^\/api\/community\/bots\/me\/nap(\/|$|\?)/.test(canonical))
|
|
23693
23704
|
return "nap";
|
|
23694
23705
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alook/daemon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Alook agent daemon — host-side runtime backend, process manager, credential proxy, and control plane.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/alookai/alook#readme",
|