Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/presentation/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"smoke:personal-workspace": "npm run smoke:goal-order && npm run smoke:delegation-preflight && node src/features/personal-workspace/workspace-theme.test.mjs && node src/features/personal-workspace/personal-workspace-contract.test.mjs && node ../../../examples/personal-workspace-browser-smoke.mjs",
"smoke:workspace-locale": "LOOPX_PERSONAL_WORKSPACE_SCENARIO=workspace-locale node ../../../examples/personal-workspace-browser-smoke.mjs",
"smoke:personal-workspace-packaged": "npm run smoke:goal-order && npm run smoke:delegation-preflight && node src/features/personal-workspace/workspace-theme.test.mjs && node src/features/personal-workspace/personal-workspace-contract.test.mjs && LOOPX_PERSONAL_WORKSPACE_PACKAGED=1 LOOPX_PLAYWRIGHT_PACKAGE=\"$PWD/node_modules/playwright\" node ../../../examples/personal-workspace-browser-smoke.mjs",
"smoke:personal-workspace-router": "rm -rf /tmp/loopx-personal-workspace-router-smoke && tsc --ignoreConfig --target ES2022 --module commonjs --moduleResolution node --ignoreDeprecations 6.0 --skipLibCheck --strict --outDir /tmp/loopx-personal-workspace-router-smoke smoke/personal-workspace-router-smoke.ts src/features/personal-workspace/personal-workspace-router.ts && node /tmp/loopx-personal-workspace-router-smoke/smoke/personal-workspace-router-smoke.js",
"smoke:todo-resume-condition": "rm -rf /tmp/loopx-todo-resume-condition-smoke && tsc --ignoreConfig --target ES2022 --module commonjs --moduleResolution node --ignoreDeprecations 6.0 --skipLibCheck --strict --outDir /tmp/loopx-todo-resume-condition-smoke smoke/todo-resume-condition-smoke.ts src/features/personal-workspace/todo-resume-condition.ts && node /tmp/loopx-todo-resume-condition-smoke/smoke/todo-resume-condition-smoke.js",
"smoke:presentation-surface-schema": "rm -rf /tmp/loopx-presentation-surface-schema-smoke && tsc --ignoreConfig --target ES2022 --module CommonJS --moduleResolution Node --ignoreDeprecations 6.0 --skipLibCheck --strict --resolveJsonModule --esModuleInterop --outDir /tmp/loopx-presentation-surface-schema-smoke smoke/presentation-surface-schema-smoke.ts src/data/status.ts src/data/decision-research.ts src/data/goal-channel-frontstage.ts && NODE_PATH=\"$PWD/node_modules\" node /tmp/loopx-presentation-surface-schema-smoke/apps/presentation/dashboard/smoke/presentation-surface-schema-smoke.js",
"smoke:projection-localization": "rm -rf /tmp/loopx-projection-localization-smoke && tsc --ignoreConfig --target ES2022 --module NodeNext --moduleResolution NodeNext --skipLibCheck --strict --outDir /tmp/loopx-projection-localization-smoke smoke/projection-localization-smoke.ts src/features/personal-workspace/projection-localization.ts && node /tmp/loopx-projection-localization-smoke/smoke/projection-localization-smoke.js",
"smoke:pwa-bundle": "python3 ../../../examples/dashboard-pwa-bundle-smoke.py",
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { parseTodoResumeCondition } from "../src/features/personal-workspace/todo-resume-condition.js";

for (const condition of ["todo_done:todo_release", "pr_merged:example/project#42", "capacity_available:worker", "resume_at:2026-10-01T09:00:00Z"]) {
if (parseTodoResumeCondition(condition) !== condition.toLowerCase()) throw new Error(`Supported resume condition rejected: ${condition}`);
}
for (const value of ["tomorrow", "owner_resume", "pr_merged:#0", "todo_done:", "resume_at:2026-10-01"]) {
if (parseTodoResumeCondition(value) !== null) throw new Error(`Unsupported resume condition admitted: ${value}`);
}
console.log("todo-resume-condition-smoke: ok");
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import type { LarkGoalConnection } from "../../data/chat";
import { localizedAttentionAge, localizedGoalState, localizedSessionStatus, useWorkspaceI18n } from "./i18n";
import { formatCostUsd, formatDurationMs, formatTokenCount, formatUsageValue } from "./personal-workspace-model";
import { TeamPlanResult } from "./team-plan-result";
import { todoResumeWhenFromMessage } from "./personal-workspace-router";
import { parseTodoResumeCondition } from "./todo-resume-condition";

function subagentModelRequest(include: boolean, model: string, effort: string) {
if (!include) return {};
Expand Down Expand Up @@ -298,7 +298,7 @@ export function ContextDrawer({ agents, attentionHistory = [], onSelectAttention
|| Boolean(selection.item.outputs?.length)
);
const attentionAge = selection.kind === "attention" ? localizedAttentionAge(selection.item.updatedAt, t) : null;
const normalizedTodoResumeWhen = todoResumeWhenFromMessage(todoResumeWhen);
const normalizedTodoResumeWhen = parseTodoResumeCondition(todoResumeWhen);

async function sendCorrection() {
if (selection.kind !== "run" || !correction.trim()) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,8 @@ const en = {
"composer.blockers": "Ask what blocks",
"composer.agentProgressPrompt": "Give me a progress report for this Goal: completed, running, blocked, and next steps.",
"composer.attachImageHint": "Choose, paste, or drag an image",
"composer.clarifyDefer": "Deferring a Todo requires a deterministic resume condition. Add todo_done:<todo_id>, pr_merged:[owner/repo]#<number>, capacity_available:<capability>, or resume_at:<timezone-aware RFC3339 timestamp>.",
"composer.clarifySingleAction": "This message contains multiple operations that may change state. Describe one operation at a time so each confirmation preview can be reviewed separately.",
"composer.createGoal": "Create Goal",
"composer.createGoalDraft": "Goal draft",
"composer.createGoalDraftDescription": "Complete the draft and send it. LoopX will show a confirmation preview first.",
"composer.createGoalDraftLead": "Create a long-term Goal:",
"composer.createGoalTemplate": "Create a long-term Goal:\nObjective:\nCompletion criteria:\nExecution boundary (optional):\nRelated repository (optional):\nNotification method (optional):",
"composer.createGoalHint": "Insert a Goal template to review before creation",
"composer.createGoalHint": "Configure and review a new Goal",
"composer.evidence": "Check what is proven",
"composer.globalProgress": "Summarize all Goal progress",
"composer.globalProgressPrompt": "Summarize the latest progress and blockers for all active Goals.",
Expand All @@ -96,13 +90,6 @@ const en = {
"composer.managerMessageHint": "Your message goes to the LoopX Manager across Goals for global questions or Goal creation.",
"composer.managerPlaceholder": "Ask the LoopX Manager, or describe a new Goal…",
"composer.monitor": "Configure scheduled check",
"composer.monitorGoalQuestion": "Which Goal should receive the scheduled check?",
"composer.monitorTemplate": "Add a scheduled check for the current Goal:\nCheck target:\nFrequency (supports 30 minutes / 2 hours / daily): Every 2 hours\nStop condition: Goal completes",
"composer.monitorShortcutTemplate": "Add a scheduled check for the current Goal:\nCheck target: {target}\nFrequency: Every 2 hours\nStop condition: Goal completes",
"composer.monitorTemplateWithoutGoal": "Configure a scheduled check:\nGoal:\nCheck target:\nFrequency: Every 2 hours\nStop condition: Goal completes",
"composer.heartbeatGoalQuestion": "Which Goal should receive the Heartbeat?",
"composer.heartbeatTemplate": "Set a Heartbeat for the current Goal:\nFrequency: Daily\nStop condition: Goal completes\nNotification: Only notify me when needed",
"composer.heartbeatTemplateWithoutGoal": "Set up a Heartbeat:\nGoal:\nFrequency: Daily\nStop condition: Goal completes\nNotification: Only notify me when needed",
"composer.nextAction": "Ask what’s next",
"composer.nextActionPrompt": "What should I do next?",
"composer.send": "Send",
Expand Down Expand Up @@ -785,7 +772,6 @@ const en = {
"schedule.paused": "Paused",
"schedule.summary": "Continuously checked under LoopX scheduling constraints",
"schedule.defaultTarget": "Check the current Goal for blockers, progress, and new outputs",
"schedule.unsupportedCalendar": "Scheduled checks do not currently support an exact weekday or time. Use a fixed interval such as “Every 30 minutes,” “Every 2 hours,” or “Daily.” The draft was preserved and no confirmation preview was created.",
"source.add": "Add source",
"source.addConfigured": "Add read-only source",
"source.addMethod": "Source setup method",
Expand Down Expand Up @@ -1183,15 +1169,9 @@ const zhCN: Record<WorkspaceMessageKey, string> = {
"composer.agentProgressPrompt": "请给我一份当前 Goal 的进度报告:已完成、执行中、阻塞和下一步。",
"composer.blockers": "看阻塞",
"composer.attachImageHint": "选择、粘贴或拖入图片",
"composer.clarifyDefer": "暂缓 Todo 需要可自动判断的恢复条件。请补充 todo_done:<todo_id>、pr_merged:[owner/repo]#<number>、capacity_available:<capability> 或 resume_at:<带时区 RFC3339 时间>。",
"composer.clarifySingleAction": "这句话包含多个可能修改状态的操作。请一次描述一项操作,我会逐项展示确认预览。",
"composer.evidence": "查证据",
"composer.createGoal": "创建新 Goal",
"composer.createGoalDraft": "Goal 草稿",
"composer.createGoalDraftDescription": "补充内容后发送,LoopX 会先展示待确认操作。",
"composer.createGoalDraftLead": "我想创建一个长期 Goal:",
"composer.createGoalTemplate": "我想创建一个长期 Goal:\n目标:\n完成标准:\n执行边界(可选):\n关联仓库(可选):\n通知方式(可选):",
"composer.createGoalHint": "填入 Goal 模板草稿,检查后再创建",
"composer.createGoalHint": "填写 Goal 配置,检查后再创建",
"composer.globalProgress": "汇总所有 Goal 进展",
"composer.globalProgressPrompt": "请帮我汇总所有活跃 Goal 的最新进展与阻塞。",
"composer.globalTasks": "询问全局待办",
Expand All @@ -1210,13 +1190,6 @@ const zhCN: Record<WorkspaceMessageKey, string> = {
"composer.managerMessageHint": "你的消息由 LoopX 管家跨 Goal 接收,支持全局询问与创建 Goal",
"composer.managerPlaceholder": "问问 LoopX 管家,或描述一个新 Goal…",
"composer.monitor": "配置定时检查",
"composer.monitorGoalQuestion": "为哪个 Goal 添加定时检查?",
"composer.monitorTemplate": "为当前 Goal 添加定时检查:\n检查内容:\n频率(支持 30 分钟 / 2 小时 / 每天):每 2 小时\n停止条件:Goal 完成",
"composer.monitorShortcutTemplate": "为当前 Goal 添加定时检查:\n检查内容:{target}\n频率:每 2 小时\n停止条件:Goal 完成",
"composer.monitorTemplateWithoutGoal": "配置定时检查:\nGoal:\n检查内容:\n频率:每 2 小时\n停止条件:Goal 完成",
"composer.heartbeatGoalQuestion": "为哪个 Goal 设置 Heartbeat?",
"composer.heartbeatTemplate": "为当前 Goal 设置 Heartbeat:\n频率:每天\n停止条件:Goal 完成\n通知:仅在需要我时",
"composer.heartbeatTemplateWithoutGoal": "设置 Heartbeat:\nGoal:\n频率:每天\n停止条件:Goal 完成\n通知:仅在需要我时",
"composer.nextAction": "询问下一步",
"composer.nextActionPrompt": "我现在该做什么?",
"composer.send": "发送",
Expand Down Expand Up @@ -1899,7 +1872,6 @@ const zhCN: Record<WorkspaceMessageKey, string> = {
"schedule.paused": "已暂停",
"schedule.summary": "按 LoopX 调度约束持续检查",
"schedule.defaultTarget": "检查当前 Goal 的阻塞、进度与新产出",
"schedule.unsupportedCalendar": "当前定时检查不支持精确到星期或时刻的日历计划。请改用固定间隔,例如“每 30 分钟”“每 2 小时”或“每天”;草稿已保留,没有生成待确认操作。",
"source.add": "添加来源",
"source.addConfigured": "添加只读来源",
"source.addMethod": "来源添加方式",
Expand Down
Loading
Loading