harness-wingman 0.9.2 → 0.9.3

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.
@@ -313,6 +313,8 @@ var init_labels = __esm({
313
313
  "packages/i18n/dist/catalog/en/labels.js"() {
314
314
  "use strict";
315
315
  labels_default = {
316
+ "panel.source.codexProject": "Codex project",
317
+ "panel.source.codexUngrouped": "Codex ungrouped",
316
318
  "panel.source.planStep": "plan.md step",
317
319
  "panel.source.planInstruction": "Instruction for the plan",
318
320
  "panel.source.latestInstruction": "Latest instruction",
@@ -350,6 +352,7 @@ var init_narrative = __esm({
350
352
  "packages/i18n/dist/catalog/en/narrative.js"() {
351
353
  "use strict";
352
354
  narrative_default = {
355
+ "narrative.codexUngrouped": "Ungrouped",
353
356
  "narrative.noStateDirectory": "No local state directory is configured",
354
357
  "narrative.acceptanceUnreadable": "Local acceptance state could not be read",
355
358
  "narrative.homeDirectory": "No project directory (home)",
@@ -615,6 +618,25 @@ var init_render = __esm({
615
618
  "packages/i18n/dist/catalog/en/render.js"() {
616
619
  "use strict";
617
620
  render_default = {
621
+ "panel.render.projectsPageTitle": "Project overview",
622
+ "panel.render.projectsPageHint": "Goals, progress and decisions across your coding apps.",
623
+ "panel.render.controlsPageHint": "Manage tools, preferences and how you return to a session.",
624
+ "panel.render.optionalSuggestions": "Optional suggestions",
625
+ "panel.render.suggestionsHint": "Based on observed session activity, for reference only. Review changes before applying.",
626
+ "panel.render.usagePageHint": "Reported usage and estimated context, kept separate.",
627
+ "panel.render.toolsAndPreferences": "Tools & preferences",
628
+ "panel.render.controlSkills": "Skills & plugins",
629
+ "panel.render.controlTools": "Tools & connections",
630
+ "panel.render.controlBehavior": "Behavior & permissions",
631
+ "panel.render.controlSummary": "{count} items \xB7 {enabled} enabled",
632
+ "panel.render.controlSummarySource": "Source: total toggleable entries and enabled entries in scanned slots.{slot}[]; this does not prove session use",
633
+ "panel.render.controlSettingsCount": "{count} settings",
634
+ "panel.render.codexPluginControlHint": "Codex plugins: controls the whole plugin package, not an individual skill.",
635
+ "panel.render.contextSources": "Explore context sources",
636
+ "panel.render.requestsUnavailable": "Requests unavailable \xB7 view details",
637
+ "panel.render.localFeedStatus": "Local feed \xB7 {status}",
638
+ "panel.render.appFilter": "App",
639
+ "panel.render.codexSessionsInProject": "Codex sessions are in project {name}",
618
640
  "panel.render.olderSessions": "{count} older sessions",
619
641
  "panel.render.olderSessionsSource": "Source: sessions.ended and lastActivity more than {days} days ago; display only",
620
642
  "panel.render.archiveSession": "Archive",
@@ -626,16 +648,21 @@ var init_render = __esm({
626
648
  "panel.render.ccPartial": "Partly restricted",
627
649
  "panel.render.ccDisableAll": "Disable all",
628
650
  "panel.render.ccPartialWarning": "Only some messaging tools are denied. Disable all denies both SendMessage and ListAgents.",
629
- "panel.render.ccFeatures": "Claude Code features",
651
+ "panel.render.ccFeatures": "Claude Code settings",
652
+ "panel.render.ccSettingsHint": "Changes local user settings, not just the selected session. Review changes before confirming.",
653
+ "panel.render.ccMessageHelp": "What this changes",
654
+ "panel.render.ccInboundHelp": "Controls messages from other Claude Code sessions. Accept delivers messages to Claude. Hold shows a notice without delivery, until an effective setting allows acceptance. Refuse discards them.",
655
+ "panel.render.ccInboundImpact": "This does not control your chat input. Delivered messages can start a new turn in an idle session and incur usage. They do not automatically include the sender\u2019s full history or files; the recipient\u2019s own permissions still apply.",
656
+ "panel.render.ccOutboundHelp": "Lets Claude find and message other sessions, for example to share a task result. Enabling only removes these send and discovery tool denials; other permission rules still apply.",
630
657
  "panel.render.ccAutoMemory": "Auto memory",
631
- "panel.render.ccInbound": "Receive messages from other sessions",
632
- "panel.render.ccOutbound": "Send messages to other sessions",
658
+ "panel.render.ccInbound": "Messages from other Claude sessions",
659
+ "panel.render.ccOutbound": "Allow Claude to send messages",
633
660
  "panel.render.ccDefault": "Default",
634
661
  "panel.render.ccByPermissionMode": "Determined by permission mode",
635
662
  "panel.render.ccAccept": "Accept",
636
663
  "panel.render.ccHold": "Hold",
637
664
  "panel.render.ccRefuse": "Refuse",
638
- "panel.render.ccOutboundWarning": "Also disables messages to subagents and agent teams",
665
+ "panel.render.ccOutboundWarning": "Disabling denies both SendMessage and ListAgents. It stops cross-session sending and also restricts communication with subagents (assistants Claude delegates to) and agent-team members. Receiving is controlled separately above.",
639
666
  "panel.render.ccOverridden": "Overridden by {layer}; changes here have no effect",
640
667
  "panel.render.ccLayerProject": "project settings",
641
668
  "panel.render.ccLayerLocal": "project-local settings",
@@ -657,6 +684,8 @@ var init_render = __esm({
657
684
  "panel.render.skillFrontmatterSource": "Source: SKILL.md frontmatter disable-model-invocation / user-invocable; invocation mode is determined by SKILL.md. The toggle only controls configuration enablement",
658
685
  "panel.render.skillOverridesSource": "Source: settings skillOverrides; disabled in configuration",
659
686
  "panel.render.skillConfiguration": "Configuration",
687
+ "panel.render.dshControlsSummary": "{count} items \xB7 {enabled} enabled",
688
+ "panel.render.dshControlsSummarySource": "Source: total toggleable entries and enabled entries in slots.{slot}[] scanned from dsh --dump-config; configuration enablement does not prove session use",
660
689
  "panel.render.plugins": "Plugins",
661
690
  "panel.render.pluginConfigurationTip": "Configuration enablement does not prove session use; usage comes from the Codex transcript",
662
691
  "panel.render.pluginsSummary": "{enabled} plugins enabled \xB7 {used} used this session",
@@ -697,6 +726,18 @@ var init_render = __esm({
697
726
  "panel.render.deleteLineNumber": "Delete line {line}",
698
727
  "panel.render.close": "Close",
699
728
  "panel.render.language": "Language",
729
+ "panel.render.noConversationObserved": "No conversation observed yet",
730
+ "panel.render.conversationDetailsPending": "Waiting for conversation details",
731
+ "panel.render.conversationDetailsPendingHint": "A conversation was observed. Its details will appear here when available. If nothing updates, check the connection details.",
732
+ "panel.render.checkConnection": "Check your connection",
733
+ "panel.render.startConversationHint": "Start or continue a conversation in {harness}. Your tasks and progress will appear here.",
734
+ "panel.render.checkConnectionHint": "Activity from {harness} is not yet confirmed. Check the connection settings, then start a conversation in the app.",
735
+ "panel.render.conversationNotShowing": "Already started, but nothing here?",
736
+ "panel.render.viewConnectionSettings": "View connection settings",
737
+ "panel.render.connectionDetails": "Connection details",
738
+ "panel.render.connectionInstallCommand": "If you need to reconnect, use this command",
739
+ "panel.render.planDisplaySettings": "Plan display settings",
740
+ "panel.render.helpAndFeedback": "Help & feedback",
700
741
  "panel.render.apiAnatomyReturnedAnEmptyArray": "/api/anatomy returned an empty array",
701
742
  "panel.render.noHarnessDetected": "No harness detected",
702
743
  "panel.render.firstRun": "First run",
@@ -720,7 +761,7 @@ var init_render = __esm({
720
761
  "panel.render.sourcePanelTimeOfTheLast": "Source: panel time of the last successful GET /api/anatomy",
721
762
  "panel.render.refreshFailedShowingDataFrom": "Refresh failed; showing data from",
722
763
  "panel.render.dataSuffix": "",
723
- "panel.render.contextBreakdown": "CONTEXT breakdown",
764
+ "panel.render.contextBreakdown": "Context estimate",
724
765
  "panel.render.previewTheCompleteContentBeforeSending": "Preview the complete content before sending; remove individual lines and select Send to submit; closing sends nothing",
725
766
  "panel.render.shareConfigurationSample": "Share configuration sample",
726
767
  "panel.render.thisItemIsDisabledToggleableItems": "This item is disabled; toggleable items can be enabled in CONFIGURE below",
@@ -952,7 +993,7 @@ var init_render = __esm({
952
993
  "panel.render.noExecutionEvidenceYet": "\u25CB No execution evidence yet",
953
994
  "panel.render.tasks": "Tasks",
954
995
  "panel.render.controls": "Controls",
955
- "panel.render.billing": "Billing",
996
+ "panel.render.billing": "Usage",
956
997
  "panel.render.turns": "{p0} turns",
957
998
  "panel.render.approx": " \xB7 Approx. {p0}",
958
999
  "panel.render.subagent": "Subagent",
@@ -1541,6 +1582,8 @@ var init_labels2 = __esm({
1541
1582
  "packages/i18n/dist/catalog/zh/labels.js"() {
1542
1583
  "use strict";
1543
1584
  labels_default2 = {
1585
+ "panel.source.codexProject": "Codex \u9879\u76EE",
1586
+ "panel.source.codexUngrouped": "Codex \u672A\u5206\u7EC4",
1544
1587
  "panel.source.planStep": "plan.md \u6B65\u9AA4",
1545
1588
  "panel.source.planInstruction": "\u8BA1\u5212\u6240\u5C5E\u6307\u4EE4",
1546
1589
  "panel.source.latestInstruction": "\u6700\u65B0\u6307\u4EE4",
@@ -1578,6 +1621,7 @@ var init_narrative2 = __esm({
1578
1621
  "packages/i18n/dist/catalog/zh/narrative.js"() {
1579
1622
  "use strict";
1580
1623
  narrative_default2 = {
1624
+ "narrative.codexUngrouped": "\u672A\u5206\u7EC4",
1581
1625
  "narrative.noStateDirectory": "\u672A\u914D\u7F6E\u672C\u673A\u72B6\u6001\u76EE\u5F55",
1582
1626
  "narrative.acceptanceUnreadable": "\u672C\u673A\u9A8C\u6536\u72B6\u6001\u4E0D\u53EF\u8BFB",
1583
1627
  "narrative.homeDirectory": "\u65E0\u9879\u76EE\u76EE\u5F55(\u5BB6\u76EE\u5F55)",
@@ -1843,6 +1887,25 @@ var init_render2 = __esm({
1843
1887
  "packages/i18n/dist/catalog/zh/render.js"() {
1844
1888
  "use strict";
1845
1889
  render_default2 = {
1890
+ "panel.render.projectsPageTitle": "\u9879\u76EE\u603B\u89C8",
1891
+ "panel.render.projectsPageHint": "\u96C6\u4E2D\u67E5\u770B\u5404\u4E2A\u7F16\u7A0B\u5DE5\u5177\u4E2D\u7684\u76EE\u6807\u3001\u8FDB\u5EA6\u548C\u5F85\u51B3\u4E8B\u9879\u3002",
1892
+ "panel.render.controlsPageHint": "\u7BA1\u7406\u5DE5\u5177\u3001\u504F\u597D\u8BBE\u7F6E\uFF0C\u4EE5\u53CA\u8FD4\u56DE\u4F1A\u8BDD\u7684\u65B9\u5F0F\u3002",
1893
+ "panel.render.optionalSuggestions": "\u53EF\u9009\u4F18\u5316\u5EFA\u8BAE",
1894
+ "panel.render.suggestionsHint": "\u6839\u636E\u5F53\u524D\u4F1A\u8BDD\u8BB0\u5F55\u751F\u6210\uFF0C\u4EC5\u4F9B\u53C2\u8003\u3002\u5E94\u7528\u524D\u8BF7\u67E5\u770B\u65B9\u6848\u3002",
1895
+ "panel.render.usagePageHint": "\u5B9E\u9645\u62A5\u544A\u7684\u7528\u91CF\u4E0E\u4E0A\u4E0B\u6587\u4F30\u7B97\uFF0C\u5206\u5F00\u5C55\u793A\u3002",
1896
+ "panel.render.toolsAndPreferences": "\u5DE5\u5177\u4E0E\u504F\u597D",
1897
+ "panel.render.controlSkills": "\u6280\u80FD\u4E0E\u63D2\u4EF6",
1898
+ "panel.render.controlTools": "\u5DE5\u5177\u4E0E\u8FDE\u63A5",
1899
+ "panel.render.controlBehavior": "\u884C\u4E3A\u4E0E\u6743\u9650",
1900
+ "panel.render.controlSummary": "\u5171 {count} \u9879 \xB7 \u5DF2\u542F\u7528 {enabled} \u9879",
1901
+ "panel.render.controlSummarySource": "\u6765\u6E90:\u626B\u63CF\u7684 slots.{slot}[] \u4E2D\u53EF\u5F00\u5173\u6761\u76EE\u7684\u603B\u6570\u4E0E enabled \u6570\uFF1B\u4E0D\u4EE3\u8868\u5F53\u524D\u4F1A\u8BDD\u5B9E\u9645\u4F7F\u7528",
1902
+ "panel.render.controlSettingsCount": "{count} \u9879\u8BBE\u7F6E",
1903
+ "panel.render.codexPluginControlHint": "Codex \u63D2\u4EF6\uFF1A\u8FD9\u91CC\u63A7\u5236\u6574\u4E2A\u63D2\u4EF6\u5305\uFF0C\u4E0D\u662F\u5355\u4E2A\u6280\u80FD\u3002",
1904
+ "panel.render.contextSources": "\u67E5\u770B\u4E0A\u4E0B\u6587\u6765\u6E90",
1905
+ "panel.render.requestsUnavailable": "\u6682\u65F6\u65E0\u6CD5\u89C2\u5BDF\u8BF7\u6C42 \xB7 \u67E5\u770B\u8BE6\u60C5",
1906
+ "panel.render.localFeedStatus": "\u672C\u5730\u6570\u636E\u6D41 \xB7 {status}",
1907
+ "panel.render.appFilter": "\u5E94\u7528",
1908
+ "panel.render.codexSessionsInProject": "Codex \u4F1A\u8BDD\u5728\u9879\u76EE {name} \u4E0B",
1846
1909
  "panel.render.olderSessions": "\u66F4\u65E9\u7684 {count} \u4E2A\u4F1A\u8BDD",
1847
1910
  "panel.render.olderSessionsSource": "\u6765\u6E90:sessions.ended \u4E14 lastActivity \u65E9\u4E8E\u5F53\u524D\u65F6\u95F4 {days} \u5929;\u4EC5\u6298\u53E0\u663E\u793A",
1848
1911
  "panel.render.archiveSession": "\u5F52\u6863",
@@ -1854,16 +1917,21 @@ var init_render2 = __esm({
1854
1917
  "panel.render.ccPartial": "\u90E8\u5206\u53D7\u9650",
1855
1918
  "panel.render.ccDisableAll": "\u5168\u90E8\u5173\u95ED",
1856
1919
  "panel.render.ccPartialWarning": "\u4EC5\u7981\u7528\u4E86\u90E8\u5206\u6D88\u606F\u5DE5\u5177\uFF1B\u5168\u90E8\u5173\u95ED\u4F1A\u540C\u65F6\u62D2\u7EDD SendMessage \u4E0E ListAgents\u3002",
1857
- "panel.render.ccFeatures": "Claude Code \u529F\u80FD",
1920
+ "panel.render.ccFeatures": "Claude Code \u8BBE\u7F6E",
1921
+ "panel.render.ccSettingsHint": "\u4FEE\u6539\u672C\u673A\u7528\u6237\u7EA7\u914D\u7F6E\uFF0C\u4E0D\u53EA\u5F71\u54CD\u5F53\u524D\u4F1A\u8BDD\u3002\u786E\u8BA4\u524D\u53EF\u67E5\u770B\u6539\u52A8\u3002",
1922
+ "panel.render.ccMessageHelp": "\u4E86\u89E3\u5F71\u54CD",
1923
+ "panel.render.ccInboundHelp": "\u5904\u7406\u5176\u4ED6 Claude Code \u4F1A\u8BDD\u53D1\u6765\u7684\u6D88\u606F\u3002\u63A5\u6536\uFF1A\u4EA4\u7ED9 Claude\uFF1B\u6682\u5B58\uFF1A\u5148\u663E\u793A\u6536\u5230\u63D0\u793A\uFF0C\u4E0D\u4EA4\u7ED9 Claude\uFF0C\u4E4B\u540E\u6709\u6548\u8BBE\u7F6E\u5141\u8BB8\u63A5\u6536\u65F6\u518D\u4EA4\u4ED8\uFF1B\u62D2\u7EDD\uFF1A\u4E22\u5F03\u6D88\u606F\u3002",
1924
+ "panel.render.ccInboundImpact": "\u8FD9\u4E0D\u662F\u4F60\u7684\u804A\u5929\u8F93\u5165\u5F00\u5173\u3002\u6536\u5230\u5E76\u4EA4\u4ED8\u7684\u6D88\u606F\u53EF\u80FD\u8BA9\u7A7A\u95F2\u7684 Claude \u5F00\u59CB\u65B0\u4E00\u8F6E\u5904\u7406\uFF0C\u4EA7\u751F\u7528\u91CF\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u9644\u5E26\u53D1\u9001\u65B9\u7684\u5B8C\u6574\u5BF9\u8BDD\u6216\u6587\u4EF6\uFF0C\u63A5\u6536\u65B9\u4ECD\u9075\u5B88\u81EA\u8EAB\u6743\u9650\u3002",
1925
+ "panel.render.ccOutboundHelp": "\u5141\u8BB8 Claude \u67E5\u627E\u5176\u4ED6\u4F1A\u8BDD\u5E76\u53D1\u9001\u6D88\u606F\uFF0C\u4F8B\u5982\u628A\u5B8C\u6210\u60C5\u51B5\u544A\u8BC9\u53E6\u4E00\u4E2A\u4EFB\u52A1\u3002\u5F00\u542F\u53EA\u79FB\u9664\u8FD9\u91CC\u5BF9\u53D1\u9001\u548C\u67E5\u627E\u5DE5\u5177\u7684\u7981\u7528\uFF0C\u4ECD\u53D7\u5176\u4ED6\u6743\u9650\u8BBE\u7F6E\u9650\u5236\u3002",
1858
1926
  "panel.render.ccAutoMemory": "Auto memory",
1859
- "panel.render.ccInbound": "\u63A5\u6536\u5176\u4ED6\u4F1A\u8BDD\u7684\u6D88\u606F",
1860
- "panel.render.ccOutbound": "\u5411\u5176\u4ED6\u4F1A\u8BDD\u53D1\u6D88\u606F",
1927
+ "panel.render.ccInbound": "\u63A5\u6536\u5176\u4ED6 Claude \u4F1A\u8BDD\u7684\u6D88\u606F",
1928
+ "panel.render.ccOutbound": "\u5141\u8BB8 Claude \u53D1\u9001\u6D88\u606F",
1861
1929
  "panel.render.ccDefault": "\u9ED8\u8BA4",
1862
1930
  "panel.render.ccByPermissionMode": "\u6309\u6743\u9650\u6A21\u5F0F\u51B3\u5B9A",
1863
1931
  "panel.render.ccAccept": "\u63A5\u6536",
1864
1932
  "panel.render.ccHold": "\u6682\u5B58",
1865
1933
  "panel.render.ccRefuse": "\u62D2\u7EDD",
1866
- "panel.render.ccOutboundWarning": "\u540C\u65F6\u7981\u6389\u5BF9\u5B50\u4EE3\u7406\u4E0E agent team \u7684\u6D88\u606F",
1934
+ "panel.render.ccOutboundWarning": "\u5173\u95ED\u4F1A\u540C\u65F6\u7981\u7528 SendMessage \u548C ListAgents\uFF1B\u4E0D\u4EC5\u505C\u6B62\u8DE8\u4F1A\u8BDD\u53D1\u6D88\u606F\uFF0C\u4E5F\u4F1A\u9650\u5236 Claude \u4E0E\u5B50\u4EE3\u7406\uFF08\u5B83\u5206\u6D3E\u51FA\u53BB\u7684\u52A9\u624B\uFF09\u548C Agent \u56E2\u961F\u6210\u5458\u7684\u901A\u4FE1\u3002\u63A5\u6536\u6D88\u606F\u7531\u4E0A\u9762\u7684\u8BBE\u7F6E\u5355\u72EC\u63A7\u5236\u3002",
1867
1935
  "panel.render.ccOverridden": "\u88AB {layer} \u8986\u76D6\uFF0C\u6B64\u5904\u6539\u52A8\u4E0D\u751F\u6548",
1868
1936
  "panel.render.ccLayerProject": "\u9879\u76EE\u5C42",
1869
1937
  "panel.render.ccLayerLocal": "\u9879\u76EE\u672C\u5730\u5C42",
@@ -1885,6 +1953,8 @@ var init_render2 = __esm({
1885
1953
  "panel.render.skillFrontmatterSource": "\u6765\u6E90:SKILL.md frontmatter disable-model-invocation / user-invocable;\u8C03\u7528\u6A21\u5F0F\u7531 SKILL.md \u51B3\u5B9A\uFF0C\u5F00\u5173\u53EA\u63A7\u5236\u914D\u7F6E\u542F\u7528\u72B6\u6001",
1886
1954
  "panel.render.skillOverridesSource": "\u6765\u6E90:settings skillOverrides;\u914D\u7F6E\u5DF2\u7981\u7528",
1887
1955
  "panel.render.skillConfiguration": "\u914D\u7F6E\u7EA7",
1956
+ "panel.render.dshControlsSummary": "\u5171 {count} \u9879 \xB7 \u5DF2\u542F\u7528 {enabled} \u9879",
1957
+ "panel.render.dshControlsSummarySource": "\u6765\u6E90:dsh --dump-config \u626B\u63CF slots.{slot}[] \u4E2D toggleable \u6761\u76EE\u7684\u603B\u6570\u4E0E enabled \u6570\uFF1B\u914D\u7F6E\u542F\u7528\u4E0D\u7B49\u4E8E\u4F1A\u8BDD\u4F7F\u7528",
1888
1958
  "panel.render.plugins": "\u63D2\u4EF6",
1889
1959
  "panel.render.pluginConfigurationTip": "\u914D\u7F6E\u542F\u7528\u4E0D\u4EE3\u8868\u672C\u4F1A\u8BDD\u8C03\u7528\uFF1B\u4F1A\u8BDD\u4F7F\u7528\u4EE5 Codex transcript \u4E3A\u51C6",
1890
1960
  "panel.render.pluginsSummary": "{enabled} \u4E2A\u63D2\u4EF6\u5DF2\u542F\u7528 \xB7 \u672C\u4F1A\u8BDD\u7528\u5230 {used} \u4E2A",
@@ -1925,6 +1995,18 @@ var init_render2 = __esm({
1925
1995
  "panel.render.deleteLineNumber": "\u5220\u9664\u7B2C {line} \u884C",
1926
1996
  "panel.render.close": "\u5173\u95ED",
1927
1997
  "panel.render.language": "\u8BED\u8A00",
1998
+ "panel.render.noConversationObserved": "\u8FD8\u6CA1\u6709\u89C2\u5BDF\u5230\u4F1A\u8BDD",
1999
+ "panel.render.conversationDetailsPending": "\u6B63\u5728\u7B49\u5F85\u4F1A\u8BDD\u8BE6\u60C5",
2000
+ "panel.render.conversationDetailsPendingHint": "\u5DF2\u6536\u5230\u4F1A\u8BDD\u4FE1\u606F\u3002\u8BE6\u60C5\u53EF\u7528\u540E\u4F1A\u663E\u793A\u5728\u8FD9\u91CC\uFF1B\u5982\u679C\u4E00\u76F4\u6CA1\u6709\u66F4\u65B0\uFF0C\u8BF7\u67E5\u770B\u8FDE\u63A5\u8BE6\u60C5\u3002",
2001
+ "panel.render.checkConnection": "\u5148\u68C0\u67E5\u8FDE\u63A5\u8BBE\u7F6E",
2002
+ "panel.render.startConversationHint": "\u5728 {harness} \u4E2D\u5F00\u59CB\u6216\u7EE7\u7EED\u5BF9\u8BDD\uFF0C\u4EFB\u52A1\u548C\u8FDB\u5C55\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002",
2003
+ "panel.render.checkConnectionHint": "\u5C1A\u672A\u786E\u8BA4 {harness} \u7684\u6D3B\u52A8\u63A5\u5165\u3002\u67E5\u770B\u8FDE\u63A5\u8BBE\u7F6E\u540E\uFF0C\u5728\u539F\u5E94\u7528\u4E2D\u5F00\u59CB\u5BF9\u8BDD\u3002",
2004
+ "panel.render.conversationNotShowing": "\u5DF2\u7ECF\u5F00\u59CB\u5BF9\u8BDD\uFF0C\u4F46\u6CA1\u6709\u663E\u793A\uFF1F",
2005
+ "panel.render.viewConnectionSettings": "\u67E5\u770B\u8FDE\u63A5\u8BBE\u7F6E",
2006
+ "panel.render.connectionDetails": "\u8FDE\u63A5\u8BE6\u60C5",
2007
+ "panel.render.connectionInstallCommand": "\u9700\u8981\u91CD\u65B0\u63A5\u5165\u65F6\uFF0C\u53EF\u4F7F\u7528\u6B64\u547D\u4EE4\uFF1A",
2008
+ "panel.render.planDisplaySettings": "\u8BA1\u5212\u663E\u793A\u8BBE\u7F6E",
2009
+ "panel.render.helpAndFeedback": "\u5E2E\u52A9\u4E0E\u53CD\u9988",
1928
2010
  "panel.render.apiAnatomyReturnedAnEmptyArray": "/api/anatomy \u8FD4\u56DE\u4E86\u7A7A\u6570\u7EC4",
1929
2011
  "panel.render.noHarnessDetected": "\u672A\u68C0\u6D4B\u5230 harness",
1930
2012
  "panel.render.firstRun": "\u5148\u8FD0\u884C",
@@ -1948,7 +2030,7 @@ var init_render2 = __esm({
1948
2030
  "panel.render.sourcePanelTimeOfTheLast": "\u6765\u6E90:\u4E0A\u6B21\u6210\u529F GET /api/anatomy \u7684\u9762\u677F\u65F6\u95F4",
1949
2031
  "panel.render.refreshFailedShowingDataFrom": "\u5237\u65B0\u5931\u8D25,\u663E\u793A\u7684\u662F",
1950
2032
  "panel.render.dataSuffix": "\u7684\u6570\u636E",
1951
- "panel.render.contextBreakdown": "CONTEXT \u7EC4\u6210",
2033
+ "panel.render.contextBreakdown": "\u4E0A\u4E0B\u6587\u4F30\u7B97",
1952
2034
  "panel.render.previewTheCompleteContentBeforeSending": "\u6253\u5F00\u9884\u89C8\u5F39\u5C42:\u5148\u770B\u5230\u5C06\u53D1\u9001\u7684\u5B8C\u6574\u5185\u5BB9,\u53EF\u9010\u884C\u5220,\u70B9\u300C\u53D1\u9001\u300D\u624D\u4F1A\u53D1\u51FA;\u5173\u95ED = \u4EC0\u4E48\u90FD\u4E0D\u53D1",
1953
2035
  "panel.render.shareConfigurationSample": "\u5206\u4EAB\u914D\u7F6E\u6837\u672C",
1954
2036
  "panel.render.thisItemIsDisabledToggleableItems": "\u8BE5\u6761\u76EE\u5F53\u524D\u88AB\u5173\u95ED;\u53EF\u5F00\u5173\u6761\u76EE\u5728\u4E0B\u65B9 CONFIGURE \u533A\u4E00\u952E\u6253\u5F00",
@@ -2180,7 +2262,7 @@ var init_render2 = __esm({
2180
2262
  "panel.render.noExecutionEvidenceYet": "\u25CB \u5C1A\u65E0\u6267\u884C\u8BC1\u636E",
2181
2263
  "panel.render.tasks": "\u4EFB\u52A1",
2182
2264
  "panel.render.controls": "\u63A7\u5236",
2183
- "panel.render.billing": "\u8D26\u5355",
2265
+ "panel.render.billing": "\u7528\u91CF",
2184
2266
  "panel.render.turns": "{p0} \u8F6E",
2185
2267
  "panel.render.approx": " \xB7 \u7EA6 {p0}",
2186
2268
  "panel.render.subagent": "\u5B50 agent",
@@ -16097,8 +16179,48 @@ process.stdin.on('end', async () => {
16097
16179
  });
16098
16180
 
16099
16181
  // packages/adapter-codex/dist/scan.js
16100
- import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync13, statSync as statSync4 } from "node:fs";
16182
+ import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync13, realpathSync as realpathSync2, statSync as statSync4 } from "node:fs";
16101
16183
  import { dirname as dirname13, isAbsolute as isAbsolute3, join as join20, resolve as resolve8 } from "node:path";
16184
+ function readCodexProjects(homeDir) {
16185
+ try {
16186
+ const state = JSON.parse(readFileSync13(join20(homeDir, ".codex", ".codex-global-state.json"), "utf8"));
16187
+ if (!isTable(state))
16188
+ return void 0;
16189
+ const localProjects = state["local-projects"];
16190
+ const threadAssignments = state["thread-project-assignments"];
16191
+ const order = state["project-order"];
16192
+ if (!isTable(localProjects) || !isTable(threadAssignments) || !Array.isArray(order) || !order.every((id) => typeof id === "string")) {
16193
+ return void 0;
16194
+ }
16195
+ const projects = /* @__PURE__ */ Object.create(null);
16196
+ for (const [key, project] of Object.entries(localProjects)) {
16197
+ if (!isTable(project) || typeof project.id !== "string" || project.id !== key || typeof project.name !== "string" || !Array.isArray(project.rootPaths) || !project.rootPaths.every((root) => typeof root === "string" && isAbsolute3(root))) {
16198
+ return void 0;
16199
+ }
16200
+ projects[key] = {
16201
+ id: project.id,
16202
+ name: project.name,
16203
+ rootPaths: project.rootPaths.map((root) => {
16204
+ try {
16205
+ return realpathSync2(root);
16206
+ } catch {
16207
+ return root;
16208
+ }
16209
+ })
16210
+ };
16211
+ }
16212
+ const assignments = /* @__PURE__ */ Object.create(null);
16213
+ for (const [threadId, assignment] of Object.entries(threadAssignments)) {
16214
+ if (!isTable(assignment) || assignment.projectKind !== "local" || typeof assignment.projectId !== "string") {
16215
+ return void 0;
16216
+ }
16217
+ assignments[threadId] = assignment.projectId;
16218
+ }
16219
+ return { projects, assignments, order };
16220
+ } catch {
16221
+ return void 0;
16222
+ }
16223
+ }
16102
16224
  async function detect(options) {
16103
16225
  const { codexHome } = resolvePaths(options);
16104
16226
  return { installed: existsSync13(codexHome) };
@@ -16656,6 +16778,7 @@ __export(dist_exports3, {
16656
16778
  installProtocolCodexUser: () => installProtocolCodexUser,
16657
16779
  protocolStatusCodex: () => protocolStatusCodex,
16658
16780
  protocolStatusCodexUser: () => protocolStatusCodexUser,
16781
+ readCodexProjects: () => readCodexProjects,
16659
16782
  recognizePluginTool: () => recognizePluginTool,
16660
16783
  resolveNodeExecutable: () => resolveNodeExecutable,
16661
16784
  uninstallProtocolCodex: () => uninstallProtocolCodex,
@@ -16681,6 +16804,7 @@ var init_dist6 = __esm({
16681
16804
  init_hooks3();
16682
16805
  init_plugin_tools();
16683
16806
  init_protocol3();
16807
+ init_scan2();
16684
16808
  init_protocol_user2();
16685
16809
  }
16686
16810
  });
@@ -17106,8 +17230,9 @@ init_dist6();
17106
17230
  init_dist3();
17107
17231
  init_dist2();
17108
17232
  init_dist();
17233
+ import { realpathSync as realpathSync3, statSync as statSync6 } from "node:fs";
17109
17234
  import { readdir as readdir2 } from "node:fs/promises";
17110
- import { isAbsolute as isAbsolute6, join as join26, resolve as resolve12 } from "node:path";
17235
+ import { isAbsolute as isAbsolute6, join as join26, relative as relative4, resolve as resolve12 } from "node:path";
17111
17236
 
17112
17237
  // packages/narrative/dist/attribute.js
17113
17238
  function extractSteps(lines2) {
@@ -17244,6 +17369,9 @@ function parseTurnContext(payload, timestamp) {
17244
17369
  assignString(line, "turnId", optionalString(payload?.turn_id));
17245
17370
  assignString(line, "model", optionalString(payload?.model));
17246
17371
  assignString(line, "cwd", optionalString(payload?.cwd));
17372
+ if (payload?.approvals_reviewer === "user" || payload?.approvals_reviewer === "auto_review") {
17373
+ line.approvalsReviewer = payload.approvals_reviewer;
17374
+ }
17247
17375
  return line;
17248
17376
  }
17249
17377
  function parseEventMessage(payload, timestamp) {
@@ -17440,7 +17568,31 @@ function isRecord2(value) {
17440
17568
  }
17441
17569
 
17442
17570
  // packages/narrative/dist/parse.js
17571
+ function userRequestText(text) {
17572
+ let body = text.trim();
17573
+ if (/^<(task-notification|system-reminder)\b/u.test(body))
17574
+ return "";
17575
+ let browserEnvelope = false;
17576
+ if (/^<in-app-browser-context\b/u.test(body)) {
17577
+ const end = body.indexOf("</in-app-browser-context>");
17578
+ if (end < 0)
17579
+ return "";
17580
+ body = body.slice(end + "</in-app-browser-context>".length).trim();
17581
+ browserEnvelope = true;
17582
+ }
17583
+ if (/^# Files mentioned by the user:[ \t]*(?:\r?\n|$)/u.test(body)) {
17584
+ const boundary = /^## My request:[ \t]*(?:\r?\n|$)/mu.exec(body);
17585
+ return boundary === null ? "" : body.slice(boundary.index + boundary[0].length).trim();
17586
+ }
17587
+ if (browserEnvelope) {
17588
+ const boundary = /^## My request:[ \t]*(?:\r?\n|$)/u.exec(body);
17589
+ return boundary === null ? "" : body.slice(boundary[0].length).trim();
17590
+ }
17591
+ return body;
17592
+ }
17443
17593
  function isHarnessSystemNotice(text) {
17594
+ if (/^\s*<in-app-browser-context\b/u.test(text))
17595
+ return userRequestText(text) === "";
17444
17596
  return /^\s*<(task-notification|system-reminder|in-app-browser-context)\b/u.test(text);
17445
17597
  }
17446
17598
  function parseTranscriptLine(line) {
@@ -19183,7 +19335,7 @@ function resolveWingmanVersion({ defined, moduleUrl = import.meta.url, readPacka
19183
19335
  return void 0;
19184
19336
  }
19185
19337
  function wingmanVersion() {
19186
- const defined = false ? void 0 : "0.9.2";
19338
+ const defined = false ? void 0 : "0.9.3";
19187
19339
  return resolveWingmanVersion({
19188
19340
  defined,
19189
19341
  readPackage: (url) => JSON.parse(readFileSync17(url, "utf8"))
@@ -19231,9 +19383,46 @@ function createNarrativeService(options = {}) {
19231
19383
  const projectFiles = /* @__PURE__ */ new Map();
19232
19384
  const rememberedProjectRoots = /* @__PURE__ */ new Map();
19233
19385
  const seenProjectRoots = /* @__PURE__ */ new Set();
19386
+ let codexProjects;
19387
+ let codexProjectsSignature;
19388
+ const codexRootResolutions = /* @__PURE__ */ new Map();
19234
19389
  let projectMemoryUnavailable;
19235
19390
  let notificationQueued = false;
19236
19391
  let closed = false;
19392
+ function refreshCodexProjects() {
19393
+ if (options.homeDir === void 0 || closed)
19394
+ return;
19395
+ let signature = "missing";
19396
+ try {
19397
+ const info = statSync6(join26(options.homeDir, ".codex", ".codex-global-state.json"));
19398
+ signature = `${info.mtimeMs}:${info.ctimeMs}:${info.size}:${info.mode}`;
19399
+ } catch {
19400
+ }
19401
+ const unchanged = signature === codexProjectsSignature;
19402
+ if (unchanged && codexProjects !== void 0)
19403
+ return;
19404
+ codexProjectsSignature = signature;
19405
+ codexProjects = readCodexProjects(options.homeDir);
19406
+ if (unchanged && codexProjects === void 0)
19407
+ return;
19408
+ codexRootResolutions.clear();
19409
+ for (const project of Object.values(codexProjects?.projects ?? {})) {
19410
+ for (const root of project.rootPaths) {
19411
+ void resolveProjectRoot(root, {
19412
+ homeDir: options.homeDir,
19413
+ maxDirectories: 1,
19414
+ ...options.projectBoundaryDir === void 0 ? {} : { boundaryDir: options.projectBoundaryDir }
19415
+ }).then((resolution) => {
19416
+ if (closed || signature !== codexProjectsSignature)
19417
+ return;
19418
+ codexRootResolutions.set(root, resolution);
19419
+ watchResolution(resolution);
19420
+ notify("codex");
19421
+ });
19422
+ }
19423
+ }
19424
+ notify("codex");
19425
+ }
19237
19426
  function notify(harness) {
19238
19427
  pendingNotifications.add(harness);
19239
19428
  if (notificationQueued)
@@ -19294,7 +19483,7 @@ function createNarrativeService(options = {}) {
19294
19483
  session.subagentTimer = void 0;
19295
19484
  }
19296
19485
  function anchorCwd(harness, session, cwd) {
19297
- if (session.cwd !== void 0)
19486
+ if (session.cwd !== void 0 || cwd.trim() === "")
19298
19487
  return;
19299
19488
  session.cwd = cwd;
19300
19489
  if (options.homeDir === void 0)
@@ -19609,6 +19798,9 @@ function createNarrativeService(options = {}) {
19609
19798
  if (harness === "codex") {
19610
19799
  const parsed = parseCodexRolloutLine(line);
19611
19800
  session.codexLines.push(parsed);
19801
+ if ((parsed.kind === "session_meta" && parsed.parentThreadId === void 0 || parsed.kind === "turn_context") && parsed.cwd !== void 0) {
19802
+ anchorCwd(harness, session, parsed.cwd);
19803
+ }
19612
19804
  if (parsed.kind !== "unknown")
19613
19805
  timestamp = parsed.timestamp;
19614
19806
  } else {
@@ -19679,13 +19871,14 @@ function createNarrativeService(options = {}) {
19679
19871
  }
19680
19872
  if (name === "UserPromptSubmit") {
19681
19873
  const prompt = typeof payload.prompt === "string" ? payload.prompt.trim() : void 0;
19874
+ const displayPrompt = prompt === void 0 ? void 0 : userRequestText(prompt);
19682
19875
  if (prompt === void 0 || prompt !== "" && !isHarnessSystemNotice(prompt)) {
19683
19876
  session.hookInstructions.push({
19684
19877
  at: event.received_at,
19685
19878
  ...prompt === void 0 ? {} : { text: prompt }
19686
19879
  });
19687
- if (prompt !== void 0) {
19688
- session.hookPrompt = truncate(prompt, DETAIL_LIMIT);
19880
+ if (displayPrompt !== void 0 && displayPrompt !== "") {
19881
+ session.hookPrompt = truncate(displayPrompt, DETAIL_LIMIT);
19689
19882
  session.hookPromptAt = event.received_at;
19690
19883
  }
19691
19884
  }
@@ -19715,6 +19908,7 @@ function createNarrativeService(options = {}) {
19715
19908
  const signal = waitingSignal(payload);
19716
19909
  if (signal !== null) {
19717
19910
  const { kind } = signal;
19911
+ session.feedbackRequestAt = event.received_at;
19718
19912
  if (session.waiting === null) {
19719
19913
  session.waiting = {
19720
19914
  kind,
@@ -19751,7 +19945,8 @@ function createNarrativeService(options = {}) {
19751
19945
  return waiting.message;
19752
19946
  },
19753
19947
  until: event.received_at,
19754
- resolvedBy: name
19948
+ resolvedBy: name,
19949
+ ...session.feedbackRequestAt === void 0 ? {} : { requestAt: session.feedbackRequestAt }
19755
19950
  });
19756
19951
  session.waiting = null;
19757
19952
  }
@@ -19877,7 +20072,7 @@ function createNarrativeService(options = {}) {
19877
20072
  label: session.projectResolution?.isHome ? t("narrative.homeDirectory") : session.label ?? shortSessionId(session.id),
19878
20073
  ...session.cwd === void 0 ? {} : { cwd: session.cwd },
19879
20074
  lastActivity,
19880
- waiting: session.waiting !== null,
20075
+ waiting: deriveCached(harness, session, configuredPlugins, configuredMcpServers).waiting !== null,
19881
20076
  ended: isEnded(session, nowIso),
19882
20077
  archived: user?.archived === true,
19883
20078
  archivedHasNewActivity: user?.archived === true && user.archivedAt !== void 0 && Date.parse(lastActivity) > Date.parse(user.archivedAt),
@@ -19892,7 +20087,7 @@ function createNarrativeService(options = {}) {
19892
20087
  ...state,
19893
20088
  taskWorkflow: {
19894
20089
  ...state.taskWorkflow,
19895
- feedback: feedbackView(harness, feedback, session.feedbackState),
20090
+ feedback: feedbackView(harness, feedback, humanFeedbackState(harness, session)),
19896
20091
  ...verification === void 0 ? {} : {
19897
20092
  verification: {
19898
20093
  ...verification,
@@ -19982,37 +20177,94 @@ function createNarrativeService(options = {}) {
19982
20177
  };
19983
20178
  }
19984
20179
  function getProjects() {
20180
+ refreshCodexProjects();
19985
20181
  const overlay = options.homeDir === void 0 ? void 0 : readTaskOverlay(options.homeDir);
19986
20182
  const overlayEntries = overlay === void 0 || "unavailable" in overlay ? {} : overlay.entries;
19987
20183
  const grouped = /* @__PURE__ */ new Map();
20184
+ const cards = /* @__PURE__ */ new Map();
20185
+ const codexNamesByRoot = /* @__PURE__ */ new Map();
19988
20186
  for (const [rootIdentity, resolution] of rememberedProjectRoots) {
19989
- grouped.set(rootIdentity, { resolution, members: [] });
20187
+ grouped.set(rootIdentity, { rootIdentity, resolution, members: [] });
19990
20188
  }
19991
20189
  for (const [harness, sessions] of harnesses) {
19992
20190
  for (const session of sessions.values()) {
19993
20191
  if (session.cwd === void 0)
19994
20192
  continue;
19995
- const rootIdentity = session.projectResolution?.rootIdentity ?? resolve12(session.cwd);
19996
- const group = grouped.get(rootIdentity);
20193
+ let rootIdentity = session.projectResolution?.rootIdentity ?? resolve12(session.cwd);
20194
+ let resolution = session.projectResolution;
20195
+ let cardId;
20196
+ if (harness === "codex" && codexProjects !== void 0) {
20197
+ const meta = session.codexLines.find((line) => line.kind === "session_meta" && line.parentThreadId === void 0);
20198
+ const threadId = meta?.kind === "session_meta" ? meta.threadId : void 0;
20199
+ const assignment = codexProjects.assignments[threadId ?? session.id];
20200
+ const cwd = codexPathIdentity(session.cwd);
20201
+ const matching = Object.values(codexProjects.projects).flatMap((project2) => project2.rootPaths.map((root) => ({ project: project2, root }))).filter(({ root }) => isPathWithin(root, cwd)).sort((left, right) => right.root.length - left.root.length)[0];
20202
+ const project = assignment === void 0 ? matching?.project : codexProjects.projects[assignment];
20203
+ if (assignment === void 0 || project !== void 0) {
20204
+ cardId = project === void 0 ? "codex-ungrouped" : `codex-project:${project.id}`;
20205
+ let card = cards.get(cardId);
20206
+ if (card === void 0) {
20207
+ card = {
20208
+ kind: project === void 0 ? "codex-ungrouped" : "codex-project",
20209
+ id: project?.id ?? "codex-ungrouped",
20210
+ name: project?.name ?? t("narrative.codexUngrouped"),
20211
+ roots: [...new Set(project?.rootPaths ?? [])]
20212
+ };
20213
+ cards.set(cardId, card);
20214
+ for (const root of card.roots) {
20215
+ grouped.set(JSON.stringify([cardId, root]), {
20216
+ rootIdentity: root,
20217
+ resolution: codexRootResolutions.get(root),
20218
+ members: [],
20219
+ cardId
20220
+ });
20221
+ }
20222
+ }
20223
+ const configuredRoot = project?.rootPaths.filter((root) => isPathWithin(root, cwd)).sort((left, right) => right.length - left.length)[0];
20224
+ if (configuredRoot !== void 0 && !(resolution?.planPath !== void 0 && resolution.rootIdentity !== configuredRoot)) {
20225
+ rootIdentity = configuredRoot;
20226
+ resolution = codexRootResolutions.get(configuredRoot) ?? (session.projectResolution?.rootIdentity === configuredRoot ? session.projectResolution : void 0);
20227
+ }
20228
+ if (!card.roots.includes(rootIdentity))
20229
+ card.roots.push(rootIdentity);
20230
+ }
20231
+ }
20232
+ const key = cardId === void 0 ? rootIdentity : JSON.stringify([cardId, rootIdentity]);
20233
+ const group = grouped.get(key);
19997
20234
  if (group === void 0) {
19998
- grouped.set(rootIdentity, {
19999
- resolution: session.projectResolution,
20000
- members: [{ harness, session }]
20235
+ grouped.set(key, {
20236
+ rootIdentity,
20237
+ resolution,
20238
+ members: [{ harness, session }],
20239
+ ...cardId === void 0 ? {} : { cardId }
20001
20240
  });
20002
20241
  } else {
20003
- group.resolution ??= session.projectResolution;
20242
+ group.resolution ??= resolution;
20004
20243
  group.members.push({ harness, session });
20005
20244
  }
20006
20245
  }
20007
20246
  }
20247
+ for (const card of cards.values()) {
20248
+ if (card.kind !== "codex-project")
20249
+ continue;
20250
+ for (const root of card.roots) {
20251
+ const names = codexNamesByRoot.get(root) ?? /* @__PURE__ */ new Set();
20252
+ names.add(card.name);
20253
+ codexNamesByRoot.set(root, names);
20254
+ }
20255
+ }
20008
20256
  const overviews = /* @__PURE__ */ new Map();
20009
20257
  for (const harness of harnesses.keys())
20010
20258
  overviews.set(harness, getOverview(harness));
20011
20259
  const projects = [];
20012
- for (const [rootIdentity, group] of grouped) {
20260
+ const cardRoots = /* @__PURE__ */ new Map();
20261
+ for (const group of grouped.values()) {
20262
+ const { rootIdentity } = group;
20013
20263
  const { members } = group;
20014
- const resolution = members.find((member) => member.session.projectResolution !== void 0)?.session.projectResolution ?? group.resolution;
20015
- const root = resolution?.root ?? resolve12(members[0]?.session.cwd ?? "");
20264
+ if (group.cardId === void 0 && members.length === 0 && [...cards.values()].some((card) => card.roots.includes(rootIdentity)))
20265
+ continue;
20266
+ const resolution = group.resolution;
20267
+ const root = resolution?.root ?? (group.cardId === void 0 ? resolve12(members[0]?.session.cwd ?? rootIdentity) : rootIdentity);
20016
20268
  const planPath = resolution?.planPath ?? join26(root, ".wingman", "plan.md");
20017
20269
  const runtime = projectFiles.get(resolution?.planPathIdentity ?? planPath);
20018
20270
  if (runtime?.current !== void 0 && runtime.readFailureKey === void 0 && runtime.parsedLocale !== getLocale()) {
@@ -20126,7 +20378,7 @@ function createNarrativeService(options = {}) {
20126
20378
  const projectUser = overlayEntries[`project:${root}`];
20127
20379
  const firstScreen = deriveProjectFirstScreen(plan, parsed?.availability === "available" ? parsed.goal : void 0, summary.currentPoints, sessionViews);
20128
20380
  const archivedHasNewActivity = projectUser?.archived === true && projectUser.archivedAt !== void 0 && firstScreen.lastActivity !== void 0 && Date.parse(firstScreen.lastActivity.at) > Date.parse(projectUser.archivedAt);
20129
- projects.push({
20381
+ const projectView = {
20130
20382
  firstScreen,
20131
20383
  root,
20132
20384
  ...resolution === void 0 ? {} : { isHome: resolution.isHome === true },
@@ -20159,6 +20411,48 @@ function createNarrativeService(options = {}) {
20159
20411
  facts: reconciliation,
20160
20412
  protocol,
20161
20413
  sessions: sessionViews
20414
+ };
20415
+ if (group.cardId === void 0) {
20416
+ const names = codexNamesByRoot.get(rootIdentity);
20417
+ if (names !== void 0)
20418
+ projectView.codexProjectNames = [...names];
20419
+ projects.push(projectView);
20420
+ } else {
20421
+ const roots = cardRoots.get(group.cardId) ?? [];
20422
+ roots.push(projectView);
20423
+ cardRoots.set(group.cardId, roots);
20424
+ }
20425
+ }
20426
+ for (const [cardId, group] of cards) {
20427
+ const rootProjects = cardRoots.get(cardId) ?? [];
20428
+ const selected = [...rootProjects].sort((left, right) => Number(left.user?.archived === true) - Number(right.user?.archived === true) || projectAttention(right) - projectAttention(left))[0];
20429
+ if (selected === void 0)
20430
+ continue;
20431
+ const order = codexProjects?.order.indexOf(group.id) ?? -1;
20432
+ const users = rootProjects.map((project) => project.user);
20433
+ const archivedAt = users.map((user) => user?.archivedAt).filter((at) => at !== void 0).sort()[0];
20434
+ const orders = users.map((user) => user?.order).filter((value) => value !== void 0);
20435
+ projects.push({
20436
+ ...selected,
20437
+ root: cardId,
20438
+ group: { ...group, roots: rootProjects.map((project) => project.root) },
20439
+ rootProjects,
20440
+ ...order < 0 ? {} : { codexOrder: order },
20441
+ title: {
20442
+ text: group.name,
20443
+ source: group.kind === "codex-project" ? "codexProject" : "codexUngrouped"
20444
+ },
20445
+ sessions: rootProjects.flatMap((project) => project.sessions),
20446
+ presence: rootProjects.some((project) => project.presence === "active") ? "active" : "remembered",
20447
+ seenSinceStart: rootProjects.some((project) => project.seenSinceStart),
20448
+ archivedHasNewActivity: rootProjects.some((project) => project.archivedHasNewActivity),
20449
+ user: {
20450
+ pinned: users.every((user) => user?.pinned === true),
20451
+ hidden: users.every((user) => user?.hidden === true),
20452
+ archived: users.every((user) => user?.archived === true),
20453
+ ...archivedAt === void 0 ? {} : { archivedAt },
20454
+ ...orders.length === 0 ? {} : { order: Math.min(...orders) }
20455
+ }
20162
20456
  });
20163
20457
  }
20164
20458
  projects.sort((left, right) => {
@@ -20169,6 +20463,15 @@ function createNarrativeService(options = {}) {
20169
20463
  const activityOrder = (right.firstScreen.lastActivity === void 0 ? 0 : Date.parse(right.firstScreen.lastActivity.at)) - (left.firstScreen.lastActivity === void 0 ? 0 : Date.parse(left.firstScreen.lastActivity.at));
20170
20464
  return decisionOrder || activityOrder || left.root.localeCompare(right.root);
20171
20465
  });
20466
+ for (const archived of [false, true]) {
20467
+ const positions = projects.flatMap((project, index) => project.group?.kind === "codex-project" && project.user?.archived === true === archived ? [index] : []);
20468
+ const ordered = positions.map((index) => projects[index]).filter((project) => project !== void 0).sort((left, right) => (left.codexOrder ?? Number.MAX_SAFE_INTEGER) - (right.codexOrder ?? Number.MAX_SAFE_INTEGER));
20469
+ positions.forEach((index, position) => {
20470
+ const project = ordered[position];
20471
+ if (project !== void 0)
20472
+ projects[index] = project;
20473
+ });
20474
+ }
20172
20475
  return {
20173
20476
  projects,
20174
20477
  ...projectMemoryUnavailable === void 0 ? {} : { memory: { unavailable: projectMemoryUnavailable() } }
@@ -20217,9 +20520,39 @@ function createNarrativeService(options = {}) {
20217
20520
  subscribe,
20218
20521
  refreshLocale,
20219
20522
  refreshOverlay,
20523
+ refreshCodexProjects,
20220
20524
  close
20221
20525
  };
20222
20526
  }
20527
+ function codexPathIdentity(path) {
20528
+ try {
20529
+ return realpathSync3(path);
20530
+ } catch {
20531
+ return resolve12(path);
20532
+ }
20533
+ }
20534
+ function isPathWithin(root, cwd) {
20535
+ const path = relative4(root, cwd);
20536
+ return path === "" || path !== ".." && !path.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) && !isAbsolute6(path);
20537
+ }
20538
+ function projectAttention(project) {
20539
+ if (project.sessions.some((session) => session.waiting))
20540
+ return 4;
20541
+ if (project.firstScreen.action.kind === "insufficient" && project.sessions.some((session) => !session.ended))
20542
+ return 2;
20543
+ switch (project.firstScreen.action.kind) {
20544
+ case "decision":
20545
+ return 4;
20546
+ case "checkpoint":
20547
+ return 3;
20548
+ case "in_progress":
20549
+ return 2;
20550
+ case "ended":
20551
+ return 1;
20552
+ case "insufficient":
20553
+ return 0;
20554
+ }
20555
+ }
20223
20556
  function deriveProjectFirstScreen(plan, goal, points, sessions) {
20224
20557
  const source = ".wingman/plan.md nodes(status, children)";
20225
20558
  const currentPoints = points.map((point) => ({ ...point, source }));
@@ -20450,6 +20783,54 @@ function feedbackView(harness, capability, state) {
20450
20783
  }
20451
20784
  return state ?? { state: "no_open_request", source: `${harness} explicit feedback signals` };
20452
20785
  }
20786
+ function codexAutomaticReviewAt(lines2, at) {
20787
+ const requestTime = Date.parse(at);
20788
+ if (!Number.isFinite(requestTime))
20789
+ return false;
20790
+ let reviewer;
20791
+ let turnId;
20792
+ for (const line of sortedCodexByTimestamp(lines2)) {
20793
+ if (line.kind === "unknown")
20794
+ continue;
20795
+ const time = Date.parse(line.timestamp ?? "");
20796
+ if (!Number.isFinite(time)) {
20797
+ if (line.kind === "turn_context" || line.kind === "task_started")
20798
+ reviewer = void 0;
20799
+ continue;
20800
+ }
20801
+ if (time > requestTime)
20802
+ continue;
20803
+ if (line.kind === "task_started") {
20804
+ reviewer = void 0;
20805
+ turnId = line.turnId;
20806
+ } else if (line.kind === "task_complete" || line.kind === "turn_aborted") {
20807
+ reviewer = void 0;
20808
+ turnId = void 0;
20809
+ } else if (line.kind === "turn_context") {
20810
+ reviewer = turnId !== void 0 && line.turnId !== turnId ? void 0 : line.approvalsReviewer;
20811
+ }
20812
+ }
20813
+ return reviewer === "auto_review";
20814
+ }
20815
+ function humanFeedbackState(harness, session) {
20816
+ const state = session.feedbackState;
20817
+ if (harness !== "codex" || state?.source !== "codex PermissionRequest signal")
20818
+ return state;
20819
+ const since = state.state === "needs_user" ? state.since : state.requestSince;
20820
+ const at = session.feedbackRequestAt ?? since;
20821
+ if (codexAutomaticReviewAt(session.codexLines, at))
20822
+ return void 0;
20823
+ if (!codexAutomaticReviewAt(session.codexLines, since))
20824
+ return state;
20825
+ return state.state === "needs_user" ? { ...state, since: at } : { ...state, requestSince: at };
20826
+ }
20827
+ function humanWaiting(harness, lines2, wait, at = wait.since) {
20828
+ if (harness !== "codex" || wait.kind !== "permission")
20829
+ return wait;
20830
+ if (codexAutomaticReviewAt(lines2, at))
20831
+ return null;
20832
+ return codexAutomaticReviewAt(lines2, wait.since) ? { ...wait, since: at } : wait;
20833
+ }
20453
20834
  function observedMcpServers(lines2, configuredServers) {
20454
20835
  const names = /* @__PURE__ */ new Set();
20455
20836
  for (const line of lines2) {
@@ -20513,6 +20894,8 @@ function observedSkills(lines2) {
20513
20894
  }
20514
20895
  function derive(harness, session, nowIso, configuredPlugins, configuredMcpServers) {
20515
20896
  const codexLines = sortedCodexByTimestamp(session.codexLines);
20897
+ const waiting = session.waiting === null ? null : humanWaiting(harness, codexLines, session.waiting, session.feedbackRequestAt);
20898
+ const waitEpisodes = session.waitEpisodes.map((wait) => humanWaiting(harness, codexLines, wait, wait.requestAt)).filter((wait) => wait !== null);
20516
20899
  const lines2 = harness === "codex" ? adaptCodexNarrativeLines(codexLines) : sortedByTimestamp(session.lines);
20517
20900
  const timeline = deriveTodoTimeline(extractTodoSnapshots(lines2));
20518
20901
  const allSteps = extractSteps(lines2);
@@ -20562,10 +20945,10 @@ function derive(harness, session, nowIso, configuredPlugins, configuredMcpServer
20562
20945
  else
20563
20946
  waitNodes.set(key, [node]);
20564
20947
  };
20565
- for (const episode of session.waitEpisodes)
20948
+ for (const episode of waitEpisodes)
20566
20949
  pushWait(episode, false);
20567
- if (session.waiting !== null)
20568
- pushWait(session.waiting, true);
20950
+ if (waiting !== null)
20951
+ pushWait(waiting, true);
20569
20952
  const traces = [];
20570
20953
  const agentsByTodo = /* @__PURE__ */ new Map();
20571
20954
  const orderedKeys = timeline.map((entry) => entry.id).filter((id) => buckets.has(id) || waitNodes.has(id));
@@ -20624,7 +21007,7 @@ function derive(harness, session, nowIso, configuredPlugins, configuredMcpServer
20624
21007
  },
20625
21008
  execution: {
20626
21009
  ...workflowAction === void 0 ? {} : { currentAction: workflowAction },
20627
- evidenceCount: steps.length + session.waitEpisodes.length + (session.waiting === null ? 0 : 1),
21010
+ evidenceCount: steps.length + waitEpisodes.length + (waiting === null ? 0 : 1),
20628
21011
  failureCount: steps.filter((step) => step.isError).length
20629
21012
  },
20630
21013
  feedback: unavailableFeedback({ key: "narrative.feedbackUnmapped" })
@@ -20677,7 +21060,7 @@ function derive(harness, session, nowIso, configuredPlugins, configuredMcpServer
20677
21060
  traces,
20678
21061
  turnUsages: harness === "codex" ? deriveCodexTurnUsages(codexLines) : deriveTurnUsages(lines2),
20679
21062
  currentAction,
20680
- waiting: session.waiting,
21063
+ waiting,
20681
21064
  agentQuote: deriveAgentQuote(lines2),
20682
21065
  // transcript 是会话事实源;hook prompt 只在 tail 尚未读到/格式暂不可读时兜底。
20683
21066
  lastPrompt,
@@ -21204,15 +21587,15 @@ function deriveAgentQuote(lines2) {
21204
21587
  return null;
21205
21588
  }
21206
21589
  function deriveLastPrompt(lines2, hookPrompt, hookPromptAt) {
21207
- const usableHookPrompt = hookPrompt === void 0 || isHarnessSystemNotice(hookPrompt) ? void 0 : hookPrompt;
21590
+ const usableHookPrompt = hookPrompt;
21208
21591
  for (let i = lines2.length - 1; i >= 0; i--) {
21209
21592
  const line = lines2[i];
21210
21593
  if (line === void 0 || line.kind !== "user" || line.agentId !== void 0)
21211
21594
  continue;
21212
21595
  if (line.toolResults.length > 0)
21213
21596
  continue;
21214
- const text = line.text?.trim();
21215
- if (text === void 0 || text === "" || isHarnessSystemNotice(text))
21597
+ const text = line.text === void 0 ? void 0 : userRequestText(line.text);
21598
+ if (text === void 0 || text === "")
21216
21599
  continue;
21217
21600
  if (usableHookPrompt !== void 0 && hookPromptAt !== void 0 && line.timestamp !== void 0 && hookPromptAt > line.timestamp) {
21218
21601
  return usableHookPrompt;
@@ -21465,7 +21848,7 @@ async function loadHarness(harness, mode) {
21465
21848
  // apps/cli/dist/return-target.js
21466
21849
  init_dist();
21467
21850
  import { randomBytes as randomBytes4 } from "node:crypto";
21468
- import { closeSync as closeSync3, copyFileSync as copyFileSync3, mkdirSync as mkdirSync12, openSync as openSync3, readFileSync as readFileSync18, renameSync as renameSync5, rmSync as rmSync10, statSync as statSync6, writeFileSync as writeFileSync13 } from "node:fs";
21851
+ import { closeSync as closeSync3, copyFileSync as copyFileSync3, mkdirSync as mkdirSync12, openSync as openSync3, readFileSync as readFileSync18, renameSync as renameSync5, rmSync as rmSync10, statSync as statSync7, writeFileSync as writeFileSync13 } from "node:fs";
21469
21852
  import { dirname as dirname18, join as join27, resolve as resolve13 } from "node:path";
21470
21853
  function isIslandSetting(value) {
21471
21854
  return isRecord8(value) && Object.keys(value).every((key) => ["edge", "offset", "screen", "size"].includes(key)) && ["top", "bottom", "left", "right"].includes(value.edge) && typeof value.offset === "number" && Number.isFinite(value.offset) && value.offset >= 0 && value.offset <= 1 && (value.screen === void 0 || typeof value.screen === "string") && (value.size === "compact" || value.size === "standard");
@@ -21486,7 +21869,7 @@ function detectReturnTargets(homeDir, roots = ["/Applications", join27(homeDir,
21486
21869
  for (const root of new Set(roots.map((root2) => resolve13(root2)))) {
21487
21870
  const bundlePath = join27(root, bundle);
21488
21871
  try {
21489
- if (statSync6(bundlePath).isDirectory())
21872
+ if (statSync7(bundlePath).isDirectory())
21490
21873
  available.push({ name, bundlePath });
21491
21874
  } catch {
21492
21875
  }
@@ -21691,7 +22074,7 @@ import { createHmac, timingSafeEqual } from "node:crypto";
21691
22074
  import { readFile as readFile4 } from "node:fs/promises";
21692
22075
  import { createServer } from "node:http";
21693
22076
  import { hostname } from "node:os";
21694
- import { extname, relative as relative4, resolve as resolve14, sep as sep2 } from "node:path";
22077
+ import { extname, relative as relative5, resolve as resolve14, sep as sep2 } from "node:path";
21695
22078
 
21696
22079
  // apps/cli/dist/suggest.js
21697
22080
  init_dist2();
@@ -22036,6 +22419,7 @@ async function handle(req, res, options, warn, runtime) {
22036
22419
  }
22037
22420
  if (url.pathname === "/api/anatomy") {
22038
22421
  const configs = await scanAll(options.harnesses, warn);
22422
+ options.narrative?.refreshCodexProjects();
22039
22423
  runtime.anatomy = { at: Date.now(), configs };
22040
22424
  const anatomy = configs.map((config) => {
22041
22425
  const scanOptions = options.harnesses.find((entry) => entry.harness === config.harness)?.scanOptions;
@@ -22282,7 +22666,7 @@ function handleProtocolUserAction(body, res, options, runtime) {
22282
22666
  sendJson2(res, 200, {
22283
22667
  ok: true,
22284
22668
  planProtocol: { user },
22285
- ...result5.backupDir === void 0 ? {} : { backupDir: `~/${relative4(homeDir, result5.backupDir).split(sep2).join("/")}` }
22669
+ ...result5.backupDir === void 0 ? {} : { backupDir: `~/${relative5(homeDir, result5.backupDir).split(sep2).join("/")}` }
22286
22670
  });
22287
22671
  }
22288
22672
  } catch (error) {