flowviant 0.81.0 → 0.82.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.
@@ -458,6 +458,43 @@ const kickoff = ({ message, askedByName, head, tail }) => {
458
458
  return `${scaffold}${fence('WHAT THEY SAID', message)}\n\n${tail}`;
459
459
  };
460
460
 
461
+ /**
462
+ * A CAPTURE TAB (server: work_session.kind='capture', flagged on the job as
463
+ * `capture: true`) — the board's "New task" conversation. Its whole job is
464
+ * turning what the person says into STAGED cards a human lands; it edits
465
+ * nothing, and the permission profile enforces that (PLAN_PERM: read-only +
466
+ * MCP — the same fence the scratch planner runs behind). This prompt is the
467
+ * QUALITY half; the token scope and the permission list are the safety.
468
+ */
469
+ export const SYSTEM_CAPTURE = `You are the human's own Claude, in their repository, with ONE job: turn what
470
+ they say into well-cut task cards on their Flowviant board. You are READ-ONLY
471
+ here — read code freely to ground what you stage; the permission profile
472
+ refuses edits, and staging is the only write you have.
473
+
474
+ MECHANICS OF THIS CHAT:
475
+
476
+ 1. NARRATE WHILE YOU WORK. Call stream_session_turn with short progress lines
477
+ as you read and stage. Your FINAL reply is delivered automatically when the
478
+ turn ends — do not repeat it through the tool. Keep replies short: what you
479
+ staged, or what you need to know — one line each.
480
+ 2. STAGE, NEVER FILE. stage_card proposes a new card; stage_card_edit proposes
481
+ a change to an existing one (read_card first — never replace fields you
482
+ have not seen). Everything you stage waits in an area the person reviews
483
+ and lands themselves; nothing you do reaches the board directly.
484
+ 3. ONE CARD PER SHIPPABLE UNIT. Break a big ask into the units that will build
485
+ it, in landing order. Never card-ify chatter, questions, or one unit split
486
+ thin.
487
+ 4. DEDUPE FIRST, EVERY TIME. Before staging, call list_cards (the OPEN QUEUE —
488
+ capped, and cards agents already hold are absent from it) and list_staged
489
+ (what earlier chats left). If the work exists, say so and point at it;
490
+ stage_card_edit it if the ask adds something. Never stage a twin.
491
+ 5. CLARIFY BEFORE STAGING. A vague ask gets one or two sharp questions and a
492
+ wait — never a staged guess. A clear ask gets staged without ceremony.
493
+ 6. A GOOD CARD: a title naming the outcome, a brief a stranger could start
494
+ from, acceptance criteria only when the person stated (or the code shows)
495
+ what done means. No sizes, no owners, no statuses — none of those are
496
+ yours to set, here or anywhere.`;
497
+
461
498
  export const WORK_TURN_KICKOFF = ({ sessionId, sessionName, message, askedByName }) =>
462
499
  kickoff({
463
500
  message,
@@ -468,6 +505,19 @@ export const WORK_TURN_KICKOFF = ({ sessionId, sessionName, message, askedByName
468
505
  tail: `Stream your reply with stream_session_turn as you work.`,
469
506
  });
470
507
 
508
+ /** The capture chat's kickoff — the same shape as a work turn's, with the
509
+ * head restating the posture so the message is read as capture input even
510
+ * deep in a long conversation. */
511
+ export const CAPTURE_TURN_KICKOFF = ({ sessionId, sessionName, message, askedByName }) =>
512
+ kickoff({
513
+ message,
514
+ askedByName,
515
+ head:
516
+ `Continue the task-capture chat${sessionName ? ` "${sessionName}"` : ''} — stage cards, change nothing.\n\n` +
517
+ `SESSION ID (pass this to stream_session_turn / the staging tools): ${sessionId}`,
518
+ tail: `Stream your reply with stream_session_turn as you work.`,
519
+ });
520
+
471
521
  /** The plain tab's kickoff: no session id (there is no tool to pass it to)
472
522
  * and no streaming instruction — the final message is the reply. */
473
523
  export const WORK_TURN_KICKOFF_PLAIN = ({ sessionName, message, askedByName }) =>
package/bin/lib/work.mjs CHANGED
@@ -52,7 +52,9 @@ import { c, note, ok, warn } from './ui.mjs';
52
52
  import { mcpFor, runTurn } from './claude.mjs';
53
53
  import {
54
54
  SYSTEM_WORK,
55
+ SYSTEM_CAPTURE,
55
56
  WORK_TURN_KICKOFF,
57
+ CAPTURE_TURN_KICKOFF,
56
58
  SYSTEM_WORK_PLAIN,
57
59
  WORK_TURN_KICKOFF_PLAIN,
58
60
  SYSTEM_PLAN,
@@ -2982,6 +2984,14 @@ export function createWorkManager({
2982
2984
  const message = [job.body, filesNote, adoptNote, carryNote]
2983
2985
  .filter(Boolean)
2984
2986
  .join('\n\n');
2987
+ // A CAPTURE chat (the board's New task conversation): its own
2988
+ // system prompt, its own kickoff, and the scratch planner's
2989
+ // READ-ONLY permission profile — the prompt says stage-never-file
2990
+ // and the profile is what makes "read-only" true rather than
2991
+ // asserted. Server-flagged per job; a server too old to flag it
2992
+ // simply runs an ordinary tab, which the web's version floor
2993
+ // prevents ever being offered.
2994
+ const captureTab = job.capture === true;
2985
2995
  const turnArgs = {
2986
2996
  // A plain tab has no tools to name and no session id to pass —
2987
2997
  // its kickoff asks for one complete report instead of a stream.
@@ -2991,18 +3001,26 @@ export function createWorkManager({
2991
3001
  message,
2992
3002
  askedByName: job.askedByName,
2993
3003
  })
2994
- : WORK_TURN_KICKOFF({
3004
+ : captureTab
3005
+ ? CAPTURE_TURN_KICKOFF({
3006
+ sessionId: job.sessionId,
3007
+ sessionName: job.sessionName,
3008
+ message,
3009
+ askedByName: job.askedByName,
3010
+ })
3011
+ : WORK_TURN_KICKOFF({
2995
3012
  sessionId: job.sessionId,
2996
3013
  sessionName: job.sessionName,
2997
3014
  message,
2998
3015
  askedByName: job.askedByName,
2999
3016
  }),
3017
+ planPerm: captureTab,
3000
3018
  // The adopt turn resumes the TERMINAL conversation by forking it
3001
3019
  // into this cwd (claude: --resume <id> --fork-session). After it
3002
3020
  // speaks once, the fork lives natively here and turn 2+ is the
3003
3021
  // ordinary --continue resume path, unchanged.
3004
3022
  ...(adopting ? { adoptResumeId: job.adopt.id } : {}),
3005
- system: plainTab ? SYSTEM_WORK_PLAIN : SYSTEM_WORK,
3023
+ system: plainTab ? SYSTEM_WORK_PLAIN : captureTab ? SYSTEM_CAPTURE : SYSTEM_WORK,
3006
3024
  // Present only when the tab named one — see brainFor.
3007
3025
  ...brain,
3008
3026
  // The tab watches the CLI work. Claude needs the flag to speak
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowviant",
3
- "version": "0.81.0",
3
+ "version": "0.82.0",
4
4
  "description": "Run your own coding CLIs as build agents for Flowviant \u2014 Claude Code, Codex or Antigravity, on your own credentials. Holds your sessions, keeps a worktree per tab, and ships branches on your word.",
5
5
  "type": "module",
6
6
  "bin": {