@flowdular/sandbox 0.2.5 → 0.2.7
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/README.md +10 -0
- package/bin/flowdular-sandbox.mjs +62 -13
- package/internal/coding-agent/src/drivers/byok.ts +17 -3
- package/internal/coding-agent/src/drivers/claude-code.ts +36 -8
- package/internal/coding-agent/src/drivers/codex.ts +8 -0
- package/internal/coding-agent/src/roles/contract.ts +2 -1
- package/internal/coding-agent/src/roles/registry.ts +1 -7
- package/internal/coding-agent/src/types.ts +2 -0
- package/internal/coding-agent/src/workspace.ts +21 -5
- package/package.json +1 -1
- package/src/client/ChatPane.tsrx +77 -45
- package/src/client/ComposerSettings.tsrx +99 -0
- package/src/client/ToolEvent.tsrx +77 -0
- package/src/client/TurnActivity.tsrx +26 -0
- package/src/client/locales/en.json +21 -1
- package/src/client/locales/pl.json +21 -1
- package/src/client/transcript.ts +110 -0
- package/src/server/auto-review.ts +2 -1
- package/src/server/gate-repair.ts +88 -0
- package/src/server/planning.ts +15 -5
- package/src/server/preview-hot-updates.ts +40 -0
- package/src/server/reference.ts +1 -1
- package/src/server/reload-log.ts +68 -0
- package/src/server/turns.ts +23 -5
- package/src/styles.css +108 -6
- package/vite.config.ts +5 -1
package/src/server/turns.ts
CHANGED
|
@@ -688,14 +688,31 @@ export async function* runTurn(
|
|
|
688
688
|
);
|
|
689
689
|
|
|
690
690
|
const history = historyFrom(await readChat(context.workspaceRoot, session));
|
|
691
|
+
// Provider conversations retain instructions and tool history. Reuse one only
|
|
692
|
+
// while its role, module, skill, write ceiling, specification and model match.
|
|
693
|
+
const resumePrefix = `${driverId}:scope:`;
|
|
694
|
+
const resumeKey =
|
|
695
|
+
resumePrefix +
|
|
696
|
+
createHash('sha256')
|
|
697
|
+
.update(
|
|
698
|
+
JSON.stringify([
|
|
699
|
+
instruction,
|
|
700
|
+
active.specHash ?? null,
|
|
701
|
+
session.model ?? context.configuration.driverModel,
|
|
702
|
+
]),
|
|
703
|
+
)
|
|
704
|
+
.digest('hex');
|
|
705
|
+
const previousKeys = Object.keys(session.resumeIds).filter(
|
|
706
|
+
(key) => key === driverId || key.startsWith(resumePrefix),
|
|
707
|
+
);
|
|
691
708
|
const resumeId = input.freshContext
|
|
692
709
|
? null
|
|
693
|
-
: (session.resumeIds[
|
|
694
|
-
if (input.freshContext) {
|
|
710
|
+
: (session.resumeIds[resumeKey] ?? null);
|
|
711
|
+
if (input.freshContext || (!resumeId && previousKeys.length > 0)) {
|
|
695
712
|
yield await appendChatEntry(context.workspaceRoot, session, {
|
|
696
713
|
kind: 'system',
|
|
697
714
|
role: roleId,
|
|
698
|
-
text:
|
|
715
|
+
text: `Starting fresh agent context for ${role.name} in ${active.id} with the current task and write scope. Draft files, approved specification and sandbox history are preserved; the agent receives the brief and recent messages.`,
|
|
699
716
|
});
|
|
700
717
|
}
|
|
701
718
|
let nextResumeId = resumeId;
|
|
@@ -973,8 +990,9 @@ export async function* runTurn(
|
|
|
973
990
|
}
|
|
974
991
|
|
|
975
992
|
const resumeIds = { ...session.resumeIds };
|
|
976
|
-
|
|
977
|
-
|
|
993
|
+
// Retain at most one conversation per driver, including after many handoffs.
|
|
994
|
+
for (const key of previousKeys) delete resumeIds[key];
|
|
995
|
+
if (nextResumeId) resumeIds[resumeKey] = nextResumeId;
|
|
978
996
|
const updated = await updateSession(context.workspaceRoot, session.id, {
|
|
979
997
|
resumeIds,
|
|
980
998
|
state: failed
|
package/src/styles.css
CHANGED
|
@@ -683,13 +683,16 @@
|
|
|
683
683
|
color: var(--danger);
|
|
684
684
|
}
|
|
685
685
|
|
|
686
|
-
.
|
|
686
|
+
.chat-settings {
|
|
687
687
|
display: inline-flex;
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.chat-settings__panel {
|
|
691
|
+
position: fixed;
|
|
692
|
+
z-index: 20;
|
|
693
|
+
width: min(320px, calc(100vw - 32px));
|
|
694
|
+
max-height: calc(100dvh - 32px);
|
|
695
|
+
overflow-y: auto;
|
|
693
696
|
}
|
|
694
697
|
|
|
695
698
|
.chat__selection {
|
|
@@ -1571,3 +1574,102 @@
|
|
|
1571
1574
|
font-size: var(--text-md);
|
|
1572
1575
|
color: var(--ink-3);
|
|
1573
1576
|
}
|
|
1577
|
+
|
|
1578
|
+
@keyframes chat-activity-spin {
|
|
1579
|
+
to {
|
|
1580
|
+
transform: rotate(360deg);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
.chat__event--active > svg {
|
|
1584
|
+
animation: chat-activity-spin 1.5s linear infinite;
|
|
1585
|
+
}
|
|
1586
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1587
|
+
.chat__event--active > svg {
|
|
1588
|
+
animation: none;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
/* Compact operation summaries with the original details available on demand. */
|
|
1593
|
+
.chat-tool {
|
|
1594
|
+
min-width: 0;
|
|
1595
|
+
color: var(--ink-2);
|
|
1596
|
+
font-size: var(--text-sm);
|
|
1597
|
+
}
|
|
1598
|
+
.chat-tool__summary {
|
|
1599
|
+
display: flex;
|
|
1600
|
+
align-items: center;
|
|
1601
|
+
gap: 8px;
|
|
1602
|
+
min-width: 0;
|
|
1603
|
+
padding: 6px 0;
|
|
1604
|
+
cursor: pointer;
|
|
1605
|
+
list-style: none;
|
|
1606
|
+
}
|
|
1607
|
+
.chat-tool__summary::-webkit-details-marker {
|
|
1608
|
+
display: none;
|
|
1609
|
+
}
|
|
1610
|
+
.chat-tool__summary:focus-visible {
|
|
1611
|
+
outline: 2px solid var(--focus);
|
|
1612
|
+
outline-offset: 2px;
|
|
1613
|
+
}
|
|
1614
|
+
.chat-tool__summary > svg {
|
|
1615
|
+
flex-shrink: 0;
|
|
1616
|
+
}
|
|
1617
|
+
.chat-tool__action {
|
|
1618
|
+
flex-shrink: 0;
|
|
1619
|
+
}
|
|
1620
|
+
.chat-tool__target {
|
|
1621
|
+
min-width: 0;
|
|
1622
|
+
flex: 1;
|
|
1623
|
+
overflow: hidden;
|
|
1624
|
+
text-overflow: ellipsis;
|
|
1625
|
+
white-space: nowrap;
|
|
1626
|
+
font-family: var(--font-mono);
|
|
1627
|
+
}
|
|
1628
|
+
.chat-tool__status,
|
|
1629
|
+
.chat-tool__duration {
|
|
1630
|
+
color: var(--ink-3);
|
|
1631
|
+
flex-shrink: 0;
|
|
1632
|
+
font-variant-numeric: tabular-nums;
|
|
1633
|
+
}
|
|
1634
|
+
.chat-tool--failed .chat-tool__status,
|
|
1635
|
+
.chat-tool--failed .chat-tool__summary > svg:first-child {
|
|
1636
|
+
color: var(--danger);
|
|
1637
|
+
}
|
|
1638
|
+
.chat-tool[open] .chat-tool__summary > svg:last-child {
|
|
1639
|
+
transform: rotate(180deg);
|
|
1640
|
+
}
|
|
1641
|
+
.chat-tool__details {
|
|
1642
|
+
margin: 0 0 8px 22px;
|
|
1643
|
+
padding: 12px;
|
|
1644
|
+
border: 1px solid var(--line);
|
|
1645
|
+
border-radius: var(--r-sm);
|
|
1646
|
+
}
|
|
1647
|
+
.chat-tool__details dt {
|
|
1648
|
+
color: var(--ink-3);
|
|
1649
|
+
margin-bottom: 4px;
|
|
1650
|
+
}
|
|
1651
|
+
.chat-tool__details dd {
|
|
1652
|
+
margin: 0 0 8px;
|
|
1653
|
+
white-space: pre-wrap;
|
|
1654
|
+
overflow-wrap: anywhere;
|
|
1655
|
+
font-family: var(--font-mono);
|
|
1656
|
+
}
|
|
1657
|
+
.chat-tool__details dd:last-child {
|
|
1658
|
+
margin-bottom: 0;
|
|
1659
|
+
}
|
|
1660
|
+
.chat-tool--running .chat-tool__summary > svg:first-child {
|
|
1661
|
+
animation: chat-activity-spin 1.5s linear infinite;
|
|
1662
|
+
}
|
|
1663
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1664
|
+
.chat-tool--running .chat-tool__summary > svg:first-child {
|
|
1665
|
+
animation: none;
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
@media (max-width: 600px) {
|
|
1669
|
+
.chat-tool__summary {
|
|
1670
|
+
flex-wrap: wrap;
|
|
1671
|
+
}
|
|
1672
|
+
.chat-tool__target {
|
|
1673
|
+
flex-basis: calc(100% - 32px);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
package/vite.config.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { defineConfig } from 'vite';
|
|
|
9
9
|
import { sandboxDirectory } from './src/server/config.ts';
|
|
10
10
|
import { findFlowdularWorkspace } from './src/server/workspace-root.ts';
|
|
11
11
|
import { resolvePreviewModules } from './src/server/preview-modules.ts';
|
|
12
|
+
import { isolatePreviewHotUpdates } from './src/server/preview-hot-updates.ts';
|
|
12
13
|
import type { SandboxSession } from './src/server/sessions.ts';
|
|
13
14
|
|
|
14
15
|
Object.assign(process.env, flowdularEnvironment(process.env));
|
|
@@ -103,7 +104,10 @@ function previewModules(workspaceRoot: string): Plugin {
|
|
|
103
104
|
|
|
104
105
|
const config = {
|
|
105
106
|
root: appRoot,
|
|
106
|
-
plugins: [
|
|
107
|
+
plugins: [
|
|
108
|
+
previewModules(workspace.root),
|
|
109
|
+
...isolatePreviewHotUpdates(octane(), workspace.root),
|
|
110
|
+
],
|
|
107
111
|
resolve: {
|
|
108
112
|
/* Draft module code is loaded from a session workspace outside this app.
|
|
109
113
|
It resolves the workspace packages through the node_modules link the
|