@botiverse/raft-daemon 0.71.0 → 0.72.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/{chunk-VZWVYMUX.js → chunk-YAI5OK4D.js} +252 -23
- package/dist/cli/index.js +132 -21
- package/dist/cli/package.json +1 -1
- package/dist/core.js +1 -1
- package/dist/{dist-R2LWKKE2.js → dist-UCGBT6NS.js} +128 -21
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -2000,6 +2000,12 @@ var actionCardActionSchema = z.discriminatedUnion("type", [
|
|
|
2000
2000
|
|
|
2001
2001
|
// ../shared/src/agentApiContract.ts
|
|
2002
2002
|
import { z as z2 } from "zod";
|
|
2003
|
+
|
|
2004
|
+
// ../shared/src/attentionDependencyOracle.ts
|
|
2005
|
+
var ATTENTION_HINT_SCHEMA = "attention-dependency-hint.v1";
|
|
2006
|
+
var ATTENTION_HINT_DEFAULT_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
2007
|
+
|
|
2008
|
+
// ../shared/src/agentApiContract.ts
|
|
2003
2009
|
var AGENT_API_BASE_PATH = "/internal/agent-api";
|
|
2004
2010
|
var optionalStringSchema = z2.string().trim().optional();
|
|
2005
2011
|
var optionalStringArraySchema = z2.array(z2.string().trim().min(1)).optional();
|
|
@@ -2526,8 +2532,17 @@ var agentApiSendResponseSchema = z2.discriminatedUnion("state", [
|
|
|
2526
2532
|
var agentApiMessageResolveResponseSchema = passthroughObject({
|
|
2527
2533
|
message: agentApiMessageEnvelopeSchema
|
|
2528
2534
|
});
|
|
2535
|
+
var agentApiChannelAttentionSchema = passthroughObject({
|
|
2536
|
+
state: optionalStringSchema,
|
|
2537
|
+
ordinaryActivity: optionalStringSchema,
|
|
2538
|
+
stillArrives: optionalStringArraySchema,
|
|
2539
|
+
threadBoundary: optionalStringSchema,
|
|
2540
|
+
manageCommand: optionalStringSchema,
|
|
2541
|
+
manageApi: optionalStringSchema
|
|
2542
|
+
});
|
|
2529
2543
|
var agentApiOkResponseSchema = passthroughObject({
|
|
2530
|
-
ok: z2.literal(true)
|
|
2544
|
+
ok: z2.literal(true),
|
|
2545
|
+
attention: agentApiChannelAttentionSchema.optional()
|
|
2531
2546
|
});
|
|
2532
2547
|
var agentApiSearchResultSchema = passthroughObject({
|
|
2533
2548
|
id: z2.string(),
|
|
@@ -2584,6 +2599,16 @@ var agentApiChannelMuteResponseSchema = passthroughObject({
|
|
|
2584
2599
|
catchUp: optionalStringSchema
|
|
2585
2600
|
}).optional()
|
|
2586
2601
|
});
|
|
2602
|
+
var agentApiChannelMuteBodySchema = passthroughObject({
|
|
2603
|
+
attentionHintAccepted: passthroughObject({
|
|
2604
|
+
schema: z2.literal(ATTENTION_HINT_SCHEMA),
|
|
2605
|
+
trigger: z2.enum(["M2", "M3"]),
|
|
2606
|
+
scope: z2.string().trim().min(1),
|
|
2607
|
+
suggested_command: optionalStringSchema,
|
|
2608
|
+
copy_version: z2.string().trim().min(1),
|
|
2609
|
+
epoch_ms: z2.number().int().nonnegative()
|
|
2610
|
+
}).optional()
|
|
2611
|
+
});
|
|
2587
2612
|
var agentApiTaskClaimResultSchema = passthroughObject({
|
|
2588
2613
|
taskNumber: z2.number().int().positive().optional(),
|
|
2589
2614
|
messageId: optionalStringSchema,
|
|
@@ -2793,7 +2818,7 @@ var agentApiContract = {
|
|
|
2793
2818
|
client: { resource: "channels", method: "mute" },
|
|
2794
2819
|
capability: "channels",
|
|
2795
2820
|
description: "Mute ordinary activity delivery for a visible regular channel as the bound agent credential.",
|
|
2796
|
-
request: { params: agentApiChannelMembershipParamsSchema },
|
|
2821
|
+
request: { params: agentApiChannelMembershipParamsSchema, body: agentApiChannelMuteBodySchema },
|
|
2797
2822
|
response: { body: agentApiChannelMuteResponseSchema }
|
|
2798
2823
|
}),
|
|
2799
2824
|
channelUnmute: route({
|
|
@@ -3103,6 +3128,20 @@ var optionalQueryIntSchema = z3.union([z3.number().int().nonnegative(), z3.strin
|
|
|
3103
3128
|
var nullableNumberSchema2 = z3.number().finite().nullable();
|
|
3104
3129
|
var passthroughObject2 = (shape) => z3.object(shape).passthrough();
|
|
3105
3130
|
var daemonApiInboxFlagSchema = z3.enum(["mention", "thread", "dm", "task"]);
|
|
3131
|
+
var daemonApiAttentionHintSchema = passthroughObject2({
|
|
3132
|
+
schema: z3.literal(ATTENTION_HINT_SCHEMA),
|
|
3133
|
+
trigger: z3.enum(["M2", "M3"]),
|
|
3134
|
+
scope: z3.string().trim().min(1),
|
|
3135
|
+
suggested_command: z3.string().trim().min(1),
|
|
3136
|
+
copy: z3.string().trim().min(1),
|
|
3137
|
+
copy_version: z3.literal("attention-hint-copy-v1"),
|
|
3138
|
+
epoch_ms: z3.number().int().nonnegative(),
|
|
3139
|
+
thresholds: passthroughObject2({
|
|
3140
|
+
K: optionalNonNegativeIntSchema,
|
|
3141
|
+
k: optionalNonNegativeIntSchema,
|
|
3142
|
+
window_ms: z3.number().int().positive()
|
|
3143
|
+
})
|
|
3144
|
+
});
|
|
3106
3145
|
var daemonApiInboxTargetRowSchema = passthroughObject2({
|
|
3107
3146
|
target: z3.string().trim().min(1),
|
|
3108
3147
|
channelId: optionalStringSchema2,
|
|
@@ -3113,8 +3152,9 @@ var daemonApiInboxTargetRowSchema = passthroughObject2({
|
|
|
3113
3152
|
latestMsgId: optionalStringSchema2,
|
|
3114
3153
|
latestSeq: optionalNonNegativeIntSchema,
|
|
3115
3154
|
latestSenderName: optionalStringSchema2,
|
|
3116
|
-
latestSenderType: z3.enum(["human", "agent", "system"]).optional(),
|
|
3117
|
-
flags: z3.array(daemonApiInboxFlagSchema)
|
|
3155
|
+
latestSenderType: z3.enum(["human", "agent", "system", "third_party_app"]).optional(),
|
|
3156
|
+
flags: z3.array(daemonApiInboxFlagSchema),
|
|
3157
|
+
attentionHint: daemonApiAttentionHintSchema.optional()
|
|
3118
3158
|
});
|
|
3119
3159
|
var daemonApiInboxCheckResponseSchema = passthroughObject2({
|
|
3120
3160
|
rows: z3.array(daemonApiInboxTargetRowSchema).optional()
|
|
@@ -3137,6 +3177,7 @@ var daemonApiWakeHintSchema = passthroughObject2({
|
|
|
3137
3177
|
target_type: optionalStringSchema2,
|
|
3138
3178
|
reason: optionalStringSchema2,
|
|
3139
3179
|
wake_reason: optionalStringSchema2,
|
|
3180
|
+
attention_hint: daemonApiAttentionHintSchema.optional(),
|
|
3140
3181
|
createdAt: optionalStringSchema2,
|
|
3141
3182
|
created_at: optionalStringSchema2
|
|
3142
3183
|
});
|
|
@@ -3223,6 +3264,7 @@ function formatAgentInboxRowDetails(row) {
|
|
|
3223
3264
|
if (row.latestSenderName) parts.push(`latest sender @${row.latestSenderName}`);
|
|
3224
3265
|
if (row.latestMsgId) parts.push(`latest msg=${shortMessageId(row.latestMsgId)}`);
|
|
3225
3266
|
parts.push(...row.flags.map(formatAgentInboxFlag));
|
|
3267
|
+
if (row.attentionHint) parts.push(`attention_hint=${formatAttentionHintField(row.attentionHint)}`);
|
|
3226
3268
|
return parts.join(" \xB7 ");
|
|
3227
3269
|
}
|
|
3228
3270
|
function formatAgentInboxFlag(flag) {
|
|
@@ -3232,6 +3274,18 @@ function formatAgentInboxFlag(flag) {
|
|
|
3232
3274
|
function shortMessageId(value) {
|
|
3233
3275
|
return value.slice(0, 8);
|
|
3234
3276
|
}
|
|
3277
|
+
function formatAttentionHintField(hint) {
|
|
3278
|
+
return JSON.stringify({
|
|
3279
|
+
schema: hint.schema,
|
|
3280
|
+
trigger: hint.trigger,
|
|
3281
|
+
scope: hint.scope,
|
|
3282
|
+
suggested_command: hint.suggested_command,
|
|
3283
|
+
copy: hint.copy,
|
|
3284
|
+
copy_version: hint.copy_version,
|
|
3285
|
+
epoch_ms: hint.epoch_ms,
|
|
3286
|
+
thresholds: hint.thresholds
|
|
3287
|
+
});
|
|
3288
|
+
}
|
|
3235
3289
|
|
|
3236
3290
|
// ../shared/src/externalAgentIntegration.ts
|
|
3237
3291
|
import { z as z4 } from "zod";
|
|
@@ -3574,9 +3628,9 @@ var EXTERNAL_AGENT_RUNTIME_ID = "external";
|
|
|
3574
3628
|
var EXTERNAL_AGENT_RUNTIME_MODEL = "external";
|
|
3575
3629
|
var EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME = "External agent";
|
|
3576
3630
|
var RUNTIMES = [
|
|
3577
|
-
{ id: "builtin", displayName: "Built-in", binary: "", supported: true },
|
|
3578
3631
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
3579
3632
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
3633
|
+
{ id: "builtin", displayName: "Builtin Pi", binary: "", supported: true },
|
|
3580
3634
|
{ id: "antigravity", displayName: "Antigravity CLI", binary: "agy", supported: true },
|
|
3581
3635
|
// Kimi: prefer the in-process SDK (`kimi-sdk` → "Kimi Code") for new agents.
|
|
3582
3636
|
// The legacy `kimi` (kimi-cli child-process) entry stays for backward compat
|
|
@@ -5869,6 +5923,7 @@ function projectBucket(target, messages) {
|
|
|
5869
5923
|
if (message.task_number || message.task_status) flags.add("task");
|
|
5870
5924
|
if (message.mentioned === true) flags.add("mention");
|
|
5871
5925
|
}
|
|
5926
|
+
const attentionHint = [...sorted].reverse().find((message) => message.attention_hint)?.attention_hint;
|
|
5872
5927
|
return stripUndefined({
|
|
5873
5928
|
target,
|
|
5874
5929
|
channelId: latest.channel_id ?? latest.parent_channel_id,
|
|
@@ -5880,7 +5935,8 @@ function projectBucket(target, messages) {
|
|
|
5880
5935
|
latestSeq: messageSeq2(latest),
|
|
5881
5936
|
latestSenderName: latest.sender_name ?? latest.senderName,
|
|
5882
5937
|
latestSenderType: normalizeSenderType(latest.sender_type ?? latest.senderType),
|
|
5883
|
-
flags: [...flags].sort()
|
|
5938
|
+
flags: [...flags].sort(),
|
|
5939
|
+
attentionHint
|
|
5884
5940
|
});
|
|
5885
5941
|
}
|
|
5886
5942
|
function compareInboxMessages(a, b) {
|
|
@@ -13947,7 +14003,7 @@ Do not imply you have already created agents or channels unless the action has a
|
|
|
13947
14003
|
### Capability Boundary Pivot
|
|
13948
14004
|
If the user's primary request is outside current capabilities, acknowledge the limitation once and pivot immediately to the nearest useful alternative.
|
|
13949
14005
|
Do not repeat that something is impossible across multiple turns.
|
|
13950
|
-
Offer a concrete substitute: a manual input path, a narrower analysis task, an agent/team setup, or another workflow
|
|
14006
|
+
Offer a concrete substitute: a manual input path, a narrower analysis task, an agent/team setup, or another workflow Raft can execute now.
|
|
13951
14007
|
|
|
13952
14008
|
### Active-Elsewhere Handoff
|
|
13953
14009
|
Channel silence is not failure.
|
|
@@ -13998,7 +14054,7 @@ The reminder must reference the user's goal, agent, recent step, or suggested ne
|
|
|
13998
14054
|
- Optimize for first useful collaboration action.
|
|
13999
14055
|
- Keep answers concise by default; expand only when the user asks.
|
|
14000
14056
|
- Never copy FAQ text verbatim; synthesize and personalize.
|
|
14001
|
-
- If user asks for team support or wants to raise a request, direct them to email cindy@
|
|
14057
|
+
- If user asks for team support or wants to raise a request, direct them to email cindy@raft.build.
|
|
14002
14058
|
- When multiple agents are involved, reduce noise and collisions by steering work into explicit task ownership.
|
|
14003
14059
|
`;
|
|
14004
14060
|
}
|
|
@@ -14011,8 +14067,8 @@ Do not copy these answers verbatim.
|
|
|
14011
14067
|
|
|
14012
14068
|
## FAQ 1: What are you? What can you do?
|
|
14013
14069
|
### Answer idea
|
|
14014
|
-
- You are Cindy, onboarding
|
|
14015
|
-
-
|
|
14070
|
+
- You are Cindy, the Raft onboarding partner for practical setup.
|
|
14071
|
+
- Raft enables persistent specialized agents collaborating in channels/threads.
|
|
14016
14072
|
|
|
14017
14073
|
### Next step
|
|
14018
14074
|
- Ask what the user is working on and map to setup.
|
|
@@ -14152,9 +14208,9 @@ Do not copy these answers verbatim.
|
|
|
14152
14208
|
### Guardrail
|
|
14153
14209
|
- Agents complement documentation; they do not replace all records.
|
|
14154
14210
|
|
|
14155
|
-
## FAQ 13: How to contact
|
|
14211
|
+
## FAQ 13: How to contact the Raft team for support or requests?
|
|
14156
14212
|
### Answer idea
|
|
14157
|
-
- For team support or product requests, contact cindy@
|
|
14213
|
+
- For team support or product requests, contact cindy@raft.build.
|
|
14158
14214
|
|
|
14159
14215
|
### Next step
|
|
14160
14216
|
- Offer to help the user draft a short, clear support/request email now.
|
|
@@ -14162,10 +14218,10 @@ Do not copy these answers verbatim.
|
|
|
14162
14218
|
### Guardrail
|
|
14163
14219
|
- Keep contact guidance concrete and current; do not invent alternative support channels.
|
|
14164
14220
|
|
|
14165
|
-
## FAQ 14: Can I use
|
|
14221
|
+
## FAQ 14: Can I use Raft on my phone?
|
|
14166
14222
|
### Answer idea
|
|
14167
|
-
- Yes.
|
|
14168
|
-
- For easier return access, users can add
|
|
14223
|
+
- Yes. Raft can be used from a mobile browser.
|
|
14224
|
+
- For easier return access, users can add Raft to their phone home screen as a web app:
|
|
14169
14225
|
- iPhone: Safari \u2192 Share \u2192 Add to Home Screen
|
|
14170
14226
|
- Android: Chrome \u2192 menu \u2192 Add to Home Screen / Install app
|
|
14171
14227
|
- Good mobile use cases: quick check-ins, todos/reminders, short replies, and reviewing agent updates.
|
|
@@ -14174,7 +14230,7 @@ Do not copy these answers verbatim.
|
|
|
14174
14230
|
- If the user wants mobile access now, ask whether they use iPhone or Android, then guide the matching Add to Home Screen step.
|
|
14175
14231
|
|
|
14176
14232
|
### Guardrail
|
|
14177
|
-
- Do not imply
|
|
14233
|
+
- Do not imply Raft has a native iOS/Android App Store app.
|
|
14178
14234
|
- Do not over-sell it as fully equivalent to a native app; call it mobile browser / home-screen web app.
|
|
14179
14235
|
|
|
14180
14236
|
## FAQ 15: How do I create agents or channels?
|
|
@@ -14182,7 +14238,7 @@ Do not copy these answers verbatim.
|
|
|
14182
14238
|
- If you have \`channel:create\` scope and your server role has channel-management authority, create channels directly with \`raft channel create --name <name>\` (add \`--private\` for private channels). This creates the channel under your agent identity and joins you to it.
|
|
14183
14239
|
- If you also have the matching channel-management scopes and authority, edit regular channels with \`raft channel update --target "#channel-name" --name "#new-name"\`, add humans or agents with \`raft channel add-member --target "#channel-name" --user @alice\` or \`--agent @scout\`, and remove them with \`raft channel remove-member --target "#channel-name" --user @alice\` or \`--agent @scout\`. Adding members is the direct follow-up for private channels you create under your agent identity.
|
|
14184
14240
|
- When a human should review/commit the action, or when creating a new agent, **post an action card** with \`raft action prepare\`. The card lives inline in chat; the owner clicks the action button, the matching create dialog opens prefilled with your values (editable), and the resource is created under their identity when they submit.
|
|
14185
|
-
- v1 supports three action types via \`raft action prepare --target '<channel>' <<'
|
|
14241
|
+
- v1 supports three action types via \`raft action prepare --target '<channel>' <<'RAFTACTION' { ... } RAFTACTION\`:
|
|
14186
14242
|
- \`{type: "channel:create", name, visibility: "public" | "private", description?, initialHumans?: ["@alice"], initialAgents?: ["@scout"], draftHint?}\`
|
|
14187
14243
|
- \`{type: "agent:create", name, description?, suggestedComputer?, requiredComputer?, draftHint?}\` \u2014 runtime / model / reasoning effort are the owner's call. Use \`requiredComputer\` only when the owner explicitly says the new agent must run on that computer; use \`suggestedComputer\` for a soft preference.
|
|
14188
14244
|
- \`{type: "channel:add_member", channel: "#existing-channel", humans?: ["@alice"], agents?: ["@scout"], draftHint?}\` \u2014 at least one of humans / agents must be non-empty. The owner clicks "Add Members" on the card; an AddMembers dialog opens with your suggested list (each row toggleable) and the owner submits to actually add them.
|
|
@@ -14208,9 +14264,146 @@ function buildOnboardingSeedFiles() {
|
|
|
14208
14264
|
{
|
|
14209
14265
|
relativePath: "notes/onboarding_knowledge_faq.md",
|
|
14210
14266
|
content: buildOnboardingKnowledgeFaqMd()
|
|
14267
|
+
},
|
|
14268
|
+
{
|
|
14269
|
+
relativePath: "notes/onboarding_objectives.md",
|
|
14270
|
+
content: buildOnboardingObjectivesMd()
|
|
14211
14271
|
}
|
|
14212
14272
|
];
|
|
14213
14273
|
}
|
|
14274
|
+
function buildOnboardingObjectivesMd() {
|
|
14275
|
+
return `# What I'm here to help you do
|
|
14276
|
+
|
|
14277
|
+
*(I mark these as we go: done / skipped / later. "Skipped" means you said no \u2014 I won't bring it back unless you do.)*
|
|
14278
|
+
|
|
14279
|
+
This is your private working file for onboarding the server owner. Keep it current as you work.
|
|
14280
|
+
|
|
14281
|
+
The system may have already posted four visible opener messages as you. Those messages count as yours. Do not resend, rephrase, or send another opener just because this is your first real wake. Continue from the owner's reply.
|
|
14282
|
+
|
|
14283
|
+
## Status Contract
|
|
14284
|
+
- This file is the durable storage mechanism. The \`status\`, \`updated_at\`, and \`refusal_note\` fields under each objective are the state you maintain across restarts.
|
|
14285
|
+
- Status values are exactly: \`todo\`, \`done\`, \`skipped\`, \`later\`, \`blocked\`.
|
|
14286
|
+
- Update one item at a time as the user moves. Preserve existing fields; do not reset this file on wake.
|
|
14287
|
+
- \`skipped\` means the user declined or said no. Treat it as persistent refusal-memory across restarts. Set \`refusal_note\` with what was declined and do not re-ask until the user explicitly reopens it.
|
|
14288
|
+
- \`later\` means the user asked to postpone. It is not consent, and it is not a refusal.
|
|
14289
|
+
- \`blocked\` means the next step needs a missing permission, unavailable tool, or human decision. Say the blocker plainly and move to a useful adjacent step.
|
|
14290
|
+
|
|
14291
|
+
## Current Objectives
|
|
14292
|
+
|
|
14293
|
+
### 1. real-work
|
|
14294
|
+
status: todo
|
|
14295
|
+
updated_at:
|
|
14296
|
+
refusal_note:
|
|
14297
|
+
|
|
14298
|
+
Get one real piece of your work done here \u2014 your actual work, not a demo.
|
|
14299
|
+
|
|
14300
|
+
### 2. starter-team
|
|
14301
|
+
status: todo
|
|
14302
|
+
updated_at:
|
|
14303
|
+
refusal_note:
|
|
14304
|
+
|
|
14305
|
+
Build your starter team: at least 3 agents with clear jobs, shaped around what you do.
|
|
14306
|
+
|
|
14307
|
+
### 3. channels
|
|
14308
|
+
status: todo
|
|
14309
|
+
updated_at:
|
|
14310
|
+
refusal_note:
|
|
14311
|
+
|
|
14312
|
+
Set up channels that match how you work \u2014 one workstream, one channel.
|
|
14313
|
+
|
|
14314
|
+
### 4. connect-computer
|
|
14315
|
+
status: todo
|
|
14316
|
+
updated_at:
|
|
14317
|
+
refusal_note:
|
|
14318
|
+
|
|
14319
|
+
Connect your computer, so your agents run on your machine and remember things.
|
|
14320
|
+
|
|
14321
|
+
### 5. ask-me-anything
|
|
14322
|
+
status: todo
|
|
14323
|
+
updated_at:
|
|
14324
|
+
refusal_note:
|
|
14325
|
+
|
|
14326
|
+
Know that you can ask me anything, anytime \u2014 that's the whole point of me.
|
|
14327
|
+
|
|
14328
|
+
## Hard Rules
|
|
14329
|
+
- One ask per turn.
|
|
14330
|
+
- No more than three owner decisions on day one.
|
|
14331
|
+
- Consent before setup scan. Never scan local setup silently.
|
|
14332
|
+
- If the owner declines setup scan, mark that scan path \`skipped\` and do not ask again unless the owner reopens it.
|
|
14333
|
+
- Manual-first when stuck: use the embedded recipes below, then \`raft manual get recipes/index\`, then \`raft manual get recipes/<slug>\` when available.
|
|
14334
|
+
- Do not read, summarize, paste, or store provider API keys, raw tokens, secrets, or credential files.
|
|
14335
|
+
|
|
14336
|
+
## Branch Behaviors
|
|
14337
|
+
|
|
14338
|
+
### Owner says they already have workflows
|
|
14339
|
+
Ask for consent to scan local setup. If they say yes, use the setup-scan toolbox below. If they say no, mark setup scan \`skipped\`, note the refusal, and continue from what they tell you manually.
|
|
14340
|
+
|
|
14341
|
+
### Owner is fresh or describes current work
|
|
14342
|
+
Say: "Got it - for [work], here's who I'd start with:" Then prepare a Cody card for an engineering operator whose description is: "turns your ideas into working things: pages, tools, automations."
|
|
14343
|
+
|
|
14344
|
+
### Owner is hesitant or silent
|
|
14345
|
+
Offer a guided walk: one card-as-conversation per turn, always with an exit back to the main question.
|
|
14346
|
+
|
|
14347
|
+
## Setup-Scan Toolbox
|
|
14348
|
+
|
|
14349
|
+
Only use this after explicit consent. Skill names and versions are safe to read directly \u2014 that output carries no secrets. The one exception is the MCP config (\`~/.claude/settings.json\` / \`~/.claude.json\`): it can inline API keys in its \`env\` block, so read only the server names with \`jq\` (below) \u2014 never \`cat\` that file.
|
|
14350
|
+
|
|
14351
|
+
- MCP names: \`jq -r '.mcpServers|keys[]' ~/.claude/settings.json\`
|
|
14352
|
+
- Skill names: \`ls ~/.claude/skills/\`
|
|
14353
|
+
- Runtime versions: \`claude --version\` and \`codex --version\`
|
|
14354
|
+
|
|
14355
|
+
After scanning, post one echo line:
|
|
14356
|
+
|
|
14357
|
+
\`read: CC v_, MCP names [...], skill names [...] - nothing else.\`
|
|
14358
|
+
|
|
14359
|
+
Then post the conclusion only: inferred workflow shape + team proposal + how the agents would run. Share the raw list only if the owner asks.
|
|
14360
|
+
|
|
14361
|
+
## Seeded Practices
|
|
14362
|
+
|
|
14363
|
+
Read this once on first startup and bank it into MEMORY. These are the highest-frequency judgment calls and moves for working well on a human-agent team here. Each entry is the short version; when you hit the situation, pull the full card with \`raft manual get recipes/<slug>\`. Once Manual search is live, use \`raft manual search "<keywords>" --scope recipes\` to discover candidates, then \`raft manual get recipes/<slug>\` for the full card.
|
|
14364
|
+
|
|
14365
|
+
Evidence grade is on each full card (\`verified\` = proven by real runs; \`candidate\` = sound but not yet firsthand-proven). Trust \`verified\` cards; treat \`candidate\` as a strong default you can improve.
|
|
14366
|
+
|
|
14367
|
+
### decision/one-or-many - adding an agent
|
|
14368
|
+
Owner asks about adding an agent? The question is what the new agent should own, not whether it's allowed. A new agent earns its seat through one of five gains: independent verification, its own compounding memory for a domain, parallel attention, volume split by data, or blast-radius isolation. Design the lane by ownership or by data - never by pipeline step. The anti-pattern is not "too many agents"; it is agents without boundaries. Full card: \`raft manual get recipes/decision/one-or-many\`.
|
|
14369
|
+
|
|
14370
|
+
### decision/stake-strictness - how careful should this loop be
|
|
14371
|
+
Task touches money, prod, or a public surface? Stakes = irreversibility x audience x money. Low: do and report. Medium: stage behind a preview, owner approves. High: hold at send-zero until the owner approves the exact final artifact, then verify the exact bytes that shipped. Approval attaches to bytes, not intentions. Full card: \`raft manual get recipes/decision/stake-strictness\`.
|
|
14372
|
+
|
|
14373
|
+
### decision/when-to-ask-human - proceed or ask
|
|
14374
|
+
Proceed when reversible + in your lane + precedented. Ask when irreversible, out-of-lane, or preference-shaped with no precedent. Never block silently: do the reversible parts, stage the rest, ask ONE question with a staged artifact attached. Defaults ("I'll do X unless...") only for reversible things - irreversible waits for an explicit yes. Full card: \`raft manual get recipes/decision/when-to-ask-human\`.
|
|
14375
|
+
|
|
14376
|
+
### pattern/discuss-then-assign - several agents could take this
|
|
14377
|
+
More than one agent could take it? Claim before work - the claim is the lock. Ambiguous? One quick thread: lane owner wins ties, non-taker exits with one line, never silence. Claim scope = the message's scope; renegotiate additions. Hand over by observed delivery, not promises. Full card: \`raft manual get recipes/pattern/discuss-then-assign\`.
|
|
14378
|
+
|
|
14379
|
+
### technique/preview-env - let the owner see it running
|
|
14380
|
+
Change is easier to experience than to read about? Don't ask the owner to imagine it from a diff. Isolate the work-in-progress -> produce something the owner can open themselves (a URL, a rendered draft, a real report on sample data) -> seed it with realistic material (empty previews can't be judged) -> hold it alive until the owner confirms. Run the env manifest before handing over (build/flags/seed/reset/URL-reachable). Approval attaches to what ships, not to the preview - re-verify after merge. Full card: \`raft manual get recipes/technique/preview-env\`.
|
|
14381
|
+
|
|
14382
|
+
### technique/login-with-raft - auth for an internal tool
|
|
14383
|
+
Internal tool needs auth? Don't skip it, don't build accounts, don't paste tokens. Register the tool with the workspace, wire Login with Raft for humans, agent-login (\`raft integration login --service <service>\`) for agents - everyone authenticates as themselves, permissions follow membership. Internal-only-by-assumption is how tools leak; access control stays on. Full card: \`raft manual get recipes/technique/login-with-raft\`.
|
|
14384
|
+
|
|
14385
|
+
### pattern/evidence-handoff - hand off with evidence, not a status story
|
|
14386
|
+
Handing off work? Don't send a status story; send evidence. Say what changed, where it is, what proves it, what is still uncertain, and what should happen next. Use durable handles: task, thread, commit, preview URL, attachment ids, command names. Label placeholders and inference explicitly. Full card: \`raft manual get recipes/pattern/evidence-handoff\`.
|
|
14387
|
+
|
|
14388
|
+
### technique/reminder-cron - schedule a reminder, don't wait in-process
|
|
14389
|
+
Need to follow up later? Use a Raft reminder, not a sleeping process or a memory note. Anchor it to the task/thread, phrase it as the next action, and choose the earliest useful time. When it fires: read context, act, snooze/update/cancel. Memory helps you resume; reminders wake you. Full card: \`raft manual get recipes/technique/reminder-cron\`.
|
|
14390
|
+
|
|
14391
|
+
### technique/task-claim-lock - claim before you work
|
|
14392
|
+
Is this actual work (tools, edits, review, not just a reply)? Claim before the first tool call - the claim is the concurrency lock. Existing task number beats a duplicate task; regular work requests can be claimed by message id. If the claim fails, stop unless redirected. Report in the task thread and move to in_review when ready for validation. Full card: \`raft manual get recipes/technique/task-claim-lock\`.
|
|
14393
|
+
|
|
14394
|
+
### technique/sent-zero - never send until the owner approves the exact bytes
|
|
14395
|
+
Task ends in an external send (email/post/publish)? Stage it, don't send it. Build the exact final artifact, hold at send-count zero, and let the owner approve those exact bytes - only then ship, and log the receipt. Silence or a timeout is never consent for a send. Full card: \`raft manual get recipes/technique/sent-zero\`.
|
|
14396
|
+
|
|
14397
|
+
### pattern/recurring-recovery - recover a missed recurring run without a silent drop
|
|
14398
|
+
A recurring job (daily brief, sweep, scan) may have missed a run across a restart, sleep, or handover? "Fired" is not "ran": a reminder firing into a sleeping/restarting agent advances its clock and looks delivered while nothing happened. Recovery has two halves - an observable anchored reminder that carries where-you-are (memory resumes you, never wakes you), and a wake-time reconcile of the reminder's fired log against the real output surface. Found a gap? Backfill that window, labeled. Handing a cadence to another agent? Cut over on observed delivery, not a promise. Full card: \`raft manual get recipes/pattern/recurring-recovery\`.
|
|
14399
|
+
|
|
14400
|
+
### technique/video-review - async review via recorded walkthrough
|
|
14401
|
+
Owner wants to review your output without a live session? Post the deliverable, let the owner record a screen walkthrough - using it like a user, talking through reactions - and drop the recording in the working channel. Extract EVERY item from the video into a written fix list before acting; confirm the list back so nothing said on tape gets lost. Beats screenshot ping-pong: one recording carries tone, order, and context that ten annotated images can't. Full card: \`raft manual get recipes/technique/video-review\`.
|
|
14402
|
+
|
|
14403
|
+
### technique/html-artifact-discussion - discuss visuals as clickable artifacts, not text
|
|
14404
|
+
Visual idea going in circles in text? Build it, don't describe it: a self-contained HTML artifact the owner can open and click. Iterate version by version on the artifact itself; feedback anchors to what exists, not to imagination. Structure first - the beauty pass only after the direction locks. When it locks, the HTML source IS the spec you hand to the implementer, never just a screenshot. Full card: \`raft manual get recipes/technique/html-artifact-discussion\`.
|
|
14405
|
+
`;
|
|
14406
|
+
}
|
|
14214
14407
|
function buildInitialMemoryMd(config) {
|
|
14215
14408
|
const agentName = config.displayName || config.name;
|
|
14216
14409
|
const seedMode = getOnboardingSeedMode(config);
|
|
@@ -14230,18 +14423,18 @@ ${config.description || "No role defined yet."}
|
|
|
14230
14423
|
return `# ${agentName}
|
|
14231
14424
|
|
|
14232
14425
|
## Role
|
|
14233
|
-
You are Cindy, the onboarding
|
|
14426
|
+
You are Cindy, the Raft onboarding partner for this server.
|
|
14234
14427
|
Your mission is to help users start real human-agent collaboration quickly.
|
|
14235
14428
|
|
|
14236
14429
|
## Core Goals
|
|
14237
|
-
1. Help the server owner get comfortable working with
|
|
14430
|
+
1. Help the server owner get comfortable working with Raft in real work.
|
|
14238
14431
|
2. Help the owner set up this server for real execution:
|
|
14239
14432
|
- initial team target: at least 3 agents
|
|
14240
14433
|
- practical channels mapped to real workflows
|
|
14241
14434
|
3. If the user has no clear idea, proactively provide inspiration and one simple starter path.
|
|
14242
14435
|
|
|
14243
|
-
## What
|
|
14244
|
-
|
|
14436
|
+
## What Raft Is (Practical Definition)
|
|
14437
|
+
Raft is a workspace where humans and AI agents collaborate as a real team.
|
|
14245
14438
|
Agents are persistent teammates: they keep memory, work in shared channels/threads, claim tasks, and hand off work.
|
|
14246
14439
|
|
|
14247
14440
|
## Decision Principles
|
|
@@ -14265,6 +14458,7 @@ Many users skip onboarding-channel replies but are still active elsewhere; optim
|
|
|
14265
14458
|
## Knowledge Index
|
|
14266
14459
|
- [Onboarding Playbook](notes/onboarding_playbook.md)
|
|
14267
14460
|
- [Onboarding FAQ](notes/onboarding_knowledge_faq.md)
|
|
14461
|
+
- [Onboarding Objectives](notes/onboarding_objectives.md)
|
|
14268
14462
|
|
|
14269
14463
|
## Success Criteria
|
|
14270
14464
|
Success = user starts useful collaboration and setup progresses,
|
|
@@ -14754,9 +14948,19 @@ function buildRuntimeInputTraceAttrs(opts) {
|
|
|
14754
14948
|
runtime_input_session_present: opts.sessionIdPresent,
|
|
14755
14949
|
runtime_input_native_standing_prompt_present: opts.nativeStandingPrompt,
|
|
14756
14950
|
runtime_input_unread_channels_count: opts.unreadSummary ? Object.keys(opts.unreadSummary).length : 0,
|
|
14951
|
+
...attentionHintInputTraceAttrs(opts.messages),
|
|
14757
14952
|
...summarizeMessageInputBytes(opts.messages)
|
|
14758
14953
|
};
|
|
14759
14954
|
}
|
|
14955
|
+
function attentionHintInputTraceAttrs(messages) {
|
|
14956
|
+
const hints = messages?.map((message) => message.attention_hint).filter((hint) => Boolean(hint)) ?? [];
|
|
14957
|
+
if (hints.length === 0) return {};
|
|
14958
|
+
const triggers = [...new Set(hints.map((hint) => hint.trigger))].join(",");
|
|
14959
|
+
return {
|
|
14960
|
+
runtime_input_attention_hint_count: hints.length,
|
|
14961
|
+
runtime_input_attention_hint_triggers: triggers
|
|
14962
|
+
};
|
|
14963
|
+
}
|
|
14760
14964
|
function runtimeTraceCounterAttrs(ap) {
|
|
14761
14965
|
return {
|
|
14762
14966
|
runtime_events_count: ap.runtimeTraceCounters.events,
|
|
@@ -18963,12 +19167,14 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18963
19167
|
let threadTargetCount = 0;
|
|
18964
19168
|
let dmTargetCount = 0;
|
|
18965
19169
|
let taskTargetCount = 0;
|
|
19170
|
+
let attentionHintTargetCount = 0;
|
|
18966
19171
|
for (const row of rows) {
|
|
18967
19172
|
maxPendingCount = Math.max(maxPendingCount, row.pendingCount);
|
|
18968
19173
|
if (row.flags.includes("mention")) mentionTargetCount += 1;
|
|
18969
19174
|
if (row.flags.includes("thread")) threadTargetCount += 1;
|
|
18970
19175
|
if (row.flags.includes("dm")) dmTargetCount += 1;
|
|
18971
19176
|
if (row.flags.includes("task")) taskTargetCount += 1;
|
|
19177
|
+
if (row.attentionHint) attentionHintTargetCount += 1;
|
|
18972
19178
|
}
|
|
18973
19179
|
return {
|
|
18974
19180
|
target_count: rows.length,
|
|
@@ -18979,9 +19185,29 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18979
19185
|
mention_target_count: mentionTargetCount,
|
|
18980
19186
|
thread_target_count: threadTargetCount,
|
|
18981
19187
|
dm_target_count: dmTargetCount,
|
|
18982
|
-
task_target_count: taskTargetCount
|
|
19188
|
+
task_target_count: taskTargetCount,
|
|
19189
|
+
attention_hint_target_count: attentionHintTargetCount
|
|
18983
19190
|
};
|
|
18984
19191
|
}
|
|
19192
|
+
recordAttentionHintsShown(agentId, rows, source) {
|
|
19193
|
+
for (const row of rows) {
|
|
19194
|
+
const hint = row.attentionHint;
|
|
19195
|
+
if (!hint) continue;
|
|
19196
|
+
this.recordDaemonTrace("attention_hint_shown", {
|
|
19197
|
+
agentId,
|
|
19198
|
+
trigger: hint.trigger,
|
|
19199
|
+
scope: hint.scope,
|
|
19200
|
+
suggested_command: hint.suggested_command,
|
|
19201
|
+
copy_version: hint.copy_version,
|
|
19202
|
+
epoch_ms: Date.now(),
|
|
19203
|
+
source,
|
|
19204
|
+
target: row.target,
|
|
19205
|
+
K: hint.thresholds.K,
|
|
19206
|
+
k: hint.thresholds.k,
|
|
19207
|
+
window_ms: hint.thresholds.window_ms
|
|
19208
|
+
});
|
|
19209
|
+
}
|
|
19210
|
+
}
|
|
18985
19211
|
runtimeProfileTurnControlTraceAttrs(control) {
|
|
18986
19212
|
if (!control) return {};
|
|
18987
19213
|
const pendingAgeMs = Math.max(0, Date.now() - control.injectedAtMs);
|
|
@@ -20277,6 +20503,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
20277
20503
|
inbox_target_count: inboxRows.length,
|
|
20278
20504
|
session_id_present: true
|
|
20279
20505
|
});
|
|
20506
|
+
this.recordAttentionHintsShown(agentId, inboxRows, "busy_stdin_notification");
|
|
20280
20507
|
ap.notifications.recordNoticeWritten(noticeFingerprint, ap.sessionId, changedMessages);
|
|
20281
20508
|
return true;
|
|
20282
20509
|
} else {
|
|
@@ -20352,6 +20579,7 @@ ${RESPONSE_TARGET_HINT}`;
|
|
|
20352
20579
|
}
|
|
20353
20580
|
deliverInboxUpdateViaStdin(agentId, ap, messages, mode, source) {
|
|
20354
20581
|
if (messages.length === 0) return true;
|
|
20582
|
+
const rows = projectAgentInboxSnapshot(messages);
|
|
20355
20583
|
const prompt = this.formatInboxUpdateRuntimeInput(messages, ap.driver, ap.inbox.length);
|
|
20356
20584
|
const projectionAttrs = this.recordInboxUpdateProjection(agentId, ap, messages, source, mode, prompt, ap.inbox.length);
|
|
20357
20585
|
const inputTraceAttrs = buildRuntimeInputTraceAttrs({
|
|
@@ -20433,6 +20661,7 @@ ${RESPONSE_TARGET_HINT}`;
|
|
|
20433
20661
|
stdin_write_attempted: true,
|
|
20434
20662
|
cursors_advanced: "none"
|
|
20435
20663
|
});
|
|
20664
|
+
this.recordAttentionHintsShown(agentId, rows, source);
|
|
20436
20665
|
ap.notifications.recordNoticeWritten(computeInboxNoticeFingerprint(messages), ap.sessionId, messages);
|
|
20437
20666
|
this.closeActivationTransition(ap, "advanced", "stdin");
|
|
20438
20667
|
return true;
|
|
@@ -22429,7 +22658,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
|
|
|
22429
22658
|
}
|
|
22430
22659
|
async function runBundledSlockCli(argv) {
|
|
22431
22660
|
process.argv = [process.execPath, "slock", ...argv];
|
|
22432
|
-
await import("./dist-
|
|
22661
|
+
await import("./dist-UCGBT6NS.js");
|
|
22433
22662
|
}
|
|
22434
22663
|
function detectRuntimes(tracer = noopTracer) {
|
|
22435
22664
|
const ids = [];
|
package/dist/cli/index.js
CHANGED
|
@@ -42907,6 +42907,13 @@ function validateActionCardAction(action) {
|
|
|
42907
42907
|
|
|
42908
42908
|
// ../shared/src/agentApiContract.ts
|
|
42909
42909
|
init_esm_shims();
|
|
42910
|
+
|
|
42911
|
+
// ../shared/src/attentionDependencyOracle.ts
|
|
42912
|
+
init_esm_shims();
|
|
42913
|
+
var ATTENTION_HINT_SCHEMA = "attention-dependency-hint.v1";
|
|
42914
|
+
var ATTENTION_HINT_DEFAULT_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
42915
|
+
|
|
42916
|
+
// ../shared/src/agentApiContract.ts
|
|
42910
42917
|
var AGENT_API_BASE_PATH = "/internal/agent-api";
|
|
42911
42918
|
var optionalStringSchema = external_exports.string().trim().optional();
|
|
42912
42919
|
var optionalStringArraySchema = external_exports.array(external_exports.string().trim().min(1)).optional();
|
|
@@ -43433,8 +43440,17 @@ var agentApiSendResponseSchema = external_exports.discriminatedUnion("state", [
|
|
|
43433
43440
|
var agentApiMessageResolveResponseSchema = passthroughObject({
|
|
43434
43441
|
message: agentApiMessageEnvelopeSchema
|
|
43435
43442
|
});
|
|
43443
|
+
var agentApiChannelAttentionSchema = passthroughObject({
|
|
43444
|
+
state: optionalStringSchema,
|
|
43445
|
+
ordinaryActivity: optionalStringSchema,
|
|
43446
|
+
stillArrives: optionalStringArraySchema,
|
|
43447
|
+
threadBoundary: optionalStringSchema,
|
|
43448
|
+
manageCommand: optionalStringSchema,
|
|
43449
|
+
manageApi: optionalStringSchema
|
|
43450
|
+
});
|
|
43436
43451
|
var agentApiOkResponseSchema = passthroughObject({
|
|
43437
|
-
ok: external_exports.literal(true)
|
|
43452
|
+
ok: external_exports.literal(true),
|
|
43453
|
+
attention: agentApiChannelAttentionSchema.optional()
|
|
43438
43454
|
});
|
|
43439
43455
|
var agentApiSearchResultSchema = passthroughObject({
|
|
43440
43456
|
id: external_exports.string(),
|
|
@@ -43491,6 +43507,16 @@ var agentApiChannelMuteResponseSchema = passthroughObject({
|
|
|
43491
43507
|
catchUp: optionalStringSchema
|
|
43492
43508
|
}).optional()
|
|
43493
43509
|
});
|
|
43510
|
+
var agentApiChannelMuteBodySchema = passthroughObject({
|
|
43511
|
+
attentionHintAccepted: passthroughObject({
|
|
43512
|
+
schema: external_exports.literal(ATTENTION_HINT_SCHEMA),
|
|
43513
|
+
trigger: external_exports.enum(["M2", "M3"]),
|
|
43514
|
+
scope: external_exports.string().trim().min(1),
|
|
43515
|
+
suggested_command: optionalStringSchema,
|
|
43516
|
+
copy_version: external_exports.string().trim().min(1),
|
|
43517
|
+
epoch_ms: external_exports.number().int().nonnegative()
|
|
43518
|
+
}).optional()
|
|
43519
|
+
});
|
|
43494
43520
|
var agentApiTaskClaimResultSchema = passthroughObject({
|
|
43495
43521
|
taskNumber: external_exports.number().int().positive().optional(),
|
|
43496
43522
|
messageId: optionalStringSchema,
|
|
@@ -43700,7 +43726,7 @@ var agentApiContract = {
|
|
|
43700
43726
|
client: { resource: "channels", method: "mute" },
|
|
43701
43727
|
capability: "channels",
|
|
43702
43728
|
description: "Mute ordinary activity delivery for a visible regular channel as the bound agent credential.",
|
|
43703
|
-
request: { params: agentApiChannelMembershipParamsSchema },
|
|
43729
|
+
request: { params: agentApiChannelMembershipParamsSchema, body: agentApiChannelMuteBodySchema },
|
|
43704
43730
|
response: { body: agentApiChannelMuteResponseSchema }
|
|
43705
43731
|
}),
|
|
43706
43732
|
channelUnmute: route({
|
|
@@ -44352,6 +44378,20 @@ var optionalQueryIntSchema = external_exports.union([external_exports.number().i
|
|
|
44352
44378
|
var nullableNumberSchema2 = external_exports.number().finite().nullable();
|
|
44353
44379
|
var passthroughObject2 = (shape) => external_exports.object(shape).passthrough();
|
|
44354
44380
|
var daemonApiInboxFlagSchema = external_exports.enum(["mention", "thread", "dm", "task"]);
|
|
44381
|
+
var daemonApiAttentionHintSchema = passthroughObject2({
|
|
44382
|
+
schema: external_exports.literal(ATTENTION_HINT_SCHEMA),
|
|
44383
|
+
trigger: external_exports.enum(["M2", "M3"]),
|
|
44384
|
+
scope: external_exports.string().trim().min(1),
|
|
44385
|
+
suggested_command: external_exports.string().trim().min(1),
|
|
44386
|
+
copy: external_exports.string().trim().min(1),
|
|
44387
|
+
copy_version: external_exports.literal("attention-hint-copy-v1"),
|
|
44388
|
+
epoch_ms: external_exports.number().int().nonnegative(),
|
|
44389
|
+
thresholds: passthroughObject2({
|
|
44390
|
+
K: optionalNonNegativeIntSchema,
|
|
44391
|
+
k: optionalNonNegativeIntSchema,
|
|
44392
|
+
window_ms: external_exports.number().int().positive()
|
|
44393
|
+
})
|
|
44394
|
+
});
|
|
44355
44395
|
var daemonApiInboxTargetRowSchema = passthroughObject2({
|
|
44356
44396
|
target: external_exports.string().trim().min(1),
|
|
44357
44397
|
channelId: optionalStringSchema2,
|
|
@@ -44362,8 +44402,9 @@ var daemonApiInboxTargetRowSchema = passthroughObject2({
|
|
|
44362
44402
|
latestMsgId: optionalStringSchema2,
|
|
44363
44403
|
latestSeq: optionalNonNegativeIntSchema,
|
|
44364
44404
|
latestSenderName: optionalStringSchema2,
|
|
44365
|
-
latestSenderType: external_exports.enum(["human", "agent", "system"]).optional(),
|
|
44366
|
-
flags: external_exports.array(daemonApiInboxFlagSchema)
|
|
44405
|
+
latestSenderType: external_exports.enum(["human", "agent", "system", "third_party_app"]).optional(),
|
|
44406
|
+
flags: external_exports.array(daemonApiInboxFlagSchema),
|
|
44407
|
+
attentionHint: daemonApiAttentionHintSchema.optional()
|
|
44367
44408
|
});
|
|
44368
44409
|
var daemonApiInboxCheckResponseSchema = passthroughObject2({
|
|
44369
44410
|
rows: external_exports.array(daemonApiInboxTargetRowSchema).optional()
|
|
@@ -44386,6 +44427,7 @@ var daemonApiWakeHintSchema = passthroughObject2({
|
|
|
44386
44427
|
target_type: optionalStringSchema2,
|
|
44387
44428
|
reason: optionalStringSchema2,
|
|
44388
44429
|
wake_reason: optionalStringSchema2,
|
|
44430
|
+
attention_hint: daemonApiAttentionHintSchema.optional(),
|
|
44389
44431
|
createdAt: optionalStringSchema2,
|
|
44390
44432
|
created_at: optionalStringSchema2
|
|
44391
44433
|
});
|
|
@@ -44741,6 +44783,7 @@ function formatAgentInboxRowDetails(row) {
|
|
|
44741
44783
|
if (row.latestSenderName) parts.push(`latest sender @${row.latestSenderName}`);
|
|
44742
44784
|
if (row.latestMsgId) parts.push(`latest msg=${shortMessageId(row.latestMsgId)}`);
|
|
44743
44785
|
parts.push(...row.flags.map(formatAgentInboxFlag));
|
|
44786
|
+
if (row.attentionHint) parts.push(`attention_hint=${formatAttentionHintField(row.attentionHint)}`);
|
|
44744
44787
|
return parts.join(" \xB7 ");
|
|
44745
44788
|
}
|
|
44746
44789
|
function formatAgentInboxFlag(flag) {
|
|
@@ -44750,6 +44793,18 @@ function formatAgentInboxFlag(flag) {
|
|
|
44750
44793
|
function shortMessageId(value) {
|
|
44751
44794
|
return value.slice(0, 8);
|
|
44752
44795
|
}
|
|
44796
|
+
function formatAttentionHintField(hint) {
|
|
44797
|
+
return JSON.stringify({
|
|
44798
|
+
schema: hint.schema,
|
|
44799
|
+
trigger: hint.trigger,
|
|
44800
|
+
scope: hint.scope,
|
|
44801
|
+
suggested_command: hint.suggested_command,
|
|
44802
|
+
copy: hint.copy,
|
|
44803
|
+
copy_version: hint.copy_version,
|
|
44804
|
+
epoch_ms: hint.epoch_ms,
|
|
44805
|
+
thresholds: hint.thresholds
|
|
44806
|
+
});
|
|
44807
|
+
}
|
|
44753
44808
|
|
|
44754
44809
|
// ../shared/src/externalAgentIntegration.ts
|
|
44755
44810
|
init_esm_shims();
|
|
@@ -45146,9 +45201,9 @@ function isExternalAgentRuntime(runtime) {
|
|
|
45146
45201
|
return runtime === EXTERNAL_AGENT_RUNTIME_ID;
|
|
45147
45202
|
}
|
|
45148
45203
|
var RUNTIMES = [
|
|
45149
|
-
{ id: "builtin", displayName: "Built-in", binary: "", supported: true },
|
|
45150
45204
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
45151
45205
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
45206
|
+
{ id: "builtin", displayName: "Builtin Pi", binary: "", supported: true },
|
|
45152
45207
|
{ id: "antigravity", displayName: "Antigravity CLI", binary: "agy", supported: true },
|
|
45153
45208
|
// Kimi: prefer the in-process SDK (`kimi-sdk` → "Kimi Code") for new agents.
|
|
45154
45209
|
// The legacy `kimi` (kimi-cli child-process) entry stays for backward compat
|
|
@@ -45536,7 +45591,7 @@ function createAgentApiSurfaceClient(client) {
|
|
|
45536
45591
|
channels: {
|
|
45537
45592
|
join: (params) => requestClientAsApiResponse(agentApi.channels.join(params)),
|
|
45538
45593
|
leave: (params) => requestClientAsApiResponse(agentApi.channels.leave(params)),
|
|
45539
|
-
mute: (params) => requestClientAsApiResponse(agentApi.channels.mute(params)),
|
|
45594
|
+
mute: (params) => requestClientAsApiResponse(agentApi.channels.mute(params, {})),
|
|
45540
45595
|
unmute: (params) => requestClientAsApiResponse(agentApi.channels.unmute(params)),
|
|
45541
45596
|
members: (query) => requestClientAsApiResponse(agentApi.channels.members(query)),
|
|
45542
45597
|
resolve: (body) => requestClientAsApiResponse(agentApi.channels.resolve(body))
|
|
@@ -46287,8 +46342,16 @@ function registerCliCommand(parent, command, runtimeOptions = {}) {
|
|
|
46287
46342
|
child.argument(arg);
|
|
46288
46343
|
}
|
|
46289
46344
|
for (const option of command.spec.options ?? []) {
|
|
46345
|
+
const commanderOption = option.hidden ? new Option(option.flags, option.description).hideHelp() : null;
|
|
46290
46346
|
if (option.parse) {
|
|
46291
|
-
|
|
46347
|
+
if (commanderOption) {
|
|
46348
|
+
commanderOption.argParser(option.parse);
|
|
46349
|
+
child.addOption(commanderOption);
|
|
46350
|
+
} else {
|
|
46351
|
+
child.option(option.flags, option.description, option.parse);
|
|
46352
|
+
}
|
|
46353
|
+
} else if (commanderOption) {
|
|
46354
|
+
child.addOption(commanderOption);
|
|
46292
46355
|
} else {
|
|
46293
46356
|
child.option(option.flags, option.description);
|
|
46294
46357
|
}
|
|
@@ -48858,8 +48921,19 @@ function parseRegularChannelTarget(target) {
|
|
|
48858
48921
|
const name = target.slice(1).trim();
|
|
48859
48922
|
return name.length > 0 ? name : null;
|
|
48860
48923
|
}
|
|
48861
|
-
function formatLeaveChannelResult(target) {
|
|
48862
|
-
|
|
48924
|
+
function formatLeaveChannelResult(target, result2) {
|
|
48925
|
+
const lines = [
|
|
48926
|
+
`Left ${target}. You can still inspect visible public channel history there, but you can no longer send or receive ordinary channel delivery until you join the public channel again or a human re-adds you to a private channel.`
|
|
48927
|
+
];
|
|
48928
|
+
if (result2?.attention?.ordinaryActivity) lines.push(result2.attention.ordinaryActivity);
|
|
48929
|
+
if (result2?.attention?.stillArrives?.length) {
|
|
48930
|
+
lines.push("Still arrives:");
|
|
48931
|
+
for (const item of result2.attention.stillArrives) lines.push(`- ${item}`);
|
|
48932
|
+
}
|
|
48933
|
+
if (result2?.attention?.threadBoundary) lines.push(result2.attention.threadBoundary);
|
|
48934
|
+
if (result2?.attention?.manageCommand) lines.push(`To stop a followed thread: ${result2.attention.manageCommand}`);
|
|
48935
|
+
if (result2?.attention?.manageApi) lines.push(`Agent API: ${result2.attention.manageApi}`);
|
|
48936
|
+
return lines.join("\n");
|
|
48863
48937
|
}
|
|
48864
48938
|
function formatAlreadyNotJoined(target) {
|
|
48865
48939
|
return `Already not joined in ${target}.`;
|
|
@@ -48914,7 +48988,7 @@ var channelLeaveCommand = defineCommand(
|
|
|
48914
48988
|
message: leaveRes.error ?? `HTTP ${leaveRes.status}`
|
|
48915
48989
|
});
|
|
48916
48990
|
}
|
|
48917
|
-
writeText(ctx.io, formatLeaveChannelResult(target) + "\n");
|
|
48991
|
+
writeText(ctx.io, formatLeaveChannelResult(target, leaveRes.data ?? void 0) + "\n");
|
|
48918
48992
|
}
|
|
48919
48993
|
);
|
|
48920
48994
|
function registerChannelLeaveCommand(parent, runtimeOptions) {
|
|
@@ -49228,9 +49302,19 @@ init_esm_shims();
|
|
|
49228
49302
|
function normalizeHandle2(raw) {
|
|
49229
49303
|
return (raw ?? "").trim().replace(/^@/, "");
|
|
49230
49304
|
}
|
|
49231
|
-
function formatRemoveMemberResult(target, memberName, wasMember) {
|
|
49305
|
+
function formatRemoveMemberResult(target, memberName, wasMember, result2) {
|
|
49232
49306
|
const member = `@${memberName}`;
|
|
49233
|
-
|
|
49307
|
+
if (!wasMember) return `${member} was not in ${target}.`;
|
|
49308
|
+
const lines = [`Removed ${member} from ${target}.`];
|
|
49309
|
+
if (result2?.attention?.ordinaryActivity) lines.push(result2.attention.ordinaryActivity);
|
|
49310
|
+
if (result2?.attention?.stillArrives?.length) {
|
|
49311
|
+
lines.push("Still arrives:");
|
|
49312
|
+
for (const item of result2.attention.stillArrives) lines.push(`- ${item}`);
|
|
49313
|
+
}
|
|
49314
|
+
if (result2?.attention?.threadBoundary) lines.push(result2.attention.threadBoundary);
|
|
49315
|
+
if (result2?.attention?.manageCommand) lines.push(`To stop a followed thread: ${result2.attention.manageCommand}`);
|
|
49316
|
+
if (result2?.attention?.manageApi) lines.push(`Agent API: ${result2.attention.manageApi}`);
|
|
49317
|
+
return lines.join("\n");
|
|
49234
49318
|
}
|
|
49235
49319
|
var channelRemoveMemberCommand = defineCommand(
|
|
49236
49320
|
{
|
|
@@ -49300,7 +49384,7 @@ var channelRemoveMemberCommand = defineCommand(
|
|
|
49300
49384
|
});
|
|
49301
49385
|
}
|
|
49302
49386
|
const memberName = removeRes.data?.member?.name ?? (user || agent);
|
|
49303
|
-
writeText(ctx.io, formatRemoveMemberResult(target, memberName, removeRes.data?.wasMember === true) + "\n");
|
|
49387
|
+
writeText(ctx.io, formatRemoveMemberResult(target, memberName, removeRes.data?.wasMember === true, removeRes.data ?? void 0) + "\n");
|
|
49304
49388
|
}
|
|
49305
49389
|
);
|
|
49306
49390
|
function registerChannelRemoveMemberCommand(parent, runtimeOptions) {
|
|
@@ -50084,11 +50168,13 @@ var knowledgeGetCommand = defineCommand(
|
|
|
50084
50168
|
},
|
|
50085
50169
|
{
|
|
50086
50170
|
flags: "--turn-id <id>",
|
|
50087
|
-
description: "
|
|
50171
|
+
description: "Diagnostic: override the turn id recorded on the knowledge event",
|
|
50172
|
+
hidden: true
|
|
50088
50173
|
},
|
|
50089
50174
|
{
|
|
50090
50175
|
flags: "--trace-id <id>",
|
|
50091
|
-
description: "
|
|
50176
|
+
description: "Diagnostic: override the trace id recorded on the knowledge event",
|
|
50177
|
+
hidden: true
|
|
50092
50178
|
}
|
|
50093
50179
|
],
|
|
50094
50180
|
helpAfter: "\nTopics:\n Run `raft manual get index` to list available manual topics.\n"
|
|
@@ -50168,11 +50254,13 @@ var knowledgeSearchCommand = defineCommand(
|
|
|
50168
50254
|
},
|
|
50169
50255
|
{
|
|
50170
50256
|
flags: "--turn-id <id>",
|
|
50171
|
-
description: "
|
|
50257
|
+
description: "Diagnostic: override the turn id recorded on the knowledge event",
|
|
50258
|
+
hidden: true
|
|
50172
50259
|
},
|
|
50173
50260
|
{
|
|
50174
50261
|
flags: "--trace-id <id>",
|
|
50175
|
-
description: "
|
|
50262
|
+
description: "Diagnostic: override the trace id recorded on the knowledge event",
|
|
50263
|
+
hidden: true
|
|
50176
50264
|
}
|
|
50177
50265
|
],
|
|
50178
50266
|
helpAfter: '\nExamples:\n raft manual search "preview before merge" --scope recipes\n raft manual get recipes/technique/preview-env\n'
|
|
@@ -53436,6 +53524,15 @@ function safeUrl2(value, label) {
|
|
|
53436
53524
|
}
|
|
53437
53525
|
return url2;
|
|
53438
53526
|
}
|
|
53527
|
+
function substituteEndpointPathParams(endpointPath, payload) {
|
|
53528
|
+
return endpointPath.replace(/\{([A-Za-z][A-Za-z0-9_]*)\}/g, (_match, name) => {
|
|
53529
|
+
const value = payload[name];
|
|
53530
|
+
if (value === void 0 || value === null || value === "") {
|
|
53531
|
+
throw cliError("INVALID_ARG", `missing path parameter ${name}`);
|
|
53532
|
+
}
|
|
53533
|
+
return encodeURIComponent(typeof value === "string" ? value : JSON.stringify(value));
|
|
53534
|
+
});
|
|
53535
|
+
}
|
|
53439
53536
|
function resolveActionUrl(input) {
|
|
53440
53537
|
const base = input.manifest.execution.base_url ?? input.manifest.app_origin ?? input.service.homepageUrl ?? (input.service.returnUrl ? safeUrl2(input.service.returnUrl, "service return URL").origin : null);
|
|
53441
53538
|
if (!base) {
|
|
@@ -53445,7 +53542,7 @@ function resolveActionUrl(input) {
|
|
|
53445
53542
|
);
|
|
53446
53543
|
}
|
|
53447
53544
|
const baseUrl = safeUrl2(base, "action base URL");
|
|
53448
|
-
return new URL(input.action.endpoint.path, baseUrl);
|
|
53545
|
+
return new URL(substituteEndpointPathParams(input.action.endpoint.path, input.payload), baseUrl);
|
|
53449
53546
|
}
|
|
53450
53547
|
function appendPayloadAsQuery(url2, payload) {
|
|
53451
53548
|
for (const [key, value] of Object.entries(payload)) {
|
|
@@ -53453,6 +53550,13 @@ function appendPayloadAsQuery(url2, payload) {
|
|
|
53453
53550
|
url2.searchParams.set(key, typeof value === "string" ? value : JSON.stringify(value));
|
|
53454
53551
|
}
|
|
53455
53552
|
}
|
|
53553
|
+
function appendResourceLocatorQuery(input) {
|
|
53554
|
+
const { url: url2, action, payload } = input;
|
|
53555
|
+
if (/\{id\}/.test(action.endpoint.path)) return;
|
|
53556
|
+
const id = payload.id;
|
|
53557
|
+
if (id === void 0 || id === null || id === "" || url2.searchParams.has("id")) return;
|
|
53558
|
+
url2.searchParams.set("id", typeof id === "string" ? id : JSON.stringify(id));
|
|
53559
|
+
}
|
|
53456
53560
|
async function invokeHttpAction(input) {
|
|
53457
53561
|
const url2 = new URL(input.url);
|
|
53458
53562
|
const cookie = cookieHeaderForUrl(input.cookies, url2);
|
|
@@ -53474,6 +53578,7 @@ async function invokeHttpAction(input) {
|
|
|
53474
53578
|
if (input.action.endpoint.method === "GET") {
|
|
53475
53579
|
appendPayloadAsQuery(url2, input.payload);
|
|
53476
53580
|
} else {
|
|
53581
|
+
appendResourceLocatorQuery({ url: url2, action: input.action, payload: input.payload });
|
|
53477
53582
|
headers["content-type"] = "application/json";
|
|
53478
53583
|
init.body = JSON.stringify(input.payload);
|
|
53479
53584
|
}
|
|
@@ -53530,6 +53635,9 @@ function formatActions(input) {
|
|
|
53530
53635
|
lines.push(` endpoint: ${action.endpoint.method} ${action.endpoint.path}`);
|
|
53531
53636
|
if (action.description) lines.push(` description: ${action.description}`);
|
|
53532
53637
|
if (required2.length > 0) lines.push(` required params: ${required2.join(", ")}`);
|
|
53638
|
+
if (action.endpoint.method !== "GET" && Object.hasOwn(action.parameters ?? {}, "id") && !/\{id\}/.test(action.endpoint.path)) {
|
|
53639
|
+
lines.push(" note: id is treated as the resource locator and is also sent as query ?id=; JSON body is preserved");
|
|
53640
|
+
}
|
|
53533
53641
|
}
|
|
53534
53642
|
lines.push(`next: raft integration invoke --service ${JSON.stringify(input.service.clientId)} --action ${JSON.stringify(actions[0]?.name ?? "<name>")}`);
|
|
53535
53643
|
return lines.join("\n");
|
|
@@ -53639,7 +53747,7 @@ var integrationInvokeCommand = defineCommand(
|
|
|
53639
53747
|
{ flags: "--list-actions", description: "List manifest actions instead of invoking one" },
|
|
53640
53748
|
{
|
|
53641
53749
|
flags: "--param <key=value>",
|
|
53642
|
-
description: "Action parameter; repeatable. Use key=@file or key=@- to read text",
|
|
53750
|
+
description: "Action parameter; repeatable. Use key=@file or key=@- to read text. For non-GET actions, id is also sent as query ?id= when the manifest path has no {id}",
|
|
53643
53751
|
parse: (value, previous = []) => {
|
|
53644
53752
|
previous.push(value);
|
|
53645
53753
|
return previous;
|
|
@@ -53767,7 +53875,7 @@ var integrationInvokeCommand = defineCommand(
|
|
|
53767
53875
|
});
|
|
53768
53876
|
cookies = session.cookies;
|
|
53769
53877
|
}
|
|
53770
|
-
const url2 = resolveActionUrl({ service, manifest, action });
|
|
53878
|
+
const url2 = resolveActionUrl({ service, manifest, action, payload });
|
|
53771
53879
|
const result2 = await invokeHttpAction({ url: url2, action, payload, cookies, service });
|
|
53772
53880
|
if (opts.json) {
|
|
53773
53881
|
writeJson(cmdCtx.io, {
|
|
@@ -54383,7 +54491,10 @@ registerServerInfoCommand(serverCmd);
|
|
|
54383
54491
|
registerServerUpdateCommand(serverCmd);
|
|
54384
54492
|
var userCmd = program2.command("user").description("User and agent introspection");
|
|
54385
54493
|
registerUserInfoCommand(userCmd);
|
|
54386
|
-
var manualCmd = program2.command("manual").description("
|
|
54494
|
+
var manualCmd = program2.command("manual").description("Look up Raft operating topics and agent recipes").addHelpText(
|
|
54495
|
+
"after",
|
|
54496
|
+
'\nCommon agent flows:\n raft manual get index\n raft manual get recipes/seeded\n raft manual get recipes/technique/preview-env\n raft manual search "preview before merge" --scope recipes\n\nUse `raft manual get --help` and `raft manual search --help` for options.\n'
|
|
54497
|
+
);
|
|
54387
54498
|
registerKnowledgeGetCommand(manualCmd);
|
|
54388
54499
|
registerKnowledgeSearchCommand(manualCmd);
|
|
54389
54500
|
var knowledgeCmd = program2.command("knowledge").description("Legacy alias for `raft manual`");
|
package/dist/cli/package.json
CHANGED
package/dist/core.js
CHANGED
|
@@ -42463,6 +42463,9 @@ function validateActionCardAction(action) {
|
|
|
42463
42463
|
return null;
|
|
42464
42464
|
}
|
|
42465
42465
|
init_esm_shims();
|
|
42466
|
+
init_esm_shims();
|
|
42467
|
+
var ATTENTION_HINT_SCHEMA = "attention-dependency-hint.v1";
|
|
42468
|
+
var ATTENTION_HINT_DEFAULT_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
42466
42469
|
var AGENT_API_BASE_PATH = "/internal/agent-api";
|
|
42467
42470
|
var optionalStringSchema = external_exports.string().trim().optional();
|
|
42468
42471
|
var optionalStringArraySchema = external_exports.array(external_exports.string().trim().min(1)).optional();
|
|
@@ -42989,8 +42992,17 @@ var agentApiSendResponseSchema = external_exports.discriminatedUnion("state", [
|
|
|
42989
42992
|
var agentApiMessageResolveResponseSchema = passthroughObject({
|
|
42990
42993
|
message: agentApiMessageEnvelopeSchema
|
|
42991
42994
|
});
|
|
42995
|
+
var agentApiChannelAttentionSchema = passthroughObject({
|
|
42996
|
+
state: optionalStringSchema,
|
|
42997
|
+
ordinaryActivity: optionalStringSchema,
|
|
42998
|
+
stillArrives: optionalStringArraySchema,
|
|
42999
|
+
threadBoundary: optionalStringSchema,
|
|
43000
|
+
manageCommand: optionalStringSchema,
|
|
43001
|
+
manageApi: optionalStringSchema
|
|
43002
|
+
});
|
|
42992
43003
|
var agentApiOkResponseSchema = passthroughObject({
|
|
42993
|
-
ok: external_exports.literal(true)
|
|
43004
|
+
ok: external_exports.literal(true),
|
|
43005
|
+
attention: agentApiChannelAttentionSchema.optional()
|
|
42994
43006
|
});
|
|
42995
43007
|
var agentApiSearchResultSchema = passthroughObject({
|
|
42996
43008
|
id: external_exports.string(),
|
|
@@ -43047,6 +43059,16 @@ var agentApiChannelMuteResponseSchema = passthroughObject({
|
|
|
43047
43059
|
catchUp: optionalStringSchema
|
|
43048
43060
|
}).optional()
|
|
43049
43061
|
});
|
|
43062
|
+
var agentApiChannelMuteBodySchema = passthroughObject({
|
|
43063
|
+
attentionHintAccepted: passthroughObject({
|
|
43064
|
+
schema: external_exports.literal(ATTENTION_HINT_SCHEMA),
|
|
43065
|
+
trigger: external_exports.enum(["M2", "M3"]),
|
|
43066
|
+
scope: external_exports.string().trim().min(1),
|
|
43067
|
+
suggested_command: optionalStringSchema,
|
|
43068
|
+
copy_version: external_exports.string().trim().min(1),
|
|
43069
|
+
epoch_ms: external_exports.number().int().nonnegative()
|
|
43070
|
+
}).optional()
|
|
43071
|
+
});
|
|
43050
43072
|
var agentApiTaskClaimResultSchema = passthroughObject({
|
|
43051
43073
|
taskNumber: external_exports.number().int().positive().optional(),
|
|
43052
43074
|
messageId: optionalStringSchema,
|
|
@@ -43256,7 +43278,7 @@ var agentApiContract = {
|
|
|
43256
43278
|
client: { resource: "channels", method: "mute" },
|
|
43257
43279
|
capability: "channels",
|
|
43258
43280
|
description: "Mute ordinary activity delivery for a visible regular channel as the bound agent credential.",
|
|
43259
|
-
request: { params: agentApiChannelMembershipParamsSchema },
|
|
43281
|
+
request: { params: agentApiChannelMembershipParamsSchema, body: agentApiChannelMuteBodySchema },
|
|
43260
43282
|
response: { body: agentApiChannelMuteResponseSchema }
|
|
43261
43283
|
}),
|
|
43262
43284
|
channelUnmute: route({
|
|
@@ -43902,6 +43924,20 @@ var optionalQueryIntSchema = external_exports.union([external_exports.number().i
|
|
|
43902
43924
|
var nullableNumberSchema2 = external_exports.number().finite().nullable();
|
|
43903
43925
|
var passthroughObject2 = (shape) => external_exports.object(shape).passthrough();
|
|
43904
43926
|
var daemonApiInboxFlagSchema = external_exports.enum(["mention", "thread", "dm", "task"]);
|
|
43927
|
+
var daemonApiAttentionHintSchema = passthroughObject2({
|
|
43928
|
+
schema: external_exports.literal(ATTENTION_HINT_SCHEMA),
|
|
43929
|
+
trigger: external_exports.enum(["M2", "M3"]),
|
|
43930
|
+
scope: external_exports.string().trim().min(1),
|
|
43931
|
+
suggested_command: external_exports.string().trim().min(1),
|
|
43932
|
+
copy: external_exports.string().trim().min(1),
|
|
43933
|
+
copy_version: external_exports.literal("attention-hint-copy-v1"),
|
|
43934
|
+
epoch_ms: external_exports.number().int().nonnegative(),
|
|
43935
|
+
thresholds: passthroughObject2({
|
|
43936
|
+
K: optionalNonNegativeIntSchema,
|
|
43937
|
+
k: optionalNonNegativeIntSchema,
|
|
43938
|
+
window_ms: external_exports.number().int().positive()
|
|
43939
|
+
})
|
|
43940
|
+
});
|
|
43905
43941
|
var daemonApiInboxTargetRowSchema = passthroughObject2({
|
|
43906
43942
|
target: external_exports.string().trim().min(1),
|
|
43907
43943
|
channelId: optionalStringSchema2,
|
|
@@ -43912,8 +43948,9 @@ var daemonApiInboxTargetRowSchema = passthroughObject2({
|
|
|
43912
43948
|
latestMsgId: optionalStringSchema2,
|
|
43913
43949
|
latestSeq: optionalNonNegativeIntSchema,
|
|
43914
43950
|
latestSenderName: optionalStringSchema2,
|
|
43915
|
-
latestSenderType: external_exports.enum(["human", "agent", "system"]).optional(),
|
|
43916
|
-
flags: external_exports.array(daemonApiInboxFlagSchema)
|
|
43951
|
+
latestSenderType: external_exports.enum(["human", "agent", "system", "third_party_app"]).optional(),
|
|
43952
|
+
flags: external_exports.array(daemonApiInboxFlagSchema),
|
|
43953
|
+
attentionHint: daemonApiAttentionHintSchema.optional()
|
|
43917
43954
|
});
|
|
43918
43955
|
var daemonApiInboxCheckResponseSchema = passthroughObject2({
|
|
43919
43956
|
rows: external_exports.array(daemonApiInboxTargetRowSchema).optional()
|
|
@@ -43936,6 +43973,7 @@ var daemonApiWakeHintSchema = passthroughObject2({
|
|
|
43936
43973
|
target_type: optionalStringSchema2,
|
|
43937
43974
|
reason: optionalStringSchema2,
|
|
43938
43975
|
wake_reason: optionalStringSchema2,
|
|
43976
|
+
attention_hint: daemonApiAttentionHintSchema.optional(),
|
|
43939
43977
|
createdAt: optionalStringSchema2,
|
|
43940
43978
|
created_at: optionalStringSchema2
|
|
43941
43979
|
});
|
|
@@ -44283,6 +44321,7 @@ function formatAgentInboxRowDetails(row) {
|
|
|
44283
44321
|
if (row.latestSenderName) parts.push(`latest sender @${row.latestSenderName}`);
|
|
44284
44322
|
if (row.latestMsgId) parts.push(`latest msg=${shortMessageId(row.latestMsgId)}`);
|
|
44285
44323
|
parts.push(...row.flags.map(formatAgentInboxFlag));
|
|
44324
|
+
if (row.attentionHint) parts.push(`attention_hint=${formatAttentionHintField(row.attentionHint)}`);
|
|
44286
44325
|
return parts.join(" \xB7 ");
|
|
44287
44326
|
}
|
|
44288
44327
|
function formatAgentInboxFlag(flag) {
|
|
@@ -44292,6 +44331,18 @@ function formatAgentInboxFlag(flag) {
|
|
|
44292
44331
|
function shortMessageId(value) {
|
|
44293
44332
|
return value.slice(0, 8);
|
|
44294
44333
|
}
|
|
44334
|
+
function formatAttentionHintField(hint) {
|
|
44335
|
+
return JSON.stringify({
|
|
44336
|
+
schema: hint.schema,
|
|
44337
|
+
trigger: hint.trigger,
|
|
44338
|
+
scope: hint.scope,
|
|
44339
|
+
suggested_command: hint.suggested_command,
|
|
44340
|
+
copy: hint.copy,
|
|
44341
|
+
copy_version: hint.copy_version,
|
|
44342
|
+
epoch_ms: hint.epoch_ms,
|
|
44343
|
+
thresholds: hint.thresholds
|
|
44344
|
+
});
|
|
44345
|
+
}
|
|
44295
44346
|
init_esm_shims();
|
|
44296
44347
|
var EXTERNAL_AGENT_COMMS_PROTOCOL_VERSION = "agent-comms-core.v1";
|
|
44297
44348
|
var EXTERNAL_AGENT_PROOF_SCHEMA_VERSION = "agent-proof.v1";
|
|
@@ -44664,9 +44715,9 @@ function isExternalAgentRuntime(runtime) {
|
|
|
44664
44715
|
return runtime === EXTERNAL_AGENT_RUNTIME_ID;
|
|
44665
44716
|
}
|
|
44666
44717
|
var RUNTIMES = [
|
|
44667
|
-
{ id: "builtin", displayName: "Built-in", binary: "", supported: true },
|
|
44668
44718
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
44669
44719
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
44720
|
+
{ id: "builtin", displayName: "Builtin Pi", binary: "", supported: true },
|
|
44670
44721
|
{ id: "antigravity", displayName: "Antigravity CLI", binary: "agy", supported: true },
|
|
44671
44722
|
// Kimi: prefer the in-process SDK (`kimi-sdk` → "Kimi Code") for new agents.
|
|
44672
44723
|
// The legacy `kimi` (kimi-cli child-process) entry stays for backward compat
|
|
@@ -45052,7 +45103,7 @@ function createAgentApiSurfaceClient(client) {
|
|
|
45052
45103
|
channels: {
|
|
45053
45104
|
join: (params) => requestClientAsApiResponse(agentApi.channels.join(params)),
|
|
45054
45105
|
leave: (params) => requestClientAsApiResponse(agentApi.channels.leave(params)),
|
|
45055
|
-
mute: (params) => requestClientAsApiResponse(agentApi.channels.mute(params)),
|
|
45106
|
+
mute: (params) => requestClientAsApiResponse(agentApi.channels.mute(params, {})),
|
|
45056
45107
|
unmute: (params) => requestClientAsApiResponse(agentApi.channels.unmute(params)),
|
|
45057
45108
|
members: (query) => requestClientAsApiResponse(agentApi.channels.members(query)),
|
|
45058
45109
|
resolve: (body) => requestClientAsApiResponse(agentApi.channels.resolve(body))
|
|
@@ -45781,8 +45832,16 @@ function registerCliCommand(parent, command, runtimeOptions = {}) {
|
|
|
45781
45832
|
child.argument(arg);
|
|
45782
45833
|
}
|
|
45783
45834
|
for (const option of command.spec.options ?? []) {
|
|
45835
|
+
const commanderOption = option.hidden ? new Option(option.flags, option.description).hideHelp() : null;
|
|
45784
45836
|
if (option.parse) {
|
|
45785
|
-
|
|
45837
|
+
if (commanderOption) {
|
|
45838
|
+
commanderOption.argParser(option.parse);
|
|
45839
|
+
child.addOption(commanderOption);
|
|
45840
|
+
} else {
|
|
45841
|
+
child.option(option.flags, option.description, option.parse);
|
|
45842
|
+
}
|
|
45843
|
+
} else if (commanderOption) {
|
|
45844
|
+
child.addOption(commanderOption);
|
|
45786
45845
|
} else {
|
|
45787
45846
|
child.option(option.flags, option.description);
|
|
45788
45847
|
}
|
|
@@ -48312,8 +48371,19 @@ function parseRegularChannelTarget(target) {
|
|
|
48312
48371
|
const name = target.slice(1).trim();
|
|
48313
48372
|
return name.length > 0 ? name : null;
|
|
48314
48373
|
}
|
|
48315
|
-
function formatLeaveChannelResult(target) {
|
|
48316
|
-
|
|
48374
|
+
function formatLeaveChannelResult(target, result2) {
|
|
48375
|
+
const lines = [
|
|
48376
|
+
`Left ${target}. You can still inspect visible public channel history there, but you can no longer send or receive ordinary channel delivery until you join the public channel again or a human re-adds you to a private channel.`
|
|
48377
|
+
];
|
|
48378
|
+
if (result2?.attention?.ordinaryActivity) lines.push(result2.attention.ordinaryActivity);
|
|
48379
|
+
if (result2?.attention?.stillArrives?.length) {
|
|
48380
|
+
lines.push("Still arrives:");
|
|
48381
|
+
for (const item of result2.attention.stillArrives) lines.push(`- ${item}`);
|
|
48382
|
+
}
|
|
48383
|
+
if (result2?.attention?.threadBoundary) lines.push(result2.attention.threadBoundary);
|
|
48384
|
+
if (result2?.attention?.manageCommand) lines.push(`To stop a followed thread: ${result2.attention.manageCommand}`);
|
|
48385
|
+
if (result2?.attention?.manageApi) lines.push(`Agent API: ${result2.attention.manageApi}`);
|
|
48386
|
+
return lines.join("\n");
|
|
48317
48387
|
}
|
|
48318
48388
|
function formatAlreadyNotJoined(target) {
|
|
48319
48389
|
return `Already not joined in ${target}.`;
|
|
@@ -48368,7 +48438,7 @@ var channelLeaveCommand = defineCommand(
|
|
|
48368
48438
|
message: leaveRes.error ?? `HTTP ${leaveRes.status}`
|
|
48369
48439
|
});
|
|
48370
48440
|
}
|
|
48371
|
-
writeText(ctx.io, formatLeaveChannelResult(target) + "\n");
|
|
48441
|
+
writeText(ctx.io, formatLeaveChannelResult(target, leaveRes.data ?? void 0) + "\n");
|
|
48372
48442
|
}
|
|
48373
48443
|
);
|
|
48374
48444
|
function registerChannelLeaveCommand(parent, runtimeOptions) {
|
|
@@ -48672,9 +48742,19 @@ init_esm_shims();
|
|
|
48672
48742
|
function normalizeHandle2(raw) {
|
|
48673
48743
|
return (raw ?? "").trim().replace(/^@/, "");
|
|
48674
48744
|
}
|
|
48675
|
-
function formatRemoveMemberResult(target, memberName, wasMember) {
|
|
48745
|
+
function formatRemoveMemberResult(target, memberName, wasMember, result2) {
|
|
48676
48746
|
const member = `@${memberName}`;
|
|
48677
|
-
|
|
48747
|
+
if (!wasMember) return `${member} was not in ${target}.`;
|
|
48748
|
+
const lines = [`Removed ${member} from ${target}.`];
|
|
48749
|
+
if (result2?.attention?.ordinaryActivity) lines.push(result2.attention.ordinaryActivity);
|
|
48750
|
+
if (result2?.attention?.stillArrives?.length) {
|
|
48751
|
+
lines.push("Still arrives:");
|
|
48752
|
+
for (const item of result2.attention.stillArrives) lines.push(`- ${item}`);
|
|
48753
|
+
}
|
|
48754
|
+
if (result2?.attention?.threadBoundary) lines.push(result2.attention.threadBoundary);
|
|
48755
|
+
if (result2?.attention?.manageCommand) lines.push(`To stop a followed thread: ${result2.attention.manageCommand}`);
|
|
48756
|
+
if (result2?.attention?.manageApi) lines.push(`Agent API: ${result2.attention.manageApi}`);
|
|
48757
|
+
return lines.join("\n");
|
|
48678
48758
|
}
|
|
48679
48759
|
var channelRemoveMemberCommand = defineCommand(
|
|
48680
48760
|
{
|
|
@@ -48744,7 +48824,7 @@ var channelRemoveMemberCommand = defineCommand(
|
|
|
48744
48824
|
});
|
|
48745
48825
|
}
|
|
48746
48826
|
const memberName = removeRes.data?.member?.name ?? (user || agent);
|
|
48747
|
-
writeText(ctx.io, formatRemoveMemberResult(target, memberName, removeRes.data?.wasMember === true) + "\n");
|
|
48827
|
+
writeText(ctx.io, formatRemoveMemberResult(target, memberName, removeRes.data?.wasMember === true, removeRes.data ?? void 0) + "\n");
|
|
48748
48828
|
}
|
|
48749
48829
|
);
|
|
48750
48830
|
function registerChannelRemoveMemberCommand(parent, runtimeOptions) {
|
|
@@ -49506,11 +49586,13 @@ var knowledgeGetCommand = defineCommand(
|
|
|
49506
49586
|
},
|
|
49507
49587
|
{
|
|
49508
49588
|
flags: "--turn-id <id>",
|
|
49509
|
-
description: "
|
|
49589
|
+
description: "Diagnostic: override the turn id recorded on the knowledge event",
|
|
49590
|
+
hidden: true
|
|
49510
49591
|
},
|
|
49511
49592
|
{
|
|
49512
49593
|
flags: "--trace-id <id>",
|
|
49513
|
-
description: "
|
|
49594
|
+
description: "Diagnostic: override the trace id recorded on the knowledge event",
|
|
49595
|
+
hidden: true
|
|
49514
49596
|
}
|
|
49515
49597
|
],
|
|
49516
49598
|
helpAfter: "\nTopics:\n Run `raft manual get index` to list available manual topics.\n"
|
|
@@ -49588,11 +49670,13 @@ var knowledgeSearchCommand = defineCommand(
|
|
|
49588
49670
|
},
|
|
49589
49671
|
{
|
|
49590
49672
|
flags: "--turn-id <id>",
|
|
49591
|
-
description: "
|
|
49673
|
+
description: "Diagnostic: override the turn id recorded on the knowledge event",
|
|
49674
|
+
hidden: true
|
|
49592
49675
|
},
|
|
49593
49676
|
{
|
|
49594
49677
|
flags: "--trace-id <id>",
|
|
49595
|
-
description: "
|
|
49678
|
+
description: "Diagnostic: override the trace id recorded on the knowledge event",
|
|
49679
|
+
hidden: true
|
|
49596
49680
|
}
|
|
49597
49681
|
],
|
|
49598
49682
|
helpAfter: '\nExamples:\n raft manual search "preview before merge" --scope recipes\n raft manual get recipes/technique/preview-env\n'
|
|
@@ -52748,6 +52832,15 @@ function safeUrl2(value, label) {
|
|
|
52748
52832
|
}
|
|
52749
52833
|
return url2;
|
|
52750
52834
|
}
|
|
52835
|
+
function substituteEndpointPathParams(endpointPath, payload) {
|
|
52836
|
+
return endpointPath.replace(/\{([A-Za-z][A-Za-z0-9_]*)\}/g, (_match, name) => {
|
|
52837
|
+
const value = payload[name];
|
|
52838
|
+
if (value === void 0 || value === null || value === "") {
|
|
52839
|
+
throw cliError("INVALID_ARG", `missing path parameter ${name}`);
|
|
52840
|
+
}
|
|
52841
|
+
return encodeURIComponent(typeof value === "string" ? value : JSON.stringify(value));
|
|
52842
|
+
});
|
|
52843
|
+
}
|
|
52751
52844
|
function resolveActionUrl(input) {
|
|
52752
52845
|
const base = input.manifest.execution.base_url ?? input.manifest.app_origin ?? input.service.homepageUrl ?? (input.service.returnUrl ? safeUrl2(input.service.returnUrl, "service return URL").origin : null);
|
|
52753
52846
|
if (!base) {
|
|
@@ -52757,7 +52850,7 @@ function resolveActionUrl(input) {
|
|
|
52757
52850
|
);
|
|
52758
52851
|
}
|
|
52759
52852
|
const baseUrl = safeUrl2(base, "action base URL");
|
|
52760
|
-
return new URL(input.action.endpoint.path, baseUrl);
|
|
52853
|
+
return new URL(substituteEndpointPathParams(input.action.endpoint.path, input.payload), baseUrl);
|
|
52761
52854
|
}
|
|
52762
52855
|
function appendPayloadAsQuery(url2, payload) {
|
|
52763
52856
|
for (const [key, value] of Object.entries(payload)) {
|
|
@@ -52765,6 +52858,13 @@ function appendPayloadAsQuery(url2, payload) {
|
|
|
52765
52858
|
url2.searchParams.set(key, typeof value === "string" ? value : JSON.stringify(value));
|
|
52766
52859
|
}
|
|
52767
52860
|
}
|
|
52861
|
+
function appendResourceLocatorQuery(input) {
|
|
52862
|
+
const { url: url2, action, payload } = input;
|
|
52863
|
+
if (/\{id\}/.test(action.endpoint.path)) return;
|
|
52864
|
+
const id = payload.id;
|
|
52865
|
+
if (id === void 0 || id === null || id === "" || url2.searchParams.has("id")) return;
|
|
52866
|
+
url2.searchParams.set("id", typeof id === "string" ? id : JSON.stringify(id));
|
|
52867
|
+
}
|
|
52768
52868
|
async function invokeHttpAction(input) {
|
|
52769
52869
|
const url2 = new URL(input.url);
|
|
52770
52870
|
const cookie = cookieHeaderForUrl(input.cookies, url2);
|
|
@@ -52786,6 +52886,7 @@ async function invokeHttpAction(input) {
|
|
|
52786
52886
|
if (input.action.endpoint.method === "GET") {
|
|
52787
52887
|
appendPayloadAsQuery(url2, input.payload);
|
|
52788
52888
|
} else {
|
|
52889
|
+
appendResourceLocatorQuery({ url: url2, action: input.action, payload: input.payload });
|
|
52789
52890
|
headers["content-type"] = "application/json";
|
|
52790
52891
|
init.body = JSON.stringify(input.payload);
|
|
52791
52892
|
}
|
|
@@ -52842,6 +52943,9 @@ function formatActions(input) {
|
|
|
52842
52943
|
lines.push(` endpoint: ${action.endpoint.method} ${action.endpoint.path}`);
|
|
52843
52944
|
if (action.description) lines.push(` description: ${action.description}`);
|
|
52844
52945
|
if (required2.length > 0) lines.push(` required params: ${required2.join(", ")}`);
|
|
52946
|
+
if (action.endpoint.method !== "GET" && Object.hasOwn(action.parameters ?? {}, "id") && !/\{id\}/.test(action.endpoint.path)) {
|
|
52947
|
+
lines.push(" note: id is treated as the resource locator and is also sent as query ?id=; JSON body is preserved");
|
|
52948
|
+
}
|
|
52845
52949
|
}
|
|
52846
52950
|
lines.push(`next: raft integration invoke --service ${JSON.stringify(input.service.clientId)} --action ${JSON.stringify(actions[0]?.name ?? "<name>")}`);
|
|
52847
52951
|
return lines.join("\n");
|
|
@@ -52951,7 +53055,7 @@ var integrationInvokeCommand = defineCommand(
|
|
|
52951
53055
|
{ flags: "--list-actions", description: "List manifest actions instead of invoking one" },
|
|
52952
53056
|
{
|
|
52953
53057
|
flags: "--param <key=value>",
|
|
52954
|
-
description: "Action parameter; repeatable. Use key=@file or key=@- to read text",
|
|
53058
|
+
description: "Action parameter; repeatable. Use key=@file or key=@- to read text. For non-GET actions, id is also sent as query ?id= when the manifest path has no {id}",
|
|
52955
53059
|
parse: (value, previous = []) => {
|
|
52956
53060
|
previous.push(value);
|
|
52957
53061
|
return previous;
|
|
@@ -53079,7 +53183,7 @@ var integrationInvokeCommand = defineCommand(
|
|
|
53079
53183
|
});
|
|
53080
53184
|
cookies = session.cookies;
|
|
53081
53185
|
}
|
|
53082
|
-
const url2 = resolveActionUrl({ service, manifest, action });
|
|
53186
|
+
const url2 = resolveActionUrl({ service, manifest, action, payload });
|
|
53083
53187
|
const result2 = await invokeHttpAction({ url: url2, action, payload, cookies, service });
|
|
53084
53188
|
if (opts.json) {
|
|
53085
53189
|
writeJson(cmdCtx.io, {
|
|
@@ -53667,7 +53771,10 @@ registerServerInfoCommand(serverCmd);
|
|
|
53667
53771
|
registerServerUpdateCommand(serverCmd);
|
|
53668
53772
|
var userCmd = program2.command("user").description("User and agent introspection");
|
|
53669
53773
|
registerUserInfoCommand(userCmd);
|
|
53670
|
-
var manualCmd = program2.command("manual").description("
|
|
53774
|
+
var manualCmd = program2.command("manual").description("Look up Raft operating topics and agent recipes").addHelpText(
|
|
53775
|
+
"after",
|
|
53776
|
+
'\nCommon agent flows:\n raft manual get index\n raft manual get recipes/seeded\n raft manual get recipes/technique/preview-env\n raft manual search "preview before merge" --scope recipes\n\nUse `raft manual get --help` and `raft manual search --help` for options.\n'
|
|
53777
|
+
);
|
|
53671
53778
|
registerKnowledgeGetCommand(manualCmd);
|
|
53672
53779
|
registerKnowledgeSearchCommand(manualCmd);
|
|
53673
53780
|
var knowledgeCmd = program2.command("knowledge").description("Legacy alias for `raft manual`");
|
package/dist/index.js
CHANGED